explain me all types of pyeloplasty done for puj obstruction

Reading File
Finding Sources
Finding Sources
Searching PubMed

pyeloplasty "ureteropelvic junction" obstruction techniques

Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Loading Image
Loading Image
I now have comprehensive information from Campbell-Walsh-Wein Urology and Hinman's Atlas of Urologic Surgery. Let me compose the full, detailed answer.

Pyeloplasty for Pelviureteric Junction (PUJ) Obstruction - All Types

Pyeloplasty is the gold-standard surgical treatment for PUJ (UPJ) obstruction. The goal is to excise or reconfigure the obstructed/aperistaltic segment, creating a wide, dependent, funnel-shaped anastomosis that allows gravity-assisted urine drainage. The overall success rate of open dismembered pyeloplasty is approximately 95%, and minimally invasive approaches achieve equivalent outcomes.

Classification Overview

CategoryTechniques
Dismembered (excisional)Anderson-Hynes pyeloplasty
Non-dismembered (flap)Foley Y-V plasty, Fenger (Heineke-Mikulicz) pyeloplasty, Spiral flap, Vertical flap, Tubularized flap
Non-dismembered (other)Davis Intubated Ureterotomy, Hellstrom Vascular Hitch
By surgical approachOpen (flank/lumbotomy), Laparoscopic, Robotic-assisted, LESS (single-site)
Endoscopic (non-reconstructive)Endopyelotomy (antegrade/retrograde), Balloon dilation

I. DISMEMBERED PYELOPLASTY

Anderson-Hynes Dismembered Pyeloplasty (GOLD STANDARD)

The most universally applicable technique and the standard against which all other interventions are compared. Success rate ~95%.
Principle: The UPJ is completely excised (dismembered), the obstructed/aperistaltic segment removed, the ureter spatulated laterally, and a tension-free, dependent anastomosis constructed between the renal pelvis and healthy ureter. A redundant pelvis can be reduced simultaneously.
Advantages:
  • Applicable to virtually all anatomical configurations (high insertion, dependent UPJ, anomalous vasculature)
  • Permits complete excision of the dysplastic/aperistaltic segment
  • Allows transposition of the UPJ anterior to crossing lower pole vessels
  • Redundant pelvis can be reduced (reduction pyeloplasty)
  • A tortuous proximal ureter can be straightened
Technique (key steps):
  1. Open Gerota's fascia; expose the UPJ and free the lower renal pole
  2. Place stay sutures on the medial and lateral pelvis and on the ureter below the obstruction
  3. Dismember the UPJ; reduce the pelvis if redundant
  4. Spatulate the ureter along its lateral border, well into healthy tissue
  5. Bring the apex of the lateral spatulated ureter to the inferior border of the pelvis; the medial ureter to the superior edge
  6. Complete anastomosis with interrupted or running 5-0/6-0 absorbable monofilament on a round needle - watertight, tension-free
  7. Place a ureteral stent (internal double-J or externalized nephro-ureteric stent, per surgeon preference)
Specific indication for accessory vessels: The dismembered technique allows the ureter to be swung anterior to crossing lower pole vessels so the new anastomosis lies ventral to them.
Contraindications: Long/multiple proximal ureteral strictures; small, intrarenal pelvis with limited access.
  • Campbell-Walsh-Wein Urology, p. 2605; Campbell-Walsh-Wein block19

II. NON-DISMEMBERED (FLAP) PYELOPLASTIES

These techniques keep the UPJ intact and use pelvic or ureteral flaps to widen the obstructed segment. They are contraindicated when crossing vessels need transposition. They are largely replaced by Anderson-Hynes but remain useful in specific anatomical scenarios.

1. Foley Y-V Plasty

Original indication: PUJ obstruction secondary to high ureteral insertion into the pelvis (ureter inserts into the apex/superior wall of the pelvis rather than dependently).
Principle: A V-shaped (triangular, widely-based) flap is fashioned from the inferior/dependent part of the renal pelvis, with the apex at the UPJ. The incision (stem of the Y) extends down the lateral aspect of the proximal ureter through the stenotic segment. The pelvic flap is then advanced down and sutured into the ureterotomy, converting the Y incision into a V (or V into Y, depending on perspective) - effectively widening the UPJ.
Technique:
  • Outline a V-shaped flap with the base on the dependent, medial pelvis and apex at the UPJ
  • Incise from the apex down the lateral ureter, past the stenosis into normal ureter
  • Advance the apex of the pelvic flap to the inferior end of the ureterotomy
  • Close in a Y configuration with fine absorbable sutures
Limitations/Contraindications:
  • Cannot be used when lower pole vessel transposition is needed
  • Of little value if pelvis reduction is required
  • Success rate ~86% vs. 95% for Anderson-Hynes (Szydelko et al.)
  • Specifically contraindicated in the presence of a crossing vessel requiring anterior transposition
  • Campbell-Walsh-Wein Urology, p. 2612

2. Fenger Pyeloplasty (Heineke-Mikulicz Pyeloplasty)

Principle: Based on the Heineke-Mikulicz pyloroplasty principle - a short longitudinal incision across the UPJ is closed transversely, widening the narrowed segment without excising it.
Indication: Short, intrinsic UPJ narrowing without high insertion or need for vessel transposition. Suitable for short stenoses.
Technique:
  • A longitudinal incision is made across the narrowed UPJ (spanning the stenosis)
  • The incision is then closed transversely with interrupted absorbable sutures
  • This converts a short longitudinal stricture into a widened lumen
Limitation: Only applicable to very short, localized stenoses. Not versatile. Largely replaced by dismembered pyeloplasty.
  • Hinman's Atlas of Urologic Surgery; Smith and Tanagho's General Urology, p. 176

3. Spiral Flap Pyeloplasty (Culp-DeWeerd / Scardino-Prince)

Indication: Long proximal ureteral stenosis where tension-free primary anastomosis (as in Anderson-Hynes) is impossible. Used when the UPJ is already in a dependent position but a long segment of proximal ureter is obstructed.
Principle: A long spiraling flap is developed from the renal pelvis, with its base at the dependent UPJ. The flap spirals posteriorly-to-anteriorly (or vice versa). The medial incision of the flap is carried down through the entire strictured proximal ureteral segment. The apex of the flap is then rotated down to bridge the ureteral defect.
Key rule: Flap length-to-width ratio must not exceed 3:1 to preserve vascular integrity of the flap.
Spiral flap and vertical flap pyeloplasty diagrams
Fig. 42.8 - Vertical flap technique; the spiral flap follows similar principles with oblique base orientation. (Campbell-Walsh-Wein)
  • Campbell-Walsh-Wein Urology, block19, Fig. 42.9

4. Vertical Flap Pyeloplasty

Indication: Similar to spiral flap - used for long proximal ureteral obstruction when the UPJ is at the medial margin of a large, box-shaped extrarenal pelvis.
Difference from spiral flap: The base of the flap is oriented more horizontally (between the UPJ and renal parenchyma), and the flap is formed by two straight converging incisions from the base up to the apex (anterior or posterior pelvic wall). The apex is rotated down to the inferior ureterotomy.

5. Tubularized Flap Pyeloplasty

Indication: Significant upper ureteral defect after excision of a long UPJ stricture - when a 3+ cm ureteral gap exists and primary anastomosis is impossible.
Technique: A wide-based pelvic flap is created and tubularized (rolled over a stent/catheter) to bridge the ureteral gap. The flap is sutured over itself to create a new ureteral tube.
Laparoscopic version described by Kaouk et al. (2002): Used a four-port transperitoneal approach with intracorporeal freehand suturing for a 3 cm ureteral defect.
  • Campbell-Walsh-Wein Urology, p. 2612

III. OTHER UPJ RECONSTRUCTION TECHNIQUES

Davis Intubated Ureterotomy

