/*	Script: string.cnet.js
		These are mootools authored extensions designed to allow prototype.lite libraries run in this environment.

Dependancies:
	 mootools - <Moo.js>, <String.js>, <Array.js>

Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>
	

		Class: String
		This extends the <String> prototype.
	*/
String.extend({
/*	Property: stripTags
		Remove all html tags from a string.	*/
	stripTags: function() {
		return this.replace(/<\/?[^>]+>/gi, '');
  },
/*	Property: stripScripts
		Removes all script tags from an HTML string.
	*/
	stripScripts: function() {
		return this.replace(/<script[^>]*?>.*?<\/script>/img, '');
	},
/*	Property: evalScripts
		Executes scripts included in an HTML string.
	*/
	evalScripts: function() {
		var scripts = this.match(/<script[^>]*?>.*?<\/script>/g);
		if(scripts) scripts.each(function(script){
				eval(script.replace(/^<script[^>]*?>/, '').replace(/<\/script>$/, ''));
			});
	},
/*	Property: replaceAll
		Replaces all instances of a string with the specified value.
		
		Arguments:
		searchValue - the string you want to replace
		replaceValue - the string you want to insert in the searchValue's place
		regExOptions - defaults to "ig" but you can pass in your preference
		
		Example:
		>"I like cheese".replaceAll("cheese", "cookies");
		> > I like cookies
	*/
	replaceAll: function(searchValue, replaceValue, regExOptions) {
		return this.replace(new RegExp(searchValue, $pick(regExOptions,'gi')), replaceValue);
	},
/*	Property: urlEncode
		urlEncodes a string (if it is not already).
		
		Example:
		> "Mondays aren't that fun".urlEncode()
		> > Mondays%20aren%27t%20that%20fun
	*/
	urlEncode: function() {
		if (this.indexOf('%') > -1) return this;
		else return escape(this);
	},
/*	Property: parseQuery
		Turns a query string into an associative array of key/value pairs.
		
		Example:
(start code)
"this=that&what=something".parseQuery()
> { this: "that", what: "something" }

var values = "this=that&what=something".parseQuery();
> values.this > "that"
(end)
	*/

	parseQuery: function() {
		var vars = this.split(/[&;]/);
		var rs = {};
		if (vars.length) vars.each(function(val) {
			var keys = val.split('=');
			if (keys.length && keys.length == 2) rs[encodeURIComponent(keys[0])] = encodeURIComponent(keys[1]);
		});
		return rs;
	},
/*	Property: tidy
		Replaces common special characters with their ASCII counterparts (smart quotes, elipse characters, stuff from MS Word, etc.).
	*/
	tidy: function() {
		var txt = this.toString();
		$each({
			"[\xa0\u2002\u2003\u2009]": " ",
			"\xb7": "*",
			"[\u2018\u2019]": "'",
			"[\u201c\u201d]": '"',
			"\u2026": "...",
			"\u2013": "-",
			"\u2014": "--"
		}, function(value, key){
			txt = txt.replace(new RegExp(key, 'g'), value);
		});
		return txt;
	}
});
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/string.cnet.js,v $
$Log: string.cnet.js,v $
Revision 1.2  2007/07/17 20:38:44  newtona
Fx.SmoothShow - refactored the exploration of the element dimensions when hidden so that it isn't visible to the user
element.position - refactored to allow for more than just the previous 5 positions, now supports nine: all corners, all mid-points between those corners, and the center
string.cnet.js - fixed up the query string logic to decode values

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories

Revision 1.8  2007/03/16 00:23:24  newtona
added string.tidy and element.tidy

Revision 1.7  2007/03/09 20:14:47  newtona
strict javascript warnings cleaned up

Revision 1.6  2007/03/08 23:32:14  newtona
strict javascript warnings cleaned up

Revision 1.5  2007/02/06 18:14:01  newtona
re-implemented replaceAll because String.replace(new, old, "ig") doesn't work in IE. Ungh. IE.

Revision 1.4  2007/01/26 06:08:27  newtona
updated docs
refactored .replaceAll
removed dependency on Prototype.compatibility.js

Revision 1.3  2006/11/15 01:19:19  newtona
added String.parseQuery

Revision 1.2  2006/11/02 21:34:00  newtona
Added cvs footer


*/
/*	Script: window.cnet.js
Extends the Mootools <Window> class.

Class: window
		This extends the <window> class from the <http://mootools.net> library.
		
Dependencies:
 mootools = <Moo.js>, <Utility.js>, <Common.js>, <Window.Base.js>
 cnet - <string.cnet.js>
	*/
window.extend({
/*	property: isLoaded (deprecated)
		Use <window.loaded>; true if the dom is ready.
	*/
	isLoaded: window.loaded,
/*	Property: getHost	
		Returns the domain of the window or the passed in url.
		
		Arguments:
		url (optional) - the url you wish to get the host for (otherwise window.getHost
							returns the host of the current window location).
*/
	getHost:function(url){
		url = $pick(url, window.location.href);
		var host = url;
		if(url.test('http://')){
			url = url.substring(url.indexOf('http://')+7,url.length);
			if(url.test(':')) url = url.substring(0, url.indexOf(":"));
			if(url.test('/')) return url.substring(0,url.indexOf('/'));
			return url;
		}
		return false;
	},
/*	Property: getQueryStringValue
		Returns a specific query string value from the window location.
		
		Arguments:
		key - the key to search for in the query string
		url - (optional) url with a query string to parse (defaults to window.location)
		
		Example:
(start code)
//window.location is http://www.example.com/?red=apple&yellow=lemon
var something = window.getQueryStringValue("red");
> something = "apple"
(end)
	*/
	getQueryStringValue: function(key, url) {
		try { 
			return window.getQueryStringValues(url)[key];
		}catch(e){return null;}
	},

/* Property: getQueryStringValues 
		An object with name/value pairs of the values in the query string of the window.
		
		Arguments:
		url - (optional) url with a query string to parse (defaults to window.location)
		
		Example:
		If you were on the page http://www.example.com?red=apple&yellow=lemon
		
		then window.getQueryStringValues() would return:
(start code)
{
	red: 'apple',
	yellow: 'lemon'
}
(end)
*/
		getQueryStringValues: function(url){
			var qs = $pick(url, $pick(window.location.search, '')); //get the query string
			if(qs == "") return []; //if there isn't one, return null
			if(qs.indexOf("?") >= 0)qs = qs.substring(qs.indexOf("?")+1, qs.length); //remove the question mark
			return qs.parseQuery();
		},

	
/*	Property: getPort
		Returns the port number of the window location.
		
		Arguments
		url - (optional) the url to test for a port; defaults to the window location.
		
		Example:
		(start code)
//window.location.href is http://www.example.com:8001/blah.html
window.getPort()
> 8001
		(end)
	*/
	getPort: function(url) {
		url = $pick(url, window.location.href);
		var re = new RegExp(':([0-9]{4})');
		var m = re.exec(url);
	  if (m == null) return false;
	  else {
			var port = false;
			m.each(function(val){
				if($chk(parseInt(val))) port = val;
			});
	  }
		return port;
	},
/*	Property:	qs
		An object with name/value pairs of the values in the query string of the window.
		
		Example:
		If you were on the page http://www.example.com?red=apple&yellow=lemon
		
		then window.qs would be:
(start code)
{
	red: 'apple',
	yellow: 'lemon'
}
(end)
	*/
	qs: {}
});
window.qs = window.getQueryStringValues();

