@arbidocs/react 0.5.120 → 0.5.121

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 (88) hide show
  1. package/dist/PdfViewerImpl-ZVJZ4KNW.cjs +22 -0
  2. package/dist/PdfViewerImpl-ZVJZ4KNW.cjs.map +1 -0
  3. package/dist/{PdfViewerImpl.d-B28hLEuj.d.ts → PdfViewerImpl.d-CqnEzQO7.d.ts} +9 -1
  4. package/dist/annotations/freeze/index.d.ts +1 -1
  5. package/dist/artifacts/artifact-kind.js +1 -0
  6. package/dist/artifacts/artifact-kind.js.map +2 -2
  7. package/dist/artifacts/index.cjs +3 -2
  8. package/dist/artifacts/index.cjs.map +1 -1
  9. package/dist/artifacts/index.d.ts +3 -2
  10. package/dist/calls/livekit/index.cjs +41 -41
  11. package/dist/chat/turn-flush.js +16 -0
  12. package/dist/chat/turn-flush.js.map +7 -0
  13. package/dist/chat/useConversationActions.js +3 -0
  14. package/dist/chat/useConversationActions.js.map +2 -2
  15. package/dist/{chunk-QP3WQSAA.cjs → chunk-4B2GW3AY.cjs} +3 -3
  16. package/dist/{chunk-QP3WQSAA.cjs.map → chunk-4B2GW3AY.cjs.map} +1 -1
  17. package/dist/{chunk-YMB6XUR2.cjs → chunk-7L7QRIQ2.cjs} +11 -7
  18. package/dist/chunk-7L7QRIQ2.cjs.map +1 -0
  19. package/dist/{chunk-KDYYAZXP.cjs → chunk-DLEHM4IA.cjs} +227 -155
  20. package/dist/chunk-DLEHM4IA.cjs.map +1 -0
  21. package/dist/{PdfViewerImpl-QUSDLNNM.cjs → chunk-ICBT2XGF.cjs} +5 -2
  22. package/dist/chunk-ICBT2XGF.cjs.map +1 -0
  23. package/dist/{chunk-AJRYZ3IC.cjs → chunk-K6ELFSG6.cjs} +3 -3
  24. package/dist/{chunk-AJRYZ3IC.cjs.map → chunk-K6ELFSG6.cjs.map} +1 -1
  25. package/dist/chunk-MAOGK7IC.cjs +61 -0
  26. package/dist/chunk-MAOGK7IC.cjs.map +1 -0
  27. package/dist/{chunk-5TRUFWKT.cjs → chunk-X5OZRLFZ.cjs} +5 -5
  28. package/dist/{chunk-5TRUFWKT.cjs.map → chunk-X5OZRLFZ.cjs.map} +1 -1
  29. package/dist/{chunk-C72FSQUE.cjs → chunk-Z3W4XFWB.cjs} +3 -3
  30. package/dist/{chunk-C72FSQUE.cjs.map → chunk-Z3W4XFWB.cjs.map} +1 -1
  31. package/dist/datasets/sources/documents.js +1 -1
  32. package/dist/datasets/sources/documents.js.map +2 -2
  33. package/dist/document-tools/core.cjs +80 -80
  34. package/dist/document-tools/images-to-pdf.js +43 -0
  35. package/dist/document-tools/images-to-pdf.js.map +7 -0
  36. package/dist/document-tools/index.cjs +184 -80
  37. package/dist/document-tools/index.cjs.map +1 -1
  38. package/dist/document-tools/index.d.ts +41 -1
  39. package/dist/document-tools/index.js +6 -1
  40. package/dist/document-tools/index.js.map +2 -2
  41. package/dist/document-tools/pdf-attachments.js +63 -0
  42. package/dist/document-tools/pdf-attachments.js.map +7 -0
  43. package/dist/entities/DocumentEntity.js +7 -2
  44. package/dist/entities/DocumentEntity.js.map +2 -2
  45. package/dist/entities/file-type.js +14 -2
  46. package/dist/entities/file-type.js.map +2 -2
  47. package/dist/entities/index.js +9 -1
  48. package/dist/entities/index.js.map +2 -2
  49. package/dist/icons/PresIcon.js +53 -0
  50. package/dist/icons/PresIcon.js.map +7 -0
  51. package/dist/icons/colors.js +2 -0
  52. package/dist/icons/colors.js.map +2 -2
  53. package/dist/icons/file-type.js +3 -0
  54. package/dist/icons/file-type.js.map +2 -2
  55. package/dist/icons/index.js +2 -0
  56. package/dist/icons/index.js.map +2 -2
  57. package/dist/index.cjs +898 -865
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/{index.d-DYlUprG9.d.ts → index.d-D2puqWeN.d.ts} +17 -3
  60. package/dist/index.d.ts +41 -8
  61. package/dist/index.js +1 -0
  62. package/dist/index.js.map +2 -2
  63. package/dist/pdf-region-impl-ZG5G2OX2.cjs +98 -0
  64. package/dist/pdf-region-impl-ZG5G2OX2.cjs.map +1 -0
  65. package/dist/session/documents.js +9 -5
  66. package/dist/session/documents.js.map +2 -2
  67. package/dist/shell/index.cjs +37 -37
  68. package/dist/ui/index.cjs +182 -170
  69. package/dist/ui/index.d.ts +1 -1
  70. package/dist/ui/slider.js +7 -1
  71. package/dist/ui/slider.js.map +2 -2
  72. package/dist/viewers/PdfViewer.cjs +3 -3
  73. package/dist/viewers/PdfViewer.d.ts +2 -2
  74. package/dist/viewers/PdfViewerImpl.js +4 -1
  75. package/dist/viewers/PdfViewerImpl.js.map +2 -2
  76. package/dist/viewers/index.cjs +28 -3
  77. package/dist/viewers/index.cjs.map +1 -1
  78. package/dist/viewers/index.d.ts +68 -2
  79. package/dist/viewers/index.js +14 -0
  80. package/dist/viewers/index.js.map +2 -2
  81. package/dist/viewers/pdf-region-impl.js +96 -0
  82. package/dist/viewers/pdf-region-impl.js.map +7 -0
  83. package/dist/viewers/pdf-region.js +57 -0
  84. package/dist/viewers/pdf-region.js.map +7 -0
  85. package/package.json +3 -3
  86. package/dist/PdfViewerImpl-QUSDLNNM.cjs.map +0 -1
  87. package/dist/chunk-KDYYAZXP.cjs.map +0 -1
  88. package/dist/chunk-YMB6XUR2.cjs.map +0 -1
@@ -1,15 +1,15 @@
1
1
  'use strict';
2
2
 
3
- var chunkAJRYZ3IC_cjs = require('../chunk-AJRYZ3IC.cjs');
3
+ var chunkK6ELFSG6_cjs = require('../chunk-K6ELFSG6.cjs');
4
4
  var chunk3JAEX57E_cjs = require('../chunk-3JAEX57E.cjs');
5
- var chunkO32T7XRD_cjs = require('../chunk-O32T7XRD.cjs');
6
5
  require('../chunk-SUZORMAB.cjs');
7
6
  require('../chunk-2IJP73ZG.cjs');
7
+ var chunkO32T7XRD_cjs = require('../chunk-O32T7XRD.cjs');
8
8
  require('../chunk-NDIKMOBJ.cjs');
9
9
  require('../chunk-VOFNX4P6.cjs');
10
10
  require('../chunk-WYZJLZ67.cjs');
11
- require('../chunk-5NOZDH3F.cjs');
12
11
  require('../chunk-HJDR5HEO.cjs');
12
+ require('../chunk-5NOZDH3F.cjs');
13
13
  require('../chunk-S6A6FSG7.cjs');
14
14
 
15
15
  // src/document-tools/production.ts
@@ -146,313 +146,414 @@ async function buildProduction(client, documents, choices, options) {
146
146
  };
147
147
  }
148
148
 
