From 3c821981e4d7a8a8327d1ca26728bf9f6fa97f8a Mon Sep 17 00:00:00 2001 From: Abhinav Upadhyay Date: Mon, 23 Apr 2012 09:06:28 +0530 Subject: [PATCH] Implement support for autocompletion in the cgi frontend using jquery. Code is raw and needs further refactoring + cleaning! --- Makefile | 5 +- ac.css | 5 + ac.js | 5 + apropos-utils.c | 91 ++++++++-- apropos-utils.h | 1 + apropos_cgi.c | 135 +------------- cgi-utils.c | 162 +++++++++++++++++ cgi-utils.h | 38 ++++ jquery.autocomplete.js | 390 +++++++++++++++++++++++++++++++++++++++++ jquery.js | 19 ++ shadow.png | Bin 0 -> 3403 bytes suggest.cgi | Bin 0 -> 23708 bytes suggest_cgi.c | 56 ++++++ 13 files changed, 759 insertions(+), 148 deletions(-) create mode 100644 ac.css create mode 100644 ac.js create mode 100644 cgi-utils.c create mode 100644 cgi-utils.h create mode 100644 jquery.autocomplete.js create mode 100644 jquery.js create mode 100644 shadow.png create mode 100755 suggest.cgi create mode 100644 suggest_cgi.c diff --git a/Makefile b/Makefile index cd83ad3..3d97c83 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,12 @@ MDIST= ${NETBSDSRCDIR}/external/bsd/mdocml/dist MDOCDIR=${NETBSDSRCDIR}/external/bsd/mdocml -PROGS= makemandb apropos whatis apropos.cgi +PROGS= makemandb apropos whatis apropos.cgi suggest.cgi SRCS.makemandb= makemandb.c apropos-utils.c SRCS.apropos= apropos.c apropos-utils.c SRCS.whatis= whatis.c apropos-utils.c -SRCS.apropos.cgi= apropos_cgi.c apropos-utils.c +SRCS.apropos.cgi= apropos_cgi.c apropos-utils.c cgi-utils.c +SRCS.suggest.cgi= suggest_cgi.c cgi-utils.c apropos-utils.c MAN.makemandb= makemandb.8 MAN.apropos= apropos.1 MAN.whatis= whatis.1 diff --git a/ac.css b/ac.css new file mode 100644 index 0000000..7a2a7e3 --- /dev/null +++ b/ac.css @@ -0,0 +1,5 @@ +.autocomplete-w1 { background:url(/shadow.png) no-repeat bottom right; position:absolute; top:0px; left:0px; margin:6px 0 0 6px; /* IE6 fix: */ _background:none; _margin:1px 0 0 0; } +.autocomplete { border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE6 specific: */ _height:350px; _margin:0; _overflow-x:hidden; } +.autocomplete .selected { background:#F0F0F0; } +.autocomplete div { padding:2px 5px; white-space:nowrap; overflow:hidden; } +.autocomplete strong { font-weight:normal; color:#3399FF; } diff --git a/ac.js b/ac.js new file mode 100644 index 0000000..26b2ef8 --- /dev/null +++ b/ac.js @@ -0,0 +1,5 @@ +var options, a; +jQuery(function () { + options = { serviceUrl: '/cgi-bin/suggest.cgi' }; + a = $('#query').autocomplete(options); +}); diff --git a/apropos-utils.c b/apropos-utils.c index 1c9e6eb..872aaff 100644 --- a/apropos-utils.c +++ b/apropos-utils.c @@ -507,28 +507,17 @@ edits1 (char *word) return candidates; } -/* - * known_word-- - * Pass an array of strings to this function and it will return the word with - * maximum frequency in the dictionary. If no word in the array list is found - * in the dictionary, it returns NULL - * #TODO rename this function +/* Build termlist: a comma separated list of all the words in the list for + * use in the SQL query later. */ static char * -known_word(sqlite3 *db, char **list, int n) +build_termlist(char **list, int n) { - int i, rc; - char *sqlstr; char *termlist = NULL; - char *correct = NULL; - sqlite3_stmt *stmt; - - /* Build termlist: a comma separated list of all the words in the list for - * use in the SQL query later. - */ int total_len = BUFLEN * 20; /* total bytes allocated to termlist */ termlist = emalloc(total_len); int offset = 0; /* Next byte to write at in termlist */ + int i; termlist[0] = '('; offset++; @@ -538,12 +527,11 @@ known_word(sqlite3 *db, char **list, int n) termlist = erealloc(termlist, offset + total_len); total_len *= 2; } - memcpy(termlist + offset, "\'", 1); - offset++; + memcpy(termlist + offset++, "\'", 1); memcpy(termlist + offset, list[i], d); offset += d; - if (i == n -1) { + if (i == n - 1) { memcpy(termlist + offset, "\'", 1); offset++; } @@ -558,6 +546,25 @@ known_word(sqlite3 *db, char **list, int n) else concat2(&termlist, ")", 1); + return termlist; +} + +/* + * known_word-- + * Pass an array of strings to this function and it will return the word with + * maximum frequency in the dictionary. If no word in the array list is found + * in the dictionary, it returns NULL + * #TODO rename this function + */ +static char * +known_word(sqlite3 *db, char **list, int n) +{ + int i, rc; + char *sqlstr; + char *correct = NULL; + sqlite3_stmt *stmt; + char *termlist = build_termlist(list, n); + easprintf(&sqlstr, "SELECT word FROM mandb_dict WHERE " "frequency = (SELECT MAX(frequency) FROM mandb_dict " "WHERE word IN %s) AND word IN %s", termlist, termlist); @@ -643,6 +650,54 @@ spell(sqlite3 *db, char *word) return correct; } +char * +get_suggestions(sqlite3 *db, char *query) +{ + char *retval = NULL; + char *term; + char *temp; + char *sqlstr; + int count; + int rc; + sqlite3_stmt *stmt; + + if ((term = strrchr(query, ' ')) == NULL) { + term = query; + query = NULL; + } else { + *term++ = 0; + } + + char **list = edits1(term); + int n = strlen(term); + count = n + n -1 + 26 * n + 26 * (n + 1); + char *termlist = build_termlist(list, count); + easprintf(&sqlstr, "SELECT word FROM mandb_dict " + "WHERE word IN %s ORDER BY frequency DESC LIMIT 10", termlist); + rc = sqlite3_prepare_v2(db, sqlstr, -1, &stmt, NULL); + if (rc != SQLITE_OK) { + warnx("%s", sqlite3_errmsg(db)); + return NULL; + } + easprintf(&temp, "{\n{ query:\'%s%s%s\',\n " + "suggestions:[", query ? query : "", query ? " " : "", term); + concat(&retval, temp); + free(temp); + count = 0; + while (sqlite3_step(stmt) == SQLITE_ROW) { + if (count++) + concat(&retval, ","); + easprintf(&temp, "\'%s %s\'\n", query ? query : "",sqlite3_column_text(stmt, 0)); + concat(&retval, temp); + free(temp); + } + concat(&retval, "]\n}"); + sqlite3_finalize(stmt); + free(sqlstr); + free(termlist); + free_list(list, count); + return retval; +} /* * rank_func -- diff --git a/apropos-utils.h b/apropos-utils.h index ff369cf..a670ed0 100644 --- a/apropos-utils.h +++ b/apropos-utils.h @@ -91,4 +91,5 @@ int run_query_html(sqlite3 *, query_args *); int run_query_pager(sqlite3 *, query_args *); char *remove_stopwords(const char *); char *spell(sqlite3*, char *); +char *get_suggestions(sqlite3 *, char *); #endif diff --git a/apropos_cgi.c b/apropos_cgi.c index 7a50643..28ab19f 100644 --- a/apropos_cgi.c +++ b/apropos_cgi.c @@ -29,12 +29,12 @@ #include -#include #include #include #include #include "apropos-utils.h" +#include "cgi-utils.h" typedef struct callback_data { int count; @@ -51,6 +51,10 @@ print_form(char *query) printf("\n"); printf("\n"); printf(" NetBSD apropos \n"); + printf("\n"); + printf("\n"); + printf("\n"); + printf("\n"); printf("\n"); printf("\n"); printf("
\n"); @@ -59,7 +63,7 @@ print_form(char *query) printf("\n", "margin:10px;>\n"); printf("\n"); printf("\n"); - printf("\n", + printf("\n", query ? query : "" ); printf("\n"); printf("\n"); @@ -67,131 +71,6 @@ print_form(char *query) } -/* - * Replaces all the occurrences of '+' in the given string with a space - */ -static char * -parse_space(char *str) -{ - if (str == NULL) - return str; - - char *iter = str; - while ((iter = strchr(iter, '+')) != NULL) - *iter = ' '; - return str; -} - -static char * -parse_hex(char *str) -{ - char *percent_ptr; - char hexcode[2]; - char *retval; - retval = malloc(strlen(str) + 1); - int i = 2; - int decval = 0; - size_t offset = 0; - size_t sz; - while ((percent_ptr = strchr(str, '%')) != NULL) { - i = 2; - sz = 0; - sz = percent_ptr - str; - decval = 0; - memcpy(retval + offset, str, sz); - percent_ptr++; - offset += sz; - while (i > 0) { - switch (*percent_ptr) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - decval += (*percent_ptr - 48) * pow(16, --i); - break; - case 'A': - decval += 10 * pow(16, --i); - break; - case 'B': - decval += 11 * pow(16, --i); - break; - case 'C': - decval += 12 * pow(16, --i); - break; - case 'D': - decval += 13 * pow(16, --i); - break; - case 'E': - decval += 14 * pow(16, --i); - break; - case 'F': - decval += 15 * pow(16, --i); - break; - } - percent_ptr++; - } - str = percent_ptr; - retval[offset++] = decval; - } - sz = strlen(str); - memcpy(retval + offset, str, sz + 1); - return retval; -} - -/* - * Parse the given query string to extract the parameter pname - * and return to the caller. (Not the best way to do it but - * going for simplicity at the moment.) - */ -static char * -get_param(char *qstr, char *pname) -{ - if (qstr == NULL) - return NULL; - - char *temp; - char *param = NULL; - char *value = NULL; - size_t sz; - while (*qstr) { - sz = strcspn(qstr, "=&"); - if (qstr[sz] == '=') { - qstr[sz] = 0; - param = qstr; - } - qstr += sz + 1; - - if (param && strcmp(param, pname) == 0) - break; - else - param = NULL; - } - if (param == NULL) - return NULL; - - if ((temp = strchr(qstr, '&')) == NULL) - value = strdup(qstr); - else { - sz = temp - qstr; - value = malloc(sz + 1); - if (value == NULL) - errx(EXIT_FAILURE, "malloc failed"); - memcpy(value, qstr, sz); - value[sz] = 0; - } - value = parse_space(value); - char *retval = parse_hex(value); - free(value); - return retval; -} - - static int query_callback(void *data, const char *section, const char *name, const char *name_desc, const char *snippet, size_t snippet_length) @@ -274,7 +153,7 @@ main(int argc, char *argv[]) page = 1; else page = atoi(p); - print_form(query); + print_form(query); search(db, query, &cbdata, page); char *correct_query; diff --git a/cgi-utils.c b/cgi-utils.c new file mode 100644 index 0000000..895b4d1 --- /dev/null +++ b/cgi-utils.c @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2011 Abhinav Upadhyay + * All rights reserved. + * + * This code was developed as part of Google's Summer of Code 2011 program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* + * Replaces all the occurrences of '+' in the given string with a space + */ +char * +parse_space(char *str) +{ + if (str == NULL) + return str; + + char *iter = str; + while ((iter = strchr(iter, '+')) != NULL) + *iter = ' '; + return str; +} + +char * +parse_hex(char *str) +{ + char *percent_ptr; + char hexcode[2]; + char *retval; + retval = malloc(strlen(str) + 1); + int i = 2; + int decval = 0; + size_t offset = 0; + size_t sz; + while ((percent_ptr = strchr(str, '%')) != NULL) { + i = 2; + sz = 0; + sz = percent_ptr - str; + decval = 0; + memcpy(retval + offset, str, sz); + percent_ptr++; + offset += sz; + while (i > 0) { + switch (*percent_ptr) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + decval += (*percent_ptr - 48) * pow(16, --i); + break; + case 'A': + decval += 10 * pow(16, --i); + break; + case 'B': + decval += 11 * pow(16, --i); + break; + case 'C': + decval += 12 * pow(16, --i); + break; + case 'D': + decval += 13 * pow(16, --i); + break; + case 'E': + decval += 14 * pow(16, --i); + break; + case 'F': + decval += 15 * pow(16, --i); + break; + } + percent_ptr++; + } + str = percent_ptr; + retval[offset++] = decval; + } + sz = strlen(str); + memcpy(retval + offset, str, sz + 1); + return retval; +} + +/* + * Parse the given query string to extract the parameter pname + * and return to the caller. (Not the best way to do it but + * going for simplicity at the moment.) + */ +char * +get_param(char *qstr, const char *pname) +{ + if (qstr == NULL) + return NULL; + + char *temp; + char *param = NULL; + char *value = NULL; + size_t sz; + while (*qstr) { + sz = strcspn(qstr, "=&"); + if (qstr[sz] == '=') { + qstr[sz] = 0; + param = qstr; + } + qstr += sz + 1; + + if (param && strcmp(param, pname) == 0) + break; + else + param = NULL; + } + if (param == NULL) + return NULL; + + if ((temp = strchr(qstr, '&')) == NULL) + value = strdup(qstr); + else { + sz = temp - qstr; + value = malloc(sz + 1); + if (value == NULL) + errx(EXIT_FAILURE, "malloc failed"); + memcpy(value, qstr, sz); + value[sz] = 0; + } + value = parse_space(value); + char *retval = parse_hex(value); + free(value); + return retval; +} + + diff --git a/cgi-utils.h b/cgi-utils.h new file mode 100644 index 0000000..560f204 --- /dev/null +++ b/cgi-utils.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2011 Abhinav Upadhyay + * All rights reserved. + * + * This code was developed as part of Google's Summer of Code 2011 program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef CGI_UTILS_H +#define CGI_UTILS_H + +char *parse_space(char *); +char *parse_hex(char *); +char *get_param(char *, const char *); +#endif diff --git a/jquery.autocomplete.js b/jquery.autocomplete.js new file mode 100644 index 0000000..6a7ce87 --- /dev/null +++ b/jquery.autocomplete.js @@ -0,0 +1,390 @@ +/** +* Ajax Autocomplete for jQuery, version 1.1.3 +* (c) 2010 Tomas Kirda +* +* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license. +* For details, see the web site: http://www.devbridge.com/projects/autocomplete/jquery/ +* +* Last Review: 04/19/2010 +*/ + +/*jslint onevar: true, evil: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */ +/*global window: true, document: true, clearInterval: true, setInterval: true, jQuery: true */ + +(function($) { + + var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g'); + + function fnFormatResult(value, data, currentValue) { + var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')'; + return value.replace(new RegExp(pattern, 'gi'), '$1<\/strong>'); + } + + function Autocomplete(el, options) { + this.el = $(el); + this.el.attr('autocomplete', 'off'); + this.suggestions = []; + this.data = []; + this.badQueries = []; + this.selectedIndex = -1; + this.currentValue = this.el.val(); + this.intervalId = 0; + this.cachedResponse = []; + this.onChangeInterval = null; + this.ignoreValueChange = false; + this.serviceUrl = options.serviceUrl; + this.isLocal = false; + this.options = { + autoSubmit: false, + minChars: 1, + maxHeight: 300, + deferRequestBy: 0, + width: 0, + highlight: true, + params: {}, + fnFormatResult: fnFormatResult, + delimiter: null, + zIndex: 9999 + }; + this.initialize(); + this.setOptions(options); + } + + $.fn.autocomplete = function(options) { + return new Autocomplete(this.get(0)||$(''), options); + }; + + + Autocomplete.prototype = { + + killerFn: null, + + initialize: function() { + + var me, uid, autocompleteElId; + me = this; + uid = Math.floor(Math.random()*0x100000).toString(16); + autocompleteElId = 'Autocomplete_' + uid; + + this.killerFn = function(e) { + if ($(e.target).parents('.autocomplete').size() === 0) { + me.killSuggestions(); + me.disableKillerFn(); + } + }; + + if (!this.options.width) { this.options.width = this.el.width(); } + this.mainContainerId = 'AutocompleteContainter_' + uid; + + $('
').appendTo('body'); + + this.container = $('#' + autocompleteElId); + this.fixPosition(); + if (window.opera) { + this.el.keypress(function(e) { me.onKeyPress(e); }); + } else { + this.el.keydown(function(e) { me.onKeyPress(e); }); + } + this.el.keyup(function(e) { me.onKeyUp(e); }); + this.el.blur(function() { me.enableKillerFn(); }); + this.el.focus(function() { me.fixPosition(); }); + }, + + setOptions: function(options){ + var o = this.options; + $.extend(o, options); + if(o.lookup){ + this.isLocal = true; + if($.isArray(o.lookup)){ o.lookup = { suggestions:o.lookup, data:[] }; } + } + $('#'+this.mainContainerId).css({ zIndex:o.zIndex }); + this.container.css({ maxHeight: o.maxHeight + 'px', width:o.width }); + }, + + clearCache: function(){ + this.cachedResponse = []; + this.badQueries = []; + }, + + disable: function(){ + this.disabled = true; + }, + + enable: function(){ + this.disabled = false; + }, + + fixPosition: function() { + var offset = this.el.offset(); + $('#' + this.mainContainerId).css({ top: (offset.top + this.el.innerHeight()) + 'px', left: offset.left + 'px' }); + }, + + enableKillerFn: function() { + var me = this; + $(document).bind('click', me.killerFn); + }, + + disableKillerFn: function() { + var me = this; + $(document).unbind('click', me.killerFn); + }, + + killSuggestions: function() { + var me = this; + this.stopKillSuggestions(); + this.intervalId = window.setInterval(function() { me.hide(); me.stopKillSuggestions(); }, 300); + }, + + stopKillSuggestions: function() { + window.clearInterval(this.intervalId); + }, + + onKeyPress: function(e) { + if (this.disabled || !this.enabled) { return; } + // return will exit the function + // and event will not be prevented + switch (e.keyCode) { + case 27: //KEY_ESC: + this.el.val(this.currentValue); + this.hide(); + break; + case 9: //KEY_TAB: + case 13: //KEY_RETURN: + if (this.selectedIndex === -1) { + this.hide(); + return; + } + this.select(this.selectedIndex); + if(e.keyCode === 9){ return; } + break; + case 38: //KEY_UP: + this.moveUp(); + break; + case 40: //KEY_DOWN: + this.moveDown(); + break; + default: + return; + } + e.stopImmediatePropagation(); + e.preventDefault(); + }, + + onKeyUp: function(e) { + if(this.disabled){ return; } + switch (e.keyCode) { + case 38: //KEY_UP: + case 40: //KEY_DOWN: + return; + } + clearInterval(this.onChangeInterval); + if (this.currentValue !== this.el.val()) { + if (this.options.deferRequestBy > 0) { + // Defer lookup in case when value changes very quickly: + var me = this; + this.onChangeInterval = setInterval(function() { me.onValueChange(); }, this.options.deferRequestBy); + } else { + this.onValueChange(); + } + } + }, + + onValueChange: function() { + clearInterval(this.onChangeInterval); + this.currentValue = this.el.val(); + var q = this.getQuery(this.currentValue); + this.selectedIndex = -1; + if (this.ignoreValueChange) { + this.ignoreValueChange = false; + return; + } + if (q === '' || q.length < this.options.minChars) { + this.hide(); + } else { + this.getSuggestions(q); + } + }, + + getQuery: function(val) { + var d, arr; + d = this.options.delimiter; + if (!d) { return $.trim(val); } + arr = val.split(d); + return $.trim(arr[arr.length - 1]); + }, + + getSuggestionsLocal: function(q) { + var ret, arr, len, val, i; + arr = this.options.lookup; + len = arr.suggestions.length; + ret = { suggestions:[], data:[] }; + q = q.toLowerCase(); + for(i=0; i< len; i++){ + val = arr.suggestions[i]; + if(val.toLowerCase().indexOf(q) === 0){ + ret.suggestions.push(val); + ret.data.push(arr.data[i]); + } + } + return ret; + }, + + getSuggestions: function(q) { + var cr, me; + cr = this.isLocal ? this.getSuggestionsLocal(q) : this.cachedResponse[q]; + if (cr && $.isArray(cr.suggestions)) { + this.suggestions = cr.suggestions; + this.data = cr.data; + this.suggest(); + } else if (!this.isBadQuery(q)) { + me = this; + me.options.params.query = q; + $.get(this.serviceUrl, me.options.params, function(txt) { me.processResponse(txt); }, 'text'); + } + }, + + isBadQuery: function(q) { + var i = this.badQueries.length; + while (i--) { + if (q.indexOf(this.badQueries[i]) === 0) { return true; } + } + return false; + }, + + hide: function() { + this.enabled = false; + this.selectedIndex = -1; + this.container.hide(); + }, + + suggest: function() { + if (this.suggestions.length === 0) { + this.hide(); + return; + } + + var me, len, div, f, v, i, s, mOver, mClick; + me = this; + len = this.suggestions.length; + f = this.options.fnFormatResult; + v = this.getQuery(this.currentValue); + mOver = function(xi) { return function() { me.activate(xi); }; }; + mClick = function(xi) { return function() { me.select(xi); }; }; + this.container.hide().empty(); + for (i = 0; i < len; i++) { + s = this.suggestions[i]; + div = $((me.selectedIndex === i ? '
' + f(s, this.data[i], v) + '
'); + div.mouseover(mOver(i)); + div.click(mClick(i)); + this.container.append(div); + } + this.enabled = true; + this.container.show(); + }, + + processResponse: function(text) { + var response; + try { + response = eval('(' + text + ')'); + } catch (err) { return; } + if (!$.isArray(response.data)) { response.data = []; } + if(!this.options.noCache){ + this.cachedResponse[response.query] = response; + if (response.suggestions.length === 0) { this.badQueries.push(response.query); } + } + if (response.query === this.getQuery(this.currentValue)) { + this.suggestions = response.suggestions; + this.data = response.data; + this.suggest(); + } + }, + + activate: function(index) { + var divs, activeItem; + divs = this.container.children(); + // Clear previous selection: + if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) { + $(divs.get(this.selectedIndex)).removeClass(); + } + this.selectedIndex = index; + if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) { + activeItem = divs.get(this.selectedIndex); + $(activeItem).addClass('selected'); + } + return activeItem; + }, + + deactivate: function(div, index) { + div.className = ''; + if (this.selectedIndex === index) { this.selectedIndex = -1; } + }, + + select: function(i) { + var selectedValue, f; + selectedValue = this.suggestions[i]; + if (selectedValue) { + this.el.val(selectedValue); + if (this.options.autoSubmit) { + f = this.el.parents('form'); + if (f.length > 0) { f.get(0).submit(); } + } + this.ignoreValueChange = true; + this.hide(); + this.onSelect(i); + } + }, + + moveUp: function() { + if (this.selectedIndex === -1) { return; } + if (this.selectedIndex === 0) { + this.container.children().get(0).className = ''; + this.selectedIndex = -1; + this.el.val(this.currentValue); + return; + } + this.adjustScroll(this.selectedIndex - 1); + }, + + moveDown: function() { + if (this.selectedIndex === (this.suggestions.length - 1)) { return; } + this.adjustScroll(this.selectedIndex + 1); + }, + + adjustScroll: function(i) { + var activeItem, offsetTop, upperBound, lowerBound; + activeItem = this.activate(i); + offsetTop = activeItem.offsetTop; + upperBound = this.container.scrollTop(); + lowerBound = upperBound + this.options.maxHeight - 25; + if (offsetTop < upperBound) { + this.container.scrollTop(offsetTop); + } else if (offsetTop > lowerBound) { + this.container.scrollTop(offsetTop - this.options.maxHeight + 25); + } + this.el.val(this.getValue(this.suggestions[i])); + }, + + onSelect: function(i) { + var me, fn, s, d; + me = this; + fn = me.options.onSelect; + s = me.suggestions[i]; + d = me.data[i]; + me.el.val(me.getValue(s)); + if ($.isFunction(fn)) { fn(s, d, me.el); } + }, + + getValue: function(value){ + var del, currVal, arr, me; + me = this; + del = me.options.delimiter; + if (!del) { return value; } + currVal = me.currentValue; + arr = currVal.split(del); + if (arr.length === 1) { return value; } + return currVal.substr(0, currVal.length - arr[arr.length - 1].length) + value; + } + + }; + +}(jQuery)); diff --git a/jquery.js b/jquery.js new file mode 100644 index 0000000..b1ae21d --- /dev/null +++ b/jquery.js @@ -0,0 +1,19 @@ +/* + * jQuery JavaScript Library v1.3.2 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + * Revision: 6246 + */ +(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"
","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file diff --git a/shadow.png b/shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..a2561df971728d988424100c74c817916eca1979 GIT binary patch literal 3403 zcmeAS@N?(olHy`uVBq!ia0y~yV738bR}L1Sh{z?w93Z7#;u=xnT$Gwvl9`{U5R#dj z$`F!Ks$i<%mYSqsWME*TU}$J%1Vly(x&~$j21QvmX+Ul4C7!;n>{pmr1x4l8+mz-4 zg*Xd5B8wRqxP?HN@zUM8KR`j2bVpxD28NCO+HqZdXMAQjaPeGm)a##I4DP>8^|Q}*osX?x zu(w4E^8SQ>2<4nWJ;;$Ch1?$dLgm)?6;Yr9_CdHMW*W(@x+ip*R06EH_T4pml(Y0_%+Z_b^VZki z+Ig-L)GH{z-FHJSJv;l^O{dMW8|Geryoiy(edpWebG3Q>oX-o7q}^hCpz*y@X6IS? ZpGWQ1{0Pup3+%oyc)I$ztaD0e0swh%>OlYi literal 0 HcmV?d00001 diff --git a/suggest.cgi b/suggest.cgi new file mode 100755 index 0000000000000000000000000000000000000000..b35a9fef19469d9a2573b17ce87072c5ff116707 GIT binary patch literal 23708 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 G`Tqdp;r74) literal 0 HcmV?d00001 diff --git a/suggest_cgi.c b/suggest_cgi.c new file mode 100644 index 0000000..d3d2106 --- /dev/null +++ b/suggest_cgi.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2011 Abhinav Upadhyay + * All rights reserved. + * + * This code was developed as part of Google's Summer of Code 2011 program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "apropos-utils.h" +#include "cgi-utils.h" + +int +main(int argc, char **argv) +{ + char * qstr; + char *query; + sqlite3 *db; + if ((qstr = getenv("QUERY_STRING")) == NULL) + exit(EXIT_FAILURE); + if ((query = get_param(qstr, "query")) == NULL) + exit(EXIT_FAILURE); + + db = init_db(MANDB_READONLY); + printf("Content-type:application/json;\n"); + query = parse_space(query); + char *suggestions = get_suggestions(db, query); + printf("%s\n", suggestions); + free(suggestions); + return 0; +}