var gListingType = 'scooters';
var gListingRecords = [ { ID:'1249988777134', Name:'Pride Mobility Go-Go Elite Traveller Plus 3-Wheel', NameID:'gogo-elite-traveller-plus-3wheel', Brand:'Pride', Type:'travel', Wheels:'3', Price:'1199', HeaviestPiece:'32.5', "BatteryCharge (Range up to)":'12', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'22', MaximumSeatToDeckHeight:'17.75', MultipleSeatingOptions:'y', TopSpeed:'4.5', Length:'40', Width:'21.125', Weight:'84', WeightCapacity:'300', TurningRadius:'34.5', GroundClearance:'1.75' },{ ID:'1249988777212', Name:'Pride Mobility Go-Go Elite Traveller Plus 4-Wheel', NameID:'gogo-elite-traveller-plus-4wheel', Brand:'Pride', Type:'travel', Wheels:'4', Price:'1249', HeaviestPiece:'35', "BatteryCharge (Range up to)":'12', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'23.25', MaximumSeatToDeckHeight:'17.75', MultipleSeatingOptions:'y', TopSpeed:'4.5', Length:'40.25', Width:'21.125', Weight:'87', WeightCapacity:'300', TurningRadius:'45.75', GroundClearance:'1.5' },{ ID:'1249988777275', Name:'Pride Mobility Go-Go Elite Traveller Plus HD 3-Wheel', NameID:'gogo-elite-traveller-plus-hd-3wheel', Brand:'Pride', Type:'travel', Wheels:'3', Price:'1299', HeaviestPiece:'32.5', "BatteryCharge (Range up to)":'12', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'22', MaximumSeatToDeckHeight:'17.75', MultipleSeatingOptions:'y', TopSpeed:'4.5', Length:'40', Width:'21.125', Weight:'84', WeightCapacity:'325', TurningRadius:'34.5', GroundClearance:'1.75' },{ ID:'1249988777337', Name:'Pride Mobility Go-Go Elite Traveller Plus HD 4-Wheel', NameID:'gogo-elite-traveller-plus-hd-4wheel', Brand:'Pride', Type:'travel', Wheels:'4', Price:'1349', HeaviestPiece:'32.5', "BatteryCharge (Range up to)":'12', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'23.25', MaximumSeatToDeckHeight:'17.75', MultipleSeatingOptions:'y', TopSpeed:'4.5', Length:'40.25', Width:'21.125', Weight:'87', WeightCapacity:'325', TurningRadius:'45.75', GroundClearance:'1.5' },{ ID:'1249988777400', Name:'Pride Mobility Go-Go Ultra X 3-Wheel Travel Scooter', NameID:'gogo-ultra-x-scooter--3-wheel', Brand:'Pride', Type:'travel', Wheels:'3', Price:'789', HeaviestPiece:'28', "BatteryCharge (Range up to)":'8', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'22.75', MaximumSeatToDeckHeight:'17.25', MultipleSeatingOptions:'n', TopSpeed:'4', Length:'37', Width:'19.5', Weight:'72', WeightCapacity:'260', TurningRadius:'32.5', GroundClearance:'1.375' },{ ID:'1249988777478', Name:'Pride Mobility Go-Go Ultra X 4-Wheel Travel Scooter', NameID:'gogo-ultra-x-scooter--4-wheel', Brand:'Pride', Type:'travel', Wheels:'4', Price:'879', HeaviestPiece:'33.5', "BatteryCharge (Range up to)":'8', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'22.75', MaximumSeatToDeckHeight:'17.25', MultipleSeatingOptions:'n', TopSpeed:'4', Length:'39.75', Width:'19.5', Weight:'78.5', WeightCapacity:'260', TurningRadius:'44.125', GroundClearance:'1.375' },{ ID:'1249988777556', Name:'evRider Classic Foldable Travel Scooter', NameID:'tzora-classic', Brand:'evRider', Type:'travel', Wheels:'4', Price:'1299', HeaviestPiece:'29', "BatteryCharge (Range up to)":'12', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'20.5', MaximumSeatToDeckHeight:'17', MultipleSeatingOptions:'n', TopSpeed:'4.5', Length:'43', Width:'22', Weight:'62', WeightCapacity:'250', TurningRadius:'30', GroundClearance:'3.5' },{ ID:'1249988777884', Name:'evRider Gusto Scooter - 3 Wheel ', NameID:'evr-gusto', Brand:'evRider', Type:'full-size', Wheels:'3', Price:'2099', HeaviestPiece:'49', "BatteryCharge (Range up to)":'20', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'21', MaximumSeatToDeckHeight:'16', MultipleSeatingOptions:'n', TopSpeed:'8', Length:'55', Width:'24', Weight:'155', WeightCapacity:'350', TurningRadius:'39', GroundClearance:'5' },{ ID:'1249988777946', Name:'Pride Mobility Revo Scooter 3-Wheel ', NameID:'revo-3wheel', Brand:'Pride', Type:'full-size', Wheels:'3', Price:'1499', HeaviestPiece:'48', "BatteryCharge (Range up to)":'20', MaximumInclineRating:'6', MaximumSeatToGroundHeight:'23.75', MaximumSeatToDeckHeight:'19', MultipleSeatingOptions:'n', TopSpeed:'4.5', Length:'43.25', Width:'21.5', Weight:'106.5', WeightCapacity:'300', TurningRadius:'38', GroundClearance:'2.25' },{ ID:'1249988778025', Name:'Pride Mobility Revo Scooter 4-Wheel', NameID:'revo-4wheel', Brand:'Pride', Type:'full-size', Wheels:'4', Price:'1599', HeaviestPiece:'51.5', "BatteryCharge (Range up to)":'20', MaximumInclineRating:'7', MaximumSeatToGroundHeight:'23.75', MaximumSeatToDeckHeight:'19', MultipleSeatingOptions:'n', TopSpeed:'4.5', Length:'44.75', Width:'21.5', Weight:'125', WeightCapacity:'300', TurningRadius:'50', GroundClearance:'2.25' },{ ID:'1249988778087', Name:'Pride Mobility Victory 10 3-Wheel Electric Scooter', NameID:'victory-10-3whee3', Brand:'Pride', Type:'full-size', Wheels:'3', Price:'1999', HeaviestPiece:'54.5', "BatteryCharge (Range up to)":'15.5', MaximumInclineRating:'6', MaximumSeatToGroundHeight:'25', MaximumSeatToDeckHeight:'19', MultipleSeatingOptions:'y', TopSpeed:'5.25', Length:'45.25', Width:'22.25', Weight:'131.5', WeightCapacity:'350', TurningRadius:'42', GroundClearance:'3' },{ ID:'1249988778150', Name:'Pride Mobility Victory 10 4-Wheel', NameID:'victory-10-4whee4', Brand:'Pride', Type:'full-size', Wheels:'4', Price:'2199', HeaviestPiece:'61', "BatteryCharge (Range up to)":'15.5', MaximumInclineRating:'6', MaximumSeatToGroundHeight:'25', MaximumSeatToDeckHeight:'19', MultipleSeatingOptions:'y', TopSpeed:'5.25', Length:'47', Width:'22.25', Weight:'132.5', WeightCapacity:'350', TurningRadius:'54', GroundClearance:'3' },{ ID:'1249988778228', Name:'Pride Mobility Victory 9 3-Wheel Electric Scooter', NameID:'victory-9-3wheel', Brand:'Pride', Type:'full-size', Wheels:'3', Price:'1549', HeaviestPiece:'48.5', "BatteryCharge (Range up to)":'13', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'25.75', MaximumSeatToDeckHeight:'18.75', MultipleSeatingOptions:'y', TopSpeed:'5.25', Length:'43.5', Width:'22.25', Weight:'117.5', WeightCapacity:'300', TurningRadius:'40.25', GroundClearance:'2' },{ ID:'1249988778290', Name:'Pride Mobility Victory 9 4-Wheel Electric Scooter', NameID:'victory-9-4wheel', Brand:'Pride', Type:'full-size', Wheels:'4', Price:'1649', HeaviestPiece:'45', "BatteryCharge (Range up to)":'13', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'25.75', MaximumSeatToDeckHeight:'18.75', MultipleSeatingOptions:'y', TopSpeed:'5.25', Length:'45.5', Width:'22.5', Weight:'131', WeightCapacity:'300', TurningRadius:'51.5', GroundClearance:'2.25' },{ ID:'1249988778353', Name:'Pride Mobility Celebrity X 3-Wheel Electric Scooter', NameID:'celebrity-x-3-wheel', Brand:'Pride', Type:'heavy duty', Wheels:'3', Price:'1899', HeaviestPiece:'56', "BatteryCharge (Range up to)":'25', MaximumInclineRating:'6', MaximumSeatToGroundHeight:'25.125', MaximumSeatToDeckHeight:'18.5', MultipleSeatingOptions:'y', TopSpeed:'6', Length:'46', Width:'24', Weight:'190.5', WeightCapacity:'350', TurningRadius:'41.5', GroundClearance:'3.5' },{ ID:'1249988778415', Name:'Pride Mobility Celebrity X 4-Wheel Electric Scooter', NameID:'celebrity-x-4-wheel', Brand:'Pride', Type:'heavy duty', Wheels:'4', Price:'2099', HeaviestPiece:'66', "BatteryCharge (Range up to)":'25', MaximumInclineRating:'6', MaximumSeatToGroundHeight:'34', MaximumSeatToDeckHeight:'52', MultipleSeatingOptions:'y', TopSpeed:'6', Length:'46.5', Width:'24', Weight:'198.5', WeightCapacity:'350', TurningRadius:'57.25', GroundClearance:'3.5' },{ ID:'1249988778556', Name:'ActiveCare Osprey 4410 Scooter 4-Wheel', NameID:'osprey4410', Brand:'ActiveCare', Type:'heavy duty', Wheels:'4', Price:'3443', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'38', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'28', MaximumSeatToDeckHeight:'23', MultipleSeatingOptions:'n/a', TopSpeed:'9', Length:'54', Width:'29', Weight:'300', WeightCapacity:'500', TurningRadius:'73', GroundClearance:'7' },{ ID:'1249988778821', Name:'Pride Mobility Wrangler PMV Personal Mobility Vehicle 4-Wheel', NameID:'wrangler-pmv', Brand:'Pride', Type:'luxury', Wheels:'4', Price:'3999', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'20', MaximumInclineRating:'5', MaximumSeatToGroundHeight:'31.75', MaximumSeatToDeckHeight:'23', MultipleSeatingOptions:'y', TopSpeed:'10', Length:'63', Width:'31', Weight:'216', WeightCapacity:'400', TurningRadius:'77', GroundClearance:'7' },{ ID:'1253033785434', Name:"Zip'r Roo Travel Scooter 3-Wheel", NameID:'ziprroo', Brand:'zipr', Type:'travel', Wheels:'3', Price:'649', HeaviestPiece:'31', "BatteryCharge (Range up to)":'10', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'21.5', MaximumSeatToDeckHeight:'18', MultipleSeatingOptions:'y', TopSpeed:'4.25', Length:'37.4', Width:'19.5', Weight:'107', WeightCapacity:'250', TurningRadius:'31.5', GroundClearance:'2' },{ ID:'1253034699247', Name:'ActiveCare Prowler 3410 Scooter 4-Wheel', NameID:'prowler4', Brand:'ActiveCare', Type:'heavy duty', Wheels:'4', Price:'2367', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'23', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'27', MaximumSeatToDeckHeight:'22', MultipleSeatingOptions:'n/a', TopSpeed:'7', Length:'51', Width:'26', Weight:'233', WeightCapacity:'500', TurningRadius:'69', GroundClearance:'5' },{ ID:'1254774586970', Name:'Pride Mobility Victory 9 with Power Elevating Seat 3-Wheel Electric Scooter', NameID:'victory9ps', Brand:'Pride', Type:'full-size', Wheels:'3', Price:'1999', HeaviestPiece:'59.5', "BatteryCharge (Range up to)":'13', MaximumInclineRating:'8', MaximumSeatToGroundHeight:'29.5', MaximumSeatToDeckHeight:'18.75', MultipleSeatingOptions:'power', TopSpeed:'5.25', Length:'43.5', Width:'23', Weight:'131', WeightCapacity:'300', TurningRadius:'41', GroundClearance:'2' },{ ID:'1254861819185', Name:'Shoprider Flagship 4-Wheel Scooter', NameID:'flagship', Brand:'Shoprider', Type:'luxury', Wheels:'4', Price:'5999', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'25', MaximumInclineRating:'15', MaximumSeatToGroundHeight:'', MaximumSeatToDeckHeight:'', MultipleSeatingOptions:'n/a', TopSpeed:'7', Length:'63', Width:'29', Weight:'328', WeightCapacity:'350', TurningRadius:'70', GroundClearance:'' },{ ID:'1266877735343', Name:'ActiveCare Prowler 3310 Scooter 3-Wheel', NameID:'prowler3', Brand:'ActiveCare', Type:'heavy duty', Wheels:'3', Price:'2267', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'23', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'27', MaximumSeatToDeckHeight:'22', MultipleSeatingOptions:'n/a', TopSpeed:'7', Length:'51', Width:'26', Weight:'233', WeightCapacity:'500', TurningRadius:'68', GroundClearance:'5' },{ ID:'1269353185866', Name:'EV Rider Vita 4 Wheel Scooter', NameID:'vita', Brand:'evRider', Type:'luxury', Wheels:'4', Price:'3999', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'30', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'29', MaximumSeatToDeckHeight:'18', MultipleSeatingOptions:'n', TopSpeed:'9', Length:'55.5', Width:'28', Weight:'248', WeightCapacity:'400', TurningRadius:'50.5', GroundClearance:'3.5' },{ ID:'1269353939419', Name:'EV Rider Royale 3 Wheel Scooter', NameID:'royale3', Brand:'evRider', Type:'luxury', Wheels:'3', Price:'4999', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'32', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'31', MaximumSeatToDeckHeight:'21', MultipleSeatingOptions:'y', TopSpeed:'11.5', Length:'62', Width:'29', Weight:'337', WeightCapacity:'350', TurningRadius:'50', GroundClearance:'6' },{ ID:'1269354436287', Name:'EV Rider Royale 4 Wheel Scooter', NameID:'royale4', Brand:'evRider', Type:'luxury', Wheels:'4', Price:'5199', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'32', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'31', MaximumSeatToDeckHeight:'21', MultipleSeatingOptions:'y', TopSpeed:'11.5', Length:'62', Width:'29', Weight:'332', WeightCapacity:'350', TurningRadius:'50', GroundClearance:'6' },{ ID:'1269530609620', Name:'ActiveCare Pilot 2310 Scooter 3-Wheel', NameID:'pilot3', Brand:'ActiveCare', Type:'full-size', Wheels:'3', Price:'1899', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'22', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'26', MaximumSeatToDeckHeight:'21', MultipleSeatingOptions:'n', TopSpeed:'6', Length:'47', Width:'22', Weight:'170', WeightCapacity:'350', TurningRadius:'53', GroundClearance:'3' },{ ID:'1269530788166', Name:'ActiveCare Pilot 2410 Scooter 4-Wheel', NameID:'pilot4', Brand:'ActiveCare', Type:'full-size', Wheels:'4', Price:'1999', HeaviestPiece:'N/A', "BatteryCharge (Range up to)":'22', MaximumInclineRating:'12', MaximumSeatToGroundHeight:'26', MaximumSeatToDeckHeight:'21', MultipleSeatingOptions:'n', TopSpeed:'6', Length:'47', Width:'22', Weight:'174', WeightCapacity:'350', TurningRadius:'54', GroundClearance:'3' },{ ID:'1271181526048', Name:'Pride Mobility Legend 3-Wheel Electric Scooter', NameID:'legend3wheel', Brand:'Pride', Type:'heavy duty', Wheels:'3', Price:'2299', HeaviestPiece:'61', "BatteryCharge (Range up to)":'22', MaximumInclineRating:'', MaximumSeatToGroundHeight:'', MaximumSeatToDeckHeight:'', MultipleSeatingOptions:'n', TopSpeed:'5.75', Length:'45.5', Width:'24', Weight:'157', WeightCapacity:'350', TurningRadius:'41', GroundClearance:'3.5' },{ ID:'1271181891640', Name:'Pride Mobility Legend 4-Wheel Electric Scooter', NameID:'legend4wheel', Brand:'Pride', Type:'heavy duty', Wheels:'4', Price:'2499', HeaviestPiece:'61', "BatteryCharge (Range up to)":'22', MaximumInclineRating:'', MaximumSeatToGroundHeight:'', MaximumSeatToDeckHeight:'', MultipleSeatingOptions:'n', TopSpeed:'5.75', Length:'47', Width:'24', Weight:'166', WeightCapacity:'350', TurningRadius:'54', GroundClearance:'3.5' },{ ID:'1271182112311', Name:'Pride Mobility Maxima 3-Wheel Electric Scooter', NameID:'max3wheel', Brand:'Pride', Type:'heavy duty', Wheels:'3', Price:'3298', HeaviestPiece:'66.5', "BatteryCharge (Range up to)":'18', MaximumInclineRating:'', MaximumSeatToGroundHeight:'', MaximumSeatToDeckHeight:'', MultipleSeatingOptions:'n', TopSpeed:'5.25', Length:'46.5', Width:'28', Weight:'171', WeightCapacity:'500', TurningRadius:'50.40', GroundClearance:'4.25' },{ ID:'1271182254153', Name:'Pride Mobility Maxima 4-Wheel Electric Scooter', NameID:'max4wheel', Brand:'Pride', Type:'heavy duty', Wheels:'4', Price:'3498', HeaviestPiece:'75.5', "BatteryCharge (Range up to)":'13', MaximumInclineRating:'', MaximumSeatToGroundHeight:'', MaximumSeatToDeckHeight:'', MultipleSeatingOptions:'n', TopSpeed:'5.25', Length:'46.875', Width:'28', Weight:'189', WeightCapacity:'500', TurningRadius:'54', GroundClearance:'3.25' }];
var gControlHTML = "<div style='padding:0 0 10px 0; background-color:#E67B2D; color:#FFFFFF; clear:both; margin-top:5px;'><div style='padding:3px 5px 5px 5px; float:right; font-size:17px; line-height:105%; font-weight:bold'>Make your selections in the<br/>drop-down windows below.</div><div style='padding:7px 0 0 10px; font-weight:bold; font-size:23px;'>Scooter Finder</div><table cellpadding='4' cellspacing='0' width='100%'><tr style='font-weight:bold;background-color:#e4e1dc;padding:5px;color:#000000;'><td valign='top'><div style='float:left;'>Show: <select name=\"Type\" class='filter' onchange='FilterChanged(this)' ><option selected=\"selected\" value=\"\" >All Types</option> <option value=\"full-size\" >full-size</option> <option value=\"heavy duty\" >heavy duty</option> <option value=\"luxury\" >luxury</option> <option value=\"travel\" >travel</option> </select> <select name=\"Brand\" class='filter' onchange='FilterChanged(this)' ><option selected=\"selected\" value=\"\" >All Brands</option> <option value=\"ActiveCare\" >ActiveCare</option> <option value=\"Pride\" >Pride</option> <option value=\"Shoprider\" >Shoprider</option> <option value=\"evRider\" >evRider</option> <option value=\"zipr\" >zipr</option> </select> <select name=\"WeightCapacity\" class='filter' onchange='FilterChanged(this)' ><option selected=\"selected\" value=\"\" >All Weight Capacities</option> <option value=\"250\" >250</option> <option value=\"260\" >260</option> <option value=\"300\" >300</option> <option value=\"325\" >325</option> <option value=\"350\" >350</option> <option value=\"400\" >400</option> <option value=\"500\" >500</option> </select> <select name=\"Wheels\" class='filter' onchange='FilterChanged(this)' ><option selected=\"selected\" value=\"\" >All Wheels</option> <option value=\"3\" >3</option> <option value=\"4\" >4</option> </select> <input type=\"button\" value=\"Start Over\" style='display:none' id='ShowAll' onclick=\"ShowAll()\" /></div><div style='float:right; width:75px;' id='ListTotal'></div></td></tr></table><div style='height:0px; overflow:hidden;'><div id='CompareButtonWrapperDiv' style='padding:10px 0; text-align:right;'><a  href=\"javascript:Compare()\"><img  src=\"/lib/yhst-13787673511982/compare.gif\" height=\"33\"  width=\"127\"  id='CompareButton' border='0' /></a><span style='display:none' id='CompareProgress' ><img  src=\"/lib/yhst-13787673511982/progressbar.gif\" height=\"24\"  width=\"24\"   border='0' /> Comparing...</span><br><label class='CompareAllLabel'><input name=\"compareAll\" type=\"checkbox\" onclick='CompareAll(this)' value=\"1\" /> Compare all</label></div></div></div>"//****************************************************************
//****************************************************************
//	COPYRIGHT 2000, Vertex Software
//****************************************************************
//****************************************************************


