// Calculators — individual calculator components.
// All loaded under window.Calc.* for the Tools section to consume.
// Each calculator self-contains: inputs, computation, results card.

const { useState: useCS, useMemo: useCM, useEffect: useCE } = React;

// ─── Shared utilities ───────────────────────────────────────
const fmt = (n, d = 1) => (isFinite(n) ? n.toFixed(d) : '—');
const fmt0 = (n) => (isFinite(n) ? Math.round(n).toString() : '—');

// ─── Shared patient store (localStorage-backed) ─────────────
// Pulled into PatientPanel and also referenced by individual calculators
// when a patient profile is active.
const PATIENT_KEY = 'cyna_patient_v1';
const defaultPatient = () => ({
  poblacion: 'adulto',     // 'adulto' | 'pediatra' | 'neonato'
  nombre: '',
  edad: '',
  edadUnit: 'años',         // 'años' | 'meses' | 'días'
  sexo: 'F',                // 'F' | 'M'
  peso: '',                 // kg (gramos para prematuro)
  talla: '',                // cm
  fc: '',                   // frecuencia cardiaca
  fr: '',                   // frecuencia respiratoria
  tas: '',                  // presión sistólica
  tad: '',                  // presión diastólica
  temp: '',                 // °C
  spo2: '',                 // %
  apoyo: 'estable',
  horas: 8,
  // Soluciones planificadas
  soluciones: [],           // [{nombre, volumen, tiempo, equipo}]
});

let patientState = defaultPatient();
try {
  const raw = localStorage.getItem(PATIENT_KEY);
  if (raw) patientState = { ...patientState, ...JSON.parse(raw) };
} catch {}

const patientSubs = new Set();
function setPatient(updater) {
  patientState = typeof updater === 'function' ? { ...patientState, ...updater(patientState) } : { ...patientState, ...updater };
  try { localStorage.setItem(PATIENT_KEY, JSON.stringify(patientState)); } catch {}
  patientSubs.forEach(fn => fn(patientState));
}
function usePatient() {
  const [, setTick] = useCS(0);
  useCE(() => {
    const fn = () => setTick(t => t + 1);
    patientSubs.add(fn);
    return () => patientSubs.delete(fn);
  }, []);
  return [patientState, setPatient];
}

window.PatientStore = { usePatient, setPatient, get: () => patientState };

// ─── Reusable bits ──────────────────────────────────────────
function NumberField({ label, value, onChange, unit, step = 'any', min = '0', placeholder }) {
  return (
    <div className="calc-field">
      <label>{label}</label>
      <div className="calc-input-row">
        <input
          type="number"
          value={value ?? ''}
          onChange={e => onChange(e.target.value === '' ? '' : +e.target.value)}
          step={step}
          min={min}
          placeholder={placeholder}
        />
        {unit && <span>{unit}</span>}
      </div>
    </div>
  );
}

