CARTE SINGOLE
A-Z
document.addEventListener("DOMContentLoaded", function(){ const root = document.querySelector(".OPSS-topbar"); if(!root) return; const hiddenLetters = ["A", "B", "C", "D", "E", "F", "H", "I", "J", "K", "L", "N", "O", "P", "Q", "R", "T", "U", "V", "Y", "W", "X", "Z"]; const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .split("") .filter(letter => !hiddenLetters.includes(letter)); const az = root.querySelector("#az"); const aa = root.querySelector("#aa"); const third = root.querySelector("#third"); const title = root.querySelector("#title"); const panel = root.querySelector("#OPSS-panel"); if(!az || !aa || !third || !title || !panel) return; let current = null; const COUNT_CONFIG = { generazioni: { api: "https://opssmarket.com/collections/pkm-tutte-le-espansioni-di-generazioni-complete/products.json?limit=250", text: "50 CARTE", fallback: "50 CARTE" }, mega: { api: "https://opssmarket.com/collections/pkm-tutte-le-espansioni-di-megaevoluzione-complete/products.json?limit=250", text: "50 CARTE", fallback: "50 CARTE" }, sel: { api: "https://opssmarket.com/collections/pkm-tutte-le-espansioni-di-sole-e-luna-complete/products.json?limit=250", text: "50 CARTE", fallback: "50 CARTE" }, sev: { api: "https://opssmarket.com/collections/pkm-tutte-le-espansioni-di-scarlatto-e-violetto-complete/products.json?limit=250", text: "50 CARTE", fallback: "50 CARTE" }, seven: { api: "https://opssmarket.com/collections/pkm-expansions-scarlet-e-violet-complete/products.json?limit=250", text: "50 CARTE", fallback: "50 CARTE" } }; const menuG = [ {name:"GENERAZIONI", url:"https://cartepokemon.opssmarket.com/#generazioni", count:true, countKey:"generazioni"} ]; const menuM = [ {name:"MEGAEVOLUZIONE", url:"https://cartepokemon.opssmarket.com/#megaevoluzione", count:true, countKey:"mega"} ]; const menuS = [ {name:"SCARLATTO E VIOLETTO", url:"https://cartepokemon.opssmarket.com/#sev", count:true, countKey:"sev"}, {name:"SCARLET & VIOLET", url:"https://cartepokemon.opssmarket.com/#seven", count:true, countKey:"seven"}, {name:"SOLE E LUNA", url:"https://cartepokemon.opssmarket.com/#sel", count:true, countKey:"sel"} ]; const thirdMenus = { G: menuG, M: menuM, S: menuS }; function lockButtonPosition(button){ requestAnimationFrame(function(){ const panelRect = panel.getBoundingClientRect(); const btnRect = button.getBoundingClientRect(); const offset = btnRect.top - panelRect.top; panel.scrollTop += offset - 10; }); } function renderCountButton(link, name, countKey){ const config = COUNT_CONFIG[countKey]; link.classList.add("OPSS-count-row"); link.dataset.countButton = countKey; link.innerHTML = ""; const nameSpan = document.createElement("span"); nameSpan.className = "OPSS-count-name"; nameSpan.textContent = name; const badge = document.createElement("span"); badge.className = "OPSS-count-badge"; badge.textContent = config && config.text ? config.text : "50 CARTE"; link.appendChild(nameSpan); link.appendChild(badge); } function updateCountButtons(){ root.querySelectorAll("[data-count-button]").forEach(function(btn){ const key = btn.dataset.countButton; const config = COUNT_CONFIG[key]; const badge = btn.querySelector(".OPSS-count-badge"); if(badge && config){ badge.textContent = config.text || config.fallback || "50 CARTE"; } }); } async function loadCollectionCount(key){ const config = COUNT_CONFIG[key]; if(!config || !config.api) return; config.text = config.fallback || "50 CARTE"; updateCountButtons(); try { let total = 0; let page = 1; let keepGoing = true; while(keepGoing && page <= 50){ const separator = config.api.indexOf("?") > -1 ? "&" : "?"; const res = await fetch(config.api + separator + "page=" + page + "&_=" + Date.now(), { method: "GET", mode: "cors", cache: "no-store" }); if(!res.ok) throw new Error("blocked"); const data = await res.json(); const products = Array.isArray(data.products) ? data.products : []; total += products.length; if(products.length < 250){ keepGoing = false; } else { page++; } } if(total > 0){ config.text = total + " CARTE"; updateCountButtons(); } } catch(e) { config.text = config.fallback || "50 CARTE"; updateCountButtons(); } } function renderMenu(letter){ title.textContent = " ESPANSIONI "; aa.innerHTML = ""; const menuItems = thirdMenus[letter] || []; menuItems.forEach(function(item){ const link = document.createElement("a"); link.href = item.url; link.target = "_blank"; link.rel = "noopener"; if(item.count){ renderCountButton(link, item.name, item.countKey || "scarlet"); } else { link.textContent = item.name; } aa.appendChild(link); }); updateCountButtons(); } az.innerHTML = ""; letters.forEach(function(letter){ const btn = document.createElement("button"); btn.type = "button"; btn.textContent = letter; btn.addEventListener("click", function(){ if(current === letter){ third.classList.remove("show"); btn.classList.remove("active"); current = null; setTimeout(function(){ lockButtonPosition(btn); }, 30); return; } current = letter; az.querySelectorAll("button").forEach(function(b){ b.classList.remove("active"); }); btn.classList.add("active"); renderMenu(letter); third.classList.add("show"); setTimeout(function(){ lockButtonPosition(btn); }, 30); }); az.appendChild(btn); }); loadCollectionCount("generazioni"); loadCollectionCount("mega"); loadCollectionCount("sel"); loadCollectionCount("sev"); loadCollectionCount("seven"); });

