Standard operating procedure sheet for Massive transfusion protocol in document form

Reading File
Reading File
Finding Sources
Finding Sources
Searching the Web

massive transfusion protocol SOP standard operating procedure components 2024

Reading File
Reading File
Reading File
Reading Web Page

https://www.vumc.org/trauma-and-scc/sites/default/files/publ…

Loading Image
Reading File
Running Command

ls /home/daytona/workspace/ && ls /home/daytona/skills/docx/scripts/office/ 2>/dev/null || true

Running Command

ls /home/daytona/workspace/mtp-sop/

Running Command

pandoc /home/daytona/workspace/mtp-sop/SOP_MTP_NABH.docx -t markdown 2>/dev/null | head -120

Running Command

pandoc /home/daytona/workspace/mtp-sop/SOP_MTP_NABH.docx -t markdown 2>/dev/null | tail -200

Running Command

pandoc /home/daytona/workspace/mtp-sop/SOP_MTP_NABH.docx -t markdown 2>/dev/null | sed -n '120,280p'

Running Command

python /home/daytona/skills/docx/scripts/office/validate.py /home/daytona/workspace/mtp-sop/SOP_MTP_NABH.docx

Writing File

~/mtp-sop/build_mtp_final.js

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

// ── Helpers ──────────────────────────────────────────────────────────────────
const FONT = 'Calibri';
const DARK_RED  = '8B0000';
const MID_RED   = 'C0392B';
const LIGHT_RED = 'FADBD8';
const DARK_GREY = '2C3E50';
const MID_GREY  = 'ECF0F1';
const WHITE     = 'FFFFFF';
const BLACK     = '000000';
const AMBER     = 'F39C12';

function txt(text, opts = {}) {
  return new TextRun({
    text,
    font: FONT,
    size: opts.size || 20,
    bold: opts.bold || false,
    italics: opts.italics || false,
    color: opts.color || BLACK,
    underline: opts.underline ? { type: UnderlineType.SINGLE } : undefined,
  });
}

function para(runs, opts = {}) {
  return new Paragraph({
    children: Array.isArray(runs) ? runs : [runs],
    alignment: opts.align || AlignmentType.LEFT,
    spacing: { before: opts.before || 60, after: opts.after || 60 },
    indent: opts.indent ? { left: opts.indent } : undefined,
    heading: opts.heading || undefined,
    bullet: opts.bullet ? { level: 0 } : undefined,
  });
}

function h1(text) {
  return new Paragraph({
    children: [new TextRun({ text, font: FONT, size: 26, bold: true, color: WHITE })],
    heading: HeadingLevel.HEADING_1,
    spacing: { before: 240, after: 120 },
    shading: { type: ShadingType.SOLID, color: DARK_RED, fill: DARK_RED },
    alignment: AlignmentType.LEFT,
  });
}

function h2(text) {
  return new Paragraph({
    children: [new TextRun({ text, font: FONT, size: 22, bold: true, color: WHITE })],
    heading: HeadingLevel.HEADING_2,
    spacing: { before: 180, after: 80 },
    shading: { type: ShadingType.SOLID, color: MID_RED, fill: MID_RED },
    alignment: AlignmentType.LEFT,
  });
}

function h3(text) {
  return new Paragraph({
    children: [new TextRun({ text, font: FONT, size: 20, bold: true, color: DARK_RED })],
    heading: HeadingLevel.HEADING_3,
    spacing: { before: 140, after: 60 },
  });
}

function bullet(text, opts = {}) {
  return new Paragraph({
    children: [new TextRun({ text, font: FONT, size: opts.size || 20, color: opts.color || BLACK })],
    bullet: { level: opts.level || 0 },
    spacing: { before: 40, after: 40 },
    indent: { left: 360 },
  });
}

function spacer(n = 1) {
  return Array.from({ length: n }, () =>
    new Paragraph({ children: [new TextRun({ text: '' })], spacing: { before: 40, after: 40 } })
  );
}

function cell(text, opts = {}) {
  return new TableCell({
    children: [new Paragraph({
      children: [new TextRun({
        text,
        font: FONT,
        size: opts.size || 18,
        bold: opts.bold || false,
        color: opts.textColor || BLACK,
      })],
      alignment: opts.align || AlignmentType.LEFT,
      spacing: { before: 40, after: 40 },
    })],
    shading: opts.shading ? { type: ShadingType.SOLID, color: opts.shading, fill: opts.shading } : undefined,
    verticalAlign: VerticalAlign.CENTER,
    columnSpan: opts.span || undefined,
    width: opts.width ? { size: opts.width, type: WidthType.DXA } : undefined,
    margins: { top: 80, bottom: 80, left: 120, right: 120 },
  });
}

function headerRow(labels, widths) {
  return new TableRow({
    tableHeader: true,
    children: labels.map((label, i) => cell(label, {
      bold: true, shading: DARK_RED, textColor: WHITE,
      size: 18, width: widths ? widths[i] : undefined,
    })),
  });
}

function dataRow(values, widths, shade) {
  return new TableRow({
    children: values.map((v, i) => cell(v, {
      size: 18,
      shading: shade || undefined,
      width: widths ? widths[i] : undefined,
    })),
  });
}

