var JQ = jQuery.noConflict();

// GLOBAL NIKEOS NAMESPACE
if (!window.NIKEOS) var NIKEOS = {};

/*
	SET THE SITE MODE
	10.30.08 - added localhost environment
*/
if (location.host.match(/inside-staging/i) || location.host.match(/ecn\d*-(www|nikeplus)/i)) {
	// don't want to include inside-staging b/c we are loading files from OS
	NIKEOS.osSubdomain = location.host.match(/ecn\d*-(www|nikeplus)/i) ? location.host.match(/ecn\d*-(www|nikeplus)/i)[0] : 'www';
	NIKEOS.site_mode = 'staging';
} else if (location.host.match(/nike\.com/i)) {
	NIKEOS.site_mode = 'prod';
} else if (location.host.match(/^[^\.]*$/i)) {
	NIKEOS.site_mode = 'localhost';
} else {
	NIKEOS.site_mode = 'dev';
}

NIKEOS.protocol = (location.protocol == 'https:') ? 'https://' : 'http://';
NIKEOS.currentURL = escape(location.href);

NIKEOS.hasSiteData = !!window.site_data;
NIKEOS.hasSettingsBaseUrl = false;

if (NIKEOS.hasSiteData) {
	NIKEOS.hasBaseUrl = !!window.site_data.base_url;
	NIKEOS.hasSettings = !!window.site_data.settings;
	if (NIKEOS.hasSettings) {
		NIKEOS.hasSettingsBaseUrl = !!window.site_data.settings.base_url;
	}
}

NIKEOS.BASE = {
	localhost : NIKEOS.protocol + location.host,
	dev : NIKEOS.protocol + (NIKEOS.siteHost || 'nike-dev4.ny.rga.com'),
	staging : NIKEOS.protocol + (NIKEOS.siteHost || (NIKEOS.hasBaseUrl ? site_data.base_url.substring(NIKEOS.protocol.length) : NIKEOS.hasSettingsBaseUrl ? site_data.settings.base_url.substring(NIKEOS.protocol.length) : NIKEOS.osSubdomain + '.nikeKISH.com')),
	prod : NIKEOS.protocol + 'www.nikeKISH.com'
};


NIKEOS.setDev = function(url) {
	NIKEOS.BASE.dev = NIKEOS.protocol + url;
};

NIKEOS.recheckSiteData = function() {
	return NIKEOS.hasSiteData = !!window.site_data;
}

NIKEOS.getLangLocale = function() {
	if (NIKEOS.hasSiteData) {
		if (window.site_data.platypus_region) {
			return window.site_data.platypus_region;
		} else if (window.site_data.lang_locale) {
			return window.site_data.lang_locale;
		}
	}
}

/*
	NIKEOS.log added 10.15.08
	Authors: Dale Tan [dt], Scott Kyle [sk]
	- method for displaying a console.log call on non-production environments
	08.20.09 - added ability to turn off logging [dt]
*/
if (typeof window.console == 'undefined') { var console = {}; console.log = function() { /*alert(console.log) */ }; }
NIKEOS.log = function() {
	var qs = window.location.search;
	var keys = qs.split('&');
	var keysLen = keys.length;
	var disable = false;
	for (var i = 0; i < keysLen; i++) {
		var left = keys[i].split('=')[0];
		var right = keys[i].split('=')[1] || '';
		if (left == 'disableLog') {
			disable = true;
			break;
		}
	}
	if (NIKEOS.site_mode != 'prod' && !disable) {
		console.log.apply(console, arguments);
	}
};

/*
	IMAGE PRELOADER
	Author: Scott Kyle [sk]
	- method accepts either a string or an array of strings (paths to imgs) and an optional callback as arguments
	10.10.08 - Added callback option that fires after all images have loaded
	10.24.08 - Fixed IE7 issue with setting image source
	01.21.09 - Now allows multiple calls to the method to not interfere with each other
*/

NIKEOS.preload = function(images, callback) {
	if (typeof images == 'string') images = [images];
	var $hidden = JQ('.hidden_content')[0] || JQ('<div class="hidden_content" />').css('display', 'none').appendTo('body');
	var $img = JQ('<img />').appendTo($hidden);
	
	function load() {
		if (images[0])
			$img.attr('src', images.shift());
		else {
			$img.remove();
			if (callback) callback();
		}
	};
	
	$img.bind('load', load);
	load();
};

/* END IMAGE PRELOADER */

/* 
	GLOBAL IMAGE SWAPPER 
	Authors: Dale Tan [dt], Scott Kyle [sk]
	- initial functionality worked for only one image.
	09.12.08 - added functionality for multiple images in one anchor block // dt
	03.09.09 - much simplified code now that I am beter at JS // sk
	09.13.10 - check for SMT styled srcs
	
	notes:
	jQuery is needed for this function to work correctly
	Default hover state and class name (both can be changed)
	<script type="text/javascript">
		NIKEOS.hover = '_on';
		NIKEOS.swap_class = 'swap_img';
	</script>
*/

NIKEOS.hover = NIKEOS.hover || '_on';
NIKEOS.swap_class = NIKEOS.swap_class || 'swap_img';

jQuery.fn.rollover = function(hover) {
	var imgs = [],
		ll = NIKEOS.getLangLocale();

	this.filter('img').each(function() {
		var src = this.src,
			hover = hover || NIKEOS.hover,
			overImg = (function() { // restructure the over image src if SMT based
				if ((/^\{smt\}_/i).test(hover)) {
					var check = new RegExp(ll),
						realHover = hover.split('_').pop(),
						srcSplit = src.split('/'),
						newSrc = srcSplit.pop(),
						tmpSrc = newSrc.replace(ll, realHover + '_' + ll);
					// format the array
					// - removes the protocol and the empty "" b/c of the split on a forward slash ("//" = "")
					srcSplit.shift();
					srcSplit.shift();
					over = NIKEOS.protocol + srcSplit.join('/') + '/' + tmpSrc;
				} else {
					over = src.replace(/\.(\w+)$/, hover + '.$1');
				}
				imgs.push(over);
				return over;
			})();
		
		JQ(this).hover(
			function() {
				this.src = overImg;
			},
			function() {
				this.src = src;
			}
		);
	});
	
	NIKEOS.preload(imgs);
	return this;
};