/*	Class: window.popup
This class opens a popup window with the passed in values.
		
Arguments
	url - the destination for the popup
	options - an object containing key/value options
	
Options:
	width - (integer) the width of the window; defaults to 500
	height - (integer) the height of the window; defaults to 300
	x - (integer) the offest from the left of the screen; defaults to 50
	y - (integer) the offset from the top of the screen; defaults to 50
	toolbar - (integer) show the browser toolbar in the window; 
			0 (zero) does not show it, 1 (one) does; defaults to 0 (zero)
	location - (integer) show the location in the browser;
			0 does not show it; defautls to 0
	directories - (integer) show the directories in the browser;
			0 does not show it; defautls to 0
	status - (integer) show the status bar in teh browser;
			0 does not show it; defautls to 0
	scrollbars - (string) 'auto' shows the scroll bars if they are required,
			'no' shows none, 'yes' shows them all the time
	resizable - (integer) lets the user resize the window;
			1 allows resizeing; defaults to 1
	name - (string) the name of the popup; defaults to "popup"
	
	Examples:
	(start code)
var myPopup = new window.popup('http://www.example.com'); //opens with default parameters

var myPopup = new window.popup('http://www.example.com', {
	width: 300,
	height: 800,
	x: 500,
	toolbar: 1
}); //launch a window with custom properties
	(end)

	Property: popupWindow
	The window object itself (the popup). The class window.popup opens a new browser window. The pointer to this
	window can be reached like so:
	(start code)
	var myPopup = new window.popup('http://www.example.com');
	myPopup.popupWindow // this is the reference to the popup itself.
	(end)
	
	Note that if you call this class with the same name (the default name is 'popup') as an already open window
	you won't open a new popup window, but instead will send your url to the existing window. You should probably
	give it something unique so you can have more than one if you need. 

	Example:
	(start code)
	var myPopup = new window.popup('http://www.example.com'); //default name for the popup is "popup"
	var anotherPopup = new window.popup('http://www.example2.com'); //you just refreshed the "popup" window with this new url
	(end)
	
	This actually represents a way to keep refering to the same window that's already open. So long as the window
	calling it is the same window that opened the popup to begin with (even if the user goes to another page), the
	above code will always re-acquire the already open popup.
	
	Example:
	(start code)
	//page loads
	var myPopup = new window.popup('http://www.example.com'); //default name for the popup is "popup"
	
	//user goes to another page, and, when that page loads, this happens again
	var myPopup = new window.popup('http://www.example.com'); //default name for the popup is "popup"
	(end)
	
	The result is you just refreshed the already open window with the same url. There are ways to do this
	without refreshing, but not with this class (yet).
	*/
window.popup = new Class({
	options: {
			width: 500,
			height: 300,
			x: 50,
			y: 50,
			toolbar: 0,
			location: 0,
			directories: 0,
			status: 0,
			scrollbars: 'auto',
			resizable: 1,
			name: 'popup',
			onBlock: Class.empty
	},
	initialize: function(url, options){
		this.url = url || false;
		this.setOptions(options);
		if(this.url) this.openWin();
		return this;
	},
	openWin: function(url){
		url = url || this.url;
		var options = 'toolbar='+this.options.toolbar+
			',location='+this.options.location+
			',directories='+this.options.directories+
			',status='+this.options.status+
			',scrollbars='+this.options.scrollbars+
			',resizable='+this.options.resizable+
			',width='+this.options.width+
			',height='+this.options.height+
			',top='+this.options.y+
			',left='+this.options.x;
		console.log('window.open("%s", "%s", "%s")', url, this.options.name, options);
		this.popupWindow = window.open(url,
			this.options.name, options);
		this.focus.delay(100, this);
		return this.popupWindow;
	},
/*	Property: focus
		Focus the window related to the window.popup object.
		
		Example:
		(start code)
var myPopup = new window.popup('http://www.example.com'); //opens with default parameters
myPopup.focus(); //bring it to the front
		(end)
		
		Note:
		When you create a new popup it calls .focus() on itself immediately by default.
	*/
	focus: function(){
		if (this.popupWindow) this.popupWindow.focus();
		else if (this.focusTries<10) this.focus.delay(100, this); //try again
		else {
			this.blocked = true;
			this.fireEvent('onBlock');
		}
		return this;
	},
	focusTries: 0,
	blocked: null,
/*	Property: close
		Closes the popup window related to the window.popup object.

		Example:
		(start code)
var myPopup = new window.popup('http://www.example.com'); //opens with default parameters
myPopup.close(); //close the window
		(end)

	*/
	close: function(){
		this.popupWindow.close();
	}
});
window.popup.implement(new Options);
window.popup.implement(new Events);

/*	Class: legacyPopup
		A legacy instance of <window.popup> that defaults to a specific width and height; not intended for use.	*/
var legacyPopup = window.popup.extend({
	setOptions: function(){
		this.parent();
		this.options = Object.extend({
			width: 516, 
			height: 350
		}, this.options);
	}
});

/*	Function: openPop
		An instance of <legacyPopup>; not intended for actual use.
	*/
function openPop(url){
	return new legacyPopup(url);
}

/*	Function: GetValue
		Legacy syntax for window.getQueryStringValue; deprecated.
	*/
var GetValue = window.getQueryStringValue;
	
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/window.cnet.js,v $
$Log: window.cnet.js,v $
Revision 1.3  2007/07/20 00:06:02  newtona
fixed an error with window.popup arguments

Revision 1.2  2007/06/25 17:24:22  newtona
fixed a typo in window.popup

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories

Revision 1.18  2007/04/11 20:52:23  newtona
removing function.cnet.js dependency

Revision 1.17  2007/03/10 01:24:47  newtona
getQueryString returns an empty array instead of null

Revision 1.16  2007/03/09 20:14:47  newtona
strict javascript warnings cleaned up

Revision 1.15  2007/02/21 00:22:21  newtona
fixed some syntax problems
implemented Events

Revision 1.14  2007/02/08 01:30:37  newtona
renamed the popup window in the class window.popup "popupWindow" instead of "window" - a reserved name in IE

Revision 1.13  2007/01/26 06:13:34  newtona
now .isLoaded = .loaded
syntax update for mootools 1.0
getHost takes a url now (defaults to window.location)
added getQueryStringValues
added .qs - an object of the window query string values

Revision 1.12  2007/01/22 22:02:02  newtona
removed ie background cache fixed; it's in mootools 1.0

Revision 1.11  2007/01/19 01:23:09  newtona
fixed a bug in window.getHost

Revision 1.10  2007/01/09 01:29:24  newtona
added returns of the Window.popup class when calling functions on Window.popups

Revision 1.9  2006/11/27 19:34:32  newtona
changed the line about firefox bugs; this comment was misleading. no functional changes.

Revision 1.8  2006/11/26 00:28:19  newtona
forgot about ports in getHost... fixed

Revision 1.7  2006/11/26 00:26:35  newtona
ok. actually *fixed* the bug with getHost

Revision 1.6  2006/11/26 00:16:48  newtona
fixed conditional bug in Window.getHost

Revision 1.5  2006/11/16 18:50:40  newtona
fixed a syntax error in getQueryStringValue

Revision 1.4  2006/11/15 01:19:49  newtona
added Window.getQueryStringValue

Revision 1.3  2006/11/04 00:54:35  newtona
added Widnow.getPort()

Revision 1.2  2006/11/02 21:34:00  newtona
Added cvs footer


*/
/*	Script: element.shortcuts.js
Extends the <Element> object with some basic shortcuts (like .hide and .show).

Dependancies:
	 mootools - <Moo.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>

Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>
	
Class: Element
		This extends the <Element> prototype.
	*/