// ── Cover / Title block ──────────────────────────────────────────────────────
const coverTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.THICK, size: 12, color: DARK_RED },
    bottom: { style: BorderStyle.THICK, size: 12, color: DARK_RED },
    left: { style: BorderStyle.THICK, size: 12, color: DARK_RED },
    right: { style: BorderStyle.THICK, size: 12, color: DARK_RED },
  },
  rows: [
    new TableRow({ children: [
      new TableCell({
        children: [
          new Paragraph({ children: [new TextRun({ text: 'STANDARD OPERATING PROCEDURE', font: FONT, size: 32, bold: true, color: WHITE })], alignment: AlignmentType.CENTER, spacing: { before: 80, after: 40 } }),
          new Paragraph({ children: [new TextRun({ text: 'MASSIVE TRANSFUSION PROTOCOL (MTP)', font: FONT, size: 36, bold: true, color: WHITE })], alignment: AlignmentType.CENTER, spacing: { before: 40, after: 80 } }),
          new Paragraph({ children: [new TextRun({ text: 'Department of Blood Bank & Transfusion Medicine', font: FONT, size: 22, italics: true, color: 'FADBD8' })], alignment: AlignmentType.CENTER, spacing: { before: 40, after: 80 } }),
        ],
        shading: { type: ShadingType.SOLID, color: DARK_RED, fill: DARK_RED },
        margins: { top: 160, bottom: 160, left: 240, right: 240 },
      }),
    ]}),
  ],
});

const metaTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    new TableRow({ children: [
      cell('Doc No.', { bold: true, shading: MID_GREY, width: 1800 }),
      cell('BB/SOP/MTP/01', { width: 1800 }),
      cell('Version / Rev.', { bold: true, shading: MID_GREY, width: 1800 }),
      cell('01 / 00', { width: 1800 }),
      cell('Effective Date', { bold: true, shading: MID_GREY, width: 1800 }),
      cell('___________', { width: 1800 }),
      cell('Review Date', { bold: true, shading: MID_GREY, width: 1800 }),
      cell('___________', { width: 1800 }),
    ]}),
    new TableRow({ children: [
      cell('Prepared By', { bold: true, shading: MID_GREY }),
      cell('Dr. ___________\nBlood Bank MO'),
      cell('Reviewed By', { bold: true, shading: MID_GREY }),
      cell('Dr. ___________\nHead, Dept.'),
      cell('Approved By', { bold: true, shading: MID_GREY }),
      cell('Dr. ___________\nMedical Director'),
      cell('NABH Ref.', { bold: true, shading: MID_GREY }),
      cell('TPC.19(e)\nBSQ.1 / BSQ.7'),
    ]}),
  ],
});

// ── Section 1: Purpose ───────────────────────────────────────────────────────
const sec1 = [
  h1('1. PURPOSE'),
  para([txt('This Standard Operating Procedure (SOP) establishes a standardised, rapid, team-based protocol for the recognition and management of life-threatening haemorrhage requiring massive transfusion. It ensures timely release of compatible blood products, optimises haemostatic resuscitation, and fulfils NABH Accreditation Standard ', { size: 20 }), txt('TPC.19(e)', { size: 20, bold: true }), txt(' — "The blood centre has written guidance for massive transfusions."', { size: 20 })]),
];

// ── Section 2: Scope ─────────────────────────────────────────────────────────
const sec2 = [
  h1('2. SCOPE'),
  para(txt('Applies to all clinical areas where massive haemorrhage may occur:', { bold: true })),
  bullet('Emergency Department (ED)'),
  bullet('Surgical Operation Theatres (OT)'),
  bullet('Obstetrics & Gynaecology (labour room, OT)'),
  bullet('Intensive Care Units — Medical, Surgical, Neonatal (ICU / NICU)'),
  bullet('Interventional Radiology / Cardiac Catheterisation Lab'),
  ...spacer(1),
  para(txt('Involves all staff: treating clinicians, nurses, Blood Bank staff, porters/runners, and the Hospital Transfusion Committee (HTC).')),
];

// ── Section 3: Definitions ───────────────────────────────────────────────────
const definitionTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Term', 'Definition'], [3000, 7500]),
    dataRow(['Massive Transfusion (MT)', 'Transfusion of ≥10 units PRBC in 24 h; OR replacement of ≥50% total blood volume (TBV) within 3 h; OR transfusion of >4 units PRBC in 1 h with anticipated ongoing need.'], [3000, 7500]),
    dataRow(['MTP Activation', 'Formal hospital-wide response triggered by defined criteria to mobilise blood products and clinical resources pre-emptively.'], [3000, 7500], MID_GREY),
    dataRow(['MTP Pack / Cycle', 'Pre-assembled set of blood components released by the Blood Bank in one round of MTP.'], [3000, 7500]),
    dataRow(['1:1:1 Ratio', 'Balanced haemostatic resuscitation — PRBC : FFP : Platelets in 1:1:1 ratio (PROPPR Trial, JAMA 2015).'], [3000, 7500], MID_GREY),
    dataRow(['Lethal Triad', 'Hypothermia (<35°C) + Acidosis (pH <7.35) + Coagulopathy — together amplifies haemorrhage mortality.'], [3000, 7500]),
    dataRow(['Damage Control Resuscitation (DCR)', 'Strategy using permissive hypotension (SBP 80–100 mmHg), minimal crystalloids, and early blood component therapy.'], [3000, 7500], MID_GREY),
    dataRow(['TXA', 'Tranexamic acid — antifibrinolytic administered early in traumatic or obstetric haemorrhage.'], [3000, 7500]),
    dataRow(['TEG / ROTEM', 'Viscoelastic haemostatic assays for real-time clot function monitoring during MTP.'], [3000, 7500], MID_GREY),
    dataRow(['ABC Score', 'Assessment of Blood Consumption — validated 4-parameter score to predict need for MTP (score ≥2 = activate).'], [3000, 7500]),
    dataRow(['PRBC', 'Packed Red Blood Cells.'], [3000, 7500], MID_GREY),
    dataRow(['FFP', 'Fresh Frozen Plasma.'], [3000, 7500]),
    dataRow(['NABH', 'National Accreditation Board for Hospitals & Healthcare Providers — Indian accreditation body.'], [3000, 7500], MID_GREY),
  ],
});

