// This file combines the juice files core, popover and effects for the Niggle widget

/*  Copyright (c) 2007, 2008 Stephen Whiteley (http://jui.ce.it)
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *  THE SOFTWARE.
 *
 *  Juice Library core.juice.js, version 0.1.2.20080911
 *
/*--------------------------------------------------------------------------*/

// Core

(function() {

	window.Juice = {

		Version: '0.1.1.20080325',

		$: function() {

			var a = [];

			var i, e;
			for ( i = 0; i < arguments.length; i++ ) {
				e = arguments[i];
				if ( typeof e == 'string' ) { e = document.getElementById( e ); }
				if ( arguments.length === 1 ) { return e; }
				a.push( e );
			}

			return a;

		},

		Bookmark: function( ele, e ) {

			Juice.Event.cancel( e );

			var w = window;

			if ( w.sidebar ) {
				w.sidebar.addPanel( ele.title, ele.href, '' );
			} else if ( w.opera && w.print ) {
				ele.rel = 'sidebar';
			} else if ( w.external ) {
				w.external.AddFavorite( ele.href, ele.title );
			} else {
				alert( 'Your Browser does not support dynamic bookmarking, please try bookmarking manually.' );
			}

			return false;

		},

		Browser: new function() {

			this.detect = function() {

				var a = navigator.userAgent, b = {};

				b.opera		= ( a.indexOf( 'Opera' ) != -1 );
				b.konqueror	= ( a.indexOf( 'Konqueror' ) != -1 );
				b.safari	= ( a.indexOf( 'Safari' ) != -1 );
				b.mozilla	= ( a.indexOf( 'Gecko' ) != -1 && !b.konqueror && !b.safari );
				b.ie7		= ( a.indexOf( 'MSIE 7' ) != -1 && !b.opera );
				b.ie6		= ( a.indexOf( 'MSIE' ) != -1 && !b.ie7 && !b.opera );
				b.ie		= ( b.ie7 || b.ie6 );
				b.quirks	= ( this.mode() == 'quirks' ? true : false );

				return b;

			};

			this.details = function() {

				var n = navigator;

				return {
					agent:		n.userAgent,
					code:		n.appCodeName,
					cookies:	n.cookieEnabled,
					name:		n.appName,
					platform:	n.platform,
					version:	n.appVersion
				};

			};

			this.dimensions = function() {

				var s = { width: 0, height: 0 };

				if ( typeof window.innerWidth == 'number' ) {
					s.width = window.innerWidth;
					s.height = window.innerHeight;
				} else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
					s.width = document.documentElement.clientWidth;
					s.height = document.documentElement.clientHeight;
				} else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
					s.width = document.body.clientWidth;
					s.height = document.body.clientHeight;
				}

				return s;

			};

			this.flash = function() {

				var c, d, f = { enabled: false, version: false }, n = navigator;

				if ( n.plugins && n.plugins.length ) {
					c = n.plugins['Shockwave Flash'];
					if ( c ) {
						f.enabled = true;
						if ( c.description ) {
							d = d.description;
							f.version = d.charAt( d.indexOf( '.' ) - 1 );
						}
					}
				} else if ( n.mimeTypes && n.mimeTypes.length ) {
					c = n.mimeTypes['application/x-shockwave-flash'];
					if ( c && d.enabledPlugin ) {
						f.enabled = true;
					}
				} else {
					for ( var v = 9; v > 0; v-- ) {
						try {
							c = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash.' + v );
							f.enabled = true;
							f.version = v;
							break;
						} catch( e ) {}
					}
				}

				return f;

			};

			this.inner = function() {

				var s = { x: 0, y: 0 }, w = Juice.Browser.dimensions();

				if ( window.innerHeight && window.scrollMaxY ) {
					s.x = document.body.scrollWidth;
					s.y = window.innerHeight + window.scrollMaxY;
				} else if ( document.body.scrollHeight > document.body.offsetHeight ) {
					s.x = document.body.scrollWidth;
					s.y = document.body.scrollHeight;
				} else {
					s.x = document.body.offsetWidth;
					s.y = document.body.offsetHeight;
				}

				return {
					width: ( s.x < w.width ) ? w.width : s.x,
					height: ( s.y < w.height ) ? w.height : s.y
				};

			};

			this.mode = function() {

				var c, m = false;

				if ( c = document.compatMode ) {
					switch ( c.toLowerCase() ) {
						case 'backcompat': m = 'quirks'; break;
						case 'css1compat': m = 'compliant'; break;
						default: m = 'hybrid';
					}
				}

				return m;

			};

		},

		Container: new function() {

			this.create = function( s ) {

				if ( !s ) { s = {}; }

				var c = {
					outer:	Juice.Element.create( 'DIV', null, s.id || null, s.className || null ),
					inner:	Juice.Element.create( 'DIV', s.value || null, null, 'inner' ),
					shadow: Juice.Element.create( 'DIV' )
				};

				c.outer.style.zIndex		= s.zIndex || 1;
				c.outer.style.position		= s.fixed === true ? 'relative' : 'absolute';

				if ( s.width ) { c.outer.style.width = s.width + 'px'; }

				c.inner.style.border		= '1px solid ' + ( s.border || '#808080' );
				c.inner.style.background	= s.background || 'white';

				if ( s.padding )	{ c.inner.style.padding = s.padding + 'px'; }
				if ( s.height )		{ c.inner.style.height = ( s.height - ( s.padding ? s.padding * 2 : 0 ) - 2 ) + 'px'; }

				c.shadow.style.position		= 'absolute';
				c.shadow.style.background	= s.shadow || '#999999';
				c.shadow.style.zIndex		= -1;
				c.shadow.style.top			= '2px';
				c.shadow.style.right = c.shadow.style.bottom = c.shadow.style.left = '-3px';

				Juice.Element.opacity( c.shadow, s.opacity || 30 );
				Juice.Element.append( c.outer, [ c.inner, c.shadow ] );

				return c;

			};

			this.render = function( c, e ) {

				if ( !e ) { e = document.body; }

				e.appendChild( c.outer );

				Juice.Container.fix( c );

			};

			this.fix = function( c ) {

				if ( c && ( Juice.Browser.detect().ie6 || Juice.Browser.detect().quirks ) ) {

					var d = Juice.Element.dimensions( c.outer );

					c.shadow.style.width = d.width + 6 + 'px';
					c.shadow.style.height = d.height + 1 + 'px';

					Juice.Element.obstructions( c.outer );

				}

			};

		},

		Convert: new function() {

			this.namehex = function( n ) {

				var c = {
					'aqua': '#00FFFF', 'black': '#000000', 'blue': '#0000FF', 'fuchsia': '#FF00FF',
					'gray': '#808080', 'green': '#008000', 'lime': '#00FF00', 'maroon': '#800000',
					'navy': '#000080', 'olive': '#808000', 'purple': '#800080', 'red': '#FF0000',
					'silver': '#C0C0C0', 'teal': '#008080', 'white': '#FFFFFF', 'yellow': '#FFFF00'
				};

				if ( c[n] ) { return c[n]; }

				return false;

			};

			this.hexrgb = function( h ) {

				if ( !Juice.Type.hexColour( h ) ) { h = this.namehex( h ); }
				if ( !Juice.Type.hexColour( h ) ) { return; }

				var x = new RegExp( '^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$', 'i' ), m = false;

				if ( m = h.match( x ) ) {
					return {
						r: parseInt( m[1], 16 ),
						g: parseInt( m[2], 16 ),
						b: parseInt( m[3], 16 )
					};
				} else {
					Juice.Debug( new Error( 'Juice.Core: Invalid hex value: ' + h ) );
				}

				return false;

			};

			this.hsvrgb = function( h, s, v ) {

				var r, g, b;

				if ( s == 0 ) {
					if ( v == 0 ) {
						r = g = b = 0;
					} else {
						r = g = b = parseInt( v * 255 / 100 );
					}
				} else {

					if ( h == 360 ) { h = 0; }

					h /= 60, s /= 100, v /= 100;

					var i = parseInt( h );
					var f = h - i;
					var p = v * ( 1 - s );
					var q = v * ( 1 - ( s * f ) );
					var t = v * ( 1 - ( s * ( 1 - f ) ) );

					switch ( i ) {
						case 0: r = v; g = t; b = p; break;
						case 1: r = q; g = v; b = p; break;
						case 2: r = p; g = v; b = t; break;
						case 3: r = p; g = q; b = v; break;
						case 4: r = t; g = p; b = v; break;
						case 5: r = v; g = p; b = q; break;
					}

					r = parseInt( r * 255 );
					g = parseInt( g * 255 );
					b = parseInt( b * 255 );

				}

				return { r: r, g: g, b: b };

			};

			this.rgbhex = function( r, g, b ) {

				var hex = '', i;

				for ( i = 0; i < arguments.length; i++ ) {
					hex += Juice.Format.pad( parseInt( arguments[i] ).toString( 16 ), 2 );
				}

				if ( Juice.Type.hexColour( hex ) ) {
					return '#' + hex;
				} else {
					return false;
				}

			};

			this.rgbhsv = function( r, g, b ) {

				var h, s, v, min, delta;

				min		= Math.min( r, g, b );
				v		= Math.max( r, g, b );
				delta	= v - min;
				s		= v == 0 ? 0 : ( delta / v ) * 100;

				if ( s == 0 ) {
					h = 0;
				} else {
					if ( r == v ) {
						h = 60 * ( g - b ) / delta;
					} else {
						if ( g == v ) {
							h = 120 + 60 * ( b - r ) / delta;
						} else {
							h = 240 + 60 * ( r - g ) / delta;
						}
					}
				}

				if ( h < 0 ) { h = h + 360; }

				return { h: h, s: s, v: ( v / 255 ) * 100 };

			};

			this.fullrgbhex = function( r ) {

				var x = new RegExp( '^rgb\\(([0-9]{3}), ([0-9]{3}), ([0-9]{3})\\)' ), m = false;

				if ( m = r.toLowerCase().match( x ) ) {
					return this.rgbhex( m[1], m[2], m[3] );
				}

				return false;

			};

		},

		Debug: function( e ) {
			if ( Juice.Prefs.debug === true ) {
				throw e;
			}
		},

		Element: new function() {

			this.addClassName = function( e, n, c ) {
			
				if ( ( typeof c == 'boolean' ) && c !== true ) {
					alert('not added');
					return false;
				}

				if ( !this.hasClassName( e, n ) ) {
					e.className += ' ' + n;
				} else {
					return false;
				}

				return true;

			};

			this.append = function( p, c ) {

				if ( Juice.Type.array( c ) ) {
					for ( var i = 0; i < c.length; i++ ) {
						p.appendChild( c[i] );
					}
				} else {
					p.appendChild( c );
				}

			};

			this.blur = function() {

				return window.focus();

			};

			this.byClassName = function( c, e ) {

				if ( !e ) { e = document; }

				var a = [];
				var n = e.getElementsByTagName( '*' );
				var i;

				for ( i = 0; i < n.length; i++ ) {
					if ( this.hasClassName( n[i], c ) ) {
						a.push( n[i] );
					}
				}

				return a;

			};

			this.contains = function( p, c ) {

				while ( c != document ) {
					if ( c == p ) {
						return true;
					}
					c = c.parentNode;
				}

				return false;

			};

			this.create = function( t, h, i, c, n ) {

				if ( !t ) { return false; }

				var p, s;

				if ( ( p = t.indexOf( ':' ) ) !== -1 ) {
					s = t.substring( p + 1, t.length );
					t = t.substring( 0, p );
				}

				var e = document.createElement( t.toUpperCase() );

				if ( i ) { e.id = i; }
				if ( c ) { e.className = c; }

				switch ( e.nodeName ) {
					case 'A':
						if ( h ) { e.innerHTML = h; }
						if ( n ) { e.href = n; }
					break;
					case 'IFRAME':
						if ( h ) { e.src = h; }
						if ( n ) { e.name = n; }
					break;
					case 'IMG':
						if ( h ) { e.src = h; }
					break;
					case 'INPUT':
						e.type = s;
						if ( h ) { e.value = h; }
						if ( n ) { e.name = n; }
					break;
					case 'OPTION':
						if ( h ) {
							e.innerHTML = h;
							e.value = n || n == '' ? n : h;
						}
					break;
					case 'SELECT':
						if ( n ) { e.name = n; }
					break;
					default:
						if ( h ) { e.innerHTML = h; }
				}

				return e;

			};

			this.dimensions = function( ele ) {

				var s = { height: 0, width: 0 };

				if ( ele.offsetHeight ) {
					s.height	= ele.offsetHeight;
					s.width		= ele.offsetWidth;
				} else {
					s.height	= ele.style.pixelHeight;
					s.width		= ele.style.pixelWidth;
				}

				return s;

			};

			this.empty = function( e ) {

				var c = Juice.$( e );

				if ( c.hasChildNodes() ) {
					while ( c.hasChildNodes() ) {
						c.removeChild( c.firstChild );
					}
				}

			};

			this.hasClassName = function( e, c ) {

				var x = new RegExp( '\\b' + c + '\\b', 'ig' );

				if ( e.className && e.className.match( x ) ) {
					return true;
				}

				return false;

			};

			this.insertAtCaret = function( n, b, a ) {

				n = Juice.$( n );
				if ( n.nodeName == 'TEXTAREA' ) {
					n.focus();
					if ( !a ) { a = ''; }
					if ( document.selection ) {
						var r = document.selection.createRange();
						if ( r.parentElement() != n ) { return false; }
						r.text = b + r.text + a;
						r.moveStart ('character', r.text.length - a.length );
						r.moveEnd ('character', r.text.length - ( a.length > 0 ? b.length - a.length : 0 ) );
						r.select();
					} else if ( n.selectionStart >= 0 ) {
						var s = n.selectionStart, e = n.selectionEnd, c = b + n.value.substring( s, e ) + a;
						if ( c != b + a ) {
							n.value = n.value.substring( 0, s ) + c + n.value.substring( e, n.value.length );
							n.setSelectionRange( s + c.length, s + c.length );
						} else {;
							n.value = n.value.substring( 0, s ) + b + a + n.value.substr( e );
							n.setSelectionRange( s + b.length, s + c.length - a.length );
						}
					} else {
						n.value = n.value + b + a;
					}
					n.focus();
				}
				return; 
	
			};

			this.nextNode = function( n, t ) {

				n = Juice.$( n );

				if ( n.firstChild ) {
					n = n.firstChild;
				} else if ( n.nextSibling ) {
					n = n.nextSibling;
				} else if ( n.parentNode != t ) {
					while ( ( n = n.parentNode ) && n != t ) {
						if ( n.nextSibling ) {
							n = n.nextSibling;
							break;
						}
					}
				} else {
					return null;
				}
				if ( n == t ) {
					return null;
				}
				if ( n != null ) {
					if ( n.nodeType != 1 ) {
						n = this.nextNode( n, t );
					}
				}

				return n;

			};

			this.prevNode = function( n, t ) {

				n = Juice.$( n );

				if ( n.lastChild ) {
					n = n.lastChild;
				} else if ( n.previousSibling ) {
					n = n.previousSibling;
				} else if ( n.parentNode != t ) {
					while ( ( n = n.parentNode ) && n != t ) {
						if ( n.previousSibling ) {
							n = n.previousSibling;
							break;
						}
					}
				} else {
					return null;
				}
				if ( n == t ) {
					return null;
				}
				if ( n != null ) {
					if ( n.nodeType != 1 ) {
						n = this.prevNode( n, t );
					}
				}

				return n;

			};

			this.obstructions = function( n ) {

				if ( Juice.Browser.detect().ie6 ) {

					if ( n.firstChild && n.firstChild.className == 'JuiceObstruction' ) {
						n.removeChild( n.firstChild );
					}

					var d = Juice.Element.dimensions( n );

					var f					= Juice.Element.create( 'IFRAME' );
						f.src				= 'about:blank';
						f.className			= 'JuiceObstruction';
						f.scrolling			= 'no';
						f.frameBorder		= 0;
						f.style.width		= d.width + 'px';
						f.style.height		= d.height + 'px';
						f.style.zIndex		= -1;
						f.style.position	= 'absolute';
						f.style.filter		= 'filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';

					if ( n.firstChild ) {
						n.insertBefore( f, n.firstChild );
					} else {
						n.appendChild( f );
					}

					n.style.zIndex = 900;

				}

			};

			this.opacity = function( e, o ) {

				e.style.opacity	= e.style.MozOpacity = e.style.KHTMLOpacity = ( o / 100 );
				e.style.filter	= 'alpha(opacity=' + o + ')';

				return true;

			};

			this.output = function( e ) {

				if ( typeof e == 'string' ) {
					if ( e.indexOf( '#' ) != -1 ) {
						return ( document.getElementById( e ) || false );
					} else {
						return ( document.getElementsByTagName( e ).item(0) || false );
					}
				}

				return false;

			};

			this.position = function( e ) {

				if ( !e ) { return false; }

				var p = { top: 0, left: 0 };

				if ( e.offsetParent ) {

					p.top	= e.offsetTop;
					p.left	= e.offsetLeft;

					while ( e.offsetParent ) {
						e		= e.offsetParent;
						p.top	+= e.offsetTop;
						p.left	+= e.offsetLeft;
					}

				}

				return p;

			};

			this.remove = function( a, v ) {

				for ( var i = 0; i < a.length; i++ ) {
					if ( v == a[i] ) {
						a.splice( i, 1 );	
					}
				}
				return a;

			};

			this.removeClassName = function( e, c ) {

				if ( this.hasClassName( e, c ) ) {
					e.className = Juice.Format.trim( e.className.replace( new RegExp( '\\b' + c + '\\b', 'ig' ), '' ) );
				} else {
					return false;
				}

				return true;

			};

			this.replaceClassName = function( e, c, r ) {

				if ( this.hasClassName( e, c ) ) {
					Juice.Element.removeClassName( e, c );
					Juice.Element.addClassName( e, r );
				} else {
					return false;
				}

				return true;

			};

			this.scroll = function( e ) {

				var p = { top: 0, left: 0 };

				if ( e ) {

					for ( var n = e; n; n = n.offsetParent ) {
						p.top	+= n.offsetTop;
						p.left	+= n.offsetLeft;
					}

				} else {

					var w = window, d = document;

					if ( typeof w.pageYOffset == 'number' ) {
						p.top	= w.pageYOffset;
						p.left	= w.pageXOffset;
					} else if ( d.body && d.body.scrollTop ) {
						p.top	= d.body.scrollTop;
						p.left	= d.body.scrollLeft;
					} else if ( d.documentElement && d.documentElement.scrollTop ) {
						p.top	= d.documentElement.scrollTop;
						p.left	= d.documentElement.scrollLeft;
					}

				}

				return p;

			};

			this.scrollTo = function( n, e, p ) {

				if ( e ) { Juice.Event.cancel( e ); }

				var o, a, r = 1, d = 3, s = this.scroll(), f = this.scroll( Juice.$( n ) );
				
				if ( s.top < f.top ) {
					o = s.top + Math.max( r, ( ( f.top - s.top ) / d ) );
					a = ( f.top - r <= o );
				} else {
					o = s.top - Math.max( r, ( ( s.top - f.top ) / d ) );
					a = ( f.top - r >= o );
				}

				if ( a || s.top == f.top || p == o ) {
					window.scrollTo( 0, f.top );
				} else {
					window.scrollTo( 0, o );
					setTimeout( function() {
						Juice.Element.scrollTo( n, false, o );
					}, 50 );
				}

			};

			this.search = function( n, h ) {

				if ( typeof h != 'object' ) { return false; }

				for ( var i = 0; i < h.length; i++ ) {
					if ( h[i] == n ) { return true; }
				}

				return false;

			};

			this.searchReplace = function( t, s, r ) {

				return t.replace( new RegExp( s, 'ig' ), r );

			};

			this.style = function( e, s ) {

				if ( !Juice.Browser.detect().ie ) {
					s = s.replace( new RegExp( '[A-Z]', 'g' ), function( m, c ) {
						return '-' + s.charAt( c ).toLowerCase();
					} );
				}

				if ( e.currentStyle ) {
					return e.currentStyle[s];
				} else if ( window.getComputedStyle ) {
					return document.defaultView.getComputedStyle( e, null ).getPropertyValue( s );
				}

				return false;

			};

			this.toggle = function( e ) {

				var c = Juice.$( e );

				if ( c.style.display != 'none' ) {
					c.style.display = 'none';
				} else {
					c.style.display = '';
				}

			};

		},

		Event: new function() {

			this.add = function( e, n, o, c ) {

				e = Juice.$( e );

				if ( e.addEventListener ) {
					e.addEventListener( n, o, c );
				} else if ( e.attachEvent ) {
					e.attachEvent( 'on' + n, o );
				} else {
					return false;
				}

				return true;

			};

			this.blur = function( e, l ) {

				var n = Juice.Event.source( e );

				while ( n != document ) {
					if ( n == l ) { break; }
					n = n.parentNode;
				}

				if ( n != l ) { return true; }

				return false;

			};

			this.cancel = function( e ) {

				if ( !e ) { return false; }

				e = e || window.event;

				if ( e.stopPropagation ) {
					e.preventDefault();
					e.stopPropagation();
				} else {
					e.returnValue	= false;
					e.cancelBubble	= true;
				}

				return true;

			};

			this.remove = function( e, n, o, c ) {

				e = Juice.$( e );

				if ( e.removeEventListener ) {
					e.removeEventListener( n, o, c );
				} else if ( e.detachEvent ) {
					e.detachEvent( 'on' + n, o );
				} else {
					return false;
				}

				return true;

			};

			this.key = function( e ) {

				e = e || window.event;

				if ( !e ) return;

				var k = e.keyCode || e.which || null;

				return { code: k, value: String.fromCharCode( k ).toLowerCase() };

			};

			this.mouse = function( e ) {

			   e = e || window.event, d = document.body;

			   var p = { left: 0, top: 0 };

				if ( e.pageX || e.pageY ) {
					p.left	= e.pageX;
					p.top	= e.pageY;
				} else if ( e.clientX || e.clientY ) {
					var s = Juice.Element.scroll();
					p.left	= e.clientX + s.left;
					p.top	= e.clientY + s.top;
				}

			   return p;

			};

			this.preload = function( s ) {

				var image = new Image();

				if ( typeof s == 'object' ) {
					for ( var i in s ) {
						image.src = s[i];
					}
				} else {
					image.src = s;
				}

			};

			this.source = function( e ) {

				e = e || window.event;

				return ( e.target || e.srcElement );

			};

			this.type = function( e ) {

				e = e || window.event;

				return ( e.type );

			};

		},

		Format: new function() {

			this.decode = function( v ) {

				return decodeURIComponent( v );

			};

			this.email = function( r, d, e ) {

				var a = r + '@' + d + e;

				return '<a href="mailto:' + a + '">' + a + '</a>';

			};

			this.encode = function( v ) {

				return encodeURIComponent( v );

			};

			this.stripTags = function( s ) {

				return s.value.replace( /<\S[^><]*>/g, '' );

			};

			this.entities = function( t ) {

				var d = document.createElement( 'DIV' );
					d.appendChild( document.createTextNode( t ) );
				
				return d.innerHTML;

			};

			this.implode = function( s, a ) {

				if ( Juice.Type.array( a ) ) {
					return a.join( s );
				}

				return false;

			};

			this.ltrim = function( s ) {

				while ( s.substr( 0, 1 ) == ' ' ) {
					s = s.substring( 1, s.length ) ;
				}

				return s;

			};

			this.number = function( n, d, p, g ) {

				var ns = n.toString();
				var s = n < 0 ? '-' : '';
				if ( d ) { n = this.round( n, d ); }
				var i = ( n > 0 ? Math.floor( n ) : Math.abs( Math.ceil( n ) ) ).toString();
				p = p ? p : '.';
				var f = n.toString().substring( i.length + s.length );
				if ( f = d || f.length > 1 ? ( p + f.substring( 1 ) ) : '' ){
					for ( var j = f.length - 1; j < d; j++ ) {
						f += '0';
					}
				}
				if ( g = ( g && g != p ) ? g : ',' ) {
					for ( var j = i.length - 3; j > 0; j -= 3 ) {
						i = i.substring ( 0, j ) + g + i.substring( j );
					}
				}
				return s + i + f;
	
			};

			this.pad = function( v, l, c ) {

				var s = '' + v;

				if ( !c ) { c = '0'; }

				while ( s.length < l ) {
					s = c + s;
				}

				return s;

			};

			this.querySting = function( a ) {

				var u = '';

				for ( var i in a ) {
					u += ( !u.length ? '?' : '&' ) + this.encode( i ) + '=' + this.encode( a[i] );
				}

				return u;

			};

			this.random = function( l, u ) {

				if ( !l || !u ) { l = 1; u = 99999; }

				return Math.floor( Math.random() * ( u - l + 1 ) + l );

			};

			this.round = function( n, d ) {

				if ( Juice.Type.number( n ) ) {
					var m = Math.pow( 10, d );
					return Math.round( n * m ) / m;
				}
				return n;

			};

			this.rtrim = function( s ) {

				while ( s.substr( s.length - 1 , 1 ) == ' ' ) {
					s = s.substring( 0, s.length - 1 );
				}

				return s;

			};

			this.trim = function( s ) {
				return this.rtrim( this.ltrim( s ) );
			};

		},

		Type: new function() {

			this.array = function( o ) {
				return ( o instanceof Array ? true : false );
			};

			this.callback = function( v ) {
				return ( typeof v == 'function' ? true : false );
			};

			this.hexColour = function( v ) {

				if ( v ) {
					return v.match( new RegExp( '^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$', 'i' ) ) ? true : false;
				}

				return false;

			};

			this.number = function( v ) {
				return ( !isNaN( v ) ? true : false );
			};

		},

		Window: new function() {

			this.open = function( url, focus ) {

				var win = window.open( url );

				if ( focus ) { win.focus(); }

				return win;

			};

		},

		Prefs: {
			container: 'body',
			debug: false,
			image: '/includes/library/juice/images/'
		}

	}

})();

