/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.xml.Parse");

dojo.require("dojo.dom");

//TODO: determine dependencies
// currently has dependency on dojo.xml.DomUtil nodeTypes constants...

/* generic method for taking a node and parsing it into an object

TODO: WARNING: This comment is wrong!

For example, the following xml fragment

<foo bar="bar">
	<baz xyzzy="xyzzy"/>
</foo>

can be described as:

dojo.???.foo = {}
dojo.???.foo.bar = {}
dojo.???.foo.bar.value = "bar";
dojo.???.foo.baz = {}
dojo.???.foo.baz.xyzzy = {}
dojo.???.foo.baz.xyzzy.value = "xyzzy"

*/
// using documentFragment nomenclature to generalize in case we don't want to require passing a collection of nodes with a single parent
dojo.xml.Parse = function(){

	function getDojoTagName (node) {
		var tagName = node.tagName;
		if (tagName.substr(0,5).toLowerCase() != "dojo:") {
			
			if (tagName.substr(0,4).toLowerCase() == "dojo") {
				// FIXME: this assuumes tag names are always lower case
				return "dojo:" + tagName.substring(4).toLowerCase();
			}
		
			// allow lower-casing
			var djt = node.getAttribute("dojoType") || node.getAttribute("dojotype");
			if (djt) { return "dojo:" + djt.toLowerCase(); }
			
			if (node.getAttributeNS && node.getAttributeNS(dojo.dom.dojoml,"type")) {
				return "dojo:" + node.getAttributeNS(dojo.dom.dojoml,"type").toLowerCase();
			}
			try {
				// FIXME: IE really really doesn't like this, so we squelch
				// errors for it
				djt = node.getAttribute("dojo:type");
			} catch (e) { /* FIXME: log? */ }

			if (djt) { return "dojo:"+djt.toLowerCase(); }
		
			if (!dj_global["djConfig"] || !djConfig["ignoreClassNames"]) {
				// FIXME: should we make this optionally enabled via djConfig?
				var classes = node.className||node.getAttribute("class");
				// FIXME: following line, without check for existence of classes.indexOf
				// breaks firefox 1.5's svg widgets
				if (classes && classes.indexOf && classes.indexOf("dojo-") != -1) {
					var aclasses = classes.split(" ");
					for(var x=0; x<aclasses.length; x++){
						if (aclasses[x].length > 5 && aclasses[x].indexOf("dojo-") >= 0) {
							return "dojo:"+aclasses[x].substr(5).toLowerCase();
						}
					}
				}
			}
		
		}
		return tagName.toLowerCase();
	}

	this.parseElement = function(node, hasParentNodeSet, optimizeForDojoML, thisIdx){

        // if parseWidgets="false" don't search inside this node for widgets
        if (node.getAttribute("parseWidgets") == "false") {
            return {};
        }

		// TODO: make this namespace aware
		var parsedNodeSet = {};

		var tagName = getDojoTagName(node);
		parsedNodeSet[tagName] = [];
		if((!optimizeForDojoML)||(tagName.substr(0,4).toLowerCase()=="dojo")){
			var attributeSet = parseAttributes(node);
			for(var attr in attributeSet){
				if((!parsedNodeSet[tagName][attr])||(typeof parsedNodeSet[tagName][attr] != "array")){
					parsedNodeSet[tagName][attr] = [];
				}
				parsedNodeSet[tagName][attr].push(attributeSet[attr]);
			}
	
			// FIXME: we might want to make this optional or provide cloning instead of
			// referencing, but for now, we include a node reference to allow
			// instantiated components to figure out their "roots"
			parsedNodeSet[tagName].nodeRef = node;
			parsedNodeSet.tagName = tagName;
			parsedNodeSet.index = thisIdx||0;
		}
	
		var count = 0;
		var tcn, i = 0, nodes = node.childNodes;
		while(tcn = nodes[i++]){
			switch(tcn.nodeType){
				case  dojo.dom.ELEMENT_NODE: // element nodes, call this function recursively
					count++;
					var ctn = getDojoTagName(tcn);
					if(!parsedNodeSet[ctn]){
						parsedNodeSet[ctn] = [];
					}
					parsedNodeSet[ctn].push(this.parseElement(tcn, true, optimizeForDojoML, count));
					if(	(tcn.childNodes.length == 1)&&
						(tcn.childNodes.item(0).nodeType == dojo.dom.TEXT_NODE)){
						parsedNodeSet[ctn][parsedNodeSet[ctn].length-1].value = tcn.childNodes.item(0).nodeValue;
					}
					break;
				case  dojo.dom.TEXT_NODE: // if a single text node is the child, treat it as an attribute
					if(node.childNodes.length == 1) {
						parsedNodeSet[tagName].push({ value: node.childNodes.item(0).nodeValue });
					}
					break;
				default: break;
				/*
				case  dojo.dom.ATTRIBUTE_NODE: // attribute node... not meaningful here
					break;
				case  dojo.dom.CDATA_SECTION_NODE: // cdata section... not sure if this would ever be meaningful... might be...
					break;
				case  dojo.dom.ENTITY_REFERENCE_NODE: // entity reference node... not meaningful here
					break;
				case  dojo.dom.ENTITY_NODE: // entity node... not sure if this would ever be meaningful
					break;
				case  dojo.dom.PROCESSING_INSTRUCTION_NODE: // processing instruction node... not meaningful here
					break;
				case  dojo.dom.COMMENT_NODE: // comment node... not not sure if this would ever be meaningful 
					break;
				case  dojo.dom.DOCUMENT_NODE: // document node... not sure if this would ever be meaningful
					break;
				case  dojo.dom.DOCUMENT_TYPE_NODE: // document type node... not meaningful here
					break;
				case  dojo.dom.DOCUMENT_FRAGMENT_NODE: // document fragment node... not meaningful here
					break;
				case  dojo.dom.NOTATION_NODE:// notation node... not meaningful here
					break;
				*/
			}
		}
		//return (hasParentNodeSet) ? parsedNodeSet[node.tagName] : parsedNodeSet;
		return parsedNodeSet;
	}

	/* parses a set of attributes on a node into an object tree */
	function parseAttributes(node) {
		// TODO: make this namespace aware
		var parsedAttributeSet = {};
		var atts = node.attributes;
		// TODO: should we allow for duplicate attributes at this point...
		// would any of the relevant dom implementations even allow this?
		var attnode, i=0;
		while(attnode=atts[i++]) {
			if((dojo.render.html.capable)&&(dojo.render.html.ie)){
				if(!attnode){ continue; }
				if(	(typeof attnode == "object")&&
					(typeof attnode.nodeValue == 'undefined')||
					(attnode.nodeValue == null)||
					(attnode.nodeValue == '')){ 
					continue; 
				}
			}
			var nn = (attnode.nodeName.indexOf("dojo:") == -1) ? attnode.nodeName : attnode.nodeName.split("dojo:")[1];
			parsedAttributeSet[nn] = { 
				value: attnode.nodeValue 
			};
		}
		return parsedAttributeSet;
	}
}

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.lang.declare");

dojo.require("dojo.lang.common");
dojo.require("dojo.lang.extras");

/*
 * Creates a constructor: inherit and extend
 *
 * - inherits from "superclass(es)" 
 *
 *   "superclass" argument may be a Function, or an array of 
 *   Functions. 
 *
 *   If "superclass" is an array, the first element is used 
 *   as the prototypical ancestor and any following Functions 
 *   become mixin ancestors. 
 * 
 *   All "superclass(es)" must be Functions (not mere Objects).
 *
 *   Using mixin ancestors provides a type of multiple
 *   inheritance. Mixin ancestors prototypical 
 *   properties are copied to the subclass, and any 
 *   inializater/constructor is invoked. 
 *
 * - "props" are copied to the constructor prototype
 *
 * - name of the class ("className" argument) is stored in 
 *   "declaredClass" property
 * 
 * - An initializer function can be specified in the "init" 
 *   argument, or by including a function called "initializer" 
 *   in "props".
 * 
 * - Superclass methods (inherited methods) can be invoked using "inherited" method:
 *
 * this.inherited(<method name>[, <argument array>]);
 * 
 * - inherited will continue up the prototype chain until it finds an implementation of method
 * - nested calls to inherited are supported (i.e. inherited method "A" can succesfully call inherited("A"), and so on)
 *
 * Aliased as "dojo.declare"
 *
 * Usage:
 *
 * dojo.declare("my.classes.bar", my.classes.foo, {
 *	initializer: function() {
 *		this.myComplicatedObject = new ReallyComplicatedObject(); 
 *	},
 *	someValue: 2,
 *	aMethod: function() { doStuff(); }
 * });
 *
 */
dojo.lang.declare = function(className /*string*/, superclass /*function || array*/, init /*function*/, props /*object*/){
	// FIXME: parameter juggling for backward compat ... deprecate and remove after 0.3.*
	// new sig: (className (string)[, superclass (function || array)[, init (function)][, props (object)]])
	// old sig: (className (string)[, superclass (function || array), props (object), init (function)])
	if ((dojo.lang.isFunction(props))||((!props)&&(!dojo.lang.isFunction(init)))){ 
		var temp = props;
		props = init;
		init = temp;
	}	
	var mixins = [ ];
	if (dojo.lang.isArray(superclass)) {
		mixins = superclass;
		superclass = mixins.shift();
	}
	if(!init){
		init = dojo.evalObjPath(className, false);
		if ((init)&&(!dojo.lang.isFunction(init))){ init = null };
	}
	var ctor = dojo.lang.declare._makeConstructor();
	var scp = (superclass ? superclass.prototype : null);
	if(scp){
		scp.prototyping = true;
		ctor.prototype = new superclass();
		scp.prototyping = false; 
	}
	ctor.superclass = scp;
	ctor.mixins = mixins;
	for(var i=0,l=mixins.length; i<l; i++){
		dojo.lang.extend(ctor, mixins[i].prototype);
	}
	ctor.prototype.initializer = null;
	ctor.prototype.declaredClass = className;
	if(dojo.lang.isArray(props)){
		dojo.lang.extend.apply(dojo.lang, [ctor].concat(props));
	}else{
		dojo.lang.extend(ctor, (props)||{});
	}
	dojo.lang.extend(ctor, dojo.lang.declare.base);
	ctor.prototype.constructor = ctor;
	ctor.prototype.initializer=(ctor.prototype.initializer)||(init)||(function(){});
	dojo.lang.setObjPathValue(className, ctor, null, true);
}

dojo.lang.declare._makeConstructor = function() {
	return function(){ 
		// get the generational context (which object [or prototype] should be constructed)
		var self = this._getPropContext();
		var s = self.constructor.superclass;
		if((s)&&(s.constructor)){
			if(s.constructor==arguments.callee){
				// if this constructor is invoked directly (my.ancestor.call(this))
				this.inherited("constructor", arguments);
			}else{
				this._inherited(s, "constructor", arguments);
			}
		}
		var m = (self.constructor.mixins)||([]);
		for(var i=0,l=m.length; i<l; i++) {
			(((m[i].prototype)&&(m[i].prototype.initializer))||(m[i])).apply(this, arguments);
		}
		if((!this.prototyping)&&(self.initializer)){
			self.initializer.apply(this, arguments);
		}
	}
}

dojo.lang.declare.base = {
	_getPropContext: function() { return (this.___proto||this); },
	// caches ptype context and calls method on it
	_inherited: function(ptype, method, args){
		var stack = this.___proto;
		this.___proto = ptype;
		var result = ptype[method].apply(this,(args||[]));
		this.___proto = stack;
		return result;
	},
	// invokes ctor.prototype.method, with args, in our context 
	inheritedFrom: function(ctor, prop, args){
		var p = ((ctor)&&(ctor.prototype)&&(ctor.prototype[prop]));
		return (dojo.lang.isFunction(p) ? p.apply(this, (args||[])) : p);
	},
	// searches backward thru prototype chain to find nearest ancestral instance of prop
	inherited: function(prop, args){
		var p = this._getPropContext();
		do{
			if((!p.constructor)||(!p.constructor.superclass)){return;}
			p = p.constructor.superclass;
		}while(!(prop in p));
		return (dojo.lang.isFunction(p[prop]) ? this._inherited(p, prop, args) : p[prop]);
	}
}

dojo.declare = dojo.lang.declare;
/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.Manager");
dojo.require("dojo.lang.array");
dojo.require("dojo.lang.func");
dojo.require("dojo.event.*");

// Manager class
dojo.widget.manager = new function(){
	this.widgets = [];
	this.widgetIds = [];
	
	// map of widgetId-->widget for widgets without parents (top level widgets)
	this.topWidgets = {};

	var widgetTypeCtr = {};
	var renderPrefixCache = [];

	this.getUniqueId = function (widgetType) {
		return widgetType + "_" + (widgetTypeCtr[widgetType] != undefined ?
			++widgetTypeCtr[widgetType] : widgetTypeCtr[widgetType] = 0);
	}

	this.add = function(widget){
		dojo.profile.start("dojo.widget.manager.add");
		this.widgets.push(widget);
		// Opera9 uses ID (caps)
		if(!widget.extraArgs["id"]){
			widget.extraArgs["id"] = widget.extraArgs["ID"];
		}
		// FIXME: the rest of this method is very slow!
		if(widget.widgetId == ""){
			if(widget["id"]){
				widget.widgetId = widget["id"];
			}else if(widget.extraArgs["id"]){
				widget.widgetId = widget.extraArgs["id"];
			}else{
				widget.widgetId = this.getUniqueId(widget.widgetType);
			}
		}
		if(this.widgetIds[widget.widgetId]){
			dojo.debug("widget ID collision on ID: "+widget.widgetId);
		}
		this.widgetIds[widget.widgetId] = widget;
		// Widget.destroy already calls removeById(), so we don't need to
		// connect() it here
		dojo.profile.end("dojo.widget.manager.add");
	}

	this.destroyAll = function(){
		for(var x=this.widgets.length-1; x>=0; x--){
			try{
				// this.widgets[x].destroyChildren();
				this.widgets[x].destroy(true);
				delete this.widgets[x];
			}catch(e){ }
		}
	}

	// FIXME: we should never allow removal of the root widget until all others
	// are removed!
	this.remove = function(widgetIndex){
		var tw = this.widgets[widgetIndex].widgetId;
		delete this.widgetIds[tw];
		this.widgets.splice(widgetIndex, 1);
	}
	
	// FIXME: suboptimal performance
	this.removeById = function(id) {
		for (var i=0; i<this.widgets.length; i++){
			if(this.widgets[i].widgetId == id){
				this.remove(i);
				break;
			}
		}
	}

	this.getWidgetById = function(id){
		return this.widgetIds[id];
	}

	this.getWidgetsByType = function(type){
		var lt = type.toLowerCase();
		var ret = [];
		dojo.lang.forEach(this.widgets, function(x){
			if(x.widgetType.toLowerCase() == lt){
				ret.push(x);
			}
		});
		return ret;
	}

	this.getWidgetsOfType = function (id) {
		dojo.deprecated("getWidgetsOfType", "use getWidgetsByType", "0.4");
		return dojo.widget.manager.getWidgetsByType(id);
	}

	this.getWidgetsByFilter = function(unaryFunc, onlyOne){
		var ret = [];
		dojo.lang.every(this.widgets, function(x){
			if(unaryFunc(x)){
				ret.push(x);
				if(onlyOne){return false;}
			}
			return true;
		});
		return (onlyOne ? ret[0] : ret);
	}

	this.getAllWidgets = function() {
		return this.widgets.concat();
	}

	//	added, trt 2006-01-20
	this.getWidgetByNode = function(/* DOMNode */ node){
		var w=this.getAllWidgets();
		for (var i=0; i<w.length; i++){
			if (w[i].domNode==node){
				return w[i];
			}
		}
		return null;
	}

	// shortcuts, baby
	this.byId = this.getWidgetById;
	this.byType = this.getWidgetsByType;
	this.byFilter = this.getWidgetsByFilter;
	this.byNode = this.getWidgetByNode;

	// map of previousally discovered implementation names to constructors
	var knownWidgetImplementations = {};

	// support manually registered widget packages
	var widgetPackages = ["dojo.widget"];
	for (var i=0; i<widgetPackages.length; i++) {
		// convenience for checking if a package exists (reverse lookup)
		widgetPackages[widgetPackages[i]] = true;
	}

	this.registerWidgetPackage = function(pname) {
		if(!widgetPackages[pname]){
			widgetPackages[pname] = true;
			widgetPackages.push(pname);
		}
	}
	
	this.getWidgetPackageList = function() {
		return dojo.lang.map(widgetPackages, function(elt) { return(elt!==true ? elt : undefined); });
	}
	
	this.getImplementation = function(widgetName, ctorObject, mixins){
		// try and find a name for the widget
		var impl = this.getImplementationName(widgetName);
		if(impl){ 
			// var tic = new Date();
			var ret = new impl(ctorObject);
			// dojo.debug(new Date() - tic);
			return ret;
		}
	}

	this.getImplementationName = function(widgetName){
		/*
		 * This is the overly-simplistic implemention of getImplementation (har
		 * har). In the future, we are going to want something that allows more
		 * freedom of expression WRT to specifying different specializations of
		 * a widget.
		 *
		 * Additionally, this implementation treats widget names as case
		 * insensitive, which does not necessarialy mesh with the markup which
		 * can construct a widget.
		 */

		var lowerCaseWidgetName = widgetName.toLowerCase();

		var impl = knownWidgetImplementations[lowerCaseWidgetName];
		if(impl){
			return impl;
		}

		// first store a list of the render prefixes we are capable of rendering
		if(!renderPrefixCache.length){
			for(var renderer in dojo.render){
				if(dojo.render[renderer]["capable"] === true){
					var prefixes = dojo.render[renderer].prefixes;
					for(var i = 0; i < prefixes.length; i++){
						renderPrefixCache.push(prefixes[i].toLowerCase());
					}
				}
			}
			// make sure we don't HAVE to prefix widget implementation names
			// with anything to get them to render
			renderPrefixCache.push("");
		}

		// look for a rendering-context specific version of our widget name
		for(var i = 0; i < widgetPackages.length; i++){
			var widgetPackage = dojo.evalObjPath(widgetPackages[i]);
			if(!widgetPackage) { continue; }

			for (var j = 0; j < renderPrefixCache.length; j++) {
				if (!widgetPackage[renderPrefixCache[j]]) { continue; }
				for (var widgetClass in widgetPackage[renderPrefixCache[j]]) {
					if (widgetClass.toLowerCase() != lowerCaseWidgetName) { continue; }
					knownWidgetImplementations[lowerCaseWidgetName] =
						widgetPackage[renderPrefixCache[j]][widgetClass];
					return knownWidgetImplementations[lowerCaseWidgetName];
				}
			}

			for (var j = 0; j < renderPrefixCache.length; j++) {
				for (var widgetClass in widgetPackage) {
					if (widgetClass.toLowerCase() !=
						(renderPrefixCache[j] + lowerCaseWidgetName)) { continue; }
	
					knownWidgetImplementations[lowerCaseWidgetName] =
						widgetPackage[widgetClass];
					return knownWidgetImplementations[lowerCaseWidgetName];
				}
			}
		}
		
		throw new Error('Could not locate "' + widgetName + '" class');
	}

	// FIXME: does it even belong in this name space?
	// NOTE: this method is implemented by DomWidget.js since not all
	// hostenv's would have an implementation.
	/*this.getWidgetFromPrimitive = function(baseRenderType){
		dojo.unimplemented("dojo.widget.manager.getWidgetFromPrimitive");
	}

	this.getWidgetFromEvent = function(nativeEvt){
		dojo.unimplemented("dojo.widget.manager.getWidgetFromEvent");
	}*/

	// Catch window resize events and notify top level widgets
	this.resizing=false;
	this.onWindowResized = function(){
		if(this.resizing){
			return;	// duplicate event
		}
		try{
			this.resizing=true;
			for(var id in this.topWidgets){
				var child = this.topWidgets[id];
				if(child.checkSize ){
					child.checkSize();
				}
			};
		}catch(e){
		}finally{
			this.resizing=false;
		}
	}
	if(typeof window != "undefined") {
		dojo.addOnLoad(this, 'onWindowResized');							// initial sizing
		dojo.event.connect(window, 'onresize', this, 'onWindowResized');	// window resize
	}

	// FIXME: what else?
};

(function(){
	var dw = dojo.widget;
	var dwm = dw.manager;
	var h = dojo.lang.curry(dojo.lang, "hitch", dwm);
	var g = function(oldName, newName){
		dw[(newName||oldName)] = h(oldName);
	}
	// copy the methods from the default manager (this) to the widget namespace
	g("add", "addWidget");
	g("destroyAll", "destroyAllWidgets");
	g("remove", "removeWidget");
	g("removeById", "removeWidgetById");
	g("getWidgetById");
	g("getWidgetById", "byId");
	g("getWidgetsByType");
	g("getWidgetsByFilter");
	g("getWidgetsByType", "byType");
	g("getWidgetsByFilter", "byFilter");
	g("getWidgetByNode", "byNode");
	dw.all = function(n){
		var widgets = dwm.getAllWidgets.apply(dwm, arguments);
		if(arguments.length > 0) {
			return widgets[n];
		}
		return widgets;
	}
	g("registerWidgetPackage");
	g("getImplementation", "getWidgetImplementation");
	g("getImplementationName", "getWidgetImplementationName");

	dw.widgets = dwm.widgets;
	dw.widgetIds = dwm.widgetIds;
	dw.root = dwm.root;
})();

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.Widget");
dojo.provide("dojo.widget.tags");

dojo.require("dojo.lang.func");
dojo.require("dojo.lang.array");
dojo.require("dojo.lang.extras");
dojo.require("dojo.lang.declare");
dojo.require("dojo.widget.Manager");
dojo.require("dojo.event.*");

dojo.declare("dojo.widget.Widget", null, {
	initializer: function() {								 
		// these properties aren't primitives and need to be created on a per-item
		// basis.
		this.children = [];
		// this.selection = new dojo.widget.Selection();
		// FIXME: need to replace this with context menu stuff
		this.extraArgs = {};
	},
	// FIXME: need to be able to disambiguate what our rendering context is
	//        here!
	//
	// needs to be a string with the end classname. Every subclass MUST
	// over-ride.
	//
	// base widget properties
	parent: null,
	// obviously, top-level and modal widgets should set these appropriately
	isTopLevel:  false,
	isModal: false,

	isEnabled: true,
	isHidden: false,
	isContainer: false, // can we contain other widgets?
	widgetId: "",
	widgetType: "Widget", // used for building generic widgets

	toString: function() {
		return '[Widget ' + this.widgetType + ', ' + (this.widgetId || 'NO ID') + ']';
	},

	repr: function(){
		return this.toString();
	},

	enable: function(){
		// should be over-ridden
		this.isEnabled = true;
	},

	disable: function(){
		// should be over-ridden
		this.isEnabled = false;
	},

	hide: function(){
		// should be over-ridden
		this.isHidden = true;
	},

	show: function(){
		// should be over-ridden
		this.isHidden = false;
	},

	onResized: function(){
		// Clients should override this function to do special processing,
		// then call this.notifyChildrenOfResize() to notify children of resize
		this.notifyChildrenOfResize();
	},
	
	notifyChildrenOfResize: function(){
		for(var i=0; i<this.children.length; i++){
			var child = this.children[i];
			//dojo.debug(this.widgetId + " resizing child " + child.widgetId);
			if( child.onResized ){
				child.onResized();
			}
		}
	},

	create: function(args, fragment, parentComp){
		// dojo.debug(this.widgetType, "create");
		this.satisfyPropertySets(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> mixInProperties");
		this.mixInProperties(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> postMixInProperties");
		this.postMixInProperties(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> dojo.widget.manager.add");
		dojo.widget.manager.add(this);
		// dojo.debug(this.widgetType, "-> buildRendering");
		this.buildRendering(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> initialize");
		this.initialize(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> postInitialize");
		this.postInitialize(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> postCreate");
		this.postCreate(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "done!");
		return this;
	},

	// Destroy this widget and it's descendants
	destroy: function(finalize){
		// FIXME: this is woefully incomplete
		this.destroyChildren();
		this.uninitialize();
		this.destroyRendering(finalize);
		dojo.widget.manager.removeById(this.widgetId);
	},

	// Destroy the children of this widget, and their descendents
	destroyChildren: function(){
		while(this.children.length > 0){
			var tc = this.children[0];
			this.removeChild(tc);
			tc.destroy();
		}
	},

	getChildrenOfType: function(type, recurse){
		var ret = [];
		var isFunc = dojo.lang.isFunction(type);
		if(!isFunc){
			type = type.toLowerCase();
		}
		for(var x=0; x<this.children.length; x++){
			if(isFunc){
				if(this.children[x] instanceof type){
					ret.push(this.children[x]);
				}
			}else{
				if(this.children[x].widgetType.toLowerCase() == type){
					ret.push(this.children[x]);
				}
			}
			if(recurse){
				ret = ret.concat(this.children[x].getChildrenOfType(type, recurse));
			}
		}
		return ret;
	},

	getDescendants: function(){
		var result = [];
		var stack = [this];
		var elem;
		while (elem = stack.pop()){
			result.push(elem);
			dojo.lang.forEach(elem.children, function(elem) { stack.push(elem); });
		}
		return result;
	},

	satisfyPropertySets: function(args){
		// dojo.profile.start("satisfyPropertySets");
		// get the default propsets for our component type
		/*
		var typePropSets = []; // FIXME: need to pull these from somewhere!
		var localPropSets = []; // pull out propsets from the parser's return structure

		// for(var x=0; x<args.length; x++){
		// }

		for(var x=0; x<typePropSets.length; x++){
		}

		for(var x=0; x<localPropSets.length; x++){
		}
		*/
		// dojo.profile.end("satisfyPropertySets");
		
		return args;
	},

	mixInProperties: function(args, frag){
		if((args["fastMixIn"])||(frag["fastMixIn"])){
			// dojo.profile.start("mixInProperties_fastMixIn");
			// fast mix in assumes case sensitivity, no type casting, etc...
			// dojo.lang.mixin(this, args);
			for(var x in args){
				this[x] = args[x];
			}
			// dojo.profile.end("mixInProperties_fastMixIn");
			return;
		}
		// dojo.profile.start("mixInProperties");
		/*
		 * the actual mix-in code attempts to do some type-assignment based on
		 * PRE-EXISTING properties of the "this" object. When a named property
		 * of a propset is located, it is first tested to make sure that the
		 * current object already "has one". Properties which are undefined in
		 * the base widget are NOT settable here. The next step is to try to
		 * determine type of the pre-existing property. If it's a string, the
		 * property value is simply assigned. If a function, the property is
		 * replaced with a "new Function()" declaration. If an Array, the
		 * system attempts to split the string value on ";" chars, and no
		 * further processing is attempted (conversion of array elements to a
		 * integers, for instance). If the property value is an Object
		 * (testObj.constructor === Object), the property is split first on ";"
		 * chars, secondly on ":" chars, and the resulting key/value pairs are
		 * assigned to an object in a map style. The onus is on the property
		 * user to ensure that all property values are converted to the
		 * expected type before usage.
		 */

		var undef;

		// NOTE: we cannot assume that the passed properties are case-correct
		// (esp due to some browser bugs). Therefore, we attempt to locate
		// properties for assignment regardless of case. This may cause
		// problematic assignments and bugs in the future and will need to be
		// documented with big bright neon lights.

		// FIXME: fails miserably if a mixin property has a default value of null in 
		// a widget

		// NOTE: caching lower-cased args in the prototype is only 
		// acceptable if the properties are invariant.
		// if we have a name-cache, get it
		var lcArgs = dojo.widget.lcArgsCache[this.widgetType];
		if ( lcArgs == null ){
			// build a lower-case property name cache if we don't have one
			lcArgs = {};
			for(var y in this){
				lcArgs[((new String(y)).toLowerCase())] = y;
			}
			dojo.widget.lcArgsCache[this.widgetType] = lcArgs;
		}
		var visited = {};
		for(var x in args){
			if(!this[x]){ // check the cache for properties
				var y = lcArgs[(new String(x)).toLowerCase()];
				if(y){
					args[y] = args[x];
					x = y; 
				}
			}
			if(visited[x]){ continue; }
			visited[x] = true;
			if((typeof this[x]) != (typeof undef)){
				if(typeof args[x] != "string"){
					this[x] = args[x];
				}else{
					if(dojo.lang.isString(this[x])){
						this[x] = args[x];
					}else if(dojo.lang.isNumber(this[x])){
						this[x] = new Number(args[x]); // FIXME: what if NaN is the result?
					}else if(dojo.lang.isBoolean(this[x])){
						this[x] = (args[x].toLowerCase()=="false") ? false : true;
					}else if(dojo.lang.isFunction(this[x])){

						// FIXME: need to determine if always over-writing instead
						// of attaching here is appropriate. I suspect that we
						// might want to only allow attaching w/ action items.
						
						// RAR, 1/19/05: I'm going to attach instead of
						// over-write here. Perhaps function objects could have
						// some sort of flag set on them? Or mixed-into objects
						// could have some list of non-mutable properties
						// (although I'm not sure how that would alleviate this
						// particular problem)? 

						// this[x] = new Function(args[x]);

						// after an IRC discussion last week, it was decided
						// that these event handlers should execute in the
						// context of the widget, so that the "this" pointer
						// takes correctly.
						
						// argument that contains no punctuation other than . is 
						// considered a function spec, not code
						if(args[x].search(/[^\w\.]+/i) == -1){
							this[x] = dojo.evalObjPath(args[x], false);
						}else{
							var tn = dojo.lang.nameAnonFunc(new Function(args[x]), this);
							dojo.event.connect(this, x, this, tn);
						}
					}else if(dojo.lang.isArray(this[x])){ // typeof [] == "object"
						this[x] = args[x].split(";");
					} else if (this[x] instanceof Date) {
						this[x] = new Date(Number(args[x])); // assume timestamp
					}else if(typeof this[x] == "object"){ 
						// FIXME: should we be allowing extension here to handle
						// other object types intelligently?

						// if we defined a URI, we probablt want to allow plain strings
						// to override it
						if (this[x] instanceof dojo.uri.Uri){

							this[x] = args[x];
						}else{

							// FIXME: unlike all other types, we do not replace the
							// object with a new one here. Should we change that?
							var pairs = args[x].split(";");
							for(var y=0; y<pairs.length; y++){
								var si = pairs[y].indexOf(":");
								if((si != -1)&&(pairs[y].length>si)){
									this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1);
								}
							}
						}
					}else{
						// the default is straight-up string assignment. When would
						// we ever hit this?
						this[x] = args[x];
					}
				}
			}else{
				// collect any extra 'non mixed in' args
				this.extraArgs[x.toLowerCase()] = args[x];
			}
		}
		// dojo.profile.end("mixInProperties");
	},
	
	postMixInProperties: function(){
	},

	initialize: function(args, frag){
		// dojo.unimplemented("dojo.widget.Widget.initialize");
		return false;
	},

	postInitialize: function(args, frag){
		return false;
	},

	postCreate: function(args, frag){
		return false;
	},

	uninitialize: function(){
		// dojo.unimplemented("dojo.widget.Widget.uninitialize");
		return false;
	},

	buildRendering: function(){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.buildRendering, on "+this.toString()+", ");
		return false;
	},

	destroyRendering: function(){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.destroyRendering");
		return false;
	},

	cleanUp: function(){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.cleanUp");
		return false;
	},

	addedTo: function(parent){
		// this is just a signal that can be caught
	},

	addChild: function(child){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.addChild");
		return false;
	},

	// Detach the given child widget from me, but don't destroy it
	removeChild: function(widget){
		for(var x=0; x<this.children.length; x++){
			if(this.children[x] === widget){
				this.children.splice(x, 1);
				break;
			}
		}
		return widget;
	},

	resize: function(width, height){
		// both width and height may be set as percentages. The setWidth and
		// setHeight  functions attempt to determine if the passed param is
		// specified in percentage or native units. Integers without a
		// measurement are assumed to be in the native unit of measure.
		this.setWidth(width);
		this.setHeight(height);
	},

	setWidth: function(width){
		if((typeof width == "string")&&(width.substr(-1) == "%")){
			this.setPercentageWidth(width);
		}else{
			this.setNativeWidth(width);
		}
	},

	setHeight: function(height){
		if((typeof height == "string")&&(height.substr(-1) == "%")){
			this.setPercentageHeight(height);
		}else{
			this.setNativeHeight(height);
		}
	},

	setPercentageHeight: function(height){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	setNativeHeight: function(height){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	setPercentageWidth: function(width){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	setNativeWidth: function(width){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	getPreviousSibling: function() {
		var idx = this.getParentIndex();
 
		 // first node is idx=0 not found is idx<0
		if (idx<=0) return null;
 
		return this.getSiblings()[idx-1];
	},
 
	getSiblings: function() {
		return this.parent.children;
	},
 
	getParentIndex: function() {
		return dojo.lang.indexOf( this.getSiblings(), this, true);
	},
 
	getNextSibling: function() {
 
		var idx = this.getParentIndex();
 
		if (idx == this.getSiblings().length-1) return null; // last node
		if (idx < 0) return null; // not found
 
		return this.getSiblings()[idx+1];
 
	}
});

// Lower case name cache: listing of the lower case elements in each widget.
// We can't store the lcArgs in the widget itself because if B subclasses A,
// then B.prototype.lcArgs might return A.prototype.lcArgs, which is not what we
// want
dojo.widget.lcArgsCache = {};

// TODO: should have a more general way to add tags or tag libraries?
// TODO: need a default tags class to inherit from for things like getting propertySets
// TODO: parse properties/propertySets into component attributes
// TODO: parse subcomponents
// TODO: copy/clone raw markup fragments/nodes as appropriate
dojo.widget.tags = {};
dojo.widget.tags.addParseTreeHandler = function(type){
	var ltype = type.toLowerCase();
	this[ltype] = function(fragment, widgetParser, parentComp, insertionIndex, localProps){ 
		return dojo.widget.buildWidgetFromParseTree(ltype, fragment, widgetParser, parentComp, insertionIndex, localProps);
	}
}
dojo.widget.tags.addParseTreeHandler("dojo:widget");

dojo.widget.tags["dojo:propertyset"] = function(fragment, widgetParser, parentComp){
	// FIXME: Is this needed?
	// FIXME: Not sure that this parses into the structure that I want it to parse into...
	// FIXME: add support for nested propertySets
	var properties = widgetParser.parseProperties(fragment["dojo:propertyset"]);
}

// FIXME: need to add the <dojo:connect />
dojo.widget.tags["dojo:connect"] = function(fragment, widgetParser, parentComp){
	var properties = widgetParser.parseProperties(fragment["dojo:connect"]);
}

// FIXME: if we know the insertion point (to a reasonable location), why then do we:
//	- create a template node
//	- clone the template node
//	- render the clone and set properties
//	- remove the clone from the render tree
//	- place the clone
// this is quite dumb
dojo.widget.buildWidgetFromParseTree = function(type, frag, 
												parser, parentComp, 
												insertionIndex, localProps){
	var stype = type.split(":");
	stype = (stype.length == 2) ? stype[1] : type;
	// FIXME: we don't seem to be doing anything with this!
	// var propertySets = parser.getPropertySets(frag);
	var localProperties = localProps || parser.parseProperties(frag["dojo:"+stype]);
	// var tic = new Date();
	var twidget = dojo.widget.manager.getImplementation(stype);
	if(!twidget){
		throw new Error("cannot find \"" + stype + "\" widget");
	}else if (!twidget.create){
		throw new Error("\"" + stype + "\" widget object does not appear to implement *Widget");
	}
	localProperties["dojoinsertionindex"] = insertionIndex;
	// FIXME: we loose no less than 5ms in construction!
	var ret = twidget.create(localProperties, frag, parentComp);
	// dojo.debug(new Date() - tic);
	return ret;
}

/*
 * Create a widget constructor function (aka widgetClass)
 */
dojo.widget.defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
	// This meta-function does parameter juggling for backward compat and overloading
	// if 4th argument is a string, we are using the old syntax
	// old sig: widgetClass, superclasses, props (object), renderer (string), init (function)
	if(dojo.lang.isString(arguments[3])){
		dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]);
	}else{
		// widgetClass
		var args = [ arguments[0] ], p = 3;
		if(dojo.lang.isString(arguments[1])){
			// renderer, superclass
			args.push(arguments[1], arguments[2]);
		}else{
			// superclass
			args.push('', arguments[1]);
			p = 2;
		}
		if(dojo.lang.isFunction(arguments[p])){
			// init (function), props (object) 
			args.push(arguments[p], arguments[p+1]);
		}else{
			// props (object) 
			args.push(null, arguments[p]);
		}
		dojo.widget._defineWidget.apply(this, args);
	}
}

dojo.widget.defineWidget.renderers = "html|svg|vml";

dojo.widget._defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
	// FIXME: uncomment next line to test parameter juggling ... remove when confidence improves
	//dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props);
	// widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName)
	var namespace = widgetClass.split(".");
	var type = namespace.pop(); // type <= WidgetName, namespace <= foo.bar.baz<.renderer>
	var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\.";
	var r = widgetClass.search(new RegExp(regx));
	namespace = (r < 0 ? namespace.join(".") : widgetClass.substr(0, r));

	dojo.widget.manager.registerWidgetPackage(namespace);
	dojo.widget.tags.addParseTreeHandler("dojo:"+type.toLowerCase());

	props=(props)||{};
	props.widgetType = type;
	if((!init)&&(props["classConstructor"])){
		init = props.classConstructor;
		delete props.classConstructor;
	}
	dojo.declare(widgetClass, superclasses, init, props);
}
/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.kwCompoundRequire({
	common: ["dojo.uri.Uri", false, false]
});
dojo.provide("dojo.uri.*");

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.Parse");

dojo.require("dojo.widget.Manager");
dojo.require("dojo.dom");

dojo.widget.Parse = function(fragment) {
	this.propertySetsList = [];
	this.fragment = fragment;
	
	this.createComponents = function(frag, parentComp){
		var comps = [ ];
		var built = false;
		// if we have items to parse/create at this level, do it!
		try{
			if((frag)&&(frag["tagName"])&&(frag!=frag["nodeRef"])){
				var djTags = dojo.widget.tags;
				// we split so that you can declare multiple
				// non-destructive widgets from the same ctor node
				var tna = String(frag["tagName"]).split(";");
				for(var x=0; x<tna.length; x++){
					var ltn = (tna[x].replace(/^\s+|\s+$/g, "")).toLowerCase();
					if(djTags[ltn]){
						built = true;
						frag.tagName = ltn;
						var ret = djTags[ltn](frag, this, parentComp, frag["index"]);
						comps.push(ret);
					}else{
						if((dojo.lang.isString(ltn))&&(ltn.substr(0, 5)=="dojo:")){
							dojo.debug("no tag handler registed for type: ", ltn);
						}
					}
				}
			}
		}catch(e){
			dojo.debug("dojo.widget.Parse: error:", e);
			// throw(e);
			// IE is such a bitch sometimes
		}
		// if there's a sub-frag, build widgets from that too
		if(!built){
			comps = comps.concat(this.createSubComponents(frag, parentComp));
		}
		return comps;
	}

	/*	createSubComponents recurses over a raw JavaScript object structure,
			and calls the corresponding handler for its normalized tagName if it exists
	*/
	this.createSubComponents = function(fragment, parentComp){
		var frag, comps = [];
		for(var item in fragment){
			frag = fragment[item];
			if ((frag)&&(typeof frag == "object")&&(frag!=fragment.nodeRef)&&(frag!=fragment["tagName"])){
				comps = comps.concat(this.createComponents(frag, parentComp));
			}
		}
		return comps;
	}

	/*  parsePropertySets checks the top level of a raw JavaScript object
			structure for any propertySets.  It stores an array of references to 
			propertySets that it finds.
	*/
	this.parsePropertySets = function(fragment) {
		return [];
		var propertySets = [];
		for(var item in fragment){
			if(	(fragment[item]["tagName"] == "dojo:propertyset") ) {
				propertySets.push(fragment[item]);
			}
		}
		// FIXME: should we store these propertySets somewhere for later retrieval
		this.propertySetsList.push(propertySets);
		return propertySets;
	}
	
	/*  parseProperties checks a raw JavaScript object structure for
			properties, and returns an array of properties that it finds.
	*/
	this.parseProperties = function(fragment) {
		var properties = {};
		for(var item in fragment){
			// FIXME: need to check for undefined?
			// case: its a tagName or nodeRef
			if((fragment[item] == fragment["tagName"])||
				(fragment[item] == fragment.nodeRef)){
				// do nothing
			}else{
				if((fragment[item]["tagName"])&&
					(dojo.widget.tags[fragment[item].tagName.toLowerCase()])){
					// TODO: it isn't a property or property set, it's a fragment, 
					// so do something else
					// FIXME: needs to be a better/stricter check
					// TODO: handle xlink:href for external property sets
				}else if((fragment[item][0])&&(fragment[item][0].value!="")&&(fragment[item][0].value!=null)){
					try{
						// FIXME: need to allow more than one provider
						if(item.toLowerCase() == "dataprovider") {
							var _this = this;
							this.getDataProvider(_this, fragment[item][0].value);
							properties.dataProvider = this.dataProvider;
						}
						properties[item] = fragment[item][0].value;
						var nestedProperties = this.parseProperties(fragment[item]);
						// FIXME: this kind of copying is expensive and inefficient!
						for(var property in nestedProperties){
							properties[property] = nestedProperties[property];
						}
					}catch(e){ dojo.debug(e); }
				}
			}
		}
		return properties;
	}

	/* getPropertySetById returns the propertySet that matches the provided id
	*/
	
	this.getDataProvider = function(objRef, dataUrl) {
		// FIXME: this is currently sync.  To make this async, we made need to move 
		//this step into the widget ctor, so that it is loaded when it is needed 
		// to populate the widget
		dojo.io.bind({
			url: dataUrl,
			load: function(type, evaldObj){
				if(type=="load"){
					objRef.dataProvider = evaldObj;
				}
			},
			mimetype: "text/javascript",
			sync: true
		});
	}

	
	this.getPropertySetById = function(propertySetId){
		for(var x = 0; x < this.propertySetsList.length; x++){
			if(propertySetId == this.propertySetsList[x]["id"][0].value){
				return this.propertySetsList[x];
			}
		}
		return "";
	}
	
	/* getPropertySetsByType returns the propertySet(s) that match(es) the
	 * provided componentClass
	 */
	this.getPropertySetsByType = function(componentType){
		var propertySets = [];
		for(var x=0; x < this.propertySetsList.length; x++){
			var cpl = this.propertySetsList[x];
			var cpcc = cpl["componentClass"]||cpl["componentType"]||null;
			// FIXME: propertySetId is not in scope here
			if((cpcc)&&(propertySetId == cpcc[0].value)){
				propertySets.push(cpl);
			}
		}
		return propertySets;
	}
	
	/* getPropertySets returns the propertySet for a given component fragment
	*/
	this.getPropertySets = function(fragment){
		var ppl = "dojo:propertyproviderlist";
		var propertySets = [];
		var tagname = fragment["tagName"];
		if(fragment[ppl]){ 
			var propertyProviderIds = fragment[ppl].value.split(" ");
			// FIXME: should the propertyProviderList attribute contain #
			// 		  syntax for reference to ids or not?
			// FIXME: need a better test to see if this is local or external
			// FIXME: doesn't handle nested propertySets, or propertySets that
			// 		  just contain information about css documents, etc.
			for(var propertySetId in propertyProviderIds){
				if((propertySetId.indexOf("..")==-1)&&(propertySetId.indexOf("://")==-1)){
					// get a reference to a propertySet within the current parsed structure
					var propertySet = this.getPropertySetById(propertySetId);
					if(propertySet != ""){
						propertySets.push(propertySet);
					}
				}else{
					// FIXME: add code to parse and return a propertySet from
					// another document
					// alex: is this even necessaray? Do we care? If so, why?
				}
			}
		}
		// we put the typed ones first so that the parsed ones override when
		// iteration happens.
		return (this.getPropertySetsByType(tagname)).concat(propertySets);
	}
	
	/* 
		nodeRef is the node to be replaced... in the future, we might want to add 
		an alternative way to specify an insertion point

		componentName is the expected dojo widget name, i.e. Button of ContextMenu

		properties is an object of name value pairs
	*/
	this.createComponentFromScript = function(nodeRef, componentName, properties){
		var ltn = "dojo:" + componentName.toLowerCase();
		if(dojo.widget.tags[ltn]){
			properties.fastMixIn = true;
			return [dojo.widget.tags[ltn](properties, this, null, null, properties)];
		}else{
			if(ltn.substr(0, 5)=="dojo:"){
				dojo.debug("no tag handler registed for type: ", ltn);
			}
		}
	}
}


dojo.widget._parser_collection = {"dojo": new dojo.widget.Parse() };
dojo.widget.getParser = function(name){
	if(!name){ name = "dojo"; }
	if(!this._parser_collection[name]){
		this._parser_collection[name] = new dojo.widget.Parse();
	}
	return this._parser_collection[name];
}

/**
 * Creates widget.
 *
 * @param name     The name of the widget to create
 * @param props    Key-Value pairs of properties of the widget
 * @param refNode  If the last argument is specified this node is used as
 *                 a reference for inserting this node into a DOM tree else
 *                 it beomces the domNode
 * @param position The position to insert this widget's node relative to the
 *                 refNode argument
 * @return The new Widget object
 */
 
dojo.widget.createWidget = function(name, props, refNode, position){
	var lowerCaseName = name.toLowerCase();
	var namespacedName = "dojo:" + lowerCaseName;
	var isNode = ( dojo.byId(name) && (!dojo.widget.tags[namespacedName]) );

	// if we got a node or an unambiguious ID, build a widget out of it
	if(	(arguments.length==1) && ((typeof name != "string")||(isNode)) ){
		// we got a DOM node
		var xp = new dojo.xml.Parse();
		// FIXME: we should try to find the parent!
		var tn = (isNode) ? dojo.byId(name) : name;
		return dojo.widget.getParser().createComponents(xp.parseElement(tn, null, true))[0];
	}

	function fromScript (placeKeeperNode, name, props) {
		props[namespacedName] = { 
			dojotype: [{value: lowerCaseName}],
			nodeRef: placeKeeperNode,
			fastMixIn: true
		};
		return dojo.widget.getParser().createComponentFromScript(
			placeKeeperNode, name, props, true);
	}

	if (typeof name != "string" && typeof props == "string") {
		dojo.deprecated("dojo.widget.createWidget", 
			"argument order is now of the form " +
			"dojo.widget.createWidget(NAME, [PROPERTIES, [REFERENCENODE, [POSITION]]])", "0.4");
		return fromScript(name, props, refNode);
	}
	
	props = props||{};
	var notRef = false;
	var tn = null;
	var h = dojo.render.html.capable;
	if(h){
		tn = document.createElement("span");
	}
	if(!refNode){
		notRef = true;
		refNode = tn;
		if(h){
			document.body.appendChild(refNode);
		}
	}else if(position){
		dojo.dom.insertAtPosition(tn, refNode, position);
	}else{ // otherwise don't replace, but build in-place
		tn = refNode;
	}
	var widgetArray = fromScript(tn, name, props);
	if (!widgetArray || !widgetArray[0] || typeof widgetArray[0].widgetType == "undefined") {
		throw new Error("createWidget: Creation of \"" + name + "\" widget failed.");
	}
	if (notRef) {
		if (widgetArray[0].domNode.parentNode) {
			widgetArray[0].domNode.parentNode.removeChild(widgetArray[0].domNode);
		}
	}
	return widgetArray[0]; // just return the widget
}
 
dojo.widget.fromScript = function(name, props, refNode, position){
	dojo.deprecated("dojo.widget.fromScript", " use " +
		"dojo.widget.createWidget instead", "0.4");
	return dojo.widget.createWidget(name, props, refNode, position);
}

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.io.cookie");

dojo.io.cookie.setCookie = function(name, value, days, path, domain, secure) {
	var expires = -1;
	if(typeof days == "number" && days >= 0) {
		var d = new Date();
		d.setTime(d.getTime()+(days*24*60*60*1000));
		expires = d.toGMTString();
	}
	value = escape(value);
	document.cookie = name + "=" + value + ";"
		+ (expires != -1 ? " expires=" + expires + ";" : "")
		+ (path ? "path=" + path : "")
		+ (domain ? "; domain=" + domain : "")
		+ (secure ? "; secure" : "");
}

dojo.io.cookie.set = dojo.io.cookie.setCookie;

dojo.io.cookie.getCookie = function(name) {
	// FIXME: Which cookie should we return?
	//        If there are cookies set for different sub domains in the current
	//        scope there could be more than one cookie with the same name.
	//        I think taking the last one in the list takes the one from the
	//        deepest subdomain, which is what we're doing here.
	var idx = document.cookie.lastIndexOf(name+'=');
	if(idx == -1) { return null; }
	var value = document.cookie.substring(idx+name.length+1);
	var end = value.indexOf(';');
	if(end == -1) { end = value.length; }
	value = value.substring(0, end);
	value = unescape(value);
	return value;
}

dojo.io.cookie.get = dojo.io.cookie.getCookie;

dojo.io.cookie.deleteCookie = function(name) {
	dojo.io.cookie.setCookie(name, "-", 0);
}

dojo.io.cookie.setObjectCookie = function(name, obj, days, path, domain, secure, clearCurrent) {
	if(arguments.length == 5) { // for backwards compat
		clearCurrent = domain;
		domain = null;
		secure = null;
	}
	var pairs = [], cookie, value = "";
	if(!clearCurrent) { cookie = dojo.io.cookie.getObjectCookie(name); }
	if(days >= 0) {
		if(!cookie) { cookie = {}; }
		for(var prop in obj) {
			if(prop == null) {
				delete cookie[prop];
			} else if(typeof obj[prop] == "string" || typeof obj[prop] == "number") {
				cookie[prop] = obj[prop];
			}
		}
		prop = null;
		for(var prop in cookie) {
			pairs.push(escape(prop) + "=" + escape(cookie[prop]));
		}
		value = pairs.join("&");
	}
	dojo.io.cookie.setCookie(name, value, days, path, domain, secure);
}

dojo.io.cookie.getObjectCookie = function(name) {
	var values = null, cookie = dojo.io.cookie.getCookie(name);
	if(cookie) {
		values = {};
		var pairs = cookie.split("&");
		for(var i = 0; i < pairs.length; i++) {
			var pair = pairs[i].split("=");
			var value = pair[1];
			if( isNaN(value) ) { value = unescape(pair[1]); }
			values[ unescape(pair[0]) ] = value;
		}
	}
	return values;
}

dojo.io.cookie.isSupported = function() {
	if(typeof navigator.cookieEnabled != "boolean") {
		dojo.io.cookie.setCookie("__TestingYourBrowserForCookieSupport__",
			"CookiesAllowed", 90, null);
		var cookieVal = dojo.io.cookie.getCookie("__TestingYourBrowserForCookieSupport__");
		navigator.cookieEnabled = (cookieVal == "CookiesAllowed");
		if(navigator.cookieEnabled) {
			// FIXME: should we leave this around?
			this.deleteCookie("__TestingYourBrowserForCookieSupport__");
		}
	}
	return navigator.cookieEnabled;
}

// need to leave this in for backwards-compat from 0.1 for when it gets pulled in by dojo.io.*
if(!dojo.io.cookies) { dojo.io.cookies = dojo.io.cookie; }

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.io.IframeIO");
dojo.require("dojo.io.BrowserIO");
dojo.require("dojo.uri.*");

// FIXME: is it possible to use the Google htmlfile hack to prevent the
// background click with this transport?

dojo.io.createIFrame = function(fname, onloadstr){
	if(window[fname]){ return window[fname]; }
	if(window.frames[fname]){ return window.frames[fname]; }
	var r = dojo.render.html;
	var cframe = null;
	var turi = dojo.uri.dojoUri("iframe_history.html?noInit=true");
	var ifrstr = ((r.ie)&&(dojo.render.os.win)) ? "<iframe name='"+fname+"' src='"+turi+"' onload='"+onloadstr+"'>" : "iframe";
	cframe = document.createElement(ifrstr);
	with(cframe){
		name = fname;
		setAttribute("name", fname);
		id = fname;
	}
	(document.body||document.getElementsByTagName("body")[0]).appendChild(cframe);
	window[fname] = cframe;
	with(cframe.style){
		position = "absolute";
		left = top = "0px";
		height = width = "1px";
		visibility = "hidden";
	
		/*if(djConfig.isDebug){
			position = "relative";
			height = "300px";
			width = "800px";
			visibility = "visible";			
			background="red";
		}*/		
	}

	if(!r.ie){
		dojo.io.setIFrameSrc(cframe, turi, true);
		cframe.onload = new Function(onloadstr);
	}
	return cframe;
}

// thanks burstlib!
dojo.io.iframeContentWindow = function(iframe_el) {
	var win = iframe_el.contentWindow || // IE
		dojo.io.iframeContentDocument(iframe_el).defaultView || // Moz, opera
		// Moz. TODO: is this available when defaultView isn't?
		dojo.io.iframeContentDocument(iframe_el).__parent__ || 
		(iframe_el.name && document.frames[iframe_el.name]) || null;
	return win;
}

dojo.io.iframeContentDocument = function(iframe_el){
	var doc = iframe_el.contentDocument || // W3
		(
			(iframe_el.contentWindow)&&(iframe_el.contentWindow.document)
		) ||  // IE
		(
			(iframe_el.name)&&(document.frames[iframe_el.name])&&
			(document.frames[iframe_el.name].document)
		) || null;
	return doc;
}

dojo.io.IframeTransport = new function(){
	var _this = this;
	this.currentRequest = null;
	this.requestQueue = [];
	this.iframeName = "dojoIoIframe";

	this.fireNextRequest = function(){
		if((this.currentRequest)||(this.requestQueue.length == 0)){ return; }
		// dojo.debug("fireNextRequest");
		var cr = this.currentRequest = this.requestQueue.shift();
		cr._contentToClean = [];
		var fn = cr["formNode"];
		var content = cr["content"] || {};
		if(cr.sendTransport) {
			content["dojo.transport"] = "iframe";
		}
		if(fn){
			if(content){
				// if we have things in content, we need to add them to the form
				// before submission
				for(var x in content){
					if(!fn[x]){
						var tn;
						if(dojo.render.html.ie){
							tn = document.createElement("<input type='hidden' name='"+x+"' value='"+content[x]+"'>");
							fn.appendChild(tn);
						}else{
							tn = document.createElement("input");
							fn.appendChild(tn);
							tn.type = "hidden";
							tn.name = x;
							tn.value = content[x];
						}
						cr._contentToClean.push(x);
					}else{
						fn[x].value = content[x];
					}
				}
			}
			if(cr["url"]){
				cr._originalAction = fn.getAttribute("action");
				fn.setAttribute("action", cr.url);
			}
			if(!fn.getAttribute("method")){
				fn.setAttribute("method", (cr["method"]) ? cr["method"] : "post");
			}
			cr._originalTarget = fn.getAttribute("target");
			fn.setAttribute("target", this.iframeName);
			fn.target = this.iframeName;
			fn.submit();
		}else{
			// otherwise we post a GET string by changing URL location for the
			// iframe
			var query = dojo.io.argsFromMap(this.currentRequest.content);
			var tmpUrl = (cr.url.indexOf("?") > -1 ? "&" : "?") + query;
			dojo.io.setIFrameSrc(this.iframe, tmpUrl, true);
		}
	}

	this.canHandle = function(kwArgs){
		return (
			(
				// FIXME: can we really handle text/plain and
				// text/javascript requests?
				dojo.lang.inArray(kwArgs["mimetype"], 
				[	"text/plain", "text/html", 
					"text/javascript", "text/json"])
			)&&(
				// make sur we really only get used in file upload cases	
				(kwArgs["formNode"])&&(dojo.io.checkChildrenForFile(kwArgs["formNode"]))
			)&&(
				dojo.lang.inArray(kwArgs["method"].toLowerCase(), ["post", "get"])
			)&&(
				// never handle a sync request
				!  ((kwArgs["sync"])&&(kwArgs["sync"] == true))
			)
		);
	}

	this.bind = function(kwArgs){
		if(!this["iframe"]){ this.setUpIframe(); }
		this.requestQueue.push(kwArgs);
		this.fireNextRequest();
		return;
	}

	this.setUpIframe = function(){

		// NOTE: IE 5.0 and earlier Mozilla's don't support an onload event for
		//       iframes. OTOH, we don't care.
		this.iframe = dojo.io.createIFrame(this.iframeName, "dojo.io.IframeTransport.iframeOnload();");
	}

	this.iframeOnload = function(){
		if(!_this.currentRequest){
			_this.fireNextRequest();
			return;
		}

		var req = _this.currentRequest;

		// remove all the hidden content inputs
		var toClean = req._contentToClean;
		for(var i = 0; i < toClean.length; i++) {
			var key = toClean[i];
			if(dojo.render.html.safari){
				//In Safari (at least 2.0.3), can't use formNode[key] syntax to find the node,
				//for nodes that were dynamically added.
				var fNode = req.formNode;
				for(var j = 0; j < fNode.childNodes.length; j++){
					var chNode = fNode.childNodes[j];
					if(chNode.name == key){
						var pNode = chNode.parentNode;
						pNode.removeChild(chNode);
						break;
					}
				}
			}else{
				var input = req.formNode[key];
				req.formNode.removeChild(input);
				req.formNode[key] = null;
			}
		}

		// restore original action + target
		if(req["_originalAction"]){
			req.formNode.setAttribute("action", req._originalAction);
		}
		req.formNode.setAttribute("target", req._originalTarget);
		req.formNode.target = req._originalTarget;

		var ifd = dojo.io.iframeContentDocument(_this.iframe);
		// handle successful returns
		// FIXME: how do we determine success for iframes? Is there an equiv of
		// the "status" property?
		var value;
		var success = false;

		try{
			var cmt = req.mimetype;
			if((cmt == "text/javascript")||(cmt == "text/json")){
				// FIXME: not sure what to do here? try to pull some evalulable
				// text from a textarea or cdata section? 
				// how should we set up the contract for that?
				var js = ifd.getElementsByTagName("textarea")[0].value;
				if(cmt == "text/json") { js = "(" + js + ")"; }
				value = dj_eval(js);
			}else if(cmt == "text/html"){
				value = ifd;
			}else{ // text/plain
				value = ifd.getElementsByTagName("textarea")[0].value;
			}
			success = true;
		}catch(e){ 
			// looks like we didn't get what we wanted!
			var errObj = new dojo.io.Error("IframeTransport Error");
			if(dojo.lang.isFunction(req["error"])){
				req.error("error", errObj, req);
			}
		}

		// don't want to mix load function errors with processing errors, thus
		// a separate try..catch
		try {
			if(success && dojo.lang.isFunction(req["load"])){
				req.load("load", value, req);
			}
		} catch(e) {
			throw e;
		} finally {
			_this.currentRequest = null;
			_this.fireNextRequest();
		}
	}

	dojo.io.transports.addTransport("IframeTransport");
}

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.kwCompoundRequire({
	common: ["dojo.io"],
	rhino: ["dojo.io.RhinoIO"],
	browser: ["dojo.io.BrowserIO", "dojo.io.cookie"],
	dashboard: ["dojo.io.BrowserIO", "dojo.io.cookie"]
});
dojo.provide("dojo.io.*");

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.require("dojo.html");
dojo.provide("dojo.html.extras");
dojo.require("dojo.string.extras"); 

/**
 * Calculates the mouse's direction of gravity relative to the centre
 * of the given node.
 * <p>
 * If you wanted to insert a node into a DOM tree based on the mouse
 * position you might use the following code:
 * <pre>
 * if (gravity(node, e) & gravity.NORTH) { [insert before]; }
 * else { [insert after]; }
 * </pre>
 *
 * @param node The node
 * @param e		The event containing the mouse coordinates
 * @return		 The directions, NORTH or SOUTH and EAST or WEST. These
 *						 are properties of the function.
 */
dojo.html.gravity = function(node, e){
	node = dojo.byId(node);
	var mouse = dojo.html.getCursorPosition(e);

	with (dojo.html) {
		var nodecenterx = getAbsoluteX(node, true) + (getInnerWidth(node) / 2);
		var nodecentery = getAbsoluteY(node, true) + (getInnerHeight(node) / 2);
	}
	
	with (dojo.html.gravity) {
		return ((mouse.x < nodecenterx ? WEST : EAST) |
			(mouse.y < nodecentery ? NORTH : SOUTH));
	}
}

dojo.html.gravity.NORTH = 1;
dojo.html.gravity.SOUTH = 1 << 1;
dojo.html.gravity.EAST = 1 << 2;
dojo.html.gravity.WEST = 1 << 3;


/**
 * Attempts to return the text as it would be rendered, with the line breaks
 * sorted out nicely. Unfinished.
 */
dojo.html.renderedTextContent = function(node){
	node = dojo.byId(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
				var display = "unknown";
				try {
					display = dojo.style.getStyle(node.childNodes[i], "display");
				} catch(E) {}
				switch (display) {
					case "block": case "list-item": case "run-in":
					case "table": case "table-row-group": case "table-header-group":
					case "table-footer-group": case "table-row": case "table-column-group":
					case "table-column": case "table-cell": case "table-caption":
						// TODO: this shouldn't insert double spaces on aligning blocks
						result += "\n";
						result += dojo.html.renderedTextContent(node.childNodes[i]);
						result += "\n";
						break;
					
					case "none": break;
					
					default:
						if(node.childNodes[i].tagName && node.childNodes[i].tagName.toLowerCase() == "br") {
							result += "\n";
						} else {
							result += dojo.html.renderedTextContent(node.childNodes[i]);
						}
						break;
				}
				break;
			case 3: // TEXT_NODE
			case 2: // ATTRIBUTE_NODE
			case 4: // CDATA_SECTION_NODE
				var text = node.childNodes[i].nodeValue;
				var textTransform = "unknown";
				try {
					textTransform = dojo.style.getStyle(node, "text-transform");
				} catch(E) {}
				switch (textTransform){
					case "capitalize": text = dojo.string.capitalize(text); break;
					case "uppercase": text = text.toUpperCase(); break;
					case "lowercase": text = text.toLowerCase(); break;
					default: break; // leave as is
				}
				// TODO: implement
				switch (textTransform){
					case "nowrap": break;
					case "pre-wrap": break;
					case "pre-line": break;
					case "pre": break; // leave as is
					default:
						// remove whitespace and collapse first space
						text = text.replace(/\s+/, " ");
						if (/\s$/.test(result)) { text.replace(/^\s/, ""); }
						break;
				}
				result += text;
				break;
			default:
				break;
		}
	}
	return result;
}

dojo.html.createNodesFromText = function(txt, trim){
	if(trim) { txt = dojo.string.trim(txt); }

	var tn = document.createElement("div");
	// tn.style.display = "none";
	tn.style.visibility= "hidden";
	document.body.appendChild(tn);
	var tableType = "none";
	if((/^<t[dh][\s\r\n>]/i).test(dojo.string.trimStart(txt))) {
		txt = "<table><tbody><tr>" + txt + "</tr></tbody></table>";
		tableType = "cell";
	} else if((/^<tr[\s\r\n>]/i).test(dojo.string.trimStart(txt))) {
		txt = "<table><tbody>" + txt + "</tbody></table>";
		tableType = "row";
	} else if((/^<(thead|tbody|tfoot)[\s\r\n>]/i).test(dojo.string.trimStart(txt))) {
		txt = "<table>" + txt + "</table>";
		tableType = "section";
	}
	tn.innerHTML = txt;
	if(tn["normalize"]){
		tn.normalize();
	}

	var parent = null;
	switch(tableType) {
		case "cell":
			parent = tn.getElementsByTagName("tr")[0];
			break;
		case "row":
			parent = tn.getElementsByTagName("tbody")[0];
			break;
		case "section":
			parent = tn.getElementsByTagName("table")[0];
			break;
		default:
			parent = tn;
			break;
	}

	/* this doesn't make much sense, I'm assuming it just meant trim() so wrap was replaced with trim
	if(wrap){ 
		var ret = [];
		// start hack
		var fc = tn.firstChild;
		ret[0] = ((fc.nodeValue == " ")||(fc.nodeValue == "\t")) ? fc.nextSibling : fc;
		// end hack
		// tn.style.display = "none";
		document.body.removeChild(tn);
		return ret;
	}
	*/
	var nodes = [];
	for(var x=0; x<parent.childNodes.length; x++){
		nodes.push(parent.childNodes[x].cloneNode(true));
	}
	tn.style.display = "none"; // FIXME: why do we do this?
	document.body.removeChild(tn);
	return nodes;
}

/* TODO: merge placeOnScreen and placeOnScreenPoint to make 1 function that allows you
 * to define which corner(s) you want to bind to. Something like so:
 *
 * kes(node, desiredX, desiredY, "TR")
 * kes(node, [desiredX, desiredY], ["TR", "BL"])
 *
 * TODO: make this function have variable call sigs
 *
 * kes(node, ptArray, cornerArray, padding, hasScroll)
 * kes(node, ptX, ptY, cornerA, cornerB, cornerC, paddingArray, hasScroll)
 */

/**
 * Keeps 'node' in the visible area of the screen while trying to
 * place closest to desiredX, desiredY. The input coordinates are
 * expected to be the desired screen position, not accounting for
 * scrolling. If you already accounted for scrolling, set 'hasScroll'
 * to true. Set padding to either a number or array for [paddingX, paddingY]
 * to put some buffer around the element you want to position.
 * NOTE: node is assumed to be absolutely or relatively positioned.
 *
 * Alternate call sig:
 *  placeOnScreen(node, [x, y], padding, hasScroll)
 *
 * Examples:
 *  placeOnScreen(node, 100, 200)
 *  placeOnScreen("myId", [800, 623], 5)
 *  placeOnScreen(node, 234, 3284, [2, 5], true)
 */
dojo.html.placeOnScreen = function(node, desiredX, desiredY, padding, hasScroll) {
	if(dojo.lang.isArray(desiredX)) {
		hasScroll = padding;
		padding = desiredY;
		desiredY = desiredX[1];
		desiredX = desiredX[0];
	}

	if(!isNaN(padding)) {
		padding = [Number(padding), Number(padding)];
	} else if(!dojo.lang.isArray(padding)) {
		padding = [0, 0];
	}

	var scroll = dojo.html.getScrollOffset();
	var view = dojo.html.getViewportSize();

	node = dojo.byId(node);
	var w = node.offsetWidth + padding[0];
	var h = node.offsetHeight + padding[1];

	if(hasScroll) {
		desiredX -= scroll.x;
		desiredY -= scroll.y;
	}

	var x = desiredX + w;
	if(x > view.w) {
		x = view.w - w;
	} else {
		x = desiredX;
	}
	x = Math.max(padding[0], x) + scroll.x;

	var y = desiredY + h;
	if(y > view.h) {
		y = view.h - h;
	} else {
		y = desiredY;
	}
	y = Math.max(padding[1], y) + scroll.y;

	node.style.left = x + "px";
	node.style.top = y + "px";

	var ret = [x, y];
	ret.x = x;
	ret.y = y;
	return ret;
}

/**
 * Like placeOnScreenPoint except that it attempts to keep one of the node's
 * corners at desiredX, desiredY.  Favors the bottom right position
 *
 * Examples placing node at mouse position (where e = [Mouse event]):
 *  placeOnScreenPoint(node, e.clientX, e.clientY);
 */
dojo.html.placeOnScreenPoint = function(node, desiredX, desiredY, padding, hasScroll) {
	if(dojo.lang.isArray(desiredX)) {
		hasScroll = padding;
		padding = desiredY;
		desiredY = desiredX[1];
		desiredX = desiredX[0];
	}

	if(!isNaN(padding)) {
		padding = [Number(padding), Number(padding)];
	} else if(!dojo.lang.isArray(padding)) {
		padding = [0, 0];
	}

	var scroll = dojo.html.getScrollOffset();
	var view = dojo.html.getViewportSize();

	node = dojo.byId(node);
	var oldDisplay = node.style.display;
	node.style.display="";
	var w = dojo.style.getInnerWidth(node);
	var h = dojo.style.getInnerHeight(node);
	node.style.display=oldDisplay;

	if(hasScroll) {
		desiredX -= scroll.x;
		desiredY -= scroll.y;
	}

	var x = -1, y = -1;
	//dojo.debug((desiredX+padding[0]) + w, "<=", view.w, "&&", (desiredY+padding[1]) + h, "<=", view.h);
	if((desiredX+padding[0]) + w <= view.w && (desiredY+padding[1]) + h <= view.h) { // TL
		x = (desiredX+padding[0]);
		y = (desiredY+padding[1]);
		//dojo.debug("TL", x, y);
	}

	//dojo.debug((desiredX-padding[0]), "<=", view.w, "&&", (desiredY+padding[1]) + h, "<=", view.h);
	if((x < 0 || y < 0) && (desiredX-padding[0]) <= view.w && (desiredY+padding[1]) + h <= view.h) { // TR
		x = (desiredX-padding[0]) - w;
		y = (desiredY+padding[1]);
		//dojo.debug("TR", x, y);
	}

	//dojo.debug((desiredX+padding[0]) + w, "<=", view.w, "&&", (desiredY-padding[1]), "<=", view.h);
	if((x < 0 || y < 0) && (desiredX+padding[0]) + w <= view.w && (desiredY-padding[1]) <= view.h) { // BL
		x = (desiredX+padding[0]);
		y = (desiredY-padding[1]) - h;
		//dojo.debug("BL", x, y);
	}

	//dojo.debug((desiredX-padding[0]), "<=", view.w, "&&", (desiredY-padding[1]), "<=", view.h);
	if((x < 0 || y < 0) && (desiredX-padding[0]) <= view.w && (desiredY-padding[1]) <= view.h) { // BR
		x = (desiredX-padding[0]) - w;
		y = (desiredY-padding[1]) - h;
		//dojo.debug("BR", x, y);
	}

	if(x < 0 || y < 0 || (x + w > view.w) || (y + h > view.h)) {
		return dojo.html.placeOnScreen(node, desiredX, desiredY, padding, hasScroll);
	}

	x += scroll.x;
	y += scroll.y;

	node.style.left = x + "px";
	node.style.top = y + "px";

	var ret = [x, y];
	ret.x = x;
	ret.y = y;
	return ret;
}

/**
 * For IE z-index schenanigans
 * Two possible uses:
 *   1. new dojo.html.BackgroundIframe(node)
 *        Makes a background iframe as a child of node, that fills area (and position) of node
 *
 *   2. new dojo.html.BackgroundIframe()
 *        Attaches frame to document.body.  User must call size() to set size.
 */
dojo.html.BackgroundIframe = function(node) {
	if(dojo.render.html.ie55 || dojo.render.html.ie60) {
		var html=
				 "<iframe "
				+"style='position: absolute; left: 0px; top: 0px; width: 100%; height: 100%;"
				+        "z-index: -1; filter:Alpha(Opacity=\"0\");' "
				+">";
		this.iframe = document.createElement(html);
		if(node){
			node.appendChild(this.iframe);
			this.domNode=node;
		}else{
			document.body.appendChild(this.iframe);
			this.iframe.style.display="none";
		}
	}
}
dojo.lang.extend(dojo.html.BackgroundIframe, {
	iframe: null,

	// TODO: this function shouldn't be necessary but setting width=height=100% doesn't work!
	onResized: function(){
		if(this.iframe && this.domNode && this.domNode.parentElement){ // No parentElement if onResized() timeout event occurs on a removed domnode
			var w = dojo.style.getOuterWidth(this.domNode);
			var h = dojo.style.getOuterHeight(this.domNode);
			if (w  == 0 || h == 0 ){
				dojo.lang.setTimeout(this, this.onResized, 50);
				return;
			}
			var s = this.iframe.style;
			s.width = w + "px";
			s.height = h + "px";
		}
	},

	// Call this function if the iframe is connected to document.body rather
	// than the node being shadowed (TODO: erase)
	size: function(node) {
		if(!this.iframe) { return; }

		var coords = dojo.style.toCoordinateArray(node, true);

		var s = this.iframe.style;
		s.width = coords.w + "px";
		s.height = coords.h + "px";
		s.left = coords.x + "px";
		s.top = coords.y + "px";
	},

	setZIndex: function(node /* or number */) {
		if(!this.iframe) { return; }

		if(dojo.dom.isNode(node)) {
			this.iframe.style.zIndex = dojo.html.getStyle(node, "z-index") - 1;
		} else if(!isNaN(node)) {
			this.iframe.style.zIndex = node;
		}
	},

	show: function() {
		if(!this.iframe) { return; }
		this.iframe.style.display = "block";
	},

	hide: function() {
		if(!this.ie) { return; }
		var s = this.iframe.style;
		s.display = "none";
	},

	remove: function() {
		dojo.dom.removeNode(this.iframe);
	}
});

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.lfx.toggle");
dojo.require("dojo.lfx.*");

dojo.lfx.toggle.plain = {
	show: function(node, duration, easing, callback){
		dojo.style.show(node);
		if(dojo.lang.isFunction(callback)){ callback(); }
	},
	
	hide: function(node, duration, easing, callback){
		dojo.style.hide(node);
		if(dojo.lang.isFunction(callback)){ callback(); }
	}
}

dojo.lfx.toggle.fade = {
	show: function(node, duration, easing, callback){
		dojo.lfx.fadeShow(node, duration, easing, callback).play();
	},

	hide: function(node, duration, easing, callback){
		dojo.lfx.fadeHide(node, duration, easing, callback).play();
	}
}

dojo.lfx.toggle.wipe = {
	show: function(node, duration, easing, callback){
		dojo.lfx.wipeIn(node, duration, easing, callback).play();
	},

	hide: function(node, duration, easing, callback){
		dojo.lfx.wipeOut(node, duration, easing, callback).play();
	}
}

dojo.lfx.toggle.explode = {
	show: function(node, duration, easing, callback, explodeSrc){
		dojo.lfx.explode(explodeSrc||[0,0,0,0], node, duration, easing, callback).play();
	},

	hide: function(node, duration, easing, callback, explodeSrc){
		dojo.lfx.implode(node, explodeSrc||[0,0,0,0], duration, easing, callback).play();
	}
}

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.DomWidget");

dojo.require("dojo.event.*");
dojo.require("dojo.widget.Widget");
dojo.require("dojo.dom");
dojo.require("dojo.xml.Parse");
dojo.require("dojo.uri.*");
dojo.require("dojo.lang.func");
dojo.require("dojo.lang.extras");

dojo.widget._cssFiles = {};
dojo.widget._cssStrings = {};
dojo.widget._templateCache = {};

dojo.widget.defaultStrings = {
	dojoRoot: dojo.hostenv.getBaseScriptUri(),
	baseScriptUri: dojo.hostenv.getBaseScriptUri()
};

dojo.widget.buildFromTemplate = function() {
	dojo.lang.forward("fillFromTemplateCache");
}

// static method to build from a template w/ or w/o a real widget in place
dojo.widget.fillFromTemplateCache = function(obj, templatePath, templateCssPath, templateString, avoidCache){
	// dojo.debug("avoidCache:", avoidCache);
	var tpath = templatePath || obj.templatePath;
	var cpath = templateCssPath || obj.templateCssPath;

	// DEPRECATED: use Uri objects, not strings
	if (tpath && !(tpath instanceof dojo.uri.Uri)) {
		tpath = dojo.uri.dojoUri(tpath);
		dojo.deprecated("templatePath should be of type dojo.uri.Uri", null, "0.4");
	}
	if (cpath && !(cpath instanceof dojo.uri.Uri)) {
		cpath = dojo.uri.dojoUri(cpath);
		dojo.deprecated("templateCssPath should be of type dojo.uri.Uri", null, "0.4");
	}
	
	var tmplts = dojo.widget._templateCache;
	if(!obj["widgetType"]) { // don't have a real template here
		do {
			var dummyName = "__dummyTemplate__" + dojo.widget._templateCache.dummyCount++;
		} while(tmplts[dummyName]);
		obj.widgetType = dummyName;
	}
	var wt = obj.widgetType;

	if(cpath && !dojo.widget._cssFiles[cpath.toString()]){
		if((!obj.templateCssString)&&(cpath)){
			obj.templateCssString = dojo.hostenv.getText(cpath);
			obj.templateCssPath = null;
		}
		if((obj["templateCssString"])&&(!obj.templateCssString["loaded"])){
			dojo.style.insertCssText(obj.templateCssString, null, cpath);
			if(!obj.templateCssString){ obj.templateCssString = ""; }
			obj.templateCssString.loaded = true;
		}
		dojo.widget._cssFiles[cpath.toString()] = true;
	}

	var ts = tmplts[wt];
	if(!ts){
		tmplts[wt] = { "string": null, "node": null };
		if(avoidCache){
			ts = {};
		}else{
			ts = tmplts[wt];
		}
	}
	if((!obj.templateString)&&(!avoidCache)){
		obj.templateString = templateString || ts["string"];
	}
	if((!obj.templateNode)&&(!avoidCache)){
		obj.templateNode = ts["node"];
	}
	if((!obj.templateNode)&&(!obj.templateString)&&(tpath)){
		// fetch a text fragment and assign it to templateString
		// NOTE: we rely on blocking IO here!
		var tstring = dojo.hostenv.getText(tpath);
		if(tstring){
			// strip <?xml ...?> declarations so that external SVG and XML
			// documents can be added to a document without worry
			tstring = tstring.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
			var matches = tstring.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
			if(matches){
				tstring = matches[1];
			}
		}else{
			tstring = "";
		}
		obj.templateString = tstring;
		if(!avoidCache){
			tmplts[wt]["string"] = tstring;
		}
	}
	if((!ts["string"])&&(!avoidCache)){
		ts.string = obj.templateString;
	}
}
dojo.widget._templateCache.dummyCount = 0;

dojo.widget.attachProperties = ["dojoAttachPoint", "id"];
dojo.widget.eventAttachProperty = "dojoAttachEvent";
dojo.widget.onBuildProperty = "dojoOnBuild";
dojo.widget.waiNames  = ["waiRole", "waiState"];
dojo.widget.wai = {
	waiRole: { 	name: "waiRole", 
				namespace: "http://www.w3.org/TR/xhtml2", 
				alias: "x2",
				prefix: "wairole:",
				nsName: "role"
	},
	waiState: { name: "waiState", 
				namespace: "http://www.w3.org/2005/07/aaa" , 
				alias: "aaa",
				prefix: "",
				nsName: "state"
	},
	setAttr: function(node, attr, value){
		if(dojo.render.html.ie){
			node.setAttribute(this[attr].alias+":"+this[attr].nsName, this[attr].prefix+value);
		}else{
			node.setAttributeNS(this[attr].namespace, this[attr].nsName, this[attr].prefix+value);
		}
	}
};

dojo.widget.attachTemplateNodes = function(rootNode, targetObj, events){
	// FIXME: this method is still taking WAAAY too long. We need ways of optimizing:
	//	a.) what we are looking for on each node
	//	b.) the nodes that are subject to interrogation (use xpath instead?)
	//	c.) how expensive event assignment is (less eval(), more connect())
	// var start = new Date();
	var elementNodeType = dojo.dom.ELEMENT_NODE;

	function trim(str){
		return str.replace(/^\s+|\s+$/g, "");
	}

	if(!rootNode){ 
		rootNode = targetObj.domNode;
	}

	if(rootNode.nodeType != elementNodeType){
		return;
	}
	// alert(events.length);

	var nodes = rootNode.all || rootNode.getElementsByTagName("*");
	var _this = targetObj;
	for(var x=-1; x<nodes.length; x++){
		var baseNode = (x == -1) ? rootNode : nodes[x];
		// FIXME: is this going to have capitalization problems?  Could use getAttribute(name, 0); to get attributes case-insensitve
		var attachPoint = [];
		for(var y=0; y<this.attachProperties.length; y++){
			var tmpAttachPoint = baseNode.getAttribute(this.attachProperties[y]);
			if(tmpAttachPoint){
				attachPoint = tmpAttachPoint.split(";");
				for(var z=0; z<attachPoint.length; z++){
					if(dojo.lang.isArray(targetObj[attachPoint[z]])){
						targetObj[attachPoint[z]].push(baseNode);
					}else{
						targetObj[attachPoint[z]]=baseNode;
					}
				}
				break;
			}
		}
		// continue;

		// FIXME: we need to put this into some kind of lookup structure
		// instead of direct assignment
		var tmpltPoint = baseNode.getAttribute(this.templateProperty);
		if(tmpltPoint){
			targetObj[tmpltPoint]=baseNode;
		}

		dojo.lang.forEach(dojo.widget.waiNames, function(name){
			var wai = dojo.widget.wai[name];
			var val = baseNode.getAttribute(wai.name);
			if(val){
				dojo.widget.wai.setAttr(baseNode, wai.name, val);
			}
		}, this);

		var attachEvent = baseNode.getAttribute(this.eventAttachProperty);
		if(attachEvent){
			// NOTE: we want to support attributes that have the form
			// "domEvent: nativeEvent; ..."
			var evts = attachEvent.split(";");
			for(var y=0; y<evts.length; y++){
				if((!evts[y])||(!evts[y].length)){ continue; }
				var thisFunc = null;
				var tevt = trim(evts[y]);
				if(evts[y].indexOf(":") >= 0){
					// oh, if only JS had tuple assignment
					var funcNameArr = tevt.split(":");
					tevt = trim(funcNameArr[0]);
					thisFunc = trim(funcNameArr[1]);
				}
				if(!thisFunc){
					thisFunc = tevt;
				}

				var tf = function(){ 
					var ntf = new String(thisFunc);
					return function(evt){
						if(_this[ntf]){
							_this[ntf](dojo.event.browser.fixEvent(evt, this));
						}
					};
				}();
				dojo.event.browser.addListener(baseNode, tevt, tf, false, true);
				// dojo.event.browser.addListener(baseNode, tevt, dojo.lang.hitch(_this, thisFunc));
			}
		}

		for(var y=0; y<events.length; y++){
			//alert(events[x]);
			var evtVal = baseNode.getAttribute(events[y]);
			if((evtVal)&&(evtVal.length)){
				var thisFunc = null;
				var domEvt = events[y].substr(4); // clober the "dojo" prefix
				thisFunc = trim(evtVal);
				var funcs = [thisFunc];
				if(thisFunc.indexOf(";")>=0){
					funcs = dojo.lang.map(thisFunc.split(";"), trim);
				}
				for(var z=0; z<funcs.length; z++){
					if(!funcs[z].length){ continue; }
					var tf = function(){ 
						var ntf = new String(funcs[z]);
						return function(evt){
							if(_this[ntf]){
								_this[ntf](dojo.event.browser.fixEvent(evt, this));
							}
						}
					}();
					dojo.event.browser.addListener(baseNode, domEvt, tf, false, true);
					// dojo.event.browser.addListener(baseNode, domEvt, dojo.lang.hitch(_this, funcs[z]));
				}
			}
		}

		var onBuild = baseNode.getAttribute(this.onBuildProperty);
		if(onBuild){
			eval("var node = baseNode; var widget = targetObj; "+onBuild);
		}
	}

}

dojo.widget.getDojoEventsFromStr = function(str){
	// var lstr = str.toLowerCase();
	var re = /(dojoOn([a-z]+)(\s?))=/gi;
	var evts = str ? str.match(re)||[] : [];
	var ret = [];
	var lem = {};
	for(var x=0; x<evts.length; x++){
		if(evts[x].legth < 1){ continue; }
		var cm = evts[x].replace(/\s/, "");
		cm = (cm.slice(0, cm.length-1));
		if(!lem[cm]){
			lem[cm] = true;
			ret.push(cm);
		}
	}
	return ret;
}

/*
dojo.widget.buildAndAttachTemplate = function(obj, templatePath, templateCssPath, templateString, targetObj) {
	this.buildFromTemplate(obj, templatePath, templateCssPath, templateString);
	var node = dojo.dom.createNodesFromText(obj.templateString, true)[0];
	this.attachTemplateNodes(node, targetObj||obj, dojo.widget.getDojoEventsFromStr(templateString));
	return node;
}
*/

dojo.declare("dojo.widget.DomWidget", dojo.widget.Widget, {
	initializer: function() {
		if((arguments.length>0)&&(typeof arguments[0] == "object")){
			this.create(arguments[0]);
		}
	},
								 
	templateNode: null,
	templateString: null,
	templateCssString: null,
	preventClobber: false,
	domNode: null, // this is our visible representation of the widget!
	containerNode: null, // holds child elements

	// Process the given child widget, inserting it's dom node as a child of our dom node
	// FIXME: should we support addition at an index in the children arr and
	// order the display accordingly? Right now we always append.
	addChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
		if(!this.isContainer){ // we aren't allowed to contain other widgets, it seems
			dojo.debug("dojo.widget.DomWidget.addChild() attempted on non-container widget");
			return null;
		}else{
			this.addWidgetAsDirectChild(widget, overrideContainerNode, pos, ref, insertIndex);
			this.registerChild(widget, insertIndex);
		}
		return widget;
	},
	
	addWidgetAsDirectChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
		if((!this.containerNode)&&(!overrideContainerNode)){
			this.containerNode = this.domNode;
		}
		var cn = (overrideContainerNode) ? overrideContainerNode : this.containerNode;
		if(!pos){ pos = "after"; }
		if(!ref){ 
			// if(!cn){ cn = document.body; }
			if(!cn){ cn = document.body; }
			ref = cn.lastChild; 
		}
		if(!insertIndex) { insertIndex = 0; }
		widget.domNode.setAttribute("dojoinsertionindex", insertIndex);

		// insert the child widget domNode directly underneath my domNode, in the
		// specified position (by default, append to end)
		if(!ref){
			cn.appendChild(widget.domNode);
		}else{
			// FIXME: was this meant to be the (ugly hack) way to support insert @ index?
			//dojo.dom[pos](widget.domNode, ref, insertIndex);

			// CAL: this appears to be the intended way to insert a node at a given position...
			if (pos == 'insertAtIndex'){
				// dojo.debug("idx:", insertIndex, "isLast:", ref === cn.lastChild);
				dojo.dom.insertAtIndex(widget.domNode, ref.parentNode, insertIndex);
			}else{
				// dojo.debug("pos:", pos, "isLast:", ref === cn.lastChild);
				if((pos == "after")&&(ref === cn.lastChild)){
					cn.appendChild(widget.domNode);
				}else{
					dojo.dom.insertAtPosition(widget.domNode, cn, pos);
				}
			}
		}
	},

	// Record that given widget descends from me
	registerChild: function(widget, insertionIndex){

		// we need to insert the child at the right point in the parent's 
		// 'children' array, based on the insertionIndex

		widget.dojoInsertionIndex = insertionIndex;

		var idx = -1;
		for(var i=0; i<this.children.length; i++){
			if (this.children[i].dojoInsertionIndex < insertionIndex){
				idx = i;
			}
		}

		this.children.splice(idx+1, 0, widget);

		widget.parent = this;
		widget.addedTo(this);
		
		// If this widget was created programatically, then it was erroneously added
		// to dojo.widget.manager.topWidgets.  Fix that here.
		delete dojo.widget.manager.topWidgets[widget.widgetId];
	},

	removeChild: function(widget){
		// detach child domNode from parent domNode
		dojo.dom.removeNode(widget.domNode);

		// remove child widget from parent widget
		return dojo.widget.DomWidget.superclass.removeChild.call(this, widget);
	},

	getFragNodeRef: function(frag){
		if( !frag || !frag["dojo:"+this.widgetType.toLowerCase()] ){
			dojo.raise("Error: no frag for widget type " + this.widgetType +
				", id " + this.widgetId + " (maybe a widget has set it's type incorrectly)");
		}
		return (frag ? frag["dojo:"+this.widgetType.toLowerCase()]["nodeRef"] : null);
	},
	
	// Replace source domNode with generated dom structure, and register
	// widget with parent.
	postInitialize: function(args, frag, parentComp){
		var sourceNodeRef = this.getFragNodeRef(frag);
		// Stick my generated dom into the output tree
		//alert(this.widgetId + ": replacing " + sourceNodeRef + " with " + this.domNode.innerHTML);
		if (parentComp && (parentComp.snarfChildDomOutput || !sourceNodeRef)){
			// Add my generated dom as a direct child of my parent widget
			// This is important for generated widgets, and also cases where I am generating an
			// <li> node that can't be inserted back into the original DOM tree
			parentComp.addWidgetAsDirectChild(this, "", "insertAtIndex", "",  args["dojoinsertionindex"], sourceNodeRef);
		} else if (sourceNodeRef){
			// Do in-place replacement of the my source node with my generated dom
			if(this.domNode && (this.domNode !== sourceNodeRef)){
				var oldNode = sourceNodeRef.parentNode.replaceChild(this.domNode, sourceNodeRef);
			}
		}

		// Register myself with my parent, or with the widget manager if
		// I have no parent
		// TODO: the code below erroneously adds all programatically generated widgets
		// to topWidgets (since we don't know who the parent is until after creation finishes)
		if ( parentComp ) {
			parentComp.registerChild(this, args.dojoinsertionindex);
		} else {
			dojo.widget.manager.topWidgets[this.widgetId]=this;
		}

		// Expand my children widgets
		if(this.isContainer){
			//alert("recurse from " + this.widgetId);
			// build any sub-components with us as the parent
			var fragParser = dojo.widget.getParser();
			fragParser.createSubComponents(frag, this);
		}
	},

	// method over-ride
	buildRendering: function(args, frag){
		// DOM widgets construct themselves from a template
		var ts = dojo.widget._templateCache[this.widgetType];
		if(	
			(!this.preventClobber)&&(
				(this.templatePath)||
				(this.templateNode)||
				(
					(this["templateString"])&&(this.templateString.length) 
				)||
				(
					(typeof ts != "undefined")&&( (ts["string"])||(ts["node"]) )
				)
			)
		){
			// if it looks like we can build the thing from a template, do it!
			this.buildFromTemplate(args, frag);
		}else{
			// otherwise, assign the DOM node that was the source of the widget
			// parsing to be the root node
			this.domNode = this.getFragNodeRef(frag);
		}
		this.fillInTemplate(args, frag); 	// this is where individual widgets
											// will handle population of data
											// from properties, remote data
											// sets, etc.
	},

	buildFromTemplate: function(args, frag){
		// var start = new Date();
		// copy template properties if they're already set in the templates object
		// dojo.debug("buildFromTemplate:", this);
		var avoidCache = false;
		if(args["templatecsspath"]){
			args["templateCssPath"] = args["templatecsspath"];
		}
		if(args["templatepath"]){
			avoidCache = true;
			args["templatePath"] = args["templatepath"];
		}
		dojo.widget.fillFromTemplateCache(	this, 
											args["templatePath"], 
											args["templateCssPath"],
											null,
											avoidCache);
		var ts = dojo.widget._templateCache[this.widgetType];
		if((ts)&&(!avoidCache)){
			if(!this.templateString.length){
				this.templateString = ts["string"];
			}
			if(!this.templateNode){
				this.templateNode = ts["node"];
			}
		}
		var matches = false;
		var node = null;
		// var tstr = new String(this.templateString); 
		var tstr = this.templateString; 
		// attempt to clone a template node, if there is one
		if((!this.templateNode)&&(this.templateString)){
			matches = this.templateString.match(/\$\{([^\}]+)\}/g);
			if(matches) {
				// if we do property replacement, don't create a templateNode
				// to clone from.
				var hash = this.strings || {};
				// FIXME: should this hash of default replacements be cached in
				// templateString?
				for(var key in dojo.widget.defaultStrings) {
					if(dojo.lang.isUndefined(hash[key])) {
						hash[key] = dojo.widget.defaultStrings[key];
					}
				}
				// FIXME: this is a lot of string munging. Can we make it faster?
				for(var i = 0; i < matches.length; i++) {
					var key = matches[i];
					key = key.substring(2, key.length-1);
					var kval = (key.substring(0, 5) == "this.") ? dojo.lang.getObjPathValue(key.substring(5), this) : hash[key];
					var value;
					if((kval)||(dojo.lang.isString(kval))){
						value = (dojo.lang.isFunction(kval)) ? kval.call(this, key, this.templateString) : kval;
						tstr = tstr.replace(matches[i], value);
					}
				}
			}else{
				// otherwise, we are required to instantiate a copy of the template
				// string if one is provided.
				
				// FIXME: need to be able to distinguish here what should be done
				// or provide a generic interface across all DOM implementations
				// FIMXE: this breaks if the template has whitespace as its first 
				// characters
				// node = this.createNodesFromText(this.templateString, true);
				// this.templateNode = node[0].cloneNode(true); // we're optimistic here
				this.templateNode = this.createNodesFromText(this.templateString, true)[0];
				if(!avoidCache){
					ts.node = this.templateNode;
				}
			}
		}
		if((!this.templateNode)&&(!matches)){ 
			dojo.debug("weren't able to create template!");
			return false;
		}else if(!matches){
			node = this.templateNode.cloneNode(true);
			if(!node){ return false; }
		}else{
			node = this.createNodesFromText(tstr, true)[0];
		}

		// recurse through the node, looking for, and attaching to, our
		// attachment points which should be defined on the template node.

		this.domNode = node;
		// dojo.profile.start("attachTemplateNodes");
		this.attachTemplateNodes(this.domNode, this);
		// dojo.profile.end("attachTemplateNodes");
		
		// relocate source contents to templated container node
		// this.containerNode must be able to receive children, or exceptions will be thrown
		if (this.isContainer && this.containerNode){
			var src = this.getFragNodeRef(frag);
			if (src){
				dojo.dom.moveChildren(src, this.containerNode);
			}
		}
	},

	attachTemplateNodes: function(baseNode, targetObj){
		if(!targetObj){ targetObj = this; }
		return dojo.widget.attachTemplateNodes(baseNode, targetObj, 
					dojo.widget.getDojoEventsFromStr(this.templateString));
	},

	fillInTemplate: function(){
		// dojo.unimplemented("dojo.widget.DomWidget.fillInTemplate");
	},
	
	// method over-ride
	destroyRendering: function(){
		try{
			delete this.domNode;
		}catch(e){ /* squelch! */ }
	},

	// FIXME: method over-ride
	cleanUp: function(){},
	
	getContainerHeight: function(){
		dojo.unimplemented("dojo.widget.DomWidget.getContainerHeight");
	},

	getContainerWidth: function(){
		dojo.unimplemented("dojo.widget.DomWidget.getContainerWidth");
	},

	createNodesFromText: function(){
		dojo.unimplemented("dojo.widget.DomWidget.createNodesFromText");
	}
});

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.HtmlWidget");
dojo.require("dojo.widget.DomWidget");
dojo.require("dojo.html");
dojo.require("dojo.html.extras");
dojo.require("dojo.lang.extras");
dojo.require("dojo.lang.func");
dojo.require("dojo.lfx.toggle");

dojo.declare("dojo.widget.HtmlWidget", dojo.widget.DomWidget, {								 
	widgetType: "HtmlWidget",

	templateCssPath: null,
	templatePath: null,

	// for displaying/hiding widget
	toggle: "plain",
	toggleDuration: 150,

	animationInProgress: false,

	initialize: function(args, frag){
	},

	postMixInProperties: function(args, frag){
		// now that we know the setting for toggle, get toggle object
		// (default to plain toggler if user specified toggler not present)
		this.toggleObj =
			dojo.lfx.toggle[this.toggle.toLowerCase()] || dojo.lfx.toggle.plain;
	},

	getContainerHeight: function(){
		// NOTE: container height must be returned as the INNER height
		dojo.unimplemented("dojo.widget.HtmlWidget.getContainerHeight");
	},

	getContainerWidth: function(){
		return this.parent.domNode.offsetWidth;
	},

	setNativeHeight: function(height){
		var ch = this.getContainerHeight();
	},

	createNodesFromText: function(txt, wrap){
		return dojo.html.createNodesFromText(txt, wrap);
	},

	destroyRendering: function(finalize){
		try{
			if(!finalize){
				dojo.event.browser.clean(this.domNode);
			}
			this.domNode.parentNode.removeChild(this.domNode);
			delete this.domNode;
		}catch(e){ /* squelch! */ }
	},

	/////////////////////////////////////////////////////////
	// Displaying/hiding the widget
	/////////////////////////////////////////////////////////
	isShowing: function(){
		return dojo.style.isShowing(this.domNode);
	},

	toggleShowing: function(){
		// dojo.style.toggleShowing(this.domNode);
		if(this.isHidden){
			this.show();
		}else{
			this.hide();
		}
	},

	show: function(){
		this.animationInProgress=true;
		this.isHidden = false;
		this.toggleObj.show(this.domNode, this.toggleDuration, null,
			dojo.lang.hitch(this, this.onShow), this.explodeSrc);
	},

	// called after the show() animation has completed
	onShow: function(){
		this.animationInProgress=false;
		this.checkSize();
	},

	hide: function(){
		this.animationInProgress = true;
		this.isHidden = true;
		this.toggleObj.hide(this.domNode, this.toggleDuration, null,
			dojo.lang.hitch(this, this.onHide), this.explodeSrc);
	},

	// called after the hide() animation has completed
	onHide: function(){
		this.animationInProgress=false;
	},

	//////////////////////////////////////////////////////////////////////////////
	// Sizing related methods
	//  If the parent changes size then for each child it should call either
	//   - resizeTo(): size the child explicitly
	//   - or checkSize(): notify the child the the parent has changed size
	//////////////////////////////////////////////////////////////////////////////

	// Test if my size has changed.
	// If width & height are specified then that's my new size; otherwise,
	// query outerWidth/outerHeight of my domNode
	_isResized: function(w, h){
		// If I'm not being displayed then disregard (show() must
		// check if the size has changed)
		if(!this.isShowing()){ return false; }

		// If my parent has been resized and I have style="height: 100%"
		// or something similar then my size has changed too.
		w=w||dojo.style.getOuterWidth(this.domNode);
		h=h||dojo.style.getOuterHeight(this.domNode);
		if(this.width == w && this.height == h){ return false; }

		this.width=w;
		this.height=h;
		return true;
	},

	// Called when my parent has changed size, but my parent won't call resizeTo().
	// This is useful if my size is height:100% or something similar.
	// Also called whenever I am shown, because the first time I am shown I may need
	// to do size calculations.
	checkSize: function(){
		if(!this._isResized()){ return; }
		this.onResized();
	},

	// Explicitly set this widget's size (in pixels).
	resizeTo: function(w, h){
		if(!this._isResized(w,h)){ return; }
		dojo.style.setOuterWidth(this.domNode, w);
		dojo.style.setOuterHeight(this.domNode, h);
		this.onResized();
	},

	resizeSoon: function(){
		if(this.isShowing()){
			dojo.lang.setTimeout(this, this.onResized, 0);
		}
	},

	// Called when my size has changed.
	// Must notify children if their size has (possibly) changed
	onResized: function(){
		dojo.lang.forEach(this.children, function(child){ child.checkSize(); });
	}
});

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.kwCompoundRequire({
	common: ["dojo.xml.Parse", 
			 "dojo.widget.Widget", 
			 "dojo.widget.Parse", 
			 "dojo.widget.Manager"],
	browser: ["dojo.widget.DomWidget",
			  "dojo.widget.HtmlWidget"],
	dashboard: ["dojo.widget.DomWidget",
			  "dojo.widget.HtmlWidget"],
	svg: 	 ["dojo.widget.SvgWidget"],
	rhino: 	 ["dojo.widget.SwtWidget"]
});
dojo.provide("dojo.widget.*");

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

// This widget doesn't do anything; is basically the same as <div>.
// It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.
// But note that those classes can contain any widget as a child.

dojo.provide("dojo.widget.ContentPane");
dojo.requireAfterIf("html", "dojo.widget.html.ContentPane");

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.Tooltip");
dojo.require("dojo.widget.Widget");

dojo.requireAfterIf("html", "dojo.widget.html.Tooltip");

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.Widget");
dojo.provide("dojo.widget.tags");

dojo.require("dojo.lang.func");
dojo.require("dojo.lang.array");
dojo.require("dojo.lang.extras");
dojo.require("dojo.lang.declare");
dojo.require("dojo.widget.Manager");
dojo.require("dojo.event.*");

dojo.declare("dojo.widget.Widget", null, {
	initializer: function() {								 
		// these properties aren't primitives and need to be created on a per-item
		// basis.
		this.children = [];
		// this.selection = new dojo.widget.Selection();
		// FIXME: need to replace this with context menu stuff
		this.extraArgs = {};
	},
	// FIXME: need to be able to disambiguate what our rendering context is
	//        here!
	//
	// needs to be a string with the end classname. Every subclass MUST
	// over-ride.
	//
	// base widget properties
	parent: null,
	// obviously, top-level and modal widgets should set these appropriately
	isTopLevel:  false,
	isModal: false,

	isEnabled: true,
	isHidden: false,
	isContainer: false, // can we contain other widgets?
	widgetId: "",
	widgetType: "Widget", // used for building generic widgets

	toString: function() {
		return '[Widget ' + this.widgetType + ', ' + (this.widgetId || 'NO ID') + ']';
	},

	repr: function(){
		return this.toString();
	},

	enable: function(){
		// should be over-ridden
		this.isEnabled = true;
	},

	disable: function(){
		// should be over-ridden
		this.isEnabled = false;
	},

	hide: function(){
		// should be over-ridden
		this.isHidden = true;
	},

	show: function(){
		// should be over-ridden
		this.isHidden = false;
	},

	onResized: function(){
		// Clients should override this function to do special processing,
		// then call this.notifyChildrenOfResize() to notify children of resize
		this.notifyChildrenOfResize();
	},
	
	notifyChildrenOfResize: function(){
		for(var i=0; i<this.children.length; i++){
			var child = this.children[i];
			//dojo.debug(this.widgetId + " resizing child " + child.widgetId);
			if( child.onResized ){
				child.onResized();
			}
		}
	},

	create: function(args, fragment, parentComp){
		// dojo.debug(this.widgetType, "create");
		this.satisfyPropertySets(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> mixInProperties");
		this.mixInProperties(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> postMixInProperties");
		this.postMixInProperties(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> dojo.widget.manager.add");
		dojo.widget.manager.add(this);
		// dojo.debug(this.widgetType, "-> buildRendering");
		this.buildRendering(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> initialize");
		this.initialize(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> postInitialize");
		this.postInitialize(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "-> postCreate");
		this.postCreate(args, fragment, parentComp);
		// dojo.debug(this.widgetType, "done!");
		return this;
	},

	// Destroy this widget and it's descendants
	destroy: function(finalize){
		// FIXME: this is woefully incomplete
		this.destroyChildren();
		this.uninitialize();
		this.destroyRendering(finalize);
		dojo.widget.manager.removeById(this.widgetId);
	},

	// Destroy the children of this widget, and their descendents
	destroyChildren: function(){
		while(this.children.length > 0){
			var tc = this.children[0];
			this.removeChild(tc);
			tc.destroy();
		}
	},

	getChildrenOfType: function(type, recurse){
		var ret = [];
		var isFunc = dojo.lang.isFunction(type);
		if(!isFunc){
			type = type.toLowerCase();
		}
		for(var x=0; x<this.children.length; x++){
			if(isFunc){
				if(this.children[x] instanceof type){
					ret.push(this.children[x]);
				}
			}else{
				if(this.children[x].widgetType.toLowerCase() == type){
					ret.push(this.children[x]);
				}
			}
			if(recurse){
				ret = ret.concat(this.children[x].getChildrenOfType(type, recurse));
			}
		}
		return ret;
	},

	getDescendants: function(){
		var result = [];
		var stack = [this];
		var elem;
		while (elem = stack.pop()){
			result.push(elem);
			dojo.lang.forEach(elem.children, function(elem) { stack.push(elem); });
		}
		return result;
	},

	satisfyPropertySets: function(args){
		// dojo.profile.start("satisfyPropertySets");
		// get the default propsets for our component type
		/*
		var typePropSets = []; // FIXME: need to pull these from somewhere!
		var localPropSets = []; // pull out propsets from the parser's return structure

		// for(var x=0; x<args.length; x++){
		// }

		for(var x=0; x<typePropSets.length; x++){
		}

		for(var x=0; x<localPropSets.length; x++){
		}
		*/
		// dojo.profile.end("satisfyPropertySets");
		
		return args;
	},

	mixInProperties: function(args, frag){
		if((args["fastMixIn"])||(frag["fastMixIn"])){
			// dojo.profile.start("mixInProperties_fastMixIn");
			// fast mix in assumes case sensitivity, no type casting, etc...
			// dojo.lang.mixin(this, args);
			for(var x in args){
				this[x] = args[x];
			}
			// dojo.profile.end("mixInProperties_fastMixIn");
			return;
		}
		// dojo.profile.start("mixInProperties");
		/*
		 * the actual mix-in code attempts to do some type-assignment based on
		 * PRE-EXISTING properties of the "this" object. When a named property
		 * of a propset is located, it is first tested to make sure that the
		 * current object already "has one". Properties which are undefined in
		 * the base widget are NOT settable here. The next step is to try to
		 * determine type of the pre-existing property. If it's a string, the
		 * property value is simply assigned. If a function, the property is
		 * replaced with a "new Function()" declaration. If an Array, the
		 * system attempts to split the string value on ";" chars, and no
		 * further processing is attempted (conversion of array elements to a
		 * integers, for instance). If the property value is an Object
		 * (testObj.constructor === Object), the property is split first on ";"
		 * chars, secondly on ":" chars, and the resulting key/value pairs are
		 * assigned to an object in a map style. The onus is on the property
		 * user to ensure that all property values are converted to the
		 * expected type before usage.
		 */

		var undef;

		// NOTE: we cannot assume that the passed properties are case-correct
		// (esp due to some browser bugs). Therefore, we attempt to locate
		// properties for assignment regardless of case. This may cause
		// problematic assignments and bugs in the future and will need to be
		// documented with big bright neon lights.

		// FIXME: fails miserably if a mixin property has a default value of null in 
		// a widget

		// NOTE: caching lower-cased args in the prototype is only 
		// acceptable if the properties are invariant.
		// if we have a name-cache, get it
		var lcArgs = dojo.widget.lcArgsCache[this.widgetType];
		if ( lcArgs == null ){
			// build a lower-case property name cache if we don't have one
			lcArgs = {};
			for(var y in this){
				lcArgs[((new String(y)).toLowerCase())] = y;
			}
			dojo.widget.lcArgsCache[this.widgetType] = lcArgs;
		}
		var visited = {};
		for(var x in args){
			if(!this[x]){ // check the cache for properties
				var y = lcArgs[(new String(x)).toLowerCase()];
				if(y){
					args[y] = args[x];
					x = y; 
				}
			}
			if(visited[x]){ continue; }
			visited[x] = true;
			if((typeof this[x]) != (typeof undef)){
				if(typeof args[x] != "string"){
					this[x] = args[x];
				}else{
					if(dojo.lang.isString(this[x])){
						this[x] = args[x];
					}else if(dojo.lang.isNumber(this[x])){
						this[x] = new Number(args[x]); // FIXME: what if NaN is the result?
					}else if(dojo.lang.isBoolean(this[x])){
						this[x] = (args[x].toLowerCase()=="false") ? false : true;
					}else if(dojo.lang.isFunction(this[x])){

						// FIXME: need to determine if always over-writing instead
						// of attaching here is appropriate. I suspect that we
						// might want to only allow attaching w/ action items.
						
						// RAR, 1/19/05: I'm going to attach instead of
						// over-write here. Perhaps function objects could have
						// some sort of flag set on them? Or mixed-into objects
						// could have some list of non-mutable properties
						// (although I'm not sure how that would alleviate this
						// particular problem)? 

						// this[x] = new Function(args[x]);

						// after an IRC discussion last week, it was decided
						// that these event handlers should execute in the
						// context of the widget, so that the "this" pointer
						// takes correctly.
						
						// argument that contains no punctuation other than . is 
						// considered a function spec, not code
						if(args[x].search(/[^\w\.]+/i) == -1){
							this[x] = dojo.evalObjPath(args[x], false);
						}else{
							var tn = dojo.lang.nameAnonFunc(new Function(args[x]), this);
							dojo.event.connect(this, x, this, tn);
						}
					}else if(dojo.lang.isArray(this[x])){ // typeof [] == "object"
						this[x] = args[x].split(";");
					} else if (this[x] instanceof Date) {
						this[x] = new Date(Number(args[x])); // assume timestamp
					}else if(typeof this[x] == "object"){ 
						// FIXME: should we be allowing extension here to handle
						// other object types intelligently?

						// if we defined a URI, we probablt want to allow plain strings
						// to override it
						if (this[x] instanceof dojo.uri.Uri){

							this[x] = args[x];
						}else{

							// FIXME: unlike all other types, we do not replace the
							// object with a new one here. Should we change that?
							var pairs = args[x].split(";");
							for(var y=0; y<pairs.length; y++){
								var si = pairs[y].indexOf(":");
								if((si != -1)&&(pairs[y].length>si)){
									this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1);
								}
							}
						}
					}else{
						// the default is straight-up string assignment. When would
						// we ever hit this?
						this[x] = args[x];
					}
				}
			}else{
				// collect any extra 'non mixed in' args
				this.extraArgs[x.toLowerCase()] = args[x];
			}
		}
		// dojo.profile.end("mixInProperties");
	},
	
	postMixInProperties: function(){
	},

	initialize: function(args, frag){
		// dojo.unimplemented("dojo.widget.Widget.initialize");
		return false;
	},

	postInitialize: function(args, frag){
		return false;
	},

	postCreate: function(args, frag){
		return false;
	},

	uninitialize: function(){
		// dojo.unimplemented("dojo.widget.Widget.uninitialize");
		return false;
	},

	buildRendering: function(){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.buildRendering, on "+this.toString()+", ");
		return false;
	},

	destroyRendering: function(){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.destroyRendering");
		return false;
	},

	cleanUp: function(){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.cleanUp");
		return false;
	},

	addedTo: function(parent){
		// this is just a signal that can be caught
	},

	addChild: function(child){
		// SUBCLASSES MUST IMPLEMENT
		dojo.unimplemented("dojo.widget.Widget.addChild");
		return false;
	},

	// Detach the given child widget from me, but don't destroy it
	removeChild: function(widget){
		for(var x=0; x<this.children.length; x++){
			if(this.children[x] === widget){
				this.children.splice(x, 1);
				break;
			}
		}
		return widget;
	},

	resize: function(width, height){
		// both width and height may be set as percentages. The setWidth and
		// setHeight  functions attempt to determine if the passed param is
		// specified in percentage or native units. Integers without a
		// measurement are assumed to be in the native unit of measure.
		this.setWidth(width);
		this.setHeight(height);
	},

	setWidth: function(width){
		if((typeof width == "string")&&(width.substr(-1) == "%")){
			this.setPercentageWidth(width);
		}else{
			this.setNativeWidth(width);
		}
	},

	setHeight: function(height){
		if((typeof height == "string")&&(height.substr(-1) == "%")){
			this.setPercentageHeight(height);
		}else{
			this.setNativeHeight(height);
		}
	},

	setPercentageHeight: function(height){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	setNativeHeight: function(height){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	setPercentageWidth: function(width){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	setNativeWidth: function(width){
		// SUBCLASSES MUST IMPLEMENT
		return false;
	},

	getPreviousSibling: function() {
		var idx = this.getParentIndex();
 
		 // first node is idx=0 not found is idx<0
		if (idx<=0) return null;
 
		return this.getSiblings()[idx-1];
	},
 
	getSiblings: function() {
		return this.parent.children;
	},
 
	getParentIndex: function() {
		return dojo.lang.indexOf( this.getSiblings(), this, true);
	},
 
	getNextSibling: function() {
 
		var idx = this.getParentIndex();
 
		if (idx == this.getSiblings().length-1) return null; // last node
		if (idx < 0) return null; // not found
 
		return this.getSiblings()[idx+1];
 
	}
});

// Lower case name cache: listing of the lower case elements in each widget.
// We can't store the lcArgs in the widget itself because if B subclasses A,
// then B.prototype.lcArgs might return A.prototype.lcArgs, which is not what we
// want
dojo.widget.lcArgsCache = {};

// TODO: should have a more general way to add tags or tag libraries?
// TODO: need a default tags class to inherit from for things like getting propertySets
// TODO: parse properties/propertySets into component attributes
// TODO: parse subcomponents
// TODO: copy/clone raw markup fragments/nodes as appropriate
dojo.widget.tags = {};
dojo.widget.tags.addParseTreeHandler = function(type){
	var ltype = type.toLowerCase();
	this[ltype] = function(fragment, widgetParser, parentComp, insertionIndex, localProps){ 
		return dojo.widget.buildWidgetFromParseTree(ltype, fragment, widgetParser, parentComp, insertionIndex, localProps);
	}
}
dojo.widget.tags.addParseTreeHandler("dojo:widget");

dojo.widget.tags["dojo:propertyset"] = function(fragment, widgetParser, parentComp){
	// FIXME: Is this needed?
	// FIXME: Not sure that this parses into the structure that I want it to parse into...
	// FIXME: add support for nested propertySets
	var properties = widgetParser.parseProperties(fragment["dojo:propertyset"]);
}

// FIXME: need to add the <dojo:connect />
dojo.widget.tags["dojo:connect"] = function(fragment, widgetParser, parentComp){
	var properties = widgetParser.parseProperties(fragment["dojo:connect"]);
}

// FIXME: if we know the insertion point (to a reasonable location), why then do we:
//	- create a template node
//	- clone the template node
//	- render the clone and set properties
//	- remove the clone from the render tree
//	- place the clone
// this is quite dumb
dojo.widget.buildWidgetFromParseTree = function(type, frag, 
												parser, parentComp, 
												insertionIndex, localProps){
	var stype = type.split(":");
	stype = (stype.length == 2) ? stype[1] : type;
	// FIXME: we don't seem to be doing anything with this!
	// var propertySets = parser.getPropertySets(frag);
	var localProperties = localProps || parser.parseProperties(frag["dojo:"+stype]);
	// var tic = new Date();
	var twidget = dojo.widget.manager.getImplementation(stype);
	if(!twidget){
		throw new Error("cannot find \"" + stype + "\" widget");
	}else if (!twidget.create){
		throw new Error("\"" + stype + "\" widget object does not appear to implement *Widget");
	}
	localProperties["dojoinsertionindex"] = insertionIndex;
	// FIXME: we loose no less than 5ms in construction!
	var ret = twidget.create(localProperties, frag, parentComp);
	// dojo.debug(new Date() - tic);
	return ret;
}

/*
 * Create a widget constructor function (aka widgetClass)
 */
dojo.widget.defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
	// This meta-function does parameter juggling for backward compat and overloading
	// if 4th argument is a string, we are using the old syntax
	// old sig: widgetClass, superclasses, props (object), renderer (string), init (function)
	if(dojo.lang.isString(arguments[3])){
		dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]);
	}else{
		// widgetClass
		var args = [ arguments[0] ], p = 3;
		if(dojo.lang.isString(arguments[1])){
			// renderer, superclass
			args.push(arguments[1], arguments[2]);
		}else{
			// superclass
			args.push('', arguments[1]);
			p = 2;
		}
		if(dojo.lang.isFunction(arguments[p])){
			// init (function), props (object) 
			args.push(arguments[p], arguments[p+1]);
		}else{
			// props (object) 
			args.push(null, arguments[p]);
		}
		dojo.widget._defineWidget.apply(this, args);
	}
}

dojo.widget.defineWidget.renderers = "html|svg|vml";

dojo.widget._defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){
	// FIXME: uncomment next line to test parameter juggling ... remove when confidence improves
	//dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props);
	// widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName)
	var namespace = widgetClass.split(".");
	var type = namespace.pop(); // type <= WidgetName, namespace <= foo.bar.baz<.renderer>
	var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\.";
	var r = widgetClass.search(new RegExp(regx));
	namespace = (r < 0 ? namespace.join(".") : widgetClass.substr(0, r));

	dojo.widget.manager.registerWidgetPackage(namespace);
	dojo.widget.tags.addParseTreeHandler("dojo:"+type.toLowerCase());

	props=(props)||{};
	props.widgetType = type;
	if((!init)&&(props["classConstructor"])){
		init = props.classConstructor;
		delete props.classConstructor;
	}
	dojo.declare(widgetClass, superclasses, init, props);
}
/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.crypto");

//	enumerations for use in crypto code. Note that 0 == default, for the most part.
dojo.crypto.cipherModes={ ECB:0, CBC:1, PCBC:2, CFB:3, OFB:4, CTR:5 };
dojo.crypto.outputTypes={ Base64:0,Hex:1,String:2,Raw:3 };

dojo.require("dojo.crypto");
dojo.provide("dojo.crypto.MD5");

/*	Return to a port of Paul Johnstone's MD5 implementation
 *	http://pajhome.org.uk/crypt/md5/index.html
 *
 *	Copyright (C) Paul Johnston 1999 - 2002.
 *	Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * 	Distributed under the BSD License
 *
 *	Dojo port by Tom Trenka
 *
 *	2005-12-7
 *	All conversions are internalized (no dependencies)
 *	implemented getHMAC for message digest auth.
 */
dojo.crypto.MD5 = new function(){
	var chrsz=8;
	var mask=(1<<chrsz)-1;
	function toWord(s) {
	  var wa=[];
	  for(var i=0; i<s.length*chrsz; i+=chrsz)
		wa[i>>5]|=(s.charCodeAt(i/chrsz)&mask)<<(i%32);
	  return wa;
	}
	function toString(wa){
		var s=[];
		for(var i=0; i<wa.length*32; i+=chrsz)
			s.push(String.fromCharCode((wa[i>>5]>>>(i%32))&mask));
		return s.join("");
	}
	function toHex(wa) {
		var h="0123456789abcdef";
		var s=[];
		for(var i=0; i<wa.length*4; i++){
			s.push(h.charAt((wa[i>>2]>>((i%4)*8+4))&0xF)+h.charAt((wa[i>>2]>>((i%4)*8))&0xF));
		}
		return s.join("");
	}
	function toBase64(wa){
		var p="=";
		var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
		var s=[];
		for(var i=0; i<wa.length*4; i+=3){
			var t=(((wa[i>>2]>>8*(i%4))&0xFF)<<16)|(((wa[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((wa[i+2>>2]>>8*((i+2)%4))&0xFF);
			for(var j=0; j<4; j++){
				if(i*8+j*6>wa.length*32) s.push(p);
				else s.push(tab.charAt((t>>6*(3-j))&0x3F));
			}
		}
		return s.join("");
	}
	function add(x,y) {
		var l=(x&0xFFFF)+(y&0xFFFF);
		var m=(x>>16)+(y>>16)+(l>>16);
		return (m<<16)|(l&0xFFFF);
	}
	function R(n,c){ return (n<<c)|(n>>>(32-c)); }
	function C(q,a,b,x,s,t){ return add(R(add(add(a,q),add(x,t)),s),b); }
	function FF(a,b,c,d,x,s,t){ return C((b&c)|((~b)&d),a,b,x,s,t); }
	function GG(a,b,c,d,x,s,t){ return C((b&d)|(c&(~d)),a,b,x,s,t); }
	function HH(a,b,c,d,x,s,t){ return C(b^c^d,a,b,x,s,t); }
	function II(a,b,c,d,x,s,t){ return C(c^(b|(~d)),a,b,x,s,t); }
	function core(x,len){
		x[len>>5]|=0x80<<((len)%32);
		x[(((len+64)>>>9)<<4)+14]=len;
		var a= 1732584193;
		var b=-271733879;
		var c=-1732584194;
		var d= 271733878;
		for(var i=0; i<x.length; i+=16){
			var olda=a;
			var oldb=b;
			var oldc=c;
			var oldd=d;

			a=FF(a,b,c,d,x[i+ 0],7 ,-680876936);
			d=FF(d,a,b,c,x[i+ 1],12,-389564586);
			c=FF(c,d,a,b,x[i+ 2],17, 606105819);
			b=FF(b,c,d,a,x[i+ 3],22,-1044525330);
			a=FF(a,b,c,d,x[i+ 4],7 ,-176418897);
			d=FF(d,a,b,c,x[i+ 5],12, 1200080426);
			c=FF(c,d,a,b,x[i+ 6],17,-1473231341);
			b=FF(b,c,d,a,x[i+ 7],22,-45705983);
			a=FF(a,b,c,d,x[i+ 8],7 , 1770035416);
			d=FF(d,a,b,c,x[i+ 9],12,-1958414417);
			c=FF(c,d,a,b,x[i+10],17,-42063);
			b=FF(b,c,d,a,x[i+11],22,-1990404162);
			a=FF(a,b,c,d,x[i+12],7 , 1804603682);
			d=FF(d,a,b,c,x[i+13],12,-40341101);
			c=FF(c,d,a,b,x[i+14],17,-1502002290);
			b=FF(b,c,d,a,x[i+15],22, 1236535329);

			a=GG(a,b,c,d,x[i+ 1],5 ,-165796510);
			d=GG(d,a,b,c,x[i+ 6],9 ,-1069501632);
			c=GG(c,d,a,b,x[i+11],14, 643717713);
			b=GG(b,c,d,a,x[i+ 0],20,-373897302);
			a=GG(a,b,c,d,x[i+ 5],5 ,-701558691);
			d=GG(d,a,b,c,x[i+10],9 , 38016083);
			c=GG(c,d,a,b,x[i+15],14,-660478335);
			b=GG(b,c,d,a,x[i+ 4],20,-405537848);
			a=GG(a,b,c,d,x[i+ 9],5 , 568446438);
			d=GG(d,a,b,c,x[i+14],9 ,-1019803690);
			c=GG(c,d,a,b,x[i+ 3],14,-187363961);
			b=GG(b,c,d,a,x[i+ 8],20, 1163531501);
			a=GG(a,b,c,d,x[i+13],5 ,-1444681467);
			d=GG(d,a,b,c,x[i+ 2],9 ,-51403784);
			c=GG(c,d,a,b,x[i+ 7],14, 1735328473);
			b=GG(b,c,d,a,x[i+12],20,-1926607734);

			a=HH(a,b,c,d,x[i+ 5],4 ,-378558);
			d=HH(d,a,b,c,x[i+ 8],11,-2022574463);
			c=HH(c,d,a,b,x[i+11],16, 1839030562);
			b=HH(b,c,d,a,x[i+14],23,-35309556);
			a=HH(a,b,c,d,x[i+ 1],4 ,-1530992060);
			d=HH(d,a,b,c,x[i+ 4],11, 1272893353);
			c=HH(c,d,a,b,x[i+ 7],16,-155497632);
			b=HH(b,c,d,a,x[i+10],23,-1094730640);
			a=HH(a,b,c,d,x[i+13],4 , 681279174);
			d=HH(d,a,b,c,x[i+ 0],11,-358537222);
			c=HH(c,d,a,b,x[i+ 3],16,-722521979);
			b=HH(b,c,d,a,x[i+ 6],23, 76029189);
			a=HH(a,b,c,d,x[i+ 9],4 ,-640364487);
			d=HH(d,a,b,c,x[i+12],11,-421815835);
			c=HH(c,d,a,b,x[i+15],16, 530742520);
			b=HH(b,c,d,a,x[i+ 2],23,-995338651);

			a=II(a,b,c,d,x[i+ 0],6 ,-198630844);
			d=II(d,a,b,c,x[i+ 7],10, 1126891415);
			c=II(c,d,a,b,x[i+14],15,-1416354905);
			b=II(b,c,d,a,x[i+ 5],21,-57434055);
			a=II(a,b,c,d,x[i+12],6 , 1700485571);
			d=II(d,a,b,c,x[i+ 3],10,-1894986606);
			c=II(c,d,a,b,x[i+10],15,-1051523);
			b=II(b,c,d,a,x[i+ 1],21,-2054922799);
			a=II(a,b,c,d,x[i+ 8],6 , 1873313359);
			d=II(d,a,b,c,x[i+15],10,-30611744);
			c=II(c,d,a,b,x[i+ 6],15,-1560198380);
			b=II(b,c,d,a,x[i+13],21, 1309151649);
			a=II(a,b,c,d,x[i+ 4],6 ,-145523070);
			d=II(d,a,b,c,x[i+11],10,-1120210379);
			c=II(c,d,a,b,x[i+ 2],15, 718787259);
			b=II(b,c,d,a,x[i+ 9],21,-343485551);

			a = add(a,olda);
			b = add(b,oldb);
			c = add(c,oldc);
			d = add(d,oldd);
		}
		return [a,b,c,d];
	}
	function hmac(data,key){
		var wa=toWord(key);
		if(wa.length>16) wa=core(wa,key.length*chrsz);
		var l=[], r=[];
		for(var i=0; i<16; i++){
			l[i]=wa[i]^0x36363636;
			r[i]=wa[i]^0x5c5c5c5c;
		}
		var h=core(l.concat(toWord(data)),512+data.length*chrsz);
		return core(r.concat(h),640);
	}

	//	Public functions
	this.compute=function(data,outputType){
		var out=outputType||dojo.crypto.outputTypes.Base64;
		switch(out){
			case dojo.crypto.outputTypes.Hex:{
				return toHex(core(toWord(data),data.length*chrsz));
			}
			case dojo.crypto.outputTypes.String:{
				return toString(core(toWord(data),data.length*chrsz));
			}
			default:{
				return toBase64(core(toWord(data),data.length*chrsz));
			}
		}
	};
	this.getHMAC=function(data,key,outputType){
		var out=outputType||dojo.crypto.outputTypes.Base64;
		switch(out){
			case dojo.crypto.outputTypes.Hex:{
				return toHex(hmac(data,key));
			}
			case dojo.crypto.outputTypes.String:{
				return toString(hmac(data,key));
			}
			default:{
				return toBase64(hmac(data,key));
			}
		}
	};
}();

/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/


dojo.provide("dojo.widget.TreeSelector");

dojo.require("dojo.widget.HtmlWidget");


dojo.widget.tags.addParseTreeHandler("dojo:TreeSelector");


dojo.widget.TreeSelector = function() {
	dojo.widget.HtmlWidget.call(this);


	this.eventNames = {};

	this.listenedTrees = [];

}

dojo.inherits(dojo.widget.TreeSelector, dojo.widget.HtmlWidget);


dojo.lang.extend(dojo.widget.TreeSelector, {
	widgetType: "TreeSelector",
	selectedNode: null,

	dieWithTree: false,

	eventNamesDefault: {
		select : "select",
		destroy : "destroy",
		deselect : "deselect",
		dblselect: "dblselect" // select already selected node.. Edit or whatever
	},

	initialize: function() {

		for(name in this.eventNamesDefault) {
			if (dojo.lang.isUndefined(this.eventNames[name])) {
				this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name];
			}
		}

	},


	destroy: function() {
		dojo.event.topic.publish(this.eventNames.destroy, { source: this } );

		return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments);
	},


	listenTree: function(tree) {
		dojo.event.topic.subscribe(tree.eventNames.titleClick, this, "select");
		dojo.event.topic.subscribe(tree.eventNames.iconClick, this, "select");
		dojo.event.topic.subscribe(tree.eventNames.collapse, this, "onCollapse");
		dojo.event.topic.subscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
		dojo.event.topic.subscribe(tree.eventNames.removeNode, this, "onRemoveNode");
		dojo.event.topic.subscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");

		/* remember all my trees to deselect when element is movedFrom them */
		this.listenedTrees.push(tree);
	},


	unlistenTree: function(tree) {

		dojo.event.topic.unsubscribe(tree.eventNames.titleClick, this, "select");
		dojo.event.topic.unsubscribe(tree.eventNames.iconClick, this, "select");
		dojo.event.topic.unsubscribe(tree.eventNames.collapse, this, "onCollapse");
		dojo.event.topic.unsubscribe(tree.eventNames.moveFrom, this, "onMoveFrom");
		dojo.event.topic.unsubscribe(tree.eventNames.removeNode, this, "onRemoveNode");
		dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy");


		for(var i=0; i<this.listenedTrees.length; i++){
           if(this.listenedTrees[i] === tree){
                   this.listenedTrees.splice(i, 1);
                   break;
           }
		}
	},


	onTreeDestroy: function(message) {

		this.unlistenTree(message.source);

		if (this.dieWithTree) {
			//dojo.debug("Killing myself "+this.widgetId);
			this.destroy();
			//dojo.debug("done");
		}
	},


	// deselect node if parent is collapsed
	onCollapse: function(message) {
		if (!this.selectedNode) return;

		var node = message.source;
		var parent = this.selectedNode.parent;
		while (parent !== node && parent.isTreeNode) {
			parent = parent.parent;
		}
		if (parent.isTreeNode) {
			this.deselect();
		}
	},



	select: function(message) {
		var node = message.source;
		var e = message.event;

		if (this.selectedNode === node) {
			dojo.event.topic.publish(this.eventNames.dblselect, { node: node });
			return;
		}

		if (this.selectedNode) {
			this.deselect();
		}

		this.doSelect(node);

		dojo.event.topic.publish(this.eventNames.select, {node: node} );
	},

	/**
	 * Deselect node if target tree is out of our concern
	 */
	onMoveFrom: function(message) {
		if (message.child !== this.selectedNode) {
			return;
		}

		if (!dojo.lang.inArray(this.listenedTrees, message.newTree)) {
			this.deselect();
		}
	},

	onRemoveNode: function(message) {
		if (message.child !== this.selectedNode) {
			return;
		}

		this.deselect();
	},

	doSelect: function(node){

		node.markSelected();

		this.selectedNode = node;
	},

	deselect: function(){

		var node = this.selectedNode;

		this.selectedNode = null;
		node.unMarkSelected();
		dojo.event.topic.publish(this.eventNames.deselect, {node: node} );

	}

});




/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/


dojo.provide("dojo.widget.TreeNode");

dojo.require("dojo.event.*");
dojo.require("dojo.io.*");

// make it a tag
dojo.widget.tags.addParseTreeHandler("dojo:TreeNode");


// # //////////

dojo.widget.TreeNode = function() {
	dojo.widget.HtmlWidget.call(this);

	this.actionsDisabled = [];
}

dojo.inherits(dojo.widget.TreeNode, dojo.widget.HtmlWidget);

dojo.lang.extend(dojo.widget.TreeNode, {
	widgetType: "TreeNode",

	loadStates: {
		UNCHECKED: "UNCHECKED",
    	LOADING: "LOADING",
    	LOADED: "LOADED"
	},


	actions: {
		MOVE: "MOVE",
    	REMOVE: "REMOVE",
    	EDIT: "EDIT",
    	ADDCHILD: "ADDCHILD"
	},

	isContainer: true,

	lockLevel: 0, // lock ++ unlock --, so nested locking works fine


	templateString: ('<div class="dojoTreeNode"> '
		+ '<span treeNode="${this.widgetId}" class="dojoTreeNodeLabel fd" dojoAttachPoint="labelNode"> '
		+ '<span dojoAttachPoint="titleNode" dojoAttachEvent="onClick: onTitleClick" class="dojoTreeNodeLabelTitle">${this.title}</span> '
		+ '</span> '
		+ '<span class="dojoTreeNodeAfterLabel" dojoAttachPoint="afterLabelNode">${this.afterLabel}</span> '
		+ '<div dojoAttachPoint="containerNode" style="display:none"></div> '
		+ '</div>').replace(/(>|<)\s+/g, '$1'), // strip whitespaces between nodes


	childIconSrc: "",
	childIconFolderSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/closed.gif"), // for under root parent item child icon,
	childIconDocumentSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/document.gif"), // for under root parent item child icon,

	childIcon: null,
	isTreeNode: true,

	objectId: "", // the widget represents an object

	afterLabel: "",
	afterLabelNode: null, // node to the left of labelNode

	// an icon left from childIcon: imgs[-2].
	// if +/- for folders, blank for leaves
	expandIcon: null,

	title: "",
	object: "", // node may have object attached, settable from HTML
	isFolder: false,

	labelNode: null, // the item label
	titleNode: null, // the item title
	imgs: null, // an array of icons imgs

	expandLevel: "", // expand to level

	tree: null,

	depth: 0,

	isExpanded: false,

	state: null,  // after creation will change to loadStates: "loaded/loading/unchecked"
	domNodeInitialized: false,  // domnode is initialized with icons etc


	isFirstNode: function() {
		return this.getParentIndex() == 0 ? true: false;
	},

	isLastNode: function() {
		return this.getParentIndex() == this.parent.children.length-1 ? true : false;
	},

	lock: function(){ return this.tree.lock.apply(this, arguments) },
	unlock: function(){ return this.tree.unlock.apply(this, arguments) },
	isLocked: function(){ return this.tree.isLocked.apply(this, arguments) },
	cleanLock: function(){ return this.tree.cleanLock.apply(this, arguments) },

	actionIsDisabled: function(action) {
		var _this = this;

		var disabled = false;

		if (this.tree.strictFolders && action == this.actions.ADDCHILD && !this.isFolder) {
			disabled = true;
		}

		if (dojo.lang.inArray(_this.actionsDisabled, action)) {
			disabled = true;
		}

		if (this.isLocked()) {
			disabled = true;
		}

		return disabled;
	},

	getInfo: function() {
		// No title here (title may be widget)
		var info = {
			widgetId: this.widgetId,
			objectId: this.objectId,
			index: this.getParentIndex(),
			isFolder: this.isFolder
		}

		return info;
	},

	initialize: function(args, frag){

		//dojo.debug(this.title)

		this.state = this.loadStates.UNCHECKED;

		for(var i=0; i<this.actionsDisabled.length; i++) {
			this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();
		}

		this.expandLevel = parseInt(this.expandLevel);

	},


	/**
	 * Change visible node depth by appending/prepending with blankImgs
	 * @param depthDiff Integer positive => move right, negative => move left
	*/
	adjustDepth: function(depthDiff) {

		for(var i=0; i<this.children.length; i++) {
			this.children[i].adjustDepth(depthDiff);
		}

		this.depth += depthDiff;

		if (depthDiff>0) {
			for(var i=0; i<depthDiff; i++) {
				var img = this.tree.makeBlankImg();
				this.imgs.unshift(img);
				//dojo.debugShallow(this.domNode);
				dojo.dom.insertBefore(this.imgs[0], this.domNode.firstChild);

			}
		}
		if (depthDiff<0) {
			for(var i=0; i<-depthDiff;i++) {
				this.imgs.shift();
				dojo.dom.removeNode(this.domNode.firstChild);
			}
		}

	},


	markLoading: function() {
		this._markLoadingSavedIcon = this.expandIcon.src;
		this.expandIcon.src = this.tree.expandIconSrcLoading;
	},

	// if icon is "Loading" then
	unMarkLoading: function() {
		if (!this._markLoadingSavedIcon) return;

		var im = new Image();
		im.src = this.tree.expandIconSrcLoading;

		//dojo.debug("Unmark "+this.expandIcon.src+" : "+im.src);
		if (this.expandIcon.src == im.src) {
			this.expandIcon.src = this._markLoadingSavedIcon;
		}
		this._markLoadingSavedIcon = null;
	},


	setFolder: function() {
		dojo.event.connect(this.expandIcon, 'onclick', this, 'onTreeClick');
		this.expandIcon.src = this.isExpanded ? this.tree.expandIconSrcMinus : this.tree.expandIconSrcPlus;
		this.isFolder = true;
	},


	createDOMNode: function(tree, depth){

		this.tree = tree;
		this.depth = depth;


		//
		// add the tree icons
		//

		this.imgs = [];

		for(var i=0; i<this.depth+1; i++){

			var img = this.tree.makeBlankImg();

			this.domNode.insertBefore(img, this.labelNode);

			this.imgs.push(img);
		}


		this.expandIcon = this.imgs[this.imgs.length-1];


		this.childIcon = this.tree.makeBlankImg();

		// add to images before the title
		this.imgs.push(this.childIcon);

		dojo.dom.insertBefore(this.childIcon, this.titleNode);

		// node with children(from source html) becomes folder on build stage.
		if (this.children.length || this.isFolder) {
			this.setFolder();
		}
		else {
			// leaves are always loaded
			//dojo.debug("Set "+this+" state to loaded");
			this.state = this.loadStates.LOADED;
		}

		dojo.event.connect(this.childIcon, 'onclick', this, 'onIconClick');


		//
		// create the child rows
		//


		for(var i=0; i<this.children.length; i++){
			this.children[i].parent = this;

			var node = this.children[i].createDOMNode(this.tree, this.depth+1);

			this.containerNode.appendChild(node);
		}


		if (this.children.length) {
			this.state = this.loadStates.LOADED;
		}

		this.updateIcons();

		this.domNodeInitialized = true;

		dojo.event.topic.publish(this.tree.eventNames.createDOMNode, { source: this } );

		return this.domNode;
	},

	onTreeClick: function(e){
		dojo.event.topic.publish(this.tree.eventNames.treeClick, { source: this, event: e });
	},

	onIconClick: function(e){
		dojo.event.topic.publish(this.tree.eventNames.iconClick, { source: this, event: e });
	},

	onTitleClick: function(e){
		dojo.event.topic.publish(this.tree.eventNames.titleClick, { source: this, event: e });
	},

	markSelected: function() {
		//dojo.html.removeClass(this.titleNode, 'dojoTreeNodeLabelTitle');
		dojo.html.addClass(this.titleNode, 'dojoTreeNodeLabelSelected');
		//dojo.html.addClass(this.titleNode, 'dojoTreeNodeLabelTitle');
	},


	unMarkSelected: function() {
		//dojo.debug('unmark')
		dojo.html.removeClass(this.titleNode, 'dojoTreeNodeLabelSelected');
	},

	updateExpandIcon: function() {
		if (this.isFolder){
			this.expandIcon.src = this.isExpanded ? this.tree.expandIconSrcMinus : this.tree.expandIconSrcPlus;
		} else {
			this.expandIcon.src = this.tree.blankIconSrc;
		}
	},

	/* set the grid under the expand icon */
	updateExpandGrid: function() {

		if (this.tree.showGrid){
			if (this.depth){
				this.setGridImage(-2, this.isLastNode() ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
			}else{
				if (this.isFirstNode()){
					this.setGridImage(-2, this.isLastNode() ? this.tree.gridIconSrcX : this.tree.gridIconSrcY);
				}else{
					this.setGridImage(-2, this.isLastNode() ? this.tree.gridIconSrcL : this.tree.gridIconSrcT);
				}
			}
		}else{
			this.setGridImage(-2, this.tree.blankIconSrc);
		}

	},

	/* set the grid under the child icon */
	updateChildGrid: function() {

		if ((this.depth || this.tree.showRootGrid) && this.tree.showGrid){
			this.setGridImage(-1, (this.children.length && this.isExpanded) ? this.tree.gridIconSrcP : this.tree.gridIconSrcC);
		}else{
			if (this.tree.showGrid && !this.tree.showRootGrid){
				this.setGridImage(-1, (this.children.length && this.isExpanded) ? this.tree.gridIconSrcZ : this.tree.blankIconSrc);
			}else{
				this.setGridImage(-1, this.tree.blankIconSrc);
			}
		}


	},

	updateParentGrid: function() {
		var parent = this.parent;

		//dojo.debug("updateParentGrid "+this);

		for(var i=0; i<this.depth; i++){

			//dojo.debug("Parent "+parent);

			var idx = this.imgs.length-(3+i);
			var img = (this.tree.showGrid && !parent.isLastNode()) ? this.tree.gridIconSrcV : this.tree.blankIconSrc;

			//dojo.debug("Image "+img+" for "+idx);

			this.setGridImage(idx, img);

			parent = parent.parent;
		}
	},

	updateExpandGridColumn: function() {
		if (!this.tree.showGrid) return;

		var _this = this;

		var icon = this.isLastNode() ? this.tree.blankIconSrc : this.tree.gridIconSrcV;

		dojo.lang.forEach(_this.getDescendants(),
			function(node) { node.setGridImage(_this.depth, icon); }
		);

		this.updateExpandGrid();
	},

	updateIcons: function(){


		//dojo.profile.start("updateIcons")

		//dojo.debug("Update icons for "+this)
		//dojo.debug(this.isFolder)

		this.imgs[0].style.display = this.tree.showRootGrid ? 'inline' : 'none';


		//
		// set the expand icon
		//


		//
		// set the child icon
		//
		this.buildChildIcon();

		this.updateExpandGrid();
		this.updateChildGrid();
		this.updateParentGrid();



		dojo.profile.stop("updateIcons")

	},

	buildChildIcon: function() {
		// IE (others?) tries to download whatever is on src attribute so setting "url()" like before isnt a good idea
		// Only results in a 404
		if(this.childIconSrc){
			this.childIcon.src = this.childIconSrc;
		}
		this.childIcon.style.display = this.childIconSrc ? 'inline' : 'none';
	},

	setGridImage: function(idx, src){

		if (idx < 0){
			idx = this.imgs.length + idx;
		}

		//if (idx >= this.imgs.length-2) return;
		this.imgs[idx].style.backgroundImage = 'url(' + src + ')';
	},


	updateIconTree: function(){
		this.tree.updateIconTree.call(this);
	},




	expand: function(){
		if (this.isExpanded) return;

		if (this.children.length) {
			this.showChildren();
		}

		this.isExpanded = true;

		this.updateExpandIcon();

		dojo.event.topic.publish(this.tree.eventNames.expand, {source: this} );
	},

	collapse: function(){
		if (!this.isExpanded) return;

		this.hideChildren();
		this.isExpanded = false;

		this.updateExpandIcon();

		dojo.event.topic.publish(this.tree.eventNames.collapse, {source: this} );
	},

	hideChildren: function(){
		this.tree.toggleObj.hide(
			this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onHide")
		);

		/* if dnd is in action, recalculate changed coordinates */
		if(dojo.exists(dojo, 'dnd.dragManager.dragObjects') && dojo.dnd.dragManager.dragObjects.length) {
			dojo.dnd.dragManager.cacheTargetLocations();
		}
	},

	showChildren: function(){
		this.tree.toggleObj.show(
			this.containerNode, this.toggleDuration, this.explodeSrc, dojo.lang.hitch(this, "onShow")
		);

		/* if dnd is in action, recalculate changed coordinates */
		if(dojo.exists(dojo, 'dnd.dragManager.dragObjects') && dojo.dnd.dragManager.dragObjects.length) {
			dojo.dnd.dragManager.cacheTargetLocations();
		}
	},

	addChild: function(){
		return this.tree.addChild.apply(this, arguments);
	},

	doAddChild: function(){
		return this.tree.doAddChild.apply(this, arguments);
	},



	/* Edit current node : change properties and update contents */
	edit: function(props) {
		dojo.lang.mixin(this, props);
		if (props.title) {
			this.titleNode.innerHTML = this.title;
		}

		if (props.afterLabel) {
			this.afterLabelNode.innerHTML = this.afterLabel;
		}

		if (props.childIconSrc) {
			this.buildChildIcon();
		}


	},


	removeNode: function(){ return this.tree.removeNode.apply(this, arguments) },
	doRemoveNode: function(){ return this.tree.doRemoveNode.apply(this, arguments) },


	toString: function() {
		return "["+this.widgetType+" Tree:"+this.tree+" ID:"+this.widgetId+" Title:"+this.title+"]";

	}

});





/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

/**
 * Tree model does all the drawing, visual node management etc.
 * Throws events about clicks on it, so someone may catch them and process
 * Tree knows nothing about DnD stuff, covered in TreeDragAndDrop and (if enabled) attached by controller
*/

/**
 * TODO: use domNode.cloneNode instead of createElement for grid
 * Should be faster (lyxsus)
 */
dojo.provide("dojo.widget.Tree");

dojo.require("dojo.event.*");
dojo.require("dojo.io.*");
dojo.require("dojo.widget.HtmlWidget");
dojo.require("dojo.widget.TreeNode");



// make it a tag
dojo.widget.tags.addParseTreeHandler("dojo:Tree");


dojo.widget.Tree = function() {
	dojo.widget.HtmlWidget.call(this);

	this.eventNames = {};

	this.tree = this;
	this.DNDAcceptTypes = [];
	this.actionsDisabled = [];

}
dojo.inherits(dojo.widget.Tree, dojo.widget.HtmlWidget);

dojo.lang.extend(dojo.widget.Tree, {
	widgetType: "Tree",

	eventNamesDefault: {
		// new child does not get domNode filled in (only template draft)
		// until addChild->createDOMNode is called(program way) OR createDOMNode (html-way)
		// hook events to operate on new DOMNode, create dropTargets etc
		createDOMNode: "createDOMNode",
		// tree created.. Perform tree-wide actions if needed
		treeCreate: "treeCreate",
		treeDestroy: "treeDestroy",
		// expand icon clicked
		treeClick: "treeClick",
		// node icon clicked
		iconClick: "iconClick",
		// node title clicked
		titleClick: "titleClick",

		moveFrom: "moveFrom",
		moveTo: "moveTo",
		addChild: "addChild",
		removeNode: "removeNode",
		expand: "expand",
		collapse: "collapse"
	},

	isContainer: true,

	DNDMode: "off",

	lockLevel: 0, // lock ++ unlock --, so nested locking works fine

	strictFolders: true,

	DNDModes: {
		BETWEEN: 1,
		ONTO: 2
	},

	DNDAcceptTypes: "",

	templateCssPath: dojo.uri.dojoUri("src/widget/templates/images/Tree/Tree.css"),

	templateString: '<div class="dojoTree"></div>',

	isExpanded: true, // consider this "root node" to be always expanded

	isTree: true,

	objectId: "",

	// autoCreate if not "off"
	// used to get the autocreated controller ONLY.
	// generally, tree DOES NOT KNOW about its CONTROLLER, it just doesn't care
	// controller gets messages via dojo.event
	controller: "",

	// autoCreate if not "off"
	// used to get the autocreated selector ONLY.
	// generally, tree DOES NOT KNOW its SELECTOR
	// binding is made with dojo.event
	selector: "",

	// used ONLY at initialization time
	menu: "", // autobind menu if menu's widgetId is set here

	expandLevel: "", // expand to level automatically

	//
	// these icons control the grid and expando buttons for the whole tree
	//

	blankIconSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_blank.gif"),

	gridIconSrcT: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_t.gif"), // for non-last child grid
	gridIconSrcL: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_l.gif"), // for last child grid
	gridIconSrcV: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_v.gif"), // vertical line
	gridIconSrcP: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_p.gif"), // for under parent item child icons
	gridIconSrcC: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_c.gif"), // for under child item child icons
	gridIconSrcX: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_x.gif"), // grid for sole root item
	gridIconSrcY: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_y.gif"), // grid for last rrot item
	gridIconSrcZ: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_z.gif"), // for under root parent item child icon

	expandIconSrcPlus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_plus.gif"),
	expandIconSrcMinus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_minus.gif"),
	expandIconSrcLoading: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_loading.gif"),


	iconWidth: 18,
	iconHeight: 18,


	//
	// tree options
	//

	showGrid: true,
	showRootGrid: true,

	actionIsDisabled: function(action) {
		var _this = this;
		return dojo.lang.inArray(_this.actionsDisabled, action)
	},


	actions: {
    	ADDCHILD: "ADDCHILD"
	},


	getInfo: function() {
		var info = {
			widgetId: this.widgetId,
			objectId: this.objectId
		}

		return info;
	},

	initializeController: function() {
		if (this.controller != "off") {
			if (this.controller) {
				this.controller = dojo.widget.byId(this.controller);
			}
			else {
				// create default controller here
				dojo.require("dojo.widget.TreeBasicController");
				this.controller = dojo.widget.createWidget("TreeBasicController",
					{ DNDController: (this.DNDMode ? "create" : ""), dieWithTree: true }
				 );

			}
			this.controller.listenTree(this); // controller listens to my events

		} else {
			this.controller = null;
		}
	},

	initializeSelector: function() {

		if (this.selector != "off") {
			if (this.selector) {
				this.selector = dojo.widget.byId(this.selector);
			}
			else {
				// create default controller here
				dojo.require("dojo.widget.TreeSelector");
				this.selector = dojo.widget.createWidget("TreeSelector", {dieWithTree: true});
			}

			this.selector.listenTree(this);

		} else {
			this.selector = null;
		}
	},

	initialize: function(args, frag){

		var _this = this;

		for(name in this.eventNamesDefault) {
			if (dojo.lang.isUndefined(this.eventNames[name])) {
				this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name];
			}
		}

		for(var i=0; i<this.actionsDisabled.length; i++) {
			this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();
		}

		if (this.DNDMode == "off") {
			this.DNDMode = 0;
		} else if (this.DNDMode == "between") {
			this.DNDMode = this.DNDModes.ONTO | this.DNDModes.BETWEEN;
		} else if (this.DNDMode == "onto") {
			this.DNDMode = this.DNDModes.ONTO;
		}

		this.expandLevel = parseInt(this.expandLevel);

		this.initializeSelector();
		this.initializeController();

		if (this.menu) {
			this.menu = dojo.widget.byId(this.menu);
			this.menu.listenTree(this);
		}


		this.containerNode = this.domNode;

	},


	postCreate: function() {
		this.createDOMNode();
	},


	createDOMNode: function() {

		dojo.html.disableSelection(this.domNode);

		for(var i=0; i<this.children.length; i++){
			this.children[i].parent = this; // root nodes have tree as parent

			var node = this.children[i].createDOMNode(this, 0);


			this.domNode.appendChild(node);
		}


		if (!this.showRootGrid){
			for(var i=0; i<this.children.length; i++){
				this.children[i].expand();
			}
		}

		dojo.event.topic.publish(this.eventNames.treeCreate, { source: this } );

	},


	destroy: function() {
		dojo.event.topic.publish(this.tree.eventNames.treeDestroy, { source: this } );

		return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments);
	},


	addChild: function(child, index) {

//		dojo.debug("doAddChild "+index+" called for "+child);

		var message = {
			child: child,
			index: index,
			parent: this,
			// remember if dom was already initialized
			// initialized => no createDOMNode => no createDOMNode event
			domNodeInitialized: child.domNodeInitialized
		}

		this.doAddChild.apply(this, arguments);

		dojo.event.topic.publish(this.tree.eventNames.addChild, message);
	},


	// not called for initial tree building. See createDOMNode instead.
	// builds child html node if needed
	// index is "last node" by default
	/**
	 * FIXME: Is it possible that removeNode from the tree will cause leaks cause of attached events ?
	 * if yes, then only attach events in addChild and detach in remove.. Seems all ok yet.
	*/
	doAddChild: function(child, index){

		if (dojo.lang.isUndefined(index)) {
			index = this.children.length;
		}

		if (!child.isTreeNode){
			dojo.raise("You can only add TreeNode widgets to a "+this.widgetType+" widget!");
			return;
		}

		// usually it is impossible to change "isFolder" state, but if anyone wants to add a child to leaf,
		// it is possible program-way.
		if (this.isTreeNode){
			if (!this.isFolder) { // just became a folder.
				//dojo.debug("becoming folder "+this);
				this.setFolder();
			}
		}

		// adjust tree
		var _this = this;
		dojo.lang.forEach(child.getDescendants(), function(elem) { elem.tree = _this.tree; });

		// fix parent
		child.parent = this;


		// no dynamic loading for those who become parents
		if (this.isTreeNode) {
			this.state = this.loadStates.LOADED;
		}

		// add new child into DOM after it was added into children
		if (index < this.children.length) { // children[] already has child
			//dojo.debug("Inserting before "+this.children[index].title);
			dojo.dom.insertBefore(child.domNode, this.children[index].domNode);
		} else {
			this.containerNode.appendChild(child.domNode);
			if (this.isExpanded && this.isTreeNode) {
				/* When I add children to hidden containerNode => show container w/ them */
				this.showChildren();
			}
		}


		this.children.splice(index, 0, child);

		//dojo.debugShallow(this.children);


		// if node exists - adjust its depth, otherwise build it
		if (child.domNodeInitialized) {
			var d = this.isTreeNode ? this.depth : -1;
			child.adjustDepth( d - child.depth + 1 );


			// update icons to link generated dom with Tree => updateParentGrid
			// if I moved child from LastNode inside the tree => need to link it up'n'down =>
			// updateExpandGridColumn
			// if I change depth => need to update all grid..
			child.updateIconTree();
		} else {
			//dojo.debug("Create domnode ");
			child.depth = this.isTreeNode ? this.depth+1 : 0;
			child.createDOMNode(child.tree, child.depth);
		}



		// Use-case:
		// When previous sibling was created => it was last, no children after it
		// so it did not create link down => let's add it for all descendants
		// Use-case:
		// a child was moved down under the last node so last node should be updated
		var prevSibling = child.getPreviousSibling();
		if (child.isLastNode() && prevSibling) {
			prevSibling.updateExpandGridColumn();
		}


		//dojo.debug("Added child "+child);



	},




	makeBlankImg: function() {
		var img = document.createElement('img');

		img.style.width = this.iconWidth + 'px';
		img.style.height = this.iconHeight + 'px';
		img.src = this.blankIconSrc;
		img.style.verticalAlign = 'middle';

		return img;
	},


	updateIconTree: function(){

		//dojo.debug("Update icons for "+this)
		if (!this.isTree) {
			this.updateIcons();
		}

		for(var i=0; i<this.children.length; i++){
			this.children[i].updateIconTree();
		}

	},

	toString: function() {
		return "["+this.widgetType+" ID:"+this.widgetId+"]"
	},




	/**
	 * Move child to newParent as last child
	 * redraw tree and update icons.
	 *
	 * Called by target, saves source in event.
	 * events are published for BOTH trees AFTER update.
	*/
	move: function(child, newParent, index) {

		//dojo.debug(child+" "+newParent+" at "+index);

		var oldParent = child.parent;
		var oldTree = child.tree;

		this.doMove.apply(this, arguments);

		var newParent = child.parent;
		var newTree = child.tree;

		var message = {
				oldParent: oldParent, oldTree: oldTree,
				newParent: newParent, newTree: newTree,
				child: child
		};

		/* publish events here about structural changes for both source and target trees */
		dojo.event.topic.publish(oldTree.eventNames.moveFrom, message);
		dojo.event.topic.publish(newTree.eventNames.moveTo, message);

	},


	/* do actual parent change here. Write remove child first */
	doMove: function(child, newParent, index) {
		//var parent = child.parent;
		child.parent.doRemoveNode(child);

		newParent.doAddChild(child, index);
	},



// ================================ removeNode ===================================

	removeNode: function(child) {
		if (!child.parent) return;

		var oldTree = child.tree;
		var oldParent = child.parent;

		var removedChild = this.doRemoveNode.apply(this, arguments);


		dojo.event.topic.publish(this.tree.eventNames.removeNode,
			{ child: removedChild, tree: oldTree, parent: oldParent }
		);

		return removedChild;
	},


	doRemoveNode: function(child) {
		if (!child.parent) return;

		var parent = child.parent;

		var children = parent.children;


		var index = child.getParentIndex();
		if (index < 0) {
			dojo.raise("Couldn't find node "+child+" for removal");
		}


		children.splice(index,1);
		dojo.dom.removeNode(child.domNode);

		if (parent.children.length == 0) {
			parent.containerNode.style.display = "none";
		}

		// if WAS last node (children.length decreased already) and has prevSibling
		if (index == children.length && index>0) {
			children[index-1].updateExpandGridColumn();
		}
		// if it WAS first node in WHOLE TREE -
		// update link up of its former lower neighbour(if exists still)
		if (parent instanceof dojo.widget.Tree && index == 0 && children.length>0) {
			children[0].updateExpandGrid();
		}

		//parent.updateIconTree();


		child.parent = child.tree = null;

		return child;
	},

	markLoading: function() {
		// no way to mark tree loading
	},

	unMarkLoading: function() {
		// no way to show that tree finished loading
	},


	lock: function() {
		!this.lockLevel && this.markLoading();
		this.lockLevel++;
	},
	unlock: function() {
		if (!this.lockLevel) {
			dojo.raise("unlock: not locked");
		}
		this.lockLevel--;
		!this.lockLevel && this.unMarkLoading();
	},

	isLocked: function() {
		var node = this;
		while (true) {
			if (node.lockLevel) {
				return true;
			}
			if (node instanceof dojo.widget.Tree) {
				break;
			}
			node = node.parent;
		}

		return false;
	},

	flushLock: function() {
		this.lockLevel = 0;
		this.unMarkLoading();
	}
});



var MOD_RECHERCHE_SEARCH=null;function init(e){dlgSession=dojo.widget.manager.getWidgetsByType("Dialog")[0];for(var i=0;i<arrayCW.length;i++){var _1=arrayCW[i];WindowSystem.createWindow("cw_"+_1["mod"],"",_1["label"]);}shortcut("backspace",function(){key_backspace();},{"propagate":true});shortcut("escape",function(){key_escape();});shortcut("tab",function(e){key_tab(e);},{"propagate":true});openCWindowMod("home");};function reloadIndex(){document.location.reload();};function showMessage(_2){var _3=$("resultBlockContent");NewAC("").inner(unescape(_2),"resultBlock",true);OPEN_MESSAGE++;_3.show();setTimeout(function(){hideMessage();},5000);};function hideMessage(){var _4=$("resultBlockContent");OPEN_MESSAGE--;if(OPEN_MESSAGE==0){_4.hide();}};function closeSession(){window.location="?module=Default&action=Logout";};function openCwindow(_5,_6,_7){if(_5){_5.showExplode(_7);_5.loadGeneralLink(_6);}};function openCWindowMod(_8,_9){var _a="?module="+_8+"&action=Index";if(_9){_a+="&"+_9;}var _b=document.getElementById("menuButton_"+_8);var _c=WindowSystem.getWindowByModuleName(_8);openCwindow(_c,_a,_b);};function openModal(_d){WindowSystem.getCurrentWindow().openModal(_d);};function testDeconnexion(){};function alertNoRight(){alert("Vous n'avez pas les droits requis pour cette operation ou l'application ne le permet pas.");};function dbg(_e,_f){if(typeof (console)!="undefined"){console.log(_e);}else{if(_f){alert(_e);}}};function selectLink(_10){try{var tr=_10.parentNode.parentNode;var _11=tr.parentNode;var _12=_11.getElementsByTagName("tr");for(var i=0;i<_12.length;i++){_12[i].className="menuLinkOut";}tr.className="menuLinkSel";}catch(er){}};function unSelectLink(_13){var tr=_13.parentNode.parentNode;tr.className="menuLinkOut";};function unSelectLinkTable(_14){var _15=_14.getElementsByTagName("tr");for(var i=0;i<_15.length;i++){_15[i].className="menuLinkOut";}};function unSelectLinkDojoTree(_16){var _17=_16.getElementsByTagName("span");for(var i=0;i<_17.length;i++){if(_17[i].className=="dojoTreeNodeLabelTitle dojoTreeNodeLabelSelected"){_17[i].className="dojoTreeNodeLabelTitle";}}};function checkIt(_18,_19,_1a,_1b){if(_19){if(!_19.checked){if(_18.className.indexOf("tuple0")>=0){_18.className="tuple0sel";}else{_18.className="tuple1sel";}_19.checked=true;}else{_19.checked=false;if(_18.className.indexOf("tuple0")>=0){_18.className="tuple0";}else{_18.className="tuple1";}}if(_1b!=null){eval(_1b);}}};function selectAll(_1c,_1d){var _1e=document.getElementsByName(_1c+"_ido[]");for(var i=0;i<_1e.length;i++){_1e[i].checked=_1d;var tr=_1e[i].parentNode.parentNode;if(!_1d){if(tr.className.indexOf("tuple0")>=0){tr.className="tuple0";}else{tr.className="tuple1";}}else{if(tr.className.indexOf("tuple0")>=0){tr.className="tuple0sel";}else{tr.className="tuple1sel";}}}};function getSelected(_1f){var _20=document.getElementsByName(_1f+"_ido[]");var _21=new Array();for(var i=0;i<_20.length;i++){if(_20[i].checked){_21.push(_20[i].value);}}return _21;};function editSelected(_22){try{var _23=getSelected(_22);if(_23.length==1){var _24=_23[0];return _24;}else{throw "Veuillez sélectionner un seul element!";}}catch(error){alert(error);}return null;};function selectLi(li){var ul=li.parentNode;var _25=ul.getElementsByTagName("li");for(var i=0;i<_25.length;i++){_25[i].className="";}li.className="navlistlink";};function Dj_tooltip(_26,_27){_26.onMouseOver=null;connectId_=_26.id;if(!connectId_){var _28=Math.round(Math.random()*1000000);connectId_="srcTip_"+_28;_26.id=connectId_;}if(!document.getElementById("tooltip_"+connectId_)){tooltip=dojo.widget.createWidget("tooltip",{caption:"",connectId:connectId_});tooltip.domNode.id="tooltip_"+connectId_;document.body.appendChild(tooltip.domNode);inner("test",tooltip.domNode.id);}};function Dj_tooltipDyn(_29,_2a){tooltip=dojo.widget.createWidget("tooltip",{href:_2a,connectId:_29});tooltip.connectNode.parentNode.appendChild(tooltip.domNode);};function openInputTree(id){var _2b=id+"_div";var _2c=document.getElementById(_2b);if(_2c.style.display!=""){_2c.style.display="";dojo.event.connect(document.body,"onmousedown",function(){closeInputTree(id);});}else{}};function closeInputTree(id){var _2d=id+"_div";var _2e=document.getElementById(_2d);_2e.style.display="none";dojo.event.disconnect(document.body,"onmousedown","closeInputTree");};function updateEditorFormValue(_2f){for(i=0;i<parent.frames.length;i++){try{if(parent.frames[i].FCK){parent.frames[i].FCK.UpdateLinkedField();}}catch(e){}}if(_2f!=""&&typeof (CKEDITOR)!="undefined"){var f=document.getElementById(_2f);for(input in CKEDITOR.instances){if(f[input]&&f[input].type=="textarea"){f[input].value=CKEDITOR.instances[input].getData();}}CKEDITOR.instances={};}};function enableDateValidite(_30,_31,_32){if(_30){document.getElementById(_31).disabled=false;document.getElementById(_31).style.color="";document.getElementById(_32).disabled=false;document.getElementById(_32).style.color="";}else{document.getElementById(_31).disabled=true;document.getElementById(_31).style.color="grey";document.getElementById(_32).disabled=true;document.getElementById(_32).style.color="grey";}};function initSearchForm(_33){MOD_RECHERCHE_SEARCH=_33;openCWindowMod("recherche");initSearchForm2();};function initSearchForm2(){var _34=document.forms["form_search"];if(_34){var _35=_34.elements["f_module[]"];for(var i=0;i<_35.length;i++){var _36=_35[i];if(_36.value==MOD_RECHERCHE_SEARCH||MOD_RECHERCHE_SEARCH==null){_36.checked=true;}else{_36.checked=false;}eval(_36.getAttribute("onchange"));}MOD_RECHERCHE_SEARCH=null;}};function key_escape(e){var _37=true; if(typeof(vtcalendar)!="undefined" && vtcalendar && vtcalendar.currentDrag && vtcalendar.currentDrag.killDrag){vtcalendar.currentDrag.killDrag(e); _37=false;}if(VTAgendaPopup){if(VTAgendaPopup.isOpen(WindowSystem.getCurrentWindow().id)){VTAgendaPopup.maskPopup(VTAgendaPopup.getIdPopupOpen(WindowSystem.getCurrentWindow().id),true);_37=false;}}if(_37){var _38=WindowSystem.getCurrentWindow();_38.closeModal();}};function key_backspace(){var _39=WindowSystem.getCurrentWindow();var _3a=_39.getShortCut("backspace");if(_3a&&!_39.isOpenedModale()){_3a();e.cancelBubble=true;e.returnValue=false;if(e.stopPropagation){e.stopPropagation();e.preventDefault();}return false;}};function key_tab(e){var e=e||window.event;var _3b=e.target;try{if(_3b!="undefined"&&_3b.tagName=="HTML"){displayMenu();e.cancelBubble=true;e.returnValue=false;if(e.stopPropagation){e.stopPropagation();e.preventDefault();}return false;}}catch(er){}};function displayMenu(){var _3c=document.getElementById("modBox");var _3d=document.getElementById("contenercwsGbl");var _3e=document.getElementById("menuController");var _3f=144;var _40=42;var _41=0;var _42=6;if(_3c.style.display=="none"){_3c.style.display="";_3e.style.borderRight="";_3d.style.marginLeft=(_3f+_42)+"px";_3c.style.width=_3f+"px";changecss(".WindowTop","left",(_3f+_42)+"px");var _43=document.getElementsByName("menuButton_label");for(var i=0;i<_43.length;i++){var iEl=_43[i];iEl.style.display="";}var _44=document.getElementsByName("menuButton_grp");for(var i=0;i<_44.length;i++){var iEl=_44[i];iEl.style.display="";}}else{if(_3c.style.width==(_40+"px")){_3c.style.display="none";_3e.style.borderRight="1px solid #CCCCCC";_3d.style.marginLeft=_42+"px";changecss(".WindowTop","left",_42+"px");}else{var _43=document.getElementsByName("menuButton_label");for(var i=0;i<_43.length;i++){var iEl=_43[i];iEl.style.display="none";}var _44=document.getElementsByName("menuButton_grp");for(var i=0;i<_44.length;i++){var iEl=_44[i];iEl.style.display="none";}_3c.style.width=_40+"px";_3d.style.marginLeft=_40+_42+"px";changecss(".WindowTop","left",_40+_42+"px");}}};function changecss(_45,_46,_47){var _48;if(document.all){_48="rules";}else{if(document.getElementById){_48="cssRules";}}for(var S=0;S<document.styleSheets.length;S++){for(var R=0;R<document.styleSheets[S][_48].length;R++){if(document.styleSheets[S][_48][R].selectorText==_45){document.styleSheets[S][_48][R].style[_46]=_47;}}}};function popUp(url,_49,_4a,_4b){mapopup=window.open(url,_49,"width="+_4a+",height="+_4b+", resizable=no, status=no, directories=no, scrollbars=yes");hauteur=screen.availHeight-_4b;largeur=screen.availWidth-_4a;pointx=(largeur)/2;pointy=(hauteur)/2;mapopup.moveTo(pointx,pointy);};function byId(id_){return document.getElementById(id_);};function heightY(_4c){return _4c.offsetHeight;};function setHeight(_4d,_4e){_4d.style.height=_4e+"px";};function setWidth(_4f,_50){_4f.style.width=_50+"px";};function widthX(_51){return _51.offsetWidth;};function posX(obj){var _52=0;if(obj.offsetParent){while(obj.offsetParent){_52+=obj.offsetLeft;obj=obj.offsetParent;}}else{if(obj.x){_52+=obj.x;}}return _52;};function posY(obj){var _53=0;if(obj.offsetParent){while(obj.offsetParent){_53+=obj.offsetTop;obj=obj.offsetParent;}}else{if(obj.y){_53+=obj.y;}}return _53;};function windowH(){var _54=0;var ie4=(document.all)?true:false;if(ie4){_54=document.body.offsetHeight;}else{_54=window.innerHeight;}return _54;};function windowW(){var _55=0;var ie4=(document.all)?true:false;if(ie4){_55=document.body.clientWidth;}else{_55=window.innerWidth;}return _55;};function percentX(_56){windowW=0;if(getNav()=="ie"){windowW=document.body.clientWidth;}else{windowW=window.innerWidth;}return Math.round(windowW*_56/100);};function percentY(_57){var ie4=(document.all)?true:false;var _58=0;if(ie4){_58=document.body.clientHeight;}else{_58=window.innerHeight;}return Math.round(_58*_57/100);};function mouseX(e){var _59=0;if(!e){var e=window.event;}if(e.pageX||e.pageY){_59=e.pageX;}else{if(e.clientX||e.clientY){_59=e.clientX+document.body.scrollLeft;}}return _59;};function mouseY(e){var _5a=0;if(!e){var e=window.event;}if(e.pageX||e.pageY){_5a=e.pageY;}else{if(e.clientX||e.clientY){_5a=e.clientY+document.body.scrollTop;}}return _5a;};function isDisplayed(_5b,_5c){if(_5c){document.getElementById(_5b).style.display="";}else{document.getElementById(_5b).style.display="none";}};function changeDisplay(_5d){if(_5d){ if(document.getElementById(_5d).style.display=="none"){document.getElementById(_5d).style.display="";}else{document.getElementById(_5d).style.display="none";}}};function in_array(_5e,_5f){if(typeof (_5e)=="object"){for(var i=0;i<_5f.length;i++){if(_5e==_5f[i]||_5e.isEqual(_5f[i])){return true;}}return false;}else{for(var i=0;i<_5f.length;i++){if(_5f[i]==_5e){return true;}}return false;}};function array_remove(_60,_61){var _62;for(var i=0;i<_61.length;i++){if(_61[i]==_60){_62=i;}}var _63=_61.slice(0,_62);var _64=_61.slice(_62+1,_61.length);var _65=_63.concat(_64);return _65;};function filterSelect(_66,_67){arrayValues=_67.split(",");options=_66.childElements();if(typeof (_66.globalArrayOptions)=="undefined"){_66.globalArrayOptions=new Array();for(var i=0;i<options.length;i++){_66.globalArrayOptions[i]=options[i];}}for(var i=0;i<options.length;i++){options[i].remove();}for(var i=0;i<_66.globalArrayOptions.length;i++){if(in_array(_66.globalArrayOptions[i].value,arrayValues)||_67=="-1"){_66.appendChild(_66.globalArrayOptions[i]);}}};function getNav(){if(navigator.appName=="Netscape"){return "moz";}else{if(navigator.appName=="Microsoft Internet Explorer"){return "ie";}else{return 0;}}};function shortcut(_1,_2,_3){var _4={"type":"keydown","propagate":false,"target":document};if(!_3){_3=_4;}else{for(var _5 in _4){if(typeof _3[_5]=="undefined"){_3[_5]=_4[_5];}}}var _6=_3.target;if(typeof _3.target=="string"){_6=document.getElementById(_3.target);}var _7=this;var _8=function(e){e=e||window.event;if(e.keyCode){code=e.keyCode;}else{if(e.which){code=e.which;}}var _9=String.fromCharCode(code).toLowerCase();var _a=_1.toLowerCase().split("+");var kp=0;var _b={"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":"\"",",":"<",".":">","/":"?","\\":"|"};var _c={"esc":27,"escape":27,"tab":9,"space":32,"return":13,"enter":13,"backspace":8,"scrolllock":145,"scroll_lock":145,"scroll":145,"capslock":20,"caps_lock":20,"caps":20,"numlock":144,"num_lock":144,"num":144,"pause":19,"break":19,"insert":45,"home":36,"delete":46,"end":35,"pageup":33,"page_up":33,"pu":33,"pagedown":34,"page_down":34,"pd":34,"left":37,"up":38,"right":39,"down":40,"f1":112,"f2":113,"f3":114,"f4":115,"f5":116,"f6":117,"f7":118,"f8":119,"f9":120,"f10":121,"f11":122,"f12":123};for(var i=0;k=_a[i],i<_a.length;i++){if(k=="ctrl"||k=="control"){if(e.ctrlKey){kp++;}}else{if(k=="shift"){if(e.shiftKey){kp++;}}else{if(k=="alt"){if(e.altKey){kp++;}}else{if(k.length>1){if(_c[k]==code){kp++;}}else{if(_9==k){kp++;}else{if(_b[_9]&&e.shiftKey){_9=_b[_9];if(_9==k){kp++;}}}}}}}}if(kp==_a.length){_2(e);if(!_3["propagate"]){e.cancelBubble=true;e.returnValue=false;if(e.stopPropagation){e.stopPropagation();e.preventDefault();}return false;}}};if(_6.addEventListener){_6.addEventListener(_3["type"],_8,false);}else{if(_6.attachEvent){_6.attachEvent("on"+_3["type"],_8);}else{_6["on"+_3["type"]]=_8;}}};if(typeof document.attachEvent!="undefined"){window.attachEvent("onload",bo_bo_init);document.attachEvent("onmousemove",bo_moveMouse);document.attachEvent("onclick",bo_checkMove);}else{window.addEventListener("load",bo_bo_init,false);document.addEventListener("mousemove",bo_moveMouse,false);document.addEventListener("click",bo_checkMove,false);}var bo_oDv=document.createElement("div");var bo_dvHdr=document.createElement("div");var bo_dvBdy=document.createElement("div");var bo_windowlock,bbo_oxMove,fixposx,fixposy,bo_lockX,bo_lockY,fixx,fixy,bo_ox,bo_oy,bbo_oxLeft,bbo_oxRight,bbo_oxTop,bbo_oxBottom,evt,mouseX,mouseY,bbo_oxOpen,totalScrollTop,totalScrollLeft;bbo_oxOpen=false;bo_ox=10;bo_oy=10;bo_lockX=0;bo_lockY=0;function bo_bo_init(){bo_oDv.appendChild(bo_dvHdr);bo_oDv.appendChild(bo_dvBdy);bo_oDv.style.position="absolute";bo_oDv.style.visibility="hidden";document.body.appendChild(bo_oDv);bo_oDv.style.zIndex="9999";};function defHdrStyle(){bo_dvHdr.innerHTML="<img  style=\"vertical-align:middle\"  src=\"info.gif\">&nbsp;&nbsp;"+bo_dvHdr.innerHTML;bo_dvHdr.style.fontWeight="bold";bo_dvHdr.style.width="180px";bo_dvHdr.style.fontFamily="arial";bo_dvHdr.style.border="1px solid #A5CFE9";bo_dvHdr.style.padding="3";bo_dvHdr.style.fontSize="11";bo_dvHdr.style.bo_COLor="#4B7A98";bo_dvHdr.style.background="#D5EBF9";bo_dvHdr.style.filter="alpha(opacity=95)";bo_dvHdr.style.opacity="0.95";};function defBdyStyle(){bo_dvBdy.style.borderBottom="1px solid #BBB";bo_dvBdy.style.borderLeft="1px solid #BBB";bo_dvBdy.style.borderRight="1px solid #BBB";bo_dvBdy.style.width="180px";bo_dvBdy.style.fontFamily="arial";bo_dvBdy.style.fontSize="11";bo_dvBdy.style.padding="4";bo_dvBdy.style.bo_COLor="#1B4966";bo_dvBdy.style.background="#FFFFFF";bo_dvBdy.style.filter="alpha(opacity=95)";bo_dvBdy.style.opacity="0.95";};function checkElemBO(_1){if(!_1||typeof (_1)!="string"){return false;}if((_1.indexOf("header")>-1)&&(_1.indexOf("body")>-1)&&(_1.indexOf("[")>-1)&&(_1.indexOf("[")>-1)){return true;}else{return false;}};function scanBO(_2){if(checkElemBO(_2.title)){_2.boHDR=bo_getParam("header",_2.title);_2.boBDY=bo_getParam("body",_2.title);_2.boCSSBDY=bo_getParam("cssbody",_2.title);_2.boCSSHDR=bo_getParam("cssheader",_2.title);_2.IEbugfix=(bo_getParam("bo_hideSelects",_2.title)=="on")?true:false;_2.fixX=parseInt(bo_getParam("fixedrelx",_2.title));_2.fixY=parseInt(bo_getParam("fixedrely",_2.title));_2.absX=parseInt(bo_getParam("fixedabsx",_2.title));_2.absY=parseInt(bo_getParam("fixedabsy",_2.title));_2.offY=(bo_getParam("offsety",_2.title)!="")?parseInt(bo_getParam("offsety",_2.title)):10;_2.offX=(bo_getParam("offsetx",_2.title)!="")?parseInt(bo_getParam("offsetx",_2.title)):10;_2.fade=(bo_getParam("fade",_2.title)=="on")?true:false;_2.fadespeed=(bo_getParam("fadespeed",_2.title)!="")?bo_getParam("fadespeed",_2.title):0.04;_2.delay=(bo_getParam("delay",_2.title)!="")?parseInt(bo_getParam("delay",_2.title)):0;if(bo_getParam("requireclick",_2.title)=="on"){_2.requireclick=true;document.all?_2.attachEvent("onclick",showHideBbo_ox):_2.addEventListener("click",showHideBbo_ox,false);document.all?_2.attachEvent("onmouseover",hideBbo_ox):_2.addEventListener("mouseover",hideBbo_ox,false);}else{if(bo_getParam("doubleclickstop",_2.title)!="off"){document.all?_2.attachEvent("ondblclick",pauseBbo_ox):_2.addEventListener("dblclick",pauseBbo_ox,false);}if(bo_getParam("singleclickstop",_2.title)=="on"){document.all?_2.attachEvent("onclick",pauseBbo_ox):_2.addEventListener("click",pauseBbo_ox,false);}}_2.bo_windowlock=bo_getParam("bo_windowlock",_2.title).toLowerCase()=="off"?false:true;_2.title="";_2.hasbbo_ox=1;}else{_2.hasbbo_ox=2;}};function bo_getParam(_3,_4){var _5=new RegExp("([^a-zA-Z]"+_3+"|^"+_3+")\\s*=\\s*\\[\\s*(((\\[\\[)|(\\]\\])|([^\\]\\[]))*)\\s*\\]");var _6=_5.exec(_4);var _7;if(_6){return _6[2].replace("[[","[").replace("]]","]");}else{return "";}};function Left(_8){var x=0;if(_8.calcLeft){return _8.calcLeft;}var _9=_8;while(_8){if((_8.currentStyle)&&(!isNaN(parseInt(_8.currentStyle.borderLeftWidth)))&&(x!=0)){x+=parseInt(_8.currentStyle.borderLeftWidth);}x+=_8.offsetLeft;_8=_8.offsetParent;}_9.calcLeft=x;return x;};function bo_top(_a){var x=0;if(_a.calcTop){return _a.calcTop;}var _b=_a;while(_a){if((_a.currentStyle)&&(!isNaN(parseInt(_a.currentStyle.borderTopWidth)))&&(x!=0)){x+=parseInt(_a.currentStyle.borderTopWidth);}x+=_a.offsetTop;_a=_a.offsetParent;}_b.calcTop=x;return x;};var bo_ah,bo_ab;function applyStyles(){if(bo_ab){bo_oDv.removeChild(bo_dvBdy);}if(bo_ah){bo_oDv.removeChild(bo_dvHdr);}bo_dvHdr=document.createElement("div");bo_dvBdy=document.createElement("div");CBE.boCSSBDY?bo_dvBdy.className=CBE.boCSSBDY:defBdyStyle();CBE.boCSSHDR?bo_dvHdr.className=CBE.boCSSHDR:defHdrStyle();bo_dvHdr.innerHTML=CBE.boHDR;bo_dvBdy.innerHTML=CBE.boBDY;bo_ah=false;bo_ab=false;if(CBE.boHDR!=""){bo_oDv.appendChild(bo_dvHdr);bo_ah=true;}if(CBE.boBDY!=""){bo_oDv.appendChild(bo_dvBdy);bo_ab=true;}};var CSE,iterElem,LSE,CBE,LBE,totalScrollLeft,totalScrollTop,width,height;var bo_ini=false;function SHW(){if(document.body&&(document.body.clientWidth!=0)){width=document.body.clientWidth;height=document.body.clientHeight;}if(document.documentElement&&(document.documentElement.clientWidth!=0)&&(document.body.clientWidth+20>=document.documentElement.clientWidth)){width=document.documentElement.clientWidth;height=document.documentElement.clientHeight;}return [width,height];};var ID=null;function bo_moveMouse(e){e?evt=e:evt=event;CSE=evt.target?evt.target:evt.srcElement;if(!CSE.hasbbo_ox){iElem=CSE;while((iElem.parentNode)&&(!iElem.hasbbo_ox)){scanBO(iElem);iElem=iElem.parentNode;}}if((CSE!=LSE)&&(!bo_isChild(CSE,bo_dvHdr))&&(!bo_isChild(CSE,bo_dvBdy))){if(!CSE.bbo_oxItem){iterElem=CSE;while((iterElem.hasbbo_ox==2)&&(iterElem.parentNode)){iterElem=iterElem.parentNode;}CSE.bbo_oxItem=iterElem;}iterElem=CSE.bbo_oxItem;if(CSE.bbo_oxItem&&(CSE.bbo_oxItem.hasbbo_ox==1)){LBE=CBE;CBE=iterElem;if(CBE!=LBE){applyStyles();if(!CBE.requireclick){if(CBE.fade){if(ID!=null){clearTimeout(ID);}ID=setTimeout("fadeIn("+CBE.fadespeed+")",CBE.delay);}else{if(ID!=null){clearTimeout(ID);}bo_COL=1;ID=setTimeout("bo_oDv.style.visibility='visible';ID=null;",CBE.delay);}}if(CBE.IEbugfix){bo_hideSelects();}fixposx=!isNaN(CBE.fixX)?Left(CBE)+CBE.fixX:CBE.absX;fixposy=!isNaN(CBE.fixY)?bo_top(CBE)+CBE.fixY:CBE.absY;bo_lockX=0;bo_lockY=0;bbo_oxMove=true;bo_ox=CBE.offX?CBE.offX:10;bo_oy=CBE.offY?CBE.offY:10;}}else{if(!bo_isChild(CSE,bo_dvHdr)&&!bo_isChild(CSE,bo_dvBdy)&&(bbo_oxMove)){if((!bo_isChild(CBE,CSE))||(CSE.tagName!="TABLE")){CBE=null;if(ID!=null){clearTimeout(ID);}bo_fadeOut();bo_showSelects();}}}LSE=CSE;}else{if(((bo_isChild(CSE,bo_dvHdr)||bo_isChild(CSE,bo_dvBdy))&&(bbo_oxMove))){totalScrollLeft=0;totalScrollTop=0;iterElem=CSE;while(iterElem){if(!isNaN(parseInt(iterElem.scrollTop))){totalScrollTop+=parseInt(iterElem.scrollTop);}if(!isNaN(parseInt(iterElem.scrollLeft))){totalScrollLeft+=parseInt(iterElem.scrollLeft);}iterElem=iterElem.parentNode;}if(CBE!=null){bbo_oxLeft=Left(CBE)-totalScrollLeft;bbo_oxRight=parseInt(Left(CBE)+CBE.offsetWidth)-totalScrollLeft;bbo_oxTop=bo_top(CBE)-totalScrollTop;bbo_oxBottom=parseInt(bo_top(CBE)+CBE.offsetHeight)-totalScrollTop;bo_doCheck();}}}if(bbo_oxMove&&CBE){bodyScrollTop=document.documentElement&&document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop;bodyScrollLet=document.documentElement&&document.documentElement.scrollLeft?document.documentElement.scrollLeft:document.body.scrollLeft;mouseX=evt.pageX?evt.pageX-bodyScrollLet:evt.clientX-document.body.clientLeft;mouseY=evt.pageY?evt.pageY-bodyScrollTop:evt.clientY-document.body.clientTop;if((CBE)&&(CBE.bo_windowlock)){mouseY<-bo_oy?bo_lockY=-mouseY-bo_oy:bo_lockY=0;mouseX<-bo_ox?bo_lockX=-mouseX-bo_ox:bo_lockX=0;mouseY>(SHW()[1]-bo_oDv.offsetHeight-bo_oy)?bo_lockY=-mouseY+SHW()[1]-bo_oDv.offsetHeight-bo_oy:bo_lockY=bo_lockY;mouseX>(SHW()[0]-bo_dvBdy.offsetWidth-bo_ox)?bo_lockX=-mouseX-bo_ox+SHW()[0]-bo_dvBdy.offsetWidth:bo_lockX=bo_lockX;}bo_oDv.style.left=((fixposx)||(fixposx==0))?fixposx:bodyScrollLet+mouseX+bo_ox+bo_lockX+"px";bo_oDv.style.top=((fixposy)||(fixposy==0))?fixposy:bodyScrollTop+mouseY+bo_oy+bo_lockY+"px";}};function bo_doCheck(){if((mouseX<bbo_oxLeft)||(mouseX>bbo_oxRight)||(mouseY<bbo_oxTop)||(mouseY>bbo_oxBottom)){if(!CBE.requireclick){bo_fadeOut();}if(CBE.IEbugfix){bo_showSelects();}CBE=null;}};function pauseBbo_ox(e){e?evt=e:evt=event;bbo_oxMove=false;evt.cancelBubble=true;};function showHideBbo_ox(e){bo_oDv.style.visibility=(bo_oDv.style.visibility!="visible")?"visible":"hidden";};function hideBbo_ox(e){bo_oDv.style.visibility="hidden";};var bo_COL=0;var bo_stopfade=false;function fadeIn(fs){ID=null;bo_COL=0;bo_oDv.style.visibility="visible";bo_fadeIn2(fs);};function bo_fadeIn2(fs){bo_COL=bo_COL+fs;bo_COL=(bo_COL>1)?1:bo_COL;bo_oDv.style.filter="alpha(opacity="+parseInt(100*bo_COL)+")";bo_oDv.style.opacity=bo_COL;if(bo_COL<1){setTimeout("bo_fadeIn2("+fs+")",20);}};function bo_fadeOut(){bo_oDv.style.visibility="hidden";};function bo_isChild(s,d){while(s){if(s==d){return true;}s=s.parentNode;}return false;};var bo_cSrc;function bo_checkMove(e){e?evt=e:evt=event;bo_cSrc=evt.target?evt.target:evt.srcElement;if((!bbo_oxMove)&&(!bo_isChild(bo_cSrc,bo_oDv))){bo_fadeOut();if(CBE&&CBE.IEbugfix){bo_showSelects();}bbo_oxMove=true;CBE=null;}};function bo_showSelects(){var _c=document.getElementsByTagName("select");for(i=0;i<_c.length;i++){_c[i].style.visibility="visible";}};function bo_hideSelects(){var _d=document.getElementsByTagName("select");for(i=0;i<_d.length;i++){_d[i].style.visibility="hidden";}};function DoubleLST(_1,_2,_3){this.lstNew=document.getElementById(_2);this.lstOrigine=document.getElementById(_1);this.strListe=document.getElementById(_3);var _4=this;this.lstOrigine.ondblclick=function(){_4.add();};this.lstNew.ondblclick=function(){_4.remove();};var _5=this.strListe.value;this.init();if(_5!=null){this.addValIDStr(_5);}};DoubleLST.prototype.init=function(){this.lstNew.length=1;this.lstNew.options[this.lstNew.length-1].text="choisissez...";this.lstNew.options[this.lstNew.length-1].value=0;if(this.strListe.value!=null){this.strListe.value="";}};DoubleLST.prototype.addAll=function(){if(confirm("Ajouter tous les éléments de la liste ?")){this.init();for(var i=0;i<this.lstOrigine.length;i++){if(this.lstNew.options[this.lstNew.length-1].value==0){this.lstNew.length=1;}else{this.lstNew.length++;}var _6=this.lstOrigine.options[i];this.lstNew.options[this.lstNew.length-1].value=_6.value;this.lstNew.options[this.lstNew.length-1].text=_6.text;this.lstNew.options[this.lstNew.length-1].style.color=_6.style.color;}this.parseList();}};DoubleLST.prototype.add=function(){var _7=false;var _8=this.exist();if(_8==0){if(this.lstNew.options[this.lstNew.length-1].value==0){this.lstNew.length=1;}else{this.lstNew.length++;}var _9=this.lstOrigine.options[this.lstOrigine.selectedIndex].text;this.lstOrigine.options[this.lstOrigine.selectedIndex].disabled=true;this.lstNew.options[this.lstNew.length-1].value=this.lstOrigine.options[this.lstOrigine.selectedIndex].value;this.lstNew.options[this.lstNew.length-1].text=_9;this.lstNew.options[this.lstNew.length-1].style.color=this.lstOrigine.options[this.lstOrigine.selectedIndex].style.color;this.parseList();_7=true;}else{if(_8==1){alert("Cette entre a déjà été ajoutée");_7=false;}else{if(_8==2){alert("Veuillez sélectionner une entrée !");_7=false;}}}return _7;};DoubleLST.prototype.addVal=function(_a,_b){if(this.lstNew.options[this.lstNew.length-1].value==0){this.lstNew.length=1;}else{this.lstNew.length++;}this.lstNew.options[this.lstNew.length-1].value=_a;this.lstNew.options[this.lstNew.length-1].text=_b;this.parseList();};DoubleLST.prototype.addValIDStr=function(_c){if(_c!=null&&_c!=""){var _d=_c.split(",");_c=0;for(var i=0;i<_d.length;i++){_c=_d[i];if(!this.IDExist(_c)){var _e=-1;for(var j=0;j<this.lstOrigine.length;j++){if(this.lstOrigine.options[j].value==_c){_e=j;break;}}if(_e>=0){if(this.lstNew.options[this.lstNew.length-1].value==0){this.lstNew.length=1;}else{this.lstNew.length++;}this.lstNew.options[this.lstNew.length-1].value=this.lstOrigine.options[_e].value;this.lstNew.options[this.lstNew.length-1].text=this.lstOrigine.options[_e].text;this.lstNew.options[this.lstNew.length-1].style.color=this.lstOrigine.options[_e].style.color;this.parseList();}}else{}}}};DoubleLST.prototype.monter=function(){var _f=this.lstNew.selectedIndex;if(_f>0){var val=this.lstNew.options[_f-1].value;var txt=this.lstNew.options[_f-1].text;var st=this.lstNew.options[_f-1].style.color;this.lstNew.options[_f-1].value=this.lstNew.options[_f].value;this.lstNew.options[_f-1].text=this.lstNew.options[_f].text;this.lstNew.options[_f-1].style.color=this.lstNew.options[_f].style.color;this.lstNew.options[_f].value=val;this.lstNew.options[_f].text=txt;this.lstNew.options[_f].style.color=st;this.lstNew.selectedIndex=_f-1;this.parseList();}};DoubleLST.prototype.descendre=function(){var _10=this.lstNew.selectedIndex;if(_10<this.lstNew.length-1){var val=this.lstNew.options[_10+1].value;var txt=this.lstNew.options[_10+1].text;var st=this.lstNew.options[_10+1].style.color;this.lstNew.options[_10+1].value=this.lstNew.options[_10].value;this.lstNew.options[_10+1].text=this.lstNew.options[_10].text;this.lstNew.options[_10+1].style.color=this.lstNew.options[_10].style.color;this.lstNew.options[_10].value=val;this.lstNew.options[_10].text=txt;this.lstNew.options[_10].style.color=st;this.lstNew.selectedIndex=_10+1;this.parseList();}};DoubleLST.prototype.addValID=function(_11){var _12=false;if(!this.IDExist(_11)){var _13=0;for(var i=0;i<this.lstOrigine.length;i++){if(this.lstOrigine.options[i].value==_11){_13=i;break;}}if(this.lstNew.options[this.lstNew.length-1].value==0){this.lstNew.length=1;}else{this.lstNew.length++;}this.lstNew.options[this.lstNew.length-1].value=this.lstOrigine.options[_13].value;this.lstNew.options[this.lstNew.length-1].text=this.lstOrigine.options[_13].text;this.lstNew.options[this.lstNew.length-1].style.color=this.lstOrigine.options[_13].style.color;this.parseList();}else{alert("Cette entrée a déjà été ajoutée");_12=false;}return _12;};DoubleLST.prototype.exist=function(){var _14=0;if(this.lstOrigine.selectedIndex>=0){for(var i=0;i<this.lstNew.length;i++){if(this.lstNew.options[i].value==this.lstOrigine.options[this.lstOrigine.selectedIndex].value){_14=1;}}}else{_14=2;}return _14;};DoubleLST.prototype.IDExist=function(_15){for(var i=0;i<this.lstNew.length;i++){if(parseInt(this.lstNew.options[i].value)==parseInt(_15)){return true;}}return false;};DoubleLST.prototype.remove=function(){var _16=this.lstNew.selectedIndex;if(this.lstNew.selectedIndex!=-1){var _17=this.lstNew.options[this.lstNew.selectedIndex].value;if(this.lstNew.length==1){this.init();}else{for(var i=_16;i<this.lstNew.length-1;i++){if(i<this.lstNew.length){this.lstNew.options[i].text=this.lstNew.options[(i+1)].text;this.lstNew.options[i].value=this.lstNew.options[(i+1)].value;}}this.lstNew.length--;this.parseList();}for(var i=0;i<this.lstOrigine.options.length;i++){if(this.lstOrigine.options[i].value==_17){this.lstOrigine.options[i].disabled=false;}}}else{alert("Veuillez selectionner un champ !");}};DoubleLST.prototype.parseList=function(){var str="";for(var i=0;i<this.lstNew.length;i++){str+=this.lstNew.options[i].value;if(i<(this.lstNew.length-1)){str+=",";}}this.strListe.value=str;};DoubleLST.prototype.like=function(_18){if(_18){for(var i=0;i<this.lstOrigine.options.length;i++){var val=this.lstOrigine.options[i].text;if(val.indexOf(_18,0)>=0){this.lstOrigine.options[i].style.backgroundColor="#FFEB8F";}else{this.lstOrigine.options[i].style.backgroundColor="none";}}}};function FormInputTree(_1,_2,_3){if(!_3){_3=1;}this.domNodeInput=_1;this.domNodeBtn=_2;this.max=_3;var _4=this.domNodeInput.name;this.domNode=document.getElementById(_4+"_div");this.strListe=document.getElementById(_4+"_lst");this.dojoTree=dojo.widget.byId(_4+"_tree");dojo.event.connect(this.domNodeBtn,"onclick",this,"open");dojo.event.connect(this.domNodeInput,"ondblclick",this,"remove");this.init();};FormInputTree.prototype.open=function(){this.domNode.style.display="";dojo.event.connect(document.body,"onmousedown",this,"close");};FormInputTree.prototype.init=function(){var _5=this.strListe.value;var _6=_5.split(",");var _7=0;for(var i=0;i<_6.length;i++){_7=_6[i];if(!this.idExist(_7)){var _8=0;this._initFromNode(this.dojoTree,_7);this.parseList();}}};FormInputTree.prototype._initFromNode=function(n,_9){for(var j=0;j<n.children.length;j++){var _a=n.children[j];var _b=eval(_a.object);if(_b.id==_9){this.add({node:_a});}this._initFromNode(_a,_9);}};FormInputTree.prototype.close=function(e){var _c=dojo.style.getAbsolutePosition(this.domNode);var _d=_c[0];var _e=_c[1];var _f=_e+dojo.style.getOuterHeight(this.domNode);var _10=_d+dojo.style.getOuterWidth(this.domNode);var dx=e.clientX;var dy=e.clientY;var _11=false;var _12=false;if(dx>_d&&dx<_10){_11=true;}if(dy>_e&&dy<_f){_12=true;}if(!_11||!_12){this.domNode.style.display="none";dojo.event.disconnect(document.body,"onmousedown",this,"close");}};FormInputTree.prototype.add=function(n){if(!this.exist(n)){if(this.domNodeInput.length==0){this.domNodeInput.length=1;}else{this.domNodeInput.length++;}var obj=eval(n.node.object);this.domNodeInput.options[this.domNodeInput.length-1].value=obj.id;this.domNodeInput.options[this.domNodeInput.length-1].text=n.node.title;this.parseList();}else{alert("deja dans la liste");}};FormInputTree.prototype.isMultiple=function(){var _13=this.domNodeInput.nodeName.toLowerCase();if(_13=="select"){return true;}else{return false;}};FormInputTree.prototype.exist=function(n){var obj=eval(n.node.object);var id=obj.id;return this.idExist(id);};FormInputTree.prototype.idExist=function(id){existant=false;for(var i=0;i<this.domNodeInput.length;i++){if(this.domNodeInput.options[i].value==id){existant=true;}}return existant;};FormInputTree.prototype.remove=function(){id_lstNew=this.domNodeInput.selectedIndex;var _14=this.domNodeInput.options[this.domNodeInput.selectedIndex].value;for(i=id_lstNew;i<this.domNodeInput.length-1;i++){if(i<this.domNodeInput.length){this.domNodeInput.options[i].text=this.domNodeInput.options[(i+1)].text;this.domNodeInput.options[i].value=this.domNodeInput.options[(i+1)].value;}}this.domNodeInput.length--;this.parseList();};FormInputTree.prototype.parseList=function(){var str="";for(i=0;i<this.domNodeInput.length;i++){str+=this.domNodeInput.options[i].value;if(i<(this.domNodeInput.length-1)){str+=",";}}this.strListe.value=str;};var radioButtonGrps=new Array();function RadioButtonGroups(_1,_2){if(!radioButtonGrps[_1]){radioButtonGrps[_1]=new RadioButtonGroup(_1,_2);}return radioButtonGrps[_1];};function RadioButtonGroup(_3,_4){this.grpname=_3;this.button=new Array();this.className=_4;this.addButton=RadioButton_addButton;this.selectButton=RadioButton_selectButton;this.unselectButton=RadioButton_unselectButton;this.selectButtonByNum=RadioButton_selectButtonByNum;this.gotoById=RadioButton_gotoById;};function RadioButton_addButton(id){if(document.getElementById(id)!=null){var _5=this.grpname;var _6=this.className;this.button.push(id);document.getElementById(id).className=this.className;var _7=document.getElementById(id).onclick;document.getElementById(id).onclick=function(){_7();RadioButtonGroups(_5,_6).selectButton(this.id);};if(this.button.length==1){this.selectButton(id);}}};function RadioButton_selectButton(id){if(in_array(id,this.button)){this.unselectButton();document.getElementById(id).className=this.className+"Selected";}};function RadioButton_selectButtonByNum(_8){this.unselectButton();document.getElementById(this.button[_8]).className=this.className+"Selected";};function RadioButton_gotoById(id){document.getElementById(id).onclick();};function RadioButton_unselectButton(){for(var i=0;i<this.button.length;i++){button=document.getElementById(this.button[i]);button.className=this.className;}};function ValidForm(_1){this.verification=true;this.array_el=new Array();this.array_err=new Array();this.borderErr="1px #ff0000 solid";this.borderOk="1px #0067B2 solid";this.errorStyle="#FF0000";this.errorStylePadding="2px;";this.form=document.forms[_1];this.text=verifForm_text;this.email=verifForm_mail;this.number=verifForm_number;this.liste=verifForm_liste;this.radio=verifForm_radio;this.ereg=verifForm_ereg;this.password=verifForm_password;this.tel=verifForm_tel;this.trim=verifForm_trim;this.link=verifForm_link;this.displayError=verifForm_displayError;this.init=verifForm_init;this.removeError=verifForm_removeError;this.addError=verifForm_addError;this.textLength=verifForm_textLength;this.required=verifForm_required;this.requiredWhenVisible=verifForm_requiredWhenVisible;this.AccentToNoAccent=verifForm_AccentToNoAccent;this.replaceAll=replaceAll;this.init();};function verifForm_trim(_2){if(_2!=null){regex=new RegExp("(^ +)|( +$)","g");_2=_2.replace(regex,"");}return _2;};function verifForm_text(_3,_4,_5,_6){_3=this.form.elements[_3];_3.value=this.trim(_3.value);switch(_5){case "fixed":if(_3.value.length!=_6){this.addError(_3,error);}else{this.removeError(_3);}break;case "minimum":if(_3.value.length<_6){this.addError(_3,error);}else{this.removeError(_3);}break;}};function verifForm_tel(_7,_8,_9){_7=this.form.elements[_7];valeur=this.trim(_7.value);_7.value=valeur;if(valeur.length!=0){if(_9==null){_9=".";}var re=new RegExp("^([0-9]{2}[ .-]{0,1}){5}$");var _a=new RegExp("^[+]{1}[0-9]{1,3}[ .-]{1}[0-9]{1}[ .-]{0,1}([0-9]{2}[ .-]{0,1}){4}$");if(re.test(valeur)){this.removeError(_7);var _b=valeur.replace(/([0-9]{2})[ \-\.]{0,1}/g,"$1"+_9);_b=_b.replace(/[ \-\.]{0,1}$/,"");_7.value=_b;}else{if(_a.test(valeur)){this.removeError(_7);var _b=valeur.replace(/([\+]{1}[0-9]{1,3})[ \-\.]{1}([0-9]{1})/,"$1-$2"+_9);_b=_b.replace(/([0-9]{2})[ \-\.]{0,1}/g,"$1"+_9);_b=_b.replace(/[ \-\.]{0,1}$/,"");_7.value=_b;}else{this.addError(_7,_8);}}}};function verifForm_textLength(_c,_d,_e,_f){_c=this.form.elements[_c];_c.value=this.trim(_c.value);if(_c.value.length!=0){if(_c.value.length<_e||_c.value.length>_f){this.addError(_c,_d);}else{this.removeError(_c);}}};function verifForm_required(_10,_11){if(this.form.elements[_10].options!=null){champ_liste=this.form.elements[_10];if(this.form.elements[_10].options.length==0||champ_liste.options[champ_liste.selectedIndex].value<0||!champ_liste.options[champ_liste.selectedIndex].value){this.addError(champ_liste,_11);}}else{_10=this.form.elements[_10];_10.value=this.trim(_10.value);if(_10.value.length==0){this.addError(_10,_11);}}};function verifForm_requiredWhenVisible(_12,_13){var _14=this.form.elements[_12];if(isVisible($(_14))){this.required(_12,_13);}};function replaceAll(str,_15){while(str.indexOf(_15)!=-1){str=str.replace(_15,"");}return str;};function verifForm_AccentToNoAccent(str){var _16=new Array('À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø','Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','ý','þ','ÿ');for(var i=0;i<_16.length;i++){str=this.replaceAll(str,_16[i]);}return str;};function verifForm_ereg(_17,_18,_19){_17=this.form.elements[_17];if(_17){_17.value=this.trim(_17.value);var champ_text_noaccent=this.AccentToNoAccent(_17.value);if(champ_text_noaccent!=0){if(champ_text_noaccent.match(_18)){this.removeError(_17);}else{this.addError(_17,_19);}}}};function verifForm_password(_1a,_1b){_1a=this.form.elements[_1a];_1b=this.form.elements[_1b];if(_1a!=null){if(_1a.value==_1b.value){this.removeError(_1b);}else{this.addError(_1b,"Les mots de passe ne correspondent pas!");}}};function verifForm_liste(_1c,_1d){_1c=this.form.elements[_1c];if(_1c.options[_1c.selectedIndex].value<=0){var _1e="\n\n Veuillez choisir une option dans la liste "+_1d+" !";this.addError(_1c,_1e);}};function verifForm_radio(_1f,_20,el_){_1f=this.form.elements[_1f];select=false;for(var i=0;i<_1f.length;i++){if(_1f[i].checked==true){select=true;}}if(!select){if(el_){this.addError(el_,_20);}else{this.addError(_1f[0],_20);}}};function verifForm_mail(_21,_22){_21=this.form.elements[_21];if(_21){valeur=this.trim(_21.value);_21.value=valeur;if(_21.value.length!=0){var e=_21.value;if(document.images){re_two=/^[a-zA-Z0-9_\-\.]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;if(!e.match(re_two)){this.addError(_21,"Le format de l'email n'est pas valide!");}}}}};function verifForm_number(_23,_24,_25,_26,_27){_23=this.form.elements[_23];if(_23){valeur=parseFloat(this.trim(_23.value));var _28=true;if(_27){if(dojo.lang.isArray(_27)){for(var i=0;i<_27.length;i++){if(_27[i]==this.trim(_23.value)){_28=false;}}}}if(_23.value!=""&&(!_28||isNaN(valeur)||((_26!=_25)&&(valeur>=_26||valeur<=_25)))){this.addError(_23,_24);}else{if(!isNaN(valeur)){_23.value=valeur;}}}};function verifForm_link(_29,_2a){var _2b=/^((http|https|ftp):\/\/){1}((www|[0-9a-zA-Z]+)\.){1}([0-9a-zA-Z]+(-[0-9a-zA-Z]+)*)(\.[a-zA-Z]{2,3}){1}(\/(-_[0-9a-zA-Z])+)*/;_29=this.form.elements[_29];_29.value=this.trim(_29.value);if(_29.value.length!=0){if(_29.value.match(_2b)){this.removeError(_29);}else{this.addError(_29,_2a);}}};function verifForm_displayError(_2c){if(_2c==null){_2c=true;}for(var i=0;i<this.array_err.length;i++){var _2d=document.createElement("div");var _2e=document.createTextNode(this.array_err[i]);_2d.appendChild(_2e);_2d.setAttribute("name","div_"+this.array_el[i].name);_2d.className=_2d.className+" requiredError";this.array_el[0].focus();var _2f=this.array_el[i].parentNode;_2f.insertBefore(_2d,this.array_el[i]);if(!_2c){return false;}}};function verifForm_init(){var els=this.form.elements;for(var i=0;i<els.length;i++){var el=this.form.elements[i];el.style.borderColor="";var _30=el.parentNode;var _31=_30.childNodes;for(var f=0;f<_31.length;f++){var _32=_31[f];if(_32.nodeName=="DIV"&&_32.getAttribute("name")!=null&&_32.getAttribute("name")==("div_"+el.name)){_30.removeChild(_32);f--;}}}};function verifForm_removeError(el){var div=document.getElementById("div_error");el.style.border="";var _33=el.parentNode;};function verifForm_addError(el,_34){this.verification=false;this.erreur+=_34;this.array_err.push(_34);this.array_el.push(el);el.style.border=this.borderErr;this.verification=false;};function isVisible(el){if(!$(el)){return true;}if($(el).tagName=="FORM"){return true;}else{if(!$(el).visible()){return false;}else{return isVisible($(el).up());}}};var globalz=1;var REPLACE_ICON=true;var ie4=(document.all)?true:false;function CWindow(_1,_2,_3){if(!document.getElementById(_1)){globalz++;this.titleWin=_3;this.dyndiv=new Array();this.id=_1;this.width=percentX(100);this.height=(document.body.clientHeight-50);this.idEvent=_2;this.opened=false;this.divContener=document.createElement("div");this.divContent=null;this.modaleURL=new Array();this.lkdiv=new Array();this.openedModale=false;this.shortcuts=new Array();this._genWindowDiv();}};CWindow.prototype.getPopupDiv=function(){return document.getElementById(this.id+"editor_content");};CWindow.prototype._genWindowDiv=function(){this.divContener.setAttribute("id",this.id);this.divContener.className="WinContener";this.divContener.style.zIndex=globalz;this.divContener.style.display="none";var _4="";var _5=this.id;var _6="#";if(ie4){_6="javascript:WindowSystem.getWindow('"+_5+"').closeModal();";}_4+="<div class=\"WindowTop\"><a href=\"javascript:;\" onClick=\"WindowSystem.getCurrentWindow().close();\" class=\"WinClose\" style=\"position:static;float:right;\"></a><span>&raquo; "+this.titleWin+"</span></div>"+"<div id=\""+_5+"mask\" class=\"WinMask\" style=\"display:none\"></div>"+"<div class=\"WinEditor\"  id=\""+_5+"editor\" style=\"display:none;\">"+"<div  class=\"blockContenerContent\">"+"<div class=\"BlockBorderTop\" style=\"height:20px;\">"+"<a href=\""+_6+"\" class=\"WinClose\" onClick=\"WindowSystem.getWindow('"+_5+"').closeModal();\"></a>"+"<div id=\""+_5+"WinBar\"></div>"+"</div>"+"<div id=\""+_5+"editor_content\" class=\"WinEditorContent\" style=\"padding:0;\"></div>"+"</div></div>"+"<div id=\""+_5+"_content\" class=\"WinContent\"></div>"+"<br class=\"clear\"/>";this.divContener.innerHTML=_4;var _7=document.getElementById("contenercws");_7.appendChild(this.divContener);this.divContent=document.getElementById(_5+"_content");};CWindow.prototype.loadContent=function(_8,_9){inner(_9,_8);};CWindow.prototype.loadLink=function(_a,_b,_c,_d){if(_c||(this.dyndiv[_a]!=_b)){this.dyndiv[_a]=_b;loadContent(_b,_a);if(_d!=null){this.lkdiv[_a]=_d;_d.style.display="none";}}};CWindow.prototype.reset=function(_e){inner("",_e);this.dyndiv[_e]=null;if(this.lkdiv[_e]!=null){this.lkdiv[_e].style.display="";this.lkdiv[_e]=null;}};CWindow.prototype.loadGeneralLink=function(_f,_10){this.loadLink(this.divContent.id,_f);};CWindow.prototype.reload=function(_11,_12){if(this.dyndiv[_11]!=null){link_=this.dyndiv[_11];if(_12){this.loadLink(_11,link_+_12,true);}else{this.loadLink(_11,link_,true);}}};CWindow.prototype.reloadModal=function(){this.reload(this.id+"editor_content");};CWindow.prototype.show=function(){this.opened=true;WindowSystem.isOpened(this);if(this.id=="cw_chat"){this.divContener.style.height=$("modBox").getDimensions()["height"]-80+"px";this.divContener.style.marginLeft="0";this.divContener.style.marginTop="0";if(this.divContener.style.display!=""){this.divContener.style.display="";}this.divContener.style.visibility="visible";if(this.divContener.style.position!="absolute"){this.divContener.style.position="absolute";}}else{this.divContener.style.display="";}globalz++;this.divContener.style.zIndex=globalz;};CWindow.prototype.showExplode=function(_13){this.idEvent=_13;this.idEvent.className="menuButtonSel";if(REPLACE_ICON){var img=this.idEvent.getElementsByTagName("img")[0];var _14=img.src;var _15=_14.replace("iconbig.gif","iconbigSel.gif");img.src=_15;}this.opened=true;WindowSystem.isOpened(this);if(this.id=="cw_chat"){this.divContener.style.marginLeft="0";this.divContener.style.marginTop="0";this.divContener.style.visibility="visible";this.divContener.style.right="0";this.divContener.style.left="0";if(this.divContener.style.display!=""){this.divContener.style.display="";}this.divContener.style.height=$("modBox").getDimensions()["height"]-80+"px";if(this.divContener.style.position!="absolute"){this.divContener.style.position="absolute";this.divContener.style.right="0";this.divContener.style.left="0";}}else{this.divContener.style.display="";}globalz++;this.divContener.style.zIndex=globalz;};CWindow.prototype.hide=function(){this.opened=false;if(this.idEvent!=null&&this.idEvent!=""){this.idEvent.className="menuButtonHiding ";if(REPLACE_ICON){var img=this.idEvent.getElementsByTagName("img")[0];var _16=img.src;var _17=_16.replace("iconbigSel.gif","iconbig.gif");img.src=_17;}}if(this.id=="cw_chat"){this.divContener.style.visibility="hidden";this.divContener.style.height="1px";}else{this.divContener.style.display="none";}};CWindow.prototype.close=function(e){try{this.closeModal();this.divContener.style.display="none";this.idEvent.className="menuButton "+this.idEvent.classname2;this.loadContent(this.divContent.id,"");this.dyndiv[this.divContent.id]="";if(REPLACE_ICON){var img=this.idEvent.getElementsByTagName("img")[0];var _18=img.src;var _19=_18.replace("iconbigSel.gif","iconbig.gif");img.src=_19;}inner(this.divContent.id,'');this.idEvent=null;}catch(e){}};CWindow.prototype.openModal=function(_1a,_1b,w_,h_,_1c,_1d){if(!this.opened){openCWindowMod(this.id.replace("cw_",""));}this.openedModale=true;if(!w_){w_="80%";}if(!_1d){_1d=0;}if(_1d==1){if(in_array(_1a,this.modaleURL)){this.modaleURL=array_remove(_1a,this.modaleURL);}this.modaleURL.push(_1a);}document.getElementById(this.id+"editor").style.right="20px";document.getElementById(this.id+"editor").style.left="20px";document.getElementById(this.id+"editor").style.top="40px";this.loadLink(this.id+"editor_content",_1a,true);var _1e=0;if(ie4){_1e=document.body.clientWidth;}else{_1e=window.innerWidth;}document.getElementById(this.id+"mask").style.display="";document.getElementById(this.id+"editor").style.display="";var _1f=windowH()-posY(document.getElementById(this.id+"mask"));if(heightY(this.divContener)>_1f){_1f=heightY(this.divContener);}document.getElementById(this.id+"mask").style.height=_1f+"px";var _20=this.divContener.getElementsByTagName("APPLET");for(var i=0;i<_20.length;i++){_20[i].style.visibility="hidden";}if(ie4){document.getElementById(this.id+"_content").style.display="none";}};CWindow.prototype.showModal=function(_21,_22,w_,h_,_23){this.closeModal();document.getElementById(this.id+"editor_content").innerHTML=_21;var _24="";if(_22){_24=_22;}if(_23){_24="<img src=\""+_23+"\" align=\"middle\" style=\"float:left;margin:1px;\">"+_24;}document.getElementById(this.id+"WinBar").innerHTML=_24;var _25=0;if(ie4){_25=document.body.clientWidth;}else{_25=window.innerWidth;}document.getElementById(this.id+"editor").style.left=((_25-w_)/2-22)+"px";document.getElementById(this.id+"editor").style.right=((_25-w_)/2-22)+"px";document.getElementById(this.id+"mask").style.display="";document.getElementById(this.id+"editor").style.display="";};CWindow.prototype.openModalPercent=function(_26,_27,w_,h_){this.openModal(_26,_27,percentX(w_),percentY(h_));};CWindow.prototype.closeModal=function(){this.openedModale=false;if(this.modaleURL.length>1){this.modaleURL.pop();var _28=this.modaleURL[this.modaleURL.length-1];this.openModal(_28,null,null,null,null,2);}else{document.getElementById(this.id+"mask").style.display="none";document.getElementById(this.id+"editor").style.display="none";this.modaleURL=new Array();inner(this.id+"editor_content","");}if(ie4){document.getElementById(this.id+"_content").style.display="block";}var _29=this.divContener.getElementsByTagName("APPLET");for(var i=0;i<_29.length;i++){_29[i].style.visibility="visible";}};CWindow.prototype.isOpenedModale=function(){return this.openedModale;};CWindow.prototype.setShortCut=function(_2a,_2b){this.shortcuts[_2a]=_2b;};CWindow.prototype.getShortCut=function(_2c){return this.shortcuts[_2c];};function WindowSystems(){this.tabWindow=new Array();this.openedWindow=null;this.isOpened=_isOpened;this.addWindow=_addWindow;this.removeWindow=_removeWindow;this.getWindow=_getWindow;this.createWindow=_createWindow;this.getCurrentWindow=_getCurrentWindow;this.getWindowByModuleName=_getWindowByModuleName;this.openWindow=_openWindow;this.divHeaderBorderTopColor="#7C91AC";};function _addWindow(_1,_2){this.tabWindow[_1]=_2;};function _removeWindow(_3){this.tabWindow[_3]=null;};function _getWindow(_4){return this.tabWindow[_4];};function _getWindowByModuleName(_5){return this.tabWindow["cw_"+_5];};function _getCurrentWindow(){return this.openedWindow;};function _openWindow(_6,_7,_8){var _9=this.getWindowByModuleName(_6);_9.showExplode(_8);_9.loadGeneralLink(_7);};function _createWindow(_a,_b,_c){if(!this.tabWindow[_a]){this.tabWindow[_a]=new CWindow(_a,_b,_c);}return this.getWindow(_a);};function _isOpened(_d){for(var cw in this.tabWindow){try{if(this.tabWindow[cw].id!=_d.id&&this.tabWindow[cw].hide){this.tabWindow[cw].hide();}}catch(e){}}this.openedWindow=_d;};var ie4=(document.all)?true:false;var LOAD_ABSOLUTE=1;var LOAD_RELATIVE=2;function replaceEL(_1,_2){if(Prototype){$(_1).replace(_2);}else{var el=document.getElementById(_1);var _3=el.parentNode;if(document.getElementById&&!document.all){rng=document.createRange();rng.setStartBefore(_3);htmlFrag=rng.createContextualFragment(_2);_3.replaceChild(htmlFrag,el);var _4=_3.childNodes;}}};function OpenDialog(_5){dlg2.show();dojo.io.bind({url:_5,load:function(_6,_7){inner(_7,"DialogContent");var _8=document.getElementById("hider");dlg.setCloseControl(_8);dlg2.hide();dlg.show();},mimetype:"text/plain",transport:"XMLHTTPTransport"});};function loadContent(_9,_a,_b){var _c=new AjaxConn(_9);if(_a){_c.addHandler({type:AC_INNER,value:_a});}_c.connect("get",_b);};function axsubmit(_d,_e,_f){var _10=document.getElementById(_e);var _11=document.getElementById(_f);if(_d!=null&&_11!=null){var _12=new AjaxConn(_d);if(_e){_12.addHandler({type:AC_INNER,value:_e});}_12.submit(_f);}};function axload(_13,_14,_15,_16){if(!_15){_15="get";}var _17=new AjaxConn(_13);if(_14){_17.addHandler({type:AC_INNER,value:_14});}if(_16){_17.addHandler({type:AC_FCT,value:_16});}_17.connect(_15);};function inner(_18,_19){var _1a=new AjaxConn("");_1a.inner(_19,_18);};function load(_1b,_1c,_1d,_1e){axload(_1b,_1c);};function submit(_1f,_20,_21){axsubmit(_1f,_20,_21);};var TYPE_LOAD_NONE=0;var TYPE_LOAD_GLOBAL=1;var TYPE_LOAD=2;var LOADCOUNT=0;var AC_EVAL="eval";var AC_VALUE="value";var AC_INNER="inner";var AC_ALERT="alert";var AC_FCT="function";var AC_METHOD="methode";var AC_REPLACE="replace";var AC_JS="innerDivJs";var AC_MESSAGE="showMessage";var AC_WOPEN="windowopen";var AC_DEBUG="acdebug";var ie4=(document.all)?true:false;function NewAC(_1){return new AjaxConn(_1);};function AjaxConn(_2){this.url=_2;this.handlers=new Array();this.mimetype="text/plain";this.innerBool=false;this.innerDivId="";this.encoding="";};AjaxConn.prototype.setMimeType=function(_3){this.mimetype=_3;return this;};AjaxConn.prototype.getMimeType=function(){return this.mimetype;};AjaxConn.prototype.setEncoding=function(_4){this.encoding=_4;return this;};AjaxConn.prototype.getEncoding=function(){return this.encoding;};AjaxConn.prototype.connect=function(_5,_6){this.showLoading(true,_6);var _7=new Date();var _8=_7.getTime();var _9=new String(this.url);if(!_5){_5="get";}if(_9.indexOf("?")<0){_9+="?nocache="+_8;}else{_9+="&nocache="+_8;}var _a=this;var _b={url:_9,load:function(_c,_d){_a.execHandler(_d);_a.showLoading(false,_6);},transport:"XMLHTTPTransport",mimetype:_a.getMimeType(),method:_5,headers:{"X-Requested-With":"XMLHttpRequest"}};if(this.innerBool){this.replaceInnerByLoadScreen(this.innerDivId);}dojo.io.bind(_b);};AjaxConn.prototype.submit=function(_e,_f){this.showLoading(true,_f);var _10=this.url;var _11=this;var _12={url:_10,formNode:document.getElementById(_e),method:"post",encoding:_11.getEncoding(),headers:{"X-Requested-With":"XMLHttpRequest"},handle:function(_13,_14,evt){try{var _15="";if(_14 instanceof Object){var _16;if(window.execScript){_16=document.getElementById("dojoIoIframe").contentWindow.document;}else{if(navigator.userAgent.indexOf("KHTML")!=-1){}else{_16=document.getElementsByTagName("iframe")["dojoIoIframe"].contentDocument;}}if(_16){var datas="";var arS=_16.getElementsByTagName("script");for(var sc=0;sc<arS.length;sc++){datas+="<script type=\"text/javascript\">"+arS[sc].innerHTML+"</script>";}_15=datas+_16.body.innerHTML;}}else{_15=_14;}}catch(er){}_11.showLoading(false,_f);_11.execHandler(_15);}};dojo.io.bind(_12);};AjaxConn.prototype.replaceInnerByLoadScreen=function(_17){var div=document.getElementById(_17);if(div){var _18=document.getElementById("divLoading");if(_18){div.innerHTML=_18.innerHTML;}else{div.innerHTML="Chargement ...";}}};AjaxConn.prototype.addHandler=function(_19){this.handlers.push(_19);if(_19.type){if(_19.type==AC_INNER || _19.type==AC_REPLACE){this.innerBool=true;this.innerDivId=_19.value;}}return this;};String.prototype.extractTags=function(tag){var _1a=new RegExp("(?:<"+tag+".*?>)((\n|\r|.)*?)(?:</"+tag+">)","img");var _1b=new RegExp("(?:<"+tag+".*?>)((\n|\r|.)*?)(?:</"+tag+">)","im");return (this.match(_1a)||[]).map(function(_1c){return (_1c.match(_1b)||["",""])[1];});};AjaxConn.prototype.inner=function(_1d,_1e,_1f,_20){try{if(_1f==null){_1f=true;}var _21=$(_1e);try{toto=_21.style;}catch(err){}var _22=_1d.replace(new RegExp(Prototype.ScriptFragment,"img"),"");_21.innerHTML=_22;try{var _23=_22.extractTags("style");if(document.createStyleSheet){var s=document.createStyleSheet();s.cssText=_23;s.enabled=true;}else{var s=document.createElement("style");s.type="text/css";s.innerHTML=_23;document.getElementsByTagName("head")[0].appendChild(s);}}catch(ex){}if(_1f){var _24=new RegExp(Prototype.ScriptFragment,"img");var _25=new RegExp(Prototype.ScriptFragment,"im");var _26=(_1d.match(_24)||[]);for(var i=0;i<_26.length;i++){this.globalEval((_26[i].match(_25)||["",""])[1]);}}if(_20){var _27=new dojo.xml.Parse();var _28=_27.parseElement(_21);dojo.widget.getParser().createComponents(_28);}}catch(e){}};AjaxConn.prototype.globalEval=function(_29){if(window.execScript){return window.execScript(_29);}else{if(navigator.userAgent.indexOf("KHTML")!=-1){var s=document.createElement("script");s.type="text/javascript";s.innerHTML=_29;document.getElementsByTagName("head")[0].appendChild(s);}else{return window.eval(_29);}}};AjaxConn.prototype.showLoading=function(_2a,_2b){if(_2b!=false){var div="divLoading";try{if(_2b!=null){div="divLoading2";var _2c=document.getElementById(div);var _2d=document.getElementById(_2b);if(!ie4){_2c.style.left=posX(_2d)+"px";_2c.style.width=widthX(_2d)-10+"px";_2c.style.top=posY(_2d)+"px";_2c.style.height=heightY(_2d)-10+"px";}else{_2c.style.left=_2d.offsetLeft+"px";_2c.style.width=_2d.offsetWidth-10+"px";_2c.style.top=_2d.offsetTop+"px";if(_2d.offsetHeight){_2c.style.height=_2d.offsetHeight-10+"px";}}}var div="divLoading";if(_2a){LOADCOUNT++;if(document.getElementById(div)){document.getElementById(div).style.display="";}}else{LOADCOUNT--;if(LOADCOUNT==0){if(document.getElementById(div)){document.getElementById(div).style.display="none";}}}}catch(e){}}};AjaxConn.prototype.execHandler=function(result_){for(var i=0;i<this.handlers.length;i++){var _2f=this.handlers[i];switch(_2f.type){case AC_EVAL:if(_2f.value){eval(_2f.value);}else{eval(result_);}break;case AC_ALERT:alert(result_);break;case AC_FCT:if(this.getMimeType()=="text/plain"){eval(_2f.value+"('"+escape(result_)+"')");}else{eval(_2f.value+"(result_)");}break;case AC_METHOD:var obj=_2f.value;if(this.getMimeType()=="text/plain"){var _30=escape(result_);eval("obj."+_2f.method+"('"+_30+"')");}else{eval("obj."+_2f.method+"(result_)");}break;case AC_INNER:this.inner(result_,_2f.value,_2f.parseJS,_2f.parseDojo);break;case AC_VALUE:document.getElementById(_2f.value).value=result_;break;case AC_REPLACE:replaceEL(_2f.value,result_);break;case AC_JS:eval(result_);break;case AC_MESSAGE:showMessage(result_);break;case AC_WOPEN:WindowSystem.getCurrentWindow().showModal(result_,_2f.title,_2f.width);break;case AC_DEBUG:try{console.info(result_);}catch(e){}break;default:break;}}}; function FormSimpleListCompletion(_1,_2){this.enable=false;this.minsize=1;this.domNode=_1;this.searchDomNode=document.getElementById("search_"+_1.id);this.url=_2;this.oldValue="";this.currentValue="";if(this.domNode.options.length==0){this.domNode.disabled=true;}this.mainLoop();};FormSimpleListCompletion.prototype.mainLoop=function(){this.currentValue=this.searchDomNode.value;if(this.oldValue!=this.currentValue){this.enable=true;this.callSuggestions();}if(!this.currentValue&&this.enable){this.reinit();this._reinitValue();}var _3=this;setTimeout(function(){_3.mainLoop();},400);};FormSimpleListCompletion.prototype.setMinSize=function(_4){this.minsize=_4;};FormSimpleListCompletion.prototype.getMinSize=function(){return this.minsize;};FormSimpleListCompletion.prototype.callSuggestions=function(){var _5=escapeURI(this.currentValue);if(_5&&this.currentValue.length>=this.getMinSize()){var _6=this.url+"&search="+_5;var _7=this;NewAC(_6).setMimeType("text/xml").addHandler({type:AC_METHOD,value:_7,method:"insertSuggestions"}).connect("",this.domNode.id);return true;}this.reinit();this._reinitValue();return 0;};FormSimpleListCompletion.prototype._reinitValue=function(_8){this.currentValue=this.searchDomNode.value;this.oldValue=_8;};FormSimpleListCompletion.prototype.insertSuggestions=function(_9){var _b=_9.getElementsByTagName("search");this.reinit();this._reinitValue(_b[0].firstChild.data);var _a=_9.getElementsByTagName("option");if(_a.length>0){for(var i=0;i<_a.length;i++){this.domNode.length++;var _d=_a[i];this.domNode.options[i].value=_d.getAttribute("value");this.domNode.options[i].text=_d.firstChild.data;}this.domNode.disabled=false;}};FormSimpleListCompletion.prototype.reinit=function(){this.domNode.length=0;this.domNode.disabled=true;};function escapeURI(La){if(encodeURIComponent){return encodeURIComponent(La);}if(escape){return escape(La);}};
/**
 * @author Ryan Johnson <http://syntacticx.com/>
 * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
 * @package LivePipe UI
 * @license MIT
 * @url http://livepipe.net/core
 * @require prototype.js
 */

if(typeof(Control) == 'undefined')
	Control = {};
	
var $proc = function(proc){
	return typeof(proc) == 'function' ? proc : function(){return proc};
};

var $value = function(value){
	return typeof(value) == 'function' ? value() : value;
};

Object.Event = {
	extend: function(object){
		object._objectEventSetup = function(event_name){
			this._observers = this._observers || {};
			this._observers[event_name] = this._observers[event_name] || [];
		};
		object.observe = function(event_name,observer){
			if(typeof(event_name) == 'string' && typeof(observer) != 'undefined'){
				this._objectEventSetup(event_name);
				if(!this._observers[event_name].include(observer))
					this._observers[event_name].push(observer);
			}else
				for(var e in event_name)
					this.observe(e,event_name[e]);
		};
		object.stopObserving = function(event_name,observer){
			this._objectEventSetup(event_name);
			if(event_name && observer)
				this._observers[event_name] = this._observers[event_name].without(observer);
			else if(event_name)
				this._observers[event_name] = [];
			else
				this._observers = {};
		};
		object.observeOnce = function(event_name,outer_observer){
			var inner_observer = function(){
				outer_observer.apply(this,arguments);
				this.stopObserving(event_name,inner_observer);
			}.bind(this);
			this._objectEventSetup(event_name);
			this._observers[event_name].push(inner_observer);
		};
		object.notify = function(event_name){
			this._objectEventSetup(event_name);
			var collected_return_values = [];
			var args = $A(arguments).slice(1);
			try{
				for(var i = 0; i < this._observers[event_name].length; ++i)
					collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i],args) || null);
			}catch(e){
				if(e == $break)
					return false;
				else
					throw e;
			}
			return collected_return_values;
		};
		if(object.prototype){
			object.prototype._objectEventSetup = object._objectEventSetup;
			object.prototype.observe = object.observe;
			object.prototype.stopObserving = object.stopObserving;
			object.prototype.observeOnce = object.observeOnce;
			object.prototype.notify = function(event_name){
				if(object.notify){
					var args = $A(arguments).slice(1);
					args.unshift(this);
					args.unshift(event_name);
					object.notify.apply(object,args);
				}
				this._objectEventSetup(event_name);
				var args = $A(arguments).slice(1);
				var collected_return_values = [];
				try{
					if(this.options && this.options[event_name] && typeof(this.options[event_name]) == 'function')
						collected_return_values.push(this.options[event_name].apply(this,args) || null);
					for(var i = 0; i < this._observers[event_name].length; ++i)
						collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i],args) || null);
				}catch(e){
					if(e == $break)
						return false;
					else
						throw e;
				}
				return collected_return_values;
			};
		}
	}
};

/* Begin Core Extensions */

//Element.observeOnce
Element.addMethods({
	observeOnce: function(element,event_name,outer_callback){
		var inner_callback = function(){
			outer_callback.apply(this,arguments);
			Element.stopObserving(element,event_name,inner_callback);
		};
		Element.observe(element,event_name,inner_callback);
	}
});

//mouseenter, mouseleave
//from http://dev.rubyonrails.org/attachment/ticket/8354/event_mouseenter_106rc1.patch
Object.extend(Event, (function() {
	var cache = Event.cache;

	function getEventID(element) {
		if (element._prototypeEventID) return element._prototypeEventID[0];
		arguments.callee.id = arguments.callee.id || 1;
		return element._prototypeEventID = [++arguments.callee.id];
	}

	function getDOMEventName(eventName) {
		if (eventName && eventName.include(':')) return "dataavailable";
		//begin extension
		if(!Prototype.Browser.IE){
			eventName = {
				mouseenter: 'mouseover',
				mouseleave: 'mouseout'
			}[eventName] || eventName;
		}
		//end extension
		return eventName;
	}

	function getCacheForID(id) {
		return cache[id] = cache[id] || { };
	}

	function getWrappersForEventName(id, eventName) {
		var c = getCacheForID(id);
		return c[eventName] = c[eventName] || [];
	}

	function createWrapper(element, eventName, handler) {
		var id = getEventID(element);
		var c = getWrappersForEventName(id, eventName);
		if (c.pluck("handler").include(handler)) return false;

		var wrapper = function(event) {
			if (!Event || !Event.extend ||
				(event.eventName && event.eventName != eventName))
					return false;

			Event.extend(event);
			handler.call(element, event);
		};
		
		//begin extension
		if(!(Prototype.Browser.IE) && ['mouseenter','mouseleave'].include(eventName)){
			wrapper = wrapper.wrap(function(proceed,event) {	
				var rel = event.relatedTarget;
				var cur = event.currentTarget;			 
				if(rel && rel.nodeType == Node.TEXT_NODE)
					rel = rel.parentNode;	  
				if(rel && rel != cur && !rel.descendantOf(cur))	  
					return proceed(event);   
			});	 
		}
		//end extension

		wrapper.handler = handler;
		c.push(wrapper);
		return wrapper;
	}

	function findWrapper(id, eventName, handler) {
		var c = getWrappersForEventName(id, eventName);
		return c.find(function(wrapper) { return wrapper.handler == handler });
	}

	function destroyWrapper(id, eventName, handler) {
		var c = getCacheForID(id);
		if (!c[eventName]) return false;
		c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
	}

	function destroyCache() {
		for (var id in cache)
			for (var eventName in cache[id])
				cache[id][eventName] = null;
	}

	if (window.attachEvent) {
		window.attachEvent("onunload", destroyCache);
	}

	return {
		observe: function(element, eventName, handler) {
			element = $(element);
			var name = getDOMEventName(eventName);

			var wrapper = createWrapper(element, eventName, handler);
			if (!wrapper) return element;

			if (element.addEventListener) {
				element.addEventListener(name, wrapper, false);
			} else {
				element.attachEvent("on" + name, wrapper);
			}

			return element;
		},

		stopObserving: function(element, eventName, handler) {
			element = $(element);
			var id = getEventID(element), name = getDOMEventName(eventName);

			if (!handler && eventName) {
				getWrappersForEventName(id, eventName).each(function(wrapper) {
					element.stopObserving(eventName, wrapper.handler);
				});
				return element;

			} else if (!eventName) {
				Object.keys(getCacheForID(id)).each(function(eventName) {
					element.stopObserving(eventName);
				});
				return element;
			}

			var wrapper = findWrapper(id, eventName, handler);
			if (!wrapper) return element;

			if (element.removeEventListener) {
				element.removeEventListener(name, wrapper, false);
			} else {
				element.detachEvent("on" + name, wrapper);
			}

			destroyWrapper(id, eventName, handler);

			return element;
		},

		fire: function(element, eventName, memo) {
			element = $(element);
			if (element == document && document.createEvent && !element.dispatchEvent)
				element = document.documentElement;

			var event;
			if (document.createEvent) {
				event = document.createEvent("HTMLEvents");
				event.initEvent("dataavailable", true, true);
			} else {
				event = document.createEventObject();
				event.eventType = "ondataavailable";
			}

			event.eventName = eventName;
			event.memo = memo || { };

			if (document.createEvent) {
				element.dispatchEvent(event);
			} else {
				element.fireEvent(event.eventType, event);
			}

			return Event.extend(event);
		}
	};
})());

Object.extend(Event, Event.Methods);

Element.addMethods({
	fire:			Event.fire,
	observe:		Event.observe,
	stopObserving:	Event.stopObserving
});

Object.extend(document, {
	fire:			Element.Methods.fire.methodize(),
	observe:		Element.Methods.observe.methodize(),
	stopObserving:	Element.Methods.stopObserving.methodize()
});

//mouse:wheel
/*
(function(){
	function wheel(event){
		var delta;
		// normalize the delta
		if(event.wheelDelta) // IE & Opera
			delta = event.wheelDelta / 120;
		else if (event.detail) // W3C
			delta =- event.detail / 3;
		if(!delta)
			return;
		var custom_event = event.element().fire('mouse:wheel',{
			delta: delta
		});
		if(custom_event.stopped){
			event.stop();
			return false;
		}
	}
	document.observe('mousewheel',wheel);
	document.observe('DOMMouseScroll',wheel);
})();
*/
/* End Core Extensions */

//from PrototypeUI
var IframeShim = Class.create({
	initialize: function() {
		this.element = new Element('iframe',{
			style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none',
			src: 'javascript:void(0);',
			frameborder: 0 
		});
		$(document.body).insert(this.element);
	},
	hide: function() {
		this.element.hide();
		return this;
	},
	show: function() {
		this.element.show();
		return this;
	},
	positionUnder: function(element) {
		var element = $(element);
		var offset = element.cumulativeOffset();
		var dimensions = element.getDimensions();
		this.element.setStyle({
			left: offset[0] + 'px',
			top: offset[1] + 'px',
			width: dimensions.width + 'px',
			height: dimensions.height + 'px',
			zIndex: element.getStyle('zIndex') - 1
		}).show();
		return this;
	},
	setBounds: function(bounds) {
		for(prop in bounds)
			bounds[prop] += 'px';
		this.element.setStyle(bounds);
		return this;
	},
	destroy: function() {
		if(this.element)
			this.element.remove();
		return this;
	}
});
/**
 * @author Ryan Johnson <http://syntacticx.com/>
 * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
 * @package LivePipe UI
 * @license MIT
 * @url http://livepipe.net/control/tabs
 * @require prototype.js, livepipe.js
 */

if(typeof(Prototype) == "undefined")
	throw "Control.Tabs requires Prototype to be loaded.";
if(typeof(Object.Event) == "undefined")
	throw "Control.Tabs requires Object.Event to be loaded.";

Control.Tabs = Class.create({
	initialize: function(tab_list_container,options){
		if(!$(tab_list_container))
			throw "Control.Tabs could not find the element: " + tab_list_container;
		this.activeContainer = false;
		this.activeLink = false;
		this.containers = $H({});
		this.links = [];
		Control.Tabs.instances.push(this);
		this.options = {
			beforeChange: Prototype.emptyFunction,
			afterChange: Prototype.emptyFunction,
			hover: false,
			linkSelector: 'li a',
			setClassOnContainer: false,
			activeClassName: 'active',
			defaultTab: 'first',
			autoLinkExternal: true,
			targetRegExp: /#(.+)$/,
			showFunction: Element.show,
			hideFunction: Element.hide
		};
		Object.extend(this.options,options || {});
		(typeof(this.options.linkSelector == 'string')
			? $(tab_list_container).select(this.options.linkSelector)
			: this.options.linkSelector($(tab_list_container))
		).findAll(function(link){
			return (/^#/).exec((Prototype.Browser.WebKit ? decodeURIComponent(link.href) : link.href).replace(window.location.href.split('#')[0],''));
		}).each(function(link){
			this.addTab(link);
		}.bind(this));
		this.containers.values().each(Element.hide);
		if(this.options.defaultTab == 'first')
			this.setActiveTab(this.links.first());
		else if(this.options.defaultTab == 'last')
			this.setActiveTab(this.links.last());
		else
			this.setActiveTab(this.options.defaultTab);
		var targets = this.options.targetRegExp.exec(window.location);
		if(targets && targets[1]){
			targets[1].split(',').each(function(target){
				this.setActiveTab(this.links.find(function(link){
					return link.key == target;
				}));
			}.bind(this));
		}
		if(this.options.autoLinkExternal){
			$A(document.getElementsByTagName('a')).each(function(a){
				if(!this.links.include(a)){
					var clean_href = a.href.replace(window.location.href.split('#')[0],'');
					if(clean_href.substring(0,1) == '#'){
						if(this.containers.keys().include(clean_href.substring(1))){
							$(a).observe('click',function(event,clean_href){
								this.setActiveTab(clean_href.substring(1));
							}.bindAsEventListener(this,clean_href));
						}
					}
				}
			}.bind(this));
		}
	},
	addTab: function(link){
		this.links.push(link);
		link.key = link.getAttribute('href').replace(window.location.href.split('#')[0],'').split('/').last().replace(/#/,'');
		var container = $(link.key);
		if(!container)
			throw "Control.Tabs: #" + link.key + " was not found on the page."
		this.containers.set(link.key,container);
		link[this.options.hover ? 'onmouseover' : 'onclick'] = function(link){
			if(window.event)
				Event.stop(window.event);
			this.setActiveTab(link);
			return false;
		}.bind(this,link);
	},
	setActiveTab: function(link){
		if(!link && typeof(link) == 'undefined')
			return;
		if(typeof(link) == 'string'){
			this.setActiveTab(this.links.find(function(_link){
				return _link.key == link;
			}));
		}else if(typeof(link) == 'number'){
			this.setActiveTab(this.links[link]);
		}else{
			if(this.notify('beforeChange',this.activeContainer,this.containers.get(link.key)) === false)
				return;
			if(this.activeContainer)
				this.options.hideFunction(this.activeContainer);
			this.links.each(function(item){
				(this.options.setClassOnContainer ? $(item.parentNode) : item).removeClassName(this.options.activeClassName);
			}.bind(this));
			(this.options.setClassOnContainer ? $(link.parentNode) : link).addClassName(this.options.activeClassName);
			this.activeContainer = this.containers.get(link.key);
			this.activeLink = link;
			this.options.showFunction(this.containers.get(link.key));
			this.notify('afterChange',this.containers.get(link.key));
		}
	},
	next: function(){
		this.links.each(function(link,i){
			if(this.activeLink == link && this.links[i + 1]){
				this.setActiveTab(this.links[i + 1]);
				throw $break;
			}
		}.bind(this));
	},
	previous: function(){
		this.links.each(function(link,i){
			if(this.activeLink == link && this.links[i - 1]){
				this.setActiveTab(this.links[i - 1]);
				throw $break;
			}
		}.bind(this));
	},
	first: function(){
		this.setActiveTab(this.links.first());
	},
	last: function(){
		this.setActiveTab(this.links.last());
	}
});
Object.extend(Control.Tabs,{
	instances: [],
	findByTabId: function(id){
		return Control.Tabs.instances.find(function(tab){
			return tab.links.find(function(link){
				return link.key == id;
			});
		});
	}
});
Object.Event.extend(Control.Tabs);
/**
 * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
 *
 * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */
if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;
//***********************************************************************************************************************************/
//	LyteBox v3.20
//
//	 Author: Markus F. Hay
//  Website: http://www.dolem.com/lytebox
//	   Date: July 12, 2007
//	License: Creative Commons Attribution 3.0 License (http://creativecommons.org/licenses/by/3.0/)
// Browsers: Tested successfully on WinXP with the following browsers (using no DOCTYPE, Strict DOCTYPE, and Transitional DOCTYPE):
//				* Firefox: 2.0.0.4, 1.5.0.12
//				* Internet Explorer: 7.0, 6.0 SP2, 5.5 SP2
//				* Opera: 9.21
//
// Releases: For up-to-date and complete release information, visit http://www.dolem.com/forum/showthread.php?tid=62
//				* v3.20 (07/11/07)
//				* v3.10 (05/28/07)
//				* v3.00 (05/15/07)
//				* v2.02 (11/13/06)
//
//   Credit: LyteBox was originally derived from the Lightbox class (v2.02) that was written by Lokesh Dhakar. For more
//			 information please visit http://huddletogether.com/projects/lightbox2/
//***********************************************************************************************************************************/
Array.prototype.removeDuplicates = function () { for (var i = 1; i < this.length; i++) { if (this[i][0] == this[i-1][0]) { this.splice(i,1); } } }
Array.prototype.empty = function () { for (var i = 0; i <= this.length; i++) { this.shift(); } }
String.prototype.trim = function () { return this.replace(/^\s+|\s+$/g, ''); }

function LyteBox() {
	/*** Start Global Configuration ***/
		this.theme					= 'grey';	// themes: grey (default), red, green, blue, gold
		this.hideFlash				= true;		// controls whether or not Flash objects should be hidden
		this.outerBorder			= true;		// controls whether to show the outer grey (or theme) border
		this.resizeSpeed			= 8;		// controls the speed of the image resizing (1=slowest and 10=fastest)
		this.maxOpacity			= 80;		// higher opacity = darker overlay, lower opacity = lighter overlay
		this.navType					= 1;		// 1 = "Prev/Next" buttons on top left and left (default), 2 = "<< prev | next >>" links next to image number
		this.autoResize				= true;		// controls whether or not images should be resized if larger than the browser window dimensions
		this.doAnimations			= true;		// controls whether or not "animate" Lytebox, i.e. resize transition between images, fade in/out effects, etc.
		
		this.borderSize				= 12;		// if you adjust the padding in the CSS, you will need to update this variable -- otherwise, leave this alone...
	/*** End Global Configuration ***/
	
	/*** Configure Slideshow Options ***/
		this.slideInterval			= 4000;		// Change value (milliseconds) to increase/decrease the time between "slides" (10000 = 10 seconds)
		this.showNavigation		= true;		// true to display Next/Prev buttons/text during slideshow, false to hide
		this.showClose				= true;		// true to display the Close button, false to hide
		this.showDetails			= true;		// true to display image details (caption, count), false to hide
		this.showPlayPause		= true;		// true to display pause/play buttons next to close button, false to hide
		this.autoEnd					= true;		// true to automatically close Lytebox after the last image is reached, false to keep open
		this.pauseOnNextClick	= false;	// true to pause the slideshow when the "Next" button is clicked
        this.pauseOnPrevClick 	= true;		// true to pause the slideshow when the "Prev" button is clicked
	/*** End Slideshow Configuration ***/
	
	if(this.resizeSpeed > 10) { this.resizeSpeed = 10; }
	if(this.resizeSpeed < 1) { resizeSpeed = 1; }
	this.resizeDuration = (11 - this.resizeSpeed) * 0.15;
	this.resizeWTimerArray			= new Array();
	this.resizeWTimerCount			= 0;
	this.resizeHTimerArray			= new Array();
	this.resizeHTimerCount			= 0;
	this.showContentTimerArray	= new Array();
	this.showContentTimerCount	= 0;
	this.overlayTimerArray			= new Array();
	this.overlayTimerCount			= 0;
	this.imageTimerArray			= new Array();
	this.imageTimerCount			= 0;
	this.timerIDArray					= new Array();
	this.timerIDCount					= 0;
	this.slideshowIDArray			= new Array();
	this.slideshowIDCount			= 0;
	this.imageArray	 = new Array();
	this.activeImage = null;
	this.slideArray	 = new Array();
	this.activeSlide = null;
	this.frameArray	 = new Array();
	this.activeFrame = null;
	this.checkFrame();
	this.isSlideshow = false;
	this.isLyteframe = false;
	/*@cc_on
		/*@if (@_jscript)
			this .ie = (document.all && !window.opera) ? checkVersion() : false;
		/*@else @*/
			this.ie = false;
		/*@end
	@*/
	this.ie7 = (this.ie && window.XMLHttpRequest);
	this.initialize();
}
LyteBox.prototype.initialize = function() {
	this.updateLyteboxItems();
	var objBody = this.doc.getElementsByTagName("body").item(0);	
	if (this.doc.getElementById('lbOverlay')) {
		objBody.removeChild(this.doc.getElementById("lbOverlay"));
		objBody.removeChild(this.doc.getElementById("lbMain"));
	}
	var objOverlay = this.doc.createElement("div");
		objOverlay.setAttribute('id','lbOverlay');
		objOverlay.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objOverlay.style.display = 'none';
		objBody.appendChild(objOverlay);
	var objLytebox = this.doc.createElement("div");
		objLytebox.setAttribute('id','lbMain');
		objLytebox.style.display = 'none';
		objBody.appendChild(objLytebox);
	var objOuterContainer = this.doc.createElement("div");
		objOuterContainer.setAttribute('id','lbOuterContainer');
		objOuterContainer.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objLytebox.appendChild(objOuterContainer);
	var objIframeContainer = this.doc.createElement("div");
		objIframeContainer.setAttribute('id','lbIframeContainer');
		objIframeContainer.style.display = 'none';
		objOuterContainer.appendChild(objIframeContainer);
	var objIframe = this.doc.createElement("iframe");
		objIframe.setAttribute('id','lbIframe');
		objIframe.setAttribute('name','lbIframe');
		objIframe.style.display = 'none';
		objIframeContainer.appendChild(objIframe);
	var objImageContainer = this.doc.createElement("div");
		objImageContainer.setAttribute('id','lbImageContainer');
		objOuterContainer.appendChild(objImageContainer);
	var objLyteboxImage = this.doc.createElement("img");
		objLyteboxImage.setAttribute('id','lbImage');
		objImageContainer.appendChild(objLyteboxImage);
	var objLoading = this.doc.createElement("div");
		objLoading.setAttribute('id','lbLoading');
		objOuterContainer.appendChild(objLoading);
	var objDetailsContainer = this.doc.createElement("div");
		objDetailsContainer.setAttribute('id','lbDetailsContainer');
		objDetailsContainer.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objLytebox.appendChild(objDetailsContainer);
	var objDetailsData =this.doc.createElement("div");
		objDetailsData.setAttribute('id','lbDetailsData');
		objDetailsData.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objDetailsContainer.appendChild(objDetailsData);
	var objDetails = this.doc.createElement("div");
		objDetails.setAttribute('id','lbDetails');
		objDetailsData.appendChild(objDetails);
	var objCaption = this.doc.createElement("span");
		objCaption.setAttribute('id','lbCaption');
		objDetails.appendChild(objCaption);
	var objHoverNav = this.doc.createElement("div");
		objHoverNav.setAttribute('id','lbHoverNav');
		objImageContainer.appendChild(objHoverNav);
	var objBottomNav = this.doc.createElement("div");
		objBottomNav.setAttribute('id','lbBottomNav');
		objDetailsData.appendChild(objBottomNav);
	var objPrev = this.doc.createElement("a");
		objPrev.setAttribute('id','lbPrev');
		objPrev.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objPrev.setAttribute('href','#');
		objHoverNav.appendChild(objPrev);
	var objNext = this.doc.createElement("a");
		objNext.setAttribute('id','lbNext');
		objNext.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objNext.setAttribute('href','#');
		objHoverNav.appendChild(objNext);
	var objNumberDisplay = this.doc.createElement("span");
		objNumberDisplay.setAttribute('id','lbNumberDisplay');
		objDetails.appendChild(objNumberDisplay);
	var objNavDisplay = this.doc.createElement("span");
		objNavDisplay.setAttribute('id','lbNavDisplay');
		objNavDisplay.style.display = 'none';
		objDetails.appendChild(objNavDisplay);
	var objClose = this.doc.createElement("a");
		objClose.setAttribute('id','lbClose');
		objClose.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objClose.setAttribute('href','#');
		objBottomNav.appendChild(objClose);
	var objPause = this.doc.createElement("a");
		objPause.setAttribute('id','lbPause');
		objPause.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objPause.setAttribute('href','#');
		objPause.style.display = 'none';
		objBottomNav.appendChild(objPause);
	var objPlay = this.doc.createElement("a");
		objPlay.setAttribute('id','lbPlay');
		objPlay.setAttribute((this.ie ? 'className' : 'class'), this.theme);
		objPlay.setAttribute('href','#');
		objPlay.style.display = 'none';
		objBottomNav.appendChild(objPlay);
};
LyteBox.prototype.updateLyteboxItems = function() {	
	var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
	for (var i = 0; i < anchors.length; i++) {
		var anchor = anchors[i];
		var relAttribute = String(anchor.getAttribute('rel'));
		if (anchor.getAttribute('href')) {
			if (relAttribute.toLowerCase().match('lytebox')) {
				anchor.onclick = function () { myLytebox.start(this, false, false); return false; }
			} else if (relAttribute.toLowerCase().match('lyteshow')) {
				anchor.onclick = function () { myLytebox.start(this, true, false); return false; }
			} else if (relAttribute.toLowerCase().match('lyteframe')) {
				anchor.onclick = function () { myLytebox.start(this, false, true); return false; }
			}
		}
	}
};
LyteBox.prototype.start = function(imageLink, doSlide, doFrame) {
	if (this.ie && !this.ie7) {	this.toggleSelects('hide');	}
	if (this.hideFlash) { this.toggleFlash('hide'); }
	this.isLyteframe = (doFrame ? true : false);
	var pageSize	= this.getPageSize();
	var objOverlay	= this.doc.getElementById('lbOverlay');
	var objBody		= this.doc.getElementsByTagName("body").item(0);
	objOverlay.style.height = pageSize[1] + "px";
	objOverlay.style.display = '';
	this.appear('lbOverlay', (this.doAnimations ? 0 : this.maxOpacity));
	var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
	if (this.isLyteframe) {
		this.frameArray = [];
		this.frameNum = 0;
		if ((imageLink.getAttribute('rel') == 'lyteframe')) {
			var rev = imageLink.getAttribute('rev');
			this.frameArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title'), (rev == null || rev == '' ? 'width: 400px; height: 400px; scrolling: auto;' : rev)));
		} else {
			if (imageLink.getAttribute('rel').indexOf('lyteframe') != -1) {
				for (var i = 0; i < anchors.length; i++) {
					var anchor = anchors[i];
					if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {
						var rev = anchor.getAttribute('rev');
						this.frameArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title'), (rev == null || rev == '' ? 'width: 400px; height: 400px; scrolling: auto;' : rev)));
					}
				}
				this.frameArray.removeDuplicates();
				while(this.frameArray[this.frameNum][0] != imageLink.getAttribute('href')) { this.frameNum++; }
			}
		}
	} else {
		this.imageArray = [];
		this.imageNum = 0;
		this.slideArray = [];
		this.slideNum = 0;
		if ((imageLink.getAttribute('rel') == 'lytebox')) {
			this.imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title')));
		} else {
			if (imageLink.getAttribute('rel').indexOf('lytebox') != -1) {
				for (var i = 0; i < anchors.length; i++) {
					var anchor = anchors[i];
					if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {
						this.imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
					}
				}
				this.imageArray.removeDuplicates();
				while(this.imageArray[this.imageNum][0] != imageLink.getAttribute('href')) { this.imageNum++; }
			}
			if (imageLink.getAttribute('rel').indexOf('lyteshow') != -1) {
				for (var i = 0; i < anchors.length; i++) {
					var anchor = anchors[i];
					if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {
						this.slideArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
					}
				}
				this.slideArray.removeDuplicates();
				while(this.slideArray[this.slideNum][0] != imageLink.getAttribute('href')) { this.slideNum++; }
			}
		}
	}
	var object = this.doc.getElementById('lbMain');
		object.style.top = (this.getPageScroll() + (pageSize[3] / 15)) + "px";
		object.style.display = '';
	if (!this.outerBorder) {
		this.doc.getElementById('lbOuterContainer').style.border = 'none';
		this.doc.getElementById('lbDetailsContainer').style.border = 'none';
	} else {
		this.doc.getElementById('lbOuterContainer').style.borderBottom = '';
		this.doc.getElementById('lbOuterContainer').setAttribute((this.ie ? 'className' : 'class'), this.theme);
	}
	this.doc.getElementById('lbOverlay').onclick = function() { myLytebox.end(); return false; }
	this.doc.getElementById('lbMain').onclick = function(e) {
		var e = e;
		if (!e) {
			if (window.parent.frames[window.name] && (parent.document.getElementsByTagName('frameset').length <= 0)) {
				e = window.parent.window.event;
			} else {
				e = window.event;
			}
		}
		var id = (e.target ? e.target.id : e.srcElement.id);
		if (id == 'lbMain') { myLytebox.end(); return false; }
	}
	this.doc.getElementById('lbClose').onclick = function() { myLytebox.end(); return false; }
	this.doc.getElementById('lbPause').onclick = function() { myLytebox.togglePlayPause("lbPause", "lbPlay"); return false; }
	this.doc.getElementById('lbPlay').onclick = function() { myLytebox.togglePlayPause("lbPlay", "lbPause"); return false; }
	this.isSlideshow = doSlide;
	this.isPaused = (this.slideNum != 0 ? true : false);
	if (this.isSlideshow && this.showPlayPause && this.isPaused) {
		this.doc.getElementById('lbPlay').style.display = '';
		this.doc.getElementById('lbPause').style.display = 'none';
	}
	if (this.isLyteframe) {
		this.changeContent(this.frameNum);
	} else {
		if (this.isSlideshow) {
			this.changeContent(this.slideNum);
		} else {
			this.changeContent(this.imageNum);
		}
	}
};
LyteBox.prototype.changeContent = function(imageNum) {
	if (this.isSlideshow) {
		for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }
	}
	this.activeImage = this.activeSlide = this.activeFrame = imageNum;
	if (!this.outerBorder) {
		this.doc.getElementById('lbOuterContainer').style.border = 'none';
		this.doc.getElementById('lbDetailsContainer').style.border = 'none';
	} else {
		this.doc.getElementById('lbOuterContainer').style.borderBottom = '';
		this.doc.getElementById('lbOuterContainer').setAttribute((this.ie ? 'className' : 'class'), this.theme);
	}
	this.doc.getElementById('lbLoading').style.display = '';
	this.doc.getElementById('lbImage').style.display = 'none';
	this.doc.getElementById('lbIframe').style.display = 'none';
	this.doc.getElementById('lbPrev').style.display = 'none';
	this.doc.getElementById('lbNext').style.display = 'none';
	this.doc.getElementById('lbIframeContainer').style.display = 'none';
	this.doc.getElementById('lbDetailsContainer').style.display = 'none';
	this.doc.getElementById('lbNumberDisplay').style.display = 'none';
	if (this.navType == 2 || this.isLyteframe) {
		object = this.doc.getElementById('lbNavDisplay');
		object.innerHTML = '&nbsp;&nbsp;&nbsp;<span id="lbPrev2_Off" style="display: none;" class="' + this.theme + '">&laquo; prev</span><a href="#" id="lbPrev2" class="' + this.theme + '" style="display: none;">&laquo; prev</a> <b id="lbSpacer" class="' + this.theme + '">||</b> <span id="lbNext2_Off" style="display: none;" class="' + this.theme + '">next &raquo;</span><a href="#" id="lbNext2" class="' + this.theme + '" style="display: none;">next &raquo;</a>';
		object.style.display = 'none';
	}
	if (this.isLyteframe) {
		var iframe = myLytebox.doc.getElementById('lbIframe');
		var styles = this.frameArray[this.activeFrame][2];
		var aStyles = styles.split(';');
		for (var i = 0; i < aStyles.length; i++) {
			if (aStyles[i].indexOf('width:') >= 0) {
				var w = aStyles[i].replace('width:', '');
				iframe.width = w.trim();
			} else if (aStyles[i].indexOf('height:') >= 0) {
				var h = aStyles[i].replace('height:', '');
				iframe.height = h.trim();
			} else if (aStyles[i].indexOf('scrolling:') >= 0) {
				var s = aStyles[i].replace('scrolling:', '');
				iframe.scrolling = s.trim();
			} else if (aStyles[i].indexOf('border:') >= 0) {
				// Not implemented yet, as there are cross-platform issues with setting the border (from a GUI standpoint)
				//var b = aStyles[i].replace('border:', '');
				//iframe.style.border = b.trim();
			}
		}
		iframe.src = this.frameArray[this.activeFrame][0];		
		this.resizeContainer(parseInt(iframe.width), parseInt(iframe.height));
	} else {
		imgPreloader = new Image();
		imgPreloader.onload = function() {
			var imageWidth = imgPreloader.width;
			var imageHeight = imgPreloader.height;
			if (myLytebox.autoResize) {
				var pagesize = myLytebox.getPageSize();
				var x = pagesize[2] - 150;
				var y = pagesize[3] - 150;
				if (imageWidth > x) {
					imageHeight = Math.round(imageHeight * (x / imageWidth));
					imageWidth = x; 
					if (imageHeight > y) { 
						imageWidth = Math.round(imageWidth * (y / imageHeight));
						imageHeight = y; 
					}
				} else if (imageHeight > y) { 
					imageWidth = Math.round(imageWidth * (y / imageHeight));
					imageHeight = y; 
					if (imageWidth > x) {
						imageHeight = Math.round(imageHeight * (x / imageWidth));
						imageWidth = x;
					}
				}
			}
			var lbImage = myLytebox.doc.getElementById('lbImage')
			lbImage.src = (myLytebox.isSlideshow ? myLytebox.slideArray[myLytebox.activeSlide][0] : myLytebox.imageArray[myLytebox.activeImage][0]);
			lbImage.width = imageWidth;
			lbImage.height = imageHeight;
			myLytebox.resizeContainer(imageWidth, imageHeight);
			imgPreloader.onload = function() {};
		}
		imgPreloader.src = (this.isSlideshow ? this.slideArray[this.activeSlide][0] : this.imageArray[this.activeImage][0]);
	}
};
LyteBox.prototype.resizeContainer = function(imgWidth, imgHeight) {
	this.wCur = this.doc.getElementById('lbOuterContainer').offsetWidth;
	this.hCur = this.doc.getElementById('lbOuterContainer').offsetHeight;
	this.xScale = ((imgWidth  + (this.borderSize * 2)) / this.wCur) * 100;
	this.yScale = ((imgHeight  + (this.borderSize * 2)) / this.hCur) * 100;
	var wDiff = (this.wCur - this.borderSize * 2) - imgWidth;
	var hDiff = (this.hCur - this.borderSize * 2) - imgHeight;
	if (!(hDiff == 0)) {
		this.hDone = false;
		this.resizeH('lbOuterContainer', this.hCur, imgHeight + this.borderSize*2, this.getPixelRate(this.hCur, imgHeight));
	} else {
		this.hDone = true;
	}
	if (!(wDiff == 0)) {
		this.wDone = false;
		this.resizeW('lbOuterContainer', this.wCur, imgWidth + this.borderSize*2, this.getPixelRate(this.wCur, imgWidth));
	} else {
		this.wDone = true;
	}
	if ((hDiff == 0) && (wDiff == 0)) {
		if (this.ie){ this.pause(250); } else { this.pause(100); } 
	}
	this.doc.getElementById('lbPrev').style.height = imgHeight + "px";
	this.doc.getElementById('lbNext').style.height = imgHeight + "px";
	this.doc.getElementById('lbDetailsContainer').style.width = (imgWidth + (this.borderSize * 2) + (this.ie && this.doc.compatMode == "BackCompat" && this.outerBorder ? 2 : 0)) + "px";
	this.showContent();
};
LyteBox.prototype.showContent = function() {
	if (this.wDone && this.hDone) {
		for (var i = 0; i < this.showContentTimerCount; i++) { window.clearTimeout(this.showContentTimerArray[i]); }
		if (this.outerBorder) {
			this.doc.getElementById('lbOuterContainer').style.borderBottom = 'none';
		}
		this.doc.getElementById('lbLoading').style.display = 'none';
		if (this.isLyteframe) {
			this.doc.getElementById('lbIframe').style.display = '';
			this.appear('lbIframe', (this.doAnimations ? 0 : 100));
		} else {
			this.doc.getElementById('lbImage').style.display = '';
			this.appear('lbImage', (this.doAnimations ? 0 : 100));
			this.preloadNeighborImages();
		}
		if (this.isSlideshow) {
			if(this.activeSlide == (this.slideArray.length - 1)) {
				if (this.autoEnd) {
					this.slideshowIDArray[this.slideshowIDCount++] = setTimeout("myLytebox.end('slideshow')", this.slideInterval);
				}
			} else {
				if (!this.isPaused) {
					this.slideshowIDArray[this.slideshowIDCount++] = setTimeout("myLytebox.changeContent("+(this.activeSlide+1)+")", this.slideInterval);
				}
			}
			this.doc.getElementById('lbHoverNav').style.display = (this.showNavigation && this.navType == 1 ? '' : 'none');
			this.doc.getElementById('lbClose').style.display = (this.showClose ? '' : 'none');
			this.doc.getElementById('lbDetails').style.display = (this.showDetails ? '' : 'none');
			this.doc.getElementById('lbPause').style.display = (this.showPlayPause && !this.isPaused ? '' : 'none');
			this.doc.getElementById('lbPlay').style.display = (this.showPlayPause && !this.isPaused ? 'none' : '');
			this.doc.getElementById('lbNavDisplay').style.display = (this.showNavigation && this.navType == 2 ? '' : 'none');
		} else {
			this.doc.getElementById('lbHoverNav').style.display = (this.navType == 1 && !this.isLyteframe ? '' : 'none');
			if ((this.navType == 2 && !this.isLyteframe && this.imageArray.length > 1) || (this.frameArray.length > 1 && this.isLyteframe)) {
				this.doc.getElementById('lbNavDisplay').style.display = '';
			} else {
				this.doc.getElementById('lbNavDisplay').style.display = 'none';
			}
			this.doc.getElementById('lbClose').style.display = '';
			this.doc.getElementById('lbDetails').style.display = '';
			this.doc.getElementById('lbPause').style.display = 'none';
			this.doc.getElementById('lbPlay').style.display = 'none';
		}
		this.doc.getElementById('lbImageContainer').style.display = (this.isLyteframe ? 'none' : '');
		this.doc.getElementById('lbIframeContainer').style.display = (this.isLyteframe ? '' : 'none');
	} else {
		this.showContentTimerArray[this.showContentTimerCount++] = setTimeout("myLytebox.showContent()", 200);
	}
};
LyteBox.prototype.updateDetails = function() {
	var object = this.doc.getElementById('lbCaption');
	var sTitle = (this.isSlideshow ? this.slideArray[this.activeSlide][1] : (this.isLyteframe ? this.frameArray[this.activeFrame][1] : this.imageArray[this.activeImage][1]));
	object.style.display = '';
	object.innerHTML = (sTitle == null ? '' : sTitle);
	this.updateNav();
	this.doc.getElementById('lbDetailsContainer').style.display = '';
	object = this.doc.getElementById('lbNumberDisplay');
	if (this.isSlideshow && this.slideArray.length > 1) {
		object.style.display = '';
		object.innerHTML = "Image " + eval(this.activeSlide + 1) + " of " + this.slideArray.length;
		this.doc.getElementById('lbNavDisplay').style.display = (this.navType == 2 && this.showNavigation ? '' : 'none');
	} else if (this.imageArray.length > 1 && !this.isLyteframe) {
		object.style.display = '';
		object.innerHTML = "Image " + eval(this.activeImage + 1) + " of " + this.imageArray.length;
		this.doc.getElementById('lbNavDisplay').style.display = (this.navType == 2 ? '' : 'none');
	} else if (this.frameArray.length > 1 && this.isLyteframe) {
		object.style.display = '';
		object.innerHTML = "Page " + eval(this.activeFrame + 1) + " of " + this.frameArray.length;
		this.doc.getElementById('lbNavDisplay').style.display = '';
	} else {
		this.doc.getElementById('lbNavDisplay').style.display = 'none';
	}
	this.appear('lbDetailsContainer', (this.doAnimations ? 0 : 100));
};
LyteBox.prototype.updateNav = function() {
	if (this.isSlideshow) {
		if (this.activeSlide != 0) {
			var object = (this.navType == 2 ? this.doc.getElementById('lbPrev2') : this.doc.getElementById('lbPrev'));
				object.style.display = '';
				object.onclick = function() {
					if (myLytebox.pauseOnPrevClick) { myLytebox.togglePlayPause("lbPause", "lbPlay"); }
					myLytebox.changeContent(myLytebox.activeSlide - 1); return false;
				}
		} else {
			if (this.navType == 2) { this.doc.getElementById('lbPrev2_Off').style.display = ''; }
		}
		if (this.activeSlide != (this.slideArray.length - 1)) {
			var object = (this.navType == 2 ? this.doc.getElementById('lbNext2') : this.doc.getElementById('lbNext'));
				object.style.display = '';
				object.onclick = function() {
					if (myLytebox.pauseOnNextClick) { myLytebox.togglePlayPause("lbPause", "lbPlay"); }
					myLytebox.changeContent(myLytebox.activeSlide + 1); return false;
				}
		} else {
			if (this.navType == 2) { this.doc.getElementById('lbNext2_Off').style.display = ''; }
		}
	} else if (this.isLyteframe) {
		if(this.activeFrame != 0) {
			var object = this.doc.getElementById('lbPrev2');
				object.style.display = '';
				object.onclick = function() {
					myLytebox.changeContent(myLytebox.activeFrame - 1); return false;
				}
		} else {
			this.doc.getElementById('lbPrev2_Off').style.display = '';
		}
		if(this.activeFrame != (this.frameArray.length - 1)) {
			var object = this.doc.getElementById('lbNext2');
				object.style.display = '';
				object.onclick = function() {
					myLytebox.changeContent(myLytebox.activeFrame + 1); return false;
				}
		} else {
			this.doc.getElementById('lbNext2_Off').style.display = '';
		}		
	} else {
		if(this.activeImage != 0) {
			var object = (this.navType == 2 ? this.doc.getElementById('lbPrev2') : this.doc.getElementById('lbPrev'));
				object.style.display = '';
				object.onclick = function() {
					myLytebox.changeContent(myLytebox.activeImage - 1); return false;
				}
		} else {
			if (this.navType == 2) { this.doc.getElementById('lbPrev2_Off').style.display = ''; }
		}
		if(this.activeImage != (this.imageArray.length - 1)) {
			var object = (this.navType == 2 ? this.doc.getElementById('lbNext2') : this.doc.getElementById('lbNext'));
				object.style.display = '';
				object.onclick = function() {
					myLytebox.changeContent(myLytebox.activeImage + 1); return false;
				}
		} else {
			if (this.navType == 2) { this.doc.getElementById('lbNext2_Off').style.display = ''; }
		}
	}
	this.enableKeyboardNav();
};
LyteBox.prototype.enableKeyboardNav = function() { document.onkeydown = this.keyboardAction; };
LyteBox.prototype.disableKeyboardNav = function() { document.onkeydown = ''; };
LyteBox.prototype.keyboardAction = function(e) {
	var keycode = key = escape = null;
	keycode	= (e == null) ? event.keyCode : e.which;
	key		= String.fromCharCode(keycode).toLowerCase();
	escape  = (e == null) ? 27 : e.DOM_VK_ESCAPE;
	if ((key == 'x') || (key == 'c') || (keycode == escape)) {
		myLytebox.end();
	} else if ((key == 'p') || (keycode == 37)) {
		if (myLytebox.isSlideshow) {
			if(myLytebox.activeSlide != 0) {
				myLytebox.disableKeyboardNav();
				myLytebox.changeContent(myLytebox.activeSlide - 1);
			}
		} else if (myLytebox.isLyteframe) {
			if(myLytebox.activeFrame != 0) {
				myLytebox.disableKeyboardNav();
				myLytebox.changeContent(myLytebox.activeFrame - 1);
			}
		} else {
			if(myLytebox.activeImage != 0) {
				myLytebox.disableKeyboardNav();
				myLytebox.changeContent(myLytebox.activeImage - 1);
			}
		}
	} else if ((key == 'n') || (keycode == 39)) {
		if (myLytebox.isSlideshow) {
			if(myLytebox.activeSlide != (myLytebox.slideArray.length - 1)) {
				myLytebox.disableKeyboardNav();
				myLytebox.changeContent(myLytebox.activeSlide + 1);
			}
		} else if (myLytebox.isLyteframe) {
			if(myLytebox.activeFrame != (myLytebox.frameArray.length - 1)) {
				myLytebox.disableKeyboardNav();
				myLytebox.changeContent(myLytebox.activeFrame + 1);
			}
		} else {
			if(myLytebox.activeImage != (myLytebox.imageArray.length - 1)) {
				myLytebox.disableKeyboardNav();
				myLytebox.changeContent(myLytebox.activeImage + 1);
			}
		}
	}
};
LyteBox.prototype.preloadNeighborImages = function() {
	if (this.isSlideshow) {
		if ((this.slideArray.length - 1) > this.activeSlide) {
			preloadNextImage = new Image();
			preloadNextImage.src = this.slideArray[this.activeSlide + 1][0];
		}
		if(this.activeSlide > 0) {
			preloadPrevImage = new Image();
			preloadPrevImage.src = this.slideArray[this.activeSlide - 1][0];
		}
	} else {
		if ((this.imageArray.length - 1) > this.activeImage) {
			preloadNextImage = new Image();
			preloadNextImage.src = this.imageArray[this.activeImage + 1][0];
		}
		if(this.activeImage > 0) {
			preloadPrevImage = new Image();
			preloadPrevImage.src = this.imageArray[this.activeImage - 1][0];
		}
	}
};
LyteBox.prototype.togglePlayPause = function(hideID, showID) {
	if (this.isSlideshow && hideID == "lbPause") {
		for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }
	}
	this.doc.getElementById(hideID).style.display = 'none';
	this.doc.getElementById(showID).style.display = '';
	if (hideID == "lbPlay") {
		this.isPaused = false;
		if (this.activeSlide == (this.slideArray.length - 1)) {
			this.end();
		} else {
			this.changeContent(this.activeSlide + 1);
		}
	} else {
		this.isPaused = true;
	}
};
LyteBox.prototype.end = function(caller) {
	var closeClick = (caller == 'slideshow' ? false : true);
	if (this.isSlideshow && this.isPaused && !closeClick) { return; }
	this.disableKeyboardNav();
	this.doc.getElementById('lbMain').style.display = 'none';
	this.fade('lbOverlay', (this.doAnimations ? this.maxOpacity : 0));
	this.toggleSelects('visible');
	if (this.hideFlash) { this.toggleFlash('visible'); }
	if (this.isSlideshow) {
		for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }
	}
};
LyteBox.prototype.checkFrame = function() {
	if (window.parent.frames[window.name] && (parent.document.getElementsByTagName('frameset').length <= 0)) {
		this.isFrame = true;
		this.lytebox = "window.parent." + window.name + ".myLytebox";
		this.doc = parent.document;
	} else {
		this.isFrame = false;
		this.lytebox = "myLytebox";
		this.doc = document;
	}
};
LyteBox.prototype.getPixelRate = function(cur, img) {
	var diff = (img > cur) ? img - cur : cur - img;
	if (diff >= 0 && diff <= 100) { return 10; }
	if (diff > 100 && diff <= 200) { return 15; }
	if (diff > 200 && diff <= 300) { return 20; }
	if (diff > 300 && diff <= 400) { return 25; }
	if (diff > 400 && diff <= 500) { return 30; }
	if (diff > 500 && diff <= 600) { return 35; }
	if (diff > 600 && diff <= 700) { return 40; }
	if (diff > 700) { return 45; }
};
LyteBox.prototype.appear = function(id, opacity) {
	var object = this.doc.getElementById(id).style;
	object.opacity = (opacity / 100);
	object.MozOpacity = (opacity / 100);
	object.KhtmlOpacity = (opacity / 100);
	object.filter = "alpha(opacity=" + (opacity + 10) + ")";
	if (opacity == 100 && (id == 'lbImage' || id == 'lbIframe')) {
		this.updateDetails();
	} else if (opacity >= this.maxOpacity && id == 'lbOverlay') {
		for (var i = 0; i < this.overlayTimerCount; i++) { window.clearTimeout(this.overlayTimerArray[i]); }
		return;
	} else if (opacity >= 100 && id == 'lbDetailsContainer') {
		for (var i = 0; i < this.imageTimerCount; i++) { window.clearTimeout(this.imageTimerArray[i]); }
		this.doc.getElementById('lbOverlay').style.height = this.getPageSize()[1] + "px";
	} else {
		if (id == 'lbOverlay') {
			this.overlayTimerArray[this.overlayTimerCount++] = setTimeout("myLytebox.appear('" + id + "', " + (opacity+20) + ")", 1);
		} else {
			this.imageTimerArray[this.imageTimerCount++] = setTimeout("myLytebox.appear('" + id + "', " + (opacity+10) + ")", 1);
		}
	}
};
LyteBox.prototype.fade = function(id, opacity) {
	var object = this.doc.getElementById(id).style;
	object.opacity = (opacity / 100);
	object.MozOpacity = (opacity / 100);
	object.KhtmlOpacity = (opacity / 100);
	object.filter = "alpha(opacity=" + opacity + ")";
	if (opacity <= 0) {
		try {
			object.display = 'none';
		} catch(err) { }
	} else if (id == 'lbOverlay') {
		this.overlayTimerArray[this.overlayTimerCount++] = setTimeout("myLytebox.fade('" + id + "', " + (opacity-20) + ")", 1);
	} else {
		this.timerIDArray[this.timerIDCount++] = setTimeout("myLytebox.fade('" + id + "', " + (opacity-10) + ")", 1);
	}
};
LyteBox.prototype.resizeW = function(id, curW, maxW, pixelrate, speed) {
	if (!this.hDone) {
		this.resizeWTimerArray[this.resizeWTimerCount++] = setTimeout("myLytebox.resizeW('" + id + "', " + curW + ", " + maxW + ", " + pixelrate + ")", 100);
		return;
	}
	var object = this.doc.getElementById(id);
	var timer = speed ? speed : (this.resizeDuration/2);
	var newW = (this.doAnimations ? curW : maxW);
	object.style.width = (newW) + "px";
	if (newW < maxW) {
		newW += (newW + pixelrate >= maxW) ? (maxW - newW) : pixelrate;
	} else if (newW > maxW) {
		newW -= (newW - pixelrate <= maxW) ? (newW - maxW) : pixelrate;
	}
	this.resizeWTimerArray[this.resizeWTimerCount++] = setTimeout("myLytebox.resizeW('" + id + "', " + newW + ", " + maxW + ", " + pixelrate + ", " + (timer+0.02) + ")", timer+0.02);
	if (parseInt(object.style.width) == maxW) {
		this.wDone = true;
		for (var i = 0; i < this.resizeWTimerCount; i++) { window.clearTimeout(this.resizeWTimerArray[i]); }
	}
};
LyteBox.prototype.resizeH = function(id, curH, maxH, pixelrate, speed) {
	var timer = speed ? speed : (this.resizeDuration/2);
	var object = this.doc.getElementById(id);
	var newH = (this.doAnimations ? curH : maxH);
	object.style.height = (newH) + "px";
	if (newH < maxH) {
		newH += (newH + pixelrate >= maxH) ? (maxH - newH) : pixelrate;
	} else if (newH > maxH) {
		newH -= (newH - pixelrate <= maxH) ? (newH - maxH) : pixelrate;
	}
	this.resizeHTimerArray[this.resizeHTimerCount++] = setTimeout("myLytebox.resizeH('" + id + "', " + newH + ", " + maxH + ", " + pixelrate + ", " + (timer+.02) + ")", timer+.02);
	if (parseInt(object.style.height) == maxH) {
		this.hDone = true;
		for (var i = 0; i < this.resizeHTimerCount; i++) { window.clearTimeout(this.resizeHTimerArray[i]); }
	}
};
LyteBox.prototype.getPageScroll = function() {
	if (self.pageYOffset) {
		return this.isFrame ? parent.pageYOffset : self.pageYOffset;
	} else if (this.doc.documentElement && this.doc.documentElement.scrollTop){
		return this.doc.documentElement.scrollTop;
	} else if (document.body) {
		return this.doc.body.scrollTop;
	}
};
LyteBox.prototype.getPageSize = function() {	
	var xScroll, yScroll, windowWidth, windowHeight;
	if (window.innerHeight && window.scrollMaxY) {
		xScroll = this.doc.scrollWidth;
		yScroll = (this.isFrame ? parent.innerHeight : self.innerHeight) + (this.isFrame ? parent.scrollMaxY : self.scrollMaxY);
	} else if (this.doc.body.scrollHeight > this.doc.body.offsetHeight){
		xScroll = this.doc.body.scrollWidth;
		yScroll = this.doc.body.scrollHeight;
	} else {
		xScroll = this.doc.getElementsByTagName("html").item(0).offsetWidth;
		yScroll = this.doc.getElementsByTagName("html").item(0).offsetHeight;
		xScroll = (xScroll < this.doc.body.offsetWidth) ? this.doc.body.offsetWidth : xScroll;
		yScroll = (yScroll < this.doc.body.offsetHeight) ? this.doc.body.offsetHeight : yScroll;
	}
	if (self.innerHeight) {
		windowWidth = (this.isFrame) ? parent.innerWidth : self.innerWidth;
		windowHeight = (this.isFrame) ? parent.innerHeight : self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) {
		windowWidth = this.doc.documentElement.clientWidth;
		windowHeight = this.doc.documentElement.clientHeight;
	} else if (document.body) {
		windowWidth = this.doc.getElementsByTagName("html").item(0).clientWidth;
		windowHeight = this.doc.getElementsByTagName("html").item(0).clientHeight;
		windowWidth = (windowWidth == 0) ? this.doc.body.clientWidth : windowWidth;
		windowHeight = (windowHeight == 0) ? this.doc.body.clientHeight : windowHeight;
	}
	var pageHeight = (yScroll < windowHeight) ? windowHeight : yScroll;
	var pageWidth = (xScroll < windowWidth) ? windowWidth : xScroll;
	return new Array(pageWidth, pageHeight, windowWidth, windowHeight);
};
LyteBox.prototype.toggleFlash = function(state) {
	var objects = this.doc.getElementsByTagName("object");
	for (var i = 0; i < objects.length; i++) {
		objects[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';
	}
	var embeds = this.doc.getElementsByTagName("embed");
	for (var i = 0; i < embeds.length; i++) {
		embeds[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';
	}
	if (this.isFrame) {
		for (var i = 0; i < parent.frames.length; i++) {
			try {
				objects = parent.frames[i].window.document.getElementsByTagName("object");
				for (var j = 0; j < objects.length; j++) {
					objects[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';
				}
			} catch(e) { }
			try {
				embeds = parent.frames[i].window.document.getElementsByTagName("embed");
				for (var j = 0; j < embeds.length; j++) {
					embeds[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';
				}
			} catch(e) { }
		}
	}
};
LyteBox.prototype.toggleSelects = function(state) {
	var selects = this.doc.getElementsByTagName("select");
	for (var i = 0; i < selects.length; i++ ) {
		selects[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';
	}
	if (this.isFrame) {
		for (var i = 0; i < parent.frames.length; i++) {
			try {
				selects = parent.frames[i].window.document.getElementsByTagName("select");
				for (var j = 0; j < selects.length; j++) {
					selects[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';
				}
			} catch(e) { }
		}
	}
};
LyteBox.prototype.pause = function(numberMillis) {
	var now = new Date();
	var exitTime = now.getTime() + numberMillis;
	while (true) {
		now = new Date();
		if (now.getTime() > exitTime) { return; }
	}
};
if (window.addEventListener) {
	window.addEventListener("load",initLytebox,false);
} else if (window.attachEvent) {
	window.attachEvent("onload",initLytebox);
} else {
	window.onload = function() {initLytebox();}
}
function initLytebox() { myLytebox = new LyteBox(); }

function checkVersion() {
    if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
             var ieversion = new Number(RegExp.$1)
             if (ieversion >= 8 )
                      return false;
             else if (ieversion < 8 )
                      return true;
    }
    return false;
}
// lightwindow.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
// 
// LightWindow is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro: 
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//

/*-----------------------------------------------------------------------------------------------*/

if(typeof Effect == 'undefined')
  throw("lightwindow.js requires including script.aculo.us' effects.js library!");

// This will stop image flickering in IE6 when elements with images are moved
try {
	document.execCommand("BackgroundImageCache", false, true);
} catch(e) {}

var lightwindow = Class.create();	
lightwindow.prototype = {
	//
	//	Setup Variables
	//
	element : null,
	contentToFetch : null,
	windowActive : false,
	dataEffects : [],
	dimensions : {
		cruft : null,
		container : null,
		viewport : {
			height : null,
			width : null,
			offsetTop : null,
			offsetLeft : null
		}
	},
	pagePosition : {
		x : 0,
		y : 0
	},
	pageDimensions : {
		width : null,
		height : null
	},
	preloadImage : [],
	preloadedImage : [],
	galleries : [],
	resizeTo : {
		height : null,
		heightPercent : null,
		width : null,
		widthPercent : null,
		fixedTop : null,
		fixedLeft : null
	},
	scrollbarOffset : 18,
	navigationObservers : {
		previous : null,
		next : null
	},
	containerChange : {
		height : 0,
		width : 0
	},
	activeGallery : false,
	galleryLocation : {
		current : 0,
		total : 0
	},
	//
	//	Initialize the lightwindow.
	//
	initialize : function(options) {
		this.options = Object.extend({
			resizeSpeed : 8,
			contentOffset : {
				height : 20,
				width : 20
			},
			dimensions : {
				image : {height : 250, width : 250},
				page : {height : 250, width : 250},
				inline : {height : 250, width : 250},
				media : {height : 250, width : 250},
				external : {height : 250, width : 250},
				titleHeight : 25
			},
			classNames : {	
				standard : 'lightwindow',
				action : 'lightwindow_action'
			},
			fileTypes : {
				page : ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'pl', 'php4', 'php3', 'php', 'php5', 'phtml', 'rhtml', 'shtml', 'txt', 'vbs', 'rb'],
				media : ['aif', 'aiff', 'asf', 'avi', 'divx', 'm1v', 'm2a', 'm2v', 'm3u', 'mid', 'midi', 'mov', 'moov', 'movie', 'mp2', 'mp3', 'mpa', 'mpa', 'mpe', 'mpeg', 'mpg', 'mpg', 'mpga', 'pps', 'qt', 'rm', 'ram', 'swf', 'viv', 'vivo', 'wav'],
				image : ['bmp', 'gif', 'jpg', 'png', 'tiff']
			},
			mimeTypes : {
				avi : 'video/avi',
				aif : 'audio/aiff',
				aiff : 'audio/aiff',
				gif : 'image/gif',
				bmp : 'image/bmp',
				jpeg : 'image/jpeg',
				m1v : 'video/mpeg',
				m2a : 'audio/mpeg',
				m2v : 'video/mpeg',
				m3u : 'audio/x-mpequrl',
				mid : 'audio/x-midi',
				midi : 'audio/x-midi',
				mjpg : 'video/x-motion-jpeg',
				moov : 'video/quicktime',
				mov : 'video/quicktime',
				movie : 'video/x-sgi-movie',
				mp2 : 'audio/mpeg',
				mp3 : 'audio/mpeg3',
				mpa : 'audio/mpeg',
				mpa : 'video/mpeg',
				mpe : 'video/mpeg',
				mpeg : 'video/mpeg',
				mpg : 'audio/mpeg',
				mpg : 'video/mpeg',
				mpga : 'audio/mpeg',
				pdf : 'application/pdf',
				png : 'image/png',
				pps : 'application/mspowerpoint',
				qt : 'video/quicktime',
				ram : 'audio/x-pn-realaudio-plugin',
				rm : 'application/vnd.rn-realmedia',
				swf	: 'application/x-shockwave-flash',
				tiff : 'image/tiff',
				viv : 'video/vivo',
				vivo : 'video/vivo',
				wav : 'audio/wav',
				wmv : 'application/x-mplayer2'			
			},	
			classids : {
				mov : 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
				swf : 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
				wmv : 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6'
			},
			codebases : {
				mov : 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',
				swf : 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0',
				wmv : 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715'
			},	
			viewportPadding : 10,
			EOLASFix : 'swf,wmv,fla,flv',
			overlay : {
				opacity : 0.7,
				image : 'http://www.efigip.org/modules/efigip/images/lightwindow/black.png',
				presetImage : 'http://www.efigip.org/modules/efigip/images/lightwindow/black-70.png'
			},
			skin : 	{
				main : 	'<div id="lightwindow_container" >'+
							'<div id="lightwindow_title_bar" >'+
								'<div id="lightwindow_title_bar_inner" >'+
									'<span id="lightwindow_title_bar_title"></span>'+
									'<a id="lightwindow_title_bar_close_link" >Fermer</a>'+
								'</div>'+
							'</div>'+
							'<div id="lightwindow_stage" >'+
								'<div id="lightwindow_contents" >'+
								'</div>'+
								'<div id="lightwindow_navigation" >'+
									'<a href="#" id="lightwindow_previous" >'+
										'<span id="lightwindow_previous_title"></span>'+
									'</a>'+
									'<a href="#" id="lightwindow_next" >'+
										'<span id="lightwindow_next_title"></span>'+
									'</a>'+
									'<iframe name="lightwindow_navigation_shim" id="lightwindow_navigation_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>'+
								'</div>'+								
								'<div id="lightwindow_galleries">'+
									'<div id="lightwindow_galleries_tab_container" >'+
										'<a href="#" id="lightwindow_galleries_tab" >'+
											'<span id="lightwindow_galleries_tab_span" class="up" >Galleries</span>'+
										'</a>'+
									'</div>'+
									'<div id="lightwindow_galleries_list" >'+
									'</div>'+
								'</div>'+
							'</div>'+
							'<div id="lightwindow_data_slide" >'+
								'<div id="lightwindow_data_slide_inner" >'+
									'<div id="lightwindow_data_details" >'+
										'<div id="lightwindow_data_gallery_container" >'+
											'<span id="lightwindow_data_gallery_current"></span>'+
											' of '+
											'<span id="lightwindow_data_gallery_total"></span>'+
										'</div>'+
										'<div id="lightwindow_data_author_container" >'+
											'by <span id="lightwindow_data_author"></span>'+
										'</div>'+
									'</div>'+
									'<div id="lightwindow_data_caption" >'+
									'</div>'+
								'</div>'+
							'</div>'+
						'</div>',	
				loading : 	'<div id="lightwindow_loading" >'+
								'<img src="http://www.efigip.org/modules/efigip/images/lightwindow/ajax-loading.gif" alt="loading" />'+
								'<span>Chargement ou <a href="javascript: myLightWindow.deactivate();">Abandonner</a></span>'+
								'<iframe name="lightwindow_loading_shim" id="lightwindow_loading_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>'+
							'</div>',
				iframe : 	'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+
							'<html xmlns="http://www.w3.org/1999/xhtml">'+
								'<body>'+
									'{body_replace}'+
								'</body>'+
							'</html>',
				gallery : {
					top :		'<div class="lightwindow_galleries_list">'+
									'<h1>{gallery_title_replace}</h1>'+
									'<ul>',
					middle : 			'<li>'+
											'{gallery_link_replace}'+
										'</li>',
					bottom : 		'</ul>'+
								'</div>'
				}
			},
			formMethod : 'get',
			hideFlash : false,
			hideGalleryTab : false,
			showTitleBar : true,
			animationHandler : false,
			navigationHandler : false,
			transitionHandler : false,
			finalAnimationHandler : false,
			formHandler : false,
			galleryAnimationHandler : false,
			showGalleryCount : true
		}, options || {});
		this.duration = ((11-this.options.resizeSpeed)*0.15);
		this._setupLinks();
		this._getScroll();
		this._getPageDimensions();
		this._browserDimensions();
		this._addLightWindowMarkup(false);
		this._setupDimensions(); 
		this.buildGalleryList();
	},
	//
	//	Activate the lightwindow.
	//
	activate : function(e, link){		
		// Clear out the window Contents
		this._clearWindowContents(true);
			
		// Add back in out loading panel
		this._addLoadingWindowMarkup();

		// Setup the element properties
		this._setupWindowElements(link);
		
		// Setup everything
		this._getScroll();
		this._browserDimensions();
		this._setupDimensions();
		this._toggleTroubleElements('hidden', false);
		this._displayLightWindow('block', 'hidden');
		this._setStatus(true);
		this._monitorKeyboard(true);
		this._prepareIE(true);
		this._loadWindow();
	},
	//
	//	Turn off the window
	//
	deactivate : function(){
		// The window is not active
		this.windowActive = false;
		
		// There is no longer a gallery active
		this.activeGallery = false;
		if (!this.options.hideGalleryTab) {
			this._handleGalleryAnimation(false);
		}
		
		// Kill the animation
		this.animating = false;
		
		// Clear our element
		this.element = null;
		
		// hide the window.
		this._displayLightWindow('none', 'visible');
		
		// Clear out the window Contents
		this._clearWindowContents(false);
		
		// Stop all animation
		var queue = Effect.Queues.get('lightwindowAnimation').each(function(e){e.cancel();});
		
		// Undo the setup
		this._prepareIE(false);
		this._setupDimensions();
		this._toggleTroubleElements('visible', false);	
		this._monitorKeyboard(false);	
	},
	//
	//  Initialize specific window
	//
	createWindow : function(element, attributes) {
		this._processLink($(element));
	},
	//
	//  Open a Window from a hash of attributes
	//
	activateWindow : function(options) {
		this.element = Object.extend({
			href : null,
			title : null,
			author : null,
			caption : null,
			rel : null,
			top : null,
			left : null,
			type : null,
			showImages : null,
			height : null,
			width : null,
			loadingAnimation : null,
			iframeEmbed : null,
			form : null
		}, options || {});
		
		// Set the window type
		this.contentToFetch = this.element.href;
		this.windowType = this.element.type ? this.element.type : this._fileType(this.element.href);	
		
		// Clear out the window Contents
		this._clearWindowContents(true);
			
		// Add back in out loading panel
		this._addLoadingWindowMarkup();
		
		// Setup everything
		this._getScroll();
		this._browserDimensions();
		this._setupDimensions();
		this._toggleTroubleElements('hidden', false);
		this._displayLightWindow('block', 'hidden');
		this._setStatus(true);
		this._monitorKeyboard(true);
		this._prepareIE(true);
		this._loadWindow();
	},
	//
	//  Fire off our Form handler
	//
	submitForm : function(e) {
		if (this.options.formHandler) {
			this.options.formHandler(e);
		} else {
			this._defaultFormHandler(e);
		}
	},
	//
	//	Reload the window with another location
	//
	openWindow : function(element) {
		var element = $(element);

		// The window is active
		this.windowActive = true;
		
		// Clear out the window Contents
		this._clearWindowContents(true);
		
		// Add back in out loading panel
		this._addLoadingWindowMarkup();
		
		// Setup the element properties
		this._setupWindowElements(element);

		this._setStatus(true);
		this._handleTransition();
	},
	//
	//  Navigate the window
	//
	navigateWindow : function(direction) {
		this._handleNavigation(false);
		if (direction == 'previous') {
			this.openWindow(this.navigationObservers.previous);
		} else if (direction == 'next'){ 
			this.openWindow(this.navigationObservers.next);
		}
	},
	//
	//  Build the Gallery List and Load it
	//
	buildGalleryList : function() {
		var output = '';
		var galleryLink;
		for (i in this.galleries) {
			if (typeof this.galleries[i] == 'object') {
				output += (this.options.skin.gallery.top).replace('{gallery_title_replace}', unescape(i));
				for (j in this.galleries[i]) {
					if (typeof this.galleries[i][j] == 'object') {						
						galleryLink = '<a href="#" id="lightwindow_gallery_'+i+'_'+j+'" >'+unescape(j)+'</a>';
						output += (this.options.skin.gallery.middle).replace('{gallery_link_replace}', galleryLink);
					}
				}
				output += this.options.skin.gallery.bottom;
			}
		}
		new Insertion.Top('lightwindow_galleries_list', output);
		
		// Attach Events
		for (i in this.galleries) {
			if (typeof this.galleries[i] == 'object') {
				for (j in this.galleries[i]) {
					if (typeof this.galleries[i][j] == 'object') {
						Event.observe($('lightwindow_gallery_'+i+'_'+j), 'click', this.openWindow.bind(this, this.galleries[i][j][0]), false);
						$('lightwindow_gallery_'+i+'_'+j).onclick = function() {return false;};	
					}
				}
			}
		}
	},
	// 
	//  Set Links Up
	//
	_setupLinks : function() {
		var links = $$('.'+this.options.classNames.standard);
		links.each(function(link) {
			this._processLink(link);
		}.bind(this));	
	},
	//
	//  Process a Link
	//
	_processLink : function(link) {
		if ((this._fileType(link.getAttribute('href')) == 'image' || this._fileType(link.getAttribute('href')) == 'media')) {
			if (gallery = this._getGalleryInfo(link.rel)) {
				if (!this.galleries[gallery[0]]) {
					this.galleries[gallery[0]] = new Array();
				}
				if (!this.galleries[gallery[0]][gallery[1]]) {
					this.galleries[gallery[0]][gallery[1]] = new Array();
				}
				this.galleries[gallery[0]][gallery[1]].push(link);
			}
		}
		
		// Take care of our inline content
		var url = link.getAttribute('href');
		if (url.indexOf('?') > -1) {
			url = url.substring(0, url.indexOf('?'));
		}
		var container = url.substring(url.indexOf('#')+1);
		if($(container)) {
			$(container).setStyle({
				display : 'none'
			});
		}
		
		Event.observe(link, 'click', this.activate.bindAsEventListener(this, link), false);
		link.onclick = function() {return false;};		
	},
	//
	//	Setup our actions
	//
	_setupActions : function() {
		var links = $$('#lightwindow_container .'+this.options.classNames.action);
		links.each(function(link) {
			Event.observe(link, 'click', this[link.getAttribute('rel')].bindAsEventListener(this, link), false);
			link.onclick = function() {return false;};
		}.bind(this));
	},
	//
	//	Add the markup to the page.
	//
	_addLightWindowMarkup : function(rebuild) {
		var overlay = Element.extend(document.createElement('div'));
		overlay.setAttribute('id', 'lightwindow_overlay');		
		// FF Mac has a problem with putting Flash above a layer without a 100% opacity background, so we need to use a pre-made
		if (Prototype.Browser.Gecko) {
			overlay.setStyle({
				backgroundImage: 'url('+this.options.overlay.presetImage+')',
				backgroundRepeat: 'repeat',
				height: this.pageDimensions.height+'px'
			});			
		} else {
			overlay.setStyle({
				opacity: this.options.overlay.opacity,
				backgroundImage: 'url('+this.options.overlay.image+')',
				backgroundRepeat: 'repeat',
				height: this.pageDimensions.height+'px'
			});
		}
		
		var lw = document.createElement('div');
		lw.setAttribute('id', 'lightwindow');
		lw.innerHTML = this.options.skin.main;
		
		var body = document.getElementsByTagName('body')[0];
		body.appendChild(overlay);
		body.appendChild(lw);	
				
		if ($('lightwindow_title_bar_close_link')) {
			Event.observe('lightwindow_title_bar_close_link', 'click', this.deactivate.bindAsEventListener(this));
			$('lightwindow_title_bar_close_link').onclick = function() {return false;};
		}
			
		Event.observe($('lightwindow_previous'), 'click', this.navigateWindow.bind(this, 'previous'), false);
		$('lightwindow_previous').onclick = function() {return false;};		
		Event.observe($('lightwindow_next'), 'click', this.navigateWindow.bind(this, 'next'), false);
		$('lightwindow_next').onclick = function() {return false;};

		if (!this.options.hideGalleryTab) {
			Event.observe($('lightwindow_galleries_tab'), 'click', this._handleGalleryAnimation.bind(this, true), false);
			$('lightwindow_galleries_tab').onclick = function() {return false;};
		}
		
		// Because we use position absolute, kill the scroll Wheel on animations
		if (Prototype.Browser.IE) {
			Event.observe(document, 'mousewheel', this._stopScrolling.bindAsEventListener(this), false);
		} else {
			Event.observe(window, 'DOMMouseScroll', this._stopScrolling.bindAsEventListener(this), false);
		}
				
		Event.observe(overlay, 'click', this.deactivate.bindAsEventListener(this), false);
		overlay.onclick = function() {return false;};
	},
	//
	//  Add loading window markup
	//
	_addLoadingWindowMarkup : function() {
		$('lightwindow_contents').innerHTML += this.options.skin.loading;
	},
	//
	//  Setup the window elements
	//
	_setupWindowElements : function(link) {
		this.element = link;
		this.element.title = null ? '' : link.getAttribute('title');
		this.element.author = null ? '' : link.getAttribute('author');
		this.element.caption = null ? '' : link.getAttribute('caption');
		this.element.rel = null ? '' : link.getAttribute('rel');
		this.element.params = null ? '' : link.getAttribute('params');

		// Set the window type
		this.contentToFetch = this.element.href;
		this.windowType = this._getParameter('lightwindow_type') ? this._getParameter('lightwindow_type') : this._fileType(this.contentToFetch);	
	},
	//
	//  Clear the window contents out
	//
	_clearWindowContents : function(contents) {
		// If there is an iframe, its got to go
		if ($('lightwindow_iframe')) {
			Element.remove($('lightwindow_iframe'));
		}

		// Stop playing an object if its still around
		if ($('lightwindow_media_primary')) {
			try {
				$('lightwindow_media_primary').Stop();
			} catch(e) {}
			Element.remove($('lightwindow_media_primary'));
		}

		// Stop playing an object if its still around		
		if ($('lightwindow_media_secondary')) {
			try {
				$('lightwindow_media_secondary').Stop();
			} catch(e) {}
			Element.remove($('lightwindow_media_secondary'));
		}
		
		this.activeGallery = false;
		this._handleNavigation(this.activeGallery);
		
		if (contents) {
			// Empty the contents
			$('lightwindow_contents').innerHTML = '';
			
			// Reset the scroll bars
			$('lightwindow_contents').setStyle({
				overflow: 'hidden'
			});		
			
			if (!this.windowActive) {
				$('lightwindow_data_slide_inner').setStyle({
					display: 'none'
				});

				$('lightwindow_title_bar_title').innerHTML = '';
			}

			// Because of browser differences and to maintain flexible captions we need to reset this height at close
			$('lightwindow_data_slide').setStyle({
				height: 'auto'
			});
		}
		
		this.resizeTo.height = null;
		this.resizeTo.width = null;
	},
	//
	//	Set the status of our animation to keep things from getting clunky
	//
	_setStatus : function(status) {
		this.animating = status;
		if (status) {
			Element.show('lightwindow_loading');
		}
		if (!(/MSIE 6./i.test(navigator.userAgent))) {
			this._fixedWindow(status);
		}
	},
	//
	//  Make this window Fixed
	//
	_fixedWindow : function(status) {
		if (status) {
			if (this.windowActive) {
				this._getScroll();
				$('lightwindow').setStyle({
					position: 'absolute',
					top: parseFloat($('lightwindow').getStyle('top'))+this.pagePosition.y+'px',
					left: parseFloat($('lightwindow').getStyle('left'))+this.pagePosition.x+'px'
				});		
			} else {
				$('lightwindow').setStyle({
					position: 'absolute'
				});						
			}
		} else {
			if (this.windowActive) {
				this._getScroll();
				$('lightwindow').setStyle({
					position: 'fixed',
					top: parseFloat($('lightwindow').getStyle('top'))-this.pagePosition.y+'px',
					left: parseFloat($('lightwindow').getStyle('left'))-this.pagePosition.x+'px'
				});		
			} else {
				if ($('lightwindow_iframe')) {
					// Ideally here we would set a 50% value for top and left, but Safari rears it ugly head again and we need to do it by pixels
					this._browserDimensions();
				}
				$('lightwindow').setStyle({
					position: 'fixed',
					top: (parseFloat(this._getParameter('lightwindow_top')) ? parseFloat(this._getParameter('lightwindow_top'))+'px' : this.dimensions.viewport.height/2+'px'),
					left: (parseFloat(this._getParameter('lightwindow_left')) ? parseFloat(this._getParameter('lightwindow_left'))+'px' : this.dimensions.viewport.width/2+'px')
				});
			}
		}
	},
	//
	//	Prepare the window for IE.
	//
	_prepareIE : function(setup) {
		if (Prototype.Browser.IE) {
			var height, overflowX, overflowY;
			if (setup) { 
				var height = '100%';
			} else {
				var height = 'auto';
			}
			var body = document.getElementsByTagName('body')[0];
			var html = document.getElementsByTagName('html')[0];
			html.style.height = body.style.height = height;
		}
	},
	_stopScrolling : function(e) {
		if (this.animating) {
			if (e.preventDefault) {
				e.preventDefault();
			}
			e.returnValue = false;		
		}
	},
	//
	//	Get the scroll for the page.
	//
	_getScroll : function(){
      	if(typeof(window.pageYOffset) == 'number') {
        	this.pagePosition.x = window.pageXOffset;
        	this.pagePosition.y = window.pageYOffset;
      	} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
	       	this.pagePosition.x = document.body.scrollLeft;
        	this.pagePosition.y = document.body.scrollTop;
		} else if(document.documentElement) {
        	this.pagePosition.x = document.documentElement.scrollLeft;
        	this.pagePosition.y = document.documentElement.scrollTop;
      	}
	},
	//
	//	Reset the scroll.
	//
	_setScroll : function(x, y) {
		document.documentElement.scrollLeft = x; 
		document.documentElement.scrollTop = y; 
	},
	//
	//	Hide Selects from the page because of IE.
	//     We could use iframe shims instead here but why add all the extra markup for one browser when this is much easier and cleaner
	//
	_toggleTroubleElements : function(visibility, content){
		
		if (content) {
			var selects = $('lightwindow_contents').getElementsByTagName('select');
		} else {
			var selects = document.getElementsByTagName('select');
		}
		
		for(var i = 0; i < selects.length; i++) {
			selects[i].style.visibility = visibility;
		}
		
		if (!content) {
			if (this.options.hideFlash){
				var objects = document.getElementsByTagName('object');
				for (i = 0; i != objects.length; i++) {
					objects[i].style.visibility = visibility;
				}
				var embeds = document.getElementsByTagName('embed');
				for (i = 0; i != embeds.length; i++) {
					embeds[i].style.visibility = visibility;
				}
			}
			var iframes = document.getElementsByTagName('iframe');
			for (i = 0; i != iframes.length; i++) {
				iframes[i].style.visibility = visibility;
			}
		}
	},
	// 
	//  Get the actual page size
	//
	_getPageDimensions : function() {
		var xScroll, yScroll;
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = document.body.scrollWidth;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ 
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { 
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}

		var windowWidth, windowHeight;
		if (self.innerHeight) {	
			windowWidth = self.innerWidth;
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { 
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { 
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	

		if(yScroll < windowHeight){
			this.pageDimensions.height = windowHeight;
		} else { 
			this.pageDimensions.height = yScroll;
		}

		if(xScroll < windowWidth){	
			this.pageDimensions.width = windowWidth;
		} else {
			this.pageDimensions.width = xScroll;
		}
	},
	//
	//	Display the lightWindow.
	//
	_displayLightWindow : function(display, visibility) {
		$('lightwindow_overlay').style.display = $('lightwindow').style.display = $('lightwindow_container').style.display = display;	
		$('lightwindow_overlay').style.visibility = $('lightwindow').style.visibility = $('lightwindow_container').style.visibility = visibility;
	},
	//
	//	Setup Dimensions of lightwindow.

	//
	_setupDimensions : function() {

		var originalHeight, originalWidth;
		switch (this.windowType) {
			case 'page' :
				originalHeight = this.options.dimensions.page.height;
				originalWidth = this.options.dimensions.page.width;
				break;

			case 'image' :
				originalHeight = this.options.dimensions.image.height;
				originalWidth = this.options.dimensions.image.width;
				break;
				
			case 'media' :
				originalHeight = this.options.dimensions.media.height;
				originalWidth = this.options.dimensions.media.width;
				break;
			
			case 'external' : 
				originalHeight = this.options.dimensions.external.height;
				originalWidth = this.options.dimensions.external.width;
				break;
				
			case 'inline' :
				originalHeight = this.options.dimensions.inline.height;
				originalWidth = this.options.dimensions.inline.width;
				break;
				
			default :
				originalHeight = this.options.dimensions.page.height;
				originalWidth = this.options.dimensions.page.width;
				break;
				
		}

		var offsetHeight = this._getParameter('lightwindow_top') ? parseFloat(this._getParameter('lightwindow_top'))+this.pagePosition.y : this.dimensions.viewport.height/2+this.pagePosition.y;
		var offsetWidth = this._getParameter('lightwindow_left') ? parseFloat(this._getParameter('lightwindow_left'))+this.pagePosition.x : this.dimensions.viewport.width/2+this.pagePosition.x;
		
		// So if a theme has say shadowed edges, they should be consistant and take care of in the contentOffset
		$('lightwindow').setStyle({
			top: offsetHeight+'px',
			left: offsetWidth+'px'
		});
		
		$('lightwindow_container').setStyle({
			height: originalHeight+'px',
			width: originalWidth+'px',
			left: -(originalWidth/2)+'px',
			top: -(originalHeight/2)+'px'
		});

		$('lightwindow_contents').setStyle({
			height: originalHeight+'px',
			width: originalWidth+'px'
		});
	},
	//
	//	Get the type of file.
	//
	_fileType : function(url) {
		var image = new RegExp("[^\.]\.("+this.options.fileTypes.image.join('|')+")\s*$", "i");
		if (image.test(url)) return 'image';
		if (url.indexOf('#') > -1 && (document.domain == this._getDomain(url))) return 'inline';		
		if (url.indexOf('?') > -1) url = url.substring(0, url.indexOf('?'));
		var type = 'unknown';
		var page = new RegExp("[^\.]\.("+this.options.fileTypes.page.join('|')+")\s*$", "i");
		var media = new RegExp("[^\.]\.("+this.options.fileTypes.media.join('|')+")\s*$", "i");
		if (document.domain != this._getDomain(url)) type = 'external';
	  	if (media.test(url)) type = 'media';
		if (type == 'external' || type == 'media') return type;
	  	if (page.test(url) || url.substr((url.length-1), url.length) == '/') type = 'page';
		return type;
	},
	//
	//  Get file Extension
	//
	_fileExtension : function(url) {
		if (url.indexOf('?') > -1) {
			url = url.substring(0, url.indexOf('?'));
		}
		var extenstion = '';
		for (var x = (url.length-1); x > -1; x--) {
			if (url.charAt(x) == '.') {
				return extenstion;
			}
			extenstion = url.charAt(x)+extenstion;
		}
	},
	//
	//	Monitor the keyboard while this lightwindow is up
	//
	_monitorKeyboard : function(status) {
		if (status) document.onkeydown = this._eventKeypress.bind(this); 
		else document.onkeydown = '';
	},
	//
	//  Perform keyboard actions
	//
	_eventKeypress : function(e) {
		if (e == null) {
			var keycode = event.keyCode;
		} else {
			var keycode = e.which;
		}
		
		switch (keycode) { 
			case 27: 
				this.deactivate(); 
				break;
			
			case 13:
				return;
				
			default:
				break;
		}
	
		// Gotta stop those quick fingers
		if (this.animating) {
			return false;
		}
		
		switch (String.fromCharCode(keycode).toLowerCase()) {
			case 'p':
				if (this.navigationObservers.previous) {
					this.navigateWindow('previous');
				}
				break;
				
			case 'n':
				if (this.navigationObservers.next) {
					this.navigateWindow('next');
				}
				break;
				
			default:
				break;
		}
	},
	//
	//	Get Gallery Information
	//
	_getGalleryInfo : function(rel) {
		if (!rel) return false;
		if (rel.indexOf('[') > -1) {
			return new Array(escape(rel.substring(0, rel.indexOf('['))), escape(rel.substring(rel.indexOf('[')+1, rel.indexOf(']'))));
		} else {
			return false;
		}
	},
	//
	//	Get the domain from a string.
	//
	_getDomain : function(url) {    
        var leadSlashes = url.indexOf('//');
        var domainStart = leadSlashes+2;
        var withoutResource = url.substring(domainStart, url.length);
        var nextSlash = withoutResource.indexOf('/');
        var domain = withoutResource.substring(0, nextSlash);
		if (domain.indexOf(':') > -1){
			var portColon = domain.indexOf(':');
			domain = domain.substring(0, portColon);
       	}
		return domain;
    },
	//
	//	Get the value from the params attribute string.
	//
	_getParameter : function(parameter, parameters) {
		if (!this.element) return false;
		if (parameter == 'lightwindow_top' && this.element.top) {
			return unescape(this.element.top);
		} else if (parameter == 'lightwindow_left' && this.element.left) {
			return unescape(this.element.left);
		} else if (parameter == 'lightwindow_type' && this.element.type) {
			return unescape(this.element.type);
		} else if (parameter == 'lightwindow_show_images' && this.element.showImages) {
			return unescape(this.element.showImages);
		} else if (parameter == 'lightwindow_height' && this.element.height) {
			return unescape(this.element.height);
		} else if (parameter == 'lightwindow_width' && this.element.width) {
			return unescape(this.element.width);
		} else if (parameter == 'lightwindow_loading_animation' && this.element.loadingAnimation) {
			return unescape(this.element.loadingAnimation);
		} else if (parameter == 'lightwindow_iframe_embed' && this.element.iframeEmbed) {
			return unescape(this.element.iframeEmbed);
		} else if (parameter == 'lightwindow_form' && this.element.form) {
			return unescape(this.element.form);
		} else {
			if (!parameters) {
				if (this.element.params) parameters = this.element.params;
				else return;
			}
			var value;
			var parameterArray = parameters.split(',');
			var compareString = parameter+'=';
			var compareLength = compareString.length;
			for (var i = 0; i < parameterArray.length; i++) {
				if (parameterArray[i].substr(0, compareLength) == compareString) {
					var currentParameter = parameterArray[i].split('=');
					value = currentParameter[1];
					break;
				}
			}
			if (!value) return false;
			else return unescape(value);
		}
	},
	//
	//  Get the Browser Viewport Dimensions
	//
	_browserDimensions : function() {
		if (Prototype.Browser.IE) {
            this.dimensions.viewport.height = document.documentElement.clientHeight;
            this.dimensions.viewport.width = document.documentElement.clientWidth;   
        } else {
            this.dimensions.viewport.height = window.innerHeight;
            this.dimensions.viewport.width = document.width || document.body.offsetWidth;
        }
	},
	//
	//  Get the scrollbar offset, I don't like this method but there is really no other way I can find.
	//
	_getScrollerWidth : function() {
	    var scrollDiv = Element.extend(document.createElement('div'));
		scrollDiv.setAttribute('id', 'lightwindow_scroll_div');
		scrollDiv.setStyle({
			position: 'absolute',
			top: '-10000px',
			left: '-10000px',
			width: '100px',
			height: '100px',
			overflow: 'hidden'
		});



	    var contentDiv = Element.extend(document.createElement('div'));
		contentDiv.setAttribute('id', 'lightwindow_content_scroll_div');
		contentDiv.setStyle({
			width: '100%',
			height: '200px'
		});

	    scrollDiv.appendChild(contentDiv);

		var body = document.getElementsByTagName('body')[0];
		body.appendChild(scrollDiv);

	    var noScroll = $('lightwindow_content_scroll_div').offsetWidth;
	    scrollDiv.style.overflow = 'auto';
    	var withScroll = $('lightwindow_content_scroll_div').offsetWidth;

	   	Element.remove($('lightwindow_scroll_div'));

	    this.scrollbarOffset = noScroll-withScroll;
	},
	

	//
	//  Add a param to an object dynamically created
	//
	_addParamToObject : function(name, value, object, id) {
		var param = document.createElement('param');
		param.setAttribute('value', value);
		param.setAttribute('name', name);
		if (id) {
			param.setAttribute('id', id);
		}
		object.appendChild(param);
		return object;
	},
	//
	//  Get the outer HTML of an object CROSS BROWSER
	//
	_outerHTML : function(object) {
 		if (Prototype.Browser.IE) {
			return object.outerHTML;
		} else {
			var clone = object.cloneNode(true);
			var cloneDiv = document.createElement('div');
			cloneDiv.appendChild(clone);
			return cloneDiv.innerHTML;
		}
	},
	//
	//  Convert an object to markup
	//
	_convertToMarkup : function(object, closeTag) {
		var markup = this._outerHTML(object).replace('</'+closeTag+'>', '');
		if (Prototype.Browser.IE) {
			for (var i = 0; i < object.childNodes.length; i++){
				markup += this._outerHTML(object.childNodes[i]);
			}
			markup += '</'+closeTag+'>';
		}
		return markup;
	},
	//
	//  Depending what type of browser it is we have to append the object differently... DAMN YOU IE!!
	//
	_appendObject : function(object, closeTag, appendTo) {
		if (Prototype.Browser.IE) {
			appendTo.innerHTML += this._convertToMarkup(object, closeTag);
			
			// Fix the Eolas activate thing but only for specified media, for example doing this to a quicktime film breaks it.
			if (this.options.EOLASFix.indexOf(this._fileType(this.element.href)) > -1) {
				var objectElements = document.getElementsByTagName('object');
				for (var i = 0; i < objectElements.length; i++) {
					if (objectElements[i].getAttribute("data")) objectElements[i].removeAttribute('data');
					objectElements[i].outerHTML = objectElements[i].outerHTML;
					objectElements[i].style.visibility = "visible";
				}
			}
		} else {
			appendTo.appendChild(object);	
		}	
	},
	//
	//  Add in iframe
	//
	_appendIframe : function(scroll) {
		var iframe = document.createElement('iframe');
		iframe.setAttribute('id', 'lightwindow_iframe');
		iframe.setAttribute('name', 'lightwindow_iframe');
		iframe.setAttribute('src', 'about:blank');
		iframe.setAttribute('height', '100%');
		iframe.setAttribute('width', '100%');
		iframe.setAttribute('frameborder', '0');
		iframe.setAttribute('marginwidth', '0');
		iframe.setAttribute('marginheight', '0');
		iframe.setAttribute('scrolling', scroll);	
		
		this._appendObject(iframe, 'iframe', $('lightwindow_contents'));
	},
	//
	//  Write Content to the iframe using the skin
	//
	_writeToIframe : function(content) {
		var template = this.options.skin.iframe;
		template = template.replace('{body_replace}', content); 
		if ($('lightwindow_iframe').contentWindow){
			$('lightwindow_iframe').contentWindow.document.open();
			$('lightwindow_iframe').contentWindow.document.write(template);
			$('lightwindow_iframe').contentWindow.document.close();
		} else {
			$('lightwindow_iframe').contentDocument.open();
			$('lightwindow_iframe').contentDocument.write(template);
			$('lightwindow_iframe').contentDocument.close();
		}
	},
	//
	//  Load the window Information
	//  
	_loadWindow : function() {
		switch (this.windowType) {
			case 'image' :

				var current = 0;
				var images = [];
				this.checkImage = [];
				this.resizeTo.height = this.resizeTo.width = 0;
				this.imageCount = this._getParameter('lightwindow_show_images') ? parseInt(this._getParameter('lightwindow_show_images')) : 1;

				// If there is a gallery get it
				if (gallery = this._getGalleryInfo(this.element.rel)) {	
					for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
						if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
							break;
						}
					}
					if (this.galleries[gallery[0]][gallery[1]][current-this.imageCount]) {
						this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current-this.imageCount];
					} else {
						this.navigationObservers.previous = false;
					}
					if (this.galleries[gallery[0]][gallery[1]][current+this.imageCount]) {
						this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current+this.imageCount];
					} else {
						this.navigationObservers.next = false;
					}
					
					this.activeGallery = true;
				} else {
					this.navigationObservers.previous = false;
					this.navigationObservers.next = false;					

					this.activeGallery = false;
				}
				
				for (var i = current; i < (current+this.imageCount); i++) {
		
					if (gallery && this.galleries[gallery[0]][gallery[1]][i]) {
						this.contentToFetch = this.galleries[gallery[0]][gallery[1]][i].href;
						
						this.galleryLocation = {current: (i+1)/this.imageCount, total: (this.galleries[gallery[0]][gallery[1]].length)/this.imageCount};
											
						if (!this.galleries[gallery[0]][gallery[1]][i+this.imageCount]) {
							$('lightwindow_next').setStyle({
								display: 'none'
							});
						} else {
							$('lightwindow_next').setStyle({
								display: 'block'
							});
							$('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i+this.imageCount].title;
						}
						
						if (!this.galleries[gallery[0]][gallery[1]][i-this.imageCount]) {
							$('lightwindow_previous').setStyle({
								display: 'none'
							});
						} else {
							$('lightwindow_previous').setStyle({
								display: 'block'
							});
							$('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i-this.imageCount].title;
						}
					}

					images[i] = document.createElement('img');
					images[i].setAttribute('id', 'lightwindow_image_'+i);
					images[i].setAttribute('border', '0');
					images[i].setAttribute('src', this.contentToFetch);
					$('lightwindow_contents').appendChild(images[i]);

					// We have to do this instead of .onload 
					this.checkImage[i] = new PeriodicalExecuter(function(i) {
						if (!(typeof $('lightwindow_image_'+i).naturalWidth != "undefined" && $('lightwindow_image_'+i).naturalWidth == 0)) {
	
							this.checkImage[i].stop();
	
							var imageHeight = $('lightwindow_image_'+i).getHeight();
							if (imageHeight > this.resizeTo.height) {
								this.resizeTo.height = imageHeight;
							}
							this.resizeTo.width += $('lightwindow_image_'+i).getWidth();
							this.imageCount--;
	
							$('lightwindow_image_'+i).setStyle({
								height: '100%'
							});
	
						 	if (this.imageCount == 0) {
								this._processWindow();
						 	}
						}
					
					}.bind(this, i), 1);			
				}


			break;
		
		case 'media' :			
		
			var current = 0;
			this.resizeTo.height = this.resizeTo.width = 0;

			// If there is a gallery get it
			if (gallery = this._getGalleryInfo(this.element.rel)) {	
				for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
					if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
						break;
					}
				}
				
				if (this.galleries[gallery[0]][gallery[1]][current-1]) {
					this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current-1];
				} else {
					this.navigationObservers.previous = false;
				}
				if (this.galleries[gallery[0]][gallery[1]][current+1]) {
					this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current+1];
				} else {
					this.navigationObservers.next = false;
				}
		
				this.activeGallery = true;
			} else {
				this.navigationObservers.previous = false;
				this.navigationObservers.next = false;
				
				this.activeGallery = false;
			}
		

			if (gallery && this.galleries[gallery[0]][gallery[1]][current]) {
				this.contentToFetch = this.galleries[gallery[0]][gallery[1]][current].href;

				this.galleryLocation = {current: current+1, total: this.galleries[gallery[0]][gallery[1]].length};
				
				if (!this.galleries[gallery[0]][gallery[1]][current+1]) {
					$('lightwindow_next').setStyle({
						display: 'none'
					});
				} else {
					$('lightwindow_next').setStyle({
						display: 'block'
					});
					$('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current+1].title;
				}
				
				if (!this.galleries[gallery[0]][gallery[1]][current-1]) {
					$('lightwindow_previous').setStyle({
						display: 'none'
					});
				} else {
					$('lightwindow_previous').setStyle({
						display: 'block'
					});
					$('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current-1].title;
				}
			}
			
			if (this._getParameter('lightwindow_iframe_embed')) {
				this.resizeTo.height = this.dimensions.viewport.height;
				this.resizeTo.width = this.dimensions.viewport.width;	
			} else {
				this.resizeTo.height = this._getParameter('lightwindow_height');
				this.resizeTo.width = this._getParameter('lightwindow_width');				
			}
			
			this._processWindow();
			
			break;

		case 'external' :		

			this._appendIframe('auto');

			this.resizeTo.height = this.dimensions.viewport.height;
			this.resizeTo.width = this.dimensions.viewport.width;
						
			this._processWindow();

			break;
				
		case 'page' :	
			
			var newAJAX = new Ajax.Request(
				this.contentToFetch, {
					method: 'get', 
					parameters: '', 
					onComplete: function(response) {
						$('lightwindow_contents').innerHTML += response.responseText;
						this.resizeTo.height = $('lightwindow_contents').scrollHeight+(this.options.contentOffset.height);
						this.resizeTo.width = $('lightwindow_contents').scrollWidth+(this.options.contentOffset.width);
						this._processWindow();
					}.bind(this)
				}
			);
			
			break;
			
		case 'inline' : 
		
			var content = this.contentToFetch;
			if (content.indexOf('?') > -1) {
				content = content.substring(0, content.indexOf('?'));
			}
			content = content.substring(content.indexOf('#')+1);
			
			new Insertion.Top($('lightwindow_contents'), $(content).innerHTML);
			
			this.resizeTo.height = $('lightwindow_contents').scrollHeight+(this.options.contentOffset.height);
			this.resizeTo.width = $('lightwindow_contents').scrollWidth+(this.options.contentOffset.width);
			
			this._toggleTroubleElements('hidden', true); 			
			this._processWindow();
			
			break;
			
		default : 
			throw("Page Type could not be determined, please amend this lightwindow URL "+this.contentToFetch);
			break;
		}
	},
	//
	//  Resize the Window to fit the viewport if necessary
	//
	_resizeWindowToFit : function() {
		if (this.resizeTo.height+this.dimensions.cruft.height > this.dimensions.viewport.height) {
			var heightRatio = this.resizeTo.height/this.resizeTo.width;
			this.resizeTo.height = this.dimensions.viewport.height-this.dimensions.cruft.height-(2*this.options.viewportPadding);
			// We only care about ratio's with this window type			
			if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
				this.resizeTo.width = this.resizeTo.height/heightRatio;
				$('lightwindow_data_slide_inner').setStyle({
					width: this.resizeTo.width+'px'
				});			
			}
		} 
		if (this.resizeTo.width+this.dimensions.cruft.width > this.dimensions.viewport.width) {
			var widthRatio = this.resizeTo.width/this.resizeTo.height;
			this.resizeTo.width = this.dimensions.viewport.width-2*this.dimensions.cruft.width-(2*this.options.viewportPadding);
			// We only care about ratio's with this window type
			if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
				this.resizeTo.height = this.resizeTo.width/widthRatio;
				$('lightwindow_data_slide_inner').setStyle({
					height: this.resizeTo.height+'px'
				});
			}
		}
			
	},
	//
	//  Set the Window to a preset size
	//
	_presetWindowSize : function() {
		if (this._getParameter('lightwindow_height')) {
			this.resizeTo.height = parseFloat(this._getParameter('lightwindow_height'));
		}
		if (this._getParameter('lightwindow_width')) {
			this.resizeTo.width = parseFloat(this._getParameter('lightwindow_width'));
		}
	},
	//
	//  Process the Window
	//
	_processWindow : function() {
		// Clean out our effects
		this.dimensions.dataEffects = [];

		// Set up the data-slide if we have caption information
		if ((this.element.caption && this.element.caption != 'null') || (this.element.author && this.element.author != 'null') || (this.activeGallery && this.options.showGalleryCount)) {
			if (this.element.caption) {
				$('lightwindow_data_caption').innerHTML = this.element.caption;
				$('lightwindow_data_caption').setStyle({
					display: 'block'
				});
			} else {
				$('lightwindow_data_caption').setStyle({
					display: 'none'
				});				
			}
			if (this.element.author) {
				$('lightwindow_data_author').innerHTML = this.element.author;
				$('lightwindow_data_author_container').setStyle({
					display: 'block'
				});
			} else {
				$('lightwindow_data_author_container').setStyle({
					display: 'none'
				});				
			}
			if (this.activeGallery && this.options.showGalleryCount) {
				$('lightwindow_data_gallery_current').innerHTML = this.galleryLocation.current;
				$('lightwindow_data_gallery_total').innerHTML = this.galleryLocation.total;
				$('lightwindow_data_gallery_container').setStyle({
					display: 'block'
				});
			} else {
				$('lightwindow_data_gallery_container').setStyle({
					display: 'none'
				});				
			}

			$('lightwindow_data_slide_inner').setStyle({
				width: this.resizeTo.width+'px',
				height: 'auto',
				visibility: 'visible',
				display: 'block'
			});
			$('lightwindow_data_slide').setStyle({
				height: $('lightwindow_data_slide').getHeight()+'px',
				width: '1px',
				overflow: 'hidden',
				display: 'block'
			});
		} else {
			$('lightwindow_data_slide').setStyle({
				display: 'none',
				width: 'auto'
			});
			$('lightwindow_data_slide_inner').setStyle({
				display: 'none',
				visibility: 'hidden',
				width: this.resizeTo.width+'px',
				height: '0px'
			});
		}
				
		if (this.element.title != 'null') {		
			$('lightwindow_title_bar_title').innerHTML = this.element.title;
		} else {
			$('lightwindow_title_bar_title').innerHTML = '';
		}
		
		var originalContainerDimensions = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
		// Position the window
    	$('lightwindow_container').setStyle({
			height: 'auto',
			// We need to set the width to a px not auto as opera has problems with it
			width: $('lightwindow_container').getWidth()+this.options.contentOffset.width-(this.windowActive ? this.options.contentOffset.width : 0)+'px'
		});
		var newContainerDimensions = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
 		
		// We need to record the container dimension changes
		this.containerChange = {height: originalContainerDimensions.height-newContainerDimensions.height, width: originalContainerDimensions.width-newContainerDimensions.width};

		// Get out general dimensions
		this.dimensions.container = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
		this.dimensions.cruft = {height: this.dimensions.container.height-$('lightwindow_contents').getHeight()+this.options.contentOffset.height, width: this.dimensions.container.width-$('lightwindow_contents').getWidth()+this.options.contentOffset.width};
		
		// Set Sizes if we need too
		this._presetWindowSize();
		this._resizeWindowToFit(); // Even if the window is preset we still don't want it to go outside of the viewport

		if (!this.windowActive) {
			// Position the window
		   	$('lightwindow_container').setStyle({
				left: -(this.dimensions.container.width/2)+'px',
				top: -(this.dimensions.container.height/2)+'px'
			});
		}
	   	$('lightwindow_container').setStyle({
			height: this.dimensions.container.height+'px',
			width: this.dimensions.container.width+'px'
		});
		
		// We are ready, lets show this puppy off!
		this._displayLightWindow('block', 'visible');
		this._animateLightWindow();
	},
	//
	//  Fire off our animation handler
	//
	_animateLightWindow : function() {
		if (this.options.animationHandler) {
			this.options.animationHandler().bind(this);
		} else {
			this._defaultAnimationHandler();
		}
	},
	//
	//  Fire off our transition handler
	//
	_handleNavigation : function(display) {
		if (this.options.navigationHandler) {
			this.options.navigationHandler().bind(this, display);
		} else {
			this._defaultDisplayNavigation(display);
		}
	},
	//
	//  Fire off our transition handler
	//
	_handleTransition : function() {
		if (this.options.transitionHandler) {
			this.options.transitionHandler().bind(this);
		} else {
			this._defaultTransitionHandler();
		}
	},
	//
	//  Handle the finish of the window animation
	// 
	_handleFinalWindowAnimation : function(delay) {
		if (this.options.finalAnimationHandler) {
			this.options.finalAnimationHandler().bind(this, delay);
		} else {
			this._defaultfinalWindowAnimationHandler(delay);
		}		
	},
	//
	//  Handle the gallery Animation
	// 
	_handleGalleryAnimation : function(list) {
		if (this.options.galleryAnimationHandler) {
			this.options.galleryAnimationHandler().bind(this, list);
		} else {
			this._defaultGalleryAnimationHandler(list);
		}		
	},
	//
	//  Display the navigation 
	//
	_defaultDisplayNavigation : function(display) {
		if (display) {
			$('lightwindow_navigation').setStyle({
				display: 'block',
				height: $('lightwindow_contents').getHeight()+'px',
				width: '100%',
				marginTop: this.options.dimensions.titleHeight+'px'
			});			
		} else {
			$('lightwindow_navigation').setStyle({
				display: 'none',
				height: 'auto',
				width: 'auto'
			});			
		}
	},
	//
	//  This is the default animation handler for LightWindow
	//
	_defaultAnimationHandler : function() {	
		// Now that we have figures out the cruft lets make the caption go away and add its effects
		if (this.element.caption || this.element.author || (this.activeGallery && this.options.showGalleryCount)) {
			$('lightwindow_data_slide').setStyle({
				display: 'none',
				width: 'auto'
			});
			this.dimensions.dataEffects.push(
				new Effect.SlideDown('lightwindow_data_slide', {sync: true}),
				new Effect.Appear('lightwindow_data_slide', {sync: true, from: 0.0, to: 1.0})
			);
		}

		// Set up the Title if we have one
		$('lightwindow_title_bar_inner').setStyle({
			height: '0px',
			marginTop: this.options.dimensions.titleHeight+'px'
		});
		
		// We always want the title bar as well
		this.dimensions.dataEffects.push(
			new Effect.Morph('lightwindow_title_bar_inner', {sync: true, style: {height: this.options.dimensions.titleHeight+'px', marginTop: '0px'}}),
		 	new Effect.Appear('lightwindow_title_bar_inner', {sync: true, from: 0.0, to: 1.0})
		);		
		
		if (!this.options.hideGalleryTab) {
			this._handleGalleryAnimation(false);
			if ($('lightwindow_galleries_tab_container').getHeight() == 0) {
				this.dimensions.dataEffects.push(
					new Effect.Morph('lightwindow_galleries_tab_container', {sync: true, style: {height: '20px', marginTop: '0px'}})
				);
				$('lightwindow_galleries').setStyle({
					width: '0px'
				});
			}
		}
		
		var resized = false;
		var ratio = this.dimensions.container.width-$('lightwindow_contents').getWidth()+this.resizeTo.width+this.options.contentOffset.width;
		if (ratio != $('lightwindow_container').getWidth()) {
			new Effect.Parallel([
					new Effect.Scale('lightwindow_contents', 100*(this.resizeTo.width/$('lightwindow_contents').getWidth()), {scaleFrom: 100*($('lightwindow_contents').getWidth()/($('lightwindow_contents').getWidth()+(this.options.contentOffset.width))), sync: true,  scaleY: false, scaleContent: false}),
					new Effect.Scale('lightwindow_container', 100*(ratio/(this.dimensions.container.width)), {sync: true, scaleY: false, scaleFromCenter: true, scaleContent: false})
				], {
					duration: this.duration, 
					delay: 0.25,
					queue: {position: 'end', scope: 'lightwindowAnimation'}
				}
			);		
		}
		
		ratio = this.dimensions.container.height-$('lightwindow_contents').getHeight()+this.resizeTo.height+this.options.contentOffset.height;
		if (ratio != $('lightwindow_container').getHeight()) {
			new Effect.Parallel([
					new Effect.Scale('lightwindow_contents', 100*(this.resizeTo.height/$('lightwindow_contents').getHeight()), {scaleFrom: 100*($('lightwindow_contents').getHeight()/($('lightwindow_contents').getHeight()+(this.options.contentOffset.height))), sync: true, scaleX: false, scaleContent: false}),
					new Effect.Scale('lightwindow_container', 100*(ratio/(this.dimensions.container.height)), {sync: true, scaleX: false, scaleFromCenter: true, scaleContent: false})
				], {
					duration: this.duration, 
					afterFinish: function() {				
						if (this.dimensions.dataEffects.length > 0) {
							if (!this.options.hideGalleryTab) {
								$('lightwindow_galleries').setStyle({
									width: this.resizeTo.width+'px'
								});
							}
							new Effect.Parallel(this.dimensions.dataEffects, {
									duration: this.duration,
									afterFinish: function() {
										this._finishWindow();
									}.bind(this),
									queue: {position: 'end', scope: 'lightwindowAnimation'} 
								}
							);
						}
					}.bind(this), 
					queue: {position: 'end', scope: 'lightwindowAnimation'} 
				}
			);
			resized = true;
		}
		
		// We need to do our data effect since there was no resizing
		if (!resized && this.dimensions.dataEffects.length > 0) {	
			new Effect.Parallel(this.dimensions.dataEffects, {
					duration: this.duration,
					beforeStart: function() {
						if (!this.options.hideGalleryTab) {
							$('lightwindow_galleries').setStyle({
								width: this.resizeTo.width+'px'
							});
						}
						if (this.containerChange.height != 0 || this.containerChange.width != 0) {
							new Effect.MoveBy('lightwindow_container', this.containerChange.height, this.containerChange.width, {transition: Effect.Transitions.sinoidal});
						}
					}.bind(this),			
					afterFinish: function() {
						this._finishWindow();
					}.bind(this),
					queue: {position: 'end', scope: 'lightwindowAnimation'} 
				}
			);
		}			
		
	},
	//
	//  Finish up Window Animation
	//
	_defaultfinalWindowAnimationHandler : function(delay) {
		if (this.windowType == 'media' || this._getParameter('lightwindow_loading_animation')) {	
			// Because of major flickering with the overlay we just hide it in this case
			Element.hide('lightwindow_loading');
			this._handleNavigation(this.activeGallery);
			this._setStatus(false);
		} else {
			Effect.Fade('lightwindow_loading', {
				duration: 0.75,
				delay: 1.0, 
				afterFinish: function() {
					// Just in case we need some scroll goodness (this also avoids the swiss cheese effect)
					if (this.windowType != 'image' && this.windowType != 'media' && this.windowType != 'external') {
						$('lightwindow_contents').setStyle({
							overflow: 'auto'
						});
					}
					this._handleNavigation(this.activeGallery);
					this._defaultGalleryAnimationHandler();
					this._setStatus(false);
				}.bind(this),
				queue: {position: 'end', scope: 'lightwindowAnimation'}
			});
		}
	},
	//
	//  Handle the gallery Animation
	//
	_defaultGalleryAnimationHandler : function(list) {
		if (this.activeGallery) {
			$('lightwindow_galleries').setStyle({
				display: 'block',
				marginBottom: $('lightwindow_data_slide').getHeight()+this.options.contentOffset.height/2+'px'
			});
			$('lightwindow_navigation').setStyle({
				height: $('lightwindow_contents').getHeight()-20+'px'
			});
		} else {
			$('lightwindow_galleries').setStyle({
				display: 'none'
			});	
			$('lightwindow_galleries_tab_container').setStyle({
				height: '0px',
				marginTop: '20px'
			});
			$('lightwindow_galleries_list').setStyle({
				height: '0px'
			});
			return false;
		}
		
		if (list) {
			if ($('lightwindow_galleries_list').getHeight() == 0) {
				var height = $('lightwindow_contents').getHeight()*0.80;
				$('lightwindow_galleries_tab_span').className = 'down';
			} else {
				var height = 0;
				$('lightwindow_galleries_tab_span').className = 'up';
			}

			new Effect.Morph('lightwindow_galleries_list', {
				duration: this.duration,
				transition: Effect.Transitions.sinoidal,
				style: {height: height+'px'},
				beforeStart: function() {
					$('lightwindow_galleries_list').setStyle({
						overflow: 'hidden'
					});					
				},
				afterFinish: function() {
					$('lightwindow_galleries_list').setStyle({
						overflow: 'auto'
					});
				},
				queue: {position: 'end', scope: 'lightwindowAnimation'}
			});	
		}
		
		
	},
	//
	//  Default Transition Handler
	//
	_defaultTransitionHandler : function() {
		// Clean out our effects
		this.dimensions.dataEffects = [];

		// Now that we have figures out the cruft lets make the caption go away and add its effects
		if ($('lightwindow_data_slide').getStyle('display') != 'none') {
			this.dimensions.dataEffects.push(
				new Effect.SlideUp('lightwindow_data_slide', {sync: true}),
				new Effect.Fade('lightwindow_data_slide', {sync: true, from: 1.0, to: 0.0})
			);
		}
		
		if (!this.options.hideGalleryTab) {
			if ($('lightwindow_galleries').getHeight() != 0 && !this.options.hideGalleryTab) {
				this.dimensions.dataEffects.push(
					new Effect.Morph('lightwindow_galleries_tab_container', {sync: true, style: {height: '0px', marginTop: '20px'}})
				);
			}
			
			if ($('lightwindow_galleries_list').getHeight() != 0) {
				$('lightwindow_galleries_tab_span').className = 'up';
				this.dimensions.dataEffects.push(
					new Effect.Morph('lightwindow_galleries_list', {
						sync: true, 
						style: {height: '0px'},
						transition: Effect.Transitions.sinoidal,
						beforeStart: function() {
							$('lightwindow_galleries_list').setStyle({
								overflow: 'hidden'
							});					
						},
						afterFinish: function() {
							$('lightwindow_galleries_list').setStyle({
								overflow: 'auto'
							});
						}
					})
				);
			}
		}
		
		// We always want the title bar as well
		this.dimensions.dataEffects.push(
			new Effect.Morph('lightwindow_title_bar_inner', {sync: true, style: {height: '0px', marginTop: this.options.dimensions.titleHeight+'px'}}),
		 	new Effect.Fade('lightwindow_title_bar_inner', {sync: true, from: 1.0, to: 0.0})
		);

		new Effect.Parallel(this.dimensions.dataEffects, {
				duration: this.duration,
				afterFinish: function() {
					this._loadWindow();
				}.bind(this),
				queue: {position: 'end', scope: 'lightwindowAnimation'} 
			}
		);	
	},
	//
	//	Default Form handler for LightWindow
	//
	_defaultFormHandler : function(e) {
		var element = Event.element(e).parentNode;
		var parameterString = Form.serialize(this._getParameter('lightwindow_form', element.getAttribute('params')));
		if (this.options.formMethod == 'post') {
			var newAJAX = new Ajax.Request(element.href, { 
				method: 'post', 
				postBody: parameterString, 
				onComplete: this.openWindow.bind(this, element)
			});
		} else if (this.options.formMethod == 'get') {
			var newAJAX = new Ajax.Request(element.href, { 
				method: 'get', 
				parameters: parameterString, 
				onComplete: this.openWindow.bind(this, element)
			});
		}
	},
	// 
	//  Wrap everything up
	//
	_finishWindow : function() {
		if (this.windowType == 'external') {
			// We set the externals source here because it allows for a much smoother animation
			$('lightwindow_iframe').setAttribute('src', this.element.href);
			this._handleFinalWindowAnimation(1);	
		} else if (this.windowType == 'media') {

			var outerObject = document.createElement('object');
			outerObject.setAttribute('classid', this.options.classids[this._fileExtension(this.contentToFetch)]);
			outerObject.setAttribute('codebase', this.options.codebases[this._fileExtension(this.contentToFetch)]);
			outerObject.setAttribute('id', 'lightwindow_media_primary');
			outerObject.setAttribute('name', 'lightwindow_media_primary');
			outerObject.setAttribute('width', this.resizeTo.width);
			outerObject.setAttribute('height', this.resizeTo.height);
			outerObject = this._addParamToObject('movie', this.contentToFetch, outerObject);
			outerObject = this._addParamToObject('src', this.contentToFetch, outerObject);
			outerObject = this._addParamToObject('controller', 'true', outerObject);
			outerObject = this._addParamToObject('wmode', 'transparent', outerObject);
			outerObject = this._addParamToObject('cache', 'false', outerObject);
			outerObject = this._addParamToObject('quality', 'high', outerObject);

			if (!Prototype.Browser.IE) {
				var innerObject = document.createElement('object');
				innerObject.setAttribute('type', this.options.mimeTypes[this._fileExtension(this.contentToFetch)]);
				innerObject.setAttribute('data', this.contentToFetch);
				innerObject.setAttribute('id', 'lightwindow_media_secondary');
				innerObject.setAttribute('name', 'lightwindow_media_secondary');
				innerObject.setAttribute('width', this.resizeTo.width);
				innerObject.setAttribute('height', this.resizeTo.height);
				innerObject = this._addParamToObject('controller', 'true', innerObject);
				innerObject = this._addParamToObject('wmode', 'transparent', innerObject);
				innerObject = this._addParamToObject('cache', 'false', innerObject);
				innerObject = this._addParamToObject('quality', 'high', innerObject);
			
				outerObject.appendChild(innerObject);
			}	
			
			if (this._getParameter('lightwindow_iframe_embed')) {
				this._appendIframe('no');
				this._writeToIframe(this._convertToMarkup(outerObject, 'object'));
			} else {
				this._appendObject(outerObject, 'object', $('lightwindow_contents'));
			}

			this._handleFinalWindowAnimation(0);
		} else {
			this._handleFinalWindowAnimation(0);
		}

		// Initialize any actions
		this._setupActions();
	}
}

/*-----------------------------------------------------------------------------------------------*/

Event.observe(window, 'load', lightwindowInit, false);

//
//	Set up all of our links
//
var myLightWindow = null;
function lightwindowInit() {
	myLightWindow = new lightwindow();
}
function setUpLink(name){
	Event.stopObserving(name, 'click', lightwindow.activate);
	myLightWindow._processLink($(name));
}
/*	Unobtrusive Flash Objects (UFO) v3.22 <http://www.bobbyvandersluis.com/ufo/>
	Copyright 2005-2007 Bobby van der Sluis
	This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/

var UFO = {
	req: ["movie", "width", "height", "majorversion", "build"],
	opt: ["play", "loop", "menu", "quality", "scale", "salign", "wmode", "bgcolor", "base", "flashvars", "devicefont", "allowscriptaccess", "seamlesstabbing", "allowfullscreen", "allownetworking"],
	optAtt: ["id", "name", "align"],
	optExc: ["swliveconnect"],
	ximovie: "ufo.swf",
	xiwidth: "215",
	xiheight: "138",
	ua: navigator.userAgent.toLowerCase(),
	pluginType: "",
	fv: [0,0],
	foList: [],
		
	create: function(FO, id) {
		if (!UFO.uaHas("w3cdom") || UFO.uaHas("ieMac")) return;
		UFO.getFlashVersion();
		UFO.foList[id] = UFO.updateFO(FO);
		UFO.createCSS("#" + id, "visibility:hidden;");
		UFO.domLoad(id);
	},

	updateFO: function(FO) {
		if (typeof FO.xi != "undefined" && FO.xi == "true") {
			if (typeof FO.ximovie == "undefined") FO.ximovie = UFO.ximovie;
			if (typeof FO.xiwidth == "undefined") FO.xiwidth = UFO.xiwidth;
			if (typeof FO.xiheight == "undefined") FO.xiheight = UFO.xiheight;
		}
		FO.mainCalled = false;
		return FO;
	},

	domLoad: function(id) {
		var _t = setInterval(function() {
			if ((document.getElementsByTagName("body")[0] != null || document.body != null) && document.getElementById(id) != null) {
				UFO.main(id);
				clearInterval(_t);
			}
		}, 250);
		if (typeof document.addEventListener != "undefined") {
			document.addEventListener("DOMContentLoaded", function() { UFO.main(id); clearInterval(_t); } , null); // Gecko, Opera 9+
		}
	},

	main: function(id) {
		var _fo = UFO.foList[id];
		if (_fo.mainCalled) return;
		UFO.foList[id].mainCalled = true;
		document.getElementById(id).style.visibility = "hidden";
		if (UFO.hasRequired(id)) {
			if (UFO.hasFlashVersion(parseInt(_fo.majorversion, 10), parseInt(_fo.build, 10))) {
				if (typeof _fo.setcontainercss != "undefined" && _fo.setcontainercss == "true") UFO.setContainerCSS(id);
				UFO.writeSWF(id);
			}
			else if (_fo.xi == "true" && UFO.hasFlashVersion(6, 65)) {
				UFO.createDialog(id);
			}
		}
		document.getElementById(id).style.visibility = "visible";
	},
	
	createCSS: function(selector, declaration) {
		var _h = document.getElementsByTagName("head")[0]; 
		var _s = UFO.createElement("style");
		if (!UFO.uaHas("ieWin")) _s.appendChild(document.createTextNode(selector + " {" + declaration + "}")); // bugs in IE/Win
		_s.setAttribute("type", "text/css");
		_s.setAttribute("media", "screen"); 
		_h.appendChild(_s);
		if (UFO.uaHas("ieWin") && document.styleSheets && document.styleSheets.length > 0) {
			var _ls = document.styleSheets[document.styleSheets.length - 1];
			if (typeof _ls.addRule == "object") _ls.addRule(selector, declaration);
		}
	},
	
	setContainerCSS: function(id) {
		var _fo = UFO.foList[id];
		var _w = /%/.test(_fo.width) ? "" : "px";
		var _h = /%/.test(_fo.height) ? "" : "px";
		UFO.createCSS("#" + id, "width:" + _fo.width + _w +"; height:" + _fo.height + _h +";");
		if (_fo.width == "100%") {
			UFO.createCSS("body", "margin-left:0; margin-right:0; padding-left:0; padding-right:0;");
		}
		if (_fo.height == "100%") {
			UFO.createCSS("html", "height:100%; overflow:hidden;");
			UFO.createCSS("body", "margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0; height:100%;");
		}
	},

	createElement: function(el) {
		return (UFO.uaHas("xml") && typeof document.createElementNS != "undefined") ?  document.createElementNS("http://www.w3.org/1999/xhtml", el) : document.createElement(el);
	},

	createObjParam: function(el, aName, aValue) {
		var _p = UFO.createElement("param");
		_p.setAttribute("name", aName);	
		_p.setAttribute("value", aValue);
		el.appendChild(_p);
	},

	uaHas: function(ft) {
		var _u = UFO.ua;
		switch(ft) {
			case "w3cdom":
				return (typeof document.getElementById != "undefined" && typeof document.getElementsByTagName != "undefined" && (typeof document.createElement != "undefined" || typeof document.createElementNS != "undefined"));
			case "xml":
				var _m = document.getElementsByTagName("meta");
				var _l = _m.length;
				for (var i = 0; i < _l; i++) {
					if (/content-type/i.test(_m[i].getAttribute("http-equiv")) && /xml/i.test(_m[i].getAttribute("content"))) return true;
				}
				return false;
			case "ieMac":
				return /msie/.test(_u) && !/opera/.test(_u) && /mac/.test(_u);
			case "ieWin":
				return /msie/.test(_u) && !/opera/.test(_u) && /win/.test(_u);
			case "gecko":
				return /gecko/.test(_u) && !/applewebkit/.test(_u);
			case "opera":
				return /opera/.test(_u);
			case "safari":
				return /applewebkit/.test(_u);
			default:
				return false;
		}
	},
	
	getFlashVersion: function() {
		if (UFO.fv[0] != 0) return;  
		if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
			UFO.pluginType = "npapi";
			var _d = navigator.plugins["Shockwave Flash"].description;
			if (typeof _d != "undefined") {
				_d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
				var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
				var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
				UFO.fv = [_m, _r];
			}
		}
		else if (window.ActiveXObject) {
			UFO.pluginType = "ax";
			try { // avoid fp 6 crashes
				var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
			}
			catch(e) {
				try { 
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
					UFO.fv = [6, 0];
					_a.AllowScriptAccess = "always"; // throws if fp < 6.47 
				}
				catch(e) {
					if (UFO.fv[0] == 6) return;
				}
				try {
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
				}
				catch(e) {}
			}
			if (typeof _a == "object") {
				var _d = _a.GetVariable("$version"); // bugs in fp 6.21/6.23
				if (typeof _d != "undefined") {
					_d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
					UFO.fv = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
				}
			}
		}
	},

	hasRequired: function(id) {
		var _l = UFO.req.length;
		for (var i = 0; i < _l; i++) {
			if (typeof UFO.foList[id][UFO.req[i]] == "undefined") return false;
		}
		return true;
	},
	
	hasFlashVersion: function(major, release) {
		return (UFO.fv[0] > major || (UFO.fv[0] == major && UFO.fv[1] >= release)) ? true : false;
	},

	writeSWF: function(id) {
		var _fo = UFO.foList[id];
		var _e = document.getElementById(id);
		if (UFO.pluginType == "npapi") {
			if (UFO.uaHas("gecko") || UFO.uaHas("xml")) {
				while(_e.hasChildNodes()) {
					_e.removeChild(_e.firstChild);
				}
				var _obj = UFO.createElement("object");
				_obj.setAttribute("type", "application/x-shockwave-flash");
				_obj.setAttribute("data", _fo.movie);
				_obj.setAttribute("width", _fo.width);
				_obj.setAttribute("height", _fo.height);
				var _l = UFO.optAtt.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[UFO.optAtt[i]] != "undefined") _obj.setAttribute(UFO.optAtt[i], _fo[UFO.optAtt[i]]);
				}
				var _o = UFO.opt.concat(UFO.optExc);
				var _l = _o.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[_o[i]] != "undefined") UFO.createObjParam(_obj, _o[i], _fo[_o[i]]);
				}
				_e.appendChild(_obj);
			}
			else {
				var _emb = "";
				var _o = UFO.opt.concat(UFO.optAtt).concat(UFO.optExc);
				var _l = _o.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[_o[i]] != "undefined") _emb += ' ' + _o[i] + '="' + _fo[_o[i]] + '"';
				}
				_e.innerHTML = '<embed type="application/x-shockwave-flash" src="' + _fo.movie + '" width="' + _fo.width + '" height="' + _fo.height + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' + _emb + '></embed>';
			}
		}
		else if (UFO.pluginType == "ax") {
			var _objAtt = "";
			var _l = UFO.optAtt.length;
			for (var i = 0; i < _l; i++) {
				if (typeof _fo[UFO.optAtt[i]] != "undefined") _objAtt += ' ' + UFO.optAtt[i] + '="' + _fo[UFO.optAtt[i]] + '"';
			}
			var _objPar = "";
			var _l = UFO.opt.length;
			for (var i = 0; i < _l; i++) {
				if (typeof _fo[UFO.opt[i]] != "undefined") _objPar += '<param name="' + UFO.opt[i] + '" value="' + _fo[UFO.opt[i]] + '" />';
			}
			var _p = window.location.protocol == "https:" ? "https:" : "http:";
			_e.innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + _objAtt + ' width="' + _fo.width + '" height="' + _fo.height + '" codebase="' + _p + '//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + _fo.majorversion + ',0,' + _fo.build + ',0"><param name="movie" value="' + _fo.movie + '" />' + _objPar + '</object>';
		}
	},
		
	createDialog: function(id) {
		var _fo = UFO.foList[id];
		UFO.createCSS("html", "height:100%; overflow:hidden;");
		UFO.createCSS("body", "height:100%; overflow:hidden;");
		UFO.createCSS("#xi-con", "position:absolute; left:0; top:0; z-index:1000; width:100%; height:100%; background-color:#fff; filter:alpha(opacity:75); opacity:0.75;");
		UFO.createCSS("#xi-dia", "position:absolute; left:50%; top:50%; margin-left: -" + Math.round(parseInt(_fo.xiwidth, 10) / 2) + "px; margin-top: -" + Math.round(parseInt(_fo.xiheight, 10) / 2) + "px; width:" + _fo.xiwidth + "px; height:" + _fo.xiheight + "px;");
		var _b = document.getElementsByTagName("body")[0];
		var _c = UFO.createElement("div");
		_c.setAttribute("id", "xi-con");
		var _d = UFO.createElement("div");
		_d.setAttribute("id", "xi-dia");
		_c.appendChild(_d);
		_b.appendChild(_c);
		var _mmu = window.location;
		if (UFO.uaHas("xml") && UFO.uaHas("safari")) {
			var _mmd = document.getElementsByTagName("title")[0].firstChild.nodeValue = document.getElementsByTagName("title")[0].firstChild.nodeValue.slice(0, 47) + " - Flash Player Installation";
		}
		else {
			var _mmd = document.title = document.title.slice(0, 47) + " - Flash Player Installation";
		}
		var _mmp = UFO.pluginType == "ax" ? "ActiveX" : "PlugIn";
		var _uc = typeof _fo.xiurlcancel != "undefined" ? "&xiUrlCancel=" + _fo.xiurlcancel : "";
		var _uf = typeof _fo.xiurlfailed != "undefined" ? "&xiUrlFailed=" + _fo.xiurlfailed : "";
		UFO.foList["xi-dia"] = { movie:_fo.ximovie, width:_fo.xiwidth, height:_fo.xiheight, majorversion:"6", build:"65", flashvars:"MMredirectURL=" + _mmu + "&MMplayerType=" + _mmp + "&MMdoctitle=" + _mmd + _uc + _uf };
		UFO.writeSWF("xi-dia");
	},

	expressInstallCallback: function() {
		var _b = document.getElementsByTagName("body")[0];
		var _c = document.getElementById("xi-con");
		_b.removeChild(_c);
		UFO.createCSS("body", "height:auto; overflow:auto;");
		UFO.createCSS("html", "height:auto; overflow:auto;");
	},

	cleanupIELeaks: function() {
		var _o = document.getElementsByTagName("object");
		var _l = _o.length
		for (var i = 0; i < _l; i++) {
			_o[i].style.display = "none";
			for (var x in _o[i]) {
				if (typeof _o[i][x] == "function") {
					_o[i][x] = null;
				}
			}
		}
	}

};

if (typeof window.attachEvent != "undefined" && UFO.uaHas("ieWin")) {
	window.attachEvent("onunload", UFO.cleanupIELeaks);
}

   var BubbleTips = {
    
	opacity : "0.9",
     bubbleNode : null,
     
	 activateTipOn : function(type){
       var bubble = document.createElement("span");
       bubble.style.position = "absolute";
       bubble.style.zIndex = "9";
       this.bubbleNode = bubble;
       document.getElementsByTagName("body")[0].appendChild(bubble);
       var tipTags = document.getElementsByTagName(type);
       for(var i=0;i<tipTags.length;i++){
         this.bindBubbleTip(tipTags[i]);
       }
     },
	 
     bindBubbleTip : function(elem) {
      var tipText=elem.getAttribute("title");
      if(tipText==null || tipText.length==0){
        tipText="No title attribute, how sad :-(";
      }
      elem.removeAttribute("title");
      var bubble = this.createElem("span","bubbleTooltip");
      var tipTop = this.createElem("span","top");
      tipTop.appendChild(document.createTextNode(tipText));
      bubble.appendChild(tipTop);
      bubble.appendChild(this.createElem("span","bottom"));
      this.setOpacity(bubble,this.opacity);
	  elem.tooltip = bubble;
      elem.onmouseover = ToolTipEvents.showTooltip;
      elem.onmouseout = ToolTipEvents.hideTooltip;
      elem.onmousemove = ToolTipEvents.followMouse;
    },
	
    createElem : function(tag,className){
      var elem = document.createElement(tag);
      elem.className = className;
      elem.style.display = "block";
      return elem;
    },
	
	setOpacity : function(obj, opa){
		obj.style.filter="alpha(opacity:"+((+opa)*100)+")";
		obj.style.KHTMLOpacity=opa;
		obj.style.MozOpacity=opa;
		obj.style.opacity=opa;
	}
  };
  
    var ToolTipEvents = {
    
	  offsetLeft : (-25),
      offsetTop : (10),
      
	  posRef : function(){
        return ((document.documentElement.scrollTop)?
        document.documentElement : document.body)
        },
      
	  showTooltip : function(e){
        ToolTipEvents._cleanup();
       BubbleTips.bubbleNode.appendChild(this.tooltip);    
	  BubbleTips.setOpacity(this.tooltip,BubbleTips.opacity);
       ToolTipEvents.followMouse(e);
     },
     
	 hideTooltip : function(e){     
	   ToolTipEvents._cleanup();
     },
     
	 followMouse : function(e){
       if(e == null){ e = window.event };
       var posx = ToolTipEvents.offsetLeft;
       var posy = ToolTipEvents.offsetTop;
       if(e.pageX || e.pageY){
         posx += e.pageX;
         posy += e.pageY;
       } else if(e.clientX || e.clientY) {
         var posRef= ToolTipEvents.posRef();
		 posx += e.clientX + posRef.scrollLeft;
         posy += e.clientY + posRef.scrollTop;
       }
       BubbleTips.bubbleNode.style.top = (posy) + "px";
       BubbleTips.bubbleNode.style.left = (posx) + "px";
     },
    
	 _cleanup : function(){
       var bubble = BubbleTips.bubbleNode;
       if( bubble.childNodes.length > 0 ){
         bubble.removeChild(bubble.firstChild);
       }
     }
   };


// JavaScript Document

/********************************************************
*  IMPORT DOJO
********************************************************/
/*
 * Configuration Dojo (import)
 */
/*dojo.require("dojo.io.*");
dojo.require("dojo.io.IframeIO");
dojo.require("dojo.event.*");
dojo.require("dojo.xml.Parse");
dojo.require("dojo.widget.Parse");
dojo.require("dojo.widget.Tooltip");
dojo.require("dojo.widget.Tree");
dojo.require("dojo.widget.TreeNode");
dojo.require("dojo.widget.TreeSelector");
dojo.require("dojo.crypto.MD5");*/
dojo.hostenv.writeIncludes();

// modales Dojo (verouillage session a prevoir)
var dlgSession;

// onload page
dojo.event.connect(dojo.hostenv, "loaded", window, "init");



/********************************************************
*  EXTERNAL LINK
********************************************************/
function externalLinks() {
	
 if (!document.getElementsByTagName) return;
 var anchors = document.getElementsByTagName("a");
 for (var i=0; i<anchors.length; i++) {
   var anchor = anchors[i];
   if (anchor.getAttribute("href") &&
       anchor.getAttribute("rel") == "external")
     anchor.target = "_blank";
 }
 
}

/********************************************************
*  NAVIGATION IE
********************************************************/

function navHover() {
	
	var lis 	=	document.getElementById("navmenu").getElementsByTagName("LI");
	//var nodes 	= 	$A(lis);
	
	for (var i=0; i<lis.length; i++) {
		lis[i].onmouseover=function() {
			this.className+=" iehover";
		}
		lis[i].onmouseout=function() {
			this.className=this.className.replace(new RegExp(" iehover\\b"), "");
		}
	}
	
}


/********************************************************
*  OPENMENU
********************************************************/


function openMenu(id_){
	
	//close all elements
	var elUL_array = $('navmenu').childElements();
	
	for (var i=0; i<elUL_array.length; i++) {
		var elLI = elUL_array[i];
		var elUL = elLI.childElements();
		if(elUL[1] != undefined)elUL[1].hide();
	}
	
	//open element ID
	if($(id_)){
		var elUL = $(id_).childElements();
		if(elUL[1] != undefined)elUL[1].show();
	}
}

Event.observe(window, 'load', externalLinks, false);

if(navigator.userAgent.indexOf("MSIE 6") != -1)
	Event.observe(window, 'load', navHover, false);


/********************************************************
*  AJOUTER FAVORIS
********************************************************/

function favoris(name_, url_){
	if(window.sidebar){
		window.sidebar.addPanel(name_, url_,"");
	}else if( document.all ){
		window.external.AddFavorite(url_, name_);
	}
} 

window.onload = function(){
   BubbleTips.activateTipOn("abbr");
   BubbleTips.activateTipOn("acronym");
};

/********************************************************
*  NEWSLETTER
********************************************************/

function PopupNewsLetter(page,nom,largeur,hauteur,options) {
	 var top=(screen.height-hauteur)/2;
	 var left=(screen.width-largeur)/2;
	 window.open(page,nom,"top="+top+",left="+left+",width="+largeur+",height="+hauteur+","+options);
}

function gonews(){	
	PopupNewsLetter('','popup',500,300,'menubar=no,scrollbars=no,statusbar=no');
	
	var boxActionInscr = document.forms["f_newsletter"].insc;
	var boxActionDesinscr = document.forms["f_newsletter"].desinsc;

	if(wysi==1)	{
		if (boxActionInscr.checked) {
			stat('efigip', '', '', '', '/lettre_info_abonn/');
		}
		else if(boxActionDesinscr.checked){
			stat('efigip', '', '', '', '/lettre_info_desabonn/');
		}
	}
	
	document.forms["f_newsletter"].submit();
	document.forms["f_newsletter"].email.value="traitement en cours...";
	return false;
}




/********************************************************
*  PARSE LINKS
********************************************************/
function parseLinks(bloc){

	if($(bloc))
	{
	  var liens = $(bloc).select("a");
	  
	  for (var i = 0; i < liens.length; i++) {
		liens[i].observe('click', onClickLien.bind(liens[i]));
	  }
	}
	
}

 function onClickLien(){
 	
	var tabHref = this.href.split('/');
	
	var type = tabHref[4];
	
	if (type == 'ressources' || type == 'publications'){
		var key = tabHref[5];
		
		pdfReg = /[0-9a-zA-Z\+\-\.]+/;
		
		if (wysi == 1 && pdfReg.test(key)) {
			var suivi = 'telechargement';
			if (type == 'ressources') suivi = type;
			
			stat('efigip','PV', '', suivi+';'+key, '/'+type+'/telechargement/'); 
		}
	}
 }
 
 
/********************************************************
*  UTILS
********************************************************/ 
function toggleVisibility()
{
	
}
function toggleDisplay(eltId)
{
  var elt = document.getElementById(eltId);
  if(elt.style.display == "none" )
  {
    elt.style.display = "";
  }
  else
  {
    elt.style.display = "none";
  }
}

/*
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
 * Copyright (C) 2003-2009 Frederico Caldeira Knabben
 *
 * == BEGIN LICENSE ==
 *
 * Licensed under the terms of any of the following licenses at your
 * choice:
 *
 *  - GNU General Public License Version 2 or later (the "GPL")
 *    http://www.gnu.org/licenses/gpl.html
 *
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 *    http://www.gnu.org/licenses/lgpl.html
 *
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
 *    http://www.mozilla.org/MPL/MPL-1.1.html
 *
 * == END LICENSE ==
 *
 * This is the integration file for JavaScript.
 *
 * It defines the FCKeditor class that can be used to create editor
 * instances in a HTML page in the client side. For server side
 * operations, use the specific integration system.
 */

// FCKeditor Class
var FCKeditor = function( instanceName, width, height, toolbarSet, value )
{
	// Properties
	this.InstanceName	= instanceName ;
	this.Width			= width			|| '100%' ;
	this.Height			= height		|| '200' ;
	this.ToolbarSet		= toolbarSet	|| 'Default' ;
	this.Value			= value			|| '' ;
	this.BasePath		= FCKeditor.BasePath ;
	this.CheckBrowser	= true ;
	this.DisplayErrors	= true ;

	this.Config			= new Object() ;

	// Events
	this.OnError		= null ;	// function( source, errorNumber, errorDescription )
}

/**
 * This is the default BasePath used by all editor instances.
 */
FCKeditor.BasePath = '/fckeditor/' ;

/**
 * The minimum height used when replacing textareas.
 */
FCKeditor.MinHeight = 200 ;

/**
 * The minimum width used when replacing textareas.
 */
FCKeditor.MinWidth = 750 ;

FCKeditor.prototype.Version			= '2.6.4' ;
FCKeditor.prototype.VersionBuild	= '21629' ;

FCKeditor.prototype.Create = function()
{
	document.write( this.CreateHtml() ) ;
}

FCKeditor.prototype.CreateHtml = function()
{
	// Check for errors
	if ( !this.InstanceName || this.InstanceName.length == 0 )
	{
		this._ThrowError( 701, 'You must specify an instance name.' ) ;
		return '' ;
	}

	var sHtml = '' ;

	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
	{
		sHtml += '<input type="hidden" id="' + this.InstanceName + '" name="' + this.InstanceName + '" value="' + this._HTMLEncode( this.Value ) + '" style="display:none" />' ;
		sHtml += this._GetConfigHtml() ;
		sHtml += this._GetIFrameHtml() ;
	}
	else
	{
		var sWidth  = this.Width.toString().indexOf('%')  > 0 ? this.Width  : this.Width  + 'px' ;
		var sHeight = this.Height.toString().indexOf('%') > 0 ? this.Height : this.Height + 'px' ;

		sHtml += '<textarea name="' + this.InstanceName +
			'" rows="4" cols="40" style="width:' + sWidth +
			';height:' + sHeight ;

		if ( this.TabIndex )
			sHtml += '" tabindex="' + this.TabIndex ;

		sHtml += '">' +
			this._HTMLEncode( this.Value ) +
			'<\/textarea>' ;
	}

	return sHtml ;
}

FCKeditor.prototype.ReplaceTextarea = function()
{
	if ( document.getElementById( this.InstanceName + '___Frame' ) )
		return ;
	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
	{
		// We must check the elements firstly using the Id and then the name.
		var oTextarea = document.getElementById( this.InstanceName ) ;
		var colElementsByName = document.getElementsByName( this.InstanceName ) ;
		var i = 0;
		while ( oTextarea || i == 0 )
		{
			if ( oTextarea && oTextarea.tagName.toLowerCase() == 'textarea' )
				break ;
			oTextarea = colElementsByName[i++] ;
		}

		if ( !oTextarea )
		{
			alert( 'Error: The TEXTAREA with id or name set to "' + this.InstanceName + '" was not found' ) ;
			return ;
		}

		oTextarea.style.display = 'none' ;

		if ( oTextarea.tabIndex )
			this.TabIndex = oTextarea.tabIndex ;

		this._InsertHtmlBefore( this._GetConfigHtml(), oTextarea ) ;
		this._InsertHtmlBefore( this._GetIFrameHtml(), oTextarea ) ;
	}
}

FCKeditor.prototype._InsertHtmlBefore = function( html, element )
{
	if ( element.insertAdjacentHTML )	// IE
		element.insertAdjacentHTML( 'beforeBegin', html ) ;
	else								// Gecko
	{
		var oRange = document.createRange() ;
		oRange.setStartBefore( element ) ;
		var oFragment = oRange.createContextualFragment( html );
		element.parentNode.insertBefore( oFragment, element ) ;
	}
}

FCKeditor.prototype._GetConfigHtml = function()
{
	var sConfig = '' ;
	for ( var o in this.Config )
	{
		if ( sConfig.length > 0 ) sConfig += '&amp;' ;
		sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.Config[o] ) ;
	}

	return '<input type="hidden" id="' + this.InstanceName + '___Config" value="' + sConfig + '" style="display:none" />' ;
}

FCKeditor.prototype._GetIFrameHtml = function()
{
	var sFile = 'fckeditor.html' ;

	try
	{
		if ( (/fcksource=true/i).test( window.top.location.search ) )
			sFile = 'fckeditor.original.html' ;
	}
	catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ }

	var sLink = this.BasePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.InstanceName ) ;
	if (this.ToolbarSet)
		sLink += '&amp;Toolbar=' + this.ToolbarSet ;

	var html = '<iframe id="' + this.InstanceName +
		'___Frame" src="' + sLink +
		'" width="' + this.Width +
		'" height="' + this.Height ;

	if ( this.TabIndex )
		html += '" tabindex="' + this.TabIndex ;

	html += '" frameborder="0" scrolling="no"></iframe>' ;

	return html ;
}

FCKeditor.prototype._IsCompatibleBrowser = function()
{
	return FCKeditor_IsCompatibleBrowser() ;
}

FCKeditor.prototype._ThrowError = function( errorNumber, errorDescription )
{
	this.ErrorNumber		= errorNumber ;
	this.ErrorDescription	= errorDescription ;

	if ( this.DisplayErrors )
	{
		document.write( '<div style="COLOR: #ff0000">' ) ;
		document.write( '[ FCKeditor Error ' + this.ErrorNumber + ': ' + this.ErrorDescription + ' ]' ) ;
		document.write( '</div>' ) ;
	}

	if ( typeof( this.OnError ) == 'function' )
		this.OnError( this, errorNumber, errorDescription ) ;
}

FCKeditor.prototype._HTMLEncode = function( text )
{
	if ( typeof( text ) != "string" )
		text = text.toString() ;

	text = text.replace(
		/&/g, "&amp;").replace(
		/"/g, "&quot;").replace(
		/</g, "&lt;").replace(
		/>/g, "&gt;") ;

	return text ;
}

;(function()
{
	var textareaToEditor = function( textarea )
	{
		var editor = new FCKeditor( textarea.name ) ;

		editor.Width = Math.max( textarea.offsetWidth, FCKeditor.MinWidth ) ;
		editor.Height = Math.max( textarea.offsetHeight, FCKeditor.MinHeight ) ;

		return editor ;
	}

	/**
	 * Replace all <textarea> elements available in the document with FCKeditor
	 * instances.
	 *
	 *	// Replace all <textarea> elements in the page.
	 *	FCKeditor.ReplaceAllTextareas() ;
	 *
	 *	// Replace all <textarea class="myClassName"> elements in the page.
	 *	FCKeditor.ReplaceAllTextareas( 'myClassName' ) ;
	 *
	 *	// Selectively replace <textarea> elements, based on custom assertions.
	 *	FCKeditor.ReplaceAllTextareas( function( textarea, editor )
	 *		{
	 *			// Custom code to evaluate the replace, returning false if it
	 *			// must not be done.
	 *			// It also passes the "editor" parameter, so the developer can
	 *			// customize the instance.
	 *		} ) ;
	 */
	FCKeditor.ReplaceAllTextareas = function()
	{
		var textareas = document.getElementsByTagName( 'textarea' ) ;

		for ( var i = 0 ; i < textareas.length ; i++ )
		{
			var editor = null ;
			var textarea = textareas[i] ;
			var name = textarea.name ;

			// The "name" attribute must exist.
			if ( !name || name.length == 0 )
				continue ;

			if ( typeof arguments[0] == 'string' )
			{
				// The textarea class name could be passed as the function
				// parameter.

				var classRegex = new RegExp( '(?:^| )' + arguments[0] + '(?:$| )' ) ;

				if ( !classRegex.test( textarea.className ) )
					continue ;
			}
			else if ( typeof arguments[0] == 'function' )
			{
				// An assertion function could be passed as the function parameter.
				// It must explicitly return "false" to ignore a specific <textarea>.
				editor = textareaToEditor( textarea ) ;
				if ( arguments[0]( textarea, editor ) === false )
					continue ;
			}

			if ( !editor )
				editor = textareaToEditor( textarea ) ;

			editor.ReplaceTextarea() ;
		}
	}
})() ;

function FCKeditor_IsCompatibleBrowser()
{
	var sAgent = navigator.userAgent.toLowerCase() ;

	// Internet Explorer 5.5+
	if ( /*@cc_on!@*/false && sAgent.indexOf("mac") == -1 )
	{
		var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
		return ( sBrowserVersion >= 5.5 ) ;
	}

	// Gecko (Opera 9 tries to behave like Gecko at this point).
	if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
		return true ;

	// Opera 9.50+
	if ( window.opera && window.opera.version && parseFloat( window.opera.version() ) >= 9.5 )
		return true ;

	// Adobe AIR
	// Checked before Safari because AIR have the WebKit rich text editor
	// features from Safari 3.0.4, but the version reported is 420.
	if ( sAgent.indexOf( ' adobeair/' ) != -1 )
		return ( sAgent.match( / adobeair\/(\d+)/ )[1] >= 1 ) ;	// Build must be at least v1

	// Safari 3+
	if ( sAgent.indexOf( ' applewebkit/' ) != -1 )
		return ( sAgent.match( / applewebkit\/(\d+)/ )[1] >= 522 ) ;	// Build must be at least 522 (v3)

	return false ;
}

function faire_liste_strucure(){
	var f = document.forms[1];
	var nom_strucure = f.texte_structure.value;
	if (nom_strucure=='') alert('Veuillez inscire un nom de structure');
	else{
		if(window.ActiveXObject) {// Internet Explorer
	    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	var xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPStructure&texte_structure="+nom_strucure, true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);	
	}
	
	//initialisation du select des adresses
	var liste_existante = document.getElementById('id_adresse');
	liste_existante.options.length = 1;
	
}


function faire_liste_adresse(){
	var f = document.forms[1];
	var liste_existante = document.getElementById('id_structure');
	var id_structure = "";
	
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			id_structure += liste_existante[i].value+",";
		}	
	}
	
	var longueur = id_structure.length;
	longueur = longueur-1;
	id_structure = id_structure.substr(0,longueur);
	
	
	if (id_structure=='') alert('Veuillez sélectionner une structure');
	else{
		if(window.ActiveXObject) {// Internet Explorer
	    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	var xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPAdresse&id_structure="+id_structure, true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);	
	}
}


/*************************************** Champsintervention ************************************/
function SelectChampsintervention(nom_form){	
	var f = eval('document.'+nom_form);
	champsintervention = document.getElementById("champsintervention");
	var selectChampsintervention = f.selectChampsintervention;
	var c = selectChampsintervention.checked;
	for(var i=0; i<champsintervention.length; i++){
		if (champsintervention[i].selected!=c){
			champsintervention[i].selected = c;
		}
	}
}

function SelectChampsintervention2(nom_form){	
	var f = eval('document.'+nom_form);
	champsintervention2 = document.getElementById("champsintervention2");
	var selectChampsintervention2 = f.selectChampsintervention2;
	var c = selectChampsintervention2.checked;
	for(var i=0; i<champsintervention2.length; i++){
		if (champsintervention2[i].selected!=c){
			champsintervention2[i].selected = c;
		}
	}
}

function SelectChampsintervention3(nom_form){	
	var f = eval('document.'+nom_form);
	champsintervention2 = document.getElementById("champsintervention2");
	for(var i=0; i<champsintervention2.length; i++){
		champsintervention2[i].selected = "true";
	}
}


function ajouterChampsintervention(nom_form){
	var f = eval('document.'+nom_form);
	var t1 = document.getElementById('champsintervention');
	var id_champsintervention = f.liste_champsintervention.value;
	
	tab_champsintervention_select = new Array();
    tab_champsintervention_exist = new Array(); 
    
	var j=0;
	for(i=0;i<t1.length;i++){
		if (t1[i].selected) {
			tab_champsintervention_select[j] = t1[i].value;
			j=j+1;
		}
	}
	
	for (i=0;i<tab_champsintervention_select.length;i++){
		var test='non';
		var valeur_selectionne = tab_champsintervention_select[i];
		for (j=0;j<tab_champsintervention_exist.length;j++){
			if (valeur_selectionne==tab_champsintervention_exist[j]){
				test='oui';
			}
		}
		if (test!='oui'){
			if (id_champsintervention!='') id_champsintervention += ",";
			id_champsintervention += valeur_selectionne;
		}
		test='non';
	}
	
	f.liste_champsintervention.value = id_champsintervention;

	if(window.ActiveXObject) {// Internet Explorer
    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	var xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}
  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPChampsinterventionAjout&id_champsintervention="+escape(id_champsintervention)+"&nom_form="+nom_form, true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	  		eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}


function supprimerChampsintervention(nom_form){
	var f = eval('document.'+nom_form);
	var id_champsintervention='';
	tab_champsintervention_select = new Array();
    tab_champsintervention_exist = new Array(); 
	f.liste_champsintervention.value = '';
	
	var j=0;
	var liste_existante = document.getElementById('champsintervention2');
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			tab_champsintervention_select[j] = liste_existante[i].value;
		}
		tab_champsintervention_exist[i] = liste_existante[i].value;
		j=j+1;
	}
	
	for (i=0;i<tab_champsintervention_exist.length;i++){
		var test='non';
		var valeur_existante = tab_champsintervention_exist[i];
		for (j=0;j<tab_champsintervention_select.length;j++){
			if (valeur_existante==tab_champsintervention_select[j]){
				test='oui';
			}
		}
		if (test!='oui')id_champsintervention += valeur_existante+",";
		test='non';
	}
	var longueur = id_champsintervention.length;
	longueur = longueur-1;
	id_champsintervention = id_champsintervention.substr(0,longueur);
	
	/*var liste_champsintervention = f.champsintervention2;
    liste_champsintervention.length=0;
    
    var selectChampsintervention2 = f.selectChampsintervention2;
	if (selectChampsintervention2.checked) selectChampsintervention2.checked=false;
	*/
	
	f.liste_champsintervention.value = id_champsintervention;
	
	if(window.ActiveXObject) {// Internet Explorer
    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	var xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}
  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPChampsinterventionAjout&id_champsintervention="+escape(id_champsintervention)+"&nom_form="+nom_form, true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	  		eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}


/*************************************** Rayonnementgeographique ************************************/
function SelectRayonnementgeographique(nom_form){	
	var f = eval('document.'+nom_form);
	rayonnementgeographique = document.getElementById("rayonnementgeographique");
	var selectRayonnementgeographique = f.selectRayonnementgeographique;
	var c = selectRayonnementgeographique.checked;
	for(var i=0; i<rayonnementgeographique.length; i++){
		if (rayonnementgeographique[i].selected!=c){
			rayonnementgeographique[i].selected = c;
		}
	}
}

function SelectRayonnementgeographique2(nom_form){	
	var f = eval('document.'+nom_form);
	rayonnementgeographique2 = document.getElementById("rayonnementgeographique2");
	var selectRayonnementgeographique2 = f.selectRayonnementgeographique2;
	var c = selectRayonnementgeographique2.checked;
	for(var i=0; i<rayonnementgeographique2.length; i++){
		if (rayonnementgeographique2[i].selected!=c){
			rayonnementgeographique2[i].selected = c;
		}
	}
}

function SelectRayonnementgeographique3(nom_form){	
	var f = eval('document.'+nom_form);
	rayonnementgeographique2 = document.getElementById("rayonnementgeographique2");
	for(var i=0; i<rayonnementgeographique2.length; i++){
		rayonnementgeographique2[i].selected = "true";
	}
}

function ajouterRayonnementgeographique(nom_form){
	var f = eval('document.'+nom_form);
	var t1 = document.getElementById('rayonnementgeographique');
	var id_rayonnementgeographique=f.liste_rayonnementgeographique.value;
	
	tab_rayonnementgeographique_select = new Array();
    tab_rayonnementgeographique_exist = new Array(); 
	
	var j=0;
	for(i=0;i<t1.length;i++){
		if (t1[i].selected) {
			tab_rayonnementgeographique_select[j] = t1[i].value;
			j=j+1;
		}
	}
	
	for (i=0;i<tab_rayonnementgeographique_select.length;i++){
		var test='non';
		var valeur_selectionne = tab_rayonnementgeographique_select[i];
		for (j=0;j<tab_rayonnementgeographique_exist.length;j++){
			if (valeur_selectionne==tab_rayonnementgeographique_exist[j]){
				test='oui';
			}
		}
		if (test!='oui'){
			if (id_rayonnementgeographique!='') id_rayonnementgeographique += ",";
			id_rayonnementgeographique += valeur_selectionne;
		}
		test='non';
	}
	
	f.liste_rayonnementgeographique.value = id_rayonnementgeographique;
	
	if(window.ActiveXObject) {// Internet Explorer
    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	var xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}
  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPRayonnementgeographiqueAjout&id_rayonnementgeographique="+escape(id_rayonnementgeographique)+"&nom_form="+nom_form, true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	  		eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}


function supprimerRayonnementgeographique(nom_form){
	var f = eval('document.'+nom_form);
	var id_rayonnementgeographique='';
	tab_rayonnementgeographique_select = new Array();
    tab_rayonnementgeographique_exist = new Array(); 
	f.liste_rayonnementgeographique.value = '';
	
	var j=0;
	var liste_existante = document.getElementById('rayonnementgeographique2');
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			tab_rayonnementgeographique_select[j] = liste_existante[i].value;
		}
		tab_rayonnementgeographique_exist[i] = liste_existante[i].value;
		j=j+1;
	}
	
	for (i=0;i<tab_rayonnementgeographique_exist.length;i++){
		var test='non';
		var valeur_existante = tab_rayonnementgeographique_exist[i];
		for (j=0;j<tab_rayonnementgeographique_select.length;j++){
			if (valeur_existante==tab_rayonnementgeographique_select[j]){
				test='oui';
			}
		}
		if (test!='oui')id_rayonnementgeographique += valeur_existante+",";
		test='non';
	}
	var longueur = id_rayonnementgeographique.length;
	longueur = longueur-1;
	id_rayonnementgeographique = id_rayonnementgeographique.substr(0,longueur);
	
	/*var liste_rayonnementgeographique = f.rayonnementgeographique2;
    liste_rayonnementgeographique.length=0;
    
    var selectRayonnementgeographique2 = f.selectRayonnementgeographique2;
	if (selectRayonnementgeographique2.checked) selectRayonnementgeographique2.checked=false;
	*/	
	f.liste_rayonnementgeographique.value = id_rayonnementgeographique;

	if(window.ActiveXObject) {// Internet Explorer
    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	var xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}
  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPRayonnementgeographiqueAjout&id_rayonnementgeographique="+escape(id_rayonnementgeographique)+"&nom_form="+nom_form, true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	  		eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}



/*************************************** Public ************************************/
function SelectPublic(nom_form){	
	var f = eval('document.'+nom_form);
	public = document.getElementById("public");
	var selectPublic = f.selectPublic;
	var c = selectPublic.checked;
	for(var i=0; i<public.length; i++){
		if (public[i].selected!=c){
			public[i].selected = c;
		}
	}
}

function SelectPublic2(nom_form){	
	var f = eval('document.'+nom_form);
	public2 = document.getElementById("public2");
	var selectPublic2 = f.selectPublic2;
	var c = selectPublic2.checked;
	for(var i=0; i<public2.length; i++){
		if (public2[i].selected!=c){
			public2[i].selected = c;
		}
	}
}

function SelectPublic3(nom_form){	
	var f = eval('document.'+nom_form);
	public2 = document.getElementById("public2");
	for(var i=0; i<public2.length; i++){
		public2[i].selected = "true";
	}
}

function ajouterPublic(nom_form){
	var f = eval('document.'+nom_form);
	var t1 = document.getElementById('public');
	var id_public=f.liste_public.value;
	
	tab_public_select = new Array();
    tab_public_exist = new Array(); 
	
	var j=0;
	for(i=0;i<t1.length;i++){
		if (t1[i].selected) {
			tab_public_select[j] = t1[i].value;
			j=j+1;
		}
	}
	
	for (i=0;i<tab_public_select.length;i++){
		var test='non';
		var valeur_selectionne = tab_public_select[i];
		for (j=0;j<tab_public_exist.length;j++){
			if (valeur_selectionne==tab_public_exist[j]){
				test='oui';
			}
		}
		if (test!='oui'){
			if (id_public!='') id_public += ",";
			id_public += valeur_selectionne;
		}
		test='non';
	}
	
	f.liste_public.value = id_public;
	
	if(window.ActiveXObject) {// Internet Explorer
    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	var xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}
  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPPublicAjout&id_public="+escape(id_public)+"&nom_form="+nom_form, true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	  		eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}


function supprimerPublic(nom_form){
	var f = eval('document.'+nom_form);
	var id_public='';
	tab_public_select = new Array();
    tab_public_exist = new Array(); 
	f.liste_public.value = '';
	
	var j=0;
	var liste_existante = document.getElementById('public2');
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			tab_public_select[j] = liste_existante[i].value;
		}
		tab_public_exist[i] = liste_existante[i].value;
		j=j+1;
	}
	
	for (i=0;i<tab_public_exist.length;i++){
		var test='non';
		var valeur_existante = tab_public_exist[i];
		for (j=0;j<tab_public_select.length;j++){
			if (valeur_existante==tab_public_select[j]){
				test='oui';
			}
		}
		if (test!='oui')id_public += valeur_existante+",";
		test='non';
	}
	var longueur = id_public.length;
	longueur = longueur-1;
	id_public = id_public.substr(0,longueur);
	
	/*var liste_public = f.public2;
    liste_public.length=0;
    
    var selectPublic2 = f.selectPublic2;
	if (selectPublic2.checked) selectPublic2.checked=false;
	*/

	f.liste_public.value = id_public;

	if(window.ActiveXObject) {// Internet Explorer
    	var xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	var xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}
  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPPublicAjout&id_public="+escape(id_public)+"&nom_form="+nom_form, true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	  		eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}


function rep_nouvelle_recherche(nom_form){
	var f = eval('document.'+nom_form);
	f.reset();
	f.structure_txt.value="";
	SelectChampsintervention3(nom_form);
	supprimerChampsintervention(nom_form);
	SelectRayonnementgeographique3(nom_form);
	supprimerRayonnementgeographique(nom_form);
	SelectPublic3(nom_form);
	supprimerPublic(nom_form);
}

var trimestre_debut = '20071';
var trimestre_fin = '20073';
var trimestre_test = '20081';


function test_date(id_trimestre){
	if ((id_trimestre >=trimestre_debut)&&(id_trimestre<=trimestre_fin)){
		return true;
	}
	else return false;
}

// debut alt
if ((navigator.appName == "Netscape")&&(navigator.appVersion.substring(0,4)>=4)) 
	{isNav="net";} 
if (navigator.appName == "Microsoft Internet Explorer")
	{isNav="ie";} 
		
function popLayer(a, pos_x, pos_y){ 
	desc = "<TABLE BORDER=1 bordercolor='#B2A047' CELLPADDING=0 CELLSPACING=0 bgcolor='#CCBB68'><tr><td>";
	desc += "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=3 bgcolor='#CCBB68'><tr><td align='center'><a id='texte'>";
	desc +=a
	desc += "</a></td></tr></table>"; 
	desc += "</td></tr></table>"; 
	
	if (isNav=="net"){
	  		var NS6_tmp = (!document.all && document.getElementById) ? 1 : 0;
	  		if (NS6_tmp){
	   			document.captureEvents(Event.MOUSEMOVE);
	   			document.onmousemove = handlerMM;
	   			document.getElementById('alt').innerHTML = desc;
	   			var taille_layer = document.getElementById('alt').offsetWidth;
	   			document.getElementById('alt').style.top=y+'px';
	   			document.getElementById('alt').style.left=x+'px';
	   			if ((document.body.clientWidth+document.body.scrollLeft)<(document.getElementById('alt').offsetLeft+taille_layer)){
	    			document.getElementById('alt').style.left=document.body.clientWidth+document.body.scrollLeft-taille_layer;
	   			}
	   			document.getElementById('alt').style.visibility = "visible";
	  		}
		  	else{
		   		document.captureEvents(Event.MOUSEMOVE);
		   		document.onmousemove = handlerMM; 
		   		document.alt.document.write(desc); 
		   		document.alt.document.close(); 
		   		document.alt.left=x-5; 
		   		document.alt.top=y-25;
		   		document.alt.visibility = "show";
		  	}
	 	}
	 	else if (isNav=="ie"){
	  		handlerMM();
	  		alt.innerHTML=desc;
	  		var taille_layer = alt.offsetWidth;
	  		alt.style.pixelLeft=x-5;
	  		alt.style.pixelTop=y-20;
	  		if ((document.body.clientWidth+document.body.scrollLeft)<(alt.offsetLeft+taille_layer)){
	   			alt.style.pixelLeft=document.body.clientWidth+document.body.scrollLeft-taille_layer;
	  		}
	  
	  
	  		alt.style.visibility = "visible";
	 	}
	}
	
	function hideLayer(a){ 
		var NS6_tmp = (!document.all && document.getElementById) ? 1 : 0;
		if (isNav=="net") {
			if (NS6_tmp) { document.getElementById('alt').style.visibility = "hidden";document.getElementById('alt').style.left=0+'px';document.getElementById('alt').style.top=0+'px';}
	  		else  { document.layers['alt'].visibility = "hide";document.alt.left=0;document.alt.top=0;}
	 	}
	 	if (isNav=="ie")
	  		{alt.style.visibility = "hidden";alt.style.pixelLeft=0;alt.style.pixelTop=0;} 
	}
	
	function handlerMM(e){
		if (isNav=="net") {
	  		x = e.pageX+25;
	  		y = e.pageY;
	  	} 
	 	if (isNav=="ie"){
	  		x = event.x+document.documentElement.scrollLeft+25;
			if (navigator.userAgent.indexOf("MSIE 8") == -1){ 
				y = event.y+document.documentElement.scrollTop;
			}
			else { 
				y = event.y; // cas IE8 en Strict
			}
			
	  		
	  	}
	}
	
	if (isNav=="net"){
		document.captureEvents(Event.MOUSEMOVE);
		document.onmousemove = handlerMM; 
	}
	//fin alt



function select_option(numero_radio) {
	document.form.option[numero_radio].checked = true;
	init_chps_opt(numero_radio);
}

function creer_liste_handi(id_select){
	
	var f = document.form;
	var ind_trimestre = f.id_trimestre.selectedIndex;
	var id_trimestre = f.id_trimestre[ind_trimestre].value;

	if(window.ActiveXObject) {// Internet Explorer
    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}

  	xhr_object.open("GET",  "index.php?module=efigip&action=ListeHandi&id_trimestre="+escape(id_trimestre)+"&id_select="+escape(id_select), true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	  		//alert(xhr_object.responseText);
	    	eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
	
}
function nouvelle_recherche(){
	var f = document.form;
	f.reset();
	// on reinitailaise les premières listes déroulantes (critères obligatoires)
	var liste_geographie = f.id_type_geographie;
	var liste_public = f.id_public;
	var liste_categorie = f.id_categorie;
	var liste_trimestre = f.id_trimestre;
	liste_geographie.selectedIndex=0;
    liste_public.selectedIndex=0;
    liste_categorie.selectedIndex=0;
    liste_trimestre.selectedIndex=liste_trimestre.length-1;
    
	// on choisi le premier bouton radio
	select_option(0);
	//remise à 0 des liste déroulante des critère optionnels
	init_chps_opt(0);
	
}

/*function affiche_message1(){
	id_type_geographie = document.form.id_type_geographie.options[document.form.id_type_geographie.selectedIndex].value;
	id_trimestre = document.form.id_trimestre.options[document.form.id_trimestre.selectedIndex].value;
	var obj_message = document.getElementById('message1');
	if ((test_date(id_trimestre)==true)&&(id_type_geographie=='BA')) {
		obj_message.style.display='block';
	}
	else obj_message.style.display='none';
}*/

/*function affiche_message2(){
	id_public = document.form.id_public.options[document.form.id_public.selectedIndex].value;
	id_trimestre = document.form.id_trimestre.options[document.form.id_trimestre.selectedIndex].value;
	var obj_message = document.getElementById('message2');
	if ((test_date(id_trimestre)==true)&&(id_public=='TH')){
		obj_message.style.display='block';
	}
	else obj_message.style.display='none';
}*/

function affiche_message3(){
	id_trimestre = document.form.id_trimestre.options[document.form.id_trimestre.selectedIndex].value;
	var obj_message = document.getElementById('message3');
		
	if ((id_trimestre==trimestre_test)&&(document.form.option[7].checked)){
		obj_message.style.display='block';
	} 
	else obj_message.style.display='none';
}

function mise_a_jour_option() {
	
	id_type_geographie = document.form.id_type_geographie.options[document.form.id_type_geographie.selectedIndex].value;
	id_public          = document.form.id_public.options[document.form.id_public.selectedIndex].value;
	id_categorie       = document.form.id_categorie.options[document.form.id_categorie.selectedIndex].value;
	
	chgt = false;
		
	// Activation de toutes les options par défaut
	disable_radio_option('all', false);

	disable_select('ext_public_sexe', false);
	disable_select('id_croisement_age', false);
	disable_select('ext_public_age_sexe', false);
	disable_select('id_croisement_anciennete', false);
	disable_select('ext_public_anciennete_age', false);
	disable_select('id_croisement_formation', false);
	disable_select('ext_public_formation_age', false);
	disable_select('id_croisement_qualification', false);
	disable_select('id_croisement_metier', false);
	disable_select('libelle_geographie_metier', false);
	disable_select('id_croisement_handicap', false);

	// Désactivation de la sélection du choix du type de handicap
	if (id_public == 'TP') {
		disable_radio_option('handicap', true);
		disable_select('id_croisement_handicap', true);
		chgt |= (document.form.option[7].checked == true);
	}
	
	// Désactivation de la liste des métiers recherchés pour les géographies != département
	if (id_type_geographie != 'FC') {
		disable_radio_option('metier', true);
		disable_select('id_croisement_metier', true);
		chgt |= (document.form.option[6].checked == true);
		disable_select('libelle_geographie_metier', true);
	}
	
	// Désactivation On active uniquementles tranches d'âges pour toutes les catégories
	if (id_categorie == 'C1-8') {
		disable_radio_option('sexe', true);
		disable_radio_option('anciennete', true);
		disable_radio_option('formation', true);
		disable_radio_option('qualification', true);
		disable_radio_option('metier', true);
		disable_radio_option('handicap', true);

		disable_select('ext_public_sexe', true);
		disable_select('id_croisement_anciennete', true);
		disable_select('ext_public_anciennete_age', true);
		disable_select('id_croisement_formation', true);
		disable_select('ext_public_formation_age', true);
		disable_select('id_croisement_qualification', true);
		disable_select('id_croisement_metier', true);
		disable_select('id_croisement_handicap', true);

		chgt |= (document.form.option[1].checked == true);
		chgt |= (document.form.option[3].checked == true);
		chgt |= (document.form.option[4].checked == true);
		chgt |= (document.form.option[5].checked == true);
		chgt |= (document.form.option[6].checked == true);
		chgt |= (document.form.option[7].checked == true);
	}
	

	// En cas de changement on sélectionne par défaut "Pas de critères"
	if (chgt) { document.form.option[0].checked = true; }
	
	
	//alert(id_type_geographie + ' ' + id_public + ' ' + id_categorie);
}

function disable_radio_option(elt,disable) {
	ret = false;
	taille = document.form.option.length;
	for (i = 0; i < taille; i++) {
		val  = document.form.option[i].value;
		if (val == elt || elt == 'all') {
			document.form.option[i].disabled = disable;
			ret = true;
		}
	}
	return ret;
}

function disable_select(elt,disable) {
	eval("document.form." + elt + ".disabled = " + disable + ";");
}

function select_via_texte(numero_radio) {
	document.form.option[numero_radio].checked = true;
	mise_a_jour_option();
}

function init_chps_opt(numero_radio) {
	// Réinitialisation de toutes les listes déroulantes sauf celles du bouton radio
	var tabOpt = document.form.option;
	var taille = tabOpt.length;
	var i;
	affiche_message3();
	for (i = 0; i < taille; i++) {
		if (numero_radio != i) {
			switch(i) {
				case 0:
					break;	
				case 1:
					init_select('ext_public_sexe');
					break;	
				case 2:
					init_select('id_croisement_age');
					init_select('ext_public_age_sexe');
					break;	
				case 3:
					init_select('id_croisement_anciennete');
					init_select('ext_public_anciennete_age');
					break;	
				case 4:
					init_select('id_croisement_formation');
					init_select('ext_public_formation_age');
					break;	
				case 5:
					init_select('id_croisement_qualification');
					break;	
				case 6:
					init_select('id_croisement_metier');
					init_select('libelle_geographie_metier');
					break;	
				case 7:
					init_select('id_croisement_handicap');
					break;	
			}
		}
	}
	
}

function init_formulaire(id_handi_select){
	//initialisation de la liste déroulante du type d'handicapés
	creer_liste_handi(id_handi_select);
	//initialisation du bouton des handicapés
	mise_a_jour_option();
}

function init_select(select_elt) {
	var type = eval('document.form.' + select_elt + '.type');
	if (type == 'select-one') {
		eval('document.form.' + select_elt + '.selectedIndex=0');
	}
}

function show_annotation(texte) {
	
	if (isNav=="net") {
		var width  = 160;
		var height = 50;

		desc  = "<TABLE WIDTH='"+width+"' BORDER=1 bordercolor='#B2A047' CELLPADDING=0 CELLSPACING=0 bgcolor='#CCBB68'><tr><td>";
		desc += "<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=3 bgcolor='#CCBB68'><tr><td align='center'><a id='texte'>";
		desc += texte;
		desc += "</a></td></tr></table>"; 
		desc += "</td></tr></table>"; 

		/*
		// Version avec div
		document.div_annotation.document.write(desc); 
		document.div_annotation.document.close(); 
		document.div_annotation.visibility = "show";
		*/
		// Version avec layer
		document.layers['div_annotation'].document.write(desc); 
		document.layers['div_annotation'].document.close(); 
		document.layers['div_annotation'].visibility = "show";

		// Position de la souris
		document.onmousemove = handlerMM; 
		document.captureEvents(Event.MOUSEMOVE);

		var pos_x  = Math.max(0, x - (width/2) - 10);
		var pos_y  = y+10;
		
		document.layers['div_annotation'].left   = pos_x;
		document.layers['div_annotation'].top    = pos_y;
		document.layers['div_annotation'].width  = width;
		document.layers['div_annotation'].height = height;
	}
	if (isNav=="ie") { 
		desc = "<table border=0 cellpadding=3 cellspacing=3><tr><td align='left'><a id='annotation'>";
		desc += texte;
		desc += "</a></td></tr></table>"; 
	
		div_annotation.innerHTML = desc;
		div_annotation.style.visibility = "visible";
	} 
}

function hide_annotation(texte) {
	if (isNav=="net") {
		// Version avec div
		//document.div_annotation.visibility = "hide";
		// Version avec layer
		document.layers['div_annotation'].visibility = "hide";
	} 
	if (isNav=="ie")  {
		div_annotation.style.visibility = "hidden";
	} 
}


function ouvre_div(nomdiv) {
	var divaouvrir = document.getElementById(nomdiv);
	var divaouvrirpicto = document.getElementById(nomdiv+'plus');
	if (divaouvrir){
		// on ouvre le div
		divaouvrir.style.display='block';
	}
	if (divaouvrirpicto){
		//changement du + en -
		divaouvrirpicto.innerHTML = "<a style=\"cursor:pointer;text-decoration:none;\" onclick=\"ferme_div('"+nomdiv+"');\"><font style=\"color:red;font-size:20px;\">-</font></a>";
	}
}


function ferme_div(nomdiv) {
	var divafermer = document.getElementById(nomdiv);
	var divafermerpicto = document.getElementById(nomdiv+'plus');
	if (divafermer){
		// on ouvre le div
		divafermer.style.display='none';
	}
	if (divafermerpicto){
		//changement du + en -
		divafermerpicto.innerHTML = "<a style=\"cursor:pointer;\" onclick=\"ouvre_div('"+nomdiv+"');\"><font style=\"color:red;font-size:20px;\">+</font></a>";
	}
}


function recharger_formulaire(){
	var f = document.form_moteur;
	f.action = "index.php?module=efigip&action=CIMoteur";
	f.submit();
}

function initialisation_moteur(){
	var f = document.form_moteur;
	f.reset();
	//suppression du php_session
	f.action = "index.php?module=efigip&action=CIMoteur&vide=1";
	f.submit();
}


function initialisation_session_item(session_name,id_item){
	var f = document.form_moteur;
	//suppression de l'item dans le php_session correspondant
	f.action = "index.php?module=efigip&action=CIMoteur&vide=1&session_name=" + session_name + "&id_item=" + id_item ;
	f.submit();
}

function definition_des_zonages(){
	window.open("http://www.efigip.org/themes/territoire/163-territoire-franche-comte-description.html", "_blank");
}


/*function REPC_ferme_div(){
	var div1 = document.getElementById('div_carte');
	div1.style.display="none";
	var div2 = document.getElementById('div_tableau');
	div2.style.display="none";
	var div3 = document.getElementById('div_graphique');
	div3.style.display="none";
	var div4 = document.getElementById('div_donnee');
	div4.style.display="none";
}

function REPC_ouvre_div(){
	var div1 = document.getElementById('div_carte');
	div1.style.display="block";
	var div2 = document.getElementById('div_tableau');
	div2.style.display="block";
	var div3 = document.getElementById('div_graphique');
	div3.style.display="block";
	var div5 = document.getElementById('div_donnee');
	div5.style.display="block";
}


function REPC_TestZonage(indicateur){
	var f = document.formList;
	var ind_type = f.zonageType.selectedIndex;
	var id_type = f.zonageType[ind_type].value;
	if(window.ActiveXObject) {// Internet Explorer
    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}

  	xhr_object.open("GET",  "index.php?module=efigip&action=Zonage&indicateur="+escape(indicateur)+"&id_type="+escape(id_type), true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	    	eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}*/

function REPC_TestAnnee(indicateur){
	var f = document.formList;
	var ind_type = f.annee.selectedIndex;
	var id_annee = f.annee[ind_type].value;
	if(window.ActiveXObject) {// Internet Explorer
    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}

  	xhr_object.open("GET",  "/index.php?module=efigip&action=REPCAnnee&indicateur_id="+escape(indicateur)+"&id_annee="+escape(id_annee), true);
	xhr_object.onreadystatechange = function() {
		if(xhr_object.readyState == 4){
	    	eval(xhr_object.responseText);
		}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}


/*
function REPC_submitImport(){		
	bas=window.open('patientez.html','popup_import','toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=no,copyhistory=no,width=600,height=400');
	document.formImport.target = 'popup_import';
	document.formImport.submit();
}


function REPC_ouverture(){
	if (document.getElementById) {	
		dragSort.dest = document.getElementById('dndSort');
		dragSort.makeElementSortable(document.getElementById('sortcat'));
	}
}



// fonction pour le surlignage des lignes des tableaux de valeurs
function REPC_selectLine(j){
	obj = document.getElementById("ligne_tr_"+j);
	var fs = 'ligne_td_select';
	if (obj.className!=fs) obj.className=fs;
}
function REPC_unselectLine(j){
	obj = document.getElementById("ligne_tr_"+j);
	var fs = 'ligne_td_normal';
	if (obj.className!=fs) obj.className=fs;
	
}


function REPC_TestZonageExport(){
	var f = document.formExport;
	var ind_type = f.zonageType.selectedIndex;
	var id_type = f.zonageType[ind_type].value;
	var liste_indicateur = f.liste_indicateur.value;
	
	
	if(window.ActiveXObject) {// Internet Explorer
    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}
  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportZonage&id_type="+escape(id_type)+"&id_indicateur="+escape(liste_indicateur), true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	    	eval(xhr_object.responseText);
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
}

*/
function REPC_insert_flash(p_src,p_name,p_width,p_height) {	
	div = document.getElementById("divCarte");
	div.innerHTML='<embed src="' + p_src + '" name="' + p_name + '" width="' + p_width + '" height="' + p_height + '" wmode="window" quality="high"  align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />';

}
/*

function REPC_TestThemeExport(){
	var f = document.formExport;
	var t = document.getElementById('theme2');
	var id_theme='';
	
	for(i=0;i<t.length;i++){
		var ind_theme = t[i].value;
		id_theme += ind_theme+",";
			
	}

	var longueur = id_theme.length;
	longueur = longueur-1;
	id_theme = id_theme.substr(0,longueur);

	if(window.ActiveXObject) {// Internet Explorer
    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  	}
	else if(window.XMLHttpRequest) {// Firefox
    	xhr_object = new XMLHttpRequest();
  	}
	else  { // XMLHttpRequest non supporté par le navigateur
    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
    	return;
  	}

  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportTheme&id_theme="+escape(id_theme), true);
		
	xhr_object.onreadystatechange = function() {
	  	if(xhr_object.readyState == 4){
	    	eval(xhr_object.responseText);
	    	TestIndicateurExport();
	  	}
	}
	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	var data = "";
	xhr_object.send(data);
	
}

function REPC_TestIndicateurExport(){
	var f = document.formExport;
	var t = document.getElementById('indicateur');
	var t2 = document.getElementById('indicateur2');
	var id_indicateur2='';
	
	if (t2.length!=0){
		//on regarde les indicateurs qui doivent rester dans la deuxième liste
		for (i=0;i<t.length;i++){
			for (j=0;j<t2.length;j++){
				if (t2[j].value == t[i].value){
					id_indicateur2 += t2[j].value+",";
				}
			}
		}
		
		f.liste_indicateur2.value = '';
		f.indicateur2.length=0;
		
		var longueur = id_indicateur2.length;
		longueur = longueur-1;
		id_indicateur2 = id_indicateur2.substr(0,longueur);

		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
		xhr_object.open("GET",  "index.php?module=efigip&action=ExportIndicateurAjout&id_indicateur="+escape(id_indicateur2), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		    	eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
}

//******************************************* formulaire d'export *******************************************
//*************************************** bouton tout selectionner ***********************************
//*************************************** THEME ************************************
function REPC_SelectTheme(){	
	var f = document.formExport;
	theme = document.getElementById("theme");
	var selectTheme = f.selectTheme;
	var c = selectTheme.checked;
	for(var i=0; i<theme.length; i++){
		if (theme[i].selected!=c){
			theme[i].selected = c;
		}
	}
}

function REPC_SelectTheme2(){	
	var f = document.formExport;
	theme2 = document.getElementById("theme2");
	var selectTheme2 = f.selectTheme2;
	var c = selectTheme2.checked;
	for(var i=0; i<theme2.length; i++){
		if (theme2[i].selected!=c){
			theme2[i].selected = c;
		}
	}
}

//*************************************** INDICATEUR ************************************
function REPC_SelectIndicateur(){	
	var f = document.formExport;
	indicateur = document.getElementById("indicateur");
	var selectIndicateur = f.selectIndicateur;
	var c = selectIndicateur.checked;
	for(var i=0; i<indicateur.length; i++){
		if (indicateur[i].selected!=c){
			indicateur[i].selected = c;
		}
	}
}

function REPC_SelectIndicateur2(){	
	var f = document.formExport;
	indicateur2 = document.getElementById("indicateur2");
	var selectIndicateur2 = f.selectIndicateur2;
	var c = selectIndicateur2.checked;
	for(var i=0; i<indicateur2.length; i++){
		if (indicateur2[i].selected!=c){
			indicateur2[i].selected = c;
		}
	}
}

//*************************************** ZONAGE ************************************
function REPC_SelectZonage(){	
	var f = document.formExport;
	zonageValeur = document.getElementById("zonageValeur");
	var selectZonageValeur = f.selectZonageValeur;
	var c = selectZonageValeur.checked;
	for(var i=0; i<zonageValeur.length; i++){
		if (zonageValeur[i].selected!=c){
			zonageValeur[i].selected = c;
		}
	}
}

function REPC_SelectZonage2(){	
	var f = document.formExport;
	zonageValeur2 = document.getElementById("zonageValeur2");
	var selectZonageValeur2 = f.selectZonageValeur2;
	var c = selectZonageValeur2.checked;
	for(var i=0; i<zonageValeur2.length; i++){
		if (zonageValeur2[i].selected!=c){
			zonageValeur2[i].selected = c;
		}
	}
}

//*************************************** ANNEE ************************************
function REPC_SelectAnnee(){	
	var f = document.formExport;
	annee = document.getElementById("annee");
	var selectAnnee = f.selectAnnee;
	var c = selectAnnee.checked;
	for(var i=0; i<annee.length; i++){
		if (annee[i].selected!=c){
			annee[i].selected = c;
		}
	}
}

function REPC_SelectAnnee2(){	
	var f = document.formExport;
	annee2 = document.getElementById("annee2");
	var selectAnnee2 = f.selectAnnee2;
	var c = selectAnnee2.checked;
	for(var i=0; i<annee2.length; i++){
		if (annee2[i].selected!=c){
			annee2[i].selected = c;
		}
	}
}

//*************************************** VISION ************************************
function REPC_SelectVision(){	
	var f = document.formExport;
	vision = document.getElementById("vision");
	var selectVision = f.selectVision;
	var c = selectVision.checked;
	for(var i=0; i<vision.length; i++){
		if (vision[i].selected!=c){
			vision[i].selected = c;
		}
	}
}


//**************************************** bouton d'ajout et de suppression ***********************************
//*************************************** THEME ************************************
function REPC_ajouterTheme(){
	var f = document.formExport;
	var t1 = document.getElementById('theme');
	var id_theme='';
	tab_theme_select = new Array();
    tab_theme_exist = new Array(); 
	f.liste_theme.value = '';

	var liste_existante = document.getElementById('theme2');
	for(i=0;i<liste_existante.length;i++){
		tab_theme_exist[i] = liste_existante[i].value;
		f.liste_theme.value += tab_theme_exist[i]+",";
	}

	var j=0;
	for(i=0;i<t1.length;i++){
		if (t1[i].selected) {
			tab_theme_select[j] = t1[i].value;
			j=j+1;
		}
	}
	
	for (i=0;i<tab_theme_select.length;i++){
		var test='non';
		var valeur_selectionne = tab_theme_select[i];
		for (j=0;j<tab_theme_exist.length;j++){
			if (valeur_selectionne==tab_theme_exist[j]){
				test='oui';
			}
		}
		if (test!='oui')id_theme += valeur_selectionne+",";
		test='non';
	}
	var longueur = id_theme.length;
	longueur = longueur-1;
	id_theme = id_theme.substr(0,longueur);
	
	f.liste_theme.value += id_theme;
	
	if (id_theme!=''){
		
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportThemeAjout&id_theme="+escape(id_theme), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  		TestThemeExport();
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
}


function REPC_supprimerTheme(){
	var f = document.formExport;
	var id_theme='';
	tab_theme_select = new Array();
    tab_theme_exist = new Array(); 
	f.liste_theme.value = '';
	
	var j=0;
	var liste_existante = document.getElementById('theme2');
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			tab_theme_select[j] = liste_existante[i].value;
		}
		tab_theme_exist[i] = liste_existante[i].value;
		j=j+1;
	}
	
	for (i=0;i<tab_theme_exist.length;i++){
		var test='non';
		var valeur_existante = tab_theme_exist[i];
		for (j=0;j<tab_theme_select.length;j++){
			if (valeur_existante==tab_theme_select[j]){
				test='oui';
			}
		}
		if (test!='oui')id_theme += valeur_existante+",";
		test='non';
	}
	var longueur = id_theme.length;
	longueur = longueur-1;
	id_theme = id_theme.substr(0,longueur);
	
	var liste_theme = f.theme2;
    liste_theme.length=0;
    
    var selectTheme2 = f.selectTheme2;
	if (selectTheme2.checked) selectTheme2.checked=false;

	f.liste_theme.value = id_theme;

	if (id_theme!=''){
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportThemeAjout&id_theme="+escape(id_theme), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  		TestThemeExport();
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
	else{
		f.liste_indicateur2.value = '';
		f.indicateur2.length=0;
		f.liste_indicateur.value = '';
		f.indicateur.length=0;
		
		
	}
}


//*************************************** INDICATEUR ************************************
function REPC_ajouterIndicateur(){
	var f = document.formExport;
	var t1 = document.getElementById('indicateur');
	var id_indicateur='';
	tab_indicateur_select = new Array();
    tab_indicateur_exist = new Array(); 
	f.liste_indicateur.value = '';
	var liste_indicateur_total = '';
	
	
	var liste_existante = document.getElementById('indicateur2');
	for(i=0;i<liste_existante.length;i++){
		tab_indicateur_exist[i] = liste_existante[i].value;
		liste_indicateur_total += tab_indicateur_exist[i]+",";
	}

	var j=0;
	for(i=0;i<t1.length;i++){
		if (t1[i].selected) {
			tab_indicateur_select[j] = t1[i].value;
			j=j+1;
		}
	}
	
	for (i=0;i<tab_indicateur_select.length;i++){
		var test='non';
		var valeur_selectionne = tab_indicateur_select[i];
		for (j=0;j<tab_indicateur_exist.length;j++){
			if (valeur_selectionne==tab_indicateur_exist[j]){
				test='oui';
			}
		}
		if (test!='oui')id_indicateur += valeur_selectionne+",";
		test='non';
	}
	var longueur = id_indicateur.length;
	longueur = longueur-1;
	id_indicateur = id_indicateur.substr(0,longueur);
	
	liste_indicateur_total += id_indicateur;
	f.liste_indicateur.value = liste_indicateur_total;
		
	
	if (id_indicateur!=''){
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportIndicateurAjout&id_indicateur="+escape(liste_indicateur_total), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
	
}


function REPC_supprimerIndicateur(){
	var f = document.formExport;
	var id_indicateur='';
	tab_indicateur_select = new Array();
    tab_indicateur_exist = new Array(); 
	f.liste_indicateur.value = '';
	
	var j=0;
	var liste_existante = document.getElementById('indicateur2');
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			tab_indicateur_select[j] = liste_existante[i].value;
		}
		tab_indicateur_exist[i] = liste_existante[i].value;
		j=j+1;
	}
	
	for (i=0;i<tab_indicateur_exist.length;i++){
		var test='non';
		var valeur_existante = tab_indicateur_exist[i];
		for (j=0;j<tab_indicateur_select.length;j++){
			if (valeur_existante==tab_indicateur_select[j]){
				test='oui';
			}
		}
		if (test!='oui')id_indicateur += valeur_existante+",";
		test='non';
	}
	var longueur = id_indicateur.length;
	longueur = longueur-1;
	id_indicateur = id_indicateur.substr(0,longueur);
	
	var liste_indicateur = f.indicateur2;
    liste_indicateur.length=0;
    
    var selectIndicateur2 = f.selectIndicateur2;
	if (selectIndicateur2.checked) selectIndicateur2.checked=false;

	f.liste_indicateur.value = id_indicateur;
	
	if (id_indicateur!=''){
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportIndicateurAjout&id_indicateur="+escape(id_indicateur), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
}


//*************************************** ZONAGE ************************************
function REPC_ajouterZonageValeur(){
	var f = document.formExport;
	var t1 = document.getElementById('zonageValeur');
	var id_zonageValeur='';
	var ind_type = f.zonageType.selectedIndex;
	var id_type = f.zonageType[ind_type].value;
	tab_zonageValeur_select = new Array();
    tab_zonageValeur_exist = new Array(); 
	f.liste_zonageValeur.value = '';
	
	var liste_existante = document.getElementById('zonageValeur2');
	for(i=0;i<liste_existante.length;i++){
		tab_zonageValeur_exist[i] = liste_existante[i].value;
		f.liste_zonageValeur.value += tab_zonageValeur_exist[i]+",";
	}
	
	var j=0;
	for(i=0;i<t1.length;i++){
		if (t1[i].selected) {
			tab_zonageValeur_select[j] = t1[i].value;
			j=j+1;
		}
	}
	
	for (i=0;i<tab_zonageValeur_select.length;i++){
		var test='non';
		var valeur_selectionne = tab_zonageValeur_select[i];
		for (j=0;j<tab_zonageValeur_exist.length;j++){
			if (valeur_selectionne==tab_zonageValeur_exist[j]){
				test='oui';
			}
		}
		if (test!='oui')id_zonageValeur += valeur_selectionne+",";
		test='non';
	}
	var longueur = id_zonageValeur.length;
	longueur = longueur-1;
	id_zonageValeur = id_zonageValeur.substr(0,longueur);
	
	f.liste_zonageValeur.value += id_zonageValeur;
	
	if (id_zonageValeur!=''){
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportZonageValeurAjout&id_zonageValeur="+escape(id_zonageValeur)+"&id_zonageType="+escape(id_type), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
}


function REPC_supprimerZonageValeur(){
	var f = document.formExport;
	var id_zonageValeur='';
	tab_zonageValeur_select = new Array();
    tab_zonageValeur_exist = new Array(); 
	var ind_type = f.zonageType.selectedIndex;
	var id_type = f.zonageType[ind_type].value;
	f.liste_zonageValeur.value = '';
	
	var j=0;
	var liste_existante = document.getElementById('zonageValeur2');
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			tab_zonageValeur_select[j] = liste_existante[i].value;
		}
		tab_zonageValeur_exist[i] = liste_existante[i].value;
		j=j+1;
	}
	
	for (i=0;i<tab_zonageValeur_exist.length;i++){
		var test='non';
		var valeur_existante = tab_zonageValeur_exist[i];
		for (j=0;j<tab_zonageValeur_select.length;j++){
			if (valeur_existante==tab_zonageValeur_select[j]){
				test='oui';
			}
		}
		if (test!='oui')id_zonageValeur += valeur_existante+",";
		test='non';
	}

	var longueur = id_zonageValeur.length;
	longueur = longueur-1;
	id_zonageValeur = id_zonageValeur.substr(0,longueur);
	var liste_zonageValeur = f.zonageValeur2;
    liste_zonageValeur.length=0;
    
    var selectZonageValeur2 = f.selectZonageValeur2;
	if (selectZonageValeur2.checked) selectZonageValeur2.checked=false;
	
	f.liste_zonageValeur.value = id_zonageValeur;
	
	if (id_zonageValeur!=''){
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportZonageValeurAjout&id_zonageValeur="+escape(id_zonageValeur)+"&id_zonageType="+escape(id_type), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
}


//*************************************** ANNEE ************************************
function REPC_ajouterAnnee(){
	var f = document.formExport;
	var t1 = document.getElementById('annee');
	var id_annee='';
	tab_annee_select = new Array();
    tab_annee_exist = new Array(); 
	f.liste_annee.value = '';
	
	var liste_existante = document.getElementById('annee2');
	for(i=0;i<liste_existante.length;i++){
		tab_annee_exist[i] = liste_existante[i].value;
		f.liste_annee.value += tab_annee_exist[i]+",";
	}
	
	var j=0;
	for(i=0;i<t1.length;i++){
		if (t1[i].selected) {
			tab_annee_select[j] = t1[i].value;
			j=j+1;
		}
	}
	
	for (i=0;i<tab_annee_select.length;i++){
		var test='non';
		var valeur_selectionne = tab_annee_select[i];
		for (j=0;j<tab_annee_exist.length;j++){
			if (valeur_selectionne==tab_annee_exist[j]){
				test='oui';
			}
		}
		if (test!='oui')id_annee += valeur_selectionne+",";
		test='non';
	}
	var longueur = id_annee.length;
	longueur = longueur-1;
	id_annee = id_annee.substr(0,longueur);
	
	f.liste_annee.value += id_annee;
	
	if (id_annee!=''){
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportAnneeAjout&id_annee="+escape(id_annee), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
}


function REPC_supprimerAnnee(){
	var f = document.formExport;
	var id_annee='';
	tab_annee_select = new Array();
    tab_annee_exist = new Array(); 
	f.liste_annee.value = '';
	
	var j=0;
	var liste_existante = document.getElementById('annee2');
	for(i=0;i<liste_existante.length;i++){
		if (liste_existante[i].selected) {
			tab_annee_select[j] = liste_existante[i].value;
		}
		tab_annee_exist[i] = liste_existante[i].value;
		j=j+1;
	}
	
	for (i=0;i<tab_annee_exist.length;i++){
		var test='non';
		var valeur_existante = tab_annee_exist[i];
		for (j=0;j<tab_annee_select.length;j++){
			if (valeur_existante==tab_annee_select[j]){
				test='oui';
			}
		}
		if (test!='oui')id_annee += valeur_existante+",";
		test='non';
	}
	var longueur = id_annee.length;
	longueur = longueur-1;
	id_annee = id_annee.substr(0,longueur);
	
	var liste_annee = f.annee2;
    liste_annee.length=0;
    
    var selectAnnee2 = f.selectAnnee2;
	if (selectAnnee2.checked) selectAnnee2.checked=false;
	
	f.liste_annee.value = id_annee;
	
	if (id_annee!=''){
		if(window.ActiveXObject) {// Internet Explorer
	    	xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
	  	}
		else if(window.XMLHttpRequest) {// Firefox
	    	xhr_object = new XMLHttpRequest();
	  	}
		else  { // XMLHttpRequest non supporté par le navigateur
	    	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
	    	return;
	  	}
	  	xhr_object.open("GET",  "index.php?module=efigip&action=ExportAnneeAjout&id_annee="+escape(id_annee), true);
			
		xhr_object.onreadystatechange = function() {
		  	if(xhr_object.readyState == 4){
		  		eval(xhr_object.responseText);
		  	}
		}
		xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		var data = "";
		xhr_object.send(data);
	}
}



//*************************************** AUTRES pour l'export ************************************
function REPC_vide_select(){
	var f = document.formExport;
	f.theme2.length=0;
	f.indicateur.length=0;
	f.indicateur2.length=0;
	f.zonageValeur.length=0;
	f.zonageValeur2.length=0;
	f.annee.length=0;
	f.annee2.length=0;
}

function REPC_ouvreDivAnnee(){
	var f = document.formExport;
	var div_annee = document.getElementById('test_annee');
	//div_annee.style.visibility='visible';
	div_annee.style.display='block';
}

function REPC_fermeDivAnnee(){
	var f = document.formExport;
	var div_annee = document.getElementById('test_annee');
    //div_annee.style.visibility='hidden';
    div_annee.style.display='none';
}


function REPC_creer_listeIndicateur(){
	var f = document.formExport;
	var liste2_indicateur='';
	var liste_existanteI = document.getElementById('indicateur2');
	for(i=0;i<liste_existanteI.length;i++){	
		liste2_indicateur += liste_existanteI[i].value+",";
	}
	var longueurI = liste2_indicateur.length;
	longueurI = longueurI-1;
	liste2_indicateur = liste2_indicateur.substr(0,longueurI);
	f.liste_indicateur.value = liste2_indicateur;
}

function REPC_creer_listeZonageValeur(){
	var f = document.formExport;
	var liste2_zonageValeur='';
	var liste_existanteZ = document.getElementById('zonageValeur2');
	for(i=0;i<liste_existanteZ.length;i++){	
		liste2_zonageValeur += liste_existanteZ[i].value+",";
	}
	var longueurZ = liste2_zonageValeur.length;
	longueurZ = longueurZ-1;
	liste2_zonageValeur = liste2_zonageValeur.substr(0,longueurZ);
	f.liste_zonageValeur.value = liste2_zonageValeur;
}

function REPC_creer_listeAnnee(){	
	var f = document.formExport;
	var liste2_annee='';
	var liste_existanteA = document.getElementById('annee2');
	for(i=0;i<liste_existanteA.length;i++){	
		liste2_annee += liste_existanteA[i].value+",";
	}
	var longueurA = liste2_annee.length;
	longueurA = longueurA-1;
	liste2_annee = liste2_annee.substr(0,longueurA);
	f.liste_annee.value = liste2_annee;
}


function REPC_nouvel_export(){
	var f = document.formExport;
	f.reset();
	
	var liste2_indicateur = document.getElementById('indicateur2');
	liste2_indicateur.length=0;
	var liste_indicateur = document.getElementById('indicateur');
	liste_indicateur.length=0;
	var liste2_zonageValeur = document.getElementById('zonageValeur2');
	liste2_zonageValeur.length=0;
	var liste_zonageValeur = document.getElementById('zonageValeur');
	liste_zonageValeur.length=0;
	var liste2_annee = document.getElementById('annee2');
	liste2_annee.length=0;
	var liste_annee = document.getElementById('annee');
	liste_annee.length=0;
	
	fermeDivAnnee();
	
	var div_vision_particuliere = document.getElementById('vision_particuliere');
    //div_vision_particuliere.style.visibility='hidden';
    div_vision_particuliere.style.display='none';
	
	window.scrollTo(0,0);	
	
}
















var Coordinates = {
	ORIGIN : new Coordinate(0, 0),

	northwestPosition : function(element) {
		var x = parseInt(element.style.left);
		var y = parseInt(element.style.top);

		return new Coordinate(isNaN(x) ? 0 : x, isNaN(y) ? 0 : y);
	},

	southeastPosition : function(element) {
		return Coordinates.northwestPosition(element).plus(
				new Coordinate(element.offsetWidth, element.offsetHeight));
	},

	northwestOffset : function(element, isRecursive) {
		var offset = new Coordinate(element.offsetLeft, element.offsetTop);

		if (!isRecursive) return offset;

		var parent = element.offsetParent;
		while (parent) {
			offset = offset.plus(
					new Coordinate(parent.offsetLeft, parent.offsetTop));
			parent = parent.offsetParent;
		}
		return offset;
	},

	southeastOffset : function(element, isRecursive) {
		return Coordinates.northwestOffset(element, isRecursive).plus(
				new Coordinate(element.offsetWidth, element.offsetHeight));
	},

	fixEvent : function(event) {
		event.windowCoordinate = new Coordinate(event.clientX, event.clientY);
	}
};

function Coordinate(x, y) {
	this.x = x;
	this.y = y;
}

Coordinate.prototype.toString = function() {
	return "(" + this.x + "," + this.y + ")";
}

Coordinate.prototype.plus = function(that) {
	return new Coordinate(this.x + that.x, this.y + that.y);
}

Coordinate.prototype.minus = function(that) {
	return new Coordinate(this.x - that.x, this.y - that.y);
}

Coordinate.prototype.distance = function(that) {
	var deltaX = this.x - that.x;
	var deltaY = this.y - that.y;

	return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
}

Coordinate.prototype.max = function(that) {
	var x = Math.max(this.x, that.x);
	var y = Math.max(this.y, that.y);
	return new Coordinate(x, y);
}

Coordinate.prototype.constrain = function(min, max) {
	if (min.x > max.x || min.y > max.y) return this;

	var x = this.x;
	var y = this.y;

	if (min.x != null) x = Math.max(x, min.x);
	if (max.x != null) x = Math.min(x, max.x);
	if (min.y != null) y = Math.max(y, min.y);
	if (max.y != null) y = Math.min(y, max.y);

	return new Coordinate(x, y);
}

Coordinate.prototype.reposition = function(element) {
	element.style["top"] = this.y + "px";
	element.style["left"] = this.x + "px";
}

Coordinate.prototype.equals = function(that) {
	if (this == that) return true;
	if (!that || that == null) return false;

	return this.x == that.x && this.y == that.y;
}


//*
// * drag.js - click & drag DOM elements
// *
// * originally based on Youngpup's dom-drag.js, www.youngpup.net
// *

var Drag = {
	BIG_Z_INDEX : 10000,
	group : null,
	isDragging : false,

	makeDraggable : function(group) {
		group.handle = group;
		group.handle.group = group;

		group.minX = null;
		group.minY = null;
		group.maxX = null;
		group.maxY = null;
		group.threshold = 0;
		group.thresholdY = 0;
		group.thresholdX = 0;

		group.onDragStart = new Function();
		group.onDragEnd = new Function();
		group.onDrag = new Function();
		
		// TODO: use element.prototype.myFunc
		group.setDragHandle = Drag.setDragHandle;
		group.setDragThreshold = Drag.setDragThreshold;
		group.setDragThresholdX = Drag.setDragThresholdX;
		group.setDragThresholdY = Drag.setDragThresholdY;
		group.constrain = Drag.constrain;
		group.constrainVertical = Drag.constrainVertical;
		group.constrainHorizontal = Drag.constrainHorizontal;

		group.onmousedown = Drag.onMouseDown;
	},

	

	constrain : function(nwPosition, sePosition) {
		this.minX = nwPosition.x;
		this.minY = nwPosition.y;
		this.maxX = sePosition.x;
		this.maxY = sePosition.y;
	},

	setDragHandle : function(handle) {
		if (handle && handle != null) 
			this.handle = handle;
		else
			this.handle = this;

		this.handle.group = this;
		this.onmousedown = null;
		this.handle.onmousedown = Drag.onMouseDown;
	},

	

	setDragThresholdY : function(threshold) {
		if (isNaN(parseInt(threshold))) return;

		this.thresholdY = threshold;
	},

	onMouseDown : function(event) {
		event = Drag.fixEvent(event);
		Drag.group = this.group;

		var group = this.group;
		var mouse = event.windowCoordinate;
		var nwOffset = Coordinates.northwestOffset(group, true);
		var nwPosition = Coordinates.northwestPosition(group);
		var sePosition = Coordinates.southeastPosition(group);
		var seOffset = Coordinates.southeastOffset(group, true);

		group.originalOpacity = group.style.opacity;
		group.originalZIndex = group.style.zIndex;
		group.initialWindowCoordinate = mouse;
		// TODO: need a better name, but don't yet understand how it
		// participates in the magic while dragging 
		group.dragCoordinate = mouse;

		Drag.showStatus(mouse, nwPosition, sePosition, nwOffset, seOffset);

		group.onDragStart(nwPosition, sePosition, nwOffset, seOffset);

		// TODO: need better constraint API
		if (group.minX != null)
			group.minMouseX = mouse.x - nwPosition.x + 
					group.minX - nwOffset.x;
		if (group.maxX != null) 
			group.maxMouseX = group.minMouseX + group.maxX - group.minX;

		if (group.minY != null)
			group.minMouseY = mouse.y - nwPosition.y + 
					group.minY - nwOffset.y;
		if (group.maxY != null) 
			group.maxMouseY = group.minMouseY + group.maxY - group.minY;

		group.mouseMin = new Coordinate(group.minMouseX, group.minMouseY);
		group.mouseMax = new Coordinate(group.maxMouseX, group.maxMouseY);

		document.onmousemove = Drag.onMouseMove;
		document.onmouseup = Drag.onMouseUp;

		return false;
	},

	showStatus : function(mouse, nwPosition, sePosition, nwOffset, seOffset) {
		window.status = 
				"mouse: " + mouse.toString() + "    " + 
				"NW pos: " + nwPosition.toString() + "    " + 
				"SE pos: " + sePosition.toString() + "    " + 
				"NW offset: " + nwOffset.toString() + "    " +
				"SE offset: " + seOffset.toString();
	},

	onMouseMove : function(event) {
		event = Drag.fixEvent(event);
		var group = Drag.group;
		var mouse = event.windowCoordinate;
		var nwOffset = Coordinates.northwestOffset(group, true);
		var nwPosition = Coordinates.northwestPosition(group);
		var sePosition = Coordinates.southeastPosition(group);
		var seOffset = Coordinates.southeastOffset(group, true);

		Drag.showStatus(mouse, nwPosition, sePosition, nwOffset, seOffset);

		if (!Drag.isDragging) {
			if (group.threshold > 0) {
				var distance = group.initialWindowCoordinate.distance(
						mouse);
				if (distance < group.threshold) return true;
			} else if (group.thresholdY > 0) {
				var deltaY = Math.abs(group.initialWindowCoordinate.y - mouse.y);
				if (deltaY < group.thresholdY) return true;
			} else if (group.thresholdX > 0) {
				var deltaX = Math.abs(group.initialWindowCoordinate.x - mouse.x);
				if (deltaX < group.thresholdX) return true;
			}

			Drag.isDragging = true;
			group.style["zIndex"] = Drag.BIG_Z_INDEX;
			group.style["opacity"] = 0.75;
		}

		// TODO: need better constraint API
		var adjusted = mouse.constrain(group.mouseMin, group.mouseMax);
		nwPosition = nwPosition.plus(adjusted.minus(group.dragCoordinate));
		nwPosition.reposition(group);
		group.dragCoordinate = adjusted;

		// once dragging has started, the position of the group
		// relative to the mouse should stay fixed.  They can get out
		// of sync if the DOM is manipulated while dragging, so we
		// correct the error here
		//
		// TODO: what we really want to do is find the offset from
		// our corner to the mouse coordinate and adjust to keep it
		// the same
		var offsetBefore = Coordinates.northwestOffset(group);
		group.onDrag(nwPosition, sePosition, nwOffset, seOffset);
		var offsetAfter = Coordinates.northwestOffset(group);

		if (!offsetBefore.equals(offsetAfter)) {
			var errorDelta = offsetBefore.minus(offsetAfter);
			nwPosition = Coordinates.northwestPosition(group).plus(errorDelta);
			nwPosition.reposition(group);
		}

		return false;
	},

	onMouseUp : function(event) {
		event = Drag.fixEvent(event);
		var group = Drag.group;

		var mouse = event.windowCoordinate;
		var nwOffset = Coordinates.northwestOffset(group, true);
		var nwPosition = Coordinates.northwestPosition(group);
		var sePosition = Coordinates.southeastPosition(group);
		var seOffset = Coordinates.southeastOffset(group, true);

		document.onmousemove = null;
		document.onmouseup   = null;
		group.onDragEnd(nwPosition, sePosition, nwOffset, seOffset);

		if (Drag.isDragging) {
			// restoring zIndex before opacity avoids visual flicker in Firefox
			group.style["zIndex"] = group.originalZIndex;
			group.style["opacity"] = group.originalOpacity;
		}

		Drag.group = null;
		Drag.isDragging = false;

		return false;
	},

	fixEvent : function(event) {
		if (typeof event == 'undefined') event = window.event;
		Coordinates.fixEvent(event);

		return event;
	}
};



// Drag and drop tools by Tim Taylor. Code is under public license.
//http://tool-man.org/examples/sorting.html 

// TODO: refactor away duplicationg in DragSort and DragSortX
var dragSort = {
	getSortableItems : function(e) {
		var items = e.getElementsByTagName('div');
		var res = Array();
		for (var i = 0; i < items.length; i++) {
			if (items[i].className.match(/(^|\s)sort(\s|$)/)) {
				res.push(items[i]);
			}
		}
		return res;
	},
	
	getOrder : function(e) {
		var items = dragSort.getSortableItems(e);
		var res = '';
		for (var i = 0; i< items.length; i++) {
			res += items[i].id+';';
		}
		
		return res.replace(/;$/,'');
	},
	
	makeElementSortable : function(e) {
		var items = dragSort.getSortableItems(e);
		for (var i = 0; i < items.length; i++) {
			dragSort.makeItemSortable(items[i]);
		}
	},
	
	prepareItem : function(e) {
		for (var i=0; i < e.childNodes.length; i++) {
			if (e.childNodes[i].nodeName == 'P' &&
			e.childNodes[i].className == 'nojsfield') {
				e.removeChild(e.childNodes[i]);
			}
		}
		e.className += ' sortJS';
	},
	
	makeItemSortable : function(item) {
		Drag.makeDraggable(item);

		dragSort.prepareItem(item);
		
		item.setDragThresholdY(5);
		item.style.position = 'relative';
		item.onDragStart = dragSort.onDragStart;
		item.onDrag = dragSort.onDrag;
		item.onDragEnd = dragSort.onDragEnd;
	},
	
	onDragStart : function(nwPosition, sePosition, nwOffset, seOffset) {
		var items = dragSort.getSortableItems(this.parentNode);
		var minOffset = Coordinates.northwestOffset(items[0], true);
		var maxOffset = Coordinates.northwestOffset(items[items.length - 1], true);
		this.constrain(minOffset, maxOffset);
	},

	onDrag : function(nwPosition, sePosition, nwOffset, seOffset) {
		var parent = this.parentNode;

		var item = this;
		var next = DragUtils.nextItem(item);
		while (next != null && this.offsetTop >= next.offsetTop - 2) {
			var item = next;
			var next = DragUtils.nextItem(item);
		}
		if (this != item) {
			DragUtils.swap(this, next);
			return;
		}

		var item = this;
		var previous = DragUtils.previousItem(item);
		while (previous != null && this.offsetTop <= previous.offsetTop + 2) {
			var item = previous;
			var previous = DragUtils.previousItem(item);
		}
		if (this != item) {
			DragUtils.swap(this, item);
			return;
		}
	},

	onDragEnd : function(nwPosition, sePosition, nwOffset, seOffset) {
		this.style["top"] = "0px";
		this.style["left"] = "0px";
		
		if (dragSort.dest != null) {
			dragSort.dest.value = dragSort.getOrder(this.parentNode);
		}
	}
};

var DragUtils = {
	swap : function(item1, item2) {
		var parent = item1.parentNode;
		parent.removeChild(item1);
		parent.insertBefore(item1, item2);

		item1.style["top"] = "0px";
		item1.style["left"] = "0px";
	},

	nextItem : function(item) {
		var sibling = item.nextSibling;
		while (sibling != null) {
			if (sibling.nodeName == item.nodeName) return sibling;
			sibling = sibling.nextSibling;
		}
		return null;
	},

	previousItem : function(item) {
		var sibling = item.previousSibling;
		while (sibling != null) {
			if (sibling.nodeName == item.nodeName) return sibling;
			sibling = sibling.previousSibling;
		}
		return null;
	}
};*/


