pediatric-ai-scribe-v3/public/js/bedside/toxicology.js
Daniel 031bfb995a feat: C — extract Bedside reference into ES modules
Split the Bedside clinical reference section out of calculators.js
(~1220 lines) into 20 focused ES modules under public/js/bedside/.
Each module owns one clinical topic (cardiac, seizure, sepsis, burns,
etc.) and exports an init() wired up by bedside/index.js. Shared
helpers live in shared.js and also set window._EM for back-compat
with the 4 remaining call sites in calculators.js.

Load order: classic defer calculators.js first, then module script
bedside/index.js. Handlers bind at DOM-ready; runtime _EM lookups
resolve after both are evaluated.

Makes bedside content editable per-section, shrinks calculators.js
from 4111 to 2891 lines, and keeps the existing Playwright smoke
suite (e2e/tests/bedside-smoke.spec.js) as the behavioral contract.
2026-04-20 23:19:50 +02:00

120 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============================================================
// bedside/toxicology.js
// TOXICOLOGY.
// ============================================================
import { S } from './shared.js';
function lookupTox() {
var wt = parseFloat(document.getElementById('tox-weight').value);
var topic = document.getElementById('tox-topic').value;
var el = document.getElementById('tox-result');
var html = '';
if (topic === 'approach') {
html += S.stepBox('#3b82f6', '1. Stabilize (ABCDE)', 'Airway, breathing, circulation, disability (glucose, pupils, GCS), exposure. Naloxone if depressed LOC + resp depression. Dextrose if hypoglycemic. Thiamine in select cases.');
html += S.stepBox('#8b5cf6', '2. Identify toxidrome', '<strong>Sympathomimetic:</strong> HTN, tachy, mydriasis, diaphoresis (cocaine, meth). <strong>Anticholinergic:</strong> hot/dry, mydriasis, tachy, delirium (antihistamines, TCAs). <strong>Cholinergic:</strong> SLUDGE-M, miosis (organophosphates). <strong>Opioid:</strong> miosis, resp depression, ↓LOC. <strong>Sedative-hypnotic:</strong> ↓LOC, normal/low vitals.');
html += S.stepBox('#f59e0b', '3. Decontamination', '<strong>Activated charcoal</strong> 1 g/kg PO (max 50 g): within 1h of ingestion, intact airway, ingestion adsorbed (not Li, metals, alcohols). Avoid caustics/hydrocarbons. <strong>Whole bowel irrigation:</strong> PEG for metals/iron/lithium/sustained release. <strong>Gastric lavage:</strong> rarely indicated. <strong>Ipecac:</strong> no longer recommended.');
html += S.stepBox('#10b981', '4. Enhance elimination', '<strong>Urinary alkalinization</strong> (salicylates, phenobarbital). <strong>Hemodialysis</strong> (see ISTUMBLE). <strong>Lipid emulsion</strong> for lipid-soluble drug toxicity (LA, CCB, TCA).');
html += S.stepBox('#ef4444', '5. Antidotes', 'See topic list. <strong>Contact Poison Center</strong> (US: 1-800-222-1222) early for any significant exposure.');
} else if (topic === 'acetaminophen') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Acetaminophen overdose</strong></div>';
html += '<p style="font-size:13px;">Acute toxic dose: &gt;150 mg/kg (or 7.5 g total) single ingestion. Hepatotoxic after 24h; AST/ALT peak day 3-4.</p>';
html += '<p style="font-size:13px;"><strong>Diagnosis:</strong> Draw level at 4h post-ingestion (or on arrival if &gt;4h). Plot on <strong>Rumack-Matthew nomogram</strong> (treatment line at 150 mcg/mL at 4h).</p>';
html += S.drugTable(
S.drugRow('N-acetylcysteine (NAC) — IV', '150 mg/kg over 1h → 50 mg/kg over 4h → 100 mg/kg over 16h (21h total)', 'IV', 'Total 300 mg/kg. Most effective if started &lt;8h post-ingestion.') +
S.drugRow('N-acetylcysteine — PO', '140 mg/kg load, then 70 mg/kg q4h × 17 doses', 'PO', 'Alternative to IV. Unpleasant taste — often with juice.') +
S.drugRow('Activated charcoal', '1 g/kg (max 50 g)', 'PO', 'If within 1-2h of ingestion and airway protected.')
);
if (wt) html += '<div style="padding:10px;background:var(--g50);border-radius:6px;font-size:12px;"><strong>For ' + wt + ' kg:</strong> IV loading = ' + S.d(wt, 150) + ' mg over 1h <span style="color:var(--g500);font-size:11px;">(150 mg/kg)</span>; 2nd bag = ' + S.d(wt, 50) + ' mg over 4h <span style="color:var(--g500);font-size:11px;">(50 mg/kg)</span>; 3rd bag = ' + S.d(wt, 100) + ' mg over 16h <span style="color:var(--g500);font-size:11px;">(100 mg/kg)</span>. <em>Total 300 mg/kg.</em></div>';
} else if (topic === 'opioids') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Opioid overdose</strong></div>';
html += '<p style="font-size:13px;">Triad: <strong>miosis + respiratory depression + ↓ LOC</strong>. Fentanyl / synthetics may require repeated/higher doses.</p>';
html += S.drugTable(
S.drugRow('Naloxone (initial)', '0.01-0.1 mg/kg' + (wt ? ' = ' + S.d(wt, 0.01) + '-' + S.d(wt, 0.1) + ' mg' : ''), 'IV / IM / IN / IO', 'Start low if chronic opioid use (avoid withdrawal). Titrate to respiratory effort, not consciousness.') +
S.drugRow('Naloxone (full reversal)', '2 mg IV/IM/IN', 'IV / IM / IN', 'If no chronic use and severe resp depression. Repeat q2-3 min.') +
S.drugRow('Naloxone infusion', '2/3 of effective bolus per hour', 'IV', 'For long-acting opioids (methadone, fentanyl patch, sustained release)')
);
html += '<div style="padding:10px;background:#fef3c7;border-radius:6px;font-size:12px;color:#92400e;margin-top:10px;">Observe ≥4h after last dose; longer for long-acting agents. Duration of naloxone (30-90 min) is shorter than most opioids — <strong>re-sedation is common</strong>.</div>';
} else if (topic === 'iron') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Iron overdose</strong></div>';
html += '<p style="font-size:13px;">Toxic dose: elemental Fe ≥20 mg/kg. Severe ≥60 mg/kg. <strong>Charcoal does NOT bind iron.</strong></p>';
html += '<p style="font-size:13px;"><strong>Stages:</strong> 1) GI (0-6h: vomiting, bloody diarrhea); 2) Latent (6-24h: deceptive improvement); 3) Shock/metabolic acidosis (12-24h); 4) Hepatotoxicity (2-5d); 5) Gastric scarring (2-8 wk).</p>';
html += S.drugTable(
S.drugRow('Whole bowel irrigation', 'PEG-ES 25-40 mL/kg/hr', 'NG', 'For radiopaque pills on KUB or ingested sustained-release iron.') +
S.drugRow('Deferoxamine', '15 mg/kg/hr IV infusion', 'IV', 'Max 6-8 g/day. Indications: shock, metabolic acidosis, Fe level &gt;500 mcg/dL, or severe symptoms. Urine turns "vin rosé" color.')
);
html += '<div style="padding:10px;background:#fef3c7;border-radius:6px;font-size:12px;color:#92400e;margin-top:10px;">Iron level at 4-6h. &lt;350 usually asymptomatic; 350-500 mild; &gt;500 severe. Consider KUB for radiopaque pills.</div>';
} else if (topic === 'tca') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>TCA overdose</strong></div>';
html += '<p style="font-size:13px;">Anticholinergic + Na-channel blockade. <strong>Risks:</strong> seizure, VT/VF, hypotension, coma. ECG: QRS &gt;100 ms or R in aVR &gt;3 mm predicts toxicity.</p>';
html += S.drugTable(
S.drugRow('Sodium bicarbonate 8.4%', '1-2 mEq/kg IV bolus → infusion', 'IV', 'Goal pH 7.45-7.55 and narrowing QRS. Repeat bolus for QRS widening, hypotension, or arrhythmia.') +
S.drugRow('Mg sulfate', S.dStr(wt || 30, 50, 2000, ' mg'), 'IV over 10 min', 'For torsades.') +
S.drugRow('IV lipid emulsion 20%', '1.5 mL/kg bolus → 0.25 mL/kg/min × 30-60 min', 'IV', 'If refractory shock/arrest. Consult toxicology.')
);
html += '<div style="padding:10px;background:#fef3c7;border-radius:6px;font-size:12px;color:#92400e;margin-top:10px;"><strong>Avoid</strong> Class IA/IC antiarrhythmics, beta-blockers, physostigmine (risk of asystole with TCAs).</div>';
} else if (topic === 'bbccb') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>β-blocker / Calcium-channel blocker overdose</strong></div>';
html += '<p style="font-size:13px;">Bradycardia + hypotension. CCBs (esp. verapamil, diltiazem, amlodipine) can be lethal in small pediatric doses.</p>';
html += S.drugTable(
S.drugRow('IV fluids', '20 mL/kg NS bolus', 'IV', 'Cautious — avoid volume overload') +
S.drugRow('Calcium chloride 10% or gluconate', 'CaCl 20 mg/kg / Ca-glu 60 mg/kg', 'IV', 'First-line for CCB. Repeat q15-20 min.') +
S.drugRow('Glucagon', '50 mcg/kg IV bolus → 50-150 mcg/kg/hr', 'IV', 'β-blocker antidote. GI side effects common.') +
S.drugRow('High-dose insulin (HIE)', 'Regular insulin 1 U/kg bolus → 0.5-2 U/kg/hr + D25% infusion', 'IV', 'Hyperinsulinemic euglycemia therapy. Monitor K+ and glucose closely.') +
S.drugRow('Vasopressors', 'Epi / norepi infusion', 'IV', 'Titrate to MAP.') +
S.drugRow('Lipid emulsion 20%', '1.5 mL/kg → 0.25 mL/kg/min', 'IV', 'For lipid-soluble CCBs (verapamil) if refractory.') +
S.drugRow('Methylene blue / ECMO', '—', '—', 'Rescue therapy — toxicology/ICU consult.')
);
} else if (topic === 'benzo') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Benzodiazepine overdose</strong></div>';
html += '<p style="font-size:13px;">Sedation + resp depression. Usually supportive — intubation rarely needed alone. <strong>Flumazenil caution.</strong></p>';
html += S.drugTable(
S.drugRow('Flumazenil', '0.01 mg/kg (max 0.2 mg) IV, may repeat q1 min to max 1 mg', 'IV', 'Only for iatrogenic reversal in a benzo-naive patient with no TCAs, seizure disorder, or chronic benzo use. <strong>Can precipitate seizures.</strong>')
);
html += '<div style="padding:10px;background:#fef3c7;border-radius:6px;font-size:12px;color:#92400e;margin-top:10px;">In real-world ingestion, <strong>supportive care (airway, monitoring)</strong> is usually safer than flumazenil.</div>';
} else if (topic === 'organo') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Organophosphate / carbamate poisoning</strong></div>';
html += '<p style="font-size:13px;">Cholinergic toxidrome: <strong>SLUDGE-M</strong> (salivation, lacrimation, urination, defecation, GI distress, emesis, miosis) + muscle fasciculation, bradycardia, bronchorrhea. Decontamination critical (PPE for providers).</p>';
html += S.drugTable(
S.drugRow('Atropine', '0.05 mg/kg IV, double q3-5 min until bronchial secretions dry', 'IV', 'Endpoint = dry lungs, not dry mouth or heart rate. Can require huge doses.') +
S.drugRow('Pralidoxime (2-PAM)', '25-50 mg/kg IV over 30 min (max 2 g) → 10-20 mg/kg/hr', 'IV', 'Only for organophosphates (not carbamates). Regenerates acetylcholinesterase.') +
S.drugRow('Diazepam / midazolam', 'Standard seizure doses', 'IV', 'For seizures or severe fasciculations.')
);
} else if (topic === 'salicylate') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Salicylate overdose</strong></div>';
html += '<p style="font-size:13px;">Mixed respiratory alkalosis + anion gap metabolic acidosis. Tinnitus, tachypnea, diaphoresis, hyperthermia. Severe: CNS depression, seizures, pulmonary edema, cerebral edema.</p>';
html += S.drugTable(
S.drugRow('Fluids', 'Aggressive resuscitation', 'IV', 'Dehydration common. Avoid fluid overload (risk of pulmonary edema).') +
S.drugRow('Sodium bicarb', '1-2 mEq/kg IV bolus → drip', 'IV', 'Urinary alkalinization (goal urine pH &gt;7.5). Prevents CNS entry.') +
S.drugRow('Glucose', 'Maintain euglycemia even if BG normal', 'IV', 'CNS hypoglycemia despite normal serum glucose.') +
S.drugRow('Hemodialysis', '—', '—', 'For severe: altered MS, pulmonary edema, renal failure, refractory acidosis, or level &gt;100 mg/dL acute / &gt;60 chronic.')
);
} else if (topic === 'etoh') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Toxic alcohols (methanol / ethylene glycol)</strong></div>';
html += '<p style="font-size:13px;">Anion gap metabolic acidosis + osmolar gap. Methanol → visual changes, blindness. Ethylene glycol → calcium oxalate crystals in urine, renal failure.</p>';
html += S.drugTable(
S.drugRow('Fomepizole', '15 mg/kg IV load → 10 mg/kg q12h × 4 → 15 mg/kg q12h', 'IV', 'First-line. Inhibits alcohol dehydrogenase.') +
S.drugRow('Ethanol (alternative)', 'Load 600 mg/kg → maintain level 100-150 mg/dL', 'IV / PO', 'If fomepizole unavailable. Monitor closely.') +
S.drugRow('Hemodialysis', '—', '—', 'For severe acidosis, end-organ damage, or high levels.') +
S.drugRow('Folate / thiamine / pyridoxine', 'Standard doses', 'IV', 'Methanol: folate. EG: thiamine + pyridoxine (divert to non-toxic metabolites).')
);
} else if (topic === 'dialyzable') {
html += '<div style="padding:10px 14px;border-radius:8px;background:var(--blue-light);border:1.5px solid var(--blue);margin-bottom:10px;"><strong>Dialyzable drugs (ISTUMBLE)</strong></div>';
html += '<p style="font-size:13px;">Commonly dialyzable in overdose:</p>';
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:6px;font-size:13px;">';
[['I','Isopropyl alcohol, INH'],['S','Salicylates'],['T','Theophylline, Toxic alcohols'],['U','Uremia-related drugs'],['M','Methanol, Metformin, Methotrexate'],['B','Barbiturates (long-acting)'],['L','Lithium'],['E','Ethylene glycol']].forEach(function(x) {
html += '<div style="padding:8px 10px;background:var(--g50);border-radius:6px;"><strong>' + x[0] + ':</strong> ' + x[1] + '</div>';
});
html += '</div>';
html += '<div style="padding:10px;background:#fef3c7;border-radius:6px;font-size:12px;color:#92400e;margin-top:10px;"><strong>Poor candidates for HD:</strong> Large Vd (TCAs, digoxin, BBs), highly protein-bound (benzos, CCBs), lipid-soluble (opioids, phenothiazines). EXTRIP recommendations are evidence-based — consult toxicology.</div>';
}
html += S.ref('Call Poison Control early: 1-800-222-1222 (US). Refs: Goldfrank\'s Toxicologic Emergencies, EXTRIP workgroup.');
el.innerHTML = html;
}
export function init() {
document.addEventListener('click', function(e) {
if (e.target.id === 'btn-tox-lookup' || e.target.closest('#btn-tox-lookup')) lookupTox();
});
}