Indication: Lengthy or multiple ureteral strictures at or near the UPJ - rarely used today.
Principle: A longitudinal incision is made through the entire length of the strictured segment. A stent (intubated ureterotomy stent) is left in situ for 4-6 weeks. Urothelial regeneration occurs over the stent, healing the incised stricture by secondary re-epithelialisation.
Limitation: High recurrence rate; unpredictable healing. Largely abandoned in favor of pyeloplasty.

Hellstrom Vascular Hitch (Vascular Relocation / "Laparoscopic Hitch")

Indication: PUJ obstruction caused exclusively by an anterior crossing lower pole vessel with no intrinsic UPJ stenosis. The ureter and UPJ itself are functionally normal.
Principle: The crossing vessel is mobilized off the UPJ and "hitched" (sutured) cranially onto the renal pelvic tissue, removing the extrinsic compression without any ureteral reconstruction.
Patient selection criteria (Gundeti et al.): Moderate hydronephrosis, no calyceal dilation, preserved renal cortex, poor drainage with preserved split function, lower pole crossing vessel confirmed - AND intraoperatively: normal-caliber ureter and UPJ with active peristalsis.
Caution: Long-term results are limited compared to Anderson-Hynes. Only appropriate when truly no intrinsic obstruction exists.
  • Campbell-Walsh-Wein Urology, block19, Fig. 42.15

IV. BY SURGICAL APPROACH

A. Open Pyeloplasty

Approaches:
  • Flank incision - most common; subcostal or transcostal
  • Posterior lumbotomy (dorsal lumbotomy) - prone position; reserved for infants and toddlers (increasing dorsal musculature with age makes this difficult); gives direct posterior access to the UPJ
  • Anterior (subcostal/transabdominal) - useful for horseshoe or malrotated kidneys
  • Transmesocolic approach - for left-sided cases, incision through the mesocolon without mobilizing the colon; ideal for pediatric/thin patients, horseshoe kidneys, malrotated kidneys with distorted pelvic anatomy
Success rate of open pyeloplasty: ~95% (Clark and Malek, 1987 - 111 patients, 15-year review: 95% symptomatic success, 91% radiographic decompression).

B. Laparoscopic Pyeloplasty

First described in 1993 (Kavoussi and Peters). Now the method of choice at many centers, with success rates >95% in experienced hands.
Approaches:
  1. Transperitoneal (transabdominal) - most widely used; largest working space; familiar anatomy; standard for adults
  2. Retroperitoneal (retroperitoneoscopic) - avoids peritoneal cavity; shorter path to UPJ; preferred at some centers, especially for redo cases or prior abdominal surgery; some evidence of shorter hospital stay and faster recovery vs. transperitoneal
  3. Hand-assisted - bridge technique for surgeons building laparoscopic skills
Most laparoscopic pyeloplasties use the Anderson-Hynes technique. Y-V plasty, Heineke-Mikulicz, Davis intubated ureterotomy, Hellstrom vascular relocation, and tubularized flap have all been described laparoscopically.
A meta-analysis (Autorino et al., 2014) confirmed laparoscopic pyeloplasty outcome is comparable to open surgery, with robotic as an attractive alternative.
  • Smith and Tanagho's General Urology, 19th ed., p. 176

C. Robotic-Assisted Pyeloplasty

First published ~2004 (Olsen and Jorgensen; Kutikov et al.). Has become increasingly popular, particularly in pediatric urology.
Advantages:
  • Articulated wristed instruments ease intracorporeal suturing (the most technically demanding part)
  • Shorter learning curve than pure laparoscopy
  • Especially useful in children where the working space is limited
  • Comparable success rates to laparoscopic and open pyeloplasty
Approaches:
  • Standard multiport robotic (transperitoneal) - most common
  • Retroperitoneal robotic
  • Single-port robotic (SP robot) - emerging; comparable outcomes with better cosmesis (meta-analysis Yang et al., 2025, PMID 40016552)
A 2025 meta-analysis (Kuiqing et al., J Robot Surg 2025) confirmed robotic-assisted pyeloplasty is equivalent or superior to conventional laparoscopic pyeloplasty in pediatric patients across efficacy, safety, and age-stratified outcomes.

D. Laparoendoscopic Single-Site (LESS) and Robotic LESS (R-LESS) Pyeloplasty

Principle: All instruments and the camera enter through a single port (typically at the umbilicus via a multichannel port such as GelPoint). Produces near-invisible cosmetic result.
Technique: 2 pediatric robotic trocars + 2 standard 12 mm trocars (camera + assistant), placed 3 cm apart in a diamond configuration at the umbilicus.
Success rate: ~93% symptomatic and radiographic success (Harrow et al., 2013).
Limitation: Technically demanding due to instrument clashing ("swordfighting"); future robotic purpose-built systems will improve adoption.
  • Hinman's Atlas of Urologic Surgery, p. 207

V. ENDOSCOPIC (ABLATIVE / NON-RECONSTRUCTIVE) APPROACHES

These are not true "pyeloplasties" but are included for comparison as they address PUJ obstruction.

Endopyelotomy

Routes:
  • Antegrade (percutaneous) - access via percutaneous nephrostomy tract; rigid nephroscope visualizes UPJ; lateral full-thickness incision with cutting balloon (or cold knife/Acucise wire) until periureteral fat is seen; endopyelotomy stent left for 6 weeks
  • Retrograde (ureteroscopic) - access via urethra and ureter; laser or cold knife incision of UPJ
Results: Significantly inferior to pyeloplasty - success rate ~65-75% (vs. 95% for pyeloplasty). Best results with: short strictures (<1 cm), no crossing vessel, and preserved renal function.
Contraindication: Crossing lower pole vessel (risk of hemorrhage).
  • Hinman's Atlas of Urologic Surgery, p. 164

Summary Table

TechniqueBest ForKey FeatureSuccess Rate
Anderson-HynesAll scenarios (gold standard)Dismembered; full excision; vessel transposition possible~95%
Foley Y-VHigh ureteral insertionNon-dismembered V flap; no vessel transposition~86%
Fenger (H-M)Short intrinsic stenosisLongitudinal incision closed transverselyLimited use
Spiral flapLong proximal ureteral stricture, dependent UPJLong spiraling pelvic flap bridges defectGood, limited data
Vertical flapLong stricture, box-shaped extrarenal pelvisStraight flap, horizontal baseSimilar to spiral
Tubularized flapLarge ureteral gap (3+ cm)Pelvic tissue tubularized to form new ureterCase reports
Davis intubated ureterotomyLong/multiple strictures (rare)Incise + stent; heals by re-epithelializationPoor; abandoned
Hellstrom vascular hitchCrossing vessel, NO intrinsic stenosisVessel repositioned craniallyComparable to dismembered (select cases)
Laparoscopic (transperitoneal/retroperitoneal)Standard minimally invasiveAny of above techniques; ~same success as open>95%
Robotic-assistedChildren, complex casesEasier intracorporeal suturing>95%
LESS/R-LESSCosmetically conscious patientsSingle umbilical incision~93%
EndopyelotomyShort stricture, no crossing vesselIncisional only; no reconstruction~65-75%

Key Points from Campbell-Walsh-Wein

  1. Anderson-Hynes dismembered pyeloplasty is the gold standard - applicable to almost all clinical scenarios, especially when crossing vessels are present.
  2. Flap techniques (Y-V, spiral, vertical) are reserved for specific anatomical situations - high insertion or long proximal ureteral strictures. They cannot be used when vessel transposition is needed.
  3. Laparoscopic and robotic approaches achieve equivalent outcomes to open surgery with less morbidity.
  4. Stenting is preferred by most surgeons (external nephro-ureteric or internal double-J) to reduce anastomotic leaks and urinary ascites.
  5. Retroperitoneal approach offers shorter hospital stay and faster recovery but is more technically demanding, especially in adults.
  6. Endopyelotomy yields inferior results compared to any form of pyeloplasty and should be avoided when crossing vessels are present.

