	;(function($) {
		
		// Global stuff to do after page load
		$(document).ready(function() {
			
			// if there's a success message on screen, slide it up after 10 seconds
			$('p.success').delay(10000).slideUp(500, function() { $(this).remove(); });
					
			$('#quote-ticker').list_ticker({
				speed:5000,
				effect:'fade'
			});
			
			// lazyload images to reduce server load
			$("img").lazyload({ 
			    placeholder : "/img/grey.gif",
			    effect : "fadeIn",
			    failurelimit: 1000,
			    threshold : 50
			});
			
			// hook all non ajax forms
			$("form").not("form[action$=ajax]").each(function() {
				$(this).submit(function() {
					return doValidate(this);
				});
			});
			
			// hook the ajax forms and prep for handling
			$("form[action$=ajax]").each(function() {
				$(this).submit(function() {
					if(doValidate(this)) {
						// run any custom validations
						if(typeof customValidate == "function") { if(customValidate(this)==false) { return false; } }
		
						// make ajax request
						$.ajax({
							type: $(this).attr("method"),
							url: $(this).attr("action")+":js",
							data: $(this).serialize(),
							dataType: "json",
							success: eval($(this).attr("name"))
						});
					}
					return false;
				});
			});
			
			// hook all checkboxes
			$("p.checkbox span").live("click", function() {
				$(this).parent().find("input[type=checkbox], input[type=radio]").click().trigger("change");
			}).css("cursor","pointer");
			
			// bind email validation to all email fields
			$("input[name*=email].validate").live("blur", function() {
				val = $(this).val();
				
				if(val=='') return;
				
				red = $(this).parent().find(".red");
				if(red.length==0) red = $(this).parent().append(' <span class="red small hide">Are you sure this email is valid?</span>').find(".red");
				
				if(!validEmail(val)) red.removeClass("hide");
				else red.addClass("hide");
			});
		
			// Modify external links on click
			$("a:external").bind("click", function() {
				// what part of the page are we in? #header, #content or #footer...
				if($(this).hasParent("#header")) loc = "header";
				else if($(this).hasParent("#content")) loc = "content";
				else if($(this).hasParent("#footer")) loc = "footer";
				
				// rewrite if it hasn't been already
				if(!$(this).hasClass("external")) {
					$(this)
						.attr("target", "_blank")
						.addClass("external")
						.attr("href", "/system/go:"
							+ base64_encode($(this).attr("href").replace("http://", ""))
							.replace(/\//g, "_") // make url friendly
							.replace(/\+/, "-") // make url friendly
							+ ":" + loc
						);
				}
				
				// go there
				return true;
			});
			
			// Gallery Rotation
			if($('#featured_images').length > 0) {
				// Set the opacity of all images to 0
				$('#featured_images li').css({opacity: 0.0});
	
				// Get the first image and display it (gets set to full opacity)
				$('#featured_images li:first').css({opacity: 1.0});
	
				setInterval(function() {
					
					// Get the first image
					var current = ($('#featured_images li.show') ? $('#featured_images li.show') : $('#featured_images li:first'));
	
					// Get next image, when it reaches the end, rotate it back to the first image
					var next = ((current.next().length) ? ((current.next().hasClass('show')) ? $('#featured_images li:first') : current.next()) : $('#featured_images li:first'));	
	
					// Set the fade in effect for the next image, the show class has higher z-index
					next.css({opacity: 0.0}).addClass('show').animate({opacity: 1.0}, 1000);
	
					// Hide the current image
					current.animate({opacity: 0.0}, 1000).removeClass('show');
					
				}, 6000);
			}
			
		});
		
	})(jQuery);
	
	// go to this location
	function goTo(where) {
		if(where!='') document.location.href = where;
	}
	
	// check email validity
	function validEmail(what) {
		return (what.indexOf("@") != -1 && what.match(/[^a-z0-9@_\.\+\-]+/ig) == null) ? true : false;
	}
	
	// validate form errors
	// by james <at> bandit.co.nz
	function doValidate(what, suppress) {
		if(suppress == undefined) { suppress = false; }
		if(!what) what = document.forms[0];
			$(what).find(".required").each(function() {
			// make sure this element isn't disabled...
			if($(this).is(":enabled")) {
				if($(this).attr("type")=="checkbox"&&!$(this).is(":checked")) $(this).parent().addClass("e");
				//else if($(this).attr("name").indexOf("email")!=-1&&$(this).val().match(/[\w\-_\.]+@[\w\-]+\.[\w\-\.]{2,}/i)==null) $(this).addClass("e");
				else if(jQuery.trim($(this).val())=="") $(this).parent().addClass("e");
				else $(this).parent().removeClass("e");
			}
			else $(this).parent().removeClass("e");
		});
		if($(what).find(".e").length>0) {
			if(suppress == false) {
				alert("Please complete all required fields!\n(These are now highlighted in red)");
				$(what).find(".e:first-child input").focus();
			}
			return false;
		}
		return true;
	}
	
	// expression to detect external links
	$.expr[':'].external = function(obj){
		return !obj.href.match(/^mailto\:/)
	        && (obj.hostname.replace("www.", "") != location.hostname.replace("www.", ""));
	}
	
	/*
		* Test whether argument elements are parents
		* of the first matched element
		* @return boolean
		* @param objs
		* 	a jQuery selector, selection, element, or array of elements
	*/
	$.fn.hasParent = function(objs) {
		// ensure that objs is a jQuery array
		objs = $(objs); var found = false;
		$(this[0]).parents().andSelf().each(function() {
			if ($.inArray(this, objs) != -1) {
				found = true;
				return false; // stops the each...
			}
		});
		return found;
	}
	
	/*
		Reverse a jQuery collection
		eg: $("div").reverse().each(function() { ... });
	*/
	$.fn.reverse = function() {
		return $(this.get().reverse());
	}
	
	/*
		JavaScript indexOf with partial matches for a jQuery array
		eg: $(["boat", "sheep", "goat"]).arrayFind("he") => 1
		eg: $(["boat", "sheep", "goat"]).arrayFind("oat") => 0
	*/
	$.fn.arrayFind = function(obj, fromIndex) {
		if(fromIndex == null) fromIndex = 0;
		else if(fromIndex < 0) fromIndex = Math.max(0, this.length + fromIndex);
		
		arr = $.makeArray(this);
		for(var i = fromIndex, j = arr.length; i < j; i++) {
			if(arr[i].indexOf(obj) > -1) return i;
		}
		
		return -1;
	};
	
	// return a number with a delimiter, eg: 10000 => 10,000
	function numberWithDelimiter(number, delimiter) {
		
		number = number + '', delimiter = delimiter || ',';
		
		var split = number.split('.');
		split[0] = split[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + delimiter);
		
		return split.join('.');
		
	};
	
	// return a big number in easy to read format, eg: 10000 => 10K
	function bigNumberFormat(number) {
		
		if(number >= 1000000) return (number / 1000000).toFixed(1) + "M";
		
		else if(number >= 1000) return (number / 1000).toFixed(1) + "k";
		
		else return numberWithDelimiter(number);
		
	}
	
	// cancel any calls to blackbird.js
	var log = {
		toggle: function() {},
		move: function() {},
		resize: function() {},
		clear: function() {},
		debug: function() {},
		info: function() {},
		warn: function() {},
		error: function() {},
		profile: function() {}
	}
	
	
	
	// base64_encode php converted to JS function base64_encode
	eval(function(p,a,c,k,e,d){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--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[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}('F Z(4){9 g="X+/=";9 j,l,u,t,s,m,p,d,i=0,f=0,B="",7=[];e(!4){w 4}4+=\'\';P{t=g.G(4.h(i++));s=g.G(4.h(i++));m=g.G(4.h(i++));p=g.G(4.h(i++));d=t<<18|s<<12|m<<6|p;j=d>>16&H;l=d>>8&H;u=d&H;e(m==U){7[f++]=c.b(j)}z e(p==U){7[f++]=c.b(j,l)}z{7[f++]=c.b(j,l,u)}}I(i<4.y);B=7.K(\'\');B=N.Y(B);w B}F 11(4){9 g="X+/=";9 j,l,u,t,s,m,p,d,i=0,f=0,a="",7=[];e(!4){w 4}4=N.M(4+\'\');P{j=4.k(i++);l=4.k(i++);u=4.k(i++);d=j<<16|l<<8|u;t=d>>18&E;s=d>>12&E;m=d>>6&E;p=d&E;7[f++]=g.h(t)+g.h(s)+g.h(m)+g.h(p)}I(i<4.y);a=7.K(\'\');14(4.y%3){S 1:a=a.W(0,-2)+\'==\';T;S 2:a=a.W(0,-1)+\'=\';T}w a}F Y(q){9 7=[],i=0,f=0,5=0,C=0,J=0;q+=\'\';I(i<q.y){5=q.k(i);e(5<D){7[f++]=c.b(5);i++}z e((5>17)&&(5<Q)){C=q.k(i+1);7[f++]=c.b(((5&19)<<6)|(C&x));i+=2}z{C=q.k(i+1);J=q.k(i+2);7[f++]=c.b(((5&15)<<12)|((C&x)<<6)|(J&x));i+=3}}w 7.K(\'\')}F M(O){9 v=(O+\'\');9 A="";9 r,o;9 L=0;r=o=0;L=v.y;1b(9 n=0;n<L;n++){9 5=v.k(n);9 a=R;e(5<D){o++}z e(5>13&&5<1a){a=c.b((5>>6)|10)+c.b((5&x)|D)}z{a=c.b((5>>12)|Q)+c.b(((5>>6)&x)|D)+c.b((5&x)|D)}e(a!==R){e(o>r){A+=v.V(r,o)}A+=a;r=o=n+1}}e(o>r){A+=v.V(r,v.y)}w A}',62,74,'||||data|c1||tmp_arr||var|enc|fromCharCode|String|bits|if|ac|b64|charAt||o1|charCodeAt|o2|h3||end|h4|str_data|start|h2|h1|o3|string|return|63|length|else|utftext|dec|c2|128|0x3f|function|indexOf|0xff|while|c3|join|stringl|utf8_encode|this|argString|do|224|null|case|break|64|substring|slice|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|utf8_decode|base64_decode|192|base64_encode||127|switch|||191||31|2048|for'.split('|'),0,{}));
