PageSourceSearch

https://www.sedgwick.com/wp-content/themes/sedgwick/blocks/2025/la…/labor-access-animation.js?ver=1790704707

js sedgwick.com collected 2026-10-02 02:59:15 UTC 7,783 bytes, 266 lines download raw bytes

1const LAA_HELPER = window.sedgwickAnimationHelper || {};
2const LAA_COUNT_UP = typeof LAA_HELPER.countUp === "function" ? LAA_HELPER.countUp : null;
3const LAA_EASE_OUT_CUBIC = typeof LAA_HELPER.easeOutCubic === "function" ? LAA_HELPER.easeOutCubic : laa_easeOutCubic;
4
5document.addEventListener("DOMContentLoaded", () => {
6    const blocks = document.querySelectorAll(".labor-access-animation-block");
7    if (!blocks.length) return;
8    blocks.forEach(laa_initBlock);
9});
10
11function laa_initBlock(block) {
12    const rows = [
13        laa_createRow(block, 1),
14        laa_createRow(block, 2),
15        laa_createRow(block, 3)
16    ].filter(Boolean);
17
18    if (!rows.length) return;
19
20    const mm = typeof window.matchMedia === "function";
21    const prefersReducedMotion = mm && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
22    const isMobile = mm && window.matchMedia("(max-width: 1023px)").matches;
23    const body = document.body;
24    const isEditor = body && (body.classList.contains("wp-admin") || body.classList.contains("block-editor-page"));
25    const shouldAnimate = !prefersReducedMotion && !isEditor;
26
27    if (!shouldAnimate) {
28        laa_revealAllImmediate(rows);
29        return;
30    }
31
32    const config = laa_getTimingConfig(block);
33
34    rows.forEach((row) => {
35        if (row.trackInner) {
36            const rect = row.trackInner.getBoundingClientRect();
37            row.finalWidth = rect.width;
38            row.trackInner.style.width = "0px";
39        }
40    });
41
42    block.classList.add("laa-animated");
43
44    if (isMobile) {
45        laa_observeRowsIndividually(rows, config);
46    } else {
47        laa_observeBlockSequence(block, rows, config);
48    }
49}
50
51function laa_createRow(block, index) {
52    const wrapper = block.querySelector(`.chart-row-${index}`);
53    if (!wrapper) return null;
54
55    const trackInner = wrapper.querySelector(`.chart-row-${index}-track-inner`);
56    const numberEl = wrapper.querySelector(`.chart-row-${index}-number`);
57
58    let finalNumberText = null;
59    let numberValue = null;
60
61    if (numberEl) {
62        finalNumberText = numberEl.textContent.trim();
63        const match = finalNumberText.match(/(-?[\d.]+)/);
64        if (match) {
65            const parsed = parseFloat(match[1]);
66            if (!isNaN(parsed)) {
67                numberValue = parsed;
68            }
69        }
70    }
71
72    return {
73        wrapper,
74        trackInner,
75        numberEl,
76        finalNumberText,
77        numberValue,
78        finalWidth: null,
79        hasPlayed: false
80    };
81}
82
83function laa_getTimingConfig(block) {
84    const styles = getComputedStyle(block);
85    return {
86        countDuration: laa_parseTime(styles.getPropertyValue("--laa-count-duration"), 1000),
87        barDuration: laa_parseTime(styles.getPropertyValue("--laa-bar-duration"), 1000),
88        stagger: laa_parseTime(styles.getPropertyValue("--laa-stagger"), 400)
89    };
90}
91
92function laa_parseTime(value, fallback) {
93    if (!value) return fallback;
94    const trimmed = value.toString().trim();
95    if (!trimmed) return fallback;
96    if (trimmed.endsWith("ms")) {
97        const n = parseFloat(trimmed.slice(0, -2));
98        return Number.isFinite(n) ? n : fallback;
99    }
100    if (trimmed.endsWith("s")) {
101        const n = parseFloat(trimmed.slice(0, -1));
102        return Number.isFinite(n) ? n * 1000 : fallback;
103    }
104    const n = parseFloat(trimmed);
105    return Number.isFinite(n) ? n : fallback;
106}
107
108function laa_observeBlockSequence(block, rows, config) {
109    if (!("IntersectionObserver" in window)) {
110        laa_runSequence(rows, config);
111        return;
112    }
113
114    let started = false;
115
116    const observer = new IntersectionObserver(
117        (entries) => {
118            entries.forEach((entry) => {
119                if (!started && entry.isIntersecting) {
120                    started = true;
121                    observer.unobserve(block);
122                    laa_runSequence(rows, config);
123                }
124            });
125        },
126        { threshold: 0.35 }
127    );
128
129    observer.observe(block);
130}
131
132function laa_observeRowsIndividually(rows, config) {
133    if (!("IntersectionObserver" in window)) {
134        rows.forEach((row) => laa_playRow(row, config));
135        return;
136    }
137
138    const observer = new IntersectionObserver(
139        (entries) => {
140            entries.forEach((entry) => {
141                if (entry.isIntersecting) {
142                    const row = rows.find((r) => r.wrapper === entry.target);
143                    if (row) {
144                        laa_playRow(row, config);
145                        observer.unobserve(entry.target);
146                    }
147                }
148            });
149        },
150        { threshold: 0.35 }
151    );
152
153    rows.forEach((row) => observer.observe(row.wrapper));
154}
155
156async function laa_runSequence(rows, config) {
157    for (const row of rows) {
158        await laa_playRow(row, config);
159        await laa_wait(config.stagger);
160    }
161}
162
163async function laa_playRow(row, config) {
164    if (!row || row.hasPlayed) return;
165    row.hasPlayed = true;
166
167    row.wrapper.style.opacity = "1";
168
169    const tasks = [];
170
171    if (row.trackInner && typeof row.finalWidth === "number") {
172        tasks.push(laa_animateBar(row.trackInner, row.finalWidth, config.barDuration));
173    }
174
175    if (row.numberEl && typeof row.numberValue === "number") {
176        row.numberEl.textContent = "0%";
177        tasks.push(laa_runCountUp(row.numberEl, row.numberValue, config.countDuration));
178    }
179
180    if (!tasks.length) return;
181    await Promise.all(tasks);
182}
183
184function laa_revealAllImmediate(rows) {
185    rows.forEach((row) => {
186        if (!row) return;
187        row.wrapper.style.opacity = "1";
188        if (row.numberEl && row.finalNumberText != null) {
189            row.numberEl.textContent = row.finalNumberText;
190        }
191    });
192}
193
194function laa_animateBar(element, finalWidth, duration) {
195    return new Promise((resolve) => {
196        const startTime = performance.now();
197
198        function step(now) {
199            const elapsed = now - startTime;
200            const progress = Math.min(elapsed / duration, 1);
201            const eased = laa_easeOutCubic(progress);
202            const currentWidth = finalWidth * eased;
203            element.style.width = currentWidth + "px";
204
205            if (progress < 1) {
206                requestAnimationFrame(step);
207            } else {
208                element.style.width = finalWidth + "px";
209                resolve();
210            }
211        }
212
213        requestAnimationFrame(step);
214    });
215}
216
217function laa_runCountUp(el, finalValue, duration) {
218    if (!el) {
219        return Promise.resolve();
220    }
221
222    if (LAA_COUNT_UP) {
223        return LAA_COUNT_UP(el, {
224            end: finalValue,
225            duration,
226            formatter: (value) => Math.round(value) + "%",
227            easing: LAA_EASE_OUT_CUBIC,
228        }).then(() => {
229            el.textContent = finalValue + "%";
230        });
231    }
232
233    return laa_countUpFallback(el, finalValue, duration);
234}
235
236function laa_countUpFallback(el, finalValue, duration) {
237    return new Promise((resolve) => {
238        let current = 0;
239        const startTime = performance.now();
240
241        function step(now) {
242            const elapsed = now - startTime;
243            const progress = Math.min(elapsed / duration, 1);
244            const eased = laa_easeOutCubic(progress);
245            const value = finalValue * eased;
246
247            if (progress < 1) {
248                el.textContent = Math.round(value) + "%";
249                requestAnimationFrame(step);
250            } else {
251                el.textContent = finalValue + "%";
252                resolve();
253            }
254        }
255
256        requestAnimationFrame(step);
257    });
258}
259
260function laa_easeOutCubic(t) {
261    return 1 - Math.pow(1 - t, 3);
262}
263
264function laa_wait(ms) {
265    return new Promise((res) => setTimeout(res, ms));
266}

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.