PageSourceSearch

https://coral-squirrel-627945.hostingersite.com/wp-content/plugins…-booking-plugin-pro-cc/js/salon.js?ver=10.5

js coral-squirrel-627945.hostingersite.com collected 2026-10-03 04:15:50 UTC 85,041 bytes, 2,268 lines download raw bytes

1"use strict";
2
3Number.prototype.formatMoney = function(c, d, t) {
4    var n = this,
5        c = isNaN((c = Math.abs(c))) ? 2 : c,
6        d = d == undefined ? "." : d,
7        t = t == undefined ? "," : t,
8        s = n < 0 ? "-" : "",
9        i = parseInt((n = Math.abs(+n || 0).toFixed(c))) + "",
10        j = (j = i.length) > 3 ? j % 3 : 0;
11    return (
12        s +
13        (j ? i.substr(0, j) + t : "") +
14        i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) +
15        (c
16            ? d +
17              Math.abs(n - i)
18                  .toFixed(c)
19                  .slice(2)
20            : "")
21    );
22};
23
24jQuery(function($) {
25    sln_init($);
26    if (salon.has_stockholm_transition == "yes") {
27        $("body").on(
28            "click",
29            'a[target!="_blank"]:not(.no_ajax):not(.no_link)',
30            function() {
31                setTimeout(function() {
32                    sln_init(jQuery);
33                }, 2000);
34            }
35        );
36    }
37});
38
39function sln_init($) {
40    if ($("#salon-step-services").length || $("#salon-step-secondary").length) {
41        let request_args = window.location.search.split('&');
42        if(! request_args.find(val => val.startsWith('submit_services') || val.startsWith('?submit_services'))
43            && ! request_args.find(val => val.startsWith('save_selected'))
44            && $("#salon-step-services").length
45            && !$('.sln-icon--back').length){
46            $('#salon-step-services input[type="checkbox"]').removeAttr('checked');
47            if(!$('.sln-checkbox.is-checked').length){
48                $('#sln-step-submit').parent().addClass('sln-btn--disabled');
49            }
50        }
51        if($("#salon-step-services").length){
52            $('.sln-service-variable-duration--counter--minus').addClass('sln-service-variable-duration--counter--button--disabled');
53        }
54        request_args = request_args.filter(item =>  !item.startsWith('save_selected'))
55        window.history.replaceState({}, document.title, window.location.pathname + request_args.join('&'))
56        sln_serviceTotal($);
57    }
58    let discount_request_arg = window.location.search.replace('?', '').split('&').find(val => val.startsWith('discount_id'));
59    if(discount_request_arg !== undefined){
60        jQuery.ajax(
61            {
62                url: salon.ajax_url,
63                data: {
64                    action: 'salon_discount',
65                    method: 'ApplyDiscountIdOnStart',
66                    discount_id: discount_request_arg.split('=')[1]
67                },
68                method: 'POST',
69                dataType: 'json',
70                success: function(data){console.log(data)}
71            }
72        );
73    }
74    if(typeof sln_select !== undefined && typeof sln_select == 'function'){
75        sln_select($);
76    }
77    if($('#salon-step-attendant').length){
78        sln_attendantTotal($);
79        // sln_stepAttendant($);
80    }
81    
82    function box_fixed_height() {
83        if ($(".sln-box--fixed_height").length) {
84            $(".sln-box--fixed_height").each(function() {
85                var el = $(this);
86                var iHeight = el.height();
87                var iScrollHeight = el.prop("scrollHeight");
88                var diff = iScrollHeight - iHeight;
89                if (diff > 1) {
90                    el.addClass('sln-box--scrollable');
91                } else {
92                    el.removeClass('sln-box--scrollable');
93                }
94            });
95        }
96            $(".sln-box--fixed_height--").css("position", "absolute").css("opacity", "0");
97            function sln_timeScroll() {
98                var dateTable = $(".datetimepicker-days"),
99                    timeTable = $(".sln-box--fixed_height--"),
100                    //originalHeight = timeTable.outerHeight(true),
101                    originalHeight = timeTable.prop("scrollHeight"),
102                    otherHeight = $(".datetimepicker-days").outerHeight(true),
103                    timeTableHeight =
104                        otherHeight -
105                        $("#sln_timepicker_viewdate").outerHeight(true) -
106                        30;
107                if (originalHeight > timeTableHeight) {
108                    timeTable
109                        .css("max-height", timeTableHeight)
110                        .addClass("is_scrollable")
111                        .css("position", "relative")
112                        .css("opacity", "1");
113                } else {
114                    timeTable.css("position", "relative").css("opacity", "1");
115                }
116            }
117            $(window).bind("load", function() {
118                setTimeout(function() {
119                    sln_timeScroll();
120                }, 200);
121            });
122            $(window).resize(function() {
123                setTimeout(function() {
124                    sln_timeScroll();
125                }, 200);
126            });
127            $(document).ajaxComplete(function(event, request, settings) {
128                setTimeout(function() {
129                    sln_timeScroll();
130                }, 200);
131            });
132            setTimeout(function() {
133                sln_timeScroll();
134            }, 200);
135    }
136    box_fixed_height();
137    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
138        // e.target // newly activated tab
139        // e.relatedTarget // previous active tab
140        box_fixed_height();
141    });
142
143    function bottombar_sticky() {
144        if ($("#sln-salon").length && screen.width < 600) {
145            var box = $("#sln-salon");
146            var box_width = box.outerWidth();
147            var window_width = $(window).width();
148            var offset_left = box.offset().left;
149            var offset_right = window_width - box_width - offset_left;
150            var margin_left = (offset_left + 0)  * -1;
151            var margin_right = (offset_right + 0)  * -1;
152            var box_nu_width = window_width + " !important" ;
153            //console.log(box_width + ' - ' + window_width + ' - ' + offset_left);
154            //box.css( "margin-right", margin_right ).css( "max-width", "unset" ).css( "width", box_nu_width );
155            //box.attr("style", "margin-left:" + margin_left + "px !important");
156            box.attr("style", "width:" + window_width +  "px; margin-right:" + margin_right + "px !important; margin-left:" + margin_left + "px !important");
157            if ($("#sln-box__bottombar").length) {
158                var bar = $("#sln-box__bottombar");
159                var bar_width = bar.width();
160                var bar_offset_left = bar.offset().left;
161                var bar_offset_right = window_width - bar_width - bar_offset_left;
162                var bar_margin_left = (bar_offset_left + 0) * -1;
163                var bar_margin_right = (bar_offset_right + 0) * -1;
164                //bar.css( "margin-left", bar_margin_left ).css( "margin-right", bar_margin_right ).css( "max-width", "unset" );
165                //$("#sln-box__bottombar.col-xs-12").css( "width", window_width );
166                const aboutUsObserver = new IntersectionObserver((entries, observer) => {
167                    entries.forEach(entry => {
168                        if(entry.isIntersecting) {
169                            $("#sln-box__bottombar").addClass("sln-box__bottombar--notsticky");
170                            //$("#sln-box__bottombar").toggleClass("underlined");
171                        } else {
172                            $("#sln-box__bottombar").removeClass("sln-box__bottombar--notsticky");
173                        }
174                    });
175                }, {});
176                aboutUsObserver.observe($("#sln-salon__follower")[0]);
177            }
178        }
179    }
180    bottombar_sticky();
181    var window_width = $(window).width();
182    $(window).resize((event) => {
183        if ($(window).width() != window_width) {
184            bottombar_sticky();
185        }
186    });
187    function attendants_hor_scroll() {
188        //const slider = document.querySelector('.sln-list__horscroller__in');
189        const sliders = document.querySelectorAll('.sln-list__horscroller__in');
190        let isDown = false;
191        let startX;
192        let scrollLeft;
193        for (const slider of sliders) {
194            slider.addEventListener('mousedown', (e) => {
195              isDown = true;
196              slider.classList.add('active');
197              startX = e.pageX - slider.offsetLeft;
198              scrollLeft = slider.scrollLeft;
199            });
200            slider.addEventListener('mouseleave', () => {
201              isDown = false;
202              slider.classList.remove('active');
203            });
204            slider.addEventListener('mouseup', () => {
205              isDown = false;
206              slider.classList.remove('active');
207            });
208            slider.addEventListener('mousemove', (e) => {
209              if(!isDown) return;
210              e.preventDefault();
211              const x = e.pageX - slider.offsetLeft;
212              const walk = (x - startX) * 3; //scroll-fast
213              slider.scrollLeft = scrollLeft - walk;
214              //console.log(walk);
215            });
216        }
217
218
219    }
220    attendants_hor_scroll();
221    function step_description() {
222        $("#sln-salon .sln-list__item .sln-list__item__description.sln-list__item__description__toggle").each(function() {
223            $(this).on( "click", function(e) {
224                $(this).closest(".sln-list__item").toggleClass("sln-list__item--moredesc");
225                $(this).closest(".sln-list__item").find(".sln-list__item__errors").toggleClass("sln-list__item__errors--pushed");
226                e.preventDefault();
227                e.stopPropagation();
228            });
229        });
230    }
231    step_description();
232
233    if ($("#salon-step-date").length) {
234        sln_stepDate($);
235    } else {
236        if ($("#salon-step-details").length) {
237            $("a.tec-link").on("click", function(e) {
238                e.preventDefault();
239                var href = $(this).attr("href");
240                var locHref = window.location.href;
241                var hrefGlue = href.indexOf("?") == -1 ? "?" : "&";
242                var locHrefGlue = locHref.indexOf("?") == -1 ? "?" : "&";
243                window.location.href =
244                    href +
245                    hrefGlue +
246                    "redirect_to=" +
247                    encodeURI(locHref + locHrefGlue + "sln_step_page=details");
248            });
249        }
250        if ($('[data-salon-click="fb_login"]').length) {
251            if (window.fbAsyncInit === undefined) {
252                if (salon.fb_app_id !== undefined) {
253                    sln_facebookInit();
254                } else {
255                    jQuery("[data-salon-click=fb_login]").remove();
256                }
257            } else {
258                jQuery("[data-salon-click=fb_login]")
259                    .off("click")
260                    .on("click", function() {
261                        FB.login(
262                            function() {
263                                sln_facebookLogin();
264                            },
265                            { scope: "email" }
266                        );
267
268                        return false;
269                    });
270            }
271        }
272        $('#sln-salon-booking [data-salon-toggle="next"]').on("click", function(e) {
273            var form = $(this).closest("form");
274            $(
275                "#sln-salon input.sln-invalid,#sln-salon textarea.sln-invalid,#sln-salon select.sln-invalid"
276            ).removeClass("sln-invalid");
277
278            if ($(form).has(".sln-file").length > 0) {
279                if ($('.sln-file input[type="file"]').data("required")) {
280                    let filesAmount = $(form).find(".sln-file .sln-file__list li input").length;
281
282                    if (filesAmount > 0) {
283                        $('.sln-file input[type="file"]').removeAttr("required");
284                    } else {
285                        $('.sln-file input[type="file"]').attr("required");
286                    }
287                }
288            }
289            if (form[0].checkValidity()) {
290                let form_data = null;
291                if(form.attr('enctype') == 'multipart/form-data'){
292                    form_data = new FormData(form[0]);
293                    let sln_data = $(this).data('salon-data').split('&');
294                    for(let i = 0; i < sln_data.length; i++){
295                        form_data.append(sln_data[i].split('=')[0], sln_data[i].split('=')[1]);
296                    }
297                }else{
298                    form_data = form.serialize() + "&" + $(this).data("salon-data")
299                }
300                
301                sln_loadStep(
302                    $,
303                    form_data
304                );
305            } else {
306                $(
307                    "#sln-salon input:invalid,#sln-salon textarea:invalid,#sln-salon select:invalid"
308                )
309                    .addClass("sln-invalid")
310                    .attr("placeholder", salon.checkout_field_placeholder);
311
312                $(
313                    "#sln-salon input:invalid,#sln-salon textarea:invalid,#sln-salon select:invalid"
314                )
315                    .parent()
316                    .addClass("sln-invalid-p")
317                    .attr("data-invtext", salon.checkout_field_placeholder);
318            }
319            chooseAsistentForMe = undefined;
320            return false;
321        });
322
323            if($('.sln-file__content').length){
324                const dropInputParents = document.querySelectorAll(".sln-file__content");
325                dropInputParents.forEach(dropInputParent => {
326                    window.addEventListener("dragenter", function(e) {
327                    //if (e.target.id != dropzoneId) {
328                    if (!e.target.classList.contains('sln-input--file__act')) {
329                        e.preventDefault();
330                        e.dataTransfer.effectAllowed = "none";
331                        e.dataTransfer.dropEffect = "none";
332                      }
333                      dropInputParent.classList.add("sln-file__content--draghover");
334                      //console.log('dragenter');
335                    }, false);
336
337                    window.addEventListener("dragover", function(e) {
338                      if (!e.target.classList.contains('sln-file__act')) {
339                        e.preventDefault();
340                        e.dataTransfer.effectAllowed = "none";
341                        e.dataTransfer.dropEffect = "none";
342                      }
343                      dropInputParent.classList.add("sln-file__content--draghover");
344                      //console.log('dragover');
345                    });
346
347                    window.addEventListener("dragleave", function(e) {
348                      if (!e.target.classList.contains('sln-file__act')) {
349                        e.preventDefault();
350                        e.dataTransfer.effectAllowed = "none";
351                        e.dataTransfer.dropEffect = "none";
352                      }
353                      dropInputParent.classList.remove("sln-file__content--draghover");
354                      //console.log('drop');
355                    });
356
357                    window.addEventListener("drop", function(e) {
358                      if (!e.target.classList.contains('sln-file__act')) {
359                        e.preventDefault();
360                        e.dataTransfer.effectAllowed = "none";
361                        e.dataTransfer.dropEffect = "none";
362                      }
363                      dropInputParent.classList.remove("sln-file__content--draghover");
364                      //console.log('drop');
365                    });
366
367                    dropInputParent.addEventListener("dragenter", function(e) {
368                      this.classList.add("sln-file__content--draghover--fine");
369                      //console.log('dragover');
370                    });
371                    dropInputParent.addEventListener("dragover", function(e) {
372                      this.classList.add("sln-file__content--draghover--fine");
373                      //console.log('dragover');
374                    });
375                    dropInputParent.addEventListener("dragleave", function(e) {
376                      this.classList.remove("sln-file__content--draghover--fine");
377                      //console.log('dragover');
378                    });
379                    dropInputParent.addEventListener("drop", function(e) {
380                      this.classList.remove("sln-file__content--draghover--fine");
381                      //console.log('dragover');
382                    });
383                // dropInputParents.forEach END
384                });
385            }
386    }
387    if($('#sln-go-to-thankyou').length){
388        let countdown = 15;
389        $('.sln-go-to-thankyou-number').text(countdown);
390        setInterval(function(){
391            $('.sln-go-to-thankyou-number').text(--countdown);
392        }, 1000);
393        setTimeout(function(){
394            window.location.replace($('#sln-go-to-thankyou').attr('href'));
395        }, countdown * 1000);
396    }
397    $('#sln-salon-booking [data-salon-toggle="direct"]').on("click", function(e) {
398        e.preventDefault();
399        var form = $(this).closest("form");
400        sln_loadStep($, form.serialize() + "&" + $(this).data("salon-data"));
401        chooseAsistentForMe = '0';
402        return false;
403    });
404
405    $('.sln-file input[type=file]').on('change', function(e){
406        let file_list = $(this).parent().find('.sln-file__list');
407        //if(!file_list.children().length){
408        //    $(this).parent().find('label:last-child').text(' ').addClass('sln-input-file--select')
409        //}
410        $('.sln-file__errors').remove();
411        $('.sln-file__progressbar__wrapper').remove();
412
413        var formData = new FormData();
414        formData.append('action', 'salon')
415        formData.append('method', 'UploadFile')
416        formData.append('security', salon.ajax_nonce)
417        formData.append('file', this.files[0])
418
419        let file_name = this.files[0].name;
420        this.files = undefined;
421        this.value = ''
422
423        var self = this
424        file_list.append($('<li class="sln-file__progressbar__wrapper"><div class="sln-file__progressbar"><div class="sln-file__progressbar__value"></div></div><div class="sln-file__progressbar__percentage"></div></li>'));
425
426        $.ajax({
427            xhr: function() {
428                var xhr = new window.XMLHttpRequest();
429
430                xhr.upload.addEventListener("progress", function(evt) {
431                    if (evt.lengthComputable) {
432                      var percentComplete = evt.loaded / evt.total;
433                      percentComplete = parseInt(percentComplete * 100);
434                      //console.log(percentComplete);
435
436                      $('.sln-file__progressbar__value').css('width', percentComplete + '%');
437                      $('.sln-file__progressbar__percentage').text(percentComplete + '%');
438
439                      if (percentComplete === 100) {
440
441                      }
442
443                    }
444                  }, false);
445
446                return xhr;
447            },
448            url: salon.ajax_url,
449            type: "POST",
450            data: formData,
451            contentType: false,
452            processData: false,
453            dataType: "json",
454            success: function(result) {
455                $('.sln-file__progressbar__wrapper').remove();
456                if (result.success) {
457                    let input_file = '<input type="hidden" name="'+ $(self).attr('name') +'" value="'+ result.file +'">';
458                    file_list.append($('<li><i class="sr-only">delete</i><span class="sln-file__name">' + file_name +  '</span><span class="sln-file__remove"></span></li>').append(input_file));
459                    file_list.children().last().find('.sln-file__remove').on('click', function(e){
460                        e.stopPropagation();
461                        var self = this
462                        $.post(salon.ajax_url, {action: 'salon', method: 'RemoveUploadedFile', security: salon.ajax_nonce, file: result.file}, function () {
463                            $(self).closest('li').remove();
464                        })
465                    });
466                } else {
467                    file_list.append($('<li class="sln-file__errors">' + result.errors.join(',') +  '</li>'));
468                }
469            }
470        });
471
472    });
473
474    // CHECKBOXES
475    $("#sln-salon input:checkbox").each(function() {
476        $(this).on("change", function() {
477            if ($(this).is(":checked")) {
478                $(this)
479                    .parent()
480                    .addClass("is-checked");
481            } else {
482                $(this)
483                    .parent()
484                    .removeClass("is-checked");
485            }
486            if(!$('.sln-checkbox.is-checked').length && $("#salon-step-services").length){
487                $('#sln-step-submit').parent().addClass('sln-btn--disabled');
488            }else{
489                $('#sln-step-submit').parent().removeClass('sln-btn--disabled');
490            }
491        });
492    });
493    // RADIOBOXES
494    $("#sln-salon input:radio").each(function() {
495        $(this).on("click", function() {
496            var name = jQuery(this).attr("name");
497            jQuery(".is-checked").each(function() {
498                if (
499                    jQuery(this)
500                        .find("input")
501                        .attr("name") == name
502                ) {
503                    $(this).removeClass("is-checked");
504                }
505            });
506            $(this)
507                .parent()
508                .toggleClass("is-checked");
509        });
510    });
511
512    $('.sln-icon-sort').on('click', function(){
513        let sorted_attendants = [];
514        let $this = $(this);
515        $this.addClass('active');
516        if($this.hasClass('sln-icon-sort--down')){
517            $this.closest('.row').find('.sln-icon-sort--up').removeClass('active');
518            $this.closest('.sln-attendant-list').find('label').each(function(ind, attendant){
519                if($(attendant).find('input').val() == 0 || $(attendant).find('input').val() == undefined){
520                    return true;
521                }
522                if($(attendant).hasClass('DEC') || !$(attendant).hasClass('INC')){
523                    return false;
524                }
525                $(attendant).addClass('DEC').removeClass('INC');
526                sorted_attendants.push($(attendant).clone());
527                $(attendant).remove();
528            });
529        }
530        if($this.hasClass('sln-icon-sort--up')){
531            $this.closest('.row').find('.sln-icon-sort--down').removeClass('active');
532            $this.closest('.sln-attendant-list').find('label').each(function(ind, attendant){
533                if($(attendant).find('input').val() == 0 || $(attendant).find('input').val() == undefined){
534                    return true;
535                }
536                if($(attendant).hasClass('INC')){
537                    return false;
538                }
539                $(attendant).addClass('INC').removeClass('DEC');
540                sorted_attendants.push($(attendant).clone());
541                $(attendant).remove();
542            });
543        }
544        if(sorted_attendants.length){
545            sorted_attendants = sorted_attendants.reverse();
546            sorted_attendants.forEach(function(el){
547                $this.closest('.sln-attendant-list').append(el);
548                $(el).on("change", function() {
549                    evalTot();
550                }).on("click", function() {
551                    var name = jQuery(this).attr("name");
552                    jQuery(".is-checked").each(function() {
553                        if (
554                            jQuery(this)
555                                .find("input")
556                                .attr("name") == name
557                        ) {
558                            $(this).removeClass("is-checked");
559                        }
560                    });
561                    $(this)
562                        .parent()
563                        .toggleClass("is-checked");
564                });
565            });
566        }
567    });
568
569    $(".sln-edit-text").on("change", function() {
570        var data =
571            "key=" +
572            $(this).attr("id") +
573            "&value=" +
574            $(this).val() +
575            "&action=salon&method=SetCustomText&security=" +
576            salon.ajax_nonce;
577        $.ajax({
578            url: salon.ajax_url,
579            data: data,
580            method: "POST",
581            dataType: "json",
582            success: function(data) {},
583            error: function(data) {
584                alert("error");
585                //console.log(data);
586            },
587        });
588        return false;
589    });
590
591    $("div.editable").on("click", function() {
592        var self = $(this);
593        self.addClass("focus");
594        var text = self.find(".text");
595        var input = self.find("input");
596        input.val(text.text().trim()).trigger("focus");
597    });
598
599    $("div.editable .input input").on("blur", function() {
600        var self = $(this);
601        var div = self.closest(".editable");
602        div.removeClass("focus");
603        var text = div.find(".text");
604        text.html(self.val());
605    });
606
607    $("#sln_no_user_account")
608        .on("change", function() {
609            if ($(this).is(":checked")) {
610                $("#sln_password")
611                    .attr("disabled", "disabled")
612                    .parent()
613                    .css("display", "none");
614                $("#sln_password_confirm")
615                    .attr("disabled", "disabled")
616                    .parent()
617                    .css("display", "none");
618                $(".sln-customer-fields").hide();
619                $(this)
620                    .closest("form")
621                    .addClass("sln-guest-checkout-form");
622            } else {
623                $("#sln_password")
624                    .attr("disabled", false)
625                    .parent()
626                    .css("display", "block");
627                $("#sln_password_confirm")
628                    .attr("disabled", false)
629                    .parent()
630                    .css("display", "block");
631                $(".sln-customer-fields").show();
632                $(this)
633                    .closest("form")
634                    .removeClass("sln-guest-checkout-form");
635            }
636        })
637        .trigger("change");
638
639    sln_createRatings(true, "star");
640
641    if (typeof sln_createSelect2Full !== "undefined") {
642        sln_createSelect2Full($);
643    }
644    sln_salonBookingCalendarInit();
645
646    $(".sln-help-button").on("click", function() {
647        window.Beacon("toggle");
648        return false;
649    });
650
651    setTimeout(function() {
652        $(".sln-service-list .sln-panel-heading").each(function() {
653            $(this).replaceWith($(this).clone());
654        });
655    }, 0);
656
657    var input = document.querySelector("#sln_phone");
658
659    if (input && $("#sln_sms_prefix").length) {
660        function getCountryCodeByDialCode(dialCode) {
661            var countryData = window.intlTelInputGlobals.getCountryData();
662            var countryCode = "";
663            countryData.forEach(function(data) {
664                if (data.dialCode == dialCode) {
665                    countryCode = data.iso2;
666                }
667            });
668            return countryCode;
669        }
670
671        var iti = window.intlTelInput(input, {
672            initialCountry: getCountryCodeByDialCode(
673                ($("#sln_sms_prefix").val() || "").replace("+", "")
674            ),
675            separateDialCode: true,
676            autoHideDialCode: true,
677            nationalMode: false,
678        });
679
680        input.addEventListener('keydown', function(event){
681            if(/[^0-9]/.test(event.key) && !/(Backspace)|(Enter)|(Tab)|(ArrowLeft)|(ArrowRight)|(Delete)/.test(event.key)){
682                event.preventDefault();
683            }
684        });
685
686        input.addEventListener("countrychange", function() {
687            if (iti.getSelectedCountryData().dialCode) {
688                $("#sln_sms_prefix").val(
689                    "+" + iti.getSelectedCountryData().dialCode
690                );
691            }
692        });
693        input.addEventListener("blur", function() {
694            if (iti.getSelectedCountryData().dialCode) {
695                $(input).val($(input).val().replace("+" + iti.getSelectedCountryData().dialCode, ""));
696            }
697        });
698    }
699
700    sln_google_maps_places_api_callback();
701
702    $('input[name="sln[customer_timezone]"]').val(new window.Intl.DateTimeFormat().resolvedOptions().timeZone);
703
704    $('.sln-service-variable-duration--counter--plus').on('click', function () {
705
706        var checkbox = $(this).closest('.sln-service').find('input[type="checkbox"][name*="sln[services]"]');
707
708        if ($(this).hasClass('sln-service-variable-duration--counter--button--disabled')  || checkbox.prop('disabled')) {
709            return false;
710        }
711
712        var counter = $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-variable-duration--counter--value');
713
714        counter.html(+counter.text().trim() + 1);
715
716        if (+counter.text().trim() > 0) {
717            $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-variable-duration--counter--minus').removeClass('sln-service-variable-duration--counter--button--disabled');
718            $(this).closest('.sln-steps-info.sln-service-info').find('.sln-steps-check .sln-checkbox input').trigger('change');
719        }
720
721        if (!checkbox.prop('checked')) {
722            checkbox.prop('checked', true)
723            checkServices();
724        }
725
726        $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-count-input').val(+counter.text().trim())
727
728        evalTot()
729
730        if (+counter.text().trim() >= +$(this).closest('.sln-service-variable-duration').data('unitsPerSession')) {
731            $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-variable-duration--counter--plus').addClass('sln-service-variable-duration--counter--button--disabled');
732        }
733
734        return false;
735    })
736
737    $('.sln-service-variable-duration--counter--minus').on('click', function () {
738
739        var checkbox = $(this).closest('.sln-service').find('input[type="checkbox"][name*="sln[services]"]');
740
741        if ($(this).hasClass('sln-service-variable-duration--counter--button--disabled') || checkbox.prop('disabled')) {
742            return false;
743        }
744
745        var counter = $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-variable-duration--counter--value');
746
747        counter.html(+counter.text().trim() - 1);
748
749        if (+counter.text().trim() < 1) {
750            $(this).addClass('sln-service-variable-duration--counter--button--disabled');
751            let input = $(this).closest('.sln-steps-info.sln-service-info').find('.sln-steps-check .sln-checkbox input');
752            input.parent().removeClass('is-checked');
753            input.removeAttr('checked').trigger('change');
754        }
755        
756        checkServices();
757
758        $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-count-input').val(+counter.text().trim())
759
760        if (+counter.text().trim() < +$(this).closest('.sln-service-variable-duration').data('unitsPerSession')) {
761            $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-variable-duration--counter--plus').removeClass('sln-service-variable-duration--counter--button--disabled');
762        }
763
764        evalTot();
765
766        return false;
767    })
768
769    $('.sln-service-variable-duration--counter--value').each(function () {
770        $(this).html($(this).closest('.sln-service-variable-duration--counter').find('.sln-service-count-input').val())
771        $(this).closest('.sln-service-variable-duration--counter').find('.sln-service-variable-duration--counter--minus').toggleClass('sln-service-variable-duration--counter--button--disabled', +$(this).text().trim() < 1)
772    })
773
774    var $checkboxes = $('.sln-service-list input[type="checkbox"]');
775    var $totalbox = $("#services-total");
776    evalTot();
777    function evalTot() {
778        var tot = 0;
779        $checkboxes.each(function() {
780            var count = $(this).closest('.sln-service').find('.sln-service-count-input').val() || 1;
781            if ($(this).is(":checked")) {
782                tot += $(this).data("price") * count;
783            }
784        });
785        var decimals = parseFloat(tot) === parseFloat(parseInt(tot)) ? 0 : 2;
786        $totalbox.text(
787            $totalbox.data("symbol-left") +
788                ($totalbox.data("symbol-left") !== "" ? " " : "") +
789                tot.formatMoney(
790                    decimals,
791                    $totalbox.data("symbol-decimal"),
792                    $totalbox.data("symbol-thousand")
793                ) +
794                ($totalbox.data("symbol-right") !== "" ? " " : "") +
795                $totalbox.data("symbol-right")
796        );
797        $checkboxes.each(function() {
798            var count = $(this).closest('.sln-service').find('.sln-service-count-input').val() || 1;
799            var tot     = $(this).data("price") * count;
800            var decimals = parseFloat(tot) === parseFloat(parseInt(tot)) ? 0 : 2;
801            $(this).closest('.sln-service').find('.sln-service-price-value').text(
802                $totalbox.data("symbol-left") +
803                ($totalbox.data("symbol-left") !== "" ? " " : "") +
804                tot.formatMoney(
805                    decimals,
806                    $totalbox.data("symbol-decimal"),
807                    $totalbox.data("symbol-thousand")
808                ) +
809                ($totalbox.data("symbol-right") !== "" ? " " : "") +
810                $totalbox.data("symbol-right")
811            );
812        });
813        $checkboxes.each(function() {
814            var count = $(this).closest('.sln-service').find('.sln-service-count-input').val() || 1;
815            var tot     = $(this).data("duration") * count;
816            var hours  = parseInt(tot / 60);
817            var minutes = tot % 60;
818            $(this).closest('.sln-service').find('.sln-service-duration').text(
819                (hours < 10 ? '0' + hours : hours) + ":" + (minutes < 10 ? '0' + minutes : minutes)
820            );
821        });
822    }
823
824    function checkServices() {
825        var form, data;
826        if ($("#salon-step-services").length) {
827            form = $("#salon-step-services");
828            data =
829                form.serialize() +
830                "&action=salon&method=CheckServices&part=primaryServices&security=" +
831                salon.ajax_nonce;
832        } else if ($("#salon-step-secondary").length) {
833            form = $("#salon-step-secondary");
834            data =
835                form.serialize() +
836                "&action=salon&method=CheckServices&part=secondaryServices&security=" +
837                salon.ajax_nonce;
838        } else {
839            return;
840        }
841
842        $.ajax({
843            url: salon.ajax_url,
844            data: data,
845            method: "POST",
846            dataType: "json",
847            success: function(data) {
848                if (!data.success) {
849                    var alertBox = $(
850                        '<div class="sln-alert sln-alert--problem sln-service-error"></div>'
851                    );
852                    $.each(data.errors, function() {
853                        alertBox.append("<p>").html(this);
854                    });
855                } else {
856                    $(".sln-alert.sln-service-error").remove();
857                    if (data.services)
858                        $.each(data.services, function(index, value) {
859                            var checkbox = $("#sln_services_" + index);
860                            var errorsArea = $("#sln_services_" + index)
861                                .closest(".sln-service")
862                                .find(".errors-area");
863                            if (value.status == -1) {
864                                var alertBox = $(
865                                    '<div class="sln-alert sln-alert-medium sln-alert--problem sln-service-error visible"><p>' +
866                                        value.error +
867                                        "</p></div>"
868                                );
869                                checkbox
870                                    .attr("checked", false)
871                                    .attr("disabled", "disabled")
872                                    .trigger("change");
873                                errorsArea.html(alertBox);
874                            } else if (value.status == 0) {
875                                checkbox
876                                    .attr("checked", false)
877                                    .attr("disabled", false)
878                                    .trigger("change");
879                            } else if (value.status == 1) {
880                                checkbox
881                                    .attr("checked", true)
882                                    .trigger("change");
883                            }
884                        });
885                    evalTot();
886                }
887            },
888        });
889    }
890}
891function sln_loadStep($, data) {
892    var loadingMessage =
893        '<div class="sln-loader-wrapper"><div class="sln-loader">Loading...</div></div>';
894        let request_arr = {
895            url: salon.ajax_url,
896            method: "POST",
897            dataType: "json",
898            success: function(data) {
899                if (typeof data.redirect != "undefined") {
900                    window.location.href = data.redirect;
901                } else {
902                    $("#sln-salon-booking").replaceWith(data.content);
903                    salon.ajax_nonce = data.nonce;
904                    $("html, body").animate(
905                        {
906                            scrollTop: $("#sln-salon-booking").offset().top,
907                        },
908                        700
909                    );
910                    sln_init($);
911                    $("div#sln-notifications")
912                        .html("")
913                        .removeClass("sln-notifications--active");
914                }
915            },
916            error: function(data) {
917                alert("error");
918                //console.log(data);
919            },
920        };
921    if(data instanceof FormData){
922        data.append('action', 'salon');
923        data.append('method', 'salonStep');
924        data.append('security', salon.ajax_nonce);
925        request_arr['processData'] = false;
926        request_arr['contentType'] = false;
927    }else{
928        data += "&action=salon&method=salonStep&security=" + salon.ajax_nonce;
929    }
930    request_arr['data'] = data;
931    $("#sln-notifications")
932        .html(loadingMessage)
933        .addClass("sln-notifications--active");
934    $.ajax(request_arr);
935}
936
937function sln_updateDatepickerTimepickerSlots($, intervals) {
938    $("[data-ymd]").addClass("disabled");
939    $.each(intervals.dates, function(key, value) {
940        $('.day[data-ymd="' + value + '"]').removeClass("disabled");
941    });
942    $(".day[data-ymd]").removeClass("full");
943    $.each(intervals.fullDays, function(key, value) {
944        //console.log(value);
945        $('.day[data-ymd="' + value + '"]').addClass("disabled full");
946    });
947
948    $.each(intervals.times, function(key, value) {
949        $('.minute[data-ymd="' + value + '"]').removeClass("disabled");
950    });
951}
952
953function sln_updateDebugDate( $, debugLog ){
954    $('.day').removeAttr( 'title');
955    if( debugLog ){
956        function show_debug_day_info(){
957            $( $( this ).find( '.sln-debug-day-info') ).show(0);
958        }
959        function hide_debug_day_info(){
960            $( $( this ).find( '.sln-debug-day-info' ) ).hide(0);
961        }
962        $('.day').hover( show_debug_day_info, hide_debug_day_info );
963        $( '.day' ).append( '<div class="sln-debug-day-info">The day out of the booking time range</div>');
964        $( '.sln-debug-day-info' ).hide(0);
965        $.each( debugLog, function(key, value) {
966            if( value == 'free' ){
967                $( '.day[data-ymd="' + key + '"] .sln-debug-day-info' ).remove();
968                return;
969            }
970            $('.day[data-ymd="' + key + '"] .sln-debug-day-info').html( value ).hide(0);
971        });
972        // $( '.sln-debug-day-info' ).hide(0);
973    }
974}
975
976function sln_stepDate($) {
977    var isValid;
978    var items = { intervals: $("#salon-step-date").data("intervals"), debugDate: $('#salon-step-date').data('debug') };
979    var updateFunc = function() {
980        sln_updateDatepickerTimepickerSlots($, items.intervals);
981        sln_updateDebugDate( $, items.debugDate );
982    };
983    var debounce = function(fn, delay) {
984        var inDebounce;
985        return function() {
986            var context = this;
987            var args = arguments;
988            clearTimeout(inDebounce);
989            inDebounce = setTimeout(function() {
990                return fn.apply(context, args);
991            }, delay);
992        };
993    };
994
995    $( document ).ready(function(){
996        var oldMousePosition = [0, false];
997        $( '#sln-debug-sticky-panel .sln-debug-move' ).mousedown(function(e){
998            oldMousePosition[0] = e.clientY;
999            oldMousePosition[1] = true;
1000        });
1001        $( 'body' ).mousemove( function(e){
1002            if( true === oldMousePosition[1] ){
1003                var heightElem = $( '#sln-debug-div' ).height();
1004                $( '#sln-debug-div' ).animate({height: heightElem + oldMousePosition[0] - e.clientY,}, 0);
1005                oldMousePosition[0] = e.clientY;
1006            }
1007        });
1008        $( 'body' ).mouseup( function(e){
1009            oldMousePosition[1] = false;
1010        });
1011
1012        $( '#sln-debug-sticky-panel #disable-debug-table' ).click(function(){
1013            if( confirm( 'Debug table will be disable.' ) ){
1014                $( "input[name='sln[debug]']").val(0);
1015                $( '#sln-debug-div' ).hide();
1016                validate( this, false );
1017                delete items.debugDate;
1018            }
1019        });
1020        var oldOpenDebugPopup = null;
1021        $( '#sln-debug-table' ).each( function( iter, elem ){
1022            elem = $( elem );
1023            $( elem.find( '.sln-debug-time' ) ).click(function(e){
1024                if( oldOpenDebugPopup ){
1025                    oldOpenDebugPopup.hide();
1026                    oldOpenDebugPopup = null;
1027                }
1028                $( window ).click( function( closeEvent){
1029                    if( e.timeStamp != closeEvent.timeStamp ){
1030                        oldOpenDebugPopup.hide()
1031                        $( window ).off('click')
1032                    }
1033                } );
1034                var popup = oldOpenDebugPopup = $( $( this ).parent().find( '.sln-debug-popup' ) );
1035                var mousePosition = [e.clientX, $(this).position().top + $( '#sln-debug-div' ).scrollTop()];
1036                if( mousePosition[0] + popup.width() > $( window ).width() ){
1037                    mousePosition[0] -= popup.width() - ($( window ).width() - mousePosition[0]);
1038                }
1039                popup.show().css( {'top': mousePosition[1], 'left': mousePosition[0]} );
1040            });
1041
1042            $( '.sln-debug-popup' ).hide();
1043        } );
1044    });
1045    var func = debounce(updateFunc, 200);
1046    func();
1047    $("body").on("sln_date", func);
1048    $("body").on("sln_date", function() {
1049        setTimeout(function() {
1050            $(".datetimepicker-days table tr td.day").on("click", function() {
1051                if ($(this).hasClass("disabled")) {
1052                    return;
1053                }
1054                var datetimepicker = $(".sln_datepicker div").data(
1055                    "datetimepicker"
1056                );
1057                datetimepicker = (datetimepicker === undefined) ? $('.sln_datepicker input').data('datetimepicker') : datetimepicker;
1058
1059                var date = $(this).attr("data-ymd");
1060
1061                var dateObj = $.fn.datetimepicker.DPGlobal.parseDate(
1062                    date,
1063                    datetimepicker.format,
1064                    datetimepicker.language,
1065                    datetimepicker.formatType
1066                );
1067
1068                var formattedDate = $.fn.datetimepicker.DPGlobal.formatDate(
1069                    dateObj,
1070                    datetimepicker.format,
1071                    datetimepicker.language,
1072                    datetimepicker.formatType
1073                );
1074                var dateString = dateObj.toLocaleDateString(
1075                    datetimepicker.language.replace("_", "-"),
1076                    {
1077                        weekday: "long",
1078                        year: "numeric",
1079                        month: "long",
1080                        day: "numeric",
1081                        timeZone: "UTC",
1082                    }
1083                );
1084                $("input[name='sln[date]']").val(formattedDate);
1085                dateString = dateString + ' |' + $('#sln_timepicker_viewdate').text().split('|')[1];
1086                $("#sln_timepicker_viewdate").text(dateString);
1087            });
1088        });
1089    });
1090
1091    function validate(obj, autosubmit) {
1092        var form = $(obj).closest("form");
1093        var validatingMessage =
1094            '<div class="sln-alert sln-alert--wait">' +
1095            salon.txt_validating +
1096            "</div>";
1097        var data = form.serialize();
1098        data += "&action=salon&method=checkDate&security=" + salon.ajax_nonce;
1099        $("#sln-notifications")
1100            .addClass("sln-notifications--active")
1101            .append(validatingMessage);
1102        $( "#sln-debug-notifications" ).addClass("sln-notifications--active" ).html( validatingMessage );
1103        $( "#sln-debug-div" ).css( 'overflow-y', 'hidden').scrollTop(0);
1104        $("#sln-salon").addClass("sln-salon--loading");
1105        $.ajax({
1106            url: salon.ajax_url,
1107            data: data,
1108            method: "POST",
1109            dataType: "json",
1110            success: function(data) {
1111                $(".sln-alert").remove();
1112                if (!data.success) {
1113                    var alertBox = $(
1114                        '<div class="sln-alert sln-alert--problem"></div>'
1115                    );
1116                    $(data.errors).each(function() {
1117                        alertBox.append("<p>").html(this);
1118                    });
1119                    $("#sln-notifications")
1120                        .html("")
1121                        .append(alertBox);
1122                    $( "#sln-debug-notifications").html("").append( alertBox );
1123                    isValid = false;
1124                } else {
1125                    $("#sln-step-submit").attr("disabled", false);
1126                    $("#sln-notifications")
1127                        .html("")
1128                        .removeClass("sln-notifications--active");
1129                    $( "#sln-debug-notifications" ).html("").removeClass( "sln-notifications--active" );
1130                    $( "#sln-debug-div" ).css( 'overflow-y', 'scroll' );
1131                    $("#sln-salon").removeClass("sln-salon--loading");
1132                    isValid = true;
1133                    if (autosubmit) submit();
1134                }
1135                bindIntervals(data.intervals);
1136                if ( data.debug ){
1137                    bindDebugTimeLog( data.debug.times );
1138                }
1139                var timeValue = Object.values(data.intervals.times)[0] || "";
1140                var hours = parseInt(timeValue, 10) || 0;
1141                var datetimepicker = $(".sln_timepicker div").data(
1142                    "datetimepicker"
1143                );
1144                datetimepicker.viewDate.setUTCHours(hours);
1145                var minutes =
1146                    parseInt(
1147                        timeValue.substr(timeValue.indexOf(":") + 1),
1148                        10
1149                    ) || 0;
1150                datetimepicker.viewDate.setUTCMinutes(minutes);
1151                sln_renderAvailableTimeslots($, data);
1152                $("body").trigger("sln_date");
1153                $("input[name='sln[time]']").val(timeValue);
1154            },
1155        });
1156    }
1157
1158    $('#close-debug-table').click(function(){
1159        $( '#sln-debug-div' ).hide();
1160    });
1161
1162    function bindIntervals(intervals) {
1163        items.intervals = intervals;
1164        $("#salon-step-date").data("intervals", intervals);
1165        func();
1166        // putOptions($("#sln_date"), intervals.suggestedDate);
1167        // putOptions($("#sln_time"), intervals.suggestedTime);
1168
1169        if (!Object.keys(intervals.dates).length) {
1170            $("#sln-step-submit").attr("disabled", true);
1171            $("#sln_time").attr("disabled", true);
1172        } else {
1173            $("#sln-step-submit").attr("disabled", false);
1174            $("#sln_time").attr("disabled", false);
1175        }
1176    }
1177
1178    function bindDebugTimeLog( debugLog ){
1179        $( '.sln-debug-time-slote').each( function( iter, element ){
1180            var time = $( $( element).find('.sln-debug-time p' ) ).text();
1181            var timeSlot = $( element );
1182            $( timeSlot.find('.sln-debug-time p' ) ).attr( 'title', '');
1183            $( timeSlot.find( '.sln-debug-time' ) ).removeClass( 'sln-debug--failed' );
1184            $( timeSlot.find( '.sln-debug-popup' ) ).html('');
1185            var firstFaild = '';
1186            for( const [ruleName, ruleValue] of Object.entries( debugLog[time] ) ){
1187                if( false === ruleValue ){
1188                    if( '' === firstFaild ){
1189                        firstFaild = ruleName;
1190                    }
1191                    $( '<p>' + ruleName + '</p>' ).appendTo( timeSlot.find( '.sln-debug-popup' ) ).addClass( 'sln-debug--failed' );
1192                } else{
1193                    $( '<p>' + ruleName + '</p>' ).appendTo( timeSlot.find( '.sln-debug-popup' ) );
1194                }
1195            }
1196            if( '' !== firstFaild ){
1197                $( timeSlot.find( '.sln-debug-time p' ) ).attr( 'title', firstFaild );
1198                $( timeSlot.find( '.sln-debug-time' ) ).addClass( 'sln-debug--failed' );
1199            }
1200        })
1201    }
1202
1203    if (!Object.keys(items.intervals.dates).length) {
1204        $("#sln-step-submit").attr("disabled", true);
1205        $("#sln_time").attr("disabled", true);
1206    } else {
1207        $("#sln-step-submit").attr("disabled", false);
1208        $("#sln_time").attr("disabled", false);
1209    }
1210
1211    function putOptions(selectElem, value) {
1212        selectElem.val(value);
1213    }
1214
1215    function submit() {
1216        if ($("#sln-salon-booking #sln-step-submit").data("salon-toggle").length)
1217            sln_loadStep(
1218                $,
1219                $("#salon-step-date").serialize() +
1220                    "&" +
1221                    $("#sln-step-submit").data("salon-data")
1222            );
1223        else $("#sln-step-submit").trigger("click");
1224    }
1225
1226    $(".sln_datepicker div").on("changeDay", function() {
1227        validate(this, false);
1228    });
1229    $("#salon-step-date").on("submit", function() {
1230        if (!isValid) {
1231            validate(this, true);
1232        } else {
1233            submit();
1234        }
1235        return false;
1236    });
1237
1238    function dateStepResize() {
1239        if ($("#sln-salon.sln-step-date").length) {
1240            var offset = $("#sln-salon.sln-step-date").offset(),
1241                newOffsetLeft = offset.left - 18,
1242                elWidth = $("#sln-salon.sln-step-date").outerWidth(),
1243                wWidth = $(window).width(),
1244                wHeight = $(window).height();
1245            if (wWidth < wHeight) {
1246                if (elWidth <= 340) {
1247                    $("#sln-salon.sln-step-date").attr(
1248                        "style",
1249                        "min-width: calc(100vw - 36px); transform: translateX(-" +
1250                            newOffsetLeft +
1251                            "px);"
1252                    );
1253                }
1254            } else {
1255                $("#sln-salon.sln-step-date").attr("style", "");
1256            }
1257        }
1258    }
1259    dateStepResize();
1260    $(window).resize(function() {
1261        dateStepResize();
1262    });
1263    $("#sln_time")
1264        .css("position", "absolute")
1265        .css("opacity", "0");
1266    function sln_timeScroll() {
1267        var dateTable = $(".datetimepicker-days"),
1268            timeTable = $("#sln_time"),
1269            //originalHeight = timeTable.outerHeight(true),
1270            originalHeight = timeTable.prop("scrollHeight"),
1271            otherHeight = $(".datetimepicker-days").outerHeight(true),
1272            timeTableHeight =
1273                otherHeight -
1274                $("#sln_timepicker_viewdate").outerHeight(true) -
1275                30;
1276        if (originalHeight > timeTableHeight) {
1277            timeTable
1278                .css("max-height", timeTableHeight)
1279                .addClass("is_scrollable")
1280                .css("position", "relative")
1281                .css("opacity", "1");
1282        } else {
1283            timeTable.css("position", "relative").css("opacity", "1");
1284        }
1285    }
1286    $(window).bind("load", function() {
1287        setTimeout(function() {
1288            sln_timeScroll();
1289        }, 200);
1290    });
1291    $(window).resize(function() {
1292        setTimeout(function() {
1293            sln_timeScroll();
1294        }, 200);
1295    });
1296    $(document).ajaxComplete(function(event, request, settings) {
1297        setTimeout(function() {
1298            sln_timeScroll();
1299        }, 200);
1300    });
1301    setTimeout(function() {
1302        sln_timeScroll();
1303    }, 200);
1304    //$("#sln_timepicker_viewdate").on("click", function() {
1305    //    sln_timeScroll();
1306    //});
1307    if($('.cloned-data').length){
1308        $('#save-post').attr('disabled', 'disabled');
1309    }
1310    sln_initDatepickers($, items);
1311    sln_initTimepickers($, items);
1312
1313    if (!$('input[name="sln[customer_timezone]"]').val() && $('input[name="sln[customer_timezone]"]').length) {
1314        $('input[name="sln[customer_timezone]"]').val(new window.Intl.DateTimeFormat().resolvedOptions().timeZone);
1315        validate($(".sln_datepicker div"), false);
1316    }
1317}
1318
1319function sln_serviceTotal($) {
1320    var $checkboxes = $('.sln-service-list input[type="checkbox"]');
1321    var $totalbox = $("#services-total");
1322    function evalTot() {
1323        var tot = 0;
1324        $checkboxes.each(function() {
1325            var count = $(this).closest('.sln-service').find('.sln-service-count-input').val() || 1;
1326            if ($(this).is(":checked")) {
1327                tot += $(this).data("price") * count;
1328            }
1329        });
1330        var decimals = parseFloat(tot) === parseFloat(parseInt(tot)) ? 0 : 2;
1331        $totalbox.text(
1332            $totalbox.data("symbol-left") +
1333                ($totalbox.data("symbol-left") !== "" ? " " : "") +
1334                tot.formatMoney(
1335                    decimals,
1336                    $totalbox.data("symbol-decimal"),
1337                    $totalbox.data("symbol-thousand")
1338                ) +
1339                ($totalbox.data("symbol-right") !== "" ? " " : "") +
1340                $totalbox.data("symbol-right")
1341        );
1342    }
1343
1344    function checkServices($) {
1345        var form, data;
1346        if ($("#salon-step-services").length) {
1347            form = $("#salon-step-services");
1348            data =
1349                form.serialize() +
1350                "&action=salon&method=CheckServices&part=primaryServices&security=" +
1351                salon.ajax_nonce;
1352        } else if ($("#salon-step-secondary").length) {
1353            form = $("#salon-step-secondary");
1354            data =
1355                form.serialize() +
1356                "&action=salon&method=CheckServices&part=secondaryServices&security=" +
1357                salon.ajax_nonce;
1358        } else {
1359            return;
1360        }
1361
1362        $.ajax({
1363            url: salon.ajax_url,
1364            data: data,
1365            method: "POST",
1366            dataType: "json",
1367            success: function(data) {
1368                if (!data.success) {
1369                    var alertBox = $(
1370                        '<div class="sln-alert sln-alert--problem sln-service-error"></div>'
1371                    );
1372                    $.each(data.errors, function() {
1373                        alertBox.append("<p>").html(this);
1374                    });
1375                } else {
1376                    $(".sln-alert.sln-service-error").remove();
1377                    if (data.services)
1378                        $.each(data.services, function(index, value) {
1379                            var checkbox = $("#sln_services_" + index);
1380                            var errorsArea = $("#sln_services_" + index)
1381                                .closest(".sln-service")
1382                                .find(".errors-area");
1383                            if (value.status == -1) {
1384                                var alertBox = $(
1385                                    '<div class="sln-alert sln-alert-medium sln-alert--problem sln-service-error visible"><p>' +
1386                                        value.error +
1387                                        "</p></div>"
1388                                );
1389                                checkbox
1390                                    .attr("checked", false)
1391                                    .attr("disabled", "disabled")
1392                                    .trigger("change");
1393                                errorsArea.html(alertBox);
1394                            } else if (value.status == 0) {
1395                                checkbox
1396                                    .attr("checked", false)
1397                                    .attr("disabled", false)
1398                                    .trigger("change");
1399                            } else if (value.status == 1) {
1400                                checkbox
1401                                    .attr("checked", true)
1402                                    .trigger("change");
1403                            }
1404                        });
1405                    evalTot();
1406                }
1407            },
1408        });
1409    }
1410
1411    $checkboxes.on("click", function() {
1412        checkServices($);
1413    });
1414    checkServices($);
1415    evalTot();
1416}
1417
1418var chooseAsistentForMe
1419function sln_stepAttendant($){
1420    if(chooseAsistentForMe != undefined){
1421        return;
1422    }
1423    chooseAsistentForMe = $('#sln_attendant_0').length;
1424    if(1+chooseAsistentForMe == $('input[name="sln[attendant]"]').length - $('.sln-alert.sln-alert--problem.sln-service-error').length){
1425        $('#sln-salon-booking input[name="sln[attendant]"]').each(function(){
1426            if(0 != $(this).val()){
1427                $(this).trigger('click');
1428                var form = $(this).closest("form");
1429                $("#sln-salon input.sln-invalid,#sln-salon textarea.sln-invalid,#sln-salon select.sln-invalid"
1430                ).removeClass("sln-invalid");
1431                if (form[0].checkValidity()) {
1432                    sln_loadStep(
1433                        $,
1434                        form.serialize() + "&" + $('#sln-step-submit').data("salon-data")
1435                    );
1436                } else {
1437                    $(
1438                        "#sln-salon input:invalid,#sln-salon textarea:invalid,#sln-salon select:invalid"
1439                    )
1440                        .addClass("sln-invalid")
1441                        .attr("placeholder", salon.checkout_field_placeholder);
1442                    $(
1443                        "#sln-salon input:invalid,#sln-salon textarea:invalid,#sln-salon select:invalid"
1444                    )
1445                        .parent()
1446                        .addClass("sln-invalid-p")
1447                        .attr("data-invtext", salon.checkout_field_placeholder);
1448                }
1449                return false;
1450            }
1451        });
1452    }
1453}
1454
1455function sln_attendantTotal($) {
1456    var $checkboxes = $('input[name*="sln[attendants]"], input[name*="sln[attendant]"]');
1457    var $totalbox = $("#services-total");
1458    function evalTot() {
1459        var tot = 0;
1460        $checkboxes.each(function() {
1461            if ($(this).is(":checked")) {
1462                $(this).closest('.sln-attendant').find('.sln-list__item__price').each(function () {
1463                    tot += $(this).data('price');
1464                });
1465            }
1466        });
1467        var decimals = parseFloat(tot) === parseFloat(parseInt(tot)) ? 0 : 2;
1468        $totalbox.text(
1469            $totalbox.data("symbol-left") +
1470                ($totalbox.data("symbol-left") !== "" ? " " : "") +
1471                tot.formatMoney(
1472                    decimals,
1473                    $totalbox.data("symbol-decimal"),
1474                    $totalbox.data("symbol-thousand")
1475                ) +
1476                ($totalbox.data("symbol-right") !== "" ? " " : "") +
1477                $totalbox.data("symbol-right")
1478        );
1479    }
1480
1481    $checkboxes.on("change", function() {
1482        evalTot();
1483    });
1484    evalTot();
1485}
1486
1487function sln_initDatepickers($, data) {
1488    $(".sln_datepicker div").each(function() {
1489        $(this).attr("readonly", "readonly");
1490        if ($(this).hasClass("started")) {
1491            return;
1492        } else {
1493            $(this)
1494                .addClass("started")
1495                .datetimepicker({
1496                    format: $(this).data("format"),
1497                    weekStart: $(this).data("weekstart"),
1498                    minuteStep: 60,
1499                    minView: 2,
1500                    maxView: 4,
1501                    language: $(this).data("locale"),
1502                })
1503                .on("changeMonth", function() {
1504                    $("body").trigger("sln_date");
1505                })
1506                .on("changeYear", function() {
1507                    $("body").trigger("sln_date");
1508                })
1509                .on("hide", function() {
1510                    if ($(this).is(":focus"));
1511                    $(this).trigger("blur");
1512                });
1513            $("body").trigger("sln_date");
1514
1515            var datetimepicker = $(this).data("datetimepicker");
1516
1517            var suggestedDate = $.fn.datetimepicker.DPGlobal.parseDate(
1518                data.intervals.suggestedDate,
1519                datetimepicker.format,
1520                datetimepicker.language,
1521                datetimepicker.formatType
1522            );
1523
1524            datetimepicker.setUTCDate(suggestedDate);
1525
1526            var dateString = suggestedDate.toLocaleDateString(
1527                datetimepicker.language.replace("_", "-"),
1528                {
1529                    weekday: "long",
1530                    year: "numeric",
1531                    month: "long",
1532                    day: "numeric",
1533                    timeZone: "UTC",
1534                }
1535            );
1536            $("#sln_timepicker_viewdate").text(dateString + ' | ' + data.intervals.suggestedTime);
1537
1538            $("input[name='sln[date]']").val(data.intervals.suggestedDate);
1539        }
1540    });
1541    var elementExists = document.getElementById("sln-salon");
1542    if (elementExists) {
1543        setTimeout(function() {
1544            $(".datetimepicker.sln-datetimepicker").wrap(
1545                "<div class='sln-salon-bs-wrap'></div>"
1546            );
1547        }, 50);
1548    }
1549
1550    if (document.dir === "rtl") {
1551        swapNodes($('.datetimepicker-days .table-condensed .prev'), $('.datetimepicker-days .table-condensed .next'));
1552    }
1553
1554    function swapNodes(a, b) {
1555        var aNext = $('<div>').insertAfter(a);
1556        a.insertAfter(b);
1557        b.insertBefore(aNext);
1558        // remove marker div
1559        aNext.remove();
1560    }
1561}
1562
1563function sln_initTimepickers($, data) {
1564    $(".sln_timepicker div").each(function() {
1565        $(this).attr("readonly", "readonly");
1566        if ($(this).hasClass("started")) {
1567            return;
1568        } else {
1569            var picker = $(this)
1570                .addClass("started")
1571                .datetimepicker({
1572                    format: $(this).data("format"),
1573                    minuteStep: $(this).data("interval"),
1574                    minView: 0,
1575                    maxView: 0,
1576                    startView: 0,
1577                    showMeridian: $(this).data("meridian") ? true : false,
1578                })
1579                .on("show", function() {
1580                    $("body").trigger("sln_date");
1581                })
1582                .on("place", function() {
1583                    sln_renderAvailableTimeslots($, data);
1584
1585                    $("body").trigger("sln_date");
1586                })
1587                .on("changeMinute", function() {
1588                    setTimeout(function() {
1589                        sln_renderAvailableTimeslots($, data);
1590
1591                        $("body").trigger("sln_date");
1592                    }, 5);
1593                })
1594                .on("hide", function() {
1595                    if ($(this).is(":focus"));
1596                    $(this).blur();
1597                })
1598
1599                .data("datetimepicker").picker;
1600            picker.addClass("timepicker");
1601
1602            picker
1603                .find(".datetimepicker-minutes")
1604                .prepend(
1605                    $(
1606                        '<div class="sln-datetimepicker-minutes-wrapper-table"></div>'
1607                    ).append(picker.find(".datetimepicker-minutes table"))
1608                );
1609
1610            function convertTo24HrsFormat(time) {
1611                const slicedTime = time.split(/(pm|am)/gm)[0];
1612
1613                let [hours, minutes] = slicedTime.split(':');
1614
1615                if (hours === '12') {
1616                    hours = '00';
1617                }
1618
1619                let updateHourAndMin;
1620
1621                function addition(hoursOrMin) {
1622                    updateHourAndMin =
1623                        hoursOrMin.length < 2
1624                            ? (hoursOrMin = `${0}${hoursOrMin}`)
1625                            : hoursOrMin;
1626
1627                    return updateHourAndMin;
1628                }
1629
1630                if (time.endsWith('pm')) {
1631                    hours = parseInt(hours, 10) + 12;
1632                }
1633
1634                return `${addition(hours)}:${addition(minutes)}`;
1635            }
1636
1637            var suggestedTime = convertTo24HrsFormat(data.intervals.suggestedTime);
1638            var hours = parseInt(suggestedTime, 10) || 0;
1639            var datetimepicker = $(this).data("datetimepicker");
1640            datetimepicker.viewDate.setUTCHours(hours);
1641            var minutes =
1642                parseInt(
1643                    suggestedTime.substr(suggestedTime.indexOf(":") + 1),
1644                    10
1645                ) || 0;
1646            datetimepicker.viewDate.setUTCMinutes(minutes);
1647
1648            sln_renderAvailableTimeslots($, data);
1649
1650            $("body").trigger("sln_date");
1651
1652            picker.find("tr td").addClass("disabled");
1653        }
1654    });
1655}
1656/* ========================================================================
1657 * Bootstrap: transition.js v3.2.0
1658 * http://getbootstrap.com/javascript/#transitions
1659 * ========================================================================
1660 * Copyright 2011-2014 Twitter, Inc.
1661 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1662 * ======================================================================== */
1663
1664+(function($) {
1665    "use strict";
1666
1667    // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
1668    // ============================================================
1669
1670    function transitionEnd() {
1671        var el = document.createElement("bootstrap");
1672
1673        var transEndEventNames = {
1674            WebkitTransition: "webkitTransitionEnd",
1675            MozTransition: "transitionend",
1676            OTransition: "oTransitionEnd otransitionend",
1677            transition: "transitionend",
1678        };
1679
1680        for (var name in transEndEventNames) {
1681            if (el.style[name] !== undefined) {
1682                return { end: transEndEventNames[name] };
1683            }
1684        }
1685
1686        return false; // explicit for ie8 (  ._.)
1687    }
1688
1689    // http://blog.alexmaccaw.com/css-transitions
1690    $.fn.emulateTransitionEnd = function(duration) {
1691        var called = false;
1692        var $el = this;
1693        $(this).one("bsTransitionEnd", function() {
1694            called = true;
1695        });
1696        var callback = function() {
1697            if (!called) $($el).trigger($.support.transition.end);
1698        };
1699        setTimeout(callback, duration);
1700        return this;
1701    };
1702
1703    $(function() {
1704        $.support.transition = transitionEnd();
1705
1706        if (!$.support.transition) return;
1707
1708        $.event.special.bsTransitionEnd = {
1709            bindType: $.support.transition.end,
1710            delegateType: $.support.transition.end,
1711            handle: function(e) {
1712                if ($(e.target).is(this))
1713                    return e.handleObj.handler.apply(this, arguments);
1714            },
1715        };
1716    });
1717})(jQuery);
1718
1719/* ========================================================================
1720 * Bootstrap: collapse.js v3.2.0
1721 * http://getbootstrap.com/javascript/#collapse
1722 * ========================================================================
1723 * Copyright 2011-2014 Twitter, Inc.
1724 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1725 * ======================================================================== */
1726
1727+(function($) {
1728    "use strict";
1729
1730    // COLLAPSE PUBLIC CLASS DEFINITION
1731    // ================================
1732
1733    var Collapse = function(element, options) {
1734        this.$element = $(element);
1735        this.options = $.extend({}, Collapse.DEFAULTS, options);
1736        this.transitioning = null;
1737
1738        if (this.options.parent) this.$parent = $(this.options.parent);
1739        if (this.options.toggle) this.toggle();
1740    };
1741
1742    Collapse.VERSION = "3.2.0";
1743
1744    Collapse.DEFAULTS = {
1745        toggle: true,
1746    };
1747
1748    Collapse.prototype.dimension = function() {
1749        var hasWidth = this.$element.hasClass("width");
1750        return hasWidth ? "width" : "height";
1751    };
1752
1753    Collapse.prototype.show = function() {
1754        if (this.transitioning || this.$element.hasClass("in")) return;
1755
1756        var startEvent = $.Event("show.bs.collapse");
1757        this.$element.trigger(startEvent);
1758        if (startEvent.isDefaultPrevented()) return;
1759
1760        var actives = this.$parent && this.$parent.find("> .panel > .in");
1761
1762        if (actives && actives.length) {
1763            var hasData = actives.data("bs.collapse");
1764            if (hasData && hasData.transitioning) return;
1765            Plugin.call(actives, "hide");
1766            hasData || actives.data("bs.collapse", null);
1767        }
1768
1769        var dimension = this.dimension();
1770
1771        this.$element
1772            .removeClass("collapse")
1773            .addClass("collapsing")
1774            [dimension](0);
1775
1776        this.transitioning = 1;
1777
1778        var complete = function() {
1779            this.$element
1780                .removeClass("collapsing")
1781                .addClass("collapse in")
1782                [dimension]("");
1783            this.transitioning = 0;
1784            this.$element.trigger("shown.bs.collapse");
1785        };
1786
1787        if (!$.support.transition) return complete.call(this);
1788
1789        var scrollSize = $.camelCase(["scroll", dimension].join("-"));
1790
1791        this.$element
1792            .one("bsTransitionEnd", $.proxy(complete, this))
1793            .emulateTransitionEnd(350)
1794            [dimension](this.$element[0][scrollSize]);
1795    };
1796
1797    Collapse.prototype.hide = function() {
1798        if (this.transitioning || !this.$element.hasClass("in")) return;
1799
1800        var startEvent = $.Event("hide.bs.collapse");
1801        this.$element.trigger(startEvent);
1802        if (startEvent.isDefaultPrevented()) return;
1803
1804        var dimension = this.dimension();
1805
1806        this.$element[dimension](this.$element[dimension]())[0].offsetHeight;
1807
1808        this.$element
1809            .addClass("collapsing")
1810            .removeClass("collapse")
1811            .removeClass("in");
1812
1813        this.transitioning = 1;
1814
1815        var complete = function() {
1816            this.transitioning = 0;
1817            this.$element
1818                .trigger("hidden.bs.collapse")
1819                .removeClass("collapsing")
1820                .addClass("collapse");
1821        };
1822
1823        if (!$.support.transition) return complete.call(this);
1824
1825        this.$element[dimension](0)
1826            .one("bsTransitionEnd", $.proxy(complete, this))
1827            .emulateTransitionEnd(350);
1828    };
1829
1830    Collapse.prototype.toggle = function() {
1831        this[this.$element.hasClass("in") ? "hide" : "show"]();
1832    };
1833
1834    // COLLAPSE PLUGIN DEFINITION
1835    // ==========================
1836
1837    function Plugin(option) {
1838        return this.each(function() {
1839            var $this = $(this);
1840            var data = $this.data("bs.collapse");
1841            var options = $.extend(
1842                {},
1843                Collapse.DEFAULTS,
1844                $this.data(),
1845                typeof option == "object" && option
1846            );
1847
1848            if (!data && options.toggle && option == "show") option = !option;
1849            if (!data)
1850                $this.data("bs.collapse", (data = new Collapse(this, options)));
1851            if (typeof option == "string") data[option]();
1852        });
1853    }
1854
1855    var old = $.fn.collapse;
1856
1857    $.fn.collapse = Plugin;
1858    $.fn.collapse.Constructor = Collapse;
1859
1860    // COLLAPSE NO CONFLICT
1861    // ====================
1862
1863    $.fn.collapse.noConflict = function() {
1864        $.fn.collapse = old;
1865        return this;
1866    };
1867
1868    // COLLAPSE DATA-API
1869    // =================
1870
1871    $(document).on(
1872        "click.bs.collapse.data-api",
1873        '[data-toggle="collapse"]',
1874        function(e) {
1875            var href;
1876            var $this = $(this);
1877            var target =
1878                $this.attr("data-target") ||
1879                e.preventDefault() ||
1880                ((href = $this.attr("href")) &&
1881                    href.replace(/.*(?=#[^\s]+$)/, "")); // strip for ie7
1882            var $target = $(target);
1883            var data = $target.data("bs.collapse");
1884            var option = data ? "toggle" : $this.data();
1885            var parent = $this.attr("data-parent");
1886            var $parent = parent && $(parent);
1887
1888            if (!data || !data.transitioning) {
1889                if ($parent)
1890                    $parent
1891                        .find(
1892                            '[data-toggle="collapse"][data-parent="' +
1893                                parent +
1894                                '"]'
1895                        )
1896                        .not($this)
1897                        .addClass("collapsed");
1898                $this[$target.hasClass("in") ? "addClass" : "removeClass"](
1899                    "collapsed"
1900                );
1901            }
1902
1903            Plugin.call($target, option);
1904        }
1905    );
1906})(jQuery);
1907
1908function sln_facebookInit() {
1909    window.fbAsyncInit = function() {
1910        FB.init({
1911            appId: salon.fb_app_id,
1912            cookie: true,
1913            xfbml: true,
1914            version: "v2.8",
1915        });
1916        FB.AppEvents.logPageView();
1917
1918        jQuery("[data-salon-click=fb_login]")
1919            .off("click")
1920            .on("click", function() {
1921                FB.login(
1922                    function() {
1923                        sln_facebookLogin();
1924                    },
1925                    { scope: "email" }
1926                );
1927
1928                return false;
1929            });
1930    };
1931
1932    (function(d, s, id) {
1933        var js,
1934            fjs = d.getElementsByTagName(s)[0];
1935        if (d.getElementById(id)) {
1936            return;
1937        }
1938        js = d.createElement(s);
1939        js.id = id;
1940
1941        var locale =
1942            typeof salon.fb_locale !== "undefined" ? salon.fb_locale : "en_US";
1943
1944        js.src = "//connect.facebook.net/" + locale + "/sdk.js";
1945        fjs.parentNode.insertBefore(js, fjs);
1946    })(document, "script", "facebook-jssdk");
1947}
1948
1949function sln_facebookLogin() {
1950    var auth = FB.getAuthResponse();
1951
1952    if (!auth) {
1953        return;
1954    }
1955
1956    var $form = jQuery("#salon-step-details");
1957
1958    if ($form.length) {
1959        $form.append(
1960            '<input type="hidden" name="fb_access_token" value="' +
1961                auth.accessToken +
1962                '" />'
1963        );
1964        $form.find("[name=submit_details]").trigger("click");
1965        return;
1966    }
1967
1968    jQuery.ajax({
1969        url: salon.ajax_url,
1970        data: {
1971            accessToken: auth.accessToken,
1972            action: "salon",
1973            method: "FacebookLogin",
1974            security: salon.ajax_nonce,
1975        },
1976        method: "POST",
1977        dataType: "json",
1978        success: function(response) {
1979            if (response.success) {
1980                location.reload();
1981            } else {
1982                alert("error");
1983                //console.log(response);
1984            }
1985        },
1986        error: function(data) {
1987            alert("error");
1988            //console.log(data);
1989        },
1990    });
1991}
1992
1993function sln_salonBookingCalendarInit() {
1994    if (jQuery("#sln-salon-booking-calendar-shortcode").length === 0) {
1995        return;
1996    }
1997    sln_salonBookingCalendarInitTooltip();
1998
1999    setInterval(function() {
2000        jQuery.ajax({
2001            url: salon.ajax_url,
2002            data: {
2003                action: "salon",
2004                method: "salonCalendar",
2005                security: salon.ajax_nonce,
2006                attrs: JSON.parse(
2007                    jQuery(
2008                        "#sln-salon-booking-calendar-shortcode .booking-main"
2009                    ).attr("data-attrs")
2010                ),
2011            },
2012
2013            method: "POST",
2014            dataType: "json",
2015            success: function(data) {
2016                if (data.success) {
2017                    jQuery(
2018                        "#sln-salon-booking-calendar-shortcode > .wrapper"
2019                    ).html(data.content);
2020                    sln_salonBookingCalendarInitTooltip();
2021                } else if (data.redirect) {
2022                    window.location.href = data.redirect;
2023                } else if (data.errors) {
2024                    // TODO: display errors
2025                }
2026            },
2027            error: function(data) {
2028                alert("error");
2029                //console.log(data);
2030            },
2031        });
2032    }, 10 * 1000);
2033}
2034
2035function sln_salonBookingCalendarInitTooltip() {
2036    jQuery('[data-toggle="tooltip"]').tooltip();
2037}
2038
2039function sln_createRatings(readOnly, view) {
2040    jQuery("[name=sln-rating]").each(function() {
2041        if (jQuery(this).val()) {
2042            sln_createRaty(jQuery(this), readOnly, view);
2043        }
2044    });
2045}
2046
2047function sln_createRaty($rating, readOnly, view) {
2048    readOnly = readOnly == undefined ? false : readOnly;
2049    view = view == undefined ? "star" : view;
2050
2051    var starOnClass = "glyphicon";
2052    var starOffClass = "glyphicon";
2053
2054    if (view === "circle") {
2055        starOnClass += " sln-rate-service-on";
2056        starOffClass += " sln-rate-service-off";
2057    } else {
2058        starOnClass += " glyphicon-star";
2059        starOffClass += " glyphicon-star-empty";
2060    }
2061
2062    var $ratyElem = $rating.parent().find(".rating");
2063    $ratyElem.raty({
2064        score: jQuery($rating).val(),
2065        space: false,
2066        path: salon.images_folder,
2067        readOnly: readOnly,
2068        starType: "i",
2069        starOff: starOffClass,
2070        starOn: starOnClass,
2071    });
2072    $ratyElem.css("display", "block");
2073}
2074
2075function sln_renderAvailableTimeslots($, data) {
2076    $(".datetimepicker-minutes table tr td").html("");
2077
2078    //for active timeslot to stay
2079    var datetimepicker = $(".sln_timepicker div").data("datetimepicker");
2080
2081    if (salon.time_format.includes('H:iip')) {
2082        var DtHours = datetimepicker.viewDate.getUTCHours();
2083        var DtHoursOld = DtHours;
2084        var DtHours = DtHours >= 13 ? DtHours % 12 : DtHours;
2085        DtHours = DtHours >= 10 ? DtHours : "0" + DtHours;
2086        var DtMinutes = datetimepicker.viewDate.getUTCMinutes();
2087        DtMinutes = DtMinutes >= 10 ? DtMinutes : "0" + DtMinutes;
2088        var DtTime = DtHours + ":" + DtMinutes;
2089        DtTime = DtHoursOld >= 12 ? DtTime + "pm" : DtTime + "am";
2090    } else {
2091        var DtHours = datetimepicker.viewDate.getUTCHours();
2092        DtHours = DtHours >= 10 ? DtHours : "0" + DtHours;
2093        var DtMinutes = datetimepicker.viewDate.getUTCMinutes();
2094        DtMinutes = DtMinutes >= 10 ? DtMinutes : "0" + DtMinutes;
2095        var DtTime = DtHours + ":" + DtMinutes;
2096    }
2097    let dateString = $('#sln_timepicker_viewdate').text().split('|')[0] + ' | ' + DtTime;
2098    $("#sln_timepicker_viewdate").text(dateString);
2099
2100    var html = [];
2101
2102    var date = datetimepicker.getDate();
2103    $.each(data.intervals.workTimes, function(value) {
2104        var hours = parseInt(value, 10) || 0;
2105        var minutes = parseInt(value.substr(value.indexOf(":") + 1), 10) || 0;
2106
2107        date.setUTCHours(hours);
2108        date.setUTCMinutes(minutes);
2109
2110        html.push(
2111            '<span data-ymd="' +
2112                value +
2113                '" class="minute disabled' +
2114                (value === DtTime ? " active" : "") +
2115                '">' +
2116                $.fn.datetimepicker.DPGlobal.formatDate(
2117                    date,
2118                    datetimepicker.format,
2119                    datetimepicker.language,
2120                    datetimepicker.formatType
2121                ) +
2122                "</span>"
2123        );
2124    });
2125
2126    $(".datetimepicker-minutes table tr td").html(html.join(""));
2127
2128    $(".datetimepicker-minutes table tr td .minute").on("click", function() {
2129        var datetimepicker = $(".sln_timepicker div").data("datetimepicker");
2130
2131        var time = $(this).attr("data-ymd");
2132
2133        var hours = parseInt(time, 10) || 0;
2134        var minutes = parseInt(time.substr(time.indexOf(":") + 1), 10) || 0;
2135
2136        datetimepicker.element.on('changeDate', function() {
2137            datetimepicker.viewDate.setUTCHours(hours);
2138            datetimepicker.viewDate.setUTCMinutes(minutes);
2139        });
2140        let dateString = $('#sln_timepicker_viewdate').text().split('|')[0] + ' | ' + time;
2141        $("#sln_timepicker_viewdate").text(dateString);
2142
2143
2144        $('#sln-booking-cloned-notice').hide();
2145        $("input[name='sln[time]']").val(time);
2146        //for reschedule timepicker
2147        $("input[name='_sln_booking_time']").val(time);
2148    });
2149    setTimeout(() => {
2150        $(".datetimepicker-days table tr th.next").on("click", function() {
2151            $("body").trigger("sln_date");
2152        });
2153        $(".datetimepicker-days table tr th.prev").on("click", function() {
2154            $("body").trigger("sln_date");
2155        });
2156    }, 0);
2157}
2158jQuery(function($) {
2159    $(function() {
2160        if ($(".sln-customcolors").length) {
2161            $("body").addClass("sln-salon-page-customcolors");
2162        }
2163    });
2164});
2165// DIVI THEME ACCORDION FIX SNIPPET
2166jQuery(function($) {
2167    if ($("body.theme-Divi").length || $("body.et_divi_theme").length) {
2168        $(".sln-panel-heading").off("click");
2169    }
2170});
2171// DIVI THEME ACCORDION FIX SNIPPET // END
2172
2173function sln_applyTipsAmount() {
2174    var $ = jQuery;
2175    var amount = $("#sln_tips").val();
2176
2177    var data =
2178        "sln[tips]=" +
2179        amount +
2180        "&action=salon&method=applyTipsAmount&security=" +
2181        salon.ajax_nonce;
2182
2183    $.ajax({
2184        url: salon.ajax_url,
2185        data: data,
2186        method: "POST",
2187        dataType: "json",
2188        success: function(data) {
2189            $("#sln_tips_status")
2190                .find(".sln-alert")
2191                .remove();
2192            var alertBox;
2193            if (data.success) {
2194                $("#sln_tips_value").html(data.tips);
2195                $('.sln-summary-row.sln-summary-row--tips').toggleClass('hide', data.tips.startsWith('0'));
2196                $(".sln-total-price").html(data.total);
2197
2198                alertBox = $(
2199                    '<div class="sln-alert sln-alert--paddingleft sln-alert--success"></div>'
2200                );
2201            } else {
2202                alertBox = $(
2203                    '<div class="sln-alert sln-alert--paddingleft sln-alert--problem"></div>'
2204                );
2205            }
2206            $(data.errors).each(function() {
2207                alertBox.append("<p>").html(this);
2208            });
2209            $("#sln_tips_status")
2210                .html("")
2211                .append(alertBox);
2212        },
2213        error: function(data) {
2214            alert("error");
2215            //console.log(data);
2216        },
2217    });
2218
2219    return false;
2220}
2221
2222function sln_google_maps_places_api_callback() {
2223    if (
2224        typeof google == "object" &&
2225        typeof google.maps == "object" &&
2226        typeof google.maps.places == "object"
2227    ) {
2228        var address_inputs = [
2229            "_sln_booking_address",
2230            "sln_address",
2231            "salon_settings_gen_address",
2232            "sln_customer_meta__sln_address",
2233        ];
2234        address_inputs.forEach((address_input) => {
2235            var address_input_obj = document.getElementById(address_input);
2236            if (
2237                !!address_input_obj &&
2238                address_input_obj instanceof HTMLInputElement &&
2239                address_input_obj.type == "text"
2240            ) {
2241                new google.maps.places.Autocomplete(
2242                    document.getElementById(address_input)
2243                );
2244            }
2245        });
2246    }
2247}
2248
2249jQuery(function($) {
2250    function sln_rememberTab() {
2251        $.ajax({
2252            url: salon.ajax_url,
2253            method: 'POST',
2254            dataType: 'json',
2255            data: {
2256                action: 'salon',
2257                method: 'rememberTab',
2258                security: salon.ajax_nonce,
2259                tab: $(this).data('tab'),
2260            },
2261            error: function (error) {
2262                console.log('cannot remember tab');
2263            },
2264        });
2265    }
2266
2267    $('.sln-content__tabs__nav__item a').on('click', sln_rememberTab);
2268});

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.