Assalam o alaikum wa rahmatullah wa barakatuhu Does this orris ai have limits also like before premium

Wa alaikum assalam wa rahmatullahi wa barakatuhu! 😊
Great to have you here. To answer your question directly:
Orris AI does have usage limits, and they depend on the plan/access level you're on. Here's a general breakdown:

Free / Standard Access

  • Limited number of messages or queries per day/session
  • May have restricted access to advanced tools (web search, PubMed, document generation, etc.)
  • Shorter response depth or fewer tool calls per session

Premium Access

  • Higher (or unlimited) message limits
  • Full access to all tools: medical library, PubMed research, file generation (PPTX, DOCX, PDF, XLSX), web search, image generation, etc.
  • Deeper research with more parallel tool calls
  • Larger context/budget per session (as you can see in the budget tracker above)

What you're seeing right now

The budget tracker at the top of each message shows your current session's tool call limits - for example, how many web searches, database queries, or PubMed lookups are available. This resets per session.
If you're asking whether Orris (this AI) has the same kind of paywalled restrictions as other tools you've used before - the answer is: it depends on how your access was set up. If you're on a premium plan, you should have significantly more capacity than a free tier.
Is there something specific you're trying to do that you're worried might be restricted? I can let you know if it's within the current session's capabilities! πŸ™‚

Sialolithiasis notes oral pathology

Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Finding Sources
Reading File
Reading File
Reading File
Finding Sources
Reading File
Loading Image
I now have comprehensive information from multiple authoritative textbooks. Let me compile the full notes:

Sialolithiasis - Oral Pathology Notes

Definition

Sialolithiasis is the formation of calculi (stones/sialoliths) within the ductal system of the salivary glands. It is the most common cause of salivary gland inflammation (sialadenitis).
  • Cummings Otolaryngology, p. 1486

Epidemiology

  • Most commonly affects patients in their 5th to 8th decades (ages 30-60 is the typical clinical presentation range)
  • Men are affected more frequently than women
  • Sialolithiasis in children is rare (if it occurs, usually presents around age 10)

Gland Distribution

