awesome-heatmap 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/AwesomeHeatmap.jsx"],"sourcesContent":["/**\n * AwesomeHeatmap\n * ─────────────────────────────────────────────────────────────────────────────\n * Zero-dependency Heatmap Grid for React 17+.\n * All styles are injected into <head> at runtime — no CSS file import needed.\n *\n * Props\n * ──────\n * data {Array | string} Array of objects OR URL string (JSON).\n * title {string} Optional title shown in the toolbar.\n * theme {\"dark\"|\"light\"|\"ember\"} Default \"dark\".\n * colorScale {string} One of the COLOR_SCALES keys. Default \"plasma\".\n * storageKey {string} IDB key for persisting prefs. Default \"awesome-heatmap\".\n * height {string|number} CSS height. Default \"100%\".\n * onThemeChange {Function} Called with new theme name on every theme switch.\n *\n * Named exports: COLOR_SCALES, PAGE_BG\n * ─────────────────────────────────────────────────────────────────────────────\n */\n\nimport {\n useState, useEffect, useCallback, useMemo, useRef, memo,\n} from \"react\";\n\n/* ═══════════════════════════════════════════════════════ STYLE INJECTION */\n\nconst P = \"ahm\"; // prefix — \"awesome-heatmap\"\n\nconst cx = (...c) => c.filter(Boolean).join(\" \");\n\nconst STYLES = `\n@import url(\"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Outfit:wght@400;500;600;700&display=swap\");\n\n.${P}-root {\n display: flex; flex-direction: column; overflow: hidden;\n background: var(--hm-bg); color: var(--hm-text1);\n font-family: \"Outfit\", sans-serif;\n border-radius: 16px; box-shadow: var(--hm-shadow);\n position: relative; container-type: inline-size;\n}\n.${P}-toolbar {\n display: flex; align-items: center; justify-content: space-between;\n padding: 0 16px; height: 52px; flex-shrink: 0;\n border-bottom: 1px solid var(--hm-border);\n background: var(--hm-surface); gap: 12px;\n}\n.${P}-toolbarL { display: flex; align-items: center; gap: 10px; overflow: hidden; }\n.${P}-toolbarR { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }\n.${P}-logoMark { display: flex; align-items: center; flex-shrink: 0; }\n.${P}-title {\n font-family: \"Outfit\", sans-serif; font-size: 15px; font-weight: 600;\n color: var(--hm-text1); white-space: nowrap; overflow: hidden;\n text-overflow: ellipsis; letter-spacing: -.01em;\n}\n.${P}-dimBadge {\n font-family: \"IBM Plex Mono\", monospace; font-size: 11px; font-weight: 500;\n color: var(--hm-text3); background: var(--hm-surface2);\n border: 1px solid var(--hm-border); border-radius: 6px;\n padding: 2px 8px; white-space: nowrap; letter-spacing: .03em; flex-shrink: 0;\n}\n.${P}-sizeControl { display: flex; align-items: center; gap: 5px; color: var(--hm-text3); }\n.${P}-sizeIcon { flex-shrink: 0; }\n.${P}-sizeSlider { width: 72px; accent-color: var(--hm-accent); cursor: pointer; height: 3px; }\n.${P}-iconBtn {\n display: flex; align-items: center; justify-content: center;\n width: 30px; height: 30px; border-radius: 8px;\n border: 1px solid var(--hm-border); background: var(--hm-surface2);\n color: var(--hm-text2); cursor: pointer; transition: all .14s; flex-shrink: 0;\n}\n.${P}-iconBtn:hover { border-color: var(--hm-border2); color: var(--hm-text1); }\n.${P}-iconBtnOn { background: var(--hm-accentbg) !important; border-color: var(--hm-accent) !important; color: var(--hm-accent) !important; }\n.${P}-dropdownWrap { position: relative; }\n.${P}-dropBtn {\n display: flex; align-items: center; gap: 6px; padding: 5px 10px;\n border-radius: 8px; border: 1px solid var(--hm-border);\n background: var(--hm-surface2); color: var(--hm-text1);\n font-family: \"Outfit\", sans-serif; font-size: 12px; font-weight: 500;\n cursor: pointer; white-space: nowrap; transition: all .14s; height: 30px;\n}\n.${P}-dropBtn:hover { border-color: var(--hm-border2); }\n.${P}-dropBtnOn { border-color: var(--hm-accent) !important; background: var(--hm-accentbg) !important; }\n.${P}-dropBtnLabel { font-size: 11.5px; color: var(--hm-text2); max-width: 90px; overflow: hidden; text-overflow: ellipsis; }\n.${P}-dropArrow { color: var(--hm-text3); flex-shrink: 0; }\n.${P}-dropdown {\n position: absolute; right: 0; top: calc(100% + 6px); z-index: 500;\n background: var(--hm-surface); border: 1px solid var(--hm-border2);\n border-radius: 10px; box-shadow: var(--hm-shadow);\n padding: 4px; min-width: 170px; display: flex; flex-direction: column; gap: 1px;\n}\n.${P}-dropItem {\n display: flex; align-items: center; gap: 8px; padding: 7px 10px;\n border-radius: 7px; border: none; background: none;\n color: var(--hm-text1); font-family: \"Outfit\", sans-serif;\n font-size: 12.5px; font-weight: 500; cursor: pointer;\n text-align: left; transition: background .10s; white-space: nowrap;\n}\n.${P}-dropItem:hover { background: var(--hm-surface2); }\n.${P}-dropItemOn { background: var(--hm-accentbg) !important; color: var(--hm-accent) !important; }\n.${P}-scalePreview { display: flex; gap: 2px; align-items: center; flex-shrink: 0; }\n.${P}-scalePreviewDot { width: 10px; height: 10px; border-radius: 2px; display: inline-block; flex-shrink: 0; }\n.${P}-themeToggle { display: flex; gap: 5px; margin-left: 4px; }\n.${P}-themeBtn {\n width: 14px; height: 14px; border-radius: 50%;\n border: 2px solid transparent; background: var(--dot);\n cursor: pointer; transition: all .15s; flex-shrink: 0; padding: 0;\n}\n.${P}-themeBtn:hover { transform: scale(1.25); }\n.${P}-themeBtnOn { border-color: var(--hm-text1) !important; transform: scale(1.2); box-shadow: 0 0 0 1px var(--hm-bg); }\n.${P}-body { flex: 1; overflow: hidden; display: flex; flex-direction: column; position: relative; }\n.${P}-stateWrap {\n flex: 1; display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n gap: 12px; color: var(--hm-text2); font-size: 14px; padding: 40px 20px;\n}\n.${P}-stateHint { font-size: 12.5px; color: var(--hm-text3); text-align: center; max-width: 360px; line-height: 1.6; }\n.${P}-stateHint code {\n font-family: \"IBM Plex Mono\", monospace; font-size: 11px;\n background: var(--hm-surface2); padding: 1px 5px;\n border-radius: 4px; color: var(--hm-accent);\n}\n.${P}-spinner {\n width: 28px; height: 28px;\n border: 2.5px solid var(--hm-border2);\n border-top-color: var(--hm-accent);\n border-radius: 50%;\n animation: ${P}-spin .65s linear infinite;\n}\n@keyframes ${P}-spin { to { transform: rotate(360deg); } }\n.${P}-errBanner {\n margin: 16px; padding: 12px 16px;\n background: rgba(239,68,68,.08); border: 1px solid rgba(239,68,68,.25);\n border-radius: 10px; color: #f87171; font-size: 13px; line-height: 1.5;\n}\n.${P}-heatmapWrap { flex: 1; overflow: hidden; display: flex; flex-direction: column; }\n.${P}-colHeaderRow {\n display: flex; align-items: flex-end; padding-bottom: 2px;\n border-bottom: 1px solid var(--hm-border); flex-shrink: 0;\n background: var(--hm-bg); position: sticky; top: 0; z-index: 20; overflow: hidden;\n}\n.${P}-cornerCell { width: 140px; min-width: 140px; flex-shrink: 0; }\n.${P}-colHeader {\n flex-shrink: 0; display: flex; flex-direction: column;\n align-items: center; justify-content: flex-end;\n padding-bottom: 4px; height: 72px; position: relative;\n transition: background .12s; border-radius: 4px 4px 0 0;\n}\n.${P}-colHeaderOn { background: var(--hm-accentbg) !important; }\n.${P}-colHeaderText {\n font-family: \"IBM Plex Mono\", monospace; font-size: 10px; font-weight: 500;\n color: var(--hm-text2); writing-mode: vertical-rl; transform: rotate(180deg);\n white-space: nowrap; overflow: hidden; max-height: 56px;\n text-overflow: ellipsis; letter-spacing: .02em; line-height: 1;\n padding-bottom: 2px; transition: color .12s;\n}\n.${P}-colHeaderOn .${P}-colHeaderText { color: var(--hm-text1) !important; }\n.${P}-colMiniBar {\n width: 100%; height: 3px; background: var(--hm-surface3);\n margin-top: 3px; border-radius: 2px; overflow: hidden;\n display: flex; align-items: flex-end;\n}\n.${P}-colMiniBarFill { width: 100%; border-radius: 2px; transition: height .3s ease; }\n.${P}-grid {\n flex: 1; overflow: auto;\n scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.08) transparent;\n}\n.${P}-grid::-webkit-scrollbar { width: 5px; height: 5px; }\n.${P}-grid::-webkit-scrollbar-thumb { background: rgba(255,255,255,.08); border-radius: 4px; }\n.${P}-row { display: flex; align-items: stretch; }\n.${P}-row:hover .${P}-rowLabel { color: var(--hm-text1); background: var(--hm-accentbg); }\n.${P}-rowLabel {\n width: 140px; min-width: 140px; flex-shrink: 0;\n font-family: \"IBM Plex Mono\", monospace; font-size: 10.5px; font-weight: 400;\n color: var(--hm-text2); padding: 0 10px; display: flex; align-items: center;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n border-right: 1px solid var(--hm-border); background: var(--hm-bg);\n position: sticky; left: 0; z-index: 10; transition: all .12s; letter-spacing: .01em;\n}\n.${P}-rowLabelOn { color: var(--hm-text1) !important; background: var(--hm-accentbg) !important; }\n.${P}-cell {\n display: flex; align-items: center; justify-content: center;\n flex-shrink: 0; cursor: crosshair;\n transition: outline .08s, filter .08s;\n outline: 2px solid transparent; outline-offset: -1px;\n position: relative; background: var(--hm-surface3);\n}\n.${P}-cell:hover { outline-color: rgba(255,255,255,.6); z-index: 5; filter: brightness(1.15); }\n.${P}-cellVal {\n font-family: \"IBM Plex Mono\", monospace; font-size: 9px; font-weight: 600;\n letter-spacing: -.01em; pointer-events: none;\n text-shadow: 0 1px 2px rgba(0,0,0,.3); line-height: 1;\n max-width: 100%; overflow: hidden; text-overflow: ellipsis;\n white-space: nowrap; padding: 0 2px;\n}\n.${P}-cellNull { font-family: \"IBM Plex Mono\", monospace; font-size: 11px; color: var(--hm-text3); opacity: .4; }\n.${P}-footer {\n display: flex; align-items: center; justify-content: space-between;\n padding: 8px 12px; border-top: 1px solid var(--hm-border);\n background: var(--hm-surface); flex-shrink: 0; gap: 16px; flex-wrap: wrap;\n}\n.${P}-legend { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }\n.${P}-legendMin, .${P}-legendMax {\n font-family: \"IBM Plex Mono\", monospace; font-size: 10px;\n color: var(--hm-text3); white-space: nowrap; min-width: 32px;\n}\n.${P}-legendMax { text-align: right; }\n.${P}-legendBar { border-radius: 4px; display: block; height: 12px; width: 140px; flex-shrink: 0; }\n.${P}-summaryStats { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }\n.${P}-statItem {\n font-family: \"IBM Plex Mono\", monospace; font-size: 11px;\n color: var(--hm-text2); display: flex; align-items: center; gap: 4px; white-space: nowrap;\n}\n.${P}-statItem span:first-child { color: var(--hm-text3); font-size: 10px; }\n.${P}-statNulls { font-family: \"IBM Plex Mono\", monospace; font-size: 10px; color: var(--hm-text3); white-space: nowrap; }\n.${P}-tooltip {\n position: fixed; z-index: 9999; pointer-events: none;\n background: var(--hm-surface); border: 1px solid var(--hm-border2);\n border-radius: 10px; box-shadow: var(--hm-shadow);\n padding: 0; overflow: hidden; min-width: 180px; max-width: 260px;\n animation: ${P}-ttIn .1s ease;\n}\n@keyframes ${P}-ttIn {\n from { opacity: 0; transform: scale(.96) translateY(3px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n.${P}-ttBody { padding: 12px 14px; display: flex; flex-direction: column; gap: 5px; }\n.${P}-ttRow { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }\n.${P}-ttKey {\n font-family: \"Outfit\", sans-serif; font-size: 10px; font-weight: 600;\n text-transform: uppercase; letter-spacing: .07em; color: var(--hm-text3); flex-shrink: 0;\n}\n.${P}-ttVal {\n font-family: \"IBM Plex Mono\", monospace; font-size: 12.5px; font-weight: 500;\n color: var(--hm-text1); text-align: right; overflow: hidden;\n text-overflow: ellipsis; white-space: nowrap; max-width: 140px;\n}\n.${P}-ttDivider { height: 1px; background: var(--hm-border); margin: 2px 0; }\n.${P}-ttBar { height: 4px; background: var(--hm-surface3); border-radius: 3px; overflow: hidden; margin-top: 3px; }\n.${P}-ttBarFill { height: 100%; border-radius: 3px; transition: width .15s ease; }\n/* Theme variants */\n.${P}-themeLight .${P}-grid::-webkit-scrollbar-thumb { background: rgba(0,0,0,.12); }\n.${P}-themeLight .${P}-cell:hover { outline-color: rgba(0,0,0,.5); }\n.${P}-themeEmber .${P}-grid::-webkit-scrollbar-thumb { background: rgba(255,100,20,.12); }\n.${P}-themeEmber .${P}-cell:hover { outline-color: rgba(255,160,60,.6); }\n`;\n\nfunction injectStyles() {\n const id = \"__ahm_styles__\";\n if (typeof document === \"undefined\") return;\n if (document.getElementById(id)) return;\n const el = document.createElement(\"style\");\n el.id = id;\n el.textContent = STYLES;\n document.head.appendChild(el);\n}\n\n/* ═══════════════════════════════════════════════════════ UTILITIES */\n\nconst toLabel = (key) =>\n String(key ?? \"\")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/[_\\-]+/g, \" \")\n .replace(/\\b\\w/g, (l) => l.toUpperCase())\n .trim() || String(key);\n\nconst toCamelCase = (s) =>\n String(s ?? \"\").trim()\n .replace(/[_\\s\\-]+(.)?/g, (_, c) => (c ? c.toUpperCase() : \"\"))\n .replace(/^(.)/, (m) => m.toLowerCase());\n\nconst flattenObj = (obj, prefix = \"\", depth = 0) => {\n if (depth > 3 || typeof obj !== \"object\" || obj === null) return { [prefix]: obj };\n return Object.entries(obj).reduce((acc, [k, v]) => {\n const key = prefix ? `${prefix}_${k}` : k;\n if (typeof v === \"object\" && v !== null && !Array.isArray(v) && depth < 3)\n return { ...acc, ...flattenObj(v, key, depth + 1) };\n return { ...acc, [key]: v };\n }, {});\n};\n\nconst normalizeRow = (row) => {\n const flat = flattenObj(row);\n return Object.fromEntries(Object.entries(flat).map(([k, v]) => [toCamelCase(k), v]));\n};\n\nconst ENVELOPE_KEYS = [\n \"data\",\"items\",\"results\",\"rows\",\"records\",\"list\",\"content\",\"payload\",\n \"body\",\"response\",\"output\",\"dataset\",\"datasets\",\"values\",\"entries\",\n];\n\nconst unwrap = (payload) => {\n if (!payload) return [];\n if (Array.isArray(payload)) {\n if (!payload.length) return [];\n const first = payload[0];\n if (typeof first !== \"object\" || first === null)\n return payload.map((v, i) => ({ index: i, value: v }));\n if (Array.isArray(first)) {\n const headers = first.map((h, i) => (h != null ? String(h) : `col${i}`));\n return payload.slice(1).map((row) => {\n const obj = {};\n headers.forEach((h, i) => { obj[h] = row[i] ?? null; });\n return obj;\n });\n }\n return payload;\n }\n if (payload.type === \"FeatureCollection\" && Array.isArray(payload.features)) {\n return payload.features\n .filter((f) => f?.properties && typeof f.properties === \"object\")\n .map((f) => ({ ...f.properties, _geomType: f.geometry?.type }));\n }\n for (const key of ENVELOPE_KEYS) {\n if (Array.isArray(payload[key])) return payload[key];\n if (payload[key] && typeof payload[key] === \"object\") {\n for (const inner of ENVELOPE_KEYS) {\n if (Array.isArray(payload[key][inner])) return payload[key][inner];\n }\n }\n }\n if (typeof payload === \"object\") return [payload];\n return [];\n};\n\nconst isNumeric = (v) => {\n if (v === null || v === undefined || v === \"\") return false;\n const n = parseFloat(String(v).replace(/[,$%\\s€£¥]/g, \"\"));\n return !isNaN(n) && isFinite(n);\n};\n\nconst toNum = (v) => {\n if (v === null || v === undefined || v === \"\") return null;\n const n = parseFloat(String(v).replace(/[,$%\\s€£¥]/g, \"\"));\n return isNaN(n) ? null : n;\n};\n\nconst buildMatrix = (data) => {\n if (!data.length) return null;\n const sample = data.slice(0, 200);\n const allKeys = [...new Set(sample.flatMap(Object.keys))];\n const numericKeys = allKeys.filter((k) => {\n const vals = sample.map((r) => r[k]).filter((v) => v !== null && v !== undefined && v !== \"\");\n if (!vals.length) return false;\n return vals.filter(isNumeric).length / vals.length > 0.75;\n });\n const labelKey = allKeys.find((k) => !numericKeys.includes(k)) ?? null;\n if (!numericKeys.length) return null;\n const rows = data;\n const cols = numericKeys;\n const rowLabels = rows.map((r, i) => labelKey ? String(r[labelKey] ?? `Row ${i + 1}`) : `Row ${i + 1}`);\n const colLabels = cols.map(toLabel);\n const values = rows.map((r) => cols.map((k) => toNum(r[k])));\n let min = Infinity, max = -Infinity;\n values.forEach((row) => row.forEach((v) => {\n if (v !== null) { if (v < min) min = v; if (v > max) max = v; }\n }));\n if (!isFinite(min)) { min = 0; max = 1; }\n if (min === max) { min = min - 1; max = max + 1; }\n return { rows, cols, rowLabels, colLabels, values, min, max, labelKey };\n};\n\n/* ═══════════════════════════════════════════════════════ COLOR SCALES */\n\nexport const COLOR_SCALES = {\n plasma: \"Plasma\", inferno: \"Inferno\", viridis: \"Viridis\", magma: \"Magma\",\n thermal: \"Thermal\", ice: \"Ice\", rdbu: \"Red → Blue\", spectral: \"Spectral\",\n};\n\nconst lerp3 = (stops, t) => {\n const n = stops.length - 1;\n const i = Math.min(Math.floor(t * n), n - 1);\n const f = t * n - i;\n const [r0,g0,b0] = stops[i];\n const [r1,g1,b1] = stops[i + 1];\n return [Math.round(r0+(r1-r0)*f), Math.round(g0+(g1-g0)*f), Math.round(b0+(b1-b0)*f)];\n};\n\nconst SCALE_STOPS = {\n plasma: [[13,8,135],[84,2,163],[139,10,165],[185,50,137],[219,92,104],[244,136,73],[254,188,43],[240,249,33]],\n inferno: [[0,0,4],[40,11,84],[101,21,110],[159,42,99],[212,72,66],[245,125,21],[250,193,39],[252,255,164]],\n viridis: [[68,1,84],[72,40,120],[62,83,160],[49,120,183],[38,153,180],[31,183,152],[122,209,81],[253,231,37]],\n magma: [[0,0,4],[28,16,68],[79,18,123],[129,37,129],[181,54,122],[229,80,100],[251,135,97],[252,253,191]],\n thermal: [[4,35,51],[23,84,107],[60,146,153],[99,197,174],[162,220,193],[218,241,211],[246,210,169],[249,142,82],[214,41,21]],\n ice: [[4,0,46],[32,20,115],[66,59,170],[103,107,211],[142,156,232],[181,205,247],[215,238,255],[252,255,255]],\n rdbu: [[178,24,43],[214,96,77],[244,165,130],[253,219,199],[209,229,240],[146,197,222],[67,147,195],[33,102,172]],\n spectral: [[158,1,66],[213,62,79],[244,109,67],[253,174,97],[254,224,139],[230,245,152],[171,221,164],[102,194,165],[50,136,189],[94,79,162]],\n};\n\nconst getColor = (scaleName, t) => lerp3(SCALE_STOPS[scaleName] ?? SCALE_STOPS.plasma, Math.max(0, Math.min(1, t)));\nconst toCss = ([r,g,b]) => `rgb(${r},${g},${b})`;\n\n/* ═══════════════════════════════════════════════════════ THEMES */\n\nconst THEMES = {\n dark: {\n \"--hm-bg\":\"#080c14\",\"--hm-surface\":\"#0e1521\",\"--hm-surface2\":\"#141d2e\",\"--hm-surface3\":\"#1a243b\",\n \"--hm-border\":\"rgba(255,255,255,.07)\",\"--hm-border2\":\"rgba(255,255,255,.13)\",\n \"--hm-text1\":\"#e4eaf8\",\"--hm-text2\":\"#6b7a9e\",\"--hm-text3\":\"#3a445e\",\n \"--hm-accent\":\"#4f7cff\",\"--hm-accentbg\":\"rgba(79,124,255,.12)\",\n \"--hm-shadow\":\"0 8px 40px rgba(0,0,0,.6)\",\"--hm-page-bg\":\"#04060c\",\n },\n light: {\n \"--hm-bg\":\"#f0f2f7\",\"--hm-surface\":\"#ffffff\",\"--hm-surface2\":\"#e8ecf5\",\"--hm-surface3\":\"#dde2ee\",\n \"--hm-border\":\"rgba(0,0,0,.08)\",\"--hm-border2\":\"rgba(0,0,0,.14)\",\n \"--hm-text1\":\"#0d1324\",\"--hm-text2\":\"#4a5370\",\"--hm-text3\":\"#99a3bc\",\n \"--hm-accent\":\"#2f5cf0\",\"--hm-accentbg\":\"rgba(47,92,240,.09)\",\n \"--hm-shadow\":\"0 4px 24px rgba(0,0,0,.10)\",\"--hm-page-bg\":\"#e0e5f0\",\n },\n ember: {\n \"--hm-bg\":\"#0e0804\",\"--hm-surface\":\"#170e06\",\"--hm-surface2\":\"#1f1408\",\"--hm-surface3\":\"#271a0a\",\n \"--hm-border\":\"rgba(255,160,60,.08)\",\"--hm-border2\":\"rgba(255,160,60,.16)\",\n \"--hm-text1\":\"#faebd7\",\"--hm-text2\":\"#a0836a\",\"--hm-text3\":\"#5a3d2a\",\n \"--hm-accent\":\"#ff7a2f\",\"--hm-accentbg\":\"rgba(255,122,47,.13)\",\n \"--hm-shadow\":\"0 8px 40px rgba(80,20,0,.7)\",\"--hm-page-bg\":\"#070402\",\n },\n};\n\nexport const PAGE_BG = {\n dark: THEMES.dark[\"--hm-page-bg\"],\n light: THEMES.light[\"--hm-page-bg\"],\n ember: THEMES.ember[\"--hm-page-bg\"],\n};\n\n/* ═══════════════════════════════════════════════════════ IDB PERSISTENCE */\n\nconst IDB_DB = \"awesome-heatmap\", IDB_STORE = \"prefs\";\n\nconst idbGet = (key) => new Promise((res) => {\n try {\n const req = indexedDB.open(IDB_DB, 1);\n req.onupgradeneeded = (e) => e.target.result.createObjectStore(IDB_STORE);\n req.onsuccess = (e) => {\n try {\n const tx = e.target.result.transaction(IDB_STORE, \"readonly\");\n const r2 = tx.objectStore(IDB_STORE).get(key);\n r2.onsuccess = () => res(r2.result ?? null);\n r2.onerror = () => res(null);\n } catch { res(null); }\n };\n req.onerror = () => res(null);\n } catch { res(null); }\n});\n\nconst idbSet = (key, val) => new Promise((res) => {\n try {\n const req = indexedDB.open(IDB_DB, 1);\n req.onupgradeneeded = (e) => e.target.result.createObjectStore(IDB_STORE);\n req.onsuccess = (e) => {\n try {\n const tx = e.target.result.transaction(IDB_STORE, \"readwrite\");\n tx.objectStore(IDB_STORE).put(val, key);\n tx.oncomplete = () => res(true);\n tx.onerror = () => res(false);\n } catch { res(false); }\n };\n req.onerror = () => res(false);\n } catch { res(false); }\n});\n\n/* ═══════════════════════════════════════════════════════ NUMBER FORMAT */\n\nconst fmtVal = (v) => {\n if (v === null || v === undefined) return \"—\";\n if (Math.abs(v) >= 1_000_000) return (v / 1_000_000).toFixed(2) + \"M\";\n if (Math.abs(v) >= 1_000) return (v / 1_000).toFixed(1) + \"K\";\n if (!Number.isInteger(v)) return v.toFixed(2);\n return String(v);\n};\n\n/* ═══════════════════════════════════════════════════════ SORT MODES */\n\nconst SORT_MODES = [\n { id: \"none\", label: \"Original order\" },\n { id: \"rowAsc\", label: \"Row A → Z\" },\n { id: \"rowDesc\", label: \"Row Z → A\" },\n { id: \"sumAsc\", label: \"Row sum ↑\" },\n { id: \"sumDesc\", label: \"Row sum ↓\" },\n];\n\n/* ═══════════════════════════════════════════════════════ TOOLTIP */\n\nfunction Tooltip({ content, x, y, visible, theme }) {\n const ref = useRef(null);\n const [pos, setPos] = useState({ top: 0, left: 0 });\n useEffect(() => {\n if (!visible || !ref.current) return;\n const el = ref.current;\n const vw = window.innerWidth, vh = window.innerHeight;\n const w = el.offsetWidth || 200;\n const h = el.offsetHeight || 80;\n const gap = 14;\n let left = x + gap, top = y - h / 2;\n if (left + w > vw - 8) left = x - w - gap;\n if (top < 8) top = 8;\n if (top + h > vh - 8) top = vh - h - 8;\n setPos({ top, left });\n }, [x, y, visible, content]);\n if (!visible) return null;\n return (\n <div ref={ref} className={`${P}-tooltip`} style={{ ...THEMES[theme], top: pos.top, left: pos.left }}>\n {content}\n </div>\n );\n}\n\n/* ═══════════════════════════════════════════════════════ COLOR LEGEND */\n\nfunction ColorLegend({ scale, min, max, theme }) {\n const T = THEMES[theme] ?? THEMES.dark;\n const canvasRef = useRef(null);\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext(\"2d\");\n const W = canvas.width;\n for (let i = 0; i < W; i++) {\n const [r,g,b] = getColor(scale, i / (W - 1));\n ctx.fillStyle = `rgb(${r},${g},${b})`;\n ctx.fillRect(i, 0, 1, canvas.height);\n }\n }, [scale]);\n return (\n <div className={`${P}-legend`} style={T}>\n <span className={`${P}-legendMin`}>{fmtVal(min)}</span>\n <canvas ref={canvasRef} width={200} height={12} className={`${P}-legendBar`} />\n <span className={`${P}-legendMax`}>{fmtVal(max)}</span>\n </div>\n );\n}\n\n/* ═══════════════════════════════════════════════════════ HEAT CELL */\n\nconst HeatCell = memo(function HeatCell({ value, t, scaleName, showVal, cellSize, onEnter, onLeave }) {\n if (value === null) {\n return (\n <div className={`${P}-cell`} style={{ width: cellSize, height: cellSize }} onMouseEnter={onEnter} onMouseLeave={onLeave}>\n <span className={`${P}-cellNull`}>·</span>\n </div>\n );\n }\n const [r,g,b] = getColor(scaleName, t);\n const lum = 0.299 * r + 0.587 * g + 0.114 * b;\n const textColor = lum > 140 ? \"rgba(0,0,0,.85)\" : \"rgba(255,255,255,.9)\";\n return (\n <div\n className={`${P}-cell`}\n style={{ width: cellSize, height: cellSize, background: `rgb(${r},${g},${b})`, color: textColor }}\n onMouseEnter={onEnter}\n onMouseLeave={onLeave}\n >\n {showVal && <span className={`${P}-cellVal`}>{fmtVal(value)}</span>}\n </div>\n );\n});\n\n/* ═══════════════════════════════════════════════════════ MAIN COMPONENT */\n\nexport default function AwesomeHeatmap({\n data = [],\n title = \"Heatmap\",\n theme: themeProp = \"dark\",\n colorScale: scaleProp = \"plasma\",\n storageKey = \"awesome-heatmap\",\n height = \"100%\",\n onThemeChange = null,\n}) {\n injectStyles();\n\n const [rawRows, setRawRows] = useState([]);\n const [loading, setLoading] = useState(false);\n const [loadErr, setLoadErr] = useState(\"\");\n\n useEffect(() => {\n let cancelled = false;\n const load = async () => {\n setLoading(true); setLoadErr(\"\");\n try {\n let raw;\n if (typeof data === \"string\") {\n const res = await fetch(data);\n if (!res.ok) throw new Error(`HTTP ${res.status} — ${data}`);\n raw = await res.json();\n } else { raw = data; }\n const arr = unwrap(raw).map(normalizeRow);\n if (!cancelled) setRawRows(arr);\n } catch (e) {\n if (!cancelled) setLoadErr(e.message);\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n load();\n return () => { cancelled = true; };\n }, [data]);\n\n const [theme, setTheme] = useState(themeProp);\n const [scale, setScale] = useState(scaleProp);\n const [sortMode, setSortMode] = useState(\"none\");\n const [showVals, setShowVals] = useState(false);\n const [cellSize, setCellSize] = useState(40);\n const [highlight, setHighlight] = useState(null);\n const [tooltip, setTooltip] = useState({ visible: false, content: null, x: 0, y: 0 });\n const [scaleOpen, setScaleOpen] = useState(false);\n const [sortOpen, setSortOpen] = useState(false);\n const [highlightCol, setHighlightCol] = useState(null);\n const [highlightRow, setHighlightRow] = useState(null);\n const prefsHydrated = useRef(false);\n const T = THEMES[theme] ?? THEMES.dark;\n\n useEffect(() => {\n if (!storageKey) return;\n idbGet(storageKey).then((saved) => {\n if (!saved) { prefsHydrated.current = true; return; }\n if (saved.theme && THEMES[saved.theme]) setTheme(saved.theme);\n if (saved.scale && COLOR_SCALES[saved.scale]) setScale(saved.scale);\n if (saved.sortMode) setSortMode(saved.sortMode);\n if (typeof saved.showVals === \"boolean\") setShowVals(saved.showVals);\n if (saved.cellSize && saved.cellSize >= 16) setCellSize(saved.cellSize);\n prefsHydrated.current = true;\n });\n }, [storageKey]);\n\n useEffect(() => {\n if (!storageKey || !prefsHydrated.current) return;\n idbSet(storageKey, { theme, scale, sortMode, showVals, cellSize });\n }, [storageKey, theme, scale, sortMode, showVals, cellSize]);\n\n useEffect(() => {\n if (THEMES[themeProp]) { setTheme(themeProp); onThemeChange?.(themeProp); }\n }, [themeProp, onThemeChange]);\n\n useEffect(() => {\n if (COLOR_SCALES[scaleProp]) setScale(scaleProp);\n }, [scaleProp]);\n\n const matrix = useMemo(() => buildMatrix(rawRows), [rawRows]);\n\n const sortedIndices = useMemo(() => {\n if (!matrix) return [];\n const n = matrix.rows.length;\n const indices = Array.from({ length: n }, (_, i) => i);\n if (sortMode === \"none\") return indices;\n if (sortMode === \"rowAsc\") return [...indices].sort((a,b) => String(matrix.rowLabels[a]).localeCompare(String(matrix.rowLabels[b])));\n if (sortMode === \"rowDesc\") return [...indices].sort((a,b) => String(matrix.rowLabels[b]).localeCompare(String(matrix.rowLabels[a])));\n const sum = (i) => matrix.values[i].reduce((s,v) => s + (v ?? 0), 0);\n if (sortMode === \"sumAsc\") return [...indices].sort((a,b) => sum(a) - sum(b));\n if (sortMode === \"sumDesc\") return [...indices].sort((a,b) => sum(b) - sum(a));\n return indices;\n }, [matrix, sortMode]);\n\n const colStats = useMemo(() => {\n if (!matrix) return [];\n return matrix.cols.map((_, ci) => {\n const vals = matrix.values.map((r) => r[ci]).filter((v) => v !== null);\n if (!vals.length) return { min:0, max:0, avg:0, sum:0 };\n const sum = vals.reduce((a,b) => a+b, 0);\n return { min: Math.min(...vals), max: Math.max(...vals), avg: sum/vals.length, sum };\n });\n }, [matrix]);\n\n const tValue = useCallback((v) => {\n if (!matrix || v === null) return 0;\n return (v - matrix.min) / (matrix.max - matrix.min);\n }, [matrix]);\n\n const switchTheme = (t) => { setTheme(t); onThemeChange?.(t); };\n\n const handleCellEnter = useCallback((rowIdx, colIdx, e) => {\n if (!matrix) return;\n const absRow = sortedIndices[rowIdx];\n const val = matrix.values[absRow]?.[colIdx];\n const rLabel = matrix.rowLabels[absRow];\n const cLabel = matrix.colLabels[colIdx];\n setHighlightRow(rowIdx); setHighlightCol(colIdx); setHighlight({ row: rowIdx, col: colIdx });\n setTooltip({\n visible: true, x: e.clientX, y: e.clientY,\n content: (\n <div className={`${P}-ttBody`} style={T}>\n <div className={`${P}-ttRow`}><span className={`${P}-ttKey`}>Row</span><span className={`${P}-ttVal`}>{rLabel}</span></div>\n <div className={`${P}-ttRow`}><span className={`${P}-ttKey`}>Column</span><span className={`${P}-ttVal`}>{cLabel}</span></div>\n <div className={`${P}-ttDivider`} />\n <div className={`${P}-ttRow`}>\n <span className={`${P}-ttKey`}>Value</span>\n <span className={`${P}-ttVal`} style={{ color: val !== null ? toCss(getColor(scale, tValue(val))) : undefined }}>\n {val !== null ? fmtVal(val) : \"—\"}\n </span>\n </div>\n {val !== null && (\n <div className={`${P}-ttBar`}>\n <div className={`${P}-ttBarFill`} style={{ width:`${tValue(val)*100}%`, background: toCss(getColor(scale, tValue(val))) }} />\n </div>\n )}\n </div>\n ),\n });\n }, [matrix, sortedIndices, scale, tValue, T]);\n\n const handleCellLeave = useCallback(() => {\n setHighlight(null); setHighlightRow(null); setHighlightCol(null);\n setTooltip((p) => ({ ...p, visible: false }));\n }, []);\n\n const handleMouseMove = useCallback((e) => {\n setTooltip((p) => p.visible ? { ...p, x: e.clientX, y: e.clientY } : p);\n }, []);\n\n const summary = useMemo(() => {\n if (!matrix) return null;\n const all = matrix.values.flat().filter((v) => v !== null);\n if (!all.length) return null;\n const sum = all.reduce((a,b) => a+b, 0);\n return { count: all.length, total: matrix.rows.length * matrix.cols.length, min: matrix.min, max: matrix.max, avg: sum/all.length, sum, rows: matrix.rows.length, cols: matrix.cols.length };\n }, [matrix]);\n\n useEffect(() => {\n const close = () => { setScaleOpen(false); setSortOpen(false); };\n document.addEventListener(\"mousedown\", close);\n return () => document.removeEventListener(\"mousedown\", close);\n }, []);\n\n const themeClass = theme === \"light\" ? `${P}-themeLight` : theme === \"ember\" ? `${P}-themeEmber` : `${P}-themeDark`;\n\n return (\n <div\n className={cx(`${P}-root`, themeClass)}\n style={{ ...T, height: typeof height === \"number\" ? `${height}px` : height }}\n onMouseMove={handleMouseMove}\n >\n {/* TOOLBAR */}\n <div className={`${P}-toolbar`}>\n <div className={`${P}-toolbarL`}>\n <div className={`${P}-logoMark`} aria-hidden=\"true\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\">\n <rect x=\"1\" y=\"1\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".3\"/>\n <rect x=\"6\" y=\"1\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"11\" y=\"1\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".9\"/>\n <rect x=\"16\" y=\"1\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"1\" y=\"6\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"6\" y=\"6\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".9\"/>\n <rect x=\"11\" y=\"6\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"16\" y=\"6\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".3\"/>\n <rect x=\"1\" y=\"11\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".9\"/>\n <rect x=\"6\" y=\"11\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"11\" y=\"11\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".3\"/>\n <rect x=\"16\" y=\"11\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"1\" y=\"16\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"6\" y=\"16\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".3\"/>\n <rect x=\"11\" y=\"16\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".5\"/>\n <rect x=\"16\" y=\"16\" width=\"4\" height=\"4\" rx=\"1\" fill=\"var(--hm-accent)\" opacity=\".9\"/>\n </svg>\n </div>\n <h1 className={`${P}-title`}>{title}</h1>\n {summary && <span className={`${P}-dimBadge`}>{summary.rows.toLocaleString()} × {summary.cols.toLocaleString()}</span>}\n </div>\n\n <div className={`${P}-toolbarR`}>\n {/* Cell size slider */}\n <div className={`${P}-sizeControl`}>\n <svg viewBox=\"0 0 14 14\" fill=\"none\" width=\"12\" height=\"12\" className={`${P}-sizeIcon`}>\n <rect x=\"1\" y=\"1\" width=\"5\" height=\"5\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.3\"/>\n <rect x=\"8\" y=\"1\" width=\"5\" height=\"5\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.3\"/>\n <rect x=\"1\" y=\"8\" width=\"5\" height=\"5\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.3\"/>\n <rect x=\"8\" y=\"8\" width=\"5\" height=\"5\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.3\"/>\n </svg>\n <input type=\"range\" min={16} max={80} step={4} value={cellSize}\n onChange={(e) => setCellSize(Number(e.target.value))}\n className={`${P}-sizeSlider`} title={`Cell size: ${cellSize}px`} />\n </div>\n\n {/* Show values toggle */}\n <button className={cx(`${P}-iconBtn`, showVals && `${P}-iconBtnOn`)}\n onClick={() => setShowVals((p) => !p)}\n title={showVals ? \"Hide cell values\" : \"Show cell values\"}>\n <svg viewBox=\"0 0 16 16\" fill=\"none\" width=\"14\" height=\"14\">\n <path d=\"M1 8C1 8 3.5 3 8 3s7 5 7 5-2.5 5-7 5S1 8 1 8z\" stroke=\"currentColor\" strokeWidth=\"1.4\"/>\n <circle cx=\"8\" cy=\"8\" r=\"2\" stroke=\"currentColor\" strokeWidth=\"1.4\"/>\n </svg>\n </button>\n\n {/* Color scale picker */}\n <div className={`${P}-dropdownWrap`} onMouseDown={(e) => e.stopPropagation()}>\n <button className={cx(`${P}-dropBtn`, scaleOpen && `${P}-dropBtnOn`)}\n onClick={() => { setScaleOpen((p) => !p); setSortOpen(false); }} title=\"Color scale\">\n <span className={`${P}-scalePreview`}>\n {[0,0.25,0.5,0.75,1].map((t) => (\n <span key={t} style={{ background: toCss(getColor(scale, t)) }} className={`${P}-scalePreviewDot`} />\n ))}\n </span>\n <span className={`${P}-dropBtnLabel`}>{COLOR_SCALES[scale]}</span>\n <svg viewBox=\"0 0 10 6\" fill=\"none\" width=\"9\" className={`${P}-dropArrow`}>\n <path d=\"M1 1l4 4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\"/>\n </svg>\n </button>\n {scaleOpen && (\n <div className={`${P}-dropdown`} style={T}>\n {Object.entries(COLOR_SCALES).map(([key, label]) => (\n <button key={key}\n className={cx(`${P}-dropItem`, scale === key && `${P}-dropItemOn`)}\n onClick={() => { setScale(key); setScaleOpen(false); }}>\n <span className={`${P}-scalePreview`}>\n {[0,0.2,0.4,0.6,0.8,1].map((t) => (\n <span key={t} style={{ background: toCss(getColor(key, t)) }} className={`${P}-scalePreviewDot`} />\n ))}\n </span>\n <span>{label}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Sort picker */}\n <div className={`${P}-dropdownWrap`} onMouseDown={(e) => e.stopPropagation()}>\n <button className={cx(`${P}-dropBtn`, sortOpen && `${P}-dropBtnOn`)}\n onClick={() => { setSortOpen((p) => !p); setScaleOpen(false); }} title=\"Sort rows\">\n <svg viewBox=\"0 0 14 14\" fill=\"none\" width=\"13\" height=\"13\">\n <path d=\"M2 3h10M4 7h6M6 11h2\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\"/>\n </svg>\n <span className={`${P}-dropBtnLabel`}>{SORT_MODES.find((m) => m.id === sortMode)?.label ?? \"Sort\"}</span>\n <svg viewBox=\"0 0 10 6\" fill=\"none\" width=\"9\" className={`${P}-dropArrow`}>\n <path d=\"M1 1l4 4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\"/>\n </svg>\n </button>\n {sortOpen && (\n <div className={`${P}-dropdown`} style={T}>\n {SORT_MODES.map((m) => (\n <button key={m.id}\n className={cx(`${P}-dropItem`, sortMode === m.id && `${P}-dropItemOn`)}\n onClick={() => { setSortMode(m.id); setSortOpen(false); }}>\n {m.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Theme dots */}\n <div className={`${P}-themeToggle`}>\n {[\n { id:\"dark\", color:\"#4f7cff\", label:\"Dark\" },\n { id:\"light\", color:\"#2f5cf0\", label:\"Light\" },\n { id:\"ember\", color:\"#ff7a2f\", label:\"Ember\" },\n ].map((th) => (\n <button key={th.id}\n className={cx(`${P}-themeBtn`, theme === th.id && `${P}-themeBtnOn`)}\n style={{ \"--dot\": th.color }}\n onClick={() => switchTheme(th.id)}\n title={th.label} />\n ))}\n </div>\n </div>\n </div>\n\n {/* BODY */}\n <div className={`${P}-body`}>\n {loading && (\n <div className={`${P}-stateWrap`}>\n <div className={`${P}-spinner`} />\n <span>Loading data…</span>\n </div>\n )}\n {!loading && loadErr && (\n <div className={`${P}-errBanner`}><strong>Failed to load:</strong> {loadErr}</div>\n )}\n {!loading && !loadErr && !matrix && rawRows.length > 0 && (\n <div className={`${P}-stateWrap`}>\n <svg viewBox=\"0 0 48 48\" fill=\"none\" width=\"48\" height=\"48\" opacity=\".3\">\n <rect x=\"4\" y=\"4\" width=\"40\" height=\"40\" rx=\"4\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n <path d=\"M12 24h24M24 12v24\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\"/>\n </svg>\n <p>No numeric columns found in this dataset.</p>\n <p className={`${P}-stateHint`}>AwesomeHeatmap needs at least one numeric column to render.</p>\n </div>\n )}\n {!loading && !loadErr && rawRows.length === 0 && (\n <div className={`${P}-stateWrap`}>\n <svg viewBox=\"0 0 48 48\" fill=\"none\" width=\"48\" height=\"48\" opacity=\".3\">\n <rect x=\"4\" y=\"8\" width=\"40\" height=\"32\" rx=\"4\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n <line x1=\"4\" y1=\"16\" x2=\"44\" y2=\"16\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n <line x1=\"16\" y1=\"8\" x2=\"16\" y2=\"40\" stroke=\"currentColor\" strokeWidth=\"2\" opacity=\".5\"/>\n </svg>\n <p>No data loaded</p>\n <p className={`${P}-stateHint`}>Pass an array, a JSON file path, or a REST API URL to the <code>data</code> prop.</p>\n </div>\n )}\n {!loading && matrix && (\n <div className={`${P}-heatmapWrap`}>\n {/* Column headers */}\n <div className={`${P}-colHeaderRow`} style={{ paddingLeft: 0 }}>\n <div className={`${P}-cornerCell`} />\n {matrix.colLabels.map((label, ci) => (\n <div key={ci}\n className={cx(`${P}-colHeader`, highlightCol === ci && `${P}-colHeaderOn`)}\n style={{ width: cellSize, minWidth: cellSize }} title={label}>\n <span className={`${P}-colHeaderText`}>{label}</span>\n <div className={`${P}-colMiniBar`}>\n <div className={`${P}-colMiniBarFill`} style={{\n height: `${Math.round(tValue(colStats[ci]?.avg ?? 0) * 100)}%`,\n background: toCss(getColor(scale, tValue(colStats[ci]?.avg ?? 0))),\n }} />\n </div>\n </div>\n ))}\n </div>\n\n {/* Rows */}\n <div className={`${P}-grid`}>\n {sortedIndices.map((absIdx, rowIdx) => (\n <div key={absIdx} className={`${P}-row`}>\n <div className={cx(`${P}-rowLabel`, highlightRow === rowIdx && `${P}-rowLabelOn`)}\n title={matrix.rowLabels[absIdx]}>\n {matrix.rowLabels[absIdx]}\n </div>\n {matrix.values[absIdx].map((val, ci) => (\n <HeatCell key={ci} value={val} t={tValue(val)} scaleName={scale}\n showVal={showVals && cellSize >= 28} cellSize={cellSize}\n onEnter={(e) => handleCellEnter(rowIdx, ci, e)}\n onLeave={handleCellLeave} />\n ))}\n </div>\n ))}\n </div>\n\n {/* Legend + summary */}\n <div className={`${P}-footer`}>\n <ColorLegend scale={scale} min={matrix.min} max={matrix.max} theme={theme} />\n {summary && (\n <div className={`${P}-summaryStats`}>\n <span className={`${P}-statItem`}><span>Σ</span> {fmtVal(summary.sum)}</span>\n <span className={`${P}-statItem`}><span>x̄</span> {fmtVal(summary.avg)}</span>\n <span className={`${P}-statItem`}><span>↑</span> {fmtVal(summary.max)}</span>\n <span className={`${P}-statItem`}><span>↓</span> {fmtVal(summary.min)}</span>\n <span className={`${P}-statNulls`}>\n {summary.total - summary.count > 0\n ? `${(summary.total - summary.count).toLocaleString()} null cells`\n : `${summary.count.toLocaleString()} cells`}\n </span>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* FLOATING TOOLTIP */}\n <Tooltip content={tooltip.content} x={tooltip.x} y={tooltip.y} visible={tooltip.visible} theme={theme} />\n </div>\n );\n}"],"names":["P","cx","c","STYLES","injectStyles","id","el","toLabel","key","l","toCamelCase","_","m","flattenObj","obj","prefix","depth","acc","k","v","normalizeRow","row","flat","ENVELOPE_KEYS","unwrap","payload","first","i","headers","h","f","_a","inner","isNumeric","n","toNum","buildMatrix","data","sample","allKeys","numericKeys","vals","r","labelKey","rows","cols","rowLabels","colLabels","values","min","max","COLOR_SCALES","lerp3","stops","t","r0","g0","b0","r1","g1","b1","SCALE_STOPS","getColor","scaleName","toCss","g","b","THEMES","IDB_DB","IDB_STORE","idbGet","res","req","e","r2","idbSet","val","tx","fmtVal","SORT_MODES","Tooltip","content","x","y","visible","theme","ref","useRef","pos","setPos","useState","useEffect","vw","vh","w","gap","left","top","jsx","ColorLegend","scale","T","canvasRef","canvas","ctx","W","HeatCell","memo","value","showVal","cellSize","onEnter","onLeave","textColor","AwesomeHeatmap","title","themeProp","scaleProp","storageKey","height","onThemeChange","rawRows","setRawRows","loading","setLoading","loadErr","setLoadErr","cancelled","raw","arr","setTheme","setScale","sortMode","setSortMode","showVals","setShowVals","setCellSize","highlight","setHighlight","tooltip","setTooltip","scaleOpen","setScaleOpen","sortOpen","setSortOpen","highlightCol","setHighlightCol","highlightRow","setHighlightRow","prefsHydrated","saved","matrix","useMemo","sortedIndices","indices","a","sum","s","colStats","ci","tValue","useCallback","switchTheme","handleCellEnter","rowIdx","colIdx","absRow","rLabel","cLabel","jsxs","handleCellLeave","p","handleMouseMove","summary","all","close","themeClass","label","th","_b","absIdx"],"mappings":"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"}