const sec3 = [
  h1('3. DEFINITIONS'),
  definitionTable,
];

// ── Section 4: Responsibilities ──────────────────────────────────────────────
const respTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Role', 'Key Responsibilities'], [3500, 7000]),
    dataRow(['Treating Clinician / MTP Lead', 'Activates and deactivates MTP; directs clinical management; communicates with Blood Bank; ensures consent or documents emergency exception.'], [3500, 7000]),
    dataRow(['Blood Bank Medical Officer (BBMO)', 'Receives activation call; prepares and releases MTP packs within target times; monitors inventory; advises on component therapy; documents all issues.'], [3500, 7000], MID_GREY),
    dataRow(['Blood Bank Technician', 'Prepares MTP coolers; labels components; performs urgent blood grouping and crossmatch; documents all releases.'], [3500, 7000]),
    dataRow(['Nursing Staff (Clinical Area)', 'Draws pre-transfusion samples; administers products safely; monitors patient; records vital signs per unit; documents in medical record.'], [3500, 7000], MID_GREY),
    dataRow(['Runner / Porter', 'Transports MTP coolers between Blood Bank and clinical area within defined time targets; maintains chain of custody.'], [3500, 7000]),
    dataRow(['Hospital Transfusion Committee (HTC)', 'Reviews all MTP activations; monitors quality indicators; revises SOP annually or after adverse event.'], [3500, 7000], MID_GREY),
  ],
});

const sec4 = [
  h1('4. RESPONSIBILITIES'),
  respTable,
];

// ── Section 5: Activation Criteria ───────────────────────────────────────────
const abcTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Parameter', 'Positive Finding (Score = 1)'], [4000, 6500]),
    dataRow(['Mechanism of injury', 'Penetrating trauma'], [4000, 6500]),
    dataRow(['Systolic BP on arrival', '≤ 90 mmHg'], [4000, 6500], MID_GREY),
    dataRow(['Heart rate on arrival', '≥ 120 beats/min'], [4000, 6500]),
    dataRow(['FAST / eFAST', 'Positive (free fluid in abdomen or pericardium)'], [4000, 6500], MID_GREY),
  ],
});

const sec5 = [
  h1('5. CRITERIA FOR MTP ACTIVATION'),
  h2('5.1  ABC Score — Assessment of Blood Consumption (Activate if Score ≥ 2)'),
  abcTable,
  ...spacer(1),
  new Paragraph({
    children: [new TextRun({ text: 'Score ≥ 2 → Activate MTP   |   Score < 2 → Continue standard resuscitation and reassess', font: FONT, size: 22, bold: true, color: WHITE })],
    alignment: AlignmentType.CENTER,
    spacing: { before: 80, after: 80 },
    shading: { type: ShadingType.SOLID, color: MID_RED, fill: MID_RED },
  }),
  ...spacer(1),
  h2('5.2  Additional Clinical Triggers'),
  bullet('Active haemorrhage with haemodynamic instability not responding to 2 L crystalloid bolus'),
  bullet('Postpartum haemorrhage (PPH) > 1000 mL with ongoing bleeding — activate OB-MTP variant'),
  bullet('Intra-operative major vessel injury or damage-control laparotomy/thoracotomy'),
  bullet('Anticipated ≥ 50% blood volume replacement within < 3 h'),
  bullet('Clinician judgement overrides score in rapidly deteriorating patients'),
  h2('5.3  Exclusions'),
  bullet('Confirmed refractory cardiac arrest from non-haemorrhagic cause'),
  bullet('Written advance directive refusing transfusion — document in medical record and communicate with treating clinician'),
];

// ── Section 6: Procedure ──────────────────────────────────────────────────────
const sampleTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Sample', 'Tube / Volume', 'Purpose', 'Target Time'], [2500, 2200, 3500, 2300]),
    dataRow(['Type & Screen', '6 mL EDTA (pink top)', 'ABO/Rh grouping, antibody screen', '≤ 15 min'], [2500, 2200, 3500, 2300]),
    dataRow(['Crossmatch sample', '6 mL EDTA', 'Compatibility testing', 'Simultaneously'], [2500, 2200, 3500, 2300], MID_GREY),
    dataRow(['Coagulation panel', '3.2% sodium citrate', 'PT, INR, aPTT, Fibrinogen', '≤ 15 min'], [2500, 2200, 3500, 2300]),
    dataRow(['TEG / ROTEM (if available)', 'Citrated whole blood', 'Real-time clot function', 'ASAP'], [2500, 2200, 3500, 2300], MID_GREY),
    dataRow(['CBC, BMP, Lactate, iCa2+', 'As per local protocol', 'Baseline and monitoring', '≤ 15 min'], [2500, 2200, 3500, 2300]),
  ],
});

const mtpPackTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Pack/Cycle', 'PRBC (units)', 'FFP (units)', 'Platelets', 'Cryoprecipitate', 'Target Release'], [1500, 1800, 1800, 2000, 2000, 2400]),
    dataRow(['Pack 1 (Immediate)', '4 (O-pos/neg)', '4 (AB or A)', '—', '—', '5–10 min after activation'], [1500, 1800, 1800, 2000, 2000, 2400]),
    dataRow(['Pack 2', '4 (typed if available)', '4', '1 apheresis or 6 pooled', '—', 'On return of Pack 1 cooler'], [1500, 1800, 1800, 2000, 2000, 2400], MID_GREY),
    dataRow(['Pack 3 onwards', '4 (crossmatched)', '4', '1 apheresis or 6 pooled (alternate cycles)', '10 units if Fibrinogen < 1.5 g/L', 'Continue until deactivation'], [1500, 1800, 1800, 2000, 2000, 2400]),
  ],
});

const pedTable = new Table({
  width: { size: 60, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Component', '< 40 kg', '> 40 kg']),
    dataRow(['PRBC', '2 units', '4 units']),
    dataRow(['FFP', '2 units', '4 units'], undefined, MID_GREY),
    dataRow(['Platelets', '1 unit (odd cycles)', '1 unit (odd cycles)']),
  ],
});

const labMonTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Test', 'Target / Action Threshold', 'Frequency'], [3000, 4500, 3000]),
    dataRow(['Haemoglobin / Haematocrit', 'Hb > 7–8 g/dL (target during active haemorrhage)', 'Every 30–60 min'], [3000, 4500, 3000]),
    dataRow(['Platelet count', 'Maintain > 50 × 10⁹/L (> 100 × 10⁹/L if TBI)', 'Every 30–60 min'], [3000, 4500, 3000], MID_GREY),
    dataRow(['PT / INR', 'INR < 1.5 (give FFP if INR > 1.5)', 'Every 30–60 min'], [3000, 4500, 3000]),
    dataRow(['aPTT', '< 1.5 × normal (give FFP if elevated)', 'Every 30–60 min'], [3000, 4500, 3000], MID_GREY),
    dataRow(['Fibrinogen', '> 1.5 g/L (give Cryoprecipitate / Fibrinogen Concentrate if < 1.5 g/L)', 'Every 30–60 min'], [3000, 4500, 3000]),
    dataRow(['Ionised Calcium (iCa²⁺)', '> 1.1 mmol/L (give CaCl₂ 1–2 g IV per pack)', 'Every MTP cycle'], [3000, 4500, 3000], MID_GREY),
    dataRow(['ABG — pH', '> 7.35 (correct metabolic acidosis)', 'Every 30 min'], [3000, 4500, 3000]),
    dataRow(['Temperature', '> 35°C (use warming devices, warmed fluids)', 'Continuous'], [3000, 4500, 3000], MID_GREY),
    dataRow(['TEG / ROTEM (if available)', 'Goal-directed: ACT, angle, MA, LY30 / A10', 'Each pack cycle'], [3000, 4500, 3000]),
  ],
});