JQ(window).load(function() {
	NIKEOS.recheckSiteData(); // reinitiate site_data when NIKEOS.global.js is defined above window.site_data
	JQ('.' + NIKEOS.swap_class + ' img, img.' + NIKEOS.swap_class).rollover(NIKEOS.hover);
});

/* end GLOBAL IMAGE SWAPPER  */

/*
	QUERY PARAMETERS 
	Author: Scott Kyle [sk]
	- Pass a specific parameter or get an object with key-value pairs of the parameter and their values
	10.09.08 - v1 with decoding URI components
	12.02.08 - alias to getParam
*/

NIKEOS.getParams = function(param) {
	var search = document.location.search.slice(1);
	if (!search) return null;
	
	var result = {};
	var args = search.split("&");
	for (var i = 0, l = args.length; i < l; i++) {
		var keys = args[i].split("=");
		result[keys[0]] = decodeURIComponent(keys[1]) || '';
	}
	return param ? result[param] : result;
};
NIKEOS.getParam = NIKEOS.getParams;		// alias


/* END QUERY PARAMETERS */


/*
	GLOBAL SWF EMBEDDER
	Authors: Dale Tan [dt] & Scott Kyle [sk]
	09.26.08 - added footer blog enablement // dt
	10.06.08 - added NIKEOS.currentURL to call escape only once // sk
	10.27.08 - added option to set minimum version of flash // sk
	01.21.09 - removed use of $merge function // sk
	03.31.09 - added option to not apply CSS to swf parent // dt
*/

// lookup tables -- add more as needed
JQ.extend(true, NIKEOS, {
	PATHS : {
	    'video_player': 'http://www.nikeKISH.com//nikeos/global/modules/video/v1/',
	    'lockup': 'http://www.nikeKISH.com//nikeos/global/modules/nav/',
	    'nav': 'http://www.nikeKISH.com//nikeos/global/modules/nav/',
	    'enablement': 'http://www.nikeKISH.com//nikeos/global/modules/enablement/'
	},
	VIDEO_PLAYER : {
		versions : {
			'v1.1' : 'swf/video_player_v1_1.swf',
			'v1.2' : 'swf/video_player_v1_2.swf',
			'v2' : 'swf/video_player_v2_0.swf',
			'Prototype_Commerce' : 'swf/video_player_prototype_com.swf',
			'tracking.20090106' : 'swf/video_player_v2_0_b.swf',
			'latest' : 'swf/video_player_v2_0.swf'
		},
		vars : {
			currentUrl : NIKEOS.currentURL
		}
	},
	LOCKUP : {
		versions : {
			'v1' : 'v1/swf/nav-module-top.swf',
			'v1.2' : 'v1/swf/nav-module-top-1-2.swf',
			'v2' : 'v1/swf/nav-module-top-2.swf',
			'tracking.20090106' : 'v1/swf/nav-module-top-1-2_b.swf',
			'latest' : 'v1/swf/nav-module-top-1-2.swf'
		}
	},
	NAV : {
		versions : {
			'v1' : 'v1/swf/nav-module-menu.swf',
			'v1.1' : 'v1/swf/nav-module-menu-1-1.swf',
			'v1.2' : 'v1/swf/nav-module-menu-1-2.swf',
			'v1.3' : 'v1/swf/nav-module-menu-1-3.swf',
			'v2' : 'v1/swf/nav-module-menu-2.swf',
			'tracking.20090106' : 'v1/swf/nav-module-menu-1-2_b.swf',
			'latest' : 'v1/swf/nav-module-menu-1-2.swf'
		},
		vars : {
		    fontPath: NIKEOS.BASE[NIKEOS.site_mode] + 'http://www.nikeKISH.com//nikeos/global/modules/nav/v1/font/fontlibrary.swf',
			currentUrl : NIKEOS.currentURL
		}
	},
	ENABLEMENT : {
		versions : {
			'v1' : 'v1/swf/enablement-module.swf',
			'tracking.20090106' : 'v1/swf/enablement-module_b.swf',
			'latest' : 'v1/swf/enablement-module.swf'
		},
		vars : {
		    fontPath: NIKEOS.BASE[NIKEOS.site_mode] + 'http://www.nikeKISH.com//nikeos/global/modules/nav/v1/font/fontlibrary.swf',
			currentUrl : NIKEOS.currentURL
		}
	}
});

jQuery.fn.extend({
	insertSWF : function(options) {
		options.element_id = this.attr('id');
		NIKEOS.insertSWF(options);
	}
});

