vendor: 34,215 bytes, lines 1-962
1/*! 2 * typeahead.js 0.11.1 3 * https://github.com/twitter/typeahead.js 4 * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT 5 */ 6 7(function (root, factory) { 8 if (typeof define === "function" && define.amd) { 9 define("bloodhound", ["jquery"], function (a0) { 10 return (root["Bloodhound"] = factory(a0)); 11 }); 12 } else if (typeof exports === "object") { 13 module.exports = factory(require("jquery")); 14 } else { 15 root["Bloodhound"] = factory(jQuery); 16 } 17})(this, function ($) { 18 var _ = (function () { 19 "use strict"; 20 return { 21 isMsie: function () { 22 return /(msie|trident)/i.test(navigator.userAgent) 23 ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] 24 : false; 25 }, 26 isBlankString: function (str) { 27 return !str || /^\s*$/.test(str); 28 }, 29 escapeRegExChars: function (str) { 30 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 31 }, 32 isString: function (obj) { 33 return typeof obj === "string"; 34 }, 35 isNumber: function (obj) { 36 return typeof obj === "number"; 37 }, 38 isArray: $.isArray, 39 isFunction: $.isFunction, 40 isObject: $.isPlainObject, 41 isUndefined: function (obj) { 42 return typeof obj === "undefined"; 43 }, 44 isElement: function (obj) { 45 return !!(obj && obj.nodeType === 1); 46 }, 47 isJQuery: function (obj) { 48 return obj instanceof $; 49 }, 50 toStr: function toStr(s) { 51 return _.isUndefined(s) || s === null ? "" : s + ""; 52 }, 53 bind: $.proxy, 54 each: function (collection, cb) { 55 $.each(collection, reverseArgs); 56 function reverseArgs(index, value) { 57 return cb(value, index); 58 } 59 }, 60 map: $.map, 61 filter: $.grep, 62 every: function (obj, test) { 63 var result = true; 64 if (!obj) { 65 return result; 66 } 67 $.each(obj, function (key, val) { 68 if (!(result = test.call(null, val, key, obj))) { 69 return false; 70 } 71 }); 72 return !!result; 73 }, 74 some: function (obj, test) { 75 var result = false; 76 if (!obj) { 77 return result; 78 } 79 $.each(obj, function (key, val) { 80 if ((result = test.call(null, val, key, obj))) { 81 return false; 82 } 83 }); 84 return !!result; 85 }, 86 mixin: $.extend, 87 identity: function (x) { 88 return x; 89 }, 90 clone: function (obj) { 91 return $.extend(true, {}, obj); 92 }, 93 getIdGenerator: function () { 94 var counter = 0; 95 return function () { 96 return counter++; 97 }; 98 }, 99 templatify: function templatify(obj) { 100 return $.isFunction(obj) ? obj : template; 101 function template() { 102 return String(obj); 103 } 104 }, 105 defer: function (fn) { 106 setTimeout(fn, 0); 107 }, 108 debounce: function (func, wait, immediate) { 109 var timeout, result; 110 return function () { 111 var context = this, 112 args = arguments, 113 later, 114 callNow; 115 later = function () { 116 timeout = null; 117 if (!immediate) { 118 result = func.apply(context, args); 119 } 120 }; 121 callNow = immediate && !timeout; 122 clearTimeout(timeout); 123 timeout = setTimeout(later, wait); 124 if (callNow) { 125 result = func.apply(context, args); 126 } 127 return result; 128 }; 129 }, 130 throttle: function (func, wait) { 131 var context, args, timeout, result, previous, later; 132 previous = 0; 133 later = function () { 134 previous = new Date(); 135 timeout = null; 136 result = func.apply(context, args); 137 }; 138 return function () { 139 var now = new Date(), 140 remaining = wait - (now - previous); 141 context = this; 142 args = arguments; 143 if (remaining <= 0) { 144 clearTimeout(timeout); 145 timeout = null; 146 previous = now; 147 result = func.apply(context, args); 148 } else if (!timeout) { 149 timeout = setTimeout(later, remaining); 150 } 151 return result; 152 }; 153 }, 154 stringify: function (val) { 155 return _.isString(val) ? val : JSON.stringify(val); 156 }, 157 noop: function () {}, 158 }; 159 })(); 160 var VERSION = "0.11.1"; 161 var tokenizers = (function () { 162 "use strict"; 163 return { 164 nonword: nonword, 165 whitespace: whitespace, 166 obj: { 167 nonword: getObjTokenizer(nonword), 168 whitespace: getObjTokenizer(whitespace), 169 }, 170 }; 171 function whitespace(str) { 172 str = _.toStr(str); 173 return str ? str.split(/\s+/) : []; 174 } 175 function nonword(str) { 176 str = _.toStr(str); 177 return str ? str.split(/\W+/) : []; 178 } 179 function getObjTokenizer(tokenizer) { 180 return function setKey(keys) { 181 keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0); 182 return function tokenize(o) { 183 var tokens = []; 184 _.each(keys, function (k) { 185 tokens = tokens.concat(tokenizer(_.toStr(o[k]))); 186 }); 187 return tokens; 188 }; 189 }; 190 } 191 })(); 192 var LruCache = (function () { 193 "use strict"; 194 function LruCache(maxSize) { 195 this.maxSize = _.isNumber(maxSize) ? maxSize : 100; 196 this.reset(); 197 if (this.maxSize <= 0) { 198 this.set = this.get = $.noop; 199 } 200 } 201 _.mixin(LruCache.prototype, { 202 set: function set(key, val) { 203 var tailItem = this.list.tail, 204 node; 205 if (this.size >= this.maxSize) { 206 this.list.remove(tailItem); 207 delete this.hash[tailItem.key]; 208 this.size--; 209 } 210 if ((node = this.hash[key])) { 211 node.val = val; 212 this.list.moveToFront(node); 213 } else { 214 node = new Node(key, val); 215 this.list.add(node); 216 this.hash[key] = node; 217 this.size++; 218 } 219 }, 220 get: function get(key) { 221 var node = this.hash[key]; 222 if (node) { 223 this.list.moveToFront(node); 224 return node.val; 225 } 226 }, 227 reset: function reset() { 228 this.size = 0; 229 this.hash = {}; 230 this.list = new List(); 231 }, 232 }); 233 function List() { 234 this.head = this.tail = null; 235 } 236 _.mixin(List.prototype, { 237 add: function add(node) { 238 if (this.head) { 239 node.next = this.head; 240 this.head.prev = node; 241 } 242 this.head = node; 243 this.tail = this.tail || node; 244 }, 245 remove: function remove(node) { 246 node.prev ? (node.prev.next = node.next) : (this.head = node.next); 247 node.next ? (node.next.prev = node.prev) : (this.tail = node.prev); 248 }, 249 moveToFront: function (node) { 250 this.remove(node); 251 this.add(node); 252 }, 253 }); 254 function Node(key, val) { 255 this.key = key; 256 this.val = val; 257 this.prev = this.next = null; 258 } 259 return LruCache; 260 })(); 261 var PersistentStorage = (function () { 262 "use strict"; 263 var LOCAL_STORAGE; 264 try { 265 LOCAL_STORAGE = window.localStorage; 266 LOCAL_STORAGE.setItem("~~~", "!"); 267 LOCAL_STORAGE.removeItem("~~~"); 268 } catch (err) { 269 LOCAL_STORAGE = null; 270 } 271 function PersistentStorage(namespace, override) { 272 this.prefix = ["__", namespace, "__"].join(""); 273 this.ttlKey = "__ttl__"; 274 this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix)); 275 this.ls = override || LOCAL_STORAGE; 276 !this.ls && this._noop(); 277 } 278 _.mixin(PersistentStorage.prototype, { 279 _prefix: function (key) { 280 return this.prefix + key; 281 }, 282 _ttlKey: function (key) { 283 return this._prefix(key) + this.ttlKey; 284 }, 285 _noop: function () { 286 this.get = this.set = this.remove = this.clear = this.isExpired = _.noop; 287 }, 288 _safeSet: function (key, val) { 289 try { 290 this.ls.setItem(key, val); 291 } catch (err) { 292 if (err.name === "QuotaExceededError") { 293 this.clear(); 294 this._noop(); 295 } 296 } 297 }, 298 get: function (key) { 299 if (this.isExpired(key)) { 300 this.remove(key); 301 } 302 return decode(this.ls.getItem(this._prefix(key))); 303 }, 304 set: function (key, val, ttl) { 305 if (_.isNumber(ttl)) { 306 this._safeSet(this._ttlKey(key), encode(now() + ttl)); 307 } else { 308 this.ls.removeItem(this._ttlKey(key)); 309 } 310 return this._safeSet(this._prefix(key), encode(val)); 311 }, 312 remove: function (key) { 313 this.ls.removeItem(this._ttlKey(key)); 314 this.ls.removeItem(this._prefix(key)); 315 return this; 316 }, 317 clear: function () { 318 var i, 319 keys = gatherMatchingKeys(this.keyMatcher); 320 for (i = keys.length; i--; ) { 321 this.remove(keys[i]); 322 } 323 return this; 324 }, 325 isExpired: function (key) { 326 var ttl = decode(this.ls.getItem(this._ttlKey(key))); 327 return _.isNumber(ttl) && now() > ttl ? true : false; 328 }, 329 }); 330 return PersistentStorage; 331 function now() { 332 return new Date().getTime(); 333 } 334 function encode(val) { 335 return JSON.stringify(_.isUndefined(val) ? null : val); 336 } 337 function decode(val) { 338 return $.parseJSON(val); 339 } 340 function gatherMatchingKeys(keyMatcher) { 341 var i, 342 key, 343 keys = [], 344 len = LOCAL_STORAGE.length; 345 for (i = 0; i < len; i++) { 346 if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) { 347 keys.push(key.replace(keyMatcher, "")); 348 } 349 } 350 return keys; 351 } 352 })(); 353 var Transport = (function () { 354 "use strict"; 355 var pendingRequestsCount = 0, 356 pendingRequests = {}, 357 maxPendingRequests = 6, 358 sharedCache = new LruCache(10); 359 function Transport(o) { 360 o = o || {}; 361 this.cancelled = false; 362 this.lastReq = null; 363 this._send = o.transport; 364 this._get = o.limiter ? o.limiter(this._get) : this._get; 365 this._cache = o.cache === false ? new LruCache(0) : sharedCache; 366 } 367 Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { 368 maxPendingRequests = num; 369 }; 370 Transport.resetCache = function resetCache() { 371 sharedCache.reset(); 372 }; 373 _.mixin(Transport.prototype, { 374 _fingerprint: function fingerprint(o) { 375 o = o || {}; 376 return o.url + o.type + $.param(o.data || {}); 377 }, 378 _get: function (o, cb) { 379 var that = this, 380 fingerprint, 381 jqXhr; 382 fingerprint = this._fingerprint(o); 383 if (this.cancelled || fingerprint !== this.lastReq) { 384 return; 385 } 386 if ((jqXhr = pendingRequests[fingerprint])) { 387 jqXhr.done(done).fail(fail); 388 } else if (pendingRequestsCount < maxPendingRequests) { 389 pendingRequestsCount++; 390 pendingRequests[fingerprint] = this._send(o) 391 .done(done) 392 .fail(fail) 393 .always(always); 394 } else { 395 this.onDeckRequestArgs = [].slice.call(arguments, 0); 396 } 397 function done(resp) { 398 cb(null, resp); 399 that._cache.set(fingerprint, resp); 400 } 401 function fail() { 402 cb(true); 403 } 404 function always() { 405 pendingRequestsCount--; 406 delete pendingRequests[fingerprint]; 407 if (that.onDeckRequestArgs) { 408 that._get.apply(that, that.onDeckRequestArgs); 409 that.onDeckRequestArgs = null; 410 } 411 } 412 }, 413 get: function (o, cb) { 414 var resp, fingerprint; 415 cb = cb || $.noop; 416 o = _.isString(o) 417 ? { 418 url: o, 419 } 420 : o || {}; 421 fingerprint = this._fingerprint(o); 422 this.cancelled = false; 423 this.lastReq = fingerprint; 424 if ((resp = this._cache.get(fingerprint))) { 425 cb(null, resp); 426 } else { 427 this._get(o, cb); 428 } 429 }, 430 cancel: function () { 431 this.cancelled = true; 432 }, 433 }); 434 return Transport; 435 })(); 436 var SearchIndex = (window.SearchIndex = (function () { 437 "use strict"; 438 var CHILDREN = "c", 439 IDS = "i"; 440 function SearchIndex(o) { 441 o = o || {}; 442 if (!o.datumTokenizer || !o.queryTokenizer) { 443 $.error("datumTokenizer and queryTokenizer are both required"); 444 } 445 this.identify = o.identify || _.stringify; 446 this.datumTokenizer = o.datumTokenizer; 447 this.queryTokenizer = o.queryTokenizer; 448 this.reset(); 449 } 450 _.mixin(SearchIndex.prototype, { 451 bootstrap: function bootstrap(o) { 452 this.datums = o.datums; 453 this.trie = o.trie; 454 }, 455 add: function (data) { 456 var that = this; 457 data = _.isArray(data) ? data : [data]; 458 _.each(data, function (datum) { 459 var id, tokens; 460 that.datums[(id = that.identify(datum))] = datum; 461 tokens = normalizeTokens(that.datumTokenizer(datum)); 462 _.each(tokens, function (token) { 463 var node, chars, ch; 464 node = that.trie; 465 chars = token.split(""); 466 while ((ch = chars.shift())) { 467 node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode()); 468 node[IDS].push(id); 469 } 470 }); 471 }); 472 }, 473 get: function get(ids) { 474 var that = this; 475 return _.map(ids, function (id) { 476 return that.datums[id]; 477 }); 478 }, 479 search: function search(query) { 480 var that = this, 481 tokens, 482 matches; 483 tokens = normalizeTokens(this.queryTokenizer(query)); 484 _.each(tokens, function (token) { 485 var node, chars, ch, ids; 486 if (matches && matches.length === 0) { 487 return false; 488 } 489 node = that.trie; 490 chars = token.split(""); 491 while (node && (ch = chars.shift())) { 492 node = node[CHILDREN][ch]; 493 } 494 if (node && chars.length === 0) { 495 ids = node[IDS].slice(0); 496 matches = matches ? getIntersection(matches, ids) : ids; 497 } else { 498 matches = []; 499 return false; 500 } 501 }); 502 return matches 503 ? _.map(unique(matches), function (id) { 504 return that.datums[id]; 505 }) 506 : []; 507 }, 508 all: function all() { 509 var values = []; 510 for (var key in this.datums) { 511 values.push(this.datums[key]); 512 } 513 return values; 514 }, 515 reset: function reset() { 516 this.datums = {}; 517 this.trie = newNode(); 518 }, 519 serialize: function serialize() { 520 return { 521 datums: this.datums, 522 trie: this.trie, 523 }; 524 }, 525 }); 526 return SearchIndex; 527 function normalizeTokens(tokens) { 528 tokens = _.filter(tokens, function (token) { 529 return !!token; 530 }); 531 tokens = _.map(tokens, function (token) { 532 return token.toLowerCase(); 533 }); 534 return tokens; 535 } 536 function newNode() { 537 var node = {}; 538 node[IDS] = []; 539 node[CHILDREN] = {}; 540 return node; 541 } 542 function unique(array) { 543 var seen = {}, 544 uniques = []; 545 for (var i = 0, len = array.length; i < len; i++) { 546 if (!seen[array[i]]) { 547 seen[array[i]] = true; 548 uniques.push(array[i]); 549 } 550 } 551 return uniques; 552 } 553 function getIntersection(arrayA, arrayB) { 554 var ai = 0, 555 bi = 0, 556 intersection = []; 557 arrayA = arrayA.sort(); 558 arrayB = arrayB.sort(); 559 var lenArrayA = arrayA.length, 560 lenArrayB = arrayB.length; 561 while (ai < lenArrayA && bi < lenArrayB) { 562 if (arrayA[ai] < arrayB[bi]) { 563 ai++; 564 } else if (arrayA[ai] > arrayB[bi]) { 565 bi++; 566 } else { 567 intersection.push(arrayA[ai]); 568 ai++; 569 bi++; 570 } 571 } 572 return intersection; 573 } 574 })()); 575 var Prefetch = (function () { 576 "use strict"; 577 var keys; 578 keys = { 579 data: "data", 580 protocol: "protocol", 581 thumbprint: "thumbprint", 582 }; 583 function Prefetch(o) { 584 this.url = o.url; 585 this.ttl = o.ttl; 586 this.cache = o.cache; 587 this.prepare = o.prepare; 588 this.transform = o.transform; 589 this.transport = o.transport; 590 this.thumbprint = o.thumbprint; 591 this.storage = new PersistentStorage(o.cacheKey); 592 } 593 _.mixin(Prefetch.prototype, { 594 _settings: function settings() { 595 return { 596 url: this.url, 597 type: "GET", 598 dataType: "json", 599 }; 600 }, 601 store: function store(data) { 602 if (!this.cache) { 603 return; 604 } 605 this.storage.set(keys.data, data, this.ttl); 606 this.storage.set(keys.protocol, location.protocol, this.ttl); 607 this.storage.set(keys.thumbprint, this.thumbprint, this.ttl); 608 }, 609 fromCache: function fromCache() { 610 var stored = {}, 611 isExpired; 612 if (!this.cache) { 613 return null; 614 } 615 stored.data = this.storage.get(keys.data); 616 stored.protocol = this.storage.get(keys.protocol); 617 stored.thumbprint = this.storage.get(keys.thumbprint); 618 isExpired = 619 stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol; 620 return stored.data && !isExpired ? stored.data : null; 621 }, 622 fromNetwork: function (cb) { 623 var that = this, 624 settings; 625 if (!cb) { 626 return; 627 } 628 settings = this.prepare(this._settings()); 629 this.transport(settings).fail(onError).done(onResponse); 630 function onError() { 631 cb(true); 632 } 633 function onResponse(resp) { 634 cb(null, that.transform(resp)); 635 } 636 }, 637 clear: function clear() { 638 this.storage.clear(); 639 return this; 640 }, 641 }); 642 return Prefetch; 643 })(); 644 var Remote = (function () { 645 "use strict"; 646 function Remote(o) { 647 this.url = o.url; 648 this.prepare = o.prepare; 649 this.transform = o.transform; 650 this.transport = new Transport({ 651 cache: o.cache, 652 limiter: o.limiter, 653 transport: o.transport, 654 }); 655 } 656 _.mixin(Remote.prototype, { 657 _settings: function settings() { 658 return { 659 url: this.url, 660 type: "GET", 661 dataType: "json", 662 }; 663 }, 664 get: function get(query, cb) { 665 var that = this, 666 settings; 667 if (!cb) { 668 return; 669 } 670 query = query || ""; 671 settings = this.prepare(query, this._settings()); 672 return this.transport.get(settings, onResponse); 673 function onResponse(err, resp) { 674 err ? cb([]) : cb(that.transform(resp)); 675 } 676 }, 677 cancelLastRequest: function cancelLastRequest() { 678 this.transport.cancel(); 679 }, 680 }); 681 return Remote; 682 })(); 683 var oParser = (function () { 684 "use strict"; 685 return function parse(o) { 686 var defaults, sorter; 687 defaults = { 688 initialize: true, 689 identify: _.stringify, 690 datumTokenizer: null, 691 queryTokenizer: null, 692 sufficient: 5, 693 sorter: null, 694 local: [], 695 prefetch: null, 696 remote: null, 697 }; 698 o = _.mixin(defaults, o || {}); 699 !o.datumTokenizer && $.error("datumTokenizer is required"); 700 !o.queryTokenizer && $.error("queryTokenizer is required"); 701 sorter = o.sorter; 702 o.sorter = sorter 703 ? function (x) { 704 return x.sort(sorter); 705 } 706 : _.identity; 707 o.local = _.isFunction(o.local) ? o.local() : o.local; 708 o.prefetch = parsePrefetch(o.prefetch); 709 o.remote = parseRemote(o.remote); 710 return o; 711 }; 712 function parsePrefetch(o) { 713 var defaults; 714 if (!o) { 715 return null; 716 } 717 defaults = { 718 url: null, 719 ttl: 24 * 60 * 60 * 1e3, 720 cache: true, 721 cacheKey: null, 722 thumbprint: "", 723 prepare: _.identity, 724 transform: _.identity, 725 transport: null, 726 }; 727 o = _.isString(o) 728 ? { 729 url: o, 730 } 731 : o; 732 o = _.mixin(defaults, o); 733 !o.url && $.error("prefetch requires url to be set"); 734 o.transform = o.filter || o.transform; 735 o.cacheKey = o.cacheKey || o.url; 736 o.thumbprint = VERSION + o.thumbprint; 737 o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; 738 return o; 739 } 740 function parseRemote(o) { 741 var defaults; 742 if (!o) { 743 return; 744 } 745 defaults = { 746 url: null, 747 cache: true, 748 prepare: null, 749 replace: null, 750 wildcard: null, 751 limiter: null, 752 rateLimitBy: "debounce", 753 rateLimitWait: 300, 754 transform: _.identity, 755 transport: null, 756 }; 757 o = _.isString(o) 758 ? { 759 url: o, 760 } 761 : o; 762 o = _.mixin(defaults, o); 763 !o.url && $.error("remote requires url to be set"); 764 o.transform = o.filter || o.transform; 765 o.prepare = toRemotePrepare(o); 766 o.limiter = toLimiter(o); 767 o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; 768 delete o.replace; 769 delete o.wildcard; 770 delete o.rateLimitBy; 771 delete o.rateLimitWait; 772 return o; 773 } 774 function toRemotePrepare(o) { 775 var prepare, replace, wildcard; 776 prepare = o.prepare; 777 replace = o.replace; 778 wildcard = o.wildcard; 779 if (prepare) { 780 return prepare; 781 } 782 if (replace) { 783 prepare = prepareByReplace; 784 } else if (o.wildcard) { 785 prepare = prepareByWildcard; 786 } else { 787 prepare = idenityPrepare; 788 } 789 return prepare; 790 function prepareByReplace(query, settings) { 791 settings.url = replace(settings.url, query); 792 return settings; 793 } 794 function prepareByWildcard(query, settings) { 795 settings.url = settings.url.replace(wildcard, encodeURIComponent(query)); 796 return settings; 797 } 798 function idenityPrepare(query, settings) { 799 return settings; 800 } 801 } 802 function toLimiter(o) { 803 var limiter, method, wait; 804 limiter = o.limiter; 805 method = o.rateLimitBy; 806 wait = o.rateLimitWait; 807 if (!limiter) { 808 limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait); 809 } 810 return limiter; 811 function debounce(wait) { 812 return function debounce(fn) { 813 return _.debounce(fn, wait); 814 }; 815 } 816 function throttle(wait) { 817 return function throttle(fn) { 818 return _.throttle(fn, wait); 819 }; 820 } 821 } 822 function callbackToDeferred(fn) { 823 return function wrapper(o) { 824 var deferred = $.Deferred(); 825 fn(o, onSuccess, onError); 826 return deferred; 827 function onSuccess(resp) { 828 _.defer(function () { 829 deferred.resolve(resp); 830 }); 831 } 832 function onError(err) { 833 _.defer(function () { 834 deferred.reject(err); 835 }); 836 } 837 }; 838 } 839 })(); 840 var Bloodhound = (function () { 841 "use strict"; 842 var old; 843 old = window && window.Bloodhound; 844 function Bloodhound(o) { 845 o = oParser(o); 846 this.sorter = o.sorter; 847 this.identify = o.identify; 848 this.sufficient = o.sufficient; 849 this.local = o.local; 850 this.remote = o.remote ? new Remote(o.remote) : null; 851 this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null; 852 this.index = new SearchIndex({ 853 identify: this.identify, 854 datumTokenizer: o.datumTokenizer, 855 queryTokenizer: o.queryTokenizer, 856 }); 857 o.initialize !== false && this.initialize(); 858 } 859 Bloodhound.noConflict = function noConflict() { 860 window && (window.Bloodhound = old); 861 return Bloodhound; 862 }; 863 Bloodhound.tokenizers = tokenizers; 864 _.mixin(Bloodhound.prototype, { 865 __ttAdapter: function ttAdapter() { 866 var that = this; 867 return this.remote ? withAsync : withoutAsync; 868 function withAsync(query, sync, async) { 869 return that.search(query, sync, async); 870 } 871 function withoutAsync(query, sync) { 872 return that.search(query, sync); 873 } 874 }, 875 _loadPrefetch: function loadPrefetch() { 876 var that = this, 877 deferred, 878 serialized; 879 deferred = $.Deferred(); 880 if (!this.prefetch) { 881 deferred.resolve(); 882 } else if ((serialized = this.prefetch.fromCache())) { 883 this.index.bootstrap(serialized); 884 deferred.resolve(); 885 } else { 886 this.prefetch.fromNetwork(done); 887 } 888 return deferred.promise(); 889 function done(err, data) { 890 if (err) { 891 return deferred.reject(); 892 } 893 that.add(data); 894 that.prefetch.store(that.index.serialize()); 895 deferred.resolve(); 896 } 897 }, 898 _initialize: function initialize() { 899 var that = this, 900 deferred; 901 this.clear(); 902 (this.initPromise = this._loadPrefetch()).done(addLocalToIndex); 903 return this.initPromise; 904 function addLocalToIndex() { 905 that.add(that.local); 906 } 907 }, 908 initialize: function initialize(force) { 909 return !this.initPromise || force ? this._initialize() : this.initPromise; 910 }, 911 add: function add(data) { 912 this.index.add(data); 913 return this; 914 }, 915 get: function get(ids) { 916 ids = _.isArray(ids) ? ids : [].slice.call(arguments); 917 return this.index.get(ids); 918 }, 919 search: function search(query, sync, async) { 920 var that = this, 921 local; 922 local = this.sorter(this.index.search(query)); 923 sync(this.remote ? local.slice() : local); 924 if (this.remote && local.length < this.sufficient) { 925 this.remote.get(query, processRemote); 926 } else if (this.remote) { 927 this.remote.cancelLastRequest(); 928 } 929 return this; 930 function processRemote(remote) { 931 var nonDuplicates = []; 932 _.each(remote, function (r) { 933 !_.some(local, function (l) { 934 return that.identify(r) === that.identify(l); 935 }) && nonDuplicates.push(r); 936 }); 937 async && async(nonDuplicates); 938 } 939 }, 940 all: function all() { 941 return this.index.all(); 942 }, 943 clear: function clear() { 944 this.index.reset(); 945 return this; 946 }, 947 clearPrefetchCache: function clearPrefetchCache() { 948 this.prefetch && this.prefetch.clear(); 949 return this; 950 }, 951 clearRemoteCache: function clearRemoteCache() { 952 Transport.resetCache(); 953 return this; 954 }, 955 ttAdapter: function ttAdapter() { 956 return this.__ttAdapter(); 957 }, 958 }); 959 return Bloodhound; 960 })(); 961 return Bloodhound; 962});
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.