Element.extend({

/*	Property: isVisible
		Returns a boolean; true = visible, false = not visible.
		
		Example:
		>$(id).isVisible()
		> > true | false	*/
	isVisible: function() {
		return this.getStyle('display') != 'none';
	},
/*	Property: toggle
		Toggles the state of an element from hidden (display = none) to 
		visible (display = what it was previously or else display = block)
		
		Example:
		> $(id).toggle()
	*/
	toggle: function() {
		return this[this.isVisible() ? 'hide' : 'show']();
	},
/*	Property: hide
		Hides an element (display = none)
		
		Example:
		> $(id).hide()
		*/
	hide: function() {
		this.originalDisplay = this.getStyle('display'); 
		this.setStyle('display','none');
		return this;
	},
/*	Property: show
		Shows an element (display = what it was previously or else display = block)
		
		Example:
		>$(id).show() */
	show: function(display) {
		this.originalDisplay = (this.originalDisplay=="none")?'block':this.originalDisplay;
		this.setStyle('display',(display || this.originalDisplay || 'block'));
		return this;
	},
/*	Property: tidy
		Uses <String.tidy> to clean up common special characters with their ASCII counterparts (smart quotes, elipse characters, stuff from MS Word, etc.).
	*/
	tidy: function(){
		try {	
			if(this.getValue().tidy())this.value = this.getValue().tidy();
		}catch(e){dbug.log('element.tidy error: %o', e);}
	},
	//DO NOT USE THIS METHOD
	//it is temporary, as Mootools 1.1 will negate its requirement
	fxOpacityOk: function(){
		if (!window.ie6)return true;
		var isColor = false;
		try {
			if (new Color(this.getStyle('backgroundColor'))) isColor = true;
		}catch(e){}
		return isColor;
	}
});
//legacy namespace
Element.visible = Element.isVisible;


if(!Element.empty) {
	Element.extend({
		/*
		Property: empty
			Empties an element of all its children (overridden by Mootools 1.1 <Element.empty> if present).
	
		Example:
			>$('myDiv').empty() // empties the Div and returns it
	
		Returns:
			The element.
		*/
		empty: function(){
			//Garbage.trash(this.getElementsByTagName('*'));
			return this.setHTML('');
		}
	});
}
/*	legacy support for $S	*/
var $S = $$;
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/element.shortcuts.js,v $
$Log: element.shortcuts.js,v $
Revision 1.3  2007/05/30 20:32:33  newtona
doc updates

Revision 1.2  2007/05/29 22:01:53  newtona
Split element.cnet.js into seperate files; updated docs in files to note this
Changed element.visible to element.isVisible (left old namespace for legacy support)
Fixed Element.empty in prototype.compatibility.js
Removed as many dependencies in common code to element.*.js as possible (espeically element.shortcuts.js)

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories

Revision 1.29  2007/05/17 19:45:57  newtona
updated element.empty for mootools 1.1

Revision 1.28  2007/05/16 20:09:42  newtona
adding new js files to redball.common.full
product.picker.js now has no picklets; these are in the implementations/picklets directory
ProductPicker now detects if there is no doctyp and, if not, sets the position of the picker to be fixed (no IE6 support)
small docs update in element.cnet.js
added new picklet: CNETProductPicker_PricePath
added new picklet: NewsStoryPicker_Path
new file: clipboard.js (allows you to insert text into the OS clipboard)
new file: html.table.js (automates building html tables)
new file: element.forms.js (for managing text inputs - get selected text information, insert content around selection, etc.)

Revision 1.27  2007/05/05 01:01:26  newtona
stickywinHTML: tweaked the options for buttons
element.cnet: tweaked smoothshow/hide css handling

Revision 1.26  2007/04/09 21:35:22  newtona
removing garbage collection from Element.empty (will have to wait for Mootools 1.1)

Revision 1.25  2007/04/02 18:04:48  newtona
syntax fix

Revision 1.24  2007/03/30 21:42:43  newtona
adding Element.isEmpty

Revision 1.23  2007/03/30 19:27:58  newtona
moved .empty to .flush

Revision 1.22  2007/03/29 22:36:42  newtona
Element.fxOpacityOk now only checks bgcolor for ie6
Added Element.flush

Revision 1.21  2007/03/28 23:22:54  newtona
Element.smoothShow/smoothHide: added Element.fxOpacityOk to deal with the IE bug where text gets blurry when you fade an element in and out without a bgcolor set

Revision 1.20  2007/03/28 18:07:21  newtona
added Element.fxOpacityOk to deal with the IE bug where text gets blurry when you fade an element in and out without a bgcolor set

Revision 1.19  2007/03/26 18:30:12  newtona
iframeShim: fixed reference to options (should be this.options)
element.cnet: removed some dbug lines

Revision 1.18  2007/03/23 20:13:38  newtona
getDimensions: added support for getComputedSize
getComputedSize: added
setPosition: added edge option, uses getComputedSize
smoothHide: uses getComputedSize
smoothShow: uses getComputedSize
sumObj: removed function; no longer needed

Revision 1.17  2007/03/16 00:23:24  newtona
added string.tidy and element.tidy

Revision 1.16  2007/03/08 23:32:14  newtona
strict javascript warnings cleaned up

Revision 1.15  2007/03/01 00:50:35  newtona
type.isNumber now returns false for NaN
element.smoothshow/hide now works (in IE specifically) when there are no values for border

Revision 1.14  2007/02/27 19:37:56  newtona
element.show now enforces that the original display was not 'none'

Revision 1.13  2007/02/22 21:05:35  newtona
smoothHide now checks that the element is not already hidden

Revision 1.12  2007/02/21 00:21:22  newtona
added legacy support for $S

Revision 1.11  2007/02/08 22:14:04  newtona
added border widths to smoothshow/hide

Revision 1.10  2007/02/08 01:30:58  newtona
tweaking element.setPosition, now can use effects

Revision 1.9  2007/02/07 20:52:34  newtona
added Element.position

Revision 1.8  2007/02/06 18:13:13  newtona
added element.smoothShow and smoothHide; depends on latest svn of mootools

Revision 1.7  2007/02/03 01:40:05  newtona
fixed a typo bug

Revision 1.6  2007/01/26 06:06:13  newtona
element.replace now takes a 2nd argument to eval scripts or not
element.getDimensions now returns w & h for hidden elements

Revision 1.5  2007/01/05 19:45:48  newtona
made getDimensions capable of discovering dimensions of hidden elements

Revision 1.4  2006/12/06 20:14:59  newtona
carousel - improved performance, changed some syntax, actually deployed into usage and tested
cnet.nav.accordion - improved css selectors for time
multiple accordion - fixed a typo
dbug.js - added load timers
element.cnet.js - changed syntax to utilize mootools more effectively
function.cnet.js - equated $set to $pick in preparation for mootools v1

Revision 1.3  2006/11/27 17:59:32  newtona
small change to replace and the way it uses timeouts

Revision 1.2  2006/11/02 21:34:00  newtona
Added cvs footer


*/
/*	Script: element.dimensions.js
Extends the <Element> object.

Dependancies:
	 mootools - <Moo.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>

Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>
	
Class: Element
		This extends the <Element> prototype.
	*/
