// ================ 
// ! Onload Event   
// ================ 


$(document).ready(function(){
	/* Load global logic (header/footer/nav stuff) */
	global_loader();
	
	var loc = window.location.pathname;
	
	/* If we're on a p3 page */
	if (loc.substr(0,4) == '/p3/') {
		p3_loader();
	}

	/* If we're on a v3 page */
	else if (loc.substr(0,4) == '/v3/') {
		v3_loader();
	}

	/* search page */
	else if (loc.substr(0,8) == '/search/') {
		search_loader();
	}
	/* front page */
	else if (loc == '/' || loc == '/index.php') {
		frontpage_loader();
	}
	/* help pages */
	else if (loc.substr(0, 9) == '/helppgs/') {
		help_loader();
	}
	/* Login Page */
	else if (loc == '/secure/login.php') {
		login_page_loader();
	}
	else if (loc.substr(0,10) == '/checkout/') {
		checkout_loader();
	}
	else if (loc == '/giftcard/balance.php') {
		giftcard_balance_loader();
	}
});

// =========== 
// ! Loaders   
// =========== 

function global_loader() {
	/* Create mouseover and mouseout events for top menu categories. Edit: #h_cslink is the customer service link, we don't want that as a category now. */
	$('.h_navcat').mouseover(function(){
		/* If we have a close menu timer running, terminate it. */
		if (typeof window.closeMenuTimer != 'undefined') clearTimeout(window.closeMenuTimer);
		
		/* Used in open_menu() */
		window.currentMenu = this;
		
		/* If a menu was already open, immediately open the new one. */
		if (close_menus() > 0) open_menu();
		/* If none were open, set timer to open current (prevents accidental menu opening) */
		else window.openMenuTimer = setTimeout('open_menu()', 150);
			
	}).mouseout(function(){
		/* Stop any ticking open timers and start up the close menu timer. */
		clearTimeout(window.openMenuTimer);
		window.closeMenuTimer = setTimeout('close_menus()', 350);
	});
	
	/* over and out events for the top menu drop down box */
	$('.h_navdrop').mouseover(function(){
		if (typeof window.closeMenuTimer != 'undefined') clearTimeout(window.closeMenuTimer);
	}).mouseout(function(){
		window.closeMenuTimer = setTimeout('close_menus()', 350);
	});
	
	/* Bind event handler to search button click. */
	$('#h_search > input[type=image]').click(function(){
		if ($('#h_searchfield').val() == "") {
			//alert('Please enter a search term.');
			$('#h_searchfield').focus();
			return false;
		}
		
		window.location = 'http://www.gifttree.com/search/?q='+encodeURIComponent($('#h_searchfield').val());
	});
		
	/* Catch return keys and send to search button. */
	$('#h_searchfield').keypress(function(ev){
		if (ev.keyCode == 13) $(this).next().click();
	});
	
	/* Create event listener for the footer email signup */
	$('#f_emailoffers > input[type=image]').click(function(){
		var email_field = $(this).prev();
		if (valid_email(email_field.val())) {
			$(this).parent().load('/global/gifttree/ajax_listeners/footer_signup_widget.php?email='+email_field.val());
		}
		else {
			alert('Please enter a valid email.');
			email_field.focus();
		}
	});
	
	/* Catch return keys in footer email signup and send it to the submit button */
	$('#f_emailoffers > input[type=text]').keypress(function(ev){
		if (ev.keyCode == 13) $(this).next().click();
	}).focus(function(){ //remove the placeholder on focus
		if ($(this).val() == 'Special Offers Email') this.value = '';
	});
	
	/* Rollover event for city link in footer: */
	$('#f_citylistlink > a').mouseover(function(){
		if (typeof window.cityMouseTimer != 'undefined') clearTimeout(window.cityMouseTimer);
		
		$('.f_dropdown').hide(); //hide footer dropdowns
		
		$('#f_citylist').show().css({
			top: ($('#f_citylistlink').offset().top - $('#f_citylist').height() - 22),
			right: 0
		});
	}).mouseout(function(){
		window.cityMouseTimer = setTimeout("$('#f_citylist').hide()", 500);
	});
	
	$('#f_citylist').mouseover(function(){
		if (typeof window.cityMouseTimer != 'undefined') clearTimeout(window.cityMouseTimer);
	}).mouseout(function(){
		window.cityMouseTimer = setTimeout("$('#f_citylist').hide()", 500);
	});
	
	/* Rollover for directory link in footer */
	$('#f_directorylistlink > a').mouseover(function(){
		if (typeof window.dirMouseTimer != 'undefined') clearTimeout(window.dirMouseTimer);
		
		$('.f_dropdown').hide(); //hide footer dropdowns
		
		$('#f_directorylist').show().css({
			top: ($('#f_directorylistlink').offset().top - $('#f_directorylist').height() - 22),
			right: '60px'
		});
	}).mouseout(function(){
		window.dirMouseTimer = setTimeout("$('#f_directorylist').hide()", 500);
	});
	
	$('#f_directorylist').mouseover(function(){
		if (typeof window.dirMouseTimer != 'undefined') clearTimeout(window.dirMouseTimer);
	}).mouseout(function(){
		window.dirMouseTimer = setTimeout("$('#f_directorylist').hide()", 500);
	});	
	
	//check to see if someone has logged out
	if (window.location.queryVars().logged_out == 'true') {
		AlertBar.open('<span id="alert_bar_simplestring">You Have Sucessfully Logged Out</span>', 5000);
	}
}

