kindly make a ppt of above
mkdir -p /home/daytona/workspace/pandemic-module && ls /home/daytona/workspace/pandemic-module/
~/pandemic-module/create_ppt.js
const pptxgen = require("pptxgenjs");
let pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "PANDEMIC Module 4.4 - Information Management during Pandemics";
pres.author = "GEN MED / PUL MED / ANAES";
// Color palette
const DARK_BLUE = "0A1628";
const MED_BLUE = "1B3A6B";
const ACCENT_TEAL = "00B4D8";
const ACCENT_ORANGE = "F77F00";
const LIGHT_BG = "EAF4FB";
const WHITE = "FFFFFF";
const LIGHT_GRAY = "D0E8F2";
const DARK_TEXT = "0A1628";
// ─────────────────────────────────────────────
// SLIDE 1 – TITLE SLIDE
// ─────────────────────────────────────────────
let slide1 = pres.addSlide();
// Dark background
slide1.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: DARK_BLUE } });
// Accent bar (teal left strip)
slide1.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.18, h: 5.625, fill: { color: ACCENT_TEAL } });
// Orange accent line at top
slide1.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 0.07, fill: { color: ACCENT_ORANGE } });
// Module label
slide1.addText("MODULE 4.4", {
x: 0.5, y: 0.6, w: 9, h: 0.55,
fontSize: 14, bold: true, color: ACCENT_TEAL,
charSpacing: 6, align: "center", fontFace: "Calibri"
});
// Main title
slide1.addText("PANDEMIC", {
x: 0.5, y: 1.2, w: 9, h: 1.0,
fontSize: 56, bold: true, color: WHITE,
align: "center", fontFace: "Calibri"
});
// Subtitle
slide1.addText("Information Management during Pandemics", {
x: 0.5, y: 2.25, w: 9, h: 0.75,
fontSize: 22, bold: false, color: LIGHT_GRAY,
align: "center", fontFace: "Calibri"
});
// Horizontal divider
slide1.addShape(pres.ShapeType.rect, { x: 1.5, y: 3.15, w: 7, h: 0.05, fill: { color: ACCENT_TEAL } });
// Duration
slide1.addText("⏱ Duration: 2 Hours | Interactive Discussion", {
x: 0.5, y: 3.3, w: 9, h: 0.5,
fontSize: 14, bold: false, color: LIGHT_GRAY,
align: "center", fontFace: "Calibri"
});
// Department tag
slide1.addShape(pres.ShapeType.rect, { x: 2.5, y: 4.2, w: 5, h: 0.55, fill: { color: MED_BLUE } });
slide1.addText("GEN MED / PUL MED / ANAES", {
x: 2.5, y: 4.2, w: 5, h: 0.55,
fontSize: 12, bold: true, color: WHITE,
align: "center", fontFace: "Calibri"
});
// ─────────────────────────────────────────────
// SLIDE 2 – MODULE OVERVIEW
// ─────────────────────────────────────────────
let slide2 = pres.addSlide();
// Light background
slide2.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: LIGHT_BG } });
// Top header bar
slide2.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 1.05, fill: { color: MED_BLUE } });
slide2.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 0.07, fill: { color: ACCENT_TEAL } });
slide2.addText("Module Overview", {
x: 0.4, y: 0.1, w: 9, h: 0.85,
fontSize: 28, bold: true, color: WHITE,
fontFace: "Calibri", valign: "middle"
});
// Three info boxes
const boxes = [
{ label: "Module", value: "4.4", icon: "📋", x: 0.4 },
{ label: "Duration", value: "2 Hours", icon: "⏱", x: 3.7 },
{ label: "Method", value: "Interactive Discussion", icon: "💬", x: 6.7 }
];
boxes.forEach(b => {
slide2.addShape(pres.ShapeType.rect, {
x: b.x, y: 1.25, w: 2.8, h: 1.5,
fill: { color: WHITE },
line: { color: ACCENT_TEAL, width: 2 }
});
slide2.addText(b.icon, { x: b.x, y: 1.3, w: 2.8, h: 0.5, fontSize: 22, align: "center" });
slide2.addText(b.value, {
x: b.x, y: 1.8, w: 2.8, h: 0.5,
fontSize: 16, bold: true, color: DARK_BLUE,
align: "center", fontFace: "Calibri"
});
slide2.addText(b.label, {
x: b.x, y: 2.3, w: 2.8, h: 0.35,
fontSize: 11, color: "555555",
align: "center", fontFace: "Calibri"
});
});
// Topics intro
slide2.addText("Topics Covered in This Module", {
x: 0.4, y: 3.0, w: 9, h: 0.45,
fontSize: 16, bold: true, color: MED_BLUE,
fontFace: "Calibri"
});
slide2.addShape(pres.ShapeType.rect, { x: 0.4, y: 3.45, w: 9.2, h: 0.05, fill: { color: ACCENT_TEAL } });
slide2.addText([
{ text: "a. Responding to Media", options: { bullet: false, breakLine: true } },
{ text: "b. Use and Misuse of Social Media for Health Related Messages", options: { bullet: false } }
], {
x: 0.5, y: 3.55, w: 9, h: 1.6,
fontSize: 15, color: DARK_TEXT,
fontFace: "Calibri", lineSpacingMultiple: 1.6
});
// ─────────────────────────────────────────────
// SLIDE 3 – TOPIC A: RESPONDING TO MEDIA
// ─────────────────────────────────────────────
let slide3 = pres.addSlide();
slide3.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: WHITE } });
// Left accent column
slide3.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.5, h: 5.625, fill: { color: MED_BLUE } });
slide3.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.5, h: 1.5, fill: { color: ACCENT_TEAL } });
// Header
slide3.addShape(pres.ShapeType.rect, { x: 0.5, y: 0, w: 9.5, h: 1.1, fill: { color: "F0F8FC" } });
slide3.addText("Topic a", {
x: 0.7, y: 0.05, w: 9, h: 0.4,
fontSize: 11, bold: true, color: ACCENT_TEAL,
fontFace: "Calibri", charSpacing: 3
});
slide3.addText("Responding to Media", {
x: 0.7, y: 0.42, w: 9, h: 0.65,
fontSize: 26, bold: true, color: DARK_BLUE,
fontFace: "Calibri"
});
// Content points
const mediaPoints = [
{ icon: "🎯", title: "Be Prepared", body: "Designate a trained spokesperson. Prepare key messages in advance. Know your facts and data." },
{ icon: "🔍", title: "Accuracy First", body: "Always verify information before sharing. Correct misinformation calmly and respectfully." },
{ icon: "🤝", title: "Transparency", body: "Acknowledge uncertainties openly. Provide timely updates as new information becomes available." },
{ icon: "📢", title: "Clear Communication", body: "Use plain language. Avoid jargon. Tailor messages to your audience." }
];
mediaPoints.forEach((pt, i) => {
const col = i % 2;
const row = Math.floor(i / 2);
const x = 0.7 + col * 4.65;
const y = 1.3 + row * 2.0;
slide3.addShape(pres.ShapeType.rect, {
x, y, w: 4.3, h: 1.75,
fill: { color: i % 2 === 0 ? "EAF4FB" : "FFF4E6" },
line: { color: i % 2 === 0 ? ACCENT_TEAL : ACCENT_ORANGE, width: 1.5 }
});
slide3.addText(pt.icon + " " + pt.title, {
x: x + 0.12, y: y + 0.12, w: 4.0, h: 0.45,
fontSize: 13, bold: true, color: DARK_BLUE,
fontFace: "Calibri"
});
slide3.addText(pt.body, {
x: x + 0.12, y: y + 0.58, w: 4.0, h: 1.05,
fontSize: 11.5, color: "333333",
fontFace: "Calibri", lineSpacingMultiple: 1.3
});
});
// ─────────────────────────────────────────────
// SLIDE 4 – MEDIA STRATEGY (deep dive)
// ─────────────────────────────────────────────
let slide4 = pres.addSlide();
slide4.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: DARK_BLUE } });
slide4.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 0.07, fill: { color: ACCENT_ORANGE } });
slide4.addText("Media Response Strategy", {
x: 0.5, y: 0.2, w: 9, h: 0.75,
fontSize: 28, bold: true, color: WHITE,
fontFace: "Calibri", align: "center"
});
slide4.addText("Topic a – Deep Dive", {
x: 0.5, y: 0.9, w: 9, h: 0.4,
fontSize: 13, color: ACCENT_TEAL,
fontFace: "Calibri", align: "center", charSpacing: 3
});
// Timeline / step boxes
const steps = [
{ num: "01", label: "Before the Interview", body: "Brief the spokesperson\nPrepare Q&A sheets\nConfirm key statistics" },
{ num: "02", label: "During the Interview", body: "Stay on-message\nBridge back to key points\nAvoid speculation" },
{ num: "03", label: "After the Interview", body: "Monitor coverage\nCorrect errors promptly\nShare approved transcript" },
{ num: "04", label: "Crisis Communication", body: "Activate rapid response team\nIssue holding statements\nEscalate to leadership" }
];
steps.forEach((s, i) => {
const x = 0.3 + i * 2.37;
slide4.addShape(pres.ShapeType.rect, { x, y: 1.55, w: 2.1, h: 3.6, fill: { color: MED_BLUE } });
slide4.addShape(pres.ShapeType.rect, { x, y: 1.55, w: 2.1, h: 0.65, fill: { color: ACCENT_TEAL } });
slide4.addText(s.num, {
x, y: 1.55, w: 2.1, h: 0.65,
fontSize: 20, bold: true, color: DARK_BLUE,
align: "center", valign: "middle", fontFace: "Calibri"
});
slide4.addText(s.label, {
x: x + 0.08, y: 2.25, w: 1.95, h: 0.65,
fontSize: 12, bold: true, color: WHITE,
align: "center", fontFace: "Calibri", lineSpacingMultiple: 1.2
});
slide4.addText(s.body, {
x: x + 0.08, y: 2.95, w: 1.95, h: 2.1,
fontSize: 10.5, color: LIGHT_GRAY,
align: "left", fontFace: "Calibri", lineSpacingMultiple: 1.4
});
});
// ─────────────────────────────────────────────
// SLIDE 5 – TOPIC B: SOCIAL MEDIA
// ─────────────────────────────────────────────
let slide5 = pres.addSlide();
slide5.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: WHITE } });
slide5.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 0.08, fill: { color: ACCENT_ORANGE } });
slide5.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.5, h: 5.625, fill: { color: ACCENT_ORANGE } });
slide5.addText("Topic b", {
x: 0.7, y: 0.1, w: 9, h: 0.4,
fontSize: 11, bold: true, color: ACCENT_ORANGE,
fontFace: "Calibri", charSpacing: 3
});
slide5.addText("Use and Misuse of Social Media", {
x: 0.7, y: 0.45, w: 9, h: 0.6,
fontSize: 26, bold: true, color: DARK_BLUE,
fontFace: "Calibri"
});
slide5.addText("for Health Related Messages", {
x: 0.7, y: 1.0, w: 9, h: 0.45,
fontSize: 18, bold: false, color: MED_BLUE,
fontFace: "Calibri"
});
// Two-column layout: USE vs MISUSE
// Use column
slide5.addShape(pres.ShapeType.rect, { x: 0.7, y: 1.6, w: 4.0, h: 0.5, fill: { color: ACCENT_TEAL } });
slide5.addText("✅ BENEFICIAL USE", {
x: 0.7, y: 1.6, w: 4.0, h: 0.5,
fontSize: 13, bold: true, color: WHITE,
align: "center", valign: "middle", fontFace: "Calibri"
});
const usePoints = [
"Rapid dissemination of accurate health alerts",
"Real-time public communication by health authorities",
"Monitoring public sentiment and questions",
"Community engagement and behavior change",
"Sharing updates: vaccination drives, outbreaks"
];
usePoints.forEach((pt, i) => {
slide5.addShape(pres.ShapeType.rect, {
x: 0.7, y: 2.18 + i * 0.57, w: 4.0, h: 0.52,
fill: { color: i % 2 === 0 ? "EAF4FB" : WHITE },
line: { color: "CCDDEE", width: 0.5 }
});
slide5.addText("• " + pt, {
x: 0.85, y: 2.19 + i * 0.57, w: 3.7, h: 0.5,
fontSize: 10.5, color: DARK_TEXT,
fontFace: "Calibri", valign: "middle"
});
});
// Misuse column
slide5.addShape(pres.ShapeType.rect, { x: 5.3, y: 1.6, w: 4.3, h: 0.5, fill: { color: ACCENT_ORANGE } });
slide5.addText("⚠️ MISUSE & RISKS", {
x: 5.3, y: 1.6, w: 4.3, h: 0.5,
fontSize: 13, bold: true, color: WHITE,
align: "center", valign: "middle", fontFace: "Calibri"
});
const misusePoints = [
"Spread of misinformation and conspiracy theories",
"Amplification of fear and panic",
"Unverified cures and remedies circulating",
"Stigmatization of communities or individuals",
"Overwhelming official channels with false reports"
];
misusePoints.forEach((pt, i) => {
slide5.addShape(pres.ShapeType.rect, {
x: 5.3, y: 2.18 + i * 0.57, w: 4.3, h: 0.52,
fill: { color: i % 2 === 0 ? "FFF4E6" : WHITE },
line: { color: "EECC99", width: 0.5 }
});
slide5.addText("• " + pt, {
x: 5.45, y: 2.19 + i * 0.57, w: 4.0, h: 0.5,
fontSize: 10.5, color: DARK_TEXT,
fontFace: "Calibri", valign: "middle"
});
});
// ─────────────────────────────────────────────
// SLIDE 6 – INFODEMIC & COUNTERING MISINFORMATION
// ─────────────────────────────────────────────
let slide6 = pres.addSlide();
slide6.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: "F8F9FA" } });
slide6.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 1.1, fill: { color: MED_BLUE } });
slide6.addText("The Infodemic Challenge", {
x: 0.5, y: 0.15, w: 9, h: 0.6,
fontSize: 26, bold: true, color: WHITE,
fontFace: "Calibri"
});
slide6.addText("Managing misinformation during a pandemic", {
x: 0.5, y: 0.7, w: 9, h: 0.35,
fontSize: 13, color: LIGHT_GRAY,
fontFace: "Calibri"
});
// Definition box
slide6.addShape(pres.ShapeType.rect, {
x: 0.5, y: 1.2, w: 9, h: 0.85,
fill: { color: MED_BLUE },
line: { color: ACCENT_TEAL, width: 2 }
});
slide6.addText('"An infodemic is an overabundance of information — both accurate and inaccurate — that spreads alongside an epidemic, making it hard for people to find trustworthy guidance." — WHO', {
x: 0.65, y: 1.25, w: 8.7, h: 0.75,
fontSize: 11, italic: true, color: WHITE,
fontFace: "Calibri", valign: "middle"
});
// Strategies
const strategies = [
{ num: "1", title: "Verify Before Sharing", desc: "Cross-check with WHO, CDC, and official health authority sources before posting or forwarding any health information." },
{ num: "2", title: "Platform Collaboration", desc: "Work with social media platforms to flag, remove, or label health misinformation rapidly." },
{ num: "3", title: "Prebunking", desc: "Proactively educate the public on common myths and manipulation tactics before misinformation spreads." },
{ num: "4", title: "Engage Trusted Voices", desc: "Amplify messages from trusted community figures, healthcare workers, and local leaders." }
];
strategies.forEach((s, i) => {
const col = i % 2;
const row = Math.floor(i / 2);
const x = 0.4 + col * 4.8;
const y = 2.22 + row * 1.55;
slide6.addShape(pres.ShapeType.rect, {
x, y, w: 4.5, h: 1.4,
fill: { color: WHITE },
line: { color: i < 2 ? ACCENT_TEAL : ACCENT_ORANGE, width: 1.5 }
});
slide6.addShape(pres.ShapeType.rect, { x, y, w: 0.4, h: 1.4, fill: { color: i < 2 ? ACCENT_TEAL : ACCENT_ORANGE } });
slide6.addText(s.num, {
x, y, w: 0.4, h: 1.4,
fontSize: 16, bold: true, color: WHITE,
align: "center", valign: "middle", fontFace: "Calibri"
});
slide6.addText(s.title, {
x: x + 0.5, y: y + 0.1, w: 3.85, h: 0.4,
fontSize: 12, bold: true, color: DARK_BLUE,
fontFace: "Calibri"
});
slide6.addText(s.desc, {
x: x + 0.5, y: y + 0.5, w: 3.85, h: 0.8,
fontSize: 10, color: "444444",
fontFace: "Calibri", lineSpacingMultiple: 1.3
});
});
// ─────────────────────────────────────────────
// SLIDE 7 – KEY PRINCIPLES
// ─────────────────────────────────────────────
let slide7 = pres.addSlide();
slide7.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: DARK_BLUE } });
slide7.addShape(pres.ShapeType.rect, { x: 0, y: 5.5, w: 10, h: 0.125, fill: { color: ACCENT_TEAL } });
slide7.addText("Key Principles", {
x: 0.5, y: 0.25, w: 9, h: 0.65,
fontSize: 30, bold: true, color: WHITE,
fontFace: "Calibri", align: "center"
});
slide7.addText("Information Management during Pandemics", {
x: 0.5, y: 0.85, w: 9, h: 0.4,
fontSize: 14, color: ACCENT_TEAL,
fontFace: "Calibri", align: "center"
});
const principles = [
{ icon: "🎯", title: "Accuracy", desc: "Share only verified information from authoritative sources" },
{ icon: "⚡", title: "Timeliness", desc: "Communicate early and update regularly as the situation evolves" },
{ icon: "🔍", title: "Transparency", desc: "Be open about what is known, unknown and uncertain" },
{ icon: "🌐", title: "Reach", desc: "Use multiple channels to reach all segments of the population" },
{ icon: "💬", title: "Clarity", desc: "Use simple, plain language free of technical jargon" },
{ icon: "🤝", title: "Trust", desc: "Build and maintain public trust through consistent messaging" }
];
principles.forEach((p, i) => {
const col = i % 3;
const row = Math.floor(i / 3);
const x = 0.35 + col * 3.2;
const y = 1.45 + row * 1.9;
slide7.addShape(pres.ShapeType.rect, {
x, y, w: 2.85, h: 1.75,
fill: { color: MED_BLUE }
});
slide7.addShape(pres.ShapeType.rect, {
x, y, w: 2.85, h: 0.07,
fill: { color: i % 2 === 0 ? ACCENT_TEAL : ACCENT_ORANGE }
});
slide7.addText(p.icon, {
x, y: y + 0.12, w: 2.85, h: 0.5,
fontSize: 22, align: "center"
});
slide7.addText(p.title, {
x: x + 0.1, y: y + 0.65, w: 2.65, h: 0.4,
fontSize: 13, bold: true, color: WHITE,
align: "center", fontFace: "Calibri"
});
slide7.addText(p.desc, {
x: x + 0.1, y: y + 1.05, w: 2.65, h: 0.6,
fontSize: 9.5, color: LIGHT_GRAY,
align: "center", fontFace: "Calibri", lineSpacingMultiple: 1.3
});
});
// ─────────────────────────────────────────────
// SLIDE 8 – SUMMARY / THANK YOU
// ─────────────────────────────────────────────
let slide8 = pres.addSlide();
slide8.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: MED_BLUE } });
slide8.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 0.08, fill: { color: ACCENT_TEAL } });
slide8.addShape(pres.ShapeType.rect, { x: 0, y: 5.545, w: 10, h: 0.08, fill: { color: ACCENT_ORANGE } });
slide8.addText("Module Summary", {
x: 0.5, y: 0.3, w: 9, h: 0.65,
fontSize: 30, bold: true, color: WHITE,
fontFace: "Calibri", align: "center"
});
const summaryPoints = [
{ icon: "📋", text: "Module 4.4 covers Information Management during Pandemics — 2 hours, interactive discussion" },
{ icon: "📺", text: "Topic a: Responding to media requires preparation, accuracy, transparency and clear messaging" },
{ icon: "📱", text: "Topic b: Social media can amplify both accurate health messages and dangerous misinformation" },
{ icon: "⚠️", text: "The 'infodemic' is a parallel public health crisis that must be actively managed" },
{ icon: "✅", text: "Health professionals must lead with trusted, verified, timely and clear communication" }
];
summaryPoints.forEach((pt, i) => {
slide8.addShape(pres.ShapeType.rect, {
x: 0.5, y: 1.15 + i * 0.83, w: 9, h: 0.72,
fill: { color: i % 2 === 0 ? "1E4578" : "163567" },
line: { color: ACCENT_TEAL, width: 0.8 }
});
slide8.addText(pt.icon + " " + pt.text, {
x: 0.65, y: 1.2 + i * 0.83, w: 8.7, h: 0.62,
fontSize: 12, color: WHITE,
fontFace: "Calibri", valign: "middle", lineSpacingMultiple: 1.2
});
});
// Footer
slide8.addText("GEN MED / PUL MED / ANAES", {
x: 0.5, y: 5.25, w: 9, h: 0.3,
fontSize: 10, color: LIGHT_GRAY,
fontFace: "Calibri", align: "center"
});
// ─────────────────────────────────────────────
// WRITE FILE
// ─────────────────────────────────────────────
pres.writeFile({ fileName: "/home/daytona/workspace/pandemic-module/Pandemic_Module_4_4.pptx" })
.then(() => console.log("SUCCESS: Pandemic_Module_4_4.pptx created"))
.catch(err => console.error("ERROR:", err));
cd /home/daytona/workspace/pandemic-module && node create_ppt.js
| Slide | Content |
|---|---|
| 1 | Title Slide - Module 4.4 branding, 2-hour duration, GEN MED/PUL MED/ANAES |
| 2 | Module Overview - info cards + topic listing |
| 3 | Topic a: Responding to Media - 4 key areas (Be Prepared, Accuracy, Transparency, Clear Communication) |
| 4 | Media Response Strategy - 4-step timeline (Before/During/After interview + Crisis Comms) |
| 5 | Topic b: Social Media - side-by-side Beneficial Use vs Misuse & Risks |
| 6 | The Infodemic Challenge - WHO definition + 4 counter-strategies |
| 7 | Key Principles - 6-tile grid (Accuracy, Timeliness, Transparency, Reach, Clarity, Trust) |
| 8 | Summary Slide - 5 key takeaways |
Pandemic Module 4 4
Presentation · PPTX
unable to download it
ls -lh /home/daytona/workspace/pandemic-module/
cd /home/daytona/workspace/pandemic-module && libreoffice --headless --convert-to pdf Pandemic_Module_4_4.pptx --outdir /home/daytona/workspace/pandemic-module/ 2>&1
cp /home/daytona/workspace/pandemic-module/Pandemic_Module_4_4.pptx /home/daytona/workspace/Pandemic_Module_4_4.pptx && ls -lh /home/daytona/workspace/Pandemic_Module_4_4.pptx
Pandemic Module 4 4
Presentation · PPTX
i phone and firefox app
cd /home/daytona/workspace && libreoffice --headless --convert-to pdf --outdir /home/daytona/workspace/ Pandemic_Module_4_4.pptx 2>&1
mkdir -p /home/daytona/workspace/output && cp /home/daytona/workspace/Pandemic_Module_4_4.pptx /home/daytona/workspace/output/ && libreoffice --headless --convert-to pdf --outdir /home/daytona/workspace/output/ /home/daytona/workspace/output/Pandemic_Module_4_4.pptx 2>&1
~/pandemic-module/make_pdf.py
from reportlab.lib.pagesizes import landscape, A4
from reportlab.lib import colors
from reportlab.lib.units import inch, cm
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import PageBreak
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor
import os
OUT = "/home/daytona/workspace/pandemic-module/Pandemic_Module_4_4.pdf"
# Colors
DARK_BLUE = HexColor("#0A1628")
MED_BLUE = HexColor("#1B3A6B")
ACCENT_TEAL = HexColor("#00B4D8")
ACCENT_ORG = HexColor("#F77F00")
LIGHT_BG = HexColor("#EAF4FB")
WHITE = colors.white
LIGHT_GRAY = HexColor("#D0E8F2")
DARK_TEXT = HexColor("#0A1628")
MID_GRAY = HexColor("#444444")
PW, PH = landscape(A4) # 842 x 595 pts
class PandemicPDF:
def __init__(self, path):
self.path = path
self.c = canvas.Canvas(path, pagesize=landscape(A4))
self.c.setTitle("Pandemic Module 4.4 – Information Management during Pandemics")
# ── helpers ──────────────────────────────────────────
def rect(self, x, y, w, h, fill, stroke=None, lw=0):
self.c.saveState()
if stroke:
self.c.setStrokeColor(stroke)
self.c.setLineWidth(lw)
else:
self.c.setStrokeColor(fill)
self.c.setLineWidth(0)
self.c.setFillColor(fill)
self.c.rect(x, y, w, h, fill=1, stroke=1 if stroke else 0)
self.c.restoreState()
def text(self, txt, x, y, size=12, color=WHITE, bold=False, align="left", width=None):
self.c.saveState()
self.c.setFillColor(color)
face = "Helvetica-Bold" if bold else "Helvetica"
self.c.setFont(face, size)
if align == "center" and width:
self.c.drawCentredString(x + width/2, y, txt)
elif align == "right" and width:
self.c.drawRightString(x + width, y, txt)
else:
self.c.drawString(x, y, txt)
self.c.restoreState()
def wrapped_text(self, txt, x, y, w, size=11, color=WHITE, bold=False, align=TA_LEFT, leading=None):
"""Draw wrapped paragraph and return new y after drawing."""
self.c.saveState()
face = "Helvetica-Bold" if bold else "Helvetica"
style = ParagraphStyle("tmp", fontName=face, fontSize=size, textColor=color,
alignment=align, leading=leading or size*1.35)
p = Paragraph(txt.replace("\n", "<br/>"), style)
pw, ph = p.wrap(w, 9999)
p.drawOn(self.c, x, y - ph)
self.c.restoreState()
return y - ph
def next_page(self):
self.c.showPage()
def save(self):
self.c.save()
# ── SLIDE 1 – TITLE ───────────────────────────────────
def slide_title(self):
c = self.c
# Background
self.rect(0, 0, PW, PH, DARK_BLUE)
# Top orange bar
self.rect(0, PH-4, PW, 4, ACCENT_ORG)
# Left teal strip
self.rect(0, 0, 10, PH, ACCENT_TEAL)
# Bottom teal bar
self.rect(0, 0, PW, 4, ACCENT_TEAL)
# Module label
self.text("MODULE 4.4", 0, PH-55, size=15, color=ACCENT_TEAL, bold=True,
align="center", width=PW)
# Main title
self.text("PANDEMIC", 0, PH-115, size=62, color=WHITE, bold=True,
align="center", width=PW)
# Subtitle
self.text("Information Management during Pandemics", 0, PH-165,
size=22, color=LIGHT_GRAY, align="center", width=PW)
# Divider
self.rect(PW*0.15, PH-190, PW*0.7, 2, ACCENT_TEAL)
# Duration
self.text("Duration: 2 Hours | Interactive Discussion", 0, PH-215,
size=14, color=LIGHT_GRAY, align="center", width=PW)
# Dept tag box
bx = PW*0.3; bw = PW*0.4; by = 60
self.rect(bx, by, bw, 38, MED_BLUE)
self.text("GEN MED / PUL MED / ANAES", bx, by+13,
size=13, color=WHITE, bold=True, align="center", width=bw)
# ── SLIDE 2 – OVERVIEW ────────────────────────────────
def slide_overview(self):
self.rect(0, 0, PW, PH, LIGHT_BG)
# Header
self.rect(0, PH-70, PW, 70, MED_BLUE)
self.rect(0, PH-4, PW, 4, ACCENT_TEAL)
self.text("Module Overview", 28, PH-48, size=28, color=WHITE, bold=True)
# 3 info cards
cards = [
("Module", "4.4", "📋"),
("Duration", "2 Hours", "⏱"),
("Method", "Interactive\nDiscussion", "💬"),
]
card_w = 200; gap = 40; start_x = (PW - 3*card_w - 2*gap)/2
for i, (label, val, icon) in enumerate(cards):
cx = start_x + i*(card_w+gap)
cy = PH - 230
self.rect(cx, cy, card_w, 130, WHITE, stroke=ACCENT_TEAL, lw=1.5)
self.rect(cx, cy+90, card_w, 40, ACCENT_TEAL)
self.text(icon, cx, cy+103, size=20, color=WHITE, align="center", width=card_w)
self.text(val.replace("\n"," "), cx, cy+55, size=16, color=DARK_BLUE,
bold=True, align="center", width=card_w)
self.text(label, cx, cy+30, size=11, color=MID_GRAY, align="center", width=card_w)
# Topics
self.text("Topics Covered in This Module", 40, PH-280,
size=16, color=MED_BLUE, bold=True)
self.rect(40, PH-290, PW-80, 2, ACCENT_TEAL)
topics = [
"a. Responding to Media",
"b. Use and Misuse of Social Media for Health Related Messages",
]
for i, t in enumerate(topics):
bg = LIGHT_BG if i % 2 == 0 else WHITE
self.rect(40, PH-340 - i*52, PW-80, 48, bg, stroke=HexColor("#CCDDEE"), lw=0.5)
self.text(t, 60, PH-318 - i*52, size=14, color=DARK_TEXT)
# ── SLIDE 3 – TOPIC A ─────────────────────────────────
def slide_topic_a(self):
self.rect(0, 0, PW, PH, WHITE)
# Left accent
self.rect(0, 0, 8, PH, MED_BLUE)
self.rect(0, PH-110, 8, 110, ACCENT_TEAL)
# Header
self.rect(8, PH-70, PW-8, 70, HexColor("#F0F8FC"))
self.text("Topic a", 28, PH-28, size=11, color=ACCENT_TEAL, bold=True)
self.text("Responding to Media", 28, PH-55, size=26, color=DARK_BLUE, bold=True)
pts = [
("Accuracy First", "Always verify information before sharing. Correct misinformation calmly.", ACCENT_TEAL, LIGHT_BG),
("Transparency", "Acknowledge uncertainties openly. Update regularly as facts change.", ACCENT_TEAL, LIGHT_BG),
("Be Prepared", "Designate a trained spokesperson. Prepare key messages and Q&A sheets.", ACCENT_ORG, HexColor("#FFF4E6")),
("Clear Communication", "Use plain language. Avoid jargon. Tailor messages to your audience.", ACCENT_ORG, HexColor("#FFF4E6")),
]
bw = (PW-60)/2 - 10; bh = 175
for i, (title, body, border, bg) in enumerate(pts):
col = i % 2; row = i // 2
bx = 30 + col*(bw+20); by = PH - 115 - row*(bh+14) - bh
self.rect(bx, by, bw, bh, bg, stroke=border, lw=1.5)
self.rect(bx, by+bh-6, bw, 6, border)
self.text(title, bx+14, by+bh-30, size=13, color=DARK_BLUE, bold=True)
self.wrapped_text(body, bx+14, by+bh-48, bw-28, size=11, color=MID_GRAY)
# ── SLIDE 4 – MEDIA STRATEGY ──────────────────────────
def slide_strategy(self):
self.rect(0, 0, PW, PH, DARK_BLUE)
self.rect(0, PH-4, PW, 4, ACCENT_ORG)
self.text("Media Response Strategy", 0, PH-55, size=28, color=WHITE,
bold=True, align="center", width=PW)
self.text("Topic a – Step by Step", 0, PH-85, size=13, color=ACCENT_TEAL,
align="center", width=PW)
steps = [
("01", "Before the\nInterview", "Brief the spokesperson\nPrepare Q&A sheets\nConfirm key statistics"),
("02", "During the\nInterview", "Stay on-message\nBridge back to key points\nAvoid speculation"),
("03", "After the\nInterview", "Monitor coverage\nCorrect errors promptly\nShare approved transcript"),
("04", "Crisis\nComms", "Activate rapid response team\nIssue holding statements\nEscalate to leadership"),
]
bw = (PW-60)/4 - 8; bh = 340
for i, (num, label, body) in enumerate(steps):
bx = 30 + i*(bw+10); by = PH - 115 - bh
self.rect(bx, by, bw, bh, MED_BLUE)
self.rect(bx, by+bh-50, bw, 50, ACCENT_TEAL)
self.text(num, bx, by+bh-32, size=22, color=DARK_BLUE, bold=True,
align="center", width=bw)
self.wrapped_text(label, bx+10, by+bh-62, bw-20, size=12, color=WHITE,
bold=True, align=TA_CENTER)
self.wrapped_text(body, bx+10, by+bh-120, bw-20, size=10.5,
color=LIGHT_GRAY, align=TA_LEFT)
# ── SLIDE 5 – TOPIC B ─────────────────────────────────
def slide_topic_b(self):
self.rect(0, 0, PW, PH, WHITE)
self.rect(0, PH-4, PW, 4, ACCENT_ORG)
self.rect(0, 0, 8, PH, ACCENT_ORG)
self.text("Topic b", 28, PH-28, size=11, color=ACCENT_ORG, bold=True)
self.text("Use and Misuse of Social Media", 28, PH-56, size=24, color=DARK_BLUE, bold=True)
self.text("for Health Related Messages", 28, PH-80, size=17, color=MED_BLUE)
col_w = (PW - 70) / 2
# USE header
self.rect(30, PH-118, col_w, 34, ACCENT_TEAL)
self.text("BENEFICIAL USE", 30, PH-102, size=13, color=WHITE, bold=True,
align="center", width=col_w)
use_pts = [
"Rapid dissemination of accurate health alerts",
"Real-time public communication by authorities",
"Monitoring public sentiment and questions",
"Community engagement and behavior change",
"Sharing updates: vaccination drives, outbreaks",
]
for i, pt in enumerate(use_pts):
bg = LIGHT_BG if i % 2 == 0 else WHITE
self.rect(30, PH-168-i*46, col_w, 42, bg, stroke=HexColor("#CCDDEE"), lw=0.5)
self.text("• " + pt, 44, PH-148-i*46, size=11, color=DARK_TEXT)
# MISUSE header
mx = 40 + col_w
self.rect(mx, PH-118, col_w, 34, ACCENT_ORG)
self.text("MISUSE & RISKS", mx, PH-102, size=13, color=WHITE, bold=True,
align="center", width=col_w)
mis_pts = [
"Spread of misinformation and conspiracy theories",
"Amplification of fear and panic in communities",
"Unverified cures and remedies circulating widely",
"Stigmatization of communities or individuals",
"Overwhelming official channels with false reports",
]
for i, pt in enumerate(mis_pts):
bg = HexColor("#FFF4E6") if i % 2 == 0 else WHITE
self.rect(mx, PH-168-i*46, col_w, 42, bg, stroke=HexColor("#EECC99"), lw=0.5)
self.text("• " + pt, mx+14, PH-148-i*46, size=11, color=DARK_TEXT)
# ── SLIDE 6 – INFODEMIC ───────────────────────────────
def slide_infodemic(self):
self.rect(0, 0, PW, PH, HexColor("#F8F9FA"))
self.rect(0, PH-70, PW, 70, MED_BLUE)
self.text("The Infodemic Challenge", 28, PH-46, size=26, color=WHITE, bold=True)
self.text("Managing misinformation during a pandemic", 28, PH-64, size=13, color=LIGHT_GRAY)
# WHO quote box
self.rect(28, PH-155, PW-56, 72, MED_BLUE, stroke=ACCENT_TEAL, lw=2)
quote = ('"An infodemic is an overabundance of information — both accurate and inaccurate — '
'that spreads alongside an epidemic, making it hard for people to find trustworthy guidance." — WHO')
self.wrapped_text(quote, 40, PH-86, PW-80, size=11, color=WHITE, align=TA_LEFT)
strategies = [
("1", "Verify Before Sharing",
"Cross-check with WHO, CDC, and official health authority sources before posting any health info.", ACCENT_TEAL),
("2", "Platform Collaboration",
"Work with social media platforms to flag, remove, or label health misinformation rapidly.", ACCENT_TEAL),
("3", "Prebunking",
"Proactively educate the public on common myths and manipulation tactics before misinformation spreads.", ACCENT_ORG),
("4", "Engage Trusted Voices",
"Amplify messages from trusted community figures, healthcare workers, and local leaders.", ACCENT_ORG),
]
bw = (PW-60)/2 - 10; bh = 130
for i, (num, title, desc, col) in enumerate(strategies):
cx = 30 + (i%2)*(bw+20); cy = PH - 175 - (i//2)*(bh+12) - bh
self.rect(cx, cy, bw, bh, WHITE, stroke=col, lw=1.5)
self.rect(cx, cy, 32, bh, col)
self.text(num, cx, cy+bh/2-8, size=16, color=WHITE, bold=True,
align="center", width=32)
self.text(title, cx+42, cy+bh-28, size=12, color=DARK_BLUE, bold=True)
self.wrapped_text(desc, cx+42, cy+bh-46, bw-52, size=10, color=MID_GRAY)
# ── SLIDE 7 – KEY PRINCIPLES ─────────────────────────
def slide_principles(self):
self.rect(0, 0, PW, PH, DARK_BLUE)
self.rect(0, PH-4, PW, 4, ACCENT_TEAL)
self.rect(0, 0, PW, 4, ACCENT_ORG)
self.text("Key Principles", 0, PH-52, size=30, color=WHITE, bold=True,
align="center", width=PW)
self.text("Information Management during Pandemics", 0, PH-78, size=14,
color=ACCENT_TEAL, align="center", width=PW)
principles = [
("Accuracy", "Share only verified information from authoritative sources"),
("Timeliness", "Communicate early and update regularly as the situation evolves"),
("Transparency", "Be open about what is known, unknown and uncertain"),
("Reach", "Use multiple channels to reach all segments of population"),
("Clarity", "Use simple, plain language free of technical jargon"),
("Trust", "Build and maintain public trust through consistent messaging"),
]
cols = 3; bw = (PW-60)/cols - 10; bh = 155
for i, (title, desc) in enumerate(principles):
col = i % cols; row = i // cols
bx = 30 + col*(bw+15); by = PH - 105 - row*(bh+12) - bh
border_col = ACCENT_TEAL if i % 2 == 0 else ACCENT_ORG
self.rect(bx, by, bw, bh, MED_BLUE)
self.rect(bx, by+bh-6, bw, 6, border_col)
self.text(title, bx, by+bh-32, size=14, color=WHITE, bold=True,
align="center", width=bw)
self.wrapped_text(desc, bx+10, by+bh-52, bw-20, size=10.5,
color=LIGHT_GRAY, align=TA_CENTER)
# ── SLIDE 8 – SUMMARY ────────────────────────────────
def slide_summary(self):
self.rect(0, 0, PW, PH, MED_BLUE)
self.rect(0, PH-4, PW, 4, ACCENT_TEAL)
self.rect(0, 0, PW, 4, ACCENT_ORG)
self.text("Module Summary", 0, PH-52, size=30, color=WHITE, bold=True,
align="center", width=PW)
summary = [
"Module 4.4 covers Information Management during Pandemics — 2 hours, interactive discussion",
"Topic a: Responding to media requires preparation, accuracy, transparency and clear messaging",
"Topic b: Social media can amplify both accurate health messages and dangerous misinformation",
"The 'infodemic' is a parallel public health crisis that must be actively managed",
"Health professionals must lead with trusted, verified, timely and clear communication",
]
for i, s in enumerate(summary):
bg = HexColor("#1E4578") if i % 2 == 0 else HexColor("#163567")
self.rect(30, PH - 105 - i*72, PW-60, 64, bg, stroke=ACCENT_TEAL, lw=0.8)
self.wrapped_text("• " + s, 50, PH-108-i*72+56, PW-100, size=12, color=WHITE)
self.text("GEN MED / PUL MED / ANAES", 0, 18, size=10,
color=LIGHT_GRAY, align="center", width=PW)
def build(self):
self.slide_title(); self.next_page()
self.slide_overview(); self.next_page()
self.slide_topic_a(); self.next_page()
self.slide_strategy(); self.next_page()
self.slide_topic_b(); self.next_page()
self.slide_infodemic(); self.next_page()
self.slide_principles(); self.next_page()
self.slide_summary()
self.save()
print(f"PDF created: {self.path}")
PandemicPDF(OUT).build()
cd /home/daytona/workspace/pandemic-module && python make_pdf.py 2>&1
ls -lh /home/daytona/workspace/pandemic-module/Pandemic_Module_4_4.pdf
Pandemic Module 4 4
PDF Document · PDF