import * as tslib_1 from "tslib";
import { searchAndInitialize, preventDefault, find, remove, internetExplorerOrEdgeVersion, scrollIntoView } from "../Utils";
import DomElement from "../DomElement";
import * as Inputs from "../Inputs";
import * as Dom from "../DomFunctions";
var CLASS_PLACEHOLDER = "select__placeholder";
var CLASS_THUMB = "select__thumb";
var CLASS_BUTTON = "select__button";
var CLASS_DROPDOWN = "select__dropdown";
var CLASS_OPEN = "select--open";
var CLASS_CLOSED = "select--closed";
var CLASS_DISABLED = "select--disabled";
var CLASS_FILTERABLE = "select--filterable";
var CLASS_ITEM = "dropdown-item";
var CLASS_ITEM_SELECTED = "dropdown-item--selected";
var CLASS_ITEM_FOCUSED = "dropdown-item--focused";
var CLASS_ITEM_DISABLED = "dropdown-item--disabled";
var CLASS_GROUP_ITEM = "dropdown-group";
var CLASS_GROUP_HEADER = "dropdown-group__item";
var QUERY_MESSAGE = ".message";
var TIMEOUT_CLOSE = 150;
var TIMEOUT_BLUR = 400;
/**
* The select component API.
*/
var Select = /** @class */ (function (_super) {
tslib_1.__extends(Select, _super);
function Select(element) {
var _this = _super.call(this, element) || this;
// Minimum filter length
_this._minFilterLength = 2;
// The options the Select was initially created upon
// These will be used as a basis for filtering
_this._initialOptions = Array.prototype.slice.call(_this.element.children);
_this._openByFocus = false;
// Check for multi-selection
_this._multiselection = _this.element.hasAttribute("multiple") === true;
// Setup event context
_this._clickHandler = _this._handleClick.bind(_this);
_this._handleDropdownClick = _this._handleClick.bind(_this);
_this._keydownHandler = _this._handleKeydown.bind(_this);
_this._focusHandler = _this._handleFocus.bind(_this);
_this._blurHandler = _this._handleBlur.bind(_this);
_this._windowClickHandler = _this._handleWindowClick.bind(_this);
_this._filterKeydownHandler = _this._handleFilterKeydown.bind(_this);
_this._filterKeyupHandler = _this._handleFilterKeyup.bind(_this);
_this._filterFocusHandler = _this._handleFilterFocus.bind(_this);
_this._initialize();
return _this;
}
/**
* Initializes the select component.
*
* This method inspects the select definition and its options and
* generates new stylable DOM elements around the original select-element
* definitions.
* @private
*/
Select.prototype._initialize = function () {
var e_1, _a;
var selectedOption = this.element.querySelector("option[selected]");
var firstOption = this.element.querySelector("option");
// Per default, set the last selected option to either the option with a "selected" attribute,
// or, if not found, to the first available option
this._lastSelectedOption = selectedOption || firstOption;
this._wrapperElement = new DomElement(this.element.parentElement)
.addClass(CLASS_CLOSED);
try {
for (var _b = tslib_1.__values(this.classes), _c = _b.next(); !_c.done; _c = _b.next()) {
var cls = _c.value;
this._wrapperElement.addClass(cls);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
this._dropdownElement = new DomElement("div")
.addClass(CLASS_DROPDOWN);
if (internetExplorerOrEdgeVersion() > 0 && internetExplorerOrEdgeVersion() < 12) {
// This is a workaround for IE browsers 11 and earlier where focusing
// a scrollable dropdown list will close the dropdown prematurely.
this._dropdownElement.element.addEventListener("mousedown", function (event) { return event.preventDefault(); });
}
this._setupTarget();
this._setupPlaceholder();
this._wrapperElement.appendChild(this._dropdownElement);
this._createOptions(this.element);
this._updateSize();
this._updateMessage();
if (this.element.disabled) {
this.disable();
}
else {
this.enable();
}
};
Select.prototype._setupTarget = function () {
// move the id from the select element to the wrapper
var id = this.element.getAttribute("id");
if (id) {
this.element.removeAttribute("id");
this._wrapperElement.setAttribute("id", id);
}
// Apply the tab index
var tabIndex = this.element.getAttribute("tabindex");
if (tabIndex) {
this._wrapperElement.setAttribute("tabIndex", tabIndex);
}
};
Select.prototype._setupPlaceholder = function () {
var _this = this;
if (!this._selectButtonElement) {
this._selectButtonElement = new DomElement("div")
.addClass(CLASS_BUTTON);
this._wrapperElement.appendChild(this._selectButtonElement);
}
if (!this._thumbElement) {
this._thumbElement = new DomElement("div")
.addClass(CLASS_THUMB);
var thumbIcon = new DomElement("div")
.addClass("thumb-icon");
var loader = new DomElement("div")
.addClass("loader-spinner")
.addClass("loader-spinner--small");
this._thumbElement.appendChild(loader);
this._thumbElement.appendChild(thumbIcon);
this._selectButtonElement.appendChild(this._thumbElement);
}
var placeholderText = "";
this._placeholderOption = this.element.querySelector("option[selected][disabled]") || undefined;
if (this._placeholderOption) {
placeholderText = Dom.text(this._placeholderOption);
if (this._multiselection === true) {
this._placeholderOption.selected = false;
}
}
var selectedOption = this.element.querySelector("option[selected]:not([disabled])");
if (selectedOption) {
placeholderText = Dom.text(selectedOption);
}
if (!this._placeholderElement) {
// When the Select is filterable, create an "input" as the placeholder element, otherwise a "span"
if (this._isFilterable()) {
this._placeholderElement = new DomElement("input");
this._placeholderElement.addEventListener("keyup", function (e) { return _this._handleFilterKeyup(e); });
this._placeholderElement.addEventListener("keydown", function (e) { return _this._handleFilterKeydown(e); });
this._placeholderElement.addEventListener("focus", function (e) { return _this._handleFilterFocus(e); });
}
else {
this._placeholderElement = new DomElement("span");
}
this._placeholderElement.addClass(CLASS_PLACEHOLDER);
this._selectButtonElement.appendChild(this._placeholderElement);
}
this._setPlaceholder(placeholderText);
this._placeholderText = placeholderText;
if (selectedOption && selectedOption !== this._placeholderOption) {
this._updatePlaceholder(true);
}
};
Select.prototype._updateMessage = function () {
var messageNode = this._wrapperElement.element.querySelector(QUERY_MESSAGE);
if (messageNode !== null) {
this._wrapperElement.appendChild(new DomElement(messageNode));
}
};
Select.prototype._isOptGroup = function (element) {
return element.tagName.toUpperCase() === "OPTGROUP";
};
Select.prototype._isOption = function (element) {
return element.tagName.toUpperCase() === "OPTION";
};
Select.prototype._createOptions = function (element) {
for (var i = 0; i < element.children.length; i++) {
var child = element.children[i];
if (this._isOptGroup(child)) {
this._appendGroup(child);
}
if (this._isOption(child)) {
var option = this._createOption(child);
if (option) {
this._dropdownElement.appendChild(option);
}
}
}
};
Select.prototype._createOption = function (option) {
var html = option.innerHTML;
if (this._activeFilter) {
var sanitizedActiveFilter = this._activeFilter.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
html = html.replace(new RegExp("(" + sanitizedActiveFilter + ")", "gi"), "$1 ");
}
var opt = new DomElement("div")
.addClass(CLASS_ITEM)
.setHtml(html);
if (option.selected) {
opt.addClass(CLASS_ITEM_SELECTED);
}
if (option.disabled) {
opt.addClass(CLASS_ITEM_DISABLED);
}
if (!this._isPlaceholder(option)) {
opt.setAttribute("data-value", option.value);
return opt;
}
return undefined;
};
Select.prototype._appendGroup = function (optgroup) {
var e_2, _a;
var label = optgroup.getAttribute("label");
var group = new DomElement("div")
.addClass(CLASS_GROUP_ITEM);
var groupHeader = new DomElement("div")
.addClass(CLASS_GROUP_HEADER)
.setHtml(label);
group.appendChild(groupHeader);
var options = optgroup.querySelectorAll("option");
try {
for (var options_1 = tslib_1.__values(options), options_1_1 = options_1.next(); !options_1_1.done; options_1_1 = options_1.next()) {
var entry = options_1_1.value;
var option = this._createOption(entry);
if (option) {
group.appendChild(option);
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (options_1_1 && !options_1_1.done && (_a = options_1.return)) _a.call(options_1);
}
finally { if (e_2) throw e_2.error; }
}
this._dropdownElement.appendChild(group);
return group;
};
Select.prototype._updateSize = function () {
var e_3, _a;
// Note: Mirroring the DOM and measuring the items using their clientWidth was very
// unreliable, therefore measuring was switched to the new HTML5 measureText method
// margins and paddings arround the text are copied from the original placeholder items
// dimension
var placeholderStyle = window.getComputedStyle(this._placeholderElement.element);
var paddingRight = parseFloat(placeholderStyle.paddingRight);
var paddingLeft = parseFloat(placeholderStyle.paddingLeft);
var font = this._placeholderElement.css("font");
var textWidth = Dom.textWidth(this._placeholderText, font);
var maxWidth = paddingLeft + paddingRight + textWidth;
var options = this._wrapperElement.element.querySelectorAll("." + CLASS_ITEM);
try {
for (var options_2 = tslib_1.__values(options), options_2_1 = options_2.next(); !options_2_1.done; options_2_1 = options_2.next()) {
var entry = options_2_1.value;
var width = Dom.textWidth(Dom.text(entry), font) + paddingLeft + paddingRight;
if (width > maxWidth) {
maxWidth = width;
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (options_2_1 && !options_2_1.done && (_a = options_2.return)) _a.call(options_2);
}
finally { if (e_3) throw e_3.error; }
}
};
Select.prototype._isButtonTarget = function (target) {
return (target === this._wrapperElement.element ||
target === this._placeholderElement.element ||
target === this._selectButtonElement.element ||
target === this._thumbElement.element);
};
Select.prototype._isDropdownTarget = function (target) {
var current = target;
while (current !== this._dropdownElement.element && current.parentElement) {
current = current.parentElement;
}
return current === this._dropdownElement.element;
};
/**
* Updates the UI if the selection has changed and makes sure the
* select control and the generated markup are synchronized.
* @private
*/
Select.prototype._selectedItemChanged = function (newItem, autoClose, multiselect) {
var _this = this;
if (autoClose === void 0) { autoClose = true; }
if (multiselect === void 0) { multiselect = false; }
var oldItems = this._dropdownElement.element.querySelectorAll("." + CLASS_ITEM_SELECTED);
if (!newItem) {
setTimeout(function () { return _this.close(); }, TIMEOUT_CLOSE);
return;
}
if (Dom.hasClass(newItem, CLASS_ITEM_DISABLED)) {
return;
}
if ((oldItems.length === 0) && !newItem) {
throw new Error("Can not select undefined elements");
}
var oldItem = oldItems[0];
if (multiselect === true) {
oldItem = find(oldItems, function (x) { return x.getAttribute("data-value") === newItem.getAttribute("data-value"); });
}
var isDeselect = false;
if (newItem && oldItem && oldItem === newItem) {
// Click on a previously selected element -> deselect
isDeselect = true;
if (!this._placeholderOption && !multiselect) {
// If there is no placeholder option, non multiselect options cannot be deselected
return;
}
delete this._lastSelectedOption;
}
if (oldItem) {
// Remove selection on the element
var oldValue_1 = oldItem.getAttribute("data-value");
var optElement = find(this.element.options, function (x) { return !x.disabled && x.value === oldValue_1; });
if (!optElement) {
throw new Error("The option with value " + oldValue_1 + " does not exist");
}
// Unset Select value
optElement.selected = false;
Dom.removeClass(oldItem, CLASS_ITEM_SELECTED);
}
if (!isDeselect) { // Select an option
// Select a new item
var newValue_1 = newItem.getAttribute("data-value");
var optElement = find(this.element.options, function (x) { return !x.disabled && x.value === newValue_1; });
if (!optElement) {
throw new Error("The option with value " + newValue_1 + " does not exist");
}
// Set Select value
optElement.selected = true;
Dom.addClass(newItem, CLASS_ITEM_SELECTED);
// Preserve selection
this._lastSelectedOption = optElement;
}
else { // Deselect an option
// Keep track of falling back to the placeholder (if any)
if (this._placeholderOption) {
this._lastSelectedOption = this._placeholderOption;
}
}
var hasSelectedItems = true;
if (this._multiselection === false && isDeselect) {
// Handle no selection for non-multiselect states
this._placeholderOption.selected = true;
hasSelectedItems = false;
}
if (this._multiselection === true && this._getSelectedOptions().length === 0) {
hasSelectedItems = false;
}
// Reset the filter if filterable
if (this._activeFilter) {
this._clearFilter();
}
this._updatePlaceholder(hasSelectedItems);
// Dispatch the changed event
this.dispatchEvent("change");
if (autoClose && !multiselect) {
setTimeout(function () {
_this.close();
}, TIMEOUT_CLOSE);
}
};
Select.prototype._updatePlaceholder = function (hasSelectedItems) {
var e_4, _a;
var text = this._placeholderOption ? Dom.text(this._placeholderOption) : " ";
if (hasSelectedItems === true) {
var selectedItems = this._getSelectedOptions();
if (selectedItems.length > 0) {
text = "";
try {
for (var selectedItems_1 = tslib_1.__values(selectedItems), selectedItems_1_1 = selectedItems_1.next(); !selectedItems_1_1.done; selectedItems_1_1 = selectedItems_1.next()) {
var item = selectedItems_1_1.value;
text += Dom.text(item) + ", ";
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (selectedItems_1_1 && !selectedItems_1_1.done && (_a = selectedItems_1.return)) _a.call(selectedItems_1);
}
finally { if (e_4) throw e_4.error; }
}
text = text.substring(0, text.length - 2);
}
}
this._setPlaceholder(text);
};
Select.prototype._getSelectedOptions = function () {
var selectedOptions = [];
if (this.element.options) {
[].forEach.call(this.element.options, (function (option) {
if (option.selected && !option.disabled) {
selectedOptions.push(option);
}
}));
}
return selectedOptions;
};
/**
* Clone all of the initially set options (and optgroups) and returns them in a new array.
* This serves as the basis for filtering. If a filter is present, it will be respected.
*/
Select.prototype.getInitialOptions = function () {
var filter = this._activeFilter || "";
var filtered = [];
var initialOptions = this._initialOptions;
for (var i = 0; i < initialOptions.length; i++) {
var child = initialOptions[i];
if (this._isOptGroup(child)) { // handle
var optGroupClone = child.cloneNode(false);
var found = false;
for (var j = 0; j < child.children.length; j++) {
var optionClone = child.children[j].cloneNode(true);
// Append on match
if (this._containsWord(optionClone.innerHTML, filter)) {
optGroupClone.appendChild(optionClone);
found = true;
}
}
// Push if any matches found
if (found) {
filtered.push(optGroupClone);
}
}
else if (this._isOption(child)) { // handle
var optionClone = child.cloneNode(true);
// Push on match
if (this._containsWord(optionClone.innerHTML, filter)) {
filtered.push(optionClone);
}
}
}
return filtered;
};
/**
* Returns true if a text contains a given keyword, e.g. in "ca" in "Car"
*/
Select.prototype._containsWord = function (text, keyword) {
return text.toLowerCase().indexOf(keyword.toLowerCase()) > -1;
};
Select.prototype._handleFocus = function () {
var _this = this;
this.open();
this._openByFocus = true;
setTimeout(function () {
_this._openByFocus = false;
}, TIMEOUT_BLUR);
};
Select.prototype._handleBlur = function () {
this.close();
};
Select.prototype._handleClick = function (event) {
var handled = false;
if (this._lastHandledEvent === event) {
this._lastHandledEvent = undefined;
return;
}
if (this._isButtonTarget(event.target) && this._openByFocus === false) {
// handle header item clicks and toggle dropdown
this.toggle();
handled = true;
}
var newItem = event.target;
if (!handled && Dom.hasClass(newItem, CLASS_ITEM)) {
// handle clicks on dropdown items
this._selectedItemChanged(newItem, true, this._multiselection);
handled = true;
}
if (handled) {
this._lastHandledEvent = event;
preventDefault(event);
}
};
Select.prototype._handleWindowClick = function (event) {
if (this._isDropdownTarget(event.target) || this._isButtonTarget(event.target)) {
return;
}
this.close();
};
Select.prototype._focusOptionStartingWith = function (keycode, startIndex, options) {
for (var index = startIndex; index < options.length; index++) {
var item = new DomElement(options[index]);
var value = item.innerText.toLowerCase();
if (index > options.length) {
index = 0;
}
if (value.startsWith(Inputs.getKeyValue(keycode))) {
var newOption = new DomElement(options[index]);
if (!newOption.hasClass(CLASS_ITEM_DISABLED)) {
scrollIntoView(options[index]);
newOption.addClass(CLASS_ITEM_FOCUSED);
return newOption;
}
}
}
return undefined;
};
Select.prototype._handleKeydown = function (event) {
var evt = event || window.event;
var keycode = event.which || event.keyCode;
if (keycode === Inputs.KEY_ESCAPE) {
// handle Escape key (ESC)
if (this.isOpen()) {
this.close();
}
evt.preventDefault();
return;
}
if (keycode === Inputs.KEY_ARROW_UP || keycode === Inputs.KEY_ARROW_DOWN) {
// Up and down arrows
var options = this._wrapperElement.element.querySelectorAll("." + CLASS_ITEM);
if (options.length > 0) {
var newIndex = 0;
var oldOption = void 0;
var focusedElement = this._wrapperElement.find("." + CLASS_ITEM_FOCUSED);
var searchFor = focusedElement ? CLASS_ITEM_FOCUSED : CLASS_ITEM_SELECTED;
var newElement = void 0;
for (var index = 0; index < options.length; index++) {
var direction = keycode === Inputs.KEY_ARROW_DOWN ? 1 : -1;
var item = new DomElement(options[index]);
// search for selected or focusedElement elements
if (item.hasClass(searchFor)) {
oldOption = item;
newIndex = index;
// get the next not disabled element in the appropriate direction
for (var count = 0; count < options.length; count++) {
newIndex += direction;
newIndex %= options.length;
if (newIndex < 0) {
newIndex = options.length - 1;
}
newElement = new DomElement(options[newIndex]);
if (!newElement.hasClass(CLASS_ITEM_DISABLED)) {
break;
}
}
}
}
// set the new element focused
scrollIntoView(options[newIndex]);
var newOption = new DomElement(options[newIndex]);
newOption.addClass(CLASS_ITEM_FOCUSED);
if (oldOption) {
oldOption.removeClass(CLASS_ITEM_FOCUSED);
}
}
evt.preventDefault();
return;
}
if (Inputs.getKeyValue(keycode) && !this._isFilterable()) {
// Keyboard keys
var options = this._wrapperElement.element.querySelectorAll("." + CLASS_ITEM);
if (options.length > 0) {
var oldFocusIndex = 0;
var hasFocusedOption = false;
for (var index = 0; index < options.length; index++) {
var item = new DomElement(options[index]);
if (item.hasClass(CLASS_ITEM_FOCUSED)) {
item.removeClass(CLASS_ITEM_FOCUSED);
var value = item.innerText.toLowerCase();
if (value.startsWith(Inputs.getKeyValue(keycode))) {
hasFocusedOption = true;
oldFocusIndex = index;
}
}
}
var newOption = this._focusOptionStartingWith(keycode, hasFocusedOption ? oldFocusIndex + 1 : 0, options);
if (newOption === undefined) {
this._focusOptionStartingWith(keycode, 0, options);
}
}
evt.preventDefault();
return;
}
if (keycode === Inputs.KEY_ENTER || keycode === Inputs.KEY_TAB) {
// Handle enter and tab key by selecting the currently focused element
var newItem = this._dropdownElement.element.querySelector("." + CLASS_ITEM_FOCUSED);
this._selectedItemChanged(newItem, true, this._multiselection);
}
};
/**
* Fired when the user presses a key in the filter field
*/
Select.prototype._handleFilterKeydown = function (e) {
var keycode = e.which || e.keyCode;
// If the user hits the enter key while filtering and there's a single match, select it
if (keycode === Inputs.KEY_ENTER) {
var dropdownElements = this._dropdownElement.element.querySelectorAll("." + CLASS_ITEM);
if (dropdownElements.length === 1) {
this._selectedItemChanged(dropdownElements[0], true, this._multiselection);
e.stopPropagation();
}
}
};
/**
* Fired when the user releases a key in the filter field
*/
Select.prototype._handleFilterKeyup = function (e) {
var target = e.target;
// Filter has changed
if (target.value !== this._activeFilter && target.value !== this._placeholderText && target.value !== this._lastSelectedOption.innerHTML) {
this._setFilter(target.value);
}
};
/**
* Fired when the user focusses the filter input field
*/
Select.prototype._handleFilterFocus = function (e) {
var target = e.target;
setTimeout(function () {
target.select();
});
};
/**
* Filters the Select by a given filter keyword
* @param filter Keyword to filter by
*/
Select.prototype._setFilter = function (filter) {
if (filter === void 0) { filter = ""; }
this._activeFilter = (filter.length >= this._minFilterLength) ? filter : "";
this.setOptions(this.getInitialOptions());
};
/**
* Resets the filter
*/
Select.prototype._clearFilter = function () {
delete this._activeFilter;
this.setOptions(this.getInitialOptions());
};
/**
* Set new content and reload the Select
* @param elements Array of new option (or optgroup) elements to display
*/
Select.prototype.setOptions = function (options) {
var _this = this;
this._emptyNode(this.element);
options.forEach(function (option) {
_this.element.appendChild(option);
});
// Preserve selected value if the selected
this.element.value = this._lastSelectedOption.value;
this.reload();
};
/**
* Clear all children of a given node
* @param node Node
*/
Select.prototype._emptyNode = function (node) {
while (node.firstChild) {
node.removeChild(node.firstChild);
}
};
/**
* Returns whether an option is a placeholder option
*/
Select.prototype._isPlaceholder = function (option) {
return option.hasAttribute("disabled") && option.hasAttribute("selected");
};
/**
* Update placeholder value
* @param text Content of the placeholder
*/
Select.prototype._setPlaceholder = function (text) {
if (this._placeholderElement && text) {
if (this._isFilterable()) {
this._placeholderElement.element.value = text;
}
else {
this._placeholderElement.setHtml(text);
}
}
};
Object.defineProperty(Select.prototype, "value", {
/**
* Gets the value of the currently selected option.
* If multiple selection is enabled this property returns an array of values.
*/
get: function () {
if (this._multiselection) {
return this._getSelectedOptions().map(function (x) { return x.value; });
}
if (this.element.value === "") {
return null;
}
return this.element.value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Select.prototype, "disabled", {
/**
* Enables or disables the select component depending on the
* 'value' parameter.
* @param {value} If true disables the control; false enables it.
*/
set: function (value) {
if (value) {
this.disable();
}
else {
this.enable();
}
},
enumerable: true,
configurable: true
});
/**
* Reloads the dropdown's option data definitions from the DOM and updates
* the generated dropdown display items.
*/
Select.prototype.reload = function () {
// Remove all existing child elements
this._emptyNode(this._dropdownElement.element);
if (this._activeFilter === undefined) { // If the user is filtering, let the placeholder "input" alive
this._setupPlaceholder();
}
this._createOptions(this.element);
this._updateSize();
this._updateMessage();
if (!this._isFilterable()) {
this._updatePlaceholder(!!this.value);
}
};
/**
* Sets the select control to the enabled state.
*/
Select.prototype.enable = function () {
this.element.removeAttribute("disabled");
this._wrapperElement.removeClass(CLASS_DISABLED);
window.addEventListener("click", this._windowClickHandler);
this._wrapperElement.element.addEventListener("click", this._clickHandler);
this._wrapperElement.element.addEventListener("keydown", this._keydownHandler);
this._wrapperElement.element.addEventListener("focus", this._focusHandler);
this._wrapperElement.element.addEventListener("blur", this._blurHandler);
};
/**
* Sets the select control to the disabled state.
*/
Select.prototype.disable = function () {
this.element.setAttribute("disabled", "");
this._wrapperElement.addClass(CLASS_DISABLED);
window.removeEventListener("click", this._windowClickHandler);
this._wrapperElement.element.removeEventListener("click", this._clickHandler);
this._wrapperElement.element.removeEventListener("keydown", this._keydownHandler);
this._wrapperElement.element.removeEventListener("focus", this._focusHandler);
this._wrapperElement.element.removeEventListener("blur", this._blurHandler);
this.close();
};
/**
* Toggles the open/closed state of the select dropdown.
*/
Select.prototype.toggle = function () {
if (this.isOpen()) {
this.close();
}
else {
this.open();
}
};
/**
* Gets if the select dropdown is open or closed.
* @return {boolean} True if open; otherwise false.
*/
Select.prototype.isOpen = function () {
return this._wrapperElement.hasClass(CLASS_OPEN);
};
/**
* Opens the select dropdown.
*/
Select.prototype.open = function () {
if (!this.isOpen()) {
this._openByFocus = false;
this._wrapperElement.removeClass(CLASS_CLOSED);
this._wrapperElement.addClass(CLASS_OPEN);
this._dropdownElement.element.addEventListener("click", this._handleDropdownClick);
this._dropdownElement.element.addEventListener("tap", this._handleDropdownClick);
}
};
/**
* Closes the select dropdown.
*/
Select.prototype.close = function () {
if (this.isOpen()) {
this._openByFocus = false;
this._wrapperElement.removeClass(CLASS_OPEN);
this._wrapperElement.addClass(CLASS_CLOSED);
// If the Select is filterable and therefore has an input field,
// reset the value of it to the chosen option
if (this._isFilterable()) {
// Unfocus input field
this._placeholderElement.element.blur();
if (!this._activeFilter || this._activeFilter === this._lastSelectedOption.innerHTML) {
this._setPlaceholder(this._lastSelectedOption.innerHTML);
}
}
this._dropdownElement.element.removeEventListener("click", this._handleDropdownClick);
this._dropdownElement.element.removeEventListener("tap", this._handleDropdownClick);
var focusedItem = this._wrapperElement.find("." + CLASS_ITEM_FOCUSED);
if (focusedItem) {
focusedItem.removeClass(CLASS_ITEM_FOCUSED);
}
}
};
/**
* Returns true when the element has the filter modifier class
*/
Select.prototype._isFilterable = function () {
return this._wrapperElement.hasClass(CLASS_FILTERABLE);
};
/**
* Destroys the component and clears all references.
*/
Select.prototype.destroy = function () {
window.removeEventListener("click", this._windowClickHandler);
if (this._dropdownElement) {
this._dropdownElement.element.removeEventListener("click", this._handleDropdownClick);
this._dropdownElement.element.removeEventListener("tap", this._handleDropdownClick);
remove(this._dropdownElement.element);
this._dropdownElement = undefined;
}
if (this._placeholderElement) {
this._placeholderElement.removeEventListener("keydown", this._filterKeydownHandler);
this._placeholderElement.removeEventListener("keyup", this._filterKeyupHandler);
this._placeholderElement.removeEventListener("focus", this._filterFocusHandler);
}
if (this._wrapperElement) {
this._wrapperElement.element.removeEventListener("click", this._clickHandler);
this._wrapperElement.element.removeEventListener("keydown", this._keydownHandler);
this._wrapperElement.element.removeEventListener("focus", this._focusHandler);
this._wrapperElement.element.removeEventListener("blur", this._blurHandler);
this._wrapperElement = undefined;
}
if (this._selectButtonElement) {
remove(this._selectButtonElement.element);
this._selectButtonElement = undefined;
}
this.removeClass(CLASS_CLOSED);
};
return Select;
}(DomElement));
export function init() {
searchAndInitialize("select", function (e) {
new Select(e);
});
}
export default Select;
//# sourceMappingURL=data:application/json;charset=utf8;base64,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SSxDQUFDLGVBQWUsRUFBRTtZQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBQzdFLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUE7WUFDakYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtZQUM3RSxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTNFLElBQVksQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFBO1NBQzFDO1FBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7WUFDN0IsTUFBTSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QyxJQUFZLENBQUMsb0JBQW9CLEdBQUcsU0FBUyxDQUFBO1NBQy9DO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUNoQyxDQUFDO0lBQ0gsYUFBQztBQUFELENBcjlCQSxBQXE5QkMsQ0FyOUJvQixVQUFVLEdBcTlCOUI7QUFFRCxNQUFNLFVBQVUsSUFBSTtJQUNsQixtQkFBbUIsQ0FBb0IsUUFBUSxFQUFFLFVBQUMsQ0FBQztRQUNqRCxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNmLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVELGVBQWUsTUFBTSxDQUFBIiwiZmlsZSI6Im1haW4vc3JjL2Zvcm0vU2VsZWN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc2VhcmNoQW5kSW5pdGlhbGl6ZSwgcHJldmVudERlZmF1bHQsIGZpbmQsIHJlbW92ZSwgaW50ZXJuZXRFeHBsb3Jlck9yRWRnZVZlcnNpb24sIHNjcm9sbEludG9WaWV3IH0gZnJvbSBcIi4uL1V0aWxzXCJcbmltcG9ydCBEb21FbGVtZW50IGZyb20gXCIuLi9Eb21FbGVtZW50XCJcbmltcG9ydCAqIGFzIElucHV0cyBmcm9tIFwiLi4vSW5wdXRzXCJcbmltcG9ydCAqIGFzIERvbSBmcm9tIFwiLi4vRG9tRnVuY3Rpb25zXCJcblxuY29uc3QgQ0xBU1NfUExBQ0VIT0xERVIgPSBcInNlbGVjdF9fcGxhY2Vob2xkZXJcIlxuY29uc3QgQ0xBU1NfVEhVTUIgPSBcInNlbGVjdF9fdGh1bWJcIlxuY29uc3QgQ0xBU1NfQlVUVE9OID0gXCJzZWxlY3RfX2J1dHRvblwiXG5jb25zdCBDTEFTU19EUk9QRE9XTiA9IFwic2VsZWN0X19kcm9wZG93blwiXG5cbmNvbnN0IENMQVNTX09QRU4gPSBcInNlbGVjdC0tb3BlblwiXG5jb25zdCBDTEFTU19DTE9TRUQgPSBcInNlbGVjdC0tY2xvc2VkXCJcbmNvbnN0IENMQVNTX0RJU0FCTEVEID0gXCJzZWxlY3QtLWRpc2FibGVkXCJcbmNvbnN0IENMQVNTX0ZJTFRFUkFCTEUgPSBcInNlbGVjdC0tZmlsdGVyYWJsZVwiXG5cbmNvbnN0IENMQVNTX0lURU0gPSBcImRyb3Bkb3duLWl0ZW1cIlxuY29uc3QgQ0xBU1NfSVRFTV9TRUxFQ1RFRCA9IFwiZHJvcGRvd24taXRlbS0tc2VsZWN0ZWRcIlxuY29uc3QgQ0xBU1NfSVRFTV9GT0NVU0VEID0gXCJkcm9wZG93bi1pdGVtLS1mb2N1c2VkXCJcbmNvbnN0IENMQVNTX0lURU1fRElTQUJMRUQgPSBcImRyb3Bkb3duLWl0ZW0tLWRpc2FibGVkXCJcblxuY29uc3QgQ0xBU1NfR1JPVVBfSVRFTSA9IFwiZHJvcGRvd24tZ3JvdXBcIlxuY29uc3QgQ0xBU1NfR1JPVVBfSEVBREVSID0gXCJkcm9wZG93bi1ncm91cF9faXRlbVwiXG5cbmNvbnN0IFFVRVJZX01FU1NBR0UgPSBcIi5tZXNzYWdlXCJcblxuY29uc3QgVElNRU9VVF9DTE9TRSA9IDE1MFxuY29uc3QgVElNRU9VVF9CTFVSID0gNDAwXG5cbi8qKlxuICogVGhlIHNlbGVjdCBjb21wb25lbnQgQVBJLlxuICovXG5jbGFzcyBTZWxlY3QgZXh0ZW5kcyBEb21FbGVtZW50PEhUTUxTZWxlY3RFbGVtZW50PiB7XG4gIHByaXZhdGUgX29wZW5CeUZvY3VzOiBib29sZWFuXG4gIHByaXZhdGUgX211bHRpc2VsZWN0aW9uOiBib29sZWFuXG4gIHByaXZhdGUgX2NsaWNrSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2hhbmRsZURyb3Bkb3duQ2xpY2s6IChlOiBFdmVudCkgPT4gdm9pZFxuICBwcml2YXRlIF9rZXlkb3duSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2ZvY3VzSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2JsdXJIYW5kbGVyOiAoZTogRXZlbnQpID0+IHZvaWRcbiAgcHJpdmF0ZSBfd2luZG93Q2xpY2tIYW5kbGVyOiAoZTogRXZlbnQpID0+IHZvaWRcbiAgcHJpdmF0ZSBfZmlsdGVyS2V5ZG93bkhhbmRsZXI6IChlOiBFdmVudCkgPT4gdm9pZFxuICBwcml2YXRlIF9maWx0ZXJLZXl1cEhhbmRsZXI6IChlOiBFdmVudCkgPT4gdm9pZFxuICBwcml2YXRlIF9maWx0ZXJGb2N1c0hhbmRsZXI6IChlOiBFdmVudCkgPT4gdm9pZFxuXG4gIHByaXZhdGUgX3dyYXBwZXJFbGVtZW50ITogRG9tRWxlbWVudFxuICBwcml2YXRlIF9kcm9wZG93bkVsZW1lbnQhOiBEb21FbGVtZW50PEhUTUxFbGVtZW50PlxuXG4gIHByaXZhdGUgX3NlbGVjdEJ1dHRvbkVsZW1lbnQhOiBEb21FbGVtZW50XG4gIHByaXZhdGUgX3RodW1iRWxlbWVudCE6IERvbUVsZW1lbnRcblxuICBwcml2YXRlIF9wbGFjZWhvbGRlck9wdGlvbj86IEhUTUxPcHRpb25FbGVtZW50XG4gIHByaXZhdGUgX3BsYWNlaG9sZGVyRWxlbWVudCE6IERvbUVsZW1lbnRcbiAgcHJpdmF0ZSBfcGxhY2Vob2xkZXJUZXh0ITogc3RyaW5nXG5cbiAgcHJpdmF0ZSBfbGFzdEhhbmRsZWRFdmVudD86IEV2ZW50XG4gIHByaXZhdGUgX2xhc3RTZWxlY3RlZE9wdGlvbj86IEhUTUxPcHRpb25FbGVtZW50XG5cbiAgLy8gTWluaW11bSBmaWx0ZXIgbGVuZ3RoXG4gIHByaXZhdGUgX21pbkZpbHRlckxlbmd0aCA9IDJcblxuICAvLyBUaGUga2V5d29yZCB0aGUgU2VsZWN0IGlzIGN1cnJlbnRseSBmaWx0ZXJlZCBieVxuICBwcml2YXRlIF9hY3RpdmVGaWx0ZXI/OiBzdHJpbmdcblxuICAvLyBUaGUgb3B0aW9ucyB0aGUgU2VsZWN0IHdhcyBpbml0aWFsbHkgY3JlYXRlZCB1cG9uXG4gIC8vIFRoZXNlIHdpbGwgYmUgdXNlZCBhcyBhIGJhc2lzIGZvciBmaWx0ZXJpbmdcbiAgcHJpdmF0ZSBfaW5pdGlhbE9wdGlvbnMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLmVsZW1lbnQuY2hpbGRyZW4pXG5cbiAgY29uc3RydWN0b3IoZWxlbWVudDogSFRNTFNlbGVjdEVsZW1lbnQpIHtcbiAgICBzdXBlcihlbGVtZW50KVxuXG4gICAgdGhpcy5fb3BlbkJ5Rm9jdXMgPSBmYWxzZVxuXG4gICAgLy8gQ2hlY2sgZm9yIG11bHRpLXNlbGVjdGlvblxuICAgIHRoaXMuX211bHRpc2VsZWN0aW9uID0gdGhpcy5lbGVtZW50Lmhhc0F0dHJpYnV0ZShcIm11bHRpcGxlXCIpID09PSB0cnVlXG5cbiAgICAvLyBTZXR1cCBldmVudCBjb250ZXh0XG4gICAgdGhpcy5fY2xpY2tIYW5kbGVyID0gdGhpcy5faGFuZGxlQ2xpY2suYmluZCh0aGlzKVxuICAgIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2sgPSB0aGlzLl9oYW5kbGVDbGljay5iaW5kKHRoaXMpXG4gICAgdGhpcy5fa2V5ZG93bkhhbmRsZXIgPSB0aGlzLl9oYW5kbGVLZXlkb3duLmJpbmQodGhpcylcbiAgICB0aGlzLl9mb2N1c0hhbmRsZXIgPSB0aGlzLl9oYW5kbGVGb2N1cy5iaW5kKHRoaXMpXG4gICAgdGhpcy5fYmx1ckhhbmRsZXIgPSB0aGlzLl9oYW5kbGVCbHVyLmJpbmQodGhpcylcbiAgICB0aGlzLl93aW5kb3dDbGlja0hhbmRsZXIgPSB0aGlzLl9oYW5kbGVXaW5kb3dDbGljay5iaW5kKHRoaXMpXG4gICAgdGhpcy5fZmlsdGVyS2V5ZG93bkhhbmRsZXIgPSB0aGlzLl9oYW5kbGVGaWx0ZXJLZXlkb3duLmJpbmQodGhpcylcbiAgICB0aGlzLl9maWx0ZXJLZXl1cEhhbmRsZXIgPSB0aGlzLl9oYW5kbGVGaWx0ZXJLZXl1cC5iaW5kKHRoaXMpXG4gICAgdGhpcy5fZmlsdGVyRm9jdXNIYW5kbGVyID0gdGhpcy5faGFuZGxlRmlsdGVyRm9jdXMuYmluZCh0aGlzKVxuXG4gICAgdGhpcy5faW5pdGlhbGl6ZSgpXG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgdGhlIHNlbGVjdCBjb21wb25lbnQuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGluc3BlY3RzIHRoZSBzZWxlY3QgZGVmaW5pdGlvbiBhbmQgaXRzIG9wdGlvbnMgYW5kXG4gICAqIGdlbmVyYXRlcyBuZXcgc3R5bGFibGUgRE9NIGVsZW1lbnRzIGFyb3VuZCB0aGUgb3JpZ2luYWwgc2VsZWN0LWVsZW1lbnRcbiAgICogZGVmaW5pdGlvbnMuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcm90ZWN0ZWQgX2luaXRpYWxpemUoKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRPcHRpb24gPSB0aGlzLmVsZW1lbnQucXVlcnlTZWxlY3RvcihcIm9wdGlvbltzZWxlY3RlZF1cIikgYXMgSFRNTE9wdGlvbkVsZW1lbnRcbiAgICBjb25zdCBmaXJzdE9wdGlvbiA9IHRoaXMuZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwib3B0aW9uXCIpIGFzIEhUTUxPcHRpb25FbGVtZW50XG5cbiAgICAvLyBQZXIgZGVmYXVsdCwgc2V0IHRoZSBsYXN0IHNlbGVjdGVkIG9wdGlvbiB0byBlaXRoZXIgdGhlIG9wdGlvbiB3aXRoIGEgXCJzZWxlY3RlZFwiIGF0dHJpYnV0ZSxcbiAgICAvLyBvciwgaWYgbm90IGZvdW5kLCB0byB0aGUgZmlyc3QgYXZhaWxhYmxlIG9wdGlvblxuICAgIHRoaXMuX2xhc3RTZWxlY3RlZE9wdGlvbiA9IHNlbGVjdGVkT3B0aW9uIHx8IGZpcnN0T3B0aW9uXG5cbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudCA9IG5ldyBEb21FbGVtZW50KHRoaXMuZWxlbWVudC5wYXJlbnRFbGVtZW50ISlcbiAgICAgIC5hZGRDbGFzcyhDTEFTU19DTE9TRUQpXG5cbiAgICBmb3IgKGxldCBjbHMgb2YgdGhpcy5jbGFzc2VzKSB7XG4gICAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5hZGRDbGFzcyhjbHMpXG4gICAgfVxuXG4gICAgdGhpcy5fZHJvcGRvd25FbGVtZW50ID0gbmV3IERvbUVsZW1lbnQ8SFRNTEVsZW1lbnQ+KFwiZGl2XCIpXG4gICAgICAuYWRkQ2xhc3MoQ0xBU1NfRFJPUERPV04pXG5cbiAgICBpZiAoaW50ZXJuZXRFeHBsb3Jlck9yRWRnZVZlcnNpb24oKSA+IDAgJiYgaW50ZXJuZXRFeHBsb3Jlck9yRWRnZVZlcnNpb24oKSA8IDEyKSB7XG4gICAgICAvLyBUaGlzIGlzIGEgd29ya2Fyb3VuZCBmb3IgSUUgYnJvd3NlcnMgMTEgYW5kIGVhcmxpZXIgd2hlcmUgZm9jdXNpbmdcbiAgICAgIC8vIGEgc2Nyb2xsYWJsZSBkcm9wZG93biBsaXN0IHdpbGwgY2xvc2UgdGhlIGRyb3Bkb3duIHByZW1hdHVyZWx5LlxuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLCAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IGV2ZW50LnByZXZlbnREZWZhdWx0KCkpXG4gICAgfVxuXG4gICAgdGhpcy5fc2V0dXBUYXJnZXQoKVxuICAgIHRoaXMuX3NldHVwUGxhY2Vob2xkZXIoKVxuXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5fZHJvcGRvd25FbGVtZW50KVxuXG4gICAgdGhpcy5fY3JlYXRlT3B0aW9ucyh0aGlzLmVsZW1lbnQpXG5cbiAgICB0aGlzLl91cGRhdGVTaXplKClcbiAgICB0aGlzLl91cGRhdGVNZXNzYWdlKClcblxuICAgIGlmICh0aGlzLmVsZW1lbnQuZGlzYWJsZWQpIHtcbiAgICAgIHRoaXMuZGlzYWJsZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW5hYmxlKClcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX3NldHVwVGFyZ2V0KCkge1xuICAgIC8vIG1vdmUgdGhlIGlkIGZyb20gdGhlIHNlbGVjdCBlbGVtZW50IHRvIHRoZSB3cmFwcGVyXG4gICAgY29uc3QgaWQgPSB0aGlzLmVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiaWRcIilcbiAgICBpZiAoaWQpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoXCJpZFwiKVxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgaWQpXG4gICAgfVxuXG4gICAgLy8gQXBwbHkgdGhlIHRhYiBpbmRleFxuICAgIGNvbnN0IHRhYkluZGV4ID0gdGhpcy5lbGVtZW50LmdldEF0dHJpYnV0ZShcInRhYmluZGV4XCIpXG4gICAgaWYgKHRhYkluZGV4KSB7XG4gICAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJ0YWJJbmRleFwiLCB0YWJJbmRleClcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX3NldHVwUGxhY2Vob2xkZXIoKSB7XG4gICAgaWYgKCF0aGlzLl9zZWxlY3RCdXR0b25FbGVtZW50KSB7XG4gICAgICB0aGlzLl9zZWxlY3RCdXR0b25FbGVtZW50ID0gbmV3IERvbUVsZW1lbnQoXCJkaXZcIilcbiAgICAgICAgLmFkZENsYXNzKENMQVNTX0JVVFRPTilcblxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5fc2VsZWN0QnV0dG9uRWxlbWVudClcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX3RodW1iRWxlbWVudCkge1xuICAgICAgdGhpcy5fdGh1bWJFbGVtZW50ID0gbmV3IERvbUVsZW1lbnQoXCJkaXZcIilcbiAgICAgICAgLmFkZENsYXNzKENMQVNTX1RIVU1CKVxuXG4gICAgICBsZXQgdGh1bWJJY29uID0gbmV3IERvbUVsZW1lbnQoXCJkaXZcIilcbiAgICAgICAgLmFkZENsYXNzKFwidGh1bWItaWNvblwiKVxuXG4gICAgICBsZXQgbG9hZGVyID0gbmV3IERvbUVsZW1lbnQoXCJkaXZcIilcbiAgICAgICAgLmFkZENsYXNzKFwibG9hZGVyLXNwaW5uZXJcIilcbiAgICAgICAgLmFkZENsYXNzKFwibG9hZGVyLXNwaW5uZXItLXNtYWxsXCIpXG5cbiAgICAgIHRoaXMuX3RodW1iRWxlbWVudC5hcHBlbmRDaGlsZChsb2FkZXIpXG4gICAgICB0aGlzLl90aHVtYkVsZW1lbnQuYXBwZW5kQ2hpbGQodGh1bWJJY29uKVxuICAgICAgdGhpcy5fc2VsZWN0QnV0dG9uRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLl90aHVtYkVsZW1lbnQpXG4gICAgfVxuXG4gICAgbGV0IHBsYWNlaG9sZGVyVGV4dCA9IFwiXCJcblxuICAgIHRoaXMuX3BsYWNlaG9sZGVyT3B0aW9uID0gdGhpcy5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJvcHRpb25bc2VsZWN0ZWRdW2Rpc2FibGVkXVwiKSBhcyBIVE1MT3B0aW9uRWxlbWVudCB8fCB1bmRlZmluZWRcblxuICAgIGlmICh0aGlzLl9wbGFjZWhvbGRlck9wdGlvbikge1xuICAgICAgcGxhY2Vob2xkZXJUZXh0ID0gRG9tLnRleHQodGhpcy5fcGxhY2Vob2xkZXJPcHRpb24pXG5cbiAgICAgIGlmICh0aGlzLl9tdWx0aXNlbGVjdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICB0aGlzLl9wbGFjZWhvbGRlck9wdGlvbi5zZWxlY3RlZCA9IGZhbHNlXG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHNlbGVjdGVkT3B0aW9uID0gdGhpcy5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJvcHRpb25bc2VsZWN0ZWRdOm5vdChbZGlzYWJsZWRdKVwiKVxuXG4gICAgaWYgKHNlbGVjdGVkT3B0aW9uKSB7XG4gICAgICBwbGFjZWhvbGRlclRleHQgPSBEb20udGV4dChzZWxlY3RlZE9wdGlvbilcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudCkge1xuICAgICAgLy8gV2hlbiB0aGUgU2VsZWN0IGlzIGZpbHRlcmFibGUsIGNyZWF0ZSBhbiBcImlucHV0XCIgYXMgdGhlIHBsYWNlaG9sZGVyIGVsZW1lbnQsIG90aGVyd2lzZSBhIFwic3BhblwiXG4gICAgICBpZiAodGhpcy5faXNGaWx0ZXJhYmxlKCkpIHtcbiAgICAgICAgdGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50ID0gbmV3IERvbUVsZW1lbnQoXCJpbnB1dFwiKVxuICAgICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleXVwXCIsIChlKSA9PiB0aGlzLl9oYW5kbGVGaWx0ZXJLZXl1cChlKSlcbiAgICAgICAgdGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChlKSA9PiB0aGlzLl9oYW5kbGVGaWx0ZXJLZXlkb3duKGUpKVxuICAgICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIChlKSA9PiB0aGlzLl9oYW5kbGVGaWx0ZXJGb2N1cyhlKSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudCA9IG5ldyBEb21FbGVtZW50KFwic3BhblwiKVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQuYWRkQ2xhc3MoQ0xBU1NfUExBQ0VIT0xERVIpXG4gICAgICB0aGlzLl9zZWxlY3RCdXR0b25FbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudClcbiAgICB9XG5cbiAgICB0aGlzLl9zZXRQbGFjZWhvbGRlcihwbGFjZWhvbGRlclRleHQpXG4gICAgdGhpcy5fcGxhY2Vob2xkZXJUZXh0ID0gcGxhY2Vob2xkZXJUZXh0XG5cbiAgICBpZiAoc2VsZWN0ZWRPcHRpb24gJiYgc2VsZWN0ZWRPcHRpb24gIT09IHRoaXMuX3BsYWNlaG9sZGVyT3B0aW9uKSB7XG4gICAgICB0aGlzLl91cGRhdGVQbGFjZWhvbGRlcih0cnVlKVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfdXBkYXRlTWVzc2FnZSgpIHtcbiAgICBjb25zdCBtZXNzYWdlTm9kZSA9IHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucXVlcnlTZWxlY3RvcihRVUVSWV9NRVNTQUdFKVxuICAgIGlmIChtZXNzYWdlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYXBwZW5kQ2hpbGQobmV3IERvbUVsZW1lbnQobWVzc2FnZU5vZGUpKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2lzT3B0R3JvdXAoZWxlbWVudDogRWxlbWVudCk6IGVsZW1lbnQgaXMgSFRNTE9wdEdyb3VwRWxlbWVudCB7XG4gICAgcmV0dXJuIGVsZW1lbnQudGFnTmFtZS50b1VwcGVyQ2FzZSgpID09PSBcIk9QVEdST1VQXCJcbiAgfVxuXG4gIHByaXZhdGUgX2lzT3B0aW9uKGVsZW1lbnQ6IEVsZW1lbnQpOiBlbGVtZW50IGlzIEhUTUxPcHRpb25FbGVtZW50IHtcbiAgICByZXR1cm4gZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09IFwiT1BUSU9OXCJcbiAgfVxuXG4gIHByb3RlY3RlZCBfY3JlYXRlT3B0aW9ucyhlbGVtZW50OiBIVE1MU2VsZWN0RWxlbWVudCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudC5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IGNoaWxkID0gZWxlbWVudC5jaGlsZHJlbltpXVxuXG4gICAgICBpZiAodGhpcy5faXNPcHRHcm91cChjaGlsZCkpIHtcbiAgICAgICAgdGhpcy5fYXBwZW5kR3JvdXAoY2hpbGQgYXMgSFRNTE9wdEdyb3VwRWxlbWVudClcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX2lzT3B0aW9uKGNoaWxkKSkge1xuICAgICAgICBsZXQgb3B0aW9uID0gdGhpcy5fY3JlYXRlT3B0aW9uKGNoaWxkIGFzIEhUTUxPcHRpb25FbGVtZW50KVxuXG4gICAgICAgIGlmIChvcHRpb24pIHtcbiAgICAgICAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuYXBwZW5kQ2hpbGQob3B0aW9uKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9jcmVhdGVPcHRpb24ob3B0aW9uOiBIVE1MT3B0aW9uRWxlbWVudCkge1xuICAgIGxldCBodG1sID0gb3B0aW9uLmlubmVySFRNTFxuXG4gICAgaWYgKHRoaXMuX2FjdGl2ZUZpbHRlcikge1xuICAgICAgY29uc3Qgc2FuaXRpemVkQWN0aXZlRmlsdGVyID0gdGhpcy5fYWN0aXZlRmlsdGVyLnJlcGxhY2UoL1stXFxcXF4kKis/LigpfFtcXF17fV0vZywgXCJcXFxcJCZcIilcbiAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UobmV3IFJlZ0V4cChgKCR7c2FuaXRpemVkQWN0aXZlRmlsdGVyfSlgLCBcImdpXCIpLCBcIjxzdHJvbmc+JDE8L3N0cm9uZz5cIilcbiAgICB9XG5cbiAgICBsZXQgb3B0ID0gbmV3IERvbUVsZW1lbnQoXCJkaXZcIilcbiAgICAgIC5hZGRDbGFzcyhDTEFTU19JVEVNKVxuICAgICAgLnNldEh0bWwoaHRtbClcblxuICAgIGlmIChvcHRpb24uc2VsZWN0ZWQpIHtcbiAgICAgIG9wdC5hZGRDbGFzcyhDTEFTU19JVEVNX1NFTEVDVEVEKVxuICAgIH1cblxuICAgIGlmIChvcHRpb24uZGlzYWJsZWQpIHtcbiAgICAgIG9wdC5hZGRDbGFzcyhDTEFTU19JVEVNX0RJU0FCTEVEKVxuICAgIH1cblxuICAgIGlmICghdGhpcy5faXNQbGFjZWhvbGRlcihvcHRpb24pKSB7XG4gICAgICBvcHQuc2V0QXR0cmlidXRlKFwiZGF0YS12YWx1ZVwiLCBvcHRpb24udmFsdWUpXG4gICAgICByZXR1cm4gb3B0XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgcHJvdGVjdGVkIF9hcHBlbmRHcm91cChvcHRncm91cDogSFRNTE9wdEdyb3VwRWxlbWVudCkge1xuICAgIGxldCBsYWJlbCA9IG9wdGdyb3VwLmdldEF0dHJpYnV0ZShcImxhYmVsXCIpIVxuXG4gICAgbGV0IGdyb3VwID0gbmV3IERvbUVsZW1lbnQoXCJkaXZcIilcbiAgICAgIC5hZGRDbGFzcyhDTEFTU19HUk9VUF9JVEVNKVxuXG4gICAgbGV0IGdyb3VwSGVhZGVyID0gbmV3IERvbUVsZW1lbnQoXCJkaXZcIilcbiAgICAgIC5hZGRDbGFzcyhDTEFTU19HUk9VUF9IRUFERVIpXG4gICAgICAuc2V0SHRtbChsYWJlbClcblxuICAgIGdyb3VwLmFwcGVuZENoaWxkKGdyb3VwSGVhZGVyKVxuXG4gICAgbGV0IG9wdGlvbnMgPSBvcHRncm91cC5xdWVyeVNlbGVjdG9yQWxsKFwib3B0aW9uXCIpXG4gICAgZm9yIChsZXQgZW50cnkgb2Ygb3B0aW9ucykge1xuICAgICAgbGV0IG9wdGlvbiA9IHRoaXMuX2NyZWF0ZU9wdGlvbihlbnRyeSlcbiAgICAgIGlmIChvcHRpb24pIHtcbiAgICAgICAgZ3JvdXAuYXBwZW5kQ2hpbGQob3B0aW9uKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5hcHBlbmRDaGlsZChncm91cClcbiAgICByZXR1cm4gZ3JvdXBcbiAgfVxuXG4gIHByb3RlY3RlZCBfdXBkYXRlU2l6ZSgpIHtcbiAgICAvLyBOb3RlOiBNaXJyb3JpbmcgdGhlIERPTSBhbmQgbWVhc3VyaW5nIHRoZSBpdGVtcyB1c2luZyB0aGVpciBjbGllbnRXaWR0aCB3YXMgdmVyeVxuICAgIC8vIHVucmVsaWFibGUsIHRoZXJlZm9yZSBtZWFzdXJpbmcgd2FzIHN3aXRjaGVkIHRvIHRoZSBuZXcgSFRNTDUgbWVhc3VyZVRleHQgbWV0aG9kXG4gICAgLy8gbWFyZ2lucyBhbmQgcGFkZGluZ3MgYXJyb3VuZCB0aGUgdGV4dCBhcmUgY29waWVkIGZyb20gdGhlIG9yaWdpbmFsIHBsYWNlaG9sZGVyIGl0ZW1zXG4gICAgLy8gZGltZW5zaW9uXG4gICAgY29uc3QgcGxhY2Vob2xkZXJTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5lbGVtZW50KVxuXG4gICAgbGV0IHBhZGRpbmdSaWdodCA9IHBhcnNlRmxvYXQocGxhY2Vob2xkZXJTdHlsZS5wYWRkaW5nUmlnaHQhKVxuICAgIGxldCBwYWRkaW5nTGVmdCA9IHBhcnNlRmxvYXQocGxhY2Vob2xkZXJTdHlsZS5wYWRkaW5nTGVmdCEpXG5cbiAgICBsZXQgZm9udCA9IHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5jc3MoXCJmb250XCIpXG4gICAgbGV0IHRleHRXaWR0aCA9IERvbS50ZXh0V2lkdGgodGhpcy5fcGxhY2Vob2xkZXJUZXh0LCBmb250KVxuICAgIGxldCBtYXhXaWR0aCA9IHBhZGRpbmdMZWZ0ICsgcGFkZGluZ1JpZ2h0ICsgdGV4dFdpZHRoXG5cbiAgICBsZXQgb3B0aW9ucyA9IHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSVRFTX1gKVxuICAgIGZvciAobGV0IGVudHJ5IG9mIG9wdGlvbnMpIHtcbiAgICAgIGxldCB3aWR0aCA9IERvbS50ZXh0V2lkdGgoRG9tLnRleHQoZW50cnkpLCBmb250KSArIHBhZGRpbmdMZWZ0ICsgcGFkZGluZ1JpZ2h0XG5cbiAgICAgIGlmICh3aWR0aCA+IG1heFdpZHRoKSB7XG4gICAgICAgIG1heFdpZHRoID0gd2lkdGhcbiAgICAgIH1cbiAgICB9XG5cbiAgfVxuXG4gIHByb3RlY3RlZCBfaXNCdXR0b25UYXJnZXQodGFyZ2V0OiBFdmVudFRhcmdldCkge1xuICAgIHJldHVybiAodGFyZ2V0ID09PSB0aGlzLl93cmFwcGVyRWxlbWVudC5lbGVtZW50IHx8XG4gICAgICB0YXJnZXQgPT09IHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5lbGVtZW50IHx8XG4gICAgICB0YXJnZXQgPT09IHRoaXMuX3NlbGVjdEJ1dHRvbkVsZW1lbnQuZWxlbWVudCB8fFxuICAgICAgdGFyZ2V0ID09PSB0aGlzLl90aHVtYkVsZW1lbnQuZWxlbWVudClcbiAgfVxuXG4gIHByb3RlY3RlZCBfaXNEcm9wZG93blRhcmdldCh0YXJnZXQ6IEV2ZW50VGFyZ2V0KSB7XG4gICAgbGV0IGN1cnJlbnQgPSB0YXJnZXQgYXMgSFRNTEVsZW1lbnRcbiAgICB3aGlsZSAoY3VycmVudCAhPT0gdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQgJiYgY3VycmVudC5wYXJlbnRFbGVtZW50KSB7XG4gICAgICBjdXJyZW50ID0gY3VycmVudC5wYXJlbnRFbGVtZW50XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnQgPT09IHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5lbGVtZW50XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgVUkgaWYgdGhlIHNlbGVjdGlvbiBoYXMgY2hhbmdlZCBhbmQgbWFrZXMgc3VyZSB0aGVcbiAgICogc2VsZWN0IGNvbnRyb2wgYW5kIHRoZSBnZW5lcmF0ZWQgbWFya3VwIGFyZSBzeW5jaHJvbml6ZWQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcm90ZWN0ZWQgX3NlbGVjdGVkSXRlbUNoYW5nZWQoXG4gICAgbmV3SXRlbTogRWxlbWVudCxcbiAgICBhdXRvQ2xvc2UgPSB0cnVlLFxuICAgIG11bHRpc2VsZWN0ID0gZmFsc2VcbiAgKSB7XG4gICAgY29uc3Qgb2xkSXRlbXMgPSB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19JVEVNX1NFTEVDVEVEfWApXG5cbiAgICBpZiAoIW5ld0l0ZW0pIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jbG9zZSgpLCBUSU1FT1VUX0NMT1NFKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKERvbS5oYXNDbGFzcyhuZXdJdGVtLCBDTEFTU19JVEVNX0RJU0FCTEVEKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKChvbGRJdGVtcy5sZW5ndGggPT09IDApICYmICFuZXdJdGVtKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4gbm90IHNlbGVjdCB1bmRlZmluZWQgZWxlbWVudHNcIilcbiAgICB9XG5cbiAgICBsZXQgb2xkSXRlbSA9IG9sZEl0ZW1zWzBdXG5cbiAgICBpZiAobXVsdGlzZWxlY3QgPT09IHRydWUpIHtcbiAgICAgIG9sZEl0ZW0gPSBmaW5kKG9sZEl0ZW1zLCAoeCkgPT4geC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXZhbHVlXCIpID09PSBuZXdJdGVtLmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIikpIVxuICAgIH1cblxuICAgIGxldCBpc0Rlc2VsZWN0ID0gZmFsc2VcblxuICAgIGlmIChuZXdJdGVtICYmIG9sZEl0ZW0gJiYgb2xkSXRlbSA9PT0gbmV3SXRlbSkge1xuICAgICAgLy8gQ2xpY2sgb24gYSBwcmV2aW91c2x5IHNlbGVjdGVkIGVsZW1lbnQgLT4gZGVzZWxlY3RcbiAgICAgIGlzRGVzZWxlY3QgPSB0cnVlXG5cbiAgICAgIGlmICghdGhpcy5fcGxhY2Vob2xkZXJPcHRpb24gJiYgIW11bHRpc2VsZWN0KSB7XG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIHBsYWNlaG9sZGVyIG9wdGlvbiwgbm9uIG11bHRpc2VsZWN0IG9wdGlvbnMgY2Fubm90IGJlIGRlc2VsZWN0ZWRcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGRlbGV0ZSB0aGlzLl9sYXN0U2VsZWN0ZWRPcHRpb25cbiAgICB9XG5cbiAgICBpZiAob2xkSXRlbSkge1xuICAgICAgLy8gUmVtb3ZlIHNlbGVjdGlvbiBvbiB0aGUgZWxlbWVudFxuICAgICAgbGV0IG9sZFZhbHVlID0gb2xkSXRlbS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXZhbHVlXCIpXG4gICAgICBsZXQgb3B0RWxlbWVudCA9IGZpbmQodGhpcy5lbGVtZW50Lm9wdGlvbnMsICh4KSA9PiAheC5kaXNhYmxlZCAmJiB4LnZhbHVlID09PSBvbGRWYWx1ZSlcblxuICAgICAgaWYgKCFvcHRFbGVtZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIG9wdGlvbiB3aXRoIHZhbHVlICR7b2xkVmFsdWV9IGRvZXMgbm90IGV4aXN0YClcbiAgICAgIH1cblxuICAgICAgLy8gVW5zZXQgU2VsZWN0IHZhbHVlXG4gICAgICBvcHRFbGVtZW50LnNlbGVjdGVkID0gZmFsc2VcbiAgICAgIERvbS5yZW1vdmVDbGFzcyhvbGRJdGVtLCBDTEFTU19JVEVNX1NFTEVDVEVEKVxuICAgIH1cblxuICAgIGlmICghaXNEZXNlbGVjdCkgeyAvLyBTZWxlY3QgYW4gb3B0aW9uXG4gICAgICAvLyBTZWxlY3QgYSBuZXcgaXRlbVxuICAgICAgbGV0IG5ld1ZhbHVlID0gbmV3SXRlbS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXZhbHVlXCIpXG4gICAgICBsZXQgb3B0RWxlbWVudCA9IGZpbmQodGhpcy5lbGVtZW50Lm9wdGlvbnMsICh4KSA9PiAheC5kaXNhYmxlZCAmJiB4LnZhbHVlID09PSBuZXdWYWx1ZSlcblxuICAgICAgaWYgKCFvcHRFbGVtZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIG9wdGlvbiB3aXRoIHZhbHVlICR7bmV3VmFsdWV9IGRvZXMgbm90IGV4aXN0YClcbiAgICAgIH1cblxuICAgICAgLy8gU2V0IFNlbGVjdCB2YWx1ZVxuICAgICAgb3B0RWxlbWVudC5zZWxlY3RlZCA9IHRydWVcbiAgICAgIERvbS5hZGRDbGFzcyhuZXdJdGVtLCBDTEFTU19JVEVNX1NFTEVDVEVEKVxuXG4gICAgICAvLyBQcmVzZXJ2ZSBzZWxlY3Rpb25cbiAgICAgIHRoaXMuX2xhc3RTZWxlY3RlZE9wdGlvbiA9IG9wdEVsZW1lbnRcblxuICAgIH0gZWxzZSB7IC8vIERlc2VsZWN0IGFuIG9wdGlvblxuICAgICAgLy8gS2VlcCB0cmFjayBvZiBmYWxsaW5nIGJhY2sgdG8gdGhlIHBsYWNlaG9sZGVyIChpZiBhbnkpXG4gICAgICBpZiAodGhpcy5fcGxhY2Vob2xkZXJPcHRpb24pIHtcbiAgICAgICAgdGhpcy5fbGFzdFNlbGVjdGVkT3B0aW9uID0gdGhpcy5fcGxhY2Vob2xkZXJPcHRpb25cbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgaGFzU2VsZWN0ZWRJdGVtcyA9IHRydWVcblxuICAgIGlmICh0aGlzLl9tdWx0aXNlbGVjdGlvbiA9PT0gZmFsc2UgJiYgaXNEZXNlbGVjdCkge1xuICAgICAgLy8gSGFuZGxlIG5vIHNlbGVjdGlvbiBmb3Igbm9uLW11bHRpc2VsZWN0IHN0YXRlc1xuICAgICAgdGhpcy5fcGxhY2Vob2xkZXJPcHRpb24hLnNlbGVjdGVkID0gdHJ1ZVxuICAgICAgaGFzU2VsZWN0ZWRJdGVtcyA9IGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX211bHRpc2VsZWN0aW9uID09PSB0cnVlICYmIHRoaXMuX2dldFNlbGVjdGVkT3B0aW9ucygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaGFzU2VsZWN0ZWRJdGVtcyA9IGZhbHNlXG4gICAgfVxuXG4gICAgLy8gUmVzZXQgdGhlIGZpbHRlciBpZiBmaWx0ZXJhYmxlXG4gICAgaWYgKHRoaXMuX2FjdGl2ZUZpbHRlcikge1xuICAgICAgdGhpcy5fY2xlYXJGaWx0ZXIoKVxuICAgIH1cblxuICAgIHRoaXMuX3VwZGF0ZVBsYWNlaG9sZGVyKGhhc1NlbGVjdGVkSXRlbXMpXG5cbiAgICAvLyBEaXNwYXRjaCB0aGUgY2hhbmdlZCBldmVudFxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChcImNoYW5nZVwiKVxuXG4gICAgaWYgKGF1dG9DbG9zZSAmJiAhbXVsdGlzZWxlY3QpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmNsb3NlKClcbiAgICAgIH0sIFRJTUVPVVRfQ0xPU0UpXG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF91cGRhdGVQbGFjZWhvbGRlcihoYXNTZWxlY3RlZEl0ZW1zOiBib29sZWFuKSB7XG4gICAgbGV0IHRleHQgPSB0aGlzLl9wbGFjZWhvbGRlck9wdGlvbiA/IERvbS50ZXh0KHRoaXMuX3BsYWNlaG9sZGVyT3B0aW9uKSA6IFwiIFwiXG5cbiAgICBpZiAoaGFzU2VsZWN0ZWRJdGVtcyA9PT0gdHJ1ZSkge1xuICAgICAgbGV0IHNlbGVjdGVkSXRlbXMgPSB0aGlzLl9nZXRTZWxlY3RlZE9wdGlvbnMoKVxuXG4gICAgICBpZiAoc2VsZWN0ZWRJdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRleHQgPSBcIlwiXG4gICAgICAgIGZvciAobGV0IGl0ZW0gb2Ygc2VsZWN0ZWRJdGVtcykge1xuICAgICAgICAgIHRleHQgKz0gYCR7RG9tLnRleHQoaXRlbSl9LCBgXG4gICAgICAgIH1cbiAgICAgICAgdGV4dCA9IHRleHQuc3Vic3RyaW5nKDAsIHRleHQubGVuZ3RoIC0gMilcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9zZXRQbGFjZWhvbGRlcih0ZXh0KVxuICB9XG5cbiAgcHJvdGVjdGVkIF9nZXRTZWxlY3RlZE9wdGlvbnMoKSB7XG4gICAgbGV0IHNlbGVjdGVkT3B0aW9uczogSFRNTE9wdGlvbkVsZW1lbnRbXSA9IFtdXG4gICAgaWYgKHRoaXMuZWxlbWVudC5vcHRpb25zKSB7XG4gICAgICBbXS5mb3JFYWNoLmNhbGwodGhpcy5lbGVtZW50Lm9wdGlvbnMsICgob3B0aW9uOiBIVE1MT3B0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAob3B0aW9uLnNlbGVjdGVkICYmICFvcHRpb24uZGlzYWJsZWQpIHtcbiAgICAgICAgICBzZWxlY3RlZE9wdGlvbnMucHVzaChvcHRpb24pXG4gICAgICAgIH1cbiAgICAgIH0pKVxuICAgIH1cbiAgICByZXR1cm4gc2VsZWN0ZWRPcHRpb25zXG4gIH1cblxuICAvKipcbiAgICogQ2xvbmUgYWxsIG9mIHRoZSBpbml0aWFsbHkgc2V0IG9wdGlvbnMgKGFuZCBvcHRncm91cHMpIGFuZCByZXR1cm5zIHRoZW0gaW4gYSBuZXcgYXJyYXkuXG4gICAqIFRoaXMgc2VydmVzIGFzIHRoZSBiYXNpcyBmb3IgZmlsdGVyaW5nLiBJZiBhIGZpbHRlciBpcyBwcmVzZW50LCBpdCB3aWxsIGJlIHJlc3BlY3RlZC5cbiAgICovXG4gIHByaXZhdGUgZ2V0SW5pdGlhbE9wdGlvbnMoKTogRWxlbWVudFtdIHtcbiAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLl9hY3RpdmVGaWx0ZXIgfHwgXCJcIlxuICAgIGNvbnN0IGZpbHRlcmVkOiBFbGVtZW50W10gPSBbXVxuICAgIGNvbnN0IGluaXRpYWxPcHRpb25zID0gdGhpcy5faW5pdGlhbE9wdGlvbnNcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5pdGlhbE9wdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNoaWxkOiBFbGVtZW50ID0gaW5pdGlhbE9wdGlvbnNbaV0gYXMgRWxlbWVudFxuXG4gICAgICBpZiAodGhpcy5faXNPcHRHcm91cChjaGlsZCkpIHsgLy8gaGFuZGxlIDxvcHRncm91cD5cbiAgICAgICAgY29uc3Qgb3B0R3JvdXBDbG9uZTogRWxlbWVudCA9IGNoaWxkLmNsb25lTm9kZShmYWxzZSkgYXMgRWxlbWVudFxuICAgICAgICBsZXQgZm91bmQgPSBmYWxzZVxuXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY2hpbGQuY2hpbGRyZW4ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICBjb25zdCBvcHRpb25DbG9uZTogRWxlbWVudCA9IGNoaWxkLmNoaWxkcmVuW2pdLmNsb25lTm9kZSh0cnVlKSBhcyBFbGVtZW50XG5cbiAgICAgICAgICAvLyBBcHBlbmQgb24gbWF0Y2hcbiAgICAgICAgICBpZiAodGhpcy5fY29udGFpbnNXb3JkKG9wdGlvbkNsb25lLmlubmVySFRNTCwgZmlsdGVyKSkge1xuICAgICAgICAgICAgb3B0R3JvdXBDbG9uZS5hcHBlbmRDaGlsZChvcHRpb25DbG9uZSlcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFB1c2ggaWYgYW55IG1hdGNoZXMgZm91bmRcbiAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgZmlsdGVyZWQucHVzaChvcHRHcm91cENsb25lKVxuICAgICAgICB9XG5cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5faXNPcHRpb24oY2hpbGQpKSB7IC8vIGhhbmRsZSA8b3B0aW9uPlxuICAgICAgICBjb25zdCBvcHRpb25DbG9uZTogRWxlbWVudCA9IGNoaWxkLmNsb25lTm9kZSh0cnVlKSBhcyBFbGVtZW50XG5cbiAgICAgICAgLy8gUHVzaCBvbiBtYXRjaFxuICAgICAgICBpZiAodGhpcy5fY29udGFpbnNXb3JkKG9wdGlvbkNsb25lLmlubmVySFRNTCwgZmlsdGVyKSkge1xuICAgICAgICAgIGZpbHRlcmVkLnB1c2gob3B0aW9uQ2xvbmUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgYSB0ZXh0IGNvbnRhaW5zIGEgZ2l2ZW4ga2V5d29yZCwgZS5nLiBpbiBcImNhXCIgaW4gXCJDYXJcIlxuICAgKi9cbiAgcHJpdmF0ZSBfY29udGFpbnNXb3JkKHRleHQ6IHN0cmluZywga2V5d29yZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRleHQudG9Mb3dlckNhc2UoKS5pbmRleE9mKGtleXdvcmQudG9Mb3dlckNhc2UoKSkgPiAtMVxuICB9XG5cbiAgcHJvdGVjdGVkIF9oYW5kbGVGb2N1cygpIHtcbiAgICB0aGlzLm9wZW4oKVxuICAgIHRoaXMuX29wZW5CeUZvY3VzID0gdHJ1ZVxuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLl9vcGVuQnlGb2N1cyA9IGZhbHNlXG4gICAgfSwgVElNRU9VVF9CTFVSKVxuICB9XG5cbiAgcHJvdGVjdGVkIF9oYW5kbGVCbHVyKCkge1xuICAgIHRoaXMuY2xvc2UoKVxuICB9XG5cbiAgcHJvdGVjdGVkIF9oYW5kbGVDbGljayhldmVudDogTW91c2VFdmVudCkge1xuICAgIGxldCBoYW5kbGVkID0gZmFsc2VcblxuICAgIGlmICh0aGlzLl9sYXN0SGFuZGxlZEV2ZW50ID09PSBldmVudCkge1xuICAgICAgdGhpcy5fbGFzdEhhbmRsZWRFdmVudCA9IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2lzQnV0dG9uVGFyZ2V0KGV2ZW50LnRhcmdldCEpICYmIHRoaXMuX29wZW5CeUZvY3VzID09PSBmYWxzZSkge1xuICAgICAgLy8gaGFuZGxlIGhlYWRlciBpdGVtIGNsaWNrcyBhbmQgdG9nZ2xlIGRyb3Bkb3duXG4gICAgICB0aGlzLnRvZ2dsZSgpXG4gICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIGxldCBuZXdJdGVtID0gZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnRcblxuICAgIGlmICghaGFuZGxlZCAmJiBEb20uaGFzQ2xhc3MobmV3SXRlbSwgQ0xBU1NfSVRFTSkpIHtcbiAgICAgIC8vIGhhbmRsZSBjbGlja3Mgb24gZHJvcGRvd24gaXRlbXNcbiAgICAgIHRoaXMuX3NlbGVjdGVkSXRlbUNoYW5nZWQobmV3SXRlbSwgdHJ1ZSwgdGhpcy5fbXVsdGlzZWxlY3Rpb24pXG4gICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIGlmIChoYW5kbGVkKSB7XG4gICAgICB0aGlzLl9sYXN0SGFuZGxlZEV2ZW50ID0gZXZlbnRcbiAgICAgIHByZXZlbnREZWZhdWx0KGV2ZW50KVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfaGFuZGxlV2luZG93Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAodGhpcy5faXNEcm9wZG93blRhcmdldChldmVudC50YXJnZXQhKSB8fCB0aGlzLl9pc0J1dHRvblRhcmdldChldmVudC50YXJnZXQhKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSgpXG4gIH1cblxuICBwcm90ZWN0ZWQgX2ZvY3VzT3B0aW9uU3RhcnRpbmdXaXRoKGtleWNvZGU6IG51bWJlciwgc3RhcnRJbmRleDogbnVtYmVyLCBvcHRpb25zOiBOb2RlTGlzdE9mPEhUTUxFbGVtZW50Pikge1xuICAgIGZvciAobGV0IGluZGV4ID0gc3RhcnRJbmRleDsgaW5kZXggPCBvcHRpb25zLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgbGV0IGl0ZW0gPSBuZXcgRG9tRWxlbWVudChvcHRpb25zW2luZGV4XSlcbiAgICAgIGxldCB2YWx1ZSA9IGl0ZW0uaW5uZXJUZXh0LnRvTG93ZXJDYXNlKClcblxuICAgICAgaWYgKGluZGV4ID4gb3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSAwXG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZS5zdGFydHNXaXRoKElucHV0cy5nZXRLZXlWYWx1ZShrZXljb2RlKSkpIHtcbiAgICAgICAgbGV0IG5ld09wdGlvbiA9IG5ldyBEb21FbGVtZW50KG9wdGlvbnNbaW5kZXhdKVxuXG4gICAgICAgIGlmICghbmV3T3B0aW9uLmhhc0NsYXNzKENMQVNTX0lURU1fRElTQUJMRUQpKSB7XG4gICAgICAgICAgc2Nyb2xsSW50b1ZpZXcob3B0aW9uc1tpbmRleF0pXG4gICAgICAgICAgbmV3T3B0aW9uLmFkZENsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcbiAgICAgICAgICByZXR1cm4gbmV3T3B0aW9uXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgcHJvdGVjdGVkIF9oYW5kbGVLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgbGV0IGV2dCA9IGV2ZW50IHx8IHdpbmRvdy5ldmVudFxuICAgIGxldCBrZXljb2RlID0gZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZVxuXG4gICAgaWYgKGtleWNvZGUgPT09IElucHV0cy5LRVlfRVNDQVBFKSB7XG4gICAgICAvLyBoYW5kbGUgRXNjYXBlIGtleSAoRVNDKVxuICAgICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgICAgdGhpcy5jbG9zZSgpXG4gICAgICB9XG4gICAgICBldnQucHJldmVudERlZmF1bHQoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGtleWNvZGUgPT09IElucHV0cy5LRVlfQVJST1dfVVAgfHwga2V5Y29kZSA9PT0gSW5wdXRzLktFWV9BUlJPV19ET1dOKSB7XG4gICAgICAvLyBVcCBhbmQgZG93biBhcnJvd3NcblxuICAgICAgbGV0IG9wdGlvbnMgPSB0aGlzLl93cmFwcGVyRWxlbWVudC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0lURU19YCkgYXMgTm9kZUxpc3RPZjxIVE1MRWxlbWVudD5cbiAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcblxuICAgICAgICBsZXQgbmV3SW5kZXggPSAwXG4gICAgICAgIGxldCBvbGRPcHRpb25cblxuICAgICAgICBsZXQgZm9jdXNlZEVsZW1lbnQgPSB0aGlzLl93cmFwcGVyRWxlbWVudC5maW5kKGAuJHtDTEFTU19JVEVNX0ZPQ1VTRUR9YClcbiAgICAgICAgbGV0IHNlYXJjaEZvciA9IGZvY3VzZWRFbGVtZW50ID8gQ0xBU1NfSVRFTV9GT0NVU0VEIDogQ0xBU1NfSVRFTV9TRUxFQ1RFRFxuXG4gICAgICAgIGxldCBuZXdFbGVtZW50XG5cbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG9wdGlvbnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgbGV0IGRpcmVjdGlvbiA9IGtleWNvZGUgPT09IElucHV0cy5LRVlfQVJST1dfRE9XTiA/IDEgOiAtMVxuXG4gICAgICAgICAgbGV0IGl0ZW0gPSBuZXcgRG9tRWxlbWVudChvcHRpb25zW2luZGV4XSlcblxuICAgICAgICAgIC8vIHNlYXJjaCBmb3Igc2VsZWN0ZWQgb3IgZm9jdXNlZEVsZW1lbnQgZWxlbWVudHNcbiAgICAgICAgICBpZiAoaXRlbS5oYXNDbGFzcyhzZWFyY2hGb3IpKSB7XG4gICAgICAgICAgICBvbGRPcHRpb24gPSBpdGVtXG4gICAgICAgICAgICBuZXdJbmRleCA9IGluZGV4XG5cbiAgICAgICAgICAgIC8vIGdldCB0aGUgbmV4dCBub3QgZGlzYWJsZWQgZWxlbWVudCBpbiB0aGUgYXBwcm9wcmlhdGUgZGlyZWN0aW9uXG4gICAgICAgICAgICBmb3IgKGxldCBjb3VudCA9IDA7IGNvdW50IDwgb3B0aW9ucy5sZW5ndGg7IGNvdW50KyspIHtcbiAgICAgICAgICAgICAgbmV3SW5kZXggKz0gZGlyZWN0aW9uXG4gICAgICAgICAgICAgIG5ld0luZGV4ICU9IG9wdGlvbnMubGVuZ3RoXG5cbiAgICAgICAgICAgICAgaWYgKG5ld0luZGV4IDwgMCkge1xuICAgICAgICAgICAgICAgIG5ld0luZGV4ID0gb3B0aW9ucy5sZW5ndGggLSAxXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBuZXdFbGVtZW50ID0gbmV3IERvbUVsZW1lbnQob3B0aW9uc1tuZXdJbmRleF0pXG4gICAgICAgICAgICAgIGlmICghbmV3RWxlbWVudC5oYXNDbGFzcyhDTEFTU19JVEVNX0RJU0FCTEVEKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgdGhlIG5ldyBlbGVtZW50IGZvY3VzZWRcbiAgICAgICAgc2Nyb2xsSW50b1ZpZXcob3B0aW9uc1tuZXdJbmRleF0pXG4gICAgICAgIGxldCBuZXdPcHRpb24gPSBuZXcgRG9tRWxlbWVudChvcHRpb25zW25ld0luZGV4XSlcbiAgICAgICAgbmV3T3B0aW9uLmFkZENsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcblxuICAgICAgICBpZiAob2xkT3B0aW9uKSB7XG4gICAgICAgICAgb2xkT3B0aW9uLnJlbW92ZUNsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBldnQucHJldmVudERlZmF1bHQoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKElucHV0cy5nZXRLZXlWYWx1ZShrZXljb2RlKSAmJiAhdGhpcy5faXNGaWx0ZXJhYmxlKCkpIHtcbiAgICAgIC8vIEtleWJvYXJkIGtleXNcblxuICAgICAgbGV0IG9wdGlvbnMgPSB0aGlzLl93cmFwcGVyRWxlbWVudC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0lURU19YCkgYXMgTm9kZUxpc3RPZjxIVE1MRWxlbWVudD5cbiAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcblxuICAgICAgICBsZXQgb2xkRm9jdXNJbmRleCA9IDBcbiAgICAgICAgbGV0IGhhc0ZvY3VzZWRPcHRpb24gPSBmYWxzZVxuXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBvcHRpb25zLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgIGxldCBpdGVtID0gbmV3IERvbUVsZW1lbnQob3B0aW9uc1tpbmRleF0pXG5cbiAgICAgICAgICBpZiAoaXRlbS5oYXNDbGFzcyhDTEFTU19JVEVNX0ZPQ1VTRUQpKSB7XG4gICAgICAgICAgICBpdGVtLnJlbW92ZUNsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcblxuICAgICAgICAgICAgbGV0IHZhbHVlID0gaXRlbS5pbm5lclRleHQudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoSW5wdXRzLmdldEtleVZhbHVlKGtleWNvZGUpKSkge1xuICAgICAgICAgICAgICBoYXNGb2N1c2VkT3B0aW9uID0gdHJ1ZVxuICAgICAgICAgICAgICBvbGRGb2N1c0luZGV4ID0gaW5kZXhcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbmV3T3B0aW9uID0gdGhpcy5fZm9jdXNPcHRpb25TdGFydGluZ1dpdGgoa2V5Y29kZSwgaGFzRm9jdXNlZE9wdGlvbiA/IG9sZEZvY3VzSW5kZXggKyAxIDogMCwgb3B0aW9ucylcbiAgICAgICAgaWYgKG5ld09wdGlvbiA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgICB0aGlzLl9mb2N1c09wdGlvblN0YXJ0aW5nV2l0aChrZXljb2RlLCAwLCBvcHRpb25zKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoa2V5Y29kZSA9PT0gSW5wdXRzLktFWV9FTlRFUiB8fCBrZXljb2RlID09PSBJbnB1dHMuS0VZX1RBQikge1xuICAgICAgLy8gSGFuZGxlIGVudGVyIGFuZCB0YWIga2V5IGJ5IHNlbGVjdGluZyB0aGUgY3VycmVudGx5IGZvY3VzZWQgZWxlbWVudFxuICAgICAgbGV0IG5ld0l0ZW0gPSB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5xdWVyeVNlbGVjdG9yKGAuJHtDTEFTU19JVEVNX0ZPQ1VTRUR9YCkhXG4gICAgICB0aGlzLl9zZWxlY3RlZEl0ZW1DaGFuZ2VkKG5ld0l0ZW0sIHRydWUsIHRoaXMuX211bHRpc2VsZWN0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIHRoZSB1c2VyIHByZXNzZXMgYSBrZXkgaW4gdGhlIGZpbHRlciBmaWVsZFxuICAgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlRmlsdGVyS2V5ZG93bihlOiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qga2V5Y29kZSA9IGUud2hpY2ggfHwgZS5rZXlDb2RlXG5cbiAgICAvLyBJZiB0aGUgdXNlciBoaXRzIHRoZSBlbnRlciBrZXkgd2hpbGUgZmlsdGVyaW5nIGFuZCB0aGVyZSdzIGEgc2luZ2xlIG1hdGNoLCBzZWxlY3QgaXRcbiAgICBpZiAoa2V5Y29kZSA9PT0gSW5wdXRzLktFWV9FTlRFUikge1xuICAgICAgY29uc3QgZHJvcGRvd25FbGVtZW50cyA9IHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0lURU19YClcblxuICAgICAgaWYgKGRyb3Bkb3duRWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHRoaXMuX3NlbGVjdGVkSXRlbUNoYW5nZWQoZHJvcGRvd25FbGVtZW50c1swXSwgdHJ1ZSwgdGhpcy5fbXVsdGlzZWxlY3Rpb24pXG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmlyZWQgd2hlbiB0aGUgdXNlciByZWxlYXNlcyBhIGtleSBpbiB0aGUgZmlsdGVyIGZpZWxkXG4gICAqL1xuICBwcml2YXRlIF9oYW5kbGVGaWx0ZXJLZXl1cChlOiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudFxuXG4gICAgLy8gRmlsdGVyIGhhcyBjaGFuZ2VkXG4gICAgaWYgKHRhcmdldC52YWx1ZSAhPT0gdGhpcy5fYWN0aXZlRmlsdGVyICYmIHRhcmdldC52YWx1ZSAhPT0gdGhpcy5fcGxhY2Vob2xkZXJUZXh0ICYmIHRhcmdldC52YWx1ZSAhPT0gdGhpcy5fbGFzdFNlbGVjdGVkT3B0aW9uIS5pbm5lckhUTUwpIHtcbiAgICAgIHRoaXMuX3NldEZpbHRlcih0YXJnZXQudmFsdWUpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpcmVkIHdoZW4gdGhlIHVzZXIgZm9jdXNzZXMgdGhlIGZpbHRlciBpbnB1dCBmaWVsZFxuICAgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlRmlsdGVyRm9jdXMoZTogRm9jdXNFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnRcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGFyZ2V0LnNlbGVjdCgpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIHRoZSBTZWxlY3QgYnkgYSBnaXZlbiBmaWx0ZXIga2V5d29yZFxuICAgKiBAcGFyYW0gZmlsdGVyIEtleXdvcmQgdG8gZmlsdGVyIGJ5XG4gICAqL1xuICBwcml2YXRlIF9zZXRGaWx0ZXIoZmlsdGVyOiBzdHJpbmcgPSBcIlwiKTogdm9pZCB7XG4gICAgdGhpcy5fYWN0aXZlRmlsdGVyID0gKGZpbHRlci5sZW5ndGggPj0gdGhpcy5fbWluRmlsdGVyTGVuZ3RoKSA/IGZpbHRlciA6IFwiXCJcbiAgICB0aGlzLnNldE9wdGlvbnModGhpcy5nZXRJbml0aWFsT3B0aW9ucygpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB0aGUgZmlsdGVyXG4gICAqL1xuICBwcml2YXRlIF9jbGVhckZpbHRlcigpOiB2b2lkIHtcbiAgICBkZWxldGUgdGhpcy5fYWN0aXZlRmlsdGVyXG4gICAgdGhpcy5zZXRPcHRpb25zKHRoaXMuZ2V0SW5pdGlhbE9wdGlvbnMoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgbmV3IGNvbnRlbnQgYW5kIHJlbG9hZCB0aGUgU2VsZWN0XG4gICAqIEBwYXJhbSBlbGVtZW50cyBBcnJheSBvZiBuZXcgb3B0aW9uIChvciBvcHRncm91cCkgZWxlbWVudHMgdG8gZGlzcGxheVxuICAgKi9cbiAgcHJpdmF0ZSBzZXRPcHRpb25zKG9wdGlvbnM6IEVsZW1lbnRbXSk6IHZvaWQge1xuICAgIHRoaXMuX2VtcHR5Tm9kZSh0aGlzLmVsZW1lbnQpXG5cbiAgICBvcHRpb25zLmZvckVhY2goKG9wdGlvbikgPT4ge1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKG9wdGlvbilcbiAgICB9KVxuXG4gICAgLy8gUHJlc2VydmUgc2VsZWN0ZWQgdmFsdWUgaWYgdGhlIHNlbGVjdGVkXG4gICAgdGhpcy5lbGVtZW50LnZhbHVlID0gdGhpcy5fbGFzdFNlbGVjdGVkT3B0aW9uIS52YWx1ZVxuXG4gICAgdGhpcy5yZWxvYWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBjaGlsZHJlbiBvZiBhIGdpdmVuIG5vZGVcbiAgICogQHBhcmFtIG5vZGUgTm9kZVxuICAgKi9cbiAgcHJpdmF0ZSBfZW1wdHlOb2RlKG5vZGU6IE5vZGUpOiB2b2lkIHtcbiAgICB3aGlsZSAobm9kZS5maXJzdENoaWxkKSB7XG4gICAgICBub2RlLnJlbW92ZUNoaWxkKG5vZGUuZmlyc3RDaGlsZClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIGFuIG9wdGlvbiBpcyBhIHBsYWNlaG9sZGVyIG9wdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBfaXNQbGFjZWhvbGRlcihvcHRpb246IEhUTUxPcHRpb25FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIG9wdGlvbi5oYXNBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSAmJiBvcHRpb24uaGFzQXR0cmlidXRlKFwic2VsZWN0ZWRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgcGxhY2Vob2xkZXIgdmFsdWVcbiAgICogQHBhcmFtIHRleHQgQ29udGVudCBvZiB0aGUgcGxhY2Vob2xkZXJcbiAgICovXG4gIHByb3RlY3RlZCBfc2V0UGxhY2Vob2xkZXIodGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudCAmJiB0ZXh0KSB7XG4gICAgICBpZiAodGhpcy5faXNGaWx0ZXJhYmxlKCkpIHtcbiAgICAgICAgKHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudCBhcyBEb21FbGVtZW50PEhUTUxJbnB1dEVsZW1lbnQ+KS5lbGVtZW50LnZhbHVlID0gdGV4dFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50LnNldEh0bWwodGV4dClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBvcHRpb24uXG4gICAqIElmIG11bHRpcGxlIHNlbGVjdGlvbiBpcyBlbmFibGVkIHRoaXMgcHJvcGVydHkgcmV0dXJucyBhbiBhcnJheSBvZiB2YWx1ZXMuXG4gICAqL1xuICBnZXQgdmFsdWUoKSB7XG4gICAgaWYgKHRoaXMuX211bHRpc2VsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRPcHRpb25zKCkubWFwKCh4KSA9PiB4LnZhbHVlKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmVsZW1lbnQudmFsdWUgPT09IFwiXCIpIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudC52YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgdGhlIHNlbGVjdCBjb21wb25lbnQgZGVwZW5kaW5nIG9uIHRoZVxuICAgKiAndmFsdWUnIHBhcmFtZXRlci5cbiAgICogQHBhcmFtIHt2YWx1ZX0gSWYgdHJ1ZSBkaXNhYmxlcyB0aGUgY29udHJvbDsgZmFsc2UgZW5hYmxlcyBpdC5cbiAgICovXG4gIHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5kaXNhYmxlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbmFibGUoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxvYWRzIHRoZSBkcm9wZG93bidzIG9wdGlvbiBkYXRhIGRlZmluaXRpb25zIGZyb20gdGhlIERPTSBhbmQgdXBkYXRlc1xuICAgKiB0aGUgZ2VuZXJhdGVkIGRyb3Bkb3duIGRpc3BsYXkgaXRlbXMuXG4gICAqL1xuICByZWxvYWQoKSB7XG4gICAgLy8gUmVtb3ZlIGFsbCBleGlzdGluZyBjaGlsZCBlbGVtZW50c1xuICAgIHRoaXMuX2VtcHR5Tm9kZSh0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudClcblxuICAgIGlmICh0aGlzLl9hY3RpdmVGaWx0ZXIgPT09IHVuZGVmaW5lZCkgeyAvLyBJZiB0aGUgdXNlciBpcyBmaWx0ZXJpbmcsIGxldCB0aGUgcGxhY2Vob2xkZXIgXCJpbnB1dFwiIGFsaXZlXG4gICAgICB0aGlzLl9zZXR1cFBsYWNlaG9sZGVyKClcbiAgICB9XG5cbiAgICB0aGlzLl9jcmVhdGVPcHRpb25zKHRoaXMuZWxlbWVudClcblxuICAgIHRoaXMuX3VwZGF0ZVNpemUoKVxuICAgIHRoaXMuX3VwZGF0ZU1lc3NhZ2UoKVxuXG4gICAgaWYgKCF0aGlzLl9pc0ZpbHRlcmFibGUoKSkge1xuICAgICAgdGhpcy5fdXBkYXRlUGxhY2Vob2xkZXIoISF0aGlzLnZhbHVlKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBzZWxlY3QgY29udHJvbCB0byB0aGUgZW5hYmxlZCBzdGF0ZS5cbiAgICovXG4gIGVuYWJsZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKFwiZGlzYWJsZWRcIilcbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5yZW1vdmVDbGFzcyhDTEFTU19ESVNBQkxFRClcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fd2luZG93Q2xpY2tIYW5kbGVyKVxuXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fY2xpY2tIYW5kbGVyKVxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgdGhpcy5fa2V5ZG93bkhhbmRsZXIpXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgdGhpcy5fZm9jdXNIYW5kbGVyKVxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fYmx1ckhhbmRsZXIpXG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgc2VsZWN0IGNvbnRyb2wgdG8gdGhlIGRpc2FibGVkIHN0YXRlLlxuICAgKi9cbiAgZGlzYWJsZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIiwgXCJcIilcbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5hZGRDbGFzcyhDTEFTU19ESVNBQkxFRClcblxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fd2luZG93Q2xpY2tIYW5kbGVyKVxuXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fY2xpY2tIYW5kbGVyKVxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgdGhpcy5fa2V5ZG93bkhhbmRsZXIpXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgdGhpcy5fZm9jdXNIYW5kbGVyKVxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fYmx1ckhhbmRsZXIpXG5cbiAgICB0aGlzLmNsb3NlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGVzIHRoZSBvcGVuL2Nsb3NlZCBzdGF0ZSBvZiB0aGUgc2VsZWN0IGRyb3Bkb3duLlxuICAgKi9cbiAgdG9nZ2xlKCkge1xuICAgIGlmICh0aGlzLmlzT3BlbigpKSB7XG4gICAgICB0aGlzLmNsb3NlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcGVuKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBpZiB0aGUgc2VsZWN0IGRyb3Bkb3duIGlzIG9wZW4gb3IgY2xvc2VkLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG9wZW47IG90aGVyd2lzZSBmYWxzZS5cbiAgICovXG4gIGlzT3BlbigpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JhcHBlckVsZW1lbnQuaGFzQ2xhc3MoQ0xBU1NfT1BFTilcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVucyB0aGUgc2VsZWN0IGRyb3Bkb3duLlxuICAgKi9cbiAgb3BlbigpIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuX29wZW5CeUZvY3VzID0gZmFsc2VcblxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQucmVtb3ZlQ2xhc3MoQ0xBU1NfQ0xPU0VEKVxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYWRkQ2xhc3MoQ0xBU1NfT1BFTilcblxuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG4gICAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidGFwXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgc2VsZWN0IGRyb3Bkb3duLlxuICAgKi9cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuX29wZW5CeUZvY3VzID0gZmFsc2VcblxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQucmVtb3ZlQ2xhc3MoQ0xBU1NfT1BFTilcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmFkZENsYXNzKENMQVNTX0NMT1NFRClcblxuICAgICAgLy8gSWYgdGhlIFNlbGVjdCBpcyBmaWx0ZXJhYmxlIGFuZCB0aGVyZWZvcmUgaGFzIGFuIGlucHV0IGZpZWxkLFxuICAgICAgLy8gcmVzZXQgdGhlIHZhbHVlIG9mIGl0IHRvIHRoZSBjaG9zZW4gb3B0aW9uXG4gICAgICBpZiAodGhpcy5faXNGaWx0ZXJhYmxlKCkpIHtcbiAgICAgICAgLy8gVW5mb2N1cyBpbnB1dCBmaWVsZFxuICAgICAgICAodGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50LmVsZW1lbnQgYXMgSFRNTElucHV0RWxlbWVudCkuYmx1cigpXG5cbiAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmVGaWx0ZXIgfHwgdGhpcy5fYWN0aXZlRmlsdGVyID09PSB0aGlzLl9sYXN0U2VsZWN0ZWRPcHRpb24hLmlubmVySFRNTCkge1xuICAgICAgICAgIHRoaXMuX3NldFBsYWNlaG9sZGVyKHRoaXMuX2xhc3RTZWxlY3RlZE9wdGlvbiEuaW5uZXJIVE1MKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLl9oYW5kbGVEcm9wZG93bkNsaWNrKVxuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRhcFwiLCB0aGlzLl9oYW5kbGVEcm9wZG93bkNsaWNrKVxuXG4gICAgICBsZXQgZm9jdXNlZEl0ZW0gPSB0aGlzLl93cmFwcGVyRWxlbWVudC5maW5kKGAuJHtDTEFTU19JVEVNX0ZPQ1VTRUR9YClcblxuICAgICAgaWYgKGZvY3VzZWRJdGVtKSB7XG4gICAgICAgIGZvY3VzZWRJdGVtLnJlbW92ZUNsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIHdoZW4gdGhlIGVsZW1lbnQgaGFzIHRoZSBmaWx0ZXIgbW9kaWZpZXIgY2xhc3NcbiAgICovXG4gIHByaXZhdGUgX2lzRmlsdGVyYWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fd3JhcHBlckVsZW1lbnQuaGFzQ2xhc3MoQ0xBU1NfRklMVEVSQUJMRSlcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95cyB0aGUgY29tcG9uZW50IGFuZCBjbGVhcnMgYWxsIHJlZmVyZW5jZXMuXG4gICAqL1xuICBkZXN0cm95KCkge1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fd2luZG93Q2xpY2tIYW5kbGVyKVxuXG4gICAgaWYgKHRoaXMuX2Ryb3Bkb3duRWxlbWVudCkge1xuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG4gICAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidGFwXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG5cbiAgICAgIHJlbW92ZSh0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudCk7XG4gICAgICAodGhpcyBhcyBhbnkpLl9kcm9wZG93bkVsZW1lbnQgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50KSB7XG4gICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgdGhpcy5fZmlsdGVyS2V5ZG93bkhhbmRsZXIpXG4gICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImtleXVwXCIsIHRoaXMuX2ZpbHRlcktleXVwSGFuZGxlcilcbiAgICAgIHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgdGhpcy5fZmlsdGVyRm9jdXNIYW5kbGVyKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl93cmFwcGVyRWxlbWVudCkge1xuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fY2xpY2tIYW5kbGVyKVxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCB0aGlzLl9rZXlkb3duSGFuZGxlcilcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIHRoaXMuX2ZvY3VzSGFuZGxlcilcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fYmx1ckhhbmRsZXIpO1xuXG4gICAgICAodGhpcyBhcyBhbnkpLl93cmFwcGVyRWxlbWVudCA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmICh0aGlzLl9zZWxlY3RCdXR0b25FbGVtZW50KSB7XG4gICAgICByZW1vdmUodGhpcy5fc2VsZWN0QnV0dG9uRWxlbWVudC5lbGVtZW50KTtcbiAgICAgICh0aGlzIGFzIGFueSkuX3NlbGVjdEJ1dHRvbkVsZW1lbnQgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICB0aGlzLnJlbW92ZUNsYXNzKENMQVNTX0NMT1NFRClcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5pdCgpIHtcbiAgc2VhcmNoQW5kSW5pdGlhbGl6ZTxIVE1MU2VsZWN0RWxlbWVudD4oXCJzZWxlY3RcIiwgKGUpID0+IHtcbiAgICBuZXcgU2VsZWN0KGUpXG4gIH0pXG59XG5cbmV4cG9ydCBkZWZhdWx0IFNlbGVjdFxuIl0sInNvdXJjZVJvb3QiOiIuLi8uLi8uLi8uLi8uLiJ9