attachment
attachment

10yr boy with gradual increase breathlessness and intermediate fever with x ray chest , what is different diagnosis

analyse_media
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Searching PubMed

right upper lobe consolidation child differential diagnosis breathlessness fever

Reading File
Finding Sources
Finding Sources
Now I have enough information to provide a thorough answer. Here is the complete clinical analysis:

Chest X-Ray Findings

X-Ray Interpretation:
  • Large, dense, homogeneous right upper and middle zone opacity/consolidation with a relatively well-demarcated lower border (at the minor/horizontal fissure level)
  • Trachea is midline - no mediastinal shift
  • Left lung is clear and well-aerated
  • No pleural effusion (both costophrenic angles are sharp)
  • Heart size appears normal
  • Right heart border is partially obscured (positive silhouette sign - middle lobe/anterior segment involvement)
The pattern is: Right upper lobe + right middle lobe consolidation in a 10-year-old with gradual breathlessness and intermittent fever.

Differential Diagnoses (Most to Least Likely)

1. Pulmonary Tuberculosis (Primary TB) - TOP DIAGNOSIS

  • Most likely in a child from a high-burden country with gradual onset breathlessness and intermittent (not spiking) fever
  • Primary TB in children commonly affects the right upper lobe
  • The gradual course strongly favors TB over acute bacterial pneumonia
  • Look for: night sweats, weight loss, anorexia, contact history with TB patient
  • Workup: Mantoux test (TST), IGRA (Quantiferon), sputum AFB / gastric lavage, CBNAAT/GeneXpert

2. Bacterial Lobar Pneumonia (CAP)

  • Streptococcus pneumoniae is the most common cause of lobar consolidation in this age group
  • Typically presents with acute high fever, productive cough, pleuritic chest pain - the gradual onset here makes this less typical but still possible
  • Other organisms: Staphylococcus aureus (can cause necrotizing pneumonia), Klebsiella, Haemophilus influenzae
  • Treatment: Amoxicillin/Ampicillin as first line for school-age CAP

3. Atypical Pneumonia (Mycoplasma pneumoniae)

  • The #1 cause of "walking pneumonia" in school-age children (5-15 years)
  • Gradual onset, low-grade/intermittent fever, dry cough - fits this clinical picture well
  • X-ray can show patchy or lobar consolidation, sometimes disproportionately worse than clinical symptoms
  • Workup: Mycoplasma IgM serology, cold agglutinins
  • Treatment: Azithromycin or clarithromycin

4. Lung Abscess / Necrotizing Pneumonia

  • Can follow bacterial pneumonia (especially Staph aureus)
  • Gradual course with persistent fever
  • X-ray may show a cavity within the opacity (not obvious here, but early stage possible)
  • Look for: swinging fever, foul-smelling sputum

5. Post-obstructive Pneumonia (Endobronchial lesion)

  • A foreign body or endobronchial tumor can cause persistent lobar collapse/consolidation with secondary pneumonia
  • The well-defined, persistent right upper lobe opacity warrants bronchoscopy if antibiotics fail
  • Consider: carcinoid tumor, endobronchial TB

6. Mediastinal/Hilar Lymphadenopathy with Compression

  • In TB or lymphoma, enlarged hilar/paratracheal nodes can compress the right upper lobe bronchus causing collapse + consolidation
  • Hodgkin's lymphoma in a 10-year-old can present with painless mediastinal adenopathy, intermittent fever ("Pel-Ebstein fever"), and breathlessness
  • The lack of visible mediastinal widening makes this less likely but a CT chest would clarify

7. Pleural Effusion with Compressive Atelectasis

  • No costophrenic blunting is visible here, so less likely

8. Congenital Lung Malformation (CCAM/CPAM or Congenital Lobar Overinflation)

  • Less likely given intermittent fever, but congenital cystic adenomatoid malformation can present in childhood with recurrent infections in the same lobe

Recommended Investigations

InvestigationPurpose
CBC with differentialLeukocytosis (bacterial), lymphocytosis (viral/TB)
CRP / ESRInflammatory marker
Mantoux / TST + IGRATB screen
Sputum AFB / gastric lavageTB confirmation
GeneXpert MTB/RIFRapid TB diagnosis
Mycoplasma IgM serologyAtypical pneumonia
Blood culture (aerobic)Bacteremia
CT ChestDefines extent, cavitation, lymphadenopathy, foreign body
BronchoscopyIf no response to antibiotics

Key Clinical Points

  • The gradual onset + intermittent (not high-grade continuous) fever in a 10-year-old in a developing country setting makes primary TB the leading diagnosis until proved otherwise
  • Absence of mediastinal shift means the opacity is consolidation (not collapse pulling, not effusion/mass pushing)
  • A CT chest is the most important next step to differentiate consolidation from cavitation/lymph nodes/mass
  • Initiate anti-TB workup and empirical management per local guidelines while awaiting results
Source: Community-Acquired Pneumonia in Children - Swanson's Family Medicine Review, p. 584

Search for clinical images of TB and pneumonia consolidation patterns in children

Searching the Web

pediatric pulmonary tuberculosis chest xray consolidation clinical images children

Searching the Web

lobar pneumonia chest xray children right upper lobe consolidation clinical images

Finding Sources
Reading Web Page

https://pmc.ncbi.nlm.nih.gov/articles/PMC8878790

Finding Sources
Loading Image
Loading Image
Loading Image
Loading Image
Loading Image
Loading Image
Loading Image
Loading Image
Here is a comprehensive illustrated guide to the TB vs. Pneumonia consolidation patterns in children, with clinical X-ray images:

Pediatric Chest X-Ray: TB vs. Pneumonia - Illustrated Clinical Comparison


🫁 Pattern 1: Bacterial Lobar Pneumonia (CAP)

Key radiological hallmarks:
  • Dense, homogeneous lobar or segmental consolidation
  • Air bronchograms present (bronchi remain air-filled within solid opacification)
  • No volume loss - fissures and mediastinum stay in normal position
  • Unilateral, often lower or middle lobe (but can be upper lobe as in your case)
  • May have associated small pleural effusion

Fig. 50.1 - Bacterial Pneumonia (Right Upper Lobe Consolidation)

Bacterial Pneumonia - RUL consolidation, frontal and lateral views
A (frontal): Dense right upper lobe alveolar consolidation. Fissures are not displaced - no volume loss, consistent with acute bacterial infection. B (lateral): Confirms the posterior upper lobe location.
  • Source: Pediatric Chest, Radiology Key

🦠 Pattern 2: Primary Pulmonary Tuberculosis (Children)

Key radiological hallmarks unique to pediatric TB:
  • Hilar/mediastinal lymphadenopathy - the most characteristic feature (often asymmetric)
  • Consolidation + hilar fullness = classic "primary complex"
  • Right upper lobe or right middle lobe most commonly affected
  • Consolidation is often less dense and more persistent than bacterial pneumonia
  • No cavitation in most children under 10 (unlike adults)
  • Tracheal compression or deviation if nodes are very enlarged
  • Lymph nodes may persist even after consolidation resolves

Fig. 50.2 - Primary TB: Consolidation + Hilar Lymphadenopathy

Primary TB with consolidation and hilar lymphadenopathy - before and after 2 weeks
A (initial): Right-sided consolidation with prominent right hilar fullness (lymphadenopathy). B (2 weeks post-treatment): Consolidation has resolved but right hilar lymphadenopathy persists (arrows) - this persistence is characteristic of TB and not bacterial pneumonia.
  • Source: Pediatric Chest, Radiology Key

πŸ” Pattern 3: Atelectasis vs. Consolidation - Key Distinction

Atelectasis can mimic consolidation but shows volume loss (shift of fissures/mediastinum toward the collapsed lobe). This matters because:
  • Atelectasis with mediastinal shift toward the lesion = collapse (foreign body, mucus plug, endobronchial TB nodes compressing bronchus)
  • Consolidation with no shift = active inflammatory filling of alveoli

Fig. 50.3 - Atelectasis with Mediastinal Shift (contrast to your case)

Atelectasis - flattened linear opacity with volume loss
Note the flattened, more linear opacity and subtle fissure displacement - distinguishing features from consolidation. In your patient's X-ray, the trachea was midline, confirming consolidation rather than significant atelectasis.
  • Source: Pediatric Chest, Radiology Key

🌫️ Pattern 4: Miliary TB (Diffuse Bilateral Micronodules)

A severe form of disseminated TB - seen in young/immunocompromised children.
Miliary TB in a child - bilateral diffuse micronodular pattern
Bilateral innumerable 1-3mm nodules scattered uniformly throughout both lung fields. This pattern is NOT seen in your patient - shown here for comparison only.
  • Source: Pediatric Chest, Radiology Key

πŸ’§ Pattern 5: Pneumonia with Pleural Effusion

Empyema / parapneumonic effusion - can occur with bacterial pneumonia (especially Staph. aureus, Strep. pneumoniae).
Pneumonia with pleural effusion - chest xray and CT
A (initial CXR): Opacification with effusion. B (after drainage): Underlying consolidation visible. C (CT): Shows fluid loculation - CT is superior for characterizing effusions and guiding drainage.
  • Source: Pediatric Chest, Radiology Key

πŸ”΄ Pattern 6: Bronchopneumonia (Patchy / Multifocal)

Gram-negative or Staph aureus etiology - patchy, bilateral, multifocal consolidation - not the pattern in your patient.
Bronchopneumonia - patchy bilateral consolidation in child
Bilateral patchy infiltrates, peribronchial thickening. Different from the lobar pattern in your patient.
  • Source: Pediatric Chest, Radiology Key

πŸ”¬ Pattern 7: TB with Cavitation (Older Children / Progressive Disease)

Cavitation in pediatric TB is uncommon under age 10, more seen in adolescents.
TB with cavitation and satellite nodules in adolescent
A (CXR): Right-sided opacity with arrowheads pointing to a cavity wall. B/C (lateral + zoomed): Air-fluid level within the cavity (arrow) - indicates caseous necrosis and liquefaction. This pattern is rare in 10-year-olds but possible in adolescents or immunocompromised children.
  • Source: Pediatric Chest, Radiology Key

🩻 Comparison Table: TB vs. Bacterial Pneumonia on CXR in Children