// ─── 1. Pérdidas insensibles · Pediátrico (incl. neonatal) ──
function PerdidasPediatricas() {
  const [p, setP] = usePatient();
  const peso = +p.peso || 15;
  const horas = +p.horas || 8;
  const apoyo = p.apoyo || 'estable';
  const [horasCustom, setHorasCustom] = useCS(8);

  // Tabla de constantes según tipo de apoyo
  const constantes = { estable: 400, puntas: 500, fiebre: 600, ventilador: 700, calor: 300 };
  const C = constantes[apoyo] ?? 400;

  // Superficie corporal según peso
  const sc = peso <= 10 ? (peso * 4 + 9) / 100 : (peso * 4 + 7) / (90 + peso);

  const perHora = (sc * C) / 24;            // mL/h
  const total24 = sc * C;                    // mL/24h
  const totalCustom = perHora * (+horasCustom || 0);

  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Pérdidas insensibles · Pediátrico / Neonatal</h3>
        <p>Fórmula: <span className="mono">SC × constante</span> = mL en 24 h · <span className="mono">/ 24</span> = mL/h.</p>
      </div>
      <div className="calc-fields">
        <NumberField
          label="Peso del paciente"
          value={p.peso}
          onChange={v => setP({ peso: v })}
          unit="kg"
          step="0.1"
          placeholder="ej. 15"
        />
        <div className="calc-field">
          <label>Tipo de apoyo</label>
          <select
            className="calc-select"
            value={apoyo}
            onChange={e => setP({ apoyo: e.target.value })}
          >
            <option value="estable">Estable · 400</option>
            <option value="puntas">Puntas nasales · 500</option>
            <option value="fiebre">Fiebre · 600</option>
            <option value="ventilador">Ventilador mecánico · 700</option>
            <option value="calor">Calor radiante · 300</option>
          </select>
        </div>
        <NumberField
          label="Horas solicitadas"
          value={horasCustom}
          onChange={v => setHorasCustom(v)}
          unit="h"
          step="1"
          placeholder="ej. 8"
        />
      </div>
      <div className="calc-result">
        <div className="calc-result-row">
          <span className="lbl">Superficie corporal (SC)</span>
          <span className="val mono">{fmt(sc, 3)} m²</span>
        </div>
        <div className="calc-multi">
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">En 1 hora</div>
            <div className="calc-multi-val">{fmt(perHora, 1)}<small> ml</small></div>
          </div>
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">En {horasCustom || 0} h <span style={{ color: 'var(--cinnamon-500)' }}>· solicitadas</span></div>
            <div className="calc-multi-val main">{fmt(totalCustom, 1)}<small> ml</small></div>
          </div>
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">En 24 horas</div>
            <div className="calc-multi-val">{fmt(total24, 1)}<small> ml</small></div>
          </div>
        </div>
        <div className="calc-result-note">
          SC: {peso <= 10 ? '(peso×4 + 9)/100' : '(peso×4 + 7)/(90 + peso)'} · Constante {C} · Pérdidas en 24 h = SC × {C}
        </div>
      </div>
    </div>
  );
}

// ─── 2. Pérdidas insensibles · Prematuro — Próximamente ─────
function PerdidasPrematuros() {
  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Pérdidas insensibles · Prematuro</h3>
        <p>Cálculo basado en peso al nacimiento y edad postnatal.</p>
      </div>
      <div className="calc-soon">
        <div className="calc-soon-badge">Próximamente</div>
        <h4>Estamos validando la fórmula con fuentes confiables</h4>
        <p>
          La tabla de constantes para prematuros varía según peso, edad postnatal y condiciones ambientales
          (humedad de la incubadora, fototerapia, calor radiante). Estamos cotejando guías de la AAP y de la
          SEN para publicar una versión clínicamente sólida.
        </p>
        <p className="muted small">
          Mientras tanto, para neonatos de término puedes usar la calculadora pediátrica con peso real.
        </p>
      </div>
    </div>
  );
}