149
+ // src/document-tools/images-to-pdf.ts
150
+ async function imagesToPdf(pages, meta = {}) {
151
+ const { PDFDocument, StandardFonts } = await import('pdf-lib');
152
+ const pdf = await PDFDocument.create();
153
+ if (meta.title) pdf.setTitle(meta.title);
154
+ const now = /* @__PURE__ */ new Date();
155
+ for (const attachment of meta.attachments ?? []) {
156
+ await pdf.attach(new Uint8Array(attachment.data), attachment.name, {
157
+ mimeType: attachment.mimeType,
158
+ description: attachment.description,
159
+ creationDate: now,
160
+ modificationDate: now
161
+ });
162
+ }
163
+ const font = await pdf.embedFont(StandardFonts.Helvetica);
164
+ const encodable = (line) => [...line].filter((ch) => {
165
+ try {
166
+ font.encodeText(ch);
167
+ return true;
168
+ } catch {
169
+ return false;
170
+ }
171
+ }).join("");
172
+ for (const entry of pages) {
173
+ const bytes = new Uint8Array(await entry.image.arrayBuffer());
174
+ const image = entry.image.type === "image/png" ? await pdf.embedPng(bytes) : await pdf.embedJpg(bytes);
175
+ const page = pdf.addPage([entry.width, entry.height]);
176
+ page.drawImage(image, { x: 0, y: 0, width: entry.width, height: entry.height });
177
+ let y = entry.height - 14;
178
+ for (const line of entry.text ?? []) {
179
+ const text = encodable(line).trim();
180
+ if (!text) continue;
181
+ page.drawText(text, { x: 8, y, size: 10, font, opacity: 0 });
182
+ y -= 12;
183
+ if (y < 4) break;
184
+ }
185
+ }
186
+ const saved = await pdf.save();
187
+ return new Blob([saved], { type: "application/pdf" });
188
+ }
189
+
190
+ // src/document-tools/pdf-attachments.ts
191
+ var asBytes = (bytes) => bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
192
+ async function readPdfAttachment(pdf, name) {
193
+ const lib = await import('pdf-lib');
194
+ const { PDFDocument, PDFName, PDFDict, PDFArray, PDFString, PDFHexString, decodePDFRawStream } = lib;
195
+ const doc = await PDFDocument.load(asBytes(pdf), { updateMetadata: false });
196
+ const names = doc.catalog.lookupMaybe(PDFName.of("Names"), PDFDict);
197
+ const root = names?.lookupMaybe(PDFName.of("EmbeddedFiles"), PDFDict);
198
+ if (!root) return null;
199
+ const find = (node) => {
200
+ const pairs = node.lookupMaybe(PDFName.of("Names"), PDFArray);
201
+ if (pairs) {
202
+ for (let i = 0; i + 1 < pairs.size(); i += 2) {
203
+ const key = pairs.lookup(i);
204
+ const text = key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : void 0;
205
+ if (text !== name) continue;
206
+ const spec = pairs.lookup(i + 1, PDFDict);
207
+ const files = spec.lookupMaybe(PDFName.of("EF"), PDFDict);
208
+ const stream = files?.lookup(PDFName.of("F"));
209
+ if (!stream || !(stream instanceof lib.PDFRawStream)) return null;
210
+ return decodePDFRawStream(stream).decode();
211
+ }
212
+ }
213
+ const kids = node.lookupMaybe(PDFName.of("Kids"), PDFArray);
214
+ for (let i = 0; kids && i < kids.size(); i++) {
215
+ const found = find(kids.lookup(i, PDFDict));
216
+ if (found) return found;
217
+ }
218
+ return null;
219
+ };
220
+ return find(root);
221
+ }
222
+ function removeEntries(lib, doc, name) {
223
+ const { PDFName, PDFDict, PDFArray, PDFString, PDFHexString } = lib;
224
+ const root = doc.catalog.lookupMaybe(PDFName.of("Names"), PDFDict)?.lookupMaybe(PDFName.of("EmbeddedFiles"), PDFDict);
225
+ const pairs = root?.lookupMaybe(PDFName.of("Names"), PDFArray);
226
+ if (!pairs) return;
227
+ for (let i = pairs.size() - 2; i >= 0; i -= 2) {
228
+ const key = pairs.lookup(i);
229
+ const text = key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : void 0;
230
+ if (text === name) {
231
+ pairs.remove(i + 1);
232
+ pairs.remove(i);
233
+ }
234
+ }
235
+ }
236
+ async function setPdfAttachment(pdf, attachment) {
237
+ const lib = await import('pdf-lib');
238
+ const doc = await lib.PDFDocument.load(asBytes(pdf), { updateMetadata: false });
239
+ removeEntries(lib, doc, attachment.name);
240
+ const now = /* @__PURE__ */ new Date();
241
+ await doc.attach(new Uint8Array(attachment.data), attachment.name, {
242
+ mimeType: attachment.mimeType,
243
+ description: attachment.description,
244
+ creationDate: now,
245
+ modificationDate: now
246
+ });
247
+ return doc.save();
248
+ }
249
+
149
250
  Object.defineProperty(exports, "DEFAULT_FIELD_SIZE", {
150
251
  enumerable: true,
151
- get: function () { return chunkAJRYZ3IC_cjs.DEFAULT_FIELD_SIZE; }
252
+ get: function () { return chunkK6ELFSG6_cjs.DEFAULT_FIELD_SIZE; }
152
253
  });
153
254
  Object.defineProperty(exports, "FIELD_TYPE_LABELS", {
154
255
  enumerable: true,
155
- get: function () { return chunkAJRYZ3IC_cjs.FIELD_TYPE_LABELS; }
256
+ get: function () { return chunkK6ELFSG6_cjs.FIELD_TYPE_LABELS; }
156
257
  });
157
258
  Object.defineProperty(exports, "INFORMAL_SIGNATURE_NOTE", {
158
259
  enumerable: true,
159
- get: function () { return chunkAJRYZ3IC_cjs.INFORMAL_SIGNATURE_NOTE; }
260
+ get: function () { return chunkK6ELFSG6_cjs.INFORMAL_SIGNATURE_NOTE; }
160
261
  });
161
262
  Object.defineProperty(exports, "LEGACY_LAYER_PREFIX", {
162
263
  enumerable: true,
163
- get: function () { return chunkAJRYZ3IC_cjs.LEGACY_LAYER_PREFIX; }
264
+ get: function () { return chunkK6ELFSG6_cjs.LEGACY_LAYER_PREFIX; }
164
265
  });
165
266
  Object.defineProperty(exports, "MARK_FIELD_TYPES", {
166
267
  enumerable: true,
167
- get: function () { return chunkAJRYZ3IC_cjs.MARK_FIELD_TYPES; }
268
+ get: function () { return chunkK6ELFSG6_cjs.MARK_FIELD_TYPES; }
168
269
  });
169
270
  Object.defineProperty(exports, "MAX_MERGE_ATTEMPTS", {
170
271
  enumerable: true,
171
- get: function () { return chunkAJRYZ3IC_cjs.MAX_MERGE_ATTEMPTS; }
272
+ get: function () { return chunkK6ELFSG6_cjs.MAX_MERGE_ATTEMPTS; }
172
273
  });
173
274
  Object.defineProperty(exports, "MarkupStoreError", {
174
275
  enumerable: true,
175
- get: function () { return chunkAJRYZ3IC_cjs.MarkupStoreError; }
276
+ get: function () { return chunkK6ELFSG6_cjs.MarkupStoreError; }
176
277
  });
177
278
  Object.defineProperty(exports, "SIGNATURE_FIELD_TYPES", {
178
279
  enumerable: true,
179
- get: function () { return chunkAJRYZ3IC_cjs.SIGNATURE_FIELD_TYPES; }
280
+ get: function () { return chunkK6ELFSG6_cjs.SIGNATURE_FIELD_TYPES; }
180
281
  });
181
282
  Object.defineProperty(exports, "SIGNED_UNCHANGED", {
182
283
  enumerable: true,
183
- get: function () { return chunkAJRYZ3IC_cjs.SIGNED_UNCHANGED; }
284
+ get: function () { return chunkK6ELFSG6_cjs.SIGNED_UNCHANGED; }
184
285
  });