Sources: Campbell-Walsh-Wein Urology, 3-Volume Set (Dismembered Pyeloplasty p. 2605, Other Reconstructive Procedures p. 2612, Laparoscopic/Robotic pp. 2100-2151); Hinman's Atlas of Urologic Surgery (Pyeloplasty p. 164, Transmesocolic p. 207, LESS p. 207); Smith and Tanagho's General Urology, 19th ed. (p. 176); Recent meta-analyses: PMID 40753141 (robotic vs. laparoscopic, 2025), PMID 40016552 (single-port vs. multiport robotic, 2025)

Make a PDF quick-reference guide for pyeloplasty techniques and approaches

Reading File
Running Command

ls -la /home/daytona/workspace/

Running Command

mkdir -p /home/daytona/workspace/pyeloplasty-guide && python3 -c "from reportlab.lib.pagesizes import A4; print('reportlab OK')" && python3 -c "from reportlab.platypus import SimpleDocTemplate; print('platypus OK')"

Writing File

~/pyeloplasty-guide/build_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether, PageBreak
)
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Polygon, Circle
from reportlab.graphics import renderPDF
from reportlab.platypus.flowables import Flowable
import os

OUTPUT = "/home/daytona/workspace/pyeloplasty-guide/Pyeloplasty_Quick_Reference.pdf"

# ─── Colour palette ───────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor("#1A3557")   # headings / header bg
MID_BLUE    = colors.HexColor("#2E6DA4")   # sub-heading accent
LIGHT_BLUE  = colors.HexColor("#D6E8F7")   # table header bg
ACCENT_GOLD = colors.HexColor("#C9902A")   # gold standard badge
LIGHT_GOLD  = colors.HexColor("#FFF5E0")   # gold standard row bg
LIGHT_GREY  = colors.HexColor("#F4F6F9")   # alternating row
WHITE       = colors.white
RED_SOFT    = colors.HexColor("#B83232")   # contraindication text
GREEN_SOFT  = colors.HexColor("#2A7A3B")   # success rates
BORDER_GREY = colors.HexColor("#C0C8D4")

# ─── Styles ───────────────────────────────────────────────────────────────────
def make_styles():
    s = {}

    s["cover_title"] = ParagraphStyle(
        "cover_title",
        fontName="Helvetica-Bold",
        fontSize=22,
        textColor=WHITE,
        leading=28,
        alignment=TA_CENTER,
    )
    s["cover_subtitle"] = ParagraphStyle(
        "cover_subtitle",
        fontName="Helvetica",
        fontSize=12,
        textColor=colors.HexColor("#B8D4EE"),
        leading=16,
        alignment=TA_CENTER,
    )
    s["section_heading"] = ParagraphStyle(
        "section_heading",
        fontName="Helvetica-Bold",
        fontSize=13,
        textColor=WHITE,
        leading=18,
        spaceBefore=0,
        spaceAfter=4,
        leftIndent=0,
        borderPad=6,
        backColor=DARK_BLUE,
    )
    s["sub_heading"] = ParagraphStyle(
        "sub_heading",
        fontName="Helvetica-Bold",
        fontSize=10.5,
        textColor=DARK_BLUE,
        leading=14,
        spaceBefore=6,
        spaceAfter=2,
    )
    s["body"] = ParagraphStyle(
        "body",
        fontName="Helvetica",
        fontSize=9,
        textColor=colors.HexColor("#222222"),
        leading=13,
        spaceAfter=3,
        alignment=TA_JUSTIFY,
    )
    s["body_small"] = ParagraphStyle(
        "body_small",
        fontName="Helvetica",
        fontSize=8,
        textColor=colors.HexColor("#333333"),
        leading=11,
        spaceAfter=2,
        alignment=TA_LEFT,
    )
    s["bullet"] = ParagraphStyle(
        "bullet",
        fontName="Helvetica",
        fontSize=8.5,
        textColor=colors.HexColor("#222222"),
        leading=12,
        leftIndent=12,
        bulletIndent=0,
        spaceAfter=2,
    )
    s["cell_head"] = ParagraphStyle(
        "cell_head",
        fontName="Helvetica-Bold",
        fontSize=8.5,
        textColor=WHITE,
        leading=12,
        alignment=TA_CENTER,
    )
    s["cell_body"] = ParagraphStyle(
        "cell_body",
        fontName="Helvetica",
        fontSize=8,
        textColor=colors.HexColor("#111111"),
        leading=11,
        alignment=TA_LEFT,
    )
    s["cell_body_center"] = ParagraphStyle(
        "cell_body_center",
        fontName="Helvetica",
        fontSize=8,
        textColor=colors.HexColor("#111111"),
        leading=11,
        alignment=TA_CENTER,
    )
    s["cell_success"] = ParagraphStyle(
        "cell_success",
        fontName="Helvetica-Bold",
        fontSize=8,
        textColor=GREEN_SOFT,
        leading=11,
        alignment=TA_CENTER,
    )
    s["cell_contra"] = ParagraphStyle(
        "cell_contra",
        fontName="Helvetica",
        fontSize=7.5,
        textColor=RED_SOFT,
        leading=10.5,
        alignment=TA_LEFT,
    )
    s["gold_badge"] = ParagraphStyle(
        "gold_badge",
        fontName="Helvetica-Bold",
        fontSize=8.5,
        textColor=ACCENT_GOLD,
        leading=11,
        alignment=TA_CENTER,
    )
    s["footer"] = ParagraphStyle(
        "footer",
        fontName="Helvetica",
        fontSize=7,
        textColor=colors.HexColor("#888888"),
        leading=10,
        alignment=TA_CENTER,
    )
    s["caption"] = ParagraphStyle(
        "caption",
        fontName="Helvetica-Oblique",
        fontSize=7.5,
        textColor=colors.HexColor("#555555"),
        leading=10,
        alignment=TA_CENTER,
        spaceAfter=4,
    )
    return s

# ─── Helper: coloured section banner ─────────────────────────────────────────
class SectionBanner(Flowable):
    def __init__(self, text, width, bg=DARK_BLUE, fg=WHITE, font_size=12, height=22):
        super().__init__()
        self.text = text
        self._width = width
        self.bg = bg
        self.fg = fg
        self.font_size = font_size
        self._height = height

    def wrap(self, availW, availH):
        return self._width, self._height

    def draw(self):
        c = self.canv
        c.setFillColor(self.bg)
        c.roundRect(0, 0, self._width, self._height, 4, fill=1, stroke=0)
        c.setFillColor(self.fg)
        c.setFont("Helvetica-Bold", self.font_size)
        c.drawString(8, 6, self.text)


# ─── Helper: horizontal rule ──────────────────────────────────────────────────
def hrule(width, color=BORDER_GREY, thickness=0.5):
    return HRFlowable(width=width, thickness=thickness, color=color, spaceAfter=4, spaceBefore=4)