function v3_loader() {
	//$('.v3_priceandperz img').GTqTip();
}

function p3_loader() {
	/* Build The info tabs. */
	
	var tabs = $('.p3_infotabs_header:visible');
	var tab_count = tabs.length;
	var total_width = $('#p3_infotabs').width();
	tabs.css('width', Math.floor(total_width / tab_count) - 1);
	
	$('.p3_infotabs_header:first-child').css({
		'border-left': 0,
		'width': $('.p3_infotabs_header:first-child').width() + tab_count - 1
	});
	
	/* Add event listeners for tab headers. */
	$('.p3_infotabs_header').click(function(){
		$('.p3_infotabs_header').css('background', 'url("/global/gifttree/images/widgets/desc_gradient_off.gif") repeat-x');
		$(this).css('background', 'url("/global/gifttree/images/widgets/desc_gradient_on.gif") repeat-x');
		
		$('#p3_infotabs_target').html( $('.p3_infotabs_body[parent_tab='+$(this).attr('tab')+']').html() );
	});
	
	/* Click first tab. */
	$('.p3_infotabs_header:first-child').click();
	
	/* Lightbox for alt images. */
	$('#p3_altimages > div > a').lightbox();
	
	/* Check main image size, if small size, remove enlarge image button, else, bind click function to it. */
	if ($('#p3_mainimage > a > img').attr('src').indexOf(/large350/) < 0 && $('#p3_mainimage > a > img').attr('src').indexOf(/gt_large/) < 0) {
		
		/* Remove enlarge button. */
		$('#p3_enlargeimage').remove();
		
		/* Fix some CSS */
		$('#p3_mainimage > a').css('cursor', 'default');
	} 
	else {
		/* Main Image Lightbox: */
		$('#p3_mainimage > a').lightbox();
		
		/* Event handler for enlarge image button */
		$('#p3_enlargeimage').click(function(){
			$('#p3_mainimage > a').click();
		});	
	}
	
	/* Bind event handler for quantity question mark. */
	$('#p3_quantitylabel > img').click(function(){ load_modal('/global/modals/quantity.php'); });
	
	/* Bind event handler for zip code question mark. */
	$('#p3_ziplabel > img').click(function(){ load_modal('/global/modals/zip_finder.php'); });
	
	/* If a quantity is typed that is greater than 1 */
	$('#p3_quantityfield').keyup(function(){
		if ($(this).val() > 1) {
			/* Turn quantity > 1 explanation to red. */
			$('#p3_formexplain > span').css('color', 'red');
			
			/* Disabled the google checkout button. */
			$('#p3_googlebutton > input')
				.attr({
					src: 'http://checkout.google.com/buttons/checkout.gif?merchant_id=765421517435431&w=160&h=43&style=white&variant=disabled&loc=en_US',
					disabled: 'disabled'
				})
				.css('cursor', 'default');
		}
		else {
			/* Turns quantity > 1 explanation back to black. */
			$('#p3_formexplain > span').css('color', 'black');
			
			/* Re-activates google checkout. */
			$('#p3_googlebutton > input')
				.attr({
					src: 'http://checkout.google.com/buttons/checkout.gif?merchant_id=765421517435431&w=160&h=43&style=white&variant=text&loc=en_US',
					disabled: ''
				})
				.css('cursor', 'pointer');
		}
	});
	
	/* Activate button for perz interface. */
	$('#p3_perznote').click(function(){ persInterface('show'); });
	
	/* Check query string in case a zip was rejected and the customer had personalizations. */
	var query_vars = window.location.queryVars();
	var perz_nest = $('#pers_forms');

	for (i in query_vars) {
		var name = i;
		var value = query_vars[i];
		
		if (!/pers_name/.test(name)) continue;
		
		var prod_name = decodeURIComponent(value);
		var prod_id = name.replace(/[\D]+/g, '');
		
		var prod_price = query_vars['pers_price['+prod_id+']'];
		
		var line = 1;
		while (typeof query_vars['pers['+prod_id+']['+line+']'] != 'undefined') {
			var line_value = query_vars['pers['+prod_id+']['+line+']'].replace('\\', '');
			line_value = decodeURIComponent(line_value);
			perz_nest.append('<input type="hidden" piid="'+prod_id+'" prodName="'+prod_name+'" prodPrice="'+prod_price+'" name="pers['+prod_id+']['+line+']" value="'+line_value+'"/>');
			line++;
		}
	}
	

	//if tab query string is present
	if (query_vars.tab) {
		$('.p3_infotabs_header[tab='+query_vars.tab+']').click();
	}
	
	//if pviid query string is present
	if (query_vars.pviid && $('#'+query_vars.pviid).length > 0) {
		$('#p3_itemlist > li').not($('#'+query_vars.pviid).parent().parent()).remove();
		$('#'+query_vars.pviid).attr('checked', 'checked');
	}
	
	//check for catalog query string
	if (query_vars.catalog) {
		AlertBar.open('<a id="alert_bar_catalog" href="/catalog/#spread='+query_vars.catalog+'"><img src="/global/gifttree/images/icons/GT_returnarrow.gif" /><span>Back To Catalog</span></a>');
	}
}

