kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
522 lines (444 loc) • 58.1 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _reactLifecyclesCompat = require("react-lifecycles-compat");
var _propTypes = _interopRequireDefault(require("prop-types"));
var _fuzzy = _interopRequireDefault(require("fuzzy"));
var _classnames = _interopRequireDefault(require("classnames"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _window = require("global/window");
var _accessor = _interopRequireDefault(require("./accessor"));
var _keyevent = _interopRequireDefault(require("./keyevent"));
var _dropdownList = _interopRequireWildcard(require("./dropdown-list"));
var _icons = require("../icons");
function _templateObject4() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n position: absolute;\n right: 15px;\n top: 14px;\n color: ", ";\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n ", " :hover {\n cursor: pointer;\n background-color: ", ";\n }\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n padding: 8px;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n flex-direction: column;\n background-color: ", ";\n box-shadow: ", ";\n\n :focus {\n outline: 0;\n }\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
var DEFAULT_CLASS = 'typeahead';
/**
* Copied mostly from 'react-typeahead', an auto-completing text input
*
* Renders an text input that shows options nearby that you can use the
* keyboard or mouse to select.
*/
var TypeaheadWrapper = _styledComponents["default"].div(_templateObject(), function (props) {
return props.theme.dropdownListBgd;
}, function (props) {
return props.theme.dropdownListShadow;
});
var InputBox = _styledComponents["default"].div(_templateObject2());
var TypeaheadInput = _styledComponents["default"].input(_templateObject3(), function (props) {
return props.theme.secondaryInput;
}, function (props) {
return props.theme.secondaryInputBgd;
});
var InputIcon = _styledComponents["default"].div(_templateObject4(), function (props) {
return props.theme.inputPlaceholderColor;
});
function generateSearchFunction(props) {
var searchOptions = props.searchOptions,
filterOption = props.filterOption;
if (typeof searchOptions === 'function') {
if (filterOption !== null) {
_window.console.warn('searchOptions prop is being used, filterOption prop will be ignored');
}
return searchOptions;
} else if (typeof filterOption === 'function') {
// use custom filter option
return function (value, options) {
return options.filter(function (o) {
return filterOption(value, o);
});
};
}
var mapper = typeof filterOption === 'string' ? _accessor["default"].generateAccessor(filterOption) : _accessor["default"].IDENTITY_FN;
return function (value, options) {
return _fuzzy["default"].filter(value, options, {
extract: mapper
}).map(function (res) {
return options[res.index];
});
};
}
function getOptionsForValue(value, props, state) {
var options = props.options,
showOptionsWhenEmpty = props.showOptionsWhenEmpty;
if (!props.searchable) {
// directly pass through options if can not be searched
return options;
}
if (shouldSkipSearch(value, state, showOptionsWhenEmpty)) {
return options;
}
var searchOptions = generateSearchFunction(props);
return searchOptions(value, options);
}
function shouldSkipSearch(input, state, showOptionsWhenEmpty) {
var emptyValue = !input || input.trim().length === 0; // this.state must be checked because it may not be defined yet if this function
// is called from within getInitialState
var isFocused = state && state.isFocused;
return !(showOptionsWhenEmpty && isFocused) && emptyValue;
}
var Typeahead =
/*#__PURE__*/
function (_Component) {
(0, _inherits2["default"])(Typeahead, _Component);
(0, _createClass2["default"])(Typeahead, null, [{
key: "getDerivedStateFromProps",
value: function getDerivedStateFromProps(props, state) {
// invoked after a component is instantiated as well as before it is re-rendered
var searchResults = getOptionsForValue(state.entryValue, props, state);
return {
searchResults: searchResults
};
}
}]);
function Typeahead(props) {
var _this;
(0, _classCallCheck2["default"])(this, Typeahead);
_this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Typeahead).call(this, props));
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "root", (0, _react.createRef)());
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "entry", (0, _react.createRef)());
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "focus", function () {
if (_this.entry.current) {
_this.entry.current.focus();
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_hasCustomValue", function () {
return _this.props.allowCustomValues > 0 && _this.state.entryValue.length >= _this.props.allowCustomValues && _this.state.searchResults.indexOf(_this.state.entryValue) < 0;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_getCustomValue", function () {
return _this._hasCustomValue() ? _this.state.entryValue : null;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onOptionSelected", function (option, event) {
if (_this.props.searchable) {
// reset entry input
_this.setState({
searchResults: getOptionsForValue('', _this.props, _this.state),
selection: '',
entryValue: ''
});
}
return _this.props.onOptionSelected(option, event);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onTextEntryUpdated", function () {
if (_this.props.searchable) {
var value = _this.entry.current.value;
_this.setState({
searchResults: getOptionsForValue(value, _this.props, _this.state),
selection: '',
entryValue: value
});
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onEnter", function (event) {
var selection = _this.getSelection();
if (!selection) {
return _this.props.onKeyDown(event);
}
return _this._onOptionSelected(selection, event);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onEscape", function () {
_this.setState({
selectionIndex: null
});
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onTab", function (event) {
var selection = _this.getSelection();
var option = selection ? selection : _this.state.searchResults.length > 0 ? _this.state.searchResults[0] : null;
if (option === null && _this._hasCustomValue()) {
option = _this._getCustomValue();
}
if (option !== null) {
return _this._onOptionSelected(option, event);
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "eventMap", function (event) {
var events = {};
events[_keyevent["default"].DOM_VK_UP] = _this.navUp;
events[_keyevent["default"].DOM_VK_DOWN] = _this.navDown;
events[_keyevent["default"].DOM_VK_RETURN] = events[_keyevent["default"].DOM_VK_ENTER] = _this._onEnter;
events[_keyevent["default"].DOM_VK_ESCAPE] = _this._onEscape;
events[_keyevent["default"].DOM_VK_TAB] = _this._onTab;
return events;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_nav", function (delta) {
if (!_this._hasHint()) {
return;
}
var newIndex = _this.state.selectionIndex === null ? delta === 1 ? 0 : delta : _this.state.selectionIndex + delta;
var length = _this.props.maxVisible ? _this.state.searchResults.slice(0, _this.props.maxVisible).length : _this.state.searchResults.length;
if (_this._hasCustomValue()) {
length += 1;
}
if (newIndex < 0) {
newIndex += length;
} else if (newIndex >= length) {
newIndex -= length;
}
_this.setState({
selectionIndex: newIndex
});
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "navDown", function () {
_this._nav(1);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "navUp", function () {
_this._nav(-1);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onChange", function (event) {
if (_this.props.onChange) {
_this.props.onChange(event);
}
_this._onTextEntryUpdated();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onKeyDown", function (event) {
// If there are no visible elements, don't perform selector navigation.
// Just pass this up to the upstream onKeydown handler.
// Also skip if the user is pressing the shift key, since none of our handlers are looking for shift
if (!_this._hasHint() || event.shiftKey) {
return _this.props.onKeyDown(event);
}
var handler = _this.eventMap()[event.keyCode];
if (handler) {
handler(event);
} else {
return _this.props.onKeyDown(event);
} // Don't propagate the keystroke back to the DOM/browser
event.preventDefault();
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onFocus", function (event) {
_this.setState({
isFocused: true
});
if (_this.props.onFocus) {
return _this.props.onFocus(event);
}
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onBlur", function (event) {
_this.setState({
isFocused: false
});
if (_this.props.onBlur) {
return _this.props.onBlur(event);
}
});
_this.state = {
searchResults: [],
// This should be called something else, 'entryValue'
entryValue: _this.props.value || _this.props.initialValue,
// A valid typeahead value
selection: _this.props.value,
// Index of the selection
selectionIndex: null,
// Keep track of the focus state of the input element, to determine
// whether to show options when empty (if showOptionsWhenEmpty is true)
isFocused: false
};
return _this;
}
(0, _createClass2["default"])(Typeahead, [{
key: "componentDidMount",
value: function componentDidMount() {
// call focus on entry or div to trigger key events listener
if (this.entry.current) {
this.entry.current.focus();
} else {
this.root.current.focus();
}
}
}, {
key: "_renderIncrementalSearchResults",
value: function _renderIncrementalSearchResults() {
return _react["default"].createElement(this.props.customListComponent, {
fixedOptions: this.props.fixedOptions,
options: this.props.maxVisible ? this.state.searchResults.slice(0, this.props.maxVisible) : this.state.searchResults,
areResultsTruncated: this.props.maxVisible && this.state.searchResults.length > this.props.maxVisible,
resultsTruncatedMessage: this.props.resultsTruncatedMessage,
onOptionSelected: this._onOptionSelected,
allowCustomValues: this.props.allowCustomValues,
customValue: this._getCustomValue(),
customClasses: this.props.customClasses,
customListItemComponent: this.props.customListItemComponent,
customListHeaderComponent: this.props.customListHeaderComponent,
selectionIndex: this.state.selectionIndex,
defaultClassNames: this.props.defaultClassNames,
displayOption: this.props.displayOption,
selectedItems: this.props.selectedItems
});
}
}, {
key: "getSelection",
value: function getSelection() {
var index = this.state.selectionIndex;
if (this._hasCustomValue()) {
if (index === 0) {
return this.state.entryValue;
}
index--;
}
if (this._hasFixedOptions()) {
return index < this.props.fixedOptions.length ? this.props.fixedOptions[index] : this.state.searchResults[index - this.props.fixedOptions.length];
}
return this.state.searchResults[index];
}
}, {
key: "_renderHiddenInput",
value: function _renderHiddenInput() {
if (!this.props.name) {
return null;
}
return _react["default"].createElement("input", {
type: "hidden",
name: this.props.name,
value: this.state.selection
});
}
}, {
key: "_hasHint",
value: function _hasHint() {
return this.state.searchResults.length > 0 || this._hasCustomValue();
}
}, {
key: "_hasFixedOptions",
value: function _hasFixedOptions() {
return Array.isArray(this.props.fixedOptions) && this.props.fixedOptions.length;
}
}, {
key: "render",
value: function render() {
var inputClasses = {};
inputClasses[this.props.customClasses.input] = Boolean(this.props.customClasses.input);
var inputClassList = (0, _classnames["default"])(inputClasses);
var classes = (0, _defineProperty2["default"])({}, DEFAULT_CLASS, this.props.defaultClassNames);
classes[this.props.className] = Boolean(this.props.className);
var classList = (0, _classnames["default"])(classes);
return _react["default"].createElement(TypeaheadWrapper, {
className: classList,
ref: this.root,
tabIndex: "0",
onKeyDown: this._onKeyDown,
onKeyPress: this.props.onKeyPress,
onKeyUp: this.props.onKeyUp,
onFocus: this._onFocus
}, this._renderHiddenInput(), this.props.searchable ? _react["default"].createElement(InputBox, null, _react["default"].createElement(TypeaheadInput, (0, _extends2["default"])({
ref: this.entry,
type: "text",
disabled: this.props.disabled
}, this.props.inputProps, {
placeholder: this.props.placeholder,
className: inputClassList,
value: this.state.entryValue,
onChange: this._onChange,
onBlur: this._onBlur
})), _react["default"].createElement(InputIcon, null, _react["default"].createElement(_icons.Search, {
height: "18px"
}))) : null, this._renderIncrementalSearchResults());
}
}]);
return Typeahead;
}(_react.Component);
(0, _defineProperty2["default"])(Typeahead, "propTypes", {
name: _propTypes["default"].string,
customClasses: _propTypes["default"].object,
maxVisible: _propTypes["default"].number,
resultsTruncatedMessage: _propTypes["default"].string,
options: _propTypes["default"].arrayOf(_propTypes["default"].any),
fixedOptions: _propTypes["default"].arrayOf(_propTypes["default"].any),
allowCustomValues: _propTypes["default"].number,
initialValue: _propTypes["default"].string,
value: _propTypes["default"].string,
placeholder: _propTypes["default"].string,
disabled: _propTypes["default"].bool,
textarea: _propTypes["default"].bool,
inputProps: _propTypes["default"].object,
onOptionSelected: _propTypes["default"].func,
onChange: _propTypes["default"].func,
onKeyDown: _propTypes["default"].func,
onKeyPress: _propTypes["default"].func,
onKeyUp: _propTypes["default"].func,
onFocus: _propTypes["default"].func,
onBlur: _propTypes["default"].func,
filterOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
searchOptions: _propTypes["default"].func,
displayOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
inputDisplayOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
formInputOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
defaultClassNames: _propTypes["default"].bool,
customListComponent: _propTypes["default"].oneOfType([_propTypes["default"].element, _propTypes["default"].func]),
customListItemComponent: _propTypes["default"].oneOfType([_propTypes["default"].element, _propTypes["default"].func]),
customListHeaderComponent: _propTypes["default"].oneOfType([_propTypes["default"].element, _propTypes["default"].func]),
showOptionsWhenEmpty: _propTypes["default"].bool,
searchable: _propTypes["default"].bool
});
(0, _defineProperty2["default"])(Typeahead, "defaultProps", {
options: [],
customClasses: {},
allowCustomValues: 0,
initialValue: '',
value: '',
placeholder: '',
disabled: false,
textarea: false,
inputProps: {},
onOptionSelected: function onOptionSelected(option) {},
onChange: function onChange(event) {},
onKeyDown: function onKeyDown(event) {},
onKeyPress: function onKeyPress(event) {},
onKeyUp: function onKeyUp(event) {},
onFocus: function onFocus(event) {},
onBlur: function onBlur(event) {},
filterOption: null,
searchOptions: null,
inputDisplayOption: null,
defaultClassNames: true,
customListComponent: _dropdownList["default"],
customListItemComponent: _dropdownList.ListItem,
customListHeaderComponent: null,
showOptionsWhenEmpty: true,
searchable: true,
resultsTruncatedMessage: null
});
(0, _reactLifecyclesCompat.polyfill)(Typeahead);
var _default = Typeahead;
exports["default"] = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2NvbW1vbi9pdGVtLXNlbGVjdG9yL3R5cGVhaGVhZC5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0NMQVNTIiwiVHlwZWFoZWFkV3JhcHBlciIsInN0eWxlZCIsImRpdiIsInByb3BzIiwidGhlbWUiLCJkcm9wZG93bkxpc3RCZ2QiLCJkcm9wZG93bkxpc3RTaGFkb3ciLCJJbnB1dEJveCIsIlR5cGVhaGVhZElucHV0IiwiaW5wdXQiLCJzZWNvbmRhcnlJbnB1dCIsInNlY29uZGFyeUlucHV0QmdkIiwiSW5wdXRJY29uIiwiaW5wdXRQbGFjZWhvbGRlckNvbG9yIiwiZ2VuZXJhdGVTZWFyY2hGdW5jdGlvbiIsInNlYXJjaE9wdGlvbnMiLCJmaWx0ZXJPcHRpb24iLCJDb25zb2xlIiwid2FybiIsInZhbHVlIiwib3B0aW9ucyIsImZpbHRlciIsIm8iLCJtYXBwZXIiLCJBY2Nlc3NvciIsImdlbmVyYXRlQWNjZXNzb3IiLCJJREVOVElUWV9GTiIsImZ1enp5IiwiZXh0cmFjdCIsIm1hcCIsInJlcyIsImluZGV4IiwiZ2V0T3B0aW9uc0ZvclZhbHVlIiwic3RhdGUiLCJzaG93T3B0aW9uc1doZW5FbXB0eSIsInNlYXJjaGFibGUiLCJzaG91bGRTa2lwU2VhcmNoIiwiZW1wdHlWYWx1ZSIsInRyaW0iLCJsZW5ndGgiLCJpc0ZvY3VzZWQiLCJUeXBlYWhlYWQiLCJzZWFyY2hSZXN1bHRzIiwiZW50cnlWYWx1ZSIsImVudHJ5IiwiY3VycmVudCIsImZvY3VzIiwiYWxsb3dDdXN0b21WYWx1ZXMiLCJpbmRleE9mIiwiX2hhc0N1c3RvbVZhbHVlIiwib3B0aW9uIiwiZXZlbnQiLCJzZXRTdGF0ZSIsInNlbGVjdGlvbiIsIm9uT3B0aW9uU2VsZWN0ZWQiLCJnZXRTZWxlY3Rpb24iLCJvbktleURvd24iLCJfb25PcHRpb25TZWxlY3RlZCIsInNlbGVjdGlvbkluZGV4IiwiX2dldEN1c3RvbVZhbHVlIiwiZXZlbnRzIiwiS2V5RXZlbnQiLCJET01fVktfVVAiLCJuYXZVcCIsIkRPTV9WS19ET1dOIiwibmF2RG93biIsIkRPTV9WS19SRVRVUk4iLCJET01fVktfRU5URVIiLCJfb25FbnRlciIsIkRPTV9WS19FU0NBUEUiLCJfb25Fc2NhcGUiLCJET01fVktfVEFCIiwiX29uVGFiIiwiZGVsdGEiLCJfaGFzSGludCIsIm5ld0luZGV4IiwibWF4VmlzaWJsZSIsInNsaWNlIiwiX25hdiIsIm9uQ2hhbmdlIiwiX29uVGV4dEVudHJ5VXBkYXRlZCIsInNoaWZ0S2V5IiwiaGFuZGxlciIsImV2ZW50TWFwIiwia2V5Q29kZSIsInByZXZlbnREZWZhdWx0Iiwib25Gb2N1cyIsIm9uQmx1ciIsImluaXRpYWxWYWx1ZSIsInJvb3QiLCJmaXhlZE9wdGlvbnMiLCJyZXN1bHRzVHJ1bmNhdGVkTWVzc2FnZSIsImN1c3RvbUNsYXNzZXMiLCJjdXN0b21MaXN0SXRlbUNvbXBvbmVudCIsImN1c3RvbUxpc3RIZWFkZXJDb21wb25lbnQiLCJkZWZhdWx0Q2xhc3NOYW1lcyIsImRpc3BsYXlPcHRpb24iLCJzZWxlY3RlZEl0ZW1zIiwiX2hhc0ZpeGVkT3B0aW9ucyIsIm5hbWUiLCJBcnJheSIsImlzQXJyYXkiLCJpbnB1dENsYXNzZXMiLCJCb29sZWFuIiwiaW5wdXRDbGFzc0xpc3QiLCJjbGFzc2VzIiwiY2xhc3NOYW1lIiwiY2xhc3NMaXN0IiwiX29uS2V5RG93biIsIm9uS2V5UHJlc3MiLCJvbktleVVwIiwiX29uRm9jdXMiLCJfcmVuZGVySGlkZGVuSW5wdXQiLCJkaXNhYmxlZCIsImlucHV0UHJvcHMiLCJwbGFjZWhvbGRlciIsIl9vbkNoYW5nZSIsIl9vbkJsdXIiLCJfcmVuZGVySW5jcmVtZW50YWxTZWFyY2hSZXN1bHRzIiwiQ29tcG9uZW50IiwiUHJvcFR5cGVzIiwic3RyaW5nIiwib2JqZWN0IiwibnVtYmVyIiwiYXJyYXlPZiIsImFueSIsImJvb2wiLCJ0ZXh0YXJlYSIsImZ1bmMiLCJvbmVPZlR5cGUiLCJpbnB1dERpc3BsYXlPcHRpb24iLCJmb3JtSW5wdXRPcHRpb24iLCJjdXN0b21MaXN0Q29tcG9uZW50IiwiZWxlbWVudCIsIkRyb3Bkb3duTGlzdCIsIkxpc3RJdGVtIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsSUFBTUEsYUFBYSxHQUFHLFdBQXRCO0FBQ0E7Ozs7Ozs7QUFPQSxJQUFNQyxnQkFBZ0IsR0FBR0MsNkJBQU9DLEdBQVYsb0JBR0EsVUFBQUMsS0FBSztBQUFBLFNBQUlBLEtBQUssQ0FBQ0MsS0FBTixDQUFZQyxlQUFoQjtBQUFBLENBSEwsRUFJTixVQUFBRixLQUFLO0FBQUEsU0FBSUEsS0FBSyxDQUFDQyxLQUFOLENBQVlFLGtCQUFoQjtBQUFBLENBSkMsQ0FBdEI7O0FBV0EsSUFBTUMsUUFBUSxHQUFHTiw2QkFBT0MsR0FBVixvQkFBZDs7QUFJQSxJQUFNTSxjQUFjLEdBQUdQLDZCQUFPUSxLQUFWLHFCQUNoQixVQUFBTixLQUFLO0FBQUEsU0FBSUEsS0FBSyxDQUFDQyxLQUFOLENBQVlNLGNBQWhCO0FBQUEsQ0FEVyxFQUdJLFVBQUFQLEtBQUs7QUFBQSxTQUFJQSxLQUFLLENBQUNDLEtBQU4sQ0FBWU8saUJBQWhCO0FBQUEsQ0FIVCxDQUFwQjs7QUFPQSxJQUFNQyxTQUFTLEdBQUdYLDZCQUFPQyxHQUFWLHFCQUlKLFVBQUFDLEtBQUs7QUFBQSxTQUFJQSxLQUFLLENBQUNDLEtBQU4sQ0FBWVMscUJBQWhCO0FBQUEsQ0FKRCxDQUFmOztBQU9BLFNBQVNDLHNCQUFULENBQWdDWCxLQUFoQyxFQUF1QztBQUFBLE1BQzlCWSxhQUQ4QixHQUNDWixLQURELENBQzlCWSxhQUQ4QjtBQUFBLE1BQ2ZDLFlBRGUsR0FDQ2IsS0FERCxDQUNmYSxZQURlOztBQUVyQyxNQUFJLE9BQU9ELGFB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LEVBQUFBLFdBQVcsRUFBRSxFQU5PO0FBT3BCRixFQUFBQSxRQUFRLEVBQUUsS0FQVTtBQVFwQmMsRUFBQUEsUUFBUSxFQUFFLEtBUlU7QUFTcEJiLEVBQUFBLFVBQVUsRUFBRSxFQVRRO0FBVXBCNUQsRUFBQUEsZ0JBVm9CLDRCQVVISixNQVZHLEVBVUssQ0FBRSxDQVZQO0FBV3BCNkIsRUFBQUEsUUFYb0Isb0JBV1g1QixLQVhXLEVBV0osQ0FBRSxDQVhFO0FBWXBCSyxFQUFBQSxTQVpvQixxQkFZVkwsS0FaVSxFQVlILENBQUUsQ0FaQztBQWFwQjBELEVBQUFBLFVBYm9CLHNCQWFUMUQsS0FiUyxFQWFGLENBQUUsQ0FiQTtBQWNwQjJELEVBQUFBLE9BZG9CLG1CQWNaM0QsS0FkWSxFQWNMLENBQUUsQ0FkRztBQWVwQm1DLEVBQUFBLE9BZm9CLG1CQWVabkMsS0FmWSxFQWVMLENBQUUsQ0FmRztBQWdCcEJvQyxFQUFBQSxNQWhCb0Isa0JBZ0JicEMsS0FoQmEsRUFnQk4sQ0FBRSxDQWhCSTtBQWlCcEJuQyxFQUFBQSxZQUFZLEVBQUUsSUFqQk07QUFrQnBCRCxFQUFBQSxhQUFhLEVBQUUsSUFsQks7QUFtQnBCbUgsRUFBQUEsa0JBQWtCLEVBQUUsSUFuQkE7QUFvQnBCbkMsRUFBQUEsaUJBQWlCLEVBQUUsSUFwQkM7QUFxQnBCcUMsRUFBQUEsbUJBQW1CLEVBQUVFLHdCQXJCRDtBQXNCcEJ6QyxFQUFBQSx1QkFBdUIsRUFBRTBDLHNCQXRCTDtBQXVCcEJ6QyxFQUFBQSx5QkFBeUIsRUFBRSxJQXZCUDtBQXdCcEI1RCxFQUFBQSxvQkFBb0IsRUFBRSxJQXhCRjtBQXlCcEJDLEVBQUFBLFVBQVUsRUFBRSxJQXpCUTtBQTBCcEJ3RCxFQUFBQSx1QkFBdUIsRUFBRTtBQTFCTCxDO0FBaVZ4QixxQ0FBU2xELFNBQVQ7ZUFFZUEsUyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMCBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBSZWFjdCwge0NvbXBvbmVudCwgY3JlYXRlUmVmfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQge3BvbHlmaWxsfSBmcm9tICdyZWFjdC1saWZlY3ljbGVzLWNvbXBhdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IGZ1enp5IGZyb20gJ2Z1enp5JztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IHN0eWxlZCBmcm9tICdzdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQge2NvbnNvbGUgYXMgQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5cbmltcG9ydCBBY2Nlc3NvciBmcm9tICcuL2FjY2Vzc29yJztcbmltcG9ydCBLZXlFdmVudCBmcm9tICcuL2tleWV2ZW50JztcbmltcG9ydCBEcm9wZG93bkxpc3QsIHtMaXN0SXRlbX0gZnJvbSAnLi9kcm9wZG93bi1saXN0JztcbmltcG9ydCB7U2VhcmNofSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9pY29ucyc7XG5cbmNvbnN0IERFRkFVTFRfQ0xBU1MgPSAndHlwZWFoZWFkJztcbi8qKlxuICogQ29waWVkIG1vc3RseSBmcm9tICdyZWFjdC10eXBlYWhlYWQnLCBhbiBhdXRvLWNvbXBsZXRpbmcgdGV4dCBpbnB1dFxuICpcbiAqIFJlbmRlcnMgYW4gdGV4dCBpbnB1dCB0aGF0IHNob3dzIG9wdGlvbnMgbmVhcmJ5IHRoYXQgeW91IGNhbiB1c2UgdGhlXG4gKiBrZXlib2FyZCBvciBtb3VzZSB0byBzZWxlY3QuXG4gKi9cblxuY29uc3QgVHlwZWFoZWFkV3JhcHBlciA9IHN0eWxlZC5kaXZgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGJhY2tncm91bmQtY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZHJvcGRvd25MaXN0QmdkfTtcbiAgYm94LXNoYWRvdzogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5kcm9wZG93bkxpc3RTaGFkb3d9O1xuXG4gIDpmb2N1cyB7XG4gICAgb3V0bGluZTogMDtcbiAgfVxuYDtcblxuY29uc3QgSW5wdXRCb3ggPSBzdHlsZWQuZGl2YFxuICBwYWRkaW5nOiA4cHg7XG5gO1xuXG5jb25zdCBUeXBlYWhlYWRJbnB1dCA9IHN0eWxlZC5pbnB1dGBcbiAgJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5zZWNvbmRhcnlJbnB1dH0gOmhvdmVyIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5zZWNvbmRhcnlJbnB1dEJnZH07XG4gIH1cbmA7XG5cbmNvbnN0IElucHV0SWNvbiA9IHN0eWxlZC5kaXZgXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgcmlnaHQ6IDE1cHg7XG4gIHRvcDogMTRweDtcbiAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuaW5wdXRQbGFjZWhvbGRlckNvbG9yfTtcbmA7XG5cbmZ1bmN0aW9uIGdlbmVyYXRlU2VhcmNoRnVuY3Rpb24ocHJvcHMpIHtcbiAgY29uc3Qge3NlYXJjaE9wdGlvbnMsIGZpbHRlck9wdGlvbn0gPSBwcm9wcztcbiAgaWYgKHR5cGVvZiBzZWFyY2hPcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgaWYgKGZpbHRlck9wdGlvbiAhPT0gbnVsbCkge1xuICAgICAgQ29uc29sZS53YXJuKCdzZWFyY2hPcHRpb25zIHByb3AgaXMgYmVpbmcgdXNlZCwgZmlsdGVyT3B0aW9uIHByb3Agd2lsbCBiZSBpZ25vcmVkJyk7XG4gICAgfVxuICAgIHJldHVybiBzZWFyY2hPcHRpb25zO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBmaWx0ZXJPcHRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyB1c2UgY3VzdG9tIGZpbHRlciBvcHRpb25cbiAgICByZXR1cm4gKHZhbHVlLCBvcHRpb25zKSA9PiBvcHRpb25zLmZpbHRlcihvID0+IGZpbHRlck9wdGlvbih2YWx1ZSwgbykpO1xuICB9XG5cbiAgY29uc3QgbWFwcGVyID1cbiAgICB0eXBlb2YgZmlsdGVyT3B0aW9uID09PSAnc3RyaW5nJ1xuICAgICAgPyBBY2Nlc3Nvci5nZW5lcmF0ZUFjY2Vzc29yKGZpbHRlck9wdGlvbilcbiAgICAgIDogQWNjZXNzb3IuSURFTlRJVFlfRk47XG5cbiAgcmV0dXJuICh2YWx1ZSwgb3B0aW9ucykgPT5cbiAgICBmdXp6eS5maWx0ZXIodmFsdWUsIG9wdGlvbnMsIHtleHRyYWN0OiBtYXBwZXJ9KS5tYXAocmVzID0+IG9wdGlvbnNbcmVzLmluZGV4XSk7XG59XG5cbmZ1bmN0aW9uIGdldE9wdGlvbnNGb3JWYWx1ZSh2YWx1ZSwgcHJvcHMsIHN0YXRlKSB7XG4gIGNvbnN0IHtvcHRpb25zLCBzaG93T3B0aW9uc1doZW5FbXB0eX0gPSBwcm9wcztcblxuICBpZiAoIXByb3BzLnNlYXJjaGFibGUpIHtcbiAgICAvLyBkaXJlY3RseSBwYXNzIHRocm91Z2ggb3B0aW9ucyBpZiBjYW4gbm90IGJlIHNlYXJjaGVkXG4gICAgcmV0dXJuIG9wdGlvbnM7XG4gIH1cbiAgaWYgKHNob3VsZFNraXBTZWFyY2godmFsdWUsIHN0YXRlLCBzaG93T3B0aW9uc1doZW5FbXB0eSkpIHtcbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfVxuXG4gIGNvbnN0IHNlYXJjaE9wdGlvbnMgPSBnZW5lcmF0ZVNlYXJjaEZ1bmN0aW9uKHByb3BzKTtcbiAgcmV0dXJuIHNlYXJjaE9wdGlvbnModmFsdWUsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRTa2lwU2VhcmNoKGlucHV0LCBzdGF0ZSwgc2hvd09wdGlvbnNXaGVuRW1wdHkpIHtcbiAgY29uc3QgZW1wdHlWYWx1ZSA9ICFpbnB1dCB8fCBpbnB1dC50cmltKCkubGVuZ3RoID09PSAwO1xuXG4gIC8vIHRoaXMuc3RhdGUgbXVzdCBiZSBjaGVja2VkIGJlY2F1c2UgaXQgbWF5IG5vdCBiZSBkZWZpbmVkIHlldCBpZiB0aGlzIGZ1bmN0aW9uXG4gIC8vIGlzIGNhbGxlZCBmcm9tIHdpdGhpbiBnZXRJbml0aWFsU3RhdGVcbiAgY29uc3QgaXNGb2N1c2VkID0gc3RhdGUgJiYgc3RhdGUuaXNGb2N1c2VkO1xuICByZXR1cm4gIShzaG93T3B0aW9uc1doZW5FbXB0eSAmJiBpc0ZvY3VzZWQpICYmIGVtcHR5VmFsdWU7XG59XG5cbmNsYXNzIFR5cGVhaGVhZCBleHRlbmRzIENvbXBvbmVudCB7XG4gIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgbmFtZTogUHJvcFR5cGVzLnN0cmluZyxcbiAgICBjdXN0b21DbGFzc2VzOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIG1heFZpc2libGU6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgcmVzdWx0c1RydW5jYXRlZE1lc3NhZ2U6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgb3B0aW9uczogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLmFueSksXG4gICAgZml4ZWRPcHRpb25zOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMuYW55KSxcbiAgICBhbGxvd0N1c3RvbVZhbHVlczogUHJvcFR5cGVzLm51bWJlcixcbiAgICBpbml0aWFsVmFsdWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgdmFsdWU6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgcGxhY2Vob2xkZXI6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgZGlzYWJsZWQ6IFByb3BUeXBlcy5ib29sLFxuICAgIHRleHRhcmVhOiBQcm9wVHlwZXMuYm9vbCxcbiAgICBpbnB1dFByb3BzOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIG9uT3B0aW9uU2VsZWN0ZWQ6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uQ2hhbmdlOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbktleURvd246IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uS2V5UHJlc3M6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uS2V5VXA6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uRm9jdXM6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uQmx1cjogUHJvcFR5cGVzLmZ1bmMsXG4gICAgZmlsdGVyT3B0aW9uOiBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIHNlYXJjaE9wdGlvbnM6IFByb3BUeXBlcy5mdW5jLFxuICAgIGRpc3BsYXlPcHRpb246IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5zdHJpbmcsIFByb3BUeXBlcy5mdW5jXSksXG4gICAgaW5wdXREaXNwbGF5T3B0aW9uOiBQcm9wVHlwZXMub25lT2ZUeXBlKFtQcm9wVHlwZXMuc3RyaW5nLCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIGZvcm1JbnB1dE9wdGlvbjogUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLnN0cmluZywgUHJvcFR5cGVzLmZ1bmNdKSxcbiAgICBkZWZhdWx0Q2xhc3NOYW1lczogUHJvcFR5cGVzLmJvb2wsXG4gICAgY3VzdG9tTGlzdENvbXBvbmVudDogUHJvcFR5cGVzLm9uZU9mVHlwZShbUHJvcFR5cGVzLmVsZW1lbnQsIFByb3BUeXBlcy5mdW5jXSksXG4gICAgY3VzdG9tTGlzdEl0ZW1Db21wb25lbnQ6IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5lbGVtZW50LCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIGN1c3RvbUxpc3RIZWFkZXJDb21wb25lbnQ6IFByb3BUeXBlcy5vbmVPZlR5cGUoW1Byb3BUeXBlcy5lbGVtZW50LCBQcm9wVHlwZXMuZnVuY10pLFxuICAgIHNob3dPcHRpb25zV2hlbkVtcHR5OiBQcm9wVHlwZXMuYm9vbCxcbiAgICBzZWFyY2hhYmxlOiBQcm9wVHlwZXMuYm9vbFxuICB9O1xuXG4gIHN0YXRpYyBkZWZhdWx0UHJvcHMgPSB7XG4gICAgb3B0aW9uczogW10sXG4gICAgY3VzdG9tQ2xhc3Nlczoge30sXG4gICAgYWxsb3dDdXN0b21WYWx1ZXM6IDAsXG4gICAgaW5pdGlhbFZhbHVlOiAnJyxcbiAgICB2YWx1ZTogJycsXG4gICAgcGxhY2Vob2xkZXI6ICcnLFxuICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICB0ZXh0YXJlYTogZmFsc2UsXG4gICAgaW5wdXRQcm9wczoge30sXG4gICAgb25PcHRpb25TZWxlY3RlZChvcHRpb24pIHt9LFxuICAgIG9uQ2hhbmdlKGV2ZW50KSB7fSxcbiAgICBvbktleURvd24oZXZlbnQpIHt9LFxuICAgIG9uS2V5UHJlc3MoZXZlbnQpIHt9LFxuICAgIG9uS2V5VXAoZXZlbnQpIHt9LFxuICAgIG9uRm9jdXMoZXZlbnQpIHt9LFxuICAgIG9uQmx1cihldmVudCkge30sXG4gICAgZmlsdGVyT3B0aW9uOiBudWxsLFxuICAgIHNlYXJjaE9wdGlvbnM6IG51bGwsXG4gICAgaW5wdXREaXNwbGF5T3B0aW9uOiBudWxsLFxuICAgIGRlZmF1bHRDbGFzc05hbWVzOiB0cnVlLFxuICAgIGN1c3RvbUxpc3RDb21wb25lbnQ6IERyb3Bkb3duTGlzdCxcbiAgICBjdXN0b21MaXN0SXRlbUNvbXBvbmVudDogTGlzdEl0ZW0sXG4gICAgY3VzdG9tTGlzdEhlYWRlckNvbXBvbmVudDogbnVsbCxcbiAgICBzaG93T3B0aW9uc1doZW5FbXB0eTogdHJ1ZSxcbiAgICBzZWFyY2hhYmxlOiB0cnVlLFxuICAgIHJlc3VsdHNUcnVuY2F0ZWRNZXNzYWdlOiBudWxsXG4gIH07XG5cbiAgc3RhdGljIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyhwcm9wcywgc3RhdGUpIHtcbiAgICAvLyAgaW52b2tlZCBhZnRlciBhIGNvbXBvbmVudCBpcyBpbnN0YW50aWF0ZWQgYXMgd2VsbCBhcyBiZWZvcmUgaXQgaXMgcmUtcmVuZGVyZWRcbiAgICBjb25zdCBzZWFyY2hSZXN1bHRzID0gZ2V0T3B0aW9uc0ZvclZhbHVlKHN0YXRlLmVudHJ5VmFsdWUsIHByb3BzLCBzdGF0ZSk7XG5cbiAgICByZXR1cm4ge3NlYXJjaFJlc3VsdHN9O1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgc2VhcmNoUmVzdWx0czogW10sXG5cbiAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBzb21ldGhpbmcgZWxzZSwgJ2VudHJ5VmFsdWUnXG4gICAgICBlbnRyeVZhbHVlOiB0aGlzLnByb3BzLnZhbHVlIHx8IHRoaXMucHJvcHMuaW5pdGlhbFZhbHVlLFxuXG4gICAgICAvLyBBIHZhbGlkIHR5cGVhaGVhZCB2YWx1ZVxuICAgICAgc2VsZWN0aW9uOiB0aGlzLnByb3BzLnZhbHVlLFxuXG4gICAgICAvLyBJbmRleCBvZiB0aGUgc2VsZWN0aW9uXG4gICAgICBzZWxlY3Rpb25JbmRleDogbnVsbCxcblxuICAgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgZm9jdXMgc3RhdGUgb2YgdGhlIGlucHV0IGVsZW1lbnQsIHRvIGRldGVybWluZVxuICAgICAgLy8gd2hldGhlciB0byBzaG93IG9wdGlvbnMgd2hlbiBlbXB0eSAoaWYgc2hvd09wdGlvbnNXaGVuRW1wdHkgaXMgdHJ1ZSlcbiAgICAgIGlzRm9jdXNlZDogZmFsc2VcbiAgICB9O1xuICB9XG5cbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgLy8gY2FsbCBmb2N1cyBvbiBlbnRyeSBvciBkaXYgdG8gdHJpZ2dlciBrZXkgZXZlbnRzIGxpc3RlbmVyXG4gICAgaWYgKHRoaXMuZW50cnkuY3VycmVudCkge1xuICAgICAgdGhpcy5lbnRyeS5jdXJyZW50LmZvY3VzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucm9vdC5jdXJyZW50LmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgcm9vdCA9IGNyZWF0ZVJlZigpO1xuICBlbnRyeSA9IGNyZWF0ZVJlZigpO1xuXG4gIGZvY3VzID0gKCkgPT4ge1xuICAgIGlmICh0aGlzLmVudHJ5LmN1cnJlbnQpIHtcbiAgICAgIHRoaXMuZW50cnkuY3VycmVudC5mb2N1cygpO1xuICAgIH1cbiAgfTtcblxuICBfaGFzQ3VzdG9tVmFsdWUgPSAoKSA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMucHJvcHMuYWxsb3dDdXN0b21WYWx1ZXMgPiAwICYmXG4gICAgICB0aGlzLnN0YXRlLmVudHJ5VmFsdWUubGVuZ3RoID49IHRoaXMucHJvcHMuYWxsb3dDdXN0b21WYWx1ZXMgJiZcbiAgICAgIHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cy5pbmRleE9mKHRoaXMuc3RhdGUuZW50cnlWYWx1ZSkgPCAwXG4gICAgKTtcbiAgfTtcblxuICBfZ2V0Q3VzdG9tVmFsdWUgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuX2hhc0N1c3RvbVZhbHVlKCkgPyB0aGlzLnN0YXRlLmVudHJ5VmFsdWUgOiBudWxsO1xuICB9O1xuXG4gIF9yZW5kZXJJbmNyZW1lbnRhbFNlYXJjaFJlc3VsdHMoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDx0aGlzLnByb3BzLmN1c3RvbUxpc3RDb21wb25lbnRcbiAgICAgICAgZml4ZWRPcHRpb25zPXt0aGlzLnByb3BzLmZpeGVkT3B0aW9uc31cbiAgICAgICAgb3B0aW9ucz17XG4gICAgICAgICAgdGhpcy5wcm9wcy5tYXhWaXNpYmxlXG4gICAgICAgICAgICA/IHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0cy5zbGljZSgwLCB0aGlzLnByb3BzLm1heFZpc2libGUpXG4gICAgICAgICAgICA6IHRoaXMuc3RhdGUuc2VhcmNoUmVzdWx0c1xuICAgICAgICB9XG4gICAgICAgIGFyZVJlc3VsdHNUcnVuY2F0ZWQ9e1xuICAgICAgICAgIHRoaXMucHJvcHMubWF4VmlzaWJsZSAmJiB0aGlzLnN0YXRlLnNlYXJjaFJlc3VsdHMubGVuZ3RoID4gdGhpcy5wcm9wcy5tYXhWaXNpYmxlXG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0c1RydW5jYXRlZE1lc3NhZ2U9e3RoaXMucHJvcHMucmVzdWx0c1RydW5jYXRlZE1lc3NhZ2V9XG4gICAgICAgIG9uT3B0aW9uU2VsZWN0ZWQ9e3RoaXMuX29uT3B0aW9uU2VsZWN0ZWR9XG4gICAgICAgIGFsbG93Q3VzdG9tVmFsdWVzPXt0aGlzLnByb3BzLmFsbG93Q3VzdG9tVmFsdWVzfVxuICAgICAgICBjdXN0b21WYWx1ZT17dGhpcy5fZ2V0Q3VzdG9tVmFsdWUoKX1cbiAgICAgICAgY3VzdG9tQ2xhc3Nlcz17dGhpcy5wcm9wcy5jdXN0b21DbGFzc2VzfVxuICAgICAgICBjdXN0b21MaXN0SXRlbUNvbXBvbmVudD17dGhpcy5wcm9wcy5jdXN0b21MaXN0SXRlbUNvbXBvbmVudH1cbiAgICAgICAgY3VzdG9tTGlzdEhlYWRlckNvbXBvbmVudD17dGhpcy5wcm9wcy5jdXN0b21MaXN0SGVhZGVyQ29tcG9uZW50