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 keyboardEvent = event;
var evt = keyboardEvent || window.event;
var keycode = keyboardEvent.which || keyboardEvent.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 keyboardEvent = e;
var keycode = keyboardEvent.which || keyboardEvent.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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QUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtTQUNoRjtRQUVELElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBQzdFLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUE7WUFDakYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtZQUM3RSxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTNFLElBQVksQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFBO1NBQzFDO1FBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7WUFDN0IsTUFBTSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QyxJQUFZLENBQUMsb0JBQW9CLEdBQUcsU0FBUyxDQUFBO1NBQy9DO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUNoQyxDQUFDO0lBQ0gsYUFBQztBQUFELENBdjlCQSxBQXU5QkMsQ0F2OUJvQixVQUFVLEdBdTlCOUI7QUFFRCxNQUFNLFVBQVUsSUFBSTtJQUNsQixtQkFBbUIsQ0FBb0IsUUFBUSxFQUFFLFVBQUMsQ0FBQztRQUNqRCxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNmLENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVELGVBQWUsTUFBTSxDQUFBIiwiZmlsZSI6Im1haW4vc3JjL2Zvcm0vU2VsZWN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc2VhcmNoQW5kSW5pdGlhbGl6ZSwgcHJldmVudERlZmF1bHQsIGZpbmQsIHJlbW92ZSwgaW50ZXJuZXRFeHBsb3Jlck9yRWRnZVZlcnNpb24sIHNjcm9sbEludG9WaWV3IH0gZnJvbSBcIi4uL1V0aWxzXCJcbmltcG9ydCBEb21FbGVtZW50IGZyb20gXCIuLi9Eb21FbGVtZW50XCJcbmltcG9ydCAqIGFzIElucHV0cyBmcm9tIFwiLi4vSW5wdXRzXCJcbmltcG9ydCAqIGFzIERvbSBmcm9tIFwiLi4vRG9tRnVuY3Rpb25zXCJcblxuY29uc3QgQ0xBU1NfUExBQ0VIT0xERVIgPSBcInNlbGVjdF9fcGxhY2Vob2xkZXJcIlxuY29uc3QgQ0xBU1NfVEhVTUIgPSBcInNlbGVjdF9fdGh1bWJcIlxuY29uc3QgQ0xBU1NfQlVUVE9OID0gXCJzZWxlY3RfX2J1dHRvblwiXG5jb25zdCBDTEFTU19EUk9QRE9XTiA9IFwic2VsZWN0X19kcm9wZG93blwiXG5cbmNvbnN0IENMQVNTX09QRU4gPSBcInNlbGVjdC0tb3BlblwiXG5jb25zdCBDTEFTU19DTE9TRUQgPSBcInNlbGVjdC0tY2xvc2VkXCJcbmNvbnN0IENMQVNTX0RJU0FCTEVEID0gXCJzZWxlY3QtLWRpc2FibGVkXCJcbmNvbnN0IENMQVNTX0ZJTFRFUkFCTEUgPSBcInNlbGVjdC0tZmlsdGVyYWJsZVwiXG5cbmNvbnN0IENMQVNTX0lURU0gPSBcImRyb3Bkb3duLWl0ZW1cIlxuY29uc3QgQ0xBU1NfSVRFTV9TRUxFQ1RFRCA9IFwiZHJvcGRvd24taXRlbS0tc2VsZWN0ZWRcIlxuY29uc3QgQ0xBU1NfSVRFTV9GT0NVU0VEID0gXCJkcm9wZG93bi1pdGVtLS1mb2N1c2VkXCJcbmNvbnN0IENMQVNTX0lURU1fRElTQUJMRUQgPSBcImRyb3Bkb3duLWl0ZW0tLWRpc2FibGVkXCJcblxuY29uc3QgQ0xBU1NfR1JPVVBfSVRFTSA9IFwiZHJvcGRvd24tZ3JvdXBcIlxuY29uc3QgQ0xBU1NfR1JPVVBfSEVBREVSID0gXCJkcm9wZG93bi1ncm91cF9faXRlbVwiXG5cbmNvbnN0IFFVRVJZX01FU1NBR0UgPSBcIi5tZXNzYWdlXCJcblxuY29uc3QgVElNRU9VVF9DTE9TRSA9IDE1MFxuY29uc3QgVElNRU9VVF9CTFVSID0gNDAwXG5cbi8qKlxuICogVGhlIHNlbGVjdCBjb21wb25lbnQgQVBJLlxuICovXG5jbGFzcyBTZWxlY3QgZXh0ZW5kcyBEb21FbGVtZW50PEhUTUxTZWxlY3RFbGVtZW50PiB7XG4gIHByaXZhdGUgX29wZW5CeUZvY3VzOiBib29sZWFuXG4gIHByaXZhdGUgX211bHRpc2VsZWN0aW9uOiBib29sZWFuXG4gIHByaXZhdGUgX2NsaWNrSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2hhbmRsZURyb3Bkb3duQ2xpY2s6IChlOiBFdmVudCkgPT4gdm9pZFxuICBwcml2YXRlIF9rZXlkb3duSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2ZvY3VzSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2JsdXJIYW5kbGVyOiAoZTogRXZlbnQpID0+IHZvaWRcbiAgcHJpdmF0ZSBfd2luZG93Q2xpY2tIYW5kbGVyOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZFxuICBwcml2YXRlIF9maWx0ZXJLZXlkb3duSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2ZpbHRlcktleXVwSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG4gIHByaXZhdGUgX2ZpbHRlckZvY3VzSGFuZGxlcjogKGU6IEV2ZW50KSA9PiB2b2lkXG5cbiAgcHJpdmF0ZSBfd3JhcHBlckVsZW1lbnQhOiBEb21FbGVtZW50XG4gIHByaXZhdGUgX2Ryb3Bkb3duRWxlbWVudCE6IERvbUVsZW1lbnQ8SFRNTEVsZW1lbnQ+XG5cbiAgcHJpdmF0ZSBfc2VsZWN0QnV0dG9uRWxlbWVudCE6IERvbUVsZW1lbnRcbiAgcHJpdmF0ZSBfdGh1bWJFbGVtZW50ITogRG9tRWxlbWVudFxuXG4gIHByaXZhdGUgX3BsYWNlaG9sZGVyT3B0aW9uPzogSFRNTE9wdGlvbkVsZW1lbnRcbiAgcHJpdmF0ZSBfcGxhY2Vob2xkZXJFbGVtZW50ITogRG9tRWxlbWVudFxuICBwcml2YXRlIF9wbGFjZWhvbGRlclRleHQhOiBzdHJpbmdcblxuICBwcml2YXRlIF9sYXN0SGFuZGxlZEV2ZW50PzogRXZlbnRcbiAgcHJpdmF0ZSBfbGFzdFNlbGVjdGVkT3B0aW9uPzogSFRNTE9wdGlvbkVsZW1lbnRcblxuICAvLyBNaW5pbXVtIGZpbHRlciBsZW5ndGhcbiAgcHJpdmF0ZSBfbWluRmlsdGVyTGVuZ3RoID0gMlxuXG4gIC8vIFRoZSBrZXl3b3JkIHRoZSBTZWxlY3QgaXMgY3VycmVudGx5IGZpbHRlcmVkIGJ5XG4gIHByaXZhdGUgX2FjdGl2ZUZpbHRlcj86IHN0cmluZ1xuXG4gIC8vIFRoZSBvcHRpb25zIHRoZSBTZWxlY3Qgd2FzIGluaXRpYWxseSBjcmVhdGVkIHVwb25cbiAgLy8gVGhlc2Ugd2lsbCBiZSB1c2VkIGFzIGEgYmFzaXMgZm9yIGZpbHRlcmluZ1xuICBwcml2YXRlIF9pbml0aWFsT3B0aW9ucyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuZWxlbWVudC5jaGlsZHJlbilcblxuICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MU2VsZWN0RWxlbWVudCkge1xuICAgIHN1cGVyKGVsZW1lbnQpXG5cbiAgICB0aGlzLl9vcGVuQnlGb2N1cyA9IGZhbHNlXG5cbiAgICAvLyBDaGVjayBmb3IgbXVsdGktc2VsZWN0aW9uXG4gICAgdGhpcy5fbXVsdGlzZWxlY3Rpb24gPSB0aGlzLmVsZW1lbnQuaGFzQXR0cmlidXRlKFwibXVsdGlwbGVcIikgPT09IHRydWVcblxuICAgIC8vIFNldHVwIGV2ZW50IGNvbnRleHRcbiAgICB0aGlzLl9jbGlja0hhbmRsZXIgPSB0aGlzLl9oYW5kbGVDbGljay5iaW5kKHRoaXMpXG4gICAgdGhpcy5faGFuZGxlRHJvcGRvd25DbGljayA9IHRoaXMuX2hhbmRsZUNsaWNrLmJpbmQodGhpcylcbiAgICB0aGlzLl9rZXlkb3duSGFuZGxlciA9IHRoaXMuX2hhbmRsZUtleWRvd24uYmluZCh0aGlzKVxuICAgIHRoaXMuX2ZvY3VzSGFuZGxlciA9IHRoaXMuX2hhbmRsZUZvY3VzLmJpbmQodGhpcylcbiAgICB0aGlzLl9ibHVySGFuZGxlciA9IHRoaXMuX2hhbmRsZUJsdXIuYmluZCh0aGlzKVxuICAgIHRoaXMuX3dpbmRvd0NsaWNrSGFuZGxlciA9IHRoaXMuX2hhbmRsZVdpbmRvd0NsaWNrLmJpbmQodGhpcylcbiAgICB0aGlzLl9maWx0ZXJLZXlkb3duSGFuZGxlciA9IHRoaXMuX2hhbmRsZUZpbHRlcktleWRvd24uYmluZCh0aGlzKVxuICAgIHRoaXMuX2ZpbHRlcktleXVwSGFuZGxlciA9IHRoaXMuX2hhbmRsZUZpbHRlcktleXVwLmJpbmQodGhpcylcbiAgICB0aGlzLl9maWx0ZXJGb2N1c0hhbmRsZXIgPSB0aGlzLl9oYW5kbGVGaWx0ZXJGb2N1cy5iaW5kKHRoaXMpXG5cbiAgICB0aGlzLl9pbml0aWFsaXplKClcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyB0aGUgc2VsZWN0IGNvbXBvbmVudC5cbiAgICpcbiAgICogVGhpcyBtZXRob2QgaW5zcGVjdHMgdGhlIHNlbGVjdCBkZWZpbml0aW9uIGFuZCBpdHMgb3B0aW9ucyBhbmRcbiAgICogZ2VuZXJhdGVzIG5ldyBzdHlsYWJsZSBET00gZWxlbWVudHMgYXJvdW5kIHRoZSBvcmlnaW5hbCBzZWxlY3QtZWxlbWVudFxuICAgKiBkZWZpbml0aW9ucy5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByb3RlY3RlZCBfaW5pdGlhbGl6ZSgpIHtcbiAgICBjb25zdCBzZWxlY3RlZE9wdGlvbiA9IHRoaXMuZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwib3B0aW9uW3NlbGVjdGVkXVwiKSBhcyBIVE1MT3B0aW9uRWxlbWVudFxuICAgIGNvbnN0IGZpcnN0T3B0aW9uID0gdGhpcy5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJvcHRpb25cIikgYXMgSFRNTE9wdGlvbkVsZW1lbnRcblxuICAgIC8vIFBlciBkZWZhdWx0LCBzZXQgdGhlIGxhc3Qgc2VsZWN0ZWQgb3B0aW9uIHRvIGVpdGhlciB0aGUgb3B0aW9uIHdpdGggYSBcInNlbGVjdGVkXCIgYXR0cmlidXRlLFxuICAgIC8vIG9yLCBpZiBub3QgZm91bmQsIHRvIHRoZSBmaXJzdCBhdmFpbGFibGUgb3B0aW9uXG4gICAgdGhpcy5fbGFzdFNlbGVjdGVkT3B0aW9uID0gc2VsZWN0ZWRPcHRpb24gfHwgZmlyc3RPcHRpb25cblxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50ID0gbmV3IERvbUVsZW1lbnQodGhpcy5lbGVtZW50LnBhcmVudEVsZW1lbnQhKVxuICAgICAgLmFkZENsYXNzKENMQVNTX0NMT1NFRClcblxuICAgIGZvciAobGV0IGNscyBvZiB0aGlzLmNsYXNzZXMpIHtcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmFkZENsYXNzKGNscylcbiAgICB9XG5cbiAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQgPSBuZXcgRG9tRWxlbWVudDxIVE1MRWxlbWVudD4oXCJkaXZcIilcbiAgICAgIC5hZGRDbGFzcyhDTEFTU19EUk9QRE9XTilcblxuICAgIGlmIChpbnRlcm5ldEV4cGxvcmVyT3JFZGdlVmVyc2lvbigpID4gMCAmJiBpbnRlcm5ldEV4cGxvcmVyT3JFZGdlVmVyc2lvbigpIDwgMTIpIHtcbiAgICAgIC8vIFRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvciBJRSBicm93c2VycyAxMSBhbmQgZWFybGllciB3aGVyZSBmb2N1c2luZ1xuICAgICAgLy8gYSBzY3JvbGxhYmxlIGRyb3Bkb3duIGxpc3Qgd2lsbCBjbG9zZSB0aGUgZHJvcGRvd24gcHJlbWF0dXJlbHkuXG4gICAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIChldmVudDogTW91c2VFdmVudCkgPT4gZXZlbnQucHJldmVudERlZmF1bHQoKSlcbiAgICB9XG5cbiAgICB0aGlzLl9zZXR1cFRhcmdldCgpXG4gICAgdGhpcy5fc2V0dXBQbGFjZWhvbGRlcigpXG5cbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLl9kcm9wZG93bkVsZW1lbnQpXG5cbiAgICB0aGlzLl9jcmVhdGVPcHRpb25zKHRoaXMuZWxlbWVudClcblxuICAgIHRoaXMuX3VwZGF0ZVNpemUoKVxuICAgIHRoaXMuX3VwZGF0ZU1lc3NhZ2UoKVxuXG4gICAgaWYgKHRoaXMuZWxlbWVudC5kaXNhYmxlZCkge1xuICAgICAgdGhpcy5kaXNhYmxlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbmFibGUoKVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfc2V0dXBUYXJnZXQoKSB7XG4gICAgLy8gbW92ZSB0aGUgaWQgZnJvbSB0aGUgc2VsZWN0IGVsZW1lbnQgdG8gdGhlIHdyYXBwZXJcbiAgICBjb25zdCBpZCA9IHRoaXMuZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJpZFwiKVxuICAgIGlmIChpZCkge1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShcImlkXCIpXG4gICAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBpZClcbiAgICB9XG5cbiAgICAvLyBBcHBseSB0aGUgdGFiIGluZGV4XG4gICAgY29uc3QgdGFiSW5kZXggPSB0aGlzLmVsZW1lbnQuZ2V0QXR0cmlidXRlKFwidGFiaW5kZXhcIilcbiAgICBpZiAodGFiSW5kZXgpIHtcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnNldEF0dHJpYnV0ZShcInRhYkluZGV4XCIsIHRhYkluZGV4KVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfc2V0dXBQbGFjZWhvbGRlcigpIHtcbiAgICBpZiAoIXRoaXMuX3NlbGVjdEJ1dHRvbkVsZW1lbnQpIHtcbiAgICAgIHRoaXMuX3NlbGVjdEJ1dHRvbkVsZW1lbnQgPSBuZXcgRG9tRWxlbWVudChcImRpdlwiKVxuICAgICAgICAuYWRkQ2xhc3MoQ0xBU1NfQlVUVE9OKVxuXG4gICAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLl9zZWxlY3RCdXR0b25FbGVtZW50KVxuICAgIH1cblxuICAgIGlmICghdGhpcy5fdGh1bWJFbGVtZW50KSB7XG4gICAgICB0aGlzLl90aHVtYkVsZW1lbnQgPSBuZXcgRG9tRWxlbWVudChcImRpdlwiKVxuICAgICAgICAuYWRkQ2xhc3MoQ0xBU1NfVEhVTUIpXG5cbiAgICAgIGxldCB0aHVtYkljb24gPSBuZXcgRG9tRWxlbWVudChcImRpdlwiKVxuICAgICAgICAuYWRkQ2xhc3MoXCJ0aHVtYi1pY29uXCIpXG5cbiAgICAgIGxldCBsb2FkZXIgPSBuZXcgRG9tRWxlbWVudChcImRpdlwiKVxuICAgICAgICAuYWRkQ2xhc3MoXCJsb2FkZXItc3Bpbm5lclwiKVxuICAgICAgICAuYWRkQ2xhc3MoXCJsb2FkZXItc3Bpbm5lci0tc21hbGxcIilcblxuICAgICAgdGhpcy5fdGh1bWJFbGVtZW50LmFwcGVuZENoaWxkKGxvYWRlcilcbiAgICAgIHRoaXMuX3RodW1iRWxlbWVudC5hcHBlbmRDaGlsZCh0aHVtYkljb24pXG4gICAgICB0aGlzLl9zZWxlY3RCdXR0b25FbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuX3RodW1iRWxlbWVudClcbiAgICB9XG5cbiAgICBsZXQgcGxhY2Vob2xkZXJUZXh0ID0gXCJcIlxuXG4gICAgdGhpcy5fcGxhY2Vob2xkZXJPcHRpb24gPSB0aGlzLmVsZW1lbnQucXVlcnlTZWxlY3RvcihcIm9wdGlvbltzZWxlY3RlZF1bZGlzYWJsZWRdXCIpIGFzIEhUTUxPcHRpb25FbGVtZW50IHx8IHVuZGVmaW5lZFxuXG4gICAgaWYgKHRoaXMuX3BsYWNlaG9sZGVyT3B0aW9uKSB7XG4gICAgICBwbGFjZWhvbGRlclRleHQgPSBEb20udGV4dCh0aGlzLl9wbGFjZWhvbGRlck9wdGlvbilcblxuICAgICAgaWYgKHRoaXMuX211bHRpc2VsZWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyT3B0aW9uLnNlbGVjdGVkID0gZmFsc2VcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgc2VsZWN0ZWRPcHRpb24gPSB0aGlzLmVsZW1lbnQucXVlcnlTZWxlY3RvcihcIm9wdGlvbltzZWxlY3RlZF06bm90KFtkaXNhYmxlZF0pXCIpXG5cbiAgICBpZiAoc2VsZWN0ZWRPcHRpb24pIHtcbiAgICAgIHBsYWNlaG9sZGVyVGV4dCA9IERvbS50ZXh0KHNlbGVjdGVkT3B0aW9uKVxuICAgIH1cblxuICAgIGlmICghdGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50KSB7XG4gICAgICAvLyBXaGVuIHRoZSBTZWxlY3QgaXMgZmlsdGVyYWJsZSwgY3JlYXRlIGFuIFwiaW5wdXRcIiBhcyB0aGUgcGxhY2Vob2xkZXIgZWxlbWVudCwgb3RoZXJ3aXNlIGEgXCJzcGFuXCJcbiAgICAgIGlmICh0aGlzLl9pc0ZpbHRlcmFibGUoKSkge1xuICAgICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQgPSBuZXcgRG9tRWxlbWVudChcImlucHV0XCIpXG4gICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwia2V5dXBcIiwgKGUpID0+IHRoaXMuX2hhbmRsZUZpbHRlcktleXVwKGUpKVxuICAgICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgKGUpID0+IHRoaXMuX2hhbmRsZUZpbHRlcktleWRvd24oZSkpXG4gICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKGUpID0+IHRoaXMuX2hhbmRsZUZpbHRlckZvY3VzKGUpKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50ID0gbmV3IERvbUVsZW1lbnQoXCJzcGFuXCIpXG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5hZGRDbGFzcyhDTEFTU19QTEFDRUhPTERFUilcbiAgICAgIHRoaXMuX3NlbGVjdEJ1dHRvbkVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50KVxuICAgIH1cblxuICAgIHRoaXMuX3NldFBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyVGV4dClcbiAgICB0aGlzLl9wbGFjZWhvbGRlclRleHQgPSBwbGFjZWhvbGRlclRleHRcblxuICAgIGlmIChzZWxlY3RlZE9wdGlvbiAmJiBzZWxlY3RlZE9wdGlvbiAhPT0gdGhpcy5fcGxhY2Vob2xkZXJPcHRpb24pIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVBsYWNlaG9sZGVyKHRydWUpXG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF91cGRhdGVNZXNzYWdlKCkge1xuICAgIGNvbnN0IG1lc3NhZ2VOb2RlID0gdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5xdWVyeVNlbGVjdG9yKFFVRVJZX01FU1NBR0UpXG4gICAgaWYgKG1lc3NhZ2VOb2RlICE9PSBudWxsKSB7XG4gICAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5hcHBlbmRDaGlsZChuZXcgRG9tRWxlbWVudChtZXNzYWdlTm9kZSkpXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfaXNPcHRHcm91cChlbGVtZW50OiBFbGVtZW50KTogZWxlbWVudCBpcyBIVE1MT3B0R3JvdXBFbGVtZW50IHtcbiAgICByZXR1cm4gZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09IFwiT1BUR1JPVVBcIlxuICB9XG5cbiAgcHJpdmF0ZSBfaXNPcHRpb24oZWxlbWVudDogRWxlbWVudCk6IGVsZW1lbnQgaXMgSFRNTE9wdGlvbkVsZW1lbnQge1xuICAgIHJldHVybiBlbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKSA9PT0gXCJPUFRJT05cIlxuICB9XG5cbiAgcHJvdGVjdGVkIF9jcmVhdGVPcHRpb25zKGVsZW1lbnQ6IEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgY2hpbGQgPSBlbGVtZW50LmNoaWxkcmVuW2ldXG5cbiAgICAgIGlmICh0aGlzLl9pc09wdEdyb3VwKGNoaWxkKSkge1xuICAgICAgICB0aGlzLl9hcHBlbmRHcm91cChjaGlsZCBhcyBIVE1MT3B0R3JvdXBFbGVtZW50KVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5faXNPcHRpb24oY2hpbGQpKSB7XG4gICAgICAgIGxldCBvcHRpb24gPSB0aGlzLl9jcmVhdGVPcHRpb24oY2hpbGQgYXMgSFRNTE9wdGlvbkVsZW1lbnQpXG5cbiAgICAgICAgaWYgKG9wdGlvbikge1xuICAgICAgICAgIHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5hcHBlbmRDaGlsZChvcHRpb24pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX2NyZWF0ZU9wdGlvbihvcHRpb246IEhUTUxPcHRpb25FbGVtZW50KSB7XG4gICAgbGV0IGh0bWwgPSBvcHRpb24uaW5uZXJIVE1MXG5cbiAgICBpZiAodGhpcy5fYWN0aXZlRmlsdGVyKSB7XG4gICAgICBjb25zdCBzYW5pdGl6ZWRBY3RpdmVGaWx0ZXIgPSB0aGlzLl9hY3RpdmVGaWx0ZXIucmVwbGFjZSgvWy1cXFxcXiQqKz8uKCl8W1xcXXt9XS9nLCBcIlxcXFwkJlwiKVxuICAgICAgaHRtbCA9IGh0bWwucmVwbGFjZShuZXcgUmVnRXhwKGAoJHtzYW5pdGl6ZWRBY3RpdmVGaWx0ZXJ9KWAsIFwiZ2lcIiksIFwiPHN0cm9uZz4kMTwvc3Ryb25nPlwiKVxuICAgIH1cblxuICAgIGxldCBvcHQgPSBuZXcgRG9tRWxlbWVudChcImRpdlwiKVxuICAgICAgLmFkZENsYXNzKENMQVNTX0lURU0pXG4gICAgICAuc2V0SHRtbChodG1sKVxuXG4gICAgaWYgKG9wdGlvbi5zZWxlY3RlZCkge1xuICAgICAgb3B0LmFkZENsYXNzKENMQVNTX0lURU1fU0VMRUNURUQpXG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbi5kaXNhYmxlZCkge1xuICAgICAgb3B0LmFkZENsYXNzKENMQVNTX0lURU1fRElTQUJMRUQpXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl9pc1BsYWNlaG9sZGVyKG9wdGlvbikpIHtcbiAgICAgIG9wdC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXZhbHVlXCIsIG9wdGlvbi52YWx1ZSlcbiAgICAgIHJldHVybiBvcHRcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICBwcm90ZWN0ZWQgX2FwcGVuZEdyb3VwKG9wdGdyb3VwOiBIVE1MT3B0R3JvdXBFbGVtZW50KSB7XG4gICAgbGV0IGxhYmVsID0gb3B0Z3JvdXAuZ2V0QXR0cmlidXRlKFwibGFiZWxcIikhXG5cbiAgICBsZXQgZ3JvdXAgPSBuZXcgRG9tRWxlbWVudChcImRpdlwiKVxuICAgICAgLmFkZENsYXNzKENMQVNTX0dST1VQX0lURU0pXG5cbiAgICBsZXQgZ3JvdXBIZWFkZXIgPSBuZXcgRG9tRWxlbWVudChcImRpdlwiKVxuICAgICAgLmFkZENsYXNzKENMQVNTX0dST1VQX0hFQURFUilcbiAgICAgIC5zZXRIdG1sKGxhYmVsKVxuXG4gICAgZ3JvdXAuYXBwZW5kQ2hpbGQoZ3JvdXBIZWFkZXIpXG5cbiAgICBsZXQgb3B0aW9ucyA9IG9wdGdyb3VwLnF1ZXJ5U2VsZWN0b3JBbGwoXCJvcHRpb25cIilcbiAgICBmb3IgKGxldCBlbnRyeSBvZiBvcHRpb25zKSB7XG4gICAgICBsZXQgb3B0aW9uID0gdGhpcy5fY3JlYXRlT3B0aW9uKGVudHJ5KVxuICAgICAgaWYgKG9wdGlvbikge1xuICAgICAgICBncm91cC5hcHBlbmRDaGlsZChvcHRpb24pXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmFwcGVuZENoaWxkKGdyb3VwKVxuICAgIHJldHVybiBncm91cFxuICB9XG5cbiAgcHJvdGVjdGVkIF91cGRhdGVTaXplKCkge1xuICAgIC8vIE5vdGU6IE1pcnJvcmluZyB0aGUgRE9NIGFuZCBtZWFzdXJpbmcgdGhlIGl0ZW1zIHVzaW5nIHRoZWlyIGNsaWVudFdpZHRoIHdhcyB2ZXJ5XG4gICAgLy8gdW5yZWxpYWJsZSwgdGhlcmVmb3JlIG1lYXN1cmluZyB3YXMgc3dpdGNoZWQgdG8gdGhlIG5ldyBIVE1MNSBtZWFzdXJlVGV4dCBtZXRob2RcbiAgICAvLyBtYXJnaW5zIGFuZCBwYWRkaW5ncyBhcnJvdW5kIHRoZSB0ZXh0IGFyZSBjb3BpZWQgZnJvbSB0aGUgb3JpZ2luYWwgcGxhY2Vob2xkZXIgaXRlbXNcbiAgICAvLyBkaW1lbnNpb25cbiAgICBjb25zdCBwbGFjZWhvbGRlclN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50LmVsZW1lbnQpXG5cbiAgICBsZXQgcGFkZGluZ1JpZ2h0ID0gcGFyc2VGbG9hdChwbGFjZWhvbGRlclN0eWxlLnBhZGRpbmdSaWdodCEpXG4gICAgbGV0IHBhZGRpbmdMZWZ0ID0gcGFyc2VGbG9hdChwbGFjZWhvbGRlclN0eWxlLnBhZGRpbmdMZWZ0ISlcblxuICAgIGxldCBmb250ID0gdGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50LmNzcyhcImZvbnRcIilcbiAgICBsZXQgdGV4dFdpZHRoID0gRG9tLnRleHRXaWR0aCh0aGlzLl9wbGFjZWhvbGRlclRleHQsIGZvbnQpXG4gICAgbGV0IG1heFdpZHRoID0gcGFkZGluZ0xlZnQgKyBwYWRkaW5nUmlnaHQgKyB0ZXh0V2lkdGhcblxuICAgIGxldCBvcHRpb25zID0gdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKGAuJHtDTEFTU19JVEVNfWApXG4gICAgZm9yIChsZXQgZW50cnkgb2Ygb3B0aW9ucykge1xuICAgICAgbGV0IHdpZHRoID0gRG9tLnRleHRXaWR0aChEb20udGV4dChlbnRyeSksIGZvbnQpICsgcGFkZGluZ0xlZnQgKyBwYWRkaW5nUmlnaHRcblxuICAgICAgaWYgKHdpZHRoID4gbWF4V2lkdGgpIHtcbiAgICAgICAgbWF4V2lkdGggPSB3aWR0aFxuICAgICAgfVxuICAgIH1cblxuICB9XG5cbiAgcHJvdGVjdGVkIF9pc0J1dHRvblRhcmdldCh0YXJnZXQ6IEV2ZW50VGFyZ2V0KSB7XG4gICAgcmV0dXJuICh0YXJnZXQgPT09IHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQgfHxcbiAgICAgIHRhcmdldCA9PT0gdGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50LmVsZW1lbnQgfHxcbiAgICAgIHRhcmdldCA9PT0gdGhpcy5fc2VsZWN0QnV0dG9uRWxlbWVudC5lbGVtZW50IHx8XG4gICAgICB0YXJnZXQgPT09IHRoaXMuX3RodW1iRWxlbWVudC5lbGVtZW50KVxuICB9XG5cbiAgcHJvdGVjdGVkIF9pc0Ryb3Bkb3duVGFyZ2V0KHRhcmdldDogRXZlbnRUYXJnZXQpIHtcbiAgICBsZXQgY3VycmVudCA9IHRhcmdldCBhcyBIVE1MRWxlbWVudFxuICAgIHdoaWxlIChjdXJyZW50ICE9PSB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudCAmJiBjdXJyZW50LnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudEVsZW1lbnRcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudCA9PT0gdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBVSSBpZiB0aGUgc2VsZWN0aW9uIGhhcyBjaGFuZ2VkIGFuZCBtYWtlcyBzdXJlIHRoZVxuICAgKiBzZWxlY3QgY29udHJvbCBhbmQgdGhlIGdlbmVyYXRlZCBtYXJrdXAgYXJlIHN5bmNocm9uaXplZC5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByb3RlY3RlZCBfc2VsZWN0ZWRJdGVtQ2hhbmdlZChcbiAgICBuZXdJdGVtOiBFbGVtZW50LFxuICAgIGF1dG9DbG9zZSA9IHRydWUsXG4gICAgbXVsdGlzZWxlY3QgPSBmYWxzZVxuICApIHtcbiAgICBjb25zdCBvbGRJdGVtcyA9IHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0lURU1fU0VMRUNURUR9YClcblxuICAgIGlmICghbmV3SXRlbSkge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNsb3NlKCksIFRJTUVPVVRfQ0xPU0UpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoRG9tLmhhc0NsYXNzKG5ld0l0ZW0sIENMQVNTX0lURU1fRElTQUJMRUQpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoKG9sZEl0ZW1zLmxlbmd0aCA9PT0gMCkgJiYgIW5ld0l0ZW0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbiBub3Qgc2VsZWN0IHVuZGVmaW5lZCBlbGVtZW50c1wiKVxuICAgIH1cblxuICAgIGxldCBvbGRJdGVtID0gb2xkSXRlbXNbMF1cblxuICAgIGlmIChtdWx0aXNlbGVjdCA9PT0gdHJ1ZSkge1xuICAgICAgb2xkSXRlbSA9IGZpbmQob2xkSXRlbXMsICh4KSA9PiB4LmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIikgPT09IG5ld0l0ZW0uZ2V0QXR0cmlidXRlKFwiZGF0YS12YWx1ZVwiKSkhXG4gICAgfVxuXG4gICAgbGV0IGlzRGVzZWxlY3QgPSBmYWxzZVxuXG4gICAgaWYgKG5ld0l0ZW0gJiYgb2xkSXRlbSAmJiBvbGRJdGVtID09PSBuZXdJdGVtKSB7XG4gICAgICAvLyBDbGljayBvbiBhIHByZXZpb3VzbHkgc2VsZWN0ZWQgZWxlbWVudCAtPiBkZXNlbGVjdFxuICAgICAgaXNEZXNlbGVjdCA9IHRydWVcblxuICAgICAgaWYgKCF0aGlzLl9wbGFjZWhvbGRlck9wdGlvbiAmJiAhbXVsdGlzZWxlY3QpIHtcbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gcGxhY2Vob2xkZXIgb3B0aW9uLCBub24gbXVsdGlzZWxlY3Qgb3B0aW9ucyBjYW5ub3QgYmUgZGVzZWxlY3RlZFxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgZGVsZXRlIHRoaXMuX2xhc3RTZWxlY3RlZE9wdGlvblxuICAgIH1cblxuICAgIGlmIChvbGRJdGVtKSB7XG4gICAgICAvLyBSZW1vdmUgc2VsZWN0aW9uIG9uIHRoZSBlbGVtZW50XG4gICAgICBsZXQgb2xkVmFsdWUgPSBvbGRJdGVtLmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIilcbiAgICAgIGxldCBvcHRFbGVtZW50ID0gZmluZCh0aGlzLmVsZW1lbnQub3B0aW9ucywgKHgpID0+ICF4LmRpc2FibGVkICYmIHgudmFsdWUgPT09IG9sZFZhbHVlKVxuXG4gICAgICBpZiAoIW9wdEVsZW1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgb3B0aW9uIHdpdGggdmFsdWUgJHtvbGRWYWx1ZX0gZG9lcyBub3QgZXhpc3RgKVxuICAgICAgfVxuXG4gICAgICAvLyBVbnNldCBTZWxlY3QgdmFsdWVcbiAgICAgIG9wdEVsZW1lbnQuc2VsZWN0ZWQgPSBmYWxzZVxuICAgICAgRG9tLnJlbW92ZUNsYXNzKG9sZEl0ZW0sIENMQVNTX0lURU1fU0VMRUNURUQpXG4gICAgfVxuXG4gICAgaWYgKCFpc0Rlc2VsZWN0KSB7IC8vIFNlbGVjdCBhbiBvcHRpb25cbiAgICAgIC8vIFNlbGVjdCBhIG5ldyBpdGVtXG4gICAgICBsZXQgbmV3VmFsdWUgPSBuZXdJdGVtLmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIilcbiAgICAgIGxldCBvcHRFbGVtZW50ID0gZmluZCh0aGlzLmVsZW1lbnQub3B0aW9ucywgKHgpID0+ICF4LmRpc2FibGVkICYmIHgudmFsdWUgPT09IG5ld1ZhbHVlKVxuXG4gICAgICBpZiAoIW9wdEVsZW1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgb3B0aW9uIHdpdGggdmFsdWUgJHtuZXdWYWx1ZX0gZG9lcyBub3QgZXhpc3RgKVxuICAgICAgfVxuXG4gICAgICAvLyBTZXQgU2VsZWN0IHZhbHVlXG4gICAgICBvcHRFbGVtZW50LnNlbGVjdGVkID0gdHJ1ZVxuICAgICAgRG9tLmFkZENsYXNzKG5ld0l0ZW0sIENMQVNTX0lURU1fU0VMRUNURUQpXG5cbiAgICAgIC8vIFByZXNlcnZlIHNlbGVjdGlvblxuICAgICAgdGhpcy5fbGFzdFNlbGVjdGVkT3B0aW9uID0gb3B0RWxlbWVudFxuXG4gICAgfSBlbHNlIHsgLy8gRGVzZWxlY3QgYW4gb3B0aW9uXG4gICAgICAvLyBLZWVwIHRyYWNrIG9mIGZhbGxpbmcgYmFjayB0byB0aGUgcGxhY2Vob2xkZXIgKGlmIGFueSlcbiAgICAgIGlmICh0aGlzLl9wbGFjZWhvbGRlck9wdGlvbikge1xuICAgICAgICB0aGlzLl9sYXN0U2VsZWN0ZWRPcHRpb24gPSB0aGlzLl9wbGFjZWhvbGRlck9wdGlvblxuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBoYXNTZWxlY3RlZEl0ZW1zID0gdHJ1ZVxuXG4gICAgaWYgKHRoaXMuX211bHRpc2VsZWN0aW9uID09PSBmYWxzZSAmJiBpc0Rlc2VsZWN0KSB7XG4gICAgICAvLyBIYW5kbGUgbm8gc2VsZWN0aW9uIGZvciBub24tbXVsdGlzZWxlY3Qgc3RhdGVzXG4gICAgICB0aGlzLl9wbGFjZWhvbGRlck9wdGlvbiEuc2VsZWN0ZWQgPSB0cnVlXG4gICAgICBoYXNTZWxlY3RlZEl0ZW1zID0gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fbXVsdGlzZWxlY3Rpb24gPT09IHRydWUgJiYgdGhpcy5fZ2V0U2VsZWN0ZWRPcHRpb25zKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICBoYXNTZWxlY3RlZEl0ZW1zID0gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBSZXNldCB0aGUgZmlsdGVyIGlmIGZpbHRlcmFibGVcbiAgICBpZiAodGhpcy5fYWN0aXZlRmlsdGVyKSB7XG4gICAgICB0aGlzLl9jbGVhckZpbHRlcigpXG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlUGxhY2Vob2xkZXIoaGFzU2VsZWN0ZWRJdGVtcylcblxuICAgIC8vIERpc3BhdGNoIHRoZSBjaGFuZ2VkIGV2ZW50XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KFwiY2hhbmdlXCIpXG5cbiAgICBpZiAoYXV0b0Nsb3NlICYmICFtdWx0aXNlbGVjdCkge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xvc2UoKVxuICAgICAgfSwgVElNRU9VVF9DTE9TRSlcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX3VwZGF0ZVBsYWNlaG9sZGVyKGhhc1NlbGVjdGVkSXRlbXM6IGJvb2xlYW4pIHtcbiAgICBsZXQgdGV4dCA9IHRoaXMuX3BsYWNlaG9sZGVyT3B0aW9uID8gRG9tLnRleHQodGhpcy5fcGxhY2Vob2xkZXJPcHRpb24pIDogXCIgXCJcblxuICAgIGlmIChoYXNTZWxlY3RlZEl0ZW1zID09PSB0cnVlKSB7XG4gICAgICBsZXQgc2VsZWN0ZWRJdGVtcyA9IHRoaXMuX2dldFNlbGVjdGVkT3B0aW9ucygpXG5cbiAgICAgIGlmIChzZWxlY3RlZEl0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGV4dCA9IFwiXCJcbiAgICAgICAgZm9yIChsZXQgaXRlbSBvZiBzZWxlY3RlZEl0ZW1zKSB7XG4gICAgICAgICAgdGV4dCArPSBgJHtEb20udGV4dChpdGVtKX0sIGBcbiAgICAgICAgfVxuICAgICAgICB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcoMCwgdGV4dC5sZW5ndGggLSAyKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3NldFBsYWNlaG9sZGVyKHRleHQpXG4gIH1cblxuICBwcm90ZWN0ZWQgX2dldFNlbGVjdGVkT3B0aW9ucygpIHtcbiAgICBsZXQgc2VsZWN0ZWRPcHRpb25zOiBIVE1MT3B0aW9uRWxlbWVudFtdID0gW11cbiAgICBpZiAodGhpcy5lbGVtZW50Lm9wdGlvbnMpIHtcbiAgICAgIFtdLmZvckVhY2guY2FsbCh0aGlzLmVsZW1lbnQub3B0aW9ucywgKChvcHRpb246IEhUTUxPcHRpb25FbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChvcHRpb24uc2VsZWN0ZWQgJiYgIW9wdGlvbi5kaXNhYmxlZCkge1xuICAgICAgICAgIHNlbGVjdGVkT3B0aW9ucy5wdXNoKG9wdGlvbilcbiAgICAgICAgfVxuICAgICAgfSkpXG4gICAgfVxuICAgIHJldHVybiBzZWxlY3RlZE9wdGlvbnNcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9uZSBhbGwgb2YgdGhlIGluaXRpYWxseSBzZXQgb3B0aW9ucyAoYW5kIG9wdGdyb3VwcykgYW5kIHJldHVybnMgdGhlbSBpbiBhIG5ldyBhcnJheS5cbiAgICogVGhpcyBzZXJ2ZXMgYXMgdGhlIGJhc2lzIGZvciBmaWx0ZXJpbmcuIElmIGEgZmlsdGVyIGlzIHByZXNlbnQsIGl0IHdpbGwgYmUgcmVzcGVjdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRJbml0aWFsT3B0aW9ucygpOiBFbGVtZW50W10ge1xuICAgIGNvbnN0IGZpbHRlciA9IHRoaXMuX2FjdGl2ZUZpbHRlciB8fCBcIlwiXG4gICAgY29uc3QgZmlsdGVyZWQ6IEVsZW1lbnRbXSA9IFtdXG4gICAgY29uc3QgaW5pdGlhbE9wdGlvbnMgPSB0aGlzLl9pbml0aWFsT3B0aW9uc1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbml0aWFsT3B0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY2hpbGQ6IEVsZW1lbnQgPSBpbml0aWFsT3B0aW9uc1tpXSBhcyBFbGVtZW50XG5cbiAgICAgIGlmICh0aGlzLl9pc09wdEdyb3VwKGNoaWxkKSkgeyAvLyBoYW5kbGUgPG9wdGdyb3VwPlxuICAgICAgICBjb25zdCBvcHRHcm91cENsb25lOiBFbGVtZW50ID0gY2hpbGQuY2xvbmVOb2RlKGZhbHNlKSBhcyBFbGVtZW50XG4gICAgICAgIGxldCBmb3VuZCA9IGZhbHNlXG5cbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjaGlsZC5jaGlsZHJlbi5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IG9wdGlvbkNsb25lOiBFbGVtZW50ID0gY2hpbGQuY2hpbGRyZW5bal0uY2xvbmVOb2RlKHRydWUpIGFzIEVsZW1lbnRcblxuICAgICAgICAgIC8vIEFwcGVuZCBvbiBtYXRjaFxuICAgICAgICAgIGlmICh0aGlzLl9jb250YWluc1dvcmQob3B0aW9uQ2xvbmUuaW5uZXJIVE1MLCBmaWx0ZXIpKSB7XG4gICAgICAgICAgICBvcHRHcm91cENsb25lLmFwcGVuZENoaWxkKG9wdGlvbkNsb25lKVxuICAgICAgICAgICAgZm91bmQgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHVzaCBpZiBhbnkgbWF0Y2hlcyBmb3VuZFxuICAgICAgICBpZiAoZm91bmQpIHtcbiAgICAgICAgICBmaWx0ZXJlZC5wdXNoKG9wdEdyb3VwQ2xvbmUpXG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmICh0aGlzLl9pc09wdGlvbihjaGlsZCkpIHsgLy8gaGFuZGxlIDxvcHRpb24+XG4gICAgICAgIGNvbnN0IG9wdGlvbkNsb25lOiBFbGVtZW50ID0gY2hpbGQuY2xvbmVOb2RlKHRydWUpIGFzIEVsZW1lbnRcblxuICAgICAgICAvLyBQdXNoIG9uIG1hdGNoXG4gICAgICAgIGlmICh0aGlzLl9jb250YWluc1dvcmQob3B0aW9uQ2xvbmUuaW5uZXJIVE1MLCBmaWx0ZXIpKSB7XG4gICAgICAgICAgZmlsdGVyZWQucHVzaChvcHRpb25DbG9uZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJlZFxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBhIHRleHQgY29udGFpbnMgYSBnaXZlbiBrZXl3b3JkLCBlLmcuIGluIFwiY2FcIiBpbiBcIkNhclwiXG4gICAqL1xuICBwcml2YXRlIF9jb250YWluc1dvcmQodGV4dDogc3RyaW5nLCBrZXl3b3JkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGV4dC50b0xvd2VyQ2FzZSgpLmluZGV4T2Yoa2V5d29yZC50b0xvd2VyQ2FzZSgpKSA+IC0xXG4gIH1cblxuICBwcm90ZWN0ZWQgX2hhbmRsZUZvY3VzKCkge1xuICAgIHRoaXMub3BlbigpXG4gICAgdGhpcy5fb3BlbkJ5Rm9jdXMgPSB0cnVlXG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuX29wZW5CeUZvY3VzID0gZmFsc2VcbiAgICB9LCBUSU1FT1VUX0JMVVIpXG4gIH1cblxuICBwcm90ZWN0ZWQgX2hhbmRsZUJsdXIoKSB7XG4gICAgdGhpcy5jbG9zZSgpXG4gIH1cblxuICBwcm90ZWN0ZWQgX2hhbmRsZUNsaWNrKGV2ZW50OiBFdmVudCkge1xuICAgIGxldCBoYW5kbGVkID0gZmFsc2VcblxuICAgIGlmICh0aGlzLl9sYXN0SGFuZGxlZEV2ZW50ID09PSBldmVudCkge1xuICAgICAgdGhpcy5fbGFzdEhhbmRsZWRFdmVudCA9IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2lzQnV0dG9uVGFyZ2V0KGV2ZW50LnRhcmdldCEpICYmIHRoaXMuX29wZW5CeUZvY3VzID09PSBmYWxzZSkge1xuICAgICAgLy8gaGFuZGxlIGhlYWRlciBpdGVtIGNsaWNrcyBhbmQgdG9nZ2xlIGRyb3Bkb3duXG4gICAgICB0aGlzLnRvZ2dsZSgpXG4gICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIGxldCBuZXdJdGVtID0gZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnRcblxuICAgIGlmICghaGFuZGxlZCAmJiBEb20uaGFzQ2xhc3MobmV3SXRlbSwgQ0xBU1NfSVRFTSkpIHtcbiAgICAgIC8vIGhhbmRsZSBjbGlja3Mgb24gZHJvcGRvd24gaXRlbXNcbiAgICAgIHRoaXMuX3NlbGVjdGVkSXRlbUNoYW5nZWQobmV3SXRlbSwgdHJ1ZSwgdGhpcy5fbXVsdGlzZWxlY3Rpb24pXG4gICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIGlmIChoYW5kbGVkKSB7XG4gICAgICB0aGlzLl9sYXN0SGFuZGxlZEV2ZW50ID0gZXZlbnRcbiAgICAgIHByZXZlbnREZWZhdWx0KGV2ZW50KVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfaGFuZGxlV2luZG93Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAodGhpcy5faXNEcm9wZG93blRhcmdldChldmVudC50YXJnZXQhKSB8fCB0aGlzLl9pc0J1dHRvblRhcmdldChldmVudC50YXJnZXQhKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSgpXG4gIH1cblxuICBwcm90ZWN0ZWQgX2ZvY3VzT3B0aW9uU3RhcnRpbmdXaXRoKGtleWNvZGU6IG51bWJlciwgc3RhcnRJbmRleDogbnVtYmVyLCBvcHRpb25zOiBOb2RlTGlzdE9mPEhUTUxFbGVtZW50Pikge1xuICAgIGZvciAobGV0IGluZGV4ID0gc3RhcnRJbmRleDsgaW5kZXggPCBvcHRpb25zLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgbGV0IGl0ZW0gPSBuZXcgRG9tRWxlbWVudChvcHRpb25zW2luZGV4XSlcbiAgICAgIGxldCB2YWx1ZSA9IGl0ZW0uaW5uZXJUZXh0LnRvTG93ZXJDYXNlKClcblxuICAgICAgaWYgKGluZGV4ID4gb3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSAwXG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZS5zdGFydHNXaXRoKElucHV0cy5nZXRLZXlWYWx1ZShrZXljb2RlKSkpIHtcbiAgICAgICAgbGV0IG5ld09wdGlvbiA9IG5ldyBEb21FbGVtZW50KG9wdGlvbnNbaW5kZXhdKVxuXG4gICAgICAgIGlmICghbmV3T3B0aW9uLmhhc0NsYXNzKENMQVNTX0lURU1fRElTQUJMRUQpKSB7XG4gICAgICAgICAgc2Nyb2xsSW50b1ZpZXcob3B0aW9uc1tpbmRleF0pXG4gICAgICAgICAgbmV3T3B0aW9uLmFkZENsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcbiAgICAgICAgICByZXR1cm4gbmV3T3B0aW9uXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgcHJvdGVjdGVkIF9oYW5kbGVLZXlkb3duKGV2ZW50OiBFdmVudCkge1xuICAgIGNvbnN0IGtleWJvYXJkRXZlbnQgPSBldmVudCBhcyBLZXlib2FyZEV2ZW50XG4gICAgbGV0IGV2dCA9IGtleWJvYXJkRXZlbnQgfHwgd2luZG93LmV2ZW50XG4gICAgbGV0IGtleWNvZGUgPSBrZXlib2FyZEV2ZW50LndoaWNoIHx8IGtleWJvYXJkRXZlbnQua2V5Q29kZVxuXG4gICAgaWYgKGtleWNvZGUgPT09IElucHV0cy5LRVlfRVNDQVBFKSB7XG4gICAgICAvLyBoYW5kbGUgRXNjYXBlIGtleSAoRVNDKVxuICAgICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgICAgdGhpcy5jbG9zZSgpXG4gICAgICB9XG4gICAgICBldnQucHJldmVudERlZmF1bHQoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGtleWNvZGUgPT09IElucHV0cy5LRVlfQVJST1dfVVAgfHwga2V5Y29kZSA9PT0gSW5wdXRzLktFWV9BUlJPV19ET1dOKSB7XG4gICAgICAvLyBVcCBhbmQgZG93biBhcnJvd3NcblxuICAgICAgbGV0IG9wdGlvbnMgPSB0aGlzLl93cmFwcGVyRWxlbWVudC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0lURU19YCkgYXMgTm9kZUxpc3RPZjxIVE1MRWxlbWVudD5cbiAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcblxuICAgICAgICBsZXQgbmV3SW5kZXggPSAwXG4gICAgICAgIGxldCBvbGRPcHRpb25cblxuICAgICAgICBsZXQgZm9jdXNlZEVsZW1lbnQgPSB0aGlzLl93cmFwcGVyRWxlbWVudC5maW5kKGAuJHtDTEFTU19JVEVNX0ZPQ1VTRUR9YClcbiAgICAgICAgbGV0IHNlYXJjaEZvciA9IGZvY3VzZWRFbGVtZW50ID8gQ0xBU1NfSVRFTV9GT0NVU0VEIDogQ0xBU1NfSVRFTV9TRUxFQ1RFRFxuXG4gICAgICAgIGxldCBuZXdFbGVtZW50XG5cbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG9wdGlvbnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgbGV0IGRpcmVjdGlvbiA9IGtleWNvZGUgPT09IElucHV0cy5LRVlfQVJST1dfRE9XTiA/IDEgOiAtMVxuXG4gICAgICAgICAgbGV0IGl0ZW0gPSBuZXcgRG9tRWxlbWVudChvcHRpb25zW2luZGV4XSlcblxuICAgICAgICAgIC8vIHNlYXJjaCBmb3Igc2VsZWN0ZWQgb3IgZm9jdXNlZEVsZW1lbnQgZWxlbWVudHNcbiAgICAgICAgICBpZiAoaXRlbS5oYXNDbGFzcyhzZWFyY2hGb3IpKSB7XG4gICAgICAgICAgICBvbGRPcHRpb24gPSBpdGVtXG4gICAgICAgICAgICBuZXdJbmRleCA9IGluZGV4XG5cbiAgICAgICAgICAgIC8vIGdldCB0aGUgbmV4dCBub3QgZGlzYWJsZWQgZWxlbWVudCBpbiB0aGUgYXBwcm9wcmlhdGUgZGlyZWN0aW9uXG4gICAgICAgICAgICBmb3IgKGxldCBjb3VudCA9IDA7IGNvdW50IDwgb3B0aW9ucy5sZW5ndGg7IGNvdW50KyspIHtcbiAgICAgICAgICAgICAgbmV3SW5kZXggKz0gZGlyZWN0aW9uXG4gICAgICAgICAgICAgIG5ld0luZGV4ICU9IG9wdGlvbnMubGVuZ3RoXG5cbiAgICAgICAgICAgICAgaWYgKG5ld0luZGV4IDwgMCkge1xuICAgICAgICAgICAgICAgIG5ld0luZGV4ID0gb3B0aW9ucy5sZW5ndGggLSAxXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBuZXdFbGVtZW50ID0gbmV3IERvbUVsZW1lbnQob3B0aW9uc1tuZXdJbmRleF0pXG4gICAgICAgICAgICAgIGlmICghbmV3RWxlbWVudC5oYXNDbGFzcyhDTEFTU19JVEVNX0RJU0FCTEVEKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgdGhlIG5ldyBlbGVtZW50IGZvY3VzZWRcbiAgICAgICAgc2Nyb2xsSW50b1ZpZXcob3B0aW9uc1tuZXdJbmRleF0pXG4gICAgICAgIGxldCBuZXdPcHRpb24gPSBuZXcgRG9tRWxlbWVudChvcHRpb25zW25ld0luZGV4XSlcbiAgICAgICAgbmV3T3B0aW9uLmFkZENsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcblxuICAgICAgICBpZiAob2xkT3B0aW9uKSB7XG4gICAgICAgICAgb2xkT3B0aW9uLnJlbW92ZUNsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBldnQucHJldmVudERlZmF1bHQoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKElucHV0cy5nZXRLZXlWYWx1ZShrZXljb2RlKSAmJiAhdGhpcy5faXNGaWx0ZXJhYmxlKCkpIHtcbiAgICAgIC8vIEtleWJvYXJkIGtleXNcblxuICAgICAgbGV0IG9wdGlvbnMgPSB0aGlzLl93cmFwcGVyRWxlbWVudC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke0NMQVNTX0lURU19YCkgYXMgTm9kZUxpc3RPZjxIVE1MRWxlbWVudD5cbiAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDApIHtcblxuICAgICAgICBsZXQgb2xkRm9jdXNJbmRleCA9IDBcbiAgICAgICAgbGV0IGhhc0ZvY3VzZWRPcHRpb24gPSBmYWxzZVxuXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBvcHRpb25zLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgIGxldCBpdGVtID0gbmV3IERvbUVsZW1lbnQob3B0aW9uc1tpbmRleF0pXG5cbiAgICAgICAgICBpZiAoaXRlbS5oYXNDbGFzcyhDTEFTU19JVEVNX0ZPQ1VTRUQpKSB7XG4gICAgICAgICAgICBpdGVtLnJlbW92ZUNsYXNzKENMQVNTX0lURU1fRk9DVVNFRClcblxuICAgICAgICAgICAgbGV0IHZhbHVlID0gaXRlbS5pbm5lclRleHQudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoSW5wdXRzLmdldEtleVZhbHVlKGtleWNvZGUpKSkge1xuICAgICAgICAgICAgICBoYXNGb2N1c2VkT3B0aW9uID0gdHJ1ZVxuICAgICAgICAgICAgICBvbGRGb2N1c0luZGV4ID0gaW5kZXhcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbmV3T3B0aW9uID0gdGhpcy5fZm9jdXNPcHRpb25TdGFydGluZ1dpdGgoa2V5Y29kZSwgaGFzRm9jdXNlZE9wdGlvbiA/IG9sZEZvY3VzSW5kZXggKyAxIDogMCwgb3B0aW9ucylcbiAgICAgICAgaWYgKG5ld09wdGlvbiA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgICB0aGlzLl9mb2N1c09wdGlvblN0YXJ0aW5nV2l0aChrZXljb2RlLCAwLCBvcHRpb25zKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoa2V5Y29kZSA9PT0gSW5wdXRzLktFWV9FTlRFUiB8fCBrZXljb2RlID09PSBJbnB1dHMuS0VZX1RBQikge1xuICAgICAgLy8gSGFuZGxlIGVudGVyIGFuZCB0YWIga2V5IGJ5IHNlbGVjdGluZyB0aGUgY3VycmVudGx5IGZvY3VzZWQgZWxlbWVudFxuICAgICAgbGV0IG5ld0l0ZW0gPSB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5xdWVyeVNlbGVjdG9yKGAuJHtDTEFTU19JVEVNX0ZPQ1VTRUR9YCkhXG4gICAgICB0aGlzLl9zZWxlY3RlZEl0ZW1DaGFuZ2VkKG5ld0l0ZW0sIHRydWUsIHRoaXMuX211bHRpc2VsZWN0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIHRoZSB1c2VyIHByZXNzZXMgYSBrZXkgaW4gdGhlIGZpbHRlciBmaWVsZFxuICAgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlRmlsdGVyS2V5ZG93bihlOiBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGtleWJvYXJkRXZlbnQgPSBlIGFzIEtleWJvYXJkRXZlbnRcbiAgICBjb25zdCBrZXljb2RlID0ga2V5Ym9hcmRFdmVudC53aGljaCB8fCBrZXlib2FyZEV2ZW50LmtleUNvZGVcblxuICAgIC8vIElmIHRoZSB1c2VyIGhpdHMgdGhlIGVudGVyIGtleSB3aGlsZSBmaWx0ZXJpbmcgYW5kIHRoZXJlJ3MgYSBzaW5nbGUgbWF0Y2gsIHNlbGVjdCBpdFxuICAgIGlmIChrZXljb2RlID09PSBJbnB1dHMuS0VZX0VOVEVSKSB7XG4gICAgICBjb25zdCBkcm9wZG93bkVsZW1lbnRzID0gdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChgLiR7Q0xBU1NfSVRFTX1gKVxuXG4gICAgICBpZiAoZHJvcGRvd25FbGVtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWRJdGVtQ2hhbmdlZChkcm9wZG93bkVsZW1lbnRzWzBdLCB0cnVlLCB0aGlzLl9tdWx0aXNlbGVjdGlvbilcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIHRoZSB1c2VyIHJlbGVhc2VzIGEga2V5IGluIHRoZSBmaWx0ZXIgZmllbGRcbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZUZpbHRlcktleXVwKGU6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudFxuXG4gICAgLy8gRmlsdGVyIGhhcyBjaGFuZ2VkXG4gICAgaWYgKHRhcmdldC52YWx1ZSAhPT0gdGhpcy5fYWN0aXZlRmlsdGVyICYmIHRhcmdldC52YWx1ZSAhPT0gdGhpcy5fcGxhY2Vob2xkZXJUZXh0ICYmIHRhcmdldC52YWx1ZSAhPT0gdGhpcy5fbGFzdFNlbGVjdGVkT3B0aW9uIS5pbm5lckhUTUwpIHtcbiAgICAgIHRoaXMuX3NldEZpbHRlcih0YXJnZXQudmFsdWUpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpcmVkIHdoZW4gdGhlIHVzZXIgZm9jdXNzZXMgdGhlIGZpbHRlciBpbnB1dCBmaWVsZFxuICAgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlRmlsdGVyRm9jdXMoZTogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRhcmdldC5zZWxlY3QoKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyB0aGUgU2VsZWN0IGJ5IGEgZ2l2ZW4gZmlsdGVyIGtleXdvcmRcbiAgICogQHBhcmFtIGZpbHRlciBLZXl3b3JkIHRvIGZpbHRlciBieVxuICAgKi9cbiAgcHJpdmF0ZSBfc2V0RmlsdGVyKGZpbHRlcjogc3RyaW5nID0gXCJcIik6IHZvaWQge1xuICAgIHRoaXMuX2FjdGl2ZUZpbHRlciA9IChmaWx0ZXIubGVuZ3RoID49IHRoaXMuX21pbkZpbHRlckxlbmd0aCkgPyBmaWx0ZXIgOiBcIlwiXG4gICAgdGhpcy5zZXRPcHRpb25zKHRoaXMuZ2V0SW5pdGlhbE9wdGlvbnMoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldHMgdGhlIGZpbHRlclxuICAgKi9cbiAgcHJpdmF0ZSBfY2xlYXJGaWx0ZXIoKTogdm9pZCB7XG4gICAgZGVsZXRlIHRoaXMuX2FjdGl2ZUZpbHRlclxuICAgIHRoaXMuc2V0T3B0aW9ucyh0aGlzLmdldEluaXRpYWxPcHRpb25zKCkpXG4gIH1cblxuICAvKipcbiAgICogU2V0IG5ldyBjb250ZW50IGFuZCByZWxvYWQgdGhlIFNlbGVjdFxuICAgKiBAcGFyYW0gZWxlbWVudHMgQXJyYXkgb2YgbmV3IG9wdGlvbiAob3Igb3B0Z3JvdXApIGVsZW1lbnRzIHRvIGRpc3BsYXlcbiAgICovXG4gIHByaXZhdGUgc2V0T3B0aW9ucyhvcHRpb25zOiBFbGVtZW50W10pOiB2b2lkIHtcbiAgICB0aGlzLl9lbXB0eU5vZGUodGhpcy5lbGVtZW50KVxuXG4gICAgb3B0aW9ucy5mb3JFYWNoKChvcHRpb24pID0+IHtcbiAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZChvcHRpb24pXG4gICAgfSlcblxuICAgIC8vIFByZXNlcnZlIHNlbGVjdGVkIHZhbHVlIGlmIHRoZSBzZWxlY3RlZFxuICAgIHRoaXMuZWxlbWVudC52YWx1ZSA9IHRoaXMuX2xhc3RTZWxlY3RlZE9wdGlvbiEudmFsdWVcblxuICAgIHRoaXMucmVsb2FkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgY2hpbGRyZW4gb2YgYSBnaXZlbiBub2RlXG4gICAqIEBwYXJhbSBub2RlIE5vZGVcbiAgICovXG4gIHByaXZhdGUgX2VtcHR5Tm9kZShub2RlOiBOb2RlKTogdm9pZCB7XG4gICAgd2hpbGUgKG5vZGUuZmlyc3RDaGlsZCkge1xuICAgICAgbm9kZS5yZW1vdmVDaGlsZChub2RlLmZpcnN0Q2hpbGQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBhbiBvcHRpb24gaXMgYSBwbGFjZWhvbGRlciBvcHRpb25cbiAgICovXG4gIHByaXZhdGUgX2lzUGxhY2Vob2xkZXIob3B0aW9uOiBIVE1MT3B0aW9uRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBvcHRpb24uaGFzQXR0cmlidXRlKFwiZGlzYWJsZWRcIikgJiYgb3B0aW9uLmhhc0F0dHJpYnV0ZShcInNlbGVjdGVkXCIpXG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHBsYWNlaG9sZGVyIHZhbHVlXG4gICAqIEBwYXJhbSB0ZXh0IENvbnRlbnQgb2YgdGhlIHBsYWNlaG9sZGVyXG4gICAqL1xuICBwcm90ZWN0ZWQgX3NldFBsYWNlaG9sZGVyKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQgJiYgdGV4dCkge1xuICAgICAgaWYgKHRoaXMuX2lzRmlsdGVyYWJsZSgpKSB7XG4gICAgICAgICh0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQgYXMgRG9tRWxlbWVudDxIVE1MSW5wdXRFbGVtZW50PikuZWxlbWVudC52YWx1ZSA9IHRleHRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5zZXRIdG1sKHRleHQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlxuICAgKiBJZiBtdWx0aXBsZSBzZWxlY3Rpb24gaXMgZW5hYmxlZCB0aGlzIHByb3BlcnR5IHJldHVybnMgYW4gYXJyYXkgb2YgdmFsdWVzLlxuICAgKi9cbiAgZ2V0IHZhbHVlKCkge1xuICAgIGlmICh0aGlzLl9tdWx0aXNlbGVjdGlvbikge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldFNlbGVjdGVkT3B0aW9ucygpLm1hcCgoeCkgPT4geC52YWx1ZSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5lbGVtZW50LnZhbHVlID09PSBcIlwiKSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmVsZW1lbnQudmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGVzIG9yIGRpc2FibGVzIHRoZSBzZWxlY3QgY29tcG9uZW50IGRlcGVuZGluZyBvbiB0aGVcbiAgICogJ3ZhbHVlJyBwYXJhbWV0ZXIuXG4gICAqIEBwYXJhbSB7dmFsdWV9IElmIHRydWUgZGlzYWJsZXMgdGhlIGNvbnRyb2w7IGZhbHNlIGVuYWJsZXMgaXQuXG4gICAqL1xuICBzZXQgZGlzYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuZGlzYWJsZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW5hYmxlKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVsb2FkcyB0aGUgZHJvcGRvd24ncyBvcHRpb24gZGF0YSBkZWZpbml0aW9ucyBmcm9tIHRoZSBET00gYW5kIHVwZGF0ZXNcbiAgICogdGhlIGdlbmVyYXRlZCBkcm9wZG93biBkaXNwbGF5IGl0ZW1zLlxuICAgKi9cbiAgcHVibGljIHJlbG9hZCgpIHtcbiAgICAvLyBSZW1vdmUgYWxsIGV4aXN0aW5nIGNoaWxkIGVsZW1lbnRzXG4gICAgdGhpcy5fZW1wdHlOb2RlKHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5lbGVtZW50KVxuXG4gICAgaWYgKHRoaXMuX2FjdGl2ZUZpbHRlciA9PT0gdW5kZWZpbmVkKSB7IC8vIElmIHRoZSB1c2VyIGlzIGZpbHRlcmluZywgbGV0IHRoZSBwbGFjZWhvbGRlciBcImlucHV0XCIgYWxpdmVcbiAgICAgIHRoaXMuX3NldHVwUGxhY2Vob2xkZXIoKVxuICAgIH1cblxuICAgIHRoaXMuX2NyZWF0ZU9wdGlvbnModGhpcy5lbGVtZW50KVxuXG4gICAgdGhpcy5fdXBkYXRlU2l6ZSgpXG4gICAgdGhpcy5fdXBkYXRlTWVzc2FnZSgpXG5cbiAgICBpZiAoIXRoaXMuX2lzRmlsdGVyYWJsZSgpKSB7XG4gICAgICB0aGlzLl91cGRhdGVQbGFjZWhvbGRlcighIXRoaXMudmFsdWUpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHNlbGVjdCBjb250cm9sIHRvIHRoZSBlbmFibGVkIHN0YXRlLlxuICAgKi9cbiAgcHVibGljIGVuYWJsZSgpIHtcbiAgICB0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKFwiZGlzYWJsZWRcIilcbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5yZW1vdmVDbGFzcyhDTEFTU19ESVNBQkxFRClcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fd2luZG93Q2xpY2tIYW5kbGVyKVxuXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fY2xpY2tIYW5kbGVyKVxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgdGhpcy5fa2V5ZG93bkhhbmRsZXIpXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgdGhpcy5fZm9jdXNIYW5kbGVyKVxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fYmx1ckhhbmRsZXIpXG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgc2VsZWN0IGNvbnRyb2wgdG8gdGhlIGRpc2FibGVkIHN0YXRlLlxuICAgKi9cbiAgcHVibGljIGRpc2FibGUoKSB7XG4gICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZShcImRpc2FibGVkXCIsIFwiXCIpXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYWRkQ2xhc3MoQ0xBU1NfRElTQUJMRUQpXG5cbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX3dpbmRvd0NsaWNrSGFuZGxlcilcblxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX2NsaWNrSGFuZGxlcilcbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIHRoaXMuX2tleWRvd25IYW5kbGVyKVxuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIHRoaXMuX2ZvY3VzSGFuZGxlcilcbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIHRoaXMuX2JsdXJIYW5kbGVyKVxuXG4gICAgdGhpcy5jbG9zZSgpXG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlcyB0aGUgb3Blbi9jbG9zZWQgc3RhdGUgb2YgdGhlIHNlbGVjdCBkcm9wZG93bi5cbiAgICovXG4gIHB1YmxpYyB0b2dnbGUoKSB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2UoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wZW4oKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGlmIHRoZSBzZWxlY3QgZHJvcGRvd24gaXMgb3BlbiBvciBjbG9zZWQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgb3Blbjsgb3RoZXJ3aXNlIGZhbHNlLlxuICAgKi9cbiAgcHVibGljIGlzT3BlbigpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JhcHBlckVsZW1lbnQuaGFzQ2xhc3MoQ0xBU1NfT1BFTilcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVucyB0aGUgc2VsZWN0IGRyb3Bkb3duLlxuICAgKi9cbiAgcHVibGljIG9wZW4oKSB7XG4gICAgaWYgKCF0aGlzLmlzT3BlbigpKSB7XG4gICAgICB0aGlzLl9vcGVuQnlGb2N1cyA9IGZhbHNlXG5cbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnJlbW92ZUNsYXNzKENMQVNTX0NMT1NFRClcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmFkZENsYXNzKENMQVNTX09QRU4pXG5cbiAgICAgIHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLl9oYW5kbGVEcm9wZG93bkNsaWNrKVxuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRhcFwiLCB0aGlzLl9oYW5kbGVEcm9wZG93bkNsaWNrKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgdGhlIHNlbGVjdCBkcm9wZG93bi5cbiAgICovXG4gIHB1YmxpYyBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy5pc09wZW4oKSkge1xuICAgICAgdGhpcy5fb3BlbkJ5Rm9jdXMgPSBmYWxzZVxuXG4gICAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5yZW1vdmVDbGFzcyhDTEFTU19PUEVOKVxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYWRkQ2xhc3MoQ0xBU1NfQ0xPU0VEKVxuXG4gICAgICAvLyBJZiB0aGUgU2VsZWN0IGlzIGZpbHRlcmFibGUgYW5kIHRoZXJlZm9yZSBoYXMgYW4gaW5wdXQgZmllbGQsXG4gICAgICAvLyByZXNldCB0aGUgdmFsdWUgb2YgaXQgdG8gdGhlIGNob3NlbiBvcHRpb25cbiAgICAgIGlmICh0aGlzLl9pc0ZpbHRlcmFibGUoKSkge1xuICAgICAgICAvLyBVbmZvY3VzIGlucHV0IGZpZWxkXG4gICAgICAgICh0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQuZWxlbWVudCBhcyBIVE1MSW5wdXRFbGVtZW50KS5ibHVyKClcblxuICAgICAgICBpZiAoIXRoaXMuX2FjdGl2ZUZpbHRlciB8fCB0aGlzLl9hY3RpdmVGaWx0ZXIgPT09IHRoaXMuX2xhc3RTZWxlY3RlZE9wdGlvbiEuaW5uZXJIVE1MKSB7XG4gICAgICAgICAgdGhpcy5fc2V0UGxhY2Vob2xkZXIodGhpcy5fbGFzdFNlbGVjdGVkT3B0aW9uIS5pbm5lckhUTUwpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG4gICAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidGFwXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG5cbiAgICAgIGxldCBmb2N1c2VkSXRlbSA9IHRoaXMuX3dyYXBwZXJFbGVtZW50LmZpbmQoYC4ke0NMQVNTX0lURU1fRk9DVVNFRH1gKVxuXG4gICAgICBpZiAoZm9jdXNlZEl0ZW0pIHtcbiAgICAgICAgZm9jdXNlZEl0ZW0ucmVtb3ZlQ2xhc3MoQ0xBU1NfSVRFTV9GT0NVU0VEKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgd2hlbiB0aGUgZWxlbWVudCBoYXMgdGhlIGZpbHRlciBtb2RpZmllciBjbGFzc1xuICAgKi9cbiAgcHJpdmF0ZSBfaXNGaWx0ZXJhYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl93cmFwcGVyRWxlbWVudC5oYXNDbGFzcyhDTEFTU19GSUxURVJBQkxFKVxuICB9XG5cbiAgLyoqXG4gICAqIERlc3Ryb3lzIHRoZSBjb21wb25lbnQgYW5kIGNsZWFycyBhbGwgcmVmZXJlbmNlcy5cbiAgICovXG4gIHB1YmxpYyBkZXN0cm95KCkge1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fd2luZG93Q2xpY2tIYW5kbGVyKVxuXG4gICAgaWYgKHRoaXMuX2Ryb3Bkb3duRWxlbWVudCkge1xuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG4gICAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidGFwXCIsIHRoaXMuX2hhbmRsZURyb3Bkb3duQ2xpY2spXG5cbiAgICAgIHJlbW92ZSh0aGlzLl9kcm9wZG93bkVsZW1lbnQuZWxlbWVudCk7XG4gICAgICAodGhpcyBhcyBhbnkpLl9kcm9wZG93bkVsZW1lbnQgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcGxhY2Vob2xkZXJFbGVtZW50KSB7XG4gICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgdGhpcy5fZmlsdGVyS2V5ZG93bkhhbmRsZXIpXG4gICAgICB0aGlzLl9wbGFjZWhvbGRlckVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImtleXVwXCIsIHRoaXMuX2ZpbHRlcktleXVwSGFuZGxlcilcbiAgICAgIHRoaXMuX3BsYWNlaG9sZGVyRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgdGhpcy5fZmlsdGVyRm9jdXNIYW5kbGVyKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl93cmFwcGVyRWxlbWVudCkge1xuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgdGhpcy5fY2xpY2tIYW5kbGVyKVxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCB0aGlzLl9rZXlkb3duSGFuZGxlcilcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIHRoaXMuX2ZvY3VzSGFuZGxlcilcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fYmx1ckhhbmRsZXIpO1xuXG4gICAgICAodGhpcyBhcyBhbnkpLl93cmFwcGVyRWxlbWVudCA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmICh0aGlzLl9zZWxlY3RCdXR0b25FbGVtZW50KSB7XG4gICAgICByZW1vdmUodGhpcy5fc2VsZWN0QnV0dG9uRWxlbWVudC5lbGVtZW50KTtcbiAgICAgICh0aGlzIGFzIGFueSkuX3NlbGVjdEJ1dHRvbkVsZW1lbnQgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICB0aGlzLnJlbW92ZUNsYXNzKENMQVNTX0NMT1NFRClcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5pdCgpIHtcbiAgc2VhcmNoQW5kSW5pdGlhbGl6ZTxIVE1MU2VsZWN0RWxlbWVudD4oXCJzZWxlY3RcIiwgKGUpID0+IHtcbiAgICBuZXcgU2VsZWN0KGUpXG4gIH0pXG59XG5cbmV4cG9ydCBkZWZhdWx0IFNlbGVjdFxuIl0sInNvdXJjZVJvb3QiOiIuLi8uLi8uLi8uLi8uLiJ9