@inkbar/core 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -1
- package/dist/dom.d.mts +597 -40
- package/dist/dom.d.mts.map +1 -1
- package/dist/dom.mjs +2154 -436
- package/dist/dom.mjs.map +1 -1
- package/dist/index.d.mts +16 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +181 -25
- package/dist/index.mjs.map +1 -1
- package/dist/{signatures-BwaXi7C8.d.mts → signatures-CalOktkf.d.mts} +148 -13
- package/dist/signatures-CalOktkf.d.mts.map +1 -0
- package/dist/{signatures-CMapTKrC.mjs → signatures-Do_l2IlM.mjs} +882 -56
- package/dist/signatures-Do_l2IlM.mjs.map +1 -0
- package/package.json +4 -3
- package/dist/signatures-BwaXi7C8.d.mts.map +0 -1
- package/dist/signatures-CMapTKrC.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signatures-CMapTKrC.mjs","names":["GlossFringe","GlossLineEnding","GlossFreeTextStyle","PDF_NAME","isWhite","latin1","numbers","PDF_NAME","GLOSS_FORMAT","GLOSS_VERSION","uuidv7","uuidv7","uuidv7"],"sources":["../src/model/errors.ts","../src/model/events.ts","../src/model/geometry.ts","../src/model/readable.ts","../src/model/selection.ts","../src/pdfjs/load.ts","../src/model/annotations/defaults.ts","../src/model/pdf-date.ts","../src/model/annotations/pdf-names.ts","../src/model/annotations/callout.ts","../src/model/annotations/types.ts","../src/model/annotations/embedded.ts","../src/pdf/lexer.ts","../src/pdf/annotation-fields.ts","../src/pdf/stream.ts","../src/pdf/xref.ts","../src/pdf/objects.ts","../src/model/annotations/embedded-fields.ts","../src/model/env.ts","../src/model/annotations/history.ts","../src/model/annotations/gloss-mapping.ts","../src/model/annotations/json.ts","../src/model/annotations/store.ts","../src/model/page-cache.ts","../src/model/pages.ts","../src/model/source.ts","../src/model/text.ts","../src/model/document.ts","../src/model/annotations/edit.ts","../src/model/annotations/style-map.ts","../src/model/annotations/tool-style.ts","../src/model/annotations/threads.ts","../src/model/annotations/shape-geometry.ts","../src/model/recognise.ts","../src/model/signatures.ts"],"sourcesContent":["export type InkErrorCode =\n | 'PasswordRequired'\n | 'InvalidPdf'\n | 'SourceFetchFailed'\n | 'AssetConfigMissing'\n | 'AssetLoadFailed'\n | 'EngineUnavailable'\n | 'ControlledMutationIgnored'\n | 'DocumentDestroyed'\n | 'PageOutOfRange'\n\nexport class InkError extends Error {\n override readonly name = 'InkError'\n readonly code: InkErrorCode\n readonly details: Readonly<Record<string, unknown>>\n\n constructor(\n code: InkErrorCode,\n message: string,\n details: Record<string, unknown> = {},\n cause?: unknown\n ) {\n super(message, cause === undefined ? undefined : { cause })\n this.code = code\n this.details = details\n }\n}\n\nexport function isInkError(value: unknown): value is InkError {\n return (\n value instanceof InkError ||\n (typeof value === 'object' &&\n value !== null &&\n (value as { name?: unknown }).name === 'InkError')\n )\n}\n","export type Listener<T> = (payload: T) => void\n\nexport class Emitter<Events extends Record<string, unknown>> {\n private listeners = new Map<keyof Events, Set<Listener<never>>>()\n\n on<K extends keyof Events>(event: K, fn: Listener<Events[K]>): () => void {\n let set = this.listeners.get(event)\n if (!set) {\n set = new Set()\n this.listeners.set(event, set)\n }\n set.add(fn)\n return () => {\n set?.delete(fn)\n }\n }\n\n emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n const set = this.listeners.get(event)\n if (!set) return\n for (const fn of [...set]) (fn as Listener<Events[K]>)(payload)\n }\n\n clear(): void {\n this.listeners.clear()\n }\n}\n","/**\n * All geometry in this module is PDF default user space: points, origin at the\n * lower-left of the page, before /Rotate. Pixel conversions live in dom/transform.ts.\n */\nexport interface Point {\n x: number\n y: number\n}\n\n/** Axis-aligned box. `x`,`y` is the lower-left corner. */\nexport interface Rect {\n x: number\n y: number\n width: number\n height: number\n}\n\n/** Four corners in PDF.js's normalised QuadPoints order: upper-left, upper-right, lower-left, lower-right. */\nexport interface Quad {\n p1: Point\n p2: Point\n p3: Point\n p4: Point\n}\n\n/** PDF transformation matrix [a b c d e f]: x' = a·x + c·y + e, y' = b·x + d·y + f. */\nexport type Matrix = readonly [number, number, number, number, number, number]\n\nexport function approxEqual(a: number, b: number, eps = 0.01): boolean {\n return Math.abs(a - b) <= eps\n}\n\nexport function rectFromPoints(a: Point, b: Point): Rect {\n const x = Math.min(a.x, b.x)\n const y = Math.min(a.y, b.y)\n return { x, y, width: Math.abs(a.x - b.x), height: Math.abs(a.y - b.y) }\n}\n\nexport function rectFromQuad(q: Quad): Rect {\n const xs = [q.p1.x, q.p2.x, q.p3.x, q.p4.x]\n const ys = [q.p1.y, q.p2.y, q.p3.y, q.p4.y]\n const x = Math.min(...xs)\n const y = Math.min(...ys)\n return { x, y, width: Math.max(...xs) - x, height: Math.max(...ys) - y }\n}\n\nexport function quadFromRect(r: Rect): Quad {\n const top = r.y + r.height\n const right = r.x + r.width\n return {\n p1: { x: r.x, y: top },\n p2: { x: right, y: top },\n p3: { x: r.x, y: r.y },\n p4: { x: right, y: r.y },\n }\n}\n\nexport function unionRects(rects: readonly Rect[]): Rect {\n if (rects.length === 0) throw new RangeError('unionRects needs at least one rect')\n let x1 = Infinity\n let y1 = Infinity\n let x2 = -Infinity\n let y2 = -Infinity\n for (const r of rects) {\n x1 = Math.min(x1, r.x)\n y1 = Math.min(y1, r.y)\n x2 = Math.max(x2, r.x + r.width)\n y2 = Math.max(y2, r.y + r.height)\n }\n return { x: x1, y: y1, width: x2 - x1, height: y2 - y1 }\n}\n\nexport function rectsIntersect(a: Rect, b: Rect): boolean {\n return (\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height\n )\n}\n\nexport function rectContainsPoint(r: Rect, p: Point): boolean {\n return p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height\n}\n\nexport function translateRect(r: Rect, dx: number, dy: number): Rect {\n return { x: r.x + dx, y: r.y + dy, width: r.width, height: r.height }\n}\n\nexport function translateQuad(q: Quad, dx: number, dy: number): Quad {\n const t = (p: Point): Point => ({ x: p.x + dx, y: p.y + dy })\n return { p1: t(q.p1), p2: t(q.p2), p3: t(q.p3), p4: t(q.p4) }\n}\n\nexport function applyMatrix(m: Matrix, p: Point): Point {\n return { x: m[0] * p.x + m[2] * p.y + m[4], y: m[1] * p.x + m[3] * p.y + m[5] }\n}\n\nexport function invertMatrix(m: Matrix): Matrix {\n const det = m[0] * m[3] - m[1] * m[2]\n if (det === 0) throw new RangeError('matrix is not invertible')\n return [\n m[3] / det,\n -m[1] / det,\n -m[2] / det,\n m[0] / det,\n (m[2] * m[5] - m[3] * m[4]) / det,\n (m[1] * m[4] - m[0] * m[5]) / det,\n ]\n}\n\n/** Returns the matrix that applies `a` first, then `b`. */\nexport function multiplyMatrix(a: Matrix, b: Matrix): Matrix {\n return [\n a[0] * b[0] + a[1] * b[2],\n a[0] * b[1] + a[1] * b[3],\n a[2] * b[0] + a[3] * b[2],\n a[2] * b[1] + a[3] * b[3],\n a[4] * b[0] + a[5] * b[2] + b[4],\n a[4] * b[1] + a[5] * b[3] + b[5],\n ]\n}\n\nexport function pointsFromFlat(flat: ArrayLike<number>): Point[] {\n const out: Point[] = []\n for (let i = 0; i + 1 < flat.length; i += 2) out.push({ x: flat[i]!, y: flat[i + 1]! })\n return out\n}\n\n/** Eight numbers per quad, in PDF.js's normalised order. Trailing partial quads are dropped. */\nexport function quadsFromFlat(flat: ArrayLike<number>): Quad[] {\n const pts = pointsFromFlat(flat)\n const out: Quad[] = []\n for (let i = 0; i + 3 < pts.length; i += 4) {\n out.push({ p1: pts[i]!, p2: pts[i + 1]!, p3: pts[i + 2]!, p4: pts[i + 3]! })\n }\n return out\n}\n","export interface Readable<T> {\n get(): T\n subscribe(fn: (value: T) => void): () => void\n}\n\nexport interface Writable<T> extends Readable<T> {\n set(this: void, value: T): void\n /** Safe to call detached (`const { update } = store`). */\n update(this: void, fn: (value: T) => T): void\n}\n\nexport function writable<T>(initial: T): Writable<T> {\n let value = initial\n const subs = new Set<(v: T) => void>()\n // Not `this.set`: `update` must work detached, e.g. `const { update } = store`.\n const set = (next: T): void => {\n if (Object.is(next, value)) return\n value = next\n for (const fn of [...subs]) fn(value)\n }\n return {\n get: () => value,\n set,\n update(fn) {\n set(fn(value))\n },\n subscribe(fn) {\n subs.add(fn)\n return () => {\n subs.delete(fn)\n }\n },\n }\n}\n\n/**\n * A readable computed from `source`. It subscribes to the source only while it has\n * subscribers of its own, so an unobserved derived value holds no reference to the source.\n */\nexport function derived<T, U>(source: Readable<T>, fn: (value: T) => U): Readable<U> {\n const subs = new Set<(v: U) => void>()\n let cached: U\n let stopSource: (() => void) | undefined\n\n const onSource = (v: T): void => {\n const next = fn(v)\n if (Object.is(next, cached)) return\n cached = next\n for (const sub of [...subs]) sub(next)\n }\n\n return {\n get: () => (stopSource ? cached : fn(source.get())),\n subscribe(sub) {\n if (!stopSource) {\n cached = fn(source.get())\n stopSource = source.subscribe(onSource)\n }\n subs.add(sub)\n return () => {\n if (!subs.delete(sub) || subs.size > 0) return\n stopSource?.()\n stopSource = undefined\n }\n },\n }\n}\n\nexport function readonly<T>(w: Writable<T>): Readable<T> {\n return { get: () => w.get(), subscribe: (fn) => w.subscribe(fn) }\n}\n","import { quadFromRect, type Quad, type Rect } from './geometry'\n\nconst union = (a: Rect, b: Rect): Rect => {\n const x = Math.min(a.x, b.x)\n const y = Math.min(a.y, b.y)\n return {\n x,\n y,\n width: Math.max(a.x + a.width, b.x + b.width) - x,\n height: Math.max(a.y + a.height, b.y + b.height) - y,\n }\n}\n\nconst centreY = (r: Rect): number => r.y + r.height / 2\n\nfunction median(values: number[]): number {\n const sorted = [...values].sort((a, b) => a - b)\n const mid = sorted.length >> 1\n return sorted.length % 2 ? sorted[mid]! : (sorted[mid - 1]! + sorted[mid]!) / 2\n}\n\n/**\n * Merges glyph boxes that share a line into one quad per run, ordered top to bottom (by\n * vertical centre) then left to right. Boxes whose vertical centres are within `tolerance`\n * points count as the same line; boxes with no area are dropped. Within a line, a horizontal\n * gap wider than `gap` points (default 1.5 × the line's median box height) starts a new run,\n * so text selected across a column gutter yields one quad per column. Pure user-space maths.\n */\nexport function mergeLineRects(\n rects: readonly Rect[],\n tolerance = 2,\n gap?: number\n): Quad[] {\n const lines: { bounds: Rect; boxes: Rect[] }[] = []\n for (const r of rects) {\n if (!(r.width > 0 && r.height > 0)) continue\n const line = lines.find((l) => Math.abs(centreY(l.bounds) - centreY(r)) <= tolerance)\n if (!line) {\n lines.push({ bounds: { ...r }, boxes: [r] })\n continue\n }\n line.bounds = union(line.bounds, r)\n line.boxes.push(r)\n }\n const runs: Rect[] = []\n for (const line of lines) {\n const maxGap = gap ?? 1.5 * median(line.boxes.map((b) => b.height))\n const boxes = [...line.boxes].sort((a, b) => a.x - b.x)\n let run = { ...boxes[0]! }\n for (const b of boxes.slice(1)) {\n if (b.x - (run.x + run.width) > maxGap) {\n runs.push(run)\n run = { ...b }\n } else {\n run = union(run, b)\n }\n }\n runs.push(run)\n }\n runs.sort((a, b) => centreY(b) - centreY(a) || a.x - b.x)\n return runs.map(quadFromRect)\n}\n","import { InkError } from '../model/errors'\n\nimport type { PdfAssets, PdfjsDocument, PdfjsLoadingTask, PdfjsModule } from './types'\n\nconst REQUIRED: ReadonlyArray<keyof PdfAssets> = [\n 'worker',\n 'cMaps',\n 'standardFonts',\n 'wasm',\n]\n\nexport function assertAssets(value: unknown): asserts value is PdfAssets {\n const record = (typeof value === 'object' && value !== null ? value : {}) as Record<\n string,\n unknown\n >\n const missing = REQUIRED.filter(\n (k) => typeof record[k] !== 'string' || record[k] === ''\n )\n if (value === undefined || value === null || missing.length > 0) {\n throw new InkError(\n 'AssetConfigMissing',\n 'openDocument needs an `assets` option naming the PDF.js worker, cMaps, standardFonts and wasm locations. ' +\n 'Vite users: add the @inkbar/core/vite plugin and pass `assets` from \"virtual:inkbar-assets\".',\n { missing: value == null ? [...REQUIRED] : missing }\n )\n }\n}\n\nlet modulePromise: Promise<PdfjsModule> | undefined\nlet configuredWorker: string | undefined\n\n/**\n * Loads PDF.js once. `#pdfjs` resolves to the legacy build in Node and the\n * modern build everywhere else (see package.json \"imports\").\n */\nexport async function loadPdfjs(assets: PdfAssets): Promise<PdfjsModule> {\n assertAssets(assets)\n modulePromise ??= import('#pdfjs').catch((cause: unknown) => {\n modulePromise = undefined\n throw new InkError(\n 'AssetLoadFailed',\n 'PDF.js could not be imported',\n { url: assets.worker },\n cause\n )\n }) as Promise<PdfjsModule>\n const pdfjs = await modulePromise\n if (configuredWorker === undefined) {\n pdfjs.GlobalWorkerOptions.workerSrc = assets.worker\n configuredWorker = assets.worker\n } else if (configuredWorker !== assets.worker) {\n throw new InkError(\n 'AssetConfigMissing',\n 'PDF.js worker URL cannot change after the first document is opened',\n { configured: configuredWorker, requested: assets.worker }\n )\n }\n return pdfjs\n}\n\nexport interface OpenProxyOptions {\n assets: PdfAssets\n password?: string | undefined\n /** PDF.js log level (0 errors, 1 warnings, 5 infos). Left to PDF.js when omitted. */\n verbosity?: number | undefined\n}\n\nexport async function openProxy(\n pdfjs: PdfjsModule,\n bytes: Uint8Array,\n options: OpenProxyOptions\n): Promise<{ task: PdfjsLoadingTask; proxy: PdfjsDocument }> {\n const { assets, password, verbosity } = options\n const task = pdfjs.getDocument({\n data: bytes,\n ...(password !== undefined ? { password } : {}),\n ...(verbosity !== undefined ? { verbosity } : {}),\n cMapUrl: assets.cMaps,\n cMapPacked: true,\n standardFontDataUrl: assets.standardFonts,\n wasmUrl: assets.wasm,\n ...(assets.icc !== undefined ? { iccUrl: assets.icc } : {}),\n })\n try {\n const proxy = await task.promise\n return { task, proxy }\n } catch (cause: unknown) {\n try {\n await task.destroy()\n } catch {\n // The caller already receives the mapped load error below; a failure\n // while tearing down the half-open task adds nothing actionable.\n }\n throw mapLoadError(cause, { assets, passwordSupplied: password !== undefined })\n }\n}\n\n/** `PasswordResponses` values from PDF.js (`NEED_PASSWORD = 1`, `INCORRECT_PASSWORD = 2`). */\nconst INCORRECT_PASSWORD = 2\n\n/**\n * PDF.js raises these from `task.promise` when the worker script cannot be\n * imported (in browsers after its real Worker fails and the fake-worker\n * fallback also fails to import `workerSrc`).\n */\nconst WORKER_FAILURE =\n /Setting up fake worker failed|No \"GlobalWorkerOptions\\.workerSrc\" specified/i\n\n/**\n * Only the worker is mapped here. CMap, standard-font and wasm failures are\n * PDF.js warnings with fallbacks that never reject the open promise, so they\n * cannot be detected at open time.\n *\n * PDF.js 6 exports only some exception classes (`PasswordException`,\n * `InvalidPDFException`, `ResponseException`, `AbortException`), and errors\n * that cross the worker boundary are rebuilt by name, so match on `name`.\n * Inputs here are always in-memory bytes, so there is no fetch to fail:\n * every non-password failure means the bytes are not a usable PDF.\n */\nexport function mapLoadError(\n cause: unknown,\n context: { assets: PdfAssets; passwordSupplied?: boolean }\n): InkError {\n const { assets, passwordSupplied = false } = context\n const name = (cause as { name?: unknown } | null)?.name\n const rawMessage = (cause as { message?: unknown } | null)?.message\n const message =\n typeof rawMessage === 'string' && rawMessage !== ''\n ? rawMessage\n : 'Unknown PDF.js error'\n if (WORKER_FAILURE.test(message)) {\n return new InkError(\n 'AssetLoadFailed',\n 'The PDF.js worker could not be loaded. Check the `assets.worker` URL.',\n { url: assets.worker },\n cause\n )\n }\n if (name === 'PasswordException') {\n const wrong = (cause as { code?: unknown }).code === INCORRECT_PASSWORD\n return new InkError(\n 'PasswordRequired',\n wrong\n ? 'The password is incorrect'\n : 'This document is encrypted and needs a password',\n { passwordSupplied, incorrect: wrong },\n cause\n )\n }\n // InvalidPDFException, FormatError, UnknownErrorException, MissingPDFException,\n // UnexpectedResponseException, ResponseException and anything unrecognised.\n return new InkError(\n 'InvalidPdf',\n message,\n {\n pdfjsErrorName: typeof name === 'string' ? name : undefined,\n pdfjsMessage: message,\n },\n cause\n )\n}\n","import type { AnnotationType } from './types'\n\nexport interface AnnotationDefaults {\n color(type: AnnotationType): string\n /** Fill colour for redactions. */\n fill(): string\n opacity(type: AnnotationType): number\n}\n\nconst COLORS: Record<AnnotationType, string> = {\n highlight: '#F2C230',\n underline: '#2B5A9E',\n strikeout: '#C0392B',\n squiggly: '#1F7A4D',\n text: '#F2C230',\n // Free text: the text colour (`defaultStyle.color`). A box's fill has no default.\n freetext: '#151820',\n square: '#C0392B',\n circle: '#C0392B',\n line: '#151820',\n polyline: '#151820',\n polygon: '#151820',\n ink: '#151820',\n // A stamp draws its image; the colour is only what XFDF requires every annotation to carry.\n stamp: '#151820',\n // The loupe's rim.\n loupe: '#151820',\n // The dimming colour.\n mask: '#000000',\n redact: '#C0392B',\n}\n\nexport const staticDefaults: AnnotationDefaults = {\n color: (type) => COLORS[type],\n fill: () => '#000000',\n opacity: (type) => (type === 'highlight' ? 0.4 : 1),\n}\n\nconst VARIABLES: Record<AnnotationType, string> = {\n highlight: '--ink-highlight',\n underline: '--ink-underline',\n strikeout: '--ink-strikeout',\n squiggly: '--ink-squiggly',\n text: '--ink-note',\n freetext: '--ink-free-text',\n square: '--ink-shape',\n circle: '--ink-shape',\n line: '--ink-shape',\n polyline: '--ink-shape',\n polygon: '--ink-shape',\n ink: '--ink-ink',\n stamp: '--ink-ink',\n loupe: '--ink-shape',\n mask: '--ink-mask',\n redact: '--ink-redact',\n}\n\n/** Resolves default colours from CSS custom properties on `el`, falling back to `staticDefaults`. */\nexport function cssVariableDefaults(el: Element): AnnotationDefaults {\n const read = (name: string): string | undefined => {\n const view = el.ownerDocument.defaultView\n if (!view) return undefined\n return normalizeColor(view.getComputedStyle(el).getPropertyValue(name))\n }\n return {\n color: (type) => read(VARIABLES[type]) ?? staticDefaults.color(type),\n fill: () => read('--ink-redact-fill') ?? staticDefaults.fill(),\n opacity: (type) => staticDefaults.opacity(type),\n }\n}\n\n/** Accepts `#rgb`, `#rrggbb`, `rgb(r, g, b)` and `rgb(r g b)`; returns `#RRGGBB` or undefined. */\nexport function normalizeColor(value: string): string | undefined {\n const v = value.trim()\n const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(v)\n if (short) {\n const [, r = '', g = '', b = ''] = short\n return `#${r}${r}${g}${g}${b}${b}`.toUpperCase()\n }\n if (/^#[0-9a-f]{6}$/i.test(v)) return v.toUpperCase()\n const rgb = /^rgba?\\(\\s*(\\d{1,3})[\\s,]+(\\d{1,3})[\\s,]+(\\d{1,3})/i.exec(v)\n if (rgb) {\n const hex = [rgb[1], rgb[2], rgb[3]]\n .map((n) => Math.min(255, Number(n)).toString(16).padStart(2, '0'))\n .join('')\n return `#${hex}`.toUpperCase()\n }\n return undefined\n}\n","/** Parses a PDF date string (`D:YYYYMMDDHHmmSSOHH'mm'`) into ISO 8601. Returns `fallback` on anything unparseable. */\nexport function parsePdfDate(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const m =\n /^(?:D:)?(\\d{4})(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?(Z|[+-]\\d{2}(?:'\\d{2}')?)?/.exec(\n value.trim()\n )\n if (!m) return fallback\n const [, y, mo = '01', d = '01', h = '00', mi = '00', s = '00', zone] = m\n let offsetMinutes = 0\n if (zone && zone !== 'Z') {\n const sign = zone.startsWith('-') ? -1 : 1\n const zh = Number(zone.slice(1, 3))\n const zm = Number(zone.slice(4, 6) || 0)\n offsetMinutes = sign * (zh * 60 + zm)\n }\n const utc =\n Date.UTC(Number(y), Number(mo) - 1, Number(d), Number(h), Number(mi), Number(s)) -\n offsetMinutes * 60_000\n if (Number.isNaN(utc)) return fallback\n return new Date(utc).toISOString()\n}\n","import { PDF_NAME } from 'gloss-format'\nimport { z } from 'zod'\n\nexport { INTENTS, LINE_ENDINGS, NOTE_ICONS, PDF_NAME } from 'gloss-format'\n\n/**\n * A set of PDF names Inkbar knows that stays open: any other valid PDF name loads, is kept and\n * is written back unchanged. The output type keeps autocomplete for the known values.\n */\nexport function pdfNameSet<const K extends readonly [string, ...string[]]>(known: K) {\n return z\n .union([z.enum(known), z.string().regex(PDF_NAME, 'expected a PDF name')])\n .describe(\n `One of ${known.join(', ')}. Any other PDF name is allowed and kept unchanged.`\n ) as z.ZodType<K[number] | (string & {}), K[number] | (string & {})>\n}\n\n/** True when `v` is one of the values in `list`. */\nexport function isKnown<K extends readonly string[]>(list: K, v: string): v is K[number] {\n return (list as readonly string[]).includes(v)\n}\n","// Free-text callouts as PDF and XFDF store them: `rect` holds box and leader line together,\n// `fringe` insets it to the text box, `callout` runs from the tip to the box and `head` is the\n// ending at the tip.\nimport { Fringe as GlossFringe } from 'gloss-format'\nimport { z } from 'zod'\n\nimport { isKnown, LINE_ENDINGS } from './pdf-names'\n\nimport type { Annotation, FreeTextAnnotation, LineEnding } from './types'\nimport type { Point, Rect } from '../geometry'\n\n/**\n * The insets from a free text's `rect` to its text box, in points (PDF `/RD`, XFDF `fringe`,\n * both in this order).\n */\nexport const FringeSchema = z.object(GlossFringe.shape)\n\nexport type Fringe = z.infer<typeof FringeSchema>\n\n/** An ending's length, and its full width, as a multiple of the stroke width. */\nconst ENDING_SCALE = 3\n\n/**\n * A free text's text box: `rect` inset by `fringe`, or `rect` itself without one. Insets wider\n * or taller than `rect` leave a box of width or height 0 at the inset origin.\n */\nexport function freeTextBox(a: Pick<FreeTextAnnotation, 'rect' | 'fringe'>): Rect {\n const { rect, fringe } = a\n if (!fringe) return rect\n return {\n x: rect.x + fringe.left,\n y: rect.y + fringe.bottom,\n width: Math.max(0, rect.width - fringe.left - fringe.right),\n height: Math.max(0, rect.height - fringe.top - fringe.bottom),\n }\n}\n\n/**\n * True for a free-text callout drawn the standard way: a box with a leader line through\n * `callout`. A callout with `cornerRadius` is Inkbar's speech bubble instead.\n */\nexport function isStandardCallout(\n a: Annotation\n): a is FreeTextAnnotation & { callout: Point[] } {\n return (\n a.type === 'freetext' &&\n a.intent === 'FreeTextCallout' &&\n a.callout !== undefined &&\n a.callout.length >= 2 &&\n a.cornerRadius === undefined\n )\n}\n\n/**\n * The leader line's stroke: the border colour, else the text colour, and the border width, with\n * 1 pt when the box has no border.\n */\nexport function calloutStroke(a: FreeTextAnnotation): { color: string; width: number } {\n return {\n color: a.borderColor ?? a.defaultStyle.color,\n width: a.width > 0 ? a.width : 1,\n }\n}\n\n/**\n * The `rect` and `fringe` that hold the text box `box` and a leader line through `callout`\n * stroked `width` points wide: every point is padded by half the stroke, and by the ending's\n * size as well when `head` is one Inkbar draws.\n */\nexport function withCalloutBounds(\n box: Rect,\n callout: readonly Point[],\n width: number,\n head: LineEnding | undefined\n): { rect: Rect; fringe: Fringe } {\n const drawn = head !== undefined && head !== 'None' && isKnown(LINE_ENDINGS, head)\n const pad = width / 2 + (drawn ? ENDING_SCALE * Math.max(width, 1) : 0)\n const xs = [box.x, box.x + box.width, ...callout.map((p) => p.x)]\n const ys = [box.y, box.y + box.height, ...callout.map((p) => p.y)]\n const left = Math.min(...xs) - pad\n const bottom = Math.min(...ys) - pad\n const right = Math.max(...xs) + pad\n const top = Math.max(...ys) + pad\n return {\n rect: { x: left, y: bottom, width: right - left, height: top - bottom },\n fringe: {\n left: box.x - left,\n top: top - (box.y + box.height),\n right: right - (box.x + box.width),\n bottom: box.y - bottom,\n },\n }\n}\n","import {\n Circle,\n Color,\n commonFields,\n FreeText,\n FreeTextStyle as GlossFreeTextStyle,\n GLOSS_FORMAT,\n GLOSS_VERSION,\n Highlight,\n Ink,\n Line,\n LineEnding as GlossLineEnding,\n Note,\n NoteIcon,\n Point,\n Polygon,\n Polyline,\n Rect,\n Redact,\n Square,\n Stamp,\n type Annotation as GlossAnnotation,\n type GlossDocument,\n type UnknownAnnotation,\n} from 'gloss-format'\nimport { z } from 'zod'\n\nimport { FringeSchema } from './callout'\n\nexport {\n GLOSS_FORMAT,\n GLOSS_MEDIA_TYPE,\n GLOSS_SCHEMA_ID,\n GLOSS_VERSION,\n} from 'gloss-format'\n\n// Each schema starts from its Gloss definition and rebuilds it as a plain object, so unknown keys\n// are dropped on import, nested ones included. Inkbar then requires what it always fills in.\n\nexport const PointSchema = z.object(Point.shape)\nexport const RectSchema = z.object(Rect.shape)\nexport const QuadSchema = z.object({\n p1: PointSchema,\n p2: PointSchema,\n p3: PointSchema,\n p4: PointSchema,\n})\n\n/** What Inkbar adds to every Gloss type: the fields it always fills in, and its viewer state. */\nconst Base = {\n /** Bounding box in PDF user space. */\n rect: RectSchema,\n /** Resolved #RRGGBB. Written into the PDF later, so it is always concrete. */\n color: Color,\n opacity: commonFields.opacity.removeDefault(),\n createdAt: commonFields.createdAt.unwrap(),\n modifiedAt: commonFields.modifiedAt.unwrap(),\n /** Created in this session, or imported from the file. Viewer state, never exported. */\n source: z.enum(['session', 'pdf']),\n /** Embedded annotations are locked until the engine can rewrite the file. Viewer state, never exported. */\n locked: z.boolean().optional(),\n}\n\nconst Quads = z.array(QuadSchema).min(1)\n\nexport const TextMarkupSchema = z.object({\n ...Highlight.shape,\n ...Base,\n type: z.enum(['highlight', 'underline', 'strikeout', 'squiggly']),\n quads: Quads,\n})\n\n/** A note's icon (XFDF `icon`): a PDF name, so a name Inkbar does not know is kept. */\nexport const NoteIconSchema = NoteIcon\n\nexport const NoteSchema = z.object({ ...Note.shape, ...Base })\n\n/** A line ending (XFDF `head`/`tail`): a PDF name, so a name Inkbar does not know is kept. */\nexport const LineEndingSchema = GlossLineEnding\n\n/**\n * A key a type refuses outright rather than dropping like other unknown keys: one an older\n * shape used (so its value is not silently lost), or one that means nothing on the type (so a\n * later version is free to give it a meaning).\n */\nconst Refused = z.never().optional()\n\n/**\n * A free-text box's text style, keyed by the CSS property names XFDF writes in its\n * `defaultstyle` string. The older `align` is refused; other unknown keys are dropped.\n */\nexport const FreeTextStyleSchema = z.object({\n ...GlossFreeTextStyle.shape,\n /** The text colour. */\n color: Color,\n align: Refused,\n})\n\n/**\n * Free text, as XFDF has it: `color` is the box's fill and the text style lives in\n * `defaultStyle`. A box in the older shape (top-level `fontFamily`, `fontSize`, `align`) is\n * refused rather than silently losing its style; other unknown keys are dropped.\n */\nexport const FreeTextSchema = z.object({\n ...FreeText.shape,\n ...Base,\n /** The box's fill (XFDF `color`). Absent means no fill. */\n color: FreeText.shape.color,\n /** The box's border colour. Absent means the text colour. */\n borderColor: Color.optional(),\n defaultStyle: FreeTextStyleSchema,\n fringe: FringeSchema.optional(),\n callout: z.array(PointSchema).min(2).max(3).optional(),\n fontFamily: Refused,\n fontSize: Refused,\n align: Refused,\n})\n\nexport const SquareSchema = z.object({ ...Square.shape, ...Base })\n\nexport const CircleSchema = z.object({ ...Circle.shape, ...Base, cornerRadius: Refused })\n\nexport const ShapeSchema = z.discriminatedUnion('type', [SquareSchema, CircleSchema])\n\nexport const LineSchema = z.object({\n ...Line.shape,\n ...Base,\n start: PointSchema,\n end: PointSchema,\n})\n\nconst Vertices = z.array(PointSchema).min(2)\n\nexport const PolylineSchema = z.object({ ...Polyline.shape, ...Base, vertices: Vertices })\n\nexport const PolygonSchema = z.object({\n ...Polygon.shape,\n ...Base,\n vertices: Vertices,\n head: Refused,\n tail: Refused,\n})\n\nexport const PolySchema = z.discriminatedUnion('type', [PolylineSchema, PolygonSchema])\n\nconst InkShape = z.object({\n ...Ink.shape,\n ...Base,\n inklist: z.array(z.array(PointSchema).min(1)).min(1),\n /** Pen pressure from 0 to 1, one value per point of each stroke. Absent means even pressure. */\n pressure: z.array(z.array(z.number().min(0).max(1))).optional(),\n})\n\n/** Pressure must have one value per point of each stroke. */\nfunction checkPressure(\n a: { inklist: unknown[][]; pressure?: unknown[][] | undefined },\n ctx: z.core.$RefinementCtx\n): void {\n if (!a.pressure) return\n const ok =\n a.pressure.length === a.inklist.length &&\n a.pressure.every((p, i) => p.length === a.inklist[i]?.length)\n if (!ok)\n ctx.addIssue({\n code: 'custom',\n path: ['pressure'],\n message: 'pressure must have the same shape as inklist',\n })\n}\n\nexport const InkSchema = InkShape.superRefine(checkPressure)\n\n/** A PNG or JPEG image as a base64 `data:` URL, as XFDF carries a stamp's `<imagedata>`. */\nexport { IMAGE_DATA_URL } from 'gloss-format'\n\n/**\n * An image on the page (XFDF `stamp`), drawn to fill `rect`. Image and typed signatures are\n * stamps with `subject: 'Signature'`.\n */\nexport const StampSchema = z.object({ ...Stamp.shape, ...Base })\n\n/**\n * A loupe (Inkbar's own type, a circle with `custom.inkbar.type: 'loupe'` in a file): a circle\n * inscribed in `rect` that shows the page content under its own centre, magnified. `color` and\n * `width` draw its rim.\n */\nexport const LoupeSchema = z.object({\n type: z.literal('loupe'),\n ...commonFields,\n /** How many times larger the content under the centre is drawn. Above 1. */\n magnification: z.number().gt(1).default(2),\n /** The rim's width in points. */\n width: z.number().nonnegative().default(2),\n ...Base,\n})\n\n/**\n * A mask (Inkbar's own type, a circle or square with `custom.inkbar.type: 'mask'` in a file):\n * dims everything on the page outside `shape` drawn in `rect`, an ellipse inscribed in it or the\n * rectangle itself. `color` is the dimming colour and `dim` how strongly it covers, from 0 to 1.\n * One per page: adding a second replaces the first.\n */\nexport const MaskSchema = z.object({\n type: z.literal('mask'),\n ...commonFields,\n shape: z.enum(['rect', 'ellipse']),\n dim: z.number().min(0).max(1).default(0.5),\n ...Base,\n})\n\nexport const RedactSchema = z.object({\n ...Redact.shape,\n ...Base,\n /** Present when the mark came from text; absent for an area mark. */\n quads: Quads.optional(),\n /** Colour the redaction will be filled with when applied. */\n interiorColor: Color,\n})\n\nexport const AnnotationSchema = z.discriminatedUnion('type', [\n TextMarkupSchema,\n NoteSchema,\n FreeTextSchema,\n SquareSchema,\n CircleSchema,\n LineSchema,\n PolylineSchema,\n PolygonSchema,\n InkSchema,\n StampSchema,\n LoupeSchema,\n MaskSchema,\n RedactSchema,\n])\n\n/** The viewer's own state on an annotation, left out of exports. */\nconst VIEWER_STATE = { source: true, locked: true } as const\n\n/** One exported annotation: the stored annotation without its viewer state. */\nexport const ExportedAnnotationSchema = z.discriminatedUnion('type', [\n TextMarkupSchema.omit(VIEWER_STATE),\n NoteSchema.omit(VIEWER_STATE),\n FreeTextSchema.omit(VIEWER_STATE),\n SquareSchema.omit(VIEWER_STATE),\n CircleSchema.omit(VIEWER_STATE),\n LineSchema.omit(VIEWER_STATE),\n PolylineSchema.omit(VIEWER_STATE),\n PolygonSchema.omit(VIEWER_STATE),\n InkShape.omit(VIEWER_STATE).superRefine(checkPressure),\n StampSchema.omit(VIEWER_STATE),\n LoupeSchema.omit(VIEWER_STATE),\n MaskSchema.omit(VIEWER_STATE),\n RedactSchema.omit(VIEWER_STATE),\n])\n\nexport type Annotation = z.infer<typeof AnnotationSchema>\nexport type ExportedAnnotation = z.infer<typeof ExportedAnnotationSchema>\nexport type AnnotationType = Annotation['type']\nexport type AnnotationOfType<T extends AnnotationType> = Extract<Annotation, { type: T }>\nexport type TextMarkupAnnotation = z.infer<typeof TextMarkupSchema>\nexport type NoteAnnotation = z.infer<typeof NoteSchema>\nexport type FreeTextAnnotation = z.infer<typeof FreeTextSchema>\nexport type FreeTextStyle = z.infer<typeof FreeTextStyleSchema>\nexport type ShapeAnnotation = z.infer<typeof ShapeSchema>\nexport type LineAnnotation = z.infer<typeof LineSchema>\nexport type PolyAnnotation = z.infer<typeof PolySchema>\nexport type InkAnnotation = z.infer<typeof InkSchema>\nexport type StampAnnotation = z.infer<typeof StampSchema>\nexport type LoupeAnnotation = z.infer<typeof LoupeSchema>\nexport type MaskAnnotation = z.infer<typeof MaskSchema>\nexport type RedactAnnotation = z.infer<typeof RedactSchema>\nexport type LineEnding = z.infer<typeof LineEndingSchema>\n/**\n * What `update` takes: any of a type's fields. A free-text `defaultStyle` may be partial; it\n * merges into the current one.\n */\nexport type AnnotationPatch = Annotation extends infer A\n ? A extends FreeTextAnnotation\n ? Omit<Partial<A>, 'defaultStyle'> & { defaultStyle?: Partial<FreeTextStyle> }\n : Partial<A>\n : never\n// Point, Rect and Quad types come from ../geometry; the zod schemas above match them structurally.\n\n/** Keys the store fills in; callers never supply them (except an optional `id`). */\ntype Generated = 'id' | 'createdAt' | 'modifiedAt' | 'source' | 'locked'\n/** Keys the store derives or defaults when absent. */\ntype Defaulted = 'rect' | 'color' | 'opacity'\n\n/** Builds the caller-facing shape of one member from its zod input type. */\ntype InputOf<I> = I extends unknown\n ? Omit<I, Generated | Defaulted> &\n Partial<Pick<I, Extract<Defaulted, keyof I>>> & { id?: string }\n : never\n\ntype FreeTextInput = z.input<typeof FreeTextSchema>\n/** Free text may leave out `defaultStyle`, or any of its keys: the store fills the text colour. */\ntype FreeTextCallerInput = Omit<InputOf<FreeTextInput>, 'defaultStyle'> & {\n defaultStyle?: Partial<z.input<typeof FreeTextStyleSchema>>\n}\n\ntype RedactInput = z.input<typeof RedactSchema>\ntype RedactBase = Omit<InputOf<RedactInput>, 'interiorColor' | 'rect' | 'quads'> & {\n interiorColor?: string\n}\ntype RedactCallerInput =\n | (RedactBase & { rect: RedactInput['rect']; quads?: RedactInput['quads'] })\n | (RedactBase & {\n rect?: RedactInput['rect']\n quads: NonNullable<RedactInput['quads']>\n })\n\n/**\n * What callers pass to `add`. Built from zod input types, so fields with defaults or\n * optional fields may be omitted. A redaction needs `rect` or `quads` (the store\n * derives the other), and `interiorColor` defaults to the store's redaction colour. Free text\n * may leave out `defaultStyle`; its text colour defaults to the store's free-text colour.\n */\nexport type AnnotationInput =\n | InputOf<\n | z.input<typeof TextMarkupSchema>\n | z.input<typeof NoteSchema>\n | z.input<typeof ShapeSchema>\n | z.input<typeof LineSchema>\n | z.input<typeof PolySchema>\n | z.input<typeof InkSchema>\n >\n | (InputOf<z.input<typeof StampSchema>> & { rect: z.input<typeof StampSchema>['rect'] })\n | (InputOf<z.input<typeof LoupeSchema>> & { rect: z.input<typeof LoupeSchema>['rect'] })\n | (InputOf<z.input<typeof MaskSchema>> & { rect: z.input<typeof MaskSchema>['rect'] })\n | FreeTextCallerInput\n | RedactCallerInput\n\nexport const AnnotationDocumentSchema = z.object({\n format: z.literal(GLOSS_FORMAT),\n version: z.literal(GLOSS_VERSION),\n documentKey: z.string().optional(),\n /** Validated item by item on import so unknown types can be preserved. */\n annotations: z.array(z.unknown()),\n})\n\n/**\n * An item whose `type` this version does not know, such as one from a newer writer. It is kept\n * as-is so it survives an import and export round trip.\n */\nexport type ForeignAnnotation = UnknownAnnotation\n\n/** A Gloss document holding Inkbar's annotations and any foreign items it kept. */\nexport interface AnnotationDocument {\n format: GlossDocument['format']\n version: GlossDocument['version']\n documentKey?: string\n annotations: Array<GlossAnnotation | ForeignAnnotation>\n}\n","import {\n pointsFromFlat,\n quadsFromFlat,\n rectFromPoints,\n type Point,\n type Quad,\n type Rect,\n} from '../geometry'\nimport { parsePdfDate } from '../pdf-date'\n\nimport { staticDefaults } from './defaults'\nimport { PDF_NAME } from './pdf-names'\nimport { AnnotationSchema, type Annotation } from './types'\n\nimport type { Fringe } from './callout'\nimport type { PdfjsAnnotationData } from '../../pdfjs/types'\n\nexport const SUPPORTED_SUBTYPES: ReadonlySet<string> = new Set([\n 'Highlight',\n 'Underline',\n 'StrikeOut',\n 'Squiggly',\n 'Text',\n 'FreeText',\n 'Square',\n 'Circle',\n 'Line',\n 'Polygon',\n 'PolyLine',\n 'Ink',\n 'Redact',\n])\n\nexport interface EmbeddedSummary {\n subtype: string\n count: number\n supported: boolean\n}\n\nexport function pdfColorToHex(\n c: ArrayLike<number> | null | undefined,\n fallback: string\n): string {\n if (!c || c.length < 3) return fallback\n const hex = [c[0]!, c[1]!, c[2]!]\n .map((n) => Math.round(n).toString(16).padStart(2, '0'))\n .join('')\n return `#${hex}`.toUpperCase()\n}\n\n/** PDF.js hands back `rect` already in user space, but not always ordered; normalise with min/max. */\nfunction rectFromPdf(r: ArrayLike<number>): Rect {\n return rectFromPoints({ x: r[0]!, y: r[1]! }, { x: r[2]!, y: r[3]! })\n}\n\n/** A PDF name exactly as PDF.js gives it (names are case-sensitive), or undefined if invalid. */\nfunction pdfName(raw: string | undefined): string | undefined {\n return raw !== undefined && PDF_NAME.test(raw) ? raw : undefined\n}\n\n/** `head` and `tail` from a Line's or PolyLine's `/LE`, left out when both are `None`. */\nfunction lineEndingsOf(\n raw: readonly string[] | undefined\n): { head: string; tail: string } | Record<string, never> {\n // PDF.js already turns a name it does not know into `None`.\n const endings = raw?.map((e) => pdfName(e) ?? 'None')\n return endings && endings.length === 2 && endings.some((e) => e !== 'None')\n ? { head: endings[0]!, tail: endings[1]! }\n : {}\n}\n\n/**\n * Imported ids are `pdf:<page>:<pdfjsId>` (page is 0-based, pdfjsId is the annotation's object\n * reference such as `12R`). They are stable across opens of the same file, and `inReplyTo`\n * uses the same scheme so threads resolve.\n */\nexport function importedId(page: number, pdfjsId: string): string {\n return `pdf:${page}:${pdfjsId}`\n}\n\n/**\n * @internal An imported annotation whose fields PDF.js leaves out, to be read from the file itself once\n * the document is ready: a FreeText's `/CL`, `/RD`, `/LE` and `/DA` font, or a note's `/Name`\n * when PDF.js reports `NoIcon`.\n */\nexport interface EmbeddedTarget {\n /** The imported id, `pdf:<page>:<pdfjsId>`. */\n id: string\n subtype: 'FreeText' | 'Text'\n /** The annotation's `/Rect` as PDF.js gives it, `[x1, y1, x2, y2]`. */\n rect: readonly number[]\n /** FreeText only: the `/DA` font resource name. */\n daFont?: string\n}\n\n/**\n * The fields read from the file for one embedded annotation: what PDF.js left out. They merge\n * onto the annotation as it is when they land, so edits made in between are kept.\n */\nexport interface EmbeddedFieldPatch {\n /** FreeText `/CL`: the tip, an optional bend, and where the line meets the box. */\n callout?: Point[]\n /** FreeText `/RD`. */\n fringe?: Fringe\n /** FreeText `/LE`. */\n head?: string\n /** Text `/Name`. */\n icon?: string\n /** FreeText `/DA` font, merged into `defaultStyle`. */\n font?: { fontFamily?: string; fontWeight?: 'bold'; fontStyle?: 'italic' }\n}\n\n/**\n * Imports one page's PDF.js annotation data. `targets` is @internal: the annotations whose\n * missing fields the document reads from the file after `ready`.\n */\nexport function importEmbeddedPage(\n page: number,\n raw: PdfjsAnnotationData[],\n importedAt: string\n): {\n annotations: Annotation[]\n counts: Record<string, number>\n targets: EmbeddedTarget[]\n} {\n const counts: Record<string, number> = {}\n const annotations: Annotation[] = []\n const targets: EmbeddedTarget[] = []\n for (const data of raw) {\n counts[data.subtype] = (counts[data.subtype] ?? 0) + 1\n if (!SUPPORTED_SUBTYPES.has(data.subtype) || data.hidden || data.noView) continue\n const converted = convert(page, data, importedAt)\n if (!converted) continue\n annotations.push(converted)\n const target = targetOf(converted.id, data)\n if (target) targets.push(target)\n }\n return { annotations, counts, targets }\n}\n\nfunction targetOf(id: string, d: PdfjsAnnotationData): EmbeddedTarget | undefined {\n const rect = Array.from(d.rect)\n if (d.subtype === 'Text')\n return d.name === 'NoIcon' ? { id, subtype: 'Text', rect } : undefined\n if (d.subtype !== 'FreeText') return undefined\n const daFont = d.defaultAppearanceData?.fontName\n return { id, subtype: 'FreeText', rect, ...(daFont ? { daFont } : {}) }\n}\n\nexport function summarise(perPage: Record<string, number>[]): EmbeddedSummary[] {\n const totals = new Map<string, number>()\n for (const counts of perPage) {\n for (const [k, v] of Object.entries(counts)) totals.set(k, (totals.get(k) ?? 0) + v)\n }\n return [...totals.entries()]\n .map(([subtype, count]) => ({\n subtype,\n count,\n supported: SUPPORTED_SUBTYPES.has(subtype),\n }))\n .sort((a, b) => (a.subtype < b.subtype ? -1 : a.subtype > b.subtype ? 1 : 0))\n}\n\nfunction convert(\n page: number,\n d: PdfjsAnnotationData,\n importedAt: string\n): Annotation | undefined {\n const created = parsePdfDate(\n d.creationDate,\n parsePdfDate(d.modificationDate, importedAt)\n )\n const author = d.titleObj?.str\n const contents = d.contentsObj?.str\n const stroke = d.borderStyle?.width ?? 1\n const quads: Quad[] = d.quadPoints ? quadsFromFlat(d.quadPoints) : []\n const optional = (v: unknown) => v !== undefined && v !== ''\n const withColor = (type: Annotation['type'], source = d.color) =>\n pdfColorToHex(source, staticDefaults.color(type))\n const intent = pdfName(d.it)\n const base = (type: Annotation['type'], color = withColor(type)) => ({\n id: importedId(page, d.id),\n page,\n rect: rectFromPdf(d.rect),\n color,\n opacity: d.opacity ?? 1,\n ...(optional(author) ? { author } : {}),\n ...(optional(contents) ? { contents } : {}),\n ...(d.inReplyTo ? { inReplyTo: importedId(page, d.inReplyTo) } : {}),\n ...(intent !== undefined ? { intent } : {}),\n createdAt: created,\n modifiedAt: parsePdfDate(d.modificationDate, created),\n source: 'pdf' as const,\n locked: true,\n })\n const fillOf = (c: ArrayLike<number> | null | undefined) =>\n c && c.length >= 3 ? { interiorColor: pdfColorToHex(c, '#FFFFFF') } : {}\n\n let candidate: Record<string, unknown>\n switch (d.subtype) {\n case 'Highlight':\n case 'Underline':\n case 'StrikeOut':\n case 'Squiggly': {\n if (quads.length === 0) return undefined\n const type =\n d.subtype === 'StrikeOut' ? 'strikeout' : (d.subtype.toLowerCase() as 'highlight')\n candidate = { ...base(type), type, quads }\n break\n }\n case 'Text': {\n // PDF.js reports `NoIcon` for any note with an appearance stream, hiding its `/Name`.\n // Leave the icon out then, as when there is no `/Name`, so the default `Note` applies.\n const icon = d.name === 'NoIcon' ? undefined : pdfName(d.name)\n candidate = {\n ...base('text'),\n type: 'text',\n ...(icon !== undefined ? { icon } : {}),\n }\n break\n }\n case 'FreeText': {\n // XFDF and PDF agree: `/C` is the box's fill, `/DA` the text's colour and size.\n const da = d.defaultAppearanceData\n const { color: _stroke, ...rest } = base('freetext')\n candidate = {\n ...rest,\n ...(d.color && d.color.length >= 3\n ? { color: pdfColorToHex(d.color, '#FFFFFF') }\n : {}),\n type: 'freetext',\n contents: contents ?? '',\n width: d.borderStyle?.width ?? 0,\n defaultStyle: {\n color: pdfColorToHex(\n da?.fontColor as ArrayLike<number> | undefined,\n staticDefaults.color('freetext')\n ),\n ...(da && da.fontSize > 0 ? { fontSize: da.fontSize } : {}),\n },\n }\n break\n }\n case 'Square':\n case 'Circle': {\n const type = d.subtype.toLowerCase() as 'square' | 'circle'\n candidate = { ...base(type), type, width: stroke, ...fillOf(d.interiorColor) }\n break\n }\n case 'Line': {\n const l = d.lineCoordinates ?? [d.rect[0], d.rect[1], d.rect[2], d.rect[3]]\n candidate = {\n ...base('line'),\n type: 'line',\n start: { x: l[0], y: l[1] },\n end: { x: l[2], y: l[3] },\n width: stroke,\n ...lineEndingsOf(d.lineEndings),\n }\n break\n }\n case 'Polygon':\n case 'PolyLine': {\n const type = d.subtype === 'Polygon' ? 'polygon' : 'polyline'\n const vertices = d.vertices ? pointsFromFlat(d.vertices) : []\n if (vertices.length < 2) return undefined\n candidate = {\n ...base(type),\n type,\n vertices,\n width: stroke,\n ...fillOf(d.interiorColor),\n ...(type === 'polyline' ? lineEndingsOf(d.lineEndings) : {}),\n }\n break\n }\n case 'Ink': {\n const inklist: Point[][] = (d.inkLists ?? [])\n .map((p) => pointsFromFlat(p))\n .filter((p) => p.length > 0)\n if (inklist.length === 0) return undefined\n candidate = { ...base('ink'), type: 'ink', inklist, width: stroke }\n break\n }\n case 'Redact':\n // PDF.js 6.4 exposes neither QuadPoints nor /OverlayText for Redact, so only quads\n // that happen to be present are used, and `overlaidText` (the text beneath) is ignored.\n candidate = {\n ...base('redact'),\n type: 'redact',\n interiorColor: pdfColorToHex(d.interiorColor, staticDefaults.fill()),\n ...(quads.length > 0 ? { quads } : {}),\n }\n break\n default:\n return undefined\n }\n const parsed = AnnotationSchema.safeParse(candidate)\n return parsed.success ? parsed.data : undefined\n}\n","/** A PDF name object, with `#xx` escapes decoded. */\nexport interface PdfName {\n kind: 'name'\n name: string\n}\n\n/** An indirect reference such as `12 0 R`. */\nexport interface PdfRef {\n kind: 'ref'\n num: number\n gen: number\n}\n\n/** A string object. Its contents are skipped, not decoded. */\nexport interface PdfString {\n kind: 'string'\n}\n\n/** A dictionary object. */\nexport interface PdfDict {\n kind: 'dict'\n entries: Map<string, PdfValue>\n}\n\n/** Any PDF object this reader understands. */\nexport type PdfValue =\n number | boolean | null | PdfName | PdfRef | PdfString | PdfDict | PdfValue[]\n\n/** Thrown when the bytes are not valid PDF object syntax. */\nexport class PdfSyntaxError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PdfSyntaxError'\n }\n}\n\nconst isWhite = (c: number): boolean =>\n c === 0 || c === 9 || c === 10 || c === 12 || c === 13 || c === 32\n\nconst isDelimiter = (c: number): boolean =>\n c === 0x28 || // (\n c === 0x29 || // )\n c === 0x3c || // <\n c === 0x3e || // >\n c === 0x5b || // [\n c === 0x5d || // ]\n c === 0x7b || // {\n c === 0x7d || // }\n c === 0x2f || // /\n c === 0x25 // %\n\nconst isRegular = (c: number): boolean => !isWhite(c) && !isDelimiter(c)\nconst isDigit = (c: number): boolean => c >= 0x30 && c <= 0x39\n\nconst latin1 = (bytes: Uint8Array, from: number, to: number): string => {\n let out = ''\n for (let i = from; i < to; i++) out += String.fromCharCode(bytes[i]!)\n return out\n}\n\nfunction skipSpace(bytes: Uint8Array, offset: number): number {\n let i = offset\n while (i < bytes.length) {\n const c = bytes[i]!\n if (isWhite(c)) {\n i++\n } else if (c === 0x25) {\n while (i < bytes.length && bytes[i] !== 10 && bytes[i] !== 13) i++\n } else {\n break\n }\n }\n return i\n}\n\nfunction tokenEnd(bytes: Uint8Array, offset: number): number {\n let i = offset\n while (i < bytes.length && isRegular(bytes[i]!)) i++\n return i\n}\n\nconst hexValue = (c: number | undefined): number => {\n if (c === undefined) return -1\n if (c >= 0x30 && c <= 0x39) return c - 0x30\n if (c >= 0x41 && c <= 0x46) return c - 0x41 + 10\n if (c >= 0x61 && c <= 0x66) return c - 0x61 + 10\n return -1\n}\n\nfunction parseName(bytes: Uint8Array, offset: number): { value: PdfName; end: number } {\n const end = tokenEnd(bytes, offset + 1)\n let name = ''\n for (let i = offset + 1; i < end; i++) {\n const c = bytes[i]!\n const hi = c === 0x23 ? hexValue(bytes[i + 1]) : -1\n const lo = hi >= 0 ? hexValue(bytes[i + 2]) : -1\n if (hi >= 0 && lo >= 0 && i + 2 < end) {\n name += String.fromCharCode(hi * 16 + lo)\n i += 2\n } else {\n name += String.fromCharCode(c)\n }\n }\n return { value: { kind: 'name', name }, end }\n}\n\nfunction skipLiteralString(bytes: Uint8Array, offset: number): number {\n let depth = 0\n for (let i = offset; i < bytes.length; i++) {\n const c = bytes[i]\n if (c === 0x5c) i++\n else if (c === 0x28) depth++\n else if (c === 0x29 && --depth === 0) return i + 1\n }\n throw new PdfSyntaxError('Unterminated string')\n}\n\n/** After a non-negative integer ending at `end`, looks for `gen R`. */\nfunction tryReference(\n bytes: Uint8Array,\n num: number,\n end: number\n): { value: PdfRef; end: number } | undefined {\n let i = end\n if (i >= bytes.length || !isWhite(bytes[i]!)) return undefined\n i = skipSpace(bytes, i)\n const genStart = i\n while (i < bytes.length && isDigit(bytes[i]!)) i++\n if (i === genStart || i >= bytes.length || !isWhite(bytes[i]!)) return undefined\n const gen = Number(latin1(bytes, genStart, i))\n i = skipSpace(bytes, i)\n if (bytes[i] !== 0x52 || (i + 1 < bytes.length && isRegular(bytes[i + 1]!))) {\n return undefined\n }\n return { value: { kind: 'ref', num, gen }, end: i + 1 }\n}\n\nfunction parseNumberOrKeyword(\n bytes: Uint8Array,\n offset: number\n): { value: PdfValue; end: number } {\n const end = tokenEnd(bytes, offset)\n const token = latin1(bytes, offset, end)\n if (token === 'true') return { value: true, end }\n if (token === 'false') return { value: false, end }\n if (token === 'null') return { value: null, end }\n if (/^[+-]?(\\d+\\.?\\d*|\\.\\d+)$/.test(token)) {\n const n = Number(token)\n if (/^\\d+$/.test(token)) {\n const ref = tryReference(bytes, n, end)\n if (ref) return ref\n }\n return { value: n, end }\n }\n throw new PdfSyntaxError(`Unexpected token \"${token}\" at ${offset}`)\n}\n\n/** Parses one value at `offset`, skipping whitespace and comments first. */\nexport function parseValue(\n bytes: Uint8Array,\n offset: number\n): { value: PdfValue; end: number } {\n const i = skipSpace(bytes, offset)\n if (i >= bytes.length) throw new PdfSyntaxError('Unexpected end of data')\n const c = bytes[i]!\n if (c === 0x2f) return parseName(bytes, i)\n if (c === 0x28) return { value: { kind: 'string' }, end: skipLiteralString(bytes, i) }\n if (c === 0x3c && bytes[i + 1] === 0x3c) return parseDict(bytes, i + 2)\n if (c === 0x3c) {\n let j = i + 1\n while (j < bytes.length && bytes[j] !== 0x3e) j++\n if (j >= bytes.length) throw new PdfSyntaxError('Unterminated hex string')\n return { value: { kind: 'string' }, end: j + 1 }\n }\n if (c === 0x5b) return parseArray(bytes, i + 1)\n if (isRegular(c)) return parseNumberOrKeyword(bytes, i)\n throw new PdfSyntaxError(`Unexpected \"${String.fromCharCode(c)}\" at ${i}`)\n}\n\nfunction parseArray(\n bytes: Uint8Array,\n offset: number\n): { value: PdfValue[]; end: number } {\n const items: PdfValue[] = []\n let i = offset\n for (;;) {\n i = skipSpace(bytes, i)\n if (i >= bytes.length) throw new PdfSyntaxError('Unterminated array')\n if (bytes[i] === 0x5d) return { value: items, end: i + 1 }\n const item = parseValue(bytes, i)\n items.push(item.value)\n i = item.end\n }\n}\n\nfunction parseDict(bytes: Uint8Array, offset: number): { value: PdfDict; end: number } {\n const entries = new Map<string, PdfValue>()\n let i = offset\n for (;;) {\n i = skipSpace(bytes, i)\n if (i >= bytes.length) throw new PdfSyntaxError('Unterminated dictionary')\n if (bytes[i] === 0x3e && bytes[i + 1] === 0x3e) {\n return { value: { kind: 'dict', entries }, end: i + 2 }\n }\n if (bytes[i] !== 0x2f) throw new PdfSyntaxError(`Expected a name key at ${i}`)\n const key = parseName(bytes, i)\n const val = parseValue(bytes, key.end)\n entries.set(key.value.name, val.value)\n i = val.end\n }\n}\n\nfunction readInteger(bytes: Uint8Array, offset: number): { n: number; end: number } {\n const i = skipSpace(bytes, offset)\n let end = i\n while (end < bytes.length && isDigit(bytes[end]!)) end++\n if (end === i) throw new PdfSyntaxError(`Expected an integer at ${i}`)\n return { n: Number(latin1(bytes, i, end)), end }\n}\n\n/** Parses `num gen obj <value> [stream]` at `offset`. `streamStart` is the first data byte after `stream` and its EOL. */\nexport function parseIndirect(\n bytes: Uint8Array,\n offset: number\n): { num: number; gen: number; value: PdfValue; streamStart?: number } {\n const num = readInteger(bytes, offset)\n const gen = readInteger(bytes, num.end)\n const kw = skipSpace(bytes, gen.end)\n if (latin1(bytes, kw, tokenEnd(bytes, kw)) !== 'obj') {\n throw new PdfSyntaxError(`Expected \"obj\" at ${kw}`)\n }\n const { value, end } = parseValue(bytes, kw + 3)\n const result: { num: number; gen: number; value: PdfValue; streamStart?: number } = {\n num: num.n,\n gen: gen.n,\n value,\n }\n const next = skipSpace(bytes, end)\n if (latin1(bytes, next, next + 6) === 'stream' && !isRegular(bytes[next + 6] ?? 32)) {\n let start = next + 6\n if (bytes[start] === 13 && bytes[start + 1] === 10) start += 2\n else if (bytes[start] === 10 || bytes[start] === 13) start += 1\n result.streamStart = start\n }\n return result\n}\n\n/** Reads a dictionary entry. */\nexport const dictGet = (d: PdfDict, key: string): PdfValue | undefined =>\n d.entries.get(key)\n\n/** True for a name object, optionally one with the given spelling. */\nexport const isName = (v: unknown, name?: string): v is PdfName =>\n typeof v === 'object' &&\n v !== null &&\n (v as PdfName).kind === 'name' &&\n (name === undefined || (v as PdfName).name === name)\n\n/** True for a dictionary object. */\nexport const isDict = (v: PdfValue | undefined): v is PdfDict =>\n typeof v === 'object' && v !== null && !Array.isArray(v) && v.kind === 'dict'\n\n/** True for an indirect reference. */\nexport const isRef = (v: PdfValue | undefined): v is PdfRef =>\n typeof v === 'object' && v !== null && !Array.isArray(v) && v.kind === 'ref'\n","import { PDF_NAME } from '../model/annotations/pdf-names'\n\nimport {\n dictGet,\n isDict,\n isName,\n type PdfDict,\n type PdfRef,\n type PdfValue,\n} from './lexer'\n\nimport type { PdfObjects } from './objects'\n\nexport interface FontFields {\n fontFamily?: string\n fontWeight?: 'bold'\n fontStyle?: 'italic'\n}\n\nexport interface FreeTextFields {\n /** Two or three points, tip first. */\n callout?: { x: number; y: number }[]\n fringe?: { left: number; top: number; right: number; bottom: number }\n head?: string\n font?: FontFields\n}\n\n/** `12R` → {num:12,gen:0}, `12R3` → {num:12,gen:3}; anything else undefined. */\nexport function refOfPdfjsId(id: string): PdfRef | undefined {\n const m = /^(\\d+)R(\\d+)?$/.exec(id)\n if (!m) return undefined\n return { kind: 'ref', num: Number(m[1]), gen: m[2] === undefined ? 0 : Number(m[2]) }\n}\n\nconst FAMILIES: [RegExp, string][] = [\n [/^(helvetica|helv)/i, 'Helvetica'],\n [/^(times|tiro)/i, 'Times'],\n [/^cour(ier|$)/i, 'Courier'],\n]\n\n/**\n * BaseFont (or bare resource name) → Inkbar font fields; undefined for Symbol and ZapfDingbats.\n * A family matches by prefix, so `HelveticaNeue` reads as Helvetica and `CourierNewPS` as\n * Courier. Any other name keeps its own family, minus a trailing `MT` or `PSMT`.\n * With `knownOnly`, a name outside Helvetica, Times and Courier gives undefined: a bare\n * resource id such as `F1` is not a family.\n */\nexport function fontFromBaseName(\n name: string,\n knownOnly = false\n): FontFields | undefined {\n const bare = name.replace(/^[A-Z]{6}\\+/, '')\n if (/^(symbol|zapfdingbats|zadb)/i.test(bare)) return undefined\n const cut = bare.search(/[-,]/)\n const base = cut < 0 ? bare : bare.slice(0, cut)\n const style = cut < 0 ? '' : bare.slice(cut + 1)\n const known = FAMILIES.find(([re]) => re.test(base))\n if (knownOnly && !known) return undefined\n const fontFamily = known ? known[1] : base.replace(/(PS)?MT$/, '')\n if (!fontFamily) return undefined\n const font: FontFields = { fontFamily }\n if (/bold|black|heavy/i.test(style)) font.fontWeight = 'bold'\n if (/italic|oblique/i.test(style)) font.fontStyle = 'italic'\n return font\n}\n\nconst finite = (v: PdfValue | undefined): v is number =>\n typeof v === 'number' && Number.isFinite(v)\n\nasync function numbers(objs: PdfObjects, v: PdfValue | undefined, counts: number[]) {\n const arr = await objs.resolve(v)\n if (!Array.isArray(arr) || !counts.includes(arr.length)) return undefined\n const out = await Promise.all(arr.map((n) => objs.resolve(n)))\n return out.every(finite) ? out : undefined\n}\n\nasync function dictOf(objs: PdfObjects, v: PdfValue | undefined) {\n const d = await objs.resolve(v)\n return isDict(d) ? d : undefined\n}\n\n/** The font's /BaseFont, looked up in a /DR resource dictionary. */\nasync function baseFontIn(objs: PdfObjects, dr: PdfValue | undefined, resource: string) {\n const res = await dictOf(objs, dr)\n const fonts = res && (await dictOf(objs, dictGet(res, 'Font')))\n const font = fonts && (await dictOf(objs, dictGet(fonts, resource)))\n const base = font && (await objs.resolve(dictGet(font, 'BaseFont')))\n return isName(base) ? base.name : undefined\n}\n\nasync function readFont(objs: PdfObjects, annot: PdfDict, daFont: string) {\n const root = await dictOf(objs, dictGet(objs.trailer, 'Root'))\n const acroForm = root && (await dictOf(objs, dictGet(root, 'AcroForm')))\n const sources = [dictGet(annot, 'DR'), acroForm && dictGet(acroForm, 'DR')]\n for (const dr of sources) {\n const base = await baseFontIn(objs, dr, daFont)\n if (base !== undefined) return fontFromBaseName(base)\n }\n return fontFromBaseName(daFont, true)\n}\n\nasync function readHead(objs: PdfObjects, le: PdfValue | undefined) {\n let v = await objs.resolve(le)\n if (Array.isArray(v)) v = await objs.resolve(v[0])\n return isName(v) && PDF_NAME.test(v.name) ? v.name : undefined\n}\n\n/** `rect` is the annotation's [x1 y1 x2 y2], used to reject a fringe that leaves no box. */\nexport async function readFreeTextFields(\n objs: PdfObjects,\n ref: PdfRef,\n rect: readonly number[],\n daFont: string | undefined\n): Promise<FreeTextFields> {\n const fields: FreeTextFields = {}\n try {\n const annot = await objs.get(ref)\n if (!isDict(annot)) return fields\n\n const cl = await numbers(objs, dictGet(annot, 'CL'), [4, 6])\n if (cl) {\n fields.callout = []\n for (let i = 0; i < cl.length; i += 2)\n fields.callout.push({ x: cl[i]!, y: cl[i + 1]! })\n }\n\n const rd = await numbers(objs, dictGet(annot, 'RD'), [4])\n if (rd && rect.length === 4 && rd.every((n) => n >= 0)) {\n const [left, top, right, bottom] = rd as [number, number, number, number]\n const width = Math.abs(rect[2]! - rect[0]!)\n const height = Math.abs(rect[3]! - rect[1]!)\n if (left + right < width && top + bottom < height)\n fields.fringe = { left, top, right, bottom }\n }\n\n const head = await readHead(objs, dictGet(annot, 'LE'))\n if (head !== undefined) fields.head = head\n\n if (daFont !== undefined) {\n const font = await readFont(objs, annot, daFont)\n if (font) fields.font = font\n }\n } catch {\n // Whatever was read before the failure stands.\n }\n return fields\n}\n\nexport async function readTextIcon(\n objs: PdfObjects,\n ref: PdfRef\n): Promise<string | undefined> {\n try {\n const annot = await objs.get(ref)\n if (!isDict(annot)) return undefined\n const name = await objs.resolve(dictGet(annot, 'Name'))\n return isName(name) && PDF_NAME.test(name.name) ? name.name : undefined\n } catch {\n return undefined\n }\n}\n","import { dictGet, isDict, isName, PdfSyntaxError, type PdfDict } from './lexer'\n\nconst ENDSTREAM = Uint8Array.from('endstream', (c) => c.charCodeAt(0))\n\nfunction matchesAt(bytes: Uint8Array, at: number, pattern: Uint8Array): boolean {\n if (at < 0 || at + pattern.length > bytes.length) return false\n for (let i = 0; i < pattern.length; i++) if (bytes[at + i] !== pattern[i]) return false\n return true\n}\n\nfunction findEndstream(bytes: Uint8Array, from: number): number {\n for (let i = from; i + ENDSTREAM.length <= bytes.length; i++) {\n if (matchesAt(bytes, i, ENDSTREAM)) return i\n }\n return bytes.length\n}\n\n/** Raw stream bytes: trusts `length` when `endstream` follows it, otherwise scans. */\nfunction rawData(\n bytes: Uint8Array,\n start: number,\n length: number | undefined\n): Uint8Array {\n if (length !== undefined && Number.isInteger(length) && length >= 0) {\n let i = start + length\n while (i < bytes.length && (bytes[i] === 10 || bytes[i] === 13 || bytes[i] === 32))\n i++\n if (matchesAt(bytes, i, ENDSTREAM)) return bytes.subarray(start, start + length)\n }\n let end = findEndstream(bytes, start)\n if (end > start && bytes[end - 1] === 10) end--\n if (end > start && bytes[end - 1] === 13) end--\n return bytes.subarray(start, end)\n}\n\n/** The single filter parameter dictionary, if any. Anything else that is defined is an error. */\nfunction decodeParms(dict: PdfDict): PdfDict | undefined {\n const parms = dictGet(dict, 'DecodeParms') ?? dictGet(dict, 'DP')\n const first = Array.isArray(parms) ? parms[0] : parms\n if (first === undefined || first === null) return undefined\n if (!isDict(first)) throw new PdfSyntaxError('Unsupported /DecodeParms')\n return first\n}\n\nfunction numberParam(parms: PdfDict | undefined, key: string, fallback: number): number {\n const v = parms ? dictGet(parms, key) : undefined\n return typeof v === 'number' ? v : fallback\n}\n\nasync function inflate(data: Uint8Array): Promise<Uint8Array> {\n const stream = new Blob([data as BlobPart])\n .stream()\n .pipeThrough(new DecompressionStream('deflate'))\n return new Uint8Array(await new Response(stream).arrayBuffer())\n}\n\nfunction paeth(a: number, b: number, c: number): number {\n const p = a + b - c\n const pa = Math.abs(p - a)\n const pb = Math.abs(p - b)\n const pc = Math.abs(p - c)\n if (pa <= pb && pa <= pc) return a\n return pb <= pc ? b : c\n}\n\nfunction undoPngPredictor(\n data: Uint8Array,\n columns: number,\n colors: number,\n bits: number\n): Uint8Array {\n const bpp = Math.max(1, Math.ceil((colors * bits) / 8))\n const rowBytes = Math.ceil((columns * colors * bits) / 8)\n const rows = Math.floor(data.length / (rowBytes + 1))\n const out = new Uint8Array(rows * rowBytes)\n for (let r = 0; r < rows; r++) {\n const type = data[r * (rowBytes + 1)]!\n const src = r * (rowBytes + 1) + 1\n const dst = r * rowBytes\n for (let x = 0; x < rowBytes; x++) {\n const raw = data[src + x]!\n const left = x >= bpp ? out[dst + x - bpp]! : 0\n const up = r > 0 ? out[dst - rowBytes + x]! : 0\n const upLeft = r > 0 && x >= bpp ? out[dst - rowBytes + x - bpp]! : 0\n let value: number\n switch (type) {\n case 0:\n value = raw\n break\n case 1:\n value = raw + left\n break\n case 2:\n value = raw + up\n break\n case 3:\n value = raw + ((left + up) >> 1)\n break\n case 4:\n value = raw + paeth(left, up, upLeft)\n break\n default:\n throw new PdfSyntaxError(`Unknown PNG filter type ${type}`)\n }\n out[dst + x] = value & 0xff\n }\n }\n return out\n}\n\n/** The decoded data of the stream whose dictionary is `dict` and whose data starts at `start`. `length` is `/Length`, already resolved. */\nexport async function decodeStream(\n bytes: Uint8Array,\n dict: PdfDict,\n start: number,\n length: number | undefined\n): Promise<Uint8Array> {\n const filter = dictGet(dict, 'Filter') ?? dictGet(dict, 'F')\n const filters = Array.isArray(filter) ? filter : filter === undefined ? [] : [filter]\n if (filters.length === 0) return rawData(bytes, start, length)\n if (filters.length > 1 || !isName(filters[0], 'FlateDecode')) {\n throw new PdfSyntaxError('Unsupported stream filter')\n }\n const inflated = await inflate(rawData(bytes, start, length))\n const parms = decodeParms(dict)\n const predictor = numberParam(parms, 'Predictor', 1)\n if (predictor === 1) return inflated\n if (predictor < 10) throw new PdfSyntaxError(`Unsupported predictor ${predictor}`)\n return undoPngPredictor(\n inflated,\n numberParam(parms, 'Columns', 1),\n numberParam(parms, 'Colors', 1),\n numberParam(parms, 'BitsPerComponent', 8)\n )\n}\n","import { isDict, parseIndirect, parseValue, type PdfDict, type PdfValue } from './lexer'\nimport { decodeStream } from './stream'\n\nexport type XrefEntry =\n | { type: 'offset'; offset: number; gen: number }\n | { type: 'compressed'; stream: number; index: number }\n | { type: 'free' }\n\nexport interface Xref {\n entries: Map<number, XrefEntry>\n trailer: PdfDict\n}\n\nconst isWhite = (c: number): boolean =>\n c === 0 || c === 9 || c === 10 || c === 12 || c === 13 || c === 32\n\nconst latin1 = (bytes: Uint8Array, from: number, to: number): string => {\n let out = ''\n for (let i = from; i < to; i++) out += String.fromCharCode(bytes[i]!)\n return out\n}\n\nfunction readToken(bytes: Uint8Array, offset: number): { token: string; end: number } {\n let i = offset\n while (i < bytes.length && isWhite(bytes[i]!)) i++\n const start = i\n while (i < bytes.length && !isWhite(bytes[i]!)) i++\n return { token: latin1(bytes, start, i), end: i }\n}\n\nfunction readInt(bytes: Uint8Array, offset: number): { n: number; end: number } {\n const { token, end } = readToken(bytes, offset)\n if (!/^\\d+$/.test(token)) throw new Error(`Expected an integer at ${offset}`)\n return { n: Number(token), end }\n}\n\nfunction findStartxref(bytes: Uint8Array): number {\n const tail = latin1(bytes, Math.max(0, bytes.length - 1024), bytes.length)\n const at = tail.lastIndexOf('startxref')\n if (at < 0) throw new Error('No startxref')\n return readInt(bytes, bytes.length - tail.length + at + 9).n\n}\n\ninterface Section {\n entries: Map<number, XrefEntry>\n trailer: PdfDict\n}\n\nfunction readTable(bytes: Uint8Array, offset: number): Section {\n const entries = new Map<number, XrefEntry>()\n let i = readToken(bytes, offset).end // past \"xref\"\n for (;;) {\n const head = readToken(bytes, i)\n if (head.token.startsWith('trailer')) {\n // The dictionary may follow the keyword with no space: `trailer<<`.\n const trailer = parseValue(bytes, head.end - (head.token.length - 7)).value\n if (!isDict(trailer)) throw new Error('Trailer is not a dictionary')\n return { entries, trailer }\n }\n const first = readInt(bytes, i)\n const count = readInt(bytes, first.end)\n i = count.end\n for (let k = 0; k < count.n; k++) {\n const off = readInt(bytes, i)\n const gen = readInt(bytes, off.end)\n const kind = readToken(bytes, gen.end)\n i = kind.end\n if (kind.token === 'n') {\n entries.set(first.n + k, { type: 'offset', offset: off.n, gen: gen.n })\n } else if (kind.token === 'f') {\n entries.set(first.n + k, { type: 'free' })\n } else {\n throw new Error(`Bad xref entry type \"${kind.token}\"`)\n }\n }\n }\n}\n\nconst numbers = (v: PdfValue | undefined): number[] | undefined =>\n Array.isArray(v) && v.every((x) => typeof x === 'number' && x >= 0)\n ? (v as number[])\n : undefined\n\nasync function readStream(bytes: Uint8Array, offset: number): Promise<Section> {\n const obj = parseIndirect(bytes, offset)\n const dict = obj.value\n if (!isDict(dict) || obj.streamStart === undefined) {\n throw new Error('Xref stream expected')\n }\n const length = dict.entries.get('Length')\n const data = await decodeStream(\n bytes,\n dict,\n obj.streamStart,\n typeof length === 'number' ? length : undefined\n )\n const w = numbers(dict.entries.get('W'))\n if (!w || w.length !== 3 || w.some((x) => x > 8)) throw new Error('Bad /W')\n const size = dict.entries.get('Size')\n const index = numbers(dict.entries.get('Index')) ?? [\n 0,\n typeof size === 'number' ? size : 0,\n ]\n const [w0, w1, w2] = w as [number, number, number]\n const rowLength = w0 + w1 + w2\n if (rowLength === 0) throw new Error('Empty xref rows')\n const field = (at: number, width: number): number => {\n let n = 0\n for (let k = 0; k < width; k++) n = n * 256 + data[at + k]!\n return n\n }\n const entries = new Map<number, XrefEntry>()\n let row = 0\n for (let s = 0; s + 1 < index.length; s += 2) {\n for (let k = 0; k < index[s + 1]!; k++, row++) {\n const at = row * rowLength\n if (at + rowLength > data.length) return { entries, trailer: dict }\n const type = w0 === 0 ? 1 : field(at, w0)\n const a = field(at + w0, w1)\n const b = field(at + w0 + w1, w2)\n const num = index[s]! + k\n if (type === 0) entries.set(num, { type: 'free' })\n else if (type === 1) entries.set(num, { type: 'offset', offset: a, gen: b })\n else if (type === 2) entries.set(num, { type: 'compressed', stream: a, index: b })\n }\n }\n return { entries, trailer: dict }\n}\n\nasync function readSection(bytes: Uint8Array, offset: number): Promise<Section> {\n if (!Number.isInteger(offset) || offset < 0 || offset >= bytes.length) {\n throw new Error('Xref offset out of range')\n }\n return readToken(bytes, offset).token === 'xref'\n ? readTable(bytes, offset)\n : readStream(bytes, offset)\n}\n\n/** Newest entry wins along the /Prev chain (and a hybrid file's /XRefStm). Undefined when startxref or a section cannot be read. */\nexport async function readXref(bytes: Uint8Array): Promise<Xref | undefined> {\n try {\n const entries = new Map<number, XrefEntry>()\n const visited = new Set<number>()\n let trailer: PdfDict | undefined\n let next: number | undefined = findStartxref(bytes)\n while (next !== undefined && !visited.has(next)) {\n visited.add(next)\n const section = await readSection(bytes, next)\n trailer ??= section.trailer\n const hybrid = section.trailer.entries.get('XRefStm')\n // A hybrid file's table marks compressed objects free; its XRefStm holds the real entries.\n if (typeof hybrid === 'number' && !visited.has(hybrid)) {\n visited.add(hybrid)\n const extra = await readSection(bytes, hybrid)\n for (const [num, e] of extra.entries) if (!entries.has(num)) entries.set(num, e)\n }\n for (const [num, e] of section.entries) if (!entries.has(num)) entries.set(num, e)\n const prev = section.trailer.entries.get('Prev')\n next = typeof prev === 'number' ? prev : undefined\n }\n return trailer ? { entries, trailer } : undefined\n } catch {\n return undefined\n }\n}\n","import {\n isDict,\n isRef,\n parseIndirect,\n parseValue,\n type PdfDict,\n type PdfRef,\n type PdfValue,\n} from './lexer'\nimport { decodeStream } from './stream'\nimport { readXref, type Xref } from './xref'\n\nexport interface PdfObjects {\n trailer: PdfDict\n /** The object `ref` names, or undefined if it is missing, free, or unreadable. Never throws. */\n get(ref: PdfRef): Promise<PdfValue | undefined>\n /** `v` with one level of reference followed; other values as they are. */\n resolve(v: PdfValue | undefined): Promise<PdfValue | undefined>\n}\n\ninterface ObjectStream {\n decoded: Uint8Array\n first: number\n /** Object numbers and offsets from the header, in order. */\n pairs: { num: number; offset: number }[]\n}\n\nclass Reader implements PdfObjects {\n readonly trailer: PdfDict\n private readonly objectStreams = new Map<number, Promise<ObjectStream | undefined>>()\n\n constructor(\n private readonly bytes: Uint8Array,\n private readonly xref: Xref\n ) {\n this.trailer = xref.trailer\n }\n\n async get(ref: PdfRef): Promise<PdfValue | undefined> {\n try {\n return await this.load(ref, true)\n } catch {\n return undefined\n }\n }\n\n async resolve(v: PdfValue | undefined): Promise<PdfValue | undefined> {\n return isRef(v) ? this.get(v) : v\n }\n\n /** `followLength` is false while resolving a /Length, so a self-referencing length cannot recurse. */\n private async load(ref: PdfRef, followLength: boolean): Promise<PdfValue | undefined> {\n const entry = this.xref.entries.get(ref.num)\n if (!entry || entry.type === 'free') return undefined\n if (entry.type === 'offset') {\n if (entry.gen !== ref.gen) return undefined\n const obj = parseIndirect(this.bytes, entry.offset)\n return obj.num === ref.num && obj.gen === ref.gen ? obj.value : undefined\n }\n if (ref.gen !== 0) return undefined\n const container = await this.objectStream(entry.stream, followLength)\n if (!container) return undefined\n let pair = container.pairs[entry.index]\n if (pair?.num !== ref.num) pair = container.pairs.find((p) => p.num === ref.num)\n if (!pair) return undefined\n return parseValue(container.decoded, container.first + pair.offset).value\n }\n\n private objectStream(\n num: number,\n followLength: boolean\n ): Promise<ObjectStream | undefined> {\n let cached = this.objectStreams.get(num)\n if (!cached) {\n cached = this.readObjectStream(num, followLength).catch(() => undefined)\n this.objectStreams.set(num, cached)\n }\n return cached\n }\n\n private async readObjectStream(\n num: number,\n followLength: boolean\n ): Promise<ObjectStream | undefined> {\n const entry = this.xref.entries.get(num)\n if (entry?.type !== 'offset') return undefined\n const obj = parseIndirect(this.bytes, entry.offset)\n const dict = obj.value\n if (obj.num !== num || !isDict(dict) || obj.streamStart === undefined)\n return undefined\n const n = dict.entries.get('N')\n const first = dict.entries.get('First')\n if (typeof n !== 'number' || typeof first !== 'number') return undefined\n let length = dict.entries.get('Length')\n if (isRef(length)) length = followLength ? await this.loadLength(length) : undefined\n const decoded = await decodeStream(\n this.bytes,\n dict,\n obj.streamStart,\n typeof length === 'number' ? length : undefined\n )\n const pairs: ObjectStream['pairs'] = []\n let at = 0\n for (let i = 0; i < n; i++) {\n const a = parseValue(decoded, at)\n const b = parseValue(decoded, a.end)\n if (typeof a.value !== 'number' || typeof b.value !== 'number') return undefined\n pairs.push({ num: a.value, offset: b.value })\n at = b.end\n }\n return { decoded, first, pairs }\n }\n\n private async loadLength(ref: PdfRef): Promise<PdfValue | undefined> {\n try {\n return await this.load(ref, false)\n } catch {\n return undefined\n }\n }\n}\n\n/** Undefined when the file is encrypted (`/Encrypt` in the trailer) or its xref cannot be read. */\nexport async function openPdfObjects(bytes: Uint8Array): Promise<PdfObjects | undefined> {\n try {\n const xref = await readXref(bytes)\n if (!xref || xref.trailer.entries.has('Encrypt')) return undefined\n return new Reader(bytes, xref)\n } catch {\n return undefined\n }\n}\n","import {\n readFreeTextFields,\n readTextIcon,\n refOfPdfjsId,\n} from '../../pdf/annotation-fields'\nimport { openPdfObjects, type PdfObjects } from '../../pdf/objects'\n\nimport { AnnotationSchema, type Annotation } from './types'\n\nimport type { EmbeddedFieldPatch, EmbeddedTarget } from './embedded'\nimport type { PdfRef } from '../../pdf/lexer'\n\n/**\n * `a` with `fields` merged in: `callout`, `fringe`, `head` and the font keys of `defaultStyle`\n * on a FreeText, `icon` on a note. Undefined when `a` is not embedded, the fields do not fit its\n * type, or the result fails the schema.\n */\nexport function withEmbeddedFields(\n a: Annotation,\n fields: EmbeddedFieldPatch\n): Annotation | undefined {\n if (a.source !== 'pdf') return undefined\n const { callout, fringe, head, icon, font } = fields\n let candidate: Record<string, unknown>\n if (a.type === 'text') {\n if (icon === undefined || callout || fringe || head !== undefined || font)\n return undefined\n candidate = { ...a, icon }\n } else if (a.type === 'freetext') {\n if (icon !== undefined) return undefined\n candidate = {\n ...a,\n ...(callout ? { callout } : {}),\n ...(fringe ? { fringe } : {}),\n ...(head !== undefined ? { head } : {}),\n defaultStyle: { ...a.defaultStyle, ...font },\n }\n } else {\n return undefined\n }\n const parsed = AnnotationSchema.safeParse(candidate)\n return parsed.success ? parsed.data : undefined\n}\n\n/**\n * Reads every target once, calling `getData` only if a target names an annotation in\n * `annotations` by an object reference, and returns the fields read, by id. A target the file\n * adds nothing to, or whose fields would fail the schema, is left out. Never throws: any\n * failure leaves the annotations as they are.\n */\nexport async function readEmbeddedFields(\n annotations: readonly Annotation[],\n targets: readonly EmbeddedTarget[],\n getData: () => Promise<Uint8Array>\n): Promise<Map<string, EmbeddedFieldPatch>> {\n const read = new Map<string, EmbeddedFieldPatch>()\n if (targets.length === 0) return read\n try {\n const byId = new Map(annotations.map((a) => [a.id, a]))\n const work = targets.flatMap((target) => {\n const current = byId.get(target.id)\n const ref = refOfPdfjsId(target.id.split(':')[2] ?? '')\n return current && ref ? [{ target, current, ref }] : []\n })\n if (work.length === 0) return read\n const objs = await openPdfObjects(await getData())\n if (!objs) return read\n for (const { target, current, ref } of work) {\n try {\n const fields = await readFields(objs, target, ref)\n if (fields && withEmbeddedFields(current, fields)) read.set(current.id, fields)\n } catch {\n // One unreadable annotation does not stop the others.\n }\n }\n } catch {\n // Unreadable bytes leave every annotation as PDF.js imported it.\n }\n return read\n}\n\nasync function readFields(\n objs: PdfObjects,\n target: EmbeddedTarget,\n ref: PdfRef\n): Promise<EmbeddedFieldPatch | undefined> {\n if (target.subtype === 'Text') {\n const icon = await readTextIcon(objs, ref)\n return icon === undefined ? undefined : { icon }\n }\n const fields = await readFreeTextFields(objs, ref, target.rect, target.daFont)\n return Object.keys(fields).length > 0 ? fields : undefined\n}\n","/** True only when the build or runtime says production; browsers without `process` count as dev. */\nexport function isProduction(): boolean {\n try {\n return process.env.NODE_ENV === 'production'\n } catch {\n return false\n }\n}\n","import { isProduction } from '../env'\nimport { readonly, writable, type Readable } from '../readable'\n\nimport { withEmbeddedFields } from './embedded-fields'\n\nimport type { AnnotationChange, AnnotationStore } from './store'\nimport type { Annotation } from './types'\n\nexport interface History {\n readonly canUndo: Readable<boolean>\n readonly canRedo: Readable<boolean>\n undo(): void\n redo(): void\n clear(): void\n /**\n * Runs `fn` and records everything it changes as one undo entry. Change events still fire once\n * per annotation. Nested calls join the outer batch. `fn` must be synchronous; changes after an\n * `await` are not part of the batch; a dev build warns when `fn` returns a promise. A throwing\n * `fn` still records what it changed, then rethrows. A batch whose list ends where it began\n * (the same annotations, by identity, in the same order) records nothing and keeps redo.\n * Calling `undo()` or `redo()` inside `fn` is not supported. On a controlled or destroyed\n * history this only runs `fn`, and a history destroyed inside `fn` records nothing.\n */\n batch(fn: () => void): void\n /** Unsubscribes from the store and empties both stacks; undo and redo become no-ops. */\n destroy(): void\n}\n\ninterface Entry {\n before: readonly Annotation[]\n after: readonly Annotation[]\n}\n\n/**\n * Snapshot-based undo and redo over an uncontrolled store.\n *\n * In controlled mode the host owns the list, so history is the host's concern (the Vue layer\n * offers `useHistory`). There `createHistory` returns an inert History: `canUndo` and `canRedo`\n * stay false, `undo` and `redo` do nothing, and nothing is recorded.\n */\nexport function createHistory(\n store: AnnotationStore,\n opts: { limit?: number } = {}\n): History {\n const canUndo = writable(false)\n const canRedo = writable(false)\n\n if (store.mode === 'controlled') {\n return {\n canUndo: readonly(canUndo),\n canRedo: readonly(canRedo),\n undo() {},\n redo() {},\n clear() {},\n batch(fn) {\n fn()\n },\n destroy() {},\n }\n }\n\n const limit = opts.limit ?? 200\n const undoStack: Entry[] = []\n const redoStack: Entry[] = []\n let previous = store.list.get()\n let replaying = false\n /** Open batch depth; while above zero, changes update `previous` but push no entry. */\n let depth = 0\n /** The list when the outermost batch opened (or was restarted by a replace). */\n let batchStart: readonly Annotation[] | null = null\n\n const sync = () => {\n canUndo.set(undoStack.length > 0)\n canRedo.set(redoStack.length > 0)\n }\n\n let destroyed = false\n const unsubscribe = store.on('change', (change: AnnotationChange) => {\n const current = store.list.get()\n // Our own replays (and any other history replace) never become entries.\n if (replaying || (change.kind === 'replace' && change.reason === 'history')) {\n previous = current\n return\n }\n if (change.kind === 'replace' && change.reason === 'embedded') {\n // Fields read from the file late fill in what the import missed: no step, and every\n // snapshot gets the same fields so undo never brings back the unfilled version. Each\n // snapshot keeps its own edits, such as a colour changed before the fields arrived.\n const fill = (list: readonly Annotation[]) =>\n list.map((a) => {\n const f = change.fields.get(a.id)\n return (f && withEmbeddedFields(a, f)) || a\n })\n for (const entry of [...undoStack, ...redoStack]) {\n entry.before = fill(entry.before)\n entry.after = fill(entry.after)\n }\n if (batchStart) batchStart = fill(batchStart)\n previous = current\n return\n }\n if (change.kind === 'replace') {\n undoStack.length = 0\n redoStack.length = 0\n previous = current\n if (depth > 0) batchStart = current\n sync()\n return\n }\n if (depth > 0) {\n previous = current\n return\n }\n undoStack.push({ before: previous, after: current })\n if (undoStack.length > limit) undoStack.shift()\n redoStack.length = 0\n previous = current\n sync()\n })\n\n const apply = (list: readonly Annotation[]) => {\n replaying = true\n try {\n store.replaceAll([...list], 'history')\n } finally {\n replaying = false\n }\n }\n\n return {\n canUndo: readonly(canUndo),\n canRedo: readonly(canRedo),\n undo() {\n const entry = undoStack.pop()\n if (destroyed || !entry) return\n redoStack.push(entry)\n apply(entry.before)\n sync()\n },\n redo() {\n const entry = redoStack.pop()\n if (destroyed || !entry) return\n undoStack.push(entry)\n apply(entry.after)\n sync()\n },\n batch(fn) {\n if (destroyed) {\n fn()\n return\n }\n if (depth++ === 0) batchStart = store.list.get()\n try {\n const result: unknown = fn()\n if (\n result !== null &&\n typeof result === 'object' &&\n typeof (result as { then?: unknown }).then === 'function' &&\n !isProduction()\n ) {\n console.warn(\n '[inkbar] history.batch(fn): fn returned a promise. Changes after its first await are not part of the batch.'\n )\n }\n } finally {\n // A history destroyed inside `fn` records nothing more.\n if (--depth === 0 && !destroyed) {\n const before = batchStart\n batchStart = null\n const after = store.list.get()\n // A list that ends where it began, the same annotations in the same order, is no step.\n if (before && !sameAnnotations(before, after)) {\n undoStack.push({ before, after })\n if (undoStack.length > limit) undoStack.shift()\n redoStack.length = 0\n sync()\n }\n }\n }\n },\n destroy() {\n destroyed = true\n batchStart = null\n unsubscribe()\n undoStack.length = 0\n redoStack.length = 0\n sync()\n },\n clear() {\n undoStack.length = 0\n redoStack.length = 0\n previous = store.list.get()\n sync()\n },\n }\n}\n\n/** The same annotation objects in the same order. */\nfunction sameAnnotations(a: readonly Annotation[], b: readonly Annotation[]): boolean {\n return a === b || (a.length === b.length && a.every((x, i) => x === b[i]))\n}\n","import type { ExportedAnnotation } from './types'\nimport type { Annotation as GlossAnnotation } from 'gloss-format'\n\n/** Inkbar's own data in a Gloss file, under custom.inkbar. */\nexport interface InkbarCustom {\n type?: 'loupe' | 'mask'\n magnification?: number\n dim?: number\n pressure?: number[][]\n borderColor?: string\n}\n\ntype Item = Record<string, unknown>\n\nconst isObject = (v: unknown): v is Item =>\n typeof v === 'object' && v !== null && !Array.isArray(v)\n\n/** `rest` with `own` merged into a copy of its `custom.inkbar`; `own` wins. */\nfunction withCustom(rest: Item, own: InkbarCustom): Item {\n const custom = isObject(rest.custom) ? rest.custom : {}\n const inkbar = isObject(custom.inkbar) ? custom.inkbar : {}\n return { ...rest, custom: { ...custom, inkbar: { ...inkbar, ...own } } }\n}\n\n/**\n * An annotation as a Gloss file writes it. Gloss has no loupe or mask and no pen pressure or\n * free-text border colour, so these go under `custom.inkbar`, with loupes and masks written as\n * the circle or square they draw.\n */\nexport function toFile(annotation: ExportedAnnotation): GlossAnnotation {\n switch (annotation.type) {\n case 'ink': {\n const { pressure, ...rest } = annotation\n return (pressure ? withCustom(rest, { pressure }) : rest) as GlossAnnotation\n }\n case 'freetext': {\n const { borderColor, ...rest } = annotation\n return (borderColor ? withCustom(rest, { borderColor }) : rest) as GlossAnnotation\n }\n case 'loupe': {\n const { magnification, ...rest } = annotation\n return withCustom(\n { ...rest, type: 'circle' },\n { type: 'loupe', magnification }\n ) as GlossAnnotation\n }\n case 'mask': {\n const { shape, dim, ...rest } = annotation\n return withCustom(\n { ...rest, type: shape === 'ellipse' ? 'circle' : 'square' },\n { type: 'mask', dim }\n ) as GlossAnnotation\n }\n default:\n return annotation\n }\n}\n\n/**\n * Moves `keys` from `custom.inkbar` to the top level of `raw`, replacing any top-level value\n * (an absent key deletes it), then drops `custom.inkbar`, and `custom`, if that leaves them\n * empty. Everything else under `custom` stays as it was.\n */\nfunction lift(raw: Item, inkbar: Item, keys: readonly string[], extra: Item = {}): Item {\n const item: Item = { ...raw, ...extra }\n const left: Item = { ...inkbar }\n let consumed = false\n for (const key of keys) {\n delete item[key]\n if (key in left) {\n item[key] = left[key]\n delete left[key]\n consumed = true\n }\n }\n if (!consumed || !isObject(raw.custom)) return item\n const { inkbar: _inkbar, ...others } = raw.custom\n const custom = Object.keys(left).length > 0 ? { ...others, inkbar: left } : others\n if (Object.keys(custom).length > 0) item.custom = custom\n else delete item.custom\n return item\n}\n\n/** A file item read back by `fromFile`. */\nexport interface FromFile {\n /** The object for ExportedAnnotationSchema to parse. */\n item: Record<string, unknown>\n /**\n * Top-level keys of `item` that the file keeps under `custom.inkbar`, so an error in one is\n * reported at `custom.inkbar.<key>`.\n */\n lifted: readonly string[]\n}\n\n/**\n * A raw file item as Inkbar parses it: Inkbar's own data moves out of `custom.inkbar`. An item\n * it doesn't recognise passes through unchanged.\n */\nexport function fromFile(raw: Record<string, unknown>): FromFile {\n const inkbar =\n isObject(raw.custom) && isObject(raw.custom.inkbar) ? raw.custom.inkbar : {}\n const from = (keys: readonly string[], extra?: Item): FromFile => ({\n item: lift(raw, inkbar, keys, extra),\n lifted: keys,\n })\n const unchanged: FromFile = { item: raw, lifted: [] }\n switch (raw.type) {\n // A top-level `pressure` or `borderColor`, as older files wrote them, is dropped.\n case 'ink':\n return from(['pressure'])\n case 'freetext':\n return from(['borderColor'])\n case 'circle':\n if (inkbar.type === 'loupe') return from(['type', 'magnification'])\n if (inkbar.type === 'mask') return from(['type', 'dim'], { shape: 'ellipse' })\n return unchanged\n case 'square':\n if (inkbar.type === 'mask') return from(['type', 'dim'], { shape: 'rect' })\n return unchanged\n default:\n return unchanged\n }\n}\n","import { isProduction } from '../env'\n\nimport { fromFile, toFile } from './gloss-mapping'\nimport {\n AnnotationDocumentSchema,\n ExportedAnnotationSchema,\n GLOSS_FORMAT,\n GLOSS_VERSION,\n type Annotation,\n type AnnotationDocument,\n type ForeignAnnotation,\n} from './types'\n\nimport type { AnnotationStore } from './store'\nimport type { Annotation as GlossAnnotation } from 'gloss-format'\n\nexport interface ImportResult {\n imported: number\n /**\n * Items whose `type` this version does not know (they still need a string `id` and a numeric\n * `page`). Keep them and pass them back to exportAnnotations.\n */\n unknown: ForeignAnnotation[]\n errors: { index: number; issues: string[] }[]\n}\n\nexport interface ImportOptions {\n /** `replace` drops every session annotation first; `merge` overwrites by id and keeps the rest. */\n mode: 'replace' | 'merge'\n}\n\n/**\n * @internal The Gloss types this core parses, taken from its own schemas rather than Gloss's\n * list, so a type a later Gloss adds is still treated as foreign here. Loupes and masks are\n * Inkbar's own types: a file writes them as circles and squares, so a `loupe` or `mask` item is\n * foreign too.\n */\nexport const KNOWN_TYPES: ReadonlySet<string> = new Set(\n ExportedAnnotationSchema.options\n .flatMap((o) => [...o.shape.type._zod.values] as string[])\n .filter((type) => type !== 'loupe' && type !== 'mask')\n)\n\n/**\n * Session annotations plus any preserved foreign items. Embedded (`source: 'pdf'`) ones stay in\n * the file. `source` and `locked` are viewer state and are left out.\n *\n * The result is a JSON copy (`JSON.parse(JSON.stringify(...))`), the same data a serialised\n * export would carry: editing it never touches the store, and values JSON cannot hold, such as\n * functions or `undefined` inside `custom`, are left out exactly as `JSON.stringify` would.\n *\n * Gloss has no loupe or mask, pen pressure or free-text border colour, so Inkbar writes these\n * under `custom.inkbar`, with loupes and masks as the circle or square they draw. Every other key\n * under `custom` goes out as it is.\n *\n * The result validates against the Gloss schema (`gloss-format/schema.json`). Foreign items\n * validate as unknown annotations while their type is one Gloss does not define.\n */\nexport function exportAnnotations(\n store: AnnotationStore,\n preserved: readonly ForeignAnnotation[] = [],\n documentKey?: string\n): AnnotationDocument {\n const session: GlossAnnotation[] = store.list\n .get()\n .filter((a) => a.source === 'session')\n .map(({ source: _source, locked: _locked, ...rest }) => toFile(rest))\n return {\n format: GLOSS_FORMAT,\n version: GLOSS_VERSION,\n ...(documentKey === undefined ? {} : { documentKey }),\n annotations: JSON.parse(JSON.stringify([...session, ...preserved])) as Array<\n GlossAnnotation | ForeignAnnotation\n >,\n }\n}\n\n/** @internal A validated import that has not touched the store yet. */\nexport interface ImportPlan {\n result: ImportResult\n /** Every id the payload brings in, known or foreign. */\n ids: ReadonlySet<string>\n /** Applies the plan to the store (one `replaceAll(..., 'import')`). */\n apply(): void\n}\n\n/**\n * Validates the envelope (throws a TypeError when it is not a gloss v1 document),\n * then each item on its own. Embedded annotations are never touched; imported items become\n * session annotations.\n */\nexport function importAnnotations(\n store: AnnotationStore,\n data: AnnotationDocument | string,\n opts: ImportOptions\n): ImportResult {\n const plan = planImport(store, data, opts)\n plan.apply()\n return plan.result\n}\n\n/**\n * @internal Validation half of `importAnnotations`, so the document can record foreign items\n * before the store publishes the change.\n *\n * Ids are unique across the payload: the first item with an id claims it, and later ones (known\n * or foreign) are reported in `errors`, even when the first was itself rejected. An id that\n * matches an embedded annotation is rejected for known and foreign items alike. In `merge` mode an incoming item replaces whatever session\n * annotation has its id, whether the incoming item is known or foreign.\n */\nexport function planImport(\n store: AnnotationStore,\n data: AnnotationDocument | string,\n opts: ImportOptions\n): ImportPlan {\n const raw: unknown = typeof data === 'string' ? JSON.parse(data) : data\n const envelope = AnnotationDocumentSchema.safeParse(raw)\n if (!envelope.success) {\n throw new TypeError(\n `Expected a ${GLOSS_FORMAT} v${GLOSS_VERSION} document: ${envelope.error.issues\n .map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('; ')}`\n )\n }\n const embeddedIds = new Set(\n store.list\n .get()\n .filter((a) => a.source === 'pdf')\n .map((a) => a.id)\n )\n const result: ImportResult = { imported: 0, unknown: [], errors: [] }\n const incoming: Annotation[] = []\n /** id -> index of the first item that used it, whether that item was accepted or not. */\n const seen = new Map<string, number>()\n /** Ids the import actually brings in. */\n const accepted = new Set<string>()\n /**\n * Reserves `id` for the item at `index`. Later items with the same id are duplicates even\n * when this one is rejected for reusing an embedded id.\n */\n const claim = (id: string, index: number): boolean => {\n const first = seen.get(id)\n if (first !== undefined) {\n result.errors.push({\n index,\n issues: [`id: duplicate id \"${id}\", already used by item ${first}`],\n })\n return false\n }\n seen.set(id, index)\n if (embeddedIds.has(id)) {\n result.errors.push({\n index,\n issues: [\n 'id: matches an annotation embedded in the PDF, which import never replaces',\n ],\n })\n return false\n }\n accepted.add(id)\n return true\n }\n\n envelope.data.annotations.forEach((raw, index) => {\n const type = (raw as { type?: unknown } | null)?.type\n if (typeof type === 'string' && !KNOWN_TYPES.has(type)) {\n if (!isForeign(raw)) {\n result.errors.push({\n index,\n issues: [\n `type: unknown type \"${type}\" needs a string id and a numeric page to be preserved`,\n ],\n })\n } else if (claim(raw.id, index)) {\n result.unknown.push(raw)\n }\n return\n }\n // Inkbar's own data comes back out of `custom.inkbar`: a circle or square marked there as a\n // loupe or mask becomes one. Unknown keys, including `source` and `locked`, are dropped here.\n const { item, lifted } =\n isRecord(raw) && typeof type === 'string'\n ? fromFile(raw)\n : { item: raw, lifted: [] as readonly string[] }\n const parsed = ExportedAnnotationSchema.safeParse(item)\n if (!parsed.success) {\n result.errors.push({\n index,\n // An error in a key Inkbar keeps under custom.inkbar names it where the file has it.\n issues: parsed.error.issues.map((i) => {\n const path = i.path.join('.')\n const own = typeof i.path[0] === 'string' && lifted.includes(i.path[0])\n return `${own ? `custom.inkbar.${path}` : path}: ${i.message}`\n }),\n })\n return\n }\n if (!claim(parsed.data.id, index)) return\n incoming.push({ ...parsed.data, source: 'session' })\n result.imported++\n })\n\n if (result.unknown.length > 0 && !isProduction()) {\n const types = [...new Set(result.unknown.map((u) => u.type))]\n console.warn(\n `[inkbar] importAnnotations kept ${result.unknown.length} annotation(s) of unknown type ` +\n `(${types.join(', ')}). They are not shown, and exportAnnotations writes them back out.`\n )\n }\n\n const ids: ReadonlySet<string> = accepted\n return {\n result,\n ids,\n apply() {\n const current = store.list.get()\n const embedded = current.filter((a) => a.source === 'pdf')\n if (opts.mode === 'replace') {\n store.replaceAll([...embedded, ...incoming], 'import')\n return\n }\n const byId = new Map(\n current\n .filter((a) => a.source === 'session' && !ids.has(a.id))\n .map((a) => [a.id, a])\n )\n for (const a of incoming) byId.set(a.id, a)\n store.replaceAll([...embedded, ...byId.values()], 'import')\n },\n }\n}\n\nfunction isRecord(item: unknown): item is Record<string, unknown> {\n return typeof item === 'object' && item !== null && !Array.isArray(item)\n}\n\nfunction isForeign(item: unknown): item is ForeignAnnotation {\n if (!isRecord(item)) return false\n const { type, id, page } = item\n return typeof type === 'string' && typeof id === 'string' && typeof page === 'number'\n}\n","import { v7 as uuidv7 } from 'uuid'\n\nimport { isProduction } from '../env'\nimport { Emitter } from '../events'\nimport { rectFromQuad, unionRects, type Point, type Rect } from '../geometry'\nimport { readonly, writable, type Readable } from '../readable'\n\nimport { withEmbeddedFields } from './embedded-fields'\nimport {\n AnnotationSchema,\n type Annotation,\n type AnnotationInput,\n type AnnotationPatch,\n} from './types'\n\nimport type { AnnotationDefaults } from './defaults'\nimport type { EmbeddedFieldPatch } from './embedded'\n\nexport type AnnotationChange =\n | { kind: 'add'; annotation: Annotation }\n | { kind: 'update'; id: string; before: Annotation; after: Annotation }\n | {\n kind: 'remove'\n /** The annotation `remove` was called with. */\n annotation: Annotation\n /** Everything that went: `annotation` first, then the replies removed with it. */\n removed: Annotation[]\n }\n | { kind: 'replace'; reason: 'import' | 'sync' | 'history' }\n | {\n kind: 'replace'\n /** Fields read from the file after `ready` filled in embedded annotations. */\n reason: 'embedded'\n /** What was merged into each annotation, by id. */\n fields: ReadonlyMap<string, EmbeddedFieldPatch>\n }\n\nexport type StoreMode =\n | { mode: 'uncontrolled'; initial?: Annotation[] }\n | {\n mode: 'controlled'\n initial: Annotation[]\n onChange: (next: Annotation[], change: AnnotationChange) => void\n }\n\nexport interface AnnotationStore {\n readonly mode: 'uncontrolled' | 'controlled'\n readonly list: Readable<readonly Annotation[]>\n readonly selection: Readable<readonly string[]>\n /** The colour, fill and opacity defaults new annotations get. */\n readonly defaults: AnnotationDefaults\n get(id: string): Annotation | undefined\n byPage(page: number): Annotation[]\n /**\n * Returns the completed annotation. In controlled mode it is proposed to the host, not\n * applied. Throws an `Error` naming the id when it is already in the list, whether it came\n * from `input.id` or the store's `id` generator.\n */\n add(input: AnnotationInput): Annotation\n /**\n * `id`, `type`, `createdAt` and `source` cannot be patched, nor can `locked` on an embedded\n * (`source: 'pdf'`) annotation: those keys are ignored. `modifiedAt` is always bumped. A\n * locked annotation refuses any patch to its geometry, `page` or `contents`.\n */\n update(id: string, patch: AnnotationPatch): Annotation | undefined\n remove(id: string): boolean\n select(ids: string[]): void\n /**\n * Uncontrolled: embedded annotations survive (the list may edit them like `update` would, but\n * cannot drop or add them). Controlled: proposes the list minus embedded items to `onChange`.\n */\n replaceAll(list: Annotation[], reason: 'import' | 'sync' | 'history'): void\n /**\n * Controlled mode only: the host pushes its current list. Embedded (`source: 'pdf'`) items\n * belong to the store, so they stay in `list` whatever the host sends; host items that reuse\n * an embedded id are dropped.\n */\n setControlledValue(list: Annotation[]): void\n /**\n * @internal Replaces the annotations embedded in the file (`source: 'pdf'`). Applied\n * directly in both modes and never passed to `onChange`; the document calls it once on open.\n */\n _setEmbedded(list: readonly Annotation[]): void\n /**\n * @internal Merges fields read from the file into embedded annotations, by id, onto their\n * current version (only ids still present with `source: 'pdf'`; a merge that fails the schema\n * is skipped). A host edit to a read field made before the pass lands is overwritten by the\n * read value. Applied directly in both modes and never passed to `onChange`. Emits\n * `{ kind: 'replace', reason: 'embedded', fields }` when anything changed.\n */\n _patchEmbedded(fields: ReadonlyMap<string, EmbeddedFieldPatch>): void\n /**\n * @internal Like `get`, but in controlled mode it also sees changes proposed to the host and\n * not applied yet: the list `update` and `remove` build on.\n */\n _getProposed(id: string): Annotation | undefined\n completeInput(input: AnnotationInput): Annotation\n on(event: 'change', fn: (change: AnnotationChange) => void): () => void\n destroy(): void\n}\n\nexport interface StoreOptions {\n mode: StoreMode\n defaults: AnnotationDefaults\n now?: () => string\n id?: () => string\n}\n\n/** Keys a locked annotation refuses to change. */\nconst LOCKED_KEYS = new Set([\n 'page',\n 'rect',\n 'quads',\n 'inklist',\n 'start',\n 'end',\n 'vertices',\n 'callout',\n 'contents',\n 'imagedata',\n 'rotation',\n])\n\nfunction keepKey(target: Record<string, unknown>, from: Annotation, key: string): void {\n if (Object.prototype.hasOwnProperty.call(from, key))\n target[key] = (from as Record<string, unknown>)[key]\n else delete target[key]\n}\n\n/** `proposed` as a replacement for embedded `current`, with what the file owns kept from `current`. */\nfunction guardEmbedded(current: Annotation, proposed: Annotation): Annotation {\n if (proposed === current) return current\n if (proposed.type !== current.type) return current\n const candidate: Record<string, unknown> = {\n ...proposed,\n id: current.id,\n createdAt: current.createdAt,\n source: 'pdf',\n }\n keepKey(candidate, current, 'locked')\n if (current.locked) for (const key of LOCKED_KEYS) keepKey(candidate, current, key)\n const parsed = AnnotationSchema.safeParse(candidate)\n return parsed.success ? parsed.data : current\n}\n\nexport function deriveRect(input: AnnotationInput): Rect {\n switch (input.type) {\n case 'highlight':\n case 'underline':\n case 'strikeout':\n case 'squiggly':\n return unionRects(input.quads.map(rectFromQuad))\n case 'redact':\n if (input.quads) return unionRects(input.quads.map(rectFromQuad))\n break\n case 'ink': {\n const pad = (input.width ?? 2) / 2\n const r = bounds(input.inklist.flat())\n return {\n x: r.x - pad,\n y: r.y - pad,\n width: r.width + pad * 2,\n height: r.height + pad * 2,\n }\n }\n case 'line':\n return bounds([input.start, input.end])\n case 'polyline':\n case 'polygon':\n return bounds(input.vertices)\n default:\n break\n }\n if (input.rect) return input.rect\n throw new TypeError(`rect is required for ${input.type}`)\n}\n\nfunction bounds(pts: readonly Point[]): Rect {\n const xs = pts.map((p) => p.x)\n const ys = pts.map((p) => p.y)\n const x = Math.min(...xs)\n const y = Math.min(...ys)\n return { x, y, width: Math.max(...xs) - x, height: Math.max(...ys) - y }\n}\n\n/** `o` without its `undefined` values. */\nfunction withoutUndefined(o: object): Record<string, unknown> {\n return Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined))\n}\n\n/**\n * A `defaultStyle` patch merges one level deep into the current one, so changing the weight\n * keeps the font and size. An `undefined` value removes its key.\n */\nfunction mergedStyle(\n before: Annotation,\n patch: AnnotationPatch\n): { defaultStyle?: Record<string, unknown> } {\n const next = (patch as { defaultStyle?: unknown }).defaultStyle\n if (before.type !== 'freetext' || next === undefined || next === null) return {}\n return { defaultStyle: withoutUndefined({ ...before.defaultStyle, ...next }) }\n}\n\n/** Pending-map key; only annotation changes are tracked, and the prefix keeps ids apart from any other slot. */\nfunction changeKey(change: Exclude<AnnotationChange, { kind: 'replace' }>): string {\n return `annotation:${change.kind === 'update' ? change.id : change.annotation.id}`\n}\n\n/** Structural equality for plain JSON values, ignoring `modifiedAt` at the top level. */\nfunction sameIgnoringModifiedAt(a: Annotation, b: Annotation): boolean {\n const { modifiedAt: _a, ...restA } = a\n const { modifiedAt: _b, ...restB } = b\n return deepEqual(restA, restB)\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null)\n return false\n if (Array.isArray(a) !== Array.isArray(b)) return false\n const ka = Object.keys(a)\n const kb = Object.keys(b)\n if (ka.length !== kb.length) return false\n return ka.every(\n (k) =>\n Object.prototype.hasOwnProperty.call(b, k) &&\n deepEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])\n )\n}\n\nfunction isApplied(change: AnnotationChange, current: readonly Annotation[]): boolean {\n switch (change.kind) {\n case 'add':\n return current.some((a) => a.id === change.annotation.id)\n case 'remove':\n return !current.some((a) => a.id === change.annotation.id)\n case 'update': {\n const mine = current.find((a) => a.id === change.id)\n if (!mine) return false\n // A host or server may re-stamp modifiedAt, so fall back to a structural match.\n return mine === change.after || sameIgnoringModifiedAt(mine, change.after)\n }\n case 'replace':\n return true\n }\n}\n\ninterface Pending {\n id: string\n change: AnnotationChange\n timer: ReturnType<typeof setTimeout>\n}\n\nexport function createAnnotationStore(opts: StoreOptions): AnnotationStore {\n const now = opts.now ?? (() => new Date().toISOString())\n const nextId = opts.id ?? (() => uuidv7())\n const list = writable<readonly Annotation[]>([...(opts.mode.initial ?? [])])\n const selection = writable<readonly string[]>([])\n const emitter = new Emitter<{ change: AnnotationChange }>()\n const controlled = opts.mode.mode === 'controlled' ? opts.mode : undefined\n const pending = new Map<string, Pending>()\n /**\n * Controlled mode: the list as the store last proposed it, embedded items included. Later\n * proposals build on it, so several mutations in a row (one highlight per page, a bulk\n * remove, add then select) all reach the host. It resets to the applied list when the host\n * pushes a value or a pending change's check fires without one.\n */\n let proposed: readonly Annotation[] | undefined\n let destroyed = false\n\n /** What mutations build on: the pending proposal in controlled mode, else the list. */\n const basis = (): readonly Annotation[] => proposed ?? list.get()\n const findIn = (items: readonly Annotation[], id: string): Annotation | undefined =>\n items.find((a) => a.id === id)\n\n function completeInput(input: AnnotationInput): Annotation {\n const ts = now()\n const candidate: Record<string, unknown> = {\n ...input,\n id: input.id ?? nextId(),\n rect: input.rect ?? deriveRect(input),\n color: input.color ?? opts.defaults.color(input.type),\n opacity: input.opacity ?? opts.defaults.opacity(input.type),\n createdAt: ts,\n modifiedAt: ts,\n source: 'session',\n }\n if (input.type === 'freetext') {\n // A box's `color` is its fill, which has no default: the default colour is the text's.\n if (input.color === undefined) delete candidate.color\n candidate.defaultStyle = {\n color: opts.defaults.color('freetext'),\n ...withoutUndefined(input.defaultStyle ?? {}),\n }\n }\n if (input.type === 'redact') {\n if (input.interiorColor === undefined)\n candidate.interiorColor = opts.defaults.fill()\n }\n return AnnotationSchema.parse(candidate)\n }\n\n function clearPending(key: string): void {\n const entry = pending.get(key)\n if (!entry) return\n clearTimeout(entry.timer)\n pending.delete(key)\n }\n\n function warnIfIgnored(key: string): void {\n const entry = pending.get(key)\n if (!entry) return\n pending.delete(key)\n // Later proposals may still be pending; they keep building on the proposed list.\n if (pending.size === 0) proposed = undefined\n // A refused add leaves nothing to select. Pruning makes the refusal observable, so a\n // one-shot tool that reported it made returns to ready.\n pruneSelection(basis())\n if (isApplied(entry.change, list.get()) || isProduction()) return\n console.warn(\n `[inkbar] ControlledMutationIgnored: the host did not apply a ${entry.change.kind} for ` +\n `annotation ${entry.id}. In controlled mode, pass the list from onChange back into the store.`\n )\n }\n\n function commit(next: readonly Annotation[], change: AnnotationChange): void {\n if (controlled) {\n if (change.kind !== 'replace') {\n const key = changeKey(change)\n clearPending(key)\n // Two macrotasks. Vue applies the change in a microtask; React may apply it after its\n // scheduler's macrotask plus an effect, so one macrotask warns a host that did apply it.\n const entry: Pending = {\n id: change.kind === 'update' ? change.id : change.annotation.id,\n change,\n timer: setTimeout(() => {\n entry.timer = setTimeout(() => {\n warnIfIgnored(key)\n }, 0)\n }, 0),\n }\n pending.set(key, entry)\n }\n proposed =\n change.kind === 'replace'\n ? [\n ...list.get().filter((a) => a.source === 'pdf'),\n ...next.filter((a) => a.source !== 'pdf'),\n ]\n : next\n // Embedded items are the store's, never the host's.\n controlled.onChange(\n next.filter((a) => a.source !== 'pdf'),\n change\n )\n return\n }\n list.set(next)\n emitter.emit('change', change)\n }\n\n /**\n * Uncontrolled `replaceAll` cannot drop or forge embedded annotations: every current embedded\n * item stays (taking the list's version of it, guarded like `update`, when the list has one),\n * and items claiming `source: 'pdf'` that the store does not hold are dropped. History\n * snapshots contain the embedded items, so undo and redo of their edits still work.\n */\n function withEmbedded(proposed: readonly Annotation[]): Annotation[] {\n const current = new Map(\n list\n .get()\n .filter((a) => a.source === 'pdf')\n .map((a) => [a.id, a])\n )\n const seen = new Set<string>()\n const out: Annotation[] = []\n for (const a of proposed) {\n const mine = current.get(a.id)\n if (mine) {\n if (!seen.has(a.id)) out.push(guardEmbedded(mine, a))\n seen.add(a.id)\n } else if (a.source !== 'pdf') {\n out.push(a)\n }\n }\n return [...[...current.values()].filter((a) => !seen.has(a.id)), ...out]\n }\n\n function pruneSelection(next: readonly Annotation[]): void {\n const known = new Set(next.map((a) => a.id))\n const current = selection.get()\n if (current.every((id) => known.has(id))) return\n selection.set(current.filter((id) => known.has(id)))\n }\n\n const store: AnnotationStore = {\n mode: opts.mode.mode,\n list: readonly(list),\n selection: readonly(selection),\n defaults: opts.defaults,\n get: (id) => list.get().find((a) => a.id === id),\n _getProposed: (id) => findIn(basis(), id),\n byPage: (page) => list.get().filter((a) => a.page === page),\n completeInput,\n add(input) {\n const a = completeInput(input)\n // Covers ids from the input and from the `id` option's generator alike.\n if (findIn(basis(), a.id))\n throw new Error(`An annotation with id ${a.id} already exists`)\n if (destroyed) return a\n // One mask per page: a new one replaces the page's session mask in the same change, so\n // the history step and the host's `onChange` see the swap once.\n const replaced =\n a.type === 'mask'\n ? basis().filter(\n (x) => x.type === 'mask' && x.page === a.page && x.source !== 'pdf'\n )\n : []\n const gone = new Set(replaced.map((x) => x.id))\n for (const x of replaced) clearPending(changeKey({ kind: 'add', annotation: x }))\n commit([...basis().filter((x) => !gone.has(x.id)), a], {\n kind: 'add',\n annotation: a,\n })\n if (!controlled && gone.size > 0) pruneSelection(list.get())\n return a\n },\n update(id, patch) {\n const before = findIn(basis(), id)\n if (destroyed || !before) return undefined\n if (before.locked && Object.keys(patch).some((k) => LOCKED_KEYS.has(k)))\n return undefined\n const candidate: Record<string, unknown> = {\n ...before,\n ...patch,\n ...mergedStyle(before, patch),\n id: before.id,\n type: before.type,\n createdAt: before.createdAt,\n source: before.source,\n modifiedAt: now(),\n }\n // An embedded annotation's lock belongs to the file: a `locked` key in the patch is ignored.\n if (before.source === 'pdf') keepKey(candidate, before, 'locked')\n const after = AnnotationSchema.parse(candidate)\n const swap = (items: readonly Annotation[]): Annotation[] =>\n items.map((a) => (a.id === id ? after : a))\n const next = swap(basis())\n const change: AnnotationChange = { kind: 'update', id, before, after }\n if (controlled && before.source === 'pdf') {\n // The host never holds embedded items, so their edits apply here.\n list.set(swap(list.get()))\n if (proposed) proposed = next\n emitter.emit('change', change)\n } else {\n commit(next, change)\n }\n return after\n },\n remove(id) {\n const items = basis()\n const target = findIn(items, id)\n if (destroyed || !target || target.locked) return false\n const doomed = new Set<string>([id])\n let grew = true\n while (grew) {\n grew = false\n for (const a of items) {\n if (a.inReplyTo !== undefined && doomed.has(a.inReplyTo) && !doomed.has(a.id)) {\n doomed.add(a.id)\n grew = true\n }\n }\n }\n const next = items.filter((a) => !doomed.has(a.id))\n const removed = [target, ...items.filter((a) => a.id !== id && doomed.has(a.id))]\n commit(next, { kind: 'remove', annotation: target, removed })\n if (!controlled) pruneSelection(next)\n return true\n },\n select(ids) {\n const known = new Set(basis().map((a) => a.id))\n selection.set(ids.filter((id) => known.has(id)))\n },\n replaceAll(list, reason) {\n if (destroyed) return\n const next = controlled ? [...list] : withEmbedded(list)\n commit(next, { kind: 'replace', reason })\n if (!controlled) pruneSelection(next)\n },\n setControlledValue(value) {\n if (!controlled)\n throw new TypeError('setControlledValue is only valid in controlled mode')\n if (destroyed) return\n const embedded = list.get().filter((a) => a.source === 'pdf')\n const embeddedIds = new Set(embedded.map((a) => a.id))\n const next = [...embedded, ...value.filter((a) => !embeddedIds.has(a.id))]\n list.set(next)\n proposed = undefined\n for (const [key, entry] of [...pending]) {\n if (isApplied(entry.change, next)) clearPending(key)\n }\n pruneSelection(next)\n emitter.emit('change', { kind: 'replace', reason: 'sync' })\n },\n _setEmbedded(items) {\n if (destroyed) return\n const ids = new Set(items.map((a) => a.id))\n const next = [\n ...items,\n ...list.get().filter((a) => a.source !== 'pdf' && !ids.has(a.id)),\n ]\n proposed = undefined\n list.set(next)\n pruneSelection(next)\n emitter.emit('change', { kind: 'replace', reason: 'import' })\n },\n _patchEmbedded(fields) {\n if (destroyed) return\n const applied = new Map<string, EmbeddedFieldPatch>()\n const merge = (items: readonly Annotation[]): Annotation[] =>\n items.map((a) => {\n const f = a.source === 'pdf' ? fields.get(a.id) : undefined\n const merged = f && withEmbeddedFields(a, f)\n if (!merged) return a\n applied.set(a.id, f)\n return merged\n })\n const next = merge(list.get())\n if (applied.size === 0) return\n list.set(next)\n // A pending controlled proposal holds the embedded items too.\n if (proposed) proposed = merge(proposed)\n emitter.emit('change', { kind: 'replace', reason: 'embedded', fields: applied })\n },\n on: (event, fn) => emitter.on(event, fn),\n destroy() {\n destroyed = true\n proposed = undefined\n for (const key of [...pending.keys()]) clearPending(key)\n emitter.clear()\n },\n }\n return store\n}\n","/**\n * Internal (not exported from the package): one in-flight or settled lookup per page index.\n * A lookup that rejects is evicted, so the next request for that page asks again instead of\n * replaying the failure for the rest of the session.\n */\nexport interface PageCache<T> {\n get(index: number): Promise<T>\n clear(): void\n}\n\nexport function createPageCache<T>(fetch: (index: number) => Promise<T>): PageCache<T> {\n const cache = new Map<number, Promise<T>>()\n return {\n get(index) {\n const cached = cache.get(index)\n if (cached) return cached\n const fetched = fetch(index)\n cache.set(index, fetched)\n fetched.catch(() => {\n if (cache.get(index) === fetched) cache.delete(index)\n })\n return fetched\n },\n clear: () => cache.clear(),\n }\n}\n","import type { Rect } from './geometry'\nimport type { PdfjsPage } from '../pdfjs/types'\n\nexport type PageRotation = 0 | 90 | 180 | 270\n\nexport interface PageInfo {\n index: number\n /** CropBox ∩ MediaBox in user space before /Rotate, as PDF.js reports `page.view`. */\n box: Rect\n /** The page's own /Rotate. View rotation applied by the viewer is separate. */\n rotate: PageRotation\n userUnit: number\n /** Unrotated box width in points. */\n width: number\n /** Unrotated box height in points. */\n height: number\n}\n\nexport function pageInfoFromProxy(page: PdfjsPage, index: number): PageInfo {\n const [x1, y1, x2, y2] = page.view as [number, number, number, number]\n const box: Rect = {\n x: Math.min(x1, x2),\n y: Math.min(y1, y2),\n width: Math.abs(x2 - x1),\n height: Math.abs(y2 - y1),\n }\n return {\n index,\n box,\n rotate: normaliseRotation(page.rotate),\n userUnit: page.userUnit > 0 ? page.userUnit : 1,\n width: box.width,\n height: box.height,\n }\n}\n\n/** PDF.js already rejects /Rotate values that are not multiples of 90; this also folds negatives. */\nfunction normaliseRotation(rotate: number): PageRotation {\n const r = (((Math.round(rotate / 90) * 90) % 360) + 360) % 360\n return r as PageRotation\n}\n","import { v7 as uuidv7 } from 'uuid'\n\nimport { InkError } from './errors'\n\nexport type DocumentSource =\n | ArrayBuffer\n | Uint8Array\n | Blob\n | string\n | { url: string; key: string }\n | { data: ArrayBuffer | Uint8Array; key: string }\n\nexport interface ResolvedSource {\n /** Identity of the document. Hosts reuse it to avoid reloads when a signed URL changes. */\n key: string\n bytes(): Promise<Uint8Array>\n}\n\nexport function resolveSource(\n src: DocumentSource,\n fetchImpl: typeof fetch = globalThis.fetch\n): ResolvedSource {\n if (typeof src === 'string')\n return { key: src, bytes: () => fetchBytes(src, fetchImpl) }\n if (src instanceof ArrayBuffer || src instanceof Uint8Array) {\n const data = toBytes(src)\n return { key: `bytes:${uuidv7()}`, bytes: () => Promise.resolve(data.slice()) }\n }\n if ('url' in src) {\n const { url } = src\n return { key: src.key, bytes: () => fetchBytes(url, fetchImpl) }\n }\n if ('data' in src) {\n const data = toBytes(src.data)\n return { key: src.key, bytes: () => Promise.resolve(data.slice()) }\n }\n const blob = src\n return {\n key: `bytes:${uuidv7()}`,\n bytes: async () => new Uint8Array(await blob.arrayBuffer()),\n }\n}\n\n/**\n * A view over the host's bytes. `bytes()` hands PDF.js a copy each time: PDF.js transfers the\n * buffer it is given to its worker, which would empty the host's array and break a reopen\n * (a password retry, for one).\n */\nfunction toBytes(data: ArrayBuffer | Uint8Array): Uint8Array {\n return data instanceof Uint8Array ? data : new Uint8Array(data)\n}\n\nasync function fetchBytes(url: string, fetchImpl: typeof fetch): Promise<Uint8Array> {\n if (typeof fetchImpl !== 'function') {\n throw new InkError(\n 'SourceFetchFailed',\n 'No fetch implementation available for URL sources',\n {\n url,\n }\n )\n }\n let res: Response\n try {\n res = await fetchImpl(url, { credentials: 'same-origin' })\n } catch (cause) {\n throw new InkError('SourceFetchFailed', `Could not fetch ${url}`, { url }, cause)\n }\n if (!res.ok) {\n throw new InkError(\n 'SourceFetchFailed',\n `Fetching ${url} returned HTTP ${res.status}`,\n {\n url,\n status: res.status,\n }\n )\n }\n try {\n return new Uint8Array(await res.arrayBuffer())\n } catch (cause) {\n throw new InkError(\n 'SourceFetchFailed',\n `Reading the body of ${url} failed`,\n { url },\n cause\n )\n }\n}\n","import { rectFromQuad, type Point, type Quad, type Rect } from './geometry'\n\nimport type { PdfjsTextContent, PdfjsTextItem } from '../pdfjs/types'\n\nexport interface TextItem {\n str: string\n dir: 'ltr' | 'rtl' | 'ttb'\n fontName: string\n fontSize: number\n hasEOL: boolean\n /** Glyph-run box in user space, following the run's rotation. */\n quad: Quad\n /** Axis-aligned bounds of `quad`. */\n rect: Rect\n}\n\nexport interface TextContent {\n page: number\n items: TextItem[]\n}\n\n/** Fractions of the font size used when PDF.js has no usable metrics for the font. */\nconst FALLBACK_ASCENT = 0.75\nconst FALLBACK_DESCENT = 0.25\n\n/**\n * Converts `getTextContent()` output to user-space boxes.\n *\n * For an item with transform [a, b, c, d, e, f] (already in user space):\n * - (e, f) is the start of the run on the baseline;\n * - u = (a, b) / |(a, b)| is the baseline direction, along which the run advances `width`;\n * - v = (c, d) / |(c, d)| is the glyph-up direction, and `fontSize` = |(c, d)|;\n * - the box spans from `descent * fontSize` below the baseline to `ascent * fontSize` above it,\n * using the font's ascent/descent from `styles` when PDF.js provides them, else 0.75 / 0.25.\n *\n * So p3 = (e, f) - v * descent * fontSize, p4 = p3 + u * width, p1 = p3 + v * (ascent + descent) * fontSize,\n * p2 = p4 + (p1 - p3). `rect` is the axis-aligned bounding box of the quad.\n */\nexport function textContentFromPdfjs(page: number, tc: PdfjsTextContent): TextContent {\n const items: TextItem[] = []\n for (const raw of tc.items) {\n if (!('str' in raw)) continue\n const item: PdfjsTextItem = raw\n const [a, b, c, d, e, f] = item.transform as [\n number,\n number,\n number,\n number,\n number,\n number,\n ]\n const baseLen = Math.hypot(a, b)\n const fontSize = Math.hypot(c, d)\n const u: Point = baseLen === 0 ? { x: 1, y: 0 } : { x: a / baseLen, y: b / baseLen }\n const v: Point =\n fontSize === 0 ? { x: -u.y, y: u.x } : { x: c / fontSize, y: d / fontSize }\n const { ascent, descent } = metrics(tc.styles[item.fontName])\n const below = descent * fontSize\n const total = (ascent + descent) * fontSize\n const w = item.width\n const p3 = { x: e - v.x * below, y: f - v.y * below }\n const p4 = { x: p3.x + u.x * w, y: p3.y + u.y * w }\n const p1 = { x: p3.x + v.x * total, y: p3.y + v.y * total }\n const p2 = { x: p4.x + v.x * total, y: p4.y + v.y * total }\n const quad: Quad = { p1, p2, p3, p4 }\n items.push({\n str: item.str,\n dir: isDir(item.dir) ? item.dir : 'ltr',\n fontName: item.fontName,\n fontSize,\n hasEOL: item.hasEOL,\n quad,\n rect: rectFromQuad(quad),\n })\n }\n return { page, items }\n}\n\nfunction metrics(style: PdfjsTextContent['styles'][string] | undefined): {\n ascent: number\n descent: number\n} {\n // Vertical fonts report metrics for horizontal layout, so they get the fallback box too.\n if (!style || style.vertical)\n return { ascent: FALLBACK_ASCENT, descent: FALLBACK_DESCENT }\n const ascent = style.ascent\n const descent = Math.abs(style.descent)\n if (!(ascent > 0) || !Number.isFinite(descent) || ascent + descent <= 0) {\n return { ascent: FALLBACK_ASCENT, descent: FALLBACK_DESCENT }\n }\n return { ascent, descent }\n}\n\nfunction isDir(dir: string): dir is TextItem['dir'] {\n return dir === 'ltr' || dir === 'rtl' || dir === 'ttb'\n}\n","import { assertAssets, loadPdfjs, openProxy } from '../pdfjs/load'\n\nimport { staticDefaults, type AnnotationDefaults } from './annotations/defaults'\nimport {\n importEmbeddedPage,\n summarise,\n type EmbeddedSummary,\n type EmbeddedTarget,\n} from './annotations/embedded'\nimport { readEmbeddedFields } from './annotations/embedded-fields'\nimport { createHistory, type History } from './annotations/history'\nimport {\n exportAnnotations,\n planImport,\n type ImportOptions,\n type ImportResult,\n} from './annotations/json'\nimport {\n createAnnotationStore,\n type AnnotationStore,\n type StoreMode,\n} from './annotations/store'\nimport { InkError, isInkError } from './errors'\nimport { createPageCache, type PageCache } from './page-cache'\nimport { pageInfoFromProxy, type PageInfo } from './pages'\nimport { readonly, writable, type Readable } from './readable'\nimport { resolveSource, type DocumentSource } from './source'\nimport { textContentFromPdfjs, type TextContent } from './text'\n\nimport type { AnnotationDocument, ForeignAnnotation } from './annotations/types'\nimport type {\n PdfAssets,\n PdfjsAnnotationData,\n PdfjsDocument,\n PdfjsModule,\n PdfjsPage,\n} from '../pdfjs/types'\n\nexport type DocumentStatus =\n { state: 'loading' } | { state: 'ready' } | { state: 'error'; error: InkError }\n\n/** A document's status plus `idle`, for a host with no document open. */\nexport type InkStatus = DocumentStatus | { state: 'idle' }\n\nexport interface DocumentInfo {\n title?: string | undefined\n author?: string | undefined\n pageCount: number\n isEncrypted: boolean\n}\n\nexport interface OpenOptions {\n assets: PdfAssets\n password?: string | undefined\n fetch?: typeof fetch | undefined\n /**\n * Defaults to uncontrolled. In controlled mode the host owns only session annotations:\n * embedded (`source: 'pdf'`) ones live in the store, are never passed to `onChange`, and stay\n * in `list` whatever the host pushes back.\n */\n annotations?: StoreMode | undefined\n /** Colour defaults. Pass `cssVariableDefaults(element)` from the DOM layer to read theme variables. */\n defaults?: AnnotationDefaults | undefined\n /**\n * Undo history, on by default. `false` disables it. In controlled mode history is always\n * inert: the host owns the list, so it owns undo too.\n */\n history?: boolean | { limit?: number | undefined } | undefined\n /** PDF.js verbosity level; 0 = errors only. Defaults to PDF.js's own level. */\n verbosity?: number | undefined\n}\n\nexport interface InkDocument {\n readonly key: string\n readonly status: Readable<DocumentStatus>\n /** Resolves when status is ready; rejects with the InkError when it is error. */\n readonly ready: Promise<void>\n readonly pages: readonly PageInfo[]\n readonly info: DocumentInfo\n text(page: number): Promise<TextContent>\n /**\n * Annotations embedded in the file arrive here as `source: 'pdf'`, `locked: true` before\n * `ready` resolves. They stay in `list` in both modes and cannot be removed; in controlled\n * mode they never reach `onChange`. Fields PDF.js leaves out (a FreeText's callout, fringe,\n * head and font, a note's icon) are read from the file after `ready` and fill in later, as a\n * `{ kind: 'replace', reason: 'embedded', fields }` change.\n */\n readonly annotations: AnnotationStore\n /** What the file contained, by PDF subtype, including subtypes Inkbar does not show. */\n readonly embedded: readonly EmbeddedSummary[]\n readonly history: History\n /** Session annotations only, plus unknown-type items kept from earlier imports. */\n exportAnnotations(format: 'json'): AnnotationDocument\n /** Defaults to `{ mode: 'replace' }`. Embedded annotations are never touched. */\n importAnnotations(data: AnnotationDocument | string, opts?: ImportOptions): ImportResult\n /** Writes the document with its annotations. Needs @inkbar/engine; rejects with EngineUnavailable otherwise. */\n save(): Promise<Uint8Array>\n destroy(): void\n /** @internal PDF.js handles for the DOM layer. Not part of the public contract. */\n readonly _pdfjs: {\n module: PdfjsModule\n proxy: PdfjsDocument\n getPage(index: number): Promise<PdfjsPage>\n }\n}\n\ninterface PdfjsInfoDict {\n Title?: unknown\n Author?: unknown\n EncryptFilterName?: unknown\n}\n\n/**\n * Opens a document. Resolves once loading has finished, whether it succeeded or not:\n * check `status` or await `ready`, which rejects with the InkError. Only a missing\n * `assets` option (a programmer error) makes this promise itself reject.\n */\nexport async function openDocument(\n source: DocumentSource,\n options: OpenOptions\n): Promise<InkDocument> {\n assertAssets(options?.assets)\n const resolved = resolveSource(source, options.fetch)\n const status = writable<DocumentStatus>({ state: 'loading' })\n const pages: PageInfo[] = []\n const info: DocumentInfo = { pageCount: 0, isEncrypted: false }\n let pageCache: PageCache<PdfjsPage> | undefined\n let destroyed = false\n let handles: InkDocument['_pdfjs'] | undefined\n let destroyTask: (() => Promise<void>) | undefined\n\n const store = createAnnotationStore({\n mode: options.annotations ?? { mode: 'uncontrolled' },\n defaults: options.defaults ?? staticDefaults,\n })\n const embedded: EmbeddedSummary[] = []\n let preserved: ForeignAnnotation[] = []\n /** Embedded annotations whose PDF.js data lacks fields the file holds; read after `ready`. */\n const targets: EmbeddedTarget[] = []\n\n const destroyedError = (): InkError =>\n new InkError('DocumentDestroyed', 'The document has been destroyed')\n\n const load = (async () => {\n const pdfjs = await loadPdfjs(options.assets)\n const bytes = await resolved.bytes()\n const { task, proxy } = await openProxy(pdfjs, bytes, {\n assets: options.assets,\n password: options.password,\n verbosity: options.verbosity,\n })\n destroyTask = () => task.destroy()\n const cache = createPageCache((index) => proxy.getPage(index + 1))\n pageCache = cache\n const getPage = (index: number): Promise<PdfjsPage> => {\n if (destroyed) return Promise.reject(destroyedError())\n if (!Number.isInteger(index) || index < 0 || index >= proxy.numPages) {\n return Promise.reject(\n new InkError('PageOutOfRange', `Page ${index} does not exist`, {\n index,\n pageCount: proxy.numPages,\n })\n )\n }\n // A failed lookup is not cached: the next mount of the page asks PDF.js again.\n return cache.get(index)\n }\n handles = { module: pdfjs, proxy, getPage }\n const meta = await proxy.getMetadata().catch(() => {\n // Metadata is optional: PDF.js throws on malformed Info dictionaries or XMP, and\n // title/author are nice-to-have. The document itself has opened, so carry on without it.\n return undefined\n })\n const docInfo = (meta?.info ?? {}) as PdfjsInfoDict\n const title = nonEmptyString(docInfo.Title)\n const author = nonEmptyString(docInfo.Author)\n if (title !== undefined) info.title = title\n if (author !== undefined) info.author = author\n info.pageCount = proxy.numPages\n info.isEncrypted =\n docInfo.EncryptFilterName !== null && docInfo.EncryptFilterName !== undefined\n for (let i = 0; i < proxy.numPages; i++)\n pages.push(pageInfoFromProxy(await getPage(i), i))\n\n const importedAt = new Date().toISOString()\n const perPage = await mapInOrder(proxy.numPages, EMBEDDED_CONCURRENCY, async (i) => {\n const page = await getPage(i)\n const raw: PdfjsAnnotationData[] = await page.getAnnotations().catch(() => {\n // A page whose annotations PDF.js cannot parse still renders; it just has none to show.\n return []\n })\n return importEmbeddedPage(i, raw, importedAt)\n })\n embedded.push(...summarise(perPage.map((r) => r.counts)))\n const fromFile = perPage.flatMap((r) => r.annotations)\n targets.push(...perPage.flatMap((r) => r.targets))\n if (fromFile.length > 0) store._setEmbedded(fromFile)\n })()\n\n const ready = load.then(\n () => {\n status.set({ state: 'ready' })\n },\n (cause: unknown) => {\n const error = isInkError(cause)\n ? cause\n : new InkError('InvalidPdf', errorMessage(cause), {}, cause)\n if (error.code === 'PasswordRequired') info.isEncrypted = true\n status.set({ state: 'error', error })\n throw error\n }\n )\n // Keep the rejection observed so hosts that only watch `status` get no unhandled-rejection warning.\n await ready.catch(() => undefined)\n\n // Created after the embedded import, so loading the file is not an undoable step.\n const historyOption = options.history ?? true\n const historyLimit =\n historyOption === false ? 0 : historyOption === true ? undefined : historyOption.limit\n const history = createHistory(\n store,\n historyLimit === undefined ? {} : { limit: historyLimit }\n )\n\n // Fills in fields PDF.js leaves out, read from the file's own bytes. It runs after `ready`\n // so it never delays it, and a failure leaves the annotations as PDF.js imported them.\n void ready.then(\n () => {\n if (destroyed || !handles) return\n const { proxy } = handles\n void readEmbeddedFields(store.list.get(), targets, () => proxy.getData())\n .then((patched) => {\n if (!destroyed && patched.size > 0) store._patchEmbedded(patched)\n })\n .catch(() => undefined)\n },\n () => undefined\n )\n\n const doc: InkDocument = {\n key: resolved.key,\n status: readonly(status),\n ready,\n pages,\n info,\n async text(page) {\n if (destroyed) throw destroyedError()\n if (!handles) throw statusError(status.get())\n const p = await handles.getPage(page)\n return textContentFromPdfjs(page, await p.getTextContent())\n },\n annotations: store,\n embedded,\n history,\n exportAnnotations(format) {\n if (format !== 'json')\n throw new TypeError(`Unsupported export format ${String(format)}`)\n return exportAnnotations(store, preserved, resolved.key)\n },\n importAnnotations(data, opts = { mode: 'replace' }) {\n const plan = planImport(store, data, opts)\n // Staged before the store publishes, so a change listener that exports sees it.\n preserved =\n opts.mode === 'replace'\n ? plan.result.unknown\n : [...preserved.filter((u) => !plan.ids.has(u.id)), ...plan.result.unknown]\n plan.apply()\n return plan.result\n },\n save() {\n return Promise.reject(\n new InkError(\n 'EngineUnavailable',\n 'Saving needs @inkbar/engine, which is not registered. Use exportAnnotations(\"json\") to keep annotations without writing the PDF.'\n )\n )\n },\n destroy() {\n if (destroyed) return\n destroyed = true\n history.destroy()\n store.destroy()\n pageCache?.clear()\n if (destroyTask) {\n teardown(destroyTask)\n }\n },\n get _pdfjs() {\n if (!handles) throw statusError(status.get())\n return handles\n },\n }\n return doc\n}\n\nconst EMBEDDED_CONCURRENCY = 8\n\n/** Runs `task(0..count-1)` with at most `limit` in flight; results come back in index order. */\nasync function mapInOrder<T>(\n count: number,\n limit: number,\n task: (index: number) => Promise<T>\n): Promise<T[]> {\n const results = new Array<T>(count)\n let next = 0\n const worker = async (): Promise<void> => {\n while (next < count) {\n const i = next++\n results[i] = await task(i)\n }\n }\n await Promise.all(Array.from({ length: Math.min(limit, count) }, worker))\n return results\n}\n\nfunction teardown(destroyTask: () => Promise<void>): void {\n destroyTask().catch(() => {\n // Teardown is best effort: the document is already marked destroyed and every later call\n // rejects with DocumentDestroyed, so a worker that fails to shut down cleanly changes nothing\n // the host can act on.\n })\n}\n\nfunction statusError(s: DocumentStatus): InkError {\n return s.state === 'error'\n ? s.error\n : new InkError('InvalidPdf', 'The document has not finished loading')\n}\n\nfunction nonEmptyString(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction errorMessage(cause: unknown): string {\n if (cause instanceof Error) return cause.message\n return String(cause)\n}\n","// Geometry edits in user space, shared by the pointer (select tool) and keyboard (overlay)\n// paths so both produce the same patch for the same change.\nimport { translateQuad, translateRect, type Point, type Rect } from '../geometry'\n\nimport {\n calloutStroke,\n freeTextBox,\n isStandardCallout,\n withCalloutBounds,\n} from './callout'\n\nimport type {\n Annotation,\n FreeTextAnnotation,\n LineAnnotation,\n TextMarkupAnnotation,\n} from './types'\n\n/** Smallest width or height a resize leaves, user-space points. */\nexport const MIN_SIZE = 1\n\nconst shift = (p: Point, dx: number, dy: number): Point => ({ x: p.x + dx, y: p.y + dy })\n\n/** The geometry patch that translates `a` by (dx, dy) in user space. */\nexport function translated(a: Annotation, dx: number, dy: number): Partial<Annotation> {\n const patch: Record<string, unknown> = { rect: translateRect(a.rect, dx, dy) }\n if ('quads' in a && a.quads) patch.quads = a.quads.map((q) => translateQuad(q, dx, dy))\n if ('callout' in a && a.callout) patch.callout = a.callout.map((p) => shift(p, dx, dy))\n switch (a.type) {\n case 'line':\n patch.start = shift(a.start, dx, dy)\n patch.end = shift(a.end, dx, dy)\n break\n case 'polyline':\n case 'polygon':\n patch.vertices = a.vertices.map((p) => shift(p, dx, dy))\n break\n case 'ink':\n patch.inklist = a.inklist.map((path) => path.map((p) => shift(p, dx, dy)))\n break\n default:\n }\n return patch\n}\n\n/**\n * True when `rect` is the annotation's whole shape, so resizing means changing `rect`: area\n * redactions, free text, squares, circles, stamps, loupes and masks. Text-derived marks (quads), note icons and\n * point-based shapes are not.\n */\nexport function hasRectGeometry(a: Annotation): boolean {\n switch (a.type) {\n case 'redact':\n return a.quads === undefined || a.quads.length === 0\n case 'freetext':\n case 'square':\n case 'circle':\n case 'stamp':\n case 'loupe':\n case 'mask':\n return true\n default:\n return false\n }\n}\n\n/**\n * Grows (positive) or shrinks (negative) a rect by `dw` and `dh` points, keeping its top-left\n * corner (user space: left edge and top edge, `y + height`) where it is. Neither side goes\n * below `MIN_SIZE`. With `keepAspect`, the side that changes leads and the other follows it in\n * proportion (the width when both change).\n */\nexport function resizedRect(r: Rect, dw: number, dh: number, keepAspect = false): Rect {\n let width = Math.max(MIN_SIZE, r.width + dw)\n let height = Math.max(MIN_SIZE, r.height + dh)\n if (keepAspect && r.width > 0 && r.height > 0) {\n const aspect = r.width / r.height\n if (dw !== 0) height = width / aspect\n else width = height * aspect\n // Neither side below MIN_SIZE, still in proportion.\n const grow = Math.max(MIN_SIZE / width, MIN_SIZE / height, 1)\n width *= grow\n height *= grow\n }\n const top = r.y + r.height\n return { x: r.x, y: top - height, width, height }\n}\n\n/**\n * True for highlight, underline, strikeout and squiggly: marks on text, which a drag passes\n * through to text selection and a click selects.\n */\nexport function isTextMarkup(a: Pick<Annotation, 'type'>): a is TextMarkupAnnotation {\n return (\n a.type === 'highlight' ||\n a.type === 'underline' ||\n a.type === 'strikeout' ||\n a.type === 'squiggly'\n )\n}\n\n/**\n * True for the point-based shapes a corner handle resizes by scaling their points: polylines,\n * polygons and ink. With `hasRectGeometry`, the annotations that get corner handles.\n */\nexport function scalesPoints(a: Annotation): boolean {\n return a.type === 'polyline' || a.type === 'polygon' || a.type === 'ink'\n}\n\n/** True when a corner handle resizes `a`: rect-shaped types and point-based shapes. */\nexport function hasCornerHandles(a: Annotation): boolean {\n return hasRectGeometry(a) || scalesPoints(a)\n}\n\n/**\n * The geometry patch that maps `a` from the box `from` onto the box `to`, both in user space:\n * `rect`, every point field (quads, ink paths, vertices, line ends, callout) and a free text's\n * `fringe` scale with the boxes. Stroke widths and font sizes stay as they are.\n */\nexport function scaled(a: Annotation, from: Rect, to: Rect): Partial<Annotation> {\n const sx = from.width === 0 ? 1 : to.width / from.width\n const sy = from.height === 0 ? 1 : to.height / from.height\n const map = (p: Point): Point => ({\n x: to.x + (p.x - from.x) * sx,\n y: to.y + (p.y - from.y) * sy,\n })\n const sameBox = (r: Rect): boolean =>\n r.x === from.x && r.y === from.y && r.width === from.width && r.height === from.height\n const patch: Record<string, unknown> = {\n // The common case, a rect that is the box, maps exactly rather than through the scale.\n rect: sameBox(a.rect)\n ? { ...to }\n : {\n ...map(a.rect),\n width: a.rect.width * sx,\n height: a.rect.height * sy,\n },\n }\n if ('quads' in a && a.quads)\n patch.quads = a.quads.map((q) => ({\n p1: map(q.p1),\n p2: map(q.p2),\n p3: map(q.p3),\n p4: map(q.p4),\n }))\n if ('callout' in a && a.callout) patch.callout = a.callout.map(map)\n // The text box inside a free text's rect scales with it.\n if (a.type === 'freetext' && a.fringe)\n patch.fringe = {\n left: a.fringe.left * sx,\n top: a.fringe.top * sy,\n right: a.fringe.right * sx,\n bottom: a.fringe.bottom * sy,\n }\n switch (a.type) {\n case 'line':\n patch.start = map(a.start)\n patch.end = map(a.end)\n break\n case 'polyline':\n case 'polygon':\n patch.vertices = a.vertices.map(map)\n break\n case 'ink':\n patch.inklist = a.inklist.map((path) => path.map(map))\n break\n default:\n }\n return patch\n}\n\n/**\n * The patch that moves one end of a line to `to` and refits `rect` to the new ends, padded by\n * half the stroke width on every side.\n */\nexport function movedEndpoint(\n a: LineAnnotation,\n which: 'start' | 'end',\n to: Point\n): Partial<LineAnnotation> {\n const start = which === 'start' ? to : a.start\n const end = which === 'end' ? to : a.end\n const pad = a.width / 2\n const x = Math.min(start.x, end.x)\n const y = Math.min(start.y, end.y)\n return {\n [which]: { ...to },\n rect: {\n x: x - pad,\n y: y - pad,\n width: Math.abs(end.x - start.x) + pad * 2,\n height: Math.abs(end.y - start.y) + pad * 2,\n },\n }\n}\n\n/**\n * True for annotations whose resize keeps their aspect ratio without `Shift`: stamps, loupes,\n * masks and signatures (ink with subject `Signature`).\n */\nexport function keepsAspect(a: Annotation): boolean {\n if (a.type === 'stamp' || a.type === 'loupe' || a.type === 'mask') return true\n return a.type === 'ink' && a.subject === 'Signature'\n}\n\n/**\n * True for a speech bubble: a standard free-text callout (`intent: 'FreeTextCallout'`, `rect`,\n * `fringe`, `callout`) with Inkbar's `cornerRadius`. Inkbar draws it as one rounded outline with\n * a wedge from where `callout`'s last point meets the box to the tip, `callout[0]`.\n */\nexport function isBubble(\n a: Annotation\n): a is FreeTextAnnotation & { callout: [Point, Point, ...Point[]] } {\n return (\n a.type === 'freetext' &&\n a.intent === 'FreeTextCallout' &&\n a.cornerRadius !== undefined &&\n a.callout !== undefined &&\n a.callout.length >= 2\n )\n}\n\n/** True for a free text with a callout to edit: a speech bubble or a standard callout. */\nexport function hasCallout(\n a: Annotation\n): a is FreeTextAnnotation & { callout: [Point, Point, ...Point[]] } {\n return isBubble(a) || isStandardCallout(a)\n}\n\n/**\n * The patch that puts a free text's text box at `box`, refitting `rect` and `fringe` around\n * it. A callout's points become `callout` (its own by default) and `rect` holds them too; any\n * other box keeps its fringe, or has `rect` equal to the box without one.\n */\nexport function withBox(\n a: FreeTextAnnotation,\n box: Rect,\n callout: readonly Point[] | undefined = a.callout\n): Partial<FreeTextAnnotation> {\n if (hasCallout(a) && callout)\n return {\n ...withCalloutBounds(box, callout, calloutStroke(a).width, a.head),\n callout: callout.map((p) => ({ ...p })),\n }\n const f = a.fringe\n if (!f) return { rect: { ...box } }\n return {\n rect: {\n x: box.x - f.left,\n y: box.y - f.bottom,\n width: box.width + f.left + f.right,\n height: box.height + f.bottom + f.top,\n },\n }\n}\n\n/** Half a speech bubble's wedge where it leaves the box, points. */\nexport const WEDGE_HALF = 8\n\ntype Edge = 'left' | 'right' | 'bottom' | 'top'\nconst EDGES: readonly Edge[] = ['left', 'right', 'bottom', 'top']\n\n/**\n * The edge of `box` nearest `p`. `bubblePath` (dom/overlay-render.ts) picks the wedge's edge by\n * the same rule in CSS px; change both together.\n */\nfunction nearestEdge(p: Point, box: Rect): Edge {\n const gaps: Record<Edge, number> = {\n left: Math.abs(p.x - box.x),\n right: Math.abs(p.x - (box.x + box.width)),\n bottom: Math.abs(p.y - box.y),\n top: Math.abs(p.y - (box.y + box.height)),\n }\n return EDGES.reduce((best, e) => (gaps[e] < gaps[best] ? e : best))\n}\n\n/** The side of `box` that `p` lies furthest beyond. */\nfunction edgeBeyond(p: Point, box: Rect): Edge {\n const beyond: Record<Edge, number> = {\n left: box.x - p.x,\n right: p.x - (box.x + box.width),\n bottom: box.y - p.y,\n top: p.y - (box.y + box.height),\n }\n return EDGES.reduce((best, e) => (beyond[e] > beyond[best] ? e : best))\n}\n\n/**\n * `p` carried from the box `from` onto the box `to`: it keeps its fraction along the box edge\n * nearest it and its distance off that edge.\n */\nexport function onMovedEdge(p: Point, from: Rect, to: Rect): Point {\n const edge = nearestEdge(p, from)\n const along = (\n v: number,\n start: number,\n size: number,\n next: number,\n nextSize: number\n ) => next + (size === 0 ? nextSize / 2 : ((v - start) / size) * nextSize)\n if (edge === 'left' || edge === 'right') {\n const x = edge === 'left' ? from.x : from.x + from.width\n const nx = edge === 'left' ? to.x : to.x + to.width\n return { x: nx + p.x - x, y: along(p.y, from.y, from.height, to.y, to.height) }\n }\n const y = edge === 'bottom' ? from.y : from.y + from.height\n const ny = edge === 'bottom' ? to.y : to.y + to.height\n return { x: along(p.x, from.x, from.width, to.x, to.width), y: ny + p.y - y }\n}\n\n/**\n * `p` placed on `box`'s `edge` at its own position along it, kept `margin` points clear of the\n * corners (at most half the edge).\n */\nfunction ontoEdge(p: Point, box: Rect, edge: Edge, margin: number): Point {\n const clamp = (v: number, start: number, size: number) => {\n const m = Math.min(margin, size / 2)\n return Math.min(Math.max(v, start + m), start + size - m)\n }\n if (edge === 'left' || edge === 'right')\n return {\n x: edge === 'left' ? box.x : box.x + box.width,\n y: clamp(p.y, box.y, box.height),\n }\n return {\n x: clamp(p.x, box.x, box.width),\n y: edge === 'bottom' ? box.y : box.y + box.height,\n }\n}\n\n/**\n * The patch that resizes a free text's text box to `to`. A callout's tip and bend stay where\n * they are and its last point moves with the box edge it sits on (`onMovedEdge`).\n */\nexport function resizedBox(a: FreeTextAnnotation, to: Rect): Partial<FreeTextAnnotation> {\n if (!hasCallout(a)) return withBox(a, to)\n const from = freeTextBox(a)\n const last = a.callout.length - 1\n return withBox(\n a,\n to,\n a.callout.map((p, i) => (i === last ? onMovedEdge(p, from, to) : p))\n )\n}\n\n/**\n * The patch that moves a callout's tip to `to`, leaving its text box where it is. A callout\n * without a bend (every bubble) moves its edge point to the side the tip now lies furthest\n * beyond, at its own position along that side and clear of the corners, so the line or wedge\n * never crosses the box; on the same side it stays put. A bend and its edge point stay.\n */\nexport function movedTip(\n a: FreeTextAnnotation & { callout: readonly Point[] },\n to: Point\n): Partial<FreeTextAnnotation> {\n const box = freeTextBox(a)\n if (a.callout.length !== 2) return withBox(a, box, [to, ...a.callout.slice(1)])\n const edge = a.callout[1]!\n const side = edgeBeyond(to, box)\n const margin = (a.cornerRadius ?? 0) + WEDGE_HALF\n return withBox(a, box, [\n to,\n nearestEdge(edge, box) === side ? edge : ontoEdge(edge, box, side, margin),\n ])\n}\n","// Maps the style controls' names (`border`, `fill`, `width`…) to each annotation type's\n// fields and back. Pure: no store, no DOM. A prop maps only where the type has the field, so a\n// patch for a mixed selection lands on each annotation as far as it can.\nimport type { StyleGroup, StyleProps } from './tool-style'\nimport type { Annotation, AnnotationPatch, AnnotationType } from './types'\n\ntype StyleKey = keyof StyleProps\n\n/** For each type, the control-level props it supports and the field each writes. */\nconst FIELDS: Readonly<\n Record<AnnotationType, Readonly<Partial<Record<StyleKey, string>>>>\n> = {\n square: {\n border: 'color',\n fill: 'interiorColor',\n opacity: 'opacity',\n width: 'width',\n dashes: 'dashes',\n },\n circle: {\n border: 'color',\n fill: 'interiorColor',\n opacity: 'opacity',\n width: 'width',\n dashes: 'dashes',\n },\n polygon: {\n border: 'color',\n fill: 'interiorColor',\n opacity: 'opacity',\n width: 'width',\n dashes: 'dashes',\n },\n polyline: {\n border: 'color',\n opacity: 'opacity',\n width: 'width',\n dashes: 'dashes',\n head: 'head',\n tail: 'tail',\n },\n line: {\n border: 'color',\n opacity: 'opacity',\n width: 'width',\n dashes: 'dashes',\n head: 'head',\n tail: 'tail',\n },\n // Ink is drawn solid, so it has no dashes.\n ink: { border: 'color', opacity: 'opacity', width: 'width' },\n highlight: { border: 'color', opacity: 'opacity' },\n underline: { border: 'color', opacity: 'opacity' },\n strikeout: { border: 'color', opacity: 'opacity' },\n squiggly: { border: 'color', opacity: 'opacity' },\n redact: { border: 'color', opacity: 'opacity' },\n // XFDF: a box's `color` is its fill; the text style lives in `defaultStyle`.\n freetext: {\n border: 'borderColor',\n fill: 'color',\n textColor: 'defaultStyle.color',\n opacity: 'opacity',\n width: 'width',\n dashes: 'dashes',\n fontFamily: 'defaultStyle.fontFamily',\n fontSize: 'defaultStyle.fontSize',\n fontWeight: 'defaultStyle.fontWeight',\n fontStyle: 'defaultStyle.fontStyle',\n textDecoration: 'defaultStyle.textDecoration',\n textAlign: 'defaultStyle.textAlign',\n },\n // The rim is the outline; the inside is the magnified page, so there is no fill, and the\n // rim is drawn solid.\n loupe: { border: 'color', opacity: 'opacity', width: 'width' },\n // A mask dims the page outside a shape: nothing for the style controls to change.\n mask: {},\n text: {},\n // An image, signatures among them: the style controls have nothing to change on it.\n stamp: {},\n}\n\nconst GROUPS: Readonly<Record<AnnotationType, StyleGroup | undefined>> = {\n square: 'shape',\n circle: 'shape',\n line: 'shape',\n polyline: 'shape',\n polygon: 'shape',\n loupe: 'shape',\n ink: 'ink',\n freetext: 'text',\n highlight: 'markup',\n underline: 'markup',\n strikeout: 'markup',\n squiggly: 'markup',\n redact: 'redact',\n text: undefined,\n stamp: undefined,\n mask: undefined,\n}\n\nconst SUPPORTED = new Map<AnnotationType, ReadonlySet<StyleKey>>(\n (Object.keys(FIELDS) as AnnotationType[]).map((type) => [\n type,\n new Set(Object.keys(FIELDS[type]) as StyleKey[]),\n ])\n)\n\n/**\n * The props a speech bubble (`intent: 'FreeTextCallout'`) takes from the `shape` group: its\n * outline, fill and opacity, as the shape tool creates it. Its text props stay in `text`.\n */\nconst BUBBLE_SHAPE_PROPS: ReadonlySet<StyleKey> = new Set([\n 'border',\n 'fill',\n 'opacity',\n 'width',\n 'dashes',\n])\n\n/**\n * The style group an annotation's type belongs to; notes belong to none. With `key`, the group\n * that owns that prop on `a`: a speech bubble's outline and fill are `shape`'s, its text `text`'s.\n */\nexport function styleGroupOf(\n a: Pick<Annotation, 'type'> & { intent?: string | undefined },\n key?: StyleKey\n): StyleGroup | undefined {\n if (\n key !== undefined &&\n a.type === 'freetext' &&\n a.intent === 'FreeTextCallout' &&\n BUBBLE_SHAPE_PROPS.has(key)\n )\n return 'shape'\n return GROUPS[a.type]\n}\n\n/** Every group that owns some prop on `a`: two for a speech bubble, else at most one. */\nexport function styleGroupsOf(\n a: Pick<Annotation, 'type'> & { intent?: string | undefined }\n): StyleGroup[] {\n const out = new Set<StyleGroup>()\n const own = GROUPS[a.type]\n if (own) out.add(own)\n for (const key of supportedProps(a.type)) {\n const g = styleGroupOf(a, key)\n if (g) out.add(g)\n }\n return [...out]\n}\n\n/** The types in `group`, from the same table `styleGroupOf` reads. */\nexport function typesInGroup(group: StyleGroup): AnnotationType[] {\n return (Object.keys(GROUPS) as AnnotationType[]).filter((t) => GROUPS[t] === group)\n}\n\n/** The style group a type belongs to. */\nexport function styleGroupOfType(type: AnnotationType): StyleGroup | undefined {\n return GROUPS[type]\n}\n\n/** The control-level props `type` supports. */\nexport function supportedProps(type: AnnotationType): ReadonlySet<StyleKey> {\n return SUPPORTED.get(type) ?? new Set()\n}\n\n/**\n * The control values a field leaves out: `normal` weight and style, no decoration. The field\n * is absent rather than holding them, as XFDF writes only what differs.\n */\nconst UNSET: Readonly<Partial<Record<StyleKey, unknown>>> = {\n fontWeight: 'normal',\n fontStyle: 'normal',\n textDecoration: 'none',\n}\n\n/** The prefix of a field nested in `defaultStyle` (free text). */\nconst STYLE = 'defaultStyle.'\n\n/**\n * The field patch `patch` means on `type`. Props the type lacks are dropped. A `null` fill\n * becomes `interiorColor: undefined` (`color` on free text), which removes the fill when the\n * store applies it; so does `normal` weight or style and no decoration. Free-text text props go\n * into a partial `defaultStyle`, which the store merges into the current one.\n */\nexport function toFields(type: AnnotationType, patch: StyleProps): AnnotationPatch {\n const fields = FIELDS[type]\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(patch) as StyleKey[]) {\n const field = fields[key]\n if (field === undefined) continue\n const raw = patch[key]\n const value = raw === null || raw === UNSET[key] ? undefined : raw\n if (field.startsWith(STYLE)) {\n const style = (out.defaultStyle ??= {}) as Record<string, unknown>\n style[field.slice(STYLE.length)] = value\n } else {\n out[field] = value\n }\n }\n return out\n}\n\n/** The control-level props an annotation shows, for the props its type supports. */\nexport function fromAnnotation(a: Annotation): StyleProps {\n const fields = FIELDS[a.type]\n const record = a as unknown as Record<string, unknown>\n const style = (record.defaultStyle ?? {}) as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(fields) as StyleKey[]) {\n const field = fields[key] as string\n const value = field.startsWith(STYLE)\n ? style[field.slice(STYLE.length)]\n : record[field]\n if (value !== undefined) out[key] = value\n else if (key === 'fill' || key === 'dashes') out[key] = null\n else if (key === 'head' || key === 'tail') out[key] = 'None'\n else if (UNSET[key] !== undefined) out[key] = UNSET[key]\n }\n return out\n}\n","// The current style per style group, shared by the tools that create into a group and the\n// style controls. Within a group the style is shared: recolouring a line also colours the next\n// rectangle. Groups start empty, so until a control sets a prop each type keeps its theme\n// default (the store's `completeInput` fills it).\n//\n// `set` writes through the store, so in controlled mode every change is proposed to the host's\n// `onChange` and nothing is applied before the host applies it.\nimport { writable, type Readable, type Writable } from '../readable'\n\nimport { freeTextBox } from './callout'\nimport { hasCallout, withBox } from './edit'\nimport {\n fromAnnotation,\n styleGroupOf,\n styleGroupsOf,\n supportedProps,\n toFields,\n typesInGroup,\n} from './style-map'\n\nimport type { AnnotationStore } from './store'\nimport type {\n Annotation,\n AnnotationInput,\n AnnotationPatch,\n FreeTextAnnotation,\n LineEnding,\n} from './types'\n\nexport type StyleGroup = 'shape' | 'ink' | 'text' | 'markup' | 'redact'\n\nexport const STYLE_GROUPS: readonly StyleGroup[] = [\n 'shape',\n 'ink',\n 'text',\n 'markup',\n 'redact',\n]\n\n/** Style as the controls name it; `style-map` turns it into each type's fields. */\nexport interface StyleProps {\n /** #RRGGBB */\n border?: string\n /** `null` means no fill. */\n fill?: string | null\n textColor?: string\n opacity?: number\n width?: number\n /** `null` means solid. */\n dashes?: number[] | null\n head?: LineEnding\n tail?: LineEnding\n fontFamily?: string\n fontSize?: number\n fontWeight?: 'normal' | 'bold'\n fontStyle?: 'normal' | 'italic'\n textDecoration?: 'none' | 'underline'\n textAlign?: 'left' | 'center' | 'right' | 'justify'\n}\n\nexport type StyleKey = keyof StyleProps\n\n/** What the controls show: one value per prop, or `'mixed'` when a selection disagrees. */\nexport type CurrentStyle = { [K in StyleKey]?: StyleProps[K] | 'mixed' }\n\nexport interface ToolStyle {\n get(group: StyleGroup): Readonly<StyleProps>\n readable(group: StyleGroup): Readable<Readonly<StyleProps>>\n /**\n * Values the controls show. Under a select tool, the selection's. Under a creation tool, the\n * selection's when it is non-empty and wholly in the tool's group, else the group's own: a\n * leftover selection from another tool does not take over the controls. `'mixed'` per prop\n * when selected values differ.\n */\n readonly current: Readable<CurrentStyle>\n /**\n * Which props the active tool or the selection supports; controls disable the rest. Under a\n * creation tool, the group's props, plus the selection's when it is wholly in the group.\n */\n readonly supported: Readable<ReadonlySet<StyleKey>>\n /**\n * Updates the active tool's group, or under a select tool (no active group) the group that\n * owns each prop on each selected annotation (a speech bubble's outline is `shape`'s, its\n * text `text`'s). With `apply` it also updates every selected, unlocked annotation that has\n * the props, in one history step. `apply` defaults to true under a select tool, and to\n * whether the selection is wholly in the group otherwise. `group` names the group explicitly.\n */\n set(patch: StyleProps, opts?: { group?: StyleGroup; apply?: boolean }): void\n /** Fills an AnnotationInput's unset style fields from the group (input wins). */\n resolve<T extends AnnotationInput>(group: StyleGroup, input: T): T\n /**\n * The style as a control for one group sees it, whatever the active tool: the selection's\n * when every selected annotation is in `group`, else the group's own. Same identity per group.\n */\n scoped(group: StyleGroup): ScopedToolStyle\n}\n\n/** A view of the tool style for one group, as `ToolStyle.scoped` gives it. */\nexport interface ScopedToolStyle {\n readonly group: StyleGroup\n readonly current: Readable<CurrentStyle>\n readonly supported: Readable<ReadonlySet<StyleKey>>\n /** Updates the group, and the selection too when every selected annotation is in it. */\n set(patch: StyleProps): void\n}\n\nexport interface ToolStyleDeps {\n store: AnnotationStore\n history: { batch(fn: () => void): void }\n /** The active tool's style group; `undefined` for select tools. */\n activeGroup: () => StyleGroup | undefined\n /** Fires when the active tool changes, so `current` and `supported` follow it. */\n active?: Readable<unknown>\n}\n\n/** Every prop some type in `group` supports. */\nfunction groupProps(group: StyleGroup): ReadonlySet<StyleKey> {\n const out = new Set<StyleKey>()\n for (const type of typesInGroup(group))\n for (const key of supportedProps(type)) out.add(key)\n return out\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (Array.isArray(a) && Array.isArray(b))\n return a.length === b.length && a.every((v, i) => Object.is(v, b[i]))\n return false\n}\n\nfunction sameRecord(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n const ka = Object.keys(a)\n if (ka.length !== Object.keys(b).length) return false\n return ka.every((k) => k in b && sameValue(a[k], b[k]))\n}\n\nfunction sameSet<T>(a: ReadonlySet<T>, b: ReadonlySet<T>): boolean {\n return a.size === b.size && [...a].every((v) => b.has(v))\n}\n\n/**\n * A readable recomputed from `fn` whenever any source fires, subscribed to its sources only\n * while it has subscribers. Equal results (by `eq`) are not re-emitted and keep their identity.\n */\nfunction computed<T>(\n sources: readonly Readable<unknown>[],\n fn: () => T,\n eq: (a: T, b: T) => boolean\n): Readable<T> {\n const subs = new Set<(v: T) => void>()\n let cached: { value: T } | undefined\n let stops: (() => void)[] | undefined\n /** Recomputes, keeping the previous value's identity when equal. True when it changed. */\n const recompute = (): boolean => {\n const next = fn()\n if (cached && eq(next, cached.value)) return false\n cached = { value: next }\n return true\n }\n const refresh = (): void => {\n if (!recompute() || !cached) return\n const value = cached.value\n for (const sub of [...subs]) sub(value)\n }\n return {\n // Stable identity for equal values even unobserved: React's useSyncExternalStore reads\n // the snapshot before it subscribes and loops on a fresh object.\n get: () => {\n if (!stops) recompute()\n return (cached as { value: T }).value\n },\n subscribe(sub) {\n if (!stops) {\n recompute()\n stops = sources.map((s) => s.subscribe(refresh))\n }\n subs.add(sub)\n return () => {\n if (!subs.delete(sub) || subs.size > 0) return\n for (const stop of stops ?? []) stop()\n stops = undefined\n }\n },\n }\n}\n\nexport function createToolStyle(deps: ToolStyleDeps): ToolStyle {\n const { store, history, activeGroup } = deps\n const groups = new Map<StyleGroup, Writable<Readonly<StyleProps>>>(\n STYLE_GROUPS.map((g) => [g, writable<Readonly<StyleProps>>({})])\n )\n const groupStore = (g: StyleGroup): Writable<Readonly<StyleProps>> => {\n const w = groups.get(g)\n if (!w) throw new RangeError(`Unknown style group ${String(g)}`)\n return w\n }\n\n /** The selected annotations, including changes proposed to a controlled host. */\n const selected = (): Annotation[] =>\n store.selection\n .get()\n .map((id) => store._getProposed(id) ?? store.get(id))\n .filter((a): a is Annotation => a !== undefined)\n\n const sources: Readable<unknown>[] = [\n store.list,\n store.selection,\n ...groups.values(),\n ...(deps.active ? [deps.active] : []),\n ]\n\n /** One value per prop over `items`, `'mixed'` where they differ. */\n const styleOf = (items: readonly Annotation[]): CurrentStyle => {\n const out: Record<string, unknown> = {}\n for (const a of items) {\n const props = fromAnnotation(a) as Record<string, unknown>\n for (const [key, value] of Object.entries(props)) {\n if (!(key in out)) out[key] = value\n else if (out[key] !== 'mixed' && !sameValue(out[key], value)) out[key] = 'mixed'\n }\n }\n return out\n }\n\n const propsOf = (items: readonly Annotation[]): ReadonlySet<StyleKey> => {\n const out = new Set<StyleKey>()\n for (const a of items) for (const key of supportedProps(a.type)) out.add(key)\n return out\n }\n\n /** The selection, when it is non-empty and wholly in `group`. */\n const selectedIn = (group: StyleGroup): Annotation[] | null => {\n const items = selected()\n return items.length > 0 && items.every((a) => styleGroupsOf(a).includes(group))\n ? items\n : null\n }\n\n const current = computed<CurrentStyle>(\n sources,\n () => {\n const g = activeGroup()\n if (!g) return styleOf(selected())\n const items = selectedIn(g)\n return items ? styleOf(items) : { ...groupStore(g).get() }\n },\n (a, b) => sameRecord(a, b)\n )\n\n const supported = computed<ReadonlySet<StyleKey>>(\n sources,\n () => {\n const g = activeGroup()\n if (!g) return propsOf(selected())\n const items = selectedIn(g)\n return items ? new Set([...groupProps(g), ...propsOf(items)]) : groupProps(g)\n },\n sameSet\n )\n\n const scopes = new Map<StyleGroup, ScopedToolStyle>()\n function scoped(group: StyleGroup): ScopedToolStyle {\n const known = scopes.get(group)\n if (known) return known\n groupStore(group)\n const scope: ScopedToolStyle = {\n group,\n current: computed<CurrentStyle>(\n sources,\n () => {\n const items = selectedIn(group)\n return items ? styleOf(items) : { ...groupStore(group).get() }\n },\n (a, b) => sameRecord(a, b)\n ),\n supported: computed<ReadonlySet<StyleKey>>(\n sources,\n () => {\n const items = selectedIn(group)\n return items ? propsOf(items) : groupProps(group)\n },\n sameSet\n ),\n set: (patch) => set(patch, { group, apply: selectedIn(group) !== null }),\n }\n scopes.set(group, scope)\n return scope\n }\n\n function set(\n patch: StyleProps,\n opts: { group?: StyleGroup; apply?: boolean } = {}\n ): void {\n const items = selected()\n const active = opts.group ?? activeGroup()\n const keys = (Object.keys(patch) as StyleKey[]).filter((k) => patch[k] !== undefined)\n // The keys each group takes: all of them for the active group, else each prop goes to the\n // group that owns it on each selected annotation.\n const targets = new Map<StyleGroup, Set<StyleKey>>()\n if (active) targets.set(active, new Set(keys))\n else\n for (const a of items)\n for (const key of keys) {\n if (!supportedProps(a.type).has(key)) continue\n const g = styleGroupOf(a, key)\n if (!g) continue\n const own = targets.get(g) ?? new Set<StyleKey>()\n own.add(key)\n targets.set(g, own)\n }\n for (const [g, own] of targets) {\n const allowed = groupProps(g)\n const next: Record<string, unknown> = { ...groupStore(g).get() }\n let changed = false\n for (const key of own) {\n if (!allowed.has(key)) continue\n next[key] = patch[key]\n changed = true\n }\n if (changed) groupStore(g).set(next)\n }\n if (!(opts.apply ?? (active === undefined || selectedIn(active) !== null))) return\n const edits = items\n .filter((a) => !a.locked)\n .map((a) => ({ id: a.id, fields: refit(a, toFields(a.type, patch)) }))\n .filter((e) => Object.keys(e.fields).length > 0)\n if (edits.length === 0) return\n history.batch(() => {\n for (const e of edits) store.update(e.id, e.fields)\n })\n }\n\n /**\n * `fields` with a callout's `rect` and `fringe` refit when they change its border width, so\n * the bounds keep covering the leader, its ending and the outline.\n */\n function refit(a: Annotation, fields: AnnotationPatch): AnnotationPatch {\n if (!('width' in fields) || !hasCallout(a)) return fields\n const next = { ...a, ...fields } as FreeTextAnnotation\n return { ...fields, ...withBox(next, freeTextBox(a)) } as AnnotationPatch\n }\n\n /** `value`'s keys that hold something. */\n const defined = (value: unknown): Record<string, unknown> =>\n Object.fromEntries(\n Object.entries((value ?? {}) as Record<string, unknown>).filter(\n ([, v]) => v !== undefined\n )\n )\n\n function resolve<T extends AnnotationInput>(group: StyleGroup, input: T): T {\n const fields = toFields(input.type, groupStore(group).get()) as Record<\n string,\n unknown\n >\n const out: Record<string, unknown> = { ...input }\n for (const [key, value] of Object.entries(fields)) {\n if (key === 'defaultStyle') {\n // Nested text style: the group's keys fill those the input leaves unset (or undefined).\n out[key] = { ...defined(value), ...defined(out[key]) }\n } else if (value !== undefined && out[key] === undefined) out[key] = value\n }\n return out as T\n }\n\n return {\n get: (g) => groupStore(g).get(),\n readable: (g) => {\n const w = groupStore(g)\n return { get: () => w.get(), subscribe: (fn) => w.subscribe(fn) }\n },\n current,\n supported,\n set,\n resolve,\n scoped,\n }\n}\n","import { isTextMarkup } from './edit'\n\nimport type { Annotation, NoteAnnotation, TextMarkupAnnotation } from './types'\n\n/** What a thread can hang from: a note, or text markup whose `contents` is its comment. */\nexport type ThreadRoot = NoteAnnotation | TextMarkupAnnotation\n\nexport function isThreadRoot(a: Annotation): a is ThreadRoot {\n return a.type === 'text' || isTextMarkup(a)\n}\n\n/**\n * True for a reply: an annotation whose `inReplyTo` names a thread root (a note or text markup)\n * in `list`. Replies show in the thread popover only, never on the page.\n */\nexport function isReply(a: Annotation, list: readonly Annotation[]): boolean {\n if (a.inReplyTo === undefined) return false\n const parent = list.find((x) => x.id === a.inReplyTo)\n return parent !== undefined && isThreadRoot(parent)\n}\n\n/** `list` less its replies (see `isReply`), in the same order. */\nexport function withoutReplies(list: readonly Annotation[]): Annotation[] {\n const roots = new Set(list.filter(isThreadRoot).map((a) => a.id))\n return list.filter((a) => a.inReplyTo === undefined || !roots.has(a.inReplyTo))\n}\n\n/** Direct replies to `id`, in creation order. */\nexport function repliesTo(list: readonly Annotation[], id: string): Annotation[] {\n return list\n .filter((a) => a.inReplyTo === id)\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt))\n}\n\n/**\n * The top of a thread: follows `inReplyTo` up through notes, stopping at text markup (which\n * roots a thread of its own), a missing parent, a parent that cannot root a thread, or a\n * cycle. Null when `start` is neither a note nor text markup.\n */\nexport function threadRoot(\n list: readonly Annotation[],\n start: Annotation\n): ThreadRoot | null {\n if (!isThreadRoot(start)) return null\n const seen = new Set([start.id])\n let current: ThreadRoot = start\n while (current.type === 'text' && current.inReplyTo) {\n const id: string = current.inReplyTo\n const parent = list.find((a) => a.id === id)\n if (!parent || !isThreadRoot(parent) || seen.has(parent.id)) break\n seen.add(parent.id)\n current = parent\n }\n return current\n}\n\n/** The root, then every reply below it, depth first, each level in creation order. */\nexport function threadOf(list: readonly Annotation[], root: ThreadRoot): Annotation[] {\n const out: Annotation[] = [root]\n const seen = new Set([root.id])\n const visit = (id: string): void => {\n for (const r of repliesTo(list, id)) {\n if (seen.has(r.id)) continue\n seen.add(r.id)\n out.push(r)\n visit(r.id)\n }\n }\n visit(root.id)\n return out\n}\n\n/**\n * An unlocked root note with no text and no replies: nothing a reader would miss. Always\n * false for text markup, which is worth keeping without a comment.\n */\nexport function isAbandonedNote(a: Annotation, list: readonly Annotation[]): boolean {\n if (a.type !== 'text' || a.locked || a.inReplyTo || a.contents?.trim()) return false\n return repliesTo(list, a.id).length === 0\n}\n","// Pure geometry for the shape tool: vertices for stars and polygons, Shift constraints and the\n// annotation each kind creates. Everything is PDF user space, points, origin bottom-left.\nimport { withCalloutBounds } from './callout'\n\nimport type { Point, Rect } from '../geometry'\nimport type { PageRotation } from '../pages'\nimport type { AnnotationInput } from './types'\n\n/** Every kind the shape menu can offer. Kinds without a creator yet are not in `SHAPE_KINDS`. */\nexport type ShapeKind =\n | 'line'\n | 'arrow'\n | 'rectangle'\n | 'roundedRectangle'\n | 'ellipse'\n | 'bubble'\n | 'star'\n | 'polygon'\n | 'loupe'\n | 'mask'\n | 'ovalMask'\n\nexport interface ShapeOptions {\n kind: ShapeKind\n /** Points of a star. */\n points: number\n /** Sides of a polygon. */\n sides: number\n}\n\n/** The kinds the shape menu offers today, in menu order. Later kinds extend this. */\nexport const SHAPE_KINDS: readonly ShapeKind[] = [\n 'line',\n 'arrow',\n 'rectangle',\n 'roundedRectangle',\n 'ellipse',\n 'bubble',\n 'star',\n 'polygon',\n 'loupe',\n 'mask',\n 'ovalMask',\n]\n\nexport const DEFAULT_SHAPE_OPTIONS: Readonly<ShapeOptions> = {\n kind: 'rectangle',\n points: 5,\n sides: 6,\n}\n\nconst POINTER_ONLY: ReadonlySet<ShapeKind> = new Set(['loupe', 'mask', 'ovalMask'])\n\n/**\n * True for kinds only a pointer creates: the loupe and the mask. `Enter` with the shape tool\n * does not place them.\n */\nexport function isPointerOnlyKind(kind: ShapeKind): boolean {\n return POINTER_ONLY.has(kind)\n}\n\n/** Magnification of a new loupe. */\nexport const DEFAULT_LOUPE_MAGNIFICATION = 2\n\n/** How strongly a new mask dims the page. */\nexport const DEFAULT_MASK_DIM = 0.5\n\n/** Side of the shape a click or Enter places, in points. */\nexport const DEFAULT_SHAPE_SIZE = 72\n/** Corner radius of a new rounded rectangle, in points. */\nexport const DEFAULT_CORNER_RADIUS = 8\n\n/** How far below and left of its anchor a new speech bubble's tail tip sits, in points. */\nconst BUBBLE_TAIL = 24\n/** A new speech bubble's outline width, in points, before the style group's applies. */\nconst BUBBLE_WIDTH = 1\n\nconst clean = (n: number): number => n + 0\n\n/** The box between two corners. */\nfunction rectOf(a: Point, b: Point): Rect {\n return {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n width: Math.abs(b.x - a.x),\n height: Math.abs(b.y - a.y),\n }\n}\n\n/**\n * Vertices round a circle, the first at the top centre, clockwise on the page, stretched so their\n * bounds fill `rect`.\n */\nfunction ring(rect: Rect, count: number, radius: (index: number) => number): Point[] {\n const unit = Array.from({ length: count }, (_, i) => {\n const angle = (i * 2 * Math.PI) / count\n const r = radius(i)\n return { x: r * Math.sin(angle), y: r * Math.cos(angle) }\n })\n const xs = unit.map((p) => p.x)\n const ys = unit.map((p) => p.y)\n const fit = (v: number, min: number, max: number, start: number, size: number) =>\n clean(max > min ? start + ((v - min) / (max - min)) * size : start + size / 2)\n const [minX, maxX, minY, maxY] = [\n Math.min(...xs),\n Math.max(...xs),\n Math.min(...ys),\n Math.max(...ys),\n ]\n return unit.map((p) => ({\n x: fit(p.x, minX, maxX, rect.x, rect.width),\n y: fit(p.y, minY, maxY, rect.y, rect.height),\n }))\n}\n\n/**\n * A star's `2 * points` vertices, outer and inner alternating, stretched to fill `rect`, the first\n * at the top centre.\n */\nexport function starVertices(rect: Rect, points: number, innerRatio = 0.5): Point[] {\n const n = Math.max(2, Math.round(points))\n return ring(rect, n * 2, (i) => (i % 2 === 0 ? 1 : innerRatio))\n}\n\n/** A regular polygon's vertices, stretched to fill `rect`, the first at the top centre. */\nexport function polygonVertices(rect: Rect, sides: number): Point[] {\n return ring(rect, Math.max(3, Math.round(sides)), () => 1)\n}\n\nconst LINE_KINDS: ReadonlySet<ShapeKind> = new Set(['line', 'arrow'])\n\n/** True for kinds drawn between two endpoints rather than inside a box. */\nexport function isLineKind(kind: ShapeKind): boolean {\n return LINE_KINDS.has(kind)\n}\n\nconst H = Math.SQRT1_2\n/** Unit steps every 45 degrees, counter-clockwise from +x (y up). */\nconst EIGHT_WAYS: readonly Point[] = [\n { x: 1, y: 0 },\n { x: H, y: H },\n { x: 0, y: 1 },\n { x: -H, y: H },\n { x: -1, y: 0 },\n { x: -H, y: -H },\n { x: 0, y: -1 },\n { x: H, y: -H },\n]\n\n/**\n * Where the drag ends with Shift held: a square or circle for box kinds, the nearest 45 degree\n * angle for lines.\n */\nexport function constrain(kind: ShapeKind, start: Point, end: Point): Point {\n const dx = end.x - start.x\n const dy = end.y - start.y\n if (isLineKind(kind)) {\n const step = Math.round(Math.atan2(dy, dx) / (Math.PI / 4))\n const u = EIGHT_WAYS[((step % 8) + 8) % 8]!\n const length = dx * u.x + dy * u.y\n return { x: clean(start.x + length * u.x), y: clean(start.y + length * u.y) }\n }\n const size = Math.max(Math.abs(dx), Math.abs(dy))\n return {\n x: clean(start.x + (dx < 0 ? -size : size)),\n y: clean(start.y + (dy < 0 ? -size : size)),\n }\n}\n\n/**\n * The two drag corners of the default-size shape centred on `at`. A line or arrow runs left to\n * right on the page as the file displays it: along user space turned anticlockwise by the\n * page's /Rotate `rotation`, which undoes the page's clockwise turn, as a signature is placed.\n */\nexport function defaultEnds(\n kind: ShapeKind,\n at: Point,\n rotation: PageRotation = 0\n): [Point, Point] {\n const half = DEFAULT_SHAPE_SIZE / 2\n if (!isLineKind(kind))\n return [\n { x: at.x - half, y: at.y - half },\n { x: at.x + half, y: at.y + half },\n ]\n const rad = (rotation * Math.PI) / 180\n const dx = Math.round(Math.cos(rad)) * half\n const dy = Math.round(Math.sin(rad)) * half\n return [\n { x: clean(at.x - dx), y: clean(at.y - dy) },\n { x: clean(at.x + dx), y: clean(at.y + dy) },\n ]\n}\n\n/** The annotation a shape kind creates between two points, or `undefined` for a kind without a creator yet. */\nexport function shapeInput(\n kind: ShapeKind,\n page: number,\n start: Point,\n end: Point,\n opts: ShapeOptions\n): AnnotationInput | undefined {\n const rect = rectOf(start, end)\n switch (kind) {\n case 'line':\n return { type: 'line', page, start, end }\n case 'arrow':\n return { type: 'line', page, start, end, intent: 'LineArrow' }\n case 'rectangle':\n return { type: 'square', page, rect }\n case 'roundedRectangle':\n return { type: 'square', page, rect, cornerRadius: DEFAULT_CORNER_RADIUS }\n case 'ellipse':\n return { type: 'circle', page, rect }\n case 'bubble': {\n // A standard callout around the dragged box: the edge point is the box's bottom-left\n // quarter point, and the tail runs from it to the tip below and left.\n const edge = { x: clean(rect.x + rect.width / 4), y: clean(rect.y) }\n const tip = { x: clean(edge.x - BUBBLE_TAIL), y: clean(edge.y - BUBBLE_TAIL) }\n const callout = [tip, edge]\n return {\n type: 'freetext',\n page,\n contents: '',\n intent: 'FreeTextCallout',\n cornerRadius: DEFAULT_CORNER_RADIUS,\n width: BUBBLE_WIDTH,\n ...withCalloutBounds(rect, callout, BUBBLE_WIDTH, undefined),\n callout,\n }\n }\n case 'star':\n return { type: 'polygon', page, vertices: starVertices(rect, opts.points) }\n case 'polygon':\n return { type: 'polygon', page, vertices: polygonVertices(rect, opts.sides) }\n case 'loupe':\n // Always a circle: the square on the drag's longer side, as Shift would make it.\n return {\n type: 'loupe',\n page,\n rect: rectOf(start, constrain(kind, start, end)),\n magnification: DEFAULT_LOUPE_MAGNIFICATION,\n }\n case 'mask':\n case 'ovalMask':\n return {\n type: 'mask',\n page,\n rect,\n shape: kind === 'mask' ? 'rect' : 'ellipse',\n dim: DEFAULT_MASK_DIM,\n }\n default:\n return undefined\n }\n}\n","// Recognises a single freehand stroke as a standard shape, by geometric fitting. Pure: no DOM.\n//\n// The stroke is resampled to evenly spaced points (a fiftieth of its box's diagonal apart, so\n// every test is scale-free). Corners of a closed stroke are where the path turns sharply over a\n// few samples, and corners whose neighbours run straight through them are dropped. Then each\n// kind is fitted and scored from 0 to 1, and the best fit wins:\n//\n// - line: how far the path strays from the chord between its ends;\n// - arrow: a straight shaft, then a short head at one end that folds back towards it;\n// - closed strokes (the ends meet, an overshoot trimmed) that wind once round their centre:\n// - ellipse: how far points stray from the ellipse inscribed in the stroke's box;\n// - rectangle: four corners, sides alternating horizontal and vertical;\n// - polygon: three to eight corners joined by straight sides that do not cross;\n// - star: an outline whose corners alternate far from and near the centre, or a pentagram\n// (five straight strokes that wind twice).\n//\n// A stroke that fails every gate (open and bent, winding more or less than once, sides that\n// cross, a corner count no kind has) gets no candidate, so a scrawl or a scribble comes back\n// undefined or scored low.\nimport { starVertices } from './annotations/shape-geometry'\n\nimport type { Point, Rect } from './geometry'\n\nexport type Recognised =\n | { kind: 'line'; start: Point; end: Point }\n | { kind: 'arrow'; start: Point; end: Point }\n | { kind: 'rectangle'; rect: Rect }\n | { kind: 'ellipse'; rect: Rect }\n /** A triangle or other closed polygon, its vertices where the stroke's corners are. */\n | { kind: 'polygon'; vertices: Point[] }\n /** A regular star, outer and inner vertices alternating, the first tip at the top. */\n | { kind: 'star'; vertices: Point[] }\n\n/** The score a fit needs before a stroke is tidied into its shape. */\nexport const RECOGNISE_THRESHOLD = 0.8\n\n/** Samples either side of a point that its turn is measured over. */\nconst W = 3\n/** Turns, over `2 * W` samples, that make a corner: outward, and back against the loop. */\nconst CONVEX_TURN = (40 * Math.PI) / 180\nconst CONCAVE_TURN = (15 * Math.PI) / 180\n/** Resampled points along the box diagonal. */\nconst DENSITY = 50\n/** A run of path is straight when its chord is at least this share of its length. */\nconst STRAIGHT = 0.95\n/** Corners whose neighbours this straight run through them (a turn under about 23 degrees) go. */\nconst MERGE_STRAIGHT = 0.98\n/** The ends of a closed stroke are within this share of the box diagonal. */\nconst CLOSE_GAP = 0.25\n/** Weights of a line's largest and mean straying from its chord, over its length. */\nconst LINE_MAX = 2\nconst LINE_MEAN = 2\n/** Weight of a polygon side's mean straying from its chord, over its length. */\nconst SIDE_MEAN = 3\n\ninterface Fit {\n shape: Recognised\n score: number\n}\n\nconst dist = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y)\nconst clamp01 = (n: number): number => Math.min(Math.max(n, 0), 1)\nconst round = (n: number): number => Math.round(n * 100) / 100 + 0\nconst pt = (p: Point): Point => ({ x: round(p.x), y: round(p.y) })\n\nfunction boxOf(points: readonly Point[]): Rect {\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n for (const p of points) {\n minX = Math.min(minX, p.x)\n minY = Math.min(minY, p.y)\n maxX = Math.max(maxX, p.x)\n maxY = Math.max(maxY, p.y)\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }\n}\n\nconst diagonal = (r: Rect): number => Math.hypot(r.width, r.height)\n\nfunction lengthOf(points: readonly Point[]): number {\n let total = 0\n for (let i = 1; i < points.length; i++) total += dist(points[i - 1]!, points[i]!)\n return total\n}\n\n/** Points every `spacing` along the path, the first and last included. */\nfunction resample(points: readonly Point[], spacing: number): Point[] {\n const out: Point[] = [points[0]!]\n let carried = 0\n let prev = points[0]!\n for (let i = 1; i < points.length; i++) {\n const next = points[i]!\n let d = dist(prev, next)\n while (carried + d >= spacing) {\n const t = (spacing - carried) / d\n const q = { x: prev.x + t * (next.x - prev.x), y: prev.y + t * (next.y - prev.y) }\n out.push(q)\n prev = q\n d = dist(prev, next)\n carried = 0\n }\n carried += d\n prev = next\n }\n const last = points[points.length - 1]!\n if (dist(out[out.length - 1]!, last) > spacing / 2) out.push(last)\n else out[out.length - 1] = last\n return out\n}\n\n/** Distance from `p` to the segment `a`–`b`. */\nfunction toSegment(p: Point, a: Point, b: Point): number {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const len2 = dx * dx + dy * dy\n const t = len2 === 0 ? 0 : clamp01(((p.x - a.x) * dx + (p.y - a.y) * dy) / len2)\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy))\n}\n\n/** Path lengths from the first point: `cum[i]` is the length up to point `i`. */\nfunction cumulative(points: readonly Point[]): number[] {\n const cum = [0]\n for (let i = 1; i < points.length; i++)\n cum.push(cum[i - 1]! + dist(points[i - 1]!, points[i]!))\n return cum\n}\n\n/**\n * Corner indices of the loop `r` (its last point joins its first), in order round it. A corner\n * is where the path turns sharply over a few samples: outward by more than `CONVEX_TURN`, or\n * back against the loop's own direction (a star's inner corner) by more than `CONCAVE_TURN`.\n */\nfunction cornersOf(r: readonly Point[]): number[] {\n const n = r.length\n if (n < 2 * W + 2) return []\n const at = (i: number): Point => r[((i % n) + n) % n]!\n const direction = Math.sign(winding(r, centroid(r))) || 1\n const turns = r.map((p, i) => {\n const a = at(i - W)\n const b = at(i + W)\n const turn = Math.atan2(b.y - p.y, b.x - p.x) - Math.atan2(p.y - a.y, p.x - a.x)\n return (\n direction *\n (turn > Math.PI ? turn - 2 * Math.PI : turn < -Math.PI ? turn + 2 * Math.PI : turn)\n )\n })\n /** 1 for an outward corner, -1 for an inward one, 0 for none. */\n const kind = (i: number): number =>\n turns[i]! > CONVEX_TURN ? 1 : turns[i]! < -CONCAVE_TURN ? -1 : 0\n // Each run of sharp turns one way is one corner, at its sharpest. Start where no run is.\n const start = turns.findIndex((_, i) => kind(i) === 0)\n if (start < 0) return []\n const corners: number[] = []\n let best: number | undefined\n for (let k = 0; k <= n; k++) {\n const i = (start + k) % n\n const c = k < n ? kind(i) : 0\n if (best !== undefined && c !== kind(best)) {\n corners.push(best)\n best = undefined\n }\n if (c !== 0 && (best === undefined || Math.abs(turns[i]!) > Math.abs(turns[best]!)))\n best = i\n }\n corners.sort((a, b) => a - b)\n // A jog where the stroke's ends meet can split one corner into two close together: keep the\n // sharper.\n for (let k = 0; corners.length > 1 && k < corners.length;) {\n const next = (k + 1) % corners.length\n if ((corners[next]! - corners[k]! + n) % n > 2 * W) k++\n else\n corners.splice(\n Math.abs(turns[corners[k]!]!) < Math.abs(turns[corners[next]!]!) ? k : next,\n 1\n )\n }\n return mergeStraight(r, corners)\n}\n\n/** Drops corners whose neighbours run straight through them, the straightest first. */\nfunction mergeStraight(r: readonly Point[], corners: number[]): number[] {\n const cum = cumulative(r)\n const total = cum[cum.length - 1]! + dist(r[r.length - 1]!, r[0]!)\n const arc = (a: number, b: number): number =>\n b > a ? cum[b]! - cum[a]! : total - cum[a]! + cum[b]!\n const out = [...corners]\n while (out.length > 3) {\n let drop = -1\n let straightest = MERGE_STRAIGHT\n for (let k = 0; k < out.length; k++) {\n const p = out[(k - 1 + out.length) % out.length]!\n const q = out[(k + 1) % out.length]!\n const a = arc(p, q)\n const ratio = a === 0 ? 1 : dist(r[p]!, r[q]!) / a\n if (ratio > straightest) {\n straightest = ratio\n drop = k\n }\n }\n if (drop < 0) break\n out.splice(drop, 1)\n }\n return out\n}\n\n/** Times the path winds round `c`, signed. */\nfunction winding(points: readonly Point[], c: Point): number {\n let total = 0\n for (let i = 0; i < points.length; i++) {\n const a = points[i]!\n const b = points[(i + 1) % points.length]!\n let d = Math.atan2(b.y - c.y, b.x - c.x) - Math.atan2(a.y - c.y, a.x - c.x)\n if (d > Math.PI) d -= 2 * Math.PI\n if (d < -Math.PI) d += 2 * Math.PI\n total += d\n }\n return total / (2 * Math.PI)\n}\n\n/** Largest and mean distance of `points` from the line through `a` and `b`, over `|ab|`. */\nfunction deviation(\n points: readonly Point[],\n a: Point,\n b: Point\n): { max: number; mean: number } {\n const len = dist(a, b)\n if (len === 0 || points.length === 0) return { max: Infinity, mean: Infinity }\n let max = 0\n let sum = 0\n for (const p of points) {\n const d = Math.abs((b.x - a.x) * (a.y - p.y) - (a.x - p.x) * (b.y - a.y)) / len\n max = Math.max(max, d)\n sum += d\n }\n return { max: max / len, mean: sum / points.length / len }\n}\n\n/** How straight a run from `a` to `b` is: 1 on the chord, falling as the path strays from it. */\nfunction straightness(points: readonly Point[], a: Point, b: Point): number {\n const dev = deviation(points, a, b)\n const bend = 1 - dist(a, b) / lengthOf(points)\n return clamp01(1 - LINE_MAX * dev.max - LINE_MEAN * dev.mean - 2 * bend)\n}\n\nfunction fitLine(r: readonly Point[]): Fit | undefined {\n const a = r[0]!\n const b = r[r.length - 1]!\n if (dist(a, b) / lengthOf(r) < 0.8) return undefined\n return {\n shape: { kind: 'line', start: pt(a), end: pt(b) },\n score: straightness(r, a, b),\n }\n}\n\n/** An arrow whose head is drawn at the end of `r`: a straight shaft, then a short fold back. */\nfunction fitArrow(r: readonly Point[]): Fit | undefined {\n // The tip is where the path first gets (nearly) as far from its start as it ever does: a\n // head with two barbs comes back to the tip, and the second visit may reach a little further.\n const from = r.map((p) => dist(p, r[0]!))\n const far = Math.max(...from)\n let tipAt = from.findIndex((d) => d >= 0.97 * far)\n while (tipAt + 1 < r.length && from[tipAt + 1]! > from[tipAt]!) tipAt++\n const shaft = r.slice(0, tipAt + 1)\n const head = r.slice(tipAt + 1)\n const tail = r[0]!\n const tip = r[tipAt]!\n const shaftLength = lengthOf(shaft)\n const headLength = lengthOf([tip, ...head])\n const total = shaftLength + headLength\n if (shaftLength < 0.6 * total || headLength < 0.06 * shaftLength) return undefined\n const along = { x: (tip.x - tail.x) / shaftLength, y: (tip.y - tail.y) / shaftLength }\n const chord = dist(tail, tip)\n if (chord / shaftLength < STRAIGHT) return undefined\n // The head stays near the tip, folds back from it, and leaves the shaft's line.\n let off = 0\n for (const p of head) {\n if (dist(p, tip) > 0.4 * chord) return undefined\n if ((p.x - tip.x) * along.x + (p.y - tip.y) * along.y > 0.08 * chord) return undefined\n off = Math.max(off, Math.abs((p.x - tip.x) * along.y - (p.y - tip.y) * along.x))\n }\n if (off < 0.04 * chord) return undefined\n return {\n shape: { kind: 'arrow', start: pt(tail), end: pt(tip) },\n score: straightness(shaft, tail, tip),\n }\n}\n\n/**\n * The stroke as a loop, evenly spaced all the way round (the gap between its ends bridged), an\n * overshoot past its start trimmed; undefined when the stroke is open.\n */\nfunction loopOf(r: readonly Point[], size: number, spacing: number): Point[] | undefined {\n const n = r.length\n if (n < 8) return undefined\n // The end may run past the start: close the loop where it comes nearest the start.\n let end = n - 1\n for (let i = Math.floor(n / 2); i < n; i++)\n if (dist(r[i]!, r[0]!) < dist(r[end]!, r[0]!)) end = i\n if (dist(r[end]!, r[0]!) > CLOSE_GAP * size || n - 1 - end > 0.25 * n) return undefined\n const loop = resample([...r.slice(0, end + 1), r[0]!], spacing)\n loop.pop()\n return loop\n}\n\nfunction fitEllipse(loop: readonly Point[], box: Rect): Fit | undefined {\n const rx = box.width / 2\n const ry = box.height / 2\n if (rx === 0 || ry === 0) return undefined\n const cx = box.x + rx\n const cy = box.y + ry\n let sum = 0\n for (const p of loop) sum += Math.abs(Math.hypot((p.x - cx) / rx, (p.y - cy) / ry) - 1)\n const mean = sum / loop.length\n return {\n shape: {\n kind: 'ellipse',\n rect: {\n x: round(box.x),\n y: round(box.y),\n width: round(box.width),\n height: round(box.height),\n },\n },\n score: clamp01(1 - 3 * mean),\n }\n}\n\n/** How closely the loop follows the polygon through `vertices`: 1 on it, falling with distance. */\nfunction polygonFit(\n loop: readonly Point[],\n vertices: readonly Point[],\n size: number\n): number {\n let sum = 0\n for (const p of loop) {\n let best = Infinity\n for (let i = 0; i < vertices.length; i++)\n best = Math.min(\n best,\n toSegment(p, vertices[i]!, vertices[(i + 1) % vertices.length]!)\n )\n sum += best\n }\n return clamp01(1 - (12 * sum) / loop.length / size)\n}\n\n/** Within `tolerance` radians of horizontal (0) or vertical (1); else -1. */\nfunction axisOf(a: Point, b: Point, tolerance: number): { axis: number; off: number } {\n const angle = Math.abs(Math.atan2(b.y - a.y, b.x - a.x)) % Math.PI\n const fromH = Math.min(angle, Math.PI - angle)\n const fromV = Math.abs(angle - Math.PI / 2)\n if (fromH <= tolerance) return { axis: 0, off: fromH }\n if (fromV <= tolerance) return { axis: 1, off: fromV }\n return { axis: -1, off: Math.PI / 4 }\n}\n\nfunction fitRectangle(vertices: readonly Point[], fit: number): Fit | undefined {\n if (vertices.length !== 4) return undefined\n const tolerance = (20 * Math.PI) / 180\n let worst = 0\n for (let i = 0; i < 4; i++) {\n const side = axisOf(vertices[i]!, vertices[(i + 1) % 4]!, tolerance)\n if (\n side.axis < 0 ||\n side.axis !== (axisOf(vertices[0]!, vertices[1]!, tolerance).axis + i) % 2\n )\n return undefined\n worst = Math.max(worst, side.off)\n }\n const xs = vertices.map((v) => v.x).sort((a, b) => a - b)\n const ys = vertices.map((v) => v.y).sort((a, b) => a - b)\n const left = (xs[0]! + xs[1]!) / 2\n const right = (xs[2]! + xs[3]!) / 2\n const bottom = (ys[0]! + ys[1]!) / 2\n const top = (ys[2]! + ys[3]!) / 2\n return {\n shape: {\n kind: 'rectangle',\n rect: {\n x: round(left),\n y: round(bottom),\n width: round(right - left),\n height: round(top - bottom),\n },\n },\n score: clamp01(fit - worst / tolerance / 10),\n }\n}\n\n/** The shape tool's star of `points` tips round `c`, tips at `radius`, the first at the top. */\nfunction regularStar(c: Point, points: number, radius: number): Point[] {\n const box = { x: c.x - radius, y: c.y - radius, width: 2 * radius, height: 2 * radius }\n return starVertices(box, points).map(pt)\n}\n\nconst centroid = (points: readonly Point[]): Point => ({\n x: points.reduce((s, p) => s + p.x, 0) / points.length,\n y: points.reduce((s, p) => s + p.y, 0) / points.length,\n})\n\n/** An outline star: an even number of corners alternating far from and near the centre. */\nfunction fitStar(vertices: readonly Point[], fit: number): Fit | undefined {\n const k = vertices.length\n if (k % 2 !== 0 || k < 8 || k > 16) return undefined\n const c = centroid(vertices)\n const radii = vertices.map((v) => dist(v, c))\n const even = radii.filter((_, i) => i % 2 === 0)\n const odd = radii.filter((_, i) => i % 2 === 1)\n const [outer, inner] = Math.min(...even) > Math.max(...odd) ? [even, odd] : [odd, even]\n if (Math.min(...outer) <= Math.max(...inner)) return undefined\n const mean = (xs: number[]): number => xs.reduce((s, x) => s + x, 0) / xs.length\n const ratio = mean(inner) / mean(outer)\n if (ratio > 0.75) return undefined\n // Tips spread unevenly from the centre make a sloppier star.\n const spread = (Math.max(...outer) - Math.min(...outer)) / mean(outer)\n return {\n shape: { kind: 'star', vertices: regularStar(c, k / 2, mean(outer)) },\n score: clamp01(fit - Math.max(0, spread - 0.2)),\n }\n}\n\n/** A pentagram: five straight strokes that wind twice round the centre. */\nfunction fitPentagram(\n vertices: readonly Point[],\n loop: readonly Point[],\n size: number\n): Fit | undefined {\n if (vertices.length !== 5) return undefined\n const c = centroid(vertices)\n const turns = Math.abs(winding(loop, c))\n if (turns < 1.6 || turns > 2.4) return undefined\n const radii = vertices.map((v) => dist(v, c))\n const mean = radii.reduce((s, x) => s + x, 0) / radii.length\n const spread = (Math.max(...radii) - Math.min(...radii)) / mean\n return {\n shape: { kind: 'star', vertices: regularStar(c, 5, mean) },\n score: clamp01(polygonFit(loop, vertices, size) - Math.max(0, spread - 0.2)),\n }\n}\n\n/** True when two sides of the polygon through `v` cross. */\nfunction crosses(v: readonly Point[]): boolean {\n const k = v.length\n const side = (a: Point, b: Point, c: Point): number =>\n Math.sign((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x))\n for (let i = 0; i < k; i++)\n for (let j = i + 2; j < k; j++) {\n if (i === 0 && j === k - 1) continue\n const [a, b, c, d] = [v[i]!, v[(i + 1) % k]!, v[j]!, v[(j + 1) % k]!]\n if (side(a, b, c) * side(a, b, d) < 0 && side(c, d, a) * side(c, d, b) < 0)\n return true\n }\n return false\n}\n\n/** How straight the loop runs between consecutive corners: the worst side's score. */\nfunction sidesFit(loop: readonly Point[], corners: readonly number[]): number {\n let worst = 1\n for (let k = 0; k < corners.length; k++) {\n const from = corners[k]!\n const to = corners[(k + 1) % corners.length]!\n const side =\n to > from\n ? loop.slice(from, to + 1)\n : [...loop.slice(from), ...loop.slice(0, to + 1)]\n const a = side[0]!\n const b = side[side.length - 1]!\n const bend = 1 - dist(a, b) / lengthOf(side)\n worst = Math.min(\n worst,\n clamp01(1 - SIDE_MEAN * deviation(side, a, b).mean - 2 * bend)\n )\n }\n return worst\n}\n\nfunction fitClosed(loop: readonly Point[], size: number): Fit[] {\n const box = boxOf(loop)\n const fits: Fit[] = []\n const corners = cornersOf(loop)\n const vertices = corners.map((i) => loop[i]!)\n const pentagram = fitPentagram(vertices, loop, size)\n if (pentagram) fits.push(pentagram)\n // Every other closed kind winds once round its middle.\n const turns = Math.abs(\n winding(loop, { x: box.x + box.width / 2, y: box.y + box.height / 2 })\n )\n if (turns < 0.8 || turns > 1.25) return fits\n const ellipse = fitEllipse(loop, box)\n if (ellipse) fits.push(ellipse)\n if (vertices.length < 3 || crosses(vertices)) return fits\n const fit = polygonFit(loop, vertices, size)\n const rectangle = fitRectangle(vertices, fit)\n if (rectangle) fits.push(rectangle)\n else if (vertices.length <= 8)\n fits.push({\n shape: { kind: 'polygon', vertices: vertices.map(pt) },\n score: Math.min(fit, sidesFit(loop, corners)),\n })\n const star = fitStar(vertices, fit)\n if (star) fits.push(star)\n return fits\n}\n\n/**\n * The standard shape a single freehand stroke (user space points, in drawing order) is closest\n * to, and how well it fits, from 0 to 1. Tidy the stroke only when the score reaches\n * `RECOGNISE_THRESHOLD`. Undefined when no shape fits at all.\n */\nexport function recogniseStroke(\n points: readonly Point[]\n): { shape: Recognised; score: number } | undefined {\n const clean = points.filter(\n (p, i) =>\n Number.isFinite(p.x) &&\n Number.isFinite(p.y) &&\n (i === 0 || p.x !== points[i - 1]!.x || p.y !== points[i - 1]!.y)\n )\n if (clean.length < 2) return undefined\n const size = diagonal(boxOf(clean))\n if (size === 0) return undefined\n // A long path in a small box (a scribble) would resample to thousands of points: cap them.\n const spacing = Math.max(size / DENSITY, lengthOf(clean) / 1000)\n const r = resample(clean, spacing)\n if (r.length < 2) return undefined\n const fits: Fit[] = []\n const line = fitLine(r)\n if (line) fits.push(line)\n const loop = loopOf(r, size, spacing)\n if (loop) fits.push(...fitClosed(loop, size))\n else {\n for (const f of [fitArrow(r), fitArrow([...r].reverse())]) if (f) fits.push(f)\n }\n let best: Fit | undefined\n for (const f of fits) if (!best || f.score > best.score) best = f\n return best && { shape: best.shape, score: round(best.score) }\n}\n","// Signature templates and where they live. A template is a signature drawn or typed once and\n// placed many times: ink strokes in a unit box, or an image. The host owns storage through a\n// `SignatureStore`; core ships a memory store and a localStorage one as conveniences.\n//\n// These are visual signatures, a mark on the page. Nothing here signs the file.\nimport { v7 as uuidv7 } from 'uuid'\nimport { z } from 'zod'\n\nimport { IMAGE_DATA_URL, PointSchema } from './annotations/types'\nimport { readonly, writable, type Readable } from './readable'\n\nimport type { AnnotationInput } from './annotations/types'\nimport type { Point, Rect } from './geometry'\n\n/**\n * A saved signature. Ink points lie in a unit box (0 to 1 on both axes, y growing upwards)\n * that `aspect` (width over height) stretches back to shape. An image keeps its own pixels.\n */\nexport type SignatureTemplate =\n | { id: string; kind: 'ink'; inklist: Point[][]; pressure?: number[][]; aspect: number }\n | { id: string; kind: 'image'; imagedata: string; aspect: number }\n\n/** Where templates live. The host's: a server, the browser, or memory. */\nexport interface SignatureStore {\n list(): Promise<SignatureTemplate[]>\n /** Adds the template, or replaces the one with its id. */\n save(t: SignatureTemplate): Promise<void>\n remove(id: string): Promise<void>\n}\n\n/** Options for the `signature` tool: the template a click places. */\nexport interface SignatureOptions {\n templateId?: string\n}\n\n/** How wide a placed signature is, in points. */\nexport const DEFAULT_SIGNATURE_WIDTH = 150\n\n/** A placed ink signature's stroke width, in points. */\nexport const SIGNATURE_INK_WIDTH = 2\n\nconst Aspect = z.number().positive().finite()\nconst TemplateSchema = z\n .discriminatedUnion('kind', [\n z.object({\n id: z.string().min(1),\n kind: z.literal('ink'),\n inklist: z.array(z.array(PointSchema).min(1)).min(1),\n pressure: z.array(z.array(z.number().min(0).max(1))).optional(),\n aspect: Aspect,\n }),\n z.object({\n id: z.string().min(1),\n kind: z.literal('image'),\n imagedata: z.string().regex(IMAGE_DATA_URL),\n aspect: Aspect,\n }),\n ])\n .refine(\n // Pressure must have one value per point of each stroke, or placing the template would\n // produce ink the store refuses.\n (t) =>\n t.kind !== 'ink' ||\n !t.pressure ||\n (t.pressure.length === t.inklist.length &&\n t.pressure.every((p, i) => p.length === t.inklist[i]?.length)),\n { message: 'pressure must have the same shape as inklist', path: ['pressure'] }\n )\n\n/** The items that are valid templates; the rest are skipped. */\nfunction validTemplates(items: readonly unknown[]): SignatureTemplate[] {\n return items.flatMap((item) => {\n const t = TemplateSchema.safeParse(item)\n return t.success ? [t.data as SignatureTemplate] : []\n })\n}\n\nconst copy = (t: SignatureTemplate): SignatureTemplate =>\n JSON.parse(JSON.stringify(t)) as SignatureTemplate\n\nfunction upsert(\n list: readonly SignatureTemplate[],\n t: SignatureTemplate\n): SignatureTemplate[] {\n const i = list.findIndex((x) => x.id === t.id)\n return i < 0 ? [...list, copy(t)] : list.map((x, j) => (j === i ? copy(t) : x))\n}\n\n/** Templates in memory, gone on reload. The default when a host passes no store. */\nexport function createMemorySignatureStore(\n initial: SignatureTemplate[] = []\n): SignatureStore {\n let items = initial.map(copy)\n return {\n list: () => Promise.resolve(items.map(copy)),\n save(t) {\n items = upsert(items, t)\n return Promise.resolve()\n },\n remove(id) {\n items = items.filter((x) => x.id !== id)\n return Promise.resolve()\n },\n }\n}\n\n/**\n * Templates in `localStorage` under `key`, as a JSON array. Where storage is blocked (it refuses\n * even a tiny test write, as in some private windows) the templates stay in memory for the\n * page's life, so signing still works. Where storage works, or is full but holds a saved list,\n * and has no room for a change, the change is undone and `save` or `remove` rejects, so the host can say so. Stored entries it\n * cannot read, such as a later version's templates, are left out of `list` and kept on write.\n */\nexport function createLocalSignatureStore(key: string): SignatureStore {\n /** Usable storage, or undefined when it is missing or blocked. */\n const storage = ((): Storage | undefined => {\n try {\n const s = globalThis.localStorage ?? undefined\n if (!s) return undefined\n const probe = `${key}:probe`\n try {\n s.setItem(probe, '1')\n s.removeItem(probe)\n } catch {\n // A full store refuses the probe too, but still holds the list: keep it, so the list\n // shows and saves reject. One that holds nothing of ours is treated as blocked.\n return s.getItem(key) === null ? undefined : s\n }\n return s\n } catch {\n return undefined\n }\n })()\n /** What storage holds: the templates, and the entries that are not (kept, never shown). */\n interface Stored {\n items: SignatureTemplate[]\n /** Entries this version cannot read, such as a newer version's: written back unchanged. */\n unread: unknown[]\n }\n /** The stored list; undefined when storage cannot be read. */\n const read = (): Stored | undefined => {\n if (!storage) return undefined\n try {\n const raw = storage.getItem(key)\n if (raw === null) return { items: [], unread: [] }\n const parsed: unknown = JSON.parse(raw)\n if (!Array.isArray(parsed)) return { items: [], unread: [] }\n const items = validTemplates(parsed)\n return { items, unread: parsed.filter((x) => validTemplates([x]).length === 0) }\n } catch (e) {\n // Unreadable JSON is an empty list; a storage that throws is no storage.\n return e instanceof SyntaxError ? { items: [], unread: [] } : undefined\n }\n }\n let { items, unread } = read() ?? { items: [], unread: [] }\n /** Picks up what another tab wrote. */\n const sync = (): void => {\n const stored = read()\n if (stored) ({ items, unread } = stored)\n }\n /** The id of an entry that may not be a template, if it has one. */\n const idOf = (x: unknown): unknown =>\n typeof x === 'object' && x !== null ? (x as { id?: unknown }).id : undefined\n /**\n * Writes `next`, then adopts it; leaves everything as it was when storage refuses. Entries\n * it cannot read go back after the templates, less any whose id a template now has.\n */\n const commit = (next: SignatureTemplate[]): Promise<void> => {\n const ids = new Set<unknown>(next.map((t) => t.id))\n const kept = unread.filter((x) => idOf(x) === undefined || !ids.has(idOf(x)))\n if (storage) {\n try {\n storage.setItem(key, JSON.stringify([...next, ...kept]))\n } catch (cause) {\n return Promise.reject(\n new Error('The signature could not be saved: browser storage is full', {\n cause,\n })\n )\n }\n }\n items = next\n unread = kept\n return Promise.resolve()\n }\n return {\n list() {\n sync()\n return Promise.resolve(items.map(copy))\n },\n save(t) {\n sync()\n return commit(upsert(items, t))\n },\n remove(id) {\n sync()\n return commit(items.filter((x) => x.id !== id))\n },\n }\n}\n\n/**\n * Fits strokes into a unit box, for an ink template. Points come in any y-up space; they go\n * out between 0 and 1 on both axes, and `aspect` is the box's width over its height. A flat\n * side is given 1% of the long side (a dot, a square), so the aspect stays finite, and the\n * strokes are centred across it.\n */\nexport function normaliseInk(inklist: Point[][]): { inklist: Point[][]; aspect: number } {\n const all = inklist.flat()\n const xs = all.map((p) => p.x)\n const ys = all.map((p) => p.y)\n const minX = Math.min(...xs)\n const minY = Math.min(...ys)\n const w = Math.max(...xs) - minX\n const h = Math.max(...ys) - minY\n const long = Math.max(w, h)\n const boxW = long === 0 ? 1 : Math.max(w, long * 0.01)\n const boxH = long === 0 ? 1 : Math.max(h, long * 0.01)\n const map = (p: Point): Point => ({\n x: (p.x - minX + (boxW - w) / 2) / boxW,\n y: (p.y - minY + (boxH - h) / 2) / boxH,\n })\n return { inklist: inklist.map((path) => path.map(map)), aspect: boxW / boxH }\n}\n\n/**\n * An ink template from strokes in any y-up space, with a new id. Throws a RangeError for no\n * strokes, an empty stroke, or pressure that does not have one value per point.\n */\nexport function createInkTemplate(\n inklist: Point[][],\n pressure?: number[][]\n): SignatureTemplate {\n if (inklist.length === 0 || inklist.some((path) => path.length === 0))\n throw new RangeError('A signature needs at least one stroke, and no empty strokes')\n if (\n pressure &&\n (pressure.length !== inklist.length ||\n pressure.some((p, i) => p.length !== inklist[i]!.length))\n )\n throw new RangeError('pressure must have the same shape as inklist')\n const fitted = normaliseInk(inklist)\n return {\n id: uuidv7(),\n kind: 'ink',\n inklist: fitted.inklist,\n ...(pressure ? { pressure: pressure.map((p) => [...p]) } : {}),\n aspect: fitted.aspect,\n }\n}\n\n/** An image template, with a new id. Throws a TypeError unless `imagedata` is a PNG or JPEG data URL. */\nexport function createImageTemplate(\n imagedata: string,\n aspect: number\n): SignatureTemplate {\n if (!IMAGE_DATA_URL.test(imagedata))\n throw new TypeError('A signature image must be a PNG or JPEG data URL')\n if (!(aspect > 0 && Number.isFinite(aspect)))\n throw new RangeError(`aspect must be positive, got ${aspect}`)\n return { id: uuidv7(), kind: 'image', imagedata, aspect }\n}\n\n/**\n * The annotation that places `t` on `page`, `width` points wide on screen and centred on\n * `centre` (user space). `rotation` is the page's /Rotate (clockwise): the signature is turned\n * back by as much, so it reads upright on the page as the file displays it. A viewer's view\n * rotation is left out; it turns the signature with the page like any annotation. Ink becomes `ink` with `subject: 'Signature'`, its strokes inset by half their\n * width; an image becomes a `stamp` with `subject: 'Signature'`.\n */\nexport function placeSignature(\n t: SignatureTemplate,\n page: number,\n centre: Point,\n width: number = DEFAULT_SIGNATURE_WIDTH,\n rotation: 0 | 90 | 180 | 270 = 0\n): AnnotationInput {\n const height = width / t.aspect\n const sideways = rotation === 90 || rotation === 270\n const rw = sideways ? height : width\n const rh = sideways ? width : height\n const rect: Rect = { x: centre.x - rw / 2, y: centre.y - rh / 2, width: rw, height: rh }\n if (t.kind === 'image')\n return {\n type: 'stamp',\n page,\n subject: 'Signature',\n imagedata: t.imagedata,\n rect,\n ...(rotation === 0 ? {} : { rotation }),\n }\n const pad = SIGNATURE_INK_WIDTH / 2\n const innerW = Math.max(width - pad * 2, 0)\n const innerH = Math.max(height - pad * 2, 0)\n const rad = (rotation * Math.PI) / 180\n const cos = Math.round(Math.cos(rad))\n const sin = Math.round(Math.sin(rad))\n const place = (p: Point): Point => {\n const u = (p.x - 0.5) * innerW\n const v = (p.y - 0.5) * innerH\n // Anticlockwise in user space (y up) undoes the page's clockwise turn on screen.\n return { x: centre.x + u * cos - v * sin, y: centre.y + u * sin + v * cos }\n }\n return {\n type: 'ink',\n page,\n subject: 'Signature',\n inklist: t.inklist.map((path) => path.map(place)),\n ...(t.pressure ? { pressure: t.pressure.map((p) => [...p]) } : {}),\n width: SIGNATURE_INK_WIDTH,\n rect,\n }\n}\n\n/**\n * A store's templates kept at hand, so the `signature` tool places one without waiting and the\n * signature menus share one list. Every change goes through the store first.\n */\nexport interface SignatureLibrary {\n readonly store: SignatureStore\n /** The templates as of the last load; empty until the first `refresh`. */\n readonly templates: Readable<readonly SignatureTemplate[]>\n get(id: string): SignatureTemplate | undefined\n /** Reloads from the store. A store that fails to list leaves the last list. */\n refresh(): Promise<void>\n /** Saves through the store, then reloads. Rejects when the store does. */\n save(t: SignatureTemplate): Promise<void>\n /**\n * Removes through the store, then reloads. Rejects when the store does, and then sets\n * `removeError` for the menus to show.\n */\n remove(id: string): Promise<void>\n /** Why the last removal failed; cleared by the next one, or by `clearRemoveError`. */\n readonly removeError: Readable<string | undefined>\n clearRemoveError(): void\n}\n\nexport function createSignatureLibrary(store: SignatureStore): SignatureLibrary {\n const templates = writable<readonly SignatureTemplate[]>([])\n const removeError = writable<string | undefined>(undefined)\n /**\n * The newest load that succeeded writes, so a slow one cannot undo a later save, and a later\n * one that fails does not throw away a slow success.\n */\n let loads = 0\n let applied = 0\n const refresh = async (): Promise<void> => {\n const n = ++loads\n try {\n // A host store may hand back anything: an invalid template would fail when placed.\n const list = validTemplates(await store.list())\n if (n > applied) {\n applied = n\n templates.set(list)\n }\n } catch {\n // The store is unavailable: keep what was there.\n }\n }\n return {\n store,\n templates: readonly(templates),\n get: (id) => templates.get().find((t) => t.id === id),\n refresh,\n async save(t) {\n await store.save(t)\n await refresh()\n },\n async remove(id) {\n removeError.set(undefined)\n try {\n await store.remove(id)\n } catch (e) {\n removeError.set('The signature could not be removed. Try again.')\n throw e\n }\n await refresh()\n },\n removeError: readonly(removeError),\n clearRemoveError: () => removeError.set(undefined),\n }\n}\n"],"mappings":"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"}
|