/*
 * JavaScript "ctype" routines, derived from FreeBSD's libc.
 *
 * $Id: ctype.js 59173 2007-11-07 18:01:36Z rpetty $
 */

// helper
function ord(c)
{
	if ("number" == typeof(c))
		return Math.floor(c);
	if ("string" == typeof(c))
		return c.charCodeAt();
	return 0xFFFD;
}


/*
 * From: ctype.h
 *
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 *
 * This code is derived from software contributed to Berkeley by
 * Paul Borman at Krystal Technologies.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

function	isalnum(c)	{ return __istype((c), _CTYPE_A|_CTYPE_D); }
function	isalpha(c)	{ return __istype((c), _CTYPE_A); }
function	iscntrl(c)	{ return __istype((c), _CTYPE_C); }
function	isdigit(c)	{ return __isctype((c), _CTYPE_D); }	/* ANSI -- locale independent */
function	isgraph(c)	{ return __istype((c), _CTYPE_G); }
function	islower(c)	{ return __istype((c), _CTYPE_L); }
function	isprint(c)	{ return __istype((c), _CTYPE_R); }
function	ispunct(c)	{ return __istype((c), _CTYPE_P); }
function	isspace(c)	{ return __istype((c), _CTYPE_S); }
function	isupper(c)	{ return __istype((c), _CTYPE_U); }
function	isxdigit(c)	{ return __isctype((c), _CTYPE_X); }	/* ANSI -- locale independent */
function	tolower(c)	{ return __tolower(c); }
function	toupper(c)	{ return __toupper(c); }

/*
 * POSIX.1-2001 specifies _tolower() and _toupper() to be macros equivalent to
 * tolower() and toupper() respectively, minus extra checking to ensure that
 * the argument is a lower or uppercase letter respectively.  We've chosen to
 * implement these macros with the same error checking as tolower() and
 * toupper() since this doesn't violate the specification itself, only its
 * intent.  We purposely leave _tolower() and _toupper() undocumented to
 * discourage their use.
 *
 * XXX isascii() and toascii() should similarly be undocumented.
 */
function	_tolower(c)	{ return __tolower(c); }
function	_toupper(c)	{ return __toupper(c); }
function	isascii(c)	{ return (((c) & ~0x7F) == 0); }
function	toascii(c)	{ return ((c) & 0x7F); }

// from C99:
function	isblank(c)	{ return __istype((c), _CTYPE_B); }

// BSD-specific:
function	digittoint(c)	{ return __maskrune((c), 0xFF); }
function	ishexnumber(c)	{ return __istype((c), _CTYPE_X); }
function	isideogram(c)	{ return __istype((c), _CTYPE_I); }
function	isnumber(c)		{ return __istype((c), _CTYPE_D); }
function	isphonogram(c)	{ return __istype((c), _CTYPE_Q); }
function	isrune(c)		{ return __istype((c), 0xFFFFFF00); }
function	isspecial(c)	{ return __istype((c), _CTYPE_T); }


/*
 * From: _ctype.h
 *
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 *
 * This code is derived from software contributed to Berkeley by
 * Paul Borman at Krystal Technologies.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

var	_CTYPE_A	= 0x00000100		/* Alpha */
var	_CTYPE_C	= 0x00000200		/* Control */
var	_CTYPE_D	= 0x00000400		/* Digit */
var	_CTYPE_G	= 0x00000800		/* Graph */
var	_CTYPE_L	= 0x00001000		/* Lower */
var	_CTYPE_P	= 0x00002000		/* Punct */
var	_CTYPE_S	= 0x00004000		/* Space */
var	_CTYPE_U	= 0x00008000		/* Upper */
var	_CTYPE_X	= 0x00010000		/* X digit */
var	_CTYPE_B	= 0x00020000		/* Blank */
var	_CTYPE_R	= 0x00040000		/* Print */
var	_CTYPE_I	= 0x00080000		/* Ideogram */
var	_CTYPE_T	= 0x00100000		/* Special */
var	_CTYPE_Q	= 0x00200000		/* Phonogram */
var	_CTYPE_SW0	= 0x20000000		/* 0 width character */
var	_CTYPE_SW1	= 0x40000000		/* 1 width character */
var	_CTYPE_SW2	= 0x80000000		/* 2 width character */
var	_CTYPE_SW3	= 0xc0000000		/* 3 width character */
var	_CTYPE_SWM	= 0xe0000000		/* Mask for screen width data */
var	_CTYPE_SWS	= 30			/* Bits to shift to get width */


var _CurrentRuneLocale, _DefaultRuneLocale;

function __maskrune(_c, _f)
{
	var runetype = _CurrentRuneLocale["__runetype"][ord(_c)];
	return ("number" == typeof(runetype)) ? (runetype & _f) : 0;
}

function __istype(_c, _f)
{
	return (!!__maskrune(_c, _f));
}

function __isctype(_c, _f)
{
	var runetype = _DefaultRuneLocale["__runetype"][ord(_c)];
	return ("number" == typeof(runetype)) ? !!(runetype & _f) : false;
}

function __toupper(_c)
{
	var rune = _CurrentRuneLocale["__mapupper"][ord(_c)];
	return ("number" == typeof(rune)) ? rune : _CurrentRuneLocale["__invalid_rune"];
}

function __tolower(_c)
{
	var rune = _CurrentRuneLocale["__maplower"][ord(_c)];
	return ("number" == typeof(rune)) ? rune : _CurrentRuneLocale["__invalid_rune"];
}

function __wcwidth(_c)
{
	var _x;

	if (_c == 0)
		return (0);
	_x = __maskrune(_c, _CTYPE_SWM|_CTYPE_R);
	if ((_x & _CTYPE_SWM) != 0)
		return ((_x & _CTYPE_SWM) >> _CTYPE_SWS);
	return ((_x & _CTYPE_R) != 0 ? 1 : -1);
}


