diff options
| -rw-r--r-- | mitmproxy/web/static/app.js | 168 | ||||
| -rw-r--r-- | mitmproxy/web/static/vendor.js | 1565 | ||||
| -rw-r--r-- | web/src/js/components/flowtable.js | 89 | ||||
| -rw-r--r-- | web/src/js/components/mainview.js | 7 | ||||
| -rw-r--r-- | web/src/js/ducks/flows.js | 13 | 
5 files changed, 1054 insertions, 788 deletions
| diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js index b3736582..b46e2432 100644 --- a/mitmproxy/web/static/app.js +++ b/mitmproxy/web/static/app.js @@ -1530,88 +1530,77 @@ var FlowRowContainer = (0, _reactRedux.connect)(function (state, ownProps) {      };  })(FlowRow); -var FlowTableHead = function (_React$Component) { -    _inherits(FlowTableHead, _React$Component); +function FlowTableHead(_ref2) { +    var setSort = _ref2.setSort; +    var columns = _ref2.columns; +    var sort = _ref2.sort; + + +    //const hasSort = Column.sortKeyFun; + +    // let sortDesc = this.props.sort.sortDesc; +    // +    // if (Column === this.props.sort.sortColumn) { +    //     sortDesc = !sortDesc; +    //     this.props.setSort(sortColumn, sortDesc); +    // } else { +    //     this.props.setSort({sortColumn: hasSort && Column, sortDesc: false}); +    // } +    // +    // let sortKeyFun = Column.sortKeyFun; +    // if (sortDesc) { +    //     sortKeyFun = hasSort && function () { +    //             const k = Column.sortKeyFun.apply(this, arguments); +    //             if (_.isString(k)) { +    //                 return reverseString("" + k); +    //             } +    //             return -k; +    //         }; +    // } +    //this.props.setSortKeyFun(sortKeyFun); + +    var sortColumn = sort.sortColumn; +    var sortType = sort.sortDesc ? "sort-desc" : "sort-asc"; -    function FlowTableHead(props, context) { -        _classCallCheck(this, FlowTableHead); - -        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(FlowTableHead).call(this, props, context)); - -        _this.state = { sortColumn: undefined, sortDesc: false }; -        return _this; -    } - -    _createClass(FlowTableHead, [{ -        key: "onClick", -        value: function onClick(Column) { -            var hasSort = Column.sortKeyFun; - -            var sortDesc = this.state.sortDesc; - -            if (Column === this.state.sortColumn) { -                sortDesc = !sortDesc; -                this.setState({ sortDesc: sortDesc }); -            } else { -                this.setState({ sortColumn: hasSort && Column, sortDesc: false }); -            } - -            var sortKeyFun = Column.sortKeyFun; -            if (sortDesc) { -                sortKeyFun = hasSort && function () { -                    var k = Column.sortKeyFun.apply(this, arguments); -                    if (_lodash2.default.isString(k)) { -                        return (0, _utils.reverseString)("" + k); -                    } -                    return -k; -                }; -            } - -            this.props.setSortKeyFun(sortKeyFun); -        } -    }, { -        key: "render", -        value: function render() { -            var _this2 = this; - -            var sortColumn = this.state.sortColumn; -            var sortType = this.state.sortDesc ? "sort-desc" : "sort-asc"; -            return _react2.default.createElement( -                "tr", -                null, -                this.props.columns.map(function (Column) { -                    return _react2.default.createElement(Column.Title, { -                        key: Column.name, -                        onClick: function onClick() { -                            return _this2.onClick(Column); -                        }, -                        className: sortColumn === Column ? sortType : undefined -                    }); -                }) -            ); -        } -    }]); - -    return FlowTableHead; -}(_react2.default.Component); +    return _react2.default.createElement( +        "tr", +        null, +        columns.map(function (Column) { +            return _react2.default.createElement(Column.Title, { +                key: Column.name, +                onClick: function onClick() { +                    return setSort({ sortColumn: Column.name, sortDesc: Column.name != sort.sortColumn ? false : !sort.sortDesc }); +                }, +                className: sortColumn === Column.name ? sortType : undefined +            }); +        }) +    ); +}  FlowTableHead.propTypes = { -    setSortKeyFun: _react2.default.PropTypes.func.isRequired, +    setSort: _react2.default.PropTypes.func.isRequired, +    sort: _react2.default.PropTypes.object.isRequired,      columns: _react2.default.PropTypes.array.isRequired  }; -var FlowTable = function (_React$Component2) { -    _inherits(FlowTable, _React$Component2); +var FlowTableHeadContainer = (0, _reactRedux.connect)(function (state, ownProps) { +    return { +        sort: state.flows.sort +    }; +})(FlowTableHead); + +var FlowTable = function (_React$Component) { +    _inherits(FlowTable, _React$Component);      function FlowTable(props, context) {          _classCallCheck(this, FlowTable); -        var _this3 = _possibleConstructorReturn(this, Object.getPrototypeOf(FlowTable).call(this, props, context)); +        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(FlowTable).call(this, props, context)); -        _this3.state = { vScroll: (0, _VirtualScroll.calcVScroll)() }; +        _this.state = { vScroll: (0, _VirtualScroll.calcVScroll)() }; -        _this3.onViewportUpdate = _this3.onViewportUpdate.bind(_this3); -        return _this3; +        _this.onViewportUpdate = _this.onViewportUpdate.bind(_this); +        return _this;      }      _createClass(FlowTable, [{ @@ -1627,11 +1616,11 @@ var FlowTable = function (_React$Component2) {      }, {          key: "componentWillReceiveProps",          value: function componentWillReceiveProps(nextProps) { -            var _this4 = this; +            var _this2 = this;              if (nextProps.selected && nextProps.selected !== this.props.selected) {                  window.setTimeout(function () { -                    return _this4.scrollIntoView(nextProps.selected); +                    return _this2.scrollIntoView(nextProps.selected);                  }, 1);              }          } @@ -1683,7 +1672,7 @@ var FlowTable = function (_React$Component2) {      }, {          key: "render",          value: function render() { -            var _this5 = this; +            var _this3 = this;              var vScroll = this.state.vScroll;              var flows = this.props.flows.slice(vScroll.start, vScroll.end); @@ -1699,9 +1688,10 @@ var FlowTable = function (_React$Component2) {                      _react2.default.createElement(                          "thead",                          { ref: "head", style: { transform: transform } }, -                        _react2.default.createElement(FlowTableHead, { +                        _react2.default.createElement(FlowTableHeadContainer, {                              columns: _flowtableColumns2.default, -                            setSortKeyFun: this.props.setSortKeyFun +                            setSortKeyFun: this.props.setSortKeyFun, +                            setSort: this.props.setSort                          })                      ),                      _react2.default.createElement( @@ -1713,7 +1703,7 @@ var FlowTable = function (_React$Component2) {                                  key: flow.id,                                  flowId: flow.id,                                  columns: _flowtableColumns2.default, -                                selectFlow: _this5.props.selectFlow +                                selectFlow: _this3.props.selectFlow                              });                          }),                          _react2.default.createElement("tr", { style: { height: vScroll.paddingBottom } }) @@ -3944,7 +3934,10 @@ var MainView = _react2.default.createClass({              { className: "main-view" },              _react2.default.createElement(_flowtable2.default, { ref: "flowTable",                  selectFlow: this.selectFlow, -                setSortKeyFun: this.setSortKeyFun, +                setSortKeyFun: function setSortKeyFun(f) { +                    return console.log("asdf"); +                }, +                setSort: this.props.setSort,                  selected: this.props.selectedFlow }),              details          ); @@ -3955,6 +3948,7 @@ var MainViewContainer = (0, _reactRedux.connect)(function (state) {      return {          flows: state.flows.view,          filter: state.flows.filter, +        sort: state.flows.sort,          highlight: state.flows.highlight,          selectedFlow: state.flows.all.byId[state.flows.selected[0]]      }; @@ -3966,6 +3960,9 @@ var MainViewContainer = (0, _reactRedux.connect)(function (state) {          setFilter: function setFilter(filter) {              return dispatch((0, _flows.setFilter)(filter));          }, +        setSort: function setSort(sort) { +            return dispatch((0, _flows.setSort)(sort)); +        },          setHighlight: function setHighlight(highlight) {              return dispatch((0, _flows.setHighlight)(highlight));          } @@ -4496,13 +4493,14 @@ exports.fetchLogEntries = fetchList;  Object.defineProperty(exports, "__esModule", {      value: true  }); -exports.fetchFlows = exports.updateFlows = exports.SELECT_FLOW = exports.SET_HIGHLIGHT = exports.SET_FILTER = exports.UPDATE_FLOWS = undefined; +exports.fetchFlows = exports.updateFlows = exports.SELECT_FLOW = exports.SET_SORT = exports.SET_HIGHLIGHT = exports.SET_FILTER = exports.UPDATE_FLOWS = undefined;  var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };  exports.default = reducer;  exports.setFilter = setFilter;  exports.setHighlight = setHighlight; +exports.setSort = setSort;  exports.selectFlow = selectFlow;  var _list = require("./utils/list"); @@ -4520,6 +4518,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de  var UPDATE_FLOWS = exports.UPDATE_FLOWS = "UPDATE_FLOWS";  var SET_FILTER = exports.SET_FILTER = "SET_FLOW_FILTER";  var SET_HIGHLIGHT = exports.SET_HIGHLIGHT = "SET_FLOW_HIGHLIGHT"; +var SET_SORT = exports.SET_SORT = "SET_FLOW_SORT";  var SELECT_FLOW = exports.SELECT_FLOW = "SELECT_FLOW";  var _makeList = (0, _list2.default)(UPDATE_FLOWS, "/flows"); @@ -4534,7 +4533,8 @@ var defaultState = {      selected: [],      view: [],      filter: undefined, -    highlight: undefined +    highlight: undefined, +    sort: { sortColumn: undefined, sortDesc: false }  };  function makeFilterFn(filter) { @@ -4563,6 +4563,10 @@ function reducer() {              return _extends({}, state, {                  highlight: action.highlight              }); +        case SET_SORT: +            return _extends({}, state, { +                sort: action.sort +            });          case SELECT_FLOW:              return _extends({}, state, {                  selected: [action.flowId] @@ -4584,6 +4588,12 @@ function setHighlight(highlight) {          highlight: highlight      };  } +function setSort(sort) { +    return { +        type: SET_SORT, +        sort: sort +    }; +}  function selectFlow(flowId) {      return {          type: SELECT_FLOW, diff --git a/mitmproxy/web/static/vendor.js b/mitmproxy/web/static/vendor.js index b2e49043..caf49f63 100644 --- a/mitmproxy/web/static/vendor.js +++ b/mitmproxy/web/static/vendor.js @@ -764,7 +764,11 @@ function createBrowserHistory() {    var useRefresh = !isSupported || forceRefresh;    function getCurrentLocation(historyState) { -    historyState = historyState || window.history.state || {}; +    try { +      historyState = historyState || window.history.state || {}; +    } catch (e) { +      historyState = {}; +    }      var path = _DOMUtils.getWindowPath();      var _historyState = historyState; @@ -2116,13 +2120,15 @@ var KNOWN_STATICS = {  };  module.exports = function hoistNonReactStatics(targetComponent, sourceComponent) { -    var keys = Object.getOwnPropertyNames(sourceComponent); -    for (var i=0; i<keys.length; ++i) { -        if (!REACT_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]]) { -            try { -                targetComponent[keys[i]] = sourceComponent[keys[i]]; -            } catch (error) { - +    if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components +        var keys = Object.getOwnPropertyNames(sourceComponent); +        for (var i=0; i<keys.length; ++i) { +            if (!REACT_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]]) { +                try { +                    targetComponent[keys[i]] = sourceComponent[keys[i]]; +                } catch (error) { + +                }              }          }      } @@ -3227,6 +3233,9 @@ var currentQueue;  var queueIndex = -1;  function cleanUpNextTick() { +    if (!draining || !currentQueue) { +        return; +    }      draining = false;      if (currentQueue.length) {          queue = currentQueue.concat(queue); @@ -4587,6 +4596,7 @@ function compilePattern(pattern) {   * - **             Consumes (greedy) all characters up to the next character   *                  in the pattern, or to the end of the URL if there is none   * + *  The function calls callback(error, matched) when finished.   * The return value is an object with the following properties:   *   * - remainingPathname @@ -6786,13 +6796,17 @@ function matchRouteDeep(route, location, remainingPathname, paramNames, paramVal    // Only try to match the path if the route actually has a pattern, and if    // we're not just searching for potential nested absolute paths.    if (remainingPathname !== null && pattern) { -    var matched = (0, _PatternUtils.matchPattern)(pattern, remainingPathname); -    if (matched) { -      remainingPathname = matched.remainingPathname; -      paramNames = [].concat(paramNames, matched.paramNames); -      paramValues = [].concat(paramValues, matched.paramValues); -    } else { -      remainingPathname = null; +    try { +      var matched = (0, _PatternUtils.matchPattern)(pattern, remainingPathname); +      if (matched) { +        remainingPathname = matched.remainingPathname; +        paramNames = [].concat(paramNames, matched.paramNames); +        paramValues = [].concat(paramValues, matched.paramValues); +      } else { +        remainingPathname = null; +      } +    } catch (error) { +      callback(error);      }      // By assumption, pattern is non-empty here, which is the prerequisite for @@ -27346,7 +27360,7 @@ module.exports.Dispatcher = require('./lib/Dispatcher');  },{"./lib/Dispatcher":5}],"jquery":[function(require,module,exports){  /*! - * jQuery JavaScript Library v2.2.3 + * jQuery JavaScript Library v2.2.4   * http://jquery.com/   *   * Includes Sizzle.js @@ -27356,7 +27370,7 @@ module.exports.Dispatcher = require('./lib/Dispatcher');   * Released under the MIT license   * http://jquery.org/license   * - * Date: 2016-04-05T19:26Z + * Date: 2016-05-20T17:23Z   */  (function( global, factory ) { @@ -27412,7 +27426,7 @@ var support = {};  var -	version = "2.2.3", +	version = "2.2.4",  	// Define a local copy of jQuery  	jQuery = function( selector, context ) { @@ -32353,13 +32367,14 @@ jQuery.Event.prototype = {  	isDefaultPrevented: returnFalse,  	isPropagationStopped: returnFalse,  	isImmediatePropagationStopped: returnFalse, +	isSimulated: false,  	preventDefault: function() {  		var e = this.originalEvent;  		this.isDefaultPrevented = returnTrue; -		if ( e ) { +		if ( e && !this.isSimulated ) {  			e.preventDefault();  		}  	}, @@ -32368,7 +32383,7 @@ jQuery.Event.prototype = {  		this.isPropagationStopped = returnTrue; -		if ( e ) { +		if ( e && !this.isSimulated ) {  			e.stopPropagation();  		}  	}, @@ -32377,7 +32392,7 @@ jQuery.Event.prototype = {  		this.isImmediatePropagationStopped = returnTrue; -		if ( e ) { +		if ( e && !this.isSimulated ) {  			e.stopImmediatePropagation();  		} @@ -33308,19 +33323,6 @@ function getWidthOrHeight( elem, name, extra ) {  		styles = getStyles( elem ),  		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; -	// Support: IE11 only -	// In IE 11 fullscreen elements inside of an iframe have -	// 100x too small dimensions (gh-1764). -	if ( document.msFullscreenElement && window.top !== window ) { - -		// Support: IE11 only -		// Running getBoundingClientRect on a disconnected node -		// in IE throws an error. -		if ( elem.getClientRects().length ) { -			val = Math.round( elem.getBoundingClientRect()[ name ] * 100 ); -		} -	} -  	// Some non-html elements return undefined for offsetWidth, so check for null/undefined  	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285  	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 @@ -35211,6 +35213,7 @@ jQuery.extend( jQuery.event, {  	},  	// Piggyback on a donor event to simulate a different one +	// Used only for `focus(in | out)` events  	simulate: function( type, elem, event ) {  		var e = jQuery.extend(  			new jQuery.Event(), @@ -35218,27 +35221,10 @@ jQuery.extend( jQuery.event, {  			{  				type: type,  				isSimulated: true - -				// Previously, `originalEvent: {}` was set here, so stopPropagation call -				// would not be triggered on donor event, since in our own -				// jQuery.event.stopPropagation function we had a check for existence of -				// originalEvent.stopPropagation method, so, consequently it would be a noop. -				// -				// But now, this "simulate" function is used only for events -				// for which stopPropagation() is noop, so there is no need for that anymore. -				// -				// For the 1.x branch though, guard for "click" and "submit" -				// events is still used, but was moved to jQuery.event.stopPropagation function -				// because `originalEvent` should point to the original event for the constancy -				// with other events and for more focused logic  			}  		);  		jQuery.event.trigger( e, null, elem ); - -		if ( e.isDefaultPrevented() ) { -			event.preventDefault(); -		}  	}  } ); @@ -37192,8 +37178,7 @@ return jQuery;  (function (global){  /**   * @license - * lodash 4.11.2 (Custom Build) <https://lodash.com/> - * Build: `lodash -d -o ./foo/lodash.js` + * lodash <https://lodash.com/>   * Copyright jQuery Foundation and other contributors <https://jquery.org/>   * Released under MIT license <https://lodash.com/license>   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> @@ -37205,7 +37190,7 @@ return jQuery;    var undefined;    /** Used as the semantic version number. */ -  var VERSION = '4.11.2'; +  var VERSION = '4.13.1';    /** Used as the size to enable large array optimizations. */    var LARGE_ARRAY_SIZE = 200; @@ -37309,7 +37294,7 @@ return jQuery;    /** Used to match property names within property paths. */    var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,        reIsPlainProp = /^\w*$/, -      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; +      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(\.|\[\])(?:\4|$))/g;    /**     * Used to match `RegExp` @@ -37442,7 +37427,7 @@ return jQuery;      'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',      'Promise', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError',      'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', -    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' +    '_', 'isFinite', 'parseInt', 'setTimeout'    ];    /** Used to make template sourceURLs easier to identify. */ @@ -37521,12 +37506,6 @@ return jQuery;      '`': '`'    }; -  /** Used to determine if values are of the language type `Object`. */ -  var objectTypes = { -    'function': true, -    'object': true -  }; -    /** Used to escape characters for inclusion in compiled string literals. */    var stringEscapes = {      '\\': '\\', @@ -37542,41 +37521,25 @@ return jQuery;        freeParseInt = parseInt;    /** Detect free variable `exports`. */ -  var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) -    ? exports -    : undefined; +  var freeExports = typeof exports == 'object' && exports;    /** Detect free variable `module`. */ -  var freeModule = (objectTypes[typeof module] && module && !module.nodeType) -    ? module -    : undefined; +  var freeModule = freeExports && typeof module == 'object' && module;    /** Detect the popular CommonJS extension `module.exports`. */ -  var moduleExports = (freeModule && freeModule.exports === freeExports) -    ? freeExports -    : undefined; +  var moduleExports = freeModule && freeModule.exports === freeExports;    /** Detect free variable `global` from Node.js. */ -  var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); +  var freeGlobal = checkGlobal(typeof global == 'object' && global);    /** Detect free variable `self`. */ -  var freeSelf = checkGlobal(objectTypes[typeof self] && self); - -  /** Detect free variable `window`. */ -  var freeWindow = checkGlobal(objectTypes[typeof window] && window); +  var freeSelf = checkGlobal(typeof self == 'object' && self);    /** Detect `this` as the global object. */ -  var thisGlobal = checkGlobal(objectTypes[typeof this] && this); +  var thisGlobal = checkGlobal(typeof this == 'object' && this); -  /** -   * Used as a reference to the global object. -   * -   * The `this` value is used if it's the global object to avoid Greasemonkey's -   * restricted `window` object, otherwise the `window` object is used. -   */ -  var root = freeGlobal || -    ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || -      freeSelf || thisGlobal || Function('return this')(); +  /** Used as a reference to the global object. */ +  var root = freeGlobal || freeSelf || thisGlobal || Function('return this')();    /*--------------------------------------------------------------------------*/ @@ -37632,7 +37595,7 @@ return jQuery;     * A specialized version of `baseAggregator` for arrays.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} setter The function to set `accumulator` values.     * @param {Function} iteratee The iteratee to transform keys.     * @param {Object} accumulator The initial aggregated object. @@ -37640,7 +37603,7 @@ return jQuery;     */    function arrayAggregator(array, setter, iteratee, accumulator) {      var index = -1, -        length = array.length; +        length = array ? array.length : 0;      while (++index < length) {        var value = array[index]; @@ -37650,41 +37613,17 @@ return jQuery;    }    /** -   * Creates a new array concatenating `array` with `other`. -   * -   * @private -   * @param {Array} array The first array to concatenate. -   * @param {Array} other The second array to concatenate. -   * @returns {Array} Returns the new concatenated array. -   */ -  function arrayConcat(array, other) { -    var index = -1, -        length = array.length, -        othIndex = -1, -        othLength = other.length, -        result = Array(length + othLength); - -    while (++index < length) { -      result[index] = array[index]; -    } -    while (++othIndex < othLength) { -      result[index++] = other[othIndex]; -    } -    return result; -  } - -  /**     * A specialized version of `_.forEach` for arrays without support for     * iteratee shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns `array`.     */    function arrayEach(array, iteratee) {      var index = -1, -        length = array.length; +        length = array ? array.length : 0;      while (++index < length) {        if (iteratee(array[index], index, array) === false) { @@ -37699,12 +37638,12 @@ return jQuery;     * iteratee shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns `array`.     */    function arrayEachRight(array, iteratee) { -    var length = array.length; +    var length = array ? array.length : 0;      while (length--) {        if (iteratee(array[length], length, array) === false) { @@ -37719,14 +37658,14 @@ return jQuery;     * iteratee shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if all elements pass the predicate check,     *  else `false`.     */    function arrayEvery(array, predicate) {      var index = -1, -        length = array.length; +        length = array ? array.length : 0;      while (++index < length) {        if (!predicate(array[index], index, array)) { @@ -37741,13 +37680,13 @@ return jQuery;     * iteratee shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {Array} Returns the new filtered array.     */    function arrayFilter(array, predicate) {      var index = -1, -        length = array.length, +        length = array ? array.length : 0,          resIndex = 0,          result = []; @@ -37765,26 +37704,27 @@ return jQuery;     * specifying an index to search from.     *     * @private -   * @param {Array} array The array to search. +   * @param {Array} [array] The array to search.     * @param {*} target The value to search for.     * @returns {boolean} Returns `true` if `target` is found, else `false`.     */    function arrayIncludes(array, value) { -    return !!array.length && baseIndexOf(array, value, 0) > -1; +    var length = array ? array.length : 0; +    return !!length && baseIndexOf(array, value, 0) > -1;    }    /**     * This function is like `arrayIncludes` except that it accepts a comparator.     *     * @private -   * @param {Array} array The array to search. +   * @param {Array} [array] The array to search.     * @param {*} target The value to search for.     * @param {Function} comparator The comparator invoked per element.     * @returns {boolean} Returns `true` if `target` is found, else `false`.     */    function arrayIncludesWith(array, value, comparator) {      var index = -1, -        length = array.length; +        length = array ? array.length : 0;      while (++index < length) {        if (comparator(value, array[index])) { @@ -37799,13 +37739,13 @@ return jQuery;     * shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns the new mapped array.     */    function arrayMap(array, iteratee) {      var index = -1, -        length = array.length, +        length = array ? array.length : 0,          result = Array(length);      while (++index < length) { @@ -37838,7 +37778,7 @@ return jQuery;     * iteratee shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @param {boolean} [initAccum] Specify using the first element of `array` as @@ -37847,7 +37787,7 @@ return jQuery;     */    function arrayReduce(array, iteratee, accumulator, initAccum) {      var index = -1, -        length = array.length; +        length = array ? array.length : 0;      if (initAccum && length) {        accumulator = array[++index]; @@ -37863,7 +37803,7 @@ return jQuery;     * iteratee shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @param {boolean} [initAccum] Specify using the last element of `array` as @@ -37871,7 +37811,7 @@ return jQuery;     * @returns {*} Returns the accumulated value.     */    function arrayReduceRight(array, iteratee, accumulator, initAccum) { -    var length = array.length; +    var length = array ? array.length : 0;      if (initAccum && length) {        accumulator = array[--length];      } @@ -37886,14 +37826,14 @@ return jQuery;     * shorthands.     *     * @private -   * @param {Array} array The array to iterate over. +   * @param {Array} [array] The array to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if any element passes the predicate check,     *  else `false`.     */    function arraySome(array, predicate) {      var index = -1, -        length = array.length; +        length = array ? array.length : 0;      while (++index < length) {        if (predicate(array[index], index, array)) { @@ -37904,23 +37844,21 @@ return jQuery;    }    /** -   * The base implementation of methods like `_.find` and `_.findKey`, without -   * support for iteratee shorthands, which iterates over `collection` using -   * `eachFunc`. +   * The base implementation of methods like `_.findKey` and `_.findLastKey`, +   * without support for iteratee shorthands, which iterates over `collection` +   * using `eachFunc`.     *     * @private     * @param {Array|Object} collection The collection to search.     * @param {Function} predicate The function invoked per iteration.     * @param {Function} eachFunc The function to iterate over `collection`. -   * @param {boolean} [retKey] Specify returning the key of the found element -   *  instead of the element itself.     * @returns {*} Returns the found element or its key, else `undefined`.     */ -  function baseFind(collection, predicate, eachFunc, retKey) { +  function baseFindKey(collection, predicate, eachFunc) {      var result;      eachFunc(collection, function(value, key, collection) {        if (predicate(value, key, collection)) { -        result = retKey ? key : value; +        result = key;          return false;        }      }); @@ -37934,12 +37872,13 @@ return jQuery;     * @private     * @param {Array} array The array to search.     * @param {Function} predicate The function invoked per iteration. +   * @param {number} fromIndex The index to search from.     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {number} Returns the index of the matched value, else `-1`.     */ -  function baseFindIndex(array, predicate, fromRight) { +  function baseFindIndex(array, predicate, fromIndex, fromRight) {      var length = array.length, -        index = fromRight ? length : -1; +        index = fromIndex + (fromRight ? 1 : -1);      while ((fromRight ? index-- : ++index < length)) {        if (predicate(array[index], index, array)) { @@ -38100,7 +38039,7 @@ return jQuery;     * @private     * @param {Object} object The object to query.     * @param {Array} props The property names to get values for. -   * @returns {Object} Returns the new array of key-value pairs. +   * @returns {Object} Returns the key-value pairs.     */    function baseToPairs(object, props) {      return arrayMap(props, function(key) { @@ -38113,7 +38052,7 @@ return jQuery;     *     * @private     * @param {Function} func The function to cap arguments for. -   * @returns {Function} Returns the new function. +   * @returns {Function} Returns the new capped function.     */    function baseUnary(func) {      return function(value) { @@ -38138,6 +38077,18 @@ return jQuery;    }    /** +   * Checks if a cache value for `key` exists. +   * +   * @private +   * @param {Object} cache The cache to query. +   * @param {string} key The key of the entry to check. +   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. +   */ +  function cacheHas(cache, key) { +    return cache.has(key); +  } + +  /**     * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol     * that is not found in the character symbols.     * @@ -38235,6 +38186,18 @@ return jQuery;    }    /** +   * Gets the value at `key` of `object`. +   * +   * @private +   * @param {Object} [object] The object to query. +   * @param {string} key The key of the property to get. +   * @returns {*} Returns the property value. +   */ +  function getValue(object, key) { +    return object == null ? undefined : object[key]; +  } + +  /**     * Gets the index at which the first occurrence of `NaN` is found in `array`.     *     * @private @@ -38245,7 +38208,7 @@ return jQuery;     */    function indexOfNaN(array, fromIndex, fromRight) {      var length = array.length, -        index = fromIndex + (fromRight ? 0 : -1); +        index = fromIndex + (fromRight ? 1 : -1);      while ((fromRight ? index-- : ++index < length)) {        var other = array[index]; @@ -38293,11 +38256,11 @@ return jQuery;    }    /** -   * Converts `map` to an array. +   * Converts `map` to its key-value pairs.     *     * @private     * @param {Object} map The map to convert. -   * @returns {Array} Returns the converted array. +   * @returns {Array} Returns the key-value pairs.     */    function mapToArray(map) {      var index = -1, @@ -38335,11 +38298,11 @@ return jQuery;    }    /** -   * Converts `set` to an array. +   * Converts `set` to an array of its values.     *     * @private     * @param {Object} set The set to convert. -   * @returns {Array} Returns the converted array. +   * @returns {Array} Returns the values.     */    function setToArray(set) {      var index = -1, @@ -38352,6 +38315,23 @@ return jQuery;    }    /** +   * Converts `set` to its value-value pairs. +   * +   * @private +   * @param {Object} set The set to convert. +   * @returns {Array} Returns the value-value pairs. +   */ +  function setToPairs(set) { +    var index = -1, +        result = Array(set.size); + +    set.forEach(function(value) { +      result[++index] = [value, value]; +    }); +    return result; +  } + +  /**     * Gets the number of symbols in `string`.     *     * @private @@ -38419,10 +38399,10 @@ return jQuery;     * lodash.isFunction(lodash.bar);     * // => true     * -   * // Use `context` to mock `Date#getTime` use in `_.now`. -   * var mock = _.runInContext({ +   * // Use `context` to stub `Date#getTime` use in `_.now`. +   * var stubbed = _.runInContext({     *   'Date': function() { -   *     return { 'getTime': getTimeMock }; +   *     return { 'getTime': stubGetTime };     *   }     * });     * @@ -38444,6 +38424,15 @@ return jQuery;          objectProto = context.Object.prototype,          stringProto = context.String.prototype; +    /** Used to detect overreaching core-js shims. */ +    var coreJsData = context['__core-js_shared__']; + +    /** Used to detect methods masquerading as native. */ +    var maskSrcKey = (function() { +      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); +      return uid ? ('Symbol(src)_1.' + uid) : ''; +    }()); +      /** Used to resolve the decompiled source of functions. */      var funcToString = context.Function.prototype.toString; @@ -38477,15 +38466,16 @@ return jQuery;          Reflect = context.Reflect,          Symbol = context.Symbol,          Uint8Array = context.Uint8Array, -        clearTimeout = context.clearTimeout,          enumerate = Reflect ? Reflect.enumerate : undefined,          getOwnPropertySymbols = Object.getOwnPropertySymbols,          iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,          objectCreate = Object.create,          propertyIsEnumerable = objectProto.propertyIsEnumerable, -        setTimeout = context.setTimeout,          splice = arrayProto.splice; +    /** Built-in method references that are mockable. */ +    var setTimeout = function(func, wait) { return context.setTimeout.call(root, func, wait); }; +      /* Built-in method references for those with the same name as other `lodash` methods. */      var nativeCeil = Math.ceil,          nativeFloor = Math.floor, @@ -38604,22 +38594,24 @@ return jQuery;       * `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,       * `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`,       * `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, -     * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, -     * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, -     * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, -     * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, -     * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`, -     * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, -     * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, -     * `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `multiply`, -     * `noConflict`, `noop`, `now`, `nth`, `pad`, `padEnd`, `padStart`, `parseInt`, -     * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`, -     * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, -     * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, -     * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toInteger`, -     * `toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`, -     * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, -     * `uniqueId`, `upperCase`, `upperFirst`, `value`, and `words` +     * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, +     * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, +     * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, +     * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, +     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, +     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, +     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, +     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, +     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, +     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, +     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, +     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, +     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, +     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, +     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, +     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, +     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, +     * `upperFirst`, `value`, and `words`       *       * @name _       * @constructor @@ -38878,64 +38870,212 @@ return jQuery;       *       * @private       * @constructor -     * @returns {Object} Returns the new hash object. +     * @param {Array} [entries] The key-value pairs to cache.       */ -    function Hash() {} +    function Hash(entries) { +      var index = -1, +          length = entries ? entries.length : 0; + +      this.clear(); +      while (++index < length) { +        var entry = entries[index]; +        this.set(entry[0], entry[1]); +      } +    } + +    /** +     * Removes all key-value entries from the hash. +     * +     * @private +     * @name clear +     * @memberOf Hash +     */ +    function hashClear() { +      this.__data__ = nativeCreate ? nativeCreate(null) : {}; +    }      /**       * Removes `key` and its value from the hash.       *       * @private +     * @name delete +     * @memberOf Hash       * @param {Object} hash The hash to modify.       * @param {string} key The key of the value to remove.       * @returns {boolean} Returns `true` if the entry was removed, else `false`.       */ -    function hashDelete(hash, key) { -      return hashHas(hash, key) && delete hash[key]; +    function hashDelete(key) { +      return this.has(key) && delete this.__data__[key];      }      /**       * Gets the hash value for `key`.       *       * @private -     * @param {Object} hash The hash to query. +     * @name get +     * @memberOf Hash       * @param {string} key The key of the value to get.       * @returns {*} Returns the entry value.       */ -    function hashGet(hash, key) { +    function hashGet(key) { +      var data = this.__data__;        if (nativeCreate) { -        var result = hash[key]; +        var result = data[key];          return result === HASH_UNDEFINED ? undefined : result;        } -      return hasOwnProperty.call(hash, key) ? hash[key] : undefined; +      return hasOwnProperty.call(data, key) ? data[key] : undefined;      }      /**       * Checks if a hash value for `key` exists.       *       * @private -     * @param {Object} hash The hash to query. +     * @name has +     * @memberOf Hash       * @param {string} key The key of the entry to check.       * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.       */ -    function hashHas(hash, key) { -      return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); +    function hashHas(key) { +      var data = this.__data__; +      return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);      }      /**       * Sets the hash `key` to `value`.       *       * @private -     * @param {Object} hash The hash to modify. +     * @name set +     * @memberOf Hash +     * @param {string} key The key of the value to set. +     * @param {*} value The value to set. +     * @returns {Object} Returns the hash instance. +     */ +    function hashSet(key, value) { +      var data = this.__data__; +      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; +      return this; +    } + +    // Add methods to `Hash`. +    Hash.prototype.clear = hashClear; +    Hash.prototype['delete'] = hashDelete; +    Hash.prototype.get = hashGet; +    Hash.prototype.has = hashHas; +    Hash.prototype.set = hashSet; + +    /*------------------------------------------------------------------------*/ + +    /** +     * Creates an list cache object. +     * +     * @private +     * @constructor +     * @param {Array} [entries] The key-value pairs to cache. +     */ +    function ListCache(entries) { +      var index = -1, +          length = entries ? entries.length : 0; + +      this.clear(); +      while (++index < length) { +        var entry = entries[index]; +        this.set(entry[0], entry[1]); +      } +    } + +    /** +     * Removes all key-value entries from the list cache. +     * +     * @private +     * @name clear +     * @memberOf ListCache +     */ +    function listCacheClear() { +      this.__data__ = []; +    } + +    /** +     * Removes `key` and its value from the list cache. +     * +     * @private +     * @name delete +     * @memberOf ListCache +     * @param {string} key The key of the value to remove. +     * @returns {boolean} Returns `true` if the entry was removed, else `false`. +     */ +    function listCacheDelete(key) { +      var data = this.__data__, +          index = assocIndexOf(data, key); + +      if (index < 0) { +        return false; +      } +      var lastIndex = data.length - 1; +      if (index == lastIndex) { +        data.pop(); +      } else { +        splice.call(data, index, 1); +      } +      return true; +    } + +    /** +     * Gets the list cache value for `key`. +     * +     * @private +     * @name get +     * @memberOf ListCache +     * @param {string} key The key of the value to get. +     * @returns {*} Returns the entry value. +     */ +    function listCacheGet(key) { +      var data = this.__data__, +          index = assocIndexOf(data, key); + +      return index < 0 ? undefined : data[index][1]; +    } + +    /** +     * Checks if a list cache value for `key` exists. +     * +     * @private +     * @name has +     * @memberOf ListCache +     * @param {string} key The key of the entry to check. +     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. +     */ +    function listCacheHas(key) { +      return assocIndexOf(this.__data__, key) > -1; +    } + +    /** +     * Sets the list cache `key` to `value`. +     * +     * @private +     * @name set +     * @memberOf ListCache       * @param {string} key The key of the value to set.       * @param {*} value The value to set. +     * @returns {Object} Returns the list cache instance.       */ -    function hashSet(hash, key, value) { -      hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; +    function listCacheSet(key, value) { +      var data = this.__data__, +          index = assocIndexOf(data, key); + +      if (index < 0) { +        data.push([key, value]); +      } else { +        data[index][1] = value; +      } +      return this;      } -    // Avoid inheriting from `Object.prototype` when possible. -    Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto; +    // Add methods to `ListCache`. +    ListCache.prototype.clear = listCacheClear; +    ListCache.prototype['delete'] = listCacheDelete; +    ListCache.prototype.get = listCacheGet; +    ListCache.prototype.has = listCacheHas; +    ListCache.prototype.set = listCacheSet;      /*------------------------------------------------------------------------*/ @@ -38944,15 +39084,15 @@ return jQuery;       *       * @private       * @constructor -     * @param {Array} [values] The values to cache. +     * @param {Array} [entries] The key-value pairs to cache.       */ -    function MapCache(values) { +    function MapCache(entries) {        var index = -1, -          length = values ? values.length : 0; +          length = entries ? entries.length : 0;        this.clear();        while (++index < length) { -        var entry = values[index]; +        var entry = entries[index];          this.set(entry[0], entry[1]);        }      } @@ -38964,10 +39104,10 @@ return jQuery;       * @name clear       * @memberOf MapCache       */ -    function mapClear() { +    function mapCacheClear() {        this.__data__ = {          'hash': new Hash, -        'map': Map ? new Map : [], +        'map': new (Map || ListCache),          'string': new Hash        };      } @@ -38981,12 +39121,8 @@ return jQuery;       * @param {string} key The key of the value to remove.       * @returns {boolean} Returns `true` if the entry was removed, else `false`.       */ -    function mapDelete(key) { -      var data = this.__data__; -      if (isKeyable(key)) { -        return hashDelete(typeof key == 'string' ? data.string : data.hash, key); -      } -      return Map ? data.map['delete'](key) : assocDelete(data.map, key); +    function mapCacheDelete(key) { +      return getMapData(this, key)['delete'](key);      }      /** @@ -38998,12 +39134,8 @@ return jQuery;       * @param {string} key The key of the value to get.       * @returns {*} Returns the entry value.       */ -    function mapGet(key) { -      var data = this.__data__; -      if (isKeyable(key)) { -        return hashGet(typeof key == 'string' ? data.string : data.hash, key); -      } -      return Map ? data.map.get(key) : assocGet(data.map, key); +    function mapCacheGet(key) { +      return getMapData(this, key).get(key);      }      /** @@ -39015,12 +39147,8 @@ return jQuery;       * @param {string} key The key of the entry to check.       * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.       */ -    function mapHas(key) { -      var data = this.__data__; -      if (isKeyable(key)) { -        return hashHas(typeof key == 'string' ? data.string : data.hash, key); -      } -      return Map ? data.map.has(key) : assocHas(data.map, key); +    function mapCacheHas(key) { +      return getMapData(this, key).has(key);      }      /** @@ -39033,30 +39161,23 @@ return jQuery;       * @param {*} value The value to set.       * @returns {Object} Returns the map cache instance.       */ -    function mapSet(key, value) { -      var data = this.__data__; -      if (isKeyable(key)) { -        hashSet(typeof key == 'string' ? data.string : data.hash, key, value); -      } else if (Map) { -        data.map.set(key, value); -      } else { -        assocSet(data.map, key, value); -      } +    function mapCacheSet(key, value) { +      getMapData(this, key).set(key, value);        return this;      }      // Add methods to `MapCache`. -    MapCache.prototype.clear = mapClear; -    MapCache.prototype['delete'] = mapDelete; -    MapCache.prototype.get = mapGet; -    MapCache.prototype.has = mapHas; -    MapCache.prototype.set = mapSet; +    MapCache.prototype.clear = mapCacheClear; +    MapCache.prototype['delete'] = mapCacheDelete; +    MapCache.prototype.get = mapCacheGet; +    MapCache.prototype.has = mapCacheHas; +    MapCache.prototype.set = mapCacheSet;      /*------------------------------------------------------------------------*/      /**       * -     * Creates a set cache object to store unique values. +     * Creates an array cache object to store unique values.       *       * @private       * @constructor @@ -39068,52 +39189,41 @@ return jQuery;        this.__data__ = new MapCache;        while (++index < length) { -        this.push(values[index]); +        this.add(values[index]);        }      }      /** -     * Checks if `value` is in `cache`. +     * Adds `value` to the array cache.       *       * @private -     * @param {Object} cache The set cache to search. -     * @param {*} value The value to search for. -     * @returns {number} Returns `true` if `value` is found, else `false`. +     * @name add +     * @memberOf SetCache +     * @alias push +     * @param {*} value The value to cache. +     * @returns {Object} Returns the cache instance.       */ -    function cacheHas(cache, value) { -      var map = cache.__data__; -      if (isKeyable(value)) { -        var data = map.__data__, -            hash = typeof value == 'string' ? data.string : data.hash; - -        return hash[value] === HASH_UNDEFINED; -      } -      return map.has(value); +    function setCacheAdd(value) { +      this.__data__.set(value, HASH_UNDEFINED); +      return this;      }      /** -     * Adds `value` to the set cache. +     * Checks if `value` is in the array cache.       *       * @private -     * @name push +     * @name has       * @memberOf SetCache -     * @param {*} value The value to cache. +     * @param {*} value The value to search for. +     * @returns {number} Returns `true` if `value` is found, else `false`.       */ -    function cachePush(value) { -      var map = this.__data__; -      if (isKeyable(value)) { -        var data = map.__data__, -            hash = typeof value == 'string' ? data.string : data.hash; - -        hash[value] = HASH_UNDEFINED; -      } -      else { -        map.set(value, HASH_UNDEFINED); -      } +    function setCacheHas(value) { +      return this.__data__.has(value);      }      // Add methods to `SetCache`. -    SetCache.prototype.push = cachePush; +    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; +    SetCache.prototype.has = setCacheHas;      /*------------------------------------------------------------------------*/ @@ -39122,17 +39232,10 @@ return jQuery;       *       * @private       * @constructor -     * @param {Array} [values] The values to cache. +     * @param {Array} [entries] The key-value pairs to cache.       */ -    function Stack(values) { -      var index = -1, -          length = values ? values.length : 0; - -      this.clear(); -      while (++index < length) { -        var entry = values[index]; -        this.set(entry[0], entry[1]); -      } +    function Stack(entries) { +      this.__data__ = new ListCache(entries);      }      /** @@ -39143,7 +39246,7 @@ return jQuery;       * @memberOf Stack       */      function stackClear() { -      this.__data__ = { 'array': [], 'map': null }; +      this.__data__ = new ListCache;      }      /** @@ -39156,10 +39259,7 @@ return jQuery;       * @returns {boolean} Returns `true` if the entry was removed, else `false`.       */      function stackDelete(key) { -      var data = this.__data__, -          array = data.array; - -      return array ? assocDelete(array, key) : data.map['delete'](key); +      return this.__data__['delete'](key);      }      /** @@ -39172,10 +39272,7 @@ return jQuery;       * @returns {*} Returns the entry value.       */      function stackGet(key) { -      var data = this.__data__, -          array = data.array; - -      return array ? assocGet(array, key) : data.map.get(key); +      return this.__data__.get(key);      }      /** @@ -39188,10 +39285,7 @@ return jQuery;       * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.       */      function stackHas(key) { -      var data = this.__data__, -          array = data.array; - -      return array ? assocHas(array, key) : data.map.has(key); +      return this.__data__.has(key);      }      /** @@ -39205,21 +39299,11 @@ return jQuery;       * @returns {Object} Returns the stack cache instance.       */      function stackSet(key, value) { -      var data = this.__data__, -          array = data.array; - -      if (array) { -        if (array.length < (LARGE_ARRAY_SIZE - 1)) { -          assocSet(array, key, value); -        } else { -          data.array = null; -          data.map = new MapCache(array); -        } -      } -      var map = data.map; -      if (map) { -        map.set(key, value); +      var cache = this.__data__; +      if (cache instanceof ListCache && cache.__data__.length == LARGE_ARRAY_SIZE) { +        cache = this.__data__ = new MapCache(cache.__data__);        } +      cache.set(key, value);        return this;      } @@ -39233,90 +39317,6 @@ return jQuery;      /*------------------------------------------------------------------------*/      /** -     * Removes `key` and its value from the associative array. -     * -     * @private -     * @param {Array} array The array to modify. -     * @param {string} key The key of the value to remove. -     * @returns {boolean} Returns `true` if the entry was removed, else `false`. -     */ -    function assocDelete(array, key) { -      var index = assocIndexOf(array, key); -      if (index < 0) { -        return false; -      } -      var lastIndex = array.length - 1; -      if (index == lastIndex) { -        array.pop(); -      } else { -        splice.call(array, index, 1); -      } -      return true; -    } - -    /** -     * Gets the associative array value for `key`. -     * -     * @private -     * @param {Array} array The array to query. -     * @param {string} key The key of the value to get. -     * @returns {*} Returns the entry value. -     */ -    function assocGet(array, key) { -      var index = assocIndexOf(array, key); -      return index < 0 ? undefined : array[index][1]; -    } - -    /** -     * Checks if an associative array value for `key` exists. -     * -     * @private -     * @param {Array} array The array to query. -     * @param {string} key The key of the entry to check. -     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. -     */ -    function assocHas(array, key) { -      return assocIndexOf(array, key) > -1; -    } - -    /** -     * Gets the index at which the `key` is found in `array` of key-value pairs. -     * -     * @private -     * @param {Array} array The array to search. -     * @param {*} key The key to search for. -     * @returns {number} Returns the index of the matched value, else `-1`. -     */ -    function assocIndexOf(array, key) { -      var length = array.length; -      while (length--) { -        if (eq(array[length][0], key)) { -          return length; -        } -      } -      return -1; -    } - -    /** -     * Sets the associative array `key` to `value`. -     * -     * @private -     * @param {Array} array The array to modify. -     * @param {string} key The key of the value to set. -     * @param {*} value The value to set. -     */ -    function assocSet(array, key, value) { -      var index = assocIndexOf(array, key); -      if (index < 0) { -        array.push([key, value]); -      } else { -        array[index][1] = value; -      } -    } - -    /*------------------------------------------------------------------------*/ - -    /**       * Used by `_.defaults` to customize its `_.assignIn` use.       *       * @private @@ -39369,6 +39369,24 @@ return jQuery;      }      /** +     * Gets the index at which the `key` is found in `array` of key-value pairs. +     * +     * @private +     * @param {Array} array The array to search. +     * @param {*} key The key to search for. +     * @returns {number} Returns the index of the matched value, else `-1`. +     */ +    function assocIndexOf(array, key) { +      var length = array.length; +      while (length--) { +        if (eq(array[length][0], key)) { +          return length; +        } +      } +      return -1; +    } + +    /**       * Aggregates elements of `collection` on `accumulator` with keys transformed       * by `iteratee` and values set by `setter`.       * @@ -39405,7 +39423,7 @@ return jQuery;       * @private       * @param {Object} object The object to iterate over.       * @param {string[]} paths The property paths of elements to pick. -     * @returns {Array} Returns the new array of picked elements. +     * @returns {Array} Returns the picked elements.       */      function baseAt(object, paths) {        var index = -1, @@ -39520,7 +39538,7 @@ return jQuery;       *       * @private       * @param {Object} source The object of property predicates to conform to. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new spec function.       */      function baseConforms(source) {        var props = keys(source), @@ -39833,7 +39851,7 @@ return jQuery;       * @private       * @param {Object} object The object to inspect.       * @param {Array} props The property names to filter. -     * @returns {Array} Returns the new array of filtered property names. +     * @returns {Array} Returns the function names.       */      function baseFunctions(object, props) {        return arrayFilter(props, function(key) { @@ -39874,9 +39892,7 @@ return jQuery;       */      function baseGetAllKeys(object, keysFunc, symbolsFunc) {        var result = keysFunc(object); -      return isArray(object) -        ? result -        : arrayPush(result, symbolsFunc(object)); +      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));      }      /** @@ -39896,7 +39912,7 @@ return jQuery;       * The base implementation of `_.has` without support for deep paths.       *       * @private -     * @param {Object} object The object to query. +     * @param {Object} [object] The object to query.       * @param {Array|string} key The key to check.       * @returns {boolean} Returns `true` if `key` exists, else `false`.       */ @@ -39904,20 +39920,21 @@ return jQuery;        // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,        // that are composed entirely of index properties, return `false` for        // `hasOwnProperty` checks of them. -      return hasOwnProperty.call(object, key) || -        (typeof object == 'object' && key in object && getPrototype(object) === null); +      return object != null && +        (hasOwnProperty.call(object, key) || +          (typeof object == 'object' && key in object && getPrototype(object) === null));      }      /**       * The base implementation of `_.hasIn` without support for deep paths.       *       * @private -     * @param {Object} object The object to query. +     * @param {Object} [object] The object to query.       * @param {Array|string} key The key to check.       * @returns {boolean} Returns `true` if `key` exists, else `false`.       */      function baseHasIn(object, key) { -      return key in Object(object); +      return object != null && key in Object(object);      }      /** @@ -40172,6 +40189,22 @@ return jQuery;      }      /** +     * The base implementation of `_.isNative` without bad shim checks. +     * +     * @private +     * @param {*} value The value to check. +     * @returns {boolean} Returns `true` if `value` is a native function, +     *  else `false`. +     */ +    function baseIsNative(value) { +      if (!isObject(value) || isMasked(value)) { +        return false; +      } +      var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; +      return pattern.test(toSource(value)); +    } + +    /**       * The base implementation of `_.iteratee`.       *       * @private @@ -40268,7 +40301,7 @@ return jQuery;       *       * @private       * @param {Object} source The object of property values to match. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new spec function.       */      function baseMatches(source) {        var matchData = getMatchData(source); @@ -40286,7 +40319,7 @@ return jQuery;       * @private       * @param {string} path The path of the property to get.       * @param {*} srcValue The value to match. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new spec function.       */      function baseMatchesProperty(path, srcValue) {        if (isKey(path) && isStrictComparable(srcValue)) { @@ -40501,7 +40534,7 @@ return jQuery;       *       * @private       * @param {string} key The key of the property to get. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new accessor function.       */      function baseProperty(key) {        return function(object) { @@ -40514,7 +40547,7 @@ return jQuery;       *       * @private       * @param {Array|string} path The path of the property to get. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new accessor function.       */      function basePropertyDeep(path) {        return function(object) { @@ -40539,6 +40572,9 @@ return jQuery;            length = values.length,            seen = array; +      if (array === values) { +        values = copyArray(values); +      }        if (iteratee) {          seen = arrayMap(array, baseUnary(iteratee));        } @@ -40615,7 +40651,7 @@ return jQuery;       * @param {number} end The end of the range.       * @param {number} step The value to increment or decrement by.       * @param {boolean} [fromRight] Specify iterating from right to left. -     * @returns {Array} Returns the new array of numbers. +     * @returns {Array} Returns the range of numbers.       */      function baseRange(start, end, step, fromRight) {        var index = -1, @@ -41329,7 +41365,7 @@ return jQuery;       * placeholders, and provided arguments into a single array of arguments.       *       * @private -     * @param {Array|Object} args The provided arguments. +     * @param {Array} args The provided arguments.       * @param {Array} partials The arguments to prepend to those provided.       * @param {Array} holders The `partials` placeholder indexes.       * @params {boolean} [isCurried] Specify composing for a curried function. @@ -41364,7 +41400,7 @@ return jQuery;       * is tailored for `_.partialRight`.       *       * @private -     * @param {Array|Object} args The provided arguments. +     * @param {Array} args The provided arguments.       * @param {Array} partials The arguments to append to those provided.       * @param {Array} holders The `partials` placeholder indexes.       * @params {boolean} [isCurried] Specify composing for a curried function. @@ -41486,7 +41522,7 @@ return jQuery;              customizer = length > 1 ? sources[length - 1] : undefined,              guard = length > 2 ? sources[2] : undefined; -        customizer = typeof customizer == 'function' +        customizer = (assigner.length > 3 && typeof customizer == 'function')            ? (length--, customizer)            : undefined; @@ -41585,7 +41621,7 @@ return jQuery;       *       * @private       * @param {string} methodName The name of the `String` case method to use. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new case function.       */      function createCaseFirst(methodName) {        return function(string) { @@ -41670,7 +41706,7 @@ return jQuery;          var length = arguments.length,              args = Array(length),              index = length, -            placeholder = getPlaceholder(wrapper); +            placeholder = getHolder(wrapper);          while (index--) {            args[index] = arguments[index]; @@ -41692,6 +41728,31 @@ return jQuery;      }      /** +     * Creates a `_.find` or `_.findLast` function. +     * +     * @private +     * @param {Function} findIndexFunc The function to find the collection index. +     * @returns {Function} Returns the new find function. +     */ +    function createFind(findIndexFunc) { +      return function(collection, predicate, fromIndex) { +        var iterable = Object(collection); +        predicate = getIteratee(predicate, 3); +        if (!isArrayLike(collection)) { +          var props = keys(collection); +        } +        var index = findIndexFunc(props || collection, function(value, key) { +          if (props) { +            key = value; +            value = iterable[key]; +          } +          return predicate(value, key, iterable); +        }, fromIndex); +        return index > -1 ? collection[props ? props[index] : index] : undefined; +      }; +    } + +    /**       * Creates a `_.flow` or `_.flowRight` function.       *       * @private @@ -41785,14 +41846,14 @@ return jQuery;        function wrapper() {          var length = arguments.length, -            index = length, -            args = Array(length); +            args = Array(length), +            index = length;          while (index--) {            args[index] = arguments[index];          }          if (isCurried) { -          var placeholder = getPlaceholder(wrapper), +          var placeholder = getHolder(wrapper),                holdersCount = countHolders(args, placeholder);          }          if (partials) { @@ -41881,7 +41942,7 @@ return jQuery;       *       * @private       * @param {Function} arrayFunc The function to iterate over iteratees. -     * @returns {Function} Returns the new invoker function. +     * @returns {Function} Returns the new over function.       */      function createOver(arrayFunc) {        return rest(function(iteratees) { @@ -42054,7 +42115,7 @@ return jQuery;        var func = Math[methodName];        return function(number, precision) {          number = toNumber(number); -        precision = toInteger(precision); +        precision = nativeMin(toInteger(precision), 292);          if (precision) {            // Shift with exponential notation to avoid floating-point issues.            // See [MDN](https://mdn.io/round#Examples) for more details. @@ -42080,6 +42141,26 @@ return jQuery;      };      /** +     * Creates a `_.toPairs` or `_.toPairsIn` function. +     * +     * @private +     * @param {Function} keysFunc The function to get the keys of a given object. +     * @returns {Function} Returns the new pairs function. +     */ +    function createToPairs(keysFunc) { +      return function(object) { +        var tag = getTag(object); +        if (tag == mapTag) { +          return mapToArray(object); +        } +        if (tag == setTag) { +          return setToPairs(object); +        } +        return baseToPairs(object, keysFunc(object)); +      }; +    } + +    /**       * Creates a function that either curries or invokes `func` with optional       * `this` binding and partially applied arguments.       * @@ -42096,6 +42177,7 @@ return jQuery;       *    64 - `_.partialRight`       *   128 - `_.rearg`       *   256 - `_.ary` +     *   512 - `_.flip`       * @param {*} [thisArg] The `this` binding of `func`.       * @param {Array} [partials] The arguments to be partially applied.       * @param {Array} [holders] The `partials` placeholder indexes. @@ -42174,9 +42256,7 @@ return jQuery;       * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.       */      function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { -      var index = -1, -          isPartial = bitmask & PARTIAL_COMPARE_FLAG, -          isUnordered = bitmask & UNORDERED_COMPARE_FLAG, +      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,            arrLength = array.length,            othLength = other.length; @@ -42188,7 +42268,10 @@ return jQuery;        if (stacked) {          return stacked == other;        } -      var result = true; +      var index = -1, +          result = true, +          seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined; +        stack.set(array, other);        // Ignore non-index properties. @@ -42209,10 +42292,12 @@ return jQuery;            break;          }          // Recursively compare arrays (susceptible to call stack limits). -        if (isUnordered) { -          if (!arraySome(other, function(othValue) { -                return arrValue === othValue || -                  equalFunc(arrValue, othValue, customizer, bitmask, stack); +        if (seen) { +          if (!arraySome(other, function(othValue, othIndex) { +                if (!seen.has(othIndex) && +                    (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { +                  return seen.add(othIndex); +                }                })) {              result = false;              break; @@ -42447,6 +42532,18 @@ return jQuery;      }      /** +     * Gets the argument placeholder value for `func`. +     * +     * @private +     * @param {Function} func The function to inspect. +     * @returns {*} Returns the placeholder value. +     */ +    function getHolder(func) { +      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; +      return object.placeholder; +    } + +    /**       * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,       * this function returns the custom method, otherwise it returns `baseIteratee`.       * If arguments are provided, the chosen function is invoked with them and @@ -42477,6 +42574,21 @@ return jQuery;      var getLength = baseProperty('length');      /** +     * Gets the data for `map`. +     * +     * @private +     * @param {Object} map The map to query. +     * @param {string} key The reference key. +     * @returns {*} Returns the map data. +     */ +    function getMapData(map, key) { +      var data = map.__data__; +      return isKeyable(key) +        ? data[typeof key == 'string' ? 'string' : 'hash'] +        : data.map; +    } + +    /**       * Gets the property names, values, and compare flags of `object`.       *       * @private @@ -42484,11 +42596,14 @@ return jQuery;       * @returns {Array} Returns the match data of `object`.       */      function getMatchData(object) { -      var result = toPairs(object), +      var result = keys(object),            length = result.length;        while (length--) { -        result[length][2] = isStrictComparable(result[length][1]); +        var key = result[length], +            value = object[key]; + +        result[length] = [key, value, isStrictComparable(value)];        }        return result;      } @@ -42502,20 +42617,8 @@ return jQuery;       * @returns {*} Returns the function if it's native, else `undefined`.       */      function getNative(object, key) { -      var value = object[key]; -      return isNative(value) ? value : undefined; -    } - -    /** -     * Gets the argument placeholder value for `func`. -     * -     * @private -     * @param {Function} func The function to inspect. -     * @returns {*} Returns the placeholder value. -     */ -    function getPlaceholder(func) { -      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; -      return object.placeholder; +      var value = getValue(object, key); +      return baseIsNative(value) ? value : undefined;      }      /** @@ -42544,9 +42647,7 @@ return jQuery;      // Fallback for IE < 11.      if (!getOwnPropertySymbols) { -      getSymbols = function() { -        return []; -      }; +      getSymbols = stubArray;      }      /** @@ -42767,7 +42868,7 @@ return jQuery;       * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.       */      function isFlattenable(value) { -      return isArrayLikeObject(value) && (isArray(value) || isArguments(value)); +      return isArray(value) || isArguments(value);      }      /** @@ -42879,6 +42980,26 @@ return jQuery;      }      /** +     * Checks if `func` has its source masked. +     * +     * @private +     * @param {Function} func The function to check. +     * @returns {boolean} Returns `true` if `func` is masked, else `false`. +     */ +    function isMasked(func) { +      return !!maskSrcKey && (maskSrcKey in func); +    } + +    /** +     * Checks if `func` is capable of being masked. +     * +     * @private +     * @param {*} value The value to check. +     * @returns {boolean} Returns `true` if `func` is maskable, else `false`. +     */ +    var isMaskable = coreJsData ? isFunction : stubFalse; + +    /**       * Checks if `value` is likely a prototype object.       *       * @private @@ -42911,7 +43032,7 @@ return jQuery;       * @private       * @param {string} key The key of the property to get.       * @param {*} srcValue The value to match. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new spec function.       */      function matchesStrictComparable(key, srcValue) {        return function(object) { @@ -43163,7 +43284,7 @@ return jQuery;       * @param {Array} array The array to process.       * @param {number} [size=1] The length of each chunk       * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. -     * @returns {Array} Returns the new array containing chunks. +     * @returns {Array} Returns the new array of chunks.       * @example       *       * _.chunk(['a', 'b', 'c', 'd'], 2); @@ -43246,16 +43367,16 @@ return jQuery;       */      function concat() {        var length = arguments.length, -          array = castArray(arguments[0]); +          args = Array(length ? length - 1 : 0), +          array = arguments[0], +          index = length; -      if (length < 2) { -        return length ? copyArray(array) : []; -      } -      var args = Array(length - 1); -      while (length--) { -        args[length - 1] = arguments[length]; +      while (index--) { +        args[index - 1] = arguments[index];        } -      return arrayConcat(array, baseFlatten(args, 1)); +      return length +        ? arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)) +        : [];      }      /** @@ -43274,8 +43395,8 @@ return jQuery;       * @see _.without, _.xor       * @example       * -     * _.difference([3, 2, 1], [4, 2]); -     * // => [3, 1] +     * _.difference([2, 1], [2, 3]); +     * // => [1]       */      var difference = rest(function(array, values) {        return isArrayLikeObject(array) @@ -43300,8 +43421,8 @@ return jQuery;       * @returns {Array} Returns the new array of filtered values.       * @example       * -     * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); -     * // => [3.1, 1.3] +     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); +     * // => [1.2]       *       * // The `_.property` iteratee shorthand.       * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); @@ -43553,6 +43674,7 @@ return jQuery;       * @param {Array} array The array to search.       * @param {Array|Function|Object|string} [predicate=_.identity]       *  The function invoked per iteration. +     * @param {number} [fromIndex=0] The index to search from.       * @returns {number} Returns the index of the found element, else `-1`.       * @example       * @@ -43577,10 +43699,16 @@ return jQuery;       * _.findIndex(users, 'active');       * // => 2       */ -    function findIndex(array, predicate) { -      return (array && array.length) -        ? baseFindIndex(array, getIteratee(predicate, 3)) -        : -1; +    function findIndex(array, predicate, fromIndex) { +      var length = array ? array.length : 0; +      if (!length) { +        return -1; +      } +      var index = fromIndex == null ? 0 : toInteger(fromIndex); +      if (index < 0) { +        index = nativeMax(length + index, 0); +      } +      return baseFindIndex(array, getIteratee(predicate, 3), index);      }      /** @@ -43594,6 +43722,7 @@ return jQuery;       * @param {Array} array The array to search.       * @param {Array|Function|Object|string} [predicate=_.identity]       *  The function invoked per iteration. +     * @param {number} [fromIndex=array.length-1] The index to search from.       * @returns {number} Returns the index of the found element, else `-1`.       * @example       * @@ -43618,10 +43747,19 @@ return jQuery;       * _.findLastIndex(users, 'active');       * // => 0       */ -    function findLastIndex(array, predicate) { -      return (array && array.length) -        ? baseFindIndex(array, getIteratee(predicate, 3), true) -        : -1; +    function findLastIndex(array, predicate, fromIndex) { +      var length = array ? array.length : 0; +      if (!length) { +        return -1; +      } +      var index = length - 1; +      if (fromIndex !== undefined) { +        index = toInteger(fromIndex); +        index = fromIndex < 0 +          ? nativeMax(length + index, 0) +          : nativeMin(index, length - 1); +      } +      return baseFindIndex(array, getIteratee(predicate, 3), index, true);      }      /** @@ -43768,11 +43906,11 @@ return jQuery;        if (!length) {          return -1;        } -      fromIndex = toInteger(fromIndex); -      if (fromIndex < 0) { -        fromIndex = nativeMax(length + fromIndex, 0); +      var index = fromIndex == null ? 0 : toInteger(fromIndex); +      if (index < 0) { +        index = nativeMax(length + index, 0);        } -      return baseIndexOf(array, value, fromIndex); +      return baseIndexOf(array, value, index);      }      /** @@ -43807,7 +43945,7 @@ return jQuery;       * @returns {Array} Returns the new array of intersecting values.       * @example       * -     * _.intersection([2, 1], [4, 2], [1, 2]); +     * _.intersection([2, 1], [2, 3]);       * // => [2]       */      var intersection = rest(function(arrays) { @@ -43833,7 +43971,7 @@ return jQuery;       * @returns {Array} Returns the new array of intersecting values.       * @example       * -     * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); +     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);       * // => [2.1]       *       * // The `_.property` iteratee shorthand. @@ -43963,7 +44101,7 @@ return jQuery;          ) + 1;        }        if (value !== value) { -        return indexOfNaN(array, index, true); +        return indexOfNaN(array, index - 1, true);        }        while (index--) {          if (array[index] === value) { @@ -43974,8 +44112,8 @@ return jQuery;      }      /** -     * Gets the nth element of `array`. If `n` is negative, the nth element -     * from the end is returned. +     * Gets the element at index `n` of `array`. If `n` is negative, the nth +     * element from the end is returned.       *       * @static       * @memberOf _ @@ -44015,11 +44153,11 @@ return jQuery;       * @returns {Array} Returns `array`.       * @example       * -     * var array = [1, 2, 3, 1, 2, 3]; +     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];       * -     * _.pull(array, 2, 3); +     * _.pull(array, 'a', 'c');       * console.log(array); -     * // => [1, 1] +     * // => ['b', 'b']       */      var pull = rest(pullAll); @@ -44037,11 +44175,11 @@ return jQuery;       * @returns {Array} Returns `array`.       * @example       * -     * var array = [1, 2, 3, 1, 2, 3]; +     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];       * -     * _.pullAll(array, [2, 3]); +     * _.pullAll(array, ['a', 'c']);       * console.log(array); -     * // => [1, 1] +     * // => ['b', 'b']       */      function pullAll(array, values) {        return (array && array.length && values && values.length) @@ -44123,14 +44261,14 @@ return jQuery;       * @returns {Array} Returns the new array of removed elements.       * @example       * -     * var array = [5, 10, 15, 20]; -     * var evens = _.pullAt(array, 1, 3); +     * var array = ['a', 'b', 'c', 'd']; +     * var pulled = _.pullAt(array, [1, 3]);       *       * console.log(array); -     * // => [5, 15] +     * // => ['a', 'c']       * -     * console.log(evens); -     * // => [10, 20] +     * console.log(pulled); +     * // => ['b', 'd']       */      var pullAt = rest(function(array, indexes) {        indexes = baseFlatten(indexes, 1); @@ -44270,9 +44408,6 @@ return jQuery;       *       * _.sortedIndex([30, 50], 40);       * // => 1 -     * -     * _.sortedIndex([4, 5], 4); -     * // => 0       */      function sortedIndex(array, value) {        return baseSortedIndex(array, value); @@ -44295,13 +44430,13 @@ return jQuery;       *  into `array`.       * @example       * -     * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 }; +     * var objects = [{ 'x': 4 }, { 'x': 5 }];       * -     * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); -     * // => 1 +     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); +     * // => 0       *       * // The `_.property` iteratee shorthand. -     * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); +     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');       * // => 0       */      function sortedIndexBy(array, value, iteratee) { @@ -44321,8 +44456,8 @@ return jQuery;       * @returns {number} Returns the index of the matched value, else `-1`.       * @example       * -     * _.sortedIndexOf([1, 1, 2, 2], 2); -     * // => 2 +     * _.sortedIndexOf([4, 5, 5, 5, 6], 5); +     * // => 1       */      function sortedIndexOf(array, value) {        var length = array ? array.length : 0; @@ -44350,8 +44485,8 @@ return jQuery;       *  into `array`.       * @example       * -     * _.sortedLastIndex([4, 5], 4); -     * // => 1 +     * _.sortedLastIndex([4, 5, 5, 5, 6], 5); +     * // => 4       */      function sortedLastIndex(array, value) {        return baseSortedIndex(array, value, true); @@ -44374,8 +44509,13 @@ return jQuery;       *  into `array`.       * @example       * +     * var objects = [{ 'x': 4 }, { 'x': 5 }]; +     * +     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); +     * // => 1 +     *       * // The `_.property` iteratee shorthand. -     * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); +     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');       * // => 1       */      function sortedLastIndexBy(array, value, iteratee) { @@ -44395,7 +44535,7 @@ return jQuery;       * @returns {number} Returns the index of the matched value, else `-1`.       * @example       * -     * _.sortedLastIndexOf([1, 1, 2, 2], 2); +     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);       * // => 3       */      function sortedLastIndexOf(array, value) { @@ -44635,8 +44775,8 @@ return jQuery;       * @returns {Array} Returns the new array of combined values.       * @example       * -     * _.union([2, 1], [4, 2], [1, 2]); -     * // => [2, 1, 4] +     * _.union([2], [1, 2]); +     * // => [2, 1]       */      var union = rest(function(arrays) {        return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); @@ -44658,8 +44798,8 @@ return jQuery;       * @returns {Array} Returns the new array of combined values.       * @example       * -     * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor); -     * // => [2.1, 1.2, 4.3] +     * _.unionBy([2.1], [1.2, 2.3], Math.floor); +     * // => [2.1, 1.2]       *       * // The `_.property` iteratee shorthand.       * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); @@ -44766,7 +44906,7 @@ return jQuery;       * @returns {Array} Returns the new duplicate free array.       * @example       * -     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }]; +     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];       *       * _.uniqWith(objects, _.isEqual);       * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] @@ -44855,13 +44995,13 @@ return jQuery;       * @memberOf _       * @since 0.1.0       * @category Array -     * @param {Array} array The array to filter. +     * @param {Array} array The array to inspect.       * @param {...*} [values] The values to exclude.       * @returns {Array} Returns the new array of filtered values.       * @see _.difference, _.xor       * @example       * -     * _.without([1, 2, 1, 3], 1, 2); +     * _.without([2, 1, 2, 3], 1, 2);       * // => [3]       */      var without = rest(function(array, values) { @@ -44881,12 +45021,12 @@ return jQuery;       * @since 2.4.0       * @category Array       * @param {...Array} [arrays] The arrays to inspect. -     * @returns {Array} Returns the new array of values. +     * @returns {Array} Returns the new array of filtered values.       * @see _.difference, _.without       * @example       * -     * _.xor([2, 1], [4, 2]); -     * // => [1, 4] +     * _.xor([2, 1], [2, 3]); +     * // => [1, 3]       */      var xor = rest(function(arrays) {        return baseXor(arrayFilter(arrays, isArrayLikeObject)); @@ -44905,11 +45045,11 @@ return jQuery;       * @param {...Array} [arrays] The arrays to inspect.       * @param {Array|Function|Object|string} [iteratee=_.identity]       *  The iteratee invoked per element. -     * @returns {Array} Returns the new array of values. +     * @returns {Array} Returns the new array of filtered values.       * @example       * -     * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); -     * // => [1.2, 4.3] +     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); +     * // => [1.2, 3.4]       *       * // The `_.property` iteratee shorthand.       * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); @@ -44934,7 +45074,7 @@ return jQuery;       * @category Array       * @param {...Array} [arrays] The arrays to inspect.       * @param {Function} [comparator] The comparator invoked per element. -     * @returns {Array} Returns the new array of values. +     * @returns {Array} Returns the new array of filtered values.       * @example       *       * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; @@ -45142,9 +45282,6 @@ return jQuery;       *       * _(object).at(['a[0].b.c', 'a[1]']).value();       * // => [3, 4] -     * -     * _(['a', 'b', 'c']).at(0, 2).value(); -     * // => ['a', 'c']       */      var wrapperAt = rest(function(paths) {        paths = baseFlatten(paths, 1); @@ -45407,6 +45544,7 @@ return jQuery;       * _.countBy([6.1, 4.2, 6.3], Math.floor);       * // => { '4': 1, '6': 2 }       * +     * // The `_.property` iteratee shorthand.       * _.countBy(['one', 'two', 'three'], 'length');       * // => { '3': 2, '5': 1 }       */ @@ -45512,6 +45650,7 @@ return jQuery;       * @param {Array|Object} collection The collection to search.       * @param {Array|Function|Object|string} [predicate=_.identity]       *  The function invoked per iteration. +     * @param {number} [fromIndex=0] The index to search from.       * @returns {*} Returns the matched element, else `undefined`.       * @example       * @@ -45536,14 +45675,7 @@ return jQuery;       * _.find(users, 'active');       * // => object for 'barney'       */ -    function find(collection, predicate) { -      predicate = getIteratee(predicate, 3); -      if (isArray(collection)) { -        var index = baseFindIndex(collection, predicate); -        return index > -1 ? collection[index] : undefined; -      } -      return baseFind(collection, predicate, baseEach); -    } +    var find = createFind(findIndex);      /**       * This method is like `_.find` except that it iterates over elements of @@ -45556,6 +45688,7 @@ return jQuery;       * @param {Array|Object} collection The collection to search.       * @param {Array|Function|Object|string} [predicate=_.identity]       *  The function invoked per iteration. +     * @param {number} [fromIndex=collection.length-1] The index to search from.       * @returns {*} Returns the matched element, else `undefined`.       * @example       * @@ -45564,14 +45697,7 @@ return jQuery;       * });       * // => 3       */ -    function findLast(collection, predicate) { -      predicate = getIteratee(predicate, 3); -      if (isArray(collection)) { -        var index = baseFindIndex(collection, predicate, true); -        return index > -1 ? collection[index] : undefined; -      } -      return baseFind(collection, predicate, baseEachRight); -    } +    var findLast = createFind(findLastIndex);      /**       * Creates a flattened array of values by running each element in `collection` @@ -45682,9 +45808,8 @@ return jQuery;       * // => Logs 'a' then 'b' (iteration order is not guaranteed).       */      function forEach(collection, iteratee) { -      return (typeof iteratee == 'function' && isArray(collection)) -        ? arrayEach(collection, iteratee) -        : baseEach(collection, getIteratee(iteratee)); +      var func = isArray(collection) ? arrayEach : baseEach; +      return func(collection, getIteratee(iteratee, 3));      }      /** @@ -45708,9 +45833,8 @@ return jQuery;       * // => Logs `2` then `1`.       */      function forEachRight(collection, iteratee) { -      return (typeof iteratee == 'function' && isArray(collection)) -        ? arrayEachRight(collection, iteratee) -        : baseEachRight(collection, getIteratee(iteratee)); +      var func = isArray(collection) ? arrayEachRight : baseEachRight; +      return func(collection, getIteratee(iteratee, 3));      }      /** @@ -46330,7 +46454,6 @@ return jQuery;       * @static       * @memberOf _       * @since 2.4.0 -     * @type {Function}       * @category Date       * @returns {number} Returns the timestamp.       * @example @@ -46338,9 +46461,11 @@ return jQuery;       * _.defer(function(stamp) {       *   console.log(_.now() - stamp);       * }, _.now()); -     * // => Logs the number of milliseconds it took for the deferred function to be invoked. +     * // => Logs the number of milliseconds it took for the deferred invocation.       */ -    var now = Date.now; +    function now() { +      return Date.now(); +    }      /*------------------------------------------------------------------------*/ @@ -46391,7 +46516,7 @@ return jQuery;       * @param {Function} func The function to cap arguments for.       * @param {number} [n=func.length] The arity cap.       * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new capped function.       * @example       *       * _.map(['6', '8', '10'], _.ary(parseInt, 1)); @@ -46444,7 +46569,7 @@ return jQuery;       * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,       * may be used as a placeholder for partially applied arguments.       * -     * **Note:** Unlike native `Function#bind` this method doesn't set the "length" +     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"       * property of bound functions.       *       * @static @@ -46475,7 +46600,7 @@ return jQuery;      var bind = rest(function(func, thisArg, partials) {        var bitmask = BIND_FLAG;        if (partials.length) { -        var holders = replaceHolders(partials, getPlaceholder(bind)); +        var holders = replaceHolders(partials, getHolder(bind));          bitmask |= PARTIAL_FLAG;        }        return createWrapper(func, bitmask, thisArg, partials, holders); @@ -46529,7 +46654,7 @@ return jQuery;      var bindKey = rest(function(object, key, partials) {        var bitmask = BIND_FLAG | BIND_KEY_FLAG;        if (partials.length) { -        var holders = replaceHolders(partials, getPlaceholder(bindKey)); +        var holders = replaceHolders(partials, getHolder(bindKey));          bitmask |= PARTIAL_FLAG;        }        return createWrapper(key, bitmask, object, partials, holders); @@ -46684,7 +46809,7 @@ return jQuery;            maxWait,            result,            timerId, -          lastCallTime = 0, +          lastCallTime,            lastInvokeTime = 0,            leading = false,            maxing = false, @@ -46735,7 +46860,7 @@ return jQuery;          // Either this is the first call, activity has stopped and we're at the          // trailing edge, the system time has gone backwards and we're treating          // it as the trailing edge, or we've hit the `maxWait` limit. -        return (!lastCallTime || (timeSinceLastCall >= wait) || +        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||            (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));        } @@ -46749,7 +46874,6 @@ return jQuery;        }        function trailingEdge(time) { -        clearTimeout(timerId);          timerId = undefined;          // Only invoke if we have `lastArgs` which means `func` has been @@ -46762,11 +46886,8 @@ return jQuery;        }        function cancel() { -        if (timerId !== undefined) { -          clearTimeout(timerId); -        } -        lastCallTime = lastInvokeTime = 0; -        lastArgs = lastThis = timerId = undefined; +        lastInvokeTime = 0; +        lastArgs = lastCallTime = lastThis = timerId = undefined;        }        function flush() { @@ -46787,7 +46908,6 @@ return jQuery;            }            if (maxing) {              // Handle invocations in a tight loop. -            clearTimeout(timerId);              timerId = setTimeout(timerExpired, wait);              return invokeFunc(lastCallTime);            } @@ -46855,7 +46975,7 @@ return jQuery;       * @since 4.0.0       * @category Function       * @param {Function} func The function to flip arguments for. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new flipped function.       * @example       *       * var flipped = _.flip(function() { @@ -46888,7 +47008,7 @@ return jQuery;       * @category Function       * @param {Function} func The function to have its output memoized.       * @param {Function} [resolver] The function to resolve the cache key. -     * @returns {Function} Returns the new memoizing function. +     * @returns {Function} Returns the new memoized function.       * @example       *       * var object = { 'a': 1, 'b': 2 }; @@ -46946,7 +47066,7 @@ return jQuery;       * @since 3.0.0       * @category Function       * @param {Function} predicate The predicate to negate. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new negated function.       * @example       *       * function isEven(n) { @@ -47011,7 +47131,7 @@ return jQuery;       *       * var func = _.overArgs(function(x, y) {       *   return [x, y]; -     * }, square, doubled); +     * }, [square, doubled]);       *       * func(9, 3);       * // => [81, 6] @@ -47070,7 +47190,7 @@ return jQuery;       * // => 'hi fred'       */      var partial = rest(function(func, partials) { -      var holders = replaceHolders(partials, getPlaceholder(partial)); +      var holders = replaceHolders(partials, getHolder(partial));        return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);      }); @@ -47107,7 +47227,7 @@ return jQuery;       * // => 'hello fred'       */      var partialRight = rest(function(func, partials) { -      var holders = replaceHolders(partials, getPlaceholder(partialRight)); +      var holders = replaceHolders(partials, getHolder(partialRight));        return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);      }); @@ -47128,7 +47248,7 @@ return jQuery;       *       * var rearged = _.rearg(function(a, b, c) {       *   return [a, b, c]; -     * }, 2, 0, 1); +     * }, [2, 0, 1]);       *       * rearged('b', 'c', 'a')       * // => ['a', 'b', 'c'] @@ -47309,7 +47429,7 @@ return jQuery;       * @since 4.0.0       * @category Function       * @param {Function} func The function to cap arguments for. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new capped function.       * @example       *       * _.map(['6', '8', '10'], _.unary(parseInt)); @@ -47767,7 +47887,7 @@ return jQuery;       * _.isBuffer(new Uint8Array(2));       * // => false       */ -    var isBuffer = !Buffer ? constant(false) : function(value) { +    var isBuffer = !Buffer ? stubFalse : function(value) {        return value instanceof Buffer;      }; @@ -47985,14 +48105,14 @@ return jQuery;       * _.isFinite(3);       * // => true       * -     * _.isFinite(Number.MAX_VALUE); -     * // => true -     * -     * _.isFinite(3.14); +     * _.isFinite(Number.MIN_VALUE);       * // => true       *       * _.isFinite(Infinity);       * // => false +     * +     * _.isFinite('3'); +     * // => false       */      function isFinite(value) {        return typeof value == 'number' && nativeIsFinite(value); @@ -48267,7 +48387,15 @@ return jQuery;      }      /** -     * Checks if `value` is a native function. +     * Checks if `value` is a pristine native function. +     * +     * **Note:** This method can't reliably detect native functions in the +     * presence of the `core-js` package because `core-js` circumvents this kind +     * of detection. Despite multiple requests, the `core-js` maintainer has made +     * it clear: any attempt to fix the detection will be obstructed. As a result, +     * we're left with little choice but to throw an error. Unfortunately, this +     * also affects packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), +     * which rely on `core-js`.       *       * @static       * @memberOf _ @@ -48285,11 +48413,10 @@ return jQuery;       * // => false       */      function isNative(value) { -      if (!isObject(value)) { -        return false; +      if (isMaskable(value)) { +        throw new Error('This method is not supported with `core-js`. Try https://github.com/es-shims.');        } -      var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; -      return pattern.test(toSource(value)); +      return baseIsNative(value);      }      /** @@ -48714,9 +48841,44 @@ return jQuery;      }      /** +     * Converts `value` to a finite number. +     * +     * @static +     * @memberOf _ +     * @since 4.12.0 +     * @category Lang +     * @param {*} value The value to convert. +     * @returns {number} Returns the converted number. +     * @example +     * +     * _.toFinite(3.2); +     * // => 3.2 +     * +     * _.toFinite(Number.MIN_VALUE); +     * // => 5e-324 +     * +     * _.toFinite(Infinity); +     * // => 1.7976931348623157e+308 +     * +     * _.toFinite('3.2'); +     * // => 3.2 +     */ +    function toFinite(value) { +      if (!value) { +        return value === 0 ? value : 0; +      } +      value = toNumber(value); +      if (value === INFINITY || value === -INFINITY) { +        var sign = (value < 0 ? -1 : 1); +        return sign * MAX_INTEGER; +      } +      return value === value ? value : 0; +    } + +    /**       * Converts `value` to an integer.       * -     * **Note:** This function is loosely based on +     * **Note:** This method is loosely based on       * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).       *       * @static @@ -48727,7 +48889,7 @@ return jQuery;       * @returns {number} Returns the converted integer.       * @example       * -     * _.toInteger(3); +     * _.toInteger(3.2);       * // => 3       *       * _.toInteger(Number.MIN_VALUE); @@ -48736,20 +48898,14 @@ return jQuery;       * _.toInteger(Infinity);       * // => 1.7976931348623157e+308       * -     * _.toInteger('3'); +     * _.toInteger('3.2');       * // => 3       */      function toInteger(value) { -      if (!value) { -        return value === 0 ? value : 0; -      } -      value = toNumber(value); -      if (value === INFINITY || value === -INFINITY) { -        var sign = (value < 0 ? -1 : 1); -        return sign * MAX_INTEGER; -      } -      var remainder = value % 1; -      return value === value ? (remainder ? value - remainder : value) : 0; +      var result = toFinite(value), +          remainder = result % 1; + +      return result === result ? (remainder ? result - remainder : result) : 0;      }      /** @@ -48767,7 +48923,7 @@ return jQuery;       * @returns {number} Returns the converted integer.       * @example       * -     * _.toLength(3); +     * _.toLength(3.2);       * // => 3       *       * _.toLength(Number.MIN_VALUE); @@ -48776,7 +48932,7 @@ return jQuery;       * _.toLength(Infinity);       * // => 4294967295       * -     * _.toLength('3'); +     * _.toLength('3.2');       * // => 3       */      function toLength(value) { @@ -48794,8 +48950,8 @@ return jQuery;       * @returns {number} Returns the number.       * @example       * -     * _.toNumber(3); -     * // => 3 +     * _.toNumber(3.2); +     * // => 3.2       *       * _.toNumber(Number.MIN_VALUE);       * // => 5e-324 @@ -48803,8 +48959,8 @@ return jQuery;       * _.toNumber(Infinity);       * // => Infinity       * -     * _.toNumber('3'); -     * // => 3 +     * _.toNumber('3.2'); +     * // => 3.2       */      function toNumber(value) {        if (typeof value == 'number') { @@ -48867,7 +49023,7 @@ return jQuery;       * @returns {number} Returns the converted integer.       * @example       * -     * _.toSafeInteger(3); +     * _.toSafeInteger(3.2);       * // => 3       *       * _.toSafeInteger(Number.MIN_VALUE); @@ -48876,7 +49032,7 @@ return jQuery;       * _.toSafeInteger(Infinity);       * // => 9007199254740991       * -     * _.toSafeInteger('3'); +     * _.toSafeInteger('3.2');       * // => 3       */      function toSafeInteger(value) { @@ -49069,16 +49225,13 @@ return jQuery;       * @category Object       * @param {Object} object The object to iterate over.       * @param {...(string|string[])} [paths] The property paths of elements to pick. -     * @returns {Array} Returns the new array of picked elements. +     * @returns {Array} Returns the picked values.       * @example       *       * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };       *       * _.at(object, ['a[0].b.c', 'a[1]']);       * // => [3, 4] -     * -     * _.at(['a', 'b', 'c'], 0, 2); -     * // => ['a', 'c']       */      var at = rest(function(object, paths) {        return baseAt(object, baseFlatten(paths, 1)); @@ -49211,7 +49364,7 @@ return jQuery;       * // => 'barney'       */      function findKey(object, predicate) { -      return baseFind(object, getIteratee(predicate, 3), baseForOwn, true); +      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);      }      /** @@ -49251,7 +49404,7 @@ return jQuery;       * // => 'pebbles'       */      function findLastKey(object, predicate) { -      return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true); +      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);      }      /** @@ -49285,7 +49438,7 @@ return jQuery;      function forIn(object, iteratee) {        return object == null          ? object -        : baseFor(object, getIteratee(iteratee), keysIn); +        : baseFor(object, getIteratee(iteratee, 3), keysIn);      }      /** @@ -49317,7 +49470,7 @@ return jQuery;      function forInRight(object, iteratee) {        return object == null          ? object -        : baseForRight(object, getIteratee(iteratee), keysIn); +        : baseForRight(object, getIteratee(iteratee, 3), keysIn);      }      /** @@ -49349,7 +49502,7 @@ return jQuery;       * // => Logs 'a' then 'b' (iteration order is not guaranteed).       */      function forOwn(object, iteratee) { -      return object && baseForOwn(object, getIteratee(iteratee)); +      return object && baseForOwn(object, getIteratee(iteratee, 3));      }      /** @@ -49379,7 +49532,7 @@ return jQuery;       * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.       */      function forOwnRight(object, iteratee) { -      return object && baseForOwnRight(object, getIteratee(iteratee)); +      return object && baseForOwnRight(object, getIteratee(iteratee, 3));      }      /** @@ -49391,7 +49544,7 @@ return jQuery;       * @memberOf _       * @category Object       * @param {Object} object The object to inspect. -     * @returns {Array} Returns the new array of property names. +     * @returns {Array} Returns the function names.       * @see _.functionsIn       * @example       * @@ -49418,7 +49571,7 @@ return jQuery;       * @since 4.0.0       * @category Object       * @param {Object} object The object to inspect. -     * @returns {Array} Returns the new array of property names. +     * @returns {Array} Returns the function names.       * @see _.functions       * @example       * @@ -49771,7 +49924,7 @@ return jQuery;       * inherited enumerable string keyed properties of source objects into the       * destination object. Source properties that resolve to `undefined` are       * skipped if a destination value exists. Array and plain object properties -     * are merged recursively.Other objects and value types are overridden by +     * are merged recursively. Other objects and value types are overridden by       * assignment. Source objects are applied from left to right. Subsequent       * sources overwrite property assignments of previous sources.       * @@ -50056,7 +50209,8 @@ return jQuery;      /**       * Creates an array of own enumerable string keyed-value pairs for `object` -     * which can be consumed by `_.fromPairs`. +     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its +     * entries are returned.       *       * @static       * @memberOf _ @@ -50064,7 +50218,7 @@ return jQuery;       * @alias entries       * @category Object       * @param {Object} object The object to query. -     * @returns {Array} Returns the new array of key-value pairs. +     * @returns {Array} Returns the key-value pairs.       * @example       *       * function Foo() { @@ -50077,13 +50231,12 @@ return jQuery;       * _.toPairs(new Foo);       * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)       */ -    function toPairs(object) { -      return baseToPairs(object, keys(object)); -    } +    var toPairs = createToPairs(keys);      /**       * Creates an array of own and inherited enumerable string keyed-value pairs -     * for `object` which can be consumed by `_.fromPairs`. +     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map +     * or set, its entries are returned.       *       * @static       * @memberOf _ @@ -50091,7 +50244,7 @@ return jQuery;       * @alias entriesIn       * @category Object       * @param {Object} object The object to query. -     * @returns {Array} Returns the new array of key-value pairs. +     * @returns {Array} Returns the key-value pairs.       * @example       *       * function Foo() { @@ -50102,25 +50255,24 @@ return jQuery;       * Foo.prototype.c = 3;       *       * _.toPairsIn(new Foo); -     * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed) +     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)       */ -    function toPairsIn(object) { -      return baseToPairs(object, keysIn(object)); -    } +    var toPairsIn = createToPairs(keysIn);      /**       * An alternative to `_.reduce`; this method transforms `object` to a new       * `accumulator` object which is the result of running each of its own       * enumerable string keyed properties thru `iteratee`, with each invocation -     * potentially mutating the `accumulator` object. The iteratee is invoked -     * with four arguments: (accumulator, value, key, object). Iteratee functions -     * may exit iteration early by explicitly returning `false`. +     * potentially mutating the `accumulator` object. If `accumulator` is not +     * provided, a new object with the same `[[Prototype]]` will be used. The +     * iteratee is invoked with four arguments: (accumulator, value, key, object). +     * Iteratee functions may exit iteration early by explicitly returning `false`.       *       * @static       * @memberOf _       * @since 1.3.0       * @category Object -     * @param {Array|Object} object The object to iterate over. +     * @param {Object} object The object to iterate over.       * @param {Function} [iteratee=_.identity] The function invoked per iteration.       * @param {*} [accumulator] The custom accumulator value.       * @returns {*} Returns the accumulated value. @@ -50542,7 +50694,7 @@ return jQuery;       * @category String       * @param {string} [string=''] The string to search.       * @param {string} [target] The string to search for. -     * @param {number} [position=string.length] The position to search from. +     * @param {number} [position=string.length] The position to search up to.       * @returns {boolean} Returns `true` if `string` ends with `target`,       *  else `false`.       * @example @@ -50936,7 +51088,7 @@ return jQuery;       * @param {string} [string=''] The string to split.       * @param {RegExp|string} separator The separator pattern to split by.       * @param {number} [limit] The length to truncate results to. -     * @returns {Array} Returns the new array of string segments. +     * @returns {Array} Returns the string segments.       * @example       *       * _.split('a-b-c', '-', 2); @@ -51081,12 +51233,6 @@ return jQuery;       * compiled({ 'user': 'pebbles' });       * // => 'hello pebbles!'       * -     * // Use custom template delimiters. -     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; -     * var compiled = _.template('hello {{ user }}!'); -     * compiled({ 'user': 'mustache' }); -     * // => 'hello mustache!' -     *       * // Use backslashes to treat delimiters as plain text.       * var compiled = _.template('<%= "\\<%- value %\\>" %>');       * compiled({ 'value': 'ignored' }); @@ -51112,9 +51258,15 @@ return jQuery;       * //   return __p;       * // }       * +     * // Use custom template delimiters. +     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; +     * var compiled = _.template('hello {{ user }}!'); +     * compiled({ 'user': 'mustache' }); +     * // => 'hello mustache!' +     *       * // Use the `source` property to inline compiled templates for meaningful       * // line numbers in error messages and stack traces. -     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ +     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\       *   var JST = {\       *     "main": ' + _.template(mainText).source + '\       *   };\ @@ -51627,7 +51779,7 @@ return jQuery;       *   }       * };       * -     * _.bindAll(view, 'onClick'); +     * _.bindAll(view, ['onClick']);       * jQuery(element).on('click', view.onClick);       * // => Logs 'clicked docs' when clicked.       */ @@ -51650,7 +51802,7 @@ return jQuery;       * @since 4.0.0       * @category Util       * @param {Array} pairs The predicate-function pairs. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new composite function.       * @example       *       * var func = _.cond([ @@ -51700,7 +51852,7 @@ return jQuery;       * @since 4.0.0       * @category Util       * @param {Object} source The object of property predicates to conform to. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new spec function.       * @example       *       * var users = [ @@ -51708,7 +51860,7 @@ return jQuery;       *   { 'user': 'fred',   'age': 40 }       * ];       * -     * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) })); +     * _.filter(users, _.conforms({ 'age': function(n) { return n > 38; } }));       * // => [{ 'user': 'fred', 'age': 40 }]       */      function conforms(source) { @@ -51723,13 +51875,15 @@ return jQuery;       * @since 2.4.0       * @category Util       * @param {*} value The value to return from the new function. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new constant function.       * @example       * -     * var object = { 'user': 'fred' }; -     * var getter = _.constant(object); +     * var objects = _.times(2, _.constant({ 'a': 1 })); +     * +     * console.log(objects); +     * // => [{ 'a': 1 }, { 'a': 1 }]       * -     * getter() === object; +     * console.log(objects[0] === objects[1]);       * // => true       */      function constant(value) { @@ -51748,7 +51902,7 @@ return jQuery;       * @since 3.0.0       * @category Util       * @param {...(Function|Function[])} [funcs] Functions to invoke. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new composite function.       * @see _.flowRight       * @example       * @@ -51756,7 +51910,7 @@ return jQuery;       *   return n * n;       * }       * -     * var addSquare = _.flow(_.add, square); +     * var addSquare = _.flow([_.add, square]);       * addSquare(1, 2);       * // => 9       */ @@ -51771,7 +51925,7 @@ return jQuery;       * @memberOf _       * @category Util       * @param {...(Function|Function[])} [funcs] Functions to invoke. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new composite function.       * @see _.flow       * @example       * @@ -51779,7 +51933,7 @@ return jQuery;       *   return n * n;       * }       * -     * var addSquare = _.flowRight(square, _.add); +     * var addSquare = _.flowRight([square, _.add]);       * addSquare(1, 2);       * // => 9       */ @@ -51798,7 +51952,7 @@ return jQuery;       *       * var object = { 'user': 'fred' };       * -     * _.identity(object) === object; +     * console.log(_.identity(object) === object);       * // => true       */      function identity(value) { @@ -51864,7 +52018,7 @@ return jQuery;       * @since 3.0.0       * @category Util       * @param {Object} source The object of property values to match. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new spec function.       * @example       *       * var users = [ @@ -51892,7 +52046,7 @@ return jQuery;       * @category Util       * @param {Array|string} path The path of the property to get.       * @param {*} srcValue The value to match. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new spec function.       * @example       *       * var users = [ @@ -51917,7 +52071,7 @@ return jQuery;       * @category Util       * @param {Array|string} path The path of the method to invoke.       * @param {...*} [args] The arguments to invoke the method with. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new invoker function.       * @example       *       * var objects = [ @@ -51948,7 +52102,7 @@ return jQuery;       * @category Util       * @param {Object} object The object to query.       * @param {...*} [args] The arguments to invoke the method with. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new invoker function.       * @example       *       * var array = _.times(3, _.constant), @@ -52059,8 +52213,7 @@ return jQuery;      }      /** -     * A no-operation function that returns `undefined` regardless of the -     * arguments it receives. +     * A method that returns `undefined`.       *       * @static       * @memberOf _ @@ -52068,17 +52221,15 @@ return jQuery;       * @category Util       * @example       * -     * var object = { 'user': 'fred' }; -     * -     * _.noop(object) === undefined; -     * // => true +     * _.times(2, _.noop); +     * // => [undefined, undefined]       */      function noop() {        // No operation performed.      }      /** -     * Creates a function that returns its nth argument. If `n` is negative, +     * Creates a function that gets the argument at index `n`. If `n` is negative,       * the nth argument from the end is returned.       *       * @static @@ -52086,7 +52237,7 @@ return jQuery;       * @since 4.0.0       * @category Util       * @param {number} [n=0] The index of the argument to return. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new pass-thru function.       * @example       *       * var func = _.nthArg(1); @@ -52117,7 +52268,7 @@ return jQuery;       * @returns {Function} Returns the new function.       * @example       * -     * var func = _.over(Math.max, Math.min); +     * var func = _.over([Math.max, Math.min]);       *       * func(1, 2, 3, 4);       * // => [4, 1] @@ -52137,7 +52288,7 @@ return jQuery;       * @returns {Function} Returns the new function.       * @example       * -     * var func = _.overEvery(Boolean, isFinite); +     * var func = _.overEvery([Boolean, isFinite]);       *       * func('1');       * // => true @@ -52163,7 +52314,7 @@ return jQuery;       * @returns {Function} Returns the new function.       * @example       * -     * var func = _.overSome(Boolean, isFinite); +     * var func = _.overSome([Boolean, isFinite]);       *       * func('1');       * // => true @@ -52184,7 +52335,7 @@ return jQuery;       * @since 2.4.0       * @category Util       * @param {Array|string} path The path of the property to get. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new accessor function.       * @example       *       * var objects = [ @@ -52211,7 +52362,7 @@ return jQuery;       * @since 3.0.0       * @category Util       * @param {Object} object The object to query. -     * @returns {Function} Returns the new function. +     * @returns {Function} Returns the new accessor function.       * @example       *       * var array = [0, 1, 2], @@ -52245,7 +52396,7 @@ return jQuery;       * @param {number} [start=0] The start of the range.       * @param {number} end The end of the range.       * @param {number} [step=1] The value to increment or decrement by. -     * @returns {Array} Returns the new array of numbers. +     * @returns {Array} Returns the range of numbers.       * @see _.inRange, _.rangeRight       * @example       * @@ -52283,7 +52434,7 @@ return jQuery;       * @param {number} [start=0] The start of the range.       * @param {number} end The end of the range.       * @param {number} [step=1] The value to increment or decrement by. -     * @returns {Array} Returns the new array of numbers. +     * @returns {Array} Returns the range of numbers.       * @see _.inRange, _.range       * @example       * @@ -52311,6 +52462,101 @@ return jQuery;      var rangeRight = createRange(true);      /** +     * A method that returns a new empty array. +     * +     * @static +     * @memberOf _ +     * @since 4.13.0 +     * @category Util +     * @returns {Array} Returns the new empty array. +     * @example +     * +     * var arrays = _.times(2, _.stubArray); +     * +     * console.log(arrays); +     * // => [[], []] +     * +     * console.log(arrays[0] === arrays[1]); +     * // => false +     */ +    function stubArray() { +      return []; +    } + +    /** +     * A method that returns `false`. +     * +     * @static +     * @memberOf _ +     * @since 4.13.0 +     * @category Util +     * @returns {boolean} Returns `false`. +     * @example +     * +     * _.times(2, _.stubFalse); +     * // => [false, false] +     */ +    function stubFalse() { +      return false; +    } + +    /** +     * A method that returns a new empty object. +     * +     * @static +     * @memberOf _ +     * @since 4.13.0 +     * @category Util +     * @returns {Object} Returns the new empty object. +     * @example +     * +     * var objects = _.times(2, _.stubObject); +     * +     * console.log(objects); +     * // => [{}, {}] +     * +     * console.log(objects[0] === objects[1]); +     * // => false +     */ +    function stubObject() { +      return {}; +    } + +    /** +     * A method that returns an empty string. +     * +     * @static +     * @memberOf _ +     * @since 4.13.0 +     * @category Util +     * @returns {string} Returns the empty string. +     * @example +     * +     * _.times(2, _.stubString); +     * // => ['', ''] +     */ +    function stubString() { +      return ''; +    } + +    /** +     * A method that returns `true`. +     * +     * @static +     * @memberOf _ +     * @since 4.13.0 +     * @category Util +     * @returns {boolean} Returns `true`. +     * @example +     * +     * _.times(2, _.stubTrue); +     * // => [true, true] +     */ +    function stubTrue() { +      return true; +    } + +    /**       * Invokes the iteratee `n` times, returning an array of the results of       * each invocation. The iteratee is invoked with one argument; (index).       * @@ -52326,8 +52572,8 @@ return jQuery;       * _.times(3, String);       * // => ['0', '1', '2']       * -     *  _.times(4, _.constant(true)); -     * // => [true, true, true, true] +     *  _.times(4, _.constant(0)); +     * // => [0, 0, 0, 0]       */      function times(n, iteratee) {        n = toInteger(n); @@ -52363,15 +52609,6 @@ return jQuery;       *       * _.toPath('a[0].b.c');       * // => ['a', '0', 'b', 'c'] -     * -     * var path = ['a', 'b', 'c'], -     *     newPath = _.toPath(path); -     * -     * console.log(newPath); -     * // => ['a', 'b', 'c'] -     * -     * console.log(path === newPath); -     * // => false       */      function toPath(value) {        if (isArray(value)) { @@ -53010,6 +53247,11 @@ return jQuery;      lodash.meanBy = meanBy;      lodash.min = min;      lodash.minBy = minBy; +    lodash.stubArray = stubArray; +    lodash.stubFalse = stubFalse; +    lodash.stubObject = stubObject; +    lodash.stubString = stubString; +    lodash.stubTrue = stubTrue;      lodash.multiply = multiply;      lodash.nth = nth;      lodash.noConflict = noConflict; @@ -53044,6 +53286,7 @@ return jQuery;      lodash.sumBy = sumBy;      lodash.template = template;      lodash.times = times; +    lodash.toFinite = toFinite;      lodash.toInteger = toInteger;      lodash.toLength = toLength;      lodash.toLower = toLower; @@ -53315,7 +53558,7 @@ return jQuery;    // also prevents errors in cases where Lodash is loaded by a script tag in the    // presence of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch    // for more details. Use `_.noConflict` to remove Lodash from the global object. -  (freeWindow || freeSelf || {})._ = _; +  (freeSelf || {})._ = _;    // Some AMD build optimizers like r.js check for condition patterns like the following:    if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { @@ -53326,11 +53569,9 @@ return jQuery;      });    }    // Check for `exports` after `define` in case a build optimizer adds an `exports` object. -  else if (freeExports && freeModule) { +  else if (freeModule) {      // Export for Node.js. -    if (moduleExports) { -      (freeModule.exports = _)._ = _; -    } +    (freeModule.exports = _)._ = _;      // Export for CommonJS support.      freeExports._ = _;    } diff --git a/web/src/js/components/flowtable.js b/web/src/js/components/flowtable.js index d621387c..642ded17 100644 --- a/web/src/js/components/flowtable.js +++ b/web/src/js/components/flowtable.js @@ -46,61 +46,59 @@ const FlowRowContainer = connect(      })  )(FlowRow) -class FlowTableHead extends React.Component { +function FlowTableHead({setSort, columns, sort}) { + +        //const hasSort = Column.sortKeyFun; + +        // let sortDesc = this.props.sort.sortDesc; +        // +        // if (Column === this.props.sort.sortColumn) { +        //     sortDesc = !sortDesc; +        //     this.props.setSort(sortColumn, sortDesc); +        // } else { +        //     this.props.setSort({sortColumn: hasSort && Column, sortDesc: false}); +        // } +        // +        // let sortKeyFun = Column.sortKeyFun; +        // if (sortDesc) { +        //     sortKeyFun = hasSort && function () { +        //             const k = Column.sortKeyFun.apply(this, arguments); +        //             if (_.isString(k)) { +        //                 return reverseString("" + k); +        //             } +        //             return -k; +        //         }; +        // } +        //this.props.setSortKeyFun(sortKeyFun); + +        const sortColumn = sort.sortColumn; +        const sortType = sort.sortDesc ? "sort-desc" : "sort-asc"; -    static propTypes = { -        setSortKeyFun: React.PropTypes.func.isRequired, -        columns: React.PropTypes.array.isRequired, -    }; - -    constructor(props, context) { -        super(props, context); -        this.state = {sortColumn: undefined, sortDesc: false}; -    } - -    onClick(Column) { -        const hasSort = Column.sortKeyFun; - -        let sortDesc = this.state.sortDesc; - -        if (Column === this.state.sortColumn) { -            sortDesc = !sortDesc; -            this.setState({sortDesc}); -        } else { -            this.setState({sortColumn: hasSort && Column, sortDesc: false}); -        } - -        let sortKeyFun = Column.sortKeyFun; -        if (sortDesc) { -            sortKeyFun = hasSort && function () { -                    const k = Column.sortKeyFun.apply(this, arguments); -                    if (_.isString(k)) { -                        return reverseString("" + k); -                    } -                    return -k; -                }; -        } - -        this.props.setSortKeyFun(sortKeyFun); -    } - -    render() { -        const sortColumn = this.state.sortColumn; -        const sortType = this.state.sortDesc ? "sort-desc" : "sort-asc";          return (              <tr> -                {this.props.columns.map(Column => ( +                {columns.map(Column => (                      <Column.Title                          key={Column.name} -                        onClick={() => this.onClick(Column)} -                        className={sortColumn === Column ? sortType : undefined} +                        onClick={() => setSort({sortColumn: Column.name, sortDesc: Column.name != sort.sortColumn ? false : !sort.sortDesc})} +                        className={sortColumn === Column.name ? sortType : undefined}                      />                  ))}              </tr>          ); -    }  } +FlowTableHead.propTypes = { +        setSort: React.PropTypes.func.isRequired, +        sort: React.PropTypes.object.isRequired, +        columns: React.PropTypes.array.isRequired +}; + +const FlowTableHeadContainer = connect( +    (state, ownProps) => ({ +        sort: state.flows.sort +    }) +)(FlowTableHead) +  class FlowTable extends React.Component {      static propTypes = { @@ -186,9 +184,10 @@ class FlowTable extends React.Component {              <div className="flow-table" onScroll={this.onViewportUpdate}>                  <table>                      <thead ref="head" style={{ transform }}> -                    <FlowTableHead +                    <FlowTableHeadContainer                          columns={flowtable_columns}                          setSortKeyFun={this.props.setSortKeyFun} +                        setSort={this.props.setSort}                      />                      </thead>                      <tbody> diff --git a/web/src/js/components/mainview.js b/web/src/js/components/mainview.js index 22895991..99cdeb3c 100644 --- a/web/src/js/components/mainview.js +++ b/web/src/js/components/mainview.js @@ -7,7 +7,7 @@ import {Splitter} from "./common.js"  import FlowTable from "./flowtable.js";  import FlowView from "./flowview/index.js";  import {connect} from 'react-redux' -import {selectFlow, setFilter, setHighlight} from "../ducks/flows"; +import {selectFlow, setFilter, setHighlight, setSort} from "../ducks/flows";  var MainView = React.createClass({ @@ -161,7 +161,8 @@ var MainView = React.createClass({              <div className="main-view">                  <FlowTable ref="flowTable"                      selectFlow={this.selectFlow} -                    setSortKeyFun={this.setSortKeyFun} +                    setSortKeyFun={(f) => console.log("asdf")} +                    setSort={this.props.setSort}                      selected={this.props.selectedFlow} />                  {details}              </div> @@ -173,12 +174,14 @@ const MainViewContainer = connect(      state => ({          flows: state.flows.view,          filter: state.flows.filter, +        sort: state.flows.sort,          highlight: state.flows.highlight,          selectedFlow: state.flows.all.byId[state.flows.selected[0]]      }),      dispatch => ({          selectFlow: flowId => dispatch(selectFlow(flowId)),          setFilter: filter => dispatch(setFilter(filter)), +        setSort: (sort) => dispatch(setSort(sort)),          setHighlight: highlight => dispatch(setHighlight(highlight))      }),      undefined, diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js index fdbc42ee..bde53179 100644 --- a/web/src/js/ducks/flows.js +++ b/web/src/js/ducks/flows.js @@ -5,6 +5,7 @@ import {updateViewFilter, updateViewList} from "./utils/view"  export const UPDATE_FLOWS = "UPDATE_FLOWS"  export const SET_FILTER = "SET_FLOW_FILTER"  export const SET_HIGHLIGHT = "SET_FLOW_HIGHLIGHT" +export const SET_SORT = "SET_FLOW_SORT"  export const SELECT_FLOW = "SELECT_FLOW"  const { @@ -20,6 +21,7 @@ const defaultState = {      view: [],      filter: undefined,      highlight: undefined, +    sort: {sortColumn: undefined, sortDesc: false},  }  function makeFilterFn(filter) { @@ -46,6 +48,11 @@ export default function reducer(state = defaultState, action) {                  ...state,                  highlight: action.highlight              } +        case SET_SORT: +            return { +                ...state, +                sort: action.sort +            }          case SELECT_FLOW:              return {                  ...state, @@ -69,6 +76,12 @@ export function setHighlight(highlight) {          highlight      }  } +export  function setSort(sort){ +    return { +        type: SET_SORT, +        sort +    } +}  export function selectFlow(flowId) {      return {          type: SELECT_FLOW, | 
