
function console_log(l) {
	if(typeof console != 'undefined')
		console.log(l);
};


jQuery.fn.inputFocus = function() {

	this.bind('focus', function() {
		var t = $(this);
		if (t.val() == t.attr('title')) {
			t.val('');
			t.removeClass("empty");
		}

		window.inputHasFocus = true;
	}).bind('blur', function() {
		var t = $(this);
		if (t.val() == "") {
			t.val(t.attr('title'));
			t.addClass("empty");
		}

		window.inputHasFocus = false;
	});

	return this;
};


$(document).ready(function(){
    $(".forwardForm").click(function() {
		 if ($("#"+$(this).attr("id")+'-form').is(":hidden")) {
		 	$("#"+$(this).attr("id")+'-form').slideDown("slow");
      	} else {
		 	$("#"+$(this).attr("id")+'-form').slideUp("slow");
      }
      });


    $(".forward-link").click(function() {
	 if ($("#"+$(this).attr("id")+'-form').is(":hidden")) {
		 	$("#"+$(this).attr("id")+'-form').slideDown("slow");
      	} else {
		 	$("#"+$(this).attr("id")+'-form').slideUp("slow");
      }
      return false;
      });

	$('#commentform').submit(function() {
		return inputValidation();
	});

	// debug
	var debug = $('#debug');
	if(debug.length > 0) {
		var toggleDebug = $('<a href="">debug</a>').click(function() {
			debug.toggle();
			return false;
		});
		$('#signinout p:eq(0)').append(' [').append(toggleDebug).append(']');
	}

});


function attachCommentForm(commentId, rgt, depth)
{
	$('#commentID').val(commentId);
	$('#parentID').val(rgt);

	if (commentId == '0') {
		$('#cancel-reply').hide();
		$('#comments-form-title').text('Add a comment');
		//$('#comments-add .comment-preview').removeClass().addClass('comment-preview');
	} else {
		$('#cancel-reply').show();
		$('#comments-form-title').text('Reply to '+$('#n'+commentId).text());
		//if(depth > 0) $('#comments-add .comment-preview').addClass('reply'+depth);
	}
	$('#comments-add').insertAfter($('#c'+commentId));
};



function forwardValidation(id)
{
	var validEmail = 0;
	$('#meua-'+id).val(navigator.userAgent);
	var errors = false;
	var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	if (filter.test($('#ForwardEmail'+id).val())) {
		validEmail = 1;
	} else {
		$('#ForwardEmail'+id).addClass('error');
		errors = true;
	}
	if (errors == false) {
		$('#ForwardEmail'+id).removeClass('error');
		return true;
	}
	return false;
};

function inputValidation()
{
	var validName = 0;
	var validEmail = 0;
	var validComments = 0;
	var validPassword = 0;
	var errors = false;
	var userType = $('#userType').val();
	
	$('#meua').val(navigator.userAgent);
	$('#AuthorPassInput').removeClass('error');
	$('#AuthorEmailInput').removeClass('error');
	$('#AuthorNameInput').removeClass('error');
	$('#CommentsInput').removeClass('error');
	
	var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	var passValid = /[\w\s]{3,}/;
	if((userType=='member' || userType=='Anonymous') && passValid.test($('#C_Comments').value)) {
		$('#commentform').attr('action','#'+$('#comments-add').parent().attr('id'));
		return true;
	}
	if($('#LoggedIn').val() == 0) {
		if($('#AuthorName').val() != '') {
			validName = 1;
		}
		if (filter.test($('#AuthorEmail').val())) {
			validEmail = 1;
		}
		if (passValid.test($('#AuthorPass').val())) {
			validPassword = 1;
		}
		if($('#AuthorPassInput').css('display') != 'none' && validPassword == 0) {
			$('#AuthorPassInput').addClass('error');
			errors = true;
		}
		if ($('#AuthorNameInput').css('display') != 'none' && validName == 0) {
			$('#AuthorNameInput').addClass('error');
			errors = true;
		}
		if (validEmail == 0) {
			$('#AuthorEmailInput').addClass('error');
			errors = true;
		}
	}
	if (passValid.test($('#C_Comments').val())) {
		validComments = 1;
	}
	if (validComments == 0) {
		$('#CommentsInput').addClass('error');
		errors = true;
	}

	$('#commentform').attr('action','#'+$('#comments-add').parent().attr('id'));

	if (errors == false) {
		return true;
	}
	return false;
};