/*
 * From: table.c
 *
 * Copyright (c) 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Paul Borman at Krystal Technologies.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

_DefaultRuneLocale = new Object();
_DefaultRuneLocale["__magic"] = "RuneMagi";		/* Indicates version 0 of RuneLocale */
_DefaultRuneLocale["__encoding"] = "NONE";
_DefaultRuneLocale["__invalid_rune"] = String.fromCharCode(0xFFFD);
_DefaultRuneLocale["__runetype"] =
[	/*00*/	_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
	/*08*/	_CTYPE_C,
			_CTYPE_C|_CTYPE_S|_CTYPE_B,
			_CTYPE_C|_CTYPE_S,
			_CTYPE_C|_CTYPE_S,
			_CTYPE_C|_CTYPE_S,
			_CTYPE_C|_CTYPE_S,
			_CTYPE_C,
			_CTYPE_C,
	/*10*/	_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
	/*18*/	_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
			_CTYPE_C,
	/*20*/	_CTYPE_S|_CTYPE_B|_CTYPE_R,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
	/*28*/	_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
	/*30*/	_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|0,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|1,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|2,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|3,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|4,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|5,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|6,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|7,
	/*38*/	_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|8,
			_CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|9,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
	/*40*/	_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10,
			_CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11,
			_CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12,
			_CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13,
			_CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14,
			_CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
	/*48*/	_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
	/*50*/	_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
	/*58*/	_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
	/*60*/	_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10,
			_CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11,
			_CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12,
			_CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13,
			_CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14,
			_CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
	/*68*/	_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
	/*70*/	_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
	/*78*/	_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_P|_CTYPE_R|_CTYPE_G,
			_CTYPE_C,
];
_DefaultRuneLocale["__maplower"] =
[	0x00,	0x01,	0x02,	0x03,	0x04,	0x05,	0x06,	0x07,
	0x08,	0x09,	0x0a,	0x0b,	0x0c,	0x0d,	0x0e,	0x0f,
	0x10,	0x11,	0x12,	0x13,	0x14,	0x15,	0x16,	0x17,
	0x18,	0x19,	0x1a,	0x1b,	0x1c,	0x1d,	0x1e,	0x1f,
	0x20,	0x21,	0x22,	0x23,	0x24,	0x25,	0x26,	0x27,
	0x28,	0x29,	0x2a,	0x2b,	0x2c,	0x2d,	0x2e,	0x2f,
	0x30,	0x31,	0x32,	0x33,	0x34,	0x35,	0x36,	0x37,
	0x38,	0x39,	0x3a,	0x3b,	0x3c,	0x3d,	0x3e,	0x3f,
	0x40,	'a',	'b',	'c',	'd',	'e',	'f',	'g',
	'h',	'i',	'j',	'k',	'l',	'm',	'n',	'o',
	'p',	'q',	'r',	's',	't',	'u',	'v',	'w',
	'x',	'y',	'z',	0x5b,	0x5c,	0x5d,	0x5e,	0x5f,
	0x60,	'a',	'b',	'c',	'd',	'e',	'f',	'g',
	'h',	'i',	'j',	'k',	'l',	'm',	'n',	'o',
	'p',	'q',	'r',	's',	't',	'u',	'v',	'w',
	'x',	'y',	'z',	0x7b,	0x7c,	0x7d,	0x7e,	0x7f,
	0x80,	0x81,	0x82,	0x83,	0x84,	0x85,	0x86,	0x87,
	0x88,	0x89,	0x8a,	0x8b,	0x8c,	0x8d,	0x8e,	0x8f,
	0x90,	0x91,	0x92,	0x93,	0x94,	0x95,	0x96,	0x97,
	0x98,	0x99,	0x9a,	0x9b,	0x9c,	0x9d,	0x9e,	0x9f,
	0xa0,	0xa1,	0xa2,	0xa3,	0xa4,	0xa5,	0xa6,	0xa7,
	0xa8,	0xa9,	0xaa,	0xab,	0xac,	0xad,	0xae,	0xaf,
	0xb0,	0xb1,	0xb2,	0xb3,	0xb4,	0xb5,	0xb6,	0xb7,
	0xb8,	0xb9,	0xba,	0xbb,	0xbc,	0xbd,	0xbe,	0xbf,
	0xc0,	0xc1,	0xc2,	0xc3,	0xc4,	0xc5,	0xc6,	0xc7,
	0xc8,	0xc9,	0xca,	0xcb,	0xcc,	0xcd,	0xce,	0xcf,
	0xd0,	0xd1,	0xd2,	0xd3,	0xd4,	0xd5,	0xd6,	0xd7,
	0xd8,	0xd9,	0xda,	0xdb,	0xdc,	0xdd,	0xde,	0xdf,
	0xe0,	0xe1,	0xe2,	0xe3,	0xe4,	0xe5,	0xe6,	0xe7,
	0xe8,	0xe9,	0xea,	0xeb,	0xec,	0xed,	0xee,	0xef,
	0xf0,	0xf1,	0xf2,	0xf3,	0xf4,	0xf5,	0xf6,	0xf7,
	0xf8,	0xf9,	0xfa,	0xfb,	0xfc,	0xfd,	0xfe,	0xff,
];
_DefaultRuneLocale["__mapupper"] =
[	0x00,	0x01,	0x02,	0x03,	0x04,	0x05,	0x06,	0x07,
	0x08,	0x09,	0x0a,	0x0b,	0x0c,	0x0d,	0x0e,	0x0f,
	0x10,	0x11,	0x12,	0x13,	0x14,	0x15,	0x16,	0x17,
	0x18,	0x19,	0x1a,	0x1b,	0x1c,	0x1d,	0x1e,	0x1f,
	0x20,	0x21,	0x22,	0x23,	0x24,	0x25,	0x26,	0x27,
	0x28,	0x29,	0x2a,	0x2b,	0x2c,	0x2d,	0x2e,	0x2f,
	0x30,	0x31,	0x32,	0x33,	0x34,	0x35,	0x36,	0x37,
	0x38,	0x39,	0x3a,	0x3b,	0x3c,	0x3d,	0x3e,	0x3f,
	0x40,	'A',	'B',	'C',	'D',	'E',	'F',	'G',
	'H',	'I',	'J',	'K',	'L',	'M',	'N',	'O',
	'P',	'Q',	'R',	'S',	'T',	'U',	'V',	'W',
	'X',	'Y',	'Z',	0x5b,	0x5c,	0x5d,	0x5e,	0x5f,
	0x60,	'A',	'B',	'C',	'D',	'E',	'F',	'G',
	'H',	'I',	'J',	'K',	'L',	'M',	'N',	'O',
	'P',	'Q',	'R',	'S',	'T',	'U',	'V',	'W',
	'X',	'Y',	'Z',	0x7b,	0x7c,	0x7d,	0x7e,	0x7f,
	0x80,	0x81,	0x82,	0x83,	0x84,	0x85,	0x86,	0x87,
	0x88,	0x89,	0x8a,	0x8b,	0x8c,	0x8d,	0x8e,	0x8f,
	0x90,	0x91,	0x92,	0x93,	0x94,	0x95,	0x96,	0x97,
	0x98,	0x99,	0x9a,	0x9b,	0x9c,	0x9d,	0x9e,	0x9f,
	0xa0,	0xa1,	0xa2,	0xa3,	0xa4,	0xa5,	0xa6,	0xa7,
	0xa8,	0xa9,	0xaa,	0xab,	0xac,	0xad,	0xae,	0xaf,
	0xb0,	0xb1,	0xb2,	0xb3,	0xb4,	0xb5,	0xb6,	0xb7,
	0xb8,	0xb9,	0xba,	0xbb,	0xbc,	0xbd,	0xbe,	0xbf,
	0xc0,	0xc1,	0xc2,	0xc3,	0xc4,	0xc5,	0xc6,	0xc7,
	0xc8,	0xc9,	0xca,	0xcb,	0xcc,	0xcd,	0xce,	0xcf,
	0xd0,	0xd1,	0xd2,	0xd3,	0xd4,	0xd5,	0xd6,	0xd7,
	0xd8,	0xd9,	0xda,	0xdb,	0xdc,	0xdd,	0xde,	0xdf,
	0xe0,	0xe1,	0xe2,	0xe3,	0xe4,	0xe5,	0xe6,	0xe7,
	0xe8,	0xe9,	0xea,	0xeb,	0xec,	0xed,	0xee,	0xef,
	0xf0,	0xf1,	0xf2,	0xf3,	0xf4,	0xf5,	0xf6,	0xf7,
	0xf8,	0xf9,	0xfa,	0xfb,	0xfc,	0xfd,	0xfe,	0xff,
];

