@laminapdf/viewer 0.2.0-alpha.3 → 0.2.0-alpha.4

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.
Files changed (112) hide show
  1. package/README.md +71 -5
  2. package/dist/client.d.ts +48 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +89 -29
  5. package/dist/client.js.map +1 -1
  6. package/dist/find/controller.d.ts +73 -0
  7. package/dist/find/controller.d.ts.map +1 -0
  8. package/dist/find/controller.js +227 -0
  9. package/dist/find/controller.js.map +1 -0
  10. package/dist/find/fold.d.ts +23 -0
  11. package/dist/find/fold.d.ts.map +1 -0
  12. package/dist/find/fold.js +99 -0
  13. package/dist/find/fold.js.map +1 -0
  14. package/dist/find/page.d.ts +44 -0
  15. package/dist/find/page.d.ts.map +1 -0
  16. package/dist/find/page.js +173 -0
  17. package/dist/find/page.js.map +1 -0
  18. package/dist/index.d.ts +7 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +2 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/layers/box.d.ts +10 -0
  23. package/dist/layers/box.d.ts.map +1 -0
  24. package/dist/layers/box.js +19 -0
  25. package/dist/layers/box.js.map +1 -0
  26. package/dist/layers/highlight-layer.d.ts +31 -0
  27. package/dist/layers/highlight-layer.d.ts.map +1 -0
  28. package/dist/layers/highlight-layer.js +95 -0
  29. package/dist/layers/highlight-layer.js.map +1 -0
  30. package/dist/layers/spans.d.ts +42 -0
  31. package/dist/layers/spans.d.ts.map +1 -0
  32. package/dist/layers/spans.js +121 -0
  33. package/dist/layers/spans.js.map +1 -0
  34. package/dist/layers/structure-layer.d.ts +15 -0
  35. package/dist/layers/structure-layer.d.ts.map +1 -0
  36. package/dist/layers/structure-layer.js +152 -0
  37. package/dist/layers/structure-layer.js.map +1 -0
  38. package/dist/layers/text-layer.d.ts +53 -0
  39. package/dist/layers/text-layer.d.ts.map +1 -0
  40. package/dist/layers/text-layer.js +292 -0
  41. package/dist/layers/text-layer.js.map +1 -0
  42. package/dist/layout/range.d.ts +3 -0
  43. package/dist/layout/range.d.ts.map +1 -0
  44. package/dist/layout/range.js +5 -0
  45. package/dist/layout/range.js.map +1 -0
  46. package/dist/network/watch.d.ts +30 -0
  47. package/dist/network/watch.d.ts.map +1 -0
  48. package/dist/network/watch.js +181 -0
  49. package/dist/network/watch.js.map +1 -0
  50. package/dist/protocol.d.ts +115 -2
  51. package/dist/protocol.d.ts.map +1 -1
  52. package/dist/protocol.js.map +1 -1
  53. package/dist/render/tiles.d.ts +43 -3
  54. package/dist/render/tiles.d.ts.map +1 -1
  55. package/dist/render/tiles.js +62 -10
  56. package/dist/render/tiles.js.map +1 -1
  57. package/dist/source/http-range.d.ts +59 -0
  58. package/dist/source/http-range.d.ts.map +1 -0
  59. package/dist/source/http-range.js +284 -0
  60. package/dist/source/http-range.js.map +1 -0
  61. package/dist/thumbnails/strip.d.ts +37 -0
  62. package/dist/thumbnails/strip.d.ts.map +1 -0
  63. package/dist/thumbnails/strip.js +313 -0
  64. package/dist/thumbnails/strip.js.map +1 -0
  65. package/dist/view/budgets.d.ts +29 -0
  66. package/dist/view/budgets.d.ts.map +1 -0
  67. package/dist/view/budgets.js +63 -0
  68. package/dist/view/budgets.js.map +1 -0
  69. package/dist/view/touch.d.ts +71 -0
  70. package/dist/view/touch.d.ts.map +1 -0
  71. package/dist/view/touch.js +220 -0
  72. package/dist/view/touch.js.map +1 -0
  73. package/dist/view/viewer.d.ts +42 -1
  74. package/dist/view/viewer.d.ts.map +1 -1
  75. package/dist/view/viewer.js +425 -68
  76. package/dist/view/viewer.js.map +1 -1
  77. package/dist/worker/document.d.ts +30 -0
  78. package/dist/worker/document.d.ts.map +1 -1
  79. package/dist/worker/document.js +176 -24
  80. package/dist/worker/document.js.map +1 -1
  81. package/dist/worker/entry.d.ts +1 -1
  82. package/dist/worker/entry.d.ts.map +1 -1
  83. package/dist/worker/entry.js +2 -0
  84. package/dist/worker/entry.js.map +1 -1
  85. package/dist/worker/find.d.ts +7 -0
  86. package/dist/worker/find.d.ts.map +1 -0
  87. package/dist/worker/find.js +59 -0
  88. package/dist/worker/find.js.map +1 -0
  89. package/dist/worker/methods.d.ts.map +1 -1
  90. package/dist/worker/methods.js +28 -2
  91. package/dist/worker/methods.js.map +1 -1
  92. package/dist/worker/navigation.d.ts +6 -0
  93. package/dist/worker/navigation.d.ts.map +1 -0
  94. package/dist/worker/navigation.js +16 -0
  95. package/dist/worker/navigation.js.map +1 -0
  96. package/dist/worker/network.d.ts +4 -0
  97. package/dist/worker/network.d.ts.map +1 -0
  98. package/dist/worker/network.js +24 -0
  99. package/dist/worker/network.js.map +1 -0
  100. package/dist/worker/render.d.ts +5 -2
  101. package/dist/worker/render.d.ts.map +1 -1
  102. package/dist/worker/render.js +13 -6
  103. package/dist/worker/render.js.map +1 -1
  104. package/dist/worker/text.d.ts +17 -0
  105. package/dist/worker/text.d.ts.map +1 -0
  106. package/dist/worker/text.js +75 -0
  107. package/dist/worker/text.js.map +1 -0
  108. package/dist/zoom/destination.d.ts +18 -0
  109. package/dist/zoom/destination.d.ts.map +1 -0
  110. package/dist/zoom/destination.js +56 -0
  111. package/dist/zoom/destination.js.map +1 -0
  112. package/package.json +5 -5