//----------------------------------------------------------------
//----------------------------------------------------------------
// General routines for "flattening" JavaScript objects into a string
// and then "expanding" the string back into an object. Useful for
// passing arrays and other objects across the internet.
//----------------------------------------------------------------
//----------------------------------------------------------------


var kDateTypeID = "_date";
var kDoubleQuote = "_quote";


//****************************************************************
// GetObjectType
// Returns the actual object type for any object passed to it.
// PARAMETERS:
//	obj:object			Object for which the type will be returned.
// RETURNS:
//	string				The type of object.
// EXAMPLE:
//	var objectType = GetObjectType( [ 1,2 ] );
//		objectType --> "Array"
//****************************************************************
function GetObjectType( obj, ignoreConstructors ) {
	var type = typeof obj;
	try {
		if (typeof obj == "function") return "function"; 
		if (typeof obj == "undefined") return "undefined"; 
		if (typeof obj == "date") return "date"; 
		if (obj == null) return type; 
		if (typeof obj.constructor != "unknown" ) {
			var constructor = "" + obj.constructor;
			if (constructor) {
				if (constructor.search( /function ([^(]+)/gi ) > -1) {
					type = RegExp.$1;
					}
				}
				// 03MAR2007 RFM - Added Pack.IgnoreConstructors to allow custom objects to be packed
			if (Pack.IgnoreConstructors && !type.match(/(string|date|array|number|boolean)/i)) type = "object"; 
			if (ignoreConstructors) type = "object"; 
			}
		else if (!ignoreConstructors && typeof obj.pop == "function" && typeof obj.join == "function") {
			// HACK!!!!!
			// Attempted global fix to the problem whereby an array's Constructor comes back unknown
			type = "Array";
			} 
		}
	catch (error) {
		alert( "GetObjectType: " + error.description );
		}
	return type;
	}

//----------------------------------------------------------------
// EncodeQueryStringCharacters
// Must encode all special query string characters as HTML
// before sending over the wire otherwise they get stripped!!!
//----------------------------------------------------------------
function EncodeQueryStringCharacters(text) {
	text = text.replace( /\+/g, "%2B" );
	return text;
	}


//----------------------------------------------------------------
// Flatten
//----------------------------------------------------------------
function Flatten(obj){
	var data = "";
	try {
		var objectType = GetObjectType(obj).toLowerCase(); 
		if (objectType == "date") {
			data += "'" + kDateTypeID + obj.getTime() + "'";
			}
		else {
			switch (objectType) {
				case "object":
					for(var attribute in obj){
						if (typeof attribute == undefined || GetObjectType( obj[attribute]) == "undefined") continue;
						if (data) data += ", ";
						// This fix breaks when an atribute with a number is parsed!!!!
						// Need to find out what the real pattern was and tighten it up!!!
						//
						if (new String(attribute).match( /^[0-9]+$/g )) {
							// !!!!!!! ERROR!!! We have an array masquerading as an object! Only
							// know solution is to call "" + obj.constructor before hand to cause the
							// constructor to get updated. No idea why it works.
							//
							// Occurs in SitePress when used ClientSide to pass FormProcessing objects
							objectType = "objectarray";
							}
						switch (objectType) {
							case "object":
								data += attribute + ":" 
								break;
							}
						switch (GetObjectType( obj[attribute]).toLowerCase()) {
							case "date":
								data += "'" + kDateTypeID + obj[attribute].getTime() + "'";
								break;
							case "string":
								var quote = (obj[attribute].match( /\'/g ) ? "\"" : "'");
								if (obj[attribute].match(/\'/g ) && obj[attribute].match( /\"/g)) {
									quote = "\"";
									// 26NOV2007 RFM - Replacing double quotes with single quotes will cause
									// data loss!! Obvious when dealing with HTML attributes wich have two 
									// types of quotes already
									//obj[attribute] = obj[attribute].replace( /\"/g, "'" );
									obj[attribute] = obj[attribute].replace( /\"/g, kDoubleQuote );
									}
								var stringValue = obj[attribute];
								data += quote + EncodeQueryStringCharacters(escape(stringValue)) + quote;
								break;
							case "object":
								data += Flatten( obj[attribute] );
								break;
							case "array":
								data += Flatten( obj[attribute] );
								break;
							case "undefined":
								break;
							default:
								data += obj[attribute] 
								}
						 }
					if (objectType == "objectarray") {
						data = "[ " + data + " ]";
						}
					else {
						data = "{ " + data + " }";
						}
					break;
				case "array":
					data += "[ ";
					for (var item=0; item<obj.length; item++) {
						if (item > 0) data += ","; 
						data +=  Flatten( obj[item] );
						}
					data += "]";
					break;
				case "string":
					var quote = (obj.match( /\'/g ) ? "\"" : "'");
					if (obj.match(/\'/g ) && obj.match( /\"/g)) {
						quote = "\"";
						// 26NOV2007 RFM - Replacing double quotes with single quotes will cause
						// data loss!! Obvious when dealing with HTML attributes wich have two 
						// types of quotes already
						//obj = obj.replace( /\"/g, "'" );
						obj = obj.replace( /\"/g, kDoubleQuote );
						}
					// 10JAN2006 RFM - replace newlines and tabs with symbolic values
					obj = obj.replace( /\n/g, "\\n" ).replace( /\t/g, "\\t" ).replace( /\r/g, "\\r" );
					data += quote + obj + quote;
					break;
				case "number":
					data += obj;
					break;
				default:
					window.status = ( "UNKNOWN: " + objectType + " = " + attribute );
				}
			}
		}
	catch (error) {
		alert( "Flatten: " + error.description );
		}	
	return data;
    }


//----------------------------------------------------------------
// Expand
//----------------------------------------------------------------
function Expand(obj){
    for(var attribute in obj){
		switch (typeof obj[attribute]) {
			case "string":
				if (obj[attribute].indexOf(kDateTypeID) > -1) {
					obj[attribute] = new Date( parseInt( obj[attribute].substring( kDateTypeID.length  ) ))
					}
				else {
					obj[attribute] = unescape( obj[attribute] );
					}
				break;
			case "object":
				obj[attribute] = Expand( obj[attribute] );
				break;
			}
         }
	return obj;
    }


//****************************************************************
// Pack
// Converts any Javascript entity passed to it into a textual
// representation suitable for tranmission over the internet.
// The packed entity can later be "unpacked" by calling <A HREF='/global/scripts/index.asp?functionID=Unpack&includeFile=/global/scripts/Serialization.asp'>Unpack</A>.
// PARAMETERS:
//	entity:any		Any valid Javascript entity such as an object, array, string, or number.
// RETURNS:
//	string			Testxaul representation of <I>entity</I> suitable for tranmission over the internet.
//****************************************************************
function Pack( entity) {
	switch (typeof entity) {
		case "object":
			entity = Flatten( entity );
			break;
		}
	return entity;
	}


//****************************************************************
// Unpack
// Converts a text string created by calling <A HREF='/global/scripts/index.asp?functionID=Pack&includeFile=/global/scripts/Serialization.asp'>Pack</A> into it's original
// Javascript object. 
// PARAMETERS:
//	packedResult:string			String created from call to <A HREF='/global/scripts/index.asp?functionID=Pack&includeFile=/global/scripts/Serialization.asp'>Pack</A>.
// RETURNS:
//	any							An object corresponding the the type of the original entity passed to the <A HREF='/global/scripts/index.asp?functionID=Pack&includeFile=/global/scripts/Serialization.asp'>Pack</A> routine.
// EXAMPLE:
//	var testObject = {};
//		testObject.now = new Date();
//		testObject.text = "this is text";
//		testObject.number = 56;
//	var packedTest = Pack( testObject );
//	packedTest -->	"{ now:'_date977089255006', text:'this%20is%20text', number:56 }"
//	var newObject = Unpack( packedTest );
//		newObject.number --> 56
//		newObject.text  --> "this is text";
//****************************************************************
function Unpack( packedResult ) {
// Sorry Charlie, 4.0 browsers don't support this
//	try {
		eval( "var result = " + packedResult );
		switch (typeof result) {
			case "object":
				result = Expand( result );
				break;
			}
//		}
//	catch ( error ) {
//		}
	return result;
	}


//****************************************************************
// GetObjectAttributeList
// Returns a comma-delimited list of all of the attributes for 
// <I>object</I>.
// PARAMETERS:
//		object:object				Object for which comma-delimited list of attributes is to be retrieved.
// RETURNS:
//		string						Comma-delimited list of attribute names for <I>object</I>
//****************************************************************
function GetObjectAttributeList( object ) {
	var attributes = "";	
	for (var attribute in object) {
		if (attributes) attributes += ",";
		attributes += attribute; 
		}
	return attributes;
	}


//****************************************************************
// DenormalizeObject
// Returns a new object with any nested objects denormalized or flattened
// into a single object having unique attributes created from teh nested objects.
// For example, given an object with the the attributes person.address1.city, person.address2.city,
// DenormalizeObject will return a new object with teh attributes personaddress1city and personaddress2city
// without any nested objects.
// PARAMETERS:
//		object:object				Object to be denormalized.
// RETURNS:
//		object						Denormalized version on <I>object</I>.
//****************************************************************
function DenormalizeObject( object, attributeDelimiter ) {
	var denormalizeObject = {};
	try {
		if (!attributeDelimiter) attributeDelimiter = "_"; 
		for(var attribute in object){
			if (attribute && object[attribute] != null)  {
				var objectType = GetObjectType(object[attribute]).toLowerCase(); 
				switch (objectType) {
					case "object":
						var denormalizeSubObject = DenormalizeObject( object[attribute] );
						for(var subattribute in denormalizeSubObject){
							if (subattribute && denormalizeSubObject[subattribute] != null)  {
								eval( "denormalizeObject." + attribute + attributeDelimiter + subattribute + " = denormalizeSubObject[subattribute];" )
								}
							}
						break;
					case "array":
						for (var item=0; item<object[attribute].length; item++) {
							var subObject = object[attribute][item];
							var subobjectType = GetObjectType(subObject).toLowerCase(); 
							if (subobjectType == "object") {
								var denormalizeSubObject = DenormalizeObject( subObject );
								for(var subattribute in denormalizeSubObject){
									eval( "denormalizeObject." + attribute + item + attributeDelimiter + subattribute + " = denormalizeSubObject[subattribute];" );
									}
								}
							else {
								eval( "denormalizeObject." + attribute +  item  + " = subObject;" );
								}
							}
						break;
					default:
						eval( "denormalizeObject." + attribute + " = object[attribute];" );
						break;
					}
				}
			}
		}
	catch (error) {
		WriteBR( "DenormalizeObject: " + error.description );
		}
	return denormalizeObject;
	}



//****************************************************************
// NormalizeObject
// Returns a new object with any denormalized attributes expanded into
// equivalent nested objects.
// PARAMETERS:
//		object:object				Object to be normalized.
// RETURNS:
//		object						Normalized version on <I>object</I>.
//****************************************************************
function NormalizeObject( object, attributeDelimiter ) {
	var normalizedObject = {};
	try {
		var indexPattern = new RegExp( "[^0-9]+[0-9]+" );
		var currentElementIndex = -1;
		if (!attributeDelimiter) attributeDelimiter = "_"; 
		//  attribute_attributeB# --->  object.attribute[].attributeB
		for(var attribute in object){
			var elements = attribute.split( attributeDelimiter );
			if (elements.length > 1) {
				var subObject = elements[0];
				var subObjectAttribute = elements[1];
				if (subObject.search(indexPattern) > -1) {
					var elementIndex = parseInt( subObject.replace( /[^0-9]+/, "" ) );
					subObject = subObject.replace( /[0-9]+/, "" )
					if (eval( "typeof normalizedObject." + subObject ) == "undefined" ) {
						eval( "normalizedObject." + subObject + " = new Array()" );
						}
//					if (eval( "typeof normalizedObject." + subObject + "[ elementIndex ]"  ) == "undefined" ) {
					if (currentElementIndex != elementIndex ) {
						currentElementIndex = elementIndex;
						eval( "normalizedObject." + subObject + ".push( {} )"  );
						}
					eval( "normalizedObject." + subObject + "[ normalizedObject." + subObject + ".length - 1 ]." + subObjectAttribute + " = object[attribute];" );
					}
				else {
					if (eval( "typeof normalizedObject." + subObject ) == "undefined" ) {
						eval( "normalizedObject." + subObject + " = {}" );
						}
					eval( "normalizedObject." + subObject + "." + subObjectAttribute + " = object[attribute];" );
					}
				}
			else {
				eval( "normalizedObject." + attribute + " = object[attribute];" );
				}
			}
		}
	catch( error ) {
		alert( "NormalizeObject: " + error.description );
		}
	return normalizedObject;
	}



//****************************************************************
// ExtractObjectAttributes
// Returns an new object having only the attributes specified in <I>attributeList</I>
// copied from <I>object</I>.
// PARAMETERS:
//	object:object			Object from whcih attributes specified in <I>attributeList</I> will be extracted.
//	attributeList:string	Comma-delimited list of attributes to be extracted from <I>object</I>.
// RETURNS:
//	object					New object having only the attributes specified in <I>attributeList</I> extracted from <I>object</I>.
//****************************************************************
function ExtractObjectAttributes( object, attributeList ) {
	var attributes = attributeList.split( "," );
	var newObject = {};
	for (var item=0; item<attributes.length; item++) {
		var attribute = attributes[item];
		eval( "newObject." + attribute+ " = object." + attribute );
		}
	return newObject;
	}


//****************************************************************
// CopyObjectAttributes
// Copies all of the attributes from <I>sourceObject</I> to <I>destinationObject</I>. Existing 
// attributes in <I>destinationObject</I> are only overwritten if <I>sourceObject</I> has
// the same attribute.
// PARAMETERS:
//	sourceObject:object			Object from which attributes will be copied.
//	destinationObject:object	Object to which attributes will be copied.
//	[defaultValue]:any			Default value used for attributes not found in soureObject.
//  [excludeUndefined]:boolean	If true, undefined values are filtered
//	[excludeFields]:string		Comma-delimited list of fields to exclude. Default is to copy all fields;
//****************************************************************
function CopyObjectAttributes( sourceObject, destinationObject, defaultValue, excludeUndefined, excludeFields ) {
	try {
		// 19MAY2009 RFM - TSS Self Help - Added ability to exclude fields
		if (excludeFields) excludeFields = MapList(excludeFields)
		for(var attribute in sourceObject){
			if (excludeFields && excludeFields[attribute]) continue;
			var value = sourceObject[ attribute ];
			// 13MAY2009 RFM - Added for Babytalk
			if (excludeUndefined && typeof value == "undefined") continue; 
			if (typeof defaultValue != "undefined" && typeof value == "undefined") value = defaultValue;
			destinationObject[ attribute ] = value;
			}
		}
	catch (error) {
		alert( "CopyObjectAttributes: " + error.description );
		}
	}




//================================================================
// Encode64
// This code was written by Tyler Akins and has been placed in the
// public domain.  It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
//================================================================
function Encode64(input) {
	try {
		// 18JUN2008 RFM - replaced string cat with array
		var output = [];
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		var keyStr = Encode64.keyStr;
		do {
			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.push( keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4) );
			} 
		while (i < input.length);
		return output.join("");
		}
	catch (error) {
		alert( "Encode64: " + error.description  );
		}
	return input;
	}
Encode64.keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";


//===========================================================
// Decode64
// This code was written by Tyler Akins and has been placed in the
// public domain.  It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
//===========================================================
function Decode64(input) {
	try {
		// 18JUN2008 RFM - replaced string cat with array
		var output = [];
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		var keyStr = Encode64.keyStr;
		// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		do {
			enc1 = keyStr.indexOf(input.charAt(i++));
			enc2 = keyStr.indexOf(input.charAt(i++));
			enc3 = keyStr.indexOf(input.charAt(i++));
			enc4 = keyStr.indexOf(input.charAt(i++));
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
			output.push( String.fromCharCode(chr1) );
			if (enc3 != 64) output.push( String.fromCharCode(chr2) );
			if (enc4 != 64) output.push( String.fromCharCode(chr3) );
			} 
		while (i < input.length);
		return output.join("");
		}
	catch (error) {
		alert( "Decode64" + error.description  );
		}
	return input;
	}

function GetCookie_CS(name) {
try {
var aCookie = document.cookie.split("; ");
for (var i=0; i < aCookie.length; i++) {
var nameValuePair = aCookie[i].split("=");
// 14AUG2009 RFM - Dont' return undefined!
//if (name == nameValuePair[0]) return unescape(nameValuePair[1]);
if (name == nameValuePair[0]) return unescape(nameValuePair[1] || "");
}
}
catch (error) {
alert( "GetCookie_CS: " + error.description  );
}
return "";
}function SetCookie_CS( name, value, expires ) {
try {
var today = new Date();
var domain = document.location.hostname;
if (typeof expires == "undefined") expires = new Date(today.getTime() + (1000*60*60*24*365));
var attributes = (expires == 0 ? "" : ";expires=" + expires.toGMTString()) + ";domain=" + domain;
document.cookie = name + "=" + escape(value) + attributes;
}
catch (error) {
alert( "SetCookie_CS: " + error.description  );
}
}function PascalToTitleCase( pascalCaseString ) {
try {
convertedText = pascalCaseString || "";
// Special case for the letter "A" as in Please Select a Date.
convertedText = convertedText.replace( /([a-z])A([A-Z])/g, "$1 a $2" );
convertedText = convertedText.replace( /([a-z])([A-Z0-9])/g, "$1 $2" );
convertedText = convertedText.replace( /([0-9])([A-Z])/g, "$1 $2" );
convertedText = convertedText.replace( /([A-Z])([A-Z][a-z])/g, "$1 $2" );
return convertedText;
}
catch (error) {
WriteAlert( "PascalToTitleCase: " + error.description, false, true );
}
return pascalCaseString;
}function SingularToPlural( text, itemCount ) {
try {
if (!text) text = "";
// 25MAY2010 RFM - DG - added option to dynamically return based on item count.
if (itemCount == 1) return text;
if (text.match( /s$/)) return text;
if (text.match( /^(cod|deer|fish|offspring|perch|sheep|trout)$/gi)) return text;
if (text.match( /^([a-z]+)man$/gi) ) return RegExp.$1 + "men";
if (text.match( /^foot$/gi) ) return "feet";
if (text.match( /^goose$/gi) ) return "geese";
if (text.match( /^([a-z]+)ouse$/gi) ) return RegExp.$1 + "ice";
if (text.match( /^([a-z]+)ooth$/gi) ) return RegExp.$1 + "eeth";
if (text.match( /(calf|elf|half|hoof|knife|leaf|life|loaf|scarf|self|sheaf|shelf|thief|wife|wolf)/gi )) return RegExp.$1.replace( /(fe|f)$/, "ves" );
if (text.match( /(echo|embargo|potato|tomato|torpedo|veto)/gi )) return RegExp.$1 + "es";
// 25MAY2010 RFM - Correct rule is ies only is not vowel before y! http://www.spelling.hemscott.net/plurals2.html
//if (text.match( /^([a-z]+)y$/gi) ) return RegExp.$1 + "ies";
if (text.match( /^([a-z]*[^aeiou])y$/gi)) return RegExp.$1 + "ies";
return text + "s";
}
catch (error) {
WriteAlert( "SingularToPlural: " + error.description, false, true );
}
return text;
}



//===========================================================
// Initialize
//===========================================================
function Initialize( ) {
	try {
		jQuery( "div.page-controls" ).before(gControlHTML).hide();
		jQuery( "div.page-controls + IMG" ).hide();
		RestoreFilterCriteria();
		AddCompareControls();
		FilterChanged();
		// 28SEP2009 KBM - Moves the Compare Button to the bottom of the Scooter List, as per requested by TSS
		jQuery(document).ready( function() {
			//window.setTimeout( "jQuery('.section-item:last').after( gCompareButtonHTML );", 500 );
			window.setTimeout( "jQuery('#CompareButtonWrapperDiv').insertAfter( jQuery('.section-item:last').parent() );", 500 );
			} );
		}
	catch (error) {
		alert( "Initialize: " + error.description  );
		}
	}


//===========================================================
// Compare
//===========================================================
function Compare( runCompare ) {
	try {
		if (jQuery( "input:checked" ).length < 2) {
			alert( "You must first select two or more products to compare by clicking the \"Add to compare\" checkboxes next to each product." );
			return;
			} 
		if (!runCompare) { 
			jQuery( "#CompareButton" ).hide();
			jQuery( "#CompareProgress" ).show();
			window.setTimeout( function() { Compare(true); }, 1000 );
			return;
			}
		var selectedRecords = GetRecordsToCompare();
		if (jQuery("#CompareContent").length ==0) jQuery("BODY").append( "<div style='display:none' id='CompareContent'></div>" );
		var compareContent = jQuery("#CompareContent");
		var html = [];
		var recordURLIndex = GetRecordURLsByNameID();
		html.push( "<style type='text/css'>" );
		html.push( ".compareHeader { font-weight:bold; background-color:#e4e1dc; white-space:nowrap; }\n" );
		html.push( "table#CompareResults { border-collapse:collapse; }\n" );
		html.push( "table#CompareResults TR.odd { background-color:#F7DFCE; }\n" );
		html.push( "table#CompareResults TR TD { border-style:solid; border:1px solid #000000; border-collapse:collapse; padding:2px 3px; line-height:115%; vertical-align:bottom; }\n" );
		<!-- 10.2.09 SZ added styles to keep compare table from scrolling -->
		html.push( "#TB_ajaxContent { overflow-x:auto; overflow-y:hidden; padding:2px 15px 35px 15px; }\n" );
		html.push( "</style>" );
		html.push( "<table id='CompareResults' width='100%' cellspacing='0' border='0' >" );
		var features = [];
		for (var attribute in selectedRecords[0]) {
			features.push(attribute);
			}
		// Features -> Columns:Feature Name|Record1|Recors2
		for (var featureIndex=0; featureIndex<features.length; featureIndex++) {	
			var feature = features[featureIndex];
			if (feature == "NameID") continue; 
			var isName = (feature == "Name");
			html.push( "<tr valign='top' class='" + (featureIndex%2 ? "odd" : "even") + "'>" );
			html.push( "<td " + (isName ? " nowrap " :  "class='compareHeader'") + ">" );
			html.push( PascalToTitleCase(feature == "Name" ? "" : feature) );
			html.push( "</td>" );
			for (var item=0; item<selectedRecords.length; item++) {
				var record = selectedRecords[item];
				var featureValue = GetFeatureValue( record, feature );
				html.push( "<td align='center'>" );				
				if (isName) {
					var recordLink = recordURLIndex[ record.NameID ];
					var recordURL = recordLink.href;
					html.push( "<a style='cursor:pointer' href='" + recordURL + "'>" );
					html.push( "<b>" + featureValue + "</b>"  );
					var imageSrc = recordLink.childNodes[0].src;
					if (imageSrc) html.push( "<br><img border='0' src='" + imageSrc + "'>" );
					html.push( "</a>" );
					} 
				else {
					html.push( featureValue );
					}
				html.push( "</td>" );
				}
			html.push( "</tr>" );
			}
		html.push( "</table>" );
		compareContent.html( html.join("") );
		tb_show( "Product Comparison", "#TB_inline?height=" + (compareContent.height()) + "&width=" + Math.min(900,(selectedRecords.length*200)) + "&inlineId=CompareContent", false);
		jQuery( "#CompareProgress" ).hide();
		jQuery( "#CompareButton" ).show();
		jQuery( "select" ).css( "cursor", "default" );
		}
	catch (error) {
		alert( "Compare: " + error.description  );
		}
	}


//===========================================================
// GetFeatureValue
//===========================================================
function GetFeatureValue( record, feature ) {
	try {
		var value = record[feature] || "";
		var units = "";
		if (value == "-") value = ""; 
		if (feature.match(/length|width|height|radius|clearance/gi)) units = "in."; 
		// 15SEP2009 KBM - Added case for heaviest piece
		//if (feature.match(/weight/gi)) units = "lbs."; 
		if (feature.match(/weight|heaviestpiece/gi) && !value.match(/n\/a/i)) units = "lbs.";
		if (feature.match(/speed/gi)) units = "mph"; 
		// 15SEP2009 KBM - Added cases for range, incline, and price
		if (feature.match(/range/gi)) units = "miles"; 
		if (feature.match(/incline/gi)) units = "degrees";
		if (feature.match(/price/gi)) value = "$" + value;
		if (value && units) value = value + "&nbsp;" + units;
		if (!value) value = "&nbsp;"
		return value;
		}
	catch (error) {
		alert( "GetFeatureValue: " + error.description  );
		}
	return "&nbsp;"
	}


//===========================================================
// GetRecordURLsByNameID
//===========================================================
function GetRecordURLsByNameID( ) {
	var recordIndex = {};
	try {
		var recordLinks = jQuery("A", jQuery("DIV.paginated-content")[0] ).each( function() {
			if (this.href.match( /([^\.\/]+)\.html/) && this.childNodes.length > 0) {
				if (!recordIndex[RegExp.$1]) recordIndex[RegExp.$1] = this; 
				}
			} );
		}
	catch (error) {
		alert( "GetRecordURLsByNameID: " + error.description  );
		}
	return recordIndex;
	}


//===========================================================
// CompareAll
//===========================================================
function CompareAll( checkbox ) {
	try {
		jQuery("input.Compare").each( function() {
			if (this.style.display == "none") return; 
			this.checked = checkbox.checked;
			} );
		}
	catch (error) {
		alert( "CompareAll: " + error.description  );
		}
	}


//===========================================================
// GetRecordsToCompare
//===========================================================
function GetRecordsToCompare( ) {
	var selectedRecords = [];
	try {
		var excludedFields =  "ID";
		for (var item=0; item<gListingRecords.length; item++) {
			var record = gListingRecords[item];
			if (!document.getElementById(record.NameID).checked) continue;
			var compareRecord = {};
			CopyObjectAttributes( record, compareRecord, "", true, excludedFields )
			selectedRecords.push( compareRecord );
			}
		}
	catch (error) {
		alert( "GetRecordsToCompare: " + error.description  );
		}
	return selectedRecords;
	}


//-----------------------------------------------------------
// AddCompareControls
//-----------------------------------------------------------
function AddCompareControls( ) {
	try {
		jQuery("div.s-add-to-cart").each( function() {
			var nameID = ( jQuery("A",this).attr("href").match( /([^\.\/]+)\.html$/g ) ? RegExp.$1 : "");
			jQuery(this).append( "<nobr><label class='CompareLabel' style='cursor:pointer'><input class='Compare' type='checkbox' id='" + nameID + "' value='" + nameID + "'> Add to compare</label></nobr>" );
			} );
		}
	catch (error) {
		alert( "AddCompareControls: " + error.description );
		}
	}


//-----------------------------------------------------------
// GetFilterCriteria
//-----------------------------------------------------------
function GetFilterCriteria( ) {
	try {
		var criteria = {};
		jQuery( "select.filter" ).each( function() {
			criteria[ this.name ] = this.value;
			} );
		return criteria;
		}
	catch (error) {
		alert( "GetFilterCriteria: " + error.description  );
		}
	return {};
	}



//-----------------------------------------------------------
// RestoreFilterCriteria
//-----------------------------------------------------------
function RestoreFilterCriteria( ) {
	try {
		jQuery( "select.filter" ).each( function() {
			var cookieValue = GetCookie_CS( this.name );
			if (!cookieValue) return;
			this.value = cookieValue;
			} );
		}
	catch (error) {
		alert( "RestoreFilterCriteria: " + error.description  );
		}
	}



//-----------------------------------------------------------
// GetSelectedItems
//-----------------------------------------------------------
function GetSelectedItems( keyField ) {
	var items = (keyField ? {} : [] );
	try {
		var criteria = GetFilterCriteria();
		for (var item=0; item<gListingRecords.length; item++) {
			var record = gListingRecords[item];
			var matched = true;
			for (var field in criteria) {
				if (!criteria[field]) continue;
				if (record[field] == criteria[field]) continue;
				matched = false;
				break;
				}
			if (matched) {
				if (keyField) items[record[keyField].toLowerCase()] = record;
				if (!keyField) items.push( record );
				}
			}
		}
	catch (error) {
		alert( "GetSelectedItems: " + error.description  );
		}
	return items;
	}


//-----------------------------------------------------------
// GetSelectedItemsByName
//-----------------------------------------------------------
function GetSelectedItemsByName(  ) {
	try {
		return GetSelectedItems( "NameID" );
		}
	catch (error) {
		alert( "GetSelectedItemsByName: " + error.description  );
		}
	return {};
	}



//===========================================================
// FilterChanged
//===========================================================
function FilterChanged( select, runTask ) {
	try {
		if (!runTask) {
			document.body.style.cursor = "wait";
			window.setTimeout( function() { FilterChanged(select,true), 100 } );
			}
		else {
			if (select) {
				SetCookie_CS( select.name, select.value );	
				}
			UpdateDisplay();
			UpdateFilterSelects();
			document.body.style.cursor = "default";
			}
		}
	catch (error) {
		alert( "FilterChanged: " + error.description  );
		}
	}


//===========================================================
// RecordsToList
//===========================================================
function RecordsToList( records, fieldList, delimiter, uniqueValues ) {
	var list = new Array();
	try {
		if (!delimiter) delimiter = ",";
		var item = 0;
		var fields = fieldList.split(",");
		uniqueValues = (uniqueValues ? new Array() : "");
		for (var i in records) {
			var value = "";
			for (var item=0; item<fields.length; item++) {
				value += records[i][ fields[item] ] || "";
				}
			if (value) {
				if (uniqueValues) {
					if (uniqueValues[value]) continue; 
					uniqueValues[value] = 1;
					}
				list.push(value);
				}
			}
		}
	catch (error) {
		alert( "RecordsToList: " + error.description  );
		}
	return list.join(delimiter);
	}



//===========================================================
// MapToArray
//===========================================================
function MapToArray( map, objectsOnly ) {
	var indexArray = new Array();
	try {
		for ( var key in map) {
			// 05FEB2006 RFM - filter out undefined values. Used in CreateRecordFilterNav
			if (typeof map[key] == "undefined") continue; 
			if (!objectsOnly || objectsOnly && typeof map[key] == "object") indexArray.push( map[key] );
			}
		}
	catch (error) {
		WriteAlert( "MapToArray: " + error.description );
		}
	return indexArray;
	}


//===========================================================
// MapList
//===========================================================
function MapList( commaDelimitedList, useIndexAsValue, delimiter ) {
	var map = new Array();
	try {
		if (!delimiter) delimiter = ","; 
		if (!commaDelimitedList) commaDelimitedList = ""; 
		var keys = commaDelimitedList.split( delimiter );
		for (var item=0; item<keys.length; item++) {
			if (!keys[item]) continue;
			map[ keys[item] ] =  (useIndexAsValue ? item : keys[item] );
			}
		}
	catch (error) {
		alert( "MapList: " + error.description  );
		}
	return map;
	}



//===========================================================
// ShowAll
//===========================================================
function ShowAll( runTask ) {
	try {
		var showAllButton = document.getElementById("ShowAll");
		if (!runTask) {
			showAllButton.style.cursor = "wait";
			showAllButton.disabled = true;
			document.body.style.cursor = "wait";
			window.setTimeout( function() { ShowAll(true), 100 } );
			}
		else {
			var criteria = GetFilterCriteria();
			for (var field in criteria) {
				jQuery( "select[name='" + field + "']" ).each( function() {
					if (this.selectedIndex == 0) return; 
					this.selectedIndex = 0;
					FilterChanged(this);
					} );
				}
			document.body.style.cursor = "default";
			showAllButton.style.cursor = "default";
			showAllButton.disabled = false;
			}
		}
	catch (error) {
		alert( "ShowAll: " + error.description  );
		}
	}


//===========================================================
// UpdateFilterSelects
//===========================================================
function UpdateFilterSelects( ) {
	try {
		var criteria = GetFilterCriteria();
		var records = GetSelectedItems();
		var isFiltered = false;
		for (var field in criteria) {
			var values = RecordsToList(records,field,"", true).split(",");
			jQuery( "select[name='" + field + "']" ).each( function() {
				var defaultOption = this.options[0].text;
				this.options.length = 0;
				this.options[this.options.length] = new Option( defaultOption, "" );
				for (var item=0; item<values.length; item++) {
					var value = values[item];
					if (!value) continue; 
					var text = value;
					switch (field) {
						case "WeightCapacity": text += " lbs"; break; 
						case "Wheels": text += " wheels"; break; 
						default: text = field + " is " + value; break; 
						}
					var newOption = new Option( text, value );
					this.options[this.options.length] = newOption;
					newOption.selected = (value == criteria[field]);
					}
				if (this.value) isFiltered = true;
				//if (this.options.length == 2) this.options[1].selected = true;
				} );
			}
		jQuery("#ShowAll").css( "display", isFiltered ? "" : "none" );
		}
	catch (error) {
		alert( "UpdateFilterSelects: " + error.description  );
		}
	}



//===========================================================
// UpdateCompareControls
//===========================================================
function UpdateCompareControls( displayed ) {
	try {
		var noCompare = (displayed < 2);
		jQuery( ".CompareAllLabel,.CompareLabel,#CompareButton" ).css( "display", (noCompare ? "none" : "") );
		jQuery("input[name='compareAll']").each( function() { this.checked = false; } );
		}
	catch (error) {
		alert( "UpdateCompareControls: " + error.description  );
		}
	}


//===========================================================
// UpdateDisplay
//===========================================================
function UpdateDisplay( ) {
	var displayed = 0;
	try {
		var records = GetSelectedItemsByName( );
		jQuery( "div.section-item" ).each( function() {
			var recordURL = jQuery( "DIV.name-detail > A:first", this ).attr("href");
			var nameID = (recordURL.match(/^http/) ? recordURL.split("/")[3] : recordURL).replace( ".html", "").toLowerCase();
			this.style.display = (records[nameID] ? "" : "none");
			var isDisplayed = (this.style.display != "none");
			jQuery("input[value='" + nameID + "']").each( function() { 
				if (this.checked && !isDisplayed) this.checked = false; 
				this.style.display = (isDisplayed ? "" : "none");
				} );
			if (isDisplayed) displayed += 1;
			} );
		jQuery("#ListTotal").text( displayed + " " + gListingType);
		UpdateCompareControls( displayed );
		}
	catch (error) {
		alert( "UpdateDisplay: " + error.description  );
		}
	return displayed;
	}


jQuery( Initialize )

