1"use strict"; 2 3/*-------------------------------------------------------------- 4 [TABLE OF CONTENTS] 5 -------------------------------------------------------------- 6 01. CUSTOM UTILITIES 7 02. PRELOADER 8 03. HEADER SCROLL 9 04. SIDEBAR TOGGLE 10 05. MENU SUBMENU TOGGLE 11 06. SCROLL TO TOP (ARROW) 12 07. SPLIDE SLIDERS 13 - Testimonial Carousel 14 - Feedback Carousel 15 - Autoscroll Carousel 16 - Counter Carousel with Counter Display 17 - Vertical Carousel with Active States 18 - Four Column Slider (Multiple IDs) 19 - Main & Thumbnail Carousel Sync 20 08. JQUERY COUNTER ANIMATION 21 09. SEARCH WRAP SLIDE 22 10. AOS INIT 23 11. GLIGHTBOX INIT 24 12. DARK MODE 25-------------------------------------------------------------------*/ 26 27/*---------------------------------------------------------- 28 01. CUSTOM UTILITIES 29------------------------------------------------------------*/ 30(function ($) { 31 // Custom jQuery Utilities 32 $.fn.is_exist = function () { 33 return this.length > 0; 34 }; 35 36 $(function () { 37 /*---------------------------------------------------------- 38 02. PRELOADER 39 ------------------------------------------------------------*/ 40 setTimeout(function () { 41 if ($('.preloader').length) { 42 $('.preloader').fadeOut(200, function () { 43 $(this).remove(); 44 }); 45 } 46 }, 200); 47 48 /*---------------------------------------------------------- 49 03. HEADER SCROLL 50 ------------------------------------------------------------*/ 51 function handleScroll() { 52 var $headerWrapper = $(".header-wrapper"); 53 if ($headerWrapper.length) { 54 var upperHeaderHeight = $(".upper-header").length ? $(".upper-header").outerHeight() : 0; 55 56 if ($(window).scrollTop() > upperHeaderHeight) { 57 $headerWrapper.addClass("scroll-header"); 58 } else { 59 $headerWrapper.removeClass("scroll-header"); 60 } 61 } 62 } 63 $(window).on("scroll", handleScroll); 64 handleScroll(); 65 66 /*---------------------------------------------------------- 67 04. SIDEBAR TOGGLE 68 ------------------------------------------------------------*/ 69 $(".mobile-menu-trigger").on("click", function (e) { 70 e.preventDefault(); 71 $(".menu-block, .menu-overlay").addClass("active"); 72 }); 73 $(".menu-close, .menu-overlay").on("click", function () { 74 $(".menu-block, .menu-overlay").removeClass("active"); 75 }); 76 77 /*---------------------------------------------------------- 78 05. MENU SUBMENU TOGGLE 79 ------------------------------------------------------------*/ 80 $(".nav-item-has-children > a").on("click", function (e) { 81 e.preventDefault(); 82 const $parent = $(this).parent(); 83 const $submenu = $parent.find(".sub-menu").first(); 84 $(".sub-menu").not($submenu).removeClass("show"); 85 $(".mega-menu-sub").removeClass("show"); 86 $submenu.toggleClass("show"); 87 }); 88 $(".mega-menu-header").on("click", function (e) { 89 e.preventDefault(); 90 const $mega = $(this).next(".mega-menu-sub"); 91 $(".mega-menu-sub").not($mega).removeClass("show"); 92 $(".sub-menu").removeClass("show"); 93 $mega.toggleClass("show"); 94 }); 95 96 /*---------------------------------------------------------- 97 06. SCROLL TO TOP (ARROW) 98 ------------------------------------------------------------*/ 99 const progressPath = document.querySelector('.arrow-round-wrap path'); 100 const arrowWrap = document.querySelector('.arrow-round-wrap'); 101 102 if (progressPath && arrowWrap) { 103 const pathLength = progressPath.getTotalLength(); 104 progressPath.style.strokeDasharray = `${pathLength} ${pathLength}`; 105 progressPath.style.strokeDashoffset = pathLength; 106 progressPath.style.transition = 'stroke-dashoffset 10ms linear'; 107 108 const updateProgress = () => { 109 const scroll = window.scrollY; 110 const height = document.documentElement.scrollHeight - window.innerHeight; 111 const progress = pathLength - (scroll * pathLength / height); 112 progressPath.style.strokeDashoffset = progress; 113 arrowWrap.classList.toggle('active-arrow', scroll > 50); 114 }; 115 116 updateProgress(); 117 window.addEventListener('scroll', updateProgress); 118 arrowWrap.addEventListener('click', e => { 119 e.preventDefault(); 120 window.scrollTo({ top: 0, behavior: 'smooth' }); 121 }); 122 } 123 124 /*---------------------------------------------------------- 125 07. SPLIDE SLIDERS 126 ------------------------------------------------------------*/ 127 if (typeof Splide === 'function') { 128 const mountSplide = (selector, options, extensions) => { 129 const el = document.querySelector(selector); 130 if (el) { 131 const instance = new Splide(el, options); 132 if (extensions) instance.mount(extensions); 133 else instance.mount(); 134 } 135 }; 136 137 // Testimonial Carousel
138 mountSplide('#testimonial-carousel', { 139 type: 'fade', perPage: 1, arrows: true, pagination: true 140 }); 141 142 // Feedback Carousel 143 mountSplide('#feedback-carousel', { 144 type: 'loop', perPage: 3, gap: 15, arrows: true, pagination: true, 145 breakpoints: { 1024: { perPage: 2 }, 768: { perPage: 1 } } 146 }); 147 148 // Course Carousel 149 mountSplide('#course-carousel', { 150 type: 'loop', perPage: 4, perMove: 1, gap: 20, arrows: true, pagination: true, 151 breakpoints: { 1280: { perPage: 3 }, 1024: { perPage: 2 }, 768: { perPage: 1 } } 152 }); 153 154 // Autoscroll Carousel 155 mountSplide('#autoscroll-carousel', { 156 type: 'loop', drag: 'free', focus: 'center', perPage: 6, pagination: false, 157 breakpoints: { 1024: { perPage: 6 }, 768: { perPage: 4 }, 480: { perPage: 2 } }, 158 autoScroll: { speed: .75 } 159 }, window.splide.Extensions); 160 161 // Counter Carousel with Dynamic Counter 162 document.querySelectorAll('.counter-carousel').forEach((counterEl) => { 163 const counterSplide = new Splide(counterEl, { 164 type: 'loop', 165 perPage: 1, 166 autoplay: true, 167 pauseOnHover: true, 168 arrows: true, 169 pagination: false, 170 }); 171 172 let counterWrapper = counterEl.querySelector('.counter-carousel-counter'); 173 let counterSpan; 174 175 counterSplide.on('mounted', () => { 176 const totalSlides = counterSplide.length; 177 178 if (!counterWrapper) { 179 counterWrapper = document.createElement('div'); 180 counterWrapper.className = 'counter-carousel-counter'; 181 182 counterSpan = document.createElement('span'); 183 counterSpan.className = 'display4-size pe-1'; 184 counterSpan.textContent = '1'; 185 186 counterWrapper.appendChild(counterSpan); 187 counterWrapper.append(`/${totalSlides}`); 188 189 counterEl.appendChild(counterWrapper); 190 } else { 191 counterSpan = counterWrapper.querySelector('span.display4-size'); 192 } 193 194 if (counterSpan) { 195 counterSpan.textContent = counterSplide.index + 1; 196 } 197 }); 198 199 counterSplide.on('move', () => { 200 if (counterSpan) { 201 counterSpan.textContent = counterSplide.index + 1; 202 } 203 }); 204 205 counterSplide.mount(); 206 }); 207 208 // Vertical Carousel 209 const bannerEl = document.querySelector('#banner-carousel'); 210 const vertical = document.querySelector('#vertical-carousel'); 211 let bannerSplide; 212 213 if (bannerEl) { 214 bannerSplide = new Splide(bannerEl, { 215 type: 'fade', perPage: 1, autoplay: false, pauseOnHover: false, 216 arrows: false, pagination: false, rewind: true, speed: 600 217 }); 218 bannerSplide.mount(); 219 } 220 221 if (vertical) { 222 const verticalSplide = new Splide(vertical, { 223 direction: 'ttb', height: '140px', perPage: 3, perMove: 1, autoplay: true, 224 interval: 3000, arrows: false, pagination: true, drag: false 225 }); 226 227 verticalSplide.on('mounted move', () => { 228 document.querySelectorAll('.splide__slide') 229 .forEach(slide => slide.classList.remove('slider-active', 'slider-active-1', 'slider-active-2')); 230 231 const slides = verticalSplide.Components.Slides.get(); 232 const [a, b, c] = [0, 1, 2].map(i =>
232 slides[(verticalSplide.index + i) % slides.length]); 233 if (a) a.slide.classList.add('slider-active-2'); 234 if (b) b.slide.classList.add('slider-active-1'); 235 if (c) c.slide.classList.add('slider-active'); 236 237 if (bannerSplide) { 238 bannerSplide.go(verticalSplide.index); 239 } 240 }); 241 242 verticalSplide.mount(); 243 } 244 245 // Four Column Carousel (Multiple) 246 const dir = localStorage.getItem('direction') === 'rtl' ? 'rtl' : 'ltr'; 247 document.querySelectorAll('.four-slider').forEach(el => { 248 new Splide(`#${el.id}`, { 249 type: 'loop', autoplay: true, gap: 10, perPage: 4, direction: dir, 250 breakpoints: { 1024: { perPage: 3 }, 768: { perPage: 2 }, 480: { perPage: 1 } } 251 }).mount(); 252 }); 253 254 // Main + Thumbnail Carousel 255 const mainCarousel = document.querySelector('#main-carousel'); 256 const thumbsCarousel = document.querySelector('#thumbnail-carousel'); 257 258 if (mainCarousel && thumbsCarousel) { 259 const main = new Splide(mainCarousel, { 260 type: 'fade', rewind: true, perPage: 1, autoplay: false, 261 pauseOnHover: true, interval: 5000, direction: dir, 262 arrows: false, pagination: false, speed: 1000 263 }); 264 265 const thumbs = new Splide(thumbsCarousel, { 266 gap: 10, perPage: 3, rewind: true, height: '120px', autoWidth: true, pagination: false, isNavigation: true, 267 direction: dir, 268 breakpoints: { 1200: { perPage: 2 }, 768: { perPage: 2 }, 480: { perPage: 1 } } 269 }); 270 271 main.sync(thumbs).mount(); 272 thumbs.mount(); 273 } 274 275 // Five Thumbnail Carousel 276 const fivemainCarousel = document.querySelector('#five-carou
276sel'); 277 const fivethumbsCarousel = document.querySelector('#five-thumbnail-carousel'); 278 279 if (fivemainCarousel && fivethumbsCarousel) { 280 const fivemain = new Splide(fivemainCarousel, { 281 type: 'fade', rewind: true, perPage: 1, autoplay: false, 282 pauseOnHover: true, interval: 5000, direction: dir, 283 arrows: false, pagination: false, speed: 1000 284 }); 285 286 const fivethumbs = new Splide(fivethumbsCarousel, { 287 gap: 20, perPage: 3, rewind: true, autoWidth: false, pagination: false, isNavigation: true, 288 direction: dir, 289 breakpoints: { 1200: { perPage: 2 }, 768: { perPage: 2 }, 480: { perPage: 1 } } 290 }); 291 292 fivemain.sync(fivethumbs).mount(); 293 fivethumbs.mount(); 294 } 295 } 296 297 /*---------------------------------------------------------- 298 08. JQUERY COUNTER ANIMATION 299 ------------------------------------------------------------*/ 300 const $counterSection = $('#lc-counter'); 301 if ($counterSection.length && typeof $ === 'function') { 302 let animated = false; 303 $(window).on('scroll', function () { 304 const offset = $counterSection.offset().top - window.innerHeight; 305 if (!animated && $(window).scrollTop() > offset) { 306 $('.lc-counter').each(function () { 307 const $el = $(this); 308 const target = parseFloat($el.data('percentage')); 309 $({ countNum: 0 }).animate({ countNum: target }, { 310 duration: 2000, 311 step: function (now) { 312 $el.text(Number.isInteger(target) ? Math.floor(now).toLocaleString() : now.toFixed(1)); 313 }, 314 complete: function () { 315 $el.text(Number.isInteger(target) ? target.toLocaleString() : target); 316 } 317 }); 318 }); 319 animated = true; 320 } 321 }); 322 } 323 /*---------------------------------------------------------- 324 09. SEARCH WRAP SLIDE 325 ------------------------------------------------------------*/ 326 const $searchBtn = $('#search-btn'); 327 const $searchWrap = $('.search-wrap'); 328 const $closeBtn = $('#close-search'); 329 330 $searchBtn.on('click', function () { 331 $searchWrap.addClass('active'); 332 }); 333 334 $closeBtn.on('click', function () { 335 $searchWrap.removeClass('active'); 336 }); 337 338 /*---------------------------------------------------------- 339 10. AOS INIT 340 ------------------------------------------------------------*/ 341 if (typeof AOS !== 'undefined') { 342 AOS.init({ duration: 800, once: true }); 343 } 344 345 /*---------------------------------------------------------- 346 11. GLIGHTBOX INIT 347 ------------------------------------------------------------*/ 348 const lightbox = GLightbox({ 349 selector: '.glightbox' 350 }); 351 /*---------------------------------------------------------- 352 12. DARK MODE (DISABLED) 353 ------------------------------------------------------------*/ 354 const btn = document.getElementById("dark-switch"); 355 document.documentElement.classList.remove("dark"); 356 localStorage.setItem("theme", "light"); 357 if (btn) { 358 btn.style.display = "none"; 359 } 360 }); 361})(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.