NIKEOS.insertSWF = function(options) {
	options = JQ.extend(true, {
		element_id : 'featured',
		type : '', 				// only four allowed: video_player | lockup | nav | enablement, 
								// optional properties: version, must not be used with src property
		version : 'latest', 	// either 'latest' or version number, #, not v#
								// required properties: type
		src : '', 				// full url or root relative url to swf, only used if not any of the options named in the type property
								// must not be used with type or version properties
		parentCSS: true,		// added option if swf parent needs to remove applied CSS
		flash : '9',
		width : '100%', 		// default video player width, adjust as needed
		height : '100%', 		// default video player height, adjust as needed
		queries : '',			// replaces vars and params that begin with this with the URL query parameter
		params: { 				// default params, can add more or overwrite 
			quality : 'best',
			scale : 'noscale',
			menu : 'false',
			wmode : 'transparent',
			allowScriptAccess : 'always'
		},
		vars : {}				// default vars, can add more or overwrite
	}, options);
	
	var $target = JQ('#' + options.element_id);
	
	function toCSS(prop) {
		return (typeof prop == 'string' && prop.match(/(%|px)$/)) ? prop : prop + 'px';
	}
	
	if (options.type != 'enablement' || options.parentCSS == false) {
		$target.css({
			width : toCSS(options.width),
			height : toCSS(options.height)
		});
	}
		
	if (typeof options.version != 'string')
		options.version = 'v' + options.version;
	
	if (!options.src)
		options.src = NIKEOS.BASE[NIKEOS.site_mode] + NIKEOS.PATHS[options.type] + NIKEOS[options.type.toUpperCase()].versions[options.version];
	
	if (window.tracking && !options.external)
		options.vars.trackerObject = tracking.flash(nav_tracker_obj);

	var so = new SWFObject(options.src, options.element_id + '_swf', options.width, options.height, options.flash);
	
	if (options.queries) {
		var regex = new RegExp('^' + options.queries + '(.+)');
		var params = NIKEOS.getParams() || {};
		JQ.each(['vars', 'params'], function(i, opt) {
			for (var name in options[opt]) {
				if (typeof options[opt][name] != 'string') continue;
				var matches = options[opt][name].match(regex);
				if (matches)  options[opt][name] = params[matches[1]] || '';
			}
		});
	}

	for (param in options.params)
		so.addParam(param, options.params[param]);
	
	if (options.type == 'video_player') {
		so.addParam('allowFullScreen', 'true');
	} else if (options.type == 'nav' || options.type == 'lockup') {
		so.addParam('salign', 'tl');
		options.vars = JQ.extend(true, NIKEOS.NAV.vars, options.vars);
	} else if (options.type == 'enablement') {
		so.addParam('salign', 'br');
		options.vars = JQ.extend(true, NIKEOS.ENABLEMENT.vars, options.vars);
	}
	
	for (var flashvar in options.vars) {
		so.addVariable(flashvar, options.vars[flashvar]);
	}
 	if (typeof site_data != 'undefined'){
		so.addVariable('site_data', escape(JSON.stringify(site_data)));
	}
	
	NIKEOS.log(options);

	var result = so.write(options.element_id);

	if (options.type == 'enablement') {
		$target.parent().css('position', 'relative');
		$target.find('object, embed').css({
			position : 'absolute',
			bottom : 0,
			right : 0
		});
	}

	return result;
};

// Trigger window scroll in Mac Firefox to fix fullscreen video player bug.
NIKEOS.triggerScroll = function() {
	window.scrollBy(0, 2);
	window.scrollBy(0, -2);
};

/* END GLOBAL SWF EMBEDDER */

/*
	stringify JSON obj - useful for passing into flash
	taken after the tracking.flash() method	
*/

NIKEOS.stringify = function(obj) {
	return escape(JSON.stringify(obj));
};

/*
	OBJECT EXTENDER AND USEFUL PROTOTYPES // LOS PROTOS
	Author: Scott Kyle [sk]
	- Extend method added to String, Number, Array, Function, RegExp, and Date to pass new methods as an object
	- Most prototypes are shamelessly stolen from MooTools (MIT License)
	10.06.08 - Added genericize and a check to make sure a method already defined is overwritten
	10.07.08 - Made this feature opt-in and you can pass key-value pairs of the objects you want to extend
*/

NIKEOS.extendNatives = function() {
	
	var objects = {'String' : String, 'Number' : Number, 'Array' : Array, 'Function' : Function, 'RegExp' : RegExp, 'Date' : Date};
	
	for (var name in objects) {
		objects[name].$family = { name : name.toLowerCase() };
		
		objects[name].extend = function(fns) {
			for (var fn in fns) {
				if (typeof fns[fn] == 'function') {
					if (!this.prototype[fn]) {
						this.prototype[fn] = fns[fn];
						this.genericize(fn);
					}
					else 
						NIKEOS.log('The method %s was not added to %s because it already exists', fn, $type(this));
				}
			}
			return this;
		};
		
		// genericize the method also - i.e. Array.each(array, fn, bind) rather than array.each(fn, bind)
		objects[name].genericize = function(fn) {
			if (!this[fn]) this[fn] = function() {
				var args = Array.prototype.slice.call(arguments);
				return this.prototype[fn].apply(args.shift(), args);
			};
			return this;
		};
	}
	
	// genericize builtin methods also (slightly modified from MooTools)
	(function(object, methods){
		for (var i = methods.length; i--; i) object.genericize(methods[i]);
		return arguments.callee;
	})
	(Array, ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice', 'toString', 'valueOf', 'indexOf', 'lastIndexOf'])
	(String, ['charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'replace', 'search', 'slice', 'split', 'substr', 'substring', 'toLowerCase', 'toUpperCase', 'valueOf']);
	
	
	String.extend({
		trim : function() {
			return this.replace(/^\s+|\s+$/g, '');
		},
		clean : function() {
			return this.replace(/\s+/g, ' ').trim();
		},
		toInt : function(base) {
			return parseInt(this, base || 10);
		},
		toFloat : function() {
			return parseFloat(this);
		},
		test : function(regex, params) {
			return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this);
		},
		contains : function(string, separator) {
			return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1;
		},
		toCSS : function() {
			return this.test(/(%|px)$/) ? this : this + 'px';
		},
		toPercent : function() {
			return this.toFloat().toPercent();
		},
		stripTags: function() {
			return this.replace(/<[^>]+>/gi, '');
		},
		capitalize: function(){
			return this.replace(/\b[a-z]/g, function(match) {
				return match.toUpperCase();
			});
		}
	});
	
	Number.extend({
		toCSS : function() {
			return this.round() + 'px';
		},
		limit : function(min, max) {
			return Math.min(max, Math.max(min, this));
		},
		round : function(precision) {
			precision = Math.pow(10, precision || 0);
			return Math.round(this * precision) / precision;
		},
		toFloat : function() {
			return parseFloat(this);
		},
		toInt : function(base) {
			return parseInt(this, base || 10);
		},
		toPercent : function() {
			return (this * 100).round();
		}
	});
	
	Array.extend({
		indexOf : function(item, from) {
			var len = this.length;
			for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) {
				if (this[i] === item) return i;
			}
			return -1;
		},
		contains : function(item, from) {
			return this.indexOf(item, from) != -1;
		},
		getLast : function() {
			return (this.length) ? this[this.length - 1] : null;
		},
		getRandom : function() {
			return (this.length) ? this[$random(0, this.length - 1)] : null;
		},
		shuffle : function() {
			for (var j, x, i = this.length; i; j = parseInt(Math.random() * i, 10), x = this[--i], this[i] = this[j], this[j] = x);
			return this;
		},
		empty : function() {
			this.length = 0;
			return this;
		},
		extend : function(array) {
			for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
			return this;
		},
		filter : function(fn, bind) {
			var results = [];
			for (var i = 0, l = this.length; i < l; i++) {
				if (fn.call(bind, this[i], i, this)) results.push(this[i]);
			}
			return results;
		},
		each : function(fn, bind) {
			for (var i = 0, l = this.length; i < l; i++)
				fn.call(bind, this[i], i, this);
			return this;
		},
		map : function(fn, bind) {
			var results = [];
			for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this);
			return results;
		},
		erase : function(item) {
			for (var i = this.length; i--; i) {
				if (this[i] === item) this.splice(i, 1);
			}
			return this;
		},
		flatten : function() {
			var array = [];
			for (var i = 0, l = this.length; i < l; i++) {
				var type = $type(this[i]);
				if (!type) continue;
				array = array.concat((type == 'array' || type == 'collection' || type == 'arguments') ? Array.flatten(this[i]) : this[i]);
			}
			return array;
		}
	});
	
	Function.extend({
		create : function(options) {
			var self = this;
			options = options || {};
			return function(event) {
				var args = options.arguments;
				args = (args != undefined) ? $splat(args) : Array.slice(arguments, 0);
				var returns = function(){
					return self.apply(options.bind || null, args);
				};
				if (options.delay) return setTimeout(returns, options.delay);
				if (options.periodical) return setInterval(returns, options.periodical);
				if (options.attempt) return $try(returns);
				return returns();
			};
		},
		pass : function(args, bind) {
			return this.create({arguments: args, bind: bind});
		},
		attempt : function(args, bind) {
			return this.create({arguments: args, bind: bind, attempt: true})();
		},
		bind : function(bind, args) {
			return this.create({bind: bind, arguments: args});
		},
		delay : function(delay, bind, args) {
			return this.create({delay: delay, bind: bind, arguments: args})();
		},
		periodical : function(interval, bind, args) {
			return this.create({periodical: interval, bind: bind, arguments: args})();
		},
		run : function(args, bind) {
			return this.apply(bind, $splat(args));
		}
	});
	
	(function(math) {
		var methods = {};
		math.each(function(name){
			if (!Number[name]) methods[name] = function() {
				return Math[name].apply(null, [this].concat($A(arguments)));
			};
		});
		Number.extend(methods);
	})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
};