_CurrentRuneLocale = _DefaultRuneLocale;
/*
 * From timelocal.c:
 *
 * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
 * Copyright (c) 1997 FreeBSD Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Id: timelocal.js 59173 2007-11-07 18:01:36Z rpetty $
 */

var _js_time_locale = new Object();
_js_time_locale["mon"] =
	[ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
_js_time_locale["month"] =
	[ "January", "February", "March", "April", "May", "June",
	  "July", "August", "September", "October", "November", "December" ];
_js_time_locale["wday"] =
	[ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ];
_js_time_locale["weekday"] =
	[ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];
_js_time_locale["X_fmt"] = "%H:%M:%S";
_js_time_locale["x_fmt"] = "%m/%d/%y";
_js_time_locale["c_fmt"] = "%a %b %e %H:%M:%S %Y";
_js_time_locale["am"] = "AM";
_js_time_locale["pm"] = "PM";
_js_time_locale["date_fmt"] = "%a %b %e %H:%M:%S %Z %Y";
_js_time_locale["alt_month"] =
	[ "January", "February", "March", "April", "May", "June",
	  "July", "August", "September", "October", "November", "December" ];
_js_time_locale["md_order"] = "md";
_js_time_locale["ampm_fmt"] = "%I:%M:%S %p";

var _time_locale;
if ("undefined" == typeof(_time_locale))
{
	// Since there is no clone() in javascript...
	_time_locale = new Array();
	var attributes = new Array("mon", "month", "wday", "weekday", "alt_month");
	for (var attr in _js_time_locale)
	{
		if ("Array" == typeof(_js_time_locale[attr]))
		{
			_time_locale[attr] = new Array();
			for (var i in _js_time_locale[attr])
			{
				_time_locale[attr][i] = _js_time_locale[attr][i];
			}
		}
		else
		{
			_time_locale[attr] = _js_time_locale[attr];
		}
	}
}


function __get_current_time_locale()
{
	return _time_locale;
}

/*
 *  Call this after manually setting up _time_locale, before calling __get_current_time_locale().
 */
function __verify_time_locale()
{
	if ("undefined" == typeof(_time_locale))
	{
		_time_locale = _js_time_locale;
		return;
	}
	if ("undefined" == typeof(_time_locale["mon"]) || _time_locale["mon"].length < 12)
	{
		_time_locale["mon"] = _js_time_locale["mon"];
	}
	if ("undefined" == typeof(_time_locale["month"]) || _time_locale["month"].length < 12)
	{
		_time_locale["month"] = _js_time_locale["month"];
	}
	if ("undefined" == typeof(_time_locale["wday"]) || _time_locale["wday"].length < 7)
	{
		_time_locale["wday"] = _js_time_locale["wday"];
	}
	if ("undefined" == typeof(_time_locale["weekday"]) || _time_locale["weekday"].length < 7)
	{
		_time_locale["weekday"] = _js_time_locale["weekday"];
	}
	if ("undefined" == typeof(_time_locale["X_fmt"]))
	{
		_time_locale["X_fmt"] = _js_time_locale["X_fmt"];
	}
	if ("undefined" == typeof(_time_locale["x_fmt"]))
	{
		_time_locale["x_fmt"] = _js_time_locale["x_fmt"];
	}
	if ("undefined" == typeof(_time_locale["c_fmt"]))
	{
		_time_locale["c_fmt"] = _js_time_locale["c_fmt"];
	}
	if ("undefined" == typeof(_time_locale["am"]))
	{
		_time_locale["am"] = _js_time_locale["am"];
	}
	if ("undefined" == typeof(_time_locale["pm"]))
	{
		_time_locale["pm"] = _js_time_locale["pm"];
	}
	if ("undefined" == typeof(_time_locale["date_fmt"]))
	{
		_time_locale["date_fmt"] = _js_time_locale["date_fmt"];
	}
	if ("undefined" == typeof(_time_locale["alt_month"]) || _time_locale["alt_month"].length < 12)
	{
		_time_locale["alt_month"] = _js_time_locale["alt_month"];
	}
	if ("undefined" == typeof(_time_locale["md_order"]))
	{
		_time_locale["md_order"] = _js_time_locale["md_order"];
	}
	if ("undefined" == typeof(_time_locale["ampm_fmt"]))
	{
		_time_locale["ampm_fmt"] = _js_time_locale["ampm_fmt"];
	}
}


/*
 * From tzfile.h:
 *
 *
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
 *
 */
var SECSPERMIN = 60;
var MINSPERHOUR = 60;
var HOURSPERDAY = 24;
var DAYSPERWEEK = 7;
var DAYSPERNYEAR = 365;
var DAYSPERLYEAR = 366;
var MONSPERYEAR = 12;

var TM_YEAR_BASE = 0;

function isleap(y)
{
	return (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0));
}
/*
 *	String strftime(String format, Date date);
 *
 * Requires: stdtime/timelocal.js
 *
 */

/*
 * From strftime.c:
 *
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * $Id: strftime.js 51599 2006-12-08 20:31:19Z rpetty $
 */

var PAD_DEFAULT = 0;
var PAD_LESS	= 1;
var PAD_SPACE	= 2;
var PAD_ZERO	= 3;

var fmt_padding_default = new Array();
var fmt_padding_length = new Array();

var PAD_FMT_MONTHDAY	= 0;
var PAD_FMT_HMS			= 0;
var PAD_FMT_CENTURY		= 0;
var PAD_FMT_SHORTYEAR	= 0;
var PAD_FMT_MONTH		= 0;
var PAD_FMT_WEEKOFYEAR	= 0;
var PAD_FMT_DAYOFMONTH	= 0;
fmt_padding_default[0] = PAD_ZERO;
fmt_padding_length[0] = 2;
var PAD_FMT_SDAYOFMONTH	= 1;
var PAD_FMT_SHMS		= 1;
fmt_padding_default[1] = PAD_SPACE;
fmt_padding_length[1] = 2;
var PAD_FMT_DAYOFYEAR	= 2;
fmt_padding_default[2] = PAD_ZERO;
fmt_padding_length[2] = 3;
var PAD_FMT_YEAR		= 3;
fmt_padding_default[3] = PAD_ZERO;
fmt_padding_length[3] = 4;


function strftime_fmt_int(i, fmt_type, pad_type)
{
	var field_length = fmt_padding_length[fmt_type];
	if (PAD_DEFAULT == pad_type)
	{
		pad_type = fmt_padding_default[fmt_type];
	}
	i = parseInt(i);
	var field = i.toString();
	if (PAD_LESS == pad_type)
	{
		return field;
	}
	var pad_char = (PAD_ZERO == pad_type ? '0' : ' ');
	while (field.length < field_length)
	{
		field = pad_char + field;
	}
	return field;
}

