// basic jQuery extensions
$.extend($,
{
	// for debugging purposes - caution - writes to global space
	log : function()
	{
		window.log = function(){
			try{
				if(!window.LOG_OFF) console.log.apply(console,arguments);
			} catch(error)
			{
				// .. IE
			}
		};
		return window.log;
	}(),
	
	// get a timer, pass old timer for time since then
	time : function(t)
	{
		var d = (new Date()).getTime();
		return ( t? d-t  : d );
	},
	
	// Original Author: Rafael Lima (http://rafael.adm.br)
	cssBrowserSelect : (function()
	{
		var ua=navigator.userAgent.toLowerCase(),
			is=function(t){ return ua.indexOf(t) != -1; },
			h=document.getElementsByTagName('html')[0],
			b=( !(/opera|webtv/i.test(ua)) && /msie (\d)/.test(ua) )? ('ie ie'+RegExp.$1):
				is('gecko/index.html')? 'gecko':
					is('applewebkit/index.html')? 'webkit safari':
						is('mozilla/index.html')? 'gecko':						
							is('opera/9')? 'opera opera9':
								/opera (\d)/.test(ua)? 'opera opera'+RegExp.$1:
									is('konqueror')? 'konqueror':
										'',
			d = is('iphone')? ' iphone' : '',
			os=( is('x11')||is('linux') )? ' linux':
				is('mac')? ' mac':
					is('win')? ' win':
						'',
			c=b+d+os+' js';
		
		h.className += h.className?' '+c:c;
		
		return true;
	})(),
	
	// helper for toggling an input field label
	inputToggle: function (selector,message)
	{
		$(selector).focus(function(){
			if($(this).val()==message) $(this).val('')
		}).blur(function(){
			if($(this).val()=='') $(this).val(message)
		});
	}
});



/*
Title:      jQuery.gridmap
Description:Draggable Grid layout with lazyloading
Developer:  Antenna Praxis (http://theantenna.org)
Date:       November 2009
Version:    0.0.1
Requires:   jQuery UI draggable module
Usage:      $('#grid').gridmap( '.entry' );
            
Notes:      

To Do:      
License:    Currently not licensed for public use.
*/

(function($) {
	
	$.gridmap = function(){}
	
	// defaults
	$.gridmap.defaults = {};

	
	$.fn.gridmap = function(options)
	{
		var $this = this,
			opts = $.extend($.gridmap.defaults, options),
			waitingLoad = false,
			_isActive = false;
		
		var initialize = function()
		{
			//log($this);
			$this.draggable({
							
				start: function(event, ui) {
					$('#nav-hint').fadeOut('def');
					$.cookie('mosaic-hint-hide', '1');
					$('#grid .post a').trigger("disable");
				},
				stop: function(event, ui) {
					setTimeout(function(){
						$('#grid .post a').trigger("enable");
					}, 10);
				}

			});
			$this.draggable( 'disable' ); // disable until needed
			
			// .. run this when dragging
			/*if ( !waitingLoad && y < -( $(window).height() - $this.height() ) )
			{
				trigger('load');
				waitingLoad = true;
				// .. listen for update event
			}*/
			
			return $this;
		}
		
		var activate = this.gridmap.activate = function()
		{
			_isActive = true;
			
			// dispatch event
			$this.trigger("activate");
			
			$this.draggable( 'enable' )
			
			return $this;
		};
		
		var deactivate = this.gridmap.deactivate = function()
		{
			_isActive = false;
			
			// dispatch event
			$this.trigger("deactivate");
			
			$this.draggable( 'disable' )
			
			return $this;
		};
		
		$this.gridmap.loadMore = function(href)
		{
			//log('loadmore', href);
			if(!href) return;
			
			$.ajax({
				url: href,
				//dataType:'html',
				data: href.indexOf('ajax')>-1?{}:{ajax:true},
				type:'GET',
				success: function(xml)
				{	
					//log(xml);
					
					var $xml = $(xml),
						items = $('.post', $xml);
					
					//log('adding ',items.length,items);
					
					$this.vertexLayout.addContent( items );
					
					//log('total now ', $('#grid .post').length );
					
					$this.trigger("update", [items] ); // trigger an update event
					
					// .. still more content? repeat
					if( $('#nav-next a', $xml).length )
					{
						//log( 'loadmore', $('#nav-next a', $xml).attr('href') );
						$this.gridmap.loadMore( $('#nav-next a', $xml).attr('href') );
					}
					else log('no more content');
				},
				error: function (XMLHttpRequest, textStatus, errorThrown) {
					log('error',textStatus);
				}
			});
		};
		
		$this.gridmap.isActive = function()
		{
			//log('isActive',_isActive);
			return _isActive;
		}
	
		return initialize();
	};
	
	
})(jQuery);





