diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..12d195e --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["react"] +} diff --git a/.gitignore b/.gitignore index 19c1030..8741fd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules example/build/* coverage +dist +lib diff --git a/dist/npm/README.md b/dist/npm/README.md deleted file mode 100644 index 051b6ae..0000000 --- a/dist/npm/README.md +++ /dev/null @@ -1,289 +0,0 @@ -Typeahead, written using the React.js library. -============================================== - -Features -======== -* Accessibility. -* BiDi support for RTL languages. -* Keyboard navigation. -* Hinting support for the current input value. -* Autocompletion of the hint when possible. -* Custom templates for each option. -* Auto-closing dropdown for the options list. -* **5KB minified+gzipped!** - -Demo -============= -**YouTube** -http://ezequiel.github.io/react-typeahead-component/youtube - -**Netflix** -http://ezequiel.github.io/react-typeahead-component/netflix - -Examples --------- - -**A Netflix autocomplete widget**. - -It uses the [`RxJs`](http://reactive-extensions.github.io/RxJS/) in conjunction with Netflix's API. It also takes from Netflix's newest layout redesign. - -![netflix](https://cloud.githubusercontent.com/assets/368069/8123520/ed4419e8-107f-11e5-8134-d13c22fcf5d2.gif) - -**YouTube's Autocomplete widget**. It uses the [Flux application architecture](https://facebook.github.io/flux/) in conjunction with YouTube's API. - -![youtube11](https://cloud.githubusercontent.com/assets/368069/7670388/3ab8d8ae-fc57-11e4-8fc1-7ff020e76bf1.gif) - -**Yahoo Mail** (this component is used in production by Yahoo Mail). - -![mail11](https://cloud.githubusercontent.com/assets/368069/7670476/137c5960-fc5b-11e4-9b9f-6d125a532239.gif) - - -Getting started ---------------- - -If you're developing using npm and CommonJS modules: -``` -npm i react-typeahead-component -``` -```jsx -var React = require('react'), - Typeahead = require('react-typeahead-component'); - -React.render( - // Pass in the desired props - , - - // Render Typeahead into the container of your choice. - document.body -); -``` - -You may also want to download one of the distributions from the `dist` folder, and load it in the browser that way. A global variable named `Typeahead` will be available to use. - -Class names ------------ - -These are some default classes names provided by the component. You may override and provide your own styling. - -**react-typeahead-container** - * A `div` element containing the entire Typeahead. - -**react-typeahead-input-container** - * A `div` element containing the usertext and hint. - -**react-typeahead-usertext** - * An `input` element containing the usertext. - -**react-typeahead-hint** - * An `input` element containing the hint. - -**react-typeahead-options** - * A `ul` element containing the rendered list of options. - -Available props: ----------------- - -#### *ReactElement* optionTemplate ***required*** -This determines how to render each option. It is required. It should a reference to a ReactElement. It is instantiated for every item in `options`. - -When instantiated, it is passed these props: - - * `index` - The position of this option in the `options` list. - * `data` - The raw data of this option. - * `userInputValue` - The value the user has **actually typed**. - * `inputValue` - Typeahead's current input value. Note: this may be different than `userInputValue`. - * `isSelected` - Is this option currently selected? This will be `true` on when hovered over, or arrowed to. - -**Example**: - -```jsx -// OptionTemplate.jsx -module.exports = React.createClass({ - render: function() { - var bgColor = null; - - // If this option is currently selected, render it with a green background. - if (this.props.isSelected) { - bgColor = { - color: 'green' - }; - } - - return ( -
-

My name is {this.props.data.name}!

-
- ); - } -}); - -// Then in your main app... -var OptionTemplate = require('./OptionTemplate.jsx'); - - -``` -#### *string* inputId ***optional*** -This input id is used for the Typeahead's input element. - -For example, this allows us to associate a label with the Typeahead's input element. Screen readers will then be able to read the label once the Typeahead is focused. - -```jsx - - - -``` - -#### *string* inputName ***optional*** -* This input name is used for the Typeahead's input element. Useful if the Typeahead happens to be inside of a `form` element. - -#### *string* className ***optional*** -* This class name is used for the Typeahead's container. - -#### *string* inputValue ***optional*** -* The input element's `value` attribute. **NOTE**: You must pass this prop to Typeahead display the value. You have control of the current input value. - -#### *array* options ***optional*** -* These options are used when rendering the options list. It can contain data of any type. - -#### *boolean* autoFocus ***optional*** -* If true, the input element is focused on the initial render. - -#### *string* placeholder ***optional*** -* The input element's `placeholder` attribute. - -#### *string* hoverSelect ***optional*** -* By default, hovering over an option causes it to be selected. - -#### *function* onComplete(*event*, *completedInputValue*) ***optional*** -Fires when the user is attempting to complete the input element's hint. If there is no hint, it will not be called. - -This function is called when the user presses the `ArrowRight`, `Tab`, or `End` keys. `ArrowLeft` is used instead of `ArrowRight` **if** the input value is RTL. - -**Example**: - -```jsx -handleComplete: function(event, completedInputValue) { - this.setState({ - inputValue: completedInputValue - }); -} - - -``` - -#### *function* onDropdownOpen() ***optional*** -* Fires when the dropdown is opened. The dropdown opens as soon as something is typed, or up/down arrow keys are pressed, or when the input is focused. - -#### *function* onDropdownClose() ***optional*** -* Fires when the dropdown is closed. The dropdown may be closed when `Escape` or `Enter` is pressed, or if any option is clicked on, or if anywhere outside the Typeahead is clicked. - -#### *function* onChange(*event*) ***optional*** -* Fires when a change occurs on the input element. - -#### *function* onInputClick(*event*) ***optional*** -* Fires when the input element is clicked. - -#### *function* onKeyDown(*event*, optionData, selectedIndex) ***optional*** -Fires when a key down occurs on the input element. -It is also passed the currently selected option, and its index. -If no option is selected, `optionData` is the input value, and `selectedIndex` is `-1`. - -#### *function* onKeyPress(*event*) ***optional*** -* Fires when a key press occurs on the input element. - -#### *function* onKeyUp(*event*) ***optional*** -* Fires when a key up occurs on the input element. - -#### *function* onFocus(*event*) ***optional*** -* Fires when the input element is focused. - -#### *function* onBlur(*event*) ***optional*** -* Fires when the input element is blurred. - -#### *function* onSelect(*event*) ***optional*** -* Fires when the input element's text is selected. - -#### *function* onOptionClick(*event*, optionData, index) ***optional*** -* Fires when an option is clicked. `optionData` is the option that was clicked. - -#### *function* onOptionChange(*event*, optionData, index) ***optional*** -* Fires when the user arrows up or down to an option. It is also called if the user arrows back to the input element, and in that case `index` is `-1`. `optionData` is the option, or input text, data that has been navigated to. - -#### *function* handleHint(inputValue, options) ***optional*** -This function determines what the hint is. It is called whenever the input has changed. If a hint is considered available, it should return the entire string, otherwise return a default string. - -**Example**: - -```jsx -handleHint: function(inputValue, options) { - // If the current input value matches the first option, - // return that option. It will be used to display the hint. - if (new RegExp('^' + inputValue).test(options[0].first_name)) { - - // This must return a string! - return options[0].first_name; - } - - // No hint is available. - return ''; -} - -// Now pass it as a prop... - -``` - -#### *function* getMessageForOption(*optionData*) ***optional*** -This is for accessibility. It is called when an option is clicked or arrowed to. `optionData` is the option we're currently on. The return value is then read by the screen reader. It is also called if the user arrows back to the input element. The string returned should be localized so it is read in the correct language. - -```js -getMessageForOption: function(optionData) { - - switch (optionData.type) { - case 'PERSON': - return 'Search for the person ' + optionData.name; - - case 'PLACE': - return 'Search for the place ' + optionData.name; - - default: - return 'Search for the thing ' + optionData.name; - } -} -``` - -#### *function* getMessageForIncomingOptions() ***optional*** -This is for accessibility. It is called when a new set of options is passed into Typeahead. The return value is then read by the screen reader. The string returned should be localized so it is read in the correct language. - -```js -getMessageForIncomingOptions: function() { - return 'There are new options available. Use the up and down arrows to navigate.'; -} -``` - -Don't see your prop? [Create an issue](https://github.com/ezequiel/react-typeahead-component/issues/new?title=Missing%20prop) explaining your use case, and I will add it. - -Testing -------- -The tests are written using [mocha](https://github.com/mochajs/mocha), and ran using [Karma](https://github.com/karma-runner/karma). Run the command `npm test` to perform a single run of the tests in PhantomJS, and `npm run test:dev` to debug the tests in Chrome. - -Issues ------- -Please [file an issue](https://github.com/ezequiel/react-typeahead-component/issues/new) if you find a bug, or need help. - -License -------- -The MIT License (MIT) -Copyright (c) 2015 Ezequiel Rodriguez diff --git a/dist/npm/components/aria_status.js b/dist/npm/components/aria_status.js deleted file mode 100644 index 85b142b..0000000 --- a/dist/npm/components/aria_status.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -var React = require('react'); - -module.exports = React.createClass({ - displayName: 'Aria Status', - - propTypes: process.env.NODE_ENV === 'production' ? {} : { - message: React.PropTypes.string - }, - - componentDidMount: function() { - var _this = this; - - // This is needed as `componentDidUpdate` - // does not fire on the initial render. - _this.setTextContent(_this.props.message); - }, - - componentDidUpdate: function() { - var _this = this; - - _this.setTextContent(_this.props.message); - }, - - render: function() { - return ( - React.createElement("span", { - role: "status", - "aria-live": "polite", - style: { - left: '-9999px', - position: 'absolute' - }} - ) - ); - }, - - // We cannot set `textContent` directly in `render`, - // because React adds/deletes text nodes when rendering, - // which confuses screen readers and doesn't cause them to read changes. - setTextContent: function(textContent) { - // We could set `innerHTML`, but it's better to avoid it. - this.getDOMNode().textContent = textContent || ''; - } -}); diff --git a/dist/npm/components/input.js b/dist/npm/components/input.js deleted file mode 100644 index d77c89e..0000000 --- a/dist/npm/components/input.js +++ /dev/null @@ -1,71 +0,0 @@ -'use strict'; - -var React = require('react'); - -module.exports = React.createClass({ - displayName: 'Input', - - propTypes: process.env.NODE_ENV === 'production' ? {} : { - value: React.PropTypes.string, - onChange: React.PropTypes.func - }, - - getDefaultProps: function() { - return { - value: '', - onChange: function() {} - }; - }, - - componentDidUpdate: function() { - var _this = this, - dir = _this.props.dir; - - if (dir === null || dir === undefined) { - // When setting an attribute to null/undefined, - // React instead sets the attribute to an empty string. - - // This is not desired because of a possible bug in Chrome. - // If the page is RTL, and the input's `dir` attribute is set - // to an empty string, Chrome assumes LTR, which isn't what we want. - React.findDOMNode(_this).removeAttribute('dir'); - } - }, - - render: function() { - var _this = this; - - return ( - React.createElement("input", React.__spread({}, - _this.props, - {onChange: _this.handleChange}) - ) - ); - }, - - handleChange: function(event) { - var props = this.props; - - // There are several React bugs in IE, - // where the `input`'s `onChange` event is - // fired even when the value didn't change. - // https://github.com/facebook/react/issues/2185 - // https://github.com/facebook/react/issues/3377 - if (event.target.value !== props.value) { - props.onChange(event); - } - }, - - blur: function() { - React.findDOMNode(this).blur(); - }, - - isCursorAtEnd: function() { - var _this = this, - inputDOMNode = React.findDOMNode(_this), - valueLength = _this.props.value.length; - - return inputDOMNode.selectionStart === valueLength && - inputDOMNode.selectionEnd === valueLength; - } -}); diff --git a/dist/npm/components/typeahead.js b/dist/npm/components/typeahead.js deleted file mode 100644 index 7ee4095..0000000 --- a/dist/npm/components/typeahead.js +++ /dev/null @@ -1,510 +0,0 @@ -'use strict'; - -var React = require('react'), - Input = require('./input'), - AriaStatus = require('./aria_status'), - getTextDirection = require('../utils/get_text_direction'), - noop = function() {}; - -module.exports = React.createClass({ - displayName: 'Typeahead', - - statics: { - getInstanceCount: (function() { - var count = 0; - - return function() { - return ++count; - }; - }()) - }, - - propTypes: process.env.NODE_ENV === 'production' ? {} : { - inputId: React.PropTypes.string, - inputName: React.PropTypes.string, - className: React.PropTypes.string, - autoFocus: React.PropTypes.bool, - hoverSelect: React.PropTypes.bool, - inputValue: React.PropTypes.string, - options: React.PropTypes.array, - placeholder: React.PropTypes.string, - onChange: React.PropTypes.func, - onKeyDown: React.PropTypes.func, - onKeyPress: React.PropTypes.func, - onKeyUp: React.PropTypes.func, - onFocus: React.PropTypes.func, - onBlur: React.PropTypes.func, - onSelect: React.PropTypes.func, - onInputClick: React.PropTypes.func, - handleHint: React.PropTypes.func, - onComplete: React.PropTypes.func, - onOptionClick: React.PropTypes.func, - onOptionChange: React.PropTypes.func, - onDropdownOpen: React.PropTypes.func, - onDropdownClose: React.PropTypes.func, - optionTemplate: React.PropTypes.func.isRequired, - getMessageForOption: React.PropTypes.func, - getMessageForIncomingOptions: React.PropTypes.func - }, - - getDefaultProps: function() { - return { - className: '', - inputValue: '', - options: [], - hoverSelect: true, - onFocus: noop, - onKeyDown: noop, - onChange: noop, - onInputClick: noop, - handleHint: function() { - return ''; - }, - onOptionClick: noop, - onOptionChange: noop, - onComplete: noop, - onDropdownOpen: noop, - onDropdownClose: noop, - getMessageForOption: function() { - return ''; - }, - getMessageForIncomingOptions: function(number) { - return ( - number + ' suggestions are available. Use up and down arrows to select.' - ); - } - }; - }, - - getInitialState: function() { - return { - selectedIndex: -1, - isHintVisible: false, - isDropdownVisible: false - }; - }, - - componentWillMount: function() { - var _this = this, - uniqueId = this.constructor.getInstanceCount(); - - _this.userInputValue = null; - _this.previousInputValue = null; - _this.activeDescendantId = 'react-typeahead-activedescendant-' + uniqueId; - _this.optionsId = 'react-typeahead-options-' + uniqueId; - }, - - componentDidMount: function() { - var addEvent = window.addEventListener, - handleWindowClose = this.handleWindowClose; - - // The `focus` event does not bubble, so we must capture it instead. - // This closes Typeahead's dropdown whenever something else gains focus. - addEvent('focus', handleWindowClose, true); - - // If we click anywhere outside of Typeahead, close the dropdown. - addEvent('click', handleWindowClose, false); - }, - - componentWillUnmount: function() { - var removeEvent = window.removeEventListener, - handleWindowClose = this.handleWindowClose; - - removeEvent('focus', handleWindowClose, true); - removeEvent('click', handleWindowClose, false); - }, - - componentWillReceiveProps: function(nextProps) { - var nextValue = nextProps.inputValue, - nextOptions = nextProps.options, - valueLength = nextValue.length, - isHintVisible = valueLength > 0 && - // A visible part of the hint must be - // available for us to complete it. - nextProps.handleHint(nextValue, nextOptions).slice(valueLength).length > 0; - - this.setState({ - isHintVisible: isHintVisible - }); - }, - - render: function() { - var _this = this; - - return ( - React.createElement("div", { - style: { - position: 'relative' - }, - className: 'react-typeahead-container ' + _this.props.className}, - _this.renderInput(), - _this.renderDropdown(), - _this.renderAriaMessageForOptions(), - _this.renderAriaMessageForIncomingOptions() - ) - ); - }, - - renderInput: function() { - var _this = this, - state = _this.state, - props = _this.props, - inputValue = props.inputValue, - className = 'react-typeahead-input', - inputDirection = getTextDirection(inputValue); - - return ( - React.createElement("div", { - style: { - position: 'relative' - }, - className: "react-typeahead-input-container"}, - React.createElement(Input, { - disabled: true, - role: "presentation", - "aria-hidden": true, - dir: inputDirection, - className: className + ' react-typeahead-hint', - style: { - color: 'silver', - WebkitTextFillColor: 'silver', - position: 'absolute' - }, - value: state.isHintVisible ? props.handleHint(inputValue, props.options) : null} - ), - React.createElement(Input, { - ref: "input", - role: "combobox", - "aria-owns": _this.optionsId, - "aria-expanded": state.isDropdownVisible, - "aria-autocomplete": "both", - "aria-activedescendant": _this.activeDescendantId, - value: inputValue, - spellCheck: false, - autoComplete: false, - autoCorrect: false, - dir: inputDirection, - onClick: _this.handleClick, - onFocus: _this.handleFocus, - onBlur: props.onBlur, - onChange: _this.handleChange, - onKeyDown: _this.handleKeyDown, - id: props.inputId, - name: props.inputName, - autoFocus: props.autoFocus, - placeholder: props.placeholder, - onSelect: props.onSelect, - onKeyUp: props.onKeyUp, - onKeyPress: props.onKeyPress, - className: className + ' react-typeahead-usertext', - style: { - position: 'relative', - background: 'transparent' - }} - ) - ) - ); - }, - - renderDropdown: function() { - var _this = this, - state = _this.state, - props = _this.props, - OptionTemplate = props.optionTemplate, - selectedIndex = state.selectedIndex, - isDropdownVisible = state.isDropdownVisible, - activeDescendantId = _this.activeDescendantId; - - if (this.props.options.length < 1) { - return null; - } - - return ( - React.createElement("ul", {id: _this.optionsId, - ref: "dropdown", - role: "listbox", - "aria-hidden": !isDropdownVisible, - style: { - width: '100%', - background: '#fff', - position: 'absolute', - boxSizing: 'border-box', - display: isDropdownVisible ? 'block' : 'none' - }, - className: "react-typeahead-options", - onMouseOut: this.handleMouseOut}, - - props.options.map(function(data, index) { - var isSelected = selectedIndex === index; - - return ( - React.createElement("li", {id: isSelected ? activeDescendantId : null, - "aria-selected": isSelected, - role: "option", - key: index, - onClick: _this.handleOptionClick.bind(_this, index), - onMouseOver: _this.handleOptionMouseOver.bind(_this, index)}, - - React.createElement(OptionTemplate, { - data: data, - index: index, - userInputValue: _this.userInputValue, - inputValue: props.inputValue, - isSelected: isSelected} - ) - ) - ); - }) - - ) - ); - }, - - renderAriaMessageForOptions: function() { - var _this = this, - props = _this.props, - inputValue = props.inputValue, - option = props.options[_this.state.selectedIndex] || inputValue; - - return ( - React.createElement(AriaStatus, { - message: props.getMessageForOption(option) || inputValue} - ) - ); - }, - - renderAriaMessageForIncomingOptions: function() { - var props = this.props; - - return ( - React.createElement(AriaStatus, { - message: props.getMessageForIncomingOptions(props.options.length)} - ) - ); - }, - - showDropdown: function() { - var _this = this; - - if (!_this.state.isDropdownVisible) { - _this.setState({ - isDropdownVisible: true - }, function() { - _this.props.onDropdownOpen(); - }); - } - }, - - hideDropdown: function() { - var _this = this; - - if (_this.state.isDropdownVisible) { - _this.setState({ - isDropdownVisible: false - }, function() { - _this.props.onDropdownClose(); - }); - } - }, - - showHint: function() { - var _this = this, - props = _this.props, - inputValue = props.inputValue, - inputValueLength = inputValue.length, - isHintVisible = inputValueLength > 0 && - // A visible part of the hint must be - // available for us to complete it. - props.handleHint(inputValue, props.options).slice(inputValueLength).length > 0; - - _this.setState({ - isHintVisible: isHintVisible - }); - }, - - hideHint: function() { - this.setState({ - isHintVisible: false - }); - }, - - setSelectedIndex: function(index, callback) { - this.setState({ - selectedIndex: index - }, callback); - }, - - handleChange: function(event) { - var _this = this; - - _this.showHint(); - _this.showDropdown(); - _this.setSelectedIndex(-1); - _this.props.onChange(event); - _this.userInputValue = event.target.value; - }, - - focus: function() { - this.refs.input.getDOMNode().focus(); - }, - - handleFocus: function(event) { - var _this = this; - - _this.showDropdown(); - _this.props.onFocus(event); - }, - - handleClick: function(event) { - var _this = this; - - _this.showHint(); - _this.props.onInputClick(event); - }, - - navigate: function(direction, callback) { - var _this = this, - minIndex = -1, - maxIndex = _this.props.options.length - 1, - index = _this.state.selectedIndex + direction; - - if (index > maxIndex) { - index = minIndex; - } else if (index < minIndex) { - index = maxIndex; - } - - _this.setSelectedIndex(index, callback); - }, - - handleKeyDown: function(event) { - var _this = this, - key = event.key, - props = _this.props, - input = _this.refs.input, - isDropdownVisible = _this.state.isDropdownVisible, - isHintVisible = _this.state.isHintVisible, - hasHandledKeyDown = false, - index, - optionData, - dir; - - switch (key) { - case 'End': - case 'Tab': - if (isHintVisible && !event.shiftKey) { - event.preventDefault(); - props.onComplete(event, props.handleHint(props.inputValue, props.options)); - } - break; - case 'ArrowLeft': - case 'ArrowRight': - if (isHintVisible && !event.shiftKey && input.isCursorAtEnd()) { - dir = getTextDirection(props.inputValue); - - if ((dir === 'ltr' && key === 'ArrowRight') || (dir === 'rtl' && key === 'ArrowLeft')) { - props.onComplete(event, props.handleHint(props.inputValue, props.options)); - } - } - break; - case 'Enter': - _this.focus(); - _this.hideHint(); - _this.hideDropdown(); - break; - case 'Escape': - _this.hideHint(); - _this.hideDropdown(); - break; - case 'ArrowUp': - case 'ArrowDown': - if (props.options.length > 0) { - event.preventDefault(); - - _this.showHint(); - _this.showDropdown(); - - if (isDropdownVisible) { - dir = key === 'ArrowUp' ? -1: 1; - hasHandledKeyDown = true; - - _this.navigate(dir, function() { - var selectedIndex = _this.state.selectedIndex, - previousInputValue = _this.previousInputValue, - optionData = previousInputValue, - optionOffsetTop = 0, - selectedOption, - dropdown; - - // We're currently on an option. - if (selectedIndex >= 0) { - // Save the current `input` value, - // as we might arrow back to it later. - if (previousInputValue === null) { - _this.previousInputValue = props.inputValue; - } - - optionData = props.options[selectedIndex]; - // Make selected option always scroll to visible - dropdown = React.findDOMNode(_this.refs.dropdown); - selectedOption = dropdown.children[selectedIndex]; - optionOffsetTop = selectedOption.offsetTop; - if(optionOffsetTop + selectedOption.clientHeight > dropdown.clientHeight || - optionOffsetTop < dropdown.scrollTop) { - dropdown.scrollTop = optionOffsetTop; - } - } - - props.onOptionChange(event, optionData, selectedIndex); - props.onKeyDown(event, optionData, selectedIndex); - }); - } - } - - break; - } - - if (!hasHandledKeyDown) { - index = this.state.selectedIndex; - optionData = index < 0 ? props.inputValue : props.options[index]; - props.onKeyDown(event, optionData, index); - } - }, - - handleOptionClick: function(selectedIndex, event) { - var _this = this, - props = _this.props; - - _this.focus(); - _this.hideHint(); - _this.hideDropdown(); - _this.setSelectedIndex(selectedIndex); - props.onOptionClick(event, props.options[selectedIndex], selectedIndex); - }, - - handleOptionMouseOver: function(selectedIndex) { - var _this = this; - - if (_this.props.hoverSelect) { - _this.setSelectedIndex(selectedIndex); - } - }, - - handleMouseOut: function() { - var _this = this; - - if (_this.props.hoverSelect) { - _this.setSelectedIndex(-1); - } - }, - - handleWindowClose: function(event) { - var _this = this, - target = event.target; - - if (target !== window && !this.getDOMNode().contains(target)) { - _this.hideHint(); - _this.hideDropdown(); - } - } -}); diff --git a/dist/npm/index.js b/dist/npm/index.js deleted file mode 100644 index f73b85b..0000000 --- a/dist/npm/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./components/typeahead'); diff --git a/dist/npm/package.json b/dist/npm/package.json deleted file mode 100644 index 704a76a..0000000 --- a/dist/npm/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "react-typeahead-component", - "description": "Typeahead, written using the React.js library.", - "author": "Ezequiel Rodriguez ", - "version": "0.9.0", - "main": "index.js", - "license": "MIT", - "bugs": "https://github.com/ezequiel/react-typeahead-component/issues", - "repository": { - "type": "git", - "url": "https://github.com/ezequiel/react-typeahead-component.git" - }, - "keywords": [ - "react", - "reactjs", - "typeahead", - "autocomplete", - "react-component", - "component" - ], - "peerDependencies": { - "react": ">=0.13.1 <1.0.0" - } -} diff --git a/dist/npm/utils/get_text_direction.js b/dist/npm/utils/get_text_direction.js deleted file mode 100644 index 9181392..0000000 --- a/dist/npm/utils/get_text_direction.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -var RTLCharactersRegExp = require('./rtl_chars_regexp'), - NeutralCharactersRegExp = require('./neutral_chars_regexp'), - startsWithRTL = new RegExp('^(?:' + NeutralCharactersRegExp + ')*(?:' + RTLCharactersRegExp + ')'), - neutralText = new RegExp('^(?:' + NeutralCharactersRegExp + ')*$'); - -module.exports = function(text) { - var dir = 'ltr'; - - if (startsWithRTL.test(text)) { - dir = 'rtl'; - } else if (neutralText.test(text)) { - dir = null; - } - - return dir; -}; diff --git a/dist/npm/utils/neutral_chars_regexp.js b/dist/npm/utils/neutral_chars_regexp.js deleted file mode 100644 index 737e1f8..0000000 --- a/dist/npm/utils/neutral_chars_regexp.js +++ /dev/null @@ -1,10 +0,0 @@ -// DO NOT EDIT! -// THIS FILE IS GENERATED! - -// All bidi characters except those found in classes 'L' (LTR), 'R' (RTL), and 'AL' (RTL Arabic) as per Unicode 7.0.0. - -// jshint ignore:start -// jscs:disable maximumLineLength -module.exports = '[\0-@\[-`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02B9\u02BA\u02C2-\u02CF\u02D2-\u02DF\u02E5-\u02ED\u02EF-\u036F\u0374\u0375\u037E\u0384\u0385\u0387\u03F6\u0483-\u0489\u058A\u058D-\u058F\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0600-\u0607\u0609\u060A\u060C\u060E-\u061A\u064B-\u066C\u0670\u06D6-\u06E4\u06E7-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07F6-\u07F9\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2\u09E3\u09F2\u09F3\u09FB\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AF1\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0BF3-\u0BFA\u0C00\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C78-\u0C7E\u0C81\u0CBC\u0CCC\u0CCD\u0CE2\u0CE3\u0D01\u0D41-\u0D44\u0D4D\u0D62\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E3F\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39-\u0F3D\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1390-\u1399\u1400\u1680\u169B\u169C\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DB\u17DD\u17F0-\u17F9\u1800-\u180E\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1940\u1944\u1945\u19DE-\u19FF\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2000-\u200D\u2010-\u2029\u202F-\u2064\u2068\u206A-\u2070\u2074-\u207E\u2080-\u208E\u20A0-\u20BD\u20D0-\u20F0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u2150-\u215F\u2189\u2190-\u2335\u237B-\u2394\u2396-\u23FA\u2400-\u2426\u2440-\u244A\u2460-\u249B\u24EA-\u26AB\u26AD-\u27FF\u2900-\u2B73\u2B76-\u2B95\u2B98-\u2BB9\u2BBD-\u2BC8\u2BCA-\u2BD1\u2CE5-\u2CEA\u2CEF-\u2CF1\u2CF9-\u2CFF\u2D7F\u2DE0-\u2E42\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u3004\u3008-\u3020\u302A-\u302D\u3030\u3036\u3037\u303D-\u303F\u3099-\u309C\u30A0\u30FB\u31C0-\u31E3\u321D\u321E\u3250-\u325F\u327C-\u327E\u32B1-\u32BF\u32CC-\u32CF\u3377-\u337A\u33DE\u33DF\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA60D-\uA60F\uA66F-\uA67F\uA69F\uA6F0\uA6F1\uA700-\uA721\uA788\uA802\uA806\uA80B\uA825\uA826\uA828-\uA82B\uA838\uA839\uA874-\uA877\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFB29\uFD3E\uFD3F\uFDFD\uFE00-\uFE19\uFE20-\uFE2D\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFEFF\uFF01-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFF9-\uFFFD]|\uD800[\uDD01\uDD40-\uDD8C\uDD90-\uDD9B\uDDA0\uDDFD\uDEE0-\uDEFB\uDF76-\uDF7A]|\uD802[\uDD1F\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6\uDF39-\uDF3F]|\uD803[\uDE60-\uDE7E]|[\uD804\uDB40][\uDC01\uDC38-\uDC46\uDC52-\uDC65\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDEDF\uDEE3-\uDEEA\uDF01\uDF3C\uDF40\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB3-\uDCB8\uDCBA\uDCBF\uDCC0\uDCC2\uDCC3\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E\uDCA0-\uDCA3]|\uD834[\uDD67-\uDD69\uDD73-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE00-\uDE45\uDF00-\uDF56]|\uD835[\uDEDB\uDF15\uDF4F\uDF89\uDFC3\uDFCE-\uDFFF]|\uD83A[\uDCD0-\uDCD6]|\uD83B[\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD00-\uDD0C\uDD6A\uDD6B\uDF00-\uDF2C\uDF30-\uDF7D\uDF80-\uDFCE\uDFD4-\uDFF7]|\uD83D[\uDC00-\uDCFE\uDD00-\uDD4A\uDD50-\uDD79\uDD7B-\uDDA3\uDDA5-\uDE42\uDE45-\uDECF\uDEE0-\uDEEC\uDEF0-\uDEF3\uDF00-\uDF73\uDF80-\uDFD4]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD]'; -// jscs:enable maximumLineLength -// jshint ignore:end diff --git a/dist/npm/utils/rtl_chars_regexp.js b/dist/npm/utils/rtl_chars_regexp.js deleted file mode 100644 index fbe7824..0000000 --- a/dist/npm/utils/rtl_chars_regexp.js +++ /dev/null @@ -1,10 +0,0 @@ -// DO NOT EDIT! -// THIS FILE IS GENERATED! - -// All bidi characters found in classes 'R', 'AL', 'RLE', 'RLO', and 'RLI' as per Unicode 7.0.0. - -// jshint ignore:start -// jscs:disable maximumLineLength -module.exports = '[\u05BE\u05C0\u05C3\u05C6\u05D0-\u05EA\u05F0-\u05F4\u0608\u060B\u060D\u061B\u061C\u061E-\u064A\u066D-\u066F\u0671-\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u070D\u070F\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0830-\u083E\u0840-\u0858\u085E\u08A0-\u08B2\u200F\u202B\u202E\u2067\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBC1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFC\uFE70-\uFE74\uFE76-\uFEFC]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC57-\uDC9E\uDCA7-\uDCAF\uDD00-\uDD1B\uDD20-\uDD39\uDD3F\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE40-\uDE47\uDE50-\uDE58\uDE60-\uDE9F\uDEC0-\uDEE4\uDEEB-\uDEF6\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDF99-\uDF9C\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]'; -// jscs:enable maximumLineLength -// jshint ignore:end diff --git a/dist/react-typeahead-component.dev.js b/dist/react-typeahead-component.dev.js deleted file mode 100644 index c6b561f..0000000 --- a/dist/react-typeahead-component.dev.js +++ /dev/null @@ -1,759 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Typeahead = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && - // A visible part of the hint must be - // available for us to complete it. - nextProps.handleHint(nextValue, nextOptions).slice(valueLength).length > 0; - - this.setState({ - isHintVisible: isHintVisible - }); - }, - - render: function() { - var _this = this; - - return ( - React.createElement("div", { - style: { - position: 'relative' - }, - className: 'react-typeahead-container ' + _this.props.className}, - _this.renderInput(), - _this.renderDropdown(), - _this.renderAriaMessageForOptions(), - _this.renderAriaMessageForIncomingOptions() - ) - ); - }, - - renderInput: function() { - var _this = this, - state = _this.state, - props = _this.props, - inputValue = props.inputValue, - className = 'react-typeahead-input', - inputDirection = getTextDirection(inputValue); - - return ( - React.createElement("div", { - style: { - position: 'relative' - }, - className: "react-typeahead-input-container"}, - React.createElement(Input, { - disabled: true, - role: "presentation", - "aria-hidden": true, - dir: inputDirection, - className: className + ' react-typeahead-hint', - style: { - color: 'silver', - WebkitTextFillColor: 'silver', - position: 'absolute' - }, - value: state.isHintVisible ? props.handleHint(inputValue, props.options) : null} - ), - React.createElement(Input, { - ref: "input", - role: "combobox", - "aria-owns": _this.optionsId, - "aria-expanded": state.isDropdownVisible, - "aria-autocomplete": "both", - "aria-activedescendant": _this.activeDescendantId, - value: inputValue, - spellCheck: false, - autoComplete: false, - autoCorrect: false, - dir: inputDirection, - onClick: _this.handleClick, - onFocus: _this.handleFocus, - onBlur: props.onBlur, - onChange: _this.handleChange, - onKeyDown: _this.handleKeyDown, - id: props.inputId, - name: props.inputName, - autoFocus: props.autoFocus, - placeholder: props.placeholder, - onSelect: props.onSelect, - onKeyUp: props.onKeyUp, - onKeyPress: props.onKeyPress, - className: className + ' react-typeahead-usertext', - style: { - position: 'relative', - background: 'transparent' - }} - ) - ) - ); - }, - - renderDropdown: function() { - var _this = this, - state = _this.state, - props = _this.props, - OptionTemplate = props.optionTemplate, - selectedIndex = state.selectedIndex, - isDropdownVisible = state.isDropdownVisible, - activeDescendantId = _this.activeDescendantId; - - if (this.props.options.length < 1) { - return null; - } - - return ( - React.createElement("ul", {id: _this.optionsId, - ref: "dropdown", - role: "listbox", - "aria-hidden": !isDropdownVisible, - style: { - width: '100%', - background: '#fff', - position: 'absolute', - boxSizing: 'border-box', - display: isDropdownVisible ? 'block' : 'none' - }, - className: "react-typeahead-options", - onMouseOut: this.handleMouseOut}, - - props.options.map(function(data, index) { - var isSelected = selectedIndex === index; - - return ( - React.createElement("li", {id: isSelected ? activeDescendantId : null, - "aria-selected": isSelected, - role: "option", - key: index, - onClick: _this.handleOptionClick.bind(_this, index), - onMouseOver: _this.handleOptionMouseOver.bind(_this, index)}, - - React.createElement(OptionTemplate, { - data: data, - index: index, - userInputValue: _this.userInputValue, - inputValue: props.inputValue, - isSelected: isSelected} - ) - ) - ); - }) - - ) - ); - }, - - renderAriaMessageForOptions: function() { - var _this = this, - props = _this.props, - inputValue = props.inputValue, - option = props.options[_this.state.selectedIndex] || inputValue; - - return ( - React.createElement(AriaStatus, { - message: props.getMessageForOption(option) || inputValue} - ) - ); - }, - - renderAriaMessageForIncomingOptions: function() { - var props = this.props; - - return ( - React.createElement(AriaStatus, { - message: props.getMessageForIncomingOptions(props.options.length)} - ) - ); - }, - - showDropdown: function() { - var _this = this; - - if (!_this.state.isDropdownVisible) { - _this.setState({ - isDropdownVisible: true - }, function() { - _this.props.onDropdownOpen(); - }); - } - }, - - hideDropdown: function() { - var _this = this; - - if (_this.state.isDropdownVisible) { - _this.setState({ - isDropdownVisible: false - }, function() { - _this.props.onDropdownClose(); - }); - } - }, - - showHint: function() { - var _this = this, - props = _this.props, - inputValue = props.inputValue, - inputValueLength = inputValue.length, - isHintVisible = inputValueLength > 0 && - // A visible part of the hint must be - // available for us to complete it. - props.handleHint(inputValue, props.options).slice(inputValueLength).length > 0; - - _this.setState({ - isHintVisible: isHintVisible - }); - }, - - hideHint: function() { - this.setState({ - isHintVisible: false - }); - }, - - setSelectedIndex: function(index, callback) { - this.setState({ - selectedIndex: index - }, callback); - }, - - handleChange: function(event) { - var _this = this; - - _this.showHint(); - _this.showDropdown(); - _this.setSelectedIndex(-1); - _this.props.onChange(event); - _this.userInputValue = event.target.value; - }, - - focus: function() { - this.refs.input.getDOMNode().focus(); - }, - - handleFocus: function(event) { - var _this = this; - - _this.showDropdown(); - _this.props.onFocus(event); - }, - - handleClick: function(event) { - var _this = this; - - _this.showHint(); - _this.props.onInputClick(event); - }, - - navigate: function(direction, callback) { - var _this = this, - minIndex = -1, - maxIndex = _this.props.options.length - 1, - index = _this.state.selectedIndex + direction; - - if (index > maxIndex) { - index = minIndex; - } else if (index < minIndex) { - index = maxIndex; - } - - _this.setSelectedIndex(index, callback); - }, - - handleKeyDown: function(event) { - var _this = this, - key = event.key, - props = _this.props, - input = _this.refs.input, - isDropdownVisible = _this.state.isDropdownVisible, - isHintVisible = _this.state.isHintVisible, - hasHandledKeyDown = false, - index, - optionData, - dir; - - switch (key) { - case 'End': - case 'Tab': - if (isHintVisible && !event.shiftKey) { - event.preventDefault(); - props.onComplete(event, props.handleHint(props.inputValue, props.options)); - } - break; - case 'ArrowLeft': - case 'ArrowRight': - if (isHintVisible && !event.shiftKey && input.isCursorAtEnd()) { - dir = getTextDirection(props.inputValue); - - if ((dir === 'ltr' && key === 'ArrowRight') || (dir === 'rtl' && key === 'ArrowLeft')) { - props.onComplete(event, props.handleHint(props.inputValue, props.options)); - } - } - break; - case 'Enter': - _this.focus(); - _this.hideHint(); - _this.hideDropdown(); - break; - case 'Escape': - _this.hideHint(); - _this.hideDropdown(); - break; - case 'ArrowUp': - case 'ArrowDown': - if (props.options.length > 0) { - event.preventDefault(); - - _this.showHint(); - _this.showDropdown(); - - if (isDropdownVisible) { - dir = key === 'ArrowUp' ? -1: 1; - hasHandledKeyDown = true; - - _this.navigate(dir, function() { - var selectedIndex = _this.state.selectedIndex, - previousInputValue = _this.previousInputValue, - optionData = previousInputValue, - optionOffsetTop = 0, - selectedOption, - dropdown; - - // We're currently on an option. - if (selectedIndex >= 0) { - // Save the current `input` value, - // as we might arrow back to it later. - if (previousInputValue === null) { - _this.previousInputValue = props.inputValue; - } - - optionData = props.options[selectedIndex]; - // Make selected option always scroll to visible - dropdown = React.findDOMNode(_this.refs.dropdown); - selectedOption = dropdown.children[selectedIndex]; - optionOffsetTop = selectedOption.offsetTop; - if(optionOffsetTop + selectedOption.clientHeight > dropdown.clientHeight || - optionOffsetTop < dropdown.scrollTop) { - dropdown.scrollTop = optionOffsetTop; - } - } - - props.onOptionChange(event, optionData, selectedIndex); - props.onKeyDown(event, optionData, selectedIndex); - }); - } - } - - break; - } - - if (!hasHandledKeyDown) { - index = this.state.selectedIndex; - optionData = index < 0 ? props.inputValue : props.options[index]; - props.onKeyDown(event, optionData, index); - } - }, - - handleOptionClick: function(selectedIndex, event) { - var _this = this, - props = _this.props; - - _this.focus(); - _this.hideHint(); - _this.hideDropdown(); - _this.setSelectedIndex(selectedIndex); - props.onOptionClick(event, props.options[selectedIndex], selectedIndex); - }, - - handleOptionMouseOver: function(selectedIndex) { - var _this = this; - - if (_this.props.hoverSelect) { - _this.setSelectedIndex(selectedIndex); - } - }, - - handleMouseOut: function() { - var _this = this; - - if (_this.props.hoverSelect) { - _this.setSelectedIndex(-1); - } - }, - - handleWindowClose: function(event) { - var _this = this, - target = event.target; - - if (target !== window && !this.getDOMNode().contains(target)) { - _this.hideHint(); - _this.hideDropdown(); - } - } -}); - - -}).call(this,require('_process')) - -},{"../utils/get_text_direction":6,"./aria_status.jsx":2,"./input.jsx":3,"_process":1,"react":"react"}],5:[function(require,module,exports){ -module.exports = require('./components/typeahead.jsx'); - - -},{"./components/typeahead.jsx":4}],6:[function(require,module,exports){ -'use strict'; - -var RTLCharactersRegExp = require('./rtl_chars_regexp'), - NeutralCharactersRegExp = require('./neutral_chars_regexp'), - startsWithRTL = new RegExp('^(?:' + NeutralCharactersRegExp + ')*(?:' + RTLCharactersRegExp + ')'), - neutralText = new RegExp('^(?:' + NeutralCharactersRegExp + ')*$'); - -module.exports = function(text) { - var dir = 'ltr'; - - if (startsWithRTL.test(text)) { - dir = 'rtl'; - } else if (neutralText.test(text)) { - dir = null; - } - - return dir; -}; - - -},{"./neutral_chars_regexp":7,"./rtl_chars_regexp":8}],7:[function(require,module,exports){ -// DO NOT EDIT! -// THIS FILE IS GENERATED! - -// All bidi characters except those found in classes 'L' (LTR), 'R' (RTL), and 'AL' (RTL Arabic) as per Unicode 7.0.0. - -// jshint ignore:start -// jscs:disable maximumLineLength -module.exports = '[\0-@\[-`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02B9\u02BA\u02C2-\u02CF\u02D2-\u02DF\u02E5-\u02ED\u02EF-\u036F\u0374\u0375\u037E\u0384\u0385\u0387\u03F6\u0483-\u0489\u058A\u058D-\u058F\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0600-\u0607\u0609\u060A\u060C\u060E-\u061A\u064B-\u066C\u0670\u06D6-\u06E4\u06E7-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07F6-\u07F9\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2\u09E3\u09F2\u09F3\u09FB\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AF1\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0BF3-\u0BFA\u0C00\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C78-\u0C7E\u0C81\u0CBC\u0CCC\u0CCD\u0CE2\u0CE3\u0D01\u0D41-\u0D44\u0D4D\u0D62\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E3F\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39-\u0F3D\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1390-\u1399\u1400\u1680\u169B\u169C\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DB\u17DD\u17F0-\u17F9\u1800-\u180E\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1940\u1944\u1945\u19DE-\u19FF\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2000-\u200D\u2010-\u2029\u202F-\u2064\u2068\u206A-\u2070\u2074-\u207E\u2080-\u208E\u20A0-\u20BD\u20D0-\u20F0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u2150-\u215F\u2189\u2190-\u2335\u237B-\u2394\u2396-\u23FA\u2400-\u2426\u2440-\u244A\u2460-\u249B\u24EA-\u26AB\u26AD-\u27FF\u2900-\u2B73\u2B76-\u2B95\u2B98-\u2BB9\u2BBD-\u2BC8\u2BCA-\u2BD1\u2CE5-\u2CEA\u2CEF-\u2CF1\u2CF9-\u2CFF\u2D7F\u2DE0-\u2E42\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u3004\u3008-\u3020\u302A-\u302D\u3030\u3036\u3037\u303D-\u303F\u3099-\u309C\u30A0\u30FB\u31C0-\u31E3\u321D\u321E\u3250-\u325F\u327C-\u327E\u32B1-\u32BF\u32CC-\u32CF\u3377-\u337A\u33DE\u33DF\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA60D-\uA60F\uA66F-\uA67F\uA69F\uA6F0\uA6F1\uA700-\uA721\uA788\uA802\uA806\uA80B\uA825\uA826\uA828-\uA82B\uA838\uA839\uA874-\uA877\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFB29\uFD3E\uFD3F\uFDFD\uFE00-\uFE19\uFE20-\uFE2D\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFEFF\uFF01-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFF9-\uFFFD]|\uD800[\uDD01\uDD40-\uDD8C\uDD90-\uDD9B\uDDA0\uDDFD\uDEE0-\uDEFB\uDF76-\uDF7A]|\uD802[\uDD1F\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6\uDF39-\uDF3F]|\uD803[\uDE60-\uDE7E]|[\uD804\uDB40][\uDC01\uDC38-\uDC46\uDC52-\uDC65\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDEDF\uDEE3-\uDEEA\uDF01\uDF3C\uDF40\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB3-\uDCB8\uDCBA\uDCBF\uDCC0\uDCC2\uDCC3\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E\uDCA0-\uDCA3]|\uD834[\uDD67-\uDD69\uDD73-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE00-\uDE45\uDF00-\uDF56]|\uD835[\uDEDB\uDF15\uDF4F\uDF89\uDFC3\uDFCE-\uDFFF]|\uD83A[\uDCD0-\uDCD6]|\uD83B[\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD00-\uDD0C\uDD6A\uDD6B\uDF00-\uDF2C\uDF30-\uDF7D\uDF80-\uDFCE\uDFD4-\uDFF7]|\uD83D[\uDC00-\uDCFE\uDD00-\uDD4A\uDD50-\uDD79\uDD7B-\uDDA3\uDDA5-\uDE42\uDE45-\uDECF\uDEE0-\uDEEC\uDEF0-\uDEF3\uDF00-\uDF73\uDF80-\uDFD4]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD]'; -// jscs:enable maximumLineLength -// jshint ignore:end - - -},{}],8:[function(require,module,exports){ -// DO NOT EDIT! -// THIS FILE IS GENERATED! - -// All bidi characters found in classes 'R', 'AL', 'RLE', 'RLO', and 'RLI' as per Unicode 7.0.0. - -// jshint ignore:start -// jscs:disable maximumLineLength -module.exports = '[\u05BE\u05C0\u05C3\u05C6\u05D0-\u05EA\u05F0-\u05F4\u0608\u060B\u060D\u061B\u061C\u061E-\u064A\u066D-\u066F\u0671-\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u070D\u070F\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0830-\u083E\u0840-\u0858\u085E\u08A0-\u08B2\u200F\u202B\u202E\u2067\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBC1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFC\uFE70-\uFE74\uFE76-\uFEFC]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC57-\uDC9E\uDCA7-\uDCAF\uDD00-\uDD1B\uDD20-\uDD39\uDD3F\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE40-\uDE47\uDE50-\uDE58\uDE60-\uDE9F\uDEC0-\uDEE4\uDEEB-\uDEF6\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDF99-\uDF9C\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]'; -// jscs:enable maximumLineLength -// jshint ignore:end - - -},{}]},{},[5])(5) -}); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwiL1VzZXJzL2V6ZXF1aWVsL0Rlc2t0b3AvcmVhY3QtdHlwZWFoZWFkLWNvbXBvbmVudC9zcmMvY29tcG9uZW50cy9hcmlhX3N0YXR1cy5qc3giLCIvVXNlcnMvZXplcXVpZWwvRGVza3RvcC9yZWFjdC10eXBlYWhlYWQtY29tcG9uZW50L3NyYy9jb21wb25lbnRzL2lucHV0LmpzeCIsIi9Vc2Vycy9lemVxdWllbC9EZXNrdG9wL3JlYWN0LXR5cGVhaGVhZC1jb21wb25lbnQvc3JjL2NvbXBvbmVudHMvdHlwZWFoZWFkLmpzeCIsIi9Vc2Vycy9lemVxdWllbC9EZXNrdG9wL3JlYWN0LXR5cGVhaGVhZC1jb21wb25lbnQvc3JjL2luZGV4LmpzIiwiL1VzZXJzL2V6ZXF1aWVsL0Rlc2t0b3AvcmVhY3QtdHlwZWFoZWFkLWNvbXBvbmVudC9zcmMvdXRpbHMvZ2V0X3RleHRfZGlyZWN0aW9uLmpzIiwiL1VzZXJzL2V6ZXF1aWVsL0Rlc2t0b3AvcmVhY3QtdHlwZWFoZWFkLWNvbXBvbmVudC9zcmMvdXRpbHMvbmV1dHJhbF9jaGFyc19yZWdleHAuanMiLCIvVXNlcnMvZXplcXVpZWwvRGVza3RvcC9yZWFjdC10eXBlYWhlYWQtY29tcG9uZW50L3NyYy91dGlscy9ydGxfY2hhcnNfcmVnZXhwLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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SUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQy9CLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDbkIsS0FBSzs7SUFFRCxPQUFPLEdBQUcsQ0FBQztDQUNkLENBQUM7Ozs7QUNqQkYsZUFBZTtBQUNmLDBCQUEwQjs7QUFFMUIsc0hBQXNIOztBQUV0SCxzQkFBc0I7QUFDdEIsaUNBQWlDO0FBQ2pDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsNjhJQUE2OEksQ0FBQztBQUMvOUksZ0NBQWdDO0FBQ2hDLG9CQUFvQjs7OztBQ1RwQixlQUFlO0FBQ2YsMEJBQTBCOztBQUUxQixnR0FBZ0c7O0FBRWhHLHNCQUFzQjtBQUN0QixpQ0FBaUM7QUFDakMsTUFBTSxDQUFDLE9BQU8sR0FBRyx3c0NBQXdzQyxDQUFDO0FBQzF0QyxnQ0FBZ0M7QUFDaEMsb0JBQW9CIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudFF1ZXVlO1xuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICAgICAgICBjdXJyZW50UXVldWVbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG59XG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHF1ZXVlLnB1c2goZnVuKTtcbiAgICBpZiAoIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnQXJpYSBTdGF0dXMnLFxuXG4gICAgcHJvcFR5cGVzOiBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nID8ge30gOiB7XG4gICAgICAgIG1lc3NhZ2U6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGFzIGBjb21wb25lbnREaWRVcGRhdGVgXG4gICAgICAgIC8vIGRvZXMgbm90IGZpcmUgb24gdGhlIGluaXRpYWwgcmVuZGVyLlxuICAgICAgICBfdGhpcy5zZXRUZXh0Q29udGVudChfdGhpcy5wcm9wcy5tZXNzYWdlKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkVXBkYXRlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICBfdGhpcy5zZXRUZXh0Q29udGVudChfdGhpcy5wcm9wcy5tZXNzYWdlKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgcm9sZT0nc3RhdHVzJ1xuICAgICAgICAgICAgICAgIGFyaWEtbGl2ZT0ncG9saXRlJ1xuICAgICAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6ICctOTk5OXB4JyxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcbiAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgLz5cbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgLy8gV2UgY2Fubm90IHNldCBgdGV4dENvbnRlbnRgIGRpcmVjdGx5IGluIGByZW5kZXJgLFxuICAgIC8vIGJlY2F1c2UgUmVhY3QgYWRkcy9kZWxldGVzIHRleHQgbm9kZXMgd2hlbiByZW5kZXJpbmcsXG4gICAgLy8gd2hpY2ggY29uZnVzZXMgc2NyZWVuIHJlYWRlcnMgYW5kIGRvZXNuJ3QgY2F1c2UgdGhlbSB0byByZWFkIGNoYW5nZXMuXG4gICAgc2V0VGV4dENvbnRlbnQ6IGZ1bmN0aW9uKHRleHRDb250ZW50KSB7XG4gICAgICAgIC8vIFdlIGNvdWxkIHNldCBgaW5uZXJIVE1MYCwgYnV0IGl0J3MgYmV0dGVyIHRvIGF2b2lkIGl0LlxuICAgICAgICB0aGlzLmdldERPTU5vZGUoKS50ZXh0Q29udGVudCA9IHRleHRDb250ZW50IHx8ICcnO1xuICAgIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0lucHV0JyxcblxuICAgIHByb3BUeXBlczogcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJyA/IHt9IDoge1xuICAgICAgICB2YWx1ZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgb25DaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogJycsXG4gICAgICAgICAgICBvbkNoYW5nZTogZnVuY3Rpb24oKSB7fVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRVcGRhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgICAgICAgZGlyID0gX3RoaXMucHJvcHMuZGlyO1xuXG4gICAgICAgIGlmIChkaXIgPT09IG51bGwgfHwgZGlyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIFdoZW4gc2V0dGluZyBhbiBhdHRyaWJ1dGUgdG8gbnVsbC91bmRlZmluZWQsXG4gICAgICAgICAgICAvLyBSZWFjdCBpbnN0ZWFkIHNldHMgdGhlIGF0dHJpYnV0ZSB0byBhbiBlbXB0eSBzdHJpbmcuXG5cbiAgICAgICAgICAgIC8vIFRoaXMgaXMgbm90IGRlc2lyZWQgYmVjYXVzZSBvZiBhIHBvc3NpYmxlIGJ1ZyBpbiBDaHJvbWUuXG4gICAgICAgICAgICAvLyBJZiB0aGUgcGFnZSBpcyBSVEwsIGFuZCB0aGUgaW5wdXQncyBgZGlyYCBhdHRyaWJ1dGUgaXMgc2V0XG4gICAgICAgICAgICAvLyB0byBhbiBlbXB0eSBzdHJpbmcsIENocm9tZSBhc3N1bWVzIExUUiwgd2hpY2ggaXNuJ3Qgd2hhdCB3ZSB3YW50LlxuICAgICAgICAgICAgUmVhY3QuZmluZERPTU5vZGUoX3RoaXMpLnJlbW92ZUF0dHJpYnV0ZSgnZGlyJyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgey4uLl90aGlzLnByb3BzfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtfdGhpcy5oYW5kbGVDaGFuZ2V9XG4gICAgICAgICAgICAvPlxuICAgICAgICApO1xuICAgIH0sXG5cbiAgICBoYW5kbGVDaGFuZ2U6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBwcm9wcyA9IHRoaXMucHJvcHM7XG5cbiAgICAgICAgLy8gVGhlcmUgYXJlIHNldmVyYWwgUmVhY3QgYnVncyBpbiBJRSxcbiAgICAgICAgLy8gd2hlcmUgdGhlIGBpbnB1dGAncyBgb25DaGFuZ2VgIGV2ZW50IGlzXG4gICAgICAgIC8vIGZpcmVkIGV2ZW4gd2hlbiB0aGUgdmFsdWUgZGlkbid0IGNoYW5nZS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8yMTg1XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMzM3N1xuICAgICAgICBpZiAoZXZlbnQudGFyZ2V0LnZhbHVlICE9PSBwcm9wcy52YWx1ZSkge1xuICAgICAgICAgICAgcHJvcHMub25DaGFuZ2UoZXZlbnQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGJsdXI6IGZ1bmN0aW9uKCkge1xuICAgICAgICBSZWFjdC5maW5kRE9NTm9kZSh0aGlzKS5ibHVyKCk7XG4gICAgfSxcblxuICAgIGlzQ3Vyc29yQXRFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgICAgICAgaW5wdXRET01Ob2RlID0gUmVhY3QuZmluZERPTU5vZGUoX3RoaXMpLFxuICAgICAgICAgICAgdmFsdWVMZW5ndGggPSBfdGhpcy5wcm9wcy52YWx1ZS5sZW5ndGg7XG5cbiAgICAgICAgcmV0dXJuIGlucHV0RE9NTm9kZS5zZWxlY3Rpb25TdGFydCA9PT0gdmFsdWVMZW5ndGggJiZcbiAgICAgICAgICAgICAgIGlucHV0RE9NTm9kZS5zZWxlY3Rpb25FbmQgPT09IHZhbHVlTGVuZ3RoO1xuICAgIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpLFxuICAgIElucHV0ID0gcmVxdWlyZSgnLi9pbnB1dC5qc3gnKSxcbiAgICBBcmlhU3RhdHVzID0gcmVxdWlyZSgnLi9hcmlhX3N0YXR1cy5qc3gnKSxcbiAgICBnZXRUZXh0RGlyZWN0aW9uID0gcmVxdWlyZSgnLi4vdXRpbHMvZ2V0X3RleHRfZGlyZWN0aW9uJyksXG4gICAgbm9vcCA9IGZ1bmN0aW9uKCkge307XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnVHlwZWFoZWFkJyxcblxuICAgIHN0YXRpY3M6IHtcbiAgICAgICAgZ2V0SW5zdGFuY2VDb3VudDogKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGNvdW50ID0gMDtcblxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiArK2NvdW50O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSgpKVxuICAgIH0sXG5cbiAgICBwcm9wVHlwZXM6IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicgPyB7fSA6IHtcbiAgICAgICAgaW5wdXRJZDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgaW5wdXROYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGF1dG9Gb2N1czogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGhvdmVyU2VsZWN0OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgaW5wdXRWYWx1ZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgb3B0aW9uczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBwbGFjZWhvbGRlcjogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgb25DaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbktleURvd246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbktleVByZXNzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb25LZXlVcDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uRm9jdXM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkJsdXI6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvblNlbGVjdDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uSW5wdXRDbGljazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGhhbmRsZUhpbnQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkNvbXBsZXRlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb25PcHRpb25DbGljazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uT3B0aW9uQ2hhbmdlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb25Ecm9wZG93bk9wZW46IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkRyb3Bkb3duQ2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvcHRpb25UZW1wbGF0ZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgZ2V0TWVzc2FnZUZvck9wdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGdldE1lc3NhZ2VGb3JJbmNvbWluZ09wdGlvbnM6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjbGFzc05hbWU6ICcnLFxuICAgICAgICAgICAgaW5wdXRWYWx1ZTogJycsXG4gICAgICAgICAgICBvcHRpb25zOiBbXSxcbiAgICAgICAgICAgIGhvdmVyU2VsZWN0OiB0cnVlLFxuICAgICAgICAgICAgb25Gb2N1czogbm9vcCxcbiAgICAgICAgICAgIG9uS2V5RG93bjogbm9vcCxcbiAgICAgICAgICAgIG9uQ2hhbmdlOiBub29wLFxuICAgICAgICAgICAgb25JbnB1dENsaWNrOiBub29wLFxuICAgICAgICAgICAgaGFuZGxlSGludDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uT3B0aW9uQ2xpY2s6IG5vb3AsXG4gICAgICAgICAgICBvbk9wdGlvbkNoYW5nZTogbm9vcCxcbiAgICAgICAgICAgIG9uQ29tcGxldGU6ICBub29wLFxuICAgICAgICAgICAgb25Ecm9wZG93bk9wZW46IG5vb3AsXG4gICAgICAgICAgICBvbkRyb3Bkb3duQ2xvc2U6IG5vb3AsXG4gICAgICAgICAgICBnZXRNZXNzYWdlRm9yT3B0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0TWVzc2FnZUZvckluY29taW5nT3B0aW9uczogZnVuY3Rpb24obnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyICsgJyBzdWdnZXN0aW9ucyBhcmUgYXZhaWxhYmxlLiBVc2UgdXAgYW5kIGRvd24gYXJyb3dzIHRvIHNlbGVjdC4nXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZWxlY3RlZEluZGV4OiAtMSxcbiAgICAgICAgICAgIGlzSGludFZpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgaXNEcm9wZG93blZpc2libGU6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxNb3VudDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXMsXG4gICAgICAgICAgICB1bmlxdWVJZCA9IHRoaXMuY29uc3RydWN0b3IuZ2V0SW5zdGFuY2VDb3VudCgpO1xuXG4gICAgICAgIF90aGlzLnVzZXJJbnB1dFZhbHVlID0gbnVsbDtcbiAgICAgICAgX3RoaXMucHJldmlvdXNJbnB1dFZhbHVlID0gbnVsbDtcbiAgICAgICAgX3RoaXMuYWN0aXZlRGVzY2VuZGFudElkID0gJ3JlYWN0LXR5cGVhaGVhZC1hY3RpdmVkZXNjZW5kYW50LScgKyB1bmlxdWVJZDtcbiAgICAgICAgX3RoaXMub3B0aW9uc0lkID0gJ3JlYWN0LXR5cGVhaGVhZC1vcHRpb25zLScgKyB1bmlxdWVJZDtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYWRkRXZlbnQgPSB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcixcbiAgICAgICAgICAgIGhhbmRsZVdpbmRvd0Nsb3NlID0gdGhpcy5oYW5kbGVXaW5kb3dDbG9zZTtcblxuICAgICAgICAvLyBUaGUgYGZvY3VzYCBldmVudCBkb2VzIG5vdCBidWJibGUsIHNvIHdlIG11c3QgY2FwdHVyZSBpdCBpbnN0ZWFkLlxuICAgICAgICAvLyBUaGlzIGNsb3NlcyBUeXBlYWhlYWQncyBkcm9wZG93biB3aGVuZXZlciBzb21ldGhpbmcgZWxzZSBnYWlucyBmb2N1cy5cbiAgICAgICAgYWRkRXZlbnQoJ2ZvY3VzJywgaGFuZGxlV2luZG93Q2xvc2UsIHRydWUpO1xuXG4gICAgICAgIC8vIElmIHdlIGNsaWNrIGFueXdoZXJlIG91dHNpZGUgb2YgVHlwZWFoZWFkLCBjbG9zZSB0aGUgZHJvcGRvd24uXG4gICAgICAgIGFkZEV2ZW50KCdjbGljaycsIGhhbmRsZVdpbmRvd0Nsb3NlLCBmYWxzZSk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHJlbW92ZUV2ZW50ID0gd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIsXG4gICAgICAgICAgICBoYW5kbGVXaW5kb3dDbG9zZSA9IHRoaXMuaGFuZGxlV2luZG93Q2xvc2U7XG5cbiAgICAgICAgcmVtb3ZlRXZlbnQoJ2ZvY3VzJywgaGFuZGxlV2luZG93Q2xvc2UsIHRydWUpO1xuICAgICAgICByZW1vdmVFdmVudCgnY2xpY2snLCBoYW5kbGVXaW5kb3dDbG9zZSwgZmFsc2UpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbihuZXh0UHJvcHMpIHtcbiAgICAgICAgdmFyIG5leHRWYWx1ZSA9IG5leHRQcm9wcy5pbnB1dFZhbHVlLFxuICAgICAgICAgICAgbmV4dE9wdGlvbnMgPSBuZXh0UHJvcHMub3B0aW9ucyxcbiAgICAgICAgICAgIHZhbHVlTGVuZ3RoID0gbmV4dFZhbHVlLmxlbmd0aCxcbiAgICAgICAgICAgIGlzSGludFZpc2libGUgPSB2YWx1ZUxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgICAvLyBBIHZpc2libGUgcGFydCBvZiB0aGUgaGludCBtdXN0IGJlXG4gICAgICAgICAgICAgICAgLy8gYXZhaWxhYmxlIGZvciB1cyB0byBjb21wbGV0ZSBpdC5cbiAgICAgICAgICAgICAgICBuZXh0UHJvcHMuaGFuZGxlSGludChuZXh0VmFsdWUsIG5leHRPcHRpb25zKS5zbGljZSh2YWx1ZUxlbmd0aCkubGVuZ3RoID4gMDtcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGlzSGludFZpc2libGU6IGlzSGludFZpc2libGVcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJ1xuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsncmVhY3QtdHlwZWFoZWFkLWNvbnRhaW5lciAnICsgX3RoaXMucHJvcHMuY2xhc3NOYW1lfT5cbiAgICAgICAgICAgICAgICB7X3RoaXMucmVuZGVySW5wdXQoKX1cbiAgICAgICAgICAgICAgICB7X3RoaXMucmVuZGVyRHJvcGRvd24oKX1cbiAgICAgICAgICAgICAgICB7X3RoaXMucmVuZGVyQXJpYU1lc3NhZ2VGb3JPcHRpb25zKCl9XG4gICAgICAgICAgICAgICAge190aGlzLnJlbmRlckFyaWFNZXNzYWdlRm9ySW5jb21pbmdPcHRpb25zKCl9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgcmVuZGVySW5wdXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgICAgICAgc3RhdGUgPSBfdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHByb3BzID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgICBpbnB1dFZhbHVlID0gcHJvcHMuaW5wdXRWYWx1ZSxcbiAgICAgICAgICAgIGNsYXNzTmFtZSA9ICdyZWFjdC10eXBlYWhlYWQtaW5wdXQnLFxuICAgICAgICAgICAgaW5wdXREaXJlY3Rpb24gPSBnZXRUZXh0RGlyZWN0aW9uKGlucHV0VmFsdWUpO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZSdcbiAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0ncmVhY3QtdHlwZWFoZWFkLWlucHV0LWNvbnRhaW5lcic+XG4gICAgICAgICAgICAgICAgPElucHV0XG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXt0cnVlfVxuICAgICAgICAgICAgICAgICAgICByb2xlPSdwcmVzZW50YXRpb24nXG4gICAgICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPXt0cnVlfVxuICAgICAgICAgICAgICAgICAgICBkaXI9e2lucHV0RGlyZWN0aW9ufVxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZSArICcgcmVhY3QtdHlwZWFoZWFkLWhpbnQnfVxuICAgICAgICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I6ICdzaWx2ZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgV2Via2l0VGV4dEZpbGxDb2xvcjogJ3NpbHZlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJ1xuICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZT17c3RhdGUuaXNIaW50VmlzaWJsZSA/IHByb3BzLmhhbmRsZUhpbnQoaW5wdXRWYWx1ZSwgcHJvcHMub3B0aW9ucykgOiBudWxsfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPElucHV0XG4gICAgICAgICAgICAgICAgICAgIHJlZj0naW5wdXQnXG4gICAgICAgICAgICAgICAgICAgIHJvbGU9J2NvbWJvYm94J1xuICAgICAgICAgICAgICAgICAgICBhcmlhLW93bnM9e190aGlzLm9wdGlvbnNJZH1cbiAgICAgICAgICAgICAgICAgICAgYXJpYS1leHBhbmRlZD17c3RhdGUuaXNEcm9wZG93blZpc2libGV9XG4gICAgICAgICAgICAgICAgICAgIGFyaWEtYXV0b2NvbXBsZXRlPSdib3RoJ1xuICAgICAgICAgICAgICAgICAgICBhcmlhLWFjdGl2ZWRlc2NlbmRhbnQ9e190aGlzLmFjdGl2ZURlc2NlbmRhbnRJZH1cbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9e2lucHV0VmFsdWV9XG4gICAgICAgICAgICAgICAgICAgIHNwZWxsQ2hlY2s9e2ZhbHNlfVxuICAgICAgICAgICAgICAgICAgICBhdXRvQ29tcGxldGU9e2ZhbHNlfVxuICAgICAgICAgICAgICAgICAgICBhdXRvQ29ycmVjdD17ZmFsc2V9XG4gICAgICAgICAgICAgICAgICAgIGRpcj17aW5wdXREaXJlY3Rpb259XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e190aGlzLmhhbmRsZUNsaWNrfVxuICAgICAgICAgICAgICAgICAgICBvbkZvY3VzPXtfdGhpcy5oYW5kbGVGb2N1c31cbiAgICAgICAgICAgICAgICAgICAgb25CbHVyPXtwcm9wcy5vbkJsdXJ9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtfdGhpcy5oYW5kbGVDaGFuZ2V9XG4gICAgICAgICAgICAgICAgICAgIG9uS2V5RG93bj17X3RoaXMuaGFuZGxlS2V5RG93bn1cbiAgICAgICAgICAgICAgICAgICAgaWQ9e3Byb3BzLmlucHV0SWR9XG4gICAgICAgICAgICAgICAgICAgIG5hbWU9e3Byb3BzLmlucHV0TmFtZX1cbiAgICAgICAgICAgICAgICAgICAgYXV0b0ZvY3VzPXtwcm9wcy5hdXRvRm9jdXN9XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPXtwcm9wcy5wbGFjZWhvbGRlcn1cbiAgICAgICAgICAgICAgICAgICAgb25TZWxlY3Q9e3Byb3BzLm9uU2VsZWN0fVxuICAgICAgICAgICAgICAgICAgICBvbktleVVwPXtwcm9wcy5vbktleVVwfVxuICAgICAgICAgICAgICAgICAgICBvbktleVByZXNzPXtwcm9wcy5vbktleVByZXNzfVxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZSArICcgcmVhY3QtdHlwZWFoZWFkLXVzZXJ0ZXh0J31cbiAgICAgICAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyRHJvcGRvd246IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgICAgICAgc3RhdGUgPSBfdGhpcy5zdGF0ZSxcbiAgICAgICAgICAgIHByb3BzID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgICBPcHRpb25UZW1wbGF0ZSA9IHByb3BzLm9wdGlvblRlbXBsYXRlLFxuICAgICAgICAgICAgc2VsZWN0ZWRJbmRleCA9IHN0YXRlLnNlbGVjdGVkSW5kZXgsXG4gICAgICAgICAgICBpc0Ryb3Bkb3duVmlzaWJsZSA9IHN0YXRlLmlzRHJvcGRvd25WaXNpYmxlLFxuICAgICAgICAgICAgYWN0aXZlRGVzY2VuZGFudElkID0gX3RoaXMuYWN0aXZlRGVzY2VuZGFudElkO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9wdGlvbnMubGVuZ3RoIDwgMSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPHVsIGlkPXtfdGhpcy5vcHRpb25zSWR9XG4gICAgICAgICAgICAgICAgcmVmPSdkcm9wZG93bidcbiAgICAgICAgICAgICAgICByb2xlPSdsaXN0Ym94J1xuICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPXshaXNEcm9wZG93blZpc2libGV9XG4gICAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJyNmZmYnLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgICAgICAgICAgYm94U2l6aW5nOiAnYm9yZGVyLWJveCcsXG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IGlzRHJvcGRvd25WaXNpYmxlID8gJ2Jsb2NrJyA6ICdub25lJ1xuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPSdyZWFjdC10eXBlYWhlYWQtb3B0aW9ucydcbiAgICAgICAgICAgICAgICBvbk1vdXNlT3V0PXt0aGlzLmhhbmRsZU1vdXNlT3V0fT5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHByb3BzLm9wdGlvbnMubWFwKGZ1bmN0aW9uKGRhdGEsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNTZWxlY3RlZCA9IHNlbGVjdGVkSW5kZXggPT09IGluZGV4O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBpZD17aXNTZWxlY3RlZCA/IGFjdGl2ZURlc2NlbmRhbnRJZCA6IG51bGx9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9e2lzU2VsZWN0ZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvbGU9J29wdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5PXtpbmRleH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17X3RoaXMuaGFuZGxlT3B0aW9uQ2xpY2suYmluZChfdGhpcywgaW5kZXgpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbk1vdXNlT3Zlcj17X3RoaXMuaGFuZGxlT3B0aW9uTW91c2VPdmVyLmJpbmQoX3RoaXMsIGluZGV4KX0+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPE9wdGlvblRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPXtkYXRhfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg9e2luZGV4fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlcklucHV0VmFsdWU9e190aGlzLnVzZXJJbnB1dFZhbHVlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRWYWx1ZT17cHJvcHMuaW5wdXRWYWx1ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2VsZWN0ZWQ9e2lzU2VsZWN0ZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyQXJpYU1lc3NhZ2VGb3JPcHRpb25zOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcyxcbiAgICAgICAgICAgIHByb3BzID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgICBpbnB1dFZhbHVlID0gcHJvcHMuaW5wdXRWYWx1ZSxcbiAgICAgICAgICAgIG9wdGlvbiA9IHByb3BzLm9wdGlvbnNbX3RoaXMuc3RhdGUuc2VsZWN0ZWRJbmRleF0gfHwgaW5wdXRWYWx1ZTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPEFyaWFTdGF0dXNcbiAgICAgICAgICAgICAgICBtZXNzYWdlPXtwcm9wcy5nZXRNZXNzYWdlRm9yT3B0aW9uKG9wdGlvbikgfHwgaW5wdXRWYWx1ZX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICk7XG4gICAgfSxcblxuICAgIHJlbmRlckFyaWFNZXNzYWdlRm9ySW5jb21pbmdPcHRpb25zOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHByb3BzID0gdGhpcy5wcm9wcztcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPEFyaWFTdGF0dXNcbiAgICAgICAgICAgICAgICBtZXNzYWdlPXtwcm9wcy5nZXRNZXNzYWdlRm9ySW5jb21pbmdPcHRpb25zKHByb3BzLm9wdGlvbnMubGVuZ3RoKX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICk7XG4gICAgfSxcblxuICAgIHNob3dEcm9wZG93bjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgaWYgKCFfdGhpcy5zdGF0ZS5pc0Ryb3Bkb3duVmlzaWJsZSkge1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGlzRHJvcGRvd25WaXNpYmxlOiB0cnVlXG4gICAgICAgICAgICB9LCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5wcm9wcy5vbkRyb3Bkb3duT3BlbigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgaGlkZURyb3Bkb3duOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICBpZiAoX3RoaXMuc3RhdGUuaXNEcm9wZG93blZpc2libGUpIHtcbiAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBpc0Ryb3Bkb3duVmlzaWJsZTogZmFsc2VcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF90aGlzLnByb3BzLm9uRHJvcGRvd25DbG9zZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2hvd0hpbnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgICAgICAgcHJvcHMgPSBfdGhpcy5wcm9wcyxcbiAgICAgICAgICAgIGlucHV0VmFsdWUgPSBwcm9wcy5pbnB1dFZhbHVlLFxuICAgICAgICAgICAgaW5wdXRWYWx1ZUxlbmd0aCA9IGlucHV0VmFsdWUubGVuZ3RoLFxuICAgICAgICAgICAgaXNIaW50VmlzaWJsZSA9IGlucHV0VmFsdWVMZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgICAgLy8gQSB2aXNpYmxlIHBhcnQgb2YgdGhlIGhpbnQgbXVzdCBiZVxuICAgICAgICAgICAgICAgIC8vIGF2YWlsYWJsZSBmb3IgdXMgdG8gY29tcGxldGUgaXQuXG4gICAgICAgICAgICAgICAgcHJvcHMuaGFuZGxlSGludChpbnB1dFZhbHVlLCBwcm9wcy5vcHRpb25zKS5zbGljZShpbnB1dFZhbHVlTGVuZ3RoKS5sZW5ndGggPiAwO1xuXG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGlzSGludFZpc2libGU6IGlzSGludFZpc2libGVcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGhpZGVIaW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBpc0hpbnRWaXNpYmxlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgc2V0U2VsZWN0ZWRJbmRleDogZnVuY3Rpb24oaW5kZXgsIGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRJbmRleDogaW5kZXhcbiAgICAgICAgfSwgY2FsbGJhY2spO1xuICAgIH0sXG5cbiAgICBoYW5kbGVDaGFuZ2U6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgX3RoaXMuc2hvd0hpbnQoKTtcbiAgICAgICAgX3RoaXMuc2hvd0Ryb3Bkb3duKCk7XG4gICAgICAgIF90aGlzLnNldFNlbGVjdGVkSW5kZXgoLTEpO1xuICAgICAgICBfdGhpcy5wcm9wcy5vbkNoYW5nZShldmVudCk7XG4gICAgICAgIF90aGlzLnVzZXJJbnB1dFZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIH0sXG5cbiAgICBmb2N1czogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMucmVmcy5pbnB1dC5nZXRET01Ob2RlKCkuZm9jdXMoKTtcbiAgICB9LFxuXG4gICAgaGFuZGxlRm9jdXM6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgX3RoaXMuc2hvd0Ryb3Bkb3duKCk7XG4gICAgICAgIF90aGlzLnByb3BzLm9uRm9jdXMoZXZlbnQpO1xuICAgIH0sXG5cbiAgICBoYW5kbGVDbGljazogZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICBfdGhpcy5zaG93SGludCgpO1xuICAgICAgICBfdGhpcy5wcm9wcy5vbklucHV0Q2xpY2soZXZlbnQpO1xuICAgIH0sXG5cbiAgICBuYXZpZ2F0ZTogZnVuY3Rpb24oZGlyZWN0aW9uLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgICAgICAgbWluSW5kZXggPSAtMSxcbiAgICAgICAgICAgIG1heEluZGV4ID0gX3RoaXMucHJvcHMub3B0aW9ucy5sZW5ndGggLSAxLFxuICAgICAgICAgICAgaW5kZXggPSBfdGhpcy5zdGF0ZS5zZWxlY3RlZEluZGV4ICsgZGlyZWN0aW9uO1xuXG4gICAgICAgIGlmIChpbmRleCA+IG1heEluZGV4KSB7XG4gICAgICAgICAgICBpbmRleCA9IG1pbkluZGV4O1xuICAgICAgICB9IGVsc2UgaWYgKGluZGV4IDwgbWluSW5kZXgpIHtcbiAgICAgICAgICAgIGluZGV4ID0gbWF4SW5kZXg7XG4gICAgICAgIH1cblxuICAgICAgICBfdGhpcy5zZXRTZWxlY3RlZEluZGV4KGluZGV4LCBjYWxsYmFjayk7XG4gICAgfSxcblxuICAgIGhhbmRsZUtleURvd246IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXMsXG4gICAgICAgICAgICBrZXkgPSBldmVudC5rZXksXG4gICAgICAgICAgICBwcm9wcyA9IF90aGlzLnByb3BzLFxuICAgICAgICAgICAgaW5wdXQgPSBfdGhpcy5yZWZzLmlucHV0LFxuICAgICAgICAgICAgaXNEcm9wZG93blZpc2libGUgPSBfdGhpcy5zdGF0ZS5pc0Ryb3Bkb3duVmlzaWJsZSxcbiAgICAgICAgICAgIGlzSGludFZpc2libGUgPSBfdGhpcy5zdGF0ZS5pc0hpbnRWaXNpYmxlLFxuICAgICAgICAgICAgaGFzSGFuZGxlZEtleURvd24gPSBmYWxzZSxcbiAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgb3B0aW9uRGF0YSxcbiAgICAgICAgICAgIGRpcjtcblxuICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICBjYXNlICdFbmQnOlxuICAgICAgICBjYXNlICdUYWInOlxuICAgICAgICAgICAgaWYgKGlzSGludFZpc2libGUgJiYgIWV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBwcm9wcy5vbkNvbXBsZXRlKGV2ZW50LCBwcm9wcy5oYW5kbGVIaW50KHByb3BzLmlucHV0VmFsdWUsIHByb3BzLm9wdGlvbnMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBcnJvd0xlZnQnOlxuICAgICAgICBjYXNlICdBcnJvd1JpZ2h0JzpcbiAgICAgICAgICAgIGlmIChpc0hpbnRWaXNpYmxlICYmICFldmVudC5zaGlmdEtleSAmJiBpbnB1dC5pc0N1cnNvckF0RW5kKCkpIHtcbiAgICAgICAgICAgICAgICBkaXIgPSBnZXRUZXh0RGlyZWN0aW9uKHByb3BzLmlucHV0VmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKChkaXIgPT09ICdsdHInICYmIGtleSA9PT0gJ0Fycm93UmlnaHQnKSB8fCAoZGlyID09PSAncnRsJyAmJiBrZXkgPT09ICdBcnJvd0xlZnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9wcy5vbkNvbXBsZXRlKGV2ZW50LCBwcm9wcy5oYW5kbGVIaW50KHByb3BzLmlucHV0VmFsdWUsIHByb3BzLm9wdGlvbnMpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgICAgICAgX3RoaXMuZm9jdXMoKTtcbiAgICAgICAgICAgIF90aGlzLmhpZGVIaW50KCk7XG4gICAgICAgICAgICBfdGhpcy5oaWRlRHJvcGRvd24oKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdFc2NhcGUnOlxuICAgICAgICAgICAgX3RoaXMuaGlkZUhpbnQoKTtcbiAgICAgICAgICAgIF90aGlzLmhpZGVEcm9wZG93bigpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICBjYXNlICdBcnJvd0Rvd24nOlxuICAgICAgICAgICAgaWYgKHByb3BzLm9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICBfdGhpcy5zaG93SGludCgpO1xuICAgICAgICAgICAgICAgIF90aGlzLnNob3dEcm9wZG93bigpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzRHJvcGRvd25WaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpciA9IGtleSA9PT0gJ0Fycm93VXAnID8gLTE6IDE7XG4gICAgICAgICAgICAgICAgICAgIGhhc0hhbmRsZWRLZXlEb3duID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5uYXZpZ2F0ZShkaXIsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkSW5kZXggPSBfdGhpcy5zdGF0ZS5zZWxlY3RlZEluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzSW5wdXRWYWx1ZSA9IF90aGlzLnByZXZpb3VzSW5wdXRWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25EYXRhID0gcHJldmlvdXNJbnB1dFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbk9mZnNldFRvcCA9IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRPcHRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJvcGRvd247XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlJ3JlIGN1cnJlbnRseSBvbiBhbiBvcHRpb24uXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBgaW5wdXRgIHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzIHdlIG1pZ2h0IGFycm93IGJhY2sgdG8gaXQgbGF0ZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzSW5wdXRWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5wcmV2aW91c0lucHV0VmFsdWUgPSBwcm9wcy5pbnB1dFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbkRhdGEgPSBwcm9wcy5vcHRpb25zW3NlbGVjdGVkSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc2VsZWN0ZWQgb3B0aW9uIGFsd2F5cyBzY3JvbGwgdG8gdmlzaWJsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyb3Bkb3duID0gUmVhY3QuZmluZERPTU5vZGUoX3RoaXMucmVmcy5kcm9wZG93bik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRPcHRpb24gPSBkcm9wZG93bi5jaGlsZHJlbltzZWxlY3RlZEluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25PZmZzZXRUb3AgPSBzZWxlY3RlZE9wdGlvbi5vZmZzZXRUb3A7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYob3B0aW9uT2Zmc2V0VG9wICsgc2VsZWN0ZWRPcHRpb24uY2xpZW50SGVpZ2h0ID4gZHJvcGRvd24uY2xpZW50SGVpZ2h0IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbk9mZnNldFRvcCA8IGRyb3Bkb3duLnNjcm9sbFRvcCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcm9wZG93bi5zY3JvbGxUb3AgPSBvcHRpb25PZmZzZXRUb3A7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wcy5vbk9wdGlvbkNoYW5nZShldmVudCwgb3B0aW9uRGF0YSwgc2VsZWN0ZWRJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wcy5vbktleURvd24oZXZlbnQsIG9wdGlvbkRhdGEsIHNlbGVjdGVkSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFoYXNIYW5kbGVkS2V5RG93bikge1xuICAgICAgICAgICAgaW5kZXggPSB0aGlzLnN0YXRlLnNlbGVjdGVkSW5kZXg7XG4gICAgICAgICAgICBvcHRpb25EYXRhID0gaW5kZXggPCAwID8gcHJvcHMuaW5wdXRWYWx1ZSA6IHByb3BzLm9wdGlvbnNbaW5kZXhdO1xuICAgICAgICAgICAgcHJvcHMub25LZXlEb3duKGV2ZW50LCBvcHRpb25EYXRhLCBpbmRleCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgaGFuZGxlT3B0aW9uQ2xpY2s6IGZ1bmN0aW9uKHNlbGVjdGVkSW5kZXgsIGV2ZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXMsXG4gICAgICAgICAgICBwcm9wcyA9IF90aGlzLnByb3BzO1xuXG4gICAgICAgIF90aGlzLmZvY3VzKCk7XG4gICAgICAgIF90aGlzLmhpZGVIaW50KCk7XG4gICAgICAgIF90aGlzLmhpZGVEcm9wZG93bigpO1xuICAgICAgICBfdGhpcy5zZXRTZWxlY3RlZEluZGV4KHNlbGVjdGVkSW5kZXgpO1xuICAgICAgICBwcm9wcy5vbk9wdGlvbkNsaWNrKGV2ZW50LCBwcm9wcy5vcHRpb25zW3NlbGVjdGVkSW5kZXhdLCBzZWxlY3RlZEluZGV4KTtcbiAgICB9LFxuXG4gICAgaGFuZGxlT3B0aW9uTW91c2VPdmVyOiBmdW5jdGlvbihzZWxlY3RlZEluZGV4KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgaWYgKF90aGlzLnByb3BzLmhvdmVyU2VsZWN0KSB7XG4gICAgICAgICAgICBfdGhpcy5zZXRTZWxlY3RlZEluZGV4KHNlbGVjdGVkSW5kZXgpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGhhbmRsZU1vdXNlT3V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICBpZiAoX3RoaXMucHJvcHMuaG92ZXJTZWxlY3QpIHtcbiAgICAgICAgICAgIF90aGlzLnNldFNlbGVjdGVkSW5kZXgoLTEpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGhhbmRsZVdpbmRvd0Nsb3NlOiBmdW5jdGlvbihldmVudCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzLFxuICAgICAgICAgICAgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuXG4gICAgICAgIGlmICh0YXJnZXQgIT09IHdpbmRvdyAmJiAhdGhpcy5nZXRET01Ob2RlKCkuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgICAgICAgX3RoaXMuaGlkZUhpbnQoKTtcbiAgICAgICAgICAgIF90aGlzLmhpZGVEcm9wZG93bigpO1xuICAgICAgICB9XG4gICAgfVxufSk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy90eXBlYWhlYWQuanN4Jyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBSVExDaGFyYWN0ZXJzUmVnRXhwID0gcmVxdWlyZSgnLi9ydGxfY2hhcnNfcmVnZXhwJyksXG4gICAgTmV1dHJhbENoYXJhY3RlcnNSZWdFeHAgPSByZXF1aXJlKCcuL25ldXRyYWxfY2hhcnNfcmVnZXhwJyksXG4gICAgc3RhcnRzV2l0aFJUTCA9IG5ldyBSZWdFeHAoJ14oPzonICsgTmV1dHJhbENoYXJhY3RlcnNSZWdFeHAgKyAnKSooPzonICsgUlRMQ2hhcmFjdGVyc1JlZ0V4cCArICcpJyksXG4gICAgbmV1dHJhbFRleHQgPSBuZXcgUmVnRXhwKCdeKD86JyArIE5ldXRyYWxDaGFyYWN0ZXJzUmVnRXhwICsgJykqJCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgICB2YXIgZGlyID0gJ2x0cic7XG5cbiAgICBpZiAoc3RhcnRzV2l0aFJUTC50ZXN0KHRleHQpKSB7XG4gICAgICAgIGRpciA9ICdydGwnO1xuICAgIH0gZWxzZSBpZiAobmV1dHJhbFRleHQudGVzdCh0ZXh0KSkge1xuICAgICAgICBkaXIgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBkaXI7XG59O1xuIiwiLy8gRE8gTk9UIEVESVQhXG4vLyBUSElTIEZJTEUgSVMgR0VORVJBVEVEIVxuXG4vLyBBbGwgYmlkaSBjaGFyYWN0ZXJzIGV4Y2VwdCB0aG9zZSBmb3VuZCBpbiBjbGFzc2VzICdMJyAoTFRSKSwgJ1InIChSVEwpLCBhbmQgJ0FMJyAoUlRMIEFyYWJpYykgYXMgcGVyIFVuaWNvZGUgNy4wLjAuXG5cbi8vIGpzaGludCBpZ25vcmU6c3RhcnRcbi8vIGpzY3M6ZGlzYWJsZSBtYXhpbXVtTGluZUxlbmd0aFxubW9kdWxlLmV4cG9ydHMgPSAnW1xcMC1AXFxbLWBcXHstXFx4QTlcXHhBQi1cXHhCNFxceEI2LVxceEI5XFx4QkItXFx4QkZcXHhEN1xceEY3XFx1MDJCOVxcdTAyQkFcXHUwMkMyLVxcdTAyQ0ZcXHUwMkQyLVxcdTAyREZcXHUwMkU1LVxcdTAyRURcXHUwMkVGLVxcdTAzNkZcXHUwMzc0XFx1MDM3NVxcdTAzN0VcXHUwMzg0XFx1MDM4NVxcdTAzODdcXHUwM0Y2XFx1MDQ4My1cXHUwNDg5XFx1MDU4QVxcdTA1OEQtXFx1MDU4RlxcdTA1OTEtXFx1MDVCRFxcdTA1QkZcXHUwNUMxXFx1MDVDMlxcdTA1QzRcXHUwNUM1XFx1MDVDN1xcdTA2MDAtXFx1MDYwN1xcdTA2MDlcXHUwNjBBXFx1MDYwQ1xcdTA2MEUtXFx1MDYxQVxcdTA2NEItXFx1MDY2Q1xcdTA2NzBcXHUwNkQ2LVxcdTA2RTRcXHUwNkU3LVxcdTA2RURcXHUwNkYwLVxcdTA2RjlcXHUwNzExXFx1MDczMC1cXHUwNzRBXFx1MDdBNi1cXHUwN0IwXFx1MDdFQi1cXHUwN0YzXFx1MDdGNi1cXHUwN0Y5XFx1MDgxNi1cXHUwODE5XFx1MDgxQi1cXHUwODIzXFx1MDgyNS1cXHUwODI3XFx1MDgyOS1cXHUwODJEXFx1MDg1OS1cXHUwODVCXFx1MDhFNC1cXHUwOTAyXFx1MDkzQVxcdTA5M0NcXHUwOTQxLVxcdTA5NDhcXHUwOTREXFx1MDk1MS1cXHUwOTU3XFx1MDk2MlxcdTA5NjNcXHUwOTgxXFx1MDlCQ1xcdTA5QzEtXFx1MDlDNFxcdTA5Q0RcXHUwOUUyXFx1MDlFM1xcdTA5RjJcXHUwOUYzXFx1MDlGQlxcdTBBMDFcXHUwQTAyXFx1MEEzQ1xcdTBBNDFcXHUwQTQyXFx1MEE0N1xcdTBBNDhcXHUwQTRCLVxcdTBBNERcXHUwQTUxXFx1MEE3MFxcdTBBNzFcXHUwQTc1XFx1MEE4MVxcdTBBODJcXHUwQUJDXFx1MEFDMS1cXHUwQUM1XFx1MEFDN1xcdTBBQzhcXHUwQUNEXFx1MEFFMlxcdTBBRTNcXHUwQUYxXFx1MEIwMVxcdTBCM0NcXHUwQjNGXFx1MEI0MS1cXHUwQjQ0XFx1MEI0RFxcdTBCNTZcXHUwQjYyXFx1MEI2M1xcdTBCODJcXHUwQkMwXFx1MEJDRFxcdTBCRjMtXFx1MEJGQVxcdTBDMDBcXHUwQzNFLVxcdTBDNDBcXHUwQzQ2LVxcdTBDNDhcXHUwQzRBLVxcdTBDNERcXHUwQzU1XFx1MEM1NlxcdTBDNjJcXHUwQzYzXFx1MEM3OC1cXHUwQzdFXFx1MEM4MVxcdTBDQkNcXHUwQ0NDXFx1MENDRFxcdTBDRTJcXHUwQ0UzXFx1MEQwMVxcdTBENDEtXFx1MEQ0NFxcdTBENERcXHUwRDYyXFx1MEQ2M1xcdTBEQ0FcXHUwREQyLVxcdTBERDRcXHUwREQ2XFx1MEUzMVxcdTBFMzQtXFx1MEUzQVxcdTBFM0ZcXHUwRTQ3LVxcdTBFNEVcXHUwRUIxXFx1MEVCNC1cXHUwRUI5XFx1MEVCQlxcdTBFQkNcXHUwRUM4LVxcdTBFQ0RcXHUwRjE4XFx1MEYxOVxcdTBGMzVcXHUwRjM3XFx1MEYzOS1cXHUwRjNEXFx1MEY3MS1cXHUwRjdFXFx1MEY4MC1cXHUwRjg0XFx1MEY4NlxcdTBGODdcXHUwRjhELVxcdTBGOTdcXHUwRjk5LVxcdTBGQkNcXHUwRkM2XFx1MTAyRC1cXHUxMDMwXFx1MTAzMi1cXHUxMDM3XFx1MTAzOVxcdTEwM0FcXHUxMDNEXFx1MTAzRVxcdTEwNThcXHUxMDU5XFx1MTA1RS1cXHUxMDYwXFx1MTA3MS1cXHUxMDc0XFx1MTA4MlxcdTEwODVcXHUxMDg2XFx1MTA4RFxcdTEwOURcXHUxMzVELVxcdTEzNUZcXHUxMzkwLVxcdTEzOTlcXHUxNDAwXFx1MTY4MFxcdTE2OUJcXHUxNjlDXFx1MTcxMi1cXHUxNzE0XFx1MTczMi1cXHUxNzM0XFx1MTc1MlxcdTE3NTNcXHUxNzcyXFx1MTc3M1xcdTE3QjRcXHUxN0I1XFx1MTdCNy1cXHUxN0JEXFx1MTdDNlxcdTE3QzktXFx1MTdEM1xcdTE3REJcXHUxN0REXFx1MTdGMC1cXHUxN0Y5XFx1MTgwMC1cXHUxODBFXFx1MThBOVxcdTE5MjAtXFx1MTkyMlxcdTE5MjdcXHUxOTI4XFx1MTkzMlxcdTE5MzktXFx1MTkzQlxcdTE5NDBcXHUxOTQ0XFx1MTk0NVxcdTE5REUtXFx1MTlGRlxcdTFBMTdcXHUxQTE4XFx1MUExQlxcdTFBNTZcXHUxQTU4LVxcdTFBNUVcXHUxQTYwXFx1MUE2MlxcdTFBNjUtXFx1MUE2Q1xcdTFBNzMtXFx1MUE3Q1xcdTFBN0ZcXHUxQUIwLVxcdTFBQkVcXHUxQjAwLVxcdTFCMDNcXHUxQjM0XFx1MUIzNi1cXHUxQjNBXFx1MUIzQ1xcdTFCNDJcXHUxQjZCLVxcdTFCNzNcXHUxQjgwXFx1MUI4MVxcdTFCQTItXFx1MUJBNVxcdTFCQThcXHUxQkE5XFx1MUJBQi1cXHUxQkFEXFx1MUJFNlxcdTFCRThcXHUxQkU5XFx1MUJFRFxcdTFCRUYtXFx1MUJGMVxcdTFDMkMtXFx1MUMzM1xcdTFDMzZcXHUxQzM3XFx1MUNEMC1cXHUxQ0QyXFx1MUNENC1cXHUxQ0UwXFx1MUNFMi1cXHUxQ0U4XFx1MUNFRFxcdTFDRjRcXHUxQ0Y4XFx1MUNGOVxcdTFEQzAtXFx1MURGNVxcdTFERkMtXFx1MURGRlxcdTFGQkRcXHUxRkJGLVxcdTFGQzFcXHUxRkNELVxcdTFGQ0ZcXHUxRkRELVxcdTFGREZcXHUxRkVELVxcdTFGRUZcXHUxRkZEXFx1MUZGRVxcdTIwMDAtXFx1MjAwRFxcdTIwMTAtXFx1MjAyOVxcdTIwMkYtXFx1MjA2NFxcdTIwNjhcXHUyMDZBLVxcdTIwNzBcXHUyMDc0LVxcdTIwN0VcXHUyMDgwLVxcdTIwOEVcXHUyMEEwLVxcdTIwQkRcXHUyMEQwLVxcdTIwRjBcXHUyMTAwXFx1MjEwMVxcdTIxMDMtXFx1MjEwNlxcdTIxMDhcXHUyMTA5XFx1MjExNFxcdTIxMTYtXFx1MjExOFxcdTIxMUUtXFx1MjEyM1xcdTIxMjVcXHUyMTI3XFx1MjEyOVxcdTIxMkVcXHUyMTNBXFx1MjEzQlxcdTIxNDAtXFx1MjE0NFxcdTIxNEEtXFx1MjE0RFxcdTIxNTAtXFx1MjE1RlxcdTIxODlcXHUyMTkwLVxcdTIzMzVcXHUyMzdCLVxcdTIzOTRcXHUyMzk2LVxcdTIzRkFcXHUyNDAwLVxcdTI0MjZcXHUyNDQwLVxcdTI0NEFcXHUyNDYwLVxcdTI0OUJcXHUyNEVBLVxcdTI2QUJcXHUyNkFELVxcdTI3RkZcXHUyOTAwLVxcdTJCNzNcXHUyQjc2LVxcdTJCOTVcXHUyQjk4LVxcdTJCQjlcXHUyQkJELVxcdTJCQzhcXHUyQkNBLVxcdTJCRDFcXHUyQ0U1LVxcdTJDRUFcXHUyQ0VGLVxcdTJDRjFcXHUyQ0Y5LVxcdTJDRkZcXHUyRDdGXFx1MkRFMC1cXHUyRTQyXFx1MkU4MC1cXHUyRTk5XFx1MkU5Qi1cXHUyRUYzXFx1MkYwMC1cXHUyRkQ1XFx1MkZGMC1cXHUyRkZCXFx1MzAwMC1cXHUzMDA0XFx1MzAwOC1cXHUzMDIwXFx1MzAyQS1cXHUzMDJEXFx1MzAzMFxcdTMwMzZcXHUzMDM3XFx1MzAzRC1cXHUzMDNGXFx1MzA5OS1cXHUzMDlDXFx1MzBBMFxcdTMwRkJcXHUzMUMwLVxcdTMxRTNcXHUzMjFEXFx1MzIxRVxcdTMyNTAtXFx1MzI1RlxcdTMyN0MtXFx1MzI3RVxcdTMyQjEtXFx1MzJCRlxcdTMyQ0MtXFx1MzJDRlxcdTMzNzctXFx1MzM3QVxcdTMzREVcXHUzM0RGXFx1MzNGRlxcdTREQzAtXFx1NERGRlxcdUE0OTAtXFx1QTRDNlxcdUE2MEQtXFx1QTYwRlxcdUE2NkYtXFx1QTY3RlxcdUE2OUZcXHVBNkYwXFx1QTZGMVxcdUE3MDAtXFx1QTcyMVxcdUE3ODhcXHVBODAyXFx1QTgwNlxcdUE4MEJcXHVBODI1XFx1QTgyNlxcdUE4MjgtXFx1QTgyQlxcdUE4MzhcXHVBODM5XFx1QTg3NC1cXHVBODc3XFx1QThDNFxcdUE4RTAtXFx1QThGMVxcdUE5MjYtXFx1QTkyRFxcdUE5NDctXFx1QTk1MVxcdUE5ODAtXFx1QTk4MlxcdUE5QjNcXHVBOUI2LVxcdUE5QjlcXHVBOUJDXFx1QTlFNVxcdUFBMjktXFx1QUEyRVxcdUFBMzFcXHVBQTMyXFx1QUEzNVxcdUFBMzZcXHVBQTQzXFx1QUE0Q1xcdUFBN0NcXHVBQUIwXFx1QUFCMi1cXHVBQUI0XFx1QUFCN1xcdUFBQjhcXHVBQUJFXFx1QUFCRlxcdUFBQzFcXHVBQUVDXFx1QUFFRFxcdUFBRjZcXHVBQkU1XFx1QUJFOFxcdUFCRURcXHVGQjFFXFx1RkIyOVxcdUZEM0VcXHVGRDNGXFx1RkRGRFxcdUZFMDAtXFx1RkUxOVxcdUZFMjAtXFx1RkUyRFxcdUZFMzAtXFx1RkU1MlxcdUZFNTQtXFx1RkU2NlxcdUZFNjgtXFx1RkU2QlxcdUZFRkZcXHVGRjAxLVxcdUZGMjBcXHVGRjNCLVxcdUZGNDBcXHVGRjVCLVxcdUZGNjVcXHVGRkUwLVxcdUZGRTZcXHVGRkU4LVxcdUZGRUVcXHVGRkY5LVxcdUZGRkRdfFxcdUQ4MDBbXFx1REQwMVxcdURENDAtXFx1REQ4Q1xcdUREOTAtXFx1REQ5QlxcdUREQTBcXHVEREZEXFx1REVFMC1cXHVERUZCXFx1REY3Ni1cXHVERjdBXXxcXHVEODAyW1xcdUREMUZcXHVERTAxLVxcdURFMDNcXHVERTA1XFx1REUwNlxcdURFMEMtXFx1REUwRlxcdURFMzgtXFx1REUzQVxcdURFM0ZcXHVERUU1XFx1REVFNlxcdURGMzktXFx1REYzRl18XFx1RDgwM1tcXHVERTYwLVxcdURFN0VdfFtcXHVEODA0XFx1REI0MF1bXFx1REMwMVxcdURDMzgtXFx1REM0NlxcdURDNTItXFx1REM2NVxcdURDN0YtXFx1REM4MVxcdURDQjMtXFx1RENCNlxcdURDQjlcXHVEQ0JBXFx1REQwMC1cXHVERDAyXFx1REQyNy1cXHVERDJCXFx1REQyRC1cXHVERDM0XFx1REQ3M1xcdUREODBcXHVERDgxXFx1RERCNi1cXHVEREJFXFx1REUyRi1cXHVERTMxXFx1REUzNFxcdURFMzZcXHVERTM3XFx1REVERlxcdURFRTMtXFx1REVFQVxcdURGMDFcXHVERjNDXFx1REY0MFxcdURGNjYtXFx1REY2Q1xcdURGNzAtXFx1REY3NF18XFx1RDgwNVtcXHVEQ0IzLVxcdURDQjhcXHVEQ0JBXFx1RENCRlxcdURDQzBcXHVEQ0MyXFx1RENDM1xcdUREQjItXFx1RERCNVxcdUREQkNcXHVEREJEXFx1RERCRlxcdUREQzBcXHVERTMzLVxcdURFM0FcXHVERTNEXFx1REUzRlxcdURFNDBcXHVERUFCXFx1REVBRFxcdURFQjAtXFx1REVCNVxcdURFQjddfFxcdUQ4MUFbXFx1REVGMC1cXHVERUY0XFx1REYzMC1cXHVERjM2XXxcXHVEODFCW1xcdURGOEYtXFx1REY5Ml18XFx1RDgyRltcXHVEQzlEXFx1REM5RVxcdURDQTAtXFx1RENBM118XFx1RDgzNFtcXHVERDY3LVxcdURENjlcXHVERDczLVxcdUREODJcXHVERDg1LVxcdUREOEJcXHVEREFBLVxcdUREQURcXHVERTAwLVxcdURFNDVcXHVERjAwLVxcdURGNTZdfFxcdUQ4MzVbXFx1REVEQlxcdURGMTVcXHVERjRGXFx1REY4OVxcdURGQzNcXHVERkNFLVxcdURGRkZdfFxcdUQ4M0FbXFx1RENEMC1cXHVEQ0Q2XXxcXHVEODNCW1xcdURFRjBcXHVERUYxXXxcXHVEODNDW1xcdURDMDAtXFx1REMyQlxcdURDMzAtXFx1REM5M1xcdURDQTAtXFx1RENBRVxcdURDQjEtXFx1RENCRlxcdURDQzEtXFx1RENDRlxcdURDRDEtXFx1RENGNVxcdUREMDAtXFx1REQwQ1xcdURENkFcXHVERDZCXFx1REYwMC1cXHVERjJDXFx1REYzMC1cXHVERjdEXFx1REY4MC1cXHVERkNFXFx1REZENC1cXHVERkY3XXxcXHVEODNEW1xcdURDMDAtXFx1RENGRVxcdUREMDAtXFx1REQ0QVxcdURENTAtXFx1REQ3OVxcdUREN0ItXFx1RERBM1xcdUREQTUtXFx1REU0MlxcdURFNDUtXFx1REVDRlxcdURFRTAtXFx1REVFQ1xcdURFRjAtXFx1REVGM1xcdURGMDAtXFx1REY3M1xcdURGODAtXFx1REZENF18XFx1RDgzRVtcXHVEQzAwLVxcdURDMEJcXHVEQzEwLVxcdURDNDdcXHVEQzUwLVxcdURDNTlcXHVEQzYwLVxcdURDODdcXHVEQzkwLVxcdURDQURdJztcbi8vIGpzY3M6ZW5hYmxlIG1heGltdW1MaW5lTGVuZ3RoXG4vLyBqc2hpbnQgaWdub3JlOmVuZFxuIiwiLy8gRE8gTk9UIEVESVQhXG4vLyBUSElTIEZJTEUgSVMgR0VORVJBVEVEIVxuXG4vLyBBbGwgYmlkaSBjaGFyYWN0ZXJzIGZvdW5kIGluIGNsYXNzZXMgJ1InLCAnQUwnLCAnUkxFJywgJ1JMTycsIGFuZCAnUkxJJyBhcyBwZXIgVW5pY29kZSA3LjAuMC5cblxuLy8ganNoaW50IGlnbm9yZTpzdGFydFxuLy8ganNjczpkaXNhYmxlIG1heGltdW1MaW5lTGVuZ3RoXG5tb2R1bGUuZXhwb3J0cyA9ICdbXFx1MDVCRVxcdTA1QzBcXHUwNUMzXFx1MDVDNlxcdTA1RDAtXFx1MDVFQVxcdTA1RjAtXFx1MDVGNFxcdTA2MDhcXHUwNjBCXFx1MDYwRFxcdTA2MUJcXHUwNjFDXFx1MDYxRS1cXHUwNjRBXFx1MDY2RC1cXHUwNjZGXFx1MDY3MS1cXHUwNkQ1XFx1MDZFNVxcdTA2RTZcXHUwNkVFXFx1MDZFRlxcdTA2RkEtXFx1MDcwRFxcdTA3MEZcXHUwNzEwXFx1MDcxMi1cXHUwNzJGXFx1MDc0RC1cXHUwN0E1XFx1MDdCMVxcdTA3QzAtXFx1MDdFQVxcdTA3RjRcXHUwN0Y1XFx1MDdGQVxcdTA4MDAtXFx1MDgxNVxcdTA4MUFcXHUwODI0XFx1MDgyOFxcdTA4MzAtXFx1MDgzRVxcdTA4NDAtXFx1MDg1OFxcdTA4NUVcXHUwOEEwLVxcdTA4QjJcXHUyMDBGXFx1MjAyQlxcdTIwMkVcXHUyMDY3XFx1RkIxRFxcdUZCMUYtXFx1RkIyOFxcdUZCMkEtXFx1RkIzNlxcdUZCMzgtXFx1RkIzQ1xcdUZCM0VcXHVGQjQwXFx1RkI0MVxcdUZCNDNcXHVGQjQ0XFx1RkI0Ni1cXHVGQkMxXFx1RkJEMy1cXHVGRDNEXFx1RkQ1MC1cXHVGRDhGXFx1RkQ5Mi1cXHVGREM3XFx1RkRGMC1cXHVGREZDXFx1RkU3MC1cXHVGRTc0XFx1RkU3Ni1cXHVGRUZDXXxcXHVEODAyW1xcdURDMDAtXFx1REMwNVxcdURDMDhcXHVEQzBBLVxcdURDMzVcXHVEQzM3XFx1REMzOFxcdURDM0NcXHVEQzNGLVxcdURDNTVcXHVEQzU3LVxcdURDOUVcXHVEQ0E3LVxcdURDQUZcXHVERDAwLVxcdUREMUJcXHVERDIwLVxcdUREMzlcXHVERDNGXFx1REQ4MC1cXHVEREI3XFx1RERCRVxcdUREQkZcXHVERTAwXFx1REUxMC1cXHVERTEzXFx1REUxNS1cXHVERTE3XFx1REUxOS1cXHVERTMzXFx1REU0MC1cXHVERTQ3XFx1REU1MC1cXHVERTU4XFx1REU2MC1cXHVERTlGXFx1REVDMC1cXHVERUU0XFx1REVFQi1cXHVERUY2XFx1REYwMC1cXHVERjM1XFx1REY0MC1cXHVERjU1XFx1REY1OC1cXHVERjcyXFx1REY3OC1cXHVERjkxXFx1REY5OS1cXHVERjlDXFx1REZBOS1cXHVERkFGXXxcXHVEODAzW1xcdURDMDAtXFx1REM0OF18XFx1RDgzQVtcXHVEQzAwLVxcdURDQzRcXHVEQ0M3LVxcdURDQ0ZdfFxcdUQ4M0JbXFx1REUwMC1cXHVERTAzXFx1REUwNS1cXHVERTFGXFx1REUyMVxcdURFMjJcXHVERTI0XFx1REUyN1xcdURFMjktXFx1REUzMlxcdURFMzQtXFx1REUzN1xcdURFMzlcXHVERTNCXFx1REU0MlxcdURFNDdcXHVERTQ5XFx1REU0QlxcdURFNEQtXFx1REU0RlxcdURFNTFcXHVERTUyXFx1REU1NFxcdURFNTdcXHVERTU5XFx1REU1QlxcdURFNURcXHVERTVGXFx1REU2MVxcdURFNjJcXHVERTY0XFx1REU2Ny1cXHVERTZBXFx1REU2Qy1cXHVERTcyXFx1REU3NC1cXHVERTc3XFx1REU3OS1cXHVERTdDXFx1REU3RVxcdURFODAtXFx1REU4OVxcdURFOEItXFx1REU5QlxcdURFQTEtXFx1REVBM1xcdURFQTUtXFx1REVBOVxcdURFQUItXFx1REVCQl0nO1xuLy8ganNjczplbmFibGUgbWF4aW11bUxpbmVMZW5ndGhcbi8vIGpzaGludCBpZ25vcmU6ZW5kXG4iXX0= diff --git a/dist/react-typeahead-component.min.js b/dist/react-typeahead-component.min.js deleted file mode 100644 index b87c66d..0000000 --- a/dist/react-typeahead-component.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Typeahead=e()}}(function(){return function e(t,n,o){function i(r,a){if(!n[r]){if(!t[r]){var l="function"==typeof require&&require;if(!a&&l)return l(r,!0);if(s)return s(r,!0);var p=new Error("Cannot find module '"+r+"'");throw p.code="MODULE_NOT_FOUND",p}var u=n[r]={exports:{}};t[r][0].call(u.exports,function(e){var n=t[r][1][e];return i(n?n:e)},u,u.exports,e,t,n,o)}return n[r].exports}for(var s="function"==typeof require&&require,r=0;r0&&e.handleHint(t,n).slice(o).length>0;this.setState({isHintVisible:i})},render:function(){var e=this;return o.createElement("div",{style:{position:"relative"},className:"react-typeahead-container "+e.props.className},e.renderInput(),e.renderDropdown(),e.renderAriaMessageForOptions(),e.renderAriaMessageForIncomingOptions())},renderInput:function(){var e=this,t=e.state,n=e.props,s=n.inputValue,a="react-typeahead-input",l=r(s);return o.createElement("div",{style:{position:"relative"},className:"react-typeahead-input-container"},o.createElement(i,{disabled:!0,role:"presentation","aria-hidden":!0,dir:l,className:a+" react-typeahead-hint",style:{color:"silver",WebkitTextFillColor:"silver",position:"absolute"},value:t.isHintVisible?n.handleHint(s,n.options):null}),o.createElement(i,{ref:"input",role:"combobox","aria-owns":e.optionsId,"aria-expanded":t.isDropdownVisible,"aria-autocomplete":"both","aria-activedescendant":e.activeDescendantId,value:s,spellCheck:!1,autoComplete:!1,autoCorrect:!1,dir:l,onClick:e.handleClick,onFocus:e.handleFocus,onBlur:n.onBlur,onChange:e.handleChange,onKeyDown:e.handleKeyDown,id:n.inputId,name:n.inputName,autoFocus:n.autoFocus,placeholder:n.placeholder,onSelect:n.onSelect,onKeyUp:n.onKeyUp,onKeyPress:n.onKeyPress,className:a+" react-typeahead-usertext",style:{position:"relative",background:"transparent"}}))},renderDropdown:function(){var e=this,t=e.state,n=e.props,i=n.optionTemplate,s=t.selectedIndex,r=t.isDropdownVisible,a=e.activeDescendantId;return this.props.options.length<1?null:o.createElement("ul",{id:e.optionsId,ref:"dropdown",role:"listbox","aria-hidden":!r,style:{width:"100%",background:"#fff",position:"absolute",boxSizing:"border-box",display:r?"block":"none"},className:"react-typeahead-options",onMouseOut:this.handleMouseOut},n.options.map(function(t,r){var l=s===r;return o.createElement("li",{id:l?a:null,"aria-selected":l,role:"option",key:r,onClick:e.handleOptionClick.bind(e,r),onMouseOver:e.handleOptionMouseOver.bind(e,r)},o.createElement(i,{data:t,index:r,userInputValue:e.userInputValue,inputValue:n.inputValue,isSelected:l}))}))},renderAriaMessageForOptions:function(){var e=this,t=e.props,n=t.inputValue,i=t.options[e.state.selectedIndex]||n;return o.createElement(s,{message:t.getMessageForOption(i)||n})},renderAriaMessageForIncomingOptions:function(){var e=this.props;return o.createElement(s,{message:e.getMessageForIncomingOptions(e.options.length)})},showDropdown:function(){var e=this;e.state.isDropdownVisible||e.setState({isDropdownVisible:!0},function(){e.props.onDropdownOpen()})},hideDropdown:function(){var e=this;e.state.isDropdownVisible&&e.setState({isDropdownVisible:!1},function(){e.props.onDropdownClose()})},showHint:function(){var e=this,t=e.props,n=t.inputValue,o=n.length,i=o>0&&t.handleHint(n,t.options).slice(o).length>0;e.setState({isHintVisible:i})},hideHint:function(){this.setState({isHintVisible:!1})},setSelectedIndex:function(e,t){this.setState({selectedIndex:e},t)},handleChange:function(e){var t=this;t.showHint(),t.showDropdown(),t.setSelectedIndex(-1),t.props.onChange(e),t.userInputValue=e.target.value},focus:function(){this.refs.input.getDOMNode().focus()},handleFocus:function(e){var t=this;t.showDropdown(),t.props.onFocus(e)},handleClick:function(e){var t=this;t.showHint(),t.props.onInputClick(e)},navigate:function(e,t){var n=this,o=-1,i=n.props.options.length-1,s=n.state.selectedIndex+e;s>i?s=o:o>s&&(s=i),n.setSelectedIndex(s,t)},handleKeyDown:function(e){var t,n,i,s=this,a=e.key,l=s.props,p=s.refs.input,u=s.state.isDropdownVisible,c=s.state.isHintVisible,d=!1;switch(a){case"End":case"Tab":c&&!e.shiftKey&&(e.preventDefault(),l.onComplete(e,l.handleHint(l.inputValue,l.options)));break;case"ArrowLeft":case"ArrowRight":c&&!e.shiftKey&&p.isCursorAtEnd()&&(i=r(l.inputValue),("ltr"===i&&"ArrowRight"===a||"rtl"===i&&"ArrowLeft"===a)&&l.onComplete(e,l.handleHint(l.inputValue,l.options)));break;case"Enter":s.focus(),s.hideHint(),s.hideDropdown();break;case"Escape":s.hideHint(),s.hideDropdown();break;case"ArrowUp":case"ArrowDown":l.options.length>0&&(e.preventDefault(),s.showHint(),s.showDropdown(),u&&(i="ArrowUp"===a?-1:1,d=!0,s.navigate(i,function(){var t,n,i=s.state.selectedIndex,r=s.previousInputValue,a=r,p=0;i>=0&&(null===r&&(s.previousInputValue=l.inputValue),a=l.options[i],n=o.findDOMNode(s.refs.dropdown),t=n.children[i],p=t.offsetTop,(p+t.clientHeight>n.clientHeight||pt?l.inputValue:l.options[t],l.onKeyDown(e,n,t))},handleOptionClick:function(e,t){var n=this,o=n.props;n.focus(),n.hideHint(),n.hideDropdown(),n.setSelectedIndex(e),o.onOptionClick(t,o.options[e],e)},handleOptionMouseOver:function(e){var t=this;t.props.hoverSelect&&t.setSelectedIndex(e)},handleMouseOut:function(){var e=this;e.props.hoverSelect&&e.setSelectedIndex(-1)},handleWindowClose:function(e){var t=this,n=e.target;n===window||this.getDOMNode().contains(n)||(t.hideHint(),t.hideDropdown())}})},{"../utils/get_text_direction":5,"./aria_status.jsx":1,"./input.jsx":2,react:"react"}],4:[function(e,t,n){t.exports=e("./components/typeahead.jsx")},{"./components/typeahead.jsx":3}],5:[function(e,t,n){"use strict";var o=e("./rtl_chars_regexp"),i=e("./neutral_chars_regexp"),s=new RegExp("^(?:"+i+")*(?:"+o+")"),r=new RegExp("^(?:"+i+")*$");t.exports=function(e){var t="ltr";return s.test(e)?t="rtl":r.test(e)&&(t=null),t}},{"./neutral_chars_regexp":6,"./rtl_chars_regexp":7}],6:[function(e,t,n){t.exports="[\x00-@[-`{-\xa9\xab-\xb4\xb6-\xb9\xbb-\xbf\xd7\xf7\u02b9\u02ba\u02c2-\u02cf\u02d2-\u02df\u02e5-\u02ed\u02ef-\u036f\u0374\u0375\u037e\u0384\u0385\u0387\u03f6\u0483-\u0489\u058a\u058d-\u058f\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0600-\u0607\u0609\u060a\u060c\u060e-\u061a\u064b-\u066c\u0670\u06d6-\u06e4\u06e7-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u07f6-\u07f9\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u0902\u093a\u093c\u0941-\u0948\u094d\u0951-\u0957\u0962\u0963\u0981\u09bc\u09c1-\u09c4\u09cd\u09e2\u09e3\u09f2\u09f3\u09fb\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0af1\u0b01\u0b3c\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b62\u0b63\u0b82\u0bc0\u0bcd\u0bf3-\u0bfa\u0c00\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c78-\u0c7e\u0c81\u0cbc\u0ccc\u0ccd\u0ce2\u0ce3\u0d01\u0d41-\u0d44\u0d4d\u0d62\u0d63\u0dca\u0dd2-\u0dd4\u0dd6\u0e31\u0e34-\u0e3a\u0e3f\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39-\u0f3d\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135d-\u135f\u1390-\u1399\u1400\u1680\u169b\u169c\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4\u17b5\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17db\u17dd\u17f0-\u17f9\u1800-\u180e\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1940\u1944\u1945\u19de-\u19ff\u1a17\u1a18\u1a1b\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1ab0-\u1abe\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1bab-\u1bad\u1be6\u1be8\u1be9\u1bed\u1bef-\u1bf1\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfc-\u1dff\u1fbd\u1fbf-\u1fc1\u1fcd-\u1fcf\u1fdd-\u1fdf\u1fed-\u1fef\u1ffd\u1ffe\u2000-\u200d\u2010-\u2029\u202f-\u2064\u2068\u206a-\u2070\u2074-\u207e\u2080-\u208e\u20a0-\u20bd\u20d0-\u20f0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211e-\u2123\u2125\u2127\u2129\u212e\u213a\u213b\u2140-\u2144\u214a-\u214d\u2150-\u215f\u2189\u2190-\u2335\u237b-\u2394\u2396-\u23fa\u2400-\u2426\u2440-\u244a\u2460-\u249b\u24ea-\u26ab\u26ad-\u27ff\u2900-\u2b73\u2b76-\u2b95\u2b98-\u2bb9\u2bbd-\u2bc8\u2bca-\u2bd1\u2ce5-\u2cea\u2cef-\u2cf1\u2cf9-\u2cff\u2d7f\u2de0-\u2e42\u2e80-\u2e99\u2e9b-\u2ef3\u2f00-\u2fd5\u2ff0-\u2ffb\u3000-\u3004\u3008-\u3020\u302a-\u302d\u3030\u3036\u3037\u303d-\u303f\u3099-\u309c\u30a0\u30fb\u31c0-\u31e3\u321d\u321e\u3250-\u325f\u327c-\u327e\u32b1-\u32bf\u32cc-\u32cf\u3377-\u337a\u33de\u33df\u33ff\u4dc0-\u4dff\ua490-\ua4c6\ua60d-\ua60f\ua66f-\ua67f\ua69f\ua6f0\ua6f1\ua700-\ua721\ua788\ua802\ua806\ua80b\ua825\ua826\ua828-\ua82b\ua838\ua839\ua874-\ua877\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\ua9e5\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaa7c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaec\uaaed\uaaf6\uabe5\uabe8\uabed\ufb1e\ufb29\ufd3e\ufd3f\ufdfd\ufe00-\ufe19\ufe20-\ufe2d\ufe30-\ufe52\ufe54-\ufe66\ufe68-\ufe6b\ufeff\uff01-\uff20\uff3b-\uff40\uff5b-\uff65\uffe0-\uffe6\uffe8-\uffee\ufff9-\ufffd]|\ud800[\udd01\udd40-\udd8c\udd90-\udd9b\udda0\uddfd\udee0-\udefb\udf76-\udf7a]|\ud802[\udd1f\ude01-\ude03\ude05\ude06\ude0c-\ude0f\ude38-\ude3a\ude3f\udee5\udee6\udf39-\udf3f]|\ud803[\ude60-\ude7e]|[\ud804\udb40][\udc01\udc38-\udc46\udc52-\udc65\udc7f-\udc81\udcb3-\udcb6\udcb9\udcba\udd00-\udd02\udd27-\udd2b\udd2d-\udd34\udd73\udd80\udd81\uddb6-\uddbe\ude2f-\ude31\ude34\ude36\ude37\udedf\udee3-\udeea\udf01\udf3c\udf40\udf66-\udf6c\udf70-\udf74]|\ud805[\udcb3-\udcb8\udcba\udcbf\udcc0\udcc2\udcc3\uddb2-\uddb5\uddbc\uddbd\uddbf\uddc0\ude33-\ude3a\ude3d\ude3f\ude40\udeab\udead\udeb0-\udeb5\udeb7]|\ud81a[\udef0-\udef4\udf30-\udf36]|\ud81b[\udf8f-\udf92]|\ud82f[\udc9d\udc9e\udca0-\udca3]|\ud834[\udd67-\udd69\udd73-\udd82\udd85-\udd8b\uddaa-\uddad\ude00-\ude45\udf00-\udf56]|\ud835[\udedb\udf15\udf4f\udf89\udfc3\udfce-\udfff]|\ud83a[\udcd0-\udcd6]|\ud83b[\udef0\udef1]|\ud83c[\udc00-\udc2b\udc30-\udc93\udca0-\udcae\udcb1-\udcbf\udcc1-\udccf\udcd1-\udcf5\udd00-\udd0c\udd6a\udd6b\udf00-\udf2c\udf30-\udf7d\udf80-\udfce\udfd4-\udff7]|\ud83d[\udc00-\udcfe\udd00-\udd4a\udd50-\udd79\udd7b-\udda3\udda5-\ude42\ude45-\udecf\udee0-\udeec\udef0-\udef3\udf00-\udf73\udf80-\udfd4]|\ud83e[\udc00-\udc0b\udc10-\udc47\udc50-\udc59\udc60-\udc87\udc90-\udcad]"},{}],7:[function(e,t,n){t.exports="[\u05be\u05c0\u05c3\u05c6\u05d0-\u05ea\u05f0-\u05f4\u0608\u060b\u060d\u061b\u061c\u061e-\u064a\u066d-\u066f\u0671-\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u070d\u070f\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07c0-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0830-\u083e\u0840-\u0858\u085e\u08a0-\u08b2\u200f\u202b\u202e\u2067\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbc1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfc\ufe70-\ufe74\ufe76-\ufefc]|\ud802[\udc00-\udc05\udc08\udc0a-\udc35\udc37\udc38\udc3c\udc3f-\udc55\udc57-\udc9e\udca7-\udcaf\udd00-\udd1b\udd20-\udd39\udd3f\udd80-\uddb7\uddbe\uddbf\ude00\ude10-\ude13\ude15-\ude17\ude19-\ude33\ude40-\ude47\ude50-\ude58\ude60-\ude9f\udec0-\udee4\udeeb-\udef6\udf00-\udf35\udf40-\udf55\udf58-\udf72\udf78-\udf91\udf99-\udf9c\udfa9-\udfaf]|\ud803[\udc00-\udc48]|\ud83a[\udc00-\udcc4\udcc7-\udccf]|\ud83b[\ude00-\ude03\ude05-\ude1f\ude21\ude22\ude24\ude27\ude29-\ude32\ude34-\ude37\ude39\ude3b\ude42\ude47\ude49\ude4b\ude4d-\ude4f\ude51\ude52\ude54\ude57\ude59\ude5b\ude5d\ude5f\ude61\ude62\ude64\ude67-\ude6a\ude6c-\ude72\ude74-\ude77\ude79-\ude7c\ude7e\ude80-\ude89\ude8b-\ude9b\udea1-\udea3\udea5-\udea9\udeab-\udebb]"},{}]},{},[4])(4)}); diff --git a/example/netflix/index.html b/example/netflix/index.html index bfdec90..6aa2783 100644 --- a/example/netflix/index.html +++ b/example/netflix/index.html @@ -7,7 +7,8 @@

Netflix Typeahead Widget

- + + diff --git a/example/netflix/js/app.jsx b/example/netflix/js/app.jsx index a72e316..59c9f0a 100644 --- a/example/netflix/js/app.jsx +++ b/example/netflix/js/app.jsx @@ -104,4 +104,4 @@ var MyApp = React.createClass({ } }); -React.render(, document.getElementById('nf-typeahead')); +ReactDOM.render(, document.getElementById('nf-typeahead')); diff --git a/example/netflix/js/bundle.js b/example/netflix/js/bundle.js index 6b6698c..13216a8 100644 --- a/example/netflix/js/bundle.js +++ b/example/netflix/js/bundle.js @@ -105,7 +105,7 @@ var MyApp = React.createClass({displayName: "MyApp", } }); -React.render(React.createElement(MyApp, null), document.getElementById('nf-typeahead')); +ReactDOM.render(React.createElement(MyApp, null), document.getElementById('nf-typeahead')); },{"./components/OptionTemplate.jsx":2,"./utils/OptionWebAPIUtils":3,"rx":9}],2:[function(require,module,exports){ var cx = require('classnames'); @@ -875,7 +875,7 @@ function plural(ms, n, name) { },{}],9:[function(require,module,exports){ (function (process,global){ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - + ;(function (undefined) { var objectTypes = { @@ -904,7 +904,7 @@ function plural(ms, n, name) { }, helpers: { } }; - + // Defaults var noop = Rx.helpers.noop = function () { }, notDefined = Rx.helpers.notDefined = function (x) { return typeof x === 'undefined'; }, @@ -936,7 +936,7 @@ function plural(ms, n, name) { }()); function cloneArray(arr) { for(var a = [], i = 0, len = arr.length; i < len; i++) { a.push(arr[i]); } return a;} - + Rx.config.longStackSupport = false; var hasStacks = false; try { @@ -947,7 +947,7 @@ function plural(ms, n, name) { // All code after this point will be filtered from stack traces reported by RxJS var rStartingLine = captureLine(), rFileName; - + var STACK_JUMP_SEPARATOR = "From previous event:"; function makeStackTraceLong(error, observable) { @@ -1032,7 +1032,7 @@ function plural(ms, n, name) { var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine); if (attempt3) { return [attempt3[1], Number(attempt3[2])]; } } - + var EmptyError = Rx.EmptyError = function() { this.message = 'Sequence contains no elements.'; Error.call(this); @@ -1070,7 +1070,7 @@ function plural(ms, n, name) { var notSupported = Rx.helpers.notSupported = function () { throw new NotSupportedError(); }; - + // Shim in iterator support var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) || '_es6shim_iterator_'; @@ -1090,7 +1090,7 @@ function plural(ms, n, name) { } Rx.helpers.iterator = $iterator$; - + var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) { if (typeof thisArg === 'undefined') { return func; } switch(argCount) { @@ -1116,7 +1116,7 @@ function plural(ms, n, name) { return func.apply(thisArg, arguments); }; }; - + /** Used to determine if values are of the language type Object */ var dontEnums = ['toString', 'toLocaleString', @@ -1126,7 +1126,7 @@ function plural(ms, n, name) { 'propertyIsEnumerable', 'constructor'], dontEnumsLength = dontEnums.length; - + /** `Object#toString` result shortcuts */ var argsClass = '[object Arguments]', arrayClass = '[object Array]', @@ -1401,7 +1401,7 @@ function plural(ms, n, name) { return result; } - + var hasProp = {}.hasOwnProperty, slice = Array.prototype.slice; @@ -1435,7 +1435,7 @@ function plural(ms, n, name) { } return a; } - + var errorObj = {e: {}}; var tryCatchTarget; function tryCatcher() { @@ -1454,7 +1454,7 @@ function plural(ms, n, name) { function thrower(e) { throw e; } - + // Collections function IndexedItem(id, value) { this.id = id; @@ -1540,7 +1540,7 @@ function plural(ms, n, name) { return false; }; PriorityQueue.count = 0; - + /** * Represents a group of disposable resources that are disposed together. * @constructor @@ -1613,7 +1613,7 @@ function plural(ms, n, name) { } } }; - + /** * Provides a set of static methods for creating Disposables. * @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once. @@ -1655,7 +1655,7 @@ function plural(ms, n, name) { var checkDisposed = Disposable.checkDisposed = function (disposable) { if (disposable.isDisposed) { throw new ObjectDisposedError(); } }; - + // Single assignment var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () { this.isDisposed = false; @@ -1704,7 +1704,7 @@ function plural(ms, n, name) { } old && old.dispose(); }; - + /** * Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed. */ @@ -1762,7 +1762,7 @@ function plural(ms, n, name) { return RefCountDisposable; })(); - + function ScheduledDisposable(scheduler, disposable) { this.scheduler = scheduler; this.disposable = disposable; @@ -1779,7 +1779,7 @@ function plural(ms, n, name) { ScheduledDisposable.prototype.dispose = function () { this.scheduler.scheduleWithState(this, scheduleItem); }; - + var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) { this.scheduler = scheduler; this.state = state; @@ -1804,7 +1804,7 @@ function plural(ms, n, name) { ScheduledItem.prototype.invokeCore = function () { return this.action(this.scheduler, this.state); }; - + /** Provides a set of static properties to access commonly used schedulers. */ var Scheduler = Rx.Scheduler = (function () { @@ -1905,7 +1905,7 @@ function plural(ms, n, name) { }()); var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler; - + (function (schedulerProto) { function invokeRecImmediate(scheduler, pair) { @@ -2026,7 +2026,7 @@ function plural(ms, n, name) { }); }; }(Scheduler.prototype)); - + (function (schedulerProto) { /** @@ -2054,7 +2054,7 @@ function plural(ms, n, name) { }; }(Scheduler.prototype)); - + (function (schedulerProto) { /** * Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions. @@ -2065,7 +2065,7 @@ function plural(ms, n, name) { return new CatchScheduler(this, handler); }; }(Scheduler.prototype)); - + var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () { function tick(command, recurse) { recurse(0, this._period); @@ -2094,13 +2094,13 @@ function plural(ms, n, name) { return SchedulePeriodicRecursive; }()); - + /** Gets a scheduler that schedules work immediately on the current thread. */ var immediateScheduler = Scheduler.immediate = (function () { function scheduleNow(state, action) { return action(this, state); } return new Scheduler(defaultNow, scheduleNow, notSupported, notSupported); }()); - + /** * Gets a scheduler that schedules work as soon as possible on the current thread. */ @@ -2135,7 +2135,7 @@ function plural(ms, n, name) { return currentScheduler; }()); - + var scheduleMethod, clearMethod; var localTimer = (function () { @@ -2318,7 +2318,7 @@ function plural(ms, n, name) { return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute); })(); - + var CatchScheduler = (function (__super__) { function scheduleNow(state, action) { @@ -2390,7 +2390,7 @@ function plural(ms, n, name) { return CatchScheduler; }(Scheduler)); - + /** * Represents a notification to an observer. */ @@ -2483,7 +2483,7 @@ function plural(ms, n, name) { return new Notification('C', null, null, _accept, _acceptObservable, toString); }; }()); - + /** * Supports push-style iteration over an observable sequence. */ @@ -2557,7 +2557,7 @@ function plural(ms, n, name) { Observer.prototype.makeSafe = function(disposable) { return new AnonymousSafeObserver(this._onNext, this._onError, this._onCompleted, disposable); }; - + /** * Abstract base class for implementations of the Observer class. * This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages. @@ -2626,7 +2626,7 @@ function plural(ms, n, name) { return AbstractObserver; }(Observer)); - + /** * Class to create an Observer instance from delegate-based implementations of the on* methods. */ @@ -2671,7 +2671,7 @@ function plural(ms, n, name) { return AnonymousObserver; }(AbstractObserver)); - + var CheckedObserver = (function (__super__) { inherits(CheckedObserver, __super__); @@ -2712,7 +2712,7 @@ function plural(ms, n, name) { return CheckedObserver; }(Observer)); - + var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) { inherits(ScheduledObserver, __super__); @@ -2775,7 +2775,7 @@ function plural(ms, n, name) { return ScheduledObserver; }(AbstractObserver)); - + var ObserveOnObserver = (function (__super__) { inherits(ObserveOnObserver, __super__); @@ -2807,7 +2807,7 @@ function plural(ms, n, name) { return ObserveOnObserver; })(ScheduledObserver); - + var observableProto; /** @@ -2886,7 +2886,7 @@ function plural(ms, n, name) { return Observable; })(); - + var ObservableBase = Rx.ObservableBase = (function (__super__) { inherits(ObservableBase, __super__); @@ -2924,7 +2924,7 @@ function plural(ms, n, name) { return ObservableBase; }(Observable)); - + var Enumerable = Rx.internals.Enumerable = function () { }; var ConcatEnumerableObservable = (function(__super__) { @@ -3148,7 +3148,7 @@ function plural(ms, n, name) { var enumerableOf = Enumerable.of = function (source, selector, thisArg) { return new OfEnumerable(source, selector, thisArg); }; - + /** * Wraps the source sequence in order to run its observer callbacks on the specified scheduler. * @@ -3164,7 +3164,7 @@ function plural(ms, n, name) { return source.subscribe(new ObserveOnObserver(scheduler, observer)); }, source); }; - + /** * Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used; * see the remarks section for more information on the distinction between subscribeOn and observeOn. @@ -3186,7 +3186,7 @@ function plural(ms, n, name) { return d; }, source); }; - + var FromPromiseObservable = (function(__super__) { inherits(FromPromiseObservable, __super__); function FromPromiseObservable(p) { @@ -3212,7 +3212,7 @@ function plural(ms, n, name) { */ var observableFromPromise = Observable.fromPromise = function (promise) { return new FromPromiseObservable(promise); - }; + }; /* * Converts an existing observable sequence to an ES6 Compatible Promise * @example @@ -3239,7 +3239,7 @@ function plural(ms, n, name) { }); }); }; - + var ToArrayObservable = (function(__super__) { inherits(ToArrayObservable, __super__); function ToArrayObservable(source) { @@ -3291,7 +3291,7 @@ function plural(ms, n, name) { observableProto.toArray = function () { return new ToArrayObservable(this); }; - + /** * Creates an observable sequence from a specified subscribe method implementation. * @example @@ -3304,7 +3304,7 @@ function plural(ms, n, name) { Observable.create = Observable.createWithDisposable = function (subscribe, parent) { return new AnonymousObservable(subscribe, parent); }; - + /** * Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes. * @@ -3325,7 +3325,7 @@ function plural(ms, n, name) { return result.subscribe(observer); }); }; - + var EmptyObservable = (function(__super__) { inherits(EmptyObservable, __super__); function EmptyObservable(scheduler) { @@ -3367,7 +3367,7 @@ function plural(ms, n, name) { isScheduler(scheduler) || (scheduler = immediateScheduler); return new EmptyObservable(scheduler); }; - + var FromObservable = (function(__super__) { inherits(FromObservable, __super__); function FromObservable(iterable, mapper, scheduler) { @@ -3532,7 +3532,7 @@ function plural(ms, n, name) { isScheduler(scheduler) || (scheduler = currentThreadScheduler); return new FromObservable(iterable, mapper, scheduler); } - + var FromArrayObservable = (function(__super__) { inherits(FromArrayObservable, __super__); function FromArrayObservable(args, scheduler) { @@ -3567,7 +3567,7 @@ function plural(ms, n, name) { return this.parent.scheduler.scheduleRecursiveWithState(0, loopRecursive); }; - + /** * Converts an array to an observable sequence, using an optional scheduler to enumerate the array. * @deprecated use Observable.from or Observable.of @@ -3578,7 +3578,7 @@ function plural(ms, n, name) { isScheduler(scheduler) || (scheduler = currentThreadScheduler); return new FromArrayObservable(array, scheduler) }; - + /** * Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages. * @@ -3618,7 +3618,7 @@ function plural(ms, n, name) { }); }); }; - + function observableOf (scheduler, array) { isScheduler(scheduler) || (scheduler = currentThreadScheduler); return new FromArrayObservable(array, scheduler); @@ -3644,7 +3644,7 @@ function plural(ms, n, name) { for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; } return new FromArrayObservable(args, scheduler); }; - + /** * Creates an Observable sequence from changes to an array using Array.observe. * @param {Array} array An array to observe changes. @@ -3667,7 +3667,7 @@ function plural(ms, n, name) { }; }); }; - + /** * Creates an Observable sequence from changes to an object using Object.observe. * @param {Object} obj An object to observe changes. @@ -3690,7 +3690,7 @@ function plural(ms, n, name) { }; }); }; - + var NeverObservable = (function(__super__) { inherits(NeverObservable, __super__); function NeverObservable() { @@ -3711,7 +3711,7 @@ function plural(ms, n, name) { var observableNever = Observable.never = function () { return new NeverObservable(); }; - + var PairsObservable = (function(__super__) { inherits(PairsObservable, __super__); function PairsObservable(obj, scheduler) { @@ -3759,7 +3759,7 @@ function plural(ms, n, name) { scheduler || (scheduler = currentThreadScheduler); return new PairsObservable(obj, scheduler); }; - + var RangeObservable = (function(__super__) { inherits(RangeObservable, __super__); function RangeObservable(start, count, scheduler) { @@ -3811,7 +3811,7 @@ function plural(ms, n, name) { isScheduler(scheduler) || (scheduler = currentThreadScheduler); return new RangeObservable(start, count, scheduler); }; - + var RepeatObservable = (function(__super__) { inherits(RepeatObservable, __super__); function RepeatObservable(value, repeatCount, scheduler) { @@ -3859,7 +3859,7 @@ function plural(ms, n, name) { isScheduler(scheduler) || (scheduler = currentThreadScheduler); return new RepeatObservable(value, repeatCount, scheduler); }; - + var JustObservable = (function(__super__) { inherits(JustObservable, __super__); function JustObservable(value, scheduler) { @@ -3902,7 +3902,7 @@ function plural(ms, n, name) { isScheduler(scheduler) || (scheduler = immediateScheduler); return new JustObservable(value, scheduler); }; - + var ThrowObservable = (function(__super__) { inherits(ThrowObservable, __super__); function ThrowObservable(error, scheduler) { @@ -3944,7 +3944,7 @@ function plural(ms, n, name) { isScheduler(scheduler) || (scheduler = immediateScheduler); return new ThrowObservable(error, scheduler); }; - + /** * Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime. * @param {Function} resourceFactory Factory function to obtain a resource object. @@ -3964,7 +3964,7 @@ function plural(ms, n, name) { return new CompositeDisposable(source.subscribe(observer), disposable); }); }; - + /** * Propagates the observable sequence or Promise that reacts first. * @param {Observable} rightSource Second observable sequence or Promise. @@ -4019,7 +4019,7 @@ function plural(ms, n, name) { return new CompositeDisposable(leftSubscription, rightSubscription); }); }; - + /** * Propagates the observable sequence or Promise that reacts first. * @@ -4043,7 +4043,7 @@ function plural(ms, n, name) { } return acc; }; - + function observableCatchHandler(source, handler) { return new AnonymousObservable(function (o) { var d1 = new SingleAssignmentDisposable(), subscription = new SerialDisposable(); @@ -4078,7 +4078,7 @@ function plural(ms, n, name) { observableCatchHandler(this, handlerOrSecond) : observableCatch([this, handlerOrSecond]); }; - + /** * Continues an observable sequence that is terminated by an exception with the next observable sequence. * @param {Array | Arguments} args Arguments or an array to use as the next sequence if an error occurs. @@ -4093,7 +4093,7 @@ function plural(ms, n, name) { } return enumerableOf(items).catchError(); }; - + /** * Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element. * This can be in the form of an argument list of observables or an array. @@ -4113,7 +4113,7 @@ function plural(ms, n, name) { } return combineLatest.apply(this, args); }; - + /** * Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element. * @@ -4174,7 +4174,7 @@ function plural(ms, n, name) { return new CompositeDisposable(subscriptions); }, this); }; - + /** * Concatenates all the observable sequences. This takes in either an array or variable arguments to concatenate. * @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order. @@ -4184,69 +4184,69 @@ function plural(ms, n, name) { args.unshift(this); return observableConcat.apply(null, args); }; - - var ConcatObservable = (function(__super__) { - inherits(ConcatObservable, __super__); - function ConcatObservable(sources) { - this.sources = sources; - __super__.call(this); - } - - ConcatObservable.prototype.subscribeCore = function(o) { - var sink = new ConcatSink(this.sources, o); - return sink.run(); - }; - - function ConcatSink(sources, o) { - this.sources = sources; - this.o = o; - } - ConcatSink.prototype.run = function () { - var isDisposed, subscription = new SerialDisposable(), sources = this.sources, length = sources.length, o = this.o; - var cancelable = immediateScheduler.scheduleRecursiveWithState(0, function (i, self) { - if (isDisposed) { return; } - if (i === length) { - return o.onCompleted(); - } - - // Check if promise - var currentValue = sources[i]; - isPromise(currentValue) && (currentValue = observableFromPromise(currentValue)); - - var d = new SingleAssignmentDisposable(); - subscription.setDisposable(d); - d.setDisposable(currentValue.subscribe( - function (x) { o.onNext(x); }, - function (e) { o.onError(e); }, - function () { self(i + 1); } - )); - }); - - return new CompositeDisposable(subscription, cancelable, disposableCreate(function () { - isDisposed = true; - })); - }; - - - return ConcatObservable; - }(ObservableBase)); - - /** - * Concatenates all the observable sequences. - * @param {Array | Arguments} args Arguments or an array to concat to the observable sequence. - * @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order. - */ - var observableConcat = Observable.concat = function () { - var args; - if (Array.isArray(arguments[0])) { - args = arguments[0]; - } else { - args = new Array(arguments.length); - for(var i = 0, len = arguments.length; i < len; i++) { args[i] = arguments[i]; } - } - return new ConcatObservable(args); - }; - + + var ConcatObservable = (function(__super__) { + inherits(ConcatObservable, __super__); + function ConcatObservable(sources) { + this.sources = sources; + __super__.call(this); + } + + ConcatObservable.prototype.subscribeCore = function(o) { + var sink = new ConcatSink(this.sources, o); + return sink.run(); + }; + + function ConcatSink(sources, o) { + this.sources = sources; + this.o = o; + } + ConcatSink.prototype.run = function () { + var isDisposed, subscription = new SerialDisposable(), sources = this.sources, length = sources.length, o = this.o; + var cancelable = immediateScheduler.scheduleRecursiveWithState(0, function (i, self) { + if (isDisposed) { return; } + if (i === length) { + return o.onCompleted(); + } + + // Check if promise + var currentValue = sources[i]; + isPromise(currentValue) && (currentValue = observableFromPromise(currentValue)); + + var d = new SingleAssignmentDisposable(); + subscription.setDisposable(d); + d.setDisposable(currentValue.subscribe( + function (x) { o.onNext(x); }, + function (e) { o.onError(e); }, + function () { self(i + 1); } + )); + }); + + return new CompositeDisposable(subscription, cancelable, disposableCreate(function () { + isDisposed = true; + })); + }; + + + return ConcatObservable; + }(ObservableBase)); + + /** + * Concatenates all the observable sequences. + * @param {Array | Arguments} args Arguments or an array to concat to the observable sequence. + * @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order. + */ + var observableConcat = Observable.concat = function () { + var args; + if (Array.isArray(arguments[0])) { + args = arguments[0]; + } else { + args = new Array(arguments.length); + for(var i = 0, len = arguments.length; i < len; i++) { args[i] = arguments[i]; } + } + return new ConcatObservable(args); + }; + /** * Concatenates an observable sequence of observable sequences. * @returns {Observable} An observable sequence that contains the elements of each observed inner sequence, in sequential order. @@ -4254,7 +4254,7 @@ function plural(ms, n, name) { observableProto.concatAll = observableProto.concatObservable = function () { return this.merge(1); }; - + var MergeObservable = (function (__super__) { inherits(MergeObservable, __super__); @@ -4381,7 +4381,7 @@ function plural(ms, n, name) { observableMerge(this, maxConcurrentOrOther) : new MergeObservable(this, maxConcurrentOrOther); }; - + /** * Merges all the observable sequences into a single observable sequence. * The scheduler is optional and if not specified, the immediate scheduler is used. @@ -4404,7 +4404,7 @@ function plural(ms, n, name) { } return observableOf(scheduler, sources).mergeAll(); }; - + var MergeAllObservable = (function (__super__) { inherits(MergeAllObservable, __super__); @@ -4501,7 +4501,7 @@ function plural(ms, n, name) { observableProto.mergeAll = observableProto.mergeObservable = function () { return new MergeAllObservable(this); }; - + var CompositeError = Rx.CompositeError = function(errors) { this.name = "NotImplementedError"; this.innerErrors = errors; @@ -4582,7 +4582,7 @@ function plural(ms, n, name) { return group; }); }; - + /** * Continues an observable sequence that is terminated normally or by an exception with the next observable sequence. * @param {Observable} second Second observable sequence used to produce results after the first sequence terminates. @@ -4592,7 +4592,7 @@ function plural(ms, n, name) { if (!second) { throw new Error('Second observable is required'); } return onErrorResumeNext([this, second]); }; - + /** * Continues an observable sequence that is terminated normally or by an exception with the next observable sequence. * @@ -4625,7 +4625,7 @@ function plural(ms, n, name) { return new CompositeDisposable(subscription, cancelable); }); }; - + /** * Returns the values from the source observable sequence only after the other observable sequence produces a value. * @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence. @@ -4655,7 +4655,7 @@ function plural(ms, n, name) { return disposables; }, source); }; - + var SwitchObservable = (function(__super__) { inherits(SwitchObservable, __super__); function SwitchObservable(source) { @@ -4751,7 +4751,7 @@ function plural(ms, n, name) { observableProto['switch'] = observableProto.switchLatest = function () { return new SwitchObservable(this); }; - + var TakeUntilObservable = (function(__super__) { inherits(TakeUntilObservable, __super__); @@ -4806,7 +4806,7 @@ function plural(ms, n, name) { observableProto.takeUntil = function (other) { return new TakeUntilObservable(this, other); }; - + function falseFactory() { return false; } /** @@ -4854,7 +4854,7 @@ function plural(ms, n, name) { return new CompositeDisposable(subscriptions); }, this); }; - + function zipArray(second, resultSelector) { var first = this; return new AnonymousObservable(function (o) { @@ -4917,7 +4917,7 @@ function plural(ms, n, name) { return new CompositeDisposable(subscriptions); }, parent); }; - + /** * Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. * @param arguments Observable sources. @@ -4930,7 +4930,7 @@ function plural(ms, n, name) { var first = args.shift(); return first.zip.apply(first, args); }; - + function falseFactory() { return false; } function arrayFactory() { return []; } @@ -4975,7 +4975,7 @@ function plural(ms, n, name) { return new CompositeDisposable(subscriptions); }); }; - + /** * Hides the identity of an observable sequence. * @returns {Observable} An observable sequence that hides the identity of the source sequence. @@ -4984,7 +4984,7 @@ function plural(ms, n, name) { var source = this; return new AnonymousObservable(function (o) { return source.subscribe(o); }, source); }; - + /** * Projects each element of an observable sequence into zero or more buffers which are produced based on element count information. * @@ -5005,7 +5005,7 @@ function plural(ms, n, name) { return x.length > 0; }); }; - + /** * Dematerializes the explicit notification values of an observable sequence as implicit notifications. * @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values. @@ -5016,7 +5016,7 @@ function plural(ms, n, name) { return source.subscribe(function (x) { return x.accept(o); }, function(e) { o.onError(e); }, function () { o.onCompleted(); }); }, this); }; - + /** * Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer. * @@ -5051,7 +5051,7 @@ function plural(ms, n, name) { }, function (e) { o.onError(e); }, function () { o.onCompleted(); }); }, this); }; - + var TapObservable = (function(__super__) { inherits(TapObservable,__super__); function TapObservable(source, observerOrOnNext, onError, onCompleted) { @@ -5150,7 +5150,7 @@ function plural(ms, n, name) { observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) { return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted); }; - + /** * Invokes a specified action after the source observable sequence terminates gracefully or exceptionally. * @param {Function} finallyAction Action to invoke after the source observable sequence terminates. @@ -5185,7 +5185,7 @@ function plural(ms, n, name) { //deprecate('finallyAction', 'finally or ensure'); return this.ensure(action); }; - + var IgnoreElementsObservable = (function(__super__) { inherits(IgnoreElementsObservable, __super__); @@ -5236,7 +5236,7 @@ function plural(ms, n, name) { observableProto.ignoreElements = function () { return new IgnoreElementsObservable(this); }; - + /** * Materializes the implicit notifications of an observable sequence as explicit notification values. * @returns {Observable} An observable sequence containing the materialized notification values from the source sequence. @@ -5255,7 +5255,7 @@ function plural(ms, n, name) { }); }, source); }; - + /** * Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely. * @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely. @@ -5264,7 +5264,7 @@ function plural(ms, n, name) { observableProto.repeat = function (repeatCount) { return enumerableRepeat(this, repeatCount).concat(); }; - + /** * Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely. * Note if you encounter an error and want it to retry once, then you must use .retry(2); @@ -5278,7 +5278,7 @@ function plural(ms, n, name) { observableProto.retry = function (retryCount) { return enumerableRepeat(this, retryCount).catchError(); }; - + /** * Repeats the source observable sequence upon error each time the notifier emits or until it successfully terminates. * if the notifier completes, the observable sequence completes. @@ -5291,7 +5291,7 @@ function plural(ms, n, name) { */ observableProto.retryWhen = function (notifier) { return enumerableRepeat(this).catchErrorWhen(notifier); - }; + }; var ScanObservable = (function(__super__) { inherits(ScanObservable, __super__); function ScanObservable(source, accumulator, hasSeed, seed) { @@ -5375,7 +5375,7 @@ function plural(ms, n, name) { } return new ScanObservable(this, accumulator, hasSeed, seed); }; - + /** * Bypasses a specified number of elements at the end of an observable sequence. * @description @@ -5395,7 +5395,7 @@ function plural(ms, n, name) { }, function (e) { o.onError(e); }, function () { o.onCompleted(); }); }, source); }; - + /** * Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend. * @example @@ -5415,7 +5415,7 @@ function plural(ms, n, name) { for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); } return enumerableOf([observableFromArray(args, scheduler), this]).concat(); }; - + /** * Returns a specified number of contiguous elements from the end of an observable sequence. * @description @@ -5438,7 +5438,7 @@ function plural(ms, n, name) { }); }, source); }; - + /** * Returns an array with the specified number of contiguous elements from the end of an observable sequence. * @@ -5461,7 +5461,7 @@ function plural(ms, n, name) { }); }, source); }; - + /** * Projects each element of an observable sequence into zero or more windows which are produced based on element count information. * @@ -5514,7 +5514,7 @@ function plural(ms, n, name) { return refCountDisposable; }, source); }; - + function concatMap(source, selector, thisArg) { var selectorFunc = bindCallback(selector, thisArg, 3); return source.map(function (x, i) { @@ -5560,7 +5560,7 @@ function plural(ms, n, name) { concatMap(this, selector, thisArg) : concatMap(this, function () { return selector; }); }; - + /** * Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence. * @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element. @@ -5614,7 +5614,7 @@ function plural(ms, n, name) { }); }, this).concatAll(); }; - + /** * Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty. * @@ -5641,7 +5641,7 @@ function plural(ms, n, name) { }); }, source); }; - + // Swap out for Array.findIndex function arrayIndexOfComparer(array, item, comparer) { for (var i = 0, len = array.length; i < len; i++) { @@ -5693,7 +5693,7 @@ function plural(ms, n, name) { function (e) { o.onError(e); }, function () { o.onCompleted(); }); }, this); }; - + /** * Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function. * @@ -5709,7 +5709,7 @@ function plural(ms, n, name) { observableProto.groupBy = function (keySelector, elementSelector, comparer) { return this.groupByUntil(keySelector, elementSelector, observableNever, comparer); }; - + /** * Groups the elements of an observable sequence according to a specified key selector function. * A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same @@ -5807,7 +5807,7 @@ function plural(ms, n, name) { return refCountDisposable; }, source); }; - + var MapObservable = (function (__super__) { inherits(MapObservable, __super__); @@ -5878,7 +5878,7 @@ function plural(ms, n, name) { this.internalMap(selectorFn, thisArg) : new MapObservable(this, selectorFn, thisArg); }; - + /** * Retrieves the value of a specified nested property from all elements in * the Observable sequence. @@ -5901,7 +5901,7 @@ function plural(ms, n, name) { return currentProp; }); }; - + function flatMap(source, selector, thisArg) { var selectorFunc = bindCallback(selector, thisArg, 3); return source.map(function (x, i) { @@ -5947,7 +5947,7 @@ function plural(ms, n, name) { flatMap(this, selector, thisArg) : flatMap(this, function () { return selector; }); }; - + /** * Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. * @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element. @@ -5999,7 +5999,7 @@ function plural(ms, n, name) { }); }, source).mergeAll(); }; - + /** * Projects each element of an observable sequence into a new sequence of observable sequences by incorporating the element's index and then * transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. @@ -6011,7 +6011,7 @@ function plural(ms, n, name) { observableProto.selectSwitch = observableProto.flatMapLatest = observableProto.switchMap = function (selector, thisArg) { return this.select(selector, thisArg).switchLatest(); }; - + var SkipObservable = (function(__super__) { inherits(SkipObservable, __super__); function SkipObservable(source, count) { @@ -6065,7 +6065,7 @@ function plural(ms, n, name) { observableProto.skip = function (count) { if (count < 0) { throw new ArgumentOutOfRangeError(); } return new SkipObservable(this, count); - }; + }; /** * Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements. * The element's index is used in the logic of the predicate function. @@ -6094,7 +6094,7 @@ function plural(ms, n, name) { }, function (e) { o.onError(e); }, function () { o.onCompleted(); }); }, source); }; - + /** * Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0). * @@ -6118,7 +6118,7 @@ function plural(ms, n, name) { }, function (e) { o.onError(e); }, function () { o.onCompleted(); }); }, source); }; - + /** * Returns elements from an observable sequence as long as a specified condition is true. * The element's index is used in the logic of the predicate function. @@ -6148,7 +6148,7 @@ function plural(ms, n, name) { }, function (e) { o.onError(e); }, function () { o.onCompleted(); }); }, source); }; - + var FilterObservable = (function (__super__) { inherits(FilterObservable, __super__); @@ -6216,7 +6216,7 @@ function plural(ms, n, name) { return this instanceof FilterObservable ? this.internalFilter(predicate, thisArg) : new FilterObservable(this, predicate, thisArg); }; - + function extremaBy(source, keySelector, comparer) { return new AnonymousObservable(function (o) { var hasValue = false, lastKey = null, list = []; @@ -6251,12 +6251,12 @@ function plural(ms, n, name) { }); }, source); } - + function firstOnly(x) { if (x.length === 0) { throw new EmptyError(); } return x[0]; } - + /** * Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value. * For aggregation behavior with incremental intermediate results, see Observable.scan. @@ -6300,7 +6300,7 @@ function plural(ms, n, name) { ); }, source); }; - + var ReduceObservable = (function(__super__) { inherits(ReduceObservable, __super__); function ReduceObservable(source, acc, hasSeed, seed) { @@ -6376,7 +6376,7 @@ function plural(ms, n, name) { } return new ReduceObservable(this, accumulator, hasSeed, seed); }; - + /** * Determines whether any element of an observable sequence satisfies a condition if present, else if any items are in the sequence. * @param {Function} [predicate] A function to test each element for a condition. @@ -6402,7 +6402,7 @@ function plural(ms, n, name) { //deprecate('any', 'some'); return this.some.apply(this, arguments); }; - + /** * Determines whether an observable sequence is empty. * @returns {Observable} An observable sequence containing a single element determining whether the source sequence is empty. @@ -6410,7 +6410,7 @@ function plural(ms, n, name) { observableProto.isEmpty = function () { return this.any().map(not); }; - + /** * Determines whether all elements of an observable sequence satisfy a condition. * @param {Function} [predicate] A function to test each element for a condition. @@ -6426,7 +6426,7 @@ function plural(ms, n, name) { //deprecate('all', 'every'); return this.every.apply(this, arguments); }; - + /** * Determines whether an observable sequence includes a specified element with an optional equality comparer. * @param searchElement The value to locate in the source sequence. @@ -6468,7 +6468,7 @@ function plural(ms, n, name) { //deprecate('contains', 'includes'); observableProto.includes(searchElement, fromIndex); }; - + /** * Returns an observable sequence containing a value that represents how many elements in the specified observable sequence satisfy a condition if provided, else the count of items. * @example @@ -6483,7 +6483,7 @@ function plural(ms, n, name) { this.filter(predicate, thisArg).count() : this.reduce(function (count) { return count + 1; }, 0); }; - + /** * Returns the first index at which a given element can be found in the observable sequence, or -1 if it is not present. * @param {Any} searchElement Element to locate in the array. @@ -6515,7 +6515,7 @@ function plural(ms, n, name) { }); }, source); }; - + /** * Computes the sum of a sequence of values that are obtained by invoking an optional transform function on each element of the input sequence, else if not specified computes the sum on each item in the sequence. * @param {Function} [selector] A transform function to apply to each element. @@ -6527,7 +6527,7 @@ function plural(ms, n, name) { this.map(keySelector, thisArg).sum() : this.reduce(function (prev, curr) { return prev + curr; }, 0); }; - + /** * Returns the elements in an observable sequence with the minimum key value according to the specified comparer. * @example @@ -6541,7 +6541,7 @@ function plural(ms, n, name) { comparer || (comparer = defaultSubComparer); return extremaBy(this, keySelector, function (x, y) { return comparer(x, y) * -1; }); }; - + /** * Returns the minimum element in an observable sequence according to the optional comparer else a default greater than less than check. * @example @@ -6553,7 +6553,7 @@ function plural(ms, n, name) { observableProto.min = function (comparer) { return this.minBy(identity, comparer).map(function (x) { return firstOnly(x); }); }; - + /** * Returns the elements in an observable sequence with the maximum key value according to the specified comparer. * @example @@ -6567,7 +6567,7 @@ function plural(ms, n, name) { comparer || (comparer = defaultSubComparer); return extremaBy(this, keySelector, comparer); }; - + /** * Returns the maximum value in an observable sequence according to the specified comparer. * @example @@ -6579,7 +6579,7 @@ function plural(ms, n, name) { observableProto.max = function (comparer) { return this.maxBy(identity, comparer).map(function (x) { return firstOnly(x); }); }; - + /** * Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present. * @param {Function} [selector] A transform function to apply to each element. @@ -6599,7 +6599,7 @@ function plural(ms, n, name) { return s.sum / s.count; }); }; - + /** * Determines whether two sequences are equal by comparing the elements pairwise using a specified equality comparer. * @@ -6687,7 +6687,7 @@ function plural(ms, n, name) { return new CompositeDisposable(subscription1, subscription2); }, first); }; - + function elementAtOrDefault(source, index, hasDefault, defaultValue) { if (index < 0) { throw new ArgumentOutOfRangeError(); } return new AnonymousObservable(function (o) { @@ -6707,7 +6707,7 @@ function plural(ms, n, name) { }); }, source); } - + /** * Returns the element at a specified index in a sequence. * @example @@ -6718,7 +6718,7 @@ function plural(ms, n, name) { observableProto.elementAt = function (index) { return elementAtOrDefault(this, index, false); }; - + /** * Returns the element at a specified index in a sequence or a default value if the index is out of range. * @example @@ -6731,7 +6731,7 @@ function plural(ms, n, name) { observableProto.elementAtOrDefault = function (index, defaultValue) { return elementAtOrDefault(this, index, true, defaultValue); }; - + function singleOrDefaultAsync(source, hasDefault, defaultValue) { return new AnonymousObservable(function (o) { var value = defaultValue, seenValue = false; @@ -6752,7 +6752,7 @@ function plural(ms, n, name) { }); }, source); } - + /** * Returns the only element of an observable sequence that satisfies the condition in the optional predicate, and reports an exception if there is not exactly one element in the observable sequence. * @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence. @@ -6764,7 +6764,7 @@ function plural(ms, n, name) { this.where(predicate, thisArg).single() : singleOrDefaultAsync(this, false); }; - + /** * Returns the only element of an observable sequence that matches the predicate, or a default value if no such element exists; this method reports an exception if there is more than one element in the observable sequence. * @example @@ -6783,7 +6783,7 @@ function plural(ms, n, name) { this.filter(predicate, thisArg).singleOrDefault(null, defaultValue) : singleOrDefaultAsync(this, true, defaultValue); }; - + function firstOrDefaultAsync(source, hasDefault, defaultValue) { return new AnonymousObservable(function (o) { return source.subscribe(function (x) { @@ -6799,7 +6799,7 @@ function plural(ms, n, name) { }); }, source); } - + /** * Returns the first element of an observable sequence that satisfies the condition in the predicate if present else the first item in the sequence. * @example @@ -6814,7 +6814,7 @@ function plural(ms, n, name) { this.where(predicate, thisArg).first() : firstOrDefaultAsync(this, false); }; - + /** * Returns the first element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists. * @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence. @@ -6827,7 +6827,7 @@ function plural(ms, n, name) { this.where(predicate).firstOrDefault(null, defaultValue) : firstOrDefaultAsync(this, true, defaultValue); }; - + function lastOrDefaultAsync(source, hasDefault, defaultValue) { return new AnonymousObservable(function (o) { var value = defaultValue, seenValue = false; @@ -6844,7 +6844,7 @@ function plural(ms, n, name) { }); }, source); } - + /** * Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element. * @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence. @@ -6856,7 +6856,7 @@ function plural(ms, n, name) { this.where(predicate, thisArg).last() : lastOrDefaultAsync(this, false); }; - + /** * Returns the last element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists. * @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence. @@ -6869,7 +6869,7 @@ function plural(ms, n, name) { this.where(predicate, thisArg).lastOrDefault(null, defaultValue) : lastOrDefaultAsync(this, true, defaultValue); }; - + function findValue (source, predicate, thisArg, yieldIndex) { var callback = bindCallback(predicate, thisArg, 3); return new AnonymousObservable(function (o) { @@ -6894,7 +6894,7 @@ function plural(ms, n, name) { }); }, source); } - + /** * Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Observable sequence. * @param {Function} predicate The predicate that defines the conditions of the element to search for. @@ -6904,7 +6904,7 @@ function plural(ms, n, name) { observableProto.find = function (predicate, thisArg) { return findValue(this, predicate, thisArg, false); }; - + /** * Searches for an element that matches the conditions defined by the specified predicate, and returns * an Observable sequence with the zero-based index of the first occurrence within the entire Observable sequence. @@ -6915,7 +6915,7 @@ function plural(ms, n, name) { observableProto.findIndex = function (predicate, thisArg) { return findValue(this, predicate, thisArg, true); }; - + /** * Converts the observable sequence to a Set if it exists. * @returns {Observable} An observable sequence with a single value of a Set containing the values from the observable sequence. @@ -6934,7 +6934,7 @@ function plural(ms, n, name) { }); }, source); }; - + /** * Converts the observable sequence to a Map if it exists. * @param {Function} keySelector A function which produces the key for the Map. @@ -6975,7 +6975,7 @@ function plural(ms, n, name) { }); }, source); }; - + var fnString = 'function', throwString = 'throw', isObject = Rx.internals.isObject; @@ -7169,7 +7169,7 @@ function plural(ms, n, name) { throw err; }); } - + /** * Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence. * @@ -7190,7 +7190,7 @@ function plural(ms, n, name) { Observable.start = function (func, context, scheduler) { return observableToAsync(func, context, scheduler)(); }; - + /** * Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler. * @param {Function} function Function to convert to an asynchronous function. @@ -7218,7 +7218,7 @@ function plural(ms, n, name) { return subject.asObservable(); }; }; - + /** * Converts a callback function to an observable sequence. * @@ -7261,7 +7261,7 @@ function plural(ms, n, name) { }).publishLast().refCount(); }; }; - + /** * Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format. * @param {Function} func The function to call @@ -7307,7 +7307,7 @@ function plural(ms, n, name) { }).publishLast().refCount(); }; }; - + function createListener (element, name, handler) { if (element.addEventListener) { element.addEventListener(name, handler, false); @@ -7388,7 +7388,7 @@ function plural(ms, n, name) { }); }).publish().refCount(); }; - + /** * Creates an observable sequence from an event emitter via an addHandler/removeHandler pair. * @param {Function} addHandler The function to add a handler to the emitter. @@ -7418,7 +7418,7 @@ function plural(ms, n, name) { }); }).publish().refCount(); }; - + /** * Invokes the asynchronous function, surfacing the result through an observable sequence. * @param {Function} functionAsync Asynchronous function which returns a Promise to run. @@ -7433,7 +7433,7 @@ function plural(ms, n, name) { } return observableFromPromise(promise); } - + var PausableObservable = (function (__super__) { inherits(PausableObservable, __super__); @@ -7491,7 +7491,7 @@ function plural(ms, n, name) { observableProto.pausable = function (pauser) { return new PausableObservable(this, pauser); }; - + function combineLatestSource(source, subject, resultSelector) { return new AnonymousObservable(function (o) { var hasValue = [false, false], @@ -7622,7 +7622,7 @@ function plural(ms, n, name) { observableProto.pausableBuffered = function (subject) { return new PausableBufferedObservable(this, subject); }; - + var ControlledObservable = (function (__super__) { inherits(ControlledObservable, __super__); @@ -7761,7 +7761,7 @@ function plural(ms, n, name) { if (enableQueue == null) { enableQueue = true; } return new ControlledObservable(this, enableQueue, scheduler); }; - + var StopAndWaitObservable = (function (__super__) { function subscribe (observer) { @@ -7835,7 +7835,7 @@ function plural(ms, n, name) { ControlledObservable.prototype.stopAndWait = function () { return new StopAndWaitObservable(this); }; - + var WindowedObservable = (function (__super__) { function subscribe (observer) { @@ -7915,7 +7915,7 @@ function plural(ms, n, name) { ControlledObservable.prototype.windowed = function (windowSize) { return new WindowedObservable(this, windowSize); }; - + /** * Pipes the existing Observable sequence into a Node.js Stream. * @param {Stream} dest The destination Node.js stream. @@ -7947,7 +7947,7 @@ function plural(ms, n, name) { return dest; }; - + /** * Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each * subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's @@ -7974,7 +7974,7 @@ function plural(ms, n, name) { }, source) : new ConnectableObservable(source, subjectOrSubjectSelector); }; - + /** * Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence. * This operator is a specialization of Multicast using a regular Subject. @@ -7991,7 +7991,7 @@ function plural(ms, n, name) { this.multicast(function () { return new Subject(); }, selector) : this.multicast(new Subject()); }; - + /** * Returns an observable sequence that shares a single subscription to the underlying sequence. * This operator is a specialization of publish which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed. @@ -8000,7 +8000,7 @@ function plural(ms, n, name) { observableProto.share = function () { return this.publish().refCount(); }; - + /** * Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence containing only the last notification. * This operator is a specialization of Multicast using a AsyncSubject. @@ -8017,7 +8017,7 @@ function plural(ms, n, name) { this.multicast(function () { return new AsyncSubject(); }, selector) : this.multicast(new AsyncSubject()); }; - + /** * Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence and starts with initialValue. * This operator is a specialization of Multicast using a BehaviorSubject. @@ -8037,7 +8037,7 @@ function plural(ms, n, name) { }, initialValueOrSelector) : this.multicast(new BehaviorSubject(initialValueOrSelector)); }; - + /** * Returns an observable sequence that shares a single subscription to the underlying sequence and starts with an initialValue. * This operator is a specialization of publishValue which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed. @@ -8047,7 +8047,7 @@ function plural(ms, n, name) { observableProto.shareValue = function (initialValue) { return this.publishValue(initialValue).refCount(); }; - + /** * Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer. * This operator is a specialization of Multicast using a ReplaySubject. @@ -8069,7 +8069,7 @@ function plural(ms, n, name) { this.multicast(function () { return new ReplaySubject(bufferSize, windowSize, scheduler); }, selector) : this.multicast(new ReplaySubject(bufferSize, windowSize, scheduler)); }; - + /** * Returns an observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer. * This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed. @@ -8088,7 +8088,7 @@ function plural(ms, n, name) { observableProto.shareReplay = function (bufferSize, windowSize, scheduler) { return this.replay(null, bufferSize, windowSize, scheduler).refCount(); }; - + var InnerSubscription = function (subject, observer) { this.subject = subject; this.observer = observer; @@ -8101,7 +8101,7 @@ function plural(ms, n, name) { this.observer = null; } }; - + /** * Represents a value that changes over time. * Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications. @@ -8212,7 +8212,7 @@ function plural(ms, n, name) { return BehaviorSubject; }(Observable)); - + /** * Represents an object that is both an observable sequence as well as an observer. * Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies. @@ -8349,7 +8349,7 @@ function plural(ms, n, name) { return ReplaySubject; }(Observable)); - + var ConnectableObservable = Rx.ConnectableObservable = (function (__super__) { inherits(ConnectableObservable, __super__); @@ -8386,7 +8386,7 @@ function plural(ms, n, name) { return ConnectableObservable; }(Observable)); - + /** * Returns an observable sequence that shares a single subscription to the underlying sequence. This observable sequence * can be resubscribed to, even if all prior subscriptions have ended. (unlike `.publish().refCount()`) @@ -8407,7 +8407,7 @@ function plural(ms, n, name) { return getObservable().subscribe(o); }); }; - + var Dictionary = (function () { var primes = [1, 3, 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647], @@ -8655,7 +8655,7 @@ function plural(ms, n, name) { return Dictionary; }()); - + /** * Correlates the elements of two sequences based on overlapping durations. * @@ -8759,7 +8759,7 @@ function plural(ms, n, name) { return group; }, left); }; - + /** * Correlates the elements of two sequences based on overlapping durations, and groups the results. * @@ -8871,7 +8871,7 @@ function plural(ms, n, name) { return r; }, left); }; - + /** * Projects each element of an observable sequence into zero or more buffers. * @@ -8882,7 +8882,7 @@ function plural(ms, n, name) { observableProto.buffer = function (bufferOpeningsOrClosingSelector, bufferClosingSelector) { return this.window.apply(this, arguments).selectMany(function (x) { return x.toArray(); }); }; - + /** * Projects each element of an observable sequence into zero or more windows. * @@ -8988,7 +8988,7 @@ function plural(ms, n, name) { return r; }, source); } - + /** * Returns a new observable that triggers on the second and subsequent triggerings of the input observable. * The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as a pair. @@ -9012,7 +9012,7 @@ function plural(ms, n, name) { observer.onCompleted.bind(observer)); }, source); }; - + /** * Returns two observables which partition the observations of the source by the given function. * The first will trigger observations for those values for which the predicate returns true. @@ -9032,7 +9032,7 @@ function plural(ms, n, name) { this.filter(function (x, i, o) { return !predicate.call(thisArg, x, i, o); }) ]; }; - + var WhileEnumerable = (function(__super__) { inherits(WhileEnumerable, __super__); function WhileEnumerable(c, s) { @@ -9055,7 +9055,7 @@ function plural(ms, n, name) { function enumerableWhile(condition, source) { return new WhileEnumerable(condition, source); } - + /** * Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions. * This operator allows for a fluent style of writing queries that use the same sequence multiple times. @@ -9066,7 +9066,7 @@ function plural(ms, n, name) { observableProto.letBind = observableProto['let'] = function (func) { return func(this); }; - + /** * Determines whether an observable collection contains values. There is an alias for this method called 'ifThen' for browsers

YouTube Autocomplete Widget

- + + diff --git a/example/youtube/js/app.jsx b/example/youtube/js/app.jsx index 94e5b08..e583e07 100644 --- a/example/youtube/js/app.jsx +++ b/example/youtube/js/app.jsx @@ -61,4 +61,4 @@ var MyApp = React.createClass({ } }); -React.render(, document.getElementById('yt-typeahead')); +ReactDOM.render(, document.getElementById('yt-typeahead')); diff --git a/karma.conf.js b/karma.conf.js index 505b25f..01a849b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -10,14 +10,12 @@ module.exports = function(config) { // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['mocha', 'sinon-chai', 'browserify'], - + frameworks: ['mocha', 'sinon-chai'], // list of files / patterns to load in the browser files: [ './test/polyfill/*.js', - './src/**/*.js?(x)', - './src/**/_browser_unit_/*.js?(x)' + './test/all.js' ], @@ -29,7 +27,7 @@ module.exports = function(config) { // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - './src/**/*.js?(x)': ['browserify'] + './test/all.js': ['webpack', 'sourcemap'] }, @@ -68,12 +66,20 @@ module.exports = function(config) { output: 'autoWatch' }, - browserify: { - debug: true, - transform: [ - 'reactify' - ], - extensions: ['.js', '.jsx'] + webpack: { + devtool: "inline-source-map", + module: { + loaders: [ + { test: /\.(js|jsx)$/, loaders: ['babel-loader'], exclude: /node_modules/ } + ] + }, + resolve: { + extensions: ["", ".js", ".jsx"] + } + }, + + webpackServer: { + noInfo: true } }); }; diff --git a/package.json b/package.json index 14ca43a..92cc509 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "Typeahead, written using the React.js library.", "author": "Ezequiel Rodriguez ", "version": "0.9.0", - "main": "./src/index.js", + "main": "./lib/index.js", "license": "MIT", "bugs": "https://github.com/ezequiel/react-typeahead-component/issues", "repository": { @@ -19,50 +19,48 @@ "component" ], "files": [ - "./dist/npm" + "dist", + "src", + "lib" ], - "directories": { - "lib": "./src", - "example": "./example" - }, "scripts": { - "build": "browserify ./src/index.js -t reactify -t literalify -x react -s Typeahead -d", - "dist:dev": "npm --loglevel=silent run build > dist/react-typeahead-component.dev.js", - "dist:min": "npm --loglevel=silent run build -- -t [envify --NODE_ENV production] | uglifyjs -cmvb beautify=false,ascii_only=true - > dist/react-typeahead-component.min.js", + "build": "npm run build:lib && npm run dist:dev && npm run dist:min", + "build:lib": "babel src --out-dir lib", + "clean": "rimraf lib dist", + "dist:dev": "webpack src/index.js dist/react-typeahead-component.dev.js --config webpack.config.development.js", + "dist:min": "webpack src/index.js dist/react-typeahead-component.min.js --config webpack.config.production.js", + "prepublish": "npm run clean && npm run build", "test": "karma start", - "test:dev": "karma start --no-single-run --browsers Chrome", - "jsx": "jsx ./src ./dist/npm -x jsx -x js" + "test:dev": "karma start --no-single-run --browsers Chrome" }, "peerDependencies": { - "react": ">=0.13.1 <1.0.0" + "react": ">=0.14.0 <1.0.0" }, "devDependencies": { - "brfs": "^1.4.0", - "browserify": "^9.0.3", - "browserify-css": "^0.6.1", - "browserify-shim": "^3.8.6", - "envify": "^3.4.0", + "babel-cli": "^6.3.17", + "babel-core": "^6.3.17", + "babel-loader": "^6.2.0", + "babel-preset-react": "^6.3.13", "insert-css": "^0.2.0", - "karma": "^0.12.31", - "karma-browserify": "^4.1.2", - "karma-chrome-launcher": "^0.1.7", - "karma-cli": "^0.0.4", + "karma": "^0.13.15", + "karma-babel-preprocessor": "^6.0.1", + "karma-chrome-launcher": "^0.2.2", + "karma-cli": "^0.1.1", "karma-firefox-launcher": "^0.1.4", - "karma-ie-launcher": "^0.1.5", - "karma-mocha": "^0.1.10", + "karma-ie-launcher": "^0.2.0", + "karma-mocha": "^0.2.1", "karma-mocha-reporter": "^1.0.2", - "karma-opera-launcher": "^0.1.0", - "karma-phantomjs-launcher": "^0.1.4", + "karma-opera-launcher": "^0.3.0", + "karma-phantomjs-launcher": "^0.2.1", "karma-safari-launcher": "^0.1.1", - "karma-sinon-chai": "^0.3.0", - "literalify": "^0.4.0", + "karma-sinon-chai": "^1.1.0", + "karma-sourcemap-loader": "^0.3.6", + "karma-webpack": "^1.7.0", "mocha": "^2.2.4", - "react-tools": "^0.13.1", - "reactify": "^1.0.0", - "uglify-js": "^2.4.20", - "watchify": "^2.4.0" - }, - "literalify": { - "react": "window.React || require('react')" + "react": "^0.14.3", + "react-addons-test-utils": "^0.14.3", + "react-dom": "^0.14.3", + "rimraf": "^2.4.4", + "webpack": "^1.12.9" } } diff --git a/src/components/_browser_unit_/aria_status_test.jsx b/src/components/_browser_unit_/aria_status_test.jsx index ac9090f..71ed6d9 100644 --- a/src/components/_browser_unit_/aria_status_test.jsx +++ b/src/components/_browser_unit_/aria_status_test.jsx @@ -1,8 +1,9 @@ 'use strict'; -var React = require('react/addons'), - TestUtils = React.addons.TestUtils, - AriaStatus = require('../aria_status.jsx'); +var React = require('react'), + ReactDOM = require('react-dom'), + TestUtils = require('react-addons-test-utils'), + AriaStatus = require('../aria_status'); describe('AriaStatus', function() { describe('#setTextContent', function() { @@ -13,7 +14,7 @@ describe('AriaStatus', function() { text = 'this is a test'; ariaStatusInstance.setTextContent(text); - expect(React.findDOMNode(ariaStatusInstance).textContent).to.equal(text); + expect(ReactDOM.findDOMNode(ariaStatusInstance).textContent).to.equal(text); }); it('should set the text content to an empty string when passed null/undefined', function() { @@ -23,7 +24,7 @@ describe('AriaStatus', function() { [null, undefined].forEach(function(value) { ariaStatusInstance.setTextContent(value); - expect(React.findDOMNode(ariaStatusInstance).textContent).to.equal(''); + expect(ReactDOM.findDOMNode(ariaStatusInstance).textContent).to.equal(''); }); }); }); diff --git a/src/components/_browser_unit_/input_test.jsx b/src/components/_browser_unit_/input_test.jsx index a57bf59..45ad82f 100644 --- a/src/components/_browser_unit_/input_test.jsx +++ b/src/components/_browser_unit_/input_test.jsx @@ -1,39 +1,38 @@ 'use strict'; -var React = require('react/addons'), - TestUtils = React.addons.TestUtils, - Input = require('../input.jsx'); +var React = require('react'), + ReactDOM = require('react-dom'), + TestUtils = require('react-addons-test-utils'), + Input = require('../input'); describe('Input', function() { describe('#componentDidUpdate', function() { + var node, inputElement, inputInstance; + it('should remove the `dir` attribute if re-rendered with a null/undefined value', function(done) { - var inputInstance = TestUtils.renderIntoDocument( - - ); + var div = document.createElement('div'); + var inputInstance = ReactDOM.render(, div); + var node = ReactDOM.findDOMNode(inputInstance); - [null, undefined].forEach(function(value) { - inputInstance.setProps({ - dir: value - }, function() { - expect(React.findDOMNode(inputInstance).hasAttribute('dir')).to.be.false; - done(); + var values = [null, undefined]; + values.forEach(function(value, i) { + ReactDOM.render(, div, function () { + expect(node.hasAttribute('dir')).to.be.false; + + if (i === values.length-1) { + done(); + } }); }); }); it('should not remove the `dir` attribute if re-rendered with a legit value', function(done) { - var inputInstance = TestUtils.renderIntoDocument( - - ); + var div = document.createElement('div'); + var inputInstance = ReactDOM.render(, div); + var node = ReactDOM.findDOMNode(inputInstance); - inputInstance.setProps({ - dir: 'ltr' - }, function() { - expect(React.findDOMNode(inputInstance).hasAttribute('dir')).to.be.true; + ReactDOM.render(, div, function () { + expect(node.hasAttribute('dir')).to.be.true; done(); }); }); @@ -116,22 +115,34 @@ describe('Input', function() { // This is only required for tests which use `setSelectionRange`. // We have to render into the body because `setSelectionRange` // doesn't work if the element isn't actually on the page. - var renderIntoBody = function(instance) { - return React.render(instance, document.body); - }; + // With React >= 0.14 rendering into document.body outputs a warning, + // use a div inside an iframe instead. (http://yahooeng.tumblr.com/post/102274727496/to-testutil-or-not-to-testutil) + + beforeEach(function () { + this.iframe = document.createElement('iframe'); + document.body.appendChild(this.iframe); + + this.iframeDiv = document.createElement('div'); + this.iframe.contentDocument.body.appendChild(this.iframeDiv); + }); afterEach(function() { - React.unmountComponentAtNode(document.body); + ReactDOM.unmountComponentAtNode(this.iframeDiv); + delete this.iframeDiv; + + document.body.removeChild(this.iframe); + delete this.iframe; }); it('should return `true` if the cursor is at the end', function() { var value = 'ezequiel', - inputInstance = renderIntoBody( + inputInstance = ReactDOM.render( + />, + this.iframeDiv ), - inputDOMNode = React.findDOMNode(inputInstance), + inputDOMNode = ReactDOM.findDOMNode(inputInstance), startRange = value.length, endRange = value.length; @@ -141,12 +152,13 @@ describe('Input', function() { }); it('should return `false` if the cursor is at the beginning', function() { - var inputInstance = renderIntoBody( + var inputInstance = ReactDOM.render( + />, + this.iframeDiv ), - inputDOMNode = React.findDOMNode(inputInstance); + inputDOMNode = ReactDOM.findDOMNode(inputInstance); inputDOMNode.setSelectionRange(0, 0); @@ -155,12 +167,13 @@ describe('Input', function() { it('should return `false` if the cursor is in the middle', function() { var value = 'ezequiel', - inputInstance = renderIntoBody( + inputInstance = ReactDOM.render( + />, + this.iframeDiv ), - inputDOMNode = React.findDOMNode(inputInstance), + inputDOMNode = ReactDOM.findDOMNode(inputInstance), startRange = Math.floor(value.length / 2), endRange = Math.floor(value.length / 2); @@ -171,18 +184,20 @@ describe('Input', function() { }); it('should return `true` if the `value` is empty', function() { - var inputInstance = renderIntoBody( + var inputInstance = ReactDOM.render( + />, + this.iframeDiv ); expect(inputInstance.isCursorAtEnd()).to.be.true; }); it('should return `true` if there is no `value`', function() { - var inputInstance = renderIntoBody( - + var inputInstance = ReactDOM.render( + , + this.iframeDiv ); expect(inputInstance.isCursorAtEnd()).to.be.true; diff --git a/src/components/_browser_unit_/typeahead_test.jsx b/src/components/_browser_unit_/typeahead_test.jsx index 9196f89..d1d576a 100644 --- a/src/components/_browser_unit_/typeahead_test.jsx +++ b/src/components/_browser_unit_/typeahead_test.jsx @@ -1,26 +1,49 @@ 'use strict'; -var React = require('react/addons'), - TestUtils = React.addons.TestUtils, - Typeahead = require('../typeahead.jsx'); +var React = require('react'), + ReactDOM = require('react-dom'), + TestUtils = require('react-addons-test-utils'), + Typeahead = require('../typeahead'); describe('Typeahead', function() { // This is only required for tests which use `setSelectionRange`. // We have to render into the body because `setSelectionRange` // doesn't work if the element isn't actually on the page. - var renderIntoBody = function(instance) { - return React.render(instance, document.body); - }; + // With React >= 0.14 rendering into document.body outputs a warning, + // use a div inside an iframe instead. (http://yahooeng.tumblr.com/post/102274727496/to-testutil-or-not-to-testutil) + + var setupIframe = function () { + this.iframe = document.createElement('iframe'); + document.body.appendChild(this.iframe); + + this.iframeDiv = document.createElement('div'); + this.iframe.contentDocument.body.appendChild(this.iframeDiv); + } + + afterEach(function () { + if (this.iframeDiv) { + ReactDOM.unmountComponentAtNode(this.iframeDiv); + delete this.iframeDiv; + } + + if (this.iframe) { + ReactDOM.unmountComponentAtNode(this.iframe.contentDocument.body); + document.body.removeChild(this.iframe); + delete this.iframe; + } + }) describe('#componentWillReceiveProps', function() { it('should set `isHintVisible` to false if there isn\'t something completeable', function(done) { - var typeaheadInstance = TestUtils.renderIntoDocument( + var div = document.createElement('div'); + var typeaheadInstance = ReactDOM.render( + />, + div ); // Put Typeahead in a state where the hint is visible. @@ -29,39 +52,49 @@ describe('Typeahead', function() { // The hint should be visible at this point. expect(typeaheadInstance.state.isHintVisible).to.be.true; - typeaheadInstance.setProps({ - inputValue: 'm', - handleHint: function() { - return ''; + ReactDOM.render( + , + div, + function () { + expect(typeaheadInstance.state.isHintVisible).to.be.false; + done(); } - }, function() { - expect(typeaheadInstance.state.isHintVisible).to.be.false; - done(); - }); + ); }); it('should set `isHintVisible` to true if there is something completeable', function(done) { - var typeaheadInstance = TestUtils.renderIntoDocument( + var div = document.createElement('div'); + var typeaheadInstance = ReactDOM.render( + />, + div ); // The hint should not be visible at this point. expect(typeaheadInstance.state.isHintVisible).to.be.false; - typeaheadInstance.setProps({ - inputValue: 'e', - handleHint: function() { - return 'ezequiel' + ReactDOM.render( + , + div, + function () { + expect(typeaheadInstance.state.isHintVisible).to.be.true; + done(); } - }, function() { - expect(typeaheadInstance.state.isHintVisible).to.be.true; - done(); - }); + ) }); }); @@ -482,28 +515,29 @@ describe('Typeahead', function() { }); describe('ArrowLeft', function() { - afterEach(function() { - React.unmountComponentAtNode(document.body); + beforeEach(function() { + setupIframe.call(this); }); describe('in rtl languages', function() { it('should complete the hint if it is visible', function() { var inputValue = 'شزذ', handleComplete = sinon.spy(), - typeaheadInstance = renderIntoBody( + typeaheadInstance = ReactDOM.render( + />, + this.iframeDiv ), eventData = { key: 'ArrowLeft' }, inputDOMNode = - React.findDOMNode( + ReactDOM.findDOMNode( TestUtils.findRenderedDOMComponentWithClass(typeaheadInstance, 'react-typeahead-usertext') ), startRange = inputValue.length, @@ -523,20 +557,21 @@ describe('Typeahead', function() { it('should not complete the hint if the cursor is not at the end', function() { var handleComplete = sinon.spy(), inputValue = 'شزذ', - typeaheadInstance = renderIntoBody( + typeaheadInstance = ReactDOM.render( + />, + this.iframeDiv ), eventData = { key: 'ArrowLeft' }, inputDOMNode = - React.findDOMNode( + ReactDOM.findDOMNode( TestUtils.findRenderedDOMComponentWithClass(typeaheadInstance, 'react-typeahead-usertext') ), startRange = Math.floor(inputValue.length / 2), @@ -620,28 +655,29 @@ describe('Typeahead', function() { }); describe('ArrowRight', function() { - afterEach(function() { - React.unmountComponentAtNode(document.body); + beforeEach(function() { + setupIframe.call(this); }); describe('in ltr languages', function() { it('should complete the hint if it is visible', function() { var inputValue = 'eze', handleComplete = sinon.spy(), - typeaheadInstance = renderIntoBody( + typeaheadInstance = ReactDOM.render( + />, + this.iframeDiv ), eventData = { key: 'ArrowRight' }, inputDOMNode = - React.findDOMNode( + ReactDOM.findDOMNode( TestUtils.findRenderedDOMComponentWithClass(typeaheadInstance, 'react-typeahead-usertext') ), startRange = inputValue.length, @@ -662,14 +698,15 @@ describe('Typeahead', function() { it('should not complete the hint if the cursor is not at the end', function() { var handleComplete = sinon.spy(), inputValue = 'eze', - typeaheadInstance = renderIntoBody( + typeaheadInstance = ReactDOM.render( + />, + this.iframeDiv ), eventData = { key: 'ArrowRight', @@ -678,7 +715,7 @@ describe('Typeahead', function() { }, }, inputDOMNode = - React.findDOMNode( + ReactDOM.findDOMNode( TestUtils.findRenderedDOMComponentWithClass(typeaheadInstance, 'react-typeahead-usertext') ), startRange = Math.floor(inputValue.length / 2), @@ -1112,7 +1149,7 @@ describe('Typeahead', function() { typeaheadInstance.handleWindowClose({ // Pretend this object is a DOM node we know nothing about. - target: {} + target: document.createElement('div') }); expect(typeaheadInstance.state.isHintVisible).to.be.false; @@ -1133,7 +1170,7 @@ describe('Typeahead', function() { // typeaheadInstance.handleChange({ target: { value: '' } }); // // typeaheadInstance.handleWindowClose({ - // target: React.findDOMNode( + // target: ReactDOM.findDOMNode( // TestUtils.findRenderedDOMComponentWithClass(typeaheadInstance, 'react-typeahead-options') // ) // }); diff --git a/src/components/aria_status.jsx b/src/components/aria_status.jsx index 73f2e61..50fae13 100644 --- a/src/components/aria_status.jsx +++ b/src/components/aria_status.jsx @@ -1,6 +1,7 @@ 'use strict'; -var React = require('react'); +var React = require('react'), + ReactDOM = require('react-dom'); module.exports = React.createClass({ displayName: 'Aria Status', @@ -41,6 +42,6 @@ module.exports = React.createClass({ // which confuses screen readers and doesn't cause them to read changes. setTextContent: function(textContent) { // We could set `innerHTML`, but it's better to avoid it. - this.getDOMNode().textContent = textContent || ''; + ReactDOM.findDOMNode(this).textContent = textContent || ''; } }); diff --git a/src/components/input.jsx b/src/components/input.jsx index 55cc07e..ade351d 100644 --- a/src/components/input.jsx +++ b/src/components/input.jsx @@ -1,6 +1,7 @@ 'use strict'; -var React = require('react'); +var React = require('react'), + ReactDOM = require('react-dom'); module.exports = React.createClass({ displayName: 'Input', @@ -28,7 +29,7 @@ module.exports = React.createClass({ // This is not desired because of a possible bug in Chrome. // If the page is RTL, and the input's `dir` attribute is set // to an empty string, Chrome assumes LTR, which isn't what we want. - React.findDOMNode(_this).removeAttribute('dir'); + ReactDOM.findDOMNode(_this).removeAttribute('dir'); } }, @@ -57,12 +58,12 @@ module.exports = React.createClass({ }, blur: function() { - React.findDOMNode(this).blur(); + ReactDOM.findDOMNode(this).blur(); }, isCursorAtEnd: function() { var _this = this, - inputDOMNode = React.findDOMNode(_this), + inputDOMNode = ReactDOM.findDOMNode(_this), valueLength = _this.props.value.length; return inputDOMNode.selectionStart === valueLength && diff --git a/src/components/typeahead.jsx b/src/components/typeahead.jsx index 6d209a5..7d8a55d 100644 --- a/src/components/typeahead.jsx +++ b/src/components/typeahead.jsx @@ -1,8 +1,9 @@ 'use strict'; var React = require('react'), - Input = require('./input.jsx'), - AriaStatus = require('./aria_status.jsx'), + ReactDOM = require('react-dom'), + Input = require('./input'), + AriaStatus = require('./aria_status'), getTextDirection = require('../utils/get_text_direction'), noop = function() {}; @@ -345,7 +346,7 @@ module.exports = React.createClass({ }, focus: function() { - this.refs.input.getDOMNode().focus(); + ReactDOM.findDOMNode(this.refs.input).focus(); }, handleFocus: function(event) { @@ -446,7 +447,7 @@ module.exports = React.createClass({ optionData = props.options[selectedIndex]; // Make selected option always scroll to visible - dropdown = React.findDOMNode(_this.refs.dropdown); + dropdown = ReactDOM.findDOMNode(_this.refs.dropdown); selectedOption = dropdown.children[selectedIndex]; optionOffsetTop = selectedOption.offsetTop; if(optionOffsetTop + selectedOption.clientHeight > dropdown.clientHeight || @@ -502,7 +503,7 @@ module.exports = React.createClass({ var _this = this, target = event.target; - if (target !== window && !this.getDOMNode().contains(target)) { + if (target !== window && !ReactDOM.findDOMNode(this).contains(target)) { _this.hideHint(); _this.hideDropdown(); } diff --git a/src/index.js b/src/index.js index dfdecde..f73b85b 100644 --- a/src/index.js +++ b/src/index.js @@ -1 +1 @@ -module.exports = require('./components/typeahead.jsx'); +module.exports = require('./components/typeahead'); diff --git a/test/all.js b/test/all.js new file mode 100644 index 0000000..6177694 --- /dev/null +++ b/test/all.js @@ -0,0 +1,2 @@ +var context = require.context('../src', true, /_test\.(js|jsx)$/); +context.keys().forEach(context); \ No newline at end of file diff --git a/webpack.config.base.js b/webpack.config.base.js new file mode 100644 index 0000000..10a5c57 --- /dev/null +++ b/webpack.config.base.js @@ -0,0 +1,34 @@ +'use strict'; + +var reactExternal = { + root: 'React', + commonjs2: 'react', + commonjs: 'react', + amd: 'react' +}; + +var reactDomExternal = { + root: 'ReactDOM', + commonjs2: 'react-dom', + commonjs: 'react-dom', + amd: 'react-dom' +}; + +module.exports = { + externals: { + 'react': reactExternal, + 'react-dom': reactDomExternal + }, + module: { + loaders: [ + { test: /\.(js|jsx)$/, loaders: ['babel-loader'], exclude: /node_modules/ } + ] + }, + output: { + library: 'Typeahead', + libraryTarget: 'umd' + }, + resolve: { + extensions: ['', '.js', '.jsx'] + } +}; \ No newline at end of file diff --git a/webpack.config.development.js b/webpack.config.development.js new file mode 100644 index 0000000..001a7ff --- /dev/null +++ b/webpack.config.development.js @@ -0,0 +1,14 @@ +'use strict'; + +var webpack = require('webpack'); +var baseConfig = require('./webpack.config.base'); + +var config = Object.create(baseConfig) +config.plugins = [ + new webpack.optimize.OccurenceOrderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('development') + }) +]; + +module.exports = config; \ No newline at end of file diff --git a/webpack.config.production.js b/webpack.config.production.js new file mode 100644 index 0000000..711a249 --- /dev/null +++ b/webpack.config.production.js @@ -0,0 +1,20 @@ +'use strict' + +var webpack = require('webpack'); +var baseConfig = require('./webpack.config.base'); + +var config = Object.create(baseConfig) +config.plugins = [ + new webpack.optimize.OccurenceOrderPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + screw_ie8: true, + warnings: false + } + }) +]; + +module.exports = config; \ No newline at end of file