function strftime(format, date)
{
	var pt = "";	// target
	var Ealternative, Oalternative, PadIndex;
	var tptr = __get_current_time_locale();
	var format_length = format.length;
	var _sec = date.getSeconds();
	var _min = date.getMinutes();
	var _hour = date.getHours();
	var _mday = date.getDate();
	var _mon = date.getMonth();
	var _year = date.getFullYear();
	var _wday = date.getDay();
	var _yday = -1;	// currently unimplemented
	var _isdst = -1;	// currently unimplemented
	var _zone = "?TZ";	// currently unimplemented
	var _gmtoff = date.getTimezoneOffset() * 60;

	for (var i = 0; i < format_length; i++)
	{
		var c = format.charAt(i);
		if (c == '%') {
			Ealternative = 0;
			Oalternative = 0;
			PadIndex	 = PAD_DEFAULT;
//label:
		var continueLoop;
		do {
			continueLoop = 0;
			i++;
			if (i >= format_length)
			{
				--i;
				break;
			}
			c = format.charAt(i);
			switch (c)
			{
			case 'A':
				pt += (_wday < 0 || wday >= DAYSPERWEEK) ? "?" : tptr["weekday"][_wday];
				continue;
			case 'a':
				pt += (_wday < 0 || wday >= DAYSPERWEEK) ? "?" : tptr["wday"][_wday];
				continue;
			case 'B':
				pt += (_mon < 0 || _mon >= MONSPERYEAR) ? "?" :
					(Oalternative ? tptr["alt_month"] : tptr["month"])[_mon];
				continue;
			case 'b':
			case 'h':
				pt += (_mon < 0 || _mon >= MONSPERYEAR) ? "?" : tptr["mon"][_mon];
				continue;
			case 'C':
				/*
				** %C used to do a...
				**	_fmt("%a %b %e %X %Y", t);
				** ...whereas now POSIX 1003.2 calls for
				** something completely different.
				** (ado, 1993-05-24)
				*/
				pt += strftime_fmt_int((_year + TM_YEAR_BASE) / 100, PAD_FMT_CENTURY, PadIndex);
				continue;
			case 'c':
				pt += strftime(tptr["c_fmt"], date);
				continue;
			case 'D':
				pt += strftime("%m/%d/%y", date);
				continue;
			case 'd':
				pt += strftime_fmt_int(_mday, PAD_FMT_DAYOFMONTH, PadIndex);
				continue;
			case 'E':
				if (Ealternative || Oalternative)
					break;
				Ealternative++;
				continueLoop = 1; break;	// goto label;
			case 'O':
				/*
				** C99 locale modifiers.
				** The sequences
				**	%Ec %EC %Ex %EX %Ey %EY
				**	%Od %oe %OH %OI %Om %OM
				**	%OS %Ou %OU %OV %Ow %OW %Oy
				** are supposed to provide alternate
				** representations.
				**
				** FreeBSD extension
				**      %OB
				*/
				if (Ealternative || Oalternative)
					break;
				Oalternative++;
				continueLoop = 1; break;	// goto label;
			case 'e':
				pt += strftime_fmt_int(_mday, PAD_FMT_SDAYOFMONTH, PadIndex);
				continue;
			case 'F':
				pt += strftime("%Y-%m-%d", date);
				continue;
			case 'H':
				pt += strftime_fmt_int(_hour, PAD_FMT_HMS, PadIndex);
				continue;
			case 'I':
				pt += strftime_fmt_int((_hour % 12) ? (_hour % 12) : 12, PAD_FMT_HMS, PadIndex);
				continue;
			case 'j':
				pt += strftime_fmt_int(_yday + 1, PAD_FMT_DAYOFYEAR, PadIndex);
				continue;
			case 'k':
				/*
				** This used to be...
				**	_conv(t->tm_hour % 12 ?
				**		t->tm_hour % 12 : 12, 2, ' ');
				** ...and has been changed to the below to
				** match SunOS 4.1.1 and Arnold Robbins'
				** strftime version 3.0.  That is, "%k" and
				** "%l" have been swapped.
				** (ado, 1993-05-24)
				*/
				pt += strftime_fmt_int(_hour, PAD_FMT_SHMS, PadIndex);
				continue;
			case 'l':
				/*
				** This used to be...
				**	_conv(t->tm_hour, 2, ' ');
				** ...and has been changed to the below to
				** match SunOS 4.1.1 and Arnold Robbin's
				** strftime version 3.0.  That is, "%k" and
				** "%l" have been swapped.
				** (ado, 1993-05-24)
				*/
				pt += strftime_fmt_int((_hour % 12) ? (_hour % 12) : 12, PAD_FMT_SHMS, PadIndex);
				continue;
			case 'M':
				pt += strftime_fmt_int(_min, PAD_FMT_HMS, PadIndex);
				continue;
			case 'm':
				pt += strftime_fmt_int(_mon + 1, PAD_FMT_MONTH, PadIndex);
				continue;
			case 'n':
				pt += "\n";
				continue;
			case 'p':
				pt += (_hour >= (HOURSPERDAY / 2)) ? tptr["pm"] : tptr["am"];
				continue;
			case 'R':
				pt += strftime("%H:%M", date);
				continue;
			case 'r':
				pt += strftime(tptr["ampm_fmt"], date);
				continue;
			case 'S':
				pt += strftime_fmt_int(_sec, PAD_FMT_HMS, PadIndex);
				continue;
			case 's':
				{
					var seconds = date.getUTCMilliseconds() / 1000;
					pt += parseInt(seconds);
				}
				continue;
			case 'T':
				pt += strftime("%H:%M:%S", date);
				continue;
			case 't':
				pt += "\t";
				continue;
			case 'U':
				pt += strftime_fmt_int((_yday + DAYSPERWEEK - _wday) / DAYSPERWEEK,
										PAD_FMT_WEEKOFYEAR, PadIndex);
				continue;
			case 'u':
				/*
				** From Arnold Robbins' strftime version 3.0:
				** "ISO 8601: Weekday as a decimal number
				** [1 (Monday) - 7]"
				** (ado, 1993-05-24)
				*/
				pt += strftime_fmt_int((_wday == 0) ? DAYSPERWEEK : _wday, 0, PAD_LESS);
				continue;
			case 'V':	/* ISO 8601 week number */
			case 'G':	/* ISO 8601 year (four digits) */
			case 'g':	/* ISO 8601 year (two digits) */
/*
** From Arnold Robbins' strftime version 3.0:  "the week number of the
** year (the first Monday as the first day of week 1) as a decimal number
** (01-53)."
** (ado, 1993-05-24)
**
** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
** "Week 01 of a year is per definition the first week which has the
** Thursday in this year, which is equivalent to the week which contains
** the fourth day of January. In other words, the first week of a new year
** is the week which has the majority of its days in the new year. Week 01
** might also contain days from the previous year and the week before week
** 01 of a year is the last week (52 or 53) of the previous year even if
** it contains days from the new year. A week starts with Monday (day 1)
** and ends with Sunday (day 7).  For example, the first week of the year
** 1997 lasts from 1996-12-30 to 1997-01-05..."
** (ado, 1996-01-02)
*/
				{
					var	year;
					var	yday;
					var	wday;
					var	w;

					year = _year + TM_YEAR_BASE;
					yday = _yday;
					wday = _wday;
					for ( ; ; ) {
						var	len;
						var	bot;
						var	top;

						len = isleap(year) ?
							DAYSPERLYEAR :
							DAYSPERNYEAR;
						/*
						** What yday (-3 ... 3) does
						** the ISO year begin on?
						*/
						bot = ((yday + 11 - wday) %
							DAYSPERWEEK) - 3;
						/*
						** What yday does the NEXT
						** ISO year begin on?
						*/
						top = bot -
							(len % DAYSPERWEEK);
						if (top < -3)
							top += DAYSPERWEEK;
						top += len;
						if (yday >= top) {
							++year;
							w = 1;
							break;
						}
						if (yday >= bot) {
							w = 1 + ((yday - bot) /
								DAYSPERWEEK);
							break;
						}
						--year;
						yday += isleap(year) ?
							DAYSPERLYEAR :
							DAYSPERNYEAR;
					}
					if (c == 'V')
						pt += strftime_fmt_int(w, PAD_FMT_WEEKOFYEAR, PadIndex);
					else if (c == 'g')
						pt += strftime_fmt_int(year % 100, PAD_FMT_SHORTYEAR, PadIndex);
					else
						pt += strftime_fmt_int(year, PAD_FMT_YEAR, PadIndex);
				}
				continue;
			case 'v':
				/*
				** From Arnold Robbins' strftime version 3.0:
				** "date as dd-bbb-YYYY"
				** (ado, 1993-05-24)
				*/
				pt += strftime("%e-%b-%Y", date);
				continue;
			case 'W':
				pt += strftime_fmt_int((_yday + DAYSPERWEEK -
						(_wday ? (_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK,
										PAD_FMT_WEEKOFYEAR, PadIndex);
				continue;
			case 'w':
				pt += strftime_fmt_int(_wday, 0, PAD_LESS);
				continue;
			case 'X':
				pt += strftime(tptr["X_fmt"], date);
				continue;
			case 'x':
				pt += strftime(tptr["x_fmt"], date);
				continue;
			case 'y':
				pt += strftime_fmt_int((_year + TM_YEAR_BASE) % 100, PAD_FMT_SHORTYEAR, PadIndex);
				continue;
			case 'Y':
				pt += strftime_fmt_int(_year + TM_YEAR_BASE, PAD_FMT_YEAR, PadIndex);
				continue;
			case 'Z':
				/*
				** C99 says that %Z must be replaced by the
				** empty string if the time zone is not
				** determinable.
				*/
				continue;
			case 'z':
				var	diff;
				var	sign;

				if (_isdst < 0)
					continue;
				diff = _gmtoff;
				/*
				** C99 says that the UTC offset must
				** be computed by looking only at
				** tm_isdst.  This requirement is
				** incorrect, since it means the code
				** must rely on magic (in this case
				** altzone and timezone), and the
				** magic might not have the correct
				** offset.  Doing things correctly is
				** tricky and requires disobeying C99;
				** see GNU C strftime for details.
				** For now, punt and conform to the
				** standard, even though it's incorrect.
				**
				** C99 says that %z must be replaced by the
				** empty string if the time zone is not
				** determinable, so output nothing if the
				** appropriate variables are not available.
				*/
				continue;
			case '+':
				pt += strftime(tptr["date_fmt"], date);
				continue;
			case '-':
				if (PadIndex != PAD_DEFAULT)
					break;
				PadIndex = PAD_LESS;
				continueLoop = 1; break;	// goto label;
			case '_':
				if (PadIndex != PAD_DEFAULT)
					break;
				PadIndex = PAD_SPACE;
				continueLoop = 1; break;	// goto label;
			case '0':
				if (PadIndex != PAD_DEFAULT)
					break;
				PadIndex = PAD_ZERO;
				continueLoop = 1; break;	// goto label;
			case '%':
			/*
			** X311J/88-090 (4.12.3.5): if conversion char is
			** undefined, behavior is undefined.  Print out the
			** character itself as printf(3) also does.
			*/
			default:
				pt += c;
				break;
			}
		} while (continueLoop);
		}
		else
		{
			pt += c;
		}
	}
	return pt;
}
/*
 *	String strptime(String parse_buffer, String format, Date date);
 *
 * Requires: locale/ctype.js, stdtime/timelocal.js
 *
 * Pilfered from FreeBSD's strptime.c:
 *
 * Powerdog Industries kindly requests feedback from anyone modifying
 * this function:
 *
 * Date: Thu, 05 Jun 1997 23:17:17 -0400  
 * From: Kevin Ruddy <kevin.ruddy@powerdog.com>
 * To: James FitzGibbon <james@nexis.net>
 * Subject: Re: Use of your strptime(3) code (fwd)
 * 
 * The reason for the "no mod" clause was so that modifications would
 * come back and we could integrate them and reissue so that a wider 
 * audience could use it (thereby spreading the wealth).  This has   
 * made it possible to get strptime to work on many operating systems.
 * I'm not sure why that's "plain unacceptable" to the FreeBSD team.
 * 
 * Anyway, you can change it to "with or without modification" as
 * you see fit.  Enjoy.                                          
 * 
 * Kevin Ruddy
 * Powerdog Industries, Inc.
 *
 *
 * Copyright (c) 1994 Powerdog Industries.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in the documentation and/or other materials provided with the
 *    distribution.
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgement:
 *      This product includes software developed by Powerdog Industries.
 * 4. The name of Powerdog Industries may not be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: strptime.js 51599 2006-12-08 20:31:19Z rpetty $
 */

var _strptime_report_errors = true;
var _strptime_report = "";

function strptime(parse_buffer, format, date)
{
	var GMT = new Array();
	GMT[0] = 0;
	var ret = _strptime(parse_buffer, format, date, GMT);
	// do what with GMT[0] ?
	return ret;
}

function strptime_err(buf, b, fmt, f, msg)
{
	if (_strptime_report_errors)
	{
		if (f > 0)
			f--;
		_strptime_report +=
			"Err in \"" + fmt.substr(f) + "\" at \"" + buf.substr(b) + "\": " + msg + "\n";
	}
	return "NULL";
}

function _strptime(buf, fmt, date, GMTp)
{
	var	c;
	var	i, len;
	var Ealternative, Oalternative;
	var tptr = __get_current_time_locale();
	var fmt_len = fmt.length, buf_len = buf.length;
	var f = 0, b = 0;
	var cmpstr, bufstr, h;

	while (f < fmt_len)
	{
		if (b >= buf_len)
			break;

		c = fmt.charAt(f++);

		if (c != '%') {
			if (isspace(c))
				while (b < buf_len && isspace(buf.charAt(b)))
					b++;
			else if (c != buf.charAt(b++))
				return strptime_err(buf, b, fmt, f, "exact character mismatch");
			continue;
		}

		Ealternative = 0;
		Oalternative = 0;
//label:
		do
		{
			var continueLoop = true;
			if (f < fmt_len)
			{
				c = fmt.charAt(f++);
			}
			else
			{
				c = '%';
				break;
			}
			switch (c)
			{
			case 'E':
				Ealternative++;
				break;
			case 'O':
				Oalternative++;
				break;
			case '%':
			default:
				continueLoop = false;
			case '-':
			case '_':
			case '0':
				break;
			}
		} while (continueLoop);

		switch (c) {
		case '%':
			if (buf.charAt(b++) != '%')
				return strptime_err(buf, b, fmt, f, "exact character mismatch");
			break;

		case '+':
			buf = _strptime(buf.substr(b), tptr["date_fmt"], date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "empty date_fmt");
			b = 0;
			buf_len = buf.length;
			break;

		case 'C':
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			/* XXX This will break for 3-digit centuries. */
			len = 2;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}
			if (i < (TM_YEAR_BASE / 100))
				return strptime_err(buf, b, fmt, f, "century too small");

			date.setFullYear(i * 100 - TM_YEAR_BASE);
			break;

		case 'c':
			buf = _strptime(buf.substr(b), tptr["c_fmt"], date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "empty c_fmt");
			b = 0;
			buf_len = buf.length;
			break;

		case 'D':
			buf = _strptime(buf.substr(b), "%m/%d/%y", date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "");
			b = 0;
			buf_len = buf.length;
			break;

		case 'F':
			buf = _strptime(buf.substr(b), "%Y-%m-%d", date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "");
			b = 0;
			buf_len = buf.length;
			break;

		case 'R':
			buf = _strptime(buf.substr(b), "%H:%M", date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "");
			b = 0;
			buf_len = buf.length;
			break;

		case 'r':
			buf = _strptime(buf.substr(b), tptr["ampm_fmt"], date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "empty ampm_fmt");
			b = 0;
			buf_len = buf.length;
			break;

		case 'T':
			buf = _strptime(buf.substr(b), "%H:%M:%S", date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "");
			b = 0;
			buf_len = buf.length;
			break;

		case 'X':
			buf = _strptime(buf.substr(b), tptr["X_fmt"], date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "empty X_fmt");
			b = 0;
			buf_len = buf.length;
			break;

		case 'x':
			buf = _strptime(buf.substr(b), tptr["x_fmt"], date, GMTp);
			if ("NULL" == buf)
				return strptime_err(buf, b, fmt, f, "empty x_fmt");
			b = 0;
			buf_len = buf.length;
			break;

		case 'j':
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			len = 3;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}
			if (i < 1 || i > 366)
				return strptime_err(buf, b, fmt, f, "out of range");

			// There's no way to set the year day to (i - 1)
			break;

		case 'M':
		case 'S':
			if (b >= buf_len || isspace(buf.charAt(b)))
				break;

			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			len = 2;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}

			if (c == 'M') {
				if (i > 59)
					return strptime_err(buf, b, fmt, f, "out of range");
				date.setMinutes(i);
			} else {
				if (i > 60)
					return strptime_err(buf, b, fmt, f, "out of range");
				date.setSeconds(i);
			}

			if (b < buf_len && isspace(buf.charAt(b)))
				while (f < fmt_len && !isspace(fmt.charAt(f)))
					f++;
			break;

		case 'H':
		case 'I':
		case 'k':
		case 'l':
			/*
			 * Of these, %l is the only specifier explicitly
			 * documented as not being zero-padded.  However,
			 * there is no harm in allowing zero-padding.
			 *
			 * XXX The %l specifier may gobble one too many
			 * digits if used incorrectly.
			 */
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			len = 2;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}
			if (c == 'H' || c == 'k') {
				if (i > 23)
					return strptime_err(buf, b, fmt, f, "out of range");
			} else if (i > 12)
				return strptime_err(buf, b, fmt, f, "out of range");

			date.setHours(i);

			if (b < buf_len && isspace(buf.charAt(b)))
				while (f < fmt_len && !isspace(fmt.charAt(f)))
					f++;
			break;

		case 'p':
			/*
			 * XXX This is bogus if parsed before hour-related
			 * specifiers.
			 */
			cmpstr = tptr["am"].substr(0).toLocaleUpperCase();
			len = cmpstr.length;
			bufstr = buf.substr(b, len).toLocaleUpperCase();
			if (bufstr == cmpstr) {
				h = date.getHours();
				if (h > 12)
					return strptime_err(buf, b, fmt, f, "out of range");
				if (h == 12)
					date.setHours(0);
				b += len;
				break;
			}

			cmpstr = tptr["pm"].substr(0).toLocaleUpperCase();
			len = cmpstr.length;
			bufstr = buf.substr(b, len).toLocaleUpperCase();
			if (bufstr == cmpstr) {
				h = date.getHours();
				if (h > 12)
					return strptime_err(buf, b, fmt, f, "out of range");
				if (h != 12)
					date.setHours(h + 12);
				b += len;
				break;
			}

			return strptime_err(buf, b, fmt, f, "not found");

		case 'A':
		case 'a':
			for (i = 0; i < tptr["weekday"].length; i++) {
				cmpstr = tptr["weekday"][i].toLocaleUpperCase();
				len = cmpstr.length;
				bufstr = buf.substr(b, len).toLocaleUpperCase();
				if (bufstr == cmpstr)
					break;
				cmpstr = tptr["wday"][i].toLocaleUpperCase();
				len = cmpstr.length;
				bufstr = buf.substr(b, len).toLocaleUpperCase();
				if (bufstr == cmpstr)
					break;
			}
			if (i == tptr["weekday"].length)
				return strptime_err(buf, b, fmt, f, "not found");

//	I guess this doesn't exist, contrary to documentation.
//			date.setDay(i);
			b += len;
			break;

		case 'U':
		case 'W':
			/*
			 * XXX This is bogus, as we can not assume any valid
			 * information present in the tm structure at this
			 * point to calculate a real value, so just check the
			 * range for now.
			 */
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			len = 2;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}
			if (i > 53)
				return strptime_err(buf, b, fmt, f, "out of range");

			if (b < buf_len && isspace(buf.charAt(b)))
				while (f < fmt_len && !isspace(fmt.charAt(f)))
					f++;
			break;

		case 'w':
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			i = buf.charAt(b) - '0';
			if (i > 6)
				return strptime_err(buf, b, fmt, f, "out of range");

			date.setDay(i);

			if (b < buf_len && isspace(buf.charAt(b)))
				while (f < fmt_len && !isspace(fmt.charAt(f)))
					f++;
			break;

		case 'd':
		case 'e':
			/*
			 * The %e specifier is explicitly documented as not
			 * being zero-padded but there is no harm in allowing
			 * such padding.
			 *
			 * XXX The %e specifier may gobble one too many
			 * digits if used incorrectly.
			 */
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			len = 2;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}
			if (i > 31)
				return strptime_err(buf, b, fmt, f, "out of range");

			date.setDate(i);

			if (b < buf_len && isspace(buf.charAt(b)))
				while (f < fmt_len && !isspace(fmt.charAt(f)))
					f++;
			break;

		case 'B':
		case 'b':
		case 'h':
			for (i = 0; i < tptr["month"].length; i++) {
				if (Oalternative) {
					if (c == 'B') {
						cmpstr = tptr["alt_month"][i].toLocaleUpperCase();
						len = cmpstr.length;
						bufstr = buf.substr(b, len).toLocaleUpperCase();
						if (bufstr == cmpstr)
							break;
					}
				} else {
					cmpstr = tptr["month"][i].toLocaleUpperCase();
					len = cmpstr.length;
					bufstr = buf.substr(b, len).toLocaleUpperCase();
					if (bufstr == cmpstr)
						break;
					cmpstr = tptr["mon"][i].toLocaleUpperCase();
					len = cmpstr.length;
					bufstr = buf.substr(b, len).toLocaleUpperCase();
					if (bufstr == cmpstr)
						break;
				}
			}
			if (i == tptr["month"].length)
				return strptime_err(buf, b, fmt, f, "not found");

			date.setMonth(i);
			b += len;
			break;

		case 'm':
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			len = 2;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}
			if (i < 1 || i > 12)
				return strptime_err(buf, b, fmt, f, "out of range");

			date.setMonth(i - 1);

			if (b < buf_len && isspace(buf.charAt(b)))
				while (f < fmt_len && !isspace(fmt.charAt(f)))
					f++;
			break;

		case 's':
			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");
			for (i = 0; b < buf_len && isdigit(buf.charAt(b)); b++)
			{
				i *= 10;
				i += buf.charAt(b) - '0';
			}
			date.setTime(i * 1000);
			GMTp[0] = 1;
			break;

		case 'Y':
		case 'y':
			if (b >= buf_len || isspace(buf.charAt(b)))
				break;

			if (!isdigit(buf.charAt(b)))
				return strptime_err(buf, b, fmt, f, "expected digit");

			len = (c == 'Y') ? 4 : 2;
			for (i = 0; len && b < buf_len && isdigit(buf.charAt(b)); b++) {
				i *= 10;
				i += buf.charAt(b) - '0';
				len--;
			}
			if (c == 'Y')
				i -= 1900;
			if (c == 'y' && i < 69)
				i += 100;
			if (i < 0)
				return strptime_err(buf, b, fmt, f, "out of range");

			date.setFullYear(i + 1900);

			if (b < buf_len && isspace(buf.charAt(b)))
				while (f < fmt_len && !isspace(fmt.charAt(f)))
					f++;
			break;

		case 'Z':
			// Not fully supported yet!
			{
			var cp;
			var zonestr;

			for (cp = b; cp < buf_len && isupper(buf.charAt(cp)); ++cp) {/*empty*/}
			if (cp - b) {
				zonestr = buf.substr(b, cp - b).toLocaleUpperCase();
				if (zonestr == "GMT") {
				    GMTp[0] = 1;
				}
				// ignore setting of daylight savings
				b += cp - b;
			}
			}
			break;
		}
	}
	return buf.substr(b);
}
/*
 * Confidential and Proprietary for Oracle Corporation
 *
 * This computer program contains valuable, confidential, and
 * proprietary information.  Disclosure, use, or reproduction
 * without the written authorization of Oracle is prohibited.
 * This unpublished work by Oracle is protected by the laws
 * of the United States and other countries.  If publication
 * of this computer program should occur, the following notice
 * shall apply:
 *
 * Copyright (c) 2006 Stellent, Inc.
 * All rights reserved.
 * Copyright (c) 2007-2008 Oracle Corp.
 * All rights reserved.
 *
 * $Id: puc.js 69187 2008-12-11 20:15:15Z rpetty $
 *
 * Source: puc.js
 * Requires: strftime.js, strptime.js
 */

