Spaces:
Build error
Build error
File size: 1,562 Bytes
1ac9f32 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | /**
* Shared dashboard utilities.
*/
/**
* Escapes HTML special characters to prevent XSS.
*/
function escapeHTML(str) {
if (str === null || str === undefined) return "";
return String(str)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
/**
* Animates a numerical value from start to end over a duration.
* @param {string} id - The ID of the element to update.
* @param {number} start - The starting value.
* @param {number} end - The ending value.
* @param {number} duration - The duration of the animation in ms.
* @param {string} suffix - Optional suffix (e.g., '%').
* @param {number} decimals - Number of decimal places to show.
*/
function animateValue(id, start, end, duration, suffix = "", decimals = 0) {
const obj = document.getElementById(id);
if (!obj) return;
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
const current = (progress * (end - start) + start).toFixed(decimals);
obj.innerHTML = current + suffix;
if (progress < 1) {
window.requestAnimationFrame(step);
} else {
obj.innerHTML = end.toFixed(decimals) + suffix;
}
};
window.requestAnimationFrame(step);
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = { escapeHTML, animateValue };
}
|