PageSourceSearch

https://penaviation.com/wp-content/themes/motors/assets/js/typeahead.jquery.min.js?ver=4.0

js penaviation.com collected 2026-09-26 07:51:50 UTC 96,605 bytes, 2,460 lines download raw bytes

vendor: 6,525 bytes, lines 1-184
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 * NOTE: This file has been edited and is not the same as the original one!
8 * #####    ####    ####    ####    ####    ####    ####    ####    ####
9 */
10
11// Stylemix custom function check
12function stm_custom_func_checker(func) {
13    return typeof func === "function";
14}
15
16(function(root, factory) {
17    if (typeof define === "function" && define.amd) {
18        define("bloodhound", [ "jquery" ], function(a0) {
19            return root["Bloodhound"] = factory(a0);
20        });
21    } else if (typeof exports === "object") {
22        module.exports = factory(require("jquery"));
23    } else {
24        root["Bloodhound"] = factory(jQuery);
25    }
26})(this, function($) {
27    var _ = function() {
28        "use strict";
29        return {
30            isMsie: function() {
31                return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
32            },
33            isBlankString: function(str) {
34                return !str || /^\s*$/.test(str);
35            },
36            escapeRegExChars: function(str) {
37                return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
38            },
39            isString: function(obj) {
40                return typeof obj === "string";
41            },
42            isNumber: function(obj) {
43                return typeof obj === "number";
44            },
45            // isArray: $.isArray,
46            // isFunction: $.isFunction,
47            isObject: $.isPlainObject,
48            isUndefined: function(obj) {
49                return typeof obj === "undefined";
50            },
51            isElement: function(obj) {
52                return !!(obj && obj.nodeType === 1);
53            },
54            isJQuery: function(obj) {
55                return obj instanceof $;
56            },
57            toStr: function toStr(s) {
58                return _.isUndefined(s) || s === null ? "" : s + "";
59            },
60            bind: $.proxy,
61            each: function(collection, cb) {
62                $.each(collection, reverseArgs);
63                function reverseArgs(index, value) {
64                    return cb(value, index);
65                }
66            },
67            map: $.map,
68            filter: $.grep,
69            every: function(obj, test) {
70                var result = true;
71                if (!obj) {
72                    return result;
73                }
74                $.each(obj, function(key, val) {
75                    if (!(result = test.call(null, val, key, obj))) {
76                        return false;
77                    }
78                });
79                return !!result;
80            },
81            some: function(obj, test) {
82                var result = false;
83                if (!obj) {
84                    return result;
85                }
86                $.each(obj, function(key, val) {
87                    if (result = test.call(null, val, key, obj)) {
88                        return false;
89                    }
90                });
91                return !!result;
92            },
93            mixin: $.extend,
94            identity: function(x) {
95                return x;
96            },
97            clone: function(obj) {
98                return $.extend(true, {}, obj);
99            },
100            getIdGenerator: function() {
101                var counter = 0;
102                return function() {
103                    return counter++;
104                };
105            },
106            templatify: function templatify(obj) {
107                return stm_custom_func_checker(obj) ? obj : template;
108                function template() {
109                    return String(obj);
110                }
111            },
112            defer: function(fn) {
113                setTimeout(fn, 0);
114            },
115            debounce: function(func, wait, immediate) {
116                var timeout, result;
117                return function() {
118                    var context = this, args = arguments, later, callNow;
119                    later = function() {
120                        timeout = null;
121                        if (!immediate) {
122                            result = func.apply(context, args);
123                        }
124                    };
125                    callNow = immediate && !timeout;
126                    clearTimeout(timeout);
127                    timeout = setTimeout(later, wait);
128                    if (callNow) {
129                        result = func.apply(context, args);
130                    }
131                    return result;
132                };
133            },
134            throttle: function(func, wait) {
135                var context, args, timeout, result, previous, later;
136                previous = 0;
137                later = function() {
138                    previous = new Date();
139                    timeout = null;
140                    result = func.apply(context, args);
141                };
142                return function() {
143                    var now = new Date(), remaining = wait - (now - previous);
144                    context = this;
145                    args = arguments;
146                    if (remaining <= 0) {
147                        clearTimeout(timeout);
148                        timeout = null;
149                        previous = now;
150                        result = func.apply(context, args);
151                    } else if (!timeout) {
152                        timeout = setTimeout(later, remaining);
153                    }
154                    return result;
155                };
156            },
157            stringify: function(val) {
158                return _.isString(val) ? val : JSON.stringify(val);
159            },
160            noop: function() {}
161        };
162    }();
163    var VERSION = "0.11.1";
164    var tokenizers = function() {
165        "use strict";
166        return {
167            nonword: nonword,
168            whitespace: whitespace,
169            obj: {
170                nonword: getObjTokenizer(nonword),
171                whitespace: getObjTokenizer(whitespace)
172            }
173        };
174        function whitespace(str) {
175            str = _.toStr(str);
176            return str ? str.split(/\s+/) : [];
177        }
178        function nonword(str) {
179            str = _.toStr(str);
180            return str ? str.split(/\W+/) : [];
181        }
182        function getObjTokenizer(tokenizer) {
183            return function setKey(keys) {
184                keys = Array
vendor: 9,551 bytes, lines 184-444
184.isArray(keys) ? keys : [].slice.call(arguments, 0);
185                return function tokenize(o) {
186                    var tokens = [];
187                    _.each(keys, function(k) {
188                        tokens = tokens.concat(tokenizer(_.toStr(o[k])));
189                    });
190                    return tokens;
191                };
192            };
193        }
194    }();
195    var LruCache = function() {
196        "use strict";
197        function LruCache(maxSize) {
198            this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
199            this.reset();
200            if (this.maxSize <= 0) {
201                this.set = this.get = $.noop;
202            }
203        }
204        _.mixin(LruCache.prototype, {
205            set: function set(key, val) {
206                var tailItem = this.list.tail, node;
207                if (this.size >= this.maxSize) {
208                    this.list.remove(tailItem);
209                    delete this.hash[tailItem.key];
210                    this.size--;
211                }
212                if (node = this.hash[key]) {
213                    node.val = val;
214                    this.list.moveToFront(node);
215                } else {
216                    node = new Node(key, val);
217                    this.list.add(node);
218                    this.hash[key] = node;
219                    this.size++;
220                }
221            },
222            get: function get(key) {
223                var node = this.hash[key];
224                if (node) {
225                    this.list.moveToFront(node);
226                    return node.val;
227                }
228            },
229            reset: function reset() {
230                this.size = 0;
231                this.hash = {};
232                this.list = new List();
233            }
234        });
235        function List() {
236            this.head = this.tail = null;
237        }
238        _.mixin(List.prototype, {
239            add: function add(node) {
240                if (this.head) {
241                    node.next = this.head;
242                    this.head.prev = node;
243                }
244                this.head = node;
245                this.tail = this.tail || node;
246            },
247            remove: function remove(node) {
248                node.prev ? node.prev.next = node.next : this.head = node.next;
249                node.next ? node.next.prev = node.prev : this.tail = node.prev;
250            },
251            moveToFront: function(node) {
252                this.remove(node);
253                this.add(node);
254            }
255        });
256        function Node(key, val) {
257            this.key = key;
258            this.val = val;
259            this.prev = this.next = null;
260        }
261        return LruCache;
262    }();
263    var PersistentStorage = function() {
264        "use strict";
265        var LOCAL_STORAGE;
266        try {
267            LOCAL_STORAGE = window.localStorage;
268            LOCAL_STORAGE.setItem("~~~", "!");
269            LOCAL_STORAGE.removeItem("~~~");
270        } catch (err) {
271            LOCAL_STORAGE = null;
272        }
273        function PersistentStorage(namespace, override) {
274            this.prefix = [ "__", namespace, "__" ].join("");
275            this.ttlKey = "__ttl__";
276            this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
277            this.ls = override || LOCAL_STORAGE;
278            !this.ls && this._noop();
279        }
280        _.mixin(PersistentStorage.prototype, {
281            _prefix: function(key) {
282                return this.prefix + key;
283            },
284            _ttlKey: function(key) {
285                return this._prefix(key) + this.ttlKey;
286            },
287            _noop: function() {
288                this.get = this.set = this.remove = this.clear = this.isExpired = _.noop;
289            },
290            _safeSet: function(key, val) {
291                try {
292                    this.ls.setItem(key, val);
293                } catch (err) {
294                    if (err.name === "QuotaExceededError") {
295                        this.clear();
296                        this._noop();
297                    }
298                }
299            },
300            get: function(key) {
301                if (this.isExpired(key)) {
302                    this.remove(key);
303                }
304                return decode(this.ls.getItem(this._prefix(key)));
305            },
306            set: function(key, val, ttl) {
307                if (_.isNumber(ttl)) {
308                    this._safeSet(this._ttlKey(key), encode(now() + ttl));
309                } else {
310                    this.ls.removeItem(this._ttlKey(key));
311                }
312                return this._safeSet(this._prefix(key), encode(val));
313            },
314            remove: function(key) {
315                this.ls.removeItem(this._ttlKey(key));
316                this.ls.removeItem(this._prefix(key));
317                return this;
318            },
319            clear: function() {
320                var i, keys = gatherMatchingKeys(this.keyMatcher);
321                for (i = keys.length; i--; ) {
322                    this.remove(keys[i]);
323                }
324                return this;
325            },
326            isExpired: function(key) {
327                var ttl = decode(this.ls.getItem(this._ttlKey(key)));
328                return _.isNumber(ttl) && now() > ttl ? true : false;
329            }
330        });
331        return PersistentStorage;
332        function now() {
333            return new Date().getTime();
334        }
335        function encode(val) {
336            return JSON.stringify(_.isUndefined(val) ? null : val);
337        }
338        function decode(val) {
339            return $.parseJSON(val);
340        }
341        function gatherMatchingKeys(keyMatcher) {
342            var i, key, keys = [], len = LOCAL_STORAGE.length;
343            for (i = 0; i < len; i++) {
344                if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) {
345                    keys.push(key.replace(keyMatcher, ""));
346                }
347            }
348            return keys;
349        }
350    }();
351    var Transport = function() {
352        "use strict";
353        var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10);
354        function Transport(o) {
355            o = o || {};
356            this.cancelled = false;
357            this.lastReq = null;
358            this._send = o.transport;
359            this._get = o.limiter ? o.limiter(this._get) : this._get;
360            this._cache = o.cache === false ? new LruCache(0) : sharedCache;
361        }
362        Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
363            maxPendingRequests = num;
364        };
365        Transport.resetCache = function resetCache() {
366            sharedCache.reset();
367        };
368        _.mixin(Transport.prototype, {
369            _fingerprint: function fingerprint(o) {
370                o = o || {};
371                return o.url + o.type + $.param(o.data || {});
372            },
373            _get: function(o, cb) {
374                var that = this, fingerprint, jqXhr;
375                fingerprint = this._fingerprint(o);
376                if (this.cancelled || fingerprint !== this.lastReq) {
377                    return;
378                }
379                if (jqXhr = pendingRequests[fingerprint]) {
380                    jqXhr.done(done).fail(fail);
381                } else if (pendingRequestsCount < maxPendingRequests) {
382                    pendingRequestsCount++;
383                    pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);
384                } else {
385                    this.onDeckRequestArgs = [].slice.call(arguments, 0);
386                }
387                function done(resp) {
388                    cb(null, resp);
389                    that._cache.set(fingerprint, resp);
390                }
391                function fail() {
392                    cb(true);
393                }
394                function always() {
395                    pendingRequestsCount--;
396                    delete pendingRequests[fingerprint];
397                    if (that.onDeckRequestArgs) {
398                        that._get.apply(that, that.onDeckRequestArgs);
399                        that.onDeckRequestArgs = null;
400                    }
401                }
402            },
403            get: function(o, cb) {
404                var resp, fingerprint;
405                cb = cb || $.noop;
406                o = _.isString(o) ? {
407                    url: o
408                } : o || {};
409                fingerprint = this._fingerprint(o);
410                this.cancelled = false;
411                this.lastReq = fingerprint;
412                if (resp = this._cache.get(fingerprint)) {
413                    cb(null, resp);
414                } else {
415                    this._get(o, cb);
416                }
417            },
418            cancel: function() {
419                this.cancelled = true;
420            }
421        });
422        return Transport;
423    }();
424    var SearchIndex = window.SearchIndex = function() {
425        "use strict";
426        var CHILDREN = "c", IDS = "i";
427        function SearchIndex(o) {
428            o = o || {};
429            if (!o.datumTokenizer || !o.queryTokenizer) {
430                $.error("datumTokenizer and queryTokenizer are both required");
431            }
432            this.identify = o.identify || _.stringify;
433            this.datumTokenizer = o.datumTokenizer;
434            this.queryTokenizer = o.queryTokenizer;
435            this.reset();
436        }
437        _.mixin(SearchIndex.prototype, {
438            bootstrap: function bootstrap(o) {
439                this.datums = o.datums;
440                this.trie = o.trie;
441            },
442            add: function(data) {
443                var that = this;
444                data = 
vendor: 8,510 bytes, lines 444-680
444Array.isArray(data) ? data : [ data ];
445                _.each(data, function(datum) {
446                    var id, tokens;
447                    that.datums[id = that.identify(datum)] = datum;
448                    tokens = normalizeTokens(that.datumTokenizer(datum));
449                    _.each(tokens, function(token) {
450                        var node, chars, ch;
451                        node = that.trie;
452                        chars = token.split("");
453                        while (ch = chars.shift()) {
454                            node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode());
455                            node[IDS].push(id);
456                        }
457                    });
458                });
459            },
460            get: function get(ids) {
461                var that = this;
462                return _.map(ids, function(id) {
463                    return that.datums[id];
464                });
465            },
466            search: function search(query) {
467                var that = this, tokens, matches;
468                tokens = normalizeTokens(this.queryTokenizer(query));
469                _.each(tokens, function(token) {
470                    var node, chars, ch, ids;
471                    if (matches && matches.length === 0) {
472                        return false;
473                    }
474                    node = that.trie;
475                    chars = token.split("");
476                    while (node && (ch = chars.shift())) {
477                        node = node[CHILDREN][ch];
478                    }
479                    if (node && chars.length === 0) {
480                        ids = node[IDS].slice(0);
481                        matches = matches ? getIntersection(matches, ids) : ids;
482                    } else {
483                        matches = [];
484                        return false;
485                    }
486                });
487                return matches ? _.map(unique(matches), function(id) {
488                    return that.datums[id];
489                }) : [];
490            },
491            all: function all() {
492                var values = [];
493                for (var key in this.datums) {
494                    values.push(this.datums[key]);
495                }
496                return values;
497            },
498            reset: function reset() {
499                this.datums = {};
500                this.trie = newNode();
501            },
502            serialize: function serialize() {
503                return {
504                    datums: this.datums,
505                    trie: this.trie
506                };
507            }
508        });
509        return SearchIndex;
510        function normalizeTokens(tokens) {
511            tokens = _.filter(tokens, function(token) {
512                return !!token;
513            });
514            tokens = _.map(tokens, function(token) {
515                return token.toLowerCase();
516            });
517            return tokens;
518        }
519        function newNode() {
520            var node = {};
521            node[IDS] = [];
522            node[CHILDREN] = {};
523            return node;
524        }
525        function unique(array) {
526            var seen = {}, uniques = [];
527            for (var i = 0, len = array.length; i < len; i++) {
528                if (!seen[array[i]]) {
529                    seen[array[i]] = true;
530                    uniques.push(array[i]);
531                }
532            }
533            return uniques;
534        }
535        function getIntersection(arrayA, arrayB) {
536            var ai = 0, bi = 0, intersection = [];
537            arrayA = arrayA.sort();
538            arrayB = arrayB.sort();
539            var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
540            while (ai < lenArrayA && bi < lenArrayB) {
541                if (arrayA[ai] < arrayB[bi]) {
542                    ai++;
543                } else if (arrayA[ai] > arrayB[bi]) {
544                    bi++;
545                } else {
546                    intersection.push(arrayA[ai]);
547                    ai++;
548                    bi++;
549                }
550            }
551            return intersection;
552        }
553    }();
554    var Prefetch = function() {
555        "use strict";
556        var keys;
557        keys = {
558            data: "data",
559            protocol: "protocol",
560            thumbprint: "thumbprint"
561        };
562        function Prefetch(o) {
563            this.url = o.url;
564            this.ttl = o.ttl;
565            this.cache = o.cache;
566            this.prepare = o.prepare;
567            this.transform = o.transform;
568            this.transport = o.transport;
569            this.thumbprint = o.thumbprint;
570            this.storage = new PersistentStorage(o.cacheKey);
571        }
572        _.mixin(Prefetch.prototype, {
573            _settings: function settings() {
574                return {
575                    url: this.url,
576                    type: "GET",
577                    dataType: "json"
578                };
579            },
580            store: function store(data) {
581                if (!this.cache) {
582                    return;
583                }
584                this.storage.set(keys.data, data, this.ttl);
585                this.storage.set(keys.protocol, location.protocol, this.ttl);
586                this.storage.set(keys.thumbprint, this.thumbprint, this.ttl);
587            },
588            fromCache: function fromCache() {
589                var stored = {}, isExpired;
590                if (!this.cache) {
591                    return null;
592                }
593                stored.data = this.storage.get(keys.data);
594                stored.protocol = this.storage.get(keys.protocol);
595                stored.thumbprint = this.storage.get(keys.thumbprint);
596                isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol;
597                return stored.data && !isExpired ? stored.data : null;
598            },
599            fromNetwork: function(cb) {
600                var that = this, settings;
601                if (!cb) {
602                    return;
603                }
604                settings = this.prepare(this._settings());
605                this.transport(settings).fail(onError).done(onResponse);
606                function onError() {
607                    cb(true);
608                }
609                function onResponse(resp) {
610                    cb(null, that.transform(resp));
611                }
612            },
613            clear: function clear() {
614                this.storage.clear();
615                return this;
616            }
617        });
618        return Prefetch;
619    }();
620    var Remote = function() {
621        "use strict";
622        function Remote(o) {
623            this.url = o.url;
624            this.prepare = o.prepare;
625            this.transform = o.transform;
626            this.transport = new Transport({
627                cache: o.cache,
628                limiter: o.limiter,
629                transport: o.transport
630            });
631        }
632        _.mixin(Remote.prototype, {
633            _settings: function settings() {
634                return {
635                    url: this.url,
636                    type: "GET",
637                    dataType: "json"
638                };
639            },
640            get: function get(query, cb) {
641                var that = this, settings;
642                if (!cb) {
643                    return;
644                }
645                query = query || "";
646                settings = this.prepare(query, this._settings());
647                return this.transport.get(settings, onResponse);
648                function onResponse(err, resp) {
649                    err ? cb([]) : cb(that.transform(resp));
650                }
651            },
652            cancelLastRequest: function cancelLastRequest() {
653                this.transport.cancel();
654            }
655        });
656        return Remote;
657    }();
658    var oParser = function() {
659        "use strict";
660        return function parse(o) {
661            var defaults, sorter;
662            defaults = {
663                initialize: true,
664                identify: _.stringify,
665                datumTokenizer: null,
666                queryTokenizer: null,
667                sufficient: 5,
668                sorter: null,
669                local: [],
670                prefetch: null,
671                remote: null
672            };
673            o = _.mixin(defaults, o || {});
674            !o.datumTokenizer && $.error("datumTokenizer is required");
675            !o.queryTokenizer && $.error("queryTokenizer is required");
676            sorter = o.sorter;
677            o.sorter = sorter ? function(x) {
678                return x.sort(sorter);
679            } : _.identity;
680            o.local = stm_custom_func_checker
vendor: 7,269 bytes, lines 680-882
680(o.local) ? o.local() : o.local;
681            o.prefetch = parsePrefetch(o.prefetch);
682            o.remote = parseRemote(o.remote);
683            return o;
684        };
685        function parsePrefetch(o) {
686            var defaults;
687            if (!o) {
688                return null;
689            }
690            defaults = {
691                url: null,
692                ttl: 24 * 60 * 60 * 1e3,
693                cache: true,
694                cacheKey: null,
695                thumbprint: "",
696                prepare: _.identity,
697                transform: _.identity,
698                transport: null
699            };
700            o = _.isString(o) ? {
701                url: o
702            } : o;
703            o = _.mixin(defaults, o);
704            !o.url && $.error("prefetch requires url to be set");
705            o.transform = o.filter || o.transform;
706            o.cacheKey = o.cacheKey || o.url;
707            o.thumbprint = VERSION + o.thumbprint;
708            o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
709            return o;
710        }
711        function parseRemote(o) {
712            var defaults;
713            if (!o) {
714                return;
715            }
716            defaults = {
717                url: null,
718                cache: true,
719                prepare: null,
720                replace: null,
721                wildcard: null,
722                limiter: null,
723                rateLimitBy: "debounce",
724                rateLimitWait: 300,
725                transform: _.identity,
726                transport: null
727            };
728            o = _.isString(o) ? {
729                url: o
730            } : o;
731            o = _.mixin(defaults, o);
732            !o.url && $.error("remote requires url to be set");
733            o.transform = o.filter || o.transform;
734            o.prepare = toRemotePrepare(o);
735            o.limiter = toLimiter(o);
736            o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
737            delete o.replace;
738            delete o.wildcard;
739            delete o.rateLimitBy;
740            delete o.rateLimitWait;
741            return o;
742        }
743        function toRemotePrepare(o) {
744            var prepare, replace, wildcard;
745            prepare = o.prepare;
746            replace = o.replace;
747            wildcard = o.wildcard;
748            if (prepare) {
749                return prepare;
750            }
751            if (replace) {
752                prepare = prepareByReplace;
753            } else if (o.wildcard) {
754                prepare = prepareByWildcard;
755            } else {
756                prepare = idenityPrepare;
757            }
758            return prepare;
759            function prepareByReplace(query, settings) {
760                settings.url = replace(settings.url, query);
761                return settings;
762            }
763            function prepareByWildcard(query, settings) {
764                settings.url = settings.url.replace(wildcard, encodeURIComponent(query));
765                return settings;
766            }
767            function idenityPrepare(query, settings) {
768                return settings;
769            }
770        }
771        function toLimiter(o) {
772            var limiter, method, wait;
773            limiter = o.limiter;
774            method = o.rateLimitBy;
775            wait = o.rateLimitWait;
776            if (!limiter) {
777                limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait);
778            }
779            return limiter;
780            function debounce(wait) {
781                return function debounce(fn) {
782                    return _.debounce(fn, wait);
783                };
784            }
785            function throttle(wait) {
786                return function throttle(fn) {
787                    return _.throttle(fn, wait);
788                };
789            }
790        }
791        function callbackToDeferred(fn) {
792            return function wrapper(o) {
793                var deferred = $.Deferred();
794                fn(o, onSuccess, onError);
795                return deferred;
796                function onSuccess(resp) {
797                    _.defer(function() {
798                        deferred.resolve(resp);
799                    });
800                }
801                function onError(err) {
802                    _.defer(function() {
803                        deferred.reject(err);
804                    });
805                }
806            };
807        }
808    }();
809    var Bloodhound = function() {
810        "use strict";
811        var old;
812        old = window && window.Bloodhound;
813        function Bloodhound(o) {
814            o = oParser(o);
815            this.sorter = o.sorter;
816            this.identify = o.identify;
817            this.sufficient = o.sufficient;
818            this.local = o.local;
819            this.remote = o.remote ? new Remote(o.remote) : null;
820            this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;
821            this.index = new SearchIndex({
822                identify: this.identify,
823                datumTokenizer: o.datumTokenizer,
824                queryTokenizer: o.queryTokenizer
825            });
826            o.initialize !== false && this.initialize();
827        }
828        Bloodhound.noConflict = function noConflict() {
829            window && (window.Bloodhound = old);
830            return Bloodhound;
831        };
832        Bloodhound.tokenizers = tokenizers;
833        _.mixin(Bloodhound.prototype, {
834            __ttAdapter: function ttAdapter() {
835                var that = this;
836                return this.remote ? withAsync : withoutAsync;
837                function withAsync(query, sync, async) {
838                    return that.search(query, sync, async);
839                }
840                function withoutAsync(query, sync) {
841                    return that.search(query, sync);
842                }
843            },
844            _loadPrefetch: function loadPrefetch() {
845                var that = this, deferred, serialized;
846                deferred = $.Deferred();
847                if (!this.prefetch) {
848                    deferred.resolve();
849                } else if (serialized = this.prefetch.fromCache()) {
850                    this.index.bootstrap(serialized);
851                    deferred.resolve();
852                } else {
853                    this.prefetch.fromNetwork(done);
854                }
855                return deferred.promise();
856                function done(err, data) {
857                    if (err) {
858                        return deferred.reject();
859                    }
860                    that.add(data);
861                    that.prefetch.store(that.index.serialize());
862                    deferred.resolve();
863                }
864            },
865            _initialize: function initialize() {
866                var that = this, deferred;
867                this.clear();
868                (this.initPromise = this._loadPrefetch()).done(addLocalToIndex);
869                return this.initPromise;
870                function addLocalToIndex() {
871                    that.add(that.local);
872                }
873            },
874            initialize: function initialize(force) {
875                return !this.initPromise || force ? this._initialize() : this.initPromise;
876            },
877            add: function add(data) {
878                this.index.add(data);
879                return this;
880            },
881            get: function get(ids) {
882                ids = 
882Array.isArray(ids) ? ids : [].slice.call(arguments);
883                return this.index.get(ids);
884            },
885            search: function search(query, sync, async) {
886                var that = this, local;
887                local = this.sorter(this.index.search(query));
888                sync(this.remote ? local.slice() : local);
889                if (this.remote && local.length < this.sufficient) {
890                    this.remote.get(query, processRemote);
891                } else if (this.remote) {
892                    this.remote.cancelLastRequest();
893                }
894                return this;
895                function processRemote(remote) {
vendor: 3,459 bytes, lines 896-995
896                    var nonDuplicates = [];
897                    _.each(remote, function(r) {
898                        !_.some(local, function(l) {
899                            return that.identify(r) === that.identify(l);
900                        }) && nonDuplicates.push(r);
901                    });
902                    async && async(nonDuplicates);
903                }
904            },
905            all: function all() {
906                return this.index.all();
907            },
908            clear: function clear() {
909                this.index.reset();
910                return this;
911            },
912            clearPrefetchCache: function clearPrefetchCache() {
913                this.prefetch && this.prefetch.clear();
914                return this;
915            },
916            clearRemoteCache: function clearRemoteCache() {
917                Transport.resetCache();
918                return this;
919            },
920            ttAdapter: function ttAdapter() {
921                return this.__ttAdapter();
922            }
923        });
924        return Bloodhound;
925    }();
926    return Bloodhound;
927});
928
929(function(root, factory) {
930    if (typeof define === "function" && define.amd) {
931        define("typeahead.js", [ "jquery" ], function(a0) {
932            return factory(a0);
933        });
934    } else if (typeof exports === "object") {
935        module.exports = factory(require("jquery"));
936    } else {
937        factory(jQuery);
938    }
939})(this, function($) {
940    var _ = function() {
941        "use strict";
942        return {
943            isMsie: function() {
944                return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
945            },
946            isBlankString: function(str) {
947                return !str || /^\s*$/.test(str);
948            },
949            escapeRegExChars: function(str) {
950                return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
951            },
952            isString: function(obj) {
953                return typeof obj === "string";
954            },
955            isNumber: function(obj) {
956                return typeof obj === "number";
957            },
958            // isArray: $.isArray,
959            // isFunction: $.isFunction,
960            isObject: $.isPlainObject,
961            isUndefined: function(obj) {
962                return typeof obj === "undefined";
963            },
964            isElement: function(obj) {
965                return !!(obj && obj.nodeType === 1);
966            },
967            isJQuery: function(obj) {
968                return obj instanceof $;
969            },
970            toStr: function toStr(s) {
971                return _.isUndefined(s) || s === null ? "" : s + "";
972            },
973            bind: $.proxy,
974            each: function(collection, cb) {
975                $.each(collection, reverseArgs);
976                function reverseArgs(index, value) {
977                    return cb(value, index);
978                }
979            },
980            map: $.map,
981            filter: $.grep,
982            every: function(obj, test) {
983                var result = true;
984                if (!obj) {
985                    return result;
986                }
987                $.each(obj, function(key, val) {
988                    if (!(result = test.call(null, val, key, obj))) {
989                        return false;
990                    }
991                });
992                return !!result;
993            },
994            some: function(obj, test) {
995                var result = false;
996                if (!obj) {
997                    return result;
998                }
999                $.each(obj, function(key, val) {
1000                    if (result = test.call(null, val, key, obj)) {
1001                        return false;
1002                    }
1003                });
1004                return !!result;
1005            },
1006            mixin: $.extend,
1007            identity: function(x) {
1008                return x;
1009            },
1010            clone: function(obj) {
1011                return $.extend(true, {}, obj);
1012            },
1013            getIdGenerator: function() {
1014                var counter = 0;
1015                return function() {
1016                    return counter++;
1017                };
1018            },
1019            templatify: function templatify(obj) {
1020                return stm_custom_func_checker
vendor: 10,118 bytes, lines 1020-1317
1020(obj) ? obj : template;
1021                function template() {
1022                    return String(obj);
1023                }
1024            },
1025            defer: function(fn) {
1026                setTimeout(fn, 0);
1027            },
1028            debounce: function(func, wait, immediate) {
1029                var timeout, result;
1030                return function() {
1031                    var context = this, args = arguments, later, callNow;
1032                    later = function() {
1033                        timeout = null;
1034                        if (!immediate) {
1035                            result = func.apply(context, args);
1036                        }
1037                    };
1038                    callNow = immediate && !timeout;
1039                    clearTimeout(timeout);
1040                    timeout = setTimeout(later, wait);
1041                    if (callNow) {
1042                        result = func.apply(context, args);
1043                    }
1044                    return result;
1045                };
1046            },
1047            throttle: function(func, wait) {
1048                var context, args, timeout, result, previous, later;
1049                previous = 0;
1050                later = function() {
1051                    previous = new Date();
1052                    timeout = null;
1053                    result = func.apply(context, args);
1054                };
1055                return function() {
1056                    var now = new Date(), remaining = wait - (now - previous);
1057                    context = this;
1058                    args = arguments;
1059                    if (remaining <= 0) {
1060                        clearTimeout(timeout);
1061                        timeout = null;
1062                        previous = now;
1063                        result = func.apply(context, args);
1064                    } else if (!timeout) {
1065                        timeout = setTimeout(later, remaining);
1066                    }
1067                    return result;
1068                };
1069            },
1070            stringify: function(val) {
1071                return _.isString(val) ? val : JSON.stringify(val);
1072            },
1073            noop: function() {}
1074        };
1075    }();
1076    var WWW = function() {
1077        "use strict";
1078        var defaultClassNames = {
1079            wrapper: "twitter-typeahead",
1080            input: "tt-input",
1081            hint: "tt-hint",
1082            menu: "tt-menu",
1083            dataset: "tt-dataset",
1084            suggestion: "tt-suggestion",
1085            selectable: "tt-selectable",
1086            empty: "tt-empty",
1087            open: "tt-open",
1088            cursor: "tt-cursor",
1089            highlight: "tt-highlight"
1090        };
1091        return build;
1092        function build(o) {
1093            var www, classes;
1094            classes = _.mixin({}, defaultClassNames, o);
1095            www = {
1096                css: buildCss(),
1097                classes: classes,
1098                html: buildHtml(classes),
1099                selectors: buildSelectors(classes)
1100            };
1101            return {
1102                css: www.css,
1103                html: www.html,
1104                classes: www.classes,
1105                selectors: www.selectors,
1106                mixin: function(o) {
1107                    _.mixin(o, www);
1108                }
1109            };
1110        }
1111        function buildHtml(c) {
1112            return {
1113                wrapper: '<span class="' + c.wrapper + '"></span>',
1114                menu: '<div class="' + c.menu + '"></div>'
1115            };
1116        }
1117        function buildSelectors(classes) {
1118            var selectors = {};
1119            _.each(classes, function(v, k) {
1120                selectors[k] = "." + v;
1121            });
1122            return selectors;
1123        }
1124        function buildCss() {
1125            var css = {
1126                wrapper: {
1127                    position: "relative",
1128                    display: "inline-block"
1129                },
1130                hint: {
1131                    position: "absolute",
1132                    top: "0",
1133                    left: "0",
1134                    borderColor: "transparent",
1135                    boxShadow: "none",
1136                    opacity: "1"
1137                },
1138                input: {
1139                    position: "relative",
1140                    verticalAlign: "top",
1141                    backgroundColor: "transparent"
1142                },
1143                inputWithNoHint: {
1144                    position: "relative",
1145                    verticalAlign: "top"
1146                },
1147                menu: {
1148                    position: "absolute",
1149                    top: "100%",
1150                    left: "0",
1151                    zIndex: "100",
1152                    display: "none"
1153                },
1154                ltr: {
1155                    left: "0",
1156                    right: "auto"
1157                },
1158                rtl: {
1159                    left: "auto",
1160                    right: " 0"
1161                }
1162            };
1163            if (_.isMsie()) {
1164                _.mixin(css.input, {
1165                    backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
1166                });
1167            }
1168            return css;
1169        }
1170    }();
1171    var EventBus = function() {
1172        "use strict";
1173        var namespace, deprecationMap;
1174        namespace = "typeahead:";
1175        deprecationMap = {
1176            render: "rendered",
1177            cursorchange: "cursorchanged",
1178            select: "selected",
1179            autocomplete: "autocompleted"
1180        };
1181        function EventBus(o) {
1182            if (!o || !o.el) {
1183                $.error("EventBus initialized without el");
1184            }
1185            this.$el = $(o.el);
1186        }
1187        _.mixin(EventBus.prototype, {
1188            _trigger: function(type, args) {
1189                var $e;
1190                $e = $.Event(namespace + type);
1191                (args = args || []).unshift($e);
1192                this.$el.trigger.apply(this.$el, args);
1193                return $e;
1194            },
1195            before: function(type) {
1196                var args, $e;
1197                args = [].slice.call(arguments, 1);
1198                $e = this._trigger("before" + type, args);
1199                return $e.isDefaultPrevented();
1200            },
1201            trigger: function(type) {
1202                var deprecatedType;
1203                this._trigger(type, [].slice.call(arguments, 1));
1204                if (deprecatedType = deprecationMap[type]) {
1205                    this._trigger(deprecatedType, [].slice.call(arguments, 1));
1206                }
1207            }
1208        });
1209        return EventBus;
1210    }();
1211    var EventEmitter = function() {
1212        "use strict";
1213        var splitter = /\s+/, nextTick = getNextTick();
1214        return {
1215            onSync: onSync,
1216            onAsync: onAsync,
1217            off: off,
1218            trigger: trigger
1219        };
1220        function on(method, types, cb, context) {
1221            var type;
1222            if (!cb) {
1223                return this;
1224            }
1225            types = types.split(splitter);
1226            cb = context ? bindContext(cb, context) : cb;
1227            this._callbacks = this._callbacks || {};
1228            while (type = types.shift()) {
1229                this._callbacks[type] = this._callbacks[type] || {
1230                    sync: [],
1231                    async: []
1232                };
1233                this._callbacks[type][method].push(cb);
1234            }
1235            return this;
1236        }
1237        function onAsync(types, cb, context) {
1238            return on.call(this, "async", types, cb, context);
1239        }
1240        function onSync(types, cb, context) {
1241            return on.call(this, "sync", types, cb, context);
1242        }
1243        function off(types) {
1244            var type;
1245            if (!this._callbacks) {
1246                return this;
1247            }
1248            types = types.split(splitter);
1249            while (type = types.shift()) {
1250                delete this._callbacks[type];
1251            }
1252            return this;
1253        }
1254        function trigger(types) {
1255            var type, callbacks, args, syncFlush, asyncFlush;
1256            if (!this._callbacks) {
1257                return this;
1258            }
1259            types = types.split(splitter);
1260            args = [].slice.call(arguments, 1);
1261            while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
1262                syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
1263                asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
1264                syncFlush() && nextTick(asyncFlush);
1265            }
1266            return this;
1267        }
1268        function getFlush(callbacks, context, args) {
1269            return flush;
1270            function flush() {
1271                var cancelled;
1272                for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
1273                    cancelled = callbacks[i].apply(context, args) === false;
1274                }
1275                return !cancelled;
1276            }
1277        }
1278        function getNextTick() {
1279            var nextTickFn;
1280            if (window.setImmediate) {
1281                nextTickFn = function nextTickSetImmediate(fn) {
1282                    setImmediate(function() {
1283                        fn();
1284                    });
1285                };
1286            } else {
1287                nextTickFn = function nextTickSetTimeout(fn) {
1288                    setTimeout(function() {
1289                        fn();
1290                    }, 0);
1291                };
1292            }
1293            return nextTickFn;
1294        }
1295        function bindContext(fn, context) {
1296            return fn.bind ? fn.bind(context) : function() {
1297                fn.apply(context, [].slice.call(arguments, 0));
1298            };
1299        }
1300    }();
1301    var highlight = function(doc) {
1302        "use strict";
1303        var defaults = {
1304            node: null,
1305            pattern: null,
1306            tagName: "strong",
1307            className: null,
1308            wordsOnly: false,
1309            caseSensitive: false
1310        };
1311        return function hightlight(o) {
1312            var regex;
1313            o = _.mixin({}, defaults, o);
1314            if (!o.node || !o.pattern) {
1315                return;
1316            }
1317            o.pattern = 
1317Array
vendor: 19,047 bytes, lines 1317-1754
1317.isArray(o.pattern) ? o.pattern : [ o.pattern ];
1318            regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
1319            traverse(o.node, hightlightTextNode);
1320            function hightlightTextNode(textNode) {
1321                var match, patternNode, wrapperNode;
1322                if (match = regex.exec(textNode.data)) {
1323                    wrapperNode = doc.createElement(o.tagName);
1324                    o.className && (wrapperNode.className = o.className);
1325                    patternNode = textNode.splitText(match.index);
1326                    patternNode.splitText(match[0].length);
1327                    wrapperNode.appendChild(patternNode.cloneNode(true));
1328                    textNode.parentNode.replaceChild(wrapperNode, patternNode);
1329                }
1330                return !!match;
1331            }
1332            function traverse(el, hightlightTextNode) {
1333                var childNode, TEXT_NODE_TYPE = 3;
1334                for (var i = 0; i < el.childNodes.length; i++) {
1335                    childNode = el.childNodes[i];
1336                    if (childNode.nodeType === TEXT_NODE_TYPE) {
1337                        i += hightlightTextNode(childNode) ? 1 : 0;
1338                    } else {
1339                        traverse(childNode, hightlightTextNode);
1340                    }
1341                }
1342            }
1343        };
1344        function getRegex(patterns, caseSensitive, wordsOnly) {
1345            var escapedPatterns = [], regexStr;
1346            for (var i = 0, len = patterns.length; i < len; i++) {
1347                escapedPatterns.push(_.escapeRegExChars(patterns[i]));
1348            }
1349            regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
1350            return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
1351        }
1352    }(window.document);
1353    var Input = function() {
1354        "use strict";
1355        var specialKeyCodeMap;
1356        specialKeyCodeMap = {
1357            9: "tab",
1358            27: "esc",
1359            37: "left",
1360            39: "right",
1361            13: "enter",
1362            38: "up",
1363            40: "down"
1364        };
1365        function Input(o, www) {
1366            o = o || {};
1367            if (!o.input) {
1368                $.error("input is missing");
1369            }
1370            www.mixin(this);
1371            this.$hint = $(o.hint);
1372            this.$input = $(o.input);
1373            this.query = this.$input.val();
1374            this.queryWhenFocused = this.hasFocus() ? this.query : null;
1375            this.$overflowHelper = buildOverflowHelper(this.$input);
1376            this._checkLanguageDirection();
1377            if (this.$hint.length === 0) {
1378                this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
1379            }
1380        }
1381        Input.normalizeQuery = function(str) {
1382            return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
1383        };
1384        _.mixin(Input.prototype, EventEmitter, {
1385            _onBlur: function onBlur() {
1386                this.resetInputValue();
1387                this.trigger("blurred");
1388            },
1389            _onFocus: function onFocus() {
1390                this.queryWhenFocused = this.query;
1391                this.trigger("focused");
1392            },
1393            _onKeydown: function onKeydown($e) {
1394                var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
1395                this._managePreventDefault(keyName, $e);
1396                if (keyName && this._shouldTrigger(keyName, $e)) {
1397                    this.trigger(keyName + "Keyed", $e);
1398                }
1399            },
1400            _onInput: function onInput() {
1401                this._setQuery(this.getInputValue());
1402                this.clearHintIfInvalid();
1403                this._checkLanguageDirection();
1404            },
1405            _managePreventDefault: function managePreventDefault(keyName, $e) {
1406                var preventDefault;
1407                switch (keyName) {
1408                  case "up":
1409                  case "down":
1410                    preventDefault = !withModifier($e);
1411                    break;
1412
1413                  default:
1414                    preventDefault = false;
1415                }
1416                preventDefault && $e.preventDefault();
1417            },
1418            _shouldTrigger: function shouldTrigger(keyName, $e) {
1419                var trigger;
1420                switch (keyName) {
1421                  case "tab":
1422                    trigger = !withModifier($e);
1423                    break;
1424
1425                  default:
1426                    trigger = true;
1427                }
1428                return trigger;
1429            },
1430            _checkLanguageDirection: function checkLanguageDirection() {
1431                var dir = (this.$input.css("direction") || "ltr").toLowerCase();
1432                if (this.dir !== dir) {
1433                    this.dir = dir;
1434                    this.$hint.attr("dir", dir);
1435                    this.trigger("langDirChanged", dir);
1436                }
1437            },
1438            _setQuery: function setQuery(val, silent) {
1439                var areEquivalent, hasDifferentWhitespace;
1440                areEquivalent = areQueriesEquivalent(val, this.query);
1441                hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
1442                this.query = val;
1443                if (!silent && !areEquivalent) {
1444                    this.trigger("queryChanged", this.query);
1445                } else if (!silent && hasDifferentWhitespace) {
1446                    this.trigger("whitespaceChanged", this.query);
1447                }
1448            },
1449            bind: function() {
1450                var that = this, onBlur, onFocus, onKeydown, onInput;
1451                onBlur = _.bind(this._onBlur, this);
1452                onFocus = _.bind(this._onFocus, this);
1453                onKeydown = _.bind(this._onKeydown, this);
1454                onInput = _.bind(this._onInput, this);
1455                this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
1456                if (!_.isMsie() || _.isMsie() > 9) {
1457                    this.$input.on("input.tt", onInput);
1458                } else {
1459                    this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
1460                        if (specialKeyCodeMap[$e.which || $e.keyCode]) {
1461                            return;
1462                        }
1463                        _.defer(_.bind(that._onInput, that, $e));
1464                    });
1465                }
1466                return this;
1467            },
1468            focus: function focus() {
1469                this.$input.focus();
1470            },
1471            blur: function blur() {
1472                this.$input.blur();
1473            },
1474            getLangDir: function getLangDir() {
1475                return this.dir;
1476            },
1477            getQuery: function getQuery() {
1478                return this.query || "";
1479            },
1480            setQuery: function setQuery(val, silent) {
1481                this.setInputValue(val);
1482                this._setQuery(val, silent);
1483            },
1484            hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
1485                return this.query !== this.queryWhenFocused;
1486            },
1487            getInputValue: function getInputValue() {
1488                return this.$input.val();
1489            },
1490            setInputValue: function setInputValue(value) {
1491                this.$input.val(value);
1492                this.clearHintIfInvalid();
1493                this._checkLanguageDirection();
1494            },
1495            resetInputValue: function resetInputValue() {
1496                this.setInputValue(this.query);
1497            },
1498            getHint: function getHint() {
1499                return this.$hint.val();
1500            },
1501            setHint: function setHint(value) {
1502                this.$hint.val(value);
1503            },
1504            clearHint: function clearHint() {
1505                this.setHint("");
1506            },
1507            clearHintIfInvalid: function clearHintIfInvalid() {
1508                var val, hint, valIsPrefixOfHint, isValid;
1509                val = this.getInputValue();
1510                hint = this.getHint();
1511                valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
1512                isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
1513                !isValid && this.clearHint();
1514            },
1515            hasFocus: function hasFocus() {
1516                return this.$input.is(":focus");
1517            },
1518            hasOverflow: function hasOverflow() {
1519                var constraint = this.$input.width() - 2;
1520                this.$overflowHelper.text(this.getInputValue());
1521                return this.$overflowHelper.width() >= constraint;
1522            },
1523            isCursorAtEnd: function() {
1524                var valueLength, selectionStart, range;
1525                valueLength = this.$input.val().length;
1526                selectionStart = this.$input[0].selectionStart;
1527                if (_.isNumber(selectionStart)) {
1528                    return selectionStart === valueLength;
1529                } else if (document.selection) {
1530                    range = document.selection.createRange();
1531                    range.moveStart("character", -valueLength);
1532                    return valueLength === range.text.length;
1533                }
1534                return true;
1535            },
1536            destroy: function destroy() {
1537                this.$hint.off(".tt");
1538                this.$input.off(".tt");
1539                this.$overflowHelper.remove();
1540                this.$hint = this.$input = this.$overflowHelper = $("<div>");
1541            }
1542        });
1543        return Input;
1544        function buildOverflowHelper($input) {
1545            return $('<pre aria-hidden="true"></pre>').css({
1546                position: "absolute",
1547                visibility: "hidden",
1548                whiteSpace: "pre",
1549                fontFamily: $input.css("font-family"),
1550                fontSize: $input.css("font-size"),
1551                fontStyle: $input.css("font-style"),
1552                fontVariant: $input.css("font-variant"),
1553                fontWeight: $input.css("font-weight"),
1554                wordSpacing: $input.css("word-spacing"),
1555                letterSpacing: $input.css("letter-spacing"),
1556                textIndent: $input.css("text-indent"),
1557                textRendering: $input.css("text-rendering"),
1558                textTransform: $input.css("text-transform")
1559            }).insertAfter($input);
1560        }
1561        function areQueriesEquivalent(a, b) {
1562            return Input.normalizeQuery(a) === Input.normalizeQuery(b);
1563        }
1564        function withModifier($e) {
1565            return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
1566        }
1567    }();
1568    var Dataset = function() {
1569        "use strict";
1570        var keys, nameGenerator;
1571        keys = {
1572            val: "tt-selectable-display",
1573            obj: "tt-selectable-object"
1574        };
1575        nameGenerator = _.getIdGenerator();
1576        function Dataset(o, www) {
1577            o = o || {};
1578            o.templates = o.templates || {};
1579            o.templates.notFound = o.templates.notFound || o.templates.empty;
1580            if (!o.source) {
1581                $.error("missing source");
1582            }
1583            if (!o.node) {
1584                $.error("missing node");
1585            }
1586            if (o.name && !isValidName(o.name)) {
1587                $.error("invalid dataset name: " + o.name);
1588            }
1589            www.mixin(this);
1590            this.highlight = !!o.highlight;
1591            this.name = o.name || nameGenerator();
1592            this.limit = o.limit || 5;
1593            this.displayFn = getDisplayFn(o.display || o.displayKey);
1594            this.templates = getTemplates(o.templates, this.displayFn);
1595            this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
1596            this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
1597            this._resetLastSuggestion();
1598            this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
1599        }
1600        Dataset.extractData = function extractData(el) {
1601            var $el = $(el);
1602            if ($el.data(keys.obj)) {
1603                return {
1604                    val: $el.data(keys.val) || "",
1605                    obj: $el.data(keys.obj) || null
1606                };
1607            }
1608            return null;
1609        };
1610        _.mixin(Dataset.prototype, EventEmitter, {
1611            _overwrite: function overwrite(query, suggestions) {
1612                suggestions = suggestions || [];
1613                if (suggestions.length) {
1614                    this._renderSuggestions(query, suggestions);
1615                } else if (this.async && this.templates.pending) {
1616                    this._renderPending(query);
1617                } else if (!this.async && this.templates.notFound) {
1618                    this._renderNotFound(query);
1619                } else {
1620                    this._empty();
1621                }
1622                this.trigger("rendered", this.name, suggestions, false);
1623            },
1624            _append: function append(query, suggestions) {
1625                suggestions = suggestions || [];
1626                if (suggestions.length && this.$lastSuggestion.length) {
1627                    this._appendSuggestions(query, suggestions);
1628                } else if (suggestions.length) {
1629                    this._renderSuggestions(query, suggestions);
1630                } else if (!this.$lastSuggestion.length && this.templates.notFound) {
1631                    this._renderNotFound(query);
1632                }
1633                this.trigger("rendered", this.name, suggestions, true);
1634            },
1635            _renderSuggestions: function renderSuggestions(query, suggestions) {
1636                var $fragment;
1637                $fragment = this._getSuggestionsFragment(query, suggestions);
1638                this.$lastSuggestion = $fragment.children().last();
1639                this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
1640            },
1641            _appendSuggestions: function appendSuggestions(query, suggestions) {
1642                var $fragment, $lastSuggestion;
1643                $fragment = this._getSuggestionsFragment(query, suggestions);
1644                $lastSuggestion = $fragment.children().last();
1645                this.$lastSuggestion.after($fragment);
1646                this.$lastSuggestion = $lastSuggestion;
1647            },
1648            _renderPending: function renderPending(query) {
1649                var template = this.templates.pending;
1650                this._resetLastSuggestion();
1651                template && this.$el.html(template({
1652                    query: query,
1653                    dataset: this.name
1654                }));
1655            },
1656            _renderNotFound: function renderNotFound(query) {
1657                var template = this.templates.notFound;
1658                this._resetLastSuggestion();
1659                template && this.$el.html(template({
1660                    query: query,
1661                    dataset: this.name
1662                }));
1663            },
1664            _empty: function empty() {
1665                this.$el.empty();
1666                this._resetLastSuggestion();
1667            },
1668            _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
1669                var that = this, fragment;
1670                fragment = document.createDocumentFragment();
1671                _.each(suggestions, function getSuggestionNode(suggestion) {
1672                    var $el, context;
1673                    context = that._injectQuery(query, suggestion);
1674                    $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
1675                    fragment.appendChild($el[0]);
1676                });
1677                this.highlight && highlight({
1678                    className: this.classes.highlight,
1679                    node: fragment,
1680                    pattern: query
1681                });
1682                return $(fragment);
1683            },
1684            _getFooter: function getFooter(query, suggestions) {
1685                return this.templates.footer ? this.templates.footer({
1686                    query: query,
1687                    suggestions: suggestions,
1688                    dataset: this.name
1689                }) : null;
1690            },
1691            _getHeader: function getHeader(query, suggestions) {
1692                return this.templates.header ? this.templates.header({
1693                    query: query,
1694                    suggestions: suggestions,
1695                    dataset: this.name
1696                }) : null;
1697            },
1698            _resetLastSuggestion: function resetLastSuggestion() {
1699                this.$lastSuggestion = $();
1700            },
1701            _injectQuery: function injectQuery(query, obj) {
1702                return _.isObject(obj) ? _.mixin({
1703                    _query: query
1704                }, obj) : obj;
1705            },
1706            update: function update(query) {
1707                var that = this, canceled = false, syncCalled = false, rendered = 0;
1708                this.cancel();
1709                this.cancel = function cancel() {
1710                    canceled = true;
1711                    that.cancel = $.noop;
1712                    that.async && that.trigger("asyncCanceled", query);
1713                };
1714                this.source(query, sync, async);
1715                !syncCalled && sync([]);
1716                function sync(suggestions) {
1717                    if (syncCalled) {
1718                        return;
1719                    }
1720                    syncCalled = true;
1721                    suggestions = (suggestions || []).slice(0, that.limit);
1722                    rendered = suggestions.length;
1723                    that._overwrite(query, suggestions);
1724                    if (rendered < that.limit && that.async) {
1725                        that.trigger("asyncRequested", query);
1726                    }
1727                }
1728                function async(suggestions) {
1729                    suggestions = suggestions || [];
1730                    if (!canceled && rendered < that.limit) {
1731                        that.cancel = $.noop;
1732                        rendered += suggestions.length;
1733                        that._append(query, suggestions.slice(0, that.limit - rendered));
1734                        that.async && that.trigger("asyncReceived", query);
1735                    }
1736                }
1737            },
1738            cancel: $.noop,
1739            clear: function clear() {
1740                this._empty();
1741                this.cancel();
1742                this.trigger("cleared");
1743            },
1744            isEmpty: function isEmpty() {
1745                return this.$el.is(":empty");
1746            },
1747            destroy: function destroy() {
1748                this.$el = $("<div>");
1749            }
1750        });
1751        return Dataset;
1752        function getDisplayFn(display) {
1753            display = display || _.stringify;
1754            return 
1754stm_custom_func_checker
vendor: 22,058 bytes, lines 1754-2242
1754(display) ? display : displayFn;
1755            function displayFn(obj) {
1756                return obj[display];
1757            }
1758        }
1759        function getTemplates(templates, displayFn) {
1760            return {
1761                notFound: templates.notFound && _.templatify(templates.notFound),
1762                pending: templates.pending && _.templatify(templates.pending),
1763                header: templates.header && _.templatify(templates.header),
1764                footer: templates.footer && _.templatify(templates.footer),
1765                suggestion: templates.suggestion || suggestionTemplate
1766            };
1767            function suggestionTemplate(context) {
1768                return $("<div>").text(displayFn(context));
1769            }
1770        }
1771        function isValidName(str) {
1772            return /^[_a-zA-Z0-9-]+$/.test(str);
1773        }
1774    }();
1775    var Menu = function() {
1776        "use strict";
1777        function Menu(o, www) {
1778            var that = this;
1779            o = o || {};
1780            if (!o.node) {
1781                $.error("node is required");
1782            }
1783            www.mixin(this);
1784            this.$node = $(o.node);
1785            this.query = null;
1786            this.datasets = _.map(o.datasets, initializeDataset);
1787            function initializeDataset(oDataset) {
1788                var node = that.$node.find(oDataset.node).first();
1789                oDataset.node = node.length ? node : $("<div>").appendTo(that.$node);
1790                return new Dataset(oDataset, www);
1791            }
1792        }
1793        _.mixin(Menu.prototype, EventEmitter, {
1794            _onSelectableClick: function onSelectableClick($e) {
1795                this.trigger("selectableClicked", $($e.currentTarget));
1796            },
1797            _onRendered: function onRendered(type, dataset, suggestions, async) {
1798                this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
1799                this.trigger("datasetRendered", dataset, suggestions, async);
1800            },
1801            _onCleared: function onCleared() {
1802                this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
1803                this.trigger("datasetCleared");
1804            },
1805            _propagate: function propagate() {
1806                this.trigger.apply(this, arguments);
1807            },
1808            _allDatasetsEmpty: function allDatasetsEmpty() {
1809                return _.every(this.datasets, isDatasetEmpty);
1810                function isDatasetEmpty(dataset) {
1811                    return dataset.isEmpty();
1812                }
1813            },
1814            _getSelectables: function getSelectables() {
1815                return this.$node.find(this.selectors.selectable);
1816            },
1817            _removeCursor: function _removeCursor() {
1818                var $selectable = this.getActiveSelectable();
1819                $selectable && $selectable.removeClass(this.classes.cursor);
1820            },
1821            _ensureVisible: function ensureVisible($el) {
1822                var elTop, elBottom, nodeScrollTop, nodeHeight;
1823                elTop = $el.position().top;
1824                elBottom = elTop + $el.outerHeight(true);
1825                nodeScrollTop = this.$node.scrollTop();
1826                nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
1827                if (elTop < 0) {
1828                    this.$node.scrollTop(nodeScrollTop + elTop);
1829                } else if (nodeHeight < elBottom) {
1830                    this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
1831                }
1832            },
1833            bind: function() {
1834                var that = this, onSelectableClick;
1835                onSelectableClick = _.bind(this._onSelectableClick, this);
1836                this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
1837                _.each(this.datasets, function(dataset) {
1838                    dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
1839                });
1840                return this;
1841            },
1842            isOpen: function isOpen() {
1843                return this.$node.hasClass(this.classes.open);
1844            },
1845            open: function open() {
1846                this.$node.addClass(this.classes.open);
1847            },
1848            close: function close() {
1849                this.$node.removeClass(this.classes.open);
1850                this._removeCursor();
1851            },
1852            setLanguageDirection: function setLanguageDirection(dir) {
1853                this.$node.attr("dir", dir);
1854            },
1855            selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
1856                var $selectables, $oldCursor, oldIndex, newIndex;
1857                $oldCursor = this.getActiveSelectable();
1858                $selectables = this._getSelectables();
1859                oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
1860                newIndex = oldIndex + delta;
1861                newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
1862                newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
1863                return newIndex === -1 ? null : $selectables.eq(newIndex);
1864            },
1865            setCursor: function setCursor($selectable) {
1866                this._removeCursor();
1867                if ($selectable = $selectable && $selectable.first()) {
1868                    $selectable.addClass(this.classes.cursor);
1869                    this._ensureVisible($selectable);
1870                }
1871            },
1872            getSelectableData: function getSelectableData($el) {
1873                return $el && $el.length ? Dataset.extractData($el) : null;
1874            },
1875            getActiveSelectable: function getActiveSelectable() {
1876                var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
1877                return $selectable.length ? $selectable : null;
1878            },
1879            getTopSelectable: function getTopSelectable() {
1880                var $selectable = this._getSelectables().first();
1881                return $selectable.length ? $selectable : null;
1882            },
1883            update: function update(query) {
1884                var isValidUpdate = query !== this.query;
1885                if (isValidUpdate) {
1886                    this.query = query;
1887                    _.each(this.datasets, updateDataset);
1888                }
1889                return isValidUpdate;
1890                function updateDataset(dataset) {
1891                    dataset.update(query);
1892                }
1893            },
1894            empty: function empty() {
1895                _.each(this.datasets, clearDataset);
1896                this.query = null;
1897                this.$node.addClass(this.classes.empty);
1898                function clearDataset(dataset) {
1899                    dataset.clear();
1900                }
1901            },
1902            destroy: function destroy() {
1903                this.$node.off(".tt");
1904                this.$node = $("<div>");
1905                _.each(this.datasets, destroyDataset);
1906                function destroyDataset(dataset) {
1907                    dataset.destroy();
1908                }
1909            }
1910        });
1911        return Menu;
1912    }();
1913    var DefaultMenu = function() {
1914        "use strict";
1915        var s = Menu.prototype;
1916        function DefaultMenu() {
1917            Menu.apply(this, [].slice.call(arguments, 0));
1918        }
1919        _.mixin(DefaultMenu.prototype, Menu.prototype, {
1920            open: function open() {
1921                !this._allDatasetsEmpty() && this._show();
1922                return s.open.apply(this, [].slice.call(arguments, 0));
1923            },
1924            close: function close() {
1925                this._hide();
1926                return s.close.apply(this, [].slice.call(arguments, 0));
1927            },
1928            _onRendered: function onRendered() {
1929                if (this._allDatasetsEmpty()) {
1930                    this._hide();
1931                } else {
1932                    this.isOpen() && this._show();
1933                }
1934                return s._onRendered.apply(this, [].slice.call(arguments, 0));
1935            },
1936            _onCleared: function onCleared() {
1937                if (this._allDatasetsEmpty()) {
1938                    this._hide();
1939                } else {
1940                    this.isOpen() && this._show();
1941                }
1942                return s._onCleared.apply(this, [].slice.call(arguments, 0));
1943            },
1944            setLanguageDirection: function setLanguageDirection(dir) {
1945                this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
1946                return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
1947            },
1948            _hide: function hide() {
1949                this.$node.hide();
1950            },
1951            _show: function show() {
1952                this.$node.css("display", "block");
1953            }
1954        });
1955        return DefaultMenu;
1956    }();
1957    var Typeahead = function() {
1958        "use strict";
1959        function Typeahead(o, www) {
1960            var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
1961            o = o || {};
1962            if (!o.input) {
1963                $.error("missing input");
1964            }
1965            if (!o.menu) {
1966                $.error("missing menu");
1967            }
1968            if (!o.eventBus) {
1969                $.error("missing event bus");
1970            }
1971            www.mixin(this);
1972            this.eventBus = o.eventBus;
1973            this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
1974            this.input = o.input;
1975            this.menu = o.menu;
1976            this.enabled = true;
1977            this.active = false;
1978            this.input.hasFocus() && this.activate();
1979            this.dir = this.input.getLangDir();
1980            this._hacks();
1981            this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this);
1982            onFocused = c(this, "activate", "open", "_onFocused");
1983            onBlurred = c(this, "deactivate", "_onBlurred");
1984            onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
1985            onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
1986            onEscKeyed = c(this, "isActive", "_onEscKeyed");
1987            onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
1988            onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
1989            onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
1990            onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
1991            onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
1992            onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
1993            this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this);
1994        }
1995        _.mixin(Typeahead.prototype, {
1996            _hacks: function hacks() {
1997                var $input, $menu;
1998                $input = this.input.$input || $("<div>");
1999                $menu = this.menu.$node || $("<div>");
2000                $input.on("blur.tt", function($e) {
2001                    var active, isActive, hasActive;
2002                    active = document.activeElement;
2003                    isActive = $menu.is(active);
2004                    hasActive = $menu.has(active).length > 0;
2005                    if (_.isMsie() && (isActive || hasActive)) {
2006                        $e.preventDefault();
2007                        $e.stopImmediatePropagation();
2008                        _.defer(function() {
2009                            $input.focus();
2010                        });
2011                    }
2012                });
2013                $menu.on("mousedown.tt", function($e) {
2014                    $e.preventDefault();
2015                });
2016            },
2017            _onSelectableClicked: function onSelectableClicked(type, $el) {
2018                this.select($el);
2019            },
2020            _onDatasetCleared: function onDatasetCleared() {
2021                this._updateHint();
2022            },
2023            _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
2024                this._updateHint();
2025                this.eventBus.trigger("render", suggestions, async, dataset);
2026            },
2027            _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
2028                this.eventBus.trigger("asyncrequest", query, dataset);
2029            },
2030            _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
2031                this.eventBus.trigger("asynccancel", query, dataset);
2032            },
2033            _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
2034                this.eventBus.trigger("asyncreceive", query, dataset);
2035            },
2036            _onFocused: function onFocused() {
2037                this._minLengthMet() && this.menu.update(this.input.getQuery());
2038            },
2039            _onBlurred: function onBlurred() {
2040                if (this.input.hasQueryChangedSinceLastFocus()) {
2041                    this.eventBus.trigger("change", this.input.getQuery());
2042                }
2043            },
2044            _onEnterKeyed: function onEnterKeyed(type, $e) {
2045                var $selectable;
2046                if ($selectable = this.menu.getActiveSelectable()) {
2047                    this.select($selectable) && $e.preventDefault();
2048                }
2049            },
2050            _onTabKeyed: function onTabKeyed(type, $e) {
2051                var $selectable;
2052                if ($selectable = this.menu.getActiveSelectable()) {
2053                    this.select($selectable) && $e.preventDefault();
2054                } else if ($selectable = this.menu.getTopSelectable()) {
2055                    this.autocomplete($selectable) && $e.preventDefault();
2056                }
2057            },
2058            _onEscKeyed: function onEscKeyed() {
2059                this.close();
2060            },
2061            _onUpKeyed: function onUpKeyed() {
2062                this.moveCursor(-1);
2063            },
2064            _onDownKeyed: function onDownKeyed() {
2065                this.moveCursor(+1);
2066            },
2067            _onLeftKeyed: function onLeftKeyed() {
2068                if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
2069                    this.autocomplete(this.menu.getTopSelectable());
2070                }
2071            },
2072            _onRightKeyed: function onRightKeyed() {
2073                if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
2074                    this.autocomplete(this.menu.getTopSelectable());
2075                }
2076            },
2077            _onQueryChanged: function onQueryChanged(e, query) {
2078                this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
2079            },
2080            _onWhitespaceChanged: function onWhitespaceChanged() {
2081                this._updateHint();
2082            },
2083            _onLangDirChanged: function onLangDirChanged(e, dir) {
2084                if (this.dir !== dir) {
2085                    this.dir = dir;
2086                    this.menu.setLanguageDirection(dir);
2087                }
2088            },
2089            _openIfActive: function openIfActive() {
2090                this.isActive() && this.open();
2091            },
2092            _minLengthMet: function minLengthMet(query) {
2093                query = _.isString(query) ? query : this.input.getQuery() || "";
2094                return query.length >= this.minLength;
2095            },
2096            _updateHint: function updateHint() {
2097                var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
2098                $selectable = this.menu.getTopSelectable();
2099                data = this.menu.getSelectableData($selectable);
2100                val = this.input.getInputValue();
2101                if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
2102                    query = Input.normalizeQuery(val);
2103                    escapedQuery = _.escapeRegExChars(query);
2104                    frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
2105                    match = frontMatchRegEx.exec(data.val);
2106                    match && this.input.setHint(val + match[1]);
2107                } else {
2108                    this.input.clearHint();
2109                }
2110            },
2111            isEnabled: function isEnabled() {
2112                return this.enabled;
2113            },
2114            enable: function enable() {
2115                this.enabled = true;
2116            },
2117            disable: function disable() {
2118                this.enabled = false;
2119            },
2120            isActive: function isActive() {
2121                return this.active;
2122            },
2123            activate: function activate() {
2124                if (this.isActive()) {
2125                    return true;
2126                } else if (!this.isEnabled() || this.eventBus.before("active")) {
2127                    return false;
2128                } else {
2129                    this.active = true;
2130                    this.eventBus.trigger("active");
2131                    return true;
2132                }
2133            },
2134            deactivate: function deactivate() {
2135                if (!this.isActive()) {
2136                    return true;
2137                } else if (this.eventBus.before("idle")) {
2138                    return false;
2139                } else {
2140                    this.active = false;
2141                    this.close();
2142                    this.eventBus.trigger("idle");
2143                    return true;
2144                }
2145            },
2146            isOpen: function isOpen() {
2147                return this.menu.isOpen();
2148            },
2149            open: function open() {
2150                if (!this.isOpen() && !this.eventBus.before("open")) {
2151                    this.menu.open();
2152                    this._updateHint();
2153                    this.eventBus.trigger("open");
2154                }
2155                return this.isOpen();
2156            },
2157            close: function close() {
2158                if (this.isOpen() && !this.eventBus.before("close")) {
2159                    this.menu.close();
2160                    this.input.clearHint();
2161                    this.input.resetInputValue();
2162                    this.eventBus.trigger("close");
2163                }
2164                return !this.isOpen();
2165            },
2166            setVal: function setVal(val) {
2167                this.input.setQuery(_.toStr(val));
2168            },
2169            getVal: function getVal() {
2170                return this.input.getQuery();
2171            },
2172            select: function select($selectable) {
2173                var data = this.menu.getSelectableData($selectable);
2174                if (data && !this.eventBus.before("select", data.obj)) {
2175                    this.input.setQuery(data.val, true);
2176                    this.eventBus.trigger("select", data.obj);
2177                    this.close();
2178                    return true;
2179                }
2180                return false;
2181            },
2182            autocomplete: function autocomplete($selectable) {
2183                var query, data, isValid;
2184                query = this.input.getQuery();
2185                data = this.menu.getSelectableData($selectable);
2186                isValid = data && query !== data.val;
2187                if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
2188                    this.input.setQuery(data.val);
2189                    this.eventBus.trigger("autocomplete", data.obj);
2190                    return true;
2191                }
2192                return false;
2193            },
2194            moveCursor: function moveCursor(delta) {
2195                var query, $candidate, data, payload, cancelMove;
2196                query = this.input.getQuery();
2197                $candidate = this.menu.selectableRelativeToCursor(delta);
2198                data = this.menu.getSelectableData($candidate);
2199                payload = data ? data.obj : null;
2200                cancelMove = this._minLengthMet() && this.menu.update(query);
2201                if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
2202                    this.menu.setCursor($candidate);
2203                    if (data) {
2204                        this.input.setInputValue(data.val);
2205                    } else {
2206                        this.input.resetInputValue();
2207                        this._updateHint();
2208                    }
2209                    this.eventBus.trigger("cursorchange", payload);
2210                    return true;
2211                }
2212                return false;
2213            },
2214            destroy: function destroy() {
2215                this.input.destroy();
2216                this.menu.destroy();
2217            }
2218        });
2219        return Typeahead;
2220        function c(ctx) {
2221            var methods = [].slice.call(arguments, 1);
2222            return function() {
2223                var args = [].slice.call(arguments);
2224                _.each(methods, function(method) {
2225                    return ctx[method].apply(ctx, args);
2226                });
2227            };
2228        }
2229    }();
2230    (function() {
2231        "use strict";
2232        var old, keys, methods;
2233        old = $.fn.typeahead;
2234        keys = {
2235            www: "tt-www",
2236            attrs: "tt-attrs",
2237            typeahead: "tt-typeahead"
2238        };
2239        methods = {
2240            initialize: function initialize(o, datasets) {
2241                var www;
2242                datasets = 
2242Array
vendor: 8,576 bytes, lines 2242-2460
2242.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
2243                o = o || {};
2244                www = WWW(o.classNames);
2245                return this.each(attach);
2246                function attach() {
2247                    var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
2248                    _.each(datasets, function(d) {
2249                        d.highlight = !!o.highlight;
2250                    });
2251                    $input = $(this);
2252                    $wrapper = $(www.html.wrapper);
2253                    $hint = $elOrNull(o.hint);
2254                    $menu = $elOrNull(o.menu);
2255                    defaultHint = o.hint !== false && !$hint;
2256                    defaultMenu = o.menu !== false && !$menu;
2257                    defaultHint && ($hint = buildHintFromInput($input, www));
2258                    defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
2259                    $hint && $hint.val("");
2260                    $input = prepInput($input, www);
2261                    if (defaultHint || defaultMenu) {
2262                        $wrapper.css(www.css.wrapper);
2263                        $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
2264                        $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
2265                    }
2266                    MenuConstructor = defaultMenu ? DefaultMenu : Menu;
2267                    eventBus = new EventBus({
2268                        el: $input
2269                    });
2270                    input = new Input({
2271                        hint: $hint,
2272                        input: $input
2273                    }, www);
2274                    menu = new MenuConstructor({
2275                        node: $menu,
2276                        datasets: datasets
2277                    }, www);
2278                    typeahead = new Typeahead({
2279                        input: input,
2280                        menu: menu,
2281                        eventBus: eventBus,
2282                        minLength: o.minLength
2283                    }, www);
2284                    $input.data(keys.www, www);
2285                    $input.data(keys.typeahead, typeahead);
2286                }
2287            },
2288            isEnabled: function isEnabled() {
2289                var enabled;
2290                ttEach(this.first(), function(t) {
2291                    enabled = t.isEnabled();
2292                });
2293                return enabled;
2294            },
2295            enable: function enable() {
2296                ttEach(this, function(t) {
2297                    t.enable();
2298                });
2299                return this;
2300            },
2301            disable: function disable() {
2302                ttEach(this, function(t) {
2303                    t.disable();
2304                });
2305                return this;
2306            },
2307            isActive: function isActive() {
2308                var active;
2309                ttEach(this.first(), function(t) {
2310                    active = t.isActive();
2311                });
2312                return active;
2313            },
2314            activate: function activate() {
2315                ttEach(this, function(t) {
2316                    t.activate();
2317                });
2318                return this;
2319            },
2320            deactivate: function deactivate() {
2321                ttEach(this, function(t) {
2322                    t.deactivate();
2323                });
2324                return this;
2325            },
2326            isOpen: function isOpen() {
2327                var open;
2328                ttEach(this.first(), function(t) {
2329                    open = t.isOpen();
2330                });
2331                return open;
2332            },
2333            open: function open() {
2334                ttEach(this, function(t) {
2335                    t.open();
2336                });
2337                return this;
2338            },
2339            close: function close() {
2340                ttEach(this, function(t) {
2341                    t.close();
2342                });
2343                return this;
2344            },
2345            select: function select(el) {
2346                var success = false, $el = $(el);
2347                ttEach(this.first(), function(t) {
2348                    success = t.select($el);
2349                });
2350                return success;
2351            },
2352            autocomplete: function autocomplete(el) {
2353                var success = false, $el = $(el);
2354                ttEach(this.first(), function(t) {
2355                    success = t.autocomplete($el);
2356                });
2357                return success;
2358            },
2359            moveCursor: function moveCursoe(delta) {
2360                var success = false;
2361                ttEach(this.first(), function(t) {
2362                    success = t.moveCursor(delta);
2363                });
2364                return success;
2365            },
2366            val: function val(newVal) {
2367                var query;
2368                if (!arguments.length) {
2369                    ttEach(this.first(), function(t) {
2370                        query = t.getVal();
2371                    });
2372                    return query;
2373                } else {
2374                    ttEach(this, function(t) {
2375                        t.setVal(newVal);
2376                    });
2377                    return this;
2378                }
2379            },
2380            destroy: function destroy() {
2381                ttEach(this, function(typeahead, $input) {
2382                    revert($input);
2383                    typeahead.destroy();
2384                });
2385                return this;
2386            }
2387        };
2388        $.fn.typeahead = function(method) {
2389            if (methods[method]) {
2390                return methods[method].apply(this, [].slice.call(arguments, 1));
2391            } else {
2392                return methods.initialize.apply(this, arguments);
2393            }
2394        };
2395        $.fn.typeahead.noConflict = function noConflict() {
2396            $.fn.typeahead = old;
2397            return this;
2398        };
2399        function ttEach($els, fn) {
2400            $els.each(function() {
2401                var $input = $(this), typeahead;
2402                (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
2403            });
2404        }
2405        function buildHintFromInput($input, www) {
2406            return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
2407                autocomplete: "off",
2408                spellcheck: "false",
2409                tabindex: -1
2410            });
2411        }
2412        function prepInput($input, www) {
2413            $input.data(keys.attrs, {
2414                dir: $input.attr("dir"),
2415                autocomplete: $input.attr("autocomplete"),
2416                spellcheck: $input.attr("spellcheck"),
2417                style: $input.attr("style")
2418            });
2419            $input.addClass(www.classes.input).attr({
2420                autocomplete: "off",
2421                spellcheck: false
2422            });
2423            try {
2424                !$input.attr("dir") && $input.attr("dir", "auto");
2425            } catch (e) {}
2426            return $input;
2427        }
2428        function getBackgroundStyles($el) {
2429            return {
2430                backgroundAttachment: $el.css("background-attachment"),
2431                backgroundClip: $el.css("background-clip"),
2432                backgroundColor: $el.css("background-color"),
2433                backgroundImage: $el.css("background-image"),
2434                backgroundOrigin: $el.css("background-origin"),
2435                backgroundPosition: $el.css("background-position"),
2436                backgroundRepeat: $el.css("background-repeat"),
2437                backgroundSize: $el.css("background-size")
2438            };
2439        }
2440        function revert($input) {
2441            var www, $wrapper;
2442            www = $input.data(keys.www);
2443            $wrapper = $input.parent().filter(www.selectors.wrapper);
2444            _.each($input.data(keys.attrs), function(val, key) {
2445                _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
2446            });
2447            $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
2448            if ($wrapper.length) {
2449                $input.detach().insertAfter($wrapper);
2450                $wrapper.remove();
2451            }
2452        }
2453        function $elOrNull(obj) {
2454            var isValid, $el;
2455            isValid = _.isJQuery(obj) || _.isElement(obj);
2456            $el = isValid ? $(obj).first() : [];
2457            return $el.length ? $el : null;
2458        }
2459    })();
2460});

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.