Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function(){};
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
/**
* jQuery-Plugin "butterHandleAutoComplete" for text autocomplete tag. Initializes auto complete functionality to
* text component.
*
* How to use:
* jQuery("#selector")._butterAutoCompleteInit();
*/
(function ($) {
// extend jQuery --------------------------------------------------------------------
$.fn._butterAutoCompleteInit = function () {
return this.each(function () {
new AutocompleteList(this);
});
};
// define objects --------------------------------------------------------------------
var AutocompleteList = Class.extend({
init: function (rootElement) {
this.SEARCH_REQUEST_DELAY = 300;// in ms
var $autocompleteTmp = $(rootElement);
this.$input = $autocompleteTmp.prev();
this.$input.parent().css({position: "relative"});
this.autocompleteId = $autocompleteTmp.attr("id");
this.$selectedOption = null;
this.ignoreKeyupEvent = false;
this.requestDelayTimerId = null;
this.isRequestRunning = false;
this.areChangesMadeWhileRequestWasRunning = false;
this._keyCodes = {
//backspace: 8,
tab: 9,
enter: 13,
shift: 16,
ctrl: 17,
alt: 18,
pause: 19,
caps_lock: 20,
escape: 27,
page_up: 33,
page_down: 34,
end: 35,
home: 36,
arrow_left: 37,
arrow_up: 38,
arrow_right: 39,
arrow_down: 40,
insert: 45,
// 'delete' is a reserved key word
delete_key: 46,
left_window_key: 91,
right_window_key: 92,
select_key: 93,
num_lock: 144,
scroll_lock: 145
};
var self = this;
self.$input
.on("keydown", function (event) {
if (event.which === self._keyCodes.enter) {
self._handleEnterKeyDown(event);
} else if (event.which === self._keyCodes.arrow_up
|| event.which === self._keyCodes.arrow_down) {
self._handleArrowUpAndDownKeyDown(event);
} else if (event.which === self._keyCodes.escape) {
self._handleEscapeKeyDown(event);
}
})
.on("keyup", function (event) {
// don't handle other keys than character keys
for (keyName in self._keyCodes) {
if (self._keyCodes[keyName] === event.which) {
self._stopEvent(event);
return;
}
}
if (self.ignoreKeyupEvent) {
self._stopEvent(event);
self.ignoreKeyupEvent = false;
return;
}
if (self.$input.val().length === 0) {
self._stopEvent(event);
self._hideAutocompleteResultList();
return;
}
self._trySendJsfAjaxRequest();
})
.on("blur", function (event) {
window.setTimeout(function () {
self._hideAutocompleteResultList();
}, 100);
});
},
_handleEnterKeyDown: function (event) {
if (this.$selectedOption !== null) {
this._stopEvent(event);
this._setSelectedValue();
}
},
_handleArrowUpAndDownKeyDown: function (event) {
this._stopEvent(event);
var $autocomplete = this._getAutocompleteElement();
if (!$autocomplete.is(":visible") && this.$input.val().length > 0) {
this._trySendJsfAjaxRequest();
} else if ($autocomplete.is(":visible") && $autocomplete.find("li").length > 0) {
if (this.$selectedOption === null) {
this._selectResultOptionElement($autocomplete.find("li")[0]);
} else {
this._moveResultOptionElementSelectionCursor(
$autocomplete, event.which === this._keyCodes.arrow_up ? -1 : 1);
}
}
},
_handleEscapeKeyDown: function (event) {
this._stopEvent(event);
this._hideAutocompleteResultList();
},
_trySendJsfAjaxRequest: function () {
var self = this;
if (self.isRequestRunning) {
// console.log("request is active, so remember that changes has been made while request was running");
self.areChangesMadeWhileRequestWasRunning = true;
}
if (self.requestDelayTimerId !== null) {
window.clearTimeout(self.requestDelayTimerId)
}
self.requestDelayTimerId = window.setTimeout(function () {
self.requestDelayTimerId = null;
self._sendJsfAjaxRequest();
}, self.SEARCH_REQUEST_DELAY);
},
_sendJsfAjaxRequest: function () {
var self = this;
if (self.isRequestRunning) {
// console.log("request is running, abort");
return;
}
self.isRequestRunning = true;
self.areChangesMadeWhileRequestWasRunning = false;
self._showLoadingSpinner();
// console.log("starting request");
var id = self.$input.parent().parent().attr('id');
jsf.ajax.request(id, "autocomplete", {
"javax.faces.behavior.event": "autocomplete",
render: self.autocompleteId,
params: self.$input.val(),
onevent: function (data) {
if (data.status === "success") {
// console.log("request finished");
// only show result if input field still has focus
if (self.$input.is(":focus")) {
self._handleAutocompleteResultListVisibility();
}
self._hideLoadingSpinner();
self.isRequestRunning = false;
if (self.areChangesMadeWhileRequestWasRunning) {
// console.log("changes made while request was running, start new request automatically");
self._sendJsfAjaxRequest();
}
}
}
});
},
_handleAutocompleteResultListVisibility: function () {
var self = this;
var $autocomplete = self._getAutocompleteElement();
if ($autocomplete.find("li").length > 0) {
self._initAndShowAutocompleteResultList();
} else {
self._hideAutocompleteResultList();
}
},
_showLoadingSpinner: function () {
$('
')
.appendTo(this.$input.parent());
},
_hideLoadingSpinner: function () {
this.$input.parent().find(".butter-dropdownlist-spinner").remove();
},
_initAndShowAutocompleteResultList: function () {
var self = this;
var $autocomplete = self._getAutocompleteElement();
$autocomplete
.show()
.css({
width: self.$input.innerWidth()
})
.highlight(self.$input.val());
$autocomplete.find("ul")
.on("mouseleave", function () {
self._clearResultOptionSelection();
});
$autocomplete.find("li")
.on("mousedown", function () {
self._setSelectedValue();
})
.on("mouseenter", function () {
self._selectResultOptionElement(this);
});
},
_selectResultOptionElement: function (optionElement) {
this._clearResultOptionSelection();
var $selectedOptionElement = $(optionElement);
$selectedOptionElement.addClass("butter-dropdownlist-resultItem-selected");
this.$selectedOption = $selectedOptionElement;
},
_clearResultOptionSelection: function () {
this.$selectedOption = null;
this._getAutocompleteElement()
.find(".butter-dropdownlist-resultItem-selected")
.removeClass("butter-dropdownlist-resultItem-selected");
},
_moveResultOptionElementSelectionCursor: function ($autocomplete, direction) {
if (direction > 0) {
var $next = this.$selectedOption.next();
if ($next.length > 0) {
this._selectResultOptionElement($next[0]);
} else {
//there is no next
this._selectResultOptionElement($autocomplete.find("li")[0]);
}
} else {
var $prev = this.$selectedOption.prev();
if ($prev.length > 0) {
this._selectResultOptionElement($prev[0]);
} else {
//there is no previous
var resultListOptions = $autocomplete.find("li");
this._selectResultOptionElement(resultListOptions[resultListOptions.length - 1]);
}
}
},
_setSelectedValue: function () {
if (this.$selectedOption !== null) {
this.ignoreKeyupEvent = true;
this.$input
.val(this.$selectedOption.attr("data-select-value"))
.change()
.focus()
.keyup();
this._hideAutocompleteResultList();
}
},
_hideAutocompleteResultList: function () {
if (this.requestDelayTimerId !== null) {
window.clearTimeout(this.requestDelayTimerId)
}
this.$selectedOption = null;
this._getAutocompleteElement().hide();
},
_getAutocompleteElement: function () {
return $(document.getElementById(this.autocompleteId));
},
_stopEvent: function (event) {
event.stopPropagation();
event.preventDefault();
}
});
}(jQuery));
/**
* jQuery-Plugin to handle bootstrap fixes.
* Works with at least jQuery 1.3.2.
*
* How to use:
* jQuery("#someTreeSelector").fixBootstrapDropDown();
*/
(function ($) {
$.fn.fixBootstrapDropDown = function () {
return this.each(function () {
$('.dropdown-menu').on('click', function(e) {
if($(this).hasClass('dropdown-menu-form')) {
e.stopPropagation();
}
});
});
};
}(jQuery));
/**
* butterItemFilterField is a jQuery plugin that filters html element with the css class filterable-item.
* It is applied to the search field.
* If no filter text is entered, then all filterable-items are displayed. Else the search field value is matched against all text contained by a filterable-item.
*
* How to use:
* jQuery("#someInputSelector").butterItemFilterField();
*
* Author: Yann Massard
*/
(function ($) {
var delay = (function () {
var timer = 0;
return function (callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
// extend jQuery --------------------------------------------------------------------
$.fn.butterItemFilterField = function (filterableItemContainerSelector) {
return this.each(function () {
var $this = $(this);
$this.keyup(function () {
delay(function () {
var filterValue = $this.val();
// find container again every time, because it could have been rerendered.
var $filterableItemContainer;
if (filterableItemContainerSelector) {
$filterableItemContainer = $(filterableItemContainerSelector);
} else {
var containerSelector = $this.attr('data-filterable-item-container');
$filterableItemContainer = $(containerSelector);
}
var filterableItems = $filterableItemContainer.find('.filterable-item');
filterableItems.each(function (i, elem) {
var $filterableItem = $(elem);
if ($filterableItem.is(':containsIgnoreCase(' + filterValue + ')')) {
$filterableItem.removeAttr("hidden");
$filterableItem.highlight(filterValue);
} else {
$filterableItem.attr("hidden", "hidden");
}
});
}, 300);
});
});
};
}(jQuery));
(function ($) {
$.expr[":"].containsIgnoreCase = $.expr.createPseudo(function (arg) {
return function (elem) {
return !arg || $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
};
});
}(jQuery));
/**
* jQuery-Plugin "Animate dots" for tree animation. Animates a waiting dot line (4 dots) in an interval of 200 millis
* as html string in given component. Note: existing html code will be cleared.
* Works with at least jQuery 1.3.2.
*
* How to use:
* jQuery("#selector").startDots();
* jQuery("#selector").stopDots();
*/
(function ($) {
// extend jQuery --------------------------------------------------------------------
var intervalTrigger = null;
$.fn.startDots = function () {
return this.each(function () {
var $originalElement = $(this);
$originalElement.html('');
intervalTrigger = setInterval(function () {
$originalElement.append('.');
if ($originalElement.html().length > 5) {
$originalElement.html('');
}
}, 200);
});
};
$.fn.stopDots = function () {
return this.each(function () {
var $originalElement = $(this);
$originalElement.html('');
window.clearInterval(intervalTrigger);
});
};
}(jQuery));
(function ($) {
$.fn.highlight = function (searchString) {
var highlightClassName = "search-highlighted";
var regex = new RegExp(searchString, "gi");
var elements = this.find('*');
this.each(function () {
elements.push(this);
$(this).find('.' + highlightClassName).contents().unwrap();
this.normalize();
});
return elements.each(function () {
var $this = $(this);
if (searchString && searchString !== '') {
$this.contents()
.filter(function () {
return this.nodeType === 3 && regex.test(this.nodeValue);
})
.replaceWith(function () {
return (this.nodeValue || "").replace(regex, function (match) {
return "" + match + "";
});
});
}
});
};
}(jQuery));
(function ($) {
// extend jQuery --------------------------------------------------------------------
$.fn.markdownReadonly = function () {
var root = $(this);
var $readonlyMarkdown = root.find('.butter-component-value-readonly-wrapper');
var markdownText = $readonlyMarkdown.html()
.replace('&', '&')
.replace('<', '<')
.replace('>', '>');
var markdownTextToHtml = new showdown.Converter().makeHtml(markdownText);
$readonlyMarkdown.empty();
$readonlyMarkdown.append(markdownTextToHtml);
};
}(jQuery));
if (typeof butter === 'undefined') {
butter = {};
}
butter.modal = {};
butter.modal.open = function (/* string */ modalPanelId) {
// console.log('Opening modal panel with data-modal-id ' + modalPanelId);
$('.butter-modal[data-modal-id=' + modalPanelId + ']').modal({show: true, keyboard: false, backdrop: 'static'})
};
butter.modal.close = function (/* string */ modalPanelId) {
// console.log('Closing modal panel with data-modal-id ' + modalPanelId);
$('.butter-modal[data-modal-id=' + modalPanelId + ']').modal('hide');
};
/**
* jQuery-Plugin "Number Spinner" for input fields.
* Works with at least jQuery 1.3.2.
*
* How to use:
* jQuery("someButterComponentSelector").butterNumberSpinner();
*/
(function ($) {
// extend jQuery --------------------------------------------------------------------
$.fn.butterNumberSpinner = function (options) {
return this.each(function () {
new NumberSpinner(this, options);
});
};
// define classes --------------------------------------------------------------------
var NumberSpinner = Class.extend({
init: function (element, options) {
this.$input = $(element).find("input");
this._initInput();
this._initOptions(options);
this._counter = null;
this.setCounter(0);
this._isValueSet = false;
this._initButtons();
this._initArrowKeys();
this._initMouseWheel();
},
_initInput: function () {
var self = this;
this.$input
.addClass("butter-component-number-input")
.blur(function () {
self._setValueOnBlur();
})
.parent().addClass("input-group");
},
_initOptions: function (options) {
var defaultOptions = {
step: 1,
disabled: false
};
this._options = $.extend({}, defaultOptions, options);
// ensure that this values are numbers
if (this._options.step !== undefined) {
this._options.step = this._options.step * 1;
}
if (this._options.min !== undefined) {
this._options.min = this._options.min * 1;
}
if (this._options.max !== undefined) {
this._options.max = this._options.max * 1;
}
},
_initButtons: function () {
var $outerAddon = $("
")
.addClass("input-group-append")
.insertAfter(this.$input);
var $addon = $("")
.addClass("input-group-text")
.addClass("butter-component-number-buttons")
.appendTo($outerAddon);
var self = this;
$("")
.addClass("glyphicon glyphicon-chevron-up")
.addClass("butter-component-number-button")
.addClass(function () {
return self._options.disabled ? "disabled" : "";
})
.click(function () {
if (!self._options.disabled) {
self.increaseCounter();
}
})
.appendTo($addon);
$("")
.addClass("glyphicon glyphicon-chevron-down")
.addClass("butter-component-number-button")
.addClass(function () {
return self._options.disabled ? "disabled" : "";
})
.click(function () {
if (!self._options.disabled) {
self.decreaseCounter();
}
})
.appendTo($addon);
},
_initArrowKeys: function () {
var self = this;
this.$input.keydown(function (event) {
if (event.which === 38) {
event.stopPropagation();
event.preventDefault();
self.increaseCounter();
} else if (event.which === 40) {
event.stopPropagation();
event.preventDefault();
self.decreaseCounter();
}
});
},
_initMouseWheel: function () {
var self = this;
this.$input.on("mousewheel DOMMouseScroll", function (event) {
if (!self.$input.is(':focus')) {
return;
}
var delta = event.originalEvent.wheelDelta || -event.originalEvent.deltaY || -event.originalEvent.detail;
event.stopPropagation();
event.preventDefault();
if (delta < 0) {
self.decreaseCounter();
} else {
self.increaseCounter();
}
});
},
_setValueOnBlur: function () {
var value = this.$input.val();
if (this._isStringEmpty(value)) {
this.$input.val("");
this.setCounter(0);
this._isValueSet = false;
} else {
var parsedInt = parseInt(value);
if (isNaN(parsedInt)) {
if (this._isValueSet) {
this.$input.val(this._counter);
} else {
this.$input.val("");
this.setCounter(0);
this._isValueSet = false;
}
} else {
this.setCounter(parsedInt);
this.$input.val(this._counter);
this._isValueSet = true;
}
}
},
increaseCounter: function () {
if (this._isValueSet) {
this.setCounter(this._counter + this._options.step);
} else {
this._isValueSet = true;
}
this.$input.val(this._counter);
this.$input.change();
},
decreaseCounter: function () {
if (this._isValueSet) {
this.setCounter(this._counter - this._options.step);
} else {
this._isValueSet = true;
}
this.$input.val(this._counter);
this.$input.change();
},
_isStringEmpty: function (value) {
return (value.length === 0 || !value.trim());
},
setCounter: function (value) {
if (this._options.min !== undefined && value < this._options.min) {
this._counter = this._options.min;
} else if (this._options.max !== undefined && value > this._options.max) {
this._counter = this._options.max;
} else {
this._counter = value;
}
}
});
}(jQuery));
if (typeof butter === 'undefined') {
butter = {};
}
butter.prettyprint = {};
/**
* calls pretty print javascript framework and removes first and last empty children.
*/
butter.prettyprint.cleanup = function() {
prettyPrint();
jQuery('.butter-component-prettyprint').each(function () {
var $firstPreChild = jQuery(this).find("pre span").first();
var $lastPreChild = jQuery(this).find("pre span").last();
if (!(typeof $firstPreChild.html() === "undefined")) {
if (!$firstPreChild.html().trim()) {
$firstPreChild.remove();
}
}
if (!(typeof $lastPreChild.html() === "undefined")) {
if (!$lastPreChild.html().trim()) {
$lastPreChild.remove();
}
}
});
};
/**
* How to use:
* jQuery("#someSelector").scrollToFirst() or jQuery("#someSelector").scrollToLast();
*/
(function ($) {
// extend jQuery --------------------------------------------------------------------
$.fn.butterScrollToFirst = function (/* int */ offset) {
void 0;
var _offset = offset === undefined ? $(this).first().offset().top : $(this).first().offset().top + offset;
$('html, body').animate({scrollTop: _offset + 'px'}, 'fast');
};
$.fn.butterScrollToLast = function (/* int */ offset) {
void 0;
var _offset = offset === undefined ? $(this).last().offset().top : $(this).last().offset().top + offset;
$('html, body').animate({scrollTop: _offset + 'px'}, 'fast');
};
}(jQuery));
/**
* jQuery-Plugin to handle selection style classes on JSF-Component "b:table".
* Works with at least jQuery 1.3.2.
*
* How to use:
* jQuery("#someTreeSelector").selectRow( {rowIndex: '6'} );
*/
(function ($) {
// extend jQuery --------------------------------------------------------------------
$.fn.toggleColumnVisibilty = function (renderIds, disableRenderIds) {
return this.each(function () {
var $toolbar = $(this);
var json = JSON.stringify(createColumnVisibilty($toolbar));
ButterFaces.Ajax.sendRequest($toolbar.attr('id'), 'toggle', renderIds, json, disableRenderIds);
});
function createColumnVisibilty($toolbar) {
var columns = [];
$toolbar.find('.butter-table-toolbar-column-option input[type=checkbox]').each(function (index, checkbox) {
var $checkbox = $(checkbox).parent('.butter-table-toolbar-column-option');
columns.push({
identifier: $checkbox.attr('data-column-model-identifier'),
visible: $checkbox.find('input[type=checkbox]').is(':checked')
});
});
return columns;
}
};
$.fn.orderColumn = function (renderIds, disableRenderIds, toLeft, columnNumber) {
return this.each(function () {
var $toolbar = $(this);
if (toLeft) {
//console.log('order column ' + columnNumber + ' to left');
orderColumnLeft($toolbar, columnNumber);
} else {
//console.log('order column ' + columnNumber + ' to right');
orderColumnRight($toolbar, columnNumber);
}
var json = JSON.stringify(createColumnOrder($toolbar));
ButterFaces.Ajax.sendRequest($toolbar.attr('id'), 'order', renderIds, json, disableRenderIds);
});
function createColumnOrder($toolbar) {
var columns = [];
$toolbar.find('.butter-table-toolbar-column-option input[type=checkbox]').each(function (index, checkbox) {
var $checkbox = $(checkbox).parent('.butter-table-toolbar-column-option');
columns.push({
identifier: $checkbox.attr('data-column-model-identifier'),
position: index
});
});
return columns;
}
function orderColumnLeft(/* jquery toolbar */ $toolbar, columnNumber) {
//console.log($toolbar);
var $column = $toolbar.find('li[data-original-column="' + columnNumber + '"]');
var $nextColumn = $column.prev();
//console.log($column);
//console.log($nextColumn);
var $detachtedColumn = $column.detach();
$nextColumn.before($detachtedColumn);
}
function orderColumnRight(/* jquery toolbar */ $toolbar, columnNumber) {
//console.log($toolbar);
var $column = $toolbar.find('li[data-original-column="' + columnNumber + '"]');
var $nextColumn = $column.next();
//console.log($column);
//console.log($nextColumn);
var $detachtedColumn = $column.detach();
$nextColumn.after($detachtedColumn);
}
};
}(jQuery));
(function ($) {
$.fn._butterTooltip = function (/* object */ data) {
var root = $(this);
//console.log(data);
var content = jQuery('[name=' + data.contentByName + ']');
var newData = {
trigger: data.trigger,
title: data.title,
placement: data.placement,
placementFunction: data.placementFunction,
minVerticalOffset: data.minVerticalOffset,
minHorizontalOffset: data.minHorizontalOffset,
content: content.html().trim()
};
//console.log(newData);
content.remove();
root.butterTooltip(newData);
};
$.fn.butterTooltip = function (/* object */ data) {
return this.each(function () {
var root = $(this);
var trigger = data.trigger ? data.trigger : 'hover';
//console.log(data);
//console.log('placement: ' + placement);
//console.log('trigger: ' + trigger);
//console.log('viewport: ' + data.viewport);
if (data.minVerticalOffset) {
root.attr('data-tooltip-min-vertical-offset', data.minVerticalOffset);
}
if (data.minHorizontalOffset) {
root.attr('data-tooltip-min-horizontal-offset', data.minHorizontalOffset);
}
if (root.next().hasClass('popover')) {
root.next().remove();
}
root.popover({
trigger: trigger,
placement: function(popover, source) {
return data.placement ? data.placement : (data.placementFunction ? data.placementFunction : new ButterFaces.Tooltip().calculateTooltipPosition(popover, source));
},
title: data.title,
html: true,
content: data.content,
viewport: data.viewport
});
});
};
}(jQuery));
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImJ1dHRlcmZhY2VzLTAxLWJhc2VDbGFzcy5qcyIsImJ1dHRlcmZhY2VzLWF1dG9jb21wbGV0ZS5qcXVlcnkuanMiLCJidXR0ZXJmYWNlcy1ib290c3RyYXAtZml4ZXMuanF1ZXJ5LmpzIiwiYnV0dGVyZmFjZXMtY2xpZW50U2lkZUZpbHRlci5qcXVlcnkuanMiLCJidXR0ZXJmYWNlcy1kb3RzLmpxdWVyeS5qcyIsImJ1dHRlcmZhY2VzLWhpZ2hsaWdodC5qcXVlcnkuanMiLCJidXR0ZXJmYWNlcy1tYXJrZG93bi5qcXVlcnkuanMiLCJidXR0ZXJmYWNlcy1tb2RhbC5qcyIsImJ1dHRlcmZhY2VzLW51bWJlclNwaW5uZXIuanF1ZXJ5LmpzIiwiYnV0dGVyZmFjZXMtcHJldHR5cHJpbnQuanMiLCJidXR0ZXJmYWNlcy1zY3JvbGwuanF1ZXJ5LmpzIiwiYnV0dGVyZmFjZXMtdGFibGUtdG9vbGJhci5qcXVlcnkuanMiLCJidXR0ZXJmYWNlcy10b29sdGlwLmpxdWVyeS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUN4U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDN0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiYnV0dGVyZmFjZXMtanMtYnVuZGxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyogU2ltcGxlIEphdmFTY3JpcHQgSW5oZXJpdGFuY2VcbiAqIEJ5IEpvaG4gUmVzaWcgaHR0cDovL2Vqb2huLm9yZy9cbiAqIE1JVCBMaWNlbnNlZC5cbiAqL1xuLy8gSW5zcGlyZWQgYnkgYmFzZTIgYW5kIFByb3RvdHlwZVxuKGZ1bmN0aW9uKCl7XG4gICAgdmFyIGluaXRpYWxpemluZyA9IGZhbHNlLCBmblRlc3QgPSAveHl6Ly50ZXN0KGZ1bmN0aW9uKCl7eHl6O30pID8gL1xcYl9zdXBlclxcYi8gOiAvLiovO1xuXG4gICAgLy8gVGhlIGJhc2UgQ2xhc3MgaW1wbGVtZW50YXRpb24gKGRvZXMgbm90aGluZylcbiAgICB0aGlzLkNsYXNzID0gZnVuY3Rpb24oKXt9O1xuXG4gICAgLy8gQ3JlYXRlIGEgbmV3IENsYXNzIHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIGNsYXNzXG4gICAgQ2xhc3MuZXh0ZW5kID0gZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICB2YXIgX3N1cGVyID0gdGhpcy5wcm90b3R5cGU7XG5cbiAgICAgICAgLy8gSW5zdGFudGlhdGUgYSBiYXNlIGNsYXNzIChidXQgb25seSBjcmVhdGUgdGhlIGluc3RhbmNlLFxuICAgICAgICAvLyBkb24ndCBydW4gdGhlIGluaXQgY29uc3RydWN0b3IpXG4gICAgICAgIGluaXRpYWxpemluZyA9IHRydWU7XG4gICAgICAgIHZhciBwcm90b3R5cGUgPSBuZXcgdGhpcygpO1xuICAgICAgICBpbml0aWFsaXppbmcgPSBmYWxzZTtcblxuICAgICAgICAvLyBDb3B5IHRoZSBwcm9wZXJ0aWVzIG92ZXIgb250byB0aGUgbmV3IHByb3RvdHlwZVxuICAgICAgICBmb3IgKHZhciBuYW1lIGluIHByb3ApIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHdlJ3JlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIGZ1bmN0aW9uXG4gICAgICAgICAgICBwcm90b3R5cGVbbmFtZV0gPSB0eXBlb2YgcHJvcFtuYW1lXSA9PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiBfc3VwZXJbbmFtZV0gPT0gXCJmdW5jdGlvblwiICYmIGZuVGVzdC50ZXN0KHByb3BbbmFtZV0pID9cbiAgICAgICAgICAgICAgICAgICAgKGZ1bmN0aW9uKG5hbWUsIGZuKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wID0gdGhpcy5fc3VwZXI7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgYSBuZXcgLl9zdXBlcigpIG1ldGhvZCB0aGF0IGlzIHRoZSBzYW1lIG1ldGhvZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBvbiB0aGUgc3VwZXItY2xhc3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdXBlciA9IF9zdXBlcltuYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBtZXRob2Qgb25seSBuZWVkIHRvIGJlIGJvdW5kIHRlbXBvcmFyaWx5LCBzbyB3ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCB3aGVuIHdlJ3JlIGRvbmUgZXhlY3V0aW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJldCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSB0bXA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfSkobmFtZSwgcHJvcFtuYW1lXSkgOlxuICAgICAgICAgICAgICAgICAgICBwcm9wW25hbWVdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlIGR1bW15IGNsYXNzIGNvbnN0cnVjdG9yXG4gICAgICAgIGZ1bmN0aW9uIENsYXNzKCkge1xuICAgICAgICAgICAgLy8gQWxsIGNvbnN0cnVjdGlvbiBpcyBhY3R1YWxseSBkb25lIGluIHRoZSBpbml0IG1ldGhvZFxuICAgICAgICAgICAgaWYgKCAhaW5pdGlhbGl6aW5nICYmIHRoaXMuaW5pdCApXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQb3B1bGF0ZSBvdXIgY29uc3RydWN0ZWQgcHJvdG90eXBlIG9iamVjdFxuICAgICAgICBDbGFzcy5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG5cbiAgICAgICAgLy8gRW5mb3JjZSB0aGUgY29uc3RydWN0b3IgdG8gYmUgd2hhdCB3ZSBleHBlY3RcbiAgICAgICAgQ2xhc3MucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ2xhc3M7XG5cbiAgICAgICAgLy8gQW5kIG1ha2UgdGhpcyBjbGFzcyBleHRlbmRhYmxlXG4gICAgICAgIENsYXNzLmV4dGVuZCA9IGFyZ3VtZW50cy5jYWxsZWU7XG5cbiAgICAgICAgcmV0dXJuIENsYXNzO1xuICAgIH07XG59KSgpOyIsIi8qKlxuICogalF1ZXJ5LVBsdWdpbiBcImJ1dHRlckhhbmRsZUF1dG9Db21wbGV0ZVwiIGZvciB0ZXh0IGF1dG9jb21wbGV0ZSB0YWcuIEluaXRpYWxpemVzIGF1dG8gY29tcGxldGUgZnVuY3Rpb25hbGl0eSB0b1xuICogdGV4dCBjb21wb25lbnQuXG4gKlxuICogSG93IHRvIHVzZTpcbiAqIGpRdWVyeShcIiNzZWxlY3RvclwiKS5fYnV0dGVyQXV0b0NvbXBsZXRlSW5pdCgpO1xuICovXG4oZnVuY3Rpb24gKCQpIHtcbiAgICAvLyBleHRlbmQgalF1ZXJ5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAkLmZuLl9idXR0ZXJBdXRvQ29tcGxldGVJbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG5ldyBBdXRvY29tcGxldGVMaXN0KHRoaXMpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gZGVmaW5lIG9iamVjdHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIHZhciBBdXRvY29tcGxldGVMaXN0ID0gQ2xhc3MuZXh0ZW5kKHtcbiAgICAgICAgaW5pdDogZnVuY3Rpb24gKHJvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLlNFQVJDSF9SRVFVRVNUX0RFTEFZID0gMzAwOy8vIGluIG1zXG5cbiAgICAgICAgICAgIHZhciAkYXV0b2NvbXBsZXRlVG1wID0gJChyb290RWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLiRpbnB1dCA9ICRhdXRvY29tcGxldGVUbXAucHJldigpO1xuICAgICAgICAgICAgdGhpcy4kaW5wdXQucGFyZW50KCkuY3NzKHtwb3NpdGlvbjogXCJyZWxhdGl2ZVwifSk7XG4gICAgICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZUlkID0gJGF1dG9jb21wbGV0ZVRtcC5hdHRyKFwiaWRcIik7XG4gICAgICAgICAgICB0aGlzLiRzZWxlY3RlZE9wdGlvbiA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmlnbm9yZUtleXVwRXZlbnQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdERlbGF5VGltZXJJZCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmlzUmVxdWVzdFJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYXJlQ2hhbmdlc01hZGVXaGlsZVJlcXVlc3RXYXNSdW5uaW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgIHRoaXMuX2tleUNvZGVzID0ge1xuICAgICAgICAgICAgICAgIC8vYmFja3NwYWNlOiA4LFxuICAgICAgICAgICAgICAgIHRhYjogOSxcbiAgICAgICAgICAgICAgICBlbnRlcjogMTMsXG4gICAgICAgICAgICAgICAgc2hpZnQ6IDE2LFxuICAgICAgICAgICAgICAgIGN0cmw6IDE3LFxuICAgICAgICAgICAgICAgIGFsdDogMTgsXG4gICAgICAgICAgICAgICAgcGF1c2U6IDE5LFxuICAgICAgICAgICAgICAgIGNhcHNfbG9jazogMjAsXG4gICAgICAgICAgICAgICAgZXNjYXBlOiAyNyxcbiAgICAgICAgICAgICAgICBwYWdlX3VwOiAzMyxcbiAgICAgICAgICAgICAgICBwYWdlX2Rvd246IDM0LFxuICAgICAgICAgICAgICAgIGVuZDogMzUsXG4gICAgICAgICAgICAgICAgaG9tZTogMzYsXG4gICAgICAgICAgICAgICAgYXJyb3dfbGVmdDogMzcsXG4gICAgICAgICAgICAgICAgYXJyb3dfdXA6IDM4LFxuICAgICAgICAgICAgICAgIGFycm93X3JpZ2h0OiAzOSxcbiAgICAgICAgICAgICAgICBhcnJvd19kb3duOiA0MCxcbiAgICAgICAgICAgICAgICBpbnNlcnQ6IDQ1LFxuICAgICAgICAgICAgICAgIC8vICdkZWxldGUnIGlzIGEgcmVzZXJ2ZWQga2V5IHdvcmRcbiAgICAgICAgICAgICAgICBkZWxldGVfa2V5OiA0NixcbiAgICAgICAgICAgICAgICBsZWZ0X3dpbmRvd19rZXk6IDkxLFxuICAgICAgICAgICAgICAgIHJpZ2h0X3dpbmRvd19rZXk6IDkyLFxuICAgICAgICAgICAgICAgIHNlbGVjdF9rZXk6IDkzLFxuICAgICAgICAgICAgICAgIG51bV9sb2NrOiAxNDQsXG4gICAgICAgICAgICAgICAgc2Nyb2xsX2xvY2s6IDE0NVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgc2VsZi4kaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgLm9uKFwia2V5ZG93blwiLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC53aGljaCA9PT0gc2VsZi5fa2V5Q29kZXMuZW50ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9oYW5kbGVFbnRlcktleURvd24oZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC53aGljaCA9PT0gc2VsZi5fa2V5Q29kZXMuYXJyb3dfdXBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZXZlbnQud2hpY2ggPT09IHNlbGYuX2tleUNvZGVzLmFycm93X2Rvd24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9oYW5kbGVBcnJvd1VwQW5kRG93bktleURvd24oZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC53aGljaCA9PT0gc2VsZi5fa2V5Q29kZXMuZXNjYXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5faGFuZGxlRXNjYXBlS2V5RG93bihldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5vbihcImtleXVwXCIsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgaGFuZGxlIG90aGVyIGtleXMgdGhhbiBjaGFyYWN0ZXIga2V5c1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXlOYW1lIGluIHNlbGYuX2tleUNvZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuX2tleUNvZGVzW2tleU5hbWVdID09PSBldmVudC53aGljaCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5pZ25vcmVLZXl1cEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmlnbm9yZUtleXVwRXZlbnQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLiRpbnB1dC52YWwoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2hpZGVBdXRvY29tcGxldGVSZXN1bHRMaXN0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl90cnlTZW5kSnNmQWpheFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLm9uKFwiYmx1clwiLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9oaWRlQXV0b2NvbXBsZXRlUmVzdWx0TGlzdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2hhbmRsZUVudGVyS2V5RG93bjogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy4kc2VsZWN0ZWRPcHRpb24gIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldFNlbGVjdGVkVmFsdWUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfaGFuZGxlQXJyb3dVcEFuZERvd25LZXlEb3duOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0b3BFdmVudChldmVudCk7XG4gICAgICAgICAgICB2YXIgJGF1dG9jb21wbGV0ZSA9IHRoaXMuX2dldEF1dG9jb21wbGV0ZUVsZW1lbnQoKTtcbiAgICAgICAgICAgIGlmICghJGF1dG9jb21wbGV0ZS5pcyhcIjp2aXNpYmxlXCIpICYmIHRoaXMuJGlucHV0LnZhbCgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cnlTZW5kSnNmQWpheFJlcXVlc3QoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoJGF1dG9jb21wbGV0ZS5pcyhcIjp2aXNpYmxlXCIpICYmICRhdXRvY29tcGxldGUuZmluZChcImxpXCIpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4kc2VsZWN0ZWRPcHRpb24gPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0UmVzdWx0T3B0aW9uRWxlbWVudCgkYXV0b2NvbXBsZXRlLmZpbmQoXCJsaVwiKVswXSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbW92ZVJlc3VsdE9wdGlvbkVsZW1lbnRTZWxlY3Rpb25DdXJzb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGF1dG9jb21wbGV0ZSwgZXZlbnQud2hpY2ggPT09IHRoaXMuX2tleUNvZGVzLmFycm93X3VwID8gLTEgOiAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2hhbmRsZUVzY2FwZUtleURvd246IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgdGhpcy5fc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIHRoaXMuX2hpZGVBdXRvY29tcGxldGVSZXN1bHRMaXN0KCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3RyeVNlbmRKc2ZBamF4UmVxdWVzdDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgICAgICAgICBpZiAoc2VsZi5pc1JlcXVlc3RSdW5uaW5nKSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJyZXF1ZXN0IGlzIGFjdGl2ZSwgc28gcmVtZW1iZXIgdGhhdCBjaGFuZ2VzIGhhcyBiZWVuIG1hZGUgd2hpbGUgcmVxdWVzdCB3YXMgcnVubmluZ1wiKTtcbiAgICAgICAgICAgICAgICBzZWxmLmFyZUNoYW5nZXNNYWRlV2hpbGVSZXF1ZXN0V2FzUnVubmluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzZWxmLnJlcXVlc3REZWxheVRpbWVySWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHNlbGYucmVxdWVzdERlbGF5VGltZXJJZClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VsZi5yZXF1ZXN0RGVsYXlUaW1lcklkID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNlbGYucmVxdWVzdERlbGF5VGltZXJJZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgc2VsZi5fc2VuZEpzZkFqYXhSZXF1ZXN0KCk7XG4gICAgICAgICAgICB9LCBzZWxmLlNFQVJDSF9SRVFVRVNUX0RFTEFZKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfc2VuZEpzZkFqYXhSZXF1ZXN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgICAgIGlmIChzZWxmLmlzUmVxdWVzdFJ1bm5pbmcpIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcInJlcXVlc3QgaXMgcnVubmluZywgYWJvcnRcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VsZi5pc1JlcXVlc3RSdW5uaW5nID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2VsZi5hcmVDaGFuZ2VzTWFkZVdoaWxlUmVxdWVzdFdhc1J1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHNlbGYuX3Nob3dMb2FkaW5nU3Bpbm5lcigpO1xuXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcInN0YXJ0aW5nIHJlcXVlc3RcIik7XG5cbiAgICAgICAgICAgIHZhciBpZCA9IHNlbGYuJGlucHV0LnBhcmVudCgpLnBhcmVudCgpLmF0dHIoJ2lkJyk7XG5cbiAgICAgICAgICAgIGpzZi5hamF4LnJlcXVlc3QoaWQsIFwiYXV0b2NvbXBsZXRlXCIsIHtcbiAgICAgICAgICAgICAgICBcImphdmF4LmZhY2VzLmJlaGF2aW9yLmV2ZW50XCI6IFwiYXV0b2NvbXBsZXRlXCIsXG4gICAgICAgICAgICAgICAgcmVuZGVyOiBzZWxmLmF1dG9jb21wbGV0ZUlkLFxuICAgICAgICAgICAgICAgIHBhcmFtczogc2VsZi4kaW5wdXQudmFsKCksXG4gICAgICAgICAgICAgICAgb25ldmVudDogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEuc3RhdHVzID09PSBcInN1Y2Nlc3NcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJyZXF1ZXN0IGZpbmlzaGVkXCIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IHNob3cgcmVzdWx0IGlmIGlucHV0IGZpZWxkIHN0aWxsIGhhcyBmb2N1c1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuJGlucHV0LmlzKFwiOmZvY3VzXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5faGFuZGxlQXV0b2NvbXBsZXRlUmVzdWx0TGlzdFZpc2liaWxpdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2hpZGVMb2FkaW5nU3Bpbm5lcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5pc1JlcXVlc3RSdW5uaW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLmFyZUNoYW5nZXNNYWRlV2hpbGVSZXF1ZXN0V2FzUnVubmluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiY2hhbmdlcyBtYWRlIHdoaWxlIHJlcXVlc3Qgd2FzIHJ1bm5pbmcsIHN0YXJ0IG5ldyByZXF1ZXN0IGF1dG9tYXRpY2FsbHlcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fc2VuZEpzZkFqYXhSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcblxuICAgICAgICBfaGFuZGxlQXV0b2NvbXBsZXRlUmVzdWx0TGlzdFZpc2liaWxpdHk6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgIHZhciAkYXV0b2NvbXBsZXRlID0gc2VsZi5fZ2V0QXV0b2NvbXBsZXRlRWxlbWVudCgpO1xuXG4gICAgICAgICAgICBpZiAoJGF1dG9jb21wbGV0ZS5maW5kKFwibGlcIikubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHNlbGYuX2luaXRBbmRTaG93QXV0b2NvbXBsZXRlUmVzdWx0TGlzdCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9oaWRlQXV0b2NvbXBsZXRlUmVzdWx0TGlzdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIF9zaG93TG9hZGluZ1NwaW5uZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICQoJzxkaXYgY2xhc3M9XCJidXR0ZXItZHJvcGRvd25saXN0LXNwaW5uZXItY29udGFpbmVyXCI+PGRpdiBjbGFzcz1cImJ1dHRlci1kcm9wZG93bmxpc3Qtc3Bpbm5lclwiPjwvZGl2PjwvZGl2PicpXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyh0aGlzLiRpbnB1dC5wYXJlbnQoKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2hpZGVMb2FkaW5nU3Bpbm5lcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy4kaW5wdXQucGFyZW50KCkuZmluZChcIi5idXR0ZXItZHJvcGRvd25saXN0LXNwaW5uZXJcIikucmVtb3ZlKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2luaXRBbmRTaG93QXV0b2NvbXBsZXRlUmVzdWx0TGlzdDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgdmFyICRhdXRvY29tcGxldGUgPSBzZWxmLl9nZXRBdXRvY29tcGxldGVFbGVtZW50KCk7XG4gICAgICAgICAgICAkYXV0b2NvbXBsZXRlXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLmNzcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogc2VsZi4kaW5wdXQuaW5uZXJXaWR0aCgpXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5oaWdobGlnaHQoc2VsZi4kaW5wdXQudmFsKCkpO1xuXG4gICAgICAgICAgICAkYXV0b2NvbXBsZXRlLmZpbmQoXCJ1bFwiKVxuICAgICAgICAgICAgICAgICAgICAub24oXCJtb3VzZWxlYXZlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NsZWFyUmVzdWx0T3B0aW9uU2VsZWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkYXV0b2NvbXBsZXRlLmZpbmQoXCJsaVwiKVxuICAgICAgICAgICAgICAgICAgICAub24oXCJtb3VzZWRvd25cIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fc2V0U2VsZWN0ZWRWYWx1ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAub24oXCJtb3VzZWVudGVyXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3NlbGVjdFJlc3VsdE9wdGlvbkVsZW1lbnQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9zZWxlY3RSZXN1bHRPcHRpb25FbGVtZW50OiBmdW5jdGlvbiAob3B0aW9uRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fY2xlYXJSZXN1bHRPcHRpb25TZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIHZhciAkc2VsZWN0ZWRPcHRpb25FbGVtZW50ID0gJChvcHRpb25FbGVtZW50KTtcbiAgICAgICAgICAgICRzZWxlY3RlZE9wdGlvbkVsZW1lbnQuYWRkQ2xhc3MoXCJidXR0ZXItZHJvcGRvd25saXN0LXJlc3VsdEl0ZW0tc2VsZWN0ZWRcIik7XG4gICAgICAgICAgICB0aGlzLiRzZWxlY3RlZE9wdGlvbiA9ICRzZWxlY3RlZE9wdGlvbkVsZW1lbnQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2NsZWFyUmVzdWx0T3B0aW9uU2VsZWN0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLiRzZWxlY3RlZE9wdGlvbiA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9nZXRBdXRvY29tcGxldGVFbGVtZW50KClcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoXCIuYnV0dGVyLWRyb3Bkb3dubGlzdC1yZXN1bHRJdGVtLXNlbGVjdGVkXCIpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcImJ1dHRlci1kcm9wZG93bmxpc3QtcmVzdWx0SXRlbS1zZWxlY3RlZFwiKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfbW92ZVJlc3VsdE9wdGlvbkVsZW1lbnRTZWxlY3Rpb25DdXJzb3I6IGZ1bmN0aW9uICgkYXV0b2NvbXBsZXRlLCBkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChkaXJlY3Rpb24gPiAwKSB7XG4gICAgICAgICAgICAgICAgdmFyICRuZXh0ID0gdGhpcy4kc2VsZWN0ZWRPcHRpb24ubmV4dCgpO1xuICAgICAgICAgICAgICAgIGlmICgkbmV4dC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NlbGVjdFJlc3VsdE9wdGlvbkVsZW1lbnQoJG5leHRbMF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vdGhlcmUgaXMgbm8gbmV4dFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RSZXN1bHRPcHRpb25FbGVtZW50KCRhdXRvY29tcGxldGUuZmluZChcImxpXCIpWzBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciAkcHJldiA9IHRoaXMuJHNlbGVjdGVkT3B0aW9uLnByZXYoKTtcbiAgICAgICAgICAgICAgICBpZiAoJHByZXYubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RSZXN1bHRPcHRpb25FbGVtZW50KCRwcmV2WzBdKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvL3RoZXJlIGlzIG5vIHByZXZpb3VzXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHRMaXN0T3B0aW9ucyA9ICRhdXRvY29tcGxldGUuZmluZChcImxpXCIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RSZXN1bHRPcHRpb25FbGVtZW50KHJlc3VsdExpc3RPcHRpb25zW3Jlc3VsdExpc3RPcHRpb25zLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3NldFNlbGVjdGVkVmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLiRzZWxlY3RlZE9wdGlvbiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlS2V5dXBFdmVudCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy4kaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC52YWwodGhpcy4kc2VsZWN0ZWRPcHRpb24uYXR0cihcImRhdGEtc2VsZWN0LXZhbHVlXCIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNoYW5nZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZm9jdXMoKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmtleXVwKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5faGlkZUF1dG9jb21wbGV0ZVJlc3VsdExpc3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfaGlkZUF1dG9jb21wbGV0ZVJlc3VsdExpc3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnJlcXVlc3REZWxheVRpbWVySWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMucmVxdWVzdERlbGF5VGltZXJJZClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuJHNlbGVjdGVkT3B0aW9uID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2dldEF1dG9jb21wbGV0ZUVsZW1lbnQoKS5oaWRlKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2dldEF1dG9jb21wbGV0ZUVsZW1lbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiAkKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuYXV0b2NvbXBsZXRlSWQpKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfc3RvcEV2ZW50OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG59KGpRdWVyeSkpOyIsIi8qKlxuICogalF1ZXJ5LVBsdWdpbiB0byBoYW5kbGUgYm9vdHN0cmFwIGZpeGVzLlxuICogV29ya3Mgd2l0aCBhdCBsZWFzdCBqUXVlcnkgMS4zLjIuXG4gKlxuICogSG93IHRvIHVzZTpcbiAqIGpRdWVyeShcIiNzb21lVHJlZVNlbGVjdG9yXCIpLmZpeEJvb3RzdHJhcERyb3BEb3duKCk7XG4gKi9cbihmdW5jdGlvbiAoJCkge1xuICAgICQuZm4uZml4Qm9vdHN0cmFwRHJvcERvd24gPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKCcuZHJvcGRvd24tbWVudScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICBpZigkKHRoaXMpLmhhc0NsYXNzKCdkcm9wZG93bi1tZW51LWZvcm0nKSkge1xuICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgIH07XG59KGpRdWVyeSkpOyIsIi8qKlxuICogYnV0dGVySXRlbUZpbHRlckZpZWxkIGlzIGEgalF1ZXJ5IHBsdWdpbiB0aGF0IGZpbHRlcnMgaHRtbCBlbGVtZW50IHdpdGggdGhlIGNzcyBjbGFzcyA8Y29kZT5maWx0ZXJhYmxlLWl0ZW08L2NvZGU+LlxuICogSXQgaXMgYXBwbGllZCB0byB0aGUgc2VhcmNoIGZpZWxkLjxici8+XG4gKiBJZiBubyBmaWx0ZXIgdGV4dCBpcyBlbnRlcmVkLCB0aGVuIGFsbCBmaWx0ZXJhYmxlLWl0ZW1zIGFyZSBkaXNwbGF5ZWQuIEVsc2UgdGhlIHNlYXJjaCBmaWVsZCB2YWx1ZSBpcyBtYXRjaGVkIGFnYWluc3QgPGI+YWxsPC9iPiB0ZXh0IGNvbnRhaW5lZCBieSBhIGZpbHRlcmFibGUtaXRlbS5cbiAqXG4gKiBIb3cgdG8gdXNlOlxuICogalF1ZXJ5KFwiI3NvbWVJbnB1dFNlbGVjdG9yXCIpLmJ1dHRlckl0ZW1GaWx0ZXJGaWVsZCgpO1xuICpcbiAqIEF1dGhvcjogWWFubiBNYXNzYXJkXG4gKi9cbihmdW5jdGlvbiAoJCkge1xuICAgIHZhciBkZWxheSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aW1lciA9IDA7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoY2FsbGJhY2ssIG1zKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KGNhbGxiYWNrLCBtcyk7XG4gICAgICAgIH07XG4gICAgfSkoKTtcblxuICAgIC8vIGV4dGVuZCBqUXVlcnkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAkLmZuLmJ1dHRlckl0ZW1GaWx0ZXJGaWVsZCA9IGZ1bmN0aW9uIChmaWx0ZXJhYmxlSXRlbUNvbnRhaW5lclNlbGVjdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKTtcbiAgICAgICAgICAgICR0aGlzLmtleXVwKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBkZWxheShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJWYWx1ZSA9ICR0aGlzLnZhbCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgY29udGFpbmVyIGFnYWluIGV2ZXJ5IHRpbWUsIGJlY2F1c2UgaXQgY291bGQgaGF2ZSBiZWVuIHJlcmVuZGVyZWQuXG4gICAgICAgICAgICAgICAgICAgIHZhciAkZmlsdGVyYWJsZUl0ZW1Db250YWluZXI7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJhYmxlSXRlbUNvbnRhaW5lclNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkZmlsdGVyYWJsZUl0ZW1Db250YWluZXIgPSAkKGZpbHRlcmFibGVJdGVtQ29udGFpbmVyU2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRhaW5lclNlbGVjdG9yID0gJHRoaXMuYXR0cignZGF0YS1maWx0ZXJhYmxlLWl0ZW0tY29udGFpbmVyJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAkZmlsdGVyYWJsZUl0ZW1Db250YWluZXIgPSAkKGNvbnRhaW5lclNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJhYmxlSXRlbXMgPSAkZmlsdGVyYWJsZUl0ZW1Db250YWluZXIuZmluZCgnLmZpbHRlcmFibGUtaXRlbScpO1xuXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcmFibGVJdGVtcy5lYWNoKGZ1bmN0aW9uIChpLCBlbGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgJGZpbHRlcmFibGVJdGVtID0gJChlbGVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkZmlsdGVyYWJsZUl0ZW0uaXMoJzpjb250YWluc0lnbm9yZUNhc2UoJyArIGZpbHRlclZhbHVlICsgJyknKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRmaWx0ZXJhYmxlSXRlbS5yZW1vdmVBdHRyKFwiaGlkZGVuXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRmaWx0ZXJhYmxlSXRlbS5oaWdobGlnaHQoZmlsdGVyVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZmlsdGVyYWJsZUl0ZW0uYXR0cihcImhpZGRlblwiLCBcImhpZGRlblwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9LCAzMDApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG59KGpRdWVyeSkpO1xuXG4oZnVuY3Rpb24gKCQpIHtcbiAgICAkLmV4cHJbXCI6XCJdLmNvbnRhaW5zSWdub3JlQ2FzZSA9ICQuZXhwci5jcmVhdGVQc2V1ZG8oZnVuY3Rpb24gKGFyZykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGVsZW0pIHtcbiAgICAgICAgICAgIHJldHVybiAhYXJnIHx8ICQoZWxlbSkudGV4dCgpLnRvVXBwZXJDYXNlKCkuaW5kZXhPZihhcmcudG9VcHBlckNhc2UoKSkgPj0gMDtcbiAgICAgICAgfTtcbiAgICB9KTtcbn0oalF1ZXJ5KSk7IiwiLyoqXG4gKiBqUXVlcnktUGx1Z2luIFwiQW5pbWF0ZSBkb3RzXCIgZm9yIHRyZWUgYW5pbWF0aW9uLiBBbmltYXRlcyBhIHdhaXRpbmcgZG90IGxpbmUgKDQgZG90cykgaW4gYW4gaW50ZXJ2YWwgb2YgMjAwIG1pbGxpc1xuICogYXMgaHRtbCBzdHJpbmcgaW4gZ2l2ZW4gY29tcG9uZW50LiBOb3RlOiBleGlzdGluZyBodG1sIGNvZGUgd2lsbCBiZSBjbGVhcmVkLlxuICogV29ya3Mgd2l0aCBhdCBsZWFzdCBqUXVlcnkgMS4zLjIuXG4gKlxuICogSG93IHRvIHVzZTpcbiAqIGpRdWVyeShcIiNzZWxlY3RvclwiKS5zdGFydERvdHMoKTtcbiAqIGpRdWVyeShcIiNzZWxlY3RvclwiKS5zdG9wRG90cygpO1xuICovXG4oZnVuY3Rpb24gKCQpIHtcbiAgICAvLyBleHRlbmQgalF1ZXJ5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICB2YXIgaW50ZXJ2YWxUcmlnZ2VyID0gbnVsbDtcblxuICAgICQuZm4uc3RhcnREb3RzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkb3JpZ2luYWxFbGVtZW50ID0gJCh0aGlzKTtcblxuICAgICAgICAgICAgJG9yaWdpbmFsRWxlbWVudC5odG1sKCcnKTtcblxuICAgICAgICAgICAgaW50ZXJ2YWxUcmlnZ2VyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICRvcmlnaW5hbEVsZW1lbnQuYXBwZW5kKCcuJyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoJG9yaWdpbmFsRWxlbWVudC5odG1sKCkubGVuZ3RoID4gNSkge1xuICAgICAgICAgICAgICAgICAgICAkb3JpZ2luYWxFbGVtZW50Lmh0bWwoJycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIDIwMCk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAkLmZuLnN0b3BEb3RzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkb3JpZ2luYWxFbGVtZW50ID0gJCh0aGlzKTtcblxuICAgICAgICAgICAgJG9yaWdpbmFsRWxlbWVudC5odG1sKCcnKTtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKGludGVydmFsVHJpZ2dlcik7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbn0oalF1ZXJ5KSk7IiwiKGZ1bmN0aW9uICgkKSB7XG4gICAgJC5mbi5oaWdobGlnaHQgPSBmdW5jdGlvbiAoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgIHZhciBoaWdobGlnaHRDbGFzc05hbWUgPSBcInNlYXJjaC1oaWdobGlnaHRlZFwiO1xuICAgICAgICB2YXIgcmVnZXggPSBuZXcgUmVnRXhwKHNlYXJjaFN0cmluZywgXCJnaVwiKTtcblxuICAgICAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmZpbmQoJyonKTtcbiAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2godGhpcyk7XG4gICAgICAgICAgICAkKHRoaXMpLmZpbmQoJy4nICsgaGlnaGxpZ2h0Q2xhc3NOYW1lKS5jb250ZW50cygpLnVud3JhcCgpO1xuICAgICAgICAgICAgdGhpcy5ub3JtYWxpemUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGVsZW1lbnRzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKTtcblxuICAgICAgICAgICAgaWYgKHNlYXJjaFN0cmluZyAmJiBzZWFyY2hTdHJpbmcgIT09ICcnKSB7XG4gICAgICAgICAgICAgICAgJHRoaXMuY29udGVudHMoKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5vZGVUeXBlID09PSAzICYmIHJlZ2V4LnRlc3QodGhpcy5ub2RlVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZVdpdGgoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0aGlzLm5vZGVWYWx1ZSB8fCBcIlwiKS5yZXBsYWNlKHJlZ2V4LCBmdW5jdGlvbiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCI8c3BhbiBjbGFzcz1cXFwiXCIgKyBoaWdobGlnaHRDbGFzc05hbWUgKyBcIlxcXCI+XCIgKyBtYXRjaCArIFwiPC9zcGFuPlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufShqUXVlcnkpKTsiLCIoZnVuY3Rpb24gKCQpIHtcbiAgICAvLyBleHRlbmQgalF1ZXJ5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgJC5mbi5tYXJrZG93blJlYWRvbmx5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcm9vdCA9ICQodGhpcyk7XG5cbiAgICAgICAgdmFyICRyZWFkb25seU1hcmtkb3duID0gcm9vdC5maW5kKCcuYnV0dGVyLWNvbXBvbmVudC12YWx1ZS1yZWFkb25seS13cmFwcGVyJyk7XG4gICAgICAgIHZhciBtYXJrZG93blRleHQgPSAkcmVhZG9ubHlNYXJrZG93bi5odG1sKClcbiAgICAgICAgICAgIC5yZXBsYWNlKCcmYW1wOycsICcmJylcbiAgICAgICAgICAgIC5yZXBsYWNlKCcmbHQ7JywgJzwnKVxuICAgICAgICAgICAgLnJlcGxhY2UoJyZndDsnLCAnPicpO1xuICAgICAgICB2YXIgbWFya2Rvd25UZXh0VG9IdG1sID0gbmV3IHNob3dkb3duLkNvbnZlcnRlcigpLm1ha2VIdG1sKG1hcmtkb3duVGV4dCk7XG5cbiAgICAgICAgJHJlYWRvbmx5TWFya2Rvd24uZW1wdHkoKTtcbiAgICAgICAgJHJlYWRvbmx5TWFya2Rvd24uYXBwZW5kKG1hcmtkb3duVGV4dFRvSHRtbCk7XG4gICAgfTtcbn0oalF1ZXJ5KSk7IiwiaWYgKHR5cGVvZiBidXR0ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgYnV0dGVyID0ge307XG59XG5idXR0ZXIubW9kYWwgPSB7fTtcblxuYnV0dGVyLm1vZGFsLm9wZW4gPSBmdW5jdGlvbiAoLyogc3RyaW5nICovIG1vZGFsUGFuZWxJZCkge1xuICAgIC8vIGNvbnNvbGUubG9nKCdPcGVuaW5nIG1vZGFsIHBhbmVsIHdpdGggZGF0YS1tb2RhbC1pZCAnICsgbW9kYWxQYW5lbElkKTtcbiAgICAkKCcuYnV0dGVyLW1vZGFsW2RhdGEtbW9kYWwtaWQ9JyArIG1vZGFsUGFuZWxJZCArICddJykubW9kYWwoe3Nob3c6IHRydWUsIGtleWJvYXJkOiBmYWxzZSwgYmFja2Ryb3A6ICdzdGF0aWMnfSlcbn07XG5cbmJ1dHRlci5tb2RhbC5jbG9zZSA9IGZ1bmN0aW9uICgvKiBzdHJpbmcgKi8gbW9kYWxQYW5lbElkKSB7XG4gICAgLy8gY29uc29sZS5sb2coJ0Nsb3NpbmcgbW9kYWwgcGFuZWwgd2l0aCBkYXRhLW1vZGFsLWlkICcgKyBtb2RhbFBhbmVsSWQpO1xuICAgICQoJy5idXR0ZXItbW9kYWxbZGF0YS1tb2RhbC1pZD0nICsgbW9kYWxQYW5lbElkICsgJ10nKS5tb2RhbCgnaGlkZScpO1xufTsiLCIvKipcbiAqIGpRdWVyeS1QbHVnaW4gXCJOdW1iZXIgU3Bpbm5lclwiIGZvciBpbnB1dCBmaWVsZHMuXG4gKiBXb3JrcyB3aXRoIGF0IGxlYXN0IGpRdWVyeSAxLjMuMi5cbiAqXG4gKiBIb3cgdG8gdXNlOlxuICogalF1ZXJ5KFwic29tZUJ1dHRlckNvbXBvbmVudFNlbGVjdG9yXCIpLmJ1dHRlck51bWJlclNwaW5uZXIoKTtcbiAqL1xuKGZ1bmN0aW9uICgkKSB7XG4gICAgLy8gZXh0ZW5kIGpRdWVyeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICQuZm4uYnV0dGVyTnVtYmVyU3Bpbm5lciA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbmV3IE51bWJlclNwaW5uZXIodGhpcywgb3B0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvLyBkZWZpbmUgY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHZhciBOdW1iZXJTcGlubmVyID0gQ2xhc3MuZXh0ZW5kKHtcbiAgICAgICAgaW5pdDogZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMuJGlucHV0ID0gJChlbGVtZW50KS5maW5kKFwiaW5wdXRcIik7XG4gICAgICAgICAgICB0aGlzLl9pbml0SW5wdXQoKTtcbiAgICAgICAgICAgIHRoaXMuX2luaXRPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy5fY291bnRlciA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnNldENvdW50ZXIoMCk7XG4gICAgICAgICAgICB0aGlzLl9pc1ZhbHVlU2V0ID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9pbml0QnV0dG9ucygpO1xuICAgICAgICAgICAgdGhpcy5faW5pdEFycm93S2V5cygpO1xuICAgICAgICAgICAgdGhpcy5faW5pdE1vdXNlV2hlZWwoKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfaW5pdElucHV0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICB0aGlzLiRpbnB1dFxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhcImJ1dHRlci1jb21wb25lbnQtbnVtYmVyLWlucHV0XCIpXG4gICAgICAgICAgICAgICAgLmJsdXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLl9zZXRWYWx1ZU9uQmx1cigpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnBhcmVudCgpLmFkZENsYXNzKFwiaW5wdXQtZ3JvdXBcIik7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2luaXRPcHRpb25zOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAgICAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIHN0ZXA6IDEsXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBkZWZhdWx0T3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgIC8vIGVuc3VyZSB0aGF0IHRoaXMgdmFsdWVzIGFyZSBudW1iZXJzXG4gICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5zdGVwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vcHRpb25zLnN0ZXAgPSB0aGlzLl9vcHRpb25zLnN0ZXAgKiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMubWluICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vcHRpb25zLm1pbiA9IHRoaXMuX29wdGlvbnMubWluICogMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLl9vcHRpb25zLm1heCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5tYXggPSB0aGlzLl9vcHRpb25zLm1heCAqIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2luaXRCdXR0b25zOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJG91dGVyQWRkb24gPSAkKFwiPGRpdj5cIilcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJpbnB1dC1ncm91cC1hcHBlbmRcIilcbiAgICAgICAgICAgICAgICAuaW5zZXJ0QWZ0ZXIodGhpcy4kaW5wdXQpO1xuXG4gICAgICAgICAgICB2YXIgJGFkZG9uID0gJChcIjxzcGFuPlwiKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhcImlucHV0LWdyb3VwLXRleHRcIilcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJidXR0ZXItY29tcG9uZW50LW51bWJlci1idXR0b25zXCIpXG4gICAgICAgICAgICAgICAgLmFwcGVuZFRvKCRvdXRlckFkZG9uKTtcblxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgJChcIjxzcGFuPlwiKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhcImdseXBoaWNvbiBnbHlwaGljb24tY2hldnJvbi11cFwiKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhcImJ1dHRlci1jb21wb25lbnQtbnVtYmVyLWJ1dHRvblwiKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLl9vcHRpb25zLmRpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIjtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jbGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZi5fb3B0aW9ucy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5pbmNyZWFzZUNvdW50ZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmFwcGVuZFRvKCRhZGRvbik7XG5cbiAgICAgICAgICAgICQoXCI8c3Bhbj5cIilcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJnbHlwaGljb24gZ2x5cGhpY29uLWNoZXZyb24tZG93blwiKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhcImJ1dHRlci1jb21wb25lbnQtbnVtYmVyLWJ1dHRvblwiKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLl9vcHRpb25zLmRpc2FibGVkID8gXCJkaXNhYmxlZFwiIDogXCJcIjtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jbGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VsZi5fb3B0aW9ucy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5kZWNyZWFzZUNvdW50ZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmFwcGVuZFRvKCRhZGRvbik7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2luaXRBcnJvd0tleXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgIHRoaXMuJGlucHV0LmtleWRvd24oZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LndoaWNoID09PSAzOCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbmNyZWFzZUNvdW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LndoaWNoID09PSA0MCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5kZWNyZWFzZUNvdW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcblxuICAgICAgICBfaW5pdE1vdXNlV2hlZWw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgIHRoaXMuJGlucHV0Lm9uKFwibW91c2V3aGVlbCBET01Nb3VzZVNjcm9sbFwiLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXNlbGYuJGlucHV0LmlzKCc6Zm9jdXMnKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGRlbHRhID0gZXZlbnQub3JpZ2luYWxFdmVudC53aGVlbERlbHRhIHx8IC1ldmVudC5vcmlnaW5hbEV2ZW50LmRlbHRhWSB8fCAtZXZlbnQub3JpZ2luYWxFdmVudC5kZXRhaWw7XG5cbiAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRlbHRhIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmRlY3JlYXNlQ291bnRlcigpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuaW5jcmVhc2VDb3VudGVyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3NldFZhbHVlT25CbHVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLiRpbnB1dC52YWwoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc1N0cmluZ0VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlucHV0LnZhbChcIlwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldENvdW50ZXIoMCk7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNWYWx1ZVNldCA9IGZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgcGFyc2VkSW50ID0gcGFyc2VJbnQodmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmIChpc05hTihwYXJzZWRJbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pc1ZhbHVlU2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRpbnB1dC52YWwodGhpcy5fY291bnRlcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRpbnB1dC52YWwoXCJcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldENvdW50ZXIoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc1ZhbHVlU2V0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldENvdW50ZXIocGFyc2VkSW50KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kaW5wdXQudmFsKHRoaXMuX2NvdW50ZXIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc1ZhbHVlU2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW5jcmVhc2VDb3VudGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNWYWx1ZVNldCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q291bnRlcih0aGlzLl9jb3VudGVyICsgdGhpcy5fb3B0aW9ucy5zdGVwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNWYWx1ZVNldCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLiRpbnB1dC52YWwodGhpcy5fY291bnRlcik7XG4gICAgICAgICAgICB0aGlzLiRpbnB1dC5jaGFuZ2UoKTtcbiAgICAgICAgfSxcblxuICAgICAgICBkZWNyZWFzZUNvdW50ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc1ZhbHVlU2V0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDb3VudGVyKHRoaXMuX2NvdW50ZXIgLSB0aGlzLl9vcHRpb25zLnN0ZXApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc1ZhbHVlU2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuJGlucHV0LnZhbCh0aGlzLl9jb3VudGVyKTtcbiAgICAgICAgICAgIHRoaXMuJGlucHV0LmNoYW5nZSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9pc1N0cmluZ0VtcHR5OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiAodmFsdWUubGVuZ3RoID09PSAwIHx8ICF2YWx1ZS50cmltKCkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHNldENvdW50ZXI6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMubWluICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgPCB0aGlzLl9vcHRpb25zLm1pbikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvdW50ZXIgPSB0aGlzLl9vcHRpb25zLm1pbjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fb3B0aW9ucy5tYXggIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSA+IHRoaXMuX29wdGlvbnMubWF4KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY291bnRlciA9IHRoaXMuX29wdGlvbnMubWF4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb3VudGVyID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn0oalF1ZXJ5KSk7IiwiaWYgKHR5cGVvZiBidXR0ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgYnV0dGVyID0ge307XG59XG5idXR0ZXIucHJldHR5cHJpbnQgPSB7fTtcblxuLyoqXG4gKiBjYWxscyBwcmV0dHkgcHJpbnQgamF2YXNjcmlwdCBmcmFtZXdvcmsgYW5kIHJlbW92ZXMgZmlyc3QgYW5kIGxhc3QgZW1wdHkgY2hpbGRyZW4uXG4gKi9cbmJ1dHRlci5wcmV0dHlwcmludC5jbGVhbnVwID0gZnVuY3Rpb24oKSB7XG4gICAgcHJldHR5UHJpbnQoKTtcblxuICAgIGpRdWVyeSgnLmJ1dHRlci1jb21wb25lbnQtcHJldHR5cHJpbnQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyICRmaXJzdFByZUNoaWxkID0galF1ZXJ5KHRoaXMpLmZpbmQoXCJwcmUgc3BhblwiKS5maXJzdCgpO1xuICAgICAgICB2YXIgJGxhc3RQcmVDaGlsZCA9IGpRdWVyeSh0aGlzKS5maW5kKFwicHJlIHNwYW5cIikubGFzdCgpO1xuXG5cbiAgICAgICAgaWYgKCEodHlwZW9mICRmaXJzdFByZUNoaWxkLmh0bWwoKSA9PT0gXCJ1bmRlZmluZWRcIikpIHtcbiAgICAgICAgICAgIGlmICghJGZpcnN0UHJlQ2hpbGQuaHRtbCgpLnRyaW0oKSkge1xuICAgICAgICAgICAgICAgICRmaXJzdFByZUNoaWxkLnJlbW92ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghKHR5cGVvZiAkbGFzdFByZUNoaWxkLmh0bWwoKSA9PT0gXCJ1bmRlZmluZWRcIikpIHtcbiAgICAgICAgICAgIGlmICghJGxhc3RQcmVDaGlsZC5odG1sKCkudHJpbSgpKSB7XG4gICAgICAgICAgICAgICAgJGxhc3RQcmVDaGlsZC5yZW1vdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufTsiLCIvKipcbiAqIEhvdyB0byB1c2U6XG4gKiBqUXVlcnkoXCIjc29tZVNlbGVjdG9yXCIpLnNjcm9sbFRvRmlyc3QoKSBvciBqUXVlcnkoXCIjc29tZVNlbGVjdG9yXCIpLnNjcm9sbFRvTGFzdCgpO1xuICovXG4oZnVuY3Rpb24gKCQpIHtcbiAgICAvLyBleHRlbmQgalF1ZXJ5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgJC5mbi5idXR0ZXJTY3JvbGxUb0ZpcnN0ID0gZnVuY3Rpb24gKC8qIGludCAqLyBvZmZzZXQpIHtcbiAgICAgICAgY29uc29sZS5sb2cob2Zmc2V0KTtcbiAgICAgICAgdmFyIF9vZmZzZXQgPSBvZmZzZXQgPT09IHVuZGVmaW5lZCA/ICQodGhpcykuZmlyc3QoKS5vZmZzZXQoKS50b3AgOiAkKHRoaXMpLmZpcnN0KCkub2Zmc2V0KCkudG9wICsgb2Zmc2V0O1xuICAgICAgICAkKCdodG1sLCBib2R5JykuYW5pbWF0ZSh7c2Nyb2xsVG9wOiBfb2Zmc2V0ICsgJ3B4J30sICdmYXN0Jyk7XG4gICAgfTtcblxuICAgICQuZm4uYnV0dGVyU2Nyb2xsVG9MYXN0ID0gZnVuY3Rpb24gKC8qIGludCAqLyBvZmZzZXQpIHtcbiAgICAgICAgY29uc29sZS5sb2cob2Zmc2V0KTtcbiAgICAgICAgdmFyIF9vZmZzZXQgPSBvZmZzZXQgPT09IHVuZGVmaW5lZCA/ICQodGhpcykubGFzdCgpLm9mZnNldCgpLnRvcCA6ICQodGhpcykubGFzdCgpLm9mZnNldCgpLnRvcCArIG9mZnNldDtcbiAgICAgICAgJCgnaHRtbCwgYm9keScpLmFuaW1hdGUoe3Njcm9sbFRvcDogX29mZnNldCArICdweCd9LCAnZmFzdCcpO1xuICAgIH07XG59KGpRdWVyeSkpOyIsIi8qKlxuICogalF1ZXJ5LVBsdWdpbiB0byBoYW5kbGUgc2VsZWN0aW9uIHN0eWxlIGNsYXNzZXMgb24gSlNGLUNvbXBvbmVudCBcImI6dGFibGVcIi5cbiAqIFdvcmtzIHdpdGggYXQgbGVhc3QgalF1ZXJ5IDEuMy4yLlxuICpcbiAqIEhvdyB0byB1c2U6XG4gKiBqUXVlcnkoXCIjc29tZVRyZWVTZWxlY3RvclwiKS5zZWxlY3RSb3coIHtyb3dJbmRleDogJzYnfSApO1xuICovXG4oZnVuY3Rpb24gKCQpIHtcbiAgICAvLyBleHRlbmQgalF1ZXJ5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgJC5mbi50b2dnbGVDb2x1bW5WaXNpYmlsdHkgPSBmdW5jdGlvbiAocmVuZGVySWRzLCBkaXNhYmxlUmVuZGVySWRzKSB7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHRvb2xiYXIgPSAkKHRoaXMpO1xuXG4gICAgICAgICAgICB2YXIganNvbiA9IEpTT04uc3RyaW5naWZ5KGNyZWF0ZUNvbHVtblZpc2liaWx0eSgkdG9vbGJhcikpO1xuICAgICAgICAgICAgQnV0dGVyRmFjZXMuQWpheC5zZW5kUmVxdWVzdCgkdG9vbGJhci5hdHRyKCdpZCcpLCAndG9nZ2xlJywgcmVuZGVySWRzLCBqc29uLCBkaXNhYmxlUmVuZGVySWRzKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZnVuY3Rpb24gY3JlYXRlQ29sdW1uVmlzaWJpbHR5KCR0b29sYmFyKSB7XG4gICAgICAgICAgICB2YXIgY29sdW1ucyA9IFtdO1xuXG4gICAgICAgICAgICAkdG9vbGJhci5maW5kKCcuYnV0dGVyLXRhYmxlLXRvb2xiYXItY29sdW1uLW9wdGlvbiBpbnB1dFt0eXBlPWNoZWNrYm94XScpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBjaGVja2JveCkge1xuICAgICAgICAgICAgICAgIHZhciAkY2hlY2tib3ggPSAkKGNoZWNrYm94KS5wYXJlbnQoJy5idXR0ZXItdGFibGUtdG9vbGJhci1jb2x1bW4tb3B0aW9uJyk7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcjogJGNoZWNrYm94LmF0dHIoJ2RhdGEtY29sdW1uLW1vZGVsLWlkZW50aWZpZXInKSxcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogJGNoZWNrYm94LmZpbmQoJ2lucHV0W3R5cGU9Y2hlY2tib3hdJykuaXMoJzpjaGVja2VkJylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gY29sdW1ucztcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAkLmZuLm9yZGVyQ29sdW1uID0gZnVuY3Rpb24gKHJlbmRlcklkcywgZGlzYWJsZVJlbmRlcklkcywgdG9MZWZ0LCBjb2x1bW5OdW1iZXIpIHtcblxuICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkdG9vbGJhciA9ICQodGhpcyk7XG5cbiAgICAgICAgICAgIGlmICh0b0xlZnQpIHtcbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdvcmRlciBjb2x1bW4gJyArIGNvbHVtbk51bWJlciArICcgdG8gbGVmdCcpO1xuICAgICAgICAgICAgICAgIG9yZGVyQ29sdW1uTGVmdCgkdG9vbGJhciwgY29sdW1uTnVtYmVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnb3JkZXIgY29sdW1uICcgKyBjb2x1bW5OdW1iZXIgKyAnIHRvIHJpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgb3JkZXJDb2x1bW5SaWdodCgkdG9vbGJhciwgY29sdW1uTnVtYmVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGpzb24gPSBKU09OLnN0cmluZ2lmeShjcmVhdGVDb2x1bW5PcmRlcigkdG9vbGJhcikpO1xuICAgICAgICAgICAgQnV0dGVyRmFjZXMuQWpheC5zZW5kUmVxdWVzdCgkdG9vbGJhci5hdHRyKCdpZCcpLCAnb3JkZXInLCByZW5kZXJJZHMsIGpzb24sIGRpc2FibGVSZW5kZXJJZHMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBmdW5jdGlvbiBjcmVhdGVDb2x1bW5PcmRlcigkdG9vbGJhcikge1xuICAgICAgICAgICAgdmFyIGNvbHVtbnMgPSBbXTtcblxuICAgICAgICAgICAgJHRvb2xiYXIuZmluZCgnLmJ1dHRlci10YWJsZS10b29sYmFyLWNvbHVtbi1vcHRpb24gaW5wdXRbdHlwZT1jaGVja2JveF0nKS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgY2hlY2tib3gpIHtcbiAgICAgICAgICAgICAgICB2YXIgJGNoZWNrYm94ID0gJChjaGVja2JveCkucGFyZW50KCcuYnV0dGVyLXRhYmxlLXRvb2xiYXItY29sdW1uLW9wdGlvbicpO1xuICAgICAgICAgICAgICAgIGNvbHVtbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXI6ICRjaGVja2JveC5hdHRyKCdkYXRhLWNvbHVtbi1tb2RlbC1pZGVudGlmaWVyJyksXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBpbmRleFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBjb2x1bW5zO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gb3JkZXJDb2x1bW5MZWZ0KC8qIGpxdWVyeSB0b29sYmFyICovICR0b29sYmFyLCBjb2x1bW5OdW1iZXIpIHtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJHRvb2xiYXIpO1xuXG4gICAgICAgICAgICB2YXIgJGNvbHVtbiA9ICR0b29sYmFyLmZpbmQoJ2xpW2RhdGEtb3JpZ2luYWwtY29sdW1uPVwiJyArIGNvbHVtbk51bWJlciArICdcIl0nKTtcbiAgICAgICAgICAgIHZhciAkbmV4dENvbHVtbiA9ICRjb2x1bW4ucHJldigpO1xuXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKCRjb2x1bW4pO1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZygkbmV4dENvbHVtbik7XG5cbiAgICAgICAgICAgIHZhciAkZGV0YWNodGVkQ29sdW1uID0gJGNvbHVtbi5kZXRhY2goKTtcbiAgICAgICAgICAgICRuZXh0Q29sdW1uLmJlZm9yZSgkZGV0YWNodGVkQ29sdW1uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIG9yZGVyQ29sdW1uUmlnaHQoLyoganF1ZXJ5IHRvb2xiYXIgKi8gJHRvb2xiYXIsIGNvbHVtbk51bWJlcikge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZygkdG9vbGJhcik7XG5cbiAgICAgICAgICAgIHZhciAkY29sdW1uID0gJHRvb2xiYXIuZmluZCgnbGlbZGF0YS1vcmlnaW5hbC1jb2x1bW49XCInICsgY29sdW1uTnVtYmVyICsgJ1wiXScpO1xuICAgICAgICAgICAgdmFyICRuZXh0Q29sdW1uID0gJGNvbHVtbi5uZXh0KCk7XG5cbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJGNvbHVtbik7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKCRuZXh0Q29sdW1uKTtcblxuICAgICAgICAgICAgdmFyICRkZXRhY2h0ZWRDb2x1bW4gPSAkY29sdW1uLmRldGFjaCgpO1xuICAgICAgICAgICAgJG5leHRDb2x1bW4uYWZ0ZXIoJGRldGFjaHRlZENvbHVtbik7XG4gICAgICAgIH1cbiAgICB9O1xufShqUXVlcnkpKTsiLCIoZnVuY3Rpb24gKCQpIHtcblxuICAgICQuZm4uX2J1dHRlclRvb2x0aXAgPSBmdW5jdGlvbiAoLyogb2JqZWN0ICovIGRhdGEpIHtcbiAgICAgICAgdmFyIHJvb3QgPSAkKHRoaXMpO1xuXG4gICAgICAgIC8vY29uc29sZS5sb2coZGF0YSk7XG5cbiAgICAgICAgdmFyIGNvbnRlbnQgPSBqUXVlcnkoJ1tuYW1lPScgKyBkYXRhLmNvbnRlbnRCeU5hbWUgKyAnXScpO1xuXG4gICAgICAgIHZhciBuZXdEYXRhID0ge1xuICAgICAgICAgICAgdHJpZ2dlcjogZGF0YS50cmlnZ2VyLFxuICAgICAgICAgICAgdGl0bGU6IGRhdGEudGl0bGUsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IGRhdGEucGxhY2VtZW50LFxuICAgICAgICAgICAgcGxhY2VtZW50RnVuY3Rpb246IGRhdGEucGxhY2VtZW50RnVuY3Rpb24sXG4gICAgICAgICAgICBtaW5WZXJ0aWNhbE9mZnNldDogZGF0YS5taW5WZXJ0aWNhbE9mZnNldCxcbiAgICAgICAgICAgIG1pbkhvcml6b250YWxPZmZzZXQ6IGRhdGEubWluSG9yaXpvbnRhbE9mZnNldCxcbiAgICAgICAgICAgIGNvbnRlbnQ6IGNvbnRlbnQuaHRtbCgpLnRyaW0oKVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vY29uc29sZS5sb2cobmV3RGF0YSk7XG5cbiAgICAgICAgY29udGVudC5yZW1vdmUoKTtcblxuICAgICAgICByb290LmJ1dHRlclRvb2x0aXAobmV3RGF0YSk7XG4gICAgfTtcblxuICAgICQuZm4uYnV0dGVyVG9vbHRpcCA9IGZ1bmN0aW9uICgvKiBvYmplY3QgKi8gZGF0YSkge1xuICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciByb290ID0gJCh0aGlzKTtcbiAgICAgICAgICAgIHZhciB0cmlnZ2VyID0gZGF0YS50cmlnZ2VyID8gZGF0YS50cmlnZ2VyIDogJ2hvdmVyJztcblxuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhkYXRhKTtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ3BsYWNlbWVudDogJyArIHBsYWNlbWVudCk7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKCd0cmlnZ2VyOiAnICsgdHJpZ2dlcik7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKCd2aWV3cG9ydDogJyArIGRhdGEudmlld3BvcnQpO1xuXG4gICAgICAgICAgICBpZiAoZGF0YS5taW5WZXJ0aWNhbE9mZnNldCkge1xuICAgICAgICAgICAgICAgIHJvb3QuYXR0cignZGF0YS10b29sdGlwLW1pbi12ZXJ0aWNhbC1vZmZzZXQnLCBkYXRhLm1pblZlcnRpY2FsT2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRhLm1pbkhvcml6b250YWxPZmZzZXQpIHtcbiAgICAgICAgICAgICAgICByb290LmF0dHIoJ2RhdGEtdG9vbHRpcC1taW4taG9yaXpvbnRhbC1vZmZzZXQnLCBkYXRhLm1pbkhvcml6b250YWxPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJvb3QubmV4dCgpLmhhc0NsYXNzKCdwb3BvdmVyJykpIHtcbiAgICAgICAgICAgICAgICByb290Lm5leHQoKS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICByb290LnBvcG92ZXIoe1xuICAgICAgICAgICAgICAgIHRyaWdnZXI6IHRyaWdnZXIsXG4gICAgICAgICAgICAgICAgcGxhY2VtZW50OiBmdW5jdGlvbihwb3BvdmVyLCBzb3VyY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEucGxhY2VtZW50ID8gZGF0YS5wbGFjZW1lbnQgOiAoZGF0YS5wbGFjZW1lbnRGdW5jdGlvbiA/IGRhdGEucGxhY2VtZW50RnVuY3Rpb24gOiBuZXcgQnV0dGVyRmFjZXMuVG9vbHRpcCgpLmNhbGN1bGF0ZVRvb2x0aXBQb3NpdGlvbihwb3BvdmVyLCBzb3VyY2UpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRpdGxlOiBkYXRhLnRpdGxlLFxuICAgICAgICAgICAgICAgIGh0bWw6IHRydWUsXG4gICAgICAgICAgICAgICAgY29udGVudDogZGF0YS5jb250ZW50LFxuICAgICAgICAgICAgICAgIHZpZXdwb3J0OiBkYXRhLnZpZXdwb3J0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn0oalF1ZXJ5KSk7Il19