GlandFrequency
Submandibular (Wharton's duct)80-90%
Parotid (Stensen's duct)10-20%
Sublingual~1%

Why the Submandibular Gland is Most Affected (IMPORTANT)

Several anatomical and physiological factors predispose the submandibular gland:
  1. Wharton's duct is longer, wider, more tortuous, and angulated against gravity as it courses around the mylohyoid muscle - all promoting stasis
  2. The saliva produced is more viscous (mucinous) and has a higher calcium and phosphate concentration
  3. The saliva is more alkaline - this causes precipitation of calcium and phosphate, predisposing to stone formation
  4. In the parotid gland, the saliva is more serous/watery, which is less conducive to stone formation
In the submandibular gland: stones tend to form in the duct (mainly proximal portion) In the parotid gland: stones are most commonly at the hilum or parenchyma (mainly distal)
  • Cummings Otolaryngology, p. 1487; Bailey & Love, p. 858

Composition of Sialoliths

Salivary stones are composed of:
  • Calcium phosphate and carbonate (majority - same composition as dental tartar/calculus) - i.e., calcium and magnesium phosphates
  • An organic matrix of glycoproteins and mucopolysaccharides
  • Small amounts of magnesium, potassium, and ammonium salts
Note: Serum calcium and phosphate levels are NOT related to stone formation. However, hyperparathyroidism is associated with an increased incidence of sialolithiasis.
  • Cummings Otolaryngology, p. 1486; S. Das Manual of Surgery, p. 367

Pathogenesis / Etiology

The precise etiology remains unknown, but the proposed mechanism is:
  1. Salivary stasis + inflammatory ductal changes β†’ alteration of mucoid elements of saliva
  2. Formation of an organic gel (the nidus/framework)
  3. Deposition of calcium salts onto this organic framework
  4. Progressive calcification β†’ calculus formation
Predisposing factors:
  • Chronic dehydration
  • Pharmacological decrease in salivary flow (anticholinergics, diuretics, antihistamines)
  • Ductal abnormality or strictures
  • Increased calcium content of saliva
  • Gout, hyperparathyroidism
Relationship to sialadenitis differs by gland:
  • Submandibular gland: The stone forms first β†’ causes stasis β†’ promotes retrograde bacterial migration β†’ results in sialadenitis
  • Parotid gland: Chronic sialadenitis causes ductal injury β†’ this then leads to sialolithiasis
  • Cummings Otolaryngology, p. 1486-1487

Clinical Features

Hallmark presentation:
  • Cyclical postprandial swelling of the affected gland (food stimulates saliva production, which can't drain past the stone)
  • Salivary colic - colicky pain and swelling, worst during meals
  • Pain and swelling are unilateral
Clinical examination findings:
  • Asymmetric enlargement of the gland
  • Bimanual palpation may reveal a palpable stone in the submandibular duct (floor of mouth)
  • Parotid stones may be visible at the orifice of Stensen's duct or along the duct
  • On milking/massaging the gland: absent, reduced, or cloudy/mucopurulent salivary flow
  • Lemon juice test: giving the patient lemon juice reproduces the swelling (a useful bedside test)
Complications:
  • Acute suppurative sialadenitis (secondary bacterial infection β†’ abscess formation)
  • Chronic non-specific sialadenitis
  • Cummings Otolaryngology, p. 1487; Bailey & Love, p. 858; S. Das Manual

Investigations / Diagnosis

Imaging Options

ModalityNotes
UltrasoundFirst-line; detects ~90% of stones >2 mm; cost-effective, no radiation, dynamic, operator-dependent
CT scan (fine cuts 1-2mm)Extremely accurate; non-contrast preferred (contrast-opacified vessels can be confused with stones); shows enlarged gland + ductal dilatation
Plain radiograph (occlusal/intraoral)Traditionally used for radiopaque stones; no longer routine - misses radiolucent stones; confuses sialoliths with phleboliths, atherosclerosis, calcified lymph nodes
MRICalculus appears as low-signal intensity focus on both T1 and T2 weighted images
Digital subtraction sialographySensitivity 95-100%; detects radiolucent stones; invasive; contraindicated in active infection and distal Wharton duct stones
MR sialographyNon-invasive; uses saliva as contrast; accuracy similar to digital sialography; better alternative when digital sialography is contraindicated
CT scan showing multiple hyperdense sialoliths in right submandibular gland
CT scan with bony windowing revealing multiple hyperdense sialoliths in the right submandibular gland - Cummings Otolaryngology
CT is the preferred modality in emergency settings for suspected sialolithiasis (also identifies associated infection).

Management

Conservative (Non-surgical) - First Line

  • Sialagogues (e.g., lemon drops, citric acid) - stimulate salivary flow to help flush the stone
  • Hydration
  • Local heat application over the gland
  • Gland massage
  • Antibiotics if secondary sialadenitis/infection is present (e.g., amoxicillin-clavulanate)
  • Analgesics for pain

Surgical / Interventional

Management depends on: size, location, shape, number, mobility (palpable vs. impacted), and surgeon's experience. The earlier the stone is removed, the better the prognosis.

Submandibular Stones:

  • Distal stones (<2 cm from duct orifice, distal to posterior edge of mylohyoid): Transoral removal - milking or simple transoral incision (duct slitting)
  • Small (<5 mm) distal stones: Sialendoscopy (endoscopic removal)
  • Larger (>5 mm) distal stones: Duct slitting may be required
  • Intraparenchymal 5-7 mm stones: Endoscopic extraction
  • Impacted or non-palpable stones: External shock wave lithotripsy (ESWL) - not suitable for stones >7-10 mm
  • Proximal/hilar/intraglandular/impacted/megaliths: Traditionally submandibular gland excision (now last resort)

Parotid Stones:

  • Small (<7 mm) parotid stones: Sialendoscopy
  • Difficult cases: Combined transcutaneous approach
  • ESWL for impacted stones
  • Gland removal only as last resort

Sialendoscopy (Modern Gold Standard):

  • Uses miniature semirigid endoscopes (0.8-1.6 mm) with an irrigation port
  • Stones ensnared with a wire basket
  • Large stones fragmented by holmium laser or lithotripsy
  • Success rates 80-100%
  • Preserves the gland (gland-preserving technique)
  • Combined/hybrid technique (endoscopy + external incision) used for impacted stones
  • After removal, a salivary stent may be placed for 2-4 weeks to prevent duct stricture
  • Cummings Otolaryngology, pp. 1487-1490; Bailey & Love, pp. 858-858

Differential Diagnosis

  • Parotitis / mumps (usually bilateral)
  • Salivary gland neoplasm (submandibular gland enlargement - mixed tumor is the most common tumor here)
  • Lymph node enlargement
  • Phleboliths (on radiograph)
  • Atherosclerosis of lingual artery (calcification on radiograph)
  • Calcified cervical lymphadenopathy

Key Points Summary

FeatureDetail
Most common glandSubmandibular (80-90%)
Duct involvedWharton's duct (submandibular)
Stone compositionCalcium phosphate + carbonate + organic matrix
Hallmark symptomCyclical postprandial pain + swelling (salivary colic)
First-line imagingUltrasound
Preferred emergency imagingCT (non-contrast)
First-line treatmentConservative (sialagogues, hydration, massage)
Minimally invasive surgerySialendoscopy (gland-preserving)
Last resortGland excision
Long-standing complicationAcute suppurative sialadenitis / chronic sialadenitis

Sources: Cummings Otolaryngology Head and Neck Surgery (p. 1486-1490), Bailey & Love's Short Practice of Surgery 28th Ed. (p. 858), S. Das Manual on Clinical Surgery 13th Ed. (p. 367), Robbins & Cotran Pathologic Basis of Disease

Create a quick reference PDF or summary table for sialolithiasis

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace is empty or does not exist"

Running Command

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

Writing File

~/sialolithiasis/build_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak

OUTPUT = "/home/daytona/workspace/sialolithiasis/Sialolithiasis_Quick_Reference.pdf"

# ── Colour palette ──────────────────────────────────────────────────────────
TEAL      = colors.HexColor("#006666")
TEAL_LITE = colors.HexColor("#E0F4F4")
TEAL_MID  = colors.HexColor("#B2DFDF")
AMBER     = colors.HexColor("#E65C00")
AMBER_LT  = colors.HexColor("#FFF3E0")
GREY_HEAD = colors.HexColor("#37474F")
GREY_ROW  = colors.HexColor("#F5F5F5")
WHITE     = colors.white
BLACK     = colors.black
RED_LT    = colors.HexColor("#FFEBEE")
RED       = colors.HexColor("#C62828")
GREEN_LT  = colors.HexColor("#E8F5E9")
GREEN     = colors.HexColor("#2E7D32")
BLUE_LT   = colors.HexColor("#E3F2FD")
BLUE      = colors.HexColor("#1565C0")
PURPLE_LT = colors.HexColor("#F3E5F5")
PURPLE    = colors.HexColor("#6A1B9A")

styles = getSampleStyleSheet()

def sty(name, **kw):
    return ParagraphStyle(name, **kw)

title_style = sty("Title2", fontSize=22, textColor=WHITE,
                  fontName="Helvetica-Bold", alignment=TA_CENTER,
                  spaceAfter=4, leading=26)
subtitle_style = sty("Sub", fontSize=11, textColor=TEAL_MID,
                     fontName="Helvetica-Oblique", alignment=TA_CENTER,
                     spaceAfter=2)
section_style = sty("Sec", fontSize=12, textColor=WHITE,
                    fontName="Helvetica-Bold", alignment=TA_LEFT,
                    leading=16)
body_style = sty("Body2", fontSize=9.5, textColor=BLACK,
                 fontName="Helvetica", leading=14, alignment=TA_JUSTIFY)
body_bold = sty("BodyBold", fontSize=9.5, textColor=BLACK,
                fontName="Helvetica-Bold", leading=14)
small_style = sty("Small", fontSize=8.5, textColor=GREY_HEAD,
                  fontName="Helvetica", leading=12, alignment=TA_CENTER)
bullet_style = sty("Bullet", fontSize=9, textColor=BLACK,
                   fontName="Helvetica", leading=13, leftIndent=10,
                   bulletIndent=0)
table_header = sty("TH", fontSize=9, textColor=WHITE,
                   fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12)
table_cell   = sty("TC", fontSize=8.8, textColor=BLACK,
                   fontName="Helvetica", alignment=TA_LEFT, leading=12)
table_cell_c = sty("TCC", fontSize=8.8, textColor=BLACK,
                   fontName="Helvetica", alignment=TA_CENTER, leading=12)
emph_cell    = sty("ECc", fontSize=8.8, textColor=TEAL,
                   fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12)
warn_style   = sty("Warn", fontSize=8.5, textColor=RED,
                   fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12)

def section_header(text, color=TEAL):
    """Return a coloured section-header table."""
    t = Table([[Paragraph(text, section_style)]], colWidths=[17.5*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("ROUNDEDCORNERS", [4, 4, 4, 4]),
        ("TOPPADDING",  (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0),(-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
    ]))
    return t

def build():
    doc = SimpleDocTemplate(
        OUTPUT, pagesize=A4,
        leftMargin=2*cm, rightMargin=2*cm,
        topMargin=2*cm, bottomMargin=2*cm,
        title="Sialolithiasis Quick Reference",
        author="Orris AI – Oral Pathology"
    )

    story = []
    W = 17.5*cm   # usable width

    # ── TITLE BANNER ──────────────────────────────────────────────────────
    banner_data = [[
        Paragraph("🦷  SIALOLITHIASIS", title_style),
        Paragraph("Quick Reference Card  |  Oral Pathology", subtitle_style)
    ]]
    banner = Table(banner_data, colWidths=[W])
    banner.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), TEAL),
        ("TOPPADDING",    (0,0), (-1,-1), 14),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
        ("LEFTPADDING",   (0,0), (-1,-1), 14),
        ("SPAN",          (0,0), (-1,-1)),
        ("ALIGN",         (0,0), (-1,-1), "CENTER"),
    ]))
    story.append(banner)
    story.append(Spacer(1, 6*mm))

    # ── ROW 1: Definition + Epidemiology side by side ─────────────────────
    def_lines = [
        Paragraph("<b>Definition:</b> Formation of calculi (stones/sialoliths) within the ductal system of the salivary glands.", body_style),
        Spacer(1, 4),
        Paragraph("<b>Most common cause</b> of salivary gland inflammation (sialadenitis).", body_style),
        Spacer(1, 4),
        Paragraph("<b>Synonym:</b> Salivary gland stones / Salivary calculi", body_style),
    ]

    epi_lines = [
        Paragraph("<b>Age:</b> 5th–8th decade (30–60 yrs typical)", body_style),
        Spacer(1, 4),
        Paragraph("<b>Sex:</b> Males &gt; Females", body_style),
        Spacer(1, 4),
        Paragraph("<b>Children:</b> Rare; usually ~10 yrs of age", body_style),
        Spacer(1, 4),
        Paragraph("<b>Hyperparathyroidism</b> β†’ increased risk", body_style),
    ]

    box_style = TableStyle([
        ("BOX",            (0,0), (-1,-1), 0.8, TEAL_MID),
        ("BACKGROUND",     (0,0), (-1,-1), TEAL_LITE),
        ("TOPPADDING",     (0,0), (-1,-1), 7),
        ("BOTTOMPADDING",  (0,0), (-1,-1), 7),
        ("LEFTPADDING",    (0,0), (-1,-1), 8),
        ("RIGHTPADDING",   (0,0), (-1,-1), 8),
    ]))

    def mini_box(title_text, content_items, bg=TEAL_LITE, border=TEAL_MID):
        inner = [Paragraph(f"<b>{title_text}</b>", sty("MBT", fontSize=9.5,
                           textColor=TEAL, fontName="Helvetica-Bold", leading=14))]
        inner += content_items
        t = Table([[inner]], colWidths=[(W/2)-3*mm])
        t.setStyle(TableStyle([
            ("BOX",           (0,0),(-1,-1), 0.8, border),
            ("BACKGROUND",    (0,0),(-1,-1), bg),
            ("TOPPADDING",    (0,0),(-1,-1), 7),
            ("BOTTOMPADDING", (0,0),(-1,-1), 7),
            ("LEFTPADDING",   (0,0),(-1,-1), 8),
            ("RIGHTPADDING",  (0,0),(-1,-1), 8),
            ("VALIGN",        (0,0),(-1,-1), "TOP"),
        ]))
        return t

    row1 = Table(
        [[mini_box("DEFINITION", def_lines),
          mini_box("EPIDEMIOLOGY", epi_lines, bg=AMBER_LT, border=AMBER)]],
        colWidths=[(W/2)-2*mm, (W/2)-2*mm], hAlign="LEFT"
    )
    row1.setStyle(TableStyle([
        ("ALIGN",   (0,0),(-1,-1), "LEFT"),
        ("VALIGN",  (0,0),(-1,-1), "TOP"),
        ("LEFTPADDING",  (0,0),(-1,-1), 0),
        ("RIGHTPADDING", (0,0),(-1,-1), 0),
        ("COLPADDING",   (0,0),(-1,-1), 3),
    ]))
    story.append(row1)
    story.append(Spacer(1, 5*mm))

    # ── SECTION: Gland Distribution ───────────────────────────────────────
    story.append(section_header("GLAND DISTRIBUTION  (Why Submandibular?)"))
    story.append(Spacer(1, 3*mm))

    gland_data = [
        [Paragraph("<b>Gland</b>", table_header),
         Paragraph("<b>Frequency</b>", table_header),
         Paragraph("<b>Duct</b>", table_header),
         Paragraph("<b>Stone Location</b>", table_header)],
        [Paragraph("Submandibular", emph_cell),
         Paragraph("80–90% β˜…", emph_cell),
         Paragraph("Wharton's duct", table_cell_c),
         Paragraph("Mainly PROXIMAL (duct)", table_cell_c)],
        [Paragraph("Parotid", table_cell_c),
         Paragraph("10–20%", table_cell_c),
         Paragraph("Stensen's duct", table_cell_c),
         Paragraph("Hilum / Parenchyma (mainly DISTAL)", table_cell_c)],
        [Paragraph("Sublingual", table_cell_c),
         Paragraph("~1%", table_cell_c),
         Paragraph("Bartholin's duct", table_cell_c),
         Paragraph("Rare", table_cell_c)],
    ]
    gland_table = Table(gland_data, colWidths=[4.2*cm, 3.5*cm, 4.2*cm, 5.6*cm])
    gland_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), TEAL),
        ("BACKGROUND",    (0,1),(-1,1), TEAL_LITE),
        ("BACKGROUND",    (0,2),(-1,2), GREY_ROW),
        ("BACKGROUND",    (0,3),(-1,3), GREY_ROW),
        ("ROWBACKGROUNDS",(0,2),(-1,-1), [GREY_ROW, WHITE]),
        ("BOX",           (0,0),(-1,-1), 0.7, TEAL_MID),
        ("INNERGRID",     (0,0),(-1,-1), 0.4, TEAL_MID),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("ALIGN",         (0,0),(-1,-1), "CENTER"),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(gland_table)
    story.append(Spacer(1, 3*mm))

    # Why submandibular?
    why_items = [
        "1. Wharton's duct is <b>longer, wider, more tortuous</b> and runs <b>against gravity</b> (around mylohyoid) β†’ salivary stasis",
        "2. Saliva is more <b>viscous / mucinous</b> with higher <b>Ca²⁺ and PO₄³⁻ concentration</b>",
        "3. Saliva is more <b>alkaline</b> β†’ precipitates calcium phosphate β†’ stone formation",
    ]
    why_table_data = [[Paragraph(i, body_style)] for i in why_items]
    why_t = Table(why_table_data, colWidths=[W])
    why_t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), BLUE_LT),
        ("BOX",           (0,0),(-1,-1), 0.7, BLUE),
        ("INNERGRID",     (0,0),(-1,-1), 0.2, TEAL_MID),
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("LEFTPADDING",   (0,0),(-1,-1), 10),
    ]))
    story.append(why_t)
    story.append(Spacer(1, 5*mm))

    # ── SECTION: Composition & Pathogenesis ───────────────────────────────
    story.append(section_header("COMPOSITION & PATHOGENESIS", color=GREY_HEAD))
    story.append(Spacer(1, 3*mm))

    comp_items = [
        ["Calcium phosphate + carbonate", "MAJOR component (same as dental tartar/calculus)"],
        ["Calcium & magnesium phosphates", "Inorganic core"],
        ["Glycoproteins + mucopolysaccharides", "Organic matrix (nidus framework)"],
        ["Mg²⁺, K⁺, NH₄⁺ salts", "Minor components"],
        ["Serum Ca²⁺ / PO₄³⁻ levels", "NOT related to stone formation"],
    ]
    comp_data = [[Paragraph("<b>Component</b>", table_header),
                  Paragraph("<b>Role / Note</b>", table_header)]]
    for r in comp_items:
        comp_data.append([Paragraph(r[0], table_cell), Paragraph(r[1], table_cell)])

    comp_t = Table(comp_data, colWidths=[7.5*cm, 10*cm])
    comp_t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), GREY_HEAD),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [GREY_ROW, WHITE]),
        ("BOX",           (0,0),(-1,-1), 0.7, GREY_HEAD),
        ("INNERGRID",     (0,0),(-1,-1), 0.3, colors.HexColor("#BDBDBD")),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("LEFTPADDING",   (0,0),(-1,-1), 8),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(comp_t)
    story.append(Spacer(1, 3*mm))

    path_text = (
        "<b>Pathogenesis (proposed):</b>  Salivary stasis + ductal inflammation "
        "β†’ alteration of mucoid elements β†’ <b>organic gel nidus</b> forms "
        "β†’ deposition of calcium salts β†’ progressive calcification β†’ <b>calculus</b>.<br/>"
        "<br/>"
        "<b>Submandibular:</b> Stone forms FIRST β†’ stasis β†’ retrograde bacterial migration β†’ sialadenitis<br/>"
        "<b>Parotid:</b> Chronic sialadenitis β†’ ductal injury β†’ THEN stone forms"
    )
    path_box = Table([[Paragraph(path_text, body_style)]], colWidths=[W])
    path_box.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), PURPLE_LT),
        ("BOX",           (0,0),(-1,-1), 0.7, PURPLE),
        ("TOPPADDING",    (0,0),(-1,-1), 8),
        ("BOTTOMPADDING", (0,0),(-1,-1), 8),
        ("LEFTPADDING",   (0,0),(-1,-1), 10),
    ]))
    story.append(path_box)
    story.append(Spacer(1, 5*mm))

    # ── SECTION: Clinical Features ────────────────────────────────────────
    story.append(section_header("CLINICAL FEATURES", color=AMBER))
    story.append(Spacer(1, 3*mm))

    cf_data = [
        [Paragraph("<b>Feature</b>", table_header),
         Paragraph("<b>Description</b>", table_header)],
        [Paragraph("Hallmark symptom", emph_cell),
         Paragraph("Cyclical <b>postprandial pain + swelling</b> of the affected gland (salivary colic)", table_cell)],
        [Paragraph("Laterality", table_cell_c),
         Paragraph("<b>Unilateral</b>", table_cell)],
        [Paragraph("Trigger", table_cell_c),
         Paragraph("Eating/smelling food (stimulates saliva β†’ can't drain past stone)", table_cell)],
        [Paragraph("Lemon juice test", table_cell_c),
         Paragraph("Give lemon juice β†’ reproduces the swelling (bedside test)", table_cell)],
        [Paragraph("Palpation (Submandibular)", table_cell_c),
         Paragraph("Bimanual palpation (floor of mouth) may reveal palpable stone in Wharton's duct", table_cell)],
        [Paragraph("Palpation (Parotid)", table_cell_c),
         Paragraph("Stone may be visible at Stensen's duct orifice or palpable along duct course", table_cell)],
        [Paragraph("Salivary flow", table_cell_c),
         Paragraph("Absent / reduced / cloudy / mucopurulent on massaging the gland", table_cell)],
        [Paragraph("Complication", table_cell_c),
         Paragraph("Acute suppurative sialadenitis β†’ abscess; Chronic non-specific sialadenitis", table_cell)],
    ]
    cf_table = Table(cf_data, colWidths=[4.5*cm, 13*cm])
    cf_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), AMBER),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [AMBER_LT, WHITE]),
        ("BOX",           (0,0),(-1,-1), 0.7, AMBER),
        ("INNERGRID",     (0,0),(-1,-1), 0.3, colors.HexColor("#FFB74D")),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("LEFTPADDING",   (0,0),(-1,-1), 8),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(cf_table)
    story.append(Spacer(1, 5*mm))

    # ── SECTION: Investigations / Imaging ─────────────────────────────────
    story.append(section_header("INVESTIGATIONS & IMAGING", color=BLUE))
    story.append(Spacer(1, 3*mm))

    img_data = [
        [Paragraph("<b>Modality</b>", table_header),
         Paragraph("<b>Sensitivity / Notes</b>", table_header),
         Paragraph("<b>Use</b>", table_header)],
        [Paragraph("Ultrasound", emph_cell),
         Paragraph("Detects ~90% of stones &gt;2 mm; no radiation; dynamic; operator-dependent", table_cell),
         Paragraph("First-line", sty("G", fontSize=8.8, textColor=GREEN, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12))],
        [Paragraph("CT (non-contrast, 1-2mm cuts)", table_cell_c),
         Paragraph("Highly accurate; avoid contrast (opacified vessels mimic stones); shows gland enlargement + ductal dilatation", table_cell),
         Paragraph("Emergency / complex cases", table_cell_c)],
        [Paragraph("Plain radiograph (occlusal)", table_cell_c),
         Paragraph("Only radiopaque stones; misses radiolucent stones; can confuse with phleboliths, atherosclerosis", table_cell),
         Paragraph("Historical / limited", sty("R", fontSize=8.8, textColor=RED, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12))],
        [Paragraph("MRI", table_cell_c),
         Paragraph("Stone = low signal on BOTH T1 and T2 weighted images", table_cell),
         Paragraph("Complex cases", table_cell_c)],
        [Paragraph("Digital subtraction sialography", table_cell_c),
         Paragraph("Sensitivity 95-100%; detects radiolucent stones; INVASIVE; <b>contraindicated</b> in active infection or distal Wharton duct stones", table_cell),
         Paragraph("Complex / radiolucent stones", table_cell_c)],
        [Paragraph("MR sialography", table_cell_c),
         Paragraph("Non-invasive; uses saliva as contrast; accuracy β‰ˆ digital sialography; better when digital sialography contraindicated", table_cell),
         Paragraph("When other methods contraindicated", table_cell_c)],
    ]
    img_table = Table(img_data, colWidths=[4.2*cm, 9.3*cm, 4*cm])
    img_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), BLUE),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [BLUE_LT, WHITE]),
        ("BOX",           (0,0),(-1,-1), 0.7, BLUE),
        ("INNERGRID",     (0,0),(-1,-1), 0.3, colors.HexColor("#90CAF9")),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("LEFTPADDING",   (0,0),(-1,-1), 8),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(img_table)
    story.append(Spacer(1, 5*mm))

    # ── SECTION: Management ───────────────────────────────────────────────
    story.append(section_header("MANAGEMENT", color=GREEN))
    story.append(Spacer(1, 3*mm))

    mgmt_data = [
        [Paragraph("<b>Approach</b>", table_header),
         Paragraph("<b>Method</b>", table_header),
         Paragraph("<b>Indication</b>", table_header)],
        # Conservative
        [Paragraph("Conservative\n(1st line)", sty("CL", fontSize=8.8, textColor=GREEN,
                   fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12)),
         Paragraph("Sialagogues (lemon drops) + hydration + local heat + gland massage + antibiotics if infected", table_cell),
         Paragraph("All patients initially", table_cell_c)],
        # Transoral
        [Paragraph("Transoral removal", table_cell_c),
         Paragraph("Milking or incision into duct (duct slitting)", table_cell),
         Paragraph("Distal submandibular stones ≀2 cm from duct orifice (palpable)", table_cell_c)],
        # Sialendoscopy
        [Paragraph("Sialendoscopy β˜…\n(Modern gold standard)", sty("SL", fontSize=8.8, textColor=TEAL,
                   fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12)),
         Paragraph("Miniature endoscope (0.8–1.6mm) + wire basket / holmium laser / lithotripsy; success 80–100%; gland-preserving", table_cell),
         Paragraph("Stones &lt;5mm (distal); Parotid stones &lt;7mm; Intraparenchymal 5–7mm", table_cell_c)],
        # ESWL
        [Paragraph("ESWL", table_cell_c),
         Paragraph("External shock wave lithotripsy; NOT suitable for stones &gt;7–10mm", table_cell),
         Paragraph("Non-palpable, non-visualised, impacted stones (submandibular / parotid)", table_cell_c)],
        # Combined
        [Paragraph("Combined / Hybrid", table_cell_c),
         Paragraph("Endoscopy + external incision for stone localisation + removal", table_cell),
         Paragraph("Impacted stones not removable endoscopically", table_cell_c)],
        # Gland excision
        [Paragraph("Gland excision\n(LAST RESORT)", sty("RL", fontSize=8.8, textColor=RED,
                   fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12)),
         Paragraph("Submandibular gland resection or parotidectomy", table_cell),
         Paragraph("Failed all other methods; large / mega stones", table_cell_c)],
    ]
    mgmt_table = Table(mgmt_data, colWidths=[3.8*cm, 8.5*cm, 5.2*cm])
    mgmt_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), GREEN),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [GREEN_LT, WHITE]),
        ("BOX",           (0,0),(-1,-1), 0.7, GREEN),
        ("INNERGRID",     (0,0),(-1,-1), 0.3, colors.HexColor("#A5D6A7")),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("LEFTPADDING",   (0,0),(-1,-1), 8),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(mgmt_table)
    story.append(Spacer(1, 5*mm))

    # ── SECTION: Key Mnemonics + Quick Facts Box ──────────────────────────
    story.append(section_header("KEY FACTS  &  MNEMONICS", color=PURPLE))
    story.append(Spacer(1, 3*mm))

    mnemo_items = [
        ("<b>WHARTON's duct mnemonic for stone predisposition:</b>  <b>W</b>ide + <b>H</b>igh Ca²⁺ + "
         "<b>A</b>gainst gravity + <b>R</b>etrograde bacterial entry + <b>T</b>ortuous + "
         "<b>O</b>blique course + <b>N</b>idus (organic gel) β†’ Stone"),
        "<b>Stone composition = 'dental tartar'</b> (calcium & magnesium phosphates + organic matrix)",
        "<b>MRI signal:</b> LOW on <u>both</u> T1 AND T2 (calcification = dark on MRI)",
        "<b>Sialography contraindications:</b> Active infection + Distal Wharton duct stones",
        "<b>Serum Ca²⁺ levels are NOT raised</b> in sialolithiasis (local process)",
        "<b>Sialendoscopy stent:</b> Left for 2–4 weeks post-procedure to prevent stricture",
    ]
    mnemo_data = [[Paragraph(f"β€’ {t}", body_style)] for t in mnemo_items]
    mnemo_t = Table(mnemo_data, colWidths=[W])
    mnemo_t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), PURPLE_LT),
        ("BOX",           (0,0),(-1,-1), 0.7, PURPLE),
        ("INNERGRID",     (0,0),(-1,-1), 0.2, colors.HexColor("#CE93D8")),
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("LEFTPADDING",   (0,0),(-1,-1), 10),
    ]))
    story.append(mnemo_t)
    story.append(Spacer(1, 4*mm))

    # ── SECTION: Differentials ────────────────────────────────────────────
    story.append(section_header("DIFFERENTIAL DIAGNOSIS", color=RED))
    story.append(Spacer(1, 3*mm))

    dd_items = [
        ["Parotitis / Mumps", "Usually bilateral; no calculus; viral etiology"],
        ["Salivary gland neoplasm", "Painless, slow-growing; no cyclical pattern; mixed tumor most common in submandibular"],
        ["Lymph node enlargement", "No salivary flow changes; lymphadenopathy features"],
        ["Phleboliths", "Calcification on X-ray; not in duct path"],
        ["Atherosclerosis (lingual artery)", "Vascular calcification on radiograph"],
        ["Calcified cervical lymph nodes", "Different location, no salivary symptoms"],
        ["Mucocele / Ranula", "Floor of mouth swelling; no colicky pattern"],
    ]
    dd_data = [[Paragraph("<b>Differential</b>", table_header),
                Paragraph("<b>Distinguishing Feature</b>", table_header)]]
    for r in dd_items:
        dd_data.append([Paragraph(r[0], table_cell), Paragraph(r[1], table_cell)])
    dd_table = Table(dd_data, colWidths=[5.5*cm, 12*cm])
    dd_table.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), RED),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [RED_LT, WHITE]),
        ("BOX",           (0,0),(-1,-1), 0.7, RED),
        ("INNERGRID",     (0,0),(-1,-1), 0.3, colors.HexColor("#EF9A9A")),
        ("TOPPADDING",    (0,0),(-1,-1), 5),
        ("BOTTOMPADDING", (0,0),(-1,-1), 5),
        ("LEFTPADDING",   (0,0),(-1,-1), 8),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    story.append(dd_table)
    story.append(Spacer(1, 4*mm))

    # ── FOOTER ────────────────────────────────────────────────────────────
    footer_text = (
        "Sources: Cummings Otolaryngology Head & Neck Surgery | Bailey & Love's Short Practice of Surgery 28th Ed. | "
        "S. Das Manual on Clinical Surgery 13th Ed. | Robbins & Cotran Pathologic Basis of Disease  "
        "β”‚  Generated by Orris AI – June 2026"
    )
    story.append(HRFlowable(width=W, thickness=0.5, color=TEAL_MID))
    story.append(Spacer(1, 2*mm))
    story.append(Paragraph(footer_text, small_style))

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

build()
Running Command

cd /home/daytona/workspace/sialolithiasis && python3 build_pdf.py 2>&1

Reading File
Editing File

~/sialolithiasis/build_pdf.py

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

cd /home/daytona/workspace/sialolithiasis && python3 build_pdf.py 2>&1

Your PDF is ready! πŸŽ‰

Sialolithiasis Quick Reference

PDF Document Β· PDF

Here's what's included in the single-page (A4) colour-coded quick reference card:
SectionColour
Definition + EpidemiologyTeal / Amber boxes
Gland Distribution table (why submandibular is most affected)Teal
Stone Composition + PathogenesisCharcoal / Purple
Clinical Features tableAmber/Orange
Investigations & Imaging tableBlue
Management table (conservative β†’ sialendoscopy β†’ last resort)Green
Key Facts & MnemonicsPurple
Differential DiagnosisRed
Designed for quick exam revision - all key facts, imaging pearls, and management steps are colour-coded and clearly separated. Sources cited from Cummings Otolaryngology, Bailey & Love, and Robbins & Cotran at the footer.

Conduct my quiz

Asking for Preferences
This is a shared conversation. Sign in to Orris to start your own chat.