# ─── Cover page flowable ──────────────────────────────────────────────────────
class CoverPage(Flowable):
    def __init__(self, width, height):
        super().__init__()
        self._width = width
        self._height = height

    def wrap(self, availW, availH):
        return self._width, self._height

    def draw(self):
        c = self.canv
        w, h = self._width, self._height

        # Dark blue gradient background (solid for simplicity)
        c.setFillColor(DARK_BLUE)
        c.rect(0, 0, w, h, fill=1, stroke=0)

        # Decorative horizontal bands
        c.setFillColor(MID_BLUE)
        c.rect(0, h * 0.38, w, h * 0.25, fill=1, stroke=0)

        c.setFillColor(DARK_BLUE)
        c.rect(0, h * 0.40, w, h * 0.21, fill=1, stroke=0)

        # Top accent stripe
        c.setFillColor(ACCENT_GOLD)
        c.rect(0, h - 8, w, 8, fill=1, stroke=0)

        # Bottom accent stripe
        c.setFillColor(MID_BLUE)
        c.rect(0, 0, w, 6, fill=1, stroke=0)

        # Title text
        c.setFillColor(WHITE)
        c.setFont("Helvetica-Bold", 26)
        c.drawCentredString(w / 2, h * 0.70, "PYELOPLASTY")
        c.setFont("Helvetica-Bold", 20)
        c.drawCentredString(w / 2, h * 0.62, "Quick Reference Guide")

        # Subtitle
        c.setFillColor(colors.HexColor("#B8D4EE"))
        c.setFont("Helvetica", 12)
        c.drawCentredString(w / 2, h * 0.54, "Techniques & Surgical Approaches for PUJ Obstruction")

        # Horizontal gold rule under subtitle
        c.setStrokeColor(ACCENT_GOLD)
        c.setLineWidth(1.5)
        c.line(w * 0.2, h * 0.50, w * 0.8, h * 0.50)

        # Info box
        c.setFillColor(colors.HexColor("#0D2236"))
        c.roundRect(w * 0.12, h * 0.12, w * 0.76, h * 0.29, 6, fill=1, stroke=0)
        c.setStrokeColor(MID_BLUE)
        c.setLineWidth(1)
        c.roundRect(w * 0.12, h * 0.12, w * 0.76, h * 0.29, 6, fill=0, stroke=1)

        c.setFillColor(WHITE)
        c.setFont("Helvetica-Bold", 10)
        c.drawCentredString(w / 2, h * 0.37, "CONTENTS")

        items = [
            "I.   Anderson-Hynes Dismembered Pyeloplasty (Gold Standard)",
            "II.  Non-Dismembered Flap Techniques",
            "III. Other UPJ Reconstruction Methods",
            "IV.  Surgical Approaches (Open / Laparoscopic / Robotic)",
            "V.   Comparison Summary Table",
            "VI.  Stenting & Key Clinical Points",
        ]
        c.setFont("Helvetica", 8.5)
        c.setFillColor(colors.HexColor("#C8DDEF"))
        y = h * 0.33
        for item in items:
            c.drawCentredString(w / 2, y, item)
            y -= 13

        # Source attribution
        c.setFillColor(colors.HexColor("#7AAAC8"))
        c.setFont("Helvetica-Oblique", 7.5)
        c.drawCentredString(w / 2, h * 0.07,
            "Sources: Campbell-Walsh-Wein Urology | Hinman's Atlas of Urologic Surgery | Smith & Tanagho's General Urology")