FeaturePrimary TBBacterial Pneumonia (CAP)
OnsetGradual (weeks-months)Acute (days)
Fever patternLow-grade, intermittentHigh-grade, continuous
Consolidation locationRUL/RML most commonAny lobe; RLL common
Hilar lymphadenopathyYES - characteristicRare
Volume lossNo (usually)No
CavitationRare in <10 yrsRare (Staph)
Pleural effusionUncommonMore common (Staph, Strep)
Air bronchogramCan be presentOften present
Response to antibioticsNo improvementImproves in 48-72h
Mantoux/TSTPositive (>10mm)Negative
Constitutional symptomsWeight loss, night sweatsCough, pleuritic pain

Clinical Bottom Line for Your 10-Year-Old Patient

Given:
  • Gradual breathlessness (weeks/months, not days)
  • Intermittent (not high-grade spiking) fever
  • Right upper lobe consolidation (classic TB lobe in children)
  • No mediastinal shift (true consolidation, not collapse)
The X-ray pattern + clinical picture strongly favors primary pulmonary TB as the leading diagnosis. The key next step is a CT chest to look for hilar lymphadenopathy (often not visible on plain X-ray), followed by Mantoux test, GeneXpert sputum/gastric lavage, and contact tracing for TB exposure.

Create a diagnostic flowchart (PDF) for pediatric right upper lobe consolidation

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not found"

Running Command

mkdir -p /home/daytona/workspace/rul-flowchart && python3 -c "import reportlab; …

Writing File

~/rul-flowchart/create_flowchart.py

"""
Diagnostic Flowchart: Pediatric Right Upper Lobe Consolidation
Uses ReportLab to draw a professional A3-landscape PDF flowchart
"""

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A3, landscape
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import Paragraph
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

OUTPUT = "/home/daytona/workspace/rul-flowchart/Pediatric_RUL_Consolidation_Flowchart.pdf"

PAGE_W, PAGE_H = landscape(A3)

# ── colour palette ──────────────────────────────────────────────────────────
C_TITLE_BG   = colors.HexColor("#1a3a5c")   # deep navy
C_TITLE_FG   = colors.white
C_START      = colors.HexColor("#2c7bb6")   # blue  – entry node
C_DIAMOND    = colors.HexColor("#f7c948")   # amber – decision
C_DIAMOND_TXT= colors.HexColor("#1a1a1a")
C_TB         = colors.HexColor("#d73027")   # red   – TB box
C_BACT       = colors.HexColor("#1a9641")   # green – bacterial pneumonia
C_ATYPICAL   = colors.HexColor("#756bb1")   # purple – atypical / Mycoplasma
C_OTHER      = colors.HexColor("#f46d43")   # orange – other / rare
C_WORKUP_BG  = colors.HexColor("#e8f4fd")   # pale blue – workup boxes
C_WORKUP_BR  = colors.HexColor("#2c7bb6")
C_TX_BG      = colors.HexColor("#f0fff0")   # pale green – treatment
C_TX_BR      = colors.HexColor("#1a9641")
C_ARROW      = colors.HexColor("#333333")
C_FOOTER     = colors.HexColor("#666666")
C_SHADOW     = colors.HexColor("#cccccc")

def draw_rounded_rect(c, x, y, w, h, r=4*mm, fill_color=colors.white,
                      stroke_color=colors.black, lw=1, shadow=False):
    if shadow:
        c.setFillColor(C_SHADOW)
        c.setStrokeColor(C_SHADOW)
        c.roundRect(x+1.5*mm, y-1.5*mm, w, h, r, stroke=0, fill=1)
    c.setFillColor(fill_color)
    c.setStrokeColor(stroke_color)
    c.setLineWidth(lw)
    c.roundRect(x, y, w, h, r, stroke=1, fill=1)

def draw_diamond(c, cx, cy, half_w, half_h,
                 fill_color=C_DIAMOND, stroke_color=colors.black, lw=1.5):
    path = c.beginPath()
    path.moveTo(cx, cy + half_h)
    path.lineTo(cx + half_w, cy)
    path.lineTo(cx, cy - half_h)
    path.lineTo(cx - half_w, cy)
    path.close()
    c.setFillColor(fill_color)
    c.setStrokeColor(stroke_color)
    c.setLineWidth(lw)
    c.drawPath(path, stroke=1, fill=1)

def centred_text(c, x, y, w, h, text, font="Helvetica-Bold", size=8,
                 color=colors.black, line_height=None):
    """Draw multi-line centred text inside a box (x,y = bottom-left)."""
    if line_height is None:
        line_height = size * 1.35
    lines = text.split("\n")
    total_h = len(lines) * line_height
    start_y = y + h/2 + total_h/2 - line_height
    c.setFont(font, size)
    c.setFillColor(color)
    for line in lines:
        c.drawCentredString(x + w/2, start_y, line)
        start_y -= line_height

def arrow(c, x1, y1, x2, y2, label="", label_side="right",
          color=C_ARROW, lw=1.5, head=4*mm):
    c.setStrokeColor(color)
    c.setFillColor(color)
    c.setLineWidth(lw)
    c.line(x1, y1, x2, y2)
    # arrowhead (simple triangle pointing toward x2,y2)
    import math
    angle = math.atan2(y2 - y1, x2 - x1)
    ax1 = x2 - head * math.cos(angle - 0.4)
    ay1 = y2 - head * math.sin(angle - 0.4)
    ax2 = x2 - head * math.cos(angle + 0.4)
    ay2 = y2 - head * math.sin(angle + 0.4)
    path = c.beginPath()
    path.moveTo(x2, y2)
    path.lineTo(ax1, ay1)
    path.lineTo(ax2, ay2)
    path.close()
    c.drawPath(path, stroke=0, fill=1)
    if label:
        mx, my = (x1+x2)/2, (y1+y2)/2
        c.setFont("Helvetica-Bold", 7)
        c.setFillColor(color)
        off = 4*mm
        if label_side == "right":
            c.drawString(mx + off, my, label)
        elif label_side == "left":
            c.drawRightString(mx - off, my, label)
        else:
            c.drawCentredString(mx, my + off, label)