package/README.md CHANGED
@@ -24,25 +24,65 @@ The view keeps only the pages near the viewport in the DOM and paints each in tw
24
24
 
25
25
  - **Layout.** Every page's size comes from its displayed size in points, the zoom and the view rotation. The pages stack in one column with a gap. The offsets are prefix sums, so finding the page at a scroll position is a binary search, and a zoom change costs one pass over the pages (`PageLayout`).
26
26
  - **Virtualisation.** The viewer mounts a shell for each page in view, plus a margin of 2 pages or one viewport each side, whichever is larger. A shell that leaves the margin aborts its renders. If a result still arrives for that page, the viewer drops it and never draws it. Scroll handling reads the DOM first and writes it once per animation frame.
27
- - **Canvases.** A shell borrows its canvas from a pool of 12, which caps the canvases' total size at 64 million device pixels (`CanvasPool`). Safari fails past an undocumented total canvas area, so the pool shrinks a canvas rather than exceed the cap. Rendered bitmaps stay in a 256 MB cache, which closes the bitmaps farthest from the current page first (`BitmapCache`).
27
+ - **Canvases.** A shell borrows its canvas from a pool of 12, which caps the canvases' total size at 40 million device pixels (`CanvasPool`). Safari fails past an undocumented total canvas area, so the pool shrinks a canvas rather than exceed the cap.
28
+ - **Detail canvases.** A page's canvas holds at most 8 million pixels (`BACKDROP_MAX_PIXELS`, below Safari's limit for one canvas). A page larger than that at the full pixel ratio, or one whose canvas the pool shrank, keeps its canvas as a backdrop. A detail canvas then covers the part in view at the full ratio. The detail canvas's size follows the viewport, not the zoom, so the page in view is sharp at every zoom up to 800 %.
29
+ - **Detail pool.** Detail canvases come from a second pool of 3 canvases and 24 million pixels. Together with the page pool, that is the 64 million pixels one pool held before. A page out of view gives its detail canvas back. When none is free, a page shows its backdrop until one is.
30
+ - **Bitmaps.** Rendered bitmaps stay in a 256 MB cache, which closes the bitmaps farthest from the current page first (`BitmapCache`).
28
31
  - **Progressive rendering.** A page first paints a blurry whole-page pass, at most 256 pixels wide, at `visible` priority. Then it paints sharp tiles, 512 CSS px × the device pixel ratio on a side, over the part in view. Pages in the margin get only the blurry pass, at `prefetch` priority. A canvas is resized only when the new pixels are ready, so the page never flashes white.
