PageSourceSearch

http://bayalagbuteegch.mn/js/bootstrap-datepicker.js

js bayalagbuteegch.mn collected 2026-10-04 13:28:54 UTC 37,363 bytes, 1,259 lines download raw bytes

vendor: 1,998 bytes, lines 1-60
1/* =========================================================
2 * bootstrap-datepicker.js
3 * http://www.eyecon.ro/bootstrap-datepicker
4 * =========================================================
5 * Copyright 2012 Stefan Petre
6 * Improvements by Andrew Rowls
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ========================================================= */
20
21
22(function( $ ) {
23
24	function UTCDate(){
25		return new Date(Date.UTC.apply(Date, arguments));
26	}
27	function UTCToday(){
28		var today = new Date();
29		return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate());
30	}
31
32	// Picker object
33
34	var Datepicker = function(element, options) {
35		var that = this;
36
37		this._process_options(options);
38
39		this.element = $(element);
40		this.isInline = false;
41		this.isInput = this.element.is('input');
42		this.component = this.element.is('.date') ? this.element.find('.add-on, .btn, .input-group-addon') : false;
43		this.hasInput = this.component && this.element.find('input').length;
44		if(this.component && this.component.length === 0)
45			this.component = false;
46
47		this.picker = $(DPGlobal.template);
48		this._buildEvents();
49		this._attachEvents();
50
51		if(this.isInline) {
52			this.picker.addClass('datepicker-inline').appendTo(this.element);
53		} else {
54			this.picker.addClass('datepicker-dropdown dropdown-menu');
55		}
56
57		if (this.o.rtl){
58			this.picker.addClass('datepicker-rtl');
59			this.picker.find('.prev i, .next i')
60						.toggleClass('glyphicon glyphicon-arrow-left glyph
vendor: 26,199 bytes, lines 60-962
60icon-arrow-right');
61		}
62
63
64		this.viewMode = this.o.startView;
65
66		if (this.o.calendarWeeks)
67			this.picker.find('tfoot th.today')
68						.attr('colspan', function(i, val){
69							return parseInt(val) + 1;
70						});
71
72		this._allow_update = false;
73
74		this.setStartDate(this.o.startDate);
75		this.setEndDate(this.o.endDate);
76		this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
77
78		this.fillDow();
79		this.fillMonths();
80
81		this._allow_update = true;
82
83		this.update();
84		this.showMode();
85
86		if(this.isInline) {
87			this.show();
88		}
89	};
90
91	Datepicker.prototype = {
92		constructor: Datepicker,
93
94		_process_options: function(opts){
95			// Store raw options for reference
96			this._o = $.extend({}, this._o, opts);
97			// Processed options
98			var o = this.o = $.extend({}, this._o);
99
100			// Check if "de-DE" style date is available, if not language should
101			// fallback to 2 letter code eg "de"
102			var lang = o.language;
103			if (!dates[lang]) {
104				lang = lang.split('-')[0];
105				if (!dates[lang])
106					lang = defaults.language;
107			}
108			o.language = lang;
109
110			switch(o.startView){
111				case 2:
112				case 'decade':
113					o.startView = 2;
114					break;
115				case 1:
116				case 'year':
117					o.startView = 1;
118					break;
119				default:
120					o.startView = 0;
121			}
122
123			switch (o.minViewMode) {
124				case 1:
125				case 'months':
126					o.minViewMode = 1;
127					break;
128				case 2:
129				case 'years':
130					o.minViewMode = 2;
131					break;
132				default:
133					o.minViewMode = 0;
134			}
135
136			o.startView = Math.max(o.startView, o.minViewMode);
137
138			o.weekStart %= 7;
139			o.weekEnd = ((o.weekStart + 6) % 7);
140
141			var format = DPGlobal.parseFormat(o.format)
142			if (o.startDate !== -Infinity) {
143				o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
144			}
145			if (o.endDate !== Infinity) {
146				o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
147			}
148
149			o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
150			if (!$.isArray(o.daysOfWeekDisabled))
151				o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
152			o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function (d) {
153				return parseInt(d, 10);
154			});
155		},
156		_events: [],
157		_secondaryEvents: [],
158		_applyEvents: function(evs){
159			for (var i=0, el, ev; i<evs.length; i++){
160				el = evs[i][0];
161				ev = evs[i][1];
162				el.on(ev);
163			}
164		},
165		_unapplyEvents: function(evs){
166			for (var i=0, el, ev; i<evs.length; i++){
167				el = evs[i][0];
168				ev = evs[i][1];
169				el.off(ev);
170			}
171		},
172		_buildEvents: function(){
173			if (this.isInput) { // single input
174				this._events = [
175					[this.element, {
176						focus: $.proxy(this.show, this),
177						keyup: $.proxy(this.update, this),
178						keydown: $.proxy(this.keydown, this)
179					}]
180				];
181			}
182			else if (this.component && this.hasInput){ // component: input + button
183				this._events = [
184					// For components that are not readonly, allow keyboard nav
185					[this.element.find('input'), {
186						focus: $.proxy(this.show, this),
187						keyup: $.proxy(this.update, this),
188						keydown: $.proxy(this.keydown, this)
189					}],
190					[this.component, {
191						click: $.proxy(this.show, this)
192					}]
193				];
194			}
195			else if (this.element.is('div')) {  // inline datepicker
196				this.isInline = true;
197			}
198			else {
199				this._events = [
200					[this.element, {
201						click: $.proxy(this.show, this)
202					}]
203				];
204			}
205
206			this._secondaryEvents = [
207				[this.picker, {
208					click: $.proxy(this.click, this)
209				}],
210				[$(window), {
211					resize: $.proxy(this.place, this)
212				}],
213				[$(document), {
214					mousedown: $.proxy(function (e) {
215						// Clicked outside the datepicker, hide it
216						if (!(
217							this.element.is(e.target) ||
218							this.element.find(e.target).size() ||
219							this.picker.is(e.target) ||
220							this.picker.find(e.target).size()
221						)) {
222							this.hide();
223						}
224					}, this)
225				}]
226			];
227		},
228		_attachEvents: function(){
229			this._detachEvents();
230			this._applyEvents(this._events);
231		},
232		_detachEvents: function(){
233			this._unapplyEvents(this._events);
234		},
235		_attachSecondaryEvents: function(){
236			this._detachSecondaryEvents();
237			this._applyEvents(this._secondaryEvents);
238		},
239		_detachSecondaryEvents: function(){
240			this._unapplyEvents(this._secondaryEvents);
241		},
242		_trigger: function(event, altdate){
243			var date = altdate || this.date,
244				local_date = new Date(date.getTime() + (date.getTimezoneOffset()*60000));
245
246			this.element.trigger({
247				type: event,
248				date: local_date,
249				format: $.proxy(function(altformat){
250					var format = altformat || this.o.format;
251					return DPGlobal.formatDate(date, format, this.o.language);
252				}, this)
253			});
254		},
255
256		show: function(e) {
257			if (!this.isInline)
258				this.picker.appendTo('body');
259			this.picker.show();
260			this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
261			this.place();
262			this._attachSecondaryEvents();
263			if (e) {
264				e.preventDefault();
265			}
266			this._trigger('show');
267		},
268
269		hide: function(e){
270			if(this.isInline) return;
271			if (!this.picker.is(':visible')) return;
272			this.picker.hide().detach();
273			this._detachSecondaryEvents();
274			this.viewMode = this.o.startView;
275			this.showMode();
276
277			if (
278				this.o.forceParse &&
279				(
280					this.isInput && this.element.val() ||
281					this.hasInput && this.element.find('input').val()
282				)
283			)
284				this.setValue();
285			this._trigger('hide');
286		},
287
288		remove: function() {
289			this.hide();
290			this._detachEvents();
291			this._detachSecondaryEvents();
292			this.picker.remove();
293			delete this.element.data().datepicker;
294			if (!this.isInput) {
295				delete this.element.data().date;
296			}
297		},
298
299		getDate: function() {
300			var d = this.getUTCDate();
301			return new Date(d.getTime() + (d.getTimezoneOffset()*60000));
302		},
303
304		getUTCDate: function() {
305			return this.date;
306		},
307
308		setDate: function(d) {
309			this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset()*60000)));
310		},
311
312		setUTCDate: function(d) {
313			this.date = d;
314			this.setValue();
315		},
316
317		setValue: function() {
318			var formatted = this.getFormattedDate();
319			if (!this.isInput) {
320				if (this.component){
321					this.element.find('input').val(formatted);
322				}
323			} else {
324				this.element.val(formatted);
325			}
326		},
327
328		getFormattedDate: function(format) {
329			if (format === undefined)
330				format = this.o.format;
331			return DPGlobal.formatDate(this.date, format, this.o.language);
332		},
333
334		setStartDate: function(startDate){
335			this._process_options({startDate: startDate});
336			this.update();
337			this.updateNavArrows();
338		},
339
340		setEndDate: function(endDate){
341			this._process_options({endDate: endDate});
342			this.update();
343			this.updateNavArrows();
344		},
345
346		setDaysOfWeekDisabled: function(daysOfWeekDisabled){
347			this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
348			this.update();
349			this.updateNavArrows();
350		},
351
352		place: function(){
353						if(this.isInline) return;
354			var zIndex = parseInt(this.element.parents().filter(function() {
355							return $(this).css('z-index') != 'auto';
356						}).first().css('z-index'))+10;
357			var offset = this.component ? this.component.parent().offset() : this.element.offset();
358			var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(true);
359			this.picker.css({
360				top: offset.top + height,
361				left: offset.left,
362				zIndex: zIndex
363			});
364		},
365
366		_allow_update: true,
367		update: function(){
368			if (!this._allow_update) return;
369
370			var date, fromArgs = false;
371			if(arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
372				date = arguments[0];
373				fromArgs = true;
374			} else {
375				date = this.isInput ? this.element.val() : this.element.data('date') || this.element.find('input').val();
376				delete this.element.data().date;
377			}
378
379			this.date = DPGlobal.parseDate(date, this.o.format, this.o.language);
380
381			if(fromArgs) this.setValue();
382
383			if (this.date < this.o.startDate) {
384				this.viewDate = new Date(this.o.startDate);
385			} else if (this.date > this.o.endDate) {
386				this.viewDate = new Date(this.o.endDate);
387			} else {
388				this.viewDate = new Date(this.date);
389			}
390			this.fill();
391		},
392
393		fillDow: function(){
394			var dowCnt = this.o.weekStart,
395			html = '<tr>';
396			if(this.o.calendarWeeks){
397				var cell = '<th class="cw">&nbsp;</th>';
398				html += cell;
399				this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
400			}
401			while (dowCnt < this.o.weekStart + 7) {
402				html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
403			}
404			html += '</tr>';
405			this.picker.find('.datepicker-days thead').append(html);
406		},
407
408		fillMonths: function(){
409			var html = '',
410			i = 0;
411			while (i < 12) {
412				html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>';
413			}
414			this.picker.find('.datepicker-months td').html(html);
415		},
416
417		setRange: function(range){
418			if (!range || !range.length)
419				delete this.range;
420			else
421				this.range = $.map(range, function(d){ return d.valueOf(); });
422			this.fill();
423		},
424
425		getClassNames: function(date){
426			var cls = [],
427				year = this.viewDate.getUTCFullYear(),
428				month = this.viewDate.getUTCMonth(),
429				currentDate = this.date.valueOf(),
430				today = new Date();
431			if (date.getUTCFullYear() < year || (date.getUTCFullYear() == year && date.getUTCMonth() < month)) {
432				cls.push('old');
433			} else if (date.getUTCFullYear() > year || (date.getUTCFullYear() == year && date.getUTCMonth() > month)) {
434				cls.push('new');
435			}
436			// Compare internal UTC date with local today, not UTC today
437			if (this.o.todayHighlight &&
438				date.getUTCFullYear() == today.getFullYear() &&
439				date.getUTCMonth() == today.getMonth() &&
440				date.getUTCDate() == today.getDate()) {
441				cls.push('today');
442			}
443			if (currentDate && date.valueOf() == currentDate) {
444				cls.push('active');
445			}
446			if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
447				$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1) {
448				cls.push('disabled');
449			}
450			if (this.range){
451				if (date > this.range[0] && date < this.range[this.range.length-1]){
452					cls.push('range');
453				}
454				if ($.inArray(date.valueOf(), this.range) != -1){
455					cls.push('selected');
456				}
457			}
458			return cls;
459		},
460
461		fill: function() {
462			var d = new Date(this.viewDate),
463				year = d.getUTCFullYear(),
464				month = d.getUTCMonth(),
465				startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
466				startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
467				endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
468				endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
469				currentDate = this.date && this.date.valueOf(),
470				tooltip;
471			this.picker.find('.datepicker-days thead th.datepicker-switch')
472						.text(dates[this.o.language].months[month]+' '+year);
473			this.picker.find('tfoot th.today')
474						.text(dates[this.o.language].today)
475						.toggle(this.o.todayBtn !== false);
476			this.picker.find('tfoot th.clear')
477						.text(dates[this.o.language].clear)
478						.toggle(this.o.clearBtn !== false);
479			this.updateNavArrows();
480			this.fillMonths();
481			var prevMonth = UTCDate(year, month-1, 28,0,0,0,0),
482				day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
483			prevMonth.setUTCDate(day);
484			prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
485			var nextMonth = new Date(prevMonth);
486			nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
487			nextMonth = nextMonth.valueOf();
488			var html = [];
489			var clsName;
490			while(prevMonth.valueOf() < nextMonth) {
491				if (prevMonth.getUTCDay() == this.o.weekStart) {
492					html.push('<tr>');
493					if(this.o.calendarWeeks){
494						// ISO 8601: First week contains first thursday.
495						// ISO also states week starts on Monday, but we can be more abstract here.
496						var
497							// Start of current week: based on weekstart/current date
498							ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
499							// Thursday of this week
500							th = new Date(+ws + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
501							// First Thursday of year, year from thursday
502							yth = new Date(+(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
503							// Calendar week: ms between thursdays, div ms per day, div 7 days
504							calWeek =  (th - yth) / 864e5 / 7 + 1;
505						html.push('<td class="cw">'+ calWeek +'</td>');
506
507					}
508				}
509				clsName = this.getClassNames(prevMonth);
510				clsName.push('day');
511
512				var before = this.o.beforeShowDay(prevMonth);
513				if (before === undefined)
514					before = {};
515				else if (typeof(before) === 'boolean')
516					before = {enabled: before};
517				else if (typeof(before) === 'string')
518					before = {classes: before};
519				if (before.enabled === false)
520					clsName.push('disabled');
521				if (before.classes)
522					clsName = clsName.concat(before.classes.split(/\s+/));
523				if (before.tooltip)
524					tooltip = before.tooltip;
525
526				clsName = $.unique(clsName);
527				html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
528				if (prevMonth.getUTCDay() == this.o.weekEnd) {
529					html.push('</tr>');
530				}
531				prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
532			}
533			this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
534			var currentYear = this.date && this.date.getUTCFullYear();
535
536			var months = this.picker.find('.datepicker-months')
537						.find('th:eq(1)')
538							.text(year)
539							.end()
540						.find('span').removeClass('active');
541			if (currentYear && currentYear == year) {
542				months.eq(this.date.getUTCMonth()).addClass('active');
543			}
544			if (year < startYear || year > endYear) {
545				months.addClass('disabled');
546			}
547			if (year == startYear) {
548				months.slice(0, startMonth).addClass('disabled');
549			}
550			if (year == endYear) {
551				months.slice(endMonth+1).addClass('disabled');
552			}
553
554			html = '';
555			year = parseInt(year/10, 10) * 10;
556			var yearCont = this.picker.find('.datepicker-years')
557								.find('th:eq(1)')
558									.text(year + '-' + (year + 9))
559									.end()
560								.find('td');
561			year -= 1;
562			for (var i = -1; i < 11; i++) {
563				html += '<span class="year'+(i == -1 ? ' old' : i == 10 ? ' new' : '')+(currentYear == year ? ' active' : '')+(year < startYear || year > endYear ? ' disabled' : '')+'">'+year+'</span>';
564				year += 1;
565			}
566			yearCont.html(html);
567		},
568
569		updateNavArrows: function() {
570			if (!this._allow_update) return;
571
572			var d = new Date(this.viewDate),
573				year = d.getUTCFullYear(),
574				month = d.getUTCMonth();
575			switch (this.viewMode) {
576				case 0:
577					if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()) {
578						this.picker.find('.prev').css({visibility: 'hidden'});
579					} else {
580						this.picker.find('.prev').css({visibility: 'visible'});
581					}
582					if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()) {
583						this.picker.find('.next').css({visibility: 'hidden'});
584					} else {
585						this.picker.find('.next').css({visibility: 'visible'});
586					}
587					break;
588				case 1:
589				case 2:
590					if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()) {
591						this.picker.find('.prev').css({visibility: 'hidden'});
592					} else {
593						this.picker.find('.prev').css({visibility: 'visible'});
594					}
595					if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()) {
596						this.picker.find('.next').css({visibility: 'hidden'});
597					} else {
598						this.picker.find('.next').css({visibility: 'visible'});
599					}
600					break;
601			}
602		},
603
604		click: function(e) {
605			e.preventDefault();
606			var target = $(e.target).closest('span, td, th');
607			if (target.length == 1) {
608				switch(target[0].nodeName.toLowerCase()) {
609					case 'th':
610						switch(target[0].className) {
611							case 'datepicker-switch':
612								this.showMode(1);
613								break;
614							case 'prev':
615							case 'next':
616								var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1);
617								switch(this.viewMode){
618									case 0:
619										this.viewDate = this.moveMonth(this.viewDate, dir);
620										break;
621									case 1:
622									case 2:
623										this.viewDate = this.moveYear(this.viewDate, dir);
624										break;
625								}
626								this.fill();
627								break;
628							case 'today':
629								var date = new Date();
630								date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
631
632								this.showMode(-2);
633								var which = this.o.todayBtn == 'linked' ? null : 'view';
634								this._setDate(date, which);
635								break;
636							case 'clear':
637								var element;
638								if (this.isInput)
639									element = this.element;
640								else if (this.component)
641									element = this.element.find('input');
642								if (element)
643									element.val("").change();
644								this._trigger('changeDate');
645								this.update();
646								if (this.o.autoclose)
647									this.hide();
648								break;
649						}
650						break;
651					case 'span':
652						if (!target.is('.disabled')) {
653							this.viewDate.setUTCDate(1);
654							if (target.is('.month')) {
655								var day = 1;
656								var month = target.parent().find('span').index(target);
657								var year = this.viewDate.getUTCFullYear();
658								this.viewDate.setUTCMonth(month);
659								this._trigger('changeMonth', this.viewDate);
660								if (this.o.minViewMode === 1) {
661									this._setDate(UTCDate(year, month, day,0,0,0,0));
662								}
663							} else {
664								var year = parseInt(target.text(), 10)||0;
665								var day = 1;
666								var month = 0;
667								this.viewDate.setUTCFullYear(year);
668								this._trigger('changeYear', this.viewDate);
669								if (this.o.minViewMode === 2) {
670									this._setDate(UTCDate(year, month, day,0,0,0,0));
671								}
672							}
673							this.showMode(-1);
674							this.fill();
675						}
676						break;
677					case 'td':
678						if (target.is('.day') && !target.is('.disabled')){
679							var day = parseInt(target.text(), 10)||1;
680							var year = this.viewDate.getUTCFullYear(),
681								month = this.viewDate.getUTCMonth();
682							if (target.is('.old')) {
683								if (month === 0) {
684									month = 11;
685									year -= 1;
686								} else {
687									month -= 1;
688								}
689							} else if (target.is('.new')) {
690								if (month == 11) {
691									month = 0;
692									year += 1;
693								} else {
694									month += 1;
695								}
696							}
697							this._setDate(UTCDate(year, month, day,0,0,0,0));
698						}
699						break;
700				}
701			}
702		},
703
704		_setDate: function(date, which){
705			if (!which || which == 'date')
706				this.date = new Date(date);
707			if (!which || which  == 'view')
708				this.viewDate = new Date(date);
709			this.fill();
710			this.setValue();
711			this._trigger('changeDate');
712			var element;
713			if (this.isInput) {
714				element = this.element;
715			} else if (this.component){
716				element = this.element.find('input');
717			}
718			if (element) {
719				element.change();
720				if (this.o.autoclose && (!which || which == 'date')) {
721					this.hide();
722				}
723			}
724		},
725
726		moveMonth: function(date, dir){
727			if (!dir) return date;
728			var new_date = new Date(date.valueOf()),
729				day = new_date.getUTCDate(),
730				month = new_date.getUTCMonth(),
731				mag = Math.abs(dir),
732				new_month, test;
733			dir = dir > 0 ? 1 : -1;
734			if (mag == 1){
735				test = dir == -1
736					// If going back one month, make sure month is not current month
737					// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
738					? function(){ return new_date.getUTCMonth() == month; }
739					// If going forward one month, make sure month is as expected
740					// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
741					: function(){ return new_date.getUTCMonth() != new_month; };
742				new_month = month + dir;
743				new_date.setUTCMonth(new_month);
744				// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
745				if (new_month < 0 || new_month > 11)
746					new_month = (new_month + 12) % 12;
747			} else {
748				// For magnitudes >1, move one month at a time...
749				for (var i=0; i<mag; i++)
750					// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
751					new_date = this.moveMonth(new_date, dir);
752				// ...then reset the day, keeping it in the new month
753				new_month = new_date.getUTCMonth();
754				new_date.setUTCDate(day);
755				test = function(){ return new_month != new_date.getUTCMonth(); };
756			}
757			// Common date-resetting loop -- if date is beyond end of month, make it
758			// end of month
759			while (test()){
760				new_date.setUTCDate(--day);
761				new_date.setUTCMonth(new_month);
762			}
763			return new_date;
764		},
765
766		moveYear: function(date, dir){
767			return this.moveMonth(date, dir*12);
768		},
769
770		dateWithinRange: function(date){
771			return date >= this.o.startDate && date <= this.o.endDate;
772		},
773
774		keydown: function(e){
775			if (this.picker.is(':not(:visible)')){
776				if (e.keyCode == 27) // allow escape to hide and re-show picker
777					this.show();
778				return;
779			}
780			var dateChanged = false,
781				dir, day, month,
782				newDate, newViewDate;
783			switch(e.keyCode){
784				case 27: // escape
785					this.hide();
786					e.preventDefault();
787					break;
788				case 37: // left
789				case 39: // right
790					if (!this.o.keyboardNavigation) break;
791					dir = e.keyCode == 37 ? -1 : 1;
792					if (e.ctrlKey){
793						newDate = this.moveYear(this.date, dir);
794						newViewDate = this.moveYear(this.viewDate, dir);
795					} else if (e.shiftKey){
796						newDate = this.moveMonth(this.date, dir);
797						newViewDate = this.moveMonth(this.viewDate, dir);
798					} else {
799						newDate = new Date(this.date);
800						newDate.setUTCDate(this.date.getUTCDate() + dir);
801						newViewDate = new Date(this.viewDate);
802						newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir);
803					}
804					if (this.dateWithinRange(newDate)){
805						this.date = newDate;
806						this.viewDate = newViewDate;
807						this.setValue();
808						this.update();
809						e.preventDefault();
810						dateChanged = true;
811					}
812					break;
813				case 38: // up
814				case 40: // down
815					if (!this.o.keyboardNavigation) break;
816					dir = e.keyCode == 38 ? -1 : 1;
817					if (e.ctrlKey){
818						newDate = this.moveYear(this.date, dir);
819						newViewDate = this.moveYear(this.viewDate, dir);
820					} else if (e.shiftKey){
821						newDate = this.moveMonth(this.date, dir);
822						newViewDate = this.moveMonth(this.viewDate, dir);
823					} else {
824						newDate = new Date(this.date);
825						newDate.setUTCDate(this.date.getUTCDate() + dir * 7);
826						newViewDate = new Date(this.viewDate);
827						newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir * 7);
828					}
829					if (this.dateWithinRange(newDate)){
830						this.date = newDate;
831						this.viewDate = newViewDate;
832						this.setValue();
833						this.update();
834						e.preventDefault();
835						dateChanged = true;
836					}
837					break;
838				case 13: // enter
839					this.hide();
840					e.preventDefault();
841					break;
842				case 9: // tab
843					this.hide();
844					break;
845			}
846			if (dateChanged){
847				this._trigger('changeDate');
848				var element;
849				if (this.isInput) {
850					element = this.element;
851				} else if (this.component){
852					element = this.element.find('input');
853				}
854				if (element) {
855					element.change();
856				}
857			}
858		},
859
860		showMode: function(dir) {
861			if (dir) {
862				this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
863			}
864			/*
865				vitalets: fixing bug of very special conditions:
866				jquery 1.7.1 + webkit + show inline datepicker in bootstrap popover.
867				Method show() does not set display css correctly and datepicker is not shown.
868				Changed to .css('display', 'block') solve the problem.
869				See https://github.com/vitalets/x-editable/issues/37
870
871				In jquery 1.7.2+ everything works fine.
872			*/
873			//this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
874			this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).css('display', 'block');
875			this.updateNavArrows();
876		}
877	};
878
879	var DateRangePicker = function(element, options){
880		this.element = $(element);
881		this.inputs = $.map(options.inputs, function(i){ return i.jquery ? i[0] : i; });
882		delete options.inputs;
883
884		$(this.inputs)
885			.datepicker(options)
886			.bind('changeDate', $.proxy(this.dateUpdated, this));
887
888		this.pickers = $.map(this.inputs, function(i){ return $(i).data('datepicker'); });
889		this.updateDates();
890	};
891	DateRangePicker.prototype = {
892		updateDates: function(){
893			this.dates = $.map(this.pickers, function(i){ return i.date; });
894			this.updateRanges();
895		},
896		updateRanges: function(){
897			var range = $.map(this.dates, function(d){ return d.valueOf(); });
898			$.each(this.pickers, function(i, p){
899				p.setRange(range);
900			});
901		},
902		dateUpdated: function(e){
903			var dp = $(e.target).data('datepicker'),
904				new_date = dp.getUTCDate(),
905				i = $.inArray(e.target, this.inputs),
906				l = this.inputs.length;
907			if (i == -1) return;
908
909			if (new_date < this.dates[i]){
910				// Date being moved earlier/left
911				while (i>=0 && new_date < this.dates[i]){
912					this.pickers[i--].setUTCDate(new_date);
913				}
914			}
915			else if (new_date > this.dates[i]){
916				// Date being moved later/right
917				while (i<l && new_date > this.dates[i]){
918					this.pickers[i++].setUTCDate(new_date);
919				}
920			}
921			this.updateDates();
922		},
923		remove: function(){
924			$.map(this.pickers, function(p){ p.remove(); });
925			delete this.element.data().datepicker;
926		}
927	};
928
929	function opts_from_el(el, prefix){
930		// Derive options from element data-attrs
931		var data = $(el).data(),
932			out = {}, inkey,
933			replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])'),
934			prefix = new RegExp('^' + prefix.toLowerCase());
935		for (var key in data)
936			if (prefix.test(key)){
937				inkey = key.replace(replace, function(_,a){ return a.toLowerCase(); });
938				out[inkey] = data[key];
939			}
940		return out;
941	}
942
943	function opts_from_locale(lang){
944		// Derive options from locale plugins
945		var out = {};
946		// Check if "de-DE" style date is available, if not language should
947		// fallback to 2 letter code eg "de"
948		if (!dates[lang]) {
949			lang = lang.split('-')[0]
950			if (!dates[lang])
951				return;
952		}
953		var d = dates[lang];
954		$.each(locale_opts, function(i,k){
955			if (k in d)
956				out[k] = d[k];
957		});
958		return out;
959	}
960
961	var old = $.fn.datepicker;
962	
vendor: 8,839 bytes, lines 962-1245
962$.fn.datepicker = function ( option ) {
963		var args = Array.apply(null, arguments);
964		args.shift();
965		var internal_return,
966			this_return;
967		this.each(function () {
968			var $this = $(this),
969				data = $this.data('datepicker'),
970				options = typeof option == 'object' && option;
971			if (!data) {
972				var elopts = opts_from_el(this, 'date'),
973					// Preliminary otions
974					xopts = $.extend({}, defaults, elopts, options),
975					locopts = opts_from_locale(xopts.language),
976					// Options priority: js args, data-attrs, locales, defaults
977					opts = $.extend({}, defaults, locopts, elopts, options);
978				if ($this.is('.input-daterange') || opts.inputs){
979					var ropts = {
980						inputs: opts.inputs || $this.find('input').toArray()
981					};
982					$this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
983				}
984				else{
985					$this.data('datepicker', (data = new Datepicker(this, opts)));
986				}
987			}
988			if (typeof option == 'string' && typeof data[option] == 'function') {
989				internal_return = data[option].apply(data, args);
990				if (internal_return !== undefined)
991					return false;
992			}
993		});
994		if (internal_return !== undefined)
995			return internal_return;
996		else
997			return this;
998	};
999
1000	var defaults = $.fn.datepicker.defaults = {
1001		autoclose: false,
1002		beforeShowDay: $.noop,
1003		calendarWeeks: false,
1004		clearBtn: false,
1005		daysOfWeekDisabled: [],
1006		endDate: Infinity,
1007		forceParse: true,
1008		format: 'mm/dd/yyyy',
1009		keyboardNavigation: true,
1010		language: 'en',
1011		minViewMode: 0,
1012		rtl: false,
1013		startDate: -Infinity,
1014		startView: 0,
1015		todayBtn: false,
1016		todayHighlight: false,
1017		weekStart: 0
1018	};
1019	var locale_opts = $.fn.datepicker.locale_opts = [
1020		'format',
1021		'rtl',
1022		'weekStart'
1023	];
1024	$.fn.datepicker.Constructor = Datepicker;
1025	var dates = $.fn.datepicker.dates = {
1026		en: {
1027			days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
1028			daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
1029			daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
1030			months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
1031			monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1032			today: "Today",
1033			clear: "Clear"
1034		}
1035	};
1036
1037	var DPGlobal = {
1038		modes: [
1039			{
1040				clsName: 'days',
1041				navFnc: 'Month',
1042				navStep: 1
1043			},
1044			{
1045				clsName: 'months',
1046				navFnc: 'FullYear',
1047				navStep: 1
1048			},
1049			{
1050				clsName: 'years',
1051				navFnc: 'FullYear',
1052				navStep: 10
1053		}],
1054		isLeapYear: function (year) {
1055			return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
1056		},
1057		getDaysInMonth: function (year, month) {
1058			return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
1059		},
1060		validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1061		nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
1062		parseFormat: function(format){
1063			// IE treats \0 as a string end in inputs (truncating the value),
1064			// so it's a bad format delimiter, anyway
1065			var separators = format.replace(this.validParts, '\0').split('\0'),
1066				parts = format.match(this.validParts);
1067			if (!separators || !separators.length || !parts || parts.length === 0){
1068				throw new Error("Invalid date format.");
1069			}
1070			return {separators: separators, parts: parts};
1071		},
1072		parseDate: function(date, format, language) {
1073			if (date instanceof Date) return date;
1074			if (typeof format === 'string')
1075				format = DPGlobal.parseFormat(format);
1076			if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
1077				var part_re = /([\-+]\d+)([dmwy])/,
1078					parts = date.match(/([\-+]\d+)([dmwy])/g),
1079					part, dir;
1080				date = new Date();
1081				for (var i=0; i<parts.length; i++) {
1082					part = part_re.exec(parts[i]);
1083					dir = parseInt(part[1]);
1084					switch(part[2]){
1085						case 'd':
1086							date.setUTCDate(date.getUTCDate() + dir);
1087							break;
1088						case 'm':
1089							date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
1090							break;
1091						case 'w':
1092							date.setUTCDate(date.getUTCDate() + dir * 7);
1093							break;
1094						case 'y':
1095							date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
1096							break;
1097					}
1098				}
1099				return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
1100			}
1101			var parts = date && date.match(this.nonpunctuation) || [],
1102				date = new Date(),
1103				parsed = {},
1104				setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
1105				setters_map = {
1106					yyyy: function(d,v){ return d.setUTCFullYear(v); },
1107					yy: function(d,v){ return d.setUTCFullYear(2000+v); },
1108					m: function(d,v){
1109						if (isNaN(d))
1110							return d;
1111						v -= 1;
1112						while (v<0) v += 12;
1113						v %= 12;
1114						d.setUTCMonth(v);
1115						while (d.getUTCMonth() != v)
1116							d.setUTCDate(d.getUTCDate()-1);
1117						return d;
1118					},
1119					d: function(d,v){ return d.setUTCDate(v); }
1120				},
1121				val, filtered, part;
1122			setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1123			setters_map['dd'] = setters_map['d'];
1124			date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
1125			var fparts = format.parts.slice();
1126			// Remove noop parts
1127			if (parts.length != fparts.length) {
1128				fparts = $(fparts).filter(function(i,p){
1129					return $.inArray(p, setters_order) !== -1;
1130				}).toArray();
1131			}
1132			// Process remainder
1133			if (parts.length == fparts.length) {
1134				for (var i=0, cnt = fparts.length; i < cnt; i++) {
1135					val = parseInt(parts[i], 10);
1136					part = fparts[i];
1137					if (isNaN(val)) {
1138						switch(part) {
1139							case 'MM':
1140								filtered = $(dates[language].months).filter(function(){
1141									var m = this.slice(0, parts[i].length),
1142										p = parts[i].slice(0, m.length);
1143									return m == p;
1144								});
1145								val = $.inArray(filtered[0], dates[language].months) + 1;
1146								break;
1147							case 'M':
1148								filtered = $(dates[language].monthsShort).filter(function(){
1149									var m = this.slice(0, parts[i].length),
1150										p = parts[i].slice(0, m.length);
1151									return m == p;
1152								});
1153								val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
1154								break;
1155						}
1156					}
1157					parsed[part] = val;
1158				}
1159				for (var i=0, _date, s; i<setters_order.length; i++){
1160					s = setters_order[i];
1161					if (s in parsed && !isNaN(parsed[s])){
1162						_date = new Date(date);
1163						setters_map[s](_date, parsed[s]);
1164						if (!isNaN(_date))
1165							date = _date;
1166					}
1167				}
1168			}
1169			return date;
1170		},
1171		formatDate: function(date, format, language){
1172			if (typeof format === 'string')
1173				format = DPGlobal.parseFormat(format);
1174			var val = {
1175				d: date.getUTCDate(),
1176				D: dates[language].daysShort[date.getUTCDay()],
1177				DD: dates[language].days[date.getUTCDay()],
1178				m: date.getUTCMonth() + 1,
1179				M: dates[language].monthsShort[date.getUTCMonth()],
1180				MM: dates[language].months[date.getUTCMonth()],
1181				yy: date.getUTCFullYear().toString().substring(2),
1182				yyyy: date.getUTCFullYear()
1183			};
1184			val.dd = (val.d < 10 ? '0' : '') + val.d;
1185			val.mm = (val.m < 10 ? '0' : '') + val.m;
1186			var date = [],
1187				seps = $.extend([], format.separators);
1188			for (var i=0, cnt = format.parts.length; i <= cnt; i++) {
1189				if (seps.length)
1190					date.push(seps.shift());
1191				date.push(val[format.parts[i]]);
1192			}
1193			return date.join('');
1194		},
1195		headTemplate: '<thead>'+
1196							'<tr>'+
1197								'<th class="prev"><i class="icon-arrow-left"/></th>'+
1198								'<th colspan="5" class="datepicker-switch"></th>'+
1199								'<th class="next"><i class="icon-arrow-right"/></th>'+
1200							'</tr>'+
1201						'</thead>',
1202		contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1203		footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr><tr><th colspan="7" class="clear"></th></tr></tfoot>'
1204	};
1205	DPGlobal.template = '<div class="datepicker">'+
1206							'<div class="datepicker-days">'+
1207								'<table class=" table-condensed">'+
1208									DPGlobal.headTemplate+
1209									'<tbody></tbody>'+
1210									DPGlobal.footTemplate+
1211								'</table>'+
1212							'</div>'+
1213							'<div class="datepicker-months">'+
1214								'<table class="table-condensed">'+
1215									DPGlobal.headTemplate+
1216									DPGlobal.contTemplate+
1217									DPGlobal.footTemplate+
1218								'</table>'+
1219							'</div>'+
1220							'<div class="datepicker-years">'+
1221								'<table class="table-condensed">'+
1222									DPGlobal.headTemplate+
1223									DPGlobal.contTemplate+
1224									DPGlobal.footTemplate+
1225								'</table>'+
1226							'</div>'+
1227						'</div>';
1228
1229	$.fn.datepicker.DPGlobal = DPGlobal;
1230
1231
1232	/* DATEPICKER NO CONFLICT
1233	* =================== */
1234
1235	$.fn.datepicker.noConflict = function(){
1236		$.fn.datepicker = old;
1237		return this;
1238	};
1239
1240
1241	/* DATEPICKER DATA-API
1242	* ================== */
1243
1244	$(document).on(
1245		'focus.datepicker.data-api click.datepicker.data-api',
1246		'[data-provide="datepicker"]',
1247		function(e){
1248			var $this = $(this);
1249			if ($this.data('datepicker')) return;
1250			e.preventDefault();
1251			// component click requires us to explicitly show it
1252			$this.datepicker('show');
1253		}
1254	);
1255	$(function(){
1256		$('[data-provide="datepicker-inline"]').datepicker();
1257	});
1258
1259}( window.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.