/*name			: Class Behaviour - Seperate Modular Behavioursupdate			: 20070705author			: Maurice van Creijdependencies	: classbehaviours.jsinfo			: http://www.woollymittens.nl/*/
	
	// create the classBehaviour object if it doesn't already
	if(typeof(classBehaviour)=='undefined'){
		function ClassBehaviour(){
			this.handlers = new Array();
		}
		classBehaviour = new ClassBehaviour();
	}
			// blinks			// define this class behaviour			function Blink(){				// properties				this.name 		= 	'blink';				this.nodes 		= 	new Array();				// methods				this.start		=	function(node){										// set the starting class, if not present										if(node.className.indexOf('blinkon')<0) node.className += " blinkon";										// make new blink entry										this.nodes[this.nodes.length] = new Array(node,null,1024);										// start blink loop										this.loop(this.nodes.length-1);									}				// events				this.loop		=	function(blinkIndex){										// what object goes with this index										blinkObject = this.nodes[blinkIndex][0];										// toggle the blink class of this object										blinkObject.className = (blinkObject.className.indexOf('blinkoff')>-1) ? blinkObject.className.replace('blinkoff','blinkon') : blinkObject.className.replace('blinkon','blinkoff');										// set timeout till the next blink toggle										this.nodes[blinkIndex][1] = setTimeout('classBehaviour.blink.loop('+blinkIndex+')',this.nodes[blinkIndex][2]);									}			}			// add this function to the classbehaviour object			classBehaviour.blink = new Blink;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.blink;
			
		// runs through a sequence of class names			// define this class behaviour			function AnimatedClassName(){				// properties				this.name 		= 	'animatedClassName';
				this.index		=	0;
				this.interval	=	null;				// methods				this.start		=	function(node){										// give an id if the item has none
										node.id = (node.id) ? node.id : this.name + this.index++ ;
										// get the animation properties
										animationDelay = parseInt(classBehaviour.utilities.getClassParameter(node, 'delay', '500'));
										// see if mouse interaction is required
										onlyOnFocus = (classBehaviour.utilities.getClassParameter(node, 'focus', 'no') == 'yes');
										if(onlyOnFocus){
											// set a classname for keeping track of the focus
											node.className += ' interaction_no';
											// set the event handlers
											node.onmouseover = this.play;
											node.onmouseout = this.stop;
											node.onfocus = this.play;
											node.onblur = this.stop;
										}else{
											// start its animation sequence
											this.interval = setInterval('classBehaviour.animatedClassName.loop("'+node.id+'")', animationDelay);
										}									}				// events
				this.play		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// add the interaction marker
										objNode.className = objNode.className.replace('interaction_no', 'interaction_yes');
										// start the animation
										classBehaviour.animatedClassName.loop(objNode.id);
									}
				this.stop		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// remove the interaction marker
										objNode.className = objNode.className.replace('interaction_yes', 'interaction_no');
									}				this.loop		=	function(animId){
										animNode = document.getElementById(animId);
										// get the animation properties
										animationStep = parseInt(classBehaviour.utilities.getClassParameter(animNode, 'step', '0'));
										animationLoop = parseInt(classBehaviour.utilities.getClassParameter(animNode, 'loop', '4'));
										// get the next animation step
										nextAnimationStep = (animationStep<animationLoop) ? animationStep+1 : 0 ;
										// set the next animation step
										animNode.className = animNode.className.replace('step_' + animationStep + ' ', 'step_' + nextAnimationStep + ' ');
										// if this node has the focus, do the animation again, or reset it
										interaction = classBehaviour.utilities.getClassParameter(animNode, 'interaction', null);
										animationDelay = parseInt(classBehaviour.utilities.getClassParameter(animNode, 'delay', '500'));
										if(interaction=='yes'){
											setTimeout('classBehaviour.animatedClassName.loop("'+animId+'")', animationDelay);
										}else if(interaction=='no'){
											classBehaviour.utilities.setClassParameter(animNode, 'step', '0');
										}									}			}			// add this function to the classbehaviour object			classBehaviour.animatedClassName = new AnimatedClassName;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.animatedClassName;					// replace in class			// define this class behaviour			function ClassMouseHover(){				// properties				this.name 		= 	'classMouseHover';				// methods				this.start		=	function(node){										node.onmouseover = this.addHover;										node.onmouseout = this.remHover;									}				this.hasNoStateClass 	= 	function(objNode){												return (objNode.className.indexOf('link')<0 && objNode.className.indexOf('hover')<0 && objNode.className.indexOf('active')<0);											}				// events				this.addHover 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var cmh = classBehaviour.classMouseHover;										// replace link by hover										objNode.className = (cmh.hasNoStateClass(objNode)) ? 'hover ' + objNode.className : objNode.className.replace('link','hover') ;										// if there is an image within, replace it with the hover state too										allImages = objNode.getElementsByTagName('IMG');										if(allImages.length>0) allImages[0].src = allImages[0].src.replace('_link','_hover');									}				this.remHover 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var cmh = classBehaviour.classMouseHover;										// replace hover by link										objNode.className = (cmh.hasNoStateClass(objNode)) ? 'link ' + objNode.className : objNode.className.replace('hover','link') ;										// if there is an image within, replace it with the hover state too										allImages = objNode.getElementsByTagName('IMG');										if(allImages.length>0) allImages[0].src = allImages[0].src.replace('_hover','_link');									}				this.addActive 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var cmh = classBehaviour.classMouseHover;										// replace link by active										objNode.className = objNode.className.replace('link','active') ;										// replace hover by active										objNode.className = objNode.className.replace('hover','active') ;										// if there's still no active class										if(cmh.hasNoStateClass(objNode)) objNode.className = 'active ' + objNode.className;									}			}			// add this function to the classbehaviour object			classBehaviour.classMouseHover = new ClassMouseHover;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.classMouseHover;					// make all sub elements fake the :hover attribute with .hover			// define this class behaviour			function PseudoHover(){				// properties				this.name 		= 	'pseudoHover';
				this.index		=	0;
				this.timeout	=	null;				// methods				this.start		=	function(node){
										//for the childnodes of the navigation
										allItems = node.getElementsByTagName('LI');
										for(var a=0; a<allItems.length; a++){
											if(allItems[a].nodeName == 'LI'){
												// add starting properties
												allItems[a].className += (allItems[a].className.indexOf('link')<0) ? ' link' : '' ;
												// add the mouse events
												allItems[a].onmouseover = this.hoverOver;
												allItems[a].onmouseout = this.hoverOff;
											}
										}									}
				// events
				this.hoverOver	=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var psh = classBehaviour.pseudoHover;
										// cancel the reset time-out
										clearTimeout(psh.timeout);
										// set the clipping to reveal the content graduately
										panelNode = objNode.getElementsByTagName('UL');
										if(panelNode.length>0){
											panelNode[0].id = (panelNode[0].id) ? panelNode[0].id : psh.name + psh.index++;
											classBehaviour.fader.reveal(panelNode[0].id, panelNode[0].offsetWidth, panelNode[0].offsetHeight, 100, 25);
										}
										// change the classname to show the item in MSIE 6
										objNode.className = objNode.className.replace('link', 'hover');
									}
				this.hoverOff	=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var psh = classBehaviour.pseudoHover;
										// cancel the reset time-out
										clearTimeout(psh.timeout);
										// set the clipping to vanish the content gradualy
										panelNode = objNode.getElementsByTagName('UL');
										if(panelNode.length>0){
											psh.timeout = setTimeout('classBehaviour.fader.vanish("'+panelNode[0].id+'")', 250);
										}
										// vanish the peers
										peersAndChildPanels = objNode.parentNode.getElementsByTagName('UL');
										for(var a=0; a<peersAndChildPanels.length; a++){
											if(peersAndChildPanels[a].id && peersAndChildPanels[a]!=panelNode[0] && peersAndChildPanels[a].parentNode.parentNode!=panelNode[0])
												classBehaviour.fader.vanish(peersAndChildPanels[a].id);
										}
										// change the classname to show the item in MSIE 6
										objNode.className = objNode.className.replace('hover', 'link');
									}			}			// add this function to the classbehaviour object			classBehaviour.pseudoHover = new PseudoHover;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.pseudoHover;
			// replace in src sub-string			// define this class behaviour			function SrcMouseHover(){				// properties				this.name 			= 	'srcMouseHover';				this.cache 			= new Array();				// methods				this.start			=	function(node){											this.cacheImages(node);											node.onmouseover = this.addHover;											node.onmouseout = this.remHover;										}				this.cacheImages	 = 	function(that) {											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;											// if this is not the image, it must be the parent											if(!objNode.src) objNode = objNode.getElementsByTagName('IMG')[0];											// replace link by hover											var cacheIdx = this.cache.length;											// hover version											this.cache[cacheIdx] = new Image();											this.cache[cacheIdx].src = objNode.src.replace('_link','_hover');											// active version											this.cache[cacheIdx+1] = new Image();											this.cache[cacheIdx+1].src = objNode.src.replace('_link','_active');										}				// events				this.addActive 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// if this is not the image, it must be the parent										if(objNode.nodeName!='IMG') objNode = objNode.getElementsByTagName('IMG')[0];										// replace link by active										objNode.src = objNode.src.replace('_link','_active');										// replace hover by active										objNode.src = objNode.src.replace('_hover','_active');									}				this.addHover 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// if this is not the image, it must be the parent										if(!objNode.src) objNode = objNode.getElementsByTagName('IMG')[0];										// replace link by hover										objNode.src = objNode.src.replace('_link','_hover');									}				this.remHover 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// if this is not the image, it must be the parent										if(!objNode.src) objNode = objNode.getElementsByTagName('IMG')[0];										// replace link by hover										objNode.src = objNode.src.replace('_hover','_link');									}			}			// add this function to the classbehaviour object			classBehaviour.srcMouseHover = new SrcMouseHover;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.srcMouseHover;					// replace in src sub-string			// define this class behaviour			function FadeMouseHover(){				// properties				this.name 			= 'fadeMouseHover';				this.index			= 0;
				this.timeOut		= null;				// methods				this.start			=	function(node){											this.setUpFader(node);										}				this.setUpFader		=	function(that){											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											// set the properties of this node
											objNode.id = (objNode.id) ? objNode.id : this.name + this.index++ ;
											objNode.className = objNode.className.replace(this.name, '');											// clone the image
											clonedNode = objNode.cloneNode(true);
											// set the properties of the clone
											clonedNode.style.position = 'absolute';
											clonedNode.className = clonedNode.className.replace(this.name, 'hover');
											if(clonedNode.src) clonedNode.src = clonedNode.src.replace('_link.','_hover.');
											clonedNode.id = (clonedNode.id) ? clonedNode.id : this.name + this.index++ ;
											// place it before the original icon
											objNode.parentNode.insertBefore(clonedNode, objNode);
											// get the new node as an object
											newNode = classBehaviour.utilities.previousNode(objNode);											// set the default fade											classBehaviour.fader.setFade(newNode, 0);											// set up the events											newNode.onmouseover = this.addHover;											newNode.onmouseout = this.remHover;										}				// events				this.addHover 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var fmh = classBehaviour.fadeMouseHover;										// if there's no fade active at the moment 										if(classBehaviour.fader.getFade(objNode)%100==0){
											// fade out the image											classBehaviour.fader.fadeIn(objNode.id, 20, 50, '');										// else try again in a bit										}else{
											fmh.timeOut = setTimeout('classBehaviour.fadeMouseHover.addHover(document.getElementById("' + objNode.id + '"))',50);										}									}				this.remHover 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var fmh = classBehaviour.fadeMouseHover;										// if there's no fade active at the moment 										if(classBehaviour.fader.getFade(objNode)%100==0){
											// fade out the image											classBehaviour.fader.fadeOut(objNode.id, 20, 50, '');										// else try again in a bit										}else{											fmh.timeOut = setTimeout('classBehaviour.fadeMouseHover.remHover(document.getElementById("' + objNode.id + '"))',100);										}									}			}			// add this function to the classbehaviour object			classBehaviour.fadeMouseHover = new FadeMouseHover;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.fadeMouseHover;					// hides nodes			// hide the "hideThisNode" class behaviour by default 			document.writeln("<style>.hideThisNode{overflow:hidden; visibility:hidden; height:1px;}</style>");			// define this class behaviour			function HideThisNode(){				// properties				this.name 		= 	'hideThisNode';				// methods				this.start		=	function(node){										node.style.overflow = 'hidden';										node.style.visibility = 'hidden';										node.style.height = '1px';
										node.className = node.className.replace('showThisNode', 'hideThisNode');									}			}			// add this function to the classbehaviour object			classBehaviour.hideThisNode = new HideThisNode;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.hideThisNode;					// explicit opposite of a hidden node			// define this class behaviour			document.writeln("<style>.ShowThisNode{overflow:visible; visibility:visible; height:auto;}</style>");			function ShowThisNode(){				// properties				this.name 		= 	'showThisNode';				// methods				this.start		=	function(node){										node.style.overflow = 'visible';										node.style.visibility = 'visible';										node.style.height = 'auto';
										node.className = node.className.replace('hideThisNode', 'showThisNode');									}			}			// add this function to the classbehaviour object			classBehaviour.showThisNode = new ShowThisNode;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.showThisNode;					// show or hide a node			// define this class behaviour			document.writeln("<style>.toggleNextNode{cursor:pointer;}</style>");			function ToggleNextNode(){				// properties				this.name 			= 	'toggleNextNode';				this.step			=	20;				this.delay			=	10;				this.index			=	0;				// methods				this.start			=	function(node){											// set the event handlers for the source node											node.onclick = this.toggle;											// give this node an id if it doesn't have one yet											node.id = (node.id) ? node.id : this.name + this.index++ ;											// is this node marked as "auto", order it to open on a timeout											autoDelay = classBehaviour.utilities.getClassParameter(node, 'auto', null);											if(autoDelay){												this.index++												node.id = (node.id) ? node.id : this.name + this.index ;												setTimeout('classBehaviour.toggleNextNode.toggle(document.getElementById("'+node.id+'"))', autoDelay);											}										}				this.shrink			=	function(label, container, finished){											var t2n = classBehaviour.toggleNextNode;											// deactivate the label											label.className = label.className.replace('active','link');											label.parentNode.className = label.parentNode.className.replace('active','link');											// if the container isn't shrunk completely											if(container.offsetHeight>t2n.step){												// height before												heightBefore = container.style.height;												// reduce its height by an amount												container.style.overflow = 'hidden';												container.style.visibility = 'visible';												container.style.height = (container.offsetHeight - t2n.step) + 'px';												// height after												heightAfter = container.style.height;												// the resizing isnt' working, skip straight to the end situation												finished = (heightBefore==heightAfter) ? classBehaviour.hideThisNode.start(container) : false ;											}else{												// close the container												classBehaviour.hideThisNode.start(container);											}											// return the state											return finished;										}				this.grow			=	function(label, container, finished){											var t2n = classBehaviour.toggleNextNode;											// activate the label											label.className = label.className.replace('link','active').replace('hover','active');											label.parentNode.className = label.parentNode.className.replace('link','active').replace('hover','active');											// measure the height of all the childnodes of the container											totalHeight = 0;											contents = container.childNodes;											for(var a=0; a<contents.length; a++){												totalHeight += (contents[a].offsetHeight) ? contents[a].offsetHeight : 0 ;											}											// if the container isn't grown completely											if(container.offsetHeight<totalHeight-t2n.step){												// height before												heightBefore = container.style.height;												// increase its height by an amount												container.style.overflow = 'hidden';												container.style.visibility = 'visible';												container.style.height = (container.offsetHeight + t2n.step) + 'px';												// height after												heightAfter = container.style.height;												// the resizing isnt' working, skip straight to the end situation
												finished = (heightBefore==heightAfter) ? classBehaviour.showThisNode.start(container) : finished = false;											}else{												// open the container
												classBehaviour.showThisNode.start(container);											}											// return the state											return finished;										}
				this.findContainer	=	function(targetLabel, targetRecursion){
											// if there was a target recursion, recurse parent nodes
											if(targetRecursion) for(var a=0; a<parseInt(targetRecursion); a++) targetLabel = targetLabel.parentNode;
											// get the next sibling of the label, which should be the container
											targetObject = classBehaviour.utilities.nextNode(targetLabel);
											// pass it back
											return targetObject;
										}				// events				this.toggle 		= 	function(that){											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;											var t2n = classBehaviour.toggleNextNode;											// get all information on this node											targetLabel = objNode;											targetContainerId = classBehaviour.utilities.getClassParameter(targetLabel, 'id', null);
											targetRecursion = classBehaviour.utilities.getClassParameter(targetLabel, 'parent', null);											targetContainer = (targetContainerId) ? document.getElementById(targetContainerId) : t2n.findContainer(targetLabel, targetRecursion) ;
											// if the target container is not marked for hiding or showing, mark it now
											if(targetContainer.className.indexOf('hideThisNode')<0 && targetContainer.className.indexOf('showThisNode')<0) targetContainer.className += ' showThisNode' ;											// call for the node to grow or shrink											targetGrows = (targetContainer.className.indexOf('hideThisNode')>-1);											t2n.update(targetLabel.id, targetGrows);											// cancel the click											return false;										}				this.update			=	function(id, grows){											var t2n = classBehaviour.toggleNextNode;											// finished marker											finished = true;											// get all information on this node											targetLabel = document.getElementById(id);											targetContainerId = classBehaviour.utilities.getClassParameter(targetLabel, 'id', null);											targetFamily = classBehaviour.utilities.getClassParameter(targetLabel, 'family', null);
											targetRecursion = classBehaviour.utilities.getClassParameter(targetLabel, 'parent', null);											targetContainer = (targetContainerId) ? document.getElementById(targetContainerId) : t2n.findContainer(targetLabel, targetRecursion) ;
											// get all nodes of this class
											allNodes = classBehaviour.utilities.getElementsByClassName(t2n.name);											// for every node in the node-list											for(var a=0; a<allNodes.length; a++){												// get its family												peerLabel = allNodes[a];												peerContainerId = classBehaviour.utilities.getClassParameter(peerLabel, 'id', null);												peerFamily = classBehaviour.utilities.getClassParameter(peerLabel, 'family', null);
												peerRecursion = classBehaviour.utilities.getClassParameter(peerLabel, 'parent', null);												peerContainer = (peerContainerId) ? document.getElementById(peerContainerId) : t2n.findContainer(peerLabel, peerRecursion) ;												// if this node belongs to the same family and is open but has a different id												if(peerFamily==targetFamily && peerFamily!=null && peerContainer.className.indexOf('hideThisNode')<0 && peerContainer!=targetContainer){													// close the container one step													finished = this.shrink(peerLabel, peerContainer, finished);												// else if this node has the same id and is open												}else if(peerLabel.id==targetLabel.id && !grows){													// close the container one step													finished = this.shrink(targetLabel, targetContainer, finished);												// else 												}else if(peerLabel.id==targetLabel.id && grows){													// open the container one step													finished = this.grow(targetLabel, targetContainer, finished);												}											}											// if any step marked the function as unfinished											if(!finished){												// repeat it												setTimeout("classBehaviour.toggleNextNode.update('"+id+"',"+grows+")", t2n.delay);											}else{												// notify the iframe resizer to update its size if needed												if(document.body.className.indexOf('resizeIframe')>-1) classBehaviour.resizeIframe.delay();											}										}			}			// add this function to the classbehaviour object			classBehaviour.toggleNextNode = new ToggleNextNode;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.toggleNextNode;
									// tabbed content			// define this class behaviour			function TabbedContent(){				// properties				this.name 		= 	'tabbedContent';				// methods				this.start		=	function(node){
										// get all lists without this node
										allLists = node.getElementsByTagName('ul');										// get all tabs from the first list										allTabs = allLists[0].getElementsByTagName('a');										// store the most likely opened tab										openedTab = allTabs[0];										// for all tabs										for(var a=0; a<allTabs.length; a++){											// get the id this tab refers to											tabId = allTabs[a].href.split('#')[1];											// apply onclick events to the referred tab											allTabs[a].onclick = this.open;											// apply the starting state of the tab if needed											if(allTabs[a].className.indexOf('closedTab')<0 && allTabs[a].className.indexOf('openedTab')<0) allTabs[a].className += ' closedTab';											// apply the starting state of the referred content if needed											document.getElementById(tabId).style.display = 'none';											// if this tab is referred to in the page url, remember it as active
											if(document.location.href.indexOf(allTabs[a].href)>-1) openedTab = allTabs[a];											// if this tab was manualy set
											if(allTabs[a].className.indexOf('openedTab')>-1) openedTab = allTabs[a];
										}										// if there is a pager list, it'd better be the last one										pager = (allLists[allLists.length-1].className.indexOf('contentPager')>-1) ? allLists[allLists.length-1] : null;
										if(pager!=null){											// assign the events for the buttons											pager.getElementsByTagName('button')[0].onclick = this.previous;											pager.getElementsByTagName('button')[1].onclick = this.next;										}										// open the most likely first tab
										this.open(openedTab, true);									}				// events				this.next		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var tbd = classBehaviour.tabbedContent;										// get the pager information										pagerInfo = objNode.parentNode.parentNode.getElementsByTagName('span')[0].firstChild.nodeValue;										// what is the current pagenumber										currentPage = parseInt(pagerInfo.split('/')[0]);										// how many pages are there										totalPages = parseInt(pagerInfo.split('/')[1]);										// what is the next page										nextPage = (currentPage<totalPages) ? currentPage + 1 : 1 ;										// what is the tabs strip										tabStrip = objNode.parentNode.parentNode.parentNode.getElementsByTagName('ul')[0];										// get the relevant page from the tab strip										targetTab = tabStrip.getElementsByTagName('a')[nextPage-1];										// activate it's click										tbd.open(targetTab);									}				this.previous	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var tbd = classBehaviour.tabbedContent;										// get the pager information										pagerInfo = objNode.parentNode.parentNode.getElementsByTagName('span')[0].firstChild.nodeValue;										// what is the current pagenumber										currentPage = parseInt(pagerInfo.split('/')[0]);										// how many pages are there										totalPages = parseInt(pagerInfo.split('/')[1]);										// what is the next page										previousPage = (currentPage>1) ? currentPage - 1 : totalPages ;										// what is the tabs strip										tabStrip = objNode.parentNode.parentNode.parentNode.getElementsByTagName('ul')[0];										// get the relevant page from the tab strip										targetTab = tabStrip.getElementsByTagName('a')[previousPage-1];										// activate it's click										tbd.open(targetTab);									}				this.open		=	function(that, noAnimation){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var tbd = classBehaviour.tabbedContent;																						// INDEX THE TAB STATES										// get all tabs										var allTabs = objNode.parentNode.parentNode.getElementsByTagName('a');										var prevTab = null;										var pageNumber = 0;										// find the current tab										for(var a=0; a<allTabs.length; a++){											// rememeber the previous tab											if(allTabs[a].className.indexOf('openedTab')>-1) prevTab = allTabs[a];											// count the new pagenumber											if(allTabs[a]==objNode) pageNumber = a;										}											// if this is the current tab again										if(prevTab!=objNode || noAnimation){																					// PREVIOUS TAB											if(prevTab){												// mark the previous tab as passive												prevTab.className = prevTab.className.replace('openedTab', 'closedTab');												// if the tab has an image												tabImages = prevTab.getElementsByTagName('img');												if(tabImages.length>0) tabImages[0].src = tabImages[0].src.replace('_active','_link');												// id the previous tabbed content												prevContentId = prevTab.href.split('#')[1];											}																						// NEXT TAB											// mark the next tab as active											objNode.className = objNode.className.replace('closedTab', 'openedTab');											// if the tab has an image											tabImages = objNode.getElementsByTagName('img');											if(tabImages.length>0) tabImages[0].src = tabImages[0].src.replace('_link','_active').replace('_hover','_active');											// id the next tabbed content											nextContentId = objNode.href.split('#')[1];																						// FADE ANIMATION											isAnimated = (noAnimation) ? 'no' : classBehaviour.utilities.getClassParameter(objNode, 'animated', 'yes') ;											if(isAnimated=='yes'){												// make the previous tab float												document.getElementById(prevContentId).style.position = 'absolute';												document.getElementById(prevContentId).style.top = '0px';												// make the next tab no float												document.getElementById(nextContentId).style.position = 'relative';												// order the animation												classBehaviour.fader.crossFade(nextContentId, prevContentId, 0, 10, 50, null);											}else{
												if(prevTab) document.getElementById(prevContentId).style.display = 'none';												document.getElementById(nextContentId).style.display = 'block';											}																						// PAGE NUMBER											// update page-numbering											pager = objNode.parentNode.parentNode.parentNode.getElementsByTagName('ul')[objNode.parentNode.parentNode.parentNode.getElementsByTagName('ul').length-1];											pager.getElementsByTagName('span')[0].firstChild.nodeValue = (pageNumber+1) + '/' + allTabs.length ;											}										// cancel the jump to the anchor
										objNode.blur();										return false;									}			}			// add this function to the classbehaviour object			classBehaviour.tabbedContent = new TabbedContent;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.tabbedContent;
							// replace image with transparent version, invoke activeX background loader			// preload cosmetic tweak			if(document.all && (navigator.userAgent.indexOf('MSIE 6.0')>-1 || navigator.userAgent.indexOf('MSIE 5')>-1) && navigator.userAgent.indexOf('Opera')<0)					document.writeln("<style>img.pngAlpha {visibility:hidden;}</style>");			// define this class behaviour			function PngAlpha(){				// properties				this.name 		= 	'pngAlpha';				// methods				this.start		=	function(node){										this.process(node);										node.onload = this.process;									}				// events				this.process 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// for the downlevel browser MSIE and the image has not been processed before										if(
											typeof(objNode.style.filter)!='undefined'
											&& (navigator.userAgent.indexOf('MSIE 6.0')>-1 || navigator.userAgent.indexOf('MSIE 5')>-1)											&& navigator.userAgent.indexOf('Opera')<0
											&& objNode.src.indexOf('.png')>-1
										){											// change the image styles											objNode.style.width		= objNode.width + 'px';											objNode.style.height	= objNode.height + 'px';											objNode.style.filter	= "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + objNode.src + "', sizingMethod='crop')";											// replace the original with the alpha variant											objNode.src = objNode.src.replace('.png', '.gif');
											objNode.style.visibility = 'visible';										}									}			}			// add this function to the classbehaviour object			classBehaviour.pngAlpha = new PngAlpha;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.pngAlpha;					// Open an overlay as a popup window			// define this class behaviour			function OpenLayerPopUp(){				// properties				this.name 		= 	'openLayerPopUp';
				this.popUpClass	=	'layerPopUp';				this.step		=	10;				this.begin		=	0;				this.end		=	50;
				this.index		=	0;				// methods				this.start		=	function(node){										// find the target layer										targetPopUp = null;										// the node's open button										node.onclick = this.load;										// open the popup immediately if required
										node.id = (node.id) ? node.id : this.name + 'Link' + this.index++ ;										if(classBehaviour.utilities.getClassParameter(node, 'auto', 'no')=='yes')
											setTimeout('classBehaviour.openLayerPopUp.load(document.getElementById("'+node.id+'"))', 250);									}				this.fadeIn	=	function(id, amount){										var olp = classBehaviour.openLayerPopUp;										node = document.getElementById(id);										nodes = node.getElementsByTagName('div');										nodeShadow = nodes[0];										nodeContent = nodes[1];										// if the amount is not 50										if(amount<olp.end){											// hide the popup content, but show the outside
											node.style.visibility = 'visible';											nodeContent.style.visibility = 'hidden';											// set the shadow's fade to the next step											nodeShadow.style.display = 'block';											if(typeof(nodeShadow.style.MozOpacity)!='undefined')	nodeShadow.style.MozOpacity = amount/100;											if(typeof(nodeShadow.style.filter)!='undefined')		nodeShadow.style.filter = "alpha(opacity=" + amount + ")";											if(typeof(nodeShadow.style.opacity)!='undefined')		nodeShadow.style.opacity = amount/100;											// show the popup collection											node.style.display = 'block';											// repeat the fade											setTimeout("classBehaviour.openLayerPopUp.fadeIn('" + id + "'," + (amount+olp.step) + ")",10);										}else{											// show the popup content											nodeContent.style.visibility = 'visible';										}									}				this.fadeOut	=	function(id, amount){										var olp = classBehaviour.openLayerPopUp;										node = document.getElementById(id);										nodes = node.getElementsByTagName('div');										nodeShadow = nodes[0];										nodeContent = nodes[1];										// if the amount is not 100										if(amount>olp.begin){											// hide the popup content											nodeContent.style.visibility = 'hidden';											// set the fade to the next step											if(typeof(nodeShadow.style.MozOpacity)!='undefined')	nodeShadow.style.MozOpacity = amount/100;											if(typeof(nodeShadow.style.filter)!='undefined')		nodeShadow.style.filter = "alpha(opacity=" + amount + ")";											if(typeof(nodeShadow.style.opacity)!='undefined')		nodeShadow.style.opacity = amount/100;											// repeat the fade											setTimeout("classBehaviour.openLayerPopUp.fadeOut('" + id + "'," + (amount-olp.step) + ")",10);										}else{											// hide the popup content											node.style.display = 'none';											// hide the popup's shadow											nodeShadow.style.display = 'none';										}									}				// events
				this.load		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var olp = classBehaviour.openLayerPopUp;
										// get the popup id
										popUpHref = (objNode.href) ? objNode.href : '' ;
										popUpId = (popUpHref.indexOf('#')>-1) ? popUpHref.split('#')[1] : classBehaviour.utilities.getClassParameter(objNode, 'id', 'popUpWithScrollBar') ;
										// if the popup is allready loaded
										popUpObj = document.getElementById(popUpId);
										if(popUpObj){
											olp.show(objNode, popUpId);
										}else{
											classBehaviour.ajax.addRequest(popUpHref, olp.insert, olp.wait, null, objNode);
										}
										// cancel the click
										return false;
									}
				this.wait		=	function(progress, referNode){
										var olp = classBehaviour.openLayerPopUp;
										// it'd be fun to see a background image behind the link text be the progress-indicator
										referNode.parentNode.style.backgroundPosition = (100-progress*100) +'% 0px';
									}
				this.insert		=	function(importedObj, referNode, importedText){
										var olp = classBehaviour.openLayerPopUp;
										//  get the popup's id
										olp.instance += 1;
										popUpId = classBehaviour.utilities.getClassParameter(referNode, 'id', olp.name+olp.instance);
										popUpWidth = classBehaviour.utilities.getClassParameter(referNode, 'width', '470');
										popUpHeight = classBehaviour.utilities.getClassParameter(referNode, 'height', '300');
										// make a new node at the end of the page
										newNode = document.createElement('div');
										document.body.appendChild(newNode);
										// get the node and fill it with delicous html
										allDivs = document.getElementsByTagName('div');
										lastDiv = allDivs[allDivs.length-1];
										importedText = (importedText.indexOf('<body>')>-1) ? importedText.split('<body>')[1].split('</body>')[0] : importedText.replace('<?xml version="1.0"?>', '') ;
										importedText = importedText.replace(/{id}/gi, popUpId);
										importedText = importedText.replace(/{title}/gi, referNode.title);
										importedText = importedText.replace(/{url}/gi, referNode.href.split('?url=')[1]);
										importedText = importedText.replace(/{width}/gi, popUpWidth);
										importedText = importedText.replace(/{height}/gi, popUpHeight);
										lastDiv.innerHTML = importedText;
										// apply any classbehaviours
										classBehaviour.parser.parseNode(lastDiv);
										// show the pop-up
										olp.show(referNode, popUpId);
									}
				this.center		=	function(popUpObj){
										if(popUpObj){
											// the dimensions can not be measured with "display:none;"											popUpObj.style.display = 'block';											// get the content segment											popupContent = popUpObj.getElementsByTagName('DIV')[2];											// how high is the content											popupHeight = popupContent.offsetHeight;											// how high is the screen											screenHeight = (window.innerHeight) ? window.innerHeight : document.documentElement.clientHeight ;											// center the popup											popupContent.style.marginTop = (screenHeight>popupHeight) ? Math.round((screenHeight-popupHeight)/2) + 'px' : '30px' ;	
										}
									}				this.show		=	function(openerObj, popUpId){										var olp = classBehaviour.openLayerPopUp;										var submit = false;										// adjust the fade parameters if it needs to open instantly
										if(openerObj){											olp.step = parseInt(classBehaviour.utilities.getClassParameter(openerObj, 'step', 10));											olp.begin = parseInt(classBehaviour.utilities.getClassParameter(openerObj, 'begin', 0));											olp.end = parseInt(classBehaviour.utilities.getClassParameter(openerObj, 'end', 50));
										}										// get the popup										popUpObj = document.getElementById(popUpId);
										// hide the popup for now
										popUpObj.style.visibility = 'hidden';
										// center the popup
										this.center(popUpObj);
										// if the link had a title and if the popup has a title. put the link title in the popup										popUpTitles = popUpObj.getElementsByTagName('h1');										if(openerObj) if(openerObj.title && popUpTitles.length>0) popUpTitles[0].innerHTML = openerObj.title;										// load a given url in the iframe it it's not there allready										popUpIframes = popUpObj.getElementsByTagName('iframe');										if(popUpIframes.length>0 && openerObj.href.indexOf('?url=')>-1){
											if(popUpIframes[0].src!=openerObj.href.split('?url=')[1]) popUpIframes[0].src = openerObj.href.split('?url=')[1];
										}										// find the close gadget										popUpClosers = popUpObj.getElementsByTagName('a');
										if(popUpClosers.length>0){											popUpClosers[0].onclick = olp.hide;
										}										// remove the scroll bars										if(navigator.appVersion.indexOf('MSIE 6')>-1 || navigator.appVersion.indexOf('MSIE 5')>-1){
											// manage the scroll positions											if(popUpObj.className.indexOf('fullHeightPopUp')<0){
												// reset the scroll position
												document.documentElement.scrollLeft = 0;
												document.documentElement.scrollTop = 0;
												// hide the scrollbars if needed
												document.body.parentNode.style.overflow = "hidden";
												// reposition the popup according to the scroll position
												popUpObj.getElementsByTagName('DIV')[2].style.marginTop = Math.round(document.documentElement.scrollTop + (screenHeight-popupHeight)/2) + 'px' ;
											}
											// size the shadow under the popup											popUpObj.getElementsByTagName('DIV')[0].style.height = document.body.offsetHeight + 'px';
											// hide the selects											allSelects = document.getElementsByTagName('select');											for(var a=0; a<allSelects.length; a++) allSelects[a].style.visibility = 'hidden';										}
										// if there is a popup open already
										if(olp.opened!=null){
											// instantly hide the old one
											document.getElementById(olp.opened).style.display = 'none';
											// instantly show the new one
											document.getElementById(popUpId).style.display = 'block';
											document.getElementById(popUpId).style.visibility = 'visible';
										}else{
											// fade the popup in, but give the contents a little head start											setTimeout('classBehaviour.openLayerPopUp.fadeIn("'+popUpId+'", '+olp.begin+')', 1000);
										}										// remember the open popup
										olp.opened = popUpId;										// cancel the click										return submit;									}				this.hide		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var olp = classBehaviour.openLayerPopUp;										// the popup object
										popUp = objNode;
										while(popUp.className.indexOf(olp.popUpClass)<0){
											popUp = popUp.parentNode;
										}										// fade the popup out										olp.fadeOut(popUp.id, olp.end);										// restore the scroll bars										if(navigator.appVersion.indexOf('MSIE 6')>-1 || navigator.appVersion.indexOf('MSIE 5')>-1){
											// show the scrollbars											if(popUp.className.indexOf('fullHeightPopUp')<0) document.body.parentNode.style.overflow = "";											// show the selects
											allSelects = document.getElementsByTagName('select');											for(var a=0; a<allSelects.length; a++) allSelects[a].style.visibility = 'visible';										}
										// clear the iframe contents
										popUpIframes = popUp.getElementsByTagName('iframe');										if(popUpIframes.length>0){
											popUpIframes[0].src = "";
										}
										// note that nothing is opened
										olp.opened = null;										// cancel the click										return false;									}			}			// add this function to the classbehaviour object			classBehaviour.openLayerPopUp = new OpenLayerPopUp;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openLayerPopUp;
			
		// replace the contents of the popup			// define this class behaviour			function ReplaceLayerPopUp(){				// properties				this.name 		= 	'replaceLayerPopUp';				// methods				this.start		=	function(node){										// set the event handler for the link
										node.onclick = this.clicked;									}
				this.wait		=	function(progress, referer){
										// No indicator was designed
									//	debug(progress);
									}
				this.insert		=	function(xmlObj, referer, xmlText){
										// get the root of this popup
										rootNode = classBehaviour.utilities.rootNode(referer, null, null, 'layerPopUp');
										// clean the incoming content
										popUpText = xmlText.split('<!-- cut here -->')[1];
										// insert the new content
										rootNode.innerHTML = popUpText;
										// re-apply the classbehaviour
										classBehaviour.parser.parseNode(rootNode);
										// recenter
										classBehaviour.openLayerPopUp.center(rootNode);										// find the close gadget										popUpClosers = rootNode.getElementsByTagName('a');
										if(popUpClosers.length>0){											popUpClosers[0].onclick = classBehaviour.openLayerPopUp.hide;
										}
									}
				// events				this.clicked 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var rlp = classBehaviour.replaceLayerPopUp;										// get the new content from the url
										importUrl = objNode.href;
										classBehaviour.ajax.addRequest(importUrl, rlp.insert, rlp.wait, null, objNode);										// cancel browser mouse click										return false;									}			}			// add this function to the classbehaviour object			classBehaviour.replaceLayerPopUp = new ReplaceLayerPopUp;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.replaceLayerPopUp;
			
		// move the node to the bottom of the document			// define this class behaviour			function LayerPopUp(){				// properties				this.name 		= 	'layerPopUp';				// methods				this.start		=	function(node){
										// if this node wasn't moved										if(node.className.indexOf('doNotMove')<0) this.process(node);									}				this.process 	= 	function(objNode){										// take this node
									 	removedChild = objNode.parentNode.removeChild(objNode);
									 	removedChild.className += ' doNotMove';
										// and put it at the end of the document
										document.body.appendChild(removedChild);									}			}			// add this function to the classbehaviour object			classBehaviour.layerPopUp = new LayerPopUp;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.layerPopUp;
			
		// use a button to hide the popup layer			// define this class behaviour			function CloseLayerPopUp(){				// properties				this.name 			= 	'closeLayerPopUp';				// methods				this.start			=	function(node){
											node.onclick = this.closePopUp;										}				this.closePopUp 	= 	function(that){											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;											// get the root of this popup
											rootNode = classBehaviour.utilities.rootNode(objNode, null, null, 'layerPopUp');
											// close the layer
											classBehaviour.openLayerPopUp.hide(rootNode);										}			}			// add this function to the classbehaviour object			classBehaviour.closeLayerPopUp = new CloseLayerPopUp;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.closeLayerPopUp;
									// Alternates the classes of a table's rows and columns			// define this class behaviour			function ZebraTable(){				// properties				this.name 		= 	'zebraTable';				// methods				this.start		=	function(node){										this.process(node);									}				this.process 	= 	function(objNode){										var objRows, objCols, intCellNumber;										// get all table rows										objRows = objNode.getElementsByTagName('TR');										// for all table rows										for(var intRow=0; intRow<objRows.length; intRow++){											// undo any previous classing											objRows[intRow].className = objRows[intRow].className.replace('odd','');											objRows[intRow].className = objRows[intRow].className.replace('even','');											// add oddrow or evenrow class to the row											objRows[intRow].className += (intRow%2==0) ? ' odd' : ' even' ;											// and row and col counters if they're not allready present											if(objRows[intRow].className.indexOf('row_')<0) objRows[intRow].className += ' row_' + intRow;											// get all nodes in this row											objCols = objRows[intRow].childNodes;											// for every node in the row											intCellNumber = 0;											for(var intCol=0; intCol<objCols.length; intCol++){												// is this a cell or a header												if(objCols[intCol].nodeName.indexOf('text')<0){													// undo any previous classing													objCols[intCol].className = objCols[intCol].className.replace('odd','');													objCols[intCol].className = objCols[intCol].className.replace('even','');													// add oddcol or evencol class													objCols[intCol].className += (intCellNumber%2==0) ? ' odd' : ' even' ;													// and row and col counters if they're not allready present													if( objCols[intCol].className.indexOf('col_')<0) objCols[intCol].className += ' col_' + intCellNumber;													// keep cell numbers													intCellNumber += 1;												}											}										}									}			}			// add this function to the classbehaviour object			classBehaviour.zebraTable = new ZebraTable;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.zebraTable;					// Makes the headers of a table click/sortable			// define this class behaviour			function SortByColumn(){				// properties				this.name 		= 	'sortByColumn';				this.column	=	0;				// methods				this.start		=	function(node){										node.onclick = this.sort;										// apply the default sort direction style										if(node.className.indexOf('sorted')<0) node.className += ' unSorted';									}				this.forward 	= 	function(rowA,rowB){										var st = classBehaviour.sortByColumn;										var regTags = new RegExp('<(.|\n)+?>','gi');										// get the string values from the node										strA = (rowA.childNodes[st.column].childNodes.length == 0) ? ' ' : rowA.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');										strB = (rowB.childNodes[st.column].childNodes.length == 0) ? ' ' : rowB.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');										// get the numeric values from the node										intA = parseInt(strA.replace(',',''));										intB = parseInt(strB.replace(',',''));										// compare the values for the sort funtion										if(strA==strB || (navigator.appVersion.indexOf('MSIE 5.0')>-1)){											// equal											return 0;										}else if(isNaN(intA) || isNaN(intB)){											// compare the textual values											return (strA<strB) ? 1 : -1 ;										}else{											// compare the numeric values											return intB - intA;										}									}				this.reverse 	= 	function(rowA,rowB){										var st = classBehaviour.sortByColumn;										var regTags = new RegExp('<(.|\n)+?>','gi');										// get the string values from the node										strA = (rowA.childNodes[st.column].childNodes.length == 0) ? ' ' : rowA.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');										strB = (rowB.childNodes[st.column].childNodes.length == 0) ? ' ' : rowB.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');										// get the numeric values from the node										intA = parseInt(strA.replace(',',''));										intB = parseInt(strB.replace(',',''));										// compare the values for the sort funtion										if(strA==strB || (navigator.appVersion.indexOf('MSIE 5.0')>-1)){											// equal											return 0;										}else if(isNaN(intA) || isNaN(intB)){											// compare the textual values											return (strA>strB) ? 1 : -1 ;										}else{											// compare the numeric values											return intA - intB;										}									}				// events				this.sort 		= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var st = classBehaviour.sortByColumn;										// defaults										sortDirection	= 'sortedForward';										// find column number										var objSiblings	= objNode.parentNode.childNodes;										for(var intA=0; intA<objSiblings.length; intA++){											// is this a cell of a text-node											if(objSiblings[intA].nodeName=="TD" || objSiblings[intA].nodeName=="TH"){												// test if this is the clicked node												if(objSiblings[intA] == objNode){													// remember the clicked column													st.column = intA;													// toggle the sort direction													sortDirection = (objSiblings[intA].className.indexOf('sortedForward')>-1) ? 'sortedReverse' : 'sortedForward' ;													// adjust the sorting direction classname													objSiblings[intA].className = objSiblings[intA].className.replace('sortedReverse', sortDirection);													objSiblings[intA].className = objSiblings[intA].className.replace('sortedForward', sortDirection);													objSiblings[intA].className = objSiblings[intA].className.replace('unSorted', sortDirection);												}else{													// unmark any previously sorted column													objSiblings[intA].className = objSiblings[intA].className.replace('sortedReverse', 'unSorted');													objSiblings[intA].className = objSiblings[intA].className.replace('sortedForward', 'unSorted');												}											}										}										// make a nodelist										var fullTable		= objNode.parentNode.parentNode.parentNode;										var sortParent		= fullTable.getElementsByTagName('TBODY')[0];										var nodeList		= sortParent.childNodes;										var nodeArray		= new Array();										// for all table rows										for(var intA=0; intA<nodeList.length; intA++){											if(nodeList[intA].nodeName.indexOf('TR')>-1){												// store it in an array												nodeArray[nodeArray.length] = nodeList[intA];											}										}										// sort the collection using a helper function										nodeArray = (sortDirection=='sortedForward') ? nodeArray.sort(st.forward) : nodeArray.sort(st.reverse);										// clear the unsorted nodelist										for(var intA=0; intA<nodeList.length; intA++){											if(nodeList[intA].nodeName.indexOf('TR')>-1){												sortParent.removeChild(nodeList[intA]);											}										}										// append the sorted nodelist										for(var intA=0; intA<nodeArray.length; intA++){											sortParent.appendChild(nodeArray[intA]);										}										// reapply the zebra effect										classBehaviour.zebraTable.process(fullTable);									}			}			// add this function to the classbehaviour object			classBehaviour.sortByColumn = new SortByColumn;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.sortByColumn;					// Open print dialog			// define this class behaviour			function OpenAsPrintable(){				// properties				this.name 		= 	'openAsPrintable';				// methods				this.start		=	function(node){										node.onclick = this.process;									}				this.process 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// If there is a demo popup										if(document.getElementById('tgtPopTitle')){											// copy the title to the print popup title											document.getElementById('tgtPopTitle').innerHTML = document.getElementById('content').getElementsByTagName('h1')[0].innerHTML;											// copy the content tot the print popup content											document.getElementById('tgtPopText').innerHTML = (document.getElementById('content').innerHTML.indexOf('</h1>')>-1) ? document.getElementById('content').innerHTML.split('</h1>')[1] : document.getElementById('content').innerHTML.split('</H1>')[1];											// show the print popup											classBehaviour.openLayerPopUp.show(document.getElementById('popup0'));											// open the print dialog											setTimeout("window.print();",2048);										}else{											window.print();										}										// cancel the click										return false;									}			}			// add this function to the classbehaviour object			classBehaviour.openAsPrintable = new OpenAsPrintable;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openAsPrintable;					// Close the window (it's cold)			// define this class behaviour			function CloseThisWindow(){				// properties				this.name 		= 	'closeThisWindow';				// methods				this.start		=	function(node){										node.onclick = this.process;									}				this.process 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										window.close();									}			}			// add this function to the classbehaviour object			classBehaviour.closeThisWindow = new CloseThisWindow;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.closeThisWindow;				      // Jump back to the previous page	            // define this class behaviour	            function GoToPrevious(){	                  // properties	                  this.name         =     'goToPrevious';	                  // methods	                  this.start        =     function(node){	                                                      node.onclick = this.process;	                                                }	                  this.process      =     function(that){	                                                      var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;	                                                      // open the print dialog	                                                      window.history.go(-1);	                                                }	            }	            // add this function to the classbehaviour object	            classBehaviour.goToPrevious = new GoToPrevious;	            classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.goToPrevious;					// Fixes the position of an element			// define this class behaviour			function FixedPosition(){				// properties				this.name 		= 	'fixedPosition';				this.nodes 		= 	new Array();				// methods				this.start		=	function(node){										this.nodes[this.nodes.length] = node;										if(document.all){											window.onscroll = this.process;										}else{											node.style.position = 'fixed';										}									}				// events				this.process 	= 	function(){										var fp = classBehaviour.fixedPosition;										// this is only needed in internet explorer										for(var a=0; a<fp.nodes.length; a++){											fp.nodes[a].style.marginTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + 'px';											fp.nodes[a].style.marginLeft = (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft) + 'px';										}									}			}			// add this function to the classbehaviour object			classBehaviour.fixedPosition = new FixedPosition;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.fixedPosition;					// Open links in a popup			// define this class behaviour			function OpenAsPopUp(){				// properties				this.name 		= 	'openAsPopUp';				this.window		=	null;				// methods				this.start		=	function(node){										node.onclick = this.process;									}				// events				this.process 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var oap = classBehaviour.openAsPopUp;										// get the parameters from the classname										var strWidth 		= 'width=' + classBehaviour.utilities.getClassParameter(objNode, 'width', '630');										var strHeight 		= ',height=' + classBehaviour.utilities.getClassParameter(objNode, 'height', '385');										var strLeft			= ',left=' + classBehaviour.utilities.getClassParameter(objNode, 'left', '');										var strTop			= ',top=' + classBehaviour.utilities.getClassParameter(objNode, 'top', '');										var strToolbars 	= ',toolbar=' + classBehaviour.utilities.getClassParameter(objNode, 'toolbar', 'no');										var strScrolling 	= ',scrollbars=' + classBehaviour.utilities.getClassParameter(objNode, 'scrollbars', 'no');										var strStatus 		= ',status=' + classBehaviour.utilities.getClassParameter(objNode, 'status', 'no');										var strResize 		= ',resizable=' + classBehaviour.utilities.getClassParameter(objNode, 'resizable', 'yes');										var strLocation 	= ',location=' + classBehaviour.utilities.getClassParameter(objNode, 'location', 'no');										var strMenu 		= ',menu=' + classBehaviour.utilities.getClassParameter(objNode, 'menu', 'no');										var strName 		= classBehaviour.utilities.getClassParameter(objNode, 'name', 'popup');										// open requested window										oap.window = window.open(objNode.getAttribute('href'), strName, strWidth+strHeight+strScrolling+strToolbars+strStatus+strResize+strLocation+strMenu+strLeft+strTop);										oap.window.focus();										// cancel click										return false;									}			}			// add this function to the classbehaviour object			classBehaviour.openAsPopUp = new OpenAsPopUp;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openAsPopUp;					// Open links in the opener of this window			// define this class behaviour			function OpenInOpener(){				// properties				this.name 		= 	'openInOpener';				// methods				this.start		=	function(node){										node.onclick = this.process;									}				// events				this.process 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// open the href in the opener of this window										window.opener.location.href = objNode.href;										// optionaly close the window										if(classBehaviour.utilities.getClassParameter(objNode, 'closeParent', 'false')=='true') window.close();										// cancel the link										return false;																			}			}			// add this function to the classbehaviour object			classBehaviour.openInOpener = new OpenInOpener;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openInOpener;					// Open links in a new window			// define this class behaviour			function OpenAsWindow(){				// properties				this.name 		= 	'openAsWindow';				// methods				this.start		=	function(node){										node.target = "_blank"									}			}			// add this function to the classbehaviour object			classBehaviour.openAsWindow = new OpenAsWindow;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openAsWindow;					// Chooses a random increment of an image source			// define this class behaviour			function SetRandomSrc(){				// properties				this.name 		= 	'setRandomSrc';				// methods				this.start		=	function(node){										this.process(node);									}				this.process 	= 	function(objNode){										// get min parameter										var intMin = parseInt(classBehaviour.utilities.getClassParameter(objNode, 'min', '0'));										// get max parameter										var intMax = parseInt(classBehaviour.utilities.getClassParameter(objNode, 'max', '1'));										// generate random number										var intRandom = Math.round(Math.random()*(intMax-intMin))+intMin;										// replace default increment by random number										if(objNode.src!=null) objNode.src = objNode.src.replace('_0','_'+intRandom);										objNode.className = objNode.className.replace('_0','_'+intRandom);									}			}			// add this function to the classbehaviour object			classBehaviour.setRandomSrc = new SetRandomSrc;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.setRandomSrc;					// Chooses a random increment of an image source			// define this class behaviour			function SetRandomClassName(){				// properties				this.name 		= 	'setRandomClassName';				// methods				this.start		=	function(node){										this.process(node);									}				this.process 	= 	function(objNode){										// get min parameter										var intMin = parseInt(classBehaviour.utilities.getClassParameter(objNode, 'min', '0'));										// get max parameter										var intMax = parseInt(classBehaviour.utilities.getClassParameter(objNode, 'max', '1'));										// generate random number										var intRandom = Math.round(Math.random()*(intMax-intMin))+intMin;										// replace default increment by random number										if(objNode.className!=null) objNode.className = objNode.className.replace('_0','_'+intRandom);										objNode.className = objNode.className.replace('_0','_'+intRandom);									}			}			// add this function to the classbehaviour object			classBehaviour.setRandomClassName = new SetRandomClassName;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.setRandomClassName;					// Class a link matching the document's url			// define this class behaviour			function MatchActiveUrl(){				// properties				this.name 		= 	'matchActiveUrl';				// methods				this.start		=	function(node){										this.process(node);									}				this.convertAbsToRelUrls 	= 	function(strUrl){													// is the url a relative path													if(strUrl.indexOf('/')<0 || strUrl.substr(0,1)=='.' || strUrl.substr(0,1)=='/'){														// the current absolute path														strAbs = document.location.href;														// remove the filename from the end														strAbs = strAbs.substring(0, strAbs.lastIndexOf('/'));														// while there are parent markers in the url														while(strUrl.indexOf('../')==0){															// remove one level from the absolute path															strUrl = strUrl.replace('../','');															// remove one parent marker from the relative path															strAbs = strAbs.substring(0, strAbs.lastIndexOf('/'));														}														// remove all current dir markers from the relative url														strUrl = strUrl.replace(/\.\//gi,'');														// add the url to the absolute path														strUrl = strAbs + '/' + strUrl;													}													return strUrl;												}				this.compareUrls 	= 	function(strUrlA,strUrlB){											var intCurScore = 0;											var intPotScore = 0;											var intMaxScore = 0;											var intA,intB;											// replace most common illegal characters											strUrlA = strUrlA.replace(/ /gi,"%20");											strUrlB = strUrlB.replace(/ /gi,"%20");											// remove anchors											strUrlA = strUrlA.split('#')[0];											strUrlB = strUrlB.split('#')[0];											// make sure both paths are absolute											strUrlA = this.convertAbsToRelUrls(strUrlA);											strUrlB = this.convertAbsToRelUrls(strUrlB);											// split the urls into manageable strings											var arrUrlA = strUrlA.split(/[?&#\/]/i);											var arrUrlB = strUrlB.split(/[?&#\/]/i);											// for every string of UrlA											for(intA=0; intA<arrUrlA.length; intA++){												// is the string in the substrings of UrlB												intB = 0; while(intB<arrUrlB.length && arrUrlA[intA]!=arrUrlB[intB]) intB += 1;												// if a match was found, add length of string A to current score												if(intB<arrUrlB.length) intCurScore += arrUrlA[intA].length;												// add length of string A to potential score												intPotScore += arrUrlA[intA].length;											}											// calcultate maximum score possible											intMaxScore = strUrlB.length - arrUrlB.length + 1;											// return the compare-score											return intCurScore/intPotScore;										}				this.process 	= 	function(objNode){										var cmh = classBehaviour.classMouseHover;										var smh = classBehaviour.srcMouseHover;										// get parent recursion										var intToParent	= parseInt(classBehaviour.utilities.getClassParameter(objNode, 'toParent', '0'));										// get parent href										var intFromParent = parseInt(classBehaviour.utilities.getClassParameter(objNode, 'fromParent', '0'));										// get the url and clean it up										var strUrl = this.convertAbsToRelUrls(document.location.href);										// get the href and clean it up										var strHref = (intFromParent>0) ? this.convertAbsToRelUrls(objNode.parentNode.getAttribute('href')) : this.convertAbsToRelUrls(objNode.getAttribute('href')) ;										// was the data bad										if(strHref!=null){											// compare score											var ftlCompareScore = this.compareUrls(strUrl, strHref) * this.compareUrls(strHref, strUrl);											// if the href matches the url 											if(ftlCompareScore==1){												// add the active class to the target item												cmh.addActive(objNode);												if(objNode.nodeName=='IMG') smh.addActive(objNode);												// if a parent node also needs to be marked												if(intToParent>0){													// get the relevant parent node													for(var intA=0; intA<intToParent; intA++) objNode = objNode.parentNode;													// if the href matches the url													if(ftlCompareScore==1){														// add the active class to the parent item														cmh.addActive(objNode);													}												}												// report a match												return true;											}										}										// report no match										return false;									}			}			// add this function to the classbehaviour object			classBehaviour.matchActiveUrl = new MatchActiveUrl;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.matchActiveUrl;					// Validate the value of a for element to a predefined regular expression			// define this class behaviour			function ValidateInput(){				// properties				this.name 			= 	'validateInput';				this.summaryId		=	null;
				this.lastFocus		=	null;
				this.customChecks	=	new CustomChecks;				// methods				this.start			=	function(node){											// was a summary requested?											this.summaryId = classBehaviour.utilities.getClassParameter(node, 'summaryId', this.summaryId);											// apply the event to all form-element childnodes											var nodes = (this.isFormElement(node)) ? new Array(node) : node.getElementsByTagName('*');											for(var a=0; a<nodes.length; a++){												if(this.isFormElement(nodes[a])){													// give it the event handler													nodes[a].onfocus = this.clear;													nodes[a].onmousedown = this.clear;													nodes[a].onblur = this.input;													nodes[a].onchange = this.input;													// and the parent's classname													nodes[a].className = node.className;												}											}											// if there's a greyed explanation											hasExplanation = classBehaviour.utilities.getClassParameter(node, 'explanation', 'no');											if(hasExplanation=='yes'){												// remove it if a value is restored by a form manager												setTimeout("classBehaviour.validateInput.restore('"+node.id+"','"+node.value+"')", 1000);											}										}				this.warning 		=	function(objNode, status){											var vi = classBehaviour.validateInput;
											// Show the input warning if this is a suitable form element
											if(objNode.className.indexOf('noWarning')<0)
												objNode.className = (status) ? objNode.className.replace(' validationWarning', '') : objNode.className + ' validationWarning' ;											// for all inputs with the same name											allWithSameName = document.getElementsByName(objNode.name);											for(var b=0; b<allWithSameName.length; b++){												objNode = allWithSameName[b];											// Show the foldout warning												// is the warning node named?												idWarningNode		= classBehaviour.utilities.getClassParameter(objNode, 'warningId', null);												// check if the next node is for summaries
												nextNode 			= classBehaviour.utilities.nextNode(objNode);												// if there's an id given for thewarning message use it. Otherwise use the next node												objWarningNode		= (idWarningNode) ? document.getElementById(idWarningNode) : nextNode ;												// show or hide the warning, if the warning node was found												if(objWarningNode)
													if(objWarningNode.className.indexOf('validationWarning')>-1)
														objWarningNode.style.display = (status) ? 'none' : 'block' ;											// Highlight the label												// get all labels												allLabels = document.getElementsByTagName('label');												// for all labels												for(var a=0; a<allLabels.length; a++){													// if the label matches this input													if(allLabels[a].getAttributeNode('for').nodeValue == objNode.id){														// add or remove the warning colour														if(allLabels[a].parentNode.className.indexOf('noWarning')<0 && allLabels[a].className.indexOf('noWarning')<0) 
															allLabels[a].className = (status) ? allLabels[a].className.replace(' validationWarning', '') : allLabels[a].className + ' validationWarning' ;													}												}											}										}				this.restore 		=	function(id, value){											var objNode = document.getElementById(id);											// if this input has a value which doesn't match the current value, a form manager has restored a value											if(objNode.value!=value){												objNode.className = objNode.className.replace('explanation_yes','explanation_no');											}										}				this.isFormElement	=	function(objNode){											return (objNode.nodeName=='INPUT' || objNode.nodeName=='SELECT' || objNode.nodeName=='TEXTAREA' || objNode.nodeName=='BUTTON');										}
				this.summary 		= 	function(objNode){
											var vi = classBehaviour.validateInput;
											// find the root of the form
											rootNode = classBehaviour.utilities.rootNode(objNode, null, null, 'validateAllInput');
											// is a summary required
											vi.summaryId = classBehaviour.utilities.getClassParameter(rootNode, 'summaryId', null);											if(vi.summaryId){												summaryObj = document.getElementById(vi.summaryId);												summaryTxt = '';												// for all nodes
												var objSubNodes = rootNode.getElementsByTagName("*");												for(var a=0; a<objSubNodes.length; a++){													// if this node a visible warning													if(objSubNodes[a].className.indexOf('validationWarning')>-1 && objSubNodes[a].style.display=='block'){														// copy it's contents to the summary text														summaryTxt += '<li>' + objSubNodes[a].innerHTML + '</li>';													}												}												// add the summary text to the summary
												summaryObj.style.display = (summaryTxt.length>0) ? 'block' : 'none' ;												summaryObj.innerHTML = (summaryTxt.length>0) ? '<ul>' + summaryTxt + '</ul>' : '' ;											}
										}
				this.ajaxWait		=	function(submitProgress, submitReferer, submitError){
											// inform the user on the progress in the reply area
											submitReferer.innerHTML = (submitProgress<0) ? 'error: ' + submitError : 'sending: ' + Math.round(submitProgress*100) + '%' ;
										}
				this.ajaxReply		=	function(replyObj, replyReferer, replyText){
											// strip and write the reply to the form reply area
											replyReferer.innerHTML = (replyText.indexOf('</body>')>-1) ? replyText.split('<body>')[1].split('</body>')[0] : replyText.split('<root>')[1].split('</root>')[0] ;
											// activate any classbehaviours
											classBehaviour.parser.parseNode(replyReferer);
										}
				// events
				this.clear	=	function(objNode){									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var vi = classBehaviour.validateInput;
									// remember the focus point
									vi.lastFocus = objNode;									// if there was an explanation provides as a value									hasExplanation = classBehaviour.utilities.getClassParameter(objNode, 'explanation', 'no');									if(hasExplanation=='yes'){										// clear the value										objNode.value = '';										// che change the class back to normal										objNode.className = objNode.className.replace('explanation_yes', 'explanation_no');									}								}
				this.all 	= 	function(that){									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;									var vi = classBehaviour.validateInput;									var booPassed = true;
									// if there was a focus point stored use it
									if(vi.lastFocus!=null) objNode = vi.lastFocus;
									// find the form's root
									if(objNode!=null) rootNode = classBehaviour.utilities.rootNode(objNode, null, null, 'validateAllInput');									// get all subnodes in the form
									var objSubNodes = rootNode.getElementsByTagName("*");									// for all nodes
									var queryString = '';									for(var intA=0; intA<objSubNodes.length; intA++){										// Does this node have the validateInput put class? Invoke the validator function upon it.										if(objSubNodes[intA].className.toLowerCase().indexOf('validateinput')>-1 && vi.isFormElement(objSubNodes[intA])) 
											booPassed = (vi.input(objSubNodes[intA], false) && booPassed);
										// Note the name and value
										if(objSubNodes[intA].nodeName=='INPUT' || objSubNodes[intA].nodeName=='SELECT' || objSubNodes[intA].nodeName=='TEXTAREA')
											queryString += (objSubNodes[intA].checked || (objSubNodes[intA].type!='radio' && objSubNodes[intA].type!='checkbox')) ? objSubNodes[intA].name + '=' + objSubNodes[intA].value + '&' : '' ;									}
									// if an ajax submit is required
									replyId = classBehaviour.utilities.getClassParameter(rootNode, 'ajaxReplyId', null);
									submitId = classBehaviour.utilities.getClassParameter(rootNode, 'ajaxReplyUrl', null);
									if(replyId!=null && submitId!=null && booPassed){
										// get the submitted properties
										replyTarget = document.getElementById(replyId);
										submitUrl = (document.getElementById(submitId).nodeName=='FORM') ? document.getElementById(submitId).getAttribute('action') : document.getElementById(submitId).getAttribute('value') ;
										// submit the form using ajax
										classBehaviour.ajax.addRequest(submitUrl + '?' + queryString, vi.ajaxReply, vi.ajaxWait, null, replyTarget);
										// cancel the actual submit
										return false;
									// else
									}else{										// let the form submit or not										return booPassed;
									}								}				this.input = 	function(that, override){									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;									var vi = classBehaviour.validateInput;									// default validator values									var booEmptyValidator, booValueValidator;									// get the type of validation required									strValidatorName	= classBehaviour.utilities.getClassParameter(objNode, 'type', '');									allowEmpty			= classBehaviour.utilities.getClassParameter(objNode, 'allowEmpty', 'no');									ifCheckedId			= classBehaviour.utilities.getClassParameter(objNode, 'ifCheckedId', null);									hasExplanation 		= classBehaviour.utilities.getClassParameter(objNode, 'explanation', 'no');									// check a special dependency on a parent checkbox									if(ifCheckedId){										if(!document.getElementById(ifCheckedId).checked) allowEmpty = 'yes';									}									// VALIDATION TESTS									// empty test	objNode.value!=''									booEmptyValidator = (allowEmpty=='yes' && (objNode.value=='' || hasExplanation=='yes'));									// bizarre exception for MSIE 5.0									if(navigator.appVersion.indexOf('MSIE 5.0')>-1 && strValidatorName=='money') strValidatorName = null;									// test expressions									switch(strValidatorName){										// regular expression tests										case 'email' : 											booValueValidator = (objNode.value.match(/^[\w\.\-\,\+]+@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/)!=null);											break;										case 'phone' : 											booValueValidator = (objNode.value.match(/(^\+[0-9]{2}|^\+[0-9]{2}\(0\)|^\(\+[0-9]{2}\)\(0\)|^00[0-9]{2}|^0)([0-9]{9}$|[0-9\-\s]{10}$)/)!=null); 											break;										case 'dutchzipcode' : 											booValueValidator = (objNode.value.match(/^[0-9]{4}\s{0,1}[a-zA-Z]{2}$/)!=null); 											break;										case 'date' : 											booValueValidator = (objNode.value.match(/^\d{4}\-\d{1,2}\-\d{1,2}$/)!=null);											// booRegExpValidator = (objNode.value.match(/^\d{1,2}\-\d{1,2}\-(\d{2}|\d{4})$/)!=null); 											break;										case 'number' : 											booValueValidator = (objNode.value.match(/^[0-9]+$/)!=null); 											break;										case 'money' :											booValueValidator = (objNode.value.match(/^[0-9]+(\.[0-9]{1,2})?$/)!=null); 											break;										case 'alphanumeric' :											booValueValidator = (objNode.value.match(/^[a-zA-Z0-9]/)!=null);											break;										// custom tests										case 'bankaccount' :											booValueValidator = vi.customChecks.bankAccount(objNode);											break;										case 'isradiochecked' :											booValueValidator = vi.customChecks.isRadioChecked(objNode);											break;										case 'anyofthesechecked' : 											booValueValidator = vi.customChecks.anyOfTheseChecked(objNode);											break;										case 'text' :											booValueValidator = (objNode.value!="");											break;
										case 'regexp' : 
											customRegId = classBehaviour.utilities.getClassParameter(objNode,'regxid','myRegExp');
											customRegString = document.getElementById(customRegId).value;
											customRegExp = new RegExp(customRegString);											booValueValidator = (objNode.value.match(customRegExp)!=null);											break;										default :											booValueValidator = true;									}									// does the input validate when the field is not empty or not allowed to be empty									validates = (!booEmptyValidator) ? (booValueValidator && hasExplanation=='no') : true ;									// show or hide the warning message based on the validator's match									vi.warning(objNode, validates);
									// is a summary required?
									vi.summary(objNode);									// return a pass of fail boolean to whoever may want to know the results of the test									return (override!=null) ? validates : override;								}			}
				function CustomChecks(){
					this.bankAccount 		= 	function(objNode){													var intDeel, intRest;													var strInput = objNode.value;													var intTot=0;													if (strInput.length!=9){														return false;													}else{														for (i=0; i<strInput.length; i++) intTot += strInput.substr(i,1) * (9 - i);														intDeel = intTot/11;														intRest = intTot%11;														return (intRest==0);													}												}					this.isRadioChecked	=	function(objNode){													// get all inputs with this name													allInputs = document.getElementsByTagName('input');													// for all inputs													for(var a=0; a<allInputs.length; a++){														// If the input has the same name. 														if(allInputs[a].name == objNode.name){															// If the input is checked set the validator to true															if(allInputs[a].checked) return true;														}													}													return false;												}					this.anyOfTheseChecked	=	function(objNode){														// default validatie														anyChecked = false;														// get all inputs from the parentnode														allChecks = objNode.parentNode.parentNode.getElementsByTagName('input');														// for all inputs														for(var a=0; a<allChecks.length; a++){															// if this checkbox is checked remember is															if(allChecks[a].checked) anyChecked = true;														}														return anyChecked;													}
				}			// add this function to the classbehaviour object			classBehaviour.validateInput = new ValidateInput;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.validateInput;
			// Triggers all validateInput class behaviours within a node after the onsubmit event.',			// define this class behaviour			function ValidateAllInput(){				// properties				this.name 		= 	'validateAllInput';				// methods				this.start		=	function(node){
										// find the form
										formNode = classBehaviour.utilities.rootNode(node, 'FORM', null, null);										// set the form validation eventhandler										formNode.onsubmit = classBehaviour.validateInput.all;									}			}			// add this function to the classbehaviour object			classBehaviour.validateAllInput = new ValidateAllInput;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.validateAllInput;
							// Disable form elements during a submit, to avoid multiple submits on slow servers			// define this class behaviour			function DisableAfterSubmit(){				// properties				this.name 		= 	'disableAfterSubmit';				// methods				this.start		=	function(node){										node.onsubmit = this.disable;										// get all elements in this form										allNodes = node.getElementsByTagName("*");										// is this a form using microsoft's postbacks										if(typeof(__doPostBack)!='undefined'){											// for all nodes in this form											for(var a=0; a<allNodes.length; a++){												// if this form element has a _dopostback												if(allNodes[a].onchange!=null){													if(allNodes[a].onchange.toString().indexOf('__doPostBack')>-1){														// overrule microsoft's postback event														allNodes[a].onchange = this.disable;													}												}												if(allNodes[a].onclick!=null){													if(allNodes[a].onclick.toString().indexOf('__doPostBack')>-1){														// overrule microsoft's postback event														allNodes[a].onclick = this.disable;													}												}											}										}										// if there's also a validation behaviour defined, trigger it										if(node.className.indexOf('validateAllInput')>-1) classBehaviour.validateAllInput.start(node);									}				// events				this.disable	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// trigger microsoft's postback										if(typeof(__doPostBack)!='undefined') __doPostBack(objNode.id, objNode.value);										// get all elements in this form										allNodes = document.getElementsByTagName("*");										// for all nodes in this form										for(var a=0; a<allNodes.length; a++){											// if this is a form element											if(												allNodes[a].nodeName.indexOf('INPUT')>-1 ||												allNodes[a].nodeName.indexOf('SELECT')>-1 ||												allNodes[a].nodeName.indexOf('TEXTAREA')>-1											){												// disable the form element												allNodes[a].disabled = true;												// deny focus												allNodes[a].onfocus = blur;											}										}									}			}			// add this function to the classbehaviour object			classBehaviour.disableAfterSubmit = new DisableAfterSubmit;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.disableAfterSubmit;					// Manage all event handlers of an imagemap			// define this class behaviour			function ImageMap(){				// properties				this.name 		= 	'imageMap';				this.map		=	new Map;				this.areas		=	new Areas;				// methods				this.start		=	function(node){										// start the storing of the map object										node.onmouseover = this.map.over;										this.map.over(node);										// get all areas in this map										areas = document.getElementById(this.map.name).getElementsByTagName('area');										// for all areas in this map										for(var a=0; a<areas.length; a++){											// cache it's image equivalent											this.cache(node.src.replace(this.map.passive, areas[a].id));											// give the area event handlers											areas[a].onmouseover = this.areas.over;											areas[a].onmouseout = this.areas.out;										}									}				// events				this.cache		= 	function(url) {											var imp = classBehaviour.imageMap;											// preload the image into an array											imp.map.images[imp.map.images.length] = new Image();											imp.map.images[imp.map.images.length-1].src = url;									}			}				function Map(){					// properties					this.object		=	null;					this.name		=	null;					this.passive	=	'default';					this.images		=	new Array();					// methods					this.over		=	function(that){											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;											var imp = classBehaviour.imageMap;											// store the currently active map											imp.map.object = objNode;											imp.map.name = objNode.getAttributeNode('usemap').value.replace('#','');										}				}				function Areas(){					// methods					this.over	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var imp = classBehaviour.imageMap;										// apply the area id to the map's source										imp.map.object.src = imp.map.object.src.replace(imp.map.passive, objNode.id);									}					this.out	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var imp = classBehaviour.imageMap;										// apply the area id to the map's source										imp.map.object.src = imp.map.object.src.replace(objNode.id, imp.map.passive);									}				}						// add this function to the classbehaviour object			classBehaviour.imageMap = new ImageMap;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.imageMap;
			
		// clear a form element filled with a help text			// define this class behaviour			function EmptyOnFocus(){				// properties				this.name 		= 	'emptyOnFocus';				// methods				this.start		=	function(node){										node.onfocus = this.clear;									}				// events				this.clear		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// clear the contents if this is the first time										if(objNode.className.indexOf('wasEmptied')<0){											// clear this field											objNode.value = '';											// mark this input as cleared											objNode.className += ' wasEmptied';										}									}			}			// add this function to the classbehaviour object			classBehaviour.emptyOnFocus = new EmptyOnFocus;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.emptyOnFocus;
	/*					// make a slideshow from a list of images			// define this class behaviour			function SlideshowList(){				// properties				this.name 		= 	'slideshowList';				this.locked	=	false;				// methods				this.start		=	function(node){										// get the next and previous buttons										allButtons = node.getElementsByTagName('button');										// set the event handlers										if(allButtons.length>0) allButtons[allButtons.length-1].onclick = this.next;										if(allButtons.length>1) allButtons[allButtons.length-2].onclick = this.previous;										// set the default states of the slides										allSlides = node.getElementsByTagName('li');										allSlides[0].className += (allSlides[0].className.indexOf('active')<0) ? ' active' : '' ;										for(var a=0; a<allSlides.length; a++) 											allSlides[a].style.display = (allSlides[a].className.indexOf('active')>-1) ? 'block' : 'none' ;									}				// events				this.next		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										if(!classBehaviour.slideshowList.locked){											classBehaviour.slideshowList.locked = true;											// get all slides											allSlides = objNode.parentNode.getElementsByTagName('li');											// default starting position											var activeSlide = allSlides[0];											var nextSlide = allSlides[1];											// look for the active node											for(var a=0; a<allSlides.length; a++){												// if the slide doesn't have an id, make one												allSlides[a].id = (allSlides[a].id) ? allSlides[a].id : 'slide' + a;												// if this slide is marked active												if(allSlides[a].className.indexOf('active')>-1){													// store the active slide													activeSlide = allSlides[a];													// store the next slide													nextSlide = (a<allSlides.length-1) ? allSlides[a+1] : allSlides[0] ;												}											}											// set the display state											activeSlide.style.position = 'absolute';											nextSlide.style.position = 'relative';											// change the classes											activeSlide.className = activeSlide.className.replace(' active','').replace('active','');											nextSlide.className += ' active';											// fade between the active and next slide											classBehaviour.fader.crossFade(nextSlide.id, activeSlide.id, 0, 5, 10, "classBehaviour.slideshowList.unlock()");										}									}				this.previous	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										if(!classBehaviour.slideshowList.locked){											classBehaviour.slideshowList.locked = true;											// get all slides											allSlides = objNode.parentNode.getElementsByTagName('li');											// default starting position											var activeSlide = allSlides[0];											var nextSlide = allSlides[allSlides.length-1];											// look for the active node											for(var a=0; a<allSlides.length; a++){												// if the slide doesn't have an id, make one												allSlides[a].id = (allSlides[a].id) ? allSlides[a].id : 'slide' + a;												// if this slide is marked active												if(allSlides[a].className.indexOf('active')>-1){													// store the active slide													activeSlide = allSlides[a];													// store the next slide													nextSlide = (a>0) ? allSlides[a-1] : allSlides[allSlides.length-1] ;												}											}											// set the display state											activeSlide.style.position = 'absolute';											nextSlide.style.position = 'relative';											// change the classes											activeSlide.className = activeSlide.className.replace(' active','').replace('active','');											nextSlide.className += ' active';											// fade between the active and next slide											classBehaviour.fader.crossFade(nextSlide.id, activeSlide.id, 0, 5, 10, "classBehaviour.slideshowList.unlock()");										}									}				this.unlock	=	function(){										this.locked = false;									}			}			// add this function to the classbehaviour object			classBehaviour.slideshowList = new SlideshowList;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.slideshowList;
	*/
	
		// make a slideshow from a list of images			// define this class behaviour			function SlideshowList(){				/* properties */				this.name 		= 	'slideshowList';				this.locked		=	false;
				this.index		=	0;				/* methods */				this.start		=	function(node){										// get the next and previous buttons										allButtons = node.getElementsByTagName('button');										// set the event handlers										if(allButtons.length>0) allButtons[allButtons.length-1].onclick = this.next;										if(allButtons.length>1) allButtons[allButtons.length-2].onclick = this.previous;
										// update the instance counter of this class
										this.index += 1;										// set the default states of the slides										allSlides = node.getElementsByTagName('li');										allSlides[0].className += (allSlides[0].className.indexOf('active')<0) ? ' active' : '' ;										for(var a=0; a<allSlides.length; a++){
											// if the slide doesn't have an id, make one											allSlides[a].id = (allSlides[a].id) ? allSlides[a].id : 'list' + this.index + 'slide' + a;
											// set the initial display state
											allSlides[a].style.display = (allSlides[a].className.indexOf('active')>-1) ? 'block' : 'none' ;
										}									}				/* events */				this.next		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										if(!classBehaviour.slideshowList.locked){											classBehaviour.slideshowList.locked = true;											// get all slides											allSlides = objNode.parentNode.getElementsByTagName('li');											// default starting position											var activeSlide = allSlides[0];											var nextSlide = allSlides[1];											// look for the active node											for(var a=0; a<allSlides.length; a++){												// if this slide is marked active												if(allSlides[a].className.indexOf('active')>-1){													// store the active slide													activeSlide = allSlides[a];													// store the next slide													nextSlide = (a<allSlides.length-1) ? allSlides[a+1] : allSlides[0] ;												}											}											// set the display state											activeSlide.style.position = 'absolute';											nextSlide.style.position = 'relative';											// change the classes											activeSlide.className = activeSlide.className.replace(' active','').replace('active','');											nextSlide.className += ' active';
											// if the two slides are of the same size
											if(classBehaviour.utilities.getClassParameter(objNode.parentNode, 'sameSize', 'no')=='yes'){
												// fade the next slide over the old one
												classBehaviour.fader.crossFade(nextSlide.id, "", 0, 100, 1, "classBehaviour.slideshowList.unlock()");
												classBehaviour.fader.crossFade("", activeSlide.id, 0, 5, 10, "classBehaviour.slideshowList.unlock()");
											}else{
												// cross-fade between the active and next slide												classBehaviour.fader.crossFade(nextSlide.id, activeSlide.id, 0, 5, 10, "classBehaviour.slideshowList.unlock()");
											}
										}									}				this.previous	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										if(!classBehaviour.slideshowList.locked){											classBehaviour.slideshowList.locked = true;											// get all slides											allSlides = objNode.parentNode.getElementsByTagName('li');											// default starting position											var activeSlide = allSlides[0];											var nextSlide = allSlides[allSlides.length-1];											// look for the active node											for(var a=0; a<allSlides.length; a++){												// if this slide is marked active												if(allSlides[a].className.indexOf('active')>-1){													// store the active slide													activeSlide = allSlides[a];													// store the next slide													nextSlide = (a>0) ? allSlides[a-1] : allSlides[allSlides.length-1] ;												}											}											// set the display state											activeSlide.style.position = 'absolute';											nextSlide.style.position = 'relative';											// change the classes											activeSlide.className = activeSlide.className.replace(' active','').replace('active','');											nextSlide.className += ' active';											// if the two slides are of the same size
											if(classBehaviour.utilities.getClassParameter(objNode.parentNode, 'sameSize', 'no')=='yes'){
												// fade the next slide over the old one
												classBehaviour.fader.crossFade(nextSlide.id, "", 0, 100, 1, "classBehaviour.slideshowList.unlock()");
												classBehaviour.fader.crossFade("", activeSlide.id, 0, 5, 10, "classBehaviour.slideshowList.unlock()");
											}else{
												// cross-fade between the active and next slide												classBehaviour.fader.crossFade(nextSlide.id, activeSlide.id, 0, 5, 10, "classBehaviour.slideshowList.unlock()");
											}										}									}				this.unlock	=	function(){										this.locked = false;									}			}			// add this function to the classbehaviour object			classBehaviour.slideshowList = new SlideshowList;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.slideshowList;
	
		// Enrich a calendar control
			// define this class behaviour
			function DatePicker(){
				// properties
				this.name 		= 	'datePicker';
				this.dateHtml	=	'';
				this.index		=	0;
				// methods
				this.start		=	function(node, nodeId){
										if(node==null) node = document.getElementById(nodeId); 										// give this node an id if it doesn't have one yet
										this.index += 1;										node.id = (node.id) ? node.id : this.name + this.index ;
										node.className += ' toggleNextNode';
										// start the toggle event
										classBehaviour.toggleNextNode.start(node);
										// find the calendar container node
										calendarContainer = classBehaviour.utilities.nextNode(node);
										// import the calendar xml or use the one allready loaded
										if(this.dateHtml==''){
											// report the loading-in-progress of the calender
											this.dateHtml='loading...';
											// find the path to the xml source
											this.dateHtmlSrc = classBehaviour.utilities.nextNode(node).getElementsByTagName('input')[0].value;
											// import it
											classBehaviour.ajax.addRequest(this.dateHtmlSrc, classBehaviour.datePicker.build, null, null, calendarContainer);
										}else if(this.dateHtml=='loading...'){
											// wait until the loading of the html is finished
											setTimeout('classBehaviour.datePicker.start(null, "' + node.id + '")', 512);
										}else{
											// continue, using the cached html
											this.build(null, calendarContainer, this.dateHtml);
										}
										// set the event handlers for this node
										node.onclick = this.open;
									}
				this.set		=	function(calendarNode, date){
										dpr = classBehaviour.datePicker;
										// get the next and previous buttons
										calendarNode.getElementsByTagName('button')[0].onclick = dpr.previous;
										calendarNode.getElementsByTagName('button')[1].onclick = dpr.next;
										// set the month dropdown
										monthNode = calendarNode.getElementsByTagName('select')[0];
										monthNode.selectedIndex = date.getMonth();
										monthNode.onchange = dpr.update;
										// set the year dropdown
										yearSelect = calendarNode.getElementsByTagName('select')[1];
										yearOptions = yearSelect.getElementsByTagName('option');
										currentYear = date.getFullYear();
										if(yearOptions.length==1){
											yearOption = yearOptions[0].cloneNode(true);
											for(var a=currentYear-100; a<currentYear+10; a++ ){
												yearOption = yearSelect.getElementsByTagName('option')[0].cloneNode(true);
												yearOption.value = a;
												yearOption.selected = (a==currentYear) ? 'selected' : '' ;
												yearOption.text = a;
												yearSelect.appendChild(yearOption);
											}
											yearSelect.removeChild(yearSelect.getElementsByTagName('option')[0]);
											yearSelect.onchange = dpr.update;
										}else{
											for(var a=0; a<yearOptions.length; a++) yearOptions[a].selected = (yearOptions[a].value==currentYear) ? 'selected' : '' ;
										}
										// clear out the previous month
										daySlots = calendarNode.getElementsByTagName('td');
										for(var a=0; a<daySlots.length; a++){
											daySlots[a].className = "empty";
											daySlots[a].innerHTML = "";
											daySlots[a].onclick = null;
										}
										// fill the new month
										currentDay = new Date(date.getFullYear(), date.getMonth(), 0);
										nextDay = new Date(date.getFullYear(), date.getMonth(), 1);
										startWeekDay = currentDay.getDay();
										do{
											// next date
											currentDay = new Date(currentDay.getFullYear(), currentDay.getMonth(), currentDay.getDate()+1);
											nextDay = new Date(nextDay.getFullYear(), nextDay.getMonth(), nextDay.getDate()+1);
											// put the date on the weekday cell
											daySlots[currentDay.getDate()+startWeekDay].innerHTML = currentDay.getDate();
											daySlots[currentDay.getDate()+startWeekDay].className = "";
											daySlots[currentDay.getDate()+startWeekDay].onclick = dpr.pick;
										}while(currentDay.getDate() < nextDay.getDate())
									}
				this.build		=	function(xmlDoc, calendarContainer, txtDoc){
										// store the html
										classBehaviour.datePicker.dateHtml = txtDoc;
										// clean the imported xhtml
										calendarContainer.innerHTML = txtDoc.replace('<?xml version="1.0"?>', '').replace('<root>', '').replace('</root>', '');
										// apply the events
										classBehaviour.parser.parseNode(calendarContainer);
									}
				// events
				this.open		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var dpr = classBehaviour.datePicker;
										// close all other calendars
										dpr.close();
										// OBJECTS
										calendar = classBehaviour.utilities.nextNode(objNode);
										// STARTING DATE
										// get the input from the field
										// turn it into a date
										// if the result is a date
											// use it as a start date
										// else
											// take the current date
											theDate = new Date();
										// CONSTRUCT THE CALENDAR AT THE GIVEN DATE
										dpr.set(calendar, theDate);
										// POSITION THE CALENDAR
										// get the position
										screenXpos = (typeof(event)!='undefined') ? event.x : that.layerX;
										screenYpos = (typeof(event)!='undefined') ? event.y : that.layerY;
										// if the position is too close to the edge
										calendarWidth = calendar.firstChild.offsetWidth;
										screenWidth = (window.innerWidth) ? window.innerWidth : document.documentElement.clientWidth ;
										scrolledWidth = (typeof(document.documentElement.scrollLeft)!='undefined') ? document.documentElement.scrollLeft : window.pageXOffset ;
										if(screenXpos+calendarWidth > screenWidth+window.pageXOffset) screenXpos -= calendarWidth;
										// if the position is too close to the bottom
										calendarHeight = calendar.firstChild.offsetHeight;
										screenHeight = (window.innerHeight) ? window.innerHeight : document.documentElement.clientHeight ;
										scrolledHeight = (typeof(document.documentElement.scrollTop)!='undefined') ? document.documentElement.scrollTop : window.pageYOffset ;
										if(screenYpos+calendarHeight+10 > screenHeight+scrolledHeight) screenYpos -= calendarHeight;
										// set the position
										calendar.style.left = screenXpos + 'px';
										calendar.style.top = screenYpos + 'px';
										// SHOW THE CALENDAR
										classBehaviour.toggleNextNode.toggle(objNode);
										// prepare to close the calendar
										calendar.onmouseover = dpr.cancel;
										calendar.onmouseout	= dpr.wait;
										return false;
									}
				this.wait		=	function(){
										closeCalendarTimeout = setTimeout('classBehaviour.datePicker.close()',1024);
									}
				this.cancel		=	function(){
										if(typeof(closeCalendarTimeout)!='undefined') clearTimeout(closeCalendarTimeout);
									}
				this.close		=	function(){
										// get all buttons that might have open calendars
										allButtons = document.getElementsByTagName('button');
										for(var a=0; a<allButtons.length; a++){
											if(allButtons[a].className.indexOf('datePicker')>-1) 
												if(classBehaviour.utilities.nextNode(allButtons[a]).className.indexOf('showThisNode')>-1)
													classBehaviour.toggleNextNode.toggle(allButtons[a]);
										}
									}
				this.update		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var dpr = classBehaviour.datePicker;
										// get both selectors from the parent node
										selectors = objNode.parentNode.getElementsByTagName('select');
										// get the month
										month = parseInt(selectors[0].value);
										// get the year
										year = parseInt(selectors[1].value);
										// make a date out of it
										theDate = new Date(year, month, 1);
										// update the calendar
										dpr.set(objNode.parentNode.parentNode.parentNode.parentNode,theDate);
									}
				this.next		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var dpr = classBehaviour.datePicker;
										// get the calendar
										calendar = objNode.parentNode.parentNode.parentNode.parentNode;
										// get the displayed date
										month = parseInt(objNode.parentNode.parentNode.parentNode.getElementsByTagName('select')[0].value);
										year = parseInt(objNode.parentNode.parentNode.parentNode.getElementsByTagName('select')[1].value);
										// add a month
										theDate = new Date(year,month+1,1);
										// build the calendar
										dpr.set(calendar, theDate);
										return false;
									}
				this.previous	=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var dpr = classBehaviour.datePicker;
										// get the calendar
										calendar = objNode.parentNode.parentNode.parentNode.parentNode;
										// get the displayed date
										month = parseInt(objNode.parentNode.parentNode.parentNode.getElementsByTagName('select')[0].value);
										year = parseInt(objNode.parentNode.parentNode.parentNode.getElementsByTagName('select')[1].value);
										// subsctract a month
										theDate = new Date(year,month-1,1);
										// build the calendar
										dpr.set(calendar,theDate);
										return false;
									}
				this.pick		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// get the selected day
										dayValue = objNode.innerHTML;
										// get the selected month
										calendarTitle = objNode.parentNode.parentNode.parentNode.getElementsByTagName('caption')[0];
										month = calendarTitle.getElementsByTagName('select')[0];
											// monthValue = month[month.selectedIndex].innerHTML;
										monthValue = parseInt(month.value) + 1;
										// get the selected year
										year = calendarTitle.getElementsByTagName('select')[1];
										yearValue = year[year.selectedIndex].innerHTML;
										// put it in the input field
										targetFields = objNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByTagName('input');
										targetFields[0].value = ((dayValue+'').length==1) ? '0' + dayValue  : dayValue;
										targetFields[1].value = ((monthValue+'').length==1) ? '0' + monthValue : monthValue;
										targetFields[2].value = yearValue;
										// close the calendar
										calendarButton = objNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByTagName('button')[0];
										classBehaviour.toggleNextNode.toggle(calendarButton);
									}
			}
			// add this function to the classbehaviour object
			classBehaviour.datePicker = new DatePicker;
			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.datePicker;
					// Center landscape or portrait thumbnails in a defined area			// define this class behaviour			function CenteredThumbnails(){				// properties				this.name 		= 	'centeredThumbnails';
				this.index		=	0;				// methods				this.start		=	function(node){
										// count the instance
										this.index += 1;
										// give this node an id if it doesn't have one
										if(node.id != null) node.id = this.name + this.index;
										// center the thumbnail in a short while										setTimeout('classBehaviour.centeredThumbnails.process("'+node.id+'")', 10);									}
				this.process	=	function(nodeId){
										// get the node
										node = document.getElementById(nodeId);
										// get all links in this container										allLinks = node.getElementsByTagName('a');										// if this is a single item										if(allLinks.length==0) allLinks = new Array(node);										// for all containers										for(var a=0; a<allLinks.length; a++){											// get the dimensions of the container											containerSize = new Array(allLinks[a].offsetWidth, allLinks[a].offsetHeight);											// get the thumbnail											thumbnail = allLinks[a].getElementsByTagName('img')[0];											// get the dimensions of the thumbnail											thumbnailSize = new Array(thumbnail.offsetWidth, thumbnail.offsetHeight);											// set the position of the thumbnail											offsetX = (containerSize[0] - thumbnailSize[0])/2;											offsetY = (containerSize[1] - thumbnailSize[1])/2;											thumbnail.style.margin = offsetY + "px " + offsetX + "px " + offsetY + "px " + offsetX + "px";										}
									}			}			// add this function to the classbehaviour object			classBehaviour.centeredThumbnails = new CenteredThumbnails;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.centeredThumbnails;					// hover the next node near the mouse pointer			// define this class behaviour			function HoverNextNode(){				// properties				this.name 		= 	'hoverNextNode';				// methods				this.start		=	function(node){										// mouse handlers										node.onmouseover = this.show;										node.onmouseout = this.hide;										node.onmousemove = this.place;									}				// events				this.show		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										targetNode = classBehaviour.utilities.nextNode(objNode);										targetNode.style.visibility = 'visible';									}				this.hide		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										targetNode = classBehaviour.utilities.nextNode(objNode);										targetNode.style.visibility = 'hidden';									}				this.place		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										targetNode = classBehaviour.utilities.nextNode(objNode);										targetNode.style.position = 'absolute';										targetNode.style.left = (typeof(that)!='undefined') ? (that.layerX) + 'px' : (event.x) + 'px' ;										targetNode.style.top = (typeof(that)!='undefined') ? (that.layerY) + 'px' : (event.y) + 'px' ;									}			}			// add this function to the classbehaviour object			classBehaviour.hoverNextNode = new HoverNextNode;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.hoverNextNode;					// Use SwfObject to replace a title with a flash version			// hide the alternative beforehand			document.writeln("<style>.flashTitle .flashAlternative{visibility : hidden;}</style>");			// define this class behaviour			function FlashTitle(){				// properties				this.name 			= 	'flashTitle';				this.index			=	0;
				this.cachedXml		=	'';				// methods				this.start			=	function(node){											// give the node an id of it doesn't have one											if(!node.id){												node.id = this.name + this.index;												this.index += 1;											}
											// check if there is flash
											requiredVersion = parseInt(classBehaviour.utilities.getClassParameter(node, 'version', '7'));
											if(this.checkForFlash(requiredVersion)){
												// load the source file
												if(this.cachedXml=='') this.loadXml(node)
												else if(this.cachedXml=='loading...') this.retryLater(node)
												else this.processXml(null, node, this.cachedXml);
											}else{
												// make the alternative content visible, just in case it didn't work
												classBehaviour.flashTitle.showAlt(node);
											}										}
				this.checkForFlash	=	function(requiredVersion){
											// check if Adobe's flash checking script is available
											return (typeof(DetectFlashVer)!='undefined') ? DetectFlashVer(requiredVersion, 0, 0) : true ;
										}
				this.loadXml		=	function(node){
											classBehaviour.flashTitle.cachedXml = 'loading...';
											// load the xml file
											loadUrl = node.getElementsByTagName('input')[0].value;
											classBehaviour.ajax.addRequest(loadUrl, this.processXml, this.loadProgress, null, node);
										}
				this.retryLater		=	function(node){
											// wait while loading
											setTimeout('classBehaviour.flashTitle.start(document.getElementById("' + node.id + '"))', 100);
										}
				this.loadProgress	=	function(progress, referer){
											// if loading fails show the alternative
											if(progress<0) classBehaviour.flashTitle.showAlt(referer);
										}				this.processXml		=	function(sourceDoc, node, sourceText){
											// store the xml for re-use
											classBehaviour.flashTitle.cachedXml = sourceText;
											// set the default values for all parameters											flashMovie		= "../flash/flashTitle.swf";											flashWidth		= node.offsetWidth;											flashHeight		= node.offsetHeight;											flashWmode		= "Transparent";											flashScale		= "noScale";											flashSalign		= "l";											flashName		= "_" + node.id;											flashVariables	= "inputText=" + node.innerHTML.replace(/<(.|\n)*?>/gi,"").replace(/^\s+/gi,"").replace(/&amp;/gi,"&");											// for all childnodes of node which may contain configuration variables
											allInputs = node.getElementsByTagName('input');											for(var a=0; a<allInputs.length; a++){
												switch(allInputs[a].name){
													case 'movie' 			: flashMovie = allInputs[a].value; break;													case 'width' 			: flashWidth = allInputs[a].value; break;													case 'height' 			: flashHeight = allInputs[a].value; break;													case 'wmode' 			: flashWmode = allInputs[a].value; break;													case 'scale' 			: flashScale = allInputs[a].value; break;													case 'salign' 			: flashSalign = allInputs[a].value; break;													case 'name' 			: flashName = allInputs[a].value; break;													case 'flashvars' 		: flashVariables += '&' + allInputs[a].value; break;													default 				: break;												}											}											// if the dimensions are in %, be sure to tell the container											if(flashWidth.toString().indexOf('%')>-1) node.style.width = flashWidth;											if(flashHeight.toString().indexOf('%')>-1) node.style.height = flashHeight;											// load the flash plugin
											sourceText = sourceText.replace('<?xml version="1.0"?>', '');
											sourceText = sourceText.replace(/{movie}/gi, flashMovie);
											sourceText = sourceText.replace(/{width}/gi, flashWidth);
											sourceText = sourceText.replace(/{height}/gi, flashHeight);
											sourceText = sourceText.replace(/{wmode}/gi, flashWmode);
											sourceText = sourceText.replace(/{scale}/gi, flashScale);
											sourceText = sourceText.replace(/{salign}/gi, flashSalign);
											sourceText = sourceText.replace(/{name}/gi, flashName);
											sourceText = sourceText.replace(/{flashvars}/gi, flashVariables);
											node.innerHTML = sourceText;										}
				this.setFlashVar	=	function(nodeId, varName, varValue){
											// find the proper buried ID
											node = 	(document.getElementById('__'+nodeId)) ? 
														document.getElementById('__'+nodeId) : 
															(document.getElementById('_'+nodeId)) ? 
																document.getElementById('_'+nodeId) : 
																	document.getElementById(nodeId) ;
											// send the parameter to the flash object
											if(typeof(node.SetVariable)!='undefined') node.SetVariable(varName, varValue);
										}				// events
				this.showAlt		=	function(node){
											allContents = node.getElementsByTagName('*');
											if(allContents.length>0) 
												for(var a=0; a<allContents.length; a++) 
													if(allContents[a].className.indexOf('flashAlternative')>-1) 
														allContents[a].style.visibility = 'visible';
										}			}			// add this function to the classbehaviour object			classBehaviour.flashTitle = new FlashTitle;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.flashTitle;
					// Update a slide based on clicks on thumbnails			// define this class behaviour			function ThumbnailToPhoto(){				// properties				this.name 		= 	'thumbnailToPhoto';
				this.thumbnails	=	new Array();
				this.stackTop	=	1;				// methods				this.start		=	function(node){
										// add the thumbnail to the index
										this.thumbnails[this.thumbnails.length] = node;										// set the click event
										node.onclick = this.loadPhoto;									}				// events				this.loadPhoto	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var ttp = classBehaviour.thumbnailToPhoto;
										// if this is not an active thumbnail
										if(objNode.className.indexOf('active')<0){
											// get the target of this thumbnail
											targetId = classBehaviour.utilities.getClassParameter(objNode, 'id', 'thumbnailTarget');
											// for all thumbnails
											allThumbnails = ttp.thumbnails;
											for(var a=0; a<allThumbnails.length; a++){
												// deactivate the thumbnails with the same target
												thumbnailTargetId = classBehaviour.utilities.getClassParameter(allThumbnails[a], 'id', 'thumbnailTarget')
												if(thumbnailTargetId==targetId) allThumbnails[a].className = allThumbnails[a].className.replace(' active','');
											}
											// activate this thumbnail
											objNode.className += ' active';
											// find the image in the existing target stack
											targetStack = document.getElementById(targetId);
											targetImages = targetStack.getElementsByTagName('img');
											targetImage = null;
											for(var a=0; a<targetImages.length; a++) if(targetImages[a].src==objNode.href) targetImage = targetImages[a];
											// if the image isn't in the stack allready
											if(targetImage==null){
												// create a new image
												clonedImage = targetImages[0].cloneNode(true);
												// place it at the bottom of the stack
												targetStack.insertBefore(clonedImage, targetStack.firstChild);
												// set the properties of the new image
												clonedImage = classBehaviour.utilities.previousNode(targetImages[0]);
												clonedImage.id = null;
												clonedImage.onload = ttp.showPhoto;
												clonedImage.src = objNode.href;
												clonedImage.title = objNode.getElementsByTagName('img')[0].title;
												clonedImage.alt = objNode.getElementsByTagName('img')[0].alt;
											// else
											}else{
												// if this isn't the same slide as the last one, skip to the show function
												ttp.showPhoto(targetImage);
											}
										}
										// cancel the click										return false;									}
				this.showPhoto	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var ttp = classBehaviour.thumbnailToPhoto;
										// fade it out
										classBehaviour.fader.setFade(objNode, 0);
										// put it at the top of the stack
										ttp.stackTop += 1;
										objNode.style.zIndex = ttp.stackTop;
										// fade it in
										objNode.id = (objNode.id==null) ? objNode.id : ttp.name + ttp.stackTop ;
										classBehaviour.fader.fadeIn(objNode.id, 10, 50, null);									}			}			// add this function to the classbehaviour object			classBehaviour.thumbnailToPhoto = new ThumbnailToPhoto;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.thumbnailToPhoto;
					// Turn an element into an HTML-editor
			// define this class behaviour
			function RichTextEditor(){
				// properties
				this.name 			= 	'richTextEditor';
				this.containerType	=	'FIELDSET';
				this.buttonType		=	'BUTTON';
				this.stylesheet		=	'';
				this.editorHtml		=	'';
				this.index			=	0;
				this.instances		= 	new Array();
				this.interval		=	null;
				this.resizing		=	false;
				this.bookmark		=	null;
				// methods
				this.start			=	function(node){ 											// give this node an id if it doesn't have one yet
											if(node.id==null){
												this.index += 1;												node.id = this.name + this.index ;
											}
											// import the editor if it has not been preloaded
											if(this.editorHtml==''){
												this.editorHtml = 'loading...';
												pathNode = node.getElementsByTagName('INPUT')[0];
												classBehaviour.ajax.addRequest(pathNode.value, this.importXml, this.awaitXml, null, node);
											// if another instance of the editor is loading
											}else if(this.editorHtml=='loading...'){
												setTimeout('classBehaviour.richTextEditor.start(document.getElementById("'+node.id+'"))', 512);
											// if the editor is allready there
											}else{
												classBehaviour.richTextEditor.process(node);
											}
										}
				this.awaitXml		=	function(loadStatus, rootNode){
											// debug(loadStatus);
										}
				this.importXml		=	function(toolsXml, rootNode, toolsText){
											var edc = classBehaviour.richTextEditor;
											// extract the html from the imported xml
											edc.stylesheet = toolsText.split('<stylesheet>')[1].split('</stylesheet>')[0];
											edc.editorHtml = toolsText.split('<editorHtml>')[1].split('</editorHtml>')[0];
											// process the nodes
											edc.process(rootNode);
										}
				this.process		=	function(rootNode){
											var edc = classBehaviour.richTextEditor;
											// insert the editor html before the textarea
											rootNode.innerHTML = edc.editorHtml + rootNode.innerHTML;
											// prepare the editor
											edc.setCanvas(rootNode);
											edc.setControls(rootNode);
											// add this editor to the instances of editors
											edc.instances[edc.instances.length] = rootNode;
											// sync loop between the textarea and the iframe
											clearInterval(edc.interval);
											edc.interval = setInterval("classBehaviour.richTextEditor.sync()", 256);
										}
				this.setCanvas		=	function(rootNode){
											var edc = classBehaviour.richTextEditor;
											// store the container type
											this.containerType = rootNode.nodeName;
											// hide the textarea
											textArea = rootNode.getElementsByTagName('TEXTAREA')[0];
											textArea.id = (textArea.id) ? textArea.id : edc.name + 'Textarea' + this.index;
											textArea.style.display = 'none';
											// show the iframe
											iframe = rootNode.getElementsByTagName('IFRAME')[0];
											iframe.id = (iframe.id) ? iframe.id : edc.name + 'Iframe' + this.index;
											iframe.style.display = 'block';
											// transform the iframe into an editor
											editor = edc.getEditor(iframe.id);
											editor.designMode = 'on';
											// set the initial content
											editor.open();
											editor.write(textArea.value + this.stylesheet);
											editor.close();
											// store the selection when the mouse lifts
											if(editor.selection) editor.onmouseup = this.storeSelect;
										}
				this.setControls	=	function(rootNode){
											// if there's no button bars yet
											toolBars = rootNode.getElementsByTagName('UL');
											if(toolBars.length==2){
												// HTML BUTTON BAR
												// apply the classbehaviours of the button bar
												classBehaviour.parser.parseNode(toolBars[0]);
												// get the buttons
												buttons = toolBars[0].getElementsByTagName('*');
												// for each button in the button bar
												for(var a=0; a<buttons.length; a++){
													// set the event handlers for the edit buttons
													if(buttons[a].className.indexOf('cmd_')>-1){
														if(buttons[a].nodeName=='SELECT') buttons[a].onchange = this.editCommand;
														if(buttons[a].nodeName=='BUTTON') buttons[a].onclick = this.editCommand;
													}
												}
												// show the button bar
												toolBars[0].style.display = 'block';
												
												// TEXT BUTTON BAR
												// apply the classbehaviours of the button bar
												classBehaviour.parser.parseNode(toolBars[1]);
												// get the buttons
												buttons = toolBars[1].getElementsByTagName(this.buttonType);
												// for each button in the button bar and set the event handlers for the edit buttons
												for(var a=0; a<buttons.length; a++)
													if(buttons[a].nodeName=='BUTTON') if(buttons[a].className.indexOf('cmd_')>-1) buttons[a].onclick = this.editCommand;
												// hide the button bar
												toolBars[1].style.display = 'none';
											}
										}
				this.getEditor		=	function(id){
											return (document.getElementById(id).contentDocument) ? 
														document.getElementById(id).contentDocument : 
															document.frames[id].document ;
										}
				this.sync			=	function(){
											var edc = classBehaviour.richTextEditor;
											// for all instances of this class
											for(var a=0; a<edc.instances.length; a++){
												// get the iframe that may be associated with the editor
												allIframes = edc.instances[a].getElementsByTagName('iframe');
												allTextareas = edc.instances[a].getElementsByTagName('textarea');
												if(allIframes.length>0 && allTextareas.length>0){
													// get the editor from the iframe
													editor = classBehaviour.richTextEditor.getEditor(allIframes[0].id);
													// if the iframe is replacing the textarea
													if(allTextareas[0].style.display=='none'){
														allTextareas[0].value = editor.documentElement.firstChild.nextSibling.innerHTML.split('<LINK')[0].split('<link')[0];
													// else the textarea will replace the iframe
													}else{
														editor.documentElement.firstChild.nextSibling.innerHTML = allTextareas[0].value + classBehaviour.richTextEditor.stylesheet;
													}
												}
											}
										}
				this.resize			=	function(container){
												if(!this.resizing){
													// get the editor
													iFrame = container.getElementsByTagName('iframe')[0];
													textArea = container.getElementsByTagName('textarea')[0];
													// what is the mode of the editor
													editor = (textArea.style.display=='none') ? iFrame : textArea;
													// if the editor wasn't marked big
													if(editor.className.indexOf('biggerEditor')<0){
														// mark is as big
														editor.className = 'biggerEditor ' + editor.className;
														// and lock this function
														classBehaviour.richTextEditor.resizing = true;
														// make the editor twice as big
															// editor.style.height = (editor.offsetHeight * 3) + 'px';
														classBehaviour.fader.grow(editor.id, null, editor.offsetHeight*3, 20, 10, 'classBehaviour.richTextEditor.resizing=false;');
													//else
													}else{
														// remove it mark
														editor.className = editor.className.replace('biggerEditor', '');
														// and lock this function
														classBehaviour.richTextEditor.resizing = true;
														// make the editor half as big
															//editor.style.height = Math.round(editor.offsetHeight / 3) + 'px';
														classBehaviour.fader.shrink(editor.id, null, editor.offsetHeight/3, 20, 10, 'classBehaviour.richTextEditor.resizing=false;');
													}
												}
												// cancel the click
												return false;
											}
				this.closeOption 	=	function(objNode){
											var ecs = classBehaviour.richTextEditor;
											// find the toggle button
											rootNode = classBehaviour.utilities.rootNode(objNode, 'LI', null, null);
											buttonNode = rootNode.getElementsByTagName(ecs.buttonType)[0];
											// and press it
											if(buttonNode.className.indexOf('toggleNextNode')>-1) buttonNode.onclick(buttonNode);
										}
				// events
				this.storeSelect	=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var ecs = classBehaviour.richTextEditor;
											// store the selection
											editor = objNode;
											if(editor.selection){
												ecs.bookmark = editor.selection.createRange().getBookmark();
											}
										}
				this.restoreSelect	=	function(editor){
											var ecs = classBehaviour.richTextEditor;
											// restore the selection
											if(editor.selection){
												if(ecs.bookmark){
													range = editor.documentElement.firstChild.nextSibling.createTextRange();
													range.moveToBookmark(ecs.bookmark);
													range.select();
												}
											}
										}
				this.toggle			=	function(container){
												// get the elements from this editor
												iframes = container.getElementsByTagName('iframe');
												buttonBars = container.getElementsByTagName('ul');
												textareas = container.getElementsByTagName('textarea');
												// if the textearea is invisible
												if(textareas[0].style.display=='none'){
													// hide the button bar
													buttonBars[0].style.display = 'none';
													buttonBars[1].style.display = 'block';
													// hide the iframe
													iframes[0].style.display = 'none';
													// show the textarea
													textareas[0].style.display = 'block';
												}else{
													// show the button bar
													buttonBars[0].style.display = 'block';
													buttonBars[1].style.display = 'none';
													// show the iframe
													iframes[0].style.display = 'block';
													// hide the textarea
													textareas[0].style.display = 'none';
												}
												// cancel the click
												return false;
											}
				this.editCommand		=	function(that){
												var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
												var ecs = classBehaviour.richTextEditor;
												// get the editor canvas
												container = objNode;
												while(container.nodeName.indexOf(classBehaviour.richTextEditor.containerType)<0) container = container.parentNode;
												editorId = container.getElementsByTagName('iframe')[0].id;
												editor = ecs.getEditor(editorId);
												// restore the selection if it was lost
												ecs.restoreSelect(editor);
												// get the selected section
												selection = 	(editor.selection) ? editor.selection.createRange().text : 
																	(editor.getSelection) ? editor.getSelection() : 
																		(editor.createRange) ? editor.createRange() : 
																			null ;
												// gather the command parameters
												commandName = classBehaviour.utilities.getClassParameter(objNode, 'cmd', '');
												commandArgument = classBehaviour.utilities.getClassParameter(objNode, 'arg', objNode.value);
												// exceptions
												command = true;
												switch(commandName){
													case 'insertimage' :
														commandArgument = classBehaviour.utilities.previousNode(objNode).value;
														ecs.closeOption(objNode);
														break;
													case 'createlink' :
														commandArgument = classBehaviour.utilities.previousNode(objNode).value;
														ecs.closeOption(objNode);
														break;
													case 'forecolor' :
														ecs.closeOption(objNode);
														break;
													case 'forecolor2' :
														commandArgument = classBehaviour.utilities.previousNode(objNode).value;
														commandName='forecolor';
														ecs.closeOption(objNode);
														break;
													case 'fontname' :
														ecs.closeOption(objNode);
														break;
													case 'fontname2' :
														commandArgument = classBehaviour.utilities.previousNode(objNode).value;
														commandName='fontname';
														ecs.closeOption(objNode);
														break;
													case 'fontsize' :
														ecs.closeOption(objNode);
														break;
													case 'fontsize2' :
														commandArgument = classBehaviour.utilities.previousNode(objNode).value;
														commandName='fontsize';
														ecs.closeOption(objNode);
														break;
													case 'toggle' :
														command = ecs.toggle(container);
														break;
													case 'bigger' :
														command = ecs.resize(container);
														break;
													default : 
														break;
												}
												// execute the command
												if(selection && command) editor.execCommand(commandName, false, commandArgument);
												// cancel the click
												return false;
											}
			}
			// add this function to the classbehaviour object
			classBehaviour.richTextEditor = new RichTextEditor;
			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.richTextEditor;
			// Construct an empty stylesheet based on the hierarchy of tags
			// define this class behaviour			function MakeStylesheet(){				// properties				this.name 				=	'makeStylesheet';
				this.styleSheet			= 	"/* " + document.location.href.split('/')[document.location.href.split('/').length-1] + " */\n";
				this.referenceCss		=	"";				// methods				this.start				=	function(node){
												// make a reference stylesheet from the current stylesheets
												this.makeReferenceCss();
												// markup the stylesheet making button
												node.style.position = 'absolute';
												node.style.right = '0px';
												node.style.top = '0px';
												node.onclick = this.showNodeClasses;
												/* how to read stylesheet content
												debug(
													document.styleSheets[0].cssRules[1].selectorText,
													document.styleSheets[0].cssRules[1].cssText,
													document.styleSheets[0].cssRules[1].style.getPropertyValue('font-family')
												);
												*/											}
				this.makeReferenceCss	=	function(){
												for(var a=0; a<document.styleSheets.length; a++)
													if(document.styleSheets[a].cssRules)
														for(var b=0; b<document.styleSheets[a].cssRules.length; b++)
															this.referenceCss += document.styleSheets[a].cssRules[b].selectorText + ' {}\n\t';
											}
				this.isFormElement		=	function(node){
												return (('INPUT,SELECT,TEXTAREA,BUTTON').indexOf(node.nodeName)>-1);
											}
				this.isClassBehaviour	=	function(newEntry){
												foundHandler = false;
												// for all behaviours, if the behaviour's name exists in the class name, apply it's events
												if(typeof(newEntry)=='string')													for(var b=0; b<classBehaviour.handlers.length; b++)														foundHandler = (newEntry.indexOf(classBehaviour.handlers[b].name)>-1) ? true : foundHandler;
												// report back
												return foundHandler;
											}
				this.isInStylesheet		=	function(newEntry, onlyChanges){
												foundStyle = false;
												// clean the new entry
												newEntry = newEntry.replace(/\t/gi,'').replace(' {}\n','').replace(',','');
												// if the style allready exists in this constructed stylesheet
												foundStyle = (this.styleSheet.indexOf(newEntry)>-1);
												// if the style allready exists in any rule in another stylesheet
												foundStyle = (this.referenceCss.indexOf(newEntry)>-1 && onlyChanges) ? true : foundStyle ;
												// report back
												return foundStyle;
											}
				this.stripBehaviour		=	function(newEntry){
												foundHandler = false;
												// for all behaviours, if the behaviour's name exists in the class name, apply it's events												for(var b=0; b<classBehaviour.handlers.length; b++)													newEntry = newEntry.replace(classBehaviour.handlers[b].name+'.', '').replace(classBehaviour.handlers[b].name, '');
												// report back
												return newEntry;
											}
				this.getNodeClasses		=	function(objNode, intRecursion, prefix, onlyChanges){
												var strTabs = '';
												var idPrefix, classPrefix, tagPrefix, addPrefix;
												var newEntry = '';
												// for every recursion add one tab
												for(var intB=0; intB<intRecursion; intB++) strTabs += '\t';
												// get the child nodes
												var objChildNodes = objNode.childNodes;
												// for every childnode
												for(var intA=0; intA<objChildNodes.length; intA++){
													// reset prefixes
													idPrefix = '';
													classPrefix = '';
													tagPrefix = '';
													addPrefix = '';
													// if it has an id, but is not a form element
													if(typeof(objChildNodes[intA].id)!='undefined' && !this.isFormElement(objChildNodes[intA])){
														if(objChildNodes[intA].id!='' && !this.isClassBehaviour(objChildNodes[intA].id)){
															if(typeof(objChildNodes[intA].id)=='string'){
																// add class to stylesheet prototype
																newEntry = strTabs + '#' + objChildNodes[intA].id + ' {}\n';
																	// strStyleSheet += strTabs + prefix + '#' + objChildNodes[intA].id + ' {}\n'
																// add this style only if there's not double
																if(!this.isInStylesheet(newEntry, onlyChanges)) this.styleSheet += newEntry;
																// update the prefix
																idPrefix = '#' + objChildNodes[intA].id;
															}
														}
													}
													// if it has a className
													if(typeof(objChildNodes[intA].className)!='undefined'){
														// strip the classnames
														allClasses = objChildNodes[intA].className.replace(/ /gi, '.');
														// if there's anything left
														if(objChildNodes[intA].className!=''){
															// add class to stylesheet prototype
															newEntry = strTabs + prefix + objChildNodes[intA].nodeName.toLowerCase() + '.' + allClasses + ' {}\n';
															// add this style only if there's not double
															if(!this.isInStylesheet(newEntry, onlyChanges)){
																// update the prefix
																this.styleSheet += newEntry;
																// if the last entry was a link
																if(objChildNodes[intA].nodeName=='A'){
																	// repeat it four times with the mouseover states
																	this.styleSheet += '\t' + strTabs + prefix + objChildNodes[intA].nodeName.toLowerCase() + '.' + allClasses + ':link,\n';
																	this.styleSheet += '\t' + strTabs + prefix + objChildNodes[intA].nodeName.toLowerCase() + '.' + allClasses + ':visited {}\n';
																	this.styleSheet += '\t' + strTabs + prefix + objChildNodes[intA].nodeName.toLowerCase() + '.' + allClasses + ':hover,\n';
																	this.styleSheet += '\t' + strTabs + prefix + objChildNodes[intA].nodeName.toLowerCase() + '.' + allClasses + ':active {}\n';
																	// and jump further in
																	intRecursion += 1;
																}
															}
															// update the prefix
															classPrefix = objChildNodes[intA].nodeName.toLowerCase() + '.' + allClasses;
														}
													}
													// if it has neither
													if(
														objChildNodes[intA].className=='' && 
														(objChildNodes[intA].id=='' || this.isFormElement(objChildNodes[intA])) && 
														objChildNodes[intA].nodeName.indexOf('text')<0 && 
														objChildNodes[intA].nodeName.indexOf('comment')<0
													){
														// add class to stylesheet prototype
														newEntry = strTabs + prefix + objChildNodes[intA].nodeName.toLowerCase() + ' {}\n';
														// add this style only if there's not double
														if(!this.isInStylesheet(newEntry, onlyChanges)){
															this.styleSheet += newEntry;
															// if the last entry was a link
															if(newEntry.indexOf(' a {}')>-1){
																// repeat it four times with the mouseover states
																this.styleSheet += '\t' + newEntry.replace('a {}','a:link,');
																this.styleSheet += '\t' + newEntry.replace('a {}','a:visited {}');
																this.styleSheet += '\t' + newEntry.replace('a {}','a:hover,');
																this.styleSheet += '\t' + newEntry.replace('a {}','a:active {}');
																// and jump further in
																intRecursion += 1;
															}
														}
														// update the prefix
														tagPrefix = objChildNodes[intA].nodeName.toLowerCase();
													}
													// if it has childNodes
													if(objChildNodes[intA].childNodes.length>0){
														// update the prefix
														if(idPrefix){
															addPrefix = idPrefix + ' ';
														}else if(classPrefix){
															addPrefix = prefix + classPrefix + ' ';
														}else if(tagPrefix){
															addPrefix = prefix + tagPrefix + ' ';
														}
														// recurse
														this.getNodeClasses(objChildNodes[intA], intRecursion+1, addPrefix, onlyChanges);
													}
												}
											}
				this.showNodeClasses	=	function(that){
												var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
												var mss = classBehaviour.makeStylesheet;
												// position it out of the way
												document.body.style.textAlign = 'left';
												document.body.style.background = '#ffffff none';
												document.body.style.color = '#000000';
												document.body.style.fontFamily = 'Sans Serif';
												document.body.style.fontSize = '12pt';
												// are only the changes to the existing stylesheets required?
												onlyChanges = (classBehaviour.utilities.getClassParameter(objNode, 'changesOnly', 'yes')=='yes');
												// generate the stylesheet code
												mss.getNodeClasses(document.body, 0 , '', onlyChanges);
												// replace the page with the stylesheet prototype
												document.body.innerHTML = (navigator.userAgent.indexOf('MSIE 6')>-1) ? '<textarea style="width:720px;height:480px;border:solid 1px #000000;">' + mss.styleSheet + '</textarea>' : '<textarea style="position:absolute;left:12.5%;top:12.5%;width:75%;height:75%;border:solid 1px #000000;">' + mss.styleSheet + '</textarea>';
											}			}			// add this function to the classbehaviour object			classBehaviour.makeStylesheet = new MakeStylesheet;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.makeStylesheet;
			
		// html encode the content of the document			// define this class behaviour			function HtmlEncode(){				// properties				this.name 		= 	'htmlEncode';				// methods				this.start		=	function(node){										// markup the stylesheet making button
										node.style.position = 'absolute';
										node.style.right = '0px';
										node.style.top = '25px';
										node.onclick = this.importDoc;									}
				// events
				this.importDoc	=	function(){
										// load the document
										classBehaviour.ajax.addRequest(document.location.href, classBehaviour.htmlEncode.encode, classBehaviour.htmlEncode.wait, false, null);
									}
				this.wait		=	function(waitStatus){
										
									}
				this.encode		=	function(docXml, referedObj, docTxt){
										// present it back
										document.body.innerHTML = '<textarea id="htmlEncoded" style="position:absolute;left:12.5%;top:12.5%;width:75%;height:75%;border:solid 1px #000000;">' + docTxt + '</textarea>';
										// translate it to blog content
										document.getElementById('htmlEncoded').value = document.getElementById('htmlEncoded').value.replace(/>/gi, '&gt;').replace(/</gi, '&lt;'); // .replace(/\t/gi,'   ');
									}			}			// add this function to the classbehaviour object			classBehaviour.htmlEncode = new HtmlEncode;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.htmlEncode;
			
		// move a link's click event to the parent node			// define this class behaviour			function ClickOnParent(){				// properties				this.name 		= 	'clickOnParent';				// methods				this.start		=	function(node){										// what node is the click supposed to go on?
										parentCount = parseInt(classBehaviour.utilities.getClassParameter(node, "parent", "2"));
										targetNode = node;
										for(var a=0; a<parentCount; a++) targetNode = targetNode.parentNode;
										// get the target of the link
										linkTarget = node.href;
										// set the click event
										targetNode.onclick = this.clicked;
										// set the cursor
										targetNode.style.cursor = 'pointer';									}
				// events
				this.clicked	=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// what is the link
										linkTargets = objNode.getElementsByTagName('A');
										for(var a=0; a<linkTargets.length; a++) if(linkTargets[a].className.indexOf('clickOnParent')>-1) linkTarget = linkTargets[a].href;
										// go to the link
										document.location.href = linkTarget;
									}			}			// add this function to the classbehaviour object			classBehaviour.clickOnParent = new ClickOnParent;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.clickOnParent;
			
		// emulates a scrollbar
			// define this class behaviour
			function VirtualScrollbar(){
				// properties
				this.name 		= 	'virtualScrollbar';
				this.interval	=	null;
				// methods
				this.start		=	function(node){
										// set the event handlers for the indicator bar
										node.onmousedown = this.pick;
										node.onmouseup = this.drop;
										node.onmousemove = this.drag;
										node.onmouseout = this.drop;
										document.onmousemove = this.nodrag;
										// set the initial position
										pageId = classBehaviour.utilities.getClassParameter(node, 'id', 'scrollCanvas');
										this.scrollTo(pageId, 0, node);
									}
				this.scrollTo	=	function(id, position, control){
										var vsb = classBehaviour.virtualScrollbar;
										// normalize the position
										if(position>0) position = 0;
										// what is the scrollable page
										page = document.getElementById(id).getElementsByTagName('div')[0];
										// how high is the page
										pageHeight = page.offsetHeight;
										// how high is the container of the page
										containerHeight = page.parentNode.offsetHeight;
										// don't allow negative scrolling
										if(pageHeight<containerHeight){
											pageHeight = containerHeight;
										}
										// if there's still a distace left to scroll on the bottom shift the page up
										if(navigator.userAgent.indexOf('Safari')>-1){
											page.style.position = 'absolute';
											page.style.top = (position<containerHeight-pageHeight) ? (containerHeight-pageHeight) + 'px' : position + 'px' ;
										}else{
											page.style.marginTop = (position<containerHeight-pageHeight) ? (containerHeight-pageHeight) + 'px' : position + 'px' ;
										}
										// set the position of the indicator
										control.style.backgroundPosition = '0px ' + Math.round(-1.2 * containerHeight * position / pageHeight)  + 'px'
									}
				this.scrollBy	=	function(id, distance, control){
										// what is the scrollable page
										page = document.getElementById(id);
										// how far has the page scrolled up
										if(navigator.userAgent.indexOf('Safari')>-1){
											scrolledHeight = (page.style.top) ? parseInt(page.style.top) : 0 ;
										}else{
											scrolledHeight = (page.style.marginTop) ? parseInt(page.style.marginTop) : 0 ;
										}
										// calculate the new position
										position = scrolledHeight + distance;
										// set the position
										this.scrollTo(id, position);
									}
				// events
				this.pick		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var vsb = classBehaviour.virtualScrollbar;
										// mark the dragged item as being active
										objNode.className = objNode.className.replace('passive', 'active');
										// initial value
										vsb.drag(objNode);
										// cancel the click
										return false;
									}
				this.drag		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var vsb = classBehaviour.virtualScrollbar;
										// if the scrollbar is marked as draggable
										if(objNode.className.indexOf('active')>-1){
											// get the click position
											mouseX = (typeof(event)!='undefined') ? event.x : that.layerX ;
											mouseY = (typeof(event)!='undefined') ? event.y : that.layerY ;
											// get the page dimensions
											id = classBehaviour.utilities.getClassParameter(objNode, 'id', 'scrollCanvas');
											page = document.getElementById(id).getElementsByTagName('div')[0];
											// how high is the page
											pageHeight = page.offsetHeight;
											// how high is the container of the page
											containerHeight = page.parentNode.offsetHeight;
											// corelate the mouse-position to the scroll-position
											position = Math.round(-1 * mouseY * (pageHeight-containerHeight) / containerHeight);
											position = position * 1.2 + containerHeight * 0.2;
											// pass the position on to the page
											vsb.scrollTo(id, position, objNode);
										}
										// cancel the click
										return false;
									}
				this.nodrag	=	function(){
										return false;
									}
				this.drop		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var vsb = classBehaviour.virtualScrollbar;
										// mark the dragged item as being passive
										objNode.className = objNode.className.replace('active', 'passive');
										// cancel the click
										return false;
									}
			}
			// add this function to the classbehaviour object
			classBehaviour.virtualScrollbar = new VirtualScrollbar;
			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.virtualScrollbar;
	
		// constants/configuration
			function RssSearch(){
				// properties
				this.name 		= 	'rssSearch';
				this.form		=	null;
				this.url 		= 	null;
				this.input 		= 	null;
				this.output 	= 	null;
				this.startIndex	=	0;
				this.endIndex	=	8;
				/* objects */
				this.search		=	new Search;
				this.source		=	new Source;
				// methods
				this.start		=	function(node){
										node.onsubmit = this.doSubmit;
										// get the default values
										this.form		=	document.getElementById('searchform');
										this.url 		= 	document.getElementById('searchsource');
										this.input 		= 	document.getElementById('searchstring');
										this.output 	= 	document.getElementById('searchresults');
									}
				this.find		=	function(start, end){
										// store paging preferences
										if(start!=null) this.startIndex = start;
										if(end!=null) 	this.endIndex = end;
										// lead the source to search
										if(this.source.document==null){
											this.source.load(this.url.value);
										}else{
											// search query
											var query					= this.search.query(this.input.value);
											// search process
											var results					= this.search.results(query, this.source.document);
											// search results
											var summary					= this.search.summary(results, this.startIndex, this.endIndex);
											// write the search summary
											this.output.innerHTML		= summary;
										}
										// cancel the submit
										return false;
									}
				// events
				this.doSubmit	=	function(){
										return classBehaviour.rssSearch.find();
									}
			}
				function Search(){
					this.sort		=	function(a, b){
											// sort by the first index of the object
											return (isNaN(a[0]) || isNaN(b[0])) ? 0 : b[0]-a[0] ;
										}
					this.query		=	function(searchString){
											// formulate the search string into a regular expression
											return new RegExp(searchString.replace(" ","|"),"gi");
										}
					this.results	=	function(query, doc, docText){
											var contents, titles, descs, text, matchText, matchScore;
											var results = new Array();
											// get all items in the rss feed
											contents = doc.getElementsByTagName('item');
											// for every item
											for(var a=0; a<contents.length; a++){
												// get the nodes
												titles	= contents[a].getElementsByTagName('title');
												descs	= contents[a].getElementsByTagName('description');
												// get the text from the nodes
												text = '';
												if(titles.length>0)		text += titles[0].firstChild.nodeValue;
												if(descs.length>0)		text += descs[0].firstChild.nodeValue;
												// match the query with the item's text
												matchText = text.match(query);
												// if there were hits
												if(matchText!=null){
													// calculate the score (the joined length of the matched array)
													matchScore = matchText.join(' ').length;
													// add the score and the node to the list of search results
													results[results.length] = new Array(matchScore,contents[a]);
												}
											}
											// sort the list of search results
											results = results.sort(this.sort);
											// pass the results back
											return results;
										}
					this.summary	=	function(results, startPage, resultsPerPage){
											var report = '<dl class="items">';
											var links, titles, summaries;
											var link, title, summary;
											// for the selected search results
											var a = startPage * resultsPerPage;
											while(a<results.length && (a+1)%resultsPerPage!=0){
												// link
												links			= results[a][1].getElementsByTagName('link')
												link			= (links.length==0) ? '' : links[0].firstChild.nodeValue;
												// title
												titles			= results[a][1].getElementsByTagName('title')
												title			= (titles.length==0) ? '' : titles[0].firstChild.nodeValue;
												// author
												authors			= results[a][1].getElementsByTagName('author')
												author			= (authors.length>0) ? authors[0].firstChild.nodeValue : '' ;
												// category
												categories		= results[a][1].getElementsByTagName('category')
												category		= (categories.length>0) ? categories[0].firstChild.nodeValue : '' ;
												// pubDate
												pubDates		= results[a][1].getElementsByTagName('pubDate')
												pubDate			= (pubDates.length>0) ? pubDates[0].firstChild.nodeValue.replace(':00 +0100', '') : '' ;
												// part of the description
												summaries		= results[a][1].getElementsByTagName('description')
												if(summaries.length>0){
													summary			= (summaries[0].xml) ? summaries[0].xml : summaries[0].firstChild.nodeValue;
													summary			= summary.replace(/&lt;/gi, '<').replace(/&gt;/gi, '>').replace(/<(.|\n)+?>/gi,'');
													summary			= (summaries[0].xml) ? summary.substr(0,64) + '...' : summary.substr(0,128) + '...';
												}else{
													summary			= '';
												}
												// construct report
												report			+= '<dt class="title"><a href="'+link+'">'+title+'</a></dt>\n';
												report			+= '<dd>\n';
												report			+= '	<ul class="information">\n';
												report			+= '		<li class="author">' + author + '</li>\n';
												report			+= '		<li class="category">' + category + '</li>\n';
												report			+= '		<li class="pubDate">' + pubDate + '</li>\n';
												report			+= '	</ul>\n';
												report			+= '	<div class="description"><p>'+summary+'</p></div>\n';
												report			+= '</dd>\n';
												// next item
												a += 1;
											}
											report += '</dl>';
											// if nothing was found
											if(results.length==0){
												// apologize
												report			+= '<p class="error">Sorry, no matches were found</p>';
											// else
											}else{
												var minPages	= 0;
												var maxPages	= Math.round(results.length/resultsPerPage+0.49);
												// page x of n
												report			+= '<ul class="pager">\n';
												report			+= (startPage>minPages) ? '<li class="previous"><a href="#" onclick="return classBehaviour.rssSearch.find('+(startPage-1)+','+resultsPerPage+')">Previous</a></li>' : '<li class="previous"></li>' ;
												report			+= (startPage<maxPages-1) ? '<li class="next"><a href="#" onclick="return classBehaviour.rssSearch.find('+(startPage+1)+','+resultsPerPage+')">Next</a></li>' : '<li class="next"></li>' ;
												report			+= '<li class="count">Page '+(startPage+1)+' of '+maxPages + '</li>';
												report			+= '</ul>\n';
											}
											// return the search results
											return report	;
										}
				}
				function Source(){
					this.document	=	null;
					this.load		=	function(url){
											classBehaviour.ajax.addRequest(url, classBehaviour.rssSearch.source.onload, classBehaviour.rssSearch.source.wait);
										}
					this.wait		=	function(status){
											if(status<0){
												classBehaviour.rssSearch.output.innerHTML = '<hr /><p>Something went wrong.</p>'
											}else{
												classBehaviour.rssSearch.output.innerHTML = '<hr /><p>Searching: ' + Math.round(status * 100) + '%</p>';
											}
										}
					this.onload	=	function(root){
											classBehaviour.rssSearch.source.document = root;
											classBehaviour.rssSearch.find();
										}
				}
			// add this function to the classbehaviour object
			classBehaviour.rssSearch = new RssSearch;
			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.rssSearch;
			
		// displays and updates the nodes of a chat window			// define this class behaviour			function RssChat(){				// properties				this.name 		= 	'rssChat';
				this.index		=	0;
				this.timeout	=	null;
				this.delay		=	4096;				// methods				this.start		=	function(node){
										// give the node an id if it doesn't have one
										node.id = (node.id) ? node.id : this.name + this.index++ ;
										// set the button event
										node.getElementsByTagName('button')[0].onclick = this.send;
										// get the delay
										this.delay = parseInt(classBehaviour.utilities.getClassParameter(node,'delay','4096'));
										// load the feed
										rssUrl = node.getElementsByTagName('input')[0].value;
										rssRnd = '&upd=' + new Date().getTime();
										classBehaviour.ajax.addRequest(rssUrl+rssRnd, this.update, this.wait, null, node.id);									}
				this.wait		=	function(progress, nodeId, error){
										var node = document.getElementById(nodeId);
										progressNode = node.getElementsByTagName('div')[0];
										progressNode.style.backgroundPosition = (progress<0) ? '0% 100%' : (100-progress*100) +'% 0%' ;
										progressNode.innerHTML = (progress<0) ? 'error: ' + error : Math.round(progress*100) + '% updated' ;
									}
				this.update		=	function(xml, nodeId, txt){
										var node = document.getElementById(nodeId);
										// clear any pending timeout
										clearTimeout(classBehaviour.rssChat.timeout);
										// update the chat title
										rssHeader = node.getElementsByTagName('h3');
										if(rssHeader.length>0) rssHeader[0].innerHTML = xml.getElementsByTagName('title')[0].firstChild.nodeValue;
										// clear all previous items except the protoype
										previousDts = node.getElementsByTagName('dt');
										previousDds = node.getElementsByTagName('dd');
										for(var a=previousDts.length-1; a>0; a--){
											removedDd = previousDds[a].parentNode.removeChild(previousDds[a]);
											removedDt = previousDts[a].parentNode.removeChild(previousDts[a]);
										}
										// for all chat items
										allItems = xml.getElementsByTagName('item');
										listNode = node.getElementsByTagName('dl')[0];
										for(var a=0; a<allItems.length; a++){
											// get the item properties
											itemAuthor = (allItems[a].getElementsByTagName('author')[0].childNodes.length>0) ? allItems[a].getElementsByTagName('author')[0].firstChild.nodeValue : '' ;
											itemPubDate = (allItems[a].getElementsByTagName('pubDate')[0].childNodes.length>0) ? allItems[a].getElementsByTagName('pubDate')[0].firstChild.nodeValue : '' ;
											itemCategory = (allItems[a].getElementsByTagName('category')[0].childNodes.length>0) ? allItems[a].getElementsByTagName('category')[0].firstChild.nodeValue : '' ;
											itemLink = (allItems[a].getElementsByTagName('link')[0].childNodes.length>0) ? allItems[a].getElementsByTagName('link')[0].firstChild.nodeValue : '' ;
											itemTitle = (allItems[a].getElementsByTagName('title')[0].childNodes.length>0) ? allItems[a].getElementsByTagName('title')[0].firstChild.nodeValue : '' ;
											itemDescription = (allItems[a].getElementsByTagName('description')[0].childNodes.length>0) ? allItems[a].getElementsByTagName('description')[0].firstChild.nodeValue : '' ;
											// format the date
											itemPubDate = (new Date(itemPubDate)).toLocaleString();
											// clone the prototype node
											clonedDt = node.getElementsByTagName('dt')[0].cloneNode(true);
											clonedDd = node.getElementsByTagName('dd')[0].cloneNode(true);
											// modify its contents
											clonedDt.className = clonedDt.className.replace('prototype', '');
											clonedDt.innerHTML = clonedDt.innerHTML.replace(/{author}/gi, itemAuthor).replace(/{pubDate}/gi, itemPubDate).replace(/{category}/gi, itemCategory).replace(/{link}/gi, itemLink).replace(/{title}/gi, itemTitle);
											clonedDd.className = clonedDd.className.replace('prototype', '');
											clonedDd.firstChild.nodeValue = itemDescription;
											// insert it at the top
											listNode.appendChild(clonedDt);
											listNode.appendChild(clonedDd);
										}
										// set the scroll position to the bottom
										listNode.scrollTop = listNode.scrollHeight + 1000;
										// order another update
										rssUrl = node.getElementsByTagName('input')[0].value;
										rssRnd = '&upd=' + '?upd=' + new Date().getTime();
										classBehaviour.rssChat.timeout = setTimeout('classBehaviour.ajax.addRequest("'+rssUrl+rssRnd+'", classBehaviour.rssChat.update, classBehaviour.rssChat.wait, null, "'+nodeId+'")', classBehaviour.rssChat.delay);
									}
				// events
				this.send		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var rsc = classBehaviour.rssChat
										// find the root node
										rootNode = classBehaviour.utilities.rootNode(objNode, null, null, rsc.name);
										// get the submitted values
										itemAuthor = rootNode.getElementsByTagName('input')[1].value.replace(';', ':');
										itemPubDate = (new Date()).toUTCString();
										itemCategory = "replies";
										itemLink = document.location.href;
										itemTitle = document.title;
										itemDescription = rootNode.getElementsByTagName('textarea')[0].value;
										// construct the post
										rssPost = "&root=channel&parent=item&indexa=-1&valuesa=author;" + itemAuthor + ";pubDate;" + itemPubDate + ";category;" + itemCategory + ";title;" + itemTitle + ";description;" + itemDescription;
										// make the http request
										rssUrl = rootNode.getElementsByTagName('input')[0].value;
										rssRnd = '&upd=' + '?upd=' + new Date().getTime();
										classBehaviour.ajax.addRequest(rssUrl+rssRnd+rssPost, rsc.update, rsc.wait, null, rootNode.id);
										// clear the textarea
										rootNode.getElementsByTagName('textarea')[0].value = '';
									}			}			// add this function to the classbehaviour object			classBehaviour.rssChat = new RssChat;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.rssChat;
			
		// edit the order of items in select lists			// define this class behaviour			function ManyToMany(){				// properties				this.name 		= 	'manyToMany';				// methods				this.start		=	function(node){
										// was the click aimed at the select list
										if(node.nodeName=='SELECT'){
											node.className += ' from_' + node.id;
											node.ondblclick = this.clicked;
										}else{											node.onclick = this.clicked;
										}									}
				// events
				this.resetEdit   =	function(id){
				                        textArea = document.getElementById(id.replace('$', ''));
				                        if (textArea.type != 'textarea') return;
				                        selectArea = document.getElementById(id);
				                        textArea.value = '';
				                        for(i = 0; i < selectArea.length; i++)
				                            textArea.value += selectArea.options[i].value + '|' + selectArea.options[i].text + '\n';
				                    }
				this.clicked	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// button settings
										moveSourceId = classBehaviour.utilities.getClassParameter(objNode, 'from', null);
										moveDestinationId = classBehaviour.utilities.getClassParameter(objNode, 'to', null);
										upSourceId = classBehaviour.utilities.getClassParameter(objNode, 'up', null);
										downSourceId = classBehaviour.utilities.getClassParameter(objNode, 'down', null);
										// get the parent nodes
										moveSource = document.getElementById(moveSourceId);
										upSource = document.getElementById(upSourceId);
										downSource = document.getElementById(downSourceId);
										moveDestination = document.getElementById(moveDestinationId);
										// if we're going to move a node
										if(moveSource && moveDestination){
											// get the source node
											sourceNode = (moveSource.selectedIndex>-1) ? moveSource.getElementsByTagName('option')[moveSource.selectedIndex] : null;
											// get the target node
											destinationNode = (moveDestination.selectedIndex>-1) ? moveDestination.getElementsByTagName('option')[moveDestination.selectedIndex] : null;
											// if there is a source node
											if(sourceNode){
												// remove the source node
												removedNode = moveSource.removeChild(sourceNode);
												// insert the source node before the desination node 
												if(destinationNode){
													moveDestination.insertBefore(removedNode, destinationNode.nextSibling);
												}else{
													moveDestination.appendChild(removedNode);
												}
											}
										}
										// if we're going to shift a node up
										if(upSource){
											// get the source node
											upNodes = upSource.getElementsByTagName('option');
											sourceNode = (upSource.selectedIndex>-1) ? upNodes[upSource.selectedIndex] : null;
											destinationNode = (upSource.selectedIndex>0) ? upNodes[upSource.selectedIndex-1] : null ;
											if(sourceNode && destinationNode){
												// remove the source node
												removedNode = upSource.removeChild(sourceNode);
												// insert it at its new place
												upSource.insertBefore(removedNode, destinationNode);
											}
											classBehaviour.manyToMany.resetEdit(upSource.id);
										}
										// if we're going to shift a node down
										if(downSource){
											// get the source node
											downNodes = downSource.getElementsByTagName('option');
											sourceNode = (downSource.selectedIndex>-1) ? downNodes[downSource.selectedIndex] : null;
											destinationNode = (downSource.selectedIndex<downNodes.length-2) ? downNodes[downSource.selectedIndex+2] : null ;
											if(sourceNode && destinationNode){
												// remove the source node
												removedNode = downSource.removeChild(sourceNode);
												// insert it at its new place
												downSource.insertBefore(removedNode, destinationNode);
											}else if(sourceNode){
												// remove the source node
												removedNode = downSource.removeChild(sourceNode);
												// insert it at its new place
												downSource.appendChild(removedNode);
											}
											classBehaviour.manyToMany.resetEdit(downSource.id);
										}
										return false;
									}			}			// add this function to the classbehaviour object			classBehaviour.manyToMany = new ManyToMany;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.manyToMany;
					
		// Sort table rows by dragging and dropping
			// define this class behaviour			function DragToSort(){				// properties				this.name 			= 	'dragToSort';
				this.moving			=	null;
				this.over			=	null;
				this.offsetX		=	-50;
				this.offsetY		=	1;
				this.timeout		=	null;
				this.allowed		=	true;
				// methods				this.start			=	function(node){
											// set the offset
											this.offsetX = parseInt(classBehaviour.utilities.getClassParameter(node,'offx', this.offsetX));
											this.offsetY = parseInt(classBehaviour.utilities.getClassParameter(node,'offy', this.offsetY));
											// apply the event handlers to all table rows
											allRows = node.getElementsByTagName('tr');
											for(var a=0; a<allRows.length; a++){
												// drag event handler
												if(allRows[a].parentNode.nodeName=='TBODY') allRows[a].onmousedown = this.pickUp;
												allRows[a].onmouseover = this.trackOver;
												allRows[a].onmouseout = this.trackOut;
												// add the undragged classname
												allRows[a].className += ' notDragged';
											}
											// for all buttons and input  fields in the table
											allInputs = node.getElementsByTagName('input');
											allButtons = node.getElementsByTagName('button');
											allLinks = node.getElementsByTagName('a');
											allSelects = node.getElementsByTagName('selects');
											// set a mouseover that disbles the pickup events
											for(var a=0; a<allInputs.length; a++){	allInputs[a].onmouseover = this.disallow; 	allInputs[a].onmouseout = this.allow;}
											for(var a=0; a<allButtons.length; a++){	allButtons[a].onmouseover = this.disallow; 	allButtons[a].onmouseout = this.allow;}
											for(var a=0; a<allLinks.length; a++){	allLinks[a].onmouseover = this.disallow; 		allLinks[a].onmouseout = this.allow;}
											for(var a=0; a<allSelects.length; a++){	allSelects[a].onmouseover = this.disallow; 	allSelects[a].onmouseout = this.allow;}
											// apply the move events
											document.onmousemove = this.moveAround;
											document.onmouseup = this.dropDown;
											// when dragged off-canvas
											document.onmouseout = this.wait;
										}
				this.disallow		=	function(){
											var dts = classBehaviour.dragToSort;
											dts.allowed = false;
										}
				this.allow			=	function(){
											var dts = classBehaviour.dragToSort;
											dts.allowed = true;
										}
				this.dropDown		=	function(){
											var dts = classBehaviour.dragToSort;
											// if there is an element being dragged
											if(dts.moving){
												// clear the remembered node
												dts.moving.style.position = 'static';
												dts.moving.style.left = 'auto' ;
												dts.moving.style.top = 'auto' ;
												// swap the nodes
												if(dts.over && dts.moving!=dts.over){
													// remove the dragged row
													storedNode = dts.moving.parentNode.removeChild(dts.moving);
													// insert it before the target row
													dts.over.parentNode.insertBefore(storedNode, dts.over);
													// redo the odd and even classes
													dts.reZebra(dts.over);
													// re-apply the classbehaviours
													classBehaviour.parser.parseNode(classBehaviour.utilities.previousNode(dts.over));
												}
												// clear the sources
												dts.moving = null;
												dts.over = null;
											}
											// cancel the mouse event
											return false;
										}
				this.reZebra		=	function(tableRow){
											// get all the siblings to this row
											allRows = tableRow.parentNode.getElementsByTagName('TR');
											for(var a=0; a<allRows.length; a++){
												allRows[a].className = (a%2==0) ? allRows[a].className.replace('even', 'odd') : allRows[a].className.replace('odd', 'even');
											}
										}
				// events
				this.trackOver		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var dts = classBehaviour.dragToSort;
											// if we are over the table
											if(objNode.parentNode.nodeName=='TBODY'){
												// store the last node the mouse went over
												if(objNode!=dts.moving) dts.over = objNode;
												// highlight the row something is dragged over
												if(dts.moving!=null) objNode.className = objNode.className.replace('notDragged', 'isDraggedOver');
											}
										}
				this.trackOut		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var dts = classBehaviour.dragToSort;
											// highlight the row something is dragged over
											if(objNode!=dts.moving) objNode.className = objNode.className.replace('isDraggedOver', 'notDragged');
										}	
				this.pickUp			=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var dts = classBehaviour.dragToSort;
											// is the mechanism disabled
											if(dts.allowed){
												// store the picked up object
												dts.moving = objNode;
												// get the mouse position
												scrollX = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft;
												scrollY = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
												xPos = (typeof(event)!='undefined') ? event.clientX+scrollX : that.pageX ;
												yPos = (typeof(event)!='undefined') ? event.clientY+scrollY : that.pageY ;
												// pick up the table row
												dts.moving.style.position = 'absolute';
												dts.moving.style.left = (xPos+dts.offsetX) + 'px' ;
												dts.moving.style.top = (yPos+dts.offsetY) + 'px' ;
												// cancel the mouse event
												return false;
											}
										}
				this.moveAround		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var dts = classBehaviour.dragToSort;
											// cancel the close timeout
											clearTimeout(dts.timeout);
											// if there is an object being dragged
											if(dts.moving){
												// get the mouse position
												scrollX = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft;
												scrollY = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
												xPos = (typeof(event)!='undefined') ? event.clientX+scrollX : that.pageX ;
												yPos = (typeof(event)!='undefined') ? event.clientY+scrollY : that.pageY ;
												// move the stored node around with the mouse
												dts.moving.style.position = 'absolute';
												dts.moving.style.left = (xPos+dts.offsetX) + 'px' ;
												dts.moving.style.top = (yPos+dts.offsetY) + 'px' ;
											}
											// cancel the mouse event
											return false;
										}
				this.wait			=	function(){
											var dts = classBehaviour.dragToSort;
											// set a timeout for resetting the system
											clearTimeout(dts.timeout);
											dts.timeout = setTimeout('classBehaviour.dragToSort.dropDown()', 250);
										}			}			// add this function to the classbehaviour object			classBehaviour.dragToSort = new DragToSort;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.dragToSort;
			
		// Sort table rows by clicking and dropping
			// define this class behaviour			function ClickToSort(){				// properties				this.name 			= 	'clickToSort';
				// methods				this.start			=	function(node){
											// get the prototype of the arrows
											indicatorArrows = node.getElementsByTagName('span')[0];
											// get the tbody
											theTbody = node.getElementsByTagName('tbody')[0];
											theTbody.className += ' hideIndicators';
											// for all table rows
											allRows = theTbody.getElementsByTagName('tr');
											for(var a=0; a<allRows.length; a++){
												// add a default class
												allRows[a].className += ' link';
												// set its event handlers
												if(navigator.appVersion.indexOf('MSIE 6')>-1){
													allRows[a].onmouseover = this.hoverOver;
													allRows[a].onmouseout = this.hoverOut;
												}
												allRows[a].onclick = this.selectRow;
												// get the first cell you can find
												firstCell = allRows[a].getElementsByTagName('td')[0];
												// clone in the prototype into the cell
												clonedArrows = indicatorArrows.cloneNode(true);
												firstCell.insertBefore(clonedArrows, firstCell.firstChild);
											}
										}
				this.reZebra		=	function(tableRow){
											// get all the siblings to this row
											allRows = tableRow.parentNode.getElementsByTagName('tr');
											for(var a=0; a<allRows.length; a++){
												allRows[a].className = (a%2==0) ? allRows[a].className.replace('even', 'odd') : allRows[a].className.replace('odd', 'even');
											}
										}
				// events
				this.hoverOver		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											objNode.className = objNode.className.replace('link', 'hover');
										}
				this.hoverOut		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											objNode.className = objNode.className.replace('hover', 'link');
										}
				this.selectRow		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var cts = classBehaviour.clickToSort;
											// get the tbody
											theTbody = objNode.parentNode;
											// if the tbody in hideIndicators mode
											if(theTbody.className.indexOf('hideIndicators')>-1){
												// mark the row as selected
												objNode.className = objNode.className.replace('link', 'active').replace('hover', 'active');
												// activate the indicator arrows
												theTbody.className = theTbody.className.replace('hideIndicators', 'showIndicators');
											// else
											}else{
												// de-activate the indicator arrows
												theTbody.className = theTbody.className.replace('showIndicators', 'hideIndicators');
												// for all rows in there
												theActiveRow = null;
												allRows = theTbody.getElementsByTagName('tr');
												for(var a=0; a<allRows.length; a++){
													// if the row is active
													if(allRows[a].className.indexOf('active')>-1){
														// store it as the source row 
														theActiveRow = allRows[a];
														// remove the active mark
														allRows[a].className = allRows[a].className.replace('active', 'link');
													}
												}
												// switch the source with the target node
												if(theActiveRow!=objNode){
													removedNode = theTbody.removeChild(theActiveRow);
													theTbody.insertBefore(removedNode, objNode);
												}
												// re-zebra
												cts.reZebra(objNode);
											}
										}
			}			// add this function to the classbehaviour object			classBehaviour.clickToSort = new ClickToSort;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.clickToSort;
			
		// Link two select lists
			// define this class behaviour			function LinkedSelects(){				// properties				this.name 			= 	'linkedSelects';
				// methods				this.start			=	function(node){
											// get the mouse position
											node.onchange = this.updateLinked;
											// sync the starting selection
											setTimeout('classBehaviour.linkedSelects.updateLinked(document.getElementById("' + node.id + '"))',100);
										}
				// events
				this.updateLinked	=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var lsl = classBehaviour.linkedSelects;
											// if there was a selected value
											if(objNode.value!=''){
												// get the target id
												linkedId = classBehaviour.utilities.getClassParameter(objNode, 'id', 'myLinkedSelect');
												// get the target object
												linkedObj = document.getElementById(linkedId);
												// start loading
												classBehaviour.ajax.addRequest(objNode.value, lsl.updateLoaded, lsl.updateProgress, null, linkedObj);
											}
										}
				this.updateProgress	=	function(progressStatus, referingObj){
											// get the first option in the select
											firstOption = referingObj.getElementsByTagName('option')[0];
											firstOption.selected = true;
											// use it as a progress indicator
											firstOption.firstChild.nodeValue = '--- loading: ' + parseInt(progressStatus*100) + '% ---';
										}
				this.updateLoaded	=	function(docXml, refererObj, docTxt){
											// for all the current options
											currentOptions = refererObj.getElementsByTagName('option');
											for(var a=currentOptions.length-1; a>=0; a--){
												removedNode = refererObj.removeChild(currentOptions[a]);
											}
											// for all the imported options
											importedOptions = docXml.getElementsByTagName('option');
											for(var a=0; a<importedOptions.length; a++){
												// replace the option contents
												newOption = document.createElement('option');
												newOptionText = document.createTextNode(importedOptions[a].firstChild.nodeValue);
												newOption.appendChild(newOptionText);
												newOption.value = importedOptions[a].getAttribute("value");
												refererObj.appendChild(newOption);
											}
										}			}			// add this function to the classbehaviour object			classBehaviour.linkedSelects = new LinkedSelects;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.linkedSelects;
			
		// Resize an iframe to accomodate the contents
			// define this class behaviour			function AutoSizeIframe(){				// properties				this.name 			= 	'autoSizeIframe';
				// methods				this.start			=	function(node){
											// set the onload event of the frame
											node.onload = this.resize;
											this.resize();
										}
				// events
				this.resize			=	function(){
											var asi = classBehaviour.autoSizeIframe;
											// if the frame is loaded, resize all iframes of this class
											allIframes = document.getElementsByTagName('iframe');
											for(var a=0; a<allIframes.length; a++)
												if(allIframes[a].className.indexOf(asi.name)>-1)
													if(window.frames[allIframes[a].name].document.getElementsByTagName('body').length>0)
														if(window.frames[allIframes[a].name].document.getElementsByTagName('body')[0].offsetHeight>0)
															document.getElementById(allIframes[0].id).style.height = (window.frames[allIframes[a].name].document.getElementsByTagName('body')[0].offsetHeight) + 'px';
										}			}			// add this function to the classbehaviour object			classBehaviour.autoSizeIframe = new AutoSizeIframe;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.autoSizeIframe;
			
		// Fetch the links from a list of portfolio templates
			// define this class behaviour			function PortfolioList(){				// properties				this.name 			= 	'portfolioList';
				// methods				this.start			=	function(node){
											// set the onclick event of the button
											allLinks = node.getElementsByTagName('a');
											for(var a=0; a<allLinks.length; a++) allLinks[a].onclick = this.clickItem;
										}
				this.waitForList	=	function(loadStatus, referedNode){
											// update the progress indicator
											referedNode.getElementsByTagName('div')[0].innerHTML = (loadStatus<0) ? '<h1>loading: failed</h1><p>Please try another.</p>' : '<h1>loading: ' + (loadStatus*100) + '%</h1>';
										}
				this.insertTheList	=	function(xmlObj, referedNode, xmlText){
											// if this page is an index list
											sourceUrl = classBehaviour.utilities.previousNode(referedNode).href;
											if(xmlText.indexOf('templates index')>-1 && xmlText.indexOf('<body>')>-1){
												// process the html to add a window opener
												sourceBaseUrl = sourceUrl.replace('/index.html', '');
												importedHtml = xmlText.split('<body>')[1].split('</body>')[0].replace(/href="./gi, 'href="' + sourceBaseUrl);
												// paste the html in place of the progress indicator
												referedNode.getElementsByTagName('div')[0].innerHTML = importedHtml;
											// else open the link normally
											}else{
												document.location.href = classBehaviour.utilities.previousNode(referedNode).href;
											}
										}
				// events
				this.clickItem		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var pfl = classBehaviour.portfolioList;
											// if the list has not been filled earlier
											if(classBehaviour.utilities.nextNode(objNode)==objNode){
												// construct the list holder
												newDiv = document.createElement('div');
												newDiv.className = 'popUp hideThisNode';
												newBorder = document.createElement('div');
												newBorder.className = 'popUpBorder';
												newTitle = document.createElement('h1');
												newText = document.createTextNode('loading...');
												// show the list holder with a progress indicator
												newTitle.appendChild(newText);
												newBorder.appendChild(newTitle);
												newDiv.appendChild(newBorder);
												objNode.parentNode.appendChild(newDiv);
												// start the loading
												classBehaviour.ajax.addRequest(objNode.href, pfl.insertTheList, pfl.waitForList, null, classBehaviour.utilities.nextNode(objNode));
												// prepare the item for toggleNextNode
												objNode.className += 'toggleNextNode family_portfolio0';
												classBehaviour.toggleNextNode.start(objNode);
												classBehaviour.toggleNextNode.toggle(objNode);
											// else
											}else{
												// toggle the list item
												classBehaviour.toggleNextNode.toggle(objNode);
											}
											// cancel the click
											return false;
										}			}			// add this function to the classbehaviour object			classBehaviour.portfolioList = new PortfolioList;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.portfolioList;
			
		// Manages an artificial scroll bar
			// define this class behaviour			function ArtificialScrollBar(){				// properties				this.name 			= 	'artificialScrollBar';
				this.interaction	=	false;
				this.interactor		=	null;
				this.scrollInterval	=	null;
				this.index			=	0;
				// methods				this.start			=	function(node){
											// give the scrollbar an id if it doesn't have one
											node.id = (node.id) ? node.id : this.name + this.index++ ;
											// get the objects inside
											allDivs = node.getElementsByTagName('DIV');
											// disable the normal scrollbar
											node.style.overflow = 'hidden';
											// show the artificial scrollbar
											allDivs[allDivs.length-5].style.display = 'block';
											// set the canvas event handlers
											node.onmouseover = this.overCanvas;
											node.onmouseout = this.offCanvas;
											// set the detector events
											allDivs[allDivs.length-1].onmousedown = this.onDown;
											allDivs[allDivs.length-1].onmousemove = this.onDrag;
											allDivs[allDivs.length-1].ondrag = this.onDrag;
											document.onmouseup = this.onUp;
											node.onmousewheel = this.onWheel;
											if(window.addEventListener) window.addEventListener('DOMMouseScroll', this.onWheel, false);
											// set the button event handlers
											allDivs[allDivs.length-3].onmousedown = this.buttonDown;
											allDivs[allDivs.length-3].onmouseup = this.buttonOff;
											allDivs[allDivs.length-3].onmouseout = this.buttonOff;
											allDivs[allDivs.length-4].onmousedown = this.buttonUp;
											allDivs[allDivs.length-4].onmouseup = this.buttonOff;
											allDivs[allDivs.length-4].onmouseout = this.buttonOff;
											// start position
											setTimeout('classBehaviour.artificialScrollBar.moveTo(document.getElementById("'+node.id+'"), 0)', 100);
										}
				this.resize			=	function(rootNode){
											// get the required objects
											allDivs = rootNode.getElementsByTagName('DIV');
											contentNode = allDivs[0];
											indicatorNode = allDivs[allDivs.length-2];
										}
				this.moveTo			=	function(rootNode, position){
											// get the required objects
											allDivs = rootNode.getElementsByTagName('DIV');
											contentNode = allDivs[0];
											indicatorNode = allDivs[allDivs.length-2];
											// size the indicator
											contentToWindowRatio = contentNode.parentNode.offsetHeight / contentNode.offsetHeight;
											scrollBarHeight = indicatorNode.parentNode.offsetHeight;
											indicatorSize = contentToWindowRatio * scrollBarHeight;
											if(!isNaN(indicatorSize)) indicatorNode.style.height = Math.round(indicatorSize) + 'px';
											// if the page is longer than the canvas
											if(contentToWindowRatio<1){
												// set the indicator position
												indicatorSurplus = indicatorSize / 2;
												indicatorPosition = position - indicatorSurplus;
												if(position < indicatorSurplus) indicatorPosition = 0;
												if(indicatorPosition > scrollBarHeight-indicatorSize) indicatorPosition = scrollBarHeight-indicatorSize;
												if(!isNaN(indicatorPosition)) indicatorNode.style.top = Math.round(indicatorPosition) + 'px';
												// set the content position
												scrollBarFraction = (position - indicatorSurplus) / (scrollBarHeight - indicatorSurplus * 2);
												contentOverlap = contentNode.offsetHeight - contentNode.parentNode.offsetHeight;
												contentPosition = scrollBarFraction * contentOverlap;
												if(contentPosition<0) contentPosition = 0;
												if(contentPosition>contentOverlap) contentPosition = contentOverlap;
												if(!isNaN(contentPosition)) contentNode.style.top = Math.round(0 - contentPosition) + "px";
											}
										}
				this.moveBy			=	function(rootNode, distance){
											if(rootNode){
												// get the required objects
												allDivs = rootNode.getElementsByTagName('DIV');
												contentNode = allDivs[0];
												indicatorNode = allDivs[allDivs.length-2];
												// get the current scroll position
												indicatorPosition = (indicatorNode.style.top) ? parseInt(indicatorNode.style.top) : 0 ;
												indicatorSize = (indicatorNode.style.height) ? parseInt(indicatorNode.style.height) : 0 ;
												// set the new scroll position
												this.moveTo(rootNode, indicatorPosition+indicatorSize/2+distance);
											}
										}
				// events
				this.onDown			=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// activate the controls
											asb.interaction = true;
											// get the interaction location
											mouseY = (typeof(event)!='undefined' && navigator.userAgent.indexOf('Safari')<0) ? event.y : that.layerY ;
											// send the coordinates to the indicator
											asb.moveTo(objNode.parentNode.parentNode, mouseY);
											// cancel the click
											return false;
										}
				this.onDrag			=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// if the controls are active
											if(asb.interaction){
												// get the interaction location
												mouseY = (typeof(event)!='undefined' && navigator.userAgent.indexOf('Safari')<0) ? event.y : that.layerY ;
												// send the coordinates to the indicator
												asb.moveTo(objNode.parentNode.parentNode, mouseY);
												// cancel the click
												return false;
											}
										}
				this.onUp			=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// de-activate the controls
											asb.interaction = false;
											// cancel the click
											return false;
										}
				this.buttonUp		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// move the scroller 1 step up
											asb.moveBy(asb.interactor, -5);
											// set an interval
											asb.scrollInterval = setInterval("classBehaviour.artificialScrollBar.moveBy(classBehaviour.artificialScrollBar.interactor, -5)", 50);
											// cancel the click
											return false;
										}
				this.buttonDown		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// move the scroller 1 step down
											asb.moveBy(asb.interactor, 5);
											// set an interval
											asb.scrollInterval = setInterval("classBehaviour.artificialScrollBar.moveBy(classBehaviour.artificialScrollBar.interactor, 5)", 50);
											// cancel the click
											return false;
										}
				this.buttonOff		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// clear the scrolling interval
											clearInterval(asb.scrollInterval);
											// cancel the click
											return false;
										}
				this.onWheel		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// get the scroll distance
											distance = (window.event) ? window.event.wheelDelta/120 : -objNode.detail/3 ; 
											// scroll the page
											asb.moveBy(asb.interactor, -5*distance);
											// cancel the click
											return false;
										}
				this.overCanvas		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// store the object hovered over
											asb.interactor = objNode;
										}
				this.offCanvas		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var asb = classBehaviour.artificialScrollBar;
											// store the object hovered over
											asb.interactor = null;
										}			}			// add this function to the classbehaviour object			classBehaviour.artificialScrollBar = new ArtificialScrollBar;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.artificialScrollBar;
			
		// Use the longdesc url to display a tooltip
			// define this class behaviour			function LongdescToolTip(){				// properties				this.name 			= 	'longdescToolTip';
				// methods				this.start			=	function(node){
											// set the event handlers of the image
											node.onmouseover = this.overImage;
											node.onmouseout = this.offImage;
							//				node.onmousemove = this.moveImage;
										}
				this.waitForDesc	=	function(importProgress, referedNode){
											targetNode = classBehaviour.utilities.previousNode(referedNode);
											targetNode.innerHTML = 'loading: ' + Math.round(importProgress*100) + '%';
										}
				this.insertDesc		=	function(importedObj, referedNode, importedText){
											targetNode = classBehaviour.utilities.previousNode(referedNode);
											targetNode.innerHTML = importedText.split('<body>')[1].split('</body>')[0];;
										}
				// events
				this.overImage		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var ltt = classBehaviour.longdescToolTip;											// get the taget node
											targetNode = classBehaviour.utilities.previousNode(objNode);
											// if this node is an existing tooltip
											if(targetNode.nodeName=='DIV' && targetNode.className.indexOf(ltt.name)>-1){
												// show it												targetNode.style.visibility = 'visible';
											}else{
												// make a new one
												newToolTip = document.createElement('DIV');
												newToolTip.className = ltt.name;
												objNode.parentNode.insertBefore(newToolTip, objNode);
												// order it to be filled
												classBehaviour.ajax.addRequest(objNode.getAttribute('longdesc'), ltt.insertDesc, ltt.waitForDesc, null, objNode);
											}
										}
				this.offImage		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var ltt = classBehaviour.longdescToolTip;											// get the next node											targetNode = classBehaviour.utilities.previousNode(objNode);
											// if this node is an existing tooltip
											if(targetNode.nodeName=='DIV' && targetNode.className.indexOf(ltt.name)>-1){												// hide it
												targetNode.style.visibility = 'hidden';
											}
										}
				this.moveImage		=	function(that){
											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var ltt = classBehaviour.longdescToolTip;											// get the next node											targetNode = classBehaviour.utilities.previousNode(objNode);
											// if this node is an existing tooltip
											if(targetNode.nodeName=='DIV' && targetNode.className.indexOf(ltt.name)>-1){												targetNode.style.position = 'absolute';												targetNode.style.left = (typeof(that)!='undefined') ? (that.layerX) + 'px' : (event.x) + 'px' ;												targetNode.style.top = (typeof(that)!='undefined') ?  (that.layerY) + 'px' : (event.y) + 'px' ;
											}
										}			}			// add this function to the classbehaviour object			classBehaviour.longdescToolTip = new LongdescToolTip;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.longdescToolTip;
			
		// Replace a link to external content with the actual content
			// define this class behaviour			function InsertFromFile(){				// properties				this.name 			= 	'insertFromFile';
				// methods				this.start			=	function(node){
											// start loading
											classBehaviour.ajax.addRequest(node.getAttribute('href'), this.insert, this.wait, null, node);
										}
				this.wait			=	function(importProgress, referedNode){
											referedNode.innerHTML = 'loading: ' + Math.round(importProgress*100) + '%';
										}
				this.insert			=	function(importedObj, referedNode, importedText){
											// insert the content before the link
											newDiv = document.createElement('div');
											referedNode.parentNode.insertBefore(newDiv, referedNode);
											insertedNode = classBehaviour.utilities.previousNode(referedNode);
											insertedNode.innerHTML = importedText.split('<body>')[1].split('</body>')[0];
											// activate any classbehaviours in there
											classBehaviour.parser.parseNode(insertedNode);
											// remove the link
											removedNode = referedNode.parentNode.removeChild(referedNode);
										}			}			// add this function to the classbehaviour object			classBehaviour.insertFromFile = new InsertFromFile;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.insertFromFile;
			
		// this keeps a screen element fixed to the scrolling
			// define this class behaviour			function ScrollLock(){				// properties				this.name 		= 	'scrollLock';
				this.index		=	0;
				this.timeout	=	null;
				this.objects	=	new Array();				// methods				this.start		=	function(node){
										// give this node and id if there isn't any
										node.id = (node.id) ? node.id : this.name + this.index ;
										// store this scrolling object and its offset
										this.objects[this.objects.length] = node;
										// set the scolling event
										window.onscroll = this.scrolled;									}
				// events
				this.scrolled	=	function(that, noOffset){
										var slc = classBehaviour.scrollLock;
										// clear the timeout on this function
										clearTimeout(classBehaviour.scrollLock.timeout);
										// for all scrolling objects
										for(var a=0; a<slc.objects.length; a++){
											// get the scrolling object
											scrollingObject = slc.objects[a];
											// get the scrolling offset
											offset = Math.round(classBehaviour.utilities.getClassParameter(scrollingObject, 'offset', '0'));
											// get the scrolling position
											scrollPos = document.documentElement.scrollTop;
											// reposition the scrolling object
											availableHeight = (window.innerHeight) ? window.innerHeight : document.documentElement.clientHeight ;
											if(scrollPos>=offset && scrollingObject.offsetHeight<availableHeight){
												scrollingObject.style.position = (navigator.appVersion.indexOf('MSIE 6')<0) ? 'fixed' : 'absolute' ;
												scrollingObject.style.marginTop = (navigator.appVersion.indexOf('MSIE 6')<0) ? (-1*offset) + 'px' : (scrollPos-offset) + 'px' ;
											}else{
												scrollingObject.style.position = 'relative';
												scrollingObject.style.marginTop = '0px';
											}
										}
										// order this function to run one last time after scrolling stops
										if(!noOffset) classBehaviour.scrollLock.timeout = setTimeout('classBehaviour.scrollLock.scrolled(null, true);', 128);
									}			}			// add this function to the classbehaviour object			classBehaviour.scrollLock = new ScrollLock;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.scrollLock;
	
		// scroll a list of options			// define this class behaviour			function ScrollList(){				// properties				this.name 		= 	'scrollList';				this.list		=	null;				this.focus		=	null;				this.speed		=	1;				this.idleTimer	=	null;				// methods				this.start		=	function(node){										// add the right event handler to the button										node.onmousedown = (classBehaviour.utilities.getClassParameter(node, 'scrollDirection', 'forward')=='backward') ? this.startBackward : this.startForward ;										node.onmouseover = this.cancel;										node.onmouseup = this.cancel;										node.onmouseout = this.cancel;										// prepare the refered list										id = classBehaviour.utilities.getClassParameter(node, 'id', 'scrollList0');										this.prepareList(id);									}				// events				this.startBackward	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var sl = classBehaviour.scrollList;										// reset all scrolling										id = sl.reset(objNode);										// start the scrolling										sl.scrollBackward(id);									}				this.startForward	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var sl = classBehaviour.scrollList;										// reset all scrolling										id = sl.reset(objNode);										// start the scrolling										sl.scrollForward(id);									}				// methods				this.idle			=	function(id){											classBehaviour.scrollList.speed = 1;											classBehaviour.scrollList.scrollForward(id);										}				this.prepareList	=	function(id) {											scroller = document.getElementById(id);											// if this list has not been prepared before											if(scroller.className.indexOf('trippled')<0){												// copy the content twice												scrollList = scroller.getElementsByTagName('UL')[0];												scrollList.innerHTML += scrollList.innerHTML + scrollList.innerHTML;												// set the scroller halfway												var contentWidth = scrollList.offsetWidth;												scrollList.style.marginLeft = '-' + Math.round(contentWidth/3) + 'px';												// mark the list as prepared												scroller.className += ' trippled';												// start the idle scrolling												classBehaviour.scrollList.idle(id);											}										}				this.reset			=	function(that){											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;											var sl = classBehaviour.scrollList;											// clear the idle timer											clearTimeout(sl.idleTimer);											// stop the scrolling											clearTimeout(sl.timeout);											// reset the speed											sl.speed = 5;											// get the target id											id = classBehaviour.utilities.getClassParameter(objNode, 'id', 'scrollList0');											// pass the id back											return id;										}				this.cancel		=	function(that){											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;											var sl = classBehaviour.scrollList;											// clear the idle timer											clearTimeout(sl.idleTimer);											// stop the scrolling											clearTimeout(sl.timeout);											// release the focus											sl.focus = null;											// wait for a while, then start idle scrolling											id = classBehaviour.utilities.getClassParameter(objNode, 'id', 'scrollList0');											sl.idleTimer = setTimeout('classBehaviour.scrollList.idle("'+id+'")',2000);										}				this.scrollBackward	=	function(id){										var sl = classBehaviour.scrollList;										// how high is the container										var container = document.getElementById(id);										var borderWidth = container.offsetWidth;										// how heigh is the content										var content = container.getElementsByTagName('UL')[0];										var contentWidth = content.offsetWidth;										// where is the content										var contentScroll = (content.style.marginLeft) ? parseInt(content.style.marginLeft) : 0 ;										// if the contant can still move										loopPoint = 0										resetPoint = -1 * Math.round(contentWidth/3);										if(contentScroll<loopPoint){											// move it											content.style.marginLeft = (contentScroll + sl.speed) + 'px';										// reset it back to the starting position										}else{											content.style.marginLeft = (resetPoint - sl.speed) + 'px';										}										// next step										sl.timeout = setTimeout('classBehaviour.scrollList.scrollBackward("' + id + '")', 40);									}				this.scrollForward	=	function(id){										var sl = classBehaviour.scrollList;										// how high is the container										var container = document.getElementById(id);										var borderWidth = container.offsetWidth;										// how heigh is the content										var content = container.getElementsByTagName('UL')[0];										var contentWidth = content.offsetWidth;										// where is the content										var contentScroll = (content.style.marginLeft) ? parseInt(content.style.marginLeft) : 0 ;										// if the contant can still move										loopPoint = -2 * Math.round(contentWidth/3);										resetPoint = -1 * Math.round(contentWidth/3);										if(loopPoint<contentScroll){											// move it											content.style.marginLeft = (contentScroll - sl.speed) + 'px';										// reset it back to the starting position										}else{											content.style.marginLeft = (resetPoint - sl.speed) + 'px';										}										// next step										sl.timeout = setTimeout('classBehaviour.scrollList.scrollForward("' + id + '")', 40);									}			}			// add this function to the classbehaviour object			classBehaviour.scrollList = new ScrollList;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.scrollList;
	
		// handle ondrag events			// define this class behaviour			function DragAndDrop(){				// properties				this.name 		= 	'dragAndDrop';				this.node		=	null;				this.grid		=	new Coordinates(16,16);				this.minPos		=	new Coordinates();				this.maxPos		=	new Coordinates();				this.pickup		=	new Coordinates();				this.mouse		=	new Coordinates();				this.style		=	new Coordinates();				this.onMove	=	null;				// methods				this.start		=	function(node){										// event										node.onmousedown 			= this.pickUp;										document.onmouseup 			= this.dropDown;									//	document.onmousemove 		= this.moveAway;										node.onmousemove 			= this.moveAway;										// exctract the limits from the class parameters										this.grid.x	=	parseInt(classBehaviour.utilities.getClassParameter(node, 'gridX', null));										this.grid.y	=	parseInt(classBehaviour.utilities.getClassParameter(node, 'gridY', null));										this.minPos.x	=	parseInt(classBehaviour.utilities.getClassParameter(node, 'limitLeft', null));										this.minPos.y	=	parseInt(classBehaviour.utilities.getClassParameter(node, 'limitTop', null));										this.maxPos.x	=	parseInt(classBehaviour.utilities.getClassParameter(node, 'limitRight', null));										this.maxPos.y	=	parseInt(classBehaviour.utilities.getClassParameter(node, 'limitBottom', null));										// saved position										this.restore(node);									}				this.restore 	= 	function(objNode){
										/*										var strStyles, arrStyles;										// retrieve styles string										strStyles = classBehaviour.cookies.getCookie('dragAndDrop');															// were any styles recovered										if(strStyles!=null){											arrStyles = strStyles.split(',');											// does the stored positions match the object											if(arrStyles[0]==objNode.id && arrStyles.length>2){												objNode.style.left = arrStyles[1];												objNode.style.top = arrStyles[2];											}										}
										*/									}				this.store 		= 	function(objNode){
										/*										// store styles										classBehaviour.cookies.setCookie('dragAndDrop', objNode.id + ',' + objNode.style.left + ',' + objNode.style.top, null, '/', null, null);
										*/									}				// events				this.pickUp 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var dnd = classBehaviour.dragAndDrop;										// accept no new pickups before dropdown										if(dnd.pickupObj==null){											// store the object being picked up											dnd.node = objNode;											// store pickup location											dnd.pickup.x = (typeof(event)!='undefined') ? event.clientX : that.clientX ;											dnd.pickup.y = (typeof(event)!='undefined') ? event.clientY : that.clientY ;											dnd.pickup.z = (objNode.style.zIndex=='') ? objNode.style.zIndex : 0;											// default starting position if none was given											if(objNode.style.position!='absolute') objNode.style.position = 'absolute';											if(objNode.style.left=='') objNode.style.left = /*dnd.pickup.x +*/ '0px'; 											if(objNode.style.top=='') objNode.style.top = /*dnd.pickup.y +*/ '0px';											// promote z position											objNode.style.zIndex = 1024;										}										// cancel browser mouse handler										return false;									}				this.dropDown 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var dnd = classBehaviour.dragAndDrop;										// only if a pickup is active										if(dnd.node!=null){											// snap coordinates to grid											if(dnd.grid.x>0) dnd.node.style.left = Math.round(parseInt(dnd.node.style.left)/dnd.grid.x)*dnd.grid.x + "px";											if(dnd.grid.y>0) dnd.node.style.top = Math.round(parseInt(dnd.node.style.top)/dnd.grid.y)*dnd.grid.y + "px";											// restore z position											dnd.node.style.zIndex = dnd.pickup.z;											// store the position in a cookie											dnd.store(dnd.node);											// release the picked up object											dnd.node = null;											// clear pickup location											dnd.pickup.x = null;											dnd.pickup.y = null;											dnd.pickup.z = null;										}										// cancel browser mouse handler										return false;									}				this.moveAway 	= 	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										var dnd = classBehaviour.dragAndDrop;										// only if a pickup is active										if(dnd.node!=null){											// mouse position											dnd.mouse.x = (typeof(event)!='undefined') ? event.clientX : that.clientX ;											dnd.mouse.y = (typeof(event)!='undefined') ? event.clientY : that.clientY ;											// current object position											dnd.style.x = (dnd.node.style.left.indexOf('px')<0) ? 0 : parseInt(dnd.node.style.left) ;											dnd.style.y = (dnd.node.style.top.indexOf('px')<0) ? 0 : parseInt(dnd.node.style.top) ;											// calculate new object position											var newXpos = dnd.style.x + dnd.mouse.x - dnd.pickup.x;											var newYpos = dnd.style.y + dnd.mouse.y - dnd.pickup.y;											// limit new object position											if(newXpos<dnd.minPos.x) newXpos = dnd.minPos.x;											if(newXpos>dnd.maxPos.x) newXpos = dnd.maxPos.x;											if(newYpos<dnd.minPos.y) newYpos = dnd.minPos.y;											if(newYpos>dnd.maxPos.y) newYpos = dnd.maxPos.y;											// apply new object position											if(dnd.pickup.x!=null) dnd.node.style.left = newXpos + 'px';											if(dnd.pickup.y!=null) dnd.node.style.top = newYpos + 'px';											// update pickup location											dnd.pickup.x = dnd.mouse.x;											dnd.pickup.y = dnd.mouse.y;											// execute custom event handler											if(dnd.onMove!=null) dnd.onMove(dnd.node);										}										// cancel browser mouse handler										return false;									}			}				function Coordinates(x,y,z){					this.x = x;					this.y = y;					this.z = z;				}			// add this function to the classbehaviour object			classBehaviour.dragAndDrop = new DragAndDrop;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.dragAndDrop;
	
		// handle the mouseclicks of a slider
			// define this class behaviour			function ValueSlider(){				// properties				this.name 		= 	'valueSlider';
				this.active		=	false;				// methods				this.start		=	function(node){
										// get the cover layer
										sliderCover = node.getElementsByTagName('div')[1];
										sliderCover.onmousedown = this.onDown;
										sliderCover.onmouseup = this.onUp;
										sliderCover.onmousemove = this.onMove;
										sliderCover.onmouseout = this.onUp;
										// get the form element
										sliderInput = classBehaviour.utilities.nextNode(node);
										sliderInput.onchange = this.onTyped;									}
				this.setSlider	=	function(rootNode, sliderSize, inputValue){
										// get the minimum value
										minimumValue = parseInt(classBehaviour.utilities.getClassParameter(rootNode, 'min', 0));
										// get the maximum value
										maximumValue = parseInt(classBehaviour.utilities.getClassParameter(rootNode, 'max', 100));
										// get the maximum size of the slider
										maximumSize = rootNode.offsetWidth - 5;
										// calculate the missing size or value
										if(sliderSize==null) sliderSize = Math.round((inputValue - minimumValue) / maximumValue * maximumSize) ;
										if(inputValue==null) inputValue = Math.round(sliderSize / maximumSize * (maximumValue - minimumValue)) + minimumValue ;
										// normalize the values
										if(sliderSize<1) sliderSize = 1;
										if(sliderSize>maximumSize) sliderSize = maximumSize;
										if(inputValue<minimumValue) inputValue = minimumValue;
										if(inputValue>maximumValue) inputValue = maximumValue;
										// set the size of the slider
										rootNode.getElementsByTagName('div')[0].style.width = (sliderSize + 5) + 'px';
										// set the value of the input
										classBehaviour.utilities.nextNode(rootNode).value = inputValue;
										rootNode.getElementsByTagName('span')[0].innerHTML = inputValue;
									}
				// events
				this.onDown		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var vsl = classBehaviour.valueSlider;
										// get the mouse position
										mouseX = (typeof(event)!='undefined' && navigator.userAgent.indexOf('Safari')<0) ? event.x : that.layerX ;
										// set the value
										vsl.setSlider(objNode.parentNode, mouseX, null);
										// mark the function active
										vsl.active = true;
										// cancel the mouse dragging the layer off
										return false;
									}
				this.onUp		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var vsl = classBehaviour.valueSlider;
										// mark the function inactive
										vsl.active = false;
										// cancel the mouse dragging the layer off
										return false;
									}
				this.onMove		=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var vsl = classBehaviour.valueSlider;
										// if the function is marked active
										if(vsl.active){
											// get the mouse position
											mouseX = (typeof(event)!='undefined' && navigator.userAgent.indexOf('Safari')<0) ? event.x : that.layerX ;
											// set the value
											vsl.setSlider(objNode.parentNode, mouseX, null);
										}
										// cancel the mouse dragging the layer off
										return false;
									}
				this.onTyped	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var vsl = classBehaviour.valueSlider;
										// get the value
										sliderNode = classBehaviour.utilities.previousNode(objNode);
										inputValue = parseInt(objNode.value);
										// set the slider
										vsl.setSlider(sliderNode, null, inputValue);
									}			}			// add this function to the classbehaviour object			classBehaviour.valueSlider = new ValueSlider;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.valueSlider;
	
		// copy text to the clipboard
			// define this class behaviour			function CopyToClipboard(){				// properties				this.name 			= 	'copyToClipboard';
				// methods				this.start			=	function(node){
											node.onclick = this.copyContents;
										}
				// events				this.copyContents	=	function(that){										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;										// get the target content
										targetId = classBehaviour.utilities.getClassParameter(objNode, 'id', null);
										if(targetId!=null){
											targetNode = document.getElementById(targetId);
											targetValue = (targetNode.value) ?  targetNode.value : targetNode.innerHTML ;
											if(window.clipboardData){
												window.clipboardData.setData('text', targetValue);
											}else{
												// this doesn't work :(
											//	targetValue = document.selection.createRange();
											//	targetValue.execCommand("Copy");
											}
										}									}			}			// add this function to the classbehaviour object			classBehaviour.copyToClipboard = new CopyToClipboard;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.copyToClipboard;
	
		// replace the content of a section based on a select
			// define this class behaviour			function SelectContent(){				// properties				this.name 			= 	'selectContent';
				// methods				this.start			=	function(node){
											node.onchange = this.loadNew;
											// load the initial content
											this.loadNew(node);
										}
				// events				this.loadNew		=	function(that){											var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
											var sct = classBehaviour.selectContent;
											// get the url from the select
											newUrl = objNode.value;
											// get the refered target
											targetId = classBehaviour.utilities.getClassParameter(objNode, 'id', null);
											// load it
											if(targetId!=null && newUrl!='') classBehaviour.ajax.addRequest(newUrl, sct.insertNew, sct.waitForNew, null, document.getElementById(targetId));										}				this.waitForNew		=	function(loadStatus, loadReferer, loadError){											// post the status to the target area
											loadReferer.innerHTML = (loadStatus<0) ? 
																		'<dt class="selectContentProgress">Foutmelding: '+loadError+'%</dt>' : 
																		'<dt class="selectContentProgress">Bezig met inladen: '+Math.round(loadStatus*100)+'%</dt>';
																					}				this.insertNew		=	function(loadedXml, loadedReferer, loadedTxt){
											// make the content invisible
											classBehaviour.fader.setFade(loadedReferer, 0);											// replace the contents
											loadedReferer.innerHTML = loadedTxt.split('</root>')[0].split('<root>')[1]
											// apply their classbehaviours
											classBehaviour.parser.parseNode(loadedReferer);
											// reveal the contents
											classBehaviour.fader.fadeIn(loadedReferer.id, 10, 100);										}			}			// add this function to the classbehaviour object			classBehaviour.selectContent = new SelectContent;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.selectContent;
			
		// replace the content of a section based on a select
			// define this class behaviour			function LoadOpml(){				// properties				this.name 			= 	'loadOpml';
				// methods				this.start			=	function(node){
											// get the url
											xmlUrl = node.getElementsByTagName('input')[0].value;
											// load the file
											classBehaviour.ajax.addRequest(xmlUrl, this.insertNew, this.waitForNew, null, node);
										}
				// events				this.waitForNew		=	function(loadStatus, loadReferer, loadError){
											// debug(loadStatus)
										}				this.insertNew		=	function(loadedXml, loadedReferer, loadedTxt){
											var listHtml = '';
											// for all the nodes in the file
											allNodes = loadedXml.getElementsByTagName('outline');
											for(var a=0; a<allNodes.length; a++){
												// get the podcast url
												podUrl = allNodes[a].getAttribute('htmlUrl');
												// get the podcast rss feed
												podRss = allNodes[a].getAttribute('xmlUrl');
												// get the title
												podTitle = allNodes[a].getAttribute('text');
												// construct a link
												listHtml += '<li><a href="'+podUrl+'">'+podTitle+'</a>';
												listHtml += (podRss!='') ? ' - <a href="'+podRss+'" class="rss">rss</a></li>' : '</li>' ;
											}
											// insert the links in the list
											loadedReferer.innerHTML = '<ul>' + listHtml + '</ul>';
										}			}			// add this function to the classbehaviour object			classBehaviour.loadOpml = new LoadOpml;			classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.loadOpml;
