/**
* This file should be shared by all web properties of AARP and contain functions
* useful to most contexts (and hopefully serve as a reference style/architectural
* guide).
* 
* As to whether some of these global objects should be more like a dictionary
* or a closure, that really depends on needs. If the object in question needs its
* own environment, go with closures.
* 
* @author Kaiser Shahid, 2007-10-02
*/

/* NATIVE PROTOTYPES SHOULD GO HERE */
String.prototype.trim = function() { return this.replace( /^\s+/g, '' ).replace( /\s+$/g, '' ); }
String.prototype.ltrim = function() { return this.replace( /^\s+/g, '' ); }
String.prototype.rtrim = function() { return this.replace( /\s+$/g, '' ); }
String.__ord_map = { " ": 32, "!": 33, '"': 34, "#": 35, "$": 36, "%": 37, "&": 38, "'": 39, "(": 40, ")": 41, "*": 42, "+": 43, ",": 44, "-": 45, ".": 46, "/": 47, "0": 48, "1": 49, "2": 50, "3": 51, "4": 52, "5": 53, "6": 54, "7": 55, "8": 56, "9": 57, ":": 58, ";": 59, "<": 60, "=": 61, ">": 62, "?": 63, "@": 64, "A": 65, "B": 66, "C": 67, "D": 68, "E": 69, "F": 70, "G": 71, "H": 72, "I": 73, "J": 74, "K": 75, "L": 76, "M": 77, "N": 78, "O": 79, "P": 80, "Q": 81, "R": 82, "S": 83, "T": 84, "U": 85, "V": 86, "W": 87, "X": 88, "Y": 89, "Z": 90, "[": 91, "\\": 92, "]": 93, "^": 94, "_": 95, "`": 96, "a": 97, "b": 98, "c": 99, "d": 100, "e": 101, "f": 102, "g": 103, "h": 104, "i": 105, "j": 106, "k": 107, "l": 108, "m": 109, "n": 110, "o": 111, "p": 112, "q": 113, "r": 114, "s": 115, "t": 116, "u": 117, "v": 118, "w": 119, "x": 120, "y": 121, "z": 122, "{": 123, "|": 124, "}": 125, "~": 126 };
String.__chr_map = { '32': " ", '33': "!", '34': '"', '35': "#", '36': "$", '37': "%", '38': "&", '39': "'", '40': "(", '41': ")", '42': "*", '43': "+", '44': ",", '45': "-", '46': ".", '47': "/", '48': "0", '49': "1", '50': "2", '51': "3", '52': "4", '53': "5", '54': "6", '55': "7", '56': "8", '57': "9", '58': ":", '59': ";", '60': "<", '61': "=", '62': ">", '63': "?", '64': "@", '65': "A", '66': "B", '67': "C", '68': "D", '69': "E", '70': "F", '71': "G", '72': "H", '73': "I", '74': "J", '75': "K", '76': "L", '77': "M", '78': "N", '79': "O", '80': "P", '81': "Q", '82': "R", '83': "S", '84': "T", '85': "U", '86': "V", '87': "W", '88': "X", '89': "Y", '90': "Z", '91': "[", "\\": 92, '93': "]", '94': "^", '95': "_", '96': "`", '97': "a", '98': "b", '99': "c", '100': "d", '101': "e", '102': "f", '103': "g", '104': "h", '105': "i", '106': "j", '107': "k", '108': "l", '109': "m", '110': "n", '111': "o", '112': "p", '113': "q", '114': "r", '115': "s", '116': "t", '117': "u", '118': "v", '119': "w", '120': "x", '121': "y", '122': "z", '123': "{", '124': "|", '125': "}", '126': "~" };

function $merge()
{
	if ( arguments.length < 2 )
		return arguments[0];
	
	var obj = {};
	for ( var i = 0; i < arguments.length; i++ )
	{
		for ( var j in arguments[i] )
			obj[j] = arguments[i][j];
	}
	
	return obj;
}

// gets ASCII value of char c
// TODO: make this work nice with chars 128-255?
String.ord = function( c )
{
	c = c.charAt( 0 );
	if ( String.__ord_map[c] )
		return String.__ord_map[c];
	else
		return -1;
}

// gets ASCII character of int c
String.chr = function( c )
{
	c = c + '';
	if ( String.__chr_map[c] )
		return String.__chr_map[c];
	else
		return null;
}