Element.extend({
/*	Property: getDimensions
		Returns width and height for element; if element is not visible the element is
		cloned off screen, shown, measured, and then removed.
		
		Arguments:
		options - a key/value set of options
		
		Options:
		computeSize - (boolean; optional) use <Element.getComputedSize> or not; defaults to false
		styles - (array; optional) see <Element.getComputedSize>
		plains - (array; optional) see <Element.getComputedSize>
		
		Returns:
		An object with .width and .height defined as integers. If options.computeSize is true, returns
		all the values that <Element.getComputedSize> returns.
		
		Example:
		>$(id).getDimensions()
		> > {width: #, height: #}
	*/
	getDimensions: function(options) {
		options = $merge({computeSize: false},options);
		var dim = {};
		function getSize(el, options){
			if(options.computeSize) dim = el.getComputedSize(options);
			else {
				dim.width = el.getSize().size.x;
				dim.height = el.getSize().size.y;
			}
			return dim;
		}
		try { //safari sometimes crashes here, so catch it
			dim = getSize(this, options);
		}catch(e){}
		if((dim.x == 0 || $type(dim.x) != 'number')||(dim.y == 0 || $type(dim.y) != 'number')){
			var holder = new Element('div').setStyles({
				'position':'absolute',
				'top':'-1000px',
				'left':'-1000px',
				'display':'block'
			}).injectAfter(this);
			var clone = this.clone().injectInside(holder).setStyle('display','block');
			dim = getSize(clone, options);
			holder.remove();
		}
		return $merge(dim, {x: dim.width, y: dim.height});
	},
/*	Property: getComputedSize
		Calculates the size of an element including the width, border, padding, etc.
		
		Arguments:
		options - an object with key/value options
		
		Options:
		styles - (array) the styles to include in the calculation; defaults to ['padding','border']	
		plains - (object) an object with height and width properties, each of which is an 
							array including the edges to include in that plain. 
							defaults to {height: ['top','bottom'], width: ['left','right']}
		mode - (string; optional) limit the plain to 'vertical' or 'horizontal'; defaults to 'both'
		
		Returns:
		size - an object that contans dimension values (integers); see list below
		
		
		Dimension Values Returned:
		width - the actual width of the object (not including borders or padding)
		height - the actual height of the object (not including borders or padding)
		border-*-width - (where * is top, right, bottom, and left) the width of the border on that edge
		padding-* - (where * is top, right, bottom, and left) the width of the padding on that edge
		computed* - (where * is Top, Right, Bottom, and Left; e.g. computedRight) the width of all the 
			styles on that edge computed (so if options.styles is left to the default padding and border,
			computedRight is the sum of border-right-width and padding-right)
		totalHeight - the total sum of the height plus all the computed styles on the top or bottom. by
			default this is just padding and border, but if you were to specify in the styles option
			margin, for instance, the totalHeight calculated would include the margin.
		totalWidth - same as totalHeight, only using width, left, and right

		Example:
(start code)
$(el).getComputedSize();
returns:
{
	padding-top:0,
	border-top-width:1,
	padding-bottom:0,
	border-bottom-width:1,
	padding-left:0,
	border-left-width:1,
	padding-right:0,
	border-right-width:1,
	width:100,
	height:100,
	totalHeight:102,
	computedTop:1,
	computedBottom:1,
	totalWidth:102,
	computedLeft:1,
	computedRight:1
}
(end)		
	*/
	getComputedSize: function(options){
		options = $merge({
			styles: ['padding','border'],
			plains: {height: ['top','bottom'], width: ['left','right']},
			mode: 'both'
		}, options);
		var size = {width: 0,height: 0};
		switch (options.mode){
			case 'vertical':
				delete size.width;
				delete options.plains.width;
				break;
			case 'horizontal':
				delete size.height;
				delete options.plains.height;
				break;
		}
		var getStyles = [];
		//this function might be useful in other places; perhaps it should be outside this function?
		$each(options.plains, function(plain, key){
			plain.each(function(edge){
				options.styles.each(function(style){
					getStyles.push((style=="border")?style+'-'+edge+'-'+'width':style+'-'+edge);
				});
			});
		});
		var styles = this.getStyles.apply(this, getStyles);
		var subtracted = [];
		$each(options.plains, function(plain, key){ //keys: width, height, plains: ['left','right'], ['top','bottom']
			size['total'+key.capitalize()] = 0;
			size['computed'+key.capitalize()] = 0;
			plain.each(function(edge){ //top, left, right, bottom
				size['computed'+edge.capitalize()] = 0;
				getStyles.each(function(style,i){ //padding, border, etc.
					//'padding-left'.test('left') size['totalWidth'] = size['width']+[padding-left]
					if(style.test(edge)) {
						styles[style] = styles[style].toInt(); //styles['padding-left'] = 5;
						if(isNaN(styles[style]))styles[style]=0;
						size['total'+key.capitalize()] = size['total'+key.capitalize()]+styles[style];
						size['computed'+edge.capitalize()] = size['computed'+edge.capitalize()]+styles[style];
					}
					//if width != width (so, padding-left, for instance), then subtract that from the total
					if(style.test(edge) && key!=style && 
						(style.test('border') || style.test('padding')) && !subtracted.test(style)) {
						subtracted.push(style);
						size['computed'+key.capitalize()] = size['computed'+key.capitalize()]-styles[style];
					}
				});
			});
		});
		if($chk(size.width)) {
			size.width = size.width+this.offsetWidth+size.computedWidth;
			size.totalWidth = size.width + size.totalWidth;
			delete size.computedWidth;
		}
		if($chk(size.height)) {
			size.height = size.height+this.offsetHeight+size.computedHeight;
			size.totalHeight = size.height + size.totalHeight;
			delete size.computedHeight;
		}
		return $merge(styles, size);
	}
});
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/element.dimensions.js,v $
$Log: element.dimensions.js,v $
Revision 1.3  2007/05/30 20:32:33  newtona
doc updates

Revision 1.2  2007/05/29 22:01:53  newtona
Split element.cnet.js into seperate files; updated docs in files to note this
Changed element.visible to element.isVisible (left old namespace for legacy support)
Fixed Element.empty in prototype.compatibility.js
Removed as many dependencies in common code to element.*.js as possible (espeically element.shortcuts.js)

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories


*/
/*	Script: element.forms.js
		Handles numerous element functions for editing text.
		
		Author:
		Aaron Newton <aaron [dot] newton [at] cnet [dot] com>
		
		Dependencies:
		Mootools - <Moo.js>, <Utilities.js>, <Common.js>, <Array.js>, <String.js>, <Element.js>, <Function.js>
	*/

Element.extend({

/*	Property: getTextInRange
		Returns the text of an input within a range.
		
		Arguments:
		start - beginning select position
		end - end position
	*/

	getTextInRange: function(start, end) {
		return this.getValue().substring(start, end);
	},

/*	Property: getSelectedText
		Get the text selected in an input, returns a range (see <Element.getTextInRange>).
	*/
	getSelectedText: function() {		
		if(window.ie) return document.selection.createRange().text;
		return this.getValue().substring(this.getSelectionStart(), this.getSelectionEnd());
	},

/*	Property: getSelectionStart
		Returns the index of start of the selected text.
	*/

	getSelectionStart: function() {
		if(window.ie) {
			this.focus();
 			var range = document.selection.createRange();
			var tmp = range.duplicate();
			tmp.moveToElementText(this);
			tmp.setEndPoint('EndToEnd', range);
			return tmp.text.length - range.text.length;
		}
		return this.selectionStart;
	},

/*	Property: getSelectionEnd
		Returns the index of end of the selected text.
	*/

	getSelectionEnd: function() {
		if(window.ie) {
			this.focus();
			var range = document.selection.createRange();
			var tmp = range.duplicate();
			tmp.moveToElementText(this);
			tmp.setEndPoint('EndToEnd', range);
			return this.getSelectionStart() + range.text.length;
		}
		return this.selectionEnd;
	},


/*	Property: getSelectedRange
		Gets the range of what is selected within the element.
		
		Returns:
		Object with start and end properties.
		
		Example:
		>{start: 2, end: 12} */

	getSelectedRange: function() {
		return {
			start: this.getSelectionStart(),
			end: this.getSelectionEnd()
		}
	},
	
/*	Property: setCaretPosition
		Sets the caret at the given position.
		
		Arguments:
		pos - (integer) the location to place the caret OR "end" to place it at the end.
	*/

	setCaretPosition: function(pos) {
		if(pos == 'end') pos = this.getValue().length;
		this.selectRange(pos, pos);
		return this;
	},

/*	Property: setCaretPosition
		Returns the caret position (integer). */

	getCaretPosition: function() {
		return this.getSelectedRange().start;
	},
	
/*	Property: selectRange
		Selects text within a given range.
		
		Arguments:
		start - (integer) starting integer
		end - (integer) ending integer
		
		Examples:
(start code)
<input id="test" value="012345">
<script>
$('test').selectRange(2,4); //selects "23"
</script>
(end)
	*/

	selectRange: function(start, end) {
		this.focus();
		if(window.ie) {
			var range = this.createTextRange();
			range.collapse(true);
			range.moveStart('character', start);
			range.moveEnd('character', end - start);
			range.select();
			return this;
		}
		this.setSelectionRange(start, end);
		return this;
	},

/*	Property: insertAtCursor
		Inserts a value at the cursor location; if text is selected, it replaces this text.
		
		Arguments:
		value - (string) value to insert.
		selectText - (boolean) selects the text after it's been inserted
	*/

	insertAtCursor: function(value, select) {
		var start = this.getSelectionStart();
		var end = this.getSelectionEnd();
		this.value = this.getValue().substring(0, start) + value + this.getValue().substring(end, this.getValue().length);
 		if($pick(select, true)) this.selectRange(start, start + value.length);
		else this.setCaretPosition(start + value.length);
		return this;
	},
 
/*	Property: insertAroundCursor
		Inserts values around selected text (think HTML).
		
		Arguments:
		options - (object) key/value set of options.
		
		Options:
		start - (string) the prefix to insert before the selected text
		end - (string) the suffix to insert after the selected text
		defaultMiddle - (string) value to insert between the prefix and the suffix if no text was selected (defaults to "SOMETHING HERE")
	*/

	insertAroundCursor: function(options, select) {
		options = $merge({
			before: '',
			defaultMiddle: 'SOMETHING HERE',
			after: ''
		}, options);
		value = this.getSelectedText() || options.defaultMiddle;
		var start = this.getSelectionStart();
		var end = this.getSelectionEnd();
		if(start == end) {
			var text = this.getValue();
			this.value = text.substring(0, start) + options.before + value + options.after + text.substring(end, text.length);
			this.selectRange(start + options.before.length, end + options.before.length + value.length);
			text = null;
		} else {
			text = this.getValue().substring(start, end);
			this.value = this.getValue().substring(0, start) + options.before + text + options.after + this.getValue().substring(end, this.getValue().length);
			var selStart = start + options.before.length;
			if($pick(select, true)) this.selectRange(selStart, selStart + text.length);
			else this.setCaretPosition(selStart + text.length);
		}	
		return this;
	}
});