function search_loader() {
	$('#v3_searchbutton > input').click(function(){
		$(this).parent().parent().submit();
		return false;
	});
	
	$('#v3_search > input, #v3_minprice > input, #v3_maxprice > input').keypress(function(ev){
		if (ev.keyCode == 13) $('#v3_searchbutton > input').click();
	});
}

function frontpage_loader() {
	/* Cycler */
	$('#fr_cycler > a').cycle({
		after: function() {
			$(this).parent().attr('href', $(this).attr('url'));
		},
		timeout: 7000,
		pause: true
	});
}

function help_loader() {
	$('#help_sidebar').css('height', $('#body').height());
}

function login_page_loader() {
	if ($('#login_email').val() == "") {
		$('#login_email').focus();
	}
	else {
		$('#login_password').focus();
	}
}

function checkout_loader() {
	$('#co_securitycodemodal').click(function(){
		load_modal('/global/modals/card_security_code.php');
		return false;
	});
	
	if (window.location.pathname == '/checkout/checkout.giftcard.php') {
		$('[name=message]').blur(function(){
			$.get(
				'/checkout/dynamic_updater.php',
				{
					'line': window.location.queryVars()['line'],
					'cart_hash': window.location.queryVars()['cart_hash'],
					'message': $(this).val()
				}
			);
		});
	}
}

function giftcard_balance_loader() {
	$('#gc_balancesubmit').click(function(){
		$('#gc_balanceresults').load('/global/gifttree/ajax_listeners/gc_balance.php?number='+$('#gc_balancecard').val());
	});
	
	$('#gc_balancecard').keypress(function(ev){
		if (ev.keyCode == 13) $('#gc_balancesubmit').click();
	});
	
	$('#gc_balancecard').focus();
}

// ===================== 
// ! Various Functions   
// ===================== 