const sec6 = [
  h1('6. PROCEDURE'),

  h2('Step 1 — Activation'),
  para(txt('Designated caller contacts Blood Bank on MTP Hotline: Extension _________ (available 24 h / 7 days). Record time of call.', { bold: true })),
  ...spacer(1),
  para(txt('Information to provide (verbally or via HIS/EMR MTP order):', { bold: true })),
  bullet('Patient name / STAT name if unidentified'),
  bullet('Medical Record Number (MRN) or unique patient identifier'),
  bullet('Sex and approximate age (identify females of childbearing age for Rh-negative allocation)'),
  bullet('Ward / location and bed number'),
  bullet('Name of attending physician initiating MTP'),
  bullet('Type of haemorrhage: Trauma / Obstetric (OB-MTP) / Surgical / GI bleeding'),

  ...spacer(1),
  h2('Step 2 — Sample Collection (Target: within 15 min of activation)'),
  sampleTable,
  ...spacer(1),
  new Paragraph({
    children: [new TextRun({ text: 'NOTE: Draw samples BEFORE administering uncrossmatched blood whenever feasible. Even 1 unit of un-crossmatched PRBC can interfere with subsequent crossmatching.', font: FONT, size: 18, bold: true, color: DARK_RED })],
    shading: { type: ShadingType.SOLID, color: LIGHT_RED, fill: LIGHT_RED },
    spacing: { before: 80, after: 80 },
  }),

  ...spacer(1),
  h2('Step 3 — Blood Bank Response: Emergency Release & MTP Packs'),
  h3('A. Uncrossmatched Emergency Release (before type & screen result):'),
  bullet('Males and post-menopausal females (> 50 y): O-positive PRBC'),
  bullet('Females of childbearing age (≤ 50 y): O-negative PRBC [Reserve O-neg blood for this group]'),
  bullet('FFP: AB or group A as default until patient group is confirmed'),
  ...spacer(1),
  h3('B. MTP Pack Composition — Standard Adult (1:1:1 ratio):'),
  mtpPackTable,
  ...spacer(1),
  h3('C. Paediatric MTP (weight-based):'),
  pedTable,
  ...spacer(1),
  para([txt('OB-MTP Note: ', { bold: true, color: DARK_RED }), txt('Cryoprecipitate (2–5 pools) added in every other cycle starting from Cycle 2 for obstetric haemorrhage.')]),

  ...spacer(1),
  h2('Step 4 — Cooler Transport & Chain of Custody'),
  bullet('Blood Bank packs all products in a validated transport cooler (maintains 1–6°C for PRBC).'),
  bullet('A designated runner collects the cooler presenting patient ID label with ≥ 2 identifiers.'),
  bullet('Runner and Blood Bank staff perform verbal read-back to confirm correct cooler is released.'),
  bullet('Target transport time: Blood Bank to clinical area ≤ 5 minutes.'),
  bullet('Any unused products from a cooler cycle returned to Blood Bank immediately.'),

  ...spacer(1),
  h2('Step 5 — Clinical Management at Bedside'),
  h3('5a. Administer Tranexamic Acid (TXA):'),
  bullet('Dose: 1 g IV over 10 min within 1 h of injury onset (maximum benefit); repeat 1 g over 8 h.'),
  bullet('Maximum window: administer within 3 h of injury/haemorrhage onset — NO benefit after 3 h.'),
  bullet('Evidence: CRASH-2 Trial (Lancet 2010); WOMAN Trial (Lancet 2017) for PPH.'),
  ...spacer(1),
  h3('5b. Calcium Replacement (Mandatory with every MTP cycle):'),
  bullet('CaCl₂ 1 g IV (10 mL of 10% solution) per MTP cycle or every 4 units PRBC.'),
  bullet('Monitor ionised calcium (iCa²⁺) — target > 1.1 mmol/L.'),
  bullet('Rationale: Citrate in PRBC and FFP chelates calcium → hypocalcaemia → impaired cardiac contractility and coagulation.'),
  ...spacer(1),
  h3('5c. Prevent & Treat the Lethal Triad:'),
  bullet('Hypothermia: Use warmed blood products (38°C), warm IV fluids, Bair Hugger® forced-air warming blanket, raise ambient OR temperature.'),
  bullet('Acidosis: Ensure adequate perfusion/oxygenation; consider sodium bicarbonate if pH < 7.1 and ventilator optimisation for intubated patients.'),
  bullet('Coagulopathy: Follow 1:1:1 ratio; use TEG/ROTEM for goal-directed therapy.'),
  ...spacer(1),
  h3('5d. Permissive Hypotension (Damage Control Resuscitation):'),
  bullet('Target SBP 80–90 mmHg (MAP ~50 mmHg) until surgical haemostasis achieved.'),
  bullet('Exception: Traumatic Brain Injury (TBI) — target MAP ≥ 80 mmHg.'),
  bullet('Minimise crystalloid (0.9% NaCl / Hartmann's) — avoid large volumes.'),
  ...spacer(1),
  h3('5e. Anticoagulant Reversal (if applicable):'),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: {
      top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
      insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    },
    rows: [
      headerRow(['Anticoagulant', 'Reversal Agent', 'Dose'], [3200, 3200, 4100]),
      dataRow(['Warfarin', 'PCC + Vitamin K', 'PCC 25–50 IU/kg IV + Vit K 10 mg IV slow'], [3200, 3200, 4100]),
      dataRow(['Dabigatran (DOAC)', 'Idarucizumab (Praxbind®)', '5 g IV (2 × 2.5 g vials)'], [3200, 3200, 4100], MID_GREY),
      dataRow(['Rivaroxaban / Apixaban', 'Andexanet alfa', 'Per local protocol / prescribing information'], [3200, 3200, 4100]),
      dataRow(['Unfractionated Heparin', 'Protamine sulphate', '1 mg per 100 units of heparin IV'], [3200, 3200, 4100], MID_GREY),
    ],
  }),

  ...spacer(1),
  h2('Step 6 — Laboratory Monitoring During MTP'),
  labMonTable,

  ...spacer(1),
  h2('Step 7 — MTP Deactivation'),
  para(txt('Deactivate MTP when ANY of the following criteria are met:', { bold: true })),
  bullet('Surgical / interventional haemostasis has been achieved and bleeding has stopped.'),
  bullet('Patient is haemodynamically stable: SBP > 90 mmHg, HR < 100/min without vasopressors.'),
  bullet('Lactate clearing (< 2 mmol/L) and base excess normalising.'),
  bullet('Clinician determines MTP is no longer required.'),
  bullet('Clinical futility — decision made in consultation with the team.'),
  ...spacer(1),
  para(txt('Deactivation Procedure:', { bold: true })),
  bullet('Attending physician calls Blood Bank on the MTP Hotline and states "MTP Deactivate" with patient ID and time.'),
  bullet('Blood Bank records deactivation time; stops preparation of further packs.'),
  bullet('All unused products returned to Blood Bank immediately for possible reissue.'),
  bullet('Post-MTP labs drawn: CBC, coagulation panel, iCa²⁺, ABG, fibrinogen.'),

  ...spacer(1),
  h2('Step 8 — Post-MTP Management'),
  bullet('Normalise temperature, pH, and calcium.'),
  bullet('Continue monitoring for complications: TACO, TRALI, hyperkalaemia, hypocalcaemia, DIC, acute haemolytic transfusion reaction.'),
  bullet('Consider VTE prophylaxis (LMWH) once bleeding is controlled and there is no contraindication.'),
  bullet('ICU / HDU admission for ongoing monitoring.'),
  bullet('HTC notification for post-event audit review.'),
];

