1document.addEventListener("DOMContentLoaded", function () { 2 // $(window).scroll(function () { 3 // if ($(this).scrollTop() > 195) { 4 // //use `this`, not `document` 5 // $(".mouse-gif").css({ 6 // opacity: "0", 7 // }); 8 9 // $(".black-bg-divider .hero-banner-divider").css({ 10 // opacity: "0", 11 // }); 12 // } 13 // if ($(this).scrollTop() < 190) { 14 // //use `this`, not `document` 15 // $(".mouse-gif").css({ 16 // opacity: "1", 17 // }); 18 // $(".black-bg-divider .hero-banner-divider").css({ 19 // opacity: "1", 20 // }); 21 // $(".black-bg-divider").css({ 22 // border: "none", 23 // }); 24 // } 25 // }); 26 27 // Swipers: 28 const exploreSwiperContainer = document.querySelector("#exploreSwiper"); 29 const exploreSwiper = document.querySelector( 30 "swiper-container#exploreSwiper", 31 ); 32 if (exploreSwiper) { 33 let currentSize = window.innerWidth; 34 const swiperParams = { 35 loop: true, 36 slidesPerView: 1, 37 centeredSlides: true, 38 navigation: true, 39 spaceBetween: 10, 40 breakpoints: { 41 679: { 42 slidesPerView: 2.9, 43 }, 44 700: { 45 slidesPerView: 3.1, 46 }, 47 1100: { 48 slidesPerView: 4.5, 49 }, 50 }, 51 pagination: { 52 el: "#exploreSwiper .swiper-pagination", 53 clickable: true, 54 }, 55 on: { 56 // init() {}, 57 }, 58 }; 59 60 // now we need to assign all parameters to Swiper element 61 Object.assign(exploreSwiper, swiperParams); 62 // and now initialize it 63 exploreSwiper.initialize(); 64 const swiper = exploreSwiperContainer.swiper; 65 if (currentSize > 679) { 66 swiper.slideTo(3); 67 } 68 69 swiper.update(); 70 // console.log(swiperParams); 71 } 72 73 const modelsSwiperContainer = document.querySelector("#modelsSwiper"); 74 const modelsSwiper = document.querySelector("swiper-container#modelsSwiper"); 75 76 if (modelsSwiper) { 77 const compareCta = document.querySelector( 78 ".compare-car-models-container[data-hide-for]", 79 ); 80 const hideForName = compareCta 81 ? (compareCta.getAttribute("data-hide-for") || "").toLowerCase() 82 : null; 83 84 function updateCompareCtaVisibility(sw) { 85 if (!compareCta || !hideForName) return; 86 const activeSlide = 87 (sw && sw.slides && sw.slides[sw.activeIndex]) || 88 document.querySelector("#modelsSwiper .swiper-slide-active"); 89 if (!activeSlide) return; 90 const activeName = ( 91 activeSlide.getAttribute("data-car-name") || "" 92 ).toLowerCase(); 93 compareCta.style.display = activeName === hideForName ? "none" : ""; 94 } 95 96 const swiperParams = { 97 slidesPerView: 2, 98 centeredSlides: true, 99 breakpoints: { 100 679: { 101 slidesPerView: 3, 102 }, 103 1100: { 104 slidesPerView: 4, 105 }, 106 }, 107 on: { 108 init(sw) { 109 updateCompareCtaVisibility(sw); 110 }, 111 slideChange(sw) { 112 updateCompareCtaVisibility(sw); 113 }, 114 }, 115 }; 116 // now we need to assign all parameters to Swiper element 117 Object.assign(modelsSwiper, swiperParams); 118 // swiper-container auto-inits before this script runs, so the `on` 119 // callbacks above may register after init has already fired. Bind to the 120 // web-component DOM events too so slide changes always update the CTA. 121 modelsSwiper.addEventListener("swiperinit", (e) => { 122 updateCompareCtaVisibility(e.detail && e.detail[0]); 123 }); 124 modelsSwiper.addEventListener("swiperslidechange", (e) => { 125 updateCompareCtaVisibility(e.detail && e.detail[0]); 126 }); 127 // and now initialize it 128 setTimeout(() => { 129 modelsSwiper.initialize(); 130 }, 1000); 131 const swiper = modelsSwiperContainer.swiper; 132 // Run once now in case init already fired before listeners were attached. 133 updateCompareCtaVisibility(swiper); 134 135 if (window.innerWidth >= 769) { 136 swiper.slideTo(3); 137 } else { 138 swiper.slideTo(2); 139 } 140
141 swiper.update(); 142 console.log(swiper); 143 } 144 const articlesSwiperContainer = document.querySelector("#articlesSwiper"); 145 const articlesSwiper = document.querySelector( 146 "swiper-container#articlesSwiper", 147 ); 148 149 if (articlesSwiper) { 150 const swiperParams = { 151 slidesPerView: 1, 152 spaceBetween: 35, 153 breakpoints: { 154 679: { 155 slidesPerView: 3, 156 spaceBetween: 35, 157 }, 158 }, 159 navigation: true, 160 pagination: true, 161 on: { 162 init() {}, 163 }, 164 }; 165 // now we need to assign all parameters to Swiper element 166 Object.assign(articlesSwiper, swiperParams); 167 168 // and now initialize it 169 articlesSwiper.initialize(); 170 const swiper = articlesSwiperContainer.swiper; 171 swiper.update(); 172 } 173 174 const weGoBeyondSwiperContainer = document.querySelector("#weGoBeyondSwiper"); 175 const weGoBeyondSwiper = document.querySelector( 176 "swiper-container#weGoBeyondSwiper", 177 ); 178 179 if (weGoBeyondSwiper) { 180 const swiperParams = { 181 slidesPerView: 1, 182 spaceBetween: 35, 183 navigation: true, 184 pagination: true, 185 on: { 186 init() {}, 187 }, 188 }; 189 // now we need to assign all parameters to Swiper element 190 Object.assign(weGoBeyondSwiper, swiperParams); 191 192 // and now initialize it 193 weGoBeyondSwiper.initialize(); 194 const swiper = weGoBeyondSwiperContainer.swiper; 195 swiper.update(); 196 } 197 198 const aboutUsSwiperContainer = document.querySelector("#aboutUsSwiper"); 199 const aboutUsSwiper = document.querySelector( 200 "swiper-container#aboutUsSwiper", 201 ); 202 if (aboutUsSwiper) { 203 const swiperParams = { 204 slidesPerView: 1, 205 spaceBetween: 35, 206 navigation: true, 207 pagination: true, 208 loop:true, 209 on: { 210 init() { 211 console.log("Swiper initialized"); 212 }, 213 resize: debounce(function () { 214 if (this && !this.destroyed) { 215 console.log("Debounced resize â updating Swiper"); 216 this.update(); 217 } 218 }, 150), 219 }, 220 }; 221 // now we need to assign all parameters to Swiper element 222 Object.assign(aboutUsSwiper, swiperParams); 223 224 // and now initialize it 225 aboutUsSwiper.initialize(); 226 const swiper = aboutUsSwiperContainer.swiper; 227 swiper.update(); 228 229 window.addEventListener("resize", () => { 230 if (swiper) { 231 swiper.update(); 232 } 233 }); 234 } 235 236 const subBannerSwiperContainer = document.querySelector("#subBannerSwiper"); 237 let subBannerSwiper = document.querySelector( 238 "swiper-container#subBannerSwiper", 239 ); 240 241 if (subBannerSwiper) { 242 let swiperInstance = null; 243 let currentSwiperContainer = subBannerSwiperContainer; 244 245 const swiperParams = { 246 loop: true, 247 centeredSlides: false, 248 slidesPerView: 1, 249 spaceBetween: 0, 250 autoplay: { 251 delay: 2500, 252 disableOnInteraction: false, 253 }, 254 breakpoints: { 255 768: { 256 slidesPerView: 2, 257 spaceBetween: 8, 258 }, 259 }, 260 navigation: true, 261 pagination: { 262 el: "#subBannerSwiper .swiper-pagination", 263 clickable: true, 264 }, 265 on: { 266 init() { 267 console.log("SubBanner swiper initialized"); 268 }, 269 breakpoint: (swiper, breakpointParams) => { 270 console.log("Breakpoint event triggered:", breakpointParams); 271 // Force update when Swiper detects breakpoint change 272 setTimeout(() => { 273 swiper.update(); 274 swiper.updateSize(); 275 swiper.updateSlides(); 276 swiper.updateProgress(); 277 swiper.updateSlidesClasses(); 278 }, 100); 279 }, 280 }, 281 }; 282 283 // Initialize swiper 284 function initializeSwiper() { 285 // Re-query the element to ensure we have the latest reference 286 subBannerSwiper = document.querySelector( 287 "swiper-container#subBannerSwiper", 288 ); 289 currentSwiperContainer = document.querySelector("#subBannerSwiper"); 290 291 if (subBannerSwiper && currentSwiperContainer) { 292 Object.assign(subBannerSwiper, swiperParams); 293 subBannerSwiper.initialize(); 294 swiperInstance = currentSwiperContainer.swiper; 295 if (swiperInstance) {
296 swiperInstance.update(); 297 } 298 } 299 } 300 301 // Completely destroy and recreate swiper element 302 function recreateSwiper() { 303 // Destroy existing swiper instance 304 if (swiperInstance && !swiperInstance.destroyed) { 305 swiperInstance.destroy(true, true); 306 swiperInstance = null; 307 } 308 309 // Get the parent container and HTML content 310 const parentContainer = currentSwiperContainer.parentNode; 311 const swiperHTML = currentSwiperContainer.innerHTML; 312 313 // Remove the entire swiper container 314 currentSwiperContainer.remove(); 315 316 // Create a new swiper container element 317 const newSwiperContainer = document.createElement("swiper-container"); 318 newSwiperContainer.id = "subBannerSwiper"; 319 newSwiperContainer.innerHTML = swiperHTML; 320 321 // Insert it back into the DOM 322 parentContainer.appendChild(newSwiperContainer); 323 324 // Update all references 325 currentSwiperContainer = document.querySelector("#subBannerSwiper"); 326 subBannerSwiper = document.querySelector( 327 "swiper-container#subBannerSwiper", 328 ); 329 330 // Small delay to ensure DOM is ready 331 setTimeout(() => { 332 initializeSwiper(); 333 }, 150); 334 } 335 336 // Initial setup 337 initializeSwiper(); 338 339 // Enhanced resize handler with complete recreation 340 let resizeTimeout; 341 let lastWidth = window.innerWidth; 342 let lastBreakpointState = lastWidth >= 768; // Track breakpoint state 343 344 window.addEventListener("resize", () => { 345 // Cancel any pending update 346 clearTimeout(resizeTimeout); 347 348 // Debounce to avoid excessive calls 349 resizeTimeout = setTimeout(() => { 350 const currentWidth = window.innerWidth; 351 const currentBreakpointState = currentWidth >= 768; 352 const crossedBreakpoint = 353 lastBreakpointState !== currentBreakpointState; 354 const significantChange = Math.abs(currentWidth - lastWidth) > 100; 355 356 if (crossedBreakpoint) { 357 console.log("Crossed 768px breakpoint, recreating swiper"); 358 recreateSwiper(); 359 } else if (swiperInstance && !swiperInstance.destroyed) { 360 // console.log("Resized â updating swiper"); 361 swiperInstance.update(); 362 } 363 364 lastWidth = currentWidth; 365 lastBreakpointState = currentBreakpointState; 366 }, 150); // 150â200ms debounce works well 367 }); 368 } 369 370 const elevatSwiperContainer = document.querySelector("#elevateYLife"); 371 const elevateSwiper = document.querySelector("swiper-container#elevateYLife"); 372 if (elevateSwiper) { 373 const swiperParams = { 374 slidesPerView: 1, 375 spaceBetween: 35, 376 loop: true, 377 navigation: true, 378 pagination: true, 379 on: { 380 init() {}, 381 resize() { 382 // Force update on resize 383 this.update(); 384 }, 385 }, 386 }; 387 // now we need to assign all parameters to Swiper element 388 Object.assign(elevateSwiper, swiperParams); 389 390 // and now initialize it 391 elevateSwiper.initialize(); 392 const swiper = elevatSwiperContainer.swiper; 393 swiper.update(); 394 395 window.addEventListener("resize", () => { 396 if (swiper) { 397 swiper.update(); 398 } 399 }); 400 } 401}); 402 403function togglePopup(value) { 404 $("." + value) 405 .get(0) 406 .classList.toggle("active"); 407} 408 409function openVideoPopup(videoId) { 410 // Set up iframe source with necessary parameters 411 const embedUrl = `https://www.youtube.com/embed/${videoId}?enablejsapi=1&rel=0&autoplay=1`; 412 413 // Inject iframe with the updated URL 414 $(".video-popup iframe").prop("src", embedUrl); 415 416 // Show the popup 417 togglePopup("video-popup"); 418 419 // Initialize YouTube API player 420 if (!player) { 421 player = new YT.Player($(".video-popup iframe")[0], { 422 events: { 423 onReady: function (event) { 424 event.target.playVideo(); 425 }, 426 }, 427 }); 428 } else { 429 player.loadVideoById(videoId); 430 } 431 playVideoWithSound(); 432} 433 434function openMultiVideoPopup(urlArray) { 435 // Build swiper slides with YouTube iframes 436 if (!Array.isArray(urlArray) || urlArray.length === 0) return; 437 438 const contentEl = document.querySelector(".multi-video-popup .popup-content"); 439 if (!contentEl) return; 440 441 // Helper to choose correct separator when video string may already contain query params 442 const sep = (s) => (s.includes("?") ? "&" : "?"); 443 444 // Build HTML for swiper container + slides 445 const swiperId = "multiVideoSwiper"; 446 let slidesHtml = urlArray 447 .map((videoParam, idx) => { 448 // Only the first iframe includes autoplay=1 so other iframes won't start automatically 449 const autoplayParam = idx === 0 ? "&autoplay=1" : ""; 450 const src = `https://www.youtube.com/embed/${videoParam}${sep(videoParam)}enablejsapi=1&rel=0&mute=1${autoplayParam}`; 451 return `<swiper-slide>
451<iframe id="multi-video-${idx}" class="multi-youtube-iframe" src="${src}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; autoplay" allowfullscreen></iframe></swiper-slide>`; 452 }) 453 .join(""); 454 455 contentEl.innerHTML = ` 456 <div class="multi-video-swiper-wrapper" style="width:100%;height:100%;"> 457 <swiper-container id="${swiperId}" class="multi-video-swiper" slides-per-view="1" navigation="true" pagination="true" style="width:100%;height:100%;"> 458 ${slidesHtml} 459 </swiper-container> 460 </div> 461 `; 462 463 // Show the popup 464 togglePopup("multi-video-popup"); 465 466 // small helper to send player commands using postMessage (YouTube iframe API) 467 function sendCommandToIframe(iframe, func, args = []) { 468 try { 469 if (!iframe || !iframe.contentWindow) return; 470 const msg = JSON.stringify({ 471 event: "command", 472 func: func, 473 args: args, 474 }); 475 iframe.contentWindow.postMessage(msg, "*"); 476 } catch (e) { 477 // ignore 478 } 479 } 480 481 console.log("[multiVideo] openMultiVideoPopup called. urlArray:", urlArray); 482 483 const swiperParams = { 484 slidesPerView: 1, 485 centeredSlides: true, 486 navigation: true, 487 pagination: { 488 el: `#${swiperId} .swiper-pagination`, 489 clickable: true, 490 }, 491 observer: true, 492 observeParents: true, 493 on: { 494 init() { 495 const swiperInst = this; 496 const allIframes = multiSwiperEl.querySelectorAll( 497 ".multi-youtube-iframe", 498 ); 499 console.log( 500 "[multiVideo] init â slides:", 501 swiperInst.slides.length, 502 "activeIndex:", 503 swiperInst.activeIndex, 504 "iframes found:", 505 allIframes.length, 506 ); 507 508 // Pause/stop all iframes first (covers clones) 509 allIframes.forEach((iframe) => { 510 console.log( 511 "[multiVideo] init â pausing iframe:", 512 iframe.id, 513 iframe.src, 514 ); 515 sendCommandToIframe(iframe, "pauseVideo"); 516 sendCommandToIframe(iframe, "stopVideo"); 517 }); 518 519 // Play the currently active slide's iframe (use activeIndex which maps to DOM slide) 520 const activeSlide = swiperInst.slides[swiperInst.activeIndex]; 521 const activeIframe = 522 activeSlide && activeSlide.querySelector(".multi-youtube-iframe"); 523 console.log( 524 "[multiVideo] init â activeSlide:", 525 activeSlide, 526 "activeIframe:", 527 activeIframe && activeIframe.id, 528 ); 529 if (activeIframe) { 530 console.log( 531 "[multiVideo] init â play active iframe:", 532 activeIframe.id, 533 ); 534 sendCommandToIframe(activeIframe, "playVideo"); 535 setTimeout(() => { 536 sendCommandToIframe(activeIframe, "unMute"); 537 sendCommandToIframe(activeIframe, "playVideo"); 538 }, 300); 539 } 540 }, 541 slideChange(swiperInst) { 542 console.log( 543 "[multiVideo] slideChange â activeIndex:", 544 swiperInst.activeIndex, 545 "realIndex:", 546 swiperInst.realIndex, 547 "previousIndex:", 548 swiperInst.previousIndex, 549 ); 550 551 // Get DOM slide that is currently active (handles loop/cloned slides correctly) 552 const activeSlide = swiperInst.slides[swiperInst.activeIndex]; 553 const activeIframe = 554 activeSlide && activeSlide.querySelector(".multi-youtube-iframe"); 555 console.log( 556 "[multiVideo] slideChange â activeSlide:", 557 activeSlide, 558 "activeIframe:", 559 activeIframe && activeIframe.id, 560 ); 561 562 // Pause/stop all iframes first 563 const allIframes = multiSwiperEl.querySelectorAll( 564 ".multi-youtube-iframe", 565 ); 566 allIframes.forEach((iframe) => { 567 if (iframe !== activeIframe) { 568 console.log( 569 "[multiVideo] slideChange â stopping iframe:", 570 iframe.id, 571 ); 572 sendCommandToIframe(iframe, "pauseVideo"); 573 sendCommandToIframe(iframe, "stopVideo"); 574 console.log( 575 "[multiVideo] slideChange â iframe contentWindow:", 576 !!(iframe && iframe.contentWindow), 577 ); 578 } 579 }); 580 581 // Play/unmute the active iframe 582 if (activeIframe) { 583 console.log( 584 "[multiVideo] slideChange â play active iframe:", 585 activeIframe.id, 586 ); 587 setTimeout(() => { 588 sendCommandToIframe(activeIframe, "playVideo"); 589 setTimeout(() => { 590 sendCommandToIframe(activeIframe, "unMute"); 591 }, 200); 592 }, 150); 593 } 594 }, 595 // ensure update on breakpoint/resize 596 resize() { 597 if (this && !this.destroyed) this.update(); 598 }, 599 }, 600 }; 601 602 // attach params and initialize with retries so we can see debug logs when elements are missing 603 let initAttempts = 0; 604 function tryInitMultiSwiper() { 605 initAttempts++; 606 const multiSwiperEl = document.querySelector( 607 `swiper-container#${swiperId}`, 608 ); 609 const multiSwiperContainer = document.querySelector(`#${swiperId}`); 610 console.log("[multiVideo] tryInitMultiSwiper attempt", initAttempts, { 611 multiSwiperEl, 612 multiSwiperContainer, 613 });
614 615 if (!multiSwiperEl || !multiSwiperContainer) { 616 if (initAttempts < 12) { 617 // retry a few times while DOM / webcomponent may upgrade 618 setTimeout(tryInitMultiSwiper, 100); 619 return; 620 } 621 console.log("[multiVideo] could not find swiper elements after retries"); 622 return; 623 } 624 625 try { 626 Object.assign(multiSwiperEl, swiperParams); 627 console.log("[multiVideo] assigned params to multiSwiperEl"); 628 } catch (e) { 629 console.log("[multiVideo] Object.assign error", e); 630 } 631 632 try { 633 if (typeof multiSwiperEl.initialize === "function") { 634 multiSwiperEl.initialize(); 635 console.log("[multiVideo] multiSwiperEl.initialize() called"); 636 637 // wait a little then attach handlers directly to the Swiper instance (guarantees events fire) 638 setTimeout(() => { 639 const sw = multiSwiperContainer && multiSwiperContainer.swiper; 640 console.log( 641 "[multiVideo] swiper instance after init:", 642 !!sw, 643 sw && { 644 activeIndex: sw.activeIndex, 645 slides: sw.slides && sw.slides.length, 646 }, 647 ); 648 649 if (!sw) { 650 console.log("[multiVideo] no swiper instance available yet"); 651 return; 652 } 653 654 // Avoid double-attaching 655 if (sw._multiVideoHandlersAttached) { 656 console.log( 657 "[multiVideo] handlers already attached on swiper instance", 658 ); 659 return; 660 } 661 sw._multiVideoHandlersAttached = true; 662 663 // Instance-level init handler 664 sw.on("init", function () { 665 console.log( 666 "[multiVideo][inst] init â activeIndex:", 667 this.activeIndex, 668 "slides:", 669 this.slides.length, 670 ); 671 const allIframes = multiSwiperEl.querySelectorAll( 672 ".multi-youtube-iframe", 673 ); 674 allIframes.forEach((iframe) => { 675 console.log( 676 "[multiVideo][inst] init â pausing iframe:", 677 iframe.id, 678 iframe.src, 679 ); 680 sendCommandToIframe(iframe, "pauseVideo"); 681 }); 682 683 const activeSlide = this.slides[this.activeIndex]; 684 const activeIframe = 685 activeSlide && activeSlide.querySelector(".multi-youtube-iframe"); 686 console.log( 687 "[multiVideo][inst] init â activeIframe:", 688 activeIframe && activeIframe.id, 689 ); 690 if (activeIframe) { 691 sendCommandToIframe(activeIframe, "playVideo"); 692 setTimeout(() => { 693 sendCommandToIframe(activeIframe, "unMute"); 694 sendCommandToIframe(activeIframe, "playVideo"); 695 }, 300); 696 } 697 }); 698 699 // Instance-level slideChange handler 700 sw.on("slideChange", function () { 701 console.log( 702 "[multiVideo][inst] slideChange â activeIndex:", 703 this.activeIndex, 704 "realIndex:", 705 this.realIndex, 706 "previousIndex:", 707 this.previousIndex, 708 ); 709 710 const activeSlide = this.slides[this.activeIndex]; 711 const activeIframe = 712 activeSlide && activeSlide.querySelector(".multi-youtube-iframe"); 713 console.log( 714 "[multiVideo][inst] slideChange â activeIframe:", 715 activeIframe && activeIframe.id, 716 ); 717 718 const allIframes = multiSwiperEl.querySelectorAll( 719 ".multi-youtube-iframe", 720 ); 721 allIframes.forEach((iframe) => { 722 if (iframe !== activeIframe) { 723 console.log( 724 "[multiVideo][inst] slideChange â stopping iframe:", 725 iframe.id, 726 ); 727 sendCommandToIframe(iframe, "pauseVideo"); 728 } 729 }); 730 731 if (activeIframe) { 732 console.log( 733 "[multiVideo][inst] slideChange â play active iframe:", 734 activeIframe.id, 735 ); 736 setTimeout(() => { 737 sendCommandToIframe(activeIframe, "playVideo"); 738 setTimeout(() => { 739 sendCommandToIframe(activeIframe, "unMute"); 740 }, 200); 741 }, 150); 742 } 743 }); 744 745 // If the instance was already initialized before we attached handlers, trigger the init handler manually 746 if (sw.initialized) { 747 console.log( 748 "[multiVideo] swiper already initialized â calling instance init handler manually", 749 ); 750 sw.emit && sw.emit("init"); 751 } 752 }, 50); 753 } else { 754 console.log( 755 "[multiVideo] initialize() not present on element, will attempt again", 756 ); 757 if (initAttempts < 12) setTimeout(tryInitMultiSwiper, 100); 758 } 759 } catch (e) { 760 console.log("[multiVideo] initialize threw", e); 761 } 762 } 763 tryInitMultiSwiper(); 764} 765 766function closeVideoPopup() { 767 $(".video-popup .popup-content").html( 768 '<iframe id="youtube-player" src="" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>', 769 ); 770 togglePopup("video-popup"); 771} 772 773function closeMultiVideoPopup() { 774 $(".multi-video-popup .popup-content").html( 775 '<div class="video-placeholder">Video will be loaded here</div>', 776 );
777 togglePopup("multi-video-popup"); 778} 779 780function playVideoWithSound() { 781 const iframe = document.getElementById("youtube-player"); 782 // Make sure the iframe has `?enablejsapi=1` in the URL 783 iframe.contentWindow.postMessage( 784 '{"event":"command","func":"playVideo","args":""}', 785 "*", 786 ); 787 console.log(iframe.contentWindow); 788} 789 790document.addEventListener("DOMContentLoaded", function () { 791 const businessContainers = document.querySelectorAll( 792 ".cl-business-accordion", 793 ); 794 let accordionClickHandlers = []; 795 let activeAccordionIndex = 0; // Track currently active accordion 796 797 function initializeAccordion() { 798 const windowWidth = window.innerWidth; 799 800 // Only apply accordion behavior when window width is between 1024px and 1650px 801 if (windowWidth >= 1024 && windowWidth <= 1600) { 802 // Find currently active accordion or default to first one 803 let foundActive = false; 804 businessContainers.forEach(function (container, index) { 805 if (container.classList.contains("active")) { 806 activeAccordionIndex = index; 807 foundActive = true; 808 } 809 }); 810 811 // First reset all accordions 812 businessContainers.forEach(function (container) { 813 container.classList.remove("active"); 814 const accordionContainer = container.querySelector( 815 ".accordion-container", 816 ); 817 if (accordionContainer) { 818 accordionContainer.classList.remove("active"); 819 } 820 }); 821 822 // Open the active accordion (or default to first) 823 if (businessContainers.length > 0) { 824 businessContainers[activeAccordionIndex].classList.add("active"); 825 const activeAccordionContainer = businessContainers[ 826 activeAccordionIndex 827 ].querySelector(".accordion-container"); 828 if (activeAccordionContainer) { 829 activeAccordionContainer.classList.add("active"); 830 } 831 } 832 833 // Add click handlers for accordion functionality 834 businessContainers.forEach(function (container, index) { 835 const clickHandler = function () { 836 const accordionContainer = container.querySelector( 837 ".accordion-container", 838 ); 839 const isCurrentlyActive = container.classList.contains("active"); 840 841 // If this accordion is already active, do nothing (prevent closing) 842 if (isCurrentlyActive) { 843 return; 844 } 845 846 // Close all other accordion containers 847 businessContainers.forEach(function (otherContainer) { 848 if (otherContainer !== container) { 849 otherContainer.classList.remove("active"); 850 const otherAccordionContainer = otherContainer.querySelector( 851 ".accordion-container", 852 ); 853 if (otherAccordionContainer) { 854 otherAccordionContainer.classList.remove("active"); 855 } 856 } 857 }); 858 859 // Open the clicked accordion and update active index 860 container.classList.add("active"); 861 activeAccordionIndex = index; 862 863 if (accordionContainer) { 864 accordionContainer.classList.add("active"); 865 } 866 }; 867 868 container.addEventListener("mouseenter", clickHandler); 869 accordionClickHandlers.push({ container, handler: clickHandler }); 870 }); 871 } else { 872 // Show all content for screens smaller than 1024px or larger than 1650px 873 businessContainers.forEach(function (container) { 874 container.classList.add("active"); 875 const accordionContainer = container.querySelector( 876 ".accordion-container", 877 ); 878 if (accordionContainer) { 879 accordionContainer.classList.add("active"); 880 } 881 }); 882 } 883 } 884 885 function removeAccordionHandlers() { 886 accordionClickHandlers.forEach(function (item) { 887 item.container.removeEventListener("mouseenter", item.handler); 888 }); 889 accordionClickHandlers = []; 890 } 891 892 function handleResize() {
893 removeAccordionHandlers(); 894 initializeAccordion(); 895 } 896 897 // Initialize accordion on page load 898 initializeAccordion(); 899 900 // Handle window resize 901 window.addEventListener("resize", handleResize); 902}); 903 904document.addEventListener("DOMContentLoaded", function () { 905 const soundContainer = document.getElementById("sound-container"); 906 const video = document.querySelector(".splash-screen-banner video"); 907 const soundIcon = soundContainer.querySelector("img"); 908 let isMuted = true; 909 910 soundContainer.addEventListener("click", function () { 911 if (isMuted) { 912 video.muted = false; 913 video.volume = 0.7; // Set volume to 70% 914 soundIcon.src = "assets/images/splashscreen/sound-on.webp"; 915 isMuted = false; 916 } else { 917 video.muted = true; 918 soundIcon.src = "assets/images/splashscreen/sound-off.webp"; 919 isMuted = true; 920 } 921 }); 922}); 923 924function debounce(func, wait = 150) { 925 let timeout; 926 return (...args) => { 927 clearTimeout(timeout); 928 timeout = setTimeout(() => func.apply(this, args), wait); 929 }; 930} 931 932// document.addEventListener("DOMContentLoaded", function () { 933// const closeSplashscreen = document.getElementById("start-icon"); 934// if (closeSplashscreen) { 935// closeSplashscreen.addEventListener("click", () => { 936// const splashscreen = document.getElementById("splashscreen"); 937// if (splashscreen) { 938// splashscreen.classList.add("removed"); 939// splashscreen.addEventListener("animationend", () => { 940// splashscreen.remove(); 941// }); 942// } 943 944// const slider = document.querySelector(".parallax-layer"); 945// slider.classList.add("animate"); 946// setTimeout(() => { 947// slider.classList.remove("animate"); 948// }, 1000); 949// }); 950// } 951// const soundSwitch = document.querySelector("#sound-container > img"); 952// if (soundSwitch) { 953// soundSwitch.addEventListener("click", () => { 954// const video = document.querySelector("#splashscreen > video"); 955// if (soundSwitch.src.includes("sound-off.webp")) { 956// soundSwitch.src = soundSwitch.src.replace( 957// "sound-off.webp", 958// "sound-on.webp" 959// ); 960// video.muted = false; 961// } else { 962// soundSwitch.src = soundSwitch.src.replace( 963// "sound-on.webp", 964// "sound-off.webp" 965// ); 966// video.muted = true; 967// } 968// }); 969// } 970// });
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.