185
286
  Object.defineProperty(exports, "SIGNER_PROGRESS_LABELS", {
186
287
  enumerable: true,
187
- get: function () { return chunkAJRYZ3IC_cjs.SIGNER_PROGRESS_LABELS; }
288
+ get: function () { return chunkK6ELFSG6_cjs.SIGNER_PROGRESS_LABELS; }
188
289
  });
189
290
  Object.defineProperty(exports, "SignatureVerificationError", {
190
291
  enumerable: true,
191
- get: function () { return chunkAJRYZ3IC_cjs.SignatureVerificationError; }
292
+ get: function () { return chunkK6ELFSG6_cjs.SignatureVerificationError; }
192
293
  });
193
294
  Object.defineProperty(exports, "SigningError", {
194
295
  enumerable: true,
195
- get: function () { return chunkAJRYZ3IC_cjs.SigningError; }
296
+ get: function () { return chunkK6ELFSG6_cjs.SigningError; }
196
297
  });
197
298
  Object.defineProperty(exports, "VERIFY_PATH", {
198
299
  enumerable: true,
199
- get: function () { return chunkAJRYZ3IC_cjs.VERIFY_PATH; }
300
+ get: function () { return chunkK6ELFSG6_cjs.VERIFY_PATH; }
200
301
  });
201
302
  Object.defineProperty(exports, "addToMarkup", {
202
303
  enumerable: true,
203
- get: function () { return chunkAJRYZ3IC_cjs.addToMarkup; }
304
+ get: function () { return chunkK6ELFSG6_cjs.addToMarkup; }
204
305
  });
205
306
  Object.defineProperty(exports, "canAnnotate", {
206
307
  enumerable: true,
207
- get: function () { return chunkAJRYZ3IC_cjs.canAnnotate; }
308
+ get: function () { return chunkK6ELFSG6_cjs.canAnnotate; }
208
309
  });
209
310
  Object.defineProperty(exports, "copyOpenThreads", {
210
311
  enumerable: true,
211
- get: function () { return chunkAJRYZ3IC_cjs.copyOpenThreads; }
312
+ get: function () { return chunkK6ELFSG6_cjs.copyOpenThreads; }
212
313
  });
213
314
  Object.defineProperty(exports, "createFileShare", {
214
315
  enumerable: true,
215
- get: function () { return chunkAJRYZ3IC_cjs.createFileShare; }
316
+ get: function () { return chunkK6ELFSG6_cjs.createFileShare; }
216
317
  });
217
318
  Object.defineProperty(exports, "createMarkupStore", {
218
319
  enumerable: true,
219
- get: function () { return chunkAJRYZ3IC_cjs.createMarkupStore; }
320
+ get: function () { return chunkK6ELFSG6_cjs.createMarkupStore; }
220
321
  });
221
322
  Object.defineProperty(exports, "deleteSavedSignature", {
222
323
  enumerable: true,
223
- get: function () { return chunkAJRYZ3IC_cjs.deleteSavedSignature; }
324
+ get: function () { return chunkK6ELFSG6_cjs.deleteSavedSignature; }
224
325
  });
225
326
  Object.defineProperty(exports, "fetchDocumentSignatureRequests", {
226
327
  enumerable: true,
227
- get: function () { return chunkAJRYZ3IC_cjs.fetchDocumentSignatureRequests; }
328
+ get: function () { return chunkK6ELFSG6_cjs.fetchDocumentSignatureRequests; }
228
329
  });
229
330
  Object.defineProperty(exports, "fetchDocumentSignatures", {
230
331
  enumerable: true,
231
- get: function () { return chunkAJRYZ3IC_cjs.fetchDocumentSignatures; }
332
+ get: function () { return chunkK6ELFSG6_cjs.fetchDocumentSignatures; }
232
333
  });
233
334
  Object.defineProperty(exports, "fetchSavedSignature", {
234
335
  enumerable: true,
235
- get: function () { return chunkAJRYZ3IC_cjs.fetchSavedSignature; }
336
+ get: function () { return chunkK6ELFSG6_cjs.fetchSavedSignature; }
236
337
  });
237
338
  Object.defineProperty(exports, "fetchSignatureVerification", {
238
339
  enumerable: true,
239
- get: function () { return chunkAJRYZ3IC_cjs.fetchSignatureVerification; }
340
+ get: function () { return chunkK6ELFSG6_cjs.fetchSignatureVerification; }
240
341
  });
241
342
  Object.defineProperty(exports, "fieldsFromSuggestions", {
242
343
  enumerable: true,
243
- get: function () { return chunkAJRYZ3IC_cjs.fieldsFromSuggestions; }
344
+ get: function () { return chunkK6ELFSG6_cjs.fieldsFromSuggestions; }
244
345
  });
245
346
  Object.defineProperty(exports, "fieldsInSigningOrder", {
246
347
  enumerable: true,
247
- get: function () { return chunkAJRYZ3IC_cjs.fieldsInSigningOrder; }
348
+ get: function () { return chunkK6ELFSG6_cjs.fieldsInSigningOrder; }
248
349
  });
249
350
  Object.defineProperty(exports, "fileShareBytes", {
250
351
  enumerable: true,
251
- get: function () { return chunkAJRYZ3IC_cjs.fileShareBytes; }
352
+ get: function () { return chunkK6ELFSG6_cjs.fileShareBytes; }
252
353
  });
253
354
  Object.defineProperty(exports, "fileShareSigningRequest", {
254
355
  enumerable: true,
255
- get: function () { return chunkAJRYZ3IC_cjs.fileShareSigningRequest; }
356
+ get: function () { return chunkK6ELFSG6_cjs.fileShareSigningRequest; }
256
357
  });
257
358
  Object.defineProperty(exports, "forgetLegacyLayer", {
258
359
  enumerable: true,
259
- get: function () { return chunkAJRYZ3IC_cjs.forgetLegacyLayer; }
360
+ get: function () { return chunkK6ELFSG6_cjs.forgetLegacyLayer; }
260
361
  });
261
362
  Object.defineProperty(exports, "frozenCopyName", {
262
363
  enumerable: true,
263
- get: function () { return chunkAJRYZ3IC_cjs.frozenCopyName; }
364
+ get: function () { return chunkK6ELFSG6_cjs.frozenCopyName; }
264
365
  });
265
366
  Object.defineProperty(exports, "getFileShare", {
266
367
  enumerable: true,
267
- get: function () { return chunkAJRYZ3IC_cjs.getFileShare; }
368
+ get: function () { return chunkK6ELFSG6_cjs.getFileShare; }
268
369
  });
269
370
  Object.defineProperty(exports, "initialsOf", {
270
371
  enumerable: true,
271
- get: function () { return chunkAJRYZ3IC_cjs.initialsOf; }
372
+ get: function () { return chunkK6ELFSG6_cjs.initialsOf; }
272
373
  });
273
374
  Object.defineProperty(exports, "intentText", {
274
375
  enumerable: true,
275
- get: function () { return chunkAJRYZ3IC_cjs.intentText; }
376
+ get: function () { return chunkK6ELFSG6_cjs.intentText; }
276
377
  });
277
378
  Object.defineProperty(exports, "inviteSigners", {
278
379
  enumerable: true,
279
- get: function () { return chunkAJRYZ3IC_cjs.inviteSigners; }
380
+ get: function () { return chunkK6ELFSG6_cjs.inviteSigners; }
280
381
  });
281
382
  Object.defineProperty(exports, "isEmailSigner", {
282
383
  enumerable: true,
283
- get: function () { return chunkAJRYZ3IC_cjs.isEmailSigner; }
384
+ get: function () { return chunkK6ELFSG6_cjs.isEmailSigner; }
284
385
  });
285
386
  Object.defineProperty(exports, "isLegibleSignatureBox", {
286
387
  enumerable: true,
287
- get: function () { return chunkAJRYZ3IC_cjs.isLegibleSignatureBox; }
388
+ get: function () { return chunkK6ELFSG6_cjs.isLegibleSignatureBox; }
288
389
  });
289
390
  Object.defineProperty(exports, "isSignatureReference", {
290
391
  enumerable: true,
291
- get: function () { return chunkAJRYZ3IC_cjs.isSignatureReference; }
392
+ get: function () { return chunkK6ELFSG6_cjs.isSignatureReference; }
292
393
  });
