// Labels for Ajax javascripts
// $Id: labels.js 27058 2007-03-13 11:25:34Z bas $
//

window.labels								= new Object();

window.labels["main"] 						= new Object();
window.labels["main"]["loading"]			= "loading...";

/* autocomplete */
window.labels["autocomplete"] 				= new Object();
window.labels["autocomplete"]["cancel"]		= "Annuleer";

/* sortable */
window.labels["sortable"]	 				= new Object();

/* lightbox */
window.labels["lightbox"]					= new Object();
window.labels["lightbox"]["cancel"]			= "Annuleer";
window.labels["lightbox"]["save"]			= "OK";

/* editatonce */
window.labels["editatonce"] 				= new Object();
window.labels["editatonce"]["saving"]		= "gegevens bewaren";

/* editinplace */
window.labels["editinplace"] 				= new Object();
window.labels["editinplace"]["cancel"]		= "Annuleer";
window.labels["editinplace"]["save"]		= "OK";
window.labels["editinplace"]["onempty"]		= "Add value";
window.labels["editinplace"]["saving"]		= "gegevens bewaren";
window.labels["editinplace"]["fetching"]	= "gegevens ophalen";
window.labels["editinplace"]["validate"]			= new Object();
window.labels["editinplace"]["validate"]["msg"]		= "Type een geldige waarde";
window.labels["editinplace"]["validate"]["out"]		= "Type een geldige waarde";
window.labels["editinplace"]["validate"]["integer"]	= "Type alleen nummers tussen 0-9";
window.labels["editinplace"]["validate"]["float"]	= "Type alleen nummers tussen 0-9";

/* unlink */
window.labels["unlink"] 					= new Object();
window.labels["unlink"]["cancel"]			= "Nee";
window.labels["unlink"]["yes"]				= "Ja";
window.labels["unlink"]["confirm"]			= "Verwijder";
window.labels["unlink"]["title"]			= "Verwijder dit item";

/*

 * jQuery - New Wave Javascript
 *
 * Copyright (c) 2006 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt) 
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2006-11-02 17:48:52 +0100 (Thu, 02 Nov 2006) $
 * $Rev: 24349 $
 */

// Global undefined variable
window.undefined = window.undefined;
function jQuery(a,c) {

	// Shortcut for document ready (because $(document).each() is silly)
	if ( a && a.constructor == Function && jQuery.fn.ready )
		return jQuery(document).ready(a);

	// Make sure that a selection was provided
	a = a || jQuery.context || document;

	// Watch for when a jQuery object is passed as the selector
	if ( a.jquery )
		return $( jQuery.merge( a, [] ) );

	// Watch for when a jQuery object is passed at the context
	if ( c && c.jquery )
		return $( c ).find(a);
	
	// If the context is global, return a new object
	if ( window == this )
		return new jQuery(a,c);

	// Handle HTML strings
	var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
	if ( m ) a = jQuery.clean( [ m[1] ] );

	// Watch for when an array is passed in
	this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ?
		// Assume that it is an array of DOM Elements
		jQuery.merge( a, [] ) :

		// Find the matching elements and save them for later
		jQuery.find( a, c ) );

  // See if an extra function was provided
	var fn = arguments[ arguments.length - 1 ];
	
	// If so, execute it in context
	if ( fn && fn.constructor == Function )
		this.each(fn);
}

// Map over the $ in case of overwrite
if ( $ )
	jQuery._$ = $;

// Map the jQuery namespace to the '$' one
var $ = jQuery;

jQuery.fn = jQuery.prototype = {
	jquery: "$Rev: 24349 $",

	size: function() {
		return this.length;
	},

	get: function( num ) {
		// Watch for when an array (of elements) is passed in
		if ( num && num.constructor == Array ) {

			// Use a tricky hack to make the jQuery object
			// look and feel like an array
			this.length = 0;
			[].push.apply( this, num );
			
			return this;
		} else
			return num == undefined ?

				// Return a 'clean' array
				jQuery.map( this, function(a){ return a } ) :

				// Return just the object
				this[num];
	},
	each: function( fn, args ) {
		return jQuery.each( this, fn, args );
	},

	index: function( obj ) {
		var pos = -1;
		this.each(function(i){
			if ( this == obj ) pos = i;
		});
		return pos;
	},

	attr: function( key, value, type ) {
		// Check to see if we're setting style values
		return key.constructor != String || value != undefined ?
			this.each(function(){
				// See if we're setting a hash of styles
				if ( value == undefined )
					// Set all the styles
					for ( var prop in key )
						jQuery.attr(
							type ? this.style : this,
							prop, key[prop]
						);
				
				// See if we're setting a single key/value style
				else
					jQuery.attr(
						type ? this.style : this,
						key, value
					);
			}) :
			
			// Look for the case where we're accessing a style value
			jQuery[ type || "attr" ]( this[0], key );
	},

	css: function( key, value ) {
		return this.attr( key, value, "curCSS" );
	},
	text: function(e) {
		e = e || this;
		var t = "";
		for ( var j = 0; j < e.length; j++ ) {
			var r = e[j].childNodes;
			for ( var i = 0; i < r.length; i++ )
				t += r[i].nodeType != 1 ?
					r[i].nodeValue : jQuery.fn.text([ r[i] ]);
		}
		return t;
	},
	wrap: function() {
		// The elements to wrap the target around
		var a = jQuery.clean(arguments);
		
		// Wrap each of the matched elements individually
		return this.each(function(){
			// Clone the structure that we're using to wrap
			var b = a[0].cloneNode(true);
			
			// Insert it before the element to be wrapped
			this.parentNode.insertBefore( b, this );
			
			// Find he deepest point in the wrap structure
			while ( b.firstChild )
				b = b.firstChild;
			
			// Move the matched element to within the wrap structure
			b.appendChild( this );
		});
	},
	append: function() {
		return this.domManip(arguments, true, 1, function(a){
			this.appendChild( a );
		});
	},
	prepend: function() {
		return this.domManip(arguments, true, -1, function(a){
			this.insertBefore( a, this.firstChild );
		});
	},
	before: function() {
		return this.domManip(arguments, false, 1, function(a){
			this.parentNode.insertBefore( a, this );
		});
	},
	after: function() {
		return this.domManip(arguments, false, -1, function(a){
			this.parentNode.insertBefore( a, this.nextSibling );
		});
	},
	end: function() {
		return this.get( this.stack.pop() );
	},
	find: function(t) {
		return this.pushStack( jQuery.map( this, function(a){
			return jQuery.find(t,a);
		}), arguments );
	},

	clone: function(deep) {
		return this.pushStack( jQuery.map( this, function(a){
			return a.cloneNode( deep != undefined ? deep : true );
		}), arguments );
	},

	filter: function(t) {
		return this.pushStack(
			t.constructor == Array &&
			jQuery.map(this,function(a){
				for ( var i = 0; i < t.length; i++ )
					if ( jQuery.filter(t[i],[a]).r.length )
						return a;
			}) ||

			t.constructor == Boolean &&
			( t ? this.get() : [] ) ||

			t.constructor == Function &&
			jQuery.grep( this, t ) ||

			jQuery.filter(t,this).r, arguments );
	},

	not: function(t) {
		return this.pushStack( t.constructor == String ?
			jQuery.filter(t,this,false).r :
			jQuery.grep(this,function(a){ return a != t; }), arguments );
	},

	add: function(t) {
		return this.pushStack( jQuery.merge( this, t.constructor == String ?
			jQuery.find(t) : t.constructor == Array ? t : [t] ), arguments );
	},
	is: function(expr) {
		return expr ? jQuery.filter(expr,this).r.length > 0 : this.length > 0;
	},
	domManip: function(args, table, dir, fn){
		var clone = this.size() > 1;
		var a = jQuery.clean(args);
		
		return this.each(function(){
			var obj = this;
			
			if ( table && this.nodeName == "TABLE" && a[0].nodeName != "THEAD" ) {
				var tbody = this.getElementsByTagName("tbody");

				if ( !tbody.length ) {
					obj = document.createElement("tbody");
					this.appendChild( obj );
				} else
					obj = tbody[0];
			}

			for ( var i = ( dir < 0 ? a.length - 1 : 0 );
				i != ( dir < 0 ? dir : a.length ); i += dir ) {
					fn.apply( obj, [ clone ? a[i].cloneNode(true) : a[i] ] );
			}
		});
	},
	pushStack: function(a,args) {
		var fn = args && args[args.length-1];

		if ( !fn || fn.constructor != Function ) {
			if ( !this.stack ) this.stack = [];
			this.stack.push( this.get() );
			this.get( a );
		} else {
			var old = this.get();
			this.get( a );
			if ( fn.constructor == Function )
				return this.each( fn );
			this.get( old );
		}

		return this;
	}
};

jQuery.extend = jQuery.fn.extend = function(obj,prop) {
	if ( !prop ) { prop = obj; obj = this; }
	for ( var i in prop ) obj[i] = prop[i];
	return obj;
};