/* do not edit below this line */	 
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/element.forms.js,v $
$Log: element.forms.js,v $
Revision 1.4  2007/05/30 20:32:33  newtona
doc updates

Revision 1.3  2007/05/29 23:06:47  newtona
fixed a few returns in element.form.js

Revision 1.2  2007/05/29 22:58:29  newtona
fixed a bug in reference to range as an array (which is no longer the case)

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories

Revision 1.3  2007/05/16 22:20:18  newtona
fixded a bug with insertAround

Revision 1.2  2007/05/16 21:39:41  newtona
added missing ;

Revision 1.1  2007/05/16 20:09:42  newtona
adding new js files to redball.common.full
product.picker.js now has no picklets; these are in the implementations/picklets directory
ProductPicker now detects if there is no doctyp and, if not, sets the position of the picker to be fixed (no IE6 support)
small docs update in element.cnet.js
added new picklet: CNETProductPicker_PricePath
added new picklet: NewsStoryPicker_Path
new file: clipboard.js (allows you to insert text into the OS clipboard)
new file: html.table.js (automates building html tables)
new file: element.forms.js (for managing text inputs - get selected text information, insert content around selection, etc.)


*//*	Script: element.pin.js
		Extends the Mootools <Window> and <Element> classes to allow fixed positioning for an element.

		Dependencies:
		mootools = <Element.js>, <Window.js> and all their dependencies
	
		Class: window
		This extends the <window> class from the <http://mootools.net> library.
	*/
window.extend({
/*	Property: supportsPositionFixed
		Returns true if the browser supports fixed positioning; must be called after DomReady (or it returns null);
	*/
	supportsPositionFixed: function(){
		if(!window.loaded) return null;
		var test = new Element('div').setStyles({
			position: 'fixed',
			top: '0px',
			right: '0px'
		}).injectInside(document.body);
		var supported = (test.offsetTop === 0);
		test.remove();
		return supported;
	}
});

/*	Class: Element
		Extends the <Element> class from the <http://mootools.net> library.
	*/
Element.extend({
/*	Property: pin
		Affixes an element at its current position, even if the window is scrolled.
		
		Arguments: 
		pin - (boolean) true: pin, false: release pin. See also <Element.unpin>.
	*/
	pin: function(enable){
		var p = this.getPosition();
		if(enable!==false) {
			if(!this.pinned) {
				var pos = {
					top: (p.y - window.getScrollTop())+'px',
					left: (p.x - window.getScrollLeft())+'px'
				};
				if(window.supportsPositionFixed()) {
					this.setStyle('position','fixed').setStyles(pos);
				} else {
					this.setStyles({
						position: 'absolute',
						top: p.y+'px',
						left: p.x+'px'
					});
					window.addEvent('scroll', function(){
						var to = {
							top: (pos.top.toInt() + window.getScrollTop())+'px',
							left: (pos.left.toInt() + window.getScrollLeft())+'px'
						};
						this.setStyles(to);
					}.bind(this));
				}
				this.pinned = true;
			}
		} else {
			this.pinned = false;
			this.setStyles({
				top: (p.y+window.getScrollTop())+'px',
				left: (p.x+window.getScrollLeft())+'px',
				position: 'absolute'
			});
		}
		return this;
	},
/*	Property: unpin
		Un-pins an element at its current position (see <Element.pin>).
	*/
	unpin: function(){
		return this.pin(false);
	},
/*	Property: togglepin
		Toggles the pin state of the element.
	*/
	togglepin: function(){
		this.pin(!this.pinned);
	}
});

/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/element.pin.js,v $
$Log: element.pin.js,v $
Revision 1.2  2007/05/30 20:32:33  newtona
doc updates

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories

Revision 1.7  2007/05/04 16:40:50  newtona
fixed a trailing comma typo

Revision 1.6  2007/05/04 01:22:38  newtona
added togglepin

Revision 1.5  2007/05/04 01:06:54  newtona
*sigh* ok, last typo

Revision 1.4  2007/05/04 01:04:35  newtona
woops, missing a "+"

Revision 1.3  2007/05/04 01:03:01  newtona
fixed a bug with unpin

Revision 1.2  2007/05/04 01:01:45  newtona
.pin only pins if the element isn't already pinned.

Revision 1.1  2007/05/04 00:36:19  newtona
*** empty log message ***


*/
/*	Script: element.position.js
Extends the <Element> object.

Dependancies:
	 mootools - <Moo.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>
	 cnet - <element.dimensions.js>

Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>
	
Class: Element
		This extends the <Element> prototype.
	*/