293
394
  Object.defineProperty(exports, "marksByVersion", {
294
395
  enumerable: true,
295
- get: function () { return chunkAJRYZ3IC_cjs.marksByVersion; }
396
+ get: function () { return chunkK6ELFSG6_cjs.marksByVersion; }
296
397
  });
297
398
  Object.defineProperty(exports, "matchSignedCopy", {
298
399
  enumerable: true,
299
- get: function () { return chunkAJRYZ3IC_cjs.matchSignedCopy; }
400
+ get: function () { return chunkK6ELFSG6_cjs.matchSignedCopy; }
300
401
  });
301
402
  Object.defineProperty(exports, "migrateLegacyLayer", {
302
403
  enumerable: true,
303
- get: function () { return chunkAJRYZ3IC_cjs.migrateLegacyLayer; }
404
+ get: function () { return chunkK6ELFSG6_cjs.migrateLegacyLayer; }
304
405
  });
305
406
  Object.defineProperty(exports, "newFieldId", {
306
407
  enumerable: true,
307
- get: function () { return chunkAJRYZ3IC_cjs.newFieldId; }
408
+ get: function () { return chunkK6ELFSG6_cjs.newFieldId; }
308
409
  });
309
410
  Object.defineProperty(exports, "openThreadsOf", {
310
411
  enumerable: true,
311
- get: function () { return chunkAJRYZ3IC_cjs.openThreadsOf; }
412
+ get: function () { return chunkK6ELFSG6_cjs.openThreadsOf; }
312
413
  });
313
414
  Object.defineProperty(exports, "pngBytes", {
314
415
  enumerable: true,
315
- get: function () { return chunkAJRYZ3IC_cjs.pngBytes; }
416
+ get: function () { return chunkK6ELFSG6_cjs.pngBytes; }
316
417
  });
317
418
  Object.defineProperty(exports, "pngSize", {
318
419
  enumerable: true,
319
- get: function () { return chunkAJRYZ3IC_cjs.pngSize; }
420
+ get: function () { return chunkK6ELFSG6_cjs.pngSize; }
320
421
  });
321
422
  Object.defineProperty(exports, "readLegacyLayer", {
322
423
  enumerable: true,
323
- get: function () { return chunkAJRYZ3IC_cjs.readLegacyLayer; }
424
+ get: function () { return chunkK6ELFSG6_cjs.readLegacyLayer; }
324
425
  });
325
426
  Object.defineProperty(exports, "redactionLogName", {
326
427
  enumerable: true,
327
- get: function () { return chunkAJRYZ3IC_cjs.redactionLogName; }
428
+ get: function () { return chunkK6ELFSG6_cjs.redactionLogName; }
328
429
  });
329
430
  Object.defineProperty(exports, "saveSignatureRequest", {
330
431
  enumerable: true,
331
- get: function () { return chunkAJRYZ3IC_cjs.saveSignatureRequest; }
432
+ get: function () { return chunkK6ELFSG6_cjs.saveSignatureRequest; }
332
433
  });
333
434
  Object.defineProperty(exports, "sendBlocker", {
334
435
  enumerable: true,
335
- get: function () { return chunkAJRYZ3IC_cjs.sendBlocker; }
436
+ get: function () { return chunkK6ELFSG6_cjs.sendBlocker; }
336
437
  });
337
438
  Object.defineProperty(exports, "sha256Hex", {
338
439
  enumerable: true,
339
- get: function () { return chunkAJRYZ3IC_cjs.sha256Hex; }
440
+ get: function () { return chunkK6ELFSG6_cjs.sha256Hex; }
340
441
  });
341
442
  Object.defineProperty(exports, "signDocument", {
342
443
  enumerable: true,
343
- get: function () { return chunkAJRYZ3IC_cjs.signDocument; }
444
+ get: function () { return chunkK6ELFSG6_cjs.signDocument; }
344
445
  });
345
446
  Object.defineProperty(exports, "signFileShare", {
346
447
  enumerable: true,
347
- get: function () { return chunkAJRYZ3IC_cjs.signFileShare; }
448
+ get: function () { return chunkK6ELFSG6_cjs.signFileShare; }
348
449
  });
349
450
  Object.defineProperty(exports, "signSignatureRequest", {
350
451
  enumerable: true,
351
- get: function () { return chunkAJRYZ3IC_cjs.signSignatureRequest; }
452
+ get: function () { return chunkK6ELFSG6_cjs.signSignatureRequest; }
352
453
  });
353
454
  Object.defineProperty(exports, "signatureFieldSuggestions", {
354
455
  enumerable: true,
355
- get: function () { return chunkAJRYZ3IC_cjs.signatureFieldSuggestions; }
456
+ get: function () { return chunkK6ELFSG6_cjs.signatureFieldSuggestions; }
356
457
  });
357
458
  Object.defineProperty(exports, "splitSuggestions", {
358
459
  enumerable: true,
359
- get: function () { return chunkAJRYZ3IC_cjs.splitSuggestions; }
460
+ get: function () { return chunkK6ELFSG6_cjs.splitSuggestions; }
360
461
  });
361
462
  Object.defineProperty(exports, "storeSavedSignature", {
362
463
  enumerable: true,
363
- get: function () { return chunkAJRYZ3IC_cjs.storeSavedSignature; }
464
+ get: function () { return chunkK6ELFSG6_cjs.storeSavedSignature; }
364
465
  });
365
466
  Object.defineProperty(exports, "suggestSignatureFields", {
366
467
  enumerable: true,
367
- get: function () { return chunkAJRYZ3IC_cjs.suggestSignatureFields; }
468
+ get: function () { return chunkK6ELFSG6_cjs.suggestSignatureFields; }
368
469
  });
369
470
  Object.defineProperty(exports, "toAppearance", {
370
471
  enumerable: true,
371
- get: function () { return chunkAJRYZ3IC_cjs.toAppearance; }
472
+ get: function () { return chunkK6ELFSG6_cjs.toAppearance; }
372
473
  });
373
474
  Object.defineProperty(exports, "uploadFrozenCopy", {
374
475
  enumerable: true,
375
- get: function () { return chunkAJRYZ3IC_cjs.uploadFrozenCopy; }
476
+ get: function () { return chunkK6ELFSG6_cjs.uploadFrozenCopy; }
376
477
  });
377
478
  Object.defineProperty(exports, "useDeclineSignatureRequest", {
378
479
  enumerable: true,
379
- get: function () { return chunkAJRYZ3IC_cjs.useDeclineSignatureRequest; }
480
+ get: function () { return chunkK6ELFSG6_cjs.useDeclineSignatureRequest; }
380
481
  });
381
482
  Object.defineProperty(exports, "useDeleteSavedSignature", {
382
483
  enumerable: true,
383
- get: function () { return chunkAJRYZ3IC_cjs.useDeleteSavedSignature; }
484
+ get: function () { return chunkK6ELFSG6_cjs.useDeleteSavedSignature; }
384
485
  });
385
486
  Object.defineProperty(exports, "useDocumentBytes", {
386
487
  enumerable: true,
387
- get: function () { return chunkAJRYZ3IC_cjs.useDocumentBytes; }
488
+ get: function () { return chunkK6ELFSG6_cjs.useDocumentBytes; }
388
489
  });
389
490
  Object.defineProperty(exports, "useDocumentMarkup", {
390
491
  enumerable: true,
391
- get: function () { return chunkAJRYZ3IC_cjs.useDocumentMarkup; }
492
+ get: function () { return chunkK6ELFSG6_cjs.useDocumentMarkup; }
392
493
  });
393
494
  Object.defineProperty(exports, "useDocumentSignatureRequests", {
394
495
  enumerable: true,
395
- get: function () { return chunkAJRYZ3IC_cjs.useDocumentSignatureRequests; }
496
+ get: function () { return chunkK6ELFSG6_cjs.useDocumentSignatureRequests; }
396
497
  });