// Popover
(function(){

	if ( typeof Juice == 'undefined' ) {
		throw new Error( 'popover.juice.js requires the core.juice.js component.' );
	}

	Juice.Popover = function( setup ) {

		var popover, container, shadow, header, content, inner, overlay, iframe, size = {}, myself = this;

		this.setup = function() {

			popover = {
				parent: Juice.Element.output( Juice.Prefs.container ),
				directory: Juice.Prefs.image + 'popover/',
				border: setup.border ||  1,
				padding: setup.padding || 10,
				reload: setup.reload ? true : false
			};

			overlay						= Juice.Element.create( 'DIV', null, 'overlay' );
			overlay.style.visibility	= 'hidden';
			overlay.style.position		= 'absolute';
			overlay.style.zIndex		= '900';
			overlay.style.width			= '100%';
			overlay.style.background	= setup.background || 'black';
			overlay.style.top = overlay.style.left = 0;

			container					= Juice.Element.create( 'DIV' );
			container.style.visibility	= 'hidden';
			container.style.position	= 'absolute';
			container.style.zIndex		= '910';
			container.style.padding		= '8px';
			container.style.top = container.style.left = 0;

			shadow						= Juice.Element.create( 'DIV' );
			shadow.style.zIndex			= '915';
			shadow.style.background		= setup.shadow || 'black';
			shadow.style.position		= 'absolute';
			shadow.style.top = shadow.style.left = 0;
			shadow.style.width = shadow.style.height = '100%';

			container.appendChild( shadow );

			inner						= Juice.Element.create( 'DIV' );
			inner.style.zIndex			= '920';
			inner.style.position		= 'relative';
			inner.style.background		= setup.color || 'white';
			inner.style.padding			= popover.padding + 'px';
			inner.style.border			= popover.border + 'px solid black';
			inner.style.backgroundPosition = 'center center';
			inner.style.backgroundRepeat = 'no-repeat';

			container.appendChild( inner );

			content						= Juice.Element.create( 'DIV' );
			content.style.zIndex		= '930';
			content.style.overflow		= 'auto';

			inner.appendChild( content );

			Juice.Element.opacity( overlay, setup.opacity || 50 );
			Juice.Element.opacity( shadow, setup.opacity / 1.5 || 30 );

			Juice.Event.add( overlay, 'click', myself.hide );
			Juice.Event.add( window, 'resize', myself.resize );
			Juice.Event.add( window, 'scroll', myself.position );

			myself.content( ( setup.type || 'frame' ), setup.action, ( setup.method || 'GET' ) );

		};

		this.content = function( type, action, method ) {

			myself.load();

			switch ( type ) {

				case 'ajax':

					if ( Juice.Ajax ) {

					var x = new Juice.Ajax();
						x.ready = function( res ) {
							myself.output( res );
							myself.parse( content );
						}
						x.request( action, method );

					} else {
						myself.error( 'ajax.juice.js componant is required to use ajax.' );
					}

				break;
				case 'image':

					var img = new Image();
						img.onload = function() {
							content.style.background = 'url(' + action + ' ) center center no-repeat';
							setup.width = img.width;
							setup.height = img.height;
							myself.output();
						};
						img.onerror = function() {
							myself.error( 'Failed to load image' );
						};
						img.src = action;

				break;
				case 'inline':

					var element;

					if ( element = Juice.$( action ) ) {
						myself.output( element.innerHTML );
						myself.parse( popover.content );
					} else {
						myself.error( 'Inline content element could not be found' );
					}

				break;
				case 'frame':

					iframe					= Juice.Element.create( 'IFRAME' );
					iframe.style.overflow	= 'auto';
					iframe.src				= action;
					iframe.style.border = iframe.frameBorder = 0;
					iframe.style.width = iframe.style.height = '100%';
					iframe.onload = iframe.onreadystatechange = myself.loaded;

					content.style.overflow = 'hidden';
					content.appendChild( iframe );

				break;
				default:

					myself.error( 'Invalid action type' );

			}

			myself.show();

		};

		this.load = function() {

			content.scrollTop = 0;
			inner.style.backgroundImage = 'url(' + popover.directory + 'loading.gif)';
			content.style.visibility = 'hidden';

		};

		this.loaded = function() {

			inner.style.backgroundImage = '';
			content.style.visibility = 'visible';

		};

		this.output = function( val ) {

			myself.size();
			myself.position();
			myself.loaded();

			if ( val ) { content.innerHTML = val; }

		};

		this.error = function( err ) {

			myself.hide();

			Juice.Debug( new Error( 'Juice.Popover: ' + err ) );

		};

		this.encode = function( name, value ) {

			return encodeURIComponent( name ) + '=' + encodeURIComponent( value );

		};

		this.overlay = function() {

			if ( overlay.parentNode ) {
				popover.parent.removeChild( overlay );
			}

			var page = Juice.Browser.inner();

			overlay.style.height = page.height + 'px';

			popover.parent.appendChild( overlay );

			Juice.Element.obstructions( overlay );

		};

		this.show = function() {

			popover.offset = popover.border + popover.padding;

			popover.parent.appendChild( container );

			myself.resize();

			overlay.style.visibility = container.style.visibility = 'visible';

		};

		this.resize = function() {

			myself.size();
			myself.overlay();
			myself.position();

		};

		this.size = function( type ) {

			var limits = Juice.Browser.dimensions(), width, height;			

			size.max = {
				width: limits.width - 100,
				height: limits.height - 100
			};

			switch ( type ) {
				case 'max':
					width = size.max.width;
					height = size.max.height;
				break;
				default:
					width = setup.width;
					height = setup.height;
			}

			if ( height ) {
				if ( typeof height == 'number' ) {
					height = height;
				} else if ( ( height.toString() ) && ( height.substring( height.length - 1 ) == '%' ) ) {
					height = ( limits.height / 100 ) * parseInt( height );
				}
			} else {
				height = ( limits.height / 100 ) * 30;
			}

			if ( height > size.max.height ) {
				height = size.max.height;
			}

			if ( width ) {
				if ( typeof width == 'number' ) {
					width = width;
				} else if ( ( width.toString() ) && ( width.substring( width.length - 1 ) == '%' ) ) {
					width = ( limits.width / 100 ) * parseInt( width );
				}
			} else {
				width = ( limits.width / 100 ) * 30;
			}

			if ( width > size.max.width ) {
				width = size.max.width;
			}

			size.height = height;
			size.width = width;

			if ( !Juice.Browser.detect().ie6 ) {
				shadow.style.width = ( size.width + ( ( popover.border + popover.padding ) * 2 ) + 18 ) + 'px';
				shadow.style.height = ( size.height + ( ( popover.border + popover.padding ) * 2 ) + 18 ) + 'px';
			}

			content.style.height = ( size.height + ( popover.border * 2 ) ) + 'px';
			content.style.width = ( size.width + ( popover.border * 2 ) ) + 'px';

		};

		this.position = function() {

			var b = Juice.Browser.dimensions();
			var s = Juice.Element.scroll();
			var p = { top: 0, left: 0 };
			var o = Juice.Browser.detect().ie ? 0 : 9;

			p.top = ( b.height / 2 ) - ( ( size.height / 2 ) ) - ( popover.padding * 2 ) + s.top;
			p.left = ( b.width / 2 ) - ( ( size.width / 2 ) ) - ( popover.padding * 2 ) + s.left - o;

			container.style.top = p.top + 'px';
			container.style.left = p.left + 'px';

		};

		this.setReload = function( reload ) {

			 popover.reload = ( reload === true ? true : false );

		};

		this.hide = function() {

			if ( Juice.Type.callback( setup.onclose ) ) {
				setup.onclose( this );
			}

			if ( popover.reload === true ) {
				window.location.reload( true );
			}

			Juice.Event.remove( overlay, 'click', myself.hide );
			Juice.Event.remove( window, 'resize', myself.resize );
			Juice.Event.remove( window, 'scroll', myself.position );
			
			popover.parent.removeChild( container );
			popover.parent.removeChild( overlay );			

		};

		this.form = function( form ) {

			var url = append = '';

			for ( var i = 0; i < form.elements.length; i++ ) {

				var element = form.elements[i];

				switch( element.nodeName ) {
					case 'BUTTON':
					case 'TEXTAREA':
						append = myself.encode( element.name, element.value );
					break;
					case 'INPUT':
						switch( element.type ) {
							case 'text':
							case 'hidden':
							case 'password':
							case 'submit':
								append = myself.encode( element.name, element.value );
							break;
							case 'checkbox':
							case 'radio':
								if ( element.checked ) append = myself.encode( element.name, element.value );
							break;
						}
					break;
					case 'SELECT':
						var option;
						for ( var j in element.options ){
							if ( option = element.options[j] ){
								if ( option.selected ){
									if ( append ) {	append += '&'; }
									append += myself.encode( element.name, option.value );
								}
							}
						}
					break;
				}

				if ( append ) { url += ( url ? '&' : '' ) + append; }

			}

			myself.content( 'ajax', form.getAttribute( 'action' ) + '?' + url, ( form.method || 'GET' ) );

		};

		this.maximise = function() {

			myself.size( 'max' );
			myself.position();

		};

		this.minimise = function() {

			myself.size( );
			myself.position();

		};

		this.parse = function( node, base ) {

			if ( !node || node.nodeType != 1 ) return false;
			if ( !base ) base = node;

			var attr;

			if ( node.nodeName == 'FORM' ) {
				node.onsubmit = function() {
					myself.form( node );
					return false;
				}
			}

			if ( attr = node.getAttribute( 'popover' ) ) {
				switch ( attr ) {
					case 'autoclose':
						myself.hide();
					break;
					case 'close':
						node.onclick = myself.hide;
					break;
					case 'max':
						node.onclick = myself.maximise;
					break;
					case 'min':
						node.onclick = myself.minimise;
					break;
					case 'reload':
						myself.setReload( true );
					break;
				}
			}

			if ( node.childNodes ) {
				for ( var i = 0; i < node.childNodes.length; i++ ) {
					myself.parse( node.childNodes[i], base );
				}
			}

		};

		this.setup();

	}

})();

