PageSourceSearch

https://www.regnum-zegg.at/fileadmin/templates/js/daterangepicker/jquery.daterangepicker.min.js?1732704309

js regnum-zegg.at collected 2026-10-10 01:14:53 UTC 114,893 bytes, 2,673 lines download raw bytes

1// jquery.daterangepicker.js
2// author : Chunlong Liu
3// license : MIT
4// www.jszen.com
5
6(function(factory) {
7    if (typeof define === 'function' && define.amd) {
8        // AMD. Register as an anonymous module.
9        define(['jquery', 'moment'], factory);
10    } else if (typeof exports === 'object' && typeof module !== 'undefined') {
11        // CommonJS. Register as a module
12        module.exports = factory(require('jquery'), require('moment'));
13    } else {
14        // Browser globals
15        factory(jQuery, moment);
16    }
17}(function($, moment) {
18    'use strict';
19    $.dateRangePickerLanguages = {
20        "default": //default language: English
21        {
22            "selected": "Selected:",
23            "day": "Day",
24            "days": "Days",
25            "apply": "Close",
26            "week-1": "mo",
27            "week-2": "tu",
28            "week-3": "we",
29            "week-4": "th",
30            "week-5": "fr",
31            "week-6": "sa",
32            "week-7": "su",
33            "week-number": "W",
34            "month-name": ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"],
35            "shortcuts": "Shortcuts",
36            "custom-values": "Custom Values",
37            "past": "Past",
38            "following": "Following",
39            "previous": "Previous",
40            "prev-week": "Week",
41            "prev-month": "Month",
42            "prev-year": "Year",
43            "next": "Next",
44            "next-week": "Week",
45            "next-month": "Month",
46            "next-year": "Year",
47            "less-than": "Date range should not be more than %d days",
48            "more-than": "Date range should not be less than %d days",
49            "default-more": "Please select a date range longer than %d days",
50            "default-single": "Please select a date",
51            "default-less": "Please select a date range less than %d days",
52            "default-range": "Please select a date range between %d and %d days",
53            "default-default": "Please select a date range",
54            "time": "Time",
55            "hour": "Hour",
56            "minute": "Minute"
57        },
58        "id": {
59            "selected": "Terpilih:",
60            "day": "Hari",
61            "days": "Hari",
62            "apply": "Tutup",
63            "week-1": "sen",
64            "week-2": "sel",
65            "week-3": "rab",
66            "week-4": "kam",
67            "week-5": "jum",
68            "week-6": "sab",
69            "week-7": "min",
70            "week-number": "W",
71            "month-name": ["januari", "februari", "maret", "april", "mei", "juni", "juli", "agustus", "september", "oktober", "november", "desember"],
72            "shortcuts": "Pintas",
73            "custom-values": "Nilai yang ditentukan",
74            "past": "Yang Lalu",
75            "following": "Mengikuti",
76            "previous": "Sebelumnya",
77            "prev-week": "Minggu",
78            "prev-month": "Bulan",
79            "prev-year": "Tahun",
80            "next": "Selanjutnya",
81            "next-week": "Minggu",
82            "next-month": "Bulan",
83            "next-year": "Tahun",
84            "less-than": "Tanggal harus lebih dari %d hari",
85            "more-than": "Tanggal harus kurang dari %d hari",
86            "default-more": "Jarak tanggal harus lebih lama dari %d hari",
87            "default-single": "Silakan pilih tanggal",
88            "default-less": "Jarak rentang tanggal tidak boleh lebih lama dari %d hari",
89            "default-range": "Rentang tanggal harus antara %d dan %d hari",
90            "default-default": "Silakan pilih rentang tanggal",
91            "time": "Waktu",
92            "hour": "Jam",
93            "minute": "Menit"
94        },
95        "az": {
96            "selected": "Seçildi:",
97            "day": " gün",
98            "days": " gün",
99            "apply": "tətbiq",
100            "week-1": "1",
101            "week-2": "2",
102            "week-3": "3",
103            "week-4": "4",
104            "week-5": "5",
105            "week-6": "6",
106            "week-7": "7",
107            "month-name": ["yanvar", "fevral", "mart", "aprel", "may", "iyun", "iyul", "avqust", "sentyabr", "oktyabr", "noyabr", "dekabr"],
108            "shortcuts": "Qısayollar",
109            "past": "Keçmiş",
110            "following": "Növbəti",
111            "previous": "   ",
112            "prev-week": "Öncəki həftə",
113            "prev-month": "Öncəki ay",
114            "prev-year": "Öncəki il",
115            "next": "   ",
116            "next-week": "Növbəti həftə",
117            "next-month": "Növbəti ay",
118            "next-year": "Növbəti il",
119            "less-than": "Tarix aralığı %d gündən çox olmamalıdır",
120            "more-than": "Tarix aralığı %d gündən az olmamalıdır",
121            "default-more": "%d gündən çox bir tarix seçin",
122            "default-single": "Tarix seçin",
123            "default-less": "%d gündən az bir tarix seçin",
124            "default-range": "%d və %d gün aralığında tarixlər seçin",
125            "default-default": "Tarix aralığı seçin"
126        },
127        "bg": {
128            "selected": "Избрано:",
129            "day": "Ден",
130            "days": "Дни",
131            "apply": "Затвори",
132            "week-1": "пн",
133            "week-2": "вт",
134            "week-3": "ср",
135            "week-4": "чт",
136            "week-5": "пт",
137            "week-6": "сб",
138            "week-7": "нд",
139            "week-number": "С",
140            "month-name": ["януари", "февруари", "март", "април", "май", "юни", "юли", "август", "септември", "октомври", "ноември", "декември"],
141            "shortcuts": "Преки пътища",
142            "custom-values": "Персонализирани стойности",
143            "past": "Минал",
144            "following": "Следващ",
145            "previous": "Предишен",
146            "prev-week": "Седмица",
147            "prev-month": "Месец",
148            "prev-year": "Година",
149            "next": "Следващ",
150            "next-week": "Седмица",
151            "next-month": "Месец",
152            "next-year": "Година",
153            "less-than": "Периодът от време не трябва да е повече от %d дни",
154            "more-than": "Периодът от време не трябва да е по-малко от %d дни",
155            "default-more": "Моля изберете период по-дълъг от %d дни",
156            "default-single": "Моля изберете дата",
157            "default-less": "Моля изберете период по-къс от %d дни",
158            "default-range": "Моля изберете период между %d и %d дни",
159            "default-default": "Моля изберете период",
160            "time": "Време",
161            "hour": "Час",
162            "minute": "Минута"
163        },
164        "cn": //simplified chinese
165        {
166            "selected": "已选择:",
167            "day": "天",
168            "days": "天",
169            "apply": "确定",
170            "week-1": "一",
171            "week-2": "二",
172            "week-3": "三",
173            "week-4": "四",
174            "week-5": "五",
175            "week-6": "六",
176            "week-7": "日",
177            "week-number": "周",
178            "month-name": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
179            "shortcuts": "快捷选择",
180            "past": "过去",
181            "following": "将来",
182            "previous": "   ",
183            "prev-week": "上周",
184            "prev-month": "上个月",
185            "prev-year": "去年",
186            "next": "   ",
187            "next-week": "下周",
188            "next-month": "下个月",
189            "next-year": "明年",
190            "less-than": "所选日期范围不能大于%d天",
191            "more-than": "所选日期范围不能小于%d天",
192            "default-more": "请选择大于%d天的日期范围",
193            "default-less": "请选择小于%d天的日期范围",
194            "default-range": "请选择%d天到%d天的日期范围",
195            "default-single": "请选择一个日期",
196            "default-default": "请选择一个日期范围",
197            "time": "时间",
198            "hour": "小时",
199            "minute": "分钟"
200        },
201        "cz": {
202            "selected": "Vybráno:",
203            "day": "Den",
204            "days": "Dny",
205            "apply": "Zavřít",
206            "week-1": "po",
207            "week-2": "út",
208            "week-3": "st",
209            "week-4": "čt",
210            "week-5": "pá",
211            "week-6": "so",
212            "week-7": "ne",
213            "month-name": ["leden", "únor", "březen", "duben", "květen", "červen", "červenec", "srpen", "září", "říjen", "listopad", "prosinec"],
214            "shortcuts": "Zkratky",
215            "past": "po",
216            "following": "následující",
217            "previous": "předchozí",
218            "prev-week": "týden",
219            "prev-month": "měsíc",
220            "prev-year": "rok",
221            "next": "další",
222            "next-week": "týden",
223            "next-month": "měsíc",
224            "next-year": "rok",
225            "less-than": "Rozsah data by neměl být větší než %d dnů",
226            "more-than": "Rozsah data by neměl být menší než %d dnů",
227            "default-more": "Prosím zvolte rozsah data větší než %d dnů",
228            "default-single": "Prosím zvolte datum",
229            "default-less": "Prosím zvolte rozsah data menší než %d dnů",
230            "default-range": "Prosím zvolte rozsah data mezi %d a %d dny",
231            "default-default": "Prosím zvolte rozsah data"
232        },
233        "de": {
234            "selected": "Auswahl:",
235            "day": "Tag",
236            "days": "Tage",
237            "apply": "Schließen",
238            "week-1": "mo",
239            "week-2": "di",
240            "week-3": "mi",
241            "week-4": "do",
242            "week-5": "fr",
243            "week-6": "sa",
244            "week-7": "so",
245            "month-name": ["januar", "februar", "märz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember"],
246            "shortcuts": "Schnellwahl",
247            "past": "Vorherige",
248            "following": "Folgende",
249            "previous": "Vorherige",
250            "prev-week": "Woche",
251            "prev-month": "Monat",
252            "prev-year": "Jahr",
253            "next": "Nächste",
254            "next-week": "Woche",
255            "next-month": "Monat",
256            "next-year": "Jahr",
257            "less-than": "Datumsbereich darf nicht größer sein als %d Tage",
258            "more-than": "Datumsbereich darf nicht kleiner sein als %d Tage",
259            "default-more": "Bitte mindestens %d Tage auswählen",
260            "default-single": "Bitte ein Datum auswählen",
261            "default-less": "Bitte weniger als %d Tage auswählen",
262            "default-range": "Bitte einen Datumsbereich zwischen %d und %d Tagen auswählen",
263            "default-default": "Bitte ein Start- und Enddatum auswählen",
264            "Time": "Zeit",
265            "hour": "Stunde",
266            "minute": "Minute"
267        },
268        "es": {
269            "selected": "Seleccionado:",
270            "day": "Día",
271            "days": "Días",
272            "apply": "Cerrar",
273            "week-1": "lu",
274            "week-2": "ma",
275            "week-3": "mi",
276            "week-4": "ju",
277            "week-5": "vi",
278            "week-6": "sa",
279            "week-7": "do",
280            "month-name": ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"],
281            "shortcuts": "Accesos directos",
282            "past": "Pasado",
283            "following": "Siguiente",
284            "previous": "Anterior",
285            "prev-week": "Semana",
286            "prev-month": "Mes",
287            "prev-year": "Año",
288            "next": "Siguiente",
289            "next-week": "Semana",
290            "next-month": "Mes",
291            "next-year": "Año",
292            "less-than": "El rango no debería ser mayor de %d días",
293            "more-than": "El rango no debería ser menor de %d días",
294            "default-more": "Por favor selecciona un rango mayor a %d días",
295            "default-single": "Por favor selecciona un día",
296            "default-less": "Por favor selecciona un rango menor a %d días",
297            "default-range": "Por favor selecciona un rango entre %d y %d días",
298            "default-default": "Por favor selecciona un rango de fechas."
299        },
300        "fr": {
301            "selected": "Sélection:",
302            "day": "Jour",
303            "days": "Jours",
304            "apply": "Fermer",
305            "week-1": "lu",
306            "week-2": "ma",
307            "week-3": "me",
308            "week-4": "je",
309            "week-5": "ve",
310            "week-6": "sa",
311            "week-7": "di",
312            "month-name": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
313            "shortcuts": "Raccourcis",
314            "past": "Passé",
315            "following": "Suivant",
316            "previous": "Précédent",
317            "prev-week": "Semaine",
318            "prev-month": "Mois",
319            "prev-year": "Année",
320            "next": "Suivant",
321            "next-week": "Semaine",
322            "next-month": "Mois",
323            "next-year": "Année",
324            "less-than": "L'intervalle ne doit pas être supérieure à %d jours",
325            "more-than": "L'intervalle ne doit pas être inférieure à %d jours",
326            "default-more": "Merci de choisir une intervalle supérieure à %d jours",
327            "default-single": "Merci de choisir une date",
328            "default-less": "Merci de choisir une intervalle inférieure %d jours",
329            "default-range": "Merci de choisir une intervalle comprise entre %d et %d jours",
330            "default-default": "Merci de choisir une date"
331        },
332        "hu": {
333            "selected": "Kiválasztva:",
334            "day": "Nap",
335            "days": "Nap",
336            "apply": "Ok",
337            "week-1": "h",
338            "week-2": "k",
339            "week-3": "sz",
340            "week-4": "cs",
341            "week-5": "p",
342            "week-6": "sz",
343            "week-7": "v",
344            "month-name": ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"],
345            "shortcuts": "Gyorsválasztó",
346            "past": "Múlt",
347            "following": "Következő",
348            "previous": "Előző",
349            "prev-week": "Hét",
350            "prev-month": "Hónap",
351            "prev-year": "Év",
352            "next": "Következő",
353            "next-week": "Hét",
354            "next-month": "Hónap",
355            "next-year": "Év",
356            "less-than": "A kiválasztás nem lehet több %d napnál",
357            "more-than": "A kiválasztás nem lehet több %d napnál",
358            "default-more": "Válassz ki egy időszakot ami hosszabb mint %d nap",
359            "default-single": "Válassz egy napot",
360            "default-less": "Válassz ki egy időszakot ami rövidebb mint %d nap",
361            "default-range": "Válassz ki egy %d - %d nap hosszú időszakot",
362            "default-default": "Válassz ki egy időszakot"
363        },
364        "it": {
365            "selected": "Selezionati:",
366            "day": "Giorno",
367            "days": "Giorni",
368            "apply": "Chiudi",
369            "week-1": "lu",
370            "week-2": "ma",
371            "week-3": "me",
372            "week-4": "gi",
373            "week-5": "ve",
374            "week-6": "sa",
375            "week-7": "do",
376            "month-name": ["gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"],
377            "shortcuts": "Scorciatoie",
378            "past": "Scorso",
379            "following": "Successivo",
380            "previous": "Precedente",
381            "prev-week": "Settimana",
382            "prev-month": "Mese",
383            "prev-year": "Anno",
384            "next": "Prossimo",
385            "next-week": "Settimana",
386            "next-month": "Mese",
387            "next-year": "Anno",
388            "less-than": "L'intervallo non dev'essere maggiore di %d giorni",
389            "more-than": "L'intervallo non dev'essere minore di %d giorni",
390            "default-more": "Seleziona un intervallo maggiore di %d giorni",
391            "default-single": "Seleziona una data",
392            "default-less": "Seleziona un intervallo minore di %d giorni",
393            "default-range": "Seleziona un intervallo compreso tra i %d e i %d giorni",
394            "default-default": "Seleziona un intervallo di date"
395        },
396        "ko": {
397            "selected": "기간:",
398            "day": "일",
399            "days": "일간",
400            "apply": "닫기",
401            "week-1": "월",
402            "week-2": "화",
403            "week-3": "수",
404            "week-4": "목",
405            "week-5": "금",
406            "week-6": "토",
407            "week-7": "일",
408            "week-number": "주",
409            "month-name": ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
410            "shortcuts": "단축키들",
411            "past": "지난(오늘기준)",
412            "following": "이후(오늘기준)",
413            "previous": "이전",
414            "prev-week": "1주",
415            "prev-month": "1달",
416            "prev-year": "1년",
417            "next": "다음",
418            "next-week": "1주",
419            "next-month": "1달",
420            "next-year": "1년",
421            "less-than": "날짜 범위는 %d 일보다 많을 수 없습니다",
422            "more-than": "날짜 범위는 %d 일보다 작을 수 없습니다",
423            "default-more": "날짜 범위를 %d 일보다 길게 선택해 주세요",
424            "default-single": "날짜를 선택해 주세요",
425            "default-less": "%d 일보다 작은 날짜를 선택해 주세요",
426            "default-range": "%d와 %d 일 사이의 날짜 범위를 선택해 주세요",
427            "default-default": "날짜 범위를 선택해 주세요",
428            "time": "시각",
429            "hour": "시",
430            "minute": "분"
431        },
432        "no": {
433            "selected": "Valgt:",
434            "day": "Dag",
435            "days": "Dager",
436            "apply": "Lukk",
437            "week-1": "ma",
438            "week-2": "ti",
439            "week-3": "on",
440            "week-4": "to",
441            "week-5": "fr",
442            "week-6": "lø",
443            "week-7": "sø",
444            "month-name": ["januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember"],
445            "shortcuts": "Snarveier",
446            "custom-values": "Egendefinerte Verdier",
447            "past": "Over", // Not quite sure about the context of this one
448            "following": "Følger",
449            "previous": "Forrige",
450            "prev-week": "Uke",
451            "prev-month": "MÃ¥ned",
452            "prev-year": "År",
453            "next": "Neste",
454            "next-week": "Uke",
455            "next-month": "MÃ¥ned",
456            "next-year": "År",
457            "less-than": "Datoperioden skal ikkje være lengre enn %d dager",
458            "more-than": "Datoperioden skal ikkje være kortere enn %d dager",
459            "default-more": "Vennligst velg ein datoperiode lengre enn %d dager",
460            "default-single": "Vennligst velg ein dato",
461            "default-less": "Vennligst velg ein datoperiode mindre enn %d dager",
462            "default-range": "Vennligst velg ein datoperiode mellom %d og %d dager",
463            "default-default": "Vennligst velg ein datoperiode",
464            "time": "Tid",
465            "hour": "Time",
466            "minute": "Minutter"
467        },
468        "nl": {
469            "selected": "Geselecteerd:",
470            "day": "Dag",
471            "days": "Dagen",
472            "apply": "Ok",
473            "week-1": "ma",
474            "week-2": "di",
475            "week-3": "wo",
476            "week-4": "do",
477            "week-5": "vr",
478            "week-6": "za",
479            "week-7": "zo",
480            "month-name": ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"],
481            "shortcuts": "Snelkoppelingen",
482            "custom-values": "Aangepaste waarden",
483            "past": "Verleden",
484            "following": "Komend",
485            "previous": "Vorige",
486            "prev-week": "Week",
487            "prev-month": "Maand",
488            "prev-year": "Jaar",
489            "next": "Volgende",
490            "next-week": "Week",
491            "next-month": "Maand",
492            "next-year": "Jaar",
493            "less-than": "Interval moet langer dan %d dagen zijn",
494            "more-than": "Interval mag niet minder dan %d dagen zijn",
495            "default-more": "Selecteer een interval langer dan %dagen",
496            "default-single": "Selecteer een datum",
497            "default-less": "Selecteer een interval minder dan %d dagen",
498            "default-range": "Selecteer een interval tussen %d en %d dagen",
499            "default-default": "Selecteer een interval",
500            "time": "Tijd",
501            "hour": "Uur",
502            "minute": "Minuut"
503        },
504        "ru": {
505            "selected": "Выбрано:",
506            "day": "День",
507            "days": "Дней",
508            "apply": "Применить",
509            "week-1": "пн",
510            "week-2": "вт",
511            "week-3": "ср",
512            "week-4": "чт",
513            "week-5": "пт",
514            "week-6": "сб",
515            "week-7": "вс",
516            "month-name": ["январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"],
517            "shortcuts": "Быстрый выбор",
518            "custom-values": "Пользовательские значения",
519            "past": "Прошедшие",
520            "following": "Следующие",
521            "previous": "   ",
522            "prev-week": "Неделя",
523            "prev-month": "Месяц",
524            "prev-year": "Год",
525            "next": "   ",
526            "next-week": "Неделя",
527            "next-month": "Месяц",
528            "next-year": "Год",
529            "less-than": "Диапазон не может быть больше %d дней",
530            "more-than": "Диапазон не может быть меньше %d дней",
531            "default-more": "Пожалуйста выберите диапазон больше %d дней",
532            "default-single": "Пожалуйста выберите дату",
533            "default-less": "Пожалуйста выберите диапазон меньше %d дней",
534            "default-range": "Пожалуйста вÑ
534‹Ð±ÐµÑ€Ð¸Ñ‚е диапазон между %d и %d днями",
535            "default-default": "Пожалуйста выберите диапазон",
536            "time": "Время",
537            "hour": "Часы",
538            "minute": "Минуты"
539        },
540        "uk": {
541            "selected": "Вибрано:",
542            "day": "День",
543            "days": "Днів",
544            "apply": "Застосувати",
545            "week-1": "пн",
546            "week-2": "вт",
547            "week-3": "ср",
548            "week-4": "чт",
549            "week-5": "пт",
550            "week-6": "сб",
551            "week-7": "нд",
552            "month-name": ["січень", "лютий", "березень", "квітень", "травень", "червень", "липень", "серпень", "вересень", "жовтень", "листопад", "грудень"],
553            "shortcuts": "Швидкий вибір",
554            "custom-values": "Значення користувача",
555            "past": "Минулі",
556            "following": "Наступні",
557            "previous": "   ",
558            "prev-week": "Тиждень",
559            "prev-month": "Місяць",
560            "prev-year": "Рік",
561            "next": "   ",
562            "next-week": "Тиждень",
563            "next-month": "Місяць",
564            "next-year": "Рік",
565            "less-than": "Діапазон не може бути більш ніж %d днів",
566            "more-than": "Діапазон не може бути меньш ніж %d днів",
567            "default-more": "Будь ласка виберіть діапазон більше %d днів",
568            "default-single": "Будь ласка виберіть дату",
569            "default-less": "Будь ласка виберіть діапазон менше %d днів",
570            "default-range": "Будь ласка виберіть діапазон між %d та %d днями",
571            "default-default": "Будь ласка виберіть діапазон",
572            "time": "Час",
573            "hour": "Години",
574            "minute": "Хвилини"
575        },
576        "pl": {
577            "selected": "Wybrany:",
578            "day": "Dzień",
579            "days": "Dni",
580            "apply": "Zamknij",
581            "week-1": "pon",
582            "week-2": "wt",
583            "week-3": "śr",
584            "week-4": "czw",
585            "week-5": "pt",
586            "week-6": "so",
587            "week-7": "nd",
588            "month-name": ["styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"],
589            "shortcuts": "Skróty",
590            "custom-values": "Niestandardowe wartości",
591            "past": "Przeszłe",
592            "following": "Następne",
593            "previous": "Poprzednie",
594            "prev-week": "tydzień",
595            "prev-month": "miesiąc",
596            "prev-year": "rok",
597            "next": "Następny",
598            "next-week": "tydzień",
599            "next-month": "miesiąc",
600            "next-year": "rok",
601            "less-than": "Okres nie powinien być dłuższy niż %d dni",
602            "more-than": "Okres nie powinien być krótszy niż  %d ni",
603            "default-more": "Wybierz okres dłuższy niż %d dni",
604            "default-single": "Wybierz datę",
605            "default-less": "Wybierz okres krótszy niż %d dni",
606            "default-range": "Wybierz okres trwający od %d do %d dni",
607            "default-default": "Wybierz okres",
608            "time": "Czas",
609            "hour": "Godzina",
610            "minute": "Minuta"
611        },
612        "se": {
613            "selected": "Vald:",
614            "day": "dag",
615            "days": "dagar",
616            "apply": "godkänn",
617            "week-1": "ma",
618            "week-2": "ti",
619            "week-3": "on",
620            "week-4": "to",
621            "week-5": "fr",
622            "week-6": "lö",
623            "week-7": "sö",
624            "month-name": ["januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"],
625            "shortcuts": "genvägar",
626            "custom-values": "Anpassade värden",
627            "past": "över",
628            "following": "följande",
629            "previous": "förra",
630            "prev-week": "vecka",
631            "prev-month": "månad",
632            "prev-year": "Ã¥r",
633            "next": "nästa",
634            "next-week": "vecka",
635            "next-month": "måned",
636            "next-year": "Ã¥r",
637            "less-than": "Datumintervall bör inte vara mindre än %d dagar",
638            "more-than": "Datumintervall bör inte vara mer än %d dagar",
639            "default-more": "Välj ett datumintervall längre än %d dagar",
640            "default-single": "Välj ett datum",
641            "default-less": "Välj ett datumintervall mindre än %d dagar",
642            "default-range": "Välj ett datumintervall mellan %d och %d dagar",
643            "default-default": "Välj ett datumintervall",
644            "time": "tid",
645            "hour": "timme",
646            "minute": "minut"
647        },
648        "pt": //Portuguese (European)
649        {
650            "selected": "Selecionado:",
651            "day": "Dia",
652            "days": "Dias",
653            "apply": "Fechar",
654            "week-1": "seg",
655            "week-2": "ter",
656            "week-3": "qua",
657            "week-4": "qui",
658            "week-5": "sex",
659            "week-6": "sab",
660            "week-7": "dom",
661            "week-number": "N",
662            "month-name": ["janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"],
663            "shortcuts": "Atalhos",
664            "custom-values": "Valores Personalizados",
665            "past": "Passado",
666            "following": "Seguinte",
667            "previous": "Anterior",
668            "prev-week": "Semana",
669            "prev-month": "Mês",
670            "prev-year": "Ano",
671            "next": "Próximo",
672            "next-week": "Próxima Semana",
673            "next-month": "Próximo Mês",
674            "next-year": "Próximo Ano",
675            "less-than": "O período selecionado não deve ser maior que %d dias",
676            "more-than": "O período selecionado não deve ser menor que %d dias",
677            "default-more": "Selecione um período superior a %d dias",
678            "default-single": "Selecione uma data",
679            "default-less": "Selecione um período inferior a %d dias",
680            "default-range": "Selecione um período de %d a %d dias",
681            "default-default": "Selecione um período",
682            "time": "Tempo",
683            "hour": "Hora",
684            "minute": "Minuto"
685        },
686        "tc": // traditional chinese
687        {
688            "selected": "已選擇:",
689            "day": "天",
690            "days": "天",
691            "apply": "確定",
692            "week-1": "一",
693            "week-2": "二",
694            "week-3": "三",
695            "week-4": "四",
696            "week-5": "五",
697            "week-6": "六",
698            "week-7": "日",
699            "week-number": "週",
700            "month-name": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
701            "shortcuts": "快速選擇",
702            "past": "過去",
703            "following": "將來",
704            "previous": "   ",
705            "prev-week": "上週",
706            "prev-month": "上個月",
707            "prev-year": "去年",
708            "next": "   ",
709            "next-week": "下週",
710            "next-month": "下個月",
711            "next-year": "明年",
712            "less-than": "所選日期範圍不能大於%d天",
713            "more-than": "所選日期範圍不能小於%d天",
714            "default-more": "請選擇大於%d天的日期範圍",
715            "default-less": "請選擇少於%d天的日期範圍",
716            "default-range": "請選擇%d天到%d天的日期範圍",
717            "default-single": "請選擇一個日期",
718            "default-default": "請選擇一個日期範圍",
719            "time": "日期",
720            "hour": "小時",
721            "minute": "分鐘"
722        },
723        "ja": {
724            "selected": "選択しました:",
725            "day": "日",
726            "days": "日",
727            "apply": "確定",
728            "week-1": "月",
729            "week-2": "火",
730            "week-3": "æ°´",
731            "week-4": "木",
732            "week-5": "金",
733            "week-6": "土",
734            "week-7": "日",
735            "month-name": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
736            "shortcuts": "クイック選択",
737            "past": "過去",
738            "following": "将来",
739            "previous": "   ",
740            "prev-week": "先週",
741            "prev-month": "先月",
742            "prev-year": "昨年",
743            "next": "   ",
744            "next-week": "来週",
745            "next-month": "来月",
746            "next-year": "来年",
747            "less-than": "日付の範囲は%d日以上にすべきではありません",
748            "more-than": "日付の範囲は%d日を下回ってはいけません",
749            "default-more": "%d日よりも長い期間を選択してください",
750            "default-less": "%d日未満の期間を選択してください",
751            "default-range": "%d日と%d日の間の日付範囲を選択してください",
752            "default-single": "日付を選択してください",
753            "default-default": "日付範囲を選択してください",
754            "time": "時間",
755            "hour": "時間",
756            "minute": "分"
757        },
758        "da": {
759            "selected": "Valgt:",
760            "day": "Dag",
761            "days": "Dage",
762            "apply": "Luk",
763            "week-1": "ma",
764            "week-2": "ti",
765            "week-3": "on",
766            "week-4": "to",
767            "week-5": "fr",
768            "week-6": "lø",
769            "week-7": "sø",
770            "month-name": ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december"],
771            "shortcuts": "genveje",
772            "custom-values": "Brugerdefinerede værdier",
773            "past": "Forbi",
774            "following": "Følgende",
775            "previous": "Forrige",
776            "prev-week": "uge",
777            "prev-month": "måned",
778            "prev-year": "Ã¥r",
779            "next": "Næste",
780            "next-week": "uge",
781            "next-month": "måned",
782            "next-year": "Ã¥r",
783            "less-than": "Dato interval bør ikke være med end %d dage",
784            "more-than": "Dato interval bør ikke være mindre end %d dage",
785            "default-more": "Vælg datointerval længere end %d dage",
786            "default-single": "Vælg dato",
787            "default-less": "Vælg datointerval mindre end %d dage",
788            "default-range": "Vælg datointerval mellem %d og %d dage",
789            "default-default": "Vælg datointerval",
790            "time": "tid",
791            "hour": "time",
792            "minute": "minut"
793        },
794        "fi": // Finnish
795        {
796            "selected": "Valittu:",
797            "day": "Päivä",
798            "days": "Päivää",
799            "apply": "Sulje",
800            "week-1": "ma",
801            "week-2": "ti",
802            "week-3": "ke",
803            "week-4": "to",
804            "week-5": "pe",
805            "week-6": "la",
806            "week-7": "su",
807            "week-number": "V",
808            "month-name": ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"],
809            "shortcuts": "Pikavalinnat",
810            "custom-values": "Mukautetut Arvot",
811            "past": "Menneet",
812            "following": "Tulevat",
813            "previous": "Edellinen",
814            "prev-week": "Viikko",
815            "prev-month": "Kuukausi",
816            "prev-year": "Vuosi",
817            "next": "Seuraava",
818            "next-week": "Viikko",
819            "next-month": "Kuukausi",
820            "next-year": "Vuosi",
821            "less-than": "Aikajakson tulisi olla vähemmän kuin %d päivää",
822            "more-than": "Aikajakson ei tulisi olla vähempää kuin %d päivää",
823            "default-more": "Valitse pidempi aikajakso kuin %d päivää",
824            "default-single": "Valitse päivä",
825            "default-less": "Valitse lyhyempi aikajakso kuin %d päivää",
826            "default-range": "Valitse aikajakso %d ja %d päivän väliltä",
827            "default-default": "Valitse aikajakso",
828            "time": "Aika",
829            "hour": "Tunti",
830            "minute": "Minuutti"
831        },
832        "cat": // Catala
833        {
834            "selected": "Seleccionats:",
835            "day": "Dia",
836            "days": "Dies",
837            "apply": "Tanca",
838            "week-1": "Dl",
839            "week-2": "Dm",
840            "week-3": "Dc",
841            "week-4": "Dj",
842            "week-5": "Dv",
843            "week-6": "Ds",
844            "week-7": "Dg",
845            "week-number": "S",
846            "month-name": ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"],
847            "shortcuts": "Dreçeres",
848            "custom-values": "Valors personalitzats",
849            "past": "Passat",
850            "following": "Futur",
851            "previous": "Anterior",
852            "prev-week": "Setmana",
853            "prev-month": "Mes",
854            "prev-year": "Any",
855            "next": "Següent",
856            "next-week": "Setmana",
857            "next-month": "Mes",
858            "next-year": "Any",
859            "less-than": "El període no hauria de ser de més de %d dies",
860            "more-than": "El període no hauria de ser de menys de %d dies",
861            "default-more": "Perfavor selecciona un període més gran de %d dies",
862            "default-single": "Perfavor selecciona una data",
863            "default-less": "Perfavor selecciona un període de menys de %d dies",
864            "default-range": "Perfavor selecciona un període d'entre %d i %d dies",
865            "default-default": "Perfavor selecciona un període",
866            "time": "Temps",
867            "hour": "Hora",
868            "minute": "Minut"
869        },
870        "sk": {
871            "selected": "Vybrané:",
872            "day": "Deň",
873            "days": "Dni",
874            "apply": "Zavrieť",
875            "week-1": "po",
876            "week-2": "út",
877            "week-3": "st",
878            "week-4": "št",
879            "week-5": "pi",
880            "week-6": "so",
881            "week-7": "ne",
882            "week-number": "T",
883            "month-name": ["január", "február", "marec", "apríl", "máj", "jún", "júl", "august", "september", "október", "november", "december"],
884            "shortcuts": "Skratky",
885            "custom-values": "Vlastné hodnoty",
886            "past": "po",
887            "following": "nasledujúci",
888            "previous": "predchádzajúci",
889            "prev-week": "týždeň",
890            "prev-month": "mesiac",
891            "prev-year": "rok",
892            "next": "ďalší",
893            "next-week": "týždeň",
894            "next-month": "mesiac",
895            "next-year": "rok",
896            "less-than": "Rozsah dátumu by nemal byť väčší ako %d dní",
897            "more-than": "Rozsah dátumu by nemal byť menší ako %d dní",
898            "default-more": "Prosím zvoľte rozsah dlhší ako %d dní",
899            "default-single": "Prosím zvoľte dátum",
900            "default-less": "Prosím zvoľte rozsah menší ako %d dní",
901            "default-range": "Prosím zvoľte rozsah medzi %d a %d dňami",
902            "default-default": "Prosím zvoľte rozsah",
903            "time": "Čas",
904            "hour": "Hodina",
905            "minute": "Minúta"
906        },
907        "tr": {
908            "selected": "Seçildi:",
909            "day": " gün",
910            "days": " gün",
911            "apply": "Uygula",
912            "week-1": "Pzt",
913            "week-2": "Sal",
914            "week-3": "Çar",
915            "week-4": "Per",
916            "week-5": "Cuma",
917            "week-6": "Cmt",
918            "week-7": "Paz",
919            "week-number": "H",
920            "month-name": ["Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"],
921            "shortcuts": "Kısayollar",
922            "custom-values": "Özel Değerler",
923            "past": "Geçmiş",
924            "following": "Sonraki",
925            "previous": "   ",
926            "prev-week": "Önceki Hafta",
927            "prev-month": "Önceki Ay",
928            "prev-year": "Öncəki Yıl",
929            "next": "   ",
930            "next-week": "Sonraki Hafta",
931            "next-month": "Sonraki Ay",
932            "next-year": "Sonraki Yıl",
933            "less-than": "Tarih aralığı %d günden çok olmamalıdır",
934            "more-than": "Tarih aralığı %d günden az olmamalıdır",
935            "default-more": "%d günden çok bir tarih seçin",
936            "default-single": "Tarih seçin",
937            "default-less": "%d günden az bir tarih seçin",
938            "default-range": "%d ve %d gün aralığında tarihler seçin",
939            "default-default": "Tarih aralığı seçin",
940            "time": "Zaman",
941            "hour": "Saat",
942            "minute": "Dakika"
943        },
944    };
945
946    $.fn.dateRangePicker = function(opt) {
947        if (!opt) opt = {};
948        opt = $.extend(true, {
949            autoClose: false,
950            format: 'YYYY-MM-DD',
951            separator: ' to ',
952            language: 'auto',
953            startOfWeek: 'sunday', // or monday
954            getValue: function() {
955                return $(this).val();
956            },
957            setValue: function(s) {
958                if (!$(this).attr('readonly') && !$(this).is(':disabled') && s != $(this).val()) {
959                    $(this).val(s);
960                }
961            },
962            startDate: false,
963            endDate: false,
964            time: {
965                enabled: false
966            },
967            minDays: 0,
968            maxDays: 0,
969            showShortcuts: false,
970            shortcuts: {
971                //'prev-days': [1,3,5,7],
972                // 'next-days': [3,5,7],
973                //'prev' : ['week','month','year'],
974                // 'next' : ['week','month','year']
975            },
976            customShortcuts: [],
977            inline: false,
978            container: 'body',
979            alwaysOpen: false,
980            singleDate: false,
981            lookBehind: false,
982            batchMode: false,
983            duration: 200,
984            stickyMonths: false,
985            dayDivAttrs: [],
986            dayTdAttrs: [],
987            selectForward: false,
988            selectBackward: false,
989            applyBtnClass: '',
990            singleMonth: 'auto',
991            hoveringTooltip: function(days, startTime, hoveringTime) {
992                return days > 1 ? days + ' ' + translate('days') : '';
993            },
994            showTopbar: true,
995            swapTime: false,
996            showWeekNumbers: false,
997            getWeekNumber: function(date) //date will be the first day of a week
998            {
999                return moment(date).format('w');
1000            },
1001            customOpenAnimation: null,
1002            customCloseAnimation: null,
1003            customArrowPrevSymbol: null,
1004            customArrowNextSymbol: null,
1005            monthSelect: false,
1006            yearSelect: false
1007        }, opt);
1008
1009        opt.start = false;
1010        opt.end = false;
1011
1012        opt.startWeek = false;
1013
1014        //detect a touch device
1015        opt.isTouchDevice = 'ontouchstart' in window || navigator.msMaxTouchPoints;
1016
1017        //if it is a touch device, hide hovering tooltip
1018        if (opt.isTouchDevice) opt.hoveringTooltip = false;
1019
1020        //show one month on mobile devices
1021        if (opt.singleMonth == 'auto') opt.singleMonth = $(window).width() < 480;
1022        if (opt.singleMonth) opt.stickyMonths = false;
1023
1024        if (!opt.showTopbar) opt.autoClose = true;
1025
1026        if (opt.startDate && typeof opt.startDate == 'string') opt.startDate = moment(opt.startDate, opt.format).toDate();
1027        if (opt.endDate && typeof opt.endDate == 'string') opt.endDate = moment(opt.endDate, opt.format).toDate();
1028
1029        if (opt.yearSelect && typeof opt.yearSelect === 'boolean') {
1030            opt.yearSelect = function(current) { return [current - 5, current + 5]; }
1031        }
1032
1033        var languages = getLanguages();
1034        var box;
1035        var initiated = false;
1036        var self = this;
1037        var selfDom = $(self).get(0);
1038        var domChangeTimer;
1039
1040        $(this).off('.datepicker').on('click.datepicker', function(evt) {
1041            var isOpen = box.is(':visible');
1042            if (!isOpen) open(opt.duration);
1043        }).on('change.datepicker', function(evt) {
1044            checkAndSetDefaultValue();
1045        }).on('keyup.datepicker', function() {
1046            try {
1047                clearTimeout(domChangeTimer);
1048            } catch (e) {}
1049            domChangeTimer = setTimeout(function() {
1050                checkAndSetDefaultValue();
1051            }, 2000);
1052        });
1053
1054        init_datepicker.call(this);
1055
1056        if (opt.alwaysOpen) {
1057            open(0);
1058        }
1059
1060        // expose some api
1061        $(this).data('dateRangePicker', {
1062            setStart: function(d1) {
1063                if (typeof d1 == 'string') {
1064                    d1 = moment(d1, opt.format).toDate();
1065                }
1066
1067                opt.end = false;
1068                setSingleDate(d1);
1069
1070                return this;
1071            },
1072            setEnd: function(d2, silent) {
1073                var start = new Date();
1074                start.setTime(opt.start);
1075                if (typeof d2 == 'string') {
1076                    d2 = moment(d2, opt.format).toDate();
1077                }
1078                setDateRange(start, d2, silent);
1079                return this;
1080            },
1081            setDateRange: function(d1, d2, silent) {
1082                if (typeof d1 == 'string' && typeof d2 == 'string') {
1083                    d1 = moment(d1, opt.format).toDate();
1084                    d2 = moment(d2, opt.format).toDate();
1085                }
1086                setDateRange(d1, d2, silent);
1087            },
1088            clear: clearSelection,
1089            close: closeDatePicker,
1090            open: open,
1091            redraw: redrawDatePicker,
1092            getDatePicker: getDatePicker,
1093            resetMonthsView: resetMonthsView,
1094            destroy: function() {
1095                $(self).off('.datepicker');
1096                $(self).data('dateRangePicker', '');
1097                $(self).data('date-picker-opened', null);
1098                box.remove();
1099                $(window).off('resize.datepicker', calcPosition);
1100                $(document).off('click.datepicker', outsideClickClose);
1101            }
1102        });
1103
1104        $(window).on('resize.datepicker', calcPosition);
1105
1106        return this;
1107
1108        function IsOwnDatePickerClicked(evt, selfObj) {
1109            return (selfObj.contains(evt.target) || evt.target == selfObj || (selfObj.childNodes != undefined && $.inArray(evt.target, selfObj.childNodes) >= 0));
1110        }
1111
1112        function init_datepicker() {
1113            var self = this;
1114
1115            if ($(this).data('date-picker-opened')) {
1116                closeDatePicker();
1117                return;
1118            }
1119            $(this).data('date-picker-opened', true);
1120
1121
1122            box = createDom().hide();
1123            box.append('<div class="date-range-length-tip"></div>');
1124
1125            $(opt.container).append(box);
1126
1127            if (!opt.inline) {
1128                calcPosition();
1129            } else {
1130                box.addClass('inline-wrapper');
1131            }
1132
1133            if (opt.alwaysOpen) {
1134                box.find('.apply-btn').hide();
1135            }
1136
1137            var defaultTime = getDefaultTime();
1138            resetMonthsView(defaultTime);
1139
1140            if (opt.time.enabled) {
1141                if ((opt.startDate && opt.endDate) || (opt.start && opt.end)) {
1142                    showTime(moment(opt.start || opt.startDate).toDate(), 'time1');
1143                    showTime(moment(opt.end || opt.endDate).toDate(), 'time2');
1144                } else {
1145                    var defaultEndTime = opt.defaultEndTime ? opt.defaultEndTime : defaultTime;
1146                    showTime(defaultTime, 'time1');
1147                    showTime(defaultEndTime, 'time2');
1148                }
1149            }
1150
1151            //showSelectedInfo();
1152
1153
1154            var defaultTopText = '';
1155            if (opt.singleDate)
1156                defaultTopText = translate('default-single');
1157            else if (opt.minDays && opt.maxDays)
1158                defaultTopText = translate('default-range');
1159            else if (opt.minDays)
1160                defaultTopText = translate('default-more');
1161            else if (opt.maxDays)
1162                defaultTopText = translate('default-less');
1163            else
1164                defaultTopText = translate('default-default');
1165
1166            box.find('.default-top').html(defaultTopText.replace(/\%d/, opt.minDays).replace(/\%d/, opt.maxDays));
1167            if (opt.singleMonth) {
1168                box.addClass('single-month');
1169            } else {
1170                box.addClass('two-months');
1171            }
1172
1173
1174            setTimeout(function() {
1175                updateCalendarWidth();
1176                initiated = true;
1177            }, 0);
1178
1179            box.on('click', function(evt) {
1180                evt.stopPropagation();
1181            });
1182
1183            //if user click other place of the webpage, close date range picker window
1184            $(document).on('click.datepicker', outsideClickClose);
1185
1186            box.find('.next').on('click', function() {
1187                if (!opt.stickyMonths)
1188                    gotoNextMonth(this);
1189                else
1190                    gotoNextMonth_stickily(this);
1191            });
1192
1193            function gotoNextMonth(self) {
1194                var isMonth2 = $(self).parents('table').hasClass('month2');
1195                var month = isMonth2 ? opt.month2 : opt.month1;
1196                month = nextMonth(month);
1197                if (!opt.singleMonth && !opt.singleDate && !isMonth2 && compare_month(month, opt.month2) >= 0 || isMonthOutOfBounds(month)) return;
1198                showMonth(month, isMonth2 ? 'month2' : 'month1');
1199                showGap();
1200            }
1201
1202            function gotoNextMonth_stickily(self) {
1203                var nextMonth1 = nextMonth(opt.month1);
1204                var nextMonth2 = nextMonth(opt.month2);
1205                if (isMonthOutOfBounds(nextMonth2)) return;
1206                if (!opt.singleDate && compare_month(nextMonth1, nextMonth2) >= 0) return;
1207                showMonth(nextMonth1, 'month1');
1208                showMonth(nextMonth2, 'month2');
1209                showSelectedDays();
1210            }
1211
1212
1213            box.find('.prev').on('click', function() {
1214                if (!opt.stickyMonths)
1215                    gotoPrevMonth(this);
1216                else
1217                    gotoPrevMonth_stickily(this);
1218            });
1219
1220            function gotoPrevMonth(self) {
1221                var isMonth2 = $(self).parents('table').hasClass('month2');
1222                var month = isMonth2 ? opt.month2 : opt.month1;
1223                month = prevMonth(month);
1224                if (isMonth2 && compare_month(month, opt.month1) <= 0 || isMonthOutOfBounds(month)) return;
1225                showMonth(month, isMonth2 ? 'month2' : 'month1');
1226                showGap();
1227            }
1228
1229            function gotoPrevMonth_stickily(self) {
1230                var prevMonth1 = prevMonth(opt.month1);
1231                var prevMonth2 = prevMonth(opt.month2);
1232                if (isMonthOutOfBounds(prevMonth1)) return;
1233                if (!opt.singleDate && compare_month(prevMonth2, prevMonth1) <= 0) return;
1234                showMonth(prevMonth2, 'month2');
1235                showMonth(prevMonth1, 'month1');
1236                showSelectedDays();
1237            }
1238
1239            box.attr('unselectable', 'on')
1240                .css('user-select', 'none')
1241                .on('selectstart', function(e) {
1242                    e.preventDefault();
1243                    return false;
1244                });
1245
1246            box.find('.apply-btn').on('click', function() {
1247                closeDatePicker();
1248                var dateRange = getDateString(new Date(opt.start)) + opt.separator + getDateString(new Date(opt.end));
1249                $(self).trigger('datepicker-apply', {
1250                    'value': dateRange,
1251                    'date1': new Date(opt.start),
1252                    'date2': new Date(opt.end)
1253                });
1254            });
1255
1256            box.find('[custom]').on('click', function() {
1257                var valueName = $(this).attr('custom');
1258                opt.start = false;
1259                opt.end = false;
1260                box.find('.day.checked').removeClass('checked');
1261                opt.setValue.call(selfDom, valueName);
1262                checkSelectionValid();
1263                showSelectedInfo(true);
1264                showSelectedDays();
1265                if (opt.autoClose) closeDatePicker();
1266            });
1267
1268            box.find('[shortcut]').on('click', function() {
1269                var shortcut = $(this).attr('shortcut');
1270                var end = new Date(),
1271                    start = false;
1272                var dir;
1273                if (shortcut.indexOf('day') != -1) {
1274                    var day = parseInt(shortcut.split(',', 2)[1], 10);
1275                    start = new Date(new Date().getTime() + 86400000 * day);
1276                    end = new Date(end.getTime() + 86400000 * (day > 0 ? 1 : -1));
1277                } else if (shortcut.indexOf('week') != -1) {
1278                    dir = shortcut.indexOf('prev,') != -1 ? -1 : 1;
1279                    var stopDay;
1280                    if (dir == 1)
1281                        stopDay = opt.startOfWeek == 'monday' ? 1 : 0;
1282                    else
1283                        stopDay = opt.startOfWeek == 'monday' ? 0 : 6;
1284
1285                    end = new Date(end.getTime() - 86400000);
1286                    while (end.getDay() != stopDay) end = new Date(end.getTime() + dir * 86400000);
1287                    start = new Date(end.getTime() + dir * 86400000 * 6);
1288                } else if (shortcut.indexOf('month') != -1) {
1289                    dir = shortcut.indexOf('prev,') != -1 ? -1 : 1;
1290                    if (dir == 1)
1291                        start = nextMonth(end);
1292                    else
1293                        start = prevMonth(end);
1294                    start.setDate(1);
1295                    end = nextMonth(start);
1296                    end.setDate(1);
1297                    end = new Date(end.getTime() - 86400000);
1298                } else if (shortcut.indexOf('year') != -1) {
1299                    dir = shortcut.indexOf('prev,') != -1 ? -1 : 1;
1300                    start = new Date();
1301                    start.setFullYear(end.getFullYear() + dir);
1302                    start.setMonth(0);
1303                    start.setDate(1);
1304                    end.setFullYear(end.getFullYear() + dir);
1305                    end.setMonth(11);
1306                    end.setDate(31);
1307                } else if (shortcut == 'custom') {
1308                    var name = $(this).html();
1309                    if (opt.customShortcuts && opt.customShortcuts.length > 0) {
1310                        for (var i = 0; i < opt.customShortcuts.length; i++) {
1311                            var sh = opt.customShortcuts[i];
1312                            if (sh.name == name) {
1313                                var data = [];
1314                                // try
1315                                // {
1316                                data = sh['dates'].call();
1317                                //}catch(e){}
1318                                if (data && data.length == 2) {
1319                                    start = data[0];
1320                                    end = data[1];
1321                                }
1322
1323                                // if only one date is specified then just move calendars there
1324                                // move calendars to show this date's month and next months
1325                                if (data && data.length == 1) {
1326                                    var movetodate = data[0];
1327                                    showMonth(movetodate, 'month1');
1328                                    showMonth(nextMonth(movetodate), 'month2');
1329                                    showGap();
1330                                }
1331
1332                                break;
1333                            }
1334                        }
1335                    }
1336                }
1337                if (start && end) {
1338                    setDateRange(start, end);
1339                    checkSelectionValid();
1340                }
1341            });
1342
1343            box.find('.time1 input[type=range]').on('change touchmove', function(e) {
1344                var target = e.target,
1345                    hour = target.name == 'hour' ? $(target).val().replace(/^(\d{1})$/, '0$1') : undefined,
1346                    min = target.name == 'minute' ? $(target).val().replace(/^(\d{1})$/, '0$1') : undefined;
1347                setTime('time1', hour, min);
1348            });
1349
1350            box.find('.time2 input[type=range]').on('change touchmove', function(e) {
1351                var target = e.target,
1352                    hour = target.name == 'hour' ? $(target).val().replace(/^(\d{1})$/, '0$1') : undefined,
1353                    min = target.name == 'minute' ? $(target).val().replace(/^(\d{1})$/, '0$1') : undefined;
1354                setTime('time2', hour, min);
1355            });
1356
1357        }
1358
1359
1360        function calcPosition() {
1361            if (!opt.inline) {
1362                var offset = $(self).offset();
1363                if ($(opt.container).css('position') == 'relative') {
1364                    var containerOffset = $(opt.container).offset();
1365                    var leftIndent = Math.max(0, offset.left + box.outerWidth() - $('body').width() + 16);
1366                    box.css({
1367                        top: offset.top - containerOffset.top + $(self).outerHeight() + 4,
1368                        left: offset.left - containerOffset.left - leftIndent
1369                    });
1370                } else {
1371                    if (offset.left < 460) //left to right
1372                    {
1373                        box.css({
1374                            top: offset.top + $(self).outerHeight() + parseInt($('body').css('border-top') || 0, 10),
1375                            left: offset.left
1376                        });
1377                    } else {
1378                        box.css({
1379                            top: offset.top + $(self).outerHeight() + parseInt($('body').css('border-top') || 0, 10),
1380                            left: offset.left + $(self).width() - box.width() - 16
1381                        });
1382                    }
1383                }
1384            }
1385        }
1386
1387        // Return the date picker wrapper element
1388        function getDatePicker() {
1389            return box;
1390        }
1391
1392        function open(animationTime) {
1393            redrawDatePicker();
1394            checkAndSetDefaultValue();
1395            if (opt.customOpenAnimation) {
1396                opt.customOpenAnimation.call(box.get(0), function() {
1397                    $(self).trigger('datepicker-opened', {
1398                        relatedTarget: box
1399                    });
1400                });
1401            } else {
1402                box.slideDown(animationTime, function() {
1403                    $(self).trigger('datepicker-opened', {
1404                        relatedTarget: box
1405                    });
1406                });
1407            }
1408            $(self).trigger('datepicker-open', {
1409                relatedTarget: box
1410            });
1411            showGap();
1412            updateCalendarWidth();
1413            calcPosition();
1414        }
1415
1416        function checkAndSetDefaultValue() {
1417            var __default_string = opt.getValue.call(selfDom);
1418            var defaults = __default_string ? __default_string.split(opt.separator) : '';
1419
1420            if (defaults && ((defaults.length == 1 && opt.singleDate) || defaults.length >= 2)) {
1421                var ___format = opt.format;
1422                if (___format.match(/Do/)) {
1423
1424                    ___format = ___format.replace(/Do/, 'D');
1425                    defaults[0] = defaults[0].replace(/(\d+)(th|nd|st)/, '$1');
1426                    if (defaults.length >= 2) {
1427                        defaults[1] = defaults[1].replace(/(\d+)(th|nd|st)/, '$1');
1428                    }
1429                }
1430                // set initiated  to avoid triggerring datepicker-change event
1431                initiated = false;
1432                if (defaults.length >= 2) {
1433                    setDateRange(getValidValue(defaults[0], ___format, moment.locale(opt.language)), getValidValue(defaults[1], ___format, moment.locale(opt.language)));
1434                } else if (defaults.length == 1 && opt.singleDate) {
1435                    setSingleDate(getValidValue(defaults[0], ___format, moment.locale(opt.language)));
1436                }
1437
1438                initiated = true;
1439            }
1440        }
1441
1442        function getValidValue(date, format, locale) {
1443            if (moment(date, format, locale).isValid()) {
1444                return moment(date, format, locale).toDate();
1445            } else {
1446                return moment().toDate();
1447            }
1448        }
1449
1450        function updateCalendarWidth() {
1451            var gapMargin = box.find('.gap').css('margin-left');
1452            if (gapMargin) gapMargin = parseInt(gapMargin);
1453            var w1 = box.find('.month1').width();
1454            var w2 = box.find('.gap').width() + (gapMargin ? gapMargin * 2 : 0);
1455            var w3 = box.find('.month2').width();
1456            box.find('.month-wrapper').width(w1 + w2 + w3);
1457        }
1458
1459        function renderTime(name, date) {
1460            box.find('.' + name + ' input[type=range].hour-range').val(moment(date).hours());
1461            box.find('.' + name + ' input[type=range].minute-range').val(moment(date).minutes());
1462            setTime(name, moment(date).format('HH'), moment(date).format('mm'));
1463        }
1464
1465        function changeTime(name, date) {
1466            opt[name] = parseInt(
1467                moment(parseInt(date))
1468                .hour(moment(opt[name + 'Time']).format('HH'), 'h')
1469                .minute(moment(opt[name + 'Time']).format('mm'), 'm').valueOf()
1470            );
1471        }
1472
1473        function swapTime() {
1474            renderTime('time1', opt.start);
1475            renderTime('time2', opt.end);
1476        }
1477
1478        function setTime(name, hour, minute) {
1479            hour && (box.find('.' + name + ' .hour-val').text(hour));
1480            minute && (box.find('.' + name + ' .minute-val').text(minute));
1481            switch (name) {
1482                case 'time1':
1483                    if (opt.start) {
1484                        setRange('start', moment(opt.start));
1485                    }
1486                    setRange('startTime', moment(opt.startTime || moment().valueOf()));
1487                    break;
1488                case 'time2':
1489                    if (opt.end) {
1490                        setRange('end', moment(opt.end));
1491                    }
1492                    setRange('endTime', moment(opt.endTime || moment().valueOf()));
1493                    break;
1494            }
1495
1496            function setRange(name, timePoint) {
1497                var h = timePoint.format('HH'),
1498                    m = timePoint.format('mm');
1499                opt[name] = timePoint
1500                    .hour(hour || h, 'h')
1501                    .minute(minute || m, 'm')
1502                    .valueOf();
1503            }
1504            checkSelectionValid();
1505            showSelectedInfo();
1506            showSelectedDays();
1507        }
1508
1509        function clearSelection() {
1510            opt.start = false;
1511            opt.end = false;
1512            box.find('.day.checked').removeClass('checked');
1513            box.find('.day.last-date-selected').removeClass('last-date-selected');
1514            box.find('.day.first-date-selected').removeClass('first-date-selected');
1515            opt.setValue.call(selfDom, '');
1516            checkSelectionValid();
1517            showSelectedInfo();
1518            showSelectedDays();
1519        }
1520
1521        function handleStart(time) {
1522            var r = time;
1523            if (opt.batchMode === 'week-range') {
1524                if (opt.startOfWeek === 'monday') {
1525                    r = moment(parseInt(time)).startOf('isoweek').valueOf();
1526                } else {
1527                    r = moment(parseInt(time)).startOf('week').valueOf();
1528                }
1529            } else if (opt.batchMode === 'month-range') {
1530                r = moment(parseInt(time)).startOf('month').valueOf();
1531            }
1532            return r;
1533        }
1534
1535        function handleEnd(time) {
1536            var r = time;
1537            if (opt.batchMode === 'week-range') {
1538                if (opt.startOfWeek === 'monday') {
1539                    r = moment(parseInt(time)).endOf('isoweek').valueOf();
1540                } else {
1541                    r = moment(parseInt(time)).endOf('week').valueOf();
1542                }
1543            } else if (opt.batchMode === 'month-range') {
1544                r = moment(parseInt(time)).endOf('month').valueOf();
1545            }
1546            return r;
1547        }
1548
1549
1550        function dayClicked(day) {
1551            if (day.hasClass('invalid')) return;
1552            var time = day.attr('time');
1553            day.addClass('checked');
1554            if (opt.singleDate) {
1555                opt.start = time;
1556                opt.end = false;
1557            } else if (opt.batchMode === 'week') {
1558                if (opt.startOfWeek === 'monday') {
1559                    opt.start = moment(parseInt(time)).startOf('isoweek').valueOf();
1560                    opt.end = moment(parseInt(time)).endOf('isoweek').valueOf();
1561                } else {
1562                    opt.end = moment(parseInt(time)).endOf('week').valueOf();
1563                    opt.start = moment(parseInt(time)).startOf('week').valueOf();
1564                }
1565            } else if (opt.batchMode === 'workweek') {
1566                opt.start = moment(parseInt(time)).day(1).valueOf();
1567                opt.end = moment(parseInt(time)).day(5).valueOf();
1568            } else if (opt.batchMode === 'weekend') {
1569                opt.start = moment(parseInt(time)).day(6).valueOf();
1570                opt.end = moment(parseInt(time)).day(7).valueOf();
1571            } else if (opt.batchMode === 'month') {
1572                opt.start = moment(parseInt(time)).startOf('month').valueOf();
1573                opt.end = moment(parseInt(time)).endOf('month').valueOf();
1574            } else if ((opt.start && opt.end) || (!opt.start && !opt.end)) {
1575                opt.start = handleStart(time);
1576                opt.end = false;
1577            } else if (opt.start) {
1578                opt.end = handleEnd(time);
1579                if (opt.time.enabled) {
1580                    changeTime('end', opt.end);
1581                }
1582            }
1583
1584            //Update time in case it is enabled and timestamps are available
1585            if (opt.time.enabled) {
1586                if (opt.start) {
1587                    changeTime('start', opt.start);
1588                }
1589                if (opt.end) {
1590                    changeTime('end', opt.end);
1591                }
1592            }
1593
1594            //In case the start is after the end, swap the timestamps
1595            if (!opt.singleDate && opt.start && opt.end && opt.start > opt.end) {
1596                var tmp = opt.end;
1597                opt.end = handleEnd(opt.start);
1598                opt.start = handleStart(tmp);
1599                if (opt.time.enabled && opt.swapTime) {
1600                    swapTime();
1601                }
1602            }
1603
1604            opt.start = parseInt(opt.start);
1605            opt.end = parseInt(opt.end);
1606
1607            clearHovering();
1608            if (opt.start && !opt.end) {
1609                $(self).trigger('datepicker-first-date-selected', {
1610                    'date1': new Date(opt.start)
1611                });
1612                dayHovering(day);
1613            }
1614            updateSelectableRange(time);
1615
1616            checkSelectionValid();
1617            showSelectedInfo();
1618            showSelectedDays();
1619            autoclose();
1620        }
1621
1622
1623        function weekNumberClicked(weekNumberDom) {
1624            var thisTime = parseInt(weekNumberDom.attr('data-start-time'), 10);
1625            var date1, date2;
1626            if (!opt.startWeek) {
1627                opt.startWeek = thisTime;
1628                weekNumberDom.addClass('week-number-selected');
1629                date1 = new Date(thisTime);
1630                opt.start = moment(date1).day(opt.startOfWeek == 'monday' ? 1 : 0).valueOf();
1631                opt.end = moment(date1).day(opt.startOfWeek == 'monday' ? 7 : 6).valueOf();
1632            } else {
1633                box.find('.week-number-selected').removeClass('week-number-selected');
1634                date1 = new Date(thisTime < opt.startWeek ? thisTime : opt.startWeek);
1635                date2 = new Date(thisTime < opt.startWeek ? opt.startWeek : thisTime);
1636                opt.startWeek = false;
1637                opt.start = moment(date1).day(opt.startOfWeek == 'monday' ? 1 : 0).valueOf();
1638                opt.end = moment(date2).day(opt.startOfWeek == 'monday' ? 7 : 6).valueOf();
1639            }
1640            updateSelectableRange();
1641            checkSelectionValid();
1642            showSelectedInfo();
1643            showSelectedDays();
1644            autoclose();
1645        }
1646
1647        function isValidTime(time) {
1648            time = parseInt(time, 10);
1649            if (opt.startDate && compare_day(time, opt.startDate) < 0) return false;
1650            if (opt.endDate && compare_day(time, opt.endDate) > 0) return false;
1651
1652            if (opt.start && !opt.end && !opt.singleDate) {
1653                //check maxDays and minDays setting
1654                if (opt.maxDays > 0 && countDays(time, opt.start) > opt.maxDays) return false;
1655                if (opt.minDays > 0 && countDays(time, opt.start) < opt.minDays) return false;
1656
1657                //check selectForward and selectBackward
1658                if (opt.selectForward && time < opt.start) return false;
1659                if (opt.selectBackward && time > opt.start) return false;
1660
1661                //check disabled days
1662                if (opt.beforeShowDay && typeof opt.beforeShowDay == 'function') {
1663                    var valid = true;
1664                    var timeTmp = time;
1665                    while (countDays(timeTmp, opt.start) > 1) {
1666                        var arr = opt.beforeShowDay(new Date(timeTmp));
1667                        if (!arr[0]) {
1668                            valid = false;
1669                            break;
1670                        }
1671                        if (Math.abs(timeTmp - opt.start) < 86400000) break;
1672                        if (timeTmp > opt.start) timeTmp -= 86400000;
1673                        if (timeTmp < opt.start) timeTmp += 86400000;
1674                    }
1675                    if (!valid) return false;
1676                }
1677            }
1678            return true;
1679        }
1680
1681
1682        function updateSelectableRange() {
1683            box.find('.day.invalid.tmp').removeClass('tmp invalid').addClass('valid');
1684            if (opt.start && !opt.end) {
1685                box.find('.day.toMonth.valid').each(function() {
1686                    var time = parseInt($(this).attr('time'), 10);
1687                    if (!isValidTime(time))
1688                        $(this).addClass('invalid tmp').removeClass('valid');
1689                    else
1690                        $(this).addClass('valid tmp').removeClass('invalid');
1691                });
1692            }
1693
1694            return true;
1695        }
1696
1697
1698        function dayHovering(day) {
1699            var hoverTime = parseInt(day.attr('time'));
1700            var tooltip = '';
1701
1702            if (day.hasClass('has-tooltip') && day.attr('data-tooltip')) {
1703                tooltip = '<span class="tooltip-content">' + day.attr('data-tooltip') + '</span>';
1704            } else if (!day.hasClass('invalid')) {
1705                if (opt.singleDate) {
1706                    box.find('.day.hovering').removeClass('hovering');
1707                    day.addClass('hovering');
1708                } else {
1709                    box.find('.day').each(function() {
1710                        var time = parseInt($(this).attr('time')),
1711                            start = opt.start,
1712                            end = opt.end;
1713
1714                        if (time == hoverTime) {
1715                            $(this).addClass('hovering');
1716                        } else {
1717                            $(this).removeClass('hovering');
1718                        }
1719
1720                        if (
1721                            (opt.start && !opt.end) &&
1722                            (
1723                                (opt.start < time && hoverTime >= time) ||
1724                                (opt.start > time && hoverTime <= time)
1725                            )
1726                        ) {
1727                            $(this).addClass('hovering');
1728                        } else {
1729                            $(this).removeClass('hovering');
1730                        }
1731                    });
1732
1733                    if (opt.start && !opt.end) {
1734                        var days = countDays(hoverTime, opt.start);
1735                        if (opt.hoveringTooltip) {
1736                            if (typeof opt.hoveringTooltip == 'function') {
1737                                tooltip = opt.hoveringTooltip(days, opt.start, hoverTime);
1738                            } else if (opt.hoveringTooltip === true && days > 1) {
1739                                tooltip = days + ' ' + translate('days');
1740                            }
1741                        }
1742                    }
1743                }
1744            }
1745
1746            if (tooltip) {
1747                var posDay = day.offset();
1748                var posBox = box.offset();
1749
1750                var _left = posDay.left - posBox.left;
1751                var _top = posDay.top - posBox.top;
1752                _left += day.width() / 2;
1753
1754
1755                var $tip = box.find('.date-range-length-tip');
1756                var w = $tip.css({
1757                    'visibility': 'hidden',
1758                    'display': 'none'
1759                }).html(tooltip).width();
1760                var h = $tip.height();
1761                _left -= w / 2;
1762                _top -= h;
1763                setTimeout(function() {
1764                    $tip.css({
1765                        left: _left,
1766                        top: _top,
1767                        display: 'block',
1768                        'visibility': 'visible'
1769                    });
1770                }, 10);
1771            } else {
1772                box.find('.date-range-length-tip').hide();
1773            }
1774        }
1775
1776        function clearHovering() {
1777            box.find('.day.hovering').removeClass('hovering');
1778            box.find('.date-range-length-tip').hide();
1779        }
1780
1781        function dateChanged(date) {
1782            var value = date.val();
1783            var name = date.attr('name');
1784            var type = date.parents('table').hasClass('month1') ? 'month1' : 'month2';
1785            var oppositeType = type === 'month1' ? 'month2' : 'month1';
1786            var startDate = opt.startDate ? moment(opt.startDate) : false;
1787            var endDate = opt.endDate ? moment(opt.endDate) : false;
1788            var newDate = moment(opt[type])[name](value);
1789
1790
1791            if (startDate && newDate.isSameOrBefore(startDate)) {
1792                newDate = startDate.add(type === 'month2' ? 1 : 0, 'month');
1793            }
1794
1795            if (endDate && newDate.isSameOrAfter(endDate)) {
1796                newDate = endDate.add(!opt.singleMonth && type === 'month1' ? -1 : 0, 'month');
1797            }
1798
1799            showMonth(newDate, type);
1800
1801            if (type === 'month1') {
1802                if (opt.stickyMonths || moment(newDate).isSameOrAfter(opt[oppositeType], 'month')) {
1803                    showMonth(moment(newDate).add(1, 'month'), oppositeType);
1804                }
1805            } else {
1806                if (opt.stickyMonths || moment(newDate).isSameOrBefore(opt[oppositeType], 'month')) {
1807                    showMonth(moment(newDate).add(-1, 'month'), oppositeType);
1808                }
1809            }
1810
1811            showGap();
1812        }
1813
1814        function autoclose() {
1815            if (opt.singleDate === true) {
1816                if (initiated && opt.start) {
1817                    if (opt.autoClose) closeDatePicker();
1818                }
1819            } else {
1820                if (initiated && opt.start && opt.end) {
1821                    if (opt.autoClose) closeDatePicker();
1822                }
1823            }
1824        }
1825
1826        function checkSelectionValid() {
1827            var days = Math.ceil((opt.end - opt.start) / 86400000) + 1;
1828            if (opt.singleDate) { // Validate if only start is there
1829                if (opt.start && !opt.end)
1830                    box.find('.drp_top-bar').removeClass('error').addClass('normal');
1831                else
1832                    box.find('.drp_top-bar').removeClass('error').removeClass('normal');
1833            } else if (opt.maxDays && days > opt.maxDays) {
1834                opt.start = false;
1835                opt.end = false;
1836                box.find('.day').removeClass('checked');
1837                box.find('.drp_top-bar').removeClass('normal').addClass('error').find('.error-top').html(translate('less-than').replace('%d', opt.maxDays));
1838            } else if (opt.minDays && days < opt.minDays) {
1839                opt.start = false;
1840                opt.end = false;
1841                box.find('.day').removeClass('checked');
1842                box.find('.drp_top-bar').removeClass('normal').addClass('error').find('.error-top').html(translate('more-than').replace('%d', opt.minDays));
1843            } else {
1844                if (opt.start || opt.end)
1845                    box.find('.drp_top-bar').removeClass('error').addClass('normal');
1846                else
1847                    box.find('.drp_top-bar').removeClass('error').removeClass('normal');
1848            }
1849
1850            if ((opt.singleDate && opt.start && !opt.end) || (!opt.singleDate && opt.start && opt.end)) {
1851                box.find('.apply-btn').removeClass('disabled');
1852            } else {
1853                box.find('.apply-btn').addClass('disabled');
1854            }
1855
1856            if (opt.batchMode) {
1857                if (
1858                    (opt.start && opt.startDate && compare_day(opt.start, opt.startDate) < 0) ||
1859                    (opt.end && opt.endDate && compare_day(opt.end, opt.endDate) > 0)
1860                ) {
1861                    opt.start = false;
1862                    opt.end = false;
1863                    box.find('.day').removeClass('checked');
1864                }
1865            }
1866        }
1867
1868        function showSelectedInfo(forceValid, silent) {
1869            box.find('.start-day').html('...');
1870            box.find('.end-day').html('...');
1871            box.find('.selected-days').hide();
1872            if (opt.start) {
1873                box.find('.start-day').html(getDateString(new Date(parseInt(opt.start))));
1874            }
1875            if (opt.end) {
1876                box.find('.end-day').html(getDateString(new Date(parseInt(opt.end))));
1877            }
1878            var dateRange;
1879            if (opt.start && opt.singleDate) {
1880                box.find('.apply-btn').removeClass('disabled');
1881                dateRange = getDateString(new Date(opt.start));
1882                opt.setValue.call(selfDom, dateRange, getDateString(new Date(opt.start)), getDateString(new Date(opt.end)));
1883
1884                if (initiated && !silent) {
1885                    $(self).trigger('datepicker-change', {
1886                        'value': dateRange,
1887                        'date1': new Date(opt.start)
1888                    });
1889                }
1890            } else if (opt.start && opt.end) {
1891                box.find('.selected-days').show().find('.selected-days-num').html(countDays(opt.end, opt.start));
1892                box.find('.apply-btn').removeClass('disabled');
1893                dateRange = getDateString(new Date(opt.start)) + opt.separator + getDateString(new Date(opt.end));
1894                opt.setValue.call(selfDom, dateRange, getDateString(new Date(opt.start)), getDateString(new Date(opt.end)));
1895                if (initiated && !silent) {
1896                    $(self).trigger('datepicker-change', {
1897                        'value': dateRange,
1898                        'date1': new Date(opt.start),
1899                        'date2': new Date(opt.end)
1900                    });
1901                }
1902            } else if (forceValid) {
1903                box.find('.apply-btn').removeClass('disabled');
1904            } else {
1905                box.find('.apply-btn').addClass('disabled');
1906            }
1907        }
1908
1909        function countDays(start, end) {
1910            return Math.abs(moment(start).diff(moment(end), 'd')) + 1;
1911        }
1912
1913        function setDateRange(date1, date2, silent) {
1914            if (date1.getTime() > date2.getTime()) {
1915                var tmp = date2;
1916                date2 = date1;
1917                date1 = tmp;
1918                tmp = null;
1919            }
1920            var valid = true;
1921            if (opt.startDate && compare_day(date1, opt.startDate) < 0) valid = false;
1922            if (opt.endDate && compare_day(date2, opt.endDate) > 0) valid = false;
1923            if (!valid) {
1924                showMonth(opt.startDate, 'month1');
1925                showMonth(nextMonth(opt.startDate), 'month2');
1926                showGap();
1927                return;
1928            }
1929
1930            opt.start = date1.getTime();
1931            opt.end = date2.getTime();
1932
1933            if (opt.time.enabled) {
1934                renderTime('time1', date1);
1935                renderTime('time2', date2);
1936            }
1937
1938            if (opt.stickyMonths || (compare_day(date1, date2) > 0 && compare_month(date1, date2) === 0)) {
1939                if (opt.lookBehind) {
1940                    date1 = prevMonth(date2);
1941                } else {
1942                    date2 = nextMonth(date1);
1943                }
1944            }
1945
1946            if (opt.stickyMonths && opt.endDate !== false && compare_month(date2, opt.endDate) > 0) {
1947                date1 = prevMonth(date1);
1948                date2 = prevMonth(date2);
1949            }
1950
1951            if (!opt.stickyMonths) {
1952                if (compare_month(date1, date2) === 0) {
1953                    if (opt.lookBehind) {
1954                        date1 = prevMonth(date2);
1955                    } else {
1956                        date2 = nextMonth(date1);
1957                    }
1958                }
1959            }
1960
1961            showMonth(date1, 'month1');
1962            showMonth(date2, 'month2');
1963            showGap();
1964            checkSelectionValid();
1965            showSelectedInfo(false, silent);
1966            autoclose();
1967        }
1968
1969        function setSingleDate(date1) {
1970
1971            var valid = true;
1972            if (opt.startDate && compare_day(date1, opt.startDate) < 0) valid = false;
1973            if (opt.endDate && compare_day(date1, opt.endDate) > 0) valid = false;
1974            if (!valid) {
1975                showMonth(opt.startDate, 'month1');
1976                return;
1977            }
1978
1979            opt.start = date1.getTime();
1980
1981
1982            if (opt.time.enabled) {
1983                renderTime('time1', date1);
1984
1985            }
1986            showMonth(date1, 'month1');
1987            if (opt.singleMonth !== true) {
1988                var date2 = nextMonth(date1);
1989                showMonth(date2, 'month2');
1990            }
1991            showGap();
1992            showSelectedInfo();
1993            autoclose();
1994        }
1995
1996        function showSelectedDays() {
1997            if (!opt.start && !opt.end) return;
1998            box.find('.day').each(function() {
1999                var time = parseInt($(this).attr('time')),
2000                    start = opt.start,
2001                    end = opt.end;
2002                if (opt.time.enabled) {
2003                    time = moment(time).startOf('day').valueOf();
2004                    start = moment(start || moment().valueOf()).startOf('day').valueOf();
2005                    end = moment(end || moment().valueOf()).startOf('day').valueOf();
2006                }
2007                if (
2008                    (opt.start && opt.end && end >= time && start <= time) ||
2009                    (opt.start && !opt.end && moment(start).format('YYYY-MM-DD') == moment(time).format('YYYY-MM-DD'))
2010                ) {
2011                    $(this).addClass('checked');
2012                } else {
2013                    $(this).removeClass('checked');
2014                }
2015
2016                //add first-date-selected class name to the first date selected
2017                if (opt.start && moment(start).format('YYYY-MM-DD') == moment(time).format('YYYY-MM-DD')) {
2018                    $(this).addClass('first-date-selected');
2019                } else {
2020                    $(this).removeClass('first-date-selected');
2021                }
2022                //add last-date-selected
2023                if (opt.end && moment(end).format('YYYY-MM-DD') == moment(time).format('YYYY-MM-DD')) {
2024                    $(this).addClass('last-date-selected');
2025                } else {
2026                    $(this).removeClass('last-date-selected');
2027                }
2028            });
2029
2030            box.find('.week-number').each(function() {
2031                if ($(this).attr('data-start-time') == opt.startWeek) {
2032                    $(this).addClass('week-number-selected');
2033                }
2034            });
2035        }
2036
2037        function showMonth(date, month) {
2038            date = moment(date).toDate();
2039            var monthElement = generateMonthElement(date, month);
2040            var yearElement = generateYearElement(date, month);
2041
2042            box.find('.' + month + ' .month-name').html(monthElement + ' ' + yearElement);
2043            box.find('.' + month + ' tbody').html(createMonthHTML(date));
2044            opt[month] = date;
2045            updateSelectableRange();
2046            bindEvents();
2047        }
2048
2049        function generateMonthElement(date, month) {
2050            date = moment(date);
2051            var currentMonth = date.get('month');
2052            var currentMonthName = nameMonth(currentMonth);
2053            var nonSelectableMonth = '<div class="month-element">' + currentMonthName + '</div>';
2054
2055            if (!opt.monthSelect) { return nonSelectableMonth; }
2056
2057            var startDate = opt.startDate ? moment(opt.startDate).add(!opt.singleMonth && month 
2057=== 'month2' ? 1 : 0, 'month') : false;
2058            var endDate = opt.endDate ? moment(opt.endDate).add(!opt.singleMonth && month === 'month1' ? -1 : 0, 'month') : false;
2059
2060            var minSelectableMonth = startDate && date.isSame(startDate, 'year') ? startDate.get('month') : 0;
2061            var maxSelectableMonth = endDate && date.isSame(endDate, 'year') ? endDate.get('month') : 11;
2062            var minVisibleMonth = Math.min(minSelectableMonth, currentMonth);
2063            var maxVisibleMonth = Math.max(maxSelectableMonth, currentMonth);
2064
2065            if (minVisibleMonth === maxVisibleMonth) { return nonSelectableMonth; }
2066
2067            var selectData = generateSelectData(
2068                {
2069                    minSelectable: minSelectableMonth,
2070                    maxSelectable: maxSelectableMonth,
2071                    minVisible: minVisibleMonth,
2072                    maxVisible: maxVisibleMonth,
2073                },
2074                currentMonth,
2075                function (value) { return nameMonth(value); }
2076            )
2077            return generateSelect('month', selectData);
2078        }
2079
2080        function generateYearElement(date, month) {
2081            date = moment(date);
2082            var currentYear = date.get('year');
2083            var nonSelectableMonth = '<div class="month-element">' + currentYear + '</div>';
2084
2085            if (!opt.yearSelect) { return nonSelectableMonth; }
2086
2087            var isYearFunction = opt.yearSelect && typeof opt.yearSelect === 'function';
2088            var startDate = opt.startDate ? moment(opt.startDate).add(!opt.singleMonth && month === 'month2' ? 1 : 0, 'month') : false;
2089            var endDate = opt.endDate ? moment(opt.endDate).add(!opt.singleMonth && month === 'month1' ? -1 : 0, 'month') : false;
2090            var range = isYearFunction ? opt.yearSelect(currentYear) : opt.yearSelect.slice();
2091
2092            var minSelectableYear = startDate ? Math.max(range[0], startDate.get('year')) : Math.min(range[0], currentYear);
2093            var maxSelectableYear = endDate ? Math.min(range[1], endDate.get('year')) : Math.max(range[1], currentYear);
2094            var minVisibleYear = Math.min(minSelectableYear, currentYear);
2095            var maxVisibleYear = Math.max(maxSelectableYear, currentYear);
2096
2097            if (minVisibleYear === maxVisibleYear) { return nonSelectableMonth; }
2098
2099            var selectData = generateSelectData(
2100                {
2101                    minSelectable: minSelectableYear,
2102                    maxSelectable: maxSelectableYear,
2103                    minVisible: minVisibleYear,
2104                    maxVisible: maxVisibleYear,
2105                },
2106                currentYear
2107            )
2108            return generateSelect('year', selectData);
2109        }
2110
2111
2112        function generateSelectData(range, current, valueBeautifier) {
2113            var data = [];
2114            valueBeautifier = valueBeautifier || function(value) { return value; };
2115
2116            for (var i = range.minVisible; i <= range.maxVisible; i++) {
2117                data.push({
2118                    value: i,
2119                    text: valueBeautifier(i),
2120                    selected: i === current,
2121                    disabled: ((i < range.minSelectable) || (i > range.maxSelectable)),
2122                });
2123            }
2124
2125            return data;
2126        }
2127
2128        function generateSelect(name, data) {
2129            var select = '<div class="select-wrapper"><select class="' + name + '" name="' + name + '">';
2130            var current;
2131
2132            for (var i = 0, l = data.length; i < l; i++) {
2133                var item = data[i];
2134                select += '<option value="' + item.value + '"' +
2135                    (item.selected ? ' selected' : '') +
2136                    (item.disabled ? ' disabled' : '') + '>' +
2137                    item.text + '</option>';
2138
2139                if (item.selected) {
2140                    current = item.text;
2141                }
2142            }
2143
2144            select += '</select>' + current + '</div>';
2145
2146            return select;
2147        }
2148
2149        function bindEvents() {
2150            box.find('.day').off("click").on('click', function(evt) {
2151                dayClicked($(this));
2152            });
2153
2154            box.find('.day').off("mouseenter").on('mouseenter', function(evt) {
2155                dayHovering($(this));
2156            });
2157
2158            box.find('.day').off("mouseleave").on('mouseleave', function(evt) {
2159                box.find('.date-range-length-tip').hide();
2160                if (opt.singleDate) {
2161                    clearHovering();
2162                }
2163            });
2164
2165            box.find('.week-number').off("click").on('click', function(evt) {
2166                weekNumberClicked($(this));
2167            });
2168
2169            box.find('.month').off("change").on('change', function(evt) {
2170                dateChanged($(this));
2171            });
2172
2173            box.find('.year').off("change").on('change', function(evt) {
2174                dateChanged($(this));
2175            });
2176        }
2177
2178        function showTime(date, name) {
2179            box.find('.' + name).append(getTimeHTML());
2180            renderTime(name, date);
2181        }
2182
2183        function nameMonth(m) {
2184            return translate('month-name')[m];
2185        }
2186
2187        function getDateString(d) {
2188            return moment(d).format(opt.format);
2189        }
2190
2191        function showGap() {
2192            showSelectedDays();
2193            var m1 = parseInt(moment(opt.month1).format('YYYYMM'));
2194            var m2 = parseInt(moment(opt.month2).format('YYYYMM'));
2195            var p = Math.abs(m1 - m2);
2196            var shouldShow = (p > 1 && p != 89);
2197            if (shouldShow) {
2198                box.addClass('has-gap').removeClass('no-gap').find('.gap').css('visibility', 'visible');
2199            } else {
2200                box.removeClass('has-gap').addClass('no-gap').find('.gap').css('visibility', 'hidden');
2201            }
2202            var h1 = box.find('table.month1').height();
2203            var h2 = box.find('table.month2').height();
2204            box.find('.gap').height(Math.max(h1, h2) + 10);
2205        }
2206
2207        function closeDatePicker() {
2208            if (opt.alwaysOpen) return;
2209
2210            var afterAnim = function() {
2211                $(self).data('date-picker-opened', false);
2212                $(self).trigger('datepicker-closed', {
2213                    relatedTarget: box
2214                });
2215            };
2216            if (opt.customCloseAnimation) {
2217                opt.customCloseAnimation.call(box.get(0), afterAnim);
2218            } else {
2219                $(box).slideUp(opt.duration, afterAnim);
2220            }
2221            $(self).trigger('datepicker-close', {
2222                relatedTarget: box
2223            });
2224        }
2225
2226        function redrawDatePicker() {
2227            showMonth(opt.month1, 'month1');
2228            showMonth(opt.month2, 'month2');
2229        }
2230
2231        function compare_month(m1, m2) {
2232            var p = parseInt(moment(m1).format('YYYYMM')) - parseInt(moment(m2).format('YYYYMM'));
2233            if (p > 0) return 1;
2234            if (p === 0) return 0;
2235            return -1;
2236        }
2237
2238        function compare_day(m1, m2) {
2239            var p = parseInt(moment(m1).format('YYYYMMDD')) - parseInt(moment(m2).format('YYYYMMDD'));
2240            if (p > 0) return 1;
2241            if (p === 0) return 0;
2242            return -1;
2243        }
2244
2245        function nextMonth(month) {
2246            return moment(month).add(1, 'months').toDate();
2247        }
2248
2249        function prevMonth(month) {
2250            return moment(month).add(-1, 'months').toDate();
2251        }
2252
2253        function getTimeHTML() {
2254            return '<div>' +
2255                '<span>' + translate('Time') + ': <span class="hour-val">00</span>:<span class="minute-val">00</span></span>' +
2256                '</div>' +
2257                '<div class="hour">' +
2258                '<label>' + translate('Hour') + ': <input type="range" class="hour-range" name="hour" min="0" max="23"></label>' +
2259                '</div>' +
2260                '<div class="minute">' +
2261                '<label>' + translate('Minute') + ': <input type="range" class="minute-range" name="minute" min="0" max="59"></label>' +
2262                '</div>';
2263        }
2264
2265        function createDom() {
2266            var html = '<div class="date-picker-wrapper';
2267            if (opt.extraClass) html += ' ' + opt.extraClass + ' ';
2268            if (opt.singleDate) html += ' single-date ';
2269            if (!opt.showShortcuts) html += ' no-shortcuts ';
2270            if (!opt.showTopbar) html += ' no-topbar ';
2271            if (opt.customTopBar) html += ' custom-topbar ';
2272            html += '">';
2273
2274            if (opt.showTopbar) {
2275                html += '<div class="drp_top-bar">';
2276
2277                if (opt.customTopBar) {
2278                    if (typeof opt.customTopBar == 'function') opt.customTopBar = opt.customTopBar();
2279                    html += '<div class="custom-top">' + opt.customTopBar + '</div>';
2280                } else {
2281                    html += '<div class="normal-top">' +
2282                        '<span class="selection-top">' + translate('selected') + ' </span> <b class="start-day">...</b>';
2283                    if (!opt.singleDate) {
2284                        html += ' <span class="separator-day">' + opt.separator + '</span> <b class="end-day">...</b> <i class="selected-days">(<span class="selected-days-num">3</span> ' + translate('days') + ')</i>';
2285                    }
2286                    html += '</div>';
2287                    html += '<div class="error-top">error</div>' +
2288                        '<div class="default-top">default</div>';
2289                }
2290
2291                html += '<input type="button" class="apply-btn disabled' + getApplyBtnClass() + '" value="' + translate('apply') + '" />';
2292                html += '</div>';
2293            }
2294
2295            var _colspan = opt.showWeekNumbers ? 6 : 5;
2296
2297            var arrowPrev = '&lt;';
2298            if (opt.customArrowPrevSymbol) arrowPrev = opt.customArrowPrevSymbol;
2299
2300            var arrowNext = '&gt;';
2301            if (opt.customArrowNextSymbol) arrowNext = opt.customArrowNextSymbol;
2302
2303            html += '<div class="month-wrapper">' +
2304                '   <table class="month1" cellspacing="0" border="0" cellpadding="0">' +
2305                '       <thead>' +
2306                '           <tr class="caption">' +
2307                '               <th>' +
2308                '                   <span class="prev">' +
2309                arrowPrev +
2310                '                   </span>' +
2311                '               </th>' +
2312                '               <th colspan="' + _colspan + '" class="month-name">' +
2313                '               </th>' +
2314                '               <th>' +
2315                (opt.singleDate || !opt.stickyMonths ? '<span class="next">' + arrowNext + '</span>' : '') +
2316                '               </th>' +
2317                '           </tr>' +
2318                '           <tr class="week-name">' + getWeekHead() +
2319                '       </thead>' +
2320                '       <tbody></tbody>' +
2321                '   </table>';
2322
2323            if (hasMonth2()) {
2324                html += '<div class="gap">' + getGapHTML() + '</div>' +
2325                    '<table class="month2" cellspacing="0" border="0" cellpadding="0">' +
2326                    '   <thead>' +
2327                    '   <tr class="caption">' +
2328                    '       <th>' +
2329                    (!opt.stickyMonths ? '<span class="prev">' + arrowPrev + '</span>' : '') +
2330                    '       </th>' +
2331                    '       <th colspan="' + _colspan + '" class="month-name">' +
2332                    '       </th>' +
2333                    '       <th>' +
2334                    '           <span class="next">' + arrowNext + '</span>' +
2335                    '       </th>' +
2336                    '   </tr>' +
2337                    '   <tr class="week-name">' + getWeekHead() +
2338                    '   </thead>' +
2339                    '   <tbody></tbody>' +
2340                    '</table>';
2341
2342            }
2343            //+'</div>'
2344            html += '<div class="dp-clearfix"></div>' +
2345                '<div class="time">' +
2346                '<div class="time1"></div>';
2347            if (!opt.singleDate) {
2348                html += '<div class="time2"></div>';
2349            }
2350            html += '</div>' +
2351                '<div class="dp-clearfix"></div>' +
2352                '</div>';
2353
2354            html += '<div class="footer">';
2355            if (opt.showShortcuts) {
2356                html += '<div class="shortcuts"><b>' + translate('shortcuts') + '</b>';
2357
2358                var data = opt.shortcuts;
2359                if (data) {
2360                    var name;
2361                    if (data['prev-days'] && data['prev-days'].length > 0) {
2362                        html += '&nbsp;<span class="prev-days">' + translate('past');
2363                        for (var i = 0; i < data['prev-days'].length; i++) {
2364                            name = data['prev-days'][i];
2365                            name += (data['prev-days'][i] > 1) ? translate('days') : translate('day');
2366                            html += ' <a href="javascript:;" shortcut="day,-' + data['prev-days'][i] + '">' + name + '</a>';
2367                        }
2368                        html += '</span>';
2369                    }
2370
2371                    if (data['next-days'] && data['next-days'].length > 0) {
2372                        html += '&nbsp;<span class="next-days">' + translate('following');
2373                        for (var i = 0; i < data['next-days'].length; i++) {
2374                            name = data['next-days'][i];
2375                            name += (data['next-days'][i] > 1) ? translate('days') : translate('day');
2376                            html += ' <a href="javascript:;" shortcut="day,' + data['next-days'][i] + '">' + name + '</a>';
2377                        }
2378                        html += '</span>';
2379                    }
2380
2381                    if (data.prev && data.prev.length > 0) {
2382                        html += '&nbsp;<span class="prev-buttons">' + translate('previous');
2383                        for (var i = 0; i < data.prev.length; i++) {
2384                            name = translate('prev-' + data.prev[i]);
2385                            html += ' <a href="javascript:;" shortcut="prev,' + data.prev[i] + '">' + name + '</a>';
2386                        }
2387                        html += '</span>';
2388                    }
2389
2390                    if (data.next && data.next.length > 0) {
2391                        html += '&nbsp;<span class="next-buttons">' + translate('next');
2392                        for (var i = 0; i < data.next.length; i++) {
2393                            name = translate('next-' + data.next[i]);
2394                            html += ' <a href="javascript:;" shortcut="next,' + data.next[i] + '">' + name + '</a>';
2395                        }
2396                        html += '</span>';
2397                    }
2398                }
2399
2400                if (opt.customShortcuts) {
2401                    for (var i = 0; i < opt.customShortcuts.length; i++) {
2402                        var sh = opt.customShortcuts[i];
2403                        html += '&nbsp;<span class="custom-shortcut"><a href="javascript:;" shortcut="custom">' + sh.name + '</a></span>';
2404                    }
2405                }
2406                html += '</div>';
2407            }
2408
2409            // Add Custom Values Dom
2410            if (opt.showCustomValues) {
2411                html += '<div class="customValues"><b>' + (opt.customValueLabel || translate('custom-values')) + '</b>';
2412
2413                if (opt.customValues) {
2414                    for (var i = 0; i < opt.customValues.length; i++) {
2415                        var val = opt.customValues[i];
2416                        html += '&nbsp;<span class="custom-value"><a href="javascript:;" custom="' + val.value + '">' + val.name + '</a></span>';
2417                    }
2418                }
2419            }
2420
2421            html += '</div></div>';
2422
2423
2424            return $(html);
2425        }
2426
2427        function getApplyBtnClass() {
2428            var klass = '';
2429            if (opt.autoClose === true) {
2430                klass += ' hide';
2431            }
2432            if (opt.applyBtnClass !== '') {
2433                klass += ' ' + opt.applyBtnClass;
2434            }
2435            return klass;
2436        }
2437
2438        function getWeekHead() {
2439            var prepend = opt.showWeekNumbers ? '<th>' + translate('week-number') + '</th>' : '';
2440            if (opt.startOfWeek == 'monday') {
2441                return prepend + '<th>' + translate('week-1') + '</th>' +
2442                    '<th>' + translate('week-2') + '</th>' +
2443                    '<th>' + translate('week-3') + '</th>' +
2444                    '<th>' + translate('week-4') + '</th>' +
2445                    '<th>' + translate('week-5') + '</th>' +
2446                    '<th>' + translate('week-6') + '</th>' +
2447                    '<th>' + translate('week-7') + '</th>';
2448            } else {
2449                return prepend + '<th>' + translate('week-7') + '</th>' +
2450                    '<th>' + translate('week-1') + '</th>' +
2451                    '<th>' + translate('week-2') + '</th>' +
2452                    '<th>' + translate('week-3') + '</th>' +
2453                    '<th>' + translate('week-4') + '</th>' +
2454                    '<th>' + translate('week-5') + '</th>' +
2455                    '<th>' + translate('week-6') + '</th>';
2456            }
2457        }
2458
2459        function isMonthOutOfBounds(month) {
2460            month = moment(month);
2461            if (opt.startDate && month.endOf('month').isBefore(opt.startDate)) {
2462                return true;
2463            }
2464            if (opt.endDate && month.startOf('month').isAfter(opt.endDate)) {
2465                return true;
2466            }
2467            return false;
2468        }
2469
2470        function getGapHTML() {
2471            var html = ['<div class="gap-top-mask"></div><div class="gap-bottom-mask"></div><div class="gap-lines">'];
2472            for (var i = 0; i < 20; i++) {
2473                html.push('<div class="gap-line">' +
2474                    '<div class="gap-1"></div>' +
2475                    '<div class="gap-2"></div>' +
2476                    '<div class="gap-3"></div>' +
2477                    '</div>');
2478            }
2479            html.push('</div>');
2480            return html.join('');
2481        }
2482
2483        function hasMonth2() {
2484            return (!opt.singleMonth);
2485        }
2486
2487        function attributesCallbacks(initialObject, callbacksArray, today) {
2488            var resultObject = $.extend(true, {}, initialObject);
2489
2490            $.each(callbacksArray, function(cbAttrIndex, cbAttr) {
2491                var addAttributes = cbAttr(today);
2492                for (var attr in addAttributes) {
2493                    if (resultObject.hasOwnProperty(attr)) {
2494                        resultObject[attr] += addAttributes[attr];
2495                    } else {
2496                        resultObject[attr] = addAttributes[attr];
2497                    }
2498                }
2499            });
2500
2501            var attrString = '';
2502
2503            for (var attr in resultObject) {
2504                if (resultObject.hasOwnProperty(attr)) {
2505                    attrString += attr + '="' + resultObject[attr] + '" ';
2506                }
2507            }
2508
2509            return attrString;
2510        }
2511
2512        function createMonthHTML(d) {
2513            var days = [];
2514            d.setDate(1);
2515            var lastMonth = new Date(d.getTime() - 86400000);
2516            var now = new Date();
2517
2518            var dayOfWeek = d.getDay();
2519            if ((dayOfWeek === 0) && (opt.startOfWeek === 'monday')) {
2520                // add one week
2521                dayOfWeek = 7;
2522            }
2523            var today, valid;
2524
2525            if (dayOfWeek > 0) {
2526                for (var i = dayOfWeek; i > 0; i--) {
2527                    var day = new Date(d.getTime() - 86400000 * i);
2528                    valid = isValidTime(day.getTime());
2529                    if (opt.startDate && compare_day(day, opt.startDate) < 0) valid = false;
2530                    if (opt.endDate && compare_day(day, opt.endDate) > 0) valid = false;
2531                    days.push({
2532                        date: day,
2533                        type: 'lastMonth',
2534                        day: day.getDate(),
2535                        time: day.getTime(),
2536                        valid: valid
2537                    });
2538                }
2539            }
2540            var toMonth = d.getMonth();
2541            for (var i = 0; i < 40; i++) {
2542                today = moment(d).add(i, 'days').toDate();
2543                valid = isValidTime(today.getTime());
2544                if (opt.startDate && compare_day(today, opt.startDate) < 0) valid = false;
2545                if (opt.endDate && compare_day(today, opt.endDate) > 0) valid = false;
2546                days.push({
2547                    date: today,
2548                    type: today.getMonth() == toMonth ? 'toMonth' : 'nextMonth',
2549                    day: today.getDate(),
2550                    time: today.getTime(),
2551                    valid: valid
2552                });
2553            }
2554            var html = [];
2555            for (var week = 0; week < 6; week++) {
2556                if (days[week * 7].type == 'nextMonth') break;
2557                html.push('<tr>');
2558
2559                for (var day = 0; day < 7; day++) {
2560                    var _day = (opt.startOfWeek == 'monday') ? day + 1 : day;
2561                    today = days[week * 7 + _day];
2562                    var highlightToday = moment(today.time).format('L') == moment(now).format('L');
2563                    today.extraClass = '';
2564                    today.tooltip = '';
2565                    if (today.valid && opt.beforeShowDay && typeof opt.beforeShowDay == 'function') {
2566                        var _r = opt.beforeShowDay(moment(today.time).toDate());
2567                        today.valid = _r[0];
2568                        today.extraClass = _r[1] || '';
2569                        today.tooltip = _r[2] || '';
2570                        if (today.tooltip !== '') today.extraClass += ' has-tooltip ';
2571                    }
2572
2573                    var todayDivAttr = {
2574                        time: today.time,
2575                        'data-tooltip': today.tooltip,
2576                        'class': 'day ' + today.type + ' ' + today.extraClass + ' ' + (today.valid ? 'valid' : 'invali
2576d') + ' ' + (highlightToday ? 'real-today' : '')
2577                    };
2578
2579                    if (day === 0 && opt.showWeekNumbers) {
2580                        html.push('<td><div class="week-number" data-start-time="' + today.time + '">' + opt.getWeekNumber(today.date) + '</div></td>');
2581                    }
2582
2583                    html.push('<td ' + attributesCallbacks({}, opt.dayTdAttrs, today) + '><div ' + attributesCallbacks(todayDivAttr, opt.dayDivAttrs, today) + '>' + showDayHTML(today.time, today.day) + '</div></td>');
2584                }
2585                html.push('</tr>');
2586            }
2587            return html.join('');
2588        }
2589
2590        function showDayHTML(time, date) {
2591            if (opt.showDateFilter && typeof opt.showDateFilter == 'function') return opt.showDateFilter(time, date);
2592            return date;
2593        }
2594
2595        function getLanguages() {
2596            if (opt.language == 'auto') {
2597                var language = navigator.language ? navigator.language : navigator.browserLanguage;
2598                if (!language) {
2599                    return $.dateRangePickerLanguages['default'];
2600                }
2601                language = language.toLowerCase();
2602                if(language in $.dateRangePickerLanguages){
2603                    return $.dateRangePickerLanguages[language];
2604                }
2605
2606                return $.dateRangePickerLanguages['default'];
2607            } else if (opt.language && opt.language in $.dateRangePickerLanguages) {
2608                return $.dateRangePickerLanguages[opt.language];
2609            } else {
2610                return $.dateRangePickerLanguages['default'];
2611            }
2612        }
2613
2614        /**
2615         * Translate language string, try both the provided translation key, as the lower case version
2616         */
2617        function translate(translationKey) {
2618            var translationKeyLowerCase = translationKey.toLowerCase();
2619            var result = (translationKey in languages) ? languages[translationKey] : (translationKeyLowerCase in languages) ? languages[translationKeyLowerCase] : null;
2620            var defaultLanguage = $.dateRangePickerLanguages['default'];
2621            if (result == null) result = (translationKey in defaultLanguage) ? defaultLanguage[translationKey] : (translationKeyLowerCase in defaultLanguage) ? defaultLanguage[translationKeyLowerCase] : '';
2622
2623            return result;
2624        }
2625
2626        function getDefaultTime() {
2627            var defaultTime = opt.defaultTime ? opt.defaultTime : new Date();
2628
2629            if (opt.lookBehind) {
2630                if (opt.startDate && compare_month(defaultTime, opt.startDate) < 0) defaultTime = nextMonth(moment(opt.startDate).toDate());
2631                if (opt.endDate && compare_month(defaultTime, opt.endDate) > 0) defaultTime = moment(opt.endDate).toDate();
2632            } else {
2633                if (opt.startDate && compare_month(defaultTime, opt.startDate) < 0) defaultTime = moment(opt.startDate).toDate();
2634                if (opt.endDate && compare_month(nextMonth(defaultTime), opt.endDate) > 0) defaultTime = prevMonth(moment(opt.endDate).toDate());
2635            }
2636
2637            if (opt.singleDate) {
2638                if (opt.startDate && compare_month(defaultTime, opt.startDate) < 0) defaultTime = moment(opt.startDate).toDate();
2639                if (opt.endDate && compare_month(defaultTime, opt.endDate) > 0) defaultTime = moment(opt.endDate).toDate();
2640            }
2641
2642            return defaultTime;
2643        }
2644
2645        function resetMonthsView(time) {
2646            if (!time) {
2647                time = getDefaultTime();
2648            }
2649
2650            if (opt.lookBehind) {
2651                showMonth(prevMonth(time), 'month1');
2652                showMonth(time, 'month2');
2653            } else {
2654                showMonth(time, 'month1');
2655                showMonth(nextMonth(time), 'month2');
2656            }
2657
2658            if (opt.singleDate) {
2659                showMonth(time, 'month1');
2660            }
2661
2662            showSelectedDays();
2663            showGap();
2664        }
2665
2666        function outsideClickClose(evt) {
2667            if (!IsOwnDatePickerClicked(evt, self[0])) {
2668                if (box.is(':visible')) closeDatePicker();
2669            }
2670        }
2671
2672    };
2673}));

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.