/* END LOS PROTOS */



/* 
	Enablement functionality
*/

/* ARTICLE SHARE -- articleShare.js */ 
function articleShare(site,popUpUrl, title, description) {
  var repQ = /\?/;
  var encQ = '%3f';
  popUpUrl = popUpUrl.replace(repQ, encQ);
  
  switch (site) {
	case "digg":
		postPopUp('http://digg.com/remote-submit?phase=2&url=' + popUpUrl , 'digg', 'toolbar=0,status=0,height=450,width=650,scrollbars=yes,resizable=yes');
		break;
	case "delicious":
		postPopUp('http://del.icio.us/post?url=' + popUpUrl + '&title=' + title, 'delicious', 'toolbar=0,status=0,height=450,width=650,scrollbars=yes,resizable=yes');
		break;
	case "facebook":
		postPopUp('http://www.facebook.com/sharer.php?u=' + popUpUrl + '&t=' + title, 'facebook', 'toolbar=0,status=0,height=436,width=646,scrollbars=yes,resizable=yes');
		break;
	case "stumble":
		postPopUp('http://www.stumbleupon.com/submit?url=' + popUpUrl + '&title=' + title, 'stumble', 'toolbar=0,status=0,height=450,width=770,scrollbars=yes,resizable=yes');
		break;
	case "newsvine":
		postPopUp('http://www.newsvine.com/_tools/seed&save?u=' + popUpUrl + '&h=' + title, 'newsvine', 'toolbar=0,status=0,height=500,width=1000,scrollbars=yes,resizable=yes');
		break;			
	};
};

function postPopUp(url, name, params) {
	var win = window.open(url, name, params);
};

/* END ARTICLE SHARE */