29
- - **Zoom.** The modes are fit width, fit page, actual size (96 CSS px per inch) and 10–800 %. Zoom comes from ctrl/cmd+wheel, trackpad pinch (ctrl+wheel, or Safari's gesture events), touch pinch and the `+`, `-` and `0` keys. The document point under the cursor stays where it is: always vertically, and horizontally while the pages are wider than the viewport. Narrower pages are centred, so no horizontal scroll can keep it there. During a gesture the canvases stretch, and the sharp re-render waits until the gesture pauses for 150 ms.
32
+ - **Zoom.** The modes are fit width, fit page, actual size (96 CSS px per inch) and 10–800 %. Zoom comes from ctrl/cmd+wheel, trackpad pinch (ctrl+wheel, or Safari's gesture events), touch (below) and the `+`, `-` and `0` keys. The document point under the cursor stays where it is: always vertically, and horizontally while the pages are wider than the viewport. Narrower pages are centred, so no horizontal scroll can keep it there. During a gesture the canvases stretch, and the sharp re-render waits until the gesture pauses for 150 ms.
33
+ - **Touch.** The viewer handles touch itself, and its root has `touch-action: none`, so the browser's page zoom never fights it. The browser still zooms the rest of the page, so accessibility zoom keeps working. A pen pans like a finger until a mode draws with it; the mouse stays the browser's.
34
+ - **Gestures.** One finger pans once it moves 10 px, and a flick carries the page on as it slows. Two fingers pinch: the document point that started under them stays under them, even when they also move together. At fit width a double tap zooms in; at any other zoom it returns to fit width. A finger held still for half a second is left to the browser, so a long press still selects text.
35
+ - **Canvas size on touch devices.** A phone or tablet can't hold the desktop's canvases: iOS Safari reloads a tab whose canvases pass 224–384 MB in all. With a coarse pointer, every canvas holds at most 5 million pixels; on a tablet whose window covers more than 5 million device pixels, the page in view shows its backdrop rather than a detail canvas.
36
+ - **Memory on touch devices.** The two pools and the bitmap cache together stay under 184 MB by default. On a device that reports 2 GB of memory or less (`navigator.deviceMemory`, in Chromium) the limit is 116 MB, and on one that reports 4 GB or more, 304 MB. `createViewer`'s options override each budget, and `device` gives the hints the budgets are chosen from instead of detecting them.
30
37
  - **Tall documents.** A document taller than 16 million CSS px at the chosen zoom gets its zoom capped, because browsers stop scrolling near that height.
31
38
 
32
39
  **API.**
33
40
 
34
41
  | Member | What it does |
35
42
  | --- | --- |
36
- | `createViewer({ client, margin?, gap?, pool?, cacheBytes?, settleMs?, zoom? })` | Makes a viewer over a `ViewerClient`. |
43
+ | `createViewer({ client, margin?, gap?, pool?, detailPool?, cacheBytes?, backdropMaxPixels?, canvasMaxPixels?, device?, settleMs?, zoom?, text? })` | Makes a viewer over a `ViewerClient`. `text` is on by default; `false` leaves the text layer out, and an object sets its `outline`, `untaggedLabel` and `onSelection`. |
37
44
  | `mount(container)`, `open(document)`, `destroy()` | Puts it on the page, shows a document, takes it down. |
38
45
  | `goToPage(index, { anchor })`, `setZoom(zoom, { anchor })`, `rotate(delta)` | Navigation. `zoom` is a mode or a percentage. |
46
+ | `goToDestination(target)` | Goes to an outline item's or a named destination's target (below). |
39
47
  | `getState()`, `subscribe(listener)` | The view state (`currentPage`, `pageCount`, `zoom`, `percent`, `rotation`, `scrollTop`, `visibleRange`), for `useSyncExternalStore`. |
40
48
  | `on("pagechange" \| "zoomchange" \| "renderstats", …)`, `stats()` | Events and counters. `renderstats` counts renders, for measuring performance. |
41
49
  | `addLayer({ name, onMount, onUnmount, onZoom })` | Mounts a layer into each page. |
50
+ | `keepMounted(pages)` | Keeps these pages mounted wherever the view scrolls, replacing the previous set; `[]` releases them. The text layer pins the pages a selection touches. |
42
51
  | `pointAt(x, y)`, `positionOf(point)` | Converts between viewport positions and document points. |
43
52
  | `MIN_ZOOM`, `MAX_ZOOM` | The bounds of a percentage zoom, 10 and 800, for a zoom control's range. |
44
53
 
45
- **Layers.** Each page shell stacks a canvas and three slots above it: `div.lamina-layer-text`, `div.lamina-layer-annot` and `div.lamina-layer-highlight`. The coming text layer, find highlights and links will mount there through `addLayer`. A layer with another name gets its own slot on top.
54
+ **Layers.** Each page shell stacks a canvas and three slots above it: `div.lamina-layer-text`, `div.lamina-layer-annot` and `div.lamina-layer-highlight`. The text layer fills the first; find's highlights mount in `highlight`, and links will mount in `annot`, through `addLayer`. A layer with another name gets its own slot on top. Every slot above the text lets the pointer through (`pointer-events: none`), so text stays selectable under it; an element a layer wants clicked, such as a link, sets `pointer-events: auto` on itself.
55
+
56
+ **Text.** The text layer makes every page's text selectable, copyable and readable by screen readers, whichever backend draws the page.
57
+ - **Spans.** Each text run of Lamina PDF's extraction gets one transparent span, placed from its glyphs' quads, never from the renderer's. A rotated or vertical run gets a rotated span, and a span reads right to left when its first letter does. The spans sit in a box sized in points, which one CSS transform scales and turns to the page, so a zoom or a rotation moves no span.
58
+ - **Selection.** Selection stays inside the viewer, and only spans are selectable. A drag runs from one page into the next and never takes in a canvas or a gap. The pages a selection touches stay mounted while it lasts. Ctrl/⌘+A in the viewer selects the text of the mounted pages only.
59
+ - **Copy** writes the extracted text in reading order: a space at a gap, a new line at a new baseline and between pages, soft hyphens dropped. `onSelection` gives the app the selected text, its rects, its pages and the pointer that made it.
60
+ - **Structure.** For a tagged document, a hidden tree of ARIA elements follows the structure tree. Headings carry their levels, and figures their alternate text; paragraphs, lists and tables keep their roles. Each element owns its text spans through `aria-owns`, matched by page and marked-content ID (the number a tagged PDF gives each piece of a page's content), so a screen reader reads the document in structure order. For a document without a structure tree, a screen reader hears "Untagged document" once (`untaggedLabel`).
61
+
62
+ The document Web Worker reads each page's text at `background` priority, after the tiles in view, and caches the text of the last 24 pages. Text needs the extract module, which the document Web Worker loads once the render backend is ready, so the first page never waits for it. Selection colours are the app's: style `.lamina-text-layer span::selection`, since the viewer adds no style sheet.
63
+
64
+ **Find.** `viewer.find` searches the whole document and highlights what it finds.
65
+ - **How it searches.** `find(query, { matchCase, wholeWords, matchDiacritics })` starts from the current page, reaches the last page and wraps to the first. The document Web Worker searches four pages per call, at `background` priority, so the pages in view render first and scrolling never waits. It keeps each page's searchable text in a cache of its own, up to 32 MB, so the next query, such as one you typed more letters into, searches the pages it has already read without reading their text again.
66
+ - **What it compares.** Find normalises text the way pdf.js does, so the counts match: ligatures unfolded, soft hyphens dropped, a word split by a hyphen at a line's end joined, white space collapsed. Case and diacritics are ignored unless asked, and diacritics are every combining mark: Latin accents, Hebrew points, Arabic harakat, Indic vowel signs. Whole words means no letter or digit runs on at either end.
67
+ - **Results.** Matches stream in by page: `getState()` gives `total`, `current`, `searched`, `pagesWithoutText` and `done` as matches arrive. The first match on or after the current page shows as soon as it's found. `next()` and `previous()` move in document order and wrap, scrolling a match to the viewport's centre when it's out of view.
68
+ - **The list of results.** `results()` lists every match found so far in document order, each with its `ordinal`, its `page` and a `snippet` of `{ before, match, after }`. The snippet keeps up to about 40 characters of the page's text on each side, cut at a word, with the match as the page spells it. `goTo(ordinal)` makes one current and scrolls it into view, and `next()` and `previous()` go on from there. The list is the same array until find's state next changes, so a React component can read it on each render.
69
+ - **Cancelling.** A new query, or `close()`, stops the search under way; its late results never show.
70
+ - **Highlights.** Every match on a mounted page gets a box with the class `lamina-find-match` in the `highlight` slot; the current match also has `lamina-find-current`. Colour them with `--lamina-find-match` and `--lamina-find-current`; the current one also has an outline, `--lamina-find-current-outline`, so it never differs by colour alone. The boxes take no pointer events, so they never get in a selection's way.
71
+
72
+ **Destinations.** `ViewerClient.outline()` reads the document's outline in the document Web Worker, and `namedDestination(name)` finds one named destination. Each item's target is a page and a view in page space: points from the displayed page's top-left, y down, whichever coordinates the file used. `goToDestination(target)` follows the target's view (ISO 32000-2 §12.3.2.2). It applies the target's zoom, if it has one, and then puts the target's point at the viewport's top-left:
73
+ - **A point** (`at`, from `/XYZ`) at its zoom, or at the current zoom when the file gives none.
74
+ - **Fit the page** (`fit`, from `/Fit` and `/FitB`).
75
+ - **Fit the width** from a top (`fit-width`, from `/FitH` and `/FitBH`), or the height from a left (`fit-height`, from `/FitV` and `/FitBV`).
76
+ - **Fit a rectangle** (`fit-rect`, from `/FitR`).
77
+
78
+ A left the file leaves out keeps the current horizontal scroll, and a top it leaves out goes to the page's top. A view rotated by `rotate()` turns the point with the page, and a fit always fits the viewport's own width or height, as in pdf.js.
79
+
80
+ **Thumbnails.** `new ThumbnailStrip(client, viewer, { width?, margin?, cacheBytes?, label?, name? })` makes a list of the pages as small pictures, for a sidebar. `mount(container)` puts it on the page, and `open(document)` shows the document the viewer opened. Size its `element` with CSS; it scrolls inside.
81
+ - **Like the viewer, it mounts only what is near its view.** It keeps the thumbnails in view and 4 either side. Each borrows a canvas from the strip's own pool, and a thumbnail scrolled away aborts its render.
82
+ - **Renders wait for the main view.** Thumbnails render at `background` priority, so the pages in view always come first. Bitmaps stay in a cache of their own, 32 MB by default.
83
+ - **It follows the viewer.** The current page is marked `aria-selected` and scrolled into the strip; a rotation turns every thumbnail.
84
+ - **Keyboard and pointer.** A click, or Enter or Space, goes to that page. The arrow keys, Home and End move the focus, and only one thumbnail is in the Tab order.
85
+ - **Names.** Each thumbnail is named by its page label and number ("Page iv (4 of 120)") and captioned with its label. For another language, pass `label` to replace both and `name` to replace the list's own name.
46
86
 
47
87
  **Tuning.** The margin, pool size, pixel cap, cache budget and settle delay are measured by the perf harness ([Performance](#performance)); the first full run kept them.
48
88
 
@@ -55,7 +95,11 @@ The client starts the Web Worker and talks to it; you call `ViewerClient`'s meth
55
95
  | Event | Source | Data | Meaning |
56
96
  | --- | --- | --- | --- |
57
97
  | `warning` | Web Worker | a reader warning | for example, a repaired xref |
98
+ | `progress` | Web Worker | `{ loaded, total }` | bytes of a remote document read so far, and its size |
58
99
  | `render-start` | Web Worker | `{ page, scale }` | a render began, for measuring performance |
100
+ | `render-fetching` | Web Worker | `{ key }` | a remote document's render stopped to fetch bytes; `render-start` follows |
101
+ | `network` | Web Worker | `{ worker, index, record }` | the Web Worker made a network request (`NetworkRecord`: URL, method, what made it, bytes, failed) |
102
+ | `csp-violation` | Web Worker | `{ worker, index, violation }` | the Web Worker's Content Security Policy blocked a request |
59
103
  | `render-slow` | page | `{ id, page }` | the soft timeout passed, counted from `render-start`: waiting in the queue isn't slow |
60
104
  | `render-stuck` | page | `{ id, page, needsPassword }` | an encrypted document's render passed the hard cap |
61
105
  | `crashed` | page | `{ reason }` | the Web Worker crashed |
@@ -63,6 +107,8 @@ The client starts the Web Worker and talks to it; you call `ViewerClient`'s meth
63
107
  | `password-required` | page | — | the new Web Worker can't reopen without the password |
64
108
  | `restart-failed` | page | `{ reason, error }` | a restart failed (for example, the backend wouldn't load again) |
65
109
 
110
+ **Network requests:** the Web Worker counts every request it makes from the moment it starts, with `watchNetwork`, which this package also exports for the page. The function wraps `fetch`, `XMLHttpRequest`, `WebSocket` and `sendBeacon`, and reads everything else from Resource Timing, so a reader can show what left the device.
111
+
66
112
  ### How it behaves
67
113
 
68
114
  - **Priorities and coalescing:** the Web Worker runs one call at a time, the highest priority first, FIFO within one.
@@ -85,10 +131,16 @@ The client starts the Web Worker and talks to it; you call `ViewerClient`'s meth
85
131
  - **Sources:**
86
132
  - A `Blob`/`File` is sent by reference, and the Web Worker reads it in 4 MiB `slice()`s.
87
133
  - Bytes are copied, and kept on the page for a reopen.
134
+ - `{ url }` is a remote file the Web Worker fetches itself, so its bytes never reach the page:
135
+ - It reads the file with HTTP Range requests through `@laminapdf/sdk`'s `httpRangeSource`, in 64 KiB blocks with one block read ahead, and keeps up to 64 MiB of them.
136
+ - Lamina PDF opens the file range by range, and a render that needs bytes not yet read fetches them and draws again, so page 1 of a large file needs only a small part of it.
137
+ - While a render fetches, it emits `render-fetching` and its timeouts pause until it draws again (`render-start`): a slow network is never a stuck render. The Web Worker still runs one call at a time, so other calls wait for that fetch.
138
+ - Requests send no cookies or referrer and skip the HTTP cache.
139
+ - A server that ignores `Range` sends the whole file, which the Web Worker accepts up to 256 MiB (`source-budget-exceeded` above that).
88
140
 
89
141
  ## For contributors
90
142
 
91
- The viewer is the web client of [ADR 0009](../../docs/decisions/0009-web-client-architecture.md); it was built in [C3a](../../docs/todos/done/C3a-viewer-worker-rpc.md) (the document worker and its typed RPC) and [C3b](../../docs/todos/done/C3b-viewer-virtualiser-and-zoom.md) (the viewer). [C3c](../../docs/todos/done/C3c-viewer-perf-harness.md) measures the tuning values with `renderstats`. The layers are for [C5a](../../docs/todos/ready/C5a-text-layer-and-selection.md) (text), [C5b](../../docs/todos/ready/C5b-find-in-document.md) (find) and [C6b](../../docs/todos/ready/C6b-links-and-history.md) (links); C4c will read documents by range through `@laminapdf/sdk`'s `RangeSource`. Cancellation follows ADR 0009 §3.5, and warnings are [ADR 0003](../../docs/decisions/0003-reader-tolerance-and-limits.md)'s.
143
+ The viewer is the web client of [ADR 0009](../../docs/decisions/0009-web-client-architecture.md); it was built in [C3a](../../docs/todos/done/C3a-viewer-worker-rpc.md) (the document worker and its typed RPC) and [C3b](../../docs/todos/done/C3b-viewer-virtualiser-and-zoom.md) (the viewer). [C3c](../../docs/todos/done/C3c-viewer-perf-harness.md) measures the tuning values with `renderstats`. The layers are for [C5a](../../docs/todos/done/C5a-text-layer-and-selection.md) (text), [C5b](../../docs/todos/done/C5b-find-in-document.md) (find) and [C6b](../../docs/todos/ready/C6b-links-and-history.md) (links); C4c will read documents by range through `@laminapdf/sdk`'s `RangeSource`. Cancellation follows ADR 0009 §3.5, and warnings are [ADR 0003](../../docs/decisions/0003-reader-tolerance-and-limits.md)'s.
92
144
 
93
145
  ### Architecture
94
146
 
@@ -116,8 +168,14 @@ There is one protocol, not two: the viewer's worker is `@laminapdf/sdk/worker`'s
116
168
  | `openDocument` | `source` (`Blob`, `ArrayBuffer`, `Uint8Array`), `{ password?, limits?, renderLimits? }` | `{ pageCount, pages, needsPassword, backend }` | document |
117
169
  | `closeDocument` | — | — | document |
118
170
  | `pageInfo` | `index` | `PageInfo` (displayed size in points, rotation, ID, label) | document |
171
+ | `find` | `query`, `FindOptions`, `pages` | `FindPageResult[]`: each page's matches as quads, and whether it has no text | `background` |
119
172
  | `render` | ADR 0004 `RenderRequest` | `{ bitmap: ImageBitmap, width, height }` (transferred) | `visible` > `prefetch` > `background` |
120
173
  | `memory` | — | `WorkerMemory`: the bytes of the backend's and Lamina PDF's WebAssembly memories | document. `client.memory()`; the perf harness samples it. |
174
+ | `pageText` | `index` | `PageTextData`: the page's runs and glyph quads | `background` |
175
+ | `structure` | — | `StructureData`: whether the document is tagged, and its structure tree | document |
176
+ | `outline` | — | `OutlineNode[]`: the outline, each item's target in page space | document |
177
+ | `namedDestination` | `name` | `Target \| undefined` | document |
178
+ | `networkLog` | — | `WorkerNetworkLog`: every request and blocked request since the Web Worker started | document. `client.networkLog()`: what the `network` and `csp-violation` events reported, those sent before anyone listened included; `index` merges the two. |
121
179
 
122
180
  `client.call(method, params, { priority, signal })` is typed by the `Methods` map: an unknown method or wrong params fails `tsc` (`test/types.test.ts`).
123
181
 
@@ -140,7 +198,15 @@ The browser suites run in Chromium, Firefox and WebKit over the built package: r
140
198
  - slow, stuck and stopped renders;
141
199
  - crashes, including an encrypted file;
142
200
  - the password count.
201
+ - `test/find-parity.test.ts` (Node) checks find's counts against pdf.js's find controller on every case of `fixtures/text/search.json`.
143
202
  - Unit tests sit next to their modules (`src/**/*.test.ts`) and run in Node. They cover the layout's cost, counted in steps, and the fit modes for portrait, landscape and rotated pages. They also cover zoom anchoring, tiles, cache eviction and the pool's caps. `test/dependencies.test.ts` checks that `src/` imports no UI framework, and `test/types.test.ts` checks the RPC types.
203
+ - `test/browser/navigation.browser.test.ts` covers the thumbnails strip over a 1,000-page document:
204
+ - while the whole strip scrolls, no more than the thumbnails in view and 4 either side mounted;
205
+ - a visible render, queued behind thumbnails, running first;
206
+ - a click and the keyboard going to a page;
207
+ - page labels in the names;
208
+ - the outline and a named destination of the links-and-outlines reference PDF landing on their pages.
209
+ - Unit tests sit next to their modules (`src/**/*.test.ts`) and run in Node. They cover the layout's cost, counted in steps, and the fit modes for portrait, landscape and rotated pages. They also cover zoom anchoring, tiles, cache eviction and the pool's caps, and where each kind of destination puts the view at each rotation. `test/dependencies.test.ts` checks that `src/` imports no UI framework, and `test/types.test.ts` checks the RPC types.
144
210
  - Two demo pages are manual checks: run `pnpm --filter @laminapdf/viewer exec vite examples`. `examples/viewer-demo.html` is the viewer, with zoom buttons; `examples/rpc-demo.html` draws page 1 through the RPC alone. The perf harness has its own page, `perf/page/` ([Performance](#performance)).
145
211
 
146
212
  ### Performance
package/dist/client.d.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  import type { RenderRequest } from "@laminapdf/render";
2
2
  import { type WorkerInitOptions, type WorkerWasmSource } from "@laminapdf/sdk/worker";
3
- import { type BackendInit, type MethodName, type OpenedDocument, type Params, type Priority, type RenderedBitmap, type Result, type SourceInit, type ViewerOpenOptions } from "./protocol.js";
3
+ import type { FindOptions } from "./find/fold.js";
4
+ import { type BackendInit, type LoadProgress, type MethodName, type NetworkRecord, type OpenedDocument, type Params, type PolicyViolation, type Priority, type RenderedBitmap, type Result, type SourceInit, type ViewerOpenOptions, type WorkerNetworkLog } from "./protocol.js";
4
5
  /** `ViewerClient.create`'s options: the backend, Lamina PDF's WebAssembly, the timeouts, the worker and a signal to stop starting. */
5
6
  export interface ViewerOptions {
6
7
  /** The render engine; PDFium needs its `.wasm` URL from your bundler (`pdfium.wasm?url`). */
7
8
  readonly backend: BackendInit;
8
- /** Where the worker loads Lamina PDF's own WebAssembly from (`@laminapdf/sdk/worker`'s `init`). */
9
+ /**
10
+ * Where the worker loads Lamina PDF's own WebAssembly from (`@laminapdf/sdk/worker`'s `init`).
11
+ * The worker loads the extract module itself, for the text layer, once the backend is ready.
12
+ */
9
13
  readonly lamina?: WorkerWasmSource | WorkerInitOptions;
10
14
  /** Render timeouts in ms (`soft` emits `render-slow`; `hard` restarts or emits `render-stuck`). */
11
15
  readonly timeouts?: {
@@ -26,12 +30,30 @@ export interface ViewerEvents {
26
30
  readonly code: string;
27
31
  readonly message: string;
28
32
  };
33
+ /** How much of a remote document the worker has fetched (bytes; the size). */
34
+ progress: LoadProgress;
29
35
  /** The worker started drawing a render (so a performance test can see what the worker is busy with). */
30
36
  "render-start": {
31
37
  readonly page: number;
32
38
  readonly scale: number;
33
39
  readonly key: string;
34
40
  };
41
+ /** A remote document's render stopped drawing to fetch bytes it needs; `render-start` follows when it draws again. */
42
+ "render-fetching": {
43
+ readonly key: string;
44
+ };
45
+ /** The document worker made a network request (`worker` names the worker, so a restart's records stay apart). */
46
+ network: {
47
+ readonly worker: string;
48
+ readonly index: number;
49
+ readonly record: NetworkRecord;
50
+ };
51
+ /** The worker's Content Security Policy blocked a request it tried. */
52
+ "csp-violation": {
53
+ readonly worker: string;
54
+ readonly index: number;
55
+ readonly violation: PolicyViolation;
56
+ };
35
57
  /** A render passed the soft timeout: offer Stop. */
36
58
  "render-slow": {
37
59
  readonly id: number;
@@ -93,10 +115,34 @@ export declare class ViewerClient {
93
115
  get document(): OpenedDocument | undefined;
94
116
  /** Closes the document in the worker (the worker stays, ready for another `open`). */
95
117
  close(): Promise<void>;
118
+ /**
119
+ * Every request the document worker has made, and had blocked, since it started: what its
120
+ * `network` and `csp-violation` events reported, including those sent before anyone listened.
121
+ */
122
+ networkLog(options?: ViewerCallOptions): Promise<WorkerNetworkLog>;
96
123
  /** The worker's WebAssembly memory in bytes (see `WorkerMemory`), for measuring. */
97
124
  memory(options?: ViewerCallOptions): Promise<import("./protocol.js").WorkerMemory>;
98
125
  /** Page `index`'s size, rotation, ID and label. */
99
126
  pageInfo(index: number, options?: ViewerCallOptions): Promise<import("@laminapdf/wasm/text").PageInfoJs>;
127
+ /**
128
+ * Page `index`'s text runs and glyph quads, read by Lamina PDF (needs the extract or text
129
+ * module, loaded by default). At `background` priority unless `options` says otherwise.
130
+ */
131
+ pageText(index: number, options?: ViewerCallOptions): Promise<import("./protocol.js").PageTextData>;
132
+ /**
133
+ * The matches of `query` on each of `pages`, at `background` priority unless `options` says
134
+ * otherwise, so renders run first. The find controller calls it a few pages at a time.
135
+ */
136
+ find(query: string, find: FindOptions, pages: readonly number[], options?: ViewerCallOptions): Promise<import("./protocol.js").FindPageResult[]>;
137
+ /** Whether the open document says it is tagged, and its structure tree when it has one. */
138
+ structure(options?: ViewerCallOptions): Promise<import("./protocol.js").StructureData>;
139
+ /**
140
+ * The open document's outline (bookmarks): top-level items, each with its children and where
141
+ * it goes as a page and a page-space view; empty without one. Read when first asked for.
142
+ */
143
+ outline(options?: ViewerCallOptions): Promise<import("@laminapdf/wasm/text").OutlineNodeJs[]>;
144
+ /** Where the named destination `name` goes, or `undefined` when the document has no such name. */
145
+ namedDestination(name: string, options?: ViewerCallOptions): Promise<import("@laminapdf/wasm/text").TargetJs | undefined>;
100
146
  /**
101
147
  * Renders `request` as an ImageBitmap (close it when done). Identical requests in flight are
102
148
  * drawn once. An aborted render rejects with `AbortError` and never paints.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -36,31 +36,47 @@ export class ViewerClient {
36
36
  #document;
37
37
  #recovering;
38
38
  #nextRender = 1;
39
- /** Renders waiting to start, by coalescing key: their timers start on `render-start`. */
40
- #waiting = new Map();
39
+ /** Each pending render's timers, by coalescing key: started on `render-start`, paused on `render-fetching`. */
40
+ #timers = new Map();
41
41
  /** The key the worker is drawing now: a render that joins it starts its timers at once. */
42
42
  #drawing;
43
43
  constructor(pdf, options) {
44
44
  this.#pdf = pdf;
45
45
  this.#backend = options.backend;
46
46
  this.#timeouts = { ...DEFAULT_TIMEOUTS, ...options.timeouts };
47
- pdf.on("event", (name, data) => {
48
- if (name === "warning")
49
- this.#events.emit("warning", data);
50
- else if (name === "render-start") {
51
- const started = data;
52
- this.#drawing = started.key;
53
- for (const start of this.#waiting.get(started.key) ?? [])
54
- start();
55
- this.#waiting.delete(started.key);
56
- this.#events.emit("render-start", started);
57
- }
58
- });
47
+ pdf.on("event", (name, data) => this.#onEvent(name, data));
59
48
  pdf.on("crashed", (reason) => {
60
49
  this.#events.emit("crashed", { reason });
61
50
  this.#recover(reason).catch((error) => this.#events.emit("restart-failed", { reason: reason, error }));
62
51
  });
63
52
  }
53
+ /** A worker event: forwarded, and for renders, their timers started or paused. */
54
+ #onEvent(name, data) {
55
+ if (name === "warning")
56
+ this.#events.emit("warning", data);
57
+ else if (name === "progress")
58
+ this.#events.emit("progress", data);
59
+ else if (name === "network")
60
+ this.#events.emit("network", data);
61
+ else if (name === "csp-violation")
62
+ this.#events.emit("csp-violation", data);
63
+ else if (name === "render-start") {
64
+ const started = data;
65
+ this.#drawing = started.key;
66
+ for (const timers of this.#timers.get(started.key) ?? [])
67
+ timers.start();
68
+ this.#events.emit("render-start", started);
69
+ }
70
+ else if (name === "render-fetching") {
71
+ // Fetching isn't drawing: a slow network must not count as a stuck render.
72
+ const { key } = data;
73
+ if (this.#drawing === key)
74
+ this.#drawing = undefined;
75
+ for (const timers of this.#timers.get(key) ?? [])
76
+ timers.pause();
77
+ this.#events.emit("render-fetching", { key });
78
+ }
79
+ }
64
80
  /**
65
81
  * Starts the document worker and loads the backend at once, so the WebAssembly downloads while
66
82
  * the user picks a file.
@@ -97,7 +113,9 @@ export class ViewerClient {
97
113
  if (this.#recovering !== undefined)
98
114
  await this.#recovering.catch(() => { });
99
115
  const { signal, priority, key } = options;
100
- const level = method === "render" ? PRIORITY[priority ?? "visible"] : PRIORITY.document;
116
+ // Renders, and calls that name a priority (text, at `background`), queue with the tiles; other
117
+ // document calls run first.
118
+ const level = method === "render" || priority !== undefined ? PRIORITY[priority ?? "visible"] : PRIORITY.document;
101
119
  try {
102
120
  return (await this.#pdf.request(method, params, {
103
121
  priority: level,
@@ -131,6 +149,13 @@ export class ViewerClient {
131
149
  this.#document = undefined;
132
150
  await this.call("closeDocument", []);
133
151
  }
152
+ /**
153
+ * Every request the document worker has made, and had blocked, since it started: what its
154
+ * `network` and `csp-violation` events reported, including those sent before anyone listened.
155
+ */
156
+ networkLog(options) {
157
+ return this.call("networkLog", [], options);
158
+ }
134
159
  /** The worker's WebAssembly memory in bytes (see `WorkerMemory`), for measuring. */
135
160
  memory(options) {
136
161
  return this.call("memory", [], options);
@@ -139,6 +164,36 @@ export class ViewerClient {
139
164
  pageInfo(index, options) {
140
165
  return this.call("pageInfo", [index], options);
141
166
  }
167
+ /**
168
+ * Page `index`'s text runs and glyph quads, read by Lamina PDF (needs the extract or text
169
+ * module, loaded by default). At `background` priority unless `options` says otherwise.
170
+ */
171
+ pageText(index, options = {}) {
172
+ const key = `text:${this.#document?.id ?? 0}:${index}`;
173
+ return this.call("pageText", [index], { priority: "background", key, ...options });
174
+ }
175
+ /**
176
+ * The matches of `query` on each of `pages`, at `background` priority unless `options` says
177
+ * otherwise, so renders run first. The find controller calls it a few pages at a time.
178
+ */
179
+ find(query, find, pages, options = {}) {
180
+ return this.call("find", [query, find, pages], { priority: "background", ...options });
181
+ }
182
+ /** Whether the open document says it is tagged, and its structure tree when it has one. */
183
+ structure(options) {
184
+ return this.call("structure", [], options);
185
+ }
186
+ /**
187
+ * The open document's outline (bookmarks): top-level items, each with its children and where
188
+ * it goes as a page and a page-space view; empty without one. Read when first asked for.
189
+ */
190
+ outline(options) {
191
+ return this.call("outline", [], options);
192
+ }
193
+ /** Where the named destination `name` goes, or `undefined` when the document has no such name. */
194
+ namedDestination(name, options) {
195
+ return this.call("namedDestination", [name], options);
196
+ }
142
197
  /**
143
198
  * Renders `request` as an ImageBitmap (close it when done). Identical requests in flight are
144
199
  * drawn once. An aborted render rejects with `AbortError` and never paints.
@@ -154,7 +209,12 @@ export class ViewerClient {
154
209
  const key = renderKey(request, documentId);
155
210
  let soft;
156
211
  let hard;
212
+ const pause = () => {
213
+ clearTimeout(soft);
214
+ clearTimeout(hard);
215
+ };
157
216
  const start = () => {
217
+ pause();
158
218
  soft = setTimeout(() => this.#events.emit("render-slow", { id, page: request.page }), this.#timeouts.soft);
159
219
  hard = setTimeout(() => {
160
220
  if (needsPassword)
@@ -163,28 +223,28 @@ export class ViewerClient {
163
223
  this.stop("hard-timeout").catch((error) => this.#events.emit("restart-failed", { reason: "hard-timeout", error }));
164
224
  }, this.#timeouts.hard);
165
225
  };
166
- let waiting = this.#waiting.get(key);
167
- if (waiting === undefined) {
168
- waiting = new Set();
169
- this.#waiting.set(key, waiting);
226
+ const timers = { start, pause };
227
+ let set = this.#timers.get(key);
228
+ if (set === undefined) {
229
+ set = new Set();
230
+ this.#timers.set(key, set);
170
231
  }
232
+ set.add(timers);
171
233
  // Joining a render already being drawn: its render-start has passed.
172
234
  if (this.#drawing === key)
173
235
  start();
174
- else
175
- waiting.add(start);
176
236
  try {
177
237
  return await this.call("render", [request, documentId], { ...options, key });
178
238
  }
179
239
  finally {
180
- const set = this.#waiting.get(key);
181
- set?.delete(start);
182
- if (set?.size === 0)
183
- this.#waiting.delete(key);
184
- if (this.#drawing === key)
185
- this.#drawing = undefined;
186
- clearTimeout(soft);
187
- clearTimeout(hard);
240
+ const own = this.#timers.get(key);
241
+ own?.delete(timers);
242
+ if (own?.size === 0) {
243
+ this.#timers.delete(key);
244
+ if (this.#drawing === key)
245
+ this.#drawing = undefined;
246
+ }
247
+ pause();
188
248
  }
189
249
  }
190
250
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { FindPageResult } from "../protocol.js";
2
+ import type { FindOptions } from "./fold.js";
3
+ import type { FindSnippet } from "./page.js";
4
+ /** Find's state, for the find bar (`useSyncExternalStore`). */
5
+ export interface FindState {
6
+ /** The query as typed; empty when find is idle. */
7
+ readonly query: string;
8
+ readonly options: FindOptions;
9
+ /** Matches found so far, in the whole document. */
10
+ readonly total: number;
11
+ /** The current match's position among them, 0-based, in document order; undefined before the first. */
12
+ readonly current: number | undefined;
13
+ /** Pages searched so far, and the document's page count. */
14
+ readonly searched: number;
15
+ readonly pageCount: number;
16
+ /** Every page searched. */
17
+ readonly done: boolean;
18
+ /** Pages with no text to search (scans without an OCR layer). */
19
+ readonly pagesWithoutText: number;
20
+ /** Which search the state belongs to, rising with each new query. */
21
+ readonly search: number;
22
+ }
23
+ /** One match, for a list of results. */
24
+ export interface FindResult {
25
+ /** Its position among every match found so far, 0-based, in document order (as `FindState.current`). */
26
+ readonly ordinal: number;
27
+ /** Its page, 0-based. */
28
+ readonly page: number;
29
+ /** The match in its line. */
30
+ readonly snippet: FindSnippet;
31
+ }
32
+ /** What the controller needs of the viewer and its client. */
33
+ export interface FindHost {
34
+ find(query: string, options: FindOptions, pages: readonly number[], signal: AbortSignal): Promise<readonly FindPageResult[]>;
35
+ pageCount(): number;
36
+ currentPage(): number;
37
+ /** Scrolls match `quads` of `page` into view (centred when it is out of view). */
38
+ reveal(page: number, quads: readonly number[]): void;
39
+ /** These pages' highlights changed. */
40
+ redraw(pages: Iterable<number>): void;
41
+ }
42
+ /** Find in one viewer's document. Reach it as `viewer.find`. */
43
+ export declare class FindController {
44
+ #private;
45
+ constructor(host: FindHost);
46
+ /** Find's state now (a new object after each change). */
47
+ getState: () => FindState;
48
+ /** Calls `listener` after every change of state (for `useSyncExternalStore`); returns a function that stops it. */
49
+ subscribe: (listener: () => void) => (() => void);
50
+ /** Searches for `query` with `options`, replacing any search under way. An empty query clears. */
51
+ find(query: string, options?: FindOptions): void;
52
+ /** The next match, wrapping to the first; scrolls it into view. */
53
+ next(): void;
54
+ /** The previous match, wrapping to the last; scrolls it into view. */
55
+ previous(): void;
56
+ /** Makes the match at `ordinal` (as `FindResult.ordinal`) current and scrolls it into view. */
57
+ goTo(ordinal: number): void;
58
+ /**
59
+ * Every match found so far, in document order. While a search runs the list grows as pages are
60
+ * searched; the same array comes back until find's state next changes.
61
+ */
62
+ results(): readonly FindResult[];
63
+ /** Ends find: the search stops and every highlight goes. */
64
+ close(): void;
65
+ /** Page `page`'s matches, and which is current (for the highlight layer). */
66
+ matchesOn(page: number): {
67
+ matches: readonly (readonly number[])[];
68
+ current: number | undefined;
69
+ };
70
+ /** Stops the search and drops the results: a new document opened. */
71
+ reset(): void;
72
+ }
73
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/find/controller.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAK7C,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uGAAuG;IACvG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2BAA2B;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,wGAAwG;IACxG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAED,8DAA8D;AAC9D,MAAM,WAAW,QAAQ;IACvB,IAAI,CACF,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAAC;IACtC,SAAS,IAAI,MAAM,CAAC;IACpB,WAAW,IAAI,MAAM,CAAC;IACtB,kFAAkF;IAClF,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACrD,uCAAuC;IACvC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CACvC;AAoBD,gEAAgE;AAChE,qBAAa,cAAc;;IAYzB,YAAY,IAAI,EAAE,QAAQ,EAEzB;IAED,yDAAyD;IACzD,QAAQ,QAAO,SAAS,CAAgB;IAExC,mHAAmH;IACnH,SAAS,aAAc,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC,CAG9C;IAEF,kGAAkG;IAClG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAanD;IAED,mEAAmE;IACnE,IAAI,IAAI,IAAI,CAEX;IAED,sEAAsE;IACtE,QAAQ,IAAI,IAAI,CAEf;IAED,+FAA+F;IAC/F,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1B;IAED;;;OAGG;IACH,OAAO,IAAI,SAAS,UAAU,EAAE,CAQ/B;IAED,4DAA4D;IAC5D,KAAK,IAAI,IAAI,CAEZ;IAED,6EAA6E;IAC7E,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAKhG;IAED,qEAAqE;IACrE,KAAK,IAAI,IAAI,CAMZ;CAsHF"}