// ── Section 7: Special Situations ────────────────────────────────────────────
const sec7 = [
  h1('7. SPECIAL SITUATIONS'),

  h2('7.1  TEG / ROTEM-Guided Therapy (if available)'),
  new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    borders: {
      top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
      insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
      insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    },
    rows: [
      headerRow(['TEG Parameter (Rapid TEG)', 'Abnormal Value', 'Recommended Action'], [3200, 2300, 5000]),
      dataRow(['ACT (Activated Clotting Time)', '> 128 sec', 'Transfuse FFP 2 units (+ PRBC)'], [3200, 2300, 5000]),
      dataRow(['Angle', '< 65°', 'Transfuse Cryoprecipitate 10 units (or Fibrinogen Concentrate 2–4 g)'], [3200, 2300, 5000], MID_GREY),
      dataRow(['MA (Maximum Amplitude)', '< 55 mm', 'Transfuse Platelets 1 apheresis unit (or 6 pooled)'], [3200, 2300, 5000]),
      dataRow(['LY30 (Lysis at 30 min)', '> 3%', 'Administer Tranexamic Acid 1 g IV'], [3200, 2300, 5000], MID_GREY),
    ],
  }),
  para([txt('If TEG/ROTEM is unavailable: ', { bold: true }), txt('Trigger FFP for PT/INR > 1.5×control, Cryoprecipitate for fibrinogen < 1.5 g/L, Platelets for count < 50 × 10⁹/L.')]),

  ...spacer(1),
  h2('7.2  Obstetric MTP (OB-MTP)'),
  bullet('Activate OB-MTP for PPH > 1000 mL with ongoing/uncontrolled bleeding.'),
  bullet('Pack composition same as standard adult MTP but add Cryoprecipitate (2–5 pools) from Cycle 2 onwards — fibrinogen is rapidly consumed in obstetric haemorrhage.'),
  bullet('Target fibrinogen > 2 g/L in PPH (higher than standard MTP threshold).'),
  bullet('Oxytocin 40 IU in 500 mL NS IV, ergometrine, misoprostol, carboprost as uterotonic adjuncts per Obstetrics team.'),
  bullet('Notify Obstetrics Consultant, Anaesthesia, and Blood Bank simultaneously at activation.'),

  ...spacer(1),
  h2('7.3  Paediatric MTP'),
  bullet('Activate for blood loss > 40 mL/kg or clinical signs of Class III/IV shock.'),
  bullet('Use weight-based dosing (see Pack table in Step 3C above).'),
  bullet('Paediatric specific: target Hb > 8 g/dL; platelet threshold > 100 × 10⁹/L in neonates.'),
  bullet('NICU: Consult Neonatologist; use irradiated, CMV-negative products.'),

  ...spacer(1),
  h2('7.4  Jehovah\'s Witness / Transfusion Refusal'),
  bullet('Make every attempt to obtain informed consent / refusal documentation.'),
  bullet('For competent adult: respect documented refusal; use alternatives (tranexamic acid, cell salvage, surgical haemostasis, iron).'),
  bullet('For minor or unconscious patient: consult ethics committee; document decision.'),
  bullet('Document all discussions and decisions in the medical record.'),
];

// ── Section 8: Documentation ─────────────────────────────────────────────────
const docTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Record / Form', 'Where Filed', 'Retention', 'Responsible Person'], [3200, 2500, 1800, 3000]),
    dataRow(['MTP Activation Log (Blood Bank)', 'Blood Bank Register / HIS', '10 years', 'BBMO / Technician'], [3200, 2500, 1800, 3000]),
    dataRow(['Blood Product Issue Record (component, volume, time, recipient)', 'Blood Bank + Patient file', '10 years', 'Blood Bank Technician'], [3200, 2500, 1800, 3000], MID_GREY),
    dataRow(['MTP Clinical Flow Sheet (bedside)', 'Patient medical record (EMR)', 'Permanent', 'Treating team / Nurse'], [3200, 2500, 1800, 3000]),
    dataRow(['Transfusion Consent Form or Emergency Exception Note', 'Patient medical record', 'Permanent', 'Treating clinician'], [3200, 2500, 1800, 3000], MID_GREY),
    dataRow(['Adverse Transfusion Reaction Report', 'Blood Bank + Quality Dept.', '10 years', 'BBMO + Treating team'], [3200, 2500, 1800, 3000]),
    dataRow(['Post-MTP Audit Sheet (HTC review)', 'Quality / HTC file', '5 years', 'HTC Convener'], [3200, 2500, 1800, 3000], MID_GREY),
  ],
});

const sec8 = [
  h1('8. DOCUMENTATION & RECORDS (NABH TPC.19-f)'),
  docTable,
];

// ── Section 9: Training ───────────────────────────────────────────────────────
const sec9 = [
  h1('9. TRAINING & COMPETENCY'),
  bullet('All Blood Bank staff complete MTP simulation training at induction and annually thereafter.'),
  bullet('Clinical staff (ED, OT, ICU, Obstetrics) complete MTP awareness training — minimum once per year.'),
  bullet('Mock MTP drills conducted at least twice per year; findings reviewed at HTC.'),
  bullet('Competency records maintained in the HR / training management system.'),
  bullet('New staff complete training before independent MTP activation is permitted.'),
];