/* EVENT BRIDGE -- eventbridge.js */
// EventBridge 
// v1.5
// 2009.04.22
if (!window.EventBridge) var EventBridge = new function(){
	if (!document.getElementById) return;
	
	var channel = "external";
	this.setChannel = function(name){
		channel = name;
	};
	this.getChannel = function(){
		return channel;
	};
	
	/*
	 * debugMode is used to send messages to a specifically named textarea/form.  
	 * If you would like to turn on debugging, call EventBridge.setMode("debug")
	 * and copy and paste the html below into your document
	 * <form name="eventbridge_debug_form">
			<textarea rows="20" cols="75" name="eventbridge_debug_txt" style="width:620"></textarea>
		</form>
	 */
	var mode = "normal";
	this.setMode = function(m){
		mode = m;
	};
	this.getMode = function(){
		return mode;
	};
	
	// Get a valid reference to Flash Object
	this.getFlash = function(movieName){
		if (navigator.appName.indexOf("Microsoft") != -1)
			return window[movieName];
		else
			return document[movieName];
	};
	
	var listeners = {};
	
	this.listeners = listeners;
	
	this.dispatchEvent = function(evtObj){
		
		// debug call
		var prefix = "dispatchEvent ";
		this.debug(prefix + "TYPE : " + evtObj.type + " DATA : " + evtObj.data);
		
		var type = evtObj.type;
		if (!listeners[type]) {
			//NIKEOS.log('UNABLE TO USE ', type);
			return;
		}
		for (var i in listeners[type]) {
			for (var j = 0, l = listeners[type][i].length; j < l; j++) {
				var target = listeners[type][i][j].target;
				var func = listeners[type][i][j].func;
				/**ADDED TRY CATCH TO SOLVE ISSUE CREATED 
				 **WHEN NOTIFIED OBJECT DOES NOT EXIST.
				 **H.L
				***/
				try
				{
				    if(typeof target[func]=='function')
					    target[func](evtObj);
				}catch(e){}
			}
		}
	};
	
	this.addListener = function(type, target, func){
		listeners[type] = listeners[type] || {};
		listeners[type][target] = listeners[type][target] || [];
		
		// debug call
		var prefix = "addListener : ";
		this.debug(prefix + "TYPE : " + type + " - TARGET : " + target + " FUNCTION : " + func);
		
		listeners[type][target].push({
			target: this.getFlash(target) || target,	// flash || DOM listener
			func: func
		});
	};
	
	// changed register to add just keeping backwards compatibility
	this.registerListener = this.addListener;
	
	this.removeListener = function(type, target, func){
		
		// debug call
		var prefix = "removeListener ";
		this.debug(prefix + "TYPE : " + type + " - TARGET : " + target + " FUNCTION : " + func);
		
		// get qualified reference
		var brain = this.getFlash(target) || target;
		
		// find match and remove
		for (var i = 0, l = listeners[type][target].length; i < l; i++) {
			if (listeners[type][target][i].target.id == target && listeners[type][target][i].func == func)
				listeners[type][target].splice(i, 1);
		}
	};
	
	this.hasListener = function(type, target, func){
		var brain = this.getFlash(target) || target;
		if (func) {
			for (var i = 0, l = listeners[type][target].length; i < l; i++) {
				var listener = listeners[type][target][i];
				if ((listener.target.id == brain.id || listener.target == target) && listener.func == func){
					this.debug("hasListener TYPE : " + type + " TARGET : " + target + " FUNCTION : " + func);
					return true;
				}
			}
			this.debug("hasListener false");
			return false;
		}
		else {
			var exists = !!listeners[type][target];
			this.debug("hasListener : " + exists);
			return exists;
		}
	};
	
	this.removeAllListeners = function(){
		listeners = {};
	};
	
	this.removeAllListenersForType = function(type){
		listeners[type]={};
	};
	
	this.debug = function(msg){
		if (document.eventbridge_debug_form && mode == "debug") {
			document.eventbridge_debug_form.eventbridge_debug_txt.value += (msg + "\n");
		}
	};
};
/* END EVENT BRIDGE */

/* 
	NAVIGATION -- navigation.js 
	updated 10.09.08
*/
var navListener = new Object();
navListener.defaultSearchText = " ";
navListener.nullSearchText = "";

//console.log("check");

navListener.openURL = function(event){
	var target = "_self";
	if (event.data.target != "") {
		target = event.data.target;
	}
	window.open(event.data.href, target);
};


navListener.searchFocus = function(event) {
	navListener.navInput = document.getElementById('nav_input');

	setTimeout("navListener.navInput.focus()",25); 
	setTimeout("setCaretTo(navListener.navInput, 1000)");
};

navListener.searchOpen = function(event) {
	//console.log("search open");
	navListener.navInput = document.getElementById('nav_input');
	navListener.navForm = document.getElementById('nav_input_form');
	navListener.navForm.style.visibility='visible';
	navListener.navInput.style.visibility='visible';
	setTimeout("navListener.navInput.value = navListener.defaultSearchText",25); 
	setTimeout("navListener.navInput.select()",25); 
	setTimeout("navListener.navInput.value = navListener.nullSearchText",26); 
	setTimeout("setCaretTo(navListener.navInput, 1000)", 27);
};

navListener.searchClose = function(event) {
	//console.log("search close");
	setTimeout("navListener.navInput.value = navListener.nullSearchText",2); 
	setTimeout("navListener.navInput.blur()",3);
	setTimeout("navListener.navInput.style.visibility='hidden'",4); 
};

function search() {
	EventBridge.dispatchEvent({type:'moduleCall',data:encodeURIComponent(document.getElementById('nav_input').value)});
};

EventBridge.addListener("url", navListener, "openURL");
EventBridge.addListener("search", navListener, "openURL");
EventBridge.addListener("searchopen", navListener, "searchOpen");
EventBridge.addListener("searchclose", navListener, "searchClose");
EventBridge.addListener("searchfocus", navListener, "searchFocus");
EventBridge.addListener("callsearch", navListener, "callSearch");
EventBridge.addListener("lockup", navListener, "lockupActive");
EventBridge.addListener("nav", navListener, "navActive");

navListener.flashTest = function(event) { 
	alert("flash working");
};

navListener.lockupActive = function(event) {

	EventBridge.dispatchEvent({type:'navCall',data:'close'});
};

navListener.navActive = function(event) {
	EventBridge.dispatchEvent({type:'lockupCall',data:'close'});
};

navListener.flashAlert = function(event) {
	alert(event.data);
};

navListener.callSearch = function(event) {
	if (document.getElementById('nav_input').value != "") {
		search();
	}
};

function setCaretTo(obj, pos) { 
    if(obj.createTextRange) { 
        var range = obj.createTextRange(); 
        range.move("character", pos); 
        range.select(); 
    } else if(obj.selectionStart) { 
        obj.focus(); 
        obj.setSelectionRange(pos, pos); 
    } 
}; 

/*For Login Update*/
EventBridge.addListener("updateNavProfile", navListener, "updateNavProfile");
EventBridge.addListener("logoutCookies", navListener, "logoutCookies");
EventBridge.addListener("logoutSocial", navListener, "logoutSocial");

var navProfileObj;
var navProfileCalled = false;

function setNavProfile(obj) {
	navListener.navProfileObj = obj;
	navListener.navProfileCalled = true;
	EventBridge.dispatchEvent({type:'setNavProfile', data: obj});
};

