PageSourceSearch

https://www.leonardo-hotels-cyprus.pl/templates/cy_leonardo_pl-joomla5/js/jquery.daterangepicker.js

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

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.