var PUC =
{
	_REVISION: "$Rev: 69187 $",

	// configuration preferences (defaults)
	EnableOnSearch: true,
	EnableNavigator: true,
	UseMonthLocale: "long",
	UseWeekdayLocale: "medium",
	XOffset: 0,
	YOffset: 0,
	ZIndex: 0,

	// values overridden by pucLoadLocalizedDateStrings()
	DateFormat: "",
	TimeOffset: 0,

	// other globals
	calendars: {},
	has_yahoo: false,
	page_loaded: true,
	debug_alerts: false,
	debug_times: true
};

if (typeof(idc) != 'undefined')
{
	idc.PopUpCalendar = PUC;
}

if (typeof(YAHOO) != "undefined")
{
	PUC.has_yahoo = true;
}


/*
 *	Create a new PopUpCalendar.
 *	The caller is responsible for showing the calendar at the appropriate time.
 *  options = a mutable object containing the following options:
 *		id = unique ID for this calendar (unique across the current page).
 *		caption = title bar text or html for the popup window.
 *		defaultTime = (optional) override the default time setting
 *	element = date field element, whose .name property will be sync'd with the calendar.
 *	dom (optional) = DOM object to append to.  If undefined, HTML is written out instead.
 */
function pucCreateCalendar(options, element, dom)
{
	if (!PUC.has_yahoo)
	{
		if (PUC.debug_alerts)
		{
			alert("warning: YUI is missing; create calendar aborted");
		}
		return;
	}
	var cal = {};
	if (PUC.debug_times)
	{
		cal.time_create = new Date();
	}
	var id = xmlEncode(options.id);
	PUC.calendars[id] = cal;
	cal.options = options;
	cal.field = element;
	cal.didInit = false;
	cal.didRender = false;
	cal.id_calendar = "puc_calendar_" + id;
	cal.id_calendar_div = cal.id_calendar + "_div";
	cal.id_panel = "puc_panel_" + id;
	cal.id_panel_div = cal.id_panel + "_div";
	if ("string" == typeof(element))
	{
		cal.id_element = element;
		cal.field = document.getElementById(element);
	}
	else if (element)
	{
		cal.id_element = element.id;
		cal.field = element;
	}
	var HTML = "<div id=\"" + cal.id_panel_div + "\" style=\"display: none;\">\n" +
		"\t<div class=\"hd\">" + options.caption + "</div>\n" +
		"\t<div class=\"bd\">\n" +
		"\t\t<div id=\"" + cal.id_calendar_div + "\"></div>\n" +
		"\t</div>\n" +
		"</div>\n";
	if ("undefined" == typeof(dom))
	{
		document.write(HTML);
	}
	else
	{
		var div = document.createElement('div');
		div.innerHTML = HTML;
		dom.appendChild(div);
	}
	if (PUC.debug_times)
	{
		var timestamp = new Date();
		cal.time_create = timestamp.getTime() - cal.time_create.getTime();
	}
}

