(() => { function pad2(value) { return String(value).padStart(2, "0"); } function splitCountdown(ms) { const totalSeconds = Math.max(0, Math.floor(ms / 1000)); const days = Math.floor(totalSeconds / 86400); const hours = Math.floor((totalSeconds % 86400) / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; return { days, hours, minutes, seconds }; } function setAnimatedValue(node, nextValue) { if (!node) { return; } if (node.textContent === nextValue) { return; } node.textContent = nextValue; node.classList.remove("is-updated"); void node.offsetWidth; node.classList.add("is-updated"); } function initTimer(widget) { const targetIso = widget.dataset.countdownTarget; const startedLabel = widget.dataset.countdownStarted || ""; const toggle = widget.querySelector("[data-countdown-toggle]"); const popover = widget.querySelector("[data-countdown-popover]"); const subline = widget.querySelector("[data-countdown-subline]"); const daysNode = widget.querySelector("[data-countdown-days]"); const hoursNode = widget.querySelector("[data-countdown-hours]"); const minutesNode = widget.querySelector("[data-countdown-minutes]"); const secondsNode = widget.querySelector("[data-countdown-seconds]"); if (!targetIso || !toggle || !popover || !subline || !daysNode || !hoursNode || !minutesNode || !secondsNode) { return; } const targetMs = Date.parse(targetIso); if (Number.isNaN(targetMs)) { subline.textContent = "--"; return; } const update = () => { const now = Date.now(); const delta = targetMs - now; if (delta <= 0) { setAnimatedValue(daysNode, "0"); setAnimatedValue(hoursNode, "00"); setAnimatedValue(minutesNode, "00"); setAnimatedValue(secondsNode, "00"); subline.textContent = startedLabel; return; } const parts = splitCountdown(delta); setAnimatedValue(daysNode, String(parts.days)); setAnimatedValue(hoursNode, pad2(parts.hours)); setAnimatedValue(minutesNode, pad2(parts.minutes)); setAnimatedValue(secondsNode, pad2(parts.seconds)); }; const close = () => { popover.hidden = true; toggle.setAttribute("aria-expanded", "false"); }; const open = () => { popover.hidden = false; toggle.setAttribute("aria-expanded", "true"); update(); }; toggle.addEventListener("click", (event) => { event.preventDefault(); if (popover.hidden) { open(); } else { close(); } }); document.addEventListener("click", (event) => { if (!widget.contains(event.target)) { close(); } }); document.addEventListener("keydown", (event) => { if (event.key === "Escape") { close(); } }); update(); window.setInterval(update, 1000); } document.addEventListener("DOMContentLoaded", () => { const widgets = document.querySelectorAll(".toolbar-timer"); widgets.forEach(initTimer); }); })();