function close_menus() {
	window.menuTimer = false;
	
	$('.h_navcat')	
		.css({
			'border-width': 0,
			'background': '',
			'color': 'white',
			'padding': '9px 17px 0'
		})
		.children('img').css({
			'visibility': 'visible'
		});

	//if we're using ie6, show the select menus that were previously hidden when the nav opened
	if (is_ie6()) $('select').css('visibility', 'visible');
	
	var open_menu_count = $('.h_navdrop:visible').length;
	$('.h_navdrop').hide();
	return open_menu_count;
}

function open_menu() {
	//ie6 will have select menus show through absolutely positioned elements above them			
	if (is_ie6()) $('select').css('visibility', 'hidden');

	$(window.currentMenu).css({
		'border-color': '#676767',
		'border-style': 'solid',
		'border-width': '1px 4px 0 1px',
		
		'background': 'white',
		'color': 'black',
		'padding-right': 13,
		'padding-left': 16,
		'padding-top': 8
	})
	.next().filter('.h_navdrop').css({
		top: $(window.currentMenu).position().top + 31,
		left:  $(window.currentMenu).position().left
	}).show();
	
	$(window.currentMenu).children('img').css('visibility', 'hidden');
}

function is_ie6() { return /MSIE 6/.test(window.navigator.userAgent); }
function is_ie7() { return /MSIE 7/.test(window.navigator.userAgent); }

/* Modal Logic */
function zip_finder() {
	var address = $('#modal_zf_address').val();
	var city = $('#modal_zf_city').val();
	var state = $('#modal_zf_state').val();
	
	$.get(
		'/global/modals/zip_finder.php?address='+address+'&city='+city+'&state='+state,
		function(data){
			data = $.trim(data);
			if (data == 'blank_info') alert("Please fill in all of the forms.");
			else if (data == 'not_found') {
				var show_string = 'Not found.';
			}
			else if (!isNaN(data)) {
				var show_string = data;
			}
			else alert("An error occured, please try again.");
		
			if (typeof show_string != "undefined") {
				$('#modal_zf_results').slideDown().children('strong').html(show_string);
			}
		}
	);
}

function load_modal(modal_url, exit_function) {
	//create background shade
	var shade = modal_shade();
	
	//add content div to the dom
	$('body').prepend('<div id="modal_content" style="position: absolute;"></div>');

	//make it invisible, inject the remote modal markup into it, then fade it in
	$('#modal_content').css({
		'visibility'		: 'hidden',
		'opacity'			: 0
	}).load(modal_url, null, function(){
		//ie6 doesn't like position fixed, so just use absolute:
		if (is_ie6()) $(this).css('position', 'absolute');
		else $(this).css('position', 'fixed');

		$(this).css({
			'left'			: '50%',
			'top'			: (window.innerHeight || document.documentElement.clientHeight)/2,
			'background'	: 'white',
			'z-index'		: '1001',
			'visibility'	: 'visible',
			'margin-left'	: ($(this).width()/-2) -3,
			'margin-top'	: ($(this).height()/-2) -3,
			'border'		: '3px solid #BFBFBF'
		}).animate({ opacity: 1 }, 'fast');
	});
	
	//give the background shade click instructions:
	$(shade).click(function(){
		$('#modal_content').animate({ opacity: 0 }, function() { $(this).remove(); });
		$(this).animate({ opacity: 0 }, function() { $(this).remove(); });
		
		if (typeof exit_function == 'function') exit_function();
		else if (typeof exit_function == 'string') window.location = exit_function;
	});
}

function modal_shade(destroyFlag) {
	if (typeof destroyFlag != 'undefined' && destroyFlag == 'destroy') {
		$('#modal_shade').remove();
		return;
	}
	
	$('#modal_shade').remove();

	$('body').prepend('<div id="modal_shade"></div>');
	
	if (!isNaN(window.scrollMaxY)) var height = window.innerHeight + window.scrollMaxY;
	else if (!isNaN(document.height)) var height = document.height;
	else if (!isNaN(document.documentElement.scrollHeight)) var height = document.documentElement.scrollHeight;
	else var height = '100%';
	
	$('#modal_shade').css({
		'position'		: 'absolute',
		'left'			: '0',
		'top'			: '0',
		'width'			: '100%',
		'height'		: height,
		'opacity'		: '0',
		'z-index'		: '1000',
		'background'	: 'black'
	}).animate({ opacity: 0.85 }, 'slow');
	
	return $('#modal_shade')[0];
}

