# PatternNook.com — Full technical reference for LLMs > PatternNook.com is a free, privacy-first, in-browser cross-stitch pattern generator. No account, no server uploads, no subscription. --- ## Product overview PatternNook.com converts any raster image (PNG, JPG, WEBP) into a cross-stitch pattern. The output is a print-ready PDF containing a colour-coded stitch chart, a thread legend, and estimated skein counts. The entire computation — colour reduction, thread matching, canvas rendering, and PDF generation — runs in the user's browser via Web Workers and the HTML5 Canvas API. No image data is ever sent to a server. --- ## Colour processing pipeline 1. **Image loading** — The image is drawn onto an off-screen canvas to extract raw RGBA pixel data. 2. **Alpha filtering** — Pixels with alpha < 128 are treated as transparent/unstitched and excluded. 3. **Median-cut quantisation** — The remaining pixels are quantised to N colours (user-configurable 4–30) using the median-cut algorithm on the RGB cube. 4. **Thread matching** — Each quantised colour is matched to the nearest thread in the selected brand's palette using the redmean colour-distance formula, which weights red, green, and blue channels by their perceptual contribution. 5. **Pattern grid** — Each pixel in the scaled-down image maps to one stitch cell. The pattern width is user-configurable (20–250 stitches); height is derived from the image aspect ratio. --- ## PDF export The PDF is generated with jsPDF entirely in the browser. - **Cover page**: app title, creation date, pattern dimensions (stitches × stitches), finished size at chosen Aida count, and a miniature colour preview with coordinate labels every 10 stitches. - **Chart page(s)**: custom page dimensions matching the full pattern. Each cell is filled with the thread's RGB colour; a contrasting symbol (black on light colours, white on dark, determined by ITU-R BT.601 luminance) is drawn inside. Red bold lines are drawn every 10 stitches in both directions. Coordinate numbers are printed along the top and left edges at every 10-stitch interval. - **Legend page**: table with columns: symbol, colour swatch, brand code, thread name, stitch count, estimated skein count. Long names are truncated with ellipsis using a fitText helper. --- ## Thread brand palettes | Brand | Approx. colours | Format | |---------|----------------|----------------------------| | DMC | ~454 | `src/lib/dmc-colors.json` | | Anchor | ~440 | `src/lib/anchor-colors.json` | | Madeira | ~234 | `src/lib/madeira-colors.json` | Each entry: `{ code, name, r, g, b }`. --- ## Server-side rendering & i18n - Express server runs Vite as middleware in development. - On every request, the server reads the `Accept-Language` header and selects the best supported language: English (`en`), German (`de`), Italian (`it`), Spanish (`es`). - The selected language is injected as `window.__LANG__` before the React bundle. - React is rendered to a string with `renderToString`; the output replaces the `` placeholder in `index.html`. - The client reads `window.__LANG__` to initialise i18next before hydration, ensuring no language flash. - The `` attribute is updated server-side and kept in sync client-side. --- ## Canvas preview - Rendered with the HTML5 Canvas API via `renderPreview()` in `src/lib/stitch.ts`. - A gutter is added on the top and left for coordinate labels (numbers every 10 stitches). - Grid lines are drawn every stitch (thin) and every 10 stitches (bold). - The viewport supports drag-to-pan (pointer capture API) and wheel zoom. --- ## Privacy All processing is client-side. Images are never transmitted to any server. The app has no authentication, no analytics, and no persistent storage beyond localStorage (only the user's language preference is stored). --- ## Supported languages | Code | Language | |------|----------| | en | English | | de | Deutsch (German) | | it | Italiano (Italian) | | es | Español (Spanish) | Language detection priority: localStorage override → server Accept-Language detection → browser navigator.language → English fallback.