apeman-react-select
Version:
apeman react package for select component.
431 lines (373 loc) • 34.4 kB
JavaScript
/**
* apeman react package for select component.
* @class ApSelect
*/
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ApSelect = undefined;
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _ap_select_item = require('./ap_select_item');
var _ap_select_item2 = _interopRequireDefault(_ap_select_item);
var _ap_select_label = require('./ap_select_label');
var _ap_select_label2 = _interopRequireDefault(_ap_select_label);
var _numcal = require('numcal');
var _numcal2 = _interopRequireDefault(_numcal);
var _bwindow = require('bwindow');
var _apemanReactMixinLayout = require('apeman-react-mixin-layout');
var _apemanReactTouchable = require('apeman-react-touchable');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** @lends ApSelect */
var ApSelect = _react2.default.createClass({
displayName: 'ApSelect',
// --------------------
// Specs
// --------------------
propTypes: {
/** Options of select */
options: _react.PropTypes.object.isRequired,
/** Option elements to render */
optionElements: _react.PropTypes.object,
/** Name of select element */
name: _react.PropTypes.string,
/** Value of select element */
value: _react.PropTypes.string,
/** Allow multiple select */
multiple: _react.PropTypes.bool,
/** Handler for change event */
onChange: _react.PropTypes.func,
/** Icon to toggle select */
openIcon: _react.PropTypes.string,
/** Placeholder of select element */
placeholder: _react.PropTypes.string
},
mixins: [_apemanReactMixinLayout.ApLayoutMixin],
statics: {},
getInitialState: function getInitialState() {
var s = this;
return {
focused: false,
focusIndex: s.getIndexForValue(s.props.value)
};
},
getDefaultProps: function getDefaultProps() {
return {
optionElements: null,
value: '',
name: null,
multiple: false,
onChange: null,
openIcon: 'ion ion-arrow-down-b',
placeholder: null
};
},
render: function render() {
var s = this;
var state = s.state,
props = s.props,
layouts = s.layouts;
var options = props.options,
optionElements = props.optionElements;
var values = s.getOptionValues();
var hasOption = options && (0, _keys2.default)(options).length > 0;
if (!hasOption) {
return null;
}
var _option = function _option(value) {
return optionElements && optionElements[value] || options[value] || null;
};
return _react2.default.createElement(
'span',
{ className: (0, _classnames2.default)('ap-select-wrap') },
_react2.default.createElement(
'span',
{ className: (0, _classnames2.default)('ap-select-options-list', {
'ap-select-options-list-visible': state.focused
}), ref: function ref(list) {
return s.registerNode(list, 'list');
}
},
_react2.default.createElement(
'ul',
{ className: 'ap-select-options-list-inner',
style: layouts.listInner },
values.map(function (value, i) {
return _react2.default.createElement(
'li',
{ key: value,
value: value,
className: (0, _classnames2.default)('ap-select-options-list-item') },
_react2.default.createElement(
_ap_select_item2.default,
{ onTap: s.handleItemTap,
data: value,
focused: state.focusIndex === i,
label: options[value]
},
_option(value) || null
)
);
})
)
),
_react2.default.createElement(
'select',
{ id: props.id,
name: props.name,
placeholder: props.placeholder,
onChange: props.onChange,
className: (0, _classnames2.default)('ap-select', props.className),
onFocus: function onFocus() {
return s.setFocus(true);
},
style: (0, _assign2.default)({}, props.style),
tabIndex: '-1'
},
values.map(function (value) {
return _react2.default.createElement(
'option',
{ key: value, value: value },
options[value]
);
}),
props.children
),
_react2.default.createElement('input', { type: 'text',
ref: function ref(text) {
return s.registerNode(text, 'text');
},
className: 'ap-select-dummy-text',
onKeyUp: s.handleKeyUp,
onKeyDown: s.handleKeyDown,
onFocus: function onFocus() {
return s.setFocus(true);
},
onBlur: function onBlur() {
return s.setFocus(false);
}
}),
_react2.default.createElement(_ap_select_label2.default, { value: _option(props.value),
placeholder: props.placeholder,
icon: props.openIcon,
onTap: s.handleLabelTap
})
);
},
// --------------------
// Lifecycle
// --------------------
componentWillMount: function componentWillMount() {
var s = this;
s.nodes = {};
},
componentDidMount: function componentDidMount() {
var s = this;
var body = (0, _bwindow.get)('document.body');
body.addEventListener('click', s.handleClickForOutside);
},
componentWillUnmount: function componentWillUnmount() {
var s = this;
var body = (0, _bwindow.get)('document.body');
body.removeEventListener('click', s.handleClickForOutside);
},
// ------------------
// Custom
// ------------------
moveFocusIndex: function moveFocusIndex(i) {
var s = this;
var state = s.state;
var values = s.getOptionValues();
var index = state.focusIndex + i;
var over = index === -1 || index === values.length;
if (over) {
return;
}
s.setState({
focusIndex: index
});
},
enterFocused: function enterFocused(e) {
var s = this;
var state = s.state,
props = s.props;
if (!state.focused) {
return;
}
var values = s.getOptionValues();
var value = values[state.focusIndex];
s.setState({
focused: false,
focusIndex: s.getIndexForValue(value)
});
e.target.value = value;
if (props.onChange) {
props.onChange(e);
}
},
getOptionValues: function getOptionValues() {
var s = this;
var props = s.props;
return (0, _keys2.default)(props.options || {});
},
getIndexForValue: function getIndexForValue(value) {
var s = this;
return s.getOptionValues().indexOf(value);
},
registerNode: function registerNode(elm, name) {
var s = this;
s.nodes[name] = _reactDom2.default.findDOMNode(elm);
},
// --------------------
// Handle
// --------------------
handleLabelTap: function handleLabelTap(e) {
var s = this;
var state = s.state;
var text = s.nodes.text;
var focused = !state.focused;
if (focused) {
s.layout();
text.focus();
} else {
text.blur();
}
s.setState({
focused: focused,
focusIndex: s.getIndexForValue(s.props.value)
});
},
setFocus: function setFocus(focused) {
var s = this;
if (focused === s.state.focused) {
return;
}
if (s._focusAt) {
var fromLastFocusAt = new Date() - s._focusAt;
if (fromLastFocusAt < 500) {
return;
}
}
s._focusAt = new Date();
s.setState({
focused: focused
});
},
handleKeyDown: function handleKeyDown(e) {
var s = this;
var props = s.props;
if (!s.state.focused) {
s.setState({ focused: true });
return;
}
switch (e.keyCode) {
case 38:
// UP
s.moveFocusIndex(-1);
break;
case 40:
// DOWN
s.moveFocusIndex(+1);
break;
case 13:
// Enter
s.enterFocused(e);
break;
case 9:
// Tab
break;
default:
e.preventDefault();
e.stopPropagation();
break;
}
if (props.onKeyDown) {
props.onKeyDown(e);
}
},
handleKeyUp: function handleKeyUp(e) {
var s = this;
var props = s.props;
if (props.onKeyUp) {
props.onKeyUp(e);
}
e.stopPropagation();
},
handleItemTap: function handleItemTap(e) {
var s = this;
var props = s.props;
(0, _assign2.default)(e.target, {
value: e.target.value || e.data || null,
name: e.target.name || props.name
});
if (props.onChange) {
props.onChange(e);
}
s.setState({
focused: false,
focusIndex: s.getIndexForValue(s.props.value)
});
},
handleClickForOutside: function handleClickForOutside(e) {
var s = this;
var node = _reactDom2.default.findDOMNode(s);
if (!node) {
return;
}
var contained = node.contains(e.target);
if (!contained) {
s.outsideDidTap(e);
}
},
outsideDidTap: function outsideDidTap(e) {
var s = this;
s.setFocus(false);
},
// ------------------
// ApLayoutMixin
// ------------------
getInitialLayouts: function getInitialLayouts() {
return {
listInner: {
transform: 'initial'
}
};
},
calcLayouts: function calcLayouts() {
var s = this;
var _window = window,
innerHeight = _window.innerHeight,
innerWidth = _window.innerWidth;
var list = s.nodes.list;
if (!list) {
return {};
}
return {
listInner: s._listInnerLayout(list.getBoundingClientRect(), innerWidth, innerHeight)
};
},
// ------------------
// Private
// ------------------
_listInnerLayout: function _listInnerLayout(rect, boundsWidth, boundsHeight) {
var x = _numcal2.default.min(boundsWidth - rect.right, 0);
var y = _numcal2.default.min(boundsHeight - rect.bottom, 0);
var maxHeight = _numcal2.default.min(boundsHeight, 280) + 'px';
return {
transform: 'translate(' + x + 'px, ' + y + 'px)',
maxHeight: maxHeight
};
}
});
exports.ApSelect = ApSelect;
exports.default = (0, _apemanReactTouchable.withOutside)(ApSelect);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwX3NlbGVjdC5qc3giXSwibmFtZXMiOlsiQXBTZWxlY3QiLCJjcmVhdGVDbGFzcyIsInByb3BUeXBlcyIsIm9wdGlvbnMiLCJvYmplY3QiLCJpc1JlcXVpcmVkIiwib3B0aW9uRWxlbWVudHMiLCJuYW1lIiwic3RyaW5nIiwidmFsdWUiLCJtdWx0aXBsZSIsImJvb2wiLCJvbkNoYW5nZSIsImZ1bmMiLCJvcGVuSWNvbiIsInBsYWNlaG9sZGVyIiwibWl4aW5zIiwic3RhdGljcyIsImdldEluaXRpYWxTdGF0ZSIsInMiLCJmb2N1c2VkIiwiZm9jdXNJbmRleCIsImdldEluZGV4Rm9yVmFsdWUiLCJwcm9wcyIsImdldERlZmF1bHRQcm9wcyIsInJlbmRlciIsInN0YXRlIiwibGF5b3V0cyIsInZhbHVlcyIsImdldE9wdGlvblZhbHVlcyIsImhhc09wdGlvbiIsImxlbmd0aCIsIl9vcHRpb24iLCJsaXN0IiwicmVnaXN0ZXJOb2RlIiwibGlzdElubmVyIiwibWFwIiwiaSIsImhhbmRsZUl0ZW1UYXAiLCJpZCIsImNsYXNzTmFtZSIsInNldEZvY3VzIiwic3R5bGUiLCJjaGlsZHJlbiIsInRleHQiLCJoYW5kbGVLZXlVcCIsImhhbmRsZUtleURvd24iLCJoYW5kbGVMYWJlbFRhcCIsImNvbXBvbmVudFdpbGxNb3VudCIsIm5vZGVzIiwiY29tcG9uZW50RGlkTW91bnQiLCJib2R5IiwiYWRkRXZlbnRMaXN0ZW5lciIsImhhbmRsZUNsaWNrRm9yT3V0c2lkZSIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsIm1vdmVGb2N1c0luZGV4IiwiaW5kZXgiLCJvdmVyIiwic2V0U3RhdGUiLCJlbnRlckZvY3VzZWQiLCJlIiwidGFyZ2V0IiwiaW5kZXhPZiIsImVsbSIsImZpbmRET01Ob2RlIiwibGF5b3V0IiwiZm9jdXMiLCJibHVyIiwiX2ZvY3VzQXQiLCJmcm9tTGFzdEZvY3VzQXQiLCJEYXRlIiwia2V5Q29kZSIsInByZXZlbnREZWZhdWx0Iiwic3RvcFByb3BhZ2F0aW9uIiwib25LZXlEb3duIiwib25LZXlVcCIsImRhdGEiLCJub2RlIiwiY29udGFpbmVkIiwiY29udGFpbnMiLCJvdXRzaWRlRGlkVGFwIiwiZ2V0SW5pdGlhbExheW91dHMiLCJ0cmFuc2Zvcm0iLCJjYWxjTGF5b3V0cyIsIndpbmRvdyIsImlubmVySGVpZ2h0IiwiaW5uZXJXaWR0aCIsIl9saXN0SW5uZXJMYXlvdXQiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJyZWN0IiwiYm91bmRzV2lkdGgiLCJib3VuZHNIZWlnaHQiLCJ4IiwibWluIiwicmlnaHQiLCJ5IiwiYm90dG9tIiwibWF4SGVpZ2h0Il0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7QUFLQTs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQTtBQUNBLElBQU1BLFdBQVcsZ0JBQU1DLFdBQU4sQ0FBa0I7QUFBQTs7O0FBRWpDO0FBQ0E7QUFDQTs7QUFFQUMsYUFBVztBQUNUO0FBQ0FDLGFBQVMsaUJBQU1DLE1BQU4sQ0FBYUMsVUFGYjtBQUdUO0FBQ0FDLG9CQUFnQixpQkFBTUYsTUFKYjtBQUtUO0FBQ0FHLFVBQU0saUJBQU1DLE1BTkg7QUFPVDtBQUNBQyxXQUFPLGlCQUFNRCxNQVJKO0FBU1Q7QUFDQUUsY0FBVSxpQkFBTUMsSUFWUDtBQVdUO0FBQ0FDLGNBQVUsaUJBQU1DLElBWlA7QUFhVDtBQUNBQyxjQUFVLGlCQUFNTixNQWRQO0FBZVQ7QUFDQU8saUJBQWEsaUJBQU1QO0FBaEJWLEdBTnNCOztBQXlCakNRLFVBQVEsdUNBekJ5Qjs7QUE2QmpDQyxXQUFTLEVBN0J3Qjs7QUErQmpDQyxpQkEvQmlDLDZCQStCZDtBQUNqQixRQUFNQyxJQUFJLElBQVY7QUFDQSxXQUFPO0FBQ0xDLGVBQVMsS0FESjtBQUVMQyxrQkFBWUYsRUFBRUcsZ0JBQUYsQ0FBbUJILEVBQUVJLEtBQUYsQ0FBUWQsS0FB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VjtBQURhLGtCQUVxQmtFLE1BRnJCO0FBQUEsUUFFUEMsV0FGTyxXQUVQQSxXQUZPO0FBQUEsUUFFTUMsVUFGTixXQUVNQSxVQUZOO0FBQUEsUUFHUHRELElBSE8sR0FHRWQsRUFBRThCLEtBSEosQ0FHUGhCLElBSE87O0FBSWIsUUFBSSxDQUFDQSxJQUFMLEVBQVc7QUFDVCxhQUFPLEVBQVA7QUFDRDtBQUNELFdBQU87QUFDTEUsaUJBQVdoQixFQUFFcUUsZ0JBQUYsQ0FBbUJ2RCxLQUFLd0QscUJBQUwsRUFBbkIsRUFBaURGLFVBQWpELEVBQTZERCxXQUE3RDtBQUROLEtBQVA7QUFHRCxHQXRVZ0M7OztBQXdVakM7QUFDQTtBQUNBOztBQUVBRSxrQkE1VWlDLDRCQTRVZkUsSUE1VWUsRUE0VVRDLFdBNVVTLEVBNFVJQyxZQTVVSixFQTRVa0I7QUFDakQsUUFBSUMsSUFBSSxpQkFBT0MsR0FBUCxDQUFXSCxjQUFjRCxLQUFLSyxLQUE5QixFQUFxQyxDQUFyQyxDQUFSO0FBQ0EsUUFBSUMsSUFBSSxpQkFBT0YsR0FBUCxDQUFXRixlQUFlRixLQUFLTyxNQUEvQixFQUF1QyxDQUF2QyxDQUFSOztBQUVBLFFBQUlDLFlBQWUsaUJBQU9KLEdBQVAsQ0FBV0YsWUFBWCxFQUF5QixHQUF6QixDQUFmLE9BQUo7QUFDQSxXQUFPO0FBQ0xULGdDQUF3QlUsQ0FBeEIsWUFBZ0NHLENBQWhDLFFBREs7QUFFTEU7QUFGSyxLQUFQO0FBSUQ7QUFyVmdDLENBQWxCLENBQWpCOztRQXdWU2xHLFEsR0FBQUEsUTtrQkFDTSx1Q0FBWUEsUUFBWixDIiwiZmlsZSI6ImFwX3NlbGVjdC5qc3giLCJzb3VyY2VSb290IjoibGliIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBhcGVtYW4gcmVhY3QgcGFja2FnZSBmb3Igc2VsZWN0IGNvbXBvbmVudC5cbiAqIEBjbGFzcyBBcFNlbGVjdFxuICovXG5cbid1c2Ugc3RyaWN0J1xuXG5pbXBvcnQgUmVhY3QsIHsgQ29tcG9uZW50LCBQcm9wVHlwZXMgYXMgdHlwZXMgfSBmcm9tICdyZWFjdCdcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nXG5pbXBvcnQgY2xhc3NuYW1lcyBmcm9tICdjbGFzc25hbWVzJ1xuaW1wb3J0IEFwU2VsZWN0SXRlbSBmcm9tICcuL2FwX3NlbGVjdF9pdGVtJ1xuaW1wb3J0IEFwU2VsZWN0TGFiZWwgZnJvbSAnLi9hcF9zZWxlY3RfbGFiZWwnXG5pbXBvcnQgbnVtY2FsIGZyb20gJ251bWNhbCdcbmltcG9ydCB7IGdldCB9IGZyb20gJ2J3aW5kb3cnXG5pbXBvcnQgeyBBcExheW91dE1peGluIH0gZnJvbSAnYXBlbWFuLXJlYWN0LW1peGluLWxheW91dCdcbmltcG9ydCB7IHdpdGhPdXRzaWRlIH0gZnJvbSAnYXBlbWFuLXJlYWN0LXRvdWNoYWJsZSdcblxuLyoqIEBsZW5kcyBBcFNlbGVjdCAqL1xuY29uc3QgQXBTZWxlY3QgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gU3BlY3NcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcm9wVHlwZXM6IHtcbiAgICAvKiogT3B0aW9ucyBvZiBzZWxlY3QgKi9cbiAgICBvcHRpb25zOiB0eXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAvKiogT3B0aW9uIGVsZW1lbnRzIHRvIHJlbmRlciAqL1xuICAgIG9wdGlvbkVsZW1lbnRzOiB0eXBlcy5vYmplY3QsXG4gICAgLyoqIE5hbWUgb2Ygc2VsZWN0IGVsZW1lbnQgKi9cbiAgICBuYW1lOiB0eXBlcy5zdHJpbmcsXG4gICAgLyoqIFZhbHVlIG9mIHNlbGVjdCBlbGVtZW50ICovXG4gICAgdmFsdWU6IHR5cGVzLnN0cmluZyxcbiAgICAvKiogQWxsb3cgbXVsdGlwbGUgc2VsZWN0ICovXG4gICAgbXVsdGlwbGU6IHR5cGVzLmJvb2wsXG4gICAgLyoqIEhhbmRsZXIgZm9yIGNoYW5nZSBldmVudCAqL1xuICAgIG9uQ2hhbmdlOiB0eXBlcy5mdW5jLFxuICAgIC8qKiBJY29uIHRvIHRvZ2dsZSBzZWxlY3QgKi9cbiAgICBvcGVuSWNvbjogdHlwZXMuc3RyaW5nLFxuICAgIC8qKiBQbGFjZWhvbGRlciBvZiBzZWxlY3QgZWxlbWVudCAqL1xuICAgIHBsYWNlaG9sZGVyOiB0eXBlcy5zdHJpbmdcbiAgfSxcblxuICBtaXhpbnM6IFtcbiAgICBBcExheW91dE1peGluXG4gIF0sXG5cbiAgc3RhdGljczoge30sXG5cbiAgZ2V0SW5pdGlhbFN0YXRlICgpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIHJldHVybiB7XG4gICAgICBmb2N1c2VkOiBmYWxzZSxcbiAgICAgIGZvY3VzSW5kZXg6IHMuZ2V0SW5kZXhGb3JWYWx1ZShzLnByb3BzLnZhbHVlKVxuICAgIH1cbiAgfSxcblxuICBnZXREZWZhdWx0UHJvcHMgKCkge1xuICAgIHJldHVybiB7XG4gICAgICBvcHRpb25FbGVtZW50czogbnVsbCxcbiAgICAgIHZhbHVlOiAnJyxcbiAgICAgIG5hbWU6IG51bGwsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBvbkNoYW5nZTogbnVsbCxcbiAgICAgIG9wZW5JY29uOiAnaW9uIGlvbi1hcnJvdy1kb3duLWInLFxuICAgICAgcGxhY2Vob2xkZXI6IG51bGxcbiAgICB9XG4gIH0sXG5cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCB7IHN0YXRlLCBwcm9wcywgbGF5b3V0cyB9ID0gc1xuXG4gICAgbGV0IHsgb3B0aW9ucywgb3B0aW9uRWxlbWVudHMgfSA9IHByb3BzXG4gICAgbGV0IHZhbHVlcyA9IHMuZ2V0T3B0aW9uVmFsdWVzKClcblxuICAgIGxldCBoYXNPcHRpb24gPSBvcHRpb25zICYmIE9iamVjdC5rZXlzKG9wdGlvbnMpLmxlbmd0aCA+IDBcbiAgICBpZiAoIWhhc09wdGlvbikge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICBsZXQgX29wdGlvbiA9ICh2YWx1ZSkgPT4gb3B0aW9uRWxlbWVudHMgJiYgb3B0aW9uRWxlbWVudHNbIHZhbHVlIF0gfHwgb3B0aW9uc1sgdmFsdWUgXSB8fCBudWxsXG5cbiAgICByZXR1cm4gKFxuICAgICAgPHNwYW4gY2xhc3NOYW1lPXsgY2xhc3NuYW1lcygnYXAtc2VsZWN0LXdyYXAnKSB9PlxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT17IGNsYXNzbmFtZXMoJ2FwLXNlbGVjdC1vcHRpb25zLWxpc3QnLCB7XG4gICAgICAgICAgICAnYXAtc2VsZWN0LW9wdGlvbnMtbGlzdC12aXNpYmxlJzogc3RhdGUuZm9jdXNlZFxuICAgICAgICAgIH0pIH0gcmVmPXsgKGxpc3QpID0+IHMucmVnaXN0ZXJOb2RlKGxpc3QsICdsaXN0JykgfVxuICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHVsIGNsYXNzTmFtZT0nYXAtc2VsZWN0LW9wdGlvbnMtbGlzdC1pbm5lcidcbiAgICAgICAgICAgICAgICAgIHN0eWxlPXsgbGF5b3V0cy5saXN0SW5uZXIgfT5cbiAgICAgICAgICAgICAgICAgIHsgdmFsdWVzLm1hcCgodmFsdWUsIGkpID0+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBrZXk9eyB2YWx1ZSB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17IHZhbHVlIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17IGNsYXNzbmFtZXMoJ2FwLXNlbGVjdC1vcHRpb25zLWxpc3QtaXRlbScpIH0+XG4gICAgICAgICAgICAgICAgICAgICAgPEFwU2VsZWN0SXRlbSBvblRhcD17IHMuaGFuZGxlSXRlbVRhcCB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPXsgdmFsdWUgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9jdXNlZD17IHN0YXRlLmZvY3VzSW5kZXggPT09IGkgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9eyBvcHRpb25zWyB2YWx1ZSBdIH1cbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7IF9vcHRpb24odmFsdWUpIHx8IG51bGwgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvQXBTZWxlY3RJdGVtPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgKSB9XG4gICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzZWxlY3QgaWQ9eyBwcm9wcy5pZCB9XG4gICAgICAgICAgICAgICAgICBuYW1lPXsgcHJvcHMubmFtZSB9XG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj17IHByb3BzLnBsYWNlaG9sZGVyIH1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsgcHJvcHMub25DaGFuZ2UgfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsgY2xhc3NuYW1lcygnYXAtc2VsZWN0JywgcHJvcHMuY2xhc3NOYW1lKSB9XG4gICAgICAgICAgICAgICAgICBvbkZvY3VzPXsgKCkgPT4gcy5zZXRGb2N1cyh0cnVlKSB9XG4gICAgICAgICAgICAgICAgICBzdHlsZT17IE9iamVjdC5hc3NpZ24oe30sIHByb3BzLnN0eWxlKSB9XG4gICAgICAgICAgICAgICAgICB0YWJJbmRleD1cIi0xXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICAgIHsgdmFsdWVzLm1hcCgodmFsdWUpID0+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBrZXk9eyB2YWx1ZSB9IHZhbHVlPXsgdmFsdWUgfT57IG9wdGlvbnNbIHZhbHVlIF0gfTwvb3B0aW9uPlxuICAgICAgICAgICAgICApIH1cbiAgICAgICAgICAgIHsgcHJvcHMuY2hpbGRyZW4gfVxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0J1xuICAgICAgICAgICAgICAgICByZWY9eyAodGV4dCkgPT4gcy5yZWdpc3Rlck5vZGUodGV4dCwgJ3RleHQnKSB9XG4gICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0nYXAtc2VsZWN0LWR1bW15LXRleHQnXG4gICAgICAgICAgICAgICAgIG9uS2V5VXA9eyBzLmhhbmRsZUtleVVwIH1cbiAgICAgICAgICAgICAgICAgb25LZXlEb3duPXsgcy5oYW5kbGVLZXlEb3duIH1cbiAgICAgICAgICAgICAgICAgb25Gb2N1cz17ICgpID0+IHMuc2V0Rm9jdXModHJ1ZSkgfVxuICAgICAgICAgICAgICAgICBvbkJsdXI9eyAoKSA9PiBzLnNldEZvY3VzKGZhbHNlKSB9XG4gICAgICAgICAgLz5cbiAgICAgICAgICA8QXBTZWxlY3RMYWJlbCB2YWx1ZT17IF9vcHRpb24ocHJvcHMudmFsdWUpIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj17IHByb3BzLnBsYWNlaG9sZGVyIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICBpY29uPXsgcHJvcHMub3Blbkljb24gfVxuICAgICAgICAgICAgICAgICAgICAgICAgIG9uVGFwPXsgcy5oYW5kbGVMYWJlbFRhcCB9XG4gICAgICAgICAgLz5cblxuICAgICAgPC9zcGFuPlxuICAgIClcbiAgfSxcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBMaWZlY3ljbGVcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBjb21wb25lbnRXaWxsTW91bnQgKCkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgcy5ub2RlcyA9IHt9XG4gIH0sXG5cbiAgY29tcG9uZW50RGlkTW91bnQgKCkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IGJvZHkgPSBnZXQoJ2RvY3VtZW50LmJvZHknKVxuICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzLmhhbmRsZUNsaWNrRm9yT3V0c2lkZSlcbiAgfSxcblxuICBjb21wb25lbnRXaWxsVW5tb3VudCAoKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgYm9keSA9IGdldCgnZG9jdW1lbnQuYm9keScpXG4gICAgYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHMuaGFuZGxlQ2xpY2tGb3JPdXRzaWRlKVxuXG4gIH0sXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBDdXN0b21cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgbW92ZUZvY3VzSW5kZXggKGkpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCB7IHN0YXRlIH0gPSBzXG4gICAgbGV0IHZhbHVlcyA9IHMuZ2V0T3B0aW9uVmFsdWVzKClcbiAgICBsZXQgaW5kZXggPSBzdGF0ZS5mb2N1c0luZGV4ICsgaVxuICAgIGxldCBvdmVyID0gKGluZGV4ID09PSAtMSkgfHwgKGluZGV4ID09PSB2YWx1ZXMubGVuZ3RoKVxuICAgIGlmIChvdmVyKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgcy5zZXRTdGF0ZSh7XG4gICAgICBmb2N1c0luZGV4OiBpbmRleFxuICAgIH0pXG4gIH0sXG5cbiAgZW50ZXJGb2N1c2VkIChlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBzdGF0ZSwgcHJvcHMgfSA9IHNcbiAgICBpZiAoIXN0YXRlLmZvY3VzZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBsZXQgdmFsdWVzID0gcy5nZXRPcHRpb25WYWx1ZXMoKVxuICAgIGxldCB2YWx1ZSA9IHZhbHVlc1sgc3RhdGUuZm9jdXNJbmRleCBdXG4gICAgcy5zZXRTdGF0ZSh7XG4gICAgICBmb2N1c2VkOiBmYWxzZSxcbiAgICAgIGZvY3VzSW5kZXg6IHMuZ2V0SW5kZXhGb3JWYWx1ZSh2YWx1ZSlcbiAgICB9KVxuICAgIGUudGFyZ2V0LnZhbHVlID0gdmFsdWVcbiAgICBpZiAocHJvcHMub25DaGFuZ2UpIHtcbiAgICAgIHByb3BzLm9uQ2hhbmdlKGUpXG4gICAgfVxuICB9LFxuXG4gIGdldE9wdGlvblZhbHVlcyAoKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBwcm9wcyB9ID0gc1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhwcm9wcy5vcHRpb25zIHx8IHt9KVxuICB9LFxuXG4gIGdldEluZGV4Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICByZXR1cm4gcy5nZXRPcHRpb25WYWx1ZXMoKS5pbmRleE9mKHZhbHVlKVxuICB9LFxuXG4gIHJlZ2lzdGVyTm9kZSAoZWxtLCBuYW1lKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBzLm5vZGVzWyBuYW1lIF0gPSBSZWFjdERPTS5maW5kRE9NTm9kZShlbG0pXG4gIH0sXG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gSGFuZGxlXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgaGFuZGxlTGFiZWxUYXAgKGUpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCB7IHN0YXRlIH0gPSBzXG5cbiAgICBsZXQgeyB0ZXh0IH0gPSBzLm5vZGVzXG5cbiAgICBsZXQgZm9jdXNlZCA9ICFzdGF0ZS5mb2N1c2VkXG4gICAgaWYgKGZvY3VzZWQpIHtcbiAgICAgIHMubGF5b3V0KClcbiAgICAgIHRleHQuZm9jdXMoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0ZXh0LmJsdXIoKVxuICAgIH1cbiAgICBzLnNldFN0YXRlKHtcbiAgICAgIGZvY3VzZWQsXG4gICAgICBmb2N1c0luZGV4OiBzLmdldEluZGV4Rm9yVmFsdWUocy5wcm9wcy52YWx1ZSlcbiAgICB9KVxuICB9LFxuXG4gIHNldEZvY3VzIChmb2N1c2VkKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBpZiAoZm9jdXNlZCA9PT0gcy5zdGF0ZS5mb2N1c2VkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYocy5fZm9jdXNBdCl7XG4gICAgICBjb25zdCBmcm9tTGFzdEZvY3VzQXQgPSBuZXcgRGF0ZSgpICAtIHMuX2ZvY3VzQXRcbiAgICAgIGlmKGZyb21MYXN0Rm9jdXNBdCA8IDUwMCl7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cbiAgICBzLl9mb2N1c0F0ID0gbmV3IERhdGUoKVxuICAgIHMuc2V0U3RhdGUoe1xuICAgICAgZm9jdXNlZFxuICAgIH0pXG4gIH0sXG5cbiAgaGFuZGxlS2V5RG93biAoZSkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IHsgcHJvcHMgfSA9IHNcbiAgICBpZiAoIXMuc3RhdGUuZm9jdXNlZCkge1xuICAgICAgcy5zZXRTdGF0ZSh7IGZvY3VzZWQ6IHRydWUgfSlcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBzd2l0Y2ggKGUua2V5Q29kZSkge1xuICAgICAgY2FzZSAzODogLy8gVVBcbiAgICAgICAgcy5tb3ZlRm9jdXNJbmRleCgtMSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgNDA6IC8vIERPV05cbiAgICAgICAgcy5tb3ZlRm9jdXNJbmRleCgrMSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgMTM6IC8vIEVudGVyXG4gICAgICAgIHMuZW50ZXJGb2N1c2VkKGUpXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIDk6IC8vIFRhYlxuICAgICAgICBicmVha1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gICAgaWYgKHByb3BzLm9uS2V5RG93bikge1xuICAgICAgcHJvcHMub25LZXlEb3duKGUpXG4gICAgfVxuICB9LFxuXG4gIGhhbmRsZUtleVVwIChlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBwcm9wcyB9ID0gc1xuICAgIGlmIChwcm9wcy5vbktleVVwKSB7XG4gICAgICBwcm9wcy5vbktleVVwKGUpXG4gICAgfVxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgfSxcblxuICBoYW5kbGVJdGVtVGFwIChlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBwcm9wcyB9ID0gc1xuICAgIE9iamVjdC5hc3NpZ24oZS50YXJnZXQsIHtcbiAgICAgIHZhbHVlOiBlLnRhcmdldC52YWx1ZSB8fCBlLmRhdGEgfHwgbnVsbCxcbiAgICAgIG5hbWU6IGUudGFyZ2V0Lm5hbWUgfHwgcHJvcHMubmFtZVxuICAgIH0pXG4gICAgaWYgKHByb3BzLm9uQ2hhbmdlKSB7XG4gICAgICBwcm9wcy5vbkNoYW5nZShlKVxuICAgIH1cbiAgICBzLnNldFN0YXRlKHtcbiAgICAgIGZvY3VzZWQ6IGZhbHNlLFxuICAgICAgZm9jdXNJbmRleDogcy5nZXRJbmRleEZvclZhbHVlKHMucHJvcHMudmFsdWUpXG4gICAgfSlcbiAgfSxcblxuICBoYW5kbGVDbGlja0Zvck91dHNpZGUgKGUpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCBub2RlID0gUmVhY3RET00uZmluZERPTU5vZGUocylcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBsZXQgY29udGFpbmVkID0gbm9kZS5jb250YWlucyhlLnRhcmdldClcbiAgICBpZiAoIWNvbnRhaW5lZCkge1xuICAgICAgcy5vdXRzaWRlRGlkVGFwKGUpXG4gICAgfVxuICB9LFxuXG4gIG91dHNpZGVEaWRUYXAgKGUpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIHMuc2V0Rm9jdXMoZmFsc2UpXG4gIH0sXG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIEFwTGF5b3V0TWl4aW5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgZ2V0SW5pdGlhbExheW91dHMgKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsaXN0SW5uZXI6IHtcbiAgICAgICAgdHJhbnNmb3JtOiAnaW5pdGlhbCdcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgY2FsY0xheW91dHMgKCkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IHsgaW5uZXJIZWlnaHQsIGlubmVyV2lkdGggfSA9IHdpbmRvd1xuICAgIGxldCB7IGxpc3QgfSA9IHMubm9kZXNcbiAgICBpZiAoIWxpc3QpIHtcbiAgICAgIHJldHVybiB7fVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbGlzdElubmVyOiBzLl9saXN0SW5uZXJMYXlvdXQobGlzdC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgaW5uZXJXaWR0aCwgaW5uZXJIZWlnaHQpXG4gICAgfVxuICB9LFxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBQcml2YXRlXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIF9saXN0SW5uZXJMYXlvdXQgKHJlY3QsIGJvdW5kc1dpZHRoLCBib3VuZHNIZWlnaHQpIHtcbiAgICBsZXQgeCA9IG51bWNhbC5taW4oYm91bmRzV2lkdGggLSByZWN0LnJpZ2h0LCAwKVxuICAgIGxldCB5ID0gbnVtY2FsLm1pbihib3VuZHNIZWlnaHQgLSByZWN0LmJvdHRvbSwgMClcblxuICAgIGxldCBtYXhIZWlnaHQgPSBgJHtudW1jYWwubWluKGJvdW5kc0hlaWdodCwgMjgwKX1weGBcbiAgICByZXR1cm4ge1xuICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlKCR7eH1weCwgJHt5fXB4KWAsXG4gICAgICBtYXhIZWlnaHRcbiAgICB9XG4gIH1cbn0pXG5cbmV4cG9ydCB7IEFwU2VsZWN0IH1cbmV4cG9ydCBkZWZhdWx0IHdpdGhPdXRzaWRlKEFwU2VsZWN0KVxuIl19