// Effects
(function() {

	if ( typeof Juice == 'undefined' ) {
		throw new Error( 'effects.juice.js requires the core.juice.js component.' );
	}

	Juice.Effect = new function() {

		var effects = [];

		this.track = new function() {

			this.add = function( e, t, c ) {

				effects.push( { ele: e, effect: t, config: c } );

			};

			this.fetch = function( e, t ) {

				for ( var i in effects ) {
					var effect = effects[i];
					if ( effect.ele == e && effect.effect == t  ) {
						return effect;
					}
				}

				return false;

			};

			this.tidy = function( e, t ) {

				for ( var i in effects ) {
					var effect = effects[i];
					if ( effect.ele == e && effect.effect == t  ) {
						delete effect;
						return true;
					}
				}

				return false;

			};

		};

		this.fader = new function() {

			var myself = this, effect = 'fader';

			this.create = function( id ) {

				var n;

				if ( n = Juice.Effect.track.fetch( Juice.$( id ), effect ) ) {
					return n;
				} else {
					n = { ele: Juice.$( id ), config: { interval: 5, duration: 500 } };
				}

				if ( n.ele.style.visibility == 'hidden' ) {
					n.config.opacity = 0;
				} else {
					n.config.opacity = 100;
				}

				Juice.Effect.track.add( n.ele, effect, n.config );

				return n;

			};

			this.start = function( n, d ) {

				n.config.started = new Date().getTime();

				if ( d ) {
					n.config.direction = d;
				}

				n.ele.style.visibility = 'visible';

				n.config.timer = setInterval( function() {
					myself.fade( n );
				}, n.config.interval );

			};

			this.show = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.visibility != 'hidden' ) { return; }

				n.config.running = true;

				myself.start( n, 'show' );

				return;

			};

			this.hide = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.visibility == 'hidden' ) { return; }

				n.config.running = true;

				myself.start( n, 'hide' );

				return;

			};

			this.fade = function( n ){

				var t = new Date().getTime() - n.config.started;

				if ( t > n.config.duration ) {

					myself.stop( n );

				} else {

					var o = Juice.Effect.ease( t, n.config.duration, n.config.opacity );

					if ( n.config.direction == 'hide' ) {
						o = n.config.opacity - o;
					}

					Juice.Element.opacity( n.ele, o );

				}

				return;

			};

			this.stop = function( n ){

				clearInterval( n.config.timer );

				if ( n.config.direction == 'hide' ) {
					n.ele.style.visibility = 'hidden';
					Juice.Element.opacity( n.ele, 0 );
				} else {
					n.ele.style.visibility = 'visible';
					Juice.Element.opacity( n.ele, 100 );
				}

				n.config.running = false;

				Juice.Effect.track.tidy( n.ele, effect );

			};

			this.toggle = function( id ) {

				var n = myself.create( id );

				if ( n.config.running ) { return; }

				myself.start( n, ( n.ele.style.visibility != 'hidden' ? 'hide' : 'show' ) );

			};

		};

		this.slider = new function() {

			var myself = this, effect = 'slider';

			this.create = function( id ) {

				var n;

				if ( n = Juice.Effect.track.fetch( Juice.$( id ), effect ) ) {
					return n;
				} else {
					n = { ele: Juice.$( id ), config: { interval: 5, duration: 300 } };
				}

				if ( !n.config.height ) {
					if ( n.ele.style.display == 'none' ) {
						n.ele.style.display = '';
					}
					n.config.height = Juice.Element.dimensions( n.ele ).height;
				}

				Juice.Effect.track.add( n.ele, effect, n.config );

				return n;

			};

			this.start = function( n, d ) {

				n.config.started = new Date().getTime();

				if ( n.config.direction == 'hide' ){
					n.ele.style.height = 0;
				}

				n.ele.style.display = 'block';

				if ( d ) {
					n.config.direction = d;
				}

				n.config.timer = setInterval( function() {
					myself.slide( n );
				}, n.config.interval );

			};

			this.show = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.display != 'none' ) { return; }

				n.config.running = true;

				myself.start( n, 'show' );

				return;

			};

			this.hide = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.display == 'none' ) { return; }

				n.config.running = true;

				myself.start( n, 'hide' );

				return;

			};

			this.slide = function( n ){

				var t = new Date().getTime() - n.config.started;

				if ( t > n.config.duration ) {

					myself.stop( n );

				} else {

					var h = Juice.Effect.ease( t, n.config.duration, n.config.height );

					if ( n.config.direction == 'hide' ) {
						h = n.config.height - h;
					}

					n.ele.style.height = h + 'px';

				}

				return;

			};

			this.stop = function( n ){

				clearInterval( n.config.timer );

				if ( n.config.direction == 'hide' ) {
					n.ele.style.display = 'none';
				} else {
					n.ele.style.display = 'block';
					n.ele.style.height = n.config.height + 'px';
				}

				n.config.running = false;

				Juice.Effect.track.tidy( n.ele, effect );

			};

			this.toggle = function( id ) {

				var n = myself.create( id );

				if ( n.config.running ) { return; }

				myself.start( n, ( n.ele.style.display != 'none' ? 'hide' : 'show' ) );

			};

		};

		this.blender = new function() {

			var myself = this, effect = 'blend';

			this.create = function( id, to, from, callback ) {

				var n = {
					ele: Juice.$( id ),
					config: {
						interval: 1,
						percent: 0,
						to: to,
						callback: callback
					}
				};

				if ( from ) {
					n.config.from = from;
				} else {
					var bg = Juice.Element.style( Juice.$( id ), 'backgroundColor' );
					n.config.from = Juice.Type.hexColour( bg ) ? bg : Juice.Convert.fullrgbhex( bg );
				}

				Juice.Effect.track.add( n.ele, effect, n.config );

				return n;

			};

			this.stop = function( n ) {

				clearInterval( n.config.timer );

				n.config.running = false;

				Juice.Effect.track.tidy( n.ele, effect );

			}

			this.blend = function( n ) {

				if ( n.config.percent >= 100 ) { myself.stop( n ); }

				n.config.percent++;

				var start	= Juice.Convert.hexrgb( n.config.from );
				var end		= Juice.Convert.hexrgb( n.config.to );
				var percent = n.config.percent / 100;

				var current = {
					r: Math.floor( start.r + ( percent * ( end.r - start.r ) ) ),
					g: Math.floor( start.g + ( percent * ( end.g - start.g ) ) ),
					b: Math.floor( start.b + ( percent * ( end.b - start.b ) ) )
				}

				var colour = Juice.Convert.rgbhex( current.r, current.g, current.b );

				if ( !colour ) { return };

				if ( Juice.Type.callback( n.config.callback ) ) {
					n.config.callback( colour, n.ele );
				} else {
					n.ele.style.backgroundColor = colour;
				}

			};

			this.show = function( id, to, from, callback ) {

				if ( !id || !to ) { return false; }

				var n = myself.create( id, to, from, callback );

				if ( !n || n.config.running ) { return; }

				n.config.running = true;
				n.config.percent = 0;

				n.config.timer = setInterval( function() {
					myself.blend( n );
				}, n.config.interval );

			};

		};

		this.resize = function( n, s ) {

			var myself = this;

			this.setup = function() {

				n = Juice.$( n );

				var d = Juice.Element.dimensions( n );

				if ( s.width ) {
					var mw = new myself.move( parseInt( s.width ), d.width, s.velocity );
					var w = setInterval( function() {
						if ( mw.stopped() == true ) {
							clearInterval( w );
						}
						n.style.width = mw.update() + 'px';
					}, 15 );
				}

				if ( s.height ) {
					var mh = new myself.move( parseInt( s.height ), d.height, s.velocity );
					var h = setInterval( function() {
						
						if ( mh.stopped() == true ) {
							clearInterval( h );
						} else {

							n.style.height = mh.update() + 'px';
						}
					}, 15 );
				}

			};

			this.move = function( targ, pos, vel ) {

				var p, t, v;

				this.setup = function() {
					p = Math.round( pos );
					t = Math.round( targ );
					v = ( vel ? Math.round( vel ) : 0 );
				};

				this.update = function() {
					p += v;
					if ( v < 0 ){
						if ( p - v * ( v - 1 ) / 2 < t ) {
							v++;
						} else if ( p - ( v - 1 ) * ( v - 2 ) / 2 >= t ) {
							v--;
						}
					} else {
						if ( p + v * ( v + 1 ) / 2 > t ){
							v--;
						} else if ( p + ( v + 1 ) * ( v + 2 ) / 2 <= t ){
							v++;
						}
					}
					return p;
				};

				this.stopped = function() {
					return ( p == t && v == 0 );
				};

				this.setup();

			};

			this.setup();

		};

		this.ease = function( e, d, c ) {

			return Math.round( e / d * c );

		};

	}

})();


Juice.Event.add(window, 'load', function() {
		Juice.Event.add( 'nigglelink', 'click', function(event) {
				Juice.Event.cancel(event);
				new Juice.Popover({ 
						action: Juice.$('nigglelink').getAttribute('rel'), 
						type: 'frame',
						width: 580,
						height: 464,
						padding: '0',
						border: '0',
						event: event
				});
		});
});