jQuery.extend({
	init: function(){
		jQuery.initDone = true;
		
		jQuery.each( jQuery.macros.axis, function(i,n){
			jQuery.fn[ i ] = function(a) {
				var ret = jQuery.map(this,n);
				if ( a && a.constructor == String )
					ret = jQuery.filter(a,ret).r;
				return this.pushStack( ret, arguments );
			};
		});
		
		jQuery.each( jQuery.macros.to, function(i,n){
			jQuery.fn[ i ] = function(){
				var a = arguments;
				return this.each(function(){
					for ( var j = 0; j < a.length; j++ )
						$(a[j])[n]( this );
				});
			};
		});
		
		jQuery.each( jQuery.macros.each, function(i,n){
			jQuery.fn[ i ] = function() {
				return this.each( n, arguments );
			};
		});

		jQuery.each( jQuery.macros.filter, function(i,n){
			jQuery.fn[ n ] = function(num,fn) {
				return this.filter( ":" + n + "(" + num + ")", fn );
			};
		});
		
		jQuery.each( jQuery.macros.attr, function(i,n){
			n = n || i;
			jQuery.fn[ i ] = function(h) {
				return h == undefined ?
					this.length ? this[0][n] : null :
					this.attr( n, h );
			};
		});
	
		jQuery.each( jQuery.macros.css, function(i,n){
			jQuery.fn[ n ] = function(h) {
				return h == undefined ?
					( this.length ? jQuery.css( this[0], n ) : null ) :
					this.css( n, h );
			};
		});
	
	},
	each: function( obj, fn, args ) {
		if ( obj.length == undefined )
			for ( var i in obj )
				fn.apply( obj[i], args || [i, obj[i]] );
		else
			for ( var i = 0; i < obj.length; i++ )
				fn.apply( obj[i], args || [i, obj[i]] );
		return obj;
	},
	
	className: {
		add: function(o,c){
			if (jQuery.className.has(o,c)) return;
			o.className += ( o.className ? " " : "" ) + c;
		},
		remove: function(o,c){
			if( !c ) {
				o.className = "";
			} else {
				var classes = o.className.split(" ");
				for(var i=0; i<classes.length; i++) {
					if(classes[i] == c) {
						classes.splice(i, 1);
						break;
					}
				}
				o.className = classes.join(' ');
			}
		},
		has: function(e,a) {
			if ( e.className != undefined )
				e = e.className;
			return new RegExp("(^|\\s)" + a + "(\\s|$)").test(e);
		}
	},
	swap: function(e,o,f) {
		for ( var i in o ) {
			e.style["old"+i] = e.style[i];
			e.style[i] = o[i];
		}
		f.apply( e, [] );
		for ( var i in o )
			e.style[i] = e.style["old"+i];
	},
	
	css: function(e,p) {
		if ( p == "height" || p == "width" ) {
			var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
	
			for ( var i in d ) {
				old["padding" + d[i]] = 0;
				old["border" + d[i] + "Width"] = 0;
			}
	
			jQuery.swap( e, old, function() {
				if (jQuery.css(e,"display") != "none") {
					oHeight = e.offsetHeight;
					oWidth = e.offsetWidth;
				} else {
					e = $(e.cloneNode(true)).css({
						visibility: "hidden", position: "absolute", display: "block"
					}).prependTo("body")[0];

					oHeight = e.clientHeight;
					oWidth = e.clientWidth;
					
					e.parentNode.removeChild(e);
				}
			});
	
			return p == "height" ? oHeight : oWidth;
		} else if ( p == "opacity" && jQuery.browser.msie )
			return parseFloat( jQuery.curCSS(e,"filter").replace(/[^0-9.]/,"") ) || 1;

		return jQuery.curCSS( e, p );
	},

	curCSS: function(elem, prop, force) {
		var ret;
	
		if (!force && elem.style[prop]) {

			ret = elem.style[prop];

		} else if (elem.currentStyle) {

			var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase()}); 
			ret = elem.currentStyle[prop] || elem.currentStyle[newProp];

		} else if (document.defaultView && document.defaultView.getComputedStyle) {

			prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
			var cur = document.defaultView.getComputedStyle(elem, null);

			if ( cur )
				ret = cur.getPropertyValue(prop);
			else if ( prop == 'display' )
				ret = 'none';
			else
				jQuery.swap(elem, { display: 'block' }, function() {
					ret = document.defaultView.getComputedStyle(this,null).getPropertyValue(prop);
				});

		}
		
		return ret;
	},
	
	clean: function(a) {
		var r = [];
		for ( var i = 0; i < a.length; i++ ) {
			if ( a[i].constructor == String ) {

				var table = "";
	
				if ( !a[i].indexOf("<thead") || !a[i].indexOf("<tbody") ) {
					table = "thead";
					a[i] = "<table>" + a[i] + "</table>";
				} else if ( !a[i].indexOf("<tr") ) {
					table = "tr";
					a[i] = "<table>" + a[i] + "</table>";
				} else if ( !a[i].indexOf("<td") || !a[i].indexOf("<th") ) {
					table = "td";
					a[i] = "<table><tbody><tr>" + a[i] + "</tr></tbody></table>";
				}
	
				var div = document.createElement("div");
				div.innerHTML = a[i];
	
				if ( table ) {
					div = div.firstChild;
					if ( table != "thead" ) div = div.firstChild;
					if ( table == "td" ) div = div.firstChild;
				}
	
				for ( var j = 0; j < div.childNodes.length; j++ )
					r.push( div.childNodes[j] );
				} else if ( a[i].jquery || a[i].length && !a[i].nodeType )
					for ( var k = 0; k < a[i].length; k++ )
						r.push( a[i][k] );
				else if ( a[i] !== null )
					r.push(	a[i].nodeType ? a[i] : document.createTextNode(a[i].toString()) );
		}
		return r;
	},
	
	expr: {
		"": "m[2]== '*'||a.nodeName.toUpperCase()==m[2].toUpperCase()",
		"#": "a.getAttribute('id')&&a.getAttribute('id')==m[2]",
		":": {
			// Position Checks
			lt: "i<m[3]-0",
			gt: "i>m[3]-0",
			nth: "m[3]-0==i",
			eq: "m[3]-0==i",
			first: "i==0",
			last: "i==r.length-1",
			even: "i%2==0",
			odd: "i%2",
			
			// Child Checks
			"first-child": "jQuery.sibling(a,0).cur",
			"last-child": "jQuery.sibling(a,0).last",
			"only-child": "jQuery.sibling(a).length==1",
			
			// Parent Checks
			parent: "a.childNodes.length",
			empty: "!a.childNodes.length",
			
			// Text Check
			contains: "(a.innerText||a.innerHTML).indexOf(m[3])>=0",
			
			// Visibility
			visible: "a.type!='hidden'&&jQuery.css(a,'display')!='none'&&jQuery.css(a,'visibility')!='hidden'",
			hidden: "a.type=='hidden'||jQuery.css(a,'display')=='none'||jQuery.css(a,'visibility')=='hidden'",
			
			// Form elements
			enabled: "!a.disabled",
			disabled: "a.disabled",
			checked: "a.checked",
			selected: "a.selected"
		},
		".": "jQuery.className.has(a,m[2])",
		"@": {
			"=": "z==m[4]",
			"!=": "z!=m[4]",
			"^=": "!z.indexOf(m[4])",
			"$=": "z.substr(z.length - m[4].length,m[4].length)==m[4]",
			"*=": "z.indexOf(m[4])>=0",
			"": "z"
		},
		"[": "jQuery.find(m[2],a).length"
	},
	
	token: [
		"\\.\\.|/\\.\\.", "a.parentNode",
		">|/", "jQuery.sibling(a.firstChild)",
		"\\+", "jQuery.sibling(a).next",
		"~", function(a){
			var r = [];
			var s = jQuery.sibling(a);
			if ( s.n > 0 )
				for ( var i = s.n; i < s.length; i++ )
					r.push( s[i] );
			return r;
		}
	],
	find: function( t, context ) {
		// Make sure that the context is a DOM Element
		if ( context && context.nodeType == undefined )
			context = null;
	
		// Set the correct context (if none is provided)
		context = context || jQuery.context || document;
	
		if ( t.constructor != String ) return [t];
	
		if ( !t.indexOf("//") ) {
			context = context.documentElement;
			t = t.substr(2,t.length);
		} else if ( !t.indexOf("/") ) {
			context = context.documentElement;
			t = t.substr(1,t.length);
			// FIX Assume the root element is right :(
			if ( t.indexOf("/") >= 1 )
				t = t.substr(t.indexOf("/"),t.length);
		}
	
		var ret = [context];
		var done = [];
		var last = null;
	
		while ( t.length > 0 && last != t ) {
			var r = [];
			last = t;
	
			t = jQuery.trim(t).replace( /^\/\//i, "" );
			
			var foundToken = false;
			
			for ( var i = 0; i < jQuery.token.length; i += 2 ) {
				var re = new RegExp("^(" + jQuery.token[i] + ")");
				var m = re.exec(t);
				
				if ( m ) {
					r = ret = jQuery.map( ret, jQuery.token[i+1] );
					t = jQuery.trim( t.replace( re, "" ) );
					foundToken = true;
				}
			}
			
			if ( !foundToken ) {
				if ( !t.indexOf(",") || !t.indexOf("|") ) {
					if ( ret[0] == context ) ret.shift();
					done = jQuery.merge( done, ret );
					r = ret = [context];
					t = " " + t.substr(1,t.length);
				} else {
					var re2 = /^([#.]?)([a-z0-9\\*_-]*)/i;
					var m = re2.exec(t);
		
					if ( m[1] == "#" ) {
						// Ummm, should make this work in all XML docs
						var oid = document.getElementById(m[2]);
						r = ret = oid ? [oid] : [];
						t = t.replace( re2, "" );
					} else {
						if ( !m[2] || m[1] == "." ) m[2] = "*";
		
						for ( var i = 0; i < ret.length; i++ )
							r = jQuery.merge( r,
								m[2] == "*" ?
									jQuery.getAll(ret[i]) :
									ret[i].getElementsByTagName(m[2])
							);
					}
				}
			}
	
			if ( t ) {
				var val = jQuery.filter(t,r);
				ret = r = val.r;
				t = jQuery.trim(val.t);
			}
		}
	
		if ( ret && ret[0] == context ) ret.shift();
		done = jQuery.merge( done, ret );
	
		return done;
	},
	
	getAll: function(o,r) {
		r = r || [];
		var s = o.childNodes;
		for ( var i = 0; i < s.length; i++ )
			if ( s[i].nodeType == 1 ) {
				r.push( s[i] );
				jQuery.getAll( s[i], r );
			}
		return r;
	},
	
	attr: function(elem, name, value){
		var fix = {
			"for": "htmlFor",
			"class": "className",
			"float": "cssFloat",
			innerHTML: "innerHTML",
			className: "className"
		};

		if ( fix[name] ) {
			if ( value != undefined ) elem[fix[name]] = value;
			return elem[fix[name]];
		} else if ( elem.getAttribute ) {
			if ( value != undefined ) elem.setAttribute( name, value );
			return elem.getAttribute( name, 2 );
		} else {
			name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
			if ( value != undefined ) elem[name] = value;
			return elem[name];
		}
	},

	// The regular expressions that power the parsing engine
	parse: [
		// Match: [@value='test'], [@foo]
		[ "\\[ *(@)S *([!*$^=]*) *Q\\]", 1 ],

		// Match: [div], [div p]
		[ "(\\[)Q\\]", 0 ],

		// Match: :contains('foo')
		[ "(:)S\\(Q\\)", 0 ],

		// Match: :even, :last-chlid
		[ "([:.#]*)S", 0 ]
	],
	
	filter: function(t,r,not) {
		// Figure out if we're doing regular, or inverse, filtering
		var g = not !== false ? jQuery.grep :
			function(a,f) {return jQuery.grep(a,f,true);};
		
		while ( t && /^[a-z[({<*:.#]/i.test(t) ) {

			var p = jQuery.parse;

			for ( var i = 0; i < p.length; i++ ) {
				var re = new RegExp( "^" + p[i][0]

					// Look for a string-like sequence
					.replace( 'S', "([a-z*_-][a-z0-9_-]*)" )

					// Look for something (optionally) enclosed with quotes
					.replace( 'Q', " *'?\"?([^'\"]*?)'?\"? *" ), "i" );

				var m = re.exec( t );

				if ( m ) {
					// Re-organize the match
					if ( p[i][1] )
						m = ["", m[1], m[3], m[2], m[4]];

					// Remove what we just matched
					t = t.replace( re, "" );

					break;
				}
			}
	
			// :not() is a special case that can be optomized by
			// keeping it out of the expression list
			if ( m[1] == ":" && m[2] == "not" )
				r = jQuery.filter(m[3],r,false).r;
			
			// Otherwise, find the expression to execute
			else {
				var f = jQuery.expr[m[1]];
				if ( f.constructor != String )
					f = jQuery.expr[m[1]][m[2]];
					
				// Build a custom macro to enclose it
				eval("f = function(a,i){" + 
					( m[1] == "@" ? "z=jQuery.attr(a,m[3]);" : "" ) + 
					"return " + f + "}");
				
				// Execute it against the current filter
				r = g( r, f );
			}
		}
	
		// Return an array of filtered elements (r)
		// and the modified expression string (t)
		return { r: r, t: t };
	},
	trim: function(t){
		return t.replace(/^\s+|\s+$/g, "");
	},
	parents: function( elem ){
		var matched = [];
		var cur = elem.parentNode;
		while ( cur && cur != document ) {
			matched.push( cur );
			cur = cur.parentNode;
		}
		return matched;
	},
	sibling: function(elem, pos, not) {
		var elems = [];

		var siblings = elem.parentNode.childNodes;
		for ( var i = 0; i < siblings.length; i++ ) {
			if ( not === true && siblings[i] == elem ) continue;

			if ( siblings[i].nodeType == 1 )
				elems.push( siblings[i] );
			if ( siblings[i] == elem )
				elems.n = elems.length - 1;
		}

		return jQuery.extend( elems, {
			last: elems.n == elems.length - 1,
			cur: pos == "even" && elems.n % 2 == 0 || pos == "odd" && elems.n % 2 || elems[pos] == elem,
			prev: elems[elems.n - 1],
			next: elems[elems.n + 1]
		});
	},
	merge: function(first, second) {
		var result = [];
		
		// Move b over to the new array (this helps to avoid
		// StaticNodeList instances)
		for ( var k = 0; k < first.length; k++ )
			result[k] = first[k];
	
		// Now check for duplicates between a and b and only
		// add the unique items
		for ( var i = 0; i < second.length; i++ ) {
			var noCollision = true;
			
			// The collision-checking process
			for ( var j = 0; j < first.length; j++ )
				if ( second[i] == first[j] )
					noCollision = false;
				
			// If the item is unique, add it
			if ( noCollision )
				result.push( second[i] );
		}
	
		return result;
	},
	grep: function(elems, fn, inv) {
		// If a string is passed in for the function, make a function
		// for it (a handy shortcut)
		if ( fn.constructor == String )
			fn = new Function("a","i","return " + fn);
			
		var result = [];
		
		// Go through the array, only saving the items
		// that pass the validator function
		for ( var i = 0; i < elems.length; i++ )
			if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
				result.push( elems[i] );
		
		return result;
	},
	map: function(elems, fn) {
		// If a string is passed in for the function, make a function
		// for it (a handy shortcut)
		if ( fn.constructor == String )
			fn = new Function("a","return " + fn);
		
		var result = [];
		
		// Go through the array, translating each of the items to their
		// new value (or values).
		for ( var i = 0; i < elems.length; i++ ) {
			var val = fn(elems[i],i);

			if ( val !== null && val != undefined ) {
				if ( val.constructor != Array ) val = [val];
				result = jQuery.merge( result, val );
			}
		}

		return result;
	},
	
	/*
	 * A number of helper functions used for managing events.
	 * Many of the ideas behind this code orignated from Dean Edwards' addEvent library.
	 */
	event: {
	
		// Bind an event to an element
		// Original by Dean Edwards
		add: function(element, type, handler) {
			// For whatever reason, IE has trouble passing the window object
			// around, causing it to be cloned in the process
			if ( jQuery.browser.msie && element.setInterval != undefined )
				element = window;
		
			// Make sure that the function being executed has a unique ID
			if ( !handler.guid )
				handler.guid = this.guid++;
				
			// Init the element's event structure
			if (!element.events)
				element.events = {};
			
			// Get the current list of functions bound to this event
			var handlers = element.events[type];
			
			// If it hasn't been initialized yet
			if (!handlers) {
				// Init the event handler queue
				handlers = element.events[type] = {};
				
				// Remember an existing handler, if it's already there
				if (element["on" + type])
					handlers[0] = element["on" + type];
			}

			// Add the function to the element's handler list
			handlers[handler.guid] = handler;
			
			// And bind the global event handler to the element
			element["on" + type] = this.handle;
	
			// Remember the function in a global list (for triggering)
			if (!this.global[type])
				this.global[type] = [];
			this.global[type].push( element );
		},
		
		guid: 1,
		global: {},
		
		// Detach an event or set of events from an element
		remove: function(element, type, handler) {
			if (element.events)
				if (type && element.events[type])
					if ( handler )
						delete element.events[type][handler.guid];
					else
						for ( var i in element.events[type] )
							delete element.events[type][i];
				else
					for ( var j in element.events )
						this.remove( element, j );
		},
		
		trigger: function(type,data,element) {
			// Touch up the incoming data
			data = data || [];
	
			// Handle a global trigger
			if ( !element ) {
				var g = this.global[type];
				if ( g )
					for ( var i = 0; i < g.length; i++ )
						this.trigger( type, data, g[i] );
	
			// Handle triggering a single element
			} else if ( element["on" + type] ) {
				// Pass along a fake event
				data.unshift( this.fix({ type: type, target: element }) );
	
				// Trigger the event
				element["on" + type].apply( element, data );
			}
		},
		
		handle: function(event) {
			if ( typeof jQuery == "undefined" ) return;

			event = event || jQuery.event.fix( window.event );
	
			// If no correct event was found, fail
			if ( !event ) return;
		
			var returnValue = true;

			var c = this.events[event.type];
		
			for ( var j in c ) {
				if ( c[j].apply( this, [event] ) === false ) {
					event.preventDefault();
					event.stopPropagation();
					returnValue = false;
				}
			}
			
			return returnValue;
		},
		
		fix: function(event) {
			if ( event ) {
				event.preventDefault = function() {
					this.returnValue = false;
				};
			
				event.stopPropagation = function() {
					this.cancelBubble = true;
				};
			}
			
			return event;
		}
	
	}
});

new function() {
	var b = navigator.userAgent.toLowerCase();

	// Figure out what browser is being used
	jQuery.browser = {
		safari: /webkit/.test(b),
		opera: /opera/.test(b),
		msie: /msie/.test(b) && !/opera/.test(b),
		mozilla: /mozilla/.test(b) && !/compatible/.test(b)
	};

	// Check to see if the W3C box model is being used
	jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
};

jQuery.macros = {
	to: {
		appendTo: "append",
		prependTo: "prepend",
		insertBefore: "before",
		insertAfter: "after"
	},

	
	css: "width,height,top,left,position,float,overflow,color,background".split(","),

	filter: [ "eq", "lt", "gt", "contains" ],

	attr: {

		val: "value",

		html: "innerHTML",

		id: null,

		title: null,

		name: null,

		href: null,

		src: null,

		rel: null
	},
	
	axis: {

		parent: "a.parentNode",

		ancestors: jQuery.parents,

		parents: jQuery.parents,

		next: "jQuery.sibling(a).next",

		prev: "jQuery.sibling(a).prev",

		siblings: jQuery.sibling,

		children: "a.childNodes"
	},

	each: {

		removeAttr: function( key ) {
			this.removeAttribute( key );
		},
		show: function(){
			this.style.display = this.oldblock ? this.oldblock : "";
			if ( jQuery.css(this,"display") == "none" )
				this.style.display = "block";
		},
		hide: function(){
			this.oldblock = this.oldblock || jQuery.css(this,"display");
			if ( this.oldblock == "none" )
				this.oldblock = "block";
			this.style.display = "none";
		},
		toggle: function(){
			$(this)[ $(this).is(":hidden") ? "show" : "hide" ].apply( $(this), arguments );
		},
		addClass: function(c){
			jQuery.className.add(this,c);
		},
		removeClass: function(c){
			jQuery.className.remove(this,c);
		},
		toggleClass: function( c ){
			jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this,c);
		},

		remove: function(a){
			if ( !a || jQuery.filter( [this], a ).r )
				this.parentNode.removeChild( this );
		},
		empty: function(){
			while ( this.firstChild )
				this.removeChild( this.firstChild );
		},
		bind: function( type, fn ) {
			if ( fn.constructor == String )
				fn = new Function("e", ( !fn.indexOf(".") ? "$(this)" : "return " ) + fn);
			jQuery.event.add( this, type, fn );
		},

		unbind: function( type, fn ) {
			jQuery.event.remove( this, type, fn );
		},
		trigger: function( type, data ) {
			jQuery.event.trigger( type, data, this );
		}
	}
};

jQuery.init();jQuery.fn.extend({

	// We're overriding the old toggle function, so
	// remember it for later
	_toggle: jQuery.fn.toggle,
	toggle: function(a,b) {
		// If two functions are passed in, we're
		// toggling on a click
		return a && b && a.constructor == Function && b.constructor == Function ? this.click(function(e){
			// Figure out which function to execute
			this.last = this.last == a ? b : a;
			
			// Make sure that clicks stop
			e.preventDefault();
			
			// and execute the function
			return this.last.apply( this, [e] ) || false;
		}) :
		
		// Otherwise, execute the old toggle function
		this._toggle.apply( this, arguments );
	},

	hover: function(f,g) {
		
		// A private function for haandling mouse 'hovering'
		function handleHover(e) {
			// Check if mouse(over|out) are still within the same parent element
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
	
			// Traverse up the tree
			while ( p && p != this ) p = p.parentNode;
			
			// If we actually just moused on to a sub-element, ignore it
			if ( p == this ) return false;
			
			// Execute the right function
			return (e.type == "mouseover" ? f : g).apply(this, [e]);
		}
		
		// Bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	},
	ready: function(f) {
		// If the DOM is already ready
		if ( jQuery.isReady )
			// Execute the function immediately
			f.apply( document );
			
		// Otherwise, remember the function for later
		else {
			// Add the function to the wait list
			jQuery.readyList.push( f );
		}
	
		return this;
	}
});

jQuery.extend({
	/*
	 * All the code that makes DOM Ready work nicely.
	 */
	isReady: false,
	readyList: [],
	
	// Handle when the DOM is ready
	ready: function() {
		// Make sure that the DOM is not already loaded
		if ( !jQuery.isReady ) {
			// Remember that the DOM is ready
			jQuery.isReady = true;
			
			// If there are functions bound, to execute
			if ( jQuery.readyList ) {
				// Execute all of them
				for ( var i = 0; i < jQuery.readyList.length; i++ )
					jQuery.readyList[i].apply( document );
				
				// Reset the list of functions
				jQuery.readyList = null;
			}
		}
	}
});

new function(){

	var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," +
		"mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select," + 
		"submit,keydown,keypress,keyup,error").split(",");

	// Go through all the event names, but make sure that
	// it is enclosed properly
	for ( var i = 0; i < e.length; i++ ) new function(){
			
		var o = e[i];
		
		// Handle event binding
		jQuery.fn[o] = function(f){
			return f ? this.bind(o, f) : this.trigger(o);
		};
		
		// Handle event unbinding
		jQuery.fn["un"+o] = function(f){ return this.unbind(o, f); };
		
		// Finally, handle events that only fire once
		jQuery.fn["one"+o] = function(f){
			// Attach the event listener
			return this.each(function(){

				var count = 0;

				// Add the event
				jQuery.event.add( this, o, function(e){
					// If this function has already been executed, stop
					if ( count++ ) return;
				
					// And execute the bound function
					return f.apply(this, [e]);
				});
			});
		};
			
	};
	
	// If Mozilla is used
	if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
	
	// If IE is used, use the excellent hack by Matthias Miller
	// http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
	} else if ( jQuery.browser.msie ) {
	
		// Only works if you document.write() it
		document.write("<scr" + "ipt id=__ie_init defer=true " + 
			"src=//:><\/script>");
	
		// Use the defer script hack
		var script = document.getElementById("__ie_init");
		script.onreadystatechange = function() {
			if ( this.readyState == "complete" )
				jQuery.ready();
		};
	
		// Clear from memory
		script = null;
	
	// If Safari  is used
	} else if ( jQuery.browser.safari ) {
		// Continually check to see if the document.readyState is valid
		jQuery.safariTimer = setInterval(function(){
			// loaded and complete are both valid states
			if ( document.readyState == "loaded" || 
				document.readyState == "complete" ) {
	
				// If either one are found, remove the timer
				clearInterval( jQuery.safariTimer );
				jQuery.safariTimer = null;
	
				// and execute any waiting functions
				jQuery.ready();
			}
		}, 10);
	} 

	// A fallback to window.onload, that will always work
	jQuery.event.add( window, "load", jQuery.ready );
	
};
jQuery.fn.extend({

	// overwrite the old show method
	_show: jQuery.fn.show,

	show: function(speed,callback){
		return speed ? this.animate({
			height: "show", width: "show", opacity: "show"
		}, speed, callback) : this._show();
	},
	
	// Overwrite the old hide method
	_hide: jQuery.fn.hide,

	hide: function(speed,callback){
		return speed ? this.animate({
			height: "hide", width: "hide", opacity: "hide"
		}, speed, callback) : this._hide();
	},

	slideDown: function(speed,callback){
		return this.animate({height: "show"}, speed, callback);
	},

	slideUp: function(speed,callback){
		return this.animate({height: "hide"}, speed, callback);
	},

	slideToggle: function(speed,callback){
		return this.each(function(){
			var state = $(this).is(":hidden") ? "show" : "hide";
			$(this).animate({height: state}, speed, callback);
		});
	},

	fadeIn: function(speed,callback){
		return this.animate({opacity: "show"}, speed, callback);
	},

	fadeOut: function(speed,callback){
		return this.animate({opacity: "hide"}, speed, callback);
	},

	fadeTo: function(speed,to,callback){
		return this.animate({opacity: to}, speed, callback);
	},
	animate: function(prop,speed,callback) {
		return this.queue(function(){
		
			this.curAnim = prop;
			
			for ( var p in prop ) {
				var e = new jQuery.fx( this, jQuery.speed(speed,callback), p );
				if ( prop[p].constructor == Number )
					e.custom( e.cur(), prop[p] );
				else
					e[ prop[p] ]( prop );
			}
			
		});
	},
	queue: function(type,fn){
		if ( !fn ) {
			fn = type;
			type = "fx";
		}
	
		return this.each(function(){
			if ( !this.queue )
				this.queue = {};
	
			if ( !this.queue[type] )
				this.queue[type] = [];
	
			this.queue[type].push( fn );
		
			if ( this.queue[type].length == 1 )
				fn.apply(this);
		});
	}

});

jQuery.extend({

	setAuto: function(e,p) {
		if ( e.notAuto ) return;

		if ( p == "height" && e.scrollHeight != parseInt(jQuery.curCSS(e,p)) ) return;
		if ( p == "width" && e.scrollWidth != parseInt(jQuery.curCSS(e,p)) ) return;

		// Remember the original height
		var a = e.style[p];

		// Figure out the size of the height right now
		var o = jQuery.curCSS(e,p,1);

		if ( p == "height" && e.scrollHeight != o ||
			p == "width" && e.scrollWidth != o ) return;

		// Set the height to auto
		e.style[p] = e.currentStyle ? "" : "auto";

		// See what the size of "auto" is
		var n = jQuery.curCSS(e,p,1);

		// Revert back to the original size
		if ( o != n && n != "auto" ) {
			e.style[p] = a;
			e.notAuto = true;
		}
	},
	
	speed: function(s,o) {
		o = o || {};
		
		if ( o.constructor == Function )
			o = { complete: o };
		
		var ss = { slow: 600, fast: 200 };
		o.duration = (s && s.constructor == Number ? s : ss[s]) || 400;
	
		// Queueing
		o.oldComplete = o.complete;
		o.complete = function(){
			jQuery.dequeue(this, "fx");
			if ( o.oldComplete && o.oldComplete.constructor == Function )
				o.oldComplete.apply( this );
		};
	
		return o;
	},
	
	queue: {},
	
	dequeue: function(elem,type){
		type = type || "fx";
	
		if ( elem.queue && elem.queue[type] ) {
			// Remove self
			elem.queue[type].shift();
	
			// Get next function
			var f = elem.queue[type][0];
		
			if ( f ) f.apply( elem );
		}
	},

	/*
	 * I originally wrote fx() as a clone of moo.fx and in the process
	 * of making it small in size the code became illegible to sane
	 * people. You've been warned.
	 */
	
	fx: function( elem, options, prop ){
	
		var z = this;
	
		// The users options
		z.o = {
			duration: options.duration || 400,
			complete: options.complete,
			step: options.step
		};
	
		// The element
		z.el = elem;
	
		// The styles
		var y = z.el.style;
	
		// Simple function for setting a style value
		z.a = function(){
			if ( options.step )
				options.step.apply( elem, [ z.now ] );

			if ( prop == "opacity" ) {
				if (z.now == 1) z.now = 0.9999;
				if (window.ActiveXObject)
					y.filter = "alpha(opacity=" + z.now*100 + ")";
				else
					y.opacity = z.now;

			// My hate for IE will never die
			} else if ( parseInt(z.now) )
				y[prop] = parseInt(z.now) + "px";
				
			y.display = "block";
		};
	
		// Figure out the maximum number to run to
		z.max = function(){
			return parseFloat( jQuery.css(z.el,prop) );
		};
	
		// Get the current size
		z.cur = function(){
			var r = parseFloat( jQuery.curCSS(z.el, prop) );
			return r && r > -10000 ? r : z.max();
		};
	
		// Start an animation from one number to another
		z.custom = function(from,to){
			z.startTime = (new Date()).getTime();
			z.now = from;
			z.a();
	
			z.timer = setInterval(function(){
				z.step(from, to);
			}, 13);
		};
	
		// Simple 'show' function
		z.show = function( p ){
			if ( !z.el.orig ) z.el.orig = {};

			// Remember where we started, so that we can go back to it later
			z.el.orig[prop] = this.cur();

			z.custom( 0, z.el.orig[prop] );

			// Stupid IE, look what you made me do
			if ( prop != "opacity" )
				y[prop] = "1px";
		};
	
		// Simple 'hide' function
		z.hide = function(){
			if ( !z.el.orig ) z.el.orig = {};

			// Remember where we started, so that we can go back to it later
			z.el.orig[prop] = this.cur();

			z.o.hide = true;

			// Begin the animation
			z.custom(z.el.orig[prop], 0);
		};
	
		// IE has trouble with opacity if it does not have layout
		if ( jQuery.browser.msie && !z.el.currentStyle.hasLayout )
			y.zoom = "1";
	
		// Remember  the overflow of the element
		if ( !z.el.oldOverlay )
			z.el.oldOverflow = jQuery.css( z.el, "overflow" );
	
		// Make sure that nothing sneaks out
		y.overflow = "hidden";
	
		// Each step of an animation
		z.step = function(firstNum, lastNum){
			var t = (new Date()).getTime();
	
			if (t > z.o.duration + z.startTime) {
				// Stop the timer
				clearInterval(z.timer);
				z.timer = null;

				z.now = lastNum;
				z.a();
				if(z.el.curAnim)
					z.el.curAnim[ prop ] = true;
				
				var done = true;
				for ( var i in z.el.curAnim )
					if ( z.el.curAnim[i] !== true )
						done = false;
						
				if ( done ) {
					// Reset the overflow
					y.overflow = z.el.oldOverflow;
				
					// Hide the element if the "hide" operation was done
					if ( z.o.hide ) 
						y.display = 'none';
					
					// Reset the property, if the item has been hidden
					if ( z.o.hide ) {
						for ( var p in z.el.curAnim ) {
							y[ p ] = z.el.orig[p] + ( p == "opacity" ? "" : "px" );
	
							// set its height and/or width to auto
							if ( p == 'height' || p == 'width' )
								jQuery.setAuto( z.el, p );
						}
					}
				}

				// If a callback was provided, execute it
				if( done && z.o.complete && z.o.complete.constructor == Function )
					// Execute the complete function
					z.o.complete.apply( z.el );
			} else {
				// Figure out where in the animation we are and set the number
				var p = (t - this.startTime) / z.o.duration;
				z.now = ((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum;
	
				// Perform the next step of the animation
				z.a();
			}
		};
	
	}

});
// AJAX Plugin
// Docs Here:
// http://jquery.com/docs/ajax/
jQuery.fn.loadIfModified = function( url, params, callback ) {
	this.load( url, params, callback, 1 );
};

jQuery.fn.load = function( url, params, callback, ifModified ) {
	if ( url.constructor == Function )
		return this.bind("load", url);

	callback = callback || function(){};

	// Default to a GET request
	var type = "GET";

	// If the second parameter was provided
	if ( params ) {
		// If it's a function
		if ( params.constructor == Function ) {
			// We assume that it's the callback
			callback = params;
			params = null;
			
		// Otherwise, build a param string
		} else {
			params = jQuery.param( params );
			type = "POST";
		}
	}
	
	var self = this;
	
	// Request the remote document
	jQuery.ajax( type, url, params,function(res, status){
		
		if ( status == "success" || !ifModified && status == "notmodified" ) {
			// Inject the HTML into all the matched elements
			self.html(res.responseText).each( callback, [res.responseText, status] );
			
			// Execute all the scripts inside of the newly-injected HTML
			$("script", self).each(function(){
				if ( this.src )
					$.getScript( this.src );
				else
					eval.call( window, this.text || this.textContent || this.innerHTML || "" );
			});
		} else
			callback.apply( self, [res.responseText, status] );

	}, ifModified);
	
	return this;
};

// If IE is used, create a wrapper for the XMLHttpRequest object
if ( jQuery.browser.msie )
	XMLHttpRequest = function(){
		return new ActiveXObject(
			navigator.userAgent.indexOf("MSIE 5") >= 0 ?
			"Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
		);
	};

// Attach a bunch of functions for handling common AJAX events
new function(){
	var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(',');
	
	for ( var i = 0; i < e.length; i++ ) new function(){
		var o = e[i];
		jQuery.fn[o] = function(f){
			return this.bind(o, f);
		};
	};
};

jQuery.extend({
	get: function( url, data, callback, type, ifModified ) {
		if ( data.constructor == Function ) {
			type = callback;
			callback = data;
			data = null;
		}
		
		if ( data ) url += "?" + jQuery.param(data);
		
		// Build and start the HTTP Request
		jQuery.ajax( "GET", url, null, function(r, status) {
			if ( callback ) callback( jQuery.httpData(r,type), status );
		}, ifModified);
	},

	getIfModified: function( url, data, callback, type ) {
		jQuery.get(url, data, callback, type, 1);
	},

	getScript: function( url, data, callback ) {
		jQuery.get(url, data, callback, "script");
	},
	post: function( url, data, callback, type ) {
		// Build and start the HTTP Request
		jQuery.ajax( "POST", url, jQuery.param(data), function(r, status) {
			if ( callback ) callback( jQuery.httpData(r,type), status );
		});
	},
	
	// timeout (ms)
	timeout: 0,

	ajaxTimeout: function(timeout) {
		jQuery.timeout = timeout;
	},

	// Last-Modified header cache for next request
	lastModified: {},
	ajax: function( type, url, data, ret, ifModified ) {
		// If only a single argument was passed in,
		// assume that it is a object of key/value pairs
		if ( !url ) {
			ret = type.complete;
			var success = type.success;
			var error = type.error;
			data = type.data;
			url = type.url;
			type = type.type;
		}
		
		// Watch for a new set of requests
		if ( ! jQuery.active++ )
			jQuery.event.trigger( "ajaxStart" );

		var requestDone = false;
	
		// Create the request object
		var xml = new XMLHttpRequest();
	
		// Open the socket
		xml.open(type || "GET", url, true);
		
		// Set the correct header, if data is being sent
		if ( data )
			xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		
		// Set the If-Modified-Since header, if ifModified mode.
		if ( ifModified )
			xml.setRequestHeader("If-Modified-Since",
				jQuery.lastModified[url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
		
		// Set header so calling script knows that it's an XMLHttpRequest
		xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
	
		// Make sure the browser sends the right content length
		if ( xml.overrideMimeType )
			xml.setRequestHeader("Connection", "close");
		
		// Wait for a response to come back
		var onreadystatechange = function(istimeout){
			// The transfer is complete and the data is available, or the request timed out
			if ( xml && (xml.readyState == 4 || istimeout == "timeout") ) {
				requestDone = true;

				var status = jQuery.httpSuccess( xml ) && istimeout != "timeout" ?
					ifModified && jQuery.httpNotModified( xml, url ) ? "notmodified" : "success" : "error";
				
				// Make sure that the request was successful or notmodified
				if ( status != "error" ) {
					// Cache Last-Modified header, if ifModified mode.
					var modRes = xml.getResponseHeader("Last-Modified");
					if ( ifModified && modRes ) jQuery.lastModified[url] = modRes;
					
					// If a local callback was specified, fire it
					if ( success ) success( xml, status );
					
					// Fire the global callback
					jQuery.event.trigger( "ajaxSuccess" );
				
				// Otherwise, the request was not successful
				} else {
					// If a local callback was specified, fire it
					if ( error ) error( xml, status );
					
					// Fire the global callback
					jQuery.event.trigger( "ajaxError" );
				}
				
				// The request was completed
				jQuery.event.trigger( "ajaxComplete" );
				
				// Handle the global AJAX counter
				if ( ! --jQuery.active )
					jQuery.event.trigger( "ajaxStop" );
	
				// Process result
				if ( ret ) ret(xml, status);
				
				// Stop memory leaks
				xml.onreadystatechange = function(){};
				xml = null;
				
			}
		};
		xml.onreadystatechange = onreadystatechange;
		
		// Timeout checker
		if(jQuery.timeout > 0)
			setTimeout(function(){
				// Check to see if the request is still happening
				if (xml) {
					// Cancel the request
					xml.abort();

					if ( !requestDone ) onreadystatechange( "timeout" );

					// Clear from memory
					xml = null;
				}
			}, jQuery.timeout);
		
		// Send the data
		xml.send(data);
	},
	
	// Counter for holding the number of active queries
	active: 0,
	
	// Determines if an XMLHttpRequest was successful or not
	httpSuccess: function(r) {
		try {
			return !r.status && location.protocol == "file:" ||
				( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
				jQuery.browser.safari && r.status == undefined;
		} catch(e){}

		return false;
	},

	// Determines if an XMLHttpRequest returns NotModified
	httpNotModified: function(xml, url) {
		try {
			var xmlRes = xml.getResponseHeader("Last-Modified");

			// Firefox always returns 200. check Last-Modified date
			return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
				jQuery.browser.safari && xml.status == undefined;
		} catch(e){}

		return false;
	},
	
	// Get the data out of an XMLHttpRequest.
	// Return parsed XML if content-type header is "xml" and type is "xml" or omitted,
	// otherwise return plain text.
	httpData: function(r,type) {
		var ct = r.getResponseHeader("content-type");
		var data = !type && ct && ct.indexOf("xml") >= 0;
		data = type == "xml" || data ? r.responseXML : r.responseText;

		// If the type is "script", eval it
		if ( type == "script" ) eval.call( window, data );

		return data;
	},
	
	// Serialize an array of form elements or a set of
	// key/values into a query string
	param: function(a) {
		var s = [];
		
		// If an array was passed in, assume that it is an array
		// of form elements
		if ( a.constructor == Array ) {
			// Serialize the form elements
			for ( var i = 0; i < a.length; i++ )
				s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );
			
		// Otherwise, assume that it's an object of key/value pairs
		} else {
			// Serialize the key/values
			for ( var j in a )
				s.push( j + "=" + encodeURIComponent( a[j] ) );
		}
		
		// Return the resulting serialization
		return s.join("&");
	}

});
/**/
/*  */

// Main library file 
// Contains all functions used by two or more widgets,
// Contains the main initialization and widget management code

/*  */

//
// START Global Initialization code
//

window.widget_manager = null;
$(document).ready(
	function ()
	{
		window.widget_manager = new WidgetManager( window.widget_names );
		if ( window.widget_roots && window.widget_roots.length > 0 )
		{
			for ( var i in window.widget_roots )
			{
				// Initialize widgets at one or more specific root points
				// This option is here for perfomance reasons: it can make
				// a huge difference on a big page with few localized widgets,
				// e.g. admin interface
				init_widgets( window.widget_roots[i] );
			}
		}
		else
		{
			// Initialize the widgets starting from the root
			init_widgets( document.body );
		}
		$( window ).unload( 
			function ()
			{
				// There might be things to save at 
				// the moment a user clicks a link
				window.widget_manager.stopAll();
			}
		);		
	}
);

// External callback for the widget 

// temporary thingie for bidnetwork 
// radio hutton save on 'view' button
var tempBid = false;
function widget_save_redir( url )
{
	var n = window.widget_manager.stopAll();
	var t = n > 0 ? 2500 : 1; 

	if ( tempBid )
	{
		var t = 2500;
	}

	setTimeout( 
		function ()
		{
			location.href = url;
		},
		t
	);
}

// Start widgets inside a given element/css selector
function init_widgets( context )
{                    
	var x = $( context ).get(0);
	x && window.widget_manager.startWidgets( x );
}

// CLASS WidgetManager
// Handles the inter-widget communication
function WidgetManager( widget_names )
{
	this.widgetNames 	= widget_names;
	this.currentWidgets = {};
	this.allWidgets 	= {};
}

// Return all widgets of a given type
WidgetManager.prototype.widgets = function ( name )
{
	return this.allWidgets[name];
}

// Make the Widget Manager aware of a new widget instance
WidgetManager.prototype.add = function ( name, w )
{
	this.allWidgets[name] = this.allWidgets[name] || [];
	this.allWidgets[name].push( w );
}

// Select all the widget instances of types defined in ws
// that match predicate function f
WidgetManager.prototype.find_all = function ( f, ws )
{
	ws = ws || ['editinplace','editatonce'];
	var rt = [];
	for ( var i in ws )
	{
		var a = this.allWidgets[ws[i]] || [];
		
		for ( var j in a )
		{
			if ( f( a[j] ) )
			{
				rt.push( a[j] );
			}
		}
	}
	return rt;
}

// Finds the first element belonging to one of the types 
// defined in ws that matches predicate function f
WidgetManager.prototype.find = function ( f, ws )
{
	ws = ws || ['editinplace','editatonce'];
	for ( var i in ws )
	{
		var a = this.allWidgets[ws[i]] || [];
		
		for ( var j in a )
		{
			if ( f( a[j] ) )
			{
				return a[j];
			}
		}
	}
	return null;
}

// Returns the current/active widget of type name
WidgetManager.prototype.current = function ( name )
{
	return this.currentWidgets[name];
}

// Stop (blur) all widgets. Used for e.g when the page is unloading
WidgetManager.prototype.stopAll = function ()
{
	var count = 0;
	for ( var name in this.currentWidgets )
	{
		var w = this.currentWidgets[name];
		if ( w )
		{
			if ( w.widgetBlur( name, null ) )
			{
				count += 1;
			}
		}
	}
	return count;
}

// Stop the current/active widget instance of type name
WidgetManager.prototype.stop = function ( name )
{
	var w = this.currentWidgets[name];
	w && w.widgetBlur( name, null );
}

// Defined a widget instance as the new current/active element
// fot the widget type name
WidgetManager.prototype.widgetFocus = function ( name, obj )
{
	for ( i in this.currentWidgets )
	{
		var w = this.currentWidgets[i];
		w.widgetBlur && w.widgetBlur( name, obj );
	}
	
	this.currentWidgets[name] = obj;
}


// Main widget initialization function
// Does a traversal of the tree that starts at root, checking
// the css classes of all elements for the do_<widgetname> pattern
// that matches one of the allowed types defined in window.widgetNames
WidgetManager.prototype.startWidgets = function ( root )
{
	var stack = [root];
	var names = this.widgetNames;
	var names_do = {};
	for ( var i in names )
	{
		names_do['do_' + names[i]] = names[i];
	}
	
	while ( stack.length > 0 )
	{
		var e = stack.pop();
		if ( e.className && e.className.match( /do_[a-z_]+/ ) )
		{
			// Note: IE6 does not recognize the \b escape char 
			// (whitespace in js regexps)
			var clsss = e.className.match( /do_[a-z_]+/g );
			for ( var i = 0; i < clsss.length; i++ )
			{
				var w = names_do[clsss[i]];
				if ( w )
				{
					eval("init_" + w + "( e )");
				}
			}
		}
		
		if ( e.childNodes ) 
		{
			for ( var i = 0 ; i < e.childNodes.length ; i++ )
			{
				if ( e.childNodes[i].nodeType != 3 )
				{
					// Only process if not a text node
					stack.unshift( e.childNodes[i] );
				}
			}
		}
	}
	
	var ends = ['editinplace','editatonce'];
	for ( var i in ends )
	{
		if ( jQuery.inArray( names, ends[i] ) )
		{
			eval( 'end_' + ends[i] + '()' );
		}
	}
}


// Convert the name of a validated field into a 
// string usable as a dom id attribute
function validate_field2id ( name )
{
	name = name.replace( /\./g, "_" );
	return 'required_fields_li_' + name;
}

function validate_cmpfield ( l )
{
	return function ( x ) 
	{
		return jQuery.inArray( l, x.options.ajax.field ); 
	}
}

// Scroll down/up the window to make visible the edit place of 
// a given validate field that was incorrect or missing
function validate_goto ( i )
{
	var e = window.widget_manager.find( validate_cmpfield( [i] ) );
	if ( e )
	{
		var p = jQuery.getPosition( e.container );
		scroll( 0, p.y - 100 );
	}
}

// Update the validate fields error information
function validate_update ()
{
	if ( jQuery.isEmptyObject( window.required_fields ) )
	{
		$( "#required_fields_main"  ).hide();
		$( "#required_fields_other" ).show();
		return;
	}
	
	$( "#required_fields_main" ).show();
	$( "#required_fields_other" ).hide();
	
	var fs = window.required_fields;
	var ul = $( "#required_fields_list" ).get( 0 );
	ul.innerHTML = '';
	var bind_click = function ( li, i )
	{
		var fu = function ( x ) 
		{ 
			return x.options.ajax.field == i; 
		};

		var e = window.widget_manager.find( fu );

		if ( e && e.options )
		{
			var c = e.options.callback;
			c = c || function () {};

			var fc = function ( d )
			{
				delete( window.required_fields[i] );
				validate_update();
				c && c( d );
			}

			e.options.callback = fc;
			
			$( li ).bind( "click",
				function () 
				{
					validate_goto( i );
					return false;
				}
			);
		}
	};
	
	var gs = jQuery.objKeys( fs );
	var fu = validate_cmpfield( gs );
	var ws = window.widget_manager.find_all( fu );
	for ( var i in ws )
	{
		ws[i].addRequiredClass();
	}
	
	for ( var i in fs )
	{
		var li = document.createElement( "li" );
		var an = document.createElement( "a" );
		li.id = validate_field2id( i );
		li.className = "required_field_title";
		an.href='#';
		$( an  ).html( fs[i] );
		$( li ).append( an );
		$( ul ).append( li );
		bind_click( an, i );
	}
}

// Used by all widgets. Override the default widget 'docs' 
// options with those 'o' specific for this instance
function apply_options( docs, o )
{
	for ( var i in docs )
	{
		var d	= docs[i];
		var ds	= d[0].split('.');
		if ( ds.length > 1 )
		{
			o[ds[0]][ds[1]]	= o[ds[0]][ds[1]]	|| d[1];
		}
		else
		{
			o[d[0]]			= o[d[0]] 			|| d[1];
		}
	}
	return o;
}


//
// END Global Initialization code
//

// Identity function
function identity ( x )
{
	return x;
}

jQuery.fn.opacity = function ( v )
{
	this.css('opacity', v );
	if ( jQuery.browser.msie ) 
	{
		this.css('filter', 'alpha(opacity=' + v * 100 + ')');
	}
}

jQuery.extend( {
	
	objKeys: function ( obj )
	{
		var ret = [];
		for ( var i in obj )
		{
			ret.push( i );
		}
		return ret;
	},
	
	label: function ( path, def )
	{
		var names 	= path.split('.');
		var tmp 	= window.labels;

		while ( names.length > 0 && tmp )
		{
			tmp = tmp[names.shift()];
		}

		return tmp || def;
	},
	
	// Create a new cookie
	// @param	name	string		name of the cookie
	// @param	value	string		value to be stored
	// @param	days	int			expiry time in days
	createCookie: function ( name, value, days )
	{
		if ( days ) 
		{
			var date = new Date();
			date.setTime( date.getTime() + ( days * 24 * 60 * 60 * 1000 ) );
			var expires = "; expires=" + date.toGMTString();
		}
		else
		{
			var expires = "";
		}
		document.cookie = name + "=" + value+expires + "; path=/";
	},

	// Read the value of a cookie
	readCookie: function ( name )
	{
		var nameEQ = name + "=";
		var ca = document.cookie.split( ';' );
		for ( var i = 0 ; i < ca.length ; i++ )
		{
			var c = ca[i];
			while ( c.charAt(0) == ' ' )
			{
				c = c.substring( 1, c.length );
			}
			
			if ( c.indexOf( nameEQ ) == 0 ) 
			{
				return c.substring( nameEQ.length, c.length );
			}
		}
		return null;
	},

	// Delete a cookie
	eraseCookie: function( name )
	{
		jQuery.createCookie( name, "", -1 );
	},
	
	// Use the log function of firebug without messing with other browsers 
	log: function () 
	{
		if ( window.console && window.console.log && window.console.assert )
		{
			window.console.log( arguments );
		}
	},
	
	warn: function( where , what )
	{
		if ( !what )
		{
			what = "You cannot edit this now.";
		}
		
		alert( where + ': ' + what );
		
		jQuery.log( arguments );
	},
	
	error: function ( msg , url , line ) 
	{
		alert( msg + " @ " + url + " @ " + line );
		return false;
	},
	
	// Encode object for get/post request: works with one-level-nested arrays and objects
	xparam: function ( params )
	{
		var res = [];
		for ( var i in params )
		{
			if ( params[i].constructor == Array )
			{
				for ( var j = 0 ; j < params[i].length ; j++ )
				{
					res.push( i + '[' + j + ']=' + encodeURIComponent( params[i][j] ) );
				}
			}
			else if ( params[i].constructor == Object )
			{
				for ( var j in params[i] )
				{
					res.push( i + '[' + j + ']=' + encodeURIComponent( params[i][j] ) );
				}
			}
			else
			{
				res.push( i + '=' + encodeURIComponent( params[i] ) );
			}
		}
		return res.join( '&' );
	},
	
	// Get the window size
	windowSize: function ()
	{
		var ret = { w: 0, h: 0 };
		if ( typeof( window.innerWidth ) == 'number' )
		{
		  //Non-IE
		  ret.w = window.innerWidth;
		  ret.h = window.innerHeight;
		}
		else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
		{
		  //IE 6+ in 'standards compliant mode'
		  ret.w = document.documentElement.clientWidth;
		  ret.h = document.documentElement.clientHeight;
		}
		else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
		{
		  //IE 4 compatible
		  ret.w = document.body.clientWidth;
		  ret.h = document.body.clientHeight;
		}	
		
		return ret;
	},
	
	mousePosition: function ( ev )
	{
		ev = ev || window.event;

		var x = 0, y = 0;

		if ( ev.pageX || ev.pageY )
		{
			x = ev.pageX;
			y = ev.pageY;
		}
		else if ( ev.clientX || ev.clientY )
		{
			x = ev.clientX + document.body.scrollLeft;
			y = ev.clientY + jQuery.pageScrollTop(); //document.body.scrollTop;
		}

		return { "x": x, "y": y };
	},
	
	// Coordinates of mouse in relation to the window 
	mouseInWindow: function ( e )
	{
		var ret = {};
		if ( !e )
		{
			var e = window.event;
		}
		
		if ( e.clientX || e.clientY )
		{
			ret.x = e.clientX - Math.max( 0 , document.body.scrollLeft );
			ret.y = e.clientY - Math.max( 0 , document.body.scrollTop ); // document.body.scrollTop*/  + document.documentElement.scrollTop;
		}
		return ret;
	},
	
	// Override r with properties from object a
	assocMergeInto: function ( r , a ) 
	{
		if ( a )
		{
			for( var i in a )
			{
				r[i] = a[i];
			}
		}
		return r;
	},
	
	// Merge two objects (properties of the second 
	// argument override those of the first), result is a new 
	// object in memory
	assocMerge: function ( a , b ) 
	{
	 	return jQuery.assocMergeInto( jQuery.assocMergeInto( {}, a ),  b );
	},
	
	// Output a datetime 
	dateFormat: function ( format , date )
	{
		format = format.replace( /\%Y/ , date.getFullYear() );
		format = format.replace( /\%m/ , date.getMonth() + 1 );
		format = format.replace( /\%d/ , date.getDate() );
		format = format.replace( /\%H/ , date.getHours() );
		format = format.replace( /\%M/ , date.getMinutes() );
		return format;
	},
	
	// Parse a sql datetime format into a javascript Date object
	parseDateTime: function ( s )
	{
		var x = s.split( ' ' );
		date = x[0].split( '-' );
		time = x[1].split( ':' );
		return new Date( date[0] , date[1] - 1 , date[2] , time[0] , time[1] , time[2] );
	},
	
	// Add some query data to a url
	addToQuery: function ( url , data ) 
	{
		return url + ( url.match( /\?/ ) ? '&' : '?' ) + data;
	},
	
	// Parse options given inside the attribute of an element
	attrOptions: function ( e , name )
	{
		var a = e.getAttribute( name ) || '';
		a = a.replace( /,\s*$/ , '' );
		eval( "var tmp = {" + a + "}" );
		return tmp;
	},

	// Vertical scroll offset in pixels
	pageScrollTop: function ()
	{
		var yScrolltop;
		if ( self.pageYOffset ) 
		{
			yScrolltop = self.pageYOffset;
		}
		else if ( document.documentElement && document.documentElement.scrollTop )
		{
			// Explorer 6 Strict
			yScrolltop = document.documentElement.scrollTop;
		}
		else if ( document.body )
		{
			// all other Explorers
			yScrolltop = document.body.scrollTop;
		}
		return yScrolltop;
	},
	
	// Calculate x,y position of a given dom element
	getPosition: function ( obj )
	{
		var curleft = curtop = 0;

		// Hack for IE not needed ?
		// Not sure but this check for IE gave problems in the end
		// Keep the if in until we're sure that it is not needed
		if ( false && jQuery.browser.msie )
		{
			// Hack for IE, naturally
			var childImg = false;
			for ( var i in obj.childNodes )
			{
				childImg = childImg || obj.childNodes[i].tagName == 'IMG';
			}

			if ( childImg )
			{
				curleft -= obj.offsetLeft;
			}
		}

		while ( obj )
		{
			curleft += obj.offsetLeft;
			curtop  += obj.offsetTop;
			obj		 = obj.offsetParent;
		}
		return { x: curleft, y: curtop };
	},
	
	// Calculate dimensions of a dom element
	getSize : function(e)
	{
		var w = jQuery.css(e,'width');
		var h = jQuery.css(e,'height');
		var wb = 0;
		var hb = 0;
		es = e.style;
		
		if ( jQuery(e).css('display') != 'none' ) 
		{
			wb = e.offsetWidth;
			hb = e.offsetHeight;
		}
		else
		{
			oldVisibility = es.visibility;
			oldPosition = es.position;
			es.visibility = 'hidden';
			es.display = 'block';
			es.position = 'absolute';
			wb = e.offsetWidth;
			hb = e.offsetHeight;
			es.display = 'none';
			es.position = oldPosition;
			es.visibility = oldVisibility;
		}
		return { w:w, h:h, wb:wb, hb:hb };
	},
	
	// Get an object position from the upper left viewport corner
	elemInWindow: function ( o )
	{
		// Get the positions from the parent object
		var oLeft = o.offsetLeft;            
		var oTop  = o.offsetTop;            

		// Parse the parent hierarchy up to the document element
		while( o.offsetParent != null )
		{   
			oParent	 = 	o.offsetParent;		// Get parent object reference
			oLeft	+=	oParent.offsetLeft;	// Add parent left position
			oTop	+=	oParent.offsetTop;	// Add parent top position
			o = oParent;
		}
		
		return { l: oLeft , t: oTop };
	},

	// Returns true if the passed value is found in the
	// array.  Returns false if it is not.
	inArray: function (a, value)
	{
		var i;
		for ( i=0 ; i < a.length ; i++)
		{
			// Matches identical (===), not just similar (==).
			if ( a[i] === value ) 
			{
				return true;
			}
		}
		return false;
	},

	// Returns value of a formfield
	getValue: function ( ffield , def )
	{
		v = '';
		t = ffield.type;
		
		if( !t ) 
		{
			t = ffield[0].type;
		}

		if( t == 'checkbox' )
		{
			if( ffield.length )
			{
				for( gv_i=0 ; gv_i < ffield.length ; gv_i++ )
				{
					if ( ffield[gv_i].checked ) 
					{
						v = ffield[gv_i].value;
					}
				}
			}
			else
			{
				if ( ffield.checked ) 
				{
					v = ffield.value;
				}
			}	
		} 
		else if ( t == 'file' )		v = ffield.value;
		else if ( t == 'hidden' )	v = ffield.value;
		else if ( t == 'password' ) v = ffield.value;
		else if ( t == 'radio' ) 
		{
			if ( ffield.length ) 
			{
				for ( gv_i=0 ; gv_i < ffield.length ; gv_i++) 
				{
					if ( ffield[gv_i].checked ) v = ffield[gv_i].value;
				}
			}
			else
			{
				if ( ffield.checked ) v = ffield.value;
			}	
		} 
		else if (t == 'select-multiple' ) v = ffield.options[ffield.selectedIndex].value;
		else if (t == 'select-one' )	  v = ffield.options[ffield.selectedIndex].value;
		else if (t == 'text' )			  v = ffield.value;
		else if (t == 'textarea' )		  v = ffield.value;
		
		if (def != null && v == '')
		{
			return def;
		}
		return v;
	},
	
	byId: function ( id , doc ) 
	{
		if ( typeof id == "string" || id instanceof String ) 
		{
			if ( !doc )
			{
				doc = document;
			}
			return doc.getElementById ( id );
		}
		// assume it's a node
		return id; 
	},

	textContent: function ( node ) 
	{
		var _result = "";
		if (node == null)
		{ 
			return _result;
		}
		
		for (var i = 0; i < node.childNodes.length; i++) 
		{
			switch (node.childNodes[i].nodeType) 
			{
				case 1: // ELEMENT_NODE
				case 5: // ENTITY_REFERENCE_NODE
					_result += jQuery.textContent(node.childNodes[i]);
					break;
				case 3: // TEXT_NODE
				case 2: // ATTRIBUTE_NODE
				case 4: // CDATA_SECTION_NODE
					_result += node.childNodes[i].nodeValue;
					break;
				default:
					break;
			}
		}
		return _result;
	},

	// used in form validator
	// maybe change in the future
	isEmailAddress: function ( v ) 
	{
		mailvalid = true;
		if ( v.indexOf ( '@' ) < 1 )
		{
			mailvalid = false;
		}
		else if ( v.lastIndexOf ( '.' ) < v.indexOf ( '@' ) ) 
		{
			isvalid = false;
		}
		aapje  = v.indexOf( '@' ); 
		puntje = v.indexOf( '.' );  
		if ( puntje - aapje == 1 ) 
		{
			mailvalid = false;
		}
		return mailvalid;
	},

	// used in form validator
	// maybe change in the future
	isSizeSmaller: function ( v , size ) 
	{
		if ( v.length < size )
		{
			return true;
		}
		else
		{
			return false;
		}
	},

	// used in form validator
	// maybe change in the future
	isSizeGreater: function ( v , size ) 
	{
		if ( v.length > size )
		{
			return true;
		}
		else
		{
			return false;
		}
	},

	// showhide functions
	// used while rest call state is failed/ok/wait
	showHide: function (str)
	{
		a = str.split(',');
		for ( var i = 0 ; i < a.length ; i++ ) 
		{
			s = a[i];
			c = s.charAt(0);
			v = 'block';
			
			if (c == '-') 
			{
				v = 'none';
				s = s.substr( 1 , s.length-1);
			}
			else if ( c == '+') 
			{
				s = s.substr( 1 , s.length - 1 );
			}
			
			if ( $( "#" + s ) ) 
			{
				$("#" + s).css( 'display', v );	
			}
		}
	},

	// Hide all obj in an array or string and optionally show obj b (can be an array)
	// Parameters:	a	which obj to hide (can be an array) 				
	//				b	which obj should openend afterwards (hide all but ...)(can be an array)
	//				s	if s = true search for objects starting with the string 'a'
	hideAllBut: function ( a, b ) 
	{
		if ( jQuery.isObject( a ) )
		{
			for ( var p in a ) 
			{
				$( "#" + a[p] ).hide(); 
			}
		}
		else if ( jQuery.isArray(a) )
		{
			for ( i = 0 ; i < a.length ; i++ )
			{
				$( "#" + a[i] ).hide(); 
			}
		}
		else if ( jQuery.isString( a ) )
		{
			var d = document.getElementsByTagName( 'div' );
			for( i = 0 ; i < d.length ; i++ )
			{
				var l = a.length;
				var id = d[i].id;
				if ( id.substring( 0 , l ) == a )
				{
					$( "#" + d[i].id ).hide(); 
				}
			}
		}
		
		if ( jQuery.isArray( b ) )
		{
			for ( i = 0 ; i < a.length ; i++) 
			{
				$( "#" + b[i] ).show();
			}
		}
		else if ( jQuery.isString( b ) ) 
		{
			$( "#" + b ).show();
		}
	},
		
	
	popup: function ( thg_id, o, l, t, w, h ) 
	{ 
		if ( l == null ) l = 100;
		if ( t == null ) t = 100;
		if ( w == null ) w = 400;
		if ( h == null ) h = 400;

		var aPopupWin = window.open( '', 'PopupWin', 'scrollbars=yes,menubar=no,location=no,directories=no,statusbar=no,toolbar=no,resizable=yes,width=' + w + ',height=' + h + ',top=' + t + ',left=' + l );
		aPopupWin.document.open(); 
		aPopupWin.document.close();
		order = '';
		if ( o != null ) order = '&order='+o;
		var p = 'popup.php?id=' + thg_id + order;

		aPopupWin.document.location.href = p;
		if( aPopupWin && !aPopupWin.closed )
		{
			aPopupWin.focus();
		}	
	},

	resizePopup: function()
	{
		var mw = 400;

		if ( parseInt( navigator.appVersion.charAt( 0 ) ) >= 4 )
		{
			NN = ( navigator.appName=="Netscape" ) ? 1 : 0;
		}

		if ( document.images[0] )
		{
			ww = ( screen.width  );
			wh = ( screen.height );

			if (NN)
			{
				rw = document.images[0].width + 80;
				rh = document.images[0].height;
				if ( ww < rw ) rw = ww;
				if ( rw < mw ) rw = mw;
				if ( wh < rh ) rh = wh;
				if ( rh < wh - 140 ) rh = rh + 160;
				window.top.innerWidth  = rw;
				window.top.innerHeight = rh;
			}
			else
			{
				rw = document.images[0].width + 80;
				rh = document.images[0].height;
				if ( ww < rw ) rw = ww;
				if ( rw < mw ) rw = mw;
				if ( wh < rh ) rh = wh;
				if ( rh < wh - 140 ) rh = rh + 160;
				window.top.resizeTo( rw, rh );
			}
			parent.window.moveTo( ( screen.width - rw ) / 2, ( screen.height - rh ) / 2 );
		}
	},

	// Returns true if the passed value is found in the
	// array.  Returns false if it is not.
	inArray: function (a, value)
	{
		var i;
		for ( i=0 ; i < a.length ; i++) 
		{
			// Matches identical (===), not just similar (==).
			if ( a[i] === value ) 
			{
				return true;
			}
		}
		return false;
	},

	// helper function
	isAlien: function ( a ) 
	{
		return jQuery.isObject(a) && typeof a.constructor != 'function';
	},

	isArray: function ( a ) 
	{
		return jQuery.isObject(a) && a.constructor == Array;
	},

	isBoolean: function ( a ) 
	{
		return typeof a == 'boolean';
	},
	
	isEmptyObject: function ( o )
	{
		for ( var i in o )
		{
			return false;
		}
		return true;
	},

	isEmpty: function(o) 
	{
		var i, v;
		if (jQuery.isObject(o)) 
		{
			for (i in o) 
			{
				v = o[i];
				if (jQuery.isUndefined(v) && jQuery.isFunction(v)) 
				{
					return false;
				}
			}
		}
		return true;
	},

	isFunction: function ( a ) 
	{
		return typeof a == 'function';
	},

	isNull: function ( a ) 
	{
		return typeof a == 'object' && !a;
	},

	isNumber: function ( a ) 
	{
		return typeof a == 'number' && isFinite(a);
	},

	isObject: function ( a ) 
	{
		return (a && typeof a == 'object') || jQuery.isFunction(a);
	},

	isString: function ( a ) 
	{
		return typeof a == 'string';
	},

	isUndefined: function ( a ) 
	{
		return typeof a == 'undefined';
	},

	isDomElement: function ( a ) 
	{
		return a && typeof a == 'object' && !jQuery.isUndefined(a.childNodes);
	}

});

// CLASS AjaxNotice
function AjaxNotice( sel )
{
	this.sel = sel;
}

// Start the notice
AjaxNotice.prototype.start = function ( text )
{
	if ( text == '...' )
	{
		text = '<img src="http://fast2.mediamatic.nl/f/nfzj/image/throbberdots.gif" />';
	}
	text && notice_corner_show( text );
	$( this.sel ).addClass( 'ajax_notice' );	
}

// Stop the notice
AjaxNotice.prototype.stop = function ()
{
	notice_corner_hide();
	$( this.sel ).removeClass( 'ajax_notice' );
}

// Make corner notices have unique ids so that timeout events
// only act if the instance that triggered them is still active
window.notice_corner_count = 0;

// Show the notice in the corner of window
function notice_corner_show ( text )
{
	window.notice_corner_count += 1;
	var x = document.getElementById( 'corner_notice' );
	if ( !x )
	{
		x = document.createElement( 'div' );
		x.id = 'corner_notice';
		$( document.body ).append( x );
	}
	$( x ).html( text );
	$( x ).show();
	window.notice_corner_time = (new Date()).getTime();
}

// Hide the notice in the corner of window
function notice_corner_hide ()
{
	window.notice_corner_count -= 1
	if ( window.notice_corner_count > 0 )
	{
		return;
	}
	else
	{
		window.notice_corner_count = 0;
	}
	var now = (new Date()).getTime();
	var dif = now - window.notice_corner_time;
	if ( dif > 1000 )
	{
		$( '#corner_notice' ).hide();
	}
	else
	{
		setTimeout(
			function () 
			{
				notice_corner_hide();
			},
			dif
		);
	}
}


// External callback for the documentation functions
function docs_validate()
{
	var lm = jQuery.label( 'editinplace.validate.msg'	, 'Please input a valid value' );
	var lo = jQuery.label( 'editinplace.validate.out'	, 'Value out of range'  );
	
	return { opts:	
		[[ "validate",			{},			"Input format validation" ]
		,[ "validate.regexp",	null,		"Regular expression to validate format" ]
		,[ "validate.name",		null,		"Name of predefined regular expression [integer|float]" ]
		,[ "validate.msg",		lm,			"Alert message to be displayed in case of wrong format" ]
		,[ "validate.min",		null,		"Minimum allowed value" ]
		,[ "validate.max",		null,		"Maximum allowed value" ]
		,[ "validate.empty",	false,		"Input value is allowed to be empty" ]
		,[ "validate.blank",	false,		"Input value is allowed to be empty/whitespace" ]
		,[ "validate.out",		lo,			"Alert message to be displayed in case of out of range number" ]
		]
	};
}

// CLASS Validate
// Used by EditAtOnce and EditInPlace to validate 
// the presence or format of some fields
function Validate( opts )
{
	this.opts = opts;
	if ( "integer" == this.opts.name )
	{
		this.opts.msg		= jQuery.label( 'editinplace.validate.integer'	, 'Please input an integer number' );
		this.opts.regexp	= /^\s*[-+]?\d+\s*$/;
	} 
	else if ( "float" == this.opts.name )
	{
		this.opts.msg		= jQuery.label( 'editinplace.validate.float'	, 'Please input a number' );
		this.opts.regexp	= /^\s*[-+]?\d+(\.\d+)?\s*$/;
	}
}

// Is the value inside this range?
Validate.prototype.range = function ( value )
{
	var fs 	= {'integer': parseInt, 'float': parseFloat};
	var f 	= fs[this.opts.name] || identity;
	value = f( value );
	
	return 	!(	this.opts.min && this.opts.min > value  
			||	this.opts.max && this.opts.max < value );
}

// Is the value not empty?
Validate.prototype.value = function ( value )
{	
	return ( this.opts.blank && value.match( /^\s*$/ ) )
		|| ( this.opts.empty && value == '' )
		|| ( this.opts.regexp && this.opts.regexp.exec( value ) )
		|| ( !this.opts.regexp );
}


// Comment this line to stop server-side reporting of javascript errors
//window.onerror = anyOnError;

window.handlingOnError = false;
window.handledErrors   = [];

// Function used for server-side reporting of javascript errors 
function anyOnError( msg , url , line )
{
	var exclude = [ "uncaught exception: Permission denied to get property HTMLInputElement.parentNode"
				  , "uncaught exception: Permission denied to get property HTMLDivElement.parentNode" ];

	// Don't report errors in black list
	for ( var i in exclude )
	{
		if ( exclude[i] == msg )
		{
			jQuery.log( "Error belongs to blacklist, won't report it." );

			// Stop browser from declaring this error
			return true;
		}
	}

	// Don't report same error twice
	for ( var i in window.handledErrors )
	{
		if ( window.handledErrors[i] == msg )
		{
			jQuery.log( "Error already reported once on this session" );
			
			// Stop browser from declaring same error twice
			return true;
		}
	}
	
	// Don't report errors that may have happened 
	// during the error-processing phase 
	// (danger of infinite recursivity)
	if ( window.handlingOnError )
	{
		jQuery.log( "Trying to report an error while already busy reporting another one" );
		
		// Pass error onto browser
		return false;
	}
	
	// Lock (informal mutex)
	window.handlingOnError = true;

	jQuery.log( "Reporting error: " + msg ); 
	
	// Remember this error
	window.handledErrors.push( msg ); 

	// Values to send to the server
	var params = {};
	params.msg			= msg;
	params.pageurl		= location.href;
	params.scripturl	= url;
	params.linenumber	= line;
	params.referrer		= document.referrer;
	
	// Send error report o server
	anyRest.error.log( params , 
		function ( xml ) 
		{ 
			jQuery.log( 'Error was reported!' ); 
			// Unlock (informal mutex)
			window.handlingOnError = false;
		}
	);
	
	// Pass error onto browser
	return false;
}


/*  */
/**/

var anyRest = {
	'search':
	{
		'live': function ( params , callback )
		{
			params.method = params.method || 'anymeta.search.live';
			anyRest.aux.skeleton( 'GET' , params , 
				function ( xml ) 
				{
					var items	= $( 'item', xml );
					callback( items );
				}
			);
		}
	},

	'aux':
	{
		'items': function ( xml )
		{
			var rsp = xml.getElementsByTagName( 'rsp' )[0];
			var rst = [];
			for ( var i = 0 ; i < rsp.childNodes.length ; i++ )
			{
				if ( rsp.childNodes[i].tagName == 'item' )
				{
					rst.push( rsp.childNodes[i] );
				}
			}
			return rst;
		},
		
		'status': function ( xml )
		{
			var rsp = xml.getElementsByTagName( 'rsp' );
			return rsp[0].getAttribute( 'stat' );
		},
		
		'error': function ( xml )
		{
			return ( anyRest.aux.status( xml ) != 'ok' );
		},

		'errorMsg': function ( xml )
		{
			var es = xml.getElementsByTagName( 'err' );
			return es[0] ? es[0].getAttribute( 'msg' ) : '';
		},
		
		'skeleton': function ( type , params , callback )
		{
			params.format = params.format || "xml";
			callback = callback || function ( _ ) {};

			var opts = {
				"type": type,
				"url": 	"http://www.lloydhotel.com/services/rest/"
			};
			
			if ( type == 'GET' ) 
			{
				opts.url += '?' + jQuery.xparam( params );
			}

			if ( type == 'POST' )
			{
				opts.data = jQuery.xparam( params );
			}

			opts.success = function restSuccess ( r )
			{
				var data = jQuery.httpData( r , params.format );
				callback( data );
			}	
			
			jQuery.ajax( opts );
		}
	}
};

anyRest.aux.concatChildNodes = function ( xmldom )
{
	var str = '';
	for ( var i = 0; i < xmldom.childNodes.length ; i++ )
	{
		str += xmldom.childNodes[i].nodeValue;
	}
	return str;
};

// POST
var batch = [
	['anymeta.','POST',
		['edge.attribute.get'
		,'edge.attribute.set'
		,'edge.add'
		,'edge.remove'
		,'edge.order'
		,'edge.addList'
		,'error.log'
		,'tags.add'
		,'predicates.get'
		,'predicates.set'
		,'user.check'
		]],
	['','POST',
		['contact.add'
		,'contact.change'
		,'contact.remove'
		]],
	['anymeta.','GET',
		['html.template'
		,'html.scomp'
		]]]

for ( var i in batch )
{
	var prefix = batch[i][0];
	var http_method = batch[i][1];
	var lis = batch[i][2];

	for ( var j in lis )
	{
		var words = lis[j].split('.');
		var tmp = anyRest;
		for ( var k = 0; k < words.length - 1; k++ )
		{
			if ( !tmp[words[k]] )
			{
				tmp[words[k]] = {};
			}
			tmp = tmp[words[k]];
		}
		
		tmp[words[words.length-1]] = makeRestMethod( http_method, prefix + lis[j] );
		
	}
}

function makeRestMethod( http_method, rest_method )
{
	return function ( params, callback )
	{
		params.method = rest_method;
		anyRest.aux.skeleton( http_method, params, callback );
	}
}

anyRest.service = function ( name, opts, callback )
{
	opts.method = name;
	anyRest.aux.skeleton( 'POST' , opts , callback );
};

anyRest.call = function ( opts, callback )
{
	anyRest.aux.skeleton( 'POST' , opts , callback );
};

anyRest.post = function ( name, opts, callback )
{
	opts.method = name;
	anyRest.aux.skeleton( 'POST' , opts , callback );
};

anyRest.get = function ( name, opts, callback )
{
	opts.method = name;
	anyRest.aux.skeleton( 'GET' , opts , callback );
};

/**/
/*  */

// Notes
// ULs and LIs margin values are set to 0
// LIs get display: block

function init_menu( do_str, context )
{
	context = context || document;
	
	$( do_str, document ).each( 
		function () 
		{
			var opts = jQuery.attrOptions( this , "menu" );
			new Menu( this, opts );
		}
	);
}

function docs_menu()
{
	var a = "Dynamic cascading menu item. Notes: ULs and LIs margin values are set to 0. LIs get display: block.";
	var e = [
		['<ul class="do_menu" menu="orientation: \'right\', width: 120">\n<li>A.root\n\t<ul>\n\t<li>A.1</li>\n\t<li>A.2</li>\n\t</ul>\n</li>\n<li>B.root\n\t<ul>\n\t<li>B.1</li>\n\t</ul>\n</li>\n</ul>',
		"Vertical menu"],
		['<table><tr><td>\n<ul class="do_menu">\n<li>A.root\n\t<ul>\n\t<li>A.1</li>\n\t<li>A.2</li>\n\t</ul>\n</li>'+
		 '\n</ul>\n</td><td>\n<ul class="do_menu">\n<li>B.root\n\t<ul>\n\t<li>B.1\n\t\t<ul>\n\t\t'+
		 '<li>B.1.1</li>\n\t\t<li>B.1.2</li>\n\t\t</ul>\n\t</li>\n\t</ul>\n</li>\n</ul>\n</div>\n</td></tr></table>',
		"Horizontal menu"]
	];
	var c = [];
	var o = 
	[[ "width", 		130, 	"Width of menu elements" ]
	,[ "orientation", 	'down', "If the first menus should go down instead of right [down,right]" ]
	,[ "timeout", 		500, 	"Milliseconds until the menu disappears after mouseout" ]
	];
	
	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
}

function opts_menu( o )
{
	return apply_options( docs_menu().opts, o );
}

function Menu( container, opts )
{
	opts			= opts_menu( opts );
	this.container	= container;
	this.opts		= opts;
	this.zindex 	= 10;
	this.timeout_lis = [];
	
	$( container ).css("margin-top","0px");
	
	var lis = $( "li" , container );

	var self = this;
	lis.each( 
		function () 
		{
			self.li( this );
		}
	);
}

Menu.prototype.li_show = function ( li, liuls )
{
	for ( var i = 0; i < this.timeout_lis.length; i++ )
	{
		// This is problematic
		this.li_hide_now( this.timeout_lis[i] );
	}
	this.timeout_lis = [];
	li.timeout_hide && clearTimeout( li.timeout_hide );
	
	$( "> ul > li", li ).css({
		"display": "block",
		"margin": "0px"
	});

	$( li ).addClass( 'menu_selected' );

	if ( !li.positioned )
	{
		// Position caches. Also avoids a li_hide_now related bug
		
		var siz = jQuery.getSize( li );

		// I don't like this test. Is there an alternative?
		if ( li.parentNode.style.position == "absolute" )
		{
			var l = siz.w;
			var t = 0;
		}
		else
		{
			var pos = jQuery.getPosition( li );
			if ( this.opts.orientation == 'down' )
			{
				var l = pos.x;
				var t = pos.y + siz.h;						
			}
			else
			{
				var w = this.opts.width || siz.w;
				var l = pos.x + w;
				var t = pos.y;
			}
		}

		liuls.css({
			"display": 	"block",
			"margin": 	"0px",
			"position": "absolute",
			"width" : 	this.opts.width + "px",
			"left": 	l + "px",
			"top":  	t + "px",
			"z-index": 	(this.zindex += 10)	
		});
		
		li.positioned = true;
	}

	liuls.css( "display", "block" );
}

Menu.prototype.li_hide_now = function ( li ) 
{
	$( li ).removeClass( "menu_selected" );
	$( "> ul" , li ).hide(); 
}

Menu.prototype.li_hide = function ( li ) 
{
	$( li ).removeClass( "menu_selected" );
	this.timeout_lis.push( li );
	var self = this;
	li.timeout_hide = setTimeout( function ()
		{
			self.li_hide_now( li );
		}, 
		this.opts.timeout
	);
}

Menu.prototype.li = function ( li )
{
	var liuls = $( "> ul" , li );
	liuls.css("display","none");

	var self = this;
	$( li ).hover( 
		function () 
		{
			self.li_show( this, liuls );
		},
		function () 
		{ 
			self.li_hide( this );
		}
	);
}


/*  */
//

window.tooltip_count 	= 0;
window.tooltip_current 	= null;

// Initialize with default values
function init_tooltip ( container, context )
{
	$( container, context ).each( 
		function ()
		{
			var opts = jQuery.attrOptions( this , 'tooltip' );
			new Tooltip( container, opts );
		}
	);
}

function docs_tooltip()
{
	var a = 'Mouse-pivoted tooltip that behaves intelligently against screen limits';
	var e = 
	[[ '<a class="do_tooltip" tooltip=\'html: "my text", id: "mydiv"\' >', "simple popup using a custom div id" ]
	,[ '<span class="do_tooltip" tooltip=\'html: "other text", width: "200px", timeout: 100\'>', "custom width and timeouts" ]
	];
	var c = [];
	var o = 
	[ [	'html'		, '', 			'The html to be injected into the tooltip div' ]
	, [	'id'		, 'tooltip',	'Id of the tooltip div (existing, or to be created)' ]
	, [ 'width'		, '250px', 		'Width of the tooltip' ]
	, [	'offx'		, 10, 			'Horizontal distance from the mouse pointer' ]
	, [	'offy'		, 5, 			'Vertical distance from the mouse pointer' ]
	, [ 'timeout'	, 300,			'Number of milliseconds before tooltip disappears' ]
	];
	
	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
}

function opts_tooltip( o )
{
	return apply_options( docs_tooltip().opts, o );
}

function Tooltip( container, options )
{
	options			= opts_tooltip( options );
	this.options	= options;
	
	var self = this;
	$( container ).bind( 'mousemove',
		function ( e )
		{
			self.show( e );
		}
	).bind( 'mouseout',
		function ( e ) 
		{
			self.hide();
		}
	);
}


Tooltip.prototype.layout = function ( ev )
{
	var w = jQuery.windowSize();
	var p = jQuery.mousePosition( ev );

	if ( p.x + this.tip.clientWidth + 30 > w.w )
	{
		this.tip.style.left	= w.w - this.options.offx - this.tip.clientWidth - 10 + 'px';
	}
	else
	{
		this.tip.style.left	= p.x + this.options.offx + 'px';
	}
	
	if ( p.y + this.tip.clientHeight + 30 > w.h + jQuery.pageScrollTop() )
	{
		this.tip.style.top = p.y - this.options.offy - this.tip.clientHeight + 'px';
	}
	else
	{
		this.tip.style.top = p.y + this.options.offy + 'px';;
	}
}

Tooltip.prototype.show = function ( ev )
{
	if ( this.options.html )
	{
		window.tooltip_current && window.tooltip_current.hide();
		
		window.tooltip_current = this;
		window.tooltip_count += 1;
		
		var tip	= document.getElementById( this.options.id );
		
		if ( !tip )
		{
			tip 	= document.createElement( 'div' );
			tip.id	= this.options.id;

			$( document.body ).append( tip );
		}

		$( tip ).addClass( 'tooltip' );
		
		this.tip					= tip;
		this.tip.innerHTML			= this.options.html;
		this.tip.style.width		= this.options.width; 
		this.tip.style.position		= "absolute";
		this.tip.style.zIndex		= 2000000;
		this.tip.style.display		= "block";
		this.layout( ev );
		this.tip.style.visibility	= "visible";
	}
}

Tooltip.prototype.hide = function ()
{
	if ( this.tip )
	{
		var self	= this;
		var count	= window.tooltip_count;
		this.timeout = setTimeout(
			function ()
			{
				if ( window.tooltip_count == count )
				{
					self.tip.style.visibility = 'hidden';
				}
			},
			self.options.timeout 
		);
	}
}

//
/**/


// STATIC 

var lightbox_pointer = null;

function lightbox_remove()
{
	window.widget_manager.stop( 'lightbox' );
}

function lightbox_bar_add( x )
{
	$( "#lightbox_bar" ).append( x );
}

function init_lightbox( container, context )
{
	context = context || document;

	$( container, context ).each(
		function ()
		{
			var opts	= jQuery.attrOptions( this , 'lightbox' );
			var ajax	= jQuery.attrOptions( this , 'lightbox_ajax' );
			
			opts.ajax = ajax;
			
			new Lightbox( this, opts );
		}
	);
}

function docs_lightbox()
{
	var a = "A slightly too versatile lightbox implementation...";
	var e = [];
	var c = [];
	var s = jQuery.label( 'lightbox.cancel', 'Cancel' );
	var o = 
	[[ 'url', 			null, 	"Url to be loaded. Defaults to the href attribute in the element, and then to null" ]
	,[ 'lbl_cancel',	s, 		"Cancel button name" ]
	,[ 'width',			"60%", 	"Css width of the lightbox" ]
	,[ 'height',		"60%", 	"Css height of the lightbox" ]
	,[ 'freeze',		false, 	"Whether the lightbox size should be fixed instead of adapting to content"]
	,[ 'ajax',			{}, 	"Parameters to be added to lightbox url" ]
	];
	
	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
}

function opts_lightbox( o )
{
	return apply_options( docs_lightbox().opts, o );	
}

// CLASS LIGHTBOX

function Lightbox( container, options )
{
	options			= opts_lightbox( options, container );
	options.url		= options.url || container.href || null;
	options.width	= ( "" + options.width  ).replace( 'px' , '' );
	options.height	= ( "" + options.height ).replace( 'px' , '' );

	this.options	= options;
	
	container = $( container ).get(0);
	container.obj_lightbox = this;

	var self = this;
	$( container ).click( 
		function ()
		{
			self.show();
			return false;
		}
	);

	if ( options.showonload )
	{
		// bug#1732
		//
		// http://support.microsoft.com/default.aspx/kb/927917
		// http://clientside.cnet.com/code-snippets/manipulating-the-dom/ie-and-operation-aborted/
		//
		// The "operation is aborted" when we generate DOM content in the parent of a container of a script.
		// It is also aborted when we try to add DOM content to a container that is not yet ready.
		// We fix this IE problem by generating the lightbox inside the container that has the showonload parameter.
		//
		if ($.browser.msie)
		{
			this.show(container);
		}
		else
		{
			this.show();
		}
		container.blur();	
	}
}

Lightbox.prototype.widgetBlur = function ( name, obj )
{
	if ( obj == null )
	{
		this.remove();
	}
	return false;
}

Lightbox.prototype.domCreate = function ()
{
	var lo	= document.createElement( "div" );
	var lf	= document.createElement( "div" );
	var lw	= document.createElement( "div" );
	var lc	= document.createElement( "div" );
	var cb	= document.createElement( "input" );
	
	lo.id	= "lightbox_overlay";
	lf.id	= "lightbox_frame";
	lw.id	= "lightbox_window";
	lc.id	= "lightbox_bar";
	cb.id	= "lightbox_cancel";
	
	lf.style.position	= "absolute";
	lw.style.width		= "100%";
	lw.style.height		= "100%";
	
	cb.type		= "button";
	cb.value	= this.options.lbl_cancel;
	
	$( "body" ).append( lo );
	$( "body" ).append( lf );
	
	$( lf ).append( lc );
	$( lf ).append( lw );
	$( lc ).append( cb );

	var self = this;
	$( cb ).click( 
		function () 
		{ 
			self.remove();
		} 
	);
}

Lightbox.prototype.clearResizeInterval = function()
{
	if ( lightbox_pointer && lightbox_pointer.interval )
	{
		clearInterval( lightbox_pointer.interval );
		lightbox_pointer.interval = null;
	}
}

Lightbox.prototype.remove = function ()
{
	this.clearResizeInterval();
	
	$( document ).unkeyup();

	// Timeout is needed when this function is called from within the lightbox itself
	setTimeout(
		function () 
		{
			$('#lightbox_window,#lightbox_frame,#lightbox_overlay').remove();
		},
		500
	);

	return false;
}

Lightbox.prototype.size_of_content = function ()
{
	var fr = document.getElementById("lightbox_iframeContent").contentWindow;
	var h1 = 0;
	var h2 = 0;
	
	if ( fr && fr.document )
	{
		if ( fr.document.documentElement && fr.document.documentElement.scrollHeight )
		{
			h1 = fr.document.documentElement.scrollHeight;
		}

		if ( fr.document.body && fr.document.body.scrollHeight )
		{
			h2 = fr.document.body.scrollHeight;
		}
	}

	var h = Math.max( h1, h2 );
	var s = jQuery.getSize( document.getElementById( 'lightbox_frame'  ) );

	h = s.h < h ? h + 60 : 0;
	
	return h;
}


Lightbox.prototype.size = function ()
{
	if ( document.getElementById( "lightbox_iframeContent" ) )
	{
		var h = this.size_of_content();
		h > 0 && $( "#lightbox_frame" ).css( 'height', h + 'px' );
	}
}

Lightbox.prototype.pixelizeSize = function ( x, y )
{
	x = parseInt( x.match( /\d+/ ) );
	x = Math.max( x , 0 );
	x = Math.min( x , 100 );
	x = Math.round( y * x / 100 );
	return x;
}

// Determine the width 
Lightbox.prototype.h_position = function ()
{
	var l = 0;
	var w = this.options.width;
	var d = jQuery.windowSize();

	if ( w.match( /\%/ ) )
	{
		w = this.pixelizeSize( w, d.w );
	}

	l = ( d.w - w ) / 2;

	$( "#lightbox_frame"  ).css( 'left',  l + 'px' );	
	$( "#lightbox_window" ).css( 'width', w + 'px' );
	
	this.overlaySize();	
}

// Determine the position  
Lightbox.prototype.v_position = function ()
{
	var pagesize   = jQuery.windowSize();	
	var pageScroll = jQuery.pageScrollTop();
	
	var t = 0;
	var h = this.options.height;
	var d = jQuery.windowSize();

	if ( h.match( /\%/ ) )
	{
		h = this.pixelizeSize( h, d.h );
	}

	t = ( d.h - h ) / 2;
	
	t = jQuery.pageScrollTop() + t;

	$( "#lightbox_frame" ).css({
		top:    t + 'px',
		height: h + 'px'
	});
}

// Determine size of dark mask 
Lightbox.prototype.overlaySize = function ()
{
	if ( window.innerHeight && window.scrollMaxY )
	{	
		yScroll = window.innerHeight + window.scrollMaxY;
	}
	else if ( document.body.scrollHeight > document.body.offsetHeight )
	{
		 // all but Explorer Mac
		yScroll = document.body.scrollHeight;
	}
	else
	{ 
		// Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		yScroll = document.body.offsetHeight;
  	}

	$( "#lightbox_overlay" ).css( "height" , yScroll + "px" );
}

// Update de size of the lightbox at a regular time interval
Lightbox.prototype.setRegularUpdate = function ()
{
	var self 	= this;
	var fr 		= document.getElementById("lightbox_iframeContent");
	fr.interval = setInterval( 
		function () 
		{ 
			self.size() 
		}, 
		800 
	);
}

Lightbox.prototype.show = function ()
{
	try 
	{
		window.widget_manager.widgetFocus( 'lightbox', this );
		
		$( "#lightbox_overlay" ).get( 0 ) || this.domCreate();
		
		var scroll = jQuery.pageScrollTop();

/*		window.scrollTo( 0, scroll );*/

		this.overlaySize();

		this.options.before_ajax && this.options.before_ajax( this.options );
		
		// Let the request know it is inside a lightbox
		this.options.ajax.in_lightbox = '1';
		
		var url		= jQuery.addToQuery( this.options.url , jQuery.param( this.options.ajax ) );
		var rand	= Math.floor( Math.random() * 100000 );
		
		if ( document.getElementById( "lightbox_iframeContent" ) == null )
		{
			$("#lightbox_window").append(
				"<iframe src='" + url + "' name='frame" + rand + "' id='lightbox_iframeContent' style='width: 100%; height: 100%;'></iframe>" );
		}
		else
		{
			$( "#lightbox_iframeContent").get(0).src = url;
		}
		
		this.v_position();
		this.h_position();
		
 		$( "#lightbox_window,#lightbox_frame" ).css( 'display' , 'block' ); 

		this.options.freeze || this.setRegularUpdate();
		
		lightbox_pointer = window.frames['frame'+rand];
		
		var self = this;
		$( window ).resize(
			function () 
			{
				self.h_position();
				self.v_position();
			}
		);		
	}
	catch( e ) 
	{
		jQuery.warn( "Lightbox" , "An error occurred when opening the lightbox." , e );
	}
}


/**/