// ── Section 10: Quality Indicators ───────────────────────────────────────────
const qiTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Quality Indicator', 'Target / Standard', 'Review Frequency'], [4500, 3500, 2500]),
    dataRow(['Time from MTP activation to first PRBC release', '≤ 10 minutes', 'Monthly'], [4500, 3500, 2500]),
    dataRow(['Time from activation to sample receipt in Blood Bank', '≤ 15 minutes', 'Monthly'], [4500, 3500, 2500], MID_GREY),
    dataRow(['TXA administered within 3 h of haemorrhage onset (eligible cases)', '≥ 90% of eligible cases', 'Monthly'], [4500, 3500, 2500]),
    dataRow(['PRBC : FFP ratio ≥ 1:1 achieved by end of MTP', '≥ 85% of MTP activations', 'Per event + Monthly'], [4500, 3500, 2500], MID_GREY),
    dataRow(['MTP activation-to-deactivation fully documented', '100%', 'Per event'], [4500, 3500, 2500]),
    dataRow(['Adverse transfusion reaction rate post-MTP', 'Monitor and trend; investigate all Grade ≥ 2', 'Per event + Monthly'], [4500, 3500, 2500], MID_GREY),
    dataRow(['Blood product wastage during MTP (unused units discarded)', 'Minimise; review each occurrence', 'Monthly'], [4500, 3500, 2500]),
    dataRow(['30-day mortality post-MTP', 'Benchmark vs national data', 'Quarterly'], [4500, 3500, 2500], MID_GREY),
  ],
});

const sec10 = [
  h1('10. QUALITY INDICATORS (NABH BSQ.7)'),
  qiTable,
];

// ── Section 11: Adverse Reactions ────────────────────────────────────────────
const sec11 = [
  h1('11. ADVERSE TRANSFUSION REACTIONS (NABH TPC.20)'),
  para(txt('If a suspected adverse transfusion reaction occurs:', { bold: true, color: DARK_RED })),
  bullet('STOP the transfusion immediately.'),
  bullet('Maintain IV access; administer 0.9% NaCl to keep vein open.'),
  bullet('Notify treating clinician and Blood Bank Medical Officer immediately.'),
  bullet('Check patient identity and blood pack label for clerical error (wrong blood in wrong patient).'),
  bullet('Return blood pack, tubing, and IV fluid bag (do not discard) to Blood Bank with post-transfusion samples (EDTA, plain tube, fresh urine).'),
  bullet('Complete Adverse Transfusion Reaction Form.'),
  bullet('Serious reactions (AHTR, TRALI, TACO, TTI) reported to Haemovigilance System and Quality Department.'),
  bullet('Root cause analysis (RCA) for severe / unexpected reactions; CAPA plan reviewed at HTC.'),
];

// ── Section 12: References ────────────────────────────────────────────────────
const sec12 = [
  h1('12. REFERENCES'),
  bullet('NABH Accreditation Standards for Blood Centres and Transfusion Services, 4th Edition. Standards: TPC.19, TPC.20, BSQ.1, BSQ.7, BSQ.11.'),
  bullet('Holcomb JB et al. PROPPR Trial: Transfusion of Plasma, Platelets, and Red Blood Cells in a 1:1:1 vs 1:1:2 Ratio and Mortality in Patients with Severe Trauma. JAMA. 2015;313(5):471–482.'),
  bullet('CRASH-2 Collaborators. Effects of tranexamic acid on death, vascular occlusive events, and blood transfusion in trauma patients with significant haemorrhage. Lancet. 2010;376:23–32.'),
  bullet('Shakur H et al. (WOMAN Trial). Effect of early tranexamic acid on mortality and hysterectomy in women with post-partum haemorrhage. Lancet. 2017;389:2105–2116.'),
  bullet('Schwartz\'s Principles of Surgery, 11th Edition. Chapter 7: Trauma. McGraw-Hill, 2019. (Denver Health MTP flowchart)'),
  bullet('Sabiston Textbook of Surgery, 21st Edition. Chapter: Damage Control Resuscitation. Elsevier, 2022.'),
  bullet('Tintinalli\'s Emergency Medicine, 9th Edition. Chapter 13: Massive Transfusion. McGraw-Hill, 2020.'),
  bullet('National Blood Policy, Ministry of Health & Family Welfare, Government of India.'),
  bullet('Drugs and Cosmetics Act, 1940 (amended) — Schedule F: Blood Bank licensing requirements.'),
];

// ── Section 13: SOP Control ───────────────────────────────────────────────────
const versionTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED },
    insideH: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Version', 'Effective Date', 'Changes Made', 'Changed By']),
    dataRow(['01 / 00', '___________', 'Initial version', 'Dr. ___________']),
    dataRow(['', '', '', ''], undefined, MID_GREY),
  ],
});