/*
 *  Initialize and render a pop-up calendar.
 *
 *  This can't be called until the corresponding DOM elements have been created.
 *  [This is only a problem in IE-- if I had a dime for every IE hack...]
 */
function pucRenderCalendar(cal)
{
	if (!PUC.has_yahoo)
	{
		if (PUC.debug_alerts)
		{
			alert("warning: YUI is missing; render calendar aborted");
		}
		return;
	}
	if (!cal.didInit)
	{
		if (PUC.debug_times)
		{
			cal.time_init = new Date();
		}
		// Setup the Calendar object.
		var config =
		{
			close: false,
			visible: true,
			SHOW_WEEKDAYS: true,
			HIDE_BLANK_WEEKS: true,
			SHOW_WEEK_HEADER: false,
			START_WEEKDAY: _time_locale["firstWeekday"],
			MULTI_SELECT: false,
			MONTHS_SHORT: _time_locale["mon"].slice(0, 12),
			MONTHS_LONG: _time_locale["month"].slice(0, 12),
			WEEKDAYS_1CHAR: _time_locale["wd1"].slice(0, 7),
			WEEKDAYS_SHORT: _time_locale["wd2"].slice(0, 7),
			WEEKDAYS_MEDIUM: _time_locale["wday"].slice(0, 7),
			WEEKDAYS_LONG: _time_locale["weekday"].slice(0, 7),
			LOCALE_MONTHS: PUC.UseMonthLocale,
			LOCALE_WEEKDAYS: PUC.UseWeekdayLocale
		};
		if (PUC.EnableNavigator)
		{
			config.navigator = { "strings": PUC.strings };
		}
		cal.calendar = new YAHOO.widget.Calendar(cal.id_calendar, cal.id_calendar_div, config);
		if (typeof(lcDirection) == 'string' && lcDirection == 'rtl')
		{
			cal.calendar.Style.CSS_NAV_LEFT = "calnavright";
			cal.calendar.Style.CSS_NAV_RIGHT = "calnavleft";
		}
		if (!cal.options.defaultTime)
		{
			cal.options.defaultTime = PUC.TimeOffset;
		}

		// Setup the Panel object.
		cal.panel = new YAHOO.widget.Panel(cal.id_panel_div,
		{
			visible: false,
			constraintoviewport: false,
			draggable: true,
			zIndex: PUC.ZIndex,
			close: true
		} );

		// Back pointers.
		cal.calendar.panel = cal.panel;
		cal.calendar.options = cal.options;
		cal.calendar.field = cal.field;
		cal.panel.options = cal.options;
		cal.panel.field = cal.field;

		if (PUC.XOffset || PUC.YOffset)
		{
			cal.panel.useXYOffsets = 1;
		}
		cal.didInit = true;
		cal.didRender = false;
		if (PUC.debug_times)
		{
			var timestamp = new Date();
			cal.time_init = timestamp.getTime() - cal.time_init.getTime();;
		}
	}

	if (!cal.didRender)
	{
		if (PUC.debug_times)
		{
			cal.time_render = new Date();
		}
		// The calendar is partly rerendered at each pucShowCalendar() invocation.
		cal.calendar.render();
		cal.calendar.selectEvent.subscribe(pucHandleSelect, cal.calendar);

		cal.panel.render();
		// Tell Panel it's contents have changed, to sync up things like the shadow.
		cal.calendar.renderEvent.subscribe(function()
			{
				cal.panel.fireEvent("changeContent");
			}
		);
		YAHOO.util.Dom.setStyle(cal.id_panel_div, 'display', 'block');
		cal.didRender = true;
		if (PUC.debug_times)
		{
			var timestamp = new Date();
			cal.time_render = timestamp.getTime() - cal.time_render.getTime();
		}
	}
}