function tell_friend(bpid, version) {	
	$.post(
		'/global/modals/tell_a_friend.php',
		{
			'bpid': bpid,
			'version': version,
			'f_n': $('#modal_taf_friend_name').val(),
			'f_e': $('#modal_taf_friend_email').val(),
			'y_n': $('#modal_taf_your_name').val(),
			'y_e': $('#modal_taf_your_email').val(),
			'msg': $('#modal_taf_your_message').val(),
			'e_m': $('#modal_taf_email_me').is(':checked')
		},
		function(data) {
			if (data == 'success') {
				$('#modal_taf_forms').slideUp('slow');
				$('#modal_taf_success').slideDown('slow');
			}
			else if (data == 'incomplete') {
				alert('Some of the fields were left incomplete or are invalid.');
			}
			else {
				alert('Email could not be sent, please try again.');
			}
		}
	);
}

function live_chat() {
	window.open('https://server.iad.liveperson.net/hc/55872508/?cmd=file&amp;file=visitorWantsToChat&amp;site=55872508&amp;imageUrl=https://www.gifttree.com/globalimages/logo.gif&amp;referrer='+escape(document.location),'chat55872508','width=472,height=320,resizable=yes');
	window.location = window.location.toString();
	return false;
}

function log(obj) { if (window.console) window.console.log(obj); }
//jquery .log()
(function($) {$.fn.log = function() {return this.each(function(){ window.console.log(this); });}})(jQuery);

function ajaxCall() { return; }

function valid_email(email) {
	var check = /^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
	return check.test(email);
}

var AlertBar = {
	transitionSpeed: 400,

	open: function(markup, time_open) {
		if ($('#alert_bar').length > 0) return false;
	
		AlertBar.generateBar();
		AlertBar.setContent(markup);

		AlertBar.slideDown( AlertBar.fadeContentIn );
		
		$('#alert_bar').click( AlertBar.close );
		
		if (!isNaN(time_open)) {
			window.AlertBarTimer = setTimeout(function(){ AlertBar.close(); }, time_open);
		}
		
		return true;
	},
	
	close: function() { AlertBar.fadeContentOut( AlertBar.slideUp ); },
	
	setContent: function(markup) { $('#alert_bar_holder').html(markup); },
	
	generateBar: function() { $('body').prepend('<div id="alert_bar"><div id="alert_bar_holder"></div></div>'); },
	removeBar: function() { $('#alert_bar').remove(); },
	
	fadeContentIn: function(callback) { $('#alert_bar_holder').fadeIn(AlertBar.transitionSpeed, callback); },
	fadeContentOut: function(callback) { $('#alert_bar_holder').fadeOut(AlertBar.transitionSpeed, callback); },
	
	slideDown: function(callback) {
		$('#main').animate({paddingTop: 57}, AlertBar.transitionSpeed);
		$('#alert_bar').slideDown(AlertBar.transitionSpeed, callback);
	},
	
	slideUp: function(callback) {
		var doctored_callback = function() {
			AlertBar.removeBar();
			if (typeof callback == 'function') callback();
		}
	
		$('#main').animate({paddingTop: 15}, AlertBar.transitionSpeed);
		$('#alert_bar').slideUp(AlertBar.transitionSpeed, doctored_callback);
	}
};

