PageSourceSearch

https://qnainternational.com/vendor/jcountdown/jquery.jcountdown.js

js qnainternational.com collected 2026-10-07 03:27:57 UTC 24,622 bytes, 910 lines download raw bytes

1(function($) {
2$.fn.countdown = function( method /*, options*/ ) {
3
4	var msPerHr = 3600000,
5		secPerYear = 31557600,
6		secPerMonth = 2629800, 
7		secPerWeek = 604800,
8		secPerDay = 86400,
9		secPerHr = 3600,
10		secPerMin = 60,
11		secPerSec = 1,
12        rTemplateTokens = /%y|%m|%w|%d|%h|%i|%s/g,
13		rDigitGlobal = /\d/g,
14		localNumber = function( numToConvert, settings ) {
15			
16			var arr = numToConvert.toString().match(rDigitGlobal),
17				localeNumber = "";
18			
19			$.each( arr, function(i,num) {
20				num = Number(num);				
21				localeNumber += (""+ settings.digits[num]) || ""+num;
22			});
23			
24			return localeNumber;
25		},
26		generateTemplateCustom = function( settings ) {
27			var template = settings.template,
28				$parent = $('<div>'),
29				$timeWrapElement = settings.dom.$time.addClass( settings.timeWrapClass ),
30				$textWrapElement = $("<"+settings.textWrapElement+">").addClass( settings.textWrapClass ),
31				
32				sep = settings.timeSeparator,
33				
34				yearsLeft = settings.yearsLeft,
35				monthsLeft = settings.monthsLeft,
36				weeksLeft = settings.weeksLeft,
37				daysLeft = settings.daysLeft,
38				hrsLeft = settings.hrsLeft,
39				minsLeft = settings.minsLeft,
40				secLeft = settings.secLeft,
41				
42				hideYears = false,
43				hideMonths = false,
44				hideWeeks = false,
45				hideDays = false,
46				hideHours = false,
47				hideMins = false,
48				hideSecs = false,
49				timeTasks = [],
50				formatTime = function(time, text, showSeparator) {
51					var timeStr = $timeWrapElement.clone().html( time + settings.spaceCharacter ).html();
52					timeStr += $textWrapElement.clone().html( text + settings.spaceCharacter ).html();
53					if( showSeparator )
54					{
55						timeStr += $textWrapElement.clone().html( settings.spaceCharacter + sep + settings.spaceCharacter ).html();
56					}
57					return timeStr;
58				};
59
60			if( settings.omitZero ) {
61				
62				if( settings.yearsAndMonths ) {
63
64					if( !settings.yearsLeft ) {
65						hideYears = true;
66					}
67					if( !settings.monthsLeft ) {
68						hideMonths = true;
69					}				
70				}
71			
72				if( settings.weeks && ( ( settings.yearsAndMonths && hideMonths && !settings.weeksLeft ) || ( !settings.yearsAndMonths && !settings.weeksLeft ) ) ) {	
73					hideWeeks = true;
74				}
75			
76				if( hideWeeks && !daysLeft ) {
77					hideDays = true;
78				}
79
80				if( hideDays && !hrsLeft ) {
81					hideHours = true;
82				}
83								
84				if( hideHours && !minsLeft ) {
85					hideMins = true;
86				}
87							
88			}		
89			
90			if( settings.leadingZero ) {
91				
92				if( yearsLeft < 10 ) {
93					yearsLeft = "0" + yearsLeft;
94				}
95
96				if( monthsLeft < 10 ) {
97					monthsLeft = "0" + monthsLeft;
98				}
99
100				if( weeksLeft < 10 ) {
101					weeksLeft = "0" + weeksLeft;
102				}
103				
104				if( daysLeft < 10 ) {
105					daysLeft = "0" + daysLeft;
106				}
107				
108				if( hrsLeft < 10 ) {
109					hrsLeft = "0" + hrsLeft;
110				}
111				
112				if( minsLeft < 10 ) {
113					minsLeft = "0" + minsLeft;
114				}
115				
116				if( secLeft < 10 ) {
117					secLeft = "0" + secLeft;
118				}								
119			}	
120			
121			yearsLeft = localNumber( yearsLeft, settings );
122			monthsLeft = localNumber( monthsLeft, settings );
123			weeksLeft = localNumber( weeksLeft, settings );
124			daysLeft = localNumber( daysLeft, settings );
125			hrsLeft = localNumber( hrsLeft, settings );
126			minsLeft = localNumber( minsLeft, settings );
127			secLeft = localNumber( secLeft, settings );
128			
129			if( settings.yearsAndMonths ) {
130								
131				if( !settings.omitZero || !hideYears  ) {
132					template = template.replace('%y', formatTime(yearsLeft, (yearsLeft == 1 && settings.yearSingularText) ? settings.yearSingularText : settings.yearText, true));
133				}
134				
135				//Only hide months if years is at 0 as well as months
136				if( !settings.omitZero || ( !hideYears && monthsLeft ) || ( !hideYears && !hideMonths ) ) {
137					template = template.replace('%m', formatTime(monthsLeft, (monthsLeft == 1 && settings.monthSingularText) ? settings.monthSingularText : settings.monthText, true));
138				} else {
139					template = template.replace('%m', '');
140				}
141
142			}
143			
144			if( settings.weeks && !hideWeeks ) {
145				template = template.replace('%w', formatTime(weeksLeft, (weeksLeft == 1 && settings.weekSingularText) ? settings.weekSingularText : settings.weekText, true));
146			} else {
147				template = template.replace('%w', '');
148			}
149
150			if( !hideDays ) {
151				template = template.replace('%d', formatTime(daysLeft, (daysLeft == 1 && settings.daySingularText) ? settings.daySingularText : settings.dayText, true));
152			} else {
153				template = template.replace('%d', '');
154			}
155
156			if( !hideHours ) {
157				template = template.replace('%h', formatTime(hrsLeft, (hrsLeft == 1 && settings.hourSingularText) ? settings.hourSingularText : settings.hourText, true));
158			} else {
159				template = template.replace('%h', '');
160			}
161			
162			if( !hideMins ) {
163				template = template.replace('%i', formatTime(minsLeft, (minsLeft == 1 && settings.minSingularText) ? settings.minSingularText : settings.minText, true));
164			} else {
165				template = template.replace('%i', '');
166			}
167		
168			template = template.replace('%s', formatTime(secLeft, (secLeft == 1 && settings.secSingularText) ? settings.secSingularText : settings.secText));
169
170            // Remove un-used tokens
171            template = template.replace(rTemplateTokens,'');
172
173			return template;
174		},
175		generateTemplate = function( settings ) {
176			
177			var $parent = $('<div>'),
178				$timeWrapElement = $("<"+settings.timeWrapElement+">").addClass( settings.timeWrapClass ),
179				$textWrapElement = $("<"+settings.textWrapElement+">").addClass( settings.textWrapClass ),
180				
181				sep = settings.timeSeparator,
182				
183				yearsLeft = settings.yearsLeft,
184				monthsLeft = settings.monthsLeft,
185				weeksLeft = settings.weeksLeft,
186				daysLeft = settings.daysLeft,
187				hrsLeft = settings.hrsLeft,
188				minsLeft = settings.minsLeft,
189				secLeft = settings.secLeft,
190				template = settings.template,
191				hasTemplate = !!settings.template,
192				hideYears = false,
193				hideMonths = false,
194				hideWeeks = false,
195				hideDays = false,
196				hideHours = false,
197				hideMins = false,
198				hideSecs = false,
199				timeTasks = [],
200				addTime = function( time ) {
201					timeTasks.push(function() {
202						$parent.append( $timeWrapElement.clone().html( time + settings.spaceCharacter ) );
203					});					
204				},
205				addText = function( text ) {
206					timeTasks.push(function() {
207						$parent.append( $textWrapElement.clone().html( text + settings.spaceCharacter ) );
208					});					
209				},
210				addSeparator = function() {
211					timeTasks.push(function() {
212						$parent.append( $textWrapElement.clone().html( settings.spaceCharacter + sep + settings.spaceCharacter) );
213					});				
214				},
215				formatTime = function(time, text, showSeparator) {
216					var timeStr = $timeWrapElement.clone().html( time + settings.spaceCharacter ).html();
217					timeStr += $textWrapElement.clone().html( text + settings.spaceCharacter ).html();
218					if( showSeparator )
219					{
220						timeStr += $textWrapElement.clone().html( settings.spaceCharacter + sep + settings.spaceCharacter ).html();
221					}
222					return timeStr;
223				};
224			
225			if( settings.template )
226			{
227				return generateTemplateCustom( settings );
228			}		
229
230			if( settings.omitZero ) {
231				
232				if( settings.yearsAndMonths ) {
233
234					if( !settings.yearsLeft ) {
235						hideYears = true;
236					}
237					if( !settings.monthsLeft ) {
238						hideMonths = true;
239					}				
240				}
241			
242				if( settings.weeks && ( ( settings.yearsAndMonths && hideMonths && !settings.weeksLeft ) || ( !settings.yearsAndMonths && !settings.weeksLeft ) ) ) {	
243					hideWeeks = true;
244				}
245			
246				if( hideWeeks && !daysLeft ) {
247					hideDays = true;
248				}
249
250				if( hideDays && !hrsLeft ) {
251					hideHours = true;
252				}
253								
254				if( hideHours && !minsLeft ) {
255					hideMins = true;
256				}
257							
258			}		
259			
260			if( settings.leadingZero ) {
261				
262				if( yearsLeft < 10 ) {
263					yearsLeft = "0" + yearsLeft;
264				}
265
266				if( monthsLeft < 10 ) {
267					monthsLeft = "0" + monthsLeft;
268				}
269
270				if( weeksLeft < 10 ) {
271					weeksLeft = "0" + weeksLeft;
272				}
273				
274				if( daysLeft < 10 ) {
275					daysLeft = "0" + daysLeft;
276				}
277				
278				if( hrsLeft < 10 ) {
279					hrsLeft = "0" + hrsLeft;
280				}
281				
282				if( minsLeft < 10 ) {
283					minsLeft = "0" + minsLeft;
284				}
285				
286				if( secLeft < 10 ) {
287					secLeft = "0" + secLeft;
288				}								
289			}	
290			
291			yearsLeft = localNumber( yearsLeft, settings );
292			monthsLeft = localNumber( monthsLeft, settings );
293			weeksLeft = localNumber( weeksLeft, settings );
294			daysLeft = localNumber( daysLeft, settings );
295			hrsLeft = localNumber( hrsLeft, settings );
296			minsLeft = localNumber( minsLeft, settings );
297			secLeft = localNumber( secLeft, settings );
298			
299			if( settings.yearsAndMonths ) {
300								
301				if( !settings.omitZero || !hideYears  ) {
302										
303					addTime( yearsLeft );					
304					addText( (yearsLeft == 1 && settings.yearSingularText) ? settings.yearSingularText : settings.yearText );
305					addSeparator();
306
307				}
308				
309				//Only hide months if years is at 0 as well as months
310				if( !settings.omitZero || ( !hideYears && monthsLeft ) || ( !hideYears && !hideMonths ) ) {
311
312					addTime( monthsLeft );
313					addText( (monthsLeft == 1 && settings.monthSingularText) ? settings.monthSingularText : settings.monthText );
314					addSeparator();
315				}
316			}
317			
318			if( settings.weeks && !hideWeeks ) {
319				addTime( weeksLeft );
320				addText( (weeksLeft == 1 && settings.weekSingularText) ? settings.weekSingularText : settings.weekText );
321				addSeparator();
322			}
323
324			if( !hideDays ) {
325				addTime( daysLeft );
326				addText( (daysLeft == 1 && settings.daySingularText) ? settings.daySingularText : settings.dayText );
327				addSeparator();
328			}
329
330			if( !hideHours ) {
331				addTime( hrsLeft );
332				addText( (hrsLeft == 1 && settings.hourSingularText) ? settings.hourSingularText : settings.hourText );
333				addSeparator();
334			}
335			
336			if( !hideMins ) {
337				addTime( minsLeft );
338				addText( (minsLeft == 1 && settings.minSingularText) ? settings.minSingularText  : settings.minText );
339				addSeparator();
340			}
341			
342			
343			addTime( secLeft );			
344			addText( settings.secText );
345						
346			if( settings.isRTL === true ) {
347				timeTasks.reverse();
348			}
349			
350			$.each( timeTasks, function(i,task ) {
351				task();
352			});
353			
354			template = $parent.html();
355			
356			return template;
357		},
358		dateNow = function( $this ) {
359			var now = new Date(), //Default to local time
360				settings = $this.data("jcdData");
361			
362			if( !settings ) {
363				return new Date() .getTime();
364			}
365			
366			if( settings.offset !== null ) {
367				now = getTZDate( settings.offset );
368			}
369			
370			now.setMilliseconds(0);
371			return now;
372		},
373		getTZDate = function( offset ) {
374			// Returns date now based on timezone/offset
375			var hrs,
376				dateMS,
377				curHrs,
378				tmpDate = new Date();
379				
380			if( offset !== null ) {
381				hrs = offset * msPerHr;
382				curHrs = tmpDate.getTime() - ( ( -tmpDate.getTimezoneOffset() / 60 ) * msPerHr ) + hrs;
383				dateMS = tmpDate.setTime( curHrs );
384			}
385			
386			return new Date( dateMS );
387		},			
388		timerFunc = function() {
389			//Function runs at set interval updating countdown
390			var $this = this,
391				template,
392				now,
393				date,
394				timeLeft,
395				yearsLeft = 0,
396				monthsLeft = 0,
397				weeksLeft = 0,
398				daysLeft = 0,
399				hrsLeft = 0,
400				minsLeft = 0,
401				secLeft = 0,
402				time = "",
403				diff,
404
405				hideYears = false,
406				hideMonths = false,
407				hideWeeks = false,
408				hideDays = false,
409				hideHours = false,
410				hideMins = false,
411				hideSecs = false,
412
413				extractSection = function( numSecs ) {
414					var amount;
415	
416					amount = Math.floor( diff / numSecs );
417					diff -= amount * numSecs;
418					
419					return amount;
420				},
421				settings = $this.data("jcdData");
422				
423			if( !settings ) {
424				return false;
425			}
426			
427			template = settings.htmlTemplate;
428			now = dateNow( $this );
429			
430			if( settings.serverDiff !== null ) {
431				date = new Date( settings.serverDiff + settings.clientdateNow.getTime() );
432			} else {
433				date = settings.dateObj; //Date to countdown to
434			}
435			
436			date.setMilliseconds(0);
437			
438			timeLeft = ( settings.direction === "down" ) ? date.getTime() - now.getTime() : now.getTime() - date.getTime();
439			
440			diff = Math.round( timeLeft / 1000 );
441
442			daysLeft = extractSection( secPerDay );			
443			hrsLeft = extractSection( secPerHr );
444			minsLeft = extractSection( secPerMin );
445			secLeft = extractSection( secPerSec );
446												
447			if( settings.yearsAndMonths ) {
448
449				//Add days back on so we can calculate years easier
450				diff += ( daysLeft * secPerDay );
451				
452				yearsLeft = extractSection( secPerYear );				
453				monthsLeft = extractSection( secPerMonth );				
454				daysLeft = extractSection( secPerDay );
455			}
456
457			if( settings.weeks ) {
458				//Add days back on so we can calculate weeks easier				
459				diff += ( daysLeft * secPerDay );
460
461				weeksLeft = extractSection( secPerWeek );
462				daysLeft = extractSection( secPerDay );
463			}
464
465			/**
466			* The following 3 option should never be used together!
467			* MAKE them work for any time
468			*/
469			
470			if( settings.hoursOnly || settings.minsOnly || settings.secsOnly )
471			{
472				
473				if( settings.yearsAndMonths ) {
474					//Add years, months, weeks and days back on so we can calculate dates easier
475					diff += ( yearsLeft * secPerYear );
476					diff += ( monthsLeft * secPerMonth );
477
478					yearsLeft = monthsLeft = 0;
479				}
480
481				if( settings.weeks ) {
482					diff += ( weeksLeft * secPerWeek );
483
484					weeksLeft = 0;
485				}
486
487			}	
488
489			//Assumes you are using dates within a month  ( ~ 30 days )
490			//as years and months aren't taken into account
491			if( settings.hoursOnly ) {
492
493				// Add days back on
494				diff += ( daysLeft * secPerDay );
495
496				// Add hours back on
497				diff += ( hrsLeft * secPerHr );
498				hrsLeft = extractSection( secPerHr );
499
500			}
501			
502			//Assumes you are only using dates in the near future ( <= 24 hours )
503			//as years and months aren't taken into account
504			if( settings.minsOnly ) {
505
506				
507				// Add days back on
508				diff += ( daysLeft * secPerDay );
509				daysLeft = 0;
510
511				// Add hours back on
512				diff += ( hrsLeft * secPerHr );
513				hrsLeft = 0;
514
515				diff += ( minsLeft * secPerMin );
516				
517				minsLeft = extractSection( secPerMin );
518
519			}
520
521			//Assumes you are only using dates in the near future ( <= 60 minutes )
522			//as years, months and days aren't taken into account
523			if( settings.secsOnly ) {
524
525				
526				// Add days back on
527				diff += ( daysLeft * secPerDay );
528				daysLeft = 0;
529
530				// Add hours back on
531				diff += ( hrsLeft * secPerHr );
532				hrsLeft = 0;
533
534				// Add minutes back on
535				diff += ( minsLeft * secPerMin );
536				minsLeft = 0;
537
538				// Add seconds back on
539				diff += secLeft;
540
541				secLeft = extractSection( secPerSec );
542			}
543						
544			settings.yearsLeft = yearsLeft;
545			settings.monthsLeft = monthsLeft;
546			settings.weeksLeft = weeksLeft;
547			settings.daysLeft = daysLeft;
548			settings.hrsLeft = hrsLeft;
549			settings.minsLeft = minsLeft;
550			settings.secLeft = secLeft;
551
552			$this.data("jcdData", settings);
553			
554			if ( ( settings.direction === "down" && ( now < date || settings.minus ) ) || ( settings.direction === "up" && ( date < now || settings.minus )  ) ) {
555				time = generateTemplate( settings );
556			} else {
557				settings.yearsLeft = settings.monthsLeft = settings.weeksLeft = settings.daysLeft = settings.hrsLeft = settings.minsLeft = settings.secLeft = 0;
558								
559				time = generateTemplate( settings );
560				settings.hasCompleted = true;
561			}
562							
563			$this.html( time ).triggerMulti("change.jcdevt,countChange", [settings]);
564			
565			if ( settings.hasCompleted ) {
566				$this.triggerMulti("complete.jcdevt,countComplete");
567				clearInterval( settings.timer );
568			}
569
570		},			
571		methods = {		
572			init: function( options ) {
573				
574				var opts = $.extend( {}, $.fn.countdown.defaults, options ),
575					local = null,
576					testDate,
577					testString;
578				
579				return this.each(function() {
580					var $this = $(this),
581						settings = {},
582						func;
583
584					//If this element already has a countdown timer, just change the settings
585					if( $this.data("jcdData") ) {
586						$this.countdown("changeSettings", options, true);
587						opts = $this.data("jcdData");
588					}
589
590					if( opts.date === null && opts.dataAttr === null ) {
591						$.error("No Date passed to jCountdown. date option is required.");
592						return true;
593					}
594					
595					if( opts.date ) {					
596						testString = opts.date;
597					} else {
598						testString = $this.data(opts.dataAttr);
599					}
600					
601					
602					testDate = new Date(testString);
603					
604					if( testDate.toString() === "Invalid Date" ) {
605						$.error("Invalid Date passed to jCountdown: " + testString);
606					}
607					
608					//Add event handlers where set
609					if( opts.onStart ) {
610						$this.on("start.jcdevt", opts.onStart );
611					}
612					
613					if( opts.onChange ) {
614						$this.on("change.jcdevt", opts.onChange );
615					}
616					
617					if( opts.onComplete ) {
618						$this.on("complete.jcdevt", opts.onComplete );
619					}
620					
621					if( opts.onPause ) {
622						$this.on("pause.jcdevt", opts.onPause );
623					}
624
625					if( opts.onResume ) {
626						$this.on("resume.jcdevt", opts.onResume );
627					}
628
629
630					if( opts.onLocaleChange ) {
631						$this.on("locale.jcdevt", opts.onLocaleChange );
632					}
633					
634					settings = $.extend( {}, opts );
635
636					
637					// Cache DOM elements for templating
638					settings.dom = {};
639
640					settings.dom.$time = $("<"+settings.timeWrapElement+">").addClass( settings.timeWrapClass );
641					settings.dom.$text = $("<"+settings.textWrapElement+">").addClass( settings.textWrapClass );
642
643					settings.clientdateNow = new Date();
644					settings.clientdateNow.setMilliseconds(0);					
645					settings.originalHTML = $this.html();
646					settings.dateObj = new Date( testString );
647					settings.dateObj.setMilliseconds(0);
648					settings.hasCompleted = false;
649					settings.timer = 0;
650					settings.yearsLeft = settings.monthsLeft = settings.weeksLeft = settings.daysLeft = settings.hrsLeft = settings.minsLeft = settings.secLeft = 0;
651					settings.difference = null;
652					
653					func = $.proxy( timerFunc, $this );
654					settings.timer = setInterval( func, settings.updateTime );
655
656					$this.data("jcdData", settings).triggerMulti("start.jcdevt,countStart", [settings]);
657					
658					func();
659				});
660			},
661			changeSettings: function( options, internal ) {
662				//Like resume but with resetting/changing options				
663				return this.each(function() {
664					var $this  = $(this),
665						settings,
666						testDate,
667						func = $.proxy( timerFunc, $this );
668						
669					if( !$this.data("jcdData") ) {
670						return true;
671					}
672					
673					settings = $.extend( {}, $this.data("jcdData"), options );
674
675					if( options.hasOwnProperty("date") ) {
676						testDate = new Date(options.date);
677						
678						if( testDate.toString() === "Invalid Date" ) {
679							$.error("Invalid Date passed to jCountdown: " + options.date);
680						}
681					}
682					
683					settings.completed = false;
684					settings.dateObj  = new Date( options.date );
685					
686					//Clear the timer, as it might not be needed
687					clearInterval( settings.timer );					
688					$this.off(".jcdevt").data("jcdData", settings);	
689					
690					//As this can be accessed via the init method as well,
691					//we need to check how this method is being accessed
692					if( !internal ) {
693						
694						if( settings.onChange ) {
695							$this.on("change.jcdevt", settings.onChange);
696						}
697
698						if( settings.onComplete ) {
699							$this.on("complete.jcdevt", settings.onComplete);
700						}
701				
702						if( settings.onPause ) {
703							$this.on("pause.jcdevt", settings.onPause );
704						}
705
706						if( settings.onResume ) {
707							$this.on("resume.jcdevt", settings.onResume );
708						}
709				
710						settings.timer = setInterval( func, settings.updateTime );
711						$this.data("jcdData", settings);
712						func(); //Needs to run straight away when changing settings
713					}
714					
715					settings = null;
716				});
717			},
718			resume: function() {			
719				//Resumes a countdown timer
720				return this.each(function() {
721					var $this = $(this),
722						settings = $this.data("jcdData"),
723						func = $.proxy( timerFunc, $this );
724					
725					if( !settings ) {
726						return true;
727					}
728
729					$this.data("jcdData", settings).triggerMulti("resume.jcdevt,countResume", [settings] );
730					//We only want to resume a countdown that hasn't finished
731					if( !settings.hasCompleted ) {
732						settings.timer = setInterval( func, settings.updateTime );						
733																		
734						if( settings.stopwatch && settings.direction === "up" ) {
735
736							var t = dateNow( $this ).getTime() - settings.pausedAt.getTime(),
737								d = new Date();
738							d.setTime( settings.dateObj.getTime() + t );
739							
740							settings.dateObj = d; //This is internal date
741						}					
742						
743						func();
744					}
745				});
746			},
747			pause: function() {	
748				//Pause a countdown timer			
749				return this.each(function() {
750					var $this = $(this),
751						settings = $this.data("jcdData");
752
753					if( !settings ) {
754						return true;
755					}
756					
757					if( settings.stopwatch ) {
758						settings.pausedAt = dateNow( $this );
759					}
760					//Clear interval (Will be started on resume)
761					clearInterval( settings.timer );
762					//Trigger pause event handler
763					$this.data("jcdData", settings).triggerMulti("pause.jcdevt,countPause", [settings] );
764				});
765			},
766			complete: function() {
767				return this.each(function() {
768					var $this = $(this),
769						settings = $this.data("jcdData");
770
771					if( !settings ) {
772						return true;
773					}
774					//Clear timer
775					clearInterval( settings.timer );
776					settings.hasCompleted = true;
777					//Update setting, trigger complete event handler, then unbind all events
778					//We don"t delete the settings in case they need to be checked later on
779
780					$this.data("jcdData", settings).triggerMulti("complete.jcdevt,countComplete", [settings]);
781					
782					//$this.off(".jcdevt, co");
783					
784				});		
785			},
786			destroy: function() {
787				return this.each(function() {
788					var $this = $(this),
789						settings = $this.data("jcdData");
790					
791					if( !settings ) {
792						return true;
793					}
794					//Clear timer
795					clearInterval( settings.timer );
796					//Unbind all events, remove data and put DOM Element back to its original state (HTML wise)
797					$this.off(".jcdevt").removeData("jcdData").html( settings.originalHTML );
798				});
799			},
800			getSettings: function( name ) {
801				var $this = $(this),
802					settings = $this.data("jcdData");
803				
804				//If an individual setting is required
805				if( name && settings ) {
806					//If it exists, return it
807					if( settings.hasOwnProperty( name ) ) {
808						return settings[name];
809					}
810					return undefined;
811				}
812				//Return all settings or undefined
813				return settings;
814			},
815			changeLocale: function( locale ) { //new in v1.5.0
816				var $this = $(this),
817					settings = $this.data("jcdData");
818				
819				// If no locale exists error and return false
820				if( !$.fn.countdown.locale[locale] ) {
821					$.error("Locale '" + locale + "' does not exist");
822					return false;
823				}
824					
825				$.extend( settings, $.fn.countdown.locale[locale] );
826				
827				$this.data("jcdData", settings).triggerMulti("locale.jcdevt,localeChange", [settings]);
828				
829				return true;
830			}
831		};
832	
833	if( methods[ method ] ) {
834		return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ) );
835	} else if ( typeof method === "object" || !method ) {
836		return methods.init.apply( this, arguments );
837	} else {
838		$.error("Method "+ method +" does not exist in the jCountdown Plugin");
839	}
840};
841
842// new in v1.5.0
843$.fn.countdown.defaults = {
844	date: null,
845	dataAttr: null,
846	updateTime: 1000,			
847	yearText: 'years',
848	monthText: 'months',
849	weekText: 'weeks',
850	dayText: 'days',
851	hourText: 'hours',
852	minText: 'mins',
853	secText: 'sec',
854
855    yearSingularText: 'year',
856    monthSingularText: 'month',
857    weekSingularText: 'week',
858    daySingularText: 'day',
859    hourSingularText: 'hour',
860    minSingularText: 'min',
861    secSingularText: 'sec',
862
863	digits : [0,1,2,3,4,5,6,7,8,9],
864	timeWrapElement: 'span',
865	textWrapElement: 'span',
866	timeWrapClass: '',
867	textWrapClass: 'cd-time',
868	timeSeparator: '',
869	isRTL: false,
870	minus: false,
871	onStart: null,
872	onChange: null,
873	onComplete: null,
874	onResume: null,
875	onPause: null,
876	onLocaleChange: null,
877	leadingZero: false,
878	offset: null,
879	serverDiff:null,
880	spaceCharacter: ' ',
881	hoursOnly: false,
882	minsOnly: false,
883	secsOnly: false,
884	weeks: false,
885	hours: false,
886	yearsAndMonths: false,
887	direction: "down",
888	stopwatch: false,
889	omitZero: false,
890	template: null
891};
892
893//Create an array to store new locales
894// new in v1.5.0
895$.fn.countdown.locale = [];
896
897// new in v1.5.0
898$.fn.triggerMulti = function( eventTypes, extraParameters ) {
899	var events = eventTypes.split(",");
900		
901	return this.each(function() {
902		var $this = $(this);
903
904		for( var i = 0; i < events.length; i++) {
905			$this.trigger( events[i], extraParameters );
906		}	
907	});
908};
909
910})(jQuery);

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.