def build_pdf():
    c = canvas.Canvas(OUTPUT, pagesize=landscape(A3))
    c.setTitle("Diagnostic Flowchart – Pediatric RUL Consolidation")

    W, H = PAGE_W, PAGE_H

    # ═══════════════════════════════════════════
    # TITLE BAR
    # ═══════════════════════════════════════════
    c.setFillColor(C_TITLE_BG)
    c.rect(0, H - 22*mm, W, 22*mm, stroke=0, fill=1)
    c.setFont("Helvetica-Bold", 16)
    c.setFillColor(C_TITLE_FG)
    c.drawCentredString(W/2, H - 14*mm,
        "DIAGNOSTIC FLOWCHART: Pediatric Right Upper Lobe Consolidation")
    c.setFont("Helvetica", 9)
    c.drawCentredString(W/2, H - 19*mm,
        "10-Year-Old Child  |  Gradual Breathlessness + Intermittent Fever")

    # ═══════════════════════════════════════════
    # LEGEND (top-right)
    # ═══════════════════════════════════════════
    legend_items = [
        (C_START,   "Entry / Step"),
        (C_DIAMOND, "Decision"),
        (C_TB,      "TB Pathway"),
        (C_BACT,    "Bacterial Pneumonia"),
        (C_ATYPICAL,"Atypical / Mycoplasma"),
        (C_OTHER,   "Other / Rare"),
    ]
    lx = W - 58*mm
    ly = H - 26*mm
    c.setFont("Helvetica-Bold", 7.5)
    c.setFillColor(C_TITLE_BG)
    c.drawString(lx, ly, "LEGEND")
    ly -= 4*mm
    for col, label in legend_items:
        c.setFillColor(col)
        c.rect(lx, ly - 2.5*mm, 8*mm, 4*mm, stroke=0, fill=1)
        c.setFillColor(colors.black)
        c.setFont("Helvetica", 7)
        c.drawString(lx + 10*mm, ly, label)
        ly -= 5*mm

    # ═══════════════════════════════════════════
    # LAYOUT CONSTANTS
    # ═══════════════════════════════════════════
    # We'll place nodes on a 5-column layout
    # Columns (centre x):
    col = [W*0.1, W*0.28, W*0.50, W*0.72, W*0.90]
    # Box dimensions
    BW, BH = 44*mm, 14*mm   # standard box
    DW, DH = 28*mm, 12*mm   # diamond half-widths

    top_y = H - 32*mm       # top of first node (top-left corner)

    # ── helper to get box centre ──
    def bc(x, y, w=BW, h=BH):
        return x + w/2, y + h/2

    # ══════════════════════════════════════════════════════════
    # ROW 1 – Entry node (centred)
    # ══════════════════════════════════════════════════════════
    r1_y = top_y - BH
    r1_x = W/2 - BW/2

    draw_rounded_rect(c, r1_x, r1_y, BW, BH,
                      fill_color=C_START, stroke_color=C_START, lw=1.5, shadow=True)
    centred_text(c, r1_x, r1_y, BW, BH,
                 "CHILD WITH RUL CONSOLIDATION\n(+ Gradual Breathlessness + Intermittent Fever)",
                 font="Helvetica-Bold", size=8, color=colors.white)

    # ══════════════════════════════════════════════════════════
    # ROW 2 – Initial Workup box
    # ══════════════════════════════════════════════════════════
    r2_y = r1_y - 22*mm
    r2_x = W/2 - BW/2 - 10*mm
    r2_w = BW + 20*mm

    arrow(c, W/2, r1_y, W/2, r2_y + BH + 0.5*mm)

    draw_rounded_rect(c, r2_x, r2_y, r2_w, BH,
                      fill_color=C_WORKUP_BG, stroke_color=C_WORKUP_BR, lw=1.5, shadow=True)
    centred_text(c, r2_x, r2_y, r2_w, BH,
                 "INITIAL ASSESSMENT: History + Exam + CXR Review\n"
                 "CBC | CRP/ESR | Blood Culture | Oβ‚‚ Saturation | Mantoux/TST",
                 font="Helvetica", size=7.5, color=C_TITLE_BG)

    # ══════════════════════════════════════════════════════════
    # ROW 3 – Decision Diamond: Acute or Gradual onset?
    # ══════════════════════════════════════════════════════════
    d1_cx = W/2
    d1_cy = r2_y - 22*mm

    arrow(c, W/2, r2_y, W/2, d1_cy + DH + 0.5*mm)

    draw_diamond(c, d1_cx, d1_cy, DW + 8*mm, DH + 2*mm,
                 fill_color=C_DIAMOND, stroke_color=colors.HexColor("#c9a800"), lw=2)
    centred_text(c, d1_cx - DW - 8*mm, d1_cy - DH - 2*mm,
                 (DW+8*mm)*2, (DH+2*mm)*2,
                 "Onset:\nAcute (<3 days)\nor Gradual (>1 wk)?",
                 font="Helvetica-Bold", size=8, color=C_DIAMOND_TXT)

    # ══════════════════════════════════════════════════════════
    # ROW 4 – Two branches: LEFT = Acute, RIGHT = Gradual
    # ══════════════════════════════════════════════════════════
    r4_y = d1_cy - 32*mm

    # -- LEFT: Acute branch --
    acute_x = col[1] - BW/2
    arrow(c, d1_cx - DW - 8*mm, d1_cy,
          acute_x + BW/2, r4_y + BH + 0.5*mm,
          label="ACUTE", label_side="left")

    draw_rounded_rect(c, acute_x, r4_y, BW, BH,
                      fill_color=C_BACT, stroke_color=C_BACT, lw=1.5, shadow=True)
    centred_text(c, acute_x, r4_y, BW, BH,
                 "BACTERIAL PNEUMONIA\n(CAP) Most Likely",
                 font="Helvetica-Bold", size=8, color=colors.white)

    # -- RIGHT: Gradual branch --
    grad_x = col[3] - BW/2
    arrow(c, d1_cx + DW + 8*mm, d1_cy,
          grad_x + BW/2, r4_y + BH + 0.5*mm,
          label="GRADUAL", label_side="right")

    draw_rounded_rect(c, grad_x, r4_y, BW, BH,
                      fill_color=C_TB, stroke_color=C_TB, lw=1.5, shadow=True)
    centred_text(c, grad_x, r4_y, BW, BH,
                 "SUSPECT TB / ATYPICAL\nPNEUMONIA",
                 font="Helvetica-Bold", size=8, color=colors.white)

    # ══════════════════════════════════════════════════════════
    # ROW 5 – Sub-decisions under each branch
    # ══════════════════════════════════════════════════════════
    r5_y = r4_y - 28*mm

    # LEFT BRANCH: Decision – High fever + toxic?
    d2_cx = col[1]
    d2_cy = r5_y + DH

    arrow(c, acute_x + BW/2, r4_y, d2_cx, d2_cy + DH + 0.5*mm)

    draw_diamond(c, d2_cx, d2_cy, DW + 2*mm, DH,
                 fill_color=C_DIAMOND, stroke_color=colors.HexColor("#c9a800"), lw=1.5)
    centred_text(c, d2_cx - DW - 2*mm, d2_cy - DH,
                 (DW+2*mm)*2, DH*2,
                 "High fever\n+ Lobar?\nToxic child?",
                 font="Helvetica-Bold", size=7.5, color=C_DIAMOND_TXT)

    # RIGHT BRANCH: Decision – Mantoux +ve / hilar LN?
    d3_cx = col[3]
    d3_cy = r5_y + DH

    arrow(c, grad_x + BW/2, r4_y, d3_cx, d3_cy + DH + 0.5*mm)

    draw_diamond(c, d3_cx, d3_cy, DW + 2*mm, DH,
                 fill_color=C_DIAMOND, stroke_color=colors.HexColor("#c9a800"), lw=1.5)
    centred_text(c, d3_cx - DW - 2*mm, d3_cy - DH,
                 (DW+2*mm)*2, DH*2,
                 "Mantoux +ve\nOR Hilar LN\non CT?",
                 font="Helvetica-Bold", size=7.5, color=C_DIAMOND_TXT)

    # ══════════════════════════════════════════════════════════
    # ROW 6 – Four diagnosis boxes
    # ══════════════════════════════════════════════════════════
    r6_y = r5_y - 26*mm
    box_w = 40*mm
    box_h = 16*mm

    # Strep pneumoniae (YES from left diamond)
    strep_x = col[0] - box_w/2
    arrow(c, d2_cx - DW - 2*mm, d2_cy,
          strep_x + box_w/2, r6_y + box_h + 0.5*mm,
          label="YES", label_side="left")
    draw_rounded_rect(c, strep_x, r6_y, box_w, box_h,
                      fill_color=C_BACT, stroke_color=C_BACT, lw=1.5, shadow=True)
    centred_text(c, strep_x, r6_y, box_w, box_h,
                 "LOBAR PNEUMONIA\nStrep. pneumoniae\nor H. influenzae",
                 font="Helvetica-Bold", size=7.5, color=colors.white)

    # Mycoplasma (NO from left diamond)
    myco_x = col[2] - box_w/2 - 4*mm
    arrow(c, d2_cx + DW + 2*mm, d2_cy,
          myco_x + box_w/2, r6_y + box_h + 0.5*mm,
          label="NO / Low grade", label_side="top")
    draw_rounded_rect(c, myco_x, r6_y, box_w, box_h,
                      fill_color=C_ATYPICAL, stroke_color=C_ATYPICAL, lw=1.5, shadow=True)
    centred_text(c, myco_x, r6_y, box_w, box_h,
                 "ATYPICAL PNEUMONIA\nMycoplasma pneumoniae\n(School-age #1)",
                 font="Helvetica-Bold", size=7.5, color=colors.white)

    # TB confirmed (YES from right diamond)
    tb_x = col[3] + 4*mm
    arrow(c, d3_cx + DW + 2*mm, d3_cy,
          tb_x + box_w/2, r6_y + box_h + 0.5*mm,
          label="YES", label_side="right")
    draw_rounded_rect(c, tb_x, r6_y, box_w, box_h,
                      fill_color=C_TB, stroke_color=C_TB, lw=1.5, shadow=True)
    centred_text(c, tb_x, r6_y, box_w, box_h,
                 "PRIMARY TB\nM. tuberculosis\n(GeneXpert / AFB)",
                 font="Helvetica-Bold", size=7.5, color=colors.white)

    # Other (NO from right diamond)
    other_x = col[4] - box_w/2
    arrow(c, d3_cx, d3_cy - DH,
          other_x + box_w/2, r6_y + box_h + 0.5*mm,
          label="NO", label_side="right")
    draw_rounded_rect(c, other_x, r6_y, box_w, box_h,
                      fill_color=C_OTHER, stroke_color=C_OTHER, lw=1.5, shadow=True)
    centred_text(c, other_x, r6_y, box_w, box_h,
                 "OTHER: Fungal\nPost-obstructive\nLymphoma / CCAM",
                 font="Helvetica-Bold", size=7.5, color=colors.white)

    # ══════════════════════════════════════════════════════════
    # ROW 7 – Investigations row
    # ══════════════════════════════════════════════════════════
    r7_y = r6_y - 26*mm
    inv_h = 22*mm

    # Strep workup
    inv1_x = col[0] - box_w/2
    arrow(c, strep_x + box_w/2, r6_y, inv1_x + box_w/2, r7_y + inv_h)
    draw_rounded_rect(c, inv1_x, r7_y, box_w, inv_h,
                      fill_color=C_WORKUP_BG, stroke_color=C_WORKUP_BR, lw=1, shadow=False)
    centred_text(c, inv1_x, r7_y, box_w, inv_h,
                 "WORKUP:\nβ€’ Blood culture\nβ€’ Pneumococcal Ag\nβ€’ Procalcitonin",
                 font="Helvetica", size=7, color=C_TITLE_BG)

    # Mycoplasma workup
    inv2_x = myco_x
    arrow(c, myco_x + box_w/2, r6_y, inv2_x + box_w/2, r7_y + inv_h)
    draw_rounded_rect(c, inv2_x, r7_y, box_w, inv_h,
                      fill_color=C_WORKUP_BG, stroke_color=C_WORKUP_BR, lw=1, shadow=False)
    centred_text(c, inv2_x, r7_y, box_w, inv_h,
                 "WORKUP:\nβ€’ Mycoplasma IgM\nβ€’ Cold agglutinins\nβ€’ NPS PCR",
                 font="Helvetica", size=7, color=C_TITLE_BG)

    # TB workup
    inv3_x = tb_x
    arrow(c, tb_x + box_w/2, r6_y, inv3_x + box_w/2, r7_y + inv_h)
    draw_rounded_rect(c, inv3_x, r7_y, box_w, inv_h,
                      fill_color=colors.HexColor("#fff0f0"), stroke_color=C_TB, lw=1, shadow=False)
    centred_text(c, inv3_x, r7_y, box_w, inv_h,
                 "WORKUP:\nβ€’ GeneXpert MTB/RIF\nβ€’ Gastric lavage AFB\nβ€’ IGRA / CT Chest",
                 font="Helvetica", size=7, color=C_TITLE_BG)

    # Other workup
    inv4_x = other_x
    arrow(c, other_x + box_w/2, r6_y, inv4_x + box_w/2, r7_y + inv_h)
    draw_rounded_rect(c, inv4_x, r7_y, box_w, inv_h,
                      fill_color=C_WORKUP_BG, stroke_color=C_OTHER, lw=1, shadow=False)
    centred_text(c, inv4_x, r7_y, box_w, inv_h,
                 "WORKUP:\nβ€’ CT Chest\nβ€’ Bronchoscopy\nβ€’ Fungal serology",
                 font="Helvetica", size=7, color=C_TITLE_BG)

    # ══════════════════════════════════════════════════════════
    # ROW 8 – Treatment row
    # ══════════════════════════════════════════════════════════
    r8_y = r7_y - 26*mm
    tx_h = 22*mm

    # Strep treatment
    tx1_x = col[0] - box_w/2
    arrow(c, inv1_x + box_w/2, r7_y, tx1_x + box_w/2, r8_y + tx_h)
    draw_rounded_rect(c, tx1_x, r8_y, box_w, tx_h,
                      fill_color=C_TX_BG, stroke_color=C_TX_BR, lw=1.5, shadow=False)
    centred_text(c, tx1_x, r8_y, box_w, tx_h,
                 "TREAT:\nAmoxicillin/Ampicillin\nIV β†’ Oral 7-10 days\n(If MRSA: Vancomycin)",
                 font="Helvetica-Bold", size=7, color=colors.HexColor("#1a4a1a"))

    # Mycoplasma treatment
    tx2_x = myco_x
    arrow(c, inv2_x + box_w/2, r7_y, tx2_x + box_w/2, r8_y + tx_h)
    draw_rounded_rect(c, tx2_x, r8_y, box_w, tx_h,
                      fill_color=C_TX_BG, stroke_color=C_TX_BR, lw=1.5, shadow=False)
    centred_text(c, tx2_x, r8_y, box_w, tx_h,
                 "TREAT:\nAzithromycin 5 days\nor Clarithromycin\n10-14 days",
                 font="Helvetica-Bold", size=7, color=colors.HexColor("#1a4a1a"))

    # TB treatment
    tx3_x = tb_x
    arrow(c, inv3_x + box_w/2, r7_y, tx3_x + box_w/2, r8_y + tx_h)
    draw_rounded_rect(c, tx3_x, r8_y, box_w, tx_h,
                      fill_color=colors.HexColor("#fff5f5"), stroke_color=C_TB, lw=1.5, shadow=False)
    centred_text(c, tx3_x, r8_y, box_w, tx_h,
                 "TREAT:\n2HRZE + 4HR\nNotify + Contact Trace\nDOTS strategy",
                 font="Helvetica-Bold", size=7, color=colors.HexColor("#5a0000"))

    # Other treatment
    tx4_x = other_x
    arrow(c, inv4_x + box_w/2, r7_y, tx4_x + box_w/2, r8_y + tx_h)
    draw_rounded_rect(c, tx4_x, r8_y, box_w, tx_h,
                      fill_color=C_TX_BG, stroke_color=C_OTHER, lw=1.5, shadow=False)
    centred_text(c, tx4_x, r8_y, box_w, tx_h,
                 "TREAT:\nDisease-specific\nOncology / Surgery\nor Antifungal",
                 font="Helvetica-Bold", size=7, color=colors.HexColor("#1a4a1a"))

    # ══════════════════════════════════════════════════════════
    # ROW 9 – Response Check box (all paths β†’ centre)
    # ══════════════════════════════════════════════════════════
    r9_y = r8_y - 26*mm
    resp_w = 70*mm
    resp_h = 14*mm
    resp_x = W/2 - resp_w/2

    # Arrows from all 4 treatment boxes converge
    # Draw a horizontal connector line first
    connect_y = r8_y - 8*mm
    c.setStrokeColor(C_ARROW)
    c.setLineWidth(1.2)
    c.line(tx1_x + box_w/2, r8_y,  tx1_x + box_w/2, connect_y)
    c.line(tx2_x + box_w/2, r8_y,  tx2_x + box_w/2, connect_y)
    c.line(tx3_x + box_w/2, r8_y,  tx3_x + box_w/2, connect_y)
    c.line(tx4_x + box_w/2, r8_y,  tx4_x + box_w/2, connect_y)
    c.line(tx1_x + box_w/2, connect_y, tx4_x + box_w/2, connect_y)

    arrow(c, W/2, connect_y, W/2, r9_y + resp_h + 0.5*mm)

    draw_diamond(c, W/2, r9_y + resp_h/2, resp_w/2, resp_h/2,
                 fill_color=C_DIAMOND, stroke_color=colors.HexColor("#c9a800"), lw=2)
    centred_text(c, resp_x, r9_y, resp_w, resp_h,
                 "Clinical response\nin 48-72 hrs?",
                 font="Helvetica-Bold", size=8.5, color=C_DIAMOND_TXT)

    # YES β†’ Discharge
    yes_x = W/2 - resp_w/2 - 50*mm
    yes_y = r9_y
    yes_w = 40*mm
    yes_h = 14*mm
    arrow(c, resp_x, r9_y + resp_h/2,
          yes_x + yes_w, yes_y + yes_h/2,
          label="YES", label_side="top")
    draw_rounded_rect(c, yes_x, yes_y, yes_w, yes_h,
                      fill_color=C_BACT, stroke_color=C_BACT, lw=1.5, shadow=True)
    centred_text(c, yes_x, yes_y, yes_w, yes_h,
                 "CONTINUE Rx\nFollow-up CXR\n@ 4-6 weeks",
                 font="Helvetica-Bold", size=7.5, color=colors.white)

    # NO β†’ Reassess
    no_x = W/2 + resp_w/2 + 10*mm
    no_y = r9_y
    no_w = 48*mm
    no_h = 14*mm
    arrow(c, resp_x + resp_w, r9_y + resp_h/2,
          no_x, no_y + no_h/2,
          label="NO", label_side="top")
    draw_rounded_rect(c, no_x, no_y, no_w, no_h,
                      fill_color=C_TB, stroke_color=C_TB, lw=1.5, shadow=True)
    centred_text(c, no_x, no_y, no_w, no_h,
                 "REASSESS: CT Chest\nBronchoscopy / HRCT\nRe-culture & Biopsy",
                 font="Helvetica-Bold", size=7.5, color=colors.white)

    # ══════════════════════════════════════════════════════════
    # RED FLAG BOX (bottom-left)
    # ══════════════════════════════════════════════════════════
    rf_x = 6*mm
    rf_y = 6*mm
    rf_w = 80*mm
    rf_h = 32*mm

    c.setFillColor(colors.HexColor("#fff3cd"))
    c.setStrokeColor(colors.HexColor("#e65c00"))
    c.setLineWidth(1.5)
    c.roundRect(rf_x, rf_y, rf_w, rf_h, 3*mm, stroke=1, fill=1)

    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(colors.HexColor("#b30000"))
    c.drawString(rf_x + 3*mm, rf_y + rf_h - 7*mm, "⚠  RED FLAGS β†’ Urgent Referral")

    red_flags = [
        "β€’ Oβ‚‚ sat < 92%  |  Severe respiratory distress",
        "β€’ Mediastinal shift or tension",
        "β€’ Bilateral involvement / Miliary pattern",
        "β€’ Immunocompromised child (HIV, malignancy)",
        "β€’ No antibiotic response in 48-72 hrs",
    ]
    c.setFont("Helvetica", 7)
    c.setFillColor(colors.HexColor("#333333"))
    ry = rf_y + rf_h - 13*mm
    for flag in red_flags:
        c.drawString(rf_x + 3*mm, ry, flag)
        ry -= 4.5*mm

    # ══════════════════════════════════════════════════════════
    # KEY DIFFERENTIATORS BOX (bottom-right)
    # ══════════════════════════════════════════════════════════
    kd_x = W - 96*mm
    kd_y = 6*mm
    kd_w = 90*mm
    kd_h = 32*mm

    c.setFillColor(colors.HexColor("#eef6ff"))
    c.setStrokeColor(C_WORKUP_BR)
    c.setLineWidth(1.5)
    c.roundRect(kd_x, kd_y, kd_w, kd_h, 3*mm, stroke=1, fill=1)

    c.setFont("Helvetica-Bold", 8)
    c.setFillColor(C_TITLE_BG)
    c.drawString(kd_x + 3*mm, kd_y + kd_h - 7*mm, "TB vs PNEUMONIA – KEY DIFFERENTIATORS")

    rows = [
        ("Feature", "TB", "Pneumonia"),
        ("Onset", "Gradual (wks)", "Acute (days)"),
        ("Fever", "Low / Intermittent", "High / Continuous"),
        ("Mantoux", "Positive >10mm", "Negative"),
        ("Hilar LN", "YES (CT)", "Absent"),
        ("Abx response", "None", "Within 48-72 hrs"),
    ]
    c.setFont("Helvetica-Bold", 6.5)
    c.setFillColor(C_TITLE_BG)
    col_x = [kd_x + 3*mm, kd_x + 30*mm, kd_x + 62*mm]
    ry = kd_y + kd_h - 13*mm
    for i, (feat, tb_val, pn_val) in enumerate(rows):
        fnt = "Helvetica-Bold" if i == 0 else "Helvetica"
        c.setFont(fnt, 6.5)
        c.setFillColor(C_TITLE_BG if i == 0 else colors.black)
        c.drawString(col_x[0], ry, feat)
        c.setFillColor(C_TB if i > 0 else C_TITLE_BG)
        c.drawString(col_x[1], ry, tb_val)
        c.setFillColor(C_BACT if i > 0 else C_TITLE_BG)
        c.drawString(col_x[2], ry, pn_val)
        # divider
        if i < len(rows) - 1:
            c.setStrokeColor(colors.HexColor("#ccddee"))
            c.setLineWidth(0.5)
            c.line(kd_x + 2*mm, ry - 1*mm, kd_x + kd_w - 2*mm, ry - 1*mm)
        ry -= 4.2*mm

    # ══════════════════════════════════════════════════════════
    # FOOTER
    # ══════════════════════════════════════════════════════════
    c.setFillColor(C_TITLE_BG)
    c.rect(0, 0, W, 5*mm, stroke=0, fill=1)
    c.setFont("Helvetica", 6.5)
    c.setFillColor(colors.white)
    c.drawCentredString(W/2, 1.5*mm,
        "For clinical use only. Correlate with local epidemiology, immunisation history, HIV status, and microbiological results. "
        "Refer to institutional TB/CAP guidelines.  |  Generated: July 2026")

    c.save()
    print(f"PDF saved β†’ {OUTPUT}")


