/* JRails */
(function(jQuery){jQuery.extend({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;}});jQuery.fn.extend({delayedObserver:function(delay,callback){var el=jQuery(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'){jQuery(':input',el).each(function(){var field=jQuery(this);field.bind(jQuery.fieldEvent(field,delay),function(){observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.obj.oldVal)return;else window.delayedObserverCallback(stackPos);});});}else{el.bind(jQuery.fieldEvent(el,delay),function(){observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.obj.oldVal)return;else window.delayedObserverCallback(stackPos);});};},formVal:function(){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(jQuery){jQuery.fn.extend({visualEffect:function(o){return this.effect(o);},Appear:function(speed,callback){return this.fadeIn(speed,callback);},BlindDown:function(speed,callback){this.show({method:'blind',direction:'vertical'},speed,callback);return this;},BlindUp:function(speed,callback){this.hide({method:'blind',direction:'vertical'},speed,callback);return this;},BlindRight:function(speed,callback){this.show({method:'blind',direction:'horizontal'},speed,callback);return this;},BlindLeft:function(speed,callback){this.hide({method:'blind',direction:'horizontal'},speed,callback);return this;},DropOut:function(speed,callback){this.hide({method:'drop',direction:'down'},speed,callback);return this;},DropIn:function(speed,callback){this.show({method:'drop',direction:'up'},speed,callback);return this;},Fade:function(speed,callback){return this.fadeOut(speed,callback);},Fold:function(speed,callback){this.hide({method:'fold'},speed,callback);return this;},FoldOut:function(speed,callback){this.show({method:'fold'},speed,callback);return this;},Grow:function(speed,callback){this.show({method:'scale'},speed,callback);return this;},Highlight:function(speed,callback){this.show({method:'highlight'},speed,callback);return this;},Puff:function(speed,callback){this.hide({method:'puff'},speed,callback);return this;},Pulsate:function(speed,callback){this.show({method:'pulsate'},speed,callback);return this;},Shake:function(speed,callback){this.show({method:'shake'},speed,callback);return this;},Shrink:function(speed,callback){this.hide({method:'scale'},speed,callback);return this;},Squish:function(speed,callback){this.hide({method:'scale',origin:['top','left']},speed,callback);return this;},SlideUp:function(speed,callback){this.hide({method:'slide',direction:'up'},speed,callback);return this;},SlideDown:function(speed,callback){this.show({method:'slide',direction:'up'},speed,callback);return this;},SwitchOff:function(speed,callback){this.hide({method:'clip'},speed,callback);return this;},SwitchOn:function(speed,callback){this.show({method:'clip'},speed,callback);return this;}});})(jQuery);(function(jQuery){jQuery.fn.extend({pause:function(milli,type){milli=milli||1000;type=type||"fx";return this.queue(type,function(){var self=this;setTimeout(function(){jQuery(self).dequeue();},milli);});},clearQueue:function(type){return this.each(function(){type=type||"fx";if(this.queue&&this.queue[type]){this.queue[type].length=0;}});},unpause:jQuery.fn.clearQueue});})(jQuery);


/**
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @author    Brian Cherne <brian@cherne.net>
*/
(function(jQuery){jQuery.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=jQuery.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){jQuery(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;jQuery(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{jQuery(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);



/* http://keith-wood.name/countdown.htmljQuery
   Countdown for jQuery v1.4.2.jQuery
   Written by Keith Wood (kbwood@virginbroadband.com.au) January 2008.jQuery
   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and jQuery
   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. jQuery
   Please attribute the author if you use it. */

/* Display a countdown timer.
   Attach it with options like:
   $('div selector').countdown(
       {until: new Date(2009, 1 - 1, 1, 0, 0, 0), onExpiry: happyNewYear}); */

(function($) { // Hide scope, no $ conflict

/* Countdown manager. */
function Countdown() {
	this.regional = []; // Available regional settings, indexed by language code
	this.regional[''] = { // Default regional settings
		// The display texts for the counters
		labels: ['Years', 'Months', 'Weeks', 'Days', 'Hours', 'Minutes', 'Seconds'],
		// The display texts for the counters if only one
		labels1: ['Year', 'Month', 'Week', 'Day', 'Hour', 'Minute', 'Second'],
		compactLabels: ['y', 'm', 'w', 'd'], // The compact texts for the counters
		timeSeparator: ':', // Separator for time periods
		isRTL: false // True for right-to-left languages, false for left-to-right
	};
	this._defaults = {
		format: 'dHMS', // Format for display - upper case for always, lower case only if non-zero,
			// 'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds
		layout: '', // Build your own layout for the countdown
		compact: false, // True to display in a compact format, false for an expanded one
		description: '', // The description displayed for the countdown
		expiryUrl: null, // A URL to load upon expiry, replacing the current page
		alwaysExpire: false, // True to trigger onExpiry even if never counted down
		onExpiry: null, // Callback when the countdown expires -
			// receives no parameters and 'this' is the containing division
		onTick: null, // Callback when the countdown is updated -
			// receives int[7] being the breakdown by period (based on format)
			// and 'this' is the containing division
		serverTime: null // The current time on the server, to calculate an offset for other time zones
	};
	$.extend(this._defaults, this.regional['']);
}

var PROP_NAME = 'countdown';

var Y = 0; // Years
var O = 1; // Months
var W = 2; // Weeks
var D = 3; // Days
var H = 4; // Hours
var M = 5; // Minutes
var S = 6; // Seconds

$.extend(Countdown.prototype, {
	/* Class name added to elements to indicate already configured with countdown. */
	markerClassName: 'hasCountdown',
	
	/* Override the default settings for all instances of the countdown widget.
	   @param  options  object - the new settings to use as defaults */
	setDefaults: function(options) {
		this._resetExtraLabels(this._defaults, options);
		extendRemove(this._defaults, options || {});
	},

	/* Attach the countdown widget to a div.
	   @param  target   element - the containing division
	   @param  options  object - the initial settings for the countdown */
	_attachCountdown: function(target, options) {
		target = $(target);
		if (target.is('.' + this.markerClassName)) {
			return;
		}
		target.addClass(this.markerClassName);
		if (!target[0].id) {
			target[0].id = 'cdn' + new Date().getTime();
		}
		var inst = {};
		inst.options = $.extend({}, options);
		inst._periods = [0, 0, 0, 0, 0, 0, 0];
		this._adjustSettings(inst);
		$.data(target[0], PROP_NAME, inst);
		this._updateCountdown(target, inst);
	},

	/* Redisplay the countdown with an updated display.
	   @param  id    element or string - the containing division or its ID
	   @param  inst  object - the current settings for this instance */
	_updateCountdown: function(id, inst) {
		var target = $(id);
		inst = inst || $.data(target[0], PROP_NAME);
		if (!inst) {
			return;
		}
		target.html(this._generateHTML(inst));
		target[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 'Class']('countdown_rtl');
		var onTick = this._get(inst, 'onTick');
		if (onTick) {
			onTick.apply(target[0], [inst._hold != 'lap' ? inst._periods :
				this._calculatePeriods(inst, inst._show, new Date())]);
		}
		var expired = inst._hold != 'pause' &&
			(inst._since ? inst._now.getTime() <= inst._since.getTime() :
			inst._now.getTime() >= inst._until.getTime());
		if (expired) {
			if (inst._timer || this._get(inst, 'alwaysExpire')) {
				var onExpiry = this._get(inst, 'onExpiry');
				if (onExpiry) {
					onExpiry.apply(target[0], []);
				}
				var expiryUrl = this._get(inst, 'expiryUrl');
				if (expiryUrl) {
					window.location = expiryUrl;
				}
			}
			inst._timer = null;
		}
		else if (inst._hold == 'pause') {
			inst._time = null;
		}
		else {
			var format = this._get(inst, 'format');
			inst._timer = setTimeout('$.countdown._updateCountdown("#' + target[0].id + '")',
				(format.match('s|S') ? 1 : (format.match('m|M') ? 30 : 600)) * 980);  // just under the full time
		}
		$.data(target[0], PROP_NAME, inst);
	},

	/* Reconfigure the settings for a countdown div.
	   @param  target   element - the containing division
	   @param  options  object - the new settings for the countdown */
	_changeCountdown: function(target, options) {
		var inst = $.data(target, PROP_NAME);
		if (inst) {
			this._resetExtraLabels(inst.options, options);
			extendRemove(inst.options, options || {});
			this._adjustSettings(inst);
			$.data(target, PROP_NAME, inst);
			this._updateCountdown(target, inst);
		}
	},

	/* Reset any extra labelsn and compactLabelsn entries if changing labels.
	   @param  base     (object) the options to be updated
	   @param  options  (object) the new option values */
	_resetExtraLabels: function(base, options) {
		var changingLabels = false;
		for (var n in options) {
			if (n.match(/[Ll]abels/)) {
				changingLabels = true;
				break;
			}
		}
		if (changingLabels) {
			for (var n in base) { // Remove custom numbered labels
				if (n.match(/[Ll]abels[0-9]/)) {
					base[n] = null;
				}
			}
		}
	},

	/* Remove the countdown widget from a div.
	   @param  target  element - the containing division */
	_destroyCountdown: function(target) {
		target = $(target);
		if (!target.is('.' + this.markerClassName)) {
			return;
		}
		target.removeClass(this.markerClassName).empty();
		var inst = $.data(target[0], PROP_NAME);
		if (inst._timer) {
			clearTimeout(inst._timer);
		}
		$.removeData(target[0], PROP_NAME);
	},

	/* Pause a countdown widget at the current time.
	   Stop it running but remember and display the current time.
	   @param  target  element - the containing division */
	_pauseCountdown: function(target) {
		this._hold(target, 'pause');
	},

	/* Pause a countdown widget at the current time.
	   Stop the display but keep the countdown running.
	   @param  target  element - the containing division */
	_lapCountdown: function(target) {
		this._hold(target, 'lap');
	},

	/* Resume a paused countdown widget.
	   @param  target  element - the containing division */
	_resumeCountdown: function(target) {
		this._hold(target, null);
	},

	/* Pause or resume a countdown widget.
	   @param  target  element - the containing division
	   @param  hold    string - the new hold setting */
	_hold: function(target, hold) {
		var inst = $.data(target, PROP_NAME);
		if (inst) {
			if (inst._hold == 'pause' && !hold) {
				inst._periods = inst._savePeriods;
				var sign = (inst._since ? '-' : '+');
				inst[inst._since ? '_since' : '_until'] =
					this._determineTime(sign + inst._periods[0] + 'Y' +
						sign + inst._periods[1] + 'O' + sign + inst._periods[2] + 'W' +
						sign + inst._periods[3] + 'D' + sign + inst._periods[4] + 'H' + 
						sign + inst._periods[5] + 'M' + sign + inst._periods[6] + 'S');
			}
			inst._hold = hold;
			inst._savePeriods = (hold == 'pause' ? inst._periods : null);
			$.data(target, PROP_NAME, inst);
			this._updateCountdown(target, inst);
		}
	},

	/* Return the current time periods.
	   @param  target  element - the containing division
	   @return  number[7] - the current periods for the countdown */
	_getTimesCountdown: function(target) {
		var inst = $.data(target, PROP_NAME);
		return (!inst ? null : (!inst._hold ? inst._periods :
			this._calculatePeriods(inst, inst._show, new Date())));
	},

	/* Get a setting value, defaulting if necessary.
	   @param  inst  object - the current settings for this instance
	   @param  name  string - the name of the required setting
	   @return  any - the setting's value or a default if not overridden */
	_get: function(inst, name) {
		return (inst.options[name] != null ?
			inst.options[name] : $.countdown._defaults[name]);
	},
	
	/* Calculate interal settings for an instance.
	   @param  inst  object - the current settings for this instance */
	_adjustSettings: function(inst) {
		var now = new Date();
		var serverTime = this._get(inst, 'serverTime');
		inst._offset = (serverTime ? serverTime.getTime() - now.getTime() : 0);
		inst._since = this._get(inst, 'since');
		if (inst._since) {
			inst._since = this._determineTime(inst._since, null);
		}
		inst._until = this._determineTime(this._get(inst, 'until'), now);
		inst._show = this._determineShow(inst);
	},

	/* A time may be specified as an exact value or a relative one.
	   @param  setting      string or number or Date - the date/time value
	           as a relative or absolute value
	   @param  defaultTime  Date - the date/time to use if no other is supplied
	   @return  Date - the corresponding date/time */
	_determineTime: function(setting, defaultTime) {
		var offsetNumeric = function(offset) { // e.g. +300, -2
			var time = new Date();
			time.setTime(time.getTime() + offset * 1000);
			return time;
		};
		var getDaysInMonth = function(year, month) {
			return 32 - new Date(year, month, 32).getDate();
		};
		var offsetString = function(offset) { // e.g. '+2d', '-4w', '+3h +30m'
			var time = new Date();
			var year = time.getFullYear();
			var month = time.getMonth();
			var day = time.getDate();
			var hour = time.getHours();
			var minute = time.getMinutes();
			var second = time.getSeconds();
			var pattern = /([+-]?[0-9]+)\s*(s|S|m|M|h|H|d|D|w|W|o|O|y|Y)?/g;
			var matches = pattern.exec(offset);
			while (matches) {
				switch (matches[2] || 's') {
					case 's' : case 'S' :
						second += parseInt(matches[1]); break;
					case 'm' : case 'M' :
						minute += parseInt(matches[1]); break;
					case 'h' : case 'H' :
						hour += parseInt(matches[1]); break;
					case 'd' : case 'D' :
						day += parseInt(matches[1]); break;
					case 'w' : case 'W' :
						day += parseInt(matches[1]) * 7; break;
					case 'o' : case 'O' :
						month += parseInt(matches[1]); 
						day = Math.min(day, getDaysInMonth(year, month));
						break;
					case 'y': case 'Y' :
						year += parseInt(matches[1]);
						day = Math.min(day, getDaysInMonth(year, month));
						break;
				}
				matches = pattern.exec(offset);
			}
			time = new Date(year, month, day, hour, minute, second, 0);
			return time;
		};
		var time = (setting == null ? defaultTime :
			(typeof setting == 'string' ? offsetString(setting) :
			(typeof setting == 'number' ? offsetNumeric(setting) : setting)));
		if (time) time.setMilliseconds(0);
		return time;
	},

	/* Generate the HTML to display the countdown widget.
	   @param  inst  object - the current settings for this instance
	   @return  string - the new HTML for the countdown display */
	_generateHTML: function(inst) {
		// Determine what to show
		inst._periods = periods = (inst._hold ? inst._periods :
			this._calculatePeriods(inst, inst._show, new Date()));
		// Show all 'asNeeded' after first non-zero value
		var shownNonZero = false;
		var showCount = 0;
		for (var period = 0; period < inst._show.length; period++) {
			shownNonZero |= (inst._show[period] == '?' && periods[period] > 0);
			inst._show[period] = (inst._show[period] == '?' && !shownNonZero ? null : inst._show[period]);
			showCount += (inst._show[period] ? 1 : 0);
		}
		var compact = this._get(inst, 'compact');
		var layout = this._get(inst, 'layout');
		var labels = (compact ? this._get(inst, 'compactLabels') : this._get(inst, 'labels'));
		var timeSeparator = this._get(inst, 'timeSeparator');
		var description = this._get(inst, 'description') || '';
		var twoDigits = function(value) {
			return (value < 10 ? '0' : '') + value;
		};
		var showCompact = function(period) {
			var labelsNum = $.countdown._get(inst, 'compactLabels' + periods[period]);
			return (inst._show[period] ? periods[period] +
				(labelsNum ? labelsNum[period] : labels[period]) + ' ' : '');
		};
		var showFull = function(period) {
			var labelsNum = $.countdown._get(inst, 'labels' + periods[period]);
			return (inst._show[period] ?
				'<div class="countdown_section"><span class="countdown_amount">' +
				periods[period] + '</span><br/>' +
				(labelsNum ? labelsNum[period] : labels[period]) + '</div>' : '');
		};
		return (layout ? this._buildLayout(inst, layout, compact) :
			((compact ? // Compact version
			'<div class="countdown_row countdown_amount' +
			(inst._hold ? ' countdown_holding' : '') + '">' + 
			showCompact(Y) + showCompact(O) + showCompact(W) + showCompact(D) + 
			(inst._show[H] ? twoDigits(periods[H]) : '') +
			(inst._show[M] ? (inst._show[H] ? timeSeparator : '') + twoDigits(periods[M]) : '') +
			(inst._show[S] ? (inst._show[H] || inst._show[M] ? timeSeparator : '') +
			twoDigits(periods[S]) : '') :
			// Full version
			'<div class="countdown_row countdown_show' + showCount +
			(inst._hold ? ' countdown_holding' : '') + '">' +
			showFull(Y) + showFull(O) + showFull(W) + showFull(D) +
			showFull(H) + showFull(M) + showFull(S)) + '</div>' +
			(description ? '<div class="countdown_row countdown_descr">' + description + '</div>' : '')));
	},

	/* Construct a custom layout.
	   @param  inst     (object) the current settings for this instance
	   @param  layout   (string) the customised layout
	   @param  compact  (boolean) true if using compact labels
	   @return  string - the custom HTML */
	_buildLayout: function(inst, layout, compact) {
		var labels = (compact ? this._get(inst, 'compactLabels') : this._get(inst, 'labels'));
		var html = layout;
		var processPeriod = function(period, index) {
			var pattern1 = new RegExp('%' + period + '.*%' + period);
			var pattern2 = new RegExp('%' + period + '.*');
			while (true) {
				var matches = pattern1.exec(html);
				if (!matches) {
					break;
				}
				matches[0] = matches[0].substr(0, 2) +
					matches[0].substr(2).replace(pattern2, '%' + period);
				html = html.replace(matches[0], inst._show[index] ?
					customisePeriod(matches[0], period, index) : '');
			}
		};
		var customisePeriod = function(text, period, index) {
			var labelsNum = $.countdown._get(inst,
				(compact ? 'compactLabels' : 'labels') + inst._periods[index]);
			return text.substr(2, text.length - 4).
				replace(/%nn/g, (inst._periods[index] < 10 ? '0' : '') +
				inst._periods[index]).
				replace(/%n/g, inst._periods[index]).
				replace(/%l/g, (labelsNum ? labelsNum[index] : labels[index]));
		};
		processPeriod('Y', Y);
		processPeriod('O', O);
		processPeriod('W', W);
		processPeriod('D', D);
		processPeriod('H', H);
		processPeriod('M', M);
		processPeriod('S', S);
		return html;
	},

	/* Translate the format into flags for each period.
	   @param  inst  object - the current settings for this instance
	   @return  string[7] - flags indicating which periods are requested (?) or
	            required (!) by year, month, week, day, hour, minute, second */
	_determineShow: function(inst) {
		var format = this._get(inst, 'format');
		var show = [];
		show[Y] = (format.match('y') ? '?' : (format.match('Y') ? '!' : null));
		show[O] = (format.match('o') ? '?' : (format.match('O') ? '!' : null));
		show[W] = (format.match('w') ? '?' : (format.match('W') ? '!' : null));
		show[D] = (format.match('d') ? '?' : (format.match('D') ? '!' : null));
		show[H] = (format.match('h') ? '?' : (format.match('H') ? '!' : null));
		show[M] = (format.match('m') ? '?' : (format.match('M') ? '!' : null));
		show[S] = (format.match('s') ? '?' : (format.match('S') ? '!' : null));
		return show;
	},
	
	/* Calculate the requested periods between now and the target time.
	   @param  inst  object - the current settings for this instance
	   @param  show  string[7] - flags indicating which periods are requested/required
	   @param  now   Date - the current date and time
	   @return  number[7] - the current time periods (always positive)
	            by year, month, week, day, hour, minute, second */
	_calculatePeriods: function(inst, show, now) {
		// Find endpoints
		inst._now = now;
		inst._now.setMilliseconds(0);
		var until = new Date(inst._now.getTime());
		if (inst._since && now.getTime() < inst._since.getTime()) {
			inst._now = now = until;
		}
		else if (inst._since) {
			now = inst._since;
		}
		else {
			until.setTime(inst._until.getTime());
			if (now.getTime() > inst._until.getTime()) {
				inst._now = now = until;
		}
		}
		until.setTime(until.getTime() - inst._offset); // Adjust for time zone
		// Calculate differences by period
		var periods = [0, 0, 0, 0, 0, 0, 0];
		if (show[Y] || show[O]) {
			var months = Math.max(0, (until.getFullYear() - now.getFullYear()) * 12 +
				until.getMonth() - now.getMonth() + (until.getDate() < now.getDate() ? -1 : 0));
			periods[Y] = (show[Y] ? Math.floor(months / 12) : 0);
			periods[O] = (show[O] ? months - periods[Y] * 12 : 0);
			if (inst._since) {
				until.setFullYear(until.getFullYear() - periods[Y]);
				until.setMonth(until.getMonth() - periods[O]);
			}
			else {
			now = new Date(now.getTime());
			now.setFullYear(now.getFullYear() + periods[Y]);
			now.setMonth(now.getMonth() + periods[O]);
		}
		}
		var diff = Math.floor((until.getTime() - now.getTime()) / 1000);
		var extractPeriod = function(period, numSecs) {
			periods[period] = (show[period] ? Math.floor(diff / numSecs) : 0);
			diff -= periods[period] * numSecs;
		};
		extractPeriod(W, 604800);
		extractPeriod(D, 86400);
		extractPeriod(H, 3600);
		extractPeriod(M, 60);
		extractPeriod(S, 1);
		return periods;
	}
});

/* jQuery extend now ignores nulls! */
function extendRemove(target, props) {
	$.extend(target, props);
	for (var name in props) {
		if (props[name] == null) {
			target[name] = null;
		}
	}
	return target;
}

/* Attach the countdown functionality to a jQuery selection.
   @param  command  string - the command to run (optional, default 'attach')
   @param  options  object - the new settings to use for these countdown instances
   @return  jQuery object - for chaining further calls */
$.fn.countdown = function(options) {
	var otherArgs = Array.prototype.slice.call(arguments, 1);
	if (options == 'getTimes') {
		return $.countdown['_' + options + 'Countdown'].
			apply($.countdown, [this[0]].concat(otherArgs));
	}
	return this.each(function() {
		if (typeof options == 'string') {
			$.countdown['_' + options + 'Countdown'].apply($.countdown, [this].concat(otherArgs));
		}
		else {
			$.countdown._attachCountdown(this, options);
		}
	});
};

/* Initialise the countdown functionality. */
$.countdown = new Countdown(); // singleton instance

})(jQuery);



/**
 *
 * Copyright (c) 2007 Tom Deater (http://www.tomdeater.com)
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 */
 
(function($) {
	/**
	 * attaches a character counter to each textarea element in the jQuery object
	 * usage: $("#myTextArea").charCounter(max, settings);
	 */

	$.fn.charCounter = function(max, settings) {
		max = max || 100;
		settings = $.extend({
			container: "<span>",
			classname: "charcounter",
			format: "%1 characters remaining",
			pulse: false,
			minimum: null,
			allowNegative: false,
			cutOffAt: null,
			negativeClassName: "negative",
			overClassName: "over_limit",
			insert: "after"
		}, settings);
		var p;

		function count(el, container, el) {
			if (settings.minimum) {
				if (el.val().length < settings.minimum) {
					container.addClass("too_low");
					container.html(settings.format.replace(/%1/, (settings.minimum - el.val().length)));
				} else {
					if (container.hasClass("too_low")) {
						container.removeClass("too_low");
					}
					container.html("");
				}
			} else {
				if (el.val().length > max) {
				    if (settings.allowNegative) {
				        container.addClass(settings.negativeClassName);
				    } else {
						container.addClass(settings.overClassName);
    			    	if (settings.pulse && !p) {
    			    		pulse(container, true);
    			    	};
						if (!settings.cutOffAt) {
	    			    	el.val(el.val().substring(0, max));
						} else if (settings.cutOffAt && el.val().length > settings.cutOffAt) {
	    			    	el.val(el.val().substring(0, settings.cutOffAt));
						}
				    }
				} else {
				    if (container.hasClass(settings.negativeClassName)) {
				        container.removeClass(settings.negativeClassName);
				    } else if (container.hasClass(settings.overClassName)) {
						container.removeClass(settings.overClassName);
					}
				}
				container.html(settings.format.replace(/%1/, (max - el.val().length)));
			}
		};

		function pulse(el, again) {
			if (p) {
				window.clearTimeout(p);
				p = null;
			};
			el.animate({ opacity: 0.1 }, 100, function() {
				$(this).animate({ opacity: 1.0 }, 100);
			});
			if (again) {
				p = window.setTimeout(function() { pulse(el) }, 200);
			};
		};

		return this.each(function() {
			var container = (!settings.container.match(/^<.+>$/)) 
				? $(settings.container) 
				: $(settings.container).addClass(settings.classname);
			if (settings.insert == "before")
				container.insertBefore(this);
			else
				container.insertAfter(this);
			var el = $(this);
			el
                // .bind("keydown", function() { count(this, container); })
                // .bind("keypress", function() { count(this, container); })
				.bind("keyup", function() { count(this, container, el); })
				//.bind("focus", function() { count(this, container, el); })
				//.bind("mouseover", function() { count(this, container, el); })
				//.bind("mouseout", function() { count(this, container, el); })
				.bind("paste", function() { 
					var me = this;
					setTimeout(function() { count(me, container, el); }, 10);
				});
			if (this.addEventListener) {
				this.addEventListener('input', function() { count(this, container, el); }, false);
			};
			count(this, container, el);
		});
	};

})(jQuery);



/**
 * jCarousel - Riding carousels with jQuery
 *   http://sorgalla.com/jcarousel/
 *
 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Built on top of the jQuery library
 *   http://jquery.com
 *
 * Inspired by the "Carousel Component" by Bill Scott
 *   http://billwscott.com/carousel/
 */
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){$.1s.B=9(o){z 4.1b(9(){3h r(4,o)})};8 q={X:I,23:1,1X:1,u:7,16:3,17:7,1I:\'2O\',2b:\'2E\',1i:0,C:7,1h:7,1D:7,2x:7,2w:7,2v:7,2t:7,2r:7,2q:7,2o:7,1Q:\'<Z></Z>\',1P:\'<Z></Z>\',2k:\'2j\',2g:\'2j\',1L:7,1J:7};$.B=9(e,o){4.5=$.1a({},q,o||{});4.P=I;4.E=7;4.H=7;4.t=7;4.U=7;4.R=7;4.M=!4.5.X?\'1E\':\'27\';4.F=!4.5.X?\'26\':\'25\';6(e.20==\'3p\'||e.20==\'3n\'){4.t=$(e);4.E=4.t.1o();6($.D.1e(4.E[0].D,\'B-H\')){6(!$.D.1e(4.E[0].3k.D,\'B-E\'))4.E=4.E.C(\'<Z></Z>\');4.E=4.E.1o()}10 6(!$.D.1e(4.E[0].D,\'B-E\'))4.E=4.t.C(\'<Z></Z>\').1o();8 a=e.D.3g(\' \');1m(8 i=0;i<a.O;i++){6(a[i].3c(\'B-3b\')!=-1){4.t.1z(a[i]);4.E.Q(a[i]);1l}}}10{4.E=$(e);4.t=$(e).2m(\'32,2Z\')}4.H=4.t.1o();6(!4.H.O||!$.D.1e(4.H[0].D,\'B-H\'))4.H=4.t.C(\'<Z></Z>\').1o();4.R=$(\'.B-13\',4.E);6(4.R.u()==0&&4.5.1P!=7)4.R=4.H.1x(4.5.1P).13();4.R.Q(4.D(\'B-13\'));4.U=$(\'.B-15\',4.E);6(4.U.u()==0&&4.5.1Q!=7)4.U=4.H.1x(4.5.1Q).13();4.U.Q(4.D(\'B-15\'));4.H.Q(4.D(\'B-H\'));4.t.Q(4.D(\'B-t\'));4.E.Q(4.D(\'B-E\'));8 b=4.5.17!=7?1j.1M(4.1q()/4.5.17):7;8 c=4.t.2m(\'1u\');8 d=4;6(c.u()>0){8 f=0,i=4.5.1X;c.1b(9(){d.1O(4,i++);f+=d.T(4,b)});4.t.y(4.M,f+\'S\');6(!o||o.u==L)4.5.u=c.u()}4.E.y(\'1y\',\'1v\');4.U.y(\'1y\',\'1v\');4.R.y(\'1y\',\'1v\');4.2p=9(){d.15()};4.2s=9(){d.13()};$(2D).1W(\'2B\',9(){d.29()});6(4.5.1h!=7)4.5.1h(4,\'28\');4.1F()};8 r=$.B;r.1s=r.2z={B:\'0.2.2\'};r.1s.1a=r.1a=$.1a;r.1s.1a({1F:9(){4.A=7;4.G=7;4.W=7;4.11=7;4.14=I;4.1c=7;4.N=7;4.V=I;6(4.P)z;4.t.y(4.F,4.1r(4.5.1X)+\'S\');8 p=4.1r(4.5.23);4.W=4.11=7;4.1g(p,I)},24:9(){4.t.22();4.t.y(4.F,\'21\');4.t.y(4.M,\'21\');6(4.5.1h!=7)4.5.1h(4,\'24\');4.1F()},29:9(){6(4.N!=7&&4.V)4.t.y(4.F,r.K(4.t.y(4.F))+4.N);4.N=7;4.V=I;6(4.5.1D!=7)4.5.1D(4);6(4.5.17!=7){8 a=4;8 b=1j.1M(4.1q()/4.5.17),M=0,F=0;$(\'1u\',4.t).1b(9(i){M+=a.T(4,b);6(i+1<a.A)F=M});4.t.y(4.M,M+\'S\');4.t.y(4.F,-F+\'S\')}4.16(4.A,I)},2y:9(){4.P=1f;4.1p()},3m:9(){4.P=I;4.1p()},u:9(s){6(s!=L){4.5.u=s;6(!4.P)4.1p()}z 4.5.u},1e:9(i,a){6(a==L||!a)a=i;1m(8 j=i;j<=a;j++){8 e=4.J(j).J(0);6(!e||$.D.1e(e,\'B-19-1C\'))z I}z 1f},J:9(i){z $(\'.B-19-\'+i,4.t)},3l:9(i,s){8 e=4.J(i),1Y=0;6(e.O==0){8 c,e=4.1B(i),j=r.K(i);1n(c=4.J(--j)){6(j<=0||c.O){j<=0?4.t.2u(e):c.1V(e);1l}}}10 1Y=4.T(e);e.1z(4.D(\'B-19-1C\'));1U s==\'3j\'?e.3f(s):e.22().3d(s);8 a=4.5.17!=7?1j.1M(4.1q()/4.5.17):7;8 b=4.T(e,a)-1Y;6(i>0&&i<4.A)4.t.y(4.F,r.K(4.t.y(4.F))+b+\'S\');4.t.y(4.M,r.K(4.t.y(4.M))+b+\'S\');z e},1T:9(i){8 e=4.J(i);6(!e.O||(i>=4.A&&i<=4.G))z;8 d=4.T(e);6(i<4.A)4.t.y(4.F,r.K(4.t.y(4.F))+d+\'S\');e.1T();4.t.y(4.M,r.K(4.t.y(4.M))-d+\'S\')},15:9(){4.1A();6(4.N!=7&&!4.V)4.1S(I);10 4.16(((4.5.C==\'1R\'||4.5.C==\'G\')&&4.5.u!=7&&4.G==4.5.u)?1:4.A+4.5.16)},13:9(){4.1A();6(4.N!=7&&4.V)4.1S(1f);10 4.16(((4.5.C==\'1R\'||4.5.C==\'A\')&&4.5.u!=7&&4.A==1)?4.5.u:4.A-4.5.16)},1S:9(b){6(4.P||4.14||!4.N)z;8 a=r.K(4.t.y(4.F));!b?a-=4.N:a+=4.N;4.V=!b;4.W=4.A;4.11=4.G;4.1g(a)},16:9(i,a){6(4.P||4.14)z;4.1g(4.1r(i),a)},1r:9(i){6(4.P||4.14)z;6(4.5.C!=\'18\')i=i<1?1:(4.5.u&&i>4.5.u?4.5.u:i);8 a=4.A>i;8 b=r.K(4.t.y(4.F));8 f=4.5.C!=\'18\'&&4.A<=1?1:4.A;8 c=a?4.J(f):4.J(4.G);8 j=a?f:f-1;8 e=7,l=0,p=I,d=0;1n(a?--j>=i:++j<i){e=4.J(j);p=!e.O;6(e.O==0){e=4.1B(j).Q(4.D(\'B-19-1C\'));c[a?\'1x\':\'1V\'](e)}c=e;d=4.T(e);6(p)l+=d;6(4.A!=7&&(4.5.C==\'18\'||(j>=1&&(4.5.u==7||j<=4.5.u))))b=a?b+d:b-d}8 g=4.1q();8 h=[];8 k=0,j=i,v=0;8 c=4.J(i-1);1n(++k){e=4.J(j);p=!e.O;6(e.O==0){e=4.1B(j).Q(4.D(\'B-19-1C\'));c.O==0?4.t.2u(e):c[a?\'1x\':\'1V\'](e)}c=e;8 d=4.T(e);6(d==0){3a(\'39: 38 1E/27 37 1m 36. 35 34 33 31 30 2Y. 2X...\');z 0}6(4.5.C!=\'18\'&&4.5.u!==7&&j>4.5.u)h.2W(e);10 6(p)l+=d;v+=d;6(v>=g)1l;j++}1m(8 x=0;x<h.O;x++)h[x].1T();6(l>0){4.t.y(4.M,4.T(4.t)+l+\'S\');6(a){b-=l;4.t.y(4.F,r.K(4.t.y(4.F))-l+\'S\')}}8 n=i+k-1;6(4.5.C!=\'18\'&&4.5.u&&n>4.5.u)n=4.5.u;6(j>n){k=0,j=n,v=0;1n(++k){8 e=4.J(j--);6(!e.O)1l;v+=4.T(e);6(v>=g)1l}}8 o=n-k+1;6(4.5.C!=\'18\'&&o<1)o=1;6(4.V&&a){b+=4.N;4.V=I}4.N=7;6(4.5.C!=\'18\'&&n==4.5.u&&(n-k+1)>=1){8 m=r.Y(4.J(n),!4.5.X?\'1k\':\'1H\');6((v-m)>g)4.N=v-g-m}1n(i-->o)b+=4.T(4.J(i));4.W=4.A;4.11=4.G;4.A=o;4.G=n;z b},1g:9(p,a){6(4.P||4.14)z;4.14=1f;8 b=4;8 c=9(){b.14=I;6(p==0)b.t.y(b.F,0);6(b.5.C==\'1R\'||b.5.C==\'G\'||b.5.u==7||b.G<b.5.u)b.2i();b.1p();b.1N(\'2h\')};4.1N(\'2V\');6(!4.5.1I||a==I){4.t.y(4.F,p+\'S\');c()}10{8 o=!4.5.X?{\'26\':p}:{\'25\':p};4.t.1g(o,4.5.1I,4.5.2b,c)}},2i:9(s){6(s!=L)4.5.1i=s;6(4.5.1i==0)z 4.1A();6(4.1c!=7)z;8 a=4;4.1c=2U(9(){a.15()},4.5.1i*2T)},1A:9(){6(4.1c==7)z;2S(4.1c);4.1c=7},1p:9(n,p){6(n==L||n==7){8 n=!4.P&&4.5.u!==0&&((4.5.C&&4.5.C!=\'A\')||4.5.u==7||4.G<4.5.u);6(!4.P&&(!4.5.C||4.5.C==\'A\')&&4.5.u!=7&&4.G>=4.5.u)n=4.N!=7&&!4.V}6(p==L||p==7){8 p=!4.P&&4.5.u!==0&&((4.5.C&&4.5.C!=\'G\')||4.A>1);6(!4.P&&(!4.5.C||4.5.C==\'G\')&&4.5.u!=7&&4.A==1)p=4.N!=7&&4.V}8 a=4;4.U[n?\'1W\':\'2f\'](4.5.2k,4.2p)[n?\'1z\':\'Q\'](4.D(\'B-15-1w\')).1K(\'1w\',n?I:1f);4.R[p?\'1W\':\'2f\'](4.5.2g,4.2s)[p?\'1z\':\'Q\'](4.D(\'B-13-1w\')).1K(\'1w\',p?I:1f);6(4.U.O>0&&(4.U[0].1d==L||4.U[0].1d!=n)&&4.5.1L!=7){4.U.1b(9(){a.5.1L(a,4,n)});4.U[0].1d=n}6(4.R.O>0&&(4.R[0].1d==L||4.R[0].1d!=p)&&4.5.1J!=7){4.R.1b(9(){a.5.1J(a,4,p)});4.R[0].1d=p}},1N:9(a){8 b=4.W==7?\'28\':(4.W<4.A?\'15\':\'13\');4.12(\'2x\',a,b);6(4.W!=4.A){4.12(\'2w\',a,b,4.A);4.12(\'2v\',a,b,4.W)}6(4.11!=4.G){4.12(\'2t\',a,b,4.G);4.12(\'2r\',a,b,4.11)}4.12(\'2q\',a,b,4.A,4.G,4.W,4.11);4.12(\'2o\',a,b,4.W,4.11,4.A,4.G)},12:9(a,b,c,d,e,f,g){6(4.5[a]==L||(1U 4.5[a]!=\'2e\'&&b!=\'2h\'))z;8 h=1U 4.5[a]==\'2e\'?4.5[a][b]:4.5[a];6(!$.2R(h))z;8 j=4;6(d===L)h(j,c,b);10 6(e===L)4.J(d).1b(9(){h(j,4,d,c,b)});10{1m(8 i=d;i<=e;i++)6(!(i>=f&&i<=g))4.J(i).1b(9(){h(j,4,i,c,b)})}},1B:9(i){z 4.1O(\'<1u></1u>\',i)},1O:9(e,i){8 a=$(e).Q(4.D(\'B-19\')).Q(4.D(\'B-19-\'+i));a.1K(\'2Q\',i);z a},D:9(c){z c+\' \'+c+(!4.5.X?\'-2P\':\'-X\')},T:9(e,d){8 a=e.2l!=L?e[0]:e;8 b=!4.5.X?a.1t+r.Y(a,\'2d\')+r.Y(a,\'1k\'):a.2c+r.Y(a,\'2n\')+r.Y(a,\'1H\');6(d==L||b==d)z b;8 w=!4.5.X?d-r.Y(a,\'2d\')-r.Y(a,\'1k\'):d-r.Y(a,\'2n\')-r.Y(a,\'1H\');$(a).y(4.M,w+\'S\');z 4.T(a)},1q:9(){z!4.5.X?4.H[0].1t-r.K(4.H.y(\'2N\'))-r.K(4.H.y(\'2M\')):4.H[0].2c-r.K(4.H.y(\'2L\'))-r.K(4.H.y(\'2K\'))},2J:9(i,s){6(s==L)s=4.5.u;z 1j.2I((((i-1)/s)-1j.3e((i-1)/s))*s)+1}});r.1a({2H:9(d){$.1a(q,d)},Y:9(e,p){6(!e)z 0;8 a=e.2l!=L?e[0]:e;6(p==\'1k\'&&$.2G.2F){8 b={\'1y\':\'1v\',\'3i\':\'2C\',\'1E\':\'1i\'},1G,1Z;$.2a(a,b,9(){1G=a.1t});b[\'1k\']=0;$.2a(a,b,9(){1Z=a.1t});z 1Z-1G}z r.K($.y(a,p))},K:9(v){v=2A(v);z 3o(v)?0:v}})})(3q);',62,213,'||||this|options|if|null|var|function||||||||||||||||||||list|size||||css|return|first|jcarousel|wrap|className|container|lt|last|clip|false|get|intval|undefined|wh|tail|length|locked|addClass|buttonPrev|px|dimension|buttonNext|inTail|prevFirst|vertical|margin|div|else|prevLast|callback|prev|animating|next|scroll|visible|circular|item|extend|each|timer|jcarouselstate|has|true|animate|initCallback|auto|Math|marginRight|break|for|while|parent|buttons|clipping|pos|fn|offsetWidth|li|block|disabled|before|display|removeClass|stopAuto|create|placeholder|reloadCallback|width|setup|oWidth|marginBottom|animation|buttonPrevCallback|attr|buttonNextCallback|ceil|notify|format|buttonPrevHTML|buttonNextHTML|both|scrollTail|remove|typeof|after|bind|offset|old|oWidth2|nodeName|0px|empty|start|reset|top|left|height|init|reload|swap|easing|offsetHeight|marginLeft|object|unbind|buttonPrevEvent|onAfterAnimation|startAuto|click|buttonNextEvent|jquery|children|marginTop|itemVisibleOutCallback|funcNext|itemVisibleInCallback|itemLastOutCallback|funcPrev|itemLastInCallback|prepend|itemFirstOutCallback|itemFirstInCallback|itemLoadCallback|lock|prototype|parseInt|resize|none|window|swing|safari|browser|defaults|round|index|borderBottomWidth|borderTopWidth|borderRightWidth|borderLeftWidth|normal|horizontal|jcarouselindex|isFunction|clearTimeout|1000|setTimeout|onBeforeAnimation|push|Aborting|loop|ol|infinite|an|ul|cause|will|This|items|set|No|jCarousel|alert|skin|indexOf|append|floor|html|split|new|float|string|parentNode|add|unlock|OL|isNaN|UL|jQuery'.split('|'),0,{}))


/**
 * Flash (http://jquery.lukelutman.com/plugins/flash)
 * A jQuery plugin for embedding Flash movies.
 **/ 
;(function(){
	
var jQuery$$;

jQuery$$ = jQuery.fn.flash = function(htmlOptions, pluginOptions, replace, update) {
	var block = replace || jQuery$$.replace;
	pluginOptions = jQuery$$.copy(jQuery$$.pluginOptions, pluginOptions);
	if(!jQuery$$.hasFlash(pluginOptions.version)) {
		if(pluginOptions.expressInstall && jQuery$$.hasFlash(6,0,65)) {
			var expressInstallOptions = {
				flashvars: {  	
					MMredirectURL: location,
					MMplayerType: 'PlugIn',
					MMdoctitle: jQuery('title').text() 
				}					
			};
		} else if (pluginOptions.update) {
			block = update || jQuery$$.update;
		} else {
			return this;
		}
	}
	htmlOptions = jQuery$$.copy(jQuery$$.htmlOptions, expressInstallOptions, htmlOptions);
	return this.each(function(){
		block.call(this, jQuery$$.copy(htmlOptions));
	});
	
};
jQuery$$.copy = function() {
	var options = {}, flashvars = {};
	for(var i = 0; i < arguments.length; i++) {
		var arg = arguments[i];
		if(arg == undefined) continue;
		jQuery.extend(options, arg);
		if(arg.flashvars == undefined) continue;
		jQuery.extend(flashvars, arg.flashvars);
	}
	options.flashvars = flashvars;
	return options;
};
jQuery$$.hasFlash = function() {
	if(/hasFlash\=true/.test(location)) return true;
	if(/hasFlash\=false/.test(location)) return false;
	var pv = jQuery$$.hasFlash.playerVersion().match(/\d+/g);
	var rv = String([arguments[0], arguments[1], arguments[2]]).match(/\d+/g) || String(jQuery$$.pluginOptions.version).match(/\d+/g);
	for(var i = 0; i < 3; i++) {
		pv[i] = parseInt(pv[i] || 0);
		rv[i] = parseInt(rv[i] || 0);
		if(pv[i] < rv[i]) return false;
		if(pv[i] > rv[i]) return true;
	}
	return true;
};
jQuery$$.hasFlash.playerVersion = function() {
	try {
		try {
			var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6');
			try { axo.AllowScriptAccess = 'always';	} 
			catch(e) { return '6,0,0'; }				
		} catch(e) {}
		return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('jQueryversion').replace(/\D+/g, ',').match(/^,?(.+),?jQuery/)[1];
	} catch(e) {
		try {
			if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
				return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?jQuery/)[1];
			}
		} catch(e) {}		
	}
	return '0,0,0';
};
jQuery$$.htmlOptions = {
	height: 240,
	flashvars: {},
	pluginspage: 'http://www.adobe.com/go/getflashplayer',
	src: '#',
	type: 'application/x-shockwave-flash',
	width: 320		
};
jQuery$$.pluginOptions = {
	expressInstall: false,
	update: true,
	version: '6.0.65'
};
jQuery$$.replace = function(htmlOptions) {
	this.innerHTML = '<div class="alt">'+this.innerHTML+'</div>';
	jQuery(this)
		.addClass('flash-replaced')
		.prepend(jQuery$$.transform(htmlOptions));
};
jQuery$$.update = function(htmlOptions) {
	var url = String(location).split('?');
	url.splice(1,0,'?hasFlash=true&');
	url = url.join('');
	var msg = '<p>This content requires the Flash Player. <a href="http://www.adobe.com/go/getflashplayer">Download Flash Player</a>. Already have Flash Player? <a href="'+url+'">Click here.</a></p>';
	this.innerHTML = '<span class="alt">'+this.innerHTML+'</span>';
	jQuery(this)
		.addClass('flash-update')
		.prepend(msg);
};
function toAttributeString() {
	var s = '';
	for(var key in this)
		if(typeof this[key] != 'function')
			s += key+'="'+this[key]+'" ';
	return s;		
};
function toFlashvarsString() {
	var s = '';
	for(var key in this)
		if(typeof this[key] != 'function')
			s += key+'='+ encodeURIComponent(this[key])+'&';
	return s.replace(/&jQuery/, '');		
};
jQuery$$.transform = function(htmlOptions) {
	htmlOptions.toString = toAttributeString;
	if(htmlOptions.flashvars) htmlOptions.flashvars.toString = toFlashvarsString;
	return '<embed ' + String(htmlOptions) + '/>';		
};
if (window.attachEvent) {
	window.attachEvent("onbeforeunload", function(){
		__flash_unloadHandler = function() {};
		__flash_savedUnloadHandler = function() {};
	});
}
	
})();


/*
 * Thickbox 3.1 - One Box To Rule Them All.
 * By Cody Lindley (http://www.codylindley.com)
 * Copyright (c) 2007 cody lindley
 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*/
		  
var tb_pathToImage = "/images/icons/loadingAnimation.gif";

/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/


//add thickbox to href & area elements that have a class of .thickbox
jQuery.fn.thickbox = function(){
	this.click(function(){
		tb_show(this.title, this.href, false)
		return false;
	})
}

function tb_init(domChunk){
	jQuery(domChunk).click(function(){
	var t = this.title || this.name || null;
	var a = this.href || this.alt;
	var g = this.rel || false;
	tb_show(t,a,g);
	this.blur();
	return false;
	});
}

function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link

	try {
		if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
			jQuery("body","html").css({height: "100%", width: "100%"});
			jQuery("html").css("overflow","hidden");
			if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
				jQuery("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
				jQuery("#TB_overlay").click(tb_remove);
			}
		}else{//all others
			if(document.getElementById("TB_overlay") === null){
				jQuery("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>");
				jQuery("#TB_overlay").click(tb_remove);
			}
		}
		
		if(tb_detectMacXFF()){
			jQuery("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash
		}else{
			jQuery("#TB_overlay").addClass("TB_overlayBG");//use background and opacity
		}

		caption = (!caption) ? "" : caption
		jQuery("body").append("<div id='TB_load'><img src='"+tb_pathToImage+"' /></div>");//add loader to the page
		
		jQuery('#TB_load').show();//show loader
		
		var baseURL;
		
		
	   if(url.indexOf("?")!==-1){ //ff there is a query string involved
			baseURL = url.substr(0, url.indexOf("?"));
	   }else{ 
	   		baseURL = url;
	   }

			var queryString = url.replace(/^[^\?]+\??/,'');
			var params = tb_parseQuery( queryString );

			TB_WIDTH = (params['width']*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL
			TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL
			ajaxContentW = TB_WIDTH - 30;
			ajaxContentH = TB_HEIGHT - 45;
			
			if(url.indexOf('TB_iframe') != -1){// either iframe or ajax window		
					urlNoQuery = url.split('TB_');
					jQuery("#TB_iframeContent").remove();
					if(params['modal'] != "true"){//iframe no modal
						jQuery("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a> or Esc Key</div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' > </iframe>");
					}else{//iframe modal
					jQuery("#TB_overlay").unbind();
						jQuery("#TB_window").append("<iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;'> </iframe>");
					}
			}else{// not an iframe, ajax
					if(jQuery("#TB_window").css("display") != "block"){
						if(params['modal'] != "true"){//ajax no modal
						jQuery("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'>close</a> or Esc Key</div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>");
						}else{//ajax modal
						jQuery("#TB_overlay").unbind();
						jQuery("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>");	
						}
					}else{//this means the window is already up, we are just loading new content via ajax
						jQuery("#TB_ajaxContent")[0].style.width = ajaxContentW +"px";
						jQuery("#TB_ajaxContent")[0].style.height = ajaxContentH +"px";
						jQuery("#TB_ajaxContent")[0].scrollTop = 0;
						jQuery("#TB_ajaxWindowTitle").html(caption);
					}
			}
					
				if(url.indexOf('TB_inline') != -1){	
					jQuery("#TB_ajaxContent").append(jQuery('#' + params['inlineId']).children());
					jQuery("#TB_window").unload(function () {
						jQuery('#' + params['inlineId']).append( jQuery("#TB_ajaxContent").children() ); // move elements back when you're finished
					});
					tb_position();
					jQuery("#TB_load").remove();
					jQuery("#TB_window").css({display:"block"}); 
				}else if(url.indexOf('TB_iframe') != -1){
					tb_position();
					if(jQuery.browser.safari){//safari needs help because it will not fire iframe onload
						jQuery("#TB_load").remove();
						jQuery("#TB_window").css({display:"block"});
					}
				}else{
					jQuery.get(url += "&random=" + (new Date().getTime()),function(data){
						if (data.indexOf("jQuery.fn.flash") != -1) {
							jQuery('#TB_ajaxContent').html(eval(data))
						} else if (data.indexOf("SWFObject") != -1) {
							eval(data)
						} else 
							jQuery('#TB_ajaxContent').html(data)
						tb_position();
						jQuery("#TB_load").remove();
						tb_init("#TB_ajaxContent a.thickbox");
						jQuery("#TB_window").css({display:"block"});
					})
				}

				jQuery("#TB_closeWindowButton").click(tb_remove);

			
		if(!params['modal']){
			document.onkeyup = function(e){ 	
				if (e == null) { // ie
					keycode = event.keyCode;
				} else { // mozilla
					keycode = e.which;
				}
				if(keycode == 27){ // close
					tb_remove();
				}	
			};
		}
		
	} catch(e) {
		//nothing here
	}
}

//helper functions below
function tb_showIframe(){
	jQuery("#TB_load").remove();
	jQuery("#TB_window").css({display:"block"});
}

function tb_remove() {
 	jQuery("#TB_imageOff").unbind("click");
	jQuery("#TB_closeWindowButton").unbind("click");
	jQuery("#TB_window").fadeOut("fast",function(){jQuery('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();});
	jQuery("#TB_load").remove();
	if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
		jQuery("body","html").css({height: "auto", width: "auto"});
		jQuery("html").css("overflow","");
	}
	document.onkeydown = "";
	document.onkeyup = "";
	jQuery('#alert').remove();
	jQuery('#confirm').remove();
	return false;
}

function tb_position() {
jQuery("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'});
	if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6
		jQuery("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'});
	}
}

function tb_parseQuery ( query ) {
   var Params = {};
   if ( ! query ) {return Params;}// return empty object
   var Pairs = query.split(/[;&]/);
   for ( var i = 0; i < Pairs.length; i++ ) {
      var KeyVal = Pairs[i].split('=');
      if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
      var key = unescape( KeyVal[0] );
      var val = unescape( KeyVal[1] );
      val = val.replace(/\+/g, ' ');
      Params[key] = val;
   }
   return Params;
}

function tb_getPageSize(){
	var de = document.documentElement;
	var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
	var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
	arrayPageSize = [w,h];
	return arrayPageSize;
}

function tb_detectMacXFF() {
  var userAgent = navigator.userAgent.toLowerCase();
  if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
    return true;
  }
}


/*
 * Facebox (for jQuery)
 * version: 1.2 (05/05/2008)
 * @requires jQuery v1.2 or later
 *
 * Examples at http://famspam.com/facebox/
 *
 * Licensed under the MIT:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
 *
 * Usage:
 *  
 *  jQuery(document).ready(function() {
 *    jQuery('a[rel*=facebox]').facebox() 
 *  })
 *
 *  <a href="#terms" rel="facebox">Terms</a>
 *    Loads the #terms div in the box
 *
 *  <a href="terms.html" rel="facebox">Terms</a>
 *    Loads the terms.html page in the box
 *
 *  <a href="terms.png" rel="facebox">Terms</a>
 *    Loads the terms.png image in the box
 *
 *
 *  You can also use it programmatically:
 * 
 *    jQuery.facebox('some html')
 *
 *  The above will open a facebox with "some html" as the content.
 *    
 *    jQuery.facebox(function($) { 
 *      $.get('blah.html', function(data) { $.facebox(data) })
 *    })
 *
 *  The above will show a loading screen before the passed function is called,
 *  allowing for a better ajaxy experience.
 *
 *  The facebox function can also display an ajax page or image:
 *  
 *    jQuery.facebox({ ajax: 'remote.html' })
 *    jQuery.facebox({ image: 'dude.jpg' })
 *
 *  Want to close the facebox?  Trigger the 'close.facebox' document event:
 *
 *    jQuery(document).trigger('close.facebox')
 *
 *  Facebox also has a bunch of other hooks:
 *
 *    loading.facebox
 *    beforeReveal.facebox
 *    reveal.facebox (aliased as 'afterReveal.facebox')
 *    init.facebox
 *
 *  Simply bind a function to any of these hooks:
 *
 *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
 *
 */
(function($) {
  $.facebox = function(data, klass) {
    $.facebox.loading()

    if (data.ajax) fillFaceboxFromAjax(data.ajax)
    else if (data.image) fillFaceboxFromImage(data.image)
    else if (data.div) fillFaceboxFromHref(data.div)
    else if ($.isFunction(data)) data.call($)
    else $.facebox.reveal(data, klass)
  }

  /*
   * Public, $.facebox methods
   */

  $.extend($.facebox, {
    settings: {
      opacity      : 0,
      overlay      : true,
      loadingImage : 'http://assets0.showpopr.com/images/arrows/ajax-loader.gif',
      closeImage   : '/images/facebox/closelabel.gif',
      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],
      faceboxHtml  : '\
    <div id="facebox" style="display:block;"> \
      <div class="popup"> \
        <table> \
          <tbody> \
            <tr> \
              <td class="tl"/><td class="bh"/><td class="tr"/> \
            </tr> \
            <tr> \
              <td class="bv"/> \
              <td class="body"> \
                <div class="outer_border"> \
                <div class="inner_border"> \
                <div class="content"> \
                </div> \
                <div class="footer"> \
                  <a href="#" class="close">close</a> \
                </div> \
                </div> \
                </div> \
              </td> \
              <td class="bv"/> \
            </tr> \
            <tr> \
              <td class="bl"/><td class="bh"/><td class="br"/> \
            </tr> \
          </tbody> \
        </table> \
      </div> \
    </div>'
    },
    
    position: function(){
        var left, top, pageHeight = getPageHeight(), pageScroll = getPageScroll()[1];
        var css = {};
        if ($.facebox.settings.top) {
            top = $.facebox.settings.top;
            top -= 125;
            if (top <= 141) top = 150;
            css.top = top;
        } else {
            css.top = pageScroll + (pageHeight / 10);
        }
        css.left = $.facebox.settings.left || ($(window).width() - $.facebox.settings.width) / 2
        $('#facebox').show().css(css);
    },

    loading: function(data) {
        $.facebox.init();
        if ($('#facebox .loading').length == 1) return true;
        showOverlay();
        
        $('#facebox .content').empty();
        $('#facebox .body .inner_border').children().hide().end().
            append('<div class="loading"><img src="'+$.facebox.settings.loadingImage+'"/></div>');

        $.facebox.settings.width = $.facebox.settings.width || 635;
        if ($.facebox.settings.video) {
            $('#facebox, #facebox_overlay').addClass("facebox_video");
            $.facebox.settings.width = 450;
        } else if ($.facebox.settings.login) {
            $('#facebox').addClass('facebox_login');
            $.facebox.settings.width = 335;
        } 
        $('#facebox div.inner_border').css({
         "width": $.facebox.settings.width + "px"
        });
        
        if ($.facebox.settings.height) {
            $('#facebox div.inner_border').css({
             "min-height": $.facebox.settings.height + "px"
            });
        }

        $.facebox.settings.video = null;
        $.facebox.settings.login = null;
        
        $.facebox.position();
        
        // scrollTo if top is offscreen
        var scrollTop = getPageScroll()[1], faceboxTop = $('#facebox').offset().top;
        if (faceboxTop <= scrollTop) {
            $(window).scrollTo('#facebox', {offset: -20, duration: 500});
        }

        $(document).bind('keydown.facebox', function(e) {
          if (e.keyCode == 27) $.facebox.close()
          return true
        })
        $(document).trigger('loading.facebox')
    },

    reveal: function(data, klass) {
      $(document).trigger('beforeReveal.facebox')
      if (klass) $('#facebox .content').addClass(klass)
      $('#facebox .content').append(data)
      $('#facebox .body .inner_border').children().show();
      // $.facebox.position();
      $('#facebox .loading').remove();
      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox');
      // setPosition();
	  $('#username').focus();
    },

    close: function() {
      $(document).trigger('close.facebox')
      return false
    },
    
    preload : function(){
        var preload = [new Image(), new Image()];
        preload[0].src = $.facebox.settings.closeImage;
        preload[1].src = $.facebox.settings.loadingImage;

        // $.facebox.preloadCorners();
        // $.facebox.preloadVideoCorners();
        $.facebox.preloaded = true;
    },
    
    preloadCorners : function(){
        var preload = []
        for(var i=0;i<=3;i++) { preload.push(new Image())}
        preload[0].src= "/facebox/bl.png";
        preload[1].src= "/facebox/br.png";
        preload[2].src= "/facebox/tl.png";
        preload[3].src= "/facebox/tr.png";
    },

    preloadVideoCorners : function(){
        var preload = []
        for(var i=0;i<=3;i++) { preload.push(new Image())}
        preload[0].src= "/facebox/bl_dark.png";
        preload[1].src= "/facebox/br_dark.png";
        preload[2].src= "/facebox/tl_dark.png";
        preload[3].src= "/facebox/tr_dark.png";
    },
    
    // called one time to setup facebox on this page
    init : function(settings) {
      if ($.facebox.settings.inited) return true
      else $.facebox.settings.inited = true

      $(document).trigger('init.facebox')
      makeCompatible()

      if (!$.facebox.preloaded)
        $.facebox.preload();

      var imageTypes = $.facebox.settings.imageTypes.join('|')
      $.facebox.settings.imageTypesRegexp = new RegExp('\.' + imageTypes + '$', 'i')

      if (settings) $.extend($.facebox.settings, settings);

      $('body').append($.facebox.settings.faceboxHtml)

      $('#facebox .close').click($.facebox.close)
      $('#facebox .close_image').attr('src', $.facebox.settings.closeImage)
    }
    

  })

  /*
   * Public, $.fn methods
   */

  $.fn.facebox = function(settings) {
    $.facebox.init(settings)

    function clickHandler() {
      $.facebox.loading(true)

      // support for rel="facebox.inline_popup" syntax, to add a class
      // also supports deprecated "facebox[.inline_popup]" syntax
      var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
      if (klass) klass = klass[1]

      fillFaceboxFromHref(this.href, klass)
      return false
    }

    return this.click(clickHandler)
  }

  /*
   * Private methods
   */

  
  // getPageScroll() by quirksmode.com
  function getPageScroll() {
    var xScroll, yScroll;
    if (self.pageYOffset) {
      yScroll = self.pageYOffset;
      xScroll = self.pageXOffset;
    } else if (document.documentElement && document.documentElement.scrollTop) {  // Explorer 6 Strict
      yScroll = document.documentElement.scrollTop;
      xScroll = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
      yScroll = document.body.scrollTop;
      xScroll = document.body.scrollLeft;    
    }
    return new Array(xScroll,yScroll) 
  }
 
  // Adapted from getPageSize() by quirksmode.com
  function getPageHeight() {
    var windowHeight
    if (self.innerHeight) {  // all except Explorer
      windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
      windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
      windowHeight = document.body.clientHeight;
    }    
    return windowHeight
  }

  function setPosition(){
      var fb = $('#facebox')
      fb.show();
      var height = getPageScroll()[1], width = fb.outerWidth();
      fb.css({marginTop: (height + 85) + "px"})
      fb.css({marginLeft: '-' + parseInt((width / 2),10) + 'px'});
      // if ( !($.browser.msie && $.browser.version < 7)) { // take away IE6
      //        fb.css({marginTop: '-' + parseInt((height / 2),10) + 'px'});
      // }
      fb.css("visibility", "visible");
  }

  // Backwards compatibility
  function makeCompatible() {
    var $s = $.facebox.settings

    $s.loadingImage = $s.loading_image || $s.loadingImage
    $s.closeImage = $s.close_image || $s.closeImage
    $s.imageTypes = $s.image_types || $s.imageTypes
    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
  }

  // Figures out what you want to display and displays it
  // formats are:
  //     div: #id
  //   image: blah.extension
  //    ajax: anything else
  function fillFaceboxFromHref(href, klass) {
    // div
    if (href.match(/#/)) {
      var url    = window.location.href.split('#')[0]
      var target = href.replace(url,'')
      $.facebox.reveal($(target).clone().show(), klass)

    // image
    } else if (href.match($.facebox.settings.imageTypesRegexp)) {
      fillFaceboxFromImage(href, klass)
    // ajax
    } else {
      fillFaceboxFromAjax(href, klass)
    }
  }

  function fillFaceboxFromImage(href, klass) {
    var image = new Image()
    image.onload = function() {
      $.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
    }
    image.src = href
  }

  function fillFaceboxFromAjax(href, klass) {
    $.get(href, function(data) { $.facebox.reveal(data, klass) })
  }

  function skipOverlay() {
    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null 
  }

  function showOverlay() {
    if (skipOverlay()) return

    if ($('facebox_overlay').length == 0) 
      $("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')

    $('#facebox_overlay').hide().addClass("facebox_overlayBG")
      .css('opacity', $.facebox.settings.opacity)
      .click(function() { $(document).trigger('close.facebox') })
      .fadeIn(200)
    return false
  }

  function hideOverlay() {
    if (skipOverlay()) return

    $('#facebox_overlay').fadeOut(200, function(){
      $("#facebox_overlay").removeClass("facebox_overlayBG")
      $("#facebox_overlay").addClass("facebox_hide") 
      $("#facebox_overlay").remove()
    })
    
    return false
  }
  
  

  /*
   * Bindings
   */

  $(document).bind('close.facebox', function(event) {
    $(document).unbind('keydown.facebox')
    $('#facebox').hide(); //.css("visibility", "hidden");
    //$('#facebox').hide();
    $('#facebox .content').removeClass().addClass('content');
    hideOverlay();
    $('#facebox .loading').remove();
	$('.facebox_video').removeClass('facebox_video');
	$('.facebox_login').removeClass('facebox_login');
	$.facebox.settings.overlay = true;
	$.facebox.settings.opacity = 0;
	$.facebox.settings.top = null;
	event.stopPropagation();
	event.preventDefault();
  });
  
  	$(document).bind("reveal.facebox", function(){
	    $.facebox.settings.width = null;
	    $.facebox.settings.height = null;
	    $.facebox.settings.top = null;
	    $.facebox.settings.left = null;
	});


})(jQuery);



jQuery.popspace_widget = function(input, options) {
	// Create a link to self
	var me = this;

	// Create jQuery object for input element
	var input_elm = jQuery(input).attr("autocomplete", "off");

	// Apply inputClass if necessary
	if (options.inputClass) input_elm.addClass(options.inputClass);

	// Create results
	var results = jQuery('#' + options.resultsClass).get(0) //document.createElement("div");
	// Create jQuery object for results
	var results_div = jQuery('#' + options.resultsClass);

	input.autocompleter = me;

	var timeout = null;
	var prev = "";
	var active = -1;
	var cache = {};
	var keyb = false;
	var hasFocus = false;
	var lastKeyPressCode = null;

	// flush cache
	function flushCache(){
		cache = {};
		cache.data = {};
		cache.length = 0;
	};

	// flush cache
	flushCache();

	// if there is a data array supplied
	if( options.data != null ){
		var sFirstChar = "", stMatchSets = {}, row = [];

		// no url was specified, we need to adjust the cache length to make sure it fits the local data store
		if( typeof options.url != "string" ) options.cacheLength = 1;

		// loop through the array and create a lookup structure
		for( var i=0; i < options.data.length; i++ ){
			// if row is a string, make an array otherwise just reference the array
			row = ((typeof options.data[i] == "string") ? [options.data[i]] : options.data[i]);

			// if the length is zero, don't add to list
			if( row[0].length > 0 ){
				// get the first character
				sFirstChar = row[0].substring(0, 1).toLowerCase();
				// if no lookup array for this character exists, look it up now
				if( !stMatchSets[sFirstChar] ) stMatchSets[sFirstChar] = [];
				// if the match is a string
				stMatchSets[sFirstChar].push(row);
			}
		}

		// add the data items to the cache
		for( var k in stMatchSets ){
			// increase the cache size
			options.cacheLength++;
			// add to the cache
			addToCache(k, stMatchSets[k]);
		}
	}

	input_elm
	.keydown(function(e) {
		// track last key pressed
		lastKeyPressCode = e.keyCode;
		switch(e.keyCode) {
			case 38: // up
				e.preventDefault();
				moveSelect(-1);
				break;
			case 40: // down
				e.preventDefault();
				moveSelect(1);
				break;
			case 9:  // tab
			case 13: // return
				if( selectCurrent() ){
					// make sure to blur off the current field
					input_elm.get(0).blur();
					e.preventDefault();
				}
				break;
			default:
				active = -1;
				if (timeout) clearTimeout(timeout);
				timeout = setTimeout(function(){onChange();}, options.delay);
				break;
		}
	})
	.focus(function(){
		// track whether the field has focus, we shouldn't process any results if the field no longer has focus
		hasFocus = true;
	})
	.blur(function() {
		// track whether the field has focus
		hasFocus = false;
	});

	function onChange() {
		// ignore if the following keys are pressed: [del] [shift] [capslock]
		if( lastKeyPressCode == 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32) ) return //results_div.hide();
		var v = input_elm.val();
		if (v == prev) return;
		prev = v;
		if (v.length >= options.minChars) {
			input_elm.addClass(options.loadingClass);
			requestData(v);
		} else {
			input_elm.removeClass(options.loadingClass);
		}
	};

 	function moveSelect(step) {

		var lis = jQuery("li", results);
		if (!lis) return;

		active += step;

		if (active < 0) {
			active = 0;
		} else if (active >= lis.size()) {
			active = lis.size() - 1;
		}

		lis.removeClass("ac_over");

		jQuery(lis[active]).addClass("ac_over");

	};

	function selectCurrent() {
		var li = jQuery("li.ac_over", results)[0];
		if (!li) {
			var jQueryli = jQuery("li", results);
			if (options.selectOnly) {
				if (jQueryli.length == 1) li = jQueryli[0];
			} else if (options.selectFirst) {
				li = jQueryli[0];
			}
		}
		if (li) {
			selectItem(li);
			return true;
		} else {
			return false;
		}
	};

	function selectItem(li) {
		if (!li) {
			li = document.createElement("li");
			li.extra = [];
			li.selectValue = "";
		}
		var v = jQuery.trim(li.selectValue ? li.selectValue : li.innerHTML);
		input.lastSelected = v;
		prev = v;
		if (options.follow_link) 
			window.location = jQuery("a",jQuery(li)).attr('href');
		else
			input_elm.val(v);
		if (options.onItemSelect) setTimeout(function() { options.onItemSelect(li) }, 1);
	};

	// selects a portion of the input string
	function createSelection(start, end){
		// get a reference to the input element
		var field = input_elm.get(0);
		if( field.createTextRange ){
			var selRange = field.createTextRange();
			selRange.collapse(true);
			selRange.moveStart("character", start);
			selRange.moveEnd("character", end);
			selRange.select();
		} else if( field.setSelectionRange ){
			field.setSelectionRange(start, end);
		} else {
			if( field.selectionStart ){
				field.selectionStart = start;
				field.selectionEnd = end;
			}
		}
		field.focus();
	};

	// fills in the input box w/the first match (assumed to be the best match)
	function autoFill(sValue){
		// if the last user key pressed was backspace, don't autofill
		if( lastKeyPressCode != 8 ){
			// fill in the value (keep the case the user has typed)
			input_elm.val(input_elm.val() + sValue.substring(prev.length));
			// select the portion of the value not typed by the user (so the next character will erase)
			createSelection(prev.length, sValue.length);
		}
	};

	function showResults() {
		// get the position of the input field right now (in case the DOM is shifted)
		var pos = findPos(input);
		// either use the specified width, or autocalculate based on form element
		var iWidth = (options.width > 0) ? options.width : input_elm.width();
		// reposition
	/*
		results_div.css({
			width: parseInt(iWidth) + "px",
			top: (pos.y + input.offsetHeight) + "px",
			left: pos.x + "px"
		}).show();
	*/
	};

	function hideResults() {
		if (timeout) clearTimeout(timeout);
		timeout = setTimeout(hideResultsNow, 200);
	};

	function hideResultsNow() {
		if (timeout) clearTimeout(timeout);
		input_elm.removeClass(options.loadingClass);
		if (results_div.is(":visible")) {
			results_div.hide();
		}
		if (options.mustMatch) {
			var v = input_elm.val();
			if (v != input.lastSelected) {
				selectItem(null);
			}
		}
	};

	function receiveData(q, data) {
		if (data) {
			input_elm.removeClass(options.loadingClass);
			results.innerHTML = "";
			results.appendChild(dataToDom(data));
			// autofill in the complete box w/the first match as long as the user hasn't entered in more data
			if (!options.follow_link && data.length)
				if( options.autoFill && (input_elm.val().toLowerCase() == q.toLowerCase()) ) autoFill(data[0][0]);
			//showResults();
		} else {
			//hideResultsNow();
		}
	};

	function parseData(data) {
		if (!data) return null;
		var parsed = [];
		var rows = eval(data); //.split(options.lineSeparator);
		jQuery(rows).each(function(){
			parsed.push([this.name, this.id, this.permalink]);
		})
		return parsed;
	};

	function dataToDom(data) {
		var ul = document.createElement("ul");
		var num = data.length;

		// limited results to a max number
		if( (options.maxItemsToShow > 0) && (options.maxItemsToShow < num) ) num = options.maxItemsToShow;

		for (var i=0; i < num; i++) {
			var row = data[i];
			if (!row) continue;
			var li = document.createElement("li");
			if (options.formatItem) {
				li.innerHTML = options.formatItem(row, i, num);
				li.selectValue = row[0];
			} else {
				li.innerHTML = row[0];
				li.selectValue = row[0];
			}
			var extra = null;
			if (row.length > 1) {
				extra = [];
				for (var j=1; j < row.length; j++) {
					extra[extra.length] = row[j];
				}
			}
			li.extra = extra;
			ul.appendChild(li);
			jQuery(li).hover(
				function() { jQuery("li", ul).removeClass("ac_over"); jQuery(this).addClass("ac_over"); active = jQuery("li", ul).indexOf(jQuery(this).get(0)); },
				function() { jQuery(this).removeClass("ac_over"); }
			)
			if (!options.follow_link)
				jQuery(li).click(function(e) { e.preventDefault(); e.stopPropagation(); selectItem(this) });
		}
		return ul;
	};

	function requestData(q) {
		if (!options.matchCase) q = q.toLowerCase();
		var data = options.cacheLength ? loadFromCache(q) : null;
		// recieve the cached data
		if (data) {
			receiveData(q, data);
		// if an AJAX url has been supplied, try loading the data now
		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
			jQuery.get(makeUrl(q), function(data) {
				data = parseData(data);
				addToCache(q, data);
				receiveData(q, data);
			});
		// if there's been no data found, remove the loading class
		} else {
			input_elm.removeClass(options.loadingClass);
		}
	};

	function makeUrl(q) {
		var url = options.url + "?q=" + encodeURI(q);
		for (var i in options.extraParams) {
			url += "&" + i + "=" + encodeURI(options.extraParams[i]);
		}
		return url;
	};

	function loadFromCache(q) {
		if (!q) return null;
		if (cache.data[q]) return cache.data[q];
		if (options.matchSubset) {
			for (var i = q.length - 1; i >= options.minChars; i--) {
				var qs = q.substr(0, i);
				var c = cache.data[qs];
				if (c) {
					var csub = [];
					for (var j = 0; j < c.length; j++) {
						var x = c[j];
						var x0 = x[0];
						if (matchSubset(x0, q)) {
							csub[csub.length] = x;
						}
					}
					return csub;
				}
			}
		}
		return null;
	};

	function matchSubset(s, sub) {
		if (!options.matchCase) s = s.toLowerCase();
		var i = s.indexOf(sub);
		if (i == -1) return false;
		return i == 0 || options.matchContains;
	};

	this.flushCache = function() {
		flushCache();
	};

	this.setExtraParams = function(p) {
		options.extraParams = p;
	};

	this.findValue = function(){
		var q = input_elm.val();

		if (!options.matchCase) q = q.toLowerCase();
		var data = options.cacheLength ? loadFromCache(q) : null;
		if (data) {
			findValueCallback(q, data);
		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
			jQuery.get(makeUrl(q), function(data) {
				data = parseData(data)
				addToCache(q, data);
				findValueCallback(q, data);
			});
		} else {
			// no matches
			findValueCallback(q, null);
		}
	}

	function findValueCallback(q, data){
		if (data) input_elm.removeClass(options.loadingClass);

		var num = (data) ? data.length : 0;
		var li = null;

		for (var i=0; i < num; i++) {
			var row = data[i];

			if( row[0].toLowerCase() == q.toLowerCase() ){
				li = document.createElement("li");
				if (options.formatItem) {
					li.innerHTML = options.formatItem(row, i, num);
					li.selectValue = row[0];
				} else {
					li.innerHTML = row[0];
					li.selectValue = row[0];
				}
				var extra = null;
				if( row.length > 1 ){
					extra = [];
					for (var j=1; j < row.length; j++) {
						extra[extra.length] = row[j];
					}
				}
				li.extra = extra;
			}
		}

		if( options.onFindValue ) setTimeout(function() { options.onFindValue(li) }, 1);
	}

	function addToCache(q, data) {
		if (!data || !q || !options.cacheLength) return;
		if (!cache.length || cache.length > options.cacheLength) {
			flushCache();
			cache.length++;
		} else if (!cache[q]) {
			cache.length++;
		}
		cache.data[q] = data;
	};

	function findPos(obj) {
		var curleft = obj.offsetLeft || 0;
		var curtop = obj.offsetTop || 0;
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
		return {x:curleft,y:curtop};
	}
}

jQuery.fn.popspace_widget = function(url, options, data) {
	// Make sure options exists
	options = options || {};
	// Set url as option
	options.url = url;
	// set some bulk local data
	options.data = ((typeof data == "object") && (data.constructor == Array)) ? data : null;
	// Set default values for required options
	options.inputClass = options.inputClass || "ac_input";
	options.resultsClass = options.resultsClass || "popspace_results";
	options.lineSeparator = options.lineSeparator || "\n";
	options.cellSeparator = options.cellSeparator || "|";
	options.minChars = options.minChars || 1;
	options.delay = options.delay || 400;
	options.matchCase = options.matchCase || 0;
	options.matchSubset = options.matchSubset || 1;
	options.matchContains = options.matchContains || 1;
	options.cacheLength = options.cacheLength || 1;
	options.mustMatch = options.mustMatch || 0;
	options.extraParams = options.extraParams || {};
	options.loadingClass = options.loadingClass || "ac_loading";
	options.selectFirst = options.selectFirst || false;
	options.selectOnly = options.selectOnly || false;
	options.maxItemsToShow = options.maxItemsToShow || -1;
	options.autoFill = options.autoFill || false;
	options.width = parseInt(options.width, 10) || 0;
	options.follow_link = options.follow_link || false;
	this.each(function() {
		var input = this;
		new jQuery.popspace_widget(input, options);
	});

	// Don't break the chain
	return this;
}

jQuery.fn.autocompleteArray = function(data, options) {
	return this.popspace_widget(null, options, data);
}

jQuery.fn.indexOf = function(e){
	for( var i=0; i<this.length; i++ ){
		if( this[i] == e ) return i;
	}
	return -1;
};



// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

if (this.loadFirebugConsole){
	loadFirebugConsole();
} else {
	console = {log: function(){}}
}
var logged_in;

jQuery(document).ready(function(){
    logged_in = typeof(login_url) == "undefined";

	jQuery('img').live('error', onImageError);
	// $(".shadow").dropShadow({
	//     	left: 1,
	//     	top: 1,
	//     	opacity: .1,
	//     	blur: 0
	//   	});

	//jQuery('a.thickbox').thickbox();
	
	imgLoader = new Image();// preload image
	imgLoader.src = tb_pathToImage;
	jQuery("form:not('.no_magic')").submitMagic();

	jQuery('#menubar li').hoverIntent({
		interval: 50,
		over: function(){
			jQuery('div.submenu',this).show();
			$(this).addClass("over");
		},
		out: function(){
			jQuery('div.submenu',this).hide();
			$(this).removeClass("over")
		}
	});
	
	// when hovering over not originally selected t1, add class "lost_focus" to t1
	var t2_panels = $('#news_menu_right div.t2_panel');
	var selected_t1 = $('#news_menu_left li.selected');
	if (selected_t1.size() > 0) selected_t1_id = selected_t1.attr('id');
	$('#news_menu_left a').mouseenter(function(){
		var li = $(this).parent();
		$('#news_menu_left li.current').toggleClass("current");
		if (selected_t1_id == li.attr("id")) {
			li.removeClass("lost_focus");
		} else {
			selected_t1.addClass("lost_focus");
		}
		li.toggleClass("current");
	   	t2_panels.removeClass("selected");
	   	$("#" + li.attr("id") + "_t2").addClass("selected");
	});
	$('#news_menu').mouseleave(function(){
		$('#news_menu_left li.current').removeClass("current");
	    if (selected_t1_id) {
			selected_t1.removeClass("lost_focus");
	        t2_panels.removeClass("selected");
	        $('#' + selected_t1_id + "_t2").addClass("selected");
	    }
	});
	if ($('#menubar #news_menu').size() > 0) {
	    $('#bookmarks_menuitem').hoverIntent({
	        interval: 50,
    		over: function(){
    			jQuery('#news_menu').show();
    			$(this).addClass("over");
    		},
    		out: function(){
    			jQuery('#news_menu').hide();
    			$(this).removeClass("over")
    		}
	    })
	}
	
    if (jQuery.browser.msie) {
        if (parseInt(jQuery.browser.version) < 7) {
            // If we need to store more in cookies to be accessed client side, move this up...
            jQuery.cookie = function(name, value, options) {
                if (typeof value != 'undefined') { // name and value given, set cookie
                    options = options || {};
                    if (value === null) {
                        value = '';
                        options.expires = -1;
                    }
                    var expires = '';
                    if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
                        var date;
                        if (typeof options.expires == 'number') {
                            date = new Date();
                            date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
                        } else {
                            date = options.expires;
                        }
                        expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
                    }
                    var path = options.path ? '; path=' + (options.path) : '';
                    var domain = options.domain ? '; domain=' + (options.domain) : '';
                    var secure = options.secure ? '; secure' : '';
                    document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
                } else { // only name given, get cookie
                    var cookieValue = null;
                    if (document.cookie && document.cookie != '') {
                        var cookies = document.cookie.split(';');
                        for (var i = 0; i < cookies.length; i++) {
                            var cookie = jQuery.trim(cookies[i]);
                            // Does this cookie string begin with the name we want?
                            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                                break;
                            }
                        }
                    }
                    return cookieValue;
                }
            };
            var warned, html;
            warned = jQuery.cookie('warned');
            if (warned) return;
            jQuery.cookie('warned', true, {expires: 1});
            var html = "<div id=\"ie6msg\">";
            html += '<h3>You Really Need To Upgrade Your Browser</h3>';
            html += "<p>To get the best possible experience using Showpopr, we recommend that you upgrade your browser.</p>"
            html += "<p>We like <strong><a href=\"http://getfirefox.com\" target=\"_blank\">Firefox</a></strong> and <strong><a href=\"http://www.apple.com/safari/download/\" target=\"_blank\">Safari</a></strong>.</p>";
            html += "<p>The current version of Internet Explorer is <a href=\"http://www.microsoft.com/windows/downloads/ie/getitnow.mspx\" target=\"_blank\">7</a> or <a href=\"http://www.microsoft.com/windows/internet-explorer/default.aspx\" target=\"_blank\">8</a>. The upgrade is free. We encourage you to stop using IE6 and try a more secure and Web Standards-friendly browser.</p>";
            html += "<p><strong><a href=\"#\" onclick=\"$('#why_upgrade').slideToggle();return false;\">Why upgrade?</a></strong></p>"
            html += "<div id=\"why_upgrade\" style=\"display:none\">";
            html += "<ul>";
            html += "<li>Microsoft stopped developing IE6 in 2006.</li>";
            html += "<li>IE6 is full of security holes.</li>";
            html += "<li>It's holding back progress on the Internet.</li>";
            html += "</ul>";
            html += "<p>Read more about why you should upgrade <a href=\"http://www.stoplivinginthepast.com/why-upgrade/\" target=\"_blank\">here</a>.</p>"
            html += "</div>"
            html += "</div>";
            jQuery.facebox(html);
        }
    }
	
	// jQuery('#menu_top > ul > li.selected a').wrap('<div class="tick"></div>');
	SiteSearch.init();
    // AddMenu.init();
    // Feedback.init();
			
	jQuery.ajaxSetup({
		complete: function(){show_submit_buttons();}
	});
		
	Tabs.init();
})

// this works with client side validation, to make sure that the submit button reappears if errors are found
function check_for_submit() {
	show_submit_buttons();
}

function show_submit_buttons() {
	//jQuery('.progress').fadeOutAndRemove(3000);
	if (jQuery.browser.msie)
		jQuery('span.progress').fadeOutAndRemove(2000);
	else
		jQuery("form").removeClass("show_progress");
	//show_progress(jQuery('form'));
	//jQuery('form').removeClass('show_progress')
	jQuery('button[type=submit],input[type=submit],input[type=button]').attr("disabled", false);
}

//the purpose of the setTimeout is to allow for multiple submit buttons - if the button is disabled then its value doesnt get posted
jQuery.fn.submitMagic = function(){
	var selector = 'button[type=submit], input[type=button], input[type=submit]';
	jQuery(selector).removeAttr("disabled");
	this.each(function(){
		// if (!jQuery.browser.msie)
		// 	jQuery(selector, this)
		// 		.after('<span class="progress" title="Submitting form, please wait."></span>')
		if (!($(this).hasClass("no_magic"))) {
    		jQuery(selector, this)
    		.click(function(){
    			clicked = this;
    			// jQuery(clicked).show_progress();
    			setTimeout("disable_submit_buttons()",20);
    		})
		}
		// jQuery(this).bind("submit",function(){
		// });
	});
	return this;
}

function show_progress(obj) {
	if (jQuery.browser.msie) {
		// jQuery('span.progress').remove();
		jQuery(obj).after('<span class="progress" title="Submitting form, please wait."></span>');
	} else {
		jQuery(obj).parents("form").addClass("show_progress");
	}
}

function hide_progress(obj){
	
}

function disable_submit_buttons(){
	jQuery(clicked).attr("disabled",true);
	clicked = null;
}

jQuery.fn.show_progress = function() {
	if (this[0] === window) return;
	this.each(function(){
		if (this.tagName == "A")
			jQuery(this).addClass("progress");
		else {
			show_progress(this);
			clicked = this
			setTimeout("disable_submit_buttons()",100);
		}
	});
	return this;
}

jQuery.fn.hide_progress = function(){
	if (this[0] === window) return;
	this.each(function(){
		if (this.tagName == "A")
			jQuery(this).removeClass("progress");
		else 
		jQuery("button[@type=submit], input[@type=submit]").removeAttr("disabled").parents("form").removeClass("show_progress");
	});
	return this;
}

// Feedback = {
//  init: function(){
//      jQuery('#dashboard_feedback').click(Feedback.load_feedback_form);
//  },
//  load_feedback_form: function() {
//      var link = jQuery(this);
//      if (jQuery('#feedback_holder').size() == 0) {
//          link.show_progress();
//          jQuery('body').append('<div id="feedback_holder" style="display:none"></div>');
//          jQuery.get("/feedback?date=" + (new Date()).getTime(), function(data){
//              jQuery('#feedback_holder').html(data).slideDown()
//              jQuery('#feedback_form form').submitMagic().bind("submit",Feedback.submit_form)
//              link.hide_progress();
//          });
//      }
//      return false;
//  },
//  submit_form: function(){
//      // jQuery('#feedback_progress').show();
//      // jQuery('#feedback_form input[type=submit]').hide();
//      var params = jQuery('#feedback_form form').serialize();
//      jQuery.post("/feedback", params, function(data){eval(data)});
//      return false;
//  },
//  hide_form: function() {
//      // jQuery('#feedback_progress').hide();
//      jQuery('#feedback_status').show();
//      setTimeout("jQuery('#feedback_holder').slideUpAndRemove()", 2000)
//  }
// }

SiteSearch = {
	init: function() {
	    $('#site_search_toggle').click(SiteSearch.show_submenu);
		SiteSearch.submenu = jQuery('#site_search ul');
		jQuery('#site_search a:not("#site_search_toggle")').click(SiteSearch.submit_form);
	},
	show_submenu: function() {
		if (SiteSearch.submenu.css("display") == "block") {
			jQuery("body").unbind("click", SiteSearch.show_submenu);
			SiteSearch.submenu.hide();
			jQuery(this).removeClass("open");
		} else {
			SiteSearch.submenu.show();
			jQuery('body').bind("click", SiteSearch.show_submenu)
			jQuery(this).addClass("open");
		}
		return false;
	},
	submit_form: function() {
	    var q = $('#site_search_q').val();
	    if (q == "Search Showpopr" || !q || q == "") return false;
		window.location = "/search/" + this.className + "/?q=" + encodeURIComponent(q);
		return false;
	},
	focus_on_search_box: function(){
		jQuery(this).hide();
		jQuery('#site_search_q').focus();
	},
	check_invalid_chars: function() {
		if (this.value.indexOf("/") != -1)
			this.value = this.value.replace(/\//gi,"")
	}
}

// AddMenu = {
//  init: function() {
//      AddMenu.submenu = jQuery('#add_menu ul');
//      jQuery('#add_toggle').click(AddMenu.show_submenu);
//      jQuery('#add_submenu a').click(AddMenu.open_link);
//  },
//  show_submenu: function() {
//      if (AddMenu.submenu.css("display") == "block") {
//          jQuery("body").unbind("click", AddMenu.show_submenu);
//          AddMenu.submenu.hide();
//          jQuery(this).removeClass("open");
//      } else {
//          AddMenu.submenu.show();
//          jQuery('body').bind("click", AddMenu.show_submenu)
//          jQuery(this).addClass("open");
//      }
//      return false;
//  },
//  open_link: function(){
//      window.location = this.href;
//  }
// }

Comment = {
	init_comment_form: function(){
		jQuery('#comment_form > form').submit(Comment.submit_comment);
		jQuery('#comment_form form p:first').before("<textarea name='comment[comment]' id='comment_comment'></textarea>");
		jQuery('#comment_comment').charCounter(500);
		// jQuery('#comments a.login_required').click(Comment.login_overlay);
		jQuery("a.add_comment").click(Comment.toggle_form);
	},
	init_inline_comment_form: function(id){
		jQuery('#' + id + ' form').submit(Comment.submit_comment);
		jQuery('#' + id + ' form p:first').before("<input name='comment[comment]' class='comment_input' value='Add a comment' onfocus='if (this.value == \"Add a comment\") this.value = \"\";' onblur='if (this.value == \"\") this.value = \"Add a comment\"' />");
	},
	toggle_form: function(){
		var form = jQuery('#comment_form');
		form.slideToggle();
		window.scrollTo(0,form.get(0).offsetTop)
		return false;
	},
	submit_comment: function(){
		jQueryform = jQuery(this);
		var params = jQueryform.serialize();
		jQuery.post(this.action, params, function(data){ eval(data) });
		return false;
	},
	pop: function(id, action) {
		Comment.do_request(Comment.get_params(1, id, action));
		return false;
	},
	drop: function(id, action) {
		Comment.do_request(Comment.get_params(2, id, action));
		return false;
	},
	do_request: function(params) {
		jQuery.post("/votes", params, function(data){
			eval(data);
		})
	},
	get_params: function(vote_type, id, action) {
		return { 	authenticity_token: jQuery('#comment_' + id + ' input[name="authenticity_token"]').val(), 
			       	id: id,
					what: "Comment",
					vote_type: vote_type,
					a: action
				};
	},
	
	flag_submit: function(){
		var params = { 	authenticity_token: jQuery('#flag_form input[name="authenticity_token"]').val(), 
			       		id: jQuery('#flag_form input[name="id"]').val(),
						what: "Comment",
						a: jQuery('#flag_form input[name="a"]').val(),
						vote_type: jQuery('#flag_form input[name="vote_type"]').val(),
						message: jQuery('#flag_form #message').val()
				};
		Comment.do_request(params);
		return false;
	},
	start_edit: function(id, obj){
		var form = jQuery('#comment_' + id + "_edit_area");
		if (form.html().length == 0)
			form.load(obj.href, function(){
				var text = jQuery("#comment_" + id + "_text")
				text.hide();
				jQuery('#comment_' + id + ' div.edit_form form').submit(function(){
					var comment = jQuery('input[name="comment[comment]"]', this);
					if (comment.val() != text.html()){
						var params = jQuery(this).serializeArray();
						jQuery.post(this.action, params, function(response){
							text.html(response)
							text.show();
							form.slideUp();
						});
					}
					return false;
				});
			});
		else {
			jQuery("#comment_" + id + "_text").hide();
			form.slideDown();
		}
		return false;
	},
	cancel_edit: function(id){
		var id = jQuery('#comment_' + id + '_edit_area').slideUp();
		jQuery("#comment_" + id + "_text").show();
		return false;
	},
	end_edit: function(id){
		jQuery('#comment_' + id + ' p.edit').slideUpAndRemove();
		jQuery('#comment_' + id + ' div.edit_form').slideUpAndRemove();
		jQuery('#comment_' + id + '_text').show();
	}
}

Login = {
	// close: function(){
	// 	jQuery('#login_form').fadeOut("fast");
	// 	jQuery('#app_menu').fadeIn("fast");
	// },
	// toggle: function(){
	// 	var jQuerylogin = jQuery('#login_form');
	// 	if (jQuerylogin.css("display") == "none") {
	// 		jQuerylogin.fadeIn("fast");
	// 	} else {
	// 		jQuerylogin.fadeOut("fast");
	// 	}
	// 	jQuerylogin = null;
	// 	return false;
	// },
	build_html: function(){
        var html = "<h2>Login and start popping today...</h2>";
        html += "<div id='facebox_login'>";
        html += "<a href='/forgot_password' class='forgot_password'>Forgot your password?</a>";
	    html += "<form method=\"post\" action=\"\">";
	    html += "<span id=\"login_up\">";
	    html += "<label for=\"username\">Username or Email</label>";
	    html += "<input type=\"text\" id=\"username\" name=\"username\" value=\"\" />";
	    html += "<label for=\"password\">Password</label>";
	    html += "<input type=\"password\" name=\"password\" id=\"password\" value=\"\" />";
	    html += "</span>";
	    html += "<label for=\"remember_me\"><input id=\"remember_me\" name=\"remember_me\" class=\"checkbox\" type=\"checkbox\" value=\"1\" /><span class=\"remember\">Remember me on this computer</span></label>";
	    html += "<input type=\"submit\" class=\"submit\" value=\"Go\" />";
	    html += "</form>";
        html += "</div>";
        html += "<a href='/signup' class='join'><span>Or, signup now</span><img src='/images/buttons/signup_button.jpg' /></a>";
        html += "<div class='clear'></div>";
		Login.html = html;
	},
	show_form: function(){
        $.facebox.settings.top = $(Login.el).offset().top;
        $.facebox.settings.login = true;
		$.facebox(Login.html);
		$('#username').focus();
	},
	init: function(action){
		if (!logged_in) {
			if (!action) action = login_url
	        // if the login form is not present then somebody clicked a login required link before the 
	        // page was loaded, and they were already logged in.
			if (Login.html) {
				Login.show_form();
			} else {
				Login.build_html();
				Login.show_form();
			}
			$('#facebox_login form').attr("action", "/login?return_to=" + encodeURIComponent(action))
			
		} else {
			return false;
		}
	}

}

function show_recaptcha(element, apikey) {
  Recaptcha.create(apikey, element, {
        theme: "white",
        tabindex: 0
  });
}

jQuery.fn.overlay = function(o) {
	options = o || {};
	options.text = options.text || "login";
	options.show_links = typeof(options.show_links) == "undefined" ? true : options.show_links
	return jQuery(this).each(function(){
	    if (options.text == "login") {
			Login.el = this;
			Login.init(options.login_url);
	    } else {
            jQuery.facebox(options.text)
	    }

		return false;
	});
}

jQuery.fn.fadeOutAndRemove = function(){
	return this.each(function(){
		jQuery(this).fadeOut("slow",function(){jQuery(this).remove()});
	});
}

jQuery.fn.slideUpAndRemove = function(){
	return this.each(function(){
		jQuery(this).slideUp("slow",function(){jQuery(this).remove()});
	});
}

jQuery.fn.reset = function(){
	this.each(function(){ this.reset() });
}

jQuery.fn.topic_selector = function(o){
	o = o || {}
	o.max_size = o.max_size || jQuery('input',this).size()
  	this.each(function(){
		jQuery('input',this).click(function(){
			jQueryself = jQuery(this);
		  	if (jQuery('table.topic_selector input:checked').size() < o.max_size) {
		    	jQueryself.parent().toggleClass("selected");
		  	} else {
		  	  this.checked = false;
		  	  jQuery(this).parent().removeClass("selected");
		  	}
		    jQueryself = null;
		});
	})
}

showFacebox = function(url){
	$.facebox(function(){
		$.get(url, function(data){
			$.facebox(data);
		});
	});
}

videoFacebox = function(embed_code, title){
	$.facebox.settings.overlay = true
	$.facebox.settings.opacity = .7
	$.facebox.settings.video = true;
	$.facebox("<h2>" + title + "</h2>" + embed_code);
}

show_video_inline = function(url) {
	$.facebox.settings.overlay = true
	$.facebox.settings.opacity = .7
	$.facebox.settings.video = true;
	url += url.indexOf("?") != -1 ? "&amp;" : "?"
	url += "width=480&amp;height=380"
    // tb_show(null, url, false);
    // jQuery('#TB_window').addClass("videobox")
	$.facebox(function(){
		$.get(url, function(data){
			$.facebox(data);
		});
	});
	return false;
}



Share = {
	friends_url: null,
	init: function(){
		jQuery('#TB_ajaxContent #share form').submitMagic();
		jQuery('#email_it').hide();
		jQuery('#share_tabs li').click(Share.toggle_tab);
		jQuery('#share_select').click(Share.toggle_checkboxes);
		jQuery.get(Share.friends_url, function(html){
			jQuery('#share_friends').html(html)
			// if (jQuery('#share_friends li').size() > 3)
			// 	jQuery('#share_friends ul').jcarousel({
			//         	scroll: 1
			//     });
			jQuery('#share_friends label').bind("mouseup",Share.toggle_checkbox);
			jQuery('#share_filter').keyup(Share.friend_filter);
		});
		jQuery('#share form').submit(Share.submit_form);
		jQuery('#email_add').click(Share.add_email_input);
		jQuery('#share_mail a').each(Share.fix_mailto);
		jQuery('#share_message_toggle').click(Share.toggle_share_message_text);
		var msg = $('#share_message').html().replace("><br", "><span id='share_message_personal' style='display:'none'></span><br");
		$('#share_message').html(msg);
		$('#email_text').bind("keyup", Share.update_preview);
	  
	},
	update_preview: function(){
	    if (this.value.length > 0) {
      	  $('#share_message_personal').html(this.value).show().css({display:"block", paddingTop:"1em"});  
	    } else {
	        $('#share_message_personal').html('').hide();
	    }
	},
	show_window: function(url, obj) {
	    if (logged_in)  {
            $.facebox.settings.width = 542;
            $.facebox.settings.height = 361;
			showFacebox(url);
	    } else {
		    $(obj).parents("div").overlay({});
	    }
	    return false;
	},
	submit_form: function(){
		var jQueryform = jQuery(this);
		if (jQuery('#share_text', this).size() > 0) {
			if (jQuery('input:checked', this).size() == 0) {
				jQuery('div.notice').remove();
				setTimeout("show_submit_buttons()",100);
				jQueryform.prepend('<div class="notice">Please select some friends with whom to share this story.</div>');
				return false;
			}
		} else {
			var emails = 0;
			jQuery('input.email_address').each(function(){
				if (this.value.length > 0)
					emails += 1;
			});
			if (emails == 0) {
				jQuery('label.error').remove();
				jQueryform.prepend('<div class="notice">Oops! You have not entered any email addresses.</div>');
				setTimeout("show_submit_buttons()",100);
				return false;
			}
		}
		jQuery.post(this.action, jQuery(this).serialize(), function(data){ eval(data) });
		return false;
	},
	toggle_tab: function(){
		jQuery('#share_tabs li.current').removeClass("current");
		jQuery(this).addClass("current");
		var tab = jQuery('a',this).attr("className");
		jQuery('#share div.tab').hide();
		jQuery('#' + tab).show();
		if (tab == "email_it")
			jQuery('#share_mail').show();
		else
			jQuery('#share_mail').hide();
		return false;
	},
	toggle_checkbox: function(){
		jQuery(this).toggleClass("selected");
	},
	toggle_checkboxes: function(){
		var obj = jQuery(this);
		if (obj.text() == "select all") {
			jQuery('#share_friends input[type="checkbox"]').attr("checked", true);
			jQuery('#share_friends label').addClass("selected");
			obj.text('deselect all');
		} else {
			jQuery('#share_friends input[type="checkbox"]').removeAttr("checked");
			jQuery('#share_friends label').removeClass("selected");
			obj.text('select all');
		}
		return false;
	},
	friend_filter: function(){
		jQuery('#share_friends label').hide();
		jQuery('#share_friends label span:contains("' + this.value + '")').parents("label").show();
	},
	add_email_input: function(){
		var size = $('#email_inputs input').size();
		if (size < 6) {
			$('#email_inputs span').append('<input type="text" class="email_address" name="emails[' + size + ']" />');
			if (size == 5)
				$(this).fadeOut();
		} else {
		}
		return false
	},
	fix_mailto: function(){
		var href = this.href.replace("mailto:?subject=", "").split("&body=");
		var body = escape(href[1]);
		body = body.replace(/@@@/gi,"%0D%0A%0D%0A");
		this.href = "mailto:?subject=" + escape(href[0]) + "&body=" + body;
	},
	toggle_share_message_text: function() {
		jQuery('#share_message').slideToggle();
		return false;
	},
	reset_email_form: function() {
		jQuery('input.email_address').val('');
		show_submit_buttons();
	},
	reset_share_form: function(){
		jQuery('input:checked').removeAttr("checked");
		jQuery('label.selected').removeClass("selected");
		setTimeout("jQuery(\"div.notice\").fadeOutAndRemove()", 3000);
		show_submit_buttons();
	}
}

function truncate_words(trunc,len){
	if (trunc.length > len) {
	    trunc = trunc.substring(0, len);
	    trunc = trunc.replace(/\w+jQuery/, '');
		trunc += "&hellip;"
	}
	return trunc;
}

Ads = {
	trigger: function(target_id){
		setTimeout("Ads.copy_ad(" + target_id + ")", 500);
	},
	copy_ad: function(target_id){
		var ad_block = jQuery('#' + target_id + '_temp');
		jQuery('#' + target_id).html(ad_block.html());
		ad_block.html('');
	}
}

Tabs = {
    init: function(){
        jQuery('div.module_top h2 a').bind("click", Tabs.change_tab);
        jQuery('div.module_top a.expander').bind("click", Tabs.toggle);
    },
    get_module: function(obj){
      return jQuery(obj).parents("div.module");  
    },
    toggle: function(){
        var module = Tabs.get_module(this);
        if (module.hasClass("module_closed")) {
            module.removeClass("module_closed").find("div.module_content").show();
            jQuery(this).html("&ndash;");
        } else {
            module.addClass("module_closed").find("div.module_content").hide();
            jQuery(this).html("+");
        }
        return false;
    },
    change_tab: function(){
        var tab_name = this.href.split("#")[1],
            module = Tabs.get_module(this);
        jQuery("div.module_top h2 a", module).removeClass("selected");
        jQuery("div.module_tab_panel", module).removeClass("selected");
		jQuery("a.see_more_link", module).removeClass("selected");
        jQuery("#" + tab_name).addClass("selected");
        jQuery(this).toggleClass("selected");
		jQuery("#" + tab_name + "_link").addClass("selected")
        return false;
    }
}


onImageError = function(){
        this.src = "/images/common/blank.gif";
        this.alt = ""
        jQuery(this).unbind("error", onImageError);
        return true;	
}

function popWin(url, width, height, options)
{
	var w = (width) ? width : 400;
	var h = (height) ? height : 400;

	var t = (screen.height) ? (screen.height - h) / 2 : 0;
	var l =	 (screen.width) ? (screen.width - w) / 2 : 0;

	var opt = (options) ? options : 'toolbar = no, location = no, directories = no, '+
		'status = yes, menubar = no, scrollbars = yes, copyhistory = no, resizable = yes';

	var popped = window.open(url, 'popupwindow',
		'top = '+t+', left = '+l+', width = '+w+', height = '+h+',' + opt);

	popped.focus();
}

/* Based on Alex Arnell's inheritance implementation. */
// var Class = {
//   create: function() {
//     var parent = null, properties = $A(arguments);
//     if (Object.isFunction(properties[0]))
//       parent = properties.shift();
// 
//     function klass() {
//       this.initialize.apply(this, arguments);
//     }
// 
//     Object.extend(klass, Class.Methods);
//     klass.superclass = parent;
//     klass.subclasses = [];
// 
//     if (parent) {
//       var subclass = function() { };
//       subclass.prototype = parent.prototype;
//       klass.prototype = new subclass;
//       parent.subclasses.push(klass);
//     }
// 
//     for (var i = 0; i < properties.length; i++)
//       klass.addMethods(properties[i]);
// 
//     if (!klass.prototype.initialize)
//       klass.prototype.initialize = Prototype.emptyFunction;
// 
//     klass.prototype.constructor = klass;
// 
//     return klass;
//   }
// };
// 
// Class.Methods = {
//   addMethods: function(source) {
//     var ancestor   = this.superclass && this.superclass.prototype;
//     var properties = Object.keys(source);
// 
//     if (!Object.keys({ toString: true }).length)
//       properties.push("toString", "valueOf");
// 
//     for (var i = 0, length = properties.length; i < length; i++) {
//       var property = properties[i], value = source[property];
//       if (ancestor && Object.isFunction(value) &&
//           value.argumentNames().first() == "$super") {
//         var method = value;
//         value = (function(m) {
//           return function() { return ancestor[m].apply(this, arguments) };
//         })(property).wrap(method);
// 
//         value.valueOf = method.valueOf.bind(method);
//         value.toString = method.toString.bind(method);
//       }
//       this.prototype[property] = value;
//     }
// 
//     return this;
//   }
// };
// 
// var Abstract = { };
// 
// Object.extend = function(destination, source) {
//   for (var property in source)
//     destination[property] = source[property];
//   return destination;
// };
// 
// Object.extend(Object, {
//   inspect: function(object) {
//     try {
//       if (Object.isUndefined(object)) return 'undefined';
//       if (object === null) return 'null';
//       return object.inspect ? object.inspect() : String(object);
//     } catch (e) {
//       if (e instanceof RangeError) return '...';
//       throw e;
//     }
//   },
// 
//   toJSON: function(object) {
//     var type = typeof object;
//     switch (type) {
//       case 'undefined':
//       case 'function':
//       case 'unknown': return;
//       case 'boolean': return object.toString();
//     }
// 
//     if (object === null) return 'null';
//     if (object.toJSON) return object.toJSON();
//     if (Object.isElement(object)) return;
// 
//     var results = [];
//     for (var property in object) {
//       var value = Object.toJSON(object[property]);
//       if (!Object.isUndefined(value))
//         results.push(property.toJSON() + ': ' + value);
//     }
// 
//     return '{' + results.join(', ') + '}';
//   },
// 
//   keys: function(object) {
//     var keys = [];
//     for (var property in object)
//       keys.push(property);
//     return keys;
//   },
// 
//   values: function(object) {
//     var values = [];
//     for (var property in object)
//       values.push(object[property]);
//     return values;
//   },
// 
//   clone: function(object) {
//     return Object.extend({ }, object);
//   },
// 
//   isElement: function(object) {
//     return !!(object && object.nodeType == 1);
//   },
// 
//   isArray: function(object) {
//     return object != null && typeof object == "object" &&
//       'splice' in object && 'join' in object;
//   },
// 
//   isFunction: function(object) {
//     return typeof object == "function";
//   },
// 
//   isString: function(object) {
//     return typeof object == "string";
//   },
// 
//   isNumber: function(object) {
//     return typeof object == "number";
//   },
// 
//   isUndefined: function(object) {
//     return typeof object == "undefined";
//   }
// });
// 
// Object.extend(Function.prototype, {
//   bind: function() {
//     if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
//     var __method = this, args = $A(arguments), object = args.shift();
//     return function() {
//       return __method.apply(object, args.concat($A(arguments)));
//     }
//   }
// });
// 
// function $A(iterable) {
//   if (!iterable) return [];
//   if (iterable.toArray) return iterable.toArray();
//   var length = iterable.length || 0, results = new Array(length);
//   while (length--) results[length] = iterable[length];
//   return results;
// }
// 
// if ($.browser.safari) {
//   $A = function(iterable) {
//     if (!iterable) return [];
//     // In Safari, only use the `toArray` method if it's not a NodeList.
//     // A NodeList is a function, has an function `item` property, and a numeric
//     // `length` property. Adapted from Google Doctype.
//     if (!(typeof iterable === 'function' && typeof iterable.length ===
//         'number' && typeof iterable.item === 'function') && iterable.toArray)
//       return iterable.toArray();
//     var length = iterable.length || 0, results = new Array(length);
//     while (length--) results[length] = iterable[length];
//     return results;
//   };
// }

toolbar_player = function(id){
  if ($('#toolbar_player').size() == 0) {
    $('body').append('<div id="toolbar_player"></div>');
  }
  $('#toolbar_player').html($.fn.flash.transform({width:200, height:18, src: '/swf/player.swf', flashvars:{file: '/promo/play/' + id, autostart: "true", type: 'video'}, wmode: 'transparent'}));
}

set_bonus_tracks_mailto = function(){
	$('#contact_us a').attr("href", "mailto:bonustracks@showpopr.com?Subject=Get%20me%20on%20Bonus%20Tracks");
}

Top10Widget = {
	init: function(){
		jQuery('#top10_stories').each(function(){
			//Top10Widget.render_most_viewed();
			jQuery('#most_viewed').click(Top10Widget.render_most_viewed);
			jQuery('#most_shared').click(Top10Widget.render_most_shared);
			jQuery('#top_keywords').click(Top10Widget.render_top_keywords);		
		})
	},
	render: function(list, tab){
		var html = "";
		var count = 1;
		if (list.msg) {
			html = list.msg;
		} else {
			jQuery(list).each(function(){
				var link = "/" + this.permalink;
				var li = "<li><span class='rank'>" + count++ + ".</span><a href='" + link + "'>" + this.name + "</a></li>";
				html += li;
			});
		}
		tab.html(html);
	},
	render_most_viewed: function(){
		var tab = jQuery('#most_viewed_list'), link = this;
		if (!tab.html()){
			jQuery.getJSON("/api/stories/most_viewed?time=" + (new Date()).getTime(), function(data){
				Top10Widget.render(data, tab);
				Top10Widget.make_this_current(link, tab);
			});
		} else {
			if (typeof(this.init) != "function"){
				Top10Widget.make_this_current(this, tab);
			}
		}
		return false;
	},
	render_most_shared: function(){
		var tab = jQuery('#most_shared_list'), link = this;
		if (!tab.html()){
			jQuery.getJSON("/api/stories/most_shared?time=" + (new Date()).getTime(), function(data){
				Top10Widget.render(data, tab);
				Top10Widget.make_this_current(link, tab);
			});
		} else {
			Top10Widget.make_this_current(this, tab);
		}
		return false;
	},
	render_top_keywords: function(){
		var tab = jQuery('#top_keywords_list'), link = this;
		if (!tab.html()){
			jQuery.getJSON("/api/stories/top_keywords?time=" + (new Date()).getTime(), function(data){
				var html = "";
				if (data.msg) {
					html = data.msg;
				} else {
					var count = 1;
					jQuery(data).each(function(){
						html += "<li><span class='rank'>" + count++ + ".</span><a href='/search/?q=" + this.term + "'>" + this.term + "</a></li>"
					});
					html = "<ul>" + html + "</ul>";
				}
				tab.html(html);
				Top10Widget.make_this_current(link, tab);
			});
		} else {
			Top10Widget.make_this_current(link, tab);
		}
		return false;
	},
	make_this_current: function(obj, tab){
		jQuery('#top10_stories ul.tabs li a').removeClass("current")
		jQuery(obj).addClass("current")
		obj = null
    	jQuery('#top10_stories_content div').hide();
		tab.show();
	}
}

jQuery(document).ready(Top10Widget.init)

LeadersWidget = {
	init: function(){
		jQuery('#point_leaders').each(function(){
			jQuery('#current_leaders').click(LeadersWidget.render_current_leaders);
			jQuery('#last_leaders').click(LeadersWidget.render_last_leaders);
			jQuery('#overall_leaders').click(LeadersWidget.render_overall_leaders);		
		})
	},
	render: function(list, tag){
		var html = "<ol>";
		var count = 1;
		jQuery(list).each(function(){
			var link = "/" + this.username;
			var li = "<li><span class='points'>" + this.points + "</span><span class='rank'>" + count++ + ".</span><a href='" + link + "'><img width='18' height='18' src='" + this.avatar + "'/>" + this.name + "</a></li>";
			html += li;
		});
		html += "</ol>";
		jQuery(tag).html(html);
	},
	render_current_leaders: function(){
	  var tab = $('#current_leaders_list');
	  var link = this;
	  if (!tab.html()) {
  		jQuery.getJSON("/api/stories/point_leaders_current?time=" + (new Date()).getTime(), function(data){
  			LeadersWidget.render(data, '#current_leaders_list');
    		LeadersWidget.make_this_current(link, tab);
  		});
	  } else {
  		if (typeof(this.init) != "function")
  			LeadersWidget.make_this_current(link, tab);
	  }
		return false;
	},
	render_last_leaders: function(){
	  var tab = $('#last_leaders_list');
	  var link = this;
	  if (!tab.html()) {
  		jQuery.getJSON("/api/stories/point_leaders_winners?time=" + (new Date()).getTime(), function(data){
  			LeadersWidget.render(data, '#last_leaders_list');
    		LeadersWidget.make_this_current(link, tab);
  		});
	  } else {
  		LeadersWidget.make_this_current(link, tab);
	  }
		return false;
	},
	render_overall_leaders: function(){
	  var tab = $('#overall_leaders_list');
	  var link = this;
	  if (!tab.html()){
  		jQuery.getJSON("/api/stories/point_leaders_overall?time=" + (new Date()).getTime(), function(data){
  			LeadersWidget.render(data, '#overall_leaders_list');
    		LeadersWidget.make_this_current(link, tab);
  		});
	  } else {
  		LeadersWidget.make_this_current(link, tab);
	  }
		return false;
	},
	make_this_current: function(obj, tab){
		jQuery('#point_leaders ul.tabs li a').removeClass("current");
		jQuery(obj).addClass("current");
		obj = null;
    	jQuery('#point_leaders_content div').hide();
		tab.show();
    // if (LeadersWidget.mask) {
    //   LeadersWidget.mask.close();
    // }
		return false;
	},
	mask: null
}

jQuery(document).ready(LeadersWidget.init)


/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 3/9/2009
 * @author Ariel Flesler
 * @version 1.4.1
 *
 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
 */
;(function($){var m=$.scrollTo=function(b,h,f){$(window).scrollTo(b,h,f)};m.defaults={axis:'xy',duration:parseFloat($.fn.jquery)>=1.3?0:1};m.window=function(b){return $(window).scrollable()};$.fn.scrollable=function(){return this.map(function(){var b=this,h=!b.nodeName||$.inArray(b.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!h)return b;var f=(b.contentWindow||b).document||b.ownerDocument||b;return $.browser.safari||f.compatMode=='BackCompat'?f.body:f.documentElement})};$.fn.scrollTo=function(l,j,a){if(typeof j=='object'){a=j;j=0}if(typeof a=='function')a={onAfter:a};if(l=='max')l=9e9;a=$.extend({},m.defaults,a);j=j||a.speed||a.duration;a.queue=a.queue&&a.axis.length>1;if(a.queue)j/=2;a.offset=n(a.offset);a.over=n(a.over);return this.scrollable().each(function(){var k=this,o=$(k),d=l,p,g={},q=o.is('html,body');switch(typeof d){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px)?$/.test(d)){d=n(d);break}d=$(d,this);case'object':if(d.is||d.style)p=(d=$(d)).offset()}$.each(a.axis.split(''),function(b,h){var f=h=='x'?'Left':'Top',i=f.toLowerCase(),c='scroll'+f,r=k[c],s=h=='x'?'Width':'Height';if(p){g[c]=p[i]+(q?0:r-o.offset()[i]);if(a.margin){g[c]-=parseInt(d.css('margin'+f))||0;g[c]-=parseInt(d.css('border'+f+'Width'))||0}g[c]+=a.offset[i]||0;if(a.over[i])g[c]+=d[s.toLowerCase()]()*a.over[i]}else g[c]=d[i];if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],u(s));if(!b&&a.queue){if(r!=g[c])t(a.onAfterFirst);delete g[c]}});t(a.onAfter);function t(b){o.animate(g,j,a.easing,b&&function(){b.call(this,l,a)})};function u(b){var h='scroll'+b;if(!q)return k[h];var f='client'+b,i=k.ownerDocument.documentElement,c=k.ownerDocument.body;return Math.max(i[h],c[h])-Math.min(i[f],c[f])}}).end()};function n(b){return typeof b=='object'?b:{top:b,left:b}}})(jQuery);

/*
	VERSION: Drop Shadow jQuery Plugin 1.6  12-13-2007

	REQUIRES: jquery.js (1.2.6 or later)

	SYNTAX: $(selector).dropShadow(options);  // Creates new drop shadows
					$(selector).redrawShadow();       // Redraws shadows on elements
					$(selector).removeShadow();       // Removes shadows from elements
					$(selector).shadowId();           // Returns an existing shadow's ID

	OPTIONS:

		left    : integer (default = 4)
		top     : integer (default = 4)
		blur    : integer (default = 2)
		opacity : decimal (default = 0.5)
		color   : string (default = "black")
		swap    : boolean (default = false)

	The left and top parameters specify the distance and direction, in	pixels, to
	offset the shadow. Zero values position the shadow directly behind the element.
	Positive values shift the shadow to the right and down, while negative values 
	shift the shadow to the left and up.
	
	The blur parameter specifies the spread, or dispersion, of the shadow. Zero 
	produces a sharp shadow, one or two produces a normal shadow, and	three or four
	produces a softer shadow. Higher values increase the processing load.
	
	The opacity parameter	should be a decimal value, usually less than one. You can
	use a value	higher than one in special situations, e.g. with extreme blurring. 
	
	Color is specified in the usual manner, with a color name or hex value. The
	color parameter	does not apply with transparent images.
	
	The swap parameter reverses the stacking order of the original and the shadow.
	This can be used for special effects, like an embossed or engraved look.

	EXPLANATION:
	
	This jQuery plug-in adds soft drop shadows behind page elements. It is only
	intended for adding a few drop shadows to mostly stationary objects, like a
	page heading, a photo, or content containers.

	The shadows it creates are not bound to the original elements, so they won't
	move or change size automatically if the original elements change. A window
	resize event listener is assigned, which should re-align the shadows in many
	cases, but if the elements otherwise move or resize you will have to handle
	those events manually. Shadows can be redrawn with the redrawShadow() method
	or removed with the removeShadow() method. The redrawShadow() method uses the
	same options used to create the original shadow. If you want to change the
	options, you should remove the shadow first and then create a new shadow.
	
	The dropShadow method returns a jQuery collection of the new shadow(s). If
	further manipulation is required, you can store it in a variable like this:

		var myShadow = $("#myElement").dropShadow();

	You can also read the ID of the shadow from the original element at a later
	time. To get a shadow's ID, either read the shadowId attribute of the
	original element or call the shadowId() method. For example:

		var myShadowId = $("#myElement").attr("shadowId");  or
		var myShadowId = $("#myElement").shadowId();

	If the original element does not already have an ID assigned, a random ID will
	be generated for the shadow. However, if the original does have an ID, the 
	shadow's ID will be the original ID and "_dropShadow". For example, if the
	element's ID is "myElement", the shadow's ID would be "myElement_dropShadow".

	If you have a long piece of text and the user resizes the	window so that the
	text wraps or unwraps, the shape of the text changes and the words are no
	longer in the same positions. In that case, you can either preset the height
	and width, so that it becomes a fixed box, or you can shadow each word
	separately, like this:

		<h1><span>Your</span> <span>Page</span> <span>Title</span></h1>

		$("h1 span").dropShadow();

	The dropShadow method attempts to determine whether the selected elements have
	transparent backgrounds. If you want to shadow the content inside an element,
	like text or a transparent image, it must not have a background-color or
	background-image style. If the element has a solid background it will create a
	rectangular	shadow around the outside box.

	The shadow elements are positioned absolutely one layer below the original 
	element, which is positioned relatively (unless it's already absolute).

	*** All shadows have the "dropShadow" class, for selecting with CSS or jQuery.

	ISSUES:
	
		1)	Limited styling of shadowed elements by ID. Because IDs must be unique,
				and the shadows have their own ID, styles applied by ID won't transfer
				to the shadows. Instead, style elements by class or use inline styles.
		2)	Sometimes shadows don't align properly. Elements may need to be wrapped
				in container elements, margins or floats changed, etc. or you may just 
				have to tweak the left and top offsets to get them to align. For example,
				with draggable objects, you have to wrap them inside two divs. Make the 
				outer div draggable and set the inner div's position to relative. Then 
				you can create a shadow on the element inside the inner div.
		3)	If the user changes font sizes it will throw the shadows off. Browsers 
				do not expose an event for font size changes. The only known way to 
				detect a user font size change is to embed an invisible text element and
				then continuously poll for changes in size.
		4)	Safari support is shaky, and may require even more tweaks/wrappers, etc.
		
		The bottom line is that this is a gimick effect, not PFM, and if you push it
		too hard or expect it to work in every possible situation on every browser,
		you will be disappointed. Use it sparingly, and don't use it for anything 
		critical. Otherwise, have fun with it!
				
	AUTHOR: Larry Stevens (McLars@eyebulb.com) This work is in the public domain,
					and it is not supported in any way. Use it at your own risk.
*/


(function($){

	var dropShadowZindex = 1;  //z-index counter

	$.fn.dropShadow = function(options)
	{
		// Default options
		var opt = $.extend({
			left: 4,
			top: 4,
			blur: 2,
			opacity: .5,
			color: "black",
			swap: false
			}, options);
		var jShadows = $([]);  //empty jQuery collection
		
		// Loop through original elements
		this.not(".dropShadow").each(function()
		{
			var jthis = $(this);
			var shadows = [];
			var blur = (opt.blur <= 0) ? 0 : opt.blur;
			var opacity = (blur == 0) ? opt.opacity : opt.opacity / (blur * 8);
			var zOriginal = (opt.swap) ? dropShadowZindex : dropShadowZindex + 1;
			var zShadow = (opt.swap) ? dropShadowZindex + 1 : dropShadowZindex;
			
			// Create ID for shadow
			var shadowId;
			if (this.id) {
				shadowId = this.id + "_dropShadow";
			}
			else {
				shadowId = "ds" + (1 + Math.floor(9999 * Math.random()));
			}

			// Modify original element
			$.data(this, "shadowId", shadowId); //store id in expando
			$.data(this, "shadowOptions", options); //store options in expando
			jthis
				.attr("shadowId", shadowId)
				.css("zIndex", zOriginal);
			if (jthis.css("position") != "absolute") {
				jthis.css({
					position: "relative",
					zoom: 1 //for IE layout
				});
			}

			// Create first shadow layer
			bgColor = jthis.css("backgroundColor");
			if (bgColor == "rgba(0, 0, 0, 0)") bgColor = "transparent";  //Safari
			if (bgColor != "transparent" || jthis.css("backgroundImage") != "none" 
					|| this.nodeName == "SELECT" 
					|| this.nodeName == "INPUT"
					|| this.nodeName == "TEXTAREA") {		
				shadows[0] = $("<div></div>")
					.css("background", opt.color);								
			}
			else {
				shadows[0] = jthis
					.clone()
					.removeAttr("id")
					.removeAttr("name")
					.removeAttr("shadowId")
					.css("color", opt.color);
			}
			shadows[0]
				.addClass("dropShadow")
				.css({
					height: jthis.outerHeight(),
					left: blur,
					opacity: opacity,
					position: "absolute",
					top: blur,
					width: jthis.outerWidth(),
					zIndex: zShadow
				});
				
			// Create other shadow layers
			var layers = (8 * blur) + 1;
			for (i = 1; i < layers; i++) {
				shadows[i] = shadows[0].clone();
			}

			// Position layers
			var i = 1;			
			var j = blur;
			while (j > 0) {
				shadows[i].css({left: j * 2, top: 0});           //top
				shadows[i + 1].css({left: j * 4, top: j * 2});   //right
				shadows[i + 2].css({left: j * 2, top: j * 4});   //bottom
				shadows[i + 3].css({left: 0, top: j * 2});       //left
				shadows[i + 4].css({left: j * 3, top: j});       //top-right
				shadows[i + 5].css({left: j * 3, top: j * 3});   //bottom-right
				shadows[i + 6].css({left: j, top: j * 3});       //bottom-left
				shadows[i + 7].css({left: j, top: j});           //top-left
				i += 8;
				j--;
			}

			// Create container
			var divShadow = $("<div></div>")
				.attr("id", shadowId) 
				.addClass("dropShadow")
				.css({
					left: jthis.position().left + opt.left - blur,
					marginTop: jthis.css("marginTop"),
					marginRight: jthis.css("marginRight"),
					marginBottom: jthis.css("marginBottom"),
					marginLeft: jthis.css("marginLeft"),
					position: "absolute",
					top: jthis.position().top + opt.top - blur,
					zIndex: zShadow
				});

			// Add layers to container	
			for (i = 0; i < layers; i++) {
				divShadow.append(shadows[i]);
			}
			
			// Add container to DOM
			jthis.after(divShadow);

			// Add shadow to return set
			jShadows = jShadows.add(divShadow);

			// Re-align shadow on window resize
			$(window).resize(function()
			{
				try {
					divShadow.css({
						left: jthis.position().left + opt.left - blur,
						top: jthis.position().top + opt.top - blur
					});
				}
				catch(e){}
			});
			
			// Increment z-index counter
			dropShadowZindex += 2;

		});  //end each
		
		return this.pushStack(jShadows);
	};


	$.fn.redrawShadow = function()
	{
		// Remove existing shadows
		this.removeShadow();
		
		// Draw new shadows
		return this.each(function()
		{
			var shadowOptions = $.data(this, "shadowOptions");
			$(this).dropShadow(shadowOptions);
		});
	};


	$.fn.removeShadow = function()
	{
		return this.each(function()
		{
			var shadowId = $(this).shadowId();
			$("div#" + shadowId).remove();
		});
	};


	$.fn.shadowId = function()
	{
		return $.data(this[0], "shadowId");
	};


	$(function()  
	{
		// Suppress printing of shadows
		var noPrint = "<style type='text/css' media='print'>";
		noPrint += ".dropShadow{visibility:hidden;}</style>";
		$("head").append(noPrint);
	});

})(jQuery);