PageSourceSearch

https://dlhtml.netlify.app/assets/js/vendor/jquery.datetimepicker.full.js

js dlhtml.netlify.app collected 2026-10-03 10:39:38 UTC 112,273 bytes, 2,953 lines download raw bytes

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

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.