1(function ($) { 2 var adminbar = 0; 3 if ($('#wpadminbar').length) { 4 adminbar = $('#wpadminbar').height(); 5 } 6 7 function generate_select(selector) { 8 $(selector).each(function () { 9 10 // Cache the number of options 11 var $this = $(this), 12 activeValue = $this.val(), 13 classselect = $this.attr("class"), 14 numberOfOptions = $(this).children("option").length; 15 16 // Hides the select element 17 $this.addClass("s-hidden"); 18 19 // Wrap the select element in a div 20 $this.wrap('<div class="select ' + classselect + '"></div>'); 21 22 // Insert a styled div to sit over the top of the hidden select element 23 $this.after('<div class="styledSelect"></div>'); 24 25 // Cache the styled div 26 var $styledSelect = $this.next("div.styledSelect"); 27 var getHTML = $this.children('option[value="' + $this.val() + '"]').text(); 28 29 // if ($this.children('option[value="' + $this.val() + '"]').length > 1) { 30 // var getHTML = $this 31 // .children("option") 32 // .eq(0) 33 // .text(); 34 // } 35 // Show the first select option in the styled div 36 $styledSelect.html('<span class="text-ellipses">' + getHTML + '</span>'); 37 38 // Insert an unordered list after the styled div and also cache the list 39 var $list = $("<ul />", { class: "options" }).insertAfter($styledSelect); 40 41 // Insert a list item into the unordered list for each select option 42 for (var i = 1; i < numberOfOptions; i++) { 43 var Cls = $this.children("option").eq(i).attr('class'); 44 if (Cls == undefined) { 45 Cls = ''; 46 } 47 if ($this.children("option").eq(i).val() == activeValue) { 48 Cls = Cls + ' active'; 49 $('.text-ellipses').addClass('valueAdded'); 50 } 51 $("<li />", { 52 text: $this 53 .children("option") 54 .eq(i) 55 .text(), 56 rel: $this 57 .children("option") 58 .eq(i) 59 .val(), 60 class: Cls 61 }).appendTo($list); 62 } 63 64 // Cache the list items 65 var $listItems = $list.children("li"); 66 67 // Show the unordered list when the styled div is clicked (also hides it if the div is clicked again) 68 $styledSelect.click(function (e) { 69 e.stopPropagation(); 70 if (!$(this).hasClass('active')) { 71 $('div.styledSelect.active').each(function () { 72 $(this).removeClass('active').next('ul.options').slideUp(); 73 // return false; 74 }); 75 $(this).toggleClass("active"); 76 $(this).next("ul.options").stop(true).slideToggle(); 77 } else { 78 $('div.styledSelect.active').each(function () { 79 $(this).removeClass('active').next('ul.options').slideUp(); 80 // return false; 81 }); 82 } 83 }); 84 85 // Hides the unordered list when a list item is clicked and updates the styled div to show the selected list item 86 // Updates the select element to have the value of the equivalent option 87 $listItems.click(function (e) { 88 e.stopPropagation(); 89 $styledSelect.html('<span class="text-ellipses valueAdded">' + $(this).text() + '</span>').removeClass("active"); 90 var value = $(this).attr("rel").toString(); 91 $($this).val(value); 92 $($this).trigger("change"); 93 $('ul.options').slideUp(); 94 $(this).addClass("active").siblings().removeClass("active"); 95 /* alert($this.val()); Uncomment this for demonstration! */ 96 if ($this.hasClass('gt_selector')) { 97 doGTranslate(value); 98 } 99 }); 100 101 // Hides the unordered list when clicking outside of it 102 $(document).click(function () { 103 $styledSelect.removeClass("active"); 104 $list.slideUp(); 105 }); 106 107 }); 108 } 109 110 // -------------------------------------------------- 111 // jQuery Match Height 112 // -------------------------------------------------- 113 114 // all the elements where MatchHeight will be applied to 115 const matchHeightElements = [ 116 '.cta_height_100 .elementor-cta__description', 117 ]; 118 119 // apply matchHeight to a single element 120 function doMatchHeight(_element) { 121 $(_element).matchHeight({ 122 byRow: true, 123 property: 'min-height', 124 }); 125 } 126 // apply match height to all the elements 127 $(window).on('resize load', function () {
128 matchHeightElements.forEach(doMatchHeight); 129 }); 130 131 132 $(document).ready(function () { 133 // add class of ie_edge for edge 134 if (document.documentMode || /Edge/.test(navigator.userAgent)) { 135 $('body').addClass('ie_edge'); 136 } 137 //run the select code for all selects 138 generate_select('select:not(.gfield_select)'); 139 document.activeElement.blur(); 140 $(document).on('gform_post_render', function (event, form_id, current_page) { 141 generate_select('#gform_wrapper_' + form_id + ' select.gfield_select'); 142 $("li.gf_readonly input").attr("readonly", "readonly"); 143 }); 144 145 146 $('.garden-events:not(.garden-events--tabs)').each(function () { 147 148 const section = $(this); 149 const slider = section.find('.garden-events__slider'); 150 const wrapper = slider.find('.swiper-wrapper'); 151 const filters = section.find('.garden-events__filter'); 152 const status = section.find('.garden-events__status-message'); 153 const prev = section.find('.garden-events__navigation-button--prev'); 154 const next = section.find('.garden-events__navigation-button--next'); 155 const progress = section.find('.garden-events__progress-bar'); 156 157 if (!slider.length || typeof Swiper === 'undefined') { 158 return; 159 } 160 161 const reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 162 const allSlides = wrapper.children('.swiper-slide').clone(); 163 let swiper; 164 165 function initSlider() { 166 167 swiper = new Swiper(slider[0], { 168 slidesPerView: 1.155, 169 spaceBetween: 16, 170 speed: reduceMotion ? 0 : 450, 171 watchOverflow: true, 172 observer: true, 173 observeParents: true, 174 175 navigation: { 176 prevEl: prev[0], 177 nextEl: next[0] 178 }, 179 180 breakpoints: { 181 520: { 182 slidesPerView: 1.5, 183 spaceBetween: 16 184 }, 185 768: { 186 slidesPerView: 2, 187 spaceBetween: 24 188 }, 189 1024: { 190 slidesPerView: 3, 191 spaceBetween: 24 192 }, 193 1280: { 194 slidesPerView: 4, 195 spaceBetween: 24 196 } 197 }, 198 199 a11y: { 200 enabled: true, 201 prevSlideMessage: 'Previous events', 202 nextSlideMessage: 'Next events' 203 }, 204 205 on: { 206 slideChange: updateControls, 207 resize: updateControls, 208 setTranslate: updateControls 209 } 210 }); 211 212 updateControls(); 213 214 slider.addClass('is-ready'); 215 } 216 217 function updateControls() { 218 219 if (!swiper || !swiper.snapGrid) { 220 return; 221 } 222 223 prev 224 .prop('disabled', swiper.isBeginning) 225 .attr('aria-disabled', swiper.isBeginning); 226 227 next 228 .prop('disabled', swiper.isEnd) 229 .attr('aria-disabled', swiper.isEnd); 230 231 // Discrete step-based progress instead of smooth swiper.progress. 232 const totalSteps = swiper.snapGrid.length || 1; 233 const currentStep = Math.round(swiper.progress * (totalSteps - 1)); 234 const progressValue = (currentStep + 1) / totalSteps; 235 236 progress.css('width', (progressValue * 100) + '%'); 237 } 238 239 function refreshOnVisible() { 240 241 if (!swiper) { 242 return; 243 } 244 245 if (section.is(':visible')) { 246 swiper.update(); 247 updateControls(); 248 } 249 } 250 251 $(document).on('shown.bs.tab', refreshOnVisible); 252 253 if (typeof ResizeObserver !== 'undefined') { 254 const resizeObserver = new ResizeObserver(function () { 255 refreshOnVisible(); 256 }); 257 resizeObserver.observe(section[0]); 258 } 259 260 filters.on('click', function () { 261 262 const button = $(this); 263 const filter = button.data('filter'); 264 265 if (button.hasClass('is-active')) { 266 return; 267 } 268 269 filters 270 .removeClass('is-active') 271 .attr('aria-pressed', 'false'); 272 273 button 274 .addClass('is-active') 275 .attr('aria-pressed', 'true'); 276 277 const filteredSlides = allSlides.filter(function () { 278 if (filter === 'all') { 279 return true; 280 } 281 282 // data-event-type can hold multiple space-separated values 283 // (e.g. "day night" for an all-day ACF selection). 284 const types = ($(this).data('event-type') || '').toString().split(' '); 285 return types.indexOf(filter) !== -1; 286 }); 287 288 slider.addClass('is-filtering'); 289 290 setTimeout(function () { 291 292 if (swiper) { 293 swiper.destroy(true, true); 294 } 295 296 wrapper.empty().append(filteredSlides.clone()); 297 298 initSlider(); 299 300 const count = filteredSlides.length; 301 302 if (!count) { 303 status.text('No events found.'); 304 } else if (filter === 'all') { 305 status.text('Showing all ' + count + ' events.'); 306 } else { 307 status.text('Showing ' + count + ' ' + filter + ' event' + (count === 1 ? '' : 's') + '.'); 308 } 309 310 requestAnimationFrame(function () { 311 slider.removeClass('is-filtering'); 312 });
313 314 }, reduceMotion ? 0 : 250); 315 }); 316 317 initSlider(); 318 319 }); 320 321 // Garden events - accessible tabs version (.garden-events--tabs) 322 $('.garden-events--tabs').each(function () { 323 324 const section = $(this); 325 326 if (typeof Swiper === 'undefined') { 327 return; 328 } 329 330 const tabs = section.find('[role="tab"]'); 331 const panels = section.find('[role="tabpanel"]'); 332 const status = section.find('.garden-events__status-message'); 333 const prev = section.find('.garden-events__navigation-button--prev'); 334 const next = section.find('.garden-events__navigation-button--next'); 335 const progress = section.find('.garden-events__progress-bar'); 336 337 const swipers = {}; 338 let activeKey = tabs.filter('[aria-selected="true"]').data('panel') || 'all'; 339 340 function getActive() { 341 return swipers[activeKey]; 342 } 343 344 function updateControls() { 345 346 const swiper = getActive(); 347 348 if (!swiper || !swiper.snapGrid) { 349 return; 350 } 351 352 prev 353 .prop('disabled', swiper.isBeginning) 354 .attr('aria-disabled', swiper.isBeginning); 355 356 next 357 .prop('disabled', swiper.isEnd) 358 .attr('aria-disabled', swiper.isEnd); 359 360 const totalSteps = swiper.snapGrid.length || 1; 361 const currentStep = Math.round(swiper.progress * (totalSteps - 1)); 362 const progressValue = (currentStep + 1) / totalSteps; 363 364 progress.css('width', (progressValue * 100) + '%'); 365 } 366 367 // One Swiper per panel 368 panels.each(function () { 369 370 const panel = $(this); 371 const key = panel.data('panel'); 372 const slider = panel.find('.garden-events__slider'); 373 374 swipers[key] = new Swiper(slider[0], { 375 slidesPerView: 1.155, 376 spaceBetween: 16, 377 speed: 450, 378 watchOverflow: true, 379 observer: true, 380 observeParents: true, 381 382 breakpoints: { 383 520: { slidesPerView: 1.5, spaceBetween: 16 }, 384 768: { slidesPerView: 2, spaceBetween: 24 }, 385 1024: { slidesPerView: 3, spaceBetween: 24 }, 386 1280: { slidesPerView: 4, spaceBetween: 24 } 387 }, 388 389 a11y: { 390 enabled: false, 391 }, 392 393 on: { 394 slideChange: function () { if (this === getActive()) updateControls(); }, 395 resize: function () { if (this === getActive()) updateControls(); }, 396 setTranslate: function () { if (this === getActive()) updateControls(); } 397 } 398 }); 399 400 slider.addClass('is-ready'); 401 }); 402 403 // Shared prev / next buttons control whichever panel is active 404 prev.on('click', function () { 405 getActive().slidePrev(); 406 }); 407 408 next.on('click', function () { 409 getActive().slideNext(); 410 }); 411 412 function activateTab(tab, moveFocus) { 413 414 const key = tab.data('panel'); 415 416 if (!swipers[key]) { 417 return; 418 } 419 420 activeKey = key; 421 422 tabs 423 .removeClass('is-active') 424 .attr({ 'aria-selected': 'false', tabindex: '-1' }); 425 426 tab 427 .addClass('is-active') 428 .attr({ 'aria-selected': 'true', tabindex: '0' }); 429 430 panels.attr('hidden', true); 431 panels.filter('[data-panel="' + key + '"]').removeAttr('hidden'); 432 433 swipers[key].update(); 434 updateControls(); 435 436 status.text( 437 key === 'all' 438 ? 'Showing all events.' 439 : 'Showing ' + key + ' events.' 440 ); 441 442 if (moveFocus) { 443 tab.trigger('focus'); 444 } 445 } 446 447 tabs.on('click', function () { 448 activateTab($(this), false); 449 }); 450 451 // Roving tabindex + arrow keys (automatic activation) 452 tabs.on('keydown', function (event) { 453 454 const current = tabs.index(this); 455 let target = current; 456 457 switch (event.key) { 458 case 'ArrowRight': 459 target = (current + 1) % tabs.length; 460 break; 461 case 'ArrowLeft': 462 target = (current - 1 + tabs.length) % tabs.length; 463 break; 464 case 'Home': 465 target = 0; 466 break; 467 case 'End': 468 target = tabs.length - 1; 469 break; 470 default: 471 return; 472 } 473 474 event.preventDefault(); 475 activateTab(tabs.eq(target), true); 476 }); 477 478 // Recalculate when the section becomes visible (hidden parents, resize) 479 if (typeof ResizeObserver !== 'undefined') { 480 new ResizeObserver(function () { 481 if (section.is(':visible') && getActive()) { 482 getActive().update(); 483 updateControls(); 484 } 485 }).observe(section[0]); 486 } 487 488 updateControls(); 489 }); 490 491
492 // Tribe Events search bar â show a clear ("x") button once there's a 493 // keyword typed, clicking it empties the field and re-triggers the search. 494 // $('.tribe-events-c-search__input-control').each(function () { 495 496 // const wrapper = $(this); 497 // const input = wrapper.find('.tribe-events-c-search__input'); 498 // const clearButton = wrapper.find('.tribe-events-c-search__input-control-clear'); 499 500 // if (!input.length || !clearButton.length) { 501 // return; 502 // } 503 504 // function toggleClearButton() { 505 // clearButton.toggleClass('is-visible', input.val().length > 0); 506 // } 507 508 // toggleClearButton(); 509 510 // input.on('input', toggleClearButton); 511 512 // clearButton.on('click', function () { 513 // input.val('').trigger('input').focus(); 514 // toggleClearButton(); 515 516 // // Submit the events bar form (same as clicking "Find Events") 517 // // so Views V2 actually re-runs the query with the keyword cleared, 518 // // instead of only clearing the field visually. 519 // input.closest('form').trigger('submit'); 520 // }); 521 // }); 522 523 function isMobileView() { 524 return window.matchMedia("(max-width: 1024px)").matches; 525 } 526 527 // Search panel accessibility setup 528 const $searchToggle = $('.header-search-toggle'); 529 const $searchWrapper = $('.site-search-main-wrapper'); 530 531 if (!$searchWrapper.attr('id')) { 532 $searchWrapper.attr('id', 'site-search-panel'); 533 } 534 535 // Agar toggle native button/link nahi hai to keyboard-focusable banao 536 if (!$searchToggle.is('button, a[href]')) { 537 $searchToggle.attr({ role: 'button', tabindex: '0' }); 538 } 539 $searchToggle.attr({ 540 'aria-expanded': 'false', 541 'aria-controls': $searchWrapper.attr('id') 542 }); 543 544 // Toggle search visibility 545 function toggleSearch(show, returnFocus) { 546 $('body').toggleClass('search-open', show); 547 $searchToggle.attr('aria-expanded', show ? 'true' : 'false'); 548 549 if (show) { 550 if (isMobileView()) { 551 // Close header menu if open 552 $('.dbg-main-menu .sub-menu.active').removeClass('active'); 553 $('.dbg-main-menu').slideUp(); 554 $('body').removeClass('open-menu'); 555 } 556 setTimeout(() => { 557 $searchWrapper.find('form input').first().val('').focus(); 558 }, 100); 559 } else if (returnFocus) { 560 // Close hone par focus wapas toggle par 561 $searchToggle.focus(); 562 } 563 } 564 565 // Click 566 $searchToggle.on('click', function (e) { 567 e.stopPropagation(); 568 toggleSearch(!$('body').hasClass('search-open'), true); 569 }); 570 571 // Keyboard (Enter / Space) - sirf non-button elements ke liye, 572 // native <button> ka Enter/Space already click fire karta hai (double toggle se bachne ke liye) 573 $searchToggle.on('keydown', function (e) { 574 if ($(this).is('button')) return; 575 if (e.key === 'Enter' || e.key === ' ') { 576 e.preventDefault(); 577 $(this).trigger('click'); 578 } 579 }); 580 581 // Close search when clicking outside the search dropdown 582 $(document).on('click', function (e) { 583 if ( 584 $('body').hasClass('search-open') && 585 !$(e.target).closest('.site-search-main-wrapper').length && 586 !$(e.target).closest('.header-search-toggle').length 587 ) { 588 toggleSearch(false, false); 589 } 590 }); 591 592 // Close on Escape (focus wapas toggle par) 593 $(document).on('keydown', function (e) { 594 if (e.key === 'Escape' && $('body').hasClass('search-open')) { 595 toggleSearch(false, true); 596 } 597 }); 598 599 // Tab se focus search area ke bahar jaye to close 600 $(document).on('focusin', function (e) { 601 if ( 602 $('body').hasClass('search-open') && 603 !$(e.target).closest('.site-search-main-wrapper').length && 604 !$(e.target).closest('.header-search-toggle').length 605 ) { 606 toggleSearch(false, false); 607 } 608 }); 609 610 // -------------------------------------------------- 611 // Flyout menu for mobile. 612 // -------------------------------------------------- 613 $('<span class="open-menu-arrow"></span>').appendTo($('.dbg-main-menu .menu .menu-item.menu-item-has-children')); 614 615 // Menu toggle 616 $('.hamburger-toggle').on('click', function () { 617 if (isMobileView()) { 618 // Close search if open 619 toggleSearch(false); 620 } 621 622 $('.dbg-main-menu .sub-menu.active').removeClass('active'); 623 $('.dbg-main-menu').slideToggle(); 624 $('body').toggleClass('open-menu'); 625 }); 626 627 $(document).on('click', '.dbg-main-menu .open-menu-arrow, .dbg-main-menu .menu-item-has-children', function (e) { 628 if ($(e.target).is('a')) { 629 return; 630 } 631 e.stopPropagation(); 632 $(this).closest('.dbg-main-menu .menu-item-has-children').children('.sub-menu').addClass('active'); 633 }); 634 635 $('.dbg-main-menu .menu .menu-item-has-children').each(function () { 636 var $menuItem = $(this); 637 var $anchor = $menuItem.children('a'); 638 var anchorText = $anchor.text(); 639 var $subMenu = $menuItem.children('.sub-menu'); 640 if ($subMenu.length) { 641 var $toggleBack = $('<span class="toggle-back"><span></span></span>'); 642 $toggleBack.find('span').text(anchorText); 643 $subMenu.prepend($toggleBack); 644 } 645 }); 646 647 $(document).on('click', '.dbg-main-menu .sub-menu .toggle-back', function (e) { 648 e.stopPropagation(); 649 $(this).closest('.sub-menu').removeClass('active'); 650 }); 651 652 if ($('.event-layout .event-sidebar').length) { 653 var $tocLinks = $('.event-sidebar__toc a'); 654 var tocItems = []; 655 656 $tocLinks.each(function () { 657 var $link = $(this); 658 var $target = $($link.attr('href')); 659 if ($target.length) { 660 tocItems.push({ $link: $link, $section: $target }); 661 } 662 }); 663 664 function getOffset() { 665 var headerOffset = parseInt( 666 getComputedStyle(document.documentElement).getPropertyValue('--header-offset') 667 ) || 0; 668 return headerOffset + adminbar + 25; // +buffer, adjust as needed 669 } 670 671 function setActiveOnScroll() { 672 var scrollPos = $(window).scrollTop() + getOffset(); 673 var activeIndex = 0; 674
675 tocItems.forEach(function (item, i) { 676 if (item.$section.offset().top <= scrollPos) { 677 activeIndex = i; 678 } 679 }); 680 681 $tocLinks.parent('li').removeClass('active'); 682 if (tocItems[activeIndex]) { 683 tocItems[activeIndex].$link.parent('li').addClass('active'); 684 } 685 } 686 687 // 1st on load 688 if (tocItems.length) { 689 tocItems[0].$link.parent('li').addClass('active'); 690 } 691 692 $(window).on('scroll', setActiveOnScroll); 693 setActiveOnScroll(); 694 } 695 696 if ($('[data-tabs]').length) { 697 var MOBILE_BREAKPOINT = 768; 698 699 $('[data-tabs]').each(function () { 700 var $wrapper = $(this); 701 var $tabs = $wrapper.find('.tabs__tab'); 702 var $panels = $wrapper.find('.tabs__panel'); 703 var $inner = $wrapper.find('.tabs__panels__inner'); 704 var $accordionToggles = $wrapper.find('.tabs__panel__accordion-toggle'); 705 var $navSwiperEl = $wrapper.find('.tabs__nav.swiper'); 706 var tabsSwiper = null; 707 708 if ($navSwiperEl.length) { 709 tabsSwiper = new Swiper($navSwiperEl[0], { 710 slidesPerView: 'auto', 711 freeMode: true, 712 watchSlidesProgress: true, 713 }); 714 } 715 716 function isMobile() { 717 return $(window).width() < MOBILE_BREAKPOINT; 718 } 719 720 function activateTab(index) { 721 $tabs.removeClass('is-active'); 722 $panels.removeClass('is-active'); 723 724 var $activeTab = $wrapper.find('.tabs__tab[data-tab="' + index + '"]'); 725 $activeTab.addClass('is-active'); 726 $wrapper.find('.tabs__panel[data-panel="' + index + '"]').addClass('is-active'); 727 728 $inner.css('--active-index', index); 729 730 if (tabsSwiper) { 731 tabsSwiper.slideTo($activeTab.index()); 732 } 733 } 734 735 // Desktop tab click 736 $tabs.on('click', function () { 737 if (isMobile()) return; 738 var index = $(this).data('tab'); 739 activateTab(index); 740 }); 741 742 // Mobile accordion click 743 $accordionToggles.on('click', function () { 744 if (!isMobile()) return; 745 746 var $panel = $(this).closest('.tabs__panel'); 747 var index = $(this).data('tab'); 748 var wasActive = $panel.hasClass('is-active'); 749 750 // Close all panels first 751 $panels.not($panel).removeClass('is-active').find('.tabs__panel__content').slideUp(200); 752 $panels.not($panel).each(function () { 753 $wrapper.find('.tabs__tab[data-tab="' + $(this).data('panel') + '"]').removeClass('is-active'); 754 }); 755 756 if (wasActive) { 757 // Was open, so close it 758 $panel.removeClass('is-active').find('.tabs__panel__content').slideUp(200); 759 $tabs.removeClass('is-active'); 760 } else { 761 // Was closed, so open it 762 $panel.addClass('is-active').find('.tabs__panel__content').slideDown(200); 763 $tabs.removeClass('is-active'); 764 $wrapper.find('.tabs__tab[data-tab="' + index + '"]').addClass('is-active'); 765 } 766 }); 767 768 // Sync state on resize (desktop <-> mobile) 769 var wasMobile = isMobile(); 770 $(window).on('resize', function () { 771 var nowMobile = isMobile(); 772 if (nowMobile !== wasMobile) { 773 wasMobile = nowMobile; 774 775 // Reset inline styles set by slideToggle so CSS controls display again 776 $wrapper.find('.tabs__panel__content').removeAttr('style'); 777 778 var activeIndex = $wrapper.find('.tabs__panel.is-active').data('panel'); 779 if (typeof activeIndex === 'undefined') { 780 activeIndex = 0; 781 } 782 activateTab(activeIndex); 783 } 784 }); 785 }); 786 } 787 788 if ($('.event-gallery.swiper').length) { 789 $('.event-gallery.swiper').each(function () { 790 var $el = $(this); 791 new Swiper(this, { 792 slidesPerView: 1.13, 793 spaceBetween: 16, 794 loop: false, 795 navigation: { 796 nextEl: $el.find('.swiper-button-next')[0], 797 prevEl: $el.find('.swiper-button-prev')[0], 798 }, 799 pagination: { 800 el: $el.find('.swiper-pagination')[0], 801 type: 'progressbar', 802 }, 803 breakpoints: { 804 768: { 805 spaceBetween: 8, 806 slidesPerView: 3, 807 }, 808 1025: { 809 spaceBetween: 8, 810 slidesPerView: 2, 811 }, 812 }, 813 }); 814 }); 815 } 816 817 if ($('.event-related__grid.swiper').length) { 818 $('.event-related__grid.swiper').each(function () { 819 var $el = $(this); 820 new Swiper(this, { 821 slidesPerView: 1.155, 822 spaceBetween: 16, 823 loop: false, 824 navigation: { 825 nextEl: $el.find('.swiper-button-next')[0], 826 prevEl: $el.find('.swiper-button-prev')[0], 827 }, 828 pagination: { 829 el: $el.find('.swiper-pagination')[0], 830 type: 'progressbar', 831 }, 832 breakpoints: { 833 560: { 834 spaceBetween: 16, 835 slidesPerView: 1.7, 836 }, 837 768: { 838 spaceBetween: 16, 839 slidesPerView: 2.2, 840 }, 841 920: { 842 spaceBetween: 16, 843 slidesPerView: 2.6, 844 }, 845 1025: { 846 spaceBetween: 16, 847 slidesPerView: 2, 848 }, 849 1280: { 850 spaceBetween: 16, 851 slidesPerView: 3, 852 }, 853 }, 854 }); 855 }); 856 } 857 858 if ($('.dbg-events-grid').length) { 859 $('.dbg-events-grid').each(function () { 860 var $el = $(this); 861 new Swiper(this, { 862 slidesPerView: 1.155, 863 spaceBetween: 16, 864 loop: false, 865 navigation: { 866 nextEl: $el.find('.swiper-button-next')[0], 867 prevEl: $el.find('.swiper-button-prev')[0], 868 }, 869 pagination: { 870 el: $el.find('.swiper-pagination')[0], 871 type: 'progressbar', 872 }, 873 breakpoints: { 874 560: { 875 spaceBetween: 16, 876 slidesPerView: 1.7, 877 }, 878 768: { 879 spaceBetween: 16, 880 slidesPerView: 3, 881 } 882 }, 883 }); 884 }); 885 } 886 887 if ($('.event-quote__swiper').length) { 888 $('.event-quote__swiper').each(function () { 889 var $el = $(this); 890 new Swiper(this, { 891 slidesPerView: 1, 892 spaceBetween: 20, 893 loop: true, 894 autoplay: { 895 delay: 5000, 896 disableOnInteraction: true, 897 }, 898 navigation: { 899 nextEl: $el.find('.swiper-button-next')[0], 900 prevEl: $el.find('.swiper-button-prev')[0], 901 }, 902 pagination: { 903 el: $el.find('.swiper-pagination')[0], 904 type: 'progressbar', 905 }, 906 }); 907 }); 908 } 909 910 if ($('.faq-accordion').length) { 911 const $faqItems = $('.faq-accordion .faq-item'); 912 913 // Open first item by default 914 $faqItems.first().addClass('active').find('.faq-item__answer').show(); 915 916 $faqItems.find('.faq-item__question').on('click', function () { 917 const $currentItem = $(this).closest('.faq-item'); 918 const $currentAnswer = $currentItem.find('.faq-item__answer'); 919 const isActive = $currentItem.hasClass('active'); 920 921 // Close all items 922 $faqItems.removeClass('active').find('.faq-item__answer').slideUp(300); 923 924 // Open clicked item if it wasn't already active 925 if (!isActive) { 926 $currentItem.addClass('active'); 927 $currentAnswer.slideDown(300); 928 } 929 }); 930 } 931 932 var BREAKPOINT = 1024; 933 934 // matchMedia query â same breakpoint jo CSS use kar raha hai. 935 var mql = window.matchMedia('(max-width: ' + BREAKPOINT + 'px)'); 936 937 function moveGTranslate() { 938 var $widget = $('.gtranslate_wrapper'); 939 var $desktopContainer = $('.desktop_gtranslate_wrap'); 940 var $mobileContainer = $('.mobile_gtranslate_wrap'); 941 942 if ($widget.length && $desktopContainer.length && $mobileContainer.length) { 943 var isMobile = mql.matches; 944 var $target = isMobile ? $mobileContainer : $desktopContainer; 945 946 if (!$widget.parent().is($target)) { 947 $widget.appendTo($target); 948 } 949 } 950 } 951 952 if (mql.addEventListener) { 953 mql.addEventListener('change', moveGTranslate); 954 } else { 955 mql.addListener(moveGTranslate); 956 } 957 958 $(document).ready(moveGTranslate); 959 960 if ($('.dbg-highlights-slider .swiper').length) { 961 962 var $sliderRoot = $('.dbg-highlights-slider'); 963 var $toggleBtn = $sliderRoot.find('.swiper-autoplay-toggle'); 964 var $pauseIcon = $sliderRoot.find('.swiper-autoplay-toggle__pause
964-icon'); 965 var $playIcon = $sliderRoot.find('.swiper-autoplay-toggle__play-icon'); 966 var $liveRegion = $sliderRoot.find('.dbg-highlights-slider__live-region'); 967 968 var swiper = new Swiper('.dbg-highlights-slider .swiper', { 969 slidesPerView: 1.155, 970 spaceBetween: 16, 971 loop: false, 972 // autoplay: { 973 // delay: 5000, 974 // disableOnInteraction: true, 975 // }, 976 a11y: { 977 enabled: true, 978 prevSlideMessage: 'Previous slide', 979 nextSlideMessage: 'Next slide', 980 }, 981 keyboard: { 982 enabled: true, 983 }, 984 navigation: { 985 nextEl: '.dbg-highlights-slider .swiper-button-next', 986 prevEl: '.dbg-highlights-slider .swiper-button-prev', 987 }, 988 pagination: { 989 el: '.dbg-highlights-slider .swiper-pagination', 990 clickable: true, 991 type: 'progressbar', 992 }, 993 breakpoints: { 994 450: { slidesPerView: 1.7 }, 995 520: { slidesPerView: 2.1 }, 996 620: { slidesPerView: 2.5 }, 997 768: { slidesPerView: 3 }, 998 1025: { slidesPerView: 4, spaceBetween: 24 }, 999 1280: { slidesPerView: 5, spaceBetween: 24 }, 1000 }, 1001 }); 1002 1003 // WCAG 2.2.2 Pause, Stop, Hide â autoplay must be pausable. 1004 $toggleBtn.on('click', function () { 1005 var isPlaying = swiper.autoplay.running; 1006 1007 if (isPlaying) { 1008 swiper.autoplay.stop(); 1009 $pauseIcon.attr('hidden', true); 1010 $playIcon.removeAttr('hidden'); 1011 $toggleBtn.attr('aria-label', 'Play automatic slide rotation'); 1012 $liveRegion.text('Slide rotation paused.'); 1013 } else { 1014 swiper.autoplay.start(); 1015 $playIcon.attr('hidden', true); 1016 $pauseIcon.removeAttr('hidden'); 1017 $toggleBtn.attr('aria-label', 'Pause automatic slide rotation'); 1018 $liveRegion.text('Slide rotation resumed.'); 1019 } 1020 }); 1021 1022 // Prev/Next are divs with role="button" â native keydown activation 1023 // (Enter/Space) is required for keyboard-only users (WCAG 2.1.1). 1024 $sliderRoot.find('.swiper-button-prev, .swiper-button-next').on('keydown', function (e) { 1025 if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') { 1026 e.preventDefault(); 1027 $(this).trigger('click'); 1028 } 1029 }); 1030 1031 // Pause autoplay whenever focus enters the slider (keyboard nav, 1032 // screen readers) â matches the hover-pause behavior sighted 1033 // mouse users already get from disableOnInteraction. 1034 $sliderRoot.on('focusin', function () { 1035 swiper.autoplay.stop(); 1036 $pauseIcon.attr('hidden', true); 1037 $playIcon.removeAttr('hidden'); 1038 $toggleBtn.attr('aria-label', 'Play automatic slide rotation'); 1039 }); 1040 } 1041 1042 // ADA for Language dropdown (GTranslate custom select: .styledSelect + ul.options) 1043 const wrapSel = '.gtranslate_wrapper .gt_selector'; 1044 const btnSel = wrapSel + ' .styledSelect'; 1045 const listSel = wrapSel + ' ul.options'; 1046 const itemSel = listSel + ' li'; 1047 1048 function isOpen($list) { 1049 return $list.css('display') !== 'none'; 1050 } 1051 function setupA11y() { 1052 $(btnSel).attr({ 1053 role: 'button', 1054 tabindex: '0', 1055 'aria-haspopup': 'listbox', 1056 'aria-expanded': isOpen($(listSel).first()) ? 'true' : 'false' 1057 }); 1058 $(listSel).attr({ role: 'listbox', 'aria-label': 'Language options' }); 1059 $(itemSel).each(function () { 1060 $(this).attr({ 1061 role: 'option', 1062 tabindex: '-1', 1063 'aria-selected': $(this).hasClass('active') ? 'true' : 'false' 1064 }); 1065 }); 1066 } 1067 1068 function closeList($wrap) { 1069 const $list = $wrap.find('ul.options'); 1070 if (isOpen($list)) { 1071 $wrap.find('.styledSelect').trigger('click'); // plugin ka apna toggle use hoga 1072 } 1073 } 1074 1075 function focusActiveItem($wrap) { 1076 setTimeout(function () { 1077 const $items = $wrap.find('ul.options li'); 1078 const $target = $items.filter('.active').first(); 1079 ($target.length ? $target : $items.first()).focus(); 1080 }, 50); 1081 } 1082 1083 setupA11y(); 1084 1085 // aria-expanded / aria-selected ko sync rakho (mouse + keyboard dono) 1086 $(listSel).each(function () { 1087 const $list = $(this); 1088 new MutationObserver(function () { 1089 $list.closest('.gt_selector').find('.styledSelect') 1090 .attr('aria-expanded', isOpen($list) ? 'true' : 'false'); 1091 $list.find('li').each(function () { 1092 $(this).attr('aria-selected', $(this).hasClass('active') ? 'true' : 'false'); 1093 }); 1094 }).observe(this, { attributes: true, attributeFilter: ['style'], subtree: true });
1095 }); 1096 1097 // Button: Enter / Space / ArrowDown 1098 $(document).on('keydown', btnSel, function (e) { 1099 const $wrap = $(this).closest('.gt_selector'); 1100 const $list = $wrap.find('ul.options'); 1101 1102 if (e.key === 'Enter' || e.key === ' ') { 1103 e.preventDefault(); 1104 $(this).trigger('click'); 1105 if (isOpen($list)) focusActiveItem($wrap); // open hua to hi focus move karo 1106 } else if (e.key === 'ArrowDown') { 1107 e.preventDefault(); 1108 if (!isOpen($list)) $(this).trigger('click'); 1109 focusActiveItem($wrap); 1110 } 1111 }); 1112 1113 // Options: Arrow keys, Home/End, Enter/Space, Tab 1114 $(document).on('keydown', itemSel, function (e) { 1115 const $item = $(this); 1116 const $wrap = $item.closest('.gt_selector'); 1117 const $items = $wrap.find('ul.options li'); 1118 const index = $items.index($item); 1119 1120 switch (e.key) { 1121 case 'ArrowDown': 1122 e.preventDefault(); 1123 $items.eq((index + 1) % $items.length).focus(); 1124 break; 1125 case 'ArrowUp': 1126 e.preventDefault(); 1127 $items.eq((index - 1 + $items.length) % $items.length).focus(); 1128 break; 1129 case 'Home': 1130 e.preventDefault(); 1131 $items.first().focus(); 1132 break; 1133 case 'End': 1134 e.preventDefault(); 1135 $items.last().focus(); 1136 break; 1137 case 'Enter': 1138 case ' ': 1139 e.preventDefault(); 1140 $item.trigger('click'); // plugin language change handle karega 1141 break; 1142 case 'Tab': 1143 closeList($wrap); 1144 break; 1145 } 1146 }); 1147 1148 // Escape (global): dropdown band, agar focus dropdown ke andar tha to button par wapas 1149 $(document).on('keydown', function (e) { 1150 if (e.key !== 'Escape') return; 1151 $(wrapSel).each(function () { 1152 const $wrap = $(this); 1153 const focusInside = $wrap.has(document.activeElement).length > 0; 1154 closeList($wrap); 1155 if (focusInside) $wrap.find('.styledSelect').focus(); 1156 }); 1157 }); 1158 1159 // ADA for Language dropdown ended 1160 1161 }); // Ready Ends 1162 1163 // $('.text-link.more-btn, .arrow-btn .elementor-button').html(function () { 1164 // var text = $(this).text().split(' '); 1165 // var last = (text.pop()).trim(); 1166 // var rest = text.join(' '); 1167 // return (rest ? rest + ' ' : '') + '<span class="last">' + last + '</span>'; 1168 // }); 1169 // ---------- Arrow/more-btn text wrapping ---------- 1170 function wrapLastWord() { 1171 $('.text-link.more-btn, .arrow-btn .elementor-button').each(function () { 1172 var $el = $(this); 1173 1174 // Skip if already wrapped, avoid double-wrapping on repeated calls 1175 if ($el.find('> span.last').length) { 1176 return; 1177 } 1178 1179 var text = $el.text().trim().split(' '); 1180 var last = (text.pop() || '').trim(); 1181 var rest = text.join(' '); 1182 $el.html((rest ? rest + ' ' : '') + '<span class="last">' + last + '</span>'); 1183 }); 1184 } 1185 1186 wrapLastWord(); 1187 1188 // ---------- Tribe Events search clear button ---------- 1189 function toggleClearButton($wrapper) { 1190 var input = $wrapper.find('.tribe-events-c-search__input'); 1191 var clearButton = $wrapper.find('.tribe-events-c-search__input-control-clear'); 1192 clearButton.toggleClass('is-visible', input.val().length > 0); 1193 } 1194 1195 function initClearButtons() { 1196 $('.tribe-events-c-search__input-control').each(function () { 1197 toggleClearButton($(this)); 1198 }); 1199 } 1200 1201 initClearButtons(); 1202 1203 // Delegated: survives DOM replacement, no rebinding needed 1204 $(document).on('input', '.tribe-events-c-search__input-control .tribe-events-c-search__input', function () { 1205 toggleClearButton($(this).closest('.tribe-events-c-search__input-control')); 1206 }); 1207 1208 $(document).on('click', '.tribe-events-c-search__input-control-clear', function () { 1209 var $wrapper = $(this).closest('.tribe-events-c-search__input-control'); 1210 var input = $wrapper.find('.tribe-events-c-search__input'); 1211 1212 input.val('').trigger('input').focus(); 1213 toggleClearButton($wrapper); 1214 1215 input.closest('form').trigger('submit'); 1216 }); 1217 1218 // ---------- Re-run after Tribe Events AJAX filter/pagination ---------- 1219 $(document).on('afterAjaxSuccess.tribeEvents', function () { 1220 wrapLastWord(); 1221 initClearButtons(); 1222 }); 1223 1224 // "Back" button (Elementor .back_btn) goes to the last FacetWP listing URL captured below, 1225 // instead of its static href - so it lands on the exact page/pagination the user came from. 1226 $(document).on('click', '.back_btn a', function (e) { 1227 var lastListingUrl = sessionStorage.getItem('dbg_last_listing_url'); 1228 1229 if (lastListingUrl) { 1230 e.preventDefault(); 1231 window.location.href = lastListingUrl; 1232 } 1233 }); 1234 1235 /*Toggle menu on mobile*/ 1236 $('.mobile-toggle-btn .elementor-icon').on('click', function () { 1237 $('body').toggleClass('mobile-menu-open'); 1238 $('.mobile-meun-wrapper').slideToggle(); 1239 }); 1240 1241 //window resize and load function 1242 $(window).on('resize load', function () { 1243 1244 }); 1245 1246 $(window).on('elementor/frontend/init', function () { 1247 setTimeout(function () { 1248 1249 $('.background-carousel').each(function () { 1250 var $sliderWrapper = $(this); 1251 if (!$sliderWrapper.find('.swiper-controllers').length) { 1252 $sliderWrapper 1253 .find('.swiper-pagination, .elementor-swiper-button')
1254 .wrapAll('<div class="slider-controls"></div>'); 1255 } 1256 }); 1257 1258 $('.testimonial_slider').each(function () { 1259 var $sliderWrapper = $(this); 1260 var sliderEl = $sliderWrapper.find('.swiper')[0]; 1261 if (!sliderEl) return; 1262 // Destroy Elementor's existing Swiper instance 1263 var existingInstance = sliderEl.swiper; 1264 if (existingInstance) { 1265 existingInstance.destroy(true, true); 1266 } 1267 // Wrap controllers only once 1268 if (!$sliderWrapper.find('.swiper-controllers').length) { 1269 $sliderWrapper 1270 .find('.swiper-pagination, .elementor-swiper-button') 1271 .wrapAll('<div class="swiper-controllers"></div>'); 1272 } 1273 // Get controls for this specific slider 1274 var paginationEl = $sliderWrapper.find('.swiper-pagination')[0]; 1275 var nextEl = $sliderWrapper.find('.elementor-swiper-button-next')[0]; 1276 var prevEl = $sliderWrapper.find('.elementor-swiper-button-prev')[0]; 1277 // Initialize this specific slider 1278 new Swiper(sliderEl, { 1279 slidesPerView: 1.001, 1280 slidesPerGroup: 1, 1281 spaceBetween: 16, 1282 loop: true, 1283 grabCursor: true, 1284 1285 pagination: { 1286 el: paginationEl, 1287 type: 'progressbar', 1288 clickable: true, 1289 }, 1290 1291 navigation: { 1292 nextEl: nextEl, 1293 prevEl: prevEl, 1294 }, 1295 1296 breakpoints: { 1297 1025: { 1298 slidesPerView: 2.001, 1299 spaceBetween: 24, 1300 } 1301 } 1302 }); 1303 }); 1304 1305 $('.hero_section_slideshow').each(function () { 1306 var $section = $(this); 1307 var sliderEl = $section.find('.elementor-background-slideshow')[0]; 1308 1309 if (!sliderEl || !sliderEl.swiper) return; 1310 1311 var swiperInstance = sliderEl.swiper; 1312 1313 // Buttons sirf ek baar append hon 1314 if (!$section.children('.e-con-inner').find('.slider-controls').length) { 1315 $section.children('.e-con-inner').append(` 1316 <div class="slider-controls"> 1317 <div class="swiper-pagination"></div> 1318 <div class="swiper-button-prev" tabindex="0" role="button" aria-label="Previous slide"> 1319 <svg width="10" height="16" viewBox="0 0 10 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="none"> 1320 <path d="M0.421875 7.17188L7.17188 0.421875C7.62891 0 8.33203 0 8.78906 0.421875C9.21094 0.878906 9.21094 1.58203 8.78906 2.03906L2.8125 7.98047L8.78906 13.9219C9.21094 14.3789 9.21094 15.082 8.78906 15.5391C8.33203 15.9609 7.62891 15.9609 7.17188 15.5391L0.421875 8.78906C0 8.33203 0 7.62891 0.421875 7.17188Z" fill="#5C5849"></path> 1321 </svg> 1322 </div> 1323 <div class="swiper-button-next" tabindex="0" role="button" aria-label="Next slide"> 1324 <svg width="10" height="16" viewBox="0 0 10 16" fill="none" xmlns="http://www.w3.org/2000/svg" role="none"> 1325 <path d="M8.78906 7.17188C9.24609 7.62891 9.24609 8.33203 8.78906 8.78906L2.03906 15.5391C1.61719 15.9609 0.878906 15.9609 0.457031 15.5391C0 15.082 0 14.3789 0.457031 13.9219L6.39844 7.98047L0.457031 2.03906C0 1.58203 0 0.878906 0.457031 0.421875C0.878906 0 1.61719 0 2.03906 0.421875L8.78906 7.17188Z" fill="#5C5849"></path> 1326 </svg> 1327 </div> 1328 </div> 1329 `); 1330 } 1331 1332 var prevEl = $section.find('.swiper-button-prev')[0]; 1333 var nextEl = $section.find('.swiper-button-next')[0]; 1334 var paginationEl = $section.find('.swiper-pagination')[0]; 1335 1336 // Navigation module ko dynamically enable/hook karo (merge, replace nahi) 1337 if (!swiperInstance.params.navigation || swiperInstance.params.navigation === false) { 1338 swiperInstance.params.navigation = {}; 1339 } 1340 Object.assign(swiperInstance.params.navigation, { 1341 nextEl: nextEl, 1342 prevEl: prevEl, 1343 }); 1344 swiperInstance.navigation.init(); 1345 swiperInstance.navigation.update(); 1346 1347 // Pagination module ko dynamically enable/hook karo (progressbar type) 1348 if (!swiperInstance.params.pagination || swiperInstance.params.pagination === false) { 1349 swiperInstance.params.pagination = {}; 1350 } 1351 Object.assign(swiperInstance.params.pagination, { 1352 el: paginationEl, 1353 type: 'progressbar', 1354 clickable: false, 1355 }); 1356 swiperInstance.pagination.init(); 1357 swiperInstance.pagination.render(); 1358 swiperInstance.pagination.update(); 1359 1360 // Arrow click par autoplay permanently pause na ho 1361 if (swiperInstance.params.autoplay) { 1362 swiperInstance.params.autoplay.disableOnInteraction = false; 1363 } 1364 }); 1365 }, 3000); 1366 }); 1367 1368 function setHeaderOffset() { 1369 var nav_bar_height = $('[data-elementor-type="header"]').outerHeight() || 0;
1370 var h = $('[data-elementor-type="header"]').outerHeight() + adminbar || 0; 1371 document.documentElement.style.setProperty('--header-offset', h + 'px'); 1372 } 1373 1374 setHeaderOffset(); 1375 $(window).on('resize', setHeaderOffset); 1376 1377 1378 1379 1380 var pendingTabScroll = false; 1381 var tabScrollTimer = null; 1382 1383 function scrollToTabsTopOnAjax() { 1384 // console.log('[scrollToTabsTopOnAjax] Function called'); 1385 1386 if (!window.matchMedia('(max-width: 1023px)').matches) { 1387 // console.log('[scrollToTabsTopOnAjax] Skipped - not mobile/tablet viewport (width > 1023px)'); 1388 return; 1389 } 1390 1391 // console.log('[scrollToTabsTopOnAjax] Mobile viewport detected, proceeding...'); 1392 1393 clearInterval(tabScrollTimer); 1394 1395 var tries = 0; 1396 1397 tabScrollTimer = setInterval(function () { 1398 tries++; 1399 1400 // Har selector ko alag se check karo taake pata chale konsa miss ho raha hai 1401 var $list = $('.tribe-events-calendar-list'); 1402 var $photo = $('.tribe-events-pro-photo'); 1403 var $month = $('.tribe-events-calendar-month'); 1404 1405 // console.log( 1406 // '[scrollToTabsTopOnAjax] Attempt #' + tries + 1407 // ' | list: ' + ($list.length ? 'FOUND' : 'not found') + 1408 // ' | photo: ' + ($photo.length ? 'FOUND' : 'not found') + 1409 // ' | month: ' + ($month.length ? 'FOUND' : 'not found') 1410 // ); 1411 1412 var $target = $list.add($photo).add($month).first(); 1413 1414 if (!$target.length && tries < 30) { 1415 // console.log('[scrollToTabsTopOnAjax] None of the 3 selectors matched yet, retrying...'); 1416 return; 1417 } 1418 1419 clearInterval(tabScrollTimer); 1420 1421 if (!$target.length) { 1422 // console.log('[scrollToTabsTopOnAjax] Primary target not found after ' + tries + ' tries. Falling back to .tribe-events-view'); 1423 $target = $('.tribe-events-view').first(); 1424 } 1425 // else { 1426 // console.log('[scrollToTabsTopOnAjax] Target found:', $target.get(0), '| matched class:', $target.attr('class')); 1427 // } 1428 1429 if (!$target.length) { 1430 // console.log('[scrollToTabsTopOnAjax] No target found at all (including fallback). Aborting scroll.'); 1431 return; 1432 } 1433 1434 var tribe_events_header = $('.tribe-events-header').outerHeight() || 0; 1435 // console.log('[scrollToTabsTopOnAjax] tribe_events_header height:', tribe_events_header); 1436 1437 var headerOffset = parseInt( 1438 getComputedStyle(document.documentElement).getPropertyValue('--header-offset') 1439 ) || 0; 1440 // console.log('[scrollToTabsTopOnAjax] headerOffset (--header-offset):', headerOffset); 1441 1442 var offset = headerOffset + tribe_events_header; 1443 var targetTop = $target.offset().top - offset; 1444 1445 // console.log('[scrollToTabsTopOnAjax] Calculated offset:', offset); 1446 // console.log('[scrollToTabsTopOnAjax] $target.offset().top:', $target.offset().top); 1447 // console.log('[scrollToTabsTopOnAjax] Final targetTop (scroll position):', targetTop); 1448 1449 $('html, body').stop(true, true).animate({ scrollTop: targetTop }, 300, function () { 1450 // console.log('[scrollToTabsTopOnAjax] Scroll animation completed'); 1451 }); 1452 }, 100); 1453 } 1454 1455 $(document).on('click', '.tribe-events-c-events-bar__views-list a, .tribe-events-c-nav__next, .tribe-events-c-nav__prev, .tribe-events-calendar-list__event-datetime-yearmonth, [data-js="tribe-events-view-link"]', function () { 1456 pendingTabScroll = true; 1457 setTimeout(function () { pendingTabScroll = false; }, 6000); // safety reset if ajax error/abort 1458 }); 1459 1460 document.addEventListener('containerReplaceAfter.tribeEvents', function () { 1461 // setupMoreEvents(); 1462 1463 if (pendingTabScroll) { 1464 pendingTabScroll = false; 1465 scrollToTabsTopOnAjax(); 1466 } 1467 }); 1468 1469 1470 1471 1472 $(document).on('click', '.menu-item.not_clickable > a', function (e) { 1473 e.preventDefault(); 1474 }); 1475 1476 // Recalculate when GTranslate swaps content inside header 1477 var headerEl = document.querySelector('[data-elementor-type="header"]'); 1478 1479 if (headerEl) { 1480 var debounceTimer; 1481 var observer = new MutationObserver(function () { 1482 clearTimeout(debounceTimer); 1483 debounceTimer = setTimeout(setHeaderOffset, 150); 1484 }); 1485 1486 observer.observe(headerEl, { 1487 childList: true, 1488 subtree: true, 1489 characterData: true 1490 }); 1491 } 1492 1493 // Hide info bar on close click and recalc header offset 1494 $(document).on('click', '.info_close_wrap', function () { 1495 var $infoBar = $('.header_info_bar'); 1496 1497 $infoBar.slideUp(200, function () { 1498 // Recalculate only after the bar has actually collapsed from the DOM flow 1499 setHeaderOffset(); 1500 }); 1501 }); 1502 1503 /** 1504 * The responsive pagination for FacetWP's Pager JS. 1505 * */ 1506 function dbg_pagination(mb_limit, mb_endpoints_limit, dk_limit, dk_endpoints_limit) { 1507 // target container 1508 let container = '.facetwp-pager'; 1509 // exist if facetwp not on the page 1510 if (!$(container).length) { 1511 return; 1512 } 1513 let mb_hide_class = 'dbg-hide-page-mb'; 1514 let dk_hide_class = 'dbg-hide-page-dk'; 1515 // dots markup 1516 let dots_start = '<a role="none" class="facetwp-page dots start ' + mb_hide_class + ' ' + dk_hide_class + '">...</a>'; 1517 let dots_end = '<a role="none" class="facetwp-page dots end ' + mb_hide_class + ' ' + dk_hide_class + '">...</a>'; 1518 // ---------------------------------------------------- 1519 let total_pages = parseInt($(container + ' a.facetwp-page.last').attr('data-page')); 1520 let active_page = parseInt($(container + ' a.facetwp-page.active').attr('data-page')); 1521 // check if the current page is an endpoint 1522 let is_endpoint_page = (active_page === 1 || active_page === total_pages) ? true : false; 1523 let mb_range_start = is_endpoint_page ? active_page - mb_endpoints_limit : active_page - mb_limit; 1524 let mb_range_end = is_endpoint_page ? active_page + mb_endpoints_limit : active_page + mb_limit; 1525 let dk_range_start = is_endpoint_page ? active_page - dk_endpoints_limit : active_page - dk_limit; 1526 let dk_range_end = is_endpoint_page ? active_page + dk_endpoints_limit : active_page + dk_limit; 1527 let dots_mb_start, dots_mb_end, dots_dk_start, dots_dk_end = false; 1528 // ---------------------------------------------------- 1529 $(container + ' .dots').remove(); 1530 $(container + ' a.facetwp-page:not(.prev, .next)').removeClass(mb_hide_class + ' ' + dk_hide_class); 1531 // loop over all the page numbers, excluding 'previous' and 'next' elements 1532 $(container + ' a.facetwp-page:not(.active, .prev, .next, [data-page="1"], [data-page="' + total_pages + '"])').each(function (i, obj) { 1533 let current_page = $(this).attr('data-page'); 1534 if (current_page < mb_range_start) { 1535 $(this).addClass(mb_hide_class); 1536 dots_mb_start = true; 1537 } 1538 if (current_page > mb_range_end) { 1539 $(this).addClass(mb_hide_class); 1540 dots_mb_end = true; 1541 } 1542 if (current_page < dk_range_start) { 1543 $(this).addClass(dk_hide_class); 1544 dots_dk_start = true; 1545 } 1546 if (current_page > dk_range_end) { 1547 $(this).addClass(dk_hide_class); 1548 dots_dk_end = true; 1549 } 1550 }); 1551 1552 // add dots element - start 1553 if (dots_mb_start || dots_dk_start) { 1554 $(container + ' a.facetwp-page[data-page="1"]').after(dots_start); 1555 if (dots_mb_start) { 1556 $(container + ' .dots.start').removeClass(mb_hide_class); 1557 } 1558 if (dots_dk_start) { 1559 $(container + ' .dots.start').removeClass(dk_hide_class); 1560 } 1561 } 1562 1563 // add dots element - end 1564 if (dots_mb_end || dots_dk_end) { 1565 $(container + ' a.facetwp-page[data-page="' + total_pages + '"]').before(dots_end); 1566 if (dots_mb_end) { 1567 $(container + ' .dots.end').removeClass(mb_hide_class); 1568 } 1569 if (dots_dk_end) { 1570 $(container + ' .dots.end').removeClass(dk_hide_class); 1571 } 1572 } 1573 active_page = active_page ? active_page : 1; 1574 total_pages = total_pages ? total_pages : 1; 1575 $('.ih-total-page-counter span.ih-current-page').html(active_page); 1576 $('.ih-total-page-counter span.ih-total-page').html(total_pages); 1577 }
1578 // Update the pagination responsively. 1579 function dbg_responsive_pagination() { 1580 1581 if (window.innerWidth < 480) { 1582 dbg_pagination(0, 0, 0, 0); 1583 } 1584 // Check if the screen size is between 400 and 767 pixels 1585 else if (window.innerWidth >= 481 && window.innerWidth <= 767) { 1586 dbg_pagination(1, 1, 1, 1); 1587 1588 } 1589 // Check if the screen size is bigger than 767 pixels 1590 else { 1591 dbg_pagination(1, 1, 1, 2); 1592 } 1593 } 1594 1595 $(document).on('facetwp-loaded', function () { 1596 // FacetWP paginates via AJAX, so the browser history entry for e.g. ?_paged=2 isn't reliable 1597 // to navigate back to (no full page load happened for it). Capture the live URL FacetWP has 1598 // already resolved to instead, for the Elementor "back" button above to use. 1599 // Blog archive only - other FacetWP listings (e.g. search results) shouldn't feed this. 1600 if (window.location.pathname.indexOf('/blog/') === 0) { 1601 sessionStorage.setItem('dbg_last_listing_url', window.location.href); 1602 } 1603 1604 if (FWP.loaded) { 1605 if ($('.facetwp-scroll-top').length) { 1606 $('html,body').animate({ 1607 scrollTop: $('.facetwp-scroll-top').offset().top - $('.elementor-location-header').height() + 10 1608 }); 1609 } 1610 } 1611 1612 // Facet Scroll to Top Code on Refresh 1613 if (FWP.enable_scroll == true) { 1614 var topbar = 0; 1615 if ($('html #wpadminbar').length > 0) { 1616 topbar = $('html #wpadminbar').height(); 1617 } 1618 $('html,body').animate({ 1619 scrollTop: $('.facetwp-scroll-top').offset().top - $('.elementor-location-header').height() - topbar 1620 }); 1621 } 1622 1623 dbg_responsive_pagination(); 1624 }); 1625 1626 function checkScroll() { 1627 if ($(window).scrollTop() > 0) { 1628 $('body').addClass('has-scrolled'); 1629 } else { 1630 $('body').removeClass('has-scrolled'); 1631 } 1632 } 1633 // Run on page load 1634 checkScroll(); 1635 // Run on scroll 1636 $(window).on('scroll', checkScroll); 1637 1638 1639 // ---------- Datepicker enhancement ---------- 1640 function enhanceDatepicker() { 1641 var $dp = $('.datepicker-dropdown').filter(function () { 1642 return $(this).find('.dbg-datepicker-header').length === 0; 1643 }); 1644 if (!$dp.length) { 1645 return; 1646 } 1647 1648 var $header = $( 1649 '<div class="dbg-datepicker-header">' + 1650 '<span class="dbg-datepicker-title">Select a date</span>' + 1651 '<button type="button" class="dbg-datepicker-close" aria-label="Close">' + 1652 '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">' + 1653 '<path d="M0.351562 1.51172C0 1.19531 0 0.632812 0.351562 0.316406C0.667969 0 1.19531 0 1.51172 0.316406L6.82031 5.625L12.1289 0.316406C12.4805 0 13.0078 0 13.3242 0.316406C13.6758 0.667969 13.6758 1.19531 13.3242 1.51172L8.01562 6.82031L13.3242 12.1289C13.6758 12.4453 13.6758 13.0078 13.3242 13.3242C13.0078 13.6406 12.4805 13.6406 12.1289 13.3242L6.82031 8.01562L1.51172 13.3242C1.19531 13.6406 0.667969 13.6406 0.351562 13.3242C0 13.0078 0 12.4453 0.351562 12.1289L5.66016 6.82031L0.351562 1.51172Z" fill="#383B17"/>' + 1654 '</svg>' + 1655 '</button>' + 1656 '</div>' 1657 ); 1658 $dp.prepend($header); 1659 1660 $header.find('.dbg-datepicker-close').on('click', function () { 1661 $('.tribe-events-c-top-bar__datepicker-button').trigger('click'); 1662 }); 1663 1664 var $footer = $( 1665 '<div class="dbg-datepicker-footer">' + 1666 // '<button type="button" class="dbg-datepicker-show"></button>' + 1667 '<a href="#" class="dbg-datepicker-clear">' + 1668 '<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">' + 1669 '<path d="M1.28906 0.28125L4.52344 3.51562L7.73438 0.28125C8.01562 0 8.50781 0 8.78906 0.28125C9.09375 0.585938 9.09375 1.05469 8.78906 1.35938L5.57812 4.57031L8.78906 7.78125C9.09375 8.08594 9.09375 8.55469 8.78906 8.85938C8.50781 9.14062 8.01562 9.14062 7.73438 8.85938L4.52344 5.625L1.28906 8.85938C1.00781 9.14062 0.515625 9.14062 0.234375 8.85938C-0.0703125 8.55469 -0.0703125 8.08594 0.234375 7.78125L3.44531 4.57031L0.234375 1.35938C-0.0703125 1.05469 -0.0703125 0.585938 0.234375 0.28125C0.515625 0 1.00781 0 1.28906 0.28125Z" fill="#576414"/>' + 1670 '</svg>' + 1671 'Clear Date' + 1672 '</a>' + 1673 '</div>' 1674 ); 1675 $dp.append($footer); 1676 1677 function shortLabel() { 1678 var $active = $dp.find('.datepicker-days .day.active').first(); 1679 if (!$active.length) { 1680 return 'Today'; 1681 } 1682 var d = new Date(parseInt($active.attr('data-date'), 10)); 1683 return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
1684 } 1685 1686 // function updateShowText() { 1687 // $footer.find('.dbg-datepicker-show').text('Show ' + shortLabel()); 1688 // } 1689 // updateShowText(); 1690 1691 $dp.on('click', '.day', function () { 1692 setTimeout(updateShowText, 0); 1693 }); 1694 1695 // $footer.find('.dbg-datepicker-show').on('click', function () { 1696 // $('.tribe-events-c-top-bar__datepicker-button').trigger('click'); 1697 // }); 1698 1699 $footer.find('.dbg-datepicker-clear').on('click', function (e) { 1700 e.preventDefault(); 1701 var todayHref = $('.tribe-events-c-top-bar__today-button').attr('href'); 1702 if (todayHref) { 1703 window.location.href = todayHref; 1704 } 1705 }); 1706 1707 } 1708 1709 var datepickerObserver = new MutationObserver(enhanceDatepicker); 1710 datepickerObserver.observe(document.body, { childList: true, subtree: true }); 1711 1712 $(document).on('click', '.tribe-events-c-top-bar__datepicker-button', function () { 1713 setTimeout(enhanceDatepicker, 0); 1714 setTimeout(enhanceDatepicker, 100); 1715 }); 1716 1717 // ---------- "+more" events toggle ---------- 1718 var EVENTS_THRESHOLD = 5; 1719 1720 function setupMoreEvents() { 1721 $('.tribe-events-calendar-month__events').not('[data-dbg-more-done]').each(function () { 1722 var $container = $(this); 1723 var $events = $container.children('.tribe-events-calendar-month__calendar-event'); 1724 1725 $container.attr('data-dbg-more-done', 'true'); 1726 1727 if ($events.length <= EVENTS_THRESHOLD) { 1728 return; 1729 } 1730 1731 var $hidden = $events.slice(EVENTS_THRESHOLD).addClass('dbg-event-hidden'); 1732 var hiddenCount = $hidden.length; 1733 1734 var $toggle = $( 1735 '<button type="button" class="dbg-events-more-toggle">' + 1736 '<span class="dbg-events-more-text">+' + hiddenCount + ' more</span>' + 1737 '<span class="dbg-events-more-icon">' + 1738 '<svg width="11" height="6" viewBox="0 0 11 6" fill="none" xmlns="http://www.w3.org/2000/svg">' + 1739 '<path d="M4.92188 5.69531L0.234375 1.00781C0 0.796875 0 0.445312 0.234375 0.210938C0.445312 0 0.796875 0 1.03125 0.210938L5.32031 4.5L9.60938 0.210938C9.82031 0 10.1719 0 10.3828 0.210938C10.6172 0.421875 10.6172 0.796875 10.3828 1.00781L5.69531 5.69531C5.48438 5.90625 5.13281 5.90625 4.92188 5.69531Z" fill="#576414"/>' + 1740 '</svg>' + 1741 '</span>' + 1742 '</button>' 1743 ); 1744 1745 $container.append($toggle); 1746 1747 $toggle.on('click', function () { 1748 var isOpen = $container.hasClass('dbg-events-expanded'); 1749 1750 if (isOpen) { 1751 $hidden.addClass('dbg-event-hidden'); 1752 $container.removeClass('dbg-events-expanded'); 1753 $toggle.find('.dbg-events-more-text').text('+' + hiddenCount + ' more'); 1754 } else { 1755 $hidden.removeClass('dbg-event-hidden'); 1756 $container.addClass('dbg-events-expanded'); 1757 $toggle.find('.dbg-events-more-text').text('Show less'); 1758 } 1759 }); 1760 }); 1761 } 1762 1763 setupMoreEvents(); 1764 1765 $(document).on('ajaxComplete', function () { 1766 setupMoreEvents(); 1767 scrollToTabsTopOnAjax(); 1768 }); 1769 1770 var moreEventsObserver = new MutationObserver(function () { 1771 setupMoreEvents(); 1772 }); 1773 moreEventsObserver.observe(document.body, { childList: true, subtree: true }); 1774 1775 function addCloseButtonToHeading() { 1776 var $heading = $('.tribe-filter-bar__form-heading').not('[data-dbg-close-added]'); 1777 if (!$heading.length) { 1778 return; 1779 } 1780 $heading.attr('data-dbg-close-added', 'true'); 1781 1782 var $closeBtn = $( 1783 '<button type="button" class="dbg-filter-bar-close" aria-label="Close">' + 1784 '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">' + 1785 '<path d="M2.26562 0.46875L7.65625 5.85938L13.0078 0.46875C13.4766 0 14.2969 0 14.7656 0.46875C15.2734 0.976562 15.2734 1.75781 14.7656 2.26562L9.41406 7.61719L14.7656 12.9688C15.2734 13.4766 15.2734 14.2578 14.7656 14.7656C14.2969 15.2344 13.4766 15.2344 13.0078 14.7656L7.65625 9.375L2.26562 14.7656C1.79688 15.2344 0.976562 15.2344 0.507812 14.7656C0 14.2578 0 13.4766 0.507812 12.9688L5.85938 7.61719L0.507812 2.26562C0 1.75781 0 0.976562 0.507812 0.46875C0.976562 0 1.79688 0 2.26562 0.46875Z" fill="#383B17"/>' + 1786 '</svg>' + 1787 '</button>' 1788 ); 1789 $heading.append($closeBtn); 1790 1791 $closeBtn.on('click', function () { 1792 $('.tribe-filter-bar__action-done').trigger('click'); 1793 }); 1794 } 1795 1796 addCloseButtonToHeading(); 1797 1798 var closeButtonObserver = new MutationObserver(addCloseButtonToHeading); 1799 closeButtonObserver.observe(document.body, { childList: true, subtree: true });
1800 1801 // Caps the Month and List views' "Jump to" datepicker dropdown to one year back/forward 1802 // from today - the plugin's own datepicker.js sets no min/max bounds by default, so 1803 // without this it lets you pick literally any date. The Month view's prev/next arrows are 1804 // already capped server-side, see dbg_limit_month_view_nav_range() in includes/wp-hooks.php. 1805 // Re-fires on every AJAX view update since the plugin re-triggers this same event each time 1806 // it re-inits the datepicker. 1807 $(document).on('afterDatepickerInit.tribeEvents', function (event, index, $container, data) { 1808 if (!data || ('month' !== data.slug && 'list' !== data.slug)) { 1809 return; 1810 } 1811 1812 var $input = $container.find('[data-js="tribe-events-top-bar-date"]'); 1813 1814 if (!$input.length) { 1815 return; 1816 } 1817 1818 var today = new Date(); 1819 var minDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); 1820 var maxDate = new Date(today.getFullYear() + 1, today.getMonth(), today.getDate()); 1821 1822 $input.bootstrapDatepicker('setStartDate', minDate); 1823 $input.bootstrapDatepicker('setEndDate', maxDate); 1824 }); 1825 1826 // Code for main role 1827 $('main').attr({ 1828 "id": "main" 1829 }); 1830 1831 $('svg').attr('role', 'none'); 1832 1833 var target = document.querySelector('.elementor-element-b19dce6'); 1834 1835 if (target) { 1836 var fixGallery = function () { 1837 $('.cr__grid[role="region"]').removeAttr('role').removeAttr('aria-label'); 1838 }; 1839 1840 // Pehli dafa chalao 1841 fixGallery(); 1842 1843 // Crowdriff async load hota hai, isliye naya markup aane par dobara chalao 1844 var observer = new MutationObserver(fixGallery); 1845 observer.observe(target, { childList: true, subtree: true }); 1846 } 1847 1848 var $main = $('main#main'); 1849 1850 if ($main.length) { 1851 $main.removeAttr('role'); 1852 } 1853 1854 // Cookiebot button 1855 var cookiebotObserver = new MutationObserver(function (mutations, obs) { 1856 var dialog = document.querySelector('#CybotCookiebotDialog'); 1857 if (dialog) { 1858 obs.disconnect(); 1859 1860 [ 1861 '#CybotCookiebotDialogBody', 1862 '#CybotCookiebotDialogTabContentDetails', 1863 '#CybotCookiebotDialogDetailBodyContentTextIABv2', 1864 '#CybotCookiebotDialogDetailBodyContentTextAbout' 1865 ].forEach(function (sel) { 1866 var el = document.querySelector(sel); 1867 if (el) el.setAttribute('role', 'region'); 1868 }); 1869 1870 document.querySelectorAll('.CybotCookiebotDialogNavItemLink').forEach(function (el) { 1871 el.setAttribute('role', 'button'); 1872 el.removeAttribute('aria-selected'); 1873 }); 1874 1875 var navList = document.querySelector('#CybotCookiebotDialogNavList'); 1876 if (navList) navList.setAttribute('role', 'list'); 1877 } 1878 }); 1879 1880 cookiebotObserver.observe(document.body, { childList: true, subtree: true }); 1881 1882}(jQuery))
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.