CARTE DISPONIBILI
--
ULTIMO AGG. 30GG
--
(function () { const baseUrl = "https://opssmarket.com/collections/pkm-carte-singole/products.json"; const limit = 250; const cacheKey = "TESTO000_STATS_CACHE_V2"; const cacheTime = 30 * 1000; const refreshInterval = 30 * 1000; const countEl = document.getElementById("TESTO000-count"); const newEl = document.getElementById("TESTO000-new"); let isLoading = false; let currentCount = 0; function setText(count, newCount) { countEl.textContent = count; newEl.textContent = newCount === 0 ? "0" : "+" + newCount; currentCount = count; } function getNewLast30Days(products) { const date = new Date(); date.setDate(date.getDate() - 30); let count = 0; for (let i = 0; i < products.length; i++) { if (!products[i].created_at) continue; if (new Date(products[i].created_at) >= date) count++; } return count; } function saveCache(count, newCount) { try { localStorage.setItem(cacheKey, JSON.stringify({ count: count, newCount: newCount, time: Date.now() })); } catch (e) {} } function readCache() { try { const raw = localStorage.getItem(cacheKey); if (!raw) return null; const data = JSON.parse(raw); if (!data || typeof data.count === "undefined") return null; return data; } catch (e) { return null; } } function sleep(ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); } async function fetchPage(page) { const controller = new AbortController(); const timeout = setTimeout(function () { controller.abort(); }, 8000); try { const url = baseUrl + "?limit=" + limit + "&page=" + page + "&_=" + Date.now(); const response = await fetch(url, { cache: "no-store", signal: controller.signal }); clearTimeout(timeout); if (!response.ok) return []; const data = await response.json(); return Array.isArray(data.products) ? data.products : []; } catch (e) { clearTimeout(timeout); return []; } } async function loadProducts() { if (isLoading) return; isLoading = true; let allProducts = []; let page = 1; let keepGoing = true; while (keepGoing) { const products = await fetchPage(page); if (!products.length) { keepGoing = false; break; } allProducts = allProducts.concat(products); const partialCount = allProducts.length; const partialNew = getNewLast30Days(allProducts); setText(partialCount, partialNew); if (products.length < limit) { keepGoing = false; } else { page++; } await sleep(60); } if (allProducts.length > 0) { const finalCount = allProducts.length; const finalNew = getNewLast30Days(allProducts); saveCache(finalCount, finalNew); setText(finalCount, finalNew); } isLoading = false; } function init() { const cache = readCache(); if (cache) { setText(cache.count, cache.newCount); const fresh = Date.now() - cache.time < cacheTime; if (!fresh) { loadProducts(); } } else { countEl.textContent = "0"; newEl.textContent = "0"; loadProducts(); } setInterval(function () { loadProducts(); }, refreshInterval); } init(); })();
(function () { const ROOT = document.getElementById("OPSS30BOX"); if (!ROOT) return; const SHOP = "https://opssmarket.com"; const LIMIT = 250; const MAX_PAGES = 80; const CACHE_TIME = 30 * 1000; const REFRESH_TIME = 5 * 60 * 1000; let isLoading = false; function cacheKey(handle) { return "OPSS30BOX_FAST_CACHE_V2_" + handle; } function setRow(row, total, recent) { const countEl = row.querySelector(".OPSS30-count"); const newEl = row.querySelector(".OPSS30-new"); if (countEl) countEl.textContent = total; if (newEl) newEl.textContent = Number(recent) > 0 ? "+" + recent : "0"; } function getLast30Created(products) { const limitDate = Date.now() - 30 * 24 * 60 * 60 * 1000; let total = 0; for (let i = 0; i < products.length; i++) { const d = products[i].created_at; if (!d) continue; if (new Date(d).getTime() >= limitDate) total++; } return total; } function readCache(handle) { try { const raw = localStorage.getItem(cacheKey(handle)); if (!raw) return null; const data = JSON.parse(raw); if (!data || typeof data.total === "undefined") return null; return data; } catch (e) { return null; } } function saveCache(handle, total, recent) { try { localStorage.setItem(cacheKey(handle), JSON.stringify({ total: total, recent: recent, time: Date.now() })); } catch (e) {} } async function fetchJson(url) { try { const res = await fetch(url, { method: "GET", cache: "no-store" }); if (!res.ok) throw new Error("direct failed"); return await res.json(); } catch (e1) { const proxyUrl = "https://api.allorigins.win/raw?url=" + encodeURIComponent(url); const res2 = await fetch(proxyUrl, { method: "GET", cache: "no-store" }); if (!res2.ok) throw new Error("proxy failed"); return await res2.json(); } } async function getPage(handle, page) { try { const url = SHOP + "/collections/" + handle + "/products.json?limit=" + LIMIT + "&page=" + page + "&_=" + Date.now(); const json = await fetchJson(url); return Array.isArray(json.products) ? json.products : []; } catch (e) { return []; } } async function loadRow(row, forceRefresh) { const handle = row.getAttribute("data-handle"); if (!handle) return; const cached = readCache(handle); if (cached) { setRow(row, cached.total, cached.recent); if (!forceRefresh && Date.now() - cached.time < CACHE_TIME) { return; } } else { setRow(row, "...", "0"); } let all = []; for (let page = 1; page <= MAX_PAGES; page++) { const products = await getPage(handle, page); if (!products.length) break; all = all.concat(products); const totalNow = all.length; const recentNow = getLast30Created(all); setRow(row, totalNow, recentNow); if (products.length < LIMIT) break; await new Promise(function(resolve) { setTimeout(resolve, 35); }); } if (all.length > 0) { const total = all.length; const recent = getLast30Created(all); setRow(row, total, recent); saveCache(handle, total, recent); } else if (!cached) { setRow(row, "ERR", "0"); } } function showCacheImmediately() { const rows = ROOT.querySelectorAll(".OPSS30-row[data-handle]"); rows.forEach(function(row) { const handle = row.getAttribute("data-handle"); const cached = readCache(handle); if (cached) { setRow(row, cached.total, cached.recent); } }); } async function refreshInBackground(forceRefresh) { if (isLoading) return; isLoading = true; const rows = Array.from(ROOT.querySelectorAll(".OPSS30-row[data-handle]")); for (let i = 0; i < rows.length; i++) { await loadRow(rows[i], forceRefresh); } isLoading = false; } function start() { showCacheImmediately(); setTimeout(function() { refreshInBackground(false); }, 80); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", start); } else { start(); } setInterval(function() { refreshInBackground(true); }, REFRESH_TIME); })();


©2026 OPSS MARKET


const audio = document.getElementById("bgm"); function startAudio(){ audio.play(); document.removeEventListener("touchstart", startAudio); document.removeEventListener("click", startAudio); } document.addEventListener("touchstart", startAudio); document.addEventListener("click", startAudio);
Aggiornamento...
CLICCA
Carte Disponibili
-- / 241
Sync live
(function () { const widgets = document.querySelectorAll(".GENERAZIONI-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".GENERAZIONI-count"); const fillEl = widget.querySelector(".GENERAZIONI-fill"); const dotEl = widget.querySelector(".GENERAZIONI-dot"); const liveText = widget.querySelector(".GENERAZIONI-live-text"); const liveBadge = widget.querySelector(".GENERAZIONI-live"); const syncText = widget.querySelector(".GENERAZIONI-sync"); const imgEl = widget.querySelector(".GENERAZIONI-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 188
Sync live
(function () { const widgets = document.querySelectorAll(".MEGAEVOLUZIONE-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".MEGAEVOLUZIONE-count"); const fillEl = widget.querySelector(".MEGAEVOLUZIONE-fill"); const dotEl = widget.querySelector(".MEGAEVOLUZIONE-dot"); const liveText = widget.querySelector(".MEGAEVOLUZIONE-live-text"); const liveBadge = widget.querySelector(".MEGAEVOLUZIONE-live"); const syncText = widget.querySelector(".MEGAEVOLUZIONE-sync"); const imgEl = widget.querySelector(".MEGAEVOLUZIONE-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 295
Sync live
(function () { const widgets = document.querySelectorAll(".MEGAEVOLUZIONEASC-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".MEGAEVOLUZIONEASC-count"); const fillEl = widget.querySelector(".MEGAEVOLUZIONEASC-fill"); const dotEl = widget.querySelector(".MEGAEVOLUZIONEASC-dot"); const liveText = widget.querySelector(".MEGAEVOLUZIONEASC-live-text"); const liveBadge = widget.querySelector(".MEGAEVOLUZIONEASC-live"); const syncText = widget.querySelector(".MEGAEVOLUZIONEASC-sync"); const imgEl = widget.querySelector(".MEGAEVOLUZIONEASC-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 295
Sync live
(function () { const widgets = document.querySelectorAll(".MEGPFL-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".MEGPFL-count"); const fillEl = widget.querySelector(".MEGPFL-fill"); const dotEl = widget.querySelector(".MEGPFL-dot"); const liveText = widget.querySelector(".MEGPFL-live-text"); const liveBadge = widget.querySelector(".MEGPFL-live"); const syncText = widget.querySelector(".MEGPFL-sync"); const imgEl = widget.querySelector(".MEGPFL-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 241
Sync live
(function () { const widgets = document.querySelectorAll(".SELCEC-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".SELCEC-count"); const fillEl = widget.querySelector(".SELCEC-fill"); const dotEl = widget.querySelector(".SELCEC-dot"); const liveText = widget.querySelector(".SELCEC-live-text"); const liveBadge = widget.querySelector(".SELCEC-live"); const syncText = widget.querySelector(".SELCEC-sync"); const imgEl = widget.querySelector(".SELCEC-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 241
Sync live
(function () { const widgets = document.querySelectorAll(".SEVEN-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".SEVEN-count"); const fillEl = widget.querySelector(".SEVEN-fill"); const dotEl = widget.querySelector(".SEVEN-dot"); const liveText = widget.querySelector(".SEVEN-live-text"); const liveBadge = widget.querySelector(".SEVEN-live"); const syncText = widget.querySelector(".SEVEN-sync"); const imgEl = widget.querySelector(".SEVEN-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 241
Sync live
(function () { const widgets = document.querySelectorAll(".MEWITA-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".MEWITA-count"); const fillEl = widget.querySelector(".MEWITA-fill"); const dotEl = widget.querySelector(".MEWITA-dot"); const liveText = widget.querySelector(".MEWITA-live-text"); const liveBadge = widget.querySelector(".MEWITA-live"); const syncText = widget.querySelector(".MEWITA-sync"); const imgEl = widget.querySelector(".MEWITA-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 1
Sync live
(function () { const widgets = document.querySelectorAll(".SEVPRE-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".SEVPRE-count"); const fillEl = widget.querySelector(".SEVPRE-fill"); const dotEl = widget.querySelector(".SEVPRE-dot"); const liveText = widget.querySelector(".SEVPRE-live-text"); const liveBadge = widget.querySelector(".SEVPRE-live"); const syncText = widget.querySelector(".SEVPRE-sync"); const imgEl = widget.querySelector(".SEVPRE-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 271
Sync live
(function () { const widgets = document.querySelectorAll(".LUCENERA-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".LUCENERA-count"); const fillEl = widget.querySelector(".LUCENERA-fill"); const dotEl = widget.querySelector(".LUCENERA-dot"); const liveText = widget.querySelector(".LUCENERA-live-text"); const liveBadge = widget.querySelector(".LUCENERA-live"); const syncText = widget.querySelector(".LUCENERA-sync"); const imgEl = widget.querySelector(".LUCENERA-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();
Aggiornamento...
CLICCA
Carte Disponibili
-- / 271
Sync live
(function () { const widgets = document.querySelectorAll(".OSSIDIANAINFUOCATA-product-widget"); function formatNumber(num) { if (num >= 999500) return "1M"; if (num >= 1000000) return (num / 1000000).toFixed(1).replace(".0", "") + "M"; if (num >= 1000) return (num / 1000).toFixed(1).replace(".0", "") + "K"; return String(num); } function initWidget(widget) { if (widget.dataset.ready === "true") return; widget.dataset.ready = "true"; const handle = widget.dataset.handle || ""; const total = Number(widget.dataset.total || 0); const logo = widget.dataset.logo || ""; const name = widget.dataset.name || "logo"; const fallbackCount = Number(widget.dataset.fallbackCount || 0); const apiUrl = "https://opssmarket.com/collections/" + handle + "/products.json?limit=250"; const countEl = widget.querySelector(".OSSIDIANAINFUOCATA-count"); const fillEl = widget.querySelector(".OSSIDIANAINFUOCATA-fill"); const dotEl = widget.querySelector(".OSSIDIANAINFUOCATA-dot"); const liveText = widget.querySelector(".OSSIDIANAINFUOCATA-live-text"); const liveBadge = widget.querySelector(".OSSIDIANAINFUOCATA-live"); const syncText = widget.querySelector(".OSSIDIANAINFUOCATA-sync"); const imgEl = widget.querySelector(".OSSIDIANAINFUOCATA-logo img"); let lastCount = null; imgEl.src = logo; imgEl.alt = name; function fitText() { countEl.style.fontSize = ""; requestAnimationFrame(() => { let size = parseFloat(window.getComputedStyle(countEl).fontSize); const minSize = window.innerWidth <= 520 ? 13 : 24; while (countEl.scrollWidth > countEl.clientWidth && size > minSize) { size -= 1; countEl.style.fontSize = size + "px"; } }); } function setCount(value) { countEl.textContent = formatNumber(value) + " / " + formatNumber(total); fitText(); } function pulseCount() { countEl.classList.add("is-pulse"); setTimeout(() => countEl.classList.remove("is-pulse"), 260); } function animateNumber(from, to) { const startTime = performance.now(); const duration = 900; function update(now) { const progress = Math.min((now - startTime) / duration, 1); const eased = 1 - Math.pow(1 - progress, 4); const value = Math.floor(from + (to - from) * eased); setCount(value); if (progress < 1) { requestAnimationFrame(update); } else { setCount(to); pulseCount(); } } requestAnimationFrame(update); } function getNewLast7Days(products) { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); let newCount = 0; products.forEach(product => { if (!product.created_at) return; const createdAt = new Date(product.created_at); if (createdAt >= sevenDaysAgo) newCount++; }); return newCount; } function updateLiveBadge(newCount) { liveBadge.classList.remove("has-new"); if (newCount > 0) { liveText.textContent = "ULTIMO AGG. 7GG | +" + newCount; liveBadge.classList.add("has-new"); } else { liveText.textContent = "NESSUNA NOVITÀ"; } } function updateSyncText(text) { if (text) { syncText.textContent = text; return; } const now = new Date(); const hh = String(now.getHours()).padStart(2, "0"); const mm = String(now.getMinutes()).padStart(2, "0"); syncText.textContent = /* "SYNC LIVE " */ + hh + ":" + mm; } function setManualFallback() { const count = fallbackCount; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; setCount(count); fillEl.style.width = percent + "%"; dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; liveText.textContent = "SYNC NON DISPONIBILE"; updateSyncText("DATI MANUALI"); } function loadProducts(retry = 0) { if (!handle) { setManualFallback(); return; } fetch(apiUrl + "&t=" + Date.now(), { method: "GET", cache: "no-store", mode: "cors" }) .then(res => { if (!res.ok) { throw new Error("HTTP " + res.status); } return res.json(); }) .then(data => { const products = Array.isArray(data.products) ? data.products : []; const count = products.length; const percent = total > 0 ? Math.min((count / total) * 100, 100) : 0; const newLast7Days = getNewLast7Days(products); updateLiveBadge(newLast7Days); updateSyncText(); dotEl.style.background = "#42dfff"; dotEl.style.boxShadow = "0 0 14px #42dfff, 0 0 28px rgba(66,223,255,.65)"; if (lastCount === null) { animateNumber(0, count); } else if (count !== lastCount) { animateNumber(lastCount, count); } else { setCount(count); } fillEl.style.background = "linear-gradient(90deg, #9ef6ff, #4cc9ff, #7a8cff)"; setTimeout(() => { fillEl.style.width = percent + "%"; }, 250); lastCount = count; }) .catch(() => { if (retry < 2) { setTimeout(() => { loadProducts(retry + 1); }, 1200); liveText.textContent = "Riprovo sync..."; return; } setManualFallback(); }); } window.addEventListener("resize", fitText); setCount(fallbackCount); loadProducts(); setInterval(loadProducts, 300000); } widgets.forEach(initWidget); })();