vendor: 3,552 bytes, lines 1-78
1(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.crossfilter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 2module.exports = require("./src/crossfilter").crossfilter; 3 4},{"./src/crossfilter":6}],2:[function(require,module,exports){ 5(function (global){ 6/** 7 * lodash (Custom Build) <https://lodash.com/> 8 * Build: `lodash modularize exports="npm" -o ./` 9 * Copyright jQuery Foundation and other contributors <https://jquery.org/> 10 * Released under MIT license <https://lodash.com/license> 11 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> 12 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 13 */ 14 15/** Used as the `TypeError` message for "Functions" methods. */ 16var FUNC_ERROR_TEXT = 'Expected a function'; 17 18/** Used to stand-in for `undefined` hash values. */ 19var HASH_UNDEFINED = '__lodash_hash_undefined__'; 20 21/** Used as references for various `Number` constants. */ 22var INFINITY = 1 / 0; 23 24/** `Object#toString` result references. */ 25var funcTag = '[object Function]', 26 genTag = '[object GeneratorFunction]', 27 symbolTag = '[object Symbol]'; 28 29/** Used to match property names within property paths. */ 30var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, 31 reIsPlainProp = /^\w*$/, 32 reLeadingDot = /^\./, 33 rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; 34 35/** 36 * Used to match `RegExp` 37 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). 38 */ 39var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; 40 41/** Used to match backslashes in property paths. */ 42var reEscapeChar = /\\(\\)?/g; 43 44/** Used to detect host constructors (Safari). */ 45var reIsHostCtor = /^\[object .+?Constructor\]$/; 46 47/** Detect free variable `global` from Node.js. */ 48var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; 49 50/** Detect free variable `self`. */ 51var freeSelf = typeof self == 'object' && self && self.Object === Object && self; 52 53/** Used as a reference to the global object. */ 54var root = freeGlobal || freeSelf || Function('return this')(); 55 56/** 57 * Gets the value at `key` of `object`. 58 * 59 * @private 60 * @param {Object} [object] The object to query. 61 * @param {string} key The key of the property to get. 62 * @returns {*} Returns the property value. 63 */ 64function getValue(object, key) { 65 return object == null ? undefined : object[key]; 66} 67 68/** 69 * Checks if `value` is a host object in IE < 9. 70 * 71 * @private 72 * @param {*} value The value to check. 73 * @returns {boolean} Returns `true` if `value` is a host object, else `false`. 74 */ 75function isHostObject(value) { 76 // Many host objects are `Object` objects that can coerce to strings 77 // despite having improperly defined `toString` methods. 78 var result = false;
vendor: 4,788 bytes, lines 79-273
79 if (value != null && typeof value.toString != 'function') { 80 try { 81 result = !!(value + ''); 82 } catch (e) {} 83 } 84 return result; 85} 86 87/** Used for built-in method references. */ 88var arrayProto = Array.prototype, 89 funcProto = Function.prototype, 90 objectProto = Object.prototype; 91 92/** Used to detect overreaching core-js shims. */ 93var coreJsData = root['__core-js_shared__']; 94 95/** Used to detect methods masquerading as native. */ 96var maskSrcKey = (function() { 97 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); 98 return uid ? ('Symbol(src)_1.' + uid) : ''; 99}()); 100 101/** Used to resolve the decompiled source of functions. */ 102var funcToString = funcProto.toString; 103 104/** Used to check objects for own properties. */ 105var hasOwnProperty = objectProto.hasOwnProperty; 106 107/** 108 * Used to resolve the 109 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 110 * of values. 111 */ 112var objectToString = objectProto.toString; 113 114/** Used to detect if a method is native. */ 115var reIsNative = RegExp('^' + 116 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') 117 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' 118); 119 120/** Built-in value references. */ 121var Symbol = root.Symbol, 122 splice = arrayProto.splice; 123 124/* Built-in method references that are verified to be native. */ 125var Map = getNative(root, 'Map'), 126 nativeCreate = getNative(Object, 'create'); 127 128/** Used to convert symbols to primitives and strings. */ 129var symbolProto = Symbol ? Symbol.prototype : undefined, 130 symbolToString = symbolProto ? symbolProto.toString : undefined; 131 132/** 133 * Creates a hash object. 134 * 135 * @private 136 * @constructor 137 * @param {Array} [entries] The key-value pairs to cache. 138 */ 139function Hash(entries) { 140 var index = -1, 141 length = entries ? entries.length : 0; 142 143 this.clear(); 144 while (++index < length) { 145 var entry = entries[index]; 146 this.set(entry[0], entry[1]); 147 } 148} 149 150/** 151 * Removes all key-value entries from the hash. 152 * 153 * @private 154 * @name clear 155 * @memberOf Hash 156 */ 157function hashClear() { 158 this.__data__ = nativeCreate ? nativeCreate(null) : {}; 159} 160 161/** 162 * Removes `key` and its value from the hash. 163 * 164 * @private 165 * @name delete 166 * @memberOf Hash 167 * @param {Object} hash The hash to modify. 168 * @param {string} key The key of the value to remove. 169 * @returns {boolean} Returns `true` if the entry was removed, else `false`. 170 */ 171function hashDelete(key) { 172 return this.has(key) && delete this.__data__[key]; 173} 174 175/** 176 * Gets the hash value for `key`. 177 * 178 * @private 179 * @name get 180 * @memberOf Hash 181 * @param {string} key The key of the value to get. 182 * @returns {*} Returns the entry value. 183 */ 184function hashGet(key) { 185 var data = this.__data__; 186 if (nativeCreate) { 187 var result = data[key]; 188 return result === HASH_UNDEFINED ? undefined : result; 189 } 190 return hasOwnProperty.call(data, key) ? data[key] : undefined; 191} 192 193/** 194 * Checks if a hash value for `key` exists. 195 * 196 * @private 197 * @name has 198 * @memberOf Hash 199 * @param {string} key The key of the entry to check. 200 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. 201 */ 202function hashHas(key) { 203 var data = this.__data__; 204 return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); 205} 206 207/** 208 * Sets the hash `key` to `value`. 209 * 210 * @private 211 * @name set 212 * @memberOf Hash 213 * @param {string} key The key of the value to set. 214 * @param {*} value The value to set. 215 * @returns {Object} Returns the hash instance. 216 */ 217function hashSet(key, value) { 218 var data = this.__data__; 219 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; 220 return this; 221} 222 223// Add methods to `Hash`. 224Hash.prototype.clear = hashClear; 225Hash.prototype['delete'] = hashDelete; 226Hash.prototype.get = hashGet; 227Hash.prototype.has = hashHas; 228Hash.prototype.set = hashSet; 229 230/** 231 * Creates an list cache object. 232 * 233 * @private 234 * @constructor 235 * @param {Array} [entries] The key-value pairs to cache. 236 */ 237function ListCache(entries) { 238 var index = -1, 239 length = entries ? entries.length : 0; 240 241 this.clear(); 242 while (++index < length) { 243 var entry = entries[index]; 244 this.set(entry[0], entry[1]); 245 } 246} 247 248/** 249 * Removes all key-value entries from the list cache. 250 * 251 * @private 252 * @name clear 253 * @memberOf ListCache 254 */ 255function listCacheClear() { 256 this.__data__ = []; 257} 258 259/** 260 * Removes `key` and its value from the list cache. 261 * 262 * @private 263 * @name delete 264 * @memberOf ListCache 265 * @param {string} key The key of the value to remove. 266 * @returns {boolean} Returns `true` if the entry was removed, else `false`. 267 */ 268function listCacheDelete(key) { 269 var data = this.__data__, 270 index = assocIndexOf(data, key); 271 272 if (index < 0) { 273 return false;
vendor: 3,992 bytes, lines 274-451
274 } 275 var lastIndex = data.length - 1; 276 if (index == lastIndex) { 277 data.pop(); 278 } else { 279 splice.call(data, index, 1); 280 } 281 return true; 282} 283 284/** 285 * Gets the list cache value for `key`. 286 * 287 * @private 288 * @name get 289 * @memberOf ListCache 290 * @param {string} key The key of the value to get. 291 * @returns {*} Returns the entry value. 292 */ 293function listCacheGet(key) { 294 var data = this.__data__, 295 index = assocIndexOf(data, key); 296 297 return index < 0 ? undefined : data[index][1]; 298} 299 300/** 301 * Checks if a list cache value for `key` exists. 302 * 303 * @private 304 * @name has 305 * @memberOf ListCache 306 * @param {string} key The key of the entry to check. 307 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. 308 */ 309function listCacheHas(key) { 310 return assocIndexOf(this.__data__, key) > -1; 311} 312 313/** 314 * Sets the list cache `key` to `value`. 315 * 316 * @private 317 * @name set 318 * @memberOf ListCache 319 * @param {string} key The key of the value to set. 320 * @param {*} value The value to set. 321 * @returns {Object} Returns the list cache instance. 322 */ 323function listCacheSet(key, value) { 324 var data = this.__data__, 325 index = assocIndexOf(data, key); 326 327 if (index < 0) { 328 data.push([key, value]); 329 } else { 330 data[index][1] = value; 331 } 332 return this; 333} 334 335// Add methods to `ListCache`. 336ListCache.prototype.clear = listCacheClear; 337ListCache.prototype['delete'] = listCacheDelete; 338ListCache.prototype.get = listCacheGet; 339ListCache.prototype.has = listCacheHas; 340ListCache.prototype.set = listCacheSet; 341 342/** 343 * Creates a map cache object to store key-value pairs. 344 * 345 * @private 346 * @constructor 347 * @param {Array} [entries] The key-value pairs to cache. 348 */ 349function MapCache(entries) { 350 var index = -1, 351 length = entries ? entries.length : 0; 352 353 this.clear(); 354 while (++index < length) { 355 var entry = entries[index]; 356 this.set(entry[0], entry[1]); 357 } 358} 359 360/** 361 * Removes all key-value entries from the map. 362 * 363 * @private 364 * @name clear 365 * @memberOf MapCache 366 */ 367function mapCacheClear() { 368 this.__data__ = { 369 'hash': new Hash, 370 'map': new (Map || ListCache), 371 'string': new Hash 372 }; 373} 374 375/** 376 * Removes `key` and its value from the map. 377 * 378 * @private 379 * @name delete 380 * @memberOf MapCache 381 * @param {string} key The key of the value to remove. 382 * @returns {boolean} Returns `true` if the entry was removed, else `false`. 383 */ 384function mapCacheDelete(key) { 385 return getMapData(this, key)['delete'](key); 386} 387 388/** 389 * Gets the map value for `key`. 390 * 391 * @private 392 * @name get 393 * @memberOf MapCache 394 * @param {string} key The key of the value to get. 395 * @returns {*} Returns the entry value. 396 */ 397function mapCacheGet(key) { 398 return getMapData(this, key).get(key); 399} 400 401/** 402 * Checks if a map value for `key` exists. 403 * 404 * @private 405 * @name has 406 * @memberOf MapCache 407 * @param {string} key The key of the entry to check. 408 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. 409 */ 410function mapCacheHas(key) { 411 return getMapData(this, key).has(key); 412} 413 414/** 415 * Sets the map `key` to `value`. 416 * 417 * @private 418 * @name set 419 * @memberOf MapCache 420 * @param {string} key The key of the value to set. 421 * @param {*} value The value to set. 422 * @returns {Object} Returns the map cache instance. 423 */ 424function mapCacheSet(key, value) { 425 getMapData(this, key).set(key, value); 426 return this; 427} 428 429// Add methods to `MapCache`. 430MapCache.prototype.clear = mapCacheClear; 431MapCache.prototype['delete'] = mapCacheDelete; 432MapCache.prototype.get = mapCacheGet; 433MapCache.prototype.has = mapCacheHas; 434MapCache.prototype.set = mapCacheSet; 435 436/** 437 * Gets the index at which the `key` is found in `array` of key-value pairs. 438 * 439 * @private 440 * @param {Array} array The array to inspect. 441 * @param {*} key The key to search for. 442 * @returns {number} Returns the index of the matched value, else `-1`. 443 */ 444function assocIndexOf(array, key) { 445 var length = array.length; 446 while (length--) { 447 if (eq(array[length][0], key)) { 448 return length; 449 } 450 } 451 return -1
vendor: 10,700 bytes, lines 451-887
451; 452} 453 454/** 455 * The base implementation of `_.isNative` without bad shim checks. 456 * 457 * @private 458 * @param {*} value The value to check. 459 * @returns {boolean} Returns `true` if `value` is a native function, 460 * else `false`. 461 */ 462function baseIsNative(value) { 463 if (!isObject(value) || isMasked(value)) { 464 return false; 465 } 466 var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; 467 return pattern.test(toSource(value)); 468} 469 470/** 471 * The base implementation of `_.toString` which doesn't convert nullish 472 * values to empty strings. 473 * 474 * @private 475 * @param {*} value The value to process. 476 * @returns {string} Returns the string. 477 */ 478function baseToString(value) { 479 // Exit early for strings to avoid a performance hit in some environments. 480 if (typeof value == 'string') { 481 return value; 482 } 483 if (isSymbol(value)) { 484 return symbolToString ? symbolToString.call(value) : ''; 485 } 486 var result = (value + ''); 487 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; 488} 489 490/** 491 * Casts `value` to a path array if it's not one. 492 * 493 * @private 494 * @param {*} value The value to inspect. 495 * @returns {Array} Returns the cast property path array. 496 */ 497function castPath(value) { 498 return isArray(value) ? value : stringToPath(value); 499} 500 501/** 502 * Gets the data for `map`. 503 * 504 * @private 505 * @param {Object} map The map to query. 506 * @param {string} key The reference key. 507 * @returns {*} Returns the map data. 508 */ 509function getMapData(map, key) { 510 var data = map.__data__; 511 return isKeyable(key) 512 ? data[typeof key == 'string' ? 'string' : 'hash'] 513 : data.map; 514} 515 516/** 517 * Gets the native function at `key` of `object`. 518 * 519 * @private 520 * @param {Object} object The object to query. 521 * @param {string} key The key of the method to get. 522 * @returns {*} Returns the function if it's native, else `undefined`. 523 */ 524function getNative(object, key) { 525 var value = getValue(object, key); 526 return baseIsNative(value) ? value : undefined; 527} 528 529/** 530 * Checks if `value` is a property name and not a property path. 531 * 532 * @private 533 * @param {*} value The value to check. 534 * @param {Object} [object] The object to query keys on. 535 * @returns {boolean} Returns `true` if `value` is a property name, else `false`. 536 */ 537function isKey(value, object) { 538 if (isArray(value)) { 539 return false; 540 } 541 var type = typeof value; 542 if (type == 'number' || type == 'symbol' || type == 'boolean' || 543 value == null || isSymbol(value)) { 544 return true; 545 } 546 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || 547 (object != null && value in Object(object)); 548} 549 550/** 551 * Checks if `value` is suitable for use as unique object key. 552 * 553 * @private 554 * @param {*} value The value to check. 555 * @returns {boolean} Returns `true` if `value` is suitable, else `false`. 556 */ 557function isKeyable(value) { 558 var type = typeof value; 559 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') 560 ? (value !== '__proto__') 561 : (value === null); 562} 563 564/** 565 * Checks if `func` has its source masked. 566 * 567 * @private 568 * @param {Function} func The function to check. 569 * @returns {boolean} Returns `true` if `func` is masked, else `false`. 570 */ 571function isMasked(func) { 572 return !!maskSrcKey && (maskSrcKey in func); 573} 574 575/** 576 * Converts `string` to a property path array. 577 * 578 * @private 579 * @param {string} string The string to convert. 580 * @returns {Array} Returns the property path array. 581 */ 582var stringToPath = memoize(function(string) { 583 string = toString(string); 584 585 var result = []; 586 if (reLeadingDot.test(string)) { 587 result.push(''); 588 } 589 string.replace(rePropName, function(match, number, quote, string) { 590 result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); 591 }); 592 return result; 593}); 594 595/** 596 * Converts `value` to a string key if it's not a string or symbol. 597 * 598 * @private 599 * @param {*} value The value to inspect. 600 * @returns {string|symbol} Returns the key. 601 */ 602function toKey(value) { 603 if (typeof value == 'string' || isSymbol(value)) { 604 return value; 605 } 606 var result = (value + ''); 607 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; 608} 609 610/** 611 * Converts `func` to its source code. 612 * 613 * @private 614 * @param {Function} func The function to process. 615 * @returns {string} Returns the source code. 616 */ 617function toSource(func) { 618 if (func != null) { 619 try { 620 return funcToString.call(func); 621 } catch (e) {} 622 try { 623 return (func + ''); 624 } catch (e) {} 625 } 626 return ''; 627} 628 629/** 630 * Creates a function that memoizes the result of `func`. If `resolver` is 631 * provided, it determines the cache key for storing the result based on the 632 * arguments provided to the memoized function. By default, the first argument 633 * provided to the memoized function is used as the map cache key. The `func` 634 * is invoked with the `this` binding of the memoized function. 635 * 636 * **Note:** The cache is exposed as the `cache` property on the memoized 637 * function. Its creation may be customized by replacing the `_.memoize.Cache` 638 * constructor with one whose instances implement the 639 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) 640 * method interface of `delete`, `get`, `has`, and `set`. 641 * 642 * @static 643 * @memberOf _ 644 * @since 0.1.0 645 * @category Function 646 * @param {Function} func The function to have its output memoized. 647 * @param {Function} [resolver] The function to resolve the cache key. 648 * @returns {Function} Returns the new memoized function. 649 * @example 650 * 651 * var object = { 'a': 1, 'b': 2 }; 652 * var other = { 'c': 3, 'd': 4 }; 653 * 654 * var values = _.memoize(_.values); 655 * values(object); 656 * // => [1, 2] 657 * 658 * values(other); 659 * // => [3, 4] 660 * 661 * object.a = 2; 662 * values(object); 663 * // => [1, 2] 664 * 665 * // Modify the result cache. 666 * values.cache.set(object, ['a', 'b']); 667 * values(object); 668 * // => ['a', 'b'] 669 * 670 * // Replace `_.memoize.Cache`. 671 * _.memoize.Cache = WeakMap; 672 */ 673function memoize(func, resolver) { 674 if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { 675 throw new TypeError(FUNC_ERROR_TEXT); 676 } 677 var memoized = function() { 678 var args = arguments, 679 key = resolver ? resolver.apply(this, args) : args[0], 680 cache = memoized.cache; 681 682 if (cache.has(key)) { 683 return cache.get(key); 684 } 685 var result = func.apply(this, args); 686 memoized.cache = cache.set(key, result); 687 return result; 688 }; 689 memoized.cache = new (memoize.Cache || MapCache); 690 return memoized; 691} 692 693// Assign cache to `_.memoize`. 694memoize.Cache = MapCache; 695 696/** 697 * Performs a 698 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) 699 * comparison between two values to determine if they are equivalent. 700 * 701 * @static 702 * @memberOf _ 703 * @since 4.0.0 704 * @category Lang 705 * @param {*} value The value to compare. 706 * @param {*} other The other value to compare. 707 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. 708 * @example 709 * 710 * var object = { 'a': 1 }; 711 * var other = { 'a': 1 }; 712 * 713 * _.eq(object, object); 714 * // => true 715 * 716 * _.eq(object, other); 717 * // => false 718 * 719 * _.eq('a', 'a'); 720 * // => true 721 * 722 * _.eq('a', Object('a')); 723 * // => false 724 * 725 * _.eq(NaN, NaN); 726 * // => true 727 */ 728function eq(value, other) { 729 return value === other || (value !== value && other !== other); 730} 731 732/** 733 * Checks if `value` is classified as an `Array` object. 734 * 735 * @static 736 * @memberOf _ 737 * @since 0.1.0 738 * @category Lang 739 * @param {*} value The value to check. 740 * @returns {boolean} Returns `true` if `value` is an array, else `false`. 741 * @example 742 * 743 * _.isArray([1, 2, 3]); 744 * // => true 745 * 746 * _.isArray(document.body.children); 747 * // => false 748 * 749 * _.isArray('abc'); 750 * // => false 751 * 752 * _.isArray(_.noop); 753 * // => false 754 */ 755var isArray = Array.isArray; 756 757/** 758 * Checks if `value` is classified as a `Function` object. 759 * 760 * @static 761 * @memberOf _ 762 * @since 0.1.0 763 * @category Lang 764 * @param {*} value The value to check. 765 * @returns {boolean} Returns `true` if `value` is a function, else `false`. 766 * @example 767 * 768 * _.isFunction(_); 769 * // => true 770 * 771 * _.isFunction(/abc/); 772 * // => false 773 */ 774function isFunction(value) { 775 // The use of `Object#toString` avoids issues with the `typeof` operator 776 // in Safari 8-9 which returns 'object' for typed array and other constructors. 777 var tag = isObject(value) ? objectToString.call(value) : ''; 778 return tag == funcTag || tag == genTag; 779} 780 781/** 782 * Checks if `value` is the 783 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) 784 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) 785 * 786 * @static 787 * @memberOf _ 788 * @since 0.1.0 789 * @category Lang 790 * @param {*} value The value to check. 791 * @returns {boolean} Returns `true` if `value` is an object, else `false`. 792 * @example 793 * 794 * _.isObject({}); 795 * // => true 796 * 797 * _.isObject([1, 2, 3]); 798 * // => true 799 * 800 * _.isObject(_.noop); 801 * // => true 802 * 803 * _.isObject(null); 804 * // => false 805 */ 806function isObject(value) { 807 var type = typeof value; 808 return !!value && (type == 'object' || type == 'function'); 809} 810 811/** 812 * Checks if `value` is object-like. A value is object-like if it's not `null` 813 * and has a `typeof` result of "object". 814 * 815 * @static 816 * @memberOf _ 817 * @since 4.0.0 818 * @category Lang 819 * @param {*} value The value to check. 820 * @returns {boolean} Returns `true` if `value` is object-like, else `false`. 821 * @example 822 * 823 * _.isObjectLike({}); 824 * // => true 825 * 826 * _.isObjectLike([1, 2, 3]); 827 * // => true 828 * 829 * _.isObjectLike(_.noop); 830 * // => false 831 * 832 * _.isObjectLike(null); 833 * // => false 834 */ 835function isObjectLike(value) { 836 return !!value && typeof value == 'object'; 837} 838 839/** 840 * Checks if `value` is classified as a `Symbol` primitive or object. 841 * 842 * @static 843 * @memberOf _ 844 * @since 4.0.0 845 * @category Lang 846 * @param {*} value The value to check. 847 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. 848 * @example 849 * 850 * _.isSymbol(Symbol.iterator); 851 * // => true 852 * 853 * _.isSymbol('abc'); 854 * // => false 855 */ 856function isSymbol(value) { 857 return typeof value == 'symbol' || 858 (isObjectLike(value) && objectToString.call(value) == symbolTag); 859} 860 861/** 862 * Converts `value` to a string. An empty string is returned for `null` 863 * and `undefined` values. The sign of `-0` is preserved. 864 * 865 * @static 866 * @memberOf _ 867 * @since 4.0.0 868 * @category Lang 869 * @param {*} value The value to process. 870 * @returns {string} Returns the string. 871 * @example 872 * 873 * _.toString(null); 874 * // => '' 875 * 876 * _.toString(-0); 877 * // => '-0' 878 * 879 * _.toString([1, 2, 3]); 880 * // => '1,2,3' 881 */ 882function toString(value) { 883 return value == null ? '' : baseToString(value); 884} 885 886/** 887 *
887This method is like `_.get` except that if the resolved value is a 888 * function it's invoked with the `this` binding of its parent object and 889 * its result is returned. 890 * 891 * @static 892 * @since 0.1.0 893 * @memberOf _ 894 * @category Object 895 * @param {Object} object The object to query. 896 * @param {Array|string} path The path of the property to resolve. 897 * @param {*} [defaultValue] The value returned for `undefined` resolved values. 898 * @returns {*} Returns the resolved value. 899 * @example 900 * 901 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; 902 * 903 * _.result(object, 'a[0].b.c1'); 904 * // => 3 905 * 906 * _.result(object, 'a[0].b.c2'); 907 * // => 4 908 * 909 * _.result(object, 'a[0].b.c3', 'default'); 910 * // => 'default' 911 * 912 * _.result(object, 'a[0].b.c3', _.constant('default')); 913 * // => 'default' 914 */ 915function result(object, path, defaultValue) { 916 path = isKey(path, object) ? [path] : castPath(path); 917 918 var index = -1, 919 length = path.length; 920 921 // Ensure the loop is entered when path is empty. 922 if (!length) { 923 object = undefined; 924 length = 1; 925 } 926 while (++index < length) { 927 var value = object == null ? undefined : object[toKey(path[index])]; 928 if (value === undefined) { 929 index = length; 930 value = defaultValue; 931 } 932 object = isFunction(value) ? value.call(object) : value; 933 } 934 return object; 935} 936 937module.exports = result; 938 939}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 940},{}],3:[function(require,module,exports){ 941module.exports={"version":"1.4.8"} 942},{}],4:[function(require,module,exports){ 943var crossfilter_array8 = crossfilter_arrayUntyped, 944 crossfilter_array16 = crossfilter_arrayUntyped, 945 crossfilter_array32 = crossfilter_arrayUntyped, 946 crossfilter_arrayLengthen = crossfilter_arrayLengthenUntyped, 947 crossfilter_arrayWiden = crossfilter_arrayWidenUntyped; 948if (typeof Uint8Array !== "undefined") { 949 crossfilter_array8 = function(n) { return new Uint8Array(n); }; 950 crossfilter_array16 = function(n) { return new Uint16Array(n); }; 951 crossfilter_array32 = function(n) { return new Uint32Array(n); }; 952 953 crossfilter_arrayLengthen = function(array, length) { 954 if (array.length >= length) return array; 955 var copy = new array.constructor(length); 956 copy.set(array); 957 return copy; 958 }; 959 960 crossfilter_arrayWiden = function(array, width) { 961 var copy; 962 switch (width) { 963 case 16: copy = crossfilter_array16(array.length); break; 964 case 32: copy = crossfilter_array32(array.length); break; 965 default: throw new Error("invalid array width!"); 966 } 967 copy.set(array); 968 return copy; 969 }; 970} 971 972function crossfilter_arrayUntyped(n) { 973 var array = new Array(n), i = -1; 974 while (++i < n) array[i] = 0; 975 return array; 976} 977 978function crossfilter_arrayLengthenUntyped(array, length) { 979 var n = array.length; 980 while (n < length) array[n++] = 0; 981 return array; 982} 983 984function crossfilter_arrayWidenUntyped(array, width) { 985 if (width > 32) throw new Error("invalid array width!"); 986 return array; 987} 988 989// An arbitrarily-wide array of bitmasks 990function crossfilter_bitarray(n) { 991 this.length = n; 992 this.subarrays = 1; 993 this.width = 8; 994 this.masks = { 995 0: 0 996 } 997 998 this[0] = crossfilter_array8(n); 999} 1000 1001crossfilter_bitarray.prototype.lengthen = function(n) { 1002 var i, len; 1003 for (i = 0, len = this.subarrays; i < len; ++i) { 1004 this[i] = crossfilter_arrayLengthen(this[i], n); 1005 } 1006 this.length = n; 1007}; 1008 1009// Reserve a new bit index in the array, returns {offset, one} 1010crossfilter_bitarray.prototype.add = function() { 1011 var m, w, one, i, len; 1012 1013 for (i = 0, len = this.subarrays; i < len; ++i) { 1014 m = this.masks[i]; 1015 w = this.width - (32 * i); 1016 // isolate the rightmost zero bit and return it as an unsigned int of 32 bits, if NaN or -1, return a 0 1017 one = (~m & (m + 1)) >>> 0; 1018 1019 if (w >= 32 && !one) { 1020 continue; 1021 } 1022 1023 if (w < 32 && (one & (1 << w))) { 1024 // widen this subarray 1025 this[i] = crossfilter_arrayWiden(this[i], w <<= 1); 1026 this.width = 32 * i + w; 1027 } 1028 1029 this.masks[i] |= one; 1030 1031 return { 1032 offset: i, 1033 one: one 1034 }; 1035 } 1036 1037 // add a new subarray 1038 this[this.subarrays] = crossfilter_array8(this.length); 1039 this.masks[this.subarrays] = 1; 1040 this.width += 8; 1041 return { 1042 offset: this.subarrays++, 1043 one: 1 1044 }; 1045}; 1046 1047// Copy record from index src to index dest 1048crossfilter_bitarray.prototype.copy = function(dest, src) { 1049 var i, len; 1050 for (i = 0, len = this.subarrays; i < len; ++i) { 1051 this[i][dest] = this[i][src]; 1052 } 1053}; 1054 1055// Truncate the array to the given length 1056crossfilter_bitarray.prototype.truncate = function(n) { 1057 var i, len; 1058 for (i = 0, len = this.subarrays; i < len; ++i) { 1059 for (var j = this.length - 1; j >= n; j--) { 1060 this[i][j] = 0; 1061 } 1062 } 1063 this.length = n; 1064}; 1065 1066// Checks that all bits for the given index are 0 1067crossfilter_bitarray.prototype.zero = function(n) { 1068 var i, len; 1069 for (i = 0, len = this.subarrays; i < len; ++i) { 1070 if (this[i][n]) { 1071 return false;
1072 } 1073 } 1074 return true; 1075}; 1076 1077// Checks that all bits for the given index are 0 except for possibly one 1078crossfilter_bitarray.prototype.zeroExcept = function(n, offset, zero) { 1079 var i, len; 1080 for (i = 0, len = this.subarrays; i < len; ++i) { 1081 if (i === offset ? this[i][n] & zero : this[i][n]) { 1082 return false; 1083 } 1084 } 1085 return true; 1086}; 1087 1088// Checks that all bits for the given index are 0 except for the specified mask. 1089// The mask should be an array of the same size as the filter subarrays width. 1090crossfilter_bitarray.prototype.zeroExceptMask = function(n, mask) { 1091 var i, len; 1092 for (i = 0, len = this.subarrays; i < len; ++i) { 1093 if (this[i][n] & mask[i]) { 1094 return false; 1095 } 1096 } 1097 return true; 1098} 1099 1100// Checks that only the specified bit is set for the given index 1101crossfilter_bitarray.prototype.only = function(n, offset, one) { 1102 var i, len; 1103 for (i = 0, len = this.subarrays; i < len; ++i) { 1104 if (this[i][n] != (i === offset ? one : 0)) { 1105 return false; 1106 } 1107 } 1108 return true; 1109}; 1110 1111// Checks that only the specified bit is set for the given index except for possibly one other 1112crossfilter_bitarray.prototype.onlyExcept = function(n, offset, zero, onlyOffset, onlyOne) { 1113 var mask; 1114 var i, len; 1115 for (i = 0, len = this.subarrays; i < len; ++i) { 1116 mask = this[i][n]; 1117 if (i === offset) 1118 mask &= zero; 1119 if (mask != (i === onlyOffset ? onlyOne : 0)) { 1120 return false; 1121 } 1122 } 1123 return true; 1124}; 1125 1126module.exports = { 1127 array8: crossfilter_array8, 1128 array16: crossfilter_array16, 1129 array32: crossfilter_array32, 1130 arrayLengthen: crossfilter_arrayLengthen, 1131 arrayWiden: crossfilter_arrayWiden, 1132 bitarray: crossfilter_bitarray 1133}; 1134 1135},{}],5:[function(require,module,exports){ 1136'use strict'; 1137 1138var crossfilter_identity = require('./identity'); 1139 1140function bisect_by(f) { 1141 1142 // Locate the insertion point for x in a to maintain sorted order. The 1143 // arguments lo and hi may be used to specify a subset of the array which 1144 // should be considered; by default the entire array is used. If x is already 1145 // present in a, the insertion point will be before (to the left of) any 1146 // existing entries. The return value is suitable for use as the first 1147 // argument to `array.splice` assuming that a is already sorted. 1148 // 1149 // The returned insertion point i partitions the array a into two halves so 1150 // that all v < x for v in a[lo:i] for the left side and all v >= x for v in 1151 // a[i:hi] for the right side. 1152 function bisectLeft(a, x, lo, hi) { 1153 while (lo < hi) { 1154 var mid = lo + hi >>> 1; 1155 if (f(a[mid]) < x) lo = mid + 1; 1156 else hi = mid; 1157 } 1158 return lo; 1159 } 1160 1161 // Similar to bisectLeft, but returns an insertion point which comes after (to 1162 // the right of) any existing entries of x in a. 1163 // 1164 // The returned insertion point i partitions the array into two halves so that 1165 // all v <= x for v in a[lo:i] for the left side and all v > x for v in 1166 // a[i:hi] for the right side. 1167 function bisectRight(a, x, lo, hi) { 1168 while (lo < hi) { 1169 var mid = lo + hi >>> 1; 1170 if (x < f(a[mid])) hi = mid; 1171 else lo = mid + 1; 1172 } 1173 return lo; 1174 } 1175 1176 bisectRight.right = bisectRight; 1177 bisectRight.left = bisectLeft; 1178 return bisectRight; 1179} 1180 1181module.exports = bisect_by(crossfilter_identity); 1182module.exports.by = bisect_by; // assign the raw function to the export as well 1183 1184},{"./identity":10}],6:[function(require,module,exports){ 1185'use strict'; 1186 1187var xfilterArray = require('./array'); 1188var xfilterFilter = require('./filter'); 1189var crossfilter_identity = require('./identity'); 1190var crossfilter_null = require('./null'); 1191var crossfilter_zero = require('./zero'); 1192var xfilterHeapselect = require('./heapselect'); 1193var xfilterHeap = require('./heap'); 1194var bisect = require('./bisect'); 1195var insertionsort = require('./insertionsort'); 1196var permute = require('./permute'); 1197var quicksort = require('./quicksort'); 1198var xfilterReduce = require('./reduce'); 1199var packageJson = require('./../package.json'); // require own package.json for the version field 1200var result = require('lodash.result'); 1201 1202// constants 1203var REMOVED_INDEX = -1; 1204
1205// expose API exports 1206exports.crossfilter = crossfilter; 1207exports.crossfilter.heap = xfilterHeap; 1208exports.crossfilter.heapselect = xfilterHeapselect; 1209exports.crossfilter.bisect = bisect; 1210exports.crossfilter.insertionsort = insertionsort; 1211exports.crossfilter.permute = permute; 1212exports.crossfilter.quicksort = quicksort; 1213exports.crossfilter.version = packageJson.version; // please note use of "package-json-versionify" transform 1214 1215function crossfilter() { 1216 var crossfilter = { 1217 add: add, 1218 remove: removeData, 1219 dimension: dimension, 1220 groupAll: groupAll, 1221 size: size, 1222 all: all, 1223 allFiltered: allFiltered, 1224 onChange: onChange, 1225 isElementFiltered: isElementFiltered 1226 }; 1227 1228 var data = [], // the records 1229 n = 0, // the number of records; data.length 1230 filters, // 1 is filtered out 1231 filterListeners = [], // when the filters change 1232 dataListeners = [], // when data is added 1233 removeDataListeners = [], // when data is removed 1234 callbacks = []; 1235 1236 filters = new xfilterArray.bitarray(0); 1237 1238 // Adds the specified new records to this crossfilter. 1239 function add(newData) { 1240 var n0 = n, 1241 n1 = newData.length; 1242 1243 // If there's actually new data to add… 1244 // Merge the new data into the existing data. 1245 // Lengthen the filter bitset to handle the new records. 1246 // Notify listeners (dimensions and groups) that new data is available. 1247 if (n1) { 1248 data = data.concat(newData); 1249 filters.lengthen(n += n1); 1250 dataListeners.forEach(function(l) { l(newData, n0, n1); }); 1251 triggerOnChange('dataAdded'); 1252 } 1253 1254 return crossfilter; 1255 } 1256 1257 // Removes all records that match the current filters, or if a predicate function is passed, 1258 // removes all records matching the predicate (ignoring filters). 1259 function removeData(predicate) { 1260 var // Mapping from old record indexes to new indexes (after records removed) 1261 newIndex = new Array(n), 1262 removed = [], 1263 usePred = typeof predicate === 'function', 1264 shouldRemove = function (i) { 1265 return usePred ? predicate(data[i], i) : filters.zero(i) 1266 }; 1267 1268 for (var index1 = 0, index2 = 0; index1 < n; ++index1) { 1269 if ( shouldRemove(index1) ) { 1270 removed.push(index1); 1271 newIndex[index1] = REMOVED_INDEX; 1272 } else { 1273 newIndex[index1] = index2++; 1274 } 1275 } 1276 1277 // Remove all matching records from groups. 1278 filterListeners.forEach(function(l) { l(-1, -1, [], removed, true); }); 1279 1280 // Update indexes. 1281 removeDataListeners.forEach(function(l) { l(newIndex); }); 1282 1283 // Remove old filters and data by overwriting. 1284 for (var index3 = 0, index4 = 0; index3 < n; ++index3) { 1285 if ( newIndex[index3] !== REMOVED_INDEX ) { 1286 if (index3 !== index4) filters.copy(index4, index3), data[index4] = data[index3]; 1287 ++index4; 1288 } 1289 } 1290 1291 data.length = n = index4; 1292 filters.truncate(index4); 1293 triggerOnChange('dataRemoved'); 1294 } 1295 1296 function maskForDimensions(dimensions) { 1297 var n, 1298 d, 1299 len, 1300 id, 1301 mask = Array(filters.subarrays); 1302 for (n = 0; n < filters.subarrays; n++) { mask[n] = ~0; } 1303 for (d = 0, len = dimensions.length; d < len; d++) { 1304 // The top bits of the ID are the subarray offset and the lower bits are the bit 1305 // offset of the "one" mask. 1306 id = dimensions[d].id(); 1307 mask[id >> 7] &= ~(0x1 << (id & 0x3f)); 1308 } 1309 return mask; 1310 } 1311 1312 // Return true if the data element at index i is filtered IN. 1313 // Optionally, ignore the filters of any dimensions in the ignore_dimensions list. 1314 function isElementFiltered(i, ignore_dimensions) { 1315 var mask = maskForDimensions(ignore_dimensions || []); 1316 return filters.zeroExceptMask(i,mask); 1317 } 1318 1319 // Adds a new dimension with the specified value accessor function. 1320 function dimension(value, iterable) { 1321 1322 if (typeof value === 'string') { 1323 var accessorPath = value; 1324 value = function(d) { return result(d, accessorPath); }; 1325 } 1326 1327 var dimension = { 1328 filter: filter, 1329 filterExact: filterExact, 1330 filterRange: filterRange, 1331 filterFunction: filterFunction, 1332 filterAll: filterAll, 1333 currentFilter: currentFilter, 1334 hasCurrentFilter: hasCurrentFilter, 1335 top: top, 1336 bottom: bottom, 1337 group: group, 1338 groupAll: groupAll,
1339 dispose: dispose, 1340 remove: dispose, // for backwards-compatibility 1341 accessor: value, 1342 id: function() { return id; } 1343 }; 1344 1345 var one, // lowest unset bit as mask, e.g., 00001000 1346 zero, // inverted one, e.g., 11110111 1347 offset, // offset into the filters arrays 1348 id, // unique ID for this dimension (reused when dimensions are disposed) 1349 values, // sorted, cached array 1350 index, // maps sorted value index -> record index (in data) 1351 newValues, // temporary array storing newly-added values 1352 newIndex, // temporary array storing newly-added index 1353 iterablesIndexCount, 1354 iterablesIndexFilterStatus, 1355 iterablesEmptyRows = [], 1356 sort = quicksort.by(function(i) { return newValues[i]; }), 1357 refilter = xfilterFilter.filterAll, // for recomputing filter 1358 refilterFunction, // the custom filter function in use 1359 filterValue, // the value used for filtering (value, array, function or undefined) 1360 filterValuePresent, // true if filterValue contains something 1361 indexListeners = [], // when data is added 1362 dimensionGroups = [], 1363 lo0 = 0, 1364 hi0 = 0, 1365 t = 0, 1366 k; 1367 1368 // Updating a dimension is a two-stage process. First, we must update the 1369 // associated filters for the newly-added records. Once all dimensions have 1370 // updated their filters, the groups are notified to update. 1371 dataListeners.unshift(preAdd); 1372 dataListeners.push(postAdd); 1373 1374 removeDataListeners.push(removeData); 1375 1376 // Add a new dimension in the filter bitmap and store the offset and bitmask. 1377 var tmp = filters.add(); 1378 offset = tmp.offset; 1379 one = tmp.one; 1380 zero = ~one; 1381 1382 // Create a unique ID for the dimension 1383 // IDs will be re-used if dimensions are disposed. 1384 // For internal use the ID is the subarray offset shifted left 7 bits or'd with the 1385 // bit offset of the set bit in the dimension's "one" mask. 1386 id = (offset << 7) | (Math.log(one) / Math.log(2)); 1387 1388 preAdd(data, 0, n); 1389 postAdd(data, 0, n); 1390 1391 // Incorporates the specified new records into this dimension. 1392 // This function is responsible for updating filters, values, and index. 1393 function preAdd(newData, n0, n1) { 1394 var newIterablesIndexCount, 1395 newIterablesIndexFilterStatus; 1396 1397 if (iterable){ 1398 // Count all the values 1399 t = 0; 1400 j = 0; 1401 k = []; 1402 1403 for (var i0 = 0; i0 < newData.length; i0++) { 1404 for(j = 0, k = value(newData[i0]); j < k.length; j++) { 1405 t++; 1406 } 1407 } 1408 1409 newValues = []; 1410 newIterablesIndexCount = crossfilter_range(newData.length); 1411 newIterablesIndexFilterStatus = crossfilter_index(t,1); 1412 var unsortedIndex = crossfilter_range(t); 1413 1414 for (var l = 0, index1 = 0; index1 < newData.length; index1++) { 1415 k = value(newData[index1]) 1416 // 1417 if(!k.length){ 1418 newIterablesIndexCount[index1] = 0; 1419 iterablesEmptyRows.push(index1 + n0); 1420 continue; 1421 } 1422 newIterablesIndexCount[index1] = k.length 1423 for (j = 0; j < k.length; j++) { 1424 newValues.push(k[j]); 1425 unsortedIndex[l] = index1; 1426 l++; 1427 } 1428 } 1429 1430 // Create the Sort map used to sort both the values and the valueToData indices 1431 var sortMap = sort(crossfilter_range(t), 0, t); 1432 1433 // Use the sortMap to sort the newValues 1434 newValues = permute(newValues, sortMap); 1435 1436 1437 // Use the sortMap to sort the unsortedIndex map 1438 // newIndex should be a map of sortedValue -> crossfilterData 1439 newIndex = permute(unsortedIndex, sortMap) 1440 1441 } else{ 1442 // Permute new values into natural order using a standard sorted index. 1443 newValues = newData.map(value); 1444 newIndex = sort(crossfilter_range(n1), 0, n1); 1445 newValues = permute(newValues, newIndex); 1446 } 1447 1448 // Bisect newValues to determine which new records are selected. 1449 var bounds = refilter(newValues), lo1 = bounds[0], hi1 = bounds[1]; 1450 1451 var index2, index3, index4; 1452 if(iterable) { 1453 n1 = t; 1454 if (refilterFunction) { 1455 for (index2 = 0; index2 < n1; ++index2) { 1456 if (!refilterFunction(newValues[index2], index2)) { 1457 if(--newIterablesIndexCount[newIndex[index2]] === 0) { 1458 filters[offset][newIndex[index2] + n0] |= one; 1459 } 1460 newIterablesIndexFilterStatus[index2] = 1; 1461 } 1462 } 1463 } else { 1464 for (index3 = 0; index3 < lo1; ++index3) { 1465 if(--newIterablesIndexCount[newIndex[index3]] === 0) { 1466 filters[offset][newIndex[index3] + n0] |= one; 1467 } 1468 newIterablesIndexFilterStatus[index3] = 1; 1469 } 1470 for (index4 = hi1; index4 < n1; ++index4) { 1471 if(--newIterablesIndexCount[newIndex[index4]] === 0) { 1472 filters[offset][newIndex[index4] + n0] |= one; 1473 } 1474 newIterablesIndexFilterStatus[index4] = 1; 1475 } 1476 } 1477 } else { 1478 if (refilterFunction) { 1479 for (index2 = 0; index2 < n1; ++index2) { 1480 if (!refilterFunction(newValues[index2], index2)) { 1481 filters[offset][newIndex[index2] + n0] |= one; 1482 } 1483 } 1484 } else { 1485 for (index3 = 0; index3 < lo1; ++index3) { 1486 filters[offset][newIndex[index3] + n0] |= one; 1487 } 1488 for (index4 = hi1; index4 < n1; ++index4) { 1489 filters[offset][newIndex[index4] + n0] |= one; 1490 } 1491 } 1492 } 1493 1494 // If this dimension previously had no data, then we don't need to do the 1495 // more expensive merge operation; use the new values and index as-is. 1496 if (!n0) { 1497 values = newValues; 1498 index = newIndex; 1499 iterablesIndexCount = newIterablesIndexCount; 1500 iterablesIndexFilterStatus = newIterablesIndexFilterStatus; 1501 lo0 = lo1; 1502 hi0 = hi1; 1503 return; 1504 } 1505 1506 1507 1508 var oldValues = values, 1509 oldIndex = index, 1510 oldIterablesIndexFilterStatus = iterablesIndexFilterStatus, 1511 old_n0, 1512 i1 = 0; 1513 1514 i0 = 0; 1515 1516 if(iterable){ 1517 old_n0 = n0 1518 n0 = oldValues.length; 1519 n1 = t 1520 } 1521 1522 // Otherwise, create new arrays into which to merge new and old. 1523 values = iterable ? new Array(n0 + n1) : new Array(n); 1524 index = iterable ? new Array(n0 + n1) : crossfilter_index(n, n); 1525 if(iterable) iterablesIndexFilterStatus = crossfilter_index(n0 + n1, 1); 1526 1527 // Concatenate the newIterablesIndexCount onto the old one. 1528 if(iterable) { 1529 var oldiiclength = iterablesIndexCount.length; 1530 iterablesIndexCount = xfilterArray.arrayLengthen(iterablesIndexCount, n); 1531 for(var j=0; j+oldiiclength < n; j++) { 1532 iterablesIndexCount[j+oldiiclength] = newIterablesIndexCount[j]; 1533 } 1534 } 1535 1536 // Merge the old and new sorted values, and old and new index. 1537 var index5 = 0; 1538 for (; i0 < n0 && i1 < n1; ++index5) { 1539 if (oldValues[i0] < newValues[i1]) { 1540 values[index5] = oldValues[i0]; 1541 if(iterable) iterablesIndexFilterStatus[index5] = oldIterablesIndexFilterStatus[i0]; 1542 index[index5] = oldIndex[i0++]; 1543 } else { 1544 values[index5] = newValues[i1]; 1545 if(iterable) iterablesIndexFilterStatus[index5] = newIterablesIndexFilterStatus[i1]; 1546 index[index5] = newIndex[i1++] + (iterable ? old_n0 : n0); 1547 } 1548 } 1549 1550 // Add any remaining old values. 1551 for (; i0 < n0; ++i0, ++index5) { 1552 values[index5] = oldValues[i0]; 1553 if(iterable) iterablesIndexFilterStatus[index5] = oldIterablesIndexFilterStatus[i0]; 1554 index[index5] = oldIndex[i0]; 1555 } 1556 1557 // Add any remaining new values. 1558 for (; i1 < n1; ++i1, ++index5) { 1559 values[index5] = newValues[i1]; 1560 if(iterable) iterablesIndexFilterStatus[index5] = newIterablesIndexFilterStatus[i1]; 1561 index[index5] = newIndex[i1] + (iterable ? old_n0 : n0); 1562 } 1563 1564 // Bisect again to recompute lo0 and hi0. 1565 bounds = refilter(values), lo0 = bounds[0], hi0 = bounds[1]; 1566 } 1567 1568 // When all filters have updated, notify index listeners of the new values. 1569 function postAdd(newData, n0, n1) {
1570 indexListeners.forEach(function(l) { l(newValues, newIndex, n0, n1); }); 1571 newValues = newIndex = null; 1572 } 1573 1574 function removeData(reIndex) { 1575 if (iterable) { 1576 for (var i0 = 0, i1 = 0; i0 < iterablesEmptyRows.length; i0++) { 1577 if (reIndex[iterablesEmptyRows[i0]] !== REMOVED_INDEX) { 1578 iterablesEmptyRows[i1] = reIndex[iterablesEmptyRows[i0]]; 1579 i1++; 1580 } 1581 } 1582 iterablesEmptyRows.length = i1; 1583 for (i0 = 0, i1 = 0; i0 < n; i0++) { 1584 if (reIndex[i0] !== REMOVED_INDEX) { 1585 if (i1 !== i0) iterablesIndexCount[i1] = iterablesIndexCount[i0]; 1586 i1++; 1587 } 1588 } 1589 iterablesIndexCount = iterablesIndexCount.slice(0, i1); 1590 } 1591 // Rewrite our index, overwriting removed values 1592 var n0 = values.length; 1593 for (var i = 0, j = 0, oldDataIndex; i < n0; ++i) { 1594 oldDataIndex = index[i]; 1595 if (reIndex[oldDataIndex] !== REMOVED_INDEX) { 1596 if (i !== j) values[j] = values[i]; 1597 index[j] = reIndex[oldDataIndex]; 1598 if (iterable) { 1599 iterablesIndexFilterStatus[j] = iterablesIndexFilterStatus[i]; 1600 } 1601 ++j; 1602 } 1603 } 1604 values.length = j; 1605 if (iterable) iterablesIndexFilterStatus = iterablesIndexFilterStatus.slice(0, j); 1606 while (j < n0) index[j++] = 0; 1607 1608 // Bisect again to recompute lo0 and hi0. 1609 var bounds = refilter(values); 1610 lo0 = bounds[0], hi0 = bounds[1]; 1611 } 1612 1613 // Updates the selected values based on the specified bounds [lo, hi]. 1614 // This implementation is used by all the public filter methods. 1615 function filterIndexBounds(bounds) { 1616 1617 var lo1 = bounds[0], 1618 hi1 = bounds[1]; 1619 1620 if (refilterFunction) { 1621 refilterFunction = null; 1622 filterIndexFunction(function(d, i) { return lo1 <= i && i < hi1; }, bounds[0] === 0 && bounds[1] === values.length); 1623 lo0 = lo1; 1624 hi0 = hi1; 1625 return dimension; 1626 } 1627 1628 var i, 1629 j, 1630 k, 1631 added = [], 1632 removed = [], 1633 valueIndexAdded = [], 1634 valueIndexRemoved = []; 1635 1636 1637 // Fast incremental update based on previous lo index. 1638 if (lo1 < lo0) { 1639 for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) { 1640 added.push(index[i]); 1641 valueIndexAdded.push(i); 1642 } 1643 } else if (lo1 > lo0) { 1644 for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) { 1645 removed.push(index[i]); 1646 valueIndexRemoved.push(i); 1647 } 1648 } 1649 1650 // Fast incremental update based on previous hi index. 1651 if (hi1 > hi0) { 1652 for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) { 1653 added.push(index[i]); 1654 valueIndexAdded.push(i); 1655 } 1656 } else if (hi1 < hi0) { 1657 for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) { 1658 removed.push(index[i]); 1659 valueIndexRemoved.push(i); 1660 } 1661 } 1662 1663 if(!iterable) { 1664 // Flip filters normally. 1665 1666 for(i=0; i<added.length; i++) { 1667 filters[offset][added[i]] ^= one; 1668 } 1669 1670 for(i=0; i<removed.length; i++) { 1671 filters[offset][removed[i]] ^= one; 1672 } 1673 1674 } else { 1675 // For iterables, we need to figure out if the row has been completely removed vs partially included 1676 // Only count a row as added if it is not already being aggregated. Only count a row 1677 // as removed if the last element being aggregated is removed. 1678 1679 var newAdded = []; 1680 var newRemoved = []; 1681 for (i = 0; i < added.length; i++) { 1682 iterablesIndexCount[added[i]]++ 1683 iterablesIndexFilterStatus[valueIndexAdded[i]] = 0; 1684 if(iterablesIndexCount[added[i]] === 1) { 1685 filters[offset][added[i]] ^= one; 1686 newAdded.push(added[i]); 1687 } 1688 } 1689 for (i = 0; i < removed.length; i++) { 1690 iterablesIndexCount[removed[i]]-- 1691 iterablesIndexFilterStatus[valueIndexRemoved[i]] = 1; 1692 if(iterablesIndexCount[removed[i]] === 0) { 1693 filters[offset][removed[i]] ^= one; 1694 newRemoved.push(removed[i]); 1695 } 1696 } 1697 1698 added = newAdded; 1699 removed = newRemoved; 1700 1701 // Now handle empty rows. 1702 if(refilter === xfilterFilter.filterAll) { 1703 for(i = 0; i < iterablesEmptyRows.length; i++) { 1704 if((filters[offset][k = iterablesEmptyRows[i]] & one)) { 1705 // Was not in the filter, so set the filter and add 1706 filters[offset][k] ^= one; 1707 added.push(k); 1708 } 1709 } 1710 } else { 1711 // filter in place - remove empty rows if necessary 1712 for(i = 0; i < iterablesEmptyRows.length; i++) { 1713 if(!(filters[offset][k = iterablesEmptyRows[i]] & one)) { 1714 // Was in the filter, so set the filter and remove 1715 filters[offset][k] ^= one; 1716 removed.push(k); 1717 } 1718 } 1719 } 1720 } 1721 1722 lo0 = lo1; 1723 hi0 = hi1;
1724 filterListeners.forEach(function(l) { l(one, offset, added, removed); }); 1725 triggerOnChange('filtered'); 1726 return dimension; 1727 } 1728 1729 // Filters this dimension using the specified range, value, or null. 1730 // If the range is null, this is equivalent to filterAll. 1731 // If the range is an array, this is equivalent to filterRange. 1732 // Otherwise, this is equivalent to filterExact. 1733 function filter(range) { 1734 return range == null 1735 ? filterAll() : Array.isArray(range) 1736 ? filterRange(range) : typeof range === "function" 1737 ? filterFunction(range) 1738 : filterExact(range); 1739 } 1740 1741 // Filters this dimension to select the exact value. 1742 function filterExact(value) { 1743 filterValue = value; 1744 filterValuePresent = true; 1745 return filterIndexBounds((refilter = xfilterFilter.filterExact(bisect, value))(values)); 1746 } 1747 1748 // Filters this dimension to select the specified range [lo, hi]. 1749 // The lower bound is inclusive, and the upper bound is exclusive. 1750 function filterRange(range) { 1751 filterValue = range; 1752 filterValuePresent = true; 1753 return filterIndexBounds((refilter = xfilterFilter.filterRange(bisect, range))(values)); 1754 } 1755 1756 // Clears any filters on this dimension. 1757 function filterAll() { 1758 filterValue = undefined; 1759 filterValuePresent = false; 1760 return filterIndexBounds((refilter = xfilterFilter.filterAll)(values)); 1761 } 1762 1763 // Filters this dimension using an arbitrary function. 1764 function filterFunction(f) { 1765 filterValue = f; 1766 filterValuePresent = true; 1767 1768 refilterFunction = f; 1769 refilter = xfilterFilter.filterAll; 1770 1771 filterIndexFunction(f, false); 1772 1773 var bounds = refilter(values); 1774 lo0 = bounds[0], hi0 = bounds[1]; 1775 1776 return dimension; 1777 } 1778 1779 function filterIndexFunction(f, filterAll) { 1780 var i, 1781 k, 1782 x, 1783 added = [], 1784 removed = [], 1785 valueIndexAdded = [], 1786 valueIndexRemoved = [], 1787 indexLength = values.length; 1788 1789 if(!iterable) { 1790 for (i = 0; i < indexLength; ++i) { 1791 if (!(filters[offset][k = index[i]] & one) ^ !!(x = f(values[i], i))) { 1792 if (x) added.push(k); 1793 else removed.push(k); 1794 } 1795 } 1796 } 1797 1798 if(iterable) { 1799 for(i=0; i < indexLength; ++i) { 1800 if(f(values[i], i)) { 1801 added.push(index[i]); 1802 valueIndexAdded.push(i); 1803 } else { 1804 removed.push(index[i]); 1805 valueIndexRemoved.push(i); 1806 } 1807 } 1808 } 1809 1810 if(!iterable) { 1811 for(i=0; i<added.length; i++) { 1812 if(filters[offset][added[i]] & one) filters[offset][added[i]] &= zero; 1813 } 1814 1815 for(i=0; i<removed.length; i++) { 1816 if(!(filters[offset][removed[i]] & one)) filters[offset][removed[i]] |= one; 1817 } 1818 } else { 1819 1820 var newAdded = []; 1821 var newRemoved = []; 1822 for (i = 0; i < added.length; i++) { 1823 // First check this particular value needs to be added 1824 if(iterablesIndexFilterStatus[valueIndexAdded[i]] === 1) { 1825 iterablesIndexCount[added[i]]++ 1826 iterablesIndexFilterStatus[valueIndexAdded[i]] = 0; 1827 if(iterablesIndexCount[added[i]] === 1) { 1828 filters[offset][added[i]] ^= one; 1829 newAdded.push(added[i]); 1830 } 1831 } 1832 } 1833 for (i = 0; i < removed.length; i++) { 1834 // First check this particular value needs to be removed 1835 if(iterablesIndexFilterStatus[valueIndexRemoved[i]] === 0) { 1836 iterablesIndexCount[removed[i]]-- 1837 iterablesIndexFilterStatus[valueIndexRemoved[i]] = 1; 1838 if(iterablesIndexCount[removed[i]] === 0) { 1839 filters[offset][removed[i]] ^= one; 1840 newRemoved.push(removed[i]); 1841 } 1842 } 1843 } 1844 1845 added = newAdded; 1846 removed = newRemoved; 1847 1848 // Now handle empty rows. 1849 if(filterAll) { 1850 for(i = 0; i < iterablesEmptyRows.length; i++) { 1851 if((filters[offset][k = iterablesEmptyRows[i]] & one)) { 1852 // Was not in the filter, so set the filter and add 1853 filters[offset][k] ^= one; 1854 added.push(k); 1855 } 1856 } 1857 } else { 1858 // filter in place - remove empty rows if necessary 1859 for(i = 0; i < iterablesEmptyRows.length; i++) { 1860 if(!(filters[offset][k = iterablesEmptyRows[i]] & one)) { 1861 // Was in the filter, so set the filter and remove 1862 filters[offset][k] ^= one; 1863 removed.push(k); 1864 } 1865 } 1866 } 1867 } 1868
1869 filterListeners.forEach(function(l) { l(one, offset, added, removed); }); 1870 triggerOnChange('filtered'); 1871 } 1872 1873 function currentFilter() { 1874 return filterValue; 1875 } 1876 1877 function hasCurrentFilter() { 1878 return filterValuePresent; 1879 } 1880 1881 // Returns the top K selected records based on this dimension's order. 1882 // Note: observes this dimension's filter, unlike group and groupAll. 1883 function top(k, top_offset) { 1884 var array = [], 1885 i = hi0, 1886 j, 1887 toSkip = 0; 1888 1889 if(top_offset && top_offset > 0) toSkip = top_offset; 1890 1891 while (--i >= lo0 && k > 0) { 1892 if (filters.zero(j = index[i])) { 1893 if(toSkip > 0) { 1894 //skip matching row 1895 --toSkip; 1896 } else { 1897 array.push(data[j]); 1898 --k; 1899 } 1900 } 1901 } 1902 1903 if(iterable){ 1904 for(i = 0; i < iterablesEmptyRows.length && k > 0; i++) { 1905 // Add row with empty iterable column at the end 1906 if(filters.zero(j = iterablesEmptyRows[i])) { 1907 if(toSkip > 0) { 1908 //skip matching row 1909 --toSkip; 1910 } else { 1911 array.push(data[j]); 1912 --k; 1913 } 1914 } 1915 } 1916 } 1917 1918 return array; 1919 } 1920 1921 // Returns the bottom K selected records based on this dimension's order. 1922 // Note: observes this dimension's filter, unlike group and groupAll. 1923 function bottom(k, bottom_offset) { 1924 var array = [], 1925 i, 1926 j, 1927 toSkip = 0; 1928 1929 if(bottom_offset && bottom_offset > 0) toSkip = bottom_offset; 1930 1931 if(iterable) { 1932 // Add row with empty iterable column at the top 1933 for(i = 0; i < iterablesEmptyRows.length && k > 0; i++) { 1934 if(filters.zero(j = iterablesEmptyRows[i])) { 1935 if(toSkip > 0) { 1936 //skip matching row 1937 --toSkip; 1938 } else { 1939 array.push(data[j]); 1940 --k; 1941 } 1942 } 1943 } 1944 } 1945 1946 i = lo0; 1947 1948 while (i < hi0 && k > 0) { 1949 if (filters.zero(j = index[i])) { 1950 if(toSkip > 0) { 1951 //skip matching row 1952 --toSkip; 1953 } else { 1954 array.push(data[j]); 1955 --k; 1956 } 1957 } 1958 i++; 1959 } 1960 1961 return array; 1962 } 1963 1964 // Adds a new group to this dimension, using the specified key function. 1965 function group(key) { 1966 var group = { 1967 top: top, 1968 all: all, 1969 reduce: reduce, 1970 reduceCount: reduceCount, 1971 reduceSum: reduceSum, 1972 order: order, 1973 orderNatural: orderNatural, 1974 size: size, 1975 dispose: dispose, 1976 remove: dispose // for backwards-compatibility 1977 }; 1978 1979 // Ensure that this group will be removed when the dimension is removed. 1980 dimensionGroups.push(group); 1981 1982 var groups, // array of {key, value} 1983 groupIndex, // object id ↦ group id 1984 groupWidth = 8, 1985 groupCapacity = crossfilter_capacity(groupWidth), 1986 k = 0, // cardinality 1987 select, 1988 heap, 1989 reduceAdd, 1990 reduceRemove, 1991 reduceInitial, 1992 update = crossfilter_null, 1993 reset = crossfilter_null, 1994 resetNeeded = true, 1995 groupAll = key === crossfilter_null, 1996 n0old; 1997 1998 if (arguments.length < 1) key = crossfilter_identity; 1999 2000 // The group listens to the crossfilter for when any dimension changes, so 2001 // that it can update the associated reduce values. It must also listen to 2002 // the parent dimension for when data is added, and compute new keys. 2003 filterListeners.push(update); 2004 indexListeners.push(add); 2005 removeDataListeners.push(removeData); 2006 2007 // Incorporate any existing data into the grouping. 2008 add(values, index, 0, n); 2009 2010 // Incorporates the specified new values into this group. 2011 // This function is responsible for updating groups and groupIndex. 2012 function add(newValues, newIndex, n0, n1) { 2013 2014 if(iterable) { 2015 n0old = n0 2016 n0 = values.length - newValues.length 2017 n1 = newValues.length; 2018 } 2019 2020 var oldGroups = groups, 2021 reIndex = iterable ? [] : crossfilter_index(k, groupCapacity), 2022 add = reduceAdd, 2023 remove = reduceRemove, 2024 initial = reduceInitial, 2025 k0 = k, // old cardinality 2026 i0 = 0, // index of old group 2027 i1 = 0, // index of new record 2028 j, // object id 2029 g0, // old group 2030 x0, // old key 2031 x1, // new key 2032 g, // group to add 2033 x; // key of group to add 2034 2035 // If a reset is needed, we don't need to update the reduce values. 2036 if (resetNeeded) add = initial = crossfilter_null; 2037 if (resetNeeded) remove = initial = crossfilter_null; 2038 2039 // Reset the new groups (k is a lower bound). 2040 // Also, make sure that groupIndex exists and is long enough. 2041 groups = new Array(k), k = 0; 2042 if(iterable){ 2043 groupIndex = k0 ? groupIndex : []; 2044 } 2045 else{ 2046 groupIndex = k0 > 1 ? xfilterArray.arrayLengthen(groupIndex, n) : crossfilter_index(n, groupCapacity); 2047 } 2048 2049 2050 // Get the first old key (x0 of g0), if it exists. 2051 if (k0) x0 = (g0 = oldGroups[0]).key; 2052 2053 // Find the first new key (x1), skipping NaN keys. 2054 while (i1 < n1 && !((x1 = key(newValues[i1])) >= x1)) ++i1; 2055 2056 // While new keys remain… 2057 while (i1 < n1) { 2058 2059 // Determine the lesser of the two current keys; new and old. 2060 // If there are no old keys remaining, then always add the new key. 2061 if (g0 && x0 <= x1) { 2062 g = g0, x = x0; 2063 2064 // Record the new index of the old group. 2065 reIndex[i0] = k; 2066 2067 // Retrieve the next old key. 2068 g0 = oldGroups[++i0]; 2069 if (g0) x0 = g0.key; 2070 } else { 2071 g = {key: x1, value: initial()}, x = x1; 2072 } 2073 2074 // Add the lesser group. 2075 groups[k] = g; 2076 2077 // Add any selected records belonging to the added group, while 2078 // advancing the new key and populating the associated group index. 2079 2080 while (x1 <= x) { 2081 j = newIndex[i1] + (iterable ? n0old : n0) 2082 2083 2084 if(iterable){ 2085 if(groupIndex[j]){ 2086 groupIndex[j].push(k) 2087 } 2088 else{ 2089 groupIndex[j] = [k] 2090 } 2091 } 2092 else{ 2093 groupIndex[j] = k; 2094 } 2095 2096 // Always add new values to groups. Only remove when not in filter. 2097 // This gives groups full information on data life-cycle. 2098 g.value = add(g.value, data[j], true); 2099 if (!filters.zeroExcept(j, offset, zero)) g.value = remove(g.value, data[j], false); 2100 if (++i1 >= n1) break; 2101 x1 = key(newValues[i1]); 2102 } 2103 2104 groupIncrement(); 2105 } 2106 2107 // Add any remaining old groups that were greater th1an all new keys. 2108 // No incremental reduce is needed; these groups have no new records. 2109 // Also record the new index of the old group. 2110 while (i0 < k0) { 2111 groups[reIndex[i0] = k] = oldGroups[i0++]; 2112 groupIncrement(); 2113 } 2114 2115 2116 // Fill in gaps with empty arrays where there may have been rows with empty iterables 2117 if(iterable){ 2118 for (var index1 = 0; index1 < n; index1++) {
2119 if(!groupIndex[index1]){ 2120 groupIndex[index1] = []; 2121 } 2122 } 2123 } 2124 2125 // If we added any new groups before any old groups, 2126 // update the group index of all the old records. 2127 if(k > i0){ 2128 if(iterable){ 2129 for (i0 = 0; i0 < n0old; ++i0) { 2130 for (index1 = 0; index1 < groupIndex[i0].length; index1++) { 2131 groupIndex[i0][index1] = reIndex[groupIndex[i0][index1]]; 2132 } 2133 } 2134 } 2135 else{ 2136 for (i0 = 0; i0 < n0; ++i0) { 2137 groupIndex[i0] = reIndex[groupIndex[i0]]; 2138 } 2139 } 2140 } 2141 2142 // Modify the update and reset behavior based on the cardinality. 2143 // If the cardinality is less than or equal to one, then the groupIndex 2144 // is not needed. If the cardinality is zero, then there are no records 2145 // and therefore no groups to update or reset. Note that we also must 2146 // change the registered listener to point to the new method. 2147 j = filterListeners.indexOf(update); 2148 if (k > 1 || iterable) { 2149 update = updateMany; 2150 reset = resetMany; 2151 } else { 2152 if (!k && groupAll) { 2153 k = 1; 2154 groups = [{key: null, value: initial()}]; 2155 } 2156 if (k === 1) { 2157 update = updateOne; 2158 reset = resetOne; 2159 } else { 2160 update = crossfilter_null; 2161 reset = crossfilter_null; 2162 } 2163 groupIndex = null; 2164 } 2165 filterListeners[j] = update; 2166 2167 // Count the number of added groups, 2168 // and widen the group index as needed. 2169 function groupIncrement() { 2170 if(iterable){ 2171 k++ 2172 return 2173 } 2174 if (++k === groupCapacity) { 2175 reIndex = xfilterArray.arrayWiden(reIndex, groupWidth <<= 1); 2176 groupIndex = xfilterArray.arrayWiden(groupIndex, groupWidth); 2177 groupCapacity = crossfilter_capacity(groupWidth); 2178 } 2179 } 2180 } 2181 2182 function removeData(reIndex) { 2183 if (k > 1 || iterable) { 2184 var oldK = k, 2185 oldGroups = groups, 2186 seenGroups = crossfilter_index(oldK, oldK), 2187 i, 2188 i0, 2189 j; 2190 2191 // Filter out non-matches by copying matching group index entries to 2192 // the beginning of the array. 2193 if (!iterable) { 2194 for (i = 0, j = 0; i < n; ++i) { 2195 if (reIndex[i] !== REMOVED_INDEX) { 2196 seenGroups[groupIndex[j] = groupIndex[i]] = 1; 2197 ++j; 2198 } 2199 } 2200 } else { 2201 for (i = 0, j = 0; i < n; ++i) { 2202 if (reIndex[i] !== REMOVED_INDEX) { 2203 groupIndex[j] = groupIndex[i]; 2204 for (i0 = 0; i0 < groupIndex[j].length; i0++) { 2205 seenGroups[groupIndex[j][i0]] = 1; 2206 } 2207 ++j; 2208 } 2209 } 2210 } 2211 2212 // Reassemble groups including only those groups that were referred 2213 // to by matching group index entries. Note the new group index in 2214 // seenGroups. 2215 groups = [], k = 0; 2216 for (i = 0; i < oldK; ++i) { 2217 if (seenGroups[i]) { 2218 seenGroups[i] = k++; 2219 groups.push(oldGroups[i]); 2220 } 2221 } 2222 2223 if (k > 1 || iterable) { 2224 // Reindex the group index using seenGroups to find the new index. 2225 if (!iterable) { 2226 for (i = 0; i < j; ++i) groupIndex[i] = seenGroups[groupIndex[i]]; 2227 } else { 2228 for (i = 0; i < j; ++i) { 2229 for (i0 = 0; i0 < groupIndex[i].length; ++i0) { 2230 groupIndex[i][i0] = seenGroups[groupIndex[i][i0]]; 2231 } 2232 } 2233 } 2234 } else { 2235 groupIndex = null; 2236 } 2237 filterListeners[filterListeners.indexOf(update)] = k > 1 || iterable 2238 ? (reset = resetMany, update = updateMany) 2239 : k === 1 ? (reset = resetOne, update = updateOne) 2240 : reset = update = crossfilter_null; 2241 } else if (k === 1) { 2242 if (groupAll) return; 2243 for (var index3 = 0; index3 < n; ++index3) if (reIndex[index3] !== REMOVED_INDEX) return; 2244 groups = [], k = 0; 2245 filterListeners[filterListeners.indexOf(update)] = 2246 update = reset = crossfilter_null; 2247 } 2248 } 2249 2250 // Reduces the specified selected or deselected records. 2251 // This function is only used when the cardinality is greater than 1. 2252 // notFilter indicates a crossfilter.add/remove operation. 2253 function updateMany(filterOne, filterOffset, added, removed, notFilter) { 2254 2255 if ((filterOne === one && filterOffset === offset) || resetNeeded) return; 2256 2257 var i, 2258 j, 2259 k, 2260 n, 2261 g; 2262 2263 if(iterable){ 2264 // Add the added values. 2265 for (i = 0, n = added.length; i < n; ++i) { 2266 if (filters.zeroExcept(k = added[i], offset, zero)) { 2267 for (j = 0; j < groupIndex[k].length; j++) { 2268 g = groups[groupIndex[k][j]]; 2269 g.value = reduceAdd(g.value, data[k], false, j); 2270 } 2271 } 2272 } 2273 2274 // Remove the removed values. 2275 for (i = 0, n = removed.length; i < n; ++i) { 2276 if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) { 2277 for (j = 0; j < groupIndex[k].length; j++) { 2278 g = groups[groupIndex[k][j]]; 2279 g.value = reduceRemove(g.value, data[k], notFilter, j); 2280 } 2281 } 2282 } 2283 return; 2284 } 2285 2286 // Add the added values. 2287 for (i = 0, n = added.length; i < n; ++i) { 2288 if (filters.zeroExcept(k = added[i], offset, zero)) { 2289 g = groups[groupIndex[k]]; 2290 g.value = reduceAdd(g.value, data[k], false); 2291 } 2292 } 2293 2294 // Remove the removed values. 2295 for (i = 0, n = removed.length; i < n; ++i) { 2296 if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) { 2297 g = groups[groupIndex[k]]; 2298 g.value = reduceRemove(g.value, data[k], notFilter); 2299 } 2300 } 2301 } 2302 2303 // Reduces the specified selected or deselected records. 2304 // This function is only used when the cardinality is 1. 2305 // notFilter indicates a crossfilter.add/remove operation. 2306 function updateOne(filterOne, filterOffset, added, removed, notFilter) { 2307 if ((filterOne === one && filterOffset === offset) || resetNeeded) return; 2308 2309 var i, 2310 k, 2311 n, 2312 g = groups[0]; 2313 2314 // Add the added values. 2315 for (i = 0, n = added.length; i < n; ++i) { 2316 if (filters.zeroExcept(k = added[i], offset, zero)) { 2317 g.value = reduceAdd(g.value, data[k], false); 2318 } 2319 } 2320 2321 // Remove the removed values. 2322 for (i = 0, n = removed.length; i < n; ++i) { 2323 if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) { 2324 g.value = reduceRemove(g.value, data[k], notFilter); 2325 } 2326 } 2327 } 2328 2329 // Recomputes the group reduce values from scratch. 2330 // This function is only used when the cardinality is greater than 1. 2331 function resetMany() { 2332 var i, 2333 j, 2334 g; 2335 2336 // Reset all group values. 2337 for (i = 0; i < k; ++i) { 2338 groups[i].value = reduceInitial(); 2339 } 2340 2341 // We add all records and then remove filtered records so that reducers 2342 // can build an 'unfiltered' view even if there are already filters in 2343 // place on other dimensions. 2344 if(iterable){ 2345 for (i = 0; i < n; ++i) { 2346 for (j = 0; j < groupIndex[i].length; j++) { 2347 g = groups[groupIndex[i][j]]; 2348 g.value = reduceAdd(g.value, data[i], true, j); 2349 } 2350 } 2351 for (i = 0; i < n; ++i) { 2352 if (!filters.zeroExcept(i, offset, zero)) { 2353 for (j = 0; j < groupIndex[i].length; j++) { 2354 g = groups[groupIndex[i][j]]; 2355 g.value = reduceRemove(g.value, data[i], false, j); 2356 } 2357 } 2358 } 2359 return; 2360 } 2361 2362 for (i = 0; i < n; ++i) { 2363 g = groups[groupIndex[i]]; 2364 g.value = reduceAdd(g.value, data[i], true); 2365 } 2366 for (i = 0; i < n; ++i) { 2367 if (!filters.zeroExcept(i, offset, zero)) { 2368 g = groups[groupIndex[i]]; 2369 g.value = reduceRemove(g.value, data[i], false); 2370 } 2371 } 2372 } 2373 2374 // Recomputes the group reduce values from scratch. 2375 // This function is only used when the cardinality is 1. 2376 function resetOne() { 2377 var i, 2378 g = groups[0]; 2379 2380 // Reset the singleton group values. 2381 g.value = reduceInitial(); 2382 2383 // We add all records and then remove filtered records so that reducers 2384 // can build an 'unfiltered' view even if there are already filters in 2385 // place on other dimensions. 2386 for (i = 0; i < n; ++i) { 2387 g.value = reduceAdd(g.value, data[i], true); 2388 } 2389 2390 for (i = 0; i < n; ++i) { 2391 if (!filters.zeroExcept(i, offset, zero)) { 2392 g.value = reduceRemove(g.value, data[i], false); 2393 } 2394 } 2395 } 2396 2397 // Returns the array of group values, in the dimension's natural order. 2398 function all() {
2399 if (resetNeeded) reset(), resetNeeded = false; 2400 return groups; 2401 } 2402 2403 // Returns a new array containing the top K group values, in reduce order. 2404 function top(k) { 2405 var top = select(all(), 0, groups.length, k); 2406 return heap.sort(top, 0, top.length); 2407 } 2408 2409 // Sets the reduce behavior for this group to use the specified functions. 2410 // This method lazily recomputes the reduce values, waiting until needed. 2411 function reduce(add, remove, initial) { 2412 reduceAdd = add; 2413 reduceRemove = remove; 2414 reduceInitial = initial; 2415 resetNeeded = true; 2416 return group; 2417 } 2418 2419 // A convenience method for reducing by count. 2420 function reduceCount() { 2421 return reduce(xfilterReduce.reduceIncrement, xfilterReduce.reduceDecrement, crossfilter_zero); 2422 } 2423 2424 // A convenience method for reducing by sum(value). 2425 function reduceSum(value) { 2426 return reduce(xfilterReduce.reduceAdd(value), xfilterReduce.reduceSubtract(value), crossfilter_zero); 2427 } 2428 2429 // Sets the reduce order, using the specified accessor. 2430 function order(value) { 2431 select = xfilterHeapselect.by(valueOf); 2432 heap = xfilterHeap.by(valueOf); 2433 function valueOf(d) { return value(d.value); } 2434 return group; 2435 } 2436 2437 // A convenience method for natural ordering by reduce value. 2438 function orderNatural() { 2439 return order(crossfilter_identity); 2440 } 2441 2442 // Returns the cardinality of this group, irrespective of any filters. 2443 function size() { 2444 return k; 2445 } 2446 2447 // Removes this group and associated event listeners. 2448 function dispose() { 2449 var i = filterListeners.indexOf(update); 2450 if (i >= 0) filterListeners.splice(i, 1); 2451 i = indexListeners.indexOf(add); 2452 if (i >= 0) indexListeners.splice(i, 1); 2453 i = removeDataListeners.indexOf(removeData); 2454 if (i >= 0) removeDataListeners.splice(i, 1); 2455 i = dimensionGroups.indexOf(group); 2456 if (i >= 0) dimensionGroups.splice(i, 1); 2457 return group; 2458 } 2459 2460 return reduceCount().orderNatural(); 2461 } 2462 2463 // A convenience function for generating a singleton group. 2464 function groupAll() { 2465 var g = group(crossfilter_null), all = g.all; 2466 delete g.all; 2467 delete g.top; 2468 delete g.order; 2469 delete g.orderNatural; 2470 delete g.size; 2471 g.value = function() { return all()[0].value; }; 2472 return g; 2473 } 2474 2475 // Removes this dimension and associated groups and event listeners. 2476 function dispose() { 2477 dimensionGroups.forEach(function(group) { group.dispose(); }); 2478 var i = dataListeners.indexOf(preAdd); 2479 if (i >= 0) dataListeners.splice(i, 1); 2480 i = dataListeners.indexOf(postAdd); 2481 if (i >= 0) dataListeners.splice(i, 1); 2482 i = removeDataListeners.indexOf(removeData); 2483 if (i >= 0) removeDataListeners.splice(i, 1); 2484 filters.masks[offset] &= zero; 2485 return filterAll(); 2486 } 2487 2488 return dimension; 2489 } 2490 2491 // A convenience method for groupAll on a dummy dimension. 2492 // This implementation can be optimized since it always has cardinality 1. 2493 function groupAll() { 2494 var group = { 2495 reduce: reduce, 2496 reduceCount: reduceCount, 2497 reduceSum: reduceSum, 2498 value: value, 2499 dispose: dispose, 2500 remove: dispose // for backwards-compatibility 2501 }; 2502 2503 var reduceValue, 2504 reduceAdd, 2505 reduceRemove, 2506 reduceInitial, 2507 resetNeeded = true; 2508 2509 // The group listens to the crossfilter for when any dimension changes, so 2510 // that it can update the reduce value. It must also listen to the parent 2511 // dimension for when data is added. 2512 filterListeners.push(update); 2513 dataListeners.push(add); 2514 2515 // For consistency; actually a no-op since resetNeeded is true. 2516 add(data, 0, n); 2517 2518 // Incorporates the specified new values into this group. 2519 function add(newData, n0) { 2520 var i; 2521 2522 if (resetNeeded) return; 2523 2524 // Cycle through all the values. 2525 for (i = n0; i < n; ++i) { 2526 2527 // Add all values all the time. 2528 reduceValue = reduceAdd(reduceValue, data[i], true); 2529 2530 // Remove the value if filtered. 2531 if (!filters.zero(i)) { 2532 reduceValue = reduceRemove(reduceValue, data[i], false); 2533 } 2534 } 2535 } 2536 2537 // Reduces the specified selected or deselected records. 2538 function update(filterOne, filterOffset, added, removed, notFilter) { 2539 var i, 2540 k, 2541 n; 2542 2543 if (resetNeeded) return; 2544 2545 // Add the added values. 2546 for (i = 0, n = added.length; i < n; ++i) { 2547 if (filters.zero(k = added[i])) { 2548 reduceValue = reduceAdd(reduceValue, data[k], notFilter); 2549 } 2550 } 2551 2552 // Remove the removed values. 2553 for (i = 0, n = removed.length; i < n; ++i) { 2554 if (filters.only(k = removed[i], filterOffset, filterOne)) { 2555 reduceValue = reduceRemove(reduceValue, data[k], notFilter); 2556 } 2557 } 2558 } 2559 2560 // Recomputes the group reduce value from scratch. 2561 function reset() { 2562 var i; 2563 2564 reduceValue = reduceInitial(); 2565 2566 // Cycle through all the values. 2567 for (i = 0; i < n; ++i) { 2568 2569 // Add all values all the time. 2570 reduceValue = reduceAdd(reduceValue, data[i], true); 2571 2572 // Remove the value if it is filtered. 2573 if (!filters.zero(i)) { 2574 reduceValue = reduceRemove(reduceValue, data[i], false); 2575 } 2576 } 2577 } 2578 2579 // Sets the reduce behavior for this group to use the specified functions. 2580 // This method lazily recomputes the reduce value, waiting until needed. 2581 function reduce(add, remove, initial) { 2582 reduceAdd = add; 2583 reduceRemove = remove; 2584 reduceInitial = initial;
2585 resetNeeded = true; 2586 return group; 2587 } 2588 2589 // A convenience method for reducing by count. 2590 function reduceCount() { 2591 return reduce(xfilterReduce.reduceIncrement, xfilterReduce.reduceDecrement, crossfilter_zero); 2592 } 2593 2594 // A convenience method for reducing by sum(value). 2595 function reduceSum(value) { 2596 return reduce(xfilterReduce.reduceAdd(value), xfilterReduce.reduceSubtract(value), crossfilter_zero); 2597 } 2598 2599 // Returns the computed reduce value. 2600 function value() { 2601 if (resetNeeded) reset(), resetNeeded = false; 2602 return reduceValue; 2603 } 2604 2605 // Removes this group and associated event listeners. 2606 function dispose() { 2607 var i = filterListeners.indexOf(update); 2608 if (i >= 0) filterListeners.splice(i, 1); 2609 i = dataListeners.indexOf(add); 2610 if (i >= 0) dataListeners.splice(i, 1); 2611 return group; 2612 } 2613 2614 return reduceCount(); 2615 } 2616 2617 // Returns the number of records in this crossfilter, irrespective of any filters. 2618 function size() { 2619 return n; 2620 } 2621 2622 // Returns the raw row data contained in this crossfilter 2623 function all(){ 2624 return data; 2625 } 2626 2627 // Returns row data with all dimension filters applied, except for filters in ignore_dimensions 2628 function allFiltered(ignore_dimensions) { 2629 var array = [], 2630 i = 0, 2631 mask = maskForDimensions(ignore_dimensions || []); 2632 2633 for (i = 0; i < n; i++) { 2634 if (filters.zeroExceptMask(i, mask)) { 2635 array.push(data[i]); 2636 } 2637 } 2638 2639 return array; 2640 } 2641 2642 function onChange(cb){ 2643 if(typeof cb !== 'function'){ 2644 /* eslint no-console: 0 */ 2645 console.warn('onChange callback parameter must be a function!'); 2646 return; 2647 } 2648 callbacks.push(cb); 2649 return function(){ 2650 callbacks.splice(callbacks.indexOf(cb), 1); 2651 }; 2652 } 2653 2654 function triggerOnChange(eventName){ 2655 for (var i = 0; i < callbacks.length; i++) { 2656 callbacks[i](eventName); 2657 } 2658 } 2659 2660 return arguments.length 2661 ? add(arguments[0]) 2662 : crossfilter; 2663} 2664 2665// Returns an array of size n, big enough to store ids up to m. 2666function crossfilter_index(n, m) { 2667 return (m < 0x101 2668 ? xfilterArray.array8 : m < 0x10001 2669 ? xfilterArray.array16 2670 : xfilterArray.array32)(n); 2671} 2672 2673// Constructs a new array of size n, with sequential values from 0 to n - 1. 2674function crossfilter_range(n) { 2675 var range = crossfilter_index(n, n); 2676 for (var i = -1; ++i < n;) range[i] = i; 2677 return range; 2678} 2679 2680function crossfilter_capacity(w) { 2681 return w === 8 2682 ? 0x100 : w === 16 2683 ? 0x10000 2684 : 0x100000000; 2685} 2686 2687},{"./../package.json":3,"./array":4,"./bisect":5,"./filter":7,"./heap":8,"./heapselect":9,"./identity":10,"./insertionsort":11,"./null":12,"./permute":13,"./quicksort":14,"./reduce":15,"./zero":16,"lodash.result":2}],7:[function(require,module,exports){ 2688'use strict'; 2689 2690function crossfilter_filterExact(bisect, value) { 2691 return function(values) { 2692 var n = values.length; 2693 return [bisect.left(values, value, 0, n), bisect.right(values, value, 0, n)]; 2694 }; 2695} 2696 2697function crossfilter_filterRange(bisect, range) { 2698 var min = range[0], 2699 max = range[1]; 2700 return function(values) { 2701 var n = values.length; 2702 return [bisect.left(values, min, 0, n), bisect.left(values, max, 0, n)]; 2703 }; 2704} 2705 2706function crossfilter_filterAll(values) { 2707 return [0, values.length]; 2708} 2709 2710module.exports = { 2711 filterExact: crossfilter_filterExact, 2712 filterRange: crossfilter_filterRange, 2713 filterAll: crossfilter_filterAll 2714}; 2715 2716},{}],8:[function(require,module,exports){ 2717'use strict'; 2718 2719var crossfilter_identity = require('./identity'); 2720 2721function heap_by(f) { 2722 2723 // Builds a binary heap within the specified array a[lo:hi]. The heap has the 2724 // property such that the parent a[lo+i] is always less than or equal to its 2725 // two children: a[lo+2*i+1] and a[lo+2*i+2]. 2726 function heap(a, lo, hi) { 2727 var n = hi - lo, 2728 i = (n >>> 1) + 1; 2729 while (--i > 0) sift(a, i, n, lo); 2730 return a; 2731 } 2732 2733 // Sorts the specified array a[lo:hi] in descending order, assuming it is 2734 // already a heap. 2735 function sort(a, lo, hi) { 2736 var n = hi - lo, 2737 t; 2738 while (--n > 0) t = a[lo], a[lo] = a[lo + n], a[lo + n] = t, sift(a, 1, n, lo); 2739 return a; 2740 } 2741 2742 // Sifts the element a[lo+i-1] down the heap, where the heap is the contiguous 2743 // slice of array a[lo:lo+n]. This method can also be used to update the heap 2744 // incrementally, without incurring the full cost of reconstructing the heap. 2745 function sift(a, i, n, lo) { 2746 var d = a[--lo + i], 2747 x = f(d), 2748 child; 2749 while ((child = i << 1) <= n) { 2750 if (child < n && f(a[lo + child]) > f(a[lo + child + 1])) child++; 2751 if (x <= f(a[lo + child])) break; 2752 a[lo + i] = a[lo + child]; 2753 i = child; 2754 } 2755 a[lo + i] = d; 2756 } 2757 2758 heap.sort = sort; 2759 return heap; 2760} 2761 2762module.exports = heap_by(crossfilter_identity); 2763module.exports.by = heap_by; 2764 2765},{"./identity":10}],9:[function(require,module,exports){ 2766'use strict'; 2767 2768var crossfilter_identity = require('./identity'); 2769var xFilterHeap = require('./heap'); 2770 2771function heapselect_by(f) { 2772 var heap = xFilterHeap.by(f); 2773 2774 // Returns a new array containing the top k elements in the array a[lo:hi]. 2775 // The returned array is not sorted, but maintains the heap property. If k is 2776 // greater than hi - lo, then fewer than k elements will be returned. The 2777 // order of elements in a is unchanged by this operation. 2778 function heapselect(a, lo, hi, k) { 2779 var queue = new Array(k = Math.min(hi - lo, k)), 2780 min, 2781 i, 2782 d; 2783 2784 for (i = 0; i < k; ++i) queue[i] = a[lo++];
2785 heap(queue, 0, k); 2786 2787 if (lo < hi) { 2788 min = f(queue[0]); 2789 do { 2790 if (f(d = a[lo]) > min) { 2791 queue[0] = d; 2792 min = f(heap(queue, 0, k)[0]); 2793 } 2794 } while (++lo < hi); 2795 } 2796 2797 return queue; 2798 } 2799 2800 return heapselect; 2801} 2802 2803module.exports = heapselect_by(crossfilter_identity); 2804module.exports.by = heapselect_by; // assign the raw function to the export as well 2805 2806},{"./heap":8,"./identity":10}],10:[function(require,module,exports){ 2807'use strict'; 2808 2809function crossfilter_identity(d) { 2810 return d; 2811} 2812 2813module.exports = crossfilter_identity; 2814 2815},{}],11:[function(require,module,exports){ 2816'use strict'; 2817 2818var crossfilter_identity = require('./identity'); 2819 2820function insertionsort_by(f) { 2821 2822 function insertionsort(a, lo, hi) { 2823 for (var i = lo + 1; i < hi; ++i) { 2824 for (var j = i, t = a[i], x = f(t); j > lo && f(a[j - 1]) > x; --j) { 2825 a[j] = a[j - 1]; 2826 } 2827 a[j] = t; 2828 } 2829 return a; 2830 } 2831 2832 return insertionsort; 2833} 2834 2835module.exports = insertionsort_by(crossfilter_identity); 2836module.exports.by = insertionsort_by; 2837 2838},{"./identity":10}],12:[function(require,module,exports){ 2839'use strict'; 2840 2841function crossfilter_null() { 2842 return null; 2843} 2844 2845module.exports = crossfilter_null; 2846 2847},{}],13:[function(require,module,exports){ 2848'use strict'; 2849 2850function permute(array, index, deep) { 2851 for (var i = 0, n = index.length, copy = deep ? JSON.parse(JSON.stringify(array)) : new Array(n); i < n; ++i) { 2852 copy[i] = array[index[i]]; 2853 } 2854 return copy; 2855} 2856 2857module.exports = permute; 2858 2859},{}],14:[function(require,module,exports){ 2860var crossfilter_identity = require('./identity'); 2861var xFilterInsertionsort = require('./insertionsort'); 2862 2863// Algorithm designed by Vladimir Yaroslavskiy. 2864// Implementation based on the Dart project; see NOTICE and AUTHORS for details. 2865 2866function quicksort_by(f) { 2867 var insertionsort = xFilterInsertionsort.by(f); 2868 2869 function sort(a, lo, hi) { 2870 return (hi - lo < quicksort_sizeThreshold 2871 ? insertionsort 2872 : quicksort)(a, lo, hi); 2873 } 2874 2875 function quicksort(a, lo, hi) { 2876 // Compute the two pivots by looking at 5 elements. 2877 var sixth = (hi - lo) / 6 | 0, 2878 i1 = lo + sixth, 2879 i5 = hi - 1 - sixth, 2880 i3 = lo + hi - 1 >> 1, // The midpoint. 2881 i2 = i3 - sixth, 2882 i4 = i3 + sixth; 2883 2884 var e1 = a[i1], x1 = f(e1), 2885 e2 = a[i2], x2 = f(e2), 2886 e3 = a[i3], x3 = f(e3), 2887 e4 = a[i4], x4 = f(e4), 2888 e5 = a[i5], x5 = f(e5); 2889 2890 var t; 2891 2892 // Sort the selected 5 elements using a sorting network. 2893 if (x1 > x2) t = e1, e1 = e2, e2 = t, t = x1, x1 = x2, x2 = t; 2894 if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t; 2895 if (x1 > x3) t = e1, e1 = e3, e3 = t, t = x1, x1 = x3, x3 = t; 2896 if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t; 2897 if (x1 > x4) t = e1, e1 = e4, e4 = t, t = x1, x1 = x4, x4 = t; 2898 if (x3 > x4) t = e3, e3 = e4, e4 = t, t = x3, x3 = x4, x4 = t; 2899 if (x2 > x5) t = e2, e2 = e5, e5 = t, t = x2, x2 = x5, x5 = t; 2900 if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t; 2901 if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t; 2902 2903 var pivot1 = e2, pivotValue1 = x2, 2904 pivot2 = e4, pivotValue2 = x4; 2905 2906 // e2 and e4 have been saved in the pivot variables. They will be written 2907 // back, once the partitioning is finished. 2908 a[i1] = e1; 2909 a[i2] = a[lo]; 2910 a[i3] = e3; 2911 a[i4] = a[hi - 1]; 2912 a[i5] = e5; 2913 2914 var less = lo + 1, // First element in the middle partition. 2915 great = hi - 2; // Last element in the middle partition. 2916 2917 // Note that for value comparison, <, <=, >= and > coerce to a primitive via 2918 // Object.prototype.valueOf; == and === do not, so in order to be consistent 2919 // with natural order (such as for Date objects), we must do two compares. 2920 var pivotsEqual = pivotValue1 <= pivotValue2 && pivotValue1 >= pivotValue2; 2921 if (pivotsEqual) { 2922 2923 // Degenerated case where the partitioning becomes a dutch national flag 2924 // problem. 2925 // 2926 // [ | < pivot | == pivot | unpartitioned | > pivot | ] 2927 // ^ ^ ^ ^ ^ 2928 // left less k great right 2929 // 2930 // a[left] and a[right] are undefined and are filled after the 2931 // partitioning. 2932 // 2933 // Invariants: 2934 // 1) for x in ]left, less[ : x < pivot. 2935 // 2) for x in [less, k[ : x == pivot. 2936 // 3) for x in ]great, right[ : x > pivot. 2937 for (var k = less; k <= great; ++k) { 2938 var ek = a[k], xk = f(ek); 2939 if (xk < pivotValue1) { 2940 if (k !== less) { 2941 a[k] = a[less]; 2942 a[less] = ek; 2943 } 2944 ++less; 2945 } else if (xk > pivotValue1) { 2946 2947 // Find the first element <= pivot in the range [k - 1, great] and 2948 // put [:ek:] there. We know that such an element must exist: 2949 // When k == less, then el3 (which is equal to pivot) lies in the 2950 // interval. Otherwise a[k - 1] == pivot and the search stops at k-1. 2951 // Note that in the latter case invariant 2 will be violated for a 2952 // short amount of time. The invariant will be restored when the 2953 // pivots are put into their final positions. 2954 /* eslint no-constant-condition: 0 */ 2955 while (true) { 2956 var greatValue = f(a[great]); 2957 if (greatValue > pivotValue1) { 2958 great--; 2959 // This is the only location in the while-loop where a new 2960 // iteration is started. 2961 continue; 2962 } else if (greatValue < pivotValue1) { 2963 // Triple exchange. 2964 a[k] = a[less]; 2965 a[less++] = a[great]; 2966 a[great--] = ek; 2967 break; 2968 } else { 2969 a[k] = a[great]; 2970 a[great--] = ek; 2971 // Note: if great < k then we will exit the outer loop and fix 2972 // invariant 2 (which we just violated). 2973 break; 2974 } 2975 } 2976 } 2977 } 2978 } else { 2979 2980 // We partition the list into three parts: 2981 // 1. < pivot1 2982 // 2. >= pivot1 && <= pivot2 2983 // 3. > pivot2 2984 // 2985 // During the loop we have: 2986 // [ | < pivot1 | >= pivot1 && <= pivot2 | unpartitioned | > pivot2 | ] 2987 // ^ ^ ^ ^ ^ 2988 // left less k great right 2989 // 2990 // a[left] and a[right] are undefined and are filled after the 2991 // partitioning. 2992 // 2993 // Invariants: 2994 // 1. for x in ]left, less[ : x < pivot1 2995 // 2. for x in [less, k[ : pivot1 <= x && x <= pivot2 2996 // 3. for x in ]great, right[ : x > pivot2 2997 (function () { // isolate scope 2998 for (var k = less; k <= great; k++) { 2999 var ek = a[k], xk = f(ek); 3000 if (xk < pivotValue1) { 3001 if (k !== less) { 3002 a[k] = a[less]; 3003 a[less] = ek; 3004 } 3005 ++less; 3006 } else { 3007 if (xk > pivotValue2) { 3008 while (true) { 3009 var greatValue = f(a[great]); 3010 if (greatValue > pivotValue2) { 3011 great--; 3012 if (great < k) break; 3013 // This is the only location inside the loop where a new 3014 // iteration is started. 3015 continue; 3016 } else { 3017 // a[great] <= pivot2. 3018 if (greatValue < pivotValue1) { 3019 // Triple exchange. 3020 a[k] = a[less]; 3021 a[less++] = a[great]; 3022 a[great--] = ek; 3023 } else { 3024 // a[great] >= pivot1. 3025 a[k] = a[great]; 3026 a[great--] = ek; 3027 } 3028 break; 3029 } 3030 } 3031 } 3032 } 3033 } 3034 })(); // isolate scope 3035 } 3036 3037 // Move pivots into their final positions.
3038 // We shrunk the list from both sides (a[left] and a[right] have 3039 // meaningless values in them) and now we move elements from the first 3040 // and third partition into these locations so that we can store the 3041 // pivots. 3042 a[lo] = a[less - 1]; 3043 a[less - 1] = pivot1; 3044 a[hi - 1] = a[great + 1]; 3045 a[great + 1] = pivot2; 3046 3047 // The list is now partitioned into three partitions: 3048 // [ < pivot1 | >= pivot1 && <= pivot2 | > pivot2 ] 3049 // ^ ^ ^ ^ 3050 // left less great right 3051 3052 // Recursive descent. (Don't include the pivot values.) 3053 sort(a, lo, less - 1); 3054 sort(a, great + 2, hi); 3055 3056 if (pivotsEqual) { 3057 // All elements in the second partition are equal to the pivot. No 3058 // need to sort them. 3059 return a; 3060 } 3061 3062 // In theory it should be enough to call _doSort recursively on the second 3063 // partition. 3064 // The Android source however removes the pivot elements from the recursive 3065 // call if the second partition is too large (more than 2/3 of the list). 3066 if (less < i1 && great > i5) { 3067 3068 (function () { // isolate scope 3069 var lessValue, greatValue; 3070 while ((lessValue = f(a[less])) <= pivotValue1 && lessValue >= pivotValue1) ++less; 3071 while ((greatValue = f(a[great])) <= pivotValue2 && greatValue >= pivotValue2) --great; 3072 3073 // Copy paste of the previous 3-way partitioning with adaptions. 3074 // 3075 // We partition the list into three parts: 3076 // 1. == pivot1 3077 // 2. > pivot1 && < pivot2 3078 // 3. == pivot2 3079 // 3080 // During the loop we have: 3081 // [ == pivot1 | > pivot1 && < pivot2 | unpartitioned | == pivot2 ] 3082 // ^ ^ ^ 3083 // less k great 3084 // 3085 // Invariants: 3086 // 1. for x in [ *, less[ : x == pivot1 3087 // 2. for x in [less, k[ : pivot1 < x && x < pivot2 3088 // 3. for x in ]great, * ] : x == pivot2 3089 for (var k = less; k <= great; k++) { 3090 var ek = a[k], xk = f(ek); 3091 if (xk <= pivotValue1 && xk >= pivotValue1) { 3092 if (k !== less) { 3093 a[k] = a[less]; 3094 a[less] = ek; 3095 } 3096 less++; 3097 } else { 3098 if (xk <= pivotValue2 && xk >= pivotValue2) { 3099 /* eslint no-constant-condition: 0 */ 3100 while (true) { 3101 greatValue = f(a[great]); 3102 if (greatValue <= pivotValue2 && greatValue >= pivotValue2) { 3103 great--; 3104 if (great < k) break; 3105 // This is the only location inside the loop where a new 3106 // iteration is started. 3107 continue; 3108 } else { 3109 // a[great] < pivot2. 3110 if (greatValue < pivotValue1) { 3111 // Triple exchange. 3112 a[k] = a[less]; 3113 a[less++] = a[great]; 3114 a[great--] = ek; 3115 } else { 3116 // a[great] == pivot1. 3117 a[k] = a[great]; 3118 a[great--] = ek; 3119 } 3120 break; 3121 } 3122 } 3123 } 3124 } 3125 } 3126 })(); // isolate scope 3127 3128 } 3129 3130 // The second partition has now been cleared of pivot elements and looks 3131 // as follows: 3132 // [ * | > pivot1 && < pivot2 | * ] 3133 // ^ ^ 3134 // less great 3135 // Sort the second partition using recursive descent. 3136 3137 // The second partition looks as follows: 3138 // [ * | >= pivot1 && <= pivot2 | * ] 3139 // ^ ^ 3140 // less great 3141 // Simply sort it by recursive descent. 3142 3143 return sort(a, less, great + 1); 3144 } 3145 3146 return sort; 3147} 3148 3149var quicksort_sizeThreshold = 32; 3150 3151module.exports = quicksort_by(crossfilter_identity); 3152module.exports.by = quicksort_by; 3153 3154},{"./identity":10,"./insertionsort":11}],15:[function(require,module,exports){ 3155'use strict'; 3156 3157function crossfilter_reduceIncrement(p) { 3158 return p + 1; 3159} 3160
3161function crossfilter_reduceDecrement(p) { 3162 return p - 1; 3163} 3164 3165function crossfilter_reduceAdd(f) { 3166 return function(p, v) { 3167 return p + +f(v); 3168 }; 3169} 3170 3171function crossfilter_reduceSubtract(f) { 3172 return function(p, v) { 3173 return p - f(v); 3174 }; 3175} 3176 3177module.exports = { 3178 reduceIncrement: crossfilter_reduceIncrement, 3179 reduceDecrement: crossfilter_reduceDecrement, 3180 reduceAdd: crossfilter_reduceAdd, 3181 reduceSubtract: crossfilter_reduceSubtract 3182}; 3183 3184},{}],16:[function(require,module,exports){ 3185'use strict'; 3186 3187function crossfilter_zero() { 3188 return 0; 3189} 3190 3191module.exports = crossfilter_zero; 3192 3193},{}]},{},[1])(1) 3194});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.