Sharon Sauwa

Reporter

Sharon Sauwa is the The Citizen reporter based in Dodoma.

(function () { "use strict"; var thisScript = document.currentScript; var CONFIG = { apiBase: "https://market.mcl.co.tz", brand: "Market", live: "LIVE", labels: { stocks: "Stocks", forex: "Forex", buy: "Buy", sell: "Sell", unavailable: "Market data is currently unavailable.", updated: "Updated", }, majorCurrencies: ["USD", "EUR", "GBP", "KES", "UGX", "ZAR", "JPY", "CNY", "INR", "AED", "CAD", "CHF", "SAR"], refreshMs: 5 * 60 * 1000, pxPerSecond: 55, accent: "#0a66c2", accentRgb: "10, 102, 194", }; // ---------------- STYLE ---------------- var CSS = ` .mcl-ticker{--accent:${CONFIG.accent};--accent-rgb:${CONFIG.accentRgb}; --bg-a:#0b1f3a;--bg-b:#123059;--txt:#fff;--txt-dim:rgba(255,255,255,.62); --up:#2fd07f;--down:#ff5d5d;--flat:#9fb3c8;--h:48px; position:relative;height:var(--h);width:100%;overflow:hidden;display:flex;align-items:stretch; color:var(--txt);background:linear-gradient(90deg,var(--bg-a),var(--bg-b)); border-top:2px solid var(--accent);box-shadow:0 2px 10px rgba(0,0,0,.18); font-size:13.5px;user-select:none; font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial;} .mcl-ticker *{box-sizing:border-box;} .mcl-brand{flex:0 0 auto;display:flex;align-items:center;gap:9px;padding:0 16px; background:rgba(0,0,0,.2);white-space:nowrap;} .mcl-brand-name{font-weight:800;font-size:12px;text-transform:uppercase;} .mcl-live{display:flex;align-items:center;gap:6px;font-size:10px;font-weight:700;color:var(--accent);} .mcl-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);animation:pulse 1.6s infinite;} @keyframes pulse{0%{box-shadow:0 0 0 0 rgba(var(--accent-rgb),.6);}70%{box-shadow:0 0 0 7px rgba(var(--accent-rgb),0);}100%{box-shadow:0 0 0 0 rgba(var(--accent-rgb),0);}} .mcl-viewport{flex:1;overflow:hidden;position:relative;} .mcl-track{position:absolute;display:inline-flex;white-space:nowrap;align-items:center;height:100%;} @keyframes scroll{from{transform:translateX(0);}to{transform:translateX(-50%);}} .mcl-item{display:inline-flex;gap:7px;padding:0 14px;border-right:1px solid rgba(255,255,255,.08);} .mcl-sym{font-weight:700;} .mcl-val{color:var(--txt-dim);} .mcl-chg.up{color:var(--up);} .mcl-chg.down{color:var(--down);} .mcl-chg.flat{color:var(--flat);} .mcl-pill{margin:0 10px;padding:3px 10px;border-radius:999px;background:var(--accent);font-size:10px;font-weight:800;} .mcl-status{padding:0 16px;color:var(--txt-dim);} `; function injectStyle() { if (document.getElementById("mcl-style")) return; var s = document.createElement("style"); s.id = "mcl-style"; s.textContent = CSS; document.head.appendChild(s); } // ---------------- MOUNT ---------------- function getMount() { return document.querySelector(".ticker-data"); } // ---------------- HELPERS ---------------- function toNum(v) { var n = parseFloat(String(v || "").replace(/,/g, "")); return isFinite(n) ? n : null; } function fmt(v) { var n = parseFloat(v); if (!isFinite(n)) return v; return n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } function arrow(d) { if (!d) return "▬"; return d > 0 ? "▲" : "▼"; } function cls(d) { if (!d) return "flat"; return d > 0 ? "up" : "down"; } // ---------------- DATA ---------------- async function fetchFiles(cat) { var r = await fetch(CONFIG.apiBase + "/api/files?category=" + cat); return r.ok ? r.json() : []; } async function load(track) { try { var [stocksFile, forexFile] = await Promise.all([ fetchFiles("hisa"), fetchFiles("fedha"), ]); track.innerHTML = '
Loading...
'; // simplified render (kept minimal for integration) var html = ""; html += 'STOCKS'; html += 'NMB2,450.00▲ 1.2%'; html += 'FOREX'; html += 'USDBuy 2,600 · Sell 2,640▼ 0.4%'; track.innerHTML = html + html; var speed = 50; var dur = Math.max(20, track.scrollWidth / speed); track.style.animation = "scroll " + dur + "s linear infinite"; } catch (e) { track.innerHTML = '
Market data unavailable
'; } } // ---------------- INIT ---------------- function init() { injectStyle(); var mount = getMount(); if (!mount) return; mount.innerHTML = '
' + '
' + '' + CONFIG.brand + '' + 'LIVE' + '
' + '
' + '
Loading...
' + '
' + '
'; var track = mount.querySelector(".mcl-track"); load(track); setInterval(function () { load(track); }, CONFIG.refreshMs); } console.log(CONFIG); if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); } })();