if (!this.JSON) {
    JSON = {};
}
(function () {

    function f(n) {
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z';
        };

        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(string) {


        escapable.lastIndex = 0;
        return escapable.test(string) ?
            '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c :
                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' :
            '"' + string + '"';
    }


    function str(key, holder) {


        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];


        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }


        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }


        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':


            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':


            return String(value);


        case 'object':


            if (!value) {
                return 'null';
            }


            gap += indent;
            partial = [];


            if (Object.prototype.toString.apply(value) === '[object Array]') {


                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }


                v = partial.length === 0 ? '[]' :
                    gap ? '[\n' + gap +
                            partial.join(',\n' + gap) + '\n' +
                                mind + ']' :
                          '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }


            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    k = rep[i];
                    if (typeof k === 'string') {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {


                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }


            v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                        mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }


    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {


            var i;
            gap = '';
            indent = '';


            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }


            } else if (typeof space === 'string') {
                indent = space;
            }


            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                     typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }


            return str('', {'': value});
        };
    }



    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {


            var j;

            function walk(holder, key) {


                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }



            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }



            if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {


                j = eval('(' + text + ')');


                return typeof reviver === 'function' ?
                    walk({'': j}, '') : j;
            }


            throw new SyntaxError('JSON.parse');
        };
    }
}());
/*!
 * jQuery JavaScript Library v1.4.2
 * http://jquery.com/
 *
 * Copyright 2010, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 * Copyright 2010, The Dojo Foundation
 * Released under the MIT, BSD, and GPL Licenses.
 *
 * Date: Sat Feb 13 22:33:48 2010 -0500
 */
(function( window, undefined ) {

var jQuery = function( selector, context ) {
		return new jQuery.fn.init( selector, context );
	},

	_jQuery = window.jQuery,

	_$ = window.$,

	document = window.document,

	rootjQuery,

	quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,

	isSimple = /^.[^:#\[\.,]*$/,

	rnotwhite = /\S/,

	rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,

	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,

	userAgent = navigator.userAgent,

	browserMatch,

	readyBound = false,

	readyList = [],

	DOMContentLoaded,

	toString = Object.prototype.toString,
	hasOwnProperty = Object.prototype.hasOwnProperty,
	push = Array.prototype.push,
	slice = Array.prototype.slice,
	indexOf = Array.prototype.indexOf;

jQuery.fn = jQuery.prototype = {
	init: function( selector, context ) {
		var match, elem, ret, doc;

		if ( !selector ) {
			return this;
		}

		if ( selector.nodeType ) {
			this.context = this[0] = selector;
			this.length = 1;
			return this;
		}

		if ( selector === "body" && !context ) {
			this.context = document;
			this[0] = document.body;
			this.selector = "body";
			this.length = 1;
			return this;
		}

		if ( typeof selector === "string" ) {
			match = quickExpr.exec( selector );

			if ( match && (match[1] || !context) ) {

				if ( match[1] ) {
					doc = (context ? context.ownerDocument || context : document);

					ret = rsingleTag.exec( selector );

					if ( ret ) {
						if ( jQuery.isPlainObject( context ) ) {
							selector = [ document.createElement( ret[1] ) ];
							jQuery.fn.attr.call( selector, context, true );

						} else {
							selector = [ doc.createElement( ret[1] ) ];
						}

					} else {
						ret = buildFragment( [ match[1] ], [ doc ] );
						selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
					}

					return jQuery.merge( this, selector );

				} else {
					elem = document.getElementById( match[2] );

					if ( elem ) {
						if ( elem.id !== match[2] ) {
							return rootjQuery.find( selector );
						}

						this.length = 1;
						this[0] = elem;
					}

					this.context = document;
					this.selector = selector;
					return this;
				}

			} else if ( !context && /^\w+$/.test( selector ) ) {
				this.selector = selector;
				this.context = document;
				selector = document.getElementsByTagName( selector );
				return jQuery.merge( this, selector );

			} else if ( !context || context.jquery ) {
				return (context || rootjQuery).find( selector );

			} else {
				return jQuery( context ).find( selector );
			}

		} else if ( jQuery.isFunction( selector ) ) {
			return rootjQuery.ready( selector );
		}

		if (selector.selector !== undefined) {
			this.selector = selector.selector;
			this.context = selector.context;
		}

		return jQuery.makeArray( selector, this );
	},

	selector: "",

	jquery: "1.4.2",

	length: 0,

	size: function() {
		return this.length;
	},

	toArray: function() {
		return slice.call( this, 0 );
	},

	get: function( num ) {
		return num == null ?

			this.toArray() :

			( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
	},

	pushStack: function( elems, name, selector ) {
		var ret = jQuery();

		if ( jQuery.isArray( elems ) ) {
			push.apply( ret, elems );

		} else {
			jQuery.merge( ret, elems );
		}

		ret.prevObject = this;

		ret.context = this.context;

		if ( name === "find" ) {
			ret.selector = this.selector + (this.selector ? " " : "") + selector;
		} else if ( name ) {
			ret.selector = this.selector + "." + name + "(" + selector + ")";
		}

		return ret;
	},

	each: function( callback, args ) {
		return jQuery.each( this, callback, args );
	},

	ready: function( fn ) {
		jQuery.bindReady();

		if ( jQuery.isReady ) {
			fn.call( document, jQuery );

		} else if ( readyList ) {
			readyList.push( fn );
		}

		return this;
	},

	eq: function( i ) {
		return i === -1 ?
			this.slice( i ) :
			this.slice( i, +i + 1 );
	},

	first: function() {
		return this.eq( 0 );
	},

	last: function() {
		return this.eq( -1 );
	},

	slice: function() {
		return this.pushStack( slice.apply( this, arguments ),
			"slice", slice.call(arguments).join(",") );
	},

	map: function( callback ) {
		return this.pushStack( jQuery.map(this, function( elem, i ) {
			return callback.call( elem, i, elem );
		}));
	},

	end: function() {
		return this.prevObject || jQuery(null);
	},

	push: push,
	sort: [].sort,
	splice: [].splice
};

jQuery.fn.init.prototype = jQuery.fn;

jQuery.extend = jQuery.fn.extend = function() {
	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;

	if ( typeof target === "boolean" ) {
		deep = target;
		target = arguments[1] || {};
		i = 2;
	}

	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
		target = {};
	}

	if ( length === i ) {
		target = this;
		--i;
	}

	for ( ; i < length; i++ ) {
		if ( (options = arguments[ i ]) != null ) {
			for ( name in options ) {
				src = target[ name ];
				copy = options[ name ];

				if ( target === copy ) {
					continue;
				}

				if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
					var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
						: jQuery.isArray(copy) ? [] : {};

					target[ name ] = jQuery.extend( deep, clone, copy );

				} else if ( copy !== undefined ) {
					target[ name ] = copy;
				}
			}
		}
	}

	return target;
};

jQuery.extend({
	noConflict: function( deep ) {
		window.$ = _$;

		if ( deep ) {
			window.jQuery = _jQuery;
		}

		return jQuery;
	},

	isReady: false,

	ready: function() {
		if ( !jQuery.isReady ) {
			if ( !document.body ) {
				return setTimeout( jQuery.ready, 13 );
			}

			jQuery.isReady = true;

			if ( readyList ) {
				var fn, i = 0;
				while ( (fn = readyList[ i++ ]) ) {
					fn.call( document, jQuery );
				}

				readyList = null;
			}

			if ( jQuery.fn.triggerHandler ) {
				jQuery( document ).triggerHandler( "ready" );
			}
		}
	},

	bindReady: function() {
		if ( readyBound ) {
			return;
		}

		readyBound = true;

		if ( document.readyState === "complete" ) {
			return jQuery.ready();
		}

		if ( document.addEventListener ) {
			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

			window.addEventListener( "load", jQuery.ready, false );

		} else if ( document.attachEvent ) {
			document.attachEvent("onreadystatechange", DOMContentLoaded);

			window.attachEvent( "onload", jQuery.ready );

			var toplevel = false;

			try {
				toplevel = window.frameElement == null;
			} catch(e) {}

			if ( document.documentElement.doScroll && toplevel ) {
				doScrollCheck();
			}
		}
	},

	isFunction: function( obj ) {
		return toString.call(obj) === "[object Function]";
	},

	isArray: function( obj ) {
		return toString.call(obj) === "[object Array]";
	},

	isPlainObject: function( obj ) {
		if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
			return false;
		}

		if ( obj.constructor
			&& !hasOwnProperty.call(obj, "constructor")
			&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
			return false;
		}


		var key;
		for ( key in obj ) {}

		return key === undefined || hasOwnProperty.call( obj, key );
	},

	isEmptyObject: function( obj ) {
		for ( var name in obj ) {
			return false;
		}
		return true;
	},

	error: function( msg ) {
		throw msg;
	},

	parseJSON: function( data ) {
		if ( typeof data !== "string" || !data ) {
			return null;
		}

		data = jQuery.trim( data );

		if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
			.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
			.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {

			return window.JSON && window.JSON.parse ?
				window.JSON.parse( data ) :
				(new Function("return " + data))();

		} else {
			jQuery.error( "Invalid JSON: " + data );
		}
	},

	noop: function() {},

	globalEval: function( data ) {
		if ( data && rnotwhite.test(data) ) {
			var head = document.getElementsByTagName("head")[0] || document.documentElement,
				script = document.createElement("script");

			script.type = "text/javascript";

			if ( jQuery.support.scriptEval ) {
				script.appendChild( document.createTextNode( data ) );
			} else {
				script.text = data;
			}

			head.insertBefore( script, head.firstChild );
			head.removeChild( script );
		}
	},

	nodeName: function( elem, name ) {
		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
	},

	each: function( object, callback, args ) {
		var name, i = 0,
			length = object.length,
			isObj = length === undefined || jQuery.isFunction(object);

		if ( args ) {
			if ( isObj ) {
				for ( name in object ) {
					if ( callback.apply( object[ name ], args ) === false ) {
						break;
					}
				}
			} else {
				for ( ; i < length; ) {
					if ( callback.apply( object[ i++ ], args ) === false ) {
						break;
					}
				}
			}

		} else {
			if ( isObj ) {
				for ( name in object ) {
					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
						break;
					}
				}
			} else {
				for ( var value = object[0];
					i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
			}
		}

		return object;
	},

	trim: function( text ) {
		return (text || "").replace( rtrim, "" );
	},

	makeArray: function( array, results ) {
		var ret = results || [];

		if ( array != null ) {
			if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
				push.call( ret, array );
			} else {
				jQuery.merge( ret, array );
			}
		}

		return ret;
	},

	inArray: function( elem, array ) {
		if ( array.indexOf ) {
			return array.indexOf( elem );
		}

		for ( var i = 0, length = array.length; i < length; i++ ) {
			if ( array[ i ] === elem ) {
				return i;
			}
		}

		return -1;
	},

	merge: function( first, second ) {
		var i = first.length, j = 0;

		if ( typeof second.length === "number" ) {
			for ( var l = second.length; j < l; j++ ) {
				first[ i++ ] = second[ j ];
			}

		} else {
			while ( second[j] !== undefined ) {
				first[ i++ ] = second[ j++ ];
			}
		}

		first.length = i;

		return first;
	},

	grep: function( elems, callback, inv ) {
		var ret = [];

		for ( var i = 0, length = elems.length; i < length; i++ ) {
			if ( !inv !== !callback( elems[ i ], i ) ) {
				ret.push( elems[ i ] );
			}
		}

		return ret;
	},

	map: function( elems, callback, arg ) {
		var ret = [], value;

		for ( var i = 0, length = elems.length; i < length; i++ ) {
			value = callback( elems[ i ], i, arg );

			if ( value != null ) {
				ret[ ret.length ] = value;
			}
		}

		return ret.concat.apply( [], ret );
	},

	guid: 1,

	proxy: function( fn, proxy, thisObject ) {
		if ( arguments.length === 2 ) {
			if ( typeof proxy === "string" ) {
				thisObject = fn;
				fn = thisObject[ proxy ];
				proxy = undefined;

			} else if ( proxy && !jQuery.isFunction( proxy ) ) {
				thisObject = proxy;
				proxy = undefined;
			}
		}

		if ( !proxy && fn ) {
			proxy = function() {
				return fn.apply( thisObject || this, arguments );
			};
		}

		if ( fn ) {
			proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
		}

		return proxy;
	},

	uaMatch: function( ua ) {
		ua = ua.toLowerCase();

		var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
			/(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
			/(msie) ([\w.]+)/.exec( ua ) ||
			!/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
		  	[];

		return { browser: match[1] || "", version: match[2] || "0" };
	},

	browser: {}
});

browserMatch = jQuery.uaMatch( userAgent );
if ( browserMatch.browser ) {
	jQuery.browser[ browserMatch.browser ] = true;
	jQuery.browser.version = browserMatch.version;
}

if ( jQuery.browser.webkit ) {
	jQuery.browser.safari = true;
}

if ( indexOf ) {
	jQuery.inArray = function( elem, array ) {
		return indexOf.call( array, elem );
	};
}

rootjQuery = jQuery(document);

if ( document.addEventListener ) {
	DOMContentLoaded = function() {
		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
		jQuery.ready();
	};

} else if ( document.attachEvent ) {
	DOMContentLoaded = function() {
		if ( document.readyState === "complete" ) {
			document.detachEvent( "onreadystatechange", DOMContentLoaded );
			jQuery.ready();
		}
	};
}

function doScrollCheck() {
	if ( jQuery.isReady ) {
		return;
	}

	try {
		document.documentElement.doScroll("left");
	} catch( error ) {
		setTimeout( doScrollCheck, 1 );
		return;
	}

	jQuery.ready();
}

function evalScript( i, elem ) {
	if ( elem.src ) {
		jQuery.ajax({
			url: elem.src,
			async: false,
			dataType: "script"
		});
	} else {
		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
	}

	if ( elem.parentNode ) {
		elem.parentNode.removeChild( elem );
	}
}

function access( elems, key, value, exec, fn, pass ) {
	var length = elems.length;

	if ( typeof key === "object" ) {
		for ( var k in key ) {
			access( elems, k, key[k], exec, fn, value );
		}
		return elems;
	}

	if ( value !== undefined ) {
		exec = !pass && exec && jQuery.isFunction(value);

		for ( var i = 0; i < length; i++ ) {
			fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
		}

		return elems;
	}

	return length ? fn( elems[0], key ) : undefined;
}

function now() {
	return (new Date).getTime();
}
(function() {

	jQuery.support = {};

	var root = document.documentElement,
		script = document.createElement("script"),
		div = document.createElement("div"),
		id = "script" + now();

	div.style.display = "none";
	div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";

	var all = div.getElementsByTagName("*"),
		a = div.getElementsByTagName("a")[0];

	if ( !all || !all.length || !a ) {
		return;
	}

	jQuery.support = {
		leadingWhitespace: div.firstChild.nodeType === 3,

		tbody: !div.getElementsByTagName("tbody").length,

		htmlSerialize: !!div.getElementsByTagName("link").length,

		style: /red/.test( a.getAttribute("style") ),

		hrefNormalized: a.getAttribute("href") === "/a",

		opacity: /^0.55$/.test( a.style.opacity ),

		cssFloat: !!a.style.cssFloat,

		checkOn: div.getElementsByTagName("input")[0].value === "on",

		optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,

		parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,

		deleteExpando: true,
		checkClone: false,
		scriptEval: false,
		noCloneEvent: true,
		boxModel: null
	};

	script.type = "text/javascript";
	try {
		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
	} catch(e) {}

	root.insertBefore( script, root.firstChild );

	if ( window[ id ] ) {
		jQuery.support.scriptEval = true;
		delete window[ id ];
	}

	try {
		delete script.test;

	} catch(e) {
		jQuery.support.deleteExpando = false;
	}

	root.removeChild( script );

	if ( div.attachEvent && div.fireEvent ) {
		div.attachEvent("onclick", function click() {
			jQuery.support.noCloneEvent = false;
			div.detachEvent("onclick", click);
		});
		div.cloneNode(true).fireEvent("onclick");
	}

	div = document.createElement("div");
	div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";

	var fragment = document.createDocumentFragment();
	fragment.appendChild( div.firstChild );

	jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;

	jQuery(function() {
		var div = document.createElement("div");
		div.style.width = div.style.paddingLeft = "1px";

		document.body.appendChild( div );
		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
		document.body.removeChild( div ).style.display = 'none';

		div = null;
	});

	var eventSupported = function( eventName ) {
		var el = document.createElement("div");
		eventName = "on" + eventName;

		var isSupported = (eventName in el);
		if ( !isSupported ) {
			el.setAttribute(eventName, "return;");
			isSupported = typeof el[eventName] === "function";
		}
		el = null;

		return isSupported;
	};

	jQuery.support.submitBubbles = eventSupported("submit");
	jQuery.support.changeBubbles = eventSupported("change");

	root = script = div = all = a = null;
})();

jQuery.props = {
	"for": "htmlFor",
	"class": "className",
	readonly: "readOnly",
	maxlength: "maxLength",
	cellspacing: "cellSpacing",
	rowspan: "rowSpan",
	colspan: "colSpan",
	tabindex: "tabIndex",
	usemap: "useMap",
	frameborder: "frameBorder"
};
var expando = "jQuery" + now(), uuid = 0, windowData = {};

jQuery.extend({
	cache: {},

	expando:expando,

	noData: {
		"embed": true,
		"object": true,
		"applet": true
	},

	data: function( elem, name, data ) {
		if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
			return;
		}

		elem = elem == window ?
			windowData :
			elem;

		var id = elem[ expando ], cache = jQuery.cache, thisCache;

		if ( !id && typeof name === "string" && data === undefined ) {
			return null;
		}

		if ( !id ) {
			id = ++uuid;
		}

		if ( typeof name === "object" ) {
			elem[ expando ] = id;
			thisCache = cache[ id ] = jQuery.extend(true, {}, name);

		} else if ( !cache[ id ] ) {
			elem[ expando ] = id;
			cache[ id ] = {};
		}

		thisCache = cache[ id ];

		if ( data !== undefined ) {
			thisCache[ name ] = data;
		}

		return typeof name === "string" ? thisCache[ name ] : thisCache;
	},

	removeData: function( elem, name ) {
		if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
			return;
		}

		elem = elem == window ?
			windowData :
			elem;

		var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];

		if ( name ) {
			if ( thisCache ) {
				delete thisCache[ name ];

				if ( jQuery.isEmptyObject(thisCache) ) {
					jQuery.removeData( elem );
				}
			}

		} else {
			if ( jQuery.support.deleteExpando ) {
				delete elem[ jQuery.expando ];

			} else if ( elem.removeAttribute ) {
				elem.removeAttribute( jQuery.expando );
			}

			delete cache[ id ];
		}
	}
});

jQuery.fn.extend({
	data: function( key, value ) {
		if ( typeof key === "undefined" && this.length ) {
			return jQuery.data( this[0] );

		} else if ( typeof key === "object" ) {
			return this.each(function() {
				jQuery.data( this, key );
			});
		}

		var parts = key.split(".");
		parts[1] = parts[1] ? "." + parts[1] : "";

		if ( value === undefined ) {
			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);

			if ( data === undefined && this.length ) {
				data = jQuery.data( this[0], key );
			}
			return data === undefined && parts[1] ?
				this.data( parts[0] ) :
				data;
		} else {
			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
				jQuery.data( this, key, value );
			});
		}
	},

	removeData: function( key ) {
		return this.each(function() {
			jQuery.removeData( this, key );
		});
	}
});
jQuery.extend({
	queue: function( elem, type, data ) {
		if ( !elem ) {
			return;
		}

		type = (type || "fx") + "queue";
		var q = jQuery.data( elem, type );

		if ( !data ) {
			return q || [];
		}

		if ( !q || jQuery.isArray(data) ) {
			q = jQuery.data( elem, type, jQuery.makeArray(data) );

		} else {
			q.push( data );
		}

		return q;
	},

	dequeue: function( elem, type ) {
		type = type || "fx";

		var queue = jQuery.queue( elem, type ), fn = queue.shift();

		if ( fn === "inprogress" ) {
			fn = queue.shift();
		}

		if ( fn ) {
			if ( type === "fx" ) {
				queue.unshift("inprogress");
			}

			fn.call(elem, function() {
				jQuery.dequeue(elem, type);
			});
		}
	}
});

jQuery.fn.extend({
	queue: function( type, data ) {
		if ( typeof type !== "string" ) {
			data = type;
			type = "fx";
		}

		if ( data === undefined ) {
			return jQuery.queue( this[0], type );
		}
		return this.each(function( i, elem ) {
			var queue = jQuery.queue( this, type, data );

			if ( type === "fx" && queue[0] !== "inprogress" ) {
				jQuery.dequeue( this, type );
			}
		});
	},
	dequeue: function( type ) {
		return this.each(function() {
			jQuery.dequeue( this, type );
		});
	},

	delay: function( time, type ) {
		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
		type = type || "fx";

		return this.queue( type, function() {
			var elem = this;
			setTimeout(function() {
				jQuery.dequeue( elem, type );
			}, time );
		});
	},

	clearQueue: function( type ) {
		return this.queue( type || "fx", [] );
	}
});
var rclass = /[\n\t]/g,
	rspace = /\s+/,
	rreturn = /\r/g,
	rspecialurl = /href|src|style/,
	rtype = /(button|input)/i,
	rfocusable = /(button|input|object|select|textarea)/i,
	rclickable = /^(a|area)$/i,
	rradiocheck = /radio|checkbox/;

jQuery.fn.extend({
	attr: function( name, value ) {
		return access( this, name, value, true, jQuery.attr );
	},

	removeAttr: function( name, fn ) {
		return this.each(function(){
			jQuery.attr( this, name, "" );
			if ( this.nodeType === 1 ) {
				this.removeAttribute( name );
			}
		});
	},

	addClass: function( value ) {
		if ( jQuery.isFunction(value) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.addClass( value.call(this, i, self.attr("class")) );
			});
		}

		if ( value && typeof value === "string" ) {
			var classNames = (value || "").split( rspace );

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 ) {
					if ( !elem.className ) {
						elem.className = value;

					} else {
						var className = " " + elem.className + " ", setClass = elem.className;
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
								setClass += " " + classNames[c];
							}
						}
						elem.className = jQuery.trim( setClass );
					}
				}
			}
		}

		return this;
	},

	removeClass: function( value ) {
		if ( jQuery.isFunction(value) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.removeClass( value.call(this, i, self.attr("class")) );
			});
		}

		if ( (value && typeof value === "string") || value === undefined ) {
			var classNames = (value || "").split(rspace);

			for ( var i = 0, l = this.length; i < l; i++ ) {
				var elem = this[i];

				if ( elem.nodeType === 1 && elem.className ) {
					if ( value ) {
						var className = (" " + elem.className + " ").replace(rclass, " ");
						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
							className = className.replace(" " + classNames[c] + " ", " ");
						}
						elem.className = jQuery.trim( className );

					} else {
						elem.className = "";
					}
				}
			}
		}

		return this;
	},

	toggleClass: function( value, stateVal ) {
		var type = typeof value, isBool = typeof stateVal === "boolean";

		if ( jQuery.isFunction( value ) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
			});
		}

		return this.each(function() {
			if ( type === "string" ) {
				var className, i = 0, self = jQuery(this),
					state = stateVal,
					classNames = value.split( rspace );

				while ( (className = classNames[ i++ ]) ) {
					state = isBool ? state : !self.hasClass( className );
					self[ state ? "addClass" : "removeClass" ]( className );
				}

			} else if ( type === "undefined" || type === "boolean" ) {
				if ( this.className ) {
					jQuery.data( this, "__className__", this.className );
				}

				this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
			}
		});
	},

	hasClass: function( selector ) {
		var className = " " + selector + " ";
		for ( var i = 0, l = this.length; i < l; i++ ) {
			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
				return true;
			}
		}

		return false;
	},

	val: function( value ) {
		if ( value === undefined ) {
			var elem = this[0];

			if ( elem ) {
				if ( jQuery.nodeName( elem, "option" ) ) {
					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
				}

				if ( jQuery.nodeName( elem, "select" ) ) {
					var index = elem.selectedIndex,
						values = [],
						options = elem.options,
						one = elem.type === "select-one";

					if ( index < 0 ) {
						return null;
					}

					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
						var option = options[ i ];

						if ( option.selected ) {
							value = jQuery(option).val();

							if ( one ) {
								return value;
							}

							values.push( value );
						}
					}

					return values;
				}

				if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
					return elem.getAttribute("value") === null ? "on" : elem.value;
				}


				return (elem.value || "").replace(rreturn, "");

			}

			return undefined;
		}

		var isFunction = jQuery.isFunction(value);

		return this.each(function(i) {
			var self = jQuery(this), val = value;

			if ( this.nodeType !== 1 ) {
				return;
			}

			if ( isFunction ) {
				val = value.call(this, i, self.val());
			}

			if ( typeof val === "number" ) {
				val += "";
			}

			if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
				this.checked = jQuery.inArray( self.val(), val ) >= 0;

			} else if ( jQuery.nodeName( this, "select" ) ) {
				var values = jQuery.makeArray(val);

				jQuery( "option", this ).each(function() {
					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
				});

				if ( !values.length ) {
					this.selectedIndex = -1;
				}

			} else {
				this.value = val;
			}
		});
	}
});

jQuery.extend({
	attrFn: {
		val: true,
		css: true,
		html: true,
		text: true,
		data: true,
		width: true,
		height: true,
		offset: true
	},

	attr: function( elem, name, value, pass ) {
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
			return undefined;
		}

		if ( pass && name in jQuery.attrFn ) {
			return jQuery(elem)[name](value);
		}

		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
			set = value !== undefined;

		name = notxml && jQuery.props[ name ] || name;

		if ( elem.nodeType === 1 ) {
			var special = rspecialurl.test( name );

			if ( name === "selected" && !jQuery.support.optSelected ) {
				var parent = elem.parentNode;
				if ( parent ) {
					parent.selectedIndex;

					if ( parent.parentNode ) {
						parent.parentNode.selectedIndex;
					}
				}
			}

			if ( name in elem && notxml && !special ) {
				if ( set ) {
					if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
						jQuery.error( "type property can't be changed" );
					}

					elem[ name ] = value;
				}

				if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
					return elem.getAttributeNode( name ).nodeValue;
				}

				if ( name === "tabIndex" ) {
					var attributeNode = elem.getAttributeNode( "tabIndex" );

					return attributeNode && attributeNode.specified ?
						attributeNode.value :
						rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
							0 :
							undefined;
				}

				return elem[ name ];
			}

			if ( !jQuery.support.style && notxml && name === "style" ) {
				if ( set ) {
					elem.style.cssText = "" + value;
				}

				return elem.style.cssText;
			}

			if ( set ) {
				elem.setAttribute( name, "" + value );
			}

			var attr = !jQuery.support.hrefNormalized && notxml && special ?
					elem.getAttribute( name, 2 ) :
					elem.getAttribute( name );

			return attr === null ? undefined : attr;
		}

		return jQuery.style( elem, name, value );
	}
});
var rnamespaces = /\.(.*)$/,
	fcleanup = function( nm ) {
		return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
			return "\\" + ch;
		});
	};

/*
 * A number of helper functions used for managing events.
 * Many of the ideas behind this code originated from
 * Dean Edwards' addEvent library.
 */
jQuery.event = {

	add: function( elem, types, handler, data ) {
		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
			return;
		}

		if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
			elem = window;
		}

		var handleObjIn, handleObj;

		if ( handler.handler ) {
			handleObjIn = handler;
			handler = handleObjIn.handler;
		}

		if ( !handler.guid ) {
			handler.guid = jQuery.guid++;
		}

		var elemData = jQuery.data( elem );

		if ( !elemData ) {
			return;
		}

		var events = elemData.events = elemData.events || {},
			eventHandle = elemData.handle, eventHandle;

		if ( !eventHandle ) {
			elemData.handle = eventHandle = function() {
				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
					undefined;
			};
		}

		eventHandle.elem = elem;

		types = types.split(" ");

		var type, i = 0, namespaces;

		while ( (type = types[ i++ ]) ) {
			handleObj = handleObjIn ?
				jQuery.extend({}, handleObjIn) :
				{ handler: handler, data: data };

			if ( type.indexOf(".") > -1 ) {
				namespaces = type.split(".");
				type = namespaces.shift();
				handleObj.namespace = namespaces.slice(0).sort().join(".");

			} else {
				namespaces = [];
				handleObj.namespace = "";
			}

			handleObj.type = type;
			handleObj.guid = handler.guid;

			var handlers = events[ type ],
				special = jQuery.event.special[ type ] || {};

			if ( !handlers ) {
				handlers = events[ type ] = [];

				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
					if ( elem.addEventListener ) {
						elem.addEventListener( type, eventHandle, false );

					} else if ( elem.attachEvent ) {
						elem.attachEvent( "on" + type, eventHandle );
					}
				}
			}

			if ( special.add ) {
				special.add.call( elem, handleObj );

				if ( !handleObj.handler.guid ) {
					handleObj.handler.guid = handler.guid;
				}
			}

			handlers.push( handleObj );

			jQuery.event.global[ type ] = true;
		}

		elem = null;
	},

	global: {},

	remove: function( elem, types, handler, pos ) {
		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
			return;
		}

		var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
			elemData = jQuery.data( elem ),
			events = elemData && elemData.events;

		if ( !elemData || !events ) {
			return;
		}

		if ( types && types.type ) {
			handler = types.handler;
			types = types.type;
		}

		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
			types = types || "";

			for ( type in events ) {
				jQuery.event.remove( elem, type + types );
			}

			return;
		}

		types = types.split(" ");

		while ( (type = types[ i++ ]) ) {
			origType = type;
			handleObj = null;
			all = type.indexOf(".") < 0;
			namespaces = [];

			if ( !all ) {
				namespaces = type.split(".");
				type = namespaces.shift();

				namespace = new RegExp("(^|\\.)" +
					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
			}

			eventType = events[ type ];

			if ( !eventType ) {
				continue;
			}

			if ( !handler ) {
				for ( var j = 0; j < eventType.length; j++ ) {
					handleObj = eventType[ j ];

					if ( all || namespace.test( handleObj.namespace ) ) {
						jQuery.event.remove( elem, origType, handleObj.handler, j );
						eventType.splice( j--, 1 );
					}
				}

				continue;
			}

			special = jQuery.event.special[ type ] || {};

			for ( var j = pos || 0; j < eventType.length; j++ ) {
				handleObj = eventType[ j ];

				if ( handler.guid === handleObj.guid ) {
					if ( all || namespace.test( handleObj.namespace ) ) {
						if ( pos == null ) {
							eventType.splice( j--, 1 );
						}

						if ( special.remove ) {
							special.remove.call( elem, handleObj );
						}
					}

					if ( pos != null ) {
						break;
					}
				}
			}

			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
					removeEvent( elem, type, elemData.handle );
				}

				ret = null;
				delete events[ type ];
			}
		}

		if ( jQuery.isEmptyObject( events ) ) {
			var handle = elemData.handle;
			if ( handle ) {
				handle.elem = null;
			}

			delete elemData.events;
			delete elemData.handle;

			if ( jQuery.isEmptyObject( elemData ) ) {
				jQuery.removeData( elem );
			}
		}
	},

	trigger: function( event, data, elem /*, bubbling */ ) {
		var type = event.type || event,
			bubbling = arguments[3];

		if ( !bubbling ) {
			event = typeof event === "object" ?
				event[expando] ? event :
				jQuery.extend( jQuery.Event(type), event ) :
				jQuery.Event(type);

			if ( type.indexOf("!") >= 0 ) {
				event.type = type = type.slice(0, -1);
				event.exclusive = true;
			}

			if ( !elem ) {
				event.stopPropagation();

				if ( jQuery.event.global[ type ] ) {
					jQuery.each( jQuery.cache, function() {
						if ( this.events && this.events[type] ) {
							jQuery.event.trigger( event, data, this.handle.elem );
						}
					});
				}
			}


			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
				return undefined;
			}

			event.result = undefined;
			event.target = elem;

			data = jQuery.makeArray( data );
			data.unshift( event );
		}

		event.currentTarget = elem;

		var handle = jQuery.data( elem, "handle" );
		if ( handle ) {
			handle.apply( elem, data );
		}

		var parent = elem.parentNode || elem.ownerDocument;

		try {
			if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
				if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
					event.result = false;
				}
			}

		} catch (e) {}

		if ( !event.isPropagationStopped() && parent ) {
			jQuery.event.trigger( event, data, parent, true );

		} else if ( !event.isDefaultPrevented() ) {
			var target = event.target, old,
				isClick = jQuery.nodeName(target, "a") && type === "click",
				special = jQuery.event.special[ type ] || {};

			if ( (!special._default || special._default.call( elem, event ) === false) &&
				!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {

				try {
					if ( target[ type ] ) {
						old = target[ "on" + type ];

						if ( old ) {
							target[ "on" + type ] = null;
						}

						jQuery.event.triggered = true;
						target[ type ]();
					}

				} catch (e) {}

				if ( old ) {
					target[ "on" + type ] = old;
				}

				jQuery.event.triggered = false;
			}
		}
	},

	handle: function( event ) {
		var all, handlers, namespaces, namespace, events;

		event = arguments[0] = jQuery.event.fix( event || window.event );
		event.currentTarget = this;

		all = event.type.indexOf(".") < 0 && !event.exclusive;

		if ( !all ) {
			namespaces = event.type.split(".");
			event.type = namespaces.shift();
			namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
		}

		var events = jQuery.data(this, "events"), handlers = events[ event.type ];

		if ( events && handlers ) {
			handlers = handlers.slice(0);

			for ( var j = 0, l = handlers.length; j < l; j++ ) {
				var handleObj = handlers[ j ];

				if ( all || namespace.test( handleObj.namespace ) ) {
					event.handler = handleObj.handler;
					event.data = handleObj.data;
					event.handleObj = handleObj;

					var ret = handleObj.handler.apply( this, arguments );

					if ( ret !== undefined ) {
						event.result = ret;
						if ( ret === false ) {
							event.preventDefault();
							event.stopPropagation();
						}
					}

					if ( event.isImmediatePropagationStopped() ) {
						break;
					}
				}
			}
		}

		return event.result;
	},

	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),

	fix: function( event ) {
		if ( event[ expando ] ) {
			return event;
		}

		var originalEvent = event;
		event = jQuery.Event( originalEvent );

		for ( var i = this.props.length, prop; i; ) {
			prop = this.props[ --i ];
			event[ prop ] = originalEvent[ prop ];
		}

		if ( !event.target ) {
			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
		}

		if ( event.target.nodeType === 3 ) {
			event.target = event.target.parentNode;
		}

		if ( !event.relatedTarget && event.fromElement ) {
			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
		}

		if ( event.pageX == null && event.clientX != null ) {
			var doc = document.documentElement, body = document.body;
			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
		}

		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
			event.which = event.charCode || event.keyCode;
		}

		if ( !event.metaKey && event.ctrlKey ) {
			event.metaKey = event.ctrlKey;
		}

		if ( !event.which && event.button !== undefined ) {
			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
		}

		return event;
	},

	guid: 1E8,

	proxy: jQuery.proxy,

	special: {
		ready: {
			setup: jQuery.bindReady,
			teardown: jQuery.noop
		},

		live: {
			add: function( handleObj ) {
				jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
			},

			remove: function( handleObj ) {
				var remove = true,
					type = handleObj.origType.replace(rnamespaces, "");

				jQuery.each( jQuery.data(this, "events").live || [], function() {
					if ( type === this.origType.replace(rnamespaces, "") ) {
						remove = false;
						return false;
					}
				});

				if ( remove ) {
					jQuery.event.remove( this, handleObj.origType, liveHandler );
				}
			}

		},

		beforeunload: {
			setup: function( data, namespaces, eventHandle ) {
				if ( this.setInterval ) {
					this.onbeforeunload = eventHandle;
				}

				return false;
			},
			teardown: function( namespaces, eventHandle ) {
				if ( this.onbeforeunload === eventHandle ) {
					this.onbeforeunload = null;
				}
			}
		}
	}
};

var removeEvent = document.removeEventListener ?
	function( elem, type, handle ) {
		elem.removeEventListener( type, handle, false );
	} :
	function( elem, type, handle ) {
		elem.detachEvent( "on" + type, handle );
	};

jQuery.Event = function( src ) {
	if ( !this.preventDefault ) {
		return new jQuery.Event( src );
	}

	if ( src && src.type ) {
		this.originalEvent = src;
		this.type = src.type;
	} else {
		this.type = src;
	}

	this.timeStamp = now();

	this[ expando ] = true;
};

function returnFalse() {
	return false;
}
function returnTrue() {
	return true;
}

jQuery.Event.prototype = {
	preventDefault: function() {
		this.isDefaultPrevented = returnTrue;

		var e = this.originalEvent;
		if ( !e ) {
			return;
		}

		if ( e.preventDefault ) {
			e.preventDefault();
		}
		e.returnValue = false;
	},
	stopPropagation: function() {
		this.isPropagationStopped = returnTrue;

		var e = this.originalEvent;
		if ( !e ) {
			return;
		}
		if ( e.stopPropagation ) {
			e.stopPropagation();
		}
		e.cancelBubble = true;
	},
	stopImmediatePropagation: function() {
		this.isImmediatePropagationStopped = returnTrue;
		this.stopPropagation();
	},
	isDefaultPrevented: returnFalse,
	isPropagationStopped: returnFalse,
	isImmediatePropagationStopped: returnFalse
};

var withinElement = function( event ) {
	var parent = event.relatedTarget;

	try {
		while ( parent && parent !== this ) {
			parent = parent.parentNode;
		}

		if ( parent !== this ) {
			event.type = event.data;

			jQuery.event.handle.apply( this, arguments );
		}

	} catch(e) { }
},

delegate = function( event ) {
	event.type = event.data;
	jQuery.event.handle.apply( this, arguments );
};

jQuery.each({
	mouseenter: "mouseover",
	mouseleave: "mouseout"
}, function( orig, fix ) {
	jQuery.event.special[ orig ] = {
		setup: function( data ) {
			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
		},
		teardown: function( data ) {
			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
		}
	};
});

if ( !jQuery.support.submitBubbles ) {

	jQuery.event.special.submit = {
		setup: function( data, namespaces ) {
			if ( this.nodeName.toLowerCase() !== "form" ) {
				jQuery.event.add(this, "click.specialSubmit", function( e ) {
					var elem = e.target, type = elem.type;

					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
						return trigger( "submit", this, arguments );
					}
				});

				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
					var elem = e.target, type = elem.type;

					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
						return trigger( "submit", this, arguments );
					}
				});

			} else {
				return false;
			}
		},

		teardown: function( namespaces ) {
			jQuery.event.remove( this, ".specialSubmit" );
		}
	};

}

if ( !jQuery.support.changeBubbles ) {

	var formElems = /textarea|input|select/i,

	changeFilters,

	getVal = function( elem ) {
		var type = elem.type, val = elem.value;

		if ( type === "radio" || type === "checkbox" ) {
			val = elem.checked;

		} else if ( type === "select-multiple" ) {
			val = elem.selectedIndex > -1 ?
				jQuery.map( elem.options, function( elem ) {
					return elem.selected;
				}).join("-") :
				"";

		} else if ( elem.nodeName.toLowerCase() === "select" ) {
			val = elem.selectedIndex;
		}

		return val;
	},

	testChange = function testChange( e ) {
		var elem = e.target, data, val;

		if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
			return;
		}

		data = jQuery.data( elem, "_change_data" );
		val = getVal(elem);

		if ( e.type !== "focusout" || elem.type !== "radio" ) {
			jQuery.data( elem, "_change_data", val );
		}

		if ( data === undefined || val === data ) {
			return;
		}

		if ( data != null || val ) {
			e.type = "change";
			return jQuery.event.trigger( e, arguments[1], elem );
		}
	};

	jQuery.event.special.change = {
		filters: {
			focusout: testChange,

			click: function( e ) {
				var elem = e.target, type = elem.type;

				if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
					return testChange.call( this, e );
				}
			},

			keydown: function( e ) {
				var elem = e.target, type = elem.type;

				if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
					type === "select-multiple" ) {
					return testChange.call( this, e );
				}
			},

			beforeactivate: function( e ) {
				var elem = e.target;
				jQuery.data( elem, "_change_data", getVal(elem) );
			}
		},

		setup: function( data, namespaces ) {
			if ( this.type === "file" ) {
				return false;
			}

			for ( var type in changeFilters ) {
				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
			}

			return formElems.test( this.nodeName );
		},

		teardown: function( namespaces ) {
			jQuery.event.remove( this, ".specialChange" );

			return formElems.test( this.nodeName );
		}
	};

	changeFilters = jQuery.event.special.change.filters;
}

function trigger( type, elem, args ) {
	args[0].type = type;
	return jQuery.event.handle.apply( elem, args );
}

if ( document.addEventListener ) {
	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
		jQuery.event.special[ fix ] = {
			setup: function() {
				this.addEventListener( orig, handler, true );
			},
			teardown: function() {
				this.removeEventListener( orig, handler, true );
			}
		};

		function handler( e ) {
			e = jQuery.event.fix( e );
			e.type = fix;
			return jQuery.event.handle.call( this, e );
		}
	});
}

jQuery.each(["bind", "one"], function( i, name ) {
	jQuery.fn[ name ] = function( type, data, fn ) {
		if ( typeof type === "object" ) {
			for ( var key in type ) {
				this[ name ](key, data, type[key], fn);
			}
			return this;
		}

		if ( jQuery.isFunction( data ) ) {
			fn = data;
			data = undefined;
		}

		var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
			jQuery( this ).unbind( event, handler );
			return fn.apply( this, arguments );
		}) : fn;

		if ( type === "unload" && name !== "one" ) {
			this.one( type, data, fn );

		} else {
			for ( var i = 0, l = this.length; i < l; i++ ) {
				jQuery.event.add( this[i], type, handler, data );
			}
		}

		return this;
	};
});

jQuery.fn.extend({
	unbind: function( type, fn ) {
		if ( typeof type === "object" && !type.preventDefault ) {
			for ( var key in type ) {
				this.unbind(key, type[key]);
			}

		} else {
			for ( var i = 0, l = this.length; i < l; i++ ) {
				jQuery.event.remove( this[i], type, fn );
			}
		}

		return this;
	},

	delegate: function( selector, types, data, fn ) {
		return this.live( types, data, fn, selector );
	},

	undelegate: function( selector, types, fn ) {
		if ( arguments.length === 0 ) {
				return this.unbind( "live" );

		} else {
			return this.die( types, null, fn, selector );
		}
	},

	trigger: function( type, data ) {
		return this.each(function() {
			jQuery.event.trigger( type, data, this );
		});
	},

	triggerHandler: function( type, data ) {
		if ( this[0] ) {
			var event = jQuery.Event( type );
			event.preventDefault();
			event.stopPropagation();
			jQuery.event.trigger( event, data, this[0] );
			return event.result;
		}
	},

	toggle: function( fn ) {
		var args = arguments, i = 1;

		while ( i < args.length ) {
			jQuery.proxy( fn, args[ i++ ] );
		}

		return this.click( jQuery.proxy( fn, function( event ) {
			var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
			jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );

			event.preventDefault();

			return args[ lastToggle ].apply( this, arguments ) || false;
		}));
	},

	hover: function( fnOver, fnOut ) {
		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
	}
});

var liveMap = {
	focus: "focusin",
	blur: "focusout",
	mouseenter: "mouseover",
	mouseleave: "mouseout"
};

jQuery.each(["live", "die"], function( i, name ) {
	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
		var type, i = 0, match, namespaces, preType,
			selector = origSelector || this.selector,
			context = origSelector ? this : jQuery( this.context );

		if ( jQuery.isFunction( data ) ) {
			fn = data;
			data = undefined;
		}

		types = (types || "").split(" ");

		while ( (type = types[ i++ ]) != null ) {
			match = rnamespaces.exec( type );
			namespaces = "";

			if ( match )  {
				namespaces = match[0];
				type = type.replace( rnamespaces, "" );
			}

			if ( type === "hover" ) {
				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
				continue;
			}

			preType = type;

			if ( type === "focus" || type === "blur" ) {
				types.push( liveMap[ type ] + namespaces );
				type = type + namespaces;

			} else {
				type = (liveMap[ type ] || type) + namespaces;
			}

			if ( name === "live" ) {
				context.each(function(){
					jQuery.event.add( this, liveConvert( type, selector ),
						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
				});

			} else {
				context.unbind( liveConvert( type, selector ), fn );
			}
		}

		return this;
	}
});

function liveHandler( event ) {
	var stop, elems = [], selectors = [], args = arguments,
		related, match, handleObj, elem, j, i, l, data,
		events = jQuery.data( this, "events" );

	if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
		return;
	}

	event.liveFired = this;

	var live = events.live.slice(0);

	for ( j = 0; j < live.length; j++ ) {
		handleObj = live[j];

		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
			selectors.push( handleObj.selector );

		} else {
			live.splice( j--, 1 );
		}
	}

	match = jQuery( event.target ).closest( selectors, event.currentTarget );

	for ( i = 0, l = match.length; i < l; i++ ) {
		for ( j = 0; j < live.length; j++ ) {
			handleObj = live[j];

			if ( match[i].selector === handleObj.selector ) {
				elem = match[i].elem;
				related = null;

				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
				}

				if ( !related || related !== elem ) {
					elems.push({ elem: elem, handleObj: handleObj });
				}
			}
		}
	}

	for ( i = 0, l = elems.length; i < l; i++ ) {
		match = elems[i];
		event.currentTarget = match.elem;
		event.data = match.handleObj.data;
		event.handleObj = match.handleObj;

		if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
			stop = false;
			break;
		}
	}

	return stop;
}

function liveConvert( type, selector ) {
	return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
}

jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {

	jQuery.fn[ name ] = function( fn ) {
		return fn ? this.bind( name, fn ) : this.trigger( name );
	};

	if ( jQuery.attrFn ) {
		jQuery.attrFn[ name ] = true;
	}
});

if ( window.attachEvent && !window.addEventListener ) {
	window.attachEvent("onunload", function() {
		for ( var id in jQuery.cache ) {
			if ( jQuery.cache[ id ].handle ) {
				try {
					jQuery.event.remove( jQuery.cache[ id ].handle.elem );
				} catch(e) {}
			}
		}
	});
}
/*!
 * Sizzle CSS Selector Engine - v1.0
 *  Copyright 2009, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *  More information: http://sizzlejs.com/
 */
(function(){

var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
	done = 0,
	toString = Object.prototype.toString,
	hasDuplicate = false,
	baseHasDuplicate = true;

[0, 0].sort(function(){
	baseHasDuplicate = false;
	return 0;
});

var Sizzle = function(selector, context, results, seed) {
	results = results || [];
	var origContext = context = context || document;

	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
		return [];
	}

	if ( !selector || typeof selector !== "string" ) {
		return results;
	}

	var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
		soFar = selector;

	while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
		soFar = m[3];

		parts.push( m[1] );

		if ( m[2] ) {
			extra = m[3];
			break;
		}
	}

	if ( parts.length > 1 && origPOS.exec( selector ) ) {
		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
			set = posProcess( parts[0] + parts[1], context );
		} else {
			set = Expr.relative[ parts[0] ] ?
				[ context ] :
				Sizzle( parts.shift(), context );

			while ( parts.length ) {
				selector = parts.shift();

				if ( Expr.relative[ selector ] ) {
					selector += parts.shift();
				}

				set = posProcess( selector, set );
			}
		}
	} else {
		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
			var ret = Sizzle.find( parts.shift(), context, contextXML );
			context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
		}

		if ( context ) {
			var ret = seed ?
				{ expr: parts.pop(), set: makeArray(seed) } :
				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
			set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;

			if ( parts.length > 0 ) {
				checkSet = makeArray(set);
			} else {
				prune = false;
			}

			while ( parts.length ) {
				var cur = parts.pop(), pop = cur;

				if ( !Expr.relative[ cur ] ) {
					cur = "";
				} else {
					pop = parts.pop();
				}

				if ( pop == null ) {
					pop = context;
				}

				Expr.relative[ cur ]( checkSet, pop, contextXML );
			}
		} else {
			checkSet = parts = [];
		}
	}

	if ( !checkSet ) {
		checkSet = set;
	}

	if ( !checkSet ) {
		Sizzle.error( cur || selector );
	}

	if ( toString.call(checkSet) === "[object Array]" ) {
		if ( !prune ) {
			results.push.apply( results, checkSet );
		} else if ( context && context.nodeType === 1 ) {
			for ( var i = 0; checkSet[i] != null; i++ ) {
				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
					results.push( set[i] );
				}
			}
		} else {
			for ( var i = 0; checkSet[i] != null; i++ ) {
				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
					results.push( set[i] );
				}
			}
		}
	} else {
		makeArray( checkSet, results );
	}

	if ( extra ) {
		Sizzle( extra, origContext, results, seed );
		Sizzle.uniqueSort( results );
	}

	return results;
};

Sizzle.uniqueSort = function(results){
	if ( sortOrder ) {
		hasDuplicate = baseHasDuplicate;
		results.sort(sortOrder);

		if ( hasDuplicate ) {
			for ( var i = 1; i < results.length; i++ ) {
				if ( results[i] === results[i-1] ) {
					results.splice(i--, 1);
				}
			}
		}
	}

	return results;
};

Sizzle.matches = function(expr, set){
	return Sizzle(expr, null, null, set);
};

Sizzle.find = function(expr, context, isXML){
	var set, match;

	if ( !expr ) {
		return [];
	}

	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
		var type = Expr.order[i], match;

		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
			var left = match[1];
			match.splice(1,1);

			if ( left.substr( left.length - 1 ) !== "\\" ) {
				match[1] = (match[1] || "").replace(/\\/g, "");
				set = Expr.find[ type ]( match, context, isXML );
				if ( set != null ) {
					expr = expr.replace( Expr.match[ type ], "" );
					break;
				}
			}
		}
	}

	if ( !set ) {
		set = context.getElementsByTagName("*");
	}

	return {set: set, expr: expr};
};

Sizzle.filter = function(expr, set, inplace, not){
	var old = expr, result = [], curLoop = set, match, anyFound,
		isXMLFilter = set && set[0] && isXML(set[0]);

	while ( expr && set.length ) {
		for ( var type in Expr.filter ) {
			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
				var filter = Expr.filter[ type ], found, item, left = match[1];
				anyFound = false;

				match.splice(1,1);

				if ( left.substr( left.length - 1 ) === "\\" ) {
					continue;
				}

				if ( curLoop === result ) {
					result = [];
				}

				if ( Expr.preFilter[ type ] ) {
					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );

					if ( !match ) {
						anyFound = found = true;
					} else if ( match === true ) {
						continue;
					}
				}

				if ( match ) {
					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
						if ( item ) {
							found = filter( item, match, i, curLoop );
							var pass = not ^ !!found;

							if ( inplace && found != null ) {
								if ( pass ) {
									anyFound = true;
								} else {
									curLoop[i] = false;
								}
							} else if ( pass ) {
								result.push( item );
								anyFound = true;
							}
						}
					}
				}

				if ( found !== undefined ) {
					if ( !inplace ) {
						curLoop = result;
					}

					expr = expr.replace( Expr.match[ type ], "" );

					if ( !anyFound ) {
						return [];
					}

					break;
				}
			}
		}

		if ( expr === old ) {
			if ( anyFound == null ) {
				Sizzle.error( expr );
			} else {
				break;
			}
		}

		old = expr;
	}

	return curLoop;
};

Sizzle.error = function( msg ) {
	throw "Syntax error, unrecognized expression: " + msg;
};

var Expr = Sizzle.selectors = {
	order: [ "ID", "NAME", "TAG" ],
	match: {
		ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
		CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
		TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
		PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
	},
	leftMatch: {},
	attrMap: {
		"class": "className",
		"for": "htmlFor"
	},
	attrHandle: {
		href: function(elem){
			return elem.getAttribute("href");
		}
	},
	relative: {
		"+": function(checkSet, part){
			var isPartStr = typeof part === "string",
				isTag = isPartStr && !/\W/.test(part),
				isPartStrNotTag = isPartStr && !isTag;

			if ( isTag ) {
				part = part.toLowerCase();
			}

			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
				if ( (elem = checkSet[i]) ) {
					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}

					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
						elem || false :
						elem === part;
				}
			}

			if ( isPartStrNotTag ) {
				Sizzle.filter( part, checkSet, true );
			}
		},
		">": function(checkSet, part){
			var isPartStr = typeof part === "string";

			if ( isPartStr && !/\W/.test(part) ) {
				part = part.toLowerCase();

				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
					var elem = checkSet[i];
					if ( elem ) {
						var parent = elem.parentNode;
						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
					}
				}
			} else {
				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
					var elem = checkSet[i];
					if ( elem ) {
						checkSet[i] = isPartStr ?
							elem.parentNode :
							elem.parentNode === part;
					}
				}

				if ( isPartStr ) {
					Sizzle.filter( part, checkSet, true );
				}
			}
		},
		"": function(checkSet, part, isXML){
			var doneName = done++, checkFn = dirCheck;

			if ( typeof part === "string" && !/\W/.test(part) ) {
				var nodeCheck = part = part.toLowerCase();
				checkFn = dirNodeCheck;
			}

			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
		},
		"~": function(checkSet, part, isXML){
			var doneName = done++, checkFn = dirCheck;

			if ( typeof part === "string" && !/\W/.test(part) ) {
				var nodeCheck = part = part.toLowerCase();
				checkFn = dirNodeCheck;
			}

			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
		}
	},
	find: {
		ID: function(match, context, isXML){
			if ( typeof context.getElementById !== "undefined" && !isXML ) {
				var m = context.getElementById(match[1]);
				return m ? [m] : [];
			}
		},
		NAME: function(match, context){
			if ( typeof context.getElementsByName !== "undefined" ) {
				var ret = [], results = context.getElementsByName(match[1]);

				for ( var i = 0, l = results.length; i < l; i++ ) {
					if ( results[i].getAttribute("name") === match[1] ) {
						ret.push( results[i] );
					}
				}

				return ret.length === 0 ? null : ret;
			}
		},
		TAG: function(match, context){
			return context.getElementsByTagName(match[1]);
		}
	},
	preFilter: {
		CLASS: function(match, curLoop, inplace, result, not, isXML){
			match = " " + match[1].replace(/\\/g, "") + " ";

			if ( isXML ) {
				return match;
			}

			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
				if ( elem ) {
					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
						if ( !inplace ) {
							result.push( elem );
						}
					} else if ( inplace ) {
						curLoop[i] = false;
					}
				}
			}

			return false;
		},
		ID: function(match){
			return match[1].replace(/\\/g, "");
		},
		TAG: function(match, curLoop){
			return match[1].toLowerCase();
		},
		CHILD: function(match){
			if ( match[1] === "nth" ) {
				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);

				match[2] = (test[1] + (test[2] || 1)) - 0;
				match[3] = test[3] - 0;
			}

			match[0] = done++;

			return match;
		},
		ATTR: function(match, curLoop, inplace, result, not, isXML){
			var name = match[1].replace(/\\/g, "");

			if ( !isXML && Expr.attrMap[name] ) {
				match[1] = Expr.attrMap[name];
			}

			if ( match[2] === "~=" ) {
				match[4] = " " + match[4] + " ";
			}

			return match;
		},
		PSEUDO: function(match, curLoop, inplace, result, not){
			if ( match[1] === "not" ) {
				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
					match[3] = Sizzle(match[3], null, null, curLoop);
				} else {
					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
					if ( !inplace ) {
						result.push.apply( result, ret );
					}
					return false;
				}
			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
				return true;
			}

			return match;
		},
		POS: function(match){
			match.unshift( true );
			return match;
		}
	},
	filters: {
		enabled: function(elem){
			return elem.disabled === false && elem.type !== "hidden";
		},
		disabled: function(elem){
			return elem.disabled === true;
		},
		checked: function(elem){
			return elem.checked === true;
		},
		selected: function(elem){
			elem.parentNode.selectedIndex;
			return elem.selected === true;
		},
		parent: function(elem){
			return !!elem.firstChild;
		},
		empty: function(elem){
			return !elem.firstChild;
		},
		has: function(elem, i, match){
			return !!Sizzle( match[3], elem ).length;
		},
		header: function(elem){
			return /h\d/i.test( elem.nodeName );
		},
		text: function(elem){
			return "text" === elem.type;
		},
		radio: function(elem){
			return "radio" === elem.type;
		},
		checkbox: function(elem){
			return "checkbox" === elem.type;
		},
		file: function(elem){
			return "file" === elem.type;
		},
		password: function(elem){
			return "password" === elem.type;
		},
		submit: function(elem){
			return "submit" === elem.type;
		},
		image: function(elem){
			return "image" === elem.type;
		},
		reset: function(elem){
			return "reset" === elem.type;
		},
		button: function(elem){
			return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
		},
		input: function(elem){
			return /input|select|textarea|button/i.test(elem.nodeName);
		}
	},
	setFilters: {
		first: function(elem, i){
			return i === 0;
		},
		last: function(elem, i, match, array){
			return i === array.length - 1;
		},
		even: function(elem, i){
			return i % 2 === 0;
		},
		odd: function(elem, i){
			return i % 2 === 1;
		},
		lt: function(elem, i, match){
			return i < match[3] - 0;
		},
		gt: function(elem, i, match){
			return i > match[3] - 0;
		},
		nth: function(elem, i, match){
			return match[3] - 0 === i;
		},
		eq: function(elem, i, match){
			return match[3] - 0 === i;
		}
	},
	filter: {
		PSEUDO: function(elem, match, i, array){
			var name = match[1], filter = Expr.filters[ name ];

			if ( filter ) {
				return filter( elem, i, match, array );
			} else if ( name === "contains" ) {
				return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
			} else if ( name === "not" ) {
				var not = match[3];

				for ( var i = 0, l = not.length; i < l; i++ ) {
					if ( not[i] === elem ) {
						return false;
					}
				}

				return true;
			} else {
				Sizzle.error( "Syntax error, unrecognized expression: " + name );
			}
		},
		CHILD: function(elem, match){
			var type = match[1], node = elem;
			switch (type) {
				case 'only':
				case 'first':
					while ( (node = node.previousSibling) )	 {
						if ( node.nodeType === 1 ) {
							return false;
						}
					}
					if ( type === "first" ) {
						return true;
					}
					node = elem;
				case 'last':
					while ( (node = node.nextSibling) )	 {
						if ( node.nodeType === 1 ) {
							return false;
						}
					}
					return true;
				case 'nth':
					var first = match[2], last = match[3];

					if ( first === 1 && last === 0 ) {
						return true;
					}

					var doneName = match[0],
						parent = elem.parentNode;

					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
						var count = 0;
						for ( node = parent.firstChild; node; node = node.nextSibling ) {
							if ( node.nodeType === 1 ) {
								node.nodeIndex = ++count;
							}
						}
						parent.sizcache = doneName;
					}

					var diff = elem.nodeIndex - last;
					if ( first === 0 ) {
						return diff === 0;
					} else {
						return ( diff % first === 0 && diff / first >= 0 );
					}
			}
		},
		ID: function(elem, match){
			return elem.nodeType === 1 && elem.getAttribute("id") === match;
		},
		TAG: function(elem, match){
			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
		},
		CLASS: function(elem, match){
			return (" " + (elem.className || elem.getAttribute("class")) + " ")
				.indexOf( match ) > -1;
		},
		ATTR: function(elem, match){
			var name = match[1],
				result = Expr.attrHandle[ name ] ?
					Expr.attrHandle[ name ]( elem ) :
					elem[ name ] != null ?
						elem[ name ] :
						elem.getAttribute( name ),
				value = result + "",
				type = match[2],
				check = match[4];

			return result == null ?
				type === "!=" :
				type === "=" ?
				value === check :
				type === "*=" ?
				value.indexOf(check) >= 0 :
				type === "~=" ?
				(" " + value + " ").indexOf(check) >= 0 :
				!check ?
				value && result !== false :
				type === "!=" ?
				value !== check :
				type === "^=" ?
				value.indexOf(check) === 0 :
				type === "$=" ?
				value.substr(value.length - check.length) === check :
				type === "|=" ?
				value === check || value.substr(0, check.length + 1) === check + "-" :
				false;
		},
		POS: function(elem, match, i, array){
			var name = match[2], filter = Expr.setFilters[ name ];

			if ( filter ) {
				return filter( elem, i, match, array );
			}
		}
	}
};

var origPOS = Expr.match.POS;

for ( var type in Expr.match ) {
	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
		return "\\" + (num - 0 + 1);
	}));
}

var makeArray = function(array, results) {
	array = Array.prototype.slice.call( array, 0 );

	if ( results ) {
		results.push.apply( results, array );
		return results;
	}

	return array;
};

try {
	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;

} catch(e){
	makeArray = function(array, results) {
		var ret = results || [];

		if ( toString.call(array) === "[object Array]" ) {
			Array.prototype.push.apply( ret, array );
		} else {
			if ( typeof array.length === "number" ) {
				for ( var i = 0, l = array.length; i < l; i++ ) {
					ret.push( array[i] );
				}
			} else {
				for ( var i = 0; array[i]; i++ ) {
					ret.push( array[i] );
				}
			}
		}

		return ret;
	};
}

var sortOrder;

if ( document.documentElement.compareDocumentPosition ) {
	sortOrder = function( a, b ) {
		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
			if ( a == b ) {
				hasDuplicate = true;
			}
			return a.compareDocumentPosition ? -1 : 1;
		}

		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
		if ( ret === 0 ) {
			hasDuplicate = true;
		}
		return ret;
	};
} else if ( "sourceIndex" in document.documentElement ) {
	sortOrder = function( a, b ) {
		if ( !a.sourceIndex || !b.sourceIndex ) {
			if ( a == b ) {
				hasDuplicate = true;
			}
			return a.sourceIndex ? -1 : 1;
		}

		var ret = a.sourceIndex - b.sourceIndex;
		if ( ret === 0 ) {
			hasDuplicate = true;
		}
		return ret;
	};
} else if ( document.createRange ) {
	sortOrder = function( a, b ) {
		if ( !a.ownerDocument || !b.ownerDocument ) {
			if ( a == b ) {
				hasDuplicate = true;
			}
			return a.ownerDocument ? -1 : 1;
		}

		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
		aRange.setStart(a, 0);
		aRange.setEnd(a, 0);
		bRange.setStart(b, 0);
		bRange.setEnd(b, 0);
		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
		if ( ret === 0 ) {
			hasDuplicate = true;
		}
		return ret;
	};
}

function getText( elems ) {
	var ret = "", elem;

	for ( var i = 0; elems[i]; i++ ) {
		elem = elems[i];

		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
			ret += elem.nodeValue;

		} else if ( elem.nodeType !== 8 ) {
			ret += getText( elem.childNodes );
		}
	}

	return ret;
}

(function(){
	var form = document.createElement("div"),
		id = "script" + (new Date).getTime();
	form.innerHTML = "<a name='" + id + "'/>";

	var root = document.documentElement;
	root.insertBefore( form, root.firstChild );

	if ( document.getElementById( id ) ) {
		Expr.find.ID = function(match, context, isXML){
			if ( typeof context.getElementById !== "undefined" && !isXML ) {
				var m = context.getElementById(match[1]);
				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
			}
		};

		Expr.filter.ID = function(elem, match){
			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
			return elem.nodeType === 1 && node && node.nodeValue === match;
		};
	}

	root.removeChild( form );
	root = form = null; // release memory in IE
})();

(function(){

	var div = document.createElement("div");
	div.appendChild( document.createComment("") );

	if ( div.getElementsByTagName("*").length > 0 ) {
		Expr.find.TAG = function(match, context){
			var results = context.getElementsByTagName(match[1]);

			if ( match[1] === "*" ) {
				var tmp = [];

				for ( var i = 0; results[i]; i++ ) {
					if ( results[i].nodeType === 1 ) {
						tmp.push( results[i] );
					}
				}

				results = tmp;
			}

			return results;
		};
	}

	div.innerHTML = "<a href='#'></a>";
	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
			div.firstChild.getAttribute("href") !== "#" ) {
		Expr.attrHandle.href = function(elem){
			return elem.getAttribute("href", 2);
		};
	}

	div = null; // release memory in IE
})();

if ( document.querySelectorAll ) {
	(function(){
		var oldSizzle = Sizzle, div = document.createElement("div");
		div.innerHTML = "<p class='TEST'></p>";

		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
			return;
		}

		Sizzle = function(query, context, extra, seed){
			context = context || document;

			if ( !seed && context.nodeType === 9 && !isXML(context) ) {
				try {
					return makeArray( context.querySelectorAll(query), extra );
				} catch(e){}
			}

			return oldSizzle(query, context, extra, seed);
		};

		for ( var prop in oldSizzle ) {
			Sizzle[ prop ] = oldSizzle[ prop ];
		}

		div = null; // release memory in IE
	})();
}

(function(){
	var div = document.createElement("div");

	div.innerHTML = "<div class='test e'></div><div class='test'></div>";

	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
		return;
	}

	div.lastChild.className = "e";

	if ( div.getElementsByClassName("e").length === 1 ) {
		return;
	}

	Expr.order.splice(1, 0, "CLASS");
	Expr.find.CLASS = function(match, context, isXML) {
		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
			return context.getElementsByClassName(match[1]);
		}
	};

	div = null; // release memory in IE
})();

function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
		var elem = checkSet[i];
		if ( elem ) {
			elem = elem[dir];
			var match = false;

			while ( elem ) {
				if ( elem.sizcache === doneName ) {
					match = checkSet[elem.sizset];
					break;
				}

				if ( elem.nodeType === 1 && !isXML ){
					elem.sizcache = doneName;
					elem.sizset = i;
				}

				if ( elem.nodeName.toLowerCase() === cur ) {
					match = elem;
					break;
				}

				elem = elem[dir];
			}

			checkSet[i] = match;
		}
	}
}

function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
		var elem = checkSet[i];
		if ( elem ) {
			elem = elem[dir];
			var match = false;

			while ( elem ) {
				if ( elem.sizcache === doneName ) {
					match = checkSet[elem.sizset];
					break;
				}

				if ( elem.nodeType === 1 ) {
					if ( !isXML ) {
						elem.sizcache = doneName;
						elem.sizset = i;
					}
					if ( typeof cur !== "string" ) {
						if ( elem === cur ) {
							match = true;
							break;
						}

					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
						match = elem;
						break;
					}
				}

				elem = elem[dir];
			}

			checkSet[i] = match;
		}
	}
}

var contains = document.compareDocumentPosition ? function(a, b){
	return !!(a.compareDocumentPosition(b) & 16);
} : function(a, b){
	return a !== b && (a.contains ? a.contains(b) : true);
};

var isXML = function(elem){
	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
	return documentElement ? documentElement.nodeName !== "HTML" : false;
};

var posProcess = function(selector, context){
	var tmpSet = [], later = "", match,
		root = context.nodeType ? [context] : context;

	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
		later += match[0];
		selector = selector.replace( Expr.match.PSEUDO, "" );
	}

	selector = Expr.relative[selector] ? selector + "*" : selector;

	for ( var i = 0, l = root.length; i < l; i++ ) {
		Sizzle( selector, root[i], tmpSet );
	}

	return Sizzle.filter( later, tmpSet );
};

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;
jQuery.unique = Sizzle.uniqueSort;
jQuery.text = getText;
jQuery.isXMLDoc = isXML;
jQuery.contains = contains;

return;

window.Sizzle = Sizzle;

})();
var runtil = /Until$/,
	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
	rmultiselector = /,/,
	slice = Array.prototype.slice;

var winnow = function( elements, qualifier, keep ) {
	if ( jQuery.isFunction( qualifier ) ) {
		return jQuery.grep(elements, function( elem, i ) {
			return !!qualifier.call( elem, i, elem ) === keep;
		});

	} else if ( qualifier.nodeType ) {
		return jQuery.grep(elements, function( elem, i ) {
			return (elem === qualifier) === keep;
		});

	} else if ( typeof qualifier === "string" ) {
		var filtered = jQuery.grep(elements, function( elem ) {
			return elem.nodeType === 1;
		});

		if ( isSimple.test( qualifier ) ) {
			return jQuery.filter(qualifier, filtered, !keep);
		} else {
			qualifier = jQuery.filter( qualifier, filtered );
		}
	}

	return jQuery.grep(elements, function( elem, i ) {
		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
	});
};

jQuery.fn.extend({
	find: function( selector ) {
		var ret = this.pushStack( "", "find", selector ), length = 0;

		for ( var i = 0, l = this.length; i < l; i++ ) {
			length = ret.length;
			jQuery.find( selector, this[i], ret );

			if ( i > 0 ) {
				for ( var n = length; n < ret.length; n++ ) {
					for ( var r = 0; r < length; r++ ) {
						if ( ret[r] === ret[n] ) {
							ret.splice(n--, 1);
							break;
						}
					}
				}
			}
		}

		return ret;
	},

	has: function( target ) {
		var targets = jQuery( target );
		return this.filter(function() {
			for ( var i = 0, l = targets.length; i < l; i++ ) {
				if ( jQuery.contains( this, targets[i] ) ) {
					return true;
				}
			}
		});
	},

	not: function( selector ) {
		return this.pushStack( winnow(this, selector, false), "not", selector);
	},

	filter: function( selector ) {
		return this.pushStack( winnow(this, selector, true), "filter", selector );
	},

	is: function( selector ) {
		return !!selector && jQuery.filter( selector, this ).length > 0;
	},

	closest: function( selectors, context ) {
		if ( jQuery.isArray( selectors ) ) {
			var ret = [], cur = this[0], match, matches = {}, selector;

			if ( cur && selectors.length ) {
				for ( var i = 0, l = selectors.length; i < l; i++ ) {
					selector = selectors[i];

					if ( !matches[selector] ) {
						matches[selector] = jQuery.expr.match.POS.test( selector ) ?
							jQuery( selector, context || this.context ) :
							selector;
					}
				}

				while ( cur && cur.ownerDocument && cur !== context ) {
					for ( selector in matches ) {
						match = matches[selector];

						if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
							ret.push({ selector: selector, elem: cur });
							delete matches[selector];
						}
					}
					cur = cur.parentNode;
				}
			}

			return ret;
		}

		var pos = jQuery.expr.match.POS.test( selectors ) ?
			jQuery( selectors, context || this.context ) : null;

		return this.map(function( i, cur ) {
			while ( cur && cur.ownerDocument && cur !== context ) {
				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
					return cur;
				}
				cur = cur.parentNode;
			}
			return null;
		});
	},

	index: function( elem ) {
		if ( !elem || typeof elem === "string" ) {
			return jQuery.inArray( this[0],
				elem ? jQuery( elem ) : this.parent().children() );
		}
		return jQuery.inArray(
			elem.jquery ? elem[0] : elem, this );
	},

	add: function( selector, context ) {
		var set = typeof selector === "string" ?
				jQuery( selector, context || this.context ) :
				jQuery.makeArray( selector ),
			all = jQuery.merge( this.get(), set );

		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
			all :
			jQuery.unique( all ) );
	},

	andSelf: function() {
		return this.add( this.prevObject );
	}
});

function isDisconnected( node ) {
	return !node || !node.parentNode || node.parentNode.nodeType === 11;
}

jQuery.each({
	parent: function( elem ) {
		var parent = elem.parentNode;
		return parent && parent.nodeType !== 11 ? parent : null;
	},
	parents: function( elem ) {
		return jQuery.dir( elem, "parentNode" );
	},
	parentsUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "parentNode", until );
	},
	next: function( elem ) {
		return jQuery.nth( elem, 2, "nextSibling" );
	},
	prev: function( elem ) {
		return jQuery.nth( elem, 2, "previousSibling" );
	},
	nextAll: function( elem ) {
		return jQuery.dir( elem, "nextSibling" );
	},
	prevAll: function( elem ) {
		return jQuery.dir( elem, "previousSibling" );
	},
	nextUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "nextSibling", until );
	},
	prevUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "previousSibling", until );
	},
	siblings: function( elem ) {
		return jQuery.sibling( elem.parentNode.firstChild, elem );
	},
	children: function( elem ) {
		return jQuery.sibling( elem.firstChild );
	},
	contents: function( elem ) {
		return jQuery.nodeName( elem, "iframe" ) ?
			elem.contentDocument || elem.contentWindow.document :
			jQuery.makeArray( elem.childNodes );
	}
}, function( name, fn ) {
	jQuery.fn[ name ] = function( until, selector ) {
		var ret = jQuery.map( this, fn, until );

		if ( !runtil.test( name ) ) {
			selector = until;
		}

		if ( selector && typeof selector === "string" ) {
			ret = jQuery.filter( selector, ret );
		}

		ret = this.length > 1 ? jQuery.unique( ret ) : ret;

		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
			ret = ret.reverse();
		}

		return this.pushStack( ret, name, slice.call(arguments).join(",") );
	};
});

jQuery.extend({
	filter: function( expr, elems, not ) {
		if ( not ) {
			expr = ":not(" + expr + ")";
		}

		return jQuery.find.matches(expr, elems);
	},

	dir: function( elem, dir, until ) {
		var matched = [], cur = elem[dir];
		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
			if ( cur.nodeType === 1 ) {
				matched.push( cur );
			}
			cur = cur[dir];
		}
		return matched;
	},

	nth: function( cur, result, dir, elem ) {
		result = result || 1;
		var num = 0;

		for ( ; cur; cur = cur[dir] ) {
			if ( cur.nodeType === 1 && ++num === result ) {
				break;
			}
		}

		return cur;
	},

	sibling: function( n, elem ) {
		var r = [];

		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				r.push( n );
			}
		}

		return r;
	}
});
var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
	rleadingWhitespace = /^\s+/,
	rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
	rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
	rtagName = /<([\w:]+)/,
	rtbody = /<tbody/i,
	rhtml = /<|&#?\w+;/,
	rnocache = /<script|<object|<embed|<option|<style/i,
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
	fcloseTag = function( all, front, tag ) {
		return rselfClosing.test( tag ) ?
			all :
			front + "></" + tag + ">";
	},
	wrapMap = {
		option: [ 1, "<select multiple='multiple'>", "</select>" ],
		legend: [ 1, "<fieldset>", "</fieldset>" ],
		thead: [ 1, "<table>", "</table>" ],
		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
		area: [ 1, "<map>", "</map>" ],
		_default: [ 0, "", "" ]
	};

wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;

if ( !jQuery.support.htmlSerialize ) {
	wrapMap._default = [ 1, "div<div>", "</div>" ];
}

jQuery.fn.extend({
	text: function( text ) {
		if ( jQuery.isFunction(text) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				self.text( text.call(this, i, self.text()) );
			});
		}

		if ( typeof text !== "object" && text !== undefined ) {
			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
		}

		return jQuery.text( this );
	},

	wrapAll: function( html ) {
		if ( jQuery.isFunction( html ) ) {
			return this.each(function(i) {
				jQuery(this).wrapAll( html.call(this, i) );
			});
		}

		if ( this[0] ) {
			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);

			if ( this[0].parentNode ) {
				wrap.insertBefore( this[0] );
			}

			wrap.map(function() {
				var elem = this;

				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
					elem = elem.firstChild;
				}

				return elem;
			}).append(this);
		}

		return this;
	},

	wrapInner: function( html ) {
		if ( jQuery.isFunction( html ) ) {
			return this.each(function(i) {
				jQuery(this).wrapInner( html.call(this, i) );
			});
		}

		return this.each(function() {
			var self = jQuery( this ), contents = self.contents();

			if ( contents.length ) {
				contents.wrapAll( html );

			} else {
				self.append( html );
			}
		});
	},

	wrap: function( html ) {
		return this.each(function() {
			jQuery( this ).wrapAll( html );
		});
	},

	unwrap: function() {
		return this.parent().each(function() {
			if ( !jQuery.nodeName( this, "body" ) ) {
				jQuery( this ).replaceWith( this.childNodes );
			}
		}).end();
	},

	append: function() {
		return this.domManip(arguments, true, function( elem ) {
			if ( this.nodeType === 1 ) {
				this.appendChild( elem );
			}
		});
	},

	prepend: function() {
		return this.domManip(arguments, true, function( elem ) {
			if ( this.nodeType === 1 ) {
				this.insertBefore( elem, this.firstChild );
			}
		});
	},

	before: function() {
		if ( this[0] && this[0].parentNode ) {
			return this.domManip(arguments, false, function( elem ) {
				this.parentNode.insertBefore( elem, this );
			});
		} else if ( arguments.length ) {
			var set = jQuery(arguments[0]);
			set.push.apply( set, this.toArray() );
			return this.pushStack( set, "before", arguments );
		}
	},

	after: function() {
		if ( this[0] && this[0].parentNode ) {
			return this.domManip(arguments, false, function( elem ) {
				this.parentNode.insertBefore( elem, this.nextSibling );
			});
		} else if ( arguments.length ) {
			var set = this.pushStack( this, "after", arguments );
			set.push.apply( set, jQuery(arguments[0]).toArray() );
			return set;
		}
	},

	remove: function( selector, keepData ) {
		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
				if ( !keepData && elem.nodeType === 1 ) {
					jQuery.cleanData( elem.getElementsByTagName("*") );
					jQuery.cleanData( [ elem ] );
				}

				if ( elem.parentNode ) {
					 elem.parentNode.removeChild( elem );
				}
			}
		}

		return this;
	},

	empty: function() {
		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
			if ( elem.nodeType === 1 ) {
				jQuery.cleanData( elem.getElementsByTagName("*") );
			}

			while ( elem.firstChild ) {
				elem.removeChild( elem.firstChild );
			}
		}

		return this;
	},

	clone: function( events ) {
		var ret = this.map(function() {
			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
				var html = this.outerHTML, ownerDocument = this.ownerDocument;
				if ( !html ) {
					var div = ownerDocument.createElement("div");
					div.appendChild( this.cloneNode(true) );
					html = div.innerHTML;
				}

				return jQuery.clean([html.replace(rinlinejQuery, "")
					.replace(/=([^="'>\s]+\/)>/g, '="$1">')
					.replace(rleadingWhitespace, "")], ownerDocument)[0];
			} else {
				return this.cloneNode(true);
			}
		});

		if ( events === true ) {
			cloneCopyEvent( this, ret );
			cloneCopyEvent( this.find("*"), ret.find("*") );
		}

		return ret;
	},

	html: function( value ) {
		if ( value === undefined ) {
			return this[0] && this[0].nodeType === 1 ?
				this[0].innerHTML.replace(rinlinejQuery, "") :
				null;

		} else if ( typeof value === "string" && !rnocache.test( value ) &&
			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {

			value = value.replace(rxhtmlTag, fcloseTag);

			try {
				for ( var i = 0, l = this.length; i < l; i++ ) {
					if ( this[i].nodeType === 1 ) {
						jQuery.cleanData( this[i].getElementsByTagName("*") );
						this[i].innerHTML = value;
					}
				}

			} catch(e) {
				this.empty().append( value );
			}

		} else if ( jQuery.isFunction( value ) ) {
			this.each(function(i){
				var self = jQuery(this), old = self.html();
				self.empty().append(function(){
					return value.call( this, i, old );
				});
			});

		} else {
			this.empty().append( value );
		}

		return this;
	},

	replaceWith: function( value ) {
		if ( this[0] && this[0].parentNode ) {
			if ( jQuery.isFunction( value ) ) {
				return this.each(function(i) {
					var self = jQuery(this), old = self.html();
					self.replaceWith( value.call( this, i, old ) );
				});
			}

			if ( typeof value !== "string" ) {
				value = jQuery(value).detach();
			}

			return this.each(function() {
				var next = this.nextSibling, parent = this.parentNode;

				jQuery(this).remove();

				if ( next ) {
					jQuery(next).before( value );
				} else {
					jQuery(parent).append( value );
				}
			});
		} else {
			return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
		}
	},

	detach: function( selector ) {
		return this.remove( selector, true );
	},

	domManip: function( args, table, callback ) {
		var results, first, value = args[0], scripts = [], fragment, parent;

		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
			return this.each(function() {
				jQuery(this).domManip( args, table, callback, true );
			});
		}

		if ( jQuery.isFunction(value) ) {
			return this.each(function(i) {
				var self = jQuery(this);
				args[0] = value.call(this, i, table ? self.html() : undefined);
				self.domManip( args, table, callback );
			});
		}

		if ( this[0] ) {
			parent = value && value.parentNode;

			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
				results = { fragment: parent };

			} else {
				results = buildFragment( args, this, scripts );
			}

			fragment = results.fragment;

			if ( fragment.childNodes.length === 1 ) {
				first = fragment = fragment.firstChild;
			} else {
				first = fragment.firstChild;
			}

			if ( first ) {
				table = table && jQuery.nodeName( first, "tr" );

				for ( var i = 0, l = this.length; i < l; i++ ) {
					callback.call(
						table ?
							root(this[i], first) :
							this[i],
						i > 0 || results.cacheable || this.length > 1  ?
							fragment.cloneNode(true) :
							fragment
					);
				}
			}

			if ( scripts.length ) {
				jQuery.each( scripts, evalScript );
			}
		}

		return this;

		function root( elem, cur ) {
			return jQuery.nodeName(elem, "table") ?
				(elem.getElementsByTagName("tbody")[0] ||
				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
				elem;
		}
	}
});

function cloneCopyEvent(orig, ret) {
	var i = 0;

	ret.each(function() {
		if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
			return;
		}

		var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;

		if ( events ) {
			delete curData.handle;
			curData.events = {};

			for ( var type in events ) {
				for ( var handler in events[ type ] ) {
					jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
				}
			}
		}
	});
}

function buildFragment( args, nodes, scripts ) {
	var fragment, cacheable, cacheresults,
		doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);

	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
		!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {

		cacheable = true;
		cacheresults = jQuery.fragments[ args[0] ];
		if ( cacheresults ) {
			if ( cacheresults !== 1 ) {
				fragment = cacheresults;
			}
		}
	}

	if ( !fragment ) {
		fragment = doc.createDocumentFragment();
		jQuery.clean( args, doc, fragment, scripts );
	}

	if ( cacheable ) {
		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
	}

	return { fragment: fragment, cacheable: cacheable };
}

jQuery.fragments = {};

jQuery.each({
	appendTo: "append",
	prependTo: "prepend",
	insertBefore: "before",
	insertAfter: "after",
	replaceAll: "replaceWith"
}, function( name, original ) {
	jQuery.fn[ name ] = function( selector ) {
		var ret = [], insert = jQuery( selector ),
			parent = this.length === 1 && this[0].parentNode;

		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
			insert[ original ]( this[0] );
			return this;

		} else {
			for ( var i = 0, l = insert.length; i < l; i++ ) {
				var elems = (i > 0 ? this.clone(true) : this).get();
				jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
				ret = ret.concat( elems );
			}

			return this.pushStack( ret, name, insert.selector );
		}
	};
});

jQuery.extend({
	clean: function( elems, context, fragment, scripts ) {
		context = context || document;

		if ( typeof context.createElement === "undefined" ) {
			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
		}

		var ret = [];

		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
			if ( typeof elem === "number" ) {
				elem += "";
			}

			if ( !elem ) {
				continue;
			}

			if ( typeof elem === "string" && !rhtml.test( elem ) ) {
				elem = context.createTextNode( elem );

			} else if ( typeof elem === "string" ) {
				elem = elem.replace(rxhtmlTag, fcloseTag);

				var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
					wrap = wrapMap[ tag ] || wrapMap._default,
					depth = wrap[0],
					div = context.createElement("div");

				div.innerHTML = wrap[1] + elem + wrap[2];

				while ( depth-- ) {
					div = div.lastChild;
				}

				if ( !jQuery.support.tbody ) {

					var hasBody = rtbody.test(elem),
						tbody = tag === "table" && !hasBody ?
							div.firstChild && div.firstChild.childNodes :

							wrap[1] === "<table>" && !hasBody ?
								div.childNodes :
								[];

					for ( var j = tbody.length - 1; j >= 0 ; --j ) {
						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
							tbody[ j ].parentNode.removeChild( tbody[ j ] );
						}
					}

				}

				if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
					div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
				}

				elem = div.childNodes;
			}

			if ( elem.nodeType ) {
				ret.push( elem );
			} else {
				ret = jQuery.merge( ret, elem );
			}
		}

		if ( fragment ) {
			for ( var i = 0; ret[i]; i++ ) {
				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );

				} else {
					if ( ret[i].nodeType === 1 ) {
						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
					}
					fragment.appendChild( ret[i] );
				}
			}
		}

		return ret;
	},

	cleanData: function( elems ) {
		var data, id, cache = jQuery.cache,
			special = jQuery.event.special,
			deleteExpando = jQuery.support.deleteExpando;

		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
			id = elem[ jQuery.expando ];

			if ( id ) {
				data = cache[ id ];

				if ( data.events ) {
					for ( var type in data.events ) {
						if ( special[ type ] ) {
							jQuery.event.remove( elem, type );

						} else {
							removeEvent( elem, type, data.handle );
						}
					}
				}

				if ( deleteExpando ) {
					delete elem[ jQuery.expando ];

				} else if ( elem.removeAttribute ) {
					elem.removeAttribute( jQuery.expando );
				}

				delete cache[ id ];
			}
		}
	}
});
var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
	ralpha = /alpha\([^)]*\)/,
	ropacity = /opacity=([^)]*)/,
	rfloat = /float/i,
	rdashAlpha = /-([a-z])/ig,
	rupper = /([A-Z])/g,
	rnumpx = /^-?\d+(?:px)?$/i,
	rnum = /^-?\d/,

	cssShow = { position: "absolute", visibility: "hidden", display:"block" },
	cssWidth = [ "Left", "Right" ],
	cssHeight = [ "Top", "Bottom" ],

	getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
	styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
	fcamelCase = function( all, letter ) {
		return letter.toUpperCase();
	};

jQuery.fn.css = function( name, value ) {
	return access( this, name, value, true, function( elem, name, value ) {
		if ( value === undefined ) {
			return jQuery.curCSS( elem, name );
		}

		if ( typeof value === "number" && !rexclude.test(name) ) {
			value += "px";
		}

		jQuery.style( elem, name, value );
	});
};

jQuery.extend({
	style: function( elem, name, value ) {
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
			return undefined;
		}

		if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
			value = undefined;
		}

		var style = elem.style || elem, set = value !== undefined;

		if ( !jQuery.support.opacity && name === "opacity" ) {
			if ( set ) {
				style.zoom = 1;

				var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
				var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
				style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
			}

			return style.filter && style.filter.indexOf("opacity=") >= 0 ?
				(parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
				"";
		}

		if ( rfloat.test( name ) ) {
			name = styleFloat;
		}

		name = name.replace(rdashAlpha, fcamelCase);

		if ( set ) {
			style[ name ] = value;
		}

		return style[ name ];
	},

	css: function( elem, name, force, extra ) {
		if ( name === "width" || name === "height" ) {
			var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;

			function getWH() {
				val = name === "width" ? elem.offsetWidth : elem.offsetHeight;

				if ( extra === "border" ) {
					return;
				}

				jQuery.each( which, function() {
					if ( !extra ) {
						val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
					}

					if ( extra === "margin" ) {
						val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
					} else {
						val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
					}
				});
			}

			if ( elem.offsetWidth !== 0 ) {
				getWH();
			} else {
				jQuery.swap( elem, props, getWH );
			}

			return Math.max(0, Math.round(val));
		}

		return jQuery.curCSS( elem, name, force );
	},

	curCSS: function( elem, name, force ) {
		var ret, style = elem.style, filter;

		if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
			ret = ropacity.test(elem.currentStyle.filter || "") ?
				(parseFloat(RegExp.$1) / 100) + "" :
				"";

			return ret === "" ?
				"1" :
				ret;
		}

		if ( rfloat.test( name ) ) {
			name = styleFloat;
		}

		if ( !force && style && style[ name ] ) {
			ret = style[ name ];

		} else if ( getComputedStyle ) {

			if ( rfloat.test( name ) ) {
				name = "float";
			}

			name = name.replace( rupper, "-$1" ).toLowerCase();

			var defaultView = elem.ownerDocument.defaultView;

			if ( !defaultView ) {
				return null;
			}

			var computedStyle = defaultView.getComputedStyle( elem, null );

			if ( computedStyle ) {
				ret = computedStyle.getPropertyValue( name );
			}

			if ( name === "opacity" && ret === "" ) {
				ret = "1";
			}

		} else if ( elem.currentStyle ) {
			var camelCase = name.replace(rdashAlpha, fcamelCase);

			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];


			if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
				var left = style.left, rsLeft = elem.runtimeStyle.left;

				elem.runtimeStyle.left = elem.currentStyle.left;
				style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
				ret = style.pixelLeft + "px";

				style.left = left;
				elem.runtimeStyle.left = rsLeft;
			}
		}

		return ret;
	},

	swap: function( elem, options, callback ) {
		var old = {};

		for ( var name in options ) {
			old[ name ] = elem.style[ name ];
			elem.style[ name ] = options[ name ];
		}

		callback.call( elem );

		for ( var name in options ) {
			elem.style[ name ] = old[ name ];
		}
	}
});

if ( jQuery.expr && jQuery.expr.filters ) {
	jQuery.expr.filters.hidden = function( elem ) {
		var width = elem.offsetWidth, height = elem.offsetHeight,
			skip = elem.nodeName.toLowerCase() === "tr";

		return width === 0 && height === 0 && !skip ?
			true :
			width > 0 && height > 0 && !skip ?
				false :
				jQuery.curCSS(elem, "display") === "none";
	};

	jQuery.expr.filters.visible = function( elem ) {
		return !jQuery.expr.filters.hidden( elem );
	};
}
var jsc = now(),
	rscript = /<script(.|\s)*?\/script>/gi,
	rselectTextarea = /select|textarea/i,
	rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
	jsre = /=\?(&|$)/,
	rquery = /\?/,
	rts = /(\?|&)_=.*?(&|$)/,
	rurl = /^(\w+:)?\/\/([^\/?#]+)/,
	r20 = /%20/g,

	_load = jQuery.fn.load;

jQuery.fn.extend({
	load: function( url, params, callback ) {
		if ( typeof url !== "string" ) {
			return _load.call( this, url );

		} else if ( !this.length ) {
			return this;
		}

		var off = url.indexOf(" ");
		if ( off >= 0 ) {
			var selector = url.slice(off, url.length);
			url = url.slice(0, off);
		}

		var type = "GET";

		if ( params ) {
			if ( jQuery.isFunction( params ) ) {
				callback = params;
				params = null;

			} else if ( typeof params === "object" ) {
				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
				type = "POST";
			}
		}

		var self = this;

		jQuery.ajax({
			url: url,
			type: type,
			dataType: "html",
			data: params,
			complete: function( res, status ) {
				if ( status === "success" || status === "notmodified" ) {
					self.html( selector ?
						jQuery("<div />")
							.append(res.responseText.replace(rscript, ""))

							.find(selector) :

						res.responseText );
				}

				if ( callback ) {
					self.each( callback, [res.responseText, status, res] );
				}
			}
		});

		return this;
	},

	serialize: function() {
		return jQuery.param(this.serializeArray());
	},
	serializeArray: function() {
		return this.map(function() {
			return this.elements ? jQuery.makeArray(this.elements) : this;
		})
		.filter(function() {
			return this.name && !this.disabled &&
				(this.checked || rselectTextarea.test(this.nodeName) ||
					rinput.test(this.type));
		})
		.map(function( i, elem ) {
			var val = jQuery(this).val();

			return val == null ?
				null :
				jQuery.isArray(val) ?
					jQuery.map( val, function( val, i ) {
						return { name: elem.name, value: val };
					}) :
					{ name: elem.name, value: val };
		}).get();
	}
});

jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
	jQuery.fn[o] = function( f ) {
		return this.bind(o, f);
	};
});

jQuery.extend({

	get: function( url, data, callback, type ) {
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = null;
		}

		return jQuery.ajax({
			type: "GET",
			url: url,
			data: data,
			success: callback,
			dataType: type
		});
	},

	getScript: function( url, callback ) {
		return jQuery.get(url, null, callback, "script");
	},

	getJSON: function( url, data, callback ) {
		return jQuery.get(url, data, callback, "json");
	},

	post: function( url, data, callback, type ) {
		if ( jQuery.isFunction( data ) ) {
			type = type || callback;
			callback = data;
			data = {};
		}

		return jQuery.ajax({
			type: "POST",
			url: url,
			data: data,
			success: callback,
			dataType: type
		});
	},

	ajaxSetup: function( settings ) {
		jQuery.extend( jQuery.ajaxSettings, settings );
	},

	ajaxSettings: {
		url: location.href,
		global: true,
		type: "GET",
		contentType: "application/x-www-form-urlencoded",
		processData: true,
		async: true,
		/*
		timeout: 0,
		data: null,
		username: null,
		password: null,
		traditional: false,
		*/
		xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
			function() {
				return new window.XMLHttpRequest();
			} :
			function() {
				try {
					return new window.ActiveXObject("Microsoft.XMLHTTP");
				} catch(e) {}
			},
		accepts: {
			xml: "application/xml, text/xml",
			html: "text/html",
			script: "text/javascript, application/javascript",
			json: "application/json, text/javascript",
			text: "text/plain",
			_default: "*/*"
		}
	},

	lastModified: {},
	etag: {},

	ajax: function( origSettings ) {
		var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);

		var jsonp, status, data,
			callbackContext = origSettings && origSettings.context || s,
			type = s.type.toUpperCase();

		if ( s.data && s.processData && typeof s.data !== "string" ) {
			s.data = jQuery.param( s.data, s.traditional );
		}

		if ( s.dataType === "jsonp" ) {
			if ( type === "GET" ) {
				if ( !jsre.test( s.url ) ) {
					s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
				}
			} else if ( !s.data || !jsre.test(s.data) ) {
				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
			}
			s.dataType = "json";
		}

		if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
			jsonp = s.jsonpCallback || ("jsonp" + jsc++);

			if ( s.data ) {
				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
			}

			s.url = s.url.replace(jsre, "=" + jsonp + "$1");

			s.dataType = "script";

			window[ jsonp ] = window[ jsonp ] || function( tmp ) {
				data = tmp;
				success();
				complete();
				window[ jsonp ] = undefined;

				try {
					delete window[ jsonp ];
				} catch(e) {}

				if ( head ) {
					head.removeChild( script );
				}
			};
		}

		if ( s.dataType === "script" && s.cache === null ) {
			s.cache = false;
		}

		if ( s.cache === false && type === "GET" ) {
			var ts = now();

			var ret = s.url.replace(rts, "$1_=" + ts + "$2");

			s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
		}

		if ( s.data && type === "GET" ) {
			s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
		}

		if ( s.global && ! jQuery.active++ ) {
			jQuery.event.trigger( "ajaxStart" );
		}

		var parts = rurl.exec( s.url ),
			remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);

		if ( s.dataType === "script" && type === "GET" && remote ) {
			var head = document.getElementsByTagName("head")[0] || document.documentElement;
			var script = document.createElement("script");
			script.src = s.url;
			if ( s.scriptCharset ) {
				script.charset = s.scriptCharset;
			}

			if ( !jsonp ) {
				var done = false;

				script.onload = script.onreadystatechange = function() {
					if ( !done && (!this.readyState ||
							this.readyState === "loaded" || this.readyState === "complete") ) {
						done = true;
						success();
						complete();

						script.onload = script.onreadystatechange = null;
						if ( head && script.parentNode ) {
							head.removeChild( script );
						}
					}
				};
			}

			head.insertBefore( script, head.firstChild );

			return undefined;
		}

		var requestDone = false;

		var xhr = s.xhr();

		if ( !xhr ) {
			return;
		}

		if ( s.username ) {
			xhr.open(type, s.url, s.async, s.username, s.password);
		} else {
			xhr.open(type, s.url, s.async);
		}

		try {
			if ( s.data || origSettings && origSettings.contentType ) {
				xhr.setRequestHeader("Content-Type", s.contentType);
			}

			if ( s.ifModified ) {
				if ( jQuery.lastModified[s.url] ) {
					xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
				}

				if ( jQuery.etag[s.url] ) {
					xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
				}
			}

			if ( !remote ) {
				xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			}

			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
				s.accepts[ s.dataType ] + ", */*" :
				s.accepts._default );
		} catch(e) {}

		if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
			if ( s.global && ! --jQuery.active ) {
				jQuery.event.trigger( "ajaxStop" );
			}

			xhr.abort();
			return false;
		}

		if ( s.global ) {
			trigger("ajaxSend", [xhr, s]);
		}

		var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
			if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
				if ( !requestDone ) {
					complete();
				}

				requestDone = true;
				if ( xhr ) {
					xhr.onreadystatechange = jQuery.noop;
				}

			} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
				requestDone = true;
				xhr.onreadystatechange = jQuery.noop;

				status = isTimeout === "timeout" ?
					"timeout" :
					!jQuery.httpSuccess( xhr ) ?
						"error" :
						s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
							"notmodified" :
							"success";

				var errMsg;

				if ( status === "success" ) {
					try {
						data = jQuery.httpData( xhr, s.dataType, s );
					} catch(err) {
						status = "parsererror";
						errMsg = err;
					}
				}

				if ( status === "success" || status === "notmodified" ) {
					if ( !jsonp ) {
						success();
					}
				} else {
					jQuery.handleError(s, xhr, status, errMsg);
				}

				complete();

				if ( isTimeout === "timeout" ) {
					xhr.abort();
				}

				if ( s.async ) {
					xhr = null;
				}
			}
		};

		try {
			var oldAbort = xhr.abort;
			xhr.abort = function() {
				if ( xhr ) {
					oldAbort.call( xhr );
				}

				onreadystatechange( "abort" );
			};
		} catch(e) { }

		if ( s.async && s.timeout > 0 ) {
			setTimeout(function() {
				if ( xhr && !requestDone ) {
					onreadystatechange( "timeout" );
				}
			}, s.timeout);
		}

		try {
			xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
		} catch(e) {
			jQuery.handleError(s, xhr, null, e);
			complete();
		}

		if ( !s.async ) {
			onreadystatechange();
		}

		function success() {
			if ( s.success ) {
				s.success.call( callbackContext, data, status, xhr );
			}

			if ( s.global ) {
				trigger( "ajaxSuccess", [xhr, s] );
			}
		}

		function complete() {
			if ( s.complete ) {
				s.complete.call( callbackContext, xhr, status);
			}

			if ( s.global ) {
				trigger( "ajaxComplete", [xhr, s] );
			}

			if ( s.global && ! --jQuery.active ) {
				jQuery.event.trigger( "ajaxStop" );
			}
		}

		function trigger(type, args) {
			(s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
		}

		return xhr;
	},

	handleError: function( s, xhr, status, e ) {
		if ( s.error ) {
			s.error.call( s.context || s, xhr, status, e );
		}

		if ( s.global ) {
			(s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
		}
	},

	active: 0,

	httpSuccess: function( xhr ) {
		try {
			return !xhr.status && location.protocol === "file:" ||
				( xhr.status >= 200 && xhr.status < 300 ) ||
				xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
		} catch(e) {}

		return false;
	},

	httpNotModified: function( xhr, url ) {
		var lastModified = xhr.getResponseHeader("Last-Modified"),
			etag = xhr.getResponseHeader("Etag");

		if ( lastModified ) {
			jQuery.lastModified[url] = lastModified;
		}

		if ( etag ) {
			jQuery.etag[url] = etag;
		}

		return xhr.status === 304 || xhr.status === 0;
	},

	httpData: function( xhr, type, s ) {
		var ct = xhr.getResponseHeader("content-type") || "",
			xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
			data = xml ? xhr.responseXML : xhr.responseText;

		if ( xml && data.documentElement.nodeName === "parsererror" ) {
			jQuery.error( "parsererror" );
		}

		if ( s && s.dataFilter ) {
			data = s.dataFilter( data, type );
		}

		if ( typeof data === "string" ) {
			if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
				data = jQuery.parseJSON( data );

			} else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
				jQuery.globalEval( data );
			}
		}

		return data;
	},

	param: function( a, traditional ) {
		var s = [];

		if ( traditional === undefined ) {
			traditional = jQuery.ajaxSettings.traditional;
		}

		if ( jQuery.isArray(a) || a.jquery ) {
			jQuery.each( a, function() {
				add( this.name, this.value );
			});

		} else {
			for ( var prefix in a ) {
				buildParams( prefix, a[prefix] );
			}
		}

		return s.join("&").replace(r20, "+");

		function buildParams( prefix, obj ) {
			if ( jQuery.isArray(obj) ) {
				jQuery.each( obj, function( i, v ) {
					if ( traditional || /\[\]$/.test( prefix ) ) {
						add( prefix, v );
					} else {
						buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
					}
				});

			} else if ( !traditional && obj != null && typeof obj === "object" ) {
				jQuery.each( obj, function( k, v ) {
					buildParams( prefix + "[" + k + "]", v );
				});

			} else {
				add( prefix, obj );
			}
		}

		function add( key, value ) {
			value = jQuery.isFunction(value) ? value() : value;
			s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
		}
	}
});
var elemdisplay = {},
	rfxtypes = /toggle|show|hide/,
	rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
	timerId,
	fxAttrs = [
		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
		[ "opacity" ]
	];

jQuery.fn.extend({
	show: function( speed, callback ) {
		if ( speed || speed === 0) {
			return this.animate( genFx("show", 3), speed, callback);

		} else {
			for ( var i = 0, l = this.length; i < l; i++ ) {
				var old = jQuery.data(this[i], "olddisplay");

				this[i].style.display = old || "";

				if ( jQuery.css(this[i], "display") === "none" ) {
					var nodeName = this[i].nodeName, display;

					if ( elemdisplay[ nodeName ] ) {
						display = elemdisplay[ nodeName ];

					} else {
						var elem = jQuery("<" + nodeName + " />").appendTo("body");

						display = elem.css("display");

						if ( display === "none" ) {
							display = "block";
						}

						elem.remove();

						elemdisplay[ nodeName ] = display;
					}

					jQuery.data(this[i], "olddisplay", display);
				}
			}

			for ( var j = 0, k = this.length; j < k; j++ ) {
				this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
			}

			return this;
		}
	},

	hide: function( speed, callback ) {
		if ( speed || speed === 0 ) {
			return this.animate( genFx("hide", 3), speed, callback);

		} else {
			for ( var i = 0, l = this.length; i < l; i++ ) {
				var old = jQuery.data(this[i], "olddisplay");
				if ( !old && old !== "none" ) {
					jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
				}
			}

			for ( var j = 0, k = this.length; j < k; j++ ) {
				this[j].style.display = "none";
			}

			return this;
		}
	},

	_toggle: jQuery.fn.toggle,

	toggle: function( fn, fn2 ) {
		var bool = typeof fn === "boolean";

		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
			this._toggle.apply( this, arguments );

		} else if ( fn == null || bool ) {
			this.each(function() {
				var state = bool ? fn : jQuery(this).is(":hidden");
				jQuery(this)[ state ? "show" : "hide" ]();
			});

		} else {
			this.animate(genFx("toggle", 3), fn, fn2);
		}

		return this;
	},

	fadeTo: function( speed, to, callback ) {
		return this.filter(":hidden").css("opacity", 0).show().end()
					.animate({opacity: to}, speed, callback);
	},

	animate: function( prop, speed, easing, callback ) {
		var optall = jQuery.speed(speed, easing, callback);

		if ( jQuery.isEmptyObject( prop ) ) {
			return this.each( optall.complete );
		}

		return this[ optall.queue === false ? "each" : "queue" ](function() {
			var opt = jQuery.extend({}, optall), p,
				hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
				self = this;

			for ( p in prop ) {
				var name = p.replace(rdashAlpha, fcamelCase);

				if ( p !== name ) {
					prop[ name ] = prop[ p ];
					delete prop[ p ];
					p = name;
				}

				if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
					return opt.complete.call(this);
				}

				if ( ( p === "height" || p === "width" ) && this.style ) {
					opt.display = jQuery.css(this, "display");

					opt.overflow = this.style.overflow;
				}

				if ( jQuery.isArray( prop[p] ) ) {
					(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
					prop[p] = prop[p][0];
				}
			}

			if ( opt.overflow != null ) {
				this.style.overflow = "hidden";
			}

			opt.curAnim = jQuery.extend({}, prop);

			jQuery.each( prop, function( name, val ) {
				var e = new jQuery.fx( self, opt, name );

				if ( rfxtypes.test(val) ) {
					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );

				} else {
					var parts = rfxnum.exec(val),
						start = e.cur(true) || 0;

					if ( parts ) {
						var end = parseFloat( parts[2] ),
							unit = parts[3] || "px";

						if ( unit !== "px" ) {
							self.style[ name ] = (end || 1) + unit;
							start = ((end || 1) / e.cur(true)) * start;
							self.style[ name ] = start + unit;
						}

						if ( parts[1] ) {
							end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
						}

						e.custom( start, end, unit );

					} else {
						e.custom( start, val, "" );
					}
				}
			});

			return true;
		});
	},

	stop: function( clearQueue, gotoEnd ) {
		var timers = jQuery.timers;

		if ( clearQueue ) {
			this.queue([]);
		}

		this.each(function() {
			for ( var i = timers.length - 1; i >= 0; i-- ) {
				if ( timers[i].elem === this ) {
					if (gotoEnd) {
						timers[i](true);
					}

					timers.splice(i, 1);
				}
			}
		});

		if ( !gotoEnd ) {
			this.dequeue();
		}

		return this;
	}

});

jQuery.each({
	slideDown: genFx("show", 1),
	slideUp: genFx("hide", 1),
	slideToggle: genFx("toggle", 1),
	fadeIn: { opacity: "show" },
	fadeOut: { opacity: "hide" }
}, function( name, props ) {
	jQuery.fn[ name ] = function( speed, callback ) {
		return this.animate( props, speed, callback );
	};
});

jQuery.extend({
	speed: function( speed, easing, fn ) {
		var opt = speed && typeof speed === "object" ? speed : {
			complete: fn || !fn && easing ||
				jQuery.isFunction( speed ) && speed,
			duration: speed,
			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
		};

		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
			jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;

		opt.old = opt.complete;
		opt.complete = function() {
			if ( opt.queue !== false ) {
				jQuery(this).dequeue();
			}
			if ( jQuery.isFunction( opt.old ) ) {
				opt.old.call( this );
			}
		};

		return opt;
	},

	easing: {
		linear: function( p, n, firstNum, diff ) {
			return firstNum + diff * p;
		},
		swing: function( p, n, firstNum, diff ) {
			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
		}
	},

	timers: [],

	fx: function( elem, options, prop ) {
		this.options = options;
		this.elem = elem;
		this.prop = prop;

		if ( !options.orig ) {
			options.orig = {};
		}
	}

});

jQuery.fx.prototype = {
	update: function() {
		if ( this.options.step ) {
			this.options.step.call( this.elem, this.now, this );
		}

		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );

		if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
			this.elem.style.display = "block";
		}
	},

	cur: function( force ) {
		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
			return this.elem[ this.prop ];
		}

		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
	},

	custom: function( from, to, unit ) {
		this.startTime = now();
		this.start = from;
		this.end = to;
		this.unit = unit || this.unit || "px";
		this.now = this.start;
		this.pos = this.state = 0;

		var self = this;
		function t( gotoEnd ) {
			return self.step(gotoEnd);
		}

		t.elem = this.elem;

		if ( t() && jQuery.timers.push(t) && !timerId ) {
			timerId = setInterval(jQuery.fx.tick, 13);
		}
	},

	show: function() {
		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
		this.options.show = true;

		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());

		jQuery( this.elem ).show();
	},

	hide: function() {
		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
		this.options.hide = true;

		this.custom(this.cur(), 0);
	},

	step: function( gotoEnd ) {
		var t = now(), done = true;

		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
			this.now = this.end;
			this.pos = this.state = 1;
			this.update();

			this.options.curAnim[ this.prop ] = true;

			for ( var i in this.options.curAnim ) {
				if ( this.options.curAnim[i] !== true ) {
					done = false;
				}
			}

			if ( done ) {
				if ( this.options.display != null ) {
					this.elem.style.overflow = this.options.overflow;

					var old = jQuery.data(this.elem, "olddisplay");
					this.elem.style.display = old ? old : this.options.display;

					if ( jQuery.css(this.elem, "display") === "none" ) {
						this.elem.style.display = "block";
					}
				}

				if ( this.options.hide ) {
					jQuery(this.elem).hide();
				}

				if ( this.options.hide || this.options.show ) {
					for ( var p in this.options.curAnim ) {
						jQuery.style(this.elem, p, this.options.orig[p]);
					}
				}

				this.options.complete.call( this.elem );
			}

			return false;

		} else {
			var n = t - this.startTime;
			this.state = n / this.options.duration;

			var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
			var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
			this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
			this.now = this.start + ((this.end - this.start) * this.pos);

			this.update();
		}

		return true;
	}
};

jQuery.extend( jQuery.fx, {
	tick: function() {
		var timers = jQuery.timers;

		for ( var i = 0; i < timers.length; i++ ) {
			if ( !timers[i]() ) {
				timers.splice(i--, 1);
			}
		}

		if ( !timers.length ) {
			jQuery.fx.stop();
		}
	},

	stop: function() {
		clearInterval( timerId );
		timerId = null;
	},

	speeds: {
		slow: 600,
 		fast: 200,
 		_default: 400
	},

	step: {
		opacity: function( fx ) {
			jQuery.style(fx.elem, "opacity", fx.now);
		},

		_default: function( fx ) {
			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
			} else {
				fx.elem[ fx.prop ] = fx.now;
			}
		}
	}
});

if ( jQuery.expr && jQuery.expr.filters ) {
	jQuery.expr.filters.animated = function( elem ) {
		return jQuery.grep(jQuery.timers, function( fn ) {
			return elem === fn.elem;
		}).length;
	};
}

function genFx( type, num ) {
	var obj = {};

	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
		obj[ this ] = type;
	});

	return obj;
}
if ( "getBoundingClientRect" in document.documentElement ) {
	jQuery.fn.offset = function( options ) {
		var elem = this[0];

		if ( options ) {
			return this.each(function( i ) {
				jQuery.offset.setOffset( this, options, i );
			});
		}

		if ( !elem || !elem.ownerDocument ) {
			return null;
		}

		if ( elem === elem.ownerDocument.body ) {
			return jQuery.offset.bodyOffset( elem );
		}

		var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
			clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
			top  = box.top  + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
			left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;

		return { top: top, left: left };
	};

} else {
	jQuery.fn.offset = function( options ) {
		var elem = this[0];

		if ( options ) {
			return this.each(function( i ) {
				jQuery.offset.setOffset( this, options, i );
			});
		}

		if ( !elem || !elem.ownerDocument ) {
			return null;
		}

		if ( elem === elem.ownerDocument.body ) {
			return jQuery.offset.bodyOffset( elem );
		}

		jQuery.offset.initialize();

		var offsetParent = elem.offsetParent, prevOffsetParent = elem,
			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
			body = doc.body, defaultView = doc.defaultView,
			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
			top = elem.offsetTop, left = elem.offsetLeft;

		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
				break;
			}

			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
			top  -= elem.scrollTop;
			left -= elem.scrollLeft;

			if ( elem === offsetParent ) {
				top  += elem.offsetTop;
				left += elem.offsetLeft;

				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
				}

				prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
			}

			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
			}

			prevComputedStyle = computedStyle;
		}

		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
			top  += body.offsetTop;
			left += body.offsetLeft;
		}

		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
			top  += Math.max( docElem.scrollTop, body.scrollTop );
			left += Math.max( docElem.scrollLeft, body.scrollLeft );
		}

		return { top: top, left: left };
	};
}

jQuery.offset = {
	initialize: function() {
		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";

		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );

		container.innerHTML = html;
		body.insertBefore( container, body.firstChild );
		innerDiv = container.firstChild;
		checkDiv = innerDiv.firstChild;
		td = innerDiv.nextSibling.firstChild.firstChild;

		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);

		checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
		checkDiv.style.position = checkDiv.style.top = "";

		innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);

		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);

		body.removeChild( container );
		body = container = innerDiv = checkDiv = table = td = null;
		jQuery.offset.initialize = jQuery.noop;
	},

	bodyOffset: function( body ) {
		var top = body.offsetTop, left = body.offsetLeft;

		jQuery.offset.initialize();

		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
			top  += parseFloat( jQuery.curCSS(body, "marginTop",  true) ) || 0;
			left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
		}

		return { top: top, left: left };
	},

	setOffset: function( elem, options, i ) {
		if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
			elem.style.position = "relative";
		}
		var curElem   = jQuery( elem ),
			curOffset = curElem.offset(),
			curTop    = parseInt( jQuery.curCSS( elem, "top",  true ), 10 ) || 0,
			curLeft   = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;

		if ( jQuery.isFunction( options ) ) {
			options = options.call( elem, i, curOffset );
		}

		var props = {
			top:  (options.top  - curOffset.top)  + curTop,
			left: (options.left - curOffset.left) + curLeft
		};

		if ( "using" in options ) {
			options.using.call( elem, props );
		} else {
			curElem.css( props );
		}
	}
};


jQuery.fn.extend({
	position: function() {
		if ( !this[0] ) {
			return null;
		}

		var elem = this[0],

		offsetParent = this.offsetParent(),

		offset       = this.offset(),
		parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();

		offset.top  -= parseFloat( jQuery.curCSS(elem, "marginTop",  true) ) || 0;
		offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;

		parentOffset.top  += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth",  true) ) || 0;
		parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;

		return {
			top:  offset.top  - parentOffset.top,
			left: offset.left - parentOffset.left
		};
	},

	offsetParent: function() {
		return this.map(function() {
			var offsetParent = this.offsetParent || document.body;
			while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
				offsetParent = offsetParent.offsetParent;
			}
			return offsetParent;
		});
	}
});


jQuery.each( ["Left", "Top"], function( i, name ) {
	var method = "scroll" + name;

	jQuery.fn[ method ] = function(val) {
		var elem = this[0], win;

		if ( !elem ) {
			return null;
		}

		if ( val !== undefined ) {
			return this.each(function() {
				win = getWindow( this );

				if ( win ) {
					win.scrollTo(
						!i ? val : jQuery(win).scrollLeft(),
						 i ? val : jQuery(win).scrollTop()
					);

				} else {
					this[ method ] = val;
				}
			});
		} else {
			win = getWindow( elem );

			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
				jQuery.support.boxModel && win.document.documentElement[ method ] ||
					win.document.body[ method ] :
				elem[ method ];
		}
	};
});

function getWindow( elem ) {
	return ("scrollTo" in elem && elem.document) ?
		elem :
		elem.nodeType === 9 ?
			elem.defaultView || elem.parentWindow :
			false;
}
jQuery.each([ "Height", "Width" ], function( i, name ) {

	var type = name.toLowerCase();

	jQuery.fn["inner" + name] = function() {
		return this[0] ?
			jQuery.css( this[0], type, false, "padding" ) :
			null;
	};

	jQuery.fn["outer" + name] = function( margin ) {
		return this[0] ?
			jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
			null;
	};

	jQuery.fn[ type ] = function( size ) {
		var elem = this[0];
		if ( !elem ) {
			return size == null ? null : this;
		}

		if ( jQuery.isFunction( size ) ) {
			return this.each(function( i ) {
				var self = jQuery( this );
				self[ type ]( size.call( this, i, self[ type ]() ) );
			});
		}

		return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
			elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
			elem.document.body[ "client" + name ] :

			(elem.nodeType === 9) ? // is it a document
				Math.max(
					elem.documentElement["client" + name],
					elem.body["scroll" + name], elem.documentElement["scroll" + name],
					elem.body["offset" + name], elem.documentElement["offset" + name]
				) :

				size === undefined ?
					jQuery.css( elem, type ) :

					this.css( type, typeof size === "string" ? size : size + "px" );
	};

});
window.jQuery = window.$ = jQuery;

})(window);
/*	SWFObject v2.2 <http://code.google.com/p/swfobject/>
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
/*
 * jQuery Form Plugin
 * version: 2.40 (26-FEB-2010)
 * @requires jQuery v1.3.2 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */
;(function($) {

/*
	Usage Note:
	-----------
	Do not use both ajaxSubmit and ajaxForm on the same form.  These
	functions are intended to be exclusive.  Use ajaxSubmit if you want
	to bind your own submit handler to the form.  For example,

	$(document).ready(function() {
		$('#myForm').bind('submit', function() {
			$(this).ajaxSubmit({
				target: '#output'
			});
			return false; // <-- important!
		});
	});

	Use ajaxForm when you want the plugin to manage all the event binding
	for you.  For example,

	$(document).ready(function() {
		$('#myForm').ajaxForm({
			target: '#output'
		});
	});

	When using ajaxForm, the ajaxSubmit function will be invoked for you
	at the appropriate time.
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
	if (!this.length) {
		log('ajaxSubmit: skipping submit process - no element selected');
		return this;
	}

	if (typeof options == 'function')
		options = { success: options };

	var url = $.trim(this.attr('action'));
	if (url) {
		url = (url.match(/^([^#]+)/)||[])[1];
   	}
   	url = url || window.location.href || '';

	options = $.extend({
		url:  url,
		type: this.attr('method') || 'GET',
		iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
	}, options || {});

	var veto = {};
	this.trigger('form-pre-serialize', [this, options, veto]);
	if (veto.veto) {
		log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
		return this;
	}

	if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
		log('ajaxSubmit: submit aborted via beforeSerialize callback');
		return this;
	}

	var a = this.formToArray(options.semantic);
	if (options.data) {
		options.extraData = options.data;
		for (var n in options.data) {
		  if(options.data[n] instanceof Array) {
			for (var k in options.data[n])
			  a.push( { name: n, value: options.data[n][k] } );
		  }
		  else
			 a.push( { name: n, value: options.data[n] } );
		}
	}

	if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
		log('ajaxSubmit: submit aborted via beforeSubmit callback');
		return this;
	}

	this.trigger('form-submit-validate', [a, this, options, veto]);
	if (veto.veto) {
		log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
		return this;
	}

	var q = $.param(a);

	if (options.type.toUpperCase() == 'GET') {
		options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
		options.data = null;  // data is null for 'get'
	}
	else
		options.data = q; // data is the query string for 'post'

	var $form = this, callbacks = [];
	if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
	if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

	if (!options.dataType && options.target) {
		var oldSuccess = options.success || function(){};
		callbacks.push(function(data) {
			$(options.target).html(data).each(oldSuccess, arguments);
		});
	}
	else if (options.success)
		callbacks.push(options.success);

	options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
		for (var i=0, max=callbacks.length; i < max; i++)
			callbacks[i].apply(options, [data, status, xhr || $form, $form]);
	};

	var files = $('input:file', this).fieldValue();
	var found = false;
	for (var j=0; j < files.length; j++)
		if (files[j])
			found = true;

	var multipart = false;

   if ((files.length && options.iframe !== false) || options.iframe || found || multipart) {
	   if (options.closeKeepAlive)
		   $.get(options.closeKeepAlive, fileUpload);
	   else
		   fileUpload();
	   }
   else
	   $.ajax(options);

	this.trigger('form-submit-notify', [this, options]);
	return this;


	function fileUpload() {
		var form = $form[0];

		if ($(':input[name=submit]', form).length) {
			alert('Error: Form elements must not be named "submit".');
			return;
		}

		var opts = $.extend({}, $.ajaxSettings, options);
		var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);

		var id = 'jqFormIO' + (new Date().getTime());
		var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ opts.iframeSrc +'" onload="(jQuery(this).data(\'form-plugin-onload\'))()" />');
		var io = $io[0];

		$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

		var xhr = { // mock object
			aborted: 0,
			responseText: null,
			responseXML: null,
			status: 0,
			statusText: 'n/a',
			getAllResponseHeaders: function() {},
			getResponseHeader: function() {},
			setRequestHeader: function() {},
			abort: function() {
				this.aborted = 1;
				$io.attr('src', opts.iframeSrc); // abort op in progress
			}
		};

		var g = opts.global;
		if (g && ! $.active++) $.event.trigger("ajaxStart");
		if (g) $.event.trigger("ajaxSend", [xhr, opts]);

		if (s.beforeSend && s.beforeSend(xhr, s) === false) {
			s.global && $.active--;
			return;
		}
		if (xhr.aborted)
			return;

		var cbInvoked = false;
		var timedOut = 0;

		var sub = form.clk;
		if (sub) {
			var n = sub.name;
			if (n && !sub.disabled) {
				opts.extraData = opts.extraData || {};
				opts.extraData[n] = sub.value;
				if (sub.type == "image") {
					opts.extraData[name+'.x'] = form.clk_x;
					opts.extraData[name+'.y'] = form.clk_y;
				}
			}
		}

		function doSubmit() {
			var t = $form.attr('target'), a = $form.attr('action');

			form.setAttribute('target',id);
			if (form.getAttribute('method') != 'POST')
				form.setAttribute('method', 'POST');
			if (form.getAttribute('action') != opts.url)
				form.setAttribute('action', opts.url);

			if (! opts.skipEncodingOverride) {
				$form.attr({
					encoding: 'multipart/form-data',
					enctype:  'multipart/form-data'
				});
			}

			if (opts.timeout)
				setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

			var extraInputs = [];
			try {
				if (opts.extraData)
					for (var n in opts.extraData)
						extraInputs.push(
							$('<input type="hidden" name="'+n+'" value="'+opts.extraData[n]+'" />')
								.appendTo(form)[0]);

				$io.appendTo('body');
				$io.data('form-plugin-onload', cb);
				form.submit();
			}
			finally {
				form.setAttribute('action',a);
				t ? form.setAttribute('target', t) : $form.removeAttr('target');
				$(extraInputs).remove();
			}
		};

		if (opts.forceSync)
			doSubmit();
		else
			setTimeout(doSubmit, 10); // this lets dom updates render

		var domCheckCount = 100;

		function cb() {
			if (cbInvoked)
				return;

			var ok = true;
			try {
				if (timedOut) throw 'timeout';
				var data, doc;

				doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;

				var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
				log('isXml='+isXml);
				if (!isXml && (doc.body == null || doc.body.innerHTML == '')) {
				 	if (--domCheckCount) {
						setTimeout(cb, 250);
						return;
					}
					log('Could not access iframe DOM after 100 tries.');
					return;
				}

				cbInvoked = true;
				xhr.responseText = doc.body ? doc.body.innerHTML : null;
				xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
				xhr.getResponseHeader = function(header){
					var headers = {'content-type': opts.dataType};
					return headers[header];
				};

				if (opts.dataType == 'json' || opts.dataType == 'script') {
					var ta = doc.getElementsByTagName('textarea')[0];
					if (ta)
						xhr.responseText = ta.value;
					else {
						var pre = doc.getElementsByTagName('pre')[0];
						if (pre)
							xhr.responseText = pre.innerHTML;
					}
				}
				else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
					xhr.responseXML = toXml(xhr.responseText);
				}
				data = $.httpData(xhr, opts.dataType);
			}
			catch(e){
				ok = false;
				$.handleError(opts, xhr, 'error', e);
			}

			if (ok) {
				opts.success(data, 'success');
				if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
			}
			if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
			if (g && ! --$.active) $.event.trigger("ajaxStop");
			if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

			setTimeout(function() {
				$io.removeData('form-plugin-onload');
				$io.remove();
				xhr.responseXML = null;
			}, 100);
		};

		function toXml(s, doc) {
			if (window.ActiveXObject) {
				doc = new ActiveXObject('Microsoft.XMLDOM');
				doc.async = 'false';
				doc.loadXML(s);
			}
			else
				doc = (new DOMParser()).parseFromString(s, 'text/xml');
			return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
		};
	};
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *	is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *	used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */
$.fn.ajaxForm = function(options) {
	return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
		e.preventDefault();
		$(this).ajaxSubmit(options);
	}).bind('click.form-plugin', function(e) {
		var target = e.target;
		var $el = $(target);
		if (!($el.is(":submit,input:image"))) {
			var t = $el.closest(':submit');
			if (t.length == 0)
				return;
			target = t[0];
		}
		var form = this;
		form.clk = target;
		if (target.type == 'image') {
			if (e.offsetX != undefined) {
				form.clk_x = e.offsetX;
				form.clk_y = e.offsetY;
			} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
				var offset = $el.offset();
				form.clk_x = e.pageX - offset.left;
				form.clk_y = e.pageY - offset.top;
			} else {
				form.clk_x = e.pageX - target.offsetLeft;
				form.clk_y = e.pageY - target.offsetTop;
			}
		}
		setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
	});
};

$.fn.ajaxFormUnbind = function() {
	return this.unbind('submit.form-plugin click.form-plugin');
};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
	var a = [];
	if (this.length == 0) return a;

	var form = this[0];
	var els = semantic ? form.getElementsByTagName('*') : form.elements;
	if (!els) return a;
	for(var i=0, max=els.length; i < max; i++) {
		var el = els[i];
		var n = el.name;
		if (!n) continue;

		if (semantic && form.clk && el.type == "image") {
			if(!el.disabled && form.clk == el) {
				a.push({name: n, value: $(el).val()});
				a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
			}
			continue;
		}

		var v = $.fieldValue(el, true);
		if (v && v.constructor == Array) {
			for(var j=0, jmax=v.length; j < jmax; j++)
				a.push({name: n, value: v[j]});
		}
		else if (v !== null && typeof v != 'undefined')
			a.push({name: n, value: v});
	}

	if (!semantic && form.clk) {
		var $input = $(form.clk), input = $input[0], n = input.name;
		if (n && !input.disabled && input.type == 'image') {
			a.push({name: n, value: $input.val()});
			a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
		}
	}
	return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
	return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
	var a = [];
	this.each(function() {
		var n = this.name;
		if (!n) return;
		var v = $.fieldValue(this, successful);
		if (v && v.constructor == Array) {
			for (var i=0,max=v.length; i < max; i++)
				a.push({name: n, value: v[i]});
		}
		else if (v !== null && typeof v != 'undefined')
			a.push({name: this.name, value: v});
	});
	return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *	  <input name="A" type="text" />
 *	  <input name="A" type="text" />
 *	  <input name="B" type="checkbox" value="B1" />
 *	  <input name="B" type="checkbox" value="B2"/>
 *	  <input name="C" type="radio" value="C1" />
 *	  <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *	   array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
	for (var val=[], i=0, max=this.length; i < max; i++) {
		var el = this[i];
		var v = $.fieldValue(el, successful);
		if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
			continue;
		v.constructor == Array ? $.merge(val, v) : val.push(v);
	}
	return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
	var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
	if (typeof successful == 'undefined') successful = true;

	if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
		(t == 'checkbox' || t == 'radio') && !el.checked ||
		(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
		tag == 'select' && el.selectedIndex == -1))
			return null;

	if (tag == 'select') {
		var index = el.selectedIndex;
		if (index < 0) return null;
		var a = [], ops = el.options;
		var one = (t == 'select-one');
		var max = (one ? index+1 : ops.length);
		for(var i=(one ? index : 0); i < max; i++) {
			var op = ops[i];
			if (op.selected) {
				var v = op.value;
				if (!v) // extra pain for IE...
					v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
				if (one) return v;
				a.push(v);
			}
		}
		return a;
	}
	return el.value;
};

/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
	return this.each(function() {
		$('input,select,textarea', this).clearFields();
	});
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
	return this.each(function() {
		var t = this.type, tag = this.tagName.toLowerCase();
		if (t == 'text' || t == 'password' || tag == 'textarea')
			this.value = '';
		else if (t == 'checkbox' || t == 'radio')
			this.checked = false;
		else if (tag == 'select')
			this.selectedIndex = -1;
	});
};

/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
	return this.each(function() {
		if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
			this.reset();
	});
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) {
	if (b == undefined) b = true;
	return this.each(function() {
		this.disabled = !b;
	});
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
	if (select == undefined) select = true;
	return this.each(function() {
		var t = this.type;
		if (t == 'checkbox' || t == 'radio')
			this.checked = select;
		else if (this.tagName.toLowerCase() == 'option') {
			var $sel = $(this).parent('select');
			if (select && $sel[0] && $sel[0].type == 'select-one') {
				$sel.find('option').selected(false);
			}
			this.selected = select;
		}
	});
};

function log() {
	if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
		window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};

})(jQuery);
/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-10-06T18:11:15.103402Z $
 * $Rev: 4893 $
 *
 * Version: @VERSION
 *
 * Requires: jQuery 1.2+
 */

(function($){

$.dimensions = {
	version: '@VERSION'
};

$.each( [ 'Height', 'Width' ], function(i, name){

	$.fn[ 'inner' + name ] = function() {
		if (!this[0]) return;

		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right

		return num( this, name.toLowerCase() ) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
	};

	$.fn[ 'outer' + name ] = function(options) {
		if (!this[0]) return;

		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right

		options = $.extend({ margin: false }, options || {});

		return num( this, name.toLowerCase() )
				+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
				+ num(this, 'padding' + torl) + num(this, 'padding' + borr)
				+ (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
	};
});

$.each( ['Left', 'Top'], function(i, name) {
	$.fn[ 'scroll' + name ] = function(val) {
		if (!this[0]) return;

		return val != undefined ?

			this.each(function() {
				this == window || this == document ?
					window.scrollTo(
						name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
						name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
					) :
					this[ 'scroll' + name ] = val;
			}) :

			this[0] == window || this[0] == document ?
				self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
					$.boxModel && document.documentElement[ 'scroll' + name ] ||
					document.body[ 'scroll' + name ] :
				this[0][ 'scroll' + name ];
	};
});

$.fn.extend({
	position: function() {
		var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;

		if (elem) {
			offsetParent = this.offsetParent();

			offset       = this.offset();
			parentOffset = offsetParent.offset();

			offset.top  -= num(elem, 'marginTop');
			offset.left -= num(elem, 'marginLeft');

			parentOffset.top  += num(offsetParent, 'borderTopWidth');
			parentOffset.left += num(offsetParent, 'borderLeftWidth');

			results = {
				top:  offset.top  - parentOffset.top,
				left: offset.left - parentOffset.left
			};
		}

		return results;
	},

	offsetParent: function() {
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent);
	}
});

function num(el, prop) {
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

})(jQuery);
/*
 * jQuery UI 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
;jQuery.ui || (function($) {

var _remove = $.fn.remove,
	isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);

$.ui = {
	version: "1.7.2",

	plugin: {
		add: function(module, option, set) {
			var proto = $.ui[module].prototype;
			for(var i in set) {
				proto.plugins[i] = proto.plugins[i] || [];
				proto.plugins[i].push([option, set[i]]);
			}
		},
		call: function(instance, name, args) {
			var set = instance.plugins[name];
			if(!set || !instance.element[0].parentNode) { return; }

			for (var i = 0; i < set.length; i++) {
				if (instance.options[set[i][0]]) {
					set[i][1].apply(instance.element, args);
				}
			}
		}
	},

	contains: function(a, b) {
		return document.compareDocumentPosition
			? a.compareDocumentPosition(b) & 16
			: a !== b && a.contains(b);
	},

	hasScroll: function(el, a) {

		if ($(el).css('overflow') == 'hidden') { return false; }

		var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
			has = false;

		if (el[scroll] > 0) { return true; }

		el[scroll] = 1;
		has = (el[scroll] > 0);
		el[scroll] = 0;
		return has;
	},

	isOverAxis: function(x, reference, size) {
		return (x > reference) && (x < (reference + size));
	},

	isOver: function(y, x, top, left, height, width) {
		return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
	},

	keyCode: {
		BACKSPACE: 8,
		CAPS_LOCK: 20,
		COMMA: 188,
		CONTROL: 17,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		INSERT: 45,
		LEFT: 37,
		NUMPAD_ADD: 107,
		NUMPAD_DECIMAL: 110,
		NUMPAD_DIVIDE: 111,
		NUMPAD_ENTER: 108,
		NUMPAD_MULTIPLY: 106,
		NUMPAD_SUBTRACT: 109,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SHIFT: 16,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
};

if (isFF2) {
	var attr = $.attr,
		removeAttr = $.fn.removeAttr,
		ariaNS = "http://www.w3.org/2005/07/aaa",
		ariaState = /^aria-/,
		ariaRole = /^wairole:/;

	$.attr = function(elem, name, value) {
		var set = value !== undefined;

		return (name == 'role'
			? (set
				? attr.call(this, elem, name, "wairole:" + value)
				: (attr.apply(this, arguments) || "").replace(ariaRole, ""))
			: (ariaState.test(name)
				? (set
					? elem.setAttributeNS(ariaNS,
						name.replace(ariaState, "aaa:"), value)
					: attr.call(this, elem, name.replace(ariaState, "aaa:")))
				: attr.apply(this, arguments)));
	};

	$.fn.removeAttr = function(name) {
		return (ariaState.test(name)
			? this.each(function() {
				this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
			}) : removeAttr.call(this, name));
	};
}

$.fn.extend({
	remove: function() {
		$("*", this).add(this).each(function() {
			$(this).triggerHandler("remove");
		});
		return _remove.apply(this, arguments );
	},

	enableSelection: function() {
		return this
			.attr('unselectable', 'off')
			.css('MozUserSelect', '')
			.unbind('selectstart.ui');
	},

	disableSelection: function() {
		return this
			.attr('unselectable', 'on')
			.css('MozUserSelect', 'none')
			.bind('selectstart.ui', function() { return false; });
	},

	scrollParent: function() {
		var scrollParent;
		if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
			scrollParent = this.parents().filter(function() {
				return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		} else {
			scrollParent = this.parents().filter(function() {
				return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		}

		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
	}
});


$.extend($.expr[':'], {
	data: function(elem, i, match) {
		return !!$.data(elem, match[3]);
	},

	focusable: function(element) {
		var nodeName = element.nodeName.toLowerCase(),
			tabIndex = $.attr(element, 'tabindex');
		return (/input|select|textarea|button|object/.test(nodeName)
			? !element.disabled
			: 'a' == nodeName || 'area' == nodeName
				? element.href || !isNaN(tabIndex)
				: !isNaN(tabIndex))
			&& !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
	},

	tabbable: function(element) {
		var tabIndex = $.attr(element, 'tabindex');
		return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
	}
});


function getter(namespace, plugin, method, args) {
	function getMethods(type) {
		var methods = $[namespace][plugin][type] || [];
		return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
	}

	var methods = getMethods('getter');
	if (args.length == 1 && typeof args[0] == 'string') {
		methods = methods.concat(getMethods('getterSetter'));
	}
	return ($.inArray(method, methods) != -1);
}

$.widget = function(name, prototype) {
	var namespace = name.split(".")[0];
	name = name.split(".")[1];

	$.fn[name] = function(options) {
		var isMethodCall = (typeof options == 'string'),
			args = Array.prototype.slice.call(arguments, 1);

		if (isMethodCall && options.substring(0, 1) == '_') {
			return this;
		}

		if (isMethodCall && getter(namespace, name, options, args)) {
			var instance = $.data(this[0], name);
			return (instance ? instance[options].apply(instance, args)
				: undefined);
		}

		return this.each(function() {
			var instance = $.data(this, name);

			(!instance && !isMethodCall &&
				$.data(this, name, new $[namespace][name](this, options))._init());

			(instance && isMethodCall && $.isFunction(instance[options]) &&
				instance[options].apply(instance, args));
		});
	};

	$[namespace] = $[namespace] || {};
	$[namespace][name] = function(element, options) {
		var self = this;

		this.namespace = namespace;
		this.widgetName = name;
		this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
		this.widgetBaseClass = namespace + '-' + name;

		this.options = $.extend({},
			$.widget.defaults,
			$[namespace][name].defaults,
			$.metadata && $.metadata.get(element)[name],
			options);

		this.element = $(element)
			.bind('setData.' + name, function(event, key, value) {
				if (event.target == element) {
					return self._setData(key, value);
				}
			})
			.bind('getData.' + name, function(event, key) {
				if (event.target == element) {
					return self._getData(key);
				}
			})
			.bind('remove', function() {
				return self.destroy();
			});
	};

	$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);

	$[namespace][name].getterSetter = 'option';
};

$.widget.prototype = {
	_init: function() {},
	destroy: function() {
		this.element.removeData(this.widgetName)
			.removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
			.removeAttr('aria-disabled');
	},

	option: function(key, value) {
		var options = key,
			self = this;

		if (typeof key == "string") {
			if (value === undefined) {
				return this._getData(key);
			}
			options = {};
			options[key] = value;
		}

		$.each(options, function(key, value) {
			self._setData(key, value);
		});
	},
	_getData: function(key) {
		return this.options[key];
	},
	_setData: function(key, value) {
		this.options[key] = value;

		if (key == 'disabled') {
			this.element
				[value ? 'addClass' : 'removeClass'](
					this.widgetBaseClass + '-disabled' + ' ' +
					this.namespace + '-state-disabled')
				.attr("aria-disabled", value);
		}
	},

	enable: function() {
		this._setData('disabled', false);
	},
	disable: function() {
		this._setData('disabled', true);
	},

	_trigger: function(type, event, data) {
		var callback = this.options[type],
			eventName = (type == this.widgetEventPrefix
				? type : this.widgetEventPrefix + type);

		event = $.Event(event);
		event.type = eventName;

		if (event.originalEvent) {
			for (var i = $.event.props.length, prop; i;) {
				prop = $.event.props[--i];
				event[prop] = event.originalEvent[prop];
			}
		}

		this.element.trigger(event, data);

		return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
			|| event.isDefaultPrevented());
	}
};

$.widget.defaults = {
	disabled: false
};



$.ui.mouse = {
	_mouseInit: function() {
		var self = this;

		this.element
			.bind('mousedown.'+this.widgetName, function(event) {
				return self._mouseDown(event);
			})
			.bind('click.'+this.widgetName, function(event) {
				if(self._preventClickEvent) {
					self._preventClickEvent = false;
					event.stopImmediatePropagation();
					return false;
				}
			});

		if ($.browser.msie) {
			this._mouseUnselectable = this.element.attr('unselectable');
			this.element.attr('unselectable', 'on');
		}

		this.started = false;
	},

	_mouseDestroy: function() {
		this.element.unbind('.'+this.widgetName);

		($.browser.msie
			&& this.element.attr('unselectable', this._mouseUnselectable));
	},

	_mouseDown: function(event) {
		event.originalEvent = event.originalEvent || {};
		if (event.originalEvent.mouseHandled) { return; }

		(this._mouseStarted && this._mouseUp(event));

		this._mouseDownEvent = event;

		var self = this,
			btnIsLeft = (event.which == 1),
			elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
			return true;
		}

		this.mouseDelayMet = !this.options.delay;
		if (!this.mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				self.mouseDelayMet = true;
			}, this.options.delay);
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted = (this._mouseStart(event) !== false);
			if (!this._mouseStarted) {
				event.preventDefault();
				return true;
			}
		}

		this._mouseMoveDelegate = function(event) {
			return self._mouseMove(event);
		};
		this._mouseUpDelegate = function(event) {
			return self._mouseUp(event);
		};
		$(document)
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		($.browser.safari || event.preventDefault());

		event.originalEvent.mouseHandled = true;
		return true;
	},

	_mouseMove: function(event) {
		if ($.browser.msie && !event.button) {
			return this._mouseUp(event);
		}

		if (this._mouseStarted) {
			this._mouseDrag(event);
			return event.preventDefault();
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted =
				(this._mouseStart(this._mouseDownEvent, event) !== false);
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
		}

		return !this._mouseStarted;
	},

	_mouseUp: function(event) {
		$(document)
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		if (this._mouseStarted) {
			this._mouseStarted = false;
			this._preventClickEvent = (event.target == this._mouseDownEvent.target);
			this._mouseStop(event);
		}

		return false;
	},

	_mouseDistanceMet: function(event) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
			) >= this.options.distance
		);
	},

	_mouseDelayMet: function(event) {
		return this.mouseDelayMet;
	},

	_mouseStart: function(event) {},
	_mouseDrag: function(event) {},
	_mouseStop: function(event) {},
	_mouseCapture: function(event) { return true; }
};

$.ui.mouse.defaults = {
	cancel: null,
	distance: 1,
	delay: 0
};

})(jQuery);
/*
 * jQuery UI Slider 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Slider
 *
 * Depends:
 *	ui.core.js
 */

(function($) {

$.widget("ui.slider", $.extend({}, $.ui.mouse, {

	_init: function() {

		var self = this, o = this.options;
		this._keySliding = false;
		this._handleIndex = null;
		this._detectOrientation();
		this._mouseInit();

		this.element
			.addClass("ui-slider"
				+ " ui-slider-" + this.orientation
				+ " ui-widget"
				+ " ui-widget-content"
				+ " ui-corner-all");

		this.range = $([]);

		if (o.range) {

			if (o.range === true) {
				this.range = $('<div></div>');
				if (!o.values) o.values = [this._valueMin(), this._valueMin()];
				if (o.values.length && o.values.length != 2) {
					o.values = [o.values[0], o.values[0]];
				}
			} else {
				this.range = $('<div></div>');
			}

			this.range
				.appendTo(this.element)
				.addClass("ui-slider-range");

			if (o.range == "min" || o.range == "max") {
				this.range.addClass("ui-slider-range-" + o.range);
			}

			this.range.addClass("ui-widget-header");

		}

		if ($(".ui-slider-handle", this.element).length == 0)
			$('<a href="#"></a>')
				.appendTo(this.element)
				.addClass("ui-slider-handle");

		if (o.values && o.values.length) {
			while ($(".ui-slider-handle", this.element).length < o.values.length)
				$('<a href="#"></a>')
					.appendTo(this.element)
					.addClass("ui-slider-handle");
		}

		this.handles = $(".ui-slider-handle", this.element)
			.addClass("ui-state-default"
				+ " ui-corner-all");

		this.handle = this.handles.eq(0);

		this.handles.add(this.range).filter("a")
			.click(function(event) {
				event.preventDefault();
			})
			.hover(function() {
				if (!o.disabled) {
					$(this).addClass('ui-state-hover');
				}
			}, function() {
				$(this).removeClass('ui-state-hover');
			})
			.focus(function() {
				if (!o.disabled) {
					$(".ui-slider .ui-state-focus").removeClass('ui-state-focus'); $(this).addClass('ui-state-focus');
				} else {
					$(this).blur();
				}
			})
			.blur(function() {
				$(this).removeClass('ui-state-focus');
			});

		this.handles.each(function(i) {
			$(this).data("index.ui-slider-handle", i);
		});

		this.handles.keydown(function(event) {

			var ret = true;

			var index = $(this).data("index.ui-slider-handle");

			if (self.options.disabled)
				return;

			switch (event.keyCode) {
				case $.ui.keyCode.HOME:
				case $.ui.keyCode.END:
				case $.ui.keyCode.UP:
				case $.ui.keyCode.RIGHT:
				case $.ui.keyCode.DOWN:
				case $.ui.keyCode.LEFT:
					ret = false;
					if (!self._keySliding) {
						self._keySliding = true;
						$(this).addClass("ui-state-active");
						self._start(event, index);
					}
					break;
			}

			var curVal, newVal, step = self._step();
			if (self.options.values && self.options.values.length) {
				curVal = newVal = self.values(index);
			} else {
				curVal = newVal = self.value();
			}

			switch (event.keyCode) {
				case $.ui.keyCode.HOME:
					newVal = self._valueMin();
					break;
				case $.ui.keyCode.END:
					newVal = self._valueMax();
					break;
				case $.ui.keyCode.UP:
				case $.ui.keyCode.RIGHT:
					if(curVal == self._valueMax()) return;
					newVal = curVal + step;
					break;
				case $.ui.keyCode.DOWN:
				case $.ui.keyCode.LEFT:
					if(curVal == self._valueMin()) return;
					newVal = curVal - step;
					break;
			}

			self._slide(event, index, newVal);

			return ret;

		}).keyup(function(event) {

			var index = $(this).data("index.ui-slider-handle");

			if (self._keySliding) {
				self._stop(event, index);
				self._change(event, index);
				self._keySliding = false;
				$(this).removeClass("ui-state-active");
			}

		});

		this._refreshValue();

	},

	destroy: function() {

		this.handles.remove();
		this.range.remove();

		this.element
			.removeClass("ui-slider"
				+ " ui-slider-horizontal"
				+ " ui-slider-vertical"
				+ " ui-slider-disabled"
				+ " ui-widget"
				+ " ui-widget-content"
				+ " ui-corner-all")
			.removeData("slider")
			.unbind(".slider");

		this._mouseDestroy();

	},

	_mouseCapture: function(event) {

		var o = this.options;

		if (o.disabled)
			return false;

		this.elementSize = {
			width: this.element.outerWidth(),
			height: this.element.outerHeight()
		};
		this.elementOffset = this.element.offset();

		var position = { x: event.pageX, y: event.pageY };
		var normValue = this._normValueFromMouse(position);

		var distance = this._valueMax() - this._valueMin() + 1, closestHandle;
		var self = this, index;
		this.handles.each(function(i) {
			var thisDistance = Math.abs(normValue - self.values(i));
			if (distance > thisDistance) {
				distance = thisDistance;
				closestHandle = $(this);
				index = i;
			}
		});

		if(o.range == true && this.values(1) == o.min) {
			closestHandle = $(this.handles[++index]);
		}

		this._start(event, index);

		self._handleIndex = index;

		closestHandle
			.addClass("ui-state-active")
			.focus();

		var offset = closestHandle.offset();
		var mouseOverHandle = !$(event.target).parents().andSelf().is('.ui-slider-handle');
		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
			left: event.pageX - offset.left - (closestHandle.width() / 2),
			top: event.pageY - offset.top
				- (closestHandle.height() / 2)
				- (parseInt(closestHandle.css('borderTopWidth'),10) || 0)
				- (parseInt(closestHandle.css('borderBottomWidth'),10) || 0)
				+ (parseInt(closestHandle.css('marginTop'),10) || 0)
		};

		normValue = this._normValueFromMouse(position);
		this._slide(event, index, normValue);
		return true;

	},

	_mouseStart: function(event) {
		return true;
	},

	_mouseDrag: function(event) {

		var position = { x: event.pageX, y: event.pageY };
		var normValue = this._normValueFromMouse(position);

		this._slide(event, this._handleIndex, normValue);

		return false;

	},

	_mouseStop: function(event) {

		this.handles.removeClass("ui-state-active");
		this._stop(event, this._handleIndex);
		this._change(event, this._handleIndex);
		this._handleIndex = null;
		this._clickOffset = null;

		return false;

	},

	_detectOrientation: function() {
		this.orientation = this.options.orientation == 'vertical' ? 'vertical' : 'horizontal';
	},

	_normValueFromMouse: function(position) {

		var pixelTotal, pixelMouse;
		if ('horizontal' == this.orientation) {
			pixelTotal = this.elementSize.width;
			pixelMouse = position.x - this.elementOffset.left - (this._clickOffset ? this._clickOffset.left : 0);
		} else {
			pixelTotal = this.elementSize.height;
			pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0);
		}

		var percentMouse = (pixelMouse / pixelTotal);
		if (percentMouse > 1) percentMouse = 1;
		if (percentMouse < 0) percentMouse = 0;
		if ('vertical' == this.orientation)
			percentMouse = 1 - percentMouse;

		var valueTotal = this._valueMax() - this._valueMin(),
			valueMouse = percentMouse * valueTotal,
			valueMouseModStep = valueMouse % this.options.step,
			normValue = this._valueMin() + valueMouse - valueMouseModStep;

		if (valueMouseModStep > (this.options.step / 2))
			normValue += this.options.step;

		return parseFloat(normValue.toFixed(5));

	},

	_start: function(event, index) {
		var uiHash = {
			handle: this.handles[index],
			value: this.value()
		};
		if (this.options.values && this.options.values.length) {
			uiHash.value = this.values(index);
			uiHash.values = this.values();
		}
		this._trigger("start", event, uiHash);
	},

	_slide: function(event, index, newVal) {

		var handle = this.handles[index];

		if (this.options.values && this.options.values.length) {

			var otherVal = this.values(index ? 0 : 1);

			if ((this.options.values.length == 2 && this.options.range === true) &&
				((index == 0 && newVal > otherVal) || (index == 1 && newVal < otherVal))){
 				newVal = otherVal;
			}

			if (newVal != this.values(index)) {
				var newValues = this.values();
				newValues[index] = newVal;
				var allowed = this._trigger("slide", event, {
					handle: this.handles[index],
					value: newVal,
					values: newValues
				});
				var otherVal = this.values(index ? 0 : 1);
				if (allowed !== false) {
					this.values(index, newVal, ( event.type == 'mousedown' && this.options.animate ), true);
				}
			}

		} else {

			if (newVal != this.value()) {
				var allowed = this._trigger("slide", event, {
					handle: this.handles[index],
					value: newVal
				});
				if (allowed !== false) {
					this._setData('value', newVal, ( event.type == 'mousedown' && this.options.animate ));
				}

			}

		}

	},

	_stop: function(event, index) {
		var uiHash = {
			handle: this.handles[index],
			value: this.value()
		};
		if (this.options.values && this.options.values.length) {
			uiHash.value = this.values(index);
			uiHash.values = this.values();
		}
		this._trigger("stop", event, uiHash);
	},

	_change: function(event, index) {
		var uiHash = {
			handle: this.handles[index],
			value: this.value()
		};
		if (this.options.values && this.options.values.length) {
			uiHash.value = this.values(index);
			uiHash.values = this.values();
		}
		this._trigger("change", event, uiHash);
	},

	value: function(newValue) {

		if (arguments.length) {
			this._setData("value", newValue);
			this._change(null, 0);
		}

		return this._value();

	},

	values: function(index, newValue, animated, noPropagation) {

		if (arguments.length > 1) {
			this.options.values[index] = newValue;
			this._refreshValue(animated);
			if(!noPropagation) this._change(null, index);
		}

		if (arguments.length) {
			if (this.options.values && this.options.values.length) {
				return this._values(index);
			} else {
				return this.value();
			}
		} else {
			return this._values();
		}

	},

	_setData: function(key, value, animated) {

		$.widget.prototype._setData.apply(this, arguments);

		switch (key) {
			case 'disabled':
				if (value) {
					this.handles.filter(".ui-state-focus").blur();
					this.handles.removeClass("ui-state-hover");
					this.handles.attr("disabled", "disabled");
				} else {
					this.handles.removeAttr("disabled");
				}
			case 'orientation':

				this._detectOrientation();

				this.element
					.removeClass("ui-slider-horizontal ui-slider-vertical")
					.addClass("ui-slider-" + this.orientation);
				this._refreshValue(animated);
				break;
			case 'value':
				this._refreshValue(animated);
				break;
		}

	},

	_step: function() {
		var step = this.options.step;
		return step;
	},

	_value: function() {

		var val = this.options.value;
		if (val < this._valueMin()) val = this._valueMin();
		if (val > this._valueMax()) val = this._valueMax();

		return val;

	},

	_values: function(index) {

		if (arguments.length) {
			var val = this.options.values[index];
			if (val < this._valueMin()) val = this._valueMin();
			if (val > this._valueMax()) val = this._valueMax();

			return val;
		} else {
			return this.options.values;
		}

	},

	_valueMin: function() {
		var valueMin = this.options.min;
		return valueMin;
	},

	_valueMax: function() {
		var valueMax = this.options.max;
		return valueMax;
	},

	_refreshValue: function(animate) {

		var oRange = this.options.range, o = this.options, self = this;

		if (this.options.values && this.options.values.length) {
			var vp0, vp1;
			this.handles.each(function(i, j) {
				var valPercent = (self.values(i) - self._valueMin()) / (self._valueMax() - self._valueMin()) * 100;
				var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
				$(this).stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate);
				if (self.options.range === true) {
					if (self.orientation == 'horizontal') {
						(i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ left: valPercent + '%' }, o.animate);
						(i == 1) && self.range[animate ? 'animate' : 'css']({ width: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
					} else {
						(i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ bottom: (valPercent) + '%' }, o.animate);
						(i == 1) && self.range[animate ? 'animate' : 'css']({ height: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
					}
				}
				lastValPercent = valPercent;
			});
		} else {
			var value = this.value(),
				valueMin = this._valueMin(),
				valueMax = this._valueMax(),
				valPercent = valueMax != valueMin
					? (value - valueMin) / (valueMax - valueMin) * 100
					: 0;
			var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
			this.handle.stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate);

			(oRange == "min") && (this.orientation == "horizontal") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ width: valPercent + '%' }, o.animate);
			(oRange == "max") && (this.orientation == "horizontal") && this.range[animate ? 'animate' : 'css']({ width: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
			(oRange == "min") && (this.orientation == "vertical") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ height: valPercent + '%' }, o.animate);
			(oRange == "max") && (this.orientation == "vertical") && this.range[animate ? 'animate' : 'css']({ height: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
		}

	}

}));

$.extend($.ui.slider, {
	getter: "value values",
	version: "1.7.2",
	eventPrefix: "slide",
	defaults: {
		animate: false,
		delay: 0,
		distance: 0,
		max: 100,
		min: 0,
		orientation: 'horizontal',
		range: false,
		step: 1,
		value: 0,
		values: null
	}
});

})(jQuery);
/*
 * jQuery UI Datepicker 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Datepicker
 *
 * Depends:
 *	ui.core.js
 */

(function($) { // hide the namespace

$.extend($.ui, { datepicker: { version: "1.7.2" } });

var PROP_NAME = 'datepicker';

/* Date picker manager.
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
   Settings for (groups of) date pickers are maintained in an instance object,
   allowing multiple different settings on the same page. */

function Datepicker() {
	this.debug = false; // Change this to true to start debugging
	this._curInst = null; // The current instance in use
	this._keyEvent = false; // If the last event was a key event
	this._disabledInputs = []; // List of date picker inputs that have been disabled
	this._datepickerShowing = false; // True if the popup picker is showing , false if not
	this._inDialog = false; // True if showing within a "dialog", false if not
	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
	this.regional = []; // Available regional settings, indexed by language code
	this.regional[''] = { // Default regional settings
		closeText: 'Done', // Display text for close link
		prevText: 'Prev', // Display text for previous month link
		nextText: 'Next', // Display text for next month link
		currentText: 'Today', // Display text for current month link
		monthNames: ['January','February','March','April','May','June',
			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
		dateFormat: 'mm/dd/yy', // See format options on parseDate
		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
		isRTL: false // True if right-to-left language, false if left-to-right
	};
	this._defaults = { // Global defaults for all the date picker instances
		showOn: 'focus', // 'focus' for popup on focus,
		showAnim: 'show', // Name of jQuery animation for popup
		showOptions: {}, // Options for enhanced animations
		defaultDate: null, // Used when field is blank: actual date,
		appendText: '', // Display text following the input box, e.g. showing the format
		buttonText: '...', // Text for trigger button
		buttonImage: '', // URL for trigger button image
		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
		hideIfNoPrevNext: false, // True to hide next/previous month links
		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
		gotoCurrent: false, // True if today link goes back to current selection instead
		changeMonth: false, // True if month can be selected directly, false if only prev/next
		changeYear: false, // True if year can be selected directly, false if only prev/next
		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
		yearRange: '-10:+10', // Range of years to display in drop-down,
		showOtherMonths: false, // True to show dates in other months, false to leave blank
		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
		shortYearCutoff: '+10', // Short year values < this are in the current century,
		minDate: null, // The earliest selectable date, or null for no limit
		maxDate: null, // The latest selectable date, or null for no limit
		duration: 'normal', // Duration of display/closure
		beforeShowDay: null, // Function that takes a date and returns an array with
		beforeShow: null, // Function that takes an input field and
		onSelect: null, // Define a callback function when a date is selected
		onChangeMonthYear: null, // Define a callback function when the month or year is changed
		onClose: null, // Define a callback function when the datepicker is closed
		numberOfMonths: 1, // Number of months to show at a time
		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
		stepMonths: 1, // Number of months to step back/forward
		stepBigMonths: 12, // Number of months to step back/forward for the big links
		altField: '', // Selector for an alternate field to store selected dates into
		altFormat: '', // The date format to use for the alternate field
		constrainInput: true, // The input is constrained by the current date format
		showButtonPanel: false // True to show button panel, false to not show it
	};
	$.extend(this._defaults, this.regional['']);
	this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>');
}

$.extend(Datepicker.prototype, {
	/* Class name added to elements to indicate already configured with a date picker. */
	markerClassName: 'hasDatepicker',

	/* Debug logging (if enabled). */
	log: function () {
		if (this.debug)
			console.log.apply('', arguments);
	},

	/* Override the default settings for all instances of the date picker.
	   @param  settings  object - the new settings to use as defaults (anonymous object)
	   @return the manager object */
	setDefaults: function(settings) {
		extendRemove(this._defaults, settings || {});
		return this;
	},

	/* Attach the date picker to a jQuery selection.
	   @param  target    element - the target input field or division or span
	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
	_attachDatepicker: function(target, settings) {
		var inlineSettings = null;
		for (var attrName in this._defaults) {
			var attrValue = target.getAttribute('date:' + attrName);
			if (attrValue) {
				inlineSettings = inlineSettings || {};
				try {
					inlineSettings[attrName] = eval(attrValue);
				} catch (err) {
					inlineSettings[attrName] = attrValue;
				}
			}
		}
		var nodeName = target.nodeName.toLowerCase();
		var inline = (nodeName == 'div' || nodeName == 'span');
		if (!target.id)
			target.id = 'dp' + (++this.uuid);
		var inst = this._newInst($(target), inline);
		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
		if (nodeName == 'input') {
			this._connectDatepicker(target, inst);
		} else if (inline) {
			this._inlineDatepicker(target, inst);
		}
	},

	/* Create a new instance object. */
	_newInst: function(target, inline) {
		var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars
		return {id: id, input: target, // associated target
			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
			drawMonth: 0, drawYear: 0, // month being drawn
			inline: inline, // is datepicker inline or not
			dpDiv: (!inline ? this.dpDiv : // presentation div
			$('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
	},

	/* Attach the date picker to an input field. */
	_connectDatepicker: function(target, inst) {
		var input = $(target);
		inst.append = $([]);
		inst.trigger = $([]);
		if (input.hasClass(this.markerClassName))
			return;
		var appendText = this._get(inst, 'appendText');
		var isRTL = this._get(inst, 'isRTL');
		if (appendText) {
			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
			input[isRTL ? 'before' : 'after'](inst.append);
		}
		var showOn = this._get(inst, 'showOn');
		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
			input.focus(this._showDatepicker);
		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
			var buttonText = this._get(inst, 'buttonText');
			var buttonImage = this._get(inst, 'buttonImage');
			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
				$('<img/>').addClass(this._triggerClass).
					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
				$('<button type="button"></button>').addClass(this._triggerClass).
					html(buttonImage == '' ? buttonText : $('<img/>').attr(
					{ src:buttonImage, alt:buttonText, title:buttonText })));
			input[isRTL ? 'before' : 'after'](inst.trigger);
			inst.trigger.click(function() {
				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
					$.datepicker._hideDatepicker();
				else
					$.datepicker._showDatepicker(target);
				return false;
			});
		}
		input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).
			bind("setData.datepicker", function(event, key, value) {
				inst.settings[key] = value;
			}).bind("getData.datepicker", function(event, key) {
				return this._get(inst, key);
			});
		$.data(target, PROP_NAME, inst);
	},

	/* Attach an inline date picker to a div. */
	_inlineDatepicker: function(target, inst) {
		var divSpan = $(target);
		if (divSpan.hasClass(this.markerClassName))
			return;
		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
			bind("setData.datepicker", function(event, key, value){
				inst.settings[key] = value;
			}).bind("getData.datepicker", function(event, key){
				return this._get(inst, key);
			});
		$.data(target, PROP_NAME, inst);
		this._setDate(inst, this._getDefaultDate(inst));
		this._updateDatepicker(inst);
		this._updateAlternate(inst);
	},

	/* Pop-up the date picker in a "dialog" box.
	   @param  input     element - ignored
	   @param  dateText  string - the initial date to display (in the current format)
	   @param  onSelect  function - the function(dateText) to call when a date is selected
	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
	                     event - with x/y coordinates or
	                     leave empty for default (screen centre)
	   @return the manager object */
	_dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
		var inst = this._dialogInst; // internal instance
		if (!inst) {
			var id = 'dp' + (++this.uuid);
			this._dialogInput = $('<input type="text" id="' + id +
				'" size="1" style="position: absolute; top: -100px;"/>');
			this._dialogInput.keydown(this._doKeyDown);
			$('body').append(this._dialogInput);
			inst = this._dialogInst = this._newInst(this._dialogInput, false);
			inst.settings = {};
			$.data(this._dialogInput[0], PROP_NAME, inst);
		}
		extendRemove(inst.settings, settings || {});
		this._dialogInput.val(dateText);

		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
		if (!this._pos) {
			var browserWidth = window.innerWidth || document.documentElement.clientWidth ||	document.body.clientWidth;
			var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
			this._pos = // should use actual width/height below
				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
		}

		this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
		inst.settings.onSelect = onSelect;
		this._inDialog = true;
		this.dpDiv.addClass(this._dialogClass);
		this._showDatepicker(this._dialogInput[0]);
		if ($.blockUI)
			$.blockUI(this.dpDiv);
		$.data(this._dialogInput[0], PROP_NAME, inst);
		return this;
	},

	/* Detach a datepicker from its control.
	   @param  target    element - the target input field or division or span */
	_destroyDatepicker: function(target) {
		var $target = $(target);
		var inst = $.data(target, PROP_NAME);
		if (!$target.hasClass(this.markerClassName)) {
			return;
		}
		var nodeName = target.nodeName.toLowerCase();
		$.removeData(target, PROP_NAME);
		if (nodeName == 'input') {
			inst.append.remove();
			inst.trigger.remove();
			$target.removeClass(this.markerClassName).
				unbind('focus', this._showDatepicker).
				unbind('keydown', this._doKeyDown).
				unbind('keypress', this._doKeyPress);
		} else if (nodeName == 'div' || nodeName == 'span')
			$target.removeClass(this.markerClassName).empty();
	},

	/* Enable the date picker to a jQuery selection.
	   @param  target    element - the target input field or division or span */
	_enableDatepicker: function(target) {
		var $target = $(target);
		var inst = $.data(target, PROP_NAME);
		if (!$target.hasClass(this.markerClassName)) {
			return;
		}
		var nodeName = target.nodeName.toLowerCase();
		if (nodeName == 'input') {
			target.disabled = false;
			inst.trigger.filter('button').
				each(function() { this.disabled = false; }).end().
				filter('img').css({opacity: '1.0', cursor: ''});
		}
		else if (nodeName == 'div' || nodeName == 'span') {
			var inline = $target.children('.' + this._inlineClass);
			inline.children().removeClass('ui-state-disabled');
		}
		this._disabledInputs = $.map(this._disabledInputs,
			function(value) { return (value == target ? null : value); }); // delete entry
	},

	/* Disable the date picker to a jQuery selection.
	   @param  target    element - the target input field or division or span */
	_disableDatepicker: function(target) {
		var $target = $(target);
		var inst = $.data(target, PROP_NAME);
		if (!$target.hasClass(this.markerClassName)) {
			return;
		}
		var nodeName = target.nodeName.toLowerCase();
		if (nodeName == 'input') {
			target.disabled = true;
			inst.trigger.filter('button').
				each(function() { this.disabled = true; }).end().
				filter('img').css({opacity: '0.5', cursor: 'default'});
		}
		else if (nodeName == 'div' || nodeName == 'span') {
			var inline = $target.children('.' + this._inlineClass);
			inline.children().addClass('ui-state-disabled');
		}
		this._disabledInputs = $.map(this._disabledInputs,
			function(value) { return (value == target ? null : value); }); // delete entry
		this._disabledInputs[this._disabledInputs.length] = target;
	},

	/* Is the first field in a jQuery collection disabled as a datepicker?
	   @param  target    element - the target input field or division or span
	   @return boolean - true if disabled, false if enabled */
	_isDisabledDatepicker: function(target) {
		if (!target) {
			return false;
		}
		for (var i = 0; i < this._disabledInputs.length; i++) {
			if (this._disabledInputs[i] == target)
				return true;
		}
		return false;
	},

	/* Retrieve the instance data for the target control.
	   @param  target  element - the target input field or division or span
	   @return  object - the associated instance data
	   @throws  error if a jQuery problem getting data */
	_getInst: function(target) {
		try {
			return $.data(target, PROP_NAME);
		}
		catch (err) {
			throw 'Missing instance data for this datepicker';
		}
	},

	/* Update or retrieve the settings for a date picker attached to an input field or division.
	   @param  target  element - the target input field or division or span
	   @param  name    object - the new settings to update or
	                   string - the name of the setting to change or retrieve,
	                   when retrieving also 'all' for all instance settings or
	                   'defaults' for all global defaults
	   @param  value   any - the new value for the setting
	                   (omit if above is an object or to retrieve a value) */
	_optionDatepicker: function(target, name, value) {
		var inst = this._getInst(target);
		if (arguments.length == 2 && typeof name == 'string') {
			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
				this._get(inst, name)) : null));
		}
		var settings = name || {};
		if (typeof name == 'string') {
			settings = {};
			settings[name] = value;
		}
		if (inst) {
			if (this._curInst == inst) {
				this._hideDatepicker(null);
			}
			var date = this._getDateDatepicker(target);
			extendRemove(inst.settings, settings);
			this._setDateDatepicker(target, date);
			this._updateDatepicker(inst);
		}
	},

	_changeDatepicker: function(target, name, value) {
		this._optionDatepicker(target, name, value);
	},

	/* Redraw the date picker attached to an input field or division.
	   @param  target  element - the target input field or division or span */
	_refreshDatepicker: function(target) {
		var inst = this._getInst(target);
		if (inst) {
			this._updateDatepicker(inst);
		}
	},

	/* Set the dates for a jQuery selection.
	   @param  target   element - the target input field or division or span
	   @param  date     Date - the new date
	   @param  endDate  Date - the new end date for a range (optional) */
	_setDateDatepicker: function(target, date, endDate) {
		var inst = this._getInst(target);
		if (inst) {
			this._setDate(inst, date, endDate);
			this._updateDatepicker(inst);
			this._updateAlternate(inst);
		}
	},

	/* Get the date(s) for the first entry in a jQuery selection.
	   @param  target  element - the target input field or division or span
	   @return Date - the current date or
	           Date[2] - the current dates for a range */
	_getDateDatepicker: function(target) {
		var inst = this._getInst(target);
		if (inst && !inst.inline)
			this._setDateFromField(inst);
		return (inst ? this._getDate(inst) : null);
	},

	/* Handle keystrokes. */
	_doKeyDown: function(event) {
		var inst = $.datepicker._getInst(event.target);
		var handled = true;
		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
		inst._keyEvent = true;
		if ($.datepicker._datepickerShowing)
			switch (event.keyCode) {
				case 9:  $.datepicker._hideDatepicker(null, '');
						break; // hide on tab out
				case 13: var sel = $('td.' + $.datepicker._dayOverClass +
							', td.' + $.datepicker._currentClass, inst.dpDiv);
						if (sel[0])
							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
						else
							$.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
						return false; // don't submit the form
						break; // select the value on enter
				case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
						break; // hide on escape
				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
							-$.datepicker._get(inst, 'stepBigMonths') :
							-$.datepicker._get(inst, 'stepMonths')), 'M');
						break; // previous month/year on page up/+ ctrl
				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
							+$.datepicker._get(inst, 'stepBigMonths') :
							+$.datepicker._get(inst, 'stepMonths')), 'M');
						break; // next month/year on page down/+ ctrl
				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
						handled = event.ctrlKey || event.metaKey;
						break; // clear on ctrl or command +end
				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
						handled = event.ctrlKey || event.metaKey;
						break; // current on ctrl or command +home
				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
						handled = event.ctrlKey || event.metaKey;
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
									-$.datepicker._get(inst, 'stepBigMonths') :
									-$.datepicker._get(inst, 'stepMonths')), 'M');
						break;
				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
						handled = event.ctrlKey || event.metaKey;
						break; // -1 week on ctrl or command +up
				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
						handled = event.ctrlKey || event.metaKey;
						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
									+$.datepicker._get(inst, 'stepBigMonths') :
									+$.datepicker._get(inst, 'stepMonths')), 'M');
						break;
				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
						handled = event.ctrlKey || event.metaKey;
						break; // +1 week on ctrl or command +down
				default: handled = false;
			}
		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
			$.datepicker._showDatepicker(this);
		else {
			handled = false;
		}
		if (handled) {
			event.preventDefault();
			event.stopPropagation();
		}
	},

	/* Filter entered characters - based on date format. */
	_doKeyPress: function(event) {
		var inst = $.datepicker._getInst(event.target);
		if ($.datepicker._get(inst, 'constrainInput')) {
			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
			return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
		}
	},

	/* Pop-up the date picker for a given input field.
	   @param  input  element - the input field attached to the date picker or
	                  event - if triggered by focus */
	_showDatepicker: function(input) {
		input = input.target || input;
		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
			input = $('input', input.parentNode)[0];
		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
			return;
		var inst = $.datepicker._getInst(input);
		var beforeShow = $.datepicker._get(inst, 'beforeShow');
		extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
		$.datepicker._hideDatepicker(null, '');
		$.datepicker._lastInput = input;
		$.datepicker._setDateFromField(inst);
		if ($.datepicker._inDialog) // hide cursor
			input.value = '';
		if (!$.datepicker._pos) { // position below input
			$.datepicker._pos = $.datepicker._findPos(input);
			$.datepicker._pos[1] += input.offsetHeight; // add the height
		}
		var isFixed = false;
		$(input).parents().each(function() {
			isFixed |= $(this).css('position') == 'fixed';
			return !isFixed;
		});
		if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
			$.datepicker._pos[0] -= document.documentElement.scrollLeft;
			$.datepicker._pos[1] -= document.documentElement.scrollTop;
		}
		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
		$.datepicker._pos = null;
		inst.rangeStart = null;
		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
		$.datepicker._updateDatepicker(inst);
		offset = $.datepicker._checkOffset(inst, offset, isFixed);
		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
			left: offset.left + 'px', top: offset.top + 'px'});
		if (!inst.inline) {
			var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
			var duration = $.datepicker._get(inst, 'duration');
			var postProcess = function() {
				$.datepicker._datepickerShowing = true;
				if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems
					$('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
						height: inst.dpDiv.height() + 4});
			};
			if ($.effects && $.effects[showAnim])
				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
			else
				inst.dpDiv[showAnim](duration, postProcess);
			if (duration == '')
				postProcess();
			if (inst.input[0].type != 'hidden')
				inst.input[0].focus();
			$.datepicker._curInst = inst;
		}
	},

	/* Generate the date picker content. */
	_updateDatepicker: function(inst) {
		var dims = {width: inst.dpDiv.width() + 4,
			height: inst.dpDiv.height() + 4};
		var self = this;
		inst.dpDiv.empty().append(this._generateHTML(inst))
			.find('iframe.ui-datepicker-cover').
				css({width: dims.width, height: dims.height})
			.end()
			.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
				.bind('mouseout', function(){
					$(this).removeClass('ui-state-hover');
					if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
					if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
				})
				.bind('mouseover', function(){
					if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
						$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
						$(this).addClass('ui-state-hover');
						if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
						if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
					}
				})
			.end()
			.find('.' + this._dayOverClass + ' a')
				.trigger('mouseover')
			.end();
		var numMonths = this._getNumberOfMonths(inst);
		var cols = numMonths[1];
		var width = 17;
		if (cols > 1) {
			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
		} else {
			inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
		}
		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
			'Class']('ui-datepicker-multi');
		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
			'Class']('ui-datepicker-rtl');
		if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst)
			$(inst.input[0]).focus();
	},

	/* Check positioning to remain on screen. */
	_checkOffset: function(inst, offset, isFixed) {
		var dpWidth = inst.dpDiv.outerWidth();
		var dpHeight = inst.dpDiv.outerHeight();
		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
		var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft();
		var viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop();

		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;

		offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0;
		offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0;

		return offset;
	},

	/* Find an object's position on the screen. */
	_findPos: function(obj) {
        while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
            obj = obj.nextSibling;
        }
        var position = $(obj).offset();
	    return [position.left, position.top];
	},

	/* Hide the date picker from view.
	   @param  input  element - the input field attached to the date picker
	   @param  duration  string - the duration over which to close the date picker */
	_hideDatepicker: function(input, duration) {
		var inst = this._curInst;
		if (!inst || (input && inst != $.data(input, PROP_NAME)))
			return;
		if (inst.stayOpen)
			this._selectDate('#' + inst.id, this._formatDate(inst,
				inst.currentDay, inst.currentMonth, inst.currentYear));
		inst.stayOpen = false;
		if (this._datepickerShowing) {
			duration = (duration != null ? duration : this._get(inst, 'duration'));
			var showAnim = this._get(inst, 'showAnim');
			var postProcess = function() {
				$.datepicker._tidyDialog(inst);
			};
			if (duration != '' && $.effects && $.effects[showAnim])
				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
					duration, postProcess);
			else
				inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
			if (duration == '')
				this._tidyDialog(inst);
			var onClose = this._get(inst, 'onClose');
			if (onClose)
				onClose.apply((inst.input ? inst.input[0] : null),
					[(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback
			this._datepickerShowing = false;
			this._lastInput = null;
			if (this._inDialog) {
				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
				if ($.blockUI) {
					$.unblockUI();
					$('body').append(this.dpDiv);
				}
			}
			this._inDialog = false;
		}
		this._curInst = null;
	},

	/* Tidy up after a dialog display. */
	_tidyDialog: function(inst) {
		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
	},

	/* Close date picker if clicked elsewhere. */
	_checkExternalClick: function(event) {
		if (!$.datepicker._curInst)
			return;
		var $target = $(event.target);
		if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
				!$target.hasClass($.datepicker.markerClassName) &&
				!$target.hasClass($.datepicker._triggerClass) &&
				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
			$.datepicker._hideDatepicker(null, '');
	},

	/* Adjust one of the date sub-fields. */
	_adjustDate: function(id, offset, period) {
		var target = $(id);
		var inst = this._getInst(target[0]);
		if (this._isDisabledDatepicker(target[0])) {
			return;
		}
		this._adjustInstDate(inst, offset +
			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
			period);
		this._updateDatepicker(inst);
	},

	/* Action for current link. */
	_gotoToday: function(id) {
		var target = $(id);
		var inst = this._getInst(target[0]);
		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
			inst.selectedDay = inst.currentDay;
			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
			inst.drawYear = inst.selectedYear = inst.currentYear;
		}
		else {
		var date = new Date();
		inst.selectedDay = date.getDate();
		inst.drawMonth = inst.selectedMonth = date.getMonth();
		inst.drawYear = inst.selectedYear = date.getFullYear();
		}
		this._notifyChange(inst);
		this._adjustDate(target);
	},

	/* Action for selecting a new month/year. */
	_selectMonthYear: function(id, select, period) {
		var target = $(id);
		var inst = this._getInst(target[0]);
		inst._selectingMonthYear = false;
		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
			parseInt(select.options[select.selectedIndex].value,10);
		this._notifyChange(inst);
		this._adjustDate(target);
	},

	/* Restore input focus after not changing month/year. */
	_clickMonthYear: function(id) {
		var target = $(id);
		var inst = this._getInst(target[0]);
		if (inst.input && inst._selectingMonthYear && !$.browser.msie)
			inst.input[0].focus();
		inst._selectingMonthYear = !inst._selectingMonthYear;
	},

	/* Action for selecting a day. */
	_selectDay: function(id, month, year, td) {
		var target = $(id);
		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
			return;
		}
		var inst = this._getInst(target[0]);
		inst.selectedDay = inst.currentDay = $('a', td).html();
		inst.selectedMonth = inst.currentMonth = month;
		inst.selectedYear = inst.currentYear = year;
		if (inst.stayOpen) {
			inst.endDay = inst.endMonth = inst.endYear = null;
		}
		this._selectDate(id, this._formatDate(inst,
			inst.currentDay, inst.currentMonth, inst.currentYear));
		if (inst.stayOpen) {
			inst.rangeStart = this._daylightSavingAdjust(
				new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
			this._updateDatepicker(inst);
		}
	},

	/* Erase the input field and hide the date picker. */
	_clearDate: function(id) {
		var target = $(id);
		var inst = this._getInst(target[0]);
		inst.stayOpen = false;
		inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
		this._selectDate(target, '');
	},

	/* Update the input field with the selected date. */
	_selectDate: function(id, dateStr) {
		var target = $(id);
		var inst = this._getInst(target[0]);
		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
		if (inst.input)
			inst.input.val(dateStr);
		this._updateAlternate(inst);
		var onSelect = this._get(inst, 'onSelect');
		if (onSelect)
			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
		else if (inst.input)
			inst.input.trigger('change'); // fire the change event
		if (inst.inline)
			this._updateDatepicker(inst);
		else if (!inst.stayOpen) {
			this._hideDatepicker(null, this._get(inst, 'duration'));
			this._lastInput = inst.input[0];
			if (typeof(inst.input[0]) != 'object')
				inst.input[0].focus(); // restore focus
			this._lastInput = null;
		}
	},

	/* Update any alternate field to synchronise with the main field. */
	_updateAlternate: function(inst) {
		var altField = this._get(inst, 'altField');
		if (altField) { // update alternate field too
			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
			var date = this._getDate(inst);
			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
			$(altField).each(function() { $(this).val(dateStr); });
		}
	},

	/* Set as beforeShowDay function to prevent selection of weekends.
	   @param  date  Date - the date to customise
	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
	noWeekends: function(date) {
		var day = date.getDay();
		return [(day > 0 && day < 6), ''];
	},

	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
	   @param  date  Date - the date to get the week for
	   @return  number - the number of the week within the year that contains this date */
	iso8601Week: function(date) {
		var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
		var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
		var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
		firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
		if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
			checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
			return $.datepicker.iso8601Week(checkDate);
		} else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
			firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
			if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
				return 1;
			}
		}
		return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
	},

	/* Parse a string value into a date object.
	   See formatDate below for the possible formats.

	   @param  format    string - the expected format of the date
	   @param  value     string - the date in the above format
	   @param  settings  Object - attributes include:
	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
	                     dayNames         string[7] - names of the days from Sunday (optional)
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
	                     monthNames       string[12] - names of the months (optional)
	   @return  Date - the extracted date value or null if value is blank */
	parseDate: function (format, value, settings) {
		if (format == null || value == null)
			throw 'Invalid arguments';
		value = (typeof value == 'object' ? value.toString() : value + '');
		if (value == '')
			return null;
		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
		var year = -1;
		var month = -1;
		var day = -1;
		var doy = -1;
		var literal = false;
		var lookAhead = function(match) {
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
			if (matches)
				iFormat++;
			return matches;
		};
		var getNumber = function(match) {
			lookAhead(match);
			var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));
			var size = origSize;
			var num = 0;
			while (size > 0 && iValue < value.length &&
					value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
				num = num * 10 + parseInt(value.charAt(iValue++),10);
				size--;
			}
			if (size == origSize)
				throw 'Missing number at position ' + iValue;
			return num;
		};
		var getName = function(match, shortNames, longNames) {
			var names = (lookAhead(match) ? longNames : shortNames);
			var size = 0;
			for (var j = 0; j < names.length; j++)
				size = Math.max(size, names[j].length);
			var name = '';
			var iInit = iValue;
			while (size > 0 && iValue < value.length) {
				name += value.charAt(iValue++);
				for (var i = 0; i < names.length; i++)
					if (name == names[i])
						return i + 1;
				size--;
			}
			throw 'Unknown name at position ' + iInit;
		};
		var checkLiteral = function() {
			if (value.charAt(iValue) != format.charAt(iFormat))
				throw 'Unexpected literal at position ' + iValue;
			iValue++;
		};
		var iValue = 0;
		for (var iFormat = 0; iFormat < format.length; iFormat++) {
			if (literal)
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
					literal = false;
				else
					checkLiteral();
			else
				switch (format.charAt(iFormat)) {
					case 'd':
						day = getNumber('d');
						break;
					case 'D':
						getName('D', dayNamesShort, dayNames);
						break;
					case 'o':
						doy = getNumber('o');
						break;
					case 'm':
						month = getNumber('m');
						break;
					case 'M':
						month = getName('M', monthNamesShort, monthNames);
						break;
					case 'y':
						year = getNumber('y');
						break;
					case '@':
						var date = new Date(getNumber('@'));
						year = date.getFullYear();
						month = date.getMonth() + 1;
						day = date.getDate();
						break;
					case "'":
						if (lookAhead("'"))
							checkLiteral();
						else
							literal = true;
						break;
					default:
						checkLiteral();
				}
		}
		if (year == -1)
			year = new Date().getFullYear();
		else if (year < 100)
			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
				(year <= shortYearCutoff ? 0 : -100);
		if (doy > -1) {
			month = 1;
			day = doy;
			do {
				var dim = this._getDaysInMonth(year, month - 1);
				if (day <= dim)
					break;
				month++;
				day -= dim;
			} while (true);
		}
		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
			throw 'Invalid date'; // E.g. 31/02/*
		return date;
	},

	/* Standard date formats. */
	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
	COOKIE: 'D, dd M yy',
	ISO_8601: 'yy-mm-dd',
	RFC_822: 'D, d M y',
	RFC_850: 'DD, dd-M-y',
	RFC_1036: 'D, d M y',
	RFC_1123: 'D, d M yy',
	RFC_2822: 'D, d M yy',
	RSS: 'D, d M y', // RFC 822
	TIMESTAMP: '@',
	W3C: 'yy-mm-dd', // ISO 8601

	/* Format a date object into a string value.
	   The format can be combinations of the following:
	   d  - day of month (no leading zero)
	   dd - day of month (two digit)
	   o  - day of year (no leading zeros)
	   oo - day of year (three digit)
	   D  - day name short
	   DD - day name long
	   m  - month of year (no leading zero)
	   mm - month of year (two digit)
	   M  - month name short
	   MM - month name long
	   y  - year (two digit)
	   yy - year (four digit)
	   @ - Unix timestamp (ms since 01/01/1970)
	   '...' - literal text
	   '' - single quote

	   @param  format    string - the desired format of the date
	   @param  date      Date - the date value to format
	   @param  settings  Object - attributes include:
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
	                     dayNames         string[7] - names of the days from Sunday (optional)
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
	                     monthNames       string[12] - names of the months (optional)
	   @return  string - the date in the above format */
	formatDate: function (format, date, settings) {
		if (!date)
			return '';
		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
		var lookAhead = function(match) {
			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
			if (matches)
				iFormat++;
			return matches;
		};
		var formatNumber = function(match, value, len) {
			var num = '' + value;
			if (lookAhead(match))
				while (num.length < len)
					num = '0' + num;
			return num;
		};
		var formatName = function(match, value, shortNames, longNames) {
			return (lookAhead(match) ? longNames[value] : shortNames[value]);
		};
		var output = '';
		var literal = false;
		if (date)
			for (var iFormat = 0; iFormat < format.length; iFormat++) {
				if (literal)
					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
						literal = false;
					else
						output += format.charAt(iFormat);
				else
					switch (format.charAt(iFormat)) {
						case 'd':
							output += formatNumber('d', date.getDate(), 2);
							break;
						case 'D':
							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
							break;
						case 'o':
							var doy = date.getDate();
							for (var m = date.getMonth() - 1; m >= 0; m--)
								doy += this._getDaysInMonth(date.getFullYear(), m);
							output += formatNumber('o', doy, 3);
							break;
						case 'm':
							output += formatNumber('m', date.getMonth() + 1, 2);
							break;
						case 'M':
							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
							break;
						case 'y':
							output += (lookAhead('y') ? date.getFullYear() :
								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
							break;
						case '@':
							output += date.getTime();
							break;
						case "'":
							if (lookAhead("'"))
								output += "'";
							else
								literal = true;
							break;
						default:
							output += format.charAt(iFormat);
					}
			}
		return output;
	},

	/* Extract all possible characters from the date format. */
	_possibleChars: function (format) {
		var chars = '';
		var literal = false;
		for (var iFormat = 0; iFormat < format.length; iFormat++)
			if (literal)
				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
					literal = false;
				else
					chars += format.charAt(iFormat);
			else
				switch (format.charAt(iFormat)) {
					case 'd': case 'm': case 'y': case '@':
						chars += '0123456789';
						break;
					case 'D': case 'M':
						return null; // Accept anything
					case "'":
						if (lookAhead("'"))
							chars += "'";
						else
							literal = true;
						break;
					default:
						chars += format.charAt(iFormat);
				}
		return chars;
	},

	/* Get a setting value, defaulting if necessary. */
	_get: function(inst, name) {
		return inst.settings[name] !== undefined ?
			inst.settings[name] : this._defaults[name];
	},

	/* Parse existing date and initialise date picker. */
	_setDateFromField: function(inst) {
		var dateFormat = this._get(inst, 'dateFormat');
		var dates = inst.input ? inst.input.val() : null;
		inst.endDay = inst.endMonth = inst.endYear = null;
		var date = defaultDate = this._getDefaultDate(inst);
		var settings = this._getFormatConfig(inst);
		try {
			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
		} catch (event) {
			this.log(event);
			date = defaultDate;
		}
		inst.selectedDay = date.getDate();
		inst.drawMonth = inst.selectedMonth = date.getMonth();
		inst.drawYear = inst.selectedYear = date.getFullYear();
		inst.currentDay = (dates ? date.getDate() : 0);
		inst.currentMonth = (dates ? date.getMonth() : 0);
		inst.currentYear = (dates ? date.getFullYear() : 0);
		this._adjustInstDate(inst);
	},

	/* Retrieve the default date shown on opening. */
	_getDefaultDate: function(inst) {
		var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
		var minDate = this._getMinMaxDate(inst, 'min', true);
		var maxDate = this._getMinMaxDate(inst, 'max');
		date = (minDate && date < minDate ? minDate : date);
		date = (maxDate && date > maxDate ? maxDate : date);
		return date;
	},

	/* A date may be specified as an exact value or a relative one. */
	_determineDate: function(date, defaultDate) {
		var offsetNumeric = function(offset) {
			var date = new Date();
			date.setDate(date.getDate() + offset);
			return date;
		};
		var offsetString = function(offset, getDaysInMonth) {
			var date = new Date();
			var year = date.getFullYear();
			var month = date.getMonth();
			var day = date.getDate();
			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
			var matches = pattern.exec(offset);
			while (matches) {
				switch (matches[2] || 'd') {
					case 'd' : case 'D' :
						day += parseInt(matches[1],10); break;
					case 'w' : case 'W' :
						day += parseInt(matches[1],10) * 7; break;
					case 'm' : case 'M' :
						month += parseInt(matches[1],10);
						day = Math.min(day, getDaysInMonth(year, month));
						break;
					case 'y': case 'Y' :
						year += parseInt(matches[1],10);
						day = Math.min(day, getDaysInMonth(year, month));
						break;
				}
				matches = pattern.exec(offset);
			}
			return new Date(year, month, day);
		};
		date = (date == null ? defaultDate :
			(typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));
		date = (date && date.toString() == 'Invalid Date' ? defaultDate : date);
		if (date) {
			date.setHours(0);
			date.setMinutes(0);
			date.setSeconds(0);
			date.setMilliseconds(0);
		}
		return this._daylightSavingAdjust(date);
	},

	/* Handle switch to/from daylight saving.
	   Hours may be non-zero on daylight saving cut-over:
	   > 12 when midnight changeover, but then cannot generate
	   midnight datetime, so jump to 1AM, otherwise reset.
	   @param  date  (Date) the date to check
	   @return  (Date) the corrected date */
	_daylightSavingAdjust: function(date) {
		if (!date) return null;
		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
		return date;
	},

	/* Set the date(s) directly. */
	_setDate: function(inst, date, endDate) {
		var clear = !(date);
		var origMonth = inst.selectedMonth;
		var origYear = inst.selectedYear;
		date = this._determineDate(date, new Date());
		inst.selectedDay = inst.currentDay = date.getDate();
		inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
		inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
		if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
			this._notifyChange(inst);
		this._adjustInstDate(inst);
		if (inst.input) {
			inst.input.val(clear ? '' : this._formatDate(inst));
		}
	},

	/* Retrieve the date(s) directly. */
	_getDate: function(inst) {
		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
			this._daylightSavingAdjust(new Date(
			inst.currentYear, inst.currentMonth, inst.currentDay)));
			return startDate;
	},

	/* Generate the HTML for the current state of the date picker. */
	_generateHTML: function(inst) {
		var today = new Date();
		today = this._daylightSavingAdjust(
			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
		var isRTL = this._get(inst, 'isRTL');
		var showButtonPanel = this._get(inst, 'showButtonPanel');
		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
		var numMonths = this._getNumberOfMonths(inst);
		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
		var stepMonths = this._get(inst, 'stepMonths');
		var stepBigMonths = this._get(inst, 'stepBigMonths');
		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
		var minDate = this._getMinMaxDate(inst, 'min', true);
		var maxDate = this._getMinMaxDate(inst, 'max');
		var drawMonth = inst.drawMonth - showCurrentAtPos;
		var drawYear = inst.drawYear;
		if (drawMonth < 0) {
			drawMonth += 12;
			drawYear--;
		}
		if (maxDate) {
			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
				maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate()));
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
				drawMonth--;
				if (drawMonth < 0) {
					drawMonth = 11;
					drawYear--;
				}
			}
		}
		inst.drawMonth = drawMonth;
		inst.drawYear = drawYear;
		var prevText = this._get(inst, 'prevText');
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
			this._getFormatConfig(inst)));
		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
			'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
		var nextText = this._get(inst, 'nextText');
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
			this._getFormatConfig(inst)));
		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
			'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
		var currentText = this._get(inst, 'currentText');
		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
		currentText = (!navigationAsDateFormat ? currentText :
			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
		var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
			(this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
		firstDay = (isNaN(firstDay) ? 0 : firstDay);
		var dayNames = this._get(inst, 'dayNames');
		var dayNamesShort = this._get(inst, 'dayNamesShort');
		var dayNamesMin = this._get(inst, 'dayNamesMin');
		var monthNames = this._get(inst, 'monthNames');
		var monthNamesShort = this._get(inst, 'monthNamesShort');
		var beforeShowDay = this._get(inst, 'beforeShowDay');
		var showOtherMonths = this._get(inst, 'showOtherMonths');
		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
		var endDate = inst.endDay ? this._daylightSavingAdjust(
			new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate;
		var defaultDate = this._getDefaultDate(inst);
		var html = '';
		for (var row = 0; row < numMonths[0]; row++) {
			var group = '';
			for (var col = 0; col < numMonths[1]; col++) {
				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
				var cornerClass = ' ui-corner-all';
				var calender = '';
				if (isMultiMonth) {
					calender += '<div class="ui-datepicker-group ui-datepicker-group-';
					switch (col) {
						case 0: calender += 'first'; cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
						case numMonths[1]-1: calender += 'last'; cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
						default: calender += 'middle'; cornerClass = ''; break;
					}
					calender += '">';
				}
				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
					selectedDate, row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
					'</div><table class="ui-datepicker-calendar"><thead>' +
					'<tr>';
				var thead = '';
				for (var dow = 0; dow < 7; dow++) { // days of the week
					var day = (dow + firstDay) % 7;
					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
				}
				calender += thead + '</tr></thead><tbody>';
				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
				var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
					calender += '<tr>';
					var tbody = '';
					for (var dow = 0; dow < 7; dow++) { // create date picker days
						var daySettings = (beforeShowDay ?
							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
						var otherMonth = (printDate.getMonth() != drawMonth);
						var unselectable = otherMonth || !daySettings[0] ||
							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
						tbody += '<td class="' +
							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
							' ' + this._dayOverClass : '') + // highlight selected day
							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
							(printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
							' ' + this._currentClass : '') + // highlight selected day
							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
							(unselectable ? '' : ' onclick="DP_jQuery.datepicker._selectDay(\'#' +
							inst.id + '\',' + drawMonth + ',' + drawYear + ', this);return false;"') + '>' + // actions
							(otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
							(printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
							' ui-state-active' : '') + // highlight selected day
							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
						printDate.setDate(printDate.getDate() + 1);
						printDate = this._daylightSavingAdjust(printDate);
					}
					calender += tbody + '</tr>';
				}
				drawMonth++;
				if (drawMonth > 11) {
					drawMonth = 0;
					drawYear++;
				}
				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
				group += calender;
			}
			html += group;
		}
		html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
		inst._keyEvent = false;
		return html;
	},

	/* Generate the month and year header. */
	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
			selectedDate, secondary, monthNames, monthNamesShort) {
		minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
		var changeMonth = this._get(inst, 'changeMonth');
		var changeYear = this._get(inst, 'changeYear');
		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
		var html = '<div class="ui-datepicker-title">';
		var monthHtml = '';
		if (secondary || !changeMonth)
			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span> ';
		else {
			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
			monthHtml += '<select class="ui-datepicker-month" ' +
				'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
				'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
			 	'>';
			for (var month = 0; month < 12; month++) {
				if ((!inMinYear || month >= minDate.getMonth()) &&
						(!inMaxYear || month <= maxDate.getMonth()))
					monthHtml += '<option value="' + month + '"' +
						(month == drawMonth ? ' selected="selected"' : '') +
						'>' + monthNamesShort[month] + '</option>';
			}
			monthHtml += '</select>';
		}
		if (!showMonthAfterYear)
			html += monthHtml + ((secondary || changeMonth || changeYear) && (!(changeMonth && changeYear)) ? '&#xa0;' : '');
		if (secondary || !changeYear)
			html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
		else {
			var years = this._get(inst, 'yearRange').split(':');
			var year = 0;
			var endYear = 0;
			if (years.length != 2) {
				year = drawYear - 10;
				endYear = drawYear + 10;
			} else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
				year = drawYear + parseInt(years[0], 10);
				endYear = drawYear + parseInt(years[1], 10);
			} else {
				year = parseInt(years[0], 10);
				endYear = parseInt(years[1], 10);
			}
			year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
			endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
			html += '<select class="ui-datepicker-year" ' +
				'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
				'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
				'>';
			for (; year <= endYear; year++) {
				html += '<option value="' + year + '"' +
					(year == drawYear ? ' selected="selected"' : '') +
					'>' + year + '</option>';
			}
			html += '</select>';
		}
		if (showMonthAfterYear)
			html += (secondary || changeMonth || changeYear ? '&#xa0;' : '') + monthHtml;
		html += '</div>'; // Close datepicker_header
		return html;
	},

	/* Adjust one of the date sub-fields. */
	_adjustInstDate: function(inst, offset, period) {
		var year = inst.drawYear + (period == 'Y' ? offset : 0);
		var month = inst.drawMonth + (period == 'M' ? offset : 0);
		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
			(period == 'D' ? offset : 0);
		var date = this._daylightSavingAdjust(new Date(year, month, day));
		var minDate = this._getMinMaxDate(inst, 'min', true);
		var maxDate = this._getMinMaxDate(inst, 'max');
		date = (minDate && date < minDate ? minDate : date);
		date = (maxDate && date > maxDate ? maxDate : date);
		inst.selectedDay = date.getDate();
		inst.drawMonth = inst.selectedMonth = date.getMonth();
		inst.drawYear = inst.selectedYear = date.getFullYear();
		if (period == 'M' || period == 'Y')
			this._notifyChange(inst);
	},

	/* Notify change of month/year. */
	_notifyChange: function(inst) {
		var onChange = this._get(inst, 'onChangeMonthYear');
		if (onChange)
			onChange.apply((inst.input ? inst.input[0] : null),
				[inst.selectedYear, inst.selectedMonth + 1, inst]);
	},

	/* Determine the number of months to show. */
	_getNumberOfMonths: function(inst) {
		var numMonths = this._get(inst, 'numberOfMonths');
		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
	},

	/* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
	_getMinMaxDate: function(inst, minMax, checkRange) {
		var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
		return (!checkRange || !inst.rangeStart ? date :
			(!date || inst.rangeStart > date ? inst.rangeStart : date));
	},

	/* Find the number of days in a given month. */
	_getDaysInMonth: function(year, month) {
		return 32 - new Date(year, month, 32).getDate();
	},

	/* Find the day of the week of the first of a month. */
	_getFirstDayOfMonth: function(year, month) {
		return new Date(year, month, 1).getDay();
	},

	/* Determines if we should allow a "next/prev" month display change. */
	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
		var numMonths = this._getNumberOfMonths(inst);
		var date = this._daylightSavingAdjust(new Date(
			curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1));
		if (offset < 0)
			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
		return this._isInRange(inst, date);
	},

	/* Is the given date in the accepted range? */
	_isInRange: function(inst, date) {
		var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust(
			new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)));
		newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
		var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
		var maxDate = this._getMinMaxDate(inst, 'max');
		return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
	},

	/* Provide the configuration settings for formatting/parsing. */
	_getFormatConfig: function(inst) {
		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
		return {shortYearCutoff: shortYearCutoff,
			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
	},

	/* Format the given date for display. */
	_formatDate: function(inst, day, month, year) {
		if (!day) {
			inst.currentDay = inst.selectedDay;
			inst.currentMonth = inst.selectedMonth;
			inst.currentYear = inst.selectedYear;
		}
		var date = (day ? (typeof day == 'object' ? day :
			this._daylightSavingAdjust(new Date(year, month, day))) :
			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
	}
});

/* jQuery extend now ignores nulls! */
function extendRemove(target, props) {
	$.extend(target, props);
	for (var name in props)
		if (props[name] == null || props[name] == undefined)
			target[name] = props[name];
	return target;
};

/* Determine whether an object is an array. */
function isArray(a) {
	return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
		(a.constructor && a.constructor.toString().match(/\Array\(\)/))));
};

/* Invoke the datepicker functionality.
   @param  options  string - a command, optionally followed by additional parameters or
                    Object - settings for attaching new datepicker functionality
   @return  jQuery object */
$.fn.datepicker = function(options){

	/* Initialise the date picker. */
	if (!$.datepicker.initialized) {
		$(document).mousedown($.datepicker._checkExternalClick).
			find('body').append($.datepicker.dpDiv);
		$.datepicker.initialized = true;
	}

	var otherArgs = Array.prototype.slice.call(arguments, 1);
	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))
		return $.datepicker['_' + options + 'Datepicker'].
			apply($.datepicker, [this[0]].concat(otherArgs));
	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
		return $.datepicker['_' + options + 'Datepicker'].
			apply($.datepicker, [this[0]].concat(otherArgs));
	return this.each(function() {
		typeof options == 'string' ?
			$.datepicker['_' + options + 'Datepicker'].
				apply($.datepicker, [this].concat(otherArgs)) :
			$.datepicker._attachDatepicker(this, options);
	});
};

$.datepicker = new Datepicker(); // singleton instance
$.datepicker.initialized = false;
$.datepicker.uuid = new Date().getTime();
$.datepicker.version = "1.7.2";

window.DP_jQuery = $;

})(jQuery);

(function($) {

  var Sammy,
      PATH_REPLACER = "([^\/]+)",
      PATH_NAME_MATCHER = /:([\w\d]+)/g,
      QUERY_STRING_MATCHER = /\?([^#]*)$/,
      _makeArray = function(nonarray) { return Array.prototype.slice.call(nonarray); },
      _isFunction = function( obj ) { return Object.prototype.toString.call(obj) === "[object Function]"; },
      _isArray = function( obj ) { return Object.prototype.toString.call(obj) === "[object Array]"; },
      _decode = decodeURIComponent,
      _routeWrapper = function(verb) {
        return function(path, callback) { return this.route.apply(this, [verb, path, callback]); };
      },
      _template_cache = {},
      loggers = [];


  Sammy = function() {
    var args = _makeArray(arguments),
        app, selector;
    Sammy.apps = Sammy.apps || {};
    if (args.length === 0 || args[0] && _isFunction(args[0])) { // Sammy()
      return Sammy.apply(Sammy, ['body'].concat(args));
    } else if (typeof (selector = args.shift()) == 'string') { // Sammy('#main')
      app = Sammy.apps[selector] || new Sammy.Application();
      app.element_selector = selector;
      if (args.length > 0) {
        $.each(args, function(i, plugin) {
          app.use(plugin);
        });
      }
      if (app.element_selector != selector) {
        delete Sammy.apps[selector];
      }
      Sammy.apps[app.element_selector] = app;
      return app;
    }
  };

  Sammy.VERSION = '0.6.0pre';

  Sammy.addLogger = function(logger) {
    loggers.push(logger);
  };

  Sammy.log = function()  {
    var args = _makeArray(arguments);
    args.unshift("[" + Date() + "]");
    $.each(loggers, function(i, logger) {
      logger.apply(Sammy, args);
    });
  };

  if (typeof window.console != 'undefined') {
    if (_isFunction(console.log.apply)) {
      Sammy.addLogger(function() {
        window.console.log.apply(console, arguments);
      });
    } else {
      Sammy.addLogger(function() {
        window.console.log(arguments);
      });
    }
  } else if (typeof console != 'undefined') {
    Sammy.addLogger(function() {
      console.log.apply(console, arguments);
    });
  }

  $.extend(Sammy, {
    makeArray: _makeArray,
    isFunction: _isFunction,
    isArray: _isArray
  })

  Sammy.Object = function(obj) { // constructor
    return $.extend(this, obj || {});
  };

  $.extend(Sammy.Object.prototype, {

    toHash: function() {
      var json = {};
      $.each(this, function(k,v) {
        if (!_isFunction(v)) {
          json[k] = v;
        }
      });
      return json;
    },

    toHTML: function() {
      var display = "";
      $.each(this, function(k, v) {
        if (!_isFunction(v)) {
          display += "<strong>" + k + "</strong> " + v + "<br />";
        }
      });
      return display;
    },

    keys: function(attributes_only) {
      var keys = [];
      for (var property in this) {
        if (!_isFunction(this[property]) || !attributes_only) {
          keys.push(property);
        }
      }
      return keys;
    },

    has: function(key) {
      return this[key] && $.trim(this[key].toString()) != '';
    },

    join: function() {
      var args = _makeArray(arguments);
      var delimiter = args.shift();
      return args.join(delimiter);
    },

    log: function() {
      Sammy.log.apply(Sammy, arguments);
    },

    toString: function(include_functions) {
      var s = [];
      $.each(this, function(k, v) {
        if (!_isFunction(v) || include_functions) {
          s.push('"' + k + '": ' + v.toString());
        }
      });
      return "Sammy.Object: {" + s.join(',') + "}";
    }
  });

  Sammy.HashLocationProxy = function(app, run_interval_every) {
    this.app = app;
    this.is_native = false;
    this._startPolling(run_interval_every);
  };

  Sammy.HashLocationProxy.prototype = {
    bind: function() {
      var proxy = this, app = this.app;
      $(window).bind('hashchange.' + this.app.eventNamespace(), function(e, non_native) {
        if (proxy.is_native === false && !non_native) {
          Sammy.log('native hash change exists, using');
          proxy.is_native = true;
          clearInterval(Sammy.HashLocationProxy._interval);
        }
        app.trigger('location-changed');
      });
    },
    unbind: function() {
      $(window).unbind('hashchange.' + this.app.eventNamespace());
    },
    getLocation: function() {
      var matches = window.location.toString().match(/^[^#]*(#.+)$/);
      return matches ? matches[1] : '';
    },
    setLocation: function(new_location) {
      return (window.location = new_location);
    },

    _startPolling: function(every) {
      var proxy = this;
      if (!Sammy.HashLocationProxy._interval) {
        if (!every) { every = 10; }
        var hashCheck = function() {
          current_location = proxy.getLocation();
          if (!Sammy.HashLocationProxy._last_location ||
            current_location != Sammy.HashLocationProxy._last_location) {
            setTimeout(function() {
              $(window).trigger('hashchange', [true]);
            }, 1);
          }
          Sammy.HashLocationProxy._last_location = current_location;
        };
        hashCheck();
        Sammy.HashLocationProxy._interval = setInterval(hashCheck, every);
        $(window).bind('beforeunload', function() {
          clearInterval(Sammy.HashLocationProxy._interval);
        });
      }
    }
  };


  Sammy.Application = function(app_function) {
    var app = this;
    this.routes            = {};
    this.listeners         = new Sammy.Object({});
    this.arounds           = [];
    this.befores           = [];
    this.namespace         = (new Date()).getTime() + '-' + parseInt(Math.random() * 1000, 10);
    this.context_prototype = function() { Sammy.EventContext.apply(this, arguments); };
    this.context_prototype.prototype = new Sammy.EventContext();

    if (_isFunction(app_function)) {
      app_function.apply(this, [this]);
    }
    if (!this.location_proxy) {
      this.location_proxy = new Sammy.HashLocationProxy(app, this.run_interval_every);
    }
    if (this.debug) {
      this.bindToAllEvents(function(e, data) {
        app.log(app.toString(), e.cleaned_type, data || {});
      });
    }
  };

  Sammy.Application.prototype = $.extend({}, Sammy.Object.prototype, {

    ROUTE_VERBS: ['get','post','put','delete'],

    APP_EVENTS: ['run','unload','lookup-route','run-route','route-found','event-context-before','event-context-after','changed','error','check-form-submission','redirect'],

    _last_route: null,
    _running: false,

    element_selector: 'body',

    debug: false,

    raise_errors: false,

    run_interval_every: 50,

    location_proxy: null,

    template_engine: null,

    history: [],

    toString: function() {
      return 'Sammy.Application:' + this.element_selector;
    },

    $element: function() {
      return $(this.element_selector);
    },

    use: function() {
      var args = _makeArray(arguments);
      var plugin = args.shift();
      try {
        args.unshift(this);
        plugin.apply(this, args);
      } catch(e) {
        if (typeof plugin == 'undefined') {
          this.error("Plugin Error: called use() but plugin is not defined", e);
        } else if (!_isFunction(plugin)) {
          this.error("Plugin Error: called use() but '" + plugin.toString() + "' is not a function", e);
        } else {
          this.error("Plugin Error", e);
        }
      }
      return this;
    },

    route: function(verb, path, callback) {
      var app = this, param_names = [], add_route;

      if (!callback && _isFunction(path)) {
        path = verb;
        callback = path;
        verb = 'any';
      }

      verb = verb.toLowerCase(); // ensure verb is lower case

      if (_isArray(path)) {
        for (var i = 0; i < path.length; i++) {
          this.route(verb, path[i], callback);
        }
        return this;
      }

      if (path.constructor == String) {
        PATH_NAME_MATCHER.lastIndex = 0;

        while ((path_match = PATH_NAME_MATCHER.exec(path)) !== null) {
          param_names.push(path_match[1]);
        }
        path = new RegExp("^" + path.replace(PATH_NAME_MATCHER, PATH_REPLACER) + "$");
      }
      if (typeof callback == 'string') {
        callback = app[callback];
      }

      add_route = function(with_verb) {
        var r = {verb: with_verb, path: path, callback: callback, param_names: param_names};
        app.routes[with_verb] = app.routes[with_verb] || [];
        app.routes[with_verb].push(r);
      };

      if (verb === 'any') {
        $.each(this.ROUTE_VERBS, function(i, v) { add_route(v); });
      } else {
        add_route(verb);
      }

      return this;
    },

    get: _routeWrapper('get'),

    post: _routeWrapper('post'),

    put: _routeWrapper('put'),

    del: _routeWrapper('delete'),

    any: _routeWrapper('any'),

    mapRoutes: function(route_array) {
      var app = this;
      $.each(route_array, function(i, route_args) {
        app.route.apply(app, route_args);
      });
      return this;
    },

    eventNamespace: function() {
      return ['sammy-app', this.namespace].join('-');
    },

    bind: function(name, data, callback) {
      var app = this;
      if (typeof callback == 'undefined') { callback = data; }
      var listener_callback =  function() {
        var e, context, data;
        e       = arguments[0];
        data    = arguments[1];
        if (data && data.context) {
          context = data.context;
          delete data.context;
        } else {
          context = new app.context_prototype(app, 'bind', e.type, data, e.target);
        }
        e.cleaned_type = e.type.replace(app.eventNamespace(), '');
        callback.apply(context, [e, data]);
      };

      if (!this.listeners[name]) { this.listeners[name] = []; }
      this.listeners[name].push(listener_callback);
      if (this.isRunning()) {
        this._listen(name, listener_callback);
      }
      return this;
    },

    trigger: function(name, data) {
      this.$element().trigger([name, this.eventNamespace()].join('.'), [data]);
      return this;
    },

    refresh: function() {
      this.last_location = null;
      this.trigger('location-changed');
      return this;
    },

    getHistory: function(index) {
      if (index < 0) index = this.history.length + index;
      return this.history[index];
    },

    before: function(options, callback) {
      if (_isFunction(options)) {
        callback = options;
        options = {};
      }
      this.befores.push([options, callback]);
      return this;
    },

    after: function(callback) {
      return this.bind('event-context-after', callback);
    },


    around: function(callback) {
      this.arounds.push(callback);
      return this;
    },

    isRunning: function() {
      return this._running;
    },

    helpers: function(extensions) {
      $.extend(this.context_prototype.prototype, extensions);
      return this;
    },

    helper: function(name, method) {
      this.context_prototype.prototype[name] = method;
      return this;
    },

    run: function(start_url) {
      if (this.isRunning()) { return false; }
      var app = this;

      $.each(this.listeners.toHash(), function(name, callbacks) {
        $.each(callbacks, function(i, listener_callback) {
          app._listen(name, listener_callback);
        });
      });

      this.trigger('run', {start_url: start_url});
      this._running = true;
      this.last_location = null;
      if (this.getLocation() == '' && typeof start_url != 'undefined') {
        this.setLocation(start_url);
      }
      this._checkLocation();
      this.location_proxy.bind();
      this.bind('location-changed', function() {
        app._checkLocation();
      });

      this.bind('submit', function(e) {
        var returned = app._checkFormSubmission($(e.target).closest('form'));
        return (returned === false) ? e.preventDefault() : false;
      });

      $(window).bind('beforeunload', function() {
        app.unload();
      });

      return this.trigger('changed');
    },

    unload: function() {
      if (!this.isRunning()) { return false; }
      var app = this;
      this.trigger('unload');
      this.location_proxy.unbind();
      this.$element().unbind('submit').removeClass(app.eventNamespace());
      $.each(this.listeners.toHash() , function(name, listeners) {
        $.each(listeners, function(i, listener_callback) {
          app._unlisten(name, listener_callback);
        });
      });
      this._running = false;
      return this;
    },

    bindToAllEvents: function(callback) {
      var app = this;
      $.each(this.APP_EVENTS, function(i, e) {
        app.bind(e, callback);
      });
      $.each(this.listeners.keys(true), function(i, name) {
        if (app.APP_EVENTS.indexOf(name) == -1) {
          app.bind(name, callback);
        }
      });
      return this;
    },

    routablePath: function(path) {
      return path.replace(QUERY_STRING_MATCHER, '');
    },

    lookupRoute: function(verb, path) {
      var app = this, routed = false;
      this.trigger('lookup-route', {verb: verb, path: path});
      if (typeof this.routes[verb] != 'undefined') {
        $.each(this.routes[verb], function(i, route) {
          if (app.routablePath(path).match(route.path)) {
            routed = route;
            return false;
          }
        });
      }
      return routed;
    },

    runRoute: function(verb, path, params, target) {
      var app = this,
          route = this.lookupRoute(verb, path),
          context,
          wrapped_route,
          arounds,
          around,
          befores,
          before,
          callback_args,
          final_returned;

      this.log('runRoute', [verb, path].join(' '));
      this.trigger('run-route', {verb: verb, path: path, params: params});
      if (typeof params == 'undefined') { params = {}; }

      $.extend(params, this._parseQueryString(path));

      if (route) {
        this.trigger('route-found', {route: route});
        if ((path_params = route.path.exec(this.routablePath(path))) !== null) {
          path_params.shift();
          $.each(path_params, function(i, param) {
            if (route.param_names[i]) {
              params[route.param_names[i]] = _decode(param);
            } else {
              if (!params.splat) { params.splat = []; }
              params.splat.push(_decode(param));
            }
          });
        }

        context  = new this.context_prototype(this, verb, path, params, target);
        arounds = this.arounds.slice(0);
        befores = this.befores.slice(0);
        callback_args = [context].concat(params.splat);
        wrapped_route = function() {
          var returned;
          while (befores.length > 0) {
            before = befores.shift();
            if (app.contextMatchesOptions(context, before[0])) {
              returned = before[1].apply(context, [context]);
              if (returned === false) { return false; }
            }
          }
          app.last_route = route;
          context.trigger('event-context-before', {context: context});
          returned = route.callback.apply(context, callback_args);
          context.trigger('event-context-after', {context: context});
          return returned;
        };
        $.each(arounds.reverse(), function(i, around) {
          var last_wrapped_route = wrapped_route;
          wrapped_route = function() { return around.apply(context, [last_wrapped_route]); };
        });
        try {
          final_returned = wrapped_route();
        } catch(e) {
          this.error(['500 Error', verb, path].join(' '), e);
        }
        return final_returned;
      } else {
        return this.notFound(verb, path);
      }
    },

    contextMatchesOptions: function(context, match_options, positive) {
      var options = match_options;
      if (typeof options === 'undefined' || options == {}) {
        return true;
      }
      if (typeof positive === 'undefined') {
        positive = true;
      }
      if (typeof options === 'string' || _isFunction(options.test)) {
        options = {path: options};
      }
      if (options.only) {
        return this.contextMatchesOptions(context, options.only, true);
      } else if (options.except) {
        return this.contextMatchesOptions(context, options.except, false);
      }
      var path_matched = true, verb_matched = true;
      if (options.path) {
        if (_isFunction(options.path.test)) {
          path_matched = options.path.test(context.path);
        } else {
          path_matched = (options.path.toString() === context.path);
        }
      }
      if (options.verb) {
        verb_matched = options.verb === context.verb;
      }
      return positive ? (verb_matched && path_matched) : !(verb_matched && path_matched);
    },


    getLocation: function() {
      return this.location_proxy.getLocation();
    },

    setLocation: function(new_location) {
      return this.location_proxy.setLocation(new_location);
    },

    swap: function(content) {
      return this.$element().html(content);
    },

    templateCache: function(key, value) {
      if (typeof value != 'undefined') {
        return _template_cache[key] = value;
      } else {
        return _template_cache[key];
      }
    },

    notFound: function(verb, path) {
      var ret = this.error(['404 Not Found', verb, path].join(' '));
      return (verb === 'get') ? ret : true;
    },

    error: function(message, original_error) {
      if (!original_error) { original_error = new Error(); }
      original_error.message = [message, original_error.message].join(' ');
      this.trigger('error', {message: original_error.message, error: original_error});
      if (this.raise_errors) {
        throw(original_error);
      } else {
        this.log(original_error.message, original_error);
      }
    },

    _checkLocation: function() {
      var location, returned;
      location = this.getLocation();
      if (location != this.last_location) {
        this.last_location = location;
        returned = this.runRoute('get', location);
      }
      return returned;
    },

    _checkFormSubmission: function(form) {
      var $form, path, verb, params, returned;
      this.trigger('check-form-submission', {form: form});
      $form = $(form);
      path  = $form.attr('action');
      verb  = $.trim($form.attr('method').toString().toLowerCase());
      if (!verb || verb == '') { verb = 'get'; }
      this.log('_checkFormSubmission', $form, path, verb);
      if (verb === 'get') {
        this.setLocation(path + '?' + $form.serialize());
        returned = false;
      } else {
        params = $.extend({}, this._parseFormParams($form));
        returned = this.runRoute(verb, path, params, form.get(0));
      };
      return (typeof returned == 'undefined') ? false : returned;
    },

    _parseFormParams: function($form) {
      var params = {},
          form_fields = $form.serializeArray(),
          i;
      for (i = 0; i < form_fields.length; i++) {
        params = this._parseParamPair(params, form_fields[i].name, form_fields[i].value);
      }
      return params;
    },

    _parseQueryString: function(path) {
      var params = {}, parts, pairs, pair, i;

      parts = path.match(QUERY_STRING_MATCHER);
      if (parts) {
        pairs = parts[1].split('&');
        for (i = 0; i < pairs.length; i++) {
          pair = pairs[i].split('=');
          params = this._parseParamPair(params, _decode(pair[0]), _decode(pair[1]));
        }
      }
      return params;
    },

    _parseParamPair: function(params, key, value) {
      if (params[key]) {
        if (_isArray(params[key])) {
          params[key].push(value);
        } else {
          params[key] = [params[key], value];
        }
      } else {
        params[key] = value;
      }
      return params;
    },

    _listen: function(name, callback) {
      return this.$element().bind([name, this.eventNamespace()].join('.'), callback);
    },

    _unlisten: function(name, callback) {
      return this.$element().unbind([name, this.eventNamespace()].join('.'), callback);
    }

  });

  Sammy.RenderContext = function(event_context) {
    this.event_context = event_context;
    this.callbacks = [];
    this.previous_content = null;
    this.content = null;
    this.next_engine = false;
    this.waiting = false;
  };

  $.extend(Sammy.RenderContext.prototype, {

    load: function(location, options, callback) {
      var context = this;
      return this.then(function() {
        var should_cache, cached;
        if (_isFunction(options)) {
          callback = options;
          options = {};
        } else {
          options = $.extend({}, options);
        }
        if (callback) { this.then(callback); }
        if (typeof location === 'string') {
          should_cache = !(options.cache === false);
          delete options.cache;
          if (options.engine) {
            context.next_engine = options.engine;
            delete options.engine;
          }
          if (should_cache && (cached = this.event_context.app.templateCache(location))) {
            return cached;
          }
          this.wait();
          $.ajax($.extend({
            url: location,
            data: {},
            type: 'get',
            success: function(data) {
              if (should_cache) {
                context.event_context.app.templateCache(location, data);
              }
              context.content = data;
              context.next();
            }
          }, options));
          return false;
        } else {
          if (location.nodeType) {
            return location.innerHTML;
          }
          if (location.selector) {
            context.next_engine = location.attr('data-engine');
            if (options.clone === false) {
              return location.remove()[0].innerHTML.toString();
            } else {
              return location[0].innerHTML.toString();
            }
          }
        }
      });
    },

    render: function(location, data, callback) {
      if (_isFunction(location) && !data) {
        return this.then(location);
      } else {
        return this.load(location).interpolate(data, location).then(callback);
      }
    },

    collect: function(array, callback) {
      var context = this;
      return this.then(function() {
        var contents = "";
        $.each(array, function(i, item) {
          var returned = callback.apply(context, [i, item]);
          contents += returned;
          return returned;
        });
        return contents;
      });
    },

    renderEach: function(path, name, data, callback) {
      if (_isArray(name)) {
        callback = data;
        data = name;
        name = null;
      }
      return this.load(path).collect(data, function(i, value) {
        var idata = {};
        name ? (idata[name] = value) : (idata = value);
        return this.event_context.interpolate(this.content, idata, path);
      });
    },

    then: function(callback) {
      if (_isFunction(callback)) {
        var context = this;
        if (this.waiting) {
          this.callbacks.push(callback);
        } else {
          this.wait();
          setTimeout(function() {
            var returned = callback.apply(context, [context.content, context.previous_content]);
            if (returned !== false) {
              if (typeof returned !== 'undefined') {
                context.previous_content = context.content;
                context.content = returned;
              }
              context.next();
            }
          }, 13);
        }
      }
      return this;
    },

    interpolate: function(data, engine, retain) {
      var context = this;
      return this.then(function(content, prev) {
        if (this.next_engine) {
          engine = this.next_engine;
          this.next_engine = false;
        }
        var rendered = context.event_context.interpolate(content, data, engine);
        return retain ? prev + rendered : rendered;
      });
    },

    swap: function() {
      return this.then(function(content) {
        this.event_context.swap(content);
      });
    },

    appendTo: function(selector) {
      return this.then(function(content) {
        $(selector).append(content);
      });
    },

    replace: function(selector) {
      return this.then(function(content) {
        $(selector).html(content);
      });
    },

    wait: function() {
      this.waiting = true;
    },

    next: function() {
      this.waiting = false;
      if (this.callbacks.length > 0) {
        this.then(this.callbacks.shift());
      }
    }

  });

  Sammy.EventContext = function(app, verb, path, params, target) {
    this.app    = app;
    this.verb   = verb;
    this.path   = path;
    this.params = new Sammy.Object(params);
    this.target = target;
  };

  Sammy.EventContext.prototype = $.extend({}, Sammy.Object.prototype, {

    $element: function() {
      return this.app.$element();
    },

    engineFor: function(engine) {
      var context = this, engine_match;
      if (_isFunction(engine)) { return engine; }
      engine = engine.toString();
      if ((engine_match = engine.match(/\.([^\.]+)$/))) { engine = engine_match[1]; }
      if (engine && _isFunction(context[engine])) {
        return context[engine];
      }
      if (context.app.template_engine) {
        return this.engineFor(context.app.template_engine);
      }
      return function(content, data) { return content; };
    },

    interpolate: function(content, data, engine) {
      Sammy.log('engine for', engine, this.engineFor(engine));
      return this.engineFor(engine).apply(this, [content, data]);
    },

    partial: function(path, data) {
      return this.render(path, data).swap();
    },

    redirect: function() {
      var to, args = _makeArray(arguments),
          current_location = this.app.getLocation();
      if (args.length > 1) {
        args.unshift('/');
        to = this.join.apply(this, args);
      } else {
        to = args[0];
      }
      this.trigger('redirect', {to: to});
      this.app.last_location = this.path;
      this.app.setLocation(to);
      if (current_location == to) {
        this.app.trigger('location-changed');
      }
    },

    trigger: function(name, data) {
      if (typeof data == 'undefined') { data = {}; }
      if (!data.context) { data.context = this; }
      return this.app.trigger(name, data);
    },

    eventNamespace: function() {
      return this.app.eventNamespace();
    },

    swap: function(contents) {
      return this.app.swap(contents);
    },

    notFound: function() {
      return this.app.notFound(this.verb, this.path);
    },

    toString: function() {
      return "Sammy.EventContext: " + [this.verb, this.path, this.params].join(' ');
    },

    render: function(path, data, callback) {
      return new Sammy.RenderContext(this).render(path, data, callback);
    },

    load: function(path, params, callback) {
      return new Sammy.RenderContext(this).load(path, params, callback);
    }

  });

  $.sammy = window.Sammy = Sammy;

})(jQuery);
(function($) {
	var imgList = [];
	$.extend({
		preload: function(imgArr, option) {
			var setting = $.extend({
				init: function(loaded, total) {},
				loaded: function(img, loaded, total) {},
				loaded_all: function(loaded, total) {}
			}, option);
			var total = imgArr.length;
			var loaded = 0;

			setting.init(0, total);
			for(var i in imgArr) {
				imgList.push($("<img />")
					.attr("src", imgArr[i]+"?"+Math.random()*999999)
					.load(function() {
						loaded++;
						setting.loaded(this, loaded, total);
						if(loaded == total) {
							setting.loaded_all(loaded, total);
						}
					})
				);
			}

		}
	});
})(jQuery);

/*
 * jQuery UI Autocomplete
 * version: 1.0 (1/2/2008)
 * @requires: jQuery v1.2 or later, dimensions plugin
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Copyright 2007 Yehuda Katz, Rein Henrichs
 */

(function($) {
  $.ui = $.ui || {};
  $.ui.autocomplete = $.ui.autocomplete || {};
  $.ui.autocomplete.ext = $.ui.autocomplete.ext || {};

  $.ui.autocomplete.ext.ajax = function(opt) {
    var ajax = opt.ajax;
    return { getList: function(input) {
			if (input.val().match(/^\s*$/)) return false;
      $.getJSON(ajax, "val=" + input.val(), function(json) { input.trigger("updateList", [json]); });
    } };
  };

  $.ui.autocomplete.ext.templateText = function(opt) {
    var template = $.makeTemplate(opt.templateText, "<%", "%>");
    return { template: function(obj) { return template(obj); } };
  };

})(jQuery);
/* jQuery Autocomplete
 * Version 1.0
 * Written by Yehuda Katz (wycats@gmail.com) and Rein Henrichs (reinh@reinh.com)
 * @requires jQuery v1.2, jQuery dimensions plugin
 *
 * Copyright 2007 Yehuda Katz, Rein Henrichs
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */

/*
 * @description Form autocomplete plugin using preloaded or Ajax JSON data source
 *
 * @example $('input#user-name').autocomplete({list: ["quentin", "adam", "admin"]})
 * @desc Simple autocomplete with basic JSON data source
 *
 * @example $('input#user-name').autocomplete({ajax: "/usernames.js"})
 * @desc Simple autocomplete with Ajax loaded JSON data source
 *
 */


(function($) {

  $.ui = $.ui || {}; $.ui.autocomplete = $.ui.autocomplete || {}; var active;

  var KEY = {
    ESC: 27,
    RETURN: 13,
    TAB: 9,
    BS: 8,
    DEL: 46,
    UP: 38,
    DOWN: 40,
    DELETELIKE: [8,46,97]
  };

  $.fn.autocompleteMode = function(container, input, size, opt) {
    var original = input.val(); var selected = 0; var self = this;

    $.data(document.body, "autocompleteMode", true);

    $("body").one("cancel.autocomplete", function() {
      input.trigger("cancel.autocomplete"); $("body").trigger("off.autocomplete"); input.val(original);
    });

    $("body").one("activate.autocomplete", function() {
      active && input.trigger("activate.autocomplete", [$.data(active[0], "originalObject")]);
      $("body").trigger("off.autocomplete");
    });

    $("body").one("off.autocomplete", function(e, reset) {
      container.remove();
      $.data(document.body, "autocompleteMode", false);
      input.unbind("keydown.autocomplete");
      $("body").add(window).unbind("click.autocomplete").unbind("cancel.autocomplete").unbind("activate.autocomplete");
    });

    $(window).bind("click.autocomplete", function() { $("body").trigger("cancel.autocomplete"); });

    var select = function() {
      active = $("> *", container).removeClass("active").slice(selected, selected + 1).addClass("active");
      input.trigger("itemSelected.autocomplete", [$.data(active[0], "originalObject")]);
      input.val(opt.insertText($.data(active[0], "originalObject")));
    };

    container.mouseover(function(e) {
      if(e.target == container[0]) return;
      selected = $("> *", container).index($(e.target).is('li') ? $(e.target)[0] : $(e.target).parents('li')[0]);
      select();
    }).bind("click.autocomplete", function(e) {
      $("body").trigger("activate.autocomplete"); $.data(document.body, "suppressKey", false);
    });

    input
      .bind("keydown.autocomplete", function(e) {
        var k = e.which || e.keyCode; // in IE e.which is undefined

        if(k == KEY.ESC) { $("body").trigger("cancel.autocomplete"); }
        else if(k == KEY.RETURN) {
          $.log('return');
          if ($.data(document.body, "autocompleteMode")) {
            $.log('activate autocomplete', selected);
            if (!selected || selected == -1) {
              select();
              e.stopPropagation();
            }
          }
          $("body").trigger("activate.autocomplete");
        }
        else if(k == KEY.UP || k == KEY.TAB || k == KEY.DOWN) {
          switch(k) {
            case KEY.DOWN:
            case KEY.TAB:
              selected = selected >= size - 1 ? 0 : selected + 1; break;
            case KEY.UP:
              selected = selected <= 0 ? size - 1 : selected - 1; break;
            default: break;
          }
          select();
        } else { return true; }
        $.data(document.body, "suppressKey", true);
      });
  };

  $.fn.autocomplete = function(opt) {

    opt = $.extend({}, {
      timeout: 1000,
      limit: 10,
      getList: function(input) { input.trigger("updateList", [opt.list]); },
      template: function(str) { return "<li>" + opt.insertText(str) + "</li>"; },
      insertText: function(str) { return str; },
      match: function(typed) { return this.match(new RegExp(typed)); },
      wrapper: "<ul class='jq-ui-autocomplete'></ul>"
    }, opt);

    if($.ui.autocomplete.ext) {
      for(var ext in $.ui.autocomplete.ext) {
        if(opt[ext]) {
          opt = $.extend(opt, $.ui.autocomplete.ext[ext](opt));
          delete opt[ext];
        }
    } }

    function preventTabInAutocompleteMode(e) {
      var k = e.which || e.keycode;
      if ($.data(document.body, "autocompleteMode") && k == KEY.TAB) {
        e.preventDefault();
      }
    }
    function startTypingTimeout(e) {
      $.data(this, "typingTimeout", window.setTimeout(function() {
        $(e.target || e.srcElement).trigger("autocomplete");
      }, opt.timeout));
    }

    return this.each(function() {
      $(this)
        .keydown(function(e) {
          preventTabInAutocompleteMode(e);
        })
        .keyup(function(e) {
          var k = e.which || e.keycode;
          if (!$.data(document.body, "autocompleteMode") &&
              (k == KEY.UP || k == KEY.DOWN) &&
              !$.data(this, "typingTimeout")) {
            startTypingTimeout(e);
          }
          else {
            preventTabInAutocompleteMode(e);
          }
        })
        .keyup(function(e) {
          var typingTimeout = $.data(this, "typingTimeout");
          var k = e.keyCode || e.which; // keyCode == 0 in Gecko/FF on keypress
          if(typingTimeout) window.clearInterval(typingTimeout);

          if($.data(document.body, "suppressKey"))
            return $.data(document.body, "suppressKey", false);
          else if($.data(document.body, "autocompleteMode") && k < 32 && $.inArray(k, KEY.DELETELIKE) == -1) return false;
          else if (k > 32 || $.inArray(k, KEY.DELETELIKE) != -1) { // more than ESC and RETURN and the like
            startTypingTimeout(e);
          }
        })
        .bind('click.autocomplete', function(e) {
          if (!$(this).blank() && !$.data(document.body, "autocompleteMode")) {
            $.log('click.autocomplete', e);
            e.stopPropagation();
            $(this).trigger('autocomplete');
          }
        })
        .bind("autocomplete", function() {
          var self = $(this);

          if (!self.data('search-active')) {
            self.one("updateList", function(e, newList) {
              var list = [], count = 0, current_val = self.val(), match;
              if (opt.matcher) current_val = opt.matcher.call(this, current_val);
              $.each(newList, function() {
                if ((match = opt.match.call(this, current_val))) {
                  list.push([match.index, this]);
                }
              });
              list.sort(function(a, b) {
                a = a[0], b = b[0];
                return a - b;
              });
              list = list.slice(0, opt.limit);
              list = $($.map(list, function(c, i) {
                var contact = c[1];
                var node = $(opt.template(contact, current_val));
                if (i == 0) { node.addClass('active'); }
                node = node[0];
                $.data(node, "originalObject", contact);
                return node;
              }));

              $("body").trigger("off.autocomplete");

              if(!list.length) return false;

              var container = list.wrapAll(opt.wrapper).parents(":last");
              var wrapper_tagName = $(opt.wrapper)[0].tagName;
              for (;container[0].tagName !== wrapper_tagName; container = container.children(':first')) {}

              var offset = self.offset();

              opt.container = container
                .css({top: offset.top + self.outerHeight(), left: offset.left, width: self.outerWidth()})
                .appendTo("body");

              $("body").autocompleteMode(container, self, list.length, opt);
            });

            opt.getList(self);
          }
        });

    });
  };

})(jQuery);

/*
 * jQuery UI 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/*
 * jQuery UI Progressbar 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Progressbar
 *
 * Depends:
 *   ui.core.js
 */
(function(a){a.widget("ui.progressbar",{_init:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=a('<div class="ui-progressbar-value ui-widget-header ui-corner-left"></div>').appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow").removeData("progressbar").unbind(".progressbar");this.valueDiv.remove();a.widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===undefined){return this._value()}this._setData("value",b);return this},_setData:function(b,c){switch(b){case"value":this.options.value=c;this._refreshValue();this._trigger("change",null,{});break}a.widget.prototype._setData.apply(this,arguments)},_value:function(){var b=this.options.value;if(b<this._valueMin()){b=this._valueMin()}if(b>this._valueMax()){b=this._valueMax()}return b},_valueMin:function(){var b=0;return b},_valueMax:function(){var b=100;return b},_refreshValue:function(){var b=this.value();this.valueDiv[b==this._valueMax()?"addClass":"removeClass"]("ui-corner-right");this.valueDiv.width(b+"%");this.element.attr("aria-valuenow",b)}});a.extend(a.ui.progressbar,{version:"1.7.2",defaults:{value:0}})})(jQuery);;

;(function($) {

  window.session_token = function(callback) {
    var success;
    if ($.isFunction(callback)) {
      success = callback;
    } else {
      success = function(data) {
        document.getElementById("flashcontent")[callback](data);
      };
    }
    $.ajax({
      url: '/token',
      success: success,
      type: 'POST',
      dataType: 'json',
      data: {}});
  };

})(jQuery);
(function($) {

  $.extend({

    log: function()  {
      var args = arguments;
      try {
        $(function() {
          if ($('body').attr('data-debug') == "true") {
            if (typeof window.console != 'undefined') {
              window.console.log.apply(window.console, args);
            } else if (typeof console != 'undefined') {
              console.log.apply(this, args);
            } else {
            }
          }
        });
      } catch(e) {
      }
    },

    guard: function(selector, callback) {
      $(function() {
        if ($(selector).length > 0) {
          callback($, $(selector));
        } else {
          return;
        }
      });
    },

    shove: function(fn, object) {
      return function() {
        return fn.apply(object, arguments);
      }
    },

    blank: function(val) {
      return !val || val === '' || !val.match(/\w+/);
    }

  });

  $.fn.extend({

    replaceClass: function(oldklass, newklass) {
      if (oldklass.constructor == RegExp) {
        $(this).each(function() {
          var class_names = this.className;
          if (class_names.match(old)) {
            this.className = class_names.replace(oldklass, newklass);
          } else {
            $(this).addClass(newklass);
          }
        });
      } else {
        $(this)
          .removeClass(oldklass)
          .addClass(newklass);
      }
      return $(this);
    },

    toggleText: function(on, off) {
      var $t = this;
      $t.text() == on ? $t.text(off) : $t.text(on)
    },

    serializeHash: function() {
      var h = {};
      $.each(this.serializeArray(), function() {
        if (typeof this.value != 'undefined') {
          h[this.name] = this.value
        }
      });
      return h;
    },

    blank: function() {
      return $.blank($(this).val().toString());
    },

    validForm: function(input_selector) {
      if (typeof input_selector == 'undefined') {
        input_selector = ':input.required';
      }
      $(this).find(input_selector).each(function() {
        valid = !($(this).blank());
        if (!valid) { return false };
      });
      return valid;
    },

    disable: function(text) {
      return $(this).each(function() {
        var $this = $(this);
        if ($this.is('input')) {
          $this.attr('disabled', 'disabled');
          if (text) {
            $this.data('original-text', $this.val());
            $this.val(text);
          }
        } else {
          $this.addClass('disabled');
          if (text) {
            $this.data('original-text', $this.text());
            $this.text(text);
          }
        }
      });
    },

    enable: function() {
      return $(this).each(function() {
        var $this = $(this),
            text  = $this.data('original-text');
        if ($this.is('input')) {
          $this.removeAttr('disabled');
          if (text) { $this.val(text); }
        } else {
          $this.removeClass('disabled');
          if (text) { $this.text(text); }
        }
      });
    },

    fadeOutSoon: function(when, length) {
      if (typeof when == "undefined") when = 10000;
      if (typeof length == "undefined") length = 1000;
      var $this = $(this);
      setTimeout(function() {
        $this.fadeOut(length)
      }, when);
      return $this;
    },

    setControl: function(control_name) {
      return $(this).addClass('control-' + control_name);
    },

    isControl: function(control_name) {
      return $(this).is('.control-' + control_name);
    },

    or: function(selector, context) {
      if ($(this).length > 0) {
        return $(this);
      } else {
        context = context || $(this).context;
        return $(selector, context);
      }
    },

    slideTo: function(speed) {
      if (!speed) { speed = 400; }
      var top = $(this).offset().top;
      $('body,html').animate({'scrollTop': top + 'px'}, speed);
    }
  });

})(jQuery);
;(function($) {

  PP = window.PP || {};

  $.extend(PP, {
    getEventID: function() {
      var match = window.location.pathname.match(/(events|stationery)\/([\d\w-]+)/);
      return (match ? match[2] : false);
    },

    eventPath: function() {
      var parts = $.makeArray(arguments);
      parts.unshift(PP.getEventID());
      parts.unshift('/events');
      return parts.join('/');
    },

    getConfirmation: function(msg, action) {
      if (confirm(msg)) {
        return !!(action && action());
      } else {
        alert("OK, no action was taken");
        return false;
      }
    },

    eventConfirmation: function(msg, event) {
      if (!confirm(msg)) {
        event.stopImmediatePropagation();
        alert("OK, no action was taken");
        return false
      }
    },

    getNotification: function(container, status, location) {
      var $container    = $(container);
      var $notification = $container.siblings('.notification.' + status)
                                    .or($container.selector + '.notification');

      $.log('notification', $notification);
      if ($notification.length == 0) {
        $notification = $('<div class="notification" style="display:none;"></div>');
        $notification.addClass(status);
        if (location) {
          $notification["insert" + location]($container);
        } else {
          $notification.insertBefore($container);
        }
      } else {
        $notification.attr('class', 'notification ' + status);
        $notification.fadeOut(200);
      }
      return $notification;
    },

    showNotification: function(container, json_response, location) {
      $.log('PP.showNotification', container, json_response);
      var $container;
      if (json_response.status == 'success' && !$.blank(json_response.location)) {
        return window.location = json_response.location;
      }
      if (typeof json_response.target != 'undefined') {
        var target = json_response.target;
        $container = $(target).find('form');
        $.log('$container', $container);
        $container.trigger('focus');
      } else {
        $container = $(container);
      }
      $.each(['notice', 'error'], function(i, status) {
        var statuses = status + "s";
        if (json_response[statuses] && json_response[statuses].length > 0) {
          var message = json_response[statuses].join('<br />');
          var $notification = PP.getNotification($container, status, location);
          $notification.find('.message').or($notification).html(message);
          $notification.fadeIn(400).fadeOutSoon();
        }
      });
    },

    setupForm: function(selector) {
      var $form = $(selector);

      $form
      .live('validate', function() {
        if (!$(this).validForm()) {
          if ($(this).data('valid') != false) {
            $(this).data('valid', false);
            $(this).trigger('is-invalid');
          }
        } else {
          if ($(this).data('valid') != true) {
            $(this).data('valid', true);
            $(this).trigger('is-valid');
          }
        }
      })
      .live('show-invalid', function() {
        $.log('form.show-invalid', this);
        $(this).find(':input.required').each(function() {
          if ($(this).blank()) {
            $(this)
              .addClass('invalid')
              .siblings('label')
              .addClass('invalid');
          } else {
            $(this)
              .removeClass('invalid')
              .siblings('label')
              .removeClass('invalid');
          }
        })
      })
      .find(':input.required')
        .live('change', function() {
          $form.trigger('validate');
          $form.data('changed', true);
        })
        .live('keyup', function() {
          $form.trigger('validate');
        });

      return $form;
    },

    openPreviewForEvent: function() {
      return PP.openWithNewWindow(PP.eventPath('card', 'preview'));
    },

    openWithNewWindow: function(url) {
      var opened = window.open(url, '_blank');
      if (!opened || typeof opened == 'undefined') {
        alert('Sorry. We cant open the preview because Pop-ups are disabled for this site. Please disable popup blocking and try again.');
      }
      return true;
    },

    calculateCoins: function(features, num_guests, total_sent) {
      var total_guests, total_coins = 0;

      if (num_guests == 0 || !features || features.length == 0) {
        return 0;
      }
      total_guests = total_sent + num_guests;
      $.each(features, function(i, feature) {
        if (feature.threshold != 0 && (total_guests * feature.unit) > feature.threshold) {
          var after_threshold = (feature.threshold - (total_sent * feature.unit));
          total_coins += (after_threshold > 0 ? after_threshold : 0);
        } else {
          total_coins += (num_guests * feature.unit);
        }
      });

      return total_coins;
    },

    sendToFlash: function(selector, method_name, args) {
      var max_attempts = 10,
          $flash_holder,
          $flash,
          wrapped_send;


      wrapped_send = function(attempts) {
        Sammy.log('sendToFlash', selector, method_name, args, attempts);
        return function() {
          $flash_holder = $(selector);
          $flash = $flash_holder.is('embed, object') ? $flash_holder : $flash_holder.find('embed, object');
          attempts += 1;
          if (attempts > max_attempts) {
            Sammy.log('== max attempts to send to flash reached, bailing');
            return false;
          }
          if ($flash.length > 0 && $flash_holder.hasClass('flash-loaded')) {
            try {
              $flash.get(0)[method_name].apply($flash.get(0), args);
            } catch(e) {
              Sammy.log('== Error sending callback to flash');
              Sammy.log(e);
              setTimeout(wrapped_send(attempts), attempts * 500);
            }
          } else {
            Sammy.log('Flash not available.');
            setTimeout(wrapped_send(attempts), attempts * 500);
          }
        };
      };
      wrapped_send(0)();
    },

    toggleAdminBar: function(show) {
      var $bar = $('#abar'),
          key  = "__ppadminbar__",
          visible = $bar.is(':visible'),
          haslocal = ('localStorage' in window);

      if ($bar.length == 0) { return false; }
      if (haslocal) {
        if (window.localStorage.getItem(key) === "true") {
          show = true;
        }
      }
      if (visible) {
        $bar.slideUp('fast');
        $('body').removeClass('abar-visible');
        if (haslocal) { window.localStorage.setItem(key, false); }
      } else if (show) {
        $('body').addClass('abar-visible');
        $bar.slideDown('fast');
        if (haslocal) { window.localStorage.setItem(key, true); }
      }
    },

    getEventImages: function(callback) {
      var event_id = PP.getEventID(),
          rate = 200;
      var pollConversionStatus = function() {
        $.getJSON(['/api/v1/events/', event_id, '/card_images'].join(''), function(json) {
          if (json && json.status == 'success') {
            callback(json.images);
          } else {
            rate += 10;
            setTimeout(pollConversionStatus, rate);
          }
        });
      };
      pollConversionStatus();
    }

  });

  $('.notification .close').live('click', function(e) {
    e.preventDefault();
    $(this).parents('.notification').fadeOut(200);
  });

  jQuery.guard('#abar', function($, $bar) {
    $(window).bind('keypress', function(e) {
      if (e.which === 96) { PP.toggleAdminBar(true); }
    });
    $bar.find('a.toggle').bind('click', function(e) {
      e.preventDefault();
      $($(this).attr('rel')).toggleClass('none');
    });
    $('select.jump').bind('change', function() {
      window.location = $(this).val();
    });
    $('.admin-note-form').ajaxForm({
      dataType: 'json',
      success: function(json) {
        window.location.reload();
      }
    });

    var $barnoteform = $('.admin-bar-note-form');
    $barnoteform.ajaxForm({
      dataType: 'json',
      beforeSubmit: function() {
        $barnoteform.find('input[type="submit"]')
          .val('Adding ...').attr('disabled', 'disabled').end();
      },
      success: function(json) {
        $barnoteform.find('input[type="submit"]')
                      .val('Add')
                      .removeAttr('disabled').end()
                    .find('textarea').val('').end()
                    .slideUp('fast');
      }
    });

    PP.toggleAdminBar();
  });


  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(elt /*, from*/) {
      var len = this.length;
      var from = Number(arguments[1]) || 0;
      from = (from < 0) ? Math.ceil(from) : Math.floor(from);
      if (from < 0) from += len;
      for (; from < len; from++) {
        if (from in this && this[from] === elt) return from;
      }
      return -1;
    };
  }

})(jQuery);
Core = window.Core || {

  beget: function(proto) {
    var F = function() {};
    F.prototype = proto;
    return new F();
  },

  bind: function(target, func) {
    return function() {
      return func.apply(target, arguments);
    };
  },

  define: function(proto, constructor, args) {
    var object;
    object = Core.beget(proto);
    object.proto = proto;
    if ($.isFunction(object.init)) {
      object.init.apply(object, args);
    }
    constructor.apply(object);
    return object;
  }

}

Function.prototype.property = function() {
  this.isProperty = true;
  return this;
}

Core.Object = {

  awaken: function(data) {
    var top;
    for(top in data) {break};
    this.data = data[top];
    this.type = top;
    return this;
  },

  clone: function() {
    return this.specialize(function() {}, arguments);
  },

  extend: function(obj) {
    return $.extend(this, obj);
  },

  get: function(keyPath) {
    return this.getPath(this.parseKeyPath(keyPath));
  },

  getPath: function(keyPath) {
    var data;
    if(this[keyPath[0]]) {
      data = this[keyPath.shift()];
    } else {
      data = this.data;
    }
    if (data.isProperty === true) data = data.apply(this);
    $(keyPath).each(function() {
      data = data[this];
      if (data.isProperty === true) data = data.apply(this);
    });
    return data;
  },

  load: function(params, yield) {
    var that = this;
    $.getJSON(this.route(params), function(data) {
      yield(that.clone().awaken(data));
    });
  },

  parseKeyPath: function(keyPath) {
    return keyPath.split('.');
  },

  set: function(keyPath, value) {
    var path, key;
    path = this.parseKeyPath(keyPath);
    key = path.pop();
    this.getPath(path)[key] = value;
    return this;
  },

  specialize: function(constructor, args) {
    return Core.define(this, constructor, args);
  }

}

Core.Controller = Core.Object.clone().extend({

});
Selection = Core.Object.clone().extend({

  init: function() {
    this.state = 'none';
    this.vector = [];
    this.filters = {};
    this.search = '';
  },

  clear: function() {
    this.vector = [];
  },

  deselect: function(id) {
    if (this.state === 'all') {
      this._include(id);
    } else {
      this._exclude(id);
    }
    return this;
  },

  noneSelected: function() {
    return (this.state === 'none' && this.vector.length === 0);
  },

  isSelected: function(id) {
    var marked = false;
    $(this.vector).each(function() {
      if (this == id) marked = true;
    });
    if (this.state === 'all') {
      return !marked;
    } else {
      return marked;
    }
  },

  select: function(id) {
    if (this.state === 'all') {
      this._exclude(id);
    } else {
      this._include(id);
    }
    return this;
  },

  selectAll: function() {
    this.state = 'all';
    this.vector = [];
    return this;
  },

  selectNone: function() {
    this.state = 'none';
    this.vector = [];
    return this;
  },

  setFilter: function(name, value) {
    return this.filters[name] = value;
  },

  getFilter: function(name) {
    return this.filters[name] || false;
  },

  filtersArray: function() {
    var filters = [];
    for (var i in this.filters) {
      filters.push(this.filters[i]);
    }
    return filters;
  },

  toJSON: function() {
    return {mode: this.state, vector: this.vector, filters: this.filters, search: this.search};
  },

  _exclude: function(x) {
    var new_vector;
    new_vector = [];
    $.each(this.vector, function() {
      if (this != x) new_vector = new_vector.concat(this);
    });
    this.vector = new_vector;
  },

  _include: function(x) {
    if ($.inArray(x, this.vector)) {
      this.vector = this.vector.concat(x);
    }
  }

});

(function($) {

  $(document).ready(function() {
    $('.second-nav > li').not('.search').hover(function(){
      $(this).toggleClass('hover');
    });

    $('.nav-secondary > li').hover(function(){
      $(this).toggleClass('on');
    });

    $('.papers > ul li').live('hover', function(){
      $(this).toggleClass('on');
    });

    $('.item-extra ul li').live('hover', function(){
      $(this).toggleClass('on');
    });

    $('.item-palette ul li').hover(function(){
      $(this).toggleClass('on');
    });

    $('.b-categories-sub .categories li').hover(
      function(){$(this).find('img').animate({"margin-top": "-=49px"}, "fast");},
      function(){$(this).find('img').animate({"margin-top": "+=49px"}, "fast");}
    );

    $('.set-auto-toggle').live('click',function(){
        $('.trackingformsubmit').attr('submitted', 'false');
    });

    $('.fadeaway').delay(5000).fadeOut(2000);

    $('.facebook-share').live('click', function(){
      window.open($(this).attr("rel"),' sharer', 'toolbar=0, status=0, width=626, height=436')
    });

    var hoverMessageDefault = "Click here to copy your personal link";
    if($('.slides').length > 0){
      hoverMessageDefault = "Click to copy the link to this page";
    }

    $('.clipboard-wrap')
      .hover(function(){
        $('.clipboard-hover').fadeIn(150);
      }, function(){
        $('.clipboard-hover').fadeOut(150);
        setTimeout("$('.hover-message').html('"+hoverMessageDefault+"')", 150);
      });

    $('#clipboard, .clipboard-hover, .clipboard-wrap')
      .live('click mouseup',function(e){
        $message = $('.hover-message');
        $message.fadeOut(200);
        setTimeout(function(){
          $message.html("URL copied to clipboard");
          $message.fadeIn(200);
        },200);
      });

    $('.cancel-confirm').click(function() {
      var event_cancel = confirm("Are you sure to cancel?");
      if (event_cancel == false) {
        return false;
      }
    });


    $('.become-member').click(function() {
      $('#become-member').hide();
      $('#session-login').show();
      $('#s-login').hide();
      $('#s-forgot').hide();
      $('#s-join').show();
      return false;
    });

    $('.inline-login').click(function() {
      $('#become-member').hide();
      $('#session-login').show();
      $('#s-login').show();
      $('#s-forgot').hide();
      $('#s-join').hide();
      return false;
    });

    $('.inline-forgot').click(function() {
      $('#become-member').hide();
      $('#session-login').show();
      $('#s-login').hide();
      $('#s-forgot').show();
      $('#s-join').hide();
      return false;
    });

    $('#header .products ul li:first-child').addClass('first');

    $('#billing_locale').change(function() {
      if ($(this).val() == 'CA') {
        $(this)
          .parents('form')
          .find('input[name="billing_address[zip]"]')
          .attr('disabled', 'disabled')
          .val('N/A');
      } else {
        $(this)
          .parents('form')
          .find('input[name="billing_address[zip]"]')
          .removeAttr('disabled')
          .val('');
      }
    });

    $('ul li .destroy-credit-card').click(function() {
      var self = $(this);
      PP.getConfirmation('Are you sure you want to remove this credit card?', function() {
        self
          .parents('form')
          .attr('action', self.attr('href'))
          .append('<input type="hidden" name="_method" value="delete" />')
          .submit();
      });
    });

    $('ul li .update-credit-card').click(function() {
      $(this)
        .parents('form')
        .attr('action', $(this).attr('href'))
        .append('<input type="hidden" name="_method" value="put" />')
        .submit();
      return false;
    });


    $('p.multiples input[type="text"]').live('focusin', function() {
      if ($(this).val() === 'yyyy') {
        $(this).val('');
      }
    });

    $('.add-individual [name="use_group_name"]').val("false");

  });


})(jQuery);

;jQuery(function($) {
  PP = window.PP || {};
  PP.customizeInputs = function(container) {
    var $container = $(container);
    $container.find('input.custom').each(function() {
      createCustomInput(this);
    });
    bindToCustomInputs($container);
  };

  function createCustomInput(original_input) {
    var $input   = $(original_input), $button;
    if ($input.data('customized')) {
      return;
    }
    $button  = $('<input type="button">');
    $button
    .attr('name', $input.attr('name'))
    .attr('disabled', $input.attr('disabled'))
    .addClass($input.attr('type'))
    .addClass($input.attr('class'))
    .removeClass('custom')
    .data('$true_input', $input);

    $input.data('customized', true);

    if ($input.is(':checked')) {
      $button.addClass('on');
    }
    $input
      .after($button)
      .bind('click', function() {
        $button.trigger('click');
      })
      .hide();
  };

  function bindToCustomInputs($container) {
    var bound_class = 'custom-input-delegator',
        $bound = $container.closest('.' + bound_class);

    if ($bound.length == 0) {
      $container
        .delegate('input.radio', 'toggle', function() {
          var name = $(this).attr('name');

          $(this)
          .parents('form').or('body')
          .find('input.radio[name="' + name + '"]')
          .removeClass('on');

          $container
          .find('input[type="radio"][name="' + name + '"]')
          .attr('checked', false);

          $(this).addClass('on');
          $(this).data('$true_input').attr('checked', 'checked');
        })
        .delegate('input.radio', 'click', function() {
          $(this).trigger('toggle');
        })
        .delegate('input.checkbox', 'check', function() {
          $(this)
          .addClass('on')
          .data('$true_input')
          .attr('checked', 'checked');
        })
        .delegate('input.checkbox', 'uncheck', function() {
          $(this)
          .removeClass('on')
          .data('$true_input')
          .removeAttr('checked');
        })
        .delegate('input.checkbox', 'click toggle', function(e) {
          $.log('checkbox.toggle', this);
          if ($(this).hasClass('on')) {
            $(this).trigger('uncheck');
          } else {
            $(this).trigger('check');
          }
        });


      $container.addClass(bound_class);
    }
  };

  $('form.custom').each(function() {
    PP.customizeInputs(this);
  });

});
(function($) {

  $('input.calendar').live('click', function(e){
    e.preventDefault();
    var current_date = $.datepicker.formatDate('MM yy', new Date());
    var dp = $(this).datepicker({
              gotoCurrent: true,
              minDate: new Date(),
              onSelect: updateInputs,
              currentText: current_date,
              prevText: '&nbsp;&nbsp;',
              nextText: '&nbsp;&nbsp;',
              beforeShowDay: validateDateForCalendar
            });
    setTimeout(function() {
      dp.datepicker('show');
    }, 50);
    updateCurrentText(dp);
  });

  function sameDate(date1, date2) {
    return ((date1.getYear() == date2.getYear())
            && (date1.getMonth() == date2.getMonth())
            && (date1.getDate() == date2.getDate()));
  }

  function validateDateForCalendar(date) {
    var today = new Date();
    var selectedDate = readCurrentDate($(this));
    var is_selected = false;
    var className;
    is_selected = selectedDate && ((date.getYear() == selectedDate.getYear())
            && (date.getMonth() == selectedDate.getMonth())
            && (date.getDate() == selectedDate.getDate()));
    className = is_selected ? 'ui-datepicker-tppevent-day' : '';
    return [today < date || sameDate(today, date), className ];
  };

  function registerCalLinks(dp){
    $.each($(".ui-datepicker-links a").get(), function(){ $(this).bind("mouseup", function(){ setTimeout(function () { updateCurrentText(dp) },1);}) });
  }

  function updateCurrentText(dp){
    var d = '';
    $.each($(".ui-datepicker-header select").get(), function(){ d += this.options[this.selectedIndex].text +' '; } );
    dp.datepicker('option', 'currentText', d);
    registerCalLinks(dp);
  }

  function updateInputs(date, datepicker) {
    var control = $(this).parent();
    $(control).children('.year').val(datepicker.currentYear);
    $(control).children('.month').val((datepicker.currentMonth + 1));
    $(control).children('.day').val(datepicker.currentDay);
    $(control).children('.year').trigger("keyup");
  }

  function readCurrentDate(datepicker) {
    var control = datepicker.parent();
    var year = $(control).children('.year').val(), month = $(control).children('.month').val(), day = $(control).children('.day').val()
    if (jQuery.trim(year)=="" || jQuery.trim(month) =="" || jQuery.trim(day) == "" ) {
      var currentDate = null;
    } else {
      var currentDate = new Date(parseInt(year), parseInt(month)-1, parseInt(day));
    }
    return currentDate;
  }


})(jQuery);
;(function($) {

  $(function() {
    $('a[rel=expand]').setControl('expander').live('click', expand);
    $('a[rel=compress]').setControl('expander').live('click', compress);
    $('a[rel=toggle]').setControl('expander').live('click', toggle);
    $('.compressed').setControl('expander').bind('focus', focus);
    update();
  });

  function compress() {
    var targets, state;
    state = link_state(this);
    targets = $(state.href);
    targets.removeClass('expanded');
    targets.slideUp('fast').addClass('compressed');
    targets.trigger('compress');
    update();
    $(targets).find('.vtabs').blur();
    return false;
  }

  function expand() {
    var targets, state;
    state = link_state(this);
    targets = $(state.href);
    targets.slideTo();
    targets.addClass('expanded');
    targets.slideDown('fast').removeClass('compressed');
    targets.trigger('expand');
    update();
    return false;
  }

  function focus() {
    $(this).addClass('expanded').slideDown('fast');
    update();
  }

  function isExpanded(state) {
    var targets;
    targets = $(state.href);
    compressed = targets.filter(':not(.expanded)');
    return compressed.length === 0;
  }

  function link_state(link) {
    return {href: $(link).attr('href')}
  }

  function toggle() {
    var state;
    state = link_state(this);
    if (isExpanded(state)) {
      compress.apply(this);
    } else {
      expand.apply(this);
    }
    return false;
  }

  function update() {
    $('a[rel=expand],a[rel=compress],.expander[rel=expand]').each(function() {
      if(isExpanded(link_state(this))) {
        $(this).removeClass('compressed').addClass('expanded');
      } else {
        $(this).removeClass('expanded').addClass('compressed');
      }
    });
  }

})(jQuery);
(function($) {

  $('.step-nav .step-next')
    .setControl('step_nav')
    .live('disable', function() {
      $(this).replaceClass('active','inactive');
    })
    .live('enable', function() {
      $(this).replaceClass('inactive','active');
    })
    .live('click', function(e) {
      var $bound_form = $('form.bound-to-step-nav');
      if ($bound_form.length > 0) {
        e.preventDefault();
        if ($(this).is('.inactive')) {
          $bound_form.trigger('validate');
          $bound_form.trigger('show-invalid');
        } else {
          $bound_form.trigger('next');
        }
      }
    });

})(jQuery);
;(function ($) {

  $(document).ready(function() {
    $('.vtabs').each(function() {
      vtabs(this); // We work with single tab groups on the page
    });

    $('a[rel="expand-tab"]').live('click', function(e) {
      e.preventDefault();
      $('a[rel="' + $(this).attr('href') + '"]').click();
    });
  });

  function vtabs(context) {
    $(context).setControl('vtabs');
    $('li', context).bind('click.vtabs', click_tab);
    setTabFromHash();

    $(context).bind('blur', function() {
      window.location.hash = '#';
    });

    function click_tab(e) {
      $(context).find('.open').removeClass('open');
      $(this).addClass('open');
      update_portals();
      setHash(this);
      $(this).trigger('focus');
      $(window).click();
      return false;
    }

    function update_portals() {
      $(context).find('li').each(function() {
        if ($(this).is('.open')) {
          $($(this).find('a').attr('rel')).show();
        } else {
          $($(this).find('a').attr('rel')).hide();
        }
      });
    }

    function setHash(tab) {
      var hash = "#/";
      hash += [$(context).attr('id'), $(tab).find('a').attr('rel')].join('/');
      window.location.hash = hash;
      return hash;
    }

    function setTabFromHash() {
      var parts = window.location.hash.toString().replace(/^\#\//,'').split('/');
      $.log('setTabFromHash', parts);
      if (parts[0] == $(context).attr('id')) {
        $(context).find('li a[rel="' + parts[1] + '"]').click();
      } else {
        update_portals();
      }
    }

  }

})(jQuery);
/*
taken from jrails
*/

(function($) {
  $.extend({ // Translate field to event
    fieldEvent: function(el, obs) {
      var field = el[0] || el, e = 'change';
      if (field.type == 'radio' || field.type == 'checkbox') e = 'click';
      else if (obs && field.type == 'text' || field.type == 'textarea') e = 'keyup';
      return e;
    }
  });
  $.fn.extend({ // Delayed observer for fields and forms
    delayedObserver: function(delay, callback){
      var el = $(this);
      if (typeof window.delayedObserverStack == 'undefined') window.delayedObserverStack = [];
      if (typeof window.delayedObserverCallback == 'undefined') {
        window.delayedObserverCallback = function(stackPos) {
          observed = window.delayedObserverStack[stackPos];
          if (observed.timer) clearTimeout(observed.timer);
          observed.timer = setTimeout(function(){
            observed.timer = null;
            observed.callback(observed.obj, observed.obj.formVal());
          }, observed.delay * 1000);
          observed.oldVal = observed.obj.formVal();
        }
      }
      window.delayedObserverStack.push({
        obj: el, timer: null, delay: delay,
        oldVal: el.formVal(), callback: callback
      });
      var stackPos = window.delayedObserverStack.length-1;
      if (el[0].tagName == 'FORM') {
        $(':input', el).each(function(){
          var field = $(this);
          field.bind($.fieldEvent(field, delay), function(){
            observed = window.delayedObserverStack[stackPos];
            if (observed.obj.formVal() == observed.obj.oldVal) return;
            else window.delayedObserverCallback(stackPos);
          });
        });
      } else {
        el.bind($.fieldEvent(el, delay), function(){
          observed = window.delayedObserverStack[stackPos];
          if (observed.obj.formVal() == observed.obj.oldVal) return;
          else window.delayedObserverCallback(stackPos);
        });
      };
    },
    formVal: function() { // Gets form values
      var el = this[0];
      if(el.tagName == 'FORM') return this.serialize();
      if(el.type == 'checkbox' || self.type == 'radio') return this.filter('input:checked').val() || '';
      else return this.val();
    }
  });
})(jQuery);

(function($) {

  $(function() {
    $('.contact-list').each(function() {
      var contact_list = this;
      if($(contact_list).closest('.address-book').size() > 0) {
        $.ajax({
          url: $('.address-book input#all_contact_list').val(),
          type: 'GET',
          dataType: 'json',
          success: function(data) {
            ContactList.instance(contact_list).selectAll = data;
            ContactList.instance(contact_list).reload();
          }
        });
      } else {
        ContactList.instance(contact_list).reload();
      }
    });

    $('.guest-state').live('change', function(){
      if($(this).val() == "attending"){
        $(this).parent().parent().find('.total-invited').hide();
        $(this).parent().parent().find('.total-attending').show();
      } else {
        $(this).parent().parent().find('.total-attending').hide();
        if($(this).val() != "not_attending"){
          $(this).parent().parent().find('.total-invited').show();
        }else{
          $(this).parent().parent().find('.total-invited').hide();
        }
      }
    });
  });

  BoundModel = Core.Object.clone()
    .specialize(function() {
      this.instance = function() {
        var element = arguments[0];
        var $element = $(element);
        if ($element.length == 0) return null;
        var instance = $element.data(this.instance_store());
        if (!instance) {
          instance = this.clone.apply(this, arguments);
        }
        return instance;
      };
    })
    .extend({
      init: function(name) {
        $.log('BoundModel#init', name);
        this.instance_store = function() { return name; }
      },
      bind: function() {
        this.$element.bind.apply(this.$element, arguments);
        return this;
      },

      trigger: function() {
        this.$element.trigger.apply(this.$element, arguments);
        return this;
      },

      _loadElement: function(element) {
        this.$element = $(element);
        if (this.$element.length < 1) {
          $.log('ERROR', '_loadElement', arguments, 'Element doesnt exist');
        }
        this.$element.setControl('contact_list');
        this.$element.data(this.instance_store(), this);
      },

      $find: function(selector) {
        return this.$element.find(selector);
      },

      $el: function(selector_name) {
        var selector = this[selector_name + '_selector'];
        if (selector) {
          return this.$find(selector);
        } else {
          $.log('ERROR', '$el', this, selector_name);
        }
      }
    });

  ContactList = BoundModel.clone('contactList').extend({

    total_guests_count: 0,
    unsent_guests_count: 0,
    sent_guests_count: 0,

    send_to_selected: false,

    checkbox_selector: 'input.checkbox.contact-list-vector',
    contact_selector: '.guests li',
    search_field_selector: '.contact-list-selection-search',
    form_selector: 'form.contact-list-form',
    filter_description_selector: '.filter-description',

    progress_selector: '.progress',
    content_selector: '.contact-list-content',
    filter_selector: '.contact-list-filter',
    filter_by_type_selector: '.contact-list-filter[rel="type"]',
    filter_by_sub_type_selector: '.contact-list-filter[rel="zsub_type"]',
    filter_by_past_event_selector: '[name="contact_list[past_event]"]',
    action_selector: '.contact-list-action',
    mode_selector: '.contact-list-selection-mode',
    page_selector: '.contact-list-page',

    selectAll: {},
    selection: {},

    init: function(element) {
      $.log('ContactList', 'init', element);
      this._loadElement(element);
      this._initForm();
      this._initColumns();
      this._initFilters();
      this._initActions();
      this._initSelection();
      this._initContacts();
      this._initPagination();
      this._initSearch();
      PP.customizeInputs(this.$element);
      this.updateTotals(JSON.parse(this.$element.attr('data-totals')));
    },

    updateTotals: function(data) {
      var contact_list = this,
          $total = contact_list.$find('.total-guests'),
          display_total,
          total_text;

      if (typeof data.sent_total != 'undefined') {
        contact_list.sent_guests_count = data.sent_total;
      }
      if (typeof data.unsent_total != 'undefined') {
        contact_list.unsent_guests_count = data.unsent_total;
      }
      if (typeof data.total != 'undefined') {
        contact_list.total_guests_count = data.total;
      }
      if ($total.length > 0) {
        display_total = $total.attr('data-display-total');
        if (display_total && display_total == 'both') {
          $total.text("(Unsent "+ contact_list.unsent_guests_count +", Sent " + contact_list.sent_guests_count +")")
        } else if (display_total && typeof data[display_total] != 'undefined') {
          $total.text("(" + data[display_total] + ")");
        }
      }
      contact_list.trigger('list-modified');
    },

    deleteContacts: function() {
      if (confirm('Are you sure you want to delete your selection?  There will be no more warnings.')) {
        var contact_list = this;
        contact_list.showLoading();
        var url = this.$element.find('.batch_destroy_url').val() + '.json';
        var list_id = this.$el('form').closest('.contact-list').attr('id');
        contact_list.selection[list_id] = [];
        $.post(url,
          "_method=delete&" + contact_list.$el('form').serialize(),
          function(data) {
            contact_list.updateTotals(data);
            contact_list.reload();
            contact_list.trigger('contacts-removed');
          }, 'json');
      }
    },

    editContacts: function() {
      this.openContacts();
    },

    openContacts: function() {
      var contact_list = this;
      this.$selectedContacts().trigger('open');
    },

    closeContacts: function() {
      var contact_list = this;
      this.$selectedContacts().trigger('close');
    },

    saveContacts: function() {
      var contact_list = this;

      contact_list.showLoading();

      var url = this.$element.find('.batch_update_url').val() + '.json';
      var params = contact_list.$selectedContacts()
                                  .find('.contact-form :input')
                                  .serializeArray();
      var contact_id;
      $.each(params, function() {
        if (this.name == 'contact_id') {
          contact_id = this.value;
        } else {
          this.name = this.name.replace('contact[', "contacts[" + contact_id + "][");
        }
      });

      $.log('batch params', params);
      $.post(url,
        "_method=PUT&" + $.param(params),
        function(data) {
          contact_list.reload();
        }, 'json');

    },

    arrayHas : function(x, a) {
      if(!a || !a.length) return false;
      var index = Math.floor(a.length / 2);

      if(a[index] == x) {
        return true;
      } else if(x < a[index]) {
        return arguments.callee(x, a.slice(0, index))
      } else if(x > a[index]) {
        return arguments.callee(x, a.slice(index+1))
      }
    },

    addContacts: function() {
      var contact_list = this;
      contact_list.showLoading();
      var $form = contact_list.$el('form');
      var list_id = contact_list.$el('form').closest('.contact-list').attr('id');
      var selectList = contact_list.getSelection(list_id);

      if(!this.selectedAll()) {
        var visible = [], offscreen = [];
        this.$el('contact').each(function() {
          if($(this).find('input.contact-list-vector:checked').val())
            visible.push($(this).find('input.contact-list-vector:checked').val());
        });

        visible = visible.sort(function(a, b) { return a-b });

        for(var i=0;i<selectList.length;i++) {
          if(!contact_list.arrayHas(selectList[i], visible)) {
            offscreen.push(selectList[i]);
          }
        }

        $form.append($('<input/>')
        .addClass('offscreen-contact')
        .attr({
          value: offscreen.join(','),
          type: 'hidden',
          name: 'contact_list[selection][vector][]'
        }));
      }
      $.post(
        PP.eventPath('guests', 'create_from_address_book'),
        $form.serialize(),
        function (data) {
          contact_list.selection[list_id] = [];
          contact_list.$el('form').find('.offscreen-contact').remove();
          contact_list.reload();
          contact_list.trigger('contacts-added', [data]);
        },
        'json'
      );
    },

    guestsToSendCount: function() {
      var list_id = this.$el('form').closest('.contact-list').attr('id');
      if(this.send_to_selected && this.hasSelection() && !this.selectedAll()) {
        return this.getSelection(list_id).length
      } else {
        return this.unsent_guests_count;
      }
    },

    deliverToSelected: function(input, costs) {
      var $input = $(input),
          recipient = "recipient",
          stamp = "stamp",
          coin = "coin",
          contact_list = this,
          total_to_send = this.guestsToSendCount(),
          total_coins = this.calculateCoins(costs, total_to_send);

      contact_list.showLoading();

      var visible = [], offscreen = [];
      var $form = contact_list.$el('form');
      var list_id = contact_list.$el('form').closest('.contact-list').attr('id');
      var selectList = contact_list.getSelection(list_id);

      this.$el('contact').each(function() {
        if($(this).find('input.contact-list-vector:checked').val())
          visible.push($(this).find('input.contact-list-vector:checked').val());
      });

      visible = visible.sort(function(a, b) { return a-b });

      for(var i=0;i<selectList.length;i++) {
        if(!contact_list.arrayHas(selectList[i], visible)) {
          offscreen.push(selectList[i]);
        }
      }

      for(var i=0;i<offscreen.length;i++) {
        $form.append($('<input/>')
        .addClass('offscreen-contact')
        .attr({
          value: offscreen[i],
          type: 'hidden',
          name: 'contact_list[selection][vector][]'
        }));
      }


      if (total_to_send > 1) { stamp += 's'; recipient += 's' }
      var text = "You are about to send to " + total_to_send + " " + recipient;
      text += " using " + total_to_send + " " + stamp;
      if (total_coins > 0) {
        if (total_coins > 1) { coin += 's'; }
        text += " and " + total_coins + " " + coin;
      }
      text += ". Click OK to continue.";

      PP.getConfirmation(text, function() {
        $input.trigger('show-loading');
        $.ajax({
          url: PP.eventPath('email_cards'),
          type: 'POST',
          data: "_method=PUT&"+contact_list.$el('form').serialize(),
          dataType: 'json',
          success: function(data) {
            selectList = [];
            PP.showNotification(contact_list.$element, data);
            contact_list.$el('form').find('.offscreen-contact').remove();
            $input.trigger('hide-loading');
          }
        });
      });

    },

    select: function(what) {
      var list_id = this.$el('form').closest('.contact-list').attr('id');
      $.log(this, 'select()', what, list_id);

      switch(what) {
        case 'all':
          this.$checkboxes().trigger('check');
          if(this.selectAll.length > 0)
            this.selection[list_id] = this.selectAll.slice()

        break;
        case 'none':
          this.$checkboxes().trigger('uncheck');
          this.selection[list_id] = [];
      }
      this.trigger('selection-changed');
    },

    selectedAll: function() {
      return this.$el('mode').is('.on');
    },

    $selectedContacts: function() {
      return this.$find('.guests li.selected');
    },

    hasSelection: function() {
      var list_id = this.$el('form').closest('.contact-list').attr('id');
      return this.getSelection(list_id).length > 0;
    },

    getSelection: function(list_id) {
      if(!this.selection[list_id])
        this.selection[list_id] = [];

      return this.selection[list_id];
    },

    hasSpecificSelection: function() {
      return !this.selectedAll() && this.hasSelection();
    },

    setCurrentFilterDescription: function(text, class_name) {
      $.log('setCurrentFilterDescription', text, class_name);
      this.$el('filter_description')
        .attr('class', this.filter_description_selector.replace(/^\./,''))
        .html(text);
      if (class_name) {
        this.$el('filter_description').addClass(class_name);
      }
    },

    reload: function(options) {
      var list_id = this.$el('form').closest('.contact-list').attr('id');
      if(!this.selection[list_id]) {
        this.selection[list_id] = [];
      }
      this.showLoading();

      var $form = this.$el('form');
      var data = $form.serialize();
      if(window.last_viewed_stats_at) {
        data += '&last_viewed_stats_at='+last_viewed_stats_at
      }

      $.ajax($.extend({
        type: 'POST',
        data: data,
        dataType: 'html',
        beforeSend: $.shove(this.showLoading, this),
        complete: $.shove(this.hideLoading, this),
        success: $.shove(this._load, this),
        url: this.$element.find('.list_url').val()
      }, options || {}));
    },

    showLoading: function() {
      this.$el('progress').show();
    },

    hideLoading: function() {
      this.$el('progress').hide();
    },

    calculateCoins: function(costs, num_guests) {
      num_guests = num_guests || this.guestsToSendCount();
      return PP.calculateCoins(costs.features, num_guests, costs.total_sent);
    },

    bindSendValidationToButton: function($send_button, costs) {
      var contact_list = this, validate = function() {
        contact_list.validatePurchasesBeforeSend($send_button, costs);
      };
      this.bind('list-modified', validate);

      $send_button
      .data('original-src', $send_button.attr('src'))
      .bind('click', function(e) {
        if (!$(this).is('.disabled')) {
          contact_list.deliverToSelected(this, costs);
        }
      });

      if (this.send_to_selected) {
        this.bind('selection-changed', function() {
          $.log('selection-changed', $send_button, 'specific selection', contact_list.hasSpecificSelection());
          setTimeout(validate, 50);
          $send_button.attr('src', function(i, src) {
            if (contact_list.hasSpecificSelection()) {
              return src.replace(/all(_new)?_(guests|recipients)/, 'selected');
            } else {
              return $(this).data('original-src');
            }
          });
        });
      }
      validate();
    },

    validatePurchasesBeforeSend: function($send_button, costs) {
      $.log('validatePurchasesBeforeSend', this);
      var contact_list    = this,
          costs           = costs || JSON.parse($('.buy').attr('data')),
          unsent_count    = this.guestsToSendCount(),
          unsent_limit    = 1000,
          needs_stamps, needs_coins;

      needs_stamps = unsent_count - costs.stamps;
      needs_coins  = this.calculateCoins(costs, unsent_count) - costs.coins;

      $.log("costs", costs, "unsent_count", unsent_count, "needs_stamps", needs_stamps, "needs_coins", needs_coins);

      function showNeed() {
        updateNeedText('stamps', needs_stamps);
        updateNeedText('coins', needs_coins);
        $('.buy').show();
      }

      function updateNeedText(type, count) {
        if (count <= 0) {
          $('.buy .buy-' + type).hide();
        } else {
          $('.buy .buy-' + type)
            .show()
            .find('strong')
              .text(count);
        }
      }

      function hideNeed() {
        $('.buy').hide();
      }

      function needsPurchase() {
        return (needs_coins > 0 || needs_stamps > 0);
      }

      function disableSend() {
        $send_button.trigger('disable');
      }

      function enableSend() {
        $send_button.trigger('enable');
      }

      if (unsent_count > unsent_limit) {
        $('.notification.limit').show();
        disableSend();
      } else {
        $('.notification.limit').hide();
        if (needsPurchase()) {
          showNeed();
          disableSend();
        } else if (unsent_count == 0) {
          hideNeed();
          disableSend();
        } else {
          hideNeed();
          enableSend();
        }
      }

    },

    bindAddressBookToList: function(address_book_instance_name) {
      var contact_list = this;
      if ($(address_book_instance_name).length != 0) {
        var address_book_contact_list = ContactList.instance(address_book_instance_name)

        address_book_contact_list.bind('contacts-added', function(e, data) {
          contact_list.reload();
          contact_list.updateTotals(data);
        });

        contact_list.bind('contacts-removed', function(e) {
          address_book_contact_list.reload();
        });
      }
    },

    _load: function(data) {
      var contact_list = this;
      this.active_navigation = false;
      this.$el('content').replaceWith(data);
      this._initActions();
      PP.customizeInputs(this.$element);
      this.trigger('list-loaded', [data]);
      this.trigger('list-modified');
      this.trigger('selection-changed');

      if(this.hasSelection()) {
        this.$el('action').trigger('activate');
        var list_id = this.$el('form').closest('.contact-list').attr('id');

        this.selection[list_id] = this.getSelection(list_id).sort(function(a,b) { return a-b });

        $('input.custom.contact-list-vector[value]').each(function(){
          if(contact_list.arrayHas($(this).val(), contact_list.getSelection(list_id))) {
            $(this).parents('li').find('.checkbox').trigger('check');
          } else {
            $(this).parents('li').find('.checkbox').trigger('uncheck')
          }
        });

      }

      $('.show-first .guests li:first').trigger('toggle');
    },

    $checkboxes: function() {
      return this.$el('checkbox');
    },

    setPageNum: function(num) {
      if (num === 'prev' && this.getPageNum() > 1) {
        num = this.getPageNum() - 1;
      } else if (num === 'next') {
        num = this.getPageNum() + 1;
      }
      this.$el('page').val(num);
    },

    getPageNum: function() {
      return parseInt(this.$el('page').val());
    },

    addContactToSelection: function(contact_id, list_id) {
      var contact_list = this;
      var add = true;

      var selectList = this.getSelection(list_id)

      for(var i=0;i<selectList.length;i++) {
        if(selectList[i] == contact_id) {
          add = false;
        }
      }

      if(add) {
        selectList.push(parseInt(contact_id));
      }
    },

    removeContactFromSelection: function(contact_id, list_id) {
      var contact = parseInt(contact_id)
      var selectList= this.getSelection(list_id)

      for(var i=0;i<selectList.length;i++) {
        if(selectList[i] == contact) {
          selectList.splice(i,1);
          break;
        }
      }
    },

    _initPagination: function() {
      var contact_list = this;

      this.$find('.contact-page-link:not(.inactive)').live('click', function(e) {
        var rel = $(this).attr('rel');
        if (contact_list.active_navigation) return;
        contact_list.active_navigation = rel;
        e.preventDefault();
        contact_list.setPageNum($(this).attr('rel'));
        contact_list.reload();
      });

    },

    _initForm: function() {
      var contact_list = this;
      $.log('form', this.$el('form'));
      this.$el('form').submit(function() {
        contact_list.reload();
        return false;
      });
    },

    _initContacts: function() {
      var contact_list = this;
      this.$el('contact')
        .live('open', function() {
          $(this).addClass('on');
          $(this).find('.details').slideDown(400);
        })
        .live('close', function() {
          $(this).removeClass('on');
          $(this).find('.details').slideUp(400);
        })
        .live('toggle', function() {
          $.log('toggle', this);
          if ($(this).is('.on')) {
            if (!contact_list.selectedAll()) {
              $(this).find('input.checkbox').trigger('uncheck');
              contact_list.trigger('selection-changed');
            }
            $(this).trigger('close');
          } else {
            if (!contact_list.selectedAll()) {

              $(this).find('input.checkbox').trigger('check');
              contact_list.trigger('selection-changed');
            }
            $(this).trigger('open');
          }
        })
        .live('save', function() {
          $.log('save contact', this);
          var $form = $(this).find('.contact-form');
          var $contact = $form.parents(contact_list.contact_selector);
          var totalInvited = $form.find('#contact_additional_guests_allowed').val();
          $.post(
            $form.attr('rel'),
            $form.find(':input').serialize() + "&_method=PUT",
            function(response) {
              if (response.status == 'success') {
                $contact.replaceWith(response.contact_html)
                PP.customizeInputs(contact_list.$element);
                setTimeout(function() {
                  $contact.trigger('toggle');
                }, 2000);
                $form.attr('rel', response.url);
              } else {
                PP.showNotification(contact_list.$element, response);
              }
            },
            'json'
          );
        })
        .find('.contact-header, .comment')
          .live('click', function(e) {
            $(this).parents('li').trigger('toggle');
          }).end()
        .find('.contact-form .save')
          .live('click', function(e) {
            e.stopPropagation();
            $(this).parents(contact_list.contact_selector).trigger('save');
            return false;
          });

      this.$find('.send-to-host').live('click', function(e) {
        e.preventDefault();
        var $link = $(this);
        setTimeout(function() {
          $link.parents('.guests li').trigger('toggle');
        }, 500);
        $.get($link.attr('href'), function(response) {
          PP.showNotification(contact_list.$element, response);
        });
      });
    },

    _initFilters: function() {
      var contact_list = this;
      this.$el('filter').live('change', function(e) {
        $.log('changing filter', e);
        if ($(e.target).is('[rel="type"]')) {
          contact_list.$el('mode').trigger('uncheck');
        }
        contact_list.reload();
      });

      var initial_type = this.$el('filter_by_type').val();
      if (!$.blank(initial_type) && $('.tracking-overview').length > 0) {
        $('.tracking-overview li[rel="'+ initial_type + '"]').trigger('activate', [false, false]);
      }
      var initial_sub_type = this.$el('filter_by_sub_type').val();
      if (!$.blank(initial_sub_type) && $('.tracking-overview').length > 0) {
        $('.tracking-overview li.on a.section[rel="'+ initial_sub_type + '"]').trigger('activate', [false, false]);
      }

      var initial_past_event = this.$el('filter_by_past_event').val();
      if (!$.blank(initial_past_event) && $('.tracking-overview').length) {
        $('.tracking-overview li.on a.section[rel="'+ initial_past_event +'"]').trigger('activate', [false, false]);
      }
    },

    _initActions: function() {
      var contact_list = this;
      this.$el('action')
        .bind('activate', function() {
          $(this).removeClass('off').removeAttr('disabled');
        })
        .bind('deactivate', function() {
          $(this).addClass('off').attr('disabled','disabled');
        })
        .bind('click', function(e) {
          e.preventDefault();
          if ($(this).is('.off')) { return; }
          var action = $(this).attr('rel');
          contact_list._runAction(action);
        });
    },

    _initSelection: function() {
      var contact_list = this;
      contact_list.bind('selection-changed', function() {
        $.log('selection-changed');

        if (contact_list.hasSelection()) {
          contact_list.$el('action').trigger('activate');
        } else {
          contact_list.$el('action').trigger('deactivate');
        }

        if($('.cufon-vml').size() > 0) { // detect IE
          contact_list.trigger('cufon-fix');
        }
      }).bind('cufon-fix', function(e) {
        setTimeout(function() { $('#footer-wrap-wrap h6.cufon').css('position','relative') }, 500);
      })
      this.$find(['.checkbox', this.mode_selector].join(''))
        .live('uncheck', function(e, no_deselect) {
          if (no_deselect !== true) {
            contact_list.select('none');
          }
        })
        .live('check', function() {
          contact_list.select('all');
        });
      this.$find(['label', this.mode_selector].join(''))
        .live('click', function() {
          $(this).siblings('input.checkbox').trigger('toggle');
        });
      this.$element
        .delegate(this.checkbox_selector, 'uncheck', function() {
          contact_list.removeContactFromSelection($(this).parents('li').find('input.contact-list-vector').val(), $(this).closest('.contact-list').attr('id'));
          if (contact_list.selectedAll()) {
            contact_list.$el('mode').trigger('uncheck', [true]);
          }
          $(this).parents('li').removeClass('selected');
          contact_list.trigger('selection-changed');
        })
        .delegate(this.checkbox_selector, 'check', function() {
          contact_list.addContactToSelection($(this).parents('li').find('input.contact-list-vector').val(), $(this).closest('.contact-list').attr('id'));

          $(this).parents('li').addClass('selected');
          contact_list.trigger('selection-changed');
        });


    },

    _initSearch: function() {
      var contact_list = this;
      var $search_field = this.$el('search_field');
      $.log('_initSearch', this, $search_field);
      if ($search_field.length < 1) return;
      $search_field.data('default_value', $search_field.attr('default'));
      $search_field.focus(function() {
        if ($(this).val() === $(this).data('default_value')) {
          $(this).val('').removeClass('default');
        }
      });
      $search_field.blur(function() {
        if ($.trim($(this).val()) === '') {
          $(this)
            .val($(this).data('default_value'))
            .addClass('default');
        }
      });
      $search_field.delayedObserver(0.5, function(obj) {
        if (obj.val().length >= 3 || obj.val().length === 0) {
          contact_list.reload();
        }
      });
      $search_field.keydown(function (e) {
        if (e.keyCode === CR_KEYCODE) {
          return false;
        }
      });
      $search_field.siblings('.clear').click(function() {
        $search_field.val('');
        contact_list.reload();
      });

    },

    _initColumns: function() {
      $.log('initColumns', this);
      var contact_list = this;
      contact_list.$find('input.radio[name="contact_list[columns]"]')
        .live('click', function(e) {
          setTimeout(function() {
            contact_list.reload();
          }, 20);
        });
    },

    _runAction: function(action, value) {
      try {
        if (action) {
          this[action](value);
        }
      } catch(e) {
        $.log('Error', '_runAction()', action, arguments, e);
      }
    },

    _runActionFromDropdown: function(dropown, action) {
      var $dropown = $(dropown);
      var value = null;
      if (typeof action != 'undefined') {
        value = $dropown.val();
      } else {
        action = $dropown.val();
      }
      try {
        if (action) {
          this[action](value);
        }
        $dropown.val('');
      } catch(e) {
        $.log('Error', '_runActionFromDropdown()', action, arguments, e);
      }
    }

  });

})(jQuery);
jQuery(function($) {

  if ($('.quick-add').length == 0) return;

  $('.quick-add').each(function() {
    setupQuickAdd(this);
  });

  function setupQuickAdd(element) {
    var $form = $(element),
        $input = $form.find('input.quick-add-input'),
        $submit = $form.find('input[type="image"]'),
        $notification = $($form.attr('data-notification')).or($form),
        cached_list = false,
        default_val = "First Last Email";

    $form.setControl('quick_add');
    $input.val(default_val); // set default val on startup
    $input.css("color","gray");
    $submit.trigger('loading-img');

    $.log('setupQuickAdd', $form, $input, $submit);

    function clearSelected() {
      $input.val('');
      $input.trigger('off.autocomplete');
      $input.removeData('autocomplete-selected');
    }

    $form
      .addClass('bound')
      .bind('submit', function(e) {
        e.preventDefault();
        var params, val, selected = $input.data('autocomplete-selected');
        if (selected && selected.contact) {
          params = "guest[contact_id]=" + selected.contact.id;
        } else if (!$input.blank()) {
          val = escape($input.val()).replace('+', '%2B');
          params = "guest=" + val;
        }
        $.log('params', params);
        if (!params) {
          $submit.trigger('hide-loading');
          return false;
        }
        clearSelected(); // clear input
        $.ajax({
                url: $(this).attr('action'),
                type: 'post',
                dataType: 'json',
                data: params,
                success: function(response) {
                  PP.showNotification($notification, response, 'After');
                  var contact_list = ContactList.instance($form.attr('rel'))
                  contact_list.updateTotals(response);
                  contact_list.reload();
                  $submit.trigger('hide-loading');
                }
              });
        return false;
      });

    $input
      .siblings('.clear-field')
        .click(function() {
          clearSelected();
        }).end()
      .bind('keyup', function() {
        $input.blank() ? $submit.trigger('loading-img') : $submit.trigger('active-img');
        if ($input.val() != $input.data('selected-display')) {
          $input.removeData('autocomplete-selected');
        }
      })
      .bind('itemSelected.autocomplete', function(e, object) {
        setTimeout(function() {
          $input.data('selected-display', $input.val());
        }, 20);
        $input.data('autocomplete-selected', object);
        $submit.show();
      })
      .focus(function(){
        if($input.val() == default_val){
          $input.val('');
          $input.css("color","black");
        }
      })
      .blur(function(){
        if($input.val() == ''){
          $input.css("color","gray");
          $input.val(default_val);
          $input.trigger('off.autocomplete');
          $input.removeData('autocomplete-selected');
        }
      })
      .autocomplete({
        timeout: 200,
        getList: function(input) {
          if (input.blank()) {
            if ($.data(document.body, "autocompleteMode")) {
              input.trigger("updateList", [[]]);
            }
            return;
          }
          if (cached_list) {
            input.trigger("updateList", [cached_list]);
          } else {
            input.data('search-active', true);
            $.getJSON(input.attr('rel'), "limit=2000", function(json) {
              cached_list = json;
              input.trigger("updateList", [json]);
              input.data('search-active', false);
            });
          }
        },
        matcher: function(typed) {
          var to_match = "(" + typed.split(' ').join(').*(') + ")";
          return new RegExp(to_match, "i");
        },
        match: function(matcher) {
          return this.display_text.match(matcher);
        },
        template: function(node, matcher) {
          var html = node.display_text.replace(matcher, "<strong>$&</strong>");
          html = html.replace(new RegExp(node.email_address), "<span>$&</span>");
          return "<li>" + html  + "</li>";
        },
        insertText: function(node) {
          return node.display_text;
        }
      });
  }


});
jQuery(function($) {

  $('.show-load-on-submit')
    .setControl('show_load_on_submit')
    .live('show-loading', function() {
      var load_image, $button = $(this);
      $button.trigger('disable');
      if ($button.hasClass('dark')) {
        load_image = '/images/smallpreloader-dark.gif';
      } else {
        load_image = '/images/smallpreloader.gif';
      }
      if ($button.siblings('img.next-to-loader').length == 0) {
        if($button.siblings('.send-me-a-reminder').length > 0){
          $('.send-me-a-reminder')
          .wrap("<span style='position:relative;'>")
          .after("<img src='"+ load_image +"' class='next-to-loader' />");
        } else {
          $button
          .wrap("<span style='position:relative;'>")
          .after("<img src='"+ load_image +"' class='next-to-loader' />");
        }
      }
    })
    .live('disable', function() {
      var $button = $(this);
      if ($button.is('.flippable')) {
        $button.trigger('loading-img');
      }
      $button.attr('disabled', 'disabled').addClass('disabled');
    })
    .live('loading-img', function() {
      $.log('loading', this);
      $(this).attr('src', function(i, src) {
        return src.replace(/active|loading|disabled/, 'loading');
      });
    })
    .live('active-img', function() {
      $(this).attr('src', function(i, src) {
        return src.replace(/active|loading|disabled/, 'active');
      })
    })
    .live('enable hide-loading', function() {
      if ($(this).is('.flippable')) {
        $(this).trigger('active-img');
      }
      $(this)
      .removeClass('disabled')
      .removeAttr('disabled');
      $('.next-to-loader').remove();
    });


  $('.show-load-on-submit:not(.no-click)').live('click', function(e) {
    e.preventDefault();
    if ($(this).is('.disabled') || $(this).attr('disabled') == 'disabled') {
      $(this).trigger('disabled-click');
      return;
    };
    var $button = $(this);
    $button.trigger('show-loading');
    setTimeout(function() {
      $button.parents('form').submit();
    }, 500);
  });

});
(function($) {

  $(function() {

    var current_coins = parseInt($('.coin-count').attr('data-total-coins') || 0);
    var show_plus = true;

    $('#pricing-calculator').setControl('pricing_calculator').each(function() {

      $('.pricing-calculator-toggle, .pricing-calculator-toggle-wrap').click(function(){
        $('#pricing-calculator').toggle().trigger('update');
        $('#pricing-calculator-outer').toggleClass('box-creme');
        $('#pricing-calculator-outer').toggleClass('box-white');
        $('.pricing-calculator-toggle-wrap').toggleClass('expanded');
        $('.pricing-calculator-close').toggle();
        return false;
      });

      PP.customizeInputs(this);

      var $pricing_calc = $(this),
          $slider_input = $('.slider-val', this),
          $slider_side = $('.slider-side-val', this),
          $slider = $('.ui-slider', this),
          $threshold_warning = $('.threshold-warning', this),
          min = 1,
          threshold = 1000,
          max = 1000;

      var updateValue = function(value) {
        value = parseInt(value);
        if (value < max && value >= min) {
          $slider_input.val(value);
          $slider_side.html(value);
          $slider.slider('value', value);
        } else if (value >= max) {
          $slider_input.val(value);
          if(show_plus){
            $slider_side.html(max + "+");
          } else{
            $slider_side.html(max);
          }
          $slider.slider('value', max);
        } else if (value) {
          return updateValue(min);
        }
        if (value >= threshold) {
          $threshold_warning.show();
        } else {
          $threshold_warning.hide();
        }
        updateCoins(value);
      };

      var updateCoins = function(num_guests) {
        var features = [], total_coins_per_guest, total_coins, should_buy;
        $pricing_calc.find('ul.features li').each(function() {
          if ($(this).find('input[type="checkbox"]').is(':checked')) {
            features.push(JSON.parse($(this).attr('data-feature')));
          }
        });
        total_coins_per_guest = PP.calculateCoins(features, 1, 0);
        total_coins = PP.calculateCoins(features, num_guests, 0);

        $pricing_calc.find('.total-coins').text(total_coins);
        should_buy = current_coins ? total_coins - current_coins : total_coins;
        if (!should_buy || should_buy < 0) { should_buy = 0; }
        $pricing_calc.find('.total-coins-per-guest').text(total_coins_per_guest);
        if (($('ul.coins').is('.products') || $pricing_calc.is(':visible')) && should_buy > 0) {
          $('ul.coins li')
            .each(function(i) {
              var $product = $(this),
                  package_coins = parseInt($product.attr('data-coins'));
              if (should_buy <= package_coins || ((i+1) == $('ul.coins li').length)) {
                $product.trigger('select');
                return false;
              }
            });
        } else {
          $('ul.coins li').trigger('deselect');
        }
      };

      $('#premium_paper_coins').live('change', function(){
        $('.premium_paper').attr("data-feature", '{"threshold":3000,"unit":'+$(this).val()+',"name":"premium_paper"}');
        $slider_input.trigger('keyup');
      });

      $('ul.coins li')
        .bind('select', function() {
          $(this).is('.product') ?
            $(this).trigger('click') :
            $(this).addClass('on').siblings().removeClass('on');
        })
        .bind('deselect', function() {
          $(this).removeClass('on');
        })

      $pricing_calc
        .find('ul.features li')
          .find('label')
            .bind('click', function() {
              $(this).siblings('.checkbox').trigger('click');
            }).end()
        .find('input.checkbox')
          .live('click', function(e) {
            setTimeout(function() {
              $slider_input.trigger('keyup');
            }, 50);
          });

      $('.premium.checkbox').live('click',function(){
          show_plus = !$(this).is('.on');
          $('.increase').html("1000" + (show_plus ? "+" : " "))
      });

      $slider.slider({
        min: min,
        max: max,
        slide: function(e, ui) {
          updateValue(ui.value);
        }
      });

      $slider_input
        .bind('inc', function() {
          var val = parseInt($(this).val());
          if (val) {
            updateValue(val + 1);
          }
        })
        .bind('dec', function() {
          var val = parseInt($(this).val());
          if (val) {
            updateValue(val - 1);
          }
        })
        .bind('keyup', function(e) {
          $.log('keyup');
          if (e.keyCode === 38) {
            $(this).trigger('inc');
          } else if (e.keyCode === 40) {
            $(this).trigger('dec');
          } else if (!$(this).blank()) {
            updateValue($(this).val());
          }
        });

      $pricing_calc
        .bind('update', function() {
          $slider_input.trigger('keyup');
        })
        .find('a.increase')
          .click(function(e) {
            e.preventDefault();
            $slider_input.trigger('inc');
          })
          .end()
        .find('a.decrease')
          .click(function(e) {
            e.preventDefault();
            $slider_input.trigger('dec');
          })
          .end()
      setTimeout(function() {
        $pricing_calc.trigger('update');
      }, 50);
    });


  });


})(jQuery);

(function($) {
  var start = 0;                                                  // start on the second item
  var numItems = null;                                              // how many items do we have
  var lowestItem = 0;                                                // lowest at start is 0
  var animationTime = 400;                                            // how long should it take to animate (in ms)
  var easingType = 'swing';                                            // what type of easing do we want

  var $list, $placeholder, $clip, $container;

    var isAnimating = false;                                            // are we animating?
  var currItem  = null;                                              // what is the current item (set later)
  var lowestUniqueItem = 0;                                            // how low can we go without repeating
  var highestUniqueItem = 0;                                            // how high can we go without repeating
  var easeAmt = 50;                                                // how much do we ease in for next and previous
  var touched = false;                                                                                             // has the carousel been interacted with?

    Carousel = function(carouselElement) {
    $list = $(carouselElement);                                          // the list is what we passed in
    $clip = $list.parent();                                            // the clip is next above
    $container = $clip.parent();                                        // the container is the clip's parent
    $placeholder = $list.children("div");                                    // set up the placeholder (prepend is buggy)

    numItems = $list.children("li").size();                                    // get the number of items
    highestUniqueItem = numItems-1;
    /*
    if($.browser.safari){                                            // Webkit sees things differently
      itemSize = width($list.children("li")) + 98;
    }else if($.browser.opera){
      itemSize = width($list.children("li").children()) + 78;                          // get the size of one item
    } else {
      itemSize = width($list.children("li").children("img")) + 78;                      // get the size of one item
    }
    console.log(itemSize);
    */
    itemSize = 458;

    var i = 0;
    $list.children("li").each( function(){                                    // for each list item
      $(this).addClass("carouselitem-"+i);                                      // set the id number
      i++;                                                    // and increment index
    });

        $list.css('width', itemSize*numItems + 'px');                                // set the total width
    $list.children("li").css({                                          // make all the items line up
      'float':'left',
      'position':'relative'
    });
      $list.css({                                                  // set up the css for the list
      overflow: 'hidden',
      position: 'relative',
      top: 0,
      left: 0,
      margin: 0,
      padding: 0
      });
    $clip.css({                                                  // set up the css for the clip
      overflow: 'hidden',
      position: 'relative'
    });
      $container.css({                                              // set up the css for the container
      position: 'relative',
      display: 'block',
      '-webkit-user-select': 'none',
      '-moz-user-select' : 'none',
      'cursor' : 'pointer'
      });

    if(numItems != 1){                                              // if we have more than one item
      goTo(start, false);                                              // go to the first item without animating
      checkTop();                                                  // if necessary, prepare for movement
      checkBottom();                                                // and again on the other side


      $('.nextItem').live('click', function(){                                  // when you click on the next item
        if(!isAnimating){                                              // as long as we're not animating
          $(this).animate({left: '0'}, 200, easingType);                              // ease it back and then go to next
          next();
        }
      });
      $('.nextItem').live('mouseover', function(){                                // when you mouse over the next item
                easeNext(0);
      });
      $('.nextItem').live('mouseout', function(){                                  // when you mouse out of the next item
                easeNext(1);
      });


      $('.prevItem').live('click', function(){                                  // when you click the previous item
        if(!isAnimating){                                              // as long as we're not animating
          $(this).animate({left: '0'}, 200, easingType);                              // ease it back and go to previous
          prev();
        }
      });
      $('.prevItem').live('mouseover', function(){                                // when you mouseover the previous item
                easePrev(0);
      });
      $('.prevItem').live('mouseout', function(){                                  // when you mouse out of the previous item
                easePrev(1);
      });

      $('.currentItem').live('click', function(){                                  // go to next if user clicks on current item
        if(!isAnimating){
          next();
        }
      });

      $(document).keydown(function(event) {
        if (event.keyCode == '37') {
          prev();
        }
        else if (event.keyCode == '39') {
          next();
         }
      });

    } else {                                                    // otherwise,
      $list.css({                                                    // set up the following css
        'left': '0px',
        'width' : $container.width()
      });
      $container.css({
        'cursor' : 'default'
      });
    }
  };

  /* width($elem)
   * $elem : a jQuery element
   * Calculates the width of the element including margins and returns it
   */
  function width($elem){                                              // return the element's width and it's margins
    return $elem.width() + parseInt($elem.css('marginLeft')) + parseInt($elem.css('marginRight'));
  };

  /* scroll(howFar, direction, doAnimation)
   * howFar : the number for how far we need to scroll (usually calculated in goTo)
   * direction : a string, either 'left' or 'right' that specifices which direction to scroll
   * doAnimation : boolean describing whether or not to do the animation
   * Moves the carousel a specific number of items in either direction. If moving to the right, it calls checkTop()
   * to make sure we're prepared to approach the top. If moving to the left, it calls checkBottom to make sure we're
   * to approach the bottom. If another direction is specified, an alert is posted.
   */
  function scroll(howFar, direction, doAnimation){
    var currentPos = parseInt($list.css('left'));                                // get our current position

    if(direction == 'right'){                                          // if we're going right,
      currItem += howFar;                                              // update our index

      if(!doAnimation){                                              // if we're not doing animation
        $list.css('left', currentPos - (itemSize*howFar) );                              // just set the new position
        checkTop();
      } else {                                                  // otherwise
        isAnimating = true;
        $list.animate({'left' : currentPos - (itemSize*howFar) }, animationTime, easingType, checkTop);    // animate over using our options
      }

    }else if(direction == 'left'){                                        // if we're going left,
      currItem -= howFar;                                              // update our index

      if(!doAnimation){                                              // if we aren't doing animation
        $list.css('left', currentPos + (itemSize*howFar) );                              // just set the new position
        checkBottom();
      } else {                                                  // otherwise
        isAnimating = true;
        $list.animate({'left' : currentPos + (itemSize*howFar) }, animationTime, easingType, checkBottom);      // animate over using our options
      }

    } else {                                                  // otherwise,
      alert("I don't know how to go that way.");                                  // ERROR!
    }
  };

  /* checkTop()
   * Checks to see if we are one away from the far-right side (top) of the carousel. If we are, it updates the number of items
   * and calls copy(1) to copy the list. Then, it resets the next and previous items by calling setLastNext(). Afterwards,
   * it tells the carousel we have finished. If we're still in the middle, it just sets the next and previous items and specifies
   * that we're done animating.
   */
  function checkTop(){
    if(currItem >= numItems-2){                                          // if we're near the last item
      copy(1);                                                  // copy the bottom one
      numItems += numItems;                                            // update the higher extreme
      setLastNext();                                                // setup the next and last
      isAnimating = false;
    } else {                                                  // otherwise, we're in the middle
      setLastNext();                                                // setup the next and last
      isAnimating = false;                                            // this is all we have to do
    }
  };

  /* checkBottom()
   * Checks to see if we are one away from the far-left side (bottom) of the carousel. If we are, it updates the number of items
   * and calls copy(0) to copy the list. Then, it resets the next and previous items by calling setLastNext(). Afterwards,
   * it tells the carousel we have finished. If we're still in the middle, it just sets the next and previous items and specifies
   * that we're done animating.
   */
  function checkBottom(){
    if(currItem <= lowestItem+1){                                        // if we're near the start of the carousel
      lowestItem-= numItems;                                            // update the lower extreme
      copy(0);                                                  // and copy the top one there
      setLastNext();                                                // setup the next and last
      isAnimating = false;
    } else {                                                  // otherwise
      setLastNext();                                                // setup the next and last
      isAnimating = false;                                            // this is all we have to do
    }
  };

  /* copy(to)
   * to : an int (either 0 or 1) that specifies where to copy the list to. 0 means copy before the list, and 1 means copy after
   * the list.
   * Copies the list to the specified side of the list (appends to placeholder for beginning), and updates the width. If we are
   * copying to the start of the list, it also updates the 'left' css value so that there are still more items on the left.
   */
  function copy(to){
    if(to == 0){                                                // if we're copying to the bottom
      var currentPos = parseInt($list.css('left'));                                // get our current position
      var $item = $list.children("li").clone();                                  // get the list to copy
      var i = lowestItem;
      $item.each(function(){
        $(this).removeClass().addClass('carouselitem-'+i);
        i++;
      });
      $item.prependTo($placeholder);                                          // put the list on the end of the placeholder
      $list.css('width', 2*$list.width() + 'px');                                  // update the width
      $list.css('left', currentPos - (itemSize*numItems) );                            // and move over
    } else if(to == 1) {                                            // but if we're copying onto the top
      var $item = $list.children("li").clone();                                  // get the list to copy
      var i = numItems;
      $item.each(function(){
        $(this).removeClass().addClass('carouselitem-'+i);
        i++;
      });
      $item.appendTo($list);                                            // put it at the end
      $list.css('width', 2*$list.width() + 'px');                                  // and update the width
    }
  };

  /* setLastNext()
   * Adds classes to the next and previous item images so that we can ease in and out when they are moused over
   * Also sets z-indexes so that items can be moused on or clicked
   */
  function setLastNext(){
    var prev = currItem - 1;                                          // get previous item index
    var next = currItem + 1;                                          // get next item index
    $('.nextItem').removeClass("nextItem");                                    // remove the old class
    $('.prevItem').removeClass("prevItem");                                    // remove the old class
    $('.currentItem').removeClass("currentItem");                                // remove the old class

    $('.carouselitem-'+next).children().addClass("nextItem");                          // add the class to the new item
    $('.carouselitem-'+prev).children().addClass("prevItem");                          // add the class to the new item
    $('.carouselitem-'+currItem).addClass("currentItem");                            // add the class to the new item

    $('.prevItem').parent().css('z-index','1');                                  // correct the z-indexes
    $('.nextItem').parent().css('z-index','1');
    $('.carouselitem-'+currItem).css('z-index','0');
  };

  /* next()
   * PUBLIC FUNCTION
   * Moves to the next item in the carousel. If we are at the end of the carousel, it goes back to the start. This should never happen,
   * but if somehow it does, we are prepared.
   */
  var next = function(){
        touched = true;
    if(currItem == numItems-1){                                          // if we're at the last item
      goTo(0);                                                  // go to the first item
    } else {                                                  // otherwise,
      goTo(currItem + 1);                                              // go to the next item
    }
  };

  /* prev()
   * PUBLIC FUNCTION
   * Does and works the same way as next(), but in the opposite direction.
   */
  var prev = function(){
        touched = true;
    if(currItem == lowestItem){                                          // if we're at the first item
      goTo(numItems-1);                                              // go to the last item
    } else {                                                  // otherwise
      goTo(currItem - 1);                                              // go to the previous item
    }
  };

  /* easeNext(direction)
   * PUBLIC FUNCTION
   * eases the next item in the specified direction
   * Directions:
   *   0 - In
   *   1 - Out
   */
  var easeNext = function(direction){
        touched = true;
      if(!isAnimating){                                              // as long as we're not animating
          if(direction == 0){
          $('.nextItem').animate({left: 0-easeAmt}, 200, easingType);                        // ease it in
        }else if(direction == 1){
        $('.nextItem').animate({left: '0'}, 200, easingType);                          // ease it back
        }else{
            alert("I can't go that direction.");
        }
    }
  };

  /* easePrev(direction)
   * PUBLIC FUNCTION
   * works the same way as easeNext()
   */
  var easePrev = function(direction){
        touched = true;
      if(!isAnimating){                                              // as long as we're not animating
          if(direction == 0){
        $('.prevItem').animate({left : easeAmt}, 200, easingType);                        // ease it in
        }else if(direction == 1){
        $('.prevItem').animate({left: '0'}, 200, easingType);                          // ease it back
        }else{
            alert("I can't go that direction.");
        }
    }
  };

  var getTouched = function(){
    return touched;
  };

   /* goT0(index, doAnimation) or goTo(index)
    * PUBLIC FUNCTION
    * index : integer specifying the index of the destination item. lowestItem < index >= numItems
    * doAnimation : boolean variable specifying whether or not to do the animation. True by default, so that it doesn't have to be
    * specified.
    * Checks to make sure a move is legal (not currently moving, in range, and not the current index) and then moves there. calls
    * scroll(howFar, direction, doAnimation) to perform the move.
    */
  var goTo = function(index, doAnimation){
    if(!isAnimating){                                              // as long as we're not currently animating
      if(typeof doAnimation === 'undefined'){                                    // if animation is not specified
        doAnimation = true;                                              // assume we do it
      }
      if(index >= numItems || index < lowestItem){                              // if the move is illegal
        alert("cannot go to non-existant item");                                // say so
      }
      if(currItem == index){                                          // if we're trying to go where we already are,
        return;                                                  // do nothing
      }
      var howFar = 0;                                              // we will calculate where we are going
      if(currItem == 0 || index > currItem) {                                 // If we're at the first item, or we're going right, we have to go to the right
        howFar = index - currItem;                                        // this is how far we're going
        scroll(howFar, 'right', doAnimation);                                  // go this far to the right
      } else {                                                // otherwise, we go left
        howFar = currItem - index;                                        // this is how far we're going
        scroll(howFar, 'left', doAnimation);                                  // go this far to the left
      }
    }
  };

  /* expose next(), prev(), and goTo(inex, doAnimation) to anything using this class
   */
  $.extend(Carousel.prototype, {
    next: next,
    prev: prev,
    goTo: goTo,
    easeNext: easeNext,
    easePrev: easePrev,
    getTouched: getTouched
  });

})(jQuery);

var ichars = "!@#$%^&*()+=[]\\\';,/{}|\":<>?~`- .,_";
var nchars = "";
var allow  = " .-'";

s = allow.split('');
for (i = 0; i < s.length; i++)
  if (ichars.indexOf(s[i]) != -1)
    s[i] = "\\" + s[i];

allow = s.join('|');

var reg = new RegExp(allow,'gi');
var ch  = ichars + nchars;
ch      = ch.replace(reg,'');

$('#event_host').live('keypress', function(e) {
  if (!e.charCode) k = String.fromCharCode(e.which);
    else k = String.fromCharCode(e.charCode);

  if (ch.indexOf(k) != -1) e.preventDefault();
  if (e.ctrlKey&&k=='v') e.preventDefault();
});

$('#event_host').live('contextmenu',function () {return false});

(function($){
  $(document).ready(function() {
    if ($('.slides').length == 0) return;

    var carousel;

    $('.carousel').each(function(){
      carousel = new Carousel(this);
    });

    if(carousel != undefined){
        $('.carousel-next').live('click', function() {
              carousel.next();
        });

        $('.carousel-prev').live('click', function() {
              carousel.prev();
        });



            $.preload([
                $('.carouselitem--1').children('img').attr('src'),
                $('.carouselitem-0').children('img').attr('src'),
                $('.carouselitem-1').children('img').attr('src')
            ], {
                loaded_all: function(loaded, total) {
                    setTimeout(function() {
                        if(!carousel.getTouched()){
                            carousel.easeNext(0);
                            carousel.easeNext(1);
                            setTimeout(function(){
                                carousel.easePrev(0);
                                carousel.easePrev(1);
                            }, 100);
                        }
                    }, 3000);
                }
            });
        }

    if($('.category-descriptions')){ $('.category-descriptions h3').addClass('cufon'); }

  });
})(jQuery);
jQuery(function($) {

  $('.tooltip-new').live('mouseover', function(){
    $box = $(this).find('.box-with-tooltip');
    $pos = $box.offset();
    if($pos.top < 0){
      $box.css({
        'width' : '400px',
        'margin-left' : '-359px'
      });
      $(this).find('.pointer').css({
        'margin-left' : '180px'
      });
    } else if($pos.left < 0){
      $box.css('margin-left', function(i, current_val){ return parseInt(current_val) - $pos.left + 5; });
      $(this).find('.pointer').css('margin-left', function(i, current_val){ return parseInt(current_val) + $pos.left - 5; });
    }
  });

});

(function($) {

  $(document).ready(function() {

    $('#admin-logos').each(function() {
      $('#user-search').submit(function() {
        $.post(
          $(this).attr('action'),
          $(this).serialize(),
          function(data, textStatus) {
            $('#results').html(data);
          },
          'html'
        );
        return false;
      });

      $('#results a').live('click', function() {
        $.get(
          $(this).attr('href'),
          null,
          function(data, textStatus) {
            $('#results').html(data);
          },
          'html'
        );
        return false;
      });
    });

    $('#new-admin-logos').each(function() {
      $('#user-search').submit(function() {
        $.post(
          $(this).attr('action'),
          $(this).serialize(),
          function(data, textStatus) {
            $('#results').html(data);
          },
          'html'
        );
        return false;
      });

      $('#results a').live('click', function() {
        $.get(
          $(this).attr('href'),
          null,
          function(data, textStatus) {
            $('#results').html(data);
          },
          'html'
        );
        return false;
      });
    });

  });

})(jQuery);
(function($) {

  $(document).ready(function() {
    $('#admin-stats').each(function() {

    });
  });

})(jQuery);
(function($) {

  $(document).ready(function() {
    $('#admin-redelivery, #admin-resend').each(function() {

      $('#events-search form').submit(function(e) {
        e.preventDefault();
        $.post(
          $(this).attr('action'),
          $(this).serialize(),
          function(data, status) {
            $('#results').html(data);
          },
          'html'
        );
      });

      $('#results a').live('click', function(e) {
        e.preventDefault();
        $.get(
          $(this).attr('href'),
          {},
          function(data, status) {
            $('#results').html(data);
          },
          'html'
        );
      });

      $('#results input[type="checkbox"][name="all"]').live('click', function(e) {
        var $checkboxes = $('#results form input[type="checkbox"]');
        if ($(this).attr('checked')) {
          $checkboxes.attr('checked', 'checked');
        } else {
          if ($('#results input[type="checkbox"][name="delivered"]').attr('checked')) {
            $checkboxes = $checkboxes.filter(':not(.delivered)');
          }
          $checkboxes.removeAttr('checked');
        }
      });

      $('#results input[type="checkbox"][name="delivered"]').live('click', function(e) {
        var $checkboxes = $('#results form input.delivered');
        if ($(this).attr('checked')) {
          $checkboxes.attr('checked', 'checked');
        } else {
          $checkboxes.removeAttr('checked');
        }
      });

      $('#results form').live('submit', function(e) {
        e.preventDefault();
        var $submit = $(this).find('input[type="submit"]');
        $submit.disable();
        $.post(
          $(this).attr('action'),
          $(this).serialize(),
          function(data, status) {
            if (data.status == 'success') {
              $('#status').html('<div class="notification">' + data.notices[0] + '</div>');
            } else {
              $('#status').html('<div class="error">' + data.message + '</div>');
            }
            $submit.enable();
          },
          'json'
        );
      });

    });
  });

})(jQuery);
(function($) {
  $(document).ready(function() {
    if($('.promo-codes-import').length == 0){ return; }

    $('.promo-codes-import form').live('submit', function(e){
      e.preventDefault();
      $.log("submitted");
      $form = $(this);
      var ajax_options = {
          url: $(this).attr('action'),
          type: $(this).attr('method'),
          data: $(this).serialize(),
          dataType: 'json',
          success: function(response) {
              $.log('form success', response);
              PP.showNotification($form, response);
          }
      }
      $(this).ajaxSubmit($.extend(ajax_options, {iframe: true}));
      return false;
    })

  });
})(jQuery);
(function($) {

  function _parsePrice(cents) {
    var price = (cents / 100).toString();
    if (/[0-9]+\.[0-9]/.test(price)) {
      price = price + '0';
    } else if (/[0-9]+/.test(price)) {
      price = price + '.00';
    }
    return price;
  }

  function Order() {
    this.items = [];
    this._initEvents();
    var counts = {};
    $.each(['stamps', 'coins'], function(i, type) {
      var count = parseInt($('[data-total-' + type +']').attr('data-total-' + type), 10);
      counts[type] = count ? count : 0;
    })
    this.account_counts = counts;
    $('ul.products li.on').triggerHandler('click');
  }

  Order.prototype = {

    _initEvents: function() {
      var order = this;
      $('ul.products li').click(function() {
        var type     = $(this).attr('data-type'),
            title    = $(this).attr('data-title'),
            price    = _parsePrice($(this).find('[data-price]').attr('data-price')),
            quantity = parseInt($(this).find('[data-quantity]').attr('data-quantity'), 10),
            new_html;

        $.log('product click', this, 'type', type);

    new_html =  '<div class="'+type+'">';
        new_html += quantity + " " + title;
        new_html += '<strong>$' + price + '</strong><br/>';
    new_html += '<a class="remove" href="javascript:">Remove</a></div>'
        new_html += '<div class="total">New total in your account: ';
        new_html += (quantity + order.account_counts[type]) + '</div>';

        $('#checkout-items .chosen.' + type)
          .attr('class', ['chosen', type, $(this).attr('class')].join(' '))
          .show().html(new_html);

        $(this).siblings().andSelf().removeClass('on');
        $(this).addClass('on');

        $('#checkout-items').trigger('items-add', [type]);

        $(this).siblings().find('[type="button"]').removeClass('on');
        $(this).find('[type="button"]').addClass('on');

        $(this).find('[type="radio"]').attr('checked', 'checked');
        $(this).siblings().find('input[type="hidden"]').attr('disabled', 'disabled');
        $(this).find('input[type="hidden"]').attr('disabled', null);
      })
      .find('a.cancel').click(function() {
        var $item = $(this).parents('li');
        $(this).parents('.products').find('.on')
          .removeClass('on')
          .find('[type=radio]')
          .removeAttr('checked');
        $('#checkout-items').trigger('items-remove', [$item.attr('data-type')]);
        return false;
      });

      $('#checkout-items')
        .bind('items-add', function(e, item_type) {
          $.log('items-add', item_type);
          var index = $.inArray(item_type, order.items),
              old_length = order.items.length;
          if (index === -1) {
            order.items.push(item_type);
          }

          if (old_length === 0 && order.items.length === 1) {
            $('span.summary', this).remove();
            $(this).siblings('input.submit').trigger('active-img').removeAttr('disabled');
          }
        })
        .bind('items-remove', function(e, item_type) {
          $.log('items-remove', item_type);
          var index = $.inArray(item_type, order.items),
              old_length = order.items.length;

          if (index !== -1) {
            order.items.splice(index, 1);
          }
          $(this).find('.' + item_type).hide();

          if (old_length === 1 && order.items.length === 0) {
            $(this).append('<span class="summary">Choose a product on the left.</span>');
            $(this).siblings('input.submit').trigger('loading-img').attr('disabled', 'disabled');
          }
        });


      $('#order-side a.remove').live('click', function() {
      var order_type = $(this).closest('div').attr('class');

      $('#order-main ul.'+order_type).find('.on')
            .removeClass('on')
            .find('[type=radio]')
            .removeAttr('checked');

          $('#checkout-items').trigger('items-remove', [order_type]);
    })
    }
  };

  $(function() {



    $('#order-splash').each(function () {
      var order = new Order(),
          costs = JSON.parse($('.event-costs').attr('data-costs') || "{}"),
          needs_stamps;

      needs_stamps = costs.unsent - costs.stamps;
      if (needs_stamps > 0) {

        $('ul.stamps li')
          .each(function(i) {
            var $product = $(this),
                package_stamps = parseInt($product.attr('data-stamps'));
            if (needs_stamps <= package_stamps || ((i+1) == $('ul.stamps li').length)) {
              setTimeout(function() {
                $product.triggerHandler('click');
              }, 50);
              return false;
            }
          });
      };


    });

    $('.tooltip-link').hover(
      function() {
        $(this).siblings('.tooltip-content').show();
      },
      function() {
        $(this).siblings('.tooltip-content').hide();
      }
    );

    $('#billing_locale').change(function() {
      if ($(this).val() == 'CA') {
        $(this)
          .parents('form')
          .find('input[name="billing_address[zip]"]')
          .attr('disabled', 'disabled')
          .val('N/A');
      } else {
        $(this)
          .parents('form')
          .find('input[name="billing_address[zip]"]')
          .removeAttr('disabled')
          .val('');
      }
    });

    $('ul li .destroy-credit-card').click(function() {
      if (confirm('Are you sure you want to remove this credit card?  There will be no more confirmation screens.')) {
        $(this)
          .parents('form')
          .attr('action', $(this).attr('href'))
          .append('<input type="hidden" name="_method" value="delete" />')
          .submit();
      }
      return false;
    });

    $('ul li .update-credit-card').click(function() {
      $(this)
        .parents('form')
        .attr('action', $(this).attr('href'))
        .append('<input type="hidden" name="_method" value="put" />')
        .submit();
      return false;
    });


  });

  $(document).ready(function() {

    if($('#billings').length == 0){
      return;
    }

    $('.pw-forgot').click(function() {
      $.log("clicked");
      $('#s-forgot').show();
      return false;
    });

    $('.pw-cancel').click(function() {
      $.log("clicked");
      $('#s-forgot').hide();
      return false;
    });

    $('#s-forgot').submit(function() {
      $.ajax({
        type: 'POST',
        url: $(this).attr('action'),
        dataType: 'json',
        data: $(this).serialize(),
        success: function(data, textStatus) {
          $('#forgot-password-messages').fadeOut(300);

          $.log(data, textStatus);

          $('#forgot-password-messages')
            .html('')
            .removeClass('notification')
            .removeClass('error');

          if(data){
            if (data.error) {
              $('#forgot-password-messages').addClass('error').html(data.error);
            }else if (data.notice) {
              $('#forgot-password-messages').addClass('notification').html(data.notice+"<br>Please log out before resetting your password.");
            }
          } else {
            if(textStatus == "success"){
              $('#forgot-password-messages').addClass('notification').html("Reset Password link emailed to "+$('#email_address').val()+"<br>Please log out before resetting your password.");
            } else {
              $('#forgot-password-messages').addClass('error').html("Something went wrong.");
            }
          }

          setTimeout(function(){
            $('#forgot-password-messages').fadeIn(400);
          }, 300);
          $('#email_address').val('');
        }
      });
      return false;
    });

  });

})(jQuery);
jQuery.guard('#home-postbox', function($) {

  var postbox = $.sammy('#home-postbox', function() {

    var current = {};

    var mainHeight = $('#events-list').height();

    this.swap = function(content) {
      $('#events-list').html(content);
    };

    this.helpers({
      blockLoading: function() {
        var height = this.$element().find('.main table').outerHeight();
        if (!height) { height = 600; }
        this.$element().find('.loading-large-wrap')
          .find('.loading-large')
          .css({height: height + 'px'}).end()
          .show();
      },
      showLoading: function() {
        $('table .buttons .loading').show();
      },
      hideLoading: function() {
        $('table .buttons .loading').hide();
      },
      loadCompose: function(section_id, category_id) {
        this.log('loadCompose', section_id, category_id);
        var context = this,
            event_type = [section_id, category_id],
            setCurrent = function() {
              context.selectNav('compose', event_type);
              current.category = 'compose';
              current.event_type = event_type;
              context.sendToFlash('focusOnFlowCategory', parseInt(section_id), parseInt(category_id));
            };
        if (current.category != 'compose') {
          context.blockLoading();
          this.log('loading compose');
          $.ajax({
            url: ['', 'postbox', 'compose'].join('/'),
            data: {},
            success: function(html) {
              setCurrent();
              context.app.swap(html)
              $('#events-list').attr('class', 'main compose');
              Cufon.refresh();
            }
          });
        } else {
          setCurrent();
        }
      },
      focusOnFlowCategory: function(section_id, category_id) {
        this.redirect('#', 'compose', 'section', section_id, 'category', category_id);
      },
      flowLoaded: function() {
        this.log('flash loaded');
        $('#flashcontent').addClass('flash-loaded');
      },

      loadEvents: function(category, event_type, page, callback) {
        var context = this,
            url = ['', 'postbox', category].join('/'),
            event_type = event_type.split(','),
            data;
        if (event_type[0] === 'archived') {
          data = {archived: true};
        } else {
          data = (event_type.length > 0) ? {event_type: event_type} : {};
        }
        if (page) {
          data['page'] = page;
        }
        var wrapped_callback = function(html) {
          context.selectNav(category, event_type);
          current.category = category;
          current.event_types = event_type;
          current.page = page;
          context.app.swap(html)
          $('#events-list').attr('class', 'main ' + category);
          if ($.isFunction(callback)) {
            callback.apply(context, [html]);
          }
          Cufon.refresh();


          /* // Update the height to new one
          var newHeight = 0;
          $('#events-list > *').each(function(){                                                        // for each item in the main div
              newHeight += $(this).height();                                                                // add its height to the total
          });
          $('#events-list').animate({height: newHeight+1+"px"}, 400, 'swing' );                         // animate to the new height
          */
        }
        context.blockLoading();
        $.ajax({
          url: url,
          data: data,
          success: wrapped_callback
        });


      },
      selectNav: function(category, event_type) {
        var $nav = this.$element().find('.side ul'),
            $category_nav = $nav.children('li.' + category),
            url = this.urlFor(category, event_type),
            section_id, category_id;

        this.log('selectNav', category, $nav);
        if (category != current.category) {
          $nav.children('li.on')
                .removeClass('on')
                .children('ul')
                  .find('li.on').removeClass('on').end()
                .slideUp();
          $category_nav
                .addClass('on')
                .children('ul')
                  .slideDown();
        }
        if (category == 'compose') {
            section_id = event_type[0];
            category_id = event_type[1];
            $category_nav.children().children().children("ul").hide();                                          // hide the subnavs
            $('.primary').removeClass('primary');                                                               // remove primary
            $category_nav.find('.on').removeClass('on').end()                                                   // remove current link
                .find("a[data-category_id='" + category_id +"']").parent().addClass('on');                      // find and add the new one
            $category_nav.find("a[data-section_id='" + section_id +"']").parent()                               // find the new current menu
                    .addClass('primary')                                                                        // add the class
                    .children("ul").addClass('current')                                                         // add the class to the list
                        .show().end();                                                                          // and show it
            /*if($('.side').height() > mainHeight){                                                               // if the side gets too big
                $('#events-list').height($('.side').height());                                                      // match it
            }else{                                                                                              // otherwise
                $('#events-list').height(646);                                                                      // make it the normal size
            }*/
        } else {
          if (event_type && event_type.length > 0) {
            $category_nav.find('li')
              .removeClass('on')
              .children().filter('[href="'+ url +'"]').parent().addClass('on');
          } else {
            $category_nav.find('li').removeClass('on');
          }
        }
      },
      urlFor: function(category, event_types, page) {
        var path = ['#', category];
        this.log('urlFor', 'category', category, 'event_types', event_types, 'page', page);
        if (event_types && event_types.length > 0 && !$.blank(event_types[0])) {
          path.push(event_types.join(','))
        }
        path = path.join('/')
        if (page) {
          path += "?page=" + page;
        }
        return path;
      },
      postWithNotifiction: function(method, url, callback) {
        var context = this,
            wrapped_callback
            $container = this.$element().find('.notification');
        context.blockLoading();
        wrapped_callback = function(json) {
          PP.showNotification($container, json, null);
          if ($.isFunction(callback)) {
            callback.apply(context, [json]);
          } else {
            context.app.refresh();
          }
        }
        $.ajax({
          url: url,
          type: 'POST',
          data: { _method: method },
          dataType: 'json',
          success: wrapped_callback
        });
      },
      sendToFlash: function() {
        PP.sendToFlash('#flashcontent', 'flowCallback', arguments)
      }
    });

    this.get('#/compose', function(context) {
      var primary_url = $('li.compose ul li.primary:eq(0) a').attr('href');
      if (!primary_url) {
        primary_url = $('li.compose ul li:eq(0) a').attr('href');
      }
      setTimeout(function() {
        if (primary_url) {
          context.redirect(primary_url);
        }
      }, 50);
    });

    this.get('#/compose/section/:section_id/category/:category_id', function(context) {
      this.loadCompose(this.params['section_id'], this.params['category_id']);
    });

    this.get('#/:category', function(context) {
      this.loadEvents(this.params['category'], "", this.params['page']);
    });

    this.get('#/:category/:event_type', function(context) {
      this.loadEvents(this.params['category'], this.params['event_type'], this.params['page']);
    });

    this.bind('flash-event', function(e) {
      var context = this;
      this.log('flash-event', e, this.params);
      if (this.params['name'] && context[this.params['name']]) {
        context[this.params['name']].apply(context, this.params['args']);
      }
    });

    this.bind('run', function() {
      var context = this;
      $('tr.row a.actions').live('click', function(e) {
        Sammy.log('clicked on actions');
        e.stopImmediatePropagation();
        return false;
      });

      $('tr.row a.action').live('click', function(e) {
        Sammy.log('clicked on action');
        e.stopImmediatePropagation();
        var $row = $(this).parents('tr.row'),
            method = $(this).attr('data-method'),
            url    = $(this).attr('href'),
            confirm = $(this).attr('data-confirm'),
            callback;

        callback = function() {
          context.postWithNotifiction(method, url)// function(json) {
        };

        if (confirm) {
          PP.getConfirmation(confirm, callback);
        } else {
          callback();
        }
        return false;
      });

      $('.buttons > *').live('mouseover', function(){
        var $dropdown = $(this).parent().find('ul');
        var $container = $('#home-postbox');
        var containerTop = $container.position().top
        var dropdownBottom = $dropdown.position().top + 10 + containerTop + $dropdown.outerHeight(true);
        var containerBottom = containerTop + $container.height();
        if(dropdownBottom > containerBottom){
          $container.css({
            'overflow' : 'visible',
            'margin-bottom' : '0'
          });
          $('#home-postbox .main').css({
            '-webkit-box-shadow' : 'none',
            '-moz-box-shadow' : 'none'
          });
          $('.temp-div').show();
        }
      });

      $('.buttons > *').live('mouseout', function(){
        $('#home-postbox').css({
          'overflow' : 'hidden',
          'margin-bottom' : '10px'
        });
        $('#home-postbox .main').css({
          '-webkit-box-shadow' : '#AAA 0px 0px 4px',
          '-moz-box-shadow' : '#AAA 0px 0px 4px'
        });
        $('.temp-div').hide();
      });

      $('tr.row').live('click', function(e) {
        Sammy.log('clicked', e);
        var $row = $(this),
            url  = $row.attr('rel');
        if ($(e.target).is('a')) {
          return true;
        }
        if (url) {
          if ($row.parents('.main').is('.received')) {
            PP.openWithNewWindow(url);

            $row.removeClass('fresh');
            $row.find('td.status p').attr('class','opened').text('opened');

            var $side_row = $('div.side li.on a.pb-cat'),
            $side_subrows = $('div.side li.on ul li a.pb-subcat'),
            fresh_rows = 0;

            $side_subrows.each(function() {
              var getFresh = function(str) {
                return str.length > 0 ? parseInt(str.replace(/\D/g, '')) : 0
              }

              var type_count = $('span', this).text().trim();

              if($(this).parent().find('input[type=hidden]').val() == $row.find('td.status input[type=hidden]').val()) {
                if(type_count.length > 0) {
                  if(getFresh(type_count) > 1)
                  type_count = '('+(getFresh(type_count)-1) +')';
                  else
                  type_count = ''
                  $('span', this).text(type_count);
                }
              }

              fresh_rows += getFresh(type_count)
            });

            $side_row.find('span').text(fresh_rows > 0 ? ' ('+fresh_rows+')' : '');

          } else {
            context.blockLoading();
            setTimeout(function() {
              context.redirect(url);
            }, 200);
          }
          return false;
        }
      });

      $('.paginate a:not(.inactive)').live('click', function(e) {
        e.preventDefault();
        var page = $(this).attr('rel'),
            url  = context.urlFor(current.category, current.event_types, page);
        context.redirect(url);
      })
    });

  });

  window.flowCallback = function() {
    var args = $.makeArray(arguments),
        name = args.shift();
    Sammy.log('=- flowCallback', name, args);
    postbox.trigger('flash-event', {name: name, args: args});
  };

  postbox.run('#/compose');

});
(function($) {

  function TicketedReply() {
    this.quantity = 0;
    this.subtotal = 0;
    this.fees = 0;
  }

  TicketedReply.prototype = {

    calculate: function() {
      var ticketed_reply = this;

      ticketed_reply._reset();

      $('.record').each(function() {
        var quantity = parseInt($(this).find('.quantity option:selected').html(), 0);
        if (quantity > 0) {
          var price = parseInt($(this).find('.price-cents').html(), 0);
          var fee = parseInt($(this).find('.fee-cents').html(), 0);
          ticketed_reply.quantity += quantity;
          ticketed_reply.subtotal += quantity * price;
          ticketed_reply.fees +=  quantity * fee;
        }
      });
    },

    init: function() {
      var ticketed_reply = this;
      ticketed_reply.update();
      $('.ticket-select').change(function() {
        ticketed_reply.update();
      });
    },

    update: function() {
      var ticketed_reply = this;
      ticketed_reply.calculate();

      var total = ticketed_reply.subtotal + ticketed_reply.fees;
      $('.total .quantity').html(ticketed_reply.quantity);
      $('.basic.fees .price').html(ticketed_reply._to_money(ticketed_reply.fees));
      $('.total .price').html(ticketed_reply._to_money(total));
    },

    _reset: function() {
      this.quantity = 0;
      this.subtotal = 0;
      this.fees = 0;
    },

    _to_money: function(total) {
      if (total === 0) {
        return '$0.00';
      }

      var str = (total / 100) + '';
      if (str.match(/\.[0-9][0-9]$/)) {
        return '$' + str;
      } else if (str.match(/\.[0-9]$/)) {
        return '$' + str + '0';
      } else {
        return '$' + str + '.00';
      }
    }

  };

  $(document).ready(function() {

    $("#purchases").each(function() {
      var ticketed_reply = new TicketedReply();
      ticketed_reply.init();
    });

  });

})(jQuery);
(function($) {

  function Rsvp() {
    this.group_name = $('input[name="contact[group_name]"]');
    this.first_name = $('input[name="contact[first_name]"]');
    this.last_name = $('input[name="contact[last_name]"]');
    this.email_address = $('input[name="contact[email_address]"]');
    this.comment_group_name = $('input[name="guest[contact][group_name]"]');
    this.comment_first_name = $('input[name="guest[contact][first_name]"]');
    this.comment_last_name = $('input[name="guest[contact][last_name]"]');
    this.prompts = [];
  }

  Rsvp.prototype = {
    setPrompt: function(selector, text) {
      this.prompts.push(text);

      selector.focus(function() {
        if ($(this).val() == text) {
          $(this).val('');
        }
      });

      selector.blur(function() {
      });

      selector.parents('form').submit(function() {
        if (selector.val() == text) {
          selector.val('');
        }
      });
    }
  };

  $(document).ready(function() {
    $("#change-rsvp a").click(function(){
      $("#change-rsvp, .replied-message").hide();
      $('#enabled-rsvp, .additional-comments, .reply-decision .options, .host-name, .reply-name-edit').show();
      return false;
    });

    $("#change-comment a").click(function(){
      $(".comment-exist, #change-comment, .guest-name").hide();
      $('.submit-note, .comment-textarea, .guest-edit').show();
      return false;
    });

    $("#reply").each(function() {
      rsvp = new Rsvp();
      rsvp.setPrompt(rsvp.group_name, 'Type your Couple/Family Name')
      rsvp.setPrompt(rsvp.first_name, 'Type your First Name');
      rsvp.setPrompt(rsvp.last_name, 'Type your Last Name');
      rsvp.setPrompt(rsvp.email_address, 'Type your Email Address');
      rsvp.setPrompt(rsvp.comment_group_name, 'Type your name');
      rsvp.setPrompt(rsvp.comment_first_name, 'Type your First Name');
      rsvp.setPrompt(rsvp.comment_last_name, 'Type your Last Name');
    });

    $("#reply-guests").each(function() {
      $(this).find('ul li a').click(function(){
        if($(this).html() == 'Hide') {
          $(this).siblings('.box-with-comment').hide();
          $(this).html('View');
        }
        else {
          $(this).siblings('.box-with-comment').show();
          $(this).html('Hide');
        }
      });
    });

    $('#reply .total-guests')
      .bind('enable', function() {
        $.log('enable');
        $(this).show().find('select').removeAttr('disabled');
      })
      .bind('disable', function() {
        $.log('disable');
        $(this).hide().find('select').attr('disabled', 'disabled');
      });

    $('#reply input.checkbox[name="attending"]')
      .live('click', function() {
        $.log("clicked", $(this).is('.on'));
        if ($(this).siblings().attr('value') == 'true' && $(this).is('.on')) {
          $('#reply .total-guests').trigger('enable');
        } else {
          $('#reply .total-guests').trigger('disable');
        }
      });

    $('#will_attend_radio').parent().find('input.checkbox').click(function(){
      $other = $('#will_not_attend_radio').parent().find('input.checkbox');
      if(!$(this).is('.on') && $other.is('.on')){
        $other.trigger('click');
      }
    });

    $('#will_not_attend_radio').parent().find('input.checkbox').click(function(){
      $other = $('#will_attend_radio').parent().find('input.checkbox');
      if(!$(this).is('.on') && $other.is('.on')){
        $other.trigger('click');
      }
    });

    $('#enabled-rsvp .submit').click(function(e){
      if(($('.options').find('input.on').length == 0) && $.trim($('.additional-comments textarea').val()) == ''){
        PP.showNotification('#reply form', {status: 'error', errors: ['Please RSVP and/or write a comment below.']})
        e.preventDefault();
      }
    });

    $('.submit-note').click(function(e){
      if($.trim($('#guest_comment').val()) == ''){
        PP.showNotification('#reply form', {status: 'error', errors: ['Please write a comment below.']})
        e.preventDefault();
      }
    });

    $('#disabled-rsvp').click(function() {
      $(this).parent().find('.error').show()
    });

    $('#reply-guests .reply-back').click(function() {
      $('#reply-guests').removeClass('guest-only');
      $('#reply').show();
      return false;
    });

    $('#reply-guests .total a').click(function() {
      $('#reply-guests').addClass('guest-only');
      $('#reply').hide();
      return false;
    });

    $(this).find('#reply-guests .view-all').toggle(
      function() {
        $('.box-with-comment').show();
        $(this).html('Hide All Comments');
        $('#reply-guests ul li a').html('Hide');
      },
      function() {
        $('.box-with-comment').hide();
        $(this).html('View All Comments');
        $('#reply-guests ul li a').html('View');
      }
    );

    $("#guest-register").each(function() {

      function toggleForms(form_id) {
        $('#session-login').show();
        $('#become-member, .account-exist').hide();
        $('#session-login').removeClass('register');

        var a = ['#s-login', '#s-join', '#s-forgot'];
        for (var i = 0; i < a.length; i++) {
          form_id == a[i] ? $(a[i]).show() : $(a[i]).hide();
        }

        return true;
      }

      $('.link-forgot').click(function() {
        toggleForms('#s-forgot');
        return false;
      });

      $('.link-cancel').click(function() {
        toggleForms('#s-login');
        return false;
      });

      $('.link-join').click(function() {
        toggleForms('#s-join');
        return false;
      });

      $('#s-forgot').submit(function() {
        $.get(
          $(this).attr('action'),
          $(this).serialize(),
          function(data, textStatus) {
            $('#forgot-password-messages')
              .html('')
              .removeClass('notification')
              .removeClass('error');

            if (data.error) {
              $('#forgot-password-messages').addClass('error').html(data.error);
            }

            if (data.notice) {
              $('#forgot-password-messages').addClass('notification').html(data.notice);
            }
            $('#email_address').val('');
          },
          'json'
        );
        return false;
      });

    });
  });

})(jQuery);
;(function($) {

  $(document).ready(function() {

    $('#session-new').each(function() {
      function toggleForms(form_id) {
        $('#session-login').show();
        $('#become-member, .account-exist').hide();
        $('#session-login').removeClass('register');

        var a = ['#s-login', '#s-join', '#s-forgot'];
        for (var i = 0; i < a.length; i++) {
          form_id == a[i] ? $(a[i]).show() : $(a[i]).hide();
        }

        return true;
      }

      PP.setupForm('#new-account')
        .bind('is-valid', function() {
          var $form = $(this);
          $form.trigger('enabled');
        })
        .bind('is-invalid', function() {
          var $form = $(this);
          $form.trigger('disabled');
        })
        .trigger('validate');

      $('.welcome-signup').bind('display-form', function() {
        $(this).hide();
      });

      $('.link-forgot').click(function() {
        var emailAddress = $('#s-login #login_email').val();
        $('#s-forgot #email_address').val(emailAddress);
        toggleForms('#s-forgot');
        return false;
      });

      $('.link-cancel').click(function() {
        toggleForms('#s-login');
        return false;
      });

      $('.link-join').click(function() {
        toggleForms('#s-join');
        return false;
      });

      $('#s-forgot').submit(function() {
        $.post(
          $(this).attr('action'),
          $(this).serialize(),
          function(data, textStatus) {
            $('#forgot-password-messages')
              .html('')
              .removeClass('notification')
              .removeClass('error');

            if (data.error) {
              $('#forgot-password-messages').addClass('error').html(data.error);
            }

            if (data.notice) {
              $('#forgot-password-messages').addClass('notification').html(data.notice);
            }
            $('#email_address').val('');
          },
          'json'
        );
        return false;
      });

    });

  });

})(jQuery);

;(function($) {

  $(document).ready(function() {

    $('#session-login.photo-login').each(function() {
      function toggleForms(form_id) {
        $('#session-login').show();
        $('#become-member, .account-exist').hide();
        $('#session-login').removeClass('register');

        var a = ['#s-login', '#s-join', '#s-forgot'];
        for (var i = 0; i < a.length; i++) {
          form_id == a[i] ? $(a[i]).show() : $(a[i]).hide();
        }

        return true;
      }

      $('.inline-forgot').click(function() {
        toggleForms('#s-forgot');
        return false;
      });

      $('.inline-login').click(function() {
        toggleForms('#s-login');
        return false;
      });

      $('#s-forgot').submit(function() {
        $.post(
          $(this).attr('action'),
          $(this).serialize(),
          function(data, textStatus) {
            $('#forgot-password-messages')
              .html('')
              .removeClass('notification')
              .removeClass('error');

            if (data.error) {
              $('#forgot-password-messages').addClass('error').html(data.error);
            }

            if (data.notice) {
              $('#forgot-password-messages').addClass('notification').html(data.notice);
            }
            $('#email_address').val('');
          },
          'json'
        );
        return false;
      });

    });

  });

})(jQuery);
(function($) {

  $(document).ready(function() {
    $('#optional h2 a').click(function() {
      if($('#optional').hasClass("o-expanded")) {
        $('#optional').addClass("o-contracted");
        $('#optional').removeClass("o-expanded");
        $('.optional').hide();
      }
      else {
        $('#optional').removeClass("o-contracted");
        $('#optional').addClass("o-expanded");
        $('.optional').show();
      }
      return false;
    });
  });

})(jQuery);
jQuery.guard('#promo', function($) {
  $(function() {
    $('#promo-form input.radio:checked').trigger('uncheck');
  });

  $('#promo-form input.radio').click(function() {
    var form_url = $(this).closest('p.radio-full').find('input[type=radio]').val() + '_url';
    if(form_url == 'login_url') {
      $('#email-field').attr('name','user[email_address]')
    } else {
      $('#email-field').attr('name','email_address')
    }

    form_url = $('#promo-form input[name='+form_url+']').val()

    $('#promo-form').attr('action',form_url);
  });

  $('.link-forgot').click(function() {
    var emailAddress = $('#email-field').val();
    $('#s-forgot #email_address').val(emailAddress);
    $('#promo-form').hide();
    $('#s-forgot').show();
    return false;
  });

  $('.link-cancel').click(function() {
    $('#promo-form').show();
    $('#s-forgot').hide();
  });

  $('#promo-form input[placeholder]').each(function() {
    $(this).css('color', 'gray');
    if($(this).val() == '') {
      $(this).val($(this).attr('placeholder'))
    }

    $(this).focus(function() {
      $(this).css('color','').val('');
      if($(this).attr('placeholder').toLowerCase() == 'password' && $(this).hasClass('pass-placeholder')) {
        $('.pass-placeholder').hide()
        $('.pass-actual').show().focus();
      }
    }).blur(function() {
      if($(this).hasClass('pass-actual')) {
        if($(this).val() == '') {
          $('.pass-placeholder').show().val($(this).attr('placeholder'))
          $('.pass-actual').hide()
        }
      } else {
        if($(this).val() == '') {
          $(this).css('color', 'gray').val($(this).attr('placeholder'));
        }
      }
    });
  });
});

(function($) {
  $('.tracking-management form, .delivery-management form')
  .live('focus', function(e) {
    $.log('focus', this);
    $('a[rel=".' + $(this).parents('div').attr('class') +'"]').trigger('click');
  }).live('submit',function(e) {
    e.preventDefault();
    return false;
  });

  var liveSubmitFix = function(e, $form){
      $form.find('.show-load-on-submit').trigger('show-loading');
      $.log("liveSubmitFix");
      if ($form.is('.bound')) return;
      e.preventDefault();
      var ajax_options = {
          url: $form.attr('action'),
          type: $form.attr('method'),
          data: $form.serialize(),
          dataType: 'json',
          success: function(response) {
              $.log('form success', $form, response);
              $form
              .find('.show-load-on-submit')
              .trigger('hide-loading');
              $form.trigger('success', [response]);
              PP.showNotification($form, response);
          }
      }
      if ($form.is('[enctype="multipart/form-data"]')) {
          $form.ajaxSubmit($.extend(ajax_options, {iframe: true}));
      } else {
          $.ajax(ajax_options);
      }
      return false;
  }

  $('.add-individual form')
    .live('success', function(e, response) {
      $.log('add-individual success', this);
      $(this).find('input.to-clear').val('').filter(':first').focus();
      var list_name = $(this).attr('rel') || $(this).find('form').attr('rel')
      var contact_list = ContactList.instance(list_name);
      $.log('contact_list', list_name, contact_list);
      contact_list.updateTotals(response);
      contact_list.reload();
    });

  $('.add-multiple form')
    .live('success', function(e, response) {
      $.log('add-multiple success', this);
      if (response.unparsed_contacts) {
        $(this).find('textarea').val($.trim(response.unparsed_contacts.join("\n")));
      }
      var contact_list = ContactList.instance($(this).attr('rel'));
      $.log('contact_list', contact_list);
      contact_list.updateTotals(response);
      contact_list.reload();
    });

  $('input.upload')
    .live('click', function(e) {
      decision = confirm("Any email addresses in this spreadsheet that already exist in your Paperless Post Address Book and on any current or past mailing lists will be overwritten with the new information in this spreadsheet.");
      if (decision == false) {
        alert("OK, no action was taken");
        return false;
      }

      return true;
    });

  $('.add-spreadsheet form')
    .live('success', function(e, response) {
      $('.add-multiple form').trigger('success', [response]);
    });

  $('.send input.show-load-on-submit').live('click', function(e) {
    e.preventDefault();
    var total_recipients = 0;
    $('.send [name="selection[filters][]"]:checked').each(function() {
      var text;
      text = $(this).siblings('label').find('span.count').text();
      if (!text || text == '') {
        text = $('li[rel=' + $(this).val() +'] h6 span, li a.section[rel=' + $(this).val() +'] span').text();
      }
      if (text) { total_recipients += parseInt(text); }
    });
    var text = "You are about to send to " + total_recipients +" recipients. Click OK to continue."
    return PP.getConfirmation(text, function(){
      liveSubmitFix(e,$('.send form'));
    });
  });

  $('.add-spreadsheet input.show-load-on-submit, .add-multiple input.show-load-on-submit')
  .live('click',function(e) {
    e.preventDefault();
    liveSubmitFix(e,$(this).parents('form'));
    return true;
  });

  $('.reminder input.show-load-on-submit').live('click', function(e){
    e.preventDefault();
    saveFormAndUpdateSide(e, '.reminder');
  });

  $('.set-auto input.trackingformsubmit').live('click', function(e){
    e.preventDefault();
    saveFormAndUpdateSide(e, '.set-auto');
  });

  $('.add-individual input.show-load-on-submit').live('click', function(e){
    e.preventDefault();
    if($('#contact_email_address').val() == (null || "")){
      var message = "Please enter an email address.";
      var $notification = PP.getNotification($(this).parents('form'), "error");
      $notification.find('.message').or($notification).html(message);
      $notification.fadeIn(400).fadeOutSoon();
      $('.add-individual').find('.show-load-on-submit').trigger('hide-loading');
      return false;
    }else {
      liveSubmitFix(e,$(this).parents('form'));
      return true;
    }
  });

  $('.contact-name-form-toggle')
    .live('click', function(e) {
      e.preventDefault();
      var $toggle = $(this);
      var $form   = $toggle.parents('.contact-form');
      $toggle.parents('.contact-name-form').hide();
      $form.find($toggle.attr('rel')).show();
      $form
        .find('[name*="use_group_name"]')
        .attr('value', function() {
          var val = $(this).val();
          return (val == "true" ? "false" : "true");
        }).end()
        .find('[name="additional_guests_allowed"]')
        .attr('value', function() {
          var val = $(this).val();
          return val == "0" ? "1" : "0";
        });
    });

  var saveFormAndUpdateSide = function(e, identifier){
    liveSubmitFix(e,$(identifier+' form'));
    var $link = $('a[rel='+identifier+'], a[href='+identifier+']');
    var $other_link = $(identifier + '.-link a');
    if ($(identifier+'-toggle').is('.on')) {
       if(identifier == ".reminder"){
         $link.html("Automatic Reminder: ");
         $other_link.html("Automatic Reminder: ");
       }
       $link.append('<span class="on">On</span>');
       $other_link.append('<span class="on">On</span>');
     } else {
       if(identifier == ".reminder"){
          $link.html("Automatic Reminder: ");
          $other_link.html("Automatic Reminder: ");
        }
        $link.append('<span>Off</span>');
        $other_link.append('<span>Off</span>');
     }
    return true;
  }

})(jQuery);
jQuery.guard('#event_form.details', function($) {

  var detailsFormDirty = false; // Details form has changed?

  PP.setupForm('#event_form')
    .live('show-loading', function() {
      $(this).find('.loading').show();
    })
    .live('hide-loading', function() {
      $(this).find('.loading').hide();
    })
    .live('submit', function(e) {
      $.log('submit');
      e.preventDefault();
      var $form = $(this);

      if (detailsFormDirty) {
        var message = "Please note that updating your event details will over-write the custom reminder you saved previously.  To customize your reminder again please return to the Tracking Page.";

        if (!confirm(message)) {
          return;
        }
      }

      $('.invalid').removeClass("invalid");

      $form.ajaxSubmit({
        type: 'put',
        data: { "details_form_dirty": detailsFormDirty },
        dataType: 'json',
        success: function(json_response) {
          if (json_response.status == 'error') {
            PP.showNotification($form, json_response);
            PP.showNotification($('.notification-placeholder'), json_response);
            if(json_response.message.match("end time")){
              $('.event-end').addClass('invalid');
            }
          } else {
            $form.trigger('success');
          }
        }
      })
    })
    .live('rsvp-privacy-toggle', function(e) {;
      var val = $('input[name="event[event_options_list_attributes][public_guest_list]"]:radio:checked').val();
      var $details = $('#event_form_rsvp_privacy_details');
      if (val != 'true') {
        $details.hide();
      } else {
        $details.show();
        $('input.checkbox[name="event[event_options_list_attributes][show_attending_guests]"], input.checkbox[name="event[event_options_list_attributes][show_not_replied_guests]"]')
          .trigger('check');
      }
    })
    .live('reload-details', function(e) {
      var $event_form = $(this);
      var event_type = $('[name="event[event_type]"]').val();
      var $form = $event_form.find('.details_form');
      $.log('reload-details', event_type);
      if (!event_type || event_type == '') return;
      if ($event_form.data('changed') == true) {
        var confirmed = confirm("Are you sure you want to switch? You will need to re-enter any unsaved information.")
        if (!confirmed) return;
      }

      $event_form.trigger('show-loading');
      $.get(PP.eventPath('details', 'form'), {event_type: event_type}, function(form) {
        $event_form.trigger('hide-loading');
        $form.html(form);
        PP.customizeInputs($event_form);
        $event_form.trigger('validate');
        if(event_type == 'rsvp_event'){
            if($('#event_location_attributes_address1').blank() && $('#event_location_attributes_city').blank()){
                $.log("blank");
                $('.include-map').hide();
            }
        }
        $('#dirty_watcher').each(function() {
          $('input').bind("change", function () {
            detailsFormDirty = true;
          });
        });
      });
    })
    .live('is-valid', function() {
      $('.step-nav .step-next, input.preview').trigger('enable');
    })
    .live('is-invalid', function() {
      $('.step-nav .step-next, input.preview').trigger('disable');
    })
    .live('ticket-add', function() {
      var $index = $('#tickets_form .current-index');
      $.get(PP.eventPath('tickets', 'form'), {index: $index.val()}, function(form) {
        $('#tickets_form').append(form);
        $index.val(parseInt($index.val()) + 1);
      });;
    })
    .live('next', function(e) {
      $(this)
        .one('success', function() {
          window.location = $('.step-next').attr('href');
        })
        .trigger('submit');
    });

  $('input.preview')
    .live('click', function() {
      if ($(this).is('.disabled')) {
        $('#event_form').trigger('validate');
      } else {
        $.log('click');
        var $button = $(this);
        $('#event_form')
          .one('success', function() {
            $button.trigger('hide-loading');
            return PP.openPreviewForEvent();
          })
          .trigger('submit');
      }
    });

  $('input.radio[name="event[event_options_list_attributes][public_guest_list]"]').live('click', function() {
    $('#event_form').trigger('rsvp-privacy-toggle');
  });

  $('input.checkbox[name="event[time_all_day]"]')
    .live('check', function() {
      $('.event-time-field').each(function() { $(this).attr('disabled', 'disabled'); });
    })
    .live('uncheck', function() {
      $('.event-time-field').each(function() { $(this).removeAttr('disabled'); });
    });


  $('#event_form_rsvp_privacy_details input.checkbox').live('click', function() {
    setTimeout(function() {
      if ($('#event_form_rsvp_privacy_details input.checkbox.on').length == 0) {
        $('input.radio[name="event[event_options_list_attributes][public_guest_list]"]:first').click();
      }
    }, 20);
  });


  $('[name="event[event_type]"]').bind('change', function() {
    $('#event_form').trigger('reload-details');
  });

  if($('[name="event[subject]"]').val() == '') {
    $('[name="event[name]"]').live('keyup', function() {
      $('[name="event[subject]"]').val($(this).val());
    });

    $('[name="event[subject]"]').live('focus', function() {
      $('[name="event[name]"]').die('keyup');
    });
  }

  $('a.ticket-add').live('click', function(e) {
    e.preventDefault();
    $(this).parents('form').trigger('ticket-add');
  });

  $('a.ticket-delete').live('click', function(e) {
    e.preventDefault();
    var $form = $(this).parents('.ticket-new');
    var $_delete = $form.find('._delete');
    if ($_delete.length > 0) {
      $form.hide()
      $_delete.val('1'); // set _delete to 1
    } else {
      $form.remove();
    }
    $('#event_form').trigger('validate');
  });

  $('#event_form').each(function() {
    $(this).data('changed', false);
    $(this).trigger('reload-details')
  })

  $('#event_location_attributes_address1, #event_location_attributes_city').live('keyup',function(){
     if($(this).blank()){
         $('.show-map').trigger('uncheck');
     }else{
        if($('.include-map').is(":hidden")){
            $('.include-map').fadeIn(200);
        }
        updateMapLink();
     }
  });

  $('#event_location_attributes_state').live('change',function(){
     updateMapLink();
  });

  var updateMapLink = function(){
      $('.show-map').trigger('check');
      var maplink = $('.address1').attr("value")+"+"+$('.address2').attr("value")+"+"+$('#event_location_attributes_state').val();
      maplink = maplink.replace(/[ ]/, "+");
      $('.map-link').attr("href","http://maps.google.com?q="+maplink);
  }

  $('.add-end-time').live('click', function(){
    if($('.set-end-time').val() == 1){
      $('.end_time_fields').slideUp(200);
      $(this).html("Add end time for calendars");
      $('.set-end-time').val(0);
    } else {
      $('.end_time_fields').slideDown(200);
      $(this).html("Remove end time");
      $('.set-end-time').val(1);
    }
  });

});
jQuery.guard('#preview', function($, $preview) {

  $('#send-me-a-test').click(function() {
    var message = 'By clicking "OK" a free Preview will be sent to the email ' +
    'address that you used to sign up for Paperless Post. It may take a few ' +
    'moments to be delivered so please be patient. It will not be possible ' +
    'to respond through this card because it is just Preview';

    return PP.getConfirmation(message, function() {
      $.ajax({
        type: 'post',
        dataType: 'json',
        data: '_method=PUT',
        method: 'POST',
        url: $('#send-me-a-test').attr('destination'),
        success: function(response) {
          var message = response.message + '<br />';
          $('.notification').html(message)
          $('.notification').fadeIn(400).fadeOutSoon();
        }
      });
    });
  });

  if ($preview.is('.loading')) {
    PP.getEventImages(function(images) {
      window.location.reload();
    });
  }

});
jQuery(function($) {
  if ($('#tracking-list').length == 0) return;

  var contact_list = ContactList.instance('#tracking-list');

  $('.tracking-overview li')
  .bind('activate', function(e, trigger_changed, clear_sub_filter) {
    $(this).siblings('li').removeClass('on').end().addClass('on');
    var filter = $(this).attr('rel');
    contact_list.$el('filter_by_type').val(filter);
    contact_list.setCurrentFilterDescription($(this).find('h6').attr('rel'), $(this).attr('class'));
    if (clear_sub_filter) {
      $.log('clearing sub filter');
      $(this).parents('ul').find('li .section').removeClass('on');
      contact_list.$el('filter_by_sub_type').val('');
    }
    if (trigger_changed) {
      contact_list.$el('filter_by_type').trigger('change');
    }
  })
  .find('h6')
  .bind('click', function(e) {
    e.preventDefault();
    $(this).parents('li').trigger('activate', [true, true]);
  })
  .end()
  .find('a.section:not(.action)')
  .bind('activate', function() {
    $(this).parents('ul').find('li .section').removeClass('on');
    contact_list.$el('filter_by_sub_type').val($(this).attr('rel'));
    $(this).addClass('on')
  })
  .bind('click', function(e) {
    e.preventDefault();
    $(this).trigger('activate', [true, false]);
  });

  $('.tracking-management .send-preview-button').live('click', function() {
    var $link = $(this);
    $.ajax({
      url: $link.attr('rel'),
      type: 'get',
      dataType: 'json',
      success: function(response) {
        $link.trigger('hide-loading');
        PP.showNotification($link.parents('div:first'), response);
      }
    })
  });

  $.log('inputs', $('.tracking-management .reminder').find('.watched'));

  $('.tracking-management .reminder').find('.watched').live('change', function() {
    $('.reminder').find('form').data('changed', true);
    $.log("data changed");
  });

  $('.tracking-management .send-me-a-reminder').live('click', function(e){
    e.preventDefault();
    var $form = $('.reminder-form');
    $.ajax({
      url: $form.attr('action'),
      type: $form.attr('method'),
      data: $form.serialize(),
      dataType: 'json',
      success: function(response) {
        $.log('form success', $form, response);
        $form.trigger('success', [response]);
      }
    });

    $.ajax({
      type: 'post',
      dataType: 'json',
      data: '_method=PUT',
      method: 'POST',
      url: $('.send-me-a-reminder').attr("destination"),
      success: function(response) {
        e.preventDefault();
        var message = response.message + '<br />';
        $('.notification').hide();
        $('.notification:first').html(message);
        $('.notification:first').fadeIn(400).fadeOutSoon();
      }
    });
  });

  $('.tracking-management input.submits').live('toggle', function() {
    $(this).parents('form').trigger('submit');
    var $span = $('a[rel=".set-auto"], a[href=".set-auto"]').children('span');
    if ($span.is('.on')) {
      $span.removeClass('on').addClass('off').html('Off');
    } else {
      $span.removeClass('off').addClass('on').html('On');
    }
  });

  if(!$('.reminder-toggle').hasClass("on")){
    $('.reminder').find('.text, textarea, select').attr("disabled", "disabled")
    .css('color', '#222');
  }

  $('.tracking-management input.reminder-toggle')
  .live('click', function() {
    var $inputs = $(this).parents('form').find('.text, textarea, select');
    if ($(this).is('.on')) {
      $inputs.removeAttr('disabled');
      $inputs.css('color', 'black');
    } else {
      $inputs.attr('disabled', 'disabled');
      $inputs.css('color', '#222');
    }

    var $span = $('a[rel=".reminder"], a[href=".reminder"]').children('span');
    if ($span.is('.on')) {
      $span.removeClass('on').addClass('off').html('Off');
    } else {
      $span.removeClass('off').addClass('on').html('On');
    }
  })
  .triggerHandler('toggle-form');


  var filter = contact_list.$el('filter_by_type').val();
  var sub_filter = contact_list.$el('filter_by_sub_type').val();
  if (sub_filter) {
    $('.tracking-overview li a.section[rel="' + sub_filter +'"]').trigger('activate');
  } else if (filter) {
    $('.tracking-overview li[rel="' + filter +'"]').triggerHandler('activate');
  }

  setTimeout(function() {
    $.post(PP.eventPath('tracking', 'view'), "_method=POST");
    }, 2000);

});
jQuery.guard('#delivery-list', function($) {

  var delivery_contact_list = ContactList.instance('#delivery-list'),
      costs = JSON.parse($('.buy').attr('data')),
      $send_button = $('.send-invitations img');

  delivery_contact_list.send_to_selected = true;
  delivery_contact_list.bindSendValidationToButton($send_button, costs);
  delivery_contact_list.bindAddressBookToList('#address_book_delivery-list');

});
jQuery(function($) {

  $('.stationery-steps li').each(function() {
    var $li = $(this),
        $a  = $li.children('a');

    if ($a.attr('href') === '' || $a.attr('href') === '#') {
      $a.click(function(e) { e.preventDefault(); return false; });
      $li.addClass('disabled');
      Cufon.refresh();
    }
  });

  var $stationery_form = $('#stationery.stationery-form');
  $stationery_form.each(function() {
    var stationery_contact_list = ContactList.instance('#stationery_details-list'),
        costs = JSON.parse($('.buy').attr('data')),
        $send_button = $('.send-invitations img'),
        $send_test_button = $('#send-me-a-test img'),
        $preview_button = $('input.preview');

    var saveFormWithCallback = function(form, callback) {
      var $form = $(form), wrapped_callback;
      wrapped_callback = function(e) {
        $form.data('changed', false);
        if (typeof callback != 'undefined') callback.apply(form, [e]);
      };
      if ($form.data('changed')) {
        $.log('Data changed, posting');
        $form
          .one('success', wrapped_callback)
          .trigger('submit');
      } else {
        $.log('Data unchanged, just running callback');
        wrapped_callback.apply($form);
      }
    };

    stationery_contact_list.send_to_selected = true;
    stationery_contact_list.bindSendValidationToButton($send_button, costs);
    stationery_contact_list.bind('list-loaded', function(e) {
      if (stationery_contact_list.total_guests_count > 10) {
        $('.contact-list-box').hide();
        $('.quick-add-bottom').show();
      } else {
        $('.contact-list-box').show();
        $('.quick-add-bottom').hide();
      }
    });

    stationery_contact_list.bind('list-modified', function(e) {
      if (stationery_contact_list.total_guests_count >= 10) {
        $('.contacts-limit-reached .reached').show();
        $('.add-contacts').hide();
      } else {
        $('.contacts-limit-reached .reached').hide();
        $('.add-contacts').show();
      }
    });

    PP.setupForm($stationery_form)
    .bind('submit', function() {
      var $form = $(this);
      var data = $form.find(':input.to-save').serialize()
      data += "&_method=PUT";
      $.ajax({
        type: 'post',
        dataType: 'js',
        data: data,
        method: 'POST',
        url: $form.attr('rel'),
        success: function() {
          $form.trigger('success');
        }
      });
    })
    .bind('is-valid', function() {
      $.log('is-valid', this);
      $preview_button.trigger('enable');
      $send_button.trigger('enable');
      $send_test_button.attr('src','/images/buttons/send-me-a-test-active.png');
      $send_test_button.parent().click(function(){
          saveFormWithCallback($stationery_form, function() {
            $.ajax({
              type: 'post',
              dataType: 'json',
              data: '_method=PUT',
              method: 'POST',
              url: $send_test_button.parent().find('input[type=hidden]').val(),
              success: function(response) {
                var message = response.message + '<br />';
                $('.notification.top').html(message)
                $('.notification.top').fadeIn(400).fadeOutSoon();
              }
            });
          })
      });
      stationery_contact_list.validatePurchasesBeforeSend($send_button);
    })
    .bind('is-invalid', function() {
      $.log('is-invalid', this);
      $preview_button.trigger('disable');
      $send_button.trigger('disable');
      $send_test_button.attr('src','/images/buttons/send-me-a-test-loading.png');
      $send_test_button.parent().click(function(){return false;});
    })
    .bind('disabled-click', function() {
      $(this).trigger('show-invalid');
    })
    .bind('show-invalid', function() {
      if ($('.buy').is(':visible')) {
        $('.buy').addClass('highlight');
      }
      PP.showNotification($('.send-select'), {
        status: 'error',
        errors: ['Please complete the highlighted fields above']
      });
    }).trigger('validate');


    $preview_button.click(function() {
      saveFormWithCallback($stationery_form, function() {
        PP.openPreviewForEvent();
        setTimeout(function() {
          $preview_button.trigger('hide-loading');
        }, 100);
      })
    });

    $('.quick-add-input').focus(function() {
      saveFormWithCallback($stationery_form, function() {
        if (!$stationery_form.validForm()) {
          $stationery_form.trigger('show-invalid');
        }
      });
    });

    if ($('.stationery-image').children('.loader').length > 0) {
      PP.getEventImages(function(images) {
        var $img = $('<img />').attr('src', images['preview']);
        $('.stationery-image')
          .children('.loader').remove().end()
          .append($img);
      });
    }

  });

  $('#stationery.stationery-design').each(function() {
    Sammy.log('stationery-design');

    var create_app = $.sammy('.stationery-design', function() {

      this.helpers({
        loadTab: function(name, num) {
          this.log('loadTab', name, num)
          PP.sendToFlash('#flashcontent', 'writeCallback', ['loadTab',name]);
          this.enableTabs(num);
        },
        enableTabs: function(num) {
          var $tab = $('.stationery-steps')
            .attr('class', 'event-steps stationery-steps')
            .addClass('steps-' + num)
            .find('li').removeClass('on')
              .filter('.step-' + num).addClass('on');

          Cufon.refresh();
          return $tab;
        }
      });

      this.get('#/design', function() {
        this.loadTab('design', 1);
      });

      this.get('#/write', function() {
        this.loadTab('write', 2);
      });

      this.bind('flash-event.loadTab', function(e, data) {
        this.log('flash-event.loadTab', data);
        this.redirect('#', data.args[0]);
      });

      this.bind('flash-event.writeLoaded', function(e, data) {
        this.log('flash-event.writeLoaded', data);
        $('#flashcontent').addClass('flash-loaded');
      });

      this.bind('flash-event.enableWrite', function(e, data) {
        this.log('flash-event.enableWrite', data);
        if (data.args[0] === true) {
          $('.stationery-steps li.step-2').removeClass('disabled')
            .find('a').attr('href', '#/write');
        } else {
          $('.stationery-steps li.step-2').addClass('disabled')
            .find('a').attr('href', '');
        }
        Cufon.refresh();
      });

    }).run('#/design');

    $('a').live('click', function(e) {
      var href = $(this).attr('href');
      e.preventDefault();
      if (href != '') {
        PP.sendToFlash('#flashcontent', 'writeCallback', ['exitingWrite', $(this).attr('href')]);
      }
    });

    function writeCallback() {
      var args = $.makeArray(arguments),
          event_name = args.shift();

      $.sammy('.stationery-design').trigger('flash-event.' + event_name,  {args: args});
    };

    window.writeCallback = writeCallback;

  });

  $('#stationery.stationery-tracking').each(function() {
    $('input.preview').click(function() {
      var $input = $(this);
      PP.openPreviewForEvent();
      setTimeout(function() {
        $input.trigger('hide-loading');
      }, 100);
    }).trigger('enable');

  });

});

jQuery(function($) {

  $('#merge').each(function() {

    function showUserFields() {
      if ($('input[name="merge"]:checked').val() === "true") {
        $('#user_fields').show();
      } else {
        $('#user_fields').hide();
      }
    };

    $('input[name="merge"]').click(function() {
      setTimeout(showUserFields, 200);
    });

    showUserFields();

  });


});


;(function($) {

  IC = window.IC || {};

  var staging_json              = null;
  var new_ordinals              = new Array();
  var match_ordinals            = new Array();
  var current_contact_import_id = null;

  $.extend(IC, {

    startImport: function(e, $form) {
      var $current = $form.find('.current');

      e.preventDefault();

      var username, name_field_split;

      var provider = $('.contact_import_provider').val();
      var name_field = $.trim($current.find('input.contact_import_username').val());
      var password_field = $.trim($current.find('input.contact_import_password').val());

      if (!name_field || name_field.length == 0) {
        IC.showMessage($form, "Please enter a username");
        return;
      }else if (!password_field || password_field.length == 0) {
        IC.showMessage($form, "Please enter a password");
        return;
      }else if (provider == undefined) {
        IC.showMessage($form, "Please select an email provider");
        return;
      }

      name_field_split = name_field.split('@');
      $('.contact_import_username').val(name_field);
      $('.contact_import_password').val(password_field);
      $('.file-import').val("false");

      if(name_field_split.length == 2){
        username = name_field_split[0];

        if (!username || username.length == 0) {
          IC.showMessage($form, "Please enter a username");
          return;
        }else if (!IC.isSupportedProvider(provider)) {
          IC.showMessage($form, "We do not yet support that email provider");
          return;
        }

        if(provider == "live"){
          provider = name_field_split[1];
        }else if(provider != "plaxo"){
          provider = provider + ".com";
        }

        $('.contact_import_provider').val(provider);
      }

      $.ajax({
        url: $form.attr('action'),
        type: $form.attr('method'),
        dataType: 'json',
        data: $form.serialize()+"&event_id="+$('#event_id_div').attr('the_event_id'),

        beforeSend: function() {
          IC.resetProgressbar();
          $('.import_ui').hide();
          $('.progress_ui').show();
        },

        success: function(json_response) {
          if (json_response.status == 'error') {
            $('.progress_ui').hide();
            $('.import_ui').show();

            PP.showNotification($form, json_response);
          } else {
            IC.resetProgressbar();
            IC.startGatherPoll(json_response, provider);
          }
        }
      });
    },

    startCommitPoll: function(contact_import_id, commit_poll_url) {

      $('#commit_status').show();
      $('#commit_status').html("Preparing to add " + (new_ordinals.length + match_ordinals.length) + " contacts...");

      IC.updateProgressbar(5);

      var commitInterval = setInterval(function() {
        $.ajax({
          dataType: 'json',
          type:     'POST',
          data:     { "contact_import_id" : contact_import_id },
          url:      commit_poll_url,
          success: function(json_response){
            if (json_response.commit_poll_status == "incomplete") {
              if (json_response.job_status != null) {
                $('#commit_status').html(json_response.job_status);

                if (json_response.job_status.search(/Processing/) == 0) {
                  if (json_response.job_status.indexOf('(') != -1) {
                    IC.addProgressPercentage(json_response.job_status, 10, 20);
                  } else {
                    IC.updateProgressbar(10);
                  }
                } else if (json_response.job_status.search(/Adding/) == 0) {
                  if (json_response.job_status.indexOf('(') != -1) {
                    IC.addProgressPercentage(json_response.job_status, 50, 50);
                  } else {
                    IC.updateProgressbar(50);
                  }
                }
              }
            } else {
              clearInterval(commitInterval);

              if (json_response.status != "error") {
                $('#commit-progress').hide();

                $('#complete_message').html("Your " + json_response.total_added + " contacts were successfully imported!");

                $('#committed').show();
                if (json_response.event_url) {
                  $('#event_link').attr('href', json_response.event_url);
                  if (json_response.event_name && json_response.event_name.length > 0) {
                    $('#event_link').html("Go back to \'" + json_response.event_name + "\'.")
                  }
                  $('#event_link').show();
                } else {
                  $('#ab_link').attr('href', json_response.address_book_url);
                  $('#ab_link').show();
                }
                Cufon.refresh();
              }
            }
          }
        })
      }, 1750);
    },

    addProgressPercentage: function(status, base, range) {
      var num_slice, num_pieces, processed, total, percentage, new_percentage;

      num_slice   = status.slice(status.indexOf('(') + 1, status.indexOf(')'));
      num_pieces  = num_slice.split(' ');

      if (num_pieces.length != 3){
        return;
      }

      processed = parseInt(num_pieces[0]);
      total = parseInt(num_pieces[2]);

      if (total == 0){
        return;
      }

      percentage = processed / total;

      new_percentage = Math.ceil(range * percentage);

      IC.updateProgressbar(base + new_percentage);
    },

    updateProgressbar: function(percentage) {
      $('#progressbar').progressbar('option', 'value', percentage);
      $('.progress-text').html(percentage + '%');
    },

    resetProgressbar: function() {
      $('#progressbar').progressbar({value: 0});
      $('.progress-text').html('0%');
    },

    startGatherPoll: function(response, provider) {

      current_contact_import_id = response.contact_import_id;

      $('#gather_status').show();

      if(provider == "client"){
        $('#gather_status').html("Preparing to import contacts...");
      } else {
        $('#gather_status').html("Preparing to contact " + provider.substr(0,1).toUpperCase() + provider.slice(1) + "...");
      }

      IC.updateProgressbar(5);

      var gatherInterval = setInterval(function() {
        $.ajax({
          dataType: 'json',
          type:     'POST',
          data:     { "contact_import_id" : response.contact_import_id },
          url:      $('#gather_poll_url_span').attr('gather_poll_url'),
          success: function(json_response) {
            if (json_response.gather_poll_status == "incomplete") {
              if (json_response.job_status != null) {
                $('#gather_status').html(json_response.job_status);

                if (json_response.job_status.search(/Contacting/) == 0) {
                  IC.updateProgressbar(10);
                } else if (json_response.job_status.search(/Retrieving/) == 0) {
                  IC.updateProgressbar(25);
                } else if (json_response.job_status.search(/Processing/) == 0) {
                  if (json_response.job_status.indexOf('(') != -1) {
                    IC.addProgressPercentage(json_response.job_status, 70, 30);
                  } else {
                    IC.updateProgressbar(50);
                  }
                }
              }
            } else {
              clearInterval(gatherInterval);

              if (json_response.status == "error") {
                PP.showNotification($('#import_types'), json_response);
                $('#gather_status').hide();
                $('.progress_ui').hide();
                $('.import_ui').show();
                $('.import-type li.on').click();
              } else {
                window.location.href = json_response.url;
              }
            }
          }
        })
      }, 1750);
    },

    handleCheckAll: function(itemSelector, self) {
      var $checkbox = $(self)
      var fullSelector = itemSelector + ' li input[type=checkbox]';

      if ($checkbox.attr('checked') == true) {
        $(fullSelector).attr('checked', 'true');
      }
      else {
        $(fullSelector).attr('checked', '');
      }
    },

    isSupportedProvider: function(provider) {
      var supported_providers = {"yahoo": true, "gmail": true, "live": true, "aol": true, "plaxo": true};

      if (supported_providers[provider]) {
        return true;
      }
      else {
        return false;
      }
    },

    showMessage: function(location, message) {
      PP.showNotification(location, {"status": "error", "errors": [message]});
    }

  });

  $('.import-type li').live('click', function() {
    $('.import-type li').removeClass('on');
    $(this).addClass('on');

    $('.import_ui').find('.radio.on').removeClass('on');

    $(this).find('input:radio').attr('checked', 'checked');
    $(this).find('.radio').addClass('on');

    $('.import-form > *').hide().removeClass("current");
    provider = $(this).attr('class').replace(" on", "");
    $('.import-form').find('.'+provider).show().addClass("current");
    $('.contact_import_provider').val(provider);
  });

  $('#import_types').find('.trackingformsubmit').live('click',function(e){
    e.preventDefault();
    IC.startImport(e, $('#import_types'));
  });

  $('#import_types').find('.fileuploadsubmit').live('click',function(e){
    $form = $('#import_types');
    $form.find('.show-load-on-submit').trigger('show-loading');
    e.preventDefault();
    $('.contact_import_provider').val($('.file-provider').val());
    $('.file-import').val("file");
    if($('.contact-file').val()){
      var ajax_options = {
        dataType: 'json',
        iframe : true,
        data: {"event_id" : $('#event_id_div').attr('the_event_id')},
        success: function(json_response) {
          if (json_response.status == 'error') {
            PP.showNotification($('#import_types'), json_response);
          } else {
            $.log('form success', $form, json_response);
            $form.find('.show-load-on-submit').trigger('hide-loading');
            $('.import_ui').hide();
            $('.progress_ui').show();
            IC.resetProgressbar();
            IC.startGatherPoll(json_response, provider);
          }
        }
      }

      $form.ajaxSubmit(ajax_options);
      return false;
    }else{
      IC.showMessage($('#import_types'),"Please Upload a File");
    }
  });

  $('.contact_import_username, .contact_import_password').live('keypress', function(e){
    if(e.keyCode == 13){
      e.preventDefault();
      $(this).parent().parent().find('.trackingformsubmit').trigger('click');
    }
  });

  $('.matching_checkbox').live('click', function () {
    IC.handleCheckAll('#match_list', this)
  });

  $('.new_checkbox').live('click', function () {
    IC.handleCheckAll('#new_list', this)
  });

  $('.import-location input').live('click', function(e){
    $('.import-location').find(".selected").removeClass("selected");
    $(this).addClass("selected");
    $('.import-merge .selected').addClass('on');
  });

  $('#staging-merge input').live('click', function() {
    $('.import-merge').find(".selected").removeClass("selected");
    $(this).addClass("selected");
    $('.import-location .selected').addClass('on');

    $('#match_list').show();
    return false;
  });

  $('#staging-unmerge input').live('click', function() {
    $('.import-merge').find(".selected").removeClass("selected");
    $(this).addClass("selected");
    $('.import-location .selected').addClass('on');

    $('#match_list').hide();
    return false;
  });

  $('#commit_staging').live('submit', function(e){
    return false;
  });

  $('.commit-submit').live('click', function(e){
    var $form = $('#commit_staging'),
    gathered_match,
    gathered_new;

    e.preventDefault();

    var staged_new      = $('#new_list li.family input[type=checkbox]');
    var staged_match    = $('#match_list li.family input[type=checkbox]');

    for (var i = 0; i < staged_new.length; i++){
      if (staged_new[i].checked){
        new_ordinals.push(i);
      }
    }

    for (var i = 0; i < staged_match.length; i++){
      if (staged_match[i].checked){
        match_ordinals.push(i);
      }
    }

    if ((match_ordinals.length + new_ordinals.length) == 0) {
      PP.showNotification($form, {"status": "error", "errors": ["Please select at least one contact to import."]});
      return;
    }

    $('.staging_ui').hide();
    $('#commit-progress').show();

    $.ajax({
      dataType: 'json',
      type:     'POST',
      data:     { "commit_to_guest_list" : $('.import-location').find('input[type=button]').first().hasClass('on'),
                  "new_ordinals"         : new_ordinals,
                  "match_ordinals"       : match_ordinals,
                  "contact_import_id"    : current_contact_import_id
                },
      url:      $('#commit_staging').attr('action'),

      beforeSend: function() {
        $('.staging_ui').hide();
        $('#commit-progress').show();
      },

      success: function(json_response) {
        IC.resetProgressbar();
        IC.startCommitPoll(json_response.contact_import_id, json_response.url);
      }
    });
  });

})(jQuery);

;(function($) {

  $('.api_exception_test').live('click', function(e) {

    $.ajax({
      dataType: 'json',
      type:     'POST',
      data:     {
                  'client': $('.api_test_client').val(),
                  'title': $('.api_test_title').val(),
                  'message': $('.api_test_message').val()
                },
      url:      '/api/v1/exceptions',
      beforeSend: function()
      {
        $('.sending').append("<br/>Sending Exception: <b>client:</b> " + $('.api_test_client').val() + " <b>title:</b> " + $('.api_test_title').val() + " <b>message:</b> " + $('.api_test_message').val());
      },
      success: function(json_response)
      {
        $('.response').append('<br/>Response: ' + json_response.status)
      }
    });
  });

})(jQuery);

CR_KEYCODE = 13;

$(document).ready(function() {
  $('.dimmed').click(function() {
    $(this).fadeOut();
    $('.modal').fadeOut();
  });

  $('.modal .close').click(function() {
    $('.dimmed').fadeOut();
    $('.modal').fadeOut();

    return false;
  });
});