# ─── Build document ───────────────────────────────────────────────────────────
def build():
    doc = SimpleDocTemplate(
        OUTPUT,
        pagesize=A4,
        leftMargin=18 * mm,
        rightMargin=18 * mm,
        topMargin=16 * mm,
        bottomMargin=16 * mm,
        title="Pyeloplasty Quick Reference Guide",
        author="Orris Medical Reference",
        subject="PUJ Obstruction Surgical Techniques",
    )

    W = A4[0] - 36 * mm  # usable width
    s = make_styles()
    story = []

    # ── Cover page ────────────────────────────────────────────────────────────
    story.append(CoverPage(W, 240 * mm))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION I – OVERVIEW & ANDERSON-HYNES
    # ══════════════════════════════════════════════════════════════════════════
    story.append(SectionBanner("SECTION I   Anderson-Hynes Dismembered Pyeloplasty", W, DARK_BLUE, WHITE, 11, 24))
    story.append(Spacer(1, 5))

    story.append(Paragraph(
        "The Anderson-Hynes dismembered pyeloplasty is the <b>gold standard</b> for repair of PUJ obstruction, "
        "applicable to virtually all clinical scenarios. The UPJ is completely excised, the aperistaltic segment "
        "removed, and a wide, dependent, tension-free anastomosis constructed. Success rate ~95%.",
        s["body"]
    ))
    story.append(Spacer(1, 4))

    # Two-column layout: Indications | Contraindications
    ind_data = [
        [Paragraph("<b>INDICATIONS</b>", s["cell_head"]),
         Paragraph("<b>ADVANTAGES</b>", s["cell_head"])],
        [
            Paragraph(
                "• All anatomical configurations\n"
                "• High or dependent ureteral insertion\n"
                "• Crossing/aberrant lower pole vessels\n"
                "• Redundant renal pelvis (reduction pyeloplasty)\n"
                "• Tortuous proximal ureter\n"
                "• Redo pyeloplasty\n"
                "• Most common first-line technique",
                s["cell_body"]
            ),
            Paragraph(
                "• Complete excision of dysplastic segment\n"
                "• UPJ transposition anterior to vessels possible\n"
                "• Pelvis reduction simultaneous\n"
                "• Universal applicability\n"
                "• Largest long-term outcome data\n"
                "• Suitable for open, laparoscopic, robotic\n"
                "• 95% success rate",
                s["cell_body"]
            ),
        ],
    ]
    ind_table = Table(ind_data, colWidths=[W * 0.49, W * 0.49], hAlign="LEFT")
    ind_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), MID_BLUE),
        ("BACKGROUND", (0, 1), (-1, 1), LIGHT_BLUE),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("ROUNDEDCORNERS", [4]),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 6),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
        ("LEFTPADDING", (0, 0), (-1, -1), 7),
        ("RIGHTPADDING", (0, 0), (-1, -1), 7),
    ]))
    story.append(ind_table)
    story.append(Spacer(1, 7))

    story.append(Paragraph("Surgical Steps", s["sub_heading"]))
    steps = [
        ("1", "Open Gerota's fascia; dissect UPJ and free lower renal pole. Inspect for crossing vessels."),
        ("2", "Place stay sutures on medial & lateral pelvis + lateral ureter below obstruction (orientation guide)."),
        ("3", "Dismember (excise) the UPJ. Aspirate tense pelvis with 21G needle before dismembering. Reduce redundant pelvis if needed."),
        ("4", "Spatulate the ureter along its LATERAL border, well beyond the dysplastic segment into healthy tissue."),
        ("5", "Bring apex of spatulated ureter to INFERIOR border of pelvis; medial ureter to SUPERIOR edge."),
        ("6", "Anastomose with 5-0 or 6-0 absorbable monofilament (round needle), interrupted or running, full-thickness, watertight."),
        ("7", "Place ureteral stent (internal double-J or externalized nephro-ureteric). Insert drain. Close Gerota's fascia."),
    ]
    steps_data = [[
        Paragraph(f"<b>{n}</b>", s["cell_body_center"]),
        Paragraph(txt, s["cell_body"])
    ] for n, txt in steps]
    steps_table = Table(steps_data, colWidths=[10 * mm, W - 10 * mm], hAlign="LEFT")
    steps_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (0, -1), DARK_BLUE),
        ("TEXTCOLOR", (0, 0), (0, -1), WHITE),
        ("BACKGROUND", (1, 0), (1, -1), WHITE),
        ("ROWBACKGROUNDS", (1, 0), (1, -1), [WHITE, LIGHT_GREY]),
        ("GRID", (0, 0), (-1, -1), 0.3, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(steps_table)
    story.append(Spacer(1, 6))

    # Crossing vessel note
    cv_data = [[
        Paragraph(
            "<b>CROSSING LOWER POLE VESSEL:</b>  After dismembering, swing the ureter ANTERIOR to the vessel "
            "before completing the anastomosis. The new UPJ lies ventral to the vessel. This is the key advantage "
            "of dismembered over flap techniques.",
            s["cell_body"]
        )
    ]]
    cv_table = Table(cv_data, colWidths=[W])
    cv_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), LIGHT_GOLD),
        ("BOX", (0, 0), (-1, -1), 1, ACCENT_GOLD),
        ("TOPPADDING", (0, 0), (-1, -1), 7),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 7),
        ("LEFTPADDING", (0, 0), (-1, -1), 10),
        ("RIGHTPADDING", (0, 0), (-1, -1), 10),
    ]))
    story.append(cv_table)

    story.append(Spacer(1, 10))

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION II – NON-DISMEMBERED FLAP TECHNIQUES
    # ══════════════════════════════════════════════════════════════════════════
    story.append(SectionBanner("SECTION II   Non-Dismembered Flap Pyeloplasties", W, MID_BLUE, WHITE, 11, 24))
    story.append(Spacer(1, 5))

    story.append(Paragraph(
        "Flap techniques preserve UPJ continuity and widen the obstruction using pelvic tissue. "
        "They are <b>universally contraindicated when crossing vessel transposition is needed</b>. "
        "Largely replaced by Anderson-Hynes but useful in specific anatomical scenarios.",
        s["body"]
    ))
    story.append(Spacer(1, 5))

    # --- Foley Y-V ---
    story.append(SectionBanner("  1.  Foley Y-V Plasty", W, colors.HexColor("#3A6B9A"), WHITE, 10, 20))
    story.append(Spacer(1, 4))

    foley_data = [
        [Paragraph("<b>Indication</b>", s["cell_head"]),
         Paragraph("<b>Technique</b>", s["cell_head"]),
         Paragraph("<b>Limitations</b>", s["cell_head"])],
        [
            Paragraph(
                "High ureteral insertion (ureter inserts into apex/superior wall of pelvis rather than dependently). "
                "No crossing vessels.",
                s["cell_body"]
            ),
            Paragraph(
                "V-shaped flap outlined on dependent/medial pelvis, apex at UPJ. "
                "Incision (stem of Y) down lateral ureter past stenosis into normal caliber. "
                "Pelvic flap apex advanced to inferior ureterotomy. Closed in Y configuration.",
                s["cell_body"]
            ),
            Paragraph(
                "• Cannot transpose crossing vessels\n"
                "• Cannot reduce redundant pelvis\n"
                "• Success ~86% vs 95% (Anderson-Hynes)\n"
                "• Not for long ureteral strictures",
                s["cell_contra"]
            ),
        ],
    ]
    foley_table = Table(foley_data, colWidths=[W * 0.22, W * 0.44, W * 0.31], hAlign="LEFT")
    foley_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#3A6B9A")),
        ("BACKGROUND", (0, 1), (-1, 1), LIGHT_BLUE),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(foley_table)
    story.append(Spacer(1, 6))

    # --- Fenger ---
    story.append(SectionBanner("  2.  Fenger Pyeloplasty (Heineke-Mikulicz Principle)", W, colors.HexColor("#3A6B9A"), WHITE, 10, 20))
    story.append(Spacer(1, 4))
    fenger_data = [
        [Paragraph("<b>Indication</b>", s["cell_head"]),
         Paragraph("<b>Technique</b>", s["cell_head"]),
         Paragraph("<b>Notes</b>", s["cell_head"])],
        [
            Paragraph("Short, localised intrinsic UPJ narrowing. No high insertion. No vessel transposition needed.", s["cell_body"]),
            Paragraph(
                "Longitudinal incision across the narrowed UPJ spanning the stenosis. "
                "Closed TRANSVERSELY with interrupted absorbable sutures — widens the lumen without excision. "
                "(Same principle as Heineke-Mikulicz pyloroplasty.)",
                s["cell_body"]
            ),
            Paragraph(
                "• Only for very short stenoses\n"
                "• Largely replaced by A-H\n"
                "• Simple technique\n"
                "• Can be done laparoscopically",
                s["cell_body"]
            ),
        ],
    ]
    fenger_table = Table(fenger_data, colWidths=[W * 0.22, W * 0.44, W * 0.31], hAlign="LEFT")
    fenger_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#3A6B9A")),
        ("BACKGROUND", (0, 1), (-1, 1), LIGHT_BLUE),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(fenger_table)
    story.append(Spacer(1, 6))

    # --- Spiral + Vertical flaps ---
    story.append(SectionBanner("  3.  Spiral Flap & Vertical Flap Pyeloplasty", W, colors.HexColor("#3A6B9A"), WHITE, 10, 20))
    story.append(Spacer(1, 4))
    flap_data = [
        [Paragraph("<b>Type</b>", s["cell_head"]),
         Paragraph("<b>Indication</b>", s["cell_head"]),
         Paragraph("<b>Technique Key Points</b>", s["cell_head"]),
         Paragraph("<b>Rule</b>", s["cell_head"])],
        [
            Paragraph("<b>Spiral Flap</b>\n(Culp-DeWeerd)", s["cell_body"]),
            Paragraph("Long proximal ureteral obstruction; UPJ already in dependent position", s["cell_body"]),
            Paragraph(
                "Oblique base on dependent pelvis. Flap spirals post-to-ant (or vice versa). "
                "Medial incision through entire stricture. Apex rotated to inferior ureterotomy.",
                s["cell_body"]
            ),
            Paragraph("Flap L:W ratio\nmax 3:1\n(vascular integrity)", s["cell_body"]),
        ],
        [
            Paragraph("<b>Vertical Flap</b>\n(Scardino-Prince)", s["cell_body"]),
            Paragraph("Long stricture; UPJ at medial margin of large box-shaped extrarenal pelvis", s["cell_body"]),
            Paragraph(
                "Horizontal base between UPJ and renal parenchyma. Two straight converging incisions to apex "
                "(ant or post pelvic wall). Apex rotated to inferior ureterotomy.",
                s["cell_body"]
            ),
            Paragraph("Flap L:W ratio\nmax 3:1", s["cell_body"]),
        ],
        [
            Paragraph("<b>Tubularized Flap</b>", s["cell_body"]),
            Paragraph("Large ureteral gap (3+ cm) after excision of long stricture; tension-free anastomosis impossible", s["cell_body"]),
            Paragraph(
                "Wide-based pelvic flap rolled/tubularized over stent to bridge the ureteral defect. "
                "Can be performed laparoscopically (Kaouk 2002).",
                s["cell_body"]
            ),
            Paragraph("Rarely needed;\nlimited data", s["cell_body"]),
        ],
    ]
    flap_table = Table(flap_data, colWidths=[W * 0.16, W * 0.25, W * 0.43, W * 0.14], hAlign="LEFT")
    flap_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#3A6B9A")),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [WHITE, LIGHT_GREY, LIGHT_BLUE]),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 5),
        ("RIGHTPADDING", (0, 0), (-1, -1), 5),
    ]))
    story.append(flap_table)

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION III – OTHER UPJ RECONSTRUCTION
    # ══════════════════════════════════════════════════════════════════════════
    story.append(SectionBanner("SECTION III   Other UPJ Reconstruction Methods", W, DARK_BLUE, WHITE, 11, 24))
    story.append(Spacer(1, 5))

    other_data = [
        [Paragraph("<b>Technique</b>", s["cell_head"]),
         Paragraph("<b>Indication</b>", s["cell_head"]),
         Paragraph("<b>Principle</b>", s["cell_head"]),
         Paragraph("<b>Notes / Status</b>", s["cell_head"])],
        [
            Paragraph("<b>Davis Intubated\nUreterotomy</b>", s["cell_body"]),
            Paragraph("Long or multiple ureteral strictures at/near UPJ", s["cell_body"]),
            Paragraph(
                "Longitudinal incision through entire stricture. Stent (intubating catheter) left for 4-6 weeks. "
                "Heals by secondary urothelial re-epithelialization over stent.",
                s["cell_body"]
            ),
            Paragraph("Rarely used today. High recurrence. Unpredictable healing. Largely abandoned.", s["cell_contra"]),
        ],
        [
            Paragraph("<b>Hellstrom\nVascular Hitch</b>", s["cell_body"]),
            Paragraph("Crossing lower pole vessel as SOLE cause; NO intrinsic UPJ stenosis", s["cell_body"]),
            Paragraph(
                "Crossing vessel mobilized off UPJ and sutured ('hitched') cranially onto renal pelvic tissue, "
                "eliminating extrinsic compression. No ureteral reconstruction.",
                s["cell_body"]
            ),
            Paragraph(
                "Select patients only (Gundeti criteria: moderate hydronephrosis, normal ureter/UPJ with peristalsis). "
                "Long-term data limited. Comparable to A-H in select cases (Madec 2016).",
                s["cell_body"]
            ),
        ],
        [
            Paragraph("<b>Bypass\nPyeloplasty</b>", s["cell_body"]),
            Paragraph("UPJ with near-dependent position; side-to-side anastomosis preferred", s["cell_body"]),
            Paragraph(
                "Side-to-side anastomosis of ureter and renal pelvis WITHOUT transecting the stenotic UPJ. "
                "New UPJ configured within 1 cm of lower pole parenchyma. Ureter kept anchored.",
                s["cell_body"]
            ),
            Paragraph("Feasible alternative; no systematic review available.", s["cell_body"]),
        ],
        [
            Paragraph("<b>Ureterocalicostomy</b>", s["cell_body"]),
            Paragraph("Failed pyeloplasty; severely scarred UPJ; small intrarenal pelvis inaccessible", s["cell_body"]),
            Paragraph(
                "Ureter anastomosed directly to the most dependent lower pole calyx after amputation of the "
                "lower pole parenchyma. Bypasses the scarred UPJ entirely.",
                s["cell_body"]
            ),
            Paragraph("Salvage procedure. Robotic-assisted variant described (RALUC - systematic review 2025).", s["cell_body"]),
        ],
    ]
    other_table = Table(other_data, colWidths=[W * 0.17, W * 0.22, W * 0.36, W * 0.23], hAlign="LEFT")
    other_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), DARK_BLUE),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [WHITE, LIGHT_GREY, WHITE, LIGHT_GREY]),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(other_table)

    story.append(Spacer(1, 10))

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION IV – SURGICAL APPROACHES
    # ══════════════════════════════════════════════════════════════════════════
    story.append(SectionBanner("SECTION IV   Surgical Approaches", W, DARK_BLUE, WHITE, 11, 24))
    story.append(Spacer(1, 5))

    # --- Open ---
    story.append(Paragraph("A.  Open Pyeloplasty", s["sub_heading"]))
    open_data = [
        [Paragraph("<b>Approach</b>", s["cell_head"]),
         Paragraph("<b>Patient Position</b>", s["cell_head"]),
         Paragraph("<b>Best For</b>", s["cell_head"]),
         Paragraph("<b>Notes</b>", s["cell_head"])],
        [
            Paragraph("Flank (subcostal / transcostal)", s["cell_body"]),
            Paragraph("Lateral decubitus", s["cell_body"]),
            Paragraph("Standard approach; most adults & children", s["cell_body"]),
            Paragraph("Most commonly used open route", s["cell_body"]),
        ],
        [
            Paragraph("Posterior Lumbotomy (Dorsal)", s["cell_body"]),
            Paragraph("Prone", s["cell_body"]),
            Paragraph("Infants & toddlers ONLY", s["cell_body"]),
            Paragraph("Increasing dorsal musculature with age makes this impractical in older patients", s["cell_body"]),
        ],
        [
            Paragraph("Anterior (subcostal / transabdominal)", s["cell_body"]),
            Paragraph("Supine / lateral", s["cell_body"]),
            Paragraph("Horseshoe/malrotated kidneys; bilateral cases", s["cell_body"]),
            Paragraph("Direct access when UPJ is anterior", s["cell_body"]),
        ],
        [
            Paragraph("Transmesocolic (through mesocolon)", s["cell_body"]),
            Paragraph("Supine", s["cell_body"]),
            Paragraph("Pediatric/thin patients; horseshoe/malrotated kidneys; left side", s["cell_body"]),
            Paragraph(
                "Incision through mesocolon without colon mobilization. Quick UPJ access. "
                "Ideal when pelvis anatomy is distorted.",
                s["cell_body"]
            ),
        ],
    ]
    open_table = Table(open_data, colWidths=[W * 0.24, W * 0.17, W * 0.30, W * 0.27], hAlign="LEFT")
    open_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), MID_BLUE),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [WHITE, LIGHT_GREY, WHITE, LIGHT_GREY]),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(open_table)
    story.append(Spacer(1, 7))

    # --- Laparoscopic ---
    story.append(Paragraph("B.  Laparoscopic Pyeloplasty  (First described 1993 - Kavoussi & Peters)", s["sub_heading"]))
    lap_data = [
        [Paragraph("<b>Route</b>", s["cell_head"]),
         Paragraph("<b>Description</b>", s["cell_head"]),
         Paragraph("<b>Advantages</b>", s["cell_head"]),
         Paragraph("<b>Considerations</b>", s["cell_head"])],
        [
            Paragraph("<b>Transperitoneal</b>\n(most common)", s["cell_body"]),
            Paragraph("Enter peritoneal cavity; reflect colon; standard port placement", s["cell_body"]),
            Paragraph("Largest working space; familiar anatomy; good visualization", s["cell_body"]),
            Paragraph("Standard route for adults; most literature data", s["cell_body"]),
        ],
        [
            Paragraph("<b>Retroperitoneal</b>\n(retroperitoneoscopic)", s["cell_body"]),
            Paragraph("Balloon/manual dilation of retroperitoneal space; direct UPJ access", s["cell_body"]),
            Paragraph("Avoids peritoneal cavity; shorter path to UPJ; faster bowel recovery; preferred in redo cases", s["cell_body"]),
            Paragraph("More technically challenging; less working space; higher conversion rate in some series", s["cell_body"]),
        ],
        [
            Paragraph("<b>Hand-Assisted</b>", s["cell_body"]),
            Paragraph("Hand port added to standard laparoscopic ports", s["cell_body"]),
            Paragraph("Bridge for surgeons building laparoscopic skills; tactile feedback", s["cell_body"]),
            Paragraph("Less commonly used now", s["cell_body"]),
        ],
    ]
    lap_table = Table(lap_data, colWidths=[W * 0.18, W * 0.27, W * 0.29, W * 0.24], hAlign="LEFT")
    lap_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), MID_BLUE),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [WHITE, LIGHT_GREY, WHITE]),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(lap_table)

    lap_note_data = [[Paragraph(
        "<b>Key fact:</b>  Laparoscopic pyeloplasty achieves success rates >95% in experienced hands, "
        "comparable to open surgery with less morbidity. "
        "All pyeloplasty techniques (A-H, Y-V, H-M, Davis, Hellstrom, tubularized flap) have been described laparoscopically. "
        "(Autorino et al. meta-analysis 2014)",
        s["cell_body"]
    )]]
    lap_note_table = Table(lap_note_data, colWidths=[W])
    lap_note_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), LIGHT_BLUE),
        ("BOX", (0, 0), (-1, -1), 0.8, MID_BLUE),
        ("TOPPADDING", (0, 0), (-1, -1), 6),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
        ("LEFTPADDING", (0, 0), (-1, -1), 10),
        ("RIGHTPADDING", (0, 0), (-1, -1), 10),
    ]))
    story.append(Spacer(1, 4))
    story.append(lap_note_table)
    story.append(Spacer(1, 7))

    # --- Robotic ---
    story.append(Paragraph("C.  Robotic-Assisted Pyeloplasty  (Since ~2004)", s["sub_heading"]))
    rob_data = [
        [Paragraph("<b>Platform</b>", s["cell_head"]),
         Paragraph("<b>Key Points</b>", s["cell_head"]),
         Paragraph("<b>Evidence (2025)</b>", s["cell_head"])],
        [
            Paragraph("Standard Multiport Robotic\n(transperitoneal, most common)", s["cell_body"]),
            Paragraph(
                "Wristed articulating instruments ease intracorporeal suturing. "
                "Shorter learning curve vs. pure laparoscopy. Especially advantageous in children and complex anatomies.",
                s["cell_body"]
            ),
            Paragraph("Equivalent or superior outcomes to laparoscopic pyeloplasty (Kuiqing et al. PMID 40753141, J Robot Surg 2025)", s["cell_body"]),
        ],
        [
            Paragraph("Retroperitoneal Robotic", s["cell_body"]),
            Paragraph("Same advantages as retroperitoneal laparoscopic + robotic dexterity. Emerging approach.", s["cell_body"]),
            Paragraph("Limited comparative data vs transperitoneal robotic", s["cell_body"]),
        ],
        [
            Paragraph("Single-Port Robotic (SP)", s["cell_body"]),
            Paragraph("Single trocar entry. Improved cosmesis. All instruments through one port.", s["cell_body"]),
            Paragraph("Meta-analysis (Yang et al. PMID 40016552, 2025): comparable efficacy to multiport with better cosmesis", s["cell_body"]),
        ],
        [
            Paragraph("LESS / R-LESS\n(Laparoendoscopic Single-Site)", s["cell_body"]),
            Paragraph(
                "Umbilical multichannel port (GelPoint). 2 robotic + 2 standard trocars 3 cm apart (diamond config). "
                "Near-invisible cosmetic result.",
                s["cell_body"]
            ),
            Paragraph("~93% success (Harrow et al. 2013). Technically demanding (instrument clashing).", s["cell_body"]),
        ],
    ]
    rob_table = Table(rob_data, colWidths=[W * 0.22, W * 0.44, W * 0.32], hAlign="LEFT")
    rob_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), DARK_BLUE),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [WHITE, LIGHT_GREY, WHITE, LIGHT_GREY]),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(rob_table)

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION V – COMPARISON TABLE
    # ══════════════════════════════════════════════════════════════════════════
    story.append(SectionBanner("SECTION V   Comparison Summary Table", W, DARK_BLUE, WHITE, 11, 24))
    story.append(Spacer(1, 5))

    comp_headers = ["Technique", "Best Indication", "Crossing Vessel?", "Success", "Key Limitation"]
    comp_rows = [
        ["Anderson-Hynes\n(Dismembered) ★", "All scenarios; gold standard", "YES - transpose", "~95%",
         "Not for tiny intrarenal pelvis or very long stricture"],
        ["Foley Y-V Plasty", "High ureteral insertion", "NO", "~86%",
         "Cannot transpose vessels; no pelvis reduction"],
        ["Fenger (H-M)", "Short intrinsic stenosis", "NO", "Limited data",
         "Only for very short strictures"],
        ["Spiral Flap\n(Culp-DeWeerd)", "Long proximal stricture, dependent UPJ", "NO", "Good",
         "L:W ratio max 3:1; cannot transpose vessels"],
        ["Vertical Flap\n(Scardino-Prince)", "Long stricture, box-shaped pelvis", "NO", "Good",
         "Same constraints as spiral flap"],
        ["Tubularized Flap", "Large ureteral gap (>3 cm)", "NO", "Case reports",
         "Rarely needed; limited outcome data"],
        ["Davis Intubated\nUreterotomy", "Long/multiple strictures", "NO", "Poor",
         "High recurrence; largely abandoned"],
        ["Hellstrom Vascular\nHitch", "Crossing vessel ONLY, no intrinsic stenosis", "N/A - addressed", "Comparable (selected)",
         "Strict patient selection; limited long-term data"],
        ["Laparoscopic\n(trans/retroperitoneal)", "Standard minimally invasive approach", "YES (with A-H)", ">95%",
         "Requires advanced laparoscopic suturing skills"],
        ["Robotic-Assisted\n(multiport / SP)", "Children; complex anatomy; suturing difficult", "YES (with A-H)", ">95%",
         "Higher cost; availability"],
        ["LESS / R-LESS", "Cosmetically conscious patients", "YES (with A-H)", "~93%",
         "Instrument clashing; steep learning curve"],
        ["Endopyelotomy\n(antegrade/retrograde)", "Short stricture, no crossing vessel, limited function", "CONTRAINDICATED", "65-75%",
         "Inferior to all pyeloplasty types; high recurrence"],
    ]

    comp_data = [[Paragraph(f"<b>{h}</b>", s["cell_head"]) for h in comp_headers]]
    for i, row in enumerate(comp_rows):
        bg = LIGHT_GOLD if i == 0 else (LIGHT_GREY if i % 2 == 0 else WHITE)
        # success column coloring
        cells = []
        for j, cell_text in enumerate(row):
            if j == 3:  # success column
                if "95%" in cell_text or ">95" in cell_text:
                    cells.append(Paragraph(f"<b>{cell_text}</b>", s["cell_success"]))
                elif "65" in cell_text or "75" in cell_text:
                    cells.append(Paragraph(cell_text, s["cell_contra"]))
                elif "86%" in cell_text:
                    cells.append(Paragraph(cell_text, s["cell_body_center"]))
                else:
                    cells.append(Paragraph(cell_text, s["cell_body_center"]))
            elif j == 2 and "CONTRA" in cell_text:
                cells.append(Paragraph(cell_text, s["cell_contra"]))
            else:
                cells.append(Paragraph(cell_text, s["cell_body"]))
        comp_data.append(cells)

    # Mark gold standard row
    comp_data[1][0] = Paragraph("<b>Anderson-Hynes\n(Dismembered) ★</b>", s["gold_badge"])

    col_widths = [W * 0.20, W * 0.26, W * 0.14, W * 0.10, W * 0.28]
    comp_table = Table(comp_data, colWidths=col_widths, hAlign="LEFT", repeatRows=1)

    row_styles = [
        ("BACKGROUND", (0, 0), (-1, 0), DARK_BLUE),
        ("BACKGROUND", (0, 1), (-1, 1), LIGHT_GOLD),
        ("BOX", (0, 1), (-1, 1), 1, ACCENT_GOLD),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 4),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 4),
        ("LEFTPADDING", (0, 0), (-1, -1), 5),
        ("RIGHTPADDING", (0, 0), (-1, -1), 5),
    ]
    for i in range(2, len(comp_data)):
        if i % 2 == 0:
            row_styles.append(("BACKGROUND", (0, i), (-1, i), LIGHT_GREY))
        else:
            row_styles.append(("BACKGROUND", (0, i), (-1, i), WHITE))

    comp_table.setStyle(TableStyle(row_styles))
    story.append(comp_table)
    story.append(Spacer(1, 6))
    story.append(Paragraph(
        "★  Anderson-Hynes dismembered pyeloplasty is the gold standard — the reference for all comparisons. "
        "Endopyelotomy is inferior to all pyeloplasty forms and should NOT be used when a crossing vessel is present (haemorrhage risk).",
        s["caption"]
    ))

    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION VI – STENTING + KEY CLINICAL POINTS
    # ══════════════════════════════════════════════════════════════════════════
    story.append(SectionBanner("SECTION VI   Stenting & Key Clinical Points", W, DARK_BLUE, WHITE, 11, 24))
    story.append(Spacer(1, 6))

    # Stenting
    story.append(Paragraph("Ureteral Stenting After Pyeloplasty", s["sub_heading"]))
    stent_data = [
        [Paragraph("<b>Stent Type</b>", s["cell_head"]),
         Paragraph("<b>Features</b>", s["cell_head"]),
         Paragraph("<b>Removal</b>", s["cell_head"])],
        [
            Paragraph("Internal Double-J (Pigtail)", s["cell_body"]),
            Paragraph(
                "Both ends in bladder & renal pelvis. Invisible externally. "
                "Avoids second anesthesia in adults. May be difficult to pass UVJ in small infants.",
                s["cell_body"]
            ),
            Paragraph("Outpatient cystoscopy at 4-6 weeks", s["cell_body"]),
        ],
        [
            Paragraph("Externalized Nephro-Ureteric Stent", s["cell_body"]),
            Paragraph(
                "Exits via nephrostomy (external). Preferred in infants (Nasser et al. RCT: reduces complications & hospital stay). "
                "Avoids need for cystoscopy under GA.",
                s["cell_body"]
            ),
            Paragraph("Bedside removal at 4-6 weeks", s["cell_body"]),
        ],
        [
            Paragraph("Stentless Anastomosis", s["cell_body"]),
            Paragraph(
                "Advocated by some surgeons; requires meticulous tissue handling to prevent edema/leak. "
                "Historically, Anderson & Hynes themselves opposed routine stenting.",
                s["cell_body"]
            ),
            Paragraph("N/A - no stent placed", s["cell_body"]),
        ],
    ]
    stent_table = Table(stent_data, colWidths=[W * 0.22, W * 0.52, W * 0.24], hAlign="LEFT")
    stent_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), MID_BLUE),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [WHITE, LIGHT_GREY, WHITE]),
        ("GRID", (0, 0), (-1, -1), 0.4, BORDER_GREY),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
        ("LEFTPADDING", (0, 0), (-1, -1), 6),
        ("RIGHTPADDING", (0, 0), (-1, -1), 6),
    ]))
    story.append(stent_table)
    story.append(Spacer(1, 8))

    # Key clinical points
    story.append(Paragraph("Key Clinical Points", s["sub_heading"]))

    key_points = [
        ("TECHNIQUE SELECTION", [
            "Anderson-Hynes is the go-to for >95% of cases. Only switch to a flap technique when anatomy specifically demands it.",
            "Foley Y-V: only for confirmed high ureteral insertion with no crossing vessel.",
            "Spiral/vertical flap: only when a long proximal ureteral gap prevents tension-free A-H anastomosis.",
            "Hellstrom hitch: only when intraoperative peristalsis confirms NO intrinsic stenosis.",
        ]),
        ("CROSSING VESSEL MANAGEMENT", [
            "Always inspect for lower pole crossing vessels before dismembering.",
            "With A-H: swing ureter anterior to vessel - confirmed by visualizing vessel lying posterior to anastomosis.",
            "With Hellstrom hitch: embed vessel into pelvic tissue with non-absorbable sutures cranially.",
            "Hypertension from embedding vessels has NOT been observed in follow-up.",
        ]),
        ("OPERATIVE TIPS", [
            "Aspirate a tensely dilated pelvis with a 21G needle before dismembering (avoid excessive pelvic reduction).",
            "Preserve periureteral tissue when mobilizing ureter (blood supply runs within it).",
            "Use bipolar diathermy near pelvis/ureter - avoid monopolar cautery.",
            "The anastomotic 'crotch' (V tip) must be assembled precisely and tension-free.",
            "Irrigate pelvis with saline before completing anastomosis (remove blood clots).",
            "Reduce pelvis only if it is genuinely redundant - unnecessary reduction risks ischemia.",
        ]),
        ("POSTOPERATIVE FOLLOW-UP", [
            "Foley catheter removed POD 1; drain removed when output <60 mL/8hr.",
            "Typical discharge POD 1-2 after minimally invasive pyeloplasty.",
            "Ureteral stent removed at 4-6 weeks (outpatient).",
            "MAG3 diuretic renal scan at 3 months, 6 months, then annually x 2 years.",
            "Whitaker pressure-flow test: used to differentiate residual obstruction vs. dilatation after pyeloplasty.",
        ]),
        ("COMPLICATIONS", [
            "Urinary leak / urinoma (most common): usually managed conservatively with prolonged stenting.",
            "Anastomotic stricture / failure: ~5%; redo pyeloplasty, endopyelotomy, or ureterocalicostomy.",
            "Laparoscopic-specific: colonic injury, ileus, urinary ascites, thrombophlebitis (~12-15% overall complication rate).",
            "Endopyelotomy-specific: haemorrhage if crossing vessel present (major risk - avoid if vessel present).",
        ]),
    ]

    for section_title, points in key_points:
        row_data = [
            [
                Paragraph(f"<b>{section_title}</b>", s["cell_head"]),
            ]
        ]
        pts_para = "".join([f"<bullet bulletChar='•'>{pt}</bullet>" for pt in points])
        pts_para_obj = Paragraph(pts_para, s["bullet"])
        row_data.append([pts_para_obj])

        kp_table = Table(row_data, colWidths=[W])
        kp_table.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, 0), DARK_BLUE),
            ("BACKGROUND", (0, 1), (-1, 1), LIGHT_GREY),
            ("BOX", (0, 0), (-1, -1), 0.5, BORDER_GREY),
            ("TOPPADDING", (0, 0), (-1, -1), 5),
            ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
            ("LEFTPADDING", (0, 0), (-1, -1), 8),
            ("RIGHTPADDING", (0, 0), (-1, -1), 8),
        ]))
        story.append(kp_table)
        story.append(Spacer(1, 4))

    story.append(Spacer(1, 8))

    # Hellstrom patient selection box
    hs_data = [[Paragraph(
        "<b>Hellstrom Vascular Hitch - Gundeti Selection Criteria (ALL must be met):</b>  "
        "Moderate hydronephrosis | No calyceal dilation | Preserved renal cortex | "
        "Poor drainage with preserved split function | Lower pole crossing vessel on imaging | "
        "Intraoperatively: normal-caliber ureter AND active peristalsis at UPJ",
        s["cell_body"]
    )]]
    hs_table = Table(hs_data, colWidths=[W])
    hs_table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, -1), LIGHT_GOLD),
        ("BOX", (0, 0), (-1, -1), 1, ACCENT_GOLD),
        ("TOPPADDING", (0, 0), (-1, -1), 7),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 7),
        ("LEFTPADDING", (0, 0), (-1, -1), 10),
        ("RIGHTPADDING", (0, 0), (-1, -1), 10),
    ]))
    story.append(hs_table)
    story.append(Spacer(1, 10))

    # Sources
    story.append(hrule(W))
    story.append(Paragraph(
        "<b>Sources:</b>  Campbell-Walsh-Wein Urology 3-Volume Set (Dismembered Pyeloplasty pp. 2605-2612; "
        "Laparoscopic/Robotic pp. 2100-2151)  |  Hinman's Atlas of Urologic Surgery (pp. 164, 207)  |  "
        "Smith & Tanagho's General Urology 19th Ed. (p. 176)  |  "
        "Kuiqing et al. J Robot Surg 2025 [PMID 40753141]  |  Yang et al. J Robot Surg 2025 [PMID 40016552]  |  "
        "Spinos et al. World J Urol 2025 [PMID 41405725 - RALUC]",
        s["footer"]
    ))

    doc.build(story)
    print(f"PDF saved to {OUTPUT}")