/*
 *	Lookup/retrieve the calendar object.
 *
 *	id = unique ID for this calendar (unique across the current page).
 *
 *	returns: calendar object
 */
function pucGetCalendar(id)
{
	id = xmlEncode(id);
	return PUC.calendars[id];
}

/*
 *	Parse the Calendar's date field & show the PopUp.
 *
 *	id = unique ID for this calendar (unique across the current page).
 */
function pucShowCalendar(id)
{
	id = xmlEncode(id);
	var cal = pucGetCalendar(id);
	if (!PUC.didRender)
	{
		pucRenderCalendar(cal);
	}
	var calendar = cal.calendar;
	if (!calendar)
	{
		if (PUC.debug_alerts)
		{
			alert("warning: YUI is missing; show calendar aborted");
		}
		return;
	}
	if (PUC.debug_times)
	{
		cal.time_show = new Date();
	}
	var value = calendar.field.value;
	var date = new Date();
	calendar.isUserSelect = 0;
	calendar.deselectAll();
	if (value.length > 0)
	{
		strptime(value, PUC.DateFormat, date);
	}
	calendar.setYear(date.getFullYear());
	calendar.setMonth(date.getMonth());
	calendar.render();
	if (value.length > 0)
	{
		calendar.selectCell(calendar.getCellIndex(date));
	}
	// Only reposition the panels the first time they are shown
	if (cal.panel.useXYOffsets)
	{
		if (PUC.XOffset)
		{
			var x = cal.panel.cfg.getProperty("x");
			cal.panel.cfg.setProperty("x", x + PUC.XOffset);
		}
		if (PUC.YOffset)
		{
			var y = cal.panel.cfg.getProperty("y");
			cal.panel.cfg.setProperty("y", y + PUC.YOffset);
		}
		cal.panel.useXYOffsets = 0;
	}
	cal.panel.show();
	calendar.isUserSelect = 1;
	if (PUC.debug_times)
	{
		var timestamp = new Date();
		cal.time_show = timestamp.getTime() - cal.time_show.getTime();
	}
}

