Maximize document quality and readability when faxing a PDF, Word, PowerPoint, Excel, or image file — make it arrive LEGIBLE after a noisy 1-bit Group-3 transmission (a fax's whole job is to be read), then optionally transmit it via a cloud fax API. Use to make a document faxable, convert it to bilevel, fix a muddy or unreadable fax, keep small text and signatures readable, halftone photos, or send a fax. Triggers: "fax this Word doc", "prep these scans to fax", "send this as a fax".
Scanned 8/30/2026
Install to Claude Code
npx -y skills add petehottelet/pdf-fax-optimizer --skill pdf-fax-optimizer --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Pdf Fax Optimizer?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/petehottelet-pdf-fax-optimizer)More formats (shields.io, HTML) on the badges page.
---
name: pdf-fax-optimizer
description: >-
Maximize document quality and readability when faxing a PDF, Word, PowerPoint,
Excel, or image file — make it arrive LEGIBLE after a noisy 1-bit Group-3
transmission (a fax's whole job is to be read), then optionally transmit it via
a cloud fax API. Use to make a document faxable, convert it to bilevel, fix a
muddy or unreadable fax, keep small text and signatures readable, halftone
photos, or send a fax. Triggers: "fax this Word doc", "prep these scans to
fax", "send this as a fax".
---
# PDF FAX
This skill converts a PDF into a **fax-ready** file and, above all, one that
**arrives LEGIBLE** on the receiving machine.
**Legibility is the entire objective.** A fax exists to be *read on the other
end*, often after surviving a low-resolution, 1-bit, lossy-by-design Group-3
transmission over a noisy phone line. So this skill is built to **maximize
document quality and enhance reception/readability** — keep text crisp, small
fonts and signatures intact, and photos recognizable — *first*. Smaller files
and faster transmission are welcome side effects, never the goal: a tiny fax
that arrives unreadable is a failure. When a trade-off is forced, choose what
stays readable on the receiving machine.
> **Just need to shrink a PDF for email or the web?** That's a different job
> with the opposite trade-offs — use the companion skill instead:
> [pdf-email-optimizer](https://github.com/petehottelet/pdf-email-optimizer).
Verify the environment once:
```bash
python3 -m pdf_fax_optimizer.check_deps # detect-only; prints the pip command
# then, if anything is missing:
pip install pdf-fax-optimizer # or: pip install -r requirements.txt
```
## Requirements
Requires Python 3.10+ with PyMuPDF (fitz), Pillow, numpy, opencv-python, and
img2pdf. Sending a fax additionally needs the requests package; faxing
Office/OpenDocument files (Word/PowerPoint/Excel) needs LibreOffice (headless);
the OCR-driven text-polarity passes (`--ocr-text` and `--recover-text`) need
rapidocr-onnxruntime (self-contained, no system binary). Without OCR the skill
still works — it falls back to the binarizer's default black-on-white for
document text and skips the within-image recover-text recolor. No CLI tools are
required for PDF/image input. Verify deps with `python3 -m
pdf_fax_optimizer.check_deps`; install with `pip install pdf-fax-optimizer` (add
the `[ocr,send]` extras for OCR and cloud-fax sending) or `pip install -r
requirements.txt`.
## How it works
**Read `references/fax-optimization.md` before running** — it explains the
constraints below and why each knob exists. Do not skip it; the defaults only
make sense once you understand the Group-3 transmission model.
The goal of every choice here is **a document that arrives readable.** Each knob
exists to protect legibility against a lossy channel — keeping edges sharp,
rescuing faint strokes, and choosing halftones that don't collapse to mud after
the receiving machine re-thresholds. Optimize for what the recipient can *read*,
not for the smallest byte count.
The core constraint: Group-3 fax is **1-bit bilevel** (pure black/white, no
gray), compressed with run-length codes (CCITT G3/G4) *along each scanline*.
That last fact is the hinge for every halftone decision — anything that creates
many black↔white transitions per line compresses badly, transmits slowly, and is
more vulnerable to line noise. Fax mode is fundamentally a balance between
**visual fidelity** and **transition density**.
The pipeline runs at the **source's NATIVE resolution with SQUARE pixels,
hard-capped at 300 PPI** — raster input (a PNG/JPG, a scanned page) comes
through pixel-for-pixel below the ceiling and bicubic-downsamples to 300 PPI
above it, **never upscaled, never anisotropically stretched.** 300 PPI is the
legibility plateau of the 1-bit fax channel, and a square 300-PPI grid keeps
page buffers at ~8 MP for letter-size. (*Background:* classic fax is
**anisotropic** — a fine preset is 196 lines-per-inch vertical, super-fine 391
lpi vertical — but this pipeline renders a **square** grid whose 300 PPI exceeds
both of those vertical line rates, so dropping the stretched axis costs nothing
the channel could carry.) Upscaling a wrapped raster bicubic-interpolates its
baked-in text and soft letterforms break the binarizer ("ABC" reads as "A8C"); a
raster source's text quality is *fundamentally* bounded by its own pixel grid, so
the pipeline honours that exactly. The `--fax-resolution` preset (`fine` /
`superfine`, **default `superfine`**) sets the halftone screen detail and the
rasterization DPI for **vector content** (whose glyphs are real vectors the
renderer can rasterise crisp at any DPI), clipped to the 300-PPI ceiling. On a
**mixed page** — live vector text plus an embedded low-DPI raster — the preset
acts as a *floor* for the live text, so a single 72-DPI image can no longer drag
the whole page (and its crisp body text) down to 72 PPI; a higher-DPI embedded
raster can still pull the page up toward the 300 cap. At low native DPI the
recommender auto-picks an FM screen
(`blue-noise` / `atkinson`) — its dot pitch is the pixel itself, with no
multi-pixel cell, so the screen looks fine and organic where a clustered cell
would collapse to a chunky 24-lpi magazine pitch. Pass `--transmission-safe`
to clamp the final output back to a 1728-px-wide Group-3 scanline if you need
to send through a real fax machine.
Run it:
```bash
python3 -m pdf_fax_optimizer.optimize_pdf INPUT.pdf -o OUTPUT.pdf \
--sample 1 --report OUTPUT.report.json # superfine + preserve_text; OCR recover_text is opt-in
```
### Input: PDF, Office, or image
`INPUT` doesn't have to be a PDF. The optimizer normalizes other formats to PDF
first (via `pdf_fax_optimizer.to_pdf`), then runs the identical pipeline:
- **PDF** — used directly.
- **Images** (`.png/.jpg/.tif/.bmp/.gif/.webp`) — wrapped to PDF with `img2pdf`
(no extra tools).
- **Office / OpenDocument / text** (`.doc/.docx/.rtf/.odt/.txt`, `.ppt/.pptx/.odp`,
`.xls/.xlsx/.ods/.csv`) — rendered to PDF by **LibreOffice headless**
(`soffice`). If LibreOffice isn't installed the skill says so; install it (no
GUI needed) or have the user export to PDF. `--keep-converted-pdf` keeps the
intermediate PDF beside the output.
```bash
python3 -m pdf_fax_optimizer.optimize_pdf proposal.docx -o proposal.fax.pdf # Word → fax PDF
```
What the pipeline does, per page (details in the reference):
1. **Rasterize at NATIVE resolution, SQUARE pixels, capped at 300 PPI.** Raster
input (a PNG/JPG, a scanned page) renders at its native pixels-per-inch
exactly when below the ceiling — pixel-for-pixel with the source, no
bicubic upsample to "lift" it — and downsamples cleanly to 300 PPI above
it. Vector pages rasterise square at the preset DPI (`fine` 196 /
`superfine` 391, default `superfine`), again clipped to 300 PPI. The
(square) effective DPI is embedded in the output TIFF/PDF so the page is
correctly proportioned, and the 300-PPI ceiling keeps per-page buffers at
~8 MP for letter-size regardless of source resolution.
2. **Segment content (MRC-lite).** Photo/continuous-tone regions are isolated
(PDF embedded-image rectangles + a variance heuristic for full-page wrapped
rasters). For colour sources a **chroma gate** also fires: a candidate
block has to carry real colour to be classified as photo, which keeps
grayscale form-table cells, message bodies, and printed text rows out of
the halftone path (their variance alone is indistinguishable from a real
photo). The chroma gate self-disables on grayscale sources. Document text
and line art outside the photo region go to the adaptive binarizer; the
photo region goes to a halftone schema. *Never dither text.*
3. **OCR (off by default).** The OCR engine is the slow step (~20 min on a
6-page 391-DPI deck) and is **only run when `--recover-text` is on**. When
it runs it provides the #808080 polarity recolour in two scopes:
- **Document text OUTSIDE images** (header/footer/form text). Every
recognised word is bucketed by the **#808080 rule**: median field
luminance below 128 → glyphs marked WHITE; at or above 128 → glyphs
marked BLACK. (`--ocr-text off` keeps the OCR pass but skips this
scope.)
- **Text INSIDE images** (`--recover-text on`). Same #808080 rule, scoped
to the photo region. Each word's ORIGINAL glyph pixels are segmented
from the colour image and marked BLACK or WHITE per its sign's median
field — preserving real letterforms, never retypesetting.
Without OCR (the default) the chroma-aware photo segmenter keeps form/
body/footer text out of the halftone path and the adaptive binarizer's
contrast threshold pulls dark text to solid black against any near-white
field — which is correct for the overwhelmingly common case. OCR is the
escape hatch for white-on-coloured headers, signage inside photos, and
captions baked into screenshots.
4. **Preserve-text rescue (default on, no OCR needed).** When dark text
sits on *any saturated-colour fill* — a highlight chip behind a slide
label, a tinted callout box, a colored table cell, a status badge in a
dashboard, a filled banner, a colored form field — the bright fill
collapses to a mid-tone in grayscale and the contrast binarizer flips
polarity, painting the field solid black and knocking the text out as
a mangled crosshatch. The preserve-text pass runs ahead of the
binarizer: small (`< 4%` of page), high-chroma, low-variance regions
that carry dark text strokes get **lifted to white in the gray image**
so the dark text reads as crisp black-on-white through the standard
binarize path. The "this is a highlight" colour cue is sacrificed —
on 1-bit fax it was going to die anyway — and the text survives.
Large colour panels and photo content are protected by the area cap
and the `~photo` mask; the rescue never touches the photo region.
Disable with `--no-preserve-text` if you'd rather keep the fill as a
halftoned tone band.
5. **Pre-clean:** flatten near-white backgrounds to pure white, despeckle, and
deskew (the photo mask and text masks ride the deskew rotation).
6. **Build the bilevel page in three layers, composited in this order:**
- **Image layer** — halftone the photo region (with dot-gain pre-
correction; `--dither auto` picks the schema).
- **Document layer** — adaptive binarization for everything else, so vector/
document text stays crisp solid black.
- **Text layer (ABOVE the others)** — the OCR-driven recolor: BLACK pixels
forced to 0, WHITE pixels forced to 255. Because text rides this layer,
the halftone screen can never disturb glyphs.
7. **Defend legibility:** optionally thicken hairlines, warn on inverted /
heavy-black pages.
8. **Emit CCITT G4** inside the PDF (default) or a Class-F multipage TIFF
(`--format tiff`) — losslessly, via img2pdf, never re-encoded. Pass
`--transmission-safe` to also clamp the scanline to 1728 px.
9. **Report** per-page transmission estimate, recoloured words (with their
confidences and polarities), total pages, and any warnings — so the result
is inspectable *before* someone faxes something unreadable.
The mindset is **optimize the document for the channel**, not "make it look like
a fax": keep text vector-crisp, render photos so they stay recognizable, and
spend bits where they buy legibility. The halftone/binarization *schema* is the
control surface for that — pick it deliberately.
### Halftone schemas (the curated comparison)
A continuous-tone photo can't exist in 1-bit fax; it must be *simulated* with
patterns of black dots. The schema chosen is the single biggest lever on how a
photo reads after transmission, and each sits at a different point on the
**fidelity ↔ transition-density** curve (transitions = compression cost = line
fragility). The skill ships six front-line schemas spanning the design space
(full theory in `references/fax-optimization.md`):
1. **`clustered`** — clustered-dot AM screening (newsprint). Dots grow in
clusters → long runs → **best G4 compression and most robust over a noisy
line**; lowest apparent resolution. The default for `--fax-heavy`.
2. **`green-noise`** — hybrid AM–FM screening. Mid-size dot clusters give
**blue-noise detail with clustered-dot run-length and robustness**; tune with
`--green-noise-coarseness` (~2 detail … 8 robust). The `auto` picker's
balanced fallback for moderate photo content; the picker chooses other
members of the detail family — `floyd`/`jarvis`/`edd`/`atkinson`/`clustered`
— when the page's content (mean/std luma, edge density, bimodality, fine
texture) signals a clearer match.
3. **`blue-noise`** — void-and-cluster FM screening. Isotropic, organic stipple
with **no directional "worms"**; excellent perceived detail, middling
compression.
4. **`atkinson`** — Atkinson error diffusion. Clean whites and crisp thin
features; good detail, looser compression than screening.
5. **`floyd`** — Floyd–Steinberg error diffusion. The classic; **maximum
detail**, and its dispersed fine-grain speckle is the richest signal to
carry over the channel — more bytes shipped, more fidelity preserved.
6. **`line`** (aliases `woodcut`/`engraving`) — horizontal line screen. Tone
becomes horizontal stripes that **thicken with darkness**; because the strokes
run *along the scanline* it produces almost entirely long runs → **G4 size and
robustness on par with `clustered`**, while reading as a crisp, high-contrast
engraving rather than mud. Great when a line is bad and the photo just has to
stay recognizable.
(Also selectable: `ordered` Bayer; `edd` edge-enhancing error diffusion for text
over a photographic background; `jarvis`/`stucki`/`sierra` heavier kernels; and
`none` = hard threshold for pure text / line art / barcodes.) Because the
pipeline runs at square pixels, the screens are isotropic by construction —
dots stay round on paper without anisotropic correction.
**Generalised AM screen — `--dither screen --dot-shape SHAPE`.** `clustered` is
one specific spot function; the `screen` family exposes the same machinery with
selectable dot shape: `round` (default; byte-identical to `clustered`),
`square` (crisp blocky), `diamond` (the classic newspaper-photo look), or
`ellipse` (smoother midtone joins, chained vertically). `--screen-angle θ`
rotates the dot lattice; off-axis angles trade some G4 compression (shorter
horizontal runs) for the angled-screen aesthetic, and the pipeline logs an
`off_axis_screen:...` warning for `|θ| > 15°`.
**Crosshatch — `--dither crosshatch`.** Layered angled-line screens lit by tone
bands, reading as a pen-and-ink etching. Default `--hatch-angles "0,90"` keeps
transition density close to `line` (compression is *better* than `clustered`
on most pages because each scanline still ends up mostly horizontal runs).
Three or four angles read as a denser engraving but multiply the transition
count along every scanline — the pipeline warns with `crosshatch_dense:...`.
**Mezzotint — `--dither mezzotint` (expressive).** Random-threshold grain — a
velvety, unstructured stippling. Unlike blue-noise FM, mezzotint enforces no
inter-dot spacing, so it has maximum 1-bit transition density per row: **poor
G4 compression and high line-noise sensitivity**. It's not eligible for `auto`
and trips an `expressive_screen:mezzotint` warning if you opt in. Use it when
the artistic surface matters more than channel cost.
### Maximally productive preview — let the user spend their *eye tokens*
Algorithms can rank compression objectively, but **only a human eye can judge
"does this read?"** So don't just pick silently — generate a side-by-side
**contact sheet** with `--sample N --panels K` and let the user spend their
*eye tokens* on the real, encoded output:
```bash
python3 -m pdf_fax_optimizer.optimize_pdf INPUT.pdf -o OUTPUT.pdf \
--fax-resolution fine --sample 1 --panels 6 --report OUTPUT.report.json
```
`--sample N --panels K` renders that page through K side-by-side panels into
one labeled PNG (`OUTPUT.sample_pN.png`), each panel annotated with its
**actual G4 size and estimated transmission time**, with the **auto-pick
highlighted** and a 3-line **settings header** at the top documenting the
exact options used. `--panels` accepts 1, 2, 4 *(default)*, 6, 8, 12, or 20
(`max`); each higher count is a strict superset of the smaller ones, so it's
a clean detail dial — from "preview the optimal" (2 panels) to "compare a
representative subset" (6 panels) to "every halftone screen in the registry"
(20 panels).
The skill therefore does both jobs the user asked for: (a) it **suggests the
optimal** method from the page's content (photo fraction, fax-heavy, line
condition), and (b) it lets the user **choose the optimal** by eye from the
contact sheet. Offer this whenever a fax has meaningful photo content — then
re-run with the chosen `--dither` for the final file.
### Text recolor by the #808080 rule (OCR-driven)
A fax is 1-bit and the receiver re-thresholds on **luminance**. The pipeline
therefore enforces a single, brutally simple legibility contract for every word
on the page: pick BLACK or WHITE by **median field luminance vs `#808080`**
(luma 128) — darker than 128 → text becomes WHITE; at or above 128 → text
becomes BLACK. The recoloured glyphs ride a **text layer composited ABOVE** the
halftoned image layer, so the halftone screen can never disturb them.
OCR (rapidocr-onnxruntime) is the **word locator**, not a typesetter. For every
recognised word the pipeline segments its ORIGINAL glyph pixels from the colour
image (using the OCR box's border ring as the field reference, which is robust
where a blind 2-means split would invert) and stamps *those exact pixels* into
the BLACK or WHITE text mask — preserving the real letterforms, spacing, and
tilt. It never pastes a synthetic font.
The same function runs in two scopes — but the **OCR engine itself only
runs when `--recover-text` is on** (it is the slow step; in default mode the
chroma-aware photo segmenter and the adaptive binarizer handle text routing
without it):
- **`--recover-text`** (default **`off`**) is the master switch — it
enables the OCR pass. When on it covers text **INSIDE** the image regions
— signage, captions baked into a photo. Polarity is decided **per sign**
(words grouped by proximity, one field tone for the whole group), so co-
located words on the same plate get one consistent treatment. This is
what brings back the cream "VILLA DEL SOL" lettering on the cyan/gold/
tan covers even when grayscale flattens it.
- **`--ocr-text`** (default `auto`) is a sub-switch — when recover-text
is on, this controls whether the same OCR pass *also* recolours text
**OUTSIDE** the image regions (the page's header/footer/form text on
coloured bars). Set it `off` to keep the within-image recolour while
leaving doc text to the binarizer.
```bash
python3 -m pdf_fax_optimizer.optimize_pdf cover.pdf -o cover.fax.pdf \
--sample 1 # 4-panel sheet of the recolor, side-by-side
```
- **Optional OCR.** Both passes need `rapidocr-onnxruntime` (`pip install
rapidocr-onnxruntime` — self-contained, no system binary). Without it the
skill still works: document text falls back to the binarizer's default
black-on-white, and the within-image recover pass becomes a no-op.
- **OCR can misread.** Every recoloured word is listed in the summary and
report (`recover_text.words` and `ocr_text.words`) with its confidence,
polarity decision, measured field luminance, and WCAG contrast. **Surface
these to the user to verify.** Low-confidence words (< `--ocr-conf`, default
0.5) are dropped.
- `--recover-text off` disables only the within-image pass; document-text
polarity stays on (it's nearly always desirable).
### The sample contact sheet (`--sample N [--panels K]`)
`--sample N` writes a labelled contact sheet so the user can confirm the
output is legible before sending. The default 4-panel layout is:
1. **ORIGINAL** — the source page in colour, untouched.
2. **TRUE GRAYSCALE** — the same page desaturated; the continuous-tone input
the 1-bit channel has to approximate.
3. **DEFAULT FAX (Otsu)** — bare-minimum bilevel (basic mode: no MRC / OCR /
halftone). The "naive fax" baseline the optimizations improve on.
4. **RECOMMENDED (auto-pick)** — full pipeline with the auto-picker's
recommended dither. The green border + `>> RECOMMENDED <<` badge marks the
skill's suggestion for this page.
Use `--panels K` to ask for 1, 2, 6, 8, 12, or 20 (`max`) panels — every
higher count is a strict superset of the smaller ones:
- `--panels 1` — just the optimized output (single-panel preview)
- `--panels 2` — original + recommended (minimal "before / after")
- `--panels 6` — adds two representative halftones for a quick side-by-side
- `--panels 20` (or `max`) — every screen in the SCREENS registry on YOUR
page (the full catalogue, same layout as `docs/readme/halftone_grid.png`)
```bash
python3 -m pdf_fax_optimizer.optimize_pdf cover.pdf -o cover.fax.pdf --sample 1
# writes cover.fax.sample_p1.png
python3 -m pdf_fax_optimizer.optimize_pdf cover.pdf -o cover.fax.pdf --sample 3 --panels max
# 20-panel "every halftone screen" sheet for page 3 of a multi-page deck
python3 -m pdf_fax_optimizer.optimize_pdf cover.pdf -o cover.fax.pdf --sample 1 \
--sample-include orig,gray,clustered,floyd,line # custom recipe
```
Each fax panel is rendered with the user's actual options (preserve_text,
ocr_text, recover_text, etc.) so the sheet is a faithful preview of the real
fax. A 3-line **settings header** at the top documents which options
produced the sheet — saved PNGs stay self-describing weeks later. Pass
`--no-sample-header` to omit it.
### Special content checks
Always run the report and skim the warnings. Watch for: **barcodes / QR codes**
(verify they survive bilevel — they want a clean threshold, *not* dither),
**signatures / handwriting** (thin low-contrast strokes — candidates for
thickening), **already-bilevel input** (detect and skip reprocessing), and
**large black / inverted areas** (slow and error-prone to transmit).
## Config file (optional)
Instead of flags, pass `--config config.json`. Schema and an annotated example:
`references/config-schema.md`. Flags override config values.
## Output
Always finish by telling the user the output path(s), the total pages +
estimated transmission time, and any warnings the report flagged. **Legibility
is the acceptance test**:
- For an at-a-glance overview, offer the **4-panel sample sheet**
(`--sample N`) showing original / grayscale / default fax / recommended
side by side. This is the fastest way to confirm aspect ratio, that the
halftone is on image areas only, and that the recommended pick reads.
- For a single-panel preview of the exact bytes that will transmit, use
`--sample N --panels 1`.
- When there's real photo content and the user wants to choose between
halftone schemes, ask for more panels: `--sample N --panels 6` for a
curated comparison, `--panels 12` or `--panels max` (=20) for a full
catalogue. The skill highlights its recommended/optimal pick on every
sheet, but the human makes the final call by eye.
- When a page has colored signage / brand-colored type, offer the **recover-text
before/after** (`--recover-text-preview N`) so the user can confirm the
within-image recolor was helpful.
If anything is borderline — small text, faint signatures, muddy photos —
recommend the knob that recovers it (`--thicken`, a higher `--fax-resolution`,
or a different `--dither`) rather than shipping an unreadable fax.
## Send it (optional)
The skill can also **transmit** the optimized file through a cloud fax API — no
machine, modem, or phone line, just an API key and the recipient number in
**E.164** (e.g. `+14155551234`). Built-in providers: `mfax` (mFax/Documo, the
default), `phaxio` (Phaxio/Sinch), and `generic` (any upload API — Telnyx, SRFax,
etc.). Full details and per-provider request shapes: `references/sending.md`.
Optimize and send in one step (always pass keys via env, and **`--dry-run` first**
to confirm the request before transmitting):
```bash
export MFAX_API_KEY=sk_live_xxx
python3 -m pdf_fax_optimizer.optimize_pdf INPUT.pdf -o OUTPUT.fax.pdf \
--transmission-safe \
--send mfax --to +14155551234 --dry-run # drop --dry-run to transmit
```
Pass `--transmission-safe` whenever the file will hit a real Group-3 line — it
clamps the rendered scanline to 1728 px so a real fax machine can transmit it.
Or send an already-optimized file directly:
```bash
python3 -m pdf_fax_optimizer.send_fax OUTPUT.fax.pdf --provider mfax --to +14155551234
```
Rules: **never** put an API key on the command line (use the provider's env var);
confirm the recipient number with the user before a real send; show the user the
`--dry-run` request and the legibility check (preview/report) before transmitting;
and remember a submit response means *queued*, not *delivered* — point the user
to the provider's status webhook/endpoint to confirm receipt.
## Reference files
- `references/fax-optimization.md` — the fax constraint model, resolutions,
dithering theory, MRC segmentation, legibility defense, transmission
economics. **Read before running.**
- `references/config-schema.md` — full JSON config schema + annotated example.
- `references/sending.md` — transmit via a cloud fax API (mFax, Phaxio,
generic): endpoints, auth, env vars, and one-step optimize-and-send.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!