// ─── 3. Pérdidas insensibles · Adulto ───────────────────────
function PerdidasAdultos() {
  const [p, setP] = usePatient();
  const peso = +p.peso || 70;
  const tempVal = +p.temp;
  const [horasCustom, setHorasCustom] = useCS(8);

  // Determine factor automatically by temperature if provided, else manual override
  const [tempBucket, setTempBucket] = useCS('auto');
  const autoBucket =
    !isFinite(tempVal) || tempVal === 0 ? 'lt37' :
    tempVal < 37 ? 'lt37' :
    tempVal < 38 ? 't37' :
    tempVal < 39 ? 't38' : 'gt39';
  const bucket = tempBucket === 'auto' ? autoBucket : tempBucket;

  const factors = { lt37: 0.5, t37: 0.6, t38: 0.7, gt39: 1 };
  const factor = factors[bucket];

  const perHora = peso * factor;
  const total24 = perHora * 24;
  const totalCustom = perHora * (+horasCustom || 0);

  const bucketLabel = { lt37: '< 37 °C', t37: '37–38 °C', t38: '38–39 °C', gt39: '> 39 °C' }[bucket];

  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Pérdidas insensibles · Adulto</h3>
        <p>Fórmula: <span className="mono">peso × factor</span> = mL/h · multiplicado por las horas indicadas.</p>
      </div>
      <div className="calc-fields">
        <NumberField label="Peso" value={p.peso} onChange={v => setP({ peso: v })} unit="kg" placeholder="ej. 70"/>
        <NumberField label="Temperatura actual" value={p.temp} onChange={v => setP({ temp: v })} unit="°C" step="0.1" placeholder="ej. 37.5"/>
        <NumberField label="Horas solicitadas" value={horasCustom} onChange={v => setHorasCustom(v)} unit="h" placeholder="ej. 12"/>
        <div className="calc-field">
          <label>Rango de temperatura</label>
          <select className="calc-select" value={tempBucket} onChange={e => setTempBucket(e.target.value)}>
            <option value="auto">Auto · según °C ingresada</option>
            <option value="lt37">&lt; 37 °C · ×0.5</option>
            <option value="t37">37–38 °C · ×0.6</option>
            <option value="t38">38–39 °C · ×0.7</option>
            <option value="gt39">&gt; 39 °C · ×1.0</option>
          </select>
        </div>
      </div>
      <div className="calc-result">
        <div className="calc-result-row">
          <span className="lbl">Rango aplicado <span className="muted small">· factor × {factor}</span></span>
          <span className="val mono">{bucketLabel}</span>
        </div>
        <div className="calc-multi">
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">Consumido por hora</div>
            <div className="calc-multi-val">{fmt(perHora, 1)}<small> ml</small></div>
          </div>
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">En {horasCustom || 0} h <span style={{ color: 'var(--cinnamon-500)' }}>· solicitadas</span></div>
            <div className="calc-multi-val main">{fmt(totalCustom, 1)}<small> ml</small></div>
          </div>
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">En 24 horas</div>
            <div className="calc-multi-val">{fmt(total24, 1)}<small> ml</small></div>
          </div>
        </div>
        <div className="calc-result-note">
          Factores por temperatura · &lt;37 °C: 0.5 · 37–38 °C: 0.6 · 38–39 °C: 0.7 · &gt;39 °C: 1.0
        </div>
      </div>
    </div>
  );
}

// ─── 4. Factor goteo / Gotas por minuto ─────────────────────
function FactorGoteo() {
  const [volumen, setVolumen] = useCS(500);
  const [tiempo, setTiempo] = useCS(60);  // minutes
  const [equipo, setEquipo] = useCS('macro');

  const gotasPorMl = { macro: 10, normo: 20, micro: 60, trans: 15 }[equipo];
  const equipoName = { macro: 'Macrogotero', normo: 'Normogotero', micro: 'Microgotero', trans: 'Equipo de transfusión' }[equipo];
  const gotasMin = (volumen * gotasPorMl) / tiempo;
  const K = 60 / gotasPorMl;                           // factor / constante
  const mlPorHora = volumen / (tiempo / 60);           // velocidad de infusión
  const mlPorGota = 1 / gotasPorMl;                    // equivalencia ml/gota

  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Factor goteo · Velocidad de infusión</h3>
        <p>Fórmula: <span className="mono">(volumen × factor de goteo) / tiempo</span> · incluye equivalencias y mL/h.</p>
      </div>
      <div className="calc-fields">
        <NumberField label="Volumen a infundir" value={volumen} onChange={v => setVolumen(v || 0)} unit="ml" step="50"/>
        <NumberField label="Tiempo total" value={tiempo} onChange={v => setTiempo(v || 0)} unit="min"/>
        <div className="calc-field full">
          <label>Equipo</label>
          <div className="calc-segmented">
            {[
              ['macro', 'Macrogotero · 10 gtt/ml'],
              ['normo', 'Normogotero · 20 gtt/ml'],
              ['micro', 'Microgotero · 60 gtt/ml'],
              ['trans', 'Transfusión · 15 gtt/ml'],
            ].map(([k, l]) => (
              <button key={k} className={equipo === k ? 'on' : ''} onClick={() => setEquipo(k)}>{l}</button>
            ))}
          </div>
        </div>
      </div>
      <div className="calc-result">
        <div className="calc-eq">
          <div className="calc-eq-row">
            <span className="calc-eq-lbl">{equipoName}</span>
            <span className="calc-eq-val mono"><strong>{gotasPorMl}</strong> gotas = <strong>1 ml</strong></span>
          </div>
          <div className="calc-eq-row">
            <span className="calc-eq-lbl">Constante (K)</span>
            <span className="calc-eq-val mono">60 / {gotasPorMl} = <strong>{fmt(K, 2)}</strong></span>
          </div>
          <div className="calc-eq-row">
            <span className="calc-eq-lbl">Equivalencia por gota</span>
            <span className="calc-eq-val mono"><strong>1 gota</strong> = {fmt(mlPorGota, 3)} ml</span>
          </div>
        </div>

        <div className="calc-multi">
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">Gotas por minuto</div>
            <div className="calc-multi-val main">{fmt0(gotasMin)}<small> gtt/min</small></div>
          </div>
          <div className="calc-multi-cell">
            <div className="calc-multi-lbl">Velocidad de infusión</div>
            <div className="calc-multi-val">{fmt0(mlPorHora)}<small> ml/h</small></div>
          </div>
        </div>
        <div className="calc-result-note">
          {volumen} ml ÷ {tiempo} min × {gotasPorMl} gtt/ml = {fmt0(gotasMin)} gtt/min · equivalente a {fmt0(mlPorHora)} ml/h
        </div>
      </div>
    </div>
  );
}

