@awacloud/pdf 0.0.0-stage → 1.0.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.
Files changed (345) hide show
  1. package/CHANGELOG.md +609 -0
  2. package/LICENSE +661 -0
  3. package/NOTICE +77 -0
  4. package/README.md +363 -2
  5. package/dist/build/index.js +21 -0
  6. package/dist/build/pdf-full-rw.js +10972 -0
  7. package/dist/build/pdf-full-rw.meta.json +105 -0
  8. package/dist/build/pdf-full-rw.min.js +53 -0
  9. package/dist/build/pdf-full.js +6078 -0
  10. package/dist/build/pdf-full.meta.json +90 -0
  11. package/dist/build/pdf-full.min.js +32 -0
  12. package/dist/build/pdf-large-rw.js +10367 -0
  13. package/dist/build/pdf-large-rw.meta.json +99 -0
  14. package/dist/build/pdf-large-rw.min.js +53 -0
  15. package/dist/build/pdf-large.js +5473 -0
  16. package/dist/build/pdf-large.meta.json +84 -0
  17. package/dist/build/pdf-large.min.js +32 -0
  18. package/dist/build/pdf-legacy-rw.js +12402 -0
  19. package/dist/build/pdf-legacy-rw.meta.json +110 -0
  20. package/dist/build/pdf-legacy-rw.min.js +53 -0
  21. package/dist/build/pdf-legacy.js +7508 -0
  22. package/dist/build/pdf-legacy.meta.json +95 -0
  23. package/dist/build/pdf-legacy.min.js +32 -0
  24. package/dist/build/pdf-rw.js +7578 -0
  25. package/dist/build/pdf-rw.meta.json +77 -0
  26. package/dist/build/pdf-rw.min.js +53 -0
  27. package/dist/build/pdf.js +2684 -0
  28. package/dist/build/pdf.meta.json +62 -0
  29. package/dist/build/pdf.min.js +32 -0
  30. package/dist/standalone/pdf-full-rw.js +16798 -0
  31. package/dist/standalone/pdf-full-rw.meta.json +78 -0
  32. package/dist/standalone/pdf-full-rw.min.js +56 -0
  33. package/dist/standalone/pdf-full.js +11904 -0
  34. package/dist/standalone/pdf-full.meta.json +63 -0
  35. package/dist/standalone/pdf-full.min.js +35 -0
  36. package/dist/standalone/pdf-large-rw.js +16193 -0
  37. package/dist/standalone/pdf-large-rw.meta.json +72 -0
  38. package/dist/standalone/pdf-large-rw.min.js +56 -0
  39. package/dist/standalone/pdf-large.js +11299 -0
  40. package/dist/standalone/pdf-large.meta.json +57 -0
  41. package/dist/standalone/pdf-large.min.js +35 -0
  42. package/dist/standalone/pdf-legacy-rw.js +18228 -0
  43. package/dist/standalone/pdf-legacy-rw.meta.json +83 -0
  44. package/dist/standalone/pdf-legacy-rw.min.js +56 -0
  45. package/dist/standalone/pdf-legacy.js +13334 -0
  46. package/dist/standalone/pdf-legacy.meta.json +68 -0
  47. package/dist/standalone/pdf-legacy.min.js +35 -0
  48. package/dist/standalone/pdf-rw.js +13404 -0
  49. package/dist/standalone/pdf-rw.meta.json +50 -0
  50. package/dist/standalone/pdf-rw.min.js +56 -0
  51. package/dist/standalone/pdf.js +8510 -0
  52. package/dist/standalone/pdf.meta.json +35 -0
  53. package/dist/standalone/pdf.min.js +35 -0
  54. package/docs/README.md +53 -0
  55. package/docs/api/README.md +38 -0
  56. package/docs/api/_shared/README.md +91 -0
  57. package/docs/api/action/README.md +29 -0
  58. package/docs/api/action/action.md +81 -0
  59. package/docs/api/action/goTo.md +66 -0
  60. package/docs/api/action/launch.md +58 -0
  61. package/docs/api/action/named.md +55 -0
  62. package/docs/api/action/uri.md +54 -0
  63. package/docs/api/annot/README.md +53 -0
  64. package/docs/api/annot/annot.md +114 -0
  65. package/docs/api/annot/fileAttach.md +53 -0
  66. package/docs/api/annot/freeText.md +68 -0
  67. package/docs/api/annot/ink.md +69 -0
  68. package/docs/api/annot/link.md +74 -0
  69. package/docs/api/annot/markup.md +83 -0
  70. package/docs/api/annot/popup.md +52 -0
  71. package/docs/api/annot/projection.md +56 -0
  72. package/docs/api/annot/redact.md +67 -0
  73. package/docs/api/annot/square.md +87 -0
  74. package/docs/api/annot/stamp.md +54 -0
  75. package/docs/api/annot/text.md +69 -0
  76. package/docs/api/annot/widget.md +69 -0
  77. package/docs/api/associatedFiles/README.md +9 -0
  78. package/docs/api/associatedFiles/associatedFiles.md +78 -0
  79. package/docs/api/bundles/README.md +68 -0
  80. package/docs/api/bundles/dist-matrix.md +165 -0
  81. package/docs/api/bundles/pdf-full.md +148 -0
  82. package/docs/api/bundles/pdf-large.md +144 -0
  83. package/docs/api/bundles/pdf-legacy.md +169 -0
  84. package/docs/api/content/README.md +29 -0
  85. package/docs/api/content/color.md +99 -0
  86. package/docs/api/content/graphics.md +114 -0
  87. package/docs/api/content/images.md +124 -0
  88. package/docs/api/content/ops.md +100 -0
  89. package/docs/api/content/stream.md +107 -0
  90. package/docs/api/content/text.md +98 -0
  91. package/docs/api/crypto/README.md +29 -0
  92. package/docs/api/crypto/aesGcm.md +72 -0
  93. package/docs/api/crypto/permissions.md +79 -0
  94. package/docs/api/crypto/security.md +98 -0
  95. package/docs/api/crypto/standardV4.md +104 -0
  96. package/docs/api/crypto/standardV5.md +84 -0
  97. package/docs/api/crypto/standardV6.md +93 -0
  98. package/docs/api/destination/README.md +9 -0
  99. package/docs/api/destination/destination.md +79 -0
  100. package/docs/api/document/README.md +29 -0
  101. package/docs/api/document/builder.md +281 -0
  102. package/docs/api/document/catalog.md +98 -0
  103. package/docs/api/document/document.md +187 -0
  104. package/docs/api/document/encryptedWriter.md +149 -0
  105. package/docs/api/document/incrementalWriter.md +148 -0
  106. package/docs/api/document/page.md +99 -0
  107. package/docs/api/document/pages.md +82 -0
  108. package/docs/api/document/resources.md +102 -0
  109. package/docs/api/document/writer.md +157 -0
  110. package/docs/api/document/xrefStreamWriter.md +122 -0
  111. package/docs/api/embedded/README.md +13 -0
  112. package/docs/api/embedded/collection.md +80 -0
  113. package/docs/api/embedded/embeddedFile.md +86 -0
  114. package/docs/api/embedded/fileSpec.md +87 -0
  115. package/docs/api/errors.md +110 -0
  116. package/docs/api/extra/3d-richmedia.md +76 -0
  117. package/docs/api/extra/README.md +99 -0
  118. package/docs/api/extra/annot-extended.md +71 -0
  119. package/docs/api/extra/associated-files.md +70 -0
  120. package/docs/api/extra/ccitt-fax-decoder.md +74 -0
  121. package/docs/api/extra/color-spaces-extended.md +72 -0
  122. package/docs/api/extra/content-ops-extended.md +82 -0
  123. package/docs/api/extra/document-parts.md +69 -0
  124. package/docs/api/extra/embedded-files-portfolio.md +87 -0
  125. package/docs/api/extra/font-cid-typed.md +77 -0
  126. package/docs/api/extra/font-color-tagging.md +76 -0
  127. package/docs/api/extra/form-actions-extended.md +75 -0
  128. package/docs/api/extra/info-dict-deprecated.md +72 -0
  129. package/docs/api/extra/jbig2-read.md +80 -0
  130. package/docs/api/extra/legacy-deprecated-annots.md +89 -0
  131. package/docs/api/extra/legacy-deprecated-filters.md +78 -0
  132. package/docs/api/extra/legacy-rc4-read.md +74 -0
  133. package/docs/api/extra/legacy-xfa-read.md +65 -0
  134. package/docs/api/extra/linearization-write.md +71 -0
  135. package/docs/api/extra/misc.md +93 -0
  136. package/docs/api/extra/optional-content-extended.md +83 -0
  137. package/docs/api/extra/pdf-a-output-intent.md +65 -0
  138. package/docs/api/extra/pdf-sandbox.md +76 -0
  139. package/docs/api/extra/pdf-ua-tagged.md +63 -0
  140. package/docs/api/extra/pdf-x-prepress.md +65 -0
  141. package/docs/api/extra/redaction-iso32005.md +65 -0
  142. package/docs/api/extra/shading-typed.md +73 -0
  143. package/docs/api/extra/sig-aes-gcm.md +69 -0
  144. package/docs/api/extra/sig-pades.md +103 -0
  145. package/docs/api/extra/tagged-pdf-typed.md +78 -0
  146. package/docs/api/extra/transparency-typed.md +74 -0
  147. package/docs/api/extra/well-tagged-pdf.md +61 -0
  148. package/docs/api/extra/xmp-extended.md +65 -0
  149. package/docs/api/font/README.md +25 -0
  150. package/docs/api/font/embed.md +157 -0
  151. package/docs/api/font/encoding.md +95 -0
  152. package/docs/api/font/font.md +97 -0
  153. package/docs/api/font/type3.md +89 -0
  154. package/docs/api/form/README.md +35 -0
  155. package/docs/api/form/acroform.md +88 -0
  156. package/docs/api/form/appearance.md +87 -0
  157. package/docs/api/form/button.md +97 -0
  158. package/docs/api/form/choice.md +96 -0
  159. package/docs/api/form/fieldTree.md +93 -0
  160. package/docs/api/form/signature.md +90 -0
  161. package/docs/api/form/text.md +88 -0
  162. package/docs/api/linearization/README.md +11 -0
  163. package/docs/api/linearization/linearization.md +81 -0
  164. package/docs/api/main.md +116 -0
  165. package/docs/api/metadata/README.md +10 -0
  166. package/docs/api/metadata/info.md +70 -0
  167. package/docs/api/metadata/xmp.md +62 -0
  168. package/docs/api/ocg/README.md +23 -0
  169. package/docs/api/ocg/config.md +95 -0
  170. package/docs/api/ocg/ocg.md +77 -0
  171. package/docs/api/outline/README.md +11 -0
  172. package/docs/api/outline/outline.md +107 -0
  173. package/docs/api/pdf.md +152 -0
  174. package/docs/api/prepress/README.md +10 -0
  175. package/docs/api/prepress/outputIntent.md +79 -0
  176. package/docs/api/prepress/pageBoundary.md +75 -0
  177. package/docs/api/sig/README.md +32 -0
  178. package/docs/api/sig/byteRange.md +120 -0
  179. package/docs/api/sig/certChain.md +84 -0
  180. package/docs/api/sig/dss.md +111 -0
  181. package/docs/api/sig/oids.md +76 -0
  182. package/docs/api/sig/sha1.md +72 -0
  183. package/docs/api/sig/sign.md +317 -0
  184. package/docs/api/sig/signature.md +178 -0
  185. package/docs/api/sig/timestamp.md +84 -0
  186. package/docs/api/syntax/README.md +29 -0
  187. package/docs/api/syntax/crossRefStream.md +115 -0
  188. package/docs/api/syntax/filters/README.md +50 -0
  189. package/docs/api/syntax/filters/ascii85.md +76 -0
  190. package/docs/api/syntax/filters/asciiHex.md +73 -0
  191. package/docs/api/syntax/filters/dispatch.md +125 -0
  192. package/docs/api/syntax/filters/flate.md +134 -0
  193. package/docs/api/syntax/filters/runLength.md +78 -0
  194. package/docs/api/syntax/objStream.md +88 -0
  195. package/docs/api/syntax/parser-obj.md +97 -0
  196. package/docs/api/syntax/parser.md +151 -0
  197. package/docs/api/syntax/serializer.md +109 -0
  198. package/docs/api/syntax/tokenizer.md +104 -0
  199. package/docs/api/syntax/trailer.md +85 -0
  200. package/docs/api/syntax/xref.md +139 -0
  201. package/docs/api/tagged/README.md +25 -0
  202. package/docs/api/tagged/classMap.md +67 -0
  203. package/docs/api/tagged/markedContent.md +62 -0
  204. package/docs/api/tagged/parentTree.md +67 -0
  205. package/docs/api/tagged/roleMap.md +67 -0
  206. package/docs/api/tagged/structElement.md +76 -0
  207. package/docs/api/tagged/structTree.md +75 -0
  208. package/docs/guide/coverage.md +113 -0
  209. package/docs/guide/crypto.md +121 -0
  210. package/docs/guide/extending.md +76 -0
  211. package/docs/guide/getting-started.md +75 -0
  212. package/docs/guide/legacy-1.7.md +42 -0
  213. package/docs/guide/pades-integration.md +579 -0
  214. package/docs/guide/read-pdf.md +89 -0
  215. package/package.json +97 -4
  216. package/src/_shared/index.js +179 -0
  217. package/src/action/action.js +119 -0
  218. package/src/action/goTo.js +89 -0
  219. package/src/action/launch.js +61 -0
  220. package/src/action/named.js +54 -0
  221. package/src/action/uri.js +51 -0
  222. package/src/annot/annot.js +212 -0
  223. package/src/annot/fileAttach.js +55 -0
  224. package/src/annot/freeText.js +82 -0
  225. package/src/annot/ink.js +77 -0
  226. package/src/annot/link.js +77 -0
  227. package/src/annot/markup.js +91 -0
  228. package/src/annot/popup.js +53 -0
  229. package/src/annot/projection.js +52 -0
  230. package/src/annot/redact.js +87 -0
  231. package/src/annot/square.js +132 -0
  232. package/src/annot/stamp.js +48 -0
  233. package/src/annot/text.js +54 -0
  234. package/src/annot/widget.js +61 -0
  235. package/src/associatedFiles/associatedFiles.js +86 -0
  236. package/src/bundles/pdf-full.js +91 -0
  237. package/src/bundles/pdf-large.js +81 -0
  238. package/src/bundles/pdf-legacy.js +107 -0
  239. package/src/content/color.js +114 -0
  240. package/src/content/graphics.js +192 -0
  241. package/src/content/images.js +160 -0
  242. package/src/content/ops.js +137 -0
  243. package/src/content/stream.js +154 -0
  244. package/src/content/text.js +125 -0
  245. package/src/crypto/aesGcm.js +123 -0
  246. package/src/crypto/permissions.js +112 -0
  247. package/src/crypto/security.js +327 -0
  248. package/src/crypto/standardV4.js +443 -0
  249. package/src/crypto/standardV5.js +306 -0
  250. package/src/crypto/standardV6.js +334 -0
  251. package/src/destination/destination.js +183 -0
  252. package/src/document/builder.js +618 -0
  253. package/src/document/catalog.js +100 -0
  254. package/src/document/document.js +472 -0
  255. package/src/document/encryptedWriter.js +554 -0
  256. package/src/document/incrementalWriter.js +514 -0
  257. package/src/document/page.js +131 -0
  258. package/src/document/pages.js +103 -0
  259. package/src/document/resources.js +146 -0
  260. package/src/document/writer.js +211 -0
  261. package/src/document/xrefStreamWriter.js +353 -0
  262. package/src/embedded/collection.js +102 -0
  263. package/src/embedded/embeddedFile.js +99 -0
  264. package/src/embedded/fileSpec.js +137 -0
  265. package/src/errors.js +78 -0
  266. package/src/extra/3d-richmedia.js +171 -0
  267. package/src/extra/annot-extended.js +200 -0
  268. package/src/extra/associated-files.js +131 -0
  269. package/src/extra/ccitt-fax-decoder.js +776 -0
  270. package/src/extra/color-spaces-extended.js +196 -0
  271. package/src/extra/content-ops-extended.js +153 -0
  272. package/src/extra/document-parts.js +149 -0
  273. package/src/extra/embedded-files-portfolio.js +234 -0
  274. package/src/extra/font-cid-typed.js +185 -0
  275. package/src/extra/font-color-tagging.js +144 -0
  276. package/src/extra/form-actions-extended.js +196 -0
  277. package/src/extra/info-dict-deprecated.js +137 -0
  278. package/src/extra/jbig2-read.js +169 -0
  279. package/src/extra/legacy-deprecated-annots.js +198 -0
  280. package/src/extra/legacy-deprecated-filters.js +167 -0
  281. package/src/extra/legacy-rc4-read.js +235 -0
  282. package/src/extra/legacy-xfa-read.js +104 -0
  283. package/src/extra/linearization-write.js +97 -0
  284. package/src/extra/misc.js +217 -0
  285. package/src/extra/optional-content-extended.js +142 -0
  286. package/src/extra/pdf-a-output-intent.js +112 -0
  287. package/src/extra/pdf-sandbox.js +88 -0
  288. package/src/extra/pdf-ua-tagged.js +116 -0
  289. package/src/extra/pdf-x-prepress.js +114 -0
  290. package/src/extra/redaction-iso32005.js +136 -0
  291. package/src/extra/shading-typed.js +222 -0
  292. package/src/extra/sig-aes-gcm.js +135 -0
  293. package/src/extra/sig-pades.js +242 -0
  294. package/src/extra/tagged-pdf-typed.js +203 -0
  295. package/src/extra/transparency-typed.js +135 -0
  296. package/src/extra/well-tagged-pdf.js +138 -0
  297. package/src/extra/xmp-extended.js +190 -0
  298. package/src/font/embed.js +480 -0
  299. package/src/font/encoding.js +92 -0
  300. package/src/font/font.js +101 -0
  301. package/src/font/type3.js +75 -0
  302. package/src/form/acroform.js +94 -0
  303. package/src/form/appearance.js +90 -0
  304. package/src/form/button.js +105 -0
  305. package/src/form/choice.js +152 -0
  306. package/src/form/fieldTree.js +120 -0
  307. package/src/form/signature.js +100 -0
  308. package/src/form/text.js +101 -0
  309. package/src/linearization/linearization.js +107 -0
  310. package/src/main.js +411 -0
  311. package/src/metadata/info.js +87 -0
  312. package/src/metadata/xmp.js +62 -0
  313. package/src/ocg/config.js +156 -0
  314. package/src/ocg/ocg.js +124 -0
  315. package/src/outline/outline.js +157 -0
  316. package/src/pdf.js +133 -0
  317. package/src/prepress/outputIntent.js +118 -0
  318. package/src/prepress/pageBoundary.js +108 -0
  319. package/src/sig/byteRange.js +306 -0
  320. package/src/sig/certChain.js +247 -0
  321. package/src/sig/dss.js +317 -0
  322. package/src/sig/oids.js +157 -0
  323. package/src/sig/sha1.js +142 -0
  324. package/src/sig/sign.js +1899 -0
  325. package/src/sig/signature.js +1441 -0
  326. package/src/sig/timestamp.js +236 -0
  327. package/src/syntax/crossRefStream.js +133 -0
  328. package/src/syntax/filters/ascii85.js +122 -0
  329. package/src/syntax/filters/asciiHex.js +83 -0
  330. package/src/syntax/filters/dispatch.js +176 -0
  331. package/src/syntax/filters/flate.js +316 -0
  332. package/src/syntax/filters/runLength.js +96 -0
  333. package/src/syntax/objStream.js +99 -0
  334. package/src/syntax/parser-obj.js +52 -0
  335. package/src/syntax/parser.js +321 -0
  336. package/src/syntax/serializer.js +221 -0
  337. package/src/syntax/tokenizer.js +290 -0
  338. package/src/syntax/trailer.js +76 -0
  339. package/src/syntax/xref.js +341 -0
  340. package/src/tagged/classMap.js +81 -0
  341. package/src/tagged/markedContent.js +123 -0
  342. package/src/tagged/parentTree.js +126 -0
  343. package/src/tagged/roleMap.js +107 -0
  344. package/src/tagged/structElement.js +138 -0
  345. package/src/tagged/structTree.js +94 -0