/*
Title:      jQuery.relativeDate
Description:Formats a date relative to current time (eg '3 mins ago')
Developer:  Antenna Logistics (http://theantenna.org)
Date:       May 2009
Version:    0.1
Usage:      
Notes:      
To Do:      
License:    Dual licensed under the MIT and GPL licenses:
            http://www.opensource.org/licenses/mit-license.php,
            http://www.gnu.org/licenses/gpl.html
*/

(function($) {
	
	var a_minute = 60 *1000,
		an_hour = a_minute*60,
		a_day = an_hour*24,
		a_month = a_day*30, // averaged
		a_year = a_day*365,
		years,months,days,hours,minutes,secs,
		_plural = "s",
		_seperator = " ",
		_now = new Date();
	
	$.relativeDate = function(date, now)
	{
		//years = months = days = hours = minutes = secs = 0;
		
		if(typeof date == "string") date = new Date(date);
		secs = (now || _now).getTime() - date.getTime();
	
		years = Math.floor(secs/a_year);
		secs = secs%a_year;
		months = Math.floor(secs/a_month);
		
		secs = secs%a_month;
		days = Math.floor(secs/a_day);
		secs = secs%a_day;
		hours = Math.floor(secs/an_hour);
		secs = secs%an_hour;
		minutes = Math.floor(secs/a_minute);
		
		return formattedDate();
	};
	
	formattedDate = function()
	{
		if(years > 0) return displayDate(years,' year');
		else if(months > 0) return displayDate(months + (days>15? 1 : 0),' month');
		else if(days > 0) return displayDate(days + (hours>12? 1 : 0),' day');
		else if(hours > 0) return displayDate(hours + (minutes>30? 1 : 0),' hour') ;
		else return displayDate(minutes ,' minute');
	}
	
	displayDate = function(num, string, seperator, plural)
	{
		plural = plural || _plural,
		seperator = seperator || _seperator;
		return (num? (num!=1? num+string+plural+seperator : num+string+seperator) : "");
	}
	
	
})(jQuery);


/*
 * jQuery Color Animations
 * Copyright 2007 John Resig
 * Released under the MIT and GPL licenses.
 */

(function(jQuery){

	// 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 );
			}
			
			//try{
			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(",") + ")";
			//}catch(error){}
		}
	});

	// 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)];

		// 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]
	};
	
})(jQuery);


/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
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
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        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;
    }
};