Element.extend({
/*	Property: setPosition
		Sets the location of an element relative to another (defaults to the document body).
		
		Note:
		The element must be absolutely positioned (if it isn't, this method will set it to be);
		
		Arguments:
		options - a key/value object with options
		
		Options:
		relativeTo - (element) the element relative to which to position this one; defaults to document.body.
		position - (string OR object) the aspect of the relativeTo element that this element should be positioned. See position section below.
		edge - (string OR object; optional) the edge of the element to set relative to the relative elements corner; this way you can specify to position this element's upper right corner to the bottom left corner of the relative element. this is optional; the default behavior positions the element's upper left corner to the relative element unless position == center, in which case it positions the center of the element to the center of the relative element. See position section below.
		offset - (object) x/y coordinates for the offset (i.e. {x: 10, y:100} will move it down 100 and to the right 10). Negative values are allowed.
		returnPos - (boolean) don't move the element, but instead just return the position object ({top: '#', left: '#'}); defaults to false

		Position & Edge Options:
		There are two ways to specify the position: strings and objects. The strings are combinations of "left", "right", and "center" with "top" (or "upper"), "bottom", and "center". These are case insensitive. These translate to:

    - upperLeft, topLeft (same thing) - or upperleft, leftupper, LEFTUPPER whatever.
    - bottomLeft
    - centerLeft
    - upperRight, topRight (same thing)
    - bottomRight
    - centerRight
    - centerTop
    - centerBottom
    - center

		Alternatively, you can be a little more expicit by using an object with x and y values. Acceptable values for the x axis are "left", "right", and "center", and for y you can use "top", "bottom" and "center".

    - {x: 'left', y: 'top'} – same as "upperLeft" or "topLeft"
    - {x: 'left', y: 'bottom'} – same as "bottomLeft"
    - etc.

		Using these options you can specify a position for each corner of the relativeTo object as well as the points between those corners (center left, top, right, bottom and the center of the entire object). 

	*/
	setPosition: function(options){
		options = $merge({
			relativeTo: document.body,
			position: {
				x: 'center', //left, center, right
				y: 'center' //top, center, bottom
			},
			edge: false,
			offset: {x:0,y:0},
			returnPos: false,
			overflown: [] //dom elements
		}, options);
		if(options.position == "center" && !options.edge) options.edge == "center";
		//upperRight, bottomRight, centerRight, upperLeft, bottomLeft, centerLeft
		//topRight, topLeft, centerTop, centerBottom, center
		function fixValue(option) {
			if($type(option) != "string") return option;
			option = option.toLowerCase();
			var val = {};
			if(option.test('left')) val.x = 'left';
			else if(option.test('right')) val.x = 'right';
			else val.x = 'center';

			if(option.test('upper')||option.test('top')) val.y = 'top';
			else if (option.test('bottom')) val.y = 'bottom';
			else val.y = 'center';
			dbug.log(val);
			return val;
		};
		options.position = fixValue(options.position);
		if(!options.edge) {
			if(options.position.x == 'center' && options.position.y == 'center')
				options.edge = 'center';
			else options.edge = 'upperLeft'
		}
		
		this.setStyle('position', 'absolute');
		var rel = $(options.relativeTo) || document.body;
		if (window.opera) {
      var top = (rel == document.body)?window.getScrollTop():rel.getTop();
      var left = (rel == document.body)?window.getScrollLeft():rel.getLeft();
    } else {
      var top = (rel == document.body)?window.getScrollTop():rel.getTop(options.overflown);
      var left = (rel == document.body)?window.getScrollLeft():rel.getLeft(options.overflown);
    }
		if (top < 0) top = 0;
    if (left < 0) left = 0;
		var dim = this.getDimensions({computeSize: true});
		var pos = {};
		var prefY = options.offset.y.toInt();
		var prefX = options.offset.x.toInt();
		switch(options.position.x) {
			case 'left':
				pos.x = left + prefX;
				break;
			case 'right':
				pos.x = left + prefX + rel.offsetWidth;
				break;
			default: //center
				pos.x = left + (((rel == document.body)?window.getWidth():rel.offsetWidth)/2) + prefX;
				break;
		};		
		switch(options.position.y) {
			case 'top':
				pos.y = top + prefY;
				break;
			case 'bottom':
				pos.y = top + prefY + rel.offsetHeight;
				break;
			default: //center
				pos.y = top + (((rel == document.body)?window.getHeight():rel.offsetHeight)/2) + prefY;
				break;
		};
		
		if(options.edge){
			options.edge = fixValue(options.edge);
			var edgeOffset = {};
			
			switch(options.edge.x) {
				case 'left':
					edgeOffset.x = 0;
					break;
				case 'right':
					edgeOffset.x = -dim.x-dim.computedRight-dim.computedLeft;
					break;
				default: //center
					edgeOffset.x = -(dim.x/2);
					break;
			};
			switch(options.edge.y) {
				case 'top':
					edgeOffset.y = 0;
					break;
				case 'bottom':
					edgeOffset.y = -dim.y-dim.computedTop-dim.computedBottom;
					break;
				default: //center
					edgeOffset.y = -(dim.y/2);
					break;
			};
			pos.x = pos.x+edgeOffset.x;
			pos.y = pos.y+edgeOffset.y;
		}
		pos = {
			left: ((pos.x >= 0)?pos.x:0).toInt()+'px',
			top: ((pos.y >= 0)?pos.y:0).toInt()+'px'
		};
		if(options.returnPos) return pos;
		if(options.smoothMove) new Fx.SmoothMove(this, options).start(); //deprecated; use Fx.SmoothMove instead
		else this.setStyles(pos);
		return this;
	}
});
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Native/element.position.js,v $
$Log: element.position.js,v $
Revision 1.6  2007/07/17 20:38:44  newtona
Fx.SmoothShow - refactored the exploration of the element dimensions when hidden so that it isn't visible to the user
element.position - refactored to allow for more than just the previous 5 positions, now supports nine: all corners, all mid-points between those corners, and the center
string.cnet.js - fixed up the query string logic to decode values

