ObjectTools = new function(){	 
	 
	this.classes = { 
		AlphaRollover : { 
			mixins: ["MouseEventElement", "OpacityElement"], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.onmouseout = function(e){ 
				 
				 
				 
					try{ 
						if(this.checkMouseOut(e)){ 
						EaseManager.createEase({ 
							subject:this, 
							getter:"getOpacity", 
							setter:"setOpacity", 
							end: 1, 
							seconds: 0.5, 
							allowFractions: true 
						}); 
						} 
					}catch(e){ 
						this.handleError("onmouseout",e,arguments); 
					}; 
				};	 
				this.onmouseover = function(e){ 
				 
				 
				 
					try{ 
						if(this.checkMouseOver(e)){ 
						EaseManager.createEase({ 
							subject:this, 
							getter:"getOpacity", 
							setter:"setOpacity", 
							beginning: 0.4, 
							end:0.8, 
							seconds: 1, 
							allowFractions: true 
						}); 
						} 
					}catch(e){ 
						this.handleError("onmouseover",e,arguments); 
					}; 
				}; 
			} 
		},  
		AnimationBroadcaster : { 
			mixins: [], 
			singleton: true, 
			domElement: false, 
			constructor: function(){ 
				 
				this.animationInterval = false; 
					 
				this.FRAME_RATE = 20; 
					 
				this.listeners = []; 
				 	 
				this.activateBroadcaster = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.setTimeout(this,"broadcast",Math.floor(1000/this.FRAME_RATE),true); 
					}catch(e){ 
						this.handleError("activateBroadcaster",e,arguments); 
					}; 
				};	 
				this.addListener = function(obj, functionName){ 
				 
				 
				 
					try{ 
						this.removeListener(obj,functionName); 
						this.listeners.push({obj:obj,functionName:functionName}); 
						if(!this.animationInterval) this.activateBroadcaster(); 
					}catch(e){ 
						this.handleError("addListener",e,arguments); 
					}; 
				};	 
				this.broadcast = function(){ 
				 
				 
				 
					try{ 
						for(var i=0; i<this.listeners.length; i++){ 
							this.listeners[i].obj[this.listeners[i].functionName]();	 
						} 
						 
					}catch(e){ 
						this.handleError("broadcast",e,arguments); 
					}; 
				};	 
				this.deactivateBroadcaster = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.clearTimeout(this,"broadcast"); 
						 
					}catch(e){ 
						this.handleError("deactivateBroadcaster",e,arguments); 
					}; 
				};	 
				this.removeListener = function(obj, functionName){ 
				 
				 
				 
					try{ 
						for(var i=0; i<this.listeners.length; i++){ 
							if(this.listeners[i].obj == obj && this.listeners[i].functionName == functionName){ 
								this.listeners.splice(i,1); 
								i--; 
							} 
						} 
						if(this.listeners.length==0) this.deactivateBroadcaster(); 
					}catch(e){ 
						this.handleError("removeListener",e,arguments); 
					}; 
				}; 
			} 
		},  
		Content : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						Layout.addListener(this,"onResize"); 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.onResize = function(s){ 
				 
				 
				 
					try{ 
						this.style.left = s.contentLeft+"px"; 
						 
						 
					}catch(e){ 
						this.handleError("onResize",e,arguments); 
					}; 
				}; 
			} 
		},  
		Ease : { 
			mixins: [], 
			singleton: false, 
			domElement: false, 
			constructor: function(){ 
				 
				this.easeParams = null; 
					 
				this.frameCounter = null; 
				 	 
				this.enterFrame = function(){ 
				 
				 
				 
					try{ 
						var easeParams = this.easeParams; 
						 
						//Figure out the end value (this may change from frame to frame). 
						var endValue; 
						if(easeParams.endObjectGetter){ 
							endValue = easeParams.endObject[easeParams.endObjectGetter](); 
						}else{ 
							endValue = easeParams.endObject[easeParams.endProperty]; 
						} 
						 
						endValue = parseFloat(endValue); 
						 
						//Figure out the current value. 
						var currentValue = easeParams.easeFunction( 
						this.frameCounter, 
						easeParams.beginning, 
						endValue-easeParams.beginning, 
						easeParams.frames 
						); 
						if(!easeParams.allowFractions) currentValue = Math.floor(currentValue); 
						if(easeParams.unit) currentValue += easeParams.unit; 
						 
						//Set the current value. 
						if(easeParams.setter){ 
						easeParams.subject[easeParams.setter](currentValue); 
						}else{ 
						easeParams.subject[easeParams.property] = currentValue; 
						} 
						 
						//Stop the ease if it >is that time. 
						if (this.frameCounter == easeParams.frames) { 
						EaseManager.removeEase(easeParams); 
						if (easeParams.callback) easeParams.callbackObject[easeParams.callback](); 
						} 
						 
						this.frameCounter++; 
						 
					}catch(e){ 
						this.handleError("enterFrame",e,arguments); 
					}; 
				};	 
				this.setParameters = function(easeParams){ 
				 
				 
				 
					try{ 
						this.easeParams = easeParams; 
						 
						//Set up the beginning value. 
						if(easeParams.beginning==undefined){ 
							if(easeParams.getter){ 
								easeParams.beginning = parseFloat(easeParams.subject[easeParams.getter]()); 
							}else{ 
								easeParams.beginning = parseFloat(easeParams.subject[easeParams.property]);	 
							} 
							if(!easeParams.beginning) easeParams.beginning = 0; 
						} 
						 
						//Set up the end object. 
						if(!easeParams.endObject){ 
							if(easeParams.endProperty){ 
								easeParams.endObject = easeParams.subject; 
							}else{ 
								easeParams.endObject = {endProperty:easeParams.end}; 
								easeParams.endProperty = "endProperty"; 
							} 
						} 
						 
						//Default callback object is the subject. 
						if(!easeParams.callbackObject) easeParams.callbackObject = easeParams.subject; 
						 
						//Default ease function is easeOutSine. 
						if(!easeParams.easeFunction) easeParams.easeFunction = EaseFunctions.easeOutSine; 
						 
						//Figure frames from seconds or set to default value. 
						if(!easeParams.frames){ 
							if(easeParams.seconds) easeParams.frames = Math.floor(easeParams.seconds*AnimationBroadcaster.FRAME_RATE); 
							else easeParams.frames = 16; 
						} 
						 
						//Set the subject to the beginning, in case it is not already there. 
						this.enterFrame(); 
					}catch(e){ 
						this.handleError("setParameters",e,arguments); 
					}; 
				}; 
			} 
		},  
		EaseFunctions : { 
			mixins: [], 
			singleton: true, 
			domElement: false, 
			constructor: function(){ 
			 	 
				this.easeInLinear = function(t, b, c, d){ 
				 
				 
				 
					try{ 
						if(t==d) return b+c; 
						return c*t/d+b; 
					}catch(e){ 
						this.handleError("easeInLinear",e,arguments); 
					}; 
				};	 
				this.easeInSine = function(t, b, c, d){ 
				 
				 
				 
					try{ 
						if(t==d) return b+c; 
						return -c*Math.cos(t/d*(Math.PI/2))+c+b; 
					}catch(e){ 
						this.handleError("easeInSine",e,arguments); 
					}; 
				};	 
				this.easeOutLinear = function(t, b, c, d){ 
				 
				 
				 
					try{ 
						if(t==d) return b+c; 
						return c*t/d+b; 
					}catch(e){ 
						this.handleError("easeOutLinear",e,arguments); 
					}; 
				};	 
				this.easeOutSine = function(t, b, c, d){ 
				 
				 
				 
					try{ 
						if(t==d) return b+c; 
						return c*Math.sin(t/d*(Math.PI/2))+b; 
					}catch(e){ 
						this.handleError("easeOutSine",e,arguments); 
					}; 
				}; 
			} 
		},  
		EaseManager : { 
			mixins: [], 
			singleton: true, 
			domElement: false, 
			constructor: function(){ 
				 
				this.eases = []; 
				 	 
				this.createEase = function(easeParams){ 
				 
				 
				 
					try{ 
						this.removeEase(easeParams); 
						var ease = ObjectTools.createFromClass("Ease"); 
						ease.setParameters(easeParams); 
						this.eases.push(ease); 
						AnimationBroadcaster.addListener(ease,'enterFrame'); 
						return ease; 
					}catch(e){ 
						this.handleError("createEase",e,arguments); 
					}; 
				};	 
				this.removeEase = function(easeParams){ 
				 
				 
				 
					try{ 
						for(var i=0; i<this.eases.length;i++){ 
							var ease = this.eases[i]; 
							//If the subject matches and either the property or setter matches, 
							//then remove the ease. 
							if(ease.easeParams.subject==easeParams.subject 
							   && ( 
							   easeParams.property && easeParams.property==ease.easeParams.property || 
							   easeParams.setter && easeParams.setter==ease.easeParams.setter 
							   ) 
							){ 
								AnimationBroadcaster.removeListener(ease,'enterFrame'); 
								this.eases.splice(i,1); 
								 
								//there should only ever be one ease to remove 
								break; 
							} 
						} 
					}catch(e){ 
						this.handleError("removeEase",e,arguments); 
					}; 
				}; 
			} 
		},  
		EventBroadcaster : { 
			mixins: [], 
			singleton: false, 
			domElement: false, 
			constructor: function(){ 
				 
				this.eventRegistry = {}; 
				 	 
				this.addListener = function(listenerObject, eventType){ 
				 
				 
				 
					try{ 
						if(!this.eventRegistry[eventType]) this.eventRegistry[eventType] = []; 
						this.eventRegistry[eventType].push(listenerObject); 
					}catch(e){ 
						this.handleError("addListener",e,arguments); 
					}; 
				};	 
				this.broadcast = function(eventType, eventObject){ 
				 
				 
				 
					try{ 
						if(this.eventRegistry[eventType]){ 
							for(var i=0;i<this.eventRegistry[eventType].length;i++){ 
								this.eventRegistry[eventType][i][eventType](eventObject); 
							} 
						} 
					}catch(e){ 
						this.handleError("broadcast",e,arguments); 
					}; 
				};	 
				this.removeListener = function(listenerObject, eventType){ 
				 
				 
				 
					try{ 
						if(this.eventRegistry[eventType]){ 
							for(var i=0; i<this.eventRegistry[eventType].length; i++) { 
								if(this.eventRegistry[eventType][i]==listenerObject) { 
								this.eventRegistry[eventType].splice(i,1); 
								} 
							} 
						} 
					}catch(e){ 
						this.handleError("removeListener",e,arguments); 
					}; 
				}; 
			} 
		},  
		Layout : { 
			mixins: ["EventBroadcaster"], 
			singleton: true, 
			domElement: false, 
			constructor: function(){ 
				 
				this.allowErrors = true; 
				 	 
				this.getSize = function(){ 
				 
				 
				 
					try{ 
						var s = {}; 
						 
						if (window.innerHeight) // all except Explorer 
						{ 
						    s.w = window.innerWidth-18; 
						    s.h = window.innerHeight; 
						} 
						else if (document.documentElement && document.documentElement.clientHeight) 
						// Explorer 6 Strict Mode 
						{ 
						    s.w = document.documentElement.clientWidth; 
						    s.h = document.documentElement.clientHeight; 
						} 
						else if (document.body) // other Explorers 
						{ 
						    s.w = document.body.clientWidth; 
						    s.h = document.body.clientHeight; 
						} 
						return s; 
						 
					}catch(e){ 
						this.handleError("getSize",e,arguments); 
					}; 
				};	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						window.onresize = function(){ 
							Layout.onResize(); 
						}; 
						window.onunload = function(){ 
							Layout.onUnload(); 
						}; 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.onResize = function(s){ 
				 
				 
				 
					try{ 
						var s = this.getSize(); 
						 
						//Set the params for the layout 
						s.contentWidth = 760; 
						s.contentLeft = Math.floor(Math.max((s.w-s.contentWidth)/2,0)); 
						 
						this.broadcast("onResize",s); 
						document.getElementsByTagName("body")[0].style.display = "block"; 
						 
					}catch(e){ 
						this.handleError("onResize",e,arguments); 
					}; 
				};	 
				this.onUnload = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.clearAllTimeouts(); 
						 
					}catch(e){ 
						this.handleError("onUnload",e,arguments); 
					}; 
				}; 
			} 
		},  
		Logger : { 
			mixins: [], 
			singleton: false, 
			domElement: false, 
			constructor: function(){ 
			 	 
				this.handleError = function(functionName, e, args){ 
				 
				 
				 
					if(false){ 
						 
					//The arguments object does not have a join method, even though it acts like an array.  It needs one. 
					args.join = [].join; 
					 
					var message = this.clazz+"."+functionName+"("+args.join(", ")+"): "+e.message+". "; //+line; 
					try{  
						console.log(message); 
					}catch(e){ 
						alert(message); 
					} 
					 
					} 
				};	 
				this.log = function(message){ 
				 
				 
				 
					try{ 
						message = this.clazz+": "+message; 
						try{  
							console.log(message); 
						}catch(e){ 
							var body = document.getElementsByTagName('body')[0]; 
							body.appendChild(document.createTextNode(message)); 
							body.appendChild(document.createElement('br')); 
						} 
						 
					}catch(e){ 
						this.handleError("log",e,arguments); 
					}; 
				};	 
				this.logFunctionCall = function(functionName, args){ 
				 
				 
				 
					//The arguments object does not have a join method, even though it acts like an array.  It needs one. 
					args.join = [].join; 
					 
					this.log(functionName+"("+args.join(", ")+")"); 
					 
				}; 
			} 
		},  
		Logo : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						if(!this.filters) this.style.backgroundImage = "url(resources/images/logo.png)"; 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				}; 
			} 
		},  
		Menubar : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
				 
				this.activatedButton = null; 
					 
				this.buttons = []; 
					 
				this.menubarIsActivated = false; 
					 
				this.menus = []; 
				 	 
				this.activateMenubar = function(button){ 
				 
				 
				 
					try{ 
						if(!this.menubarIsActivated){ 
							this.menubarIsActivated = true; 
							this.activatedButton = null; 
							this.setActivatedButton(button); 
						} 
						 
					}catch(e){ 
						this.handleError("activateMenubar",e,arguments); 
					}; 
				};	 
				this.deactivateMenubar = function(){ 
				 
				 
				 
					try{ 
						this.menubarIsActivated = false; 
						this.setActivatedButton(null); 
					}catch(e){ 
						this.handleError("deactivateMenubar",e,arguments); 
					}; 
				};	 
				this.onmouseout = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.setTimeout(this,"deactivateMenubar",1200); 
					}catch(e){ 
						this.handleError("onmouseout",e,arguments); 
					}; 
				};	 
				this.onmouseover = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.clearTimeout(this,"deactivateMenubar"); 
					}catch(e){ 
						this.handleError("onmouseover",e,arguments); 
					}; 
				};	 
				this.setActivatedButton = function(button){ 
				 
				 
				 
					try{ 
						if(this.activatedButton != button){ 
							this.activatedButton = button;	 
						 
							//Figure out which menus to keep. 
							var keepers = []; 
						 
							if(this.activatedButton){ 
						 
								TimeoutManager.clearTimeout(this.activatedButton.parentMenu,"hide"); 
						 
								//If the button has a submenu, show the menu, 
								//and mark the menu as a keeper. 
								if(this.activatedButton.submenu && this.menubarIsActivated){ 
									this.activatedButton.submenu.show(); 
									keepers.push(this.activatedButton.submenu); 
								} 
						 
								//If the button has a parent menu, mark the menu, 
								//and it's ancestors, as keepers. 
								var menu = this.activatedButton.parentMenu; 
								if(menu) do{ 
									keepers.push(menu); 
								}while(menu = menu.parentMenu); 
							} 
						 
							//Reset button backgrounds. 
							for(var i=0; i<this.buttons.length; i++){ 
								if(this.buttons[i]!=this.activatedButton){ 
									if(!ObjectTools.contains(this.buttons[i].submenu,keepers)){ 
										this.buttons[i].resetBackgroundColor(); 
									} 
								} 
							} 
						 
							//Hide the other menus. 
							for(var i=0; i<this.menus.length; i++){ 
								if(!ObjectTools.contains(this.menus[i],keepers)){ 
									//Do we need to get out of the way of another menu? 
									if(!this.activatedButton || this.activatedButton.submenu){ 
										//Hide the menu NOW. 
										this.menus[i].hide(); 
									}else{ 
										//Hide the menu in a little bit. 
										this.menus[i].hideLater(); 
									} 
								} 
							} 
						} 
						 
					}catch(e){ 
						this.handleError("setActivatedButton",e,arguments); 
					}; 
				}; 
			} 
		},  
		MenubarBackground : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			  
			} 
		},  
		MenuButton : { 
			mixins: ["MouseEventElement", "OpacityElement"], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						//Add to the buttons array. 
						Menubar.buttons.push(this); 
						//Assign the parentMenu property. 
						if(this.parentNode.className.indexOf('MenuCascading')!=-1){ 
						   this.parentMenu = this.parentNode; 
						} 
						//Register this button with the parent menu. 
						if(!this.parentNode.buttons) this.parentNode.buttons = []; 
						this.parentNode.buttons.push(this);	 
						 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.onclick = function(){ 
				 
				 
				 
					try{ 
						if(!this.href) Menubar.activateMenubar(this); 
					}catch(e){ 
						this.handleError("onclick",e,arguments); 
					}; 
				};	 
				this.onmouseover = function(e){ 
				 
				 
				 
					try{ 
						this.firstChild.setOpacity(0.8); 
						Menubar.setActivatedButton(this); 
						 
						 
					}catch(e){ 
						this.handleError("onmouseover",e,arguments); 
					}; 
				};	 
				this.resetBackgroundColor = function(){ 
				 
				 
				 
					try{ 
						this.firstChild.setOpacity(0.3); 
					}catch(e){ 
						this.handleError("resetBackgroundColor",e,arguments); 
					}; 
				}; 
			} 
		},  
		MenuButtonBackground : { 
			mixins: ["OpacityElement"], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			  
			} 
		},  
		MenuCascading : { 
			mixins: [], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.finishedHiding = function(){ 
				 
				 
				 
					try{ 
						this.style.display = 'none'; 
					}catch(e){ 
						this.handleError("finishedHiding",e,arguments); 
					}; 
				};	 
				this.getOpacity = function(){ 
				 
				 
				 
					try{ 
						return this.buttons[0].getOpacity(); 
					}catch(e){ 
						this.handleError("getOpacity",e,arguments); 
					}; 
				};	 
				this.hide = function(){ 
				 
				 
				 
					try{ 
						//is it already hidden? 
						if(this.style.display == 'none') return; 
						TimeoutManager.clearTimeout(this,"hide"); 
						this.style.zIndex = 0; 
						EaseManager.createEase({ 
							subject:this, 
							setter:'setOpacity', 
							getter:'getOpacity', 
							end:0, 
							allowFractions:true, 
							callbackObject:this, 
							callback:'finishedHiding' 
						}); 
						 
						 
					}catch(e){ 
						this.handleError("hide",e,arguments); 
					}; 
				};	 
				this.hideLater = function(){ 
				 
				 
				 
					try{ 
						//is it already hidden or hiding? 
						if(this.style.display == 'none' || TimeoutManager.getTimeout(this,"hide")) return; 
						TimeoutManager.setTimeout(this,"hide",1000); 
						 
						 
					}catch(e){ 
						this.handleError("hideLater",e,arguments); 
					}; 
				};	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						//Assign this to a button as it's submenu. 
						this.previousSibling.submenu = this; 
						//Add to the menus array. 
						Menubar.menus.push(this); 
						//Assign the parentMenu property. 
						if(this.parentNode.className.indexOf('MenuCascading')!=-1){ 
						   this.parentMenu = this.parentNode; 
						} 
						 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.setOpacity = function(opacity){ 
				 
				 
				 
					try{ 
						for(var i=0; i<this.buttons.length; i++){ 
							this.buttons[i].setOpacity(opacity); 
						} 
						 
						 
					}catch(e){ 
						this.handleError("setOpacity",e,arguments); 
					}; 
				};	 
				this.show = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.clearTimeout(this,"hide"); 
						this.style.zIndex = 1; 
						EaseManager.createEase({ 
							subject:this, 
							setter:'setOpacity', 
							getter:'getOpacity', 
							end:1, 
							allowFractions:true 
						}); 
						this.style.display = 'block'; 
						 
						 
					}catch(e){ 
						this.handleError("show",e,arguments); 
					}; 
				}; 
			} 
		},  
		MouseEventElement : { 
			mixins: [], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.checkMouseOut = function(event){ 
				 
				 
				 
					try{ 
						if (!event) var event = window.event; 
						if (!event){ 
							this.log("No event object available"); 
							return true; 
						} 
						var target = window.event ? event.srcElement : event.target; 
						 
						var relatedTarget = event.relatedTarget ? event.relatedTarget : event.toElement; 
						 
						while (relatedTarget && relatedTarget.nodeName != 'BODY'){ 
							if(relatedTarget==this) return false; 
							relatedTarget = relatedTarget.parentNode; 
						} 
						return true; 
						 
						 
					}catch(e){ 
						this.handleError("checkMouseOut",e,arguments); 
					}; 
				};	 
				this.checkMouseOver = function(event){ 
				 
				 
				 
					try{ 
						if (!event) var event = window.event; 
						var target = (window.event) ? event.srcElement : event.target; 
						var relatedTarget = (event.relatedTarget) ? event.relatedTarget : event.fromElement; 
						 
						while (relatedTarget && relatedTarget.nodeName != 'BODY'){ 
							if(relatedTarget==this) return false; 
							relatedTarget = relatedTarget.parentNode; 
						} 
						return true; 
						 
						 
					}catch(e){ 
						this.handleError("checkMouseOver",e,arguments); 
					}; 
				};	 
				this.getEventTarget = function(e){ 
				 
				 
				 
					try{ 
						//Credit Peter-Paul Koch 
						//quirksmode.org 
						var target; 
						if (!e) var e = window.event; 
						if (e.target) target = e.target; 
						else if (e.srcElement) target = e.srcElement; 
						if (target.nodeType == 3) // defeat Safari bug 
							target = target.parentNode; 
						return target; 
					}catch(e){ 
						this.handleError("getEventTarget",e,arguments); 
					}; 
				}; 
			} 
		},  
		ObjectTools : { 
			mixins: [], 
			singleton: true, 
			domElement: false, 
			constructor: function(){ 
			 	 
				this.contains = function(needle, haystack){ 
				 
				 
				 
					try{ 
						for(var i=0; i<haystack.length; i++){ 
							if(needle==haystack[i]) return true; 
						} 
						return false; 
						 
						 
					}catch(e){ 
						this.handleError("contains",e,arguments); 
					}; 
				};	 
				this.createDomElementFromClass = function(nodeName, className){ 
				 
				 
				 
					try{ 
						var e = document.createElement(nodeName); 
							e.className = className; 
							ObjectTools.mixIn(e,className); 
							if(e.init) e.init(); 
						return e; 
						 
					}catch(e){ 
						this.handleError("createDomElementFromClass",e,arguments); 
					}; 
				};	 
				this.createFromClass = function(name){ 
				 
				 
				 
					try{ 
						var c = this.classes[name]; 
						var o = new c.constructor(); 
						o.clazz = name; 
						for(var i=0; i<c.mixins.length; i++){ 
							this.mixIn(o,c.mixins[i]); 
						} 
						if(!o.log) this.mixIn(o,"Logger"); 
						return o; 
						 
					}catch(e){ 
						this.handleError("createFromClass",e,arguments); 
					}; 
				};	 
				this.getKeys = function(obj){ 
				 
				 
				 
					try{ 
						var keys = []; 
						for(key in obj){ 
							keys.push(key); 
						} 
						return keys; 
					}catch(e){ 
						this.handleError("getKeys",e,arguments); 
					}; 
				};	 
				this.hasKey = function(obj, key){ 
				 
				 
				 
					try{ 
						for(aKey in obj){ 
							if(aKey == key) return true; 
						} 
						return false; 
					}catch(e){ 
						this.handleError("hasKey",e,arguments); 
					}; 
				};	 
				this.init = function(){ 
				 
				 
				 
					var domMixins = []; 
					 
					var inits = []; 
					 
					for(var name in this.classes){ 
						var c = this.classes[name]; 
						//Find the singletons, instantiate or mix in to dom elements as appropriate. 
						if(c.singleton){ 
							if(c.domElement){ 
								var e = document.getElementById(name); 
								if(e){ 
									ObjectTools.mixIn(e,name); 
									window[name] = e; 
								} 
							}else{ 
								if(name!=this.clazz){ 
									window[name] = this.createFromClass(name); 
								} 
								 
							} 
							if(window[name] && window[name].init && name!=this.clazz) inits.push(window[name]); 
						}else{ 
							if(c.domElement){ 
								domMixins.push({ 
									name: name, 
									regex: new RegExp("^(.*? )?"+name+"( .*?)?$") 
								}); 
							}else{ 
								//Do nothing. 
							} 
						} 
					} 
					 
					//Scan the document and mix in classes based on class names. 
					var elements = document.getElementsByTagName("*"); 
					for(var i=0; i<elements.length; i++){ 
						var e = elements[i]; 
						if(e.className){ 
							for(var j=0; j<domMixins.length; j++){ 
								var mixin = domMixins[j]; 
								if(e.className.match(mixin.regex)){ 
									ObjectTools.mixIn(e,mixin.name); 
									if(e.init) inits.push(e); 
								} 
							} 
						} 
					} 
					 
					//Execute the inits 
					for(var i=0; i<inits.length; i++){ 
						inits[i].init(); 
					} 
					 
					 
					//Layout the display 
					Layout.onResize(); 
					 
				};	 
				this.mixIn = function(iceCream, cherries){ 
				 
				 
				 
					try{ 
						//Instantiate an object of the class if a class name is specified. 
						if(typeof cherries == "string") cherries = this.createFromClass(cherries); 
						 
						//Copy the properties from cherries to object. 
						for(name in cherries){ 
							if(iceCream[name]==undefined) iceCream[name] = cherries[name];	 
						} 
						return iceCream; 
					}catch(e){ 
						this.handleError("mixIn",e,arguments); 
					}; 
				}; 
			} 
		},  
		OpacityElement : { 
			mixins: [], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.getOpacity = function(){ 
				 
				 
				 
					try{ 
						var opacity; 
						if(this.filters){ 
							opacity = this.filters.item(0).opacity/100; 
						}else{ 
							opacity = parseInt(this.style.opacity); 
						} 
						 
						//if opacity is not explicitly set, then we assume  
						//there is full opacity as the browser would render it 
						if(typeof opacity != "number" || isNaN(opacity)) opacity=1; 
						 
						return opacity; 
					}catch(e){ 
						this.handleError("getOpacity",e,arguments); 
					}; 
				};	 
				this.setOpacity = function(opacity){ 
				 
				 
				 
					try{ 
						if(this.filters){ 
							this.filters.item(0).opacity = Math.floor(opacity*100);	 
						}else{ 
							this.style.opacity = opacity; 
						} 
						 
					}catch(e){ 
						this.handleError("setOpacity",e,arguments); 
					}; 
				}; 
			} 
		},  
		RemoteBoat : { 
			mixins: [], 
			singleton: false, 
			domElement: false, 
			constructor: function(){ 
			 	 
				this.getXMLHTTPRequest = function(){ 
				 
				 
				 
					try{ 
						var req = false; 
						// branch for native XMLHttpRequest object 
						if(window.XMLHttpRequest) { 
							try { 
								req = new XMLHttpRequest(); 
						    } catch(e) { 
								req = false; 
						    } 
						// branch for IE/Windows ActiveX version 
						} else if(window.ActiveXObject) { 
						   	try { 
						    	req = new ActiveXObject("Msxml2.XMLHTTP"); 
						  	} catch(e) { 
						    	try { 
						      		req = new ActiveXObject("Microsoft.XMLHTTP"); 
						    	} catch(e) { 
						      		req = false; 
						    	} 
							} 
						} 
						return req; 
					}catch(e){ 
						this.handleError("getXMLHTTPRequest",e,arguments); 
					}; 
				};	 
				this.sendRequest = function(params){ 
				 
				 
				 
					try{ 
						//The default callback object is this. 
						if(params.callbackObject==undefined) params.callbackObject = this; 
						 
						//Get the request and add mixins if proivided. 
						var request = this.getXMLHTTPRequest(); 
						if(params.mixin){ 
							ObjectTools.mixIn(request,params.mixin); 
						} 
						 
						//If an XML doc has been provided, serialize it. 
						if(typeof params.query == "object"){ 
							//For Gecko browsers. 
							if(params.query.xml) params.query = params.query.xml; 
							//For IE 
							else params.query = (new XMLSerializer()).serializeToString(params.query); 
						} 
						 
						//Prepare to handle the completed request. 
						request.onreadystatechange = function(){ 
							// only if request shows "loaded" 
							if (request.readyState == 4) { 
								// only if "OK" 
								if (request.status == 200) { 
									if(params.callback) params.callbackObject[params.callback](request); 
								} else { 
									alert("There was a problem executing the query: " + request.statusText); 
								} 
							} 
						} 
						//Send the request. 
						request.open('POST',params.url,true); 
						 
						request.send(params.query);	 
					}catch(e){ 
						this.handleError("sendRequest",e,arguments); 
					}; 
				}; 
			} 
		},  
		ShoppingCart : { 
			mixins: ["RemoteBoat"], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
				 
				this.currentSyncId = null; 
					 
				this.items = {}; 
					 
				this.total = null; 
					 
				this.xml = null; 
				 	 
				this.addItem = function(name, quantity){ 
				 
				 
				 
					try{ 
						var productForm = document.forms['Product: '+name]; 
						 
						var attributes = ""; 
						var i=0; 
						var formField; 
						while(formField = productForm['attribute_'+i]){ 
							if(attributes.length==0) attributes = " ("; 
							else attributes += ", "; 
							attributes += formField.value; 
							i++; 
						} 
						 
						if(attributes.length>0) attributes += ")"; 
						 
						name = name+attributes; 
						 
						if(this.items[name]) this.items[name].quantity += quantity; 
						else { 
							var item = ObjectTools.createFromClass("ShoppingCartItem"); 
							item.name = name; 
							item.description = productForm.description.value; 
							item.price = parseFloat(productForm.price.value); 
							item.quantity = quantity; 
							this.items[name] = item; 
						} 
								 
						ShoppingCart.syncCart(); 
					}catch(e){ 
						this.handleError("addItem",e,arguments); 
					}; 
				};	 
				this.encryptAndSubmit = function(){ 
				 
				 
				 
					try{ 
						this.sendRequest({ 
							url: 'encrypted_cart.php', 
							query: this.getXml(), 
							callback:"encryptAndSubmitCallback" 
						}); 
					}catch(e){ 
						this.handleError("encryptAndSubmit",e,arguments); 
					}; 
				};	 
				this.encryptAndSubmitCallback = function(request){ 
				 
				 
				 
					try{ 
						var button = document.getElementById("shopping_cart_checkout_button_td"); 
						button.innerHTML = request.responseText; 
						button.firstChild.submit(); 
					}catch(e){ 
						this.handleError("encryptAndSubmitCallback",e,arguments); 
					}; 
				};	 
				this.getXml = function(){ 
				 
				 
				 
					try{ 
						//This is important for the first request, when we don't have the doc yet and we need to get one from the session (or get a new one). 
						if(!this.xml) return ""; 
										 
						var itemsNode = this.xml.documentElement.firstChild.firstChild; 
						 
						//clear out item nodes 
						while(itemsNode.firstChild){ 
						    itemsNode.removeChild(itemsNode.firstChild); 
						} 
						 
						//update the item nodes from items 
						for(var name in this.items){ 
							itemsNode.appendChild(this.items[name].createXml()); 
						} 
							 
						return this.xml; 
					}catch(e){ 
						this.handleError("getXml",e,arguments); 
					}; 
				};	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						this.syncCart(); 
						this.updateGoogleCheckoutButton(); 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.refreshView = function(){ 
				 
				 
				 
					try{ 
						//extract and sort the item names lexographically 
						var names = ObjectTools.getKeys(this.items).sort(); 
						 
						//get the site for the cart items 
						var tbody = document.getElementById("shopping_cart_items"); 
						 
						//make an object to reference rows by name 
						var itemRows = {}; 
						 
						//iterate all rows except the shipping row 
						for(var i=0; i<tbody.childNodes.length-1; i++){ 
							var tr = tbody.childNodes[i]; 
							if(ObjectTools.contains(names,tr.itemName)){ 
								//add the row to the rows object 
								itemRows[tr.itemName] = tr; 
							}else{ 
								//clear the old rows if they are not needed 
								tbody.removeChild(tr); 
								i--; 
							} 
						} 
								 
						//update rows or create new ones 
						for(var i=0; i<names.length; i++){ 
							var item = this.items[names[i]]; 
							 
							//is there one in the right position? 
							if(tbody.childNodes[i].itemName==item.name){ 
								tbody.childNodes[i].updateRow(item); 
							}else{ 
								//is there one in the wrong position? 
								if(ObjectTools.hasKey(itemRows,item.name)){ 
									//move it to the end 
									var tr = tbody.insertBefore(itemRows[item.name],tbody.lastChild); 
									tr.updateRow(item); 
								}else{ 
									//otherwise, create a new one 
									tbody.insertBefore(item.createRow(),tbody.lastChild); 
								} 
							} 
						} 
						 
						this.updateShippingAndTotal(); 
						 
					}catch(e){ 
						this.handleError("refreshView",e,arguments); 
					}; 
				};	 
				this.removeItem = function(name){ 
				 
				 
				 
					try{ 
						delete this.items[name];		 
						this.syncCart(); 
					}catch(e){ 
						this.handleError("removeItem",e,arguments); 
					}; 
				};	 
				this.saveCart = function(){ 
				 
				 
				 
					try{ 
						this.sendRequest({ 
							url: 'cart.php', 
							query: this.getXml() 
						}); 
					}catch(e){ 
						this.handleError("saveCart",e,arguments); 
					}; 
				};	 
				this.setXml = function(newXml){ 
				 
				 
				 
					try{ 
						this.xml = newXml; 
						 
						var itemNodes = this.xml.documentElement.firstChild.firstChild.childNodes; 
						 
						//parse into item objects 
						this.items = {}; 
						for(var i=0; i<itemNodes.length; i++){ 
							var itemNode = itemNodes[i]; 
							if(itemNode.nodeName == "item"){ 
								var item = ObjectTools.createFromClass("ShoppingCartItem"); 
								item.name = itemNode.childNodes[0].firstChild.nodeValue; 
								item.description = itemNode.childNodes[1].firstChild && 
									itemNode.childNodes[1].firstChild.nodeValue ? 
									itemNode.childNodes[1].firstChild.nodeValue : ""; 
								item.price = parseFloat(itemNode.childNodes[2].firstChild.nodeValue); 
								item.quantity = parseInt(itemNode.childNodes[3].firstChild.nodeValue);	 
								this.items[item.name] = item; 
							} 
						} 
						 
						this.refreshView(); 
						 
						 
					}catch(e){ 
						this.handleError("setXml",e,arguments); 
					}; 
				};	 
				this.syncCart = function(){ 
				 
				 
				 
					try{ 
						this.currentSyncId = new Date().getTime(); 
						this.sendRequest({ 
							url: 'cart.php', 
							query: this.getXml(), 
							callback: "syncCartCallback", 
							mixin: {syncId: this.currentSyncId} 
						}); 
					}catch(e){ 
						this.handleError("syncCart",e,arguments); 
					}; 
				};	 
				this.syncCartCallback = function(request){ 
				 
				 
				 
					try{ 
						if(this.currentSyncId==request.syncId){ 
							this.setXml(request.responseXML); 
						} 
					}catch(e){ 
						this.handleError("syncCartCallback",e,arguments); 
					}; 
				};	 
				this.updateGoogleCheckoutButton = function(){ 
				 
				 
				 
					try{ 
						this.sendRequest({ 
							url: 'encrypted_cart.php', 
							query: this.getXml(), 
							callback:"updateGoogleCheckoutButtonCallback" 
						}); 
					}catch(e){ 
						this.handleError("updateGoogleCheckoutButton",e,arguments); 
					}; 
				};	 
				this.updateGoogleCheckoutButtonCallback = function(request){ 
				 
				 
				 
					try{ 
						var button = document.getElementById("shopping_cart_checkout_button_td"); 
						button.innerHTML = request.responseText; 
					}catch(e){ 
						this.handleError("updateGoogleCheckoutButtonCallback",e,arguments); 
					}; 
				};	 
				this.updateQuantity = function(name, quantity){ 
				 
				 
				 
					try{ 
						this.items[name].quantity = quantity; 
							 
						this.syncCart(); 
					}catch(e){ 
						this.handleError("updateQuantity",e,arguments); 
					}; 
				};	 
				this.updateShippingAndTotal = function(){ 
				 
				 
				 
					try{ 
						this.total = 0; 
						for(var name in this.items) this.total += this.items[name].getTotal(); 
						 
						var zip = parseInt(document.getElementById("zip_input").value); 
						if(zip){		 
							//update the shipping row, then the total 
							this.sendRequest({ 
								url: "shipping.php?zip="+zip, 
								callback: "updateShippingAndTotalCallback" 
							}); 
						}else{ 
							//just update the total 
							document.getElementById("shipping_cost_td").firstChild.nodeValue = "?"; 
							document.getElementById("shopping_cart_total_div").firstChild.nodeValue = "Total: $"+this.total+" + shipping"; 
						} 
					}catch(e){ 
						this.handleError("updateShippingAndTotal",e,arguments); 
					}; 
				};	 
				this.updateShippingAndTotalCallback = function(request){ 
				 
				 
				 
					try{ 
						//get the shipping price for all three options 
						var rates = eval(request.responseText); 
						var shippingCost = rates["Priority Mail"]; 
						 
						if(isNaN(shippingCost)){ 
							document.getElementById("shipping_cost_td").firstChild.nodeValue = "?"; 
							document.getElementById("shopping_cart_total_div").firstChild.nodeValue = "Total: $"+this.total+" + shipping"; 
						}else{ 
							document.getElementById("shipping_cost_td").firstChild.nodeValue = shippingCost; 
							document.getElementById("shopping_cart_total_div").firstChild.nodeValue = "Total: $"+(this.total+shippingCost); 
						} 
						 
						 
					}catch(e){ 
						this.handleError("updateShippingAndTotalCallback",e,arguments); 
					}; 
				}; 
			} 
		},  
		ShoppingCartItem : { 
			mixins: [], 
			singleton: false, 
			domElement: false, 
			constructor: function(){ 
				 
				this.description = null; 
					 
				this.name = null; 
					 
				this.ounces = null; 
					 
				this.pounds = null; 
					 
				this.price = null; 
					 
				this.quantity = null; 
				 	 
				this.createRow = function(){ 
				 
				 
				 
					try{ 
						var item = this; 
						var e = document.createElement("tr"); 
							e.itemName = this.name; 
							e = e.appendChild(document.createElement("td")); 
								e = e.appendChild(document.createElement("a")); 
									e.href=item.name.replace(/ *?\(.*?\)/g,"").replace(/\W/g,"_")+"_detail.html"; 
									e.appendChild(document.createTextNode(item.name)); 
								e = e.parentNode; 
							e = e.parentNode; 
							e = e.appendChild(document.createElement("td")); 
								e.appendChild(document.createTextNode(item.price)); 
							e = e.parentNode; 
							e = e.appendChild(document.createElement("td")); 
								e = e.appendChild(ObjectTools.createDomElementFromClass("input","ShoppingCartQuantityInput")); 
									e.value = item.quantity; 
									e.itemName = item.name; 
									var quantityInput = e; 
								e = e.parentNode; 
							e = e.parentNode; 
							e = e.appendChild(document.createElement("td")); 
								var totalTextNode = e.appendChild(document.createTextNode(item.getTotal())); 
							e = e.parentNode; 
							e = e.appendChild(document.createElement("td")); 
								e = e.appendChild(ObjectTools.createDomElementFromClass("img","ShoppingCartRemoveButton")); 
									e.itemName = item.name; 
								e = e.parentNode; 
							e = e.parentNode; 
							e.updateRow = function(newItem){ 
								item = newItem; 
								if(quantityInput.getValue()!=item.quantity){ 
									quantityInput.value = item.quantity; 
								} 
								totalTextNode.nodeValue = item.getTotal(); 
							} 
						return e; 
						 
						 
					}catch(e){ 
						this.handleError("createRow",e,arguments); 
					}; 
				};	 
				this.createXml = function(){ 
				 
				 
				 
					try{ 
						var xml = ShoppingCart.xml; 
						var e = xml.createElement('item'); 
							e = e.appendChild(xml.createElement('item-name')); 
								e.appendChild(xml.createTextNode(this.name)); 
							e = e.parentNode; 
							e = e.appendChild(xml.createElement('item-description')); 
								e.appendChild(xml.createTextNode(this.description)); 
							e = e.parentNode; 
							e = e.appendChild(xml.createElement('unit-price')); 
								e.setAttribute("currency","USD"); 
								e.appendChild(xml.createTextNode(this.price)); 
							e = e.parentNode; 
							e = e.appendChild(xml.createElement('quantity')); 
								e.appendChild(xml.createTextNode(this.quantity)); 
							e = e.parentNode; 
							return e; 
						 
						 
					}catch(e){ 
						this.handleError("createXml",e,arguments); 
					}; 
				};	 
				this.getTotal = function(){ 
				 
				 
				 
					try{ 
						return this.price*this.quantity; 
					}catch(e){ 
						this.handleError("getTotal",e,arguments); 
					}; 
				}; 
			} 
		},  
		ShoppingCartQuantityInput : { 
			mixins: [], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
				 
				this.itemName = null; 
				 	 
				this.getValue = function(){ 
				 
				 
				 
					try{ 
						var value = parseInt(this.value); 
						return value?value:0; 
					}catch(e){ 
						this.handleError("getValue",e,arguments); 
					}; 
				};	 
				this.onkeyup = function(){ 
				 
				 
				 
					try{ 
						ShoppingCart.updateQuantity(this.itemName,this.getValue()); 
					}catch(e){ 
						this.handleError("onkeyup",e,arguments); 
					}; 
				}; 
			} 
		},  
		ShoppingCartRemoveButton : { 
			mixins: [], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						this.src = "resources/images/remove.gif"; 
						this.title = "Remove items from cart"; 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.onclick = function(){ 
				 
				 
				 
					try{ 
						ShoppingCart.removeItem(this.itemName); 
					}catch(e){ 
						this.handleError("onclick",e,arguments); 
					}; 
				}; 
			} 
		},  
		Slideshow : { 
			mixins: ["EventBroadcaster"], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
				 
				this.currentSlide = null; 
					 
				this.previousSlide = null; 
					 
				this.slideshowButtons = []; 
				 	 
				this.contract = function(){ 
				 
				 
				 
					try{ 
						Slideshow.easeImageHeight(320); 
						Slideshow.isExpanded = false; 
						if(SlideshowExpandButton) SlideshowExpandButton.firstChild.nodeValue = "[+] Expand"; 
						 
					}catch(e){ 
						this.handleError("contract",e,arguments); 
					}; 
				};	 
				this.easeImageHeight = function(newHeight){ 
				 
				 
				 
					try{ 
						EaseManager.createEase({ 
							subject:this, 
							getter:"getImageHeight", 
							setter:"setImageHeight", 
							end:newHeight 
						}); 
					}catch(e){ 
						this.handleError("easeImageHeight",e,arguments); 
					}; 
				};	 
				this.expand = function(){ 
				 
				 
				 
					try{ 
						this.easeImageHeight(510); 
						this.isExpanded = true; 
						if(SlideshowExpandButton) SlideshowExpandButton.firstChild.nodeValue = "[-] Collapse"; 
						 
					}catch(e){ 
						this.handleError("expand",e,arguments); 
					}; 
				};	 
				this.getImageHeight = function(){ 
				 
				 
				 
					try{ 
						return this.imageHeight; 
					}catch(e){ 
						this.handleError("getImageHeight",e,arguments); 
					}; 
				};	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						//init the image height, otherwise setSlide fails 
						this.imageHeight = 256; 
						 
						this.setSlide(0); 
						 
						if(document.slides.expanded && Layout.getSize().h>0){ 
							this.expand(); 
						}else{ 
							this.contract(); 
						} 
						 
						//start playing 
						if(document.slides.length>1) this.play(); 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.nextSlide = function(){ 
				 
				 
				 
					try{ 
						this.setSlide(this.currentSlide.slideNumber<document.slides.length-1?this.currentSlide.slideNumber+1 : 0); 
						 
						 
					}catch(e){ 
						this.handleError("nextSlide",e,arguments); 
					}; 
				};	 
				this.pause = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.clearTimeout(Slideshow,'nextSlide'); 
						this.broadcast("onPause"); 
						 
					}catch(e){ 
						this.handleError("pause",e,arguments); 
					}; 
				};	 
				this.play = function(){ 
				 
				 
				 
					try{ 
						TimeoutManager.setTimeout(this,'nextSlide',5000,true); 
						this.broadcast("onPlay"); 
						 
					}catch(e){ 
						this.handleError("play",e,arguments); 
					}; 
				};	 
				this.positionImage = function(){ 
				 
				 
				 
					try{ 
						this.currentSlide.img.style.top = ((this.imageHeight-512)*((this.currentSlide.position+100)/200))+"px"; 
						 
						 
					}catch(e){ 
						this.handleError("positionImage",e,arguments); 
					}; 
				};	 
				this.setImageHeight = function(height){ 
				 
				 
				 
					try{ 
						SlideshowImages.style.height = height+"px"; 
						Slideshow.style.height = height+"px"; 
						SlideshowControls.style.top = (height-24)+"px"; 
						this.imageHeight = height; 
						this.positionImage(); 
						 
					}catch(e){ 
						this.handleError("setImageHeight",e,arguments); 
					}; 
				};	 
				this.setSlide = function(slideNumber){ 
				 
				 
				 
					try{ 
						var slide = document.slides[slideNumber]; 
						 
						if(slide==this.currentSlide) return; 
						 
						this.previousSlide = this.currentSlide; 
						 
						this.currentSlide = slide; 
						 
						//Create the image or show the existing one. 
						if(!slide.img){ 
							slide.img = SlideshowImages.appendChild(document.createElement('img')); 
							ObjectTools.mixIn(slide.img,"SlideshowImage"); 
							slide.img.setOpacity(0); 
							this.addListener(slide.img,"slideChanged"); 
							slide.img.src = 'resources/image.php?name='+slide.filename+'&location=slideshow_images&width=768&height=768'; 
						}else{ 
							slide.img.show(); 
						} 
						 
						this.positionImage(); 
						 
						this.broadcast("slideChanged"); 
					}catch(e){ 
						this.handleError("setSlide",e,arguments); 
					}; 
				}; 
			} 
		},  
		SlideshowControls : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			  
			} 
		},  
		SlideshowExpandButton : { 
			mixins: ["AlphaRollover"], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.onclick = function(){ 
				 
				 
				 
					if(Slideshow.isExpanded) Slideshow.contract(); 
					else Slideshow.expand(); 
				}; 
			} 
		},  
		SlideshowFooter : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			  
			} 
		},  
		SlideshowImage : { 
			mixins: ["OpacityElement"], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.onload = function(){ 
				 
				 
				 
					try{ 
						if(Slideshow.currentSlide.img == this) this.show(); 
					}catch(e){ 
						this.handleError("onload",e,arguments); 
					}; 
				};	 
				this.show = function(){ 
				 
				 
				 
					try{ 
						this.style.display = "block"; 
						this.style.zIndex = 1; 
						EaseManager.createEase({ 
							subject:this, 
							getter:"getOpacity", 
							setter:"setOpacity", 
							beginning: 0, 
							end:1, 
							allowFractions: true 
						}); 
						 
					}catch(e){ 
						this.handleError("show",e,arguments); 
					}; 
				};	 
				this.slideChanged = function(){ 
				 
				 
				 
					try{ 
						if(Slideshow.previousSlide  
						&& Slideshow.previousSlide.img==this 
						&& Slideshow.currentSlide.img!=this){ 
							this.style.zIndex = 0; 
						} else  
						if(Slideshow.currentSlide.img!=this){ 
							this.setOpacity(0); 
							this.style.zIndex = 0; 
							this.style.display = "none"; 
							EaseManager.removeEase({ 
								subject:this, 
								setter:"setOpacity" 
							}); 
						} 
						 
					}catch(e){ 
						this.handleError("slideChanged",e,arguments); 
					}; 
				}; 
			} 
		},  
		SlideshowImages : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			  
			} 
		},  
		SlideshowNumberButton : { 
			mixins: [], 
			singleton: false, 
			domElement: true, 
			constructor: function(){ 
				 
				this.slideNumber = null; 
				 	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						Slideshow.addListener(this,"slideChanged"); 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.onclick = function(){ 
				 
				 
				 
					try{ 
						Slideshow.pause(); 
						Slideshow.setSlide(this.slideNumber); 
					}catch(e){ 
						this.handleError("onclick",e,arguments); 
					}; 
				};	 
				this.onmouseout = function(){ 
				 
				 
				 
					try{ 
						this.style.color = "#ffffff"; 
						 
						 
					}catch(e){ 
						this.handleError("onmouseout",e,arguments); 
					}; 
				};	 
				this.onmouseover = function(){ 
				 
				 
				 
					try{ 
						this.style.color = "#999999"; 
						 
						 
					}catch(e){ 
						this.handleError("onmouseover",e,arguments); 
					}; 
				};	 
				this.slideChanged = function(){ 
				 
				 
				 
					try{ 
						if(Slideshow.currentSlide.slideNumber == this.slideNumber){ 
							this.style.textDecoration = "underline"; 
						}else{ 
							this.style.textDecoration = "none"; 
						} 
						 
					}catch(e){ 
						this.handleError("slideChanged",e,arguments); 
					}; 
				}; 
			} 
		},  
		SlideshowNumberButtons : { 
			mixins: [], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
			 	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						 
						for(var i=0; i<document.slides.length; i++){ 
							//Create slideshow button. 
							var e = this.appendChild(ObjectTools.createDomElementFromClass("span","SlideshowNumberButton")); 
								e.slideNumber = i; 
								e.appendChild(document.createTextNode(i)); 
							e = e.parentNode; 
							e.appendChild(document.createTextNode(" ")); 
						} 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				}; 
			} 
		},  
		SlideshowPauseButton : { 
			mixins: ["SlideshowPlayButton"], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
				 
				this.mouseOverImage = "resources/images/pause_button_over.gif"; 
				 	 
				this.onclick = function(){ 
				 
				 
				 
					try{ 
						Slideshow.pause(); 
					}catch(e){ 
						this.handleError("onclick",e,arguments); 
					}; 
				};	 
				this.onPause = function(){ 
				 
				 
				 
					try{ 
						this.setOpacity(0.3); 
						this.isEnabled = false; 
					}catch(e){ 
						this.handleError("onPause",e,arguments); 
					}; 
				};	 
				this.onPlay = function(){ 
				 
				 
				 
					try{ 
						this.setOpacity(1); 
						this.isEnabled = true; 
					}catch(e){ 
						this.handleError("onPlay",e,arguments); 
					}; 
				}; 
			} 
		},  
		SlideshowPlayButton : { 
			mixins: ["OpacityElement"], 
			singleton: true, 
			domElement: true, 
			constructor: function(){ 
				 
				this.isEnabled = true; 
					 
				this.mouseOverImage = "resources/images/play_button_over.gif"; 
				 	 
				this.init = function(){ 
				 
				 
				 
					try{ 
						Slideshow.addListener(this,"onPause"); 
						Slideshow.addListener(this,"onPlay"); 
						this.onPlay(); 
						 
					}catch(e){ 
						this.handleError("init",e,arguments); 
					}; 
				};	 
				this.onclick = function(){ 
				 
				 
				 
					try{ 
						Slideshow.nextSlide(); 
						Slideshow.play(); 
					}catch(e){ 
						this.handleError("onclick",e,arguments); 
					}; 
				};	 
				this.onmouseout = function(){ 
				 
				 
				 
					try{ 
						this.src = this.mouseOutImage; 
					}catch(e){ 
						this.handleError("onmouseout",e,arguments); 
					}; 
				};	 
				this.onmouseover = function(){ 
				 
				 
				 
					try{ 
						this.mouseOutImage = this.src;		 
						if(this.isEnabled){ 
							this.src = this.mouseOverImage; 
						} 
					}catch(e){ 
						this.handleError("onmouseover",e,arguments); 
					}; 
				};	 
				this.onPause = function(){ 
				 
				 
				 
					try{ 
						this.setOpacity(1); 
						this.isEnabled = true; 
					}catch(e){ 
						this.handleError("onPause",e,arguments); 
					}; 
				};	 
				this.onPlay = function(){ 
				 
				 
				 
					try{ 
						this.setOpacity(0.3); 
						this.isEnabled = false; 
					}catch(e){ 
						this.handleError("onPlay",e,arguments); 
					}; 
				}; 
			} 
		},  
		TimeoutManager : { 
			mixins: [], 
			singleton: true, 
			domElement: false, 
			constructor: function(){ 
				 
				this.timeouts = []; 
				 	 
				this.clearAllTimeouts = function(){ 
				 
				 
				 
					try{ 
						while(this.timeouts.length){ 
							clearInterval(this.timeouts[0].id); 
							this.timeouts.splice(0,1); 
						} 
					}catch(e){ 
						this.handleError("clearAllTimeouts",e,arguments); 
					}; 
				};	 
				this.clearTimeout = function(obj, functionName){ 
				 
				 
				 
					try{ 
						for(var i=0; i<this.timeouts.length; i++){ 
							if(this.timeouts[i].obj==obj && this.timeouts[i].functionName==functionName){ 
								clearInterval(this.timeouts[i].id); 
								this.timeouts.splice(i,1); 
								i--; 
							} 
						} 
					}catch(e){ 
						this.handleError("clearTimeout",e,arguments); 
					}; 
				};	 
				this.getTimeout = function(obj, functionName){ 
				 
				 
				 
					try{ 
						var timeout = false; 
						for(var i=0; i<this.timeouts.length; i++){ 
							if(this.timeouts[i].obj==obj && this.timeouts[i].functionName==functionName){ 
								timeout = this.timeouts[i]; 
							} 
						} 
						return timeout; 
					}catch(e){ 
						this.handleError("getTimeout",e,arguments); 
					}; 
				};	 
				this.setTimeout = function(obj, functionName, time){ 
				 
				 
				 
					try{ 
						var repeat = arguments[3]; 
						var exists = false; 
						for(var i=0; i<this.timeouts.length; i++){ 
							if(this.timeouts[i].obj==obj && this.timeouts[i].functionName==functionName){ 
								exists = true; 
							} 
						} 
						if(!exists){ 
							var doFunction = function(){ 
								if(!repeat) TimeoutManager.clearTimeout(obj,functionName); 
								obj[functionName](); 
							} 
							this.timeouts.push({ 
								obj:obj, 
								functionName:functionName, 
								id: setInterval(doFunction,time) 
							}); 
						} 
					}catch(e){ 
						this.handleError("setTimeout",e,arguments); 
					}; 
				}; 
			} 
		} 
	};	 
}; 
 
//Set up the ObjectTools properly, and initialize. 
 
var o = new ObjectTools.classes.ObjectTools.constructor(); 
 
o.clazz = "ObjectTools"; 
 
for(name in o){ 
	if(ObjectTools[name]==undefined) ObjectTools[name] = o[name]; 
} 
 
var o = new ObjectTools.classes.Logger.constructor(); 
 
for(name in o){ 
	if(ObjectTools[name]==undefined) ObjectTools[name] = o[name]; 
} 
 
ObjectTools.init(); 
 
