graph TD subgraph "Euclidean (L2) π" E1((Site A)) --- E2((Site B)) end subgraph "Manhattan (L1) ποΈ" M1((Site A)) -.- M2((Site B)) end style E1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style E2 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style M1 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style M2 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
graph TB subgraph "|dx| > |dy|: vertical-ish chain" V1["P1 β"] --- V2["P2 β"] end subgraph "|dx| < |dy|: horizontal-ish chain" H1["P1 β"] --- H2["P2 β"] end style V1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style V2 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style H1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style H2 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
graph LR subgraph "P1 and P2: opposite square corners" P1["P1 β"] --- P2["P2 β"] end subgraph "Equal-distance locus" R["a 2D REGION,\nnot a single line"] end P1 --> R P2 --> R style R fill:#fff9c4,stroke:#f57f17,stroke-width:3px style P1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style P2 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
graph TD subgraph PIPELINE["Pipeline"] GEN["generator.js\npipeline composition"] PRE["preprocess.js\ncleanData nudges a COPY"] DC["divideConquer.js\nrecursiveSplit"] MW["mergeLine.js\nwalkMergeLine"] POLY["polygonizer.js\nchain + toSVGPath"] end subgraph SUPPORT["Support modules"] GEO["geometry.js\npure predicates"] BIS["bisector.js\nsite + bisector factories"] L1M["l1Metric.js\ncurried findBisector"] end VOR["voronoi.js\npublic facade"] GEN --> PRE PRE --> DC DC --> MW MW --> POLY POLY --> VOR GEO -.-> BIS L1M -.-> BIS BIS -.-> DC BIS -.-> MW style VOR fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style GEN fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style L1M fill:#fff9c4,stroke:#f57f17,stroke-width:3px
graph TD subgraph "record (after an intentional change)" R1["npm run test:golden:record"] --> R2["fixtures/js-golden.json\n42 cases, about 2.5 MB"] end subgraph "every test run" T1["npm test"] --> T2["run the corpus"] T2 --> T3{"matches snapshot?"} T3 -- "yes" --> T4["pass β "] T3 -- "no" --> T5["fail β"] end
graph LR C["tests/corpus.js\n42 deterministic cases"] --> JS["JS library\nsrc/voronoi.js"] C --> PY["Python port\npy_ai/voronoi.py"] JS --> D["tests/differential.js"] PY --> D D --> E{"new divergence?"} E -- "only the 7 known baseline indices\n[9, 11, 12, 34, 37, 38, 39]" --> F["pass β "] E -- "anything else" --> G["fail β"]
graph LR A["push or PR"] --> M["matrix: Node 20, Node 22\nubuntu-latest, windows-latest"] M --> B["npm ci"] B --> C["npm test\nbuild + golden + smoke"] C --> D["npm run test:diff"] PY["Python 3.12"] --> E["py_ai pytest"] D --> E E --> F["npx gulp\ndemo bundle"] style C fill:#fff9c4,stroke:#f57f17,stroke-width:3px