/*
Title:      jQuery.vertexLayout
Description:Layout on vertices.
Developer:  Antenna Praxis (http://theantenna.org)
Date:       December 2009
Version:    0.0.8
Usage:      $(<target>).vertexLayout(<elements:selector string or list> [,{col_width (px), min_cols}])
Notes:      Uses a matrix/buffer for hit testing (slow but easy)	
To Do:      
            
License:    Not currently licensed for public use.
*/
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($){n T=0,B=1,L=0,R=2,8=4,u=0,D=T+L,N=T+R,O=B+R,P=B+L,1f=0,1g=1,1h=3,1i=2,q=[{15:0,5:D+8,x:0,y:0,d:0}],E=[],16=0,17,I=1I,l,$h,Q;$.F=9(){};$.F.1j={G:\'18\',1k:1l,19:{x:0,y:0},S:1m,U:1m};$.Z.F=9(a,b){$h=h;l=$.1J($.F.1j,b);I=$(a);17=l.G==\'18\'?1n:1o;1a(\'1K 1L \',I);G(I);$h.1p("1q");w h};1M=9(){G(I);$h.1p("1q")};G=9(g){Q=$.Q();g.1r(9(o){n a=$(h),V=J.1s(a.1N()/l.S)*l.S,W=J.1s(a.1O()/l.U)*l.U;q.1P(17);r(i=0;i<q.X;i++){n v=q[i],6;1Q(v.5){C N:C D+8:6={5:1f,s:v.x,t:v.y,z:v.x+V,A:v.y+W};Y;C D:C P+8:6={5:1h,s:v.x,t:v.y-W,z:v.x+V,A:v.y};Y;C O:C N+8:6={5:1g,s:v.x-V,t:v.y,z:v.x,A:v.y+W};Y;C P:C O+8:6={5:1i,s:v.x-V,t:v.y-W,z:v.x,A:v.y};Y}n b=1t(6.s,6.t,6.z,6.A);7(!b)1R;q.10(i,1);n c=[{5:D+u,K:D+u,x:6.s,y:6.t},{5:N+u,K:N+u,x:6.z,y:6.t},{5:O+u,K:O+u,x:6.z,y:6.A},{5:P+u,K:P+u,x:6.s,y:6.A}];c.10(6.5,1);r(k=0;k<c.X;k++){n p=c[k];r(j=0;j<q.X;j++){n d=q[j];7(p.x==d.x&&p.y==d.y){7(p.K!=(d.5^(R|B))){c.10(k,1);k--;q.10(j,1);j--;Y}H{p.5=p.K;p.5^=(R|8);d.5^=(R|8)}}H 7(p.x==d.x){7(d.y>6.t){7(d.y<6.A){7(!(d.5&8)){d.5^=(B|8)}}H 7(!p.1u&&p.5&B){7(d.5==(p.5^8)||d.5==(p.5^R)){p.5^=(B|8)}p.1u=M}}H 7(!p.1v&&!(p.5&B)){7(d.5==(p.5^8)||d.5==(p.5^R)){p.5^=(B|8)}p.1v=M}}H 7(p.y==d.y){7(d.x>6.s){7(d.x<6.z){7(!(d.5&8)){d.5^=(R|8)}}H 7(!p.1w&&p.5&R){7(d.5==(p.5^8)||d.5==(p.5^B)){p.5^=(R|8)}p.1w=M}}H 7(!p.1x&&!(p.5&R)){7(d.5==(p.5^8)||d.5==(p.5^B)){p.5^=(R|8)}p.1x=M}}}}7(l.G==\'18\'&&!q.X)q.1y({15:0,5:D,x:0,y:0,d:0});++16;r(k=0;k<c.X;k++){n p=c[k];1z(p.5,p.x,p.y,16,J.1S(J.1T(J.1A(p.x-l.19.x,2)+J.1A(p.y-l.19.y,2))))}1B($(h),6.s,6.t);r(y=6.t;y<6.A;y+=l.U){n e=y.11();r(x=6.s;x<6.z;x+=l.S){n f=x.11();E[e][f]=1}}w M}});7(l.1k){$(\'.12-1C\').1D();$.1r(q,9(i){$(\'<13 1E="12-1C"></13>\').1F(h.5).1b({1c:h.x,1d:h.y}).1e($h)});$(\'.12-1G\').1D();r(y 1H E){n m=E[y];r(x 1H m){$(\'<13 1E="12-1G"></13>\').1F(x+\'/\'+y).1b({1c:x+\'14\',1d:y+\'14\'}).1e($h)}}}1a(\'1U 1V\',$.Q(Q))};1t=9(a,b,c,d,e){r(y=b;y<d;y+=l.U){n f=y.11();7(!E[f])E[f]=[];r(x=a;x<c;x+=l.S){n g=x.11();7(E[f][g]){w 1l}}}w M};1z=9(a,x,y,b,d){q.1y({x:x,y:y,15:b,5:a,d:d})};1B=9(a,x,y){w a.1b({1W:"1X",1c:x+"14",1d:y+"14"}).1e($h)};1Y=9(a,b){w(a.x-b.x)};1o=9(a,b){w(a.y!=b.y?a.y-b.y:a.x-b.x)};1n=9(a,b){w a.d-b.d};$.Z.F.1Z=9(a){n b=$(a);1a(\'20 \',b);$h.21(b);G(b);I.22(b);w $h};$.Z.F.23=9(){};$.Z.F.24=9(){}})(25);',62,130,'|||||type|bounds|if|CONCAVE|function||||||||this||||opts||var|||vertices|for|x1|y1|CONVEX||return|||x2|y2||case|TL|matrix|vertexLayout|layout|else|content|Math|otype||true|TR|BR|BL|time||min_width||min_height|itemW|itemH|length|break|fn|splice|toString|grid|div|px|id|v_id|sortFunc|centre|centre_offset|log|css|left|top|appendTo|RD|LD|RU|LU|defaults|debug|false|100|dSort|ySort|trigger|gridchange|each|round|testFootprint|bchecked|tchecked|rchecked|lchecked|push|addVertex|pow|attachItem|vert|remove|class|html|cell|in|null|extend|laying|out|onResize|outerWidth|outerHeight|sort|switch|continue|abs|sqrt|Layout|took|position|absolute|xSort|addContent|adding|append|add|refresh|info|jQuery'.split('|'),0,{}))
