Stroke presentation 2 poster complete
Hariison and archit bollor bassed
mkdir -p /home/daytona/workspace/stroke-poster && ls /home/daytona/workspace/stroke-poster/
Hariison and archit bollor bassed stroke prentaton 1 page poster prepareHariison and archit bollor bassed stroke prentaton 1 page poster prepare
~/stroke-poster/make_poster.js
const pptxgen = require("pptxgenjs");
const { execSync } = require("child_process");
// Fetch brain anatomy images
const imageUrls = [
"https://cdn.orris.care/cdss_images/a94f73b585c5e20ed028f1355e098e6586f719d44ecf40e25bcecae9becae90e.png", // coronal - vascular territories
"https://cdn.orris.care/cdss_images/8f0e604f6f7bf69fead85d715302de646237f0d46b91557eecf6337566990d8d.png", // lateral MCA
"https://cdn.orris.care/cdss_images/697e750632ff92a3b9dd4b7dd47a61a2a44176ffc37a7f4c30e64d9224280140.png", // medial ACA/PCA
];
console.log("Fetching images...");
const images = JSON.parse(
execSync(
`node /home/daytona/skills/shared/scripts/fetch_images.js "${imageUrls[0]}" "${imageUrls[1]}" "${imageUrls[2]}"`
).toString()
);
console.log("Images fetched:", images.map(i => i.error || "OK"));
// ─── POSTER SETUP ────────────────────────────────────────────────────────────
const pres = new pptxgen();
pres.layout = "LAYOUT_WIDE"; // 13.3" × 7.5"
pres.title = "Stroke Presentation Poster";
const W = 13.3;
const H = 7.5;
// Color palette - deep medical navy dominant, crimson accent
const C = {
navy: "0D2B5E", // dominant background panels
navyDark: "081A40", // header/footer
crimson: "C0272D", // accent headers
gold: "E8A020", // subaccent
steel: "2F5F8F", // mid panels
white: "FFFFFF",
offwhite: "F2F5FA",
lightblue: "D6E4F0",
textDark: "0D2B5E",
textLight: "FFFFFF",
textGray: "445566",
green: "1A7A4A",
orange: "D15400",
};
const slide = pres.addSlide();
// ═══════════════════════════════════════════════════════════════
// BACKGROUND
// ═══════════════════════════════════════════════════════════════
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: W, h: H,
fill: { color: C.offwhite }, line: { color: C.offwhite }
});
// ═══════════════════════════════════════════════════════════════
// HEADER BAR
// ═══════════════════════════════════════════════════════════════
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: W, h: 0.72,
fill: { color: C.navyDark }, line: { color: C.navyDark }
});
// Crimson left accent stripe
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: 0.18, h: 0.72,
fill: { color: C.crimson }, line: { color: C.crimson }
});
slide.addText("STROKE · CLINICAL PRESENTATION & SYNDROMES", {
x: 0.25, y: 0, w: 9.5, h: 0.72,
fontSize: 22, bold: true, color: C.white, fontFace: "Calibri",
align: "left", valign: "middle", margin: 0
});
slide.addText("Based on Harrison's Principles of Internal Medicine 22e & Goldman-Cecil Medicine", {
x: 0.25, y: 0, w: 13, h: 0.72,
fontSize: 9, color: "B0C4DE", fontFace: "Calibri",
align: "right", valign: "bottom", margin: 4
});
// ═══════════════════════════════════════════════════════════════
// SECTION HEADER HELPER
// ═══════════════════════════════════════════════════════════════
function sectionHeader(slide, x, y, w, label, color) {
slide.addShape(pres.shapes.RECTANGLE, {
x, y, w, h: 0.26,
fill: { color: color || C.crimson }, line: { color: color || C.crimson }
});
slide.addText(label, {
x: x + 0.06, y, w: w - 0.06, h: 0.26,
fontSize: 8.5, bold: true, color: C.white, fontFace: "Calibri",
align: "left", valign: "middle", margin: 0, charSpacing: 1.5
});
}
function panel(slide, x, y, w, h, fillColor) {
slide.addShape(pres.shapes.RECTANGLE, {
x, y, w, h,
fill: { color: fillColor || C.white },
line: { color: "CBD8E8", pt: 0.5 },
shadow: { type: "outer", color: "000000", blur: 4, offset: 1, angle: 135, opacity: 0.08 }
});
}
// ═══════════════════════════════════════════════════════════════
// ROW 1 (y=0.82 to 2.60) — 3 columns
// ═══════════════════════════════════════════════════════════════
const row1y = 0.82;
const row1h = 1.78;
const col1x = 0.12, col2x = 4.52, col3x = 8.92;
const colW = 4.22;
// ── COL 1: DEFINITION & CLASSIFICATION ──────────────────────────
panel(slide, col1x, row1y, colW, row1h);
sectionHeader(slide, col1x, row1y, colW, "DEFINITION & CLASSIFICATION");
slide.addText([
{ text: "Stroke: ", options: { bold: true, color: C.textDark } },
{ text: "Sudden neurological deficit lasting >24h (or any duration with infarction on imaging) due to focal cerebrovascular pathology.\n", options: { color: C.textGray } },
{ text: "\nIschemic (87%)\n", options: { bold: true, color: C.steel } },
{ text: "• Large-vessel atherothrombosis (~30%)\n• Cardioembolic (A-fib, LV thrombus) (~25%)\n• Small-vessel (lacunar) (~20%)\n• Cryptogenic / undetermined (~20%)\n• Other (dissection, vasculitis, hypercoag) (~5%)\n", options: { color: C.textGray } },
{ text: "\nHemorrhagic (13%)\n", options: { bold: true, color: C.crimson } },
{ text: "• Intracerebral hemorrhage (ICH)\n• Subarachnoid hemorrhage (SAH)", options: { color: C.textGray } },
], {
x: col1x + 0.1, y: row1y + 0.3, w: colW - 0.2, h: row1h - 0.36,
fontSize: 7.8, fontFace: "Calibri", valign: "top"
});
// ── COL 2: FAST + TIA ──────────────────────────────────────────
panel(slide, col2x, row1y, colW, row1h);
sectionHeader(slide, col2x, row1y, colW, "RECOGNITION: FAST & TIA", C.crimson);
// FAST boxes
const fastItems = [
{ letter: "F", word: "Face", detail: "Facial droop / asymmetry", col: "C0272D" },
{ letter: "A", word: "Arm", detail: "Arm weakness / drift", col: "1A4F8A" },
{ letter: "S", word: "Speech", detail: "Slurred / absent speech", col: "1A7A4A" },
{ letter: "T", word: "Time", detail: "Call 999/112 immediately!", col: "D15400" },
];
fastItems.forEach((item, i) => {
const bx = col2x + 0.1 + i * 1.0;
const by = row1y + 0.32;
slide.addShape(pres.shapes.RECTANGLE, { x: bx, y: by, w: 0.92, h: 0.58, fill: { color: item.col }, line: { color: item.col } });
slide.addText(item.letter, { x: bx, y: by, w: 0.92, h: 0.38, fontSize: 20, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle" });
slide.addText(item.word, { x: bx, y: by + 0.38, w: 0.92, h: 0.20, fontSize: 7, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle" });
slide.addText(item.detail, { x: bx, y: by + 0.60, w: 0.92, h: 0.28, fontSize: 6.5, color: C.textGray, fontFace: "Calibri", align: "center", valign: "top" });
});
slide.addText([
{ text: "TIA: ", options: { bold: true, color: C.steel } },
{ text: "Same symptoms resolving <24h, no infarction on DWI. High early stroke risk (ABCD² score).\n", options: { color: C.textGray } },
{ text: "\nOther warning signs: ", options: { bold: true, color: C.textDark } },
{ text: "Sudden severe headache ('thunderclap'), unilateral vision loss (amaurosis fugax), diplopia, ataxia, vertigo with vomiting, sudden confusion.", options: { color: C.textGray } },
], {
x: col2x + 0.1, y: row1y + 1.08, w: colW - 0.2, h: 0.68,
fontSize: 7.5, fontFace: "Calibri", valign: "top"
});
// ── COL 3: RISK FACTORS & ABCD2 ─────────────────────────────────
panel(slide, col3x, row1y, colW, row1h);
sectionHeader(slide, col3x, row1y, colW, "RISK FACTORS & ABCD² SCORE", C.steel);
slide.addText([
{ text: "Modifiable risk factors:\n", options: { bold: true, color: C.steel } },
{ text: "Hypertension (#1) • Atrial fibrillation • Smoking • Diabetes mellitus • Hyperlipidemia • Carotid stenosis • Heart failure • Obesity • Physical inactivity\n", options: { color: C.textGray } },
{ text: "\nABCD² Score (TIA stroke risk at 2 days)\n", options: { bold: true, color: C.crimson } },
], {
x: col3x + 0.1, y: row1y + 0.30, w: colW - 0.2, h: 0.72,
fontSize: 7.5, fontFace: "Calibri", valign: "top"
});
// ABCD2 mini table
const abcdRows = [
["Age ≥60 yrs", "1"],
["BP ≥140/90", "1"],
["Clinical features: unilateral weakness", "2"],
["Speech disturbance only", "1"],
["Duration ≥60 min", "2 | 10-59 min = 1"],
["Diabetes", "1"],
];
abcdRows.forEach((row, i) => {
const ty = row1y + 1.04 + i * 0.115;
slide.addShape(pres.shapes.RECTANGLE, { x: col3x + 0.1, y: ty, w: 3.3, h: 0.11, fill: { color: i % 2 === 0 ? "E8F0FA" : C.white }, line: { color: C.offwhite } });
slide.addText(row[0], { x: col3x + 0.12, y: ty, w: 2.6, h: 0.11, fontSize: 6.8, color: C.textGray, fontFace: "Calibri", valign: "middle" });
slide.addText(row[1], { x: col3x + 2.72, y: ty, w: 0.7, h: 0.11, fontSize: 6.8, bold: true, color: C.navy, fontFace: "Calibri", align: "center", valign: "middle" });
});
slide.addText("Score 0-3: Low risk | 4-5: Moderate | 6-7: High", {
x: col3x + 0.1, y: row1y + 1.73, w: colW - 0.2, h: 0.12,
fontSize: 6.8, italic: true, color: C.steel, fontFace: "Calibri"
});
// ═══════════════════════════════════════════════════════════════
// ROW 2 — VASCULAR ANATOMY DIAGRAMS (center) + syndromes left/right
// ═══════════════════════════════════════════════════════════════
const row2y = 2.68;
const row2h = 2.52;
// ── LEFT: ANTERIOR CIRCULATION SYNDROMES ────────────────────────
panel(slide, col1x, row2y, 4.25, row2h);
sectionHeader(slide, col1x, row2y, 4.25, "ANTERIOR CIRCULATION STROKES");
slide.addText([
{ text: "MCA (Middle Cerebral Artery) — Most common\n", options: { bold: true, color: C.steel } },
{ text: "Full occlusion: ", options: { bold: true, color: C.textDark } },
{ text: "Contralateral hemiplegia, hemianesthesia, homonymous hemianopia, ipsilateral gaze deviation, dysarthria\n", options: { color: C.textGray } },
{ text: "Dominant (L) hemisphere: ", options: { bold: true, color: C.textDark } },
{ text: "Global aphasia\n", options: { color: C.textGray } },
{ text: "Non-dominant (R) hemisphere: ", options: { bold: true, color: C.textDark } },
{ text: "Anosognosia, hemispatial neglect, constructional apraxia\n", options: { color: C.textGray } },
{ text: "Superior division: ", options: { bold: true, color: C.textDark } },
{ text: "Broca's (non-fluent) aphasia + contralateral face/arm > leg weakness\n", options: { color: C.textGray } },
{ text: "Inferior division: ", options: { bold: true, color: C.textDark } },
{ text: "Wernicke's (fluent) aphasia + superior quadrantanopia\n", options: { color: C.textGray } },
{ text: "Lacunar (lenticulostriate): ", options: { bold: true, color: C.textDark } },
{ text: "Pure motor/sensory stroke; clumsy hand + dysarthria\n\n", options: { color: C.textGray } },
{ text: "ACA (Anterior Cerebral Artery)\n", options: { bold: true, color: C.steel } },
{ text: "Contralateral leg > arm weakness, cortical sensory loss (foot/leg), urinary incontinence, gait apraxia, abulia (bilateral: paraparesis + mutism)\n\n", options: { color: C.textGray } },
{ text: "Internal Carotid Artery (ICA)\n", options: { bold: true, color: C.steel } },
{ text: "Amaurosis fugax (ipsilateral monocular blindness), MCA + ACA territory deficit, Horner's syndrome (if cervical)", options: { color: C.textGray } },
], {
x: col1x + 0.1, y: row2y + 0.30, w: 4.05, h: row2h - 0.36,
fontSize: 7.4, fontFace: "Calibri", valign: "top"
});
// ── CENTER: BRAIN DIAGRAMS ──────────────────────────────────────
const imgX = 4.50;
const imgW = 4.25;
if (images[0] && !images[0].error) {
slide.addImage({ data: images[0].base64, x: imgX, y: row2y + 0.28, w: 2.0, h: 1.55 });
}
if (images[1] && !images[1].error) {
slide.addImage({ data: images[1].base64, x: imgX + 2.1, y: row2y + 0.28, w: 2.1, h: 1.55 });
}
if (images[2] && !images[2].error) {
slide.addImage({ data: images[2].base64, x: imgX + 0.55, y: row2y + 1.90, w: 3.1, h: 1.30 });
}
// Image captions
slide.addText("Coronal vascular territories", { x: imgX, y: row2y + 1.83, w: 2.1, h: 0.14, fontSize: 5.8, italic: true, color: C.textGray, fontFace: "Calibri", align: "center" });
slide.addText("Lateral MCA branches", { x: imgX + 2.1, y: row2y + 1.83, w: 2.1, h: 0.14, fontSize: 5.8, italic: true, color: C.textGray, fontFace: "Calibri", align: "center" });
slide.addText("Medial ACA / PCA distribution", { x: imgX + 0.4, y: row2y + 3.18, w: 3.4, h: 0.14, fontSize: 5.8, italic: true, color: C.textGray, fontFace: "Calibri", align: "center" });
slide.addText("Source: Harrison's Principles of Internal Medicine, 22e", {
x: imgX + 0.1, y: row2y + 3.34, w: 4.0, h: 0.14,
fontSize: 5.5, italic: true, color: "8899AA", fontFace: "Calibri", align: "center"
});
// ── RIGHT: POSTERIOR CIRCULATION SYNDROMES ──────────────────────
panel(slide, 8.9, row2y, 4.25, row2h);
sectionHeader(slide, 8.9, row2y, 4.25, "POSTERIOR CIRCULATION STROKES", C.navy);
slide.addText([
{ text: "PCA (Posterior Cerebral Artery)\n", options: { bold: true, color: C.steel } },
{ text: "P1 (proximal) syndrome: ", options: { bold: true, color: C.textDark } },
{ text: "3rd nerve palsy + contralateral ataxia (Claude's) or hemiplegia (Weber's); thalamic signs (amnesia, confusion), midbrain ischemia\n", options: { color: C.textGray } },
{ text: "P2 (cortical) syndrome: ", options: { bold: true, color: C.textDark } },
{ text: "Homonymous hemianopia (macular sparing), cortical blindness (bilateral), alexia without agraphia, prosopagnosia, memory impairment\n\n", options: { color: C.textGray } },
{ text: "Basilar Artery — EMERGENCY\n", options: { bold: true, color: C.crimson } },
{ text: "Top-of-basilar: ", options: { bold: true, color: C.textDark } },
{ text: "Bilateral motor + sensory deficits, coma, 'locked-in syndrome'\n", options: { color: C.textGray } },
{ text: "Warning: ", options: { bold: true, color: C.textDark } },
{ text: "Multiple TIAs in brainstem territory (diplopia, ataxia, perioral numbness, drop attacks)\n\n", options: { color: C.textGray } },
{ text: "Vertebral Artery / PICA\n", options: { bold: true, color: C.steel } },
{ text: "Lateral medullary (Wallenberg) syndrome: ", options: { bold: true, color: C.textDark } },
{ text: "Ipsilateral: facial pain/numbness, Horner's, ataxia, hoarseness\nContralateral: pain/temp loss body\nDysphagia, vertigo, nystagmus, hiccups\n\n", options: { color: C.textGray } },
{ text: "Lacunar Syndromes (small-vessel)\n", options: { bold: true, color: C.steel } },
{ text: "Pure motor hemiplegia (post. limb internal capsule) • Pure sensory stroke (thalamus VPL) • Ataxic hemiparesis • Clumsy hand–dysarthria • Sensorimotor stroke", options: { color: C.textGray } },
], {
x: 9.0, y: row2y + 0.30, w: 4.05, h: row2h - 0.36,
fontSize: 7.4, fontFace: "Calibri", valign: "top"
});
// ═══════════════════════════════════════════════════════════════
// ROW 3 — MANAGEMENT (3 panels across bottom)
// ═══════════════════════════════════════════════════════════════
const row3y = 5.28;
const row3h = 1.78;
const mgmtW = 4.22;
// ── ACUTE MANAGEMENT ─────────────────────────────────────────────
panel(slide, col1x, row3y, mgmtW, row3h);
sectionHeader(slide, col1x, row3y, mgmtW, "ACUTE MANAGEMENT (ISCHEMIC)", C.crimson);
slide.addText([
{ text: "Time targets:", options: { bold: true, color: C.steel } },
{ text: " Door-to-CT ≤25 min | Door-to-needle (tPA) ≤60 min | Onset-to-needle ≤4.5 h\n", options: { color: C.textGray } },
{ text: "\nIV Alteplase (tPA): ", options: { bold: true, color: C.textDark } },
{ text: "0.9 mg/kg (max 90 mg), 10% bolus + 60 min infusion. Window: ≤4.5 h from onset. Contraindications: ICH, recent surgery, uncontrolled BP >185/110, coagulopathy\n", options: { color: C.textGray } },
{ text: "\nEndovascular thrombectomy (EVT): ", options: { bold: true, color: C.textDark } },
{ text: "Large-vessel occlusion, up to 24 h with perfusion imaging selection (DAWN/DEFUSE-3). Treat BP <185/110 before tPA\n", options: { color: C.textGray } },
{ text: "\nGeneral care: ", options: { bold: true, color: C.textDark } },
{ text: "O₂ only if SpO₂ <94%. Avoid glucose >180 mg/dL. Permissive hypertension (allow up to 220/120 if no tPA). Antipyretics if febrile. DVT prophylaxis.", options: { color: C.textGray } },
], {
x: col1x + 0.1, y: row3y + 0.30, w: mgmtW - 0.2, h: row3h - 0.36,
fontSize: 7.3, fontFace: "Calibri", valign: "top"
});
// ── INVESTIGATIONS ──────────────────────────────────────────────
panel(slide, col2x, row3y, mgmtW, row3h);
sectionHeader(slide, col2x, row3y, mgmtW, "KEY INVESTIGATIONS", C.steel);
slide.addText([
{ text: "IMMEDIATE (all patients):\n", options: { bold: true, color: C.steel } },
{ text: "• NCCT brain — exclude hemorrhage (do NOT delay for MRI)\n• ECG — AF, acute MI\n• Blood: glucose, FBC, coagulation, U&E, troponin, lipids\n• CXR, SpO₂\n\n", options: { color: C.textGray } },
{ text: "IMAGING for reperfusion decisions:\n", options: { bold: true, color: C.steel } },
{ text: "• CT angiography (CTA) — large vessel occlusion, carotid stenosis\n• CT perfusion — ischemic penumbra (salvageable tissue)\n• MRI DWI/PWI — gold standard; confirms TIA vs stroke\n\n", options: { color: C.textGray } },
{ text: "ETIOLOGY WORKUP (admit):\n", options: { bold: true, color: C.steel } },
{ text: "• Cardiac monitoring ≥24h (prolonged telemetry/Holter for AF)\n• Echocardiography — source of emboli\n• Carotid Doppler / CTA neck\n• Hypercoagulable screen if young stroke", options: { color: C.textGray } },
], {
x: col2x + 0.1, y: row3y + 0.30, w: mgmtW - 0.2, h: row3h - 0.36,
fontSize: 7.3, fontFace: "Calibri", valign: "top"
});
// ── SECONDARY PREVENTION ─────────────────────────────────────────
panel(slide, col3x, row3y, mgmtW, row3h);
sectionHeader(slide, col3x, row3y, mgmtW, "SECONDARY PREVENTION & PROGNOSIS", C.navy);
slide.addText([
{ text: "Antiplatelet (non-cardioembolic):\n", options: { bold: true, color: C.steel } },
{ text: "Aspirin 300 mg STAT → dual (aspirin + clopidogrel) for 21 days (POINT/CHANCE), then clopidogrel 75 mg monotherapy\n\n", options: { color: C.textGray } },
{ text: "Anticoagulation (cardioembolic / AF):\n", options: { bold: true, color: C.steel } },
{ text: "DOAC (rivaroxaban / apixaban) preferred over warfarin. Start 4-14 days post-stroke depending on infarct size\n\n", options: { color: C.textGray } },
{ text: "Risk factor control:\n", options: { bold: true, color: C.steel } },
{ text: "BP target <130/80 mmHg • Statin (LDL-C <1.8 mmol/L) • HbA1c control • Smoking cessation • Carotid endarterectomy if stenosis 70-99% (symptomatic)\n\n", options: { color: C.textGray } },
{ text: "Prognosis:", options: { bold: true, color: C.crimson } },
{ text: " ~1/3 recover fully | ~1/3 moderate disability | ~1/3 severe or death. NIHSS score guides prognosis. Stroke Unit care reduces mortality by ~25%.", options: { color: C.textGray } },
], {
x: col3x + 0.1, y: row3y + 0.30, w: mgmtW - 0.2, h: row3h - 0.36,
fontSize: 7.3, fontFace: "Calibri", valign: "top"
});
// ═══════════════════════════════════════════════════════════════
// FOOTER
// ═══════════════════════════════════════════════════════════════
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: H - 0.22, w: W, h: 0.22,
fill: { color: C.navyDark }, line: { color: C.navyDark }
});
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: H - 0.22, w: 0.18, h: 0.22,
fill: { color: C.gold }, line: { color: C.gold }
});
slide.addText(
"Harrison's Principles of Internal Medicine, 22e (2025) · Goldman-Cecil Medicine, International Ed · Bradley & Daroff's Neurology in Clinical Practice · Adams & Victor's Principles of Neurology, 12e",
{
x: 0.24, y: H - 0.22, w: 12.8, h: 0.22,
fontSize: 5.5, color: "8899BB", fontFace: "Calibri",
align: "left", valign: "middle", margin: 0
}
);
// ═══════════════════════════════════════════════════════════════
// DIVIDER LINES between major sections
// ═══════════════════════════════════════════════════════════════
// Horizontal dividers
[row2y - 0.04, row3y - 0.04].forEach(dy => {
slide.addShape(pres.shapes.LINE, {
x: 0.12, y: dy, w: W - 0.24, h: 0,
line: { color: "CBD8E8", pt: 0.5 }
});
});
const outPath = "/home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pptx";
pres.writeFile({ fileName: outPath }).then(() => {
console.log("Poster saved:", outPath);
});
cd /home/daytona/workspace/stroke-poster && node make_poster.js 2>&1
cd /home/daytona/workspace/stroke-poster && \ node /home/daytona/skills/shared/scripts/fetch_images.js "https://cdn.orris.care/cdss_images/a94f73b585c5e20ed028f1355e098e6586f719d44ecf40e25bcecae9becae90e.png" > img1.json && echo "img1 done" && \ node /home/daytona/skills/shared/scripts/fetch_images.js "https://cdn.orris.care/cdss_images/8f0e604f6f7bf69fead85d715302de646237f0d46b91557eecf6337566990d8d.png" > img2.json && echo "img2 done" && \ node /home/daytona/skills/shared/scripts/fetch_images.js "https://cdn.orris.care/cdss_images/697e750632ff92a3b9dd4b7dd47a61a2a44176ffc37a7f4c30e64d9224280140.png" > img3.json && echo "img3 done"
~/stroke-poster/make_poster.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-poster/make_poster.js'
~/stroke-poster/make_poster.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-poster/make_poster.js'
cd /home/daytona/workspace/stroke-poster && node make_poster.js 2>&1
ls -lh /home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pptx && node /home/daytona/skills/pptx/scripts/thumbnail.py /home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pptx 2>/dev/null || python3 /home/daytona/skills/pptx/scripts/thumbnail.py /home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pptx 2>&1 | head -20
ls /home/daytona/workspace/stroke-poster/ && find /home/daytona/workspace/stroke-poster -name "thumbnails*" 2>/dev/null
Stroke Presentation Poster
Presentation · PPTX
Make a PDF version of the poster for easier sharing
libreoffice --headless --convert-to pdf --outdir /home/daytona/workspace/stroke-poster/ /home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pptx 2>&1
cp /home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pptx /tmp/stroke_temp.pptx && libreoffice --headless --convert-to pdf --outdir /tmp/ /tmp/stroke_temp.pptx 2>&1 && cp /tmp/stroke_temp.pdf /home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pdf && ls -lh /home/daytona/workspace/stroke-poster/Stroke_Presentation_Poster.pdf
Stroke Presentation Poster
PDF Document · PDF
Stroke Presentation Poster
Presentation · PPTX
Instagram poster mode
ls /home/daytona/workspace/stroke-poster/img1.json 2>/dev/null && echo "Images already cached" || echo "Need to fetch"
~/stroke-poster/make_instagram.js
const pptxgen = require("pptxgenjs");
const fs = require("fs");
// Load cached images
const img1 = JSON.parse(fs.readFileSync("/home/daytona/workspace/stroke-poster/img1.json"))[0]; // coronal territories
const img2 = JSON.parse(fs.readFileSync("/home/daytona/workspace/stroke-poster/img2.json"))[0]; // lateral MCA
const img3 = JSON.parse(fs.readFileSync("/home/daytona/workspace/stroke-poster/img3.json"))[0]; // medial ACA/PCA
// ── SETUP ─────────────────────────────────────────────────────────────────
const pres = new pptxgen();
// Instagram square = 1080×1080px → use custom layout in inches (1080/96 = 11.25")
pres.defineLayout({ name: "SQUARE", width: 7.5, height: 7.5 });
pres.layout = "SQUARE";
const W = 7.5;
const H = 7.5;
// Color palette — modern, bold, Instagram-optimized
const C = {
navy: "0B1F4B",
navyMid: "142B65",
steel: "1C4E8A",
crimson: "C0272D",
gold: "E8A020",
teal: "0D7377",
purple: "5B2D8E",
green: "1A7A4A",
white: "FFFFFF",
offwhite: "F0F4FA",
light: "D6E4F7",
gray: "556677",
darkgray: "334455",
orange: "D15400",
};
// ── HELPERS ───────────────────────────────────────────────────────────────
function bg(slide, color) {
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: W, h: H,
fill: { color }, line: { color }
});
}
function topBar(slide, color, text, sub) {
// Top accent strip
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: 0, w: W, h: 0.55,
fill: { color }, line: { color }
});
slide.addText(text, {
x: 0.25, y: 0, w: W - 0.5, h: 0.55,
fontSize: 11, bold: true, color: C.white, fontFace: "Calibri",
align: "center", valign: "middle", charSpacing: 1.5
});
if (sub) {
slide.addText(sub, {
x: 0.25, y: 0.55, w: W - 0.5, h: 0.28,
fontSize: 8, color: color, fontFace: "Calibri",
align: "center", valign: "middle", bold: true, charSpacing: 0.5
});
}
}
function bottomBar(slide, pageNum, total) {
slide.addShape(pres.shapes.RECTANGLE, {
x: 0, y: H - 0.38, w: W, h: 0.38,
fill: { color: C.navy }, line: { color: C.navy }
});
slide.addText("STROKE · Harrison's 22e & Goldman-Cecil", {
x: 0.25, y: H - 0.38, w: W - 1.0, h: 0.38,
fontSize: 7, color: "7799BB", fontFace: "Calibri",
align: "left", valign: "middle"
});
slide.addText(`${pageNum}/${total}`, {
x: W - 0.7, y: H - 0.38, w: 0.5, h: 0.38,
fontSize: 8.5, bold: true, color: C.gold, fontFace: "Calibri",
align: "center", valign: "middle"
});
// progress dots
const total2 = total;
const dotW = 0.11; const dotGap = 0.05;
const totalW = total2 * dotW + (total2 - 1) * dotGap;
const startX = (W - totalW) / 2;
for (let i = 0; i < total2; i++) {
slide.addShape(pres.shapes.OVAL, {
x: startX + i * (dotW + dotGap),
y: H - 0.38 - 0.18,
w: dotW, h: dotW,
fill: { color: i + 1 === pageNum ? C.gold : "445566" },
line: { color: i + 1 === pageNum ? C.gold : "445566" }
});
}
}
function sectionLabel(slide, x, y, w, label, color) {
slide.addShape(pres.shapes.RECTANGLE, { x, y, w, h: 0.28, fill: { color }, line: { color } });
slide.addShape(pres.shapes.RECTANGLE, { x, y, w: 0.06, h: 0.28, fill: { color: C.gold }, line: { color: C.gold } });
slide.addText(label, {
x: x + 0.1, y, w: w - 0.12, h: 0.28,
fontSize: 9, bold: true, color: C.white, fontFace: "Calibri",
charSpacing: 1, align: "left", valign: "middle"
});
}
function card(slide, x, y, w, h, fill) {
slide.addShape(pres.shapes.RECTANGLE, {
x, y, w, h,
fill: { color: fill || C.white },
line: { color: "C8D8EC", pt: 0.8 },
shadow: { type: "outer", color: "000000", blur: 5, offset: 2, angle: 135, opacity: 0.1 }
});
}
const TOTAL = 10;
// ════════════════════════════════════════════════════════════════════════
// SLIDE 1 — COVER
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.navy);
// Bold diagonal accent shape
s.addShape(pres.shapes.RECTANGLE, {
x: -0.5, y: 4.8, w: 8.5, h: 3.5,
fill: { color: C.crimson }, line: { color: C.crimson }, rotate: -8
});
s.addShape(pres.shapes.RECTANGLE, {
x: -0.5, y: 5.3, w: 8.5, h: 3.5,
fill: { color: "8B0000" }, line: { color: "8B0000" }, rotate: -8
});
s.addText("STROKE", {
x: 0.3, y: 1.0, w: W - 0.6, h: 1.5,
fontSize: 72, bold: true, color: C.white, fontFace: "Calibri",
align: "center", valign: "middle"
});
s.addText("Clinical Presentation\n& Syndromes", {
x: 0.3, y: 2.5, w: W - 0.6, h: 1.1,
fontSize: 24, color: C.gold, fontFace: "Calibri",
align: "center", valign: "middle", bold: false
});
s.addShape(pres.shapes.LINE, {
x: 1.5, y: 3.68, w: W - 3.0, h: 0,
line: { color: C.gold, pt: 1.5 }
});
s.addText("Based on Harrison's Principles\nof Internal Medicine 22e\n& Goldman-Cecil Medicine", {
x: 0.3, y: 3.78, w: W - 0.6, h: 0.95,
fontSize: 11, color: "99BBDD", fontFace: "Calibri",
align: "center", valign: "middle"
});
s.addText("Swipe to learn →", {
x: 0.3, y: 6.6, w: W - 0.6, h: 0.4,
fontSize: 11, bold: true, color: C.gold, fontFace: "Calibri",
align: "center", valign: "middle"
});
bottomBar(s, 1, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 2 — DEFINITION & CLASSIFICATION
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.navy, "WHAT IS A STROKE?", "Definition & Classification");
// Big stat boxes
const boxes = [
{ label: "87%", sub: "Ischemic", col: C.steel },
{ label: "13%", sub: "Hemorrhagic", col: C.crimson },
];
boxes.forEach((b, i) => {
const bx = 0.4 + i * 3.55;
card(s, bx, 1.0, 3.25, 1.4, C.white);
s.addShape(pres.shapes.RECTANGLE, { x: bx, y: 1.0, w: 3.25, h: 0.08, fill: { color: b.col }, line: { color: b.col } });
s.addText(b.label, { x: bx, y: 1.05, w: 3.25, h: 0.85, fontSize: 44, bold: true, color: b.col, fontFace: "Calibri", align: "center", valign: "middle" });
s.addText(b.sub, { x: bx, y: 1.88, w: 3.25, h: 0.48, fontSize: 13, bold: true, color: b.col, fontFace: "Calibri", align: "center", valign: "middle" });
});
s.addText("Sudden focal neurological deficit due to\ncerebrovascular disease (infarct or bleed)", {
x: 0.3, y: 2.5, w: W - 0.6, h: 0.65,
fontSize: 13, color: C.darkgray, fontFace: "Calibri", align: "center", valign: "middle"
});
// Ischemic subtypes
sectionLabel(s, 0.3, 3.22, W - 0.6, "ISCHEMIC SUBTYPES", C.steel);
const iTypes = [
["Large-vessel atherothrombosis", "~30%"],
["Cardioembolic (AF, LV thrombus)", "~25%"],
["Small-vessel / Lacunar", "~20%"],
["Cryptogenic / Undetermined", "~20%"],
["Other (dissection, vasculitis)", " ~5%"],
];
iTypes.forEach(([label, pct], i) => {
const ry = 3.56 + i * 0.48;
card(s, 0.3, ry, W - 0.6, 0.44, i % 2 === 0 ? "EBF2FB" : C.white);
s.addText(label, { x: 0.42, y: ry, w: 4.9, h: 0.44, fontSize: 11, color: C.darkgray, fontFace: "Calibri", valign: "middle" });
s.addText(pct, { x: 5.32, y: ry, w: 1.85, h: 0.44, fontSize: 12, bold: true, color: C.steel, fontFace: "Calibri", align: "right", valign: "middle" });
});
bottomBar(s, 2, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 3 — FAST + WARNING SIGNS
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.crimson, "RECOGNIZE STROKE FAST", "Time = Brain Cells");
const fastItems = [
{ letter: "F", word: "Face", detail: "Facial droop\nor asymmetry", col: "C0272D" },
{ letter: "A", word: "Arm", detail: "Arm weakness\nor drift", col: "1C4E8A" },
{ letter: "S", word: "Speech", detail: "Slurred or\nabsent speech", col: "1A7A4A" },
{ letter: "T", word: "Time", detail: "Call Emergency\nIMMEDIATELY!", col: "D15400" },
];
fastItems.forEach((item, i) => {
const col = i % 2; const row = Math.floor(i / 2);
const bx = 0.35 + col * 3.55;
const by = 0.9 + row * 2.25;
card(s, bx, by, 3.25, 2.1, C.white);
s.addShape(pres.shapes.RECTANGLE, { x: bx, y: by, w: 3.25, h: 1.1, fill: { color: item.col }, line: { color: item.col } });
s.addText(item.letter, { x: bx, y: by, w: 3.25, h: 1.1, fontSize: 56, bold: true, color: C.white, fontFace: "Calibri", align: "center", valign: "middle" });
s.addText(item.word, { x: bx, y: by + 1.1, w: 3.25, h: 0.42, fontSize: 14, bold: true, color: item.col, fontFace: "Calibri", align: "center", valign: "middle" });
s.addText(item.detail, { x: bx, y: by + 1.52, w: 3.25, h: 0.54, fontSize: 10.5, color: C.gray, fontFace: "Calibri", align: "center", valign: "middle" });
});
s.addText("⏱ Every minute, ~1.9 million neurons die during a stroke", {
x: 0.25, y: 5.45, w: W - 0.5, h: 0.42,
fontSize: 10.5, bold: true, color: C.crimson, fontFace: "Calibri", align: "center", valign: "middle"
});
s.addText("TIA: Same symptoms but resolves <24h. Still URGENT — high early stroke risk!", {
x: 0.25, y: 5.88, w: W - 0.5, h: 0.44,
fontSize: 10, color: C.steel, fontFace: "Calibri", align: "center", valign: "middle",
italic: true
});
bottomBar(s, 3, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 4 — RISK FACTORS
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.steel, "RISK FACTORS", "Modifiable & Non-Modifiable");
sectionLabel(s, 0.3, 0.72, W - 0.6, "MODIFIABLE — TARGET THESE", C.crimson);
const modRFs = [
["🩸", "Hypertension", "#1 modifiable risk factor"],
["💓", "Atrial Fibrillation", "5× stroke risk"],
["🚬", "Smoking", "2× stroke risk"],
["🍬", "Diabetes Mellitus", "1.5–3× risk"],
["🫀", "Hyperlipidaemia", "LDL drives atheroma"],
["⚖️", "Obesity & Inactivity", "Metabolic syndrome"],
["🍷", "Excess Alcohol", ">2 drinks/day"],
["💊", "OCP + Migraine", "Combined = high risk"],
];
modRFs.forEach(([icon, label, note], i) => {
const col = i % 2; const row = Math.floor(i / 2);
const bx = 0.3 + col * 3.55;
const by = 1.06 + row * 0.72;
card(s, bx, by, 3.25, 0.65, col === 0 ? "EBF2FB" : C.white);
s.addText(icon + " " + label, { x: bx + 0.1, y: by, w: 2.5, h: 0.65, fontSize: 10.5, bold: true, color: C.navy, fontFace: "Calibri", valign: "middle" });
s.addText(note, { x: bx + 0.1, y: by + 0.36, w: 3.0, h: 0.29, fontSize: 8.5, color: C.gray, fontFace: "Calibri", valign: "middle" });
});
sectionLabel(s, 0.3, 3.98, W - 0.6, "NON-MODIFIABLE", C.navy);
s.addText("Age > 55 · Male sex · Family history · Prior stroke / TIA · Sickle cell disease · Race (African-Caribbean higher risk)", {
x: 0.3, y: 4.3, w: W - 0.6, h: 0.65,
fontSize: 10.5, color: C.darkgray, fontFace: "Calibri", align: "center", valign: "middle"
});
// ABCD2 mini
sectionLabel(s, 0.3, 5.02, W - 0.6, "ABCD² SCORE — TIA 2-Day Stroke Risk", C.teal);
const abcd = [["Age ≥60", "1"], ["BP ≥140/90", "1"], ["Clinical: unilateral weakness", "2"], ["Speech disturbance only", "1"], ["Duration ≥60 min / 10-59 min", "2 / 1"], ["Diabetes", "1"]];
abcd.forEach(([item, pts], i) => {
const ry = 5.35 + i * 0.29;
s.addShape(pres.shapes.RECTANGLE, { x: 0.3, y: ry, w: W - 0.6, h: 0.27, fill: { color: i % 2 === 0 ? "E8F0FA" : C.white }, line: { color: "DDEEFF" } });
s.addText(item, { x: 0.42, y: ry, w: 5.4, h: 0.27, fontSize: 9.5, color: C.darkgray, fontFace: "Calibri", valign: "middle" });
s.addText(pts, { x: 5.82, y: ry, w: 1.35, h: 0.27, fontSize: 10, bold: true, color: C.crimson, fontFace: "Calibri", align: "center", valign: "middle" });
});
s.addText("0-3 = Low | 4-5 = Moderate | 6-7 = HIGH RISK", {
x: 0.3, y: 7.06, w: W - 0.6, h: 0.28,
fontSize: 9, bold: true, color: C.teal, fontFace: "Calibri", align: "center"
});
bottomBar(s, 4, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 5 — VASCULAR ANATOMY
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.navy);
topBar(s, C.crimson, "CEREBROVASCULAR ANATOMY", "Know the Territories");
// Image 1 — coronal territories
if (img1 && !img1.error) {
s.addImage({ data: img1.base64, x: 0.25, y: 0.75, w: 3.4, h: 2.6 });
}
s.addText("Coronal — Vascular Territories", { x: 0.25, y: 3.35, w: 3.4, h: 0.3, fontSize: 8, italic: true, color: C.light, fontFace: "Calibri", align: "center" });
// Image 2 — lateral MCA
if (img2 && !img2.error) {
s.addImage({ data: img2.base64, x: 3.85, y: 0.75, w: 3.4, h: 2.6 });
}
s.addText("Lateral — MCA Branches & Cortical Areas", { x: 3.85, y: 3.35, w: 3.4, h: 0.3, fontSize: 8, italic: true, color: C.light, fontFace: "Calibri", align: "center" });
// Image 3 — medial
if (img3 && !img3.error) {
s.addImage({ data: img3.base64, x: 1.5, y: 3.72, w: 4.5, h: 3.08 });
}
s.addText("Medial — ACA & PCA Distribution", { x: 1.5, y: 6.78, w: 4.5, h: 0.28, fontSize: 8, italic: true, color: C.light, fontFace: "Calibri", align: "center" });
s.addText("Harrison's Principles of Internal Medicine, 22e", {
x: 0.2, y: 7.04, w: W - 0.4, h: 0.2,
fontSize: 6.5, italic: true, color: "556688", fontFace: "Calibri", align: "center"
});
bottomBar(s, 5, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 6 — MCA STROKE SYNDROMES
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.steel, "MCA STROKE SYNDROMES", "Most Common — ~70% of Ischemic Strokes");
const mcaItems = [
{
title: "Complete MCA Occlusion",
col: C.steel,
items: ["Contralateral hemiplegia (face + arm > leg)", "Hemianesthesia (sensory loss)", "Homonymous hemianopia", "Ipsilateral gaze deviation", "Dysarthria"]
},
{
title: "Dominant (Left) Hemisphere",
col: C.purple,
items: ["Global aphasia (Broca + Wernicke)", "Superior div. → Broca's: non-fluent aphasia, face/arm weakness", "Inferior div. → Wernicke's: fluent aphasia, quadrantanopia"]
},
{
title: "Non-Dominant (Right) Hemisphere",
col: C.teal,
items: ["Anosognosia (denial of deficit)", "Hemispatial neglect (left)", "Constructional apraxia", "Dressing apraxia, spatial disorientation"]
},
{
title: "Lacunar / Lenticulostriate",
col: C.orange,
items: ["Pure motor hemiplegia (post. limb internal capsule)", "Clumsy hand + dysarthria syndrome", "Sensorimotor stroke"]
},
];
mcaItems.forEach((sec, i) => {
const by = 0.82 + i * 1.6;
card(s, 0.28, by, W - 0.56, 1.52, C.white);
s.addShape(pres.shapes.RECTANGLE, { x: 0.28, y: by, w: 0.18, h: 1.52, fill: { color: sec.col }, line: { color: sec.col } });
s.addText(sec.title, {
x: 0.55, y: by + 0.04, w: W - 0.85, h: 0.32,
fontSize: 11, bold: true, color: sec.col, fontFace: "Calibri", valign: "middle"
});
s.addText(sec.items.map(t => "• " + t).join("\n"), {
x: 0.55, y: by + 0.36, w: W - 0.85, h: 1.1,
fontSize: 9.5, color: C.darkgray, fontFace: "Calibri", valign: "top"
});
});
bottomBar(s, 6, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 7 — ACA + PCA + ICA SYNDROMES
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.navy, "ACA · PCA · ICA SYNDROMES", "Anterior Circulation — Continued");
const sections = [
{
title: "ACA — Anterior Cerebral Artery",
col: C.green,
items: [
"Contralateral leg > arm weakness (medial cortex)",
"Cortical sensory loss: foot & leg",
"Urinary incontinence",
"Gait apraxia (frontal lobe)",
"Abulia: slowed responses, lack of spontaneity",
"Bilateral A2 occlusion → paraparesis + mutism"
]
},
{
title: "ICA — Internal Carotid Artery",
col: C.orange,
items: [
"Amaurosis fugax: ipsilateral transient monocular blindness",
"Combines MCA + ACA territory deficits",
"Carotid bruit (tight stenosis)",
"Horner's syndrome (cervical dissection)",
"Massive hemisphere infarct if circle of Willis incompetent"
]
},
{
title: "PCA — Posterior Cerebral Artery (P2 Cortical)",
col: C.purple,
items: [
"Homonymous hemianopia (macular sparing)",
"Bilateral → cortical blindness; may deny blindness (Anton's)",
"Alexia without agraphia (dominant hemisphere)",
"Prosopagnosia (face recognition loss)",
"Memory impairment (hippocampal involvement)"
]
},
];
sections.forEach((sec, i) => {
const by = 0.78 + i * 2.15;
card(s, 0.28, by, W - 0.56, 2.05, C.white);
s.addShape(pres.shapes.RECTANGLE, { x: 0.28, y: by, w: W - 0.56, h: 0.32, fill: { color: sec.col }, line: { color: sec.col } });
s.addText(sec.title, {
x: 0.38, y: by, w: W - 0.7, h: 0.32,
fontSize: 10.5, bold: true, color: C.white, fontFace: "Calibri", valign: "middle"
});
s.addText(sec.items.map(t => "• " + t).join("\n"), {
x: 0.38, y: by + 0.34, w: W - 0.7, h: 1.65,
fontSize: 9.5, color: C.darkgray, fontFace: "Calibri", valign: "top"
});
});
bottomBar(s, 7, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 8 — POSTERIOR CIRCULATION
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.teal, "POSTERIOR CIRCULATION STROKES", "Vertebrobasilar System");
const psecs = [
{
title: "PCA — P1 (Proximal) Syndrome",
col: C.purple,
items: [
"Weber's: ipsilateral CN III palsy + contralateral hemiplegia",
"Claude's: CN III palsy + contralateral ataxia",
"Thalamic: memory loss, confusion, hypersomnia"
]
},
{
title: "Basilar Artery — CRITICAL",
col: C.crimson,
items: [
"Top-of-basilar: coma, bilateral motor/sensory deficits",
"Locked-in syndrome: quadriplegia + intact consciousness",
"Warning TIAs: diplopia, ataxia, perioral numbness, drop attacks"
]
},
{
title: "Lateral Medullary — Wallenberg Syndrome (PICA)",
col: C.teal,
items: [
"Ipsilateral: facial pain/numbness (CN V), Horner's, cerebellar ataxia, hoarseness/dysphagia (CN IX/X)",
"Contralateral: pain & temperature loss (body) — hemisensory",
"Vertigo, nystagmus, intractable hiccups"
]
},
{
title: "Lacunar Syndromes",
col: C.navy,
items: [
"Pure motor hemiplegia — posterior limb internal capsule",
"Pure sensory stroke — VPL nucleus thalamus",
"Ataxic hemiparesis — ipsilateral ataxia + leg weakness",
"Clumsy hand–dysarthria — pons or genu internal capsule"
]
},
];
psecs.forEach((sec, i) => {
const by = 0.78 + i * 1.65;
card(s, 0.28, by, W - 0.56, 1.55, C.white);
s.addShape(pres.shapes.RECTANGLE, { x: 0.28, y: by, w: 0.16, h: 1.55, fill: { color: sec.col }, line: { color: sec.col } });
s.addText(sec.title, {
x: 0.52, y: by + 0.02, w: W - 0.82, h: 0.32,
fontSize: 10.5, bold: true, color: sec.col, fontFace: "Calibri", valign: "middle"
});
s.addText(sec.items.map(t => "• " + t).join("\n"), {
x: 0.52, y: by + 0.34, w: W - 0.82, h: 1.15,
fontSize: 9.2, color: C.darkgray, fontFace: "Calibri", valign: "top"
});
});
bottomBar(s, 8, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 9 — INVESTIGATIONS & ACUTE MANAGEMENT
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.crimson, "INVESTIGATIONS & ACUTE Rx", "Time-Critical Decisions");
// Timeline strip
const times = [
{ t: "0", label: "Onset" },
{ t: "25m", label: "Door-to-CT" },
{ t: "60m", label: "Door-to-Needle" },
{ t: "4.5h", label: "tPA window" },
{ t: "24h", label: "EVT window" },
];
s.addShape(pres.shapes.RECTANGLE, { x: 0.3, y: 0.72, w: W - 0.6, h: 0.08, fill: { color: C.crimson }, line: { color: C.crimson } });
times.forEach((t, i) => {
const tx = 0.3 + (i / (times.length - 1)) * (W - 0.6);
s.addShape(pres.shapes.OVAL, { x: tx - 0.15, y: 0.64, w: 0.3, h: 0.3, fill: { color: C.crimson }, line: { color: C.white, pt: 1 } });
s.addText(t.t, { x: tx - 0.5, y: 0.93, w: 1.0, h: 0.22, fontSize: 8.5, bold: true, color: C.crimson, fontFace: "Calibri", align: "center" });
s.addText(t.label, { x: tx - 0.5, y: 1.13, w: 1.0, h: 0.22, fontSize: 7.5, color: C.gray, fontFace: "Calibri", align: "center" });
});
// Investigations
sectionLabel(s, 0.3, 1.42, W - 0.6, "IMMEDIATE INVESTIGATIONS", C.navy);
const invItems = [
["NCCT Brain", "Exclude hemorrhage before thrombolysis — do NOT delay for MRI"],
["CT Angiography", "Large vessel occlusion? Carotid stenosis?"],
["CT Perfusion", "Penumbra (salvageable tissue) — guides EVT up to 24h"],
["ECG", "Atrial fibrillation, acute MI"],
["Blood tests", "Glucose, FBC, coag, U&E, troponin, lipid profile"],
["MRI DWI/PWI", "Gold standard — confirms TIA vs stroke, posterior fossa"],
];
invItems.forEach(([title, detail], i) => {
const ry = 1.76 + i * 0.48;
card(s, 0.3, ry, W - 0.6, 0.44, i % 2 === 0 ? "EBF2FB" : C.white);
s.addText(title + ":", { x: 0.42, y: ry, w: 1.8, h: 0.44, fontSize: 9.5, bold: true, color: C.steel, fontFace: "Calibri", valign: "middle" });
s.addText(detail, { x: 2.22, y: ry, w: 5.1, h: 0.44, fontSize: 9.2, color: C.darkgray, fontFace: "Calibri", valign: "middle" });
});
sectionLabel(s, 0.3, 4.68, W - 0.6, "REPERFUSION THERAPY", C.crimson);
s.addText([
{ text: "IV Alteplase (tPA): ", options: { bold: true, color: C.crimson } },
{ text: "0.9 mg/kg (max 90 mg). Window ≤4.5h. BP must be <185/110 mmHg.\n", options: { color: C.darkgray } },
{ text: "Endovascular Thrombectomy (EVT): ", options: { bold: true, color: C.navy } },
{ text: "Large vessel occlusion, up to 24h with perfusion imaging (DAWN / DEFUSE-3 trials).\n", options: { color: C.darkgray } },
{ text: "General care: ", options: { bold: true, color: C.teal } },
{ text: "O₂ only if SpO₂ <94% | Permissive HTN up to 220/120 (no tPA) | Avoid glucose >180 | Antipyretics | DVT prophylaxis", options: { color: C.darkgray } },
], {
x: 0.35, y: 5.0, w: W - 0.65, h: 2.08,
fontSize: 9.8, fontFace: "Calibri", valign: "top"
});
bottomBar(s, 9, TOTAL);
}
// ════════════════════════════════════════════════════════════════════════
// SLIDE 10 — SECONDARY PREVENTION + SAVE THIS CARD CTA
// ════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
bg(s, C.offwhite);
topBar(s, C.green, "SECONDARY PREVENTION", "Prevent the Next Stroke");
const prevSecs = [
{
title: "Non-Cardioembolic — Antiplatelet",
col: C.steel,
text: "Aspirin 300 mg STAT → Dual antiplatelet (aspirin + clopidogrel) for 21 days (POINT/CHANCE trial) → then clopidogrel 75 mg monotherapy long-term"
},
{
title: "Cardioembolic / AF — Anticoagulate",
col: C.crimson,
text: "DOAC (apixaban / rivaroxaban) preferred over warfarin. Start 4–14 days post-stroke (size-dependent). Target CHA₂DS₂-VASc ≥2"
},
{
title: "Blood Pressure",
col: C.navy,
text: "Target <130/80 mmHg. ACE-i or ARB + thiazide preferred. Greatest modifiable risk reduction."
},
{
title: "Lipids & Lifestyle",
col: C.teal,
text: "High-intensity statin (target LDL-C <1.8 mmol/L). Smoking cessation. Weight loss. Physical activity ≥150 min/week. Limit alcohol."
},
{
title: "Carotid Revascularization",
col: C.orange,
text: "Carotid endarterectomy (CEA) for symptomatic stenosis 70–99%. CAS (stenting) for surgical high-risk patients. Do within 2 weeks of TIA/stroke."
},
];
prevSecs.forEach((sec, i) => {
const by = 0.78 + i * 1.25;
card(s, 0.28, by, W - 0.56, 1.16, C.white);
s.addShape(pres.shapes.RECTANGLE, { x: 0.28, y: by, w: W - 0.56, h: 0.26, fill: { color: sec.col }, line: { color: sec.col } });
s.addText(sec.title, { x: 0.38, y: by, w: W - 0.7, h: 0.26, fontSize: 10, bold: true, color: C.white, fontFace: "Calibri", valign: "middle" });
s.addText(sec.text, { x: 0.38, y: by + 0.28, w: W - 0.7, h: 0.82, fontSize: 9.5, color: C.darkgray, fontFace: "Calibri", valign: "top" });
});
// Prognosis bar at bottom
s.addShape(pres.shapes.RECTANGLE, { x: 0.28, y: 7.06, w: W - 0.56, h: 0.22, fill: { color: C.navy }, line: { color: C.navy } });
s.addText("Prognosis: ~⅓ full recovery · ~⅓ moderate disability · ~⅓ severe/death. Stroke Unit reduces mortality ~25%", {
x: 0.38, y: 7.06, w: W - 0.7, h: 0.22,
fontSize: 7.5, color: C.gold, fontFace: "Calibri", align: "center", valign: "middle"
});
bottomBar(s, 10, TOTAL);
}
// ── WRITE FILE ─────────────────────────────────────────────────────────────
const outPath = "/home/daytona/workspace/stroke-poster/Stroke_Instagram_Carousel.pptx";
pres.writeFile({ fileName: outPath }).then(() => {
console.log("Instagram carousel saved:", outPath);
});
cd /home/daytona/workspace/stroke-poster && node make_instagram.js 2>&1
cp /home/daytona/workspace/stroke-poster/Stroke_Instagram_Carousel.pptx /tmp/insta_temp.pptx && libreoffice --headless --convert-to pdf --outdir /tmp/ /tmp/insta_temp.pptx 2>&1 && cp /tmp/insta_temp.pdf /home/daytona/workspace/stroke-poster/Stroke_Instagram_Carousel.pdf && ls -lh /home/daytona/workspace/stroke-poster/Stroke_Instagram_Carousel.pdf
Stroke Instagram Carousel
Presentation · PPTX
Stroke Instagram Carousel
PDF Document · PDF
| # | Card | Color |
|---|---|---|
| 1 | Cover — Bold title + "Swipe to learn →" | Dark navy + crimson |
| 2 | Definition & Classification — 87% ischemic vs 13% hemorrhagic with % breakdown | Navy |
| 3 | FAST Recognition — Big F·A·S·T boxes + "1.9M neurons/min" stat | Crimson |
| 4 | Risk Factors + ABCD² Score — Emoji-labeled risks + scoring table | Steel blue |
| 5 | Cerebrovascular Anatomy — All 3 Harrison's diagrams (territories, MCA lateral, ACA/PCA medial) | Dark navy |
| 6 | MCA Syndromes — Complete, dominant, non-dominant, lacunar | Steel blue |
| 7 | ACA · PCA · ICA Syndromes | Navy |
| 8 | Posterior Circulation — Wallenberg, basilar, locked-in, lacunar | Teal |
| 9 | Investigations + Acute Management — Timeline strip + tPA/EVT details | Crimson |
| 10 | Secondary Prevention — Antiplatelets, anticoagulation, BP, statins, CEA | Green |