// ─── 5. IMC + clasificación OMS ────────────────────────────
const IMC_LEVELS = [
  { max: 16,    label: 'Delgadez severa',      color: 'var(--wine-700)', tint: 'var(--wine-100)' },
  { max: 16.99, label: 'Delgadez moderada',    color: 'var(--wine-500)', tint: 'var(--wine-100)' },
  { max: 18.49, label: 'Delgadez leve',        color: 'var(--honey-700)', tint: 'var(--honey-100)' },
  { max: 24.99, label: 'Peso normal',          color: 'var(--sage-700)', tint: 'var(--sage-100)' },
  { max: 29.99, label: 'Sobrepeso',            color: 'var(--honey-700)', tint: 'var(--honey-100)' },
  { max: 34.99, label: 'Obesidad grado I',     color: 'var(--cinnamon-600)', tint: 'var(--cinnamon-100)' },
  { max: 39.99, label: 'Obesidad grado II',    color: 'var(--wine-500)', tint: 'var(--wine-100)' },
  { max: Infinity, label: 'Obesidad grado III · mórbida', color: 'var(--wine-700)', tint: 'var(--wine-100)' },
];
function classifyImc(imc) {
  if (!isFinite(imc) || imc <= 0) return null;
  return IMC_LEVELS.find(l => imc <= l.max);
}

function IMCalc() {
  const [p, setP] = usePatient();
  const peso = +p.peso;
  const tallaCm = +p.talla;
  const tallaM = tallaCm / 100;
  const imc = (peso && tallaM) ? peso / (tallaM * tallaM) : NaN;
  const klass = classifyImc(imc);
  const pesoIdealMin = isFinite(tallaM) ? 18.5 * tallaM * tallaM : NaN;
  const pesoIdealMax = isFinite(tallaM) ? 24.9 * tallaM * tallaM : NaN;

  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Índice de Masa Corporal (IMC)</h3>
        <p>Fórmula: <span className="mono">peso (kg) ÷ talla² (m)</span> · Clasificación según OMS.</p>
      </div>
      <div className="calc-fields">
        <NumberField label="Peso" value={p.peso} onChange={v => setP({ peso: v })} unit="kg" step="0.1" placeholder="ej. 70"/>
        <NumberField label="Talla" value={p.talla} onChange={v => setP({ talla: v })} unit="cm" placeholder="ej. 170"/>
      </div>
      <div className="calc-result">
        <div className="calc-result-row main">
          <span className="lbl">IMC</span>
          <span className="val mono">{fmt(imc, 2)}<small style={{ fontSize: 16, marginLeft: 6, color: 'var(--cinnamon-500)' }}> kg/m²</small></span>
        </div>
        {klass && (
          <div className="imc-classify" style={{ background: klass.tint, borderLeft: `4px solid ${klass.color}` }}>
            <div className="imc-classify-eyebrow">Clasificación OMS</div>
            <div className="imc-classify-label" style={{ color: klass.color }}>{klass.label}</div>
          </div>
        )}
        <div className="imc-scale">
          {IMC_LEVELS.map((l, i) => (
            <div key={i} className={'imc-scale-row ' + (klass === l ? 'on' : '')}>
              <span className="imc-scale-dot" style={{ background: l.color }}/>
              <span className="imc-scale-range mono">
                {i === 0 ? '< 16.0' :
                 l.max === Infinity ? '≥ 40.0' :
                 `${IMC_LEVELS[i - 1] ? (IMC_LEVELS[i - 1].max + 0.01).toFixed(2) : '16.00'} – ${l.max.toFixed(2)}`}
              </span>
              <span className="imc-scale-lbl">{l.label}</span>
            </div>
          ))}
        </div>
        {isFinite(pesoIdealMin) && (
          <div className="calc-result-note">
            Rango saludable para esta talla: <strong>{fmt(pesoIdealMin, 1)} – {fmt(pesoIdealMax, 1)} kg</strong>
          </div>
        )}
      </div>
    </div>
  );
}

