diff --git a/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.js b/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.js
new file mode 100755
index 000000000..fbd561da8
--- /dev/null
+++ b/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.js
@@ -0,0 +1,650 @@
+/*!
+ * jQuery.textcomplete.js
+ *
+ * Repositiory: https://github.com/yuku-t/jquery-textcomplete
+ * License: MIT
+ * Author: Yuku Takahashi
+ */
+
+;(function ($) {
+
+ 'use strict';
+
+ /**
+ * Exclusive execution control utility.
+ */
+ var lock = function (func) {
+ var free, locked, queuedArgsToReplay;
+ free = function () { locked = false; };
+ return function () {
+ var args = toArray(arguments);
+ if (locked) {
+ // Keep a copy of this argument list to replay later.
+ // OK to overwrite a previous value because we only replay the last one.
+ queuedArgsToReplay = args;
+ return;
+ }
+ locked = true;
+ var that = this;
+ args.unshift(function replayOrFree() {
+ if (queuedArgsToReplay) {
+ // Other request(s) arrived while we were locked.
+ // Now that the lock is becoming available, replay
+ // the latest such request, then call back here to
+ // unlock (or replay another request that arrived
+ // while this one was in flight).
+ var replayArgs = queuedArgsToReplay;
+ queuedArgsToReplay = undefined;
+ replayArgs.unshift(replayOrFree);
+ func.apply(that, replayArgs);
+ } else {
+ locked = false;
+ }
+ });
+ func.apply(this, args);
+ };
+ };
+
+ /**
+ * Convert arguments into a real array.
+ */
+ var toArray = function (args) {
+ var result;
+ result = Array.prototype.slice.call(args);
+ return result;
+ };
+
+ /**
+ * Get the styles of any element from property names.
+ */
+ var getStyles = (function () {
+ var color;
+ color = $('
').css(['color']).color;
+ if (typeof color !== 'undefined') {
+ return function ($el, properties) {
+ return $el.css(properties);
+ };
+ } else { // for jQuery 1.8 or below
+ return function ($el, properties) {
+ var styles;
+ styles = {};
+ $.each(properties, function (i, property) {
+ styles[property] = $el.css(property);
+ });
+ return styles;
+ };
+ }
+ })();
+
+ /**
+ * Default template function.
+ */
+ var identity = function (obj) { return obj; };
+
+ /**
+ * Memoize a search function.
+ */
+ var memoize = function (func) {
+ var memo = {};
+ return function (term, callback) {
+ if (memo[term]) {
+ callback(memo[term]);
+ } else {
+ func.call(this, term, function (data) {
+ memo[term] = (memo[term] || []).concat(data);
+ callback.apply(null, arguments);
+ });
+ }
+ };
+ };
+
+ /**
+ * Determine if the array contains a given value.
+ */
+ var include = function (array, value) {
+ var i, l;
+ if (array.indexOf) return array.indexOf(value) != -1;
+ for (i = 0, l = array.length; i < l; i++) {
+ if (array[i] === value) return true;
+ }
+ return false;
+ };
+
+ /**
+ * Textarea manager class.
+ */
+ var Completer = (function () {
+ var html, css, $baseList, _id;
+
+ html = {
+ list: ''
+ };
+ css = {
+ // Removed the 'top' property to support the placement: 'top' option
+ list: {
+ position: 'absolute',
+ left: 0,
+ zIndex: '100',
+ display: 'none'
+ }
+ };
+ $baseList = $(html.list).css(css.list);
+ _id = 0;
+
+ function Completer($el, option) {
+ var focus;
+ this.el = $el.get(0); // textarea element
+ focus = this.el === document.activeElement;
+ this.$el = $el;
+ this.id = 'textComplete' + _id++;
+ this.strategies = [];
+ this.option = option;
+ if (focus) {
+ this.initialize();
+ this.$el.focus();
+ } else {
+ this.$el.one('focus.textComplete', $.proxy(this.initialize, this));
+ }
+ }
+
+ /**
+ * Completer's public methods
+ */
+ $.extend(Completer.prototype, {
+
+ /**
+ * Prepare ListView and bind events.
+ */
+ initialize: function () {
+ var $list, globalEvents, appendTo;
+ $list = $baseList.clone();
+ this.listView = new ListView($list, this);
+ this.$el.on({
+ 'keyup.textComplete': $.proxy(this.onKeyup, this),
+ 'keydown.textComplete': $.proxy(this.listView.onKeydown, this.listView)
+ });
+ appendTo = this.option.appendTo;
+ if (appendTo) {
+ // Append ListView to specified element.
+ $list.appendTo(appendTo instanceof $ ? appendTo : $(appendTo));
+ } else {
+ this.$el.before($list);
+ }
+ globalEvents = {};
+ globalEvents['click.' + this.id] = $.proxy(this.onClickDocument, this);
+ globalEvents['keyup.' + this.id] = $.proxy(this.onKeyupDocument, this);
+ $(document).on(globalEvents);
+ },
+
+ /**
+ * Register strategies to the completer.
+ */
+ register: function (strategies) {
+ this.strategies = this.strategies.concat(strategies);
+ },
+
+ /**
+ * Show autocomplete list next to the caret.
+ */
+ renderList: function (data) {
+ if (this.clearAtNext) {
+ this.listView.clear();
+ this.clearAtNext = false;
+ }
+ if (data.length) {
+ this.listView.strategy = this.strategy;
+ if (!this.listView.shown) {
+ this.listView
+ .setPosition(this.getCaretPosition())
+ .clear()
+ .activate();
+ }
+ data = data.slice(0, this.strategy.maxCount);
+ this.listView.render(data);
+ }
+
+ if (!this.listView.data.length && this.listView.shown) {
+ this.listView.deactivate();
+ }
+ },
+
+ searchCallbackFactory: function (free) {
+ var self = this;
+ return function (data, keep) {
+ self.renderList(data);
+ if (!keep) {
+ // This is the last callback for this search.
+ free();
+ self.clearAtNext = true;
+ }
+ };
+ },
+
+ /**
+ * Keyup event handler.
+ */
+ onKeyup: function (e) {
+ var searchQuery, term;
+ if (this.skipSearch(e)) { return; }
+
+ searchQuery = this.extractSearchQuery(this.getTextFromHeadToCaret());
+ if (searchQuery.length) {
+ term = searchQuery[1];
+ if (this.term === term) return; // Ignore shift-key or something.
+ this.term = term;
+ this.search(searchQuery);
+ } else {
+ this.term = null;
+ this.listView.deactivate();
+ }
+ },
+
+ /**
+ * Suppress searching if it returns true.
+ */
+ skipSearch: function (e) {
+ switch (e.keyCode) {
+ case 40: // DOWN
+ case 38: // UP
+ return true;
+ }
+ if (e.ctrlKey) switch (e.keyCode) {
+ case 78: // Ctrl-N
+ case 80: // Ctrl-P
+ return true;
+ }
+ },
+
+ onSelect: function (value) {
+ var pre, post, newSubStr, sel, range, selection;
+ pre = this.getTextFromHeadToCaret();
+
+ if (this.el.contentEditable == 'true') {
+ sel = window.getSelection();
+ range = sel.getRangeAt(0);
+ selection = range.cloneRange();
+ selection.selectNodeContents(range.startContainer);
+ var content = selection.toString();
+ post = content.substring(range.startOffset);
+ } else {
+ post = this.el.value.substring(this.el.selectionEnd);
+ }
+
+ newSubStr = this.strategy.replace(value);
+
+ if ($.isArray(newSubStr)) {
+ post = newSubStr[1] + post;
+ newSubStr = newSubStr[0];
+ }
+
+ pre = pre.replace(this.strategy.match, newSubStr);
+
+ if (this.el.contentEditable == 'true') {
+ range.selectNodeContents(range.startContainer);
+ range.deleteContents();
+ var node = document.createTextNode(pre + post);
+ range.insertNode(node);
+ range.setStart(node, pre.length);
+ range.collapse(true);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ } else {
+ this.$el.val(pre + post);
+ this.el.selectionStart = this.el.selectionEnd = pre.length;
+ }
+
+ this.$el.trigger('change')
+ .trigger('textComplete:select', value);
+ this.el.focus();
+ },
+
+ /**
+ * Global click event handler.
+ */
+ onClickDocument: function (e) {
+ if (e.originalEvent && !e.originalEvent.keepTextCompleteDropdown) {
+ this.listView.deactivate();
+ }
+ },
+
+ /**
+ * Global keyup event handler.
+ */
+ onKeyupDocument: function (e) {
+ if (this.listView.shown && e.keyCode === 27) { // ESC
+ this.listView.deactivate();
+ this.$el.focus();
+ }
+ },
+
+ /**
+ * Remove all event handlers.
+ */
+ destroy: function () {
+ this.$el.off('.textComplete');
+ $(document).off('.' + this.id);
+ if (this.listView) { this.listView.destroy(); }
+ this.$el.data('textComplete', void 0);
+ this.$el = null;
+ },
+
+ // Helper methods
+ // ==============
+
+ getCaretPosition: function () {
+ var caretPosition, textareaOffset;
+ caretPosition = this.getCaretRelativePosition();
+ textareaOffset = this.$el.offset();
+ caretPosition.top += textareaOffset.top;
+ caretPosition.left += textareaOffset.left;
+ return caretPosition;
+ },
+
+ /**
+ * Returns caret's relative coordinates from textarea's left top corner.
+ */
+ getCaretRelativePosition: function () {
+ var properties, css, $div, $span, position, dir, scrollbar, range, node, $node;
+ if (this.el.contentEditable != 'true') {
+ // Browser native API does not provide the way to know the position of
+ // caret in pixels, so that here we use a kind of hack to accomplish
+ // the aim. First of all it puts a div element and completely copies
+ // the textarea's style to the element, then it inserts the text and a
+ // span element into the textarea.
+ // Consequently, the span element's position is the thing what we want.
+ properties = ['border-width', 'font-family', 'font-size', 'font-style',
+ 'font-variant', 'font-weight', 'height', 'letter-spacing',
+ 'word-spacing', 'line-height', 'text-decoration', 'text-align',
+ 'width', 'padding-top', 'padding-right', 'padding-bottom',
+ 'padding-left', 'margin-top', 'margin-right', 'margin-bottom',
+ 'margin-left', 'border-style', 'box-sizing'
+ ];
+ scrollbar = this.$el[0].scrollHeight > this.$el[0].offsetHeight;
+ css = $.extend({
+ position: 'absolute',
+ overflow: scrollbar ? 'scroll' : 'auto',
+ 'white-space': 'pre-wrap',
+ top: 0,
+ left: -9999,
+ direction: dir
+ }, getStyles(this.$el, properties));
+
+ $div = $('').css(css).text(this.getTextFromHeadToCaret());
+ $span = $('').text('.').appendTo($div);
+ this.$el.before($div);
+ position = $span.position();
+ position.top += $span.height() - this.$el.scrollTop();
+ $div.remove();
+ } else {
+ range = window.getSelection().getRangeAt(0).cloneRange();
+ node = document.createElement('span');
+ range.insertNode(node);
+ range.selectNodeContents(node);
+ range.deleteContents();
+ $node = $(node);
+ position = $node.offset();
+ position.top += $node.height() - this.$el.offset().top;
+ }
+ dir = this.$el.attr('dir') || this.$el.css('direction');
+ if (dir === 'rtl') { position.left -= this.listView.$el.width(); }
+ return position;
+ },
+
+ getTextFromHeadToCaret: function () {
+ var text, selectionEnd, range;
+ if (this.el.contentEditable == 'true') {
+ if (window.getSelection) {
+ // IE9+ and non-IE
+ var range = window.getSelection().getRangeAt(0);
+ var selection = range.cloneRange();
+ selection.selectNodeContents(range.startContainer);
+ text = selection.toString().substring(0, range.startOffset);
+ }
+ } else {
+ selectionEnd = this.el.selectionEnd;
+ if (typeof selectionEnd === 'number') {
+ text = this.el.value.substring(0, selectionEnd);
+ } else if (document.selection) {
+ range = this.el.createTextRange();
+ range.moveStart('character', 0);
+ range.moveEnd('textedit');
+ text = range.text;
+ }
+ }
+ return text;
+ },
+
+ /**
+ * Parse the value of textarea and extract search query.
+ */
+ extractSearchQuery: function (text) {
+ var i, l, strategy, match;
+ for (i = 0, l = this.strategies.length; i < l; i++) {
+ strategy = this.strategies[i];
+ match = text.match(strategy.match);
+ if (match) { return [strategy, match[strategy.index]]; }
+ }
+ return [];
+ },
+
+ search: lock(function (free, searchQuery) {
+ var term;
+ this.strategy = searchQuery[0];
+ term = searchQuery[1];
+ this.strategy.search(term, this.searchCallbackFactory(free));
+ })
+ });
+
+ return Completer;
+ })();
+
+ /**
+ * Dropdown menu manager class.
+ */
+ var ListView = (function () {
+
+ function ListView($el, completer) {
+ this.data = [];
+ this.$el = $el;
+ this.index = 0;
+ this.completer = completer;
+
+ this.$el.on('mousedown.textComplete', 'li.textcomplete-item',
+ $.proxy(this.onClick, this));
+ }
+
+ $.extend(ListView.prototype, {
+ shown: false,
+
+ render: function (data) {
+ var html, i, l, index, val, str;
+
+ html = '';
+
+ if(this.strategy.header) {
+ if ($.isFunction(this.strategy.header)) {
+ str = this.strategy.header(data);
+ } else {
+ str = this.strategy.header;
+ }
+ html += '';
+ }
+
+ for (i = 0, l = data.length; i < l; i++) {
+ val = data[i];
+ if (include(this.data, val)) continue;
+ index = this.data.length;
+ this.data.push(val);
+ html += '';
+ html += this.strategy.template(val);
+ html += '';
+ if (this.data.length === this.strategy.maxCount) break;
+ }
+
+ if(this.strategy.footer) {
+ if ($.isFunction(this.strategy.footer)) {
+ str = this.strategy.footer(data);
+ } else {
+ str = this.strategy.footer;
+ }
+ html += '';
+ }
+
+ this.$el.append(html);
+ if (!this.data.length) {
+ this.deactivate();
+ } else {
+ this.activateIndexedItem();
+ }
+ },
+
+ clear: function () {
+ this.data = [];
+ this.$el.html('');
+ this.index = 0;
+ return this;
+ },
+
+ activateIndexedItem: function () {
+ this.$el.find('.active').removeClass('active');
+ this.getActiveItem().addClass('active');
+ },
+
+ getActiveItem: function () {
+ return $(this.$el.children('.textcomplete-item').get(this.index));
+ },
+
+ activate: function () {
+ if (!this.shown) {
+ this.$el.show();
+ this.completer.$el.trigger('textComplete:show');
+ this.shown = true;
+ }
+ return this;
+ },
+
+ deactivate: function () {
+ if (this.shown) {
+ this.$el.hide();
+ this.completer.$el.trigger('textComplete:hide');
+ this.shown = false;
+ this.data = [];
+ this.index = null;
+ }
+ return this;
+ },
+
+ setPosition: function (position) {
+ var fontSize;
+ // If the strategy has the 'placement' option set to 'top', move the
+ // position above the element
+ if(this.strategy.placement === 'top') {
+ // Move it to be in line with the match character
+ fontSize = parseInt(this.$el.css('font-size'));
+ // Overwrite the position object to set the 'bottom' property instead of the top.
+ position = {
+ top: 'auto',
+ bottom: this.$el.parent().height() - position.top + fontSize,
+ left: position.left
+ };
+ } else {
+ // Overwrite 'bottom' property because once `placement: 'top'`
+ // strategy is shown, $el keeps the property.
+ position.bottom = 'auto';
+ }
+ this.$el.css(position);
+ return this;
+ },
+
+ select: function (index) {
+ var self = this;
+ this.completer.onSelect(this.data[index]);
+ // Deactive at next tick to allow other event handlers to know whether
+ // the dropdown has been shown or not.
+ setTimeout(function () { self.deactivate(); }, 0);
+ },
+
+ onKeydown: function (e) {
+ if (!this.shown) return;
+ if (e.keyCode === 38 || (e.ctrlKey && e.keyCode === 80)) { // UP, or Ctrl-P
+ e.preventDefault();
+ if (this.index === 0) {
+ this.index = this.data.length-1;
+ } else {
+ this.index -= 1;
+ }
+ this.activateIndexedItem();
+ } else if (e.keyCode === 40 || (e.ctrlKey && e.keyCode === 78)) { // DOWN, or Ctrl-N
+ e.preventDefault();
+ if (this.index === this.data.length - 1) {
+ this.index = 0;
+ } else {
+ this.index += 1;
+ }
+ this.activateIndexedItem();
+ } else if (e.keyCode === 13 || e.keyCode === 9) { // ENTER or TAB
+ e.preventDefault();
+ this.select(parseInt(this.getActiveItem().data('index'), 10));
+ }
+ },
+
+ onClick: function (e) {
+ var $e = $(e.target);
+ e.preventDefault();
+ e.originalEvent.keepTextCompleteDropdown = true;
+ if (!$e.hasClass('textcomplete-item')) {
+ $e = $e.parents('li.textcomplete-item');
+ }
+ this.select(parseInt($e.data('index'), 10));
+ },
+
+ destroy: function () {
+ this.deactivate();
+ this.$el.off('click.textComplete').remove();
+ this.$el = null;
+ }
+ });
+
+ return ListView;
+ })();
+
+ $.fn.textcomplete = function (strategies, option) {
+ var i, l, strategy, dataKey;
+
+ dataKey = 'textComplete';
+ option || (option = {});
+
+ if (strategies === 'destroy') {
+ return this.each(function () {
+ var completer = $(this).data(dataKey);
+ if (completer) { completer.destroy(); }
+ });
+ }
+
+ for (i = 0, l = strategies.length; i < l; i++) {
+ strategy = strategies[i];
+ if (!strategy.template) {
+ strategy.template = identity;
+ }
+ if (strategy.index == null) {
+ strategy.index = 2;
+ }
+ if (strategy.cache) {
+ strategy.search = memoize(strategy.search);
+ }
+ strategy.maxCount || (strategy.maxCount = 10);
+ }
+
+ return this.each(function () {
+ var $this, completer;
+ $this = $(this);
+ completer = $this.data(dataKey);
+ if (!completer) {
+ completer = new Completer($this, option);
+ $this.data(dataKey, completer);
+ }
+ completer.register(strategies);
+ });
+ };
+
+})(window.jQuery || window.Zepto);
diff --git a/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.min.js b/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.min.js
new file mode 100755
index 000000000..d7d138f35
--- /dev/null
+++ b/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.min.js
@@ -0,0 +1,4 @@
+/*! jquery-textcomplete - v0.2.1 - 2014-05-15 */!function(a){"use strict";var b=function(a){var b,d,e;return b=function(){d=!1},function(){var b=c(arguments);if(d)return e=b,void 0;d=!0;var f=this;b.unshift(function g(){if(e){var b=e;e=void 0,b.unshift(g),a.apply(f,b)}else d=!1}),a.apply(this,b)}},c=function(a){var b;return b=Array.prototype.slice.call(a)},d=function(){var b;return b=a("").css(["color"]).color,"undefined"!=typeof b?function(a,b){return a.css(b)}:function(b,c){var d;return d={},a.each(c,function(a,c){d[c]=b.css(c)}),d}}(),e=function(a){return a},f=function(a){var b={};return function(c,d){b[c]?d(b[c]):a.call(this,c,function(a){b[c]=(b[c]||[]).concat(a),d.apply(null,arguments)})}},g=function(a,b){var c,d;if(a.indexOf)return-1!=a.indexOf(b);for(c=0,d=a.length;d>c;c++)if(a[c]===b)return!0;return!1},h=function(){function c(b,c){var d;this.el=b.get(0),d=this.el===document.activeElement,this.$el=b,this.id="textComplete"+h++,this.strategies=[],this.option=c,d?(this.initialize(),this.$el.focus()):this.$el.one("focus.textComplete",a.proxy(this.initialize,this))}var e,f,g,h;return e={list:''},f={list:{position:"absolute",left:0,zIndex:"100",display:"none"}},g=a(e.list).css(f.list),h=0,a.extend(c.prototype,{initialize:function(){var b,c,d;b=g.clone(),this.listView=new i(b,this),this.$el.on({"keyup.textComplete":a.proxy(this.onKeyup,this),"keydown.textComplete":a.proxy(this.listView.onKeydown,this.listView)}),d=this.option.appendTo,d?b.appendTo(d instanceof a?d:a(d)):this.$el.before(b),c={},c["click."+this.id]=a.proxy(this.onClickDocument,this),c["keyup."+this.id]=a.proxy(this.onKeyupDocument,this),a(document).on(c)},register:function(a){this.strategies=this.strategies.concat(a)},renderList:function(a){this.clearAtNext&&(this.listView.clear(),this.clearAtNext=!1),a.length&&(this.listView.strategy=this.strategy,this.listView.shown||this.listView.setPosition(this.getCaretPosition()).clear().activate(),a=a.slice(0,this.strategy.maxCount),this.listView.render(a)),!this.listView.data.length&&this.listView.shown&&this.listView.deactivate()},searchCallbackFactory:function(a){var b=this;return function(c,d){b.renderList(c),d||(a(),b.clearAtNext=!0)}},onKeyup:function(a){var b,c;if(!this.skipSearch(a))if(b=this.extractSearchQuery(this.getTextFromHeadToCaret()),b.length){if(c=b[1],this.term===c)return;this.term=c,this.search(b)}else this.term=null,this.listView.deactivate()},skipSearch:function(a){switch(a.keyCode){case 40:case 38:return!0}if(a.ctrlKey)switch(a.keyCode){case 78:case 80:return!0}},onSelect:function(b){var c,d,e,f,g,h;if(c=this.getTextFromHeadToCaret(),"true"==this.el.contentEditable){f=window.getSelection(),g=f.getRangeAt(0),h=g.cloneRange(),h.selectNodeContents(g.startContainer);var i=h.toString();d=i.substring(g.startOffset)}else d=this.el.value.substring(this.el.selectionEnd);if(e=this.strategy.replace(b),a.isArray(e)&&(d=e[1]+d,e=e[0]),c=c.replace(this.strategy.match,e),"true"==this.el.contentEditable){g.selectNodeContents(g.startContainer),g.deleteContents();var j=document.createTextNode(c+d);g.insertNode(j),g.setStart(j,c.length),g.collapse(!0),f.removeAllRanges(),f.addRange(g)}else this.$el.val(c+d),this.el.selectionStart=this.el.selectionEnd=c.length;this.$el.trigger("change").trigger("textComplete:select",b),this.el.focus()},onClickDocument:function(a){a.originalEvent&&!a.originalEvent.keepTextCompleteDropdown&&this.listView.deactivate()},onKeyupDocument:function(a){this.listView.shown&&27===a.keyCode&&(this.listView.deactivate(),this.$el.focus())},destroy:function(){this.$el.off(".textComplete"),a(document).off("."+this.id),this.listView&&this.listView.destroy(),this.$el.data("textComplete",void 0),this.$el=null},getCaretPosition:function(){var a,b;return a=this.getCaretRelativePosition(),b=this.$el.offset(),a.top+=b.top,a.left+=b.left,a},getCaretRelativePosition:function(){var b,c,e,f,g,h,i,j,k;return"true"!=this.el.contentEditable?(b=["border-width","font-family","font-size","font-style","font-variant","font-weight","height","letter-spacing","word-spacing","line-height","text-decoration","text-align","width","padding-top","padding-right","padding-bottom","padding-left","margin-top","margin-right","margin-bottom","margin-left","border-style","box-sizing"],i=this.$el[0].scrollHeight>this.$el[0].offsetHeight,c=a.extend({position:"absolute",overflow:i?"scroll":"auto","white-space":"pre-wrap",top:0,left:-9999,direction:h},d(this.$el,b)),e=a("").css(c).text(this.getTextFromHeadToCaret()),f=a("").text(".").appendTo(e),this.$el.before(e),g=f.position(),g.top+=f.height()-this.$el.scrollTop(),e.remove()):(j=window.getSelection().getRangeAt(0).cloneRange(),k=document.createElement("span"),j.insertNode(k),j.selectNodeContents(k),j.deleteContents(),g=a(k).position(),g.top+=a(k).height()-this.$el.scrollTop()),h=this.$el.attr("dir")||this.$el.css("direction"),"rtl"===h&&(g.left-=this.listView.$el.width()),g},getTextFromHeadToCaret:function(){var a,b,c;if("true"==this.el.contentEditable){if(window.getSelection){var c=window.getSelection().getRangeAt(0),d=c.cloneRange();d.selectNodeContents(c.startContainer),a=d.toString().substring(0,c.startOffset)}}else b=this.el.selectionEnd,"number"==typeof b?a=this.el.value.substring(0,b):document.selection&&(c=this.el.createTextRange(),c.moveStart("character",0),c.moveEnd("textedit"),a=c.text);return a},extractSearchQuery:function(a){var b,c,d,e;for(b=0,c=this.strategies.length;c>b;b++)if(d=this.strategies[b],e=a.match(d.match))return[d,e[d.index]];return[]},search:b(function(a,b){var c;this.strategy=b[0],c=b[1],this.strategy.search(c,this.searchCallbackFactory(a))})}),c}(),i=function(){function b(b,c){this.data=[],this.$el=b,this.index=0,this.completer=c,this.$el.on("mousedown.textComplete","li.textcomplete-item",a.proxy(this.onClick,this))}return a.extend(b.prototype,{shown:!1,render:function(b){var c,d,e,f,h,i;for(c="",this.strategy.header&&(i=a.isFunction(this.strategy.header)?this.strategy.header(b):this.strategy.header,c+='"),d=0,e=b.length;e>d&&(h=b[d],g(this.data,h)||(f=this.data.length,this.data.push(h),c+='',c+=this.strategy.template(h),c+="",this.data.length!==this.strategy.maxCount));d++);this.strategy.footer&&(i=a.isFunction(this.strategy.footer)?this.strategy.footer(b):this.strategy.footer,c+='"),this.$el.append(c),this.data.length?this.activateIndexedItem():this.deactivate()},clear:function(){return this.data=[],this.$el.html(""),this.index=0,this},activateIndexedItem:function(){this.$el.find(".active").removeClass("active"),this.getActiveItem().addClass("active")},getActiveItem:function(){return a(this.$el.children(".textcomplete-item").get(this.index))},activate:function(){return this.shown||(this.$el.show(),this.completer.$el.trigger("textComplete:show"),this.shown=!0),this},deactivate:function(){return this.shown&&(this.$el.hide(),this.completer.$el.trigger("textComplete:hide"),this.shown=!1,this.data=[],this.index=null),this},setPosition:function(a){var b;return"top"===this.strategy.placement?(b=parseInt(this.$el.css("font-size")),a={top:"auto",bottom:this.$el.parent().height()-a.top+b,left:a.left}):a.bottom="auto",this.$el.css(a),this},select:function(a){var b=this;this.completer.onSelect(this.data[a]),setTimeout(function(){b.deactivate()},0)},onKeydown:function(a){this.shown&&(38===a.keyCode||a.ctrlKey&&80===a.keyCode?(a.preventDefault(),0===this.index?this.index=this.data.length-1:this.index-=1,this.activateIndexedItem()):40===a.keyCode||a.ctrlKey&&78===a.keyCode?(a.preventDefault(),this.index===this.data.length-1?this.index=0:this.index+=1,this.activateIndexedItem()):(13===a.keyCode||9===a.keyCode)&&(a.preventDefault(),this.select(parseInt(this.getActiveItem().data("index"),10))))},onClick:function(b){var c=a(b.target);b.preventDefault(),b.originalEvent.keepTextCompleteDropdown=!0,c.hasClass("textcomplete-item")||(c=c.parents("li.textcomplete-item")),this.select(parseInt(c.data("index"),10))},destroy:function(){this.deactivate(),this.$el.off("click.textComplete").remove(),this.$el=null}}),b}();a.fn.textcomplete=function(b,c){var d,g,i,j;if(j="textComplete",c||(c={}),"destroy"===b)return this.each(function(){var b=a(this).data(j);b&&b.destroy()});for(d=0,g=b.length;g>d;d++)i=b[d],i.template||(i.template=e),null==i.index&&(i.index=2),i.cache&&(i.search=f(i.search)),i.maxCount||(i.maxCount=10);return this.each(function(){var d,e;d=a(this),e=d.data(j),e||(e=new h(d,c),d.data(j,e)),e.register(b)})}}(window.jQuery||window.Zepto);
+/*
+//@ sourceMappingURL=jquery.textcomplete.min.map
+*/
\ No newline at end of file
diff --git a/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.min.map b/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.min.map
new file mode 100755
index 000000000..dcf8bb89b
--- /dev/null
+++ b/ajax/libs/jquery.textcomplete/0.2.1/jquery.textcomplete.min.map
@@ -0,0 +1 @@
+{"version":3,"file":"jquery.textcomplete.min.js","sources":["jquery.textcomplete.js"],"names":["$","lock","func","free","locked","queuedArgsToReplay","args","toArray","arguments","that","this","unshift","replayOrFree","replayArgs","undefined","apply","result","Array","prototype","slice","call","getStyles","color","css","$el","properties","styles","each","i","property","identity","obj","memoize","memo","term","callback","data","concat","include","array","value","l","indexOf","length","Completer","option","focus","el","get","document","activeElement","id","_id","strategies","initialize","one","proxy","html","$baseList","list","position","left","zIndex","display","extend","$list","globalEvents","appendTo","clone","listView","ListView","on","keyup.textComplete","onKeyup","keydown.textComplete","onKeydown","before","onClickDocument","onKeyupDocument","register","renderList","clearAtNext","clear","strategy","shown","setPosition","getCaretPosition","activate","maxCount","render","deactivate","searchCallbackFactory","self","keep","e","searchQuery","skipSearch","extractSearchQuery","getTextFromHeadToCaret","search","keyCode","ctrlKey","onSelect","pre","post","newSubStr","sel","range","selection","contentEditable","window","getSelection","getRangeAt","cloneRange","selectNodeContents","startContainer","content","toString","substring","startOffset","selectionEnd","replace","isArray","match","deleteContents","node","createTextNode","insertNode","setStart","collapse","removeAllRanges","addRange","val","selectionStart","trigger","originalEvent","keepTextCompleteDropdown","destroy","off","caretPosition","textareaOffset","getCaretRelativePosition","offset","top","$div","$span","dir","scrollbar","scrollHeight","offsetHeight","overflow","white-space","direction","text","height","scrollTop","remove","createElement","attr","width","createTextRange","moveStart","moveEnd","index","completer","onClick","str","header","isFunction","push","template","footer","append","activateIndexedItem","find","removeClass","getActiveItem","addClass","children","show","hide","fontSize","placement","parseInt","bottom","parent","select","setTimeout","preventDefault","$e","target","hasClass","parents","fn","textcomplete","dataKey","cache","$this","jQuery","Zepto"],"mappings":"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"}
\ No newline at end of file
diff --git a/ajax/libs/jquery.textcomplete/package.json b/ajax/libs/jquery.textcomplete/package.json
new file mode 100644
index 000000000..b5804c5a8
--- /dev/null
+++ b/ajax/libs/jquery.textcomplete/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "jquery.textcomplete",
+ "npmName": "jquery-textcomplete",
+ "npmFileMap": [
+ {
+ "basePath": "/",
+ "files": [
+ "jquery.*"
+ ]
+ }
+ ],
+ "filename": "jquery.textcomplete.min.js",
+ "version": "0.2.1",
+ "description": "Introduce autocompleting power to textareas, like GitHub comment forms have.",
+ "homepage": "http://yuku-t.com/jquery-textcomplete/",
+ "keywords": [
+ "jquery.textcomplete"
+ ],
+ "maintainers": [
+ {
+ "name": "Yuku Takahashi "
+ }
+ ],
+ "repositories": [
+ {
+ "type": "git",
+ "url": "https://github.com/yuku-t/jquery-textcomplete.git"
+ }
+ ]
+}