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.
103 lines
8 KiB
JavaScript
103 lines
8 KiB
JavaScript
// ============================================================
|
|
// bedside/cardiac.js
|
|
// CARDIAC ARREST / PALS.
|
|
// ============================================================
|
|
|
|
import { S } from './shared.js';
|
|
|
|
function getWt() {
|
|
return parseFloat(document.getElementById('cardiac-weight').value) || 0;
|
|
}
|
|
|
|
function title(k) {
|
|
return { general: 'PALS General Doses', asystole: 'Asystole / PEA', brady: 'Bradycardia', svt: 'SVT', vfib: 'VF / Pulseless VT', vt: 'Stable VT' }[k] || k;
|
|
}
|
|
|
|
function cardiacShow(kind) {
|
|
var wt = getWt();
|
|
var el = document.getElementById('cardiac-result');
|
|
if (!wt) { el.innerHTML = '<p style="color:var(--red);font-size:13px;">Enter weight (kg).</p>'; return; }
|
|
var html = '<div style="padding:10px 14px;border-radius:8px;background:var(--red)10;border:1.5px solid var(--red);margin-bottom:10px;"><strong style="color:var(--red);">' + title(kind) + ' — ' + wt + ' kg</strong></div>';
|
|
|
|
if (kind === 'general') {
|
|
html += S.drugTable(
|
|
S.drugRow('Epinephrine 1:10,000', S.dStr(wt, 0.01, 1, ' mg') + ' (' + S.dStr(wt, 0.1, 10, ' mL') + ')', 'IV / IO', '0.01 mg/kg = 0.1 mL/kg of 1:10,000. Max single dose 1 mg. Repeat q3-5 min.') +
|
|
S.drugRow('Epinephrine ET', S.dStr(wt, 0.1, 2.5, ' mg'), 'ETT', '0.1 mg/kg (1 mL/kg of 1:10,000) if no IV/IO') +
|
|
S.drugRow('Amiodarone', S.dStr(wt, 5, 300, ' mg'), 'IV / IO bolus', '5 mg/kg for arrest. Max 300 mg. Repeat up to 2 times (max 15 mg/kg/day).') +
|
|
S.drugRow('Lidocaine', S.dStr(wt, 1, 100, ' mg'), 'IV / IO bolus', '1 mg/kg. Alternative to amiodarone for VF/VT.') +
|
|
S.drugRow('Atropine', S.dStr(wt, 0.02, 0.5, ' mg') + ' (min 0.1 mg)', 'IV / IO', '0.02 mg/kg. Bradycardia from ↑vagal tone or AV block.') +
|
|
S.drugRow('Adenosine (1st)', S.dStr(wt, 0.1, 6, ' mg'), 'IV push + flush', '0.1 mg/kg (max 6 mg). For SVT. Rapid push, double flush.') +
|
|
S.drugRow('Adenosine (2nd)', S.dStr(wt, 0.2, 12, ' mg'), 'IV push + flush', '0.2 mg/kg (max 12 mg). Second dose if first unsuccessful.') +
|
|
S.drugRow('Sodium bicarb 8.4%', S.dStr(wt, 1, 50, ' mEq'), 'IV / IO', '1 mEq/kg. ONLY if severe metabolic acidosis, hyperK, or TCA OD. Not routine.') +
|
|
S.drugRow('Calcium chloride 10%', S.dStr(wt, 20, 1000, ' mg') + ' (' + S.dStr(wt, 0.2, 10, ' mL') + ')', 'IV / IO (central preferred)', 'For hyperK, hypoCa, Mg OD, CCB OD. 20 mg/kg = 0.2 mL/kg.') +
|
|
S.drugRow('Calcium gluconate 10%', S.dStr(wt, 60, 3000, ' mg') + ' (' + S.dStr(wt, 0.6, 30, ' mL') + ')', 'IV / IO (peripheral OK)', '60 mg/kg = 0.6 mL/kg. Preferred peripherally.') +
|
|
S.drugRow('Magnesium sulfate', S.dStr(wt, 50, 2000, ' mg'), 'IV over 10-20 min', '25-50 mg/kg. Torsades, severe asthma. Max 2 g.') +
|
|
S.drugRow('Dextrose 10%', S.dStr(wt, 2, null, ' mL') + ' (0.2 g/kg)', 'IV push', 'For documented hypoglycemia') +
|
|
S.drugRow('Defibrillation', '2 J/kg → 4 J/kg → 10 J/kg (max 10 J/kg or adult dose)', 'Pad', 'For VF/pulseless VT. Resume CPR immediately after shock.') +
|
|
S.drugRow('Cardioversion (sync)', '0.5-1 J/kg → 2 J/kg', 'Pad', 'For unstable SVT/VT. Sedate if possible.')
|
|
);
|
|
html += '<div style="padding:10px;background:#fef3c7;border-radius:6px;font-size:12px;color:#92400e;margin-top:10px;"><strong>Concentrations:</strong> Epi 1:10,000 (0.1 mg/mL) for IV arrest. 1:1000 (1 mg/mL) for IM anaphylaxis. Atropine <0.1 mg can cause paradoxical bradycardia.</div>';
|
|
} else if (kind === 'asystole') {
|
|
html += S.drugTable(
|
|
S.drugRow('CPR', '100-120/min, depth 1/3 AP', '—', '15:2 (2 rescuer) or 30:2 (single). Rotate every 2 min.') +
|
|
S.drugRow('Epinephrine', S.dStr(wt, 0.01, 1, ' mg') + ' IV/IO', 'IV / IO', '0.01 mg/kg 1:10,000 = 0.1 mL/kg. Q3-5 min. Start early.') +
|
|
S.drugRow('Epinephrine ETT', S.dStr(wt, 0.1, 2.5, ' mg'), 'ETT', '0.1 mg/kg if no IV access')
|
|
);
|
|
html += '<h5 style="font-size:13px;font-weight:700;color:var(--g700);margin:14px 0 6px;">Reversible causes (H\'s & T\'s)</h5>';
|
|
html += '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:6px;font-size:12px;">';
|
|
html += '<div style="padding:8px;background:var(--g50);border-radius:6px;"><strong>H\'s</strong><br>Hypoxia, Hypovolemia, H+ (acidosis), Hypo/hyperK, Hypoglycemia, Hypothermia</div>';
|
|
html += '<div style="padding:8px;background:var(--g50);border-radius:6px;"><strong>T\'s</strong><br>Tension PTX, Tamponade, Toxins, Thrombosis (MI/PE), Trauma</div>';
|
|
html += '</div>';
|
|
} else if (kind === 'brady') {
|
|
html += S.stepBox('#f59e0b', 'Bradycardia with poor perfusion (HR < 60)', 'Start CPR if HR < 60 with poor perfusion despite oxygenation and ventilation.');
|
|
html += S.arrow;
|
|
html += S.drugTable(
|
|
S.drugRow('Epinephrine', S.dStr(wt, 0.01, 1, ' mg'), 'IV / IO', 'First-line. Q3-5 min.') +
|
|
S.drugRow('Atropine', S.dStr(wt, 0.02, 0.5, ' mg') + ' (min 0.1 mg)', 'IV / IO', 'If ↑ vagal tone or AV block. Max 1 mg child / 0.5 mg infant.') +
|
|
S.drugRow('Transcutaneous pacing', '—', 'Pad', 'For refractory bradycardia not responsive to drugs.') +
|
|
S.drugRow('Consider', '—', '—', 'Hypoxia, tension pneumothorax, ↑ICP, toxic ingestion (organo, CCB, BB), heart block')
|
|
);
|
|
} else if (kind === 'svt') {
|
|
html += S.stepBox('#3b82f6', 'SVT — narrow complex, rate usually >220 infant / >180 child', 'Differentiate from sinus tach: abrupt onset/offset, no P waves or abnormal P axis, HR minimally variable.');
|
|
html += S.arrow;
|
|
html += '<h5 style="font-size:13px;font-weight:700;color:var(--g700);margin:6px 0;">If STABLE</h5>';
|
|
html += S.drugTable(
|
|
S.drugRow('Vagal maneuvers', 'Ice to face, blow into syringe, Valsalva', '—', 'Try first in stable patient') +
|
|
S.drugRow('Adenosine (1st)', S.dStr(wt, 0.1, 6, ' mg'), 'IV push (proximal) + flush', 'Rapid push, 3-way stopcock with NS flush') +
|
|
S.drugRow('Adenosine (2nd)', S.dStr(wt, 0.2, 12, ' mg'), 'IV push + flush', 'If first dose unsuccessful') +
|
|
S.drugRow('Procainamide', '15 mg/kg over 30-60 min', 'IV', 'Expert consult. Avoid with amiodarone.') +
|
|
S.drugRow('Amiodarone', '5 mg/kg over 20-60 min', 'IV', 'Expert consult.')
|
|
);
|
|
html += '<h5 style="font-size:13px;font-weight:700;color:var(--g700);margin:10px 0 4px;">If UNSTABLE</h5>';
|
|
html += S.drugTable(S.drugRow('Synchronized cardioversion', '0.5-1 J/kg → 2 J/kg', 'Pad', 'Sedate if possible. Pre-treat with adenosine if IV available.'));
|
|
} else if (kind === 'vfib') {
|
|
html += S.stepBox('#dc2626', 'VF / Pulseless VT', 'High-quality CPR + defibrillation are key. Minimize interruptions.');
|
|
html += S.arrow;
|
|
html += S.drugTable(
|
|
S.drugRow('Defibrillation (1st)', '2 J/kg', 'Pad', 'Resume CPR immediately after shock.') +
|
|
S.drugRow('Defibrillation (2nd)', '4 J/kg', 'Pad', 'After 2 min CPR.') +
|
|
S.drugRow('Defibrillation (3rd+)', '≥4 J/kg (max 10 J/kg or adult dose)', 'Pad', '') +
|
|
S.drugRow('Epinephrine', S.dStr(wt, 0.01, 1, ' mg'), 'IV / IO', 'After 2nd shock. Q3-5 min.') +
|
|
S.drugRow('Amiodarone', S.dStr(wt, 5, 300, ' mg'), 'IV / IO bolus', 'Refractory VF/VT. Max 15 mg/kg/day.') +
|
|
S.drugRow('Lidocaine', S.dStr(wt, 1, 100, ' mg'), 'IV / IO', 'Alternative to amiodarone. Then 20-50 mcg/kg/min gtt.') +
|
|
S.drugRow('Mg sulfate', S.dStr(wt, 50, 2000, ' mg'), 'IV over 1-2 min', 'For torsades or hypoMg.')
|
|
);
|
|
} else if (kind === 'vt') {
|
|
html += S.stepBox('#f59e0b', 'Stable monomorphic VT', 'Expert consult. Avoid combining QT-prolonging agents.');
|
|
html += S.arrow;
|
|
html += S.drugTable(
|
|
S.drugRow('Amiodarone', '5 mg/kg over 20-60 min', 'IV', '= ' + S.d(wt, 5, 300) + ' mg over 20-60 min') +
|
|
S.drugRow('Procainamide', '15 mg/kg over 30-60 min', 'IV', 'Do not combine with amiodarone') +
|
|
S.drugRow('Sync cardioversion', '0.5-1 → 2 J/kg', 'Pad', 'If becomes unstable. Sedate.')
|
|
);
|
|
}
|
|
html += S.ref('AHA PALS Guidelines 2020. Always verify against institutional protocols.');
|
|
el.innerHTML = html;
|
|
}
|
|
|
|
export function init() {
|
|
document.addEventListener('click', function(e) {
|
|
var btn = e.target.closest('[data-cardiac]');
|
|
if (btn) cardiacShow(btn.dataset.cardiac);
|
|
});
|
|
}
|