function previewComments() {
	$('#C_Preview').html($('#C_Comments').val().replace(/\n/g,'<br />'));
};

function makeSlug(str, allow_end_space) {
  var theSlug = '';
	var decodedSlug = '';
	theSlug = str.substring(0,255);
	theSlug = theSlug.toLowerCase();
	for (var n = 0; n < theSlug.length; n++) {
		var c = theSlug.charCodeAt(n);
		if (c <= 127) {
			decodedSlug += String.fromCharCode(c);
		}
		if ((c >=224 && c <=229) || (c>=192 && c<=198) || (c>=281 && c<=286)) {
			decodedSlug += 'a';
		} else if ((c >=232 && c<=235) || (c>=200 && c<=203)) {
			decodedSlug += 'e';
		} else if ((c>=236 && c<=239) || (c>=204 && c<=207)) {
			decodedSlug += 'i';
		} else if ((c>=242 && c<=248) || (c>=210 && c<=216)) {
			decodedSlug += 'o';
		} else if ((c>=249 && c<=252) || (c>=217 && c<=220)) {
			decodedSlug += 'u';
		} else if (c==253 || c==255 || c==221 || c==376) {
			decodedSlug += 'y';
		} else if (c==230 || c==198) {
			decodedSlug += 'ae';
		} else if (c==338 || c==339) {
			decodedSlug += 'oe';
		} else if (c==199 || c==231) {
			decodedSlug += 'c';
		} else if (c==209 || c==241) {
			decodedSlug += 'n';
		} else if (c==352 || c==353) {
			decodedSlug += 's';
		} else if (c==208 || c==240) {
			decodedSlug += 'eth';
		} else if (c==223) {
			decodedSlug += 'sz';
          } else if ((c>=8219 && c<=8223) || c==8242 || c==8243 || c==8216 || c==8217 || c==168 || c==180 || c==729 || c==733) {
              //all the strange curly single and double quotes
		} else if  (c>127) {
			decodedSlug += '-';
		}
	}
	theSlug = decodedSlug;
	theSlug = theSlug.replace(/\'/gi, '');
	theSlug = theSlug.replace(/&/gi, '-and-');
	theSlug = theSlug.replace(/[^a-zA-Z0-9\-]/gi,'-');
	theSlug = theSlug.replace(/\-+/gi, '-');
	if (allow_end_space == undefined) {
  	theSlug = theSlug.replace(/\-$/gi, '');
  }
	theSlug = theSlug.replace(/^\-/gi, '');
	return theSlug;
}

function swapTab(arg) {
  $('#commenterrors').hide();
	$('#commentType').val(arg);
	$('#userType').val(arg);
	if (arg == 'Email') {
		$('#AuthorNameInput').show();
		$('#AuthorURLInput').show();
		$('#AuthorPassInput').hide();
		$('#AuthorEmailInput').show();
		$('#AuthorNotifyHeading').show();
		$('#AuthorNotifyInput').show();
		$('#tabEmail').removeClass().addClass('chosen');
		$('#tabPass').removeClass();
		$('#tabAnonymous').removeClass();
		$('#N_Preview').text(($('#AuthorName').val()==''?'Your Name':$('#AuthorName').val()));
	} else if (arg == 'Pass') {
		$('#AuthorNameInput').hide();
		$('#AuthorURLInput').show();
		$('#AuthorPassInput').show();
		$('#AuthorEmailInput').show();
		$('#AuthorNotifyHeading').show();
		$('#AuthorNotifyInput').show();
		$('#tabEmail').removeClass();
		$('#tabPass').removeClass().addClass('chosen');
		$('#tabAnonymous').removeClass();
		$('#N_Preview').text((window.userName ?'Your Name':window.userName));
	} else {
		$('#AuthorNameInput').hide();
		$('#AuthorURLInput').hide();
		$('#AuthorPassInput').hide();
		$('#AuthorEmailInput').hide();
		$('#AuthorNotifyHeading').hide();
		$('#AuthorNotifyInput').hide();
		$('#tabEmail').removeClass();
		$('#tabPass').removeClass();
		$('#tabAnonymous').removeClass().addClass('chosen');
		$('#N_Preview').text('Anonymous');
	}
};


$(document).ready(function() {
	// navigation
	var navItems = [];
	var superCategory = null;
	$('#menu li').each(function(i, n) {
			n = $(n);
			if(n.hasClass('super-selected'))
				superCategory = n;

			n.hover( function() {
					$.each(navItems,function(i, e) {
						e.removeClass('nav-active')
						clearTimeout(e.navTimeout);
					});
					navItems = [];
					$('#menu li').removeClass('super-selected');
					n.addClass('nav-active');
					$('#alphaindex').hide();
			},
			function() {
					if(n.hasClass('parent')) {
							n.navTimeout = setTimeout(function() {
								n.removeClass('nav-active');
								if(superCategory)
									superCategory.addClass('super-selected');
								$('#alphaindex').show();
							}, 1500);
							navItems[navItems.length++] = n;
					} else {
							n.removeClass('nav-active');
					}
			});
	});

	$('.tabs').tabs();

	$('#q').inputFocus();
});

var MemberToolbar = (function() {

    /* private attributes */
    var toolbar;
	var message;
	var emailPanel;
	var emailButton;
	var sharePanel;
	var shareButton;

	var forwardLink;

	/* private methods */
    var init = function() {

        toolbar = $('#member-toolbar');
		message = $('p.message',toolbar);
		emailPanel = $('#email-slide-out',toolbar);
		emailButton = $('#email-it',toolbar);
		sharePanel = $('#share-slide-out',toolbar);
		shareButton = $('#share-it',toolbar);

		//EVENTS
		emailButton.click(function(event){
			if(emailButton.hasClass('active')) {
				_hideEmail();
				_showMessage();
			} else {
				_hideMessage();
				_hideShare();
				_showEmail();
			}
			event.preventDefault();
		});

		shareButton.click(function(event){
			if(shareButton.hasClass('active')) {
				_hideShare();
				_showMessage();
			} else {
				_hideMessage();
				_hideEmail();
				_showShare();
			}
			event.preventDefault();
		});

		forwardLink = $('a.submit',emailPanel).click(function(event){
			_sendEmail();
			event.preventDefault();
		});
		$('a.cancel',emailPanel).click(function(event){
			_hideEmail();
			_showMessage();
			event.preventDefault();	
		});
		$('li > a',sharePanel).click(function(event){
			_sharePage($(event.target).parents('a')); //for some reason the target is not the anchor, but the img inside
			event.preventDefault();
		});
		$('a.cancel',sharePanel).click(function(event){
			_hideShare();
			_showMessage();
			event.preventDefault();
		});
		$('input[name=ForwardTo]',emailPanel).bind('keyup',function(event){
			if(event.keyCode == 13) {
				$('a.submit',emailPanel).click();
				event.preventDefault();
			}
		});
	};

    var _showMessage = function() {
		message.fadeIn({duration:1000});
    };

	var _hideMessage = function() {
		message.fadeOut({duration:100});
	};

	var _showEmail = function() {
		emailButton.addClass('active');
		emailPanel.css({left:emailButton.position().left+emailButton.outerWidth()+7});
		emailPanel.animate({
			width: "435px",
			opacity: 1
		},200,function(){
			$('input[name=ForwardTo]',emailPanel)[0].focus();
		});
	};

	var _hideEmail = function() {
		emailButton.removeClass('active');
		emailPanel.animate({
			width: "0",
			opacity: 0
		},200);
	};

	var _showShare = function() {
		shareButton.addClass('active');
		sharePanel.css({left:shareButton.position().left+shareButton.outerWidth()+7});
		sharePanel.animate({
			width: "400px",
			opacity: 1
		},200);
	};

	var _hideShare = function() {
		shareButton.removeClass('active');
		sharePanel.animate({
			width: "0",
			opacity: 0
		},200);
	};

	var _sendEmail = function() {

		if(!window.forwardValidation('slice'))
			return;

		forwardLink.text('Sending...');
		$.ajax({
			url:_getFormInput('FullURL'),
			type:'POST',
			dataType:'text',
			async:true,
			data:{
				ForwardTo:_getFormInput('ForwardTo'),
				emailAddress:_getFormInput('emailAddress'),
				formtype:_getFormInput('formtype'),
				meua:_getFormInput('meua'),
				FullURL:_getFormInput('FullURL'),
				id:_getFormInput('id'),
				Type:_getFormInput('Type'),
				Slug:_getFormInput('Slug'),
				Value:_getFormInput('Value'),
				action:_getFormInput('action'),
				ajax:'true'
			},
			complete:function() {
				forwardLink.text('SUCCESS!');
				setTimeout(function(){forwardLink.text('Forward');},5000);
				$('input[name=ForwardTo]',emailPanel).val('')[0].focus();
			}
		});
	};

	var _getFormInput = function(name){
		var formInput = $('input[name='+name+']',emailPanel);
		return formInput.length > 0?formInput.val():'';
	};

	var _sharePage = function($target) {
		var id = _getFormInput('id').replace(/emailed-/, 'shared-');
		var Slug = _getFormInput('Slug');
		var Type = _getFormInput('Type');
		var Value = $target.attr('title');

		//news isn't typeable
		//if(id == '') id = 'news';
		
		$('div',sharePanel).empty().append('<label>Just a moment while we load '+Value+'...</label>');
		_addTag(id,Slug,Type,Value,function(){
			window.location = $target.attr('href');
		});
	};

	var _displayConfirmation = function() {
		//don't know what to do for this yet...
	};

	var _addTag = function(id,Slug,Type,Value,callback) {
		$.ajax({
			url:'/members/add-tag/',
			type:'GET',
			dataType:'text',
			async:true,
			data:{
				id:id,
				Type:Type,
				Slug:Slug,
				Value:Value,
				ajax:'true'
			},
			complete:function() {
				callback();
			}
		});
	};

	/* initialize singleton */
    $(document).ready( function() {
        init();
    });


    /* public methods */
    return {
        publicFunc : function() {
        }
    };

})();


var EditProfile = (function() {

    /* private attributes */
    var personalLinks;
	var socialNetworks;

	/* private methods */
    var init = function() {

        personalLinks = $('#content .personal-links');
		socialNetworks = $('#content .social-networks');

		$('p > a',personalLinks).click(function(event){
			_addPersonalLink();
			event.preventDefault();
		});

		$('p > a',socialNetworks).click(function(event){
			_addSocialNetwork();
			event.preventDefault();
		});

		$('tbody td > a',personalLinks).click(function(event){
			_removePersonalLink($(event.target));
			event.preventDefault();
		});

		$('tbody td > a',socialNetworks).click(function(event){
			_removeSocialNetwork($(event.target));
			event.preventDefault();
		});

		$('tr',socialNetworks).each(function(i,tr){
			tr = $(tr);
			$('select',tr).click(function(event){
				var $select = $(event.target);
				var helpText = document.socialnetworks[$select.val()];
				$('p.note',tr).text(helpText);
			});
		});


		$('form').submit(function(){
			_pruneEmptyRows();
		});

		$('a.reset-avatar').click(function(event){
			var $this = $(event.target);
			$this.prev().show().prev().hide();
			$this.hide();
			$this.parents("ol").prev().text('Default Avatar:');
			$this.after($('<input type="hidden" name="ResetAvatar" value="true"/>'));
			event.preventDefault();
		});

		_addPersonalLink();
		_addSocialNetwork();
	};

	var _reorderPersonalLinks = function() {
		$('tbody > tr',personalLinks).removeClass('alt').each(function(i){
			var tr = $(this);
			$('input:eq(0)',tr).attr('name','PersonalLinks['+i+'][Title]');
			$('input:eq(1)',tr).attr('name','PersonalLinks['+i+'][ID]');
			$('input:eq(2)',tr).attr('name','PersonalLinks['+i+'][URL]');
		});

		$('tbody > tr:odd',personalLinks).addClass('alt');
	};

	var _reorderSocialNetworks = function() {
		$('tbody > tr',socialNetworks).removeClass('alt').each(function(i){
			var tr = $(this);
			$('select:eq(0)',tr).attr('name','SocialNetworks['+i+'][Network]');
			$('input:eq(0)',tr).attr('name','SocialNetworks['+i+'][ID]');
			$('input:eq(1)',tr).attr('name','SocialNetworks['+i+'][Username]');
		});

		$('tbody > tr:odd',socialNetworks).addClass('alt');
	};

	var _removePersonalLink = function($target) {

		var tr = $target.parents('tr');

		tr.fadeOut(300,function(){
			tr.remove();

			if($('tbody > tr',personalLinks).length == 0)
				_addPersonalLink();

			_reorderPersonalLinks();
		});

	};

	var _removeSocialNetwork = function($target) {

		var tr = $target.parents('tr');

		tr.fadeOut(300,function(){
			tr.remove();

			if($('tbody > tr',socialNetworks).length == 0)
				_addSocialNetwork();

			_reorderSocialNetworks();
		});

	};

	var _addPersonalLink = function() {
		var tbody = $('tbody',personalLinks);

		var tr = $('<tr>').css({display:'none'});

		tr.append($('<td><input class="textfield" type="text" name="" maxlength="254"/><input type="hidden" name="" value="0"/></td>'));
		tr.append($('<td><input class="textfield url" type="text" name="" maxlength="254"/></td>'));
		tr.append($('<td>').append($('<a href="#" title="Remove">Remove</a>').click(function(event){
			_removePersonalLink($(event.target));
			event.preventDefault();
		})));

		tbody.append(tr.fadeIn(300,function(){
			//$('input:first',tr)[0].focus();
		}));

		_reorderPersonalLinks();
	};

	var _addSocialNetwork = function() {
		var tbody = $('tbody',socialNetworks);

		var tr = $('<tr>').css({display:'none'});

		tr.append($('<td valign="top"><select name="" class="textfield"></select><input type="hidden" name="" value="0"/></td>'));
		tr.append($('<td valign="top"><input class="textfield url" type="text" name="" maxlength="254"/><p class="note"></p></td>'));
		tr.append($('<td valign="top"></td>').append($('<a href="#" title="Remove">Remove</a>').click(function(event){
			_removeSocialNetwork($(event.target));
			event.preventDefault();
		})));

		var select = $('select',tr).append('<option value="">Please Select...</option>').click(function(event){
			var $select = $(event.target);
			var helpText = document.socialnetworks[$select.val()];
			$('p.note',tr).text(helpText);
		});
		//var supported = $('#supported-social-networks dt').text().split(',');
		for(var i in document.socialnetworks) {
			select.append('<option value="'+i+'">'+i+'</option>');
		}

		tbody.append(tr.fadeIn(300,function(){
			//$('input:first',tr)[0].focus();
		}));

		_reorderSocialNetworks();
	};

	var _pruneEmptyRows = function() {
		$('tbody > tr',personalLinks).each(function(){
			var tr = $(this);
			if($.trim($('input:eq(0)',tr).val()).length == 0 && $.trim($('input:eq(2)',tr).val()).length == 0)
				tr.remove();
		});

		$('tbody > tr',socialNetworks).each(function(){
			var tr = $(this);
			if($.trim($('select:eq(0)',tr).val()).length == 0 && $.trim($('input:eq(2)',tr).val()).length == 0)
				tr.remove();
		});
	};

	/* initialize singleton */
    $(document).ready( function() {
        init();
    });


    /* public methods */
    return {
        onsubmit : function() {
			_pruneEmptyRows();
		}
    };

})();


/*
 * jQuery UI Effects 1.5
 *
 * Copyright (c) 2008 Aaron Eisenberger (aaronchi@gmail.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 * 
 * http://docs.jquery.com/UI/Effects/
 *
 */
;(function($) {

$.effects = $.effects || {}; //Add the 'effects' scope

$.extend($.effects, {
	save: function(el, set) {
		for(var i=0;i<set.length;i++) {
			if(set[i] !== null) $.data(el[0], "ec.storage."+set[i], el[0].style[set[i]]);
		}
	},
	restore: function(el, set) {
		for(var i=0;i<set.length;i++) {
			if(set[i] !== null) el.css(set[i], $.data(el[0], "ec.storage."+set[i]));
		}
	},
	setMode: function(el, mode) {
		if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
		return mode;
	},
	getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
		// this should be a little more flexible in the future to handle a string & hash
		var y, x;
		switch (origin[0]) {
			case 'top': y = 0; break;
			case 'middle': y = 0.5; break;
			case 'bottom': y = 1; break;
			default: y = origin[0] / original.height;
		};
		switch (origin[1]) {
			case 'left': x = 0; break;
			case 'center': x = 0.5; break;
			case 'right': x = 1; break;
			default: x = origin[1] / original.width;
		};
		return {x: x, y: y};
	},
	createWrapper: function(el) {
		if (el.parent().attr('id') == 'fxWrapper')
			return el;
		var props = {width: el.outerWidth({margin:true}), height: el.outerHeight({margin:true}), 'float': el.css('float')};
		el.wrap('<div id="fxWrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');
		var wrapper = el.parent();
		if (el.css('position') == 'static'){
			wrapper.css({position: 'relative'});
			el.css({position: 'relative'});
		} else {
			var top = parseInt(el.css('top'), 10); if(isNaN(top)) top = 'auto';
			var left = parseInt(el.css('left'), 10); if(isNaN(top)) left = 'auto';
			wrapper.css({ position: el.css('position'), top: top, left: left, zIndex: el.css('z-index') }).show();
			el.css({position: 'relative', top:0, left:0});
		}
		wrapper.css(props);
		return wrapper;
	},
	removeWrapper: function(el) {
		if (el.parent().attr('id') == 'fxWrapper')
			return el.parent().replaceWith(el);
		return el;
	},
	setTransition: function(el, list, factor, val) {
		val = val || {};
		$.each(list,function(i, x){
			unit = el.cssUnit(x);
			if (unit[0] > 0) val[x] = unit[0] * factor + unit[1];
		});
		return val;
	},
	animateClass: function(value, duration, easing, callback) {

		var cb = (typeof easing == "function" ? easing : (callback ? callback : null));
		var ea = (typeof easing == "object" ? easing : null);

		return this.each(function() {

			var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || '';
			if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */
			if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; }

			//Let's get a style offset
			var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
			if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove);
			var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
			if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove);

			// The main function to form the object for animation
			for(var n in newStyle) {
				if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */
				&& n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */
				&& newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */
				&& (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */
				&& (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */
				) offset[n] = newStyle[n];
			}

			that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object
				// Change style attribute back to original. For stupid IE, we need to clear the damn object.
				if(typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr);
				if(value.add) $(this).addClass(value.add); if(value.remove) $(this).removeClass(value.remove);
				if(cb) cb.apply(this, arguments);
			});

		});
	}
});