const authTable = new Table({
  width: { size: 100, type: WidthType.PERCENTAGE },
  borders: {
    top: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    bottom: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    left: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    right: { style: BorderStyle.SINGLE, size: 6, color: DARK_RED },
    insideV: { style: BorderStyle.SINGLE, size: 4, color: 'CCCCCC' },
  },
  rows: [
    headerRow(['Prepared By', 'Reviewed By', 'Approved By']),
    new TableRow({ children: [
      new TableCell({
        children: [
          new Paragraph({ children: [new TextRun({ text: 'Name: ___________________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Designation: _____________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Signature: _______________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Date: ___________________', font: FONT, size: 18 })], spacing: { before: 60, after: 80 } }),
        ],
        margins: { top: 80, bottom: 80, left: 120, right: 120 },
      }),
      new TableCell({
        children: [
          new Paragraph({ children: [new TextRun({ text: 'Name: ___________________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Designation: _____________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Signature: _______________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Date: ___________________', font: FONT, size: 18 })], spacing: { before: 60, after: 80 } }),
        ],
        margins: { top: 80, bottom: 80, left: 120, right: 120 },
      }),
      new TableCell({
        children: [
          new Paragraph({ children: [new TextRun({ text: 'Name: ___________________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Designation: _____________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Signature: _______________', font: FONT, size: 18 })], spacing: { before: 60, after: 60 } }),
          new Paragraph({ children: [new TextRun({ text: 'Date: ___________________', font: FONT, size: 18 })], spacing: { before: 60, after: 80 } }),
        ],
        margins: { top: 80, bottom: 80, left: 120, right: 120 },
      }),
    ]}),
  ],
});

const sec13 = [
  h1('13. SOP CONTROL & REVIEW'),
  versionTable,
  ...spacer(1),
  para(txt('This SOP is reviewed annually by the HTC or earlier if triggered by:')),
  bullet('Adverse event / sentinel event related to MTP'),
  bullet('Changes in national blood transfusion guidelines'),
  bullet('NABH inspection findings'),
  bullet('Mock drill audit findings'),
  ...spacer(2),
  para(txt('Authorisation Signatures', { bold: true, size: 22 }), { align: AlignmentType.CENTER }),
  ...spacer(1),
  authTable,
  ...spacer(2),
  new Paragraph({
    children: [new TextRun({ text: 'CONTROLLED DOCUMENT — Uncontrolled copies are valid only on the date of printing. Verify version on the Document Management System before use.', font: FONT, size: 16, bold: true, color: WHITE })],
    alignment: AlignmentType.CENTER,
    spacing: { before: 80, after: 80 },
    shading: { type: ShadingType.SOLID, color: DARK_GREY, fill: DARK_GREY },
  }),
];

// ── Assemble Document ─────────────────────────────────────────────────────────
const doc = new Document({
  styles: {
    default: {
      document: {
        run: { font: FONT, size: 20, color: BLACK },
      },
    },
  },
  sections: [{
    properties: {
      page: {
        margin: { top: 720, bottom: 720, left: 900, right: 900 },
      },
    },
    headers: {
      default: new Header({
        children: [
          new Paragraph({
            children: [
              new TextRun({ text: 'SOP: Massive Transfusion Protocol (MTP)  |  BB/SOP/MTP/01  |  Version 01/00', font: FONT, size: 16, color: '666666' }),
              new TextRun({ text: '    Page ', font: FONT, size: 16, color: '666666' }),
              new PageNumber({ font: FONT, size: 16, color: '666666' }),
            ],
            alignment: AlignmentType.RIGHT,
            border: { bottom: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED } },
            spacing: { after: 80 },
          }),
        ],
      }),
    },
    footers: {
      default: new Footer({
        children: [
          new Paragraph({
            children: [new TextRun({ text: 'Department of Blood Bank & Transfusion Medicine  |  NABH Ref: TPC.19(e), BSQ.1, BSQ.7  |  UNCONTROLLED IF PRINTED', font: FONT, size: 14, color: '888888', italics: true })],
            alignment: AlignmentType.CENTER,
            border: { top: { style: BorderStyle.SINGLE, size: 4, color: DARK_RED } },
            spacing: { before: 80 },
          }),
        ],
      }),
    },
    children: [
      coverTable,
      ...spacer(1),
      metaTable,
      ...spacer(2),
      ...sec1,
      ...spacer(1),
      ...sec2,
      ...spacer(1),
      ...sec3,
      ...spacer(1),
      ...sec4,
      ...spacer(1),
      ...sec5,
      ...spacer(1),
      ...sec6,
      ...spacer(1),
      ...sec7,
      ...spacer(1),
      ...sec8,
      ...spacer(1),
      ...sec9,
      ...spacer(1),
      ...sec10,
      ...spacer(1),
      ...sec11,
      ...spacer(1),
      ...sec12,
      ...spacer(1),
      ...sec13,
    ],
  }],
});

Packer.toBuffer(doc).then(buf => {
  fs.writeFileSync('/home/daytona/workspace/mtp-sop/SOP_Massive_Transfusion_Protocol.docx', buf);
  console.log('Done: SOP_Massive_Transfusion_Protocol.docx');
}).catch(err => { console.error(err); process.exit(1); });
Running Command

cd /home/daytona/workspace/mtp-sop && node build_mtp_final.js 2>&1

Editing File

~/mtp-sop/build_mtp_final.js

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mtp-sop/build_mtp_final.js'
Running Command

cd /home/daytona/workspace/mtp-sop && node build_mtp_final.js 2>&1

Editing File

~/mtp-sop/build_mtp_final.js

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mtp-sop/build_mtp_final.js'
Editing File

~/mtp-sop/build_mtp_final.js

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/mtp-sop/build_mtp_final.js'
Running Command

cd /home/daytona/workspace/mtp-sop && node build_mtp_final.js 2>&1 && python /home/daytona/skills/docx/scripts/office/validate.py SOP_Massive_Transfusion_Protocol.docx 2>&1 | tail -15

Your credits are exhausted. Your daily credits reset tomorrow, or you can purchase a top-up for more.
This is a shared conversation. Sign in to Orris to start your own chat.