var Notifications = {
	show: function(note, id) {
		if (this.inLog(id)) return false;
		
		if (AlertBar.open(note, 5000)) {
			this.createLogEntry(id);
		}
	},
	
	getLog: function() {
		if (!Cookie.get('note_log')) var cookie_arr = [];
		else {
			try {
				var cookie_arr = eval('('+Cookie.get('note_log')+')');
			}
			catch(e) {
				var cookie_arr = [];
			}
		}
		return cookie_arr;		
	},
	
	createLogEntry: function(val) {
		var cookie_arr = this.getLog();
		
		cookie_arr.push(val);
		cookie_arr = cookie_arr.unique();

		Cookie.set('note_log', JSON.stringify(cookie_arr));
	},
	
	removeLogEntry: function(val) {
		var log = this.getLog();
		var new_log = [];
		
		for (var i=0; i < log.length; i++) {
			if (
				(val instanceof RegExp && val.test(log[i])) ||
				(typeof val == 'string' && log[i] == val)
			) continue;
			
			new_log.push(log[i])
		}
		
		Cookie.set('note_log', JSON.stringify(new_log));
		return new_log;
	},
	
	inLog: function(id) {
		return this.getLog().exists(id);
	}
};

// ==================== 
// ! Array Prototypes   
// ==================== 

//array unique
Array.prototype.unique=function(){var a=[];for(var b=0;b<this.length;b++){if(!a.exists(this[b])){a.push(this[b])}}return a};

//array keys
Array.prototype.keys=function(){var b=[];for(var a in this){if(this.hasOwnProperty(a)){b.push(a)}}return b};

//array item exists
Array.prototype.exists=function(b){for(var a=0;a<this.length;a++){if(this[a]==b){return true}}return false};

//array mapping
Array.prototype.each = function(func) {
	var return_arr = [];
	for (var i=0; i < this.length; i++) return_arr.push(func.call(this[i]));
	return return_arr;
};

// =================== 
// ! Window.location   
// =================== 

//query vars
window.location.queryVars=function(){var e=this.search.substr(1);var d=e.split("&");var c={};for(var b=0;b<d.length;b++){var a=d[b].split("=");c[a[0]]=a[1]}return c};
//hash vars
window.location.hashVars=function(){var e=this.hash.substr(1);var a=e.split("&");var d={};for(var c=0;c<a.length;c++){var b=a[c].split("=");d[b[0]]=b[1]}return d};

window.location.isSecure = function() { return (this.protocol == 'https:'); };
window.location.dirName = function(dir_level) { return window.location.pathname.split('/')[dir_level]; };
window.location.fileName = window.location.dirName( window.location.pathname.split('/').length - 1 );

// =============== 
// ! Third Party   
// =============== 

/**
 * @author 	Maxime Haineault (max@centdessin.com)
 * @version	0.3
 * @desc 	JavaScript cookie manipulation class
 * 
 */
Cookie={get:function(a){tmp=document.cookie.match((new RegExp(a+"=[a-zA-Z0-9.()_=|%/]+($|;)","g")));if(!tmp||!tmp[0]){return null}else{return unescape(tmp[0].substring(a.length+1,tmp[0].length).replace(";",""))||null}},set:function(b,d,a,f,c,e){cookie=[b+"="+escape(d),"path="+((!f||f=="")?"/":f),"domain="+((!c||c=="")?window.location.hostname:c)];if(a){cookie.push(Cookie.hoursToExpireDate(a))}if(e){cookie.push("secure")}return document.cookie=cookie.join("; ")},unset:function(a,c,b){c=(!c||typeof c!="string")?"":c;b=(!b||typeof b!="string")?"":b;if(Cookie.get(a)){Cookie.set(a,"","Thu, 01-Jan-70 00:00:01 GMT",c,b)}},hoursToExpireDate:function(a){if(parseInt(a)=="NaN"){return""}else{now=new Date();now.setTime(now.getTime()+(parseInt(a)*60*60*1000));return now.toGMTString()}},test:function(){Cookie.set("b49f729efde9b2578ea9f00563d06e57","true");if(Cookie.get("b49f729efde9b2578ea9f00563d06e57")=="true"){Cookie.unset("b49f729efde9b2578ea9f00563d06e57");return true}return false},dump:function(){if(typeof console!="undefined"){console.log(document.cookie.split(";"))}}};

/*
 * JSON encode/decoder
 * http://www.json.org/js.html
 */
if(!this.JSON){this.JSON={}}(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}());

// Array Remove - By John Resig (MIT Licensed)
// http://ejohn.org/blog/javascript-array-remove/
Array.prototype.remove=function(c,b){var a=this.slice((b||c)+1||this.length);this.length=c<0?this.length+c:c;return this.push.apply(this,a)};