397
498
  Object.defineProperty(exports, "useDocumentSignatures", {
398
499
  enumerable: true,
399
- get: function () { return chunkAJRYZ3IC_cjs.useDocumentSignatures; }
500
+ get: function () { return chunkK6ELFSG6_cjs.useDocumentSignatures; }
400
501
  });
401
502
  Object.defineProperty(exports, "useFileShare", {
402
503
  enumerable: true,
403
- get: function () { return chunkAJRYZ3IC_cjs.useFileShare; }
504
+ get: function () { return chunkK6ELFSG6_cjs.useFileShare; }
404
505
  });
405
506
  Object.defineProperty(exports, "useFileSharePdf", {
406
507
  enumerable: true,
407
- get: function () { return chunkAJRYZ3IC_cjs.useFileSharePdf; }
508
+ get: function () { return chunkK6ELFSG6_cjs.useFileSharePdf; }
408
509
  });
409
510
  Object.defineProperty(exports, "useFileShares", {
410
511
  enumerable: true,
411
- get: function () { return chunkAJRYZ3IC_cjs.useFileShares; }
512
+ get: function () { return chunkK6ELFSG6_cjs.useFileShares; }
412
513
  });
413
514
  Object.defineProperty(exports, "useInviteSigners", {
414
515
  enumerable: true,
415
- get: function () { return chunkAJRYZ3IC_cjs.useInviteSigners; }
516
+ get: function () { return chunkK6ELFSG6_cjs.useInviteSigners; }
416
517
  });
417
518
  Object.defineProperty(exports, "useIsOnline", {
418
519
  enumerable: true,
419
- get: function () { return chunkAJRYZ3IC_cjs.useIsOnline; }
520
+ get: function () { return chunkK6ELFSG6_cjs.useIsOnline; }
420
521
  });
421
522
  Object.defineProperty(exports, "useSaveSignatureRequest", {
422
523
  enumerable: true,
423
- get: function () { return chunkAJRYZ3IC_cjs.useSaveSignatureRequest; }
524
+ get: function () { return chunkK6ELFSG6_cjs.useSaveSignatureRequest; }
424
525
  });
425
526
  Object.defineProperty(exports, "useSavedSignature", {
426
527
  enumerable: true,
427
- get: function () { return chunkAJRYZ3IC_cjs.useSavedSignature; }
528
+ get: function () { return chunkK6ELFSG6_cjs.useSavedSignature; }
428
529
  });
429
530
  Object.defineProperty(exports, "useSignDocument", {
430
531
  enumerable: true,
431
- get: function () { return chunkAJRYZ3IC_cjs.useSignDocument; }
532
+ get: function () { return chunkK6ELFSG6_cjs.useSignDocument; }
432
533
  });
433
534
  Object.defineProperty(exports, "useSignSignatureRequest", {
434
535
  enumerable: true,
435
- get: function () { return chunkAJRYZ3IC_cjs.useSignSignatureRequest; }
536
+ get: function () { return chunkK6ELFSG6_cjs.useSignSignatureRequest; }
436
537
  });
437
538
  Object.defineProperty(exports, "useSignatureVerification", {
438
539
  enumerable: true,
439
- get: function () { return chunkAJRYZ3IC_cjs.useSignatureVerification; }
540
+ get: function () { return chunkK6ELFSG6_cjs.useSignatureVerification; }
440
541
  });
441
542
  Object.defineProperty(exports, "useSignerCandidates", {
442
543
  enumerable: true,
443
- get: function () { return chunkAJRYZ3IC_cjs.useSignerCandidates; }
544
+ get: function () { return chunkK6ELFSG6_cjs.useSignerCandidates; }
444
545
  });
445
546
  Object.defineProperty(exports, "useStoreSavedSignature", {
446
547
  enumerable: true,
447
- get: function () { return chunkAJRYZ3IC_cjs.useStoreSavedSignature; }
548
+ get: function () { return chunkK6ELFSG6_cjs.useStoreSavedSignature; }
448
549
  });
449
550
  Object.defineProperty(exports, "useVoidSignatureRequest", {
450
551
  enumerable: true,
451
- get: function () { return chunkAJRYZ3IC_cjs.useVoidSignatureRequest; }
552
+ get: function () { return chunkK6ELFSG6_cjs.useVoidSignatureRequest; }
452
553
  });
453
554
  Object.defineProperty(exports, "versionsWithMarkup", {
454
555
  enumerable: true,
455
- get: function () { return chunkAJRYZ3IC_cjs.versionsWithMarkup; }
556
+ get: function () { return chunkK6ELFSG6_cjs.versionsWithMarkup; }
456
557
  });