// ─── 6. Índice de choque (Shock Index) ──────────────────────
function IndiceChoque() {
  const [p, setP] = usePatient();
  const fc = +p.fc;
  const tas = +p.tas;
  const si = (fc && tas) ? fc / tas : NaN;

  // Bandas clínicas: <0.5 inadecuada; 0.5–0.7 normal; 0.7–1.0 leve; 1.0–1.4 moderado; >1.4 severo
  const level = !isFinite(si) ? null :
    si < 0.5  ? { label: 'Volumen inadecuado / sobrecarga', color: 'var(--wine-500)', tint: 'var(--wine-100)' } :
    si <= 0.7 ? { label: 'Normal', color: 'var(--sage-700)', tint: 'var(--sage-100)' } :
    si < 1.0  ? { label: 'Choque leve / compensación', color: 'var(--honey-700)', tint: 'var(--honey-100)' } :
    si < 1.4  ? { label: 'Choque moderado', color: 'var(--cinnamon-600)', tint: 'var(--cinnamon-100)' } :
                { label: 'Choque severo · alerta', color: 'var(--wine-700)', tint: 'var(--wine-100)' };

  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Índice de choque (Shock Index)</h3>
        <p>Fórmula: <span className="mono">frecuencia cardiaca ÷ presión sistólica</span> · útil para sospecha temprana de choque.</p>
      </div>
      <div className="calc-fields">
        <NumberField label="Frecuencia cardiaca" value={p.fc} onChange={v => setP({ fc: v })} unit="lpm" placeholder="ej. 96"/>
        <NumberField label="Presión sistólica" value={p.tas} onChange={v => setP({ tas: v })} unit="mmHg" placeholder="ej. 120"/>
      </div>
      <div className="calc-result">
        <div className="calc-result-row main">
          <span className="lbl">Índice de choque</span>
          <span className="val mono">{fmt(si, 2)}</span>
        </div>
        {level && (
          <div className="imc-classify" style={{ background: level.tint, borderLeft: `4px solid ${level.color}` }}>
            <div className="imc-classify-eyebrow">Interpretación</div>
            <div className="imc-classify-label" style={{ color: level.color }}>{level.label}</div>
          </div>
        )}
        <div className="imc-scale compact">
          <div className="imc-scale-row"><span className="imc-scale-dot" style={{ background: 'var(--wine-500)' }}/><span className="imc-scale-range mono">&lt; 0.50</span><span className="imc-scale-lbl">Sobrecarga / inadecuado</span></div>
          <div className="imc-scale-row"><span className="imc-scale-dot" style={{ background: 'var(--sage-700)' }}/><span className="imc-scale-range mono">0.50 – 0.70</span><span className="imc-scale-lbl">Normal</span></div>
          <div className="imc-scale-row"><span className="imc-scale-dot" style={{ background: 'var(--honey-700)' }}/><span className="imc-scale-range mono">0.70 – 1.00</span><span className="imc-scale-lbl">Choque leve</span></div>
          <div className="imc-scale-row"><span className="imc-scale-dot" style={{ background: 'var(--cinnamon-600)' }}/><span className="imc-scale-range mono">1.00 – 1.40</span><span className="imc-scale-lbl">Choque moderado</span></div>
          <div className="imc-scale-row"><span className="imc-scale-dot" style={{ background: 'var(--wine-700)' }}/><span className="imc-scale-range mono">≥ 1.40</span><span className="imc-scale-lbl">Choque severo</span></div>
        </div>
      </div>
    </div>
  );
}