if __name__ == "__main__":
    build_pdf()
Running Command

cd /home/daytona/workspace/rul-flowchart && python3 create_flowchart.py 2>&1

Running Command

ls -lh /home/daytona/workspace/rul-flowchart/

The PDF was generated successfully (9.8 KB). Here is your download link:

Pediatric RUL Consolidation Flowchart

PDF Document Β· PDF


What's Inside the Flowchart

The PDF is A3 landscape format with a full colour-coded diagnostic algorithm covering:

Flow Structure (9 Rows)

  1. Entry node - Child with RUL consolidation + gradual breathlessness + intermittent fever
  2. Initial assessment - CBC, CRP/ESR, blood culture, Oβ‚‚ sat, Mantoux/TST
  3. Decision diamond - Acute onset (<3 days) vs. Gradual onset (>1 week)
  4. Branch split - Bacterial CAP pathway (left) vs. TB/Atypical pathway (right)
  5. Sub-decisions - High fever/toxic? (left) | Mantoux +ve / hilar LN on CT? (right)
  6. Four diagnosis boxes:
    • Lobar Pneumonia (Strep/H.flu) - green
    • Atypical Pneumonia / Mycoplasma - purple
    • Primary TB (M. tuberculosis) - red
    • Other: Fungal/Lymphoma/CCAM - orange
  7. Investigations specific to each diagnosis
  8. Treatment for each pathway
  9. Response check at 48-72 hrs β†’ Continue Rx OR Reassess with CT/Bronchoscopy