457
558
  Object.defineProperty(exports, "DocumentFetchError", {
458
559
  enumerable: true,
@@ -530,12 +631,15 @@ exports.PRODUCTIONS_FOLDER = PRODUCTIONS_FOLDER;
530
631
  exports.buildProduction = buildProduction;
531
632
  exports.fetchProductionPdf = fetchProductionPdf;
532
633
  exports.hasNoRendition = hasNoRendition;
634
+ exports.imagesToPdf = imagesToPdf;
533
635
  exports.isPdfDocument = isPdfDocument;
534
636
  exports.productionDocumentName = productionDocumentName;
535
637
  exports.productionFileName = productionFileName;
536
638
  exports.productionFolder = productionFolder;
537
639
  exports.productionIndexCsv = productionIndexCsv;
538
640
  exports.productionTitle = productionTitle;
641
+ exports.readPdfAttachment = readPdfAttachment;
539
642
  exports.saveProductionFiles = saveProductionFiles;
643
+ exports.setPdfAttachment = setPdfAttachment;
540
644
  //# sourceMappingURL=index.cjs.map
541
645
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/document-tools/production.ts"],"names":["fetchDocumentFile","fetchDocumentPdf","DocumentFetchError"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Production sets: number the selected documents with Bates labels (optionally a QR code back to\n * each document and an index page) and save the result back to the workspace. The dialog is\n * `ProductionSetDialog` in `@arbidocs/blocks/document-tools`; this is its data side.\n *\n * A PDF is numbered as stored (`/download`). Any other document is numbered through its PDF\n * rendition (`/view`, what the viewer shows for a Word or text file); one without a rendition is\n * left out. Saved results are new documents derived from their sources (role `production`) in a\n * Productions folder, shared with the workspace only if every source is. The originals never\n * change.\n *\n * pdf-lib (the numbering) is loaded only when a production is built, so importing this module\n * stays as light as the rest of the document tools.\n */\n\nimport type { components } from '@arbidocs/client'\nimport type { ProductionChoices } from '../annotations/ProductionDialog'\nimport type { BundleFile, BundleIndexEntry, BundleItem } from '../annotations/freeze/bundle'\nimport { DocumentFetchError, fetchDocumentFile, fetchDocumentPdf } from './document-pdf'\nimport type {\n DocumentToolsClient,\n DocumentToolsEnvironment,\n DocumentUploadQuery,\n} from './environment'\n\n/** The fields of a document record (`DocResponse`) a production uses. */\nexport type ProductionSource = Pick<\n components['schemas']['DocResponse'],\n 'external_id' | 'file_name' | 'file_type' | 'shared'\n> & {\n doc_metadata?: { title?: string | null } | null\n /** The document's workspace: the produced files are saved there, named on the upload. */\n workspace_ext_id?: string | null\n}\n\nexport const PRODUCTIONS_FOLDER = 'Productions'\n\nconst extensionOf = (fileName: string | null | undefined) => {\n const name = (fileName ?? '').toLowerCase()\n const dot = name.lastIndexOf('.')\n return dot < 0 ? '' : name.slice(dot + 1)\n}\n\n/** Media, archives and design files: no PDF version to number. */\nconst NO_RENDITION_EXTENSIONS = new Set(\n [\n // images\n 'jpg jpeg png gif bmp tiff tif webp heic',\n // video and audio\n 'mp4 mpeg mpg webm mov avi mkv mp3 wav m4a aac ogg flac',\n // archives, binaries, design files\n 'zip rar 7z tar gz exe bin dmg iso apk msi dll so psd ai sketch',\n ]\n .join(' ')\n .split(' ')\n)\n\nexport const isPdfDocument = (doc: ProductionSource) =>\n /pdf/i.test(doc.file_type ?? '') || extensionOf(doc.file_name) === 'pdf'\n\n/** True for a document with no PDF version to number (media, archives and the like). */\nexport const hasNoRendition = (doc: ProductionSource) =>\n !isPdfDocument(doc) && NO_RENDITION_EXTENSIONS.has(extensionOf(doc.file_name))\n\n/** The name a document goes by in the dialog and the index: its title, else its file name. */\nexport const productionDocumentName = (doc: ProductionSource) =>\n doc.doc_metadata?.title || doc.file_name || doc.external_id\n\nconst isPdfBytes = (bytes: Uint8Array) =>\n bytes.length > 4 && String.fromCharCode(...bytes.subarray(0, 5)) === '%PDF-'\n\n/**\n * The PDF to number for `doc`: the file itself, or the PDF version of anything else. `null` when a\n * non-PDF has no PDF version (yet), so it is left out; a PDF that cannot be downloaded throws.\n */\nexport async function fetchProductionPdf(\n client: DocumentToolsClient,\n doc: ProductionSource\n): Promise<Uint8Array | null> {\n const pdf = isPdfDocument(doc)\n let blob: Blob\n try {\n blob = await (pdf ? fetchDocumentFile : fetchDocumentPdf)(client, doc.external_id)\n } catch (e) {\n if (!pdf && e instanceof DocumentFetchError) return null\n throw e\n }\n const bytes = new Uint8Array(await blob.arrayBuffer())\n return pdf || isPdfBytes(bytes) ? bytes : null\n}\n\nconst safeName = (name: string) => name.replace(/[\\\\/:*?\"<>|]+/g, '_').trim()\n\n/** \"Production ACME-000001-ACME-000042\": names the files and folder of one production. */\nexport function productionTitle(firstLabel: string, lastLabel: string): string {\n return safeName(`Production ${firstLabel}-${lastLabel}`)\n}\n\n/** Where a production is saved: the Productions folder, or a folder of its own per document. */\nexport function productionFolder(title: string, merged: boolean): string {\n return merged ? PRODUCTIONS_FOLDER : `${PRODUCTIONS_FOLDER}/${title}`\n}\n\n/** In the workspace a per-document file says which range it holds, beside its original. */\nexport function productionFileName(file: BundleFile, title: string): string {\n if (!file.firstLabel) return `${title} index.pdf`\n return `${file.name.replace(/\\.pdf$/i, '')} (${file.firstLabel}-${file.lastLabel}).pdf`\n}\n\nconst csvCell = (value: string | number) => `\"${String(value).replace(/\"/g, '\"\"')}\"`\n\n/** The `index.csv` of a per-document production: every document with its file and range. */\nexport function productionIndexCsv(index: readonly BundleIndexEntry[]): string {\n const rows = index.map((e) =>\n [e.documentId, e.name, e.file, e.pages, e.firstLabel, e.lastLabel].map(csvCell).join(',')\n )\n return ['document_id,name,file,pages,first_label,last_label', ...rows].join('\\n')\n}\n\nexport interface ProductionUpload {\n name: string\n bytes: Uint8Array\n /** The documents this file was made from. */\n sources: ProductionSource[]\n}\n\n/** Save each file as a new workspace document derived from its sources; returns the new ids. */\nexport async function saveProductionFiles(\n upload: NonNullable<DocumentToolsEnvironment['uploadDocument']>,\n files: readonly ProductionUpload[],\n folder: string\n): Promise<string[]> {\n const ids: string[] = []\n for (const file of files) {\n const query: DocumentUploadQuery = {\n derived_from: file.sources.map((doc) => doc.external_id),\n derived_role: 'production',\n shared: file.sources.every((doc) => doc.shared),\n folder,\n }\n // Saved in the sources' workspace, named on the upload (never whichever one is open now).\n const workspaces = new Set(file.sources.map((doc) => doc.workspace_ext_id).filter(Boolean))\n if (workspaces.size === 1) query.workspace_ext_id = [...workspaces][0]\n const response = await upload({\n file: new File([file.bytes as BlobPart], file.name, { type: 'application/pdf' }),\n query,\n })\n ids.push(...(response?.doc_ext_ids ?? []))\n }\n return ids\n}\n\nexport interface BuildProductionOptions {\n /** The link a document's QR code opens (the document in the host app). */\n documentUrl: (documentId: string) => string\n /** Who produced the set; recorded in a merged file's metadata. */\n author?: string\n onProgress?: (done: number, total: number) => void\n}\n\nexport interface BuiltProduction {\n title: string\n merged: boolean\n /** The numbered files: one merged PDF (named after its range), or one per document (+ index). */\n files: BundleFile[]\n index: BundleIndexEntry[]\n /** The documents numbered, in order. */\n included: ProductionSource[]\n /** Documents left out because they have no PDF version yet. */\n noRendition: ProductionSource[]\n /** The files as they are saved to the workspace, each with the documents it was made from. */\n uploads: ProductionUpload[]\n folder: string\n}\n\n/**\n * Fetch each document's PDF (in `choices.order`) and number the set. Throws when none of the\n * documents has a PDF version, or when a PDF cannot be fetched.\n */\nexport async function buildProduction(\n client: DocumentToolsClient,\n documents: readonly ProductionSource[],\n choices: ProductionChoices,\n options: BuildProductionOptions\n): Promise<BuiltProduction> {\n const byId = new Map(documents.map((doc) => [doc.external_id, doc]))\n const included: ProductionSource[] = []\n const noRendition: ProductionSource[] = []\n const items: BundleItem[] = []\n for (const doc of choices.order.flatMap((id) => byId.get(id) ?? [])) {\n const bytes = await fetchProductionPdf(client, doc)\n if (!bytes) {\n noRendition.push(doc)\n continue\n }\n included.push(doc)\n items.push({\n name: productionDocumentName(doc),\n documentId: doc.external_id,\n bytes,\n qrUrl: options.documentUrl(doc.external_id),\n })\n }\n if (items.length === 0) {\n throw new Error('None of these documents has a PDF version to number yet.')\n }\n\n const { buildBundle } = await import('../annotations/freeze/bundle')\n const result = await buildBundle(items, {\n layout: choices.layout,\n bates: {\n prefix: choices.prefix,\n start: choices.start,\n digits: choices.digits,\n corner: choices.corner,\n },\n qr: choices.qr,\n // The QR code sits in the bottom corner the label is not in.\n qrCorner: choices.corner.endsWith('left') ? 'bottom-right' : 'bottom-left',\n indexPage: choices.indexPage,\n author: options.author,\n onProgress: options.onProgress,\n })\n\n const title = productionTitle(\n result.index[0].firstLabel,\n result.index[result.index.length - 1].lastLabel\n )\n const merged = choices.layout === 'merged'\n // A merged file is named after its range; per-document files keep their document names.\n const files = merged ? [{ ...result.files[0], name: `${title}.pdf` }] : result.files\n const sourceOf = new Map(result.index.map((e) => [e.file, byId.get(e.documentId)!]))\n const uploads = files.map((file) => ({\n name: merged ? file.name : productionFileName(file, title),\n bytes: file.bytes,\n // The merged file (and a separate index) is made from every document; each per-document\n // file from its own.\n sources: merged || !sourceOf.has(file.name) ? included : [sourceOf.get(file.name)!],\n }))\n return {\n title,\n merged,\n files,\n index: result.index,\n included,\n noRendition,\n uploads,\n folder: productionFolder(title, merged),\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/document-tools/production.ts","../../src/document-tools/images-to-pdf.ts","../../src/document-tools/pdf-attachments.ts"],"names":["fetchDocumentFile","fetchDocumentPdf","DocumentFetchError"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Production sets: number the selected documents with Bates labels (optionally a QR code back to\n * each document and an index page) and save the result back to the workspace. The dialog is\n * `ProductionSetDialog` in `@arbidocs/blocks/document-tools`; this is its data side.\n *\n * A PDF is numbered as stored (`/download`). Any other document is numbered through its PDF\n * rendition (`/view`, what the viewer shows for a Word or text file); one without a rendition is\n * left out. Saved results are new documents derived from their sources (role `production`) in a\n * Productions folder, shared with the workspace only if every source is. The originals never\n * change.\n *\n * pdf-lib (the numbering) is loaded only when a production is built, so importing this module\n * stays as light as the rest of the document tools.\n */\n\nimport type { components } from '@arbidocs/client'\nimport type { ProductionChoices } from '../annotations/ProductionDialog'\nimport type { BundleFile, BundleIndexEntry, BundleItem } from '../annotations/freeze/bundle'\nimport { DocumentFetchError, fetchDocumentFile, fetchDocumentPdf } from './document-pdf'\nimport type {\n DocumentToolsClient,\n DocumentToolsEnvironment,\n DocumentUploadQuery,\n} from './environment'\n\n/** The fields of a document record (`DocResponse`) a production uses. */\nexport type ProductionSource = Pick<\n components['schemas']['DocResponse'],\n 'external_id' | 'file_name' | 'file_type' | 'shared'\n> & {\n doc_metadata?: { title?: string | null } | null\n /** The document's workspace: the produced files are saved there, named on the upload. */\n workspace_ext_id?: string | null\n}\n\nexport const PRODUCTIONS_FOLDER = 'Productions'\n\nconst extensionOf = (fileName: string | null | undefined) => {\n const name = (fileName ?? '').toLowerCase()\n const dot = name.lastIndexOf('.')\n return dot < 0 ? '' : name.slice(dot + 1)\n}\n\n/** Media, archives and design files: no PDF version to number. */\nconst NO_RENDITION_EXTENSIONS = new Set(\n [\n // images\n 'jpg jpeg png gif bmp tiff tif webp heic',\n // video and audio\n 'mp4 mpeg mpg webm mov avi mkv mp3 wav m4a aac ogg flac',\n // archives, binaries, design files\n 'zip rar 7z tar gz exe bin dmg iso apk msi dll so psd ai sketch',\n ]\n .join(' ')\n .split(' ')\n)\n\nexport const isPdfDocument = (doc: ProductionSource) =>\n /pdf/i.test(doc.file_type ?? '') || extensionOf(doc.file_name) === 'pdf'\n\n/** True for a document with no PDF version to number (media, archives and the like). */\nexport const hasNoRendition = (doc: ProductionSource) =>\n !isPdfDocument(doc) && NO_RENDITION_EXTENSIONS.has(extensionOf(doc.file_name))\n\n/** The name a document goes by in the dialog and the index: its title, else its file name. */\nexport const productionDocumentName = (doc: ProductionSource) =>\n doc.doc_metadata?.title || doc.file_name || doc.external_id\n\nconst isPdfBytes = (bytes: Uint8Array) =>\n bytes.length > 4 && String.fromCharCode(...bytes.subarray(0, 5)) === '%PDF-'\n\n/**\n * The PDF to number for `doc`: the file itself, or the PDF version of anything else. `null` when a\n * non-PDF has no PDF version (yet), so it is left out; a PDF that cannot be downloaded throws.\n */\nexport async function fetchProductionPdf(\n client: DocumentToolsClient,\n doc: ProductionSource\n): Promise<Uint8Array | null> {\n const pdf = isPdfDocument(doc)\n let blob: Blob\n try {\n blob = await (pdf ? fetchDocumentFile : fetchDocumentPdf)(client, doc.external_id)\n } catch (e) {\n if (!pdf && e instanceof DocumentFetchError) return null\n throw e\n }\n const bytes = new Uint8Array(await blob.arrayBuffer())\n return pdf || isPdfBytes(bytes) ? bytes : null\n}\n\nconst safeName = (name: string) => name.replace(/[\\\\/:*?\"<>|]+/g, '_').trim()\n\n/** \"Production ACME-000001-ACME-000042\": names the files and folder of one production. */\nexport function productionTitle(firstLabel: string, lastLabel: string): string {\n return safeName(`Production ${firstLabel}-${lastLabel}`)\n}\n\n/** Where a production is saved: the Productions folder, or a folder of its own per document. */\nexport function productionFolder(title: string, merged: boolean): string {\n return merged ? PRODUCTIONS_FOLDER : `${PRODUCTIONS_FOLDER}/${title}`\n}\n\n/** In the workspace a per-document file says which range it holds, beside its original. */\nexport function productionFileName(file: BundleFile, title: string): string {\n if (!file.firstLabel) return `${title} index.pdf`\n return `${file.name.replace(/\\.pdf$/i, '')} (${file.firstLabel}-${file.lastLabel}).pdf`\n}\n\nconst csvCell = (value: string | number) => `\"${String(value).replace(/\"/g, '\"\"')}\"`\n\n/** The `index.csv` of a per-document production: every document with its file and range. */\nexport function productionIndexCsv(index: readonly BundleIndexEntry[]): string {\n const rows = index.map((e) =>\n [e.documentId, e.name, e.file, e.pages, e.firstLabel, e.lastLabel].map(csvCell).join(',')\n )\n return ['document_id,name,file,pages,first_label,last_label', ...rows].join('\\n')\n}\n\nexport interface ProductionUpload {\n name: string\n bytes: Uint8Array\n /** The documents this file was made from. */\n sources: ProductionSource[]\n}\n\n/** Save each file as a new workspace document derived from its sources; returns the new ids. */\nexport async function saveProductionFiles(\n upload: NonNullable<DocumentToolsEnvironment['uploadDocument']>,\n files: readonly ProductionUpload[],\n folder: string\n): Promise<string[]> {\n const ids: string[] = []\n for (const file of files) {\n const query: DocumentUploadQuery = {\n derived_from: file.sources.map((doc) => doc.external_id),\n derived_role: 'production',\n shared: file.sources.every((doc) => doc.shared),\n folder,\n }\n // Saved in the sources' workspace, named on the upload (never whichever one is open now).\n const workspaces = new Set(file.sources.map((doc) => doc.workspace_ext_id).filter(Boolean))\n if (workspaces.size === 1) query.workspace_ext_id = [...workspaces][0]\n const response = await upload({\n file: new File([file.bytes as BlobPart], file.name, { type: 'application/pdf' }),\n query,\n })\n ids.push(...(response?.doc_ext_ids ?? []))\n }\n return ids\n}\n\nexport interface BuildProductionOptions {\n /** The link a document's QR code opens (the document in the host app). */\n documentUrl: (documentId: string) => string\n /** Who produced the set; recorded in a merged file's metadata. */\n author?: string\n onProgress?: (done: number, total: number) => void\n}\n\nexport interface BuiltProduction {\n title: string\n merged: boolean\n /** The numbered files: one merged PDF (named after its range), or one per document (+ index). */\n files: BundleFile[]\n index: BundleIndexEntry[]\n /** The documents numbered, in order. */\n included: ProductionSource[]\n /** Documents left out because they have no PDF version yet. */\n noRendition: ProductionSource[]\n /** The files as they are saved to the workspace, each with the documents it was made from. */\n uploads: ProductionUpload[]\n folder: string\n}\n\n/**\n * Fetch each document's PDF (in `choices.order`) and number the set. Throws when none of the\n * documents has a PDF version, or when a PDF cannot be fetched.\n */\nexport async function buildProduction(\n client: DocumentToolsClient,\n documents: readonly ProductionSource[],\n choices: ProductionChoices,\n options: BuildProductionOptions\n): Promise<BuiltProduction> {\n const byId = new Map(documents.map((doc) => [doc.external_id, doc]))\n const included: ProductionSource[] = []\n const noRendition: ProductionSource[] = []\n const items: BundleItem[] = []\n for (const doc of choices.order.flatMap((id) => byId.get(id) ?? [])) {\n const bytes = await fetchProductionPdf(client, doc)\n if (!bytes) {\n noRendition.push(doc)\n continue\n }\n included.push(doc)\n items.push({\n name: productionDocumentName(doc),\n documentId: doc.external_id,\n bytes,\n qrUrl: options.documentUrl(doc.external_id),\n })\n }\n if (items.length === 0) {\n throw new Error('None of these documents has a PDF version to number yet.')\n }\n\n const { buildBundle } = await import('../annotations/freeze/bundle')\n const result = await buildBundle(items, {\n layout: choices.layout,\n bates: {\n prefix: choices.prefix,\n start: choices.start,\n digits: choices.digits,\n corner: choices.corner,\n },\n qr: choices.qr,\n // The QR code sits in the bottom corner the label is not in.\n qrCorner: choices.corner.endsWith('left') ? 'bottom-right' : 'bottom-left',\n indexPage: choices.indexPage,\n author: options.author,\n onProgress: options.onProgress,\n })\n\n const title = productionTitle(\n result.index[0].firstLabel,\n result.index[result.index.length - 1].lastLabel\n )\n const merged = choices.layout === 'merged'\n // A merged file is named after its range; per-document files keep their document names.\n const files = merged ? [{ ...result.files[0], name: `${title}.pdf` }] : result.files\n const sourceOf = new Map(result.index.map((e) => [e.file, byId.get(e.documentId)!]))\n const uploads = files.map((file) => ({\n name: merged ? file.name : productionFileName(file, title),\n bytes: file.bytes,\n // The merged file (and a separate index) is made from every document; each per-document\n // file from its own.\n sources: merged || !sourceOf.has(file.name) ? included : [sourceOf.get(file.name)!],\n }))\n return {\n title,\n merged,\n files,\n index: result.index,\n included,\n noRendition,\n uploads,\n folder: productionFolder(title, merged),\n }\n}\n","/**\n * Page images to a PDF: one page per image, the image filling it, and the page's text laid on it\n * invisibly so the PDF is searchable (a presentation's slides: what shows is exactly the image,\n * redactions burnt in, while their titles and labels can still be found). pdf-lib is loaded on\n * first use. Files can be attached to it (`meta.attachments`; see `pdf-attachments`).\n */\n\nimport type { PdfAttachment } from './pdf-attachments'\n\nexport interface PdfImagePage {\n /** A JPEG or PNG. */\n image: Blob\n /** The page size, in PDF points. */\n width: number\n height: number\n /** Text on the page, laid on it invisibly for search. */\n text?: readonly string[]\n}\n\nexport async function imagesToPdf(\n pages: readonly PdfImagePage[],\n meta: { title?: string; attachments?: readonly PdfAttachment[] } = {}\n): Promise<Blob> {\n const { PDFDocument, StandardFonts } = await import('pdf-lib')\n const pdf = await PDFDocument.create()\n if (meta.title) pdf.setTitle(meta.title)\n const now = new Date()\n for (const attachment of meta.attachments ?? []) {\n // Copied: bytes made in another realm (Node's TextEncoder under jsdom) fail pdf-lib's type check.\n await pdf.attach(new Uint8Array(attachment.data), attachment.name, {\n mimeType: attachment.mimeType,\n description: attachment.description,\n creationDate: now,\n modificationDate: now,\n })\n }\n const font = await pdf.embedFont(StandardFonts.Helvetica)\n // The standard font covers Latin text; characters it cannot encode are left out of the hidden\n // layer rather than failing the export.\n const encodable = (line: string) =>\n [...line]\n .filter((ch) => {\n try {\n font.encodeText(ch)\n return true\n } catch {\n return false\n }\n })\n .join('')\n\n for (const entry of pages) {\n const bytes = new Uint8Array(await entry.image.arrayBuffer())\n const image =\n entry.image.type === 'image/png' ? await pdf.embedPng(bytes) : await pdf.embedJpg(bytes)\n const page = pdf.addPage([entry.width, entry.height])\n page.drawImage(image, { x: 0, y: 0, width: entry.width, height: entry.height })\n let y = entry.height - 14\n for (const line of entry.text ?? []) {\n const text = encodable(line).trim()\n if (!text) continue\n page.drawText(text, { x: 8, y, size: 10, font, opacity: 0 })\n y -= 12\n if (y < 4) break\n }\n }\n const saved = await pdf.save()\n return new Blob([saved as BlobPart], { type: 'application/pdf' })\n}\n","/**\n * Files attached to a PDF (the standard /EmbeddedFiles name tree, what a PDF reader lists under\n * \"Attachments\"): read one by name, or put one in (replacing any of that name). Plain functions\n * over bytes, for the browser and Node alike: a saved presentation is a PDF of its slides with its\n * editable data attached (`arbi-presentation.json`), and anything that can read and write a PDF's\n * attachments (these, pypdf / PyMuPDF on a server) can read and edit it. pdf-lib is loaded on use.\n */\n\nimport type { PDFDict as PDFDictType, PDFDocument as PDFDocumentType } from 'pdf-lib'\n\nexport interface PdfAttachment {\n name: string\n data: Uint8Array\n mimeType: string\n description?: string\n}\n\ntype Bytes = Uint8Array | ArrayBuffer\nconst asBytes = (bytes: Bytes) => (bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes))\n\n/** The attachment called `name`, or null when the PDF has none of that name. */\nexport async function readPdfAttachment(pdf: Bytes, name: string): Promise<Uint8Array | null> {\n const lib = await import('pdf-lib')\n const { PDFDocument, PDFName, PDFDict, PDFArray, PDFString, PDFHexString, decodePDFRawStream } =\n lib\n const doc = await PDFDocument.load(asBytes(pdf), { updateMetadata: false })\n const names = doc.catalog.lookupMaybe(PDFName.of('Names'), PDFDict)\n const root = names?.lookupMaybe(PDFName.of('EmbeddedFiles'), PDFDict)\n if (!root) return null\n\n // A name tree: pairs [name, file spec] in /Names, or nested nodes under /Kids.\n const find = (node: PDFDictType): Uint8Array | null => {\n const pairs = node.lookupMaybe(PDFName.of('Names'), PDFArray)\n if (pairs) {\n for (let i = 0; i + 1 < pairs.size(); i += 2) {\n const key = pairs.lookup(i)\n const text =\n key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : undefined\n if (text !== name) continue\n const spec = pairs.lookup(i + 1, PDFDict)\n const files = spec.lookupMaybe(PDFName.of('EF'), PDFDict)\n const stream = files?.lookup(PDFName.of('F'))\n if (!stream || !(stream instanceof lib.PDFRawStream)) return null\n return decodePDFRawStream(stream).decode()\n }\n }\n const kids = node.lookupMaybe(PDFName.of('Kids'), PDFArray)\n for (let i = 0; kids && i < kids.size(); i++) {\n const found = find(kids.lookup(i, PDFDict))\n if (found) return found\n }\n return null\n }\n return find(root)\n}\n\n/** Remove the name-tree entries called `name` (flat /Names arrays; the shape pdf-lib writes). */\nfunction removeEntries(lib: typeof import('pdf-lib'), doc: PDFDocumentType, name: string) {\n const { PDFName, PDFDict, PDFArray, PDFString, PDFHexString } = lib\n const root = doc.catalog\n .lookupMaybe(PDFName.of('Names'), PDFDict)\n ?.lookupMaybe(PDFName.of('EmbeddedFiles'), PDFDict)\n const pairs = root?.lookupMaybe(PDFName.of('Names'), PDFArray)\n if (!pairs) return\n for (let i = pairs.size() - 2; i >= 0; i -= 2) {\n const key = pairs.lookup(i)\n const text =\n key instanceof PDFString || key instanceof PDFHexString ? key.decodeText() : undefined\n if (text === name) {\n pairs.remove(i + 1)\n pairs.remove(i)\n }\n }\n}\n\n/** The PDF with `attachment` in it, replacing any attachment of the same name. */\nexport async function setPdfAttachment(pdf: Bytes, attachment: PdfAttachment): Promise<Uint8Array> {\n const lib = await import('pdf-lib')\n const doc = await lib.PDFDocument.load(asBytes(pdf), { updateMetadata: false })\n removeEntries(lib, doc, attachment.name)\n const now = new Date()\n await doc.attach(new Uint8Array(attachment.data), attachment.name, {\n mimeType: attachment.mimeType,\n description: attachment.description,\n creationDate: now,\n modificationDate: now,\n })\n return doc.save()\n}\n"]}