navListener.updateNavProfile = function(event) {
	if ((navProfileCalled == false) && (navProfileObj != undefined)) {
		setNavProfile(navListener.navProfileObj);
	}
};

navListener.logoutCookies = function(event) {
	NIKEOS.ME.clearSocialCookies();
	if(typeof nikeplus != "undefined") nikeplus.user.logout();
};

//Logout for social-enabled sites (add type="logoutSocial" to nav.xml)
//Clears social cookies, logs user out of UPM and refreshes page.
navListener.logoutSocial = function(event){
	if(typeof(AC)=='undefined'){
		AC = new NIKEOS.AjaxController({});
	}
	NIKEOS.ME.clearSocialCookies();
	var profileServiceUrl = 'https://' + location.hostname + '/services/profileService';
	if(typeof(NIKEOS.YP)!='undefined'){
		profileServiceUrl = NIKEOS.YP.profileService;
	}
	var request = { url:profileServiceUrl, method:'POST', post_data:'action=logout' };
	var callback = function(data){
		location.reload(true);
	};
	AC.request(request,callback);
};
/*End Login Update*/

/* END NAVIGATION */

/* INNER XHTML -- innerXHTML.js */
/*===================================================================*\
  innerXHTML

  Copyright (c) 2006 space150, LLC and released under the CPL license: 
		http://opensource.org/licenses/cpl1.0.php
\*===================================================================*/

function innerXHTML(obj, encode) {	
  // It is an option to pass innerXHTML() a string indicating an id attribute
  if (typeof obj == "string") {
    obj = document.getElementById(obj);
  };
  
  var open = '';
  var content = '';
  var close = '';
  var tagname = obj.nodeName.toLowerCase();
  var emptytag = (obj.nodeName.match(/area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param/i)) ? true : false; 

  // Write open tag
  open = '<'+tagname;
  for (var i=0; i<obj.attributes.length; i++) {
    if (obj.attributes[i].specified && obj.attributes[i].value != "null")
      open += ' '+obj.attributes[i].name.toLowerCase()+'="'+obj.attributes[i].value+'"';
  }
  open += (emptytag) ? ' />' : '>';

  if (!emptytag) {
    // Write tag content
    for (var i=0; i<obj.childNodes.length; i++) {
      var node = obj.childNodes[i];
      if (node.nodeType==3)
        content += node.data;
      else if (node.nodeType==1)
        content += innerXHTML(obj.childNodes[i], false);
      else
        content += " ";
    }

    // Write closing tag
    close = '</'+tagname+'>';
  }

	// URI encode the content if desired
  return (typeof(encode)=="undefined" || encode==true) ? encodeURIComponent(open+content+close) : open+content+close;
}

/* END INNER XHTML */

/* ENABLEMENT -- enablement.js */

var enablementListener =  {};
var http_request;

enablementListener.fileSave = function(event) {
	//window.open(event.data.url, event.data.target);
	window.open(event.data.url, "_self");
};

enablementListener.blogPrint = function(event) {
	//alert("opening print window");
	window.open(event.data.url, "_blank");
};

enablementListener.blogShare = function(event) {
	//alert("article enablement share: sn name: " + event.data.sn + ", url: " + event.data.url + ", title: " + event.data.title);
	articleShare(event.data.sn, event.data.url, event.data.title, event.data.title);
};

