fix project dir setting
[emels.git] / emels / static / django_extensions / js / jquery.autocomplete.js
diff --git a/emels/static/django_extensions/js/jquery.autocomplete.js b/emels/static/django_extensions/js/jquery.autocomplete.js
deleted file mode 100644 (file)
index 77c1db6..0000000
+++ /dev/null
@@ -1,1152 +0,0 @@
-/**
- * @fileOverview jquery-autocomplete, the jQuery Autocompleter
- * @author <a href="mailto:dylan@dyve.net">Dylan Verheul</a>
- * @version 2.4.4
- * @requires jQuery 1.6+
- * @license MIT | GPL | Apache 2.0, see LICENSE.txt
- * @see https://github.com/dyve/jquery-autocomplete
- */
-(function($) {
-    "use strict";
-
-    /**
-     * jQuery autocomplete plugin
-     * @param {object|string} options
-     * @returns (object} jQuery object
-     */
-    $.fn.autocomplete = function(options) {
-        var url;
-        if (arguments.length > 1) {
-            url = options;
-            options = arguments[1];
-            options.url = url;
-        } else if (typeof options === 'string') {
-            url = options;
-            options = { url: url };
-        }
-        var opts = $.extend({}, $.fn.autocomplete.defaults, options);
-        return this.each(function() {
-            var $this = $(this);
-            $this.data('autocompleter', new $.Autocompleter(
-                $this,
-                $.meta ? $.extend({}, opts, $this.data()) : opts
-            ));
-        });
-    };
-
-    /**
-     * Store default options
-     * @type {object}
-     */
-    $.fn.autocomplete.defaults = {
-        inputClass: 'acInput',
-        loadingClass: 'acLoading',
-        resultsClass: 'acResults',
-        selectClass: 'acSelect',
-        queryParamName: 'q',
-        extraParams: {},
-        remoteDataType: false,
-        lineSeparator: '\n',
-        cellSeparator: '|',
-        minChars: 2,
-        maxItemsToShow: 10,
-        delay: 400,
-        useCache: true,
-        maxCacheLength: 10,
-        matchSubset: true,
-        matchCase: false,
-        matchInside: true,
-        mustMatch: false,
-        selectFirst: false,
-        selectOnly: false,
-        showResult: null,
-        preventDefaultReturn: 1,
-        preventDefaultTab: 0,
-        autoFill: false,
-        filterResults: true,
-        filter: true,
-        sortResults: true,
-        sortFunction: null,
-        onItemSelect: null,
-        onNoMatch: null,
-        onFinish: null,
-        matchStringConverter: null,
-        beforeUseConverter: null,
-        autoWidth: 'min-width',
-        useDelimiter: false,
-        delimiterChar: ',',
-        delimiterKeyCode: 188,
-        processData: null,
-        onError: null,
-        enabled: true
-    };
-
-    /**
-     * Sanitize result
-     * @param {Object} result
-     * @returns {Object} object with members value (String) and data (Object)
-     * @private
-     */
-    var sanitizeResult = function(result) {
-        var value, data;
-        var type = typeof result;
-        if (type === 'string') {
-            value = result;
-            data = {};
-        } else if ($.isArray(result)) {
-            value = result[0];
-            data = result.slice(1);
-        } else if (type === 'object') {
-            value = result.value;
-            data = result.data;
-        }
-        value = String(value);
-        if (typeof data !== 'object') {
-            data = {};
-        }
-        return {
-            value: value,
-            data: data
-        };
-    };
-
-    /**
-     * Sanitize integer
-     * @param {mixed} value
-     * @param {Object} options
-     * @returns {Number} integer
-     * @private
-     */
-    var sanitizeInteger = function(value, stdValue, options) {
-        var num = parseInt(value, 10);
-        options = options || {};
-        if (isNaN(num) || (options.min && num < options.min)) {
-            num = stdValue;
-        }
-        return num;
-    };
-
-    /**
-     * Create partial url for a name/value pair
-     */
-    var makeUrlParam = function(name, value) {
-        return [name, encodeURIComponent(value)].join('=');
-    };
-
-    /**
-     * Build an url
-     * @param {string} url Base url
-     * @param {object} [params] Dictionary of parameters
-     */
-    var makeUrl = function(url, params) {
-        var urlAppend = [];
-        $.each(params, function(index, value) {
-            urlAppend.push(makeUrlParam(index, value));
-        });
-        if (urlAppend.length) {
-            url += url.indexOf('?') === -1 ? '?' : '&';
-            url += urlAppend.join('&');
-        }
-        return url;
-    };
-
-    /**
-     * Default sort filter
-     * @param {object} a
-     * @param {object} b
-     * @param {boolean} matchCase
-     * @returns {number}
-     */
-    var sortValueAlpha = function(a, b, matchCase) {
-        a = String(a.value);
-        b = String(b.value);
-        if (!matchCase) {
-            a = a.toLowerCase();
-            b = b.toLowerCase();
-        }
-        if (a > b) {
-            return 1;
-        }
-        if (a < b) {
-            return -1;
-        }
-        return 0;
-    };
-
-    /**
-     * Parse data received in text format
-     * @param {string} text Plain text input
-     * @param {string} lineSeparator String that separates lines
-     * @param {string} cellSeparator String that separates cells
-     * @returns {array} Array of autocomplete data objects
-     */
-    var plainTextParser = function(text, lineSeparator, cellSeparator) {
-        var results = [];
-        var i, j, data, line, value, lines;
-        // Be nice, fix linebreaks before splitting on lineSeparator
-        lines = String(text).replace('\r\n', '\n').split(lineSeparator);
-        for (i = 0; i < lines.length; i++) {
-            line = lines[i].split(cellSeparator);
-            data = [];
-            for (j = 0; j < line.length; j++) {
-                data.push(decodeURIComponent(line[j]));
-            }
-            value = data.shift();
-            results.push({ value: value, data: data });
-        }
-        return results;
-    };
-
-    /**
-     * Autocompleter class
-     * @param {object} $elem jQuery object with one input tag
-     * @param {object} options Settings
-     * @constructor
-     */
-    $.Autocompleter = function($elem, options) {
-
-        /**
-         * Assert parameters
-         */
-        if (!$elem || !($elem instanceof $) || $elem.length !== 1 || $elem.get(0).tagName.toUpperCase() !== 'INPUT') {
-            throw new Error('Invalid parameter for jquery.Autocompleter, jQuery object with one element with INPUT tag expected.');
-        }
-
-        /**
-         * @constant Link to this instance
-         * @type object
-         * @private
-         */
-        var self = this;
-
-        /**
-         * @property {object} Options for this instance
-         * @public
-         */
-        this.options = options;
-
-        /**
-         * @property object Cached data for this instance
-         * @private
-         */
-        this.cacheData_ = {};
-
-        /**
-         * @property {number} Number of cached data items
-         * @private
-         */
-        this.cacheLength_ = 0;
-
-        /**
-         * @property {string} Class name to mark selected item
-         * @private
-         */
-        this.selectClass_ = 'jquery-autocomplete-selected-item';
-
-        /**
-         * @property {number} Handler to activation timeout
-         * @private
-         */
-        this.keyTimeout_ = null;
-
-        /**
-         * @property {number} Handler to finish timeout
-         * @private
-         */
-        this.finishTimeout_ = null;
-
-        /**
-         * @property {number} Last key pressed in the input field (store for behavior)
-         * @private
-         */
-        this.lastKeyPressed_ = null;
-
-        /**
-         * @property {string} Last value processed by the autocompleter
-         * @private
-         */
-        this.lastProcessedValue_ = null;
-
-        /**
-         * @property {string} Last value selected by the user
-         * @private
-         */
-        this.lastSelectedValue_ = null;
-
-        /**
-         * @property {boolean} Is this autocompleter active (showing results)?
-         * @see showResults
-         * @private
-         */
-        this.active_ = false;
-
-        /**
-         * @property {boolean} Is this autocompleter allowed to finish on blur?
-         * @private
-         */
-        this.finishOnBlur_ = true;
-
-        /**
-         * Sanitize options
-         */
-        this.options.minChars = sanitizeInteger(this.options.minChars, $.fn.autocomplete.defaults.minChars, { min: 0 });
-        this.options.maxItemsToShow = sanitizeInteger(this.options.maxItemsToShow, $.fn.autocomplete.defaults.maxItemsToShow, { min: 0 });
-        this.options.maxCacheLength = sanitizeInteger(this.options.maxCacheLength, $.fn.autocomplete.defaults.maxCacheLength, { min: 1 });
-        this.options.delay = sanitizeInteger(this.options.delay, $.fn.autocomplete.defaults.delay, { min: 0 });
-        if (this.options.preventDefaultReturn != 2) {
-            this.options.preventDefaultReturn = this.options.preventDefaultReturn ? 1 : 0;
-        }
-        if (this.options.preventDefaultTab != 2) {
-            this.options.preventDefaultTab = this.options.preventDefaultTab ? 1 : 0;
-        }
-
-        /**
-         * Init DOM elements repository
-         */
-        this.dom = {};
-
-        /**
-         * Store the input element we're attached to in the repository
-         */
-        this.dom.$elem = $elem;
-
-        /**
-         * Switch off the native autocomplete and add the input class
-         */
-        this.dom.$elem.attr('autocomplete', 'off').addClass(this.options.inputClass);
-
-        /**
-         * Create DOM element to hold results, and force absolute position
-         */
-        this.dom.$results = $('<div></div>').hide().addClass(this.options.resultsClass).css({
-            position: 'absolute'
-        });
-        $('body').append(this.dom.$results);
-
-        /**
-         * Attach keyboard monitoring to $elem
-         */
-        $elem.keydown(function(e) {
-            self.lastKeyPressed_ = e.keyCode;
-            switch(self.lastKeyPressed_) {
-
-                case self.options.delimiterKeyCode: // comma = 188
-                    if (self.options.useDelimiter && self.active_) {
-                        self.selectCurrent();
-                    }
-                    break;
-
-                // ignore navigational & special keys
-                case 35: // end
-                case 36: // home
-                case 16: // shift
-                case 17: // ctrl
-                case 18: // alt
-                case 37: // left
-                case 39: // right
-                    break;
-
-                case 38: // up
-                    e.preventDefault();
-                    if (self.active_) {
-                        self.focusPrev();
-                    } else {
-                        self.activate();
-                    }
-                    return false;
-
-                case 40: // down
-                    e.preventDefault();
-                    if (self.active_) {
-                        self.focusNext();
-                    } else {
-                        self.activate();
-                    }
-                    return false;
-
-                case 9: // tab
-                    if (self.active_) {
-                        self.selectCurrent();
-                        if (self.options.preventDefaultTab) {
-                            e.preventDefault();
-                            return false;
-                        }
-                    }
-                    if (self.options.preventDefaultTab === 2) {
-                        e.preventDefault();
-                        return false;
-                    }
-                break;
-
-                case 13: // return
-                    if (self.active_) {
-                        self.selectCurrent();
-                        if (self.options.preventDefaultReturn) {
-                            e.preventDefault();
-                            return false;
-                        }
-                    }
-                    if (self.options.preventDefaultReturn === 2) {
-                        e.preventDefault();
-                        return false;
-                    }
-                break;
-
-                case 27: // escape
-                    if (self.active_) {
-                        e.preventDefault();
-                        self.deactivate(true);
-                        return false;
-                    }
-                break;
-
-                default:
-                    self.activate();
-
-            }
-        });
-
-        /**
-         * Attach paste event listener because paste may occur much later then keydown or even without a keydown at all
-         */
-        $elem.on('paste', function() {
-            self.activate();
-        });
-
-        /**
-         * Finish on blur event
-         * Use a timeout because instant blur gives race conditions
-         */
-        var onBlurFunction = function() {
-            self.deactivate(true);
-        }
-        $elem.blur(function() {
-            if (self.finishOnBlur_) {
-                self.finishTimeout_ = setTimeout(onBlurFunction, 200);
-            }
-        });
-        /**
-         * Catch a race condition on form submit
-         */
-        $elem.parents('form').on('submit', onBlurFunction);
-
-    };
-
-    /**
-     * Position output DOM elements
-     * @private
-     */
-    $.Autocompleter.prototype.position = function() {
-        var offset = this.dom.$elem.offset();
-        var height = this.dom.$results.outerHeight();
-        var totalHeight = $(window).outerHeight();
-        var inputBottom = offset.top + this.dom.$elem.outerHeight();
-        var bottomIfDown = inputBottom + height;
-        // Set autocomplete results at the bottom of input
-        var position = {top: inputBottom, left: offset.left};
-        if (bottomIfDown > totalHeight) {
-            // Try to set autocomplete results at the top of input
-            var topIfUp = offset.top - height;
-            if (topIfUp >= 0) {
-                position.top = topIfUp;
-            }
-        }
-        this.dom.$results.css(position);
-    };
-
-    /**
-     * Read from cache
-     * @private
-     */
-    $.Autocompleter.prototype.cacheRead = function(filter) {
-        var filterLength, searchLength, search, maxPos, pos;
-        if (this.options.useCache) {
-            filter = String(filter);
-            filterLength = filter.length;
-            if (this.options.matchSubset) {
-                searchLength = 1;
-            } else {
-                searchLength = filterLength;
-            }
-            while (searchLength <= filterLength) {
-                if (this.options.matchInside) {
-                    maxPos = filterLength - searchLength;
-                } else {
-                    maxPos = 0;
-                }
-                pos = 0;
-                while (pos <= maxPos) {
-                    search = filter.substr(0, searchLength);
-                    if (this.cacheData_[search] !== undefined) {
-                        return this.cacheData_[search];
-                    }
-                    pos++;
-                }
-                searchLength++;
-            }
-        }
-        return false;
-    };
-
-    /**
-     * Write to cache
-     * @private
-     */
-    $.Autocompleter.prototype.cacheWrite = function(filter, data) {
-        if (this.options.useCache) {
-            if (this.cacheLength_ >= this.options.maxCacheLength) {
-                this.cacheFlush();
-            }
-            filter = String(filter);
-            if (this.cacheData_[filter] !== undefined) {
-                this.cacheLength_++;
-            }
-            this.cacheData_[filter] = data;
-            return this.cacheData_[filter];
-        }
-        return false;
-    };
-
-    /**
-     * Flush cache
-     * @public
-     */
-    $.Autocompleter.prototype.cacheFlush = function() {
-        this.cacheData_ = {};
-        this.cacheLength_ = 0;
-    };
-
-    /**
-     * Call hook
-     * Note that all called hooks are passed the autocompleter object
-     * @param {string} hook
-     * @param data
-     * @returns Result of called hook, false if hook is undefined
-     */
-    $.Autocompleter.prototype.callHook = function(hook, data) {
-        var f = this.options[hook];
-        if (f && $.isFunction(f)) {
-            return f(data, this);
-        }
-        return false;
-    };
-
-    /**
-     * Set timeout to activate autocompleter
-     */
-    $.Autocompleter.prototype.activate = function() {
-        if (!this.options.enabled) return;
-        var self = this;
-        if (this.keyTimeout_) {
-            clearTimeout(this.keyTimeout_);
-        }
-        this.keyTimeout_ = setTimeout(function() {
-            self.activateNow();
-        }, this.options.delay);
-    };
-
-    /**
-     * Activate autocompleter immediately
-     */
-    $.Autocompleter.prototype.activateNow = function() {
-        var value = this.beforeUseConverter(this.dom.$elem.val());
-        if (value !== this.lastProcessedValue_ && value !== this.lastSelectedValue_) {
-            this.fetchData(value);
-        }
-    };
-
-    /**
-     * Get autocomplete data for a given value
-     * @param {string} value Value to base autocompletion on
-     * @private
-     */
-    $.Autocompleter.prototype.fetchData = function(value) {
-        var self = this;
-        var processResults = function(results, filter) {
-            if (self.options.processData) {
-                results = self.options.processData(results);
-            }
-            self.showResults(self.filterResults(results, filter), filter);
-        };
-        this.lastProcessedValue_ = value;
-        if (value.length < this.options.minChars) {
-            processResults([], value);
-        } else if (this.options.data) {
-            processResults(this.options.data, value);
-        } else {
-            this.fetchRemoteData(value, function(remoteData) {
-                processResults(remoteData, value);
-            });
-        }
-    };
-
-    /**
-     * Get remote autocomplete data for a given value
-     * @param {string} filter The filter to base remote data on
-     * @param {function} callback The function to call after data retrieval
-     * @private
-     */
-    $.Autocompleter.prototype.fetchRemoteData = function(filter, callback) {
-        var data = this.cacheRead(filter);
-        if (data) {
-            callback(data);
-        } else {
-            var self = this;
-            var dataType = self.options.remoteDataType === 'json' ? 'json' : 'text';
-            var ajaxCallback = function(data) {
-                var parsed = false;
-                if (data !== false) {
-                    parsed = self.parseRemoteData(data);
-                    self.cacheWrite(filter, parsed);
-                }
-                self.dom.$elem.removeClass(self.options.loadingClass);
-                callback(parsed);
-            };
-            this.dom.$elem.addClass(this.options.loadingClass);
-            $.ajax({
-                url: this.makeUrl(filter),
-                success: ajaxCallback,
-                error: function(jqXHR, textStatus, errorThrown) {
-                    if($.isFunction(self.options.onError)) {
-                        self.options.onError(jqXHR, textStatus, errorThrown);
-                    } else {
-                      ajaxCallback(false);
-                    }
-                },
-                dataType: dataType
-            });
-        }
-    };
-
-    /**
-     * Create or update an extra parameter for the remote request
-     * @param {string} name Parameter name
-     * @param {string} value Parameter value
-     * @public
-     */
-    $.Autocompleter.prototype.setExtraParam = function(name, value) {
-        var index = $.trim(String(name));
-        if (index) {
-            if (!this.options.extraParams) {
-                this.options.extraParams = {};
-            }
-            if (this.options.extraParams[index] !== value) {
-                this.options.extraParams[index] = value;
-                this.cacheFlush();
-            }
-        }
-
-        return this;
-    };
-
-    /**
-     * Build the url for a remote request
-     * If options.queryParamName === false, append query to url instead of using a GET parameter
-     * @param {string} param The value parameter to pass to the backend
-     * @returns {string} The finished url with parameters
-     */
-    $.Autocompleter.prototype.makeUrl = function(param) {
-        var self = this;
-        var url = this.options.url;
-        var params = $.extend({}, this.options.extraParams);
-
-        if (this.options.queryParamName === false) {
-            url += encodeURIComponent(param);
-        } else {
-            params[this.options.queryParamName] = param;
-        }
-
-        return makeUrl(url, params);
-    };
-
-    /**
-     * Parse data received from server
-     * @param remoteData Data received from remote server
-     * @returns {array} Parsed data
-     */
-    $.Autocompleter.prototype.parseRemoteData = function(remoteData) {
-        var remoteDataType;
-        var data = remoteData;
-        if (this.options.remoteDataType === 'json') {
-            remoteDataType = typeof(remoteData);
-            switch (remoteDataType) {
-                case 'object':
-                    data = remoteData;
-                    break;
-                case 'string':
-                    data = $.parseJSON(remoteData);
-                    break;
-                default:
-                    throw new Error("Unexpected remote data type: " + remoteDataType);
-            }
-            return data;
-        }
-        return plainTextParser(data, this.options.lineSeparator, this.options.cellSeparator);
-    };
-
-    /**
-     * Default filter for results
-     * @param {Object} result
-     * @param {String} filter
-     * @returns {boolean} Include this result
-     * @private
-     */
-    $.Autocompleter.prototype.defaultFilter = function(result, filter) {
-        if (!result.value) {
-            return false;
-        }
-        if (this.options.filterResults) {
-            var pattern = this.matchStringConverter(filter);
-            var testValue = this.matchStringConverter(result.value);
-            if (!this.options.matchCase) {
-                pattern = pattern.toLowerCase();
-                testValue = testValue.toLowerCase();
-            }
-            var patternIndex = testValue.indexOf(pattern);
-            if (this.options.matchInside) {
-                return patternIndex > -1;
-            } else {
-                return patternIndex === 0;
-            }
-        }
-        return true;
-    };
-
-    /**
-     * Filter result
-     * @param {Object} result
-     * @param {String} filter
-     * @returns {boolean} Include this result
-     * @private
-     */
-    $.Autocompleter.prototype.filterResult = function(result, filter) {
-        // No filter
-        if (this.options.filter === false) {
-            return true;
-        }
-        // Custom filter
-        if ($.isFunction(this.options.filter)) {
-            return this.options.filter(result, filter);
-        }
-        // Default filter
-        return this.defaultFilter(result, filter);
-    };
-
-    /**
-     * Filter results
-     * @param results
-     * @param filter
-     */
-    $.Autocompleter.prototype.filterResults = function(results, filter) {
-        var filtered = [];
-        var i, result;
-
-        for (i = 0; i < results.length; i++) {
-            result = sanitizeResult(results[i]);
-            if (this.filterResult(result, filter)) {
-                filtered.push(result);
-            }
-        }
-        if (this.options.sortResults) {
-            filtered = this.sortResults(filtered, filter);
-        }
-        if (this.options.maxItemsToShow > 0 && this.options.maxItemsToShow < filtered.length) {
-            filtered.length = this.options.maxItemsToShow;
-        }
-        return filtered;
-    };
-
-    /**
-     * Sort results
-     * @param results
-     * @param filter
-     */
-    $.Autocompleter.prototype.sortResults = function(results, filter) {
-        var self = this;
-        var sortFunction = this.options.sortFunction;
-        if (!$.isFunction(sortFunction)) {
-            sortFunction = function(a, b, f) {
-                return sortValueAlpha(a, b, self.options.matchCase);
-            };
-        }
-        results.sort(function(a, b) {
-            return sortFunction(a, b, filter, self.options);
-        });
-        return results;
-    };
-
-    /**
-     * Convert string before matching
-     * @param s
-     * @param a
-     * @param b
-     */
-    $.Autocompleter.prototype.matchStringConverter = function(s, a, b) {
-        var converter = this.options.matchStringConverter;
-        if ($.isFunction(converter)) {
-            s = converter(s, a, b);
-        }
-        return s;
-    };
-
-    /**
-     * Convert string before use
-     * @param {String} s
-     */
-    $.Autocompleter.prototype.beforeUseConverter = function(s) {
-        s = this.getValue(s);
-        var converter = this.options.beforeUseConverter;
-        if ($.isFunction(converter)) {
-            s = converter(s);
-        }
-        return s;
-    };
-
-    /**
-     * Enable finish on blur event
-     */
-    $.Autocompleter.prototype.enableFinishOnBlur = function() {
-        this.finishOnBlur_ = true;
-    };
-
-    /**
-     * Disable finish on blur event
-     */
-    $.Autocompleter.prototype.disableFinishOnBlur = function() {
-        this.finishOnBlur_ = false;
-    };
-
-    /**
-     * Create a results item (LI element) from a result
-     * @param result
-     */
-    $.Autocompleter.prototype.createItemFromResult = function(result) {
-        var self = this;
-        var $li = $('<li/>');
-        $li.html(this.showResult(result.value, result.data));
-        $li.data({value: result.value, data: result.data})
-            .click(function() {
-                self.selectItem($li);
-            })
-            .mousedown(self.disableFinishOnBlur)
-            .mouseup(self.enableFinishOnBlur)
-        ;
-        return $li;
-    };
-
-    /**
-     * Get all items from the results list
-     * @param result
-     */
-    $.Autocompleter.prototype.getItems = function() {
-        return $('>ul>li', this.dom.$results);
-    };
-
-    /**
-     * Show all results
-     * @param results
-     * @param filter
-     */
-    $.Autocompleter.prototype.showResults = function(results, filter) {
-        var numResults = results.length;
-        var self = this;
-        var $ul = $('<ul></ul>');
-        var i, result, $li, autoWidth, first = false, $first = false;
-
-        if (numResults) {
-            for (i = 0; i < numResults; i++) {
-                result = results[i];
-                $li = this.createItemFromResult(result);
-                $ul.append($li);
-                if (first === false) {
-                    first = String(result.value);
-                    $first = $li;
-                    $li.addClass(this.options.firstItemClass);
-                }
-                if (i === numResults - 1) {
-                    $li.addClass(this.options.lastItemClass);
-                }
-            }
-
-            this.dom.$results.html($ul).show();
-
-            // Always recalculate position since window size or
-            // input element location may have changed.
-            this.position();
-            if (this.options.autoWidth) {
-                autoWidth = this.dom.$elem.outerWidth() - this.dom.$results.outerWidth() + this.dom.$results.width();
-                this.dom.$results.css(this.options.autoWidth, autoWidth);
-            }
-            this.getItems().hover(
-                function() { self.focusItem(this); },
-                function() { /* void */ }
-            );
-            if (this.autoFill(first, filter) || this.options.selectFirst || (this.options.selectOnly && numResults === 1)) {
-                this.focusItem($first);
-            }
-            this.active_ = true;
-        } else {
-            this.hideResults();
-            this.active_ = false;
-        }
-    };
-
-    $.Autocompleter.prototype.showResult = function(value, data) {
-        if ($.isFunction(this.options.showResult)) {
-            return this.options.showResult(value, data);
-        } else {
-            return $('<p></p>').text(value).html();
-        }
-    };
-
-    $.Autocompleter.prototype.autoFill = function(value, filter) {
-        var lcValue, lcFilter, valueLength, filterLength;
-        if (this.options.autoFill && this.lastKeyPressed_ !== 8) {
-            lcValue = String(value).toLowerCase();
-            lcFilter = String(filter).toLowerCase();
-            valueLength = value.length;
-            filterLength = filter.length;
-            if (lcValue.substr(0, filterLength) === lcFilter) {
-                var d = this.getDelimiterOffsets();
-                var pad = d.start ? ' ' : ''; // if there is a preceding delimiter
-                this.setValue( pad + value );
-                var start = filterLength + d.start + pad.length;
-                var end = valueLength + d.start + pad.length;
-                this.selectRange(start, end);
-                return true;
-            }
-        }
-        return false;
-    };
-
-    $.Autocompleter.prototype.focusNext = function() {
-        this.focusMove(+1);
-    };
-
-    $.Autocompleter.prototype.focusPrev = function() {
-        this.focusMove(-1);
-    };
-
-    $.Autocompleter.prototype.focusMove = function(modifier) {
-        var $items = this.getItems();
-        modifier = sanitizeInteger(modifier, 0);
-        if (modifier) {
-            for (var i = 0; i < $items.length; i++) {
-                if ($($items[i]).hasClass(this.selectClass_)) {
-                    this.focusItem(i + modifier);
-                    return;
-                }
-            }
-        }
-        this.focusItem(0);
-    };
-
-    $.Autocompleter.prototype.focusItem = function(item) {
-        var $item, $items = this.getItems();
-        if ($items.length) {
-            $items.removeClass(this.selectClass_).removeClass(this.options.selectClass);
-            if (typeof item === 'number') {
-                if (item < 0) {
-                    item = 0;
-                } else if (item >= $items.length) {
-                    item = $items.length - 1;
-                }
-                $item = $($items[item]);
-            } else {
-                $item = $(item);
-            }
-            if ($item) {
-                $item.addClass(this.selectClass_).addClass(this.options.selectClass);
-            }
-        }
-    };
-
-    $.Autocompleter.prototype.selectCurrent = function() {
-        var $item = $('li.' + this.selectClass_, this.dom.$results);
-        if ($item.length === 1) {
-            this.selectItem($item);
-        } else {
-            this.deactivate(false);
-        }
-    };
-
-    $.Autocompleter.prototype.selectItem = function($li) {
-        var value = $li.data('value');
-        var data = $li.data('data');
-        var displayValue = this.displayValue(value, data);
-        var processedDisplayValue = this.beforeUseConverter(displayValue);
-        this.lastProcessedValue_ = processedDisplayValue;
-        this.lastSelectedValue_ = processedDisplayValue;
-        var d = this.getDelimiterOffsets();
-        var delimiter = this.options.delimiterChar;
-        var elem = this.dom.$elem;
-        var extraCaretPos = 0;
-        if ( this.options.useDelimiter ) {
-            // if there is a preceding delimiter, add a space after the delimiter
-            if ( elem.val().substring(d.start-1, d.start) == delimiter && delimiter != ' ' ) {
-                displayValue = ' ' + displayValue;
-            }
-            // if there is not already a delimiter trailing this value, add it
-            if ( elem.val().substring(d.end, d.end+1) != delimiter && this.lastKeyPressed_ != this.options.delimiterKeyCode ) {
-                displayValue = displayValue + delimiter;
-            } else {
-                // move the cursor after the existing trailing delimiter
-                extraCaretPos = 1;
-            }
-        }
-        this.setValue(displayValue);
-        this.setCaret(d.start + displayValue.length + extraCaretPos);
-        this.callHook('onItemSelect', { value: value, data: data });
-        this.deactivate(true);
-        elem.focus();
-    };
-
-    $.Autocompleter.prototype.displayValue = function(value, data) {
-        if ($.isFunction(this.options.displayValue)) {
-            return this.options.displayValue(value, data);
-        }
-        return value;
-    };
-
-    $.Autocompleter.prototype.hideResults = function() {
-        this.dom.$results.hide();
-    };
-
-    $.Autocompleter.prototype.deactivate = function(finish) {
-        if (this.finishTimeout_) {
-            clearTimeout(this.finishTimeout_);
-        }
-        if (this.keyTimeout_) {
-            clearTimeout(this.keyTimeout_);
-        }
-        if (finish) {
-            if (this.lastProcessedValue_ !== this.lastSelectedValue_) {
-                if (this.options.mustMatch) {
-                    this.setValue('');
-                }
-                this.callHook('onNoMatch');
-            }
-            if (this.active_) {
-                this.callHook('onFinish');
-            }
-            this.lastKeyPressed_ = null;
-            this.lastProcessedValue_ = null;
-            this.lastSelectedValue_ = null;
-            this.active_ = false;
-        }
-        this.hideResults();
-    };
-
-    $.Autocompleter.prototype.selectRange = function(start, end) {
-        var input = this.dom.$elem.get(0);
-        if (input.setSelectionRange) {
-            input.focus();
-            input.setSelectionRange(start, end);
-        } else if (input.createTextRange) {
-            var range = input.createTextRange();
-            range.collapse(true);
-            range.moveEnd('character', end);
-            range.moveStart('character', start);
-            range.select();
-        }
-    };
-
-    /**
-     * Move caret to position
-     * @param {Number} pos
-     */
-    $.Autocompleter.prototype.setCaret = function(pos) {
-        this.selectRange(pos, pos);
-    };
-
-    /**
-     * Get caret position
-     */
-    $.Autocompleter.prototype.getCaret = function() {
-        var $elem = this.dom.$elem;
-        var elem = $elem[0];
-        var val, selection, range, start, end, stored_range;
-        if (elem.createTextRange) { // IE
-            selection = document.selection;
-            if (elem.tagName.toLowerCase() != 'textarea') {
-                val = $elem.val();
-                range = selection.createRange().duplicate();
-                range.moveEnd('character', val.length);
-                if (range.text === '') {
-                    start = val.length;
-                } else {
-                    start = val.lastIndexOf(range.text);
-                }
-                range = selection.createRange().duplicate();
-                range.moveStart('character', -val.length);
-                end = range.text.length;
-            } else {
-                range = selection.createRange();
-                stored_range = range.duplicate();
-                stored_range.moveToElementText(elem);
-                stored_range.setEndPoint('EndToEnd', range);
-                start = stored_range.text.length - range.text.length;
-                end = start + range.text.length;
-            }
-        } else {
-            start = $elem[0].selectionStart;
-            end = $elem[0].selectionEnd;
-        }
-        return {
-            start: start,
-            end: end
-        };
-    };
-
-    /**
-     * Set the value that is currently being autocompleted
-     * @param {String} value
-     */
-    $.Autocompleter.prototype.setValue = function(value) {
-        if ( this.options.useDelimiter ) {
-            // set the substring between the current delimiters
-            var val = this.dom.$elem.val();
-            var d = this.getDelimiterOffsets();
-            var preVal = val.substring(0, d.start);
-            var postVal = val.substring(d.end);
-            value = preVal + value + postVal;
-        }
-        this.dom.$elem.val(value);
-    };
-
-    /**
-     * Get the value currently being autocompleted
-     * @param {String} value
-     */
-    $.Autocompleter.prototype.getValue = function(value) {
-        if ( this.options.useDelimiter ) {
-            var d = this.getDelimiterOffsets();
-            return value.substring(d.start, d.end).trim();
-        } else {
-            return value;
-        }
-    };
-
-    /**
-     * Get the offsets of the value currently being autocompleted
-     */
-    $.Autocompleter.prototype.getDelimiterOffsets = function() {
-        var val = this.dom.$elem.val();
-        if ( this.options.useDelimiter ) {
-            var preCaretVal = val.substring(0, this.getCaret().start);
-            var start = preCaretVal.lastIndexOf(this.options.delimiterChar) + 1;
-            var postCaretVal = val.substring(this.getCaret().start);
-            var end = postCaretVal.indexOf(this.options.delimiterChar);
-            if ( end == -1 ) end = val.length;
-            end += this.getCaret().start;
-        } else {
-            start = 0;
-            end = val.length;
-        }
-        return {
-            start: start,
-            end: end
-        };
-    };
-
-})((typeof window.jQuery == 'undefined' && typeof window.django != 'undefined')? django.jQuery : jQuery);