Supplementary Panels

  • Red Flag box - Oβ‚‚ sat <92%, mediastinal shift, bilateral/miliary, immunocompromise
  • TB vs Pneumonia comparison table - 5 key differentiators at a glance
  • Clinical disclaimer footer

Generate a case management protocol Word document for TB vs CAP

Reading File
Running Command

ls /home/daytona/skills/docx/scripts/office/ && node --version && npm list -g do…

Running Command

mkdir -p /home/daytona/workspace/tb-cap-protocol

Writing File

~/tb-cap-protocol/create_protocol.js

const {
  Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
  Header, Footer, AlignmentType, HeadingLevel, BorderStyle, WidthType,
  ShadingType, VerticalAlign, PageNumber, NumberFormat, TableBorders,
  convertInchesToTwip, UnderlineType, PageBreak
} = require('docx');
const fs = require('fs');

// ── Colour palette ──────────────────────────────────────────────────────────
const NAVY    = "1A3A5C";
const RED     = "C0392B";
const GREEN   = "1A7A41";
const PURPLE  = "6C3483";
const ORANGE  = "D35400";
const AMBER   = "B7950B";
const LGRAY   = "F2F3F4";
const MGRAY   = "D5D8DC";
const WHITE   = "FFFFFF";
const LRED    = "FDEDEC";
const LGREEN  = "EAFAF1";
const LPURP   = "F5EEF8";
const LBLUE   = "EBF5FB";
const AMBER_L = "FEF9E7";

// ── Helper: shaded cell ──────────────────────────────────────────────────────
function shadedCell(text, bgHex, fgHex = "000000", bold = false, colspan = 1, width = null) {
  const cellOpts = {
    shading: { fill: bgHex, type: ShadingType.CLEAR, color: "auto" },
    verticalAlign: VerticalAlign.CENTER,
    margins: { top: 80, bottom: 80, left: 120, right: 120 },
    children: [new Paragraph({
      alignment: AlignmentType.CENTER,
      children: [new TextRun({ text, bold, color: fgHex, size: 18 })]
    })]
  };
  if (width) cellOpts.width = { size: width, type: WidthType.DXA };
  if (colspan > 1) cellOpts.columnSpan = colspan;
  return new TableCell(cellOpts);
}

function plainCell(text, bgHex = WHITE, fgHex = "000000", bold = false, align = AlignmentType.LEFT) {
  return new TableCell({
    shading: { fill: bgHex, type: ShadingType.CLEAR, color: "auto" },
    verticalAlign: VerticalAlign.CENTER,
    margins: { top: 70, bottom: 70, left: 120, right: 120 },
    children: [new Paragraph({
      alignment: align,
      children: [new TextRun({ text, bold, color: fgHex, size: 18 })]
    })]
  });
}

// ── Helper: standard bordered table ─────────────────────────────────────────
const STD_BORDERS = {
  top:    { style: BorderStyle.SINGLE, size: 6, color: MGRAY },
  bottom: { style: BorderStyle.SINGLE, size: 6, color: MGRAY },
  left:   { style: BorderStyle.SINGLE, size: 6, color: MGRAY },
  right:  { style: BorderStyle.SINGLE, size: 6, color: MGRAY },
  insideHorizontal: { style: BorderStyle.SINGLE, size: 4, color: MGRAY },
  insideVertical:   { style: BorderStyle.SINGLE, size: 4, color: MGRAY },
};

// ── Helper: heading paragraph ────────────────────────────────────────────────
function h1(text) {
  return new Paragraph({
    heading: HeadingLevel.HEADING_1,
    spacing: { before: 300, after: 100 },
    children: [new TextRun({ text, bold: true, color: NAVY, size: 28, allCaps: true })]
  });
}
function h2(text) {
  return new Paragraph({
    heading: HeadingLevel.HEADING_2,
    spacing: { before: 240, after: 80 },
    children: [new TextRun({ text, bold: true, color: NAVY, size: 24 })]
  });
}
function h3(text) {
  return new Paragraph({
    heading: HeadingLevel.HEADING_3,
    spacing: { before: 180, after: 60 },
    children: [new TextRun({ text, bold: true, color: "444444", size: 22, italics: true })]
  });
}
function body(text, options = {}) {
  return new Paragraph({
    spacing: { before: 60, after: 60 },
    children: [new TextRun({ text, size: 20, color: "1A1A1A", ...options })]
  });
}
function bullet(text, level = 0) {
  return new Paragraph({
    bullet: { level },
    spacing: { before: 40, after: 40 },
    children: [new TextRun({ text, size: 19, color: "1A1A1A" })]
  });
}
function gap(n = 1) {
  return [...Array(n)].map(() => new Paragraph({ children: [new TextRun({ text: "" })] }));
}
function divider() {
  return new Paragraph({
    border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: MGRAY } },
    children: [new TextRun({ text: "" })],
    spacing: { before: 120, after: 120 }
  });
}
function noteBox(text, bgHex = AMBER_L, labelColor = AMBER) {
  return new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: {
      top:    { style: BorderStyle.THICK, size: 12, color: labelColor },
      bottom: { style: BorderStyle.SINGLE, size: 6, color: labelColor },
      left:   { style: BorderStyle.THICK, size: 12, color: labelColor },
      right:  { style: BorderStyle.SINGLE, size: 6, color: labelColor },
      insideHorizontal: { style: BorderStyle.NONE, size: 0, color: "FFFFFF" },
      insideVertical:   { style: BorderStyle.NONE, size: 0, color: "FFFFFF" },
    },
    rows: [
      new TableRow({
        children: [new TableCell({
          shading: { fill: bgHex, type: ShadingType.CLEAR, color: "auto" },
          margins: { top: 100, bottom: 100, left: 160, right: 160 },
          children: [new Paragraph({
            children: [new TextRun({ text, size: 18, color: "1A1A1A" })]
          })]
        })]
      })
    ]
  });
}

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 1 – Cover / Title
// ═══════════════════════════════════════════════════════════════════════════
const coverSection = [
  ...gap(2),
  new Paragraph({
    alignment: AlignmentType.CENTER,
    spacing: { before: 0, after: 80 },
    children: [new TextRun({ text: "CASE MANAGEMENT PROTOCOL", bold: true, size: 48, color: NAVY, allCaps: true })]
  }),
  new Paragraph({
    alignment: AlignmentType.CENTER,
    spacing: { before: 0, after: 200 },
    children: [new TextRun({ text: "Pediatric Right Upper Lobe Consolidation:", bold: true, size: 36, color: NAVY })]
  }),
  new Paragraph({
    alignment: AlignmentType.CENTER,
    spacing: { before: 0, after: 400 },
    children: [new TextRun({ text: "Tuberculosis vs. Community-Acquired Pneumonia", bold: true, size: 32, color: RED })]
  }),
  // meta table
  new Table({
    alignment: AlignmentType.CENTER,
    width: { size: 70, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        plainCell("Target Population", NAVY, WHITE, true, AlignmentType.CENTER),
        plainCell("Pediatric patients aged 5–15 years", LBLUE, "000000", false)
      ]}),
      new TableRow({ children: [
        plainCell("Setting", NAVY, WHITE, true, AlignmentType.CENTER),
        plainCell("Inpatient / Emergency / Outpatient Clinic", LBLUE)
      ]}),
      new TableRow({ children: [
        plainCell("Document Version", NAVY, WHITE, true, AlignmentType.CENTER),
        plainCell("1.0 β€” July 2026", LBLUE)
      ]}),
      new TableRow({ children: [
        plainCell("Classification", NAVY, WHITE, true, AlignmentType.CENTER),
        plainCell("Clinical Protocol β€” For Physician / Paediatric Team Use", LBLUE)
      ]}),
    ]
  }),
  ...gap(2),
  new Paragraph({
    alignment: AlignmentType.CENTER,
    children: [new TextRun({ text: "Prepared by: Orris Medical AI Assistant  |  Based on WHO, IAP & IDSA Guidelines", size: 18, color: "777777", italics: true })]
  }),
  new Paragraph({ children: [new PageBreak()] })
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 2 – Purpose & Scope
// ═══════════════════════════════════════════════════════════════════════════
const purposeSection = [
  h1("1. Purpose and Scope"),
  body("This protocol provides a structured clinical framework for the differentiation, investigation, and management of right upper lobe (RUL) pulmonary consolidation in a child presenting with gradual-onset breathlessness and intermittent fever. The two most clinically important and epidemiologically significant diagnoses are:"),
  ...gap(1),
  bullet("Primary Pulmonary Tuberculosis (TB) β€” M. tuberculosis infection"),
  bullet("Community-Acquired Pneumonia (CAP) β€” bacterial, atypical, or viral"),
  ...gap(1),
  body("This protocol is applicable to emergency departments, general paediatric wards, and outpatient settings in any region where TB burden is moderate to high. It does not replace local institutional guidelines or clinical judgement."),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 3 – Clinical Presentation
// ═══════════════════════════════════════════════════════════════════════════
const clinicalSection = [
  h1("2. Clinical Presentation & Initial Triage"),
  h2("2.1 Presenting Features"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Feature", NAVY, WHITE, true, 1, 2200),
        shadedCell("Primary TB", RED, WHITE, true, 1, 2600),
        shadedCell("Bacterial CAP", GREEN, WHITE, true, 1, 2600),
        shadedCell("Atypical (Mycoplasma)", PURPLE, WHITE, true, 1, 2600),
      ]}),
      ...[
        ["Onset",            "Gradual (weeks–months)",  "Acute (1–3 days)",       "Subacute (1–2 weeks)"],
        ["Fever pattern",    "Low-grade, intermittent", "High-grade, continuous",  "Low-grade, persistent"],
        ["Cough",            "Dry or minimal",          "Productive, purulent",    "Dry, persistent ('walking')"],
        ["Breathlessness",   "Gradual, progressive",    "Rapid onset",             "Mild to moderate"],
        ["Chest pain",       "Absent / mild",           "Pleuritic, sharp",        "Absent / mild"],
        ["Constitutional",   "Weight loss, night sweats","Rigors, vomiting",       "Fatigue, headache"],
        ["Auscultation",     "Reduced air entry",       "Bronchial breath sounds", "Fine crackles"],
        ["O2 Saturation",    "Normal–mildly reduced",   "Often <95%",              "Usually maintained"],
      ].map((row, i) =>
        new TableRow({ children: [
          plainCell(row[0], i%2===0 ? LGRAY : WHITE, "000000", true),
          plainCell(row[1], i%2===0 ? LRED : "FFF5F5",  RED),
          plainCell(row[2], i%2===0 ? LGREEN : "F0FFF4", GREEN),
          plainCell(row[3], i%2===0 ? LPURP : "FAF0FE", PURPLE),
        ]})
      )
    ]
  }),
  ...gap(1),
  h2("2.2 Risk Factor Assessment"),
  bullet("TB contact history (household or close contact with confirmed TB)"),
  bullet("BCG vaccination status (unvaccinated = higher TB risk)"),
  bullet("HIV status β€” immunocompromised children have atypical presentations"),
  bullet("Malnutrition / low BMI β€” independently increases TB risk"),
  bullet("Prior TB treatment or incomplete course"),
  bullet("Migration from high-burden TB region"),
  bullet("School / orphanage exposure"),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 4 – Radiology