// ─── 7. Presión arterial media (PAM / MAP) ──────────────────
function PAM() {
  const [p, setP] = usePatient();
  const tas = +p.tas;
  const tad = +p.tad;
  const pam = (tas && tad) ? (tas + 2 * tad) / 3 : NaN;
  const pp  = (tas && tad) ? tas - tad : NaN;       // presión de pulso

  const level = !isFinite(pam) ? null :
    pam < 60  ? { label: 'Hipoperfusión · riesgo de daño orgánico', color: 'var(--wine-700)', tint: 'var(--wine-100)' } :
    pam < 70  ? { label: 'Límite inferior', color: 'var(--honey-700)', tint: 'var(--honey-100)' } :
    pam <= 105? { label: 'Perfusión adecuada', color: 'var(--sage-700)', tint: 'var(--sage-100)' } :
                { label: 'Elevada · vigilar hipertensión', color: 'var(--wine-500)', tint: 'var(--wine-100)' };

  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Presión arterial media (PAM)</h3>
        <p>Fórmula: <span className="mono">(sistólica + 2 × diastólica) ÷ 3</span> · meta clínica habitual: ≥ 65 mmHg.</p>
      </div>
      <div className="calc-fields">
        <NumberField label="Presión sistólica" value={p.tas} onChange={v => setP({ tas: v })} unit="mmHg" placeholder="ej. 120"/>
        <NumberField label="Presión diastólica" value={p.tad} onChange={v => setP({ tad: v })} unit="mmHg" placeholder="ej. 80"/>
      </div>
      <div className="calc-result">
        <div className="calc-result-row">
          <span className="lbl">Presión de pulso</span>
          <span className="val mono">{fmt0(pp)} mmHg</span>
        </div>
        <div className="calc-result-row main">
          <span className="lbl">PAM</span>
          <span className="val mono">{fmt(pam, 1)}<small style={{ fontSize: 16, marginLeft: 6, color: 'var(--cinnamon-500)' }}> mmHg</small></span>
        </div>
        {level && (
          <div className="imc-classify" style={{ background: level.tint, borderLeft: `4px solid ${level.color}` }}>
            <div className="imc-classify-eyebrow">Interpretación</div>
            <div className="imc-classify-label" style={{ color: level.color }}>{level.label}</div>
          </div>
        )}
        <div className="calc-result-note">
          Meta habitual en cuidados intensivos: PAM ≥ 65 mmHg para asegurar perfusión tisular.
        </div>
      </div>
    </div>
  );
}

// ─── 8. Tabla líquidos infundidos (referencia) ──────────────
function TablaLiquidos() {
  const rows = [
    [1000, 24, 41, 13], [1000, 12, 83, 27], [1000, 8, 125, 41], [1000, 6, 166, 55], [1000, 4, 250, 83],
    [500, 24, 20, 6], [500, 12, 41, 13], [500, 8, 62, 20], [500, 6, 83, 27], [500, 4, 125, 41],
    [250, 24, 10, 3], [250, 12, 20, 6], [250, 8, 31, 10], [250, 6, 41, 13], [250, 4, 62, 20],
  ];
  return (
    <div className="calc-card">
      <div className="calc-head">
        <h3>Líquidos infundidos · Tabla de referencia</h3>
        <p>Macrogotero (10 gtt/ml) — valores de mantenimiento más comunes.</p>
      </div>
      <div className="table-wrap">
        <table className="ref-table">
          <thead><tr><th>Volumen</th><th>Horas</th><th>ml / hora</th><th>Gotas / minuto</th></tr></thead>
          <tbody>
            {rows.map((r, i) => (
              <tr key={i} className={r[0] === 1000 ? '' : (r[0] === 500 ? 'alt' : 'alt2')}>
                <td><span className="mono">{r[0]} ml</span></td>
                <td>{r[1]} h</td>
                <td><span className="mono">{r[2]} ml</span></td>
                <td><span className="mono">{r[3]} gtt</span></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

window.Calc = {
  PerdidasPediatricas,
  PerdidasPrematuros,
  PerdidasAdultos,
  FactorGoteo,
  IMCalc,
  IndiceChoque,
  PAM,
  TablaLiquidos,
  // exports for re-use
  fmt, fmt0, classifyImc, IMC_LEVELS, NumberField,
};
