PageSourceSearch

https://eitrawmaterials.eu/themes/custom/eitrm/components/stats/stats.js?tlpf0o

js eitrawmaterials.eu collected 2026-09-24 09:10:58 UTC 8,383 bytes, 282 lines download raw bytes

1((document, Drupal) => {
2  let rootMargin = '0px';
3
4  const desktopBP = window.matchMedia('(min-width: 1440px)');
5  const largeTabletBP = window.matchMedia('(min-width: 1200px)');
6  const tabletBP = window.matchMedia('(min-width: 768px)');
7  const mobileBP = window.matchMedia('(min-width: 330px)');
8
9  if (mobileBP.matches) {
10    rootMargin = '0px 0px -13% 0px';
11  }
12  if (tabletBP.matches) {
13    rootMargin = '0px 0px -13% 0px';
14  }
15  if (largeTabletBP.matches) {
16    rootMargin = '0px 0px -27% 0px';
17  }
18  if (desktopBP.matches) {
19    rootMargin = '0px 0px -27% 0px';
20  }
21
22  const observer = new IntersectionObserver(
23    // eslint-disable-next-line no-shadow
24    (entries, observer) => {
25      entries.forEach((entry) => {
26        if (entry.isIntersecting) {
27          const stats = entry.target.querySelectorAll(
28            '.dxp-stats__stat-element__inner__number',
29          );
30          const animateSpeed = entry.target.dataset.animateSpeed
31            ? entry.target.dataset.animateSpeed
32            : 2000;
33          const easingType = entry.target.dataset.animateEasing
34            ? entry.target.dataset.animateEasing
35            : 'linear';
36          const { locale } = entry.target.dataset;
37          // eslint-disable-next-line no-use-before-define
38          const easingFunction = chooseEasingFunction(easingType);
39          stats.forEach((stat) => {
40            // eslint-disable-next-line no-use-before-define
41            animateNumber(
42              stat,
43              0,
44              stat.dataset.number,
45              stat.dataset.suffix,
46              animateSpeed,
47              easingFunction,
48              locale,
49              stat.dataset.decimalCount,
50            );
51          });
52          observer.unobserve(entry.target);
53        }
54      });
55    },
56    {
57      rootMargin,
58      threshold: 0.001,
59    },
60  );
61
62  function init() {
63    const dxpStats = document.querySelectorAll('.js--dxp-stats-animated');
64    const defaultLocale = 'en-US';
65
66    if (dxpStats.length > 0) {
67      dxpStats.forEach((dxpStat) => {
68        if (!dxpStat.dataset.animationStarted) {
69          const stats = dxpStat.querySelectorAll(
70            '.dxp-stats__stat-element__inner__number',
71          );
72          const locale = dxpStat.dataset.locale
73            ? dxpStat.dataset.locale
74            : defaultLocale;
75          stats.forEach((stat) => {
76            // eslint-disable-next-line no-use-before-define
77            resetNumber(stat, locale);
78          });
79          observer.observe(dxpStat);
80          dxpStat.dataset.animationStarted = '1';
81        }
82      });
83    }
84  }
85
86  Drupal.behaviors.statsAnimation = {
87    attach() {
88      init();
89    },
90  };
91
92  document.addEventListener(
93    'DOMContentLoaded',
94    // eslint-disable-next-line func-names
95    function () {
96      init();
97    },
98    { once: true },
99  );
100
101  function chooseEasingFunction(easingType) {
102    switch (easingType) {
103      case 'linear':
104        // eslint-disable-next-line no-use-before-define
105        return linear;
106      case 'easeOut':
107        // eslint-disable-next-line no-use-before-define
108        return easeOutCubic;
109      case 'easeIn':
110        // eslint-disable-next-line no-use-before-define
111        return easeInCubic;
112      case 'easeInOutCubic':
113        // eslint-disable-next-line no-use-before-define
114        return easeInOutCubic;
115      default:
116        // eslint-disable-next-line no-use-before-define
117        return linear; // Default to linear if not specified
118    }
119  }
120
121  function linear(t) {
122    return t;
123  }
124
125  function easeOutCubic(t) {
126    return 1 - (1 - t) ** 3;
127  }
128
129  function easeInCubic(t) {
130    return t * t * t;
131  }
132
133  function easeInOutCubic(t) {
134    return t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2;
135  }
136
137  function parseNumber(content, locale) {
138    // eslint-disable-next-line no-use-before-define
139    const { decimalSeparator, thousandSeparator } = detectSeparators(locale);
140    // Escape special characters for regex use
141    const escapedThousand = thousandSeparator.replace(
142      /[.*+?^${}()|[\]\\]/g,
143      '\\$&',
144    );
145    const escapedDecimal = decimalSeparator.replace(
146      /[.*+?^${}()|[\]\\]/g,
147      '\\$&',
148    );
149    let decimalCount = 0;
150
151    // Regex to find the numeric part with potential formatting and an optional suffix
152    const numberRegex = new RegExp(
153      `([\\d${escapedThousand}${escapedDecimal}]+)([^\\d]*)`,
154    );
155
156    // Extract the numeric part and any suffix
157    const result = content.match(numberRegex);
158    let value = 0;
159    let suffix = '';
160
161    if (result) {
162      let numberPart = result[1];
163      // eslint-disable-next-line prefer-destructuring
164      suffix = result[2];
165
166      // Replace thousand separator and fix decimal separator for parsing
167      numberPart = numberPart.replace(new RegExp(escapedThousand, 'g'), ''); // Remove thousand separators
168      numberPart = numberPart.replace(new RegExp(escapedDecimal, 'g'), '.'); // Ensure correct decimal separator for parsing
169      decimalCount = numberPart.includes('.')
170        ? numberPart.split('.')[1].length
171        : 0;
172
173      // Parse the number
174      value = parseFloat(numberPart);
175    }
176    return { value, suffix, decimalCount };
177  }
178
179  function animateNumber(
180    element,
181    start,
182    end,
183    suffix,
184    duration,
185    easingFunc,
186    locale,
187    digits,
188  ) {
189    let startTime = null;
190
191    function animation(currentTime) {
192      if (!startTime) startTime = currentTime;
193      const elapsedTime = currentTime - startTime;
194      const progress = Math.min(elapsedTime / duration, 1);
195      const easedProgress = easingFunc(progress); // Apply the easing function
196      const currentNumber = easedProgress * (end - start) + start;
197
198      // element.textContent = customFormatNumber(currentNumber, { locale: 'de-DE' }) + suffix;
199      element.textContent =
200        // eslint-disable-next-line no-use-before-define
201        customFormatNumber(currentNumber, {
202          locale,
203          minimumFractionDigits: digits,
204          maximumFractionDigits: digits,
205        }) + suffix;
206
207      if (elapsedTime < duration) {
208        requestAnimationFrame(animation);
209      }
210    }
211
212    requestAnimationFrame(animation);
213  }
214
215  function customFormatNumber(value, config) {
216    const {
217      locale,
218      useGrouping = true,
219      minimumFractionDigits = 0,
220      maximumFractionDigits = 0,
221    } = config;
222    const options = {
223      style: 'decimal',
224      useGrouping,
225      minimumFractionDigits,
226      maximumFractionDigits,
227    };
228
229    const formatter = new Intl.NumberFormat(locale, options);
230    return formatter.format(value);
231  }
232
233  function resetNumber(element, locale) {
234    const originalContent = element.textContent;
235    const parsedNumber = parseNumber(originalContent, locale);
236    element.style.opacity = '1';
237    element.dataset.number = parsedNumber.value.toString();
238    element.dataset.decimalCount = parsedNumber.decimalCount.toString();
239    element.dataset.suffix = parsedNumber.suffix;
240    // eslint-disable-next-line no-use-before-define
241    element.textContent = formatNumber(0) + parsedNumber.suffix;
242  }
243
244  function formatNumber(number) {
245    return number.toLocaleString();
246  }
247
248  function detectSeparators(locale) {
249    const number = 1234567.89; // Use a sample number that includes both a thousand and decimal separator
250    const formattedNumber = new Intl.NumberFormat(locale).format(number);
251
252    // Extract the non-numeric characters from the formatted string
253    // Assuming the formatted number includes a decimal and thousands separator
254    const match = formattedNumber.match(/(\D+)/g);
255
256    // Heuristic: Assume the last group of non-digit characters is the decimal separator,
257    // and the first (if any) is the thousand separator
258    if (match && match.length > 0) {
259      const separators = {
260        thousandSeparator: match.length > 1 ? match[0] : '',
261        decimalSeparator: match[match.length - 1],
262      };
263
264      // Clean up any extra characters that might be in the separators
265      separators.thousandSeparator = separators.thousandSeparator.replace(
266        /\s/g,
267        '',
268      ); // Remove any whitespace
269      separators.decimalSeparator = separators.decimalSeparator.replace(
270        /\s/g,
271        '',
272      ); // Remove any whitespace
273
274      return separators;
275    }
276
277    return {
278      thousandSeparator: '',
279      decimalSeparator: '',
280    };
281  }
282})(document, Drupal);

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.