	//// BEGIN HEADER ////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////
	////                                                                                          ////
	////    SWFHANDLER CLASS.                                                                     ////
	////                                                                                          ////
	////    Copyright 2007, Jose Cao-Garcia                                                       ////
	////                                                                                          ////
	////    This software is licensed under the Creative Commons                                  ////
	////    Attribution-ShareAlike 2.5 License:                                                   ////
	////    <http://creativecommons.org/licenses/by-sa/2.5/legalcode>                             ////
	////                                                                                          ////
	////    HELP/INFO/DEVELOPER CONTACT: jose@jcao.com, http://jcao.com                           ////
	////                                                                                          ////
	//////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////
	////                                                                                          ////
	////    SWFHANDLER is a simple, powerful and lightweight JavaScript class that provides       ////
	////    support for flash deployment across all major/modern browsers (as well as Internet    ////
	////    Explorer) via W3C DOM and JavaScript. SWFHANDLER detects for the availability and     ////
	////    version of the shockwave flash plugin, It generates a pure-dom swf object that can    ////
	////    be inserted and manipulated via standard W3C DOM methods. In addition to detecting    ////
	////    the flash plugin and generating SWF objects, this script also provides object-level   ////
	////    support for javascript/flash interaction, via the Flash 'liveconnect' methods         ////
	////    provided by the shockwave flash browser plugin. Finally, this script provides a       ////
	////    flexible mechanism for serving alternate content to browsers with missing or          ////
	////    inadequate flash support. Although this class does not rely on string-based code      ////
	////    insertion by design, a method for markup extraction is provided--however, using       ////
	////    markup for string-based code insertion is recommended against, as it is vastly        ////
	////    inferior to dom based insertion.                                                      ////
	////                                                                                          ////
	//////////////////////////////////////////////////////////////////////////////////////////////////
	//// END HEADER //////////////////////////////////////////////////////////////////////////////////


	//// OBJECT CLASS FOR WORKING WITH SHOCKWAVE FLASH FILES
		function swfHandler() {
		// root for scope
			var root  = this;
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//// TEST FOR FLASH PLUGIN CONSERVATIVELY (RETURNS FALSE IF VERSION INDETERMINATE)           ////
		/////////////////////////////////////////////////////////////////////////////////////////////////
			var swfStr     = false;
			var swfValue   = false;
		// msie handholding requred ...
			if (typeof(ActiveXObject) != 'undefined') { 
				for (var loop = 0; loop < 50; loop++){
					try {
						var swfAxObj = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + loop);
						swfValue = loop;
					} catch(e) {  }
				}
		// for standards-based browsers:
			} else {
			    if (navigator.plugins && navigator.plugins.length > 0) {
					if (navigator.plugins['Shockwave Flash 2.0'])  { swfValue = 2; }
					if (navigator.plugins['Shockwave Flash'])      {
						swfStr = navigator.plugins['Shockwave Flash'].description;
						swfValue = swfStr.split('.')[0].substring(swfStr.split('.')[0].lastIndexOf(' '));
					}
				}
			}
		// set the revision value
			root.rev = swfValue;
		// include an override test
			if (document.location.href.indexOf('flash=false') != -1) { root.rev = false; }
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//// CREATES A BASIC SWF OBJECT, AND RETURNS IT                                              ////
		/////////////////////////////////////////////////////////////////////////////////////////////////
			root.movie = function(swfFile, swfWidth, swfHeight, revReq, altCont) {
			// create object and set attributes
				var swfObject   = document.createElement('object');
			// for standards-challenged browsers ...
				try {
					var embObject = document.createElement('embed');
						embObject = swfObject.appendChild(embObject);
				} catch (e) {
					swfObject = document.createElement('embed');
				}
			// handle fallback content if specified
				if (revReq) {
					if (root.rev == false || parseFloat(revReq) > parseFloat(root.rev)) {
						if (altCont) {
							if (typeof(altCont) == 'string')   {
								if ((/\.png$/.test(altCont)) || (/\.jpg$/.test(altCont)) || (/\.jpeg$/.test(altCont)) || (/\.gif$/.test(altCont))) {
								// alternate image content
									swfObject        = document.createElement('img');
									swfObject.src    = altCont;
									swfObject.width  = swfWidth;
									swfObject.height = swfHeight;
								} else if ((/\.html$/.test(altCont)) || (/\.htm$/.test(altCont)) || (/\.shtml$/.test(altCont)) || (/\.asp$/.test(altCont)) || (/\.aspx$/.test(altCont)) || (/\.php$/.test(altCont)) || (/^http/.test(altCont)) || (/^https/.test(altCont)) ) {
								// go to alternative location ...
									parent.location.replace(altCont);
								} else {
								// alternate textNode content
									swfObject = document.createTextNode(altCont);
								}
							} else {
								if (typeof(altCont) == 'function') {
								// assume alternate is function fired
									altCont();
								} else {
								// assume alternate dom content (hope for the best)
									swfObject = altCont;
								}
							}
						} else {
							swfObject.style.display = 'none';
						}
					}
				}
				if (swfObject) {
				// add a method for adding new parameters
					swfObject.setParam  = root.setParam;
				// add a method for removing parameters
					swfObject.killParam = root.killParam;
				// register liveconnect methods
					swfObject.getVar    = root.getVar;
					swfObject.setVar    = root.setVar;
					swfObject.goFrame   = root.goFrame;
					swfObject.pause     = root.pause;
					swfObject.play      = root.play;
					swfObject.rewind    = root.rewind;
					swfObject.loadMov   = root.loadMov;
				// add the basic object attributes/parameters
					swfObject.setParam('data', swfFile);
					swfObject.setParam('movie', swfFile);
					swfObject.setParam('src', swfFile);
					swfObject.setParam('width', swfWidth);
					swfObject.setParam('height', swfHeight);
					swfObject.setParam('swfLiveConnect', true);
					swfObject.setParam('quality', 'best');
					swfObject.setParam('type', 'application/x-shockwave-flash');
				// add a method for extracting object markup.
				// This should be a property, but can't be,
				// thanks to standards-challenged browsers.
					swfObject.markup   = root.getMarkup;
				}
			// return object
				return swfObject;
			}
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//// METHOD ADDS PARAMS/ATTRIBUTES TO AN SWF OBJECT.                                         ////
		/////////////////////////////////////////////////////////////////////////////////////////////////
			root.setParam = function(name, value, killRecursion) {
			// only perform this operation if this is is a flash movie
			// eg: ignore alt content returned for deficient flash support
				if (this.nodeName == 'OBJECT' || this.nodeName == 'EMBED') {
				//  remove preexisting params/attributes first ?
					this.killParam(name, true);
				// set attribute in initial object
					this.setAttribute(name, value);
				// handle child-embed support if there, exclude id to prevent screwing up dom
					if (this.hasChildNodes() && this.firstChild.nodeName.toLowerCase() == 'embed' && name != 'id') {
						this.firstChild.setAttribute(name, value);
					}
					if (this.nodeName != 'EMBED') {
					// add param within object tag
						var param = document.createElement('param');
							param.name  = name;
							param.value = value;
						var param = this.appendChild(param);
					}
				// handle id/name synchronization
					if ((name == 'id' || name == 'name') && !killRecursion) {
						this.setParam((name == 'id') ? 'name' : 'id', value, true);
					}
				}
			}
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//// METHOD REMOVES PARAMS/ATTRIBUTES FROM AN SWF OBJECT.                                    ////
		/////////////////////////////////////////////////////////////////////////////////////////////////
			root.killParam = function(name, killRecursion) {
			// only perform this operation if this is is a flash movie
			// eg: ignore alt content returned for deficient flash support
				if (this.nodeName == 'OBJECT' || this.nodeName == 'EMBED') {
				// remove attribute from initial object
					this.removeAttribute(name);
				// handle child-embed support if there, exclude id to prevent screwing up dom
					if (this.hasChildNodes() && this.firstChild.nodeName.toLowerCase() == 'embed' && name != 'id') {
						if (this.firstChild.hasAttribute(name)) { this.firstChild.removeAttribute(name) }
					}
				// remove param
					if (this.hasChildNodes()) {
						for (var loop = 0; loop < this.childNodes.length; loop++) {
							if (this.childNodes[loop].nodeName.toLowerCase() == 'param' && this.childNodes[loop].name == name) { this.removeChild(this.childNodes[loop]); }
						}
					}
				// handle id/name synchronization
					if ((name == 'id' || name == 'name') && !killRecursion) {
						this.killParam((name == 'id') ? 'name' : 'id', true);
					}
				}
			}
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//// SUPPORTS ACCESS TO THE OBJECT MARKUP. NOTE: STRING BASED INSERTION HAS MAJOR DRAWBACKS. ////
		/////////////////////////////////////////////////////////////////////////////////////////////////
			root.getMarkup =  function() {
				var tempDiv = document.createElement('div');
				var tempSwf = tempDiv.appendChild(this);
				var markup  = tempDiv.innerHTML;
				return markup;
			}
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//// METHODS PROVIDE WAYS TO INTERACT WITH YOUR SWF MOVIE VIA JAVASCRIPT. NO ICAB SUPPORT.   ////
		/////////////////////////////////////////////////////////////////////////////////////////////////
			// get value of a variable in a flash movie
			root.getVar = function(varName, swfMovie) {
				swfMovie = root.getObjRef(swfMovie) || this;
				try {
					return swfMovie.GetVariable(varName);
				} catch (e) { return false; }
			}
			// set value of a variable in a flash movie
			root.setVar = function(varName, varValue, swfMovie) {
				swfMovie = root.getObjRef(swfMovie) || this;
				try {
					swfMovie.SetVariable(varName, varValue);
				} catch (e) { return false; }
			}
			// go to a frame number (or label) in a flash movie
			root.goFrame = function(swfFrame, swfLayer, swfMovie) {
				try {
				swfMovie = root.getObjRef(swfMovie) || this;
					var movieLayer = (swfLayer) ? swfLayer : '_level0/';
					if (parseInt(swfFrame) == NaN) {
						swfMovie.TGotoLabel(movieLayer, swfFrame);
					} else {
						swfMovie.TGotoFrame(movieLayer, swfFrame);
					}
				} catch (e) { return false; }
			}
			// pause playback of a flash movie
			root.pause = function(swfLayer, swfMovie) {
				swfMovie = root.getObjRef(swfMovie) || this;
				try {
					var movieLayer = (swfLayer) ? swfLayer : '_level0/';
					swfMovie.TStopPlay(movieLayer);
				} catch (e) { return false; }
			}
			// resume playback of a flash movie
			root.play = function(swfLayer, swfMovie) {
				swfMovie = root.getObjRef(swfMovie) || this;
				try {
					var movieLayer = (swfLayer) ? swfLayer : '_level0/';
					swfMovie.TPlay(movieLayer);
				} catch (e) { return false; }
			}
			// rewind movie, reset variables
			root.rewind = function() {
				swfMovie = root.getObjRef(swfMovie) || this;
				try {
					swfMovie.Rewind();
				} catch (e) { return false; }
			}
			// load a separate flash movie into a layer of an existing movie
			// set 'newSwf' to false to unload a movie from a particular layer
			root.loadMov = function(layer, newSwf, swfMovie) {
				swfMovie = root.getObjRef(swfMovie) || this;
				if (!newSwf) { var newSwf = ''; }
				try {
					swfMovie.LoadMovie(layer, newSwf);
				} catch (e) { return false; }
			}
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//// SUPPORTS THE LIVECONNECT METHODS ABOVE WHEN USED WITH A SWF OBJECT THAT HAS BEEN ADDED  ////
		//// TO THE PAGE VIA STRING BASED MARKUP (obj.innerHTML or document.write()). THIS WILL NOT  ////
		//// WORK IN OMNIWEB, ICAB OR VERSIONS OF OPERA OLDER THAN 9. FOR THIS REASON, STRING BASED  ////
		//// INSERTION IS VASTLY INFERIOR TO DOM BASED INSERTION, AND IS NOT RECCOMMENDED.           ////
		/////////////////////////////////////////////////////////////////////////////////////////////////
			root.getObjRef = function(swfId) {
				var objRef = false;
				if (window.document[swfId])  { objRef = window.document[swfId]; }
				if (typeof(ActiveXObject) != 'undefined') {
					if (document.embeds && document.embeds[swfId]) { objRef =  document.embeds[swfId]; }
				} else {
					objRef = document.getElementById(swfId);
				}
				return objRef;
			}
		// if the browser doesn't support the movie method, don't indicate flash support,
		// as it does the user no benefit to try and insert a movie if they cant see it.
		// It is better to rely on the fallback content if root.movie is unsupported.
			try {
				var testMovie = root.movie('', 1, 1);
			} catch (e) {
				root.rev = false;
			}
		}

	// initialize swfHandler object
	var swf = new swfHandler();