//Extend the methods of jQuery
$.fn.extend({
	//Save old methods
	_show: $.fn.show,
	_hide: $.fn.hide,
	__toggle: $.fn.toggle,
	_addClass: $.fn.addClass,
	_removeClass: $.fn.removeClass,
	_toggleClass: $.fn.toggleClass,
	// New ec methods
	effect: function(fx,o,speed,callback) {
		return $.effects[fx] ? $.effects[fx].call(this, {method: fx, options: o || {}, duration: speed, callback: callback }) : null;
	},
	show: function() {
		if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])))
			return this._show.apply(this, arguments);
		else {
			var o = arguments[1] || {}; o['mode'] = 'show';
			return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
		}
	},
	hide: function() {
		if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])))
			return this._hide.apply(this, arguments);
		else {
			var o = arguments[1] || {}; o['mode'] = 'hide';
			return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
		}
	},
	toggle: function(){
		if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])) || (arguments[0].constructor == Function))
			return this.__toggle.apply(this, arguments);
		else {
			var o = arguments[1] || {}; o['mode'] = 'toggle';
			return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
		}
	},
	addClass: function(classNames,speed,easing,callback) {
		return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
	},
	removeClass: function(classNames,speed,easing,callback) {
		return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
	},
	toggleClass: function(classNames,speed,easing,callback) {
		return speed ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames);
	},
	morph: function(remove,add,speed,easing,callback) {
		return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
	},
	switchClass: function() {
		return this.morph.apply(this, arguments);
	},
	// helper functions
	cssUnit: function(key) {
		var style = this.css(key), val = [];
		$.each( ['em','px','%','pt'], function(i, unit){
			if(style.indexOf(unit) > 0)
				val = [parseFloat(style), unit];
		});
		return val;
	}
});

