~/csom-anaesthesia-pptx/generate.js
const pptxgen = require("pptxgenjs");
const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.author = "Department of Anaesthesiology";
pres.title = "Anaesthesia for Tympanomastoidectomy in a Child";
// ── COLOR PALETTE ─────────────────────────────────────────────────────────────
// Deep navy dominates, teal accent, white text, warm amber highlights
const C = {
navy: "0A1628", // dominant dark bg
navyMid: "0E2040", // mid tone
teal: "1A9B8A", // accent
tealDark: "127A6D",
tealPale: "D0F0EB",
amber: "F0A500",
white: "FFFFFF",
offWhite: "EEF4F7",
gray: "8FA3B1",
grayLight:"C8D8E0",
red: "E84040",
green: "27AE60",
};
// ── HELPERS ───────────────────────────────────────────────────────────────────
function addSlideNumber(slide, num, total) {
slide.addText(`${num} / ${total}`, {
x: 9.3, y: 5.3, w: 0.6, h: 0.2,
fontSize: 9, color: C.gray, align: "right",
});
}
function sectionHeader(slide, title, subtitle) {
// Full-bleed dark bg
slide.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy } });
// Teal accent bar left
slide.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.08, h: 5.625, fill: { color: C.teal } });
// Decorative circle
slide.addShape(pres.shapes.OVAL, { x: 7.8, y: -1.2, w: 3.5, h: 3.5, fill: { color: C.navyMid }, line: { color: C.teal, width: 1.5 } });
slide.addText(title, {
x: 0.55, y: 1.9, w: 7, h: 1.0,
fontSize: 34, bold: true, color: C.white, fontFace: "Calibri Light",
});
if (subtitle) {
slide.addText(subtitle, {
x: 0.55, y: 2.95, w: 7, h: 0.55,
fontSize: 16, color: C.teal, fontFace: "Calibri",
});
}
}
function contentSlide(slide) {
slide.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.offWhite } });
slide.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 0.07, fill: { color: C.teal } });
slide.addShape(pres.shapes.RECTANGLE, { x: 0, y: 5.55, w: 10, h: 0.075, fill: { color: C.navy } });
}
function slideTitle(slide, title) {
slide.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0.07, w: 10, h: 0.7, fill: { color: C.navy } });
slide.addText(title, {
x: 0.3, y: 0.1, w: 9.4, h: 0.62,
fontSize: 18, bold: true, color: C.white, fontFace: "Calibri", valign: "middle",
});
}
function tealBadge(slide, label, x, y, w) {
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x, y, w, h: 0.32, fill: { color: C.teal }, rectRadius: 0.05,
});
slide.addText(label, {
x, y, w, h: 0.32, fontSize: 10, bold: true, color: C.white,
align: "center", valign: "middle",
});
}
function amberBadge(slide, label, x, y, w) {
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x, y, w, h: 0.32, fill: { color: C.amber }, rectRadius: 0.05,
});
slide.addText(label, {
x, y, w, h: 0.32, fontSize: 10, bold: true, color: C.navy,
align: "center", valign: "middle",
});
}
function vivaBox(slide, question, answer, x, y, w, h) {
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x, y, w, h, fill: { color: C.navyMid }, rectRadius: 0.1,
shadow: { type: "outer", color: "000000", blur: 8, offset: 2, angle: 135, opacity: 0.2 },
});
slide.addText("Q: " + question, {
x: x + 0.15, y: y + 0.1, w: w - 0.3, h: 0.35,
fontSize: 10, bold: true, color: C.amber, fontFace: "Calibri",
});
slide.addShape(pres.shapes.RECTANGLE, { x: x + 0.15, y: y + 0.46, w: w - 0.3, h: 0.02, fill: { color: C.teal } });
slide.addText(answer, {
x: x + 0.15, y: y + 0.5, w: w - 0.3, h: h - 0.65,
fontSize: 9, color: C.white, fontFace: "Calibri",
});
}
function bullets(items) {
return items.map((t, i) => ({
text: t,
options: { bullet: { code: "2022" }, breakLine: i < items.length - 1, fontSize: 12, color: C.navy },
}));
}
function bulletsTeal(items) {
return items.map((t, i) => ({
text: t,
options: { bullet: { code: "25B6" }, breakLine: i < items.length - 1, fontSize: 11, color: C.navyMid },
}));
}
// ═══════════════════════════════════════════════════════════════════
// TOTAL SLIDES: 28
// ═══════════════════════════════════════════════════════════════════
const TOTAL = 28;
// ── SLIDE 1: TITLE ───────────────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy } });
// Large decorative circle top-right
s.addShape(pres.shapes.OVAL, { x: 6.5, y: -1.5, w: 5, h: 5, fill: { color: C.navyMid }, line: { color: C.teal, width: 2 } });
// Small circle accent
s.addShape(pres.shapes.OVAL, { x: 8.6, y: 3.8, w: 1.8, h: 1.8, fill: { color: C.tealDark } });
// Bottom teal bar
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 5.15, w: 10, h: 0.475, fill: { color: C.teal } });
// Left accent bar
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.1, h: 5.625, fill: { color: C.teal } });
s.addText("ANAESTHESIA FOR", {
x: 0.4, y: 0.7, w: 7, h: 0.5,
fontSize: 14, color: C.teal, bold: true, charSpacing: 4, fontFace: "Calibri",
});
s.addText("Tympanomastoidectomy", {
x: 0.4, y: 1.2, w: 8, h: 1.0,
fontSize: 36, bold: true, color: C.white, fontFace: "Calibri Light",
});
s.addText("in a Paediatric Patient", {
x: 0.4, y: 2.2, w: 7, h: 0.6,
fontSize: 22, color: C.grayLight, fontFace: "Calibri Light",
});
s.addText([
{ text: "Case: ", options: { bold: true, color: C.amber } },
{ text: "12-year-old boy | CSOM | Elective Surgery", options: { color: C.white } },
], { x: 0.4, y: 3.0, w: 8, h: 0.4, fontSize: 13 });
s.addText([
{ text: "Long Case Presentation ", options: { bold: true, color: C.white } },
{ text: "MD Anaesthesia Final Practical Exam", options: { color: C.grayLight } },
], { x: 0.4, y: 5.18, w: 9, h: 0.38, fontSize: 12, valign: "middle" });
}
// ── SLIDE 2: LEARNING OBJECTIVES ─────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Learning Objectives");
const objs = [
"Present a structured long case of a child with CSOM planned for tympanomastoidectomy",
"Discuss preoperative assessment and optimisation specific to this case",
"Outline a safe intraoperative anaesthesia plan — with rationale for every key decision",
"Explain why TIVA and NO nitrous oxide are the cornerstones of anaesthetic management",
"Manage PONV, controlled hypotension, and facial nerve monitoring considerations",
"Handle postoperative analgesia, recovery, and potential complications",
"Answer high-yield viva questions at every stage of management",
];
objs.forEach((obj, i) => {
const yPos = 0.95 + i * 0.63;
s.addShape(pres.shapes.OVAL, { x: 0.22, y: yPos + 0.05, w: 0.28, h: 0.28, fill: { color: C.teal } });
s.addText(`${i + 1}`, {
x: 0.22, y: yPos + 0.05, w: 0.28, h: 0.28,
fontSize: 10, bold: true, color: C.white, align: "center", valign: "middle",
});
s.addText(obj, {
x: 0.65, y: yPos, w: 9.0, h: 0.42,
fontSize: 11.5, color: C.navyMid, fontFace: "Calibri", valign: "middle",
});
});
addSlideNumber(s, 2, TOTAL);
}
// ── SLIDE 3: CASE AT A GLANCE ─────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Case at a Glance");
// Patient info card
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.3, y: 0.9, w: 4.2, h: 4.4, fill: { color: C.navyMid }, rectRadius: 0.12,
shadow: { type: "outer", color: "000000", blur: 8, offset: 2, angle: 135, opacity: 0.2 },
});
s.addText("PATIENT PROFILE", {
x: 0.5, y: 1.0, w: 3.8, h: 0.35,
fontSize: 11, bold: true, color: C.teal, charSpacing: 3, align: "center",
});
s.addShape(pres.shapes.RECTANGLE, { x: 0.5, y: 1.35, w: 3.8, h: 0.03, fill: { color: C.teal } });
const patientDetails = [
["Age", "12 years"],
["Sex", "Male"],
["Weight", "~32 kg"],
["Diagnosis", "CSOM (Right ear)"],
["Procedure", "Tympanomastoidectomy"],
["ASA Status", "ASA I"],
["Surgery Type", "Elective"],
];
patientDetails.forEach(([label, val], i) => {
const y = 1.5 + i * 0.48;
s.addText(label + ":", { x: 0.55, y, w: 1.4, h: 0.38, fontSize: 10.5, color: C.grayLight, bold: true, valign: "middle" });
s.addText(val, { x: 2.0, y, w: 2.3, h: 0.38, fontSize: 10.5, color: C.white, valign: "middle" });
});
// Right side: key anaesthetic flags
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 4.8, y: 0.9, w: 4.9, h: 4.4, fill: { color: C.offWhite }, rectRadius: 0.12,
shadow: { type: "outer", color: "000000", blur: 6, offset: 2, angle: 135, opacity: 0.1 },
});
s.addText("KEY ANAESTHETIC FLAGS", {
x: 5.0, y: 1.0, w: 4.5, h: 0.35,
fontSize: 11, bold: true, color: C.navy, charSpacing: 3, align: "center",
});
s.addShape(pres.shapes.RECTANGLE, { x: 5.0, y: 1.35, w: 4.5, h: 0.03, fill: { color: C.amber } });
const flags = [
["NO Nitrous Oxide", "red", "Middle ear graft — pressure risk"],
["TIVA Preferred", "teal", "Propofol + Remifentanil"],
["PONV High Risk", "red", "Dual prophylaxis mandatory"],
["Facial Nerve Monitor", "amber", "No relaxants if NIM in use"],
["Deep Extubation", "teal", "Prevent cough on ETT"],
["Paediatric Dosing", "amber", "All drugs are weight-based"],
];
const flagColors = { red: C.red, teal: C.teal, amber: C.amber };
flags.forEach(([title, col, sub], i) => {
const y = 1.5 + i * 0.63;
s.addShape(pres.shapes.RECTANGLE, { x: 5.0, y: y + 0.08, w: 0.06, h: 0.32, fill: { color: flagColors[col] } });
s.addText(title, { x: 5.2, y, w: 2.5, h: 0.28, fontSize: 11, bold: true, color: C.navy, valign: "bottom" });
s.addText(sub, { x: 5.2, y: y + 0.28, w: 4.2, h: 0.25, fontSize: 9.5, color: C.gray, valign: "top" });
});
addSlideNumber(s, 3, TOTAL);
}
// ── SLIDE 4: SECTION HEADER — PREOPERATIVE ────────────────────────────────────
{
const s = pres.addSlide();
sectionHeader(s, "SECTION 1\nPreoperative Assessment", "History · Examination · Investigations · Optimisation");
s.addShape(pres.shapes.RECTANGLE, { x: 0.55, y: 1.85, w: 2.5, h: 0.07, fill: { color: C.teal } });
}
// ── SLIDE 5: HISTORY ──────────────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "History — Chief Complaint & HPI");
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 4.6, h: 4.45, fill: { color: C.navyMid }, rectRadius: 0.1 });
tealBadge(s, "CHIEF COMPLAINTS", 0.45, 0.98, 2.5);
s.addText([
...bullets([
"Persistent ear discharge — years duration",
"Decreased hearing (affected ear)",
"Occasional earache & headache",
"No facial palsy",
"No vertigo",
])
], { x: 0.45, y: 1.38, w: 4.2, h: 3.7, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.15, y: 0.9, w: 4.6, h: 4.45, fill: { color: C.offWhite }, rectRadius: 0.1 });
amberBadge(s, "ANAESTHETIC RELEVANCE", 5.35, 0.98, 3.0);
s.addText([
...bulletsTeal([
"No facial palsy → no facial canal erosion",
"No headache/neck stiffness → no intracranial extension",
"No previous anaesthesia → no known reactions",
"No family h/o adverse reactions (MH screen)",
"No NKDA — note clearly in chart",
"CSOM = obstructed Eustachian tube",
"→ N₂O will NOT vent → CONTRAINDICATED",
])
], { x: 5.35, y: 1.38, w: 4.2, h: 3.7, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
addSlideNumber(s, 5, TOTAL);
}
// ── SLIDE 6: AIRWAY ASSESSMENT ────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Airway Assessment — The Anaesthetist's Priority");
const rows = [
["Parameter", "Finding", "Grade"],
["Mouth opening", ">4 cm (>3 finger-breadths)", "✓ Adequate"],
["Mallampati class", "Class I–II", "✓ Easy intubation"],
["Thyromental distance", ">6.5 cm (>3 FB)", "✓ Adequate"],
["Neck mobility", "Full range", "✓ Unrestricted"],
["ULBT (jaw protrusion)", "Class A", "✓ Favourable"],
["Loose teeth", "Check permanent dentition", "Document"],
["Tonsil size", "Grade I–II", "Note if enlarged"],
["Predicted CL grade", "Grade I–II", "Easy laryngoscopy"],
];
const colW = [2.9, 3.4, 2.5];
const colX = [0.25, 3.2, 6.65];
const rowH = 0.46;
rows.forEach((row, ri) => {
const y = 0.9 + ri * rowH;
row.forEach((cell, ci) => {
const isHeader = ri === 0;
const bg = isHeader ? C.navy : (ri % 2 === 0 ? C.white : C.offWhite);
s.addShape(pres.shapes.RECTANGLE, { x: colX[ci], y, w: colW[ci], h: rowH, fill: { color: bg }, line: { color: C.grayLight, width: 0.5 } });
const textColor = isHeader ? C.white : (ci === 2 ? (cell.includes("✓") ? C.tealDark : C.amber) : C.navyMid);
s.addText(cell, {
x: colX[ci] + 0.1, y, w: colW[ci] - 0.2, h: rowH,
fontSize: isHeader ? 11 : 10.5, bold: isHeader, color: textColor, valign: "middle",
});
});
});
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.25, y: 5.1, w: 9.5, h: 0.37, fill: { color: C.teal }, rectRadius: 0.05,
});
s.addText("Predicted: NOT DIFFICULT AIRWAY — Proceed with standard oral RAE tube (cuffed 6.5 mm) + video laryngoscope on standby", {
x: 0.35, y: 5.1, w: 9.3, h: 0.37,
fontSize: 10.5, color: C.white, bold: true, valign: "middle",
});
addSlideNumber(s, 6, TOTAL);
}
// ── SLIDE 7: INVESTIGATIONS ───────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Preoperative Investigations");
const inv = [
["Haemoglobin", "Target >10 g/dL", "Blood loss risk during mastoid drilling"],
["Blood group & X-match", "1–2 units RBC reserved", "Sigmoid sinus injury risk"],
["BT / CT / PT-INR", "Within normal limits", "Microsurgery — no coagulopathy"],
["RBS", "Normal", "Paediatric glucose monitoring"],
["Electrolytes", "Normal", "Fluid management reference"],
["ECG", "NSR — not mandatory ASA I", "Done if clinically indicated"],
["CT Temporal Bone", "Extent of CSOM, facial canal", "Guides surgical + anaes planning"],
["Pure Tone Audiogram", "Conductive hearing loss", "Surgical documentation"],
];
const colW2 = [2.0, 2.5, 5.2];
const colX2 = [0.25, 2.3, 4.85];
const headers2 = ["Investigation", "Expected Finding", "Anaesthetic Relevance"];
headers2.forEach((h, ci) => {
s.addShape(pres.shapes.RECTANGLE, { x: colX2[ci], y: 0.9, w: colW2[ci], h: 0.42, fill: { color: C.teal }, line: { color: C.tealDark, width: 0.5 } });
s.addText(h, { x: colX2[ci] + 0.1, y: 0.9, w: colW2[ci] - 0.2, h: 0.42, fontSize: 11, bold: true, color: C.white, valign: "middle" });
});
inv.forEach((row, ri) => {
const y = 1.32 + ri * 0.5;
row.forEach((cell, ci) => {
const bg = ri % 2 === 0 ? C.white : C.offWhite;
s.addShape(pres.shapes.RECTANGLE, { x: colX2[ci], y, w: colW2[ci], h: 0.5, fill: { color: bg }, line: { color: C.grayLight, width: 0.5 } });
s.addText(cell, { x: colX2[ci] + 0.1, y, w: colW2[ci] - 0.2, h: 0.5, fontSize: 10, color: C.navyMid, valign: "middle" });
});
});
addSlideNumber(s, 7, TOTAL);
}
// ── SLIDE 8: NPO & PREMEDICATION ─────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Fasting Guidelines & Premedication");
// NPO left
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 4.6, h: 4.45, fill: { color: C.navyMid }, rectRadius: 0.1 });
tealBadge(s, "ASA NPO GUIDELINES (2023)", 0.45, 0.98, 3.8);
const npoItems = [
["Clear liquids (water, juice)", "2 hours"],
["Breast milk", "4 hours"],
["Formula / light meal", "6 hours"],
["Full / fatty meal", "8 hours"],
];
npoItems.forEach(([item, time], i) => {
const y = 1.5 + i * 0.7;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.45, y, w: 3.7, h: 0.58, fill: { color: C.navy }, rectRadius: 0.06 });
s.addText(item, { x: 0.6, y: y + 0.02, w: 2.5, h: 0.3, fontSize: 10, color: C.white, valign: "bottom" });
s.addText(time, { x: 3.1, y: y + 0.02, w: 0.9, h: 0.54, fontSize: 14, bold: true, color: C.amber, align: "center", valign: "middle" });
});
s.addText("⚠ Prolonged fasting → hypoglycaemia in children\nAllow clear fluids up to 2h before induction", {
x: 0.45, y: 4.38, w: 4.1, h: 0.65, fontSize: 9.5, color: C.amber, fontFace: "Calibri",
});
// Premedication right
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.15, y: 0.9, w: 4.6, h: 4.45, fill: { color: C.offWhite }, rectRadius: 0.1 });
amberBadge(s, "PREMEDICATION (32 kg child)", 5.35, 0.98, 3.4);
const premed = [
["Midazolam", "0.5 mg/kg oral (max 15 mg)", "Anxiolysis / amnesia"],
["Paracetamol", "15 mg/kg oral/rectal", "Pre-emptive analgesia"],
["Ondansetron", "0.1 mg/kg IV at induction", "PONV prophylaxis"],
["Dexamethasone", "0.1 mg/kg IV at induction", "PONV + anti-inflam"],
["Atropine", "0.02 mg/kg IV at induction", "Antisialagogue"],
];
premed.forEach(([drug, dose, purpose], i) => {
const y = 1.5 + i * 0.72;
s.addShape(pres.shapes.RECTANGLE, { x: 5.25, y: y + 0.1, w: 0.05, h: 0.3, fill: { color: C.teal } });
s.addText(drug, { x: 5.45, y, w: 1.5, h: 0.3, fontSize: 11, bold: true, color: C.navy, valign: "bottom" });
s.addText(dose, { x: 5.45, y: y + 0.3, w: 2.8, h: 0.25, fontSize: 9.5, color: C.navyMid });
s.addText(purpose, { x: 5.45, y: y + 0.48, w: 4.1, h: 0.22, fontSize: 9, color: C.gray });
});
addSlideNumber(s, 8, TOTAL);
}
// ── SLIDE 9: VIVA — NPO & N2O ────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy } });
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.08, h: 5.625, fill: { color: C.amber } });
s.addText("VIVA QUESTIONS — Preoperative", {
x: 0.3, y: 0.18, w: 9, h: 0.45,
fontSize: 16, bold: true, color: C.amber, charSpacing: 2,
});
vivaBox(s,
"Clear fluids last given at what time if surgery is at 10 AM?",
"8 AM — clear fluids are permitted up to 2 hours before induction per ASA 2023 NPO guidelines. Solids stopped at midnight (10 h prior). Gastric ultrasound may confirm emptying if in doubt.",
0.25, 0.75, 9.5, 1.4);
vivaBox(s,
"Why is N₂O contraindicated in tympanomastoidectomy?",
"N₂O is 20× more soluble in blood than nitrogen. It diffuses into the closed middle ear cavity faster than N₂ escapes, raising pressure. This displaces the TM graft. CSOM patients have obstructed Eustachian tubes — cannot passively vent pressure. Even stopping N₂O after graft placement creates negative pressure → graft dislodgement. Avoid entirely or wash out 15–30 min before graft.",
0.25, 2.3, 9.5, 1.65);
vivaBox(s,
"Why is family history of anaesthesia complications relevant?",
"Malignant hyperthermia (MH) is autosomal dominant, triggered by volatile agents and succinylcholine. Positive family history mandates TIVA — avoiding all volatile agents and succinylcholine. Incidence ~1:10,000–50,000 anaesthetics. A TIVA plan already being considered for this case eliminates MH trigger risk.",
0.25, 4.1, 9.5, 1.35);
addSlideNumber(s, 9, TOTAL);
}
// ── SLIDE 10: SECTION HEADER — INTRAOPERATIVE ────────────────────────────────
{
const s = pres.addSlide();
sectionHeader(s, "SECTION 2\nIntraoperative Management", "Induction · Maintenance · Monitoring · Controlled Hypotension");
s.addShape(pres.shapes.RECTANGLE, { x: 0.55, y: 1.8, w: 2.5, h: 0.07, fill: { color: C.teal } });
}
// ── SLIDE 11: INDUCTION ───────────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Induction of Anaesthesia — TIVA Protocol");
// Left: steps
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 5.1, h: 4.45, fill: { color: C.navyMid }, rectRadius: 0.1 });
tealBadge(s, "INDUCTION SEQUENCE (32 kg)", 0.4, 0.98, 3.8);
const steps = [
["1", "Pre-oxygenate", "100% O₂ × 3–5 min via tight-fitting mask"],
["2", "Fentanyl 2 mcg/kg IV", "= 64 mcg (give slowly over 60 sec)"],
["3", "Propofol 2–2.5 mg/kg IV", "= 64–80 mg (over 60–90 sec)"],
["4", "Atracurium 0.5 mg/kg IV", "= 16 mg | OR Rocuronium 0.6 mg/kg"],
["5", "Wait full relaxation 3 min", "Confirm with nerve stimulator / TOF"],
["6", "Laryngoscopy + intubation", "Cuffed oral RAE 6.5 mm, Macintosh 3"],
["7", "Confirm position", "Bilateral BS + capnograph waveform"],
];
steps.forEach(([num, action, detail], i) => {
const y = 1.5 + i * 0.54;
s.addShape(pres.shapes.OVAL, { x: 0.4, y: y + 0.04, w: 0.3, h: 0.3, fill: { color: C.teal } });
s.addText(num, { x: 0.4, y: y + 0.04, w: 0.3, h: 0.3, fontSize: 9, bold: true, color: C.white, align: "center", valign: "middle" });
s.addText(action, { x: 0.82, y, w: 2.0, h: 0.3, fontSize: 10, bold: true, color: C.white, valign: "bottom" });
s.addText(detail, { x: 0.82, y: y + 0.28, w: 4.3, h: 0.24, fontSize: 9, color: C.grayLight });
});
// Right: ETT choice
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.6, y: 0.9, w: 4.15, h: 2.4, fill: { color: C.teal }, rectRadius: 0.1 });
s.addText("ETT SELECTION", { x: 5.8, y: 0.98, w: 3.8, h: 0.35, fontSize: 12, bold: true, color: C.navy, align: "center" });
s.addText([
{ text: "Formula: ", options: { bold: true, color: C.navy } },
{ text: "Age/4 + 4 = 7.0 mm (uncuffed)\n", options: { color: C.white } },
{ text: "Cuffed tube: ", options: { bold: true, color: C.navy } },
{ text: "6.5 mm (preferred)\n", options: { color: C.white } },
{ text: "Tube type: ", options: { bold: true, color: C.navy } },
{ text: "Oral RAE (south-facing preformed)\n", options: { color: C.white } },
{ text: "Have ready: ", options: { bold: true, color: C.navy } },
{ text: "6.0, 6.5, 7.0 mm sizes", options: { color: C.white } },
], { x: 5.8, y: 1.38, w: 3.75, h: 1.75, fontSize: 10.5, fontFace: "Calibri", lineSpacingMultiple: 1.5 });
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.6, y: 3.5, w: 4.15, h: 1.85, fill: { color: C.offWhite }, rectRadius: 0.1 });
s.addText("WHY AVOID SUCCINYLCHOLINE?", { x: 5.8, y: 3.58, w: 3.8, h: 0.3, fontSize: 10, bold: true, color: C.red, align: "center" });
s.addText([
...bulletsTeal([
"MH trigger (autosomal dominant risk)",
"Fasciculations → ↑IOP, ↑intragastric P",
"Rocuronium + sugammadex = safer alternative",
"Elective case with predicted easy airway",
])
], { x: 5.75, y: 3.95, w: 3.85, h: 1.25, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
addSlideNumber(s, 11, TOTAL);
}
// ── SLIDE 12: POSITIONING & EYES ─────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Patient Positioning — Details Matter");
const posItems = [
["Supine + head turned", "Head turned away from surgical ear; secured in head ring"],
["15° reverse Trendelenburg", "Head-up tilt — reduces venous pooling, decreases bleeding"],
["Eyes padded bilaterally", "Corneal abrasion from drapes; pressure on dependent eye"],
["ETT secured away from field", "Confirm no tube kink after final head position; check EtCO₂ + air pressures"],
["Arms tucked by sides", "Surgeon needs unobstructed access from head-end"],
["Temperature maintenance", "Warm OR, warm IV fluids, forced-air warming blanket — paediatrics lose heat rapidly"],
["Nerve integrity monitor", "NIM ETT if facial nerve monitoring planned — confirm with surgeon PRE-INDUCTION"],
];
posItems.forEach(([title, detail], i) => {
const y = 0.92 + i * 0.64;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y, w: 9.5, h: 0.56, fill: { color: i % 2 === 0 ? C.white : C.offWhite }, rectRadius: 0.05, line: { color: C.grayLight, width: 0.5 } });
s.addShape(pres.shapes.RECTANGLE, { x: 0.25, y, w: 0.06, h: 0.56, fill: { color: i % 2 === 0 ? C.teal : C.amber } });
s.addText(title, { x: 0.44, y: y + 0.04, w: 2.6, h: 0.26, fontSize: 10.5, bold: true, color: C.navyMid });
s.addText(detail, { x: 0.44, y: y + 0.28, w: 9.1, h: 0.24, fontSize: 10, color: C.gray });
});
addSlideNumber(s, 12, TOTAL);
}
// ── SLIDE 13: MAINTENANCE — TIVA ─────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Maintenance — TIVA (Preferred Technique)");
// Why TIVA box
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 4.6, h: 2.0, fill: { color: C.navy }, rectRadius: 0.1 });
s.addText("WHY TIVA?", { x: 0.45, y: 0.95, w: 4.2, h: 0.35, fontSize: 12, bold: true, color: C.teal });
s.addText([
...bullets([
"Avoids N₂O — mandatory in ear surgery",
"Propofol TIVA ↓ PONV vs volatile agents",
"Remifentanil enables controlled hypotension",
"Smooth, rapid, clear-headed emergence",
"No airway reactivity of volatile agents",
])
], { x: 0.45, y: 1.35, w: 4.2, h: 1.45, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
// Drugs infusion
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.15, y: 0.9, w: 4.6, h: 2.0, fill: { color: C.teal }, rectRadius: 0.1 });
s.addText("TIVA INFUSION RATES", { x: 5.35, y: 0.95, w: 4.2, h: 0.35, fontSize: 12, bold: true, color: C.navy });
s.addText([
{ text: "Propofol:\n", options: { bold: true, color: C.navy, breakLine: true } },
{ text: "4–12 mg/kg/hr (TCI or manual)\n\n", options: { color: C.white, breakLine: true } },
{ text: "Remifentanil:\n", options: { bold: true, color: C.navy, breakLine: true } },
{ text: "0.05–0.25 mcg/kg/min\n\n", options: { color: C.white, breakLine: true } },
{ text: "Gas: O₂ in Air (FiO₂ 0.3–0.4) — NO N₂O", options: { bold: true, color: C.amber } },
], { x: 5.35, y: 1.35, w: 4.2, h: 1.45, fontSize: 10.5, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
// BIS monitoring
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 3.05, w: 4.6, h: 1.65, fill: { color: C.offWhite }, rectRadius: 0.1 });
amberBadge(s, "DEPTH OF ANAESTHESIA — BIS", 0.45, 3.13, 3.5);
s.addText([
...bulletsTeal([
"BIS target: 40–60 (adequate anaesthesia depth)",
"BIS >60 → risk of awareness → increase propofol",
"BIS <40 → too deep → reduce infusion",
])
], { x: 0.45, y: 3.5, w: 4.2, h: 1.1, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
// Ventilation
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.15, y: 3.05, w: 4.6, h: 1.65, fill: { color: C.offWhite }, rectRadius: 0.1 });
amberBadge(s, "VENTILATION TARGETS", 5.35, 3.13, 3.0);
s.addText([
...bulletsTeal([
"TV 6–8 mL/kg = 190–255 mL; Rate 14–18/min",
"EtCO₂ target: 35–40 mmHg (normocapnia)",
"PEEP 3–5 cmH₂O — prevent atelectasis",
])
], { x: 5.35, y: 3.5, w: 4.2, h: 1.1, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
// Volatile alternative note
s.addShape(pres.shapes.RECTANGLE, { x: 0.25, y: 4.8, w: 9.5, h: 0.65, fill: { color: C.navyMid } });
s.addText("Alternative (if TIVA unavailable): Sevoflurane in O₂/Air (1.0–1.5 MAC) — NO N₂O. Increased PONV risk vs TIVA.", {
x: 0.4, y: 4.82, w: 9.2, h: 0.6, fontSize: 10.5, color: C.grayLight, valign: "middle",
});
addSlideNumber(s, 13, TOTAL);
}
// ── SLIDE 14: CONTROLLED HYPOTENSION ─────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Controlled Hypotension — Improving the Surgical Field");
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 9.5, h: 0.65, fill: { color: C.teal }, rectRadius: 0.08 });
s.addText("Target MAP: 50–65 mmHg (20–30% below patient baseline) — microsurgery demands bloodless field", {
x: 0.4, y: 0.9, w: 9.2, h: 0.65, fontSize: 12, bold: true, color: C.white, valign: "middle",
});
const methods = [
["Remifentanil infusion", "Primary agent: ↓SVR + ↓HR; ultra-short t½; most titratable"],
["Propofol TIVA", "Vasodilation + ↓CO; synergistic with remifentanil"],
["Esmolol infusion", "β₁ blockade → ↓HR; controls reflex tachycardia"],
["15° head-up tilt", "Simple non-pharmacological; reduces venous pooling"],
["Epinephrine 1:200,000", "Surgeon's local infiltration; local vasoconstriction"],
["Dexmedetomidine", "α₂ agonist → ↓sympathetic tone + opioid sparing"],
];
methods.forEach(([method, detail], i) => {
const y = 1.68 + i * 0.6;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y, w: 9.5, h: 0.52, fill: { color: i % 2 === 0 ? C.white : C.offWhite }, rectRadius: 0.05, line: { color: C.grayLight, width: 0.5 } });
s.addText(method, { x: 0.4, y, w: 2.5, h: 0.52, fontSize: 10.5, bold: true, color: C.navyMid, valign: "middle" });
s.addText(detail, { x: 3.0, y, w: 6.6, h: 0.52, fontSize: 10, color: C.navy, valign: "middle" });
});
// Contraindications
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 5.18, w: 9.5, h: 0.32, fill: { color: C.red }, rectRadius: 0.05 });
s.addText("Contraindicated in: Uncontrolled hypertension | Cerebrovascular disease | Severe anaemia | Renal insufficiency", {
x: 0.4, y: 5.18, w: 9.2, h: 0.32, fontSize: 10, bold: true, color: C.white, valign: "middle",
});
addSlideNumber(s, 14, TOTAL);
}
// ── SLIDE 15: VIVA — INTRAOPERATIVE ──────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy } });
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.08, h: 5.625, fill: { color: C.amber } });
s.addText("VIVA QUESTIONS — Intraoperative", {
x: 0.3, y: 0.18, w: 9, h: 0.45, fontSize: 16, bold: true, color: C.amber, charSpacing: 2,
});
vivaBox(s,
"Surgeon injects epinephrine 1:50,000. You see sudden hypertension + VEs. What do you do?",
"Alert surgeon to stop further injection. Increase anaesthetic depth (propofol bolus). For VEs: lignocaine 1 mg/kg IV or esmolol 0.5 mg/kg IV. Correct ventilation (avoid hypercapnia). Note: sevoflurane sensitises myocardium less than halothane. Document and communicate.",
0.25, 0.75, 9.5, 1.5);
vivaBox(s,
"Surgeon asks for a muscle relaxant mid-surgery because patient moved. Your response?",
"First: ask surgeon — is facial nerve NIM monitoring in use? If YES, NMBs are absolutely contraindicated. If NO: increase anaesthetic depth first (propofol + remifentanil bolus). Check TOF — if fully recovered and patient still moves, anaesthesia is too light. Never reflexively give relaxant without understanding why patient moved.",
0.25, 2.4, 9.5, 1.65);
vivaBox(s,
"What is facial nerve monitoring and how does it change your anaesthetic plan?",
"NIM (Nerve Integrity Monitoring) detects facial nerve EMG signals when surgically stimulated. If in use: muscle relaxants must NOT be given post-intubation — paralysis abolishes EMG signal. Communicate with surgeon BEFORE induction. Plan: TIVA depth control replaces relaxants for immobility. TOF monitoring essential to confirm spontaneous recovery.",
0.25, 4.18, 9.5, 1.3);
addSlideNumber(s, 15, TOTAL);
}
// ── SLIDE 16: MONITORING ──────────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Intraoperative Monitoring — Standards");
const monitors = [
["ECG (5-lead)", "HR, rhythm, ST changes, arrhythmia from epinephrine injection", C.teal],
["Pulse oximetry", "Oxygenation — continuous SpO₂; desaturation alert <95%", C.teal],
["NIBP (q 3–5 min)", "Haemodynamic monitoring; target MAP during controlled hypotension", C.teal],
["Capnography (EtCO₂)", "Ventilation adequacy; ETT confirmation; air embolism detection (early)", C.teal],
["Temperature probe", "Core temp — paediatric hypothermia is rapid; maintain >36°C", C.amber],
["Neuromuscular (TOF)", "NMB depth monitoring; confirm full recovery before extubation (TOF ratio >0.9)", C.amber],
["BIS monitor", "Depth of anaesthesia 40–60; prevents awareness under TIVA", C.amber],
["Urine output (if >3h)", "Foley catheter — target 0.5–1 mL/kg/hr; guides fluid management", C.amber],
["Arterial line (if deliberate hypotension)", "Beat-to-beat BP; ABG sampling — pH, lactate, glucose, Hb", C.red],
];
monitors.forEach(([monitor, detail, col], i) => {
const y = 0.93 + i * 0.52;
s.addShape(pres.shapes.RECTANGLE, { x: 0.25, y, w: 0.06, h: 0.44, fill: { color: col } });
s.addText(monitor, { x: 0.4, y: y + 0.02, w: 2.7, h: 0.26, fontSize: 10.5, bold: true, color: C.navyMid });
s.addText(detail, { x: 0.4, y: y + 0.26, w: 9.4, h: 0.22, fontSize: 9.5, color: C.gray });
if (i < monitors.length - 1) {
s.addShape(pres.shapes.RECTANGLE, { x: 0.25, y: y + 0.46, w: 9.5, h: 0.01, fill: { color: C.grayLight } });
}
});
addSlideNumber(s, 16, TOTAL);
}
// ── SLIDE 17: FLUID MANAGEMENT ───────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Fluid Management — 32 kg Paediatric Patient");
// Maintenance calculation
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 4.6, h: 2.5, fill: { color: C.navyMid }, rectRadius: 0.1 });
tealBadge(s, "MAINTENANCE — HOLLIDAY-SEGAR", 0.4, 0.97, 3.8);
s.addText([
{ text: "First 10 kg: ", options: { bold: true, color: C.amber } },
{ text: "4 mL/kg/hr = 40 mL/hr\n", options: { color: C.white, breakLine: true } },
{ text: "Next 10 kg: ", options: { bold: true, color: C.amber } },
{ text: "2 mL/kg/hr = 20 mL/hr\n", options: { color: C.white, breakLine: true } },
{ text: "Next 12 kg: ", options: { bold: true, color: C.amber } },
{ text: "1 mL/kg/hr = 12 mL/hr\n\n", options: { color: C.white, breakLine: true } },
{ text: "Total Maintenance = 72 mL/hr", options: { bold: true, color: C.teal } },
], { x: 0.45, y: 1.4, w: 4.2, h: 1.85, fontSize: 11, fontFace: "Calibri", lineSpacingMultiple: 1.5 });
// Deficit
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.15, y: 0.9, w: 4.6, h: 2.5, fill: { color: C.offWhite }, rectRadius: 0.1 });
amberBadge(s, "DEFICIT REPLACEMENT (8h fast)", 5.3, 0.97, 3.5);
s.addText([
{ text: "Deficit = 8 h × 72 mL/hr = 576 mL\n\n", options: { color: C.navyMid, breakLine: true } },
{ text: "1st hour: ", options: { bold: true, color: C.navy } },
{ text: "50% = 288 mL + 72 mL maint.\n", options: { color: C.navyMid, breakLine: true } },
{ text: "2nd hour: ", options: { bold: true, color: C.navy } },
{ text: "25% = 144 mL + 72 mL maint.\n", options: { color: C.navyMid, breakLine: true } },
{ text: "3rd hour: ", options: { bold: true, color: C.navy } },
{ text: "25% = 144 mL + 72 mL maint.", options: { color: C.navyMid } },
], { x: 5.3, y: 1.4, w: 4.2, h: 1.85, fontSize: 10.5, fontFace: "Calibri", lineSpacingMultiple: 1.5 });
// Blood
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 3.55, w: 4.6, h: 1.8, fill: { color: C.navy }, rectRadius: 0.1 });
s.addText("BLOOD LOSS MANAGEMENT", { x: 0.45, y: 3.62, w: 4.2, h: 0.32, fontSize: 11, bold: true, color: C.amber });
s.addText([
...bullets([
"TBV = 70 mL/kg = 2240 mL",
"MABL = TBV × (Hct_start–Hct_min)/Hct_avg",
"Hb 12→ min 8 g/dL = allow ~50 mL/kg",
"Replace crystalloid 3:1 up to MABL",
])
], { x: 0.45, y: 3.98, w: 4.25, h: 1.3, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.15, y: 3.55, w: 4.6, h: 1.8, fill: { color: C.offWhite }, rectRadius: 0.1 });
s.addText("FLUID CHOICE", { x: 5.35, y: 3.62, w: 4.2, h: 0.32, fontSize: 11, bold: true, color: C.tealDark });
s.addText([
...bulletsTeal([
"Balanced crystalloid: Plasmalyte / Lactated Ringer's",
"Avoid large-volume normal saline (hyperchloraemic acidosis)",
"Colloid if persistent hypotension after crystalloid",
"Glucose-containing solution if hypoglycaemia detected",
])
], { x: 5.35, y: 3.98, w: 4.35, h: 1.3, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
addSlideNumber(s, 17, TOTAL);
}
// ── SLIDE 18: SECTION HEADER — EMERGENCE ────────────────────────────────────
{
const s = pres.addSlide();
sectionHeader(s, "SECTION 3\nEmergence & Extubation", "The most critical phase — protecting the graft");
s.addShape(pres.shapes.RECTANGLE, { x: 0.55, y: 1.8, w: 2.5, h: 0.07, fill: { color: C.teal } });
}
// ── SLIDE 19: EMERGENCE & EXTUBATION ─────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Emergence — Smooth is Safe");
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 9.5, h: 0.55, fill: { color: C.red }, rectRadius: 0.06 });
s.addText("⚠ Coughing on ETT raises venous pressure → bleeding → graft displacement | PONV = graft at risk", {
x: 0.4, y: 0.9, w: 9.3, h: 0.55, fontSize: 11, bold: true, color: C.white, valign: "middle",
});
// Deep extubation
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 1.55, w: 4.6, h: 3.8, fill: { color: C.navyMid }, rectRadius: 0.1 });
tealBadge(s, "DEEP EXTUBATION (Preferred)", 0.4, 1.63, 3.8);
s.addText([
...bullets([
"Pre-requisites: fasted, easy airway, haemodynamically stable",
"Turn patient lateral (recovery position) before removing ETT",
"Remove ETT while patient in deep anaesthesia plane",
"Transition to spontaneous ventilation on face mask",
"Maintain airway with jaw thrust + gentle CPAP",
"Move to PACU once SpO₂ >95% breathing spontaneously",
])
], { x: 0.4, y: 2.02, w: 4.25, h: 3.1, fontFace: "Calibri", lineSpacingMultiple: 1.35 });
// Awake extubation
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.15, y: 1.55, w: 4.6, h: 3.8, fill: { color: C.offWhite }, rectRadius: 0.1 });
amberBadge(s, "AWAKE EXTUBATION (Alternative)", 5.3, 1.63, 3.6);
s.addText([
...bulletsTeal([
"Reverse NMB: neostigmine 50 mcg/kg + glycopyrrolate 10 mcg/kg",
"Wait: TOF ratio >0.9 (quantitative monitoring preferred)",
"Signs: spontaneous breathing, eye opening, purposeful movement",
"Lignocaine 1 mg/kg IV 2 min before extubation (blunt cough reflex)",
"OR: remifentanil 0.01–0.05 mcg/kg/min at emergence (suppresses cough without apnoea)",
"Suction gently before removal",
])
], { x: 5.3, y: 2.02, w: 4.3, h: 3.1, fontFace: "Calibri", lineSpacingMultiple: 1.35 });
addSlideNumber(s, 19, TOTAL);
}
// ── SLIDE 20: VIVA — LARYNGOSPASM ────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy } });
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.08, h: 5.625, fill: { color: C.red } });
s.addText("VIVA — Emergency Scenario: Post-Extubation", {
x: 0.3, y: 0.18, w: 9, h: 0.42, fontSize: 16, bold: true, color: C.red, charSpacing: 2,
});
s.addText("You performed deep extubation. Child now has stridor. SpO₂ falling. What is your diagnosis and management?", {
x: 0.25, y: 0.72, w: 9.5, h: 0.5, fontSize: 12, bold: true, color: C.amber,
});
// Diagnosis
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 1.3, w: 9.5, h: 0.55, fill: { color: C.navyMid }, rectRadius: 0.08 });
s.addText("Diagnosis: LARYNGOSPASM — inspiratory stridor + paradoxical chest movement + absent air entry on auscultation", {
x: 0.4, y: 1.3, w: 9.3, h: 0.55, fontSize: 10.5, color: C.white, valign: "middle",
});
const steps = [
["1", "Call for Help", "Activate emergency protocol immediately"],
["2", "Jaw thrust + 100% O₂", "CPAP 20–30 cmH₂O via tight-fitting mask — may break incomplete laryngospasm"],
["3", "Larson's manoeuvre", "Firm pressure in notch posterior to mandibular condyle bilaterally"],
["4", "Propofol 0.5–1 mg/kg IV", "Small subanaesthetic dose often breaks laryngospasm without full induction"],
["5", "Succinylcholine 1–2 mg/kg IV", "Complete relaxation if SpO₂ <85% or no response — bag-mask → re-intubate"],
["6", "Atropine if bradycardia", "Suxamethonium + hypoxia → bradycardia in children — 0.02 mg/kg IV"],
];
steps.forEach(([num, action, detail], i) => {
const y = 2.0 + i * 0.57;
s.addShape(pres.shapes.OVAL, { x: 0.28, y: y + 0.06, w: 0.32, h: 0.32, fill: { color: C.red } });
s.addText(num, { x: 0.28, y: y + 0.06, w: 0.32, h: 0.32, fontSize: 10, bold: true, color: C.white, align: "center", valign: "middle" });
s.addText(action + ": ", { x: 0.7, y, w: 2.1, h: 0.32, fontSize: 10.5, bold: true, color: C.amber, valign: "bottom" });
s.addText(detail, { x: 0.7, y: y + 0.3, w: 9.0, h: 0.24, fontSize: 9.5, color: C.grayLight });
});
addSlideNumber(s, 20, TOTAL);
}
// ── SLIDE 21: SECTION HEADER — POSTOPERATIVE ────────────────────────────────
{
const s = pres.addSlide();
sectionHeader(s, "SECTION 4\nPostoperative Management", "Recovery · Analgesia · PONV · Complications");
s.addShape(pres.shapes.RECTANGLE, { x: 0.55, y: 1.8, w: 2.5, h: 0.07, fill: { color: C.teal } });
}
// ── SLIDE 22: POSTOP ANALGESIA ────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Postoperative Analgesia — Multimodal Approach");
const drugs = [
["Paracetamol", "15 mg/kg", "IV/oral", "q6h (max 60 mg/kg/day)", C.teal, "First-line — all cases"],
["Ibuprofen", "10 mg/kg", "Oral", "q8h PRN", C.teal, "Add if no contraindication"],
["Tramadol", "1–2 mg/kg", "IV/oral", "q6h PRN", C.amber, "Moderate pain"],
["Morphine", "0.05–0.1 mg/kg", "IV", "PRN (titrate)", C.amber, "Severe pain — mastoidectomy"],
];
const colWd = [1.8, 1.4, 1.0, 2.0, 1.3, 2.0];
const colXd = [0.25, 2.1, 3.55, 4.6, 6.65, 7.75];
const hdrs = ["Drug", "Dose", "Route", "Frequency", "Tier", "Notes"];
hdrs.forEach((h, ci) => {
s.addShape(pres.shapes.RECTANGLE, { x: colXd[ci], y: 0.9, w: colWd[ci], h: 0.42, fill: { color: C.navy }, line: { color: C.navyMid, width: 0.5 } });
s.addText(h, { x: colXd[ci] + 0.05, y: 0.9, w: colWd[ci] - 0.1, h: 0.42, fontSize: 10, bold: true, color: C.white, valign: "middle" });
});
drugs.forEach((row, ri) => {
const y = 1.32 + ri * 0.62;
const cells = [row[0], row[1], row[2], row[3], "", row[5]];
cells.forEach((cell, ci) => {
const bg = ri % 2 === 0 ? C.white : C.offWhite;
s.addShape(pres.shapes.RECTANGLE, { x: colXd[ci], y, w: colWd[ci], h: 0.62, fill: { color: bg }, line: { color: C.grayLight, width: 0.5 } });
s.addText(cell, { x: colXd[ci] + 0.05, y, w: colWd[ci] - 0.1, h: 0.62, fontSize: 10, color: C.navyMid, valign: "middle" });
});
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: colXd[4] + 0.15, y: y + 0.15, w: 0.95, h: 0.3, fill: { color: row[4] }, rectRadius: 0.04 });
s.addText(row[4] === C.teal ? "First Line" : "Second Line", { x: colXd[4] + 0.15, y: y + 0.15, w: 0.95, h: 0.3, fontSize: 8, bold: true, color: C.white, align: "center", valign: "middle" });
});
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 3.9, w: 9.5, h: 1.5, fill: { color: C.navyMid }, rectRadius: 0.1 });
s.addText("SCOTT-BROWN'S KEY POINT:", { x: 0.4, y: 3.98, w: 4.0, h: 0.3, fontSize: 10, bold: true, color: C.teal });
s.addText('"Post-operative pain is relatively low and well managed with paracetamol and NSAIDs EXCEPT in the mastoidectomy group — where opioid analgesia is required."', {
x: 0.4, y: 4.3, w: 9.2, h: 0.88, fontSize: 11, color: C.white, italic: true, fontFace: "Calibri",
});
addSlideNumber(s, 22, TOTAL);
}
// ── SLIDE 23: PONV MANAGEMENT ─────────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "PONV — Risk, Prophylaxis & Rescue");
// Apfel score
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 0.9, w: 4.3, h: 2.8, fill: { color: C.navyMid }, rectRadius: 0.1 });
tealBadge(s, "APFEL SCORE — THIS PATIENT", 0.4, 0.98, 3.6);
const apfelItems = [
["Female sex", "Male → 0 points"],
["Non-smoker", "12-yr-old → +1"],
["Hx of PONV/motion sickness", "+1 if present"],
["Post-op opioids", "+1 if used"],
["Middle ear surgery", "Independent risk factor +++"],
];
apfelItems.forEach(([factor, score], i) => {
const y = 1.48 + i * 0.48;
s.addText(factor, { x: 0.4, y, w: 2.4, h: 0.26, fontSize: 10, color: C.grayLight, valign: "bottom" });
s.addText(score, { x: 2.85, y, w: 1.55, h: 0.4, fontSize: 9.5, color: score.includes("+") ? C.amber : C.gray, valign: "middle" });
});
// Prophylaxis given
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 4.8, y: 0.9, w: 4.95, h: 2.8, fill: { color: C.offWhite }, rectRadius: 0.1 });
amberBadge(s, "INTRAOPERATIVE PROPHYLAXIS", 4.95, 0.98, 3.8);
const ponvDrugs = [
["Dexamethasone 0.1 mg/kg IV", "At induction", "Anti-inflammatory + antiemetic"],
["Ondansetron 0.1 mg/kg IV", "End of surgery", "5-HT3 antagonist"],
["TIVA (propofol)", "Throughout", "Propofol per se reduces PONV"],
["Avoid N₂O", "Entire case", "N₂O increases PONV independently"],
];
ponvDrugs.forEach(([drug, timing, note], i) => {
const y = 1.48 + i * 0.58;
s.addShape(pres.shapes.RECTANGLE, { x: 4.95, y: y + 0.1, w: 0.05, h: 0.28, fill: { color: C.teal } });
s.addText(drug, { x: 5.12, y, w: 3.0, h: 0.3, fontSize: 10, bold: true, color: C.navy });
s.addText(timing + " | " + note, { x: 5.12, y: y + 0.3, w: 4.5, h: 0.22, fontSize: 9, color: C.gray });
});
// Rescue in PACU
s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.25, y: 3.82, w: 9.5, h: 1.6, fill: { color: C.navy }, rectRadius: 0.1 });
s.addText("RESCUE ANTIEMETICS IN PACU (if PONV despite prophylaxis)", {
x: 0.4, y: 3.9, w: 9.2, h: 0.32, fontSize: 11, bold: true, color: C.amber,
});
s.addText([
...bullets([
"Switch antiemetic class: droperidol 0.01 mg/kg IV | metoclopramide 0.15 mg/kg IV | promethazine 0.25 mg/kg IM",
"Ensure adequate hydration and pain control — pain drives PONV",
"Keep lateral position — reduces aspiration risk; inform surgeon (vomiting threatens graft integrity)",
])
], { x: 0.4, y: 4.25, w: 9.2, h: 1.1, fontFace: "Calibri", lineSpacingMultiple: 1.3 });
addSlideNumber(s, 23, TOTAL);
}
// ── SLIDE 24: POSTOP COMPLICATIONS ───────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "Postoperative Complications — Monitor & Act");
const comps = [
["Haematoma / Bleeding", C.red,
"Monitor wound dressing hourly. Expanding haematoma or airway compromise → return to OT immediately."],
["Facial Nerve Palsy", C.red,
"Document nerve function BEFORE surgery. Immediate + complete palsy post-op = surgical injury → urgent re-exploration. Delayed partial palsy = oedema → steroids + expectant management."],
["Postoperative Vertigo", C.amber,
"Common after inner ear manipulation. Reassure patient and parents. Monitor ambulation closely — fall risk. Anti-vertigo: betahistine, promethazine."],
["PONV (Nausea/Vomiting)", C.amber,
"See previous slide. Repeated vomiting → graft displacement risk + aspiration. Treat aggressively with rescue antiemetics."],
["CSF Leak / Otorrhoea", C.amber,
"Clear watery discharge post-op. Test for glucose (CSF positive) or beta-2 transferrin. Conservative: head elevation, avoid blowing nose. Persistent → surgical repair."],
["Graft Failure", C.gray,
"Suspected if hearing fails to improve at 6–8 week audiometry. May require revision surgery. Prevent by smooth emergence, avoiding PONV, avoiding N₂O."],
];
comps.forEach(([title, col, detail], i) => {
const y = 0.92 + i * 0.77;
s.addShape(pres.shapes.RECTANGLE, { x: 0.25, y, w: 0.06, h: 0.68, fill: { color: col } });
s.addText(title, { x: 0.4, y: y + 0.02, w: 2.4, h: 0.3, fontSize: 10.5, bold: true, color: C.navyMid });
s.addText(detail, { x: 0.4, y: y + 0.33, w: 9.35, h: 0.38, fontSize: 9.5, color: C.gray, fontFace: "Calibri" });
if (i < comps.length - 1) {
s.addShape(pres.shapes.RECTANGLE, { x: 0.25, y: y + 0.72, w: 9.5, h: 0.01, fill: { color: C.grayLight } });
}
});
addSlideNumber(s, 24, TOTAL);
}
// ── SLIDE 25: MODIFIED ALDRETE SCORE ─────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "PACU Discharge — Modified Aldrete Score");
const rows2 = [
["Parameter", "Score 2", "Score 1", "Score 0"],
["Activity", "Moves all 4 limbs", "Moves 2 limbs", "No movement"],
["Respiration", "Deep breath + cough", "Dyspnoea / limited", "Apnoeic"],
["Circulation", "BP within 20% of pre-op", "BP within 20–50% of pre-op", "BP >50% from pre-op"],
["Consciousness", "Fully awake", "Arousable on calling", "Not responding"],
["SpO₂", ">92% on room air", ">90% with O₂", "<90% with O₂"],
];
const cW = [2.0, 2.5, 2.5, 2.5];
const cX = [0.25, 2.3, 4.85, 7.35];
rows2.forEach((row, ri) => {
const y = 0.92 + ri * 0.7;
row.forEach((cell, ci) => {
const isHeader = ri === 0;
const isCol2 = ci === 1;
const bg = isHeader ? C.navy : (isCol2 ? "#E8F7F4" : C.white);
s.addShape(pres.shapes.RECTANGLE, { x: cX[ci], y, w: cW[ci], h: 0.7, fill: { color: isHeader ? C.navy : (isCol2 ? "D0F0EB" : "FFFFFF") }, line: { color: C.grayLight, width: 0.5 } });
s.addText(cell, {
x: cX[ci] + 0.08, y, w: cW[ci] - 0.16, h: 0.7,
fontSize: isHeader ? 11 : 10, bold: isHeader, color: isHeader ? C.white : (isCol2 ? C.tealDark : C.navyMid), valign: "middle",
});
});
});
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.25, y: 5.1, w: 9.5, h: 0.42, fill: { color: C.teal }, rectRadius: 0.05,
});
s.addText("Discharge from PACU when Aldrete Score ≥ 9 | Pain NRS ≤ 3 | No active vomiting | SpO₂ ≥ 95% on room air", {
x: 0.35, y: 5.1, w: 9.3, h: 0.42, fontSize: 10.5, bold: true, color: C.white, valign: "middle",
});
addSlideNumber(s, 25, TOTAL);
}
// ── SLIDE 26: VIVA — POSTOPERATIVE ───────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy } });
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.08, h: 5.625, fill: { color: C.amber } });
s.addText("VIVA QUESTIONS — Postoperative", {
x: 0.3, y: 0.18, w: 9, h: 0.42, fontSize: 16, bold: true, color: C.amber, charSpacing: 2,
});
vivaBox(s,
"Child is vomiting repeatedly in PACU despite ondansetron. What next?",
"Rule out surgical cause (haematoma, CSF leak) and pain as a PONV driver. Switch antiemetic CLASS — if 5-HT3 has failed use droperidol 0.01 mg/kg IV or metoclopramide 0.15 mg/kg IV. Ensure adequate IV hydration. Keep lateral position (aspiration prevention). Inform surgeon — vomiting threatens graft integrity.",
0.25, 0.75, 9.5, 1.5);
vivaBox(s,
"You notice new-onset complete facial palsy immediately after surgery. What do you do?",
"This is a surgical emergency. Immediate complete palsy = direct facial nerve injury. Inform surgeon immediately. Return to OT for urgent re-exploration. Contrast with delayed partial palsy = post-operative oedema → managed conservatively with steroids and observation. Always document pre-operative baseline nerve function.",
0.25, 2.4, 9.5, 1.65);
vivaBox(s,
"Patient needs to return to OT within 4 hours for haematoma. How do you manage anaesthesia?",
"Treat as FULL STOMACH: impaired gastric motility post-opioids, pain, fear delay emptying. Use RSI: preoxygenate, cricoid pressure, fentanyl + propofol IV + succinylcholine 1–2 mg/kg (or high-dose rocuronium 1.2 mg/kg). Have sugammadex ready. Intubate quickly. Continue TIVA — avoid N₂O (graft still at risk).",
0.25, 4.18, 9.5, 1.3);
addSlideNumber(s, 26, TOTAL);
}
// ── SLIDE 27: THE 5 KEY TAKEAWAYS ────────────────────────────────────────────
{
const s = pres.addSlide();
contentSlide(s);
slideTitle(s, "5 Key Anaesthetic Takeaways — What the Examiner Expects");
const takeaways = [
["1", "NO Nitrous Oxide", "Middle ear graft = closed space. N₂O diffuses in faster than N₂ escapes → pressure rise → graft displacement. Contraindicated throughout. CSOM obstructs Eustachian tube = no passive venting.", C.red],
["2", "TIVA is the Technique of Choice", "Propofol + remifentanil TIVA: avoids N₂O, ↓PONV vs volatiles, enables controlled hypotension, smooth rapid emergence. Graft is protected by every drug choice.", C.teal],
["3", "Dual PONV Prophylaxis is Mandatory", "Dexamethasone at induction + ondansetron at emergence. Ear surgery is a high-risk independent factor beyond Apfel score. Repeated PONV = graft failure + aspiration.", C.teal],
["4", "Communicate with Surgeon Pre-Induction", "Confirm: NIM facial nerve monitoring in use? If YES — no muscle relaxants post-induction. Plan must be agreed BEFORE first dose of drug is given. This is a team sport.", C.amber],
["5", "Smooth Emergence = Protected Graft", "Coughing on ETT raises venous pressure → bleeding and graft displacement. Deep extubation, lignocaine, or low-dose remifentanil at emergence — every anaesthetist's responsibility.", C.amber],
];
takeaways.forEach(([num, title, detail, col], i) => {
const y = 0.93 + i * 0.9;
s.addShape(pres.shapes.ROUNDED_RECTANGLE, {
x: 0.25, y, w: 9.5, h: 0.82, fill: { color: C.white }, rectRadius: 0.06,
line: { color: C.grayLight, width: 0.5 },
shadow: { type: "outer", color: "000000", blur: 4, offset: 1, angle: 135, opacity: 0.1 },
});
s.addShape(pres.shapes.OVAL, { x: 0.32, y: y + 0.22, w: 0.38, h: 0.38, fill: { color: col } });
s.addText(num, { x: 0.32, y: y + 0.22, w: 0.38, h: 0.38, fontSize: 13, bold: true, color: C.white, align: "center", valign: "middle" });
s.addText(title, { x: 0.85, y: y + 0.04, w: 3.5, h: 0.36, fontSize: 12, bold: true, color: C.navyMid });
s.addText(detail, { x: 0.85, y: y + 0.42, w: 8.75, h: 0.36, fontSize: 9.5, color: C.gray, fontFace: "Calibri" });
});
addSlideNumber(s, 27, TOTAL);
}
// ── SLIDE 28: CLOSING SLIDE ───────────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: C.navy } });
s.addShape(pres.shapes.OVAL, { x: 6.8, y: -1.0, w: 4.5, h: 4.5, fill: { color: C.navyMid }, line: { color: C.teal, width: 1.5 } });
s.addShape(pres.shapes.OVAL, { x: -1.2, y: 3.5, w: 3, h: 3, fill: { color: C.tealDark } });
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 5.15, w: 10, h: 0.475, fill: { color: C.teal } });
s.addShape(pres.shapes.RECTANGLE, { x: 0, y: 0, w: 0.1, h: 5.625, fill: { color: C.teal } });
s.addText("PROFESSOR'S CLOSING NOTE", {
x: 0.4, y: 0.65, w: 7, h: 0.4,
fontSize: 12, bold: true, color: C.teal, charSpacing: 3,
});
s.addText('"The moment you anchor your management to patient safety,\nthe examiner knows you are a clinician — not just a student."', {
x: 0.4, y: 1.15, w: 8.5, h: 1.3,
fontSize: 19, color: C.white, italic: true, fontFace: "Calibri Light", lineSpacingMultiple: 1.5,
});
s.addShape(pres.shapes.RECTANGLE, { x: 0.4, y: 2.55, w: 3.5, h: 0.04, fill: { color: C.teal } });
s.addText("Always close your case by saying:", { x: 0.4, y: 2.72, w: 9, h: 0.32, fontSize: 11, color: C.gray });
s.addText('"I would like to re-examine the child in the anaesthetic room immediately before induction to confirm no interval changes, re-check fasting status, and obtain final assent from the child."', {
x: 0.4, y: 3.08, w: 8.8, h: 1.0,
fontSize: 12, color: C.amber, italic: true, fontFace: "Calibri", lineSpacingMultiple: 1.4,
});
s.addText("Anaesthesia for Tympanomastoidectomy | MD Anaesthesia Exam Prep | Department of Anaesthesiology", {
x: 0.3, y: 5.18, w: 9.5, h: 0.38,
fontSize: 10, color: C.white, valign: "middle",
});
}
// ── WRITE FILE ────────────────────────────────────────────────────────────────
pres.writeFile({ fileName: "/home/daytona/workspace/csom-anaesthesia-pptx/CSOM_Anaesthesia_Tympanomastoidectomy.pptx" })
.then(() => console.log("SUCCESS: PPTX written."))
.catch(e => { console.error("ERROR:", e); process.exit(1); });