Author: Roy Orbitson (Roy-Orbison)
Committer: GitHub (web-flow)
Pusher: sy-records
Date: 2024-08-09T12:11:16+08:00

Commit: 
https://github.com/php/web-php/commit/2dcf9c37963b171224a7182a850deb715ad6cf64
Raw diff: 
https://github.com/php/web-php/commit/2dcf9c37963b171224a7182a850deb715ad6cf64.diff

Fuzzy search of docs (#1007)

Changed paths:
  A  js/ext/FuzzySearch.min.js
  A  js/ext/typeahead.jquery.min.js
  D  js/ext/typeahead.min.js
  M  include/footer.inc
  M  js/search.js
  M  styles/theme-base.css


Diff:

diff --git a/include/footer.inc b/include/footer.inc
index f4dad0d68e..778a3cb55f 100644
--- a/include/footer.inc
+++ b/include/footer.inc
@@ -99,7 +99,7 @@ if (!empty($_SERVER['BASE_PAGE'])
  <!-- External and third party libraries. -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"; 
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" 
crossorigin="anonymous"></script>
 <?php
- $jsfiles = ["ext/hogan-3.0.2.min.js", "ext/typeahead.min.js", 
"ext/mousetrap.min.js", "ext/jquery.scrollTo.min.js", "search.js", "common.js"];
+ $jsfiles = ["ext/hogan-3.0.2.min.js", "ext/typeahead.jquery.min.js", 
"ext/FuzzySearch.min.js", "ext/mousetrap.min.js", "ext/jquery.scrollTo.min.js", 
"search.js", "common.js"];
  foreach ($jsfiles as $filename) {
    $path = dirname(__DIR__) . '/js/' . $filename;
    echo '<script src="/cached.php?t=' . @filemtime($path) . '&amp;f=/js/' . 
$filename . '"></script>' . "\n";
diff --git a/js/ext/FuzzySearch.min.js b/js/ext/FuzzySearch.min.js
new file mode 100644
index 0000000000..ac8d3d6c9d
--- /dev/null
+++ b/js/ext/FuzzySearch.min.js
@@ -0,0 +1,10 @@
+/**
+ * @license FuzzySearch.js
+ * Autocomplete suggestion engine using approximate string matching
+ * https://github.com/jeancroy/FuzzySearch
+ *
+ * Copyright (c) 2015, Jean Christophe Roy
+ * Licensed under The MIT License.
+ * http://opensource.org/licenses/MIT
+ */
+!function(){"use strict";function a(b){return void 0===b&&(b={}),this 
instanceof a?void 
a.setOptions(this,b,a.defaultOptions,F,!0,this._optionsHook):new a(b)}function 
b(a,b){for(var c in a)a.hasOwnProperty(c)&&(this[c]=b.hasOwnProperty(c)&&void 
0!==b[c]?b[c]:a[c])}function c(a,b){for(var c in 
b)b.hasOwnProperty(c)&&(a[c]=b[c])}function d(a,b){for(var 
c=b.length,d=0,e=-1;++e<c;){var 
f=b[e],g=f.length;a.substr(d,g)===f&&(d+=g)}return d>0?a.substr(d):a}function 
e(a){var b=a.length;if(!b)return null;for(var 
c=g(a[0]),d=0;++d<b;)c+="|"+g(a[d]);return new 
RegExp("(?:^|\\s)\\s*("+c+"):\\s*","g")}function f(a){var 
b=a.length;if(!b)return null;var c=g(a);return new 
RegExp("(?:^|["+c+"])+([^"+c+"])[^"+c+"]*","g")}function g(a){var 
b=/[\-\[\]\/\{}\(\)\*\+\?\.\\\^\$\|]/g;return a.replace(b,"\\$&")}function 
h(a,b,c,d,e,f){this.item=a,this.fields=b,this.score=c,this.matchIndex=d,this.subIndex=e,this.sortKey=f}function
 i(a,b){var c=b.score-a.score;if(0!==c)return c;var 
d=a.sortKey,e=b.sortKey;return d>e?1:e>d?-1:0}function 
j(a,b,c,d,e,f,g){this.normalized=a,this.words=b,this.tokens_groups=c,this.fused_str=d,this.fused_map=e,this.fused_score=0,this.has_children=f,this.children=g}function
 k(a,b,c){this.tokens=a,this.map=b,this.gate=c;for(var d=a.length,e=-1,f=new 
Array(d);++e<d;)f[e]=0;this.score_item=f.slice(),this.score_field=f.slice(),this.field_pos=f}function
 l(a,b){this.start=a,this.end=b}function 
m(a,b){this.item=a,this.fields=b}function n(a,b,c,d){for(var 
e,f,g,h=b.length;h>d&&(e=b[d++],"*"!==e&&""!==e);){if(null==a||!(e in a))return 
c;a=a[e]}if(null==a)return c;var i=Object.prototype.toString.call(a),j="[object 
Array]"===i,k="[object 
Object]"===i;if(d===h)if(j)for(f=-1,g=a.length;++f<g;)c.push(o(a[f],""));else 
if(k)for(e in a)a.hasOwnProperty(e)&&c.push(o(a[e],""));else 
c.push(o(a,""));else 
if("*"===e)if(j)for(f=-1,g=a.length;++f<g;)n(a[f],b,c,d);else if(k)for(e in 
a)a.hasOwnProperty(e)&&n(a[e],b,c,d);return c}function o(a,b){return 
null==a?b:a.toString()}function p(a){for(var 
b=[],c={},d=a.fields,e=0;e<d.length;e++)for(var 
f=d[e],g=0;g<f.length;g++)for(var h=f[g],i=0;i<h.length;i++)r(h[i],b,c);return 
b}function q(a){var 
b,c,d=[],e={},f=a.words;for(b=0;b<f.length;b++)r(f[b],d,e);var 
g=a.children;for(b=0;b<g.length;b++)for(f=g[b].words,c=0;f>c;c++)r(f[c],d,e);return
 d}function r(a,b,c){var 
d=a.length;0!=d&&(d>=3&&t(a,6,b,c),d>=2&&s(a,4,b,c),u(a[0],b,c))}function 
s(a,b,c,d){for(var e=Math.min(a.length,b),f=0;e-1>f;f++)for(var 
g=f+1;e>g;g++)u(a[f]+a[g],c,d);return c}function t(a,b,c,d){for(var 
e=Math.min(a.length,b),f=0;e-2>f;f++)for(var g=f+1;e-1>g;g++)for(var 
h=g+1;e>h;h++)u(a[f]+a[g]+a[h],c,d);return c}function u(a,b,c){a in 
c||(c[a]=!0,b.push(a))}function v(a,b){var c={};if(0==a.length)return[];for(var 
d=0;d<a.length;d++){var e=a[d];if(e in b)for(var f=b[e],g=0;g<f.length;g++){var 
h=f[g];h in c?c[h]++:c[h]=1}}var i=[];for(var j in 
c)c.hasOwnProperty(j)&&i.push(new w(j,c[j]));return 
i=i.sort(function(a,b){return b.count-a.count})}function 
w(a,b){this.id=a,this.count=b}function x(a){return 
a?a.toLowerCase().replace(/[^\u0000-\u007E]/g,function(a){return 
H[a]||a}):""}function y(){for(var 
a="\xe3\xe0\xe1\xe4\xe2\xe6\u1ebd\xe8\xe9\xeb\xea\xec\xed\xef\xee\xf5\xf2\xf3\xf6\xf4\u0153\xf9\xfa\xfc\xfb\xf1\xe7",b="aaaaaaeeeeeiiiioooooouuuunc",c={},d=0;d<a.length;d++)c[a[d]]=b[d];return
 c}function z(a,b,c,d){var e=c.length,f=b.exec(a);if(null===f)return 
c[e]=a,void(d[e]="");for(var 
g,h,i=0;null!==f;)g=f.index,h=f[0].length,c[e]=a.substring(i,g),d[e]=a.substr(g,h),i=g+h,e++,f=b.exec(a);c[e]=a.substring(i),d[e]=""}function
 A(a,b,c,d){var e,f,g=a.length,h=[];for(e=0;g>e;e++)h[e]={};var i,j=new 
D(a,h,c,d),k=B(j,0,0).score,l=0;for(e=0;g>e&&(i=h[e][l],i);e++)b[e]=f=i.index,f>-1&&(l|=1<<f);return
 k}function B(a,b,c){var 
d=a.score_grid,e=a.cache_tree,f=a.score_thresholds,g=a.order_bonus,h=d.length,i=d[c].length;i>G&&(i=G);var
 j,k,l,m=f[c],n=0,o=-1,p=h-1>c,q=e[c+1];for(j=0;i>j;j++){var 
r=1<<j;if(!(b&r||(k=d[c][j],m>k))){if(p){l=b|r;var s=l in 
q?q[l]:B(a,l,c+1);k+=s.score,j<s.index&&(k+=g)}k>=n&&(n=k,o=j)}}p&&(l=b,k=l in 
q?q[l].score:B(a,l,c+1).score,k>n&&(n=k,o=-1));var t=new C(n,o);return 
e[c][b]=t,t}function C(a,b){this.score=a,this.index=b}function 
D(a,b,c,d){this.score_grid=a,this.cache_tree=b,this.score_thresholds=c,this.order_bonus=d}function
 E(a,b){var 
c,d,e=a.slice();for(a.length=b,c=0;b>c;c++)a[c]=-1;for(c=0;c<e.length;c++)d=e[c],d>-1&&b>d&&(a[d]=c)}a.defaultOptions={minimum_match:1,thresh_include:2,thresh_relative_to_best:.5,field_good_enough:20,bonus_match_start:.5,bonus_token_order:2,bonus_position_decay:.7,score_per_token:!0,score_test_fused:!1,score_acronym:!1,token_sep:"
 
.,-:",score_round:.1,output_limit:0,sorter:i,normalize:x,filter:null,output_map:"item",join_str:",
 
",token_query_min_length:2,token_field_min_length:3,token_query_max_length:64,token_field_max_length:64,token_fused_max_length:64,token_min_rel_size:.6,token_max_rel_size:10,interactive_debounce:150,interactive_mult:1.2,interactive_burst:3,source:[],keys:[],lazy:!1,token_re:/\s+/g,identify_item:null,use_index_store:!1,store_thresh:.7,store_max_results:1500};var
 
F={keys:[],tags:[],index:[],index_map:{},nb_indexed:0,store:{},tags_re:null,acro_re:null,token_re:null,options:null,dirty:!1,query:null,results:[],start_time:0,search_time:0},G=32;b.update=function(a,b,c){for(var
 d in c)c.hasOwnProperty(d)&&b.hasOwnProperty(d)&&(a[d]=void 
0===c[d]?b[d]:c[d])},a.setOptions=function(a,d,e,f,g,h){g?(c(a,f),a.options=new 
b(e,d)):b.update(a.options,e,d),h.call(a,d)},c(a.prototype,{setOptions:function(b,c){void
 
0===c&&(c=b.reset||!1),a.setOptions(this,b,a.defaultOptions,F,c,this._optionsHook)},_optionsHook:function(a){var
 b=this.options;"output_map"in a&&"string"==typeof 
a.output_map&&("alias"===b.output_map?b.output_map=this.aliasResult:b.output_map=d(b.output_map,["root","."])),this.source=b.source;var
 c;if("keys"in a&&void 0!==(c=a.keys)){var 
h,i,j=Object.prototype.toString.call(c);if(this.tags=null,"[object 
String]"===j)this.keys=c.length?[c]:[];else if("[object 
Object]"===j){this.keys=[],this.tags=[],h=0;for(var k in 
c)c.hasOwnProperty(k)&&(this.tags[h]=k,this.keys[h]=c[k],h++)}else 
this.keys=c;for(c=this.keys,i=c.length,h=-1;++h<i;)c[h]=d(c[h],["item","."]);this.tags||(this.tags=c),this.tags_re=e(this.tags)}(null===this.acro_re||"acronym_tok"in
 a)&&(this.acro_re=f(b.token_sep)),(null===this.token_re||"token_sep"in 
a)&&(this.token_re=b.token_re=new 
RegExp("["+g(b.token_sep)+"]+","g")),(a.dirty||"source"in a||"keys"in 
a||"use_index_store"in 
a)&&(b.lazy?this.dirty=!0:(this._buildIndexFromSource(),this.dirty=!1))}}),c(a.prototype,{getMatchingField:function(b){var
 c=a.generateFields(b.item,[this.keys[b.matchIndex]]);return 
c[0][b.subIndex]},aliasResult:function(b){for(var 
c=this.options,d=a.generateFields(b.item,this.keys),e={},f=this.tags,g=c.join_str,h=-1,i=d.length;++h<i;)e[f[h]]=d[h].join(g);return
 
e._item=b.item,e._score=b.score,e._match=d[b.matchIndex][b.subIndex],e}}),a.map=function(a,b,c,d){var
 e=a.length;if(d>0&&e>d&&(e=d),"function"!=typeof b)return a.slice(0,e);for(var 
f=new Array(e),g=-1;++g<e;)f[g]=b.call(c,a[g],g,a);return 
f},a.mapField=function(a,b,c){var d=a.length;if(c>0&&d>c&&(d=c),""===b)return 
a.slice(0,d);var e,f,g=new 
Array(d);if(-1===b.indexOf("."))for(f=-1;++f<d;)e=a[f],b in 
e&&(g[f]=e[b]);else{var 
h=b.split("."),i=h.length;for(f=-1;++f<d;){e=a[f];for(var j=-1;++j<i;){var 
k=h[j];if(!(k in e))break;e=e[k]}g[f]=e}}return 
g},a.filterGTE=function(a,b,c){for(var 
d,e=-1,f=-1,g=a.length,h=[];++e<g;)d=a[e],d[b]>=c&&(h[++f]=d);return 
h},c(a.prototype,{_prepQuery:function(b){var 
c,d,e,f,g,h,i,k=this.options,l=k.score_per_token,m=k.score_test_fused,n=k.token_fused_max_length,o=k.token_field_min_length,p=k.token_field_max_length,q=this.tags,r=this.tags_re,s=q.length,t=this.token_re;if(l&&s&&r){var
 u,v=0,w=0,x=new 
Array(s+1),y=r.exec(b);for(g=null!==y;null!==y;)u=y.index,x[w]=b.substring(v,u),v=u+y[0].length,w=q.indexOf(y[1])+1,y=r.exec(b);x[w]=b.substring(v),f=[];for(var
 z=-1;++z<s;){var 
A=x[z+1];A&&A.length&&(c=k.normalize(A),d=c.substring(0,n),e=m||!l?a.alphabet(d):{},i=a.filterSize(c.split(t),o,p),h=a.pack_tokens(i),f[z]=new
 
j(c,i,h,d,e,!1,[]))}c=k.normalize(x[0]),i=a.filterSize(c.split(t),o,p),h=a.pack_tokens(i)}else
 
c=k.normalize(b),i=a.filterSize(c.split(t),o,p),h=l?a.pack_tokens(i):[],g=!1,f=new
 Array(s);return d=c.substring(0,n),e=m||!l?a.alphabet(d):{},new 
j(c,i,h,d,e,g,f)}}),j.prototype.resetItem=function(){for(var 
a=this.tokens_groups,b=-1,c=a.length;++b<c;)for(var 
d=a[b].score_item,e=-1,f=d.length;++e<f;)d[e]=0;if(this.fused_score=0,this.has_children)for(var
 g=this.children,h=-1,i=g.length;++h<i;){var 
j=g[h];j&&j.resetItem()}},j.prototype.scoreItem=function(){for(var 
a=0,b=this.tokens_groups,c=-1,d=b.length;++c<d;)for(var 
e=b[c].score_item,f=-1,g=e.length;++f<g;)a+=e[f];if(this.fused_score>a&&(a=this.fused_score),this.has_children)for(var
 h=this.children,i=-1,j=h.length;++i<j;){var 
k=h[i];k&&(a+=k.scoreItem())}return a},a.alphabet=function(b){var 
c=b.length;return 
c>G?a.posVector(b):a.bitVector(b,{},0)},a.mapAlphabet=function(b){for(var 
c=b.length,d=new Array(c),e=-1;++e<c;){var 
f=b[e];f.length>G?d[e]=a.posVector(f):d[e]=a.bitVector(f,{},0)}return 
d},a.bitVector=function(a,b,c){for(var d,e=a.length,f=-1,g=c;++f<e;)d=a[f],d in 
b?b[d]|=1<<g++:b[d]=1<<g++;return b},a.posVector=function(a){for(var 
b,c={},d=a.length,e=-1;++e<d;)b=a[e],b in c?c[b].push(e):c[b]=[e];for(b in 
c)c.hasOwnProperty(b)&&c[b].push(1/0);return 
c},a.pack_tokens=function(b){for(var c,d=-1,e=b.length,f=[];e>d;){for(var 
g=[],h={},i=0,j=0;++d<e;){var l=b[d],m=l.length;if(m>=G){c=new 
k([l],a.posVector(l),4294967295);break}if(m+i>=G){d--;break}g.push(l),a.bitVector(l,h,i),j|=(1<<l.length-1)-1<<i,i+=m}g.length>0&&f.push(new
 k(g,h,j)),c&&(f.push(c),c=null)}return f},a.prototype.score=function(b,c){var 
d=a.alphabet(b);return 
a.score_map(b,c,d,this.options)},a.score_map=function(b,c,d,e){var 
f,g,h=b.length,i=c.length,j=e.bonus_match_start,k=i>h?h:i;if(0===k)return 0;var 
l=(h+i)/(2*h*i),m=0;if(b===c)m=k;else for(;b[m]===c[m]&&++m<k;);if(m===k)return 
g=m,l*g*g+j*m;if(h>G)return g=a.llcs_large(b,c,d,m),l*g*g+j*m;var 
n,o,p=(1<<h)-1,q=p;for(f=m-1;++f<i;)o=c[f],o in d&&(n=q&d[o],q=q+n|q-n);return 
p&=~((1<<m)-1),q=~q&p,q-=q>>1&1431655765,q=(858993459&q)+(q>>2&858993459),g=16843009*(q+(q>>4)&252645135)>>24,g+=m,l*g*g+j*m},a.score_single=function(b,c,d){var
 e=b.tokens[0],f=e.length,g=c.length;return 
g<d.token_min_rel_size*f||g>d.token_max_rel_size*f?[0]:[a.score_map(e,c,b.map,d)]},a.score_pack=function(b,c,d){var
 e=b.tokens,f=e.length;if(1==f)return a.score_single(b,c,d);for(var 
g,h,i=4294967295,j=0|b.gate,k=b.map,l=-1,m=c.length;++l<m;)h=c[l],h in 
k&&(g=i&k[h],i=(i&j)+(g&j)|i-g);i=~i;for(var 
n=d.bonus_match_start,o=d.token_min_rel_size,p=d.token_max_rel_size,q=new 
Array(f),r=0,s=-1;++s<f;){var 
t,u,v=e[s],w=v.length;if(o*w>m||m>p*w)q[s]=0,r+=w;else{if(v===c)u=t=w;else{var 
x=m>w?w:m;for(u=0;v[u]===c[u]&&++u<x;);t=u;for(var 
y=(i>>>r&(1<<w)-1)>>>u;y;)y&=y-1,t++}r+=w;var 
z=(w+m)/(2*w*m);q[s]=z*t*t+n*u}}return q},a.llcs_large=function(a,b,c,d){var 
e,f,g,h,i,j;void 0===d&&(d=0),g=d?[new l(0,d),new l(1/0,1/0)]:[new 
l(1/0,1/0)];var k,m,n,o,p,q,r=d,s=g.length,t=b.length;for(q=d;t>q;q++){var 
u=b[q];if(u in c){k=c[u];var v=new 
Array(Math.min(2*s,r+2));for(h=-1,m=0,f=k[0],j=-1,o=-1;++o<s;){for(i=j,n=g[o],e=n.start,j=n.end,p=j-e;i>f;)f=k[++m];f>=e?v[++h]=n:(f===i?v[h].end++:1===p?(n.start=f,n.end=f+1,v[++h]=n):v[++h]=new
 l(f,f+1),p>1&&(n.start++,v[++h]=n))}e>f&&(v[++h]=n,r++),g=v,s=++h}}return 
r},c(a.prototype,{search:function(b){var c=Date.now();this.start_time=c;var 
d=this.options;this.dirty&&d.lazy&&(this._buildIndexFromSource(),this.dirty=!1);var
 
e=this.query=this._prepQuery(b),f=this.index,g=[];d.use_index_store&&(f=this._storeSearch(e,f)),d.filter&&(f=d.filter.call(this,f));var
 h=this._searchIndex(e,f,g);g=a.filterGTE(g,"score",h),"function"==typeof 
d.sorter&&(g=g.sort(d.sorter)),(d.output_map||d.output_limit>0)&&(g="function"==typeof
 
d.output_map?a.map(g,d.output_map,this,d.output_limit):a.mapField(g,d.output_map,d.output_limit));var
 i=Date.now();return 
this.search_time=i-c,this.results=g,g},_searchIndex:function(b,c,d){for(var 
e=this.options,f=e.bonus_position_decay,g=e.field_good_enough,i=e.thresh_relative_to_best,j=e.score_per_token,k=e.score_round,l=e.thresh_include,m=0,n=b.children,o=-1,p=c.length;++o<p;){var
 q=c[o],r=q.fields;b.resetItem();for(var 
s=0,t=-1,u=-1,v=1,w=-1,x=r.length;++w<x;){for(var 
y=0,z=-1,A=r[w],B=n[w],C=!!B,D=-1,E=A.length;++D<E;){var 
F,G=A[D];j?(F=this._scoreField(G,b),C&&(F+=this._scoreField(G,B))):F=a.score_map(b.fused_str,G.join("
 
"),b.fused_map,e),F>y&&(y=F,z=D)}if(y*=1+v,v*=f,y>s&&(s=y,t=w,u=z,y>g))break}if(j){var
 H=b.scoreItem();s=.5*s+.5*H}if(s>m){m=s;var 
I=s*i;I>l&&(l=I)}s>l&&(s=Math.round(s/k)*k,d.push(new 
h(q.item,r,s,t,u,r[0][0].join(" "))))}return l},_scoreField:function(b,c){var 
d=c.tokens_groups,e=d.length,f=b.length;if(!e||!f)return 0;for(var 
g,h,i,j,k,l=0,m=-1,n=this.options,o=n.bonus_token_order,p=n.minimum_match,q=-1;++q<e;){var
 r=d[q],s=r.tokens.length,t=r.score_field;for(k=-1;++k<s;)t[k]=0;var 
u=r.field_pos;for(k=-1;++k<s;)u[k]=0;for(var 
v=-1;++v<f;)for(i=b[v],j=a.score_pack(r,i,n),k=-1;++k<s;)g=j[k],h=t[k],(g>h||o>h-g&&k>0&&u[k]<=u[k-1])&&(t[k]=g,u[k]=v);var
 w=r.score_item;for(k=-1;++k<s;){if(g=t[k],l+=g,g>p){var 
x=u[k],y=x-m,z=o*(1/(1+Math.abs(y)));y>0&&(z*=2),l+=z,g+=z,m=x}g>w[k]&&(w[k]=g)}}if(n.score_test_fused){for(var
 A=n.score_acronym?f-1:f,B=b[0],C=0;++C<A;)B+=" "+b[C];var 
D=a.score_map(c.fused_str,B,c.fused_map,n);D+=o,l=D>l?D:l,D>c.fused_score&&(c.fused_score=D)}return
 l}}),c(a.prototype,{_prepItem:function(b,c){for(var 
d=a.generateFields(b,c),e=d.length,f=-1;++f<e;)for(var 
g=d[f],h=-1,i=g.length;++h<i;){var 
j=this.options.normalize(g[h]),k=j.split(this.token_re);j.length>2*this.options.token_field_min_length&&(k=a.filterSize(k,this.options.token_field_min_length,this.options.token_field_max_length)),this.options.score_acronym&&k.push(j.replace(this.acro_re,"$1")),g[h]=k}return
 new m(b,d)},add:function(a,b){void 0===b&&(b=!0);var c,d="function"==typeof 
this.options.identify_item?this.options.identify_item(a):null;null===d?(c=this.nb_indexed,this.nb_indexed++):d
 in 
this.index_map?c=this.index_map[d]:(this.index_map[d]=this.nb_indexed,c=this.nb_indexed,this.nb_indexed++);var
 
e=this._prepItem(a,this.keys);this.index[c]=e,b&&(this.source[c]=a),this.options.use_index_store&&this._storeAdd(e,c)},_buildIndexFromSource:function(){var
 a=this.source.length;this.index=new 
Array(a),this.index_map={},this.nb_indexed=0;for(var b=-1;++b<a;){var 
c=this.source[b];this.add(c,!1)}}}),a.generateFields=function(a,b){if(!b||!b.length)return[[a.toString()]];for(var
 c=b.length,d=new Array(c),e=-1;++e<c;)d[e]=n(a,b[e].split("."),[],0);return 
d},c(a.prototype,{_storeAdd:function(a,b){var c=p(a);if(0!=c.length)for(var 
d=0;d<c.length;d++){var e=c[d];e in 
this.store?this.store[e].push(b):this.store[e]=[b]}},_storeSearch:function(b,c){var
 d=q(b);if(0==d.length)return[];var 
e=v(d,this.store);if(0==e.length)return[];var 
f=e[0].count*this.options.store_thresh;return 
e=a.filterGTE(e,"count",f),a.map(e,function(a){return 
c[a.id]},this,this.options.store_max_results)}});var H=y();return 
a.filterSize=function(a,b,c){for(var 
d,e,f=-1,g=-1,h=a.length,i=[];++f<h;)d=a[f],e=d.length,e>=b&&(i[++g]=c>e?d:d.substr(0,c));return
 
i},c(a.defaultOptions,{highlight_prefix:!1,highlight_bridge_gap:2,highlight_before:'<strong
 
class="highlight">',highlight_after:"</strong>"}),a.prototype.highlight=function(b,c){var
 d,e,f=this.query.normalized;return 
c&&c.length&&(d=this.tags.indexOf(c))>-1&&(e=this.query.children[d])&&(f+=(f.length?"
 
":"")+e.normalized),a.highlight(f,b,this.options)},a.highlight=function(b,c,d){if(void
 0===d&&(d=a.defaultOptions),!c)return"";var 
e=d.highlight_before,f=d.highlight_after,g=d.score_per_token,h=d.score_test_fused,i=d.score_acronym,j=d.token_re,k=d.normalize(b),l=d.normalize(c),m=k.split(j),n=l.split(j),o=[],p=[];z(c,j,o,p);var
 
q=[],r=[],s=0,t=0;if(g&&(t=a.matchTokens(n,m,r,d,!1)),(h||!g||i)&&(s=a.score_map(k,l,a.alphabet(k),d)+d.bonus_token_order),0===t&&0===s)return
 c;(!g||s>t)&&(m=[k],n=[l],o=[c],r=[0]);for(var u=o.length,v=-1;++v<u;){var 
w=r[v];if(-1!==w){var 
x=m[w],y=n[v],A=o[v],B=0,C=[],D=[];a.align(x,y,C,D);for(var 
E=C.length,F=-1;++F<E;){var 
G=C[F],H=D[F];G>B&&q.push(A.substring(B,G)),q.push(e+A.substring(G,H)+f),B=H}q.push(A.substring(B)+p[v])}else
 q.push(o[v]+p[v])}return q.join("")},a.align=function(b,c,d,e,f){void 
0===f&&(f=a.defaultOptions);var 
g,h,i=100,j=-10,k=-1,l=0,m=1,n=2,o=3,p=f.score_acronym,q=f.token_sep,r=Math.min(b.length+1,f.token_query_max_length),s=Math.min(c.length+1,f.token_field_max_length),t=s>r?r:s,u=0;if(b===c)u=r,r=0;else
 
if(f.highlight_prefix){for(g=0;t>g&&b[g]===c[g];g++)u++;u&&(b=b.substring(u),c=c.substring(u),r-=u,s-=u)}var
 v=0,w=0,x=0,y=new Array(r*s),z=s-1;if(r>1&&s>1){var A,B,C,D,E=new 
Array(s),F=new 
Array(s),G=0;for(h=0;s>h;h++)F[h]=0,E[h]=0,y[h]=l;for(g=1;r>g;g++)for(G=0,A=E[0],z++,y[z]=l,h=1;s>h;h++)switch(D=F[h]=Math.max(F[h]+k,E[h]+j),G=Math.max(G+k,E[h-1]+j),C=p?b[g-1]!==c[h-1]?-(1/0):A+i+(2>g||q.indexOf(b[g-2])>-1?i:0)+(2>h||q.indexOf(c[h-2])>-1?i:0):b[g-1]===c[h-1]?A+i:-(1/0),A=E[h],B=E[h]=Math.max(C,D,G,0),z++,B){case
 G:y[z]=n;break;case C:y[z]=o,B>v&&(v=B,w=g,x=h);break;case 
D:y[z]=m;break;default:y[z]=l}}var 
H=f.highlight_bridge_gap,I=0;if(v>0){g=w,h=x,z=g*s+h,I=x,e.push(x+u);for(var 
J=!0;J;)switch(y[z]){case m:g--,z-=s;break;case n:h--,z--;break;case 
o:I-h>H&&(d.push(I+u),e.push(h+u)),h--,g--,I=h,z-=s+1;break;case 
l:default:J=!1}d.push(I+u)}return 
u&&(I>0&&H>=I?d[d.length-1]=0:(d.push(0),e.push(u))),d.reverse(),e.reverse(),v+u},a.matchTokens=function(b,c,d,e,f){void
 0===e&&(e=a.defaultOptions),void 0===f&&(f=!1);var 
g,h,i,j,k,l,m,n=e.minimum_match,o=e.thresh_relative_to_best,p=[],q=b.length,r=c.length,s=a.mapAlphabet(b),t=n,u=-1,v=-1,w=0,x=[];for(g=0;q>g;g++)if(i=[],d[g]=-1,t=n,j=b[g],j.length){for(l=s[g],h=0;r>h;h++)k=c[h],k.length?(m=a.score_map(j,k,l,e),i[h]=m,m>n&&w++,m>t&&(t=m,u=g,v=h)):i[h]=0;x[g]=t,p[g]=i}else{for(h=0;r>h;h++)i[h]=0;p[g]=i}if(0===w)return
 0;if(1===w)return 
d[u]=v,f&&E(d,r),t;for(g=0;g<b.length;g++)x[g]=Math.max(o*x[g],n);var 
y=A(p,d,x,e.bonus_token_order);return 
f&&E(d,r),y},c(a.prototype,{getInteractive:function(){var 
a=this,b=this.options,c=b.interactive_debounce,d=b.interactive_mult,e=b.interactive_burst;if(0===c)return
 function(b,c,d,e){return c(a.search(b))};var 
f,g,h=window.performance&&window.performance.now?window.performance:Date,i=0,j=!1;return
 function(b,k,l,m){var 
n=function(){f=null,j&&(g=a.search(b),m(g)),i=0,j=!1};if(clearTimeout(f),f=setTimeout(n,c),++i<e){j=!1;var
 o=h.now();g=a.search(b);var p=k(g),q=h.now();return c=.5*c+.5*d*(q-o),p}return 
j=!0,l(g)}},__ttAdapter:function(){var 
a=this.getInteractive(),b=function(a){};return 
function(c,d,e){a(c,d,b,e)}},$uiSource:function(){var 
a=this.getInteractive(),b=function(a){};return 
function(c,d){a(c.term,d,b,d)}}}),"function"==typeof 
require&&"undefined"!=typeof 
module&&module.exports?module.exports=a:"function"==typeof 
define&&define.amd?define(function(){return a}):window.FuzzySearch=a,a}();
\ No newline at end of file
diff --git a/js/ext/typeahead.jquery.min.js b/js/ext/typeahead.jquery.min.js
new file mode 100644
index 0000000000..39023c83ec
--- /dev/null
+++ b/js/ext/typeahead.jquery.min.js
@@ -0,0 +1,8 @@
+/*!
+ * typeahead.js 1.3.3
+ * https://github.com/corejavascript/typeahead.js
+ * Copyright 2013-2024 Twitter, Inc. and other contributors; Licensed MIT
+ */
+
+
+!function(a,b){"function"==typeof 
define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof 
module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){var
 b=function(){"use 
strict";return{isMsie:function(){return!!/(msie|trident)/i.test(navigator.userAgent)&&navigator.userAgent.match(/(msie
 
|rv:)(\d+(.\d+)?)/i)[2]},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return
 
a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof
 a},isNumber:function(a){return"number"==typeof 
a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return
 void 
0===a},isElement:function(a){return!(!a||1!==a.nodeType)},isJQuery:function(b){return
 b instanceof a},toStr:function(a){return 
b.isUndefined(a)||null===a?"":a+""},bind:a.proxy,each:function(b,c){function 
d(a,b){return 
c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return 
b?(a.each(b,function(a,e){if(!(d=c.call(null,e,a,b)))return!1}),!!d):d},some:function(b,c){var
 d=!1;return 
b?(a.each(b,function(a,e){if(d=c.call(null,e,a,b))return!1}),!!d):d},mixin:a.extend,identity:function(a){return
 a},clone:function(b){return a.extend(!0,{},b)},getIdGenerator:function(){var 
a=0;return function(){return a++}},templatify:function(b){function c(){return 
String(b)}return 
a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var
 d,e;return function(){var f,g,h=this,i=arguments;return 
f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var
 c,d,e,f,g,h;return g=0,h=function(){g=new 
Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return 
c=this,d=arguments,j<=0?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},stringify:function(a){return
 b.isString(a)?a:JSON.stringify(a)},guid:function(){function a(a){var 
b=(Math.random().toString(16)+"000000000").substr(2,8);return 
a?"-"+b.substr(0,4)+"-"+b.substr(4,4):b}return"tt-"+a()+a(!0)+a(!0)+a()},noop:function(){}}}(),c=function(){"use
 strict";function a(a){var g,h;return 
h=b.mixin({},f,a),g={css:e(),classes:h,html:c(h),selectors:d(h)},{css:g.css,html:g.html,classes:g.classes,selectors:g.selectors,mixin:function(a){b.mixin(a,g)}}}function
 c(a){return{wrapper:'<span class="'+a.wrapper+'"></span>',menu:'<div 
role="listbox" class="'+a.menu+'"></div>'}}function d(a){var c={};return 
b.each(a,function(a,b){c[b]="."+a}),c}function e(){var 
a={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"}};return 
b.isMsie()&&b.mixin(a.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),a}var
 
f={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
 a}(),d=function(){"use strict";function c(b){b&&b.el||a.error("EventBus 
initialized without el"),this.$el=a(b.el)}var d,e;return 
d="typeahead:",e={render:"rendered",cursorchange:"cursorchanged",select:"selected",autocomplete:"autocompleted"},b.mixin(c.prototype,{_trigger:function(b,c){var
 e=a.Event(d+b);return 
this.$el.trigger.call(this.$el,e,c||[]),e},before:function(a){var b,c;return 
b=[].slice.call(arguments,1),c=this._trigger("before"+a,b),c.isDefaultPrevented()},trigger:function(a){var
 
b;this._trigger(a,[].slice.call(arguments,1)),(b=e[a])&&this._trigger(b,[].slice.call(arguments,1))}}),c}(),e=function(){"use
 strict";function a(a,b,c,d){var e;if(!c)return 
this;for(b=b.split(h),c=d?g(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return
 this}function b(b,c,d){return a.call(this,"async",b,c,d)}function 
c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var 
b;if(!this._callbacks)return this;for(a=a.split(h);b=a.shift();)delete 
this._callbacks[b];return this}function e(a){var 
b,c,d,e,g;if(!this._callbacks)return 
this;for(a=a.split(h),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&i(g);return
 this}function f(a,b,c){function d(){for(var 
d,e=0,f=a.length;!d&&e<f;e+=1)d=!1===a[e].apply(b,c);return!d}return d}function 
g(a,b){return 
a.bind?a.bind(b):function(){a.apply(b,[].slice.call(arguments,0))}}var 
h=/\s+/,i=function(){return 
window.setImmediate?function(a){setImmediate(function(){a()})}:function(a){setTimeout(function(){a()},0)}}();return{onSync:c,onAsync:b,off:d,trigger:e}}(),f=function(a){"use
 strict";function c(a){return f[a.toUpperCase()]||a}function d(a,d,e,f){for(var 
g,h=[],i=0,j=a.length;i<j;i++){var 
k=b.escapeRegExChars(a[i]);f&&(k=k.replace(/\S/g,c)),h.push(k)}return 
g=e?"\\b("+h.join("|")+")\\b":"("+h.join("|")+")",d?new RegExp(g):new 
RegExp(g,"i")}var 
e={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1,diacriticInsensitive:!1},f={A:"[AaªÀ-Åà-åĀ-ąǍǎȀ-ȃȦȧᴬᵃḀḁẚẠ-ảₐ℀℁℻⒜Ⓐⓐ㍱-㍴㎀-㎄㎈㎉㎩-㎯㏂㏊㏟㏿Aa]",B:"[BbᴮᵇḂ-ḇℬ⒝Ⓑⓑ㍴㎅-㎇㏃㏈㏔㏝Bb]",C:"[CcÇçĆ-čᶜ℀ℂ℃℅℆ℭⅭⅽ⒞Ⓒⓒ㍶㎈㎉㎝㎠㎤㏄-㏇Cc]",D:"[DdĎďDŽ-džDZ-dzᴰᵈḊ-ḓⅅⅆⅮⅾ⒟Ⓓⓓ㋏㍲㍷-㍹㎗㎭-㎯㏅㏈Dd]",E:"[EeÈ-Ëè-ëĒ-ěȄ-ȇȨȩᴱᵉḘ-ḛẸ-ẽₑ℡ℯℰⅇ⒠Ⓔⓔ㉐㋍㋎Ee]",F:"[FfᶠḞḟ℉ℱ℻⒡Ⓕⓕ㎊-㎌㎙ff-fflFf]",G:"[GgĜ-ģǦǧǴǵᴳᵍḠḡℊ⒢Ⓖⓖ㋌㋍㎇㎍-㎏㎓㎬㏆㏉㏒㏿Gg]",H:"[HhĤĥȞȟʰᴴḢ-ḫẖℋ-ℎ⒣Ⓗⓗ㋌㍱㎐-㎔㏊㏋㏗Hh]",I:"[IiÌ-Ïì-ïĨ-İIJijǏǐȈ-ȋᴵᵢḬḭỈ-ịⁱℐℑℹⅈⅠ-ⅣⅥ-ⅨⅪⅫⅰ-ⅳⅵ-ⅸⅺⅻ⒤Ⓘⓘ㍺㏌㏕fiffiIi]",J:"[JjIJ-ĵLJ-njǰʲᴶⅉ⒥ⒿⓙⱼJj]",K:"[KkĶķǨǩᴷᵏḰ-ḵK⒦Ⓚⓚ㎄㎅㎉㎏㎑㎘㎞㎢㎦㎪㎸㎾㏀㏆㏍-㏏Kk]",L:"[LlĹ-ŀLJ-ljˡᴸḶḷḺ-ḽℒℓ℡Ⅼⅼ⒧Ⓛⓛ㋏㎈㎉㏐-㏓㏕㏖㏿flfflLl]",M:"[MmᴹᵐḾ-ṃ℠™ℳⅯⅿ⒨Ⓜⓜ㍷-㍹㎃㎆㎎㎒㎖㎙-㎨㎫㎳㎷㎹㎽㎿㏁㏂㏎㏐㏔-㏖㏘㏙㏞㏟Mm]",N:"[NnÑñŃ-ʼnNJ-njǸǹᴺṄ-ṋⁿℕ№⒩Ⓝⓝ㎁㎋㎚㎱㎵㎻㏌㏑Nn]",O:"[OoºÒ-Öò-öŌ-őƠơǑǒǪǫȌ-ȏȮȯᴼᵒỌ-ỏₒ℅№ℴ⒪Ⓞⓞ㍵㏇㏒㏖Oo]",P:"[PpᴾᵖṔ-ṗℙ⒫Ⓟⓟ㉐㍱㍶㎀㎊㎩-㎬㎰㎴㎺㏋㏗-㏚Pp]",Q:"[Qqℚ⒬Ⓠⓠ㏃Qq]",R:"[RrŔ-řȐ-ȓʳᴿᵣṘ-ṛṞṟ₨ℛ-ℝ⒭Ⓡⓡ㋍㍴㎭-㎯㏚㏛Rr]",S:"[SsŚ-šſȘșˢṠ-ṣ₨℁℠⒮Ⓢⓢ㎧㎨㎮-㎳㏛㏜stSs]",T:"[TtŢ-ťȚțᵀᵗṪ-ṱẗ℡™⒯Ⓣⓣ㉐㋏㎔㏏ſtstTt]",U:"[UuÙ-Üù-üŨ-ųƯưǓǔȔ-ȗᵁᵘᵤṲ-ṷỤ-ủ℆⒰Ⓤⓤ㍳㍺Uu]",V:"[VvᵛᵥṼ-ṿⅣ-Ⅷⅳ-ⅷ⒱Ⓥⓥⱽ㋎㍵㎴-㎹㏜㏞Vv]",W:"[WwŴŵʷᵂẀ-ẉẘ⒲Ⓦⓦ㎺-㎿㏝Ww]",X:"[XxˣẊ-ẍₓ℻Ⅸ-Ⅻⅸ-ⅻ⒳Ⓧⓧ㏓Xx]",Y:"[YyÝýÿŶ-ŸȲȳʸẎẏẙỲ-ỹ⒴Ⓨⓨ㏉Yy]",Z:"[ZzŹ-žDZ-dzᶻẐ-ẕℤℨ⒵Ⓩⓩ㎐-㎔Zz]"};return
 function(c){function f(b){var 
d,e,f;return(d=h.exec(b.data))&&(f=a.createElement(c.tagName),c.className&&(f.className=c.className),e=b.splitText(d.index),e.splitText(d[0].length),f.appendChild(e.cloneNode(!0)),b.parentNode.replaceChild(f,e)),!!d}function
 g(a,b){for(var 
c,d=0;d<a.childNodes.length;d++)c=a.childNodes[d],3===c.nodeType?d+=b(c)?1:0:g(c,b)}var
 
h;c=b.mixin({},e,c),c.node&&c.pattern&&(c.pattern=b.isArray(c.pattern)?c.pattern:[c.pattern],h=d(c.pattern,c.caseSensitive,c.wordsOnly,c.diacriticInsensitive),g(c.node,f))}}(window.document),g=function(){"use
 strict";function c(c,e){var f;c=c||{},c.input||a.error("input is 
missing"),e.mixin(this),this.$hint=a(c.hint),this.$input=a(c.input),this.$menu=a(c.menu),f=this.$input.attr("id")||b.guid(),this.$menu.attr("id",f+"_listbox"),this.$hint.attr({"aria-hidden":!0}),this.$input.attr({"aria-owns":f+"_listbox","aria-controls":f+"_listbox",role:"combobox","aria-autocomplete":"list","aria-expanded":!1}),this.query=this.$input.val(),this.queryWhenFocused=this.hasFocus()?this.query:null,this.$overflowHelper=d(this.$input),this._checkLanguageDirection(),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=b.noop),this.onSync("cursorchange",this._updateDescendent)}function
 d(b){return a('<pre 
aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function
 f(a,b){return c.normalizeQuery(a)===c.normalizeQuery(b)}function g(a){return 
a.altKey||a.ctrlKey||a.metaKey||a.shiftKey}var h;return 
h={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},c.normalizeQuery=function(a){return
 b.toStr(a).replace(/^\s*/g,"").replace(/\s{2,}/g," 
")},b.mixin(c.prototype,e,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.queryWhenFocused=this.query,this.trigger("focused")},_onKeydown:function(a){var
 
b=h[a.which||a.keyCode];this._managePreventDefault(b,a),b&&this._shouldTrigger(b,a)&&this.trigger(b+"Keyed",a)},_onInput:function(){this._setQuery(this.getInputValue()),this.clearHintIfInvalid(),this._checkLanguageDirection()},_managePreventDefault:function(a,b){var
 
c;switch(a){case"up":case"down":c=!g(b);break;default:c=!1}c&&b.preventDefault()},_shouldTrigger:function(a,b){var
 c;switch(a){case"tab":c=!g(b);break;default:c=!0}return 
c},_checkLanguageDirection:function(){var 
a=(this.$input.css("direction")||"ltr").toLowerCase();this.dir!==a&&(this.dir=a,this.$hint.attr("dir",a),this.trigger("langDirChanged",a))},_setQuery:function(a,b){var
 
c,d;c=f(a,this.query),d=!!c&&this.query.length!==a.length,this.query=a,b||c?!b&&d&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},_updateDescendent:function(a,b){this.$input.attr("aria-activedescendant",b)},bind:function(){var
 a,c,d,e,f=this;return 
a=b.bind(this._onBlur,this),c=b.bind(this._onFocus,this),d=b.bind(this._onKeydown,this),e=b.bind(this._onInput,this),this.$input.on("blur.tt",a).on("focus.tt",c).on("keydown.tt",d),!b.isMsie()||b.isMsie()>9?this.$input.on("input.tt",e):this.$input.on("keydown.tt
 keypress.tt cut.tt 
paste.tt",function(a){h[a.which||a.keyCode]||b.defer(b.bind(f._onInput,f,a))}),this},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getLangDir:function(){return
 this.dir},getQuery:function(){return 
this.query||""},setQuery:function(a,b){this.setInputValue(a),this._setQuery(a,b)},hasQueryChangedSinceLastFocus:function(){return
 this.query!==this.queryWhenFocused},getInputValue:function(){return 
this.$input.val()},setInputValue:function(a){this.$input.val(a),this.clearHintIfInvalid(),this._checkLanguageDirection()},resetInputValue:function(){this.setInputValue(this.query)},getHint:function(){return
 
this.$hint.val()},setHint:function(a){this.$hint.val(a)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var
 
a,b,c,d;a=this.getInputValue(),b=this.getHint(),c=a!==b&&0===b.indexOf(a),!(d=""!==a&&c&&!this.hasOverflow())&&this.clearHint()},hasFocus:function(){return
 this.$input.is(":focus")},hasOverflow:function(){var 
a=this.$input.width()-2;return 
this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=a},isCursorAtEnd:function(){var
 a,c,d;return 
a=this.$input.val().length,c=this.$input[0].selectionStart,b.isNumber(c)?c===a:!document.selection||(d=document.selection.createRange(),d.moveStart("character",-a),a===d.text.length)},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$overflowHelper.remove(),this.$hint=this.$input=this.$overflowHelper=a("<div>")},setAriaExpanded:function(a){this.$input.attr("aria-expanded",a)}}),c}(),h=function(){"use
 strict";function 
c(c,e){c=c||{},c.templates=c.templates||{},c.templates.notFound=c.templates.notFound||c.templates.empty,c.source||a.error("missing
 source"),c.node||a.error("missing node"),c.name&&!h(c.name)&&a.error("invalid 
dataset name: 
"+c.name),e.mixin(this),this.highlight=!!c.highlight,this.name=b.toStr(c.name||j()),this.limit=c.limit||5,this.displayFn=d(c.display||c.displayKey),this.templates=g(c.templates,this.displayFn),this.source=c.source.__ttAdapter?c.source.__ttAdapter():c.source,this.async=b.isUndefined(c.async)?this.source.length>2:!!c.async,this._resetLastSuggestion(),this.$el=a(c.node).attr("role","presentation").addClass(this.classes.dataset).addClass(this.classes.dataset+"-"+this.name)}function
 d(a){function c(b){return b[a]}return 
a=a||b.stringify,b.isFunction(a)?a:c}function g(c,d){function e(d){var 
e=c.suggestion;return a(e(d)).attr("id",b.guid())}function f(c){return a('<div 
role="option">').attr("id",b.guid()).text(d(c))}return{notFound:c.notFound&&b.templatify(c.notFound),pending:c.pending&&b.templatify(c.pending),header:c.header&&b.templatify(c.header),footer:c.footer&&b.templatify(c.footer),suggestion:c.suggestion?e:f}}function
 h(a){return/^[_a-zA-Z0-9-]+$/.test(a)}var i,j;return 
i={dataset:"tt-selectable-dataset",val:"tt-selectable-display",obj:"tt-selectable-object"},j=b.getIdGenerator(),c.extractData=function(b){var
 c=a(b);return 
c.data(i.obj)?{dataset:c.data(i.dataset)||"",val:c.data(i.val)||"",obj:c.data(i.obj)||null}:null},b.mixin(c.prototype,e,{_overwrite:function(a,b){b=b||[],b.length?this._renderSuggestions(a,b):this.async&&this.templates.pending?this._renderPending(a):!this.async&&this.templates.notFound?this._renderNotFound(a):this._empty(),this.trigger("rendered",b,!1,this.name)},_append:function(a,b){b=b||[],b.length&&this.$lastSuggestion.length?this._appendSuggestions(a,b):b.length?this._renderSuggestions(a,b):!this.$lastSuggestion.length&&this.templates.notFound&&this._renderNotFound(a),this.trigger("rendered",b,!0,this.name)},_renderSuggestions:function(a,b){var
 
c;c=this._getSuggestionsFragment(a,b),this.$lastSuggestion=c.children().last(),this.$el.html(c).prepend(this._getHeader(a,b)).append(this._getFooter(a,b))},_appendSuggestions:function(a,b){var
 
c,d;c=this._getSuggestionsFragment(a,b),d=c.children().last(),this.$lastSuggestion.after(c),this.$lastSuggestion=d},_renderPending:function(a){var
 
b=this.templates.pending;this._resetLastSuggestion(),b&&this.$el.html(b({query:a,dataset:this.name}))},_renderNotFound:function(a){var
 
b=this.templates.notFound;this._resetLastSuggestion(),b&&this.$el.html(b({query:a,dataset:this.name}))},_empty:function(){this.$el.empty(),this._resetLastSuggestion()},_getSuggestionsFragment:function(c,d){var
 e,g=this;return e=document.createDocumentFragment(),b.each(d,function(b){var 
d,f;f=g._injectQuery(c,b),d=a(g.templates.suggestion(f)).data(i.dataset,g.name).data(i.obj,b).data(i.val,g.displayFn(b)).addClass(g.classes.suggestion+"
 
"+g.classes.selectable),e.appendChild(d[0])}),this.highlight&&f({className:this.classes.highlight,node:e,pattern:c}),a(e)},_getFooter:function(a,b){return
 
this.templates.footer?this.templates.footer({query:a,suggestions:b,dataset:this.name}):null},_getHeader:function(a,b){return
 
this.templates.header?this.templates.header({query:a,suggestions:b,dataset:this.name}):null},_resetLastSuggestion:function(){this.$lastSuggestion=a()},_injectQuery:function(a,c){return
 b.isObject(c)?b.mixin({_query:a},c):c},update:function(b){function 
c(a){g||(g=!0,a=(a||[]).slice(0,e.limit),h=a.length,e._overwrite(b,a),h<e.limit&&e.async&&e.trigger("asyncRequested",b,e.name))}function
 d(c){if(c=c||[],!f&&h<e.limit){e.cancel=a.noop;var 
d=Math.abs(h-e.limit);h+=d,e._append(b,c.slice(0,d)),e.async&&e.trigger("asyncReceived",b,e.name)}}var
 
e=this,f=!1,g=!1,h=0;this.cancel(),this.cancel=function(){f=!0,e.cancel=a.noop,e.async&&e.trigger("asyncCanceled",b,e.name)},this.source(b,c,d),!g&&c([])},cancel:a.noop,clear:function(){this._empty(),this.cancel(),this.trigger("cleared")},isEmpty:function(){return
 
this.$el.is(":empty")},destroy:function(){this.$el=a("<div>")}}),c}(),i=function(){"use
 strict";function c(c,d){function e(b){var 
c=f.$node.find(b.node).first();return 
b.node=c.length?c:a("<div>").appendTo(f.$node),new h(b,d)}var 
f=this;c=c||{},c.node||a.error("node is 
required"),d.mixin(this),this.$node=a(c.node),this.query=null,this.datasets=b.map(c.datasets,e)}return
 
b.mixin(c.prototype,e,{_onSelectableClick:function(b){this.trigger("selectableClicked",a(b.currentTarget))},_onRendered:function(a,b,c,d){this.$node.toggleClass(this.classes.empty,this._allDatasetsEmpty()),this.trigger("datasetRendered",b,c,d)},_onCleared:function(){this.$node.toggleClass(this.classes.empty,this._allDatasetsEmpty()),this.trigger("datasetCleared")},_propagate:function(){this.trigger.apply(this,arguments)},_allDatasetsEmpty:function(){return
 b.every(this.datasets,b.bind(function(a){var b=a.isEmpty();return 
this.$node.attr("aria-expanded",!b),b},this))},_getSelectables:function(){return
 this.$node.find(this.selectors.selectable)},_removeCursor:function(){var 
a=this.getActiveSelectable();a&&a.removeClass(this.classes.cursor)},_ensureVisible:function(a){var
 
b,c,d,e;b=a.position().top,c=b+a.outerHeight(!0),d=this.$node.scrollTop(),e=this.$node.height()+parseInt(this.$node.css("paddingTop"),10)+parseInt(this.$node.css("paddingBottom"),10),b<0?this.$node.scrollTop(d+b):e<c&&this.$node.scrollTop(d+(c-e))},bind:function(){var
 c,d=this;return 
c=b.bind(this._onSelectableClick,this),this.$node.on("click.tt",this.selectors.selectable,c),this.$node.on("mouseover",this.selectors.selectable,function(){d.setCursor(a(this))}),this.$node.on("mouseleave",function(){d._removeCursor()}),b.each(this.datasets,function(a){a.onSync("asyncRequested",d._propagate,d).onSync("asyncCanceled",d._propagate,d).onSync("asyncReceived",d._propagate,d).onSync("rendered",d._onRendered,d).onSync("cleared",d._onCleared,d)}),this},isOpen:function(){return
 
this.$node.hasClass(this.classes.open)},open:function(){this.$node.scrollTop(0),this.$node.addClass(this.classes.open)},close:function(){this.$node.attr("aria-expanded",!1),this.$node.removeClass(this.classes.open),this._removeCursor()},setLanguageDirection:function(a){this.$node.attr("dir",a)},selectableRelativeToCursor:function(a){var
 b,c,d,e;return 
c=this.getActiveSelectable(),b=this._getSelectables(),d=c?b.index(c):-1,e=d+a,e=(e+1)%(b.length+1)-1,e=e<-1?b.length-1:e,-1===e?null:b.eq(e)},setCursor:function(a){this._removeCursor(),(a=a&&a.first())&&(a.addClass(this.classes.cursor),this._ensureVisible(a))},getSelectableData:function(a){return
 a&&a.length?h.extractData(a):null},getActiveSelectable:function(){var 
a=this._getSelectables().filter(this.selectors.cursor).first();return 
a.length?a:null},getTopSelectable:function(){var 
a=this._getSelectables().first();return 
a.length?a:null},update:function(a){function c(b){b.update(a)}var 
d=a!==this.query;return 
d&&(this.query=a,b.each(this.datasets,c)),d},empty:function(){function 
a(a){a.clear()}b.each(this.datasets,a),this.query=null,this.$node.addClass(this.classes.empty)},destroy:function(){function
 
c(a){a.destroy()}this.$node.off(".tt"),this.$node=a("<div>"),b.each(this.datasets,c)}}),c}(),j=function(){"use
 strict";function 
c(c){this.$el=a("<span></span>",{role:"status","aria-live":"polite"}).css({position:"absolute",padding:"0",border:"0",height:"1px",width:"1px","margin-bottom":"-1px","margin-right":"-1px",overflow:"hidden",clip:"rect(0
 0 0 
0)","white-space":"nowrap"}),c.$input.after(this.$el),b.each(c.menu.datasets,b.bind(function(a){a.onSync&&(a.onSync("rendered",b.bind(this.update,this)),a.onSync("cleared",b.bind(this.cleared,this)))},this))}return
 b.mixin(c.prototype,{update:function(a,b){var 
c,d=b.length;c=1===d?{result:"result",is:"is"}:{result:"results",is:"are"},this.$el.text(d+"
 "+c.result+" "+c.is+" available, use up and down arrow keys to 
navigate.")},cleared:function(){this.$el.text("")}}),c}(),k=function(){"use 
strict";function a(){i.apply(this,[].slice.call(arguments,0))}var 
c=i.prototype;return 
b.mixin(a.prototype,i.prototype,{open:function(){return!this._allDatasetsEmpty()&&this._show(),c.open.apply(this,[].slice.call(arguments,0))},close:function(){return
 
this._hide(),c.close.apply(this,[].slice.call(arguments,0))},_onRendered:function(){return
 
this._allDatasetsEmpty()?this._hide():this.isOpen()&&this._show(),c._onRendered.apply(this,[].slice.call(arguments,0))},_onCleared:function(){return
 
this._allDatasetsEmpty()?this._hide():this.isOpen()&&this._show(),c._onCleared.apply(this,[].slice.call(arguments,0))},setLanguageDirection:function(a){return
 
this.$node.css("ltr"===a?this.css.ltr:this.css.rtl),c.setLanguageDirection.apply(this,[].slice.call(arguments,0))},_hide:function(){this.$node.hide()},_show:function(){this.$node.css("display","block")}}),a}(),l=function(){"use
 strict";function c(c,e){var 
f,g,h,i,j,k,l,m,n,o,p;c=c||{},c.input||a.error("missing 
input"),c.menu||a.error("missing menu"),c.eventBus||a.error("missing event 
bus"),e.mixin(this),this.eventBus=c.eventBus,this.minLength=b.isNumber(c.minLength)?c.minLength:1,this.input=c.input,this.menu=c.menu,this.enabled=!0,this.autoselect=!!c.autoselect,this.active=!1,this.input.hasFocus()&&this.activate(),this.dir=this.input.getLangDir(),this._hacks(),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),f=d(this,"activate","open","_onFocused"),g=d(this,"deactivate","_onBlurred"),h=d(this,"isActive","isOpen","_onEnterKeyed"),i=d(this,"isActive","isOpen","_onTabKeyed"),j=d(this,"isActive","_onEscKeyed"),k=d(this,"isActive","open","_onUpKeyed"),l=d(this,"isActive","open","_onDownKeyed"),m=d(this,"isActive","isOpen","_onLeftKeyed"),n=d(this,"isActive","isOpen","_onRightKeyed"),o=d(this,"_openIfActive","_onQueryChanged"),p=d(this,"_openIfActive","_onWhitespaceChanged"),this.input.bind().onSync("focused",f,this).onSync("blurred",g,this).onSync("enterKeyed",h,this).onSync("tabKeyed",i,this).onSync("escKeyed",j,this).onSync("upKeyed",k,this).onSync("downKeyed",l,this).onSync("leftKeyed",m,this).onSync("rightKeyed",n,this).onSync("queryChanged",o,this).onSync("whitespaceChanged",p,this).onSync("langDirChanged",this._onLangDirChanged,this)}function
 d(a){var c=[].slice.call(arguments,1);return function(){var 
d=[].slice.call(arguments);b.each(c,function(b){return 
a[b].apply(a,d)})}}return b.mixin(c.prototype,{_hacks:function(){var 
c,d;c=this.input.$input||a("<div>"),d=this.menu.$node||a("<div>"),c.on("blur.tt",function(a){var
 
e,f,g;e=document.activeElement,f=d.is(e),g=d.has(e).length>0,b.isMsie()&&(f||g)&&(a.preventDefault(),a.stopImmediatePropagation(),b.defer(function(){c.focus()}))}),d.on("mousedown.tt",function(a){a.preventDefault()})},_onSelectableClicked:function(a,b){this.select(b)},_onDatasetCleared:function(){this._updateHint()},_onDatasetRendered:function(a,b,c,d){if(this._updateHint(),this.autoselect){var
 
e=this.selectors.cursor.substr(1);this.menu.$node.find(this.selectors.suggestion).first().addClass(e)}this.eventBus.trigger("render",b,c,d)},_onAsyncRequested:function(a,b,c){this.eventBus.trigger("asyncrequest",c,b)},_onAsyncCanceled:function(a,b,c){this.eventBus.trigger("asynccancel",c,b)},_onAsyncReceived:function(a,b,c){this.eventBus.trigger("asyncreceive",c,b)},_onFocused:function(){this._minLengthMet()&&this.menu.update(this.input.getQuery())},_onBlurred:function(){this.input.hasQueryChangedSinceLastFocus()&&this.eventBus.trigger("change",this.input.getQuery())},_onEnterKeyed:function(a,b){var
 
c;(c=this.menu.getActiveSelectable())?this.select(c)&&(b.preventDefault(),b.stopPropagation()):this.autoselect&&this.select(this.menu.getTopSelectable())&&(b.preventDefault(),b.stopPropagation())},_onTabKeyed:function(a,b){var
 
c;(c=this.menu.getActiveSelectable())?this.select(c)&&b.preventDefault():this.autoselect&&(c=this.menu.getTopSelectable())&&this.autocomplete(c)&&b.preventDefault()},_onEscKeyed:function(){this.close()},_onUpKeyed:function(){this.moveCursor(-1)},_onDownKeyed:function(){this.moveCursor(1)},_onLeftKeyed:function(){"rtl"===this.dir&&this.input.isCursorAtEnd()&&this.autocomplete(this.menu.getActiveSelectable()||this.menu.getTopSelectable())},_onRightKeyed:function(){"ltr"===this.dir&&this.input.isCursorAtEnd()&&this.autocomplete(this.menu.getActiveSelectable()||this.menu.getTopSelectable())},_onQueryChanged:function(a,b){this._minLengthMet(b)?this.menu.update(b):this.menu.empty()},_onWhitespaceChanged:function(){this._updateHint()},_onLangDirChanged:function(a,b){this.dir!==b&&(this.dir=b,this.menu.setLanguageDirection(b))},_openIfActive:function(){this.isActive()&&this.open()},_minLengthMet:function(a){return
 
a=b.isString(a)?a:this.input.getQuery()||"",a.length>=this.minLength},_updateHint:function(){var
 
a,c,d,e,f,h,i;a=this.menu.getTopSelectable(),c=this.menu.getSelectableData(a),d=this.input.getInputValue(),!c||b.isBlankString(d)||this.input.hasOverflow()?this.input.clearHint():(e=g.normalizeQuery(d),f=b.escapeRegExChars(e),h=new
 
RegExp("^(?:"+f+")(.+$)","i"),(i=h.exec(c.val))&&this.input.setHint(d+i[1]))},isEnabled:function(){return
 
this.enabled},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},isActive:function(){return
 
this.active},activate:function(){return!!this.isActive()||!(!this.isEnabled()||this.eventBus.before("active"))&&(this.active=!0,this.eventBus.trigger("active"),!0)},deactivate:function(){return!this.isActive()||!this.eventBus.before("idle")&&(this.active=!1,this.close(),this.eventBus.trigger("idle"),!0)},isOpen:function(){return
 this.menu.isOpen()},open:function(){return 
this.isOpen()||this.eventBus.before("open")||(this.input.setAriaExpanded(!0),this.menu.open(),this._updateHint(),this.eventBus.trigger("open")),this.isOpen()},close:function(){return
 
this.isOpen()&&!this.eventBus.before("close")&&(this.input.setAriaExpanded(!1),this.menu.close(),this.input.clearHint(),this.input.resetInputValue(),this.eventBus.trigger("close")),!this.isOpen()},setVal:function(a){this.input.setQuery(b.toStr(a))},getVal:function(){return
 this.input.getQuery()},select:function(a){var 
b=this.menu.getSelectableData(a);return!(!b||this.eventBus.before("select",b.obj,b.dataset))&&(this.input.setQuery(b.val,!0),this.eventBus.trigger("select",b.obj,b.dataset),this.close(),!0)},autocomplete:function(a){var
 b,c;return 
b=this.input.getQuery(),c=this.menu.getSelectableData(a),!(!(c&&b!==c.val)||this.eventBus.before("autocomplete",c.obj,c.dataset))&&(this.input.setQuery(c.val),this.eventBus.trigger("autocomplete",c.obj,c.dataset),!0)},moveCursor:function(a){var
 b,c,d,e,f,g;return 
b=this.input.getQuery(),c=this.menu.selectableRelativeToCursor(a),d=this.menu.getSelectableData(c),e=d?d.obj:null,f=d?d.dataset:null,g=c?c.attr("id"):null,this.input.trigger("cursorchange",g),!(this._minLengthMet()&&this.menu.update(b))&&!this.eventBus.before("cursorchange",e,f)&&(this.menu.setCursor(c),d?"string"==typeof
 
d.val&&this.input.setInputValue(d.val):(this.input.resetInputValue(),this._updateHint()),this.eventBus.trigger("cursorchange",e,f),!0)},destroy:function(){this.input.destroy(),this.menu.destroy()}}),c}();!function(){"use
 strict";function e(b,c){b.each(function(){var 
b,d=a(this);(b=d.data(q.typeahead))&&c(b,d)})}function f(a,b){return 
a.clone().addClass(b.classes.hint).removeData().css(b.css.hint).css(m(a)).prop({readonly:!0,required:!1}).removeAttr("id
 name 
placeholder").removeClass("required").attr({spellcheck:"false",tabindex:-1})}function
 
h(a,b){a.data(q.attrs,{dir:a.attr("dir"),autocomplete:a.attr("autocomplete"),spellcheck:a.attr("spellcheck"),style:a.attr("style")}),a.addClass(b.classes.input).attr({spellcheck:!1});try{!a.attr("dir")&&a.attr("dir","auto")}catch(a){}return
 a}function 
m(a){return{backgroundAttachment:a.css("background-attachment"),backgroundClip:a.css("background-clip"),backgroundColor:a.css("background-color"),backgroundImage:a.css("background-image"),backgroundOrigin:a.css("background-origin"),backgroundPosition:a.css("background-position"),backgroundRepeat:a.css("background-repeat"),backgroundSize:a.css("background-size")}}function
 n(a){var 
c,d;c=a.data(q.www),d=a.parent().filter(c.selectors.wrapper),b.each(a.data(q.attrs),function(c,d){b.isUndefined(c)?a.removeAttr(d):a.attr(d,c)}),a.removeData(q.typeahead).removeData(q.www).removeData(q.attr).removeClass(c.classes.input),d.length&&(a.detach().insertAfter(d),d.remove())}function
 o(c){var d,e;return 
d=b.isJQuery(c)||b.isElement(c),e=d?a(c).first():[],e.length?e:null}var 
p,q,r;p=a.fn.typeahead,q={www:"tt-www",attrs:"tt-attrs",typeahead:"tt-typeahead"},r={initialize:function(e,m){function
 n(){var 
c,n,r,s,t,u,v,w,x,y,z;b.each(m,function(a){a.highlight=!!e.highlight}),c=a(this),n=a(p.html.wrapper),r=o(e.hint),s=o(e.menu),t=!1!==e.hint&&!r,u=!1!==e.menu&&!s,t&&(r=f(c,p)),u&&(s=a(p.html.menu).css(p.css.menu)),r&&r.val(""),c=h(c,p),(t||u)&&(n.css(p.css.wrapper),c.css(t?p.css.input:p.css.inputWithNoHint),c.wrap(n).parent().prepend(t?r:null).append(u?s:null)),z=u?k:i,v=new
 d({el:c}),w=new g({hint:r,input:c,menu:s},p),x=new 
z({node:s,datasets:m},p),new j({$input:c,menu:x}),y=new 
l({input:w,menu:x,eventBus:v,minLength:e.minLength,autoselect:e.autoselect},p),c.data(q.www,p),c.data(q.typeahead,y)}var
 p;return 
m=b.isArray(m)?m:[].slice.call(arguments,1),e=e||{},p=c(e.classNames),this.each(n)},isEnabled:function(){var
 a;return 
e(this.first(),function(b){a=b.isEnabled()}),a},enable:function(){return 
e(this,function(a){a.enable()}),this},disable:function(){return 
e(this,function(a){a.disable()}),this},isActive:function(){var a;return 
e(this.first(),function(b){a=b.isActive()}),a},activate:function(){return 
e(this,function(a){a.activate()}),this},deactivate:function(){return 
e(this,function(a){a.deactivate()}),this},isOpen:function(){var a;return 
e(this.first(),function(b){a=b.isOpen()}),a},open:function(){return 
e(this,function(a){a.open()}),this},close:function(){return 
e(this,function(a){a.close()}),this},select:function(b){var c=!1,d=a(b);return 
e(this.first(),function(a){c=a.select(d)}),c},autocomplete:function(b){var 
c=!1,d=a(b);return 
e(this.first(),function(a){c=a.autocomplete(d)}),c},moveCursor:function(a){var 
b=!1;return 
e(this.first(),function(c){b=c.moveCursor(a)}),b},val:function(a){var c;return 
arguments.length?(e(this,function(c){c.setVal(b.toStr(a))}),this):(e(this.first(),function(a){c=a.getVal()}),c)},destroy:function(){return
 
e(this,function(a,b){n(b),a.destroy()}),this}},a.fn.typeahead=function(a){return
 
r[a]?r[a].apply(this,[].slice.call(arguments,1)):r.initialize.apply(this,arguments)},a.fn.typeahead.noConflict=function(){return
 a.fn.typeahead=p,this}}()});
\ No newline at end of file
diff --git a/js/ext/typeahead.min.js b/js/ext/typeahead.min.js
deleted file mode 100644
index 51c61f0778..0000000000
--- a/js/ext/typeahead.min.js
+++ /dev/null
@@ -1 +0,0 @@
-(function(c){var l="0.9.3";var j={isMsie:function(){var m=/(msie) 
([\w.]+)/i.exec(navigator.userAgent);return 
m?parseInt(m[2],10):false},isBlankString:function(m){return 
!m||/^\s*$/.test(m)},escapeRegExChars:function(m){return 
m.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(m){return
 typeof m==="string"},isNumber:function(m){return typeof 
m==="number"},isArray:c.isArray,isFunction:c.isFunction,isObject:c.isPlainObject,isUndefined:function(m){return
 typeof m==="undefined"},bind:c.proxy,bindAll:function(n){var o;for(var m in 
n){c.isFunction(o=n[m])&&(n[m]=c.proxy(o,n))}},indexOf:function(n,o){for(var 
m=0;m<n.length;m++){if(n[m]===o){return m}}return 
-1},each:c.each,map:c.map,filter:c.grep,every:function(n,o){var 
m=true;if(!n){return 
m}c.each(n,function(p,q){if(!(m=o.call(null,q,p,n))){return false}});return 
!!m},some:function(n,o){var m=false;if(!n){return 
m}c.each(n,function(p,q){if(m=o.call(null,q,p,n)){return false}});return 
!!m},mixin:c.extend,getUniqueId:function(){var m=0;return function(){return 
m++}}(),defer:function(m){setTimeout(m,0)},debounce:function(o,q,n){var 
p,m;return function(){var 
u=this,t=arguments,s,r;s=function(){p=null;if(!n){m=o.apply(u,t)}};r=n&&!p;clearTimeout(p);p=setTimeout(s,q);if(r){m=o.apply(u,t)}return
 m}},throttle:function(r,t){var p,o,s,m,q,n;q=0;n=function(){q=new 
Date();s=null;m=r.apply(p,o)};return function(){var u=new 
Date(),v=t-(u-q);p=this;o=arguments;if(v<=0){clearTimeout(s);s=null;q=u;m=r.apply(p,o)}else{if(!s){s=setTimeout(n,v)}}return
 m}},tokenizeQuery:function(m){return 
c.trim(m).toLowerCase().split(/[\s]+/)},tokenizeText:function(m){return 
c.trim(m).toLowerCase().split(/[\s\-_]+/)},getProtocol:function(){return 
location.protocol},noop:function(){}};var k=function(){var 
m=/\s+/;return{on:function(n,p){var o;if(!p){return 
this}this._callbacks=this._callbacks||{};n=n.split(m);while(o=n.shift()){this._callbacks[o]=this._callbacks[o]||[];this._callbacks[o].push(p)}return
 this},trigger:function(o,r){var q,p;if(!this._callbacks){return 
this}o=o.split(m);while(q=o.shift()){if(p=this._callbacks[q]){for(var 
n=0;n<p.length;n+=1){p[n].call(this,{type:q,data:r})}}}return this}}}();var 
e=function(){var n="typeahead:";function m(p){if(!p||!p.el){c.error("EventBus 
initialized without 
el")}this.$el=c(p.el)}j.mixin(m.prototype,{trigger:function(p){var 
o=[].slice.call(arguments,1);this.$el.trigger(n+p,o)}});return m}();var 
g=function(){var 
m,n;try{m=window.localStorage;m.setItem("~~~","!");m.removeItem("~~~")}catch(r){m=null}function
 
p(t){this.prefix=["__",t,"__"].join("");this.ttlKey="__ttl__";this.keyMatcher=new
 RegExp("^"+this.prefix)}if(m&&window.JSON){n={_prefix:function(t){return 
this.prefix+t},_ttlKey:function(t){return 
this._prefix(t)+this.ttlKey},get:function(t){if(this.isExpired(t)){this.remove(t)}return
 
s(m.getItem(this._prefix(t)))},set:function(u,v,t){if(j.isNumber(t)){m.setItem(this._ttlKey(u),q(o()+t))}else{m.removeItem(this._ttlKey(u))}return
 
m.setItem(this._prefix(u),q(v))},remove:function(t){m.removeItem(this._ttlKey(t));m.removeItem(this._prefix(t));return
 this},clear:function(){var 
v,u,w=[],t=m.length;for(v=0;v<t;v++){if((u=m.key(v)).match(this.keyMatcher)){w.push(u.replace(this.keyMatcher,""))}}for(v=w.length;v--;){this.remove(w[v])}return
 this},isExpired:function(u){var t=s(m.getItem(this._ttlKey(u)));return 
j.isNumber(t)&&o()>t?true:false}}}else{n={get:j.noop,set:j.noop,remove:j.noop,clear:j.noop,isExpired:j.noop}}j.mixin(p.prototype,n);return
 p;function o(){return new Date().getTime()}function q(t){return 
JSON.stringify(j.isUndefined(t)?null:t)}function s(t){return 
JSON.parse(t)}}();var i=function(){function 
m(n){j.bindAll(this);n=n||{};this.sizeLimit=n.sizeLimit||10;this.cache={};this.cachedKeysByAge=[]}j.mixin(m.prototype,{get:function(n){return
 this.cache[n]},set:function(o,p){var 
n;if(this.cachedKeysByAge.length===this.sizeLimit){n=this.cachedKeysByAge.shift();delete
 this.cache[n]}this.cache[o]=p;this.cachedKeysByAge.push(o)}});return m}();var 
d=function(){var n=0,q={},m,s;function 
t(u){j.bindAll(this);u=j.isString(u)?{url:u}:u;s=s||new 
i();m=j.isNumber(u.maxParallelRequests)?u.maxParallelRequests:m||6;this.url=u.url;this.wildcard=u.wildcard||"%QUERY";this.filter=u.filter;this.replace=u.replace;this.ajaxSettings={type:"get",cache:u.cache,timeout:u.timeout,dataType:u.dataType||"json",beforeSend:u.beforeSend};this._get=(/^throttle$/i.test(u.rateLimitFn)?j.throttle:j.debounce)(this._get,u.rateLimitWait||300)}j.mixin(t.prototype,{_get:function(w,u){var
 
x=this;if(p()){this._sendRequest(w).done(v)}else{this.onDeckRequestArgs=[].slice.call(arguments,0)}function
 v(z){var 
y=x.filter?x.filter(z):z;u&&u(y);s.set(w,z)}},_sendRequest:function(v){var 
x=this,w=q[v];if(!w){o();w=q[v]=c.ajax(v,this.ajaxSettings).always(u)}return 
w;function 
u(){r();q[v]=null;if(x.onDeckRequestArgs){x._get.apply(x,x.onDeckRequestArgs);x.onDeckRequestArgs=null}}},get:function(y,u){var
 
x=this,w=encodeURIComponent(y||""),v,z;u=u||j.noop;v=this.replace?this.replace(this.url,w):this.url.replace(this.wildcard,w);if(z=s.get(v)){j.defer(function(){u(x.filter?x.filter(z):z)})}else{this._get(v,u)}return
 !!z}});return t;function o(){n++}function r(){n--}function p(){return 
n<m}}();var a=function(){var 
o={thumbprint:"thumbprint",protocol:"protocol",itemHash:"itemHash",adjacencyList:"adjacencyList"};function
 n(p){j.bindAll(this);if(j.isString(p.template)&&!p.engine){c.error("no 
template engine specified")}if(!p.local&&!p.prefetch&&!p.remote){c.error("one 
of local, prefetch, or remote is 
required")}this.name=p.name||j.getUniqueId();this.limit=p.limit||5;this.minLength=p.minLength||1;this.header=p.header;this.footer=p.footer;this.valueKey=p.valueKey||"value";this.template=m(p.template,p.engine,this.valueKey);this.local=p.local;this.prefetch=p.prefetch;this.remote=p.remote;this.itemHash={};this.adjacencyList={};this.storage=p.name?new
 
g(p.name):null}j.mixin(n.prototype,{_processLocalData:function(p){this._mergeProcessedData(this._processData(p))},_loadPrefetchData:function(q){var
 
t=this,y=l+(q.thumbprint||""),w,r,u,p,s,x;if(this.storage){w=this.storage.get(o.thumbprint);r=this.storage.get(o.protocol);u=this.storage.get(o.itemHash);p=this.storage.get(o.adjacencyList)}s=w!==y||r!==j.getProtocol();q=j.isString(q)?{url:q}:q;q.ttl=j.isNumber(q.ttl)?q.ttl:24*60*60*1000;if(u&&p&&!s){this._mergeProcessedData({itemHash:u,adjacencyList:p});x=c.Deferred().resolve()}else{x=c.getJSON(q.url).done(v)}return
 x;function v(D){var 
C=q.filter?q.filter(D):D,B=t._processData(C),z=B.itemHash,A=B.adjacencyList;if(t.storage){t.storage.set(o.itemHash,z,q.ttl);t.storage.set(o.adjacencyList,A,q.ttl);t.storage.set(o.thumbprint,y,q.ttl);t.storage.set(o.protocol,j.getProtocol(),q.ttl)}t._mergeProcessedData(B)}},_transformDatum:function(p){var
 
r=j.isString(p)?p:p[this.valueKey],s=p.tokens||j.tokenizeText(r),q={value:r,tokens:s};if(j.isString(p)){q.datum={};q.datum[this.valueKey]=p}else{q.datum=p}q.tokens=j.filter(q.tokens,function(t){return
 !j.isBlankString(t)});q.tokens=j.map(q.tokens,function(t){return 
t.toLowerCase()});return q},_processData:function(s){var 
r=this,p={},q={};j.each(s,function(u,t){var 
v=r._transformDatum(t),w=j.getUniqueId(v.value);p[w]=v;j.each(v.tokens,function(y,x){var
 
A=x.charAt(0),z=q[A]||(q[A]=[w]);!~j.indexOf(z,w)&&z.push(w)})});return{itemHash:p,adjacencyList:q}},_mergeProcessedData:function(p){var
 
q=this;j.mixin(this.itemHash,p.itemHash);j.each(p.adjacencyList,function(t,s){var
 
r=q.adjacencyList[t];q.adjacencyList[t]=r?r.concat(s):s})},_getLocalSuggestions:function(u){var
 t=this,s=[],q=[],r,p=[];j.each(u,function(w,v){var 
x=v.charAt(0);!~j.indexOf(s,x)&&s.push(x)});j.each(s,function(v,w){var 
x=t.adjacencyList[w];if(!x){return 
false}q.push(x);if(!r||x.length<r.length){r=x}});if(q.length<s.length){return[]}j.each(r,function(v,z){var
 x=t.itemHash[z],y,w;y=j.every(q,function(A){return 
~j.indexOf(A,z)});w=y&&j.every(u,function(A){return 
j.some(x.tokens,function(B){return B.indexOf(A)===0})});w&&p.push(x)});return 
p},initialize:function(){var 
p;this.local&&this._processLocalData(this.local);this.transport=this.remote?new 
d(this.remote):null;p=this.prefetch?this._loadPrefetchData(this.prefetch):c.Deferred().resolve();this.local=this.prefetch=this.remote=null;this.initialize=function(){return
 p};return p},getSuggestions:function(u,q){var 
t=this,s,p,r=false;if(u.length<this.minLength){return}s=j.tokenizeQuery(u);p=this._getLocalSuggestions(s).slice(0,this.limit);if(p.length<this.limit&&this.transport){r=this.transport.get(u,v)}!r&&q&&q(p);function
 v(w){p=p.slice(0);j.each(w,function(z,y){var 
A=t._transformDatum(y),x;x=j.some(p,function(B){return 
A.value===B.value});!x&&p.push(A);return p.length<t.limit});q&&q(p)}}});return 
n;function m(s,r,t){var 
q,p;if(j.isFunction(s)){q=s}else{if(j.isString(s)){p=r.compile(s);q=j.bind(p.render,p)}else{q=function(u){return"<p>"+u[t]+"</p>"}}}return
 q}}();var b=function(){function n(q){var 
p=this;j.bindAll(this);this.specialKeyCodeMap={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"};this.$hint=c(q.hint);this.$input=c(q.input).on("blur.tt",this._handleBlur).on("focus.tt",this._handleFocus).on("keydown.tt",this._handleSpecialKeyEvent);if(!j.isMsie()){this.$input.on("input.tt",this._compareQueryToInputValue)}else{this.$input.on("keydown.tt
 keypress.tt cut.tt 
paste.tt",function(r){if(p.specialKeyCodeMap[r.which||r.keyCode]){return}j.defer(p._compareQueryToInputValue)})}this.query=this.$input.val();this.$overflowHelper=o(this.$input)}j.mixin(n.prototype,k,{_handleFocus:function(){this.trigger("focused")},_handleBlur:function(){this.trigger("blured")},_handleSpecialKeyEvent:function(p){var
 
q=this.specialKeyCodeMap[p.which||p.keyCode];q&&this.trigger(q+"Keyed",p)},_compareQueryToInputValue:function(){var
 
p=this.getInputValue(),r=m(this.query,p),q=r?this.query.length!==p.length:false;if(q){this.trigger("whitespaceChanged",{value:this.query})}else{if(!r){this.trigger("queryChanged",{value:this.query=p})}}},destroy:function(){this.$hint.off(".tt");this.$input.off(".tt");this.$hint=this.$input=this.$overflowHelper=null},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return
 this.query},setQuery:function(p){this.query=p},getInputValue:function(){return 
this.$input.val()},setInputValue:function(q,p){this.$input.val(q);!p&&this._compareQueryToInputValue()},getHintValue:function(){return
 
this.$hint.val()},setHintValue:function(p){this.$hint.val(p)},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},isOverflow:function(){this.$overflowHelper.text(this.getInputValue());return
 this.$overflowHelper.width()>this.$input.width()},isCursorAtEnd:function(){var 
q=this.$input.val().length,r=this.$input[0].selectionStart,p;if(j.isNumber(r)){return
 
r===q}else{if(document.selection){p=document.selection.createRange();p.moveStart("character",-q);return
 q===p.text.length}}return true}});return n;function o(p){return 
c("<span></span>").css({position:"absolute",left:"-9999px",visibility:"hidden",whiteSpace:"nowrap",fontFamily:p.css("font-family"),fontSize:p.css("font-size"),fontStyle:p.css("font-style"),fontVariant:p.css("font-variant"),fontWeight:p.css("font-weight"),wordSpacing:p.css("word-spacing"),letterSpacing:p.css("letter-spacing"),textIndent:p.css("text-indent"),textRendering:p.css("text-rendering"),textTransform:p.css("text-transform")}).insertAfter(p)}function
 m(q,p){q=(q||"").replace(/^\s*/g,"").replace(/\s{2,}/g," 
");p=(p||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ");return q===p}}();var 
f=function(){var o={suggestionsList:'<span 
class="tt-suggestions"></span>'},n={suggestionsList:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"}};function
 
p(q){j.bindAll(this);this.isOpen=false;this.isEmpty=true;this.isMouseOverDropdown=false;this.$menu=c(q.menu).on("mouseenter.tt",this._handleMouseenter).on("mouseleave.tt",this._handleMouseleave).on("click.tt",".tt-suggestion",this._handleSelection).on("mouseover.tt",".tt-suggestion",this._handleMouseover)}j.mixin(p.prototype,k,{_handleMouseenter:function(){this.isMouseOverDropdown=true},_handleMouseleave:function(){this.isMouseOverDropdown=false},_handleMouseover:function(r){var
 
q=c(r.currentTarget);this._getSuggestions().removeClass("tt-is-under-cursor");q.addClass("tt-is-under-cursor")},_handleSelection:function(r){var
 
q=c(r.currentTarget);this.trigger("suggestionSelected",m(q))},_show:function(){this.$menu.css("display","block")},_hide:function(){this.$menu.hide()},_moveCursor:function(s){var
 
u,r,q,t;if(!this.isVisible()){return}u=this._getSuggestions();r=u.filter(".tt-is-under-cursor");r.removeClass("tt-is-under-cursor");q=u.index(r)+s;q=(q+1)%(u.length+1)-1;if(q===-1){this.trigger("cursorRemoved");return}else{if(q<-1){q=u.length-1}}t=u.eq(q).addClass("tt-is-under-cursor");this._ensureVisibility(t);this.trigger("cursorMoved",m(t))},_getSuggestions:function(){return
 this.$menu.find(".tt-suggestions > 
.tt-suggestion")},_ensureVisibility:function(t){var 
u=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),r=this.$menu.scrollTop(),q=t.position().top,s=q+t.outerHeight(true);if(q<0){this.$menu.scrollTop(r+q)}else{if(u<s){this.$menu.scrollTop(r+(s-u))}}},destroy:function(){this.$menu.off(".tt");this.$menu=null},isVisible:function(){return
 
this.isOpen&&!this.isEmpty},closeUnlessMouseIsOverDropdown:function(){if(!this.isMouseOverDropdown){this.close()}},close:function(){if(this.isOpen){this.isOpen=false;this.isMouseOverDropdown=false;this._hide();this.$menu.find(".tt-suggestions
 > 
.tt-suggestion").removeClass("tt-is-under-cursor");this.trigger("closed")}},open:function(){if(!this.isOpen){this.isOpen=true;!this.isEmpty&&this._show();this.trigger("opened")}},setLanguageDirection:function(q){var
 r={left:"0",right:"auto"},s={left:"auto",right:" 
0"};q==="ltr"?this.$menu.css(r):this.$menu.css(s)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(+1)},getSuggestionUnderCursor:function(){var
 q=this._getSuggestions().filter(".tt-is-under-cursor").first();return 
q.length>0?m(q):null},getFirstSuggestion:function(){var 
q=this._getSuggestions().first();return 
q.length>0?m(q):null},renderSuggestions:function(t,u){var 
q="tt-dataset-"+t.name,r='<div 
class="tt-suggestion">%body</div>',x,w,y=this.$menu.find("."+q),s,v,z;if(y.length===0){w=c(o.suggestionsList).css(n.suggestionsList);y=c("<div></div>").addClass(q).append(t.header).append(w).append(t.footer).appendTo(this.$menu)}if(u.length>0){this.isEmpty=false;this.isOpen&&this._show();s=document.createElement("div");v=document.createDocumentFragment();j.each(u,function(B,A){A.dataset=t.name;x=t.template(A.datum);s.innerHTML=r.replace("%body",x);z=c(s.firstChild).css(n.suggestion).data("suggestion",A);z.children().each(function(){c(this).css(n.suggestionChild)});v.appendChild(z[0])});y.show().find(".tt-suggestions").html(v)}else{this.clearSuggestions(t.name)}this.trigger("suggestionsRendered")},clearSuggestions:function(s){var
 
q=s?this.$menu.find(".tt-dataset-"+s):this.$menu.find('[class^="tt-dataset-"]'),r=q.find(".tt-suggestions");q.hide();r.empty();if(this._getSuggestions().length===0){this.isEmpty=true;this._hide()}}});return
 p;function m(q){return q.data("suggestion")}}();var h=function(){var 
q={wrapper:'<span class="twitter-typeahead"></span>',hint:'<input 
class="tt-hint" type="text" autocomplete="off" spellcheck="off" 
disabled>',dropdown:'<span 
class="tt-dropdown-menu"></span>'},p={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none"},query:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"}};if(j.isMsie()){j.mixin(p.query,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"})}if(j.isMsie()&&j.isMsie()<=7){j.mixin(p.wrapper,{display:"inline",zoom:"1"});j.mixin(p.query,{marginTop:"-1px"})}function
 n(t){var 
s,u,r;j.bindAll(this);this.$node=m(t.input);this.datasets=t.datasets;this.dir=null;this.eventBus=t.eventBus;s=this.$node.find(".tt-dropdown-menu");u=this.$node.find(".tt-query");r=this.$node.find(".tt-hint");this.dropdownView=new
 
f({menu:s}).on("suggestionSelected",this._handleSelection).on("cursorMoved",this._clearHint).on("cursorMoved",this._setInputValueToSuggestionUnderCursor).on("cursorRemoved",this._setInputValueToQuery).on("cursorRemoved",this._updateHint).on("suggestionsRendered",this._updateHint).on("opened",this._updateHint).on("closed",this._clearHint).on("opened
 closed",this._propagateEvent);this.inputView=new 
b({input:u,hint:r}).on("focused",this._openDropdown).on("blured",this._closeDropdown).on("blured",this._setInputValueToQuery).on("enterKeyed
 
tabKeyed",this._handleSelection).on("queryChanged",this._clearHint).on("queryChanged",this._clearSuggestions).on("queryChanged",this._getSuggestions).on("whitespaceChanged",this._updateHint).on("queryChanged
 whitespaceChanged",this._openDropdown).on("queryChanged 
whitespaceChanged",this._setLanguageDirection).on("escKeyed",this._closeDropdown).on("escKeyed",this._setInputValueToQuery).on("tabKeyed
 upKeyed downKeyed",this._managePreventDefault).on("upKeyed 
downKeyed",this._moveDropdownCursor).on("upKeyed 
downKeyed",this._openDropdown).on("tabKeyed leftKeyed 
rightKeyed",this._autocomplete)}j.mixin(n.prototype,k,{_managePreventDefault:function(u){var
 
t=u.data,v,r,s=false;switch(u.type){case"tabKeyed":v=this.inputView.getHintValue();r=this.inputView.getInputValue();s=v&&v!==r;break;case"upKeyed":case"downKeyed":s=!t.shiftKey&&!t.ctrlKey&&!t.metaKey;break}s&&t.preventDefault()},_setLanguageDirection:function(){var
 
r=this.inputView.getLanguageDirection();if(r!==this.dir){this.dir=r;this.$node.css("direction",r);this.dropdownView.setLanguageDirection(r)}},_updateHint:function(){var
 
u=this.dropdownView.getFirstSuggestion(),t=u?u.value:null,x=this.dropdownView.isVisible(),w=this.inputView.isOverflow(),s,y,z,r,v;if(t&&x&&!w){s=this.inputView.getInputValue();y=s.replace(/\s{2,}/g,"
 ").replace(/^\s+/g,"");z=j.escapeRegExChars(y);r=new 
RegExp("^(?:"+z+")(.*$)","i");v=r.exec(t);this.inputView.setHintValue(s+(v?v[1]:""))}},_clearHint:function(){this.inputView.setHintValue("")},_clearSuggestions:function(){this.dropdownView.clearSuggestions()},_setInputValueToQuery:function(){this.inputView.setInputValue(this.inputView.getQuery())},_setInputValueToSuggestionUnderCursor:function(s){var
 
r=s.data;this.inputView.setInputValue(r.value,true)},_openDropdown:function(){this.dropdownView.open()},_closeDropdown:function(r){this.dropdownView[r.type==="blured"?"closeUnlessMouseIsOverDropdown":"close"]()},_moveDropdownCursor:function(s){var
 
r=s.data;if(!r.shiftKey&&!r.ctrlKey&&!r.metaKey){this.dropdownView[s.type==="upKeyed"?"moveCursorUp":"moveCursorDown"]()}},_handleSelection:function(t){var
 
s=t.type==="suggestionSelected",r=s?t.data:this.dropdownView.getSuggestionUnderCursor();if(r){this.inputView.setInputValue(r.value);s?this.inputView.focus():t.data.preventDefault();s&&j.isMsie()?j.defer(this.dropdownView.close):this.dropdownView.close();this.eventBus.trigger("selected",r.datum,r.dataset)}},_getSuggestions:function(){var
 
r=this,s=this.inputView.getQuery();if(j.isBlankString(s)){return}j.each(this.datasets,function(t,u){u.getSuggestions(s,function(v){if(s===r.inputView.getQuery()){r.dropdownView.renderSuggestions(u,v)}})})},_autocomplete:function(v){var
 
s,r,u,w,t;if(v.type==="rightKeyed"||v.type==="leftKeyed"){s=this.inputView.isCursorAtEnd();r=this.inputView.getLanguageDirection()==="ltr"?v.type==="leftKeyed":v.type==="rightKeyed";if(!s||r){return}}u=this.inputView.getQuery();w=this.inputView.getHintValue();if(w!==""&&u!==w){t=this.dropdownView.getFirstSuggestion();this.inputView.setInputValue(t.value);this.eventBus.trigger("autocompleted",t.datum,t.dataset)}},_propagateEvent:function(r){this.eventBus.trigger(r.type)},destroy:function(){this.inputView.destroy();this.dropdownView.destroy();o(this.$node);this.$node=null},setQuery:function(r){this.inputView.setQuery(r);this.inputView.setInputValue(r);this._clearHint();this._clearSuggestions();this._getSuggestions()}});return
 n;function m(r){var 
t=c(q.wrapper),v=c(q.dropdown),w=c(r),s=c(q.hint);t=t.css(p.wrapper);v=v.css(p.dropdown);s.css(p.hint).css({backgroundAttachment:w.css("background-attachment"),backgroundClip:w.css("background-clip"),backgroundColor:w.css("background-color"),backgroundImage:w.css("background-image"),backgroundOrigin:w.css("background-origin"),backgroundPosition:w.css("background-position"),backgroundRepeat:w.css("background-repeat"),backgroundSize:w.css("background-size")});w.data("ttAttrs",{dir:w.attr("dir"),autocomplete:w.attr("autocomplete"),spellcheck:w.attr("spellcheck"),style:w.attr("style")});w.addClass("tt-query").attr({autocomplete:"off",spellcheck:false}).css(p.query);try{!w.attr("dir")&&w.attr("dir","auto")}catch(u){}return
 w.wrap(t).parent().prepend(s).append(v)}function o(r){var 
s=r.find(".tt-query");j.each(s.data("ttAttrs"),function(t,u){j.isUndefined(u)?s.removeAttr(t):s.attr(t,u)});s.detach().removeData("ttAttrs").removeClass("tt-query").insertAfter(r);r.remove()}}();(function(){var
 n={},o="ttView",m;m={initialize:function(r){var 
q;r=j.isArray(r)?r:[r];if(r.length===0){c.error("no datasets 
provided")}q=j.map(r,function(t){var s=n[t.name]?n[t.name]:new 
a(t);if(t.name){n[t.name]=s}return s});return this.each(p);function p(){var 
u=c(this),t,s=new e({el:u});t=j.map(q,function(v){return 
v.initialize()});u.data(o,new h({input:u,eventBus:s=new 
e({el:u}),datasets:q}));c.when.apply(c,t).always(function(){j.defer(function(){s.trigger("initialized")})})}},destroy:function(){return
 this.each(p);function p(){var 
r=c(this),q=r.data(o);if(q){q.destroy();r.removeData(o)}}},setQuery:function(p){return
 this.each(q);function q(){var 
r=c(this).data(o);r&&r.setQuery(p)}}};jQuery.fn.typeahead=function(p){if(m[p]){return
 m[p].apply(this,[].slice.call(arguments,1))}else{return 
m.initialize.apply(this,arguments)}}})()})(window.jQuery);
diff --git a/js/search.js b/js/search.js
index 37fc0ea16f..4e80d2835c 100644
--- a/js/search.js
+++ b/js/search.js
@@ -19,13 +19,12 @@
     /**
      * Adds an item to the backend.
      *
-     * @param {String} id     The item ID. It would help if this was unique.
-     * @param {String} name   The item name to use as a label.
-     * @param {Array}  tokens An array of tokens that should match this item.
+     * @param {String} id          The item ID. It would help if this was 
unique.
+     * @param {String} name        The item name to use as a label.
+     * @param {String} description Explanatory text for item.
      */
-    Backend.prototype.addItem = function (id, name, description, tokens) {
+    Backend.prototype.addItem = function (id, name, description) {
         this.elements[id] = {
-            tokens: tokens,
             id: id,
             name: name,
             description: description
@@ -42,52 +41,18 @@
         var array = [];
 
         $.each(this.elements, function (_, element) {
-            array.push(element);
-        });
-
-        /* This is a rather convoluted sorting function, but the idea is to
-         * make the results as useful as possible, since only a few are shown
-         * at any one time. In general, we favour shorter names over longer
-         * ones, and favour regular functions over methods when sorting
-         * functions. Ideally, this would actually sort based on function
-         * popularity, but this is a simpler algorithmic approach for now that
-         * seems to result in generally useful results. */
-        array.sort(function (a, b) {
-            var a = a.name;
-            var b = b.name;
-
-            var aIsMethod = (a.indexOf("::") != -1);
-            var bIsMethod = (b.indexOf("::") != -1);
-
-            // Methods are always after regular functions.
-            if (aIsMethod && !bIsMethod) {
-                return 1;
-            } else if (bIsMethod && !aIsMethod) {
-                return -1;
-            }
-
-            /* If one function name is the exact prefix of the other, we want
-             * to sort the shorter version first (mostly for things like date()
-             * versus date_format()). */
-            if (a.length > b.length) {
-                if (a.indexOf(b) == 0) {
-                    return 1;
-                }
+            element.methodName = element.name.split('::');
+            if (element.methodName.length > 1) {
+                element.methodName = element.methodName.slice(-1)[0];
             } else {
-                if (b.indexOf(a) == 0) {
-                    return -1;
-                }
+                delete element.methodName;
             }
-
-            // Otherwise, sort normally.
-            if (a > b) {
-                return 1;
-            } else if (a < b) {
-                return -1;
-            }
-
-            return 0;
+            array.push(element);
         });
+
+        /**
+         * Old pre-sorting has no effect on results sorted by score.
+         */
         return array;
     };
 
@@ -143,21 +108,8 @@
                  * of data this is, and hence which backend this should go
                  * into. */
                 if (item[0]) {
-                    var tokens = [item[0]];
                     var type = null;
 
-                    if (item[0].indexOf("_") != -1) {
-                        tokens.push(item[0].replace("_", ""));
-                    }
-                    if (item[0].indexOf("::") != -1) {
-                        /* We'll add tokens to make the autocompletion more
-                         * useful: users can search for method names and can
-                         * specify that they only want method names by
-                         * prefixing their search with ::. */
-                        tokens.push(item[0].split("::")[1]);
-                        tokens.push("::" + item[0].split("::")[1]);
-                    }
-
                     switch(item[2]) {
                         case "phpdoc:varentry":
                             type = "variable";
@@ -190,7 +142,7 @@
                     }
 
                     if (type) {
-                        backends[type].addItem(id, item[0], item[1], tokens);
+                        backends[type].addItem(id, item[0], item[1]);
                     }
                 }
             });
@@ -270,33 +222,74 @@
          * @param {Object} backends An array-like object containing backends.
          */
         var enableSearchTypeahead = function (backends) {
-            var template = "<h4>{{ name }}</h4>" +
-                           "<span title='{{ description }}' 
class='description'>{{ description }}</span>";
+            var header = Hogan.compile(
+                '<h3 class="result-heading"><span 
class="collapsible"></span>{{ label }}' +
+                '<span class="result-count">{{ count }}</span></h3>' +
+                '<div class="tt-suggestions"></div>'
+            );
+            var template = Hogan.compile(
+                '<div>' +
+                    '<h4>{{ name }}</h4>' +
+                    '<span title="{{ description }}" class="description">{{ 
description }}</span>' +
+                '</div>'
+            );
 
             // Build the typeahead options array.
             var typeaheadOptions = $.map(backends, function (backend, name) {
-                var local = backend instanceof Backend ? 
backend.toTypeaheadArray() : backend;
+                var fuzzyhound = new FuzzySearch({
+                    source: backend.toTypeaheadArray(),
+                    token_sep: ' \t.,-_', // treat colon as part of token, 
ignore tabs (from pasted content)
+                    score_test_fused: true,
+                    keys: [
+                        'name',
+                        'methodName',
+                        'description'
+                    ],
+                    thresh_include: 5.0,
+                    thresh_relative_to_best: 0.7,
+                    bonus_match_start: 0.7,
+                    bonus_token_order: 1.0,
+                    bonus_position_decay: 0.3,
+                    token_query_min_length: 1,
+                    token_field_min_length: 2
+                });
 
                 return {
+                    source: fuzzyhound,
                     name: name,
-                    local: backend.toTypeaheadArray(),
-                    header: '<h3 class="result-heading"><span 
class="collapsible"></span>' + backend.label + '</h3>',
                     limit: options.limit,
-                    valueKey: "name",
-                    engine: Hogan,
-                    template: template
+                    display: 'name',
+                    templates: {
+                        header: function () {
+                            return header.render({
+                                label: backend.label,
+                                count: fuzzyhound.results.length
+                            });
+                        },
+                        suggestion: function (result) {
+                            return template.render({
+                                name: result.name,
+                                description: result.description
+                            });
+                        }
+                    }
                 };
             });
 
-            /* Construct a global that we can use to track the total number of
-             * results from each backend. */
-            var results = {};
-
             // Set up the typeahead and the various listeners we need.
-            var searchTypeahead = $(element).typeahead(typeaheadOptions);
+            var searchTypeahead = element.typeahead(
+                {
+                    minLength: 1,
+                    classNames: {
+                        menu: 'tt-dropdown-menu',
+                        cursor: 'tt-is-under-cursor'
+                    }
+                },
+                typeaheadOptions
+            );
 
             // Delegate click events to result-heading collapsible icons, and 
trigger the accordion action
-            $('.tt-dropdown-menu').delegate('.result-heading .collapsible', 
'click', function() {
+            $('.tt-dropdown-menu').delegate('.result-heading .collapsible', 
'click', function () {
                 var el = $(this), suggestions = 
el.parent().parent().find('.tt-suggestions');
                 suggestions.stop();
                 if(!el.hasClass('closed')) {
@@ -310,10 +303,20 @@
             });
 
             // If the user has selected an autocomplete item and hits enter, 
we should take them straight to the page.
-            searchTypeahead.on("typeahead:selected", function (_, item) {
-                window.location = "/manual/" + options.language + "/" + 
item.id;
+            searchTypeahead.on("typeahead:select", function (_, item) {
+                window.location = "/manual/" + options.language + "/" + 
item.id + ".php";
             });
 
+            // Get new parent after initialization
+            var elementParent = element.parent();
+
+            searchTypeahead.on('typeahead:render', function (evt, 
renderedSuggestions, fetchedAsync, datasetIndex) {
+                // Fix the missing wrapper from typeahead v0.9.3 for UI parity
+                var set = elementParent.find('.tt-dataset-' + datasetIndex);
+                
set.children('.tt-suggestions').first().append(set.children('.tt-suggestion'));
+            });
+
+            var lastPattern;
             searchTypeahead.on("keyup", (function () {
                 /* typeahead.js doesn't give us a reliable event for the
                  * dropdown entries having been updated, so we'll hook into the
@@ -323,41 +326,26 @@
                  * entered. */
 
                 // Precompile the templates we need for the fake entries.
-                var moreTemplate = Hogan.compile("<a class='more' href='{{ url 
}}'>&raquo; {{ num }} more result{{ plural }}</a>");
                 var searchTemplate = Hogan.compile("<a class='search' href='{{ 
url }}'>&raquo; Search php.net for {{ pattern }}</a>");
 
                 /* Now we'll return the actual function that should be invoked
                  * when the user has typed something into the search box after
                  * typeahead.js has done its thing. */
                 return function () {
-                    // Add result totals to each section heading.
-                    $.each(results, function (name, numResults) {
-                        var container = $(".tt-dataset-" + name, 
$(element).parent()),
-                            resultHeading = container.find('.result-heading'),
-                            resultCount = container.find('.result-count');
-
-                        // Does a result count already exist in this 
resultHeading?
-                        if(resultCount.length == 0) {
-                            var results = $("<span 
class='result-count'>").text(numResults);
-                            resultHeading.append(results);
-                        } else {
-                            resultCount.text(numResults);
-                        }
-
-
-                    });
-
                     // Grab what the user entered.
-                    var pattern = $(element).val();
+                    var pattern = element.val();
+                    if (pattern == lastPattern) {
+                        return;
+                    }
+                    lastPattern = pattern;
 
                     /* Add a global search option. Note that, as above, the
                      * link is only displayed if more than 2 characters have
                      * been entered: this is due to our search functionality
                      * requiring at least 3 characters in the pattern. */
-                    $(".tt-dropdown-menu .search", 
$(element).parent()).remove();
+                    var dropdown = elementParent.children('.tt-dropdown-menu');
+                    dropdown.children('.search').remove();
                     if (pattern.length > 2) {
-                        var dropdown = $(".tt-dropdown-menu", 
$(element).parent());
-
                         dropdown.append(searchTemplate.render({
                             pattern: pattern,
                             url: "/search.php?pattern=" + 
encodeURIComponent(pattern)
@@ -370,19 +358,6 @@
                 };
             })());
 
-            /* Override the dataset._getLocalSuggestions() method to grab the
-             * number of results each dataset returns when a search occurs. */
-            $.each($(element).data().ttView.datasets, function (_, dataset) {
-                var originalGetLocal = dataset._getLocalSuggestions;
-
-                dataset._getLocalSuggestions = function () {
-                    var suggestions = originalGetLocal.apply(dataset, 
arguments);
-
-                    results[dataset.name] = suggestions.length;
-                    return suggestions;
-                };
-            });
-
             /* typeahead.js adds another input element as part of its DOM
              * manipulation, which breaks the auto-submit functionality we
              * previously relied upon for enter keypresses in the input box to
@@ -390,7 +365,7 @@
             $("<input type='submit' style='visibility: hidden; position: 
fixed'>").insertAfter(element);
 
             // Fix for a styling issue on the created input element.
-            $(".tt-hint", $(element).parent()).addClass("search-query");
+            elementParent.children(".tt-hint").addClass("search-query");
         };
 
         // Look for the user's language, then fall back to English.
diff --git a/styles/theme-base.css b/styles/theme-base.css
index 97c494b6ce..7cbaed7dbe 100644
--- a/styles/theme-base.css
+++ b/styles/theme-base.css
@@ -1038,6 +1038,8 @@ fieldset {
     padding-top: 3px;
     margin-top: -3px;
     min-width: 100%;
+    overflow: auto;
+    max-height: 90vh;
 }
 
 .tt-dropdown-menu .result-heading {

Reply via email to