/*
 * jQuery Color Animations
 * Copyright 2007 John Resig
 * Released under the MIT and GPL licenses.
 */

// We override the animation for all of these color styles
jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
		jQuery.fx.step[attr] = function(fx){
				if ( fx.state == 0 ) {
						fx.start = getColor( fx.elem, attr );
						fx.end = getRGB( fx.end );
				}

				fx.elem.style[attr] = "rgb(" + [
						Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
						Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
						Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
				].join(",") + ")";
		};
});

// Color Conversion functions from highlightFade
// By Blair Mitchelmore
// http://jquery.offput.ca/highlightFade/

// Parse strings looking for color tuples [255,255,255]
function getRGB(color) {
		var result;

		// Check if we're already dealing with an array of colors
		if ( color && color.constructor == Array && color.length == 3 )
				return color;

		// Look for rgb(num,num,num)
		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
				return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];

		// Look for rgb(num%,num%,num%)
		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
				return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];

		// Look for #a0b1c2
		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
				return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];

		// Look for #fff
		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
				return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];

		// Look for rgba(0, 0, 0, 0) == transparent in Safari 3
		if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
				return colors['transparent'];

		// Otherwise, we're most likely dealing with a named color
		return colors[jQuery.trim(color).toLowerCase()];
}

function getColor(elem, attr) {
		var color;

		do {
				color = jQuery.curCSS(elem, attr);

				// Keep going until we find an element that has color, or we hit the body
				if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") )
						break;

				attr = "backgroundColor";
		} while ( elem = elem.parentNode );

		return getRGB(color);
};