/*
 *	Hide the PopUp.
 *
 *	id = unique ID for this calendar (unique across the current page).
 */
function pucHideCalendar(id)
{
	var cal = pucGetCalendar(id);
	cal.panel.hide();
}

/*
 *  Toggle the PopUp's visibility.
 *
 *	id = unique ID for this calendar (unique across the current page).
 */
function pucToggleCalendar(id)
{
	if (!PUC.has_yahoo)
	{
		alert("PopUpCalendar is disabled because Yahoo user interface (yui) is not properly initialized.\n" +
			  "Ensure that the latest YahooUserInterfaceLibrary component is installed properly and\n" +
			  "perform a static publish (if available).");
		return;
	}
	var cal = pucGetCalendar(id);
	pucRenderCalendar(cal);
	var panel = cal.panel;
	if (!panel)
	{
		if (PUC.debug_alerts)
		{
			alert("This calendar has no panel, aborting toggle.");
		}
		return;
	}
	if (!panel.field)
	{
		alert("This calendar is not initialized: missing form element \"" + calendar.options.id_element + "\"");
		return;
	}
	var visible = panel.cfg.getProperty("visible");
	if (visible)
	{
		pucHideCalendar(id);
	}
	else
	{
		pucShowCalendar(id);
	}
}

/*
 *	Internal method used to copy the date out of the calendar into the field element.
 *
 *	type = event type name
 *	args = array of selection objects
 *	obj = the Calendar object
 */
function pucHandleSelect(type, args, obj)
{
	if (!obj.isUserSelect)
		return;
	obj.panel.hide();
	var selected = args[0];
	var date = obj._toDate(selected[0]);
	if (obj.options.defaultTime < 0)
	{
		var now = new Date();
		date.setHours(now.getHours());
		date.setMinutes(now.getMinutes());
		date.setSeconds(now.getSeconds());
	}
	else if (obj.options.defaultTime > 0)
	{
		var time = obj.options.defaultTime;
		date.setHours(time / 3600);
		date.setMinutes(time / 60 % 60);
		date.setSeconds(time % 60);
	}
	obj.field.value = strftime(PUC.DateFormat, date);

	if (obj.options.onchange)
	{
		obj.options.onchange(obj);
	}
}