enablementListener.blogEmail = function(event) {
	//alert("blog email");
  http_request = null;
  if (window.XMLHttpRequest) { // Mozilla, Safari,...
	 http_request = new XMLHttpRequest();
	 if (http_request.overrideMimeType) {
		// set type accordingly to anticipated content type
		//http_request.overrideMimeType('text/xml');
		http_request.overrideMimeType('text/html');
	 }
  } else if (window.ActiveXObject) { // IE
	 try {
		http_request = new ActiveXObject("Msxml2.XMLHTTP");
	 } catch (e) {
		try {
		   http_request = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (e) {}
	 }
  }
  if (http_request != null) { 
	var parameters = "?recipient=" + event.data.to + "&sender=" + event.data.from + "&message=" + event.data.message + "&language=" + event.data.language + "&country=" + event.data.country + "&link=" + event.data.link + "&title=" + event.data.title + "&brandName=" + event.data.brandName;
	  var url = "http://cs.ny.rga.com/reboot/sendmailProxy.jsp";
	  var urlParam = url + parameters;
	  http_request.onreadystatechange = alertContents;
	  http_request.open('GET', urlParam, true);
	  http_request.send(null);
	} else {
		alert('Cannot create XMLHTTP instance');
		return false;
	 }
};

function alertContents() {
	if (xmlhttp.readyState==4) {
		// 4 = "loaded"
		if (xmlhttp.status==200) {
			// 200 = OK
			// ...our code here...
		}
	}
	else {
		alert("Problem retrieving XML data");
    }
}
EventBridge.addListener("blogprint", enablementListener, "blogPrint");
EventBridge.addListener("blogshare", enablementListener, "blogShare");
EventBridge.addListener("blogemail", enablementListener, "blogEmail");
EventBridge.addListener("filesave", enablementListener, "fileSave");

/* END ENABLEMENT */

/* 
	End Enablement functionality
*/

/* QUERYSTRING */

/**
 * Q()
 * Maintains query string parameters from page to page. Used w/ createSmartLinks()
 * @example :
 		<script>createSmartLinks()</script>
 		<a href="?page=nextpage&param=param" class="smart">Click me</a>
 */
function Q(){
	this.qsArray = window.location.search.substring(1).split('&');
	this.qsObject = {};
	this.init = function(){
		for ( var i = 0; i < this.qsArray.length; i++ ){
			if((this.qsArray[i].indexOf('=') == -1)|| this.qsArray[i].indexOf('=') == this.qsArray[i].length+1){
				this.qsObject[this.qsArray[i]] = '';				
			} else {
				this.qsObject[this.qsArray[i].split('=')[0]] = this.qsArray[i].split('=')[1];
			}
		}
	};
	this.getParam = function(param) { return this.qsObject[name]; };
	this.modifyParam = function(name, value) { this.qsObject[name] = value; };
	this.removeParam = function(name) { delete this.qsObject[name]; };
	this.getQueryString = function(){
		var qs = '?';
		for (i in this.qsObject){
			if (this.qsObject[i] != null){
				qs += (i + '=' + this.qsObject[i] + '&');
			}
		}
		return qs.substring(0,qs.length-1);
	};
	this.makeLink = function(pageName, subPageName){
		if(subPageName){
			this.qsObject["page"] = subPageName;
		}
		return(pageName + this.getQueryString());
	};
}

/**
 * createSmartLinks()
 * Modify all links w/ class "smart" to contain querystring params of current page.
 * @example :
 		<script>createSmartLinks()</script>
 		<a href="?page=nextpage&param=param" class="smart">Click me</a>
 */
function createSmartLinks(){
	JQ('a.smart').each( function(){
		var targetHref = JQ(this).attr('href');
		var currentQ = new Q();
		currentQ.init();
		var targetQ = new Q();
		targetQ.qsArray = targetHref.split('?')[1].split('&');
		targetQ.init();
		var targetPage = targetHref.split('?')[0];
		var targetSubPage = targetQ.getParam('page');
		for (i in targetQ.qsObject){
			currentQ.modifyParam(i,targetQ.qsObject[i]);
		}

		JQ(this).attr({'href': currentQ.makeLink(targetPage,targetSubPage)});
	});
}

/* END QUERYSTRING */

/* me.nikeKISH.com COOKIE */

if (!NIKEOS.ME) NIKEOS.ME = {};

/**
 * setCookie
 * sets the "me.nikeKISH.com" cookie
 * @param {object} obj : hash of profile name/values
 */
NIKEOS.ME.setCookie = function(obj){
	var str = '';
	var counter = 0;
	for(i in obj){
		if(counter!=0){ str += '&'; } else { counter++; }
		str += i + '=' + obj[i];
	}
	NIKEOS.ME.data = obj;
	var date = new Date();
	date.setTime(date.getTime() + (5 * 60 * 1000));
	JQ.cookie('me.nikeKISH.com',Base64.encode(str),{path:'/',expires:date});
};

/** getCookie
 * gets hash from "me.nikeKISH.com" cookie
 * @return {object} obj : hash of profile name/values
 */
NIKEOS.ME.getCookie = function(){
	if(JQ.cookie('me.nikeKISH.com')){
		var str = Base64.decode(JQ.cookie('me.nikeKISH.com'));
		var arr = str.split('&');
		var obj = {};
		for(var i = 0;i<arr.length;i++){
			obj[arr[i].split('=')[0]] = arr[i].split('=')[1];
		}
		return obj;
	} else { return false; }
};

/** addToCookie
 * add hash to "me.nikeKISH.com" cookie (OVERWRITES)
 * @param {object} params : hash of name/values to add
 * @return {object} obj : hash of profile name/values
 */
NIKEOS.ME.addToCookie = function(params){
	if(JQ.cookie('me.nikeKISH.com')){
		var str = Base64.decode(JQ.cookie('me.nikeKISH.com'));
		var arr = str.split('&');
		var obj = {};
		for(var i = 0;i<arr.length;i++){
			obj[arr[i].split('=')[0]] = arr[i].split('=')[1];
		}
		for(var j in params){
			obj[j] = params[j];
		}
		NIKEOS.ME.setCookie(obj);
		return obj;
	} else { NIKEOS.ME.setCookie(params); }
};

/** removeFromCookie
 * remove array of keys from "me.nikeKISH.com" cookie
 * @param {array} params : array of keys to delete
 * @return {object} obj : hash of profile name/values
 */
NIKEOS.ME.removeFromCookie = function(toDelete){
	if(JQ.cookie('me.nikeKISH.com')){
		var str = Base64.decode(JQ.cookie('me.nikeKISH.com'));
		var arr = str.split('&');
		var obj = {};
		for(var i = 0;i<arr.length;i++){
			obj[arr[i].split('=')[0]] = arr[i].split('=')[1];
		}
		for(var j = 0;j<toDelete.length;j++){
			delete obj[toDelete[j]];
		}
		NIKEOS.ME.setCookie(obj);
		return obj;
	} else { return false; }	
};

/** clearSocialCookies
 * remove me.nikeKISH.com and st.nikeKISH.com cookies on logout.
 */
NIKEOS.ME.clearSocialCookies = function(){
	if(JQ.cookie){
		JQ.cookie('me.nikeKISH.com', null, {path:'/'});
		JQ.cookie('st.nikeKISH.com', null, {path:'/'});
		JQ.cookie('TERMS_OF_SERVICE_UPDATED', null, {path:'/'});
		//NSL cookies
		//JQ.cookie('SOCTOKEN', null, {path:'/', domain: '.nikeKISH.com'});
		//JQ.cookie('at', null, {path:'/', domain: '.nikeKISH.com'});
		//JQ.cookie('slCheck', null, {path:'/', domain: '.nikeKISH.com'});
		//JQ.cookie('s_sq', null, {path:'/', domain: '.nikeKISH.com'});
	} else {
		NIKEOS.log('JQ.cookie not available');
	}
};
/** verifyCookie
 * make sure that id.nikeKISH.com matches me.nikeKISH.com
 * if it doesn't, clearSocialCookies
 */
NIKEOS.ME.verifyCookie = function(){
	if(JQ.cookie){
		if(JQ.cookie('me.nikeKISH.com') && JQ.cookie('id.nikeKISH.com')){
			var id_id = Base64.decode(JQ.cookie('id.nikeKISH.com')).split(':')[0];
			var me_id = NIKEOS.ME.getCookie().id;
			if (id_id != me_id){
				NIKEOS.ME.clearSocialCookies();
				return false;
			} else {
				return true;
			}
		} return false;
	}
	NIKEOS.log('JQ.cookie not available');
};

/** updateNav
 * set nav profile tab to have updated screenName, profileImage, messageCount
 */
NIKEOS.ME.setMessageCount = function(){
	if(JQ.cookie){
		if(JQ.cookie('me.nikeKISH.com')){
			var messageCount = NIKEOS.ME.getCookie().messageCount;
			if(typeof(messageCount)!='undefined'){
				setNavProfile({'messageCount':messageCount});
			}
		}
	}
};
/* END me.nikeKISH.com COOKIE */

/* SWFjax Controller */
NIKEOS.AjaxController = function(options){
	var self = this;
	self.setup = JQ.extend(true,{
		f4a : {
			swf_src : 'http://www.nikeKISH.com/nikeos/global/swf/f4a/f4a.swf',
			div_id : 'f4a_nikeAC'
		}
	}, options);
	self.metadata = {
		ready : false,
		queue : []
	};
	self.init = function(){
		var f4a_div=document.createElement('div');
		f4a_div.id=self.setup.f4a.div_id+'flashcontent';f4a_div.style.height="1px";f4a_div.style.width="1px";f4a_div.style.marginTop="-1px";f4a_div.style.marginLeft="-1px";f4a_div.style.backgroundColor="transparent";
		var bodyInterval = window.setInterval(function(){
			if(!document.body){} else {
				if(document.body.hasChildNodes()){
					//DOM in the f4a crossdomain ajax javascript and div.
					if((navigator.userAgent.toLowerCase().indexOf("msie") != -1) && (navigator.userAgent.toLowerCase().indexOf("opera") == -1)){
						document.getElementsByTagName('head')[0].appendChild(f4a_div);
					} else {
						document.body.appendChild(f4a_div);
					}
					var f4a_divInterval = window.setInterval(function(){
						if(document.getElementById(self.setup.f4a.div_id+'flashcontent')){
							f4aSwf();
							window.clearInterval(f4a_divInterval);
						}
					}, 50);
					window.clearInterval(bodyInterval);
				}
			};
		}, 50);

		function f4aSwf(){
			var f4aInterval = window.setInterval(function(){
				if(typeof(f4a_js_flash)=='undefined'){
				}
				else{
					f4a = new f4a_js_flash({'id':self.setup.f4a.div_id,'swfname':'f4a.swf','swfuri':self.setup.f4a.swf_src});
					f4a.createSwfObject(function(){
						self.metadata.ready = true;
						self.unloadQueue();
					});
					window.clearInterval(f4aInterval);
				};
			}, 50);
		}
	};
	self.request = function(request_obj, cb){
		if(self.metadata.ready == true){
			self.fire(request_obj, cb);
		} else {
			var req = [ request_obj, cb ];
			self.metadata.queue.push(req);
		}
	};
	self.fire = function(data, cb){
		this.url = data['url'] || '';
		this.method = data['method'] || 'POST';
		this.data = data['post_data'] || {};
		this.contenttype = data['contenttype'] || null;
		var cb = cb || function(){ return; };
		this.req = {'url':this.url,'meth':this.method,'contenttype':this.contenttype,'data':this.data,'onready':function(data){ cb(data); }};
		f4a.open(this.req);
	};
	self.unloadQueue = function(){
		if(self.metadata.queue[0]){
			for(var i = 0; i < self.metadata.queue.length; i++){
				self.fire(self.metadata.queue[i][0], self.metadata.queue[i][1]);
			}
		}
	};
	self.test = function(){
		console.log('testing');
		var data = {};
		data['url'] = '/services/profileService?action=getprofile';
		data['method'] = 'POST';
		data['post_data'] = 'test=12';
		var fn = function(o){ alert(o); };
		self.request(data, fn);
	};
	self.init();
};

/* BASE 64 Encoding/Decoding */

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }
};

