PageSourceSearch

https://starrcompanies.com/-/media/Themes/Starr/Starr/Starr-Base-Theme/Scripts/insights-ui.js

js starrcompanies.com collected 2026-09-24 19:07:27 UTC 32,777 bytes, 1,041 lines download raw bytes

1$(document).ready(function () {
2  // Discover our products
3  let $disProdList = $('.str-prodlist-slides');
4  let $insgtOtherSlides = $('.insights-oth-slider');
5  let $insgtTeamSlides = $('.insights-team-slider');
6  let $insgtRETeamSlides = $('.insights-re-team-slider')
7
8  $disProdList.length && $disProdList.slick({
9    dots: false,
10    infinite: false,
11    speed: 300,
12    slidesToShow: 4,
13    slidesToScroll: 2,
14    draggable: false,
15    responsive: [
16      {
17        breakpoint: 1024,
18        settings: {
19          slidesToShow: 3,
20          slidesToScroll: 1,
21          infinite: false,
22          dots: false,
23          draggable: false,
24        },
25      },
26      {
27        breakpoint: 767,
28        settings: {
29          slidesToShow: 2,
30          slidesToScroll: 1,
31          draggable: true,
32        },
33      },
34      {
35        breakpoint: 600,
36        settings: {
37          slidesToShow: 1,
38          slidesToScroll: 1,
39          draggable: true,
40        },
41      }
42    ],
43  });
44
45  $insgtOtherSlides.slick({
46    dots: false,
47    infinite: false,
48    speed: 500,
49    slidesToShow: 2.5,
50    slidesToScroll: 2,
51    draggable: false,
52    responsive: [
53      {
54        breakpoint: 1025,
55        settings: {
56          slidesToShow: 2,
57          slidesToScroll: 2
58        },
59      },
60      {
61        breakpoint: 767,
62        settings: {
63          slidesToShow: 1,
64          slidesToScroll: 1,
65          draggable: true,
66        },
67      }
68    ],
69  });
70
71  $insgtTeamSlides.slick({
72    dots: false,
73    infinite: false,
74    speed: 300,
75    slidesToShow: 3,
76    slidesToScroll: 2,
77    draggable: false,
78    responsive: [
79      {
80        breakpoint: 1024,
81        settings: {
82          slidesToShow: 3,
83          slidesToScroll: 1,
84          infinite: false,
85          dots: false,
86          draggable: false,
87        },
88      },
89      {
90        breakpoint: 992,
91        settings: {
92          slidesToShow: 2,
93          slidesToScroll: 1,
94          infinite: false,
95          dots: false,
96        },
97      },
98      {
99        breakpoint: 600,
100        settings: {
101          slidesToShow: 1,
102          slidesToScroll: 1,
103        },
104      },
105    ],
106  });
107
108  $insgtRETeamSlides.slick({
109    dots: false,
110    infinite: false,
111    speed: 300,
112    slidesToShow: 4,
113    slidesToScroll: 3,
114    draggable: false,
115    responsive: [
116      {
117        breakpoint: 1500,
118        settings: {
119          slidesToShow: 3,
120          slidesToScroll: 2,
121          infinite: false,
122          dots: false,
123          draggable: false,
124        },
125      },
126      {
127        breakpoint: 992,
128        settings: {
129          slidesToShow: 2,
130          slidesToScroll: 1,
131          infinite: false,
132          dots: false,
133        },
134      },
135      {
136        breakpoint: 600,
137        settings: {
138          slidesToShow: 1,
139          slidesToScroll: 1,
140        },
141      },
142    ],
143  });
144
145
146  // Check if the device supports touch
147  const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
148
149  if (isTouchDevice) {
150    // MOBILE: Tap to toggle open/closed
151    $('.flipcard-float-text').on('click', function (e) {
152      e.preventDefault();
153      $('.insights-re-multidev-flipcard .flip-card-hld').toggleClass('flip-card--active');
154    });
155  } else {
156    // DESKTOP: Smooth hover in and out
157    $('.flipcard-float-text').hover(
158      function () { $('.insights-re-multidev-flipcard .flip-card-hld').addClass('flip-card--active'); },
159      function () { $('.insights-re-multidev-flipcard .flip-card-hld').removeClass('flip-card--active'); }
160    );
161  }
162
163  /* GSAP OnLoad Banner Animation */
164  let bannerSplit;
165  let fadeInUpOnLoad = {
166    y: 50,
167    autoAlpha: 0,
168    duration: 1,
169    stagger: 0.1,
170    ease: "power2.inOut"
171  }
172
173  const heroTl = gsap.timeline({
174    defaults: { ease: "power2.inOut" }
175  });
176
177  gsap.set(".starr-content_banner--insights h1, .banner--profile-badge", { opacity: 1, y: 0 });
178
179  heroTl.from(".starr-content_banner--insights h1 span", fadeInUpOnLoad).from(".banner--profile-badge", fadeInUpOnLoad, "-=0.5");
180});
181
182document.addEventListener("DOMContentLoaded", (event) => {
183  // Target the video element
184  const myVideo = document.querySelector(".re-capital-vid-hld video");
185  if (myVideo) {
186    myVideo.playbackRate = 0.35;
187  }
188
189
190  // you only need to define the configuration settings you want to CHANGE. Omitted properties won't be affected.
191  gsap.config({
192    nullTargetWarn: false,
193  });
194
195  gsap.registerPlugin(ScrollTrigger);
196
197  const heroBannerSc = document.querySelector('.starr_hero_banner');
198  if (heroBannerSc && heroBannerSc.classList.contains('starr-smooth-scroll-lenis')) {
199    const lenis = new Lenis();
200    // Synchronize Lenis scrolling with GSAP's ScrollTrigger plugin
201    lenis.on('scroll', ScrollTrigger.update);
202
203    // Add Lenis's requestAnimationFrame (raf) method to GSAP's ticker
204    // This ensures Lenis's smooth scroll animation updates on each GSAP tick
205    gsap.ticker.add((time) => {
206      lenis.raf(time * 1000); // Convert time from seconds to milliseconds
207
208      // Disable lag smoothing in GSAP to prevent any delay in scroll animations
209      gsap.ticker.lagSmoothing(0);
210
211    });
212  }
213
214  ScrollTrigger.defaults({
215    anticipatePin: 1, // Gives the engine a buffer to calculate layout shifts
216  });
217
218  // gsap code here!
219  // media query
220  let mm = gsap.matchMedia(),
221    breakPoint = 768;
222
223
224  /* fn - Global Header group animation */
225  function createScrollTrigger(triggerElmt, timeline, startDesktop = 75, startMob = 85, markers = false) {
226    ScrollTrigger.create({
227      trigger: triggerElmt,
228      start: () => {
229        return window.innerWidth >= 768 ? `top ${startDesktop}%` : `top ${startMob}%`;
230      },
231      end: "bottom center",
232      markers: markers,
233      onEnter: () => timeline.play(),
234      onLeaveBack: () => {
235        // Reverse animation when scrolled past
236        timeline.reverse();
237      }
238    });
239  }
240
241  /* fn - Zigzag Line Animation */
242  function fnZigzagSVGAnime(svgPathID, duration = 1, start = "top bottom", end = "bottom 70%", scrub = 1) {
243    if (svgPathID) {
244      let path = document.querySelector(`#${svgPathID}`);
245      if (path) {
246        let pathLength = path.getTotalLength();
247        gsap.set(path, { strokeDasharray: pathLength });
248
249        let shipfleetTL = gsap.timeline();
250        shipfleetTL.fromTo(
251          path, {
252          strokeDashoffset: pathLength
253        },
254          {
255            strokeDashoffset: 0,
256            duration: duration,
257            ease: "power2.in",
258            scrollTrigger: {
259              trigger: path,
260              start: start,
261              end: end,
262              scrub: scrub
263            }
264          }
265        )
266      }
267    }
268  }
269
270  /* fn - Global fadein up stagger list animation */
271  function gsapFadeInUpStagger(el, y = 50, duration = 1, stagger = 0.3, ease = "power2.inOut") {
272    let elArr = gsap.utils.toArray(el);
273    let tL = gsap.timeline({ ease: ease, paused: true });
274    if (elArr.length) {
275      tL.from(el, {
276        y: y,
277        autoAlpha: 0,
278        duration: duration,
279        stagger: stagger
280      }, createScrollTrigger(el, tL));
281    }
282  }
283
284  let mainNav = document.querySelector(".starr-menubar .header");
285  let mainNavH = mainNav ? mainNav.clientHeight : "";
286
287  mm.add({
288    isDesktop: `(min-width: ${breakPoint}px)`,
289    isMobile: `(max-width: ${breakPoint - 1}px)`
290  }, (context) => {
291    // Extract context conditions for easy reference if needed
292    let { isDesktop, isMobile } = context.conditions;
293    /* ==== 
294    ** All pinned Animationn Should keep to top ----
295    ** Pinned Animation Start
296    =====*/
297
298    /* Shipfleet section  Tab Animaiton */
299    let tabCards = gsap.utils.toArray(".anime-horiz-tab-content .insights-tab-content");
300    if (tabCards.length) {
301      let tabCardsContainer = document.querySelector(".anime-horiz-tab-content");
302      let tabTotalscroll = tabCardsContainer.scrollWidth - (tabCards[0].offsetWidth);
303      let tabShipImg1 = tabCards[0].querySelector(".insights-tab-img-xl");
304      let tabEllipseImg1 = tabCards[0].querySelector(".insights-tab-ellipse");
305
306      let tabCards1TL = gsap.timeline({
307        scrollTrigger: {
308          trigger: tabCards[0],
309          start: "top 70%",
310          end: "top top",
311          scrub: true
312        }
313      });
314
315      tabCards1TL.from(tabShipImg1, {
316        xPercent: -80,
317        duration: 1,
318      })
319        .from(tabEllipseImg1, {
320          scale: 0,
321          autoAlpha: 0,
322          duration: 1,
323        })
324
325      let scrollTrackTL = gsap.timeline({
326        scrollTrigger: {
327          trigger: ".insights-tab-scroller",
328          start: `top ${mainNavH}px`,
329          end: `+=${tabTotalscroll}`,
330          pin: true,
331          scrub: true,
332        }
333      });
334
335      scrollTrackTL.to(tabCardsContainer, {
336        x: -tabTotalscroll,
337        duration: tabCards.length,
338        ease: "none"
339      });
340
341      tabCards.forEach(tab => {
342        let tabContent = tab.querySelectorAll(".insights-content");
343        let tabShipImg = tab.querySelector(".insights-tab-img-xl");
344        let tabEllipseImg = tab.querySelector(".insights-tab-ellipse");
345
346        scrollTrackTL.from(tabEllipseImg, {
347          scale: 0,
348          autoAlpha: 0,
349          duration: 1,
350          scrollTrigger: {
351            trigger: tab,
352            start: "left 70%",
353            end: "center center",
354            containerAnimation: scrollTrackTL,
355            scrub: true,
356          }
357        },)
358
359        if (tab.classList.contains("insights-tab-content--grey")) {
360          scrollTrackTL.from(tabShipImg, {
361            xPercent: -80,
362            duration: 1,
363            scrollTrigger: {
364              trigger: tab,
365              start: "left 75%",
366              end: "left 40%",
367              containerAnimation: scrollTrackTL,
368              scrub: true,
369            }
370          }, "<")
371        }
372
373        if (tab.classList.contains("insights-tab-content--shadow")) {
374          scrollTrackTL.from(tabShipImg, {
375            yPercent: -100,
376            duration: 1,
377            scrollTrigger: {
378              trigger: tab,
379              start: "left 75%",
380              end: "left 40%",
381              containerAnimation: scrollTrackTL,
382              scrub: true,
383            }
384          }, "<")
385        }
386
387      });
388
389    }
390
391    /* Stack Card pined Animation */
392
393    /* Stacked Image Card Intro Animation */
394    gsapFadeInUpStagger(".anime-stacked-card-col", 100);
395
396    /* Stacked Image Card Pinned Animation */
397    let stackCardItems = gsap.utils.toArray(".stack-card-item");
398    if (stackCardItems.length) {
399      let stackContainer = document.querySelector(".stacked-card-panel");
400      let stackContainerHeight = parseInt(stackContainer.getBoundingClientRect().height);
401
402
403      gsap.set(stackCardItems[0], { y: 0, autoAlpha: 1, display: "block" });
404
405      const stackCardTl = gsap.timeline({
406        scrollTrigger: {
407          trigger: ".stacked-card-panel",
408          start: () => {
409            return window.innerWidth >= 768 ? "top 8%" : "top 50px";
410          },
411          end: () => "=+" + (stackContainerHeight * stackCardItems.length),
412          scrub: 1,
413          pin: true
414        }
415      });
416
417      stackCardItems.forEach((el, i) => {
418        if (i === 0) return;
419
420        let prevItem = stackCardItems[i - 1];
421        let stepLable = `step_${i}`;
422
423        stackCardTl.addLabel(stepLable);
424
425        // move previous card content to top
426        stackCardTl.to(prevItem, {
427          y: -25,
428          autoAlpha: 0,
429          duration: 0.6,
430          ease: "power2.inOut",
431          display: "none"
432        }, stepLable);
433
434
435        //Transition in for current card
436        stackCardTl.fromTo(el, {
437          autoAlpha: 0,
438          y: 50,
439          display: "none"
440        }, {
441          y: 0,
442          autoAlpha: 1,
443          duration: 0.6,
444          ease: "power2.inOut",
445          display: "block"
446        }, `${stepLable}+=0.4`);
447      });
448
449      stackCardTl.to({}, { duration: 0.3 });
450    }
451
452    /* Regions Map slideup */
453    let regionMapTL = gsap.timeline({
454      scrollTrigger: {
455        trigger: ".regions-map-hld",
456        start: () => {
457          return window.innerWidth >= 768 ? "top 70%" : "top 80%";
458        },
459        toggleActions: "play none none reverse"
460      }
461    });
462
463    regionMapTL.to(".regions-map-imghld svg", { autoAlpha: 1, duration: 0.6, ease: "power2.inOut" });
464
465    const popupMapCards = gsap.utils.toArray(".regions-map-popover");
466    const popupMapPointers = gsap.utils.toArray(".popover-circle");
467
468    if (popupMapCards.length) {
469      const mcTotalLen = popupMapCards.length;
470      const mcTotalScroll = mcTotalLen * 1000;
471
472      const mcTL = gsap.timeline({
473        scrollTrigger: {
474          trigger: ".regions-map-hld",
475          start: isDesktop ? "top 70px" : "top 12%",
476          end: `+=${mcTotalScroll}`,
477          pin: true,
478          scrub: 1
479        }
480      });
481
482      popupMapCards.forEach((card, index) => {
483        const pointerEl = popupMapPointers[index];
484        gsap.set(card, { yPercent: isDesktop ? -25 : 0, display: "none" });
485
486        mcTL.to(card, {
487          autoAlpha: 1,
488          yPercent: isDesktop ? -50 : -15,
489          duration: isDesktop ? 1 : 0.6,
490          ease: "power2.inOut",
491          display: "flex",
492          onStart: () => pointerEl && pointerEl.classList.add('active'),
493          onReverseComplete: () => pointerEl && pointerEl.classList.remove('active')
494        })
495          .to({}, { duration: isDesktop ? 0.5 : 0.3 });
496
497        if (index < mcTotalLen - 1) {
498          mcTL.to(card, {
499            autoAlpha: 0,
500            yPercent: isDesktop ? -75 : -25,
501            duration: isDesktop ? 1 : 0.6,
502            display: "none",
503            ease: "power2.inOut",
504            onComplete: () => pointerEl && pointerEl.classList.remove('active'),
505            onInterrupt: () => pointerEl && pointerEl.classList.add('active'),
506            onReverseComplete: () => pointerEl && pointerEl.classList.add('active')
507          })
508        }
509      });
510    }
511
512    /* RE Stacked icon sldier */
513    const stackIconGrp = gsap.utils.toArray(".anime-stack-icon-grp li");
514    if (stackIconGrp.length) {
515      const stackIconGrpLen = stackIconGrp.length * 200;
516
517      const stackIconTL = gsap.timeline({
518        scrollTrigger: {
519          trigger: ".anime-stack-icon-sec",
520          start: isDesktop ? "top 35%" : "top 75%",
521          end: isDesktop ? `+=${stackIconGrpLen}` : "+=70%",
522          scrub: isDesktop ? 1 : true,
523          pin: isDesktop ? true : false
524        }
525      });
526
527      stackIconGrp.forEach((element, index) => {
528        stackIconTL.from(element, {
529          autoAlpha: 0,
530          y: 100,
531          xPercent: isDesktop ? 70 : 0,
532          duration: 1,
533        })
534      });
535    }
536
537    /* RE Category Slider */
538    const catSliderPanels = document.querySelectorAll(".stack-catslider-sec");
539
540    if (catSliderPanels.length) {
541
542      const sliderIntroTL = gsap.timeline({
543        scrollTrigger: {
544          trigger: ".regions-stack-wrapper",
545          start: "top 60%",
546          toggleActions: "play none none reverse"
547        }
548      });
549
550      sliderIntroTL.from(".re-regions-stack-header", { autoAlpha: 0, y: 70, duration: 1.2, ease: "power2.inOut" })
551        .from(".stack-catslider-container", { autoAlpha: 0, y: 70, duration: 0.8, ease: "power2.inOut" }, "-=0.5");
552
553      const catTotalCards = document.querySelectorAll(".catslider").length;
554      const carScrollDistance = window.innerWidth >= 768 ? catTotalCards * 800 : catTotalCards * 600;
555
556      gsap.set(".stack-catslider-sec:not(:first-of-type) h3", { autoAlpha: 0, y: isDesktop ? 50 : 20 });
557      gsap.set(".catslider:not(.stack-catslider-sec:first-of-type .catslider:first-of-type)", { autoAlpha: 0, y: isDesktop ? 50 : 20, pointerEvents: "none" });
558
559      gsap.set(".stack-catslider-sec:first-of-type .catslider:first-of-type", { autoAlpha: 1, y: 0, pointerEvents: "auto" });
560
561      const catSliderTL = gsap.timeline({
562        scrollTrigger: {
563          trigger: ".regions-stack-wrapper",
564          start: isDesktop ? "top 6%" : "top 40px",
565          end: `+=${carScrollDistance}`,
566          scrub: 1,
567          pin: true,
568          anticipatePin: 1,
569          pinnedContainer: ".regions-stack-wrapper"
570        }
571      });
572
573      catSliderPanels.forEach((panel, panelIndex) => {
574        const heading = panel.querySelector("h3");
575        const cards = panel.querySelectorAll(".catslider");
576
577        catSliderTL.set(panel, { className: "stack-catslider-sec active" });
578
579        if (panelIndex > 0) {
580          catSliderTL.to(heading, { autoAlpha: 1, y: 0, duration: 1 });
581        }
582
583        cards.forEach((card, cardIndex) => {
584          const isFirstCard = (panelIndex === 0 && cardIndex === 0);
585          const isLastCard = (panelIndex === catSliderPanels.length - 1) && (cardIndex === cards.length - 1);
586
587
588          if (!isFirstCard) {
589            catSliderTL.to(card, { autoAlpha: 1, y: 0, duration: 1.3, pointerEvents: "auto" }, "+=0.2")
590              .to({}, { duration: 0.5 });
591          }
592
593          if (!isLastCard) {
594            catSliderTL.to({}, { duration: 0.5 })
595              .to(card, { autoAlpha: 0, y: isDesktop ? -50 : -20, duration: 1.2, pointerEvents: "none" }, "+=0.8");
596          }
597        });
598
599        if (panelIndex < catSliderPanels.length - 1) {
600          catSliderTL.to(heading, { autoAlpha: 0, y: isDesktop ? -50 : -20, duration: 1 }, "-=0.4")
601            .set(panel, { className: "stack-catslider-sec" });
602        }
603      });
604    }
605
606    /* RE Stacked gloab card animation */
607    const stackGloabCradList = gsap.utils.toArray(".re-acc-market-content li");
608    if (stackGloabCradList.length) {
609      const stackGloabCradTL = gsap.timeline({
610        scrollTrigger: {
611          trigger: ".acc-market-map-container",
612          start: "top 18%",
613          end: "+=1000",
614          pin: true,
615          scrub: 1
616        }
617      });
618
619      stackGloabCradList.forEach((card, index) => {
620        stackGloabCradTL.to(card, {
621          autoAlpha: 1,
622          y: 0,
623          pointerEvents: "auto",
624          duration: 1
625        }
626        )
627          .to({}, { duration: 0.8 });
628
629
630        if (index < stackGloabCradList.length - 1) {
631          stackGloabCradTL.to(card, {
632            autoAlpha: 0,
633            y: -50,
634            pointerEvents: "none",
635            duration: 1
636          }
637          )
638        }
639      });
640    }
641
642    /*RE Home clip Animation */
643    const svgClipTL = gsap.timeline({
644      scrollTrigger: {
645        trigger: ".insights-re-claim-panel",
646        start: "top 25%",
647        end: "+=600",
648        scrub: 1,
649        pin: true,
650      }
651    });
652    svgClipTL.to("#home_clip_rect", {
653      attr: {
654        y: 0,
655        height: 321
656      },
657      duration: 1,
658      ease: "none"
659    })
660
661    /* ====  Pinned Animation End =====*/
662
663    let glHeaderGrp = gsap.utils.toArray(".anime-header-grp");
664    if (glHeaderGrp.length) {
665      glHeaderGrp.forEach((header, index) => {
666        let hdrGrpH2 = header.querySelector(".insights-sec-header");
667        let hdrGrpContent = header.querySelectorAll(".insights-content p");
668        let hdrGrpContentBtn = header.querySelector(".anim-insights-content-btn");
669
670        let headingTl = gsap.timeline({ ease: "power2.inOut", paused: true });
671
672        headingTl.from(hdrGrpH2, {
673          yPercent: 100,
674          autoAlpha: 0,
675          duration: 1,
676        })
677          .from(hdrGrpContent, {
678            yPercent: 100,
679            autoAlpha: 0,
680            duration: 1,
681            stagger: 0.3
682          }, "-=0.3")
683          .from(hdrGrpContentBtn, {
684            yPercent: 100,
685            autoAlpha: 0,
686            duration: 1,
687          }, "-=0.5");
688        createScrollTrigger(header, headingTl);
689      });
690    }
691
692    /* Global shipping section Animaiton */
693    let wavyTextGrp = gsap.utils.toArray(".globalship-wrapper .anime-wavytext svg, .globalship-wrapper .anime-content");
694    if (wavyTextGrp.length) {
695      wavyTextGrp.forEach(element => {
696        let tl = gsap.timeline({ ease: "power2.out", paused: true });
697        let textPath = element.querySelector("textPath");
698        const getOffset = element.getAttribute('data-start-offset');
699        gsap.set(textPath, { opacity: 0 })
700        tl.to(textPath, {
701          attr: {
702            startOffset: `${getOffset}%`
703          },
704          duration: 1,
705          autoAlpha: 1,
706        });
707
708        if (element.classList.contains("anime-content")) {
709          let emlt = element.querySelectorAll("p");
710          tl.from(emlt, {
711            y: 50,
712            autoAlpha: 0,
713            stagger: 0.3,
714            duration: 1,
715          }, "-=0.3");
716        }
717        createScrollTrigger(element, tl);
718      });
719    }
720
721    /* All Zigzag SVG line Animation  */
722    fnZigzagSVGAnime("zigzagP1");
723    fnZigzagSVGAnime("zigzagP2", 1, "top bottom", "top 60%", 1);
724    fnZigzagSVGAnime("zigzagP3");
725
726    /* Follow the Oil Section */
727    let folList = gsap.utils.toArray(".follow-oil-list li");
728
729    if (folList.length) {
730      gsap.set(".follow-oil-list li", { y: 100, autoAlpha: 0, ease: "power3", duration: 1 });
731      ScrollTrigger.batch(".follow-oil-list li", {
732        interval: 0.2, // time window (in seconds) for batching to occur.
733        batchMax: 3,   // maximum batch size (targets). Can be function-based for dynamic values
734        onEnter: batch => gsap.to(batch, { autoAlpha: 1, y: 0, stagger: { each: 0.20, grid: [1, 3] }, duration: 1, overwrite: true }),
735        onLeaveBack: batch => gsap.to(batch, { autoAlpha: 0, y: 100, duration: 0.5, overwrite: true }),
736        start: "top 80%",
737        end: "top center",
738      });
739
740      // return a gsap.set() in the listener, it'll automatically revert it after the refresh()!
741      ScrollTrigger.addEventListener("refreshInit", () => gsap.set(".follow-oil-list li", { y: 0, autoAlpha: 1 }));
742
743    }
744
745    /* Explosive expansion Section */
746    let rippleCont = document.querySelector(".insights-ripple-cont");
747    let rippleContList = gsap.utils.toArray(".insights-ripple-cont li");
748    let movingShipHld = document.querySelector(".insights-ship-moving");
749    let movingShip = document.querySelector(".insights-ship-moving img");
750    let cargoSec = document.querySelector(".cargo-container");
751
752
753    let rippleTL = gsap.timeline({
754      paused: true,
755      repeat: -1,
756      delay: 0.2,
757      scrollTrigger: {
758        trigger: ".insights-ripple-main",
759        start: "top center",
760        end: "bottom center",
761        toggleActions: "play pause resume pause", // onEnter, onLeave, onEnterBack, onLeaveBack
762      }
763    });
764    rippleTL.fromTo('.insights-ripple-img #circle3', { scale: 0, autoAlpha: 0.5, transformOrigin: "center center" },
765      {
766        scale: 1, autoAlpha: 1, duration: 1
767      })
768      .fromTo('.insights-ripple-img #circle2', { scale: 0, autoAlpha: 1, transformOrigin: "center center" },
769        {
770          scale: 1, autoAlpha: 0.7, duration: 1,
771        }, "-=0.5")
772      .fromTo('.insights-ripple-img #circle1', { scale: 0, autoAlpha: 1, transformOrigin: "center center" },
773        {
774          scale: 1, autoAlpha: 0.5, duration: 1,
775        }, "-=0.5");
776
777    if (rippleContList.length) {
778      rippleContTL = gsap.timeline({ paused: true });
779
780      rippleContTL.from(rippleContList, {
781        y: 50,
782        autoAlpha: 0,
783        duration: 1,
784        stagger: 0.3,
785        delay: 1
786      })
787      createScrollTrigger(rippleContList, rippleContTL);
788    }
789
790    function fnGetPosX(section, xPercent) {
791      const rect = section.getBoundingClientRect();
792      return {
793        x: parseInt(rect.left + rect.width * xPercent - (window.innerWidth / 2))
794      };
795    }
796
797    if (movingShip) {
798      let movingShipH = movingShip.offsetHeight;
799      let cargoSecH = cargoSec.offsetHeight;
800      let totalTL = Math.round((movingShipH + cargoSecH) / movingShipH);
801      let shipY = parseInt((window.innerHeight - (movingShipHld.clientHeight + mainNavH + 10)) / (totalTL + 1));
802
803      let shipTL = gsap.timeline({
804        rotate: 0,
805        x: 0,
806        y: 0,
807        scrollTrigger: {
808          trigger: ".insights-ship-moving-outer",
809          start: `top ${mainNavH}`,
810          end: "bottom bottom",
811          endTrigger: cargoSec,
812          pin: movingShipHld,
813          scrub: true,
814          invalidateOnRefresh: true
815        }
816      });
817
818      shipTL.to(movingShip, {
819        x: 0,
820        y: `+=${shipY}`,
821        rotation: 45,
822        duration: 1,
823        transformOrigin: "50% 15%"
824      })
825      for (let i = 1; i <= totalTL; i++) {
826        shipTL.to(movingShip, {
827          x: () => isMobile ? -fnGetPosX(cargoSec, 0.85).x : -fnGetPosX(cargoSec, 0.8).x,
828          y: `+=${shipY}`,
829          rotate: 0,
830          duration: 1,
831        },)
832      }
833    }
834
835    /* Cargo Section */
836    gsap.set(".cargo-cont-listhld li", { y: 100, autoAlpha: 0, ease: "power3", duration: 1 });
837
838    ScrollTrigger.batch(".cargo-cont-listhld li", {
839      interval: 0.2, // time window (in seconds) for batching to occur.
840      batchMax: 3,   // maximum batch size (targets). Can be function-based for dynamic values
841      onEnter: batch => gsap.to(batch, { autoAlpha: 1, y: 0, stagger: { each: 0.15, grid: [1, 3] }, duration: 1, overwrite: true }),
842      onLeaveBack: batch => gsap.to(batch, { autoAlpha: 0, y: 100, duration: 0.5, overwrite: true }),
843      start: "top 80%",
844      end: "bottom top"
845    });
846
847    // return a gsap.set() in the listener, it'll automatically revert it after the refresh()!
848    ScrollTrigger.addEventListener("refreshInit", () => gsap.set(".cargo-cont-listhld li", { y: 0, autoAlpha: 1 }));
849
850    /* Discover Slides */
851    let discSlidesArr = gsap.utils.toArray(".str-prodlist-slides .str-prodlist-slides-box");
852    let discTL = gsap.timeline({ paused: true });
853    if (discSlidesArr.length) {
854      discTL.from(discSlidesArr, {
855        y: 50,
856        autoAlpha: 0,
857        duration: 1,
858        stagger: 0.3
859      }, createScrollTrigger(discSlidesArr, discTL));
860    }
861
862
863    /* Image Reveal Animation */
864    let imgRevealList = gsap.utils.toArray(".anime-imgreveal-hld");
865    if (imgRevealList.length) {
866      imgRevealList.forEach(wrapper => {
867        let imgHld = wrapper.querySelector(".anime-imgreveal");
868        let img = wrapper.querySelector(".anime-imgreveal img");
869
870        let tl = gsap.timeline({
871          paused: true,
872          scrollTrigger: {
873            trigger: wrapper,
874            toggleActions: "play none none reverse",
875            start: "top 70%",
876          }
877        });
878        tl.set(imgHld, { autoAlpha: 1 });
879        tl.from(imgHld, 1.5, {
880          xPercent: -100,
881          ease: "power2.out"
882        });
883        tl.from(img, 1.5, {
884          xPercent: 100,
885          scale: 1.3,
886          delay: -1.5,
887          ease: "power2.out",
888          onComplete: function () {
889            const element = this.targets()[0];
890            const mainWrapper = element.closest(".anime-imgreveal-hld");
891
892            if (mainWrapper) {
893              mainWrapper.classList.add("anime-imgreveal-done");
894            }
895          },
896          onUpdate: function () {
897            const element = this.targets()[0];
898            const mainWrapper = element.closest(".anime-imgreveal-hld");
899            if (mainWrapper) {
900              mainWrapper.classList.remove("anime-imgreveal-done");
901            }
902          }
903        });
904      });
905    }
906
907    /* Other insights */
908    let otherSlider = gsap.utils.toArray(".insights-oth-slider-item figcaption");
909    let otherSliderTL = gsap.timeline({ paused: true });
910    if (otherSlider.length) {
911      otherSliderTL.from(otherSlider, {
912        y: 50,
913        autoAlpha: 0,
914        duration: 1,
915        stagger: 0.2
916      }, createScrollTrigger(otherSlider, otherSliderTL, 90, 90));
917    }
918
919    /* ======= Insights RE Animation -- Start ======== */
920
921    /* anime-content-box-grp */
922    let reContBox = gsap.utils.toArray(".anime-content-box-grp");
923    if (reContBox.length) {
924      reContBox.forEach((item, index) => {
925        let topPara = item.querySelectorAll(".re-content-box-para p");
926        let boxCont = item.querySelector(".insights-re-content-box");
927        let boxContEl = boxCont?.querySelectorAll("p, .card-profile-badge");
928        let reContBoxTl = gsap.timeline({ ease: "power2.inOut", paused: true });
929
930        reContBoxTl.from(topPara, {
931          yPercent: 100,
932          autoAlpha: 0,
933          duration: 1,
934          stagger: 0.3
935        })
936          .from(boxCont, {
937            yPercent: 50,
938            autoAlpha: 0,
939            duration: 0.6,
940          }, "-=0.5")
941          .from(boxContEl, {
942            yPercent: 50,
943            autoAlpha: 0,
944            duration: 0.8,
945            stagger: 0.2
946          }, "-=0.3");
947        createScrollTrigger(item, reContBoxTl);
948      });
949    }
950
951    /* Price counter up */
952    gsap.utils.toArray(".anime-price").forEach((el, index) => {
953      const countObj = { min: 0, max: 0 };
954
955      const targetMin = parseFloat(el.dataset.min);
956      const targetMax = parseFloat(el.dataset.max);
957
958      gsap.to(countObj, {
959        min: targetMin,
960        max: targetMax,
961        duration: 1.8,
962        ease: "power2.out",
963        delay: index * 0.15,
964        scrollTrigger: {
965          trigger: ".anime-pricing-stack",
966          // Starts 100px BEFORE the container hits 75% of the viewport (adds an entry buffer)
967          start: "top bottom",
968          end: "bottom center",
969          // play (on enter), reverse (on leave), play (on enter back), reverse (on leave back)
970          toggleActions: "play none none reverse"
971        },
972        onUpdate: function () {
973          el.innerText = `${Math.floor(countObj.min)}-${Math.floor(countObj.max)}`;
974        }
975      });
976    });
977
978    /* RE capital list Fade up*/
979    const reCapitalList = gsap.utils.toArray(".insights-re-capital-list li");
980
981    if (reCapitalList.length) {
982      gsap.set(reCapitalList, { y: 100, autoAlpha: 0, ease: "power2.inOut", duration: 1 });
983      ScrollTrigger.batch(reCapitalList, {
984        interval: 0.2, // time window (in seconds) for batching to occur.
985        batchMax: 3,   // maximum batch size (targets). Can be function-based for dynamic values
986        onEnter: batch => gsap.to(batch, { autoAlpha: 1, y: 0, stagger: { each: 0.20, grid: [1, 3] }, duration: 1, overwrite: true }),
987        onLeaveBack: batch => gsap.to(batch, { autoAlpha: 0, y: 100, duration: 0.5, overwrite: true }),
988        start: "top 80%",
989        end: "top center",
990      });
991
992      // return a gsap.set() in the listener, it'll automatically revert it after the refresh()!
993      ScrollTrigger.addEventListener("refreshInit", () => gsap.set(reCapitalList, { y: 0, autoAlpha: 1 }));
994
995    }
996
997
998    /* RE Continue para with line animation */
999    const continuePara = document.querySelectorAll(".anime-continue-para p");
1000
1001    if (continuePara.length) {
1002      const continueParaTL = gsap.timeline({ ease: "power2.inOut", paused: true });
1003
1004      continueParaTL.from(continuePara, {
1005        y: 50,
1006        autoAlpha: 0,
1007        duration: 1,
1008        stagger: 0.3
1009      })
1010        .from(".anime-continue-line", {
1011          scaleY: 0,
1012          transformOrigin: "top",
1013          duration: 1
1014        }, "-=0.2", createScrollTrigger(".anime-continue-hld", continueParaTL, 50, 60));
1015    }
1016
1017    /* Flip card floated text line animation*/
1018
1019    const textLineX = gsap.utils.toArray(".flipcard-float-text");
1020    if (textLineX.length) {
1021      gsap.to(".flipcard-float-text", {
1022        scrollTrigger: {
1023          trigger: ".anime-flipcard-float-text-wrap",
1024          start: "top 60%",
1025          toggleActions: "play none none reverse",
1026          onEnter: () => document.querySelector(".flipcard-float-text").classList.add("anime-fliptext-line"),
1027          onLeaveBack: () => document.querySelector(".flipcard-float-text").classList.remove("anime-fliptext-line")
1028        }
1029      });
1030    }
1031
1032  });
1033
1034  // End DOMContentLoaded event 
1035});
1036
1037
1038
1039
1040
1041

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.