landing: kGOA units, full money stats, rootless resource display

Public bank/exchange/merchant landing stats and performance UI only.
Secret goa-ui overlay stays on local/merchant-secret-ui (never push).
This commit is contained in:
Hernâni Marques 2026-07-17 13:30:23 +02:00
parent bf8a915a01
commit fb1a0b0b8e
No known key found for this signature in database
GPG key ID: CB5738652768F7E9
12 changed files with 1046 additions and 333 deletions

View file

@ -1,29 +1,63 @@
/* Compact GOA / CUR:amount display using currency alt_unit_names.
* Large values "1.23 Mega-GOA" (title = full GOA:n) so landing tiles fit.
/* Compact GOA / CUR:amount display using SI-style alt units (kGOA, MGOA, ).
* Large values "1.23 MGOA" (title = full GOA:n) so landing tiles fit.
*/
(function (global) {
"use strict";
var DEFAULT_ALT = {
"24": "Yotta-GOA",
"21": "Zetta-GOA",
"18": "Exa-GOA",
"15": "Peta-GOA",
"12": "Tera-GOA",
"9": "Giga-GOA",
"6": "Mega-GOA",
"3": "Kilo-GOA",
"24": "YGOA",
"21": "ZGOA",
"18": "EGOA",
"15": "PGOA",
"12": "TGOA",
"9": "GGOA",
"6": "MGOA",
"3": "kGOA",
"0": "GOA",
"-1": "Deci-GOA",
"-2": "Centi-GOA",
"-3": "Milli-GOA",
"-6": "Micro-GOA",
"-7": "Deci-Micro-GOA",
"-8": "Atomic-GOA"
"-1": "dGOA",
"-2": "cGOA",
"-3": "mGOA",
"-6": "µGOA",
"-7": "dµGOA",
"-8": "aGOA"
};
var LONG_TO_COMPACT = {
"yotta-goa": "YGOA",
"zetta-goa": "ZGOA",
"exa-goa": "EGOA",
"peta-goa": "PGOA",
"tera-goa": "TGOA",
"giga-goa": "GGOA",
"mega-goa": "MGOA",
"kilo-goa": "kGOA",
"goa": "GOA",
"deci-goa": "dGOA",
"centi-goa": "cGOA",
"milli-goa": "mGOA",
"micro-goa": "µGOA",
"deci-micro-goa": "dµGOA",
"atomic-goa": "aGOA"
};
var THRESHOLD = 1000;
function compactAlt(altMap) {
var out = {};
var src = altMap || DEFAULT_ALT;
Object.keys(DEFAULT_ALT).forEach(function (k) {
out[k] = DEFAULT_ALT[k];
});
Object.keys(src).forEach(function (k) {
var name = String(src[k] || "").trim();
var low = name.toLowerCase().replace(/\s+/g, "");
if (LONG_TO_COMPACT[low]) out[k] = LONG_TO_COMPACT[low];
else if (DEFAULT_ALT[k] && /goa/i.test(name)) out[k] = DEFAULT_ALT[k];
else out[k] = name || DEFAULT_ALT[k] || name;
});
return out;
}
function parseAmount(s) {
if (s == null || s === "") return { cur: "GOA", val: 0 };
if (typeof s === "number") return { cur: "GOA", val: s };
@ -51,7 +85,7 @@
}
/**
* @param {string|number} amount
* @param {string|number|object} amount
* @param {object} [altMap]
* @returns {{ display: string, title: string, raw: string, usedAlt: boolean }}
*/
@ -59,24 +93,17 @@
if (amount == null || amount === "") {
return { display: "—", title: "", raw: "", usedAlt: false };
}
// Prefer server-provided alt if caller passes object {amount, amount_alt}
// Prefer re-format from canonical amount (keeps kGOA even if server sent Kilo-GOA)
if (typeof amount === "object" && amount) {
if (amount.amount_alt) {
var rawO = amount.amount || amount.amount_full || String(amount.amount_alt);
return {
display: String(amount.amount_alt),
title: amount.amount_full || rawO,
raw: String(rawO),
usedAlt: true
};
if (amount.amount) {
return format(amount.amount, altMap);
}
amount = amount.amount || amount.amount_full || "";
amount = amount.amount_full || amount.amount_alt || "";
}
var alt = altMap || global.__GOA_ALT_UNITS || DEFAULT_ALT;
var alt = compactAlt(altMap || global.__GOA_ALT_UNITS || DEFAULT_ALT);
var p = parseAmount(amount);
var raw = baseStr(p.cur, p.val);
// Foreign currencies must not pick up Kilo-GOA / Mega-GOA labels
var baseName = (alt && alt["0"]) || p.cur;
var curU = String(p.cur || "").toUpperCase();
var baseU = String(baseName || "").toUpperCase();
@ -95,7 +122,9 @@
var n = parseInt(k, 10);
if (!isNaN(n)) scales.push({ sc: n, name: String(alt[k]) });
});
scales.sort(function (a, b) { return b.sc - a.sc; });
scales.sort(function (a, b) {
return b.sc - a.sc;
});
var abs = Math.abs(p.val);
var chosen = null;
@ -136,33 +165,80 @@
setText(document.getElementById(id), amount, altMap);
}
/** Prefer amount_alt from stats row, else format amount. */
/** Prefer formatting from amount field; fall back to amount_alt string. */
function pick(rowOrAmount, altMap) {
if (rowOrAmount && typeof rowOrAmount === "object") {
var a =
rowOrAmount.amount ||
rowOrAmount.total_amount ||
rowOrAmount.amount_paid_sum ||
rowOrAmount.amount_sum;
if (a) return format(a, altMap);
if (rowOrAmount.amount_alt) {
return format({
amount: rowOrAmount.amount,
amount_alt: rowOrAmount.amount_alt,
amount_full: rowOrAmount.amount_full
}, altMap);
return {
display: String(rowOrAmount.amount_alt),
title: String(rowOrAmount.amount_full || rowOrAmount.amount_alt),
raw: String(rowOrAmount.amount_full || rowOrAmount.amount_alt),
usedAlt: true
};
}
return format(rowOrAmount.amount || rowOrAmount.total_amount, altMap);
return format("", altMap);
}
return format(rowOrAmount, altMap);
}
function rememberAlt(stats) {
if (stats && stats.alt_unit_names && typeof stats.alt_unit_names === "object") {
global.__GOA_ALT_UNITS = stats.alt_unit_names;
global.__GOA_ALT_UNITS = compactAlt(stats.alt_unit_names);
}
}
/** Small legend HTML (positive scales). */
function legendHtml(stats) {
var alt = compactAlt((stats && stats.alt_unit_names) || global.__GOA_ALT_UNITS || DEFAULT_ALT);
var rows = [];
Object.keys(alt)
.map(function (k) {
return parseInt(k, 10);
})
.filter(function (n) {
return !isNaN(n) && n > 0;
})
.sort(function (a, b) {
return a - b;
})
.forEach(function (sc) {
rows.push(
"<tr><td>10<sup>" +
sc +
"</sup></td><td><strong>" +
alt[String(sc)] +
"</strong></td></tr>"
);
});
if (!rows.length) return "";
return (
'<table class="unit-legend" aria-label="GOA unit names"><thead><tr><th>×base</th><th>name</th></tr></thead><tbody>' +
rows.join("") +
"</tbody></table>"
);
}
function fillLegend(elOrId, stats) {
var el = typeof elOrId === "string" ? document.getElementById(elOrId) : elOrId;
if (!el) return;
el.innerHTML = legendHtml(stats);
}
global.GoaAmount = {
format: format,
setText: setText,
setById: setById,
pick: pick,
rememberAlt: rememberAlt,
compactAlt: compactAlt,
legendHtml: legendHtml,
fillLegend: fillLegend,
DEFAULT_ALT: DEFAULT_ALT,
THRESHOLD: THRESHOLD
};