/* END BASE 64 Encoding/Decoding */


/* Utility Functions taken from MooTools */

function $A(iterable) {
	if (iterable.item) {
		var array = [];
		for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i];
		return array;
	}
	return Array.prototype.slice.call(iterable);
};

function $chk(obj){
	return !!(obj || obj === 0);
};

function $clear(timer){
	clearTimeout(timer);
	clearInterval(timer);
	return null;
};

function $defined(obj){
	return (obj != undefined);
};

function $empty(){};

function $arguments(i){
	return function(){
		return arguments[i];
	};
};

function $lambda(value){
	return (typeof value == 'function') ? value : function(){
		return value;
	};
};

function $extend(original, extended){
	for (var key in (extended || {})) original[key] = extended[key];
	return original;
};

function $unlink(object){
	var unlinked;
	
	switch ($type(object)){
		case 'object':
			unlinked = {};
			for (var p in object) unlinked[p] = $unlink(object[p]);
		break;
		case 'hash':
			unlinked = $unlink(object.getClean());
		break;
		case 'array':
			unlinked = [];
			for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
		break;
		default: return object;
	}
	
	return unlinked;
};

function $merge(){
	var mix = {};
	for (var i = 0, l = arguments.length; i < l; i++){
		var object = arguments[i];
		if ($type(object) != 'object') continue;
		for (var key in object){
			var op = object[key], mp = mix[key];
			mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $merge(mp, op) : $unlink(op);
		}
	}
	return mix;
};

function $pick(){
	for (var i = 0, l = arguments.length; i < l; i++){
		if (arguments[i] != undefined) return arguments[i];
	}
	return null;
};

function $random(min, max){
	return Math.floor(Math.random() * (max - min + 1) + min);
};

function $splat(obj){
	var type = $type(obj);
	return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : [];
};

var $time = Date.now || function(){
	return new Date().getTime();
};

function $try(){
	for (var i = 0, l = arguments.length; i < l; i++){
		try {
			return arguments[i]();
		} catch(e){}
	}
	return null;
};

function $type(obj){
	if (obj == undefined) return false;
//	if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name;
	if (obj.nodeName){
		switch (obj.nodeType){
			case 1: return 'element';
			case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
		}
	} else if (typeof obj.length == 'number'){
		if (obj.callee) return 'arguments';
		else if (obj.item) return 'collection';
	}
	return typeof obj;
};

/* End MooTools Utility Functions */

