diff --git a/app/assets/images/keywords/faciliter.png b/app/assets/images/keywords/faciliter.png index 35d0da530..020ba4339 100644 Binary files a/app/assets/images/keywords/faciliter.png and b/app/assets/images/keywords/faciliter.png differ diff --git a/app/assets/images/keywords/profiter.png b/app/assets/images/keywords/profiter.png index 682ea1723..0e1f016ba 100644 Binary files a/app/assets/images/keywords/profiter.png and b/app/assets/images/keywords/profiter.png differ diff --git a/app/assets/images/landing_background.jpg b/app/assets/images/landing_background.jpg index 3f25fb159..f7ddc8c98 100644 Binary files a/app/assets/images/landing_background.jpg and b/app/assets/images/landing_background.jpg differ diff --git a/vendor/assets/javascripts/typeahead.bundle.js b/vendor/assets/javascripts/typeahead.bundle.js index 64b508ac5..ffd98f320 100644 --- a/vendor/assets/javascripts/typeahead.bundle.js +++ b/vendor/assets/javascripts/typeahead.bundle.js @@ -4,2448 +4,5 @@ * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT */ -(function(root, factory) { - if (typeof define === "function" && define.amd) { - define("bloodhound", [ "jquery" ], function(a0) { - return root["Bloodhound"] = factory(a0); - }); - } else if (typeof exports === "object") { - module.exports = factory(require("jquery")); - } else { - root["Bloodhound"] = factory(jQuery); - } -})(this, function($) { - var _ = function() { - "use strict"; - return { - isMsie: function() { - return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; - }, - isBlankString: function(str) { - return !str || /^\s*$/.test(str); - }, - escapeRegExChars: function(str) { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - }, - isString: function(obj) { - return typeof obj === "string"; - }, - isNumber: function(obj) { - return typeof obj === "number"; - }, - isArray: $.isArray, - isFunction: $.isFunction, - isObject: $.isPlainObject, - isUndefined: function(obj) { - return typeof obj === "undefined"; - }, - isElement: function(obj) { - return !!(obj && obj.nodeType === 1); - }, - isJQuery: function(obj) { - return obj instanceof $; - }, - toStr: function toStr(s) { - return _.isUndefined(s) || s === null ? "" : s + ""; - }, - bind: $.proxy, - each: function(collection, cb) { - $.each(collection, reverseArgs); - function reverseArgs(index, value) { - return cb(value, index); - } - }, - map: $.map, - filter: $.grep, - every: function(obj, test) { - var result = true; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (!(result = test.call(null, val, key, obj))) { - return false; - } - }); - return !!result; - }, - some: function(obj, test) { - var result = false; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (result = test.call(null, val, key, obj)) { - return false; - } - }); - return !!result; - }, - mixin: $.extend, - identity: function(x) { - return x; - }, - clone: function(obj) { - return $.extend(true, {}, obj); - }, - getIdGenerator: function() { - var counter = 0; - return function() { - return counter++; - }; - }, - templatify: function templatify(obj) { - return $.isFunction(obj) ? obj : template; - function template() { - return String(obj); - } - }, - defer: function(fn) { - setTimeout(fn, 0); - }, - debounce: function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments, later, callNow; - later = function() { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - } - }; - callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - } - return result; - }; - }, - throttle: function(func, wait) { - var context, args, timeout, result, previous, later; - previous = 0; - later = function() { - previous = new Date(); - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date(), remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }, - stringify: function(val) { - return _.isString(val) ? val : JSON.stringify(val); - }, - noop: function() {} - }; - }(); - var VERSION = "0.11.1"; - var tokenizers = function() { - "use strict"; - return { - nonword: nonword, - whitespace: whitespace, - obj: { - nonword: getObjTokenizer(nonword), - whitespace: getObjTokenizer(whitespace) - } - }; - function whitespace(str) { - str = _.toStr(str); - return str ? str.split(/\s+/) : []; - } - function nonword(str) { - str = _.toStr(str); - return str ? str.split(/\W+/) : []; - } - function getObjTokenizer(tokenizer) { - return function setKey(keys) { - keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0); - return function tokenize(o) { - var tokens = []; - _.each(keys, function(k) { - tokens = tokens.concat(tokenizer(_.toStr(o[k]))); - }); - return tokens; - }; - }; - } - }(); - var LruCache = function() { - "use strict"; - function LruCache(maxSize) { - this.maxSize = _.isNumber(maxSize) ? maxSize : 100; - this.reset(); - if (this.maxSize <= 0) { - this.set = this.get = $.noop; - } - } - _.mixin(LruCache.prototype, { - set: function set(key, val) { - var tailItem = this.list.tail, node; - if (this.size >= this.maxSize) { - this.list.remove(tailItem); - delete this.hash[tailItem.key]; - this.size--; - } - if (node = this.hash[key]) { - node.val = val; - this.list.moveToFront(node); - } else { - node = new Node(key, val); - this.list.add(node); - this.hash[key] = node; - this.size++; - } - }, - get: function get(key) { - var node = this.hash[key]; - if (node) { - this.list.moveToFront(node); - return node.val; - } - }, - reset: function reset() { - this.size = 0; - this.hash = {}; - this.list = new List(); - } - }); - function List() { - this.head = this.tail = null; - } - _.mixin(List.prototype, { - add: function add(node) { - if (this.head) { - node.next = this.head; - this.head.prev = node; - } - this.head = node; - this.tail = this.tail || node; - }, - remove: function remove(node) { - node.prev ? node.prev.next = node.next : this.head = node.next; - node.next ? node.next.prev = node.prev : this.tail = node.prev; - }, - moveToFront: function(node) { - this.remove(node); - this.add(node); - } - }); - function Node(key, val) { - this.key = key; - this.val = val; - this.prev = this.next = null; - } - return LruCache; - }(); - var PersistentStorage = function() { - "use strict"; - var LOCAL_STORAGE; - try { - LOCAL_STORAGE = window.localStorage; - LOCAL_STORAGE.setItem("~~~", "!"); - LOCAL_STORAGE.removeItem("~~~"); - } catch (err) { - LOCAL_STORAGE = null; - } - function PersistentStorage(namespace, override) { - this.prefix = [ "__", namespace, "__" ].join(""); - this.ttlKey = "__ttl__"; - this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix)); - this.ls = override || LOCAL_STORAGE; - !this.ls && this._noop(); - } - _.mixin(PersistentStorage.prototype, { - _prefix: function(key) { - return this.prefix + key; - }, - _ttlKey: function(key) { - return this._prefix(key) + this.ttlKey; - }, - _noop: function() { - this.get = this.set = this.remove = this.clear = this.isExpired = _.noop; - }, - _safeSet: function(key, val) { - try { - this.ls.setItem(key, val); - } catch (err) { - if (err.name === "QuotaExceededError") { - this.clear(); - this._noop(); - } - } - }, - get: function(key) { - if (this.isExpired(key)) { - this.remove(key); - } - return decode(this.ls.getItem(this._prefix(key))); - }, - set: function(key, val, ttl) { - if (_.isNumber(ttl)) { - this._safeSet(this._ttlKey(key), encode(now() + ttl)); - } else { - this.ls.removeItem(this._ttlKey(key)); - } - return this._safeSet(this._prefix(key), encode(val)); - }, - remove: function(key) { - this.ls.removeItem(this._ttlKey(key)); - this.ls.removeItem(this._prefix(key)); - return this; - }, - clear: function() { - var i, keys = gatherMatchingKeys(this.keyMatcher); - for (i = keys.length; i--; ) { - this.remove(keys[i]); - } - return this; - }, - isExpired: function(key) { - var ttl = decode(this.ls.getItem(this._ttlKey(key))); - return _.isNumber(ttl) && now() > ttl ? true : false; - } - }); - return PersistentStorage; - function now() { - return new Date().getTime(); - } - function encode(val) { - return JSON.stringify(_.isUndefined(val) ? null : val); - } - function decode(val) { - return $.parseJSON(val); - } - function gatherMatchingKeys(keyMatcher) { - var i, key, keys = [], len = LOCAL_STORAGE.length; - for (i = 0; i < len; i++) { - if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) { - keys.push(key.replace(keyMatcher, "")); - } - } - return keys; - } - }(); - var Transport = function() { - "use strict"; - var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10); - function Transport(o) { - o = o || {}; - this.cancelled = false; - this.lastReq = null; - this._send = o.transport; - this._get = o.limiter ? o.limiter(this._get) : this._get; - this._cache = o.cache === false ? new LruCache(0) : sharedCache; - } - Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { - maxPendingRequests = num; - }; - Transport.resetCache = function resetCache() { - sharedCache.reset(); - }; - _.mixin(Transport.prototype, { - _fingerprint: function fingerprint(o) { - o = o || {}; - return o.url + o.type + $.param(o.data || {}); - }, - _get: function(o, cb) { - var that = this, fingerprint, jqXhr; - fingerprint = this._fingerprint(o); - if (this.cancelled || fingerprint !== this.lastReq) { - return; - } - if (jqXhr = pendingRequests[fingerprint]) { - jqXhr.done(done).fail(fail); - } else if (pendingRequestsCount < maxPendingRequests) { - pendingRequestsCount++; - pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always); - } else { - this.onDeckRequestArgs = [].slice.call(arguments, 0); - } - function done(resp) { - cb(null, resp); - that._cache.set(fingerprint, resp); - } - function fail() { - cb(true); - } - function always() { - pendingRequestsCount--; - delete pendingRequests[fingerprint]; - if (that.onDeckRequestArgs) { - that._get.apply(that, that.onDeckRequestArgs); - that.onDeckRequestArgs = null; - } - } - }, - get: function(o, cb) { - var resp, fingerprint; - cb = cb || $.noop; - o = _.isString(o) ? { - url: o - } : o || {}; - fingerprint = this._fingerprint(o); - this.cancelled = false; - this.lastReq = fingerprint; - if (resp = this._cache.get(fingerprint)) { - cb(null, resp); - } else { - this._get(o, cb); - } - }, - cancel: function() { - this.cancelled = true; - } - }); - return Transport; - }(); - var SearchIndex = window.SearchIndex = function() { - "use strict"; - var CHILDREN = "c", IDS = "i"; - function SearchIndex(o) { - o = o || {}; - if (!o.datumTokenizer || !o.queryTokenizer) { - $.error("datumTokenizer and queryTokenizer are both required"); - } - this.identify = o.identify || _.stringify; - this.datumTokenizer = o.datumTokenizer; - this.queryTokenizer = o.queryTokenizer; - this.reset(); - } - _.mixin(SearchIndex.prototype, { - bootstrap: function bootstrap(o) { - this.datums = o.datums; - this.trie = o.trie; - }, - add: function(data) { - var that = this; - data = _.isArray(data) ? data : [ data ]; - _.each(data, function(datum) { - var id, tokens; - that.datums[id = that.identify(datum)] = datum; - tokens = normalizeTokens(that.datumTokenizer(datum)); - _.each(tokens, function(token) { - var node, chars, ch; - node = that.trie; - chars = token.split(""); - while (ch = chars.shift()) { - node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode()); - node[IDS].push(id); - } - }); - }); - }, - get: function get(ids) { - var that = this; - return _.map(ids, function(id) { - return that.datums[id]; - }); - }, - search: function search(query) { - var that = this, tokens, matches; - tokens = normalizeTokens(this.queryTokenizer(query)); - _.each(tokens, function(token) { - var node, chars, ch, ids; - if (matches && matches.length === 0) { - return false; - } - node = that.trie; - chars = token.split(""); - while (node && (ch = chars.shift())) { - node = node[CHILDREN][ch]; - } - if (node && chars.length === 0) { - ids = node[IDS].slice(0); - matches = matches ? getIntersection(matches, ids) : ids; - } else { - matches = []; - return false; - } - }); - return matches ? _.map(unique(matches), function(id) { - return that.datums[id]; - }) : []; - }, - all: function all() { - var values = []; - for (var key in this.datums) { - values.push(this.datums[key]); - } - return values; - }, - reset: function reset() { - this.datums = {}; - this.trie = newNode(); - }, - serialize: function serialize() { - return { - datums: this.datums, - trie: this.trie - }; - } - }); - return SearchIndex; - function normalizeTokens(tokens) { - tokens = _.filter(tokens, function(token) { - return !!token; - }); - tokens = _.map(tokens, function(token) { - return token.toLowerCase(); - }); - return tokens; - } - function newNode() { - var node = {}; - node[IDS] = []; - node[CHILDREN] = {}; - return node; - } - function unique(array) { - var seen = {}, uniques = []; - for (var i = 0, len = array.length; i < len; i++) { - if (!seen[array[i]]) { - seen[array[i]] = true; - uniques.push(array[i]); - } - } - return uniques; - } - function getIntersection(arrayA, arrayB) { - var ai = 0, bi = 0, intersection = []; - arrayA = arrayA.sort(); - arrayB = arrayB.sort(); - var lenArrayA = arrayA.length, lenArrayB = arrayB.length; - while (ai < lenArrayA && bi < lenArrayB) { - if (arrayA[ai] < arrayB[bi]) { - ai++; - } else if (arrayA[ai] > arrayB[bi]) { - bi++; - } else { - intersection.push(arrayA[ai]); - ai++; - bi++; - } - } - return intersection; - } - }(); - var Prefetch = function() { - "use strict"; - var keys; - keys = { - data: "data", - protocol: "protocol", - thumbprint: "thumbprint" - }; - function Prefetch(o) { - this.url = o.url; - this.ttl = o.ttl; - this.cache = o.cache; - this.prepare = o.prepare; - this.transform = o.transform; - this.transport = o.transport; - this.thumbprint = o.thumbprint; - this.storage = new PersistentStorage(o.cacheKey); - } - _.mixin(Prefetch.prototype, { - _settings: function settings() { - return { - url: this.url, - type: "GET", - dataType: "json" - }; - }, - store: function store(data) { - if (!this.cache) { - return; - } - this.storage.set(keys.data, data, this.ttl); - this.storage.set(keys.protocol, location.protocol, this.ttl); - this.storage.set(keys.thumbprint, this.thumbprint, this.ttl); - }, - fromCache: function fromCache() { - var stored = {}, isExpired; - if (!this.cache) { - return null; - } - stored.data = this.storage.get(keys.data); - stored.protocol = this.storage.get(keys.protocol); - stored.thumbprint = this.storage.get(keys.thumbprint); - isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol; - return stored.data && !isExpired ? stored.data : null; - }, - fromNetwork: function(cb) { - var that = this, settings; - if (!cb) { - return; - } - settings = this.prepare(this._settings()); - this.transport(settings).fail(onError).done(onResponse); - function onError() { - cb(true); - } - function onResponse(resp) { - cb(null, that.transform(resp)); - } - }, - clear: function clear() { - this.storage.clear(); - return this; - } - }); - return Prefetch; - }(); - var Remote = function() { - "use strict"; - function Remote(o) { - this.url = o.url; - this.prepare = o.prepare; - this.transform = o.transform; - this.transport = new Transport({ - cache: o.cache, - limiter: o.limiter, - transport: o.transport - }); - } - _.mixin(Remote.prototype, { - _settings: function settings() { - return { - url: this.url, - type: "GET", - dataType: "json" - }; - }, - get: function get(query, cb) { - var that = this, settings; - if (!cb) { - return; - } - query = query || ""; - settings = this.prepare(query, this._settings()); - return this.transport.get(settings, onResponse); - function onResponse(err, resp) { - err ? cb([]) : cb(that.transform(resp)); - } - }, - cancelLastRequest: function cancelLastRequest() { - this.transport.cancel(); - } - }); - return Remote; - }(); - var oParser = function() { - "use strict"; - return function parse(o) { - var defaults, sorter; - defaults = { - initialize: true, - identify: _.stringify, - datumTokenizer: null, - queryTokenizer: null, - sufficient: 5, - sorter: null, - local: [], - prefetch: null, - remote: null - }; - o = _.mixin(defaults, o || {}); - !o.datumTokenizer && $.error("datumTokenizer is required"); - !o.queryTokenizer && $.error("queryTokenizer is required"); - sorter = o.sorter; - o.sorter = sorter ? function(x) { - return x.sort(sorter); - } : _.identity; - o.local = _.isFunction(o.local) ? o.local() : o.local; - o.prefetch = parsePrefetch(o.prefetch); - o.remote = parseRemote(o.remote); - return o; - }; - function parsePrefetch(o) { - var defaults; - if (!o) { - return null; - } - defaults = { - url: null, - ttl: 24 * 60 * 60 * 1e3, - cache: true, - cacheKey: null, - thumbprint: "", - prepare: _.identity, - transform: _.identity, - transport: null - }; - o = _.isString(o) ? { - url: o - } : o; - o = _.mixin(defaults, o); - !o.url && $.error("prefetch requires url to be set"); - o.transform = o.filter || o.transform; - o.cacheKey = o.cacheKey || o.url; - o.thumbprint = VERSION + o.thumbprint; - o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; - return o; - } - function parseRemote(o) { - var defaults; - if (!o) { - return; - } - defaults = { - url: null, - cache: true, - prepare: null, - replace: null, - wildcard: null, - limiter: null, - rateLimitBy: "debounce", - rateLimitWait: 300, - transform: _.identity, - transport: null - }; - o = _.isString(o) ? { - url: o - } : o; - o = _.mixin(defaults, o); - !o.url && $.error("remote requires url to be set"); - o.transform = o.filter || o.transform; - o.prepare = toRemotePrepare(o); - o.limiter = toLimiter(o); - o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax; - delete o.replace; - delete o.wildcard; - delete o.rateLimitBy; - delete o.rateLimitWait; - return o; - } - function toRemotePrepare(o) { - var prepare, replace, wildcard; - prepare = o.prepare; - replace = o.replace; - wildcard = o.wildcard; - if (prepare) { - return prepare; - } - if (replace) { - prepare = prepareByReplace; - } else if (o.wildcard) { - prepare = prepareByWildcard; - } else { - prepare = idenityPrepare; - } - return prepare; - function prepareByReplace(query, settings) { - settings.url = replace(settings.url, query); - return settings; - } - function prepareByWildcard(query, settings) { - settings.url = settings.url.replace(wildcard, encodeURIComponent(query)); - return settings; - } - function idenityPrepare(query, settings) { - return settings; - } - } - function toLimiter(o) { - var limiter, method, wait; - limiter = o.limiter; - method = o.rateLimitBy; - wait = o.rateLimitWait; - if (!limiter) { - limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait); - } - return limiter; - function debounce(wait) { - return function debounce(fn) { - return _.debounce(fn, wait); - }; - } - function throttle(wait) { - return function throttle(fn) { - return _.throttle(fn, wait); - }; - } - } - function callbackToDeferred(fn) { - return function wrapper(o) { - var deferred = $.Deferred(); - fn(o, onSuccess, onError); - return deferred; - function onSuccess(resp) { - _.defer(function() { - deferred.resolve(resp); - }); - } - function onError(err) { - _.defer(function() { - deferred.reject(err); - }); - } - }; - } - }(); - var Bloodhound = function() { - "use strict"; - var old; - old = window && window.Bloodhound; - function Bloodhound(o) { - o = oParser(o); - this.sorter = o.sorter; - this.identify = o.identify; - this.sufficient = o.sufficient; - this.local = o.local; - this.remote = o.remote ? new Remote(o.remote) : null; - this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null; - this.index = new SearchIndex({ - identify: this.identify, - datumTokenizer: o.datumTokenizer, - queryTokenizer: o.queryTokenizer - }); - o.initialize !== false && this.initialize(); - } - Bloodhound.noConflict = function noConflict() { - window && (window.Bloodhound = old); - return Bloodhound; - }; - Bloodhound.tokenizers = tokenizers; - _.mixin(Bloodhound.prototype, { - __ttAdapter: function ttAdapter() { - var that = this; - return this.remote ? withAsync : withoutAsync; - function withAsync(query, sync, async) { - return that.search(query, sync, async); - } - function withoutAsync(query, sync) { - return that.search(query, sync); - } - }, - _loadPrefetch: function loadPrefetch() { - var that = this, deferred, serialized; - deferred = $.Deferred(); - if (!this.prefetch) { - deferred.resolve(); - } else if (serialized = this.prefetch.fromCache()) { - this.index.bootstrap(serialized); - deferred.resolve(); - } else { - this.prefetch.fromNetwork(done); - } - return deferred.promise(); - function done(err, data) { - if (err) { - return deferred.reject(); - } - that.add(data); - that.prefetch.store(that.index.serialize()); - deferred.resolve(); - } - }, - _initialize: function initialize() { - var that = this, deferred; - this.clear(); - (this.initPromise = this._loadPrefetch()).done(addLocalToIndex); - return this.initPromise; - function addLocalToIndex() { - that.add(that.local); - } - }, - initialize: function initialize(force) { - return !this.initPromise || force ? this._initialize() : this.initPromise; - }, - add: function add(data) { - this.index.add(data); - return this; - }, - get: function get(ids) { - ids = _.isArray(ids) ? ids : [].slice.call(arguments); - return this.index.get(ids); - }, - search: function search(query, sync, async) { - var that = this, local; - local = this.sorter(this.index.search(query)); - sync(this.remote ? local.slice() : local); - if (this.remote && local.length < this.sufficient) { - this.remote.get(query, processRemote); - } else if (this.remote) { - this.remote.cancelLastRequest(); - } - return this; - function processRemote(remote) { - var nonDuplicates = []; - _.each(remote, function(r) { - !_.some(local, function(l) { - return that.identify(r) === that.identify(l); - }) && nonDuplicates.push(r); - }); - async && async(nonDuplicates); - } - }, - all: function all() { - return this.index.all(); - }, - clear: function clear() { - this.index.reset(); - return this; - }, - clearPrefetchCache: function clearPrefetchCache() { - this.prefetch && this.prefetch.clear(); - return this; - }, - clearRemoteCache: function clearRemoteCache() { - Transport.resetCache(); - return this; - }, - ttAdapter: function ttAdapter() { - return this.__ttAdapter(); - } - }); - return Bloodhound; - }(); - return Bloodhound; -}); - -(function(root, factory) { - if (typeof define === "function" && define.amd) { - define("typeahead.js", [ "jquery" ], function(a0) { - return factory(a0); - }); - } else if (typeof exports === "object") { - module.exports = factory(require("jquery")); - } else { - factory(jQuery); - } -})(this, function($) { - var _ = function() { - "use strict"; - return { - isMsie: function() { - return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; - }, - isBlankString: function(str) { - return !str || /^\s*$/.test(str); - }, - escapeRegExChars: function(str) { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - }, - isString: function(obj) { - return typeof obj === "string"; - }, - isNumber: function(obj) { - return typeof obj === "number"; - }, - isArray: $.isArray, - isFunction: $.isFunction, - isObject: $.isPlainObject, - isUndefined: function(obj) { - return typeof obj === "undefined"; - }, - isElement: function(obj) { - return !!(obj && obj.nodeType === 1); - }, - isJQuery: function(obj) { - return obj instanceof $; - }, - toStr: function toStr(s) { - return _.isUndefined(s) || s === null ? "" : s + ""; - }, - bind: $.proxy, - each: function(collection, cb) { - $.each(collection, reverseArgs); - function reverseArgs(index, value) { - return cb(value, index); - } - }, - map: $.map, - filter: $.grep, - every: function(obj, test) { - var result = true; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (!(result = test.call(null, val, key, obj))) { - return false; - } - }); - return !!result; - }, - some: function(obj, test) { - var result = false; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (result = test.call(null, val, key, obj)) { - return false; - } - }); - return !!result; - }, - mixin: $.extend, - identity: function(x) { - return x; - }, - clone: function(obj) { - return $.extend(true, {}, obj); - }, - getIdGenerator: function() { - var counter = 0; - return function() { - return counter++; - }; - }, - templatify: function templatify(obj) { - return $.isFunction(obj) ? obj : template; - function template() { - return String(obj); - } - }, - defer: function(fn) { - setTimeout(fn, 0); - }, - debounce: function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments, later, callNow; - later = function() { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - } - }; - callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - } - return result; - }; - }, - throttle: function(func, wait) { - var context, args, timeout, result, previous, later; - previous = 0; - later = function() { - previous = new Date(); - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date(), remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }, - stringify: function(val) { - return _.isString(val) ? val : JSON.stringify(val); - }, - noop: function() {} - }; - }(); - var WWW = function() { - "use strict"; - var defaultClassNames = { - wrapper: "twitter-typeahead", - input: "tt-input", - hint: "tt-hint", - menu: "tt-menu", - dataset: "tt-dataset", - suggestion: "tt-suggestion", - selectable: "tt-selectable", - empty: "tt-empty", - open: "tt-open", - cursor: "tt-cursor", - highlight: "tt-highlight" - }; - return build; - function build(o) { - var www, classes; - classes = _.mixin({}, defaultClassNames, o); - www = { - css: buildCss(), - classes: classes, - html: buildHtml(classes), - selectors: buildSelectors(classes) - }; - return { - css: www.css, - html: www.html, - classes: www.classes, - selectors: www.selectors, - mixin: function(o) { - _.mixin(o, www); - } - }; - } - function buildHtml(c) { - return { - wrapper: '', - menu: '
' - }; - } - function buildSelectors(classes) { - var selectors = {}; - _.each(classes, function(v, k) { - selectors[k] = "." + v; - }); - return selectors; - } - function buildCss() { - var css = { - wrapper: { - position: "relative", - display: "inline-block" - }, - hint: { - position: "absolute", - top: "0", - left: "0", - borderColor: "transparent", - boxShadow: "none", - opacity: "1" - }, - input: { - position: "relative", - verticalAlign: "top", - backgroundColor: "transparent" - }, - inputWithNoHint: { - position: "relative", - verticalAlign: "top" - }, - menu: { - position: "absolute", - top: "100%", - left: "0", - zIndex: "100", - display: "none" - }, - ltr: { - left: "0", - right: "auto" - }, - rtl: { - left: "auto", - right: " 0" - } - }; - if (_.isMsie()) { - _.mixin(css.input, { - backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" - }); - } - return css; - } - }(); - var EventBus = function() { - "use strict"; - var namespace, deprecationMap; - namespace = "typeahead:"; - deprecationMap = { - render: "rendered", - cursorchange: "cursorchanged", - select: "selected", - autocomplete: "autocompleted" - }; - function EventBus(o) { - if (!o || !o.el) { - $.error("EventBus initialized without el"); - } - this.$el = $(o.el); - } - _.mixin(EventBus.prototype, { - _trigger: function(type, args) { - var $e; - $e = $.Event(namespace + type); - (args = args || []).unshift($e); - this.$el.trigger.apply(this.$el, args); - return $e; - }, - before: function(type) { - var args, $e; - args = [].slice.call(arguments, 1); - $e = this._trigger("before" + type, args); - return $e.isDefaultPrevented(); - }, - trigger: function(type) { - var deprecatedType; - this._trigger(type, [].slice.call(arguments, 1)); - if (deprecatedType = deprecationMap[type]) { - this._trigger(deprecatedType, [].slice.call(arguments, 1)); - } - } - }); - return EventBus; - }(); - var EventEmitter = function() { - "use strict"; - var splitter = /\s+/, nextTick = getNextTick(); - return { - onSync: onSync, - onAsync: onAsync, - off: off, - trigger: trigger - }; - function on(method, types, cb, context) { - var type; - if (!cb) { - return this; - } - types = types.split(splitter); - cb = context ? bindContext(cb, context) : cb; - this._callbacks = this._callbacks || {}; - while (type = types.shift()) { - this._callbacks[type] = this._callbacks[type] || { - sync: [], - async: [] - }; - this._callbacks[type][method].push(cb); - } - return this; - } - function onAsync(types, cb, context) { - return on.call(this, "async", types, cb, context); - } - function onSync(types, cb, context) { - return on.call(this, "sync", types, cb, context); - } - function off(types) { - var type; - if (!this._callbacks) { - return this; - } - types = types.split(splitter); - while (type = types.shift()) { - delete this._callbacks[type]; - } - return this; - } - function trigger(types) { - var type, callbacks, args, syncFlush, asyncFlush; - if (!this._callbacks) { - return this; - } - types = types.split(splitter); - args = [].slice.call(arguments, 1); - while ((type = types.shift()) && (callbacks = this._callbacks[type])) { - syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); - asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); - syncFlush() && nextTick(asyncFlush); - } - return this; - } - function getFlush(callbacks, context, args) { - return flush; - function flush() { - var cancelled; - for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { - cancelled = callbacks[i].apply(context, args) === false; - } - return !cancelled; - } - } - function getNextTick() { - var nextTickFn; - if (window.setImmediate) { - nextTickFn = function nextTickSetImmediate(fn) { - setImmediate(function() { - fn(); - }); - }; - } else { - nextTickFn = function nextTickSetTimeout(fn) { - setTimeout(function() { - fn(); - }, 0); - }; - } - return nextTickFn; - } - function bindContext(fn, context) { - return fn.bind ? fn.bind(context) : function() { - fn.apply(context, [].slice.call(arguments, 0)); - }; - } - }(); - var highlight = function(doc) { - "use strict"; - var defaults = { - node: null, - pattern: null, - tagName: "strong", - className: null, - wordsOnly: false, - caseSensitive: false - }; - return function hightlight(o) { - var regex; - o = _.mixin({}, defaults, o); - if (!o.node || !o.pattern) { - return; - } - o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; - regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly); - traverse(o.node, hightlightTextNode); - function hightlightTextNode(textNode) { - var match, patternNode, wrapperNode; - if (match = regex.exec(textNode.data)) { - wrapperNode = doc.createElement(o.tagName); - o.className && (wrapperNode.className = o.className); - patternNode = textNode.splitText(match.index); - patternNode.splitText(match[0].length); - wrapperNode.appendChild(patternNode.cloneNode(true)); - textNode.parentNode.replaceChild(wrapperNode, patternNode); - } - return !!match; - } - function traverse(el, hightlightTextNode) { - var childNode, TEXT_NODE_TYPE = 3; - for (var i = 0; i < el.childNodes.length; i++) { - childNode = el.childNodes[i]; - if (childNode.nodeType === TEXT_NODE_TYPE) { - i += hightlightTextNode(childNode) ? 1 : 0; - } else { - traverse(childNode, hightlightTextNode); - } - } - } - }; - function getRegex(patterns, caseSensitive, wordsOnly) { - var escapedPatterns = [], regexStr; - for (var i = 0, len = patterns.length; i < len; i++) { - escapedPatterns.push(_.escapeRegExChars(patterns[i])); - } - regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; - return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); - } - }(window.document); - var Input = function() { - "use strict"; - var specialKeyCodeMap; - specialKeyCodeMap = { - 9: "tab", - 27: "esc", - 37: "left", - 39: "right", - 13: "enter", - 38: "up", - 40: "down" - }; - function Input(o, www) { - o = o || {}; - if (!o.input) { - $.error("input is missing"); - } - www.mixin(this); - this.$hint = $(o.hint); - this.$input = $(o.input); - this.query = this.$input.val(); - this.queryWhenFocused = this.hasFocus() ? this.query : null; - this.$overflowHelper = buildOverflowHelper(this.$input); - this._checkLanguageDirection(); - if (this.$hint.length === 0) { - this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; - } - } - Input.normalizeQuery = function(str) { - return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); - }; - _.mixin(Input.prototype, EventEmitter, { - _onBlur: function onBlur() { - this.resetInputValue(); - this.trigger("blurred"); - }, - _onFocus: function onFocus() { - this.queryWhenFocused = this.query; - this.trigger("focused"); - }, - _onKeydown: function onKeydown($e) { - var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; - this._managePreventDefault(keyName, $e); - if (keyName && this._shouldTrigger(keyName, $e)) { - this.trigger(keyName + "Keyed", $e); - } - }, - _onInput: function onInput() { - this._setQuery(this.getInputValue()); - this.clearHintIfInvalid(); - this._checkLanguageDirection(); - }, - _managePreventDefault: function managePreventDefault(keyName, $e) { - var preventDefault; - switch (keyName) { - case "up": - case "down": - preventDefault = !withModifier($e); - break; - - default: - preventDefault = false; - } - preventDefault && $e.preventDefault(); - }, - _shouldTrigger: function shouldTrigger(keyName, $e) { - var trigger; - switch (keyName) { - case "tab": - trigger = !withModifier($e); - break; - - default: - trigger = true; - } - return trigger; - }, - _checkLanguageDirection: function checkLanguageDirection() { - var dir = (this.$input.css("direction") || "ltr").toLowerCase(); - if (this.dir !== dir) { - this.dir = dir; - this.$hint.attr("dir", dir); - this.trigger("langDirChanged", dir); - } - }, - _setQuery: function setQuery(val, silent) { - var areEquivalent, hasDifferentWhitespace; - areEquivalent = areQueriesEquivalent(val, this.query); - hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false; - this.query = val; - if (!silent && !areEquivalent) { - this.trigger("queryChanged", this.query); - } else if (!silent && hasDifferentWhitespace) { - this.trigger("whitespaceChanged", this.query); - } - }, - bind: function() { - var that = this, onBlur, onFocus, onKeydown, onInput; - onBlur = _.bind(this._onBlur, this); - onFocus = _.bind(this._onFocus, this); - onKeydown = _.bind(this._onKeydown, this); - onInput = _.bind(this._onInput, this); - this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); - if (!_.isMsie() || _.isMsie() > 9) { - this.$input.on("input.tt", onInput); - } else { - this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { - if (specialKeyCodeMap[$e.which || $e.keyCode]) { - return; - } - _.defer(_.bind(that._onInput, that, $e)); - }); - } - return this; - }, - focus: function focus() { - this.$input.focus(); - }, - blur: function blur() { - this.$input.blur(); - }, - getLangDir: function getLangDir() { - return this.dir; - }, - getQuery: function getQuery() { - return this.query || ""; - }, - setQuery: function setQuery(val, silent) { - this.setInputValue(val); - this._setQuery(val, silent); - }, - hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() { - return this.query !== this.queryWhenFocused; - }, - getInputValue: function getInputValue() { - return this.$input.val(); - }, - setInputValue: function setInputValue(value) { - this.$input.val(value); - this.clearHintIfInvalid(); - this._checkLanguageDirection(); - }, - resetInputValue: function resetInputValue() { - this.setInputValue(this.query); - }, - getHint: function getHint() { - return this.$hint.val(); - }, - setHint: function setHint(value) { - this.$hint.val(value); - }, - clearHint: function clearHint() { - this.setHint(""); - }, - clearHintIfInvalid: function clearHintIfInvalid() { - var val, hint, valIsPrefixOfHint, isValid; - val = this.getInputValue(); - hint = this.getHint(); - valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; - isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); - !isValid && this.clearHint(); - }, - hasFocus: function hasFocus() { - return this.$input.is(":focus"); - }, - hasOverflow: function hasOverflow() { - var constraint = this.$input.width() - 2; - this.$overflowHelper.text(this.getInputValue()); - return this.$overflowHelper.width() >= constraint; - }, - isCursorAtEnd: function() { - var valueLength, selectionStart, range; - valueLength = this.$input.val().length; - selectionStart = this.$input[0].selectionStart; - if (_.isNumber(selectionStart)) { - return selectionStart === valueLength; - } else if (document.selection) { - range = document.selection.createRange(); - range.moveStart("character", -valueLength); - return valueLength === range.text.length; - } - return true; - }, - destroy: function destroy() { - this.$hint.off(".tt"); - this.$input.off(".tt"); - this.$overflowHelper.remove(); - this.$hint = this.$input = this.$overflowHelper = $("