// ═══════════════════════════════════════════════════════════════════════════
const radiologySection = [
  h1("3. Radiological Assessment"),
  h2("3.1 Chest X-Ray Interpretation"),
  body("A CXR is mandatory in all children with suspected lower respiratory tract infection with consolidation pattern. Obtain PA view (AP if unable to stand). Request lateral view if upper lobe involvement suspected."),
  ...gap(1),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("CXR Finding", NAVY, WHITE, true, 1, 2200),
        shadedCell("Favours TB", RED, WHITE, true, 1, 2600),
        shadedCell("Favours Bacterial CAP", GREEN, WHITE, true, 1, 2600),
        shadedCell("Significance", AMBER, WHITE, true, 1, 2600),
      ]}),
      ...[
        ["Lobar consolidation", "RUL β€” classic primary focus", "Any lobe; RLL common", "Location alone insufficient"],
        ["Hilar lymphadenopathy", "Present (asymmetric, unilateral)", "Absent", "Most specific TB sign in children"],
        ["Mediastinal shift", "Absent (unless compressive nodes)", "Absent in consolidation", "Shift β†’ collapse not consolidation"],
        ["Pleural effusion", "Uncommon (<10%)", "Common with Staph, Strep", "Effusion needs drainage evaluation"],
        ["Cavitation", "Rare <10 yrs; possible in adolescents", "Rare; Staph necrotising", "CT needed if suspected cavity"],
        ["Miliary nodules", "TB dissemination (severe)", "Absent", "Urgent TB workup mandatory"],
        ["Air bronchogram", "May be present", "Characteristic finding", "Does not differentiate TB vs CAP"],
        ["No volume loss", "Present", "Present", "Distinguishes consolidation from atelectasis"],
      ].map((row, i) =>
        new TableRow({ children: [
          plainCell(row[0], i%2===0 ? LGRAY : WHITE, "000000", true),
          plainCell(row[1], i%2===0 ? LRED : "FFF5F5",  RED),
          plainCell(row[2], i%2===0 ? LGREEN : "F0FFF4", GREEN),
          plainCell(row[3], i%2===0 ? AMBER_L : WHITE, AMBER),
        ]})
      )
    ]
  }),
  ...gap(1),
  h2("3.2 CT Chest Indications"),
  body("CT chest is NOT routine. Order CT in the following situations:"),
  bullet("CXR shows consolidation but clinical course is atypical or prolonged (>2 weeks)"),
  bullet("Suspicion of hilar or mediastinal lymphadenopathy not visible on CXR"),
  bullet("No response to empiric antibiotics after 48–72 hours"),
  bullet("Suspected complication: cavitation, empyema, lung abscess, pneumothorax"),
  bullet("Immunocompromised child with atypical presentation"),
  bullet("Suspected foreign body or endobronchial lesion"),
  ...gap(1),
  noteBox("CT Tip: A low-dose CT chest with contrast is preferred in children to minimise radiation. Window the images at both lung and mediastinal settings. Report specifically: lymph node size/distribution, consolidation extent, cavitation, and pleural collections.", LBLUE, NAVY),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 5 – Investigations
// ═══════════════════════════════════════════════════════════════════════════
const investigationsSection = [
  h1("4. Investigations"),
  h2("4.1 First-Line Investigations (ALL Children)"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Investigation", NAVY, WHITE, true, 1, 2800),
        shadedCell("Purpose", NAVY, WHITE, true, 1, 4200),
        shadedCell("Interpretation", NAVY, WHITE, true, 1, 3000),
      ]}),
      ...[
        ["CBC with differential",  "Screen for leukocytosis (bacterial), lymphocytosis (TB/viral), anaemia (TB)", "WBC >15,000 with neutrophilia β†’ bacterial; Lymphocytosis β†’ TB/viral"],
        ["CRP + ESR",              "Inflammatory markers; CRP more sensitive for acute bacterial infection", "CRP >100 mg/L β†’ bacterial CAP; mildly elevated β†’ TB or atypical"],
        ["Blood culture (aerobic)", "Identify bacteraemia in bacterial CAP; positive in ~10–20% lobar pneumonia", "Positive β†’ guides targeted antibiotic therapy"],
        ["Pulse oximetry / ABG",   "Assess oxygenation; guide O2 therapy and admission decision", "SpO2 <92% = indication for admission and oxygen supplementation"],
        ["Mantoux / TST (5 TU PPD)", "Screen for TB sensitization; β‰₯10mm = positive in immunocompetent child", "β‰₯5mm in HIV+ / severely malnourished counts as positive"],
        ["Chest X-Ray (PA + Lateral)", "Primary imaging; assess consolidation pattern, hilar nodes, effusion", "See Section 3 interpretation guide"],
        ["Sputum / Nasopharyngeal swab", "Gram stain and culture; PCR for Mycoplasma, Respiratory Viruses", "Positive culture guides targeted therapy"],
      ].map((row, i) =>
        new TableRow({ children: [
          plainCell(row[0], i%2===0 ? LGRAY : WHITE, "000000", true),
          plainCell(row[1], i%2===0 ? LGRAY : WHITE),
          plainCell(row[2], i%2===0 ? LGRAY : WHITE, "333333", false),
        ]})
      )
    ]
  }),
  ...gap(1),
  h2("4.2 TB-Specific Investigations"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Test", RED, WHITE, true, 1, 2800),
        shadedCell("Specimen", RED, WHITE, true, 1, 2000),
        shadedCell("When to Order", RED, WHITE, true, 1, 2200),
        shadedCell("Key Note", RED, WHITE, true, 1, 3000),
      ]}),
      ...[
        ["GeneXpert MTB/RIF Ultra", "Sputum / Gastric aspirate / BAL", "First-line molecular test; order in all suspected TB", "Detects MTB + RIF resistance in <2 hrs; highest sensitivity in children"],
        ["Gastric Lavage / Aspirate (x3)", "Gastric juice (early morning, 3 consecutive days)", "Children who cannot produce sputum (<10 yrs)", "Positive AFB smear or culture confirms TB"],
        ["AFB Smear + Culture (MGIT)", "Sputum or gastric aspirate", "All TB suspect cases; culture is gold standard", "Culture takes 2–6 weeks; sensitivity 40–70% in children"],
        ["IGRA (QuantiFERON-TB Gold)", "Venous blood", "TST-negative but high clinical suspicion; BCG-vaccinated child", "Not affected by BCG; better specificity than TST"],
        ["Induced sputum", "Hypertonic saline nebulised sputum", "When spontaneous sputum unobtainable in older child", "Higher yield than gastric aspirate in children >5 yrs"],
        ["CT Chest with contrast", "Imaging", "When hilar LN suspected but not visible on CXR", "Detects lymphadenopathy, cavitation, complications"],
        ["HIV serology + CD4 count", "Blood", "All TB-suspected children; mandatory workup", "HIV co-infection alters TB presentation and management"],
      ].map((row, i) =>
        new TableRow({ children: row.map(cell =>
          plainCell(cell, i%2===0 ? LRED : "FFF5F5", i===0 ? RED : "000000", i===0)
        )})
      )
    ]
  }),
  ...gap(1),
  h2("4.3 CAP-Specific Investigations"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Test", GREEN, WHITE, true, 1, 2800),
        shadedCell("Indication", GREEN, WHITE, true, 1, 3000),
        shadedCell("Key Note", GREEN, WHITE, true, 1, 4200),
      ]}),
      ...[
        ["Urine Pneumococcal Ag", "Suspected Strep pneumoniae CAP; severe illness", "Rapid; +ve even after antibiotic start; high specificity"],
        ["Mycoplasma IgM serology", "School-age child, gradual onset, dry cough, Azithro non-response", "Peaks at 2–3 weeks; cold agglutinins +ve in ~50%"],
        ["Cold Agglutinins", "Suspected Mycoplasma pneumoniae", "Titre β‰₯1:64 supports diagnosis; cheaper than serology"],
        ["NPS PCR panel", "Viral CAP (RSV, Influenza, Adeno, hMPV)", "Guides antiviral therapy and infection control"],
        ["Pleural fluid (if effusion)", "Exudative / Empyema workup: LDH, protein, pH, culture", "pH <7.2 β†’ drainage required; Staph/Strep most common"],
        ["Procalcitonin (PCT)", "Distinguish bacterial from viral CAP; guide de-escalation", "PCT >0.5 ng/mL supports bacterial aetiology"],
      ].map((row, i) =>
        new TableRow({ children: row.map((cell, j) =>
          plainCell(cell, i%2===0 ? LGREEN : "F0FFF4", j===0 ? GREEN : "000000", j===0)
        )})
      )
    ]
  }),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 6 – Management TB
