PageSourceSearch

https://www.corporal.cz/js/jquery.anytime.js

js corporal.cz collected 2026-10-06 13:15:25 UTC 134,614 bytes, 3,582 lines download raw bytes

1/*****************************************************************************
2 *  FILE:  anytime.js - The Any+Time(TM) JavaScript Library (source)
3 *
4 *  VERSION: 5.1.2
5 *
6 *  Copyright 2008-2015 Andrew M. Andrews III (www.AMA3.com). Some Rights
7 *  Reserved. This work licensed under the Creative Commons Attribution-
8 *  Noncommercial-Share Alike 3.0 Unported License except in jurisdicitons
9 *  for which the license has been ported by Creative Commons International,
10 *  where the work is licensed under the applicable ported license instead.
11 *  For a copy of the unported license, visit
12 *  http://creativecommons.org/licenses/by-nc-sa/3.0/
13 *  or send a letter to Creative Commons, 171 Second Street, Suite 300,
14 *  San Francisco, California, 94105, USA.  For ported versions of the
15 *  license, visit http://creativecommons.org/international/
16 *
17 *  Alternative licensing arrangements may be made by contacting the
18 *  author at http://www.AMA3.com/
19 *
20 *  The Any+Time(TM) JavaScript Library provides the following ECMAScript
21 *  functionality:
22 *
23 *    AnyTime.Converter
24 *      Converts Dates to/from Strings, allowing a wide range of formats
25 *      closely matching those provided by the MySQL DATE_FORMAT() function,
26 *      with some noteworthy enhancements.
27 *
28 *    AnyTime.pad()
29 *      Pads a value with a specific number of leading zeroes.
30 *
31 *    AnyTime.noPicker()
32 *      Destroys a calendar widget previously added by AnyTime.picker().
33 *      Can also be invoked via jQuery using $(selector).AnyTime_noPicker()
34 *
35 *    AnyTime.picker()
36 *      Attaches a calendar widget to a text field for selecting date/time
37 *      values with fewer mouse movements than most similar pickers.  Any
38 *      format supported by AnyTime.Converter can be used for the text field.
39 *      If JavaScript is disabled, the text field remains editable without
40 *      any of the picker features.
41 *      Can also be invoked via jQuery using $(selector).AnyTime_picker()
42 *
43 *  IMPORTANT NOTICE:  This code depends upon the jQuery JavaScript Library
44 *  (www.jquery.com); tested with version 1.11.0.
45 *
46 *  The Any+Time(TM) code and styles in anytime.css have been tested (but not
47 *  extensively) on the following Windows platforms:
48 *    IE 8 (XP)
49 *    IE 11 (8.1)
50 *    Firefox 26
51 *    Chrome 31
52 *
53 *  Any+Time is a trademark of Andrew M. Andrews III.
54 *  Thanks to Chu for help with a setMonth() issue!
55 ****************************************************************************/
56
57var AnyTime =
58{
59    version: '5.1.2',
60
61  	//=========================================================================
62  	//  AnyTime.pad() pads a value with a specified number of zeroes and
63    //  returns a string containing the padded value.
64  	//=========================================================================
65
66  	pad: function( val, len )
67  	{
68  		var str = String(Math.abs(val));
69  		while ( str.length < len )
70  		str = '0'+str;
71  		if ( val < 0 )
72  		str = '-'+str;
73  		return str;
74  	}
75};
76
77(function($)
78{
79	// private members
80
81	var __daysIn = [ 31,28,31,30,31,30,31,31,30,31,30,31 ];
82	var __initialized = false;
83  var __pickers = [];
84
85  	//  Add methods to jQuery to create and destroy pickers using
86  	//  the typical jQuery approach.
87
88  	$.fn.AnyTime_picker = function( options )
89  	{
90  		return this.each( function(i) { AnyTime.picker( this.id, options ); } );
91  	}
92
93  	$.fn.AnyTime_noPicker = function()
94  	{
95  		return this.each( function(i) { AnyTime.noPicker( this.id ); } );
96  	}
97
98  	//  Add methods to jQuery to change the current, earliest and latest times
99  	//  using the typical jQuery approach.
100
101  	$.fn.AnyTime_setCurrent = function( newTime )
102    {
103  		return this.each( function(i) { AnyTime.setCurrent( this.id, newTime ); } );
104    }
105
106  	$.fn.AnyTime_setEarliest = function( newTime )
107    {
108  		return this.each( function(i) { AnyTime.setEarliest( this.id, newTime ); } );
109    }
110
111  	$.fn.AnyTime_setLatest = function( newTime )
112    {
113  		return this.each( function(i) { AnyTime.setLatest( this.id, newTime ); } );
114    }
115
116  	// 	Add a method to jQuery to change the classes of an element to
117  	//  indicate whether it's value is current (used by AnyTime.picker),
118  	//  and another to trigger the click handler for the currently-
119  	//  selected button under an element.
120
121  	$.fn.AnyTime_current = function(isCurrent,isLegal)
122	{
123	    if ( isCurrent )
124	    {
125		  this.removeClass('AnyTime-out-btn ui-state-default ui-state-disabled ui-state-highlight');
126	      this.addClass('AnyTime-cur-btn ui-state-default ui-state-highlight');
127	    }
128	    else
129	    {
130	      this.removeClass('AnyTime-cur-btn ui-state-highlight');
131	      if ( ! isLegal )
132	    	  this.addClass('AnyTime-out-btn ui-state-disabled');
133	      else
134	    	  this.removeClass('AnyTime-out-btn ui-state-disabled');
135	    }
136	};
137
138	$.fn.AnyTime_clickCurrent = function()
139	{
140		this.find('.AnyTime-cur-btn').triggerHandler('click');
141	}
142
143  	$(document).ready(
144  		function()
145		{
146			//  Move popup windows to the end of the page.  This allows them to
147			//  overcome XHTML restrictions on <table> placement enforced by MSIE.
148
149			for ( var id in __pickers )
150        if ( ! Array.prototype[id] ) // prototype.js compatibility issue
151			    __pickers[id].onReady();
152
153			__initialized = true;
154
155		} ); // document.ready
156
157//=============================================================================
158//  AnyTime.Converter
159//
160//  This object converts between Date objects and Strings.
161//
162//  To use AnyTime.Converter, simply create an instance for a format string,
163//  and then (repeatedly) invoke the format() and/or parse() methods to
164//  perform the conversions.  For example:
165//
166//    var converter = new AnyTime.Converter({format:'%Y-%m-%d'})
167//    var datetime = converter.parse('1967-07-30') // July 30, 1967 @ 00:00
168//    alert( converter.format(datetime) ); // outputs: 1967-07-30
169//
170//  Constructor parameter:
171//
172//  options - an object of optional parameters that override default behaviors.
173//    The supported options are:
174//
175//    baseYear - the number to add to two-digit years if the %y format
176//      specifier is used.  By default, AnyTime.Converter follows the
177//      MySQL assumption that two-digit years are in the range 1970 to 2069
178//      (see http://dev.mysql.com/doc/refman/5.1/en/y2k-issues.html).
179//      The most common alternatives for baseYear are 1900 and 2000.
180//
181//    dayAbbreviations - an array of seven strings, indexed 0-6, to be used
182//      as ABBREVIATED day names.  If not specified, the following are used:
183//      ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
184//      Note that if the firstDOW option is passed to AnyTime.picker() (see
185//      AnyTime.picker()), this array should nonetheless begin with the
186//      desired abbreviation for Sunday.
187//
188//    dayNames - an array of seven strings, indexed 0-6, to be used as
189//      day names.  If not specified, the following are used: ['Sunday',
190//        'Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
191//      Note that if the firstDOW option is passed to AnyTime.picker() (see
192//      AnyTime.picker()), this array should nonetheless begin with the
193//      desired name for Sunday.
194//
195//    eraAbbreviations - an array of two strings, indexed 0-1, to be used
196//      as ABBREVIATED era names.  Item #0 is the abbreviation for "Before
197//      Common Era" (years before 0001, sometimes represented as negative
198//      years or "B.C"), while item #1 is the abbreviation for "Common Era"
199//      (years from 0001 to present, usually represented as unsigned years
200//      or years "A.D.").  If not specified, the following are used:
201//      ['BCE','CE']
202//
203//    format - a string specifying the pattern of strings involved in the
204//      conversion.  The parse() method can take a string in this format and
205//      convert it to a Date, and the format() method can take a Date object
206//      and convert it to a string matching the format.
207//
208//      Fields in the format string must match those for the DATE_FORMAT()
209//      function in MySQL, as defined here:
210//      http://tinyurl.com/bwd45#function_date-format
211//
212//      IMPORTANT:  Some MySQL specifiers are not supported (especially
213//      those involving day-of-the-year, week-of-the-year) or approximated.
214//      See the code for exact behavior.
215//
216//      In addition to the MySQL format specifiers, the following custom
217//      specifiers are also supported:
218//
219//        %B - If the year is before 0001, then the "Before Common Era"
220//          abbreviation (usually BCE or the obsolete BC) will go here.
221//
222//        %C - If the year is 0001 or later, then the "Common Era"
223//          abbreviation (usually CE or the obsolete AD) will go here.
224//
225//        %E - If the year is before 0001, then the "Before Common Era"
226//          abbreviation (usually BCE or the obsolete BC) will go here.
227//          Otherwise, the "Common Era" abbreviation (usually CE or the
228//          obsolete AD) will go here.
229//
230//        %Z - The current four-digit year, without any sign.  This is
231//          commonly used with years that might be before (or after) 0001,
232//          when the %E (or %B and %C) specifier is used instead of a sign.
233//          For example, 45 BCE is represented "0045".  By comparison, in
234//          the "%Y" format, 45 BCE is represented "-0045".
235//
236//        %z - The current year, without any sign, using only the necessary
237//          number of digits.  This if the year is commonly used with years
238//          that might be before (or after) 0001, when the %E (or %B and %C)
239//          specifier is used instead of a sign.  For example, the year
240//          45 BCE is represented as "45", and the year 312 CE as "312".
241//
242//        %# - the timezone offset, with a sign, in minutes.
243//
244//        %+ - the timezone offset, with a sign, in hours and minutes, in
245//          four-digit, 24-hour format with no delimiter (for example, +0530).
246//          To remember the difference between %+ and %-, it might be helpful
247//          to remember that %+ might have more characters than %-.
248//
249//        %: - the timezone offset, with a sign, in hours and minutes, in
250//          four-digit, 24-hour format with a colon delimiter (for example,
251//          +05:30).  This is similar to the %z format used by Java.
252//          To remember the difference between %: and %;, it might be helpful
253//          to remember that a colon (:) has a period (.) on the bottom and
254//          a semicolon (;) has a comma (,), and in English sentence structure,
255//          a period represents a more significant stop than a comma, and
256//          %: might be a longer string than %; (I know it's a stretch, but
257//          it's easier than looking it up every time)!
258//
259//        %- - the timezone offset, with a sign, in hours and minutes, in
260//          three-or-four-digit, 24-hour format with no delimiter (for
261//          example, +530).
262//
263//        %; - the timezone offset, with a sign, in hours and minutes, in
264//          three-or-four-digit, 24-hour format with a colon delimiter
265//          (for example, +5:30).
266//
267//        %@ - the timezone offset label.  By default, this will be the
268//          string "UTC" followed by the offset, with a sign, in hours and
269//          minutes, in four-digit, 24-hour format with a colon delimiter
270//          (for example, UTC+05:30).  However, if Any+Time(TM) has been
271//          extended with a member named utcLabel (for example, by the
272//          anytimetz.js file), then it is assumed to be an array of arrays,
273//          where the primary array is indexed by time zone offsets, and
274//          each sub-array contains a potential label for that offset.
275//          When parsing with %@, the array is scanned for matches to the
276//          input string, and if a match is found, the corresponding UTC
277//          offset is used.  When formatting, the array is scanned for a
278//          matching offset, and if one is found, the first member of the
279//          sub-array is used for output (unless overridden with
280//          utcFormatOffsetSubIndex or setUtcFormatOffsetSubIndex()).
281//          If the array does not exist, or does not contain a sub-array
282//          for the offset, then the default format is used.
283//
284//    monthAbbreviations - an array of twelve strings, indexed 0-6, to be
285//      used as ABBREVIATED month names.  If not specified, the following
286//      are used: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep',
287//        'Oct','Nov','Dec']
288//
289//    monthNames - an array of twelve strings, indexed 0-6, to be used as
290//      month names.  If not specified, the following are used:
291//      ['January','February','March','April','May','June','July',
292//        'August','September','October','November','December']
293//
294//    utcFormatOffsetAlleged - the offset from UTC, in minutes, to claim that
295//      a Date object represents during formatting, even though it is formatted
296//      using local time. Unlike utcFormatOffsetImposed, which actually
297//      converts the Date object to the specified different time zone, this
298//      option merely reports the alleged offset when a timezone specifier
299//      (%#, %+, %-, %:, %; %@) is encountered in the format string.
300//      This primarily exists so AnyTime.picker can edit the time as specified
301//      (without conversion to local time) and then convert the edited time to
302//      a different time zone (as selected using the picker).  Any initial
303//      value specified here can be changed by setUtcFormatOffsetAlleged().
304//      If a format offset is alleged, one cannot also be imposed (the imposed
305//      offset is ignored).
306//
307//    utcFormatOffsetImposed - the offset from UTC, in minutes, to specify when
308//      formatting a Date object.  By default, a Date is always formatted
309//      using the local time zone.
310//
311//    utcFormatOffsetSubIndex - when extending AnyTime with a utcLabel array
312//      (for example, by the anytimetz.js file), the specified sub-index is
313//      used to choose the Time Zone label for the UTC offset when formatting
314//      a Date object.  This primarily exists so AnyTime.picker can specify
315//      the label selected using the picker.  Any initial value specified here
316//      can be changed by setUtcFormatOffsetSubIndex().
317//
318//    utcParseOffsetAssumed - the offset from UTC, in minutes, to assume when
319//      parsing a String object.  By default, a Date is always parsed using the
320//      local time zone, unless the format string includes a timezone
321//      specifier (%#, %+, %-, %:, %; or %@), in which case the timezone
322//      specified in the string is used. The Date object created by parsing
323//      always represents local time regardless of the input time zone.
324//
325//    utcParseOffsetCapture - if true, any parsed string is always treated as
326//      though it represents local time, and any offset specified by the string
327//      (or utcParseOffsetAssume) is captured for return by the
328//      getUtcParseOffsetCaptured() method.  If the %@ format specifier is
329//      used, the sub-index of any matched label is also captured for return
330//      by the getUtcParseOffsetSubIndex() method.  This primarily exists so
331//      AnyTime.picker can edit the time as specified (without conversion to
332//      local time) and then convert the edited time to a different time zone
333//      (as selected using the picker).
334//=============================================================================
335
336AnyTime.Converter = function(options)
337{
338  	// private members
339
340  	var _flen = 0;
341	var _longDay = 9;
342	var _longMon = 9;
343	var _shortDay = 6;
344	var _shortMon = 3;
345	var _offAl = Number.MIN_VALUE; // format time zone offset alleged
346	var _offCap = Number.MIN_VALUE; // parsed time zone offset captured
347	var _offF = Number.MIN_VALUE; // format time zone offset imposed
348	var _offFSI = (-1); // format time zone label subindex
349	var _offP = Number.MIN_VALUE; // parsed time zone offset assumed
350	var _offPSI = (-1);        // parsed time zone label subindex captured
351	var _captureOffset = false;
352
353	// public members
354
355	this.fmt = '%Y-%m-%d %T';
356	this.dAbbr = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
357	this.dNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
358	this.eAbbr = ['BCE','CE'];
359	this.mAbbr = [ 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' ];
360	this.mNames = [ 'January','February','March','April','May','June','July','August','September','October','November','December' ];
361	this.baseYear = null;
362
363	//-------------------------------------------------------------------------
364	//  AnyTime.Converter.dAt() returns true if the character in str at pos
365	//  is a digit.
366	//-------------------------------------------------------------------------
367
368	this.dAt = function( str, pos )
369	{
370	    return ( (str.charCodeAt(pos)>='0'.charCodeAt(0)) &&
371	            (str.charCodeAt(pos)<='9'.charCodeAt(0)) );
372	};
373
374	//-------------------------------------------------------------------------
375	//  AnyTime.Converter.format() returns a String containing the value
376	//  of a specified Date object, using the format string passed to
377	//  AnyTime.Converter().
378	//
379	//  Method parameter:
380	//
381	//    date - the Date object to be converted
382	//-------------------------------------------------------------------------
383
384	this.format = function( date )
385	{
386		var d = new Date(date.getTime());
387		if ( ( _offAl == Number.MIN_VALUE ) && ( _offF != Number.MIN_VALUE ) )
388		  d.setTime( ( d.getTime() + (d.getTimezoneOffset()*60000) ) + (_offF*60000) );
389
390	    var t;
391	    var str = '';
392	    for ( var f = 0 ; f < _flen ; f++ )
393	    {
394	      if ( this.fmt.charAt(f) != '%' )
395	        str += this.fmt.charAt(f);
396	      else
397	      {
398	    	var ch = this.fmt.charAt(f+1)
399	        switch ( ch )
400	        {
401	          case 'a': // Abbreviated weekday name (Sun..Sat)
402	            str += this.dAbbr[ d.getDay() ];
403	            break;
404	          case 'B': // BCE string (eAbbr[0], usually BCE or BC, only if appropriate) (NON-MYSQL)
405	            if ( d.getFullYear() < 0 )
406	              str += this.eAbbr[0];
407	            break;
408	          case 'b': // Abbreviated month name (Jan..Dec)
409	            str += this.mAbbr[ d.getMonth() ];
410	            break;
411	          case 'C': // CE string (eAbbr[1], usually CE or AD, only if appropriate) (NON-MYSQL)
412	            if ( d.getFullYear() > 0 )
413	              str += this.eAbbr[1];
414	            break;
415	          case 'c': // Month, numeric (0..12)
416	            str += d.getMonth()+1;
417	            break;
418	          case 'd': // Day of the month, numeric (00..31)
419	            t = d.getDate();
420	            if ( t < 10 ) str += '0';
421	            str += String(t);
422	            break;
423	          case 'D': // Day of the month with English suffix (0th, 1st,...)
424	            t = String(d.getDate());
425	            str += t;
426	            if ( ( t.length == 2 ) && ( t.charAt(0) == '1' ) )
427	              str += 'th';
428	            else
429	            {
430	              switch ( t.charAt( t.length-1 ) )
431	              {
432	                case '1': str += 'st'; break;
433	                case '2': str += 'nd'; break;
434	                case '3': str += 'rd'; break;
435	                default: str += 'th'; break;
436	              }
437	            }
438	            break;
439	          case 'E': // era string (from eAbbr[], BCE, CE, BC or AD) (NON-MYSQL)
440	            str += this.eAbbr[ (d.getFullYear()<0) ? 0 : 1 ];
441	            break;
442	          case 'e': // Day of the month, numeric (0..31)
443	            str += d.getDate();
444	            break;
445	          case 'H': // Hour (00..23)
446	            t = d.getHours();
447	            if ( t < 10 ) str += '0';
448	            str += String(t);
449	            break;
450	          case 'h': // Hour (01..12)
451	          case 'I': // Hour (01..12)
452	            t = d.getHours() % 12;
453	            if ( t == 0 )
454	              str += '12';
455	            else
456	            {
457	              if ( t < 10 ) str += '0';
458	              str += String(t);
459	            }
460	            break;
461	          case 'i': // Minutes, numeric (00..59)
462	            t = d.getMinutes();
463	            if ( t < 10 ) str += '0';
464	            str += String(t);
465	            break;
466	          case 'k': // Hour (0..23)
467	            str += d.getHours();
468	            break;
469	          case 'l': // Hour (1..12)
470	            t = d.getHours() % 12;
471	            if ( t == 0 )
472	              str += '12';
473	            else
474	              str += String(t);
475	            break;
476	          case 'M': // Month name (January..December)
477	            str += this.mNames[ d.getMonth() ];
478	            break;
479	          case 'm': // Month, numeric (00..12)
480	            t = d.getMonth() + 1;
481	            if ( t < 10 ) str += '0';
482	            str += String(t);
483	            break;
484	          case 'p': // AM or PM
485	            str += ( ( d.getHours() < 12 ) ? 'AM' : 'PM' );
486	            break;
487	          case 'r': // Time, 12-hour (hh:mm:ss followed by AM or PM)
488	            t = d.getHours() % 12;
489	            if ( t == 0 )
490	              str += '12:';
491	            else
492	            {
493	              if ( t < 10 ) str += '0';
494	              str += String(t) + ':';
495	            }
496	            t = d.getMinutes();
497	            if ( t < 10 ) str += '0';
498	            str += String(t) + ':';
499	            t = d.getSeconds();
500	            if ( t < 10 ) str += '0';
501	            str += String(t);
502	            str += ( ( d.getHours() < 12 ) ? 'AM' : 'PM' );
503	            break;
504	          case 'S': // Seconds (00..59)
505	          case 's': // Seconds (00..59)
506	            t = d.getSeconds();
507	            if ( t < 10 ) str += '0';
508	            str += String(t);
509	            break;
510	          case 'T': // Time, 24-hour (hh:mm:ss)
511	            t = d.getHours();
512	            if ( t < 10 ) str += '0';
513	            str += String(t) + ':';
514	            t = d.getMinutes();
515	            if ( t < 10 ) str += '0';
516	            str += String(t) + ':';
517	            t = d.getSeconds();
518	            if ( t < 10 ) str += '0';
519	            str += String(t);
520	            break;
521	          case 'W': // Weekday name (Sunday..Saturday)
522	            str += this.dNames[ d.getDay() ];
523	            break;
524	          case 'w': // Day of the week (0=Sunday..6=Saturday)
525	            str += d.getDay();
526	            break;
527	          case 'Y': // Year, numeric, four digits (negative if before 0001)
528	            str += AnyTime.pad(d.getFullYear(),4);
529	            break;
530	          case 'y': // Year, numeric (two digits, negative if before 0001)
531	            t = d.getFullYear() % 100;
532	            str += AnyTime.pad(t,2);
533	            break;
534	          case 'Z': // Year, numeric, four digits, unsigned (NON-MYSQL)
535	            str += AnyTime.pad(Math.abs(d.getFullYear()),4);
536	            break;
537	          case 'z': // Year, numeric, variable length, unsigned (NON-MYSQL)
538	            str += Math.abs(d.getFullYear());
539	            break;
540	          case '%': // A literal '%' character
541	            str += '%';
542	            break;
543	          case '#': // signed timezone offset in minutes
544	        	t = ( _offAl != Number.MIN_VALUE ) ? _offAl :
545	        		( _offF == Number.MIN_VALUE ) ? (0-d.getTimezoneOffset()) : _offF;
546	        	if ( t >= 0 )
547	        		str += '+';
548	        	str += t;
549	        	break;
550	          case '@': // timezone offset label
551		        t = ( _offAl != Number.MIN_VALUE ) ? _offAl :
552		        	( _offF == Number.MIN_VALUE ) ? (0-d.getTimezoneOffset()) : _offF;
553		        if ( AnyTime.utcLabel && AnyTime.utcLabel[t] )
554		        {
555		          if ( ( _offFSI > 0 ) && ( _offFSI < AnyTime.utcLabel[t].length ) )
556		            str += AnyTime.utcLabel[t][_offFSI];
557		          else
558		            str += AnyTime.utcLabel[t][0];
559		          break;
560		        }
561		        str += 'UTC';
562		        ch = ':'; // drop through for offset formatting
563	          case '+': // signed, 4-digit timezone offset in hours and minutes
564	          case '-': // signed, 3-or-4-digit timezone offset in hours and minutes
565	          case ':': // signed 4-digit timezone offset with colon delimiter
566	          case ';': // signed 3-or-4-digit timezone offset with colon delimiter
567		        t = ( _offAl != Number.MIN_VALUE ) ? _offAl :
568		        		( _offF == Number.MIN_VALUE ) ? (0-d.getTimezoneOffset()) : _offF;
569		        if ( t < 0 )
570		          str += '-';
571		        else
572		          str += '+';
573		        t = Math.abs(t);
574		        str += ((ch=='+')||(ch==':')) ? AnyTime.pad(Math.floor(t/60),2) : Math.floor(t/60);
575		        if ( (ch==':') || (ch==';') )
576		          str += ':';
577		        str += AnyTime.pad(t%60,2);
578		        break;
579	          case 'f': // Microseconds (000000..999999)
580	          case 'j': // Day of year (001..366)
581	          case 'U': // Week (00..53), where Sunday is the first day of the week
582	          case 'u': // Week (00..53), where Monday is the first day of the week
583	          case 'V': // Week (01..53), where Sunday is the first day of the week; used with %X
584	          case 'v': // Week (01..53), where Monday is the first day of the week; used with %x
585	          case 'X': // Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
586	          case 'x': // Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v
587	            throw '%'+ch+' not implemented by AnyTime.Converter';
588	          default: // for any character not listed above
589	            str += this.fmt.substr(f,2);
590	        } // switch ( this.fmt.charAt(f+1) )
591	        f++;
592	      } // else
593	    } // for ( var f = 0 ; f < _flen ; f++ )
594	    return str;
595
596	}; // AnyTime.Converter.format()
597
598	//-------------------------------------------------------------------------
599	//  AnyTime.Converter.getUtcParseOffsetCaptured() returns the UTC offset
600	//  last captured by a parsed string (or assumed by utcParseOffsetAssumed).
601	//  It returns Number.MIN_VALUE if this object was not constructed with
602	//  the utcParseOffsetCapture option set to true, or if an offset was not
603	//  specified by the last parsed string or utcParseOffsetAssumed.
604	//-------------------------------------------------------------------------
605
606	this.getUtcParseOffsetCaptured = function()
607	{
608	    return _offCap;
609	};
610
611	//-------------------------------------------------------------------------
612	//  AnyTime.Converter.getUtcParseOffsetCaptured() returns the UTC offset
613	//  last captured by a parsed string (or assumed by utcParseOffsetAssumed).
614	//  It returns Number.MIN_VALUE if this object was not constructed with
615	//  the utcParseOffsetCapture option set to true, or if an offset was not
616	//  specified by the last parsed string or utcParseOffsetAssumed.
617	//-------------------------------------------------------------------------
618
619	this.getUtcParseOffsetSubIndex = function()
620	{
621	    return _offPSI;
622	};
623
624	//-------------------------------------------------------------------------
625	//  AnyTime.Converter.parse() returns a Date initialized from a specified
626	//  string, using the format passed to AnyTime.Converter().
627	//
628	//  Method parameter:
629	//
630	//    str - the String object to be converted
631	//-------------------------------------------------------------------------
632
633	this.parse = function( str )
634	{
635		_offCap = _offP;
636		_offPSI = (-1);
637	    var era = 1;
638      var time = new Date(4,0,1,0,0,0,0);//4=leap year bug
639	    var slen = str.length;
640	    var s = 0;
641	    var tzSign = 1, tzOff = _offP;
642	    var i, matched, sub, sublen, temp;
643	    for ( var f = 0 ; f < _flen ; f++ )
644	    {
645	      if ( this.fmt.charAt(f) == '%' )
646	      {
647			var ch = this.fmt.charAt(f+1);
648	        switch ( ch )
649	        {
650	          case 'a': // Abbreviated weekday name (Sun..Sat)
651	            matched = false;
652	            for ( sublen = 0 ; s + sublen < slen ; sublen++ )
653	            {
654	              sub = str.substr(s,sublen);
655	              for ( i = 0 ; i < 12 ; i++ )
656	                if ( this.dAbbr[i] == sub )
657	                {
658	                  matched = true;
659	                  s += sublen;
660	                  break;
661	                }
662	              if ( matched )
663	                break;
664	            } // for ( sublen ... )
665	            if ( ! matched )
666	              throw 'unknown weekday: '+str.substr(s);
667	            break;
668	          case 'B': // BCE string (eAbbr[0]), only if needed. (NON-MYSQL)
669	            sublen = this.eAbbr[0].length;
670	            if ( ( s + sublen <= slen ) && ( str.substr(s,sublen) == this.eAbbr[0] ) )
671	            {
672	              era = (-1);
673	              s += sublen;
674	            }
675	            break;
676	          case 'b': // Abbreviated month name (Jan..Dec)
677	            matched = false;
678	            for ( sublen = 0 ; s + sublen < slen ; sublen++ )
679	            {
680	              sub = str.substr(s,sublen);
681	              for ( i = 0 ; i < 12 ; i++ )
682	                if ( this.mAbbr[i] == sub )
683	                {
684	                  time.setMonth( i );
685	                  matched = true;
686	                  s += sublen;
687	                  break;
688	                }
689	              if ( matched )
690	                break;
691	            } // for ( sublen ... )
692	            if ( ! matched )
693	              throw 'unknown month: '+str.substr(s);
694	            break;
695	          case 'C': // CE string (eAbbr[1]), only if needed. (NON-MYSQL)
696	            sublen = this.eAbbr[1].length;
697	            if ( ( s + sublen <= slen ) && ( str.substr(s,sublen) == this.eAbbr[1] ) )
698	              s += sublen;
698 // note: CE is the default era
699	            break;
700	          case 'c': // Month, numeric (0..12)
701	            if ( ( s+1 < slen ) && this.dAt(str,s+1) )
702	            {
703	              time.setMonth( (Number(str.substr(s,2))-1)%12 );
704	              s += 2;
705	            }
706	            else
707	            {
708	              time.setMonth( (Number(str.substr(s,1))-1)%12 );
709	              s++;
710	            }
711	            break;
712	          case 'D': // Day of the month with English suffix (0th,1st,...)
713	            if ( ( s+1 < slen ) && this.dAt(str,s+1) )
714	            {
715	              time.setDate( Number(str.substr(s,2)) );
716	              s += 4;
717	            }
718	            else
719	            {
720	              time.setDate( Number(str.substr(s,1)) );
721	              s += 3;
722	            }
723	            break;
724	          case 'd': // Day of the month, numeric (00..31)
725	            time.setDate( Number(str.substr(s,2)) );
726	            s += 2;
727	            break;
728	          case 'E': // era string (from eAbbr[]) (NON-MYSQL)
729	            sublen = this.eAbbr[0].length;
730	            if ( ( s + sublen <= slen ) && ( str.substr(s,sublen) == this.eAbbr[0] ) )
731	            {
732	              era = (-1);
733	              s += sublen;
734	            }
735	            else if ( ( s + ( sublen = this.eAbbr[1].length ) <= slen ) && ( str.substr(s,sublen) == this.eAbbr[1] ) )
736	              s += sublen;
736 // note: CE is the default era
737	            else
738	              throw 'unknown era: '+str.substr(s);
739	            break;
740	          case 'e': // Day of the month, numeric (0..31)
741	            if ( ( s+1 < slen ) && this.dAt(str,s+1) )
742	            {
743	              time.setDate( Number(str.substr(s,2)) );
744	              s += 2;
745	            }
746	            else
747	            {
748	              time.setDate( Number(str.substr(s,1)) );
749	              s++;
750	            }
751	            break;
752	          case 'f': // Microseconds (000000..999999)
753	            s += 6; // SKIPPED!
754	            break;
755	          case 'H': // Hour (00..23)
756	            time.setHours( Number(str.substr(s,2)) );
757	            s += 2;
758	            break;
759	          case 'h': // Hour (01..12)
760	          case 'I': // Hour (01..12)
761	            time.setHours( Number(str.substr(s,2)) );
762	            s += 2;
763	            break;
764	          case 'i': // Minutes, numeric (00..59)
765	            time.setMinutes( Number(str.substr(s,2)) );
766	            s += 2;
767	            break;
768	          case 'k': // Hour (0..23)
769	            if ( ( s+1 < slen ) && this.dAt(str,s+1) )
770	            {
771	              time.setHours( Number(str.substr(s,2)) );
772	              s += 2;
773	            }
774	            else
775	            {
776	              time.setHours( Number(str.substr(s,1)) );
777	              s++;
778	            }
779	            break;
780	          case 'l': // Hour (1..12)
781	            if ( ( s+1 < slen ) && this.dAt(str,s+1) )
782	            {
783	              time.setHours( Number(str.substr(s,2)) );
784	              s += 2;
785	            }
786	            else
787	            {
788	              time.setHours( Number(str.substr(s,1)) );
789	              s++;
790	            }
791	            break;
792	          case 'M': // Month name (January..December)
793	            matched = false;
794	            for (sublen=_shortMon ; s + sublen <= slen ; sublen++ )
795	            {
796	              if ( sublen > _longMon )
797	                break;
798	              sub = str.substr(s,sublen);
799	              for ( i = 0 ; i < 12 ; i++ )
800	              {
801	                if ( this.mNames[i] == sub )
802	                {
803	                  time.setMonth( i );
804	                  matched = true;
805	                  s += sublen;
806	                  break;
807	                }
808	              }
809	              if ( matched )
810	                break;
811	            }
812	            break;
813	          case 'm': // Month, numeric (00..12)
814	            time.setMonth( (Number(str.substr(s,2))-1)%12 );
815	            s += 2;
816	            break;
817	          case 'p': // AM or PM
818              if ( time.getHours() == 12 )
819              {
820	              if ( str.charAt(s) == 'A' )
821	                time.setHours(0);
822              }
823              else if ( str.charAt(s) == 'P' )
824	              time.setHours( time.getHours() + 12 );
825	            s += 2;
826	            break;
827	          case 'r': // Time, 12-hour (hh:mm:ss followed by AM or PM)
828	            time.setHours(Number(str.substr(s,2)));
829	            time.setMinutes(Number(str.substr(s+3,2)));
830	            time.setSeconds(Number(str.substr(s+6,2)));
831              if ( time.getHours() == 12 )
832              {
833	              if ( str.charAt(s+8) == 'A' )
834	                time.setHours(0);
835              }
836              else if ( str.charAt(s+8) == 'P' )
837	              time.setHours( time.getHours() + 12 );
838	            s += 10;
839	            break;
840	          case 'S': // Seconds (00..59)
841	          case 's': // Seconds (00..59)
842	            time.setSeconds(Number(str.substr(s,2)));
843	            s += 2;
844	            break;
845	          case 'T': // Time, 24-hour (hh:mm:ss)
846	            time.setHours(Number(str.substr(s,2)));
847	            time.setMinutes(Number(str.substr(s+3,2)));
848	            time.setSeconds(Number(str.substr(s+6,2)));
849	            s += 8;
850	            break;
851	          case 'W': // Weekday name (Sunday..Saturday)
852	            matched = false;
853	            for (sublen=_shortDay ; s + sublen <= slen ; sublen++ )
854	            {
855	              if ( sublen > _longDay )
856	                break;
857	              sub = str.substr(s,sublen);
858	              for ( i = 0 ; i < 7 ; i++ )
859	              {
860	                if ( this.dNames[i] == sub )
861	                {
862	                  matched = true;
863	                  s += sublen;
864	                  break;
865	                }
866	              }
867	              if ( matched )
868	                break;
869	            }
870	            break;
871            case 'w': // Day of the week (0=Sunday..6=Saturday) (ignored)
872              s += 1;
873              break;
874	          case 'Y': // Year, numeric, four digits, negative if before 0001
875	            i = 4;
876	            if ( str.substr(s,1) == '-' )
877	              i++;
878	            time.setFullYear(Number(str.substr(s,i)));
879	            s += i;
880	            break;
881	          case 'y': // Year, numeric (two digits), negative before baseYear
882	            i = 2;
883	            if ( str.substr(s,1) == '-' )
884	              i++;
885	            temp = Number(str.substr(s,i));
886	            if ( typeof(this.baseYear) == 'number' )
887	            	temp += this.baseYear;
888	            else if ( temp < 70 )
889	            	temp += 2000;
890	            else
891	            	temp += 1900;
892	            time.setFullYear(temp);
893	            s += i;
894	            break;
895	          case 'Z': // Year, numeric, four digits, unsigned (NON-MYSQL)
896	            time.setFullYear(Number(str.substr(s,4)));
897	            s += 4;
898	            break;
899	          case 'z': // Year, numeric, variable length, unsigned (NON-MYSQL)
900	            i = 0;
901	            while ( ( s < slen ) && this.dAt(str,s) )
902	              i = ( i * 10 ) + Number(str.charAt(s++));
903	            time.setFullYear(i);
904	            break;
905	          case '#': // signed timezone offset in minutes.
906	            if ( str.charAt(s++) == '-' )
907	            	tzSign = (-1);
908	            for ( tzOff = 0 ; ( s < slen ) && (String(i=Number(str.charAt(s)))==str.charAt(s)) ; s++ )
909	            	tzOff = ( tzOff * 10 ) + i;
910	            tzOff *= tzSign;
911	            break;
912	          case '@': // timezone label
913	        	_offPSI = (-1);
914	        	if ( AnyTime.utcLabel )
915	        	{
916		            matched = false;
917		            for ( tzOff in AnyTime.utcLabel )
918                  if ( ! Array.prototype[tzOff] ) // prototype.js compatibility issue
919		              {
920		            	  for ( i = 0 ; i < AnyTime.utcLabel[tzOff].length ; i++ )
921  		            	{
922	  	            		sub = AnyTime.utcLabel[tzOff][i];
923		              		sublen = sub.length;
924		              		if ( ( s+sublen <= slen ) && ( str.substr(s,sublen) == sub ) )
925		              		{
926                        s+=sublen;
927		              			matched = true;
928		              			break;
929		              		}
930		              	}
931	            		  if ( matched )
932	            			  break;
933		              }
934		            if ( matched )
935		            {
936		            	_offPSI = i;
937		            	tzOff = Number(tzOff);
938		            	break; // case
939		            }
940	        	}
941	        	if ( ( s+9 < slen ) || ( str.substr(s,3) != "UTC" ) )
942                    throw 'unknown time zone: '+str.substr(s);
943	        	s += 3;
944	            ch = ':'; // drop through for offset parsing
945	          case '-': // signed, 3-or-4-digit timezone offset in hours and minutes
946	          case '+': // signed, 4-digit timezone offset in hours and minutes
947	          case ':': // signed 4-digit timezone offset with colon delimiter
948	          case ';': // signed 3-or-4-digit timezone offset with colon delimiter
949	            if ( str.charAt(s++) == '-' )
950	            	tzSign = (-1);
951	            tzOff = Number(str.charAt(s));
952	            if ( (ch=='+')||(ch==':')||((s+3<slen)&&(String(Number(str.charAt(s+3)))!==str.charAt(s+3))) )
953	            	tzOff = (tzOff*10) + Number(str.charAt(++s));
954                tzOff *= 60;
955	        	if ( (ch==':') || (ch==';') )
956	        		s++;
956 // skip ":" (assumed)
957	        	tzOff = ( tzOff + Number(str.substr(++s,2)) ) * tzSign;
958	        	s += 2;
959		        break;
960	          case 'j': // Day of year (001..366)
961	          case 'U': // Week (00..53), where Sunday is the first day of the week
962	          case 'u': // Week (00..53), where Monday is the first day of the week
963	          case 'V': // Week (01..53), where Sunday is the first day of the week; used with %X
964	          case 'v': // Week (01..53), where Monday is the first day of the week; used with %x
965	          case 'X': // Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
966	          case 'x': // Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v
967	            throw '%'+this.fmt.charAt(f+1)+' not implemented by AnyTime.Converter';
968	          case '%': // A literal '%' character
969	          default: // for any character not listed above
970		        throw '%'+this.fmt.charAt(f+1)+' reserved for future use';
971	            break;
972	        }
973	        f++;
974	      } // if ( this.fmt.charAt(f) == '%' )
975	      else if ( this.fmt.charAt(f) != str.charAt(s) )
976	        throw str + ' is not in "' + this.fmt + '" format';
977	      else
978	        s++;
979	    } // for ( var f ... )
980	    if ( era < 0 )
981	      time.setFullYear( 0 - time.getFullYear() );
982		if ( tzOff != Number.MIN_VALUE )
983		{
984	       if ( _captureOffset )
985	    	 _offCap = tzOff;
986	       else
987	    	 time.setTime( ( time.getTime() - (tzOff*60000) ) - (time.getTimezoneOffset()*60000) );
988		}
989
990	    return time;
991
992	}; // AnyTime.Converter.parse()
993
994	//-------------------------------------------------------------------------
995	//  AnyTime.Converter.setUtcFormatOffsetAlleged()  sets the offset from
996    //  UTC, in minutes, to claim that a Date object represents during
997	//  formatting, even though it is formatted using local time.  This merely
998	//  reports the alleged offset when a timezone specifier (%#, %+, %-, %:,
999	//  %; or %@) is encountered in the format string--it does not otherwise
1000	//  affect the date/time value.  This primarily exists so AnyTime.picker
1001	//  can edit the time as specified (without conversion to local time) and
1002	//  then convert the edited time to a different time zone (as selected
1003	//  using the picker).  This method returns the previous value, if any,
1004	//  set by the utcFormatOffsetAlleged option, or a previous call to
1005	//  setUtcFormatOffsetAlleged(), or Number.MIN_VALUE if no offset was
1006	//  previously-alleged.  Call this method with Number.MIN_VALUE to cancel
1007	//  any prior value.  Note that if a format offset is alleged, any offset
1008	//  specified by option utcFormatOffsetImposed is ignored.
1009	//-------------------------------------------------------------------------
1010
1011	this.setUtcFormatOffsetAlleged = function( offset )
1012	{
1013		var prev = _offAl;
1014	    _offAl = offset;
1015	    return prev;
1016	};
1017
1018	//-------------------------------------------------------------------------
1019	//  AnyTime.Converter.setUtcFormatOffsetSubIndex() sets the sub-index
1020	//  to choose from the AnyTime.utcLabel array of arrays when formatting
1021	//  a Date using the %@ specifier.  For more information, see option
1022	//  AnyTime.Converter.utcFormatOffsetSubIndex.  This primarily exists so
1023	//  AnyTime.picker can specify the Time Zone label selected using the
1024	//  picker).  This method returns the previous value, if any, set by the
1025	//  utcFormatOffsetSubIndex option, or a previous call to
1026	//  setUtcFormatOffsetAlleged(), or (-1) if no sub-index was previously-
1027	//  chosen.  Call this method with (-1) to cancel any prior value.
1028	//-------------------------------------------------------------------------
1029
1030	this.setUtcFormatOffsetSubIndex = function( subIndex )
1031	{
1032		var prev = _offFSI;
1033	    _offFSI = subIndex;
1034	    return prev;
1035	};
1036
1037	//-------------------------------------------------------------------------
1038	//	AnyTime.Converter construction code:
1039	//-------------------------------------------------------------------------
1040
1041	(function(_this)
1042	{
1043      var i, len;
1044
1045		options = jQuery.extend(true,{},options||{});
1046
1047	  	if ( options.baseYear )
1048			_this.baseYear = Number(options.baseYear);
1049
1050	  	if ( options.format )
1051			_this.fmt = options.format;
1052
1053	  	_flen = _this.fmt.length;
1054
1055	  	if ( options.dayAbbreviations )
1056	  		_this.dAbbr = $.makeArray( options.dayAbbreviations );
1057
1058	  	if ( options.dayNames )
1059	  	{
1060	  		_this.dNames = $.makeArray( options.dayNames );
1061	  		_longDay = 1;
1062	  		_shortDay = 1000;
1063	  		for ( i = 0 ; i < 7 ; i++ )
1064	  		{
1065          len = _this.dNames[i].length;
1066				if ( len > _longDay )
1067					_longDay = len;
1068				if ( len < _shortDay )
1069					_shortDay = len;
1070	  		}
1071	  	}
1072
1073	  	if ( options.eraAbbreviations )
1074	  		_this.eAbbr = $.makeArray(options.eraAbbreviations);
1075
1076	  	if ( options.monthAbbreviations )
1077	  		_this.mAbbr = $.makeArray(options.monthAbbreviations);
1078
1079	  	if ( options.monthNames )
1080	  	{
1081	  		_this.mNames = $.makeArray( options.monthNames );
1082	  		_longMon = 1;
1083	  		_shortMon = 1000;
1084	  		for ( i = 0 ; i < 12 ; i++ )
1085	  		{
1086	  			len = _this.mNames[i].length;
1087	  			if ( len > _longMon )
1088					_longMon = len;
1089	  			if ( len < _shortMon )
1090	  				_shortMon = len;
1091	  		}
1092	  	}
1093
1094	  	if ( typeof options.utcFormatOffsetImposed != "undefined" )
1095	  		_offF = options.utcFormatOffsetImposed;
1096
1097	  	if ( typeof options.utcParseOffsetAssumed != "undefined" )
1098	  		_offP = options.utcParseOffsetAssumed;
1099
1100	  	if ( options.utcParseOffsetCapture )
1101	  		_captureOffset = true;
1102
1103	})(this); // AnyTime.Converter construction
1104
1105}; // AnyTime.Converter =
1106
1107//=============================================================================
1108//  AnyTime.noPicker()
1109//
1110//  Removes the date/time entry picker attached to a specified text field.
1111//=============================================================================
1112
1113AnyTime.noPicker = function( id )
1114{
1115	if ( __pickers[id] )
1116	{
1117		__pickers[id].cleanup();
1118		delete __pickers[id];
1119	}
1120};
1121
1122//=============================================================================
1123//  AnyTime.picker()
1124//
1125//  Creates a date/time entry picker attached to a specified text field.
1126//  Instead of entering a date and/or time into the text field, the user
1127//  selects legal combinations using the picker, and the field is auto-
1128//  matically populated.  The picker can be incorporated into the page
1129//	"inline", or used as a "popup" that appears when the text field is
1130//  clicked and disappears when the picker is dismissed. Ajax can be used
1131//  to send the selected value to a server to approve or veto it.
1132//
1133//  To create a picker, simply include the necessary files in an HTML page
1134//  and call the function for each date/time input field.  The following
1135//  example creates a popup picker for field "foo" using the default
1136//  format, and a second date-only (no time) inline (always-visible)
1137//  Ajax-enabled picker for field "bar":
1138//
1139//    <link rel="stylesheet" type="text/css" href="anytime.css" />
1140//    <script type="text/javascript" src="jquery.js"></script>
1141//    <script type="text/javascript" src="anytime.js"></script>
1142//    <input type="text" id="foo" tabindex="1" value="1967-07-30 23:45" />
1143//    <input type="text" id="bar" tabindex="2" value="01/06/90" />
1144//    <script type="text/javascript">
1145//      AnyTime.picker( "foo" );
1146//      AnyTime.picker( "bar", { placement:"inline", format: "%m/%d/%y",
1147//								ajaxOptions { url: "/some/server/page/" } } );
1148//    </script>
1149//
1150//  The appearance of the picker can be extensively modified using CSS styles.
1151//  A default appearance can be achieved by the "anytime.css" stylesheet that
1152//  accompanies this script.
1153//
1154//  Method parameters:
1155//
1156//  id - the "id" attribute of the textfield to associate with the
1157//    AnyTime.picker object.  The AnyTime.picker will attach itself
1158//    to the textfield and manage its value.
1159//
1160//  options - an object (associative array) of optional parameters that
1161//    override default behaviors.  The supported options are:
1162//
1163//    ajaxOptions - options passed to jQuery's $.ajax() method whenever
1164//      the user dismisses a popup picker or selects a value in an inline
1165//      picker.  The input's name (or ID) and value are passed to the
1166//      server (appended to ajaxOptions.data, if present), and the
1167//      "success" handler sets the input's value to the responseText.
1168//      Therefore, the text returned by the server must be valid for the
1169//      input'sdate/time format, and the server can approve or veto the
1170//      value chosen by the user. For more information, see:
1171//      http://docs.jquery.com/Ajax.
1172//      If ajaxOptions.success is specified, it is used instead of the
1173//      default "success" behavior.
1174//
1175//    askEra - if true, buttons to select the era are shown on the year
1176//        selector popup, even if format specifier does not include the
1177//        era.  If false, buttons to select the era are NOT shown, even
1178//        if the format specifier includes ther era.  Normally, era buttons
1179//        are only shown if the format string specifies the era.
1180//
1181//    askSecond - if false, buttons for number-of-seconds are not shown
1182//        even if the format includes seconds.  Normally, the buttons
1183//        are shown if the format string includes seconds.
1184//
1185//    earliest - String or Date object representing the earliest date/time
1186//        that a user can select.  For best results if the field is only
1187//        used to specify a date, be sure to set the time to 00:00:00.
1188//        If a String is used, it will be parsed according to the picker's
1189//        format (see AnyTime.Converter.format()).
1190//
1191//    firstDOW - a value from 0 (Sunday) to 6 (Saturday) stating which
1192//      day should appear at the beginning of the week.  The default is 0
1193//      (Sunday).  The most common substitution is 1 (Monday).  Note that
1194//      if custom arrays are specified for AnyTime.Converter's dayAbbreviations
1195//      and/or dayNames options, they should nonetheless begin with the
1196//      value for Sunday.
1197//
1198//    hideInput - if true, the <input> is "hidden" (the picker appears in
1199//      its place). This actually sets the border, height, margin, padding
1200//      and width of the field as small as possivle, so it can still get focus.
1201//      If you try to hide the field using traditional techniques (such as
1202//      setting "display:none"), the picker will not behave correctly.
1203//
1204//    labelDayOfMonth - the label for the day-of-month "buttons".
1205//      Can be any HTML!  If not specified, "Day of Month" is assumed.
1206//
1207//    labelDismiss - the label for the dismiss "button" (if placement is
1208//      "popup"). Can be any HTML!  If not specified, "X" is assumed.
1209//
1210//    labelHour - the label for the hour "buttons".
1211//      Can be any HTML!  If not specified, "Hour" is assumed.
1212//
1213//    labelMinute - the label for the minute "buttons".
1214//      Can be any HTML!  If not specified, "Minute" is assumed.
1215//
1216//    labelMonth - the label for the month "buttons".
1217//      Can be any HTML!  If not specified, "Month" is assumed.
1218//
1219//    labelTimeZone - the label for the UTC offset (timezone) "buttons".
1220//      Can be any HTML!  If not specified, "Time Zone" is assumed.
1221//
1222//    labelSecond - the label for the second "buttons".
1223//      Can be any HTML!  If not specified, "Second" is assumed.
1224//      This option is ignored if askSecond is false!
1225//
1226//    labelTitle - the label for the "title bar".  Can be any HTML!
1227//      If not specified, then whichever of the following is most
1228//      appropriate is used:  "Select a Date and Time", "Select a Date"
1229//      or "Select a Time", or no label if only one field is present.
1230//
1231//    labelYear - the label for the year "buttons".
1232//      Can be any HTML!  If not specified, "Year" is assumed.
1233//
1234//    latest - String or Date object representing the latest date/time
1235//        that a user can select.  For best results if the field is only
1236//        used to specify a date, be sure to set the time to 23:59:59.
1237//        If a String is used, it will be parsed according to the picker's
1238//        format (see AnyTime.Converter.format()).
1239//
1240//    placement - One of the following strings:
1241//
1242//      "popup" = the picker appears above its <input> when the input
1243//        receives focus, and disappears when it is dismissed.  This is
1244//        the default behavior.
1245//
1246//      "inline" = the picker is placed immediately after the <input>
1247//        and remains visible at all times.  When choosing this placement,
1248//        it is best to make the <input> invisible and use only the
1249//        picker to select dates.  The <input> value can still be used
1250//        during form submission as it will always reflect the current
1251//        picker state.
1252//
1253//        WARNING: when using "inline" and XHTML and including a day-of-
1254//        the-month format field, the input may only appear where a <table>
1255//        element is permitted (for example, NOT within a <p> element).
1256//        This is because the picker uses a <table> element to arrange
1257//        the day-of-the-month (calendar) buttons.  Failure to follow this
1258//        advice may result in an "unknown error" in Internet Explorer.
1259//
1260//    The following additional options may be specified; see documentation
1261//    for AnyTime.Converter (above) for information about these options:
1262//
1263//      baseYear
1264//      dayAbbreviations
1265//      dayNames
1266//      eraAbbreviations
1267//      format
1268//      monthAbbreviations
1269//      monthNames
1270//
1271//  Other behavior, such as how to format the values on the display
1272//  and which "buttons" to include, is inferred from the format string.
1273//=============================================================================
1274
1275AnyTime.picker = function( id, options )
1276{
1277	//  Create a new private object instance to manage the picker,
1278	//  if one does not already exist.
1279
1280    if ( __pickers[id] )
1281    	throw 'Cannot create another AnyTime.picker for "'+id+'"';
1282
1283	var _this = null;
1284
1285	__pickers[id] =
1286	{
1287		//  private members
1288
1289		twelveHr: false,
1290		ajaxOpts: null,		// options for AJAX requests
1291		denyTab: true,      // set to true to stop Opera from tabbing away
1292		askEra: false,		// prompt the user for the era in yDiv?
1293		cloak: null,		// cloak div
1294		conv: null,			// AnyTime.Converter
1295		div: null,			// picker div
1296	  	dB: null,			// body div
1297	  	dD: null,			// date div
1298	  	dY: null,			// years div
1299	  	dMo: null,			// months div
1300	  	dDoM: null,			// date-of-month table
1301	  	hDoM: null,			// date-of-month heading
1302	  	hMo: null,			// month heading
1303	  	hTitle: null,		// title heading
1304	  	hY: null,			// year heading
1305	  	dT: null,			// time div
1306	  	dH: null,			// hours div
1307	  	dM: null,			// minutes div
1308	  	dS: null,			// seconds div
1309	  	dO: null,           // offset (time zone) div
1310		earliest: null,		// earliest selectable date/time
1311		fBtn: null,			// button with current focus
1312		fDOW: 0,			// index to use as first day-of-week
1313	    hBlur: null,        // input handler
1314	    hClick: null,       // input handler
1315	    hFocus: null,       // input handler
1316	    hKeydown: null,     // input handler
1317	    hKeypress: null,    // input handler
1318	    hResize: null,      // event handler
1319		id: null,			// picker ID
1320		inp: null,			// input text field
1321		latest: null,		// latest selectable date/time
1322		lastAjax: null,		// last value submitted using AJAX
1323		lostFocus: false,	// when focus is lost, must redraw
1324		lX: 'X',			// label for dismiss button
1325		lY: 'Year',			// label for year
1326		lO: 'Time Zone',    // label for UTC offset (time zone)
1327		oBody: null,        // UTC offset selector popup
1328		oConv: null,        // AnyTime.Converter for offset display
1329		oCur: null,         // current-UTC-offset button
1330		oDiv: null,			// UTC offset selector popup
1331		oLab: null,			// UTC offset label
1332		oList: null,       // UTC offset container
1333		oSel: null,         // select (plus/minus) UTC-offset button
1334		offMin: Number.MIN_VALUE, // current UTC offset in minutes
1335		offSI: -1,          // current UTC label sub-index (if any)
1336		offStr: "",         // current UTC offset (time zone) string
1337		pop: true,			// picker is a popup?
1338		ro: false,      // was input readonly before picker initialized?
1339		time: null,			// current date/time
1340		url: null,			// URL to submit value using AJAX
1341		yAhead: null,		// years-ahead button
1342		y0XXX: null,		// millenium-digit-zero button (for focus)
1343		yCur: null,			// current-year button
1344		yDiv: null,			// year selector popup
1345		yLab: null,			// year label
1346		yNext: null,		// next-year button
1347		yPast: null,		// years-past button
1348		yPrior: null,		// prior-year button
1349
1350		//---------------------------------------------------------------------
1351		//  .initialize() initializes the picker instance.
1352		//---------------------------------------------------------------------
1353
1354		initialize: function( id )
1355		{
1356			_this = this;
1357
1358      this.id = 'AnyTime--'+id.replace(/[^-_.A-Za-z0-9]/g,'--AnyTime--');
1359
1360			options = jQuery.extend(true,{},options||{});
1361		  	options.utcParseOffsetCapture = true;
1362		  	this.conv = new AnyTime.Converter(options);
1363
1364		  	if ( options.placement )
1365		  	{
1366		  		if ( options.placement == 'inline' )
1367		  			this.pop = false;
1368		  		else if ( options.placement != 'popup' )
1369		  			throw 'unknown placement: ' + options.placement;
1370		  	}
1371
1372		  	if ( options.ajaxOptions )
1373		  	{
1374		  		this.ajaxOpts = jQuery.extend( {}, options.ajaxOptions );
1375		        if ( ! this.ajaxOpts.success )
1376		        	this.ajaxOpts.success = function(data,status) { _this.updVal(data); };
1377		  	}
1378
1379		  	if ( options.earliest )
1380          this.earliest = this.makeDate( options.earliest );
1381
1382		  	if ( options.firstDOW )
1383		  	{
1384		  		if ( ( options.firstDOW < 0 ) || ( options.firstDOW > 6 ) )
1385		  			throw 'illegal firstDOW: ' + options.firstDOW;
1386		  		this.fDOW = options.firstDOW;
1387		  	}
1388
1389		  	if ( options.latest )
1390		  		this.latest = this.makeDate( options.latest );
1391
1392		  	this.lX = options.labelDismiss || 'X';
1393		  	this.lY = options.labelYear || 'Year';
1394		  	this.lO = options.labelTimeZone || 'Time Zone';
1395
1396		  	//  Infer what we can about what to display from the format.
1397
1398		  	var i;
1399		  	var t;
1400		  	var lab;
1401		  	var shownFields = 0;
1402		  	var format = this.conv.fmt;
1403
1404		  	if ( typeof options.askEra != 'undefined' )
1405		  		this.askEra = options.askEra;
1406		  	else
1407		  		this.askEra = (format.indexOf('%B')>=0) || (format.indexOf('%C')>=0) || (format.indexOf('%E')>=0);
1408		  	var askYear = (format.indexOf('%Y')>=0) || (format.indexOf('%y')>=0) || (format.indexOf('%Z')>=0) || (format.indexOf('%z')>=0);
1409		  	var askMonth = (format.indexOf('%b')>=0) || (format.indexOf('%c')>=0) || (format.indexOf('%M')>=0) || (format.indexOf('%m')>=0);
1410		  	var askDoM = (format.indexOf('%D')>=0) || (format.indexOf('%d')>=0) || (format.indexOf('%e')>=0);
1411		  	var askDate = askYear || askMonth || askDoM;
1412		  	this.twelveHr = (format.indexOf('%h')>=0) || (format.indexOf('%I')>=0) || (format.indexOf('%l')>=0) || (format.indexOf('%r')>=0);
1413		  	var askHour = this.twelveHr || (format.indexOf('%H')>=0) || (format.indexOf('%k')>=0) || (format.indexOf('%T')>=0);
1414		  	var askMinute = (format.indexOf('%i')>=0) || (format.indexOf('%r')>=0) || (format.indexOf('%T')>=0);
1415		  	var askSec = ( (format.indexOf('%r')>=0) || (format.indexOf('%S')>=0) || (format.indexOf('%s')>=0) || (format.indexOf('%T')>=0) );
1416		  	if ( askSec && ( typeof options.askSecond != 'undefined' ) )
1417		  		askSec = options.askSecond;
1418		  	var askOff = ( (format.indexOf('%#')>=0) || (format.indexOf('%+')>=0) || (format.indexOf('%-')>=0) || (format.indexOf('%:')>=0) || (format.indexOf('%;')>=0) || (format.indexOf('%<')>=0) || (format.indexOf('%>')>=0) || (format.indexOf('%@')>=0) );
1419		  	var askTime = askHour || askMinute || askSec || askOff;
1420
1421		  	if ( askOff )
1422			  	this.oConv = new AnyTime.Converter( { format: options.formatUtcOffset ||
1423			  		format.match(/\S*%[-+:;<>#@]\S*/g).join(' ') } );
1424
1425		  	//  Create the picker HTML and add it to the page.
1426		  	//  Popup pickers will be moved to the end of the body
1427		  	//  once the entire page has loaded.
1428
1429        this.inp = $(document.getElementById(id)); // avoids ID-vs-pseudo-selector probs like id="foo:bar"
1430        this.ro = this.inp.prop('readonly');
1431        this.inp.prop('readonly',true);
1432		  	this.div = $( '<div class="AnyTime-win AnyTime-pkr ui-widget ui-widget-content ui-corner-all" id="' + this.id + '" aria-live="off"></div>' );
1433		    this.inp.after(this.div);
1434		  	this.hTitle = $( '<h5 class="AnyTime-hdr ui-widget-header ui-corner-top"/>' );
1435		  	this.div.append( this.hTitle );
1436		  	this.dB = $( '<div class="AnyTime-body"></div>' );
1437		  	this.div.append( this.dB );
1438
1439		  	if ( options.hideInput )
1440		        this.inp.css({border:0,height:'1px',margin:0,padding:0,width:'1px'});
1441
1442		  	//  Add dismiss box to title (if popup)
1443
1444		  	t = null;
1445		  	var xDiv = null;
1446		  	if ( this.pop )
1447		  	{
1448		  		xDiv = $( '<div class="AnyTime-x-btn ui-state-default">'+this.lX+'</div>' );
1449		  		this.hTitle.append( xDiv );
1450		  		xDiv.click(function(e){_this.dismiss(e);});
1451		  	}
1452
1453		  	//  date (calendar) portion
1454
1455		  	lab = '';
1456		  	if ( askDate )
1457		  	{
1458          this.dD = $( '<div class="AnyTime-date"></div>' );
1459          this.dB.append( this.dD );
1460
1461		      if ( askYear )
1462		      {
1463		    	  this.yLab = $('<h6 class="AnyTime-lbl AnyTime-lbl-yr">' + this.lY + '</h6>');
1464		    	  this.dD.append( this.yLab );
1465
1466		          this.dY = $( '<ul class="AnyTime-yrs ui-helper-reset" />' );
1467		          this.dD.append( this.dY );
1468
1469		          this.yPast = this.btn(this.dY,'&lt;',this.newYear,['yrs-past'],'- '+this.lY);
1470		          this.yPrior = this.btn(this.dY,'1',this.newYear,['yr-prior'],'-1 '+this.lY);
1471		          this.yCur = this.btn(this.dY,'2',this.newYear,['yr-cur'],this.lY);
1472		          this.yCur.removeClass('ui-state-default');
1473		          this.yCur.addClass('AnyTime-cur-btn ui-state-default ui-state-highlight');
1474
1475		          this.yNext = this.btn(this.dY,'3',this.newYear,['yr-next'],'+1 '+this.lY);
1476		          this.yAhead = this.btn(this.dY,'&gt;',this.newYear,['yrs-ahead'],'+ '+this.lY);
1477
1478		          shownFields++;
1479
1480		      } // if ( askYear )
1481
1482		      if ( askMonth )
1483		      {
1484		    	  lab = options.labelMonth || 'Month';
1485		    	  this.hMo = $( '<h6 class="AnyTime-lbl AnyTime-lbl-month">' + lab + '</h6>' );
1486		    	  this.dD.append( this.hMo );
1487		    	  this.dMo = $('<ul class="AnyTime-mons" />');
1488		    	  this.dD.append(this.dMo);
1489		    	  for ( i = 0 ; i < 12 ; i++ )
1490		    	  {
1491		    		  var mBtn = this.btn( this.dMo, this.conv.mAbbr[i],
1492			    			function( event )
1493			    			{
1494			    				var elem = $(event.target);
1495			    			    if ( elem.hasClass("AnyTime-out-btn") )
1496			    			    	return;
1497			    				var mo = event.target.AnyTime_month;
1498			    				var t = new Date(this.time.getTime());
1499			    				if ( t.getDate() > __daysIn[mo] )
1500			    					t.setDate(__daysIn[mo])
1501			    				t.setMonth(mo);
1502			    				this.set(t);
1503			    			    this.upd(elem);
1504			    			},
1505			    			['mon','mon'+String(i+1)], lab+' '+this.conv.mNames[i] );
1506		    		  mBtn[0].AnyTime_month = i;
1507		    	  }
1508		    	  shownFields++;
1509		      }
1510
1511		      if ( askDoM )
1512		      {
1513		    	lab = options.labelDayOfMonth || 'Day of Month';
1514		        this.hDoM = $('<h6 class="AnyTime-lbl AnyTime-lbl-dom">' + lab + '</h6>' );
1515		      	this.dD.append( this.hDoM );
1516		        this.dDoM =  $( '<table border="0" cellpadding="0" cellspacing="0" class="AnyTime-dom-table"/>' );
1517		        this.dD.append( this.dDoM );
1518		        t = $( '<thead class="AnyTime-dom-head"/>' );
1519		        this.dDoM.append(t);
1520		        var tr = $( '<tr class="AnyTime-dow"/>' );
1521		        t.append(tr);
1522		        for ( i = 0 ; i < 7 ; i++ )
1523		          tr.append( '<th class="AnyTime-dow AnyTime-dow'+String(i+1)+'">'+this.conv.dAbbr[(this.fDOW+i)%7]+'</th>' );
1524
1525		        var tbody = $( '<tbody class="AnyTime-dom-body" />' );
1526		        this.dDoM.append(tbody);
1527		        for ( var r = 0 ; r < 6 ; r++ )
1528		        {
1529		          tr = $( '<tr class="AnyTime-wk AnyTime-wk'+String(r+1)+'"/>' );
1530		          tbody.append(tr);
1531		          for ( i = 0 ; i < 7 ; i++ )
1532		        	  this.btn( tr, 'x',
1533		        		function( event )
1534		        		{
1535		        			var elem = $(event.target);
1536		        		    if ( elem.hasClass("AnyTime-out-btn") )
1537		        		    	return;
1538		        			var dom = Number(elem.html());
1539		        			if ( dom )
1540		        			{
1541		        				var t = new Date(this.time.getTime());
1542		        				t.setDate(dom);
1543		        				this.set(t);
1544		        				this.upd(elem);
1545		        			}
1546		        		},
1547		        		['dom'], lab );
1548		        }
1549		        shownFields++;
1550
1551		      } // if ( askDoM )
1552
1553		    } // if ( askDate )
1554
1555		    //  time portion
1556
1557		    if ( askTime )
1558		    {
1559          var tensDiv, onesDiv;
1560
1561		      this.dT = $('<div class="AnyTime-time"></div>');
1562		      this.dB.append(this.dT);
1563
1564		      if ( askHour )
1565		      {
1566		        this.dH = $('<div class="AnyTime-hrs"></div>');
1567		        this.dT.append(this.dH);
1568
1569		        lab = options.labelHour || 'Hour';
1570		        this.dH.append( $('<h6 class="AnyTime-lbl AnyTime-lbl-hr">'+lab+'</h6>') );
1571		        var amDiv = $('<ul class="AnyTime-hrs-am"/>');
1572		        this.dH.append( amDiv );
1573		        var pmDiv = $('<ul class="AnyTime-hrs-pm"/>');
1574		        this.dH.append( pmDiv );
1575
1576		        for ( i = 0 ; i < 12 ; i++ )
1577		        {
1578		          if ( this.twelveHr )
1579		          {
1580		            if ( i == 0 )
1581		              t = '12am';
1582		            else
1583		              t = String(i)+'am';
1584		          }
1585		          else
1586		            t = AnyTime.pad(i,2);
1587
1588		          this.btn( amDiv, t, this.newHour,['hr','hr'+String(i)],lab+' '+t);
1589
1590		          if ( this.twelveHr )
1591		          {
1592		            if ( i == 0 )
1593		              t = '12pm';
1594		            else
1595		              t = String(i)+'pm';
1596		          }
1597		          else
1598		            t = i+12;
1599
1600		          this.btn( pmDiv, t, this.newHour,['hr','hr'+String(i+12)],lab+' '+t);
1601		        }
1602
1603				shownFields++;
1604
1605		      } // if ( askHour )
1606
1607		      if ( askMinute )
1608		      {
1609		        this.dM = $('<div class="AnyTime-mins"></div>');
1610		        this.dT.append(this.dM);
1611
1612		        lab = options.labelMinute || 'Minute';
1613		        this.dM.append( $('<h6 class="AnyTime-lbl AnyTime-lbl-min">'+lab+'</h6>') );
1614            tensDiv = $('<ul class="AnyTime-mins-tens"/>');
1615		        this.dM.append(tensDiv);
1616
1617		        for ( i = 0 ; i < 6 ; i++ )
1618		          this.btn( tensDiv, i,
1619		        		  function( event )
1620		        		  {
1621		        		      var elem = $(event.target);
1622		        			  if ( elem.hasClass("AnyTime-out-btn") )
1623		        			    	return;
1624		        		      var t = new Date(this.time.getTime());
1625		        		      t.setMinutes( (Number(elem.text())*10) + (this.time.getMinutes()%10) );
1626		        		      this.set(t);
1627		        		      this.upd(elem);
1628		        		  },
1629		        		  ['min-ten','min'+i+'0'], lab+' '+i+'0' );
1630		        for ( ; i < 12 ; i++ )
1631			          this.btn( tensDiv, '&#160;', $.noop, ['min-ten','min'+i+'0'], lab+' '+i+'0' ).addClass('AnyTime-min-ten-btn-empty ui-state-default ui-state-disabled');
1632
1633            onesDiv = $('<ul class="AnyTime-mins-ones"/>');
1634		        this.dM.append(onesDiv);
1635		        for ( i = 0 ; i < 10 ; i++ )
1636		          this.btn( onesDiv, i,
1637		    		  function( event )
1638		    		  {
1639		    		      var elem = $(event.target);
1640		    			  if ( elem.hasClass("AnyTime-out-btn") )
1641		    			    	return;
1642		    		      var t = new Date(this.time.getTime());
1643		    		      t.setMinutes( (Math.floor(this.time.getMinutes()/10)*10)+Number(elem.text()) );
1644		    		      this.set(t);
1645		    		      this.upd(elem);
1646		    		  },
1647		    		  ['min-one','min'+i], lab+' '+i );
1648		        for ( ; i < 12 ; i++ )
1649			          this.btn( onesDiv, '&#160;', $.noop, ['min-one','min'+i+'0'], lab+' '+i ).addClass('AnyTime-min-one-btn-empty ui-state-default ui-state-disabled');
1650
1651				shownFields++;
1652
1653		      } // if ( askMinute )
1654
1655		      if ( askSec )
1656		      {
1657		        this.dS = $('<div class="AnyTime-secs"></div>');
1658		        this.dT.append(this.dS);
1659		        lab = options.labelSecond || 'Second';
1660		        this.dS.append( $('<h6 class="AnyTime-lbl AnyTime-lbl-sec">'+lab+'</h6>') );
1661            tensDiv = $('<ul class="AnyTime-secs-tens"/>');
1662		        this.dS.append(tensDiv);
1663
1664		        for ( i = 0 ; i < 6 ; i++ )
1665		          this.btn( tensDiv, i,
1666		    		  function( event )
1667		    		  {
1668		    		      var elem = $(event.target);
1669		    			  if ( elem.hasClass("AnyTime-out-btn") )
1670		    			    	return;
1671		    		      var t = new Date(this.time.getTime());
1672		    		      t.setSeconds( (Number(elem.text())*10) + (this.time.getSeconds()%10) );
1673		    		      this.set(t);
1674		    		      this.upd(elem);
1675		    		  },
1676		    		  ['sec-ten','sec'+i+'0'], lab+' '+i+'0' );
1677		        for ( ; i < 12 ; i++ )
1678			          this.btn( tensDiv, '&#160;', $.noop, ['sec-ten','sec'+i+'0'], lab+' '+i+'0' ).addClass('AnyTime-sec-ten-btn-empty ui-state-default ui-state-disabled');
1679
1680            onesDiv = $('<ul class="AnyTime-secs-ones"/>');
1681		        this.dS.append(onesDiv);
1682		        for ( i = 0 ; i < 10 ; i++ )
1683		          this.btn( onesDiv, i,
1684		    		  function( event )
1685		    		  {
1686		    		      var elem = $(event.target);
1687		    			  if ( elem.hasClass("AnyTime-out-btn") )
1688		    			    	return;
1689		    		      var t = new Date(this.time.getTime());
1690		    		      t.setSeconds( (Math.floor(this.time.getSeconds()/10)*10) + Number(elem.text()) );
1691		    		      this.set(t);
1692		    		      this.upd(elem);
1693		    		  },
1694		    		  ['sec-one','sec'+i], lab+' '+i );
1695		        for ( ; i < 12 ; i++ )
1696			          this.btn( onesDiv, '&#160;', $.noop, ['sec-one','sec'+i+'0'], lab+' '+i ).addClass('AnyTime-sec-one-btn-empty ui-state-default ui-state-disabled');
1697
1698				shownFields++;
1699
1700		      } // if ( askSec )
1701
1702		      if ( askOff )
1703		      {
1704		    	this.dO = $('<div class="AnyTime-offs" ></div>');
1705          this.dT.append('<br />');
1706          this.dT.append(this.dO);
1707
1708		    	this.oList = $('<ul class="AnyTime-off-list ui-helper-reset" />');
1709          this.dO.append(this.oList);
1710
1711          this.oCur = this.btn(this.oList,'',this.newOffset,['off','off-cur'],lab);
1712          this.oCur.removeClass('ui-state-default');
1713          this.oCur.addClass('AnyTime-cur-btn ui-state-default ui-state-highlight');
1714
1715			  	this.oSel = this.btn(this.oList,'&#177;',this.newOffset,['off','off-select'],'+/- '+this.lO);
1716
1717			  	this.oMinW = this.dO.outerWidth(true);
1718		    	this.oLab = $('<h6 class="AnyTime-lbl AnyTime-lbl-off">' + this.lO + '</h6>');
1719		    	this.dO.prepend( this.oLab );
1720
1721				shownFields++;
1722		      }
1723
1724		    } // if ( askTime )
1725
1726		    //  Set the title.  If a title option has been specified, use it.
1727		    //  Otherwise, determine a worthy title based on which (and how many)
1728		    //  format fields have been specified.
1729
1730		    if ( options.labelTitle )
1731		      this.hTitle.append( options.labelTitle );
1732		    else if ( shownFields > 1 )
1733		      this.hTitle.append( 'Select a '+(askDate?(askTime?'Date and Time':'Date'):'Time') );
1734		    else
1735		      this.hTitle.append( 'Select' );
1736
1737
1738		    //  Initialize the picker's date/time value.
1739
1740		    try
1741		    {
1742		      this.time = this.conv.parse(this.inp.val());
1743		      this.offMin = this.conv.getUtcParseOffsetCaptured();
1744		      this.offSI = this.conv.getUtcParseOffsetSubIndex();
1745		      if ( 'init' in options ) // override
1746            this.time = this.makeDate( options.init);
1747		    }
1748		    catch ( e )
1749		    {
1750		      this.time = new Date();
1751		    }
1752		    this.lastAjax = this.time;
1753
1754
1755		    //  If this is a popup picker, hide it until needed.
1756
1757		    if ( this.pop )
1758		    {
1759		      this.div.hide();
1760		      this.div.css('position','absolute');
1761		    }
1762
1763		    //  Setup event listeners for the input and resize listeners for
1764		    //  the picker.  Add the picker to the instances list (which is used
1765		    //  to hide pickers if the user clicks off of them).
1766
1767		    this.inp.blur( this.hBlur =
1768		    	function(e)
1769		    	{
1770		    		_this.inpBlur(e);
1771		    	} );
1772
1773		    this.inp.click( this.hClick =
1774		    	function(e)
1775		    	{
1776	    			_this.showPkr(e);
1777		    	} );
1778
1779		    this.inp.focus( this.hFocus =
1780		    	function(e)
1781		    	{
1782		    		if ( _this.lostFocus )
1783		    			_this.showPkr(e);
1784		    		_this.lostFocus = false;
1785		    	} );
1786
1787		    this.inp.keydown( this.hKeydown =
1788		    	function(e)
1789		    	{
1790		    		_this.key(e);
1791		    	} );
1792
1793		    this.inp.keypress( this.hKeypress =
1794          function(e)
1795          {
1796//			    if ( $.browser.opera && _this.denyTab )
1797//			    	e.preventDefault();
1798          } );
1799
1800		    this.div.click(
1801          function(e)
1802          {
1803            _this.lostFocus = false;
1804            _this.inp.focus();
1805          } );
1806
1807		    $(window).resize( this.hResize =
1808		    	function(e)
1809		    	{
1810		    		_this.pos(e);
1811		    	} );
1812
1813		    if ( __initialized )
1814		    	this.onReady();
1815
1816		}, // initialize()
1817
1818
1819		//---------------------------------------------------------------------
1820		//  .ajax() notifies the server of a value change using Ajax.
1821		//---------------------------------------------------------------------
1822
1823		ajax: function()
1824		{
1825		    if ( this.ajaxOpts && ( this.time.getTime() != this.lastAjax.getTime() ) )
1826		    {
1827		      try
1828		      {
1829		    	var opts = jQuery.extend( {}, this.ajaxOpts );
1830		        if ( typeof opts.data == 'object' )
1831		        	opts.data[this.inp[0].name||this.inp[0].id] = this.inp.val();
1832		        else
1833		        {
1834		        	var opt = (this.inp[0].name||this.inp[0].id) + '=' + encodeURI(this.inp.val());
1835		        	if ( opts.data )
1836		        		opts.data += '&' + opt;
1837		        	else
1838		        		opts.data = opt;
1839		        }
1840		        $.ajax( opts );
1841		        this.lastAjax = this.time;
1842		      }
1843		      catch( e )
1844		      {
1845		      }
1846		    }
1847		    return;
1848
1849		}, // .ajax()
1850
1851		//---------------------------------------------------------------------
1852		//  .askOffset() is called by this.newOffset() when the UTC offset or
1853		//  +- selection button is clicked.
1854		//---------------------------------------------------------------------
1855
1856		askOffset: function( event )
1857		{
1858		    if ( ! this.oDiv )
1859		    {
1860		      this.makeCloak();
1861
1862		      this.oDiv = $('<div class="AnyTime-win AnyTime-off-selector ui-widget ui-widget-content ui-corner-all"></div>');
1863		      this.div.append(this.oDiv);
1864
1865		      // the order here (HDR,BODY,XDIV,TITLE) is important for width calcluation:
1866		      var title = $('<h5 class="AnyTime-hdr AnyTime-hdr-off-selector ui-widget-header ui-corner-top" />');
1867		      this.oDiv.append( title );
1868		      this.oBody = $('<div class="AnyTime-body AnyTime-body-off-selector"></div>');
1869		      this.oDiv.append( this.oBody );
1870
1871		      var xDiv = $('<div class="AnyTime-x-btn ui-state-default">'+this.lX+'</div>');
1872		      title.append(xDiv);
1873		      xDiv.click(function(e){_this.dismissODiv(e);});
1874		      title.append( this.lO );
1875
1876		      var cont = $('<ul class="AnyTime-off-off" />' );
1877		      var last = null;
1878		      this.oBody.append(cont);
1879		      var useSubIndex = (this.oConv.fmt.indexOf('%@')>=0);
1880		      if ( AnyTime.utcLabel )
1881			      for ( var o = -720 ; o <= 840 ; o++ )
1882			    	  if ( AnyTime.utcLabel[o] )
1883			    	  {
1884				        this.oConv.setUtcFormatOffsetAlleged(o);
1885				        for ( var i = 0; i < AnyTime.utcLabel[o].length; i++ )
1886				        {
1887				          this.oConv.setUtcFormatOffsetSubIndex(i);
1888				          last = this.btn( cont, this.oConv.format(this.time), this.newOPos, ['off-off'], o );
1889				          last[0].AnyTime_offMin = o;
1890				          last[0].AnyTime_offSI = i;
1891				          if ( ! useSubIndex )
1892				        	  break; // for
1893				        }
1894			    	  }
1895
1896		      if ( last )
1897		    	  last.addClass('AnyTime-off-off-last-btn');
1898
1899          if ( this.oDiv.outerHeight(true) > this.div.height() )
1900          {
1901            var oldW = this.oBody.width();
1902            this.oBody.css('height','0');
1903            this.oBody.css({
1904              height:
1905                String(this.div.height()-
1906                  (this.oDiv.outerHeight(true)+this.oBody.outerHeight(false)))+'px',
1907              width: String(oldW+20)+'px' }); // wider for scroll bar
1908          }
1909          if ( this.oDiv.outerWidth(true) > this.div.width() )
1910          {
1911            this.oBody.css('width','0');
1912            this.oBody.css('width',
1913                  String(this.div.width()-
1914                    (this.oDiv.outerWidth(true)+this.oBody.outerWidth(false)))+'px');
1915          }
1916
1917		    } // if ( ! this.oDiv )
1918		    else
1919		    {
1920		      this.cloak.show();
1921		      this.oDiv.show();
1922		    }
1923		    this.pos(event);
1924		    this.updODiv(null);
1925
1926		    var f = this.oDiv.find('.AnyTime-off-off-btn.AnyTime-cur-btn:first');
1927		    if ( ! f.length )
1928		    	f = this.oDiv.find('.AnyTime-off-off-btn:first');
1929		    this.setFocus( f );
1930
1931		}, // .askOffset()
1932
1933		//---------------------------------------------------------------------
1934		//  .askYear() is called by this.newYear() when the yPast or yAhead
1935		//  button is clicked.
1936		//---------------------------------------------------------------------
1937
1938		askYear: function( event )
1939		{
1940		    if ( ! this.yDiv )
1941		    {
1942		      this.makeCloak();
1943
1944		      this.yDiv = $('<div class="AnyTime-win AnyTime-yr-selector ui-widget ui-widget-content ui-corner-all"></div>');
1945		      this.div.append(this.yDiv);
1946
1947		      var title = $('<h5 class="AnyTime-hdr AnyTime-hdr-yr-selector ui-widget-header ui-corner-top" />');
1948		      this.yDiv.append( title );
1949
1950		      var xDiv = $('<div class="AnyTime-x-btn ui-state-default">'+this.lX+'</div>');
1951		      title.append(xDiv);
1952		      xDiv.click(function(e){_this.dismissYDiv(e);});
1953
1954		      title.append( this.lY );
1955
1956		      var yBody = $('<div class="AnyTime-body AnyTime-body-yr-selector" ></div>');
1957		      this.yDiv.append( yBody );
1958
1959		      cont = $('<ul class="AnyTime-yr-mil" />' );
1960		      yBody.append(cont);
1961		      this.y0XXX = this.btn( cont, 0, this.newYPos,['mil','mil0'],this.lY+' '+0+'000');
1962		      for ( i = 1; i < 10 ; i++ )
1963		        this.btn( cont, i, this.newYPos,['mil','mil'+i],this.lY+' '+i+'000');
1964
1965  			  cont = $('<ul class="AnyTime-yr-cent" />' );
1966		      yBody.append(cont);
1967		      for ( i = 0 ; i < 10 ; i++ )
1968		        this.btn( cont, i, this.newYPos,['cent','cent'+i],this.lY+' '+i+'00');
1969
1970		      cont = $('<ul class="AnyTime-yr-dec" />');
1971		      yBody.append(cont);
1972		      for ( i = 0 ; i < 10 ; i++ )
1973		        this.btn( cont, i, this.newYPos,['dec','dec'+i],this.lY+' '+i+'0');
1974
1975		      cont = $('<ul class="AnyTime-yr-yr" />');
1976		      yBody.append(cont);
1977		      for ( i = 0 ; i < 10 ; i++ )
1978		        this.btn( cont, i, this.newYPos,['yr','yr'+i],this.lY+' '+i );
1979
1980		      if ( this.askEra )
1981		      {
1982		        cont = $('<ul class="AnyTime-yr-era" />' );
1983		        yBody.append(cont);
1984
1985		        this.btn( cont, this.conv.eAbbr[0],
1986		        		function( event )
1987		        		{
1988	  		      			var t = new Date(this.time.getTime());
1989		        			var year = t.getFullYear();
1990		        		    if ( year > 0 )
1991								t.setFullYear(0-year);
1992							this.set(t);
1993							this.updYDiv($(event.target));
1994		        		},
1995		        		['era','bce'], this.conv.eAbbr[0] );
1996
1997		        this.btn( cont, this.conv.eAbbr[1],
1998		        		function( event )
1999		        		{
2000			      			var t = new Date(this.time.getTime());
2001		        			var year = t.getFullYear();
2002		        		    if ( year < 0 )
2003								t.setFullYear(0-year);
2004							this.set(t);
2005							this.updYDiv($(event.target));
2006		        		},
2007		        		['era','ce'], this.conv.eAbbr[1] );
2008
2009		      } // if ( this.askEra )
2010		    } // if ( ! this.yDiv )
2011		    else
2012		    {
2013		      this.cloak.show();
2014		      this.yDiv.show();
2015		    }
2016		    this.pos(event);
2017		    this.updYDiv(null);
2018		    this.setFocus( this.yDiv.find('.AnyTime-yr-btn.AnyTime-cur-btn:first') );
2019
2020		}, // .askYear()
2021
2022		//---------------------------------------------------------------------
2023		//  .inpBlur() is called when a picker's input loses focus to dismiss
2024		//  the popup.  A 1/3 second delay is necessary to restore focus if
2025		//	the div is clicked (shorter delays don't always work!)  To prevent
2026		//  problems cause by scrollbar focus (except in FF), focus is
2027		//  force-restored if the offset div is visible.
2028		//---------------------------------------------------------------------
2029
2030		inpBlur: function(event)
2031		{
2032			if ( this.oDiv && this.oDiv.is(":visible") )
2033			{
2034				_this.inp.focus();
2035				return;
2036			}
2037			this.lostFocus = true;
2038		    setTimeout(
2039		    	function()
2040		    	{
2041		    		if ( _this.lostFocus )
2042		    		{
2043		    			_this.div.find('.AnyTime-focus-btn').removeClass('AnyTime-focus-btn ui-state-focus');
2044		    			if ( _this.pop )
2045		    				_this.dismiss(event);
2046		    			else
2047		    				_this.ajax();
2048		    		}
2049		    	}, 334 );
2050		},
2051
2052		//---------------------------------------------------------------------
2053		//  .btn() is called by AnyTime.picker() to create a <div> element
2054		//  containing an <a> element.  The elements are given appropriate
2055		//  classes based on the specified "classes" (an array of strings).
2056		//	The specified "text" and "title" are used for the <a> element.
2057		//	The "handler" is bound to click events for the <div>, which will
2058		//	catch bubbling clicks from the <a> as well.  The button is
2059		//	appended to the specified parent (jQuery), and the <div> jQuery
2060		//	is returned.
2061		//---------------------------------------------------------------------
2062
2063		btn: function( parent, text, handler, classes, title )
2064		{
2065			var tagName = ( (parent[0].nodeName.toLowerCase()=='ul')?'li':'td');
2066			var div$ = '<' + tagName +
2067			  				' class="AnyTime-btn';
2068			for ( var i = 0 ; i < classes.length ; i++ )
2069				div$ += ' AnyTime-' + classes[i] + '-btn';
2070			var div = $( div$ + ' ui-state-default">
2070' + text + '</' + tagName + '>' );
2071			parent.append(div);
2072			div.AnyTime_title = title;
2073
2074			div.click(
2075			    function(e)
2076			  	{
2077			      // bind the handler to the picker so "this" is correct
2078				  _this.tempFunc = handler;
2079				  _this.tempFunc(e);
2080			  	});
2081			div.dblclick(
2082				function(e)
2083				{
2084					var elem = $(this);
2085					if ( elem.is('.AnyTime-off-off-btn') )
2086						_this.dismissODiv(e);
2087					else if ( elem.is('.AnyTime-mil-btn') || elem.is('.AnyTime-cent-btn') || elem.is('.AnyTime-dec-btn') || elem.is('.AnyTime-yr-btn') || elem.is('.AnyTime-era-btn') )
2088						_this.dismissYDiv(e);
2089					else if ( _this.pop )
2090						_this.dismiss(e);
2091				});
2092		    return div;
2093
2094		}, // .btn()
2095
2096		//---------------------------------------------------------------------
2097		//  .cleanup() destroys the DOM events and elements associated with
2098		//  the picker so it can be deleted.
2099		//---------------------------------------------------------------------
2100
2101		cleanup: function(event)
2102		{
2103			this.
2104			  inp.
2105			    prop('readonly',this.ro).
2106			    off('blur',this.hBlur).
2107		      off('click',this.hClick).
2108		      off('focus',this.hFocus).
2109		      off('keydown',this.hKeydown).
2110		      off('keypress',this.hKeypress);
2111      $(window).off('resize',this.hResize);
2112			this.div.remove();
2113		},
2114
2115		//---------------------------------------------------------------------
2116		//  .dismiss() dismisses a popup picker.
2117		//---------------------------------------------------------------------
2118
2119		dismiss: function(event)
2120		{
2121			this.ajax();
2122			if ( this.yDiv )
2123				this.dismissYDiv();
2124			if ( this.oDiv )
2125				this.dismissODiv();
2126			this.div.hide();
2127			this.lostFocus = true;
2128		},
2129
2130		//---------------------------------------------------------------------
2131		//  .dismissODiv() dismisses the UTC offset selector popover.
2132		//---------------------------------------------------------------------
2133
2134		dismissODiv: function(event)
2135		{
2136		    this.oDiv.hide();
2137		    this.cloak.hide();
2138			this.setFocus(this.oCur);
2139		},
2140
2141		//---------------------------------------------------------------------
2142		//  .dismissYDiv() dismisses the date selector popover.
2143		//---------------------------------------------------------------------
2144
2145		dismissYDiv: function(event)
2146		{
2147		    this.yDiv.hide();
2148		    this.cloak.hide();
2149			this.setFocus(this.yCur);
2150		},
2151
2152		//---------------------------------------------------------------------
2153		//  .setFocus() makes a specified psuedo-button appear to get focus.
2154		//---------------------------------------------------------------------
2155
2156		setFocus: function(btn)
2157		{
2158			if ( ! btn.hasClass('AnyTime-focus-btn') )
2159			{
2160				this.div.find('.AnyTime-focus-btn').removeClass('AnyTime-focus-btn ui-state-focus');
2161				this.fBtn = btn;
2162				btn.removeClass('ui-state-default ui-state-highlight');
2163				btn.addClass('AnyTime-focus-btn ui-state-default ui-state-highlight ui-state-focus');
2164			}
2165			if ( btn.hasClass('AnyTime-off-off-btn') )
2166			{
2167				var oBT = this.oBody.offset().top;
2168				var btnT = btn.offset().top;
2169				var btnH = btn.outerHeight(true);
2170				if ( btnT - btnH < oBT ) // move a page up
2171					this.oBody.scrollTop( btnT + this.oBody.scrollTop() - ( this.oBody.innerHeight() + oBT ) + ( btnH * 2 ) );
2172				else if ( btnT + btnH > oBT + this.oBody.innerHeight() ) // move a page down
2173					this.oBody.scrollTop( ( btnT + this.oBody.scrollTop() ) - ( oBT + btnH ) );
2174			}
2175		},
2176
2177		//---------------------------------------------------------------------
2178		//  .key() is invoked when a user presses a key while the picker's
2179		//	input has focus.  A psuedo-button is considered "in focus" and an
2180		//	appropriate action is performed according to the WAI-ARIA Authoring
2181		//	Practices 1.0 for datepicker from
2182		//  www.w3.org/TR/2009/WD-wai-aria-practices-20091215/#datepicker:
2183		//
2184		//  * LeftArrow moves focus left, continued to previous week.
2185		//  * RightArrow moves focus right, continued to next week.
2186		//  * UpArrow moves focus to the same weekday in the previous week.
2187		//  * DownArrow moves focus to same weekday in the next week.
2188		//  * PageUp moves focus to same day in the previous month.
2189		//  * PageDown moves focus to same day in the next month.
2190		//  * Shift+Page Up moves focus to same day in the previous year.
2191		//  * Shift+Page Down moves focus to same day in the next year.
2192		//  * Home moves focus to the first day of the month.
2193		//  * End moves focus to the last day of the month.
2194		//  * Ctrl+Home moves focus to the first day of the year.
2195		//  * Ctrl+End moves focus to the last day of the year.
2196		//  * Esc closes a DatePicker that is opened as a Popup.
2197		//
2198		//  The following actions (for multiple-date selection) are NOT
2199		//	supported:
2200		//  * Shift+Arrow performs continous selection.
2201		//  * Ctrl+Space multiple selection of certain days.
2202		//
2203		//  The authoring practices do not specify behavior for a time picker,
2204		//  or for month-and-year pickers that do not have a day-of-the-month,
2205		//  but AnyTime.picker uses the following behavior to be as consistent
2206		//  as possible with the defined datepicker functionality:
2207		//  * LeftArrow moves focus left or up to previous value or field.
2208		//  * RightArrow moves focus right or down to next value or field.
2209		//  * UpArrow moves focus up or left to previous value or field.
2210		//  * DownArrow moves focus down or right to next value or field
2211		//  * PageUp moves focus to the current value in the previous units
2212		//    (for example, from ten-minutes to hours or one-minutes to
2213		//	  ten-minutes or months to years).
2214		//  * PageDown moves focus to the current value in the next units
2215		//    (for example, from hours to ten-minutes or ten-minutes to
2216		//    one-minutes or years to months).
2217		//  * Home moves the focus to the first unit button.
2218		//  * End moves the focus to the last unit button.
2219		//
2220		//  In addition, Tab and Shift+Tab move between units (including to/
2221		//	from the Day-of-Month table) and also in/out of the picker.
2222		//
2223		//  Because AnyTime.picker sets a value as soon as the button receives
2224		//  focus, SPACE and ENTER are not needed (the WAI-ARIA guidelines use
2225		//  them to select a value.
2226		//---------------------------------------------------------------------
2227
2228		key: function(event)
2229		{
2230      var mo;
2231			var t = null;
2232      var _this = this;
2233			var elem = this.div.find('.AnyTime-focus-btn');
2234		    var key = event.keyCode || event.which;
2235		    this.denyTab = true;
2236
2237		    if ( key == 16 ) // Shift
2238		    {
2239		    }
2240		    else if ( ( key == 10 ) || ( key == 13 ) || ( key == 27 ) ) // Enter & Esc
2241		    {
2242		      if ( this.oDiv && this.oDiv.is(':visible') )
2243		        this.dismissODiv(event);
2244		      else if ( this.yDiv && this.yDiv.is(':visible') )
2245			    this.dismissYDiv(event);
2246		      else if ( this.pop )
2247			    this.dismiss(event);
2248		    }
2249		    else if ( ( key == 33 ) || ( ( key == 9 ) && event.shiftKey ) ) // PageUp & Shift+Tab
2250		    {
2251		    	if ( this.fBtn.hasClass('AnyTime-off-off-btn') )
2252				{
2253		    		if ( key == 9 )
2254				        this.dismissODiv(event);
2255				}
2256		    	else if ( this.fBtn.hasClass('AnyTime-mil-btn') )
2257				{
2258		    		if ( key == 9 )
2259				        this.dismissYDiv(event);
2260				}
2261		    	else if ( this.fBtn.hasClass('AnyTime-cent-btn') )
2262					this.yDiv.find('.AnyTime-mil-btn.AnyTime-cur-btn').triggerHandler('click');
2263		    	else if ( this.fBtn.hasClass('AnyTime-dec-btn') )
2264					this.yDiv.find('.AnyTime-cent-btn.AnyTime-cur-btn').triggerHandler('click');
2265		    	else if ( this.fBtn.hasClass('AnyTime-yr-btn') )
2266					this.yDiv.find('.AnyTime-dec-btn.AnyTime-cur-btn').triggerHandler('click');
2267		    	else if ( this.fBtn.hasClass('AnyTime-era-btn') )
2268					this.yDiv.find('.AnyTime-yr-btn.AnyTime-cur-btn').triggerHandler('click');
2269		    	else if ( this.fBtn.parents('.AnyTime-yrs').length )
2270				{
2271					if ( key == 9 )
2272					{
2273						this.denyTab = false;
2274						return;
2275					}
2276				}
2277		    	else if ( this.fBtn.hasClass('AnyTime-mon-btn') )
2278				{
2279					if ( this.dY )
2280						this.yCur.triggerHandler('click');
2281					else if ( key == 9 )
2282					{
2283						this.denyTab = false;
2284						return;
2285					}
2286				}
2287		    	else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2288		    	{
2289		    		if ( ( key == 9 ) && event.shiftKey ) // Shift+Tab
2290					{
2291						this.denyTab = false;
2292						return;
2293					}
2294		    		else // PageUp
2295		    		{
2296			    		t = new Date(this.time.getTime());
2297				    	if ( event.shiftKey )
2298				    		t.setFullYear(t.getFullYear()-1);
2299				    	else
2300				    	{
2301				    		mo = t.getMonth()-1;
2302		    				if ( t.getDate() > __daysIn[mo] )
2303		    					t.setDate(__daysIn[mo])
2304			    			t.setMonth(mo);
2305				    	}
2306			    		this.keyDateChange(t);
2307		    		}
2308		    	}
2309		    	else if ( this.fBtn.hasClass('AnyTime-hr-btn') )
2310				{
2311		    		t = this.dDoM || this.dMo;
2312					if ( t )
2313						t.AnyTime_clickCurrent();
2314					else if ( this.dY )
2315						this.yCur.triggerHandler('click');
2316					else if ( key == 9 )
2317					{
2318						this.denyTab = false;
2319						return;
2320					}
2321				}
2322		    	else if ( this.fBtn.hasClass('AnyTime-min-ten-btn') )
2323				{
2324		    		t = this.dH || this.dDoM || this.dMo;
2325					if ( t )
2326						t.AnyTime_clickCurrent();
2327					else if ( this.dY )
2328						this.yCur.triggerHandler('click');
2329					else if ( key == 9 )
2330					{
2331						this.denyTab = false;
2332						return;
2333					}
2334				}
2335		    	else if ( this.fBtn.hasClass('AnyTime-min-one-btn') )
2336					this.dM.AnyTime_clickCurrent();
2337		    	else if ( this.fBtn.hasClass('AnyTime-sec-ten-btn') )
2338				{
2339		    		if ( this.dM )
2340		    			t = this.dM.find('.AnyTime-mins-ones');
2341		    		else
2342		    			t = this.dH || this.dDoM || this.dMo;
2343					if ( t )
2344						t.AnyTime_clickCurrent();
2345					else if ( this.dY )
2346						this.yCur.triggerHandler('click');
2347					else if ( key == 9 )
2348					{
2349						this.denyTab = false;
2350						return;
2351					}
2352				}
2353		    	else if ( this.fBtn.hasClass('AnyTime-sec-one-btn') )
2354					this.dS.AnyTime_clickCurrent();
2355		    	else if ( this.fBtn.hasClass('AnyTime-off-btn') )
2356				{
2357		    		if ( this.dS )
2358		    			t = this.dS.find('.AnyTime-secs-ones');
2359		    		else if ( this.dM )
2360		    			t = this.dM.find('.AnyTime-mins-ones');
2361		    		else
2362		    			t = this.dH || this.dDoM || this.dMo;
2363					if ( t )
2364						t.AnyTime_clickCurrent();
2365					else if ( this.dY )
2366						this.yCur.triggerHandler('click');
2367					else if ( key == 9 )
2368					{
2369						this.denyTab = false;
2370						return;
2371					}
2372				}
2373			}
2374		    else if ( ( key == 34 ) || ( key == 9 ) ) // PageDown or Tab
2375		    {
2376		    	if ( this.fBtn.hasClass('AnyTime-mil-btn') )
2377					this.yDiv.find('.AnyTime-cent-btn.AnyTime-cur-btn').triggerHandler('click');
2378		    	else if ( this.fBtn.hasClass('AnyTime-cent-btn') )
2379					this.yDiv.find('.AnyTime-dec-btn.AnyTime-cur-btn').triggerHandler('click');
2380		    	else if ( this.fBtn.hasClass('AnyTime-dec-btn') )
2381					this.yDiv.find('.AnyTime-yr-btn.AnyTime-cur-btn').triggerHandler('click');
2382		    	else if ( this.fBtn.hasClass('AnyTime-yr-btn') )
2383		    	{
2384		    		t = this.yDiv.find('.AnyTime-era-btn.AnyTime-cur-btn');
2385					if ( t.length )
2386						t.triggerHandler('click');
2387					else if ( key == 9 )
2388						this.dismissYDiv(event);
2389		    	}
2390		    	else if ( this.fBtn.hasClass('AnyTime-era-btn') )
2391		    	{
2392		    		if ( key == 9 )
2393		    			this.dismissYDiv(event);
2394		    	}
2395		    	else if ( this.fBtn.hasClass('AnyTime-off-off-btn') )
2396		    	{
2397		    		if ( key == 9 )
2398		    			this.dismissODiv(event);
2399		    	}
2400		    	else if ( this.fBtn.parents('.AnyTime-yrs').length )
2401				{
2402		    		t = this.dDoM || this.dMo || this.dH || this.dM || this.dS || this.dO;
2403					if ( t )
2404						t.AnyTime_clickCurrent();
2405					else if ( key == 9 )
2406					{
2407						this.denyTab = false;
2408						return;
2409					}
2410				}
2411		    	else if ( this.fBtn.hasClass('AnyTime-mon-btn') )
2412				{
2413		    		t = this.dDoM || this.dH || this.dM || this.dS || this.dO;
2414					if ( t )
2415						t.AnyTime_clickCurrent();
2416					else if ( key == 9 )
2417					{
2418						this.denyTab = false;
2419						return;
2420					}
2421				}
2422		    	else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2423		    	{
2424		    		if ( key == 9 ) // Tab
2425		    		{
2426		        		t = this.dH || this.dM || this.dS || this.dO;
2427		    			if ( t )
2428							t.AnyTime_clickCurrent();
2429		    			else
2430						{
2431							this.denyTab = false;
2432							return;
2433						}
2434		    		}
2435		    		else // PageDown
2436		    		{
2437			    		t = new Date(this.time.getTime());
2438				    	if ( event.shiftKey )
2439				    		t.setFullYear(t.getFullYear()+1);
2440				    	else
2441				    	{
2442				    		mo = t.getMonth()+1;
2443		    				if ( t.getDate() > __daysIn[mo] )
2444		    					t.setDate(__daysIn[mo])
2445			    			t.setMonth(mo);
2446				    	}
2447			    		this.keyDateChange(t);
2448		    		}
2449		    	}
2450		    	else if ( this.fBtn.hasClass('AnyTime-hr-btn') )
2451				{
2452		    		t = this.dM || this.dS || this.dO;
2453					if ( t )
2454						t.AnyTime_clickCurrent();
2455					else if ( key == 9 )
2456					{
2457						this.denyTab = false;
2458						return;
2459					}
2460				}
2461		    	else if ( this.fBtn.hasClass('AnyTime-min-ten-btn') )
2462		    		this.dM.find('.AnyTime-mins-ones .AnyTime-cur-btn').triggerHandler('click');
2463		    	else if ( this.fBtn.hasClass('AnyTime-min-one-btn') )
2464				{
2465					t = this.dS || this.dO;
2466					if ( t )
2467						t.AnyTime_clickCurrent();
2468					else if ( key == 9 )
2469					{
2470						this.denyTab = false;
2471						return;
2472					}
2473				}
2474		    	else if ( this.fBtn.hasClass('AnyTime-sec-ten-btn') )
2475		    		this.dS.find('.AnyTime-secs-ones .AnyTime-cur-btn').triggerHandler('click');
2476		    	else if ( this.fBtn.hasClass('AnyTime-sec-one-btn') )
2477				{
2478		    		if ( this.dO )
2479						this.dO.AnyTime_clickCurrent();
2480		    		else if ( key == 9 )
2481					{
2482						this.denyTab = false;
2483						return;
2484					}
2485				}
2486		    	else if ( this.fBtn.hasClass('AnyTime-off-btn') )
2487				{
2488		    		if ( key == 9 )
2489					{
2490						this.denyTab = false;
2491						return;
2492					}
2493				}
2494			}
2495		    else if ( key == 35 ) // END
2496		    {
2497		    	if ( this.fBtn.hasClass('AnyTime-mil-btn') || this.fBtn.hasClass('AnyTime-cent-btn') ||
2498				    this.fBtn.hasClass('AnyTime-dec-btn') || this.fBtn.hasClass('AnyTime-yr-btn') ||
2499				    this.fBtn.hasClass('AnyTime-era-btn') )
2500		    	{
2501		    		t = this.yDiv.find('.AnyTime-ce-btn');
2502		    		if ( ! t.length )
2503		    			t = this.yDiv.find('.AnyTime-yr9-btn');
2504		    		t.triggerHandler('click');
2505		    	}
2506		    	else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2507		    	{
2508		    		t = new Date(this.time.getTime());
2509					t.setDate(1);
2510		    		t.setMonth(t.getMonth()+1);
2511					t.setDate(t.getDate()-1);
2512			    	if ( event.ctrlKey )
2513			    		t.setMonth(11);
2514		    		this.keyDateChange(t);
2515		    	}
2516		    	else if ( this.dS )
2517					this.dS.find('.AnyTime-sec9-btn').triggerHandler('click');
2518		    	else if ( this.dM )
2519					this.dM.find('.AnyTime-min9-btn').triggerHandler('click');
2520				else if ( this.dH )
2521					this.dH.find('.AnyTime-hr23-btn').triggerHandler('click');
2522				else if ( this.dDoM )
2523					this.dDoM.find('.AnyTime-dom-btn-filled:last').triggerHandler('click');
2524				else if ( this.dMo )
2525					this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
2526				else if ( this.dY )
2527					this.yAhead.triggerHandler('click');
2528		    }
2529		    else if ( key == 36 ) // HOME
2530		    {
2531		    	if ( this.fBtn.hasClass('AnyTime-mil-btn') || this.fBtn.hasClass('AnyTime-cent-btn') ||
2532				    this.fBtn.hasClass('AnyTime-dec-btn') || this.fBtn.hasClass('AnyTime-yr-btn') ||
2533				    this.fBtn.hasClass('AnyTime-era-btn') )
2534				{
2535		    		this.yDiv.find('.AnyTime-mil0-btn').triggerHandler('click');
2536		    	}
2537			    else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2538		    	{
2539		    		t = new Date(this.time.getTime());
2540					t.setDate(1);
2541			    	if ( event.ctrlKey )
2542			    		t.setMonth(0);
2543		    		this.keyDateChange(t);
2544		    	}
2545				else if ( this.dY )
2546					this.yCur.triggerHandler('click');
2547				else if ( this.dMo )
2548					this.dMo.find('.AnyTime-mon1-btn').triggerHandler('click');
2549				else if ( this.dDoM )
2550					this.dDoM.find('.AnyTime-dom-btn-filled:first').triggerHandler('click');
2551				else if ( this.dH )
2552					this.dH.find('.AnyTime-hr0-btn').triggerHandler('click');
2553		    	else if ( this.dM )
2554					this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
2555		    	else if ( this.dS )
2556					this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
2557		    }
2558		    else if ( key == 37 ) // left arrow
2559		    {
2560		    	if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2561          {
2562			      t = new Date(this.time.getTime());
2563            t.setDate(t.getDate()-1);
2564		    		this.keyDateChange(t);
2565          }
2566		    	else
2567		    		this.keyBack();
2568		    }
2569		    else if ( key == 38 ) // up arrow
2570		    {
2571		    	if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2572          {
2573			      t = new Date(this.time.getTime());
2574            t.setDate(t.getDate()-7);
2575		    		this.keyDateChange(t);
2576          }
2577		    	else
2578		    		this.keyBack();
2579		    }
2580		    else if ( key == 39 ) // right arrow
2581		    {
2582		    	if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2583          {
2584			      t = new Date(this.time.getTime());
2585            t.setDate(t.getDate()+1);
2586		    		this.keyDateChange(t);
2587          }
2588		    	else
2589		    		this.keyAhead();
2590		    }
2591		    else if ( key == 40 ) // down arrow
2592		    {
2593		    	if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2594         {
2595			      t = new Date(this.time.getTime());
2596            t.setDate(t.getDate()+7);
2597		    		this.keyDateChange(t);
2598          }
2599		    	else
2600		    		this.keyAhead();
2601		    }
2602		    else if ( ( ( key == 86 ) || ( key == 118 ) ) && event.ctrlKey )
2603		    {
2604		    	this.updVal('');
2605		    	setTimeout( function() { _this.showPkr(null); }, 100 );
2606		    	return;
2607		    }
2608		    else
2609    			this.showPkr(null);
2610
2611		    event.preventDefault();
2612
2613		}, // .key()
2614
2615		//---------------------------------------------------------------------
2616		//  .keyAhead() is called by #key when a user presses the right or
2617		//	down arrow.  It moves to the next appropriate button.
2618		//---------------------------------------------------------------------
2619
2620		keyAhead: function()
2621		{
2622		   	if ( this.fBtn.hasClass('AnyTime-mil9-btn') )
2623		   		this.yDiv.find('.AnyTime-cent0-btn').triggerHandler('click');
2624		   	else if ( this.fBtn.hasClass('AnyTime-cent9-btn') )
2625		   		this.yDiv.find('.AnyTime-dec0-btn').triggerHandler('click');
2626		   	else if ( this.fBtn.hasClass('AnyTime-dec9-btn') )
2627		   		this.yDiv.find('.AnyTime-yr0-btn').triggerHandler('click');
2628		   	else if ( this.fBtn.hasClass('AnyTime-yr9-btn') )
2629		   		this.yDiv.find('.AnyTime-bce-btn').triggerHandler('click');
2630		   	else if ( this.fBtn.hasClass('AnyTime-sec9-btn') )
2631		   		{}
2632		   	else if ( this.fBtn.hasClass('AnyTime-sec50-btn') )
2633		   		this.dS.find('.AnyTime-sec0-btn').triggerHandler('click');
2634		   	else if ( this.fBtn.hasClass('AnyTime-min9-btn') )
2635		   	{
2636		   		if ( this.dS )
2637		   			this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
2638		   	}
2639		   	else if ( this.fBtn.hasClass('AnyTime-min50-btn') )
2640		   		this.dM.find('.AnyTime-min0-btn').triggerHandler('click');
2641		   	else if ( this.fBtn.hasClass('AnyTime-hr23-btn') )
2642		   	{
2643		   		if ( this.dM )
2644		   			this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
2645		   		else if ( this.dS )
2646		   			this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
2647		   	}
2648		   	else if ( this.fBtn.hasClass('AnyTime-hr11-btn') )
2649				this.dH.find('.AnyTime-hr12-btn').triggerHandler('click');
2650		   	else if ( this.fBtn.hasClass('AnyTime-mon12-btn') )
2651		   	{
2652		   		if ( this.dDoM )
2653		   			this.dDoM.AnyTime_clickCurrent();
2654		   		else if ( this.dH )
2655		   			this.dH.find('.AnyTime-hr0-btn').triggerHandler('click');
2656		   		else if ( this.dM )
2657		   			this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
2658		   		else if ( this.dS )
2659		   			this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
2660		   	}
2661		   	else if ( this.fBtn.hasClass('AnyTime-yrs-ahead-btn') )
2662		   	{
2663		   		if ( this.dMo )
2664		   			this.dMo.find('.AnyTime-mon1-btn').triggerHandler('click');
2665		   		else if ( this.dH )
2666		   			this.dH.find('.AnyTime-hr0-btn').triggerHandler('click');
2667		   		else if ( this.dM )
2668		   			this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
2669		   		else if ( this.dS )
2670		   			this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
2671		   	}
2672		   	else if ( this.fBtn.hasClass('AnyTime-yr-cur-btn') )
2673		        this.yNext.triggerHandler('click');
2674		   	else
2675				 this.fBtn.next().triggerHandler('click');
2676
2677		}, // .keyAhead()
2678
2679
2680		//---------------------------------------------------------------------
2681		//  .keyBack() is called by #key when a user presses the left or
2682		//	up arrow. It moves to the previous appropriate button.
2683		//---------------------------------------------------------------------
2684
2685		keyBack: function()
2686		{
2687		   	if ( this.fBtn.hasClass('AnyTime-cent0-btn') )
2688		   		this.yDiv.find('.AnyTime-mil9-btn').triggerHandler('click');
2689		   	else if ( this.fBtn.hasClass('AnyTime-dec0-btn') )
2690		   		this.yDiv.find('.AnyTime-cent9-btn').triggerHandler('click');
2691		   	else if ( this.fBtn.hasClass('AnyTime-yr0-btn') )
2692		   		this.yDiv.find('.AnyTime-dec9-btn').triggerHandler('click');
2693		   	else if ( this.fBtn.hasClass('AnyTime-bce-btn') )
2694			   		this.yDiv.find('.AnyTime-yr9-btn').triggerHandler('click');
2695		   	else if ( this.fBtn.hasClass('AnyTime-yr-cur-btn') )
2696		        this.yPrior.triggerHandler('click');
2697		   	else if ( this.fBtn.hasClass('AnyTime-mon1-btn') )
2698		   	{
2699		   		if ( this.dY )
2700		   			this.yCur.triggerHandler('click');
2701		   	}
2702		   	else if ( this.fBtn.hasClass('AnyTime-hr0-btn') )
2703		   	{
2704		   		if ( this.dDoM )
2705		   			this.dDoM.AnyTime_clickCurrent();
2706		   		else if ( this.dMo )
2707		   			this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
2708		   		else if ( this.dY )
2709		   			this.yNext.triggerHandler('click');
2710		   	}
2711		   	else if ( this.fBtn.hasClass('AnyTime-hr12-btn') )
2712		   		 this.dH.find('.AnyTime-hr11-btn').triggerHandler('click');
2713		   	else if ( this.fBtn.hasClass('AnyTime-min00-btn') )
2714		   	{
2715		   		if ( this.dH )
2716		   			this.dH.find('.AnyTime-hr23-btn').triggerHandler('click');
2717		   		else if ( this.dDoM )
2718		   			this.dDoM.AnyTime_clickCurrent();
2719		   		else if ( this.dMo )
2720		   			this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
2721		   		else if ( this.dY )
2722		   			this.yNext.triggerHandler('click');
2723		   	}
2724		   	else if ( this.fBtn.hasClass('AnyTime-min0-btn') )
2725		   		 this.dM.find('.AnyTime-min50-btn').triggerHandler('click');
2726		   	else if ( this.fBtn.hasClass('AnyTime-sec00-btn') )
2727		   	{
2728		   		if ( this.dM )
2729		   			this.dM.find('.AnyTime-min9-btn').triggerHandler('click');
2730		   		else if ( this.dH )
2731		   			this.dH.find('.AnyTime-hr23-btn').triggerHandler('click');
2732		   		else if ( this.dDoM )
2733		   			this.dDoM.AnyTime_clickCurrent();
2734		   		else if ( this.dMo )
2735		   			this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
2736		   		else if ( this.dY )
2737		   			this.yNext.triggerHandler('click');
2738		   	}
2739		   	else if ( this.fBtn.hasClass('AnyTime-sec0-btn') )
2740		   		 this.dS.find('.AnyTime-sec50-btn').triggerHandler('click');
2741		   	else
2742				 this.fBtn.prev().triggerHandler('click');
2743
2744		}, // .keyBack()
2745
2746		//---------------------------------------------------------------------
2747		//  .keyDateChange() is called by #key when an direction key
2748		//	(arrows/page/etc) is pressed while the Day-of-Month calendar has
2749		//	focus. The current day is adjusted accordingly.
2750		//---------------------------------------------------------------------
2751
2752		keyDateChange: function( newDate )
2753		{
2754			if ( this.fBtn.hasClass('AnyTime-dom-btn') )
2755			{
2756				this.set(newDate);
2757				this.upd(null);
2758				this.setFocus( this.dDoM.find('.AnyTime-cur-btn') );
2759			}
2760		},
2761
2762		//---------------------------------------------------------------------
2763		//  .makeCloak() is called by .askOffset() and .askYear() to create
2764		//  a cloak div.
2765		//---------------------------------------------------------------------
2766
2767		makeCloak: function()
2768		{
2769			if ( ! this.cloak )
2770			{
2771		      this.cloak = $('<div class="AnyTime-cloak"></div>');
2772		      this.div.append( this.cloak );
2773		      this.cloak.click(
2774		        function(e)
2775		        {
2776		        	if ( _this.oDiv && _this.oDiv.is(":visible") )
2777		        		_this.dismissODiv(e);
2778		        	else
2779		        		_this.dismissYDiv(e);
2780		        });
2781		    }
2782			else
2783		      this.cloak.show();
2784		},
2785
2786		//---------------------------------------------------------------------
2787		//  makeDate() returns a Date object for the parameter as follows.
2788    //  Strings are parsed using the converter and numbers are assumed
2789    //  to be milliseconds.
2790		//---------------------------------------------------------------------
2791
2792		makeDate: function(time)
2793    {
2794      if ( typeof time == 'number' )
2795        time = new Date(time);
2796      else if ( typeof time == 'string' )
2797        time = this.conv.parse( time );
2798      if ( 'getTime' in time )
2799        return time;
2800      throw 'cannot make a Date from ' + time;
2801    },
2802
2803		//---------------------------------------------------------------------
2804		//  .newHour() is called when a user clicks an hour value.
2805		//  It changes the date and updates the text field.
2806		//---------------------------------------------------------------------
2807
2808		newHour: function( event )
2809		{
2810		    var h;
2811		    var t;
2812		    var elem = $(event.target);
2813		    if ( elem.hasClass("AnyTime-out-btn") )
2814		    	return;
2815		    if ( ! this.twelveHr )
2816		      h = Number(elem.text());
2817		    else
2818		    {
2819		      var str = elem.text();
2820		      t = str.indexOf('a');
2821		      if ( t < 0 )
2822		      {
2823		        t = Number(str.substr(0,str.indexOf('p')));
2824		        h = ( (t==12) ? 12 : (t+12) );
2825		      }
2826		      else
2827		      {
2828		        t = Number(str.substr(0,t));
2829		        h = ( (t==12) ? 0 : t );
2830		      }
2831		    }
2832		    t = new Date(this.time.getTime());
2833		    t.setHours(h);
2834		    this.set(t);
2835		    this.upd(elem);
2836
2837		}, // .newHour()
2838
2839		//---------------------------------------------------------------------
2840		//  .newOffset() is called when a user clicks the UTC offset (timezone)
2841		//  (or +/- button) to shift the year.  It changes the date and updates
2842		//  the text field.
2843		//---------------------------------------------------------------------
2844
2845		newOffset: function( event )
2846		{
2847		    if ( event.target == this.oSel[0] )
2848			    this.askOffset(event);
2849		    else
2850		    {
2851		      this.upd(this.oCur);
2852		    }
2853		},
2854
2855		//---------------------------------------------------------------------
2856		//  .newOPos() is called internally whenever a user clicks an offset
2857		//  selection value.  It changes the date and updates the text field.
2858		//---------------------------------------------------------------------
2859
2860		newOPos: function( event )
2861		{
2862		    var elem = $(event.target);
2863            this.offMin = elem[0].AnyTime_offMin;
2864            this.offSI = elem[0].AnyTime_offSI;
2865		    var t = new Date(this.time.getTime());
2866		    this.set(t);
2867		    this.updODiv(elem);
2868
2869		}, // .newOPos()
2870
2871		//---------------------------------------------------------------------
2872		//  .newYear() is called when a user clicks a year (or one of the
2873		//	"arrows") to shift the year.  It changes the date and updates the
2874		//	text field.
2875		//---------------------------------------------------------------------
2876
2877		newYear: function( event )
2878		{
2879		    var elem = $(event.target);
2880		    if ( elem.hasClass("AnyTime-out-btn") )
2881		    	return;
2882		    var txt = elem.text();
2883		    if ( ( txt == '<' ) || ( txt == '&lt;' ) )
2884		      this.askYear(event);
2885		    else if ( ( txt == '>' ) || ( txt == '&gt;' ) )
2886		      this.askYear(event);
2887		    else
2888		    {
2889		      var t = new Date(this.time.getTime());
2890		      t.setFullYear(Number(txt));
2891		      this.set(t);
2892		      this.upd(this.yCur);
2893		    }
2894		},
2895
2896		//---------------------------------------------------------------------
2897		//  .newYPos() is called internally whenever a user clicks a year
2898		//  selection value.  It changes the date and updates the text field.
2899		//---------------------------------------------------------------------
2900
2901		newYPos: function( event )
2902		{
2903		    var elem = $(event.target);
2904		    if ( elem.hasClass("AnyTime-out-btn") )
2905		    	return;
2906
2907		    var era = 1;
2908		    var year = this.time.getFullYear();
2909		    if ( year < 0 )
2910		    {
2911		      era = (-1);
2912		      year = 0 - year;
2913		    }
2914		    year = AnyTime.pad( year, 4 );
2915		    if ( elem.hasClass('AnyTime-mil-btn') )
2916		      year = elem.html() + year.substring(1,4);
2917		    else if ( elem.hasClass('AnyTime-cent-btn') )
2918		      year = year.substring(0,1) + elem.html() + year.substring(2,4);
2919		    else if ( elem.hasClass('AnyTime-dec-btn') )
2920		      year = year.substring(0,2) + elem.html() + year.substring(3,4);
2921		    else
2922		      year = year.substring(0,3) + elem.html();
2923		    if ( year == '0000' )
2924		      year = 1;
2925		    var t = new Date(this.time.getTime());
2926		    t.setFullYear( era * year );
2927		    this.set(t);
2928		    this.updYDiv(elem);
2929
2930		}, // .newYPos()
2931
2932		//---------------------------------------------------------------------
2933		//  .onReady() initializes the picker after the page has loaded.
2934		//---------------------------------------------------------------------
2935
2936		onReady: function()
2937		{
2938			this.lostFocus = true;
2939			if ( ! this.pop )
2940				this.upd(null);
2941			else
2942			{
2943				if ( this.div.parent() != document.body )
2944					this.div.appendTo( document.body );
2945			}
2946		},
2947
2948		//---------------------------------------------------------------------
2949		//  .pos() positions the picker, such as when it is displayed or
2950		//	when the window is resized.
2951		//---------------------------------------------------------------------
2952
2953		pos: function(event) // note: event is ignored but this is a handler
2954		{
2955		    if ( this.pop )
2956		    {
2957		      var off = this.inp.offset();
2958		      var bodyWidth = $(document.body).outerWidth(true);
2959		      var pickerWidth = this.div.outerWidth(true);
2960		      var left = off.left;
2961		      if ( left + pickerWidth > bodyWidth - 20 )
2962		        left = bodyWidth - ( pickerWidth + 20 );
2963		      var top = off.top - this.div.outerHeight(true);
2964		      if ( top < 0 )
2965		        top = off.top + this.inp.outerHeight(true);
2966		      this.div.css( { top: String(top)+'px', left: String(left<0?0:left)+'px' } );
2967		    }
2968
2969		    var wOff = this.div.offset();
2970
2971		    if ( this.oDiv && this.oDiv.is(":visible") )
2972		    {
2973		      var oOff = this.oLab.offset();
2974		      if ( this.div.css('position') == 'absolute' )
2975		      {
2976		    	  oOff.top -= wOff.top;
2977		          oOff.left = oOff.left - wOff.left;
2978		    	  wOff = { top: 0, left: 0 };
2979		      }
2980		      var oW = this.oDiv.outerWidth(true);
2981		      var wW = this.div.outerWidth(true);
2982		      if ( oOff.left + oW > wOff.left + wW )
2983		      {
2984		    	  oOff.left = (wOff.left+wW)-oW;
2985		    	  if ( oOff.left < 2 )
2986		    		  oOff.left = 2;
2987		      }
2988
2989		      var oH = this.oDiv.outerHeight(true);
2990		      var wH = this.div.outerHeight(true);
2991		      oOff.top += this.oLab.outerHeight(true);
2992		      if ( oOff.top + oH > wOff.top + wH )
2993		    	  oOff.top = oOff.top - oH;
2994		      if ( oOff.top < wOff.top )
2995		    	  oOff.top = wOff.top;
2996
2997		      this.oDiv.css( { top: oOff.top+'px', left: oOff.left+'px' } ) ;
2998		    }
2999
3000		    else if ( this.yDiv && this.yDiv.is(":visible") )
3001		    {
3002		      var yOff = this.yLab.offset();
3003		      if ( this.div.css('position') == 'absolute' )
3004		      {
3005		    	  yOff.top -= wOff.top;
3006		          yOff.left = yOff.left - wOff.left;
3007		    	  wOff = { top: 0, left: 0 };
3008		      }
3009		      yOff.left += ( (this.yLab.outerWidth(true)-this.yDiv.outerWidth(true)) / 2 );
3010		      this.yDiv.css( { top: yOff.top+'px', left: yOff.left+'px' } ) ;
3011		    }
3012
3013		    if ( this.cloak )
3014			  this.cloak.css( {
3015		      	top: wOff.top+'px',
3016		      	left: wOff.left+'px',
3017		      	height: String(this.div.outerHeight(true)-2)+'px',
3018		    	width: String(this.div.outerWidth(true)-2)+'px'
3019		    	} );
3020
3021		}, // .pos()
3022
3023		//---------------------------------------------------------------------
3024		//  .set() changes the current time.  It returns true if the new
3025		//	time is within the allowed range (if any).
3026		//---------------------------------------------------------------------
3027
3028		set: function(newTime)
3029		{
3030		    var t = newTime.getTime();
3031		    if ( this.earliest && ( t < this.earliest.getTime() ) )
3032		      this.time = new Date(this.earliest.getTime());
3033		    else if ( this.latest && ( t > this.latest.getTime() ) )
3034		      this.time = new Date(this.latest.getTime());
3035		    else
3036		      this.time = newTime;
3037		},
3038
3039		//---------------------------------------------------------------------
3040		//  .setCurrent() changes the current time.
3041		//---------------------------------------------------------------------
3042
3043		setCurrent: function(newTime)
3044		{
3045        this.set(this.makeDate(newTime));
3046        this.upd(null);
3047		},
3048
3049		//---------------------------------------------------------------------
3050		//  .setEarliest() changes the earliest time.
3051		//---------------------------------------------------------------------
3052
3053		setEarliest: function(newTime)
3054		{
3055        this.earliest = this.makeDate( newTime );
3056        this.set(this.time);
3057        this.upd(null);
3058		},
3059
3060		//---------------------------------------------------------------------
3061		//  .setLatest() changes the latest time.
3062		//---------------------------------------------------------------------
3063
3064		setLatest: function(newTime)
3065		{
3066        this.latest = this.makeDate( newTime );
3067        this.set(this.time);
3068        this.upd(null);
3069		},
3070
3071		//---------------------------------------------------------------------
3072		//  .showPkr() displays the picker and sets the focus psuedo-
3073		//	element. The current value in the input field is used to initialize
3074		//	the picker.
3075		//---------------------------------------------------------------------
3076
3077		showPkr: function(event)
3078		{
3079			try
3080		    {
3081		      this.time = this.conv.parse(this.inp.val());
3082		      this.offMin = this.conv.getUtcParseOffsetCaptured();
3083		      this.offSI = this.conv.getUtcParseOffsetSubIndex();
3084		    }
3085		    catch ( e )
3086		    {
3087		      this.time = new Date();
3088		    }
3089		    this.set(this.time);
3090		    this.upd(null);
3091
3092		    fBtn = null;
3093		    var cb = '.AnyTime-cur-btn:first';
3094		    if ( this.dDoM )
3095		    	fBtn = this.dDoM.find(cb);
3096			else if ( this.yCur )
3097				fBtn = this.yCur;
3098			else if ( this.dMo )
3099				fBtn = this.dMo.find(cb);
3100			else if ( this.dH )
3101				fBtn = this.dH.find(cb);
3102			else if ( this.dM )
3103				fBtn = this.dM.find(cb);
3104			else if ( this.dS )
3105				fBtn = this.dS.find(cb);
3106
3107      this.setFocus(fBtn);
3108      this.pos(event);
3109
3110		}, // .showPkr()
3111
3112		//---------------------------------------------------------------------
3113		//  .upd() updates the picker's appearance.  It is called after
3114		//	most events to make the picker reflect the currently-selected
3115		//	values. fBtn is the psuedo-button to be given focus.
3116		//---------------------------------------------------------------------
3117
3118		upd: function(fBtn)
3119		{
3120		    var cmpLo = new Date(this.time.getTime());
3121		    cmpLo.setMonth(0,1);
3122		    cmpLo.setHours(0,0,0,0);
3123		    var cmpHi = new Date(this.time.getTime());
3124		    cmpHi.setMonth(11,31);
3125		    cmpHi.setHours(23,59,59,999);
3126        var earliestTime = this.earliest && this.earliest.getTime();
3127        var latestTime = this.latest && this.latest.getTime();
3128
3129		    //  Update year.
3130
3131		    var current = this.time.getFullYear();
3132		    if ( this.earliest && this.yPast )
3133		    {
3134				  cmpHi.setFullYear(current-2);
3135			      if ( cmpHi.getTime() < this.earliestTime )
3136              this.yPast.addClass('AnyTime-out-btn ui-state-disabled');
3137            else
3138              this.yPast.removeClass('AnyTime-out-btn ui-state-disabled');
3139          }
3140          if ( this.yPrior )
3141          {
3142		      this.yPrior.text(AnyTime.pad((current==1)?(-1):(current-1),4));
3143		      if ( this.earliest )
3144		      {
3145				  cmpHi.setFullYear(current-1);
3146			      if ( cmpHi.getTime() < this.earliestTime )
3147			    	  this.yPrior.addClass('AnyTime-out-btn ui-state-disabled');
3148			      else
3149			    	  this.yPrior.removeClass('AnyTime-out-btn ui-state-disabled');
3150		      }
3151		    }
3152		    if ( this.yCur )
3153		      this.yCur.text(AnyTime.pad(current,4));
3154		    if ( this.yNext )
3155		    {
3156		      this.yNext.text(AnyTime.pad((current==-1)?1:(current+1),4));
3157		      if ( this.latest )
3158		      {
3159			      cmpLo.setFullYear(current+1);
3160			      if ( cmpLo.getTime() > this.latestTime )
3161			    	  this.yNext.addClass('AnyTime-out-btn ui-state-disabled');
3162			      else
3163			    	  this.yNext.removeClass('AnyTime-out-btn ui-state-disabled');
3164		      }
3165		    }
3166		    if ( this.latest && this.yAhead )
3167		    {
3168				  cmpLo.setFullYear(current+2);
3169			      if ( cmpLo.getTime() > this.latestTime )
3170			    	  this.yAhead.addClass('AnyTime-out-btn ui-state-disabled');
3171			      else
3172			    	  this.yAhead.removeClass('AnyTime-out-btn ui-state-disabled');
3173		    }
3174
3175		    //  Update month.
3176
3177		    cmpLo.setFullYear( this.time.getFullYear() );
3178		    cmpHi.setFullYear( this.time.getFullYear() );
3179		    var i = 0;
3180		    current = this.time.getMonth();
3181		    $('#'+this.id+' .AnyTime-mon-btn').each(
3182		      function()
3183		      {
3184		    	cmpLo.setMonth(i);
3185				cmpHi.setDate(1);
3186		    	cmpHi.setMonth(i+1);
3187				cmpHi.setDate(0);
3188		        $(this).AnyTime_current( i == current,
3189		        		((!_this.earliest)||(cmpHi.getTime()>=earliestTime)) &&
3190		        		((!_this.latest)||(cmpLo.getTime()<=latestTime)) );
3191		        i++;
3192		      } );
3193
3194		    //  Update days.
3195
3196		    cmpLo.setFullYear( this.time.getFullYear() );
3197		    cmpHi.setFullYear( this.time.getFullYear() );
3198		    cmpLo.setMonth( this.time.getMonth() );
3199		    cmpHi.setMonth( this.time.getMonth(), 1 );
3200		    current = this.time.getDate();
3201		    var currentMonth = this.time.getMonth();
3202		    var lastLoDate = -1;
3203		    var dow1 = cmpLo.getDay();
3204		    if ( this.fDOW > dow1 )
3205		      dow1 += 7;
3206		    var wom = 0, dow=0;
3207		    $('#'+this.id+' .AnyTime-wk').each(
3208		      function()
3209		      {
3210		        dow = _this.fDOW;
3211		        $(this).children().each(
3212		          function()
3213		          {
3214		        	  if ( dow - _this.fDOW < 7 )
3215		        	  {
3216		        		  var td = $(this);
3217				          if ( ((wom==0)&&(dow<dow1)) || (cmpLo.getMonth()!=currentMonth) )
3218				          {
3219				            td.html('&#160;');
3220				            td.removeClass('AnyTime-dom-btn-filled AnyTime-cur-btn ui-state-default ui-state-highlight');
3221				            td.addClass('AnyTime-dom-btn-empty');
3222				            if ( wom ) // not first week
3223				            {
3224				            	if ( ( cmpLo.getDate() == 1 ) && ( dow != 0 ) )
3225				            		td.addClass('AnyTime-dom-btn-empty-after-filled');
3226				            	else
3227				            		td.removeClass('AnyTime-dom-btn-empty-after-filled');
3228				            	if ( cmpLo.getDate() <= 7 )
3229				            		td.addClass('AnyTime-dom-btn-empty-below-filled');
3230				            	else
3231				            		td.removeClass('AnyTime-dom-btn-empty-below-filled');
3232				                cmpLo.setDate(cmpLo.getDate()+1);
3233				                cmpHi.setDate(cmpHi.getDate()+1);
3234				            }
3235				            else // first week
3236				            {
3237				            	td.addClass('AnyTime-dom-btn-empty-above-filled');
3238				            	if ( dow == dow1 - 1 )
3239				            		td.addClass('AnyTime-dom-btn-empty-before-filled');
3240				            	else
3241				            		td.removeClass('AnyTime-dom-btn-empty-before-filled');
3242				            }
3243				            td.addClass('ui-state-default ui-state-disabled');
3244				          }
3245				          else
3246				          {
3247				            // Brazil daylight savings time sometimes results in
3248				            // midnight being the same day twice. This skips the
3249				            //  second one.
3250                    if ( ( i = cmpLo.getDate() ) == lastLoDate )
3251                      cmpLo.setDate( ++i );
3252                    lastLoDate = i;
3253
3254				            td.text(i);
3255				            td.removeClass('AnyTime-dom-btn-empty AnyTime-dom-btn-empty-above-filled AnyTime-dom-btn-empty-before-filled '+
3256				            				'AnyTime-dom-btn-empty-after-filled AnyTime-dom-btn-empty-below-filled ' +
3257				            				'ui-state-default ui-state-disabled');
3258				            td.addClass('AnyTime-dom-btn-filled ui-state-default');
3259				            td.AnyTime_current( i == current,
3260					        		((!_this.earliest)||(cmpHi.getTime()>=earliestTime)) &&
3261					        		((!_this.latest)||(cmpLo.getTime()<=latestTime)) );
3262				            cmpLo.setDate(i+1);
3263				            cmpHi.setDate(i+1);
3264				          }
3265		        	  }
3266		              dow++;
3267		          } );
3268		          wom++;
3269		      } );
3270
3271		    //  Update hour.
3272
3273		    cmpLo.setFullYear( this.time.getFullYear() );
3274		    cmpHi.setFullYear( this.time.getFullYear() );
3275		    cmpLo.setMonth( this.time.getMonth(), this.time.getDate() );
3276		    cmpHi.setMonth( this.time.getMonth(), this.time.getDate() );
3277		    var not12 = ! this.twelveHr;
3278        var hr = this.time.getHours();
3279		    $('#'+this.id+' .AnyTime-hr-btn').each(
3280		      function()
3281		      {
3282            var html = this.innerHTML;
3283            var i;
3284            if ( not12 )
3285              i = Number(html);
3286            else
3287            {
3288              i = Number(html.substring(0,html.length-2) );
3289              if ( html.charAt(html.length-2) == 'a' )
3290              {
3291                if ( i == 12 )
3292                  i = 0;
3293              }
3294              else if ( i < 12 )
3295                i += 12;
3296            }
3297                cmpLo.setHours(i);
3298                cmpHi.setHours(i);
3299            $(this).AnyTime_current( hr == i,
3300		        	((!_this.earliest)||(cmpHi.getTime()>=earliestTime)) &&
3301		        		((!_this.latest)||(cmpLo.getTime()<=latestTime)) );
3302            if ( i < 23 )
3303		          cmpLo.setHours( cmpLo.getHours()+1 );
3304		      } );
3305
3306		    //  Update minute.
3307
3308        cmpLo.setHours( this.time.getHours() );
3309        cmpHi.setHours( this.time.getHours(), 9 );
3310		    var units = this.time.getMinutes();
3311		    var tens = String(Math.floor(units/10));
3312		    var ones = String(units % 10);
3313		    $('#'+this.id+' .AnyTime-min-ten-btn:not(.AnyTime-min-ten-btn-empty)').each(
3314		      function()
3315		      {
3316		        $(this).AnyTime_current( this.innerHTML == tens,
3317		        		((!_this.earliest)||(cmpHi.getTime()>=earliestTime)) &&
3318		        		((!_this.latest)||(cmpLo.getTime()<=latestTime)) );
3319            if ( cmpLo.getMinutes() < 50 )
3320            {
3321		        cmpLo.setMinutes( cmpLo.getMinutes()+10 );
3322		        cmpHi.setMinutes( cmpHi.getMinutes()+10 );
3323            }
3324		      } );
3325		    cmpLo.setMinutes( Math.floor(this.time.getMinutes()/10)*10 );
3326		    cmpHi.setMinutes( Math.floor(this.time.getMinutes()/10)*10 );
3327		    $('#'+this.id+' .AnyTime-min-one-btn:not(.AnyTime-min-one-btn-empty)').each(
3328		      function()
3329		      {
3330		        $(this).AnyTime_current( this.innerHTML == ones,
3331		        		((!_this.earliest)||(cmpHi.getTime()>=earliestTime)) &&
3332		        		((!_this.latest)||(cmpLo.getTime()<=latestTime)) );
3333		        cmpLo.setMinutes( cmpLo.getMinutes()+1 );
3334		        cmpHi.setMinutes( cmpHi.getMinutes()+1 );
3335		      } );
3336
3337		    //  Update second.
3338
3339		    cmpLo.setMinutes( this.time.getMinutes() );
3340		    cmpHi.setMinutes( this.time.getMinutes(), 9 );
3341		    units = this.time.getSeconds();
3342		    tens = String(Math.floor(units/10));
3343		    ones = String(units % 10);
3344		    $('#'+this.id+' .AnyTime-sec-ten-btn:not(.AnyTime-sec-ten-btn-empty)').each(
3345		      function()
3346		      {
3347		        $(this).AnyTime_current( this.innerHTML == tens,
3348		        		((!_this.earliest)||(cmpHi.getTime()>=earliestTime)) &&
3349		        		((!_this.latest)||(cmpLo.getTime()<=latestTime)) );
3350            if ( cmpLo.getSeconds() < 50 )
3351            {
3352		        cmpLo.setSeconds( cmpLo.getSeconds()+10 );
3353		        cmpHi.setSeconds( cmpHi.getSeconds()+10 );
3354            }
3355		      } );
3356		    cmpLo.setSeconds( Math.floor(this.time.getSeconds()/10)*10 );
3357		    cmpHi.setSeconds( Math.floor(this.time.getSeconds()/10)*10 );
3358		    $('#'+this.id+' .AnyTime-sec-one-btn:not(.AnyTime-sec-one-btn-empty)').each(
3359		      function()
3360		      {
3361		        $(this).AnyTime_current( this.innerHTML == ones,
3362		        		((!_this.earliest)||(cmpHi.getTime()>=earliestTime)) &&
3363		        		((!_this.latest)||(cmpLo.getTime()<=latestTime)) );
3364		        cmpLo.setSeconds( cmpLo.getSeconds()+1 );
3365		        cmpHi.setSeconds( cmpHi.getSeconds()+1 );
3366		      } );
3367
3368		    //  Update offset (time zone).
3369
3370		    if ( this.oConv )
3371		    {
3372			    this.oConv.setUtcFormatOffsetAlleged(this.offMin);
3373			    this.oConv.setUtcFormatOffsetSubIndex(this.offSI);
3374			    var tzs = this.oConv.format(this.time);
3375			    this.oCur.html( tzs );
3376		    }
3377
3378		    //	Set the focus element, then size the picker according to its
3379		    //	components, show the changes, and invoke Ajax if desired.
3380
3381		    if ( fBtn )
3382		    	this.setFocus(fBtn);
3383
3384            this.conv.setUtcFormatOffsetAlleged(this.offMin);
3385		    this.conv.setUtcFormatOffsetSubIndex(this.offSI);
3386		    this.updVal(this.conv.format(this.time));
3387		    this.div.show();
3388
3389        if ( this.dO ) // fit offset button
3390        {
3391          this.oCur.css('width','0');
3392          var curW = this.dT.width()-this.oMinW;
3393          if ( curW < 40 )
3394            curW = 40;
3395          this.oCur.css('width',String(curW)+'px');
3396        }
3397
3398		    if ( ! this.pop )
3399		      this.ajax();
3400
3401		}, // .upd()
3402
3403		//---------------------------------------------------------------------
3404		//  .updODiv() updates the UTC offset selector's appearance.  It is
3405		//	called after most events to make the picker reflect the currently-
3406		//	selected values. fBtn is the psuedo-button to be given focus.
3407		//---------------------------------------------------------------------
3408
3409		updODiv: function(fBtn)
3410		{
3411            var cur, matched = false, def = null;
3412		    this.oDiv.find('.AnyTime-off-off-btn').each(
3413		      function()
3414		      {
3415		    	  if ( this.AnyTime_offMin == _this.offMin )
3416		    	  {
3417		    		  if ( this.AnyTime_offSI == _this.offSI )
3418		    			  $(this).AnyTime_current(matched=true,true);
3419		    		  else
3420		    	      {
3421		    			  $(this).AnyTime_current(false,true);
3422		    			  if ( def == null )
3423			    			  def = $(this);
3424		    	      }
3425		    	  }
3426		    	  else
3427	    			  $(this).AnyTime_current(false,true);
3428		      } );
3429		    if ( ( ! matched ) && ( def != null ) )
3430		    	def.AnyTime_current(true,true);
3431
3432		    //  Show change
3433
3434            this.conv.setUtcFormatOffsetAlleged(this.offMin);
3435            this.conv.setUtcFormatOffsetSubIndex(this.offSI);
3436		    this.updVal(this.conv.format(this.time));
3437		    this.upd(fBtn);
3438
3439		}, // .updODiv()
3440
3441		//---------------------------------------------------------------------
3442		//  .updYDiv() updates the year selector's appearance.  It is
3443		//	called after most events to make the picker reflect the currently-
3444		//	selected values. fBtn is the psuedo-button to be given focus.
3445		//---------------------------------------------------------------------
3446
3447		updYDiv: function(fBtn)
3448		{
3449		    var i, legal;
3450			var era = 1;
3451		    var yearValue = this.time.getFullYear();
3452		    if ( yearValue < 0 )
3453		    {
3454		      era = (-1);
3455		      yearValue = 0 - yearValue;
3456		    }
3457		    yearValue = AnyTime.pad( yearValue, 4 );
3458		    var eY = _this.earliest && _this.earliest.getFullYear();
3459		    var lY = _this.latest && _this.latest.getFullYear();
3460
3461		    i = 0;
3462		    this.yDiv.find('.AnyTime-mil-btn').each(
3463		      function()
3464		      {
3465		    	legal = ( ((!_this.earliest)||(era*(i+(era<0?0:999))>=eY)) && ((!_this.latest)||(era*(i+(era>0?0:999))<=lY)) );
3466		        $(this).AnyTime_current( this.innerHTML == yearValue.substring(0,1), legal );
3467		        i += 1000;
3468		      } );
3469
3470		    i = (Math.floor(yearValue/1000)*1000);
3471		    this.yDiv.find('.AnyTime-cent-btn').each(
3472		      function()
3473		      {
3474			    	legal = ( ((!_this.earliest)||(era*(i+(era<0?0:99))>=eY)) && ((!_this.latest)||(era*(i+(era>0?0:99))<=lY)) );
3475		        $(this).AnyTime_current( this.innerHTML == yearValue.substring(1,2), legal );
3476		        i += 100;
3477		      } );
3478
3479		    i = (Math.floor(yearValue/100)*100);
3480		    this.yDiv.find('.AnyTime-dec-btn').each(
3481		      function()
3482		      {
3483			    	legal = ( ((!_this.earliest)||(era*(i+(era<0?0:9))>=eY)) && ((!_this.latest)||(era*(i+(era>0?0:9))<=lY)) );
3484		        $(this).AnyTime_current( this.innerHTML == yearValue.substring(2,3), legal );
3485		        i += 10;
3486		      } );
3487
3488		    i = (Math.floor(yearValue/10)*10);
3489		    this.yDiv.find('.AnyTime-yr-btn').each(
3490		      function()
3491		      {
3492			    legal = ( ((!_this.earliest)||(era*i>=eY)) && ((!_this.latest)||(era*i<=lY)) );
3493		        $(this).AnyTime_current( this.innerHTML == yearValue.substring(3), legal );
3494		        i += 1;
3495	          } );
3496
3497		    this.yDiv.find('.AnyTime-bce-btn').each(
3498		      function()
3499		      {
3500		    	  $(this).AnyTime_current( era < 0, (!_this.earliest) || ( _this.earliest.getFullYear() < 0 ) );
3501		      } );
3502		    this.yDiv.find('.AnyTime-ce-btn').each(
3503		      function()
3504		      {
3505		    	$(this).AnyTime_current( era > 0, (!_this.latest) || ( _this.latest.getFullYear() > 0 ) );
3506		      } );
3507
3508		    //  Show change
3509
3510            this.conv.setUtcFormatOffsetAlleged(this.offMin);
3511            this.conv.setUtcFormatOffsetSubIndex(this.offSI);
3512		    this.updVal(this.conv.format(this.time));
3513		    this.upd(fBtn);
3514
3515		}, // .updYDiv()
3516
3517		//---------------------------------------------------------------------
3518		//  .updVal() updates the input value, but only if it's different
3519		//	than the previous value. It also triggers a change() event if
3520		//	the value is updated.
3521		//---------------------------------------------------------------------
3522
3523		updVal: function(val)
3524		{
3525		    if ( this.inp.val() != val ) {
3526		      this.inp.val(val);
3527		      this.inp.change();
3528          }
3529    }
3530
3531	}; // __pickers[id] = ...
3532	__pickers[id].initialize(id);
3533
3534} // AnyTime.picker =
3535
3536//=============================================================================
3537//  AnyTime.setCurrent()
3538//
3539//  Updates the current date/time for the picker attached to a specified
3540//  text field.  This also sets the value of the text field.
3541//=============================================================================
3542
3543AnyTime.setCurrent = function( id, newTime )
3544{
3545  __pickers[id].setCurrent(newTime)
3546};
3547
3548
3549//=============================================================================
3550//  AnyTime.setEarliest()
3551//
3552//  Updates the earliest date/time for the picker attached to a specified
3553//  text field.
3554//=============================================================================
3555
3556AnyTime.setEarliest = function( id, newTime )
3557{
3558  __pickers[id].setEarliest(newTime)
3559};
3560
3561
3562//=============================================================================
3563//  AnyTime.setLatest()
3564//
3565//  Updates the latest date/time for the picker attached to a specified
3566//  text field.
3567//=============================================================================
3568
3569AnyTime.setLatest = function( id, newTime )
3570{
3571  __pickers[id].setLatest(newTime)
3572};
3573
3574
3575})(jQuery); // function($)...
3576
3577
3578//
3579//  END OF FILE
3580//
3581
3582

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.