PageSourceSearch

https://maldivy.ru/local/templates/main/js/script.js?1786713084154597

js maldivy.ru collected 2026-10-09 21:36:50 UTC 154,597 bytes, 4,368 lines download raw bytes

1Fancybox.defaults.placeFocusBack = false;
2// Fancybox.defaults.autoFocus = false;
3
4
5
6const convertImages = (query, callback) => {
7	const images = document.querySelectorAll(query);
8
9	images.forEach(image => {
10		fetch(image.src)
11			.then(res => res.text())
12			.then(data => {
13				const parser = new DOMParser();
14				const svg = parser.parseFromString(data, 'image/svg+xml').querySelector('svg');
15
16				if (image.id) svg.id = image.id;
17				if (image.className) svg.classList = image.classList;
18
19				image.parentNode.replaceChild(svg, image);
20			})
21			.then(callback)
22			.catch(error => console.error(error))
23	});
24}
25
26function declOfNum(number, words) {
27	return words[(number % 100 > 4 && number % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][(number % 10 < 5) ? Math.abs(number) % 10 : 5]];
28}
29
30function calcScroll() {
31	let div = document.createElement('div');
32
33	div.style.width = '50px';
34	div.style.height = '50px';
35	div.style.overflowY = 'scroll';
36	div.style.visibility = 'hidden';
37
38	document.body.appendChild(div);
39	let scrollWidth = div.offsetWidth - div.clientWidth;
40	div.remove();
41
42	return scrollWidth;
43}
44
45
46
47
48
49
50function atollsSlider() {
51	let slider = new Swiper(".atolls-slider.swiper-container", {
52		slidesPerView: 1,
53		spaceBetween: 10,
54		loop: false,
55		observer: true,
56		observeParents: true,
57		watchOverflow: true,
58		touchReleaseOnEdges: true,
59		speed: 700,
60		navigation: {
61			nextEl: ".atolls-slider__next",
62			prevEl: ".atolls-slider__prev",
63		},
64		breakpoints: {
65			480: {
66				slidesPerView: 2,
67				spaceBetween: 10,
68			},
69			768: {
70				slidesPerView: 3,
71				spaceBetween: 10,
72			},
73			1200: {
74				slidesPerView: 4,
75				spaceBetween: 10,
76			},
77		}
78	});
79}
80function blogSliderInnerMob() {
81	let slider = new Swiper(".blog-slider-inner-mob.swiper-container", {
82		slidesPerView: 'auto',
83		spaceBetween: 10,
84		loop: false,
85		observer: true,
86		observeParents: true,
87		watchOverflow: true,
88		touchReleaseOnEdges: true,
89		speed: 700,
90		navigation: {
91			nextEl: ".blog-slider-inner-mob__next",
92			prevEl: ".blog-slider-inner-mob__prev",
93		},
94		breakpoints: {
95			768: {
96				slidesPerView: 2,
97				spaceBetween: 10,
98			},
99			1440: {
100				slidesPerView: 3,
101				spaceBetween: 10,
102			},
103		}
104	});
105}
106function ourTeamSlider() {
107	let slider = new Swiper(".our-team-slider.swiper-container", {
108		slidesPerView: 1,
109		spaceBetween: 10,
110		loop: false,
111		observer: true,
112		observeParents: true,
113		watchOverflow: true,
114		touchReleaseOnEdges: true,
115		speed: 700,
116		navigation: {
117			nextEl: ".our-team-slider__next",
118			prevEl: ".our-team-slider__prev",
119		},
120		breakpoints: {
121			480: {
122				slidesPerView: 2,
123				spaceBetween: 10,
124			},
125			768: {
126				slidesPerView: 3,
127				spaceBetween: 10,
128			},
129			992: {
130				slidesPerView: 4,
131				spaceBetween: 10,
132			},
133			1200: {
134				slidesPerView: 5,
135				spaceBetween: 10,
136			},
137		}
138	});
139}
140function blogSlider() {
141	let slider = new Swiper(".blog-slider.swiper-container", {
142		slidesPerView: 1,
143		spaceBetween: 10,
144		loop: false,
145		observer: true,
146		observeParents: true,
147		watchOverflow: true,
148		touchReleaseOnEdges: true,
149		speed: 700,
150		navigation: {
151			nextEl: ".blog-slider__next",
152			prevEl: ".blog-slider__prev",
153		},
154		breakpoints: {
155			768: {
156				slidesPerView: 2,
157				spaceBetween: 10,
158			},
159			1440: {
160				slidesPerView: 'auto',
161				spaceBetween: 10,
162			},
163		}
164	});
165}
166function blogSliderInner() {
167	let slider = new Swiper(".blog-slider-inner.swiper-container", {
168		slidesPerView: 'auto',
169		spaceBetween: 10,
170		loop: false,
171		observer: true,
172		observeParents: true,
173		watchOverflow: true,
174		touchReleaseOnEdges: true,
175		speed: 700,
176		navigation: {
177			nextEl: ".blog-slider-inner__next",
178			prevEl: ".blog-slider-inner__prev",
179		},
180		breakpoints: {
181			768: {
182				slidesPerView: 2,
183				spaceBetween: 10,
184			},
185			1440: {
186				slidesPerView: 'auto',
187				spaceBetween: 10,
188			},
189		}
190	});
191}
192function storiesSlider() {
193	let slider = new Swiper(".stories-slider.swiper-container", {
194		slidesPerView: 1,
195		spaceBetween: 15,
196		loop: false,
197		observer: true,
198		observeParents: true,
199		watchOverflow: true,
200		touchReleaseOnEdges: true,
201		speed: 700,
202		navigation: {
203			nextEl: ".stories-slider__next",
204			prevEl: ".stories-slider__prev",
205		},
206		breakpoints: {
207			480: {
208				slidesPerView: 2,
209				spaceBetween: 15,
210			},
211			768: {
212				slidesPerView: 3,
213				spaceBetween: 15,
214			},
215			1200: {
216				slidesPerView: 4,
217				spaceBetween: 15,
218			},
219		}
220	});
221}
222function awardsSlider() {
223	let prev, next, pagination;
224	$('.awards-slider.swiper-container').each(function (index, value) {
225		prev = $(value).parents('.awards-block').find('.awards-slider__prev')[0];
226		next = $(value).parents('.awards-block').find('.awards-slider__next')[0];
227		pagination = $(value).parents('.awards-block').find('.awards-slider__pagination')[0];
228		let slider = new Swiper(value, {
229			slidesPerView: 1,
230			spaceBetween: 10,
231			loop: false,
232			observer: true,
233			observeParents: true,
234			watchOverflow: true,
235			touchReleaseOnEdges: true,
236			speed: 700,
237			rewind: true,
238			pagination: {
239				el: pagination,
240				clickable: true,
241			},
242			navigation: {
243				nextEl: next,
244				prevEl: prev,
245			},
246			breakpoints: {
247				425: {
248					slidesPerView: 2,
249					spaceBetween: 10,
250				},
251				768: {
252					slidesPerView: 3,
253					spaceBetween: 20,
254				},
255				992: {
256					slidesPerView: 4,
257					spaceBetween: 20,
258				},
259			}
260		});
261	});
262}
263function itemProductSlider() {
264	let slider = new Swiper(".item-product-slider.swiper-container", {
265		slidesPerView: 1,
266		spaceBetween: 0,
267		loop: false,
268		observer: true,
269		observeParents: true,
270		watchOverflow: true,
271		touchReleaseOnEdges: true,
272		speed: 700,
273		pagination: {
274			type: "fraction",
275			el: ".item-product-slider__fraction"
276		},
277		navigation: {
278			nextEl: ".item-product-slider__next",
279			prevEl: ".item-product-slider__prev",
280		},
281		on: {
282			slideChange: function () {
283				let slider = this.$el;
284				if (this.activeIndex + 1 == this.slides.length) {
285					$(slider).addClass('hide-nav')
286				} else {
287					$(slider).removeClass('hide-nav')
288				}
289			},
290		},
291	});
292}
293function categoriesSlider() {
294	if ($('.categories-slider').length) {
295		$('.categories-slider.swiper-container').each(function (index, value) {
296			let slider = undefined;
297			function initSwiper() {
298				var screenWidth = $(window).width();
299				if (screenWidth < 768 && slider == undefined) {
300					slider = new Swiper(value, {
301						slidesPerView: 'auto',
302						spaceBetween: 10,
303						loop: false,
304						observer: true,
305						observeParents: true,
306						watchOverflow: true,
307						touchReleaseOnEdges: true,
308						freeMode: true,
309						speed: 700,
310						pagination: {
311							el: ".categories-slider__pagination",
312							clickable: true
313						},
314					});
315				} else if (screenWidth > 767 && slider != undefined) {
316					slider.destroy();
317					slider = undefined;
318					$('.categories-slider').find('.swiper-wrapper').removeAttr('style');
319					$('.categories-slider').find('.swiper-slide').removeAttr('style');
320				}
321			}
322			initSwiper();
323			$(window).resize(function () {
324				initSwiper();
325			});
326		});
327	}
328}
329function stockSlider() {
330	if ($('.stock-slider').length) {
331		$('.stock-slider.swiper-container').each(function (index, value) {
332			let slider = undefined;
333			function initSwiper() {
334				var screenWidth = $(window).width();
335				if (screenWidth < 768 && slider == undefined) {
336					slider = new Swiper(value, {
337						slidesPerView: 'auto',
338						spaceBetween: 10,
339						loop: false,
340						observer: true,
341						observeParents: true,
342						watchOverflow: true,
343						touchReleaseOnEdges: true,
344						freeMode: true,
345						speed: 700,
346						pagination: {
347							el: ".stock-slider__pagination",
348							clickable: true
349						},
350					});
351				} else if (screenWidth > 767 && slider != undefined) {
352					slider.destroy();
353					slider = undefined;
354					$('.stock-slider').find('.swiper-wrapper').removeAttr('style');
355					$('.stock-slider').find('.swiper-slide').removeAttr('style');
356				}
357			}
358			initSwiper();
359			$(window).resize(function () {
360				initSwiper();
361			});
362		});
363	}
364}
365
366// function galleryGridSlider() {
367// 	let slider = new Swiper(".gallery-grid-slider.swiper-container", {
368// 		slidesPerView: 1,
369// 		spaceBetween: 10,
370// 		loop: false,
371// 		observer: true,
372// 		observeParents: true,
373// 		watchOverflow: true,
374// 		touchReleaseOnEdges: true,
375// 		speed: 700,
376// 		navigation: {
377// 			nextEl: ".gallery-grid-slider__next",
378// 			prevEl: ".gallery-grid-slider__prev",
379// 		},
380// 		breakpoints: {
381// 			576: {
382// 				slidesPerView: 'auto',
383// 				spaceBetween: 10,
384// 			},
385// 		}
386// 	});
387// }
388function galleryGridSlider() {
389	let slider = new Swiper(".gallery-grid-slider.swiper-container", {
390		slidesPerView: 'auto',
391		spaceBetween: 10,
392		loop: false,
393		observer: true,
394		observeParents: true,
395		watchOverflow: true,
396		touchReleaseOnEdges: true,
397		speed: 700,
398		grid: {
399			rows: 1,
400		},
401		navigation: {
402			nextEl: ".gallery-grid-slider__next",
403			prevEl: ".gallery-grid-slider__prev",
404		},
405		breakpoints: {
406			576: {
407				slidesPerView: 'auto',
408				spaceBetween: 10,
409				grid: {
410					rows: 2,
411				}
412			}
413		}
414	});
415}
416
417
418function hotelsNearbySlider() {
419	let slider = new Swiper(".hotels-nearby-slider.swiper-container", {
420		slidesPerView: 1,
421		spaceBetween: 10,
422		loop: false,
423		observer: true,
424		observeParents: true,
425		watchOverflow: true,
426		touchReleaseOnEdges: true,
427		speed: 700,
428		navigation: {
429			nextEl: ".hotels-nearby-slider__next",
430			prevEl: ".hotels-nearby-slider__prev",
431		},
432		breakpoints: {
433			480: {
434				slidesPerView: 2,
435				spaceBetween: 10,
436			},
437			768: {
438				slidesPerView: 3,
439				spaceBetween: 20,
440			},
441			992: {
442				slidesPerView: 2,
443				spaceBetween: 20,
444			},
445			1200: {
446				slidesPerView: 3,
447				spaceBetween: 20,
448			}
449		}
450	});
451}
452function photoRoom() {
453	let sliders = $('.js-photo-room');
454	if (sliders.length) {
455		let prev, next;
456		$(sliders).each(function (index, value) {
457			prev = $(value).find('.photo-room-slider__prev')[0];
458			next = $(value).find('.photo-room-slider__next')[0];
459			let thumb = new Swiper($(value).find('.photo-room-thumbs.swiper-container')[0], {
460				spaceBetween: 10,
461				slidesPerView: 3,
462				watchSlidesProgress: true,
463				loop: true,
464				observer: true,
465				observeParents: true,
466				watchOverflow: true,
467				touchReleaseOnEdges: true,
468				direction: 'vertical',
469			});
470			let slider = new Swiper($(value).find('.photo-room-slider.swiper-container')[0], {
471				slidesPerView: 1,
472				spaceBetween: 20,
473				loop: true,
474				observer: true,
475				observeParents: true,
476				watchOverflow: true,
477				touchReleaseOnEdges: true,
478				simulateTouch: false,
479				speed: 300,
480				effect: 'fade',
481				autoHeight: true,
482				navigation: {
483					nextEl: next,
484					prevEl: prev,
485				},
486				thumbs: {
487					swiper: thumb,
488					autoScrollOffset: 1
489				},
490				breakpoints: {
491					768: {
492						speed: 300,
493						autoHeight: false,
494						simulateTouch: false,
495					},
496					992: {
497						speed: 300,
498						autoHeight: false,
499						simulateTouch: true,
500					}
501				},
502				on: {
503					slideChangeTransitionEnd: function () {
504						lazyLoadInstance.update();
505					}
506				}
507			});
508			$(window).on('resize', function () {
509				slider.update();
510			});
511		});
512	}
513}
514function imagesSlider() {
515	let slider = new Swiper(".images-slider.swiper-container", {
516		slidesPerView: 1,
517		spaceBetween: 10,
518		loop: false,
519		observer: true,
520		observeParents: true,
521		watchOverflow: true,
522		touchReleaseOnEdges: true,
523		speed: 700,
524		navigation: {
525			nextEl: ".images-slider__next",
526			prevEl: ".images-slider__prev",
527		},
528		breakpoints: {
529			375: {
530				slidesPerView: 2,
531				spaceBetween: 10,
532			},
533			768: {
534				slidesPerView: 3,
535				spaceBetween: 20,
536			},
537		}
538	});
539}
540let scrollTopBodyFixed = 0;
541
542function unlockBody() {
543	if (window.innerWidth < 992) { // только для мобилки
544		document.body.classList.remove('lock');
545		document.body.style.position = '';
546		document.body.style.top = '';
547		document.body.style.left = '';
548		document.body.style.right = '';
549		window.scrollTo(0, scrollTopBodyFixed); // вернёмся на место
550	}
551}
552function lockBody() {
553	if (window.innerWidth < 992) { // только для мобилки
554		scrollTopBodyFixed = window.scrollY || document.documentElement.scrollTop;
555		document.body.style.position = 'fixed';
556		document.body.style.top = `-${scrollTopBodyFixed}px`;
557		document.body.style.left = '0';
558		document.body.style.right = '0';
559		document.body.classList.add('lock');
560	}
561}
562
563
564
565function offerBlock() {
566	let contentHeight = $('.js-offer-block').find('.js-offer-block__content').outerHeight();
567	$('.js-offer-block').find('.js-offer-block__body').css('padding-bottom', contentHeight / 2 + 'px');
568	$('.js-offer-block').find('.js-offer-block__content').css('margin-bottom', '-' + contentHeight / 2 + 'px');
569	$('.js-offer-block').addClass('active');
570}
571
572function focusInput(item) {
573	if (item.val() !== '') {
574		item.parents('.js-input').addClass('active');
575	} else {
576		item.parents('.js-input').removeClass('active');
577	}
578}
579
580
581
582let allowScrolling = true;
583var lastScrollTop = 0;
584let isAnchorClicking = true;
585let lastScrollTopForUp = 0; // для отслеживания, с какого места начался скролл вверх
586
587$(window).on('scroll', function () {
588	let currentScrollTop = $(this).scrollTop();
589	let windowHeight = $(window).height();
590
591	let $block = $('.blog-content');
592	if ($block.length) {
593		let blockTop = $block.offset().top;           // положение блока сверху
594		let blockBottom = blockTop + $block.outerHeight(); // низ блока
595
596		// Если верх блока <= скролл (т.е. дошли до верха окна)
597		// и низ блока всё ещё видим (ниже верхней границы окна)
598		if (currentScrollTop >= blockTop && currentScrollTop < blockBottom) {
599			$('body').addClass('in-blog-content');
600		} else {
601			$('body').removeClass('in-blog-content');
602			if (!$('body').attr('class')) {
603				$('body').removeAttr('class');
604			}
605		}
606	}
607
608
609
610	// Проверка направления скролла
611	if (currentScrollTop < lastScrollTop) {
612		// Скролл вверх
613
614		// Если разница прокрутки вверх больше 100px
615		if ((lastScrollTopForUp - currentScrollTop) > 100) {
616			if (isAnchorClicking) {
617				$('body').addClass('show-elements');
618			}
619			if (isAnchorClicking) {
620				// $('body').addClass('show-bottom-nav').removeClass('hide-bottom-panel');
621				$('body').removeClass('hide-bottom-panel');
622				if (!$('body').attr('class')) {
623					$('body').removeAttr('class');
624				}
625			}
626		}
627	} else {
628		// Скролл вниз или без движения вверх
629
630		// Сбрасываем точку отсчёта для скролла вверх
631		lastScrollTopForUp = currentScrollTop;
632
633		// $('body').removeClass('show-elements show-bottom-nav');
634		$('body').removeClass('show-elements');
635		if (!$('body').attr('class')) {
636			$('body').removeAttr('class');
637		}
638	}
639
640	// Остальной код без изменений 
641	if (currentScrollTop > 200) {
642		$('body').addClass('show-btn-menu');
643		$('.js-scroll-top').addClass('show');
644	} else {
645		$('body').removeClass('show-btn-menu');
646		$('.js-scroll-top').removeClass('show');
647		if (!$('body').attr('class')) {
648			$('body').removeAttr('class');
649		}
650	}
651
652	lastScrollTop = currentScrollTop; // обновляем последнее значение прокрутки
653});
654window.isHovered = false;
655function isHoveredFunction() {
656	let windowWidth = $(window).width() + calcScroll();
657	// Если ширина окна больше 991 и функция ещё не была выполнена для этого случая
658	if (windowWidth > 991) {
659		window.isHovered = true;
660	}
661	// Если ширина окна меньше 992 и функция ещё не была выполнена для этого случая
662	else {
663		window.isHovered = false;
664	}
665	return window.isHovered
666}
667$(window).on('resize', function () {
668	offerBlock();
669	isHoveredFunction();
670});
671const checkElement = setInterval(function () {
672	const element = document.querySelector('.js-offer-block'); // Укажите нужный селектор
673	if (element) {
674		offerBlock();
675		clearInterval(checkElement); // Прекращаем проверку
676	}
677}, 100); // Проверка каждый 100 миллисекунд
678document.addEventListener("DOMContentLoaded", function () {
679	offerBlock();
680});
681
682function updateVh() {
683	const vh = window.innerHeight * 0.01;
684	document.documentElement.style.setProperty('--vh', `${vh}px`);
685	document.querySelector('body').style.setProperty('--scrollbar-width', calcScroll() + 'px');
686}
687
688
689window.addEventListener('orientationchange', updateVh);
690window.addEventListener('resize', updateVh);
691var lazyLoadInstance;
692
693
694
695
696let scrollPosition = 0;
697let lockCount = 0;
698
699function lockBodyScroll() {
700	if (lockCount === 0) {
701		scrollPosition = window.pageYOffset;
702
703		const scrollBarWidth = window.innerWidth - document.documentElement.clientWidth;
704
705		document.body.style.position = 'fixed';
706		document.body.style.top = `-${scrollPosition}px`;
707		document.body.style.left = '0';
708		document.body.style.right = '0';
709		document.body.style.width = '100%';
710
711		// компенсация скроллбара (для десктопа)
712		if (scrollBarWidth > 0) {
713			document.body.style.paddingRight = scrollBarWidth + 'px';
714		}
715	}
716
717	lockCount++;
718}
719
720function unlockBodyScroll() {
721	lockCount--;
722
723	if (lockCount <= 0) {
724		const offset = parseInt(document.body.style.top || '0') * -1;
725
726		document.body.style.position = '';
727		document.body.style.top = '';
728		document.body.style.left = '';
729		document.body.style.right = '';
730		document.body.style.width = '';
731		document.body.style.paddingRight = '';
732
733		window.scrollTo(0, offset);
734
735		lockCount = 0;
736	}
737}
738
739
740
741
742$(document).ready(function () {
743
744
745	updateVh(); // вызвать при инициализации
746	isHoveredFunction(); // Переменная для отслеживания состояния наведения/касания
747	$(".js-input input, .js-input textarea").each(function (index, value) {
748		focusInput($(this))
749	});
750	if ($(window).scrollTop() > 200) {
751		$('body').addClass('show-btn-menu');
752		$('.js-scroll-top').addClass('show');
753	} else {
754		$('body').removeClass('show-btn-menu');
755		$('.js-scroll-top').removeClass('show');
756		if (!$('body').attr('class')) {
757			$('body').removeAttr('class');
758		}
759	}
760	lazyLoadInstance = new LazyLoad({
761		// Your custom settings go here
762		callback_loading: (el) => {
763			$(el).parent().addClass('loading-block');
764		},
765		callback_loaded: (el) => {
766			$(el).parent().removeClass('loading-block');
767		}
768	});
769	convertImages('img.js-convert-to-svg');
770	Fancybox.bind("[data-fancybox]", {
771		// on: {
772		// 	close: (fancybox, slide) => {
773		// 		const $timerEl = $('.js-counter-block');
774		// 		const intervalId = $timerEl.data('interval');
775		// 		if (intervalId) {
776		// 			clearInterval(intervalId);
777		// 		}
778		// 	},
779		// },
780		Toolbar: {
781			display: {
782				right: ["close"],
783			}
784		},
785		Thumbs: {
786			type: "classic",
787		},
788		backdropClick: false,
789		dragToClose: false,
790		on: {
791			ready: () => lockBodyScroll(),
792			destroy: () => unlockBodyScroll()
793		}
794	});
795	Fancybox.bind("[data-fancybox^='video']", {
796		groupAll: false,
797		mainClass: "gallery-video-fancybox",
798		dragToClose: false,
799		on: {
800			ready: () => lockBodyScroll(),
801			destroy: () => unlockBodyScroll()
802		}
803	});
804	Fancybox.bind("[data-fancybox^='full-video']", {
805		mainClass: "gallery-video-full",
806		on: {
807			ready: () => lockBodyScroll(),
808			destroy: () => unlockBodyScroll()
809		}
810	});
811	Fancybox.bind("[data-fancybox$='gallery-awards']", {
812		contentClick: false,
813		backdropClick: false,
814		dragToClose: false,
815		mainClass: "gallery-awards-fancybox",
816		wheel: false,
817		Toolbar: {
818			display: {
819				right: ["close"],
820			}
821		},
822		Thumbs: false,
823		on: {
824			ready: () => lockBodyScroll(),
825			destroy: () => unlockBodyScroll()
826		}
827	});
828	$('input[type="tel"]').inputmask({
829		mask: "+7(999) 999-99-99",
830		inputmode: "numeric",
831	});
832
833	if ($('.js-item-panzoom').length) {
834		$('.js-item-panzoom').each(function (index, value) {
835			const panzoomInstance = new Panzoom(value, {
836				panMode: "mousemove",
837			});
838			// Сохраняем экземпляр в DOM-элемент, чтобы использовать в обработчиках
839			$(value).data('panzoomInstance', panzoomInstance);
840
841			// Наведение мыши — увеличить зум до 1.5
842			$(value).on('mouseenter', function () {
843				panzoomInstance.zoomTo(1.5, { friction: "auto" });
844			});
845
846			// Уход мыши — вернуть зум к 1 
847			$(value).on('mouseleave', function () {
848				panzoomInstance.zoomTo(1, { friction: "auto" });
849			});
850		});
851	}
852	if ($('.js-img-plan-block.villa-plan__plan').length) {
853		$('.js-img-plan-block.villa-plan__plan').each(function (index, value) {
854			const panzoomInstance = new Panzoom(value, {
855				panMode: "mousemove",
856			});
857
858			// Сохраняем экземпляр в DOM-элемент, чтобы использовать в обработчиках
859			$(value).data('panzoomInstance', panzoomInstance);
860
861			// Наведение мыши — увеличить зум до 1.5
862			$(value).on('mouseenter', function () {
863				panzoomInstance.zoomTo(1.5, { friction: "auto" });
864			});
865
866			// Уход мыши — вернуть зум к 1
867			$(value).on('mouseleave', function () {
868				panzoomInstance.zoomTo(1, { friction: "auto" });
869			});
870		});
871	}
872
873
874
875	storiesSlider();
876	ourTeamSlider();
877	categoriesSlider();
878	stockSlider();
879	awardsSlider();
880	itemProductSlider();
881	atollsSlider();
882	blogSlider();
883	blogSliderInner();
884	blogSliderInnerMob();
885	galleryGridSlider();
886	hotelsNearbySlider();
887	imagesSlider();
888	photoRoom();
889	let isScrolling = false;
890	if ($('.menu-nav .js-link-anchor').length) {
891		$('.menu-nav .js-link-anchor').mPageScroll2id({
892			offset: 20,
893			highlightClass: "link-active",
894			forceSingleHighlight: true,
895			keepHighlightUntilNext: true,
896			highlightByNextTarget: true,
897			scrollSpeed: 700,
898			loop: true,
899			appendHash: true,
900			autoScrollSpeed: false,
901			pageEndSmoothScroll: false,
902			onStart: function () {
903				allowScrolling = false;
904			},
905			onComplete: function () {
906				allowScrolling = true;
907				isScrolling = false; // Разрешаем прокрутку, когда анимация завершена
908			}
909		});
910	}
911
912	if ($('.menu-nav-blog .js-link-anchor').length) {
913		$('.menu-nav-blog .js-link-anchor').mPageScroll2id({
914			offset: 20,
915			highlightClass: "link-active",
916			forceSingleHighlight: true,
917			keepHighlightUntilNext: false,
918			highlightByNextTarget: true,
919			loop: true,
920			appendHash: true,
921			autoScrollSpeed: false,
922			scrollSpeed: 700,
923			pageEndSmoothScroll: false,
924			onStart: function () {
925				allowScrolling = false;
926			},
927			onComplete: function () {
928				allowScrolling = true;
929				isScrolling = false; // Разрешаем прокрутку, когда анимация завершена
930			}
931		});
932	}
933
934	$(document).on('click', '.js-link-anchor', function () {
935
936		if (!isScrolling) {
937			isScrolling = true;  // Устанавливаем флаг, что идет прокрутка
938		}
939
940	});
941	// Блокировка прокрутки колесом мыши (с отключением passive)
942	window.addEventListener('wheel', function (e) {
943		if (isScrolling) {
944			e.preventDefault();  // Блокируем прокрутку
945		}
946	}, { passive: false }); // Здесь отключаем passive
947
948})
949
950$(document).on('input', 'input[type="tel"]', function () {
951	const $input = $(this);
952	const $parent = $input.closest('.js-input');
953	const $label = $parent.find('.form-label');
954
955	// Сохраняем оригинальный текст метки (один раз)
956	if (!$label.data('original-text')) {
957		$label.data('original-text', $label.text());
958	}
959	const originalText = $label.data('original-text');
960	const errorMessage = 'Недопустимый формат номера';
961
962	const digitsOnly = this.value.replace(/\D/g, '');
963	const firstAfter7 = digitsOnly.charAt(1);
964
965	if (digitsOnly.length > 1 && firstAfter7 !== '4' && firstAfter7 !== '9') {
966		$parent.addClass('error');
967		$label.text(errorMessage);
968	} else {
969		$parent.removeClass('error');
970		$label.text(originalText);
971	}
972});
973
974// Обработчик кликов по элементу .fancybox__container
975$(document).on('click', '.fancybox__carousel', function (event) {
976	// Проверяем, что галерея открыта
977	if ($('.fancybox__carousel').length > 0) {
978		const screenWidth = $(window).width();
979		const screenCenter = screenWidth / 2;
980
981		// Левая и правая части экрана
982		const leftLimit = screenCenter - 50;  // Левая часть экрана
983		const clickX = event.clientX;
984
985		// Если клик в левой части экрана
986		if (clickX < leftLimit) {
987			Fancybox.prev(); // Переключаем на предыдущую картинку
988		}
989		// Если клик не в левой части (значит, в правой)
990		else {
991			Fancybox.next(); // Переключаем на следующую картинку
992		}
993	}
994});
995function parseDate(str) {
996	if (!str) return null;
997	const parts = str.split('.');
998	if (parts.length !== 3) return null;
999
1000	const [day, month, year] = parts.map(Number);
1001	const date = new Date(year, month - 1, day);
1002
1003	return isNaN(date.getTime()) ? null : date;
1004}
1005
1006$(document).ready(function () {
1007
1008	$('.js-book-hotel').each(function () {
1009		let dpMin, dpMax;
1010		let from = $(this).find('.js-book-hotel__from');
1011		let to = $(this).find('.js-book-hotel__to');
1012		let fromText = $(this).find('.js-book-hotel__from-text');
1013		let toText = $(this).find('.js-book-hotel__to-text');
1014		let containerFrom = from.parents('.js-book-hotel__container')[0];
1015		let containerTo = to.parents('.js-book-hotel__container')[0];
1016		// Преобразование строк в даты
1017		let fromDate = parseDate(from.val());
1018		let toDate = parseDate(to.val());
1019
1020
1021
1022
1023		// Инициализация календаря "from"
1024		dpMin = new AirDatepicker(from[0], {
1025			container: containerFrom,
1026			toggleSelected: false,
1027			autoClose: true,
1028			selectedDates: fromDate ? [fromDate] : [],
1029			minDate: new Date(),
1030			onSelect({ date }) {
1031				dpMax.update({ minDate: date });
1032				fromText.text(date ? date.toLocaleDateString() : '');
1033				from.trigger('change');
1034			}
1035		});
1036
1037		// Инициализация календаря "to"
1038		dpMax = new AirDatepicker(to[0], {
1039			container: containerTo,
1040			toggleSelected: false,
1041			autoClose: true,
1042			selectedDates: toDate ? [toDate] : [],
1043			minDate: new Date(),
1044			onSelect({ date }) {
1045				dpMin.update({ maxDate: date });
1046				toText.text(date ? date.toLocaleDateString() : '');
1047				to.trigger('change');
1048			}
1049		});
1050
1051
1052	});
1053
1054
1055});
1056
1057
1058
1059$(window).on('load', function () {
1060
1061	// Проверка, есть ли в URL хеш (якорь)
1062	if (window.hashName) {
1063
1064		// Получаем элемент с ID из хеша
1065		var target = $(window.hashName);
1066		// Позиция по умосчанию = позиция элемента - 10
1067		let pos = target.offset().top - 10;
1068		if (target.hasClass('js-block-questions__item')) {
1069			if (!target.hasClass('active')) {
1070				target.find('.js-spoiler__title').trigger('click');
1071			}
1072		}
1073		if (target.hasClass('js-main-spoiler__title')) {
1074			if (!target.closest('.js-main-spoiler__title').hasClass('active')) {
1075				target.trigger('click');
1076				// Позиция блок с спецпредложениями
1077				pos = target.closest('.js-special-offers-hotel').find('.js-special-offers-hotel__head').offset().top - 10
1078			}
1079		}
1080		if (target.hasClass('js-documents__btn')) {
1081			target.trigger('click');
1082			pos = target.closest('.js-documents').find('.js-documents__text').offset().top - 10
1083		}
1084
1085		if (target.hasClass('js-main-spoiler__item')) {
1086			if (!target.hasClass('active')) {
1087				target.find('.js-main-spoiler__title').trigger('click');
1088			}
1089		}
1090		var menuItem = $('.js-menu-nav-new__item[href="' + hashName + '"]');
1091		if (menuItem.length) {
1092			pos = target.offset().top
1093		}
1094		// Если элемент существует
1095		if (target.length) {
1096			// Плавная прокрутка до элемента
1097			$('html, body').animate({ scrollTop: pos }, 700);
1098		}
1099		window.location.hash = window.hashName;
1100	}
1101});
1102
1103
1104
1105
1106
1107
1108
1109$(document).on('input', '.js-input input, .js-input textarea', function () {
1110	focusInput($(this))
1111});
1112$(document).on('input', '.js-input input, .js-input textarea', function () {
1113	$(this).closest('.js-input').addClass('focus');
1114});
1115$(document).on('focusin', '.js-input input, .js-input textarea', function () {
1116	$(this).closest('.js-input').addClass('focus');
1117});
1118$(document).on('focusout', '.js-input input, .js-input textarea', function () {
1119	$(this).closest('.js-input').removeClass('focus');
1120});
1121$(document).on('click', '.js-input__clear', function () {
1122	$(this).closest('.js-input').removeClass('active').find('input, textarea').val('');
1123});
1124$(document).on('mouseenter', '.element-blur', function () {
1125	$(this).removeClass('element-blur');
1126});
1127$(document).on('mouseenter', '.js-block-cursor', function () {
1128	$(this).addClass('cursor-hide');
1129});
1130
1131$(document).on('focusin', '.js-hotel-selection__input', function () {
1132	$(this).parents('.js-hotel-selection').addClass('open');
1133});
1134$(document).on('click', function (e) {
1135	if (!$(e.target).closest('.js-hotel-selection__body').length && !$(e.target).closest('.js-hotel-selection__btn').length && !$(e.target).closest('.js-hotels-filter__btn-search').length) {
1136		$('.js-hotel-selection').removeClass('open');
1137	}
1138});
1139
1140
1141//  Мобильное меню ======================
1142$(document).on('click', '.js-menu__btn', function () {
1143	if (!$(this).hasClass('open')) {
1144		isAnchorClicking = false; // Устанавливаем флаг, что скроллинг по якорю
1145		$('html, body').animate({
1146			scrollTop: 0
1147		}, 200);
1148		$(this).addClass('open');
1149		$('.js-menu').addClass('open').removeClass('hide');
1150		$('body').addClass('lock').removeClass('show-bottom-nav');
1151		$('.header').addClass('menu-open');
1152		setTimeout(() => {
1153
1154			isAnchorClicking = true; // Сбрасываем флаг после завершения анимации
1155		}, 300);
1156
1157
1158	} else {
1159		$(this).removeClass('open');
1160		$('.js-menu').addClass('hide');
1161		$('body').removeClass('lock').addClass('show-bottom-nav');
1162		$('.header').removeClass('menu-open');
1163		if (!$('body').attr('class')) {
1164			$('body').removeAttr('class');
1165		}
1166		setTimeout(() => {
1167			$('.js-menu').removeClass('hide open');
1168
1169		}, 400);
1170	}
1171});
1172$(document).on('click', '.js-menu', function (e) {
1173	if (!$(e.target).closest('.js-menu__btn').length && !$(e.target).closest('.js-menu__body').length) {
1174		$('.js-menu__btn').removeClass('open');
1175		$('.js-menu').removeClass('open');
1176		$('body').removeClass('lock');
1177		$('.header').removeClass('menu-open');
1178		if (!$('body').attr('class')) {
1179			$('body').removeAttr('class');
1180		}
1181	}
1182});
1183$(document).on('click', '.js-sub-menu__btn', function () {
1184	if ($(window).width() < 992) {
1185		let parent = $(this).parents('.js-menu__body');
1186		let item = $(this);
1187		if (!$(this).parents('.js-sub-menu').hasClass('open')) {
1188			$(this).parents('.js-menu__body').find('.js-sub-menu').removeClass('open');
1189			$(this).parents('.js-menu__body').find('.js-sub-menu__body').slideUp(300);
1190			$(this).parents('.js-sub-menu').addClass('open');
1191			$(this).parents('.js-sub-menu').find('.js-sub-menu__body').slideDown(300);
1192			setTimeout(() => {
1193				let element = item.parents('.js-sub-menu');
1194				let elementPosition = element.offset();
1195				let parentPosition = parent.offset();
1196				let realPosition = $(parent).scrollTop() + (elementPosition.top - parentPosition.top);
1197				$(parent).animate({
1198					scrollTop: realPosition
1199				}, 300);
1200			}, 300);
1201		} else {
1202			$(this).parents('.js-sub-menu').removeClass('open');
1203			$(this).parents('.js-sub-menu').find('.js-sub-menu__body').slide
1203Up(300);
1204			setTimeout(() => {
1205				$(parent).animate({
1206					scrollTop: 0
1207				}, 300);
1208			}, 300);
1209		}
1210	}
1211});
1212// Tabs start --------------------------
1213$(document).on('mouseenter', '.js-sub-menu__nav', function () {
1214	if ($(window).width() > 991) {
1215		let thisValueData = $(this).data('tab');
1216		$(this).parents('.js-sub-menu__body').find(`.js-sub-menu__box-item`).removeClass('active').hide();
1217		$(this).parents('.js-sub-menu__body').find(`.js-sub-menu__nav`).removeClass('active');
1218		$(this).addClass('active');
1219		$(this).parents('.js-sub-menu__body').find(`.js-sub-menu__box-item[data-tab="${thisValueData}"]`).addClass('active').show();
1220	}
1221});
1222// Tabs end --------------------------
1223$(document).on('click', '.js-sub-sub-menu__btn', function () {
1224	if ($(window).width() < 992) {
1225		let parent = $(this).parents('.js-menu__body');
1226		let item = $(this);
1227		if (!$(this).parents('.js-sub-sub-menu').hasClass('open')) {
1228			$(this).parents('.js-menu__body').find('.js-sub-sub-menu').removeClass('open');
1229			$(this).parents('.js-menu__body').find('.js-sub-sub-menu__body').slideUp(300);
1230			$(this).parents('.js-sub-sub-menu').addClass('open');
1231			$(this).parents('.js-sub-sub-menu').find('.js-sub-sub-menu__body').slideDown(300);
1232			setTimeout(() => {
1233				let element = item.parents('.js-sub-sub-menu');
1234				let elementPosition = element.offset();
1235				let parentPosition = parent.offset();
1236				let realPosition = $(parent).scrollTop() + (elementPosition.top - parentPosition.top);
1237				$(parent).animate({
1238					scrollTop: realPosition
1239				}, 300);
1240			}, 300);
1241		} else {
1242			$(this).parents('.js-sub-sub-menu').removeClass('open');
1243			$(this).parents('.js-sub-sub-menu').find('.js-sub-sub-menu__body').slideUp(300);
1244			setTimeout(() => {
1245				$(parent).animate({
1246					scrollTop: 0
1247				}, 300);
1248			}, 300);
1249		}
1250	}
1251});
1252
1253//  Мобильное меню end ======================
1254$(document).on('mouseenter', '.js-item-active', function () {
1255	$(this).removeClass('active');
1256});
1257
1258
1259// Меню навигации по странице
1260$(document).on('click', '.js-menu-nav__btn', function () {
1261	let item = $(this);
1262	let positioActive = $(this).parents('.js-menu-nav').find('.js-menu-nav__item.link-active');
1263	let positioActiveY = positioActive.position();
1264	let scrollBlock = $(this).parents('.js-menu-nav').find('.js-menu-nav__content');
1265	if (!$(this).hasClass('open')) {
1266		$(this).addClass('open');
1267		$(this).parents('.js-menu-nav').addClass('open');
1268		if (positioActive.length) {
1269			$(scrollBlock).animate({
1270				scrollTop: positioActiveY.top
1271			}, 0);
1272		}
1273		lockBody();
1274		$('body').addClass('lock hide-bottom-panel').removeClass('show-bottom-nav');
1275	} else {
1276		$(this).removeClass('open');
1277		$(this).parents('.js-menu-nav').addClass('hide');
1278		unlockBody();
1279		$('body').removeClass('lock hide-bottom-panel').addClass('show-bottom-nav');
1280		setTimeout(() => {
1281			$(item).parents('.js-menu-nav').removeClass('hide open');
1282		}, 400);
1283	}
1284});
1285$(document).on('click', '.js-menu-nav__item', function () {
1286	isAnchorClicking = false; // Устанавливаем флаг, что скроллинг по якорю
1287	let item = $(this);
1288	$(this).parents('.js-menu-nav').find('.js-menu-nav__btn').removeClass('open');
1289	$(this).parents('.js-menu-nav').addClass('hide');
1290	unlockBody();
1291	$('body').removeClass('lock');
1292	if (!$('body').attr('class')) {
1293		$('body').removeAttr('class');
1294	}
1295	setTimeout(() => {
1296		$(item).parents('.js-menu-nav').removeClass('hide open');
1297	}, 400);
1298	setTimeout(() => {
1299		$('body').removeClass('show-elements');
1300		if (!$('body').attr('class')) {
1301			$('body').removeAttr('class');
1302		}
1303		isAnchorClicking = true; // Сбрасываем флаг после завершения анимации
1304	}, 1500);
1305});
1306$(document).on('click', '.js-menu-nav__body', function (e) {
1307	if (!$(e.target).closest('.js-menu-nav__btn').length && !$(e.target).closest('.js-menu-nav__list').length) {
1308		$('.js-menu-nav__btn').removeClass('open');
1309		$('.js-menu-nav').addClass('hide');
1310		unlockBody();
1311		$('body').removeClass('lock hide-bottom-panel').addClass('show-bottom-nav');
1312		setTimeout(() => {
1313			$('.js-menu-nav').removeClass('hide open');
1314		}, 400);
1315	}
1316});
1317// Меню навигации по странице end
1318
1319
1320
1321// Нижняя панель навигации --------------------------
1322$(document).on('click', '.js-tab-panel__nav', function () {
1323	let thisValueData = $(this).data('tab');
1324	if (!$(this).hasClass('active')) {
1325		$(this).parents('.js-tab-panel').find('.js-tab-panel__nav').removeClass('active');
1326		$(this).addClass('active');
1327		$(this).parents('.js-tab-panel').addClass('open');
1328		lockBody();
1329		$('body').addClass('lock');
1330		let contentData = $(this).parents('.js-tab-panel').find('.js-tab-panel__item');
1331		contentData.each(function () {
1332			if ($(this).data('tab') == thisValueData) {
1333				let item = $(this);
1334				contentData.removeClass('open');
1335				setTimeout(() => {
1336					item.addClass('open');
1337				}, 150);
1338			}
1339		});
1340	} else {
1341		$(this).parents('.js-tab-panel').find('.js-tab-panel__nav').removeClass('active');
1342		$(this).parents('.js-tab-panel').removeClass('open');
1343		$(this).parents('.js-tab-panel').find('.js-tab-panel__item').removeClass('open');
1344		unlockBody();
1345		$('body').removeClass('lock');
1346		if (!$('body').attr('class')) {
1347			$('body').removeAttr('class');
1348		}
1349	}
1350
1351});
1352$(document).on('click', '.js-tab-panel__close', function () {
1353	$('.js-tab-panel').removeClass('open');
1354	$('.js-tab-panel__nav').removeClass('active');
1355	$('.js-tab-panel__item').removeClass('open');
1356	unlockBody();
1357	$('body').removeClass('lock');
1358	if (!$('body').attr('class')) {
1359		$('body').removeAttr('class');
1360	}
1361});
1362$(document).on('click', '.js-tab-panel__body', function (e) {
1363	if (!$(e.target).closest('.js-tab-panel__item').length && !$(e.target).closest('.js-tab-panel__nav').length) {
1364		$('.js-tab-panel').removeClass('open');
1365		$('.js-tab-panel__nav').removeClass('active');
1366		$('.js-tab-panel__item').removeClass('open');
1367		unlockBody();
1368		$('body').removeClass('lock');
1369		if (!$('body').attr('class')) {
1370			$('body').removeAttr('class');
1371		}
1372	}
1373});
1374// Нижняя панель навигации end --------------------------
1375
1376// spoiler start ===============================================
1377$(document).on('click', '.js-spoiler-title', function () {
1378	let parents = $(this).parents('.js-spoiler');
1379	if (!parents.hasClass('js-spoiler-double')) {
1380		if (!$(this).parents('.js-spoiler-item').hasClass('active')) {
1381			$(this).parents('.js-spoiler').find('.js-spoiler-item').removeClass('active');
1382			$(this).parents('.js-spoiler').find('.js-spoiler-body').removeClass('active');
1383			$(this).parents('.js-spoiler-item').addClass('active');
1384			$(this).parents('.js-spoiler-item').find('.js-spoiler-body');
1385		} else {
1386			$(this).parents('.js-spoiler').find('.js-spoiler-item').removeClass('active');
1387			$(this).parents('.js-spoiler').find('.js-spoiler-body');
1388		}
1389	} else {
1390		if (!$(this).parents('.js-spoiler-item').hasClass('active')) {
1391			$(this).parents('.js-spoiler-item').addClass('active');
1392			$(this).parents('.js-spoiler-item').find('.js-spoiler-body');
1393		} else {
1394			$(this).parents('.js-spoiler-item').removeClass('active');
1395			$(this).parents('.js-spoiler-item').find('.js-spoiler-body');
1396		}
1397	}
1398});
1399// spoiler end ===============================================
1400
1401// smooth hover spoilers start ===============================================
1402const dfSpoilerMotionDuration = 380;
1403
1404function dfSpoilerPrefersReducedMotion() {
1405	return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
1406}
1407
1408function dfCancelSpoilerMotion(body) {
1409	if (body.dfSpoilerMotionFrame) {
1410		window.cancelAnimationFrame(body.dfSpoilerMotionFrame);
1411		body.dfSpoilerMotionFrame = null;
1412	}
1413	if (body.dfSpoilerMotionCancel) {
1414		body.dfSpoilerMotionCancel();
1415		body.dfSpoilerMotionCancel = null;
1416	}
1417}
1418
1419function dfAfterSpoilerMotion(body, callback) {
1420	let finished = false;
1421	const finish = function () {
1422		if (finished) return;
1423		finished = true;
1424		body.removeEventListener('transitionend', onTransitionEnd);
1425		window.clearTimeout(timer);
1426		body.dfSpoilerMotionCancel = null;
1427		callback();
1428	};
1429	const onTransitionEnd = function (event) {
1430		if (event.target === body && event.propertyName === 'height') {
1431			finish();
1432		}
1433	};
1434	const timer = window.setTimeout(finish, dfSpoilerMotionDuration + 100);
1435	body.addEventListener('transitionend', onTransitionEnd);
1436	body.dfSpoilerMotionCancel = function () {
1437		if (finished) return;
1438		finished = true;
1439		body.removeEventListener('transitionend', onTransitionEnd);
1440		window.clearTimeout(timer);
1441	};
1442}
1443
1444function dfPrepareSpoilerBody(body) {
1445	let initialized = false;
1446	if (!body.classList.contains('js-spoiler-motion')) {
1447		const inner = document.createElement('div');
1448		inner.className = 'spoiler-motion__inner';
1449		while (body.firstChild) {
1450			inner.appendChild(body.firstChild);
1451		}
1452		body.appendChild(inner);
1453		body.classList.add('js-spoiler-motion');
1454		initialized = true;
1455	}
1456
1457	if (initialized) {
1458		const item = body.closest('.js-spoiler-inner-item, .js-spoiler-hover__item');
1459		body.style.height = item && item.classList.contains('active') ? 'auto' : '0px';
1460	}
1461	return body.firstElementChild;
1462}
1463
1464function dfOpenSpoilerItem(item, bodySelector, titleSelector) {
1465	const body = item.querySelector(bodySelector);
1466	if (!body) return;
1467	const inner = dfPrepareSpoilerBody(body);
1468	dfCancelSpoilerMotion(body);
1469
1470	if (dfSpoilerPrefersReducedMotion()) {
1471		item.classList.add('active');
1472		body.classList.remove('is-opening', 'is-closing');
1473		body.style.height = 'auto';
1474		const title = item.querySelector(titleSelector);
1475		if (title) title.setAttribute('aria-expanded', 'true');
1476		return;
1477	}
1478
1479	body.style.height = body.getBoundingClientRect().height + 'px';
1480	body.classList.remove('is-closing');
1481	body.classList.add('is-opening');
1482	void body.offsetHeight;
1483	body.dfSpoilerMotionFrame = window.requestAnimationFrame(function () {
1484		body.dfSpoilerMotionFrame = null;
1485		item.classList.add('active');
1486		const title = item.querySelector(titleSelector);
1487		if (title) title.setAttribute('aria-expanded', 'true');
1488		body.style.height = inner.getBoundingClientRect().height + 'px';
1489		dfAfterSpoilerMotion(body, function () {
1490			body.classList.remove('is-opening');
1491			body.style.height = 'auto';
1492		});
1493	});
1494}
1495
1496function dfCloseSpoilerItem(item, bodySelector, titleSelector) {
1497	const body = item.querySelector(bodySelector);
1498	if (!body) return;
1499	dfPrepareSpoilerBody(body);
1500	dfCancelSpoilerMotion(body);
1501
1502	if (dfSpoilerPrefersReducedMotion()) {
1503		item.classList.remove('active');
1504		body.classList.remove('is-opening', 'is-closing');
1505		body.style.height = '0px';
1506		const title = item.querySelector(titleSelector);
1507		if (title) title.setAttribute('aria-expanded', 'false');
1508		return;
1509	}
1510
1511	body.style.height = body.getBoundingClientRect().height + 'px';
1512	body.classList.remove('is-opening');
1513	body.classList.add('is-closing');
1514	void body.offsetHeight;
1515	body.dfSpoilerMotionFrame = window.requestAnimationFrame(function () {
1516		body.dfSpoilerMotionFrame = null;
1517		item.classList.remove('active');
1518		const title = item.querySelector(titleSelector);
1519		if (title) title.setAttribute('aria-expanded', 'false');
1520		body.style.height = '0px';
1521		dfAfterSpoilerMotion(body, function () {
1522			body.classList.remove('is-closing');
1523		});
1524	});
1525}
1526
1527function dfPrepareHoverSpoilers(root) {
1528	$(root).find('.js-spoiler-inner-body, .js-spoiler-hover__body').each(function () {
1529		dfPrepareSpoilerBody(this);
1530		const item = this.closest('.js-spoiler-inner-item, .js-spoiler-hover__item');
1531		const title = item && item.querySelector('.js-spoiler-inner-title, .js-spoiler-hover__title');
1532		if (title) title.setAttribute('aria-expanded', item.classList.contains('active') ? 'true' : 'false');
1533	});
1534}
1535
1536$(document).on('mouseenter', '.js-spoiler-inner-title, .js-spoiler-hover__title', function () {
1537	const isInner = this.classList.contains('js-spoiler-inner-title');
1538	const groupSelector = isInner ? '.js-spoiler-inner' : '.js-spoiler-hover';
1539	const itemSelector = isInner ? '.js-spoiler-inner-item' : '.js-spoiler-hover__item';
1540	const bodySelector = isInner ? '.js-spoiler-inner-body' : '.js-spoiler-hover__body';
1541	const titleSelector = isInner ? '.js-spoiler-inner-title' : '.js-spoiler-hover__title';
1542	const doubleClass = isInner ? 'js-spoiler-inner-double' : 'js-spoiler-hover__double';
1543	const group = this.closest(groupSelector);
1544	const item = this.closest(itemSelector);
1545	if (!group || !item) return;
1546
1547	dfPrepareHoverSpoilers(group);
1548	if (group.classList.contains(doubleClass)) {
1549		if (item.classList.contains('active')) {
1550			dfCloseSpoilerItem(item, bodySelector, titleSelector);
1551		} else {
1552			dfOpenSpoilerItem(item, bodySelector, titleSelector);
1553		}
1554		return;
1555	}
1556
1557	if (item.classList.contains('active')) return;
1558	group.querySelectorAll(itemSelector + '.active').forEach(function (activeItem) {
1559		dfCloseSpoilerItem(activeItem, bodySelector, titleSelector);
1560	});
1561	dfOpenSpoilerItem(item, bodySelector, titleSelector);
1562});
1563
1564$(document).ready(function () {
1565	dfPrepareHoverSpoilers(document);
1566});
1567// smooth hover spoilers end ===============================================
1568
1569$(document).on('click', '.js-blog-detail-card__btn', function () {
1570	if (!$(this).parents('.js-blog-detail-card').hasClass('open')) {
1571		$(this).parents('.js-blog-detail-card').addClass('open');
1572		$(this).parents('.js-blog-detail-card').find('.js-blog-detail-card__body').slideDown(300);
1573	} else {
1574		$(this).parents('.js-blog-detail-card').removeClass('open');
1575		$(this).parents('.js-blog-detail-card').find('.js-blog-detail-card__body').slideUp(300);
1576	}
1577});
1578
1579$(document).on('click', '.js-scroll-top', function () {
1580	$('html, body').animate({
1581		scrollTop: 0
1582	}, 700);
1583	history.replaceState(null, null, window.location.pathname + window.location.search);
1584});
1585
1586$(document).on('mouseenter', '.js-item-info', function () {
1587	if ($(window).width() > 991) {
1588		let windowWidth = $(window).width();
1589		let label = $(this).find('.js-item-info__body');
1590		let labelRight = label.offset().left + label.outerWidth();
1591		$(this).addClass('open');
1592		if (labelRight < windowWidth) {
1593			$(this).addClass('label-right')
1594		} else {
1595			$(this).addClass('label-left')
1596		}
1597	}
1598});
1599$(document).on('mouseleave', '.js-item-info', function () {
1600	if ($(window).width() > 991) {
1601		let item = $(this);
1602		item.removeClass('open');
1603		setTimeout(() => {
1604			item.removeClass('label-right label-left');
1605		}, 300);
1606	}
1607
1608});
1609$(document).on('click', '.js-item-info', function (e) {
1610	if ($(window).width() < 992) {
1611		if (!e.target.closest('.js-item-info__close')) {
1612			let windowWidth = $(window).width();
1613			let label = $(this).find('.js-item-info__body');
1614			let labelRight = label.offset().left + label.outerWidth();
1615			$(this).parents('.js-info-items').find('.js-item-info').removeClass('open');
1616			$(this).addClass('open');
1617			$(this).parents('.js-info-items').addClass('active');
1618			if (labelRight < windowWidth) {
1619				$(this).addClass('label-right')
1620			} else {
1621				$(this).addClass('label-left')
1622			}
1623		}
1624
1625	}
1626});
1627$(document).on('click', '.js-item-info__close', function () {
1628	let item = $(this).parents('.js-item-info');
1629	item.removeClass('open');
1630	item.parents('.js-info-items').removeClass('active');
1631	setTimeout(() => {
1632		item.removeClass('label-right label-left');
1633	}, 300);
1634});
1635
1636
1637// quiz форма
1638// выозв окна с quiz
1639function loadingQuiz() {
1640	if ($('.js-quiz-block').length) {
1641		let thisStep = $('.js-quiz-block').data('step');
1642		let itemLength = $('.js-quiz-block').find('.js-quiz-block__item').length;
1643		$('.js-quiz-block').find('.js-quiz-block__item').removeClass('active');
1644		$('.js-quiz-block').find('.js-quiz-block__item').eq(thisStep - 1).addClass('active');
1645		$('.js-quiz-block').find('.js-quiz-block__desc').removeClass('active');
1646		$('.js-quiz-block').find('.js-quiz-block__desc').eq(thisStep - 1).addClass('active');
1647		$('.js-quiz-block .js-quiz-block__label').each(function (index, value) {
1648			if (index <= thisStep - 1) {
1649				$(value).addClass('active');
1650			}
1651		});
1652		$('.js-quiz-block__step-number').each(function (index, value) {
1653			if (index <= thisStep - 1) {
1654				$(value).addClass('active');
1655			}
1656		});
1657
1658		if (thisStep > 1) {
1659			$('.js-quiz-block').find('.js-quiz-block__prev').addClass('active');
1660		}
1661		if (thisStep == itemLength) {
1662			$('.js-quiz-block').addClass('quiz-end');
1663		}
1664
1665	}
1666}
1667function quizFormReset() {
1668	if ($('.js-quiz-block').length) {
1669		$('.js-quiz-block').removeClass('quiz-end');
1670		$('.js-quiz-block').find('.js-quiz-block__label').removeClass('active');
1671		$('.js-quiz-block').find('.js-quiz-block__item').removeClass('active');
1672		$('.js-quiz-block').find('.js-quiz-block__desc').removeClass('active');
1673		$('.js-quiz-block').find('.js-quiz-block__label').eq(0).addClass('active');
1674		$('.js-quiz-block').find('.js-quiz-block__item').eq(0).addClass('active');
1675		$('.js-quiz-block').find('.js-quiz-block__desc').eq(0).addClass('active');
1676	}
1677}
1678function quizFormClose() {
1679	if ($('.js-quiz-block').length) {
1680		$('.js-quiz-block').removeClass('open');
1681		$('body').removeClass('lock').css('padding-right', '0px');
1682		if (!$('body').attr('class')) {
1683			$('body').removeAttr('class');
1684		}
1685	}
1686}
1687$(document).on('click', '.js-popup-quiz', function (e) {
1688	if (!$(e.target).closest('.js-popup-quiz__btn').length && !$(e.target).closest('.js-popup-quiz__body').length) {
1689		unlockBody();
1690		$(this).removeClass('open');
1691		$('body').removeClass('lock').css('padding-right', '0px');
1692		if (!$('body').attr('class')) {
1693			$('body').removeAttr('class');
1694		}
1695	}
1696});
1697$(document).on('click', '.js-popup-quiz__btn', function (e) {
1698	e.preventDefault();
1699	let href = $(this).attr('href').slice(1);
1700	let popup = $(document).find('#' + href);
1701	if (popup.length) {
1702		lockBody();
1703		$('body').addClass('lock').css('padding-right', calcScroll() + 'px');
1704		popup.addClass('open');
1705	}
1706});
1707$(document).on('click', '.js-popup-quiz__close', function () {
1708	unlockBody();
1709	$(this).parents('.js-popup-quiz').removeClass('open');
1710	$('body').removeClass('lock').css('padding-right', '0px');
1711	if (!$('body').attr('class')) {
1712		$('body').removeAttr('class');
1713	}
1714});
1715// выозв окна с quiz end
1716function quizBlockHeight() {
1717	if ($('.js-quiz-block').length) {
1718		let items = $('.js-quiz-block').find('.js-quiz-block__item');
1719		let heightBlock = 0;
1720		$(items).each(function (index, value) {
1721			if ($(value).outerHeight() > heightBlock) {
1722				heightBlock = $(value).outerHeight();
1723			}
1724		});
1725		$('.js-quiz-block').find('.js-quiz-block__items').css('min-height', heightBlock + 'px')
1726	}
1727}
1728$(document).on('click', '.js-quiz-block__next', function () {
1729	let itemLength = $(this).parents('.js-quiz-block').find('.js-quiz-block__item').length;
1730	let step = $(this).parents('.js-quiz-block').find('.js-quiz-block__item.active').data('step');
1731	if (step < itemLength) {
1732		$(this).parents('.js-quiz-block').find('.js-quiz-block__item').removeClass('active');
1733		$(this).parents('.js-quiz-block').find('.js-quiz-block__item').eq(step).addClass('active');
1734		$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').removeClass('active');
1735		$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').eq(step).addClass('active');
1736	}
1737	$(this).parents('.js-quiz-block').find('.js-quiz-block__label').eq(step).addClass('active');
1738	$(this).parents('.js-quiz-block').find('.js-quiz-block__prev').addClass('active');
1739	$(this).parents('.js-quiz-block').data('step', step + 1);
1740	new session().set("quiz_step_count", Number(step + 1));
1741	$('.js-quiz-block__step-number').each(function (index, value) {
1742		if (index <= step) {
1743			$(value).addClass('active');
1744		} else {
1745			$(value).removeClass('active');
1746		}
1747	});
1748	if (step == itemLength - 1) {
1749		$(this).parents('.js-quiz-block').addClass('quiz-end');
1750	}
1751});
1752$(document).on('click', '.js-quiz-block__prev', function () {
1753	let itemLength = $(this).parents('.js-quiz-block').find('.js-quiz-block__item').length;
1754	let step = $(this).parents('.js-quiz-block').find('.js-quiz-block__item.active').data('step');
1755	$(this).parents('.js-quiz-block').find('.js-quiz-block__item').removeClass('active');
1756	$(this).parents('.js-quiz-block').find('.js-quiz-block__item').eq(step - 2).addClass('active');
1757	$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').removeClass('active');
1758	$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').eq(step - 2).addClass('active');
1759	$(this).parents('.js-quiz-block').find('.js-quiz-block__label').eq(step - 1).removeClass('active');
1760	$(this).parents('.js-quiz-block').data('step', step - 1);
1761	new session().set("quiz_step_count", Number(step - 1))
1762	$('.js-quiz-block__step-number').each(function (index, value) {
1763		if (index <= step - 2) {
1764			$(value).addClass('active');
1765		} else {
1766			$(value).removeClass('active');
1767		}
1768	});
1769	if (step - 1 == 1) {
1770		$(this).parents('.js-quiz-block').find('.js-quiz-block__prev').removeClass('active');
1771	}
1772});
1773$(document).on('click', '.js-quiz-block__label', function () {
1774	let labelIndex = $(this).index() + 1;
1775	let step = $(this).parents('.js-quiz-block').data('step');
1776	if (labelIndex == 1) {
1777		$(this).parents('.js-quiz-block').find('.js-quiz-block__prev').removeClass('active');
1778	} else {
1779		$(this).parents('.js-quiz-block').find('.js-quiz-block__prev').addClass('active');
1780	}
1781	if (step < labelIndex) {
1782		$(this).parents('.js-quiz-block').find('.js-quiz-block__label').each(function (index, value) {
1783			if (index <= step) {
1784				$(value).addClass('active');
1785			} else {
1786				$(value).removeClass('active');
1787			}
1788		});
1789		$('.js-quiz-block__step-number').each(function (index, value) {
1790			if (index <= step) {
1791				$(value).addClass('active');
1792			} else {
1793				$(value).removeClass('active');
1794			}
1795		});
1796		$(this).parents('.js-quiz-block').find('.js-quiz-block__item').removeClass('active');
1797		$(this).parents('.js-quiz-block').find('.js-quiz-block__item').eq(step).addClass('active');
1798		$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').removeClass('active');
1799		$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').eq(step).addClass('active');
1800		$(this).parents('.js-quiz-block').data('step', step + 1);
1801		new session().set("quiz_step_count", Number(step + 1))
1802	} else {
1803		$(this).parents('.js-quiz-block').find('.js-quiz-block__label').each(function (index, value) {
1804			if (index <= labelIndex - 1) {
1805				$(value).addClass('active');
1806			} else {
1807				$(value).removeClass('active');
1808			}
1809		});
1810		$('.js-quiz-block__step-number').each(function (index, value) {
1811			if (index <= labelIndex - 1) {
1812				$(value).addClass('active');
1813			} else {
1814				$(value).removeClass('active');
1815			}
1816		});
1817		$(this).parents('.js-quiz-block').find('.js-quiz-block__item').removeClass('active');
1818		$(this).parents('.js-quiz-block').find('.js-quiz-block__item').eq(labelIndex - 1).addClass('active');
1819		$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').removeClass('active');
1820		$(this).parents('.js-quiz-block').find('.js-quiz-block__desc').eq(labelIndex - 1).addClass('active');
1821		$(this).parents('.js-quiz-block').data('step', labelIndex);
1822		new session().set("quiz_step_count", Number(labelIndex))
1823	}
1824
1825
1826
1827
1828});
1829$(document).ready(function () {
1830	quizBlockHeight();
1831	loadingQuiz();
1832})
1833// quiz форма end
1834
1835
1836// Команда проекта
1837$(document).on('click', '.js-project-team__btn', function () {
1838	if (!$(this).parents('.js-project-team').hasClass('active')) {
1839		$(this).parents('.js-project-team').addClass('active');
1840	} else {
1841		$(this).parents('.js-project-team').removeClass('active');
1842	}
1843});
1844$(document).on('click', '.js-project-team__item', function () {
1845	let index = $(this).index();
1846	$(this).parents('.js-project-team').find('.js-project-team__item').removeClass('active');
1847	$(this).addClass('active');
1848	$(this).parents('.js-project-team').find('.js-project-team__desc').removeClass('active');
1849	$(this).parents('.js-project-team').find('.js-project-team__desc').eq(index).addClass('active');
1850});
1851$(document).on('mouseenter', '.js-project-team__item', function () {
1852	let index = $(this).index();
1853	$(this).parents('.js-project-team').find('.js-project-team__item').removeClass('active');
1854	$(this).addClass('active');
1855	$(this).parents('.js-project-team').find('.js-project-team__desc').removeClass('active');
1856	$(this).parents('.js-project-team').find('.js-project-team__desc').eq(index).addClass('active');
1857});
1858// Команда проекта end
1859
1860//  Меню в детальной блога
1861function menuNavHeight() {
1862	if ($('.js-menu-nav.js-menu-nav-height').length) {
1863		$('.js-menu-nav.js-menu-nav-height').each(function (index, value) {
1864			let itemsHeight = 0;
1865			let heightParent = $(window).height() / 2;
1866			let links = $(value).find('.js-menu-nav__item');
1867			$(links).each(function (i, item) {
1868				itemsHeight += $(item).outerHeight();
1869				if (itemsHeight > heightParent) {
1870					let heightContent = itemsHeight - $(item).outerHeight();
1871					$(value).find('.js-menu-nav__items').css('max-height', heightContent + 'px');
1872					return false;
1873				}
1874			});
1875		});
1876	}
1877}
1878function menuNavScroll(item) {
1879	if ($('.js-menu-nav.js-menu-nav-scroll').length) {
1880		$('.js-menu-nav.js-menu-nav-scroll').each(function (index, value) {
1881			let linkActive = $(value).find('.js-menu-nav__item.link-active');
1882			let linkActiveIndex = 0;
1883			let items = $(value).find('.js-menu-nav__item');
1884			let scroll = 0;
1885			$(items).each(function (i, v) {
1886				if ($(v).hasClass('link-active')) {
1887					linkActiveIndex = i;
1888					return false
1889				}
1890			});
1891			if (linkActive.length && allowScrolling) {
1892				let heightParent = $(value).find('.js-menu-nav__content').outerHeight();
1893				let scrollBlock = $(value).find('.js-menu-nav__items');
1894				let scrollBlockY = scrollBlock.scrollTop();
1895				let linkActivePosition = linkActive.position();
1896				let linkActiveY = linkActivePosition.top + linkActive.outerHeight();
1897				let scrollTop = (linkActiveY - heightParent);
1898				let scrollableContentHeight = scrollBlock[0].scrollHeight;
1899				if ($(window).scrollTop() > linkActive.outerHeight()) {
1900					// Если скролим вниз
1901					if (item > 0) {
1902						scroll += $(items).eq(linkActiveIndex + 1).outerHeight() + $(items).eq(linkActiveIndex + 2).outerHeight();
1903						if (linkActiveY > heightParent + scrollBlockY - scroll) {
1904							if (scrollableContentHeight - linkActivePosition.top < heightParent) {
1905								scroll = scrollableContentHeight;
1906								$(scrollBlock).animate({
1907									scrollTop: scrollTop + scroll
1908								}, 300);
1909							} else {
1910								$(scrollBlock).animate({
1911									scrollTop: scrollTop + scroll
1912								}, 300);
1913							}
1914						} else if (linkActivePosition.top < scrollBlockY + scroll) {
1915							if (scrollableContentHeight - linkActivePosition.top < heightParent) {
1916								scroll = scrollableContentHeight;
1917								$(scrollBlock).animate({
1918									scrollTop: scrollTop + scroll
1919								}, 300);
1920							} else {
1921								$(scrollBlock).animate({
1922									scrollTop: scrollTop + scroll
1923								}, 300);
1924							}
1925						}
1926					} else {
1927						scroll += $(items).eq(linkActiveIndex - 1).outerHeight() + $(items).eq(linkActiveIndex - 2).outerHeight();
1928						if (linkActiveY + scroll < heightParent) {
1929							$(scrollBlock).animate({
1930								scrollTop: 0
1931							}, 300);
1932						} else {
1933							$(scrollBlock).animate({
1934								scrollTop: linkActivePosition.top - scroll
1935							}, 300)
1936
1937						}
1938					}
1939				}
1940			}
1941		});
1942	}
1943}
1944let resizeTimeout;
1945$(window).on('resize', function () {
1946	clearTimeout(resizeTimeout);
1947	// Устанавливаем новый таймер, чтобы выполнить функцию только после завершения resize
1948	resizeTimeout = setTimeout(function () {
1949		menuNavHeight();
1950	}, 200); // Задержка 200 мс, чтобы подождать окончания изменения размера
1951});
1952$(document).ready(function () {
1953	menuNavHeight();
1954})
1955var scrollTopLast = 0;
1956var isScrolling = false;
1957$(window).on('scroll', function () {
1958	if (isScrolling) return;
1959	isScrolling = true;
1960	setTimeout(() => {
1961		let currentScrollTop = $(this).scrollTop();
1962		if (currentScrollTop > scrollTopLast) {
1963			menuNavScroll(currentScrollTop);
1964		} else {
1965			menuNavScroll(0);
1966
1967		}
1968		scrollTopLast = currentScrollTop; // Обновляем последнее значение прокрутки
1969		isScrolling = false;  // Через 300ms сбрасываем флаг.
1970	}, 200);
1971
1972});
1973//  Меню в детальной блога end
1974
1975
1976
1977
1978
1979$(document).on('click', '.js-hotels-filter__btn', function () {
1980	if (!$(this).parents('.js-hotels-filter').hasClass('open')) {
1981		$(this).parents('.js-hotels-filter').addClass('open');
1982	} else {
1983		$(this).parents('.js-hotels-filter').removeClass('open');
1984	}
1985});
1986$(document).on('click', '.js-hotels-filter__btn-search', function () {
1987	let item = $(this);
1988	if (!$(this).hasClass('open')) {
1989		$(this).addClass('open');
1990		$(this).parents('.js-hotels-filter').find('.js-hotels-filter__search').slideDown(300);
1991		$(this).parents('.js-hotels-filter').find('.js-hotels-filter__body').addClass('open');
1992		if ($(window).width() > 991) {
1993			setTimeout(() => {
1994				$(item).parents('.js-hotels-filter').find('.js-hotels-filter__search input').focus();
1995			}, 300);
1996		}
1997
1998	} else {
1999		$(this).removeClass('open');
2000		$(this).parents('.js-hotels-filter').find('.js-hotels-filter__search').slideUp(300);
2001		$(this).parents('.js-hotels-filter').find('.js-hotels-filter__body').removeClass('open');
2002		$(this).parents('.js-hotels-filter').find('.js-hotel-selection').removeClass('open');
2003	}
2004});
2005
2006
2007function positionFormClick(item) {
2008	let heightBlock = item.outerHeight();
2009	let parent = item.parents('.js-item-product__body');
2010	let position = (parent.offset().top + parent.outerHeight()) - $(window).scrollTop();
2011	if (heightBlock + position + 50 > $(window).height()) {
2012		position = (parent.offset().top - parent.outerHeight()) - $(window).scrollTop();
2013		if (position < heightBlock) {
2014			$(item).removeClass('bottom top').addClass('center');
2015		} else {
2016			$(item).removeClass('top center').addClass('bottom');
2017		}
2018	} else if (heightBlock + position + 50 < $(window).height()) {
2019		$(item).removeClass('bottom').addClass('top');
2020	} else {
2021		$(item).removeClass('bottom top').addClass('center');
2022	}
2023}
2024// $(window).on('scroll', function () {
2025// 	if ($('.js-book-one-click.open').length) {
2026// 		positionFormClick($('.js-book-one-click.open'))
2027// 	}
2028// });
2029$(document).on('click', '.js-item-product__btn', function () {
2030	if ($(this).parents('.js-item-product').find('.js-item-product__form').length) {
2031		let item = $(this);
2032		if (!$(this).hasClass('open')) {
2033			$('.js-item-product__btn').removeClass('open');
2034			$('.js-item-product__body').removeClass('open');
2035			$('.js-book-one-click').removeClass('open').remove();
2036			$('body').addClass('form-focus lock');
2037			item.addClass('open');
2038			let formContent = item.parents('.js-item-product').find('.js-item-product__form').html();
2039			item.parents('.js-item-product').find('.js-item-product__body').append(formContent).addClass('open');
2040			let interval = setInterval(function () {
2041				if (item.parents('.js-item-product').find('.js-book-one-click').length) {
2042					positionFormClick(item.parents('.js-item-product').find('.js-book-one-click'));
2043					if ($(window).width() > 991) {
2044						setTimeout(() => {
2045							item.parents('.js-item-product').find('.js-book-one-click .js-input input').focus();
2046							item.parents('.js-item-product').find('.js-book-one-click .js-input').addClass('focus');
2047						}, 50);
2048					}
2049					item.parents('.js-item-product').find('.js-book-one-click .js-input input').inputmask({
2050						mask: "+7(999) 999-99-99",
2051						inputmode: "numeric",
2052					});
2053					item.parents('.js-item-product').find('.js-book-one-click').addClass('open');
2054					clearInterval(interval);
2055					// startCountdown(item.parents('.js-item-product').find('.js-counter-block'));
2056				}
2057			}, 100);
2058
2059		} else {
2060			item.removeClass('open');
2061			item.parents('.js-item-product').find('.js-book-one-click').removeClass('open').remove();
2062			$('body').removeClass('form-focus');
2063			if (!$('body').attr('class')) {
2064				$('body').removeAttr('class');
2065			}
2066		}
2067		$('body').removeClass('show-bottom-nav');
2068		if (!$('body').attr('class')) {
2069			$('body').removeAttr('class');
2070		}
2071	}
2072});
2073// Код для счетчика в формах ====================================
2074function startCountdown($el) {
2075	let totalSeconds = parseInt($el.data('time'), 10);
2076
2077	function getWordForm(n, forms) {
2078		n = Math.abs(n) % 100;
2079		const n1 = n % 10;
2080		if (n > 10 && n < 20) return forms[2];
2081		if (n1 > 1 && n1 < 5) return forms[1];
2082		if (n1 == 1) return forms[0];
2083		return forms[2];
2084	}
2085
2086	function updateTimer() {
2087		const minutes = Math.floor(totalSeconds / 60);
2088		const seconds = totalSeconds % 60;
2089
2090		const minuteWord = getWordForm(minutes, ['минута', 'минуты', 'минут']);
2091		const secondWord = getWordForm(seconds, ['секунда', 'секунды', 'секунд']);
2092
2093		let text = '';
2094		if (minutes > 0) {
2095			text += `${minutes}\u00A0${minuteWord}`;
2096		}
2097		if (seconds > 0) {
2098			if (text.length >
2098 0) text += ' ';
2099			text += `${seconds}\u00A0${secondWord}`;
2100		}
2101
2102		if (totalSeconds <= 0) {
2103			clearInterval($el.data('interval'));
2104			Fancybox.close();
2105			$('.js-book-one-click__close').trigger('click');
2106			return;
2107		}
2108
2109		$el.text(text);
2110		totalSeconds--;
2111	}
2112
2113	updateTimer();
2114	const interval = setInterval(updateTimer, 1000);
2115	$el.data('interval', interval); // сохраняем ID в DOM
2116}
2117$(document).on('click', '.js-counter-block-clear', function () {
2118	const $timerEl = $(this).parents('.js-book-one-click').find('.js-counter-block');
2119	const interval = $timerEl.data('interval');
2120	if (interval) {
2121		clearInterval(interval);
2122	}
2123});
2124// $(document).ready(function () {
2125// 	$('.js-counter-block').each(function () {
2126// 		startCountdown($(this));
2127// 	});
2128// })
2129// Код для счетчика в формах end ====================================
2130// Перенос цены в карточке товара в моб и пк версии
2131let hasRunSmall = false; // Флаг для выполнения функции при ширине < 768
2132let hasRunLarge = false; // Флаг для выполнения функции при ширине > 768
2133// Функция для выполнения при ширине < 768 (мобильная версия)
2134function priceMobProduct() {
2135	$(".js-item-product").each(function () {
2136		let pricesHtml = $(this).find('.js-item-product__price').html();
2137		$(this).find('.js-item-product__mob-price').html(pricesHtml);
2138	});
2139}
2140// Функция для выполнения при ширине > 768 (десктопная версия)
2141function pricePcProduct() {
2142	$(".js-item-product").each(function () {
2143		let pricesHtml = $(this).find('.js-item-product__mob-price').html();
2144		// Проверяем, есть ли контент в блоке для мобильной версии
2145		if (pricesHtml) {
2146			$(this).find('.js-item-product__price').html(pricesHtml);
2147		}
2148	});
2149}
2150// Проверка ширины экрана при загрузке и ресайзе 
2151function checkScreenWidth() {
2152	let screenWidth = $(window).width();
2153	// Если экран меньше 768px (мобильная версия)
2154	if (screenWidth < 768 && !hasRunSmall) {
2155		priceMobProduct();
2156		hasRunSmall = true; // Функция выполнена, больше не выполняем
2157		hasRunLarge = false; // Сбрасываем флаг для десктопа
2158	}
2159	// Если экран больше или равен 768px (десктопная версия)
2160	if (screenWidth >= 768 && !hasRunLarge) {
2161		pricePcProduct();
2162		hasRunLarge = true; // Функция выполнена, больше не выполняем
2163		hasRunSmall = false; // Сбрасываем флаг для мобильной версии
2164	}
2165}
2166// Проверка при ресайзе окна
2167$(window).resize(function () {
2168	checkScreenWidth();
2169});
2170$(document).ready(function () {
2171	// Проверка сразу при загрузке страницы
2172	checkScreenWidth();
2173})
2174// Перенос цены в карточке товара в моб и пк версии end
2175
2176
2177
2178$(document).on('click', '.js-book-one-click__close', function () {
2179	$(this).parents('.js-item-product').find('.js-item-product__btn').removeClass('open');
2180	$(this).parents('.js-item-product').find('.js-item-product__body').removeClass('open');
2181	$(this).parents('.js-book-one-click').removeClass('open').remove();
2182	$('body').removeClass('form-focus lock');
2183	if (!$('body').attr('class')) {
2184		$('body').removeAttr('class');
2185	}
2186});
2187$(document).on('click', '.js-book-one-click', function (e) {
2188	if (!$(e.target).closest('.js-item-product__btn').length && !$(e.target).closest('.js-book-one-click__body').length) {
2189		$('.js-item-product__btn').removeClass('open');
2190		$('.js-item-product__body').removeClass('open');
2191		$('.js-book-one-click').removeClass('open').remove();
2192		$('body').removeClass('form-focus lock');
2193		if (!$('body').attr('class')) {
2194			$('body').removeAttr('class');
2195		}
2196	}
2197});
2198$(document).on('mouseenter', '.js-item-tooltip', function (event) {
2199	if (!window.isHovered) {
2200		return;
2201	}
2202	let $tooltip = $(this).find('.item-tooltip__text');
2203	let parent = $(this).parents('.js-tooltip-parent');
2204	let parentPos = parent.offset();
2205	let tooltipWidth = $tooltip.outerWidth();
2206	let tooltipHeight = $tooltip.outerHeight();
2207	// Получаем координаты курсора относительно окна браузера
2208	let mouseX = event.pageX - window.scrollX;  // Учитаем горизонтальную прокрутку
2209	let mouseY = event.pageY - window.scrollY;  // Учитаем вертикальную прокрутку
2210	let tooltipPosLeft = mouseX - parentPos.left;
2211	if (parent.outerWidth() - tooltipPosLeft < tooltipWidth) {
2212		mouseX = mouseX - tooltipWidth;
2213		if (tooltipPosLeft < tooltipWidth) {
2214			mouseX = ((parent.outerWidth() / 2) - (tooltipWidth / 2)) + parentPos.left;
2215		}
2216		// if (mouseX < 30) {
2217		// 	mouseX = (parent.outerWidth() / 2) - (tooltipWidth / 2);
2218		// }
2219	}
2220	// Обновляем позицию подсказки относительно окна браузера
2221	$tooltip.css({
2222		'top': mouseY + 0 + 'px',  // Позиционируем по оси Y относительно окна
2223		'left': mouseX + 'px'       // Позиционируем по оси X относительно окна
2224	});
2225	// Показываем подсказку
2226	$tooltip.css({
2227		'visibility': 'visible',
2228		'opacity': '1'
2229	});
2230});
2231$(document).on('mouseleave', '.js-item-tooltip', function () {
2232	if (!window.isHovered) {
2233		return;
2234	}
2235	let $tooltip = $(this).find('.item-tooltip__text');
2236	// Скрываем подсказку
2237	$tooltip.css({
2238		'visibility': 'hidden',
2239		'opacity': '0'
2240	});
2241});
2242
2243$(document).on('click', '.js-item-tooltip', function (event) {
2244	if (window.isHovered || $(event.target).closest('.item-tooltip__text').length) {
2245		return
2246	}
2247	$(this).addClass('open');
2248	let $tooltip = $(this).find('.item-tooltip__text');
2249	let parent = $(this).parents('.js-tooltip-parent');
2250	let parentPos = parent.offset();
2251	let tooltipWidth = $tooltip.outerWidth();
2252	let tooltipHeight = $tooltip.outerHeight();
2253	// Получаем координаты курсора относительно окна браузера
2254	let mouseX = event.pageX - window.scrollX;  // Учитаем горизонтальную прокрутку
2255	let mouseY = event.pageY - window.scrollY;  // Учитаем вертикальную прокрутку
2256	let tooltipPosLeft = mouseX - parentPos.left;
2257	let tooltipPosRight = tooltipPosLeft + tooltipWidth;
2258	let tooltipPosTop = mouseY;
2259	let tooltipPosBottom = mouseY + tooltipHeight;
2260	let windowWidth = $(this).parents('.js-tooltip-parent').outerWidth();
2261	let windowHeight = $(this).parents('.js-tooltip-parent').outerHeight();
2262	let transformSlider = 0
2263	if ($(this).parents('.swiper-container').length) {
2264		var transformValue = $(this).parents('.swiper-container');
2265		transformSlider = Math.abs(transformValue[0].swiper.getTranslate());
2266		mouseX = (mouseX + transformSlider) - (mouseX - tooltipPosLeft);
2267		mouseY = mouseY + (window.scrollY - parentPos.top);
2268	}
2269	if (windowWidth - tooltipPosLeft < tooltipWidth) {
2270		mouseX = mouseX - tooltipWidth
2271		if ($(this).parents('.swiper-container').length) {
2272			mouseX = mouseX - transformSlider
2273		}
2274		if (mouseX < 30) {
2275			mouseX = ((windowWidth / 2) - (tooltipWidth / 2)) + 20
2276			if ($(this).parents('.swiper-container').length) {
2277				mouseX = ((windowWidth / 2) - (tooltipWidth / 2)) + transformSlider
2278			}
2279		}
2280	}
2281
2282	// Обновляем позицию подсказки относительно окна браузера
2283	$tooltip.css({
2284		'top': mouseY + 10 + 'px',  // Позиционируем по оси Y относительно окна
2285		'left': mouseX + 'px'  // Позиционируем по оси X относительно окна
2286	});
2287	// Показываем подсказку
2288	$tooltip.css({
2289		'visibility': 'visible',
2290		'opacity': '1'
2291	});
2292});
2293
2294
2295
2296
2297$(document).on('mouseenter', '.js-item-tooltip-img', function (event) {
2298	if (!window.isHovered) {
2299		return;
2300	}
2301	let $tooltip = $(this).find('.item-tooltip-img__content');
2302	let parent = $(this).parents('.js-tooltip-parent');
2303	let parentWidth = parent.outerWidth();
2304	let parentPos = parent.offset();
2305	let tooltipWidth = $tooltip.outerWidth();
2306	let tooltipHeight = $tooltip.outerHeight();
2307	// Получаем координаты курсора относительно окна браузера
2308	let mouseX = event.pageX - window.scrollX;  // Учитаем горизонтальную прокрутку
2309	let mouseY = event.pageY - window.scrollY;  // Учитаем вертикальную прокрутку
2310	let tooltipPosLeft = mouseX - parentPos.left;
2311	if (parentWidth < tooltipWidth) {
2312		$tooltip.css({
2313			'max-width': parentWidth
2314		});
2315	}
2316	if (parent.outerWidth() - tooltipPosLeft < tooltipWidth) {
2317		mouseX = mouseX - tooltipWidth;
2318		if (tooltipPosLeft < tooltipWidth) {
2319			mouseX = ((parent.outerWidth() / 2) - (tooltipWidth / 2)) + parentPos.left;
2320		}
2321		// if (mouseX < 30) {
2322		// 	mouseX = ((parent.outerWidth() / 2) - (tooltipWidth / 2)) + parentPos.left;
2323		// 	if (mouseX < 20) {
2324		// 		mouseX = parentPos.left;
2325		// 	}
2326		// }
2327	}
2328	// Обновляем позицию подсказки относительно окна браузера
2329	$tooltip.css({
2330		'top': mouseY + 10 + 'px',  // Позиционируем по оси Y относительно окна
2331		'left': mouseX + 'px'       // Позиционируем по оси X относительно окна
2332	});
2333	// Показываем подсказку
2334	$tooltip.css({
2335		'visibility': 'visible',
2336		'opacity': '1',
2337		'pointer-events': 'auto'
2338	});
2339});
2340
2341$(document).on('mouseleave', '.js-item-tooltip-img', function () {
2342	if (!window.isHovered) {
2343		return;
2344	}
2345	let $tooltip = $(this).find('.item-tooltip-img__content');
2346	// Скрываем подсказку
2347	$tooltip.css({
2348		'visibility': 'hidden',
2349		'opacity': '0',
2350		'pointer-events': 'none',
2351		'max-width': ''
2352	});
2353});
2354$(document).on('click', '.js-item-tooltip-img', function (e) {
2355	if (window.isHovered || $(e.target).closest('.item-tooltip-img__content').length) {
2356		return
2357	}
2358	let $tooltip = $(this).find('.item-tooltip-img__content');
2359	let parent = $(this).parents('.js-tooltip-parent');
2360	let parentWidth = parent.outerWidth();
2361	let parentPos = parent.offset();
2362	let tooltipWidth = $tooltip.outerWidth();
2363	let tooltipHeight = $tooltip.outerHeight();
2364	// Получаем координаты курсора относительно окна браузера
2365	let mouseX = event.pageX - window.scrollX;  // Учитаем горизонтальную прокрутку
2366	let mouseY = event.pageY - window.scrollY;  // Учитаем вертикальную прокрутку
2367	let tooltipPosLeft = mouseX - parentPos.left;
2368	let tooltipPosRight = tooltipPosLeft + tooltipWidth;
2369	let tooltipPosTop = mouseY;
2370	let tooltipPosBottom = mouseY + tooltipHeight;
2371	let windowWidth = $(this).parents('.js-tooltip-parent').outerWidth();
2372	let windowHeight = $(this).parents('.js-tooltip-parent').outerHeight();
2373	if (parentWidth < tooltipWidth) {
2374		$tooltip.css({
2375			'max-width': parentWidth
2376		});
2377	}
2378	if (windowWidth - tooltipPosLeft < tooltipWidth) {
2379		mouseX = mouseX - tooltipWidth
2380		if (mouseX < 30) {
2381			mouseX = ((windowWidth / 2) - (tooltipWidth / 2)) + parentPos.left
2382			if (mouseX < 20) {
2383				mouseX = parentPos.left
2384			}
2385		}
2386	}
2387	// Обновляем позицию подсказки относительно окна браузера
2388	$tooltip.css({
2389		'top': mouseY + 10 + 'px',  // Позиционируем по оси Y относительно окна
2390		'left': mouseX + 'px'  // Позиционируем по оси X относительно окна
2391	});
2392	// Показываем подсказку
2393	$tooltip.css({
2394		'visibility': 'visible',
2395		'opacity': '1',
2396		'pointer-events': 'auto'
2397	});
2398});
2399
2400
2401$(document).on('click', function (e) {
2402	if (!$(e.target).closest('.js-item-tooltip').length) {
2403		$('.item-tooltip__text').css({
2404			'visibility': 'hidden',
2405			'opacity': '0',
2406		});
2407	}
2408	if ($(window).width() > 991) {
2409		if (!$(e.target).closest('.js-item-tooltip-img').length) {
2410			$('.item-tooltip-img__content').css({
2411				'visibility': 'hidden',
2412				'opacity': '0',
2413				'pointer-events': 'none',
2414				'max-width': ''
2415			});
2416		}
2417	}
2418
2419});
2420
2421// Обработчик прокрутки для скрытия подсказки
2422$(window).on('scroll', function () {
2423	$('.item-tooltip__text').css({
2424		'visibility': 'hidden',
2425		'opacity': '0'
2426	});
2427	if ($(window).width() > 991) {
2428		$('.item-tooltip-img__content').not('.item-product__plan .item-tooltip-img__content').css({
2429			'visibility': 'hidden',
2430			'opacity': '0',
2431			'pointer-events': 'none',
2432			'max-width': ''
2433		});
2434	}
2435
2436
2437});
2438$(document).on('click', '.js-item-tooltip-img__close', function () {
2439	$(this).parents('.item-tooltip-img__content').css({
2440		'visibility': 'hidden',
2441		'opacity': '0',
2442		'pointer-events': 'none',
2443		'max-width': ''
2444	});
2445});
2446
2447
2448$(document).on('click', '.js-accordion__btn', function () {
2449	if (!$(this).parents('.js-accordion').hasClass('open')) {
2450		$(this).parents('.js-accordion').addClass('open');
2451		$(this).parents('.js-accordion').find('.js-accordion__content').slideDown(300);
2452	} else {
2453		$(this).parents('.js-accordion').removeClass('open');
2454		$(this).parents('.js-accordion').find('.js-accordion__content').slideUp(300);
2455	}
2456});
2457
2458// Клик по ссылкам-якорям в мобильном меню с акциями ==========================
2459$(document).on('click', '.js-link-sale-anchor', function () {
2460	let anchor = '#' + $(this).attr('href').split('#')[1];
2461	let el = $(document).find(`${anchor}`);
2462	$('.js-tab-panel').removeClass('open');
2463	$('.js-tab-panel__nav').removeClass('active');
2464	$('.js-tab-panel__item').removeClass('open');
2465	if (el.length) {
2466		$('html, body').animate({
2467			scrollTop: el.offset().top
2468		}, 300);
2469		setTimeout(() => {
2470			el.find('.js-main-spoiler__title').trigger('click');
2471			$('body').removeClass('lock show-bottom-nav show-elements');
2472			if (!$('body').attr('class')) {
2473				$('body').removeAttr('class');
2474			}
2475		}, 400);
2476		history.pushState(null, null, anchor);
2477	}
2478});
2479// Клик по ссылкам-якорям в мобильном меню с акциями end ==========================
2480
2481
2482// spoiler start ===============================================
2483$(document).on('click', '.js-spoiler__title', function () {
2484	let parents = $(this).parents('.js-spoiler');
2485	let element = $(this);
2486	let anchor = '#' + $(this).parents('.js-spoiler__item').attr('id');
2487	parents.find('.js-spoiler__body').stop(true, true);
2488	if (!parents.hasClass('js-spoiler__double')) {
2489		if (!$(this).parents('.js-spoiler__item').hasClass('active')) {
2490			element.parents('.js-block-questions').find('.js-block-questions__link').removeClass('link-active');
2491			element.parents('.js-spoiler').find('.js-spoiler__item.active .js-spoiler__body').slide
2491Up(300);
2492			element.parents('.js-spoiler').find('.js-spoiler__item.active').removeClass('active');
2493			element.parents('.js-spoiler__item').addClass('active');
2494			element.parents('.js-spoiler__item').find('.js-spoiler__body').slideDown(300).addClass('active');
2495			element.parents('.js-block-questions').find('.js-block-questions__link').eq(element.parents('.js-block-questions__item').index()).addClass('link-active');
2496			setTimeout(() => {
2497				// Выполняем скролл к якорю 
2498				scrollTopQuestions(element.parents('.js-block-questions__item'))
2499			}, 300);
2500		} else {
2501			$(this).parents('.js-spoiler').find('.js-spoiler__item').removeClass('active');
2502			$(this).parents('.js-spoiler').find('.js-spoiler__body').slideUp(300);
2503			element.parents('.js-block-questions').find('.js-block-questions__link').removeClass('link-active');
2504		}
2505	} else {
2506		if (!$(this).parents('.js-spoiler__item').hasClass('active')) {
2507			$(this).parents('.js-spoiler__item').addClass('active');
2508			$(this).parents('.js-spoiler__item').find('.js-spoiler__body').slideDown(300).addClass('active');
2509		} else {
2510			$(this).parents('.js-spoiler__item').removeClass('active');
2511			$(this).parents('.js-spoiler__item').find('.js-spoiler__body').slideUp(300);
2512		}
2513	}
2514	setTimeout(() => {
2515		elementsNavTable();
2516		updateArrowPositions();
2517	}, 300);
2518	history.pushState(null, null, anchor);
2519});
2520
2521
2522// spoiler start ===============================================
2523$(document).on('click', '.js-main-spoiler__title', function () {
2524	let parents = $(this).parents('.js-main-spoiler');
2525	let element = $(this);
2526	parents.find('.js-main-spoiler__body').stop(true, true);
2527	if (!parents.hasClass('js-main-spoiler__double')) {
2528		if (!$(this).parents('.js-main-spoiler__item').hasClass('active')) {
2529			element.parents('.js-main-spoiler').find('.js-main-spoiler__item.active .js-main-spoiler__body').removeClass('active').slideUp(300);
2530			element.parents('.js-main-spoiler').find('.js-main-spoiler__item.active').removeClass('active');
2531			element.parents('.js-main-spoiler__item').addClass('active');
2532			element.parents('.js-main-spoiler__item').find('.js-main-spoiler__body').slideDown(300);
2533		} else {
2534			$(this).parents('.js-main-spoiler').find('.js-main-spoiler__item').removeClass('active');
2535			$(this).parents('.js-main-spoiler').find('.js-main-spoiler__body').slideUp(300);
2536		}
2537	} else {
2538		if (!$(this).parents('.js-spoiler__item').hasClass('active')) {
2539			$(this).parents('.js-spoiler__item').addClass('active');
2540			$(this).parents('.js-spoiler__item').find('.js-spoiler__body').slideDown(300);
2541		} else {
2542			$(this).parents('.js-spoiler__item').removeClass('active');
2543			$(this).parents('.js-spoiler__item').find('.js-spoiler__body').slideUp(300);
2544		}
2545	}
2546});
2547
2548//  Адаптивные таблицы + навигация для них ===================================
2549
2550function createMobTables(event) {
2551	$('.js-table').each(function (index, item) {
2552		let table = $(this).find('table');
2553		let tableBtn = $(this).closest('.main-table__body').find('.js-table__btn');
2554		let tableBtnHTML;
2555		if (tableBtn.length) {
2556			tableBtnHTML = tableBtn.length ? tableBtn[0].outerHTML : '';
2557		}
2558		let titles = [];
2559		let rowSpan = 1;
2560		let colspanTdHtml = ''
2561		let colspanTdStartIndex = 0;
2562		let endTitleItems = [];
2563		let navHtml = '';
2564		let navTopHtml = '';
2565		let count = 0;
2566		let tableSlider = $(`
2567			<div class="table-slider">
2568				<div class="table-slider__select js-table__select"></div>
2569				<div class="table-slider__slider swiper-container">
2570					<div class="table-slider__wrapper swiper-wrapper"></div>
2571				</div>
2572				${tableBtnHTML ? tableBtnHTML : ''} 
2573				<div class="table-slider__nav">
2574					<div class="table-slider__prev">
2575						<svg>
2576							<use xlink:href="${SITE_TEMPLATE_PATH}/img/sprite.svg#slider-prev"></use>
2577						</svg>
2578					</div>
2579					<div class="table-slider__next">
2580						<svg>
2581							<use xlink:href="${SITE_TEMPLATE_PATH}/img/sprite.svg#slider-next"></use>
2582						</svg>
2583					</div>
2584				</div>
2585			</div>
2586			`);
2587		$(table.find('tr')).each(function (trIndex, trEl) {
2588			let tr = $(this);
2589			let hasColspan = false;
2590			if (trIndex === 0 || rowSpan >= (trIndex + 1)) {
2591				$(tr.find('td, th')).each(function (tdIndex, tdEl) {
2592					let td = $(this);
2593					if (td.attr('colspan')) {
2594						hasColspan = true;
2595						colspanTdHtml = td.html();
2596						colspanTdStartIndex = tdIndex;
2597					} else {
2598						if (hasColspan) {
2599							endTitleItems.push(td.html())
2600						} else {
2601							titles.push(td.html());
2602						}
2603						if (td.attr('rowspan')) {
2604							rowSpan = td.attr('rowspan');
2605						}
2606
2607
2608					}
2609				})
2610			} else {
2611				if (count === 0) {
2612					navTopHtml = $(`
2613						<div class="table-slider__top">
2614							<div class="table-slider__top-left">
2615								<div class="table-slider__top-title js-table__select-title">
2616									${tr.find('td, th').eq(0).html()}
2617								</div>
2618								<div class="table-slider__top-number">
2619									<span class="js-table__select-count">${(parseInt(trIndex) - parseInt(rowSpan) + 1)}</span>
2620									из
2621									${(table.find('tr').length - parseInt(rowSpan))}
2622								</div>
2623							</div>
2624							<div class="table-slider__icon js-table__select-btn">
2625								<svg>
2626									<use xlink:href="${SITE_TEMPLATE_PATH}/img/sprite.svg#menu-dots"></use>
2627								</svg>
2628								<svg>  
2629									<use xlink:href="${SITE_TEMPLATE_PATH}/img/sprite.svg#close"></use>
2630								</svg>
2631							</div>
2632						</div>
2633						<div class="table-slider__top-items js-table__select-body">
2634							<div class="table-slider__top-items-body"></div>
2635						</div>
2636					`);
2637					count = 1
2638				}
2639				let tableSlide = $(`
2640					<div class="table-slider__slide js-tooltip-parent swiper-slide">
2641						<div class="table-slider__body"></div>
2642					</div>
2643					`);
2644				titles = titles.concat(endTitleItems);
2645				$(tr.find('td, th')).each(function (tdIndex, tdEl) {
2646					let td = $(this);
2647					if (tdIndex !== 0) {
2648						// if (tdIndex === colspanTdStartIndex) {
2649						// 	tableSlide.find('.table-slider__body').append('<div class="table-slider__item-yellow">' + colspanTdHtml + '</div>');
2650						// }
2651						let tableSlideItem = $(`
2652							<div class="table-slider__item">
2653								<div class="table-slider__item-title"> 
2654									${titles[tdIndex]}
2655								</div>
2656								<div class="table-slider__item-text">
2657									${td.html()}
2658								</div>
2659							</div>
2660							`);
2661						tableSlide.find('.table-slider__body').append(tableSlideItem);
2662					}
2663				})
2664				tableSlider.find('.table-slider__wrapper').append(tableSlide);
2665				navHtml += '<div class="table-slider__top-item js-table__select-item' + (navHtml === '' ? ' active' : '') + '" data-count="' + (parseInt(trIndex) - parseInt(rowSpan) + 1) + '. ' + '">' + tr.find('td, th').eq(0).html() + '</div>';
2666			}
2667
2668		});
2669
2670		tableSlider.find('.table-slider__select').append(navTopHtml);
2671		tableSlider.find('.table-slider__top-items-body').append(navHtml);
2672		if ($(window).width() + calcScroll() < 992) {
2673			table.next('.table-slider').remove();
2674			table.hide().after(tableSlider);
2675			tableMobSlider();
2676
2677		} else {
2678			table.show().next('.table-slider').remove();
2679		}
2680	})
2681}
2682
2683function tableMobSlider() {
2684	let prev, next;
2685	$('.table-slider__slider.swiper-container').each(function (el) {
2686		prev = $(this).parents('.table-slider').find('.table-slider__prev')[0];
2687		next = $(this).parents('.table-slider').find('.table-slider__next')[0];
2688		new Swiper(this, {
2689			slidesPerView: 1,
2690			spaceBetween: 20,
2691			loop: false,
2692			observer: true,
2693			observeParents: true,
2694			watchOverflow: true,
2695			touchReleaseOnEdges: true,
2696			navigation: {
2697				nextEl: next,
2698				prevEl: prev,
2699			},
2700		}).on('slideChange', function (swiper) {
2701			$('body').removeClass('show-bottom-nav');
2702			if (!$('body').attr('class')) {
2703				$('body').removeAttr('class');
2704			}
2705			let parent = $(swiper['el']).find('.table-slider__slide').parents('.js-table__content');
2706			parent.find('.js-table__select').removeClass('open');
2707			parent.find('.js-table__select-body').slideUp(300);
2708			parent.find('.js-table__select-item').removeClass('active');
2709			parent.find('.js-table__select-item').eq(swiper['activeIndex']).addClass('active');
2710			parent.find('.js-table__select-title').html(parent.find('.js-table__select-item').eq(swiper['activeIndex']).html());
2711			parent.find('.js-table__select-count').html(swiper['activeIndex'] + 1);
2712		});
2713	})
2714}
2715$(document).ready(function () {
2716	createMobTables();
2717})
2718let tableMob = false; // Флаг для выполнения при ширине меньше 992
2719let tablePc = false; // Флаг для выполнения при ширине больше 992
2720$(window).resize(function () {
2721	let windowWidth = $(window).width() + calcScroll();
2722	// Если ширина окна меньше 992 и функция ещё не была выполнена для этого случая
2723	if (windowWidth < 992 && !tableMob) {
2724		// Ваш код для ширины меньше 992
2725		createMobTables(true);
2726		tableMob = true; // Отмечаем, что функция выполнена
2727		tablePc = false; // Сбрасываем флаг для ширины больше 992
2728	}
2729	// Если ширина окна больше 992 и функция ещё не была выполнена для этого случая
2730	else if (windowWidth > 991 && !tablePc) {
2731		// Ваш код для ширины больше 991
2732		createMobTables(false);
2733		tablePc = true; // Отмечаем, что функция выполнена
2734		tableMob = false; // Сбрасываем флаг для ширины меньше 992
2735	}
2736});
2737$(document).on('click', '.js-table__select-btn', function () {
2738	if (!$(this).parents('.js-table__select').hasClass('open')) {
2739		$(this).parents('.js-table__select').addClass('open')
2740		$(this).parents('.js-table__select').find('.js-table__select-body').slideDown(300)
2741	} else {
2742		$(this).parents('.js-table__select').removeClass('open')
2743		$(this).parents('.js-table__select').find('.js-table__select-body').slide
2743Up(300)
2744	}
2745});
2746$(document).on('click', function (e) {
2747	if (!$(e.target).closest('.js-table__select-btn').length && !$(e.target).closest('.js-table__select-body').length) {
2748		$('.js-table__select').removeClass('open');
2749		$('.js-table__select-body').slideUp(300);
2750	}
2751});
2752$(document).on('click', '.js-table__select-item', function (e) {
2753	e.preventDefault();
2754	let el = $(this);
2755	$(this).parents('.js-table__select').removeClass('open');
2756	$(this).parents('.js-table__select').find('.js-table__select-body').slideUp(300);
2757	$(this).parents('.js-table__select').find('.js-table__select-title').html($(this).html());
2758	$(this).parents('.js-table__select').find('.js-table__select-count').html($(this).index() + 1);
2759	const swiper = el.parents('.js-table__content').find('.table-slider__slider')[0].swiper;
2760	swiper.slideTo(el.index());
2761});
2762function checkScrollButtons(block) {
2763	const scrollLeft = Math.round(block.scrollLeft());
2764	const scrollWidth = Math.round(block[0].scrollWidth);
2765	const width = Math.round(block.width());
2766	if (scrollLeft <= 0) {
2767		block.parents('.js-table').find('.js-table__prev').addClass('disabled');
2768	} else {
2769		block.parents('.js-table').find('.js-table__prev').removeClass('disabled');
2770	}
2771	if (scrollLeft >= scrollWidth - width) {
2772		block.parents('.js-table').find('.js-table__next').addClass('disabled');
2773	} else {
2774		block.parents('.js-table').find('.js-table__next').removeClass('disabled');
2775	}
2776}
2777
2778function elementsNavTable() {
2779	if ($('.js-table table').length) {
2780		$('.js-table table').each(function (index, value) {
2781			let parent = $(value).parents('.js-table__content');
2782			// Проверяем, доступен ли горизонтальный скролл
2783			let isHorizontalScroll = parent[0].scrollWidth > parent[0].clientWidth;
2784			if (isHorizontalScroll) {
2785				parent.parents('.js-table').addClass('show-nav')
2786			} else {
2787				parent.parents('.js-table').removeClass('show-nav')
2788			}
2789			checkScrollButtons(parent);
2790		});
2791	}
2792}
2793$(document).ready(function () {
2794	if ($('.js-table table').length) {
2795		$('.js-table table').each(function (index, value) {
2796			let parent = $(value).parents('.js-table__content');
2797			let scrollTimeout;
2798			$(parent).on('scroll', function () {
2799				if (parent.scrollLeft() <= 0) {
2800					parent.parents('.js-table').removeClass('fixed-column');
2801				} else {
2802					parent.parents('.js-table').addClass('fixed-column');
2803				}
2804				clearTimeout(scrollTimeout);
2805				// Устанавливаем новый таймер, чтобы выполнить функцию только после завершения resize
2806				scrollTimeout = setTimeout(function () {
2807					checkScrollButtons(parent);
2808				}, 500); // Задержка 200 мс, чтобы подождать окончания изменения размера
2809			});
2810		});
2811	}
2812})
2813$(document).on('mousemove', '.js-table', function (e) {
2814	var blockOffset = $(this).offset();
2815	var blockWidth = $(this).width();
2816	var mouseX = e.pageX - blockOffset.left; // Получаем координаты курсора относительно блока
2817	if (mouseX < blockWidth / 2) {
2818		// Наведено на левую половину
2819		$(this).addClass('hovered-left').removeClass('hovered-right');
2820	} else {
2821		// Наведено на правую половину
2822		$(this).addClass('hovered-right').removeClass('hovered-left');
2823	}
2824});
2825
2826$(document).on('mouseleave', '.js-table', function () {
2827	$(this).removeClass('hovered-left hovered-right');
2828});
2829
2830var isAnimating = false; // Флаг для отслеживания анимации
2831// При клике на кнопку "Прокрутить влево"
2832$(document).on('click', '.js-table__prev', function () {
2833	if (isAnimating) return; // Если анимация уже идет, прекращаем выполнение
2834	isAnimating = true; // Устанавливаем флаг анимации
2835	let block = $(this).parents('.js-table').find('.js-table__content');
2836	let scrollStep = 100;
2837	block.animate({
2838		scrollLeft: block.scrollLeft() - scrollStep
2839	}, 300, function () {
2840		isAnimating = false; // Сбрасываем флаг анимации после завершения анимации
2841		checkScrollButtons(block);  // После анимации обновляем состояние кнопок
2842	}); // Плавная прокрутка влево
2843});
2844// При клике на кнопку "Прокрутить вправо"
2845$(document).on('click', '.js-table__next', function () {
2846	if (isAnimating) return; // Если анимация уже идет, прекращаем выполнение
2847	isAnimating = true; // Устанавливаем флаг анимации
2848	let block = $(this).parents('.js-table').find('.js-table__content');
2849	let scrollStep = 100;
2850	// Проверка, если скролл достигнут до Ð
2850ºÐ¾Ð½Ñ†Ð°
2851	if (block[0].scrollWidth - block.width() < scrollStep) {
2852		scrollStep = block[0].scrollWidth; // Устанавливаем прокрутку на максимально возможное значение
2853	}
2854	block.animate({
2855		scrollLeft: block.scrollLeft() + scrollStep
2856	}, 300, function () {
2857		isAnimating = false; // Сбрасываем флаг анимации после завершения анимации
2858		checkScrollButtons(block);  // После анимации обновляем состояние кнопок
2859	}); // Плавная прокрутка вправо
2860});
2861
2862
2863// Функция для создания фиксированой шапки таблицы
2864function createHeadTable() {
2865	if ($('.js-table').length) {
2866		$('.js-table table:not(.head-fixed-table)').each(function (index, value) {
2867			let head = $(value).find('thead');
2868			let headParent = $(value).parents('.js-table').find('.js-table__head');
2869			if (head.length) {
2870				let headContent = $(value).find('thead')[0].outerHTML;
2871				let bodyContent = $(value).find('tbody tr')[0].outerHTML;
2872				headParent.html(`
2873					<table class="head-fixed-table">
2874						${headContent}			
2875						
2876					</table>
2877					`)
2878			}
2879		});
2880	}
2881}
2882
2883// Функция для фиксирования шапки таблицы
2884function tableHeadFixed() {
2885
2886	// Получаем высоту видимой части контейнера с таблицей
2887	let containerHeight = $(window).height();
2887  // Высота окна (видимая часть)
2888	// Получаем текущую прокрутку
2889	let scrollTop = $(window).scrollTop();
2890	$('.js-table table').each(function (index, value) {
2891
2892
2893		// Получаем высоту таблицы
2894		let tableHeight = $(value).outerHeight();
2895		// Получаем шапку
2896		let tableHead = $(value).find('thead');
2897
2898
2899		// Получаем высоту шапки 
2900		let tableHeadHeight = $(value).find('thead').outerHeight();
2901		// Получаем верхнюю позицию таблицы относительно страницы
2902		let tableOffsetTop = $(value).offset().top
2903		if (scrollTop > (tableOffsetTop) && scrollTop < (tableOffsetTop + (tableHeight - (tableHeadHeight * 2))) && + tableHeight > containerHeight && tableHead.length) {
2904			$(value).parents('.js-table').addClass('table-head-fixed');
2905			tableHead.css('transform', 'translateY(' + (scrollTop - tableOffsetTop) + 'px)')
2906		} else {
2907			$(value).parents('.js-table').removeClass('table-head-fixed')
2908			tableHead.css('transform', '')
2909		}
2910	});
2911}
2912
2913
2914
2915$(document).ready(function () {
2916	createHeadTable();
2917	tableHeadFixed()
2918})
2919// Функция для обновления позиции стрелок и их содержимого
2920function updateArrowPositions() {
2921	// Получаем высоту видимой части контейнера с таблицей
2922	let containerHeight = $(window).height();
2922  // Высота окна (видимая часть)
2923	// Получаем текущую прокрутку
2924	let scrollTop = $(window).scrollTop();
2925	$('.js-table').each(function (index, value) {
2926		let $scrollableBlock = $(value);
2927		var $svgArrows = $scrollableBlock.find('.js-table__prev svg, .js-table__next svg'); // Получаем все SVG внутри стрелок
2928		// Получаем высоту таблицы
2929		let tableHeight = $scrollableBlock.outerHeight();  // Высота таблицы
2930		// Получаем верхнюю позицию таблицы относительно страницы
2931		let tableOffsetTop = $scrollableBlock.offset().top
2932		if ((scrollTop + containerHeight) - 64 > tableOffsetTop && scrollTop < (tableHeight + tableOffsetTop) - 64 && tableOffsetTop !== 0) {
2933			// Вычисляем центр видимой части контейнера
2934			let centerY = (containerHeight - (tableOffsetTop - scrollTop)) / 2;
2935			if (scrollTop > tableOffsetTop && tableHeight > containerHeight) {
2936				centerY = (scrollTop - tableOffsetTop) + (containerHeight / 2)
2937			}
2938			if (scrollTop > tableOffsetTop && tableHeight < containerHeight) {
2939				centerY = ((tableOffsetTop + tableHeight) - scrollTop) / 2 + (scrollTop - tableOffsetTop);
2940			}
2941			if ((scrollTop + containerHeight) > (tableOffsetTop + tableHeight) && tableHeight > containerHeight) {
2942				centerY = ((tableOffsetTop + tableHeight) - scrollTop) / 2 + (scrollTop - tableOffsetTop);
2943			}
2944			if ((scrollTop + containerHeight) > (tableOffsetTop + tableHeight) && scrollTop < tableOffsetTop) {
2945				centerY = tableHeight / 2
2946			}
2947			// Центрируем все SVG внутри стрелок по вертикали в видимой части таблицы
2948			$svgArrows.css({
2949				top: centerY - ($svgArrows.outerHeight() / 2) + 'px'  // Центрируем SVG по вертикали
2950			});
2951		}
2952	});
2953}
2954
2955
2956
2957// При прокрутке страницы обновляем позицию стрелок
2958$(window).on('scroll', function () {
2959
2960	if ($(window).width() + calcScroll() > 991) {
2961		updateArrowPositions();
2962		tableHeadFixed();
2963	}
2964});
2965let resizeTimeoutNavTable;
2966// При resize страницы обновляем позицию стрелок
2967$(window).on('resize', function () {
2968	// Очищаем предыдущий таймер, если он существует
2969	clearTimeout(resizeTimeoutNavTable);
2970	// Устанавливаем новый таймер
2971	resizeTimeoutNavTable = setTimeout(function () {
2972		// Если ширина окна больше 991 пикселя, вызываем функцию elementsNavTable
2973		if ($(window).width() + calcScroll() > 991) {
2974			elementsNavTable();
2975		}
2976	}, 500); // Задержка 300 мс после завершения ресайза
2977
2978});
2979$(document).ready(function () {
2980	if ($(window).width() + calcScroll() > 991) {
2981		// Инициализация положения стрелок при загрузке страницы
2982		updateArrowPositions();
2983		elementsNavTable();
2984	}
2985})
2986
2987//  Адаптивные таблицы + навигация для них end ===================================
2988
2989function selectVillaPlanMeal(item) {
2990	$('.js-item-villa__item-meal').removeClass('active');
2991	$(item).closest('.js-item-villa__item-meal').addClass('active');
2992	$(item).closest('.js-main-hotel-villa').addClass('open');
2993	if ($(window).width() + calcScroll() < 992) {
2994		$('body').addClass('lock').removeClass('show-elements show-bottom-nav');
2995	}
2996}
2997$(document).on('click', '.js-item-villa__item-meal-btn', function () {
2998	selectVillaPlanMeal($(this))
2999});
3000$(document).on('click', '.js-main-hotel-villa__close', function () {
3001	$('body').removeClass('lock');
3002	$('.js-main-hotel-villa').removeClass('open');
3003	if (!$('body').attr('class')) {
3004		$('body').removeAttr('class');
3005	}
3006});
3007$(document).on('click', '.js-main-hotel-villa__body', function (e) {
3008	if (!$(e.target).closest('.js-main-hotel-villa__box').length) {
3009		$('.js-main-hotel-villa').removeClass('open');
3010
3011		if ($(window).width() + calcScroll() < 992) {
3012			$('body').removeClass('lock');
3013			if (!$('body').attr('class')) {
3014				$('body').removeAttr('class');
3015			}
3016		}
3017	}
3018});
3019
3020
3021// Скрипт для фиксации формы поиска отелей и вилл ==============================================
3022function initHotelStickyForm() {
3023	const $parent = $('.js-parent-filter-block');
3024	const $form = $parent.find('.js-hotel-content-form');
3025	const $body = $form.find('.js-hotel-content-form__body');
3026	const $sidebar = $('.js-parent-filter-block__sidebar');
3027
3028	if (!$parent.length || !$form.length) return;
3029
3030	const hasVillaBody = $sidebar.length > 0;
3031
3032	let blockTop = $parent.offset().top;
3033	let blockHeight = $form.outerHeight();
3034	let offset = blockHeight;
3035
3036	function isParentVisible() {
3037		const scrollTop = $(window).scrollTop();
3038		const windowHeight = $(window).height();
3039		const parentTop = $parent.offset().top;
3040		const parentBottom = parentTop + $parent.outerHeight();
3041
3042		return parentBottom > scrollTop && parentTop < scrollTop + windowHeight;
3043	}
3044
3045	function resetOpen() {
3046		$form.removeClass('open');
3047
3048		if (hasVillaBody) {
3049			$sidebar.css('top', '20px');
3050		}
3051	}
3052
3053	function onScrollOrResize() {
3054		const scrollTop = $(window).scrollTop();
3055
3056		blockTop = $parent.offset().top;
3057		blockHeight = $form.outerHeight();
3058		offset = blockHeight;
3059
3060		/* ---------- ACTIVE ---------- */
3061		if (scrollTop >= blockTop + blockHeight) {
3062			if (!$form.hasClass('active')) {
3063				$form
3064					.css('height', blockHeight)
3065					.addClass('active');
3066			}
3067		} else {
3068			$form.removeClass('active open').css('height', '');
3069
3070			if (hasVillaBody) {
3071				$sidebar.css('top', '20px');
3072			}
3073
3074			return;
3075		}
3076
3077		/* ---------- OPEN ---------- */
3078		if (
3079			scrollTop >= blockTop + blockHeight + offset &&
3080			isParentVisible()
3081		) {
3082			$form.addClass('open');
3083
3084			if (hasVillaBody) {
3085				const bodyHeight = $body.outerHeight() + 20;
3086				$sidebar.css('top', bodyHeight + 'px');
3087			}
3088		} else {
3089			resetOpen();
3090		}
3091	}
3092
3093	$(window).on('scroll resize', onScrollOrResize);
3094}
3095
3096$(document).ready(function () {
3097	initHotelStickyForm();
3098});
3099
3100// Скрипт для фиксации формы поиска отелей и вилл end ==========================================
3101
3102
3103
3104
3105
3106// Скрипт для страницы "Справочник иконок" ==========================================
3107$(document).on('click', '.js-item-icon-directory__copy-icon', function () {
3108	let iconHTML = $(this).closest('.js-item-icon-directory').find('.js-item-icon-directory__icon').html();
3109	let currentBtnText = $(this).find('span').text();
3110	let btnText = $(this).find('span');
3111	// Используем Clipboard API для копирования
3112	navigator.clipboard.writeText(iconHTML).then(function () {
3113		$(btnText).text('Скопировано в буфер')
3114		setTimeout(() => {
3115			$(btnText).text(currentBtnText)
3116		}, 5000);
3117	}).catch(function (err) {
3118		console.error("Ошибка при копировании иконки: ", err);
3119	});
3120});
3121
3122$(document).on('click', '.js-item-icon-directory__copy-name', function () {
3123	var iconId = $(this).closest('.js-item-icon-directory').find('.js-item-icon-directory__code').text().trim();
3124	let currentBtnText = $(this).find('span').text();
3125	let btnText = $(this).find('span');
3126	// Используем Clipboard API для копирования
3127	navigator.clipboard.writeText(iconId).then(function () {
3128		$(btnText).text('Скопировано в буфер')
3129		setTimeout(() => {
3130			$(btnText).text(currentBtnText)
3131		}, 5000);
3132	}).catch(function (err) {
3133		console.error("Ошибка при копировании ID иконки: ", err);
3134	});
3135});
3136// Скрипт для страницы "Справочник иконок" end ======================================
3137
3138
3139// Скрипт для блока Вопросы клиентов ==========================
3140$(document).on('click', '.js-block-questions__link', function (e) {
3141	isAnchorClicking = false; // Устанавливаем флаг, что скроллинг по якорю
3142	e.preventDefault();
3143	e.stopImmediatePropagation();
3144	let prevIndex = $(this).parents('.js-block-questions').find('.js-block-questions__link.link-active').parent().index();
3145	$(this).parents('.js-block-questions').find('.js-block-questions__link').removeClass('link-active');
3146	$(this).addClass('link-active');
3147	let anchor = '#' + $(this).attr('href').split('#')[1];
3148	let el = $(document).find(`${anchor}`);
3149	if (el.length) {
3150		if (prevIndex > $(this).parent().index()) {
3151			$('html, body').animate({
3152				scrollTop: el.offset().top - 20
3153			}, 300);
3154			setTimeout(() => {
3155				el.find('.js-spoiler__title').trigger('click');
3156
3157			}, 300);
3158		} else {
3159			el.find('.js-spoiler__title').trigger('click');
3160		}
3161		isAnchorClicking = true; // Сбрасываем флаг после завершения анимации
3162	}
3163});
3164function scrollTopQuestions(item) {
3165	if (item.length) {
3166		let top = item.offset().top;
3167		let offset = 20;
3168		isAnchorClicking = false;
3169		$('html, body').animate({
3170			scrollTop: top - offset
3171		}, 300, function () {
3172			// сбрасываем флаг после завершения анимации
3173			setTimeout(function () {
3174				isAnchorClicking = true;
3175			}, 50);
3176		});
3177	}
3178
3179}
3180
3181// Скрипт для блока Вопросы клиентов end ==========================
3182
3183$(document).on('click', '.js-block__btn', function () {
3184	if (!$(this).parents('.js-block').hasClass('open')) {
3185		$(this).parents('.js-block').addClass('open');
3186	} else {
3187		$(this).parents('.js-block').removeClass('open');
3188	}
3189});
3190$(document).on('click', '.js-block__close', function () {
3191	$(this).parents('.js-block').removeClass('open');
3192});
3193$(document).on('click', function (e) {
3194	if (!$(e.target).closest('.js-block__btn').length && !$(e.target).closest('.js-block__body').length) {
3195		$('.js-block').removeClass('open');
3196	}
3197});
3198
3199
3200$(document).on('mousemove', '.js-offers-form', function () {
3201	$(this).removeClass('element-blur');
3202});
3203$(document).on('click', '.js-offers-form__delete', function () {
3204	$(this).parents('.js-offers-form').remove();
3205});
3206
3207
3208
3209
3210$(document).on('mouseenter', '.js-offers-form', function () {
3211	var $parentBlock = $(this); // Родительский блок, на который наведены
3212	var $timerBlock = $parentBlock.find('.js-timer-block'); // Таймер внутри родительского блока
3213	// Запуск таймера только если он ещё не запущен
3214	if (!$timerBlock.data('timerInterval') && $timerBlock.length) {
3215		// Получаем количество минут из data-time (если оно не задано, используем 60 минут)
3216		var minutesLeft = parseInt($timerBlock.data('time')) || 60;
3216 // Если data-time нет, ставим 60 минут
3217		// Начинаем с (minutesLeft - 1) минут и 59 секунд
3218		var initialMinutes = minutesLeft > 0 ? minutesLeft - 1 : 59;
3219		var initialSeconds = initialMinutes * 60 + 59; // (minutesLeft - 1) * 60 + 59 или 59 минут и 59 секунд
3220		// Инициализируем seconds в data-атрибуте, если они еще не установлены
3221		$timerBlock.data('seconds', initialSeconds);
3222		// Создаем новый интервал для обновления таймера
3223		var timerInterval = setInterval(function () {
3224			var secondsLeft = $timerBlock.data('seconds'); // Получаем оставшиеся секунды
3225			// Вычисляем минуты и секунды
3226			var minutes = Math.floor(secondsLeft / 60);
3227			var seconds = secondsLeft % 60;
3228			// Обновляем отображение минут с правильным склонением
3229			var minutesText = minutes; // Без ведущего нуля для минут
3230			var minutesDeclined = declOfNum(minutes, ['минута', 'минуты', 'минут']);
3231			$timerBlock.find('.js-timer-block__minutes').text(minutesText + ' ' + minutesDeclined);
3232			// Обновляем отображение секунд с правильным склонением
3233			var secondsText = seconds < 10 ? '0' + seconds : seconds; // Ведущий ноль для секунд
3234			var secondsDeclined = declOfNum(seconds, ['секунда', 'секунды', 'секунд']);
3235			$timerBlock.find('.js-timer-block__seconds').text(secondsText + ' ' + secondsDeclined);
3236			// Обновляем data-атрибут с оставшимися секундами
3237			$timerBlock.data('seconds', secondsLeft - 1); // Сохраняем обновленное количество секунд
3238			// Останавливаем таймер, когда время закончилось
3239			if (secondsLeft <= 0) {
3240				clearInterval($timerBlock.data('timerInterval')); // Используем интервал из data-атрибутов
3241			}
3242		}, 1000); // обновление каждую секунду
3243		// Сохраняем интервал в data-атрибут, чтобы избежать повторного запуска
3244		$timerBlock.data('timerInterval', timerInterval);
3245	}
3246});
3247
3248
3249// Форма бронирования, выбор количества человек
3250function addElementSelection(item) {
3251	let itemsBlock = item.parents('.js-number-people').find('.js-number-people__items');
3252	let index = parseInt(item.parents('.js-item-people').find('.js-quantity-block__value').val());
3253	let itemHtml = `
3254		<div class="item-people js-item-people">
3255			<div class="item-people__title">
3256				Возраст ${index} ребенка
3257			</div>
3258			<div class="item-people__quantity">
3259				<div class="quantity-block js-quantity-block">
3260					<div
3261						class="quantity-block__btn disabled js-quantity-block__minus">
3262						-
3263					</div>
3264					<input type="text" value="1" readonly data-min="1" data-max="17"
3265						class="js-quantity-block__value" name="KID_AGE[]">
3266					<div class="quantity-block__btn js-quantity-block__plus">
3267						+
3268					</div>
3269				</div>
3270			</div>
3271		</div>
3272	`;
3273	itemsBlock.append(itemHtml)
3274}
3275function removeElementSelection(item) {
3276	let itemsBlock = item.parents('.js-number-people').find('.js-number-people__items');
3277	let index = item.parents('.js-item-people').find('.js-quantity-block__value').val();
3278	itemsBlock.find('.js-item-people').eq(index).remove();
3279}
3280$(document).on('change', '.js-adult-input', function () {
3281	let val = $(this).val();
3282	if (val > 0) {
3283		$(this).parents('.js-number-people').find('.js-number-people__text-adult').text(val + ' ' + declOfNum(val, ['взрослый', 'взрослых', 'взрослых']));
3284	}
3285});
3286$(document).on('change', '.js-children-input', function () {
3287	let val = $(this).val();
3288	let minValue = parseInt($(this).data('min') || 0);
3289	let maxValue = parseInt($(this).data('max'));
3290	if (val > 0) {
3291		$(this).parents('.js-number-people').find('.js-number-people__text-children').text(val + ' ' + declOfNum(val, ['ребенок', 'детей', 'детей']));
3292	} else {
3293		$(this).parents('.js-number-people').find('.js-number-people__text-children').text('');
3294	}
3295	let currentChildrenCount = $(this).parents('.js-number-people').find('.js-number-people__items .js-item-people').length;
3296	// Если количество детей изменилось, добавляем или удаляем нужное количество блоков
3297	// Добавление или удаление элементов
3298	if (val > currentChildrenCount) {
3299		for (var i = currentChildrenCount; i < val; i++) {
3300			addElementSelection($(this)); // Добавляем элементы до нужного количества
3301		}
3302	} else if (val < currentChildrenCount) {
3303		for (var i = currentChildrenCount; i > val; i--) {
3304			removeElementSelection($(this)); // Удаляем лишние элементы
3305		}
3306	}
3307});
3308// quantity start --------------------------
3309$(document).on('click', '.js-quantity-block__plus', function () {
3310	let input = $(this).parents('.js-quantity-block').find('input');
3311	let maxValue = parseInt($(this).parents('.js-quantity-block').find('.js-quantity-block__value').data('max'));
3312	let val = parseInt(input.val());
3313	val = val + 1;
3314	if (maxValue <= val) {
3315		val = maxValue
3316	}
3317	input.val(val).trigger('change');
3318});
3319$(document).on('click', '.js-quantity-block__minus', function () {
3320	let input = $(this).parents('.js-quantity-block').find('input');
3321	let minValue = parseInt($(this).parents('.js-quantity-block').find('.js-quantity-block__value').data('min') || 0);
3322	let val = parseInt(input.val());
3323	val = val - 1;
3324	if (minValue >= val) {
3325		val = minValue
3326	}
3327	input.val(val).trigger('change');
3328});
3329$(document).on('change', '.js-quantity-block__value', function () {
3330	// Получаем значение из поля ввода
3331	let val = parseInt($(this).val());
3332	let maxValue = parseInt($(this).data('max'));
3333	let minValue = parseInt($(this).data('min') || 0);
3334	// Условие для минимального значения
3335	if (val <= minValue) {
3336		$(this).parents('.js-quantity-block').find('.js-quantity-block__minus').addClass('disabled');
3337	} else {
3338		$(this).parents('.js-quantity-block').find('.js-quantity-block__minus').removeClass('disabled');
3339	}
3340	// Условие для максимального значения
3341	if (val >= maxValue) {
3342		$(this).parents('.js-quantity-block').find('.js-quantity-block__plus').addClass('disabled');
3343	} else {
3344		$(this).parents('.js-quantity-block').find('.js-quantity-block__plus').removeClass('disabled');
3345	}
3346});
3347
3348// quantity end --------------------------
3349$(document).ready(function () {
3350	$('.js-adult-input, .js-children-input').trigger('change');
3351})
3352// $(document).on('change', '.js-number-people input', function () {
3353// 	let adults = parseInt($('.js-adult-input').val()) || 0;
3354// 	let children = parseInt($('.js-children-input').val()) || 0; 
3355// 	let val = adults + children;
3356// 	$(this).parents('.js-number-people').find('.js-number-people__all-people').val(val + ' ' + declOfNum(val, ['гость', 'гостя', 'гостей']))
3357// });
3358$(document).on('change', '.js-number-people input', function () {
3359	let $parent = $(this).parents('.js-number-people');
3360
3361	let adults = parseInt($parent.find('.js-adult-input').val()) || 0;
3362	let children = parseInt($parent.find('.js-children-input').val()) || 0;
3363	let val = adults + children;
3364
3365	let $result = $parent.find('.js-number-people__all-people');
3366
3367	let decl = $result.attr('data-text')
3368		? JSON.parse($result.attr('data-text'))
3369		: ['гость', 'гостя', 'гостей'];
3370
3371	$result.val(val + ' ' + declOfNum(val, decl));
3372});
3373
3374// Форма бронирования, выбор количества человек end
3375
3376
3377// Выбор файла в форме отзывов =========================================
3378// Максимальное количество файлов
3379const MAX_FILES = 99;
3380// Максимальный размер файла (5 Мб)
3381const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 Мб в байтах
3382
3383// Массив для хранения всех выбранных файлов
3384let allFiles = [];
3385
3386$(document).on('change', '.js-main-file__input', function (e) {
3387	const newFiles = e.target.files;
3388
3389	// Получаем уже выбранные файлы из инпута
3390	const fileInput = $('.js-main-file__input')[0];
3391
3392	// Массив для хранения файлов, которые прошли проверку
3393	let validFiles = [];
3394
3395	// Массив для хранения имён неподходящих файлов
3396	let invalidFiles = [];
3397
3398	// Разрешённые MIME типы
3399	const allowedTypes = ['image/jpeg', 'image/png', 'video/mp4'];
3400
3401	// Перебираем все выбранные файлы
3402	$.each(newFiles, function (_, file) {
3403		// Проверка типа файла
3404		if (allowedTypes.includes(file.type)) {
3405			// Проверка размера файла
3406			if (file.size > MAX_FILE_SIZE) {
3407				alert(`Файл ${file.name} слишком большой. Максимальный размер: 5 Мб.`);
3408				return; // Пропускаем этот файл
3409			}
3410			validFiles.push(file); // Добавляем файл в массив, если тип разрешён
3411		} else {
3412			// Добавляем имя файла в массив неподходящих
3413			invalidFiles.push(file.name);
3414		}
3415	});
3416
3417	// Если есть неподходящие файлы, показываем их в alert
3418	if (invalidFiles.length > 0) {
3419		alert(`Следующие файлы не поддерживаются: \n${invalidFiles.join('\n')}\nДопустимые форматы: .jpg, .jpeg, .png, .mp4`);
3420	}
3421
3422	// Проверяем количество файлов в текущем инпуте
3423	const currentFileCount = allFiles.length;
3424
3425	// Если общее количество файлов с новыми не превышает MAX_FILES, добавляем их
3426	if (currentFileCount + validFiles.length <= MAX_FILES) {
3427		// Добавляем файлы в основной массив allFiles
3428		allFiles = allFiles.concat(validFiles);
3429
3430		// Обновляем список файлов в input
3431		const dataTransfer = new DataTransfer();
3432		allFiles.forEach(file => dataTransfer.items.add(file));
3433		fileInput.files = dataTransfer.files;
3434
3435		// Перерисовываем список файлов
3436		updateFileList();
3437
3438		// Добавляем класс, если файлов ровно 4
3439		if (allFiles.length === MAX_FILES) {
3440			$('.js-main-file').addClass('max-files');
3441		} else {
3442			$('.js-main-file').removeClass('max-files');
3443		}
3444
3445		// Добавляем класс "active", если файлов от 2 до 3
3446		if (allFiles.length > 0 && allFiles.length <= 3) {
3447			$('.js-main-file').addClass('active');
3448		} else {
3449			$('.js-main-file').removeClass('active');
3450		}
3451	} else {
3452		alert(`Вы можете выбрать не более ${MAX_FILES} файлов.`);
3453	}
3454});
3455
3456// Обработчик удаления файла
3457$(document).on('click', '.js-main-file__delete', function (e) {
3458	e.preventDefault();
3459	const index = $(this).data('index');
3460
3461	// Удаляем файл из массива
3462	allFiles.splice(index, 1);
3463
3464	// Обновляем список файлов в input
3465	const dataTransfer = new DataTransfer();
3466	allFiles.forEach(file => dataTransfer.items.add(file));
3467	$('.js-main-file__input')[0].files = dataTransfer.files;
3468
3469	// Перерисовываем отображение файлов
3470	updateFileList();
3471
3472	// Убираем класс, если файлов меньше 4
3473	if (allFiles.length < MAX_FILES) {
3474		$('.js-main-file').removeClass('max-files');
3475	}
3476
3477	// Добавляем класс "active", если файлов от 2 до 3
3478	if (allFiles.length > 0 && allFiles.length <= 3) {
3479		$('.js-main-file').addClass('active');
3480	} else {
3481		$('.js-main-file').removeClass('active');
3482	}
3483});
3484
3485// Обновление отображения списка файлов
3486function updateFileList() {
3487	const fileList = $('.js-main-file__result');
3488	const files = $('.js-main-file__input')[0].files;
3489	fileList.empty();
3490
3491	$.each(files, function (index, file) {
3492		const fileName = file.name;
3493		const fileSize = (file.size / 1024).toFixed(2) + ' KB';
3494
3495		// Создаем элемент для каждого файла
3496		const fileItem = $('<div class="main-file-block__result-item"></div>')
3497			.append(`
3498        <div class="main-file-block__result-item-status">
3499          <svg>
3500            <use xlink:href="${SITE_TEMPLATE_PATH}/img/sprite.svg#check"></use>
3501          </svg>
3502        </div>
3503        <div class="main-file-block__result-item-text">${fileName} <span>(${fileSize})</span></div>
3504        <div class="main-file-block__result-item-icon js-main-file__delete" data-index="${index}">
3505          <svg>
3506            <use xlink:href="${SITE_TEMPLATE_PATH}/img/sprite.svg#close"></use>
3507          </svg>
3508        </div>
3509      `);
3510		fileList.append(fileItem);
3511	});
3512}
3513// Выбор файла в форме отзывов end =========================================
3514
3515// Tabs start --------------------------
3516$(document).on('click', '.js-tab-nav-item', function () {
3517	let thisValueData = $(this).data('tab');
3518	if (!$(this).hasClass('active')) {
3519		$(this).parents('.js-tab').find('.js-tab-nav-item').removeClass('active');
3520		$(this).addClass('active');
3521	}
3522	let contentData = $(this).parents('.js-tab').find('.js-tab-body-item');
3523	contentData.each(function () {
3524		if ($(this).data('tab') == thisValueData) {
3525			contentData.removeClass('active').hide();
3526			$(this).addClass('active').show();
3527		}
3528	});
3529});
3530// Tabs end --------------------------
3531
3532$(document).on('click', '.js-block-section-atoll__btn', function () {
3533	$(this).parents('.js-block-section-atoll').addClass('open');
3534	$(this).parents('.js-block-section-atoll').find('.js-block-section-atoll__body').slideDown(300);
3535});
3536
3537$(document).on('click', '.js-block-spoiler__btn', function () {
3538	let item = $(this);
3539	$(this).parents('.js-block-spoiler').addClass('open');
3540	$(this).parents('.js-block-spoiler').find('.js-block-spoiler__desc').slideDown(300)
3541});
3542
3543
3544// Код для отзывов на странице reviews ====================================
3545function reviewsBlock(element) {
3546	let blockHeight = parseInt(element.find('.js-reviews-item__text').get(0).scrollHeight);
3547	let height = parseInt(element.find('.js-reviews-item__text').height() + 2);
3548	if (blockHeight > height) {
3549		element.addClass('active');
3550	} else {
3551		element.removeClass('active');
3552	}
3553}
3554$(window).resize(function () {
3555	$(".js-reviews-item").each(function (index, value) {
3556		reviewsBlock($(this))
3557	});
3558});
3559$(".js-reviews-item").each(function (index, value) {
3560	reviewsBlock($(this))
3561});
3562
3563$(document).on('click', '.js-reviews-item__btn', function () {
3564	if (!$(this).parents('.js-reviews-item').hasClass('open')) {
3565		$(this).parents('.js-reviews-item').addClass('open');
3566	} else {
3567		$(this).parents('.js-reviews-item').removeClass('open');
3568	}
3569});
3570// Код для отзывов на странице reviews end ====================================
3571
3572// Select start --------------------------
3573function customSelect(element) {
3574	element.parents('.js-select__list').find('.js-select__item').removeClass('selected');
3575	element.addClass('selected');
3576	let text = element.text().trim();
3577	let value = element.data('value');
3578	element.parents('.js-select').find('.js-select__value').text(text);
3579	element.parents('.js-select').find('input[type="hidden"]').val(value).trigger('change')
3580}
3581$(document).on('click', '.js-select__trigger', function (e) {
3582	if (!$(this).parents('.js-select').hasClass('open')) {
3583		$('.js-select').removeClass('open').find('.js-select__list').removeClass('open');
3584		$(this).parents('.js-select').addClass('open').find('.js-select__list').addClass('open');
3585	} else {
3586		$(this).parents('.js-select').removeClass('open').find('.js-select__list').removeClass('open');
3587	}
3588});
3589$(document).on('click', '.js-select__item', function () {
3590	if (!$(this).hasClass('selected')) {
3591		customSelect($(this))
3592	}
3593	$(this).parents('.js-select').find('.js-select__trigger').removeClass('open')
3594	$(this).parents('.js-select').removeClass('open').find('.js-select__list').removeClass('open');
3595});
3596$(document).on('click', function (e) {
3597	if (!$(e.target).closest('.js-select__trigger').length && !$(e.target).closest('.js-select__list').length) {
3598		$('.js-select').removeClass('open');
3599		$('.js-select__list').removeClass('open');
3600	}
3601});
3602$(document).ready(function () {
3603	$('.js-select').each(function (index, value) {
3604		$(value).find('.js-select__item').each(function (index, item) {
3605			if ($(item).hasClass('selected')) {
3606				$(item).trigger('click')
3607				customSelect($(item));
3608			}
3609		});
3610	});
3611})
3612// Select end --------------------------
3613
3614$(document).on('click', '.js-meal-plans__btn', function () {
3615	if (!$(this).parents('.js-meal-plans__item').hasClass('open')) {
3616		$(this).parents('.js-meal-plans__item').addClass('open');
3617	} else {
3618		$(this).parents('.js-meal-plans__item').removeClass('open');
3619	}
3620});
3621
3622$(document).on('click', '.js-item-villa__btn', function () {
3623	if (!$(this).parents('.js-item-villa').hasClass('active')) {
3624		$(this).parents('.js-item-villa').addClass('active');
3625	} else {
3626		$(this).parents('.js-item-villa').removeClass('active');
3627	}
3628});
3629
3630
3631
3632
3633
3634
3635
3636// Когда API Kinescope готово
3637function onKinescopeIframeAPIReady(playerFactory) {
3638
3639	// Перебираем все блоки с видео
3640	$('.js-video-block').each(function (index, value) {
3641		let playerId = $(this).find('.js-video-block__video').data('player-id');
3642		// Получаем URL для каждого видео (из data-vi
3642deo-url)
3643		let videoUrl = $(this).find('.js-video-block__video').data('video-url');
3644		let timeBlock = $(this).find('.js-video-block__time'); // Блок для продолжительности видео
3645		let playBtn = $(this).find('.js-video-block__play')[0];
3646		let videoBlock = $(this); // Ссылка на сам блок видео
3647		// Создаем плеер для каждого видео без стандартных элементов управления и кнопки play
3648		playerFactory.create(playerId, {
3649			url: videoUrl, // Уникальный URL для каждого видео
3650			size: { width: '100%', height: '100%' }, // Высота плеера на 100% от родительского контейнера
3651			ui: {
3652				mainPlayButton: false, // Отключаем стандартную кнопку воспроизведения
3653				controls: false,       // Отключаем стандартные элементы управления
3654				playbackRateButton: false // Отключаем кнопку изменения скорости воспроизведения
3655			},
3656			behavior: {
3657				autoPlay: false,        // Не автозапускать видео
3658				loop: false,            // Без зацикливания
3659				muted: true,            // Отключаем звук
3660				localStorage: false     // Отключаем использование localStorage для хранения состояния плеера
3661			}
3662		}).then(function (player) {
3663			// Подписываемся на событие "готовность" плеера
3664			player.on(player.Events.Ready, function (event) {
3665				// Принудительно ставим на паузу, даже если видео вдруг воспроизводится
3666				player.pause().catch(function (err) {
3667					console.warn('Не удалось поставить видео на паузу:', err);
3668				});
3669				// console.log('Плеер для ' + playerId + ' готов');
3670
3671				// Получаем продолжительность видео в секундах
3672				player.getDuration().then(function (durationInSeconds) {
3673					// Преобразуем в минуты и секунды
3674					let minutes = Math.floor(durationInSeconds / 60);
3675					let seconds = Math.floor(durationInSeconds % 60);
3676
3677					// Форматируем в нужный вид "X мин Y с", но если меньше минуты, то только "Y с"
3678					let formattedTime = minutes > 0 ? (minutes + ' мин ' + seconds + ' с') : (seconds + ' с');
3679
3680					// Отображаем продолжительность в соответствующем блоке
3681					timeBlock.text(formattedTime);
3682					videoBlock.addClass('loaded');
3683				});
3684			});
3685
3686			// Логика для переключения состояния видео
3687			$(playBtn).on('click', function () {
3688
3689
3690				// Проверяем состояние видео с помощью метода isPaused()
3691				player.isPaused().then(function (isPaused) {
3692					if (isPaused) {
3693						// Если видео на паузе, запускаем его
3694						player.play().then(function () {
3695							// console.log('Видео ' + playerId + ' началось');
3696							// Добавляем класс "active" к текущему блоку при запуске видео
3697							videoBlock.removeClass('video-ended');
3698							videoBlock.addClass('active played');
3699						});
3700					} else {
3701						// Если видео воспроизводится, ставим его на паузу
3702						player.pause().then(function () {
3703							// console.log('Видео ' + playerId + ' поставлено на паузу');
3704							// Не удаляем класс "active", потому что приостанавливается видео
3705							videoBlock.removeClass('active');
3706						});
3707					}
3708				}).catch(function (error) {
3709					// console.log('Ошибка при проверке состояния видео ' + playerId, error);
3710				});
3711			});
3712
3713			// Скрытие кнопки повторного запуска при завершении видео
3714			player.on(player.Events.Ended, function () {
3715				// console.log('Видео ' + playerId + ' завершилось');
3716				// Убираем класс "active" при завершении видео
3717				videoBlock.removeClass('active played');
3718				videoBlock.addClass('video-ended');
3719			});
3720		});
3721	});
3722}
3723
3724// Загрузим скрипт API
3725var tag = document.createElement('script');
3726tag.src = 'https://player.kinescope.io/latest/iframe.player.js';
3727var firstScriptTag = document.getElementsByTagName('script')[0];
3728firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739function nearestValue(arr, val) {
3740	return arr.reduce((nearest, num) => {
3741		// Если текущее число ближе к val, чем ближайшее найденное ранее — обновляем nearest
3742		if (Math.abs(num - val) < Math.abs(nearest - val)) {
3743			return num;
3744		}
3745		// Если расстояния равны — выбираем меньшее из двух
3746		if (Math.abs(num - val) === Math.abs(nearest - val)) {
3747			return num < nearest ? num : nearest;
3748		}
3749		return nearest;
3750	});
3751}
3752
3753$(window).scroll(function () {
3754	let navBlock = $('.js-df-page-nav');
3755	if (navBlock.length) {
3756		let arBlockOffsets = [];
3757		let arBlockIds = [];
3758
3759		navBlock.find('.js-menu-nav__item').each(function (i, el) {
3760			let navEl = $(this);
3761			let navElId = navEl.attr('href').replace('#', '');
3762			arBlockIds.push(navElId);
3763			let contentBlock = $('[id=' + navElId + ']');
3764			if (contentBlock.length) {
3765				arBlockOffsets.push(contentBlock.offset().top);
3766			}
3767		});
3768
3769		// Получаем ближайшее значение прокрутки
3770		let nearestScrollTop = nearestValue(arBlockOffsets, $(window).scrollTop());
3771
3772		// Находим индекс ближайшего значения
3773		let nearestIndex = arBlockOffsets.indexOf(nearestScrollTop);
3774
3775		if (nearestIndex > -1) {
3776			navBlock.find('.js-menu-nav__item').removeClass('link-active')
3777				.eq(nearestIndex).addClass('link-active');
3778		}
3779	}
3780});
3781$(document).ready(function () {
3782	$(window).trigger('scroll');
3783})
3784
3785$(document).on('click', '#page-to-up, .js-open-menu', function (event) {
3786	$("html, body").animate({
3787		scrollTop: 0
3788	}, 300, function () {
3789		$('.mob-bottom-nav__links').slideUp(100)
3790	});
3791});
3792
3793
3794
3795
3796
3797
3798$(document).ready(function () {
3799
3800
3801
3802
3803
3804	if ($('.js-date-placement__input').length > 0) {
3805		const monthNames = ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
3806
3807		$('.js-date-placement__input').each(function () {
3808			const $input = $(this);
3809			const $val = $input.closest('.js-date-placement').find('.js-date-placement__value');
3810			const $daysLabel = $input.closest('.js-date-placement').find('.js-date-placement__days');
3811
3812			const dataStart = $input.data('start');
3813			const dataEnd = $input.data('end');
3814
3815			// --- парсим даты ---
3816			let startDate = dataStart ? new Date(dataStart) : null;
3817			let endDate = dataEnd ? new Date(dataEnd) : null;
3818
3819			// --- если нет атрибутов — ставим завтра и +7 дней ---
3820			if (!startDate || isNaN(startDate.getTime())) {
3821				startDate = new Date();
3822				startDate.setDate(startDate.getDate() + 1);
3823			}
3824
3825			if (!endDate || isNaN(endDate.getTime())) {
3826				endDate = new Date(startDate);
3827				endDate.setDate(startDate.getDate() + 6); // 7 дней включительно
3828			}
3829
3830			// --- формат для отображения ---
3831			const formatDisplay = (start, end) => {
3832				if (!end) return `${start.getDate()} ${monthNames[start.getMonth()]}`;
3833				if (start.getMonth() === end.getMonth()) {
3834					return `${start.getDate()} - ${end.getDate()} ${monthNames[end.getMonth()]}`;
3835				} else {
3836					return `${start.getDate()} ${monthNames[start.getMonth()]} - ${end.getDate()} ${monthNames[end.getMonth()]}`;
3837				}
3838			};
3839
3840			// --- нормальный формат для value ---
3841			const formatISO = (date) => {
3842				const y = date.getFullYear();
3843				const m = String(date.getMonth() + 1).padStart(2, '0');
3844				const d = String(date.getDate()).padStart(2, '0');
3845				return `${y}-${m}-${d}`;
3846			};
3847
3848			const dp = new AirDatepicker($input[0], {
3849				range: true,
3850				toggleSelected: false,
3851				minDate: new Date(), // нельзя выбрать прошедшие
3852				onSelect({ date, datepicker }) {
3853					if (datepicker.selectedDates.length === 2) {
3854						const [start, end] = datepicker.selectedDates;
3855
3856						$input.val(formatDisplay(start, end));
3857						$val.val(`${formatISO(start)} - ${formatISO(end)}`);
3858
3859						const daysDiff = Math.floor((end - start) / (1000 * 60 * 60 * 24));
3860						$daysLabel.text(`${daysDiff} ${declOfNum(daysDiff, ['ночь', 'ночи', 'ночей'])}`);
3861					} else if (datepicker.selectedDates.length === 1) {
3862						const [start] = datepicker.selectedDates;
3863
3864						$input.val(formatDisplay(start));
3865						$val.val(formatISO(start));
3866
3867						$daysLabel.text('1 день');
3868					} else {
3869						$input.val('');
3870						$val.val('');
3871						$daysLabel.text('');
3872					}
3873				}
3874			});
3875
3876			// --- устанавливаем стартовые даты ---
3877			dp.selectDate([startDate, endDate]);
3878
3879			$input.val(formatDisplay(startDate, endDate));
3880			$val.val(`${formatISO(startDate)} - ${formatISO(endDate)}`);
3881
3882			const diffDays = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
3883			$daysLabel.text(`${diffDays} ${declOfNum(diffDays, ['ночь', 'ночи', 'ночей'])}`);
3884
3885		});
3886	}
3887
3888
3889})
3890
3891// Скрипт для слайдера цены ===========================
3892if ($('.js-slider-noui-slider').length) {
3893	$('.js-slider-noui-slider').each(function (index, value) {
3894		let from = $(value).parents('.js-slider-noui').find('.js-slider-noui-from');
3895		let to = $(value).parents('.js-slider-noui').find('.js-slider-noui-to');
3896		let min = $(value).data('min');
3897		let max = $(value).data('max');
3898		noUiSlider.create(value, {
3899			start: [min, max],
3900			connect: true,
3901			step: 1000,
3902			range: {
3903				'min': min,
3904				'max': max
3905			},
3906			format: wNumb({
3907				decimals: 0,
3908				thousand: ' ',
3909
3910			}),
3911		}).on('update', function (values, handle, unencoded) {
3912			$(value).parents('.js-slider-noui').find('.js-slider-noui-from').val(values[0]);
3913			$(value).parents('.js-slider-noui').find('.js-slider-noui-to').val(values[1]);
3914			$(value).parents('.js-slider-noui').find('.js-slider-noui__tag').removeClass('active');;
3915		});
3916		Inputmask('numeric', {
3917			groupSeparator: ' ',
3918			autoGroup: true,
3919			digits: 0,
3920			rightAlign: false,
3921			removeMaskOnSubmit: true
3922		}).mask(from.add(to));
3923		$(from).on('change', function () {
3924			let parent = $(this).parents('.js-slider-noui');
3925			let to = $(value).find('.js-slider-noui-to').val();
3926			value.noUiSlider.set([$(this).val(), to]);
3927			parent.find('.js-slider-noui__tag').removeClass('active');
3928		});
3929		$(to).on('change', function () {
3930			let parent = $(this).parents('.js-slider-noui');
3931			let from = $(parent).find('.js-slider-noui-from').val();
3932			value.noUiSlider.set([from, $(this).val()]);
3933			parent.find('.js-slider-noui__tag').removeClass('active');
3934		});
3935		$(value).parents('.js-slider-noui').find('.js-slider-noui__tag').on('click', function () {
3936			let parent = $(this).parents('.js-slider-noui');
3937			parent.find('.js-slider-noui__tag').removeClass('active');
3938			let slider = parent.find('.js-slider-noui-slider')[0];
3939			let min = parseInt($(this).data('min'), 10);
3940			let max = parseInt($(this).data('max'), 10);
3941			slider.noUiSlider.set([min, max]);
3942			$(this).addClass('active');
3943		});
3944
3945	});
3946}
3947// Скрипт для слайдера цены end ===========================
3948
3949function scrollToBlock(speed = 800, selector) {
3950	// поддержка вызова scrollToBlock('.class')
3951	if (typeof speed === 'string' && !selector) {
3952		selector = speed;
3953		speed = 800;
3954	}
3955
3956	if (!selector) return;
3957
3958	const $el = $(selector);
3959	if ($el.length === 0) return;
3960
3961	$('html, body').animate({
3962		scrollTop: $el.offset().top
3963	}, speed);
3964}
3965
3966
3967$(document).on('click', '.js-anchor', function (e) {
3968	e.preventDefault();
3969	var anchor = '#' + $(this).attr('href').split('#')[1];
3970	let el = $(document).find(`${anchor}`);
3971	if (el.length) {
3972		var top = $(el).offset().top;
3973		$('html, body').animate({
3974			scrollTop: top - 10
3975		}, 700);
3976	}
3977});
3978
3979// Код для описания блоков на странице отеля ====================================
3980function hotelDescBlock(element) {
3981	let textBlock = element.find('.js-block-description__text');
3982	if (!textBlock.length) {
3983		return;
3984	}
3985	let blockHeight = textBlock.get(0).scrollHeight;
3986	let height = textBlock.height() + 2;
3987	if (blockHeight > height) {
3988		element.addClass('active');
3989	} else {
3990		element.removeClass('active');
3991	}
3992}
3993$(window).resize(function () {
3994	$(".block-section").each(function (index, value) {
3995		hotelDescBlock($(this))
3996	});
3997});
3998$(document).ready(function () {
3999	$(".block-section").each(function (index, value) {
4000		hotelDescBlock($(this))
4001	});
4002})
4003
4004$(document).on('click', '.js-block-description__btn', function () {
4005	if (!$(this).parents('.block-section').hasClass('open')) {
4006		$(this).parents('.block-section').addClass('open');
4007	} else {
4008		$(this).parents('.block-section').removeClass('open');
4009	}
4010});
4011// Код для описания блоков на странице отеля end ====================================
4012
4013function checkAirTickets() {
4014	var value = $('.js-air-tickets:checked').val();
4015	var $block = $('.js-air-tickets-content');
4016
4017	if (value === "false") {
4018		$block.addClass('hide-block');
4019
4020		// снимаем выбор
4021		$block.find('input[type="checkbox"], input[type="radio"]').prop('checked', false);
4022
4023		// сбрасываем select
4024		$block.find('select').prop('selectedIndex', 0);
4025
4026		// отключаем все поля
4027		$block.find('input, select, textarea').prop('disabled', true);
4028
4029	} else {
4030		$block.removeClass('hide-block');
4031
4032		// включаем обратно
4033		$block.find('input, select, textarea').prop('disabled', false);
4034	}
4035}
4036function checkTypeConnection() {
4037	var value = $('.js-type-connection:checked').val();
4038	var $block = $('.js-type-connection-content');
4039
4040	if (value !== "telegram") {
4041		$block.addClass('hide-block');
4042
4043		// снимаем выбор
4044		$block.find('input[type="checkbox"], input[type="radio"]').prop('checked', false);
4045
4046		// сбрасываем select
4047		$block.find('select').prop('selectedIndex', 0);
4048
4049		// отключаем всё
4050		$block.find('input, select, textarea').prop('disabled', true);
4051
4052	} else {
4053		$block.removeClass('hide-block');
4054
4055		// включаем обратно
4056		$block.find('input, select, textarea').prop('disabled', false);
4057	}
4058}
4059$(document).on('change', '.js-air-tickets', function () {
4060	checkAirTickets();
4061});
4062$(document).on('change', '.js-type-connection', function () {
4063	checkTypeConnection();
4064});
4065$(document).ready(function () {
4066	checkAirTickets();
4067	checkTypeConnection();
4068});
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084// =========================================================================================
4085
4086
4087// ===========================
4088// Настройка меню: открытие/закрытие
4089// ===========================
4090$(document).on('click', '.js-menu-nav-new__btn', function () {
4091	let $menu = $(this).parents('.js-menu-nav-new');
4092	let $content = $menu.find('.js-menu-nav-new__content');
4093	let $activeItem = $menu.find('.js-menu-nav-new__item.link-active');
4094
4095	if (!$(this).hasClass('open')) {
4096		$(this).addClass('open');
4097		$menu.addClass('open');
4098		if ($activeItem.length) $content.scrollTop($activeItem.position().top);
4099		lockBody();
4100		$('body').addClass('hide-bottom-panel').removeClass('show-bottom-nav');
4101	} else {
4102		$(this).removeClass('open');
4103		$menu.addClass('hide');
4104		unlockBody();
4105		$('body').removeClass('hide-bottom-panel').addClass('show-bottom-nav');
4106		setTimeout(() => $menu.removeClass('hide open'), 400);
4107	}
4108});
4109
4110$(document).on('click', '.js-menu-nav-new__body', function (e) {
4111	if (!$(e.target).closest('.js-menu-nav-new__btn, .js-menu-nav-new__list').length) {
4112		$('.js-menu-nav-new__btn').removeClass('open');
4113		$('.js-menu-nav-new').addClass('hide');
4114		unlockBody();
4115		$('body').removeClass('hide-bottom-panel').addClass('show-bottom-nav');
4116		setTimeout(() => $('.js-menu-nav-new').removeClass('hide open'), 400);
4117	}
4118});
4119
4120// ===========================
4121// Подсветка активного пункта для нескольких меню
4122// ===========================
4123$(document).ready(function () {
4124	$('.js-menu-nav-new').each(function () {
4125		let $menu = $(this);
4126		let menuItems = $menu.find('.js-menu-nav-new__item');
4127		let targets = [];
4128		let lastScrollTop = 0;
4129		let isAnimatingScroll = false;
4130		let forcedIndex = null;
4131
4132		// связываем пункты меню с блоками Ð
4132½Ð° странице
4133		menuItems.each(function (index) {
4134			let targetSelector = $(this).attr('href');
4135			if (targetSelector && $(targetSelector).length) {
4136				targets.push($(targetSelector)[0]);
4137			} else {
4138				targets.push(null);
4139			}
4140		});
4141
4142		function highlightMenuItem() {
4143			if (isAnimatingScroll && forcedIndex !== null) {
4144				menuItems.removeClass('link-active');
4145				menuItems.eq(forcedIndex).addClass('link-active');
4146				return;
4147			}
4148
4149			let scrollTop = $(window).scrollTop();
4150			let direction = scrollTop > lastScrollTop ? 1 : -1;
4151
4152			lastScrollTop = scrollTop;
4153
4154			let activeIndex = -1;
4155
4156			for (let i = 0; i < targets.length; i++) {
4157				if (!targets[i]) continue;
4158
4159				let $current = $(targets[i]);
4160				let start = $current.offset().top;
4161
4162				let nextTop = (i + 1 < targets.length && targets[i + 1])
4163					? $(targets[i + 1]).offset().top
4164					: $(document).height();
4165
4166				if (scrollTop >= start - 5 && scrollTop < nextTop - 5) {
4167					activeIndex = i;
4168					break;
4169				}
4170			}
4171
4172			let prevActiveIndex = menuItems.filter('.link-active').index();
4173
4174			// Если активного пункта ещё не было
4175			if (prevActiveIndex === -1 && activeIndex !== -1) {
4176				menuItems.eq(activeIndex).addClass('link-active');
4177				menuNavScrollNew(direction);
4178				return;
4179			}
4180
4181			if (activeIndex !== prevActiveIndex && activeIndex !== -1) {
4182				menuItems.removeClass('link-active');
4183				menuItems.eq(activeIndex).addClass('link-active');
4184				menuNavScrollNew(direction);
4185			}
4186		}
4187
4188		// Скролл страницы
4189		$(window).on('scroll', highlightMenuItem);
4190
4191		// Клик по пункту меню
4192		menuItems.on('click', function (e) {
4193
4194			let targetSelector = $(this).attr('href');
4195			if (targetSelector && $(targetSelector).length) {
4196				e.preventDefault();
4197				isAnchorClicking = false; // Устанавливаем флаг, что скроллинг по якорю
4198				let item = $(this);
4199				isAnimatingScroll = true;
4200				forcedIndex = menuItems.index(this);
4201
4202				$(this).parents('.js-menu-nav-new').find('.js-menu-nav-new__btn').removeClass('open');
4203				$(this).parents('.js-menu-nav-new').addClass('hide');
4204				unlockBody();
4205				$('body').removeClass('lock');
4206				if (!$('body').attr('class')) {
4207					$('body').removeAttr('class');
4208				}
4209
4210				let targetTop = $(targetSelector).offset().top;
4211				$('html, body').animate({ scrollTop: targetTop }, 700, function () {
4212					isAnimatingScroll = false;
4213					forcedIndex = null;
4214					highlightMenuItem();
4215
4216					// Вычисляем направление скролла по сравнению с предыдущим scrollTop
4217					let direction = $(window).scrollTop() > lastScrollTop ? 1 : -1;
4218					lastScrollTop = $(window).scrollTop();
4219
4220					// Прокручиваем меню к активному элементу
4221					menuNavScrollNew(direction);
4222					// Удаляем хеш из URL после прокрутки
4223					history.replaceState(null, null, ' ');
4224				});
4225
4226				setTimeout(() => {
4227					$(item).parents('.js-menu-nav-new').removeClass('hide open');
4228				}, 400);
4229				setTimeout(() => {
4230					$('body').removeClass('show-elements');
4231					if (!$('body').attr('class')) {
4232						$('body').removeAttr('class');
4233					}
4234					isAnchorClicking = true; // Сбрасываем флаг после завершения анимации
4235				}, 1500);
4236
4237			}
4238		});
4239
4240		// Инициализация при загрузке страницы
4241		highlightMenuItem();
4242	});
4243});
4244// ===========================
4245// Ограничение высоты меню
4246// ===========================
4247function menuNavHeightNew() {
4248	$('.js-menu-nav-new.js-menu-nav-height').each(function () {
4249		let itemsHeight = 0;
4250		let heightParent = $(window).height() / 2;
4251		let $links = $(this).find('.js-menu-nav-new__item');
4252
4253		for (let i = 0; i < $links.length; i++) {
4254			itemsHeight += $($links[i]).outerHeight();
4255			if (itemsHeight > heightParent) {
4256				let maxHeight = itemsHeight - $($links[i]).outerHeight();
4257				$(this).find('.js-menu-nav-new__items').css('max-height', maxHeight + 'px');
4258				break;
4259			}
4260		}
4261	});
4262}
4263$(window).on('resize', () => setTimeout(menuNavHeightNew, 200));
4264menuNavHeightNew();
4265
4266
4267//  Меню в детальной блога
4268// function menuNavHeightNew() {
4269// 	if ($('.js-menu-nav-new.js-menu-nav-height').length) {
4270// 		$('.js-menu-nav-new.js-menu-nav-height').each(function (index, value) {
4271// 			let itemsHeight = 0;
4272// 			let heightParent = $(window).height() / 2;
4273// 			let links = $(value).find('.js-menu-nav-new__item');
4274// 			$(links).each(function (i, item) {
4275// 				itemsHeight += $(item).outerHeight();
4276// 				if (itemsHeight > heightParent) {
4277// 					let heightContent = itemsHeight - $(item).outerHeight();
4278// 					$(value).find('.js-menu-nav-new__items').css('max-height', heightContent + 'px');
4279// 					return false;
4280// 				}
4281// 			});
4282// 		});
4283// 	}
4284// }
4285function menuNavScrollNew(item) {
4286	if ($('.js-menu-nav-new.js-menu-nav-scroll').length) {
4287		$('.js-menu-nav-new.js-menu-nav-scroll').each(function (index, value) {
4288			let linkActive = $(value).find('.js-menu-nav-new__item.link-active');
4289			let linkActiveIndex = 0;
4290			let items = $(value).find('.js-menu-nav-new__item');
4291			let scroll = 0;
4292			$(items).each(function (i, v) {
4293				if ($(v).hasClass('link-active')) {
4294					linkActiveIndex = i;
4295					return false
4296				}
4297			});
4298			if (linkActive.length && allowScrolling) {
4299				let heightParent = $(value).find('.js-menu-nav-new__content').outerHeight();
4300
4301
4302				let scrollBlock = $(value).find('.js-menu-nav-new__items');
4303				let scrollBlockY = scrollBlock.scrollTop();
4304				let linkActiveY = linkActive.offset().top - scrollBlock.offset().top + scrollBlockY + linkActive.outerHeight();
4305				// let linkActiveY = linkActivePosition.top + linkActive.outerHeight();
4306				let scrollTop = (linkActiveY - heightParent);
4307				let scrollableContentHeight = scrollBlock[0].scrollHeight;
4308				if ($(window).scrollTop() > linkActive.outerHeight()) {
4309
4310
4311					// Если скролим вниз
4312					if (item > 0) {
4313						scroll += $(items).eq(linkActiveIndex + 1).outerHeight() + $(items).eq(linkActiveIndex + 2).outerHeight();
4314						if (linkActiveY > heightParent + scrollBlockY - scroll) {
4315							if (scrollableContentHeight - linkActiveY < heightParent) {
4316								scroll = scrollableContentHeight;
4317								$(scrollBlock).animate({
4318									scrollTop: scrollTop + scroll
4319								}, 300);
4320							} else {
4321								$(scrollBlock).animate({
4322									scrollTop: scrollTop + scroll
4323								}, 300);
4324							}
4325						} else if (linkActiveY < scrollBlockY + scroll) {
4326							if (scrollableContentHeight - linkActiveY < heightParent) {
4327								scroll = scrollableContentHeight;
4328								$(scrollBlock).animate({
4329									scrollTop: scrollTop + scroll
4330								}, 300);
4331							} else {
4332								$(scrollBlock).animate({
4333									scrollTop: scrollTop + scroll
4334								}, 300);
4335							}
4336						}
4337					} else {
4338						scroll += $(items).eq(linkActiveIndex - 1).outerHeight() + $(items).eq(linkActiveIndex - 2).outerHeight();
4339						if ((linkActiveY - linkActive.outerHeight()) + scroll < heightParent) {
4340							$(scrollBlock).animate({
4341								scrollTop: 0
4342							}, 300);
4343						} else {
4344							$(scrollBlock).animate({
4345								scrollTop: linkActiveY - scroll - linkActive.outerHeight()
4346							}, 300)
4347
4348						}
4349					}
4350				}
4351			}
4352		});
4353	}
4354}
4355let resizeTimeoutNew;
4356$(window).on('resize', function () {
4357	clearTimeout(resizeTimeoutNew);
4358	// Устанавливаем новый таймер, чтобы выполнить функцию только после завершения resize
4359	resizeTimeoutNew = setTimeout(function () {
4360		menuNavHeightNew();
4361	}, 200); // Задержка 200 мс, чтобы подождать окончания изменения размера
4362});
4363$(document).ready(function () {
4364	menuNavHeightNew();
4365})
4366
4367//  Меню в детальной блога end
4368// =========================================================================================

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.