// ═══════════════════════════════════════════════════════════════════════════
const tbManagementSection = [
  h1("5. Management: Tuberculosis"),
  h2("5.1 Admission Criteria (TB)"),
  bullet("Moderate-to-severe respiratory distress (SpO2 <92%, retractions, tachypnoea)"),
  bullet("Miliary TB or disseminated disease on CXR"),
  bullet("Infant (<2 years) with confirmed or highly suspected TB"),
  bullet("HIV-positive child with TB co-infection"),
  bullet("Severe malnutrition with TB"),
  bullet("Central nervous system TB (TB meningitis)"),
  bullet("Unable to tolerate oral medications"),
  ...gap(1),
  h2("5.2 Anti-TB Regimen (Standard First-Line β€” WHO / National Programme)"),
  noteBox("Dosing is weight-based. Use Fixed-Dose Combinations (FDC) where available. All regimens below are for drug-susceptible TB (DS-TB). If RIF resistance detected on GeneXpert, refer for MDR-TB management.", LRED, RED),
  ...gap(1),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Phase", RED, WHITE, true, 1, 1600),
        shadedCell("Duration", RED, WHITE, true, 1, 1400),
        shadedCell("Drugs (Abbreviation)", RED, WHITE, true, 1, 2200),
        shadedCell("Daily Doses (mg/kg/day)", RED, WHITE, true, 1, 2200),
        shadedCell("Notes", RED, WHITE, true, 1, 2600),
      ]}),
      new TableRow({ children: [
        plainCell("Intensive Phase", LRED, RED, true),
        plainCell("2 months", LRED),
        plainCell("HRZE  (Isoniazid + Rifampicin + Pyrazinamide + Ethambutol)", LRED, RED),
        plainCell("H: 10 mg/kg (max 300 mg)\nR: 15 mg/kg (max 600 mg)\nZ: 35 mg/kg (max 2 g)\nE: 20 mg/kg (max 1.2 g)", LRED),
        plainCell("Add Pyridoxine (Vit B6) 10–25 mg/day with Isoniazid to prevent neuropathy", LRED),
      ]}),
      new TableRow({ children: [
        plainCell("Continuation Phase", "FFF5F5", RED, true),
        plainCell("4 months", "FFF5F5"),
        plainCell("HR  (Isoniazid + Rifampicin)", "FFF5F5", RED),
        plainCell("H: 10 mg/kg/day\nR: 15 mg/kg/day", "FFF5F5"),
        plainCell("Total treatment duration: 6 months for pulmonary TB. Extend to 9–12 months for TB meningitis or bone TB.", "FFF5F5"),
      ]}),
    ]
  }),
  ...gap(1),
  h2("5.3 Monitoring During TB Treatment"),
  bullet("Monthly clinical review: weight, symptoms, adherence, adverse effects"),
  bullet("Liver function tests (AST/ALT) at baseline, 2 weeks, and monthly (if symptomatic)"),
  bullet("Repeat CXR at 2 months (end of intensive phase) and at completion (6 months)"),
  bullet("Sputum / gastric aspirate for culture at 2 months if initial positive"),
  bullet("Symptom check at every visit: jaundice, rash, visual changes (Ethambutol)"),
  ...gap(1),
  h2("5.4 DOTS and Notification"),
  bullet("Notify TB case to local public health authority β€” mandatory in most jurisdictions"),
  bullet("Initiate DOTS (Directly Observed Therapy, Short-course) β€” community health worker observed dosing"),
  bullet("Contact tracing: screen all household contacts with TST/IGRA + CXR"),
  bullet("Close contacts aged <5 years or immunocompromised β†’ consider Isoniazid Preventive Therapy (IPT)"),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 7 – Management CAP
// ═══════════════════════════════════════════════════════════════════════════
const capManagementSection = [
  h1("6. Management: Community-Acquired Pneumonia (CAP)"),
  h2("6.1 Severity Assessment β€” PEWS / CURB-Children"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Parameter", NAVY, WHITE, true),
        shadedCell("Mild (Outpatient)", GREEN, WHITE, true),
        shadedCell("Moderate (Ward Admission)", ORANGE, WHITE, true),
        shadedCell("Severe (PICU)", RED, WHITE, true),
      ]}),
      ...[
        ["SpO2",         "β‰₯95% on room air", "92–94% on room air", "<92% or requiring >50% O2"],
        ["Respiratory rate (5–12 yrs)", "<30/min", "30–40/min", ">40/min"],
        ["Work of breathing", "None", "Mild subcostal recession", "Severe retractions, nasal flaring, grunting"],
        ["Feeding / Activity", "Normal", "Reduced intake", "Unable to feed, lethargic"],
        ["Heart rate",   "Normal for age", "Mildly elevated", "Tachycardia with poor perfusion"],
        ["CXR extent",   "<1 lobe", "1 lobe",  ">1 lobe or bilateral"],
      ].map((row, i) =>
        new TableRow({ children: [
          plainCell(row[0], i%2===0 ? LGRAY : WHITE, "000000", true),
          plainCell(row[1], i%2===0 ? LGREEN : "F0FFF4", GREEN),
          plainCell(row[2], i%2===0 ? "FEF0E7" : WHITE, ORANGE),
          plainCell(row[3], i%2===0 ? LRED : "FFF5F5",  RED),
        ]})
      )
    ]
  }),
  ...gap(1),
  h2("6.2 Antibiotic Selection (Age 5–15 Years)"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Severity / Suspected Organism", GREEN, WHITE, true, 1, 2800),
        shadedCell("First-Line Antibiotic", GREEN, WHITE, true, 1, 2800),
        shadedCell("Dose & Duration", GREEN, WHITE, true, 1, 2400),
        shadedCell("Alternative", GREEN, WHITE, true, 1, 2000),
      ]}),
      ...[
        ["Mild CAP (outpatient)\nPresumptive Strep. pneumoniae",  "Amoxicillin oral",                      "90 mg/kg/day Γ· 3 doses Γ— 5–7 days (max 3 g/day)", "Co-amoxiclav if local resistance high"],
        ["Moderate CAP (admitted ward)\nStrep. pneumoniae",       "Ampicillin IV OR\nBenzyl Penicillin IV", "Ampicillin: 200 mg/kg/day Γ· 4 doses\nSwitch to oral amoxicillin when improving Γ— 7–10 days total", "Ceftriaxone IV 50 mg/kg/day if Penicillin allergy"],
        ["Atypical pneumonia (Mycoplasma)\nGradual onset, dry cough, school-age", "Azithromycin oral",    "10 mg/kg Day 1, then 5 mg/kg Days 2–5\n(5-day course)", "Clarithromycin 15 mg/kg/day Γ· 2 doses Γ— 10 days"],
        ["Severe CAP / PICU\nΒ± Staph aureus suspicion",           "Ceftriaxone IV +\nVancomycin IV",        "Ceftriaxone 100 mg/kg/day\nVancomycin 60 mg/kg/day Γ· 4 doses", "Add Clindamycin if necrotising pneumonia"],
        ["Aspiration pneumonia",                                   "Co-amoxiclav IV",                       "100 mg/kg/day (amoxicillin component) Γ· 3 doses",  "Add Metronidazole for anaerobic cover"],
      ].map((row, i) =>
        new TableRow({ children: row.map((cell, j) =>
          plainCell(cell, i%2===0 ? LGREEN : "F0FFF4", j===0 ? GREEN : (j===2 ? "444444" : "000000"), j===0)
        )})
      )
    ]
  }),
  ...gap(1),
  h2("6.3 Supportive Management"),
  bullet("Oxygen: target SpO2 β‰₯95%; use nasal cannula 1–2 L/min for mild hypoxaemia; HFNC/CPAP for severe"),
  bullet("Antipyretics: Paracetamol 15 mg/kg/dose 4–6 hourly (max 60 mg/kg/day) for fever and discomfort"),
  bullet("Hydration: IV fluids if unable to tolerate oral; correct dehydration"),
  bullet("Bronchodilators: only if wheeze or bronchospasm present; not routine in CAP"),
  bullet("Physiotherapy: not recommended in acute phase; consider in post-acute recovery"),
  bullet("IV to oral switch criteria: afebrile >24 h, SpO2 β‰₯95%, tolerating oral feeds, CRP declining"),
  ...gap(1),
  h2("6.4 Response Assessment"),
  bullet("Re-examine at 48–72 hours; failure to improve = reassess diagnosis (consider TB, abscess, empyema, resistant organism)"),
  bullet("Repeat CXR only if clinically deteriorating or complications suspected β€” not routine at 48 hrs"),
  bullet("Follow-up CXR at 4–6 weeks post-discharge to confirm radiological resolution"),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 8 – Complications
// ═══════════════════════════════════════════════════════════════════════════
const complicationsSection = [
  h1("7. Complications and Escalation"),
  h2("7.1 Complications of Bacterial CAP"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Complication", GREEN, WHITE, true, 1, 2200),
        shadedCell("Clinical Features", GREEN, WHITE, true, 1, 3000),
        shadedCell("Investigation", GREEN, WHITE, true, 1, 2400),
        shadedCell("Management", GREEN, WHITE, true, 1, 2400),
      ]}),
      ...[
        ["Parapneumonic effusion", "Dullness to percussion, reduced breath sounds, fever persistence", "USG chest / CT; pleural fluid aspirate", "Small: antibiotics only; Large/Empyema: chest drain"],
        ["Empyema", "Persistent fever >72 hrs, toxic appearance, frank pus on aspiration", "Pleural fluid: pH <7.2, glucose <2.2, positive culture", "Chest tube drainage; VATS decortication if loculated"],
        ["Lung abscess", "Foul sputum, swinging fever, cavity on CXR/CT", "CT chest; Blood culture; Anaerobic sputum culture", "Prolonged antibiotics 4–6 weeks; percutaneous/surgical drainage if fails"],
        ["Necrotising pneumonia", "Rapid deterioration, cavity formation, Staph aureus", "CT chest (multiple cavities, pneumatoceles)", "IV Vancomycin + Clindamycin; PICU; surgical consult"],
        ["Pneumothorax", "Sudden worsening, tracheal deviation, absent breath sounds", "CXR / USG", "Tension: immediate needle decompression; then chest drain"],
      ].map((row, i) =>
        new TableRow({ children: row.map((cell, j) =>
          plainCell(cell, i%2===0 ? LGREEN : "F0FFF4", j===0 ? GREEN : "000000", j===0)
        )})
      )
    ]
  }),
  ...gap(1),
  h2("7.2 Complications of Pulmonary TB"),
  bullet("Bronchial obstruction: enlarged hilar nodes compress bronchus β†’ collapse-consolidation β†’ treat with corticosteroids (Prednisolone 2 mg/kg/day Γ— 4–6 weeks)"),
  bullet("Pleural effusion (TB): exudative; diagnose by ADA >40 U/L; treat with standard anti-TB therapy"),
  bullet("Miliary TB: haematogenous spread; bilateral micronodules; admit to PICU, add corticosteroids"),
  bullet("TB meningitis: urgent LP; add Dexamethasone; treat 12 months total"),
  bullet("Paradoxical reaction (IRIS): worsening after starting treatment; diagnose by exclusion; treat with short-course corticosteroids"),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 9 – Infection Control