Revision 1.5  2007/06/27 18:58:15  newtona
checking in built versions of cat libraries; i have not compressed these or anything to prevent accidental publishing
element.position.js: fixed an error with overflown items in Element.setPosition; this fix depends on Mootools 1.11, see: http://forum.mootools.net/viewtopic.php?pid=20391#p20391
default.accordion.nav.js: changed window.onDomReady (which is deprecated) to window.addEvent('domready'...
checking in the build file for redball.global.framework.dev.js - this will build a copy of redball.global using the copy of Mootools in the dev directory (currently, 1.11)

Revision 1.4  2007/06/27 18:30:33  newtona
debugger.footer.js: added a delay for IE to avoid the dreaded "operation aborted" bug
element.position.js: deprecated the smoothMove option in Element.setPosition
Fx.SmoothMove: moving this effect out of Element.setPosition and making it a stand alone Fx class
bat file (build file) changes: adding Fx.SmoothMove

Revision 1.3  2007/05/30 20:32:33  newtona
doc updates

Revision 1.2  2007/05/29 22:01:53  newtona
Split element.cnet.js into seperate files; updated docs in files to note this
Changed element.visible to element.isVisible (left old namespace for legacy support)
Fixed Element.empty in prototype.compatibility.js
Removed as many dependencies in common code to element.*.js as possible (espeically element.shortcuts.js)

Revision 1.1  2007/05/29 21:25:31  newtona
splitting up element.cnet.js (which had grown to be too unweildy); moving things into sub-directories


*/
/*	Script: Fx.Smoothshow.js
Extends the <Element> object.

Dependancies:
	 mootools - <Moo.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>

Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>
	
		Class: Fx.SmoothShow
		Transitions the height, opacity, padding, and margin (but not border) from and to their current height from and to zero, then set's display to none or block and resets the height, opacity, etc. back to their original values.

		Arguments:
		options - a key/value object of options
		
		Options:
		all the options passed along to <Fx.Base> (transition, duration, etc.); (optional); PLUS
		
		styles - (array; optional) css properties to transition in addition to width/height; 
							defaults to ['padding','border','margin']
		mode - (string; optional) 'vertical','horizontal', or 'both' to describe how the element should slide in.
							defaults to 'vertical'
		heightOverride - (integer; optional) height to open to; overrides the default offsetheight
		widthOverride -  (integer; optional) width to open to; overrides the default offsetwidth
	*/
Fx.SmoothShow = Fx.Styles.extend({
	options: {
		styles: ['padding','border','margin'],
		transitionOpacity: true,
		mode:'vertical',
		heightOverride: null,
		widthOverride: null
	},
	initialize: function(el, options){
		this.parent(el, options);
		if(!this.element) return false;
	},
	//Mootools 1.0 compatability; CNET needs this for now
	//just adds "px" to integer values
	fixStyle: function(style, name){
		if(!$type(style)=="number") return style;
		var fix = ['margin', 'padding', 'width', 'height'].some(function(st){return name.test(st, 'i')});
		return (fix)?style+'px':style;
	},
/*	Property: hide
		Transitions the height, opacity, padding, and margin (but not border) from their current height to zero, then set's display to none and resets the height, opacity, etc. back to their original values.	
		*/
	hide: function(){
		if(!this.hiding && !this.showing) {
			if(this.element.getStyle('display') != 'none'){
				this.hiding = true;
				this.showing = false;
				this.hidden = true;
				var startStyles = this.element.getComputedSize({
					styles: this.options.styles,
					mode: this.options.mode
				});
				if (this.element.fxOpacityOk() && this.options.transitionOpacity) startStyles.opacity = 1;
				var zero = {};
				$each(startStyles, function(style, name){
					zero[name] = this.fixStyle(0, name); 
				}, this);
				this.addEvent('onComplete', function(){
					if(this.hidden) {
						this.hiding = false;
						$each(startStyles, function(style, name) {
							startStyles[name] = this.fixStyle(style, name);
						}, this);
						this.element.setStyles(startStyles).setStyle('display','none');
					}
				}.bind(this));
				this.start(zero);
			} else {
				this.callChain();
				this.fireEvent('onComplete', this.element);
			}
		}
		return this;
	},
/*	Property: show
		Sets the display of the element to opacity: 0 and display: block, then transitions the height, opacity, padding, and margin (but not border) from zero to their proper height.
	*/
	show: function(){
		if(!this.showing && !this.hiding) {
			//if(arguments[1]) options.heightOverride = arguments[1];
			if(this.element.getStyle('display') == "none" || 
				 this.element.getStyle('visiblity') == "hidden" || 
				 this.element.getStyle('opacity')==0){
				this.showing = true;
				this.hiding = false;
				this.hidden = false;
				//toggle display, but hide it
				var before = this.element.getStyles('visibility', 'display');
				this.element.setStyles({
					visibility: 'hidden',
					display: 'block'
				});
				//enable opacity effects
				if(this.element.fxOpacityOk() && this.options.transitionOpacity) this.element.setStyle('opacity',0);
				//create the styles for the opened/visible state
				var startStyles = this.element.getComputedSize({
					styles: this.options.styles,
					mode: this.options.mode
				});
				//reset the styles back to hidden now
				this.element.setStyles(before);
				$each(startStyles, function(style, name) {
					startStyles[name] = this.fixStyle(style, name);
				}, this);
				//if we're overridding height/width
				if($chk(this.options.heightOverride)) startStyles['height'] = this.options.heightOverride.toInt()+'px';
				if($chk(this.options.widthOverride)) startStyles['width'] = this.options.widthOverride.toInt()+'px';
				if(this.element.fxOpacityOk() && this.options.transitionOpacity) startStyles.opacity = 1;
				//create the zero state for the beginning of the transition
				var zero = { 
					height: '0px',
					display: 'block'
				};
				$each(startStyles, function(style, name){ zero[name] = this.fixStyle(0, name); }, this);
				//set to zero
				this.element.setStyles(zero);
				//start the effect
				this.start(startStyles);
				this.addEvent('onComplete', function(){
					if(!this.hidden) this.showing = false;
				}.bind(this));
			} else {
				this.callChain();
				this.fireEvent('onComplete', this.element);
			}
		}
		return this;
	},
/*	Property: toggle
		Toggles the element from shown to hidden.
	*/
	toggle: function(){
		if(this.element.getStyle('display') == "none" || 
			 this.element.getStyle('visiblity') == "hidden" || 
			 this.element.getStyle('opacity')==0){
			this.show();
	 } else this.hide();
	 return this;
	}
});
Fx.SmoothShow.implement(new Options);
Fx.SmoothShow.implement(new Events);


/*	Class: Element
		Adds <Fx.SmoothShow> shortcuts to the <Element> class.
	*/
Element.extend({
/*	Property: smoothShow
		Creates a new instance of <Fx.SmoothShow> and calls its *show* method. Returns the instance of <Fx.SmoothShow>.

		Arguments: 
		options	- see <Fx.SmoothShow> options.
	*/
	smoothShow: function(options){
 		if (arguments[1]) { options.heightOverride = arguments[1]; }
		return new Fx.SmoothShow(this, options).show();
	},
/*	Property: smoothHide
		Creates a new instance of <Fx.SmoothShow> and calls its *hide* method. Returns the instance of <Fx.SmoothShow>.

		Arguments: 
		options	- see <Fx.SmoothShow> options.
	*/
	smoothHide: function(options){
 		if (arguments[1]) { options.heightOverride = arguments[1]; }
		return new Fx.SmoothShow(this, options).hide();
	}
});
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Effects/Fx.SmoothShow.js,v $
$Log: Fx.SmoothShow.js,v $
Revision 1.11  2007/07/20 20:05:51  newtona
Fx.Smoothshow: that last fix didn't quite do it.

Revision 1.10  2007/07/20 17:56:24  newtona
Fixed a bug in Fx.SmoothShow that prevented it from getting the dimensions of hidden elements (to show them)

Revision 1.9  2007/07/17 20:38:44  newtona
Fx.SmoothShow - refactored the exploration of the element dimensions when hidden so that it isn't visible to the user
element.position - refactored to allow for more than just the previous 5 positions, now supports nine: all corners, all mid-points between those corners, and the center
string.cnet.js - fixed up the query string logic to decode values

Revision 1.8  2007/06/28 01:28:08  newtona
adding an option for opacity fading to Fx.SmoothShow

Revision 1.7  2007/06/12 20:46:21  newtona
added tbody to html.table.js
added legacy argument support to Fx.SmoothShow

Revision 1.6  2007/05/31 23:57:49  newtona
slight tweak to last checkin

Revision 1.5  2007/05/31 23:55:30  newtona
chaining now works properly; added logic to handle double-click behavior

Revision 1.4  2007/05/31 21:33:42  newtona
.toggle returns the effect

Revision 1.3  2007/05/30 20:32:33  newtona
doc updates

Revision 1.2  2007/05/29 22:46:19  newtona
syntax fix in Fx.SmoothShow; docs update, too.

Revision 1.1  2007/05/29 22:27:02  newtona
rebuilt cat libs, added Fx.SmoothShow.js


*/


/*	Script: Fx.SmoothMove.js
Moves an element to another location (relative to another element) with a transition.

Dependancies:
	 mootools - <Moo.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>, <Fx.Styles>
	 CNET - <element.position.js>

Author:
	Aaron Newton <aaron [dot] newton [at] cnet [dot] com>
		
Class: Fx.SmoothMove
Moves an element to another location (relative to another element) with a transition.

Options:
	relativeTo - (element) the element relative to which to position this one; defaults to document.body.
	position - (string) the aspect of the relativeTo element that this element should be positioned. Options are 'upperRight', 'upperLeft', 'bottomLeft', 'bottomRight', and 'center' (the default). With the exception of center, all other options will make the upper right corner of the positioned element = the specified corner of the relativeTo element. 'center' will make the center point of the positioned element = the center point of the relativeTo element.
	edge - (string; optional) the edge of the element to set relative to the relative elements corner; this way you can specify to position this element's upper right corner to the bottom left corner of the relative element. this is optional; the default behavior positions the element's upper left corner to the relative element unless position == center, in which case it positions the center of the element to the center of the relative element. Acceptable values here are the same as those in the 'position' option.
	offset - (object) x/y coordinates for the offset (i.e. {x: 10, y:100} will move it down 100 and to the right 10). Negative values are allowed.

Example:
(start code)
var mover = new Fx.SmoothMove($('myelement'), {
	relativeTo: $('someOtherElement'),
	position: 'upperRight',
	edge: 'upperLeft',
	offset: {x: 10, y: 100}
});
mover.start(); //moves to the new location
mover.start({
	relativeTo: document.body,
	position: 'center',
	edge: false,
	offset: {x:0,y:0}
}); //move it to the center of the window
(end)
	*/
Fx.SmoothMove = Fx.Styles.extend({
	options: {
		relativeTo: document.body,
		position: 'center',
		edge: false,
		offset: {x:0,y:0}
	},
	initialize: function(el, options){
		this.parent(el,options);
		if(!this.element) return false;
	},
/*	Property: start
		Moves the element to provided destination or the destination specified in the options.
		
		Arguments:
		destination - an object of key/value options specifying a new position for the element; optional. If not provided the values in the options set at initialization will be used.

		Destination:
		See all the arguments defined in the options above for the key/value options in the destination object.
		
		Note:
		If you want to pass in a destination, you must pass in ALL of the options (relativeTo, position, edge, and offset x & y) unless you want to use those already defined in the options at initialization. In other words, if you only pass in one of these options, the rest will be filled in from the options defined at initialization.

		You can always set new defaults using //setOptions//.
	*/
	start: function(destination){
		destination = $merge(this.options, destination, {returnPos: true});
		var styles = this.element.setPosition(destination);
		return this.parent(styles);
	}
});

/*	Class: Element
		Adds <Fx.SmoothMove> shortcuts to the <Element> class.
	*/
Element.extend({
/*	Property: smoothMove
		Creates a new instance of <Fx.SmoothMove> and calls its *start* method. Returns the instance of <Fx.SmoothMove>.

		Arguments: 
		options	- see <Fx.SmoothMove> options.
	*/
	smoothMove: function(options){
		return new Fx.SmoothMove(this, options).start();
	}
});
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Effects/Fx.SmoothMove.js,v $
$Log: Fx.SmoothMove.js,v $
Revision 1.3  2007/06/27 22:45:23  newtona
docs update to overfiew.js
tabswapper gets some events action
fixed a typo in the docs for smoothmove

Revision 1.2  2007/06/27 21:08:10  newtona
added a missing return statement

Revision 1.1  2007/06/27 18:30:33  newtona
debugger.footer.js: added a delay for IE to avoid the dreaded "operation aborted" bug
element.position.js: deprecated the smoothMove option in Element.setPosition
Fx.SmoothMove: moving this effect out of Element.setPosition and making it a stand alone Fx class
bat file (build file) changes: adding Fx.SmoothMove


*/
/*	Script: Fx.Sort
Reorders a group of items with a transition.

Dependancies:
	mootools - <Moo.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>, <Fx.Styles>, <Fx.Elements.js>
	CNET - <element.position.js>

Author:
	Aaron Newton <aaron [dot] newton [at] cnet [dot] com>

Class: Fx.Sort
Reorders a group of items with a transition.

Arguments:
elements - a collection of elements the effects will be applied to.
options - same as <Fx.Base> options, plus the option(s) listed below

Options:
mode - (string; optional) either "vertical" or "horizontal". Defaults to "vertical".

Example:
(start code)
var mysort = new Fx.Sort($$('ul li'), {
	transition: Fx.Transitions.Back.easeInOut,
	duration: 1000
});
mysort.sort([2,0,1]); //a specific order
mysort.forward(); //forward (the original) order
(end)
	*/

Fx.Sort = Fx.Elements.extend({
	options: {
			mode: 'vertical' //or 'horizontal'
	},
	initialize: function(elements, options){
			this.parent(elements, options);
			//set the position of each element to relative
			this.elements.each(function(el){
					if(el.getStyle('position') == 'static') el.setStyle('position', 'relative');
			});
			this.setDefaultOrder();
	},
/*	Property: currentOrder
		An array representing the current sort state.
	*/
	setDefaultOrder: function(){
			this.currentOrder = this.elements.map(function(el, index){
				return index;
			});
	},
/*	Property: sort
		Rearrange the items visually into a new order.
		
		Argument:
		newOrder - (array) the new order for the items.
	
		Example:
		> mySort.sort([2,1,0]); //reverse
	*/
	sort: function(newOrder){
		if($type(newOrder) != 'array') return;
		var top = 0;
		var left = 0;
		//calculate the current location of all the elements
		var current = this.elements.map(function(el, index){
			var size = el.getComputedSize({styles:['border','padding','margin']});
			if(this.options.mode == "vertical") {
				var val =	{
					top: top,
					margin: size['margin-top'],
					height: size.totalHeight
				};
				top += val.height - size['margin-top'];
				return val;
			} else {
				var val = {
					left: left,
					margin: size['margin-left'],
					width: size.totalWidth
				};
				left += val.width;
				return val;
			}
		}, this);
		//if the array passed in is not the same size as
		//the amount of elements we have, fill it in
		//or cut it short
		if (newOrder.length != this.elements.length){
			this.currentOrder.each(function(index) {
				if(!newOrder.contains(index)) newOrder.push(index);
			});
			if(newOrder.length > this.elements.length) {
				newOrder.splice(this.elements.length-1, newOrder.length-this.elements.length);
			}
		}
		
		var top = 0;
		var left = 0;
		var margin = 0;
		var next = {};
		//calculate the new location of each item
		newOrder.each(function(item, index){
			var newPos = {};
			if(this.options.mode == "vertical") {
					newPos.top = top - current[item].top - margin;
					top += current[item].height;
			} else {
					newPos.left = left - current[item].left;	
					left += current[item].width;
			}
			margin = margin + current[item].margin;
			next[item+""]=newPos;
		}, this);
		//execute the effect
		this.start(next);
		//store the current order
		this.currentOrder = newOrder;
		return this;
	},
/*	Property: rearrangeDOM
		Rearranges the DOM to the current sort order.
		
		Arguments:
		newOrder - (array; optional) the order to arrange the DOM with; defaults to this.currentOrder.
	*/
	rearrangeDOM: function(newOrder){
		newOrder = newOrder || this.currentOrder;
		var parent = this.elements[0].getParent();
		var rearranged = [];
		this.elements.setStyle('opacity', 0);
		//move each element and store the new default order
		newOrder.each(function(index) {
			rearranged.push(this.elements[index].injectInside(parent).setStyles({
				top: 0,
				left: 0
			}));
		}, this);
		this.elements.setStyle('opacity', 1);
		this.elements = rearranged;
		this.setDefaultOrder();
		return this;
	},
	getDefaultOrder: function(){
		return this.elements.map(function(el, index) {
			return index;
		})
	},
/*	Property: forward
		Arrange the items in the original order (0,1,2,3,etc).
	*/
		forward: function(){
			return this.sort(this.getDefaultOrder());
		},
/*	Property: backward
		Arrange the items in the reverse of the original order (3,2,1,0);
	*/
		backward: function(){
			return this.sort(this.getDefaultOrder().reverse());
		},
/*	Property: reverse
		Reverse the current order.
	*/
		reverse: function(){
			return this.sort(this.currentOrder.reverse());
		},
/*	Property: sortByElements
		Sort by the order specified in a collection of elements; elements must be an array (collection) of the elements within the elements specified at instantiation.
	
		Arguments:
		elements - (array/collection) a collection or array of elements in the new order

		Example:
		(start code)
		var mySort = new Fx.Sort($$('ul li'));
		mySort.sortByElements($$('#li3, #li2, #li1, #li0'));
		(end)
		
		Note:
		Again, the elements passed in to sortByElements must be the same ones passed in to the effect when it was created.
	*/
		sortByElements: function(elements){
			return this.sort(elements.map(function(el){
				return this.elements.indexOf(el);
			}));
		},
/*	Property: swap
		Swaps the position of one item with another.
		
		Arguments:
		one - the element or its index to swap
		two - the other element or its index to swap
		
		Example:
		(start code)
		var mySort = new Fx.Sort($$('ul li'));
		mySort.swap($('#li3'), $('#li0'));
		//OR
		mySort.swap(3, 0);
		(end)
	*/
		swap: function(one, two) {
			if($type(one) == 'element') {
				one = this.elements.indexOf(one);
				two = this.elements.indexOf(two);
			}
			var indexOne = this.currentOrder.indexOf(one);
			var indexTwo = this.currentOrder.indexOf(two);
			var newOrder = this.currentOrder.copy();
			newOrder[indexOne] = two;
			newOrder[indexTwo] = one;
			this.sort(newOrder);
		}
});
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/mootools.extended/Effects/Fx.Sort.js,v $
$Log: Fx.Sort.js,v $
Revision 1.4  2007/07/19 23:26:00  newtona
a small tweak to fx.sort - hide/unhide elements on dom rearrange...

Revision 1.3  2007/07/19 21:29:36  newtona
moving dom arrangement in Fx.Sort to a stand alone method

Revision 1.2  2007/07/19 18:55:27  newtona
small docs change

Revision 1.1  2007/07/19 18:46:04  newtona
nifty new effect for sorting things


*/