text: /*!
   * typeahead.js 0.11.1
   * https://github.com/twitter/typeahead.js
   * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
   */
  
  (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: '<span class="' + c.wrapper + '"></span>',
                  menu: '<div class="' + c.menu + '"></div>'
              };
          }
          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());
                