PageSourceSearch

https://www.afimilk.com/wp-content/cache/min/1/wp-content/themes/l…/assets/js/pages/homepage.js?ver=1790060304

js afimilk.com collected 2026-09-24 20:46:00 UTC 20,161 bytes, 22 lines download raw bytes

1(()=>{"use strict";var __webpack_modules__={
1"./src/js/components/animation_handler.js":
2/*!************************************************!*\
3  !*** ./src/js/components/animation_handler.js ***!
4  \************************************************/(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   animationsHandler: () => (/* binding */ animationsHandler)\n/* harmony export */ });\n// Default animation classes\nconst defaultAnimationClasses = ['animate-on-scroll', 'animate-on-scroll--stagger',\n// Fade animations\n'reveal-fade', 'reveal-fade-up', 'reveal-fade-down', 'reveal-fade-left', 'reveal-fade-right',\n// Scale animations\n'reveal-zoom-in', 'reveal-zoom-out',\n// Slide animations\n'reveal-slide-up', 'reveal-slide-down', 'reveal-slide-left', 'reveal-slide-right',\n// Flip animations\n'reveal-flip-up', 'reveal-flip-down',\n// Special effects\n'reveal-blur', 'reveal-blur-up', 'reveal-clip-up', 'reveal-clip-left', 'reveal-clip-right',\n// Stagger (for lists/grids)\n'reveal-stagger', 'reveal-stagger-fade', 'reveal-stagger-scale', 'reveal-stagger-left', 'reveal-stagger-right',\n// Block reveal (Codrops-style)\n'reveal-block', 'reveal-block--rl', 'reveal-block--tb', 'reveal-block--bt'];\n(function (window, document, $) {\n  \"use strict\";\n\n  $(document).ready(function ($) {\n    // Run immediately\n    animationsHandler();\n\n    // Run again after a short delay to ensure layout is complete\n    setTimeout(function () {\n      animationsHandler();\n    }, 100);\n\n    // Add scroll listener for all screen sizes\n    $(window).on('scroll', function () {\n      animationsHandler();\n    });\n  });\n})(window, document, jQuery);\n\n/**\n * Animation handler:\n * Search for animation classes and activate them when the user reach them in the scroll position\n * @var animationClasses: str[] (optional, uses default list if not provided)\n */\nfunction animationsHandler(animationClasses = defaultAnimationClasses) {\n  const isMobile = typeof window !== 'undefined' && window.innerWidth <= 768;\n  // On mobile trigger animations earlier (smaller threshold) so they don't feel delayed\n  const viewportFactor = isMobile ? 0.65 : 0.85;\n  animationClasses.map(animationClass => {\n    $('.' + animationClass).each(elem => {\n      let current = $('.' + animationClass)[elem];\n      let position = $(current).offset().top;\n      if ($(document).scrollTop() > position - $(window).height() * viewportFactor) {\n        $(current).addClass('active');\n      }\n    });\n  });\n\n  // Block reveal: also trigger for elements with data-reveal-block (when using @include block-reveal in SCSS without utility class)\n  $('[data-reveal-block]').each(function () {\n    const current = $(this);\n    const position = current.offset().top;\n    if ($(document).scrollTop() > position - $(window).height() * viewportFactor) {\n      current.addClass('active');\n    }\n  });\n}\n\n//# sourceURL=webpack://wp_layer_starter/./src/js/components/animation_handler.js?")},
4"./src/js/components/initCollaborationsSlider.js":
5/*!*******************************************************!*\
6  !*** ./src/js/components/initCollaborationsSlider.js ***!
7  \*******************************************************/(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   initCollaborationsSlider: () => (/* binding */ initCollaborationsSlider)\n/* harmony export */ });\nfunction initCollaborationsSlider() {\n  const swiperElement = document.querySelector('.home-collaborations__swiper, .collaborations__swiper');\n  if (!swiperElement) {\n    return;\n  }\n\n  // Use CSS animation for marquee effect\n  const wrapper = swiperElement.querySelector('.swiper-wrapper');\n  if (wrapper) {\n    const slides = Array.from(wrapper.querySelectorAll('.swiper-slide'));\n\n    // Duplicate slides twice for seamless infinite loop\n    // First duplicate\n    slides.forEach(sli
7de => {\n      const clone = slide.cloneNode(true);\n      wrapper.appendChild(clone);\n    });\n\n    // Second duplicate for smoother loop\n    slides.forEach(slide => {\n      const clone = slide.cloneNode(true);\n      wrapper.appendChild(clone);\n    });\n\n    // Ensure wrapper is set up for animation\n    wrapper.style.display = 'flex';\n    wrapper.style.width = 'max-content';\n  }\n}\n\n//# sourceURL=webpack://wp_layer_starter/./src/js/components/initCollaborationsSlider.js?")},
7"./src/js/components/initRunningNumbers.js":
8/*!*************************************************!*\
9  !*** ./src/js/components/initRunningNumbers.js ***!
10  \*************************************************/(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   initRunningNumbers: () => (/* binding */ initRunningNumbers)\n/* harmony export */ });\nfunction initRunningNumbers() {\n  const numberElements = document.querySelectorAll('.home-running-numbers__card__number, .in-numbers__card__number');\n  if (numberElements.length === 0) {\n    return;\n  }\n  numberElements.forEach(element => {\n    const originalText = element.dataset.number || element.textContent.trim();\n    const parsed = parseNumberString(originalText);\n    if (parsed) {\n      const {\n        prefix,\n        suffix,\n        target\n      } = parsed;\n      const formattedTarget = formatNumber(target);\n      const fullText = prefix + formattedTarget + suffix;\n      element.style.setProperty('--number-width', `${fullText.length}ch`);\n      element.dataset.targetNumber = originalText;\n      element.textContent = prefix + '0' + suffix;\n    }\n  });\n  const observerOptions = {\n    threshold: 0.1,\n    rootMargin: '0px'\n  };\n  const observer = new IntersectionObserver(entries => {\n    entries.forEach(entry => {\n      if (entry.isIntersecting && !entry.target.dataset.animated) {\n        animateNumber(entry.target);\n        entry.target.dataset.animated = 'true';\n        observer.unobserve(entry.target);\n      }\n    });\n  }, observerOptions);\n  numberElements.forEach(element => {\n    observer.observe(element);\n  });\n}\nfunction animateNumber(element) {\n  const originalText = element.dataset.targetNumber || element.textContent.trim();\n  const parsed = parseNumberString(originalText);\n  if (!parsed) {\n    return;\n  }\n  const {\n    prefix,\n    suffix,\n    target\n  } = parsed;\n  if (isNaN(target)) {\n    return;\n  }\n  const isMobile = typeof window !== 'undefined' && window.innerWidth <= 768;\n  const duration = isMobile ? 600 : 2000;\n  const startTime = performance.now();\n  function updateNumber(currentTime) {\n    const elapsed = currentTime - startTime;\n    const progress = Math.min(elapsed / duration, 1);\n    const easeOut = 1 - Math.pow(1 - progress, 3);\n    const currentValue = Math.floor(target * easeOut);\n    element.textContent = prefix + formatNumber(currentValue) + suffix;\n    if (progress < 1) {\n      requestAnimationFrame(updateNumber);\n    } else {\n      element.textContent = prefix + formatNumber(target) + suffix;\n    }\n  }\n  requestAnimationFrame(updateNumber);\n}\n\n/**\n * Parse a number string that may have:\n * - An optional non-numeric prefix (e.g. \">\", \"~\", \"<\", \"≈\")\n * - A numeric part with optional commas/dots (e.g. \"10,000\", \"50\")\n * - An optional suffix after the number (e.g. \" years\", \"%\", \"+\", \" countries\")\n *\n * Returns { prefix, target, suffix } or null if no number found.\n */\nfunction parseNumberString(str) {\n  // Match: optional prefix (non-digit, non-comma, non-dot chars) + number + optional suffix\n  const match = str.match(/^([^\\d]*)([0-9][0-9,\\.]*)(.*)$/);\n  if (!match) {\n    return null;\n  }\n  const prefix = match[1] || '';\n  const numberStr = match[2].replace(/,/g, '');\n  const suffix = match[3] || '';\n  const target = parseFloat(numberStr);\n  if (isNaN(target)) {\n    return null;\n  }\n  return {\n    prefix,\n    target,\n    suffix\n  };\n}\nfunction formatNumber(num) {\n  return Math.floor(num).toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\n//# sourceURL=webpack://wp_layer_starter/./src/js/components/initRunningNumbers.js?")},
10"./src/js/components/initSolutionsSlider.js":
11/*!**************************************************!*\
12  !*** ./src/js/components/initSolutionsSlider.js ***!
13  \**************************************************/(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   initSolutionsSlider: () => (/* binding */ initSolutionsSlider)\n/* harmony export */ });\nfunction initSolutionsSlider() {\n  const swiperElement = document.querySelector('.solutions-slider__swiper');\n  if (!swiperElement) {\n    return;\n  }\n  const containerMaxWidth = 1760;\n  function getEndOffset() {\n    const viewportWidth = window.innerWidth;\n    const offset = Math.max(20, (viewportWidth - containerMaxWidth) / 2);\n    return offset;\n  }\n  const swiper = new Swiper(swiperElement, {\n    pagination: {\n      el: '.solutions-slider__pagination',\n      clickable: true\n    },\n    navigation: {\n      nextEl: '.solutions-slider__button-next',\n      prevEl: '.solutions-slider__button-prev'\n    },\n    slidesPerView: 'auto',\n    spaceBetween: 20,\n    slidesOffsetAfter: getEndOffset(),\n    breakpoints: {\n      768: {\n        slidesPerView: 'auto',\n        spaceBetween: 40,\n        slidesOffsetAfter: getEndOffset()\n      },\n      992: {\n        slidesPerView: 'auto',\n        spaceBetween: 40,\n        slidesOffsetAfter: getEndOffset()\n      },\n      1200: {\n        slidesPerView: 'auto',\n        spaceBetween: 40,\n        slidesOffsetAfter: getEndOffset()\n      },\n      1400: {\n        slidesPerView: 'auto',\n        spaceBetween: 40,\n        slidesOffsetAfter: getEndOffset()\n      }\n    }\n  });\n  function runEntryAnimation() {\n    const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n    const slides = swiperElement.querySelectorAll('.swiper-slide');
13\n    if (prefersReducedMotion) {\n      slides.forEach(slide => slide.classList.add('is-entered'));\n      return;\n    }\n    slides.forEach((slide, index) => {\n      window.setTimeout(() => {\n        slide.classList.add('is-entered');\n      }, index * 120);\n    });\n  }\n  const sectionElement = swiperElement.closest('.solutions-slider');\n  let hasRunEntryAnimation = false;\n  function runEntryAnimationOnce() {\n    if (hasRunEntryAnimation) return;\n    hasRunEntryAnimation = true;\n    runEntryAnimation();\n  }\n  if (!sectionElement || !('IntersectionObserver' in window)) {\n    runEntryAnimationOnce();\n  } else {\n    const entryObserver = new IntersectionObserver((entries, observer) => {\n      entries.forEach(entry => {\n        if (!entry.isIntersecting) return;\n        runEntryAnimationOnce();\n        observer.disconnect();\n      });\n    }, {\n      threshold: 0.25\n    });\n    entryObserver.observe(sectionElement);\n  }\n\n  // Update offset on resize\n  window.addEventListener('resize', () => {\n    swiper.params.slidesOffsetAfter = getEndOffset();\n    swiper.update();\n  });\n}\n\n//# sourceURL=webpack://wp_layer_starter/./src/js/components/initSolutionsSlider.js?")},
13"./src/js/components/initStories.js":
14/*!******************************************!*\
15  !*** ./src/js/components/initStories.js ***!
16  \******************************************/(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   initStories: () => (/* binding */ initStories)\n/* harmony export */ });\nfunction initStories() {\n  if (typeof jQuery === 'undefined') {\n    return;\n  }\n  var $ = jQuery;\n  document.addEventListener('click', function (e) {\n    var button = e.target && e.target.closest && e.target.closest('.stories__play-button');\n    if (!button) return;\n    var activeItem = document.querySelector('.stories__selector-item.is-active');\n    if (activeItem) {\n      button.setAttribute('data-video-url', activeItem.getAttribute('data-video-url') || '');\n      button.setAttribute('data-video-type', activeItem.getAttribute('data-video-type') || '');\n      button.setAttribute('data-video-youtube', activeItem.getAttribute('data-video-youtube') || '0');\n    }\n  }, true);\n  $('.stories__selector-item').on('click', function () {\n    var $item = $(this);\n    var videoUrl = $item.data('video-url');\n    var videoType = $item.data('video-type');\n    var isYoutube = String($item.data('video-youtube')) === '1';\n    var youtubeEmbedUrl = $item.data('youtube-embed-url');\n    var playText = $item.data('play-text');\n    var quoteText = $item.data('quote-text');\n    var quoteAuthor = $item.data('quote-author');\n\n    // Remove active class from all items\n    $('.stories__selector-item').removeClass('is-active');\n\n    // Add active class to clicked item\n    $item.addClass('is-active');\n\n    // Fade out and update content with fade in\n    var $videoTitle = $('.stories__video-title');\n    var $quoteText = $('.stories__quote-text');\n    var $quoteAuthor = $('.stories__quote-author');\n    var $video = $('.stories__video');\n    var $videoSource = $video.find('source');\n    var $youtubeWrapper = $('.stories__youtube-wrapper');\n    var $youtubeIframe = $('.stories__youtube-iframe');\n\n    // Fade out all text elements\n    $videoTitle.addClass('fade-out');\n    $quoteText.addClass('fade-out');\n    $quoteAuthor.addClass('fade-out');\n    setTimeout(function () {\n      // Update media (file video / YouTube)\n      if (isYoutube) {\n        if ($video.length && $videoSource.length) {\n          $videoSource.attr('src', '');\n          $videoSource.attr('type', '');\n          $video.attr('src', '');\n        }\n        $video.hide();\n        if ($youtubeIframe.length) {\n          $youtubeIframe.attr('src', youtubeEmbedUrl || '');\n        }\n        $youtubeWrapper.show();\n      } else if ($video.length && $videoSource.length) {\n        $youtubeWrapper.hide();\n        if ($youtubeIframe.length) {\n          $youtubeIframe.attr('src', '');\n        }\n        $videoSource.attr('src', videoUrl);\n        $videoSource.attr('type', videoType);\n        $video.attr('src', videoUrl);\n        $video.show();\n        $video[0].load();\n        $video[0].play();\n      }\n\n      // Update video title\n      if ($videoTitle.length && playText) {\n        $videoTitle.html('Meet ' + $('<div>').text(playText).html());\n      }\n\n      // Update quote text\n      if ($quoteText.length && quoteText) {\n        $quoteText.html(quoteText);\n      }\n\n      // Update quote author\n      if ($quoteAuthor.length && quoteAuthor) {\n        $quoteAuthor.html(quoteAuthor);\n      }\n\n      // Fade in all text elements\n      setTimeout(function () {\n        $videoTitle.removeClass('fade-out').addClass('fade-in');\n        $quoteText.removeClass('fade-out').addClass('fade-in');\n        $quoteAuthor.removeClass('fade-out').addClass('fade-in');\n\n        // Remove fade-in class after animation\n        setTimeout(function () {\n          $videoTitle.removeClass('fade-in');\n          $quoteText.removeClass('fade-in');\n          $quoteAuthor.removeClass('fade-in');\n        }, 300);\n      }, 50);\n    }, 200);\n  });\n  $(document).on('click', '.stories__play-button', function () {\n    var $activeItem = $('.stories__selector-item.is-active');\n    if (!$activeItem.length) {\n      $activeItem = $('.stories__selector-item').first();\n    }\n    var videoUrl = $activeItem.data('video-url');\n    var videoType = $activeItem.data('video-type');\n    var videoYoutube = String($activeItem.data('video-youtube')) === '1' ? '1' : '0';\n    $(this).attr('data-video-url', videoUrl || '');\n    $(this).attr('data-video-type', videoType || '');\n    $(this).attr('data-video-youtube', videoYoutube);\n  });\n}\n\n//# sourceURL=webpack://wp_layer_starter/./src/js/components/initStories.js?")},
16"./src/js/pages/homepage.js":
17/*!**********************************!*\
18  !*** ./src/js/pages/homepage.js ***!
19  \**********************************/(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _components_initRunningNumbers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../components/initRunningNumbers */ "./src/js/components/initRunningNumbers.js");\n/* harmony import */ var _components_initSolutionsSlider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/initSolutionsSlider */ "./src/js/components/initSolutionsSlider.js");\n/* harmony import */ var _components_initCollaborationsSlider__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/initCollaborationsSlider */ "./src/js/components/initCollaborationsSlider.js");\n/* harmony import */ var _components_initStories__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/initStories */ "./src/js/components/initStories.js");\n/* harmony import */ var _components_animation_handler__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/animation_handler */ "./src/js/components/animation_handler.js");\n\n\n\n\n\n(function (window, document, $) {\n  "use strict";\n\n  $(document).ready(function ($) {\n    console.log(\'Homepage.js\');\n    (0,_components_animation_handler__WEBPACK_IMPORTED_MODULE_4__.animationsHandler)();\n    var swiper = new Swiper(".mySwiper", {\n      pagination: {\n        el: ".swiper-pagination",\n        clickable: true\n      },\n      threshold: 8,\n      centeredSlides: true,\n      centeredSlidesBounds: true,\n      navigation: {\n        nextEl: \'.swiper-button-next\',\n        prevEl: \'.swiper-button-prev\'\n      }\n    });\n\n    // Initialize running numbers animation\n    (0,_components_initRunningNumbers__WEBPACK_IMPORTED_MODULE_0__.initRunningNumbers)();\n\n    // Initialize solutions slider\n    (0,_components_initSolutionsSlider__WEBPACK_IMPORTED_MODULE_1__.initSolutionsSlider)();\n\n    // Initialize collaborations slider\n    (0,_components_initCollaborationsSlider__WEBPACK_IMPORTED_MODULE_2__.initCollaborationsSlider)();\n\n    // Initialize stories selector\n    (0,_components_initStories__WEBPACK_IMPORTED_MODULE_3__.initStories)();\n  });\n})(window, document, jQuery);\n\n//# sourceURL=webpack://wp_layer_starter/./src/js/pages/homepage.js?')},
19"./src/scss/pages/homepage.scss":
20/*!**************************************!*\
21  !*** ./src/scss/pages/homepage.scss ***!
22  \**************************************/(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n\n\n//# sourceURL=webpack://wp_layer_starter/./src/scss/pages/homepage.scss?")}
22},__webpack_module_cache__={};function __webpack_require__(e){var n=__webpack_module_cache__[e];if(void 0!==n)return n.exports;var t=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e](t,t.exports,__webpack_require__),t.exports}__webpack_require__.d=(e,n)=>{for(var t in n)__webpack_require__.o(n,t)&&!__webpack_require__.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},__webpack_require__.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__("./src/scss/pages/homepage.scss");var __webpack_exports__=__webpack_require__("./src/js/pages/homepage.js")})()

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.