// ═══════════════════════════════════════════════════════════════════════════
const infectionControlSection = [
  h1("8. Infection Prevention and Control"),
  h2("8.1 TB Infection Control"),
  bullet("Isolate suspected pulmonary TB in a negative-pressure room (or single room with closed door)"),
  bullet("Healthcare workers to wear N95 respirators (not surgical masks) when entering room"),
  bullet("Visitors limited; must wear surgical mask minimum"),
  bullet("Children with pulmonary TB are generally paucibacillary β€” transmission risk is lower than adults, but precautions must be maintained"),
  bullet("Sputum / gastric aspirate collected in dedicated negative-pressure rooms or well-ventilated areas"),
  bullet("Airborne precautions maintained until 2 weeks of effective therapy confirmed and clinical improvement"),
  ...gap(1),
  h2("8.2 CAP Infection Control"),
  bullet("Droplet precautions for bacterial CAP (surgical mask for patients when outside room; mask + eye protection for HCW within 1 m)"),
  bullet("Contact precautions for Staph aureus CAP (gown + gloves)"),
  bullet("Influenza / RSV CAP: cohort patients; droplet + contact precautions"),
  bullet("Hand hygiene: soap and water or alcohol-based handrub before and after all patient contact"),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 10 – Discharge & Follow-Up
// ═══════════════════════════════════════════════════════════════════════════
const dischargeSection = [
  h1("9. Discharge Criteria and Follow-Up"),
  h2("9.1 Discharge Criteria"),
  bullet("SpO2 β‰₯95% on room air for β‰₯24 hours"),
  bullet("Afebrile for β‰₯24 hours"),
  bullet("Tolerating oral fluids and medications"),
  bullet("No signs of respiratory distress (normal respiratory rate for age)"),
  bullet("Caregiver counselled and able to administer oral medications"),
  bullet("Follow-up appointment confirmed before discharge"),
  ...gap(1),
  h2("9.2 Follow-Up Schedule"),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: STD_BORDERS,
    rows: [
      new TableRow({ children: [
        shadedCell("Diagnosis", NAVY, WHITE, true, 1, 2000),
        shadedCell("Follow-up Visit", NAVY, WHITE, true, 1, 2200),
        shadedCell("What to Assess", NAVY, WHITE, true, 1, 3000),
        shadedCell("Repeat CXR?", NAVY, WHITE, true, 1, 2000),
      ]}),
      ...[
        ["CAP (Mild)", "1–2 weeks post-discharge", "Clinical resolution, completed antibiotics", "Only if persistent symptoms"],
        ["CAP (Moderate/Severe)", "1 week, then 4–6 weeks", "Radiological clearance, complications", "At 4–6 weeks"],
        ["Pulmonary TB", "Monthly for 6 months", "Drug adherence, weight gain, adverse effects, sputum clearance", "At 2 months and 6 months (completion)"],
      ].map((row, i) =>
        new TableRow({ children: row.map(cell => plainCell(cell, i%2===0 ? LGRAY : WHITE)) })
      )
    ]
  }),
  divider(),
];

// ═══════════════════════════════════════════════════════════════════════════
// SECTION 11 – Quick Reference Summary
// ═══════════════════════════════════════════════════════════════════════════
const summarySection = [
  h1("10. Quick Reference Summary"),
  noteBox(
    "STEP 1 – Assess: History (onset, fever pattern, contacts) + CXR + O2 sat\n" +
    "STEP 2 – Classify: Acute β†’ Bacterial CAP   |   Gradual β†’ TB / Atypical\n" +
    "STEP 3 – Investigate: Mantoux + GeneXpert (TB pathway) | Blood Cx + PCT (CAP pathway)\n" +
    "STEP 4 – Treat: Amoxicillin/Ampicillin (CAP) | 2HRZEβ†’4HR (TB) | Azithromycin (Mycoplasma)\n" +
    "STEP 5 – Review at 48–72 hrs: No response β†’ reassess with CT Chest + Bronchoscopy\n" +
    "STEP 6 – Discharge: SpO2 β‰₯95%, afebrile, oral tolerated | Follow-up booked",
    LBLUE, NAVY
  ),
  ...gap(1),
  noteBox(
    "RED FLAGS β€” Immediate Senior Review:\n" +
    "β€’ SpO2 <92%  β€’  Severe respiratory distress  β€’  Bilateral / Miliary CXR\n" +
    "β€’ Mediastinal shift  β€’  No improvement in 72 hrs  β€’  HIV+ / Immunocompromised\n" +
    "β€’ Suspected TB meningitis (altered sensorium, neck stiffness, bulging fontanelle)",
    LRED, RED
  ),
  divider(),
  h1("11. References"),
  bullet("WHO. Guidance for national tuberculosis programmes on the management of tuberculosis in children. 3rd Ed. 2022."),
  bullet("IAP Guidelines on Childhood Tuberculosis β€” Indian Academy of Pediatrics, 2023."),
  bullet("IDSA / PIDS Guidelines for Management of Community-Acquired Pneumonia in Infants and Children. CID 2011."),
  bullet("The Union. Diagnostic CXR Atlas for Tuberculosis in Children. 2nd Ed. 2022."),
  bullet("Swanson's Family Medicine Review β€” Community-Acquired Pneumonia in Children. 9th Ed, p.584."),
  bullet("PMC Article: Chest Imaging for Pulmonary TB β€” An Update. Pathogens 2022; 11(2):254. PMID 35215198."),
];

// ═══════════════════════════════════════════════════════════════════════════
// ASSEMBLE DOCUMENT
// ═══════════════════════════════════════════════════════════════════════════
const doc = new Document({
  numbering: {
    config: []
  },
  styles: {
    default: {
      document: {
        run: { font: "Calibri", size: 20 }
      }
    }
  },
  sections: [
    {
      properties: {
        page: {
          margin: { top: 1000, bottom: 900, left: 1080, right: 1080 },
          pageNumbers: { start: 1, formatType: NumberFormat.DECIMAL }
        }
      },
      headers: {
        default: new Header({
          children: [new Table({
            width: { size: 100, type: WidthType.PERCENTAGE },
            borders: {
              top: { style: BorderStyle.NONE, size: 0 }, bottom: { style: BorderStyle.SINGLE, size: 6, color: NAVY },
              left: { style: BorderStyle.NONE, size: 0 }, right: { style: BorderStyle.NONE, size: 0 },
              insideHorizontal: { style: BorderStyle.NONE, size: 0 }, insideVertical: { style: BorderStyle.NONE, size: 0 }
            },
            rows: [new TableRow({ children: [
              new TableCell({ children: [new Paragraph({ children: [new TextRun({ text: "Case Management Protocol: Pediatric RUL Consolidation β€” TB vs CAP", bold: true, size: 16, color: NAVY })] })] }),
              new TableCell({ width: { size: 2000, type: WidthType.DXA }, children: [new Paragraph({ alignment: AlignmentType.RIGHT, children: [new TextRun({ text: "Page ", size: 16, color: "777777" }), new TextRun({ children: [PageNumber.CURRENT], size: 16, color: "777777" }), new TextRun({ text: " of ", size: 16, color: "777777" }), new TextRun({ children: [PageNumber.TOTAL_PAGES], size: 16, color: "777777" })] })] })
            ]})]
          })]
        })
      },
      footers: {
        default: new Footer({
          children: [new Paragraph({
            alignment: AlignmentType.CENTER,
            border: { top: { style: BorderStyle.SINGLE, size: 4, color: MGRAY } },
            children: [new TextRun({ text: "For clinical use only. Correlate with local epidemiology and institutional guidelines. Version 1.0 β€” July 2026  |  Orris Medical AI", size: 16, color: "777777", italics: true })]
          })]
        })
      },
      children: [
        ...coverSection,
        ...purposeSection,
        ...clinicalSection,
        ...radiologySection,
        ...investigationsSection,
        ...tbManagementSection,
        ...capManagementSection,
        ...complicationsSection,
        ...infectionControlSection,
        ...dischargeSection,
        ...summarySection,
      ]
    }
  ]
});

Packer.toBuffer(doc).then(buffer => {
  const outPath = "/home/daytona/workspace/tb-cap-protocol/TB_vs_CAP_Case_Management_Protocol.docx";
  fs.writeFileSync(outPath, buffer);
  console.log("DOCX saved β†’", outPath);
}).catch(err => {
  console.error("Error:", err.message);
  process.exit(1);
});
Running Command

cd /home/daytona/workspace/tb-cap-protocol && node create_protocol.js 2>&1

Running Command

python3 /home/daytona/skills/docx/scripts/office/validate.py /home/daytona/works…

Running Command

python3 -c " from zipfile import ZipFile z = ZipFile('/home/daytona/workspace/tb…

The document is valid and ready. Here is your download link:

TB vs CAP Case Management Protocol

Word Document Β· DOCX


What's Inside the Document (22 KB, 11 Sections)

The Word document is fully formatted with colour-coded tables, headers/footers, and page numbers. Here's what each section covers:
SectionContent
Cover PageTitle, target population, setting, version, classification table
1. Purpose & ScopeProtocol goals, applicable settings, populations
2. Clinical Presentation3-way comparison table (TB vs Bacterial CAP vs Mycoplasma) across 8 clinical features + risk factor checklist
3. RadiologyCXR interpretation table, CT chest indications, clinical tips
4. InvestigationsFirst-line workup for all children; TB-specific tests (GeneXpert, Gastric lavage, IGRA, induced sputum); CAP-specific tests (Mycoplasma IgM, Urine Ag, PCT)
5. TB ManagementAdmission criteria, 2HRZE/4HR regimen with weight-based dosing, monitoring schedule, DOTS/notification
6. CAP ManagementSeverity scoring (Mild/Moderate/Severe), antibiotic selection table by organism, supportive care, IV-to-oral switch criteria
7. ComplicationsCAP complications (empyema, abscess, necrotising pneumonia, pneumothorax) + TB complications (IRIS, miliary, meningitis) with management
8. Infection ControlAirborne precautions for TB (N95, negative-pressure room), droplet/contact for CAP
9. Discharge & Follow-UpDischarge criteria, follow-up schedule table for CAP and TB
10. Quick Reference6-step summary box + Red Flags box for immediate reference
11. ReferencesWHO, IAP, IDSA guidelines + key cited sources
This is a shared conversation. Sign in to Orris to start your own chat.