build()
Running Command

cd /home/daytona/workspace/pyeloplasty-guide && python3 build_pdf.py 2>&1

Editing File

~/pyeloplasty-guide/build_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/pyeloplasty-guide/build_pdf.py'
Running Command

cd /home/daytona/workspace/pyeloplasty-guide && python3 build_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/pyeloplasty-guide/Pyeloplasty_Quick_Reference.pdf && python3 -c "from pypdf import PdfReader; r = PdfReader('/home/daytona/workspace/pyeloplasty-guide/Pyeloplasty_Quick_Reference.pdf'); print(f'Pages: {len(r.pages)}')"

The PDF is ready - 8 pages, 23 KB. Here it is:

Your Quick Reference Guide is ready:

Pyeloplasty Quick Reference

PDF Document · PDF


What's inside (8 pages, A4):
PageSection
1Cover page with contents list
2Section I - Anderson-Hynes Dismembered Pyeloplasty (gold standard, step-by-step, crossing vessel note)
3Section II - All Non-Dismembered Flap Techniques (Foley Y-V, Fenger, Spiral, Vertical, Tubularized)
4Section III - Other UPJ Methods (Davis, Hellstrom Hitch, Bypass, Ureterocalicostomy)
4-5Section IV - All Surgical Approaches (Open incisions, Laparoscopic trans/retroperitoneal, Robotic multiport/SP/LESS)
6Section V - Full Comparison Summary Table (12 techniques, color-coded success rates, contraindications)
7-8Section VI - Stenting options + Key Clinical Points (technique selection, crossing vessel management, operative tips, follow-up, complications) + Hellstrom Gundeti selection criteria box
Sourced from Campbell-Walsh-Wein Urology, Hinman's Atlas, Smith & Tanagho, and 2025 meta-analyses.
This is a shared conversation. Sign in to Orris to start your own chat.