diff --git a/public/components/calculators.html b/public/components/calculators.html index 63a9710..ea34f48 100644 --- a/public/components/calculators.html +++ b/public/components/calculators.html @@ -12,6 +12,7 @@ + @@ -419,25 +420,23 @@

Normal Vital Signs by Age

- Harriet Lane Handbook, 23rd Edition + Johns Hopkins Children's Center Kids Kard
-

Select age group to view normal vital sign ranges. Source: Harriet Lane Handbook, 23rd Ed. (Johns Hopkins).

+

Select age group to view normal vital sign ranges. Source: Johns Hopkins Children's Center Kids Kard.

@@ -449,19 +448,17 @@
- + - - - - - - - - - - + + + + + + + +
AgeHR (bpm)RRSBP (mmHg)DBP (mmHg)Temp (C)
AgeHR (bpm)RRBP (mmHg)Temp (C)
Preterm120-17040-7055-7535-4536.5-37.5
Newborn100-16530-6060-8035-5536.5-37.5
1-6 mo100-15030-5370-9040-6336.5-37.5
6-12 mo80-14025-4072-9540-6536.0-37.5
1-3 yr80-13020-3080-10545-7036.0-37.5
4-5 yr75-12020-2585-10848-7036.0-37.5
6-9 yr70-11518-2488-11550-7536.0-37.5
10-12 yr65-11016-2295-12055-7836.0-37.5
13-15 yr60-10014-20100-12858-8036.0-37.5
16-18 yr55-9512-18105-13560-8536.0-37.5
Premie120-17040-7055-75/35-4536.5-37.5
0-3 mo100-15035-5565-85/45-5536.5-37.5
3-6 mo90-12030-4570-90/50-6536.5-37.5
6-12 mo80-12025-4080-100/55-6536.0-37.5
1-3 yr70-11020-3090-105/55-7036.0-37.5
3-6 yr65-11020-2595-110/60-7536.0-37.5
6-12 yr60-9514-22100-120/60-7536.0-37.5
>12 yr55-8512-18110-135/65-8536.0-37.5
@@ -498,3 +495,25 @@
+ + + diff --git a/public/js/calculators.js b/public/js/calculators.js index bab81d6..09e3e92 100644 --- a/public/js/calculators.js +++ b/public/js/calculators.js @@ -1434,8 +1434,8 @@ // ═══════════════════════════════════════════════════════════ var VITALS_DATA = { - preterm: { - label: 'Preterm (<37 weeks GA)', + premie: { + label: 'Premie', hr: { awake: '120-170', sleeping: '100-150' }, rr: '40-70', sbp: '55-75', dbp: '35-45', @@ -1450,29 +1450,29 @@ 'Bradycardia (<100 bpm) and apnea are common in premature infants' ] }, - newborn: { - label: 'Newborn (0-28 days)', - hr: { awake: '100-165', sleeping: '90-145' }, - rr: '30-60', - sbp: '60-80', dbp: '35-55', + '0-3mo': { + label: '0-3 Months', + hr: { awake: '100-150', sleeping: '85-135' }, + rr: '35-55', + sbp: '65-85', dbp: '45-55', temp: '36.5-37.5', - weight: '2.5-4.5 kg', + weight: '2.5-6 kg', spo2: '>95%', notes: [ 'HR normally increases with crying (up to 180-190 bpm) — this is physiologic', - 'Periodic breathing (pauses <10 sec) is normal in newborns', + 'Periodic breathing (pauses <10 sec) is normal in neonates', 'Acrocyanosis (blue hands/feet) is normal; central cyanosis is not', - 'BP is best measured in the right arm (pre-ductal)', + 'BP is best measured in the right arm (pre-ductal) in neonates', 'Normal weight loss of 5-7% in first 3-5 days; regain by 10-14 days' ] }, - '1-6mo': { - label: '1-6 Months', - hr: { awake: '100-150', sleeping: '85-135' }, - rr: '30-53', - sbp: '70-90', dbp: '40-63', + '3-6mo': { + label: '3-6 Months', + hr: { awake: '90-120', sleeping: '75-110' }, + rr: '30-45', + sbp: '70-90', dbp: '50-65', temp: '36.5-37.5', - weight: '4-8 kg', + weight: '5-8 kg', spo2: '>95%', notes: [ 'Expected weight gain: 20-30 g/day (150-200 g/week)', @@ -1483,9 +1483,9 @@ }, '6-12mo': { label: '6-12 Months', - hr: { awake: '80-140', sleeping: '75-130' }, + hr: { awake: '80-120', sleeping: '70-110' }, rr: '25-40', - sbp: '72-95', dbp: '40-65', + sbp: '80-100', dbp: '55-65', temp: '36.0-37.5', weight: '8-10 kg', spo2: '>95%', @@ -1498,109 +1498,79 @@ }, '1-3yr': { label: '1-3 Years', - hr: { awake: '80-130', sleeping: '70-120' }, + hr: { awake: '70-110', sleeping: '60-100' }, rr: '20-30', - sbp: '80-105', dbp: '45-70', + sbp: '90-105', dbp: '55-70', temp: '36.0-37.5', weight: '10-15 kg', spo2: '>95%', notes: [ 'Expected weight gain: ~200-250 g/month (2-2.5 kg/year)', - 'Tachycardia: HR >130 at rest warrants evaluation', + 'Tachycardia: HR >110 at rest warrants evaluation', 'Tachypnea: RR >30 at rest may indicate respiratory distress', 'BP screening begins at age 3 per AAP 2017 guidelines', 'Estimated weight: 2 x (age in years) + 8' ] }, - '4-5yr': { - label: '4-5 Years', - hr: { awake: '75-120', sleeping: '65-110' }, + '3-6yr': { + label: '3-6 Years', + hr: { awake: '65-110', sleeping: '55-100' }, rr: '20-25', - sbp: '85-108', dbp: '48-70', + sbp: '95-110', dbp: '60-75', temp: '36.0-37.5', - weight: '15-20 kg', + weight: '14-20 kg', spo2: '>95%', notes: [ 'Annual BP screening recommended from age 3', 'Normal BP <90th percentile for age, sex, and height', 'Elevated BP: 90th to <95th percentile (or 120/80 if lower)', 'Estimated weight: 2 x (age in years) + 8', - 'ETT size (uncuffed): (age/4) + 4 = 5.0-5.25' + 'ETT size (uncuffed): (age/4) + 4' ] }, - '6-9yr': { - label: '6-9 Years', - hr: { awake: '70-115', sleeping: '60-105' }, - rr: '18-24', - sbp: '88-115', dbp: '50-75', + '6-12yr': { + label: '6-12 Years', + hr: { awake: '60-95', sleeping: '50-85' }, + rr: '14-22', + sbp: '100-120', dbp: '60-75', temp: '36.0-37.5', - weight: '20-30 kg', + weight: '20-40 kg', spo2: '>95%', notes: [ - 'Resting HR >115 or <60 warrants evaluation', + 'Resting HR >95 or <60 warrants evaluation', 'BP should be measured at every clinical encounter', 'Stage 1 HTN: >=95th percentile on 3 separate occasions', 'Estimated weight: 3 x (age in years) + 7', - 'ETT size (cuffed): (age/4) + 3.5 = 5.0-5.75' + 'ETT size (cuffed): (age/4) + 3.5' ] }, - '10-12yr': { - label: '10-12 Years', - hr: { awake: '65-110', sleeping: '58-100' }, - rr: '16-22', - sbp: '95-120', dbp: '55-78', - temp: '36.0-37.5', - weight: '30-45 kg', - spo2: '>95%', - notes: [ - 'Pre-pubertal and early pubertal changes may affect vitals', - 'Orthostatic hypotension may emerge during growth spurts', - 'BP classification uses percentile tables for age <13', - 'HR may decrease with athletic training', - 'ETT size (cuffed): (age/4) + 3.5 = 6.0-6.5' - ] - }, - '13-15yr': { - label: '13-15 Years', - hr: { awake: '60-100', sleeping: '50-90' }, - rr: '14-20', - sbp: '100-128', dbp: '58-80', - temp: '36.0-37.5', - weight: '45-65 kg', - spo2: '>95%', - notes: [ - 'From age 13: use adult BP thresholds (AAP 2017)', - 'Normal: <120/<80 mmHg', - 'Elevated: 120-129/<80 mmHg', - 'Stage 1 HTN: 130-139/80-89 mmHg', - 'Stage 2 HTN: >=140/>=90 mmHg', - 'Athletic bradycardia (HR 45-60) may be normal in trained adolescents' - ] - }, - '16-18yr': { - label: '16-18 Years', - hr: { awake: '55-95', sleeping: '45-85' }, + '>12yr': { + label: '>12 Years', + hr: { awake: '55-85', sleeping: '45-75' }, rr: '12-18', - sbp: '105-135', dbp: '60-85', + sbp: '110-135', dbp: '65-85', temp: '36.0-37.5', - weight: '55-80 kg', + weight: '40-80 kg', spo2: '>95%', notes: [ 'Vital signs approach adult values', - 'Adult BP thresholds apply (same as age 13+)', + 'From age 13: use adult BP thresholds (AAP 2017)', + 'Normal: <120/<80 mmHg; Elevated: 120-129/<80 mmHg', + 'Stage 1 HTN: 130-139/80-89 mmHg; Stage 2 HTN: >=140/>=90 mmHg', 'Orthostatic vitals: measure lying, sitting, standing if dizzy', - 'Positive orthostatic test: SBP drop >20 or DBP drop >10 on standing', - 'Consider screening for eating disorders if bradycardia + low BMI' + 'Athletic bradycardia (HR 45-60) may be normal in trained adolescents' ] } }; - // Delay slightly to ensure DOM is ready for hidden panels - setTimeout(function() { - var vitalsSelect = document.getElementById('vitals-age-select'); - if (vitalsSelect) { - vitalsSelect.addEventListener('change', function() { - var key = vitalsSelect.value; + // Use event delegation on the vitals panel so the listener works even + // when the panel is hidden at init time (hidden elements are still in the DOM, + // but a setTimeout-based approach can race with dynamic content loading). + var vitalsPanel = document.getElementById('calc-vitals'); + if (vitalsPanel) { + vitalsPanel.addEventListener('change', function(e) { + if (e.target.id !== 'vitals-age-select') return; + var key = e.target.value; var resultDiv = document.getElementById('vitals-result'); if (!key || !VITALS_DATA[key]) { resultDiv.classList.add('hidden'); return; } @@ -1628,6 +1598,245 @@ ''; }); } - }, 100); // end setTimeout for vitals + + // ═══════════════════════════════════════════════════════════ + // RESUSCITATION MEDICATIONS — Johns Hopkins Kids Kard / AHA PALS 2020 + // ═══════════════════════════════════════════════════════════ + + var RESUS_MEDS = [ + { + name: 'Adenosine', indication: 'SVT', category: 'cardiac', + route: 'IV/IO rapid bolus', + calc: function(w) { + var d1 = +(w * 0.1).toFixed(2); + var d2 = +(w * 0.2).toFixed(2); + var d3 = +(w * 0.3).toFixed(2); + return { + dose: d1 + ' mg (0.1 mg/kg)', + extra: 'May repeat: ' + Math.min(d2, 12) + ' mg (0.2 mg/kg), then ' + Math.min(d3, 12) + ' mg (0.3 mg/kg)', + max: 'Max first dose 6 mg, max subsequent 12 mg' + }; + } + }, + { + name: 'Amiodarone', indication: 'VT / VF', category: 'cardiac', + route: 'IV/IO', + calc: function(w) { + var d = +(w * 5).toFixed(1); + return { + dose: Math.min(d, 300) + ' mg (5 mg/kg)', + extra: 'No pulse: push undiluted. Pulse: over 20-60 min. Subsequent max 150 mg.', + max: 'Max first 300 mg, max total 15 mg/kg/24hr or 2200 mg' + }; + } + }, + { + name: 'Atropine', indication: 'Bradycardia', category: 'cardiac', + route: 'IV/IO/IM', + calc: function(w) { + var d = +(w * 0.02).toFixed(3); + var ett = (w * 0.04).toFixed(3) + '-' + (w * 0.06).toFixed(3); + return { + dose: Math.min(d, 0.5) + ' mg (0.02 mg/kg)', + extra: 'ETT dose: ' + ett + ' mg (0.04-0.06 mg/kg)', + max: 'Max single 0.5 mg, max total 1 mg' + }; + } + }, + { + name: 'Calcium Chloride 10%', indication: 'Hypocalcemia / Hyperkalemia', category: 'metabolic', + route: 'IV/IO', + calc: function(w) { + var d = +(w * 20).toFixed(0); + return { + dose: Math.min(d, 1000) + ' mg (20 mg/kg)', + extra: 'Give slowly. Central line preferred.', + max: 'Max 1 g (1000 mg)' + }; + } + }, + { + name: 'Calcium Gluconate 10%', indication: 'Hypocalcemia / Hyperkalemia', category: 'metabolic', + route: 'IV/IO', + calc: function(w) { + var d = +(w * 60).toFixed(0); + return { + dose: Math.min(d, 3000) + ' mg (60 mg/kg)', + extra: 'Give slowly over 10-20 min with cardiac monitoring.', + max: 'Max 3 g (3000 mg)' + }; + } + }, + { + name: 'Dextrose', indication: 'Hypoglycemia', category: 'metabolic', + route: 'IV', + calc: function(w) { + var grams = +(w * 0.5).toFixed(1) + '-' + +(w * 1).toFixed(1); + var detail = ''; + if (w < 5) { + var ml = (w * 5).toFixed(1) + '-' + (w * 10).toFixed(1); + detail = 'D10W: ' + ml + ' mL (5-10 mL/kg)'; + } else if (w < 45) { + var ml = (w * 2).toFixed(1) + '-' + (w * 4).toFixed(1); + detail = 'D25W: ' + ml + ' mL (2-4 mL/kg)'; + } else { + var ml = (w * 1).toFixed(1) + '-' + (w * 2).toFixed(1); + detail = 'D50W: ' + ml + ' mL (1-2 mL/kg)'; + } + return { + dose: grams + ' g (0.5-1 g/kg)', + extra: detail, + max: 'Max 25 g' + }; + } + }, + { + name: 'Epinephrine', indication: 'Pulseless arrest / Anaphylaxis', category: 'cardiac', + route: 'IV/IO/IM/ETT', + calc: function(w) { + var iv = +(w * 0.01).toFixed(3); + var ivVol = +(w * 0.1).toFixed(2); + var ett = +(w * 0.1).toFixed(2); + var im = +(w * 0.01).toFixed(3); + return { + dose: Math.min(iv, 1) + ' mg IV/IO (0.01 mg/kg of 0.1 mg/mL = ' + Math.min(ivVol, 10) + ' mL) q3-5 min', + extra: 'ETT: ' + Math.min(ett, 2.5) + ' mg (0.1 mg/kg of 1 mg/mL). Anaphylaxis IM: ' + Math.min(im, 0.5) + ' mg (0.01 mg/kg)', + max: 'Max IV 1 mg, max ETT 2.5 mg, max IM 0.5 mg' + }; + } + }, + { + name: 'Hydrocortisone', indication: 'Adrenal crisis', category: 'metabolic', + route: 'IV/IM/IO', + calc: function(w) { + var d = +(w * 2).toFixed(1); + return { + dose: Math.min(d, 100) + ' mg (2 mg/kg)', + extra: 'Stress dosing for adrenal insufficiency.', + max: 'Max 100 mg' + }; + } + }, + { + name: 'Insulin (Regular)', indication: 'Hyperkalemia', category: 'metabolic', + route: 'IV', + calc: function(w) { + var d = +(w * 0.1).toFixed(2); + var dex = +(w * 0.5).toFixed(1); + return { + dose: Math.min(d, 5) + ' units (0.1 units/kg)', + extra: 'Give with ' + dex + ' g/kg dextrose (0.5 g/kg). Monitor glucose closely.', + max: 'Max 5 units' + }; + } + }, + { + name: 'Lidocaine', indication: 'Antiarrhythmic', category: 'cardiac', + route: 'IV/IO', + calc: function(w) { + var d = +(w * 1).toFixed(1); + var ett = (w * 2).toFixed(1) + '-' + (w * 3).toFixed(1); + return { + dose: Math.min(d, 100) + ' mg (1 mg/kg)', + extra: 'ETT: ' + ett + ' mg (2-3 mg/kg). May repeat q5 min.', + max: 'Max 100 mg/dose, max total 3 mg/kg' + }; + } + }, + { + name: 'Magnesium Sulfate', indication: 'Torsades de Pointes', category: 'cardiac', + route: 'IV/IO', + calc: function(w) { + var d = +(w * 50).toFixed(0); + return { + dose: Math.min(d, 2000) + ' mg (50 mg/kg)', + extra: 'Give over 10-20 min (faster if pulseless).', + max: 'Max 2 g (2000 mg)' + }; + } + }, + { + name: 'Naloxone', indication: 'Opioid overdose', category: 'reversal', + route: 'IV/IO/IM/IN/ETT', + calc: function(w) { + var partial = +(w * 0.001).toFixed(4) + '-' + +(w * 0.005).toFixed(4); + var full = +(w * 0.1).toFixed(3); + return { + dose: 'Partial: ' + partial + ' mg (0.001-0.005 mg/kg)', + extra: 'Full reversal: ' + Math.min(full, 2) + ' mg (0.1 mg/kg)', + max: 'Max partial first dose 0.1 mg, max full 2 mg' + }; + } + }, + { + name: 'Sodium Bicarbonate', indication: 'Metabolic acidosis', category: 'metabolic', + route: 'IV/IO', + calc: function(w) { + var d = +(w * 1).toFixed(1); + return { + dose: Math.min(d, 50) + ' mEq (1 mEq/kg)', + extra: w < 10 ? 'Dilute to 0.5 mEq/mL (use 4.2% solution) for neonates/small infants.' : 'Use 8.4% solution (1 mEq/mL).', + max: 'Max 50 mEq' + }; + } + } + ]; + + var categoryColors = { cardiac: '#ef4444', metabolic: '#3b82f6', reversal: '#10b981' }; + var categoryLabels = { cardiac: 'Cardiac', metabolic: 'Metabolic', reversal: 'Reversal' }; + + // Use event delegation for resus panel + var resusPanel = document.getElementById('calc-resus'); + if (resusPanel) { + resusPanel.addEventListener('click', function(e) { + var btn = e.target.closest('#btn-calc-resus, #btn-clear-resus'); + if (!btn) return; + + if (btn.id === 'btn-clear-resus') { + var wi = document.getElementById('resus-weight'); if (wi) wi.value = ''; + var rd = document.getElementById('resus-result'); if (rd) { rd.classList.add('hidden'); rd.innerHTML = ''; } + return; + } + + // Calculate + var weightEl = document.getElementById('resus-weight'); + var resultDiv = document.getElementById('resus-result'); + var w = parseFloat(weightEl.value); + if (!w || w <= 0) { alert('Please enter a valid weight.'); return; } + + var html = '
Doses for ' + w + ' kg patient
'; + html += '
'; + Object.keys(categoryColors).forEach(function(cat) { + html += '' + categoryLabels[cat] + ''; + }); + html += '
'; + html += '
'; + + RESUS_MEDS.forEach(function(med) { + var r = med.calc(w); + var color = categoryColors[med.category] || '#6b7280'; + html += '
' + + '
' + + '
' + med.name + '
' + + '
' + med.indication + '
' + + '
' + + '
' + + '
Dose: ' + r.dose + '
' + + '
' + r.extra + '
' + + '
Max: ' + r.max + '
' + + '
Route: ' + med.route + '
' + + '
' + + '
'; + }); + + html += '
'; + html += '
' + + 'Disclaimer: Always verify doses against institutional protocols and current guidelines. This tool is for educational reference only.' + + '
'; + + resultDiv.innerHTML = html; + resultDiv.classList.remove('hidden'); + }); + } } })();