PageSourceSearch

https://citaprevia.cambrils.cat/assets/plugins/bootstrap-datetimep…/bootstrap-datetimepicker.js?v=1784113222

js cambrils.cat collected 2026-10-02 06:57:52 UTC 93,081 bytes, 1,970 lines download raw bytes

1/* =========================================================
2 * bootstrap-datetimepicker.js
3 * =========================================================
4 * Copyright 2012 Stefan Petre
5 * Improvements by Andrew Rowls
6 * Improvements by Sébastien Malot
7 * Improvements by Yun Lai
8 * Improved by Keenthemes for Bootstrap 3.0 Support
9
10 * Project URL : http://www.malot.fr/bootstrap-datetimepicker
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 * ========================================================= */
24
25!function ($) {
26
27    function UTCDate() {
28        return new Date(Date.UTC.apply(Date, arguments));
29    }
30
31    function UTCToday() {
32        var today = new Date();
33        return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate(), today.getUTCHours(), today.getUTCMinutes(), today.getUTCSeconds(), 0);
34    }
35
36    function selectDay(e, aixo) {
37        var target = $(e.target).closest('span, td, th, legend');
38        if (target.length == 1) {
39            if (target.is('.disabled')) {
40                aixo.element.trigger({
41                    type: 'outOfRange',
42                    date: aixo.viewDate,
43                    startDate: aixo.startDate,
44                    endDate: aixo.endDate
45                });
46                return;
47            }
48            switch (target[0].nodeName.toLowerCase()) {
49                case 'th':
50                    switch (target[0].className) {
51                        case 'switch':
52                            aixo.showMode(1);
53                            break;
54                        case 'prev':
55                        case 'next':
56                            var dir = DPGlobal.modes[aixo.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1);
57                            switch (aixo.viewMode) {
58                                case 0:
59                                    aixo.viewDate = aixo.moveHour(aixo.viewDate, dir);
60                                    break;
61                                case 1:
62                                    aixo.viewDate = aixo.moveDate(aixo.viewDate, dir);
63                                    break;
64                                case 2:
65                                    aixo.viewDate = aixo.moveMonth(aixo.viewDate, dir);
66                                    break;
67                                case 3:
68                                case 4:
69                                    aixo.viewDate = aixo.moveYear(aixo.viewDate, dir);
70                                    break;
71                            }
72                            aixo.fill();
73                            break;
74                        case 'today':
75                            var date = new Date();
76                            date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0);
77
78                            aixo.viewMode = aixo.startViewMode;
79                            aixo.showMode(0);
80                            aixo._setDate(date);
81                            aixo.fill();
82                            if (aixo.autoclose) {
83                                aixo.hide();
84                            }
85                            break;
86                    }
87                    break;
88                // case 'span':
89                    // if (!target.is('.disabled')) {
90                    //     var year = aixo.viewDate.getUTCFullYear(),
91                    //         month = aixo.viewDate.getUTCMonth(),
92                    //         day = aixo.viewDate.getUTCDate(),
93                    //         hours = aixo.viewDate.getUTCHours(),
94                    //         minutes = aixo.viewDate.getUTCMinutes(),
95                    //         seconds = aixo.viewDate.getUTCSeconds();
96                    //
97                    //     if (target.is('.month')) {
98                    //         aixo.viewDate.setUTCDate(1);
99                    //         month = target.parent().find('span').index(target);
100                    //         day = aixo.viewDate.getUTCDate();
101                    //         aixo.viewDate.setUTCMonth(month);
102                    //         aixo.element.trigger({
103                    //             type: 'changeMonth',
104                    //             date: aixo.viewDate
105                    //         });
106                    //         if (aixo.viewSelect >= 3) {
107                    //             aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
108                    //         }
109                    //     } else if (target.is('.year')) {
110                    //         aixo.viewDate.setUTCDate(1);
111                    //         year = parseInt(target.text(), 10) || 0;
112                    //         aixo.viewDate.setUTCFullYear(year);
113                    //         aixo.element.trigger({
114                    //             type: 'changeYear',
115                    //             date: aixo.viewDate
116                    //         });
117                    //         if (aixo.viewSelect >= 4) {
118                    //             aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
119                    //         }
120                    //     } else if (target.is('.hour')) {
121                    //         hours = parseInt(target.text(), 10) || 0;
122                    //         if (target.hasClass('hour_am') || target.hasClass('hour_pm')) {
123                    //             if (hours == 12 && target.hasClass('hour_am')) {
124                    //                 hours = 0;
125                    //             } else if (hours != 12 && target.hasClass('hour_pm')) {
126                    //                 hours += 12;
127                    //             }
128                    //         }
129                    //         aixo.viewDate.setUTCHours(hours);
130                    //         aixo.element.trigger({
131                    //             type: 'changeHour',
132                    //             date: aixo.viewDate
133                    //         });
134                    //         if (aixo.viewSelect >= 1) {
135                    //             aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
136                    //         }
137                    //     } else if (target.is('.minute')) {
138                    //         let hora = target.text().split(":");
139                    //         hours = parseInt(hora[0], 10) || 0;
140                    //         minutes = parseInt(target.text().substr(target.text().indexOf(':') + 1), 10) || 0;
141                    //
142                    //         aixo.viewDate.setUTCHours(hours);
143                    //         aixo.viewDate.setUTCMinutes(minutes);
144                    //         aixo.element.trigger({
145                    //             type: 'changeMinute',
146                    //             date: aixo.viewDate
147                    //         });
148                    //         if (aixo.viewSelect >= 0) {
149                    //             aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
150                    //         }
151                    //     }
152                    //     if (aixo.viewMode != 0) {
153                    //         var oldViewMode = aixo.viewMode;
154                    //         aixo.showMode(-1);
155                    //         aixo.fill();
156                    //         if (oldViewMode == aixo.viewMode && aixo.autoclose) {
157                    //             aixo.hide();
158                    //         }
159                    //     } else {
160                    //         aixo.fill();
161                    //         if (aixo.autoclose) {
162                    //             aixo.hide();
163                    //         }
164                    //     }
165                    // }
166                    // break;
167                case 'span':
168                case 'td':
169                    if (target.is('.minute') || target.is('.hour')) {
170                        if (!target.is('.disabled')) {
171                            var year = aixo.viewDate.getUTCFullYear(),
172                                month = aixo.viewDate.getUTCMonth(),
173                                day = aixo.viewDate.getUTCDate(),
174                                hours = aixo.viewDate.getUTCHours(),
175                                minutes = aixo.viewDate.getUTCMinutes(),
176                                seconds = aixo.viewDate.getUTCSeconds();
177
178                            if (target.is('.month')) {
179                                aixo.viewDate.setUTCDate(1);
180                                month = target.parent().find('span').index(target);
181                                day = aixo.viewDate.getUTCDate();
182                                aixo.viewDate.setUTCMonth(month);
183                                aixo.element.trigger({
184                                    type: 'changeMonth',
185                                    date: aixo.viewDate
186                                });
187                                if (aixo.viewSelect >= 3) {
188                                    aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
189                                }
190                            } else if (target.is('.year')) {
191                                aixo.viewDate.setUTCDate(1);
192                                year = parseInt(target.text(), 10) || 0;
193                                aixo.viewDate.setUTCFullYear(year);
194                                aixo.element.trigger({
195                                    type: 'changeYear',
196                                    date: aixo.viewDate
197                                });
198                                if (aixo.viewSelect >= 4) {
199                                    aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
200                                }
201                            } else if (target.is('.hour')) {
202                                hours = parseInt(target.text(), 10) || 0;
203                                if (target.hasClass('hour_am') || target.hasClass('hour_pm')) {
204                                    if (hours == 12 && target.hasClass('hour_am')) {
205                                        hours = 0;
206                                    } else if (hours != 12 && target.hasClass('hour_pm')) {
207                                        hours += 12;
208                                    }
209                                }
210                                aixo.viewDate.setUTCHours(hours);
211                                aixo.element.trigger({
212                                    type: 'changeHour',
213                                    date: aixo.viewDate
214                                });
215                                if (aixo.viewSelect >= 1) {
216                                    aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
217                                }
218                            } else if (target.is('.minute')) {
219                                let hora = target.text().split(":");
220                                hours = parseInt(hora[0], 10) || 0;
221                                minutes = parseInt(target.text().substr(target.text().indexOf(':') + 1), 10) || 0;
222
223                                aixo.viewDate.setUTCHours(hours);
224                                aixo.viewDate.setUTCMinutes(minutes);
225                                aixo.element.trigger({
226                                    type: 'changeMinute',
227                                    date: aixo.viewDate
228                                });
229                                if (aixo.viewSelect >= 0) {
230                                    aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
231                                }
232                            }
233                            if (aixo.viewMode != 0) {
234                                var oldViewMode = aixo.viewMode;
235                                aixo.showMode(-1);
236                                aixo.fill();
237                                if (oldViewMode == aixo.viewMode && aixo.autoclose) {
238                                    aixo.hide();
239                                }
240                            } else {
241                                aixo.fill();
242                                if (aixo.autoclose) {
243                                    aixo.hide();
244                                }
245                            }
246                        }
247                        break;
248                    }
249                    if (target.is('.day')) {
250                        if (target.is('.day') && !target.is('.disabled')) {
251                            var day = parseInt(target.text(), 10) || 1;
252                            var year = aixo.viewDate.getUTCFullYear(),
253                                month = aixo.viewDate.getUTCMonth(),
254                                hours = aixo.viewDate.getUTCHours(),
255                                minutes = aixo.viewDate.getUTCMinutes(),
256                                seconds = aixo.viewDate.getUTCSeconds();
257                            if (target.is('.old')) {
258                                if (month === 0) {
259                                    month = 11;
260                                    year -= 1;
261                                } else {
262                                    month -= 1;
263                                }
264                            } else if (target.is('.new')) {
265                                if (month == 11) {
266                                    month = 0;
267                                    year += 1;
268                                } else {
269                                    month += 1;
270                                }
271                            }
272                            aixo.viewDate.setUTCFullYear(year);
273                            aixo.viewDate.setUTCMonth(month);
274                            aixo.viewDate.setUTCDate(day);
275                            aixo.clickDia = aixo.viewDate;
276                            aixo.element.trigger({
277                                type: 'changeDay',
278                                date: aixo.viewDate
279                            });
280                            if (aixo.viewSelect >= 2) {
281                                aixo._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
282                            }
283                        }
284                        var oldViewMode = aixo.viewMode;
285                        aixo.showMode(-1);
286                        aixo.fill();
287                        if (oldViewMode == aixo.viewMode && aixo.autoclose) {
288                            aixo.hide();
289                        }
290                    }
291                    break;
292            }
293        }
294        return aixo;
295    }
296
297    // Picker object
298
299    var Datetimepicker = function (element, options) {
300        var that = this;
301
302        this.element = $(element);
303        this.language = options.language || this.element.data('date-language') || "en";
304        this.language = this.language in dates ? this.language : "en";
305        this.isRTL = dates[this.language].rtl || ($('body').css("direction") == 'rtl');
306        this.formatType = options.formatType || this.element.data('format-type') || 'standard';
307        this.format = DPGlobal.parseFormat(options.format || this.element.data('date-format') || dates[this.language].format || DPGlobal.getDefaultFormat(this.formatType, 'input'), this.formatType);
308        this.isInline = false;
309        this.isVisible = false;
310        this.isInput = this.element.is('input');
311        this.component = this.element.is('.date') ? this.element.find('.date-set').parent() : false;
312        this.componentReset = this.element.is('.date') ? this.element.find('.date-reset').parent() : false;
313        this.hasInput = this.component && this.element.find('input').length;
314        if (this.component && this.component.length === 0) {
315            this.component = false;
316        }
317        this.linkField = options.linkField || this.element.data('link-field') || false;
318        this.linkFormat = DPGlobal.parseFormat(options.linkFormat || this.element.data('link-format') || DPGlobal.getDefaultFormat(this.formatType, 'link'), this.formatType);
319        this.minuteStep = options.minuteStep || this.element.data('minute-step') || 5;
320        this.pickerPosition = options.pickerPosition || this.element.data('picker-position') || 'bottom-right';
321        //INICI MODIFICACIONS UBINTIA
322        //this.showMeridian = options.showMeridian || this.element.data('show-meridian') || false;
323        //Sempre ha de ser false ja no en fem cas a diversos llocs
324        this.showMeridian = false;
325        //FI MODIFICACIONS UBINTIA
326        this.initialDate = options.initialDate || new Date();
327        //INICI MODIFICACIONS UBINTIA
328        this.activeDays = options.activeDays || [];
329        this.totalDays = options.totalDays || [];
330        this.visiblesOcupades = options.visibleOcupades || 0;
331        this.activeClass = options.activeClass || '';
332        this.tramitacio = options.tramitacio || 0;
333        this.activeHoursMinutes = [];
334        this.activeHours = [];
335        this.busyHours = [];
336        this.totalHours = [];
337        this.totalHoursNumber = 0;
338        this.totalHoursSenseMinuts = [];
339        this.missatgeHoresAgrupades = '';
340        this.missatgeHoresNoAgrupades = '';
341        this.missatgeHoresOcupades = '';
342        this.missatgeFrangesOcupades = '';
343        this.urlWebService = options.urlWebService || '';
344        this.dataInici = options.startDate || options.dataInici;
345        this.dia_cita = options.dia_cita;
346        this.consultaHores = false;
347        this.horariInicial = 0;
348        this.horariFinal = 0;
349        this.clickDia = '';
350        this.leyenda_hores = '';
351        //FI MODIFICACIONS UBINTIA
352        this._attachEvents();
353        this.formatViewType = "datetime";
354        if ('formatViewType' in options) {
355            this.formatViewType = options.formatViewType;
356        } else if ('formatViewType' in this.element.data()) {
357            this.formatViewType = this.element.data('formatViewType');
358        }
359
360        this.minView = 0;
361        if ('minView' in options) {
362            this.minView = options.minView;
363        } else if ('minView' in this.element.data()) {
364            this.minView = this.element.data('min-view');
365        }
366        this.minView = DPGlobal.convertViewMode(this.minView);
367
368        this.maxView = DPGlobal.modes.length - 1;
369        if ('maxView' in options) {
370            this.maxView = options.maxView;
371        } else if ('maxView' in this.element.data()) {
372            this.maxView = this.element.data('max-view');
373        }
374        this.maxView = DPGlobal.convertViewMode(this.maxView);
375
376        this.wheelViewModeNavigation = false;
377        if ('wheelViewModeNavigation' in options) {
378            this.wheelViewModeNavigation = options.wheelViewModeNavigation;
379        } else if ('wheelViewModeNavigation' in this.element.data()) {
380            this.wheelViewModeNavigation = this.element.data('view-mode-wheel-navigation');
381        }
382
383        this.wheelViewModeNavigationInverseDirection = false;
384
385        if ('wheelViewModeNavigationInverseDirection' in options) {
386            this.wheelViewModeNavigationInverseDirection = options.wheelViewModeNavigationInverseDirection;
387        } else if ('wheelViewModeNavigationInverseDirection' in this.element.data()) {
388            this.wheelViewModeNavigationInverseDirection = this.element.data('view-mode-wheel-navigation-inverse-dir');
389        }
390
391        this.wheelViewModeNavigationDelay = 100;
392        if ('wheelViewModeNavigationDelay' in options) {
393            this.wheelViewModeNavigationDelay = options.wheelViewModeNavigationDelay;
394        } else if ('wheelViewModeNavigationDelay' in this.element.data()) {
395            this.wheelViewModeNavigationDelay = this.element.data('view-mode-wheel-navigation-delay');
396        }
397
398        this.startViewMode = 2;
399        if ('startView' in options) {
400            this.startViewMode = options.startView;
401        } else if ('startView' in this.element.data()) {
402            this.startViewMode = this.element.data('start-view');
403        }
404        this.startViewMode = DPGlobal.convertViewMode(this.startViewMode);
405        this.viewMode = this.startViewMode;
406        //
407        this.viewSelect = this.minView;
408        if ('viewSelect' in options) {
409            this.viewSelect = options.viewSelect;
410        } else if ('viewSelect' in this.element.data()) {
411            this.viewSelect = this.element.data('view-select');
412        }
413        this.viewSelect = DPGlobal.convertViewMode(this.viewSelect);
414
415        this.forceParse = true;
416        if ('forceParse' in options) {
417            this.forceParse = options.forceParse;
418        } else if ('dateForceParse' in this.element.data()) {
419            this.forceParse = this.element.data('date-force-parse');
420        }
421
422        this.picker = $(DPGlobal.template)
423            .appendTo(this.isInline ? this.element : 'body')
424            .on({
425                click: $.proxy(this.click, this),
426                mousedown: $.proxy(this.mousedown, this)
427            });
428
429        if (this.wheelViewModeNavigation) {
430            if ($.fn.mousewheel) {
431                this.picker.on({mousewheel: $.proxy(this.mousewheel, this)});
432            } else {
433                console.log("Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option");
434            }
435        }
436
437        if (this.isInline) {
438            this.picker.addClass('datetimepicker-inline');
439        } else {
440            this.picker.addClass('datetimepicker-dropdown-' + this.pickerPosition + ' dropdown-menu');
441        }
442        if (this.isRTL) {
443            this.picker.addClass('datetimepicker-rtl');
444            this.picker.find('.prev i, .next i')
445                .toggleClass('fa-arrow-left fa-arrow-right');
446        }
447        $(document).on('mousedown', function (e) {
448            // Clicked outside the datetimepicker, hide it
449            if ($(e.target).closest('.datetimepicker').length === 0) {
450                that.hide();
451            }
452        });
453
454        this.autoclose = false;
455        if ('autoclose' in options) {
456            this.autoclose = options.autoclose;
457        } else if ('dateAutoclose' in this.element.data()) {
458            this.autoclose = this.element.data('date-autoclose');
459        }
460
461        this.keyboardNavigation = true;
462        if ('keyboardNavigation' in options) {
463            this.keyboardNavigation = options.keyboardNavigation;
464        } else if ('dateKeyboardNavigation' in this.element.data()) {
465            this.keyboardNavigation = this.element.data('date-keyboard-navigation');
466        }
467
468        this.todayBtn = (options.todayBtn || this.element.data('date-today-btn') || false);
469        this.todayHighlight = (options.todayHighlight || this.element.data('date-today-highlight') || false);
470
471        this.weekStart = ((options.weekStart || this.element.data('date-weekstart') || dates[this.language].weekStart || 0) % 7);
472        this.weekEnd = ((this.weekStart + 6) % 7);
473        this.startDate = -Infinity;
474        this.endDate = Infinity;
475        this.daysOfWeekDisabled = [];
476        this.setStartDate(options.startDate || this.element.data('date-startdate'));
477        this.setEndDate(options.endDate || this.element.data('date-enddate'));
478        this.setDaysOfWeekDisabled(options.daysOfWeekDisabled || this.element.data('date-days-of-week-disabled'));
479        this.fillDow();
480        this.fillMonths();
481        this.update();
482        this.showMode();
483
484        if (this.isInline) {
485            this.show();
486        }
487    };
488
489    Datetimepicker.prototype = {
490        constructor: Datetimepicker,
491        _events: [],
492        _attachEvents: function () {
493            this._detachEvents();
494            if (this.isInput) { // single input
495                this._events = [
496                    [this.element, {
497                        focus: $.proxy(this.show, this),
498                        keyup: $.proxy(this.update, this),
499                        keydown: $.proxy(this.keydown, this)
500                    }]
501                ];
502            } else if (this.component && this.hasInput) { // component: input + button
503                this._events = [
504                    // For components that are not readonly, allow keyboard nav
505                    [this.element.find('input'), {
506                        focus: $.proxy(this.show, this),
507                        keyup: $.proxy(this.update, this),
508                        keydown: $.proxy(this.keydown, this)
509                    }],
510                    [this.component, {
511                        click: $.proxy(this.show, this)
512                    }]
513                ];
514                if (this.componentReset) {
515                    this._events.push([
516                        this.componentReset,
517                        {click: $.proxy(this.reset, this)}
518                    ]);
519                }
520            } else if (this.element.is('div')) {  // inline datetimepicker
521                this.isInline = true;
522                this._events = [
523                    [this.element, {
524                        keydown: $.proxy(this.keydown, this)
525                    }]
526                ];
527            } else {
528                this._events = [
529                    [this.element, {
530                        click: $.proxy(this.show, this)
531                    }]
532                ];
533            }
534            for (var i = 0, el, ev; i < this._events.length; i++) {
535                el = this._events[i][0];
536                ev = this._events[i][1];
537                el.on(ev);
538            }
539        },
540        _detachEvents: function () {
541            for (var i = 0, el, ev; i < this._events.length; i++) {
542                el = this._events[i][0];
543                ev = this._events[i][1];
544                el.off(ev);
545            }
546            this._events = [];
547        },
548        show: function (e) {
549            this.picker.show();
550            this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
551            if (this.forceParse) {
552                this.update();
553            }
554            this.place();
555            $(window).on('resize', $.proxy(this.place, this));
556            if (e) {
557                e.stopPropagation();
558                e.preventDefault();
559            }
560            this.isVisible = true;
561            this.element.trigger({
562                type: 'show',
563                date: this.date
564            });
565        },
566        hide: function (e) {
567            if (!this.isVisible)
568                return;
569            if (this.isInline)
570                return;
571            this.picker.hide();
572            $(window).off('resize', this.place);
573            this.viewMode = this.startViewMode;
574            this.showMode();
575            if (!this.isInput) {
576                $(document).off('mousedown', this.hide);
577            }
578
579            if (
580                this.forceParse &&
581                (
582                    this.isInput && this.element.val() ||
583                    this.hasInput && this.element.find('input').val()
584                )
585            )
586                this.setValue();
587            this.isVisible = false;
588            this.element.trigger({
589                type: 'hide',
590                date: this.date
591            });
592        },
593        remove: function () {
594            this._detachEvents();
595            this.picker.remove();
596            delete this.picker;
597            delete this.element.data().datetimepicker;
598        },
599        getDate: function () {
600            var d = this.getUTCDate();
601            return new Date(d.getTime() + (d.getTimezoneOffset() * 60000));
602        },
603        getUTCDate: function () {
604            return this.date;
605        },
606        setDate: function (d) {
607            this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset() * 60000)));
608        },
609        setUTCDate: function (d) {
610            if (d >= this.startDate && d <= this.endDate) {
611                this.date = d;
612                this.setValue();
613                this.viewDate = this.date;
614                this.fill();
615            } else {
616                this.element.trigger({
617                    type: 'outOfRange',
618                    date: d,
619                    startDate: this.startDate,
620                    endDate: this.endDate
621                });
622            }
623        },
624        setFormat: function (format) {
625            this.format = DPGlobal.parseFormat(format, this.formatType);
626            var element;
627            if (this.isInput) {
628                element = this.element;
629            } else if (this.component) {
630                element = this.element.find('input');
631            }
632            if (element && element.val()) {
633                this.setValue();
634            }
635        },
636        setValue: function () {
637            var formatted = this.getFormattedDate();
638            if (!this.isInput) {
639                if (this.component) {
640                    this.element.find('input').val(formatted);
641                }
642                this.element.data('date', formatted);
643            } else {
644                this.element.val(formatted);
645            }
646            if (this.linkField) {
647                $('#' + this.linkField).val(this.getFormattedDate(this.linkFormat));
648            }
649        },
650        getFormattedDate: function (format) {
651            if (format == undefined)
652                format = this.format;
653            return DPGlobal.formatDate(this.date, format, this.language, this.formatType);
654        },
655        setStartDate: function (startDate) {
656            this.startDate = startDate || -Infinity;
657            if (this.startDate !== -Infinity) {
658                this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language, this.formatType);
659            }
660            this.update();
661            this.updateNavArrows();
662        },
663        setEndDate: function (endDate) {
664            this.endDate = endDate || Infinity;
665            if (this.endDate !== Infinity) {
666                this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language, this.formatType);
667            }
668            this.update();
669            this.updateNavArrows();
670        },
671        setDaysOfWeekDisabled: function (daysOfWeekDisabled) {
672            this.daysOfWeekDisabled = daysOfWeekDisabled || [];
673            if (!$.isArray(this.daysOfWeekDisabled)) {
674                this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
675            }
676            this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) {
677                return parseInt(d, 10);
678            });
679            this.update();
680            this.updateNavArrows();
681        },
682        place: function () {
683            if (this.isInline)
684                return;
685            var zIndex = parseInt(this.element.parents().filter(function () {
686                return $(this).css('z-index') != 'auto';
687            }).first().css('z-index')) + 10;
688            var offset, top, left;
689            if (this.component) {
690                offset = this.component.offset();
691                left = offset.left;
692                if (this.pickerPosition == 'bottom-left' || this.pickerPosition == 'top-left') {
693                    left += this.component.outerWidth() - this.picker.outerWidth();
694                }
695            } else {
696                offset = this.element.offset();
697                left = offset.left;
698            }
699            if (this.pickerPosition == 'top-left' || this.pickerPosition == 'top-right') {
700                top = offset.top - this.picker.outerHeight();
701            } else {
702                top = offset.top + this.height;
703            }
704            this.picker.css({
705                top: top,
706                left: left,
707                zIndex: zIndex
708            });
709        },
710        update: function () {
711            var date, fromArgs = false;
712            if (arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
713                date = arguments[0];
714                fromArgs = true;
715            } else {
716                date = this.element.data('date') || (this.isInput ? this.element.val() : this.element.find('input').val()) || this.initialDate;
717            }
718
719            if (!date) {
720                date = new Date();
721                fromArgs = false;
722            }
723
724            this.date = DPGlobal.parseDate(date, this.format, this.language, this.formatType);
725
726            if (fromArgs)
727                this.setValue();
728
729            if (this.date < this.startDate) {
730                this.viewDate = new Date(this.startDate);
731            } else if (this.date > this.endDate) {
732                this.viewDate = new Date(this.endDate);
733            } else {
734                this.viewDate = new Date(this.date);
735            }
736            this.fill();
737        },
738        fillDow: function () {
739            var dowCnt = this.weekStart,
740                html = '<tr>';
741            while (dowCnt < this.weekStart + 7) {
742                html += '<th class="dow">' + dates[this.language].daysMin[(dowCnt++) % 7] + '</th>';
743            }
744            html += '</tr>';
745            this.picker.find('.datetimepicker-days thead').append(html);
746        },
747        fillMonths: function () {
748            var html = '',
749                i = 0;
750            while (i < 12) {
751                html += '<span class="month">' + dates[this.language].monthsShort[i++] + '</span>';
752            }
753            this.picker.find('.datetimepicker-months td').html(html);
754        },
755        fill: function () {
756            if (this.date == null || this.viewDate == null) {
757                return;
758            }
759            var d = new Date(this.viewDate),
760                year = d.getUTCFullYear(),
761                month = d.getUTCMonth(),
762                dayMonth = d.getUTCDate(),
763                hours = d.getUTCHours(),
764                minutes = d.getUTCMinutes(),
765                startYear = this.startDate !== -Infinity ? this.startDate.getUTCFullYear() : -Infinity,
766                startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() : -Infinity,
767                endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity,
768                endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity,
769                currentDate = (new UTCDate(this.date.getUTCFullYear(), this.date.getUTCMonth(), this.date.getUTCDate())).valueOf(),
770                today = new Date();
771            this.picker.find('.datetimepicker-days thead th:eq(1)')
772                .text(dates[this.language].months[month] + ' ' + year);
773            if (this.formatViewType == "time") {
774                var hourConverted = hours % 12 ? hours % 12 : 12;
775                var hoursDisplay = (hourConverted < 10 ? '0' : '') + hourConverted;
776                var minutesDisplay = (minutes < 10 ? '0' : '') + minutes;
777                var meridianDisplay = dates[this.language].meridiem[hours < 12 ? 0 : 1];
778                this.picker.find('.datetimepicker-hours thead th:eq(1)')
779                    .text(hoursDisplay + ':' + minutesDisplay + ' ' + meridianDisplay.toUpperCase());
780                this.picker.find('.datetimepicker-minutes thead th:eq(1)')
781                    .text(hoursDisplay + ':' + minutesDisplay + ' ' + meridianDisplay.toUpperCase());
782            } else {
783                this.picker.find('.datetimepicker-hours thead th:eq(1)')
784                    .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);
785                this.picker.find('.datetimepicker-minutes thead th:eq(1)')
786                    .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);
787            }
788            this.picker.find('tfoot th.today')
789                .text(dates[this.language].today)
790                .toggle(this.todayBtn !== false);
791            this.updateNavArrows();
792            this.fillMonths();
793            /*var prevMonth = UTCDate(year, month, 0,0,0,0,0);
794             prevMonth.setUTCDate(prevMonth.getDate() - (prevMonth.getUTCDay() - this.weekStart + 7)%7);*/
795            var prevMonth = UTCDate(year, month - 1, 28, 0, 0, 0, 0),
796                day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
797            prevMonth.setUTCDate(day);
798            prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7);
799            var nextMonth = new Date(prevMonth);
800            nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
801            nextMonth = nextMonth.valueOf();
802            var html = [];
803            var clsName;
804            var aria_disabled = ' ';
805            while (prevMonth.valueOf() < nextMonth) {
806                aria_disabled = ' ';
807                if (prevMonth.getUTCDay() == this.weekStart) {
808                    html.push('<tr>');
809                }
810                clsName = '';
811                if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {
812                    clsName += ' old';
813                } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() > month)) {
814                    clsName += ' new';
815                }
816                // Compare internal UTC date with local today, not UTC today
817                if (this.todayHighlight &&
818                    prevMonth.getUTCFullYear() == today.getFullYear() &&
819                    prevMonth.getUTCMonth() == today.getMonth() &&
820                    prevMonth.getUTCDate() == today.getDate()) {
821                    clsName += ' today';
822                }
823                if (prevMonth.valueOf() == currentDate) {
824                    // clsName += ' active';
825                }
826                if ((prevMonth.valueOf() + 86400000) <= this.startDate || prevMonth.valueOf() > this.endDate ||
827                    $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1) {
828                    clsName += ' disabled';
829                    aria_disabled = ' aria-disabled="true" ';
830                }
831                //INICI MODIFICACIONS UBINTIA
832                //Només fem la comprovació si no té cap clase assignada
833                if ((clsName == '') || (clsName == ' new') || (clsName == ' old')) {
834                    if (this.visiblesOcupades == 0) { // Si no es veuen les cites ocupades
835                        if (this.activeDays.length > 0) { // Mostarem els dies amb cites
836                            var daySearch = DPGlobal.formatDate(prevMonth, DPGlobal.parseFormat("dd/mm/yyyy", this.formatType), this.language, this.formatType);
837                            //Si el dia esta dins l'array possem la clase per pertoca
838                            if ($.inArray(daySearch, this.activeDays) !== -1) { //Si el dia te cites
839                                clsName += ' ' + this.activeClass; //Possem les classes necessaries
840                            } else {
841                                //Sino esta dins l'array i ens han passat dies hem de desactivar-lo
842                                clsName += ' disabled';
843                                aria_disabled = ' aria-disabled="true" ';
844                            }
845                        }
846                    } else {
847                        if (this.totalDays.length > 0) { //Mirem tots els dies amb cites (ocupades o sense ocupar)
848                            var daySearch = DPGlobal.formatDate(prevMonth, DPGlobal.parseFormat("dd/mm/yyyy", this.formatType), this.language, this.formatType);
849                            //Si el dia esta dins l'array possem la clase per pertoca
850                            if ($.inArray(daySearch, this.activeDays) !== -1) {
851                                clsName += ' ' + this.activeClass;
852                            } else {
853                                if ($.inArray(daySearch, this.totalDays) !== -1) { //Sino esta dins l'array mirem si es que te les cites ocupades
854                                    clsName += ' sense_hores';
855                                } else { //Aquest dia no permet cites el desactivem
856                                    clsName += ' disabled';
857                                    aria_disabled = ' aria-disabled="true" ';
858                                }
859                            }
860                        }
861                    }
862
863                }
864                //FI MODIFICACIONS UBINTIA
865                var tabindex = 0;
866                if (clsName.includes("sense_hores") || clsName.includes("disabled")) {
867                    tabindex = -1;
868                }
869                html.push('<td tabindex="'+tabindex+'" class="day' + clsName + '" '+aria_disabled+' ><span class="day' + clsName + '" role="button">' + prevMonth.getUTCDate() + '</span></td>');
870                if (prevMonth.getUTCDay() == this.weekEnd) {
871                    html.push('</tr>');
872                }
873                prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
874            }
875            this.picker.find('.datetimepicker-days tbody').empty().append(html.join(''));
876
877            html = [];
878            var txt = '', meridian = '', meridianOld = '';
879            //INICI MODIFICACIONS UBINTIA
880            var daySearch = '';
881            var selfThis = this;
882            //Mirem si el viewMode és el d'hores
883            if ((this.viewMode == 1) && (daySearch == '') && (this.consultaHores == false)) {
884                this.consultaHores = true;
885                daySearch = DPGlobal.formatDate(this.viewDate, DPGlobal.parseFormat("yyyy-mm-dd", this.formatType), this.language, this.formatType);
886
887                $.ajax({
888                    type: "POST",
889                    async: false,
890                    url: this.urlWebService,
891                    dataType: "json",
892                    data: {
893                        t: "getIntervalHores",
894                        tramitacio: this.tramitacio,
895                        dia: daySearch,
896                        inici: this.dataInici,
897                        idioma: this.language,
898                        dia_cita: this.dia_cita
899                    },
900                    success: function (dades) {
901                        if (dades) {
902                            selfThis.activeHours = dades.nomesHoresLliures;
903                            selfThis.activeHoursMinutes = dades.horesLliures;
904                            selfThis.horariInicial = dades.horari.inicial;
905                            selfThis.horariFinal = dades.horari.final;
906                            selfThis.busyHours = dades.horesOcupades;
907                            selfThis.totalHours = dades.hores;
908                            selfThis.visiblesOcupades = dades.visible_ocupades;
909                            selfThis.totalHoursNumber = dades.total_hores;
910                            selfThis.totalHoursSenseMinuts = dades.hores_totals_sense_minuts;
911                            selfThis.missatgeHoresAgrupades = dades.missatgeHoresAgrupades;
912                            selfThis.missatgeHoresNoAgrupades = dades.missatgeHoresNoAgrupades;
913                            selfThis.missatgeHoresOcupades = dades.missatgeHoresOcupades;
914                            selfThis.missatgeFrangesOcupades = dades.missatgeFrangesOcupades;
915                        }
916                    }
917                });
918            }
919            if (this.viewMode == 1) {
920                /**
921                 * Només mostrem les hores disponibles amb l'array que d'hores que recuperem de la petició
922                 * web.
923                 */
924                /*
925                for(let i = 0; i < this.activeHours.length; i++) {
926                    clsName = ' ' + this.activeClass;
927                    txt = this.activeHours[i] + ':00';
928                    html.push('<span tabindex="0" class="hour' + clsName + '">' + txt + '</span>');
929                }
930                 */
931
932                /**
933                 for(let i = 0; i < this.activeHoursMinutes.length; i++) {
934                    clsName = ' ' + this.activeClass;
935                    txt = this.activeHoursMinutes[i];
936                    html.push('<span tabindex="0" class="minute' + clsName + '">' + txt + '</span>');
937                }
938                 */
939
940                if (this.totalHoursNumber > 50) { // Si hi ha moltes cites, mostrarem les hores i fent click els minuts
941                    this.leyenda_hores = '<span class=\'datepicker_actiu datepicker_actiu_text\'>___</span> ' + this.missatgeHoresAgrupades + '<br>';
942                    if (this.visiblesOcupades === '1') { //Mostrarem les cites ocupades
943                        this.leyenda_hores += '<span class=\'sense_hores sense_hores_text\'>___</span> ' + this.missatgeFrangesOcupades;
944                        html.push('<ul class="llista-hores">');
945                        for (let i = 0; i < this.totalHoursSenseMinuts.length; i++) { //Mostrem totes les hores
946                            txt = this.totalHoursSenseMinuts[i] + ':00'; //Creem el text del missatge
947                            if (this.activeHours.includes(this.totalHoursSenseMinuts[i])) { //Si l'hora té alguna cita disponible estarà en aciveHours
948                                clsName = ' ' + this.activeClass; //Posem les classes corresponents
949                                html.push('<li><span class="hour' + clsName + '" role="button" tabindex="0">' + txt + '</span></li>'); //Introduïm al final la hora corresponent
950                            } else {
951                                clsName = ' sense_hores'; //Posem el color grey pero fem que sigui clicable
952                                html.push('<li><span class="hour' + clsName + '">' + txt + '</span></li>'); //Introduïm al final la hora corresponent
953                            }
954                        }
955                        html.push('</ul>');
956                    } else {
957                        html.push('<ul class="llista-hores">');
958                        for (let i = 0; i < this.activeHours.length; i++) { //Mostrem nomes les hores que tenen cites disponibles
959                            clsName = ' ' + this.activeClass; //Posem les classes corresponents
960                            txt = this.activeHours[i] + ':00'; //Creem el missatge
961                            html.push('<li><span class="hour' + clsName + '" role="button" tabindex="0">' + txt + '</span></li>'); //Introduïm al final la hora corresponent
962                        }
963                        html.push('</ul>');
964                    }
965                    $("#infohores").html(this.leyenda_hores);
966                } else {
967                    this.leyenda_hores = '<span class=\'datepicker_actiu datepicker_actiu_text\'>___</span> ' + this.missatgeHoresNoAgrupades + '<br>';
968                    if (this.visiblesOcupades === '1') { //Mostrem les cites ocupades
969                        this.leyenda_hores += '<span class=\'busy_leyenda\'>___</span> ' + this.missatgeHoresOcupades;
970                        html.push('<ul class="llista-hores">');
971                        for (let i = 0; i < this.totalHours.length; i++) { //Mostrem totes les cites
972                            txt = this.totalHours[i]; //Creem el missatge
973                            if (this.activeHoursMinutes.includes(txt)) { //Si la cita está disponible
974                                clsName = ' ' + this.activeClass; //Introduïm les classes necessaries
975                                html.push('<li><span class="minute' + clsName + '" role="button" tabindex="0">' + txt + '</span></li>'); //Introduïm la cita al final
976                            } else {
977                                clsName = ' disabled'; //Desactivem les cites perqué no siguin clicables
978                                html.push('<li><span class="minute' + clsName + '">' + txt + '</span></li>'); //Introduïm la cita al final
979                            }
980                        }
981                        html.push('</ul>');
982                    } else {
983                        html.push('<ul class="llista-hores">');
984                        for (let i = 0; i < this.activeHoursMinutes.length; i++) { //Per cada hora amb cites disponibles
985                            clsName = ' ' + this.activeClass; //Introduïm les classes necessaries
986                            txt = this.activeHoursMinutes[i]; //Creem el missatge
987                            html.push('<li><span class="minute' + clsName + '" role="button" tabindex="0">' + txt + '</span></li>'); //Introduïm la cita al final
988                        }
989                        html.push('</ul>');
990                    }
991                    $("#infohores").html(this.leyenda_hores);
992                }
993
994                /**
995                 for(var i = 0; i < 24; i++) {
996                    var actual = UTCDate(year, month, dayMonth, i);
997                    clsName = '';
998                    // We want the previous hour for the startDate
999                    if((actual.valueOf() + 3600000) <= this.startDate || actual.valueOf() > this.endDate) {
1000                        clsName += ' disabled';
1001                    } else if(hours == i) {
1002                        // clsName += ' active';
1003                    }
1004                    //
1005                    if(this.showMeridian && dates[this.language].meridiem.length == 2) {
1006                        meridian = (i < 12? dates[this.language].meridiem[0] :dates[this.language].meridiem[1]);
1007                        if(meridian != meridianOld) {
1008                            if(meridianOld != '') {
1009                                html.push('</fieldset>');
1010                            }
1011                            html.push('<fieldset class="hour"><legend>' + meridian.toUpperCase() + '</legend>');
1012                        }
1013                        meridianOld = meridian;
1014                        txt = (i % 12? i % 12 :12);
1015                        //INICI MODIFICACIONS UBINTIA
1016                        html.push('<span tabindex="0" class="hour' + clsName + ' hour_' + (i < 12? 'am' :'pm') + '">' + txt + '</span>');
1017                        if(i == 23) {
1018                            html.push('</fieldset>');
1019                        }
1020                    } else {
1021                        txt = i + ':00';
1022                        //INICI MODIFICACIONS UBINTIA
1023                        var mostrar_hora = false;
1024                        //Només fem la comprovació si no té cap clase assignada
1025                        if(clsName == '') {
1026                            if(this.activeHours.length > 0) {
1027                                //Si la hora esta dins de l'array d'hores actives li canviem la classe
1028                                if($.inArray(String(i), this.activeHours) !== -1) {
1029                                    clsName += ' ' + this.activeClass;
1030                                    mostrar_hora = true;
1031                                } else {
1032                                    //Sino esta dins l'array i ens han passat dies hem de desactivar-lo
1033                                    clsName += ' disabled';
1034                                }
1035                            }
1036                        }
1037                        if((i >= this.horariInicial) && (i <= this.horariFinal)) {
1038                            if(mostrar_hora) {
1039                                html.push('<span tabindex="0" class="hour' + clsName + '">' + txt + '</span>');
1040                            }
1041                        }
1042                        //FI MODIFICACIONS UBINTIA
1043                    }
1044                } */
1045                //FI MODIFICACIONS UBINTIA
1046                this.picker.find('.datetimepicker-hours td').html(html.join(''));
1047            }
1048            if (this.viewMode == 0) {
1049                html = [];
1050                txt = '', meridian = '', meridianOld = '';
1051                //INICI MODIFICACIONS UBINTIA
1052                /**
1053                 * Només mostrem les hores que ens passen, d'aquesta manera concideix l'interval
1054                 * sinó ens trovavem que hi depenent de l'interval no es calculava correctament en
1055                 * el caledari
1056                 */
1057                this.leyenda_hores = '<span class=\'datepicker_actiu datepicker_actiu_text\'>___</span> ' + this.missatgeHoresNoAgrupades + '<br>';
1058                if (this.visiblesOcupades === '1') { //Si s'han de mostrar les cites ocupades
1059                    this.leyenda_hores += '<span class=\'busy_leyenda\'>___</span> ' + this.missatgeHoresOcupades;
1060                    html.push('<ul class="llista-hores">');
1061                    for (let i = 0; i < this.totalHours.length; i++) { //Mostrarem totes les hores
1062                        txt = this.totalHours[i]; //Creem el text de la hora
1063                        if (this.activeHoursMinutes.includes(txt)) { //Si hi ha cites en aquesta hora
1064                            clsName = ' ' + this.activeClass; //Indiquem les classes necessaries
1065                            let hora = txt.split(":"); //Mirem si la cita és de l'hora que hem clicat
1066                            if (parseInt(hora[0], 10) === hours) {
1067                                html.push('<span class="minute' + clsName + '" role="button" tabindex="0">' + txt + '</span>'); //Introduïm la cita al final
1068                            }
1069                        } else {
1070                            clsName = ' disabled'; //Indiquem que la cita no es clicable
1071                            let hora = txt.split(":"); //Mirem si la cita és de l'hora que hem clicat
1072                            if (parseInt(hora[0], 10) === hours) {
1073                                html.push('<span class="minute' + clsName + '"  role="button" tabindex="-1">' + txt + '</span>'); //Introduïm la cita al final
1074                            }
1075                        }
1076                    }
1077                    html.push('</ul>');
1078                } else {
1079                    html.push('<ul class="llista-hores">');
1080                    for (let i = 0; i < this.activeHoursMinutes.length; i++) { //Mostem totes les hores amb cites
1081                        clsName = ' ' + this.activeClass; //Introduïm les classes necessaries
1082                        txt = this.activeHoursMinutes[i]; //Introduïm el text
1083                        //Només hem de mostrar l'hora que ens han clickat
1084                        let hora = txt.split(":");
1085                        if (parseInt(hora[0], 10) === hours) {
1086                            html.push('<span class="minute' + clsName + '" role="button" tabindex="0">' + txt + '</span>'); //Introduïm la cita al final
1087                        }
1088                    }
1089                    html.push('</ul>');
1090                }
1091                $("#infohores").html(this.leyenda_hores);
1092
1093
1094                /**
1095                 for(var i = 0; i < 60; i += this.minuteStep) {
1096                    var actual = UTCDate(year, month, dayMonth, hours, i, 0);
1097                    clsName = '';
1098                    if(actual.valueOf() < this.startDate || actual.valueOf() > this.endDate) {
1099                        clsName += ' disabled';
1100                    } else if(Math.floor(minutes / this.minuteStep) == Math.floor(i / this.minuteStep)) {
1101                        //  clsName += ' active';
1102                    }
1103                    if(this.showMeridian && dates[this.language].meridiem.length == 2) {
1104                        meridian = (hours < 12? dates[this.language].meridiem[0] :dates[this.language].meridiem[1]);
1105                        if(meridian != meridianOld) {
1106                            if(meridianOld != '') {
1107                                html.push('</fieldset>');
1108                            }
1109                            html.push('<fieldset class="minute"><legend>' + meridian.toUpperCase() + '</legend>');
1110                        }
1111                        meridianOld = meridian;
1112                        txt = (hours % 12? hours % 12 :12);
1113                        //html.push('<span class="minute'+clsName+' minute_'+(hours<12?'am':'pm')+'">'+txt+'</span>');
1114                        html.push('<span tabindex="0" class="minute' + clsName + '">' + txt + ':' + (i < 10? '0' + i :i) + '</span>');
1115                        if(i == 59) {
1116                            html.push('</fieldset>');
1117                        }
1118                    } else {
1119                        txt = hours + ':' + (i < 10? '0' + i :i);
1120                        var mostrar = false;
1121                        //INICI MODIFICACIONS UBINTIA
1122                        //Només fem la comprovació si no té cap clase assignada
1123                        if(clsName == '') {
1124                            if(this.activeHoursMinutes.length > 0) {
1125                                //Si el dia esta dins l'array possem la clase per pertoca
1126                                if($.inArray(txt, this.activeHoursMinutes) !== -1) {
1127                                    clsName += ' ' + this.activeClass;
1128                                    mostrar = true;
1129                                } else {
1130                                    //Sino esta dins l'array i ens han passat dies hem de desactivar-lo
1131                                    clsName += ' disabled';
1132                                }
1133                            }
1134                        }
1135                        if(mostrar) {
1136                            //Només mostrem les hores que estan lliures
1137                            html.push('<span tabindex="0" class="minute' + clsName + '">' + txt + '</span>');
1138                        }
1139                        //FI MODIFICACIONS UBINTIA
1140                    }
1141                }*/
1142                //FI MODIFICACIONS UBINTIA
1143                this.picker.find('.datetimepicker-minutes td').html(html.join(''));
1144            }
1145
1146            var currentYear = this.date.getUTCFullYear();
1147            var months = this.picker.find('.datetimepicker-months')
1148                .find('th:eq(1)')
1149                .text(year)
1150                .end()
1151                .find('span').removeClass('active');
1152            if (currentYear == year) {
1153                months.eq(this.date.getUTCMonth()).addClass('active');
1154            }
1155            if (year < startYear || year > endYear) {
1156                months.addClass('disabled');
1157            }
1158            if (year == startYear) {
1159                months.slice(0, startMonth).addClass('disabled');
1160            }
1161            if (year == endYear) {
1162                months.slice(endMonth + 1).addClass('disabled');
1163            }
1164
1165            html = '';
1166            year = parseInt(year / 10, 10) * 10;
1167            var yearCont = this.picker.find('.datetimepicker-years')
1168                .find('th:eq(1)')
1169                .text(year + '-' + (year + 9))
1170                .end()
1171                .find('td');
1172            year -= 1;
1173            for (var i = -1; i < 11; i++) {
1174                html += '<span class="year' + (i == -1 || i == 10 ? ' old' : '') + (currentYear == year ? ' active' : '') + (year < startYear || year > endYear ? ' disabled' : '') + '">' + year + '</span>';
1175                year += 1;
1176            }
1177            yearCont.html(html);
1178            this.place();
1179        },
1180        updateNavArrows: function () {
1181            var d = new Date(this.viewDate),
1182                year = d.getUTCFullYear(),
1183                month = d.getUTCMonth(),
1184                day = d.getUTCDate(),
1185                hour = d.getUTCHours();
1186            switch (this.viewMode) {
1187                case 0:
1188                    if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
1189                        && month <= this.startDate.getUTCMonth()
1190                        && day <= this.startDate.getUTCDate()
1191                        && hour <= this.startDate.getUTCHours()) {
1192                        this.picker.find('.prev').css({visibility: 'hidden'});
1193                    } else {
1194                        this.picker.find('.prev').css({visibility: 'visible'});
1195                    }
1196                    if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
1197                        && month >= this.endDate.getUTCMonth()
1198                        && day >= this.endDate.getUTCDate()
1199                        && hour >= this.endDate.getUTCHours()) {
1200                        this.picker.find('.next').css({visibility: 'hidden'});
1201                    } else {
1202                        this.picker.find('.next').css({visibility: 'visible'});
1203                    }
1204                    //MODIFICACIONS UBINTIA
1205                    this.picker.find('.prev').css({visibility: 'hidden'});
1206                    this.picker.find('.next').css({visibility: 'hidden'});
1207                    break;
1208                case 1:
1209                    if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
1210                        && month <= this.startDate.getUTCMonth()
1211                        && day <= this.startDate.getUTCDate()) {
1212                        this.picker.find('.prev').css({visibility: 'hidden'});
1213                    } else {
1214                        this.picker.find('.prev').css({visibility: 'visible'});
1215                    }
1216                    if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
1217                        && month >= this.endDate.getUTCMonth()
1218                        && day >= this.endDate.getUTCDate()) {
1219                        this.picker.find('.next').css({visibility: 'hidden'});
1220                    } else {
1221                        this.picker.find('.next').css({visibility: 'visible'});
1222                    }
1223                    //MODIFICACIONS UBINTIA
1224                    this.picker.find('.prev').css({visibility: 'hidden'});
1225                    this.picker.find('.next').css({visibility: 'hidden'});
1226                    break;
1227                case 2:
1228                    if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
1229                        && month <= this.startDate.getUTCMonth()) {
1230                        this.picker.find('.prev').css({visibility: 'hidden'});
1231                    } else {
1232                        this.picker.find('.prev').css({visibility: 'visible'});
1233                    }
1234                    if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
1235                        && month >= this.endDate.getUTCMonth()) {
1236                        this.picker.find('.next').css({visibility: 'hidden'});
1237                    } else {
1238                        this.picker.find('.next').css({visibility: 'visible'});
1239                    }
1240                    break;
1241                case 3:
1242                case 4:
1243                    if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()) {
1244                        this.picker.find('.prev').css({visibility: 'hidden'});
1245                    } else {
1246                        this.picker.find('.prev').css({visibility: 'visible'});
1247                    }
1248                    if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()) {
1249                        this.picker.find('.next').css({visibility: 'hidden'});
1250                    } else {
1251                        this.picker.find('.next').css({visibility: 'visible'});
1252                    }
1253                    break;
1254            }
1255        },
1256        mousewheel: function (e) {
1257
1258            e.preventDefault();
1259            e.stopPropagation();
1260
1261            if (this.wheelPause) {
1262                return;
1263            }
1264
1265            this.wheelPause = true;
1266
1267            var originalEvent = e.originalEvent;
1268
1269            var delta = originalEvent.wheelDelta;
1270
1271            var mode = delta > 0 ? 1 : (delta === 0) ? 0 : -1;
1272
1273            if (this.wheelViewModeNavigationInverseDirection) {
1274                mode = -mode;
1275            }
1276
1277            this.showMode(mode);
1278
1279            setTimeout($.proxy(function () {
1280
1281                this.wheelPause = false
1282
1283            }, this), this.wheelViewModeNavigationDelay);
1284
1285
1286        },
1287        click: function (e) {
1288            e.stopPropagation();
1289            e.preventDefault();
1290            selectDay(e, this);
1291        },
1292        _setDate: function (date, which) {
1293            if (!which || which == 'date')
1294                this.date = date;
1295            if (!which || which == 'view')
1296                this.viewDate = date;
1297            this.fill();
1298            this.setValue();
1299            var element;
1300            if (this.isInput) {
1301                element = this.element;
1302            } else if (this.component) {
1303                element = this.element.find('input');
1304            }
1305            if (element) {
1306                element.change();
1307                if (this.autoclose && (!which || which == 'date')) {
1308                    //this.hide();
1309                }
1310            }
1311            this.element.trigger({
1312                type: 'changeDate',
1313                date: this.date
1314            });
1315            this.element.trigger({
1316                type: 'enterDate',
1317                date: this.date
1318            });
1319        },
1320        moveMinute: function (date, dir) {
1321            if (!dir)
1322                return date;
1323            var new_date = new Date(date.valueOf());
1324            //dir = dir > 0 ? 1 : -1;
1325            new_date.setUTCMinutes(new_date.getUTCMinutes() + (dir * this.minuteStep));
1326            return new_date;
1327        },
1328        moveHour: function (date, dir) {
1329            if (!dir)
1330                return date;
1331            var new_date = new Date(date.valueOf());
1332            //dir = dir > 0 ? 1 : -1;
1333            new_date.setUTCHours(new_date.getUTCHours() + dir);
1334            return new_date;
1335        },
1336        moveDate: function (date, dir) {
1337            if (!dir)
1338                return date;
1339            var new_date = new Date(date.valueOf());
1340            //dir = dir > 0 ? 1 : -1;
1341            new_date.setUTCDate(new_date.getUTCDate() + dir);
1342            return new_date;
1343        },
1344        moveMonth: function (date, dir) {
1345            if (!dir)
1346                return date;
1347            var new_date = new Date(date.valueOf()),
1348                day = new_date.getUTCDate(),
1349                month = new_date.getUTCMonth(),
1350                mag = Math.abs(dir),
1351                new_month, test;
1352            dir = dir > 0 ? 1 : -1;
1353            if (mag == 1) {
1354                test = dir == -1
1355                    // If going back one month, make sure month is not current month
1356                    // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
1357                    ? function () {
1358                        return new_date.getUTCMonth() == month;
1359                    }
1360                    // If going forward one month, make sure month is as expected
1361                    // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
1362                    : function () {
1363                        return new_date.getUTCMonth() != new_month;
1364                    };
1365                new_month = month + dir;
1366                new_date.setUTCMonth(new_month);
1367                // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
1368                if (new_month < 0 || new_month > 11)
1369                    new_month = (new_month + 12) % 12;
1370            } else {
1371                // For magnitudes >1, move one month at a time...
1372                for (var i = 0; i < mag; i++)
1373                    // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
1374                    new_date = this.moveMonth(new_date, dir);
1375                // ...then reset the day, keeping it in the new month
1376                new_month = new_date.getUTCMonth();
1377                new_date.setUTCDate(day);
1378                test = function () {
1379                    return new_month != new_date.getUTCMonth();
1380                };
1381            }
1382            // Common date-resetting loop -- if date is beyond end of month, make it
1383            // end of month
1384            while (test()) {
1385                new_date.setUTCDate(--day);
1386                new_date.setUTCMonth(new_month);
1387            }
1388            return new_date;
1389        },
1390        moveYear: function (date, dir) {
1391            return this.moveMonth(date, dir * 12);
1392        },
1393        dateWithinRange: function (date) {
1394            return date >= this.startDate && date <= this.endDate;
1395        },
1396        keydown: function (e) {
1397            if (this.picker.is(':not(:visible)')) {
1398                if (e.keyCode == 27) // allow escape to hide and re-show picker
1399                    this.show();
1400                return;
1401            }
1402            var dateChanged = false,
1403                dir, day, month,
1404                newDate, newViewDate;
1405            switch (e.key) {
1406                case 27: // escape
1407                    this.hide();
1408                    e.preventDefault();
1409                    break;
1410                case 37: // left
1411                case 39: // right
1412                    if (!this.keyboardNavigation)
1413                        break;
1414                    dir = e.keyCode == 37 ? -1 : 1;
1415                    viewMode = this.viewMode;
1416                    if (e.ctrlKey) {
1417                        viewMode += 2;
1418                    } else if (e.shiftKey) {
1419                        viewMode += 1;
1420                    }
1421                    if (viewMode == 4) {
1422                        newDate = this.moveYear(this.date, dir);
1423                        newViewDate = this.moveYear(this.viewDate, dir);
1424                    } else if (viewMode == 3) {
1425                        newDate = this.moveMonth(this.date, dir);
1426                        newViewDate = this.moveMonth(this.viewDate, dir);
1427                    } else if (viewMode == 2) {
1428                        newDate = this.moveDate(this.date, dir);
1429                        newViewDate = this.moveDate(this.viewDate, dir);
1430                    } else if (viewMode == 1) {
1431                        newDate = this.moveHour(this.date, dir);
1432                        newViewDate = this.moveHour(this.viewDate, dir);
1433                    } else if (viewMode == 0) {
1434                        newDate = this.moveMinute(this.date, dir);
1435                        newViewDate = this.moveMinute(this.viewDate, dir);
1436                    }
1437                    if (this.dateWithinRange(newDate)) {
1438                        this.date = newDate;
1439                        this.viewDate = newViewDate;
1440                        this.setValue();
1441                        this.update();
1442                        e.preventDefault();
1443                        dateChanged = true;
1444                    }
1445                    break;
1446                case 38: // up
1447                case 40: // down
1448                    if (!this.keyboardNavigation)
1449                        break;
1450                    dir = e.keyCode == 38 ? -1 : 1;
1451                    viewMode = this.viewMode;
1452                    if (e.ctrlKey) {
1453                        viewMode += 2;
1454                    } else if (e.shiftKey) {
1455                        viewMode += 1;
1456                    }
1457                    if (viewMode == 4) {
1458                        newDate = this.moveYear(this.date, dir);
1459                        newViewDate = this.moveYear(this.viewDate, dir);
1460                    } else if (viewMode == 3) {
1461                        newDate = this.moveMonth(this.date, dir);
1462                        newViewDate = this.moveMonth(this.viewDate, dir);
1463                    } else if (viewMode == 2) {
1464                        newDate = this.moveDate(this.date, dir * 7);
1465                        newViewDate = this.moveDate(this.viewDate, dir * 7);
1466                    } else if (viewMode == 1) {
1467                        if (this.showMeridian) {
1468                            newDate = this.moveHour(this.date, dir * 6);
1469                            newViewDate = this.moveHour(this.viewDate, dir * 6);
1470                        } else {
1471                            newDate = this.moveHour(this.date, dir * 4);
1472                            newViewDate = this.moveHour(this.viewDate, dir * 4);
1473                        }
1474                    } else if (viewMode == 0) {
1475                        newDate = this.moveMinute(this.date, dir * 4);
1476                        newViewDate = this.moveMinute(this.viewDate, dir * 4);
1477                    }
1478                    if (this.dateWithinRange(newDate)) {
1479                        this.date = newDate;
1480                        this.viewDate = newViewDate;
1481                        this.setValue();
1482                        this.update();
1483                        e.preventDefault();
1484                        dateChanged = true;
1485                    }
1486                    break;
1487                case 13: // enter
1488                case 'Enter':
1489                    if (this.viewMode != 0) {
1490                        selectDay(e, this);
1491                    } else {
1492                        this.fill();
1493                        if (this.autoclose) {
1494                            this.hide();
1495                        }
1496                    }
1497                    e.preventDefault();
1498                    break;
1499                case 9: // tab
1500                    this.hide();
1501                    break;
1502            }
1503            if (dateChanged) {
1504                var element;
1505                if (this.isInput) {
1506                    element = this.element;
1507                } else if (this.component) {
1508                    element = this.element.find('input');
1509                }
1510                if (element) {
1511                    element.change();
1512                }
1513                this.element.trigger({
1514                    type: 'changeDate',
1515                    date: this.date
1516                });
1517            }
1518        },
1519        showMode: function (dir) {
1520            if (dir) {
1521                var newViewMode = Math.max(0, Math.min(DPGlobal.modes.length - 1, this.viewMode + dir));
1522                if (newViewMode >= this.minView && newViewMode <= this.maxView) {
1523                    this.element.trigger({
1524                        type: 'changeMode',
1525                        date: this.viewDate,
1526                        oldViewMode: this.viewMode,
1527                        newViewMode: newViewMode
1528                    });
1529
1530                    this.viewMode = newViewMode;
1531                }
1532            }
1533            /*
1534             vitalets: fixing bug of very special conditions:
1535             jquery 1.7.1 + webkit + show inline datetimepicker in bootstrap popover.
1536             Method show() does not set display css correctly and datetimepicker is not shown.
1537             Changed to .css('display', 'block') solve the problem.
1538             See https://github.com/vitalets/x-editable/issues/37
1539
1540             In jquery 1.7.2+ everything works fine.
1541             */
1542            //this.picker.find('>div').hide().filter('.datetimepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
1543            this.picker.find('>div').hide().filter('.datetimepicker-' + DPGlobal.modes[this.viewMode].clsName).css('display', 'block');
1544            this.updateNavArrows();
1545        },
1546        reset: function (e) {
1547            this._setDate(null, 'date');
1548        }
1549    };
1550
1551    $.fn.datetimepicker = function (option) {
1552        var args = Array.apply(null, arguments);
1553        args.shift();
1554        return this.each(function () {
1555            var $this = $(this),
1556                data = $this.data('datetimepicker'),
1557                options = typeof option == 'object' && option;
1558            if (!data) {
1559                $this.data('datetimepicker', (data = new Datetimepicker(this, $.extend({}, $.fn.datetimepicker.defaults, options))));
1560            }
1561            if (typeof option == 'string' && typeof data[option] == 'function') {
1562                data[option].apply(data, args);
1563            }
1564        });
1565    };
1566
1567    $.fn.datetimepicker.defaults = {};
1568    $.fn.datetimepicker.Constructor = Datetimepicker;
1569    var dates = $.fn.datetimepicker.dates = {
1570        en: {
1571            days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
1572            daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
1573            daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
1574            months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
1574November", "December"],
1575            monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1576            meridiem: ["am", "pm"],
1577            suffix: ["st", "nd", "rd", "th"],
1578            today: "Today"
1579        }
1580    };
1581
1582    var DPGlobal = {
1583        modes: [
1584            {
1585                clsName: 'minutes',
1586                navFnc: 'Hours',
1587                navStep: 1
1588            },
1589            {
1590                clsName: 'hours',
1591                navFnc: 'Date',
1592                navStep: 1
1593            },
1594            {
1595                clsName: 'days',
1596                navFnc: 'Month',
1597                navStep: 1
1598            },
1599            {
1600                clsName: 'months',
1601                navFnc: 'FullYear',
1602                navStep: 1
1603            },
1604            {
1605                clsName: 'years',
1606                navFnc: 'FullYear',
1607                navStep: 10
1608            }],
1609        isLeapYear: function (year) {
1610            return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
1611        },
1612        getDaysInMonth: function (year, month) {
1613            return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
1614        },
1615        getDefaultFormat: function (type, field) {
1616            if (type == "standard") {
1617                if (field == 'input')
1618                    return 'yyyy-mm-dd hh:ii';
1619                else
1620                    return 'yyyy-mm-dd hh:ii:ss';
1621            } else if (type == "php") {
1622                if (field == 'input')
1623                    return 'Y-m-d H:i';
1624                else
1625                    return 'Y-m-d H:i:s';
1626            } else {
1627                throw new Error("Invalid format type.");
1628            }
1629        },
1630        validParts: function (type) {
1631            if (type == "standard") {
1632                return /hh?|HH?|p|P|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g;
1633            } else if (type == "php") {
1634                return /[dDjlNwzFmMnStyYaABgGhHis]/g;
1635            } else {
1636                throw new Error("Invalid format type.");
1637            }
1638        },
1639        nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,
1640        parseFormat: function (format, type) {
1641            // IE treats \0 as a string end in inputs (truncating the value),
1642            // so it's a bad format delimiter, anyway
1643            var separators = format.replace(this.validParts(type), '\0').split('\0'),
1644                parts = format.match(this.validParts(type));
1645            if (!separators || !separators.length || !parts || parts.length == 0) {
1646                throw new Error("Invalid date format.");
1647            }
1648            return {separators: separators, parts: parts};
1649        },
1650        parseDate: function (date, format, language, type) {
1651            if (date instanceof Date) {
1652                var dateUTC = new Date(date.valueOf() - date.getTimezoneOffset() * 60000);
1653                dateUTC.setMilliseconds(0);
1654                return dateUTC;
1655            }
1656            if (/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(date)) {
1657                format = this.parseFormat('yyyy-mm-dd', type);
1658            }
1659            if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(date)) {
1660                format = this.parseFormat('yyyy-mm-dd hh:ii', type);
1661            }
1662            if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(date)) {
1663                format = this.parseFormat('yyyy-mm-dd hh:ii:ss', type);
1664            }
1665            if (/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(date)) {
1666                var part_re = /([-+]\d+)([dmwy])/,
1667                    parts = date.match(/([-+]\d+)([dmwy])/g),
1668                    part, dir;
1669                date = new Date();
1670                for (var i = 0; i < parts.length; i++) {
1671                    part = part_re.exec(parts[i]);
1672                    dir = parseInt(part[1]);
1673                    switch (part[2]) {
1674                        case 'd':
1675                            date.setUTCDate(date.getUTCDate() + dir);
1676                            break;
1677                        case 'm':
1678                            date = Datetimepicker.prototype.moveMonth.call(Datetimepicker.prototype, date, dir);
1679                            break;
1680                        case 'w':
1681                            date.setUTCDate(date.getUTCDate() + dir * 7);
1682                            break;
1683                        case 'y':
1684                            date = Datetimepicker.prototype.moveYear.call(Datetimepicker.prototype, date, dir);
1685                            break;
1686                    }
1687                }
1688                return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), 0);
1689            }
1690            var parts = date && date.match(this.nonpunctuation) || [],
1691                date = new Date(0, 0, 0, 0, 0, 0, 0),
1692                parsed = {},
1693                setters_order = ['hh', 'h', 'ii', 'i', 'ss', 's', 'yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'D', 'DD', 'd', 'dd', 'H', 'HH', 'p', 'P'],
1694                setters_map = {
1695                    hh: function (d, v) {
1696                        return d.setUTCHours(v);
1697                    },
1698                    h: function (d, v) {
1699                        return d.setUTCHours(v);
1700                    },
1701                    HH: function (d, v) {
1702                        return d.setUTCHours(v == 12 ? 0 : v);
1703                    },
1704                    H: function (d, v) {
1705                        return d.setUTCHours(v == 12 ? 0 : v);
1706                    },
1707                    ii: function (d, v) {
1708                        return d.setUTCMinutes(v);
1709                    },
1710                    i: function (d, v) {
1711                        return d.setUTCMinutes(v);
1712                    },
1713                    ss: function (d, v) {
1714                        return d.setUTCSeconds(v);
1715                    },
1716                    s: function (d, v) {
1717                        return d.setUTCSeconds(v);
1718                    },
1719                    yyyy: function (d, v) {
1720                        return d.setUTCFullYear(v);
1721                    },
1722                    yy: function (d, v) {
1723                        return d.setUTCFullYear(2000 + v);
1724                    },
1725                    m: function (d, v) {
1726                        v -= 1;
1727                        while (v < 0)
1728                            v += 12;
1729                        v %= 12;
1730                        d.setUTCMonth(v);
1731                        while (d.getUTCMonth() != v)
1732                            d.setUTCDate(d.getUTCDate() - 1);
1733                        return d;
1734                    },
1735                    d: function (d, v) {
1736                        return d.setUTCDate(v);
1737                    },
1738                    p: function (d, v) {
1739                        return d.setUTCHours(v == 1 ? d.getUTCHours() + 12 : d.getUTCHours());
1740                    }
1741                },
1742                val, filtered, part;
1743            setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1744            setters_map['dd'] = setters_map['d'];
1745            setters_map['P'] = setters_map['p'];
1746            date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
1747            if (parts.length == format.parts.length) {
1748                for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
1749                    val = parseInt(parts[i], 10);
1750                    part = format.parts[i];
1751                    if (isNaN(val)) {
1752                        switch (part) {
1753                            case 'MM':
1754                                filtered = $(dates[language].months).filter(function () {
1755                                    var m = this.slice(0, parts[i].length),
1756                                        p = parts[i].slice(0, m.length);
1757                                    return m == p;
1758                                });
1759                                val = $.inArray(filtered[0], dates[language].months) + 1;
1760                                break;
1761                            case 'M':
1762                                filtered = $(dates[language].monthsShort).filter(function () {
1763                                    var m = this.slice(0, parts[i].length),
1764                                        p = parts[i].slice(0, m.length);
1765                                    return m == p;
1766                                });
1767                                val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
1768                                break;
1769                            case 'p':
1770                            case 'P':
1771                                val = $.inArray(parts[i].toLowerCase(), dates[language].meridiem);
1772                                break;
1773                        }
1774                    }
1775                    parsed[part] = val;
1776                }
1777                for (var i = 0, s; i < setters_order.length; i++) {
1778                    s = setters_order[i];
1779                    if (s in parsed && !isNaN(parsed[s]))
1780                        setters_map[s](date, parsed[s])
1781                }
1782            }
1783            return date;
1784        },
1785        formatDate: function (date, format, language, type) {
1786            if (date == null) {
1787                return '';
1788            }
1789            var val;
1790            if (type == 'standard') {
1791                val = {
1792                    // year
1793                    yy: date.getUTCFullYear().toString().substring(2),
1794                    yyyy: date.getUTCFullYear(),
1795                    // month
1796                    m: date.getUTCMonth() + 1,
1797                    M: dates[language].monthsShort[date.getUTCMonth()],
1798                    MM: dates[language].months[date.getUTCMonth()],
1799                    // day
1800                    d: date.getUTCDate(),
1801                    D: dates[language].daysShort[date.getUTCDay()],
1802                    DD: dates[language].days[date.getUTCDay()],
1803                    p: (dates[language].meridiem.length == 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),
1804                    // hour
1805                    h: date.getUTCHours(),
1806                    // minute
1807                    i: date.getUTCMinutes(),
1808                    // second
1809                    s: date.getUTCSeconds()
1810                };
1811                val.H = (val.h % 12 == 0 ? 12 : val.h % 12);
1812                val.HH = (val.H < 10 ? '0' : '') + val.H;
1813                val.P = val.p.toUpperCase();
1814                val.hh = (val.h < 10 ? '0' : '') + val.h;
1815                val.ii = (val.i < 10 ? '0' : '') + val.i;
1816                val.ss = (val.s < 10 ? '0' : '') + val.s;
1817                val.dd = (val.d < 10 ? '0' : '') + val.d;
1818                val.mm = (val.m < 10 ? '0' : '') + val.m;
1819            } else if (type == 'php') {
1820                // php format
1821                val = {
1822                    // year
1823                    y: date.getUTCFullYear().toString().substring(2),
1824                    Y: date.getUTCFullYear(),
1825                    // month
1826                    F: dates[language].months[date.getUTCMonth()],
1827                    M: dates[language].monthsShort[date.getUTCMonth()],
1828                    n: date.getUTCMonth() + 1,
1829                    t: DPGlobal.getDaysInMonth(date.getUTCFullYear(), date.getUTCMonth()),
1830                    // day
1831                    j: date.getUTCDate(),
1832                    l: dates[language].days[date.getUTCDay()],
1833                    D: dates[language].daysShort[date.getUTCDay()],
1834                    w: date.getUTCDay(), // 0 -> 6
1835                    N: (date.getUTCDay() == 0 ? 7 : date.getUTCDay()), // 1 -> 7
1836                    S: (date.getUTCDate() % 10 <= dates[language].suffix.length ? dates[language].suffix[date.getUTCDate() % 10 - 1] : ''),
1837                    // hour
1838                    a: (dates[language].meridiem.length == 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),
1839                    g: (date.getUTCHours() % 12 == 0 ? 12 : date.getUTCHours() % 12),
1840                    G: date.getUTCHours(),
1841                    // minute
1842                    i: date.getUTCMinutes(),
1843                    // second
1844                    s: date.getUTCSeconds()
1845                };
1846                val.m = (val.n < 10 ? '0' : '') + val.n;
1847                val.d = (val.j < 10 ? '0' : '') + val.j;
1848                val.A = val.a.toString().toUpperCase();
1849                val.h = (val.g < 10 ? '0' : '') + val.g;
1850                val.H = (val.G < 10 ? '0' : '') + val.G;
1851                val.i = (val.i < 10 ? '0' : '') + val.i;
1852                val.s = (val.s < 10 ? '0' : '') + val.s;
1853            } else {
1854                throw new Error("Invalid format type.");
1855            }
1856            var date = [],
1857                seps = $.extend([], format.separators);
1858            for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
1859                if (seps.length)
1860                    date.push(seps.shift())
1861                date.push(val[format.parts[i]]);
1862            }
1863            return date.join('');
1864        },
1865        convertViewMode: function (viewMode) {
1866            switch (viewMode) {
1867                case 4:
1868                case 'decade':
1869                    viewMode = 4;
1870                    break;
1871                case 3:
1872                case 'year':
1873                    viewMode = 3;
1874                    break;
1875                case 2:
1876                case 'month':
1877                    viewMode = 2;
1878                    break;
1879                case 1:
1880                case 'day':
1881                    viewMode = 1;
1882                    break;
1883                case 0:
1884                case 'hour':
1885                    viewMode = 0;
1886                    break;
1887            }
1888
1889            return viewMode;
1890        },
1891        headTemplate: '<thead>' +
1892            '<tr>' +
1893            '<th class="prev" tabindex="0" role="button"><span style="display: none">Previous month</span><i title="Previous month" class="fa fa-angle-left"/></th>' +
1894            '<th colspan="5" class="switch"></th>' +
1895            '<th class="next" tabindex="0"  role="button"><span style="display: none">Next month</span><i title="Next month" class="fa fa-angle-right"/></th>' +
1896            '</tr>' +
1897            '</thead>',
1898        contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1899        footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'
1900    };
1901    DPGlobal.template = '<div class="datetimepicker">' +
1902        '<div class="datetimepicker-minutes">' +
1903        '<table class=" table-condensed">' +
1904        DPGlobal.headTemplate +
1905        DPGlobal.contTemplate +
1906        DPGlobal.footTemplate +
1907        '</table>' +
1908        '</div>' +
1909        '<div class="datetimepicker-hours">' +
1910        '<table class=" table-condensed">' +
1911        DPGlobal.headTemplate +
1912        DPGlobal.contTemplate +
1913        DPGlobal.footTemplate +
1914        '</table>' +
1915        '</div>' +
1916        '<div class="datetimepicker-days">' +
1917        '<table class=" table-condensed">' +
1918        DPGlobal.headTemplate +
1919        '<tbody></tbody>' +
1920        DPGlobal.footTemplate +
1921        '</table>' +
1922        '</div>' +
1923        '<div class="datetimepicker-months">' +
1924        '<table class="table-condensed">' +
1925        DPGlobal.headTemplate +
1926        DPGlobal.contTemplate +
1927        DPGlobal.footTemplate +
1928        '</table>' +
1929        '</div>' +
1930        '<div class="datetimepicker-years">' +
1931        '<table class="table-condensed">' +
1932        DPGlobal.headTemplate +
1933        DPGlobal.contTemplate +
1934        DPGlobal.footTemplate +
1935        '</table>' +
1936        '</div>' +
1937        '</div>';
1938
1939    $.fn.datetimepicker.DPGlobal = DPGlobal;
1940
1941
1942    /* DATETIMEPICKER NO CONFLICT
1943     * =================== */
1944
1945    $.fn.datetimepicker.noConflict = function () {
1946        $.fn.datetimepicker = old;
1947        return this;
1948    };
1949
1950
1951    /* DATETIMEPICKER DATA-API
1952     * ================== */
1953
1954    $(document).on(
1955        'focus.datetimepicker.data-api click.datetimepicker.data-api',
1956        '[data-provide="datetimepicker"]',
1957        function (e) {
1958            var $this = $(this);
1959            if ($this.data('datetimepicker'))
1960                return;
1961            e.preventDefault();
1962            // component click requires us to explicitly show it
1963            $this.datetimepicker('show');
1964        }
1965    );
1966    $(function () {
1967        $('[data-provide="datetimepicker-inline"]').datetimepicker();
1968    });
1969
1970}(window.jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.