package/package.json CHANGED
@@ -1,6 +1,99 @@
1
1
  {
2
2
  "name": "@awacloud/pdf",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "license": "AGPL-3.0-only",
5
+ "author": "Matthieu Bouilloux",
6
+ "company": "AwaCloud SAS",
7
+ "copyright": "Copyright (c) 2026 AwaCloud SAS",
8
+ "type": "module",
9
+ "main": "src/main.js",
10
+ "description": "Browser-safe PDF 2.0 reader/writer — ISO 32000-2:2020, PDF 1.7 legacy read, typed object graph, AES-256 encrypted write, PKCS#7/PAdES signatures (sign + verify). Zero runtime dependency beyond @awacloud/fw and @awacloud/fonts.",
11
+ "keywords": [
12
+ "pdf",
13
+ "pdf-2.0",
14
+ "iso-32000",
15
+ "pades",
16
+ "pkcs7",
17
+ "tagged-pdf",
18
+ "pdf-a",
19
+ "pdf-ua",
20
+ "xmp",
21
+ "acroform",
22
+ "browser",
23
+ "worker-safe"
24
+ ],
25
+ "engines": {
26
+ "node": ">=18"
27
+ },
28
+ "sideEffects": false,
29
+ "files": [
30
+ "src/**/*.js",
31
+ "!src/**/*.test.js",
32
+ "dist/**",
33
+ "docs",
34
+ "LICENSE",
35
+ "NOTICE",
36
+ "README.md",
37
+ "CHANGELOG.md"
38
+ ],
39
+ "exports": {
40
+ ".": "./src/main.js",
41
+ "./pdf": "./src/pdf.js",
42
+ "./errors": "./src/errors.js",
43
+ "./serializer": "./src/syntax/serializer.js",
44
+ "./filters/*.js": "./src/syntax/filters/*.js",
45
+ "./filters/*": "./src/syntax/filters/*.js",
46
+ "./annot/*.js": "./src/annot/*.js",
47
+ "./annot/*": "./src/annot/*.js",
48
+ "./tagged/*.js": "./src/tagged/*.js",
49
+ "./tagged/*": "./src/tagged/*.js",
50
+ "./crypto/*.js": "./src/crypto/*.js",
51
+ "./crypto/*": "./src/crypto/*.js",
52
+ "./sig/*.js": "./src/sig/*.js",
53
+ "./sig/*": "./src/sig/*.js",
54
+ "./ocg/*.js": "./src/ocg/*.js",
55
+ "./ocg/*": "./src/ocg/*.js",
56
+ "./action/*.js": "./src/action/*.js",
57
+ "./action/*": "./src/action/*.js",
58
+ "./embedded/*.js": "./src/embedded/*.js",
59
+ "./embedded/*": "./src/embedded/*.js",
60
+ "./metadata/*.js": "./src/metadata/*.js",
61
+ "./metadata/*": "./src/metadata/*.js",
62
+ "./prepress/*.js": "./src/prepress/*.js",
63
+ "./prepress/*": "./src/prepress/*.js",
64
+ "./extra/*.js": "./src/extra/*.js",
65
+ "./extra/*": "./src/extra/*.js",
66
+ "./bundles/*.js": "./src/bundles/*.js",
67
+ "./bundles/*": "./src/bundles/*.js",
68
+ "./pdf-large": "./src/bundles/pdf-large.js",
69
+ "./pdf-full": "./src/bundles/pdf-full.js",
70
+ "./pdf-legacy": "./src/bundles/pdf-legacy.js",
71
+ "./build/*": {
72
+ "default": "./dist/build/*"
73
+ },
74
+ "./standalone/*": {
75
+ "default": "./dist/standalone/*"
76
+ }
77
+ },
78
+ "scripts": {
79
+ "gen:bundles": "bun run tools/generate-bundles.mjs",
80
+ "lint": "eslint . --max-warnings 0"
81
+ },
82
+ "dependencies": {
83
+ "@awacloud/fw": "0.1.0",
84
+ "@awacloud/fonts": "1.0.0"
85
+ },
86
+ "awa": {
87
+ "maturity": "L4",
88
+ "coverageFloor": 0.58
89
+ },
90
+ "repository": {
91
+ "type": "git",
92
+ "url": "git+https://github.com/awacloud/awa.git",
93
+ "directory": "packages/front/office/pdf"
94
+ },
95
+ "homepage": "https://awaforge.eu",
96
+ "bugs": {
97
+ "url": "https://github.com/awacloud/awa/issues"
98
+ }
99
+ }
@@ -0,0 +1,179 @@
1
+ // Copyright (c) 2026 AwaCloud SAS
2
+ // Author: Matthieu Bouilloux
3
+ // SPDX-License-Identifier: AGPL-3.0-only
4
+ // Dual-licensed; see the NOTICE file for licensing and any additional terms.
5
+
6
+ /**
7
+ * @fileoverview `pdfShared` — canonical source of PDF byte-level
8
+ * constants and stateless helpers previously duplicated across many
9
+ * `@awacloud/pdf` factories.
10
+ *
11
+ * Exposes :
12
+ * - **Magic bytes** : `HEADER_PREFIX` (`%PDF-`), `EOF_MARKER` (`%%EOF`),
13
+ * `BINARY_MARKER` (the `%¡¢£¤\n` byte tail).
14
+ * - **ASCII constants** : `ASCII` object grouping the byte values used
15
+ * by the tokenizer / parsers / writers — `SP`, `HT`, `LF`, `CR`, `FF`,
16
+ * `NUL`, `HASH`, `PERCENT`, `BACKSLASH`, `SLASH`, `LPAREN`, `RPAREN`,
17
+ * `LANGLE`, `RANGLE`, `LBRACK`, `RBRACK`, `LBRACE`, `RBRACE`, `PLUS`,
18
+ * `MINUS`, `DOT`, `ZERO`, `NINE`, `A_UP`, `F_UP`, `Z_UP`, `A_LO`,
19
+ * `F_LO`, `Z_LO`.
20
+ * - **Character class predicates** (PDF 32000-2 §7.2) : `isWs`, `isEol`,
21
+ * `isDigit`, `isHex`, `isDelim`, `isRegular`, `hexNibble`. Each is a
22
+ * pure function over byte values.
23
+ * - **Hex tables** : `HEX_LO` — 128-entry lookup `byte → nibble value`
24
+ * (`-1` for non-hex), used by `asciiHex` and serializer.
25
+ * - **UTF-8 / latin1 codec singletons** : `te` (`TextEncoder`),
26
+ * `tdUtf8` (`TextDecoder('utf-8')`), `tdUtf8Lenient`
27
+ * (`TextDecoder('utf-8', { fatal: false })`), `tdLatin1`
28
+ * (`TextDecoder('latin1')`). Both `tdUtf8` and `tdUtf8Lenient` are
29
+ * non-fatal (`fatal: false` is the `TextDecoder` default). Available to
30
+ * `writer.js` and `serializer.js`.
31
+ * - **Codec helpers** : `encodeAscii(s)` / `decodeLatin1(bytes)` /
32
+ * `decodeUtf8(bytes)` / `decodeUtf8Lenient(bytes)` — thin wrappers
33
+ * over the singletons.
34
+ * - **Byte helpers** : `pad10(n)`, `hexLit(bytes)`, `bytesEqual(a, b, n)`,
35
+ * `concatBytes(arrays)` — available to modules; `writer.js` and
36
+ * `serializer.js` still carry their own copies.
37
+ *
38
+ * **Worker-safe** : every export is either a constant byte array, a
39
+ * pure function, or a singleton instantiated inside the factory body
40
+ * (so `factory.toString()` produces a self-contained closure).
41
+ *
42
+ * @module pdf/_shared
43
+ */
44
+
45
+ export const pdfShared = {
46
+ name: 'pdfShared',
47
+ dependencies: [],
48
+
49
+ factory() {
50
+ // --- Magic bytes -----------------------------------------------
51
+ const HEADER_PREFIX = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2D]); // %PDF-
52
+ const EOF_MARKER = new Uint8Array([0x25, 0x25, 0x45, 0x4F, 0x46]); // %%EOF
53
+ // Binary marker line emitted right after the version header so
54
+ // transports treat the file as binary (per PDF 32000-2 §7.5.2).
55
+ const BINARY_MARKER = new Uint8Array([0x25, 0xE2, 0xE3, 0xCF, 0xD3, 0x0A]);
56
+
57
+ // --- ASCII byte constants --------------------------------------
58
+ const ASCII = Object.freeze({
59
+ NUL: 0x00, HT: 0x09, LF: 0x0A, FF: 0x0C, CR: 0x0D, SP: 0x20,
60
+ HASH: 0x23, PERCENT: 0x25, LPAREN: 0x28, RPAREN: 0x29,
61
+ PLUS: 0x2B, MINUS: 0x2D, DOT: 0x2E, SLASH: 0x2F,
62
+ ZERO: 0x30, NINE: 0x39,
63
+ LANGLE: 0x3C, RANGLE: 0x3E,
64
+ A_UP: 0x41, F_UP: 0x46, Z_UP: 0x5A,
65
+ LBRACK: 0x5B, BACKSLASH: 0x5C, RBRACK: 0x5D,
66
+ A_LO: 0x61, F_LO: 0x66, Z_LO: 0x7A,
67
+ LBRACE: 0x7B, RBRACE: 0x7D
68
+ });
69
+
70
+ // --- Character class predicates (PDF 32000-2 §7.2) -------------
71
+ function isWs(b) {
72
+ return b === 0x20 || b === 0x09 || b === 0x0A
73
+ || b === 0x0D || b === 0x0C || b === 0x00;
74
+ }
75
+ function isEol(b) { return b === 0x0A || b === 0x0D; }
76
+ function isDigit(b) { return b >= 0x30 && b <= 0x39; }
77
+ function isHex(b) {
78
+ return (b >= 0x30 && b <= 0x39)
79
+ || (b >= 0x41 && b <= 0x46)
80
+ || (b >= 0x61 && b <= 0x66);
81
+ }
82
+ function isDelim(b) {
83
+ return b === 0x28 || b === 0x29 // ( )
84
+ || b === 0x3C || b === 0x3E // < >
85
+ || b === 0x5B || b === 0x5D // [ ]
86
+ || b === 0x2F || b === 0x25 // / %
87
+ || b === 0x7B || b === 0x7D; // { }
88
+ }
89
+ function isRegular(b) { return !isWs(b) && !isDelim(b); }
90
+
91
+ function hexNibble(b) {
92
+ if (b >= 0x30 && b <= 0x39) return b - 0x30;
93
+ if (b >= 0x41 && b <= 0x46) return b - 0x41 + 10;
94
+ if (b >= 0x61 && b <= 0x66) return b - 0x61 + 10;
95
+ return -1;
96
+ }
97
+
98
+ // --- Hex lookup table (byte → nibble value, -1 if non-hex) -----
99
+ // 128 entries, indexable by ASCII byte. Identical semantics to
100
+ // hexNibble() but O(1) without branches.
101
+ const HEX_LO = (function buildHexLo() {
102
+ const t = new Int8Array(128);
103
+ t.fill(-1);
104
+ for (let c = 0x30; c <= 0x39; c++) t[c] = c - 0x30;
105
+ for (let c = 0x41; c <= 0x46; c++) t[c] = c - 0x41 + 10;
106
+ for (let c = 0x61; c <= 0x66; c++) t[c] = c - 0x61 + 10;
107
+ return t;
108
+ })();
109
+
110
+ // --- UTF-8 / latin1 codec singletons ---------------------------
111
+ const te = new TextEncoder();
112
+ const tdUtf8 = new TextDecoder('utf-8');
113
+ const tdUtf8Lenient = new TextDecoder('utf-8', { fatal: false });
114
+ const tdLatin1 = new TextDecoder('latin1');
115
+
116
+ function encodeAscii(s) { return te.encode(s); }
117
+ function decodeUtf8(bytes) { return tdUtf8.decode(bytes); }
118
+ function decodeUtf8Lenient(b) { return tdUtf8Lenient.decode(b); }
119
+ function decodeLatin1(bytes) { return tdLatin1.decode(bytes); }
120
+
121
+ // --- Byte helpers ----------------------------------------------
122
+ function pad10(n) { return String(n).padStart(10, '0'); }
123
+
124
+ function hexLit(bytes) {
125
+ const H = '0123456789ABCDEF';
126
+ let s = '<';
127
+ for (let i = 0; i < bytes.length; i++) {
128
+ s += H[bytes[i] >> 4] + H[bytes[i] & 0xF];
129
+ }
130
+ return s + '>';
131
+ }
132
+
133
+ /**
134
+ * Constant-time-ish equality of two byte arrays.
135
+ *
136
+ * @param {Uint8Array} a
137
+ * @param {Uint8Array} b
138
+ * @param {number} [n] — optional prefix length to compare;
139
+ * defaults to `min(a.length, b.length)` and requires both
140
+ * arrays to be that length exactly.
141
+ */
142
+ function bytesEqual(a, b, n) {
143
+ if (!a || !b) return false;
144
+ if (n == null) {
145
+ if (a.length !== b.length) return false;
146
+ n = a.length;
147
+ } else {
148
+ if (a.length < n || b.length < n) return false;
149
+ }
150
+ let diff = 0;
151
+ for (let i = 0; i < n; i++) diff |= (a[i] ^ b[i]);
152
+ return diff === 0;
153
+ }
154
+
155
+ function concatBytes(arrays) {
156
+ let total = 0;
157
+ for (const a of arrays) total += a.length;
158
+ const out = new Uint8Array(total);
159
+ let o = 0;
160
+ for (const a of arrays) { out.set(a, o); o += a.length; }
161
+ return out;
162
+ }
163
+
164
+ return {
165
+ // magic
166
+ HEADER_PREFIX, EOF_MARKER, BINARY_MARKER,
167
+ // ASCII constants
168
+ ASCII,
169
+ // char classes
170
+ isWs, isEol, isDigit, isHex, isDelim, isRegular, hexNibble,
171
+ HEX_LO,
172
+ // codec singletons
173
+ te, tdUtf8, tdUtf8Lenient, tdLatin1,
174
+ encodeAscii, decodeUtf8, decodeUtf8Lenient, decodeLatin1,
175
+ // byte helpers
176
+ pad10, hexLit, bytesEqual, concatBytes
177
+ };
178
+ }
179
+ };
@@ -0,0 +1,119 @@
1
+ // Copyright (c) 2026 AwaCloud SAS
2
+ // Author: Matthieu Bouilloux
3
+ // SPDX-License-Identifier: AGPL-3.0-only
4
+ // Dual-licensed; see the NOTICE file for licensing and any additional terms.
5
+
6
+ /**
7
+ * @fileoverview Action orchestrator per ISO 32000-2:2020 §12.6.
8
+ *
9
+ * Dispatches on `/S` (action type) and delegates to a specialised typer
10
+ * when available, otherwise returns a generic `{ kind, raw, _extras }`
11
+ * record for action subtypes not (yet) covered by a dedicated module
12
+ * (Thread, Sound, Movie, Hide, SubmitForm, ResetForm, ImportData,
13
+ * SetOCGState, Rendition, Trans, GoTo3DView, GoToDp, JavaScript).
14
+ *
15
+ * The `/Next` entry (a single action dict or an array of them) is
16
+ * recursively typed, with cycle protection via a Set of seen dicts.
17
+ *
18
+ * Optional sub-typers are passed via the `typers` argument — this lets
19
+ * callers wire `typeGoTo`, `typeUri`, etc. without creating a hard
20
+ * import chain.
21
+ *
22
+ * @module pdf/action/action
23
+ */
24
+
25
+ /**
26
+ * Module factory.
27
+ */
28
+ import { pdfErrors } from '../errors.js';
29
+ import { pdfParser } from '../syntax/parser.js';
30
+
31
+ export const pdfAction = {
32
+ name: 'pdfAction',
33
+ dependencies: ['pdfErrors', 'pdfParser'],
34
+ deps: [pdfErrors, pdfParser],
35
+ factory(errors, parser) {
36
+ const { ParseError } = errors;
37
+ const { isType } = parser;
38
+
39
+ const GENERIC_KINDS = new Set([
40
+ 'GoTo', 'GoToR', 'GoToE', 'GoToDp', 'Launch', 'Thread', 'URI',
41
+ 'Sound', 'Movie', 'Hide', 'Named', 'SubmitForm', 'ResetForm',
42
+ 'ImportData', 'SetOCGState', 'Rendition', 'Trans', 'GoTo3DView',
43
+ 'JavaScript', 'RichMediaExecute'
44
+ ]);
45
+
46
+ function typeAction(dict, typers, opts) {
47
+ const seen = new Set();
48
+ const maxDepth = (opts && opts.maxDepth) || 16;
49
+ return walk(dict, 0);
50
+
51
+ function walk(d, depth) {
52
+ if (depth > maxDepth) {
53
+ throw new ParseError('pdf/action/max-depth',
54
+ 'action /Next chain too deep',
55
+ { context: { depth, maxDepth } });
56
+ }
57
+ if (!isType(d, 'dict')) {
58
+ throw new ParseError('pdf/action/not-dict',
59
+ 'action must be a dictionary',
60
+ { context: { type: d && d.type } });
61
+ }
62
+ if (seen.has(d)) {
63
+ throw new ParseError('pdf/action/cycle',
64
+ 'cycle detected in action /Next chain');
65
+ }
66
+ seen.add(d);
67
+
68
+ const e = d.entries;
69
+ if (e.Type && (e.Type.type !== 'name' || e.Type.value !== 'Action')) {
70
+ throw new ParseError('pdf/action/bad-type',
71
+ '/Type must be /Action when present',
72
+ { context: { actual: e.Type.value } });
73
+ }
74
+ if (!e.S || e.S.type !== 'name') {
75
+ throw new ParseError('pdf/action/missing-s',
76
+ 'action missing /S name',
77
+ { context: { type: e.S && e.S.type } });
78
+ }
79
+ const kind = e.S.value;
80
+
81
+ let rec;
82
+ const t = typers && typers[kind];
83
+ if (typeof t === 'function') {
84
+ rec = t(d);
85
+ if (!rec.kind) rec.kind = kind;
86
+ } else {
87
+ if (!GENERIC_KINDS.has(kind)) {
88
+ rec = { kind, vendor: true, raw: d, _extras: collectExtras(e) };
89
+ } else {
90
+ rec = { kind, raw: d, _extras: collectExtras(e) };
91
+ }
92
+ }
93
+
94
+ if (e.Next) {
95
+ if (e.Next.type === 'dict') {
96
+ rec.next = [walk(e.Next, depth + 1)];
97
+ } else if (e.Next.type === 'array') {
98
+ rec.next = e.Next.items.map((nx) => walk(nx, depth + 1));
99
+ } else {
100
+ throw new ParseError('pdf/action/bad-next',
101
+ '/Next must be a dict or array of dicts',
102
+ { context: { type: e.Next.type } });
103
+ }
104
+ }
105
+ return rec;
106
+ }
107
+ }
108
+
109
+ function collectExtras(entries) {
110
+ const out = {};
111
+ for (const k of Object.keys(entries)) {
112
+ if (k !== 'Type' && k !== 'S' && k !== 'Next') out[k] = entries[k];
113
+ }
114
+ return out;
115
+ }
116
+
117
+ return { typeAction };
118
+ }
119
+ };
@@ -0,0 +1,89 @@
1
+ // Copyright (c) 2026 AwaCloud SAS
2
+ // Author: Matthieu Bouilloux
3
+ // SPDX-License-Identifier: AGPL-3.0-only
4
+ // Dual-licensed; see the NOTICE file for licensing and any additional terms.
5
+
6
+ /**
7
+ * @fileoverview GoTo / GoToR / GoToE actions per ISO 32000-2:2020
8
+ * §12.6.4.2, §12.6.4.3, §12.6.4.4.
9
+ *
10
+ * GoTo — navigate to a destination in the current document.
11
+ * GoToR — navigate to a destination in a remote document (`/F` + `/D`).
12
+ * GoToE — navigate to a destination in an embedded document.
13
+ *
14
+ * These typers read the raw entries; resolution of `/F` (file
15
+ * specification) and `/D` (destination) is left to the caller via
16
+ * dedicated modules (`fileSpec`, `destination`).
17
+ *
18
+ * @module pdf/action/goTo
19
+ */
20
+
21
+ /**
22
+ * Module factory.
23
+ */
24
+ import { pdfErrors } from '../errors.js';
25
+ import { pdfParser } from '../syntax/parser.js';
26
+
27
+ export const pdfActionGoTo = {
28
+ name: 'pdfActionGoTo',
29
+ dependencies: ['pdfErrors', 'pdfParser'],
30
+ deps: [pdfErrors, pdfParser],
31
+ factory(errors, parser) {
32
+ const { ParseError } = errors;
33
+ const { isType } = parser;
34
+
35
+ function expectDict(d, kind) {
36
+ if (!isType(d, 'dict')) {
37
+ throw new ParseError('pdf/action/' + kind.toLowerCase() + '/not-dict',
38
+ kind + ' action must be a dictionary',
39
+ { context: { type: d && d.type } });
40
+ }
41
+ }
42
+
43
+ function typeGoTo(dict) {
44
+ expectDict(dict, 'GoTo');
45
+ const e = dict.entries;
46
+ if (!e.D) {
47
+ throw new ParseError('pdf/action/goto/missing-d',
48
+ 'GoTo action is missing /D');
49
+ }
50
+ return { kind: 'GoTo', dest: e.D, raw: dict };
51
+ }
52
+
53
+ function typeGoToR(dict) {
54
+ expectDict(dict, 'GoToR');
55
+ const e = dict.entries;
56
+ if (!e.F) {
57
+ throw new ParseError('pdf/action/gotor/missing-f',
58
+ 'GoToR action is missing /F');
59
+ }
60
+ if (!e.D) {
61
+ throw new ParseError('pdf/action/gotor/missing-d',
62
+ 'GoToR action is missing /D');
63
+ }
64
+ const out = { kind: 'GoToR', file: e.F, dest: e.D, raw: dict };
65
+ if (e.NewWindow && e.NewWindow.type === 'bool') {
66
+ out.newWindow = e.NewWindow.value;
67
+ }
68
+ return out;
69
+ }
70
+
71
+ function typeGoToE(dict) {
72
+ expectDict(dict, 'GoToE');
73
+ const e = dict.entries;
74
+ if (!e.D) {
75
+ throw new ParseError('pdf/action/gotoe/missing-d',
76
+ 'GoToE action is missing /D');
77
+ }
78
+ const out = { kind: 'GoToE', dest: e.D, raw: dict };
79
+ if (e.F) out.file = e.F;
80
+ if (e.T) out.target = e.T;
81
+ if (e.NewWindow && e.NewWindow.type === 'bool') {
82
+ out.newWindow = e.NewWindow.value;
83
+ }
84
+ return out;
85
+ }
86
+
87
+ return { typeGoTo, typeGoToR, typeGoToE };
88
+ }
89
+ };
@@ -0,0 +1,61 @@
1
+ // Copyright (c) 2026 AwaCloud SAS
2
+ // Author: Matthieu Bouilloux
3
+ // SPDX-License-Identifier: AGPL-3.0-only
4
+ // Dual-licensed; see the NOTICE file for licensing and any additional terms.
5
+
6
+ /**
7
+ * @fileoverview Launch action per ISO 32000-2:2020 §12.6.4.6.
8
+ *
9
+ * `/S /Launch` actions request the PDF viewer to run an external
10
+ * application or open a file. Executing such an action is a known
11
+ * security risk; this typer **never executes anything** — it surfaces
12
+ * the entries plus a `securityWarning` flag so the host application can
13
+ * decide what to do (typically: ignore, or prompt the user).
14
+ *
15
+ * @module pdf/action/launch
16
+ */
17
+
18
+ /**
19
+ * Module factory.
20
+ */
21
+ import { pdfErrors } from '../errors.js';
22
+ import { pdfParser } from '../syntax/parser.js';
23
+
24
+ export const pdfActionLaunch = {
25
+ name: 'pdfActionLaunch',
26
+ dependencies: ['pdfErrors', 'pdfParser'],
27
+ deps: [pdfErrors, pdfParser],
28
+ factory(errors, parser) {
29
+ const { ParseError } = errors;
30
+ const { isType } = parser;
31
+
32
+ function typeLaunch(dict) {
33
+ if (!isType(dict, 'dict')) {
34
+ throw new ParseError('pdf/action/launch/not-dict',
35
+ 'Launch action must be a dictionary',
36
+ { context: { type: dict && dict.type } });
37
+ }
38
+ const e = dict.entries;
39
+ const out = {
40
+ kind: 'Launch',
41
+ sandboxed: true,
42
+ securityWarning: 'launch actions are not executed by @awacloud/pdf',
43
+ raw: dict
44
+ };
45
+ if (e.F) out.file = e.F;
46
+ if (e.Win && e.Win.type === 'dict') out.win = e.Win;
47
+ if (e.Mac && e.Mac.type === 'dict') out.mac = e.Mac;
48
+ if (e.Unix && e.Unix.type === 'dict') out.unix = e.Unix;
49
+ if (e.NewWindow && e.NewWindow.type === 'bool') {
50
+ out.newWindow = e.NewWindow.value;
51
+ }
52
+ if (!out.file && !out.win && !out.mac && !out.unix) {
53
+ throw new ParseError('pdf/action/launch/empty',
54
+ 'Launch action has no /F, /Win, /Mac, or /Unix target');
55
+ }
56
+ return out;
57
+ }
58
+
59
+ return { typeLaunch };
60
+ }
61
+ };
@@ -0,0 +1,54 @@
1
+ // Copyright (c) 2026 AwaCloud SAS
2
+ // Author: Matthieu Bouilloux
3
+ // SPDX-License-Identifier: AGPL-3.0-only
4
+ // Dual-licensed; see the NOTICE file for licensing and any additional terms.
5
+
6
+ /**
7
+ * @fileoverview Named action per ISO 32000-2:2020 §12.6.4.11.
8
+ *
9
+ * `/S /Named` actions carry a `/N` name. The standard predefined names
10
+ * are NextPage, PrevPage, FirstPage, LastPage; vendor-defined names are
11
+ * accepted but flagged via `standard: false`.
12
+ *
13
+ * @module pdf/action/named
14
+ */
15
+
16
+ /**
17
+ * Module factory.
18
+ */
19
+ import { pdfErrors } from '../errors.js';
20
+ import { pdfParser } from '../syntax/parser.js';
21
+
22
+ export const pdfActionNamed = {
23
+ name: 'pdfActionNamed',
24
+ dependencies: ['pdfErrors', 'pdfParser'],
25
+ deps: [pdfErrors, pdfParser],
26
+ factory(errors, parser) {
27
+ const { ParseError } = errors;
28
+ const { isType } = parser;
29
+
30
+ const STANDARD = new Set(['NextPage', 'PrevPage', 'FirstPage', 'LastPage']);
31
+
32
+ function typeNamed(dict) {
33
+ if (!isType(dict, 'dict')) {
34
+ throw new ParseError('pdf/action/named/not-dict',
35
+ 'Named action must be a dictionary',
36
+ { context: { type: dict && dict.type } });
37
+ }
38
+ const e = dict.entries;
39
+ if (!e.N || e.N.type !== 'name') {
40
+ throw new ParseError('pdf/action/named/missing-n',
41
+ 'Named action missing /N name',
42
+ { context: { type: e.N && e.N.type } });
43
+ }
44
+ return {
45
+ kind: 'Named',
46
+ name: e.N.value,
47
+ standard: STANDARD.has(e.N.value),
48
+ raw: dict
49
+ };
50
+ }
51
+
52
+ return { typeNamed };
53
+ }
54
+ };
@@ -0,0 +1,51 @@
1
+ // Copyright (c) 2026 AwaCloud SAS
2
+ // Author: Matthieu Bouilloux
3
+ // SPDX-License-Identifier: AGPL-3.0-only
4
+ // Dual-licensed; see the NOTICE file for licensing and any additional terms.
5
+
6
+ /**
7
+ * @fileoverview URI action per ISO 32000-2:2020 §12.6.4.7.
8
+ *
9
+ * `/S /URI` actions navigate to a URI; `/IsMap` indicates that mouse
10
+ * coordinates should be appended for image-map style links. The URI
11
+ * value is preserved as a raw byte string — callers decide how to
12
+ * decode it (typically PDFDocEncoding or UTF-8).
13
+ *
14
+ * @module pdf/action/uri
15
+ */
16
+
17
+ /**
18
+ * Module factory — worker-safe, self-contained.
19
+ */
20
+ import { pdfErrors } from '../errors.js';
21
+ import { pdfParser } from '../syntax/parser.js';
22
+
23
+ export const pdfActionUri = {
24
+ name: 'pdfActionUri',
25
+ dependencies: ['pdfErrors', 'pdfParser'],
26
+ deps: [pdfErrors, pdfParser],
27
+ factory(errors) {
28
+ const { ParseError } = errors;
29
+ // Self-contained isType: tolerates `parser = {}` from tests.
30
+ function isType(node, kind) { return !!(node && node.type === kind); }
31
+
32
+ function typeUri(dict) {
33
+ if (!isType(dict, 'dict')) {
34
+ throw new ParseError('pdf/action/uri/not-dict',
35
+ 'URI action must be a dictionary',
36
+ { context: { type: dict && dict.type } });
37
+ }
38
+ const e = dict.entries;
39
+ if (!e.URI || e.URI.type !== 'string') {
40
+ throw new ParseError('pdf/action/uri/missing',
41
+ 'URI action missing /URI string',
42
+ { context: { type: e.URI && e.URI.type } });
43
+ }
44
+ const out = { kind: 'URI', uri: e.URI.value, raw: dict };
45
+ if (e.IsMap && e.IsMap.type === 'bool') out.isMap = e.IsMap.value;
46
+ return out;
47
+ }
48
+
49
+ return { typeUri };
50
+ }
51
+ };