// Some named colors to work with
// From Interface by Stefan Petre
// http://interface.eyecon.ro/

var colors = {
	aqua:[0,255,255],
	azure:[240,255,255],
	beige:[245,245,220],
	black:[0,0,0],
	blue:[0,0,255],
	brown:[165,42,42],
	cyan:[0,255,255],
	darkblue:[0,0,139],
	darkcyan:[0,139,139],
	darkgrey:[169,169,169],
	darkgreen:[0,100,0],
	darkkhaki:[189,183,107],
	darkmagenta:[139,0,139],
	darkolivegreen:[85,107,47],
	darkorange:[255,140,0],
	darkorchid:[153,50,204],
	darkred:[139,0,0],
	darksalmon:[233,150,122],
	darkviolet:[148,0,211],
	fuchsia:[255,0,255],
	gold:[255,215,0],
	green:[0,128,0],
	indigo:[75,0,130],
	khaki:[240,230,140],
	lightblue:[173,216,230],
	lightcyan:[224,255,255],
	lightgreen:[144,238,144],
	lightgrey:[211,211,211],
	lightpink:[255,182,193],
	lightyellow:[255,255,224],
	lime:[0,255,0],
	magenta:[255,0,255],
	maroon:[128,0,0],
	navy:[0,0,128],
	olive:[128,128,0],
	orange:[255,165,0],
	pink:[255,192,203],
	purple:[128,0,128],
	violet:[128,0,128],
	red:[255,0,0],
	silver:[192,192,192],
	white:[255,255,255],
	yellow:[255,255,0],
	transparent: [255,255,255]
};
	
/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2008 George McGinley Smith
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2001 Robert Penner
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
 */

})(jQuery);


/*
 * jQuery UI Effects Highlight
 *
 * Copyright (c) 2008 Aaron Eisenberger (aaronchi@gmail.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 * 
 * http://docs.jquery.com/UI/Effects/Highlight
 *
 * Depends:
 *	effects.core.js
 *
 */
;(function($) {

$.effects.highlight = function(o) {

	return this.queue(function() {
		
		// Create element
		var el = $(this), props = ['backgroundImage','backgroundColor','opacity'];
		
		// Set options
		var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
		var color = o.options.color || "#ffff99"; // Default highlight color
		var oldColor = el.css("backgroundColor");
		
		// Adjust
		$.effects.save(el, props); el.show(); // Save & Show
		el.css({backgroundImage: 'none', backgroundColor: color}); // Shift
		
		// Animation
		var animation = {backgroundColor: oldColor };
		if (mode == "hide") animation['opacity'] = 0;
		
		// Animate
		el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
			if(mode == "hide") el.hide();
			$.effects.restore(el, props);
		if (mode == "show" && jQuery.browser.msie) this.style.removeAttribute('filter'); 
			if(o.callback) o.callback.apply(this, arguments);
			el.dequeue();
		}});
		
	});
	
};

})(jQuery);


/**
 * jQuery.ScrollTo
 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Date: 2/19/2008
 *
 * @projectDescription Easy element scrolling using jQuery.
 * Tested with jQuery 1.2.1. On FF 2.0.0.11, IE 6, Opera 9.22 and Safari 3 beta. on Windows.
 *
 * @author Ariel Flesler
 * @version 1.3.3
 *
 * @id jQuery.scrollTo
 * @id jQuery.fn.scrollTo
 * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
 *	  The different options for target are:
 *		- A number position (will be applied to all axes).
 *		- A string position ('44', '100px', '+=90', etc ) will be applied to all axes
 *		- A jQuery/DOM element ( logically, child of the element to scroll )
 *		- A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
 *		- A hash { top:x, left:y }, x and y can be any kind of number/string like above.
 * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
 * @param {Object} settings Hash of settings, optional.
 *	 @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
 *	 @option {Number} duration The OVERALL length of the animation.
 *	 @option {String} easing The easing method for the animation.
 *	 @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
 *	 @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
 *	 @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
 *	 @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
 *	 @option {Function} onAfter Function to be called after the scrolling ends. 
 *	 @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
 * @return {jQuery} Returns the same jQuery object, for chaining.
 *
 * @example $('div').scrollTo( 340 );
 *
 * @example $('div').scrollTo( '+=340px', { axis:'y' } );
 *
 * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
 *
 * @example var second_child = document.getElementById('container').firstChild.nextSibling;
 *			$('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
 *				alert('scrolled!!');																   
 *			}});
 *
 * @example $('div').scrollTo( { top: 300, left:'+=200' }, { offset:-20 } );
 *
 * Notes:
 *  - jQuery.scrollTo will make the whole window scroll, it accepts the same arguments as jQuery.fn.scrollTo.
 *	- If you are interested in animated anchor navigation, check http://jquery.com/plugins/project/LocalScroll.
 *	- The options margin, offset and over are ignored, if the target is not a jQuery object or a DOM element.
 *	- The option 'queue' won't be taken into account, if only 1 axis is given.
 */
;(function( $ ){

	var $scrollTo = $.scrollTo = function( target, duration, settings ){
		$scrollTo.window().scrollTo( target, duration, settings );
	};

	$scrollTo.defaults = {
		axis:'y',
		duration:1
	};

	//returns the element that needs to be animated to scroll the window
	$scrollTo.window = function(){
		return $( $.browser.safari ? 'body' : 'html' );
	};

	$.fn.scrollTo = function( target, duration, settings ){
		if( typeof duration == 'object' ){
			settings = duration;
			duration = 0;
		}
		settings = $.extend( {}, $scrollTo.defaults, settings );
		duration = duration || settings.speed || settings.duration;//speed is still recognized for backwards compatibility
		settings.queue = settings.queue && settings.axis.length > 1;//make sure the settings are given right
		if( settings.queue )
			duration /= 2;//let's keep the overall speed, the same.
		settings.offset = both( settings.offset );
		settings.over = both( settings.over );

		return this.each(function(){
			var elem = this, $elem = $(elem),
				t = target, toff, attr = {},
				win = $elem.is('html,body');
			switch( typeof t ){
				case 'number'://will pass the regex
				case 'string':
					if( /^([+-]=)?\d+(px)?$/.test(t) ){
						t = both( t );
						break;//we are done
					}
					t = $(t,this);// relative selector, no break!
				case 'object':
					if( t.is || t.style )//DOM/jQuery
						toff = (t = $(t)).offset();//get the real position of the target 
			}
			$.each( settings.axis.split(''), function( i, axis ){
				var Pos	= axis == 'x' ? 'Left' : 'Top',
					pos = Pos.toLowerCase(),
					key = 'scroll' + Pos,
					act = elem[key],
					Dim = axis == 'x' ? 'Width' : 'Height',
					dim = Dim.toLowerCase();

				if( toff ){//jQuery/DOM
					attr[key] = toff[pos] + ( win ? 0 : act - $elem.offset()[pos] );

					if( settings.margin ){//if it's a dom element, reduce the margin
						attr[key] -= parseInt(t.css('margin'+Pos)) || 0;
						attr[key] -= parseInt(t.css('border'+Pos+'Width')) || 0;
					}
					
					attr[key] += settings.offset[pos] || 0;//add/deduct the offset
					
					if( settings.over[pos] )//scroll to a fraction of its width/height
						attr[key] += t[dim]() * settings.over[pos];
				}else
					attr[key] = t[pos];//remove the unnecesary 'px'

				if( /^\d+$/.test(attr[key]) )//number or 'number'
					attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max(Dim) );//check the limits

				if( !i && settings.queue ){//queueing each axis is required					
					if( act != attr[key] )//don't waste time animating, if there's no need.
						animate( settings.onAfterFirst );//intermediate animation
					delete attr[key];//don't animate this axis again in the next iteration.
				}
			});			
			animate( settings.onAfter );			

			function animate( callback ){
				$elem.animate( attr, duration, settings.easing, callback && function(){
					callback.call(this, target);
				});
			};
			function max( Dim ){
				var el = win ? $.browser.opera ? document.body : document.documentElement : elem;
				return el['scroll'+Dim] - el['client'+Dim];
			};
		});
	};

	function both( val ){
		return typeof val == 'object' ? val : { top:val, left:val };
	};

})( jQuery );