var AARP = {
	__version__: '1.0b1'
	
	/*
	store & set user's login state
	*/
	// NEW [2008-02-14 | kaiser]: awesome, no one told me these additions were happening, so I had to infer it
	// from eForce's personalization component. GOTTA LOVE THE PROCESS AND TRANSPARENCY HERE!!!@1
	, User: { name: '', firstName: '', mail: 0, isLoggedIn: false, accountStatus: '', expirationDate: '' }
	, setUser: function()
	{
		var inf = Cookies.get( 'header' );
		if ( inf == null ) return;
		inf = inf.replace( /\"/g, '' ) ;
		var inf = inf.split( '|' );
		
		AARP.User.isLoggedIn = true;
		
		AARP.User.name = inf[2];
		AARP.User.firstName = inf[0];
		AARP.User.messages = inf[1];
		
		try { AARP.User.accountStatus = inf[3]; } catch ( e ) { }
		try { AARP.User.expirationDate = inf[4]; } catch ( e ) { }
	}
	/*
	Helper Objects/Functions
	*/
	
	/**
	* Hopefully a useful function to open new windows. Usage:
	* 
	* AARP.newWindow( 'http://...', '_new', 500, 500 );
	* AARP.newWindow( 'http://...', '_new', 500, 600, { titlebar: true, menubar: true, addressbar: true } );
	*
	* @param href string Where the window should point to
	* @param name string The name of the window (equivalent to target attribute)
	* @param w int (Optional) Width of window
	* @param h int (Optional) Height of window
	* @param opts int (Optional) Additional options, defined below, are either true or false.
	*        - centered (window centered on screen), scrollbars, titlebar, addressbar, menubar, statusbar, toolbar, resizable, left, top
	*        By default, everything is false, except for resizable and centered.
	* @return object The reference to the new window
	*/
	
	, newWindow: function( href, name )
	{
		var w = '', h = '', opts = {};
		if ( arguments.length > 2 )
			w = arguments[2];
		if ( arguments.length > 3 )
			h = arguments[3];
		if ( arguments.length > 4 )
			opts = arguments[4];
		
		w = parseInt( w );
		if ( !w ) w = 100;
		h = parseInt( h );
		if ( !h ) h = 100;
		
		// merge default values on absense of these items. otherwise, presence denotes true
		for ( var x in AARP.__newWindow_default_opts )
		{
			if ( opts[x] ) opts[x] = 1;
			else opts[x] = AARP.__newWindow_default_opts[x];
		}
		
		var xpos = 0, ypos = 0;
		if ( ( parseInt( navigator.appVersion ) >= 4 ) && (opts.centered) )
		{
			xpos = (screen.width - w) / 2;
			ypos = (screen.height - h) / 2;
		}
		
		var args = "width=" + w + "," 
			+ "height=" + h + "," 
			+ "location=" + opts.addressbar + "," 
			+ "menubar=" + opts.menubar + ","
			+ "resizable=" + opts.resizable + ","
			+ "scrollbars=" + opts.scrollbars + ","
			+ "status=" + opts.statusbar + "," 
			+ "titlebar=" + opts.titlebar + ","
			+ "toolbar=" + opts.toolbar + ","
			+ "hotkeys=" + opts.hotkeys + ","
			+ "screenx=" + xpos + "," // netscape
			+ "screeny=" + ypos + "," // netscape
			+ "left=" + xpos + ","
			+ "top=" + ypos
		;
		
		return window.open( href, name, args );
	}
	, __newWindow_default_opts: { 
		addressbar: 0
		, menubar: 0
		, resizable: 1
		, scrollbars: 0
		, statusbar: 0
		, titlebar: 0
		, toolbar: 0
		, left: 0
		, top: 0
		, hotkeys: 0
		, centered: 1
	}
	
	/*
	The 'page' variable contains convenient components of the URL for all sorts of use.
	setPage() parsers the URL into these components.
	*/
	
	// NEW [2008-02-12 | kaiser] added some new properties:
	// is_authoring; site {dotorg,bulletin}; path_effective; pathc_effective
	, page: { url: '', protocol: 'http', host: '', port: '80', path: '', pathc: [], file: '', querystring: '', parameters: {}, anchor: ''
		, is_authoring: false, site: 'dotorg', path_effective: '', pathc_effective: []
	}
	, setPage: function()
	{
		AARP.page.url = document.location.toString();
		
		// separate path from querystring. [0] is full path, [1] is querystring
		var __path_qs = AARP.page.url.split( '?', 2 );
		
		// if url is 'http://www.aarp.org/health/', tmp would be [http:, , www.aarp.org, health, ]
		// if url is 'http://www.aarp.org/health/page.html', tmp would be [http:, , www.aarp.org, health, page.html]
		var tmp = __path_qs[0].split( '/' );
		
		// protocol
		var tmp2 = tmp.shift(); tmp.shift();
		AARP.page.protocol = tmp2.substring( 0, tmp2.length - 1 );
		
		// domain & port
		tmp2 = tmp.shift().split( ':' );
		AARP.page.host = tmp2[0];
		if ( tmp2.length > 1 )
			AARP.page.port = tmp2[1];
		
		// remove page from end (page could be an empty string)
		tmp2 = '';
		if ( tmp.length > 0 )
			tmp2 = tmp.pop();
		
		// remove & save anchor
		var anchor = [];
		if ( __path_qs[1] ) anchor = __path_qs[1].split( '#', 2 );
		else
		{
			// no querystring, so anchor would be immediately after page
			anchor = tmp2.split( '#', 2 );
			tmp2 = anchor[0];
		}
		
		if ( anchor[1] ) AARP.page.anchor = anchor[1];
		
		// set path & filename	
		AARP.page.file = tmp2.substring( 0, tmp2.length );
		AARP.page.path = '/' + tmp.join( '/' );
		if ( AARP.page.path == '/' )
			AARP.page.path = '';
		else
			AARP.page.pathc = AARP.page.path.substring( 1, AARP.page.path.length ).split( '/' );
		//AARP.page.pathc = tmp;
		
		// parse querystring into dictionary
		if ( __path_qs.length > 1 && __path_qs[1] != '' )
		{
			AARP.page.querystring = __path_qs[1];
			tmp = __path_qs[1].split( '&' ); //AARP.page.querystring.split( '&' );
			var ptr = AARP.page.parameters;
			for ( var p = 0; p < tmp.length; p++ )
			{
				var tmp3 = tmp[p].split( '=', 2 );
				if ( tmp3.length == 1 ) tmp2[1] = '';

				// check if the parameter already exists. if so, either convert to
				// an array, or append
				if ( ptr[tmp3[0]] )
				{
					// array
					if ( ptr[tmp3[0]].push )
						ptr[tmp3[0]].push( unescape( tmp3[1] ) );
					else
						ptr[tmp3[0]] = [ ptr[tmp3[0]], unescape( tmp3[1] ) ];
				}
				else
					ptr[tmp3[0]] = unescape( tmp3[1] );
			}
		}

		// TODO: add ?querystring to end?
		var portStr = '';
		if ( AARP.page.port != '80' )
			portStr = ':' + AARP.page.port;

		AARP.page.url = AARP.page.protocol + '://' + AARP.page.host + portStr + AARP.page.path + '/' + AARP.page.file;

		// NEW [2008-02-12 | kaiser]: set site and whether or not in authoring mode,
		// and also set what the real path(s) would be.

		if ( AARP.page.url.match( /bulletin[^.]*\.aarp/ ) ) AARP.page.site = 'bulletin';
		if ( AARP.page.url.match( /products[^.]*\.aarp/ ) ) AARP.page.site = 'products';
		if ( AARP.page.host.match( /w-d|w-s|author/ ) || AARP.page.port == '4402' )
		{
			AARP.page.is_authoring = true;

			// set what would be the published path. if we're on /content/bulletin.html 
			// or /content/home.html, set the root values
			if ( AARP.page.pathc.length > 2 )
			{
				//alert(AARP.page.pathc);
				last_dir = '';
				for ( var i = 2; i < AARP.page.pathc.length; i++ )
				{
					AARP.page.pathc_effective.push( AARP.page.pathc[i] );
					last_dir = AARP.page.pathc[i];
				}
				// if last_dir IS articles, the filename is an article, otherwise, it should be a valid channel.
				if ( last_dir != 'articles' )
				{
					var tf = AARP.page.file.split( '.' );
					if ( tf.length > 0 ) AARP.page.pathc_effective.push( tf[0] );
				}
				AARP.page.path_effective = '/' + AARP.page.pathc_effective.join( '/' );
			}
			else
			{
				AARP.page.path_effective = '';
				AARP.page.pathc_effective = [];
			}
		}
		else
		{
			AARP.page.path_effective = AARP.page.path;
			AARP.page.pathc_effective = AARP.page.pathc;
		}
	}
	
	/**
	* pageLpaded()
	* 
	* Should be called prior to BODY closing.
	*/
	, pageLoaded: function()
	{
		if ( document.location.toString().match( /debugAds/ ) )
			AARPAds.debug();
		
		if ( AARP.page.parameters['generalStatus'] )
			AARP.generalStatus( AARP.page.parameters['generalStatus'] );
	}
	
	// if generalStatus is in querystring, attempt to show the div that should be populated with the value
	, generalStatus: function( msg )
	{
		try
		{
			$( 'generalStatus' ).innerHTML = msg;
			Effect.Appear( 'generalStatus' );
			setTimeout( "Effect.Squish( 'generalStatus' );", 4000 );
		}
		catch ( e ) { }
	}
	
	// the legendary encryption/decryption library, defined below
	, daw: null
	
	/*
	Objects/Functions definition deferred for other scripts.
	*/
	, Login: null // header.js
	, Comment: null // community/comments.js
	, Flag: null // community/content.js
	, Favorite: null // community/content.js
	, Email: null // community/content.js
	, Form: null // global.forms.js
	, Validator: null // global.forms.js
	, Persistence: null
	, Personalization: null
}


/*
% Kaiser Shahid, 2007-09-17
Set of functions to easily handle cookie retrieval/manipulation. Code
adapted from http://www.quirksmode.org/js/cookies.html
*/

var Cookies = {
	__version__: ''
	, cookies: {}
	, domain: 'aarp.org'
	, path: '/'
	, load: function()
	{
		var ca = document.cookie.split( ';' );
		for ( var i = 0; i < ca.length; i++ )
		{
			var c = ca[i].ltrim();
			var kv = c.split( '=', 2 );
			// unescape value if hexcodes are in
			if ( kv[1] && kv[1].match( /\%[0-9a-zA-Z]+/ ) )
				kv[1] = unescape( kv[1] );
			this.cookies[kv[0]] = kv[1];
		}
	}
	
	, get: function( key )
	{
		if ( this.cookies[key] )
			return this.cookies[key];
		else
			return null;
	}
	
	/*
	Parameters: key, val, expiry, domain, path.
	Expiry should be in seconds. Use helper methods to convert other times.
	*/
	
	, set: function( key, val )
	{
		var buffer = key + '=' + escape( val );
		var expiry = arguments[2];
		var domain = this.domain;
		var path = this.path;
		
		if ( expiry )
		{
			// CHANGED: if possible, figure out a way to account for DST, since 
			// getTime() seems to need a couple of hours padded on to actually persist.
			// --> getTime() returns milliseconds. duh.
			var date = new Date();
			date.setTime( date.getTime() + expiry*1000 );
			buffer += '; expires=' + date.toUTCString();
		}
		
		if ( arguments.length > 3 )
			domain = arguments[3];
		if ( arguments.length > 4 )
			path = arguments[4];
		
		buffer += '; path=' + path + '; domain=' + domain; // + '; domain=' + domain;
		document.cookie = buffer;
		this.cookies[key] = val;
		//alert( buffer + "\n\n" + document.cookie );
	}
	
	/*
	Parameters: key, domain, path.
	*/
	
	, expire: function( key )
	{
		var domain = this.domain;
		var path = this.path;
		
		if ( arguments.length > 1 )
			domain = arguments[1];
		if ( arguments.length > 2 )
			path = arguments[2];
		
		this.set( key, 'x', -1, domain, path );
		delete this.cookies[key];
	}
	
	, debug: function()
	{
		var str = '';
		for ( var k in this.cookies )
			str += k + '=>' + this.cookies[k] + "\n";
		return str + "\n\n" + document.cookie;
	}
}

Cookies.load();


/*
% Kaiser Shahid, 2007-09-17
Set of functions to handle serving ads.

/community
	# $zonename = 'channel_community'
	# $iachn = 'community'
	showCommunityHomepage
		# $dindx = 'yes'
	/%object%
		# $taxa = 'subchannel_%object%'
		# $iasub = '%object%'
		# $dindx = 'yes'
	/%user%/%object% --> this is equivalent to /portfolio/%object%/index.jsp?membername=%user%&pageNum=1
	/portfolio/%object%/index.jsp?membername=%user%[&pageNum=%page%]
		# $taxa = 'subchannel_%object%'
		# $iasub = '%object%'
		# $dindx = 'yes'
		? $pgid = '%user%__%object%__page_%page%'
	/%user%/%object%/%label%/%id%
		# $taxa = 'subchannel_%object%'
		# $iasub = '%object%'
		? $pgid = '%user%__%object%__id_%id%'
	/profile
		# skip!
	/community/%user%
		# skip!
/%channel%/index.html
	# $zonename = 'channel_%channel%'
	# $iachn = '%channel%'
	# $dindx = 'yes'
	/articles/index.html
		? $taxa = 'subchannel_articles'
		# $iasub = 'articles'
		# $dindx = 'yes'
		%id%.html
			# $zonename = '%converted:pgid[0]%'
			# $taxa = '%converted:pgid[1]%'
			# $pgid = '%pgid%'
	/%subchannel%/index.html
		# $taxa = 'subchannel_%subchannel%'
		# $iasub = '%subchannel%'
		# $dindx = 'yes'
		/articles/index.html
			? $taxb = 'articles'
			# $dindx = 'yes'
			%id%.html
				# $zonename = '%converted:pgid[0]%'
				# $taxa = '%converted:pgid[1]%'
				# $pgid = '%pgid%'
/states[/index.html]
	# $zonename = 'channel_states'
	# $iachn = 'states'
	# $dindx = 'yes'
	%state%.html
		# $taxa = 'subchannel__state_%state%' OR 'subchannel__%state%' (if state is full name)
		# $iasub = 'state_%state%' OR '%state%' (if %state% is full name)
		# $dindx = 'yes'
/members[/index.html]
	# $zonename = 'channel_members'
	# $iachn = 'members'
	# $dindx = 'yes'
*/

var AARPAds = {
	__version__: ''
	, sitename: 'aarporgv2.dart'
	, sitename_map: { 'bulletin':'bulletin.dart','products':'aarppnsv2.dart' }
	, zonename: ''
	, kw: ''
	, house: ''
	, taxa: ''
	, taxb: ''
	, iachn: ''
	, iasub: ''
	, dindx: ''
	, jsrpt: ''
	, sorce: ''
	, pgid: ''
	, ord: 0
	, tile: 0
	, pgtyp: ''
	, tpl: null
	
	, tpl_str: '<' + "script type=\"text/javascript\" src=\"http://ad.doubleclick.net/N1175/adj/#{sitename}/#{zonename};abr=!webtv;kw=#{kw};sz=#{width}x#{height};tile=#{tile};jsrpt=yes;grab=all;house=#{house};taxa=#{taxa};taxb=#{taxb};iachn=#{iachn};iasub=#{iasub};dindx=#{dindx};sorce=#{sorce};pgid=#{pgid};ord=#{ord}?\">"
		+ '<' + "/script><!-- ad_doc_write -->"
		+ '<' + "script type='text/javascript'>"
		+ "if ((!document.images && navigator.userAgent.indexOf(\"Mozilla/2.\") >= 0) || (navigator.userAgent.indexOf(\"WebTV\") >= 0)) {"
		+ "document.write('<a href=\"http://ad.doubleclick.net/N1175/jump/#{sitename}/#{zonename};kw=#{kw};sz=#{width}x#{height};tile=#{tile};jsrpt=no;grab=all;house=#{house};taxa=#{taxa};taxb=#{taxb};iachn=#{iachn};iasub=#{iasub};dindx=#{dindx};sorce=#{sorce};pgid=#{pgid};ord=#{ord}?\">');"
		+ "document.write('<img src=\"http://ad.doubleclick.net/N1175/ad/#{sitename}/#{zonename};kw=#{kw};sz=#{width}x#{height};tile=#{tile};jsrpt=no;grab=all;house=#{house};taxa=#{taxa};taxb=#{taxb};iachn=#{iachn};iasub=#{iasub};dindx=#{dindx};sorce=#{sorce};pgid=#{pgid};ord=#{ord}?\" width=\"#{width}\" height=\"#{height}\" border=\"0\"></a>');"
		+ "}"
		+ '<' + "/script>"
	, width: 0
	, height: 0
	, buffer: ''
	
	// TODO: figure out definitions how to get definitions for these
	, dem1: ''
	, dem2: ''
	, dem3: ''
	, debugInline: false
	, _pri: ''
	, _sec: ''
	, _ter: ''
	, _qua: ''
	
	/*
	AARPAds will set the taxonomy, page id, etc., based on any set vars and also where
	the user currently is (since /community will need to auto-generate all AARPAds).
	
	AARPAds SHOULD ONLY BE CALLED BEFORE <head> CLOSES! (AARPAds will allow the CMS to set
	some parameters manually through the custom head file).
	*/
	
	, init: function()
	{
		AARPAds.ord = Math.floor( Math.random() * 1298948098294839 );
		AARPAds.tpl = new Template( AARPAds.tpl_str );
		
		//if ( AARPAds.sitename_map[AARP.page.host] )
		//	AARPAds.sitename = AARPAds.sitename_map[AARP.page.host];
		if( AARPAds.sitename_map[AARP.page.site] )
			AARPAds.sitename = AARPAds.sitename_map[AARP.page.site];
		
		var tmp = null;
		// woo! with setPage(), don't need to worry about AARPAds nonsense that used to be here.
		//var comp = document.location.toString().split( '/' );
		//var comp = "http://beta.aarp.org/health/index.html".split( '/' );
		
		var protocol = AARP.page.protocol;
		var domain = AARP.page.host;
		var page = AARP.page.file;
		var querystring = AARP.page.querystring;
		var comp = AARP.page.path.split( '/' );
		comp.shift();
		if ( comp.length == 0 ) comp.push( '' ); // to make sure code doesn't throw errors, just put in a dummy value
		
		// /pri/articles/article.html -> 3
		// /pri/sec/articles/articles.html -> 4
		
		//Modified by Yonas Hassen on 02 July 2008:
		//Added third and fourth level subdirectories.
		//These will fill the values for 'taxa' and 'taxb' respectively, 
		//only if 'iachn' and 'iasub' are not null.
		var _pri = comp[0];
		var _sec = comp[1];
		var _ter = comp[2];
		var _qua = comp[3];
		AARPAds._pri = _pri;
		AARPAds._sec = _sec;
		AARPAds._ter = _ter;
		AARPAds._qua = _qua;
		
		/* dbg( "Ad Init:\n"
			+ 'url: ' + AARP.page.url + "\n"
			+ "querystring: " + querystring + "\n"
			+ 'domain: ' + domain + "\n"
			+ 'page: ' + page + "\n"
			+ 'pathc: ' + comp + "\n"
			+ 'primary: ' + _pri + "\n"
			+ 'secondary: ' + _sec + "\n"
		); */
		
		//TODO: check for subdomain properties (bulletin, magazine, etc.)--
		//taxonomy/zonename/etc. conventions should be the same throughout
		//(at least for the time being), so only sitename ever needs to change.
		
		var isArticle = false;
		
		// CMS processing
		if ( _pri != 'community' )
		{
			// normalize pgid to set for zonename, taxa, and taxb
			// NEW (2008-02-05): add != 'null' test
			var pgid = null;
			if ( AARPAds.pgid != '' && AARPAds.pgid != 'null' )
			{
				if ( AARPAds.pgid.match( /\/content\/articlerepository/ ) )
				{
					isArticle = true;
					
					// remove '/content/articlerepository' from beginning, and article label from end
					pgid = AARPAds.pgid.split( '/' );
					if ( pgid[0] == '' ) pgid.shift();
					pgid.shift(); pgid.shift();
					pgid.pop();
					
					/*
					// NEW [2008-07-10 | kaiser]: special processing for articles only (used to
					// be anytime pgid was pre-set). the article template was changed way back per
					// scott's request to include dcsubject1 as a zonename, but apparently he now 
					// wants the repository path to be the zonename and dcsubject1 to be taxa/taxb.
					// this code change is specific to how the data is outputted on the proxy, so
					// any changes to the ad code in the proxy (regarding zonename) will affect this.
					
					var taxonomy = AARPAds.zonename.split( /__/ );
					var l1 = pgid[0];
					var l2 = 'null';
					if ( pgid[1] ) l2 = pgid[1];
					
					AARPAds.zonename = l1 + '__' + l2;
					AARPAds.taxa = taxonomy[0];
					AARPAds.taxb = taxonomy[1];
					if ( !AARPAds.taxa || AARPAds.taxa == '' ) AARPAds.taxa = 'null';
					if ( !AARPAds.taxb || AARPAds.taxb == '' ) AARPAds.taxb = 'null';
					*/
					
					// NEW [2007-12-14 | kaiser]: don't override taxa, taxb, and zonename if they're set
					//if ( AARPAds.taxa == '' || AARPAds.taxa == 'null' ) AARPAds.taxa = pgid[0];
					//if ( (AARPAds.taxb == '' || AARPAds.taxb == 'null') && pgid.length > 1 ) AARPAds.taxb = pgid[1];
					if ( AARPAds.zonename == '' )
					{
						AARPAds.zonename = pgid[0];
						for ( var i = 1; i < pgid.length; i++ )
							AARPAds.zonename += '_' + pgid[i];
					}
				}
			}
			else
			{
				// NEW [2008-07-09]: assign a page id
				AARPAds.pgid = '/' + AARP.page.path;
				AARPAds.taxa = _ter;
				AARPAds.taxb = _qua;
			}
			
			// for now, AARPAds only includes states pages. but it could grow.
			var notPrimaryChannels = /^states$/;
			if ( !comp[0].match( notPrimaryChannels ) )
			{
				// no matter what, index.html in the CMS will be an index/landing page of some sort.
				// however, if dindx is manually set at startup, its current value will be respected.
				// TODO: match for /^index/ instead?
				
				if ( page != 'index.html' && AARPAds.dindx == '' )
					AARPAds.dindx = 'no';
				else if ( page == 'index.html' )
					AARPAds.dindx = 'yes';
			
				if ( comp[1] == 'articles' )
					_sec = 'articles';
				else if ( comp[2] == 'articles' )
				{
					_sec = comp[1];
					_ter = 'articles';
				}
			}
			else
			{
				// main state landing & individual state pages
				if ( _pri == 'states' && comp.length <= 2 )
					AARPAds.dindx = 'yes';
			}
			
			AARPAds.iachn = _pri;
			AARPAds.iasub = _sec;
		}
		else
		{
			var comObjMatch = /^(people|photos|video|journals|groups|tags)$/;
			if ( page.match( /^showCommunityHome/ ) )
				AARPAds.dindx = 'yes';
			else
			{
				// /community/%object%
				var m = null;
				if ( comp[1] ) m = comp[1].match( comObjMatch );
				
				if ( AARP.page.file == 'search.bt' )
				{
					AARPAds.zonename = 'search_results';
					AARPAds.dindx = 'yes';
				}
				else if ( m )
				{
					_sec = comp[1];
					AARPAds.dindx = 'yes';
				}
				// user's profile index
				else if ( comp.length == 2 )
				{
					AARPAds.dindx = 'yes';
				}
				// /community/portfolio/%object%/index.jsp?membername=%user%&pageNum=%page%
				else if ( comp[1] == 'portfolio' )
				{
					_sec = comp[2];
					AARPAds.dindx = 'yes';
					m = querystring.match( /membername=([\w_]+)/ );
					if ( m[1] )
					{
						AARPAds.pgid = m[1] + '__' + _sec;
						m = querystring.match( /pageNum=([\d]+)/ );
						if ( m[1] )
							AARPAds.pgid += '__page_' + m[1];
						else
							AARPAds.pgid += '__page_1';
					}
				}
				// /community/%user%/%object%[/%label%/%id%]
				else if ( comp[1] != 'misc' && comp[1] != 'profile' )
				{
					// TODO: should i set page [id] to be %user%__%object%__%id%?
					_sec = comp[2];
					AARPAds.pgid = comp[1] + '__' + _sec;
					
					// if the url decomp is 
					if ( comp.length == 5 )
					 	AARPAds.pgid += '__id_' + comp[4]; // + '__' + comp[3]
					else if ( comp.length == 3 )
					{
						AARPAds.pgid += '__page_1';
						AARPAds.dindx = 'yes';
					}
					
					page = AARPAds.pgid;
				}
				else
				{
					// TODO: what would go here?
				}
			}
		}
		
		// NEW [2008-07-10 | kaiser]: moved stuff under this branch since it interferes with article behavior.
		if ( !isArticle )
		{
			if ( AARPAds.zonename == '' )
			{
				// NEW [2008-07-09 | kaiser]: if in a subchannel, make sure to set the zone to subchannel. may need to revisit
				// code regarding 2008-02-16 later (once scott gives test cases)
				if ( _sec && _sec != '' && _sec != 'null' )
					AARPAds.zonename = 'subchannel_' + _sec;
				else
					AARPAds.zonename = 'channel__' + _pri;
			}
			
			if ( AARPAds.taxa == 'topic' ) AARPAds.taxa = 'null';
			if ( AARPAds.taxb == 'subtopic' ) AARPAds.taxb = 'null';
			
			if ( AARPAds.taxb == '' ) AARPAds.taxb = _ter;		
			AARPAds.iachn = _pri;
			AARPAds.iasub = _sec;
			
			//Added by Yonas Hassen on 02 July 2008
			if (AARPAds.iachn != '' && AARPAds.iasub != '')
			{
				if ( AARPAds.taxa == '' || AARPAds.taxa == 'null' ) AARPAds.taxa = _ter;
				if ( AARPAds.taxb == '' || AARPAds.taxb == 'null' ) AARPAds.taxb = _qua;
			}
		}
		
		var kw = Cookies.get( 'search-kw' );
		var queryPatterns = /(query|tags|groupQuery|keywords|terms)=([^&]+)/;
		
		// look for & set query for duration of session
		var m = document.location.toString().match( queryPatterns );
		if ( m )
		{
			AARPAds.kw = AARPAds.kw_normalize( m[2] );
			Cookies.set( 'search-kw', AARPAds.kw );
		}
		else if ( kw )
			AARPAds.kw = kw;
		
		// NEW (2008-01-22): per Scott's fixes
		// set 'null' if these are empty still
		// # Modified by Yonas Hassen (30 June 2008)
		var tmp = ['kw', 'taxa', 'taxb', 'iachn', 'iasub', 'sorce', 'pgid'];
		for ( var y in tmp )
		{
			y = tmp[y];
			if ( AARPAds[y] == '' || AARPAds[y] == undefined ) AARPAds[y] = 'null';
		}
		
		// NEW [2008-07-31 | kaiser]: post-fixing things
		AARPAds['sorce'] = AARPAds.normalize( AARPAds['sorce'].toLowerCase() );
		
		// for easier debugging: just show output inline with the ad so that
		// viewing community code is easier
		if ( AARP.page.parameters['debugAds'] )
			AARPAds.debugInline = true;
		
		// there's a 49 character limit on zonenames
		try
		{
			if ( AARPAds.zonename.length > 49 )
				AARPAds.zonename = AARPAds.zonename.substring( 0, 49 );
		}
		catch ( e ) { }
	}
	
	// output ad code
	// optional 3rd parameter, if given, should be an id string of an object whose innerHTML will be set 
	//    to the ad code.
	//    NEW [2009-02-20 | kaiser]: typecheck on 3rd parameter. if object, will do innerHTML, otherwise, will return the ad string
	
	, serve: function( width, height )
	{
		AARPAds.fix_before_serve();
		AARPAds.width = width;
		AARPAds.height = height;
		
		var obj = null;
		var ret_str = false;
		if ( arguments.length > 2 )
		{
			if ( typeof( arguments[2] ) == 'object' )
			{
				obj = arguments[2];
				obj = $( obj );
			}
			else
			{
				ret_str = true;
			}
		}
		
		// we're sending 'AARPAds' as the dictionary because, well, AARPAds is a 
		// dictionary. with super powers.
		
		AARPAds.tile++;
		var buffer = AARPAds.tpl.evaluate( AARPAds );
		
		if ( obj == null )
		{
			if ( !ret_str )
			{
				if ( AARPAds.debugInline )
					buffer += "<textarea rows='10' cols='25'>Tile #" + AARPAds.tile + "\n" + buffer.replace( "<" + "&gt;" ).replace( ">", "&lt;" ) + "</textarea>\n\n";
				document.write( buffer );
			}
		}
		else
			obj.innerHTML = buffer;
		
		if ( !AARPAds.debugInline )
			AARPAds.buffer += "Tile #" + AARPAds.tile + "\n" + buffer + "\n\n";
		
		if ( ret_str ) return buffer;
	}
	
	// NEW [2008-02-16 | kaiser]: catch any runtime errors post-initialize
	, fix_before_serve: function()
	{
		if ( AARP.page.file == 'search.bt' )
		{
			AARPAds.zonename = 'search_results';
		}
		// TODO: individual checks on overwriting taxa/taxb?
		else if ( AARPAds.taxa == 'topic' || AARPAds.taxa == '' ) //  || AARPAds.taxb == 'subtopic' || AARPAds.taxb == ''
		{
			AARPAds.zonename = 'channel_community';
			AARPAds.taxa = 'null';
			AARPAds.taxb = 'null';
		}
	}
	
	, debug: function()
	{
		document.write( "<textarea rows='20' cols='60'>" + AARPAds.buffer + "</textarea>" );
	}
	
	// convert 'fancy' characters into alphanumeric and underscore
	, normalize: function( str )
	{
		/*
		str = str.replace( /[^\w\s-]/g, '' );
		str = str.replace( /-/g, ' ' );
		*/
		
		// Round 1: remove non-word characters from beginning & end of string
		// Round 2: all non-word, non-dash characters get converted to _
		// Round 3: replace any remaining spaces with _
		str = str.trim().replace( /^[^\w]+/, '' ).replace( /[^\w]+$/, '' );
		str = str.replace( /[^\w-]+/g, '_' );
		str = str.replace( /\s+/g, '_' );
		
		if ( arguments.length > 1 )
			str = str.toLowerCase();
		
		return str;
	}
	
	// simlar to normalize(), except convert all non-words to spaces, then convert 
	// groups of spaces to +
	, kw_normalize: function( str )
	{
		// trim & replace non-words at beginning and end with empty strings
		str = str.trim().replace( /^[^\w]+/, '' ).replace( /[^\w]+$/, '' );
		// replace any run of non-words and dashes with a single space
		str = str.replace( /[^\w-]+/g, ' ' );
		// convert one or more spaces to a single plus
		str = str.replace( /\s+/g, '+' );
		
		return str.toLowerCase();
	}
}

// TODO: for search keywords, we need to make sure those are available via querystring, because we 
//       need to incorporate that into the ad code init before any ads are served.

/**
* Ported David's daw_encrypt.py to Javascript. Biggest missing pieces was ord() and chr(), which I implemented on String:
* the caveat is that they can only handle asci characters 33-127. Which is fine, since these functions would be
* used for non-special character encodings (i.e. email, urls, timestamps, plaintext).
* 
* @author Kaiser Shahid, 2007-10-09
*/

// TODO: obfuscate this! (or at least the key.)
AARP.daw = {
	aKey: [ 26, 238, 80, 83, 225, 13, 123, 145, 78, 248, 63, 65, 54, 208, 199, 45, 152, 229, 168, 109, 82, 189, 183, 208, 132, 192, 141, 139, 42, 239, 20, 166, 66, 54, 43, 40, 62, 114, 14, 34, 39, 30, 66, 220, 237, 82, 218, 82, 194, 66, 245, 200, 102, 240, 232, 97, 165, 42, 93, 236, 19, 109, 160, 14, 163, 15, 127, 222, 219, 18, 213, 90, 220, 234, 59, 125, 243, 14, 237, 104, 85, 200, 140, 200, 49, 52, 124, 83, 36, 241, 162, 237, 18, 222, 150, 73, 84, 130, 114, 92, 123, 3, 205, 176, 100, 232, 244, 244, 244, 47, 187, 128, 82, 177, 33, 135, 152, 249, 49, 157, 88, 70, 69, 45, 138, 94, 5, 116, 74, 231, 76, 243, 55, 39, 136, 158, 138, 214, 109, 173, 16, 170, 163, 182, 166, 111, 141, 168, 243, 150, 112, 64, 141, 130, 71, 199, 77, 187, 151, 174, 103, 216, 127, 153, 147, 43, 70, 164, 17, 192, 181, 141, 184, 68, 174, 50, 48, 187, 219, 90, 3, 19, 83, 61, 244, 93, 216, 118, 140, 157, 181, 34, 118, 57, 167, 180, 132, 127, 232, 77, 146, 248, 29, 9, 225, 121, 145, 23, 163, 162, 65, 79, 219, 67, 143, 160, 169, 202, 90, 105, 227, 107, 98, 243, 44, 44, 135, 67, 96, 99, 13, 40, 163, 34, 8, 21, 220, 153, 162, 154, 172, 111, 11, 193, 24, 199, 142, 133, 166, 17, 69, 97, 96, 86, 74, 106, 31, 39, 12, 190, 224, 212, 216, 201, 181, 22, 13, 56, 98, 185, 226, 248, 214, 180, 182, 124, 157, 14, 89, 7, 212, 173, 67, 161, 101, 85, 191, 183, 205, 222, 65, 56, 56, 163, 60, 219, 41, 6, 228, 123, 142, 182, 4, 123, 156, 87, 240, 196, 206, 59, 160, 70, 10, 122, 39, 0, 202, 42, 197, 45, 171, 96, 100, 57, 230, 96, 178, 9, 57, 97, 126, 114, 236, 56, 76, 100, 88, 118, 137, 116, 113, 74, 195, 115, 240, 137, 226, 198, 208, 93, 4, 19, 9, 232, 216, 216, 238, 100, 116, 244, 24, 231, 220, 57, 116, 162, 184, 13, 79, 131, 114, 225, 168, 246, 198, 194, 59, 62, 161, 222, 29, 65, 187, 190, 24, 24, 46, 191, 174, 208, 84, 105, 211, 160, 61, 108, 117, 53, 237, 200, 175, 52, 200, 246, 16, 207, 84, 118, 98, 60, 165, 171, 179, 233, 237, 151, 2, 184, 16, 19, 230, 150, 207, 31, 114, 208, 239, 60, 179, 225, 56, 8, 146, 130, 216, 35, 152, 34, 188, 205, 218, 116, 97, 29, 23, 66, 56, 4, 200, 244, 88, 124, 204, 101, 24, 218, 207, 20, 134, 87, 92, 120, 127, 42, 241, 183, 17, 79, 173, 248, 3, 28, 4, 35, 107, 160, 25, 230, 214, 106, 107, 59, 15, 61, 242, 180, 237, 122, 187, 61, 165, 245, 248, 126, 101, 164, 184, 99, 3, 2, 26, 68, 190, 173, 19, 191, 132, 64, 4, 83, 192, 75, 184, 51, 90, 16, 95, 203, 213, 203, 231, 115, 38, 225, 139, 76, 41, 245, 177, 88, 108, 55, 12, 156, 72, 230, 53, 29, 150, 122, 129, 183, 136, 35, 121, 215, 141, 62, 112, 181, 233, 182, 242, 38, 1, 98, 111, 247, 176, 164, 147, 178, 58, 128, 32, 121, 138, 48, 120, 65, 176, 97, 169, 29, 106, 117, 85, 115, 40, 151, 245, 68, 242, 37, 98, 5, 89, 71, 110, 114, 147, 55, 249, 219, 117, 239, 89, 16, 39, 234, 213, 134, 17, 136, 247, 68, 77, 213, 217, 136, 194, 119, 49, 17, 98, 4, 156, 13, 127, 231, 183, 95, 11, 63, 114, 130, 88, 41, 38, 89, 91, 152, 52, 143, 15, 19, 88, 191, 186, 219, 138, 233, 52, 186, 179, 123, 76, 76, 246, 127, 230, 49, 231, 54, 238, 90, 99, 152, 64, 70, 85, 36, 25, 174, 80, 68, 56, 159, 15, 235, 236, 41, 193, 180, 101, 203, 142, 179, 111, 4, 178, 234, 49, 130, 4, 50, 213, 46, 38, 95, 176, 244, 37, 245, 234, 182, 221, 206, 61, 100, 206, 232, 194, 93, 204, 73, 116, 156, 45, 172, 55, 47, 236, 40, 26, 210, 105, 88, 233, 96, 242, 89, 94, 114, 54, 52, 26, 62, 123, 173, 241, 20, 190, 159, 190, 46, 220, 78, 162, 161, 100, 34, 173, 223, 184, 74, 144, 159, 238, 119, 12, 168, 248, 87, 29, 114, 147, 236, 124, 212, 160, 157, 97, 231, 96, 189, 17, 79, 16, 182, 94, 219, 118, 144, 145, 56, 8, 183, 171, 228, 209, 37, 175, 193, 70, 108, 228, 61, 177, 23, 165, 33, 185, 166, 169, 176, 155, 190, 136, 128, 96, 190, 55, 214, 11, 73, 63, 78, 175, 33, 167, 52, 175, 184, 14, 112, 198, 244, 230, 153, 110, 83, 197, 188, 25, 27, 36, 182, 201, 225, 168, 138, 186, 230, 226, 160, 46, 90, 186, 80, 125, 114, 230, 150, 144, 94, 233, 123, 99, 158, 111, 224, 9, 33, 187, 97, 236, 139, 65, 207, 169, 53, 150, 62, 242, 248, 80, 207, 87, 160, 184, 111, 26, 234, 248, 173, 229, 0, 200, 184, 216, 82, 236, 239, 43, 184, 12, 185, 98, 221, 162, 95, 95, 128, 33, 111, 197, 12, 125, 136, 103, 190, 143, 225, 23, 21, 146, 153, 139, 78, 199, 9, 220, 68, 12, 46, 230, 42, 215, 138, 120, 61, 25, 69, 115, 99, 182, 1, 208, 110, 163, 112, 163, 36, 63, 237, 238, 175, 141, 8, 189, 200, 177, 68, 6, 239, 131, 125, 190, 60, 2, 149, 36, 18, 137, 238, 221, 60, 125, 209, 160, 200, 31, 181, 188, 247, 107, 219, 17, 215, 236, 35, 45, 182, 244, 93, 198, 38, 76, 89, 145, 134, 244, 168, 57, 22, 23, 92, 2, 52, 56, 219, 165, 9, 107, 25, 200, 68, 103, 0, 185, 230, 226, 168, 221, 39, 175, 70, 146, 229, 120, 187, 169, 108, 226, 154, 120, 73, 246, 4, 151, 59, 81, 22 ]
	, encrypt: function( s, start, backwards )
	{
		L = [];
		if ( backwards )
			key = 1023 - start;
		else
			key = start;
		
		for ( var i = 0; i < s.length; i++ )
		{
			next = String.ord( s.charAt( i ) ) ^ AARP.daw.aKey[key];
			L.push( AARP.daw._hex( next ) ); // strip of the 0x added by hex
			if ( backwards )
			{
				key -= 1;
				if ( key < 0 )
					key = 1023;
			}
			else
			{
				key += 1;
				if ( key > 1023 )
					key = 0;
			}
		}
		
		L.push( AARP.daw._hex( start ) );
		return L.join( "" );
	}
	, decrypt: function( s )
	{
		start = parseInt( s.substring( s.length - 2 ), 16 ) // last two chars are encoded start value
		backwards = start % 2;
		s = s.substring( 0, s.length - 2 );
		L = [];
		
		if ( backwards )
			key = 1023 - start;
		else
			key = start;
		
		var max = Math.floor( s.length / 2 ) - 1;
		
		for ( var i = 0; i <= max; i++ )
		{
			var lo = i * 2;
			var hi = (i + 1) * 2;
			next = parseInt( s.substring( lo, hi ), 16 ) ^ AARP.daw.aKey[key];
			
			L.push( String.chr( next ) );
			
			if ( backwards )
			{
				key -= 1;
				if ( key < 0 )
					key = 1023;
			}
			else
			{
				key += 1;
				if ( key > 1023 )
					key = 0;
			}
		}
		
		return L.join( "" );	
	}
	, _hex: function( n )
	{
		s = n.toString( 16 );
		if ( s.length == 1 )
	        return "0" + s;
	    else
	        return s;
	}
	, crypt_text: function( plain )
	{
		var start = plain.length % 250;
		var backwards = start % 2;
		return AARP.daw.encrypt( plain, start, backwards );
	}
	, decrypt_text: function( enc )
	{
		return AARP.daw.decrypt( enc );
	}
	, create_timestamp: function()
	{
		var s = null;
		if ( arguments.length > 0 )
		{
			s = arguments[0];
		}
		else
		{
			s = new Date();
			s = s.getTime();
		}
		var start = s % 250;
		var backwards = start % 2;

		return AARP.daw.encrypt( s + "", start, backwards );
	}
	, show_timestamp: function( ts )
	{
		var s = parseInt( AARP.daw.decrypt( ts + "" ) );
		return new Date( s );
	}
}

// added by kaiser shahid [2007-11-05]
// this used to be here, i thought...

var defaultText = {
	__version__: ''
	, set: function( obj, txt )
	{
		if ( obj.value.trim() == '' )
			obj.value = txt;
	}
	, unset: function( obj, txt )
	{
		if ( obj.value.trim() == txt )
			obj.value = '';
	}
}

// added by kaiser shahid [2008-02-05]
AARP.hitTracker = {
	server: 'www.aarp.org'
	, name: ''
	, url: ''
	, repoUrl: ''
	, authorName: ''
	, category: ''
	, debugURL: ''
	, hit: function()
	{
		// do not track author instance hits
		if ( AARP.page.is_authoring ) return;
		
		// NEW [2008-03-24]: remove 'debug=y'
		AARP.hitTracker.url = AARP.hitTracker.url.replace( /debug=[^&]+/, '' );
		
		// remove empty querystring
		if ( AARP.hitTracker.url[AARP.hitTracker.url.length-1] == '?' )
			AARP.hitTracker.url = AARP.hitTracker.url.substring( 0, AARP.hitTracker.url.length-1 );
		
		// NEW [2008-03-05 | kaiser]: add site to top of category if not dotorg
		var category = AARP.hitTracker.category;
		if ( AARP.page.site != 'dotorg' ) category = '/' + AARP.page.site + category;
		
		url = 'http://' + AARP.hitTracker.server + '/community/hitTracker/track.action'
			+ '?name=' + escape( AARP.hitTracker.name ) + '&url=' + escape( AARP.hitTracker.url )
			+ '&repoUrl=' + escape( AARP.hitTracker.repoUrl ) + '&authorName=' + escape( AARP.hitTracker.authorName )
			+ '&category=' + escape( category )
		;
		
		var img = new Image();
		img.src = url;
		
		AARP.hitTracker.debugURL = url;
		if ( AARP.page.parameters['debug'] ) document.write( "this: " + AARP.hitTracker.url + "<br />target: " + url + "<br />path, effective: " + AARP.page.pathc_effective + "<br />path: " + AARP.page.pathc + "<br />category: " + category + "<br />site: " + AARP.page.site );
		//document.location = url;
	}
}

/**
* AARP.Persistence provides larger, more long-term storage solutions on the browser end,
* utilizing either Mozilla's globalStorage or IE's userData. If neither are available, returns
* false on any calls  made to its methods.
* 
* @author Kaiser Shahid, 2007-10-09
*/

// TODO: fill this out.

AARP.Persistence = {
	__version__: ''
	, persistable: false
	, type: ''
	, domain: 'aarp.org' // default domain to store data to. aarp.org will be available to all subdomains
	, init: function()
	{
		this.persistable = true;
		if ( globalStorage )
			this.type = 'mozilla'; 
		else if ( userData )
			this.type = 'ie';
		else
			this.persistable = false;
	}
}

function dbg( str ) { if ( document.location.toString().match( /debug/ ) ) { alert(str); } }

AARP.setPage();
AARP.setUser();

// CHANGED [2008-03-05 | kaiser]: only condition needed now is that staging & dev point to www-s
if ( AARP.page.host.match( /-[sd]\.aarp/ ) ) AARP.hitTracker.server = 'beta-s.aarp.org';

AARP.Personalization = {
	// User not logged in
	notLoginImage: ''
	, notLoginImageLink: ''
	// Not an active member
	, notMemberImage: ''
	, notMemberImageLink: ''
	// Active Member
	, activeMemberImage: ''
	, actibeMemberImageLink: ''
	//Expiring member
	, expiringMemberImage: ''
	, expiringMemberImageLink: ''
	//Expired member
	, expiredmemberimage: ''
	, expiredmemberimageLink: ''
	, checkStatus: function()
	{
		//var loginStatus 	= checkLoginStatus("header");
		var loginStatus = AARP.User.isLoggedIn;
						
		// Defining the variable
		var userName		="";
		var accountStatus	="";
		var expirationDate	="";
		
		if (loginStatus) // != null
		{
			userName = AARP.User.name;
			accountStatus = AARP.User.accountStatus;
			expirationDate = AARP.User.expirationDate;
			//if ( AARP.page.is_authoring ) { alert( "accountStatus=" + accountStatus ); }
			// checking for account status
			if (accountStatus == "0") 
			{
				if (expirationDate != undefined || expirationDate != '') 
				{
					// checking for non user member
					var toDay 	= new Date();
					
					// parsing the expire date
					var exactDate		=  expirationDate.split(' ')[0];
					var expireMonth		=  exactDate.split('/')[0];
					var expireDay		=  exactDate.split('/')[1];
					var expireYear		=  exactDate.split('/')[2];
					
					var expireDay		= new Date(expireYear,expireMonth-1,expireDay);
					
					var milli_toDay 	= toDay.getTime();
					var milli_expireDay 	= expireDay.getTime();
					var diff 		= milli_expireDay - milli_toDay;
					var noDay		= Math.round(diff/(1000*60*60*24));					
										
					if (noDay>180) 
					{
						// active member
						if (AARP.Personalization.activeMemberImage!="")
						{
							//checking the image reference is there or not
							if (AARP.Personalization.actibeMemberImageLink!="")
							{
								document.write("<a href='"+AARP.Personalization.actibeMemberImageLink+"'>"+AARP.Personalization.activeMemberImage+"</a>");
							}
							 else 
							{
								document.write("<a href='#' onclick='return false;'>"+AARP.Personalization.activeMemberImage+"</a>");
							}	
						}
					}
					else if (noDay<=180) 
					{
						//expering member
						if (AARP.Personalization.expiringMemberImage!="")
						{
							//checking the image reference is there or not
							if (AARP.Personalization.expiringMemberImageLink!="")
							{
								document.write("<a href='"+AARP.Personalization.expiringMemberImageLink+"'>"+AARP.Personalization.expiringMemberImage+"</a>");
							}
							 else 
							{
								document.write("<a href='#' onclick='return false;'>"+AARP.Personalization.expiringMemberImage+"</a>");
							}	
						}
					}
				}				
			}
			else if (accountStatus == "5") 
			{
				//expired member
				if (AARP.Personalization.expiredmemberimage!="")
				{
					//checking the image reference is there or not
					if (AARP.Personalization.expiredmemberimageLink!="")
					{
						document.write("<a href='"+AARP.Personalization.expiredmemberimageLink+"'>"+AARP.Personalization.expiredmemberimage+"</a>");
					}
					 else 
					{
						document.write("<a href='#' onclick='return false;'>"+AARP.Personalization.expiredmemberimage+"</a>");
					}	
				}
				
			}
			else
			{
				if (AARP.Personalization.notMemberImage!="")
				{
					//checking the image reference is there or not
					if (AARP.Personalization.notMemberImageLink!="")
					{
						document.write("<a href='"+AARP.Personalization.notMemberImageLink+"'>"+AARP.Personalization.notMemberImage+"</a>");
					}
					 else 
					{
						document.write("<a href='#' onclick='return false;'>"+AARP.Personalization.notMemberImage+"</a>");
					}	
				}						
			}
		}
		else
		{
			// should display the default Image
			if (AARP.Personalization.notLoginImage!="")
			{
				//checking the image reference is there or not
				if (AARP.Personalization.notLoginImageLink!="")
				{
					document.write("<a href='"+AARP.Personalization.notLoginImageLink+"'>"+AARP.Personalization.notLoginImage+"</a>");
				}
				 else 
				{
					document.write("<a href='#' onclick='return false;'>"+AARP.Personalization.notLoginImage+"</a>");
				}	
			}
		}
	}
}


/**
* compatibility with popup option in article authoring.
*/

function CFC_popup(/*String*/ url, /*String*/ name, /*String*/ features)
{
	var defaultWidth = 500;
	var defaultHeight = 400;
	if (url.indexOf("/content/") == 0) url = url.substr(8);
	var w = window.open(url, name, features);
	w.focus();
}









/*
The below is for email and favorite overlays
Copied by Jon Lechliter from article_v2.js (2008-12-16)
-------------------------------------------------------*/

AARP.Email = {
	__version__: ''
	, email_validation: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
	, mail_template: ''
	, generalStatus: ''
	, currentOverlay: ''
	, overlayToPrefix: {}
	, formToPrefix: {}
	, overlayCreated: false
	, nodeCache: {}

	, open: function( event )
	{
		hideCalcs();
		hideSelectBoxes() ;
		hideFlash() ;
		
		var overlay = 'emailOverlay';
		var form = 'emailContentForm';
		var prefix = 'email';
		
		if ( arguments.length > 1 && arguments[1] )
			overlay = arguments[1];
		if ( arguments.length > 2 && arguments[2] )
			form = arguments[2];
		if ( arguments.length > 3 && arguments[3] )
			prefix = arguments[3];
		
		AARP.Email.currentOverlay = overlay;
		AARP.Email.currentForm = form;
		
		AARP.Email.overlayToPrefix[overlay] = prefix;
		AARP.Email.formToPrefix[form] = prefix;
		
	var objBody = document.getElementsByTagName("body").item(0);
	
	var objOverlay = null;
	if ( !AARP.Email.overlayCreated )
	{
		objOverlay = document.createElement("div");
		objOverlay.setAttribute('id','overlay');
		objOverlay.style.display = 'none';
		objBody.appendChild(objOverlay);
		AARP.Email.overlayCreated = objOverlay;
	}
	else
	{
		objOverlay = AARP.Email.overlayCreated;
	}
	
	var overlayDel = null;
	if ( !AARP.Email.nodeCache[overlay] )
	{
		overlayDel = $("tools").removeChild($(overlay));
		objBody.appendChild(overlayDel);
		AARP.Email.nodeCache[overlay] = overlayDel;
	}
	else
	{
		overlayDel = AARP.Email.nodeCache[overlay];
	}
	
	var arrayPageSize = getPageSize();
	$('overlay').setStyle({position: 'absolute', top: '0', left: '0'});
	$('overlay').style.width = arrayPageSize[0] +"px";
	$('overlay').style.height = arrayPageSize[1] +"px";

	var overlayDuration = 0.2;	// shadow fade in/out duration
	var overlayOpacity = 0.6;	// controls transparency of shadow overlay
	new Effect.Appear('overlay', { duration: overlayDuration, from: 0.0, to: overlayOpacity });
	
	var arrayPageScroll = getPageScroll();
	var dialogBoxTop = arrayPageScroll[1] + (arrayPageSize[3] / 3);
	var dialogBoxWidth = 350;
	var dialogBoxLeft = ((arrayPageSize[0] - dialogBoxWidth) / 2) + arrayPageScroll[0];
	overlayDel.style.top = dialogBoxTop +"px"; 
	overlayDel.style.left = dialogBoxLeft +"px"; 
	overlayDel.setStyle({position: 'absolute', zIndex: 1000000});

	$(overlay).show();

	}
	, send: function()
	{
		var prefix = 'email';
		
		if ( arguments.length > 0 && arguments[0] )
		{
			AARP.Email.currentForm = arguments[0];
			prefix = AARP.Email.formToPrefix[arguments[0]];
		}
		
		// this first check indicates that this is on a non-community page (presumably an article).
		// fill in fields if true.
		
		var ctypename = $( prefix + '.contentTypeName' );
		if ( ctypename && ctypename.value == "article" )
		{
			var em = $( prefix + '.from' ).value;
			var emc = AARP.daw.crypt_text( em );
			var url = AARP.page.protocol + '://' + AARP.page.host + ':' + AARP.page.port + AARP.page.path + '/' + AARP.page.file;
			$( prefix + '.status' ).style.display = 'none';
			var req = $( prefix + '.required' );
			
			// repository id gives unique value
			//$( prefix + '.contentId' ).value = AARPAds.pgid;
			$( prefix + '.contentTitle' ).value = document.title;
			$( prefix + '.permalinkUrl' ).value = url;
			$( prefix + '.redirect' ).value = url + '?generalStatus=' + AARP.Email.generalStatus;
			
			// TODO: when form validation is built, use that instead of this
			var msgs = [];
			if ( !em.match( AARP.Email.email_validation ) )
				msgs.push( "Your E-mail address is invalid" );
			
			// split up recipients list and validate each email;
			// show the addresses that aren't valid.

			var tmpRE = /,\s*/;
			var tmp = $( prefix + '.to' ).value.trim().split( tmpRE );
			var recipients = [];
			var rinvalid = [];
			for ( var i = 0; i < tmp.length; i++ )
			{
				if ( tmp[i].match( AARP.Email.email_validation ) )
					recipients.push( AARP.daw.crypt_text( tmp[i].trim() ) );
				else
					rinvalid.push( tmp[i] );
			}
			if ( rinvalid.length > 0 )
				msgs.push( 'These recipients are invalid: ' + rinvalid.join( ", " ) );
			else
			{
				// limit # of recipients after processing copyme
				if ( $( prefix + '.copyme' ).checked ) recipients.push( emc );
				if ( recipients.length > 5 )
					msgs.push( "You can send emails up to 5 people at a time (including yourself). You currently have " + recipients.length ) + " people on your list";
			}
			
			if ( req && req.value.match( /emailContentMessage/ ) )
			{
				var _m = $( prefix + '.message' );
				if ( _m.value.trim() == '' )
					msgs.push( "Message must not be empty." );
			}
			
			if ( msgs.length > 0 )
			{
				$( prefix + '.status' ).innerHTML = "The following errors occurred:<br />&ndash; " + msgs.join( '<br />&ndash; ' );
				$( prefix + '.status' ).style.display = 'block';
			}
			else
			{
				var realname = $( prefix + '.fromName' ).value.trim();
				if ( realname == '' ) realname = em;
				
				//$( prefix + '.email' ).disabled = true;
				$( prefix + '.email' ).value = em;
				$( prefix + '.realname' ).value = $( prefix + '.fromName' ).value = realname;
				$( prefix + '.recipients' ).value = recipients.join( ',' );
				$( prefix + '.mail_template' ).value = AARP.Email.mail_template;
				$( prefix + '.subject' ).value = 'AARP.org Article from ' + em;
				$( AARP.Email.currentForm ).submit();
			}
		}
	}

	, close: function()
	{
		if ( arguments.length > 0 )
			AARP.Email.currentOverlay = arguments[0];
		
		// hide error messages
		var prefix = AARP.Email.overlayToPrefix[AARP.Email.currentOverlay];
		$( prefix + '.status' ).style.display = 'none';
		
	$(AARP.Email.currentOverlay).hide();
	var overlayDuration = 0.2;	// shadow fade in/out duration
	new Effect.Fade('overlay', { duration: overlayDuration});
	showCalcs();
	showSelectBoxes() ;
	showFlash() ;
	}
}

AARP.Email.mail_template = AARP.daw.crypt_text( 'http://assets.aarp.org/aarp.org_/misc/formmail_email-tpl_article.html' );
AARP.Email.generalStatus = escape( 'Thanks! Your email has been sent.' );

AARP.Favorite = {
	__version__: ''

	, errorHandler: function(transport)
	{
		if (AARP.page.querystring["debug"])
		{
				alert(transport.responseText);
		}
	}
	
	// need two parameters: stringURL and articleTitle
	, Article: {
		submitURL: '/community/articleFavorite/submit.bt'
		, checkURL: '/community/articleFavorite/validate.bt'
		, open: function()
		{
			$( 'favorite.title' ).innerHTML = document.title;
			overlayConfirmation('favoriteContentOverlay');
		}
		, save: function()
		{
			if ( !AARP.User.isLoggedIn )
			{
				// TODO: make a nicer way of showing error/status message
				alert( "You must be logged in." );
				return;
			}
			
			// TODO: does one save the proxy path or the repository path?
			// TODO: is it right to be using document.title going forward?
			var params = 'articleURL=http://' + AARP.page.host + AARP.page.path + '/' + AARP.page.file
				+ '&articleTitle=' + escape( document.title )
				;
			
			new Ajax.Request(
				AARP.Favorite.Article.submitURL
				, { method: 'get', parameters: params, onSuccess: AARP.Favorite.Article.save__onSuccess, onError: AARP.Favorite.errorHandler }
			);
		}
		, save__onSuccess: function( response )
		{
			// TODO: check response for status code
			//alert(response.responseText.trim());
			AARP.generalStatus( 'This has been saved to your Bookmarks on your Profile Page.' );
			closeOverlayConfirmation();
		}
		, unsave: function()
		{
			
		}
		/*
		check that the current article is already saved? use Cookies to
		cache this info (maybe do it per session).
		*/
		// TODO: parameter check to see if an external method is explicitly forcing an action
		, check: function()
		{
			var page = AARP.page.path + '/' + AARP.page.file;
			var params = 'articleID=' + page + '&memberID=' + AARP.User.name;
			
			new Ajax.Request(
				AARP.Favorite.Article.checkURL
				, { method: 'post', data: params, onSuccess: AARP.Favorite.Article.check__onSuccess }
			);
			
			/* var article = Cookies.get( 'favorite.article.' + page;
			
			// not saved for this session
			if ( article == null )
			{
				
			} */
			
		}
		, check__onSuccess: function( response )
		{
			var val = response.responseText.trim().toLowerCase();
			if ( val == "true" )
			{
				// TODO: disable bookmark link and indicate that this is already saved
			}
		}
	}
}


/*
Dynamic character counter for <textarea> and <input> tags
Copied by Jon Lechliter from bulletin/js/global.js (2008-7-30)
-------------------------------------------------------*/

function getObject(obj) {
	var theObj;
	if(document.all) 
	{
    	if(typeof obj=="string") 
		{
      		return document.all(obj);
    	} 
		else 
		{
      		return obj.style;
    	}
  	}
  
	if(document.getElementById) 
	{
    	if(typeof obj=="string") 
		{
      		return document.getElementById(obj);
    	} 
		else 
		{
      		return obj.style;
    	}
  	}
	return null;
}

function toCount(entrance,exit,text,characters) {
	var entranceObj=getObject(entrance);
	var exitObj=getObject(exit);
	var length=characters - entranceObj.value.length;
  	
	if(length <= 0) 
	{
    	length=0;
   	 	text='<span class="disable">You have reached your character limit.</span>';
    	entranceObj.value=entranceObj.value.substr(0,characters);
  	}
  	
	exitObj.innerHTML = text.replace("{CHAR}",length);
}

/* end: Dynamic character counter */


/* Old Functions for Social Bookmarking tool */
function toggleShare() {
	$('shareBG').style.visibility = "visible";
	$('socialBookmarks').style.display= "block";
}

function toggleShareOff() {
	$('shareBG').style.visibility = "hidden";
	$('socialBookmarks').style.display= "none";
}

function toggleShare2() {
	$('socialBookmarks2').style.display = "block";
	$('socialBookmarks2').style.visibility = "visible";
	$('shareBG2').style.visibility = "visible";
}

function toggleShareOff2() {
	$('socialBookmarks2').style.display = "none";
	$('socialBookmarks2').style.visibility = "hidden";
	$('shareBG2').style.visibility = "hidden";
}


/* Functions for Social Bookmarking tool */
AARP.Share = {
	__version__: ''
	, errorHandler: function(transport)
	{
		if (AARP.page.querystring["debug"])
		{
				alert(transport.responseText);
		}
	}
	,	open: function()
		{
			overlayConfirmation('shareContentOverlay');
			yahooBuzzArticleHeadline = document.title;
			yahooBuzzArticleSummary = getMetaValue('description');
			yahooBuzzArticleId = window.location.href;
	}
}

function openShareWindow(url) {
	var flowURL = null;
	if(url=="DIGG") {
		flowURL = "http://digg.com/remote-submit?url=" + window.location.href + "&title=" + document.title + "&bodytext=" + getMetaValue('description');
	} else if(url =="DELICIOUS") {
		flowURL = "http://del.icio.us/post?url=" + window.location.href + "&title=" + document.title;
	} else if(url =="LINKEDIN") {
		flowURL = "http://www.linkedin.com/shareArticle?mini=true&url=" + window.location.href + "&title=" + document.title + "&summary=" + getMetaValue('description');
	} else if(url == "FACEBOOK") {
		flowURL = "http://www.facebook.com/sharer.php?u=" + window.location.href + "&t=" + document.title;
	}
	var shareWindowRef = window.open(''+flowURL,"SHARE",'left=20,top=20,width=650,height=450,toolbar=0,resizable=0,scrollbars=1');
}

function getMetaValue(metaName) {
	var metaTags=document.getElementsByTagName("META");
	for (var i=0; i<metaTags.length; i++) {
		if (metaTags[i].name.toLowerCase() == metaName.toLowerCase()) {
			return metaTags[i].content;
		}
	}
	return "NA";
}
/* end: Functions for Social Bookmarking tool */


/*
	Function for disabling ads
-----------------------------------*/

function removeAds() {
	var adArr = $$('div.ad');
	
	for (var i = 0; i<adArr.length; i++) {
		adArr[i].style.display = "none";	
	}
}

/* end: Function for disabling ads */


/**
* Helper functions to fix dynamic right column for (what else) IE.
* @author Kaiser Shahid (2009-02-20; 2009-02-23)
*/

AARP.externalRight = {
	found_ads: 0
	, dbg: null
	
	/**
	* This function will turn the calls to AARPAds.serve() into actual HTML, in order to reduce
	* the number of document.write() calls and also do a little modifying of html (mainly
	* wrapping the ad code with a div and giving it a unique id).
	*/
	, adFix: function( str )
	{
		// NEW [2009-05-11 | kaiser]: it looks like the end head and opening body tag are included as part of output, so strip
		// those off. split on that.
		
		var head_body_remover = new RegExp( /<\/head><body[^>]+>/ );
		var div_container_remover = new RegExp( "<div id='AARPRightColumn'>" );
		var script_matcher_init = new RegExp(
			'<' + 'script[^>]*>\\s*AARPAds\.init[^;]+;\\s*</' + 'script>'
		);
		var script_matcher_serve = new RegExp(
			'<' + 'script[^>]*>\\s*AARPAds\\.serve([^;]+);\\s*</' + 'script>', 'g'
		);
		
		// replace the start & end of the big container and then the script init call
		
		// [NEW [2009-06-02 | kaiser]: the tag balancing with the replacement of
		// AARPRightColumn seemed to be broken, so now just replace the opening tag
		// and id with a plain <div>. this code was removed: "replace( /\s*<\/div>\s*$/, '' )"
		
		str = str.replace( head_body_remover, '' );
		str = str.replace( div_container_remover, '<div>' ).replace( script_matcher_init, '' );
		str += "<div id='aarp.ad.___separator___' style='display: none;'> </div>";
		AARPAds.init();
		
		var t = null;
		if ( document.location.href.match( /debug/ ) )
		{
			t = document.createElement( 'textarea' );
			t.id = 'dbgggr';
			t.value = str;
			t.style.width = '100%';
			t.style.height = '100px';
			document.getElementsByTagName( 'body' )[0].appendChild( t );
			AARP.externalRight.dbg = t;
		}
		
		var serves = str.match( script_matcher_serve );
		for ( var i = 0; i < serves.length; i++ )
		{
			// break up '...serve( x, y )...' into '..serve( ' and 'x,y )...'
			var tmp = serves[i].split( /serve\(\s*/ );
			// break up 'x, y )...' into 'x, y' and ' )...'
			tmp = tmp[1].split( /\s*\)/ );
			
			// parse out the dimensions and retrieve the corresponding ad code.
			// also, wrap the ad code with a unique container and id
			var dim = tmp[0].split( /,\s*/ );
			var w = parseInt( dim[0] ), h = parseInt( dim[1] );
			var ad_buff = "<div id='aarp.ad." + i + "'>" + AARPAds.serve( w, h, true ) + "</div>";
			AARP.externalRight.found_ads++;
			
			// replace the script call with the actual ad output
			str = str.replace( serves[i], ad_buff );
		}
		
		if ( AARP.externalRight.dbg != null ) AARP.externalRight.dbg.value = str;
		
		return str;
	}
	
	/**
	* Once the page finishes loading, re-examine the right column and move each of the ads inserted at the bottom to
	* the appropriate slots above. The typical way to check if the current node is an ad element is if:
	* 1) the separator has been found
	* 2) the current element is not: SCRIPT, NOSCRIPT, non-HTML element (whitespace, html comments)
	*/
	
	, postFix: function()
	{
		//if ( !navigator.userAgent.toString().match( /MSIE/ ) ) return;
		
		var right = $( 'rightColumn' );
		var dbg = $( 'rightColumnText' );
		
		var found_separator = false;
		var last_ele_was_script = false;
		var ad_counter = 0;
		var ad_containers = [];
		var dbg = AARP.externalRight.dbg;
		
		for ( var i = 0; i < right.childNodes.length; i++ )
		{
			var node = right.childNodes[i];
			var tagname = ''; if ( node.tagName ) tagname = node.tagName.toUpperCase();
			//dbg.value += node.tagName + ' -> ' + node.id  + ' ? ' + node.src + "\n";
			
			if ( node.id == 'aarp.ad.___separator___' )
			{
				if ( dbg ) dbg.value += "\n# found_separator!";
				found_separator = true;
				continue;
			}
			else if ( tagname == 'DIV' && node.getAttribute( 'table' ) == 'y' )
			{
				ad_containers = AARP.externalRight.extractAdContainers( node );
				if ( dbg ) dbg.value += "\nad_containers=" + ad_containers;
			}
			
			if ( !found_separator ) continue;
			
			// a legitimate ad node; remove and insert into container pointed to by ad_counter,
			// then increment ad_counter by 1.
			if ( tagname != 'SCRIPT' && tagname != 'NOSCRIPT' && tagname.match( /[\w]+/ ) )
			{
				//dbg.value += ad_counter + ' - ' + tagname + ' : ' + node.innerHTML + "\n\n";
				right.removeChild( node );
				if ( ad_containers[ad_counter] )
				{
					ad_containers[ad_counter].appendChild( node );
					ad_counter++;
				}
				last_ele_was_script = false;
			}
		}
	}
	
	/**
	* Grabs the first child of each node under parent that has 'ad' in the class name.
	*/
	
	, extractAdContainers: function( parent )
	{
		var ad_containers = [];
		for ( var i = 0; i < parent.childNodes.length; i++ )
		{
			var node = parent.childNodes[i];
			if ( node.className.match( /^ad/ ) )
				ad_containers.push( node.firstChild );
		}
		
		return ad_containers;
	}
}


AARP.misc = {
   mostPopularFixer: function( div_id )
   {
       Event.observe( window, 'load', function() {
           if ( !$( div_id ) ) return;
           var li = $( div_id ).getElementsByTagName( 'a' );
           for ( var i = 0; i < li.length; i++ )
           {
               var a = li[i];
               try { a.innerHTML = unescape( a.innerHTML ); }
               catch ( e ) {}
           }
       } );
   }
}

/**
* Moved from js/cms/ctg.js to here. Could be useful for other things.
*/

AARP.XMLParser = {
   parse: function( xml )
   {
       var xmlDoc = null;
       var docType = "text/xml";

       var opts = {}; if ( arguments[1] ) opts = arguments[1];
       if ( opts.docType ) docType = opts.docType;

       try //Internet Explorer
       {
           xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" );
           xmlDoc.async = false;
           // IE parser does not like DOCTYPE =/
           xmlDoc.loadXML( xml.replace( /^\s*<!DOCTYPE[^>]+>/, '' ) );
       }
       catch( e )
       {
           try //Firefox, Mozilla, Opera, etc.
           {
               var parser = new DOMParser();
               xmlDoc = parser.parseFromString( xml, docType );
           }
           catch( f ) { dbg(f.description) }
       }

       return xmlDoc;
   }

   , getSpanText: function( span )
   {
       if ( span.childNodes.length > 0 )
           return span.childNodes[0].nodeValue;
       else
           return '';
   }
}

/*
Expandable Categories.
  Example can be seen at http://www.aarp.org/aarp/About_AARP/contact_aarp/
*/

AARP.expandCats = {
    enabled: false
    , categories: function()
    {
        if ( !AARP.expandCats.enabled ) return;

        var groupArray = $$('.categoryGroup');
        var groupTitleArray = $$('.categoryGroup h3 a');
        var subGroupsArray = $$('.subGroups');
        var categoryArray = $$('.category');
        var categoryTitleArray = $$('.category h4 a');
        var contentArray = $$('.categoryContent');

        for (var i = 0; i < groupArray.length; ++i) {
          var subCat = groupArray[i].getElementsByTagName("div");
          var groupId = groupArray[i].id;
          for (var j = 0; j < subCat.length; ++j) {
            if (subCat[j].id.indexOf(groupId + "_") != 0) {
              if (subCat[j].className == "category") {
                subCat[j].id = groupId + "_" + subCat[j].id;
              }
              if (subCat[j].className == "categoryContent") {
                subCat[j].id = subCat[j].parentNode.id + "_content";
              }
            }
          }
        }

        for (var i = 0; i < groupTitleArray.length; ++i) {
          var groupTitle = groupTitleArray[i];
          groupTitle.onclick = switcherManual;
        }

        for (var i = 0; i < categoryTitleArray.length; ++i) {
          var subCatTitle = categoryTitleArray[i];
          subCatTitle.onclick = switcherManual2;
        }

        function switcherManual()
    		{
    				var thisGroup = "";
    				var parent = this.parentNode;
    				while ( parent != null ) {
    					if ( parent.className && parent.className == "categoryGroup" ) {
    						thisGroup = parent;
    					}
    					parent = parent.parentNode;
    				}
    				var subGroup = document.getElementById(thisGroup.id + "_subGroup");
    				if (subGroup == null) {
    					subGroup = document.getElementById(thisGroup.id + "_" + "categorySolo");
    				}
    				if (subGroup.style.display == "block") {
    					subGroup.style.display = "none";
    					thisGroup.getElementsByTagName("a")[0].className = "";
    				} else {
    					for (var i = 0; i < groupTitleArray.length; ++i) {
    						groupTitleArray[i].className = "";
    					}
    					for (var i = 0; i < subGroupsArray.length; ++i) {
    						subGroupsArray[i].style.display = "none";
    					}
    					for (var i = 0; i < categoryArray.length; ++i) {
    						if (categoryArray[i].id.indexOf("categorySolo") > -1) {
    							categoryArray[i].style.display = "none";
    						}
    					}
    					subGroup.style.display = "block";
    					thisGroup.getElementsByTagName("a")[0].className = "on";
    					for (var i = 0; i < contentArray.length; ++i) {
    						if (contentArray[i].id.indexOf("categorySolo") < 0) {
    							contentArray[i].style.display = "none"
    							if (categoryTitleArray[i]) {
    								categoryTitleArray[i].className = "";
    							}
    							if (contentArray[i].id.split("_content")[0] == this.href.split("#")[1]) {
    								contentArray[i].style.display = "block";
    								categoryTitleArray[i].className = "on";
    							}
    						}
    		
    					}
    					if (!subGroup) {
    						soloCat.style.display = "block"
    					}
    				}
    				return false;
    		} //switcherManual
    
        function switcherManual2()
    		{
    				var thisGroup = "";
    				var parent = this.parentNode;
    				while ( parent != null ) {
    					if ( parent.className && parent.className == "category" ) {
    						thisGroup = parent;
    					}
    					parent = parent.parentNode;
    				}
    				var catContent = document.getElementById(thisGroup.id + "_content");
    		
    				if (catContent == null) {
    					catContent = document.getElementById(thisGroup.id + "_" + thisGroup.id + "Solo");
    				}
    				if (catContent.style.display == "block") {
    					catContent.style.display = "none";
    					thisGroup.getElementsByTagName("a")[0].className = "";
    				} else {
    					for (var i = 0; i < contentArray.length; ++i) {
    						if (contentArray[i].id.indexOf("categorySolo") < 0) {
    							contentArray[i].style.display = "none";
    							if (categoryTitleArray[i]) {
    								categoryTitleArray[i].className = "";
    							}
    						}
    					}
    					for (var i = 0; i < contentArray.length; ++i) {
    						if (contentArray[i].id.indexOf("categorySolo") > -1) {
    							categoryArray[i].style.display = "none";
    						}
    					}
    					catContent.style.display = "block";
    					thisGroup.getElementsByTagName("a")[0].className = "on";
    				}
    				return false;
    		} //switcherManual2
    }
}
Event.observe( window, 'load', function() { AARP.expandCats.categories(); } );


if ( ( typeof swapFromCommunity ) == 'undefined' ) {
	function swapFromCommunity() {
	}
} ;
