PageSourceSearch

https://newamsterdamhistorycenter.org/wp-content/plugins/fat-event…query.datetimepicker.full.min.js?ver=6.8.10

js newamsterdamhistorycenter.org collected 2026-10-02 10:25:15 UTC 144,508 bytes, 2,911 lines download raw bytes

vendor: 6,961 bytes, lines 1-19
1/*!
2 * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2016
3 * @version 1.3.4
4 *
5 * Date formatter utility library that allows formatting date/time variables or Date objects using PHP DateTime format.
6 * @see http://php.net/manual/en/function.date.php
7 *
8 * For more JQuery plugins visit http://plugins.krajee.com
9 * For more Yii related demos visit http://demos.krajee.com
10 */var DateFormatter;!function(){"use strict";var t,e,r,n,a,u,i;u=864e5,i=3600,t=function(t,e){return"string"==typeof t&&"string"==typeof e&&t.toLowerCase()===e.toLowerCase()},e=function(t,r,n){var a=n||"0",u=t.toString();return u.length<r?e(a+u,r):u},r=function(t){var e,n;for(t=t||{},e=1;e<arguments.length;e++)if(n=arguments[e])for(var a in n)n.hasOwnProperty(a)&&("object"==typeof n[a]?r(t[a],n[a]):t[a]=n[a]);return t},n=function(t,e){for(var r=0;r<e.length;r++)if(e[r].toLowerCase()===t.toLowerCase())return r;return-1},a={dateSettings:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],meridiem:["AM","PM"],ordinal:function(t){var e=t%10,r={1:"st",2:"nd",3:"rd"};return 1!==Math.floor(t%100/10)&&r[e]?r[e]:"th"}},separators:/[ \-+\/\.T:@]/g,validParts:/[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g,intParts:/[djwNzmnyYhHgGis]/g,tzParts:/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,tzClip:/[^-+\dA-Z]/g},DateFormatter=function(t){var e=this,n=r(a,t);e.dateSettings=n.dateSettings,e.separators=n.separators,e.validParts=n.validParts,e.intParts=n.intParts,e.tzParts=n.tzParts,e.tzClip=n.tzClip},DateFormatter.prototype={constructor:DateFormatter,getMonth:function(t){var e,r=this;return e=n(t,r.dateSettings.monthsShort)+1,0===e&&(e=n(t,r.dateSettings.months)+1),e},parseDate:function(e,r){var n,a,u,i,s,o,c,f,l,h,d=this,g=!1,m=!1,p=d.dateSettings,y={date:null,year:null,month:null,day:null,hour:0,min:0,sec:0};if(!e)return null;if(e instanceof Date)return e;if("U"===r)return u=parseInt(e),u?new Date(1e3*u):e;switch(typeof e){case"number":return new Date(e);case"string":break;default:return null}if(n=r.match(d.validParts),!n||0===n.length)throw new Error("Invalid date format definition.");for(a=e.replace(d.separators,"\x00").split("\x00"),u=0;u<a.length;u++)switch(i=a[u],s=parseInt(i),n[u]){case"y":case"Y":if(!s)return null;l=i.length,y.year=2===l?parseInt((70>s?"20":"19")+i):s,g=!0;break;case"m":case"n":case"M":case"F":if(isNaN(s)){if(o=d.getMonth(i),!(o>0))return null;y.month=o}else{if(!(s>=1&&12>=s))return null;y.month=s}g=!0;break;case"d":case"j":if(!(s>=1&&31>=s))return null;y.day=s,g=!0;break;case"g":case"h":if(c=n.indexOf("a")>-1?n.indexOf("a"):n.indexOf("A")>-1?n.indexOf("A"):-1,h=a[c],c>-1)f=t(h,p.meridiem[0])?0:t(h,p.meridiem[1])?12:-1,s>=1&&12>=s&&f>-1?y.hour=s+f-1:s>=0&&23>=s&&(y.hour=s);else{if(!(s>=0&&23>=s))return null;y.hour=s}m=!0;break;case"G":case"H":if(!(s>=0&&23>=s))return null;y.hour=s,m=!0;break;case"i":if(!(s>=0&&59>=s))return null;y.min=s,m=!0;break;case"s":if(!(s>=0&&59>=s))return null;y.sec=s,m=!0}if(g===!0&&y.year&&y.month&&y.day)y.date=new Date(y.year,y.month-1,y.day,y.hour,y.min,y.sec,0);else{if(m!==!0)return null;y.date=new Date(0,0,0,y.hour,y.min,y.sec,0)}return y.date},guessDate:function(t,e){if("string"!=typeof t)return t;var r,n,a,u,i,s,o=this,c=t.replace(o.separators,"\x00").split("\x00"),f=/^[djmn]/g,l=e.match(o.validParts),h=new Date,d=0;if(!f.test(l[0]))return t;for(a=0;a<c.length;a++){if(d=2,i=c[a],s=parseInt(i.substr(0,2)),isNaN(s))return null;switch(a){case 0:"m"===l[0]||"n"===l[0]?h.setMonth(s-1):h.setDate(s);break;case 1:"m"===l[0]||"n"===l[0]?h.setDate(s):h.setMonth(s-1);break;case 2:if(n=h.getFullYear(),r=i.length,d=4>r?r:4,n=parseInt(4>r?n.toString().substr(0,4-r)+i:i.substr(0,4)),!n)return null;h.setFullYear(n);break;case 3:h.setHours(s);break;case 4:h.setMinutes(s);break;case 5:h.setSeconds(s)}u=i.substr(d),u.length>0&&c.splice(a+1,0,u)}return h},parseFormat:function(t,r){var n,a=this,s=a.dateSettings,o=/\\?(.?)/gi,c=function(t,e){return n[t]?n[t]():e};return n={d:function(){return e(n.j(),2)},D:function(){return s.daysShort[n.w()]},j:function(){return r.getDate()},l:function(){return s.days[n.w()]},N:function(){return n.w()||7},w:function(){return r.getDay()},z:function(){var t=new Date(n.Y(),n.n()-1,n.j()),e=new Date(n.Y(),0,1);return Math.round((t-e)/u)},W:function(){var t=new Date(n.Y(),n.n()-1,n.j()-n.N()+3),r=new Date(t.getFullYear(),0,4);return e(1+Math.round((t-r)/u/7),2)},F:function(){return s.months[r.getMonth()]},m:function(){return e(n.n(),2)},M:function(){return s.monthsShort[r.getMonth()]},n:function(){return r.getMonth()+1},t:function(){return new Date(n.Y(),n.n(),0).getDate()},L:function(){var t=n.Y();return t%4===0&&t%100!==0||t%400===0?1:0},o:function(){var t=n.n(),e=n.W(),r=n.Y();return r+(12===t&&9>e?1:1===t&&e>9?-1:0)},Y:function(){return r.getFullYear()},y:function(){return n.Y().toString().slice(-2)},a:function(){return n.A().toLowerCase()},A:function(){var t=n.G()<12?0:1;return s.meridiem[t]},B:function(){var t=r.getUTCHours()*i,n=60*r.getUTCMinutes(),a=r.getUTCSeconds();return e(Math.floor((t+n+a+i)/86.4)%1e3,3)},g:function(){return n.G()%12||12},G:function(){return r.getHours()},h:function(){return e(n.g(),2)},H:function(){return e(n.G(),2)},i:function(){return e(r.getMinutes(),2)},s:function(){return e(r.getSeconds(),2)},u:function(){return e(1e3*r.getMilliseconds(),6)},e:function(){var t=/\((.*)\)/.exec(String(r))[1];return t||"Coordinated Universal Time"},I:function(){var t=new Date(n.Y(),0),e=Date.UTC(n.Y(),0),r=new Date(n.Y(),6),a=Date.UTC(n.Y(),6);return t-e!==r-a?1:0},O:function(){var t=r.getTimezoneOffset(),n=Math.abs(t);return(t>0?"-":"+")+e(100*Math.floor(n/60)+n%60,4)},P:function(){var t=n.O();return t.substr(0,3)+":"+t.substr(3,2)},T:function(){var t=(String(r).match(a.tzParts)||[""]).pop().replace(a.tzClip,"");return t||"UTC"},Z:function(){return 60*-r.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(o,c)},r:function(){return"D, d M Y H:i:s O".replace(o,c)},U:function(){return r.getTime()/1e3||0}},c(t,t)},formatDate:function(t,e){var r,n,a,u,i,s=this,o="",c="\\";if("string"==typeof t&&(t=s.parseDate(t,e),!t))return null;if(t instanceof Date){for(a=e.length,r=0;a>r;r++)i=e.charAt(r),"S"!==i&&i!==c&&(r>0&&e.charAt(r-1)===c?o+=i:(u=s.parseFormat(i,t),r!==a-1&&s.intParts.test(i)&&"S"===e.charAt(r+1)&&(n=parseInt(u)||0,u+=s.dateSettings.ordinal(n)),o+=u));return o}return""}}}();/**
11 * @preserve jQuery DateTimePicker
12 * @homepage http://xdsoft.net/jqplugins/datetimepicker/
13 * @author Chupurnov Valeriy (<[email protected]>)
14 */
15
16/**
17 * @param {jQuery} $
18 */
19var datetimepickerFactory = function ($) {
20    'use strict';
21
22    var default_options  = {
23        i18n: {
24            ar: { // Arabic
25                months: [
26                    "كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"
27                ],
28                dayOfWeekShort: [
29                    "ن", "ث", "ع", "خ", "ج", "س", "ح"
30                ],
31                dayOfWeek: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"]
32            },
33            ro: { // Romanian
34                months: [
35                    "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"
36                ],
37                dayOfWeekShort: [
38                    "Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ"
39                ],
40                dayOfWeek: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă"]
41            },
42            id: { // Indonesian
43                months: [
44                    "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"
45                ],
46                dayOfWeekShort: [
47                    "Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"
48                ],
49                dayOfWeek: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"]
50            },
51            is: { // Icelandic
52                months: [
53                    "Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"
54                ],
55                dayOfWeekShort: [
56                    "Sun", "Mán", "Þrið", "Mið", "Fim", "Fös", "Lau"
57                ],
58                dayOfWeek: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur"]
59            },
60            bg: { // Bulgarian
61                months: [
62                    "Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"
63                ],
64                dayOfWeekShort: [
65                    "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
66                ],
67                dayOfWeek: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота"]
68            },
69            fa: { // Persian/Farsi
70                months: [
71                    'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
72                ],
73                dayOfWeekShort: [
74                    'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
75                ],
76                dayOfWeek: ["یک‌شنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", "شنبه", "یک‌شنبه"]
77            },
78            ru: { // Russian
79                months: [
80                    'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
81                ],
82                dayOfWeekShort: [
83                    "Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
84                ],
85                dayOfWeek: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"]
86            },
87            uk: { // Ukrainian
88                months: [
89                    'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
90                ],
91                dayOfWeekShort: [
92                    "Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт"
93                ],
94                dayOfWeek: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота"]
95            },
96            en: { // English
97                months: [
98                    "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
98November", "December"
99                ],
100                dayOfWeekShort: [
101                    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
102                ],
103                dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
104            },
105            el: { // Ελληνικά
106                months: [
107                    "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
108                ],
109                dayOfWeekShort: [
110                    "Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"
111                ],
112                dayOfWeek: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"]
113            },
114            de: { // German
115                months: [
116                    'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
117                ],
118                dayOfWeekShort: [
119                    "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
120                ],
121                dayOfWeek: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
122            },
123            nl: { // Dutch
124                months: [
125                    "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
126                ],
127                dayOfWeekShort: [
128                    "zo", "ma", "di", "wo", "do", "vr", "za"
129                ],
130                dayOfWeek: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"]
131            },
132            tr: { // Turkish
133                months: [
134                    "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"
135                ],
136                dayOfWeekShort: [
137                    "Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts"
138                ],
139                dayOfWeek: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"]
140            },
141            fr: { //French
142                months: [
143                    "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
144                ],
145                dayOfWeekShort: [
146                    "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
147                ],
148                dayOfWeek: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
149            },
150            es: { // Spanish
151                months: [
152                    "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
153                ],
154                dayOfWeekShort: [
155                    "Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
156                ],
157                dayOfWeek: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"]
158            },
159            th: { // Thai
160                months: [
161                    'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
162                ],
163                dayOfWeekShort: [
164                    'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
165                ],
166                dayOfWeek: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"]
167            },
168            pl: { // Polish
169                months: [
170                    "styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"
171                ],
172                dayOfWeekShort: [
173                    "nd", "pn", "wt", "śr", "cz", "pt", "sb"
174                ],
175                dayOfWeek: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"]
176            },
177            pt: { // Portuguese
178                months: [
179                    "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
180                ],
181                dayOfWeekShort: [
182                    "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
183                ],
184                dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "SÃ
184¡bado"]
185            },
186            ch: { // Simplified Chinese
187                months: [
188                    "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
189                ],
190                dayOfWeekShort: [
191                    "日", "一", "二", "三", "四", "五", "六"
192                ]
193            },
194            se: { // Swedish
195                months: [
196                    "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September",  "Oktober", "November", "December"
197                ],
198                dayOfWeekShort: [
199                    "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
200                ]
201            },
202            km: { // Khmer (ភាសាខ្មែរ)
203                months: [
204                    "មករា​", "កុម្ភៈ", "មិនា​", "មេសា​", "ឧសភា​", "មិថុនា​", "កក្កដា​", "សីហា​", "កញ្ញា​", "តុលា​", "វិច្ឆិកា", "ធ្នូ​"
205                ],
206                dayOfWeekShort: ["អាទិ​", "ច័ន្ទ​", "អង្គារ​", "ពុធ​", "ព្រហ​​", "សុក្រ​", "សៅរ៍"],
207                dayOfWeek: ["អាទិត្យ​", "ច័ន្ទ​", "អង្គារ​", "ពុធ​", "ព្រហស្បតិ៍​", "សុក្រ​", "សៅរ៍"]
208            },
209            kr: { // Korean
210                months: [
211                    "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
212                ],
213                dayOfWeekShort: [
214                    "일", "월", "화", "수", "목", "금", "토"
215                ],
216                dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
217            },
218            it: { // Italian
219                months: [
220                    "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
221                ],
222                dayOfWeekShort: [
223                    "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
224                ],
225                dayOfWeek: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"]
226            },
227            da: { // Dansk
228                months: [
229                    "Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"
230                ],
231                dayOfWeekShort: [
232                    "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
233                ],
234                dayOfWeek: ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"]
235            },
236            no: { // Norwegian
237                months: [
238                    "Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"
239                ],
240                dayOfWeekShort: [
241                    "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
242                ],
243                dayOfWeek: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag']
244            },
245            ja: { // Japanese
246                months: [
247                    "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
248                ],
249                dayOfWeekShort: [
250                    "日", "月", "火", "水", "木", "金", "土"
251                ],
252                dayOfWeek: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"]
253            },
254            vi: { // Vietnamese
255                months: [
256                    "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"
257                ],
258                dayOfWeekShort: [
259                    "CN", "T2", "T3", "T4", "T5", "T6", "T7"
260                ],
261                dayOfWeek: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"]
262            },
263            sl: { // Slovenščina
264                months: [
265                    "Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "
265November", "December"
266                ],
267                dayOfWeekShort: [
268                    "Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"
269                ],
270                dayOfWeek: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota"]
271            },
272            cs: { // Čeština
273                months: [
274                    "Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
275                ],
276                dayOfWeekShort: [
277                    "Ne", "Po", "Út", "St", "Čt", "Pá", "So"
278                ]
279            },
280            hu: { // Hungarian
281                months: [
282                    "Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"
283                ],
284                dayOfWeekShort: [
285                    "Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"
286                ],
287                dayOfWeek: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"]
288            },
289            az: { //Azerbaijanian (Azeri)
290                months: [
291                    "Yanvar", "Fevral", "Mart", "Aprel", "May", "Iyun", "Iyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"
292                ],
293                dayOfWeekShort: [
294                    "B", "Be", "Ça", "Ç", "Ca", "C", "Ş"
295                ],
296                dayOfWeek: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə"]
297            },
298            bs: { //Bosanski
299                months: [
300                    "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
301                ],
302                dayOfWeekShort: [
303                    "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
304                ],
305                dayOfWeek: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
306            },
307            ca: { //Català
308                months: [
309                    "Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"
310                ],
311                dayOfWeekShort: [
312                    "Dg", "Dl", "Dt", "Dc", "Dj", "Dv", "Ds"
313                ],
314                dayOfWeek: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte"]
315            },
316            'en-GB': { //English (British)
317                months: [
318                    "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
318November", "December"
319                ],
320                dayOfWeekShort: [
321                    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
322                ],
323                dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
324            },
325            et: { //"Eesti"
326                months: [
327                    "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"
328                ],
329                dayOfWeekShort: [
330                    "P", "E", "T", "K", "N", "R", "L"
331                ],
332                dayOfWeek: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev"]
333            },
334            eu: { //Euskara
335                months: [
336                    "Urtarrila", "Otsaila", "Martxoa", "Apirila", "Maiatza", "Ekaina", "Uztaila", "Abuztua", "Iraila", "Urria", "Azaroa", "Abendua"
337                ],
338                dayOfWeekShort: [
339                    "Ig.", "Al.", "Ar.", "Az.", "Og.", "Or.", "La."
340                ],
341                dayOfWeek: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata']
342            },
343            fi: { //Finnish (Suomi)
344                months: [
345                    "Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"
346                ],
347                dayOfWeekShort: [
348                    "Su", "Ma", "Ti", "Ke", "To", "Pe", "La"
349                ],
350                dayOfWeek: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"]
351            },
352            gl: { //Galego
353                months: [
354                    "Xan", "Feb", "Maz", "Abr", "Mai", "Xun", "Xul", "Ago", "Set", "Out", "Nov", "Dec"
355                ],
356                dayOfWeekShort: [
357                    "Dom", "Lun", "Mar", "Mer", "Xov", "Ven", "Sab"
358                ],
359                dayOfWeek: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado"]
360            },
361            hr: { //Hrvatski
362                months: [
363                    "Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"
364                ],
365                dayOfWeekShort: [
366                    "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
367                ],
368                dayOfWeek: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"]
369            },
370            ko: { //Korean (한국어)
371                months: [
372                    "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
373                ],
374                dayOfWeekShort: [
375                    "일", "월", "화", "수", "목", "금", "토"
376                ],
377                dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
378            },
379            lt: { //Lithuanian (lietuvių)
380                months: [
381                    "Sausio", "Vasario", "Kovo", "Balandžio", "Gegužės", "Birželio", "Liepos", "Rugpjūčio", "Rugsėjo", "Spalio", "Lapkričio", "Gruodžio"
382                ],
383                dayOfWeekShort: [
384                    "Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Šeš"
385                ],
386                dayOfWeek: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis"]
387            },
388            lv: { //Latvian (Latviešu)
389                months: [
390                    "Janvāris", "Februāris", "Marts", "Aprīlis ", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"
391                ],
392                dayOfWeekShort: [
393                    "Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "St"
394                ],
395                dayOfWeek: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena"]
396            },
397            mk: { //Macedonian (Македонски)
398                months: [
399                    "јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"
400                ],
401                dayOfWeekShort: [
402                    "нед", "пон", "вто", "сре", "чет", "пет", "саб"
403                ],
404                dayOfWeek: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота"]
405            },
406            mn: { //Mongolian (Монгол)
407                months: [
408                    "1-р сар", "2-р сар", "3-р сар", "4-р сар", "5-р сар", "6-р сар", "7-р сар", "8-р сар", "9-р сар", "10-р сар", "11-р сар", "12-р сар"
409                ],
410                dayOfWeekShort: [
411                    "Дав", "Мяг", "Лха", "Пүр", "Бсн", "Бям", "Ням"
412                ],
413                dayOfWeek: ["Даваа", "Мягмар", "Лхагва", "Пүрэв", "Баасан", "Бямба", "Ням"]
414            },
415            'pt-BR': { //Português(Brasil)
416                months: [
417                    "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
418                ],
419                dayOfWeekShort: [
420                    "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"
421                ],
422                dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "SÃ
422¡bado"]
423            },
424            sk: { //Slovenčina
425                months: [
426                    "Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"
427                ],
428                dayOfWeekShort: [
429                    "Ne", "Po", "Ut", "St", "Å t", "Pi", "So"
430                ],
431                dayOfWeek: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"]
432            },
433            sq: { //Albanian (Shqip)
434                months: [
435                    "Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor"
436                ],
437                dayOfWeekShort: [
438                    "Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu"
439                ],
440                dayOfWeek: ["E Diel", "E Hënë", "E Martē", "E Mërkurë", "E Enjte", "E Premte", "E Shtunë"]
441            },
442            'sr-YU': { //Serbian (Srpski)
443                months: [
444                    "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
445                ],
446                dayOfWeekShort: [
447                    "Ned", "Pon", "Uto", "Sre", "čet", "Pet", "Sub"
448                ],
449                dayOfWeek: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"]
450            },
451            sr: { //Serbian Cyrillic (Српски)
452                months: [
453                    "јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар"
454                ],
455                dayOfWeekShort: [
456                    "нед", "пон", "уто", "сре", "чет", "пет", "суб"
457                ],
458                dayOfWeek: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"]
459            },
460            sv: { //Svenska
461                months: [
462                    "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
463                ],
464                dayOfWeekShort: [
465                    "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
466                ],
467                dayOfWeek: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"]
468            },
469            'zh-TW': { //Traditional Chinese (繁體中文)
470                months: [
471                    "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
472                ],
473                dayOfWeekShort: [
474                    "日", "一", "二", "三", "四", "五", "六"
475                ],
476                dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
477            },
478            zh: { //Simplified Chinese (简体中文)
479                months: [
480                    "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
481                ],
482                dayOfWeekShort: [
483                    "日", "一", "二", "三", "四", "五", "六"
484                ],
485                dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
486            },
487            ug:{ // Uyghur(ئۇيغۇرچە)
488                months: [
489                    "1-ئاي","2-ئاي","3-ئاي","4-ئاي","5-ئاي","6-ئاي","7-ئاي","8-ئاي","9-ئاي","10-ئاي","11-ئاي","12-ئاي"
490                ],
491                dayOfWeek: [
492                    "يەكشەنبە", "دۈشەنبە","سەيشەنبە","چارشەنبە","پەيشەنبە","جۈمە","شەنبە"
493                ]
494            },
495            he: { //Hebrew (עברית)
496                months: [
497                    'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'
498                ],
499                dayOfWeekShort: [
500                    'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת'
501                ],
502                dayOfWeek: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"]
503            },
504            hy: { // Armenian
505                months: [
506                    "Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"
507                ],
508                dayOfWeekShort: [
509                    "Կի", "Երկ", "Երք", "Չոր", "Հնգ", "Ուրբ", "Շբթ"
510                ],
511                dayOfWeek: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ"]
512            },
513            kg: { // Kyrgyz
514                months: [
515                    'Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш Оона', 'Аяк Оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы'
516                ],
517                dayOfWeekShort: [
518                    "Жек", "Дүй", "Шей", "Шар", "Бей", "Жум", "Ише"
519                ],
520                dayOfWeek: [
521                    "Жекшемб", "Дүйшөмб", "Шейшемб", "Шаршемб", "Бейшемби", "Жума", "Ишенб"
522                ]
523            },
524            rm: { // Romansh
525                months: [
526                    "Schaner", "Favrer", "Mars", "Avrigl", "Matg", "Zercladur", "Fanadur", "Avust", "Settember", "October", "November", "December"
527                ],
528                dayOfWeekShort: [
529                    "Du", "Gli", "Ma", "Me", "Gie", "Ve", "So"
530                ],
531                dayOfWeek: [
532                    "Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda"
533                ]
534            },
535            ka: { // Georgian
536                months: [
537                    'იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'
538                ],
539                dayOfWeekShort: [
540                    "კვ", "ორშ", "სამშ", "ოთხ", "ხუთ", "პარ", "შაბ"
541                ],
542                dayOfWeek: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი"]
543            }
544        },
545
546        ownerDocument: document,
547        contentWindow: window,
548
549        value: '',
550        rtl: false,
551
552        format:	'Y/m/d H:i',
553        formatTime:	'H:i',
554        formatDate:	'Y/m/d',
555
556        startDate:	false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
557        step: 60,
558        monthChangeSpinner: true,
559
560        closeOnDateSelect: false,
561        closeOnTimeSelect: true,
562        closeOnWithoutClick: true,
563        closeOnInputClick: true,
564        openOnFocus: true,
565
566        timepicker: true,
567        datepicker: true,
568        weeks: false,
569
570        defaultTime: false,	// use formatTime format (ex. '10:00' for formatTime:	'H:i')
571        defaultDate: false,	// use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05')
572
573        minDate: false,
574        maxDate: false,
575        minTime: false,
576        maxTime: false,
577        minDateTime: false,
578        maxDateTime: false,
579
580        allowTimes: [],
581        opened: false,
582        initTime: true,
583        inline: false,
584        theme: '',
585        touchMovedThreshold: 5,
586
587        onSelectDate: function () {},
588        onSelectTime: function () {},
589        onChangeMonth: function () {},
590        onGetWeekOfYear: function () {},
591        onChangeYear: function () {},
592        onChangeDateTime: function () {},
593        onShow: function () {},
594        onClose: function () {},
595        onGenerate: function () {},
596
597        withoutCopyright: true,
598        inverseButton: false,
599        hours12: false,
600        next: 'xdsoft_next',
601        prev : 'xdsoft_prev',
602        dayOfWeekStart: 0,
603        parentID: 'body',
604        timeHeightInTimePicker: 25,
605        timepickerScrollbar: true,
606        todayButton: true,
607        prevButton: true,
608        nextButton: true,
609        defaultSelect: true,
610
611        scrollMonth: true,
612        scrollTime: true,
613        scrollInput: true,
614
615        lazyInit: false,
616        mask: false,
617        validateOnBlur: true,
618        allowBlank: true,
619        yearStart: 1950,
620        yearEnd: 2050,
621        monthStart: 0,
622        monthEnd: 11,
623        style: '',
624        id: '',
625        fixed: false,
626        roundTime: 'round', // ceil, floor
627        className: '',
628        weekends: [],
629        highlightedDates: [],
630        highlightedPeriods: [],
631        allowDates : [],
632        allowDateRe : null,
633        disabledDates : [],
634        disabledWeekDays: [],
635        yearOffset: 0,
636        beforeShowDay: null,
637
638        enterLikeTab: true,
vendor: 104,685 bytes, lines 639-2889
639        showApplyButton: false,
640        insideParent: false,
641    };
642
643    var dateHelper = null,
644        defaultDateHelper = null,
645        globalLocaleDefault = 'en',
646        globalLocale = 'en';
647
648    var dateFormatterOptionsDefault = {
649        meridiem: ['AM', 'PM']
650    };
651
652    var initDateFormatter = function(){
653        var locale = default_options.i18n[globalLocale],
654            opts = {
655                days: locale.dayOfWeek,
656                daysShort: locale.dayOfWeekShort,
657                months: locale.months,
658                monthsShort: $.map(locale.months, function(n){ return n.substring(0, 3) })
659            };
660
661        if (typeof DateFormatter === 'function') {
662            dateHelper = defaultDateHelper = new DateFormatter({
663                dateSettings: $.extend({}, dateFormatterOptionsDefault, opts)
664            });
665        }
666    };
667
668    var dateFormatters = {
669        moment: {
670            default_options:{
671                format: 'YYYY/MM/DD HH:mm',
672                formatDate: 'YYYY/MM/DD',
673                formatTime: 'HH:mm',
674            },
675            formatter: {
676                parseDate: function (date, format) {
677                    if(isFormatStandard(format)){
678                        return defaultDateHelper.parseDate(date, format);
679                    }
680                    var d = moment(date, format);
681                    return d.isValid() ? d.toDate() : false;
682                },
683
684                formatDate: function (date, format) {
685                    if(isFormatStandard(format)){
686                        return defaultDateHelper.formatDate(date, format);
687                    }
688                    return moment(date).format(format);
689                },
690
691                formatMask: function(format){
692                    return format
693                        .replace(/Y{4}/g, '9999')
694                        .replace(/Y{2}/g, '99')
695                        .replace(/M{2}/g, '19')
696                        .replace(/D{2}/g, '39')
697                        .replace(/H{2}/g, '29')
698                        .replace(/m{2}/g, '59')
699                        .replace(/s{2}/g, '59');
700                },
701            }
702        }
703    }
704
705    // for locale settings
706    $.datetimepicker = {
707        setLocale: function(locale){
708            var newLocale = default_options.i18n[locale] ? locale : globalLocaleDefault;
709            if (globalLocale !== newLocale) {
710                globalLocale = newLocale;
711                // reinit date formatter
712                initDateFormatter();
713            }
714        },
715
716        setDateFormatter: function(dateFormatter) {
717            if(typeof dateFormatter === 'string' && dateFormatters.hasOwnProperty(dateFormatter)){
718                var df = dateFormatters[dateFormatter];
719                $.extend(default_options, df.default_options);
720                dateHelper = df.formatter;
721            }
722            else {
723                dateHelper = dateFormatter;
724            }
725        },
726    };
727
728    var standardFormats = {
729        RFC_2822: 'D, d M Y H:i:s O',
730        ATOM: 'Y-m-d\TH:i:sP',
731        ISO_8601: 'Y-m-d\TH:i:sO',
732        RFC_822: 'D, d M y H:i:s O',
733        RFC_850: 'l, d-M-y H:i:s T',
734        RFC_1036: 'D, d M y H:i:s O',
735        RFC_1123: 'D, d M Y H:i:s O',
736        RSS: 'D, d M Y H:i:s O',
737        W3C: 'Y-m-d\TH:i:sP'
738    }
739
740    var isFormatStandard = function(format){
741        return Object.values(standardFormats).indexOf(format) === -1 ? false : true;
742    }
743
744    $.extend($.datetimepicker, standardFormats);
745
746    // first init date formatter
747    initDateFormatter();
748
749    // fix for ie8
750    if (!window.getComputedStyle) {
751        window.getComputedStyle = function (el) {
752            this.el = el;
753            this.getPropertyValue = function (prop) {
754                var re = /(-([a-z]))/g;
755                if (prop === 'float') {
756                    prop = 'styleFloat';
757                }
758                if (re.test(prop)) {
759                    prop = prop.replace(re, function (a, b, c) {
760                        return c.toUpperCase();
761                    });
762                }
763                return el.currentStyle[prop] || null;
764            };
765            return this;
766        };
767    }
768    if (!Array.prototype.indexOf) {
769        Array.prototype.indexOf = function (obj, start) {
770            var i, j;
771            for (i = (start || 0), j = this.length; i < j; i += 1) {
772                if (this[i] === obj) { return i; }
773            }
774            return -1;
775        };
776    }
777
778    Date.prototype.countDaysInMonth = function () {
779        return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate();
780    };
781
782    $.fn.xdsoftScroller = function (options, percent) {
783        return this.each(function () {
784            var timeboxparent = $(this),
785                pointerEventToXY = function (e) {
786                    var out = {x: 0, y: 0},
787                        touch;
788                    if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
789                        touch  = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
790                        out.x = touch.clientX;
791                        out.y = touch.clientY;
792                    } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
793                        out.x = e.clientX;
794                        out.y = e.clientY;
795                    }
796                    return out;
797                },
798                timebox,
799                parentHeight,
800                height,
801                scrollbar,
802                scroller,
803                maximumOffset = 100,
804                start = false,
805                startY = 0,
806                startTop = 0,
807                h1 = 0,
808                touchStart = false,
809                startTopScroll = 0,
810                calcOffset = function () {};
811
812            if (percent === 'hide') {
813                timeboxparent.find('.xdsoft_scrollbar').hide();
814                return;
815            }
816
817            if (!$(this).hasClass('xdsoft_scroller_box')) {
818                timebox = timeboxparent.children().eq(0);
819                parentHeight = timeboxparent[0].clientHeight;
820                height = timebox[0].offsetHeight;
821                scrollbar = $('<div class="xdsoft_scrollbar"></div>');
822                scroller = $('<div class="xdsoft_scroller"></div>');
823                scrollbar.append(scroller);
824
825                timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar);
826                calcOffset = function calcOffset(event) {
827                    var offset = pointerEventToXY(event).y - startY + startTopScroll;
828                    if (offset < 0) {
829                        offset = 0;
830                    }
831                    if (offset + scroller[0].offsetHeight > h1) {
832                        offset = h1 - scroller[0].offsetHeight;
833                    }
834                    timeboxparent.trigger('scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0]);
835                };
836
837                scroller
838                    .on('touchstart.xdsoft_scroller mousedown.xdsoft_scroller', function (event) {
839                        if (!parentHeight) {
840                            timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
841                        }
842
843                        startY = pointerEventToXY(event).y;
844                        startTopScroll = parseInt(scroller.css('margin-top'), 10);
845                        h1 = scrollbar[0].offsetHeight;
846
847                        if (event.type === 'mousedown' || event.type === 'touchstart') {
848                            if (options.ownerDocument) {
849                                $(options.ownerDocument.body).addClass('xdsoft_noselect');
850                            }
851                            $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft_scroller', function arguments_callee() {
852                                $([options.ownerDocument.body, options.contentWindow]).off('touchend mouseup.xdsoft_scroller', arguments_callee)
853                                    .off('mousemove.xdsoft_scroller', calcOffset)
854                                    .removeClass('xdsoft_noselect');
855                            });
856                            $(options.ownerDocument.body).on('mousemove.xdsoft_scroller', calcOffset);
857                        } else {
858                            touchStart = true;
859                            event.stopPropagation();
860                            event.preventDefault();
861                        }
862                    })
863                    .on('touchmove', function (event) {
864                        if (touchStart) {
865                            event.preventDefault();
866                            calcOffset(event);
867                        }
868                    })
869                    .on('touchend touchcancel', function () {
870                        touchStart =  false;
871                        startTopScroll = 0;
872                    });
873
874                timeboxparent
875                    .on('scroll_element.xdsoft_scroller', function (event, percentage) {
876                        if (!parentHeight) {
877                            timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percentage, true]);
878                        }
879                        percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN(percentage)) ? 0 : percentage;
880
881                        scroller.css('margin-top', maximumOffset * percentage);
882
883                        setTimeout(function () {
884                            timebox.css('marginTop', -parseInt((timebox[0].offsetHeight - parentHeight) * percentage, 10));
885                        }, 10);
886                    })
887                    .on('resize_scroll.xdsoft_scroller', function (event, percentage, noTriggerScroll) {
888                        var percent, sh;
889                        parentHeight = timeboxparent[0].clientHeight;
890                        height = timebox[0].offsetHeight;
891                        percent = parentHeight / height;
892                        sh = percent * scrollbar[0].offsetHeight;
893                        if (percent > 1) {
894                            scroller.hide();
895                        } else {
896                            scroller.show();
897                            scroller.css('height', parseInt(sh > 10 ? sh : 10, 10));
898                            maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight;
899                            if (noTriggerScroll !== true) {
900                                timeboxparent.trigger('scroll_element.xdsoft_scroller', [percentage || Math.abs(parseInt(timebox.css('marginTop'), 10)) / (height - parentHeight)]);
901                            }
902                        }
903                    });
904
905                timeboxparent.on('mousewheel', function (event) {
906                    var top = Math.abs(parseInt(timebox.css('marginTop'), 10));
907
908                    top = top - (event.deltaY * 20);
909                    if (top < 0) {
910                        top = 0;
911                    }
912
913                    timeboxparent.trigger('scroll_element.xdsoft_scroller', [top / (height - parentHeight)]);
914                    event.stopPropagation();
915                    return false;
916                });
917
918                timeboxparent.on('touchstart', function (event) {
919                    start = pointerEventToXY(event);
920                    startTop = Math.abs(parseInt(timebox.css('marginTop'), 10));
921                });
922
923                timeboxparent.on('touchmove', function (event) {
924                    if (start) {
925                        event.preventDefault();
926                        var coord = pointerEventToXY(event);
927                        timeboxparent.trigger('scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)]);
928                    }
929                });
930
931                timeboxparent.on('touchend touchcancel', function () {
932                    start = false;
933                    startTop = 0;
934                });
935            }
936            timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
937        });
938    };
939
940    $.fn.fat_datetimepicker = function (opt, opt2) {
941        var result = this,
942            KEY0 = 48,
943            KEY9 = 57,
944            _KEY0 = 96,
945            _KEY9 = 105,
946            CTRLKEY = 17,
947            CMDKEY = 91,
948            DEL = 46,
949            ENTER = 13,
950            ESC = 27,
951            BACKSPACE = 8,
952            ARROWLEFT = 37,
953            ARROWUP = 38,
954            ARROWRIGHT = 39,
955            ARROWDOWN = 40,
956            TAB = 9,
957            F5 = 116,
958            AKEY = 65,
959            CKEY = 67,
960            VKEY = 86,
961            ZKEY = 90,
962            YKEY = 89,
963            ctrlDown	=	false,
964            cmdDown = false,
965            options = ($.isPlainObject(opt) || !opt) ? $.extend(true, {}, default_options, opt) : $.extend(true, {}, default_options),
966
967            lazyInitTimer = 0,
968            createDateTimePicker,
969            destroyDateTimePicker,
970
971            lazyInit = function (input) {
972                input
973                    .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function initOnActionCallback() {
974                        if (input.is(':disabled') || input.data('xdsoft_datetimepicker')) {
975                            return;
976                        }
977                        clearTimeout(lazyInitTimer);
978                        lazyInitTimer = setTimeout(function () {
979
980                            if (!input.data('xdsoft_datetimepicker')) {
981                                createDateTimePicker(input);
982                            }
983                            input
984                                .off('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', initOnActionCallback)
985                                .trigger('open.xdsoft');
986                        }, 100);
987                    });
988            };
989
990        createDateTimePicker = function (input) {
991            var datetimepicker = $('<div class="xdsoft_datetimepicker xdsoft_noselect"></div>'),
992                xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),
993                datepicker = $('<div class="xdsoft_datepicker active"></div>'),
994                month_picker = $('<div class="xdsoft_monthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' +
995                    '<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' +
996                    '<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' +
997                    '<button type="button" class="xdsoft_next"></button></div>'),
998                calendar = $('<div class="xdsoft_calendar"></div>'),
999                timepicker = $('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'),
1000                timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
1001                timebox = $('<div class="xdsoft_time_variant"></div>'),
1002                applyButton = $('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'),
1003
1004                monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
1005                yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),
1006                triggerAfterOpen = false,
1007                XDSoft_datetime,
1008
1009                xchangeTimer,
1010                timerclick,
1011                current_time_index,
1012                setPos,
1013                timer = 0,
1014                _xdsoft_datetime,
1015                forEachAncestorOf;
1016
1017            if (options.id) {
1018                datetimepicker.attr('id', options.id);
1019            }
1020            if (options.style) {
1021                datetimepicker.attr('style', options.style);
1022            }
1023            if (options.weeks) {
1024                datetimepicker.addClass('xdsoft_showweeks');
1025            }
1026            if (options.rtl) {
1027                datetimepicker.addClass('xdsoft_rtl');
1028            }
1029
1030            datetimepicker.addClass('xdsoft_' + options.theme);
1031            datetimepicker.addClass(options.className);
1032
1033            month_picker
1034                .find('.xdsoft_month span')
1035                .after(monthselect);
1036            month_picker
1037                .find('.xdsoft_year span')
1038                .after(yearselect);
1039
1040            month_picker
1041                .find('.xdsoft_month,.xdsoft_year')
1042                .on('touchstart mousedown.xdsoft', function (event) {
1043                    var select = $(this).find('.xdsoft_select').eq(0),
1044                        val = 0,
1045                        top = 0,
1046                        visible = select.is(':visible'),
1047                        items,
1048                        i;
1049
1050                    month_picker
1051                        .find('.xdsoft_select')
1052                        .hide();
1053                    if (_xdsoft_datetime.currentTime) {
1054                        val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month') ? 'getMonth' : 'getFullYear']();
1055                    }
1056
1057                    select[visible ? 'hide' : 'show']();
1058                    for (items = select.find('div.xdsoft_option'), i = 0; i < items.length; i += 1) {
1059                        if (items.eq(i).data('value') === val) {
1060                            break;
1061                        } else {
1062                            top += items[0].offsetHeight;
1063                        }
1064                    }
1065
1066                    select.xdsoftScroller(options, top / (select.children()[0].offsetHeight - (select[0].clientHeight)));
1067                    event.stopPropagation();
1068                    return false;
1069                });
1070
1071            var handleTouchMoved = function (event) {
1072                var evt = event.originalEvent;
1073                var touchPosition = evt.touches ? evt.touches[0] : evt;
1074                this.touchStartPosition = this.touchStartPosition || touchPosition;
1075                var xMovement = Math.abs(this.touchStartPosition.clientX - touchPosition.clientX);
1076                var yMovement = Math.abs(this.touchStartPosition.clientY - touchPosition.clientY);
1077                var distance = Math.sqrt(xMovement * xMovement + yMovement * yMovement);
1078                if(distance > options.touchMovedThreshold) {
1079                    this.touchMoved = true;
1080                }
1081            }
1082
1083            month_picker
1084                .find('.xdsoft_select')
1085                .xdsoftScroller(options)
1086                .on('touchstart mousedown.xdsoft', function (event) {
1087                    var evt = event.originalEvent;
1088                    this.touchMoved = false;
1089                    this.touchStartPosition = evt.touches ? evt.touches[0] : evt;
1090                    event.stopPropagation();
1091                    event.preventDefault();
1092                })
1093                .on('touchmove', '.xdsoft_option', handleTouchMoved)
1094                .on('touchend mousedown.xdsoft', '.xdsoft_option', function () {
1095                    if (!this.touchMoved) {
1096                        if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
1097                            _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1098                        }
1099
1100                        var year = _xdsoft_datetime.currentTime.getFullYear();
1101                        if (_xdsoft_datetime && _xdsoft_datetime.currentTime) {
1102                            _xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect') ? 'setMonth' : 'setFullYear']($(this).data('value'));
1103                        }
1104
1105                        $(this).parent().parent().hide();
1106
1107                        datetimepicker.trigger('xchange.xdsoft');
1108                        if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
1109                            options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1110                        }
1111
1112                        if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
1113                            options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1114                        }
1115                    }
1116                });
1117
1118            datetimepicker.getValue = function () {
1119                return _xdsoft_datetime.getCurrentTime();
1120            };
1121
1122            datetimepicker.setOptions = function (_options) {
1123                var highlightedDates = {};
1124
1125                options = $.extend(true, {}, options, _options);
1126
1127                if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) {
1128                    options.allowTimes = $.extend(true, [], _options.allowTimes);
1129                }
1130
1131                if (_options.weekends && $.isArray(_options.weekends) && _options.weekends.length) {
1132                    options.weekends = $.extend(true, [], _options.weekends);
1133                }
1134
1135                if (_options.allowDates && $.isArray(_options.allowDates) && _options.allowDates.length) {
1136                    options.allowDates = $.extend(true, [], _options.allowDates);
1137                }
1138
1139                if (_options.allowDateRe && Object.prototype.toString.call(_options.allowDateRe)==="[object String]") {
1140                    options.allowDateRe = new RegExp(_options.allowDateRe);
1141                }
1142
1143                if (_options.highlightedDates && $.isArray(_options.highlightedDates) && _options.highlightedDates.length) {
1144                    $.each(_options.highlightedDates, function (index, value) {
1145                        var splitData = $.map(value.split(','), $.trim),
1146                            exDesc,
1147                            hDate = new HighlightedDate(dateHelper.parseDate(splitData[0], options.formatDate), splitData[1], splitData[2]), // date, desc, style
1148                            keyDate = dateHelper.formatDate(hDate.date, options.formatDate);
1149                        if (highlightedDates[keyDate] !== undefined) {
1150                            exDesc = highlightedDates[keyDate].desc;
1151                            if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
1152                                highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
1153                            }
1154                        } else {
1155                            highlightedDates[keyDate] = hDate;
1156                        }
1157                    });
1158
1159                    options.highlightedDates = $.extend(true, [], highlightedDates);
1160                }
1161
1162                if (_options.highlightedPeriods && $.isArray(_options.highlightedPeriods) && _options.highlightedPeriods.length) {
1163                    highlightedDates = $.extend(true, [], options.highlightedDates);
1164                    $.each(_options.highlightedPeriods, function (index, value) {
1165                        var dateTest, // start date
1166                            dateEnd,
1167                            desc,
1168                            hDate,
1169                            keyDate,
1170                            exDesc,
1171                            style;
1172                        if ($.isArray(value)) {
1173                            dateTest = value[0];
1174                            dateEnd = value[1];
1175                            desc = value[2];
1176                            style = value[3];
1177                        }
1178                        else {
1179                            var splitData = $.map(value.split(','), $.trim);
1180                            dateTest = dateHelper.parseDate(splitData[0], options.formatDate);
1181                            dateEnd = dateHelper.parseDate(splitData[1], options.formatDate);
1182                            desc = splitData[2];
1183                            style = splitData[3];
1184                        }
1185
1186                        while (dateTest <= dateEnd) {
1187                            hDate = new HighlightedDate(dateTest, desc, style);
1188                            keyDate = dateHelper.formatDate(dateTest, options.formatDate);
1189                            dateTest.setDate(dateTest.getDate() + 1);
1190                            if (highlightedDates[keyDate] !== undefined) {
1191                                exDesc = highlightedDates[keyDate].desc;
1192                                if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) {
1193                                    highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc;
1194                                }
1195                            } else {
1196                                highlightedDates[keyDate] = hDate;
1197                            }
1198                        }
1199                    });
1200
1201                    options.highlightedDates = $.extend(true, [], highlightedDates);
1202                }
1203
1204                if (_options.disabledDates && $.isArray(_options.disabledDates) && _options.disabledDates.length) {
1205                    options.disabledDates = $.extend(true, [], _options.disabledDates);
1206                }
1207
1208                if (_options.disabledWeekDays && $.isArray(_options.disabledWeekDays) && _options.disabledWeekDays.length) {
1209                    options.disabledWeekDays = $.extend(true, [], _options.disabledWeekDays);
1210                }
1211
1212                if ((options.open || options.opened) && (!options.inline)) {
1213                    input.trigger('open.xdsoft');
1214                }
1215
1216                if (options.inline) {
1217                    triggerAfterOpen = true;
1218                    datetimepicker.addClass('xdsoft_inline');
1219                    input.after(datetimepicker).hide();
1220                }
1221
1222                if (options.inverseButton) {
1223                    options.next = 'xdsoft_prev';
1224                    options.prev = 'xdsoft_next';
1225                }
1226
1227                if (options.datepicker) {
1228                    datepicker.addClass('active');
1229                } else {
1230                    datepicker.removeClass('active');
1231                }
1232
1233                if (options.timepicker) {
1234                    timepicker.addClass('active');
1235                } else {
1236                    timepicker.removeClass('active');
1237                }
1238
1239                if (options.value) {
1240                    _xdsoft_datetime.setCurrentTime(options.value);
1241                    if (input && input.val) {
1242                        input.val(_xdsoft_datetime.str);
1243                    }
1244                }
1245
1246                if (isNaN(options.dayOfWeekStart)) {
1247                    options.dayOfWeekStart = 0;
1248                } else {
1249                    options.dayOfWeekStart = parseInt(options.dayOfWeekStart, 10) % 7;
1250                }
1251
1252                if (!options.timepickerScrollbar) {
1253                    timeboxparent.xdsoftScroller(options, 'hide');
1254                }
1255
1256                if (options.minDate && /^[\+\-](.*)$/.test(options.minDate)) {
1257                    options.minDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.minDate), options.formatDate);
1258                }
1259
1260                if (options.maxDate &&  /^[\+\-](.*)$/.test(options.maxDate)) {
1261                    options.maxDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.maxDate), options.formatDate);
1262                }
1263
1264                if (options.minDateTime &&  /^\+(.*)$/.test(options.minDateTime)) {
1265                    options.minDateTime = _xdsoft_datetime.strToDateTime(options.minDateTime).dateFormat(options.formatDate);
1266                }
1267
1268                if (options.maxDateTime &&  /^\+(.*)$/.test(options.maxDateTime)) {
1269                    options.maxDateTime = _xdsoft_datetime.strToDateTime(options.maxDateTime).dateFormat(options.formatDate);
1270                }
1271
1272                applyButton.toggle(options.showApplyButton);
1273
1274                month_picker
1275                    .find('.xdsoft_today_button')
1276                    .css('visibility', !options.todayButton ? 'hidden' : 'visible');
1277
1278                month_picker
1279                    .find('.' + options.prev)
1280                    .css('visibility', !options.prevButton ? 'hidden' : 'visible');
1281
1282                month_picker
1283                    .find('.' + options.next)
1284                    .css('visibility', !options.nextButton ? 'hidden' : 'visible');
1285
1286                setMask(options);
1287
1288                if (options.validateOnBlur) {
1289                    input
1290                        .off('blur.xdsoft')
1291                        .on('blur.xdsoft', function () {
1292                            if (options.allowBlank && (!$.trim($(this).val()).length ||
1293                                (typeof options.mask === "string" && $.trim($(this).val()) === options.mask.replace(/[0-9]/g, '_')))) {
1294                                $(this).val(null);
1295                                datetimepicker.data('xdsoft_datetime').empty();
1296                            } else {
1297                                var d = dateHelper.parseDate($(this).val(), options.format);
1298                                if (d) { // parseDate() may skip some invalid parts like date or time, so make it clear for user: show parsed date/time
1299                                    $(this).val(dateHelper.formatDate(d, options.format));
1300                                } else {
1301                                    var splittedHours   = +([$(this).val()[0], $(this).val()[1]].join('')),
1302                                        splittedMinutes = +([$(this).val()[2], $(this).val()[3]].join(''));
1303
1304                                    // parse the numbers as 0312 => 03:12
1305                                    if (!options.datepicker && options.timepicker && splittedHours >= 0 && splittedHours < 24 && splittedMinutes >= 0 && splittedMinutes < 60) {
1306                                        $(this).val([splittedHours, splittedMinutes].map(function (item) {
1307                                            return item > 9 ? item : '0' + item;
1308                                        }).join(':'));
1309                                    } else {
1310                                        $(this).val(dateHelper.formatDate(_xdsoft_datetime.now(), options.format));
1311                                    }
1312                                }
1313                                datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
1314                            }
1315
1316                            datetimepicker.trigger('changedatetime.xdsoft');
1317                            datetimepicker.trigger('close.xdsoft');
1318                        });
1319                }
1320                options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
1321
1322                datetimepicker
1323                    .trigger('xchange.xdsoft')
1324                    .trigger('afterOpen.xdsoft');
1325            };
1326
1327            datetimepicker
1328                .data('options', options)
1329                .on('touchstart mousedown.xdsoft', function (event) {
1330                    event.stopPropagation();
1331                    event.preventDefault();
1332                    yearselect.hide();
1333                    monthselect.hide();
1334                    return false;
1335                });
1336
1337            //scroll_element = timepicker.find('.xdsoft_time_box');
1338            timeboxparent.append(timebox);
1339            timeboxparent.xdsoftScroller(options);
1340
1341            datetimepicker.on('afterOpen.xdsoft', function () {
1342                timeboxparent.xdsoftScroller(options);
1343            });
1344
1345            datetimepicker
1346                .append(datepicker)
1347                .append(timepicker);
1348
1349            if (options.withoutCopyright !== true) {
1350                datetimepicker
1351                    .append(xdsoft_copyright);
1352            }
1353
1354            datepicker
1355                .append(month_picker)
1356                .append(calendar)
1357                .append(applyButton);
1358
1359            if (options.insideParent) {
1360                $(input).parent().append(datetimepicker);
1361            } else {
1362                $(options.parentID).append(datetimepicker);
1363            }
1364
1365            XDSoft_datetime = function () {
1366                var _this = this;
1367                _this.now = function (norecursion) {
1368                    var d = new Date(),
1369                        date,
1370                        time;
1371
1372                    if (!norecursion && options.defaultDate) {
1373                        date = _this.strToDateTime(options.defaultDate);
1374                        d.setFullYear(date.getFullYear());
1375                        d.setMonth(date.getMonth());
1376                        d.setDate(date.getDate());
1377                    }
1378
1379                    d.setFullYear(d.getFullYear());
1380
1381                    if (!norecursion && options.defaultTime) {
1382                        time = _this.strtotime(options.defaultTime);
1383                        d.setHours(time.getHours());
1384                        d.setMinutes(time.getMinutes());
1385                        d.setSeconds(time.getSeconds());
1386                        d.setMilliseconds(time.getMilliseconds());
1387                    }
1388                    return d;
1389                };
1390
1391                _this.isValidDate = function (d) {
1392                    if (Object.prototype.toString.call(d) !== "[object Date]") {
1393                        return false;
1394                    }
1395                    return !isNaN(d.getTime());
1396                };
1397
1398                _this.setCurrentTime = function (dTime, requireValidDate) {
1399                    if (typeof dTime === 'string') {
1400                        _this.currentTime = _this.strToDateTime(dTime);
1401                    }
1402                    else if (_this.isValidDate(dTime)) {
1403                        _this.currentTime = dTime;
1404                    }
1405                    else if (!dTime && !requireValidDate && options.allowBlank && !options.inline) {
1406                        _this.currentTime = null;
1407                    }
1408                    else {
1409                        _this.currentTime = _this.now();
1410                    }
1411
1412                    datetimepicker.trigger('xchange.xdsoft');
1413                };
1414
1415                _this.empty = function () {
1416                    _this.currentTime = null;
1417                };
1418
1419                _this.getCurrentTime = function () {
1420                    return _this.currentTime;
1421                };
1422
1423                _this.nextMonth = function () {
1424
1425                    if (_this.currentTime === undefined || _this.currentTime === null) {
1426                        _this.currentTime = _this.now();
1427                    }
1428
1429                    var month = _this.currentTime.getMonth() + 1,
1430                        year;
1431                    if (month === 12) {
1432                        _this.currentTime.setFullYear(_this.currentTime.getFullYear() + 1);
1433                        month = 0;
1434                    }
1435
1436                    year = _this.currentTime.getFullYear();
1437
1438                    _this.currentTime.setDate(
1439                        Math.min(
1440                            new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
1441                            _this.currentTime.getDate()
1442                        )
1443                    );
1444                    _this.currentTime.setMonth(month);
1445
1446                    if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
1447                        options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1448                    }
1449
1450                    if (year !== _this.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
1451                        options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1452                    }
1453
1454                    datetimepicker.trigger('xchange.xdsoft');
1455                    return month;
1456                };
1457
1458                _this.prevMonth = function () {
1459
1460                    if (_this.currentTime === undefined || _this.currentTime === null) {
1461                        _this.currentTime = _this.now();
1462                    }
1463
1464                    var month = _this.currentTime.getMonth() - 1;
1465                    if (month === -1) {
1466                        _this.currentTime.setFullYear(_this.currentTime.getFullYear() - 1);
1467                        month = 11;
1468                    }
1469                    _this.currentTime.setDate(
1470                        Math.min(
1471                            new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
1472                            _this.currentTime.getDate()
1473                        )
1474                    );
1475                    _this.currentTime.setMonth(month);
1476                    if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
1477                        options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
1478                    }
1479                    datetimepicker.trigger('xchange.xdsoft');
1480                    return month;
1481                };
1482
1483                _this.getWeekOfYear = function (datetime) {
1484                    if (options.onGetWeekOfYear && $.isFunction(options.onGetWeekOfYear)) {
1485                        var week = options.onGetWeekOfYear.call(datetimepicker, datetime);
1486                        if (typeof week !== 'undefined') {
1487                            return week;
1488                        }
1489                    }
1490                    var onejan = new Date(datetime.getFullYear(), 0, 1);
1491
1492                    //First week of the year is th one with the first Thursday according to ISO8601
1493                    if (onejan.getDay() !== 4) {
1494                        onejan.setMonth(0, 1 + ((4 - onejan.getDay()+ 7) % 7));
1495                    }
1496
1497                    return Math.ceil((((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7);
1498                };
1499
1500                _this.strToDateTime = function (sDateTime) {
1501                    var tmpDate = [], timeOffset, currentTime;
1502
1503                    if (sDateTime && sDateTime instanceof Date && _this.isValidDate(sDateTime)) {
1504                        return sDateTime;
1505                    }
1506
1507                    tmpDate = /^([+-]{1})(.*)$/.exec(sDateTime);
1508
1509                    if (tmpDate) {
1510                        tmpDate[2] = dateHelper.parseDate(tmpDate[2], options.formatDate);
1511                    }
1512
1513                    if (tmpDate  && tmpDate[2]) {
1514                        timeOffset = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000;
1515                        currentTime = new Date((_this.now(true)).getTime() + parseInt(tmpDate[1] + '1', 10) * timeOffset);
1516                    } else {
1517                        currentTime = sDateTime ? dateHelper.parseDate(sDateTime, options.format) : _this.now();
1518                    }
1519
1520                    if (!_this.isValidDate(currentTime)) {
1521                        currentTime = _this.now();
1522                    }
1523
1524                    return currentTime;
1525                };
1526
1527                _this.strToDate = function (sDate) {
1528                    if (sDate && sDate instanceof Date && _this.isValidDate(sDate)) {
1529                        return sDate;
1530                    }
1531
1532                    var currentTime = sDate ? dateHelper.parseDate(sDate, options.formatDate) : _this.now(true);
1533                    if (!_this.isValidDate(currentTime)) {
1534                        currentTime = _this.now(true);
1535                    }
1536                    return currentTime;
1537                };
1538
1539                _this.strtotime = function (sTime) {
1540                    if (sTime && sTime instanceof Date && _this.isValidDate(sTime)) {
1541                        return sTime;
1542                    }
1543                    var currentTime = sTime ? dateHelper.parseDate(sTime, options.formatTime) : _this.now(true);
1544                    if (!_this.isValidDate(currentTime)) {
1545                        currentTime = _this.now(true);
1546                    }
1547                    return currentTime;
1548                };
1549
1550                _this.str = function () {
1551                    var format = options.format;
1552                    if (options.yearOffset) {
1553                        format = format.replace('Y', _this.currentTime.getFullYear() + options.yearOffset);
1554                        format = format.replace('y', String(_this.currentTime.getFullYear() + options.yearOffset).substring(2, 4));
1555                    }
1556                    return dateHelper.formatDate(_this.currentTime, format);
1557                };
1558                _this.currentTime = this.now();
1559            };
1560
1561            _xdsoft_datetime = new XDSoft_datetime();
1562
1563            applyButton.on('touchend click', function (e) {//pathbrite
1564                e.preventDefault();
1565                datetimepicker.data('changed', true);
1566                _xdsoft_datetime.setCurrentTime(getCurrentValue());
1567                input.val(_xdsoft_datetime.str());
1568                datetimepicker.trigger('close.xdsoft');
1569            });
1570            month_picker
1571                .find('.xdsoft_today_button')
1572                .on('touchend mousedown.xdsoft', function () {
1573                    datetimepicker.data('changed', true);
1574                    _xdsoft_datetime.setCurrentTime(0, true);
1575                    datetimepicker.trigger('afterOpen.xdsoft');
1576                }).on('dblclick.xdsoft', function () {
1577                var currentDate = _xdsoft_datetime.getCurrentTime(), minDate, maxDate;
1578                currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
1579                minDate = _xdsoft_datetime.strToDate(options.minDate);
1580                minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
1581                if (currentDate < minDate) {
1582                    return;
1583                }
1584                maxDate = _xdsoft_datetime.strToDate(options.maxDate);
1585                maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate());
1586                if (currentDate > maxDate) {
1587                    return;
1588                }
1589                input.val(_xdsoft_datetime.str());
1590                input.trigger('change');
1591                datetimepicker.trigger('close.xdsoft');
1592            });
1593            month_picker
1594                .find('.xdsoft_prev,.xdsoft_next')
1595                .on('touchend mousedown.xdsoft', function () {
1596                    var $this = $(this),
1597                        timer = 0,
1598                        stop = false;
1599
1600                    (function arguments_callee1(v) {
1601                        if ($this.hasClass(options.next)) {
1602                            _xdsoft_datetime.nextMonth();
1603                        } else if ($this.hasClass(options.prev)) {
1604                            _xdsoft_datetime.prevMonth();
1605                        }
1606                        if (options.monthChangeSpinner) {
1607                            if (!stop) {
1608                                timer = setTimeout(arguments_callee1, v || 100);
1609                            }
1610                        }
1611                    }(500));
1612
1613                    $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft', function arguments_callee2() {
1614                        clearTimeout(timer);
1615                        stop = true;
1616                        $([options.ownerDocument.body, options.contentWindow]).off('touchend mouseup.xdsoft', arguments_callee2);
1617                    });
1618                });
1619
1620            timepicker
1621                .find('.xdsoft_prev,.xdsoft_next')
1622                .on('touchend mousedown.xdsoft', function () {
1623                    var $this = $(this),
1624                        timer = 0,
1625                        stop = false,
1626                        period = 110;
1627                    (function arguments_callee4(v) {
1628                        var pheight = timeboxparent[0].clientHeight,
1629                            height = timebox[0].offsetHeight,
1630                            top = Math.abs(parseInt(timebox.css('marginTop'), 10));
1631                        if ($this.hasClass(options.next) && (height - pheight) - options.timeHeightInTimePicker >= top) {
1632                            timebox.css('marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px');
1633                        } else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) {
1634                            timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px');
1635                        }
1636                        /**
1637                         * Fixed bug:
1638                         * When using css3 transition, it will cause a bug that you cannot scroll the timepicker list.
1639                         * The reason is that the transition-duration time, if you set it to 0, all things fine, otherwise, this
1640                         * would cause a bug when you use jquery.css method.
1641                         * Let's say: * { transition: all .5s ease; }
1642                         * jquery timebox.css('marginTop') will return the original value which is before you clicking the next/prev button,
1643                         * meanwhile the timebox[0].style.marginTop will return the right value which is after you clicking the
1644                         * next/prev button.
1645                         *
1646                         * What we should do:
1647                         * Replace timebox.css('marginTop') with timebox[0].style.marginTop.
1648                         */
1649                        timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox[0].style.marginTop, 10) / (height - pheight))]);
1650                        period = (period > 10) ? 10 : period - 10;
1651                        if (!stop) {
1652                            timer = setTimeout(arguments_callee4, v || period);
1653                        }
1654                    }(500));
1655                    $([options.ownerDocument.body, options.contentWindow]).on('touchend mouseup.xdsoft', function arguments_callee5() {
1656                        clearTimeout(timer);
1657                        stop = true;
1658                        $([options.ownerDocument.body, options.contentWindow])
1659                            .off('touchend mouseup.xdsoft', arguments_callee5);
1660                    });
1661                });
1662
1663            xchangeTimer = 0;
1664            // base handler - generating a calendar and timepicker
1665            datetimepicker
1666                .on('xchange.xdsoft', function (event) {
1667                    clearTimeout(xchangeTimer);
1668                    xchangeTimer = setTimeout(function () {
1669
1670                        if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
1671                            _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1672                        }
1673
1674                        var table =	'',
1675                            start = new Date(_xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0),
1676                            i = 0,
1677                            j,
1678                            today = _xdsoft_datetime.now(),
1679                            maxDate = false,
1680                            minDate = false,
1681                            minDateTime = false,
1682                            maxDateTime = false,
1683                            hDate,
1684                            day,
1685                            d,
1686                            y,
1687                            m,
1688                            w,
1689                            classes = [],
1690                            customDateSettings,
1691                            newRow = true,
1692                            time = '',
1693                            h,
1694                            line_time,
1695                            description;
1696
1697                        while (start.getDay() !== options.dayOfWeekStart) {
1698                            start.setDate(start.getDate() - 1);
1699                        }
1700
1701                        table += '<table><thead><tr>';
1702
1703                        if (options.weeks) {
1704                            table += '<th></th>';
1705                        }
1706
1707                        for (j = 0; j < 7; j += 1) {
1708                            table += '<th>' + options.i18n[globalLocale].dayOfWeekShort[(j + options.dayOfWeekStart) % 7] + '</th>';
1709                        }
1710
1711                        table += '</tr></thead>';
1712                        table += '<tbody>';
1713
1714                        if (options.maxDate !== false) {
1715                            maxDate = _xdsoft_datetime.strToDate(options.maxDate);
1716                            maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999);
1717                        }
1718
1719                        if (options.minDate !== false) {
1720                            minDate = _xdsoft_datetime.strToDate(options.minDate);
1721                            minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
1722                        }
1723
1724                        if (options.minDateTime !== false) {
1725                            minDateTime = _xdsoft_datetime.strToDate(options.minDateTime);
1726                            minDateTime = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), minDateTime.getHours(), minDateTime.getMinutes(), minDateTime.getSeconds());
1727                        }
1728
1729                        if (options.maxDateTime !== false) {
1730                            maxDateTime = _xdsoft_datetime.strToDate(options.maxDateTime);
1731                            maxDateTime = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), maxDateTime.getHours(), maxDateTime.getMinutes(), maxDateTime.getSeconds());
1732                        }
1733
1734                        var maxDateTimeDay;
1735                        if (maxDateTime !== false) {
1736                            maxDateTimeDay = ((maxDateTime.getFullYear() * 12) + maxDateTime.getMonth()) * 31 + maxDateTime.getDate();
1737                        }
1738
1739                        while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) {
1740                            classes = [];
1741                            i += 1;
1742
1743                            day = start.getDay();
1744                            d = start.getDate();
1745                            y = start.getFullYear();
1746                            m = start.getMonth();
1747                            w = _xdsoft_datetime.getWeekOfYear(start);
1748                            description = '';
1749
1750                            classes.push('xdsoft_date');
1751
1752                            if (options.beforeShowDay && $.isFunction(options.beforeShowDay.call)) {
1753                                customDateSettings = options.beforeShowDay.call(datetimepicker, start);
1754                            } else {
1755                                customDateSettings = null;
1756                            }
1757
1758                            if(options.allowDateRe && Object.prototype.toString.call(options.allowDateRe) === "[object RegExp]"){
1759                                if(!options.allowDateRe.test(dateHelper.formatDate(start, options.formatDate))){
1760                                    classes.push('xdsoft_disabled');
1761                                }
1762                            }
1763
1764                            if(options.allowDates && options.allowDates.length>0){
1765                                if(options.allowDates.indexOf(dateHelper.formatDate(start, options.formatDate)) === -1){
1766                                    classes.push('xdsoft_disabled');
1767                                }
1768                            }
1769
1770                            var currentDay = ((start.getFullYear() * 12) + start.getMonth()) * 31 + start.getDate();
1771                            if ((maxDate !== false && start > maxDate) || (minDateTime !== false && start < minDateTime)  || (minDate !== false && start < minDate) || (maxDateTime !== false && currentDay > maxDateTimeDay) || (customDateSettings && customDateSettings[0] === false)) {
1772                                classes.push('xdsoft_disabled');
1773                            }
1774
1775                            if (options.disabledDates.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
1776                                classes.push('xdsoft_disabled');
1777                            }
1778
1779                            if (options.disabledWeekDays.indexOf(day) !== -1) {
1780                                classes.push('xdsoft_disabled');
1781                            }
1782
1783                            if (input.is('[disabled]')) {
1784                                classes.push('xdsoft_disabled');
1785                            }
1786
1787                            if (customDateSettings && customDateSettings[1] !== "") {
1788                                classes.push(customDateSettings[1]);
1789                            }
1790
1791                            if (_xdsoft_datetime.currentTime.getMonth() !== m) {
1792                                classes.push('xdsoft_other_month');
1793                            }
1794
1795                            if ((options.defaultSelect || datetimepicker.data('changed')) && dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
1796                                classes.push('xdsoft_current');
1797                            }
1798
1799                            if (dateHelper.formatDate(today, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) {
1800                                classes.push('xdsoft_today');
1801                            }
1802
1803                            if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
1804                                classes.push('xdsoft_weekend');
1805                            }
1806
1807                            if (options.highlightedDates[dateHelper.formatDate(start, options.formatDate)] !== undefined) {
1808                                hDate = options.highlightedDates[dateHelper.formatDate(start, options.formatDate)];
1809                                classes.push(hDate.style === undefined ? 'xdsoft_highlighted_default' : hDate.style);
1810                                description = hDate.desc === undefined ? '' : hDate.desc;
1811                            }
1812
1813                            if (options.beforeShowDay && $.isFunction(options.beforeShowDay)) {
1814                                classes.push(options.beforeShowDay(start));
1815                            }
1816
1817                            if (newRow) {
1818                                table += '<tr>';
1819                                newRow = false;
1820                                if (options.weeks) {
1821                                    table += '<th>' + w + '</th>';
1822                                }
1823                            }
1824
1825                            table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join(' ') + '" title="' + description + '">' +
1826                                '<div>' + d + '</div>' +
1827                                '</td>';
1828
1829                            if (start.getDay() === options.dayOfWeekStartPrev) {
1830                                table += '</tr>';
1831                                newRow = true;
1832                            }
1833
1834                            start.setDate(d + 1);
1835                        }
1836                        table += '</tbody></table>';
1837
1838                        calendar.html(table);
1839
1840                        month_picker.find('.xdsoft_label span').eq(0).text(options.i18n[globalLocale].months[_xdsoft_datetime.currentTime.getMonth()]);
1841                        month_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear() + options.yearOffset);
1842
1843                        // generate timebox
1844                        time = '';
1845                        h = '';
1846                        m = '';
1847
1848                        var minTimeMinutesOfDay = 0;
1849                        if (options.minTime !== false) {
1850                            var t = _xdsoft_datetime.strtotime(options.minTime);
1851                            minTimeMinutesOfDay = 60 * t.getHours() + t.getMinutes();
1852                        }
1853                        var maxTimeMinutesOfDay = 24 * 60;
1854                        if (options.maxTime !== false) {
1855                            var t = _xdsoft_datetime.strtotime(options.maxTime);
1856                            maxTimeMinutesOfDay = 60 * t.getHours() + t.getMinutes();
1857                        }
1858
1859                        if (options.minDateTime !== false) {
1860                            var t = _xdsoft_datetime.strToDateTime(options.minDateTime);
1861                            var currentDayIsMinDateTimeDay = dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(t, options.formatDate);
1862                            if (currentDayIsMinDateTimeDay) {
1863                                var m = 60 * t.getHours() + t.getMinutes();
1864                                if (m > minTimeMinutesOfDay) minTimeMinutesOfDay = m;
1865                            }
1866                        }
1867
1868                        if (options.maxDateTime !== false) {
1869                            var t = _xdsoft_datetime.strToDateTime(options.maxDateTime);
1870                            var currentDayIsMaxDateTimeDay = dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(t, options.formatDate);
1871                            if (currentDayIsMaxDateTimeDay) {
1872                                var m = 60 * t.getHours() + t.getMinutes();
1873                                if (m < maxTimeMinutesOfDay) maxTimeMinutesOfDay = m;
1874                            }
1875                        }
1876
1877                        line_time = function line_time(h, m) {
1878                            var now = _xdsoft_datetime.now(), current_time,
1879                                isALlowTimesInit = options.allowTimes && $.isArray(options.allowTimes) && options.allowTimes.length;
1880                            now.setHours(h);
1881                            h = parseInt(now.getHours(), 10);
1882                            now.setMinutes(m);
1883                            m = parseInt(now.getMinutes(), 10);
1884                            classes = [];
1885                            var currentMinutesOfDay = 60 * h + m;
1886                            if (input.is('[disabled]') || (currentMinutesOfDay >= maxTimeMinutesOfDay) || (currentMinutesOfDay < minTimeMinutesOfDay)) {
1887                                classes.push('xdsoft_disabled');
1888                            }
1889
1890                            current_time = new Date(_xdsoft_datetime.currentTime);
1891                            current_time.setHours(parseInt(_xdsoft_datetime.currentTime.getHours(), 10));
1892
1893                            if (!isALlowTimesInit) {
1894                                current_time.setMinutes(Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes() / options.step) * options.step);
1895                            }
1896
1897                            if ((options.initTime || options.defaultSelect || datetimepicker.data('changed')) && current_time.getHours() === parseInt(h, 10) && ((!isALlowTimesInit && options.step > 59) || current_time.getMinutes() === parseInt(m, 10))) {
1898                                if (options.defaultSelect || datetimepicker.data('changed')) {
1899                                    classes.push('xdsoft_current');
1900                                } else if (options.initTime) {
1901                                    classes.push('xdsoft_init_time');
1902                                }
1903                            }
1904                            if (parseInt(today.getHours(), 10) === parseInt(h, 10) && parseInt(today.getMinutes(), 10) === parseInt(m, 10)) {
1905                                classes.push('xdsoft_today');
1906                            }
1907                            time += '<div class="xdsoft_time ' + classes.join(' ') + '" data-hour="' + h + '" data-minute="' + m + '">' + dateHelper.formatDate(now, options.formatTime) + '</div>';
1908                        };
1909
1910                        if (!options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length) {
1911                            for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) {
1912                                for (j = 0; j < 60; j += options.step) {
1913                                    var currentMinutesOfDay = i * 60 + j;
1914                                    if (currentMinutesOfDay < minTimeMinutesOfDay) continue;
1915                                    if (currentMinutesOfDay >= maxTimeMinutesOfDay) continue;
1916                                    h = (i < 10 ? '0' : '') + i;
1917                                    m = (j < 10 ? '0' : '') + j;
1918                                    line_time(h, m);
1919                                }
1920                            }
1921                        } else {
1922                            for (i = 0; i < options.allowTimes.length; i += 1) {
1923                                h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours();
1924                                m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes();
1925                                line_time(h, m);
1926                            }
1927                        }
1928
1929                        timebox.html(time);
1930
1931                        opt = '';
1932
1933                        for (i = parseInt(options.yearStart, 10); i <= parseInt(options.yearEnd, 10); i += 1) {
1934                            opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + (i + options.yearOffset) + '</div>';
1935                        }
1936                        yearselect.children().eq(0)
1937                            .html(opt);
1938
1939                        for (i = parseInt(options.monthStart, 10), opt = ''; i <= parseInt(options.monthEnd, 10); i += 1) {
1940                            opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[globalLocale].months[i] + '</div>';
1941                        }
1942                        monthselect.children().eq(0).html(opt);
1943                        $(datetimepicker)
1944                            .trigger('generate.xdsoft');
1945                    }, 10);
1946                    event.stopPropagation();
1947                })
1948                .on('afterOpen.xdsoft', function () {
1949                    if (options.timepicker) {
1950                        var classType, pheight, height, top;
1951                        if (timebox.find('.xdsoft_current').length) {
1952                            classType = '.xdsoft_current';
1953                        } else if (timebox.find('.xdsoft_init_time').length) {
1954                            classType = '.xdsoft_init_time';
1955                        }
1956                        if (classType) {
1957                            pheight = timeboxparent[0].clientHeight;
1958                            height = timebox[0].offsetHeight;
1959                            top = timebox.find(classType).index() * options.timeHeightInTimePicker + 1;
1960                            if ((height - pheight) < top) {
1961                                top = height - pheight;
1962                            }
1963                            timeboxparent.trigger('scroll_element.xdsoft_scroller', [parseInt(top, 10) / (height - pheight)]);
1964                        } else {
1965                            timeboxparent.trigger('scroll_element.xdsoft_scroller', [0]);
1966                        }
1967                    }
1968                });
1969
1970            timerclick = 0;
1971            calendar
1972                .on('touchend click.xdsoft', 'td', function (xdevent) {
1973                    xdevent.stopPropagation();  // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
1974                    timerclick += 1;
1975                    var $this = $(this),
1976                        currentTime = _xdsoft_datetime.currentTime;
1977
1978                    if (currentTime === undefined || currentTime === null) {
1979                        _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1980                        currentTime = _xdsoft_datetime.currentTime;
1981                    }
1982
1983                    if ($this.hasClass('xdsoft_disabled')) {
1984                        return false;
1985                    }
1986
1987                    currentTime.setDate(1);
1988                    currentTime.setFullYear($this.data('year'));
1989                    currentTime.setMonth($this.data('month'));
1990                    currentTime.setDate($this.data('date'));
1991
1992                    datetimepicker.trigger('select.xdsoft', [currentTime]);
1993
1994                    input.val(_xdsoft_datetime.str());
1995
1996                    if (options.onSelectDate &&	$.isFunction(options.onSelectDate)) {
1997                        options.onSelectDate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
1998                    }
1999
2000                    datetimepicker.data('changed', true);
2001                    datetimepicker.trigger('xchange.xdsoft');
2002                    datetimepicker.trigger('changedatetime.xdsoft');
2003                    if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === false && !options.timepicker))) && !options.inline) {
2004                        datetimepicker.trigger('close.xdsoft');
2005                    }
2006                    setTimeout(function () {
2007                        timerclick = 0;
2008                    }, 200);
2009                });
2010
2011            timebox
2012                .on('touchstart', 'div', function (xdevent) {
2013                    this.touchMoved = false;
2014                })
2015                .on('touchmove', 'div', handleTouchMoved)
2016                .on('touchend click.xdsoft', 'div', function (xdevent) {
2017                    if (!this.touchMoved) {
2018                        xdevent.stopPropagation();
2019                        var $this = $(this),
2020                            currentTime = _xdsoft_datetime.currentTime;
2021
2022                        if (currentTime === undefined || currentTime === null) {
2023                            _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
2024                            currentTime = _xdsoft_datetime.currentTime;
2025                        }
2026
2027                        if ($this.hasClass('xdsoft_disabled')) {
2028                            return false;
2029                        }
2030                        currentTime.setHours($this.data('hour'));
2031                        currentTime.setMinutes($this.data('minute'));
2032                        datetimepicker.trigger('select.xdsoft', [currentTime]);
2033
2034                        datetimepicker.data('input').val(_xdsoft_datetime.str());
2035
2036                        if (options.onSelectTime && $.isFunction(options.onSelectTime)) {
2037                            options.onSelectTime.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
2038                        }
2039                        datetimepicker.data('changed', true);
2040                        datetimepicker.trigger('xchange.xdsoft');
2041                        datetimepicker.trigger('changedatetime.xdsoft');
2042                        if (options.inline !== true && options.closeOnTimeSelect === true) {
2043                            datetimepicker.trigger('close.xdsoft');
2044                        }
2045                    }
2046                });
2047
2048            datepicker
2049                .on('mousewheel.xdsoft', function (event) {
2050                    if (!options.scrollMonth) {
2051                        return true;
2052                    }
2053                    if (event.deltaY < 0) {
2054                        _xdsoft_datetime.nextMonth();
2055                    } else {
2056                        _xdsoft_datetime.prevMonth();
2057                    }
2058                    return false;
2059                });
2060
2061            input
2062                .on('mousewheel.xdsoft', function (event) {
2063                    if (!options.scrollInput) {
2064                        return true;
2065                    }
2066                    if (!options.datepicker && options.timepicker) {
2067                        current_time_index = timebox.find('.xdsoft_current').length ? timebox.find('.xdsoft_current').eq(0).index() : 0;
2068                        if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) {
2069                            current_time_index += event.deltaY;
2070                        }
2071                        if (timebox.children().eq(current_time_index).length) {
2072                            timebox.children().eq(current_time_index).trigger('mousedown');
2073                        }
2074                        return false;
2075                    }
2076                    if (options.datepicker && !options.timepicker) {
2077                        datepicker.trigger(event, [event.deltaY, event.deltaX, event.deltaY]);
2078                        if (input.val) {
2079                            input.val(_xdsoft_datetime.str());
2080                        }
2081                        datetimepicker.trigger('changedatetime.xdsoft');
2082                        return false;
2083                    }
2084                });
2085
2086            datetimepicker
2087                .on('changedatetime.xdsoft', function (event) {
2088                    if (options.onChangeDateTime && $.isFunction(options.onChangeDateTime)) {
2089                        var $input = datetimepicker.data('input');
2090                        options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input, event);
2091                        delete options.value;
2092                        $input.trigger('change');
2093                    }
2094                })
2095                .on('generate.xdsoft', function () {
2096                    if (options.onGenerate && $.isFunction(options.onGenerate)) {
2097                        options.onGenerate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
2098                    }
2099                    if (triggerAfterOpen) {
2100                        datetimepicker.trigger('afterOpen.xdsoft');
2101                        triggerAfterOpen = false;
2102                    }
2103                })
2104                .on('click.xdsoft', function (xdevent) {
2105                    xdevent.stopPropagation();
2106                });
2107
2108            current_time_index = 0;
2109
2110            /**
2111             * Runs the callback for each of the specified node's ancestors.
2112             *
2113             * Return FALSE from the callback to stop ascending.
2114             *
2115             * @param {DOMNode} node
2116             * @param {Function} callback
2117             * @returns {undefined}
2118             */
2119            forEachAncestorOf = function (node, callback) {
2120                do {
2121                    node = node.parentNode;
2122
2123                    if (!node || callback(node) === false) {
2124                        break;
2125                    }
2126                } while (node.nodeName !== 'HTML');
2127            };
2128
2129            /**
2130             * Sets the position of the picker.
2131             *
2132             * @returns {undefined}
2133             */
2134            setPos = function () {
2135                var dateInputOffset,
2136                    dateInputElem,
2137                    verticalPosition,
2138                    left,
2139                    position,
2140                    datetimepickerElem,
2141                    dateInputHasFixedAncestor,
2142                    $dateInput,
2143                    windowWidth,
2144                    verticalAnchorEdge,
2145                    datetimepickerCss,
2146                    windowHeight,
2147                    windowScrollTop;
2148
2149                $dateInput = datetimepicker.data('input');
2150                dateInputOffset = $dateInput.offset();
2151                dateInputElem = $dateInput[0];
2152
2153                verticalAnchorEdge = 'top';
2154                verticalPosition = (dateInputOffset.top + dateInputElem.offsetHeight) - 1;
2155                left = dateInputOffset.left;
2156                position = "absolute";
2157
2158                windowWidth = $(options.contentWindow).width();
2159                windowHeight = $(options.contentWindow).height();
2160                windowScrollTop = $(options.contentWindow).scrollTop();
2161
2162                if ((options.ownerDocument.documentElement.clientWidth - dateInputOffset.left) < datepicker.parent().outerWidth(true)) {
2163                    var diff = datepicker.parent().outerWidth(true) - dateInputElem.offsetWidth;
2164                    left = left - diff;
2165                }
2166
2167                if ($dateInput.parent().css('direction') === 'rtl') {
2168                    left -= (datetimepicker.outerWidth() - $dateInput.outerWidth());
2169                }
2170
2171                if (options.fixed) {
2172                    verticalPosition -= windowScrollTop;
2173                    left -= $(options.contentWindow).scrollLeft();
2174                    position = "fixed";
2175                } else {
2176                    dateInputHasFixedAncestor = false;
2177
2178                    forEachAncestorOf(dateInputElem, function (ancestorNode) {
2179                        if (ancestorNode === null) {
2180                            return false;
2181                        }
2182
2183                        if (options.contentWindow.getComputedStyle(ancestorNode).getPropertyValue('position') === 'fixed') {
2184                            dateInputHasFixedAncestor = true;
2185                            return false;
2186                        }
2187                    });
2188
2189                    if (dateInputHasFixedAncestor && !options.insideParent) {
2190                        position = 'fixed';
2191
2192                        //If the picker won't fit entirely within the viewport then display it above the date input.
2193                        if (verticalPosition + datetimepicker.outerHeight() > windowHeight + windowScrollTop) {
2194                            verticalAnchorEdge = 'bottom';
2195                            verticalPosition = (windowHeight + windowScrollTop) - dateInputOffset.top;
2196                        } else {
2197                            verticalPosition -= windowScrollTop;
2198                        }
2199                    } else {
2200                        if (verticalPosition + datetimepicker[0].offsetHeight > windowHeight + windowScrollTop) {
2201                            verticalPosition = dateInputOffset.top - datetimepicker[0].offsetHeight + 1;
2202                        }
2203                    }
2204
2205                    if (verticalPosition < 0) {
2206                        verticalPosition = 0;
2207                    }
2208
2209                    if (left + dateInputElem.offsetWidth > windowWidth) {
2210                        left = windowWidth - dateInputElem.offsetWidth;
2211                    }
2212                }
2213
2214                datetimepickerElem = datetimepicker[0];
2215
2216                forEachAncestorOf(datetimepickerElem, function (ancestorNode) {
2217                    var ancestorNodePosition;
2218
2219                    ancestorNodePosition = options.contentWindow.getComputedStyle(ancestorNode).getPropertyValue('position');
2220
2221                    if (ancestorNodePosition === 'relative' && windowWidth >= ancestorNode.offsetWidth) {
2222                        left = left - ((windowWidth - ancestorNode.offsetWidth) / 2);
2223                        return false;
2224                    }
2225                });
2226
2227                datetimepickerCss = {
2228                    position: position,
2229                    left: options.insideParent ? dateInputElem.offsetLeft : left,
2230                    top: '',  //Initialize to prevent previous values interfering with new ones.
2231                    bottom: ''  //Initialize to prevent previous values interfering with new ones.
2232                };
2233
2234                if (options.insideParent) {
2235                    datetimepickerCss[verticalAnchorEdge] = dateInputElem.offsetTop + dateInputElem.offsetHeight;
2236                } else {
2237                    datetimepickerCss[verticalAnchorEdge] = verticalPosition;
2238                }
2239
2240                datetimepicker.css(datetimepickerCss);
2241            };
2242
2243            datetimepicker
2244                .on('open.xdsoft', function (event) {
2245                    var onShow = true;
2246                    if (options.onShow && $.isFunction(options.onShow)) {
2247                        onShow = options.onShow.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
2248                    }
2249                    if (onShow !== false) {
2250                        datetimepicker.show();
2251                        setPos();
2252                        $(options.contentWindow)
2253                            .off('resize.xdsoft', setPos)
2254                            .on('resize.xdsoft', setPos);
2255
2256                        if (options.closeOnWithoutClick) {
2257                            $([options.ownerDocument.body, options.contentWindow]).on('touchstart mousedown.xdsoft', function arguments_callee6() {
2258                                datetimepicker.trigger('close.xdsoft');
2259                                $([options.ownerDocument.body, options.contentWindow]).off('touchstart mousedown.xdsoft', arguments_callee6);
2260                            });
2261                        }
2262                    }
2263                })
2264                .on('close.xdsoft', function (event) {
2265                    var onClose = true;
2266                    month_picker
2267                        .find('.xdsoft_month,.xdsoft_year')
2268                        .find('.xdsoft_select')
2269                        .hide();
2270                    if (options.onClose && $.isFunction(options.onClose)) {
2271                        onClose = options.onClose.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
2272                    }
2273                    if (onClose !== false && !options.opened && !options.inline) {
2274                        datetimepicker.hide();
2275                    }
2276                    event.stopPropagation();
2277                })
2278                .on('toggle.xdsoft', function () {
2279                    if (datetimepicker.is(':visible')) {
2280                        datetimepicker.trigger('close.xdsoft');
2281                    } else {
2282                        datetimepicker.trigger('open.xdsoft');
2283                    }
2284                })
2285                .data('input', input);
2286
2287            timer = 0;
2288
2289            datetimepicker.data('xdsoft_datetime', _xdsoft_datetime);
2290            datetimepicker.setOptions(options);
2291
2292            function getCurrentValue() {
2293                var ct = false, time;
2294
2295                if (options.startDate) {
2296                    ct = _xdsoft_datetime.strToDate(options.startDate);
2297                } else {
2298                    ct = options.value || ((input && input.val && input.val()) ? input.val() : '');
2299                    if (ct) {
2300                        ct = _xdsoft_datetime.strToDateTime(ct);
2301                        if (options.yearOffset) {
2302                            ct = new Date(ct.getFullYear() - options.yearOffset, ct.getMonth(), ct.getDate(), ct.getHours(), ct.getMinutes(), ct.getSeconds(), ct.getMilliseconds());
2303                        }
2304                    } else if (options.defaultDate) {
2305                        ct = _xdsoft_datetime.strToDateTime(options.defaultDate);
2306                        if (options.defaultTime) {
2307                            time = _xdsoft_datetime.strtotime(options.defaultTime);
2308                            ct.setHours(time.getHours());
2309                            ct.setMinutes(time.getMinutes());
2310                        }
2311                    }
2312                }
2313
2314                if (ct && _xdsoft_datetime.isValidDate(ct)) {
2315                    datetimepicker.data('changed', true);
2316                } else {
2317                    ct = '';
2318                }
2319
2320                return ct || 0;
2321            }
2322
2323            function setMask(options) {
2324
2325                var isValidValue = function (mask, value) {
2326                        var reg = mask
2327                            .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
2328                            .replace(/_/g, '{digit+}')
2329                            .replace(/([0-9]{1})/g, '{digit$1}')
2330                            .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
2331                            .replace(/\{digit[\+]\}/g, '[0-9_]{1}');
2332                        return (new RegExp(reg)).test(value);
2333                    },
2334                    getCaretPos = function (input) {
2335                        try {
2336                            if (options.ownerDocument.selection && options.ownerDocument.selection.createRange) {
2337                                var range = options.ownerDocument.selection.createRange();
2338                                return range.getBookmark().charCodeAt(2) - 2;
2339                            }
2340                            if (input.setSelectionRange) {
2341                                return input.selectionStart;
2342                            }
2343                        } catch (e) {
2344                            return 0;
2345                        }
2346                    },
2347                    setCaretPos = function (node, pos) {
2348                        node = (typeof node === "string" || node instanceof String) ? options.ownerDocument.getElementById(node) : node;
2349                        if (!node) {
2350                            return false;
2351                        }
2352                        if (node.createTextRange) {
2353                            var textRange = node.createTextRange();
2354                            textRange.collapse(true);
2355                            textRange.moveEnd('character', pos);
2356                            textRange.moveStart('character', pos);
2357                            textRange.select();
2358                            return true;
2359                        }
2360                        if (node.setSelectionRange) {
2361                            node.setSelectionRange(pos, pos);
2362                            return true;
2363                        }
2364                        return false;
2365                    };
2366
2367                if(options.mask) {
2368                    input.off('keydown.xdsoft');
2369                }
2370
2371                if (options.mask === true) {
2372                    if (dateHelper.formatMask) {
2373                        options.mask = dateHelper.formatMask(options.format)
2374                    } else {
2375                        options.mask = options.format
2376                            .replace(/Y/g, '9999')
2377                            .replace(/F/g, '9999')
2378                            .replace(/m/g, '19')
2379                            .replace(/d/g, '39')
2380                            .replace(/H/g, '29')
2381                            .replace(/i/g, '59')
2382                            .replace(/s/g, '59');
2383                    }
2384                }
2385
2386                if ($.type(options.mask) === 'string') {
2387                    if (!isValidValue(options.mask, input.val())) {
2388                        input.val(options.mask.replace(/[0-9]/g, '_'));
2389                        setCaretPos(input[0], 0);
2390                    }
2391
2392                    input.on('paste.xdsoft', function (event) {
2393                        // couple options here
2394                        // 1. return false - tell them they can't paste
2395                        // 2. insert over current characters - minimal validation
2396                        // 3. full fledged parsing and validation
2397                        // let's go option 2 for now
2398
2399                        // fires multiple times for some reason
2400
2401                        // https://stackoverflow.com/a/30496488/1366033
2402                        var clipboardData = event.clipboardData || event.originalEvent.clipboardData || window.clipboardData,
2403                            pastedData = clipboardData.getData('text'),
2404                            val = this.value,
2405                            pos = this.selectionStart
2406
2407                        var valueBeforeCursor = val.substr(0, pos);
2408                        var valueAfterPaste = val.substr(pos + pastedData.length);
2409
2410                        val = valueBeforeCursor + pastedData + valueAfterPaste;
2411                        pos += pastedData.length;
2412
2413                        if (isValidValue(options.mask, val)) {
2414                            this.value = val;
2415                            setCaretPos(this, pos);
2416                        } else if ($.trim(val) === '') {
2417                            this.value = options.mask.replace(/[0-9]/g, '_');
2418                        } else {
2419                            input.trigger('error_input.xdsoft');
2420                        }
2421
2422                        event.preventDefault();
2423                        return false;
2424                    });
2425
2426                    input.on('keydown.xdsoft', function (event) {
2427                        var val = this.value,
2428                            key = event.which,
2429                            pos = this.selectionStart,
2430                            selEnd = this.selectionEnd,
2431                            hasSel = pos !== selEnd,
2432                            digit;
2433
2434                        // only alow these characters
2435                        if (((key >=  KEY0 && key <=  KEY9)  ||
2436                            (key >= _KEY0 && key <= _KEY9)) ||
2437                            (key === BACKSPACE || key === DEL)) {
2438
2439                            // get char to insert which is new character or placeholder ('_')
2440                            digit = (key === BACKSPACE || key === DEL) ? '_' :
2441                                String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key);
2442
2443                            // we're deleting something, we're not at the start, and have normal cursor, move back one
2444                            // if we have a selection length, cursor actually sits behind deletable char, not in front
2445                            if (key === BACKSPACE && pos && !hasSel) {
2446                                pos -= 1;
2447                            }
2448
2449                            // don't stop on a separator, continue whatever direction you were going
2450                            //   value char - keep incrementing position while on separator char and we still have room
2451                            //   del char   - keep decrementing position while on separator char and we still have room
2452                            while (true) {
2453                                var maskValueAtCurPos = options.mask.substr(pos, 1);
2454                                var posShorterThanMaskLength = pos < options.mask.length;
2455                                var posGreaterThanZero = pos > 0;
2456                                var notNumberOrPlaceholder = /[^0-9_]/;
2457                                var curPosOnSep = notNumberOrPlaceholder.test(maskValueAtCurPos);
2458                                var continueMovingPosition = curPosOnSep && posShorterThanMaskLength && posGreaterThanZero
2459
2460                                // if we hit a real char, stay where we are
2461                                if (!continueMovingPosition) break;
2462
2463                                // hitting backspace in a selection, you can possibly go back any further - go forward
2464                                pos += (key === BACKSPACE && !hasSel) ? -1 : 1;
2465
2466                            }
2467
2468                            if (event.metaKey) {    // cmd has been pressed
2469                                pos = 0;
2470                                hasSel = true;
2471                            }
2472
2473                            if (hasSel) {
2474                                // pos might have moved so re-calc length
2475                                var selLength = selEnd - pos
2476
2477                                // if we have a selection length we will wipe out entire selection and replace with default template for that range
2478                                var defaultBlank = options.mask.replace(/[0-9]/g, '_');
2479                                var defaultBlankSelectionReplacement = defaultBlank.substr(pos, selLength);
2480                                var selReplacementRemainder = defaultBlankSelectionReplacement.substr(1) // might be empty
2481
2482                                var valueBeforeSel = val.substr(0, pos);
2483                                var insertChars = digit + selReplacementRemainder;
2484                                var charsAfterSelection = val.substr(pos + selLength);
2485
2486                                val = valueBeforeSel + insertChars + charsAfterSelection
2487
2488                            } else {
2489                                var valueBeforeCursor = val.substr(0, pos);
2490                                var insertChar = digit;
2491                                var valueAfterNextChar = val.substr(pos + 1);
2492
2493                                val = valueBeforeCursor + insertChar + valueAfterNextChar
2494                            }
2495
2496                            if ($.trim(val) === '') {
2497                                // if empty, set to default
2498                                val = defaultBlank
2499                            } else {
2500                                // if at the last character don't need to do anything
2501                                if (pos === options.mask.length) {
2502                                    event.preventDefault();
2503                                    return false;
2504                                }
2505                            }
2506
2507                            // resume cursor location
2508                            pos += (key === BACKSPACE) ? 0 : 1;
2509                            // don't stop on a separator, continue whatever direction you were going
2510                            while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
2511                                pos += (key === BACKSPACE) ? 0 : 1;
2512                            }
2513
2514                            if (isValidValue(options.mask, val)) {
2515                                this.value = val;
2516                                setCaretPos(this, pos);
2517                            } else if ($.trim(val) === '') {
2518                                this.value = options.mask.replace(/[0-9]/g, '_');
2519                            } else {
2520                                input.trigger('error_input.xdsoft');
2521                            }
2522                        } else {
2523                            if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
2524                                return true;
2525                            }
2526                        }
2527
2528                        event.preventDefault();
2529                        return false;
2530                    });
2531                }
2532            }
2533
2534            _xdsoft_datetime.setCurrentTime(getCurrentValue());
2535
2536            input
2537                .data('xdsoft_datetimepicker', datetimepicker)
2538                .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function () {
2539                    if (input.is(':disabled') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) {
2540                        return;
2541                    }
2542                    if (!options.openOnFocus) {
2543                        return;
2544                    }
2545                    clearTimeout(timer);
2546                    timer = setTimeout(function () {
2547                        if (input.is(':disabled')) {
2548                            return;
2549                        }
2550
2551                        triggerAfterOpen = true;
2552                        _xdsoft_datetime.setCurrentTime(getCurrentValue(), true);
2553                        if(options.mask) {
2554                            setMask(options);
2555                        }
2556                        datetimepicker.trigger('open.xdsoft');
2557                    }, 100);
2558                })
2559                .on('keydown.xdsoft', function (event) {
2560                    var elementSelector,
2561                        key = event.which;
2562                    if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) {
2563                        elementSelector = $("input:visible,textarea:visible,button:visible,a:visible");
2564                        datetimepicker.trigger('close.xdsoft');
2565                        elementSelector.eq(elementSelector.index(this) + 1).focus();
2566                        return false;
2567                    }
2568                    if ([TAB].indexOf(key) !== -1) {
2569                        datetimepicker.trigger('close.xdsoft');
2570                        return true;
2571                    }
2572                })
2573                .on('blur.xdsoft', function () {
2574                    datetimepicker.trigger('close.xdsoft');
2575                });
2576        };
2577        destroyDateTimePicker = function (input) {
2578            var datetimepicker = input.data('xdsoft_datetimepicker');
2579            if (datetimepicker) {
2580                datetimepicker.data('xdsoft_datetime', null);
2581                datetimepicker.remove();
2582                input
2583                    .data('xdsoft_datetimepicker', null)
2584                    .off('.xdsoft');
2585                $(options.contentWindow).off('resize.xdsoft');
2586                $([options.contentWindow, options.ownerDocument.body]).off('mousedown.xdsoft touchstart');
2587                if (input.unmousewheel) {
2588                    input.unmousewheel();
2589                }
2590            }
2591        };
2592        $(options.ownerDocument)
2593            .off('keydown.xdsoftctrl keyup.xdsoftctrl')
2594            .off('keydown.xdsoftcmd keyup.xdsoftcmd')
2595            .on('keydown.xdsoftctrl', function (e) {
2596                if (e.keyCode === CTRLKEY) {
2597                    ctrlDown = true;
2598                }
2599            })
2600            .on('keyup.xdsoftctrl', function (e) {
2601                if (e.keyCode === CTRLKEY) {
2602                    ctrlDown = false;
2603                }
2604            })
2605            .on('keydown.xdsoftcmd', function (e) {
2606                if (e.keyCode === CMDKEY) {
2607                    cmdDown = true;
2608                }
2609            })
2610            .on('keyup.xdsoftcmd', function (e) {
2611                if (e.keyCode === CMDKEY) {
2612                    cmdDown = false;
2613                }
2614            });
2615
2616        this.each(function () {
2617            var datetimepicker = $(this).data('xdsoft_datetimepicker'), $input;
2618            if (datetimepicker) {
2619                if ($.type(opt) === 'string') {
2620                    switch (opt) {
2621                        case 'show':
2622                            $(this).select().focus();
2623                            datetimepicker.trigger('open.xdsoft');
2624                            break;
2625                        case 'hide':
2626                            datetimepicker.trigger('close.xdsoft');
2627                            break;
2628                        case 'toggle':
2629                            datetimepicker.trigger('toggle.xdsoft');
2630                            break;
2631                        case 'destroy':
2632                            destroyDateTimePicker($(this));
2633                            break;
2634                        case 'reset':
2635                            this.value = this.defaultValue;
2636                            if (!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(dateHelper.parseDate(this.value, options.format))) {
2637                                datetimepicker.data('changed', false);
2638                            }
2639                            datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value);
2640                            break;
2641                        case 'validate':
2642                            $input = datetimepicker.data('input');
2643                            $input.trigger('blur.xdsoft');
2644                            break;
2645                        default:
2646                            if (datetimepicker[opt] && $.isFunction(datetimepicker[opt])) {
2647                                result = datetimepicker[opt](opt2);
2648                            }
2649                    }
2650                } else {
2651                    datetimepicker
2652                        .setOptions(opt);
2653                }
2654                return 0;
2655            }
2656            if ($.type(opt) !== 'string') {
2657                if (!options.lazyInit || options.open || options.inline) {
2658                    createDateTimePicker($(this));
2659                } else {
2660                    lazyInit($(this));
2661                }
2662            }
2663        });
2664
2665        return result;
2666    };
2667
2668    $.fn.fat_datetimepicker.defaults = default_options;
2669
2670    function HighlightedDate(date, desc, style) {
2671        "use strict";
2672        this.date = date;
2673        this.desc = desc;
2674        this.style = style;
2675    }
2676};
2677;(function (factory) {
2678    if ( typeof define === 'function' && define.amd ) {
2679        // AMD. Register as an anonymous module.
2680        define(['jquery', 'jquery-mousewheel'], factory);
2681    } else if (typeof exports === 'object') {
2682        // Node/CommonJS style for Browserify
2683        module.exports = factory(require('jquery'));;
2684    } else {
2685        // Browser globals
2686        factory(jQuery);
2687    }
2688}(datetimepickerFactory));
2689
2690
2691/*!
2692 * jQuery Mousewheel 3.1.13
2693 *
2694 * Copyright jQuery Foundation and other contributors
2695 * Released under the MIT license
2696 * http://jquery.org/license
2697 */
2698
2699(function (factory) {
2700    if ( typeof define === 'function' && define.amd ) {
2701        // AMD. Register as an anonymous module.
2702        define(['jquery'], factory);
2703    } else if (typeof exports === 'object') {
2704        // Node/CommonJS style for Browserify
2705        module.exports = factory;
2706    } else {
2707        // Browser globals
2708        factory(jQuery);
2709    }
2710}(function ($) {
2711
2712    var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
2713        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
2714            ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
2715        slice  = Array.prototype.slice,
2716        nullLowestDeltaTimeout, lowestDelta;
2717
2718    if ( $.event.fixHooks ) {
2719        for ( var i = toFix.length; i; ) {
2720            $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
2721        }
2722    }
2723
2724    var special = $.event.special.mousewheel = {
2725        version: '3.1.12',
2726
2727        setup: function() {
2728            if ( this.addEventListener ) {
2729                for ( var i = toBind.length; i; ) {
2730                    this.addEventListener( toBind[--i], handler, false );
2731                }
2732            } else {
2733                this.onmousewheel = handler;
2734            }
2735            // Store the line height and page height for this particular element
2736            $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
2737            $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
2738        },
2739
2740        teardown: function() {
2741            if ( this.removeEventListener ) {
2742                for ( var i = toBind.length; i; ) {
2743                    this.removeEventListener( toBind[--i], handler, false );
2744                }
2745            } else {
2746                this.onmousewheel = null;
2747            }
2748            // Clean up the data we added to the element
2749            $.removeData(this, 'mousewheel-line-height');
2750            $.removeData(this, 'mousewheel-page-height');
2751        },
2752
2753        getLineHeight: function(elem) {
2754            var $elem = $(elem),
2755                $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
2756            if (!$parent.length) {
2757                $parent = $('body');
2758            }
2759            return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
2760        },
2761
2762        getPageHeight: function(elem) {
2763            return $(elem).height();
2764        },
2765
2766        settings: {
2767            adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
2768            normalizeOffset: true  // calls getBoundingClientRect for each event
2769        }
2770    };
2771
2772    $.fn.extend({
2773        mousewheel: function(fn) {
2774            return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
2775        },
2776
2777        unmousewheel: function(fn) {
2778            return this.unbind('mousewheel', fn);
2779        }
2780    });
2781
2782
2783    function handler(event) {
2784        var orgEvent   = event || window.event,
2785            args       = slice.call(arguments, 1),
2786            delta      = 0,
2787            deltaX     = 0,
2788            deltaY     = 0,
2789            absDelta   = 0,
2790            offsetX    = 0,
2791            offsetY    = 0;
2792        event = $.event.fix(orgEvent);
2793        event.type = 'mousewheel';
2794
2795        // Old school scrollwheel delta
2796        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }
2797        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }
2798        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }
2799        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
2800
2801        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
2802        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
2803            deltaX = deltaY * -1;
2804            deltaY = 0;
2805        }
2806
2807        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
2808        delta = deltaY === 0 ? deltaX : deltaY;
2809
2810        // New school wheel delta (wheel event)
2811        if ( 'deltaY' in orgEvent ) {
2812            deltaY = orgEvent.deltaY * -1;
2813            delta  = deltaY;
2814        }
2815        if ( 'deltaX' in orgEvent ) {
2816            deltaX = orgEvent.deltaX;
2817            if ( deltaY === 0 ) { delta  = deltaX * -1; }
2818        }
2819
2820        // No change actually happened, no reason to go any further
2821        if ( deltaY === 0 && deltaX === 0 ) { return; }
2822
2823        // Need to convert lines and pages to pixels if we aren't already in pixels
2824        // There are three delta modes:
2825        //   * deltaMode 0 is by pixels, nothing to do
2826        //   * deltaMode 1 is by lines
2827        //   * deltaMode 2 is by pages
2828        if ( orgEvent.deltaMode === 1 ) {
2829            var lineHeight = $.data(this, 'mousewheel-line-height');
2830            delta  *= lineHeight;
2831            deltaY *= lineHeight;
2832            deltaX *= lineHeight;
2833        } else if ( orgEvent.deltaMode === 2 ) {
2834            var pageHeight = $.data(this, 'mousewheel-page-height');
2835            delta  *= pageHeight;
2836            deltaY *= pageHeight;
2837            deltaX *= pageHeight;
2838        }
2839
2840        // Store lowest absolute delta to normalize the delta values
2841        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
2842
2843        if ( !lowestDelta || absDelta < lowestDelta ) {
2844            lowestDelta = absDelta;
2845
2846            // Adjust older deltas if necessary
2847            if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
2848                lowestDelta /= 40;
2849            }
2850        }
2851
2852        // Adjust older deltas if necessary
2853        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
2854            // Divide all the things by 40!
2855            delta  /= 40;
2856            deltaX /= 40;
2857            deltaY /= 40;
2858        }
2859
2860        // Get a whole, normalized value for the deltas
2861        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);
2862        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
2863        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
2864
2865        // Normalise offsetX and offsetY properties
2866        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
2867            var boundingRect = this.getBoundingClientRect();
2868            offsetX = event.clientX - boundingRect.left;
2869            offsetY = event.clientY - boundingRect.top;
2870        }
2871
2872        // Add information to the event object
2873        event.deltaX = deltaX;
2874        event.deltaY = deltaY;
2875        event.deltaFactor = lowestDelta;
2876        event.offsetX = offsetX;
2877        event.offsetY = offsetY;
2878        // Go ahead and set deltaMode to 0 since we converted to pixels
2879        // Although this is a little odd since we overwrite the deltaX/Y
2880        // properties with normalized deltas.
2881        event.deltaMode = 0;
2882
2883        // Add event and delta to the front of the arguments
2884        args.unshift(event, delta, deltaX, deltaY);
2885
2886        // Clearout lowestDelta after sometime to better
2887        // handle multiple device types that give different
2888        // a different lowestDelta
2889        // Ex: trackpad = 3 and mouse wheel = 120
2890        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
2891        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
2892
2893        return ($.event.dispatch || $.event.handle).apply(this, args);
2894    }
2895
2896    function nullLowestDelta() {
2897        lowestDelta = null;
2898    }
2899
2900    function shouldAdjustOldDeltas(orgEvent, absDelta) {
2901        // If this is an older event and the delta is divisable by 120,
2902        // then we are assuming that the browser is treating this as an
2903        // older mouse wheel event and that we should divide the deltas
2904        // by 40 to try and get a more usable deltaFactor.
2905        // Side note, this actually impacts the reported scroll distance
2906        // in older browsers and can cause scrolling to be slower than native.
2907        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
2908        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
2909    }
2910
2911}));

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.