@signiphi/pdf-signer 0.2.0-beta.2 → 0.2.0-beta.21

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 (197) hide show
  1. package/assets/viewer.html +1 -5
  2. package/dist/components/index.js +2746 -901
  3. package/dist/components/index.js.map +1 -1
  4. package/dist/components/index.mjs +2513 -669
  5. package/dist/components/index.mjs.map +1 -1
  6. package/dist/core/index.js +420 -20
  7. package/dist/core/index.js.map +1 -1
  8. package/dist/core/index.mjs +420 -20
  9. package/dist/core/index.mjs.map +1 -1
  10. package/dist/hooks/index.js +506 -211
  11. package/dist/hooks/index.js.map +1 -1
  12. package/dist/hooks/index.mjs +507 -212
  13. package/dist/hooks/index.mjs.map +1 -1
  14. package/dist/index.css +214 -191
  15. package/dist/index.css.map +1 -1
  16. package/dist/index.js +3019 -893
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +2762 -653
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/styles/index.css +202 -172
  21. package/dist/types/index.js.map +1 -1
  22. package/dist/types/index.mjs.map +1 -1
  23. package/dist/utils/index.js +792 -147
  24. package/dist/utils/index.js.map +1 -1
  25. package/dist/utils/index.mjs +777 -148
  26. package/dist/utils/index.mjs.map +1 -1
  27. package/package.json +2 -2
  28. package/scripts/copy-utils.js +14 -3
  29. package/src/styles/index.css +33 -3
  30. package/dist/__tests__/helpers/fixtures.d.ts +0 -43
  31. package/dist/__tests__/helpers/fixtures.d.ts.map +0 -1
  32. package/dist/__tests__/helpers/mocks.d.ts +0 -333
  33. package/dist/__tests__/helpers/mocks.d.ts.map +0 -1
  34. package/dist/__tests__/setup.d.ts +0 -6
  35. package/dist/__tests__/setup.d.ts.map +0 -1
  36. package/dist/components/AcknowledgementModal.d.ts +0 -21
  37. package/dist/components/AcknowledgementModal.d.ts.map +0 -1
  38. package/dist/components/AcknowledgementsSidebar.d.ts +0 -22
  39. package/dist/components/AcknowledgementsSidebar.d.ts.map +0 -1
  40. package/dist/components/AttachmentUpload.d.ts +0 -17
  41. package/dist/components/AttachmentUpload.d.ts.map +0 -1
  42. package/dist/components/EditableFieldsPanel.d.ts +0 -30
  43. package/dist/components/EditableFieldsPanel.d.ts.map +0 -1
  44. package/dist/components/ErrorBoundary.d.ts +0 -67
  45. package/dist/components/ErrorBoundary.d.ts.map +0 -1
  46. package/dist/components/FormFieldsView.d.ts +0 -46
  47. package/dist/components/FormFieldsView.d.ts.map +0 -1
  48. package/dist/components/InitialsModal.d.ts +0 -16
  49. package/dist/components/InitialsModal.d.ts.map +0 -1
  50. package/dist/components/PdfViewerStyled.d.ts +0 -16
  51. package/dist/components/PdfViewerStyled.d.ts.map +0 -1
  52. package/dist/components/PoweredBySigniphi.d.ts +0 -11
  53. package/dist/components/PoweredBySigniphi.d.ts.map +0 -1
  54. package/dist/components/RequiredFieldNavigation.d.ts +0 -18
  55. package/dist/components/RequiredFieldNavigation.d.ts.map +0 -1
  56. package/dist/components/SignatureCanvas.d.ts +0 -12
  57. package/dist/components/SignatureCanvas.d.ts.map +0 -1
  58. package/dist/components/SignatureInitialsBox.d.ts +0 -25
  59. package/dist/components/SignatureInitialsBox.d.ts.map +0 -1
  60. package/dist/components/SignatureModal.d.ts +0 -21
  61. package/dist/components/SignatureModal.d.ts.map +0 -1
  62. package/dist/components/SigningInstructions.d.ts +0 -12
  63. package/dist/components/SigningInstructions.d.ts.map +0 -1
  64. package/dist/components/SubmissionForm.d.ts +0 -52
  65. package/dist/components/SubmissionForm.d.ts.map +0 -1
  66. package/dist/components/UnacknowledgedFieldsModal.d.ts +0 -23
  67. package/dist/components/UnacknowledgedFieldsModal.d.ts.map +0 -1
  68. package/dist/components/ViewToggleToolbar.d.ts +0 -38
  69. package/dist/components/ViewToggleToolbar.d.ts.map +0 -1
  70. package/dist/components/form-fields/CheckboxRenderer.d.ts +0 -10
  71. package/dist/components/form-fields/CheckboxRenderer.d.ts.map +0 -1
  72. package/dist/components/form-fields/DateFieldRenderer.d.ts +0 -14
  73. package/dist/components/form-fields/DateFieldRenderer.d.ts.map +0 -1
  74. package/dist/components/form-fields/DropdownRenderer.d.ts +0 -14
  75. package/dist/components/form-fields/DropdownRenderer.d.ts.map +0 -1
  76. package/dist/components/form-fields/FormFieldRenderer.d.ts +0 -22
  77. package/dist/components/form-fields/FormFieldRenderer.d.ts.map +0 -1
  78. package/dist/components/form-fields/InitialsFieldRenderer.d.ts +0 -16
  79. package/dist/components/form-fields/InitialsFieldRenderer.d.ts.map +0 -1
  80. package/dist/components/form-fields/RadioGroupRenderer.d.ts +0 -10
  81. package/dist/components/form-fields/RadioGroupRenderer.d.ts.map +0 -1
  82. package/dist/components/form-fields/SignatureFieldRenderer.d.ts +0 -16
  83. package/dist/components/form-fields/SignatureFieldRenderer.d.ts.map +0 -1
  84. package/dist/components/form-fields/TextFieldRenderer.d.ts +0 -14
  85. package/dist/components/form-fields/TextFieldRenderer.d.ts.map +0 -1
  86. package/dist/components/form-fields/TextLabelRenderer.d.ts +0 -14
  87. package/dist/components/form-fields/TextLabelRenderer.d.ts.map +0 -1
  88. package/dist/components/form-fields/index.d.ts +0 -14
  89. package/dist/components/form-fields/index.d.ts.map +0 -1
  90. package/dist/components/index.d.ts +0 -17
  91. package/dist/components/index.d.ts.map +0 -1
  92. package/dist/core/PdfViewerCore.d.ts +0 -19
  93. package/dist/core/PdfViewerCore.d.ts.map +0 -1
  94. package/dist/core/SignatureCaptureCore.d.ts +0 -37
  95. package/dist/core/SignatureCaptureCore.d.ts.map +0 -1
  96. package/dist/core/index.d.ts +0 -3
  97. package/dist/core/index.d.ts.map +0 -1
  98. package/dist/hooks/index.d.ts +0 -9
  99. package/dist/hooks/index.d.ts.map +0 -1
  100. package/dist/hooks/useAcknowledgements.d.ts +0 -50
  101. package/dist/hooks/useAcknowledgements.d.ts.map +0 -1
  102. package/dist/hooks/useAttachments.d.ts +0 -25
  103. package/dist/hooks/useAttachments.d.ts.map +0 -1
  104. package/dist/hooks/useFieldFiltering.d.ts +0 -29
  105. package/dist/hooks/useFieldFiltering.d.ts.map +0 -1
  106. package/dist/hooks/useFormFields.d.ts +0 -23
  107. package/dist/hooks/useFormFields.d.ts.map +0 -1
  108. package/dist/hooks/useMultiSignerContext.d.ts +0 -25
  109. package/dist/hooks/useMultiSignerContext.d.ts.map +0 -1
  110. package/dist/hooks/usePdfViewer.d.ts +0 -52
  111. package/dist/hooks/usePdfViewer.d.ts.map +0 -1
  112. package/dist/hooks/useRequiredFieldNavigation.d.ts +0 -16
  113. package/dist/hooks/useRequiredFieldNavigation.d.ts.map +0 -1
  114. package/dist/hooks/useSignatureCapture.d.ts +0 -17
  115. package/dist/hooks/useSignatureCapture.d.ts.map +0 -1
  116. package/dist/hooks/useSignatures.d.ts +0 -29
  117. package/dist/hooks/useSignatures.d.ts.map +0 -1
  118. package/dist/index.d.ts +0 -17
  119. package/dist/index.d.ts.map +0 -1
  120. package/dist/integrations/index.d.ts +0 -6
  121. package/dist/integrations/index.d.ts.map +0 -1
  122. package/dist/integrations/next-config.d.ts +0 -46
  123. package/dist/integrations/next-config.d.ts.map +0 -1
  124. package/dist/integrations/vite-plugin.d.ts +0 -48
  125. package/dist/integrations/vite-plugin.d.ts.map +0 -1
  126. package/dist/lib/index.d.ts +0 -3
  127. package/dist/lib/index.d.ts.map +0 -1
  128. package/dist/lib/ui/accordion.d.ts +0 -8
  129. package/dist/lib/ui/accordion.d.ts.map +0 -1
  130. package/dist/lib/ui/alert.d.ts +0 -9
  131. package/dist/lib/ui/alert.d.ts.map +0 -1
  132. package/dist/lib/ui/button.d.ts +0 -12
  133. package/dist/lib/ui/button.d.ts.map +0 -1
  134. package/dist/lib/ui/calendar.d.ts +0 -10
  135. package/dist/lib/ui/calendar.d.ts.map +0 -1
  136. package/dist/lib/ui/card.d.ts +0 -9
  137. package/dist/lib/ui/card.d.ts.map +0 -1
  138. package/dist/lib/ui/checkbox.d.ts +0 -5
  139. package/dist/lib/ui/checkbox.d.ts.map +0 -1
  140. package/dist/lib/ui/dialog.d.ts +0 -20
  141. package/dist/lib/ui/dialog.d.ts.map +0 -1
  142. package/dist/lib/ui/index.d.ts +0 -13
  143. package/dist/lib/ui/index.d.ts.map +0 -1
  144. package/dist/lib/ui/input.d.ts +0 -6
  145. package/dist/lib/ui/input.d.ts.map +0 -1
  146. package/dist/lib/ui/label.d.ts +0 -6
  147. package/dist/lib/ui/label.d.ts.map +0 -1
  148. package/dist/lib/ui/popover.d.ts +0 -7
  149. package/dist/lib/ui/popover.d.ts.map +0 -1
  150. package/dist/lib/ui/radio-group.d.ts +0 -6
  151. package/dist/lib/ui/radio-group.d.ts.map +0 -1
  152. package/dist/lib/ui/select.d.ts +0 -14
  153. package/dist/lib/ui/select.d.ts.map +0 -1
  154. package/dist/lib/utils.d.ts +0 -7
  155. package/dist/lib/utils.d.ts.map +0 -1
  156. package/dist/types/index.d.ts +0 -278
  157. package/dist/types/index.d.ts.map +0 -1
  158. package/dist/utils/attachment-validators.d.ts +0 -118
  159. package/dist/utils/attachment-validators.d.ts.map +0 -1
  160. package/dist/utils/audit-trail.d.ts +0 -27
  161. package/dist/utils/audit-trail.d.ts.map +0 -1
  162. package/dist/utils/date-validation.d.ts +0 -30
  163. package/dist/utils/date-validation.d.ts.map +0 -1
  164. package/dist/utils/errors.d.ts +0 -106
  165. package/dist/utils/errors.d.ts.map +0 -1
  166. package/dist/utils/field-extraction.d.ts +0 -36
  167. package/dist/utils/field-extraction.d.ts.map +0 -1
  168. package/dist/utils/field-visibility.d.ts +0 -104
  169. package/dist/utils/field-visibility.d.ts.map +0 -1
  170. package/dist/utils/index.d.ts +0 -18
  171. package/dist/utils/index.d.ts.map +0 -1
  172. package/dist/utils/logger.d.ts +0 -16
  173. package/dist/utils/logger.d.ts.map +0 -1
  174. package/dist/utils/pdf-field-type-helpers.d.ts +0 -78
  175. package/dist/utils/pdf-field-type-helpers.d.ts.map +0 -1
  176. package/dist/utils/pdf-helpers.d.ts +0 -38
  177. package/dist/utils/pdf-helpers.d.ts.map +0 -1
  178. package/dist/utils/pdf-lib-loader.d.ts +0 -45
  179. package/dist/utils/pdf-lib-loader.d.ts.map +0 -1
  180. package/dist/utils/pdf-manipulation.d.ts +0 -93
  181. package/dist/utils/pdf-manipulation.d.ts.map +0 -1
  182. package/dist/utils/pdf-metadata.d.ts +0 -41
  183. package/dist/utils/pdf-metadata.d.ts.map +0 -1
  184. package/dist/utils/pdf-validators.d.ts +0 -149
  185. package/dist/utils/pdf-validators.d.ts.map +0 -1
  186. package/dist/utils/pdf-viewer-filter.d.ts +0 -35
  187. package/dist/utils/pdf-viewer-filter.d.ts.map +0 -1
  188. package/dist/utils/pdf-widget-helpers.d.ts +0 -98
  189. package/dist/utils/pdf-widget-helpers.d.ts.map +0 -1
  190. package/dist/utils/pdfjs-config.d.ts +0 -56
  191. package/dist/utils/pdfjs-config.d.ts.map +0 -1
  192. package/dist/utils/pdfjs-version-check.d.ts +0 -28
  193. package/dist/utils/pdfjs-version-check.d.ts.map +0 -1
  194. package/dist/utils/performance-monitor.d.ts +0 -172
  195. package/dist/utils/performance-monitor.d.ts.map +0 -1
  196. package/dist/utils/tracking.d.ts +0 -89
  197. package/dist/utils/tracking.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logger.ts","../../src/utils/pdf-validators.ts","../../src/utils/pdf-helpers.ts","../../src/utils/pdf-metadata.ts","../../src/utils/pdf-lib-loader.ts","../../src/utils/field-visibility.ts","../../src/utils/pdf-widget-helpers.ts","../../src/utils/pdf-field-type-helpers.ts","../../src/utils/pdf-manipulation.ts","../../src/utils/field-extraction.ts","../../src/utils/pdfjs-config.ts","../../src/utils/pdfjs-version-check.ts","../../src/utils/audit-trail.ts","../../src/utils/errors.ts","../../src/utils/attachment-validators.ts","../../src/utils/performance-monitor.ts","../../src/utils/date-validation.ts","../../src/utils/tracking.ts"],"names":["pdfjsLib","isSignatureField","isInitialsField","PDFName","pdfjsLib2","pdfjsLib3","parseISO","isValidDate","parse"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,SAAS,YAAA,GAAwB;AAC/B,EAAA,OAAO,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,IAAI,QAAA,KAAa,YAAA;AACpE;AAKA,SAAS,aAAa,KAAA,EAAyB;AAC7C,EAAA,OAAO,CAAA,wBAAA,EAA2B,KAAA,CAAM,WAAA,EAAa,CAAA,CAAA,CAAA;AACvD;AAKA,SAAS,YAAA,GAAuB;AAC9B,EAAA,MAAM,SAAS,YAAA,EAAa;AAE5B,EAAA,OAAO;AAAA,IACL,KAAA,CAAM,YAAoB,IAAA,EAAuB;AAC/C,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAA,CAAQ,IAAI,YAAA,CAAa,OAAO,CAAA,EAAG,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,MACrD;AAAA,IACF,CAAA;AAAA,IAEA,IAAA,CAAK,YAAoB,IAAA,EAAuB;AAC9C,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAA,CAAQ,IAAI,YAAA,CAAa,MAAM,CAAA,EAAG,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,MACpD;AAAA,IACF,CAAA;AAAA,IAEA,IAAA,CAAK,YAAoB,IAAA,EAAuB;AAC9C,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAA,CAAQ,KAAK,YAAA,CAAa,MAAM,CAAA,EAAG,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,MACrD;AAAA,IACF,CAAA;AAAA,IAEA,KAAA,CAAM,YAAoB,IAAA,EAAuB;AAE/C,MAAA,OAAA,CAAQ,MAAM,YAAA,CAAa,OAAO,CAAA,EAAG,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,IACvD;AAAA,GACF;AACF;AAKO,IAAM,SAAS,YAAA;;;ACrCf,SAAS,iBAAiB,QAAA,EAG/B;AAEA,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AACtC,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,KAAA;AAAA,MACP,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,IAAI,WAAA,EAAY,CAAE,OAAO,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAC7D,EAAA,IAAI,CAAC,MAAA,CAAO,UAAA,CAAW,OAAO,CAAA,EAAG;AAC/B,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,KAAA;AAAA,MACP,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AACvB;AAqBO,SAAS,qBAAqB,KAAA,EAAwB;AAC3D,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,CAAM,IAAA,IAAQ,OAAO,IAAA;AAEpC,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,WAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,UAAA,CAAW,QAAA,CAAS,KAAA,CAAM,IAAA,EAAM,CAAA;AACzC;AAmBO,SAAS,oBAAoB,MAAA,EAGlC;AACA,EAAA,MAAM,SAAmB,EAAC;AAG1B,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACzC,IAAA,MAAA,CAAO,KAAK,gCAAgC,CAAA;AAC5C,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,MAAA,EAAO;AAAA,EAChC;AAGA,EAAA,MAAM,SAAA,GAAY,MAAA;AAClB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AACpD,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,MAAA,CAAO,KAAK,CAAA,iBAAA,EAAoB,GAAG,CAAA,wBAAA,EAA2B,OAAO,KAAK,CAAA,CAAE,CAAA;AAAA,IAC9E;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,IACzB;AAAA,GACF;AACF;AAqBO,SAAS,mBAAmB,UAAA,EAGjC;AACA,EAAA,MAAM,SAAmB,EAAC;AAG1B,EAAA,IAAI,CAAC,UAAA,IAAc,OAAO,UAAA,KAAe,QAAA,EAAU;AACjD,IAAA,MAAA,CAAO,KAAK,8BAA8B,CAAA;AAC1C,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,MAAA,EAAO;AAAA,EAChC;AAGA,EAAA,MAAM,OAAA,GAAU,UAAA;AAChB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAClD,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,MAAA,CAAO,KAAK,CAAA,eAAA,EAAkB,GAAG,CAAA,wBAAA,EAA2B,OAAO,KAAK,CAAA,CAAE,CAAA;AAC1E,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,aAAa,CAAA,EAAG;AACpC,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,eAAA,EAAkB,GAAG,CAAA,gDAAA,CAAkD,CAAA;AAAA,IACrF;AAGA,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,CAAC,KAAA,CAAM,CAAC,CAAA,EAAG;AACnC,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,eAAA,EAAkB,GAAG,CAAA,mDAAA,CAAqD,CAAA;AAAA,IACxF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,IACzB;AAAA,GACF;AACF;AAyBO,SAAS,kBAAkB,KAAA,EAGhC;AACA,EAAA,MAAM,SAAmB,EAAC;AAG1B,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,MAAA,CAAO,KAAK,8BAA8B,CAAA;AAC1C,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,MAAA,EAAO;AAAA,EAChC;AAEA,EAAA,MAAM,CAAA,GAAI,KAAA;AAGV,EAAA,IAAI,CAAC,CAAA,CAAE,EAAA,IAAM,OAAO,CAAA,CAAE,OAAO,QAAA,EAAU;AACrC,IAAA,MAAA,CAAO,KAAK,qCAAqC,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,CAAC,CAAA,CAAE,IAAA,IAAQ,OAAO,CAAA,CAAE,SAAS,QAAA,EAAU;AACzC,IAAA,MAAA,CAAO,KAAK,uCAAuC,CAAA;AAAA,EACrD;AAEA,EAAA,IAAI,CAAC,CAAA,CAAE,IAAA,IAAQ,OAAO,CAAA,CAAE,SAAS,QAAA,EAAU;AACzC,IAAA,MAAA,CAAO,KAAK,uCAAuC,CAAA;AAAA,EACrD;AAEA,EAAA,IAAI,CAAC,CAAA,CAAE,KAAA,IAAS,OAAO,CAAA,CAAE,UAAU,QAAA,EAAU;AAC3C,IAAA,MAAA,CAAO,KAAK,wCAAwC,CAAA;AAAA,EACtD;AAGA,EAAA,IAAI,CAAC,CAAA,CAAE,QAAA,IAAY,OAAO,CAAA,CAAE,aAAa,QAAA,EAAU;AACjD,IAAA,MAAA,CAAO,KAAK,2CAA2C,CAAA;AAAA,EACzD,CAAA,MAAO;AACL,IAAA,MAAM,MAAM,CAAA,CAAE,QAAA;AACd,IAAA,IAAI,OAAO,GAAA,CAAI,CAAA,KAAM,QAAA,EAAU;AAC7B,MAAA,MAAA,CAAO,KAAK,mDAAmD,CAAA;AAAA,IACjE;AACA,IAAA,IAAI,OAAO,GAAA,CAAI,CAAA,KAAM,QAAA,EAAU;AAC7B,MAAA,MAAA,CAAO,KAAK,mDAAmD,CAAA;AAAA,IACjE;AACA,IAAA,IAAI,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,IAAY,GAAA,CAAI,SAAS,CAAA,EAAG;AACnD,MAAA,MAAA,CAAO,KAAK,6CAA6C,CAAA;AAAA,IAC3D;AACA,IAAA,IAAI,OAAO,GAAA,CAAI,MAAA,KAAW,QAAA,IAAY,GAAA,CAAI,UAAU,CAAA,EAAG;AACrD,MAAA,MAAA,CAAO,KAAK,8CAA8C,CAAA;AAAA,IAC5D;AACA,IAAA,IAAI,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,IAAY,GAAA,CAAI,OAAO,CAAA,EAAG;AAChD,MAAA,MAAA,CAAO,KAAK,4DAA4D,CAAA;AAAA,IAC1E;AAAA,EACF;AAEA,EAAA,IAAI,OAAO,CAAA,CAAE,QAAA,KAAa,SAAA,EAAW;AACnC,IAAA,MAAA,CAAO,KAAK,+CAA+C,CAAA;AAAA,EAC7D;AAGA,EAAA,IAAI,CAAA,CAAE,QAAA,KAAa,MAAA,KAAc,OAAO,CAAA,CAAE,QAAA,KAAa,QAAA,IAAY,CAAA,CAAE,QAAA,GAAW,CAAA,IAAK,CAAA,CAAE,QAAA,GAAW,EAAA,CAAA,EAAK;AACrG,IAAA,MAAA,CAAO,KAAK,kDAAkD,CAAA;AAAA,EAChE;AAEA,EAAA,IAAI,CAAA,CAAE,cAAc,MAAA,KAAc,OAAO,EAAE,SAAA,KAAc,QAAA,IAAY,CAAA,CAAE,SAAA,IAAa,CAAA,CAAA,EAAI;AACtF,IAAA,MAAA,CAAO,KAAK,2CAA2C,CAAA;AAAA,EACzD;AAEA,EAAA,IAAI,CAAA,CAAE,YAAY,MAAA,IAAa,CAAC,MAAM,OAAA,CAAQ,CAAA,CAAE,OAAO,CAAA,EAAG;AACxD,IAAA,MAAA,CAAO,KAAK,gCAAgC,CAAA;AAAA,EAC9C;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,IACzB;AAAA,GACF;AACF;AA4BO,SAAS,eAAe,GAAA,EAG7B;AACA,EAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC3B,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,sBAAA,EAAuB;AAAA,EACvD;AAEA,EAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,IAAA,EAAK,CAAE,WAAW,CAAA,EAAG;AACnC,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,qBAAA,EAAsB;AAAA,EACtD;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,IAAA,EAAK;AAG5B,EAAA,MAAM,gBAAgB,CAAC,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,SAAS,SAAS,CAAA;AACzE,EAAA,MAAM,iBAAiB,aAAA,CAAc,IAAA,CAAK,YAAU,UAAA,CAAW,UAAA,CAAW,MAAM,CAAC,CAAA;AAEjF,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AAGA,EAAA,IAAI,UAAA,CAAW,UAAA,CAAW,GAAG,CAAA,IAAK,UAAA,CAAW,UAAA,CAAW,IAAI,CAAA,IAAK,UAAA,CAAW,UAAA,CAAW,KAAK,CAAA,EAAG;AAC7F,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AAGA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,KAAA;AAAA,IACP,KAAA,EAAO;AAAA,GACT;AACF;;;AC7UO,SAAS,iBAAiB,QAAA,EAA8B;AAC7D,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,QAAoB,CAAA,EAAG,EAAE,IAAA,EAAM,iBAAA,EAAmB,CAAA;AACzE,EAAA,OAAO,GAAA,CAAI,gBAAgB,IAAI,CAAA;AACjC;AAKO,SAAS,WAAA,CAAY,UAAsB,QAAA,EAAwB;AACxE,EAAA,MAAM,GAAA,GAAM,iBAAiB,QAAQ,CAAA;AACrC,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACpC,EAAA,CAAA,CAAE,IAAA,GAAO,GAAA;AACT,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,CAAA,CAAE,KAAA,EAAM;AACR,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;AAOA,eAAsB,cAAc,GAAA,EAAkC;AACpE,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAG,CAAA;AAEhC,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,MAAM,CAAA,qBAAA,EAAwB,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,IAClF;AAEA,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,EAAY;AAG/C,IAAA,MAAM,QAAA,GAAW,IAAI,UAAA,CAAW,WAAA,CAAY,UAAU,CAAA;AACtD,IAAA,QAAA,CAAS,GAAA,CAAI,IAAI,UAAA,CAAW,WAAW,CAAC,CAAA;AAGxC,IAAA,MAAM,UAAA,GAAa,iBAAiB,QAAQ,CAAA;AAC5C,IAAA,IAAI,CAAC,WAAW,KAAA,EAAO;AACrB,MAAA,MAAM,IAAI,KAAA,CAAM,UAAA,CAAW,KAAA,IAAS,oBAAoB,CAAA;AAAA,IAC1D;AAEA,IAAA,OAAO,QAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,gCAAgC,KAAK,CAAA;AAClD,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAKO,SAAS,WAAW,QAAA,EAA+B;AACxD,EAAA,MAAM,UAAA,GAAa,iBAAiB,QAAQ,CAAA;AAC5C,EAAA,OAAO,UAAA,CAAW,KAAA;AACpB;AAKO,SAAS,eAAe,OAAA,EAA6B;AAC1D,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAAA,EAChE;AACA,EAAA,OAAO,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,UAAU,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,CAAE,UAAA,CAAW,CAAC,CAAC,CAAA;AACjE;AAKO,SAAS,gBAAgB,SAAA,EAA2B;AACzD,EAAA,OAAO,SAAA,CACJ,QAAQ,OAAA,EAAS,GAAG,EACpB,OAAA,CAAQ,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,CAAA,CACvC,QAAQ,WAAA,EAAa,EAAE,EACvB,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CACtB,IAAA,EAAK;AACV;AAKO,SAAS,iBAAiB,SAAA,EAA4B;AAC3D,EAAA,OAAO,SAAA,CAAU,WAAA,EAAY,CAAE,QAAA,CAAS,WAAW,CAAA;AACrD;AAKO,SAAS,gBAAgB,SAAA,EAA4B;AAC1D,EAAA,OAAO,SAAA,CAAU,WAAA,EAAY,CAAE,QAAA,CAAS,UAAU,CAAA;AACpD;;;AC7FA,IAAI,OAAA;AACJ,IAAI,SAAA;AAMG,SAAS,gBAAgB,YAAA,EAAyB;AACvD,EAAA,OAAA,GAAU,YAAA,CAAa,OAAA;AACvB,EAAA,SAAA,GAAY,YAAA,CAAa,SAAA;AAC3B;AA0BO,SAAS,mBAAA,CAAoB,QAAqB,QAAA,EAAkC;AACzF,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,SAAA,EAAW;AAC1B,MAAA,OAAA,CAAQ,MAAM,mEAAmE,CAAA;AACjF,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,WAAA,CAAY,IAAA;AAC3C,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AAC7C,IAAA,IAAI,CAAC,OAAA,IAAW,OAAQ,OAAA,CAAgB,QAAQ,UAAA,EAAY;AAC1D,MAAA,MAAM,IAAI,MAAM,0DAA0D,CAAA;AAAA,IAC5E;AACA,IAAA,MAAM,QAAA,GAAW,OAAA;AACjB,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAG9C,IAAA,QAAA,CAAS,GAAA,CAAI,QAAQ,EAAA,CAAG,kBAAkB,GAAG,SAAA,CAAU,EAAA,CAAG,cAAc,CAAC,CAAA;AAAA,EAC3E,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,oCAAoC,KAAK,CAAA;AACvD,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAOO,SAAS,oBAAoB,MAAA,EAA8C;AAChF,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,SAAA,EAAW;AAC1B,MAAA,OAAA,CAAQ,MAAM,mEAAmE,CAAA;AACjF,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,WAAA,CAAY,IAAA;AAC3C,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AAE7C,IAAA,IAAI,CAAC,WAAW,OAAQ,OAAA,CAAgB,QAAQ,UAAA,IAAc,CAAE,QAAgB,IAAA,EAAM;AACpF,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,QAAA,GAAW,OAAA;AACjB,IAAA,MAAM,cAAc,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,EAAA,CAAG,kBAAkB,CAAC,CAAA;AAE/D,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,WAAA,GAAc,YAAY,QAAA,EAAS;AAGzC,IAAA,IAAI,OAAA,GAAU,WAAA;AACd,IAAA,MAAM,UAAA,GAAa,WAAA,CAAY,KAAA,CAAM,YAAY,CAAA;AACjD,IAAA,IAAI,UAAA,IAAc,UAAA,CAAW,CAAC,CAAA,EAAG;AAC/B,MAAA,OAAA,GAAU,WAAW,CAAC,CAAA;AAAA,IACxB,CAAA,MAAO;AACL,MAAA,MAAM,QAAA,GAAW,WAAA,CAAY,KAAA,CAAM,UAAU,CAAA;AAC7C,MAAA,IAAI,QAAA,IAAY,QAAA,CAAS,CAAC,CAAA,EAAG;AAE3B,QAAA,OAAA,GAAU,SAAS,CAAC,CAAA;AAAA,MACtB;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACnC,IAAA,OAAO,QAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,qCAAqC,KAAK,CAAA;AACxD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;ACtGA,IAAI,aAAA,GAA0D,IAAA;AAgB9D,eAAsB,UAAA,GAAa;AACjC,EAAA,IAAI,CAAC,aAAA,EAAe;AAClB,IAAA,aAAA,GAAgB,OAAO,SAAS,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,aAAA;AACT;;;ACeO,SAAS,sBAAA,CACd,OACA,kBAAA,EACS;AAET,EAAA,IAAI,CAAC,mBAAmB,aAAA,EAAe;AACrC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,EAAE,kBAAA,EAAoB,eAAA,EAAiB,aAAA,EAAc,GAAI,kBAAA;AAG/D,EAAA,IAAI,CAAC,MAAM,mBAAA,EAAqB;AAC9B,IAAA,OAAO,aAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,wBAAwB,kBAAA,EAAoB;AACpD,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,mBAAA,CAAoB,QAAA,CAAS,YAAY,CAAA,EAAG;AACpD,IAAA,OAAO,eAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,mBAAA,CAAoB,QAAA,CAAS,SAAS,CAAA,EAAG;AACjD,IAAA,OAAO,aAAA;AAAA,EACT;AAGA,EAAA,OAAO,KAAA;AACT;AAgBO,SAAS,oBAAA,CACd,QACA,kBAAA,EACkB;AAElB,EAAA,IAAI,CAAC,mBAAmB,aAAA,EAAe;AACrC,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,OAAO,OAAO,MAAA,CAAO,CAAA,KAAA,KAAS,sBAAA,CAAuB,KAAA,EAAO,kBAAkB,CAAC,CAAA;AACjF;AAwCO,SAAS,kBAAA,CACd,OACA,kBAAA,EACS;AAET,EAAA,IAAI,CAAC,mBAAmB,aAAA,EAAe;AACrC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,EAAE,kBAAA,EAAoB,eAAA,EAAiB,aAAA,EAAc,GAAI,kBAAA;AAG/D,EAAA,IAAI,CAAC,MAAM,mBAAA,EAAqB;AAC9B,IAAA,OAAO,aAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,wBAAwB,kBAAA,EAAoB;AACpD,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,mBAAA,CAAoB,QAAA,CAAS,YAAY,CAAA,EAAG;AACpD,IAAA,OAAO,eAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,mBAAA,CAAoB,QAAA,CAAS,SAAS,CAAA,EAAG;AACjD,IAAA,OAAO,aAAA;AAAA,EACT;AAGA,EAAA,OAAO,KAAA;AACT;;;ACjJO,SAAS,kBAAA,CACd,OACA,OAAA,EACQ;AACR,EAAA,IAAI,CAAC,SAAS,OAAO,EAAA;AAErB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,IAAI,IAAA,CAAK,QAAQ,OAAA,EAAS;AACxB,MAAA,OAAO,CAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,EAAA;AACT;AAgCO,SAAS,yBAAA,CACd,QACA,KAAA,EAKO;AACP,EAAA,MAAM,IAAA,GAAO,OAAO,YAAA,IAAe;AACnC,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAElB,EAAA,MAAM,OAAA,GAAU,OAAO,CAAA,IAAI;AAC3B,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AAErB,EAAA,MAAM,SAAA,GAAY,kBAAA,CAAmB,KAAA,EAAO,OAAO,CAAA;AACnD,EAAA,IAAI,SAAA,KAAc,IAAI,OAAO,IAAA;AAE7B,EAAA,MAAM,IAAA,GAAO,MAAM,SAAS,CAAA;AAC5B,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAElB,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,SAAA,EAAU;AACjC;AAyBO,SAAS,yBAAA,CACd,OACA,OAAA,EACQ;AACR,EAAA,IAAI,CAAC,OAAA,EAAS;AAEZ,IAAA,OAAO,KAAA,CAAM,MAAA,KAAW,CAAA,GAAI,CAAA,GAAI,EAAA;AAAA,EAClC;AAEA,EAAA,MAAM,SAAA,GAAY,kBAAA,CAAmB,KAAA,EAAO,OAAO,CAAA;AAGnD,EAAA,IAAI,SAAA,KAAc,EAAA,IAAM,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC1C,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,OAAO,SAAA;AACT;;;AChHO,SAAS,gBAAgB,KAAA,EAA6B;AAC3D,EAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,IAAA;AAEnC,EAAA,IAAI,aAAa,cAAA,EAAgB;AAC/B,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,MAAA,IAAW,aAAa,aAAA,EAAe;AACrC,IAAA,OAAO,UAAA;AAAA,EACT,CAAA,MAAA,IAAW,aAAa,aAAA,EAAe;AACrC,IAAA,OAAO,UAAA;AAAA,EACT,CAAA,MAAA,IAAW,aAAa,eAAA,EAAiB;AACvC,IAAA,OAAO,YAAA;AAAA,EACT,CAAA,MAAA,IAAW,aAAa,eAAA,EAAiB;AACvC,IAAA,OAAO,YAAA;AAAA,EACT,CAAA,MAAA,IAAW,aAAa,cAAA,EAAgB;AACtC,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,OAAO,SAAA;AACT;AAqBO,SAAS,iBAAA,CAAkB,OAAqB,SAAA,EAA2B;AAChF,EAAA,IAAI;AACF,IAAA,QAAQ,SAAA;AAAW,MACjB,KAAK,MAAA;AACH,QAAA,OAAO,KAAA,CAAM,WAAU,IAAK,EAAA;AAAA,MAE9B,KAAK,UAAA;AACH,QAAA,OAAO,KAAA,CAAM,SAAA,IAAY,GAAI,MAAA,GAAS,OAAA;AAAA,MAExC,KAAK,UAAA;AAAA,MACL,KAAK,YAAA;AAAA,MACL,KAAK,YAAA;AACH,QAAA,OAAO,KAAA,CAAM,WAAA,IAAc,GAAI,CAAC,CAAA,IAAK,EAAA;AAAA,MAEvC;AACE,QAAA,OAAO,EAAA;AAAA;AACX,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AAqBO,SAAS,eAAA,CACd,KAAA,EACA,SAAA,EACA,SAAA,EACS;AAET,EAAA,IAAI,cAAc,WAAA,EAAa;AAC7B,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI;AACF,IAAA,IAAI,KAAA,CAAM,cAAa,EAAG;AACxB,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAGA,EAAA,IACE,SAAA,CAAU,QAAA,CAAS,WAAW,CAAA,IAC9B,SAAA,CAAU,QAAA,CAAS,UAAU,CAAA,IAC7B,SAAA,CAAU,QAAA,CAAS,UAAU,CAAA,EAC7B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,KAAA;AACT;;;ACzGA,eAAsB,WAAA,CACpB,UACA,OAAA,EACoB;AACpB,EAAA,IAAI;AAEF,IAAA,MAAM,UAAA,GAAa,iBAAiB,QAAQ,CAAA;AAC5C,IAAA,IAAI,CAAC,WAAW,KAAA,EAAO;AACrB,MAAA,MAAA,CAAO,KAAA,CAAM,cAAA,EAAgB,UAAA,CAAW,KAAK,CAAA;AAC7C,MAAA,MAAM,IAAI,KAAA,CAAM,UAAA,CAAW,KAAA,IAAS,oBAAoB,CAAA;AAAA,IAC1D;AAGA,IAAA,MAAM,cAAuBA,oBAAA,CAAA,WAAA,CAAY;AAAA,MACvC,IAAA,EAAM,QAAA;AAAA,MACN,SAAA,EAAW;AAAA,KACZ,CAAA;AACD,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,OAAA;AAEjC,IAAA,MAAM,QAAmB,EAAC;AAG1B,IAAA,IAAI,SAAA,GAAY,IAAA;AAChB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM,UAAA,EAAW;AACzC,MAAA,SAAA,GAAY,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAAA,IAC7C,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,MAAA,CAAO,UAAU,OAAA,EAAA,EAAW;AAC3D,MAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA;AACzC,MAAA,MAAM,WAAW,IAAA,CAAK,WAAA,CAAY,EAAE,KAAA,EAAO,GAAK,CAAA;AAGhD,MAAA,IAAI,QAAA,GAAW,SAAS,KAAA,GAAQ,CAAA;AAChC,MAAA,IAAI,SAAA,GAAY,SAAS,MAAA,GAAS,CAAA;AAGlC,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,IAAI;AACF,UAAA,MAAM,UAAA,GAAa,SAAA,CAAU,OAAA,CAAQ,OAAA,GAAU,CAAC,CAAA;AAChD,UAAA,QAAA,GAAW,WAAW,QAAA,EAAS;AAC/B,UAAA,SAAA,GAAY,WAAW,SAAA,EAAU;AAAA,QACnC,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AAGA,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AACtC,MAAA,MAAA,CAAO,SAAS,QAAA,CAAS,MAAA;AACzB,MAAA,MAAA,CAAO,QAAQ,QAAA,CAAS,KAAA;AAGxB,MAAA,MAAM,cAAA,GAAiB,SAAS,cAAA,IAAkB,KAAA;AAClD,MAAA,MAAM,aAAA,GAAqB;AAAA,QACzB,aAAA,EAAe,OAAA;AAAA,QACf,QAAA;AAAA,QACA,wBAAwB,CAAC,cAAA;AAAA,QACzB,GAAI,cAAA,IAAkB;AAAA,UACpB,cAAA,EAAgB,CAAA;AAAA,UAChB,iBAAA,EAAmB,KAAA;AAAA,UACnB,WAAA,EAAa;AAAA;AACf,OACF;AAEA,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,aAAa,CAAA,CAAE,OAAA;AAGjC,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA;AAE7C,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,UAAA,EAAY,OAAA;AAAA,QACZ,KAAA,EAAO,QAAA;AAAA,QACP,MAAA,EAAQ,SAAA;AAAA,QACR,QAAA;AAAA,QACA,aAAa,QAAA,CAAS,KAAA;AAAA,QACtB,cAAc,QAAA,CAAS;AAAA,OACxB,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,KAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,+CAA+C,KAAK,CAAA;AACjE,IAAA,OAAO,MAAM,oBAAoB,QAAQ,CAAA;AAAA,EAC3C;AACF;AAKA,eAAe,oBAAoB,QAAA,EAA0C;AAC3E,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM,UAAA,EAAW;AACzC,IAAA,MAAM,GAAA,GAAM,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAC3C,IAAA,MAAM,QAAmB,EAAC;AAE1B,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,YAAA,IAAgB,CAAA,EAAA,EAAK;AAC3C,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAA;AAC1B,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,KAAK,OAAA,EAAQ;AAGvC,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAEtC,MAAA,MAAM,KAAA,GAAQ,GAAA;AACd,MAAA,MAAA,CAAO,QAAQ,KAAA,GAAQ,KAAA;AACvB,MAAA,MAAA,CAAO,SAAS,MAAA,GAAS,KAAA;AAGzB,MAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AACpB,MAAA,OAAA,CAAQ,SAAS,CAAA,EAAG,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,OAAO,MAAM,CAAA;AAClD,MAAA,OAAA,CAAQ,WAAA,GAAc,SAAA;AACtB,MAAA,OAAA,CAAQ,SAAA,GAAY,CAAA;AACpB,MAAA,OAAA,CAAQ,WAAW,CAAA,EAAG,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,OAAO,MAAM,CAAA;AACpD,MAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AACpB,MAAA,OAAA,CAAQ,IAAA,GAAO,qBAAA;AACf,MAAA,OAAA,CAAQ,SAAA,GAAY,QAAA;AACpB,MAAA,OAAA,CAAQ,QAAA,CAAS,CAAA,KAAA,EAAQ,CAAA,GAAI,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,KAAA,GAAQ,CAAA,EAAG,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,EAAE,CAAA;AAC1E,MAAA,OAAA,CAAQ,IAAA,GAAO,gBAAA;AACf,MAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AACpB,MAAA,OAAA,CAAQ,QAAA,CAAS,6BAA6B,MAAA,CAAO,KAAA,GAAQ,GAAG,MAAA,CAAO,MAAA,GAAS,IAAI,EAAE,CAAA;AAEtF,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA;AAE7C,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,YAAY,CAAA,GAAI,CAAA;AAAA,QAChB,KAAA;AAAA,QACA,MAAA;AAAA,QACA,QAAA;AAAA,QACA,aAAa,MAAA,CAAO,KAAA;AAAA,QACpB,cAAc,MAAA,CAAO;AAAA,OACtB,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,KAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,gCAAgC,KAAK,CAAA;AAElD,IAAA,OAAO,CAAC,iBAAiB,CAAA;AAAA,EAC3B;AACF;AAKA,SAAS,eAAA,GAA2B;AAClC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AACtC,EAAA,MAAA,CAAO,KAAA,GAAQ,GAAA;AACf,EAAA,MAAA,CAAO,MAAA,GAAS,GAAA;AAEhB,EAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AACpB,EAAA,OAAA,CAAQ,SAAS,CAAA,EAAG,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,OAAO,MAAM,CAAA;AAClD,EAAA,OAAA,CAAQ,WAAA,GAAc,SAAA;AACtB,EAAA,OAAA,CAAQ,SAAA,GAAY,CAAA;AACpB,EAAA,OAAA,CAAQ,WAAW,CAAA,EAAG,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,OAAO,MAAM,CAAA;AACpD,EAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AACpB,EAAA,OAAA,CAAQ,IAAA,GAAO,qBAAA;AACf,EAAA,OAAA,CAAQ,SAAA,GAAY,QAAA;AACpB,EAAA,OAAA,CAAQ,QAAA,CAAS,wBAAwB,MAAA,CAAO,KAAA,GAAQ,GAAG,MAAA,CAAO,MAAA,GAAS,IAAI,EAAE,CAAA;AACjF,EAAA,OAAA,CAAQ,IAAA,GAAO,gBAAA;AACf,EAAA,OAAA,CAAQ,SAAA,GAAY,SAAA;AACpB,EAAA,OAAA,CAAQ,QAAA,CAAS,2CAA2C,MAAA,CAAO,KAAA,GAAQ,GAAG,MAAA,CAAO,MAAA,GAAS,IAAI,EAAE,CAAA;AAEpG,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,CAAA;AAAA,IACZ,KAAA,EAAO,GAAA;AAAA,IACP,MAAA,EAAQ,GAAA;AAAA,IACR,QAAA,EAAU,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA;AAAA,IACtC,aAAa,MAAA,CAAO,KAAA;AAAA,IACpB,cAAc,MAAA,CAAO;AAAA,GACvB;AACF;AAgCA,eAAsB,mBAAA,CAAoB,QAAA,EAAsB,mBAAA,GAAsB,KAAA,EAA4B;AAChH,EAAA,IAAI;AAEF,IAAA,MAAM,UAAA,GAAa,iBAAiB,QAAQ,CAAA;AAC5C,IAAA,IAAI,CAAC,WAAW,KAAA,EAAO;AACrB,MAAA,OAAO,QAAA;AAAA,IACT;AAEA,IAAA,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM,UAAA,EAAW;AACzC,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAE9C,IAAA,IAAI,mBAAA,EAAqB;AAEvB,MAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,EAAS;AAE9B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,QAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AAEpB,QAAA,IAAI;AAEF,UAAA,MAAM,UAAW,IAAA,CAAa,GAAA;AAC9B,UAAA,MAAM,WAAA,GAAc,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AAEjD,UAAA,IAAI,WAAA,EAAa;AACf,YAAA,MAAM,QAAA,GAAW,WAAA;AAEjB,YAAA,IAAI,QAAA,IAAY,QAAA,CAAS,GAAA,IAAO,QAAA,CAAS,MAAA,EAAQ;AAC/C,cAAA,MAAM,YAAY,QAAA,CAAS,GAAA,CAAK,OAAO,OAAA,CAAgB,GAAA,CAAI,QAAQ,CAAC,CAAA;AAEpE,cAAA,IAAI,SAAA,EAAW;AACb,gBAAA,QAAA,CAAS,MAAA,CAAQ,MAAA,CAAO,OAAA,CAAgB,GAAA,CAAI,QAAQ,CAAC,CAAA;AAAA,cACvD;AAAA,YACF,CAAA,MAAO;AAAA,YACP;AAAA,UACF,CAAA,MAAO;AAAA,UACP;AAAA,QACF,SAAS,SAAA,EAAW;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,MAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAE9B,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,QAAA,OAAO,QAAA;AAAA,MACT;AAGA,MAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,QAAA,IAAI;AACF,UAAA,MAAM,YAAa,KAAA,CAA0C,SAAA;AAC7D,UAAA,IAAI,SAAA,IAAa,OAAO,SAAA,CAAU,UAAA,KAAe,UAAA,EAAY;AAC3D,YAAA,IAAI,OAAA,GAAU,UAAU,UAAA,EAAW;AAGnC,YAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,YAAA,MAAM,aAAA,GAAgB,QAAQ,MAAA,GAAS,CAAA;AAEvC,YAAA,OAAO,OAAA,CAAQ,MAAA,GAAS,CAAA,IAAK,aAAA,GAAgB,aAAA,EAAe;AAC1D,cAAA,IAAI;AACF,gBAAA,MAAM,WAAA,GAAc,QAAQ,MAAA,GAAS,CAAA;AACrC,gBAAA,SAAA,CAAU,aAAa,WAAW,CAAA;AAClC,gBAAA,OAAA,GAAU,UAAU,UAAA,EAAW;AAAA,cACjC,SAAS,WAAA,EAAa;AACpB,gBAAA;AAAA,cACF;AACA,cAAA,aAAA,EAAA;AAAA,YACF;AAEA,YAAA,IAAI,iBAAiB,aAAA,EAAe;AAAA,YACpC;AAAA,UACF;AAEA,UAAA,IAAA,CAAK,YAAY,KAAY,CAAA;AAAA,QAC/B,SAAS,KAAA,EAAO;AAEd,UAAA,IAAI;AACF,YAAA,IAAA,CAAK,YAAY,KAAY,CAAA;AAAA,UAC/B,SAAS,aAAA,EAAe;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,eAAA,GAAkB,KAAK,SAAA,EAAU;AACvC,MAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAAA,MAChC;AAAA,IACF;AAEA,IAAA,MAAM,eAAA,GAAkB,MAAM,MAAA,CAAO,IAAA,EAAK;AAC1C,IAAA,OAAO,eAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAC1D,IAAA,OAAO,QAAA;AAAA,EACT;AACF;AAKA,eAAsB,kBAAkB,QAAA,EAKnC;AACH,EAAA,IAAI;AAEF,IAAA,MAAM,UAAA,GAAa,iBAAiB,QAAQ,CAAA;AAC5C,IAAA,IAAI,CAAC,WAAW,KAAA,EAAO;AACrB,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAA,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM,UAAA,EAAW;AACzC,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAE9B,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,GAAA,CAAI,CAAA,KAAA,KAAS;AACrC,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,EAAQ;AAChC,MAAA,MAAM,QAAA,GAAW,KAAA;AAEjB,MAAA,IAAI;AAEF,QAAA,MAAM,SAAA,GAAY,gBAAgB,QAAQ,CAAA;AAC1C,QAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,QAAA,EAAU,SAAS,CAAA;AACnD,QAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,QAAA,EAAU,SAAA,EAAW,SAAS,CAAA;AAE/D,QAAA,OAAO;AAAA,UACL,IAAA,EAAM,SAAA;AAAA,UACN,IAAA,EAAM,SAAA;AAAA,UACN,QAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,SAAS,UAAA,EAAY;AAEnB,QAAA,OAAO;AAAA,UACL,IAAA,EAAM,SAAA;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,QAAA,EAAU,KAAA;AAAA,UACV,KAAA,EAAO;AAAA,SACT;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,UAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,kCAAkC,KAAK,CAAA;AACpD,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAKA,eAAsB,yBAAyB,QAAA,EAAuD;AACpG,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AACtC,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAA,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM,UAAA,EAAW;AACzC,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAE9B,IAAA,MAAM,gBAAwC,EAAC;AAE/C,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,EAAQ;AAChC,MAAA,MAAM,QAAA,GAAW,KAAA;AAEjB,MAAA,IAAI;AAEF,QAAA,MAAM,SAAA,GAAY,gBAAgB,QAAQ,CAAA;AAC1C,QAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,QAAA,EAAU,SAAS,CAAA;AAEnD,QAAA,aAAA,CAAc,SAAS,CAAA,GAAI,KAAA;AAAA,MAC7B,SAAS,UAAA,EAAY;AACnB,QAAA,aAAA,CAAc,SAAS,CAAA,GAAI,EAAA;AAAA,MAC7B;AAAA,IACF;AAEA,IAAA,OAAO,aAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,0CAA0C,KAAK,CAAA;AAC5D,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAMA,eAAsB,qBAAA,CACpB,QAAA,EACA,WAAA,EACA,UAAA,EACA,iBACA,kBAAA,EACmB;AACnB,EAAA,IAAI;AACF,IAAA,MAAM,aAAA,GAAgB,MAAM,iBAAA,CAAkB,QAAQ,CAAA;AACtD,IAAA,MAAM,SAAmB,EAAC;AAG1B,IAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,MAAA,IAAI,MAAM,QAAA,EAAU;AAElB,QAAA,IAAI,kBAAA,EAAoB,iBAAiB,eAAA,EAAiB;AACxD,UAAA,MAAM,iBAAiB,eAAA,CAAgB,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,KAAS,MAAM,IAAI,CAAA;AACtE,UAAA,IAAI,CAAC,cAAA,EAAgB;AAEnB,YAAA;AAAA,UACF;AAAA,QACF;AAEA,QAAA,IAAI,QAAA,GAAW,KAAA;AACf,QAAA,MAAM,UAAA,GAAa,WAAA,CAAY,KAAA,CAAM,IAAI,CAAA;AACzC,QAAA,MAAM,cAAA,GAAiB,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA;AAC5C,QAAA,MAAM,aAAA,GAAgB,WAAW,sBAAsB,CAAA;AACvD,QAAA,MAAM,YAAA,GAAe,UAAA,CAAW,qBAAqB,CAAA,IAAK,YAAY,qBAAqB,CAAA;AAE3F,QAAA,IAAI,MAAM,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA,IAAK,KAAA,CAAM,SAAS,WAAA,EAAa;AAClE,UAAA,QAAA,GAAW,CAAC,EAAE,cAAA,IAAkB,UAAA,IAAc,aAAA,CAAA;AAAA,QAChD,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG;AAC1C,UAAA,QAAA,GAAW,CAAC,EAAE,cAAA,IAAkB,UAAA,IAAc,YAAA,CAAA;AAAA,QAChD,CAAA,MAAO;AACL,UAAA,QAAA,GAAW,CAAC,EAAE,UAAA,IAAc,KAAA,CAAM,KAAA,CAAA;AAAA,QACpC;AAEA,QAAA,IAAI,CAAC,QAAA,EAAU;AACb,UAAA,IAAI,YAAA,GAAe,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAA,EAAS,CAAA,CAAA,KAAK,CAAA,CAAE,WAAA,EAAa,CAAA;AAEzF,UAAA,IAAI,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA,EAAG;AACpC,YAAA,YAAA,GAAe,WAAA;AAAA,UACjB,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG;AAC1C,YAAA,YAAA,GAAe,UAAA;AAAA,UACjB;AAEA,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,YAAY,CAAA,YAAA,CAAc,CAAA;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,qCAAqC,KAAK,CAAA;AACvD,IAAA,OAAO,CAAC,kFAAkF,CAAA;AAAA,EAC5F;AACF;AAKA,eAAsB,uBAAA,CACpB,QAAA,EACA,UAAA,EACA,eAAA,GAA0C,EAAC,EACxB;AACnB,EAAA,IAAI;AACF,IAAA,MAAM,aAAA,GAAgB,MAAM,iBAAA,CAAkB,QAAQ,CAAA;AACtD,IAAA,MAAM,aAAA,GAAgB,MAAM,wBAAA,CAAyB,QAAQ,CAAA;AAC7D,IAAA,MAAM,SAAmB,EAAC;AAE1B,IAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,MAAA,MAAMC,oBAAmB,KAAA,CAAM,IAAA,CAAK,SAAS,WAAW,CAAA,IAAK,MAAM,IAAA,KAAS,MAAA;AAC5E,MAAA,MAAMC,mBAAkB,KAAA,CAAM,IAAA,CAAK,SAAS,UAAU,CAAA,IAAK,MAAM,IAAA,KAAS,MAAA;AAE1E,MAAA,IAAI,KAAA,CAAM,QAAA,IAAYD,iBAAAA,IAAoBC,gBAAAA,EAAiB;AACzD,QAAA,IAAI,QAAA,GAAW,KAAA;AACf,QAAA,MAAM,YAAA,GAAe,aAAA,CAAc,KAAA,CAAM,IAAI,CAAA,IAAK,EAAA;AAElD,QAAA,IAAID,iBAAAA,EAAkB;AACpB,UAAA,QAAA,GAAW,CAAC,CAAC,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA;AAAA,QACpC,WAAWC,gBAAAA,EAAiB;AAC1B,UAAA,QAAA,GAAW,CAAC,CAAC,UAAA,CAAW,KAAA,CAAM,IAAI,KAAK,CAAC,CAAE,eAAA,CAAgB,KAAA,CAAM,IAAI,CAAA,EAAG,IAAA,EAAK,IAAM,YAAA,CAAa,MAAK,KAAM,EAAA;AAAA,QAC5G,CAAA,MAAO;AACL,UAAA,QAAA,GAAW,YAAA,CAAa,MAAK,KAAM,EAAA;AAAA,QACrC;AAEA,QAAA,IAAI,CAAC,QAAA,EAAU;AACb,UAAA,IAAI,YAAA,GAAe,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAA,EAAS,CAAA,CAAA,KAAK,CAAA,CAAE,WAAA,EAAa,CAAA;AAEzF,UAAA,IAAI,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA,EAAG;AACpC,YAAA,YAAA,GAAe,WAAA;AAAA,UACjB,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG;AAC1C,YAAA,YAAA,GAAe,UAAA;AAAA,UACjB;AAEA,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,YAAY,CAAA,YAAA,CAAc,CAAA;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,uCAAuC,KAAK,CAAA;AACzD,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AASA,eAAsB,qBAAA,CACpB,QAAA,EACA,UAAA,EACA,eAAA,GAA0C,IAC1C,kBAAA,EACA,mBAAA,EACA,QAAA,EACA,UAAA,EACA,kBAAA,EACqB;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,WAAA,EAAa,GAAA,EAAK,aAAA,EAAc,GAAI,MAAM,UAAA,EAAW;AAC7D,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,IAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,EAAS;AAG9B,IAAA,MAAM,EAAE,SAAS,YAAA,EAAc,WAAA,EAAa,kBAAiB,GAAI,MAAM,oBAAoB,QAAQ,CAAA;AAInG,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,EAAQ;AAChC,MAAA,MAAM,UAAA,GAAa,gBAAgB,SAAS,CAAA;AAE5C,MAAA,IAAI,CAAC,UAAA,EAAY;AAEf,QAAA,IAAI,SAAA,CAAU,QAAA,CAAS,OAAO,CAAA,EAAG;AAAA,QACjC;AACA,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,aAAA,GAAgB,MAAM,WAAA,CAAY,IAAA;AAGxC,QAAA,IAAI,aAAA,KAAkB,cAAA,IAAkB,aAAA,KAAkB,eAAA,EAAiB;AACzE,UAAA,MAAM,SAAA,GAAY,KAAA;AAClB,UAAA,SAAA,CAAU,UAAU,UAAU,CAAA;AAAA,QAChC,CAAA,MAAA,IAES,aAAA,KAAkB,aAAA,IAAiB,aAAA,KAAkB,cAAA,EAAgB;AAC5E,UAAA,MAAM,QAAA,GAAW,KAAA;AACjB,UAAA,IAAI,eAAe,MAAA,IAAU,UAAA,KAAe,SAAS,UAAA,KAAe,SAAA,IAAa,eAAe,IAAA,EAAM;AACpG,YAAA,QAAA,CAAS,KAAA,IAAQ;AAAA,UACnB,CAAA,MAAO;AACL,YAAA,QAAA,CAAS,OAAA,IAAU;AAAA,UACrB;AAAA,QACF,CAAA,MAAA,IAES,aAAA,KAAkB,eAAA,IAAmB,aAAA,KAAkB,gBAAA,EAAkB;AAChF,UAAA,MAAM,UAAA,GAAa,KAAA;AAGnB,UAAA,IAAI,UAAA,KAAe,MAAA,IAAU,UAAA,KAAe,OAAA,EAAS;AACnD,YAAA;AAAA,UACF;AAGA,UAAA,MAAM,QAAA,GAAW,UAAA,CAAW,KAAA,CAAM,8BAA8B,CAAA;AAChE,UAAA,IAAI,QAAA,IAAY,QAAA,CAAS,CAAC,CAAA,EAAG;AAC3B,YAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,QAAA,CAAS,CAAC,GAAG,EAAE,CAAA;AAC9C,YAAA,MAAM,OAAA,GAAU,UAAA,CAAW,UAAA,IAAa,IAAK,EAAC;AAC9C,YAAA,IAAI,aAAA,IAAiB,CAAA,IAAK,aAAA,GAAgB,OAAA,CAAQ,MAAA,EAAQ;AACxD,cAAA,UAAA,CAAW,MAAA,GAAS,OAAA,CAAQ,aAAa,CAAC,CAAA;AAAA,YAC5C;AAAA,UACF,CAAA,MAAO;AAEL,YAAA,MAAM,OAAA,GAAU,UAAA,CAAW,UAAA,IAAa,IAAK,EAAC;AAC9C,YAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,UAAU,CAAA,EAAG;AAChC,cAAA,UAAA,CAAW,SAAS,UAAU,CAAA;AAAA,YAChC,CAAA,MAAO;AAAA,YACP;AAAA,UACF;AAAA,QACF,CAAA,MAAA,IAES,aAAA,KAAkB,aAAA,IAAiB,aAAA,KAAkB,cAAA,EAAgB;AAC5E,UAAA,MAAM,QAAA,GAAW,KAAA;AACjB,UAAA,QAAA,CAAS,SAAS,UAAU,CAAA;AAAA,QAC9B;AAAA,MACF,SAAS,UAAA,EAAY;AACnB,QAAA,MAAA,CAAO,KAAA,CAAM,CAAA,qBAAA,EAAwB,SAAS,CAAA,EAAA,CAAA,EAAM,UAAU,CAAA;AAAA,MAChE;AAAA,IACF;AAKA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,sBAAA,EAAuB;AAI5B,MAAA,MAAMC,WAAU,MAAA,CAAO,OAAA;AACvB,MAAA,MAAM,WAAW,MAAA,CAAO,OAAA,CAAQ,OAAOA,QAAAA,CAAQ,EAAA,CAAG,UAAU,CAAC,CAAA;AAC7D,MAAA,IAAI,QAAA,IAAY,OAAO,QAAA,KAAa,QAAA,IAAY,SAAS,QAAA,EAAU;AACjE,QAAC,SAAiB,GAAA,CAAIA,QAAAA,CAAQ,EAAA,CAAG,iBAAiB,GAAG,KAAK,CAAA;AAAA,MAC5D;AAAA,IACF,SAAS,eAAA,EAAiB;AAExB,MAAA,MAAA,CAAO,IAAA,CAAK,uCAAuC,eAAe,CAAA;AAAA,IACpE;AAGA,IAAA,MAAM,iBAAA,GAAoB,WAAW,sBAAsB,CAAA;AAC3D,IAAA,IAAI,iBAAA,IAAqB,iBAAA,CAAkB,IAAA,EAAK,EAAG;AAIjD,MAAA,MAAM,mBAAA,GAAsB;AAAA,QAC1B,WAAA;AAAA,QAAa,WAAA;AAAA,QAAa,WAAA;AAAA,QAC1B,MAAA;AAAA,QAAQ,MAAA;AAAA,QAAQ,MAAA;AAAA,QAChB;AAAA,OACF;AACA,MAAA,IAAI,uBAAuB,MAAA,CAAO,IAAA,CAAK,YAAY,CAAA,CAAE,OAAO,CAAA,SAAA,KAAa;AACvE,QAAA,MAAM,sBAAsB,mBAAA,CAAoB,IAAA;AAAA,UAAK,aACnD,SAAA,CAAU,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,aAAa;AAAA,SACxD;AACA,QAAA,MAAM,iBAAiB,CAAC,SAAA,CAAU,WAAA,EAAY,CAAE,WAAW,OAAO,CAAA;AAClE,QAAA,OAAO,mBAAA,IAAuB,cAAA;AAAA,MAChC,CAAC,CAAA;AAGD,MAAA,IAAI,mBAAA,IAAuB,mBAAA,CAAoB,MAAA,GAAS,CAAA,EAAG;AACzD,QAAA,MAAM,4BAAA,GAA+B,oBAAA,CAAqB,MAAA,CAAO,CAAA,SAAA,KAAa;AAC5E,UAAA,MAAM,YAAY,mBAAA,CAAoB,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,SAAS,CAAA;AACpE,UAAA,IAAI,CAAC,SAAA,EAAW;AACd,YAAA,OAAO,KAAA;AAAA,UACT;AAMA,UAAA,MAAM,sBAAA,GAAA,CAA0B,SAAA,CAAU,IAAA,KAAS,WAAA,IACjD,UAAU,WAAA,EAAY,CAAE,QAAA,CAAS,WAAW,MACzC,CAAC,SAAA,CAAU,WAAA,EAAY,CAAE,SAAS,UAAU,CAAA;AAEjD,UAAA,IAAI,CAAC,sBAAA,EAAwB;AAC3B,YAAA,OAAO,KAAA;AAAA,UACT;AAGA,UAAA,MAAM,SAAA,GAAY,kBAAA,GACd,sBAAA,CAAuB,SAAA,EAAW,kBAAkB,CAAA,GACpD,IAAA;AAEJ,UAAA,OAAO,SAAA;AAAA,QACT,CAAC,CAAA;AACD,QAAA,oBAAA,GAAuB,4BAAA;AAAA,MACzB;AAGA,MAAA,IAAI,oBAAA,CAAqB,SAAS,CAAA,EAAG;AACnC,QAAA,IAAI;AAEF,UAAA,IAAI,cAAA;AACJ,UAAA,IAAI,iBAAA,CAAkB,QAAA,CAAS,gBAAgB,CAAA,EAAG;AAChD,YAAA,cAAA,GAAiB,MAAM,MAAA,CAAO,QAAA,CAAS,iBAAiB,CAAA;AAAA,UAC1D,CAAA,MAAA,IAAW,kBAAkB,QAAA,CAAS,iBAAiB,KAAK,iBAAA,CAAkB,QAAA,CAAS,gBAAgB,CAAA,EAAG;AACxG,YAAA,cAAA,GAAiB,MAAM,MAAA,CAAO,QAAA,CAAS,iBAAiB,CAAA;AAAA,UAC1D,CAAA,MAAO;AAEL,YAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AACjD,YAAA,IAAI,CAAC,UAAA,EAAY;AACf,cAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AAAA,YACtE;AACA,YAAA,MAAM,UAAA,GAAa,KAAK,UAAU,CAAA;AAGlC,YAAA,IAAI,WAAW,UAAA,CAAW,CAAC,MAAM,GAAA,IAC7B,UAAA,CAAW,WAAW,CAAC,CAAA,KAAM,MAC7B,UAAA,CAAW,UAAA,CAAW,CAAC,CAAA,KAAM,EAAA,IAC7B,WAAW,UAAA,CAAW,CAAC,MAAM,EAAA,EAAM;AACrC,cAAA,cAAA,GAAiB,MAAM,MAAA,CAAO,QAAA,CAAS,iBAAiB,CAAA;AAAA,YAC1D,CAAA,MAAA,IAES,UAAA,CAAW,UAAA,CAAW,CAAC,MAAM,GAAA,IAC7B,UAAA,CAAW,UAAA,CAAW,CAAC,MAAM,GAAA,IAC7B,UAAA,CAAW,UAAA,CAAW,CAAC,MAAM,GAAA,EAAM;AAC1C,cAAA,cAAA,GAAiB,MAAM,MAAA,CAAO,QAAA,CAAS,iBAAiB,CAAA;AAAA,YAC1D,CAAA,MACK;AACH,cAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,YACrE;AAAA,UACF;AAGA,UAAA,KAAA,MAAW,aAAa,oBAAA,EAAsB;AAE5C,YAAA,MAAM,UAAA,GAAa,aAAa,SAAS,CAAA;AAEzC,YAAA,IAAI,UAAA,IAAc,UAAA,IAAc,KAAA,CAAM,MAAA,EAAQ;AAC5C,cAAA,MAAM,IAAA,GAAO,KAAA,CAAM,UAAA,GAAa,CAAC,CAAA;AACjC,cAAA,IAAI,CAAC,IAAA,EAAM;AAGX,cAAA,MAAM,aAAA,GAAgB,iBAAiB,SAAS,CAAA;AAEhD,cAAA,IAAI,aAAA,EAAe;AAEjB,gBAAA,MAAM,IAAI,aAAA,CAAc,CAAA;AACxB,gBAAA,MAAM,IAAI,aAAA,CAAc,CAAA;AACxB,gBAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,aAAA,CAAc,OAAO,EAAE,CAAA;AAC9C,gBAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,aAAA,CAAc,QAAQ,EAAE,CAAA;AAGhD,gBAAA,MAAM,gBAAgB,cAAA,CAAe,UAAA,CAAW,KAAA,GAAQ,CAAA,EAAG,SAAS,CAAC,CAAA;AAGrE,gBAAA,MAAM,MAAA,GAAS,CAAA;AACf,gBAAA,MAAM,MAAA,GAAS,CAAA;AAGf,gBAAA,IAAA,CAAK,UAAU,cAAA,EAAgB;AAAA,kBAC7B,CAAA,EAAG,MAAA;AAAA,kBACH,CAAA,EAAG,MAAA;AAAA,kBACH,OAAO,aAAA,CAAc,KAAA;AAAA,kBACrB,QAAQ,aAAA,CAAc;AAAA,iBACvB,CAAA;AAAA,cAEH,CAAA,MAAO;AAAA,cACP;AAAA,YACF,CAAA,MAAO;AAAA,YACP;AAAA,UACF;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,MAAA,CAAO,KAAA,CAAM,8BAA8B,KAAK,CAAA;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAGA,IAAA,OAAA,CAAQ,IAAI,qCAAqC,CAAA;AACjD,IAAA,OAAA,CAAQ,GAAA,CAAI,iCAAA,EAAmC,MAAA,CAAO,IAAA,CAAK,eAAe,CAAC,CAAA;AAC3E,IAAA,OAAA,CAAQ,GAAA,CAAI,+CAAA,EAAiD,MAAA,CAAO,IAAA,CAAK,eAAe,CAAA,CAAE,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAA,EAAY,CAAE,QAAA,CAAS,UAAU,CAAC,CAAC,CAAA;AAC3I,IAAA,MAAM,gBAAA,GAAmB,gBAAgB,qBAAqB,CAAA;AAC9D,IAAA,OAAA,CAAQ,GAAA,CAAI,wDAAwD,gBAAA,GAAmB,gBAAA,CAAiB,UAAU,CAAA,EAAG,EAAE,IAAI,WAAW,CAAA;AACtI,IAAA,IAAI,gBAAA,IAAoB,gBAAA,CAAiB,IAAA,EAAK,EAAG;AAE/C,MAAA,OAAA,CAAQ,GAAA,CAAI,8BAAA,EAAgC,MAAA,CAAO,IAAA,CAAK,YAAY,CAAC,CAAA;AACrE,MAAA,OAAA,CAAQ,IAAI,0DAA0D,CAAA;AAEtE,MAAA,MAAM,kBAAA,GAAqB,CAAC,UAAA,EAAY,UAAA,EAAY,UAAU,CAAA;AAC9D,MAAA,IAAI,mBAAA,GAAsB,MAAA,CAAO,IAAA,CAAK,YAAY,CAAA,CAAE,MAAA;AAAA,QAAO,CAAA,SAAA,KACzD,kBAAA,CAAmB,IAAA,CAAK,CAAA,OAAA,KAAW,SAAA,CAAU,WAAA,EAAY,CAAE,QAAA,CAAS,OAAA,CAAQ,WAAA,EAAa,CAAC;AAAA,OAC5F;AACA,MAAA,OAAA,CAAQ,GAAA,CAAI,qDAAqD,mBAAmB,CAAA;AAGpF,MAAA,IAAI,mBAAA,IAAuB,mBAAA,CAAoB,MAAA,GAAS,CAAA,EAAG;AACzD,QAAA,mBAAA,GAAsB,mBAAA,CAAoB,OAAO,CAAA,SAAA,KAAa;AAC5D,UAAA,MAAM,YAAY,mBAAA,CAAoB,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,SAAS,CAAA;AACpE,UAAA,IAAI,CAAC,WAAW,OAAO,KAAA;AAEvB,UAAA,MAAM,qBAAA,GAAwB,UAAU,IAAA,KAAS,UAAA,IAC/C,UAAU,WAAA,EAAY,CAAE,SAAS,UAAU,CAAA;AAC7C,UAAA,IAAI,CAAC,uBAAuB,OAAO,KAAA;AAGnC,UAAA,MAAM,SAAA,GAAY,kBAAA,GACd,sBAAA,CAAuB,SAAA,EAAW,kBAAkB,CAAA,GACpD,IAAA;AAEJ,UAAA,OAAO,SAAA;AAAA,QACT,CAAC,CAAA;AAAA,MACH;AAEA,MAAA,OAAA,CAAQ,GAAA,CAAI,iBAAA,EAAmB,mBAAA,CAAoB,MAAA,EAAQ,+BAA+B,mBAAmB,CAAA;AAC7G,MAAA,IAAI,mBAAA,CAAoB,SAAS,CAAA,EAAG;AAClC,QAAA,IAAI;AACF,UAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,SAAA,CAAU,cAAc,aAAa,CAAA;AAE/D,UAAA,KAAA,MAAW,aAAa,mBAAA,EAAqB;AAC3C,YAAA,OAAA,CAAQ,GAAA,CAAI,wCAAwC,SAAS,CAAA;AAC7D,YAAA,MAAM,UAAA,GAAa,aAAa,SAAS,CAAA;AACzC,YAAA,OAAA,CAAQ,GAAA,CAAI,4BAA4B,UAAU,CAAA;AAClD,YAAA,IAAI,UAAA,IAAc,UAAA,IAAc,KAAA,CAAM,MAAA,EAAQ;AAC5C,cAAA,MAAM,IAAA,GAAO,KAAA,CAAM,UAAA,GAAa,CAAC,CAAA;AACjC,cAAA,IAAI,CAAC,IAAA,EAAM;AACT,gBAAA,OAAA,CAAQ,IAAI,mCAA8B,CAAA;AAC1C,gBAAA;AAAA,cACF;AAEA,cAAA,MAAM,aAAA,GAAgB,iBAAiB,SAAS,CAAA;AAChD,cAAA,OAAA,CAAQ,GAAA,CAAI,+BAA+B,aAAa,CAAA;AACxD,cAAA,IAAI,aAAA,EAAe;AACjB,gBAAA,MAAM,IAAI,aAAA,CAAc,CAAA;AACxB,gBAAA,MAAM,IAAI,aAAA,CAAc,CAAA;AACxB,gBAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,aAAA,CAAc,QAAQ,EAAE,CAAA;AAEhD,gBAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,KAAK,EAAE,CAAA;AAG1C,gBAAA,MAAM,SAAS,CAAA,GAAI,CAAA;AACnB,gBAAA,MAAM,MAAA,GAAS,CAAA,GAAA,CAAK,MAAA,GAAS,QAAA,IAAY,CAAA;AAEzC,gBAAA,OAAA,CAAQ,GAAA,CAAI,yCAAA,EAAsC,EAAE,CAAA,EAAG,MAAA,EAAQ,GAAG,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,gBAAA,EAAkB,CAAA;AAC5G,gBAAA,IAAA,CAAK,SAAS,gBAAA,EAAkB;AAAA,kBAC9B,CAAA,EAAG,MAAA;AAAA,kBACH,CAAA,EAAG,MAAA;AAAA,kBACH,IAAA,EAAM,QAAA;AAAA,kBACN,IAAA;AAAA,kBACA,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,iBACnB,CAAA;AAAA,cAEH,CAAA,MAAO;AACL,gBAAA,OAAA,CAAQ,IAAI,6DAAwD,CAAA;AAAA,cACtE;AAAA,YACF,CAAA,MAAO;AACL,cAAA,OAAA,CAAQ,IAAI,8DAAyD,CAAA;AAAA,YACvE;AAAA,UACF;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,MAAA,CAAO,KAAA,CAAM,4BAA4B,KAAK,CAAA;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAIA,IAAA,MAAM,aAAA,GAAgB,KAAK,SAAA,EAAU;AAErC,IAAA,IAAI,eAAA;AAEJ,IAAA,IAAI,oBAAoB,aAAA,EAAe;AAGrC,MAAA,eAAA,GAAkB,aAAA,CAAc,OAAO,CAAA,CAAA,KAAK;AAC1C,QAAA,MAAM,SAAA,GAAY,EAAE,OAAA,EAAQ;AAE5B,QAAA,IAAI,CAAC,mBAAA,IAAuB,mBAAA,CAAoB,MAAA,KAAW,CAAA,EAAG;AAC5D,UAAA,OAAO,IAAA;AAAA,QACT;AAEA,QAAA,MAAM,YAAY,mBAAA,CAAoB,IAAA,CAAK,CAAA,EAAA,KAAM,EAAA,CAAG,SAAS,SAAS,CAAA;AACtE,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA,OAAO,IAAA;AAAA,QACT;AAGA,QAAA,OAAO,kBAAA,CAAmB,WAAW,kBAAkB,CAAA;AAAA,MACzD,CAAC,CAAA;AAAA,IACH,CAAA,MAAO;AAEL,MAAA,eAAA,GAAkB,aAAA;AAAA,IACpB;AAUA,IAAA,IAAI,cAAA,GAAiB,CAAA;AAErB,IAAA,KAAA,MAAW,SAAS,eAAA,EAAiB;AACnC,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,EAAQ;AAChC,MAAA,MAAM,SAAA,GAAY,MAAM,WAAA,CAAY,IAAA;AAEpC,MAAA,IAAI;AAEF,QAAA,MAAM,gBAAA,GAAmB,gBAAgB,SAAS,CAAA;AAGlD,QAAA,MAAMF,iBAAAA,GAAmB,UAAU,WAAA,EAAY,CAAE,SAAS,WAAW,CAAA,IAAK,SAAA,CAAU,QAAA,CAAS,WAAW,CAAA;AACxG,QAAA,MAAMC,gBAAAA,GAAkB,UAAU,WAAA,EAAY,CAAE,SAAS,UAAU,CAAA,IAAK,SAAA,CAAU,QAAA,CAAS,UAAU,CAAA;AAErG,QAAA,IAAID,qBAAoBC,gBAAAA,EAAiB;AAEvC,UAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,UAAA,cAAA,EAAA;AACA,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,gBAAA,GAAmB,KAAA;AACzB,QAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,SAAA,EAAW,UAAA,QAAkB,EAAC;AAG/D,QAAA,IAAI,SAAA,KAAc,aAAA,IAAiB,SAAA,KAAc,cAAA,EAAgB;AAE/D,UAAA,MAAM,WAAA,GAAc,MAAA,CAAO,gBAAA,IAAoB,EAAE,CAAA;AACjD,UAAA,MAAM,YAAY,WAAA,KAAgB,MAAA,IAAU,gBAAgB,KAAA,IAC3C,WAAA,KAAgB,QAAQ,WAAA,KAAgB,SAAA;AAGzD,UAAA,IAAI,SAAA,EAAW;AACb,YAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,cAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,MAAA,EAA8C,KAAK,CAAA;AAC5F,cAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,cAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAK,GAAI,MAAA;AAGvB,cAAA,MAAM,eAAe,IAAA,CAAK,GAAA,CAAI,KAAK,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA,GAAI,GAAA;AACzD,cAAA,MAAM,SAAA,GAAY,IAAA,CAAK,CAAA,GAAA,CAAK,IAAA,CAAK,QAAQ,YAAA,IAAgB,CAAA;AACzD,cAAA,MAAM,SAAA,GAAY,IAAA,CAAK,CAAA,GAAA,CAAK,IAAA,CAAK,SAAS,YAAA,IAAgB,CAAA;AAE1D,cAAA,IAAA,CAAK,aAAA,CAAc;AAAA,gBACjB,CAAA,EAAG,SAAA;AAAA,gBACH,CAAA,EAAG,SAAA;AAAA,gBACH,KAAA,EAAO,YAAA;AAAA,gBACP,MAAA,EAAQ,YAAA;AAAA,gBACR,WAAA,EAAa,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,gBACxB,WAAA,EAAa;AAAA,eACd,CAAA;AAGD,cAAA,MAAM,YAAY,YAAA,GAAe,GAAA;AACjC,cAAA,MAAM,YAAY,SAAA,GAAY,GAAA;AAC9B,cAAA,MAAM,aAAa,SAAA,GAAY,GAAA;AAE/B,cAAA,IAAA,CAAK,SAAS,GAAA,EAAK;AAAA,gBACjB,CAAA,EAAG,SAAA,GAAA,CAAa,YAAA,GAAe,SAAA,IAAa,CAAA;AAAA,gBAC5C,CAAA,EAAG,SAAA,GAAA,CAAa,YAAA,GAAe,UAAA,IAAc,IAAI,UAAA,GAAa,GAAA;AAAA,gBAC9D,IAAA,EAAM,SAAA;AAAA,gBACN,IAAA,EAAM,MAAM,MAAA,CAAO,SAAA,CAAU,cAAc,aAAa,CAAA;AAAA,gBACxD,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,eACnB,CAAA;AAAA,YAEH;AAAA,UACF;AAAA,QACF,CAAA,MAAA,IAAW,SAAA,KAAc,eAAA,IAAmB,SAAA,KAAc,gBAAA,EAAkB;AAE1E,UAAA,MAAM,UAAA,GAAa,KAAA;AAGnB,UAAA,MAAM,YAAY,mBAAA,EAAqB,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,SAAS,CAAA;AAGrE,UAAA,IAAI,mBAAA,GAAsB,EAAA;AAC1B,UAAA,IAAI;AACF,YAAA,mBAAA,GAAsB,UAAA,CAAW,eAAc,IAAK,EAAA;AACpD,YAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,sCAAA,EAAyC,mBAAmB,CAAA,CAAA,CAAG,CAAA;AAAA,UAC/G,SAAS,CAAA,EAAG;AAEV,YAAA,mBAAA,GAAsB,gBAAA,GAAmB,MAAA,CAAO,gBAAgB,CAAA,GAAI,EAAA;AACpE,YAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,0DAAA,EAA6D,mBAAmB,CAAA,CAAA,CAAG,CAAA;AAAA,UACnI;AAGA,UAAA,IAAI,aAAA,GAAgB,CAAA,CAAA;AAGpB,UAAA,MAAM,YAAA,GAAe,UAAA,CAAW,UAAA,IAAa,IAAK,EAAC;AACnD,UAAA,MAAA,CAAO,KAAK,CAAA,sBAAA,EAAyB,SAAS,sCAAsC,YAAA,CAAa,MAAM,aAAa,YAAY,CAAA;AAGhI,UAAA,IAAI,mBAAA,IAAuB,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG;AAClD,YAAA,aAAA,GAAgB,YAAA,CAAa,SAAA,CAAU,CAAC,GAAA,KAAgB,QAAQ,mBAAmB,CAAA;AACnF,YAAA,MAAA,CAAO,KAAK,CAAA,sBAAA,EAAyB,SAAS,gCAAgC,mBAAmB,CAAA,WAAA,EAAc,aAAa,CAAA,CAAE,CAAA;AAAA,UAChI;AAGA,UAAA,IAAI,aAAA,KAAkB,MAAM,gBAAA,EAAkB;AAC5C,YAAA,MAAM,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,YAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,kEAAA,EAAqE,aAAa,CAAA,CAAA,CAAG,CAAA;AAGnI,YAAA,IAAI,aAAA,CAAc,UAAA,CAAW,uBAAuB,CAAA,EAAG;AACrD,cAAA,MAAM,UAAA,GAAa,aAAA,CAAc,KAAA,CAAM,8BAA8B,CAAA;AACrE,cAAA,IAAI,UAAA,IAAc,UAAA,CAAW,CAAC,CAAA,EAAG;AAC/B,gBAAA,aAAA,GAAgB,QAAA,CAAS,UAAA,CAAW,CAAC,CAAA,EAAG,EAAE,CAAA;AAC1C,gBAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,kBAAA,EAAqB,aAAa,CAAA,mCAAA,CAAqC,CAAA;AAAA,cACvH;AAAA,YACF,CAAA,MAAA,IAES,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA,EAAG;AACpC,cAAA,aAAA,GAAgB,QAAA,CAAS,eAAe,EAAE,CAAA;AAC1C,cAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,uBAAA,EAA0B,aAAa,CAAA,CAAE,CAAA;AAAA,YACzF,CAAA,MAAA,IAES,SAAA,EAAW,OAAA,IAAW,aAAA,EAAe;AAC5C,cAAA,aAAA,GAAgB,SAAA,CAAU,OAAA,CAAQ,SAAA,CAAU,CAAA,MAAA,KAAU,WAAW,aAAa,CAAA;AAC9E,cAAA,MAAA,CAAO,KAAK,CAAA,sBAAA,EAAyB,SAAS,cAAc,aAAa,CAAA,gCAAA,EAAmC,aAAa,CAAA,CAAE,CAAA;AAAA,YAC7H,CAAA,MAAA,IAES,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG;AAChC,cAAA,aAAA,GAAgB,YAAA,CAAa,SAAA,CAAU,CAAC,GAAA,KAAgB,QAAQ,aAAa,CAAA;AAC7E,cAAA,MAAA,CAAO,KAAK,CAAA,sBAAA,EAAyB,SAAS,cAAc,aAAa,CAAA,2BAAA,EAA8B,aAAa,CAAA,CAAE,CAAA;AAAA,YACxH;AAAA,UACF;AAEA,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,wBAAA,EAA2B,aAAa,CAAA,uCAAA,CAAyC,CAAA;AAC/H,UAAA,MAAM,SAAA,GAAY,MAAM,MAAA,CAAO,SAAA,CAAU,gBAAgB,CAAA;AACzD,UAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAY;AACzC,UAAA,MAAM,iBAAA,uBAAwB,GAAA,EAAY;AAG1C,UAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,YAAA,MAAM,MAAA,GAAS,QAAQ,CAAC,CAAA;AACxB,YAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,MAAA,EAA8C,KAAK,CAAA;AAC5F,YAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,YAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,SAAA,EAAU,GAAI,MAAA;AAIlC,YAAA,IAAI,CAAA,KAAM,CAAA,IAAK,SAAA,EAAW,KAAA,IAAS,SAAA,CAAU,KAAA,CAAM,IAAA,EAAK,IAAK,CAAC,oBAAA,CAAqB,SAAA,CAAU,KAAK,CAAA,EAAG;AACnG,cAAA,MAAM,aAAA,GAAgB,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,SAAS,CAAA,WAAA,CAAA;AAC/C,cAAA,IAAI,CAAC,gBAAA,CAAiB,GAAA,CAAI,aAAa,CAAA,EAAG;AACxC,gBAAA,MAAM,MAAA,GAAS,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,CAAA;AACtC,gBAAA,IAAA,CAAK,QAAA,CAAS,UAAU,KAAA,EAAO;AAAA,kBAC7B,GAAG,IAAA,CAAK,CAAA;AAAA,kBACR,CAAA,EAAG,MAAA;AAAA,kBACH,IAAA,EAAM,CAAA;AAAA,kBACN,IAAA,EAAM,SAAA;AAAA,kBACN,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,iBACnB,CAAA;AACD,gBAAA,gBAAA,CAAiB,IAAI,aAAa,CAAA;AAAA,cACpC;AAAA,YACF,WAAW,CAAA,KAAM,CAAA,IAAK,qBAAqB,SAAA,EAAW,KAAA,IAAS,EAAE,CAAA,EAAG;AAAA,YACpE;AAGA,YAAA,MAAM,YAAY,IAAA,CAAK,GAAA,CAAI,KAAK,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA,GAAI,GAAA;AACtD,YAAA,MAAM,MAAA,GAAS,IAAA,CAAK,CAAA,GAAA,CAAK,IAAA,CAAK,QAAQ,SAAA,IAAa,CAAA;AACnD,YAAA,MAAM,MAAA,GAAS,IAAA,CAAK,CAAA,GAAA,CAAK,IAAA,CAAK,SAAS,SAAA,IAAa,CAAA;AAEpD,YAAA,IAAA,CAAK,UAAA,CAAW;AAAA,cACd,CAAA,EAAG,SAAS,SAAA,GAAY,CAAA;AAAA,cACxB,CAAA,EAAG,SAAS,SAAA,GAAY,CAAA;AAAA,cACxB,IAAA,EAAM,SAAA;AAAA,cACN,WAAA,EAAa,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,cACxB,WAAA,EAAa;AAAA,aACd,CAAA;AAGD,YAAA,IAAI,MAAM,aAAA,EAAe;AACvB,cAAA,MAAM,aAAa,SAAA,GAAY,GAAA;AAC/B,cAAA,IAAA,CAAK,UAAA,CAAW;AAAA,gBACd,CAAA,EAAG,SAAS,SAAA,GAAY,CAAA;AAAA,gBACxB,CAAA,EAAG,SAAS,SAAA,GAAY,CAAA;AAAA,gBACxB,IAAA,EAAM,UAAA;AAAA,gBACN,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,eACnB,CAAA;AAAA,YACH;AAGA,YAAA,IAAI,SAAA,EAAW,OAAA,IAAW,SAAA,CAAU,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtD,cAAA,MAAM,UAAA,GAAa,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA;AACtC,cAAA,MAAM,YAAY,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,SAAS,QAAQ,CAAC,CAAA,CAAA;AAEpD,cAAA,IAAI,UAAA,IAAc,CAAC,iBAAA,CAAkB,GAAA,CAAI,SAAS,CAAA,EAAG;AACnD,gBAAA,IAAA,CAAK,SAAS,UAAA,EAAY;AAAA,kBACxB,CAAA,EAAG,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,CAAA;AAAA,kBACzB,CAAA,EAAG,IAAA,CAAK,CAAA,GAAA,CAAK,IAAA,CAAK,SAAS,CAAA,IAAK,CAAA;AAAA,kBAChC,IAAA,EAAM,CAAA;AAAA,kBACN,IAAA,EAAM,SAAA;AAAA,kBACN,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,iBACnB,CAAA;AACD,gBAAA,iBAAA,CAAkB,IAAI,SAAS,CAAA;AAAA,cACjC;AAAA,YACF;AAAA,UACF;AAEA,UAAA,IAAI,WAAW,OAAA,EAAS;AAAA,UACxB;AAAA,QACF,CAAA,MAAA,IAAW,SAAA,KAAc,aAAA,IAAiB,SAAA,KAAc,cAAA,EAAgB;AAEtE,UAAA,MAAM,aAAA,GAAgB,gBAAA,GAAmB,MAAA,CAAO,gBAAgB,CAAA,GAAI,EAAA;AAGpE,UAAA,IAAI,aAAA,IAAiB,aAAA,CAAc,IAAA,EAAK,EAAG;AACzC,YAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,cAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,MAAA,EAA8C,KAAK,CAAA;AAC5F,cAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,cAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAK,GAAI,MAAA;AAGvB,cAAA,IAAA,CAAK,SAAS,aAAA,EAAe;AAAA,gBAC3B,CAAA,EAAG,KAAK,CAAA,GAAI,CAAA;AAAA,gBACZ,CAAA,EAAG,KAAK,CAAA,GAAI,CAAA;AAAA,gBACZ,IAAA,EAAM,EAAA;AAAA,gBACN,IAAA,EAAM,MAAM,MAAA,CAAO,SAAA,CAAU,cAAc,SAAS,CAAA;AAAA,gBACpD,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,eACrB,CAAA;AAAA,YAEH;AAAA,UACF;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,MAAM,UAAA,GAAa,gBAAA,GAAmB,MAAA,CAAO,gBAAgB,CAAA,GAAI,EAAA;AAG/D,UAAA,IAAI,UAAA,IAAc,UAAA,CAAW,IAAA,EAAK,EAAG;AACnC,YAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,cAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,MAAA,EAA8C,KAAK,CAAA;AAC5F,cAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,cAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAK,GAAI,MAAA;AAGvB,cAAA,IAAA,CAAK,SAAS,UAAA,EAAY;AAAA,gBACxB,CAAA,EAAG,KAAK,CAAA,GAAI,CAAA;AAAA,gBACZ,CAAA,EAAG,KAAK,CAAA,GAAI,CAAA;AAAA,gBACZ,IAAA,EAAM,EAAA;AAAA,gBACN,IAAA,EAAM,MAAM,MAAA,CAAO,SAAA,CAAU,cAAc,SAAS,CAAA;AAAA,gBACpD,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,eACrB,CAAA;AAAA,YAEH;AAAA,UACF;AAAA,QACF;AAGA,QAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,QAAA,cAAA,EAAA;AAAA,MACF,SAAS,KAAA,EAAO;AAAA,MAChB;AAAA,IACF;AAEA,IAAA,MAAM,eAAA,GAAkB,KAAK,SAAA,EAAU;AAGrC,IAAA,IAAI,oBAAoB,aAAA,EAAe;AAEvC,MAAA,MAAM,sBAAA,GAAyB,aAAA,CAAc,MAAA,GAAS,eAAA,CAAgB,MAAA;AACtE,MAAA,IAAI,eAAA,CAAgB,WAAW,sBAAA,EAAwB;AAAA,MACvD,CAAA,MAAO;AAAA,MACP;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC9B,QAAA,MAAA,CAAO,KAAA,CAAM,CAAA,8BAAA,EAAiC,eAAA,CAAgB,MAAM,CAAA,oBAAA,CAAsB,CAAA;AAC1F,QAAA,MAAA,CAAO,KAAA,CAAM,qBAAqB,eAAA,CAAgB,GAAA,CAAI,OAAK,CAAA,CAAE,OAAA,EAAS,CAAC,CAAA;AAGvE,QAAA,IAAI;AACF,UAAA,IAAA,CAAK,OAAA,EAAQ;AACb,UAAA,MAAM,oBAAA,GAAuB,KAAK,SAAA,EAAU;AAE5C,UAAA,IAAI,oBAAA,CAAqB,SAAS,CAAA,EAAG;AACnC,YAAA,MAAA,CAAO,KAAA,CAAM,CAAA,+BAAA,EAAkC,oBAAA,CAAqB,MAAM,CAAA,oBAAA,CAAsB,CAAA;AAChG,YAAA,MAAA,CAAO,KAAA,CAAM,2BAA2B,oBAAA,CAAqB,GAAA,CAAI,OAAK,CAAA,CAAE,OAAA,EAAS,CAAC,CAAA;AAAA,UACpF;AAAA,QACF,SAAS,aAAA,EAAe;AACtB,UAAA,MAAA,CAAO,KAAA,CAAM,+BAA+B,aAAa,CAAA;AAAA,QAC3D;AAAA,MACF,CAAA,MAAO;AAAA,MACP;AAAA,IACF;AAGA,IAAA,IAAI;AAGA,MAAA,MAAM,gBAAgB,QAAA,EAAU,UAAA,GAC5B,CAAA,aAAA,EAAgB,QAAA,CAAS,UAAU,CAAA,CAAA,GACnC,iBAAA;AACJ,MAAA,MAAA,CAAO,SAAS,aAAa,CAAA;AAG7B,MAAA,MAAM,eAAA,GAAkB,QAAA,EAAU,YAAA,GAC9B,CAAA,eAAA,EAAkB,QAAA,CAAS,YAAY,CAAA,CAAA,GACvC,QAAA,EAAU,WAAA,GACV,CAAA,UAAA,EAAa,QAAA,CAAS,WAAW,CAAA,CAAA,GACjC,2BAAA;AACJ,MAAA,MAAA,CAAO,WAAW,eAAe,CAAA;AAGjC,MAAA,MAAM,cAAA,GAAiB,QAAA,EAAU,MAAA,IAAU,QAAA,EAAU,WAAA,IAAe,SAAA;AACpE,MAAA,MAAA,CAAO,UAAU,cAAc,CAAA;AAE/B,MAAA,MAAA,CAAO,YAAY,4CAA4C,CAAA;AAE/D,MAAA,IAAI,UAAU,WAAA,EAAa;AACzB,QAAA,MAAA,CAAO,UAAA,CAAW,CAAA,QAAA,EAAW,QAAA,CAAS,WAAW,CAAA,CAAE,CAAA;AAAA,MACrD;AAGA,MAAA,IAAI,UAAU,SAAA,EAAW;AACvB,QAAA,MAAA,CAAO,eAAA,CAAgB,SAAS,SAAS,CAAA;AAAA,MAC3C;AAGA,MAAA,MAAA,CAAO,mBAAA,iBAAoB,IAAI,IAAA,EAAM,CAAA;AAGrC,MAAA,MAAM,WAAqB,EAAC;AAG5B,MAAA,IAAI,UAAU,WAAA,EAAa;AACzB,QAAA,QAAA,CAAS,IAAA,CAAK,SAAS,WAAW,CAAA;AAAA,MACpC;AAGA,MAAA,IAAI,QAAA,EAAU,cAAA,IAAkB,QAAA,CAAS,cAAA,CAAe,MAAK,EAAG;AAC9D,QAAA,QAAA,CAAS,KAAK,CAAA,SAAA,EAAY,QAAA,CAAS,cAAA,CAAe,IAAA,EAAM,CAAA,CAAE,CAAA;AAAA,MAC5D;AAGA,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,IAAI;AAEF,UAAA,IAAI,WAAW,SAAA,EAAW;AACxB,YAAA,QAAA,CAAS,IAAA,CAAK,CAAA,UAAA,EAAa,UAAA,CAAW,SAAS,CAAA,CAAE,CAAA;AAAA,UACnD;AAGA,UAAA,IAAI,WAAW,gBAAA,EAAkB;AAC/B,YAAA,QAAA,CAAS,IAAA,CAAK,CAAA,OAAA,EAAU,UAAA,CAAW,gBAAgB,CAAA,CAAE,CAAA;AAAA,UACvD;AAGA,UAAA,IAAI,WAAW,QAAA,EAAU;AACvB,YAAA,QAAA,CAAS,IAAA,CAAK,CAAA,SAAA,EAAY,UAAA,CAAW,QAAQ,CAAA,CAAE,CAAA;AAAA,UACjD;AAGA,UAAA,IAAI,WAAW,QAAA,EAAU;AACvB,YAAA,QAAA,CAAS,IAAA,CAAK,CAAA,SAAA,EAAY,UAAA,CAAW,QAAQ,CAAA,CAAE,CAAA;AAAA,UACjD;AAGA,UAAA,IAAI,WAAW,QAAA,EAAU;AACvB,YAAA,QAAA,CAAS,IAAA,CAAK,CAAA,SAAA,EAAY,UAAA,CAAW,QAAQ,CAAA,CAAE,CAAA;AAAA,UACjD;AAGA,UAAA,IAAI,WAAW,SAAA,EAAW;AACxB,YAAA,QAAA,CAAS,IAAA,CAAK,CAAA,GAAA,EAAM,UAAA,CAAW,SAAS,CAAA,CAAE,CAAA;AAAA,UAC5C;AAGA,UAAA,IAAI,WAAW,WAAA,EAAa;AAC1B,YAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,QAAA,KAAa,UAAA,CAAW,WAAA;AACrD,YAAA,MAAM,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA;AAC9B,YAAA,MAAM,GAAA,GAAM,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA;AAC/B,YAAA,QAAA,CAAS,IAAA,CAAK,CAAA,SAAA,EAAY,GAAG,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAA;AAGtC,YAAA,IAAI,aAAa,KAAA,CAAA,EAAW;AAC1B,cAAA,QAAA,CAAS,IAAA,CAAK,CAAA,iBAAA,EAAoB,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,YAC/C;AAAA,UACF;AAAA,QACF,SAAS,UAAA,EAAY;AACnB,UAAA,MAAA,CAAO,IAAA,CAAK,sDAA4C,UAAU,CAAA;AAAA,QACpE;AAAA,MACF;AAEA,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,QAAA,MAAA,CAAO,YAAY,QAAQ,CAAA;AAAA,MAC7B;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,KAAA,CAAM,oCAAoC,KAAK,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,aAAA,GAAgB,MAAM,MAAA,CAAO,IAAA,EAAK;AACxC,IAAA,OAAO,aAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,sCAAsC,KAAK,CAAA;AACxD,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAWA,eAAsB,4BAAA,CACpB,QAAA,EACA,UAAA,EACA,WAAA,EACA,UAAA,EACqB;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,WAAA,EAAa,GAAA,EAAK,aAAA,EAAc,GAAI,MAAM,UAAA,EAAW;AAC7D,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,EAAS;AAC9B,IAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,SAAA,CAAU,cAAc,SAAS,CAAA;AAE3D,IAAA,KAAA,MAAW,SAAS,UAAA,EAAY;AAChC,MAAA,MAAM,SAAA,GAAY,KAAA,CAAM,QAAA,CAAS,IAAA,GAAO,CAAA;AAExC,MAAA,IAAI,SAAA,GAAY,CAAA,IAAK,SAAA,IAAa,KAAA,CAAM,MAAA,EAAQ;AAC9C,QAAA;AAAA,MACF;AAEE,MAAA,MAAM,IAAA,GAAO,MAAM,SAAS,CAAA;AAC5B,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAW,GAAI,KAAK,OAAA,EAAQ;AAG5C,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,CAAA;AAC5B,MAAA,MAAM,OAAO,UAAA,GAAa,KAAA,CAAM,QAAA,CAAS,CAAA,GAAI,MAAM,QAAA,CAAS,MAAA;AAE5D,MAAA,IAAI;AACF,QAAA,QAAQ,MAAM,IAAA;AAAM,UAClB,KAAA,MAAA,aAAyB;AACvB,YAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,EAAE,CAAA,IAAK,EAAA;AACvC,YAAA,IAAI,KAAA,EAAO;AAET,cAAA,MAAM,WAAW,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,QAAA,IAAY,KAAK,KAAA,CAAM,QAAA,IAAY,EAAA,GACxE,KAAA,CAAM,WACN,IAAA,CAAK,GAAA,CAAI,IAAI,KAAA,CAAM,QAAA,CAAS,SAAS,GAAG,CAAA;AAC5C,cAAA,IAAA,CAAK,SAAS,KAAA,EAAO;AAAA,gBACnB,GAAG,IAAA,GAAO,CAAA;AAAA;AAAA,gBACV,CAAA,EAAG,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,SAAS,QAAA,IAAY,CAAA;AAAA;AAAA,gBAC/C,IAAA,EAAM,QAAA;AAAA,gBACN,IAAA;AAAA,gBACA,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,gBAClB,QAAA,EAAU,KAAA,CAAM,QAAA,CAAS,KAAA,GAAQ;AAAA;AAAA,eAClC,CAAA;AAAA,YACH;AACA,YAAA;AAAA,UACF;AAAA,UAEA,KAAA,MAAA,aAAyB;AACvB,YAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,EAAE,CAAA,IAAK,EAAA;AACvC,YAAA,IAAI,KAAA,EAAO;AACT,cAAA,MAAM,WAAW,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,QAAA,IAAY,KAAK,KAAA,CAAM,QAAA,IAAY,EAAA,GACxE,KAAA,CAAM,WACN,IAAA,CAAK,GAAA,CAAI,IAAI,KAAA,CAAM,QAAA,CAAS,SAAS,GAAG,CAAA;AAC5C,cAAA,IAAA,CAAK,SAAS,KAAA,EAAO;AAAA,gBACnB,GAAG,IAAA,GAAO,CAAA;AAAA,gBACV,CAAA,EAAG,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,SAAS,QAAA,IAAY,CAAA;AAAA,gBAC/C,IAAA,EAAM,QAAA;AAAA,gBACN,IAAA;AAAA,gBACA,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,gBAClB,QAAA,EAAU,KAAA,CAAM,QAAA,CAAS,KAAA,GAAQ;AAAA,eAClC,CAAA;AAAA,YACH;AACA,YAAA;AAAA,UACF;AAAA,UAEA,KAAA,UAAA,iBAA6B;AAC3B,YAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,EAAE,CAAA,IAAK,EAAA;AACvC,YAAA,IAAI,UAAU,MAAA,EAAQ;AAEpB,cAAA,MAAM,SAAA,GAAY,KAAK,GAAA,CAAI,KAAA,CAAM,SAAS,KAAA,EAAO,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,GAAI,GAAA;AAC1E,cAAA,MAAM,MAAA,GAAS,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,QAAQ,SAAA,IAAa,CAAA;AAC3D,cAAA,MAAM,MAAA,GAAS,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,SAAS,SAAA,IAAa,CAAA;AAE5D,cAAA,IAAA,CAAK,SAAS,QAAA,EAAK;AAAA,gBACjB,CAAA,EAAG,MAAA;AAAA,gBACH,CAAA,EAAG,MAAA;AAAA,gBACH,IAAA,EAAM,SAAA;AAAA,gBACN,IAAA;AAAA,gBACA,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC;AAAA,eACnB,CAAA;AAAA,YACH;AACA,YAAA;AAAA,UACF;AAAA,UAEA,KAAA,WAAA,kBAA8B;AAC5B,YAAA,MAAM,gBAAA,GAAmB,UAAA,CAAW,KAAA,CAAM,EAAE,CAAA;AAC5C,YAAA,IAAI,gBAAA,EAAkB;AAEpB,cAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAChD,cAAA,IAAI,CAAC,UAAA,EAAY;AACf,gBAAA,MAAA,CAAO,KAAA,CAAM,8CAAA,EAAgD,KAAA,CAAM,EAAE,CAAA;AACrE,gBAAA;AAAA,cACF;AACA,cAAA,MAAM,UAAA,GAAa,UAAA,CAAW,IAAA,CAAK,IAAA,CAAK,UAAU,GAAG,CAAA,CAAA,KAAK,CAAA,CAAE,UAAA,CAAW,CAAC,CAAC,CAAA;AAGzE,cAAA,MAAM,KAAA,GAAQ,MAAM,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA;AAG9C,cAAA,MAAM,SAAA,GAAY,MAAM,IAAA,EAAK;AAC7B,cAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,QAAA,CAAS,KAAA,GAAQ,MAAM,QAAA,CAAS,MAAA;AAC/D,cAAA,MAAM,gBAAA,GAAmB,SAAA,CAAU,KAAA,GAAQ,SAAA,CAAU,MAAA;AAErD,cAAA,IAAI,SAAA,GAAY,MAAM,QAAA,CAAS,KAAA;AAC/B,cAAA,IAAI,UAAA,GAAa,MAAM,QAAA,CAAS,MAAA;AAEhC,cAAA,IAAI,mBAAmB,gBAAA,EAAkB;AAEvC,gBAAA,UAAA,GAAa,SAAA,GAAY,gBAAA;AAAA,cAC3B,CAAA,MAAO;AAEL,gBAAA,SAAA,GAAY,UAAA,GAAa,gBAAA;AAAA,cAC3B;AAGA,cAAA,MAAM,MAAA,GAAS,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,QAAQ,SAAA,IAAa,CAAA;AAC3D,cAAA,MAAM,MAAA,GAAS,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,SAAS,UAAA,IAAc,CAAA;AAG7D,cAAA,IAAA,CAAK,UAAU,KAAA,EAAO;AAAA,gBACpB,CAAA,EAAG,MAAA;AAAA,gBACH,CAAA,EAAG,MAAA;AAAA,gBACH,KAAA,EAAO,SAAA;AAAA,gBACP,MAAA,EAAQ;AAAA,eACT,CAAA;AAAA,YACH;AACA,YAAA;AAAA,UACF;AAAA,UAEA,KAAA,UAAA,iBAA6B;AAC3B,YAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,EAAE,CAAA,IAAK,EAAA;AACvC,YAAA,IAAI,KAAA,EAAO;AAET,cAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,IAAI,KAAA,CAAM,QAAA,CAAS,SAAS,GAAG,CAAA;AACzD,cAAA,IAAA,CAAK,SAAS,KAAA,EAAO;AAAA,gBACnB,GAAG,IAAA,GAAO,CAAA;AAAA,gBACV,CAAA,EAAG,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,SAAS,QAAA,IAAY,CAAA;AAAA,gBAC/C,IAAA,EAAM,QAAA;AAAA,gBACN,IAAA;AAAA,gBACA,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,gBAClB,QAAA,EAAU,KAAA,CAAM,QAAA,CAAS,KAAA,GAAQ;AAAA,eAClC,CAAA;AAAA,YACH;AACA,YAAA;AAAA,UACF;AAAA,UAEA,KAAA,UAAA,iBAA6B;AAC3B,YAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,EAAE,CAAA,IAAK,EAAA;AACvC,YAAA,IAAI,KAAA,EAAO;AACT,cAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,IAAI,KAAA,CAAM,QAAA,CAAS,SAAS,GAAG,CAAA;AACzD,cAAA,IAAA,CAAK,SAAS,KAAA,EAAO;AAAA,gBACnB,GAAG,IAAA,GAAO,CAAA;AAAA,gBACV,CAAA,EAAG,IAAA,GAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,SAAS,QAAA,IAAY,CAAA;AAAA,gBAC/C,IAAA,EAAM,QAAA;AAAA,gBACN,IAAA;AAAA,gBACA,KAAA,EAAO,GAAA,CAAI,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,gBAClB,QAAA,EAAU,KAAA,CAAM,QAAA,CAAS,KAAA,GAAQ;AAAA,eAClC,CAAA;AAAA,YACH;AACA,YAAA;AAAA,UACF;AAAA,UAEF;AACE,YAAA;AAAA;AACJ,MACF,SAAS,UAAA,EAAY;AACnB,QAAA,MAAA,CAAO,KAAA,CAAM,CAAA,uBAAA,EAA0B,KAAA,CAAM,IAAI,KAAK,UAAU,CAAA;AAAA,MAClE;AAAA,IACF;AAEA,IAAA,OAAO,MAAM,OAAO,IAAA,EAAK;AAAA,EAC3B,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,8BAA8B,KAAK,CAAA;AAChD,IAAA,MAAM,KAAA;AAAA,EACR;AACA;AAMA,eAAsB,oBACpB,QAAA,EAIC;AACD,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM,UAAA,EAAW;AACzC,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,IAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,EAAS;AAE9B,IAAA,MAAM,UAAkC,EAAC;AACzC,IAAA,MAAM,cAAiD,EAAC;AAExD,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,EAAQ;AAChC,MAAA,MAAM,aAAA,GAAgB,KAAA;AACtB,MAAA,MAAM,OAAA,GAAU,aAAA,CAAc,SAAA,EAAW,UAAA,QAAkB,EAAC;AAE5D,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AAEtB,QAAA,MAAM,MAAA,GAAS,QAAQ,CAAC,CAAA;AACxB,QAAA,IAAI,CAAC,MAAA,EAAQ;AACb,QAAA,MAAM,IAAA,GAAO,OAAO,YAAA,IAAe;AACnC,QAAA,MAAM,OAAA,GAAU,OAAO,CAAA,IAAI;AAE3B,QAAA,IAAI,QAAQ,OAAA,EAAS;AAEnB,UAAA,MAAM,SAAA,GAAY,kBAAA,CAAmB,KAAA,EAAO,OAAO,CAAA;AAEnD,UAAA,IAAI,cAAc,CAAA,CAAA,EAAI;AACpB,YAAA,MAAM,aAAa,SAAA,GAAY,CAAA;AAC/B,YAAA,OAAA,CAAQ,SAAS,CAAA,GAAI,UAAA;AAGrB,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI;AAAA,cACvB,GAAG,IAAA,CAAK,CAAA;AAAA,cACR,GAAG,IAAA,CAAK,CAAA;AAAA,cACR,OAAO,IAAA,CAAK,KAAA;AAAA,cACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,cACb,IAAA,EAAM;AAAA,aACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEF,IAAA,OAAO,EAAE,SAAS,WAAA,EAAY;AAAA,EAChC,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAC1D,IAAA,OAAO,EAAE,OAAA,EAAS,EAAC,EAAG,WAAA,EAAa,EAAC,EAAE;AAAA,EACxC;AACA;;;ACjhDA,IAAIC,QAAAA;AAwBJ,eAAsB,wBAAA,CACpB,UACA,kBAAA,EAC2B;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,YAAA,GAAe,MAAM,UAAA,EAAW;AACtC,IAAA,MAAM,EAAE,WAAA,EAAa,eAAA,EAAiB,OAAA,EAAS,cAAa,GAAI,YAAA;AAChE,IAAAA,QAAAA,GAAU,YAAA;AAGV,IAAA,eAAA,CAAgB,YAAY,CAAA;AAE5B,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AAG9C,IAAA,MAAM,QAAA,GAAW,oBAAoB,MAAM,CAAA;AAE3C,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,IAAA,MAAM,gBAAkC,EAAC;AACzC,IAAA,IAAI,oBAAA,GAAuB,KAAA;AAC3B,IAAA,IAAI,iCAAA,GAAoC,KAAA;AAExC,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAM,OAAA,EAAQ;AAGhC,MAAA,MAAM,mBAAA,GAAsB,KAAA;AAC5B,MAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,UAAA,QAAkB,EAAC;AAElE,MAAA,IAAI,SAAA,GAAY,IAAA;AAGhB,MAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,QAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,OAAA,GAAU,eAAA,CAAgB,MAAM,CAAA,IAAK,KAAA;AAClE,QAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,OAAA,GAAU,eAAA,CAAgB,MAAM,CAAA,IAAK,KAAA;AAElE,QAAA,IAAI,iBAAiB,aAAA,EAAe;AAClC,UAAA,SAAA,GAAY,KAAA;AACZ,UAAA;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,MAAM,yBAAA,GAA4B,SAAA,CAAU,OAAA,CAAQ,gCAAA,EAAkC,EAAE,CAAA;AAIxF,QAAA,MAAM,aAAA,GAA+B,UAAU,MAAA,CAAO,SAAS,KAC1D,QAAA,EAAU,MAAA,CAAO,yBAAyB,CAAA,IAAA,CACzC,MAAM;AAER,UAAA,MAAM,OAAA,GAAU,gBAAgB,SAAS,CAAA;AACzC,UAAA,OAAO;AAAA,YACL,OAAO,OAAA,CAAQ,YAAA;AAAA,YACf,QAAQ,OAAA,CAAQ,mBAAA;AAAA,YAChB,aAAa,OAAA,CAAQ,gBAAA;AAAA,YACrB,kBAAkB,OAAA,CAAQ;AAAA,WAC5B;AAAA,QACF,CAAA,GAAG;AAUL,QAAA,IAAI,SAAA,GAAA,MAAA;AACJ,QAAA,MAAM,aAAA,GAAgB,MAAM,WAAA,CAAY,IAAA;AAGxC,QAAA,MAAM,cAAA,GAAiB,SAAA,CAAU,OAAA,CAAQ,gCAAA,EAAkC,EAAE,CAAA;AAI7E,QAAA,MAAM,yBAAyB,aAAA,CAAc,QAAA,CAAS,WAAW,CAAA,IAC9D,cAAA,CAAe,aAAY,CAAE,QAAA,CAAS,WAAW,CAAA,IACjD,CAAC,cAAc,QAAA,CAAS,UAAU,KAClC,CAAC,aAAA,CAAc,SAAS,OAAO,CAAA;AAClC,QAAA,MAAM,qBAAA,GAAwB,cAAA,CAAe,WAAA,EAAY,CAAE,SAAS,UAAU,CAAA,IAC5E,CAAC,aAAA,CAAc,SAAS,UAAU,CAAA,IAClC,CAAC,aAAA,CAAc,SAAS,OAAO,CAAA;AAEjC,QAAA,IAAI,sBAAA,EAAwB;AAC1B,UAAA,SAAA,GAAA,WAAA;AAAA,QACF,WAAW,qBAAA,EAAuB;AAChC,UAAA,SAAA,GAAA,UAAA;AAKA,UAAA,oBAAA,GAAuB,IAAA;AAGvB,UAAA,IAAI,kBAAA,IAAsB,aAAA,CAAc,MAAA,KAAW,kBAAA,EAAoB;AACrE,YAAA,iCAAA,GAAoC,IAAA;AAAA,UACtC;AAAA,QACF,WAAW,cAAA,CAAe,WAAA,EAAY,CAAE,QAAA,CAAS,MAAM,CAAA,EAAG;AACxD,UAAA,SAAA,GAAA,MAAA;AAAA,QACF,CAAA,MAAA,IAAW,aAAA,CAAc,QAAA,CAAS,UAAU,CAAA,EAAG;AAC7C,UAAA,SAAA,GAAA,UAAA;AAAA,QACF,WAAW,aAAA,CAAc,WAAA,EAAY,CAAE,QAAA,CAAS,UAAU,CAAA,EAAG;AAC3D,UAAA,SAAA,GAAA,UAAA;AAAA,QACF,CAAA,MAAA,IAAW,aAAA,CAAc,QAAA,CAAS,OAAO,CAAA,EAAG;AAC1C,UAAA,SAAA,GAAA,OAAA;AAAA,QACF;AAGA,QAAA,IAAI,YAAA,GAAe,cAAc,KAAA,IAAS,EAAA;AAG1C,QAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,YAAA,CAAa,MAAK,EAAG;AACzC,UAAA,IAAI;AACF,YAAA,MAAM,OAAA,GAAU,eAAe,mBAAmB,CAAA;AAClD,YAAA,IAAI,OAAA,IAAW,OAAA,CAAQ,IAAA,EAAK,EAAG;AAC7B,cAAA,YAAA,GAAe,OAAA;AAAA,YACjB;AAAA,UACF,SAAS,OAAA,EAAS;AAAA,UAClB;AAAA,QACF;AAKA,QAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,YAAA,CAAa,MAAK,EAAG;AACzC,UAAA,YAAA,GAAe,qBAAA,CAAsB,gBAAgB,SAAS,CAAA;AAAA,QAChE;AAGA,QAAA,MAAM,UAAA,GAA6B;AAAA,UACjC,EAAA,EAAI,SAAA;AAAA;AAAA,UACJ,OAAA,EAAS,cAAc,OAAA,IAAW,SAAA;AAAA;AAAA,UAClC,IAAA,EAAM,SAAA;AAAA;AAAA,UACN,IAAA,EAAM,SAAA;AAAA,UACN,KAAA,EAAO,YAAA;AAAA;AAAA,UACP,QAAA,EAAU,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAM,CAAA,EAAE;AAAA;AAAA,UACxD,QAAA,EAAU,mBAAA,CAAoB,UAAA,IAAa,IAAK,KAAA;AAAA,UAChD,WAAA,EAAa,cAAc,WAAA,IAAe,EAAA;AAAA;AAAA,UAC1C,qBAAqB,aAAA,CAAc,MAAA;AAAA;AAAA,UACnC,kBAAkB,aAAA,CAAc;AAAA;AAAA,SAClC;AAGA,QAAA,IAAI,2CAAwC,SAAA,KAAA,OAAA,cAAmC;AAC7E,UAAA,IAAI;AACF,YAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,UAAA,IAAa,IAAK,EAAC;AACvD,YAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,YAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AAAA,YACxB;AAAA,UACF,SAAS,KAAA,EAAO;AACd,YAAA,MAAA,CAAO,IAAA,CAAK,uCAAuC,KAAK,CAAA;AAAA,UAC1D;AAAA,QACF;AAEA,QAAA,aAAA,CAAc,KAAK,UAAU,CAAA;AAAA,MAC/B;AAAA,IACF;AAIA,IAAA,MAAM,aAA+B,EAAC;AAGtC,IAAA,UAAA,CAAW,IAAA,CAAK;AAAA,MACd,EAAA,EAAI,sBAAA;AAAA,MACJ,OAAA,EAAS,sBAAA;AAAA;AAAA,MACT,IAAA,EAAM,sBAAA;AAAA,MACN,IAAA,EAAA,WAAA;AAAA,MACA,KAAA,EAAO,0DAAA;AAAA,MACP,QAAA,EAAU,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAM,CAAA,EAAE;AAAA,MACxD,QAAA,EAAU,IAAA;AAAA,MACV,WAAA,EAAa,+BAAA;AAAA,MACb,mBAAA,EAAqB;AAAA,KACtB,CAAA;AAQD,IAAA,MAAM,yBAAA,GAA4B,iCAAA,IAC/B,oBAAA,IAAwB,CAAC,kBAAA;AAE5B,IAAA,IAAI,yBAAA,EAA2B;AAC7B,MAAA,IAAI,iCAAA,EAAmC;AAAA,MACvC,CAAA,MAAO;AAAA,MACP;AAEA,MAAA,UAAA,CAAW,IAAA,CAAK;AAAA,QACd,EAAA,EAAI,qBAAA;AAAA,QACJ,OAAA,EAAS,qBAAA;AAAA;AAAA,QACT,IAAA,EAAM,qBAAA;AAAA,QACN,IAAA,EAAA,UAAA;AAAA,QACA,KAAA,EAAO,wDAAA;AAAA,QACP,QAAA,EAAU,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAM,CAAA,EAAE;AAAA,QACxD,QAAA,EAAU,IAAA;AAAA,QACV,WAAA,EAAa,qBAAA;AAAA,QACb,mBAAA,EAAqB;AAAA,OACtB,CAAA;AAAA,IACH;AAGA,IAAA,OAAO,CAAC,GAAG,UAAA,EAAY,GAAG,aAAa,CAAA;AAAA,EACzC,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,kDAAkD,KAAK,CAAA;AACpE,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAUO,SAAS,gBAAgB,SAAA,EAM9B;AACA,EAAA,IAAI,gBAAA,GAAmB,SAAA;AACvB,EAAA,IAAI,YAAA,GAAe,EAAA;AACnB,EAAA,IAAI,mBAAA,GAA0C,MAAA;AAC9C,EAAA,IAAI,gBAAA,GAAmB,EAAA;AACvB,EAAA,IAAI,gBAAA,GAAwF,MAAA;AAG5F,EAAA,IAAI,SAAA,CAAU,QAAA,CAAS,SAAS,CAAA,EAAG;AACjC,IAAA,MAAM,cAAA,GAAiB,SAAA,CAAU,OAAA,CAAQ,SAAS,CAAA;AAClD,IAAA,MAAM,SAAA,GAAY,SAAA,CAAU,SAAA,CAAU,CAAA,EAAG,cAAc,CAAA;AACvD,IAAA,MAAM,UAAA,GAAa,SAAA,CAAU,SAAA,CAAU,cAAA,GAAiB,CAAC,CAAA;AAEzD,IAAA,IAAI;AAEF,MAAA,MAAM,OAAA,GAAU,KAAK,UAAU,CAAA;AAC/B,MAAA,gBAAA,GAAmB,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,IACvC,SAAS,CAAA,EAAG;AACV,MAAA,OAAA,CAAQ,IAAA,CAAK,sCAAsC,CAAC,CAAA;AAAA,IACtD;AAGA,IAAA,SAAA,GAAY,SAAA;AACZ,IAAA,gBAAA,GAAmB,SAAA;AAAA,EACrB;AAGA,EAAA,IAAI,SAAA,CAAU,QAAA,CAAS,WAAW,CAAA,EAAG;AACnC,IAAA,MAAM,gBAAA,GAAmB,SAAA,CAAU,OAAA,CAAQ,WAAW,CAAA;AACtD,IAAA,gBAAA,GAAmB,SAAA,CAAU,SAAA,CAAU,CAAA,EAAG,gBAAgB,CAAA;AAE1D,IAAA,MAAM,UAAA,GAAa,SAAA,CAAU,SAAA,CAAU,gBAAA,GAAmB,CAAC,CAAA;AAG3D,IAAA,IAAI,UAAA,CAAW,QAAA,CAAS,YAAY,CAAA,EAAG;AACrC,MAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,OAAA,CAAQ,YAAY,CAAA;AACzD,MAAA,YAAA,GAAe,UAAA,CAAW,SAAA,CAAU,CAAA,EAAG,iBAAiB,CAAA;AACxD,MAAA,MAAM,WAAA,GAAc,UAAA,CAAW,SAAA,CAAU,iBAAA,GAAoB,EAAE,CAAA;AAG/D,MAAA,IAAI,WAAA,CAAY,QAAA,CAAS,iBAAiB,CAAA,EAAG;AAC3C,QAAA,MAAM,sBAAA,GAAyB,WAAA,CAAY,OAAA,CAAQ,iBAAiB,CAAA;AACpE,QAAA,mBAAA,GAAsB,WAAA,CAAY,SAAA,CAAU,CAAA,EAAG,sBAAsB,CAAA;AACrE,QAAA,gBAAA,GAAmB,WAAA,CAAY,SAAA,CAAU,sBAAA,GAAyB,EAAE,CAAA;AAAA,MACtE,CAAA,MAAO;AACL,QAAA,mBAAA,GAAsB,WAAA;AAAA,MACxB;AAAA,IACF,CAAA,MAAA,IAAW,UAAA,CAAW,QAAA,CAAS,iBAAiB,CAAA,EAAG;AAEjD,MAAA,MAAM,sBAAA,GAAyB,UAAA,CAAW,OAAA,CAAQ,iBAAiB,CAAA;AACnE,MAAA,YAAA,GAAe,UAAA,CAAW,SAAA,CAAU,CAAA,EAAG,sBAAsB,CAAA;AAC7D,MAAA,gBAAA,GAAmB,UAAA,CAAW,SAAA,CAAU,sBAAA,GAAyB,EAAE,CAAA;AAAA,IACrE,CAAA,MAAO;AACL,MAAA,YAAA,GAAe,UAAA;AAAA,IACjB;AAAA,EACF,CAAA,MAAA,IAAW,SAAA,CAAU,QAAA,CAAS,YAAY,CAAA,EAAG;AAE3C,IAAA,MAAM,iBAAA,GAAoB,SAAA,CAAU,OAAA,CAAQ,YAAY,CAAA;AACxD,IAAA,gBAAA,GAAmB,SAAA,CAAU,SAAA,CAAU,CAAA,EAAG,iBAAiB,CAAA;AAC3D,IAAA,MAAM,WAAA,GAAc,SAAA,CAAU,SAAA,CAAU,iBAAA,GAAoB,EAAE,CAAA;AAG9D,IAAA,IAAI,WAAA,CAAY,QAAA,CAAS,iBAAiB,CAAA,EAAG;AAC3C,MAAA,MAAM,sBAAA,GAAyB,WAAA,CAAY,OAAA,CAAQ,iBAAiB,CAAA;AACpE,MAAA,mBAAA,GAAsB,WAAA,CAAY,SAAA,CAAU,CAAA,EAAG,sBAAsB,CAAA;AACrE,MAAA,gBAAA,GAAmB,WAAA,CAAY,SAAA,CAAU,sBAAA,GAAyB,EAAE,CAAA;AAAA,IACtE,CAAA,MAAO;AACL,MAAA,mBAAA,GAAsB,WAAA;AAAA,IACxB;AAAA,EACF,CAAA,MAAA,IAAW,SAAA,CAAU,QAAA,CAAS,iBAAiB,CAAA,EAAG;AAEhD,IAAA,MAAM,sBAAA,GAAyB,SAAA,CAAU,OAAA,CAAQ,iBAAiB,CAAA;AAClE,IAAA,gBAAA,GAAmB,SAAA,CAAU,SAAA,CAAU,CAAA,EAAG,sBAAsB,CAAA;AAChE,IAAA,gBAAA,GAAmB,SAAA,CAAU,SAAA,CAAU,sBAAA,GAAyB,EAAE,CAAA;AAAA,EACpE;AAEA,EAAA,OAAO;AAAA,IACL,gBAAA;AAAA,IACA,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,SAAS,qBAAA,CAAsB,kBAA0B,SAAA,EAAkC;AAChG,EAAA,IAAI,YAAA,GAAe,gBAAA;AAGnB,EAAA,YAAA,GAAe,YAAA,CAAa,OAAA,CAAQ,cAAA,EAAgB,EAAE,CAAA,CAAE,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA,CAAE,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA;AAOxG,EAAA,IAAI,uCAAA,CAAwC,IAAA,CAAK,YAAY,CAAA,EAAG;AAE9D,IAAA,IAAI,2CAAuC,OAAO,WAAA;AAClD,IAAA,IAAI,yCAAsC,OAAO,UAAA;AACjD,IAAA,IAAI,iCAAkC,OAAO,MAAA;AAC7C,IAAA,IAAI,iCAAkC,OAAO,MAAA;AAC7C,IAAA,IAAI,yCAAsC,OAAO,UAAA;AACjD,IAAA,IAAI,yCAAsC,OAAO,UAAA;AACjD,IAAA,IAAI,mCAAmC,OAAO,QAAA;AAAA,EAChD,CAAA,MAAO;AAEL,IAAA,YAAA,GAAe,YAAA,CACZ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,CACtB,IAAA,EAAK,CACL,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,CACtE,KAAK,GAAG,CAAA;AAAA,EACb;AAEA,EAAA,OAAO,YAAA;AACT;AAOA,SAAS,eAAe,KAAA,EAAuC;AAC7D,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,KAAA,CAAM,SAAA,EAAW,IAAA,EAAM;AAC1B,MAAA,OAAO,EAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,MAAM,SAAA,CAAU,IAAA,CAAK,IAAIA,QAAAA,CAAQ,EAAA,CAAG,IAAI,CAAC,CAAA;AACzD,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,EAAA;AAAA,IACT;AAGA,IAAA,MAAM,OAAA,GAAU,QAAQ,QAAA,EAAS;AACjC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,CAAQ,MAAK,EAAG;AAC/B,MAAA,OAAO,EAAA;AAAA,IACT;AAIA,IAAA,IAAI,QAAQ,UAAA,CAAW,GAAG,KAAK,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AACtD,MAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAA,IAAK,OAAA,CAAQ,MAAM,UAAU,CAAA;AACrE,MAAA,IAAI,KAAA,IAAS,KAAA,CAAM,CAAC,CAAA,EAAG;AACrB,QAAA,OAAO,MAAM,CAAC,CAAA;AAAA,MAChB;AAAA,IACF;AAGA,IAAA,OAAO,OAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AC/YO,IAAM,UAAA,GAAa;AACnB,IAAM,UAAA,GAAa;AAK1B,IAAI,kBAAA,GAAqB,KAAA;AACzB,IAAI,gBAAA,GAAkC,IAAA;AAWtC,SAAS,mBAAA,GAA8B;AAErC,EAAA,IAAI,kBAAA,IAAsB,qBAAqB,IAAA,EAAM;AACnD,IAAA,OAAO,gBAAA;AAAA,EACT;AAGA,EAAA,IAAI,SAAA,GAAY,6BAAA;AAGhB,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,QAAQ,WAAA,EAAa;AAC/D,IAAA,IAAI;AAGF,MAAA,MAAM,QAAQ,WAAW;AACvB,QAAA,IAAI;AAEF,UAAA,OAAO,IAAI,QAAA,CAAS,oBAAoB,CAAA,EAAE;AAAA,QAC5C,CAAA,CAAA,MAAQ;AACN,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,MACF,CAAA,GAAG;AAEH,MAAA,IAAI,IAAA,IAAQ,KAAK,GAAA,EAAK;AACpB,QAAA,SAAA,GAAY,IAAI,GAAA,CAAI,iCAAA,EAAmC,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA;AAAA,MACnE;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAGR;AAAA,EACF;AAGA,EAAA,kBAAA,GAAqB,IAAA;AACrB,EAAA,gBAAA,GAAmB,SAAA;AAEnB,EAAA,OAAO,SAAA;AACT;AAeA,IAAI,YAAA,GAAsC;AAAA,EACxC,cAAA,EAAgB,QAAA;AAAA,EAChB,SAAA,EAAW;AAAA;AACb,CAAA;AAGA,IAAI,kBAAA,GAAqB,KAAA;AAKzB,SAAS,uBAAA,GAAgC;AACvC,EAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,IAAA,YAAA,CAAa,YAAY,mBAAA,EAAoB;AAC7C,IAAA,kBAAA,GAAqB,IAAA;AAGrB,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAASC,oBAAA,CAAA,mBAAA,CAAoB,YAAY,YAAA,CAAa,SAAA;AAAA,IACxD;AAAA,EACF;AACF;AAiBO,SAAS,eAAe,MAAA,EAAoC;AAEjE,EAAA,uBAAA,EAAwB;AAExB,EAAA,IAAI,MAAA,CAAO,mBAAmB,MAAA,EAAW;AACvC,IAAA,YAAA,CAAa,iBAAiB,MAAA,CAAO,cAAA;AAAA,EACvC;AAEA,EAAA,IAAI,MAAA,CAAO,cAAc,MAAA,EAAW;AAClC,IAAA,YAAA,CAAa,YAAY,MAAA,CAAO,SAAA;AAAA,EAClC,CAAA,MAAA,IAAW,MAAA,CAAO,cAAA,KAAmB,MAAA,EAAW;AAE9C,IAAA,YAAA,CAAa,SAAA,GAAY,CAAA,EAAG,MAAA,CAAO,cAAc,CAAA,qBAAA,CAAA;AAAA,EACnD;AAGA,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAASA,oBAAA,CAAA,mBAAA,CAAoB,YAAY,YAAA,CAAa,SAAA;AAAA,EACxD;AACF;AAMO,SAAS,cAAA,GAAwC;AAEtD,EAAA,uBAAA,EAAwB;AACxB,EAAA,OAAO,EAAE,GAAG,YAAA,EAAa;AAC3B;AAKO,SAAS,gBAAA,GAAyB;AAEvC,EAAA,kBAAA,GAAqB,KAAA;AACrB,EAAA,gBAAA,GAAmB,IAAA;AACnB,EAAA,kBAAA,GAAqB,KAAA;AAGrB,EAAA,uBAAA,EAAwB;AAC1B;AAUO,SAAS,eAAA,GAAwB;AACtC,EAAA,uBAAA,EAAwB;AAC1B;ACpKA,eAAsB,iBAAA,CACpB,iBAAyB,QAAA,EACS;AAClC,EAAA,MAAM,aAAA,GAAyBC,oBAAA,CAAA,OAAA;AAE/B,EAAA,IAAI;AAEF,IAAA,MAAM,UAAA,GAAa,GAAG,cAAc,CAAA,SAAA,CAAA;AACpC,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,UAAU,CAAA;AAEvC,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAO;AAAA,QACL,YAAA,EAAc,KAAA;AAAA,QACd,YAAA,EAAc,KAAA;AAAA,QACd,aAAA;AAAA,QACA,YAAA,EAAc;AAAA,OAChB;AAAA,IACF;AAEA,IAAA,MAAM,aAAA,GAAA,CAAiB,MAAM,QAAA,CAAS,IAAA,IAAQ,IAAA,EAAK;AACnD,IAAA,MAAM,eAAe,aAAA,KAAkB,aAAA;AAEvC,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,OAAO;AAAA,QACL,YAAA,EAAc,IAAA;AAAA,QACd,YAAA,EAAc,KAAA;AAAA,QACd,aAAA;AAAA,QACA,aAAA;AAAA,QACA,YAAA,EAAc,CAAA,yBAAA,EAA4B,aAAa,CAAA,SAAA,EAAY,aAAa,CAAA,yBAAA;AAAA,OAClF;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,IAAA;AAAA,MACd,YAAA,EAAc,IAAA;AAAA,MACd,aAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,KAAA;AAAA,MACd,YAAA,EAAc,KAAA;AAAA,MACd,aAAA;AAAA,MACA,YAAA,EAAc;AAAA,KAChB;AAAA,EACF;AACF;AAMO,SAAS,uBAAuB,MAAA,EAAuC;AAC5E,EAAA,IAAI,CAAC,OAAO,YAAA,EAAc;AACxB,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KAIF;AAAA,EACF,CAAA,MAAA,IAAW,CAAC,MAAA,CAAO,YAAA,EAAc;AAC/B,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,CAAA;AAAA,WAAA,EACc,OAAO,aAAa;AAAA,WAAA,EACpB,OAAO,aAAa;AAAA,wCAAA;AAAA,KAEpC;AAAA,EACF;AACF;AAMA,eAAsB,uBAAA,CACpB,iBAAyB,QAAA,EACS;AAClC,EAAA,MAAM,MAAA,GAAS,MAAM,iBAAA,CAAkB,cAAc,CAAA;AAErD,EAAA,IAAI,CAAC,MAAA,CAAO,YAAA,IAAgB,CAAC,OAAO,YAAA,EAAc;AAChD,IAAA,sBAAA,CAAuB,MAAM,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,MAAA;AACT;;;AC7FO,SAAS,qBAAA,GAAqD;AACnE,EAAA,MAAM,WAAwC,EAAC;AAE/C,EAAA,IAAI;AAEF,IAAA,IAAI,UAAU,SAAA,EAAW;AACvB,MAAA,QAAA,CAAS,SAAA,GAAY,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,GAAG,GAAG,CAAA;AAAA,IAC3D;AAGA,IAAA,IAAI,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,MAAA,EAAQ;AACjC,MAAA,QAAA,CAAS,mBAAmB,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,CAAA,EAAI,OAAO,MAAM,CAAA,CAAA;AAAA,IAC9D;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,cAAA,EAAe,CAAE,iBAAgB,CAAE,QAAA;AACzD,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,QAAA,GAAW,QAAA;AAAA,MACtB;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAGA,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,QAAA,CAAS,WAAW,SAAA,CAAU,QAAA;AAAA,IAChC;AAGA,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,QAAA,CAAS,WAAW,SAAA,CAAU,QAAA;AAAA,IAChC;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,IAAA,CAAK,oCAAoC,KAAK,CAAA;AAAA,EACvD;AAEA,EAAA,OAAO,QAAA;AACT;AAKA,eAAsB,gBAAA,GAAoC;AACxD,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,YAAY,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,GAAI,CAAA;AAE3D,IAAA,MAAM,UAAA,GAAa,MAAM,KAAA,CAAM,mCAAA,EAAqC;AAAA,MAClE,MAAA,EAAQ,KAAA;AAAA,MACR,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AAED,IAAA,YAAA,CAAa,SAAS,CAAA;AAEtB,IAAA,IAAI,WAAW,EAAA,EAAI;AACjB,MAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,IAAA,EAAK;AACrC,MAAA,IAAI,OAAO,EAAA,EAAI;AACb,QAAA,OAAO,MAAA,CAAO,EAAA;AAAA,MAChB;AAAA,IACF;AAEA,IAAA,OAAO,SAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,SAAA;AAAA,EACT;AACF;AAKA,eAAsB,kBAAA,GAIZ;AACR,EAAA,IAAI,CAAC,UAAU,WAAA,EAAa;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,WAAW,MAAM,IAAI,OAAA,CAA6B,CAAC,SAAS,MAAA,KAAW;AAC3E,MAAA,SAAA,CAAU,WAAA,CAAY,kBAAA,CAAmB,OAAA,EAAS,MAAA,EAAQ;AAAA,QACxD,OAAA,EAAS,GAAA;AAAA;AAAA,QACT,kBAAA,EAAoB,KAAA;AAAA,QACpB,UAAA,EAAY;AAAA;AAAA,OACb,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,MAAM,WAAW,UAAA,CAAW,QAAA,CAAS,OAAO,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAC,CAAA;AAC/D,MAAA,MAAM,YAAY,UAAA,CAAW,QAAA,CAAS,OAAO,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,CAAA;AACjE,MAAA,MAAM,QAAA,GAAW,SAAS,MAAA,CAAO,QAAA,GAC7B,KAAK,KAAA,CAAM,QAAA,CAAS,MAAA,CAAO,QAAQ,CAAA,GACnC,KAAA,CAAA;AAGJ,MAAA,OAAO;AAAA,QACL,QAAA;AAAA,QACA,SAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMA,eAAsB,iBAAA,GAAiD;AAErE,EAAA,MAAM,aAAiC,EAAC;AAExC,EAAA,IAAI;AAEF,IAAA,MAAM,iBAAiB,qBAAA,EAAsB;AAC7C,IAAA,MAAA,CAAO,MAAA,CAAO,YAAY,cAAc,CAAA;AAGxC,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,MAAM,gBAAA,EAAiB;AACzC,MAAA,UAAA,CAAW,SAAA,GAAY,SAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,IAAA,CAAK,+BAA+B,KAAK,CAAA;AAChD,MAAA,UAAA,CAAW,SAAA,GAAY,SAAA;AAAA,IACzB;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,kBAAA,EAAmB;AAC7C,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,UAAA,CAAW,WAAA,GAAc,WAAA;AAAA,MAC3B;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,IAAA,CAAK,gCAAgC,KAAK,CAAA;AAAA,IACnD;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,IAAA,CAAK,gCAAgC,KAAK,CAAA;AAAA,EACnD;AAEA,EAAA,OAAO,UAAA;AACT;;;AC7IO,IAAM,kBAAA,GAAN,MAAM,mBAAA,SAA2B,KAAA,CAAM;AAAA,EAC5C,WAAA,CACE,SACgB,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAFG,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAEZ,IAAA,IAAI,MAAM,iBAAA,EAAmB;AAC3B,MAAA,KAAA,CAAM,iBAAA,CAAkB,MAAM,mBAAkB,CAAA;AAAA,IAClD;AAAA,EACF;AACF;AAcO,IAAM,kBAAA,GAAN,MAAM,mBAAA,SAA2B,KAAA,CAAM;AAAA,EAC5C,WAAA,CACE,SACgB,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAFG,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAI,MAAM,iBAAA,EAAmB;AAC3B,MAAA,KAAA,CAAM,iBAAA,CAAkB,MAAM,mBAAkB,CAAA;AAAA,IAClD;AAAA,EACF;AACF;AAeO,IAAM,cAAA,GAAN,MAAM,eAAA,SAAuB,KAAA,CAAM;AAAA,EACxC,WAAA,CACE,OAAA,EACgB,SAAA,EACA,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHG,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,IAAI,MAAM,iBAAA,EAAmB;AAC3B,MAAA,KAAA,CAAM,iBAAA,CAAkB,MAAM,eAAc,CAAA;AAAA,IAC9C;AAAA,EACF;AACF;AAeO,IAAM,yBAAA,GAAN,MAAM,0BAAA,SAAkC,KAAA,CAAM;AAAA,EACnD,WAAA,CACE,OAAA,EACgB,QAAA,EACA,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHG,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,IAAI,MAAM,iBAAA,EAAmB;AAC3B,MAAA,KAAA,CAAM,iBAAA,CAAkB,MAAM,0BAAyB,CAAA;AAAA,IACzD;AAAA,EACF;AACF;AAKO,SAAS,qBAAqB,KAAA,EAA6C;AAChF,EAAA,OAAO,KAAA,YAAiB,kBAAA;AAC1B;AAKO,SAAS,qBAAqB,KAAA,EAA6C;AAChF,EAAA,OAAO,KAAA,YAAiB,kBAAA;AAC1B;AAKO,SAAS,iBAAiB,KAAA,EAAyC;AACxE,EAAA,OAAO,KAAA,YAAiB,cAAA;AAC1B;AAKO,SAAS,4BAA4B,KAAA,EAAoD;AAC9F,EAAA,OAAO,KAAA,YAAiB,yBAAA;AAC1B;AAmBO,SAAS,eAAA,CAAgB,KAAA,EAAgB,cAAA,GAAiB,eAAA,EAAyB;AACxF,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,OAAO,KAAA,CAAM,OAAA;AAAA,EACf;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,cAAA;AACT;;;ACvJO,IAAM,8BAAA,GAAwD;AAAA,EACnE,WAAA,EAAa,KAAK,IAAA,GAAO,IAAA;AAAA;AAAA,EACzB,YAAA,EAAc,KAAK,IAAA,GAAO,IAAA;AAAA;AAAA,EAC1B,QAAA,EAAU,EAAA;AAAA,EACV,YAAA,EAAc,CAAC,SAAA,EAAW,iBAAA,EAAmB,sBAAsB,yEAAyE,CAAA;AAAA,EAC5I,iBAAA,EAAmB,CAAC,MAAA,EAAQ,MAAA,EAAQ,SAAS,MAAA,EAAQ,MAAA,EAAQ,QAAQ,OAAO;AAC9E;AAiBO,SAAS,YAAA,CACd,IAAA,EACA,WAAA,GAAqC,8BAAA,EAIrC;AACA,EAAA,MAAM,SAAmB,EAAC;AAG1B,EAAA,IAAI,IAAA,CAAK,IAAA,GAAO,WAAA,CAAY,WAAA,EAAa;AACvC,IAAA,MAAM,SAAS,WAAA,CAAY,WAAA,GAAc,IAAA,GAAO,IAAA,EAAM,QAAQ,CAAC,CAAA;AAC/D,IAAA,MAAM,UAAU,IAAA,CAAK,IAAA,GAAO,IAAA,GAAO,IAAA,EAAM,QAAQ,CAAC,CAAA;AAClD,IAAA,MAAA,CAAO,IAAA,CAAK,SAAS,IAAA,CAAK,IAAI,mBAAmB,MAAM,CAAA,qBAAA,EAAwB,KAAK,CAAA,GAAA,CAAK,CAAA;AAAA,EAC3F;AAGA,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,YAAA,CAAa,IAAA,CAAK,CAAC,WAAA,KAAgB;AACnE,IAAA,IAAI,WAAA,CAAY,QAAA,CAAS,IAAI,CAAA,EAAG;AAE9B,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AACtC,MAAA,OAAO,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,KAAK,IAAA,KAAS,WAAA;AAAA,EACvB,CAAC,CAAA;AAED,EAAA,IAAI,CAAC,aAAA,IAAiB,WAAA,CAAY,YAAA,CAAa,SAAS,CAAA,EAAG;AACzD,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,CAAA,WAAA,EAAc,IAAA,CAAK,IAAI,CAAA,sBAAA,EAAyB,IAAA,CAAK,IAAI,CAAA,kBAAA,EAAqB,WAAA,CAAY,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KACnH;AAAA,EACF;AAGA,EAAA,IAAI,WAAA,CAAY,iBAAA,IAAqB,WAAA,CAAY,iBAAA,CAAkB,SAAS,CAAA,EAAG;AAC7E,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,IAAA,CAAK,MAAM,GAAG,CAAA,CAAE,GAAA,EAAI,EAAG,WAAA,EAAY;AAC9D,IAAA,MAAM,YAAA,GAAe,YAAY,iBAAA,CAAkB,IAAA;AAAA,MACjD,CAAC,GAAA,KAAQ,GAAA,CAAI,WAAA,EAAY,KAAM;AAAA,KACjC;AAEA,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,gBAAA,EAAmB,OAAO,CAAA,sBAAA,EAAyB,IAAA,CAAK,IAAI,0BAA0B,WAAA,CAAY,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,OAChI;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,IACzB;AAAA,GACF;AACF;AAkBO,SAAS,cACd,KAAA,EACA,mBAAA,GAAoC,EAAC,EACrC,cAAqC,8BAAA,EAIrC;AACA,EAAA,MAAM,SAAmB,EAAC;AAG1B,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,MAAA,GAAS,mBAAA,CAAoB,MAAA;AACtD,EAAA,IAAI,UAAA,GAAa,YAAY,QAAA,EAAU;AACrC,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,CAAA,mCAAA,EAAsC,WAAA,CAAY,QAAQ,CAAA,WAAA,EAAc,UAAU,CAAA,aAAA;AAAA,KACpF;AAAA,EACF;AAGA,EAAA,MAAM,YAAA,GAAe,oBAAoB,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ,GAAA,GAAM,GAAA,CAAI,IAAA,EAAM,CAAC,CAAA;AAC/E,EAAA,MAAM,YAAA,GAAe,MAAM,MAAA,CAAO,CAAC,KAAK,IAAA,KAAS,GAAA,GAAM,IAAA,CAAK,IAAA,EAAM,CAAC,CAAA;AACnE,EAAA,MAAM,YAAY,YAAA,GAAe,YAAA;AAEjC,EAAA,IAAI,SAAA,GAAY,YAAY,YAAA,EAAc;AACxC,IAAA,MAAM,SAAS,WAAA,CAAY,YAAA,GAAe,IAAA,GAAO,IAAA,EAAM,QAAQ,CAAC,CAAA;AAChE,IAAA,MAAM,OAAA,GAAA,CAAW,SAAA,GAAY,IAAA,GAAO,IAAA,EAAM,QAAQ,CAAC,CAAA;AACnD,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,CAAA,sCAAA,EAAyC,OAAO,CAAA,2BAAA,EAA8B,KAAK,CAAA,GAAA;AAAA,KACrF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,UAAA,GAAa,YAAA,CAAa,IAAA,EAAM,WAAW,CAAA;AACjD,IAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAA,CAAW,MAAM,CAAA;AAAA,EAClC;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,IACzB;AAAA,GACF;AACF;AAuBO,SAAS,mBAAA,CACd,IAAA,EACA,WAAA,GAAqC,8BAAA,EAC/B;AACN,EAAA,MAAM,MAAA,GAAS,YAAA,CAAa,IAAA,EAAM,WAAW,CAAA;AAC7C,EAAA,IAAI,CAAC,OAAO,KAAA,EAAO;AACjB,IAAA,MAAM,IAAI,yBAAA;AAAA,MACR,CAAA,wBAAA,EAA2B,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,MACnD,IAAA,CAAK,IAAA;AAAA,MACL,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAA,CAAO,MAAA;AAAO,KAChC;AAAA,EACF;AACF;AAsBO,SAAS,qBACd,KAAA,EACA,mBAAA,GAAoC,EAAC,EACrC,cAAqC,8BAAA,EAC/B;AACN,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,KAAA,EAAO,mBAAA,EAAqB,WAAW,CAAA;AACpE,EAAA,IAAI,CAAC,OAAO,KAAA,EAAO;AACjB,IAAA,MAAM,IAAI,yBAAA;AAAA,MACR,CAAA,wBAAA,EAA2B,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,MACnD,MAAA;AAAA,MACA,EAAE,KAAA,EAAO,MAAA,EAAQ,MAAA,CAAO,MAAA;AAAO,KACjC;AAAA,EACF;AACF;AAeO,SAAS,YAAY,QAAA,EAA2B;AACrD,EAAA,OAAO,QAAA,CAAS,WAAW,QAAQ,CAAA;AACrC;AAaO,SAAS,eAAe,KAAA,EAAuB;AACpD,EAAA,IAAI,KAAA,KAAU,GAAG,OAAO,SAAA;AAExB,EAAA,MAAM,CAAA,GAAI,IAAA;AACV,EAAA,MAAM,KAAA,GAAQ,CAAC,OAAA,EAAS,IAAA,EAAM,MAAM,IAAI,CAAA;AACxC,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAElD,EAAA,OAAO,IAAA,CAAK,KAAA,CAAO,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA,GAAK,GAAG,CAAA,GAAI,GAAA,GAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACzE;;;AClNO,IAAM,qBAAN,MAAyB;AAAA,EAI9B,WAAA,CAAY,UAAmB,IAAA,EAAM;AAHrC,IAAA,aAAA,CAAA,IAAA,EAAQ,SAAA,sBAAqC,GAAA,EAAI,CAAA;AACjD,IAAA,aAAA,CAAA,IAAA,EAAQ,SAAA,CAAA;AAGN,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,WAAW,KAAA,EAA2B;AACpC,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,OAAO,MAAM;AAAA,MAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,SAAA,GAAY,YAAY,GAAA,EAAI;AAElC,IAAA,OAAO,MAAM;AACX,MAAA,MAAM,QAAA,GAAW,WAAA,CAAY,GAAA,EAAI,GAAI,SAAA;AACrC,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,QAAQ,CAAA;AAAA,IAC9B,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,OAAA,CAAQ,OAAe,QAAA,EAAwB;AAC7C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,eAAe,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,EAAC;AACjD,IAAA,YAAA,CAAa,KAAK,QAAQ,CAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,YAAY,CAAA;AAEpC,IAAA,MAAA,CAAO,IAAA,CAAK,iBAAiB,KAAK,CAAA,EAAA,EAAK,SAAS,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAI,CAAA;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,UAAA,GAAiC;AAC/B,IAAA,MAAM,SAA6B,EAAC;AAEpC,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,YAAY,KAAK,IAAA,CAAK,OAAA,CAAQ,SAAQ,EAAG;AAC1D,MAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAE/B,MAAA,MAAM,KAAA,GAAQ,aAAa,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ,GAAA,GAAM,KAAK,CAAC,CAAA;AAC5D,MAAA,MAAM,GAAA,GAAM,QAAQ,YAAA,CAAa,MAAA;AACjC,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,YAAY,CAAA;AACpC,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,YAAY,CAAA;AACpC,MAAA,MAAM,IAAA,GAAO,YAAA,CAAa,YAAA,CAAa,MAAA,GAAS,CAAC,CAAA,IAAK,CAAA;AAEtD,MAAA,MAAA,CAAO,KAAK,CAAA,GAAI;AAAA,QACd,OAAO,YAAA,CAAa,MAAA;AAAA,QACpB,KAAA;AAAA,QACA,GAAA;AAAA,QACA,GAAA;AAAA,QACA,GAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAU,KAAA,EAAkD;AAC1D,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AAC3C,IAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AAC9C,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,KAAA,GAAQ,aAAa,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ,GAAA,GAAM,KAAK,CAAC,CAAA;AAC5D,IAAA,MAAM,GAAA,GAAM,QAAQ,YAAA,CAAa,MAAA;AACjC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,YAAY,CAAA;AACpC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,YAAY,CAAA;AACpC,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,YAAA,CAAa,MAAA,GAAS,CAAC,CAAA,IAAK,CAAA;AAEtD,IAAA,OAAO;AAAA,MACL,OAAO,YAAA,CAAa,MAAA;AAAA,MACpB,KAAA;AAAA,MACA,GAAA;AAAA,MACA,GAAA;AAAA,MACA,GAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBAAmB,KAAA,EAAyB;AAC1C,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,EAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,KAAA,EAAqB;AAC9B,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,OAAA,EAAwB;AACjC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAqB;AACnB,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAA,GAAyB;AACvB,IAAA,MAAM,OAAA,GAAU,KAAK,UAAA,EAAW;AAChC,IAAA,MAAM,QAAkB,EAAC;AAEzB,IAAA,KAAA,CAAM,KAAK,oBAAoB,CAAA;AAC/B,IAAA,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,EAAE,CAAC,CAAA;AACzB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAEb,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AACpD,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,KAAK,CAAA,CAAA,CAAG,CAAA;AACtB,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,SAAA,EAAY,KAAA,CAAM,KAAK,CAAA,CAAE,CAAA;AACpC,MAAA,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,KAAA,CAAM,IAAI,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAI,CAAA;AAC/C,MAAA,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,KAAA,CAAM,IAAI,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAI,CAAA;AAC/C,MAAA,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,KAAA,CAAM,IAAI,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAI,CAAA;AAC/C,MAAA,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,KAAA,CAAM,KAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAI,CAAA;AAChD,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACf;AAEA,IAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACxB;AACF;AAaO,SAAS,yBAAyB,OAAA,EAAuC;AAC9E,EAAA,MAAM,SAAA,GAAY,OAAA,IAAW,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA;AACtD,EAAA,OAAO,IAAI,mBAAmB,SAAS,CAAA;AACzC;AAMO,IAAM,2BAA2B,wBAAA;AAmBjC,SAAS,kBAAA,CACd,KAAA,EACA,OAAA,GAA8B,wBAAA,EAC9B;AACA,EAAA,OAAO,SACL,OAAA,EACA,YAAA,EACA,UAAA,EACA;AACA,IAAA,MAAM,iBAAiB,UAAA,CAAW,KAAA;AAElC,IAAA,UAAA,CAAW,KAAA,GAAQ,kBAAmB,IAAA,EAAa;AACjD,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,UAAA,CAAW,KAAK,CAAA;AACzC,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,KAAA,CAAM,MAAM,IAAI,CAAA;AACpD,QAAA,OAAO,MAAA;AAAA,MACT,CAAA,SAAE;AACA,QAAA,QAAA,EAAS;AAAA,MACX;AAAA,IACF,CAAA;AAEA,IAAA,OAAO,UAAA;AAAA,EACT,CAAA;AACF;AAkBO,SAAS,yBAAA,CACd,KAAA,EACA,EAAA,EACA,OAAA,GAA8B,wBAAA,EAC3B;AACH,EAAA,QAAQ,UAAU,IAAA,KAAgB;AAChC,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,UAAA,CAAW,KAAK,CAAA;AACzC,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACzB,CAAA,SAAE;AACA,MAAA,QAAA,EAAS;AAAA,IACX;AAAA,EACF,CAAA;AACF;ACrTA,SAAS,gBAAgB,IAAA,EAAoB;AAC3C,EAAA,MAAM,IAAA,GAAO,KAAK,WAAA,EAAY;AAC9B,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAA,CAAK,QAAA,KAAa,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA;AACzD,EAAA,MAAM,GAAA,GAAM,OAAO,IAAA,CAAK,OAAA,EAAS,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAClD,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,IAAI,GAAG,CAAA,CAAA;AAChC;AAeO,SAAS,qBAAqB,KAAA,EAAwD;AAC3F,EAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,KAAA,IAAS,EAAE,CAAA;AAGxC,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,IAAA,OAAW,EAAA,EAAI;AACjC,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,IAAA,EAAM,IAAA;AAAA,MACN,SAAA,EAAW,IAAA;AAAA,MACX,aAAA;AAAA,MACA,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AAEA,EAAA,MAAM,YAAA,GAAe,MAAM,IAAA,EAAK;AAChC,EAAA,MAAM,cAAA,GAAiB,YAAA,CAEpB,OAAA,CAAQ,sBAAA,EAAwB,IAAI,CAAA,CAEpC,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,MAAA,EAAQ,GAAG,EACnB,IAAA,EAAK;AAGR,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAUC,iBAAS,YAAY,CAAA;AACrC,IAAA,IAAIC,eAAA,CAAY,OAAO,CAAA,IAAK,CAAC,MAAM,OAAA,CAAQ,OAAA,EAAS,CAAA,EAAG;AACrD,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM,OAAA;AAAA,QACN,SAAA,EAAW,YAAA;AAAA,QACX;AAAA,OACF;AAAA,IACF;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAGA,EAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,KAAA,CAAM,2CAA2C,CAAA;AACvF,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,MAAM,GAAG,QAAA,EAAU,MAAA,EAAQ,OAAO,CAAA,GAAI,cAAA;AACtC,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,QAAA,IAAY,EAAA,EAAI,EAAE,CAAA;AACzC,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,MAAA,IAAU,EAAA,EAAI,EAAE,CAAA;AACrC,IAAA,MAAM,IAAA,GAAO,GAAA,GAAO,QAAA,CAAS,OAAA,IAAW,IAAI,EAAE,CAAA;AAC9C,IAAA,MAAM,YAAY,IAAI,IAAA,CAAK,IAAA,EAAM,KAAA,GAAQ,GAAG,GAAG,CAAA;AAC/C,IAAA,IAAIA,eAAA,CAAY,SAAS,CAAA,IAAK,CAAC,MAAM,SAAA,CAAU,OAAA,EAAS,CAAA,EAAG;AACzD,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM,SAAA;AAAA,QACN,SAAA,EAAW,gBAAgB,SAAS,CAAA;AAAA,QACpC;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,OAAA,GAAU;AAAA;AAAA,IAEd,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,wBAAA,EAAyB;AAAA,IACxD,EAAE,OAAA,EAAS,UAAA,EAAY,IAAA,EAAM,sBAAA,EAAuB;AAAA,IACpD,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,wBAAA,EAAyB;AAAA,IACxD,EAAE,OAAA,EAAS,UAAA,EAAY,IAAA,EAAM,sBAAA,EAAuB;AAAA,IACpD,EAAE,OAAA,EAAS,UAAA,EAAY,IAAA,EAAM,sBAAA,EAAuB;AAAA,IACpD,EAAE,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,oBAAA,EAAqB;AAAA,IAChD,EAAE,OAAA,EAAS,UAAA,EAAY,IAAA,EAAM,sBAAA,EAAuB;AAAA,IACpD,EAAE,OAAA,EAAS,QAAA,EAAU,IAAA,EAAM,oBAAA,EAAqB;AAAA;AAAA,IAGhD,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,wBAAA,EAAyB;AAAA,IACxD,EAAE,OAAA,EAAS,UAAA,EAAY,IAAA,EAAM,sBAAA,EAAuB;AAAA,IACpD,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,wBAAA,EAAyB;AAAA,IACxD,EAAE,OAAA,EAAS,UAAA,EAAY,IAAA,EAAM,sBAAA,EAAuB;AAAA;AAAA,IAGpD,EAAE,OAAA,EAAS,cAAA,EAAgB,IAAA,EAAM,qCAAA,EAAsC;AAAA,IACvE,EAAE,OAAA,EAAS,aAAA,EAAe,IAAA,EAAM,kCAAA,EAAmC;AAAA,IACnE,EAAE,OAAA,EAAS,aAAA,EAAe,IAAA,EAAM,kDAAA,EAAmD;AAAA,IACnF,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,wCAAA,EAAyC;AAAA,IACxE,EAAE,OAAA,EAAS,aAAA,EAAe,IAAA,EAAM,kCAAA,EAAmC;AAAA,IACnE,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,oCAAA,EAAqC;AAAA,IACpE,EAAE,OAAA,EAAS,aAAA,EAAe,IAAA,EAAM,yCAAA,EAA0C;AAAA;AAAA,IAG1E,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,8BAAA,EAA+B;AAAA,IAC9D,EAAE,OAAA,EAAS,YAAA,EAAc,IAAA,EAAM,wBAAA;AAAyB,GAC1D;AAEA,EAAA,MAAM,aAAA,uBAAoB,IAAA,EAAK;AAE/B,EAAA,KAAA,MAAW,EAAE,OAAA,EAAQ,IAAK,OAAA,EAAS;AACjC,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAaC,aAAA,CAAM,cAAA,EAAgB,OAAA,EAAS,aAAa,CAAA;AAC/D,MAAA,IAAID,eAAA,CAAY,UAAU,CAAA,IAAK,CAAC,MAAM,UAAA,CAAW,OAAA,EAAS,CAAA,EAAG;AAE3D,QAAA,MAAM,SAAA,GAAY,gBAAgB,UAAU,CAAA;AAE5C,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,IAAA,EAAM,UAAA;AAAA,UACN,SAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAGA,EAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,YAAY,CAAA,EAAG;AAC9B,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,QAAA,CAAS,YAAA,EAAc,EAAE,CAAA;AAC3C,MAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,SAAS,CAAA;AAC/B,MAAA,IAAIA,eAAA,CAAY,IAAI,CAAA,IAAK,CAAC,MAAM,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AAC/C,QAAA,MAAM,SAAA,GAAY,gBAAgB,IAAI,CAAA;AAEtC,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,IAAA;AAAA,UACA,SAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAGA,EAAA,MAAM,YAAA,GAAe,IAAI,IAAA,CAAK,cAAc,CAAA;AAC5C,EAAA,IAAIA,eAAA,CAAY,YAAY,CAAA,IAAK,CAAC,MAAM,YAAA,CAAa,OAAA,EAAS,CAAA,EAAG;AAC/D,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,IAAA,EAAM,YAAA;AAAA,MACN,SAAA,EAAW,gBAAgB,YAAY,CAAA;AAAA,MACvC;AAAA,KACF;AAAA,EACF;AAGA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT,IAAA,EAAM,IAAA;AAAA,IACN,SAAA,EAAW,IAAA;AAAA,IACX,aAAA;AAAA,IACA,KAAA,EAAO,yBAAyB,YAAY,CAAA,sDAAA;AAAA,GAC9C;AACF;AAKO,SAAS,eAAe,KAAA,EAA2C;AACxE,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAa,qBAAA;AACnB,EAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,KAAK,CAAA,EAAG;AAC3B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAOD,iBAAS,KAAK,CAAA;AAC3B,IAAA,OAAOC,gBAAY,IAAI,CAAA,IAAK,CAAC,KAAA,CAAM,IAAA,CAAK,SAAS,CAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;ACjJA,IAAM,oBAAA,GAAuB,6BAAA;AAE7B,IAAM,UAAA,GAAa,SAAA;AAUnB,eAAsB,iBAAA,CACpB,QACA,IAAA,EAC2B;AAC3B,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,oBAAA;AACpC,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,QAAQ,CAAA,EAAG,UAAU,CAAA,iBAAA,CAAA;AAEpC,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,aAAa,MAAA,CAAO;AAAA,OACtB;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,gBAAgB,IAAA,CAAK,cAAA;AAAA,QACrB,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,gBAAgB,IAAA,CAAK,cAAA;AAAA,QACrB,UAAU,IAAA,CAAK;AAAA,OAChB;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,EAAK;AACtC,MAAA,MAAA,CAAO,MAAM,CAAA,mBAAA,EAAsB,QAAA,CAAS,MAAM,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AACnE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AACnC,IAAA,MAAA,CAAO,MAAM,oCAAA,EAAsC,EAAE,OAAA,EAAS,MAAA,CAAO,SAAS,CAAA;AAC9E,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,kCAAkC,KAAK,CAAA;AACpD,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAUA,eAAsB,mBAAA,CACpB,QACA,IAAA,EAC2B;AAC3B,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,oBAAA;AACpC,EAAA,MAAM,GAAA,GAAM,CAAA,EAAG,QAAQ,CAAA,EAAG,UAAU,CAAA,oBAAA,CAAA;AAEpC,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,aAAa,MAAA,CAAO;AAAA,OACtB;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,aAAa,IAAA,CAAK,WAAA;AAAA,QAClB,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,gBAAgB,IAAA,CAAK,cAAA;AAAA,QACrB,UAAU,IAAA,CAAK;AAAA,OAChB;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,EAAK;AACtC,MAAA,MAAA,CAAO,MAAM,CAAA,sBAAA,EAAyB,QAAA,CAAS,MAAM,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AACtE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AACnC,IAAA,MAAA,CAAO,MAAM,uCAAA,EAAyC,EAAE,OAAA,EAAS,MAAA,CAAO,SAAS,CAAA;AACjF,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,KAAA,CAAM,qCAAqC,KAAK,CAAA;AACvD,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAUA,eAAsB,yBAAA,CACpB,QACA,IAAA,EACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,mBAAA,CAAoB,QAAQ,IAAI,CAAA;AAAA,EACxC,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,IAAA,CAAK,0CAA0C,KAAK,CAAA;AAAA,EAC7D;AACF;AAUA,eAAsB,uBAAA,CACpB,QACA,IAAA,EACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,iBAAA,CAAkB,QAAQ,IAAI,CAAA;AAAA,EACtC,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,IAAA,CAAK,0CAA0C,KAAK,CAAA;AAAA,EAC7D;AACF","file":"index.js","sourcesContent":["/**\r\n * Logger Utility\r\n * Centralized logging system with environment-based log level control\r\n */\r\n\r\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\r\n\r\ninterface Logger {\r\n debug(message: string, ...args: unknown[]): void;\r\n info(message: string, ...args: unknown[]): void;\r\n warn(message: string, ...args: unknown[]): void;\r\n error(message: string, ...args: unknown[]): void;\r\n}\r\n\r\n/**\r\n * Determines if the current environment is production\r\n */\r\nfunction isProduction(): boolean {\r\n return typeof process !== 'undefined' && process.env.NODE_ENV === 'production';\r\n}\r\n\r\n/**\r\n * Creates a formatted log prefix\r\n */\r\nfunction createPrefix(level: LogLevel): string {\r\n return `[@signiphi/pdf-signer] [${level.toUpperCase()}]`;\r\n}\r\n\r\n/**\r\n * Creates the logger instance with environment-based behavior\r\n */\r\nfunction createLogger(): Logger {\r\n const isProd = isProduction();\r\n\r\n return {\r\n debug(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.log(createPrefix('debug'), message, ...args);\r\n }\r\n },\r\n\r\n info(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.log(createPrefix('info'), message, ...args);\r\n }\r\n },\r\n\r\n warn(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.warn(createPrefix('warn'), message, ...args);\r\n }\r\n },\r\n\r\n error(message: string, ...args: unknown[]): void {\r\n // Errors are shown in both development and production\r\n console.error(createPrefix('error'), message, ...args);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Singleton logger instance\r\n */\r\nexport const logger = createLogger();\r\n\r\n\r\n\r\n","/**\r\n * PDF Validation Utilities\r\n * Common validation functions used across the package\r\n */\r\n\r\nimport type { FormField } from '../types';\r\n\r\n/**\r\n * Validate that bytes represent a valid PDF file\r\n * \r\n * Checks for:\r\n * - Non-empty bytes\r\n * - Valid PDF header (%PDF-)\r\n * \r\n * @param pdfBytes - The PDF bytes to validate\r\n * @returns Validation result with valid flag and optional error message\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validatePdfBytes(pdfBytes);\r\n * if (!result.valid) {\r\n * console.error(result.error);\r\n * return;\r\n * }\r\n * ```\r\n */\r\nexport function validatePdfBytes(pdfBytes: Uint8Array): { \r\n valid: boolean; \r\n error?: string \r\n} {\r\n // Check for empty bytes\r\n if (!pdfBytes || pdfBytes.length === 0) {\r\n return { \r\n valid: false, \r\n error: 'PDF bytes are empty' \r\n };\r\n }\r\n \r\n // Check for valid PDF header\r\n const header = new TextDecoder().decode(pdfBytes.slice(0, 12));\r\n if (!header.startsWith('%PDF-')) {\r\n return { \r\n valid: false, \r\n error: 'Invalid PDF format: Missing PDF header' \r\n };\r\n }\r\n \r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Check if a label is auto-generated (not user-typed)\r\n * \r\n * Auto-generated labels are simple type names like \"Text\", \"Signature\", etc.\r\n * These are default labels assigned by the form builder and should not be\r\n * displayed to users in the same way as custom labels.\r\n * \r\n * Works identically in both single-signer and multi-signer flows.\r\n * \r\n * @param label - The label to check\r\n * @returns true if the label is auto-generated, false if it's a custom user label\r\n * \r\n * @example\r\n * ```ts\r\n * isAutoGeneratedLabel('Signature') // true\r\n * isAutoGeneratedLabel('Sign here please') // false\r\n * isAutoGeneratedLabel('') // true\r\n * ```\r\n */\r\nexport function isAutoGeneratedLabel(label: string): boolean {\r\n if (!label || !label.trim()) return true;\r\n \r\n const autoLabels = [\r\n 'Signature',\r\n 'Initials',\r\n 'Date',\r\n 'Text',\r\n 'Checkbox',\r\n 'Dropdown',\r\n 'Option',\r\n 'Radio',\r\n ];\r\n \r\n return autoLabels.includes(label.trim());\r\n}\r\n\r\n/**\r\n * Validate field values object\r\n * \r\n * Checks that the values object is properly formatted and contains\r\n * only string values for field IDs.\r\n * \r\n * @param values - Field values to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFieldValues({ field1: 'value1', field2: 'value2' });\r\n * if (!result.valid) {\r\n * console.error('Validation errors:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFieldValues(values: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if values is an object\r\n if (!values || typeof values !== 'object') {\r\n errors.push('Field values must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n // Check each value is a string\r\n const valuesObj = values as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(valuesObj)) {\r\n if (typeof value !== 'string') {\r\n errors.push(`Field value for \"${key}\" must be a string, got ${typeof value}`);\r\n }\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate signatures object\r\n * \r\n * Checks that signatures are properly formatted data URLs.\r\n * \r\n * @param signatures - Signatures to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateSignatures({\r\n * sig1: 'data:image/png;base64,iVBORw0KG...',\r\n * sig2: 'data:image/png;base64,iVBORw0KG...'\r\n * });\r\n * if (!result.valid) {\r\n * console.error('Invalid signatures:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateSignatures(signatures: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if signatures is an object\r\n if (!signatures || typeof signatures !== 'object') {\r\n errors.push('Signatures must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n // Check each signature is a valid data URL\r\n const sigsObj = signatures as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(sigsObj)) {\r\n if (typeof value !== 'string') {\r\n errors.push(`Signature for \"${key}\" must be a string, got ${typeof value}`);\r\n continue;\r\n }\r\n \r\n // Validate data URL format\r\n if (!value.startsWith('data:image/')) {\r\n errors.push(`Signature for \"${key}\" must be a data URL starting with \"data:image/\"`);\r\n }\r\n \r\n // Check for base64 data\r\n const parts = value.split(',');\r\n if (parts.length !== 2 || !parts[1]) {\r\n errors.push(`Signature for \"${key}\" has invalid data URL format (missing base64 data)`);\r\n }\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate a form field definition\r\n * \r\n * Checks that a field has all required properties and they are valid.\r\n * \r\n * @param field - Form field to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFormField({\r\n * id: 'field1',\r\n * name: 'firstName',\r\n * type: FormFieldType.TEXT,\r\n * label: 'First Name',\r\n * position: { x: 100, y: 200, width: 150, height: 30, page: 1 },\r\n * required: true\r\n * });\r\n * if (!result.valid) {\r\n * console.error('Field validation errors:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFormField(field: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if field is an object\r\n if (!field || typeof field !== 'object') {\r\n errors.push('Form field must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n const f = field as Partial<FormField>;\r\n \r\n // Required properties\r\n if (!f.id || typeof f.id !== 'string') {\r\n errors.push('Field must have a valid \"id\" string');\r\n }\r\n \r\n if (!f.type || typeof f.type !== 'string') {\r\n errors.push('Field must have a valid \"type\" string');\r\n }\r\n \r\n if (!f.name || typeof f.name !== 'string') {\r\n errors.push('Field must have a valid \"name\" string');\r\n }\r\n \r\n if (!f.label || typeof f.label !== 'string') {\r\n errors.push('Field must have a valid \"label\" string');\r\n }\r\n \r\n // Validate position\r\n if (!f.position || typeof f.position !== 'object') {\r\n errors.push('Field must have a valid \"position\" object');\r\n } else {\r\n const pos = f.position;\r\n if (typeof pos.x !== 'number') {\r\n errors.push('Field position must have a numeric \"x\" coordinate');\r\n }\r\n if (typeof pos.y !== 'number') {\r\n errors.push('Field position must have a numeric \"y\" coordinate');\r\n }\r\n if (typeof pos.width !== 'number' || pos.width <= 0) {\r\n errors.push('Field position must have a positive \"width\"');\r\n }\r\n if (typeof pos.height !== 'number' || pos.height <= 0) {\r\n errors.push('Field position must have a positive \"height\"');\r\n }\r\n if (typeof pos.page !== 'number' || pos.page < 1) {\r\n errors.push('Field position must have a valid \"page\" number (1-indexed)');\r\n }\r\n }\r\n \r\n if (typeof f.required !== 'boolean') {\r\n errors.push('Field must have a boolean \"required\" property');\r\n }\r\n \r\n // Optional properties validation\r\n if (f.fontSize !== undefined && (typeof f.fontSize !== 'number' || f.fontSize < 8 || f.fontSize > 72)) {\r\n errors.push('Field fontSize must be a number between 8 and 72');\r\n }\r\n \r\n if (f.maxLength !== undefined && (typeof f.maxLength !== 'number' || f.maxLength <= 0)) {\r\n errors.push('Field maxLength must be a positive number');\r\n }\r\n \r\n if (f.options !== undefined && !Array.isArray(f.options)) {\r\n errors.push('Field options must be an array');\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate PDF URL format\r\n * \r\n * Accepts absolute URLs, relative paths, and data URLs.\r\n * \r\n * @param url - URL to validate\r\n * @returns Validation result with valid flag and optional error message\r\n * \r\n * @example\r\n * ```ts\r\n * // Absolute URLs\r\n * validatePdfUrl('https://example.com/document.pdf'); // valid\r\n * validatePdfUrl('http://localhost:3000/doc.pdf'); // valid\r\n * \r\n * // Relative paths\r\n * validatePdfUrl('/public/document.pdf'); // valid\r\n * validatePdfUrl('./document.pdf'); // valid\r\n * \r\n * // Data URLs and blobs\r\n * validatePdfUrl('data:application/pdf;base64,...'); // valid\r\n * validatePdfUrl('blob:http://localhost/...'); // valid\r\n * \r\n * // Local files\r\n * validatePdfUrl('file:///C:/path/to/file.pdf'); // valid\r\n * ```\r\n */\r\nexport function validatePdfUrl(url: unknown): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n if (typeof url !== 'string') {\r\n return { valid: false, error: 'URL must be a string' };\r\n }\r\n \r\n if (!url || url.trim().length === 0) {\r\n return { valid: false, error: 'URL cannot be empty' };\r\n }\r\n \r\n const trimmedUrl = url.trim();\r\n \r\n // Check for absolute URLs with protocols\r\n const validPrefixes = ['http://', 'https://', 'blob:', 'data:', 'file://'];\r\n const hasValidPrefix = validPrefixes.some(prefix => trimmedUrl.startsWith(prefix));\r\n \r\n if (hasValidPrefix) {\r\n return { valid: true };\r\n }\r\n \r\n // Allow relative paths (start with / or ./ or ../)\r\n if (trimmedUrl.startsWith('/') || trimmedUrl.startsWith('./') || trimmedUrl.startsWith('../')) {\r\n return { valid: true };\r\n }\r\n \r\n // Reject URLs that look malformed\r\n return {\r\n valid: false,\r\n error: 'URL must be an absolute URL (http://, https://, blob:, data:, file://) or a relative path (/, ./, ../)',\r\n };\r\n}\r\n\r\n","/**\r\n * PDF utility helper functions\r\n */\r\n\r\nimport { logger } from \"./logger\";\r\nimport { validatePdfBytes } from \"./pdf-validators\";\r\n\r\n/**\r\n * Create a blob URL from PDF bytes for preview\r\n */\r\nexport function createPdfBlobUrl(pdfBytes: Uint8Array): string {\r\n const blob = new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\n/**\r\n * Download PDF file\r\n */\r\nexport function downloadPdf(pdfBytes: Uint8Array, filename: string): void {\r\n const url = createPdfBlobUrl(pdfBytes);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = filename;\r\n a.click();\r\n URL.revokeObjectURL(url);\r\n}\r\n\r\n/**\r\n * Convert URL to PDF bytes\r\n * @param url - The URL to fetch the PDF from\r\n * @returns PDF bytes as Uint8Array\r\n */\r\nexport async function urlToPdfBytes(url: string): Promise<Uint8Array> {\r\n try {\r\n const response = await fetch(url);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch PDF: ${response.status} ${response.statusText}`);\r\n }\r\n\r\n const arrayBuffer = await response.arrayBuffer();\r\n\r\n // Create a new Uint8Array and copy the data to avoid detached ArrayBuffer issues\r\n const pdfBytes = new Uint8Array(arrayBuffer.byteLength);\r\n pdfBytes.set(new Uint8Array(arrayBuffer));\r\n\r\n // Validate that we have a PDF\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n throw new Error(validation.error || 'Invalid PDF format');\r\n }\r\n\r\n return pdfBytes;\r\n } catch (error) {\r\n logger.error('Error fetching PDF from URL:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Validate that data is a valid PDF\r\n */\r\nexport function isValidPdf(pdfBytes: Uint8Array): boolean {\r\n const validation = validatePdfBytes(pdfBytes);\r\n return validation.valid;\r\n}\r\n\r\n/**\r\n * Convert base64 data URL to image bytes\r\n */\r\nexport function dataUrlToBytes(dataUrl: string): Uint8Array {\r\n const base64Data = dataUrl.split(',')[1];\r\n if (!base64Data) {\r\n throw new Error('Invalid data URL format: missing base64 data');\r\n }\r\n return Uint8Array.from(atob(base64Data), (c) => c.charCodeAt(0));\r\n}\r\n\r\n/**\r\n * Format field name for display\r\n */\r\nexport function formatFieldName(fieldName: string): string {\r\n return fieldName\r\n .replace(/[_-]/g, ' ')\r\n .replace(/\\b\\w/g, (l) => l.toUpperCase())\r\n .replace('Signature', '')\r\n .replace('Initials', '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Check if a field is a signature field\r\n */\r\nexport function isSignatureField(fieldName: string): boolean {\r\n return fieldName.toLowerCase().includes('signature');\r\n}\r\n\r\n/**\r\n * Check if a field is an initials field\r\n */\r\nexport function isInitialsField(fieldName: string): boolean {\r\n return fieldName.toLowerCase().includes('initials');\r\n}\r\n\r\n","/**\r\n * PDF Metadata Utilities\r\n * Functions for storing and retrieving Signiphi metadata in PDF documents\r\n */\r\n\r\nimport type { PDFDocument, PDFName as PDFNameType, PDFString as PDFStringType } from 'pdf-lib';\r\nimport { Acknowledgement } from '../types';\r\n\r\n// Module-level variables for pdf-lib classes (loaded dynamically)\r\nlet PDFName: typeof PDFNameType;\r\nlet PDFString: typeof PDFStringType;\r\n\r\n/**\r\n * Initialize PDF classes from dynamically loaded pdf-lib module\r\n * Must be called before using getSigniphiMetadata or setSigniphiMetadata\r\n */\r\nexport function initPdfMetadata(pdfLibModule: any): void {\r\n PDFName = pdfLibModule.PDFName;\r\n PDFString = pdfLibModule.PDFString;\r\n}\r\n\r\n/**\r\n * Metadata for a single form field\r\n */\r\nexport interface FieldMetadata {\r\n fieldId?: string; // Immutable UUID for reliable field identification\r\n label?: string;\r\n signer?: string;\r\n placeholder?: string;\r\n acknowledgements?: Acknowledgement[];\r\n}\r\n\r\n/**\r\n * Complete metadata structure stored in PDF\r\n */\r\nexport interface SigniphiMetadata {\r\n version: string;\r\n fields: Record<string, FieldMetadata>; // Key is the clean field name\r\n}\r\n\r\n/**\r\n * Stores Signiphi metadata in the PDF's document information dictionary\r\n * @param pdfDoc - The PDF document to store metadata in\r\n * @param metadata - The metadata object to store\r\n */\r\nexport function setSigniphiMetadata(pdfDoc: PDFDocument, metadata: SigniphiMetadata): void {\r\n try {\r\n if (!PDFName || !PDFString) {\r\n console.error('PDF metadata classes not initialized. Call initPdfMetadata first.');\r\n return;\r\n }\r\n \r\n const infoRef = pdfDoc.context.trailerInfo.Info;\r\n const infoObj = pdfDoc.context.lookup(infoRef);\r\n if (!infoObj || typeof (infoObj as any).set !== 'function') {\r\n throw new Error('Info object is not a PDFDict or does not have set method');\r\n }\r\n const infoDict = infoObj as any;\r\n const metadataString = JSON.stringify(metadata);\r\n \r\n // Set the metadata\r\n infoDict.set(PDFName.of('SigniphiMetadata'), PDFString.of(metadataString));\r\n } catch (error) {\r\n console.error('Failed to set Signiphi metadata:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Retrieves Signiphi metadata from the PDF's document information dictionary\r\n * @param pdfDoc - The PDF document to read metadata from\r\n * @returns The metadata object if found, null otherwise\r\n */\r\nexport function getSigniphiMetadata(pdfDoc: PDFDocument): SigniphiMetadata | null {\r\n try {\r\n if (!PDFName || !PDFString) {\r\n console.error('PDF metadata classes not initialized. Call initPdfMetadata first.');\r\n return null;\r\n }\r\n \r\n const infoRef = pdfDoc.context.trailerInfo.Info;\r\n const infoObj = pdfDoc.context.lookup(infoRef);\r\n \r\n if (!infoObj || typeof (infoObj as any).get !== 'function' || !(infoObj as any).dict) {\r\n return null;\r\n }\r\n \r\n const infoDict = infoObj as any;\r\n const metadataObj = infoDict.get(PDFName.of('SigniphiMetadata'));\r\n \r\n if (!metadataObj) {\r\n return null;\r\n }\r\n \r\n // PDFString objects are encoded as \"(content)\" in their toString() representation\r\n const metadataStr = metadataObj.toString();\r\n \r\n // Extract content from PDF string format: (content) or <hex>\r\n let jsonStr = metadataStr;\r\n const parenMatch = metadataStr.match(/^\\((.*)\\)$/);\r\n if (parenMatch && parenMatch[1]) {\r\n jsonStr = parenMatch[1];\r\n } else {\r\n const hexMatch = metadataStr.match(/^<(.*)>$/);\r\n if (hexMatch && hexMatch[1]) {\r\n // Convert hex to string if needed\r\n jsonStr = hexMatch[1];\r\n }\r\n }\r\n \r\n const metadata = JSON.parse(jsonStr);\r\n return metadata;\r\n } catch (error) {\r\n console.error('Failed to load Signiphi metadata:', error);\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Lazy loader for pdf-lib\r\n * \r\n * This module provides a lazy loading mechanism for the pdf-lib library (~150KB).\r\n * By deferring the import until actually needed, we can significantly reduce\r\n * the initial bundle size for consumers who only view PDFs without filling forms.\r\n * \r\n * The pdf-lib library is only loaded when:\r\n * - fillPdf() is called\r\n * - combinePdfs() is called\r\n * - Other PDF manipulation functions are used\r\n */\r\n\r\n// Cache the promise to ensure we only import once\r\nlet pdfLibPromise: Promise<typeof import('pdf-lib')> | null = null;\r\n\r\n/**\r\n * Dynamically import pdf-lib library\r\n * \r\n * This function lazily loads pdf-lib only when needed. The import is cached\r\n * so subsequent calls return the same promise, avoiding multiple imports.\r\n * \r\n * @returns Promise resolving to the pdf-lib module\r\n * \r\n * @example\r\n * ```typescript\r\n * const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n * const pdfDoc = await PDFDocument.load(pdfBytes);\r\n * ```\r\n */\r\nexport async function loadPdfLib() {\r\n if (!pdfLibPromise) {\r\n pdfLibPromise = import('pdf-lib');\r\n }\r\n return pdfLibPromise;\r\n}\r\n\r\n/**\r\n * Check if pdf-lib has been loaded\r\n * \r\n * Useful for debugging and testing to verify lazy loading behavior.\r\n * \r\n * @returns true if pdf-lib has been loaded, false otherwise\r\n */\r\nexport function isPdfLibLoaded(): boolean {\r\n return pdfLibPromise !== null;\r\n}\r\n\r\n/**\r\n * Reset the pdf-lib cache (primarily for testing)\r\n * \r\n * This should only be used in test environments to reset state\r\n * between tests.\r\n * \r\n * @internal\r\n */\r\nexport function resetPdfLibCache(): void {\r\n pdfLibPromise = null;\r\n}\r\n\r\n","/**\r\n * Field Visibility Utilities\r\n * Core logic for determining which fields are visible/editable in multi-signer mode\r\n * \r\n * CRITICAL: This logic must work identically in both flows:\r\n * - Single-signer flow: isMultiSigner = false, all fields visible\r\n * - Multi-signer flow: isMultiSigner = true, filtered by assignment rules\r\n */\r\n\r\nimport type { EsignFormField, MultiSignerContext } from '../types';\r\n\r\n/**\r\n * Determine if a field should be visible to the current signer\r\n * \r\n * Implements the 5-rule visibility logic used throughout the application:\r\n * - Rule 1: Unassigned fields → only final signer sees them\r\n * - Rule 2: Direct assignment → show if assigned to current signer\r\n * - Rule 3: Recipients group → only primary signers (signOrder === 1)\r\n * - Rule 4: Signers group → only final signer\r\n * - Rule 5: Assigned to different signer → hide\r\n * \r\n * @param field - The form field to check\r\n * @param multiSignerContext - Multi-signer context with current signer info\r\n * @returns true if field should be visible, false if hidden\r\n * \r\n * @example Single-signer flow\r\n * ```ts\r\n * const context = { isMultiSigner: false, ... };\r\n * isFieldVisibleToSigner(anyField, context); // always returns true\r\n * ```\r\n * \r\n * @example Multi-signer flow\r\n * ```ts\r\n * const context = {\r\n * isMultiSigner: true,\r\n * currentSignerEmail: 'signer1@example.com',\r\n * isPrimarySigner: true,\r\n * isFinalSigner: false\r\n * };\r\n * \r\n * // Unassigned field - only final signer sees it\r\n * isFieldVisibleToSigner({ assignedSignerEmail: undefined, ... }, context); // false\r\n * \r\n * // Direct assignment to current signer\r\n * isFieldVisibleToSigner({ assignedSignerEmail: 'signer1@example.com', ... }, context); // true\r\n * \r\n * // Recipients group - primary signer sees it\r\n * isFieldVisibleToSigner({ assignedSignerEmail: 'recipients', ... }, context); // true\r\n * ```\r\n */\r\nexport function isFieldVisibleToSigner(\r\n field: EsignFormField,\r\n multiSignerContext: MultiSignerContext\r\n): boolean {\r\n // Single-signer mode: all fields are visible\r\n if (!multiSignerContext.isMultiSigner) {\r\n return true;\r\n }\r\n\r\n const { currentSignerEmail, isPrimarySigner, isFinalSigner } = multiSignerContext;\r\n\r\n // RULE 1: Unassigned fields - only final signer sees them\r\n if (!field.assignedSignerEmail) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 2: Direct assignment - show if assigned to current signer\r\n if (field.assignedSignerEmail === currentSignerEmail) {\r\n return true;\r\n }\r\n\r\n // RULE 3: Recipients group - only primary signers (signOrder === 1)\r\n if (field.assignedSignerEmail.includes('recipients')) {\r\n return isPrimarySigner;\r\n }\r\n\r\n // RULE 4: Signers group - only final signer\r\n if (field.assignedSignerEmail.includes('signers')) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 5: Assigned to different signer - hide\r\n return false;\r\n}\r\n\r\n/**\r\n * Filter an array of fields to only those visible to the current signer\r\n * \r\n * @param fields - All form fields\r\n * @param multiSignerContext - Multi-signer context\r\n * @returns Filtered array of visible fields\r\n * \r\n * @example\r\n * ```ts\r\n * const allFields = [...]; // 10 fields\r\n * const context = { isMultiSigner: true, isPrimarySigner: true, ... };\r\n * const visible = filterFieldsBySigner(allFields, context); // 5 fields (only primary signer's)\r\n * ```\r\n */\r\nexport function filterFieldsBySigner(\r\n fields: EsignFormField[],\r\n multiSignerContext: MultiSignerContext\r\n): EsignFormField[] {\r\n // Single-signer mode: return all fields\r\n if (!multiSignerContext.isMultiSigner) {\r\n return fields;\r\n }\r\n\r\n // Multi-signer mode: filter using visibility logic\r\n return fields.filter(field => isFieldVisibleToSigner(field, multiSignerContext));\r\n}\r\n\r\n/**\r\n * Determine if a field should be flattened (made non-editable) by the current signer\r\n * \r\n * Used during PDF submission to determine which fields to flatten.\r\n * In multi-signer mode, only flatten fields assigned to current signer.\r\n * In single-signer mode, flatten all fields.\r\n * \r\n * CRITICAL: This affects PDF flattening behavior - must preserve exact logic!\r\n * \r\n * @param field - The form field to check\r\n * @param multiSignerContext - Multi-signer context\r\n * @returns true if current signer should flatten this field\r\n * \r\n * @example Single-signer flow\r\n * ```ts\r\n * const context = { isMultiSigner: false, ... };\r\n * shouldFlattenField(anyField, context); // always returns true\r\n * ```\r\n * \r\n * @example Multi-signer flow\r\n * ```ts\r\n * const context = {\r\n * isMultiSigner: true,\r\n * currentSignerEmail: 'signer1@example.com',\r\n * isPrimarySigner: true,\r\n * isFinalSigner: false\r\n * };\r\n * \r\n * // Current signer's field - flatten it\r\n * shouldFlattenField({ assignedSignerEmail: 'signer1@example.com', ... }, context); // true\r\n * \r\n * // Different signer's field - don't flatten (keep editable for them)\r\n * shouldFlattenField({ assignedSignerEmail: 'signer2@example.com', ... }, context); // false\r\n * \r\n * // Unassigned field - only final signer flattens\r\n * shouldFlattenField({ assignedSignerEmail: undefined, ... }, context); // false (not final)\r\n * ```\r\n */\r\nexport function shouldFlattenField(\r\n field: EsignFormField,\r\n multiSignerContext: MultiSignerContext\r\n): boolean {\r\n // Single-signer mode: flatten all fields\r\n if (!multiSignerContext.isMultiSigner) {\r\n return true;\r\n }\r\n\r\n const { currentSignerEmail, isPrimarySigner, isFinalSigner } = multiSignerContext;\r\n\r\n // RULE 1: Unassigned fields - only final signer flattens them\r\n if (!field.assignedSignerEmail) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 2: Direct assignment - flatten if assigned to current signer\r\n if (field.assignedSignerEmail === currentSignerEmail) {\r\n return true;\r\n }\r\n\r\n // RULE 3: Recipients group - only primaries flatten them\r\n if (field.assignedSignerEmail.includes('recipients')) {\r\n return isPrimarySigner;\r\n }\r\n\r\n // RULE 4: Signers group - only final signer flattens them\r\n if (field.assignedSignerEmail.includes('signers')) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 5: Assigned to different signer - DON'T flatten (keep editable for them)\r\n return false;\r\n}\r\n\r\n","/**\r\n * PDF Widget Helper Utilities\r\n * Common utilities for working with PDF widgets and pages\r\n * \r\n * Used across pdf-manipulation.ts and pdf-viewer-filter.ts\r\n */\r\n\r\nimport type { PDFPage } from 'pdf-lib';\r\n\r\n/**\r\n * Extended type for PDF pages with ref property\r\n */\r\ninterface PDFPageWithRef {\r\n ref: unknown;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Find the page index for a given page reference\r\n * \r\n * This is a common pattern used when working with PDF widgets to determine\r\n * which page a widget belongs to by comparing page references.\r\n * \r\n * @param pages - Array of PDF pages\r\n * @param pageRef - The page reference to search for\r\n * @returns Page index (0-based), or -1 if not found\r\n * \r\n * @example\r\n * ```ts\r\n * const widget = widgets[0];\r\n * const pageRef = widget.P?.();\r\n * const pageIndex = findPageIndexByRef(pages, pageRef);\r\n * if (pageIndex >= 0) {\r\n * const page = pages[pageIndex];\r\n * // Draw on the page\r\n * }\r\n * ```\r\n */\r\nexport function findPageIndexByRef(\r\n pages: PDFPage[],\r\n pageRef: unknown\r\n): number {\r\n if (!pageRef) return -1;\r\n \r\n for (let i = 0; i < pages.length; i++) {\r\n const page = pages[i] as unknown as PDFPageWithRef;\r\n if (page.ref === pageRef) {\r\n return i;\r\n }\r\n }\r\n \r\n return -1;\r\n}\r\n\r\n/**\r\n * Extended type for PDF widgets with rectangle and page methods\r\n */\r\nexport interface PDFWidgetWithExtensions {\r\n getRectangle?: () => { x: number; y: number; width: number; height: number } | undefined;\r\n P?: () => unknown;\r\n}\r\n\r\n/**\r\n * Get widget rectangle and its page\r\n * \r\n * Helper to extract both the rectangle coordinates and the page that a widget\r\n * belongs to in a single operation.\r\n * \r\n * @param widget - The PDF widget\r\n * @param pages - Array of PDF pages\r\n * @returns Object with rect, page, and pageIndex, or null if unable to determine\r\n * \r\n * @example\r\n * ```ts\r\n * for (const widget of widgets) {\r\n * const result = getWidgetRectangleAndPage(widget, pages);\r\n * if (result) {\r\n * const { rect, page, pageIndex } = result;\r\n * // Draw something at rect coordinates on page\r\n * page.drawRectangle({ x: rect.x, y: rect.y, ... });\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function getWidgetRectangleAndPage(\r\n widget: PDFWidgetWithExtensions,\r\n pages: PDFPage[]\r\n): {\r\n rect: { x: number; y: number; width: number; height: number };\r\n page: PDFPage;\r\n pageIndex: number;\r\n} | null {\r\n const rect = widget.getRectangle?.();\r\n if (!rect) return null;\r\n \r\n const pageRef = widget.P?.();\r\n if (!pageRef) return null;\r\n \r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n if (pageIndex === -1) return null;\r\n \r\n const page = pages[pageIndex];\r\n if (!page) return null;\r\n \r\n return { rect, page, pageIndex };\r\n}\r\n\r\n/**\r\n * Find page index with fallback to single-page PDFs\r\n * \r\n * Same as findPageIndexByRef but with a fallback: if pageRef lookup fails\r\n * and there's only one page in the document, returns index 0.\r\n * \r\n * This is useful for label drawing where single-page PDFs might not have\r\n * proper page references but we can safely assume page 0.\r\n * \r\n * @param pages - Array of PDF pages\r\n * @param pageRef - The page reference to search for\r\n * @returns Page index (0-based), 0 if single-page PDF, or -1 if not found\r\n * \r\n * @example\r\n * ```ts\r\n * // Used in pdf-viewer-filter for label drawing\r\n * const pageIndex = findPageIndexWithFallback(pages, pageRef);\r\n * if (pageIndex >= 0) {\r\n * const page = pages[pageIndex];\r\n * page.drawText(label, ...);\r\n * }\r\n * ```\r\n */\r\nexport function findPageIndexWithFallback(\r\n pages: PDFPage[],\r\n pageRef: unknown\r\n): number {\r\n if (!pageRef) {\r\n // No page ref - fallback to page 0 if single-page PDF\r\n return pages.length === 1 ? 0 : -1;\r\n }\r\n \r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n \r\n // If not found but single-page PDF, assume page 0\r\n if (pageIndex === -1 && pages.length === 1) {\r\n return 0;\r\n }\r\n \r\n return pageIndex;\r\n}\r\n\r\n","/**\r\n * PDF Field Type Helper Utilities\r\n * Common utilities for detecting field types and extracting values\r\n * \r\n * Used across pdf-manipulation.ts for consistent field processing\r\n */\r\n\r\n/**\r\n * PDF form field type for operations\r\n */\r\ninterface PDFFormField {\r\n getName(): string;\r\n constructor: { name: string };\r\n getText?(): string;\r\n setText?(text: string): void;\r\n isRequired?(): boolean;\r\n isChecked?(): boolean;\r\n getSelected?(): string[];\r\n enableReadOnly?(): void;\r\n}\r\n\r\n/**\r\n * Detect the field type from a PDF field\r\n * \r\n * Maps pdf-lib's field constructor names to standardized type strings.\r\n * \r\n * @param field - The PDF form field\r\n * @returns Standardized field type string\r\n * \r\n * @example\r\n * ```ts\r\n * const fieldType = detectFieldType(field);\r\n * // Returns: 'text', 'checkbox', 'dropdown', 'radiogroup', 'signature', etc.\r\n * ```\r\n */\r\nexport function detectFieldType(field: PDFFormField): string {\r\n const typeName = field.constructor.name;\r\n \r\n if (typeName === 'PDFTextField') {\r\n return 'text';\r\n } else if (typeName === 'PDFCheckBox') {\r\n return 'checkbox';\r\n } else if (typeName === 'PDFDropdown') {\r\n return 'dropdown';\r\n } else if (typeName === 'PDFOptionList') {\r\n return 'optionlist';\r\n } else if (typeName === 'PDFRadioGroup') {\r\n return 'radiogroup';\r\n } else if (typeName === 'PDFSignature') {\r\n return 'signature';\r\n }\r\n \r\n return 'unknown';\r\n}\r\n\r\n/**\r\n * Extract the current value from a PDF field based on its type\r\n * \r\n * Handles different field types appropriately:\r\n * - Text fields: getText()\r\n * - Checkboxes: isChecked() → 'true'/'false'\r\n * - Dropdowns: getSelected()[0]\r\n * - Radio groups: getSelected()[0]\r\n * \r\n * @param field - The PDF form field\r\n * @param fieldType - The field type (from detectFieldType)\r\n * @returns The field value as a string, or empty string if no value\r\n * \r\n * @example\r\n * ```ts\r\n * const fieldType = detectFieldType(field);\r\n * const value = extractFieldValue(field, fieldType);\r\n * ```\r\n */\r\nexport function extractFieldValue(field: PDFFormField, fieldType: string): string {\r\n try {\r\n switch (fieldType) {\r\n case 'text':\r\n return field.getText?.() || '';\r\n \r\n case 'checkbox':\r\n return field.isChecked?.() ? 'true' : 'false';\r\n \r\n case 'dropdown':\r\n case 'optionlist':\r\n case 'radiogroup':\r\n return field.getSelected?.()?.[0] || '';\r\n \r\n default:\r\n return '';\r\n }\r\n } catch (error) {\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Check if a field is required based on field metadata and name patterns\r\n * \r\n * Attempts to determine required status through:\r\n * 1. field.isRequired() method (if available)\r\n * 2. Field name patterns (signature, initials, required)\r\n * 3. Field type (signatures are always required)\r\n * \r\n * @param field - The PDF form field\r\n * @param fieldName - The field name\r\n * @param fieldType - The field type (from detectFieldType)\r\n * @returns true if field is required\r\n * \r\n * @example\r\n * ```ts\r\n * const isRequired = isRequiredField(field, 'signature_1', 'text');\r\n * // Returns: true (signature fields are required)\r\n * ```\r\n */\r\nexport function isRequiredField(\r\n field: PDFFormField,\r\n fieldName: string,\r\n fieldType: string\r\n): boolean {\r\n // Signature fields are always required\r\n if (fieldType === 'signature') {\r\n return true;\r\n }\r\n \r\n // Try the isRequired method if available\r\n try {\r\n if (field.isRequired?.()) {\r\n return true;\r\n }\r\n } catch {\r\n // isRequired() not available or threw error\r\n }\r\n \r\n // Check field name patterns\r\n if (\r\n fieldName.includes('signature') ||\r\n fieldName.includes('initials') ||\r\n fieldName.includes('required')\r\n ) {\r\n return true;\r\n }\r\n \r\n return false;\r\n}\r\n\r\n","/**\r\n * PDF Manipulation Utilities\r\n * Core utilities for PDF processing, page manipulation, and file combining\r\n */\r\n\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\nimport { loadPdfLib } from './pdf-lib-loader';\r\nimport { \r\n PdfPage, \r\n EsignFormField, \r\n FormFieldType, \r\n FormFieldPosition,\r\n MultiSignerContext \r\n} from '../types';\r\nimport { logger } from './logger';\r\nimport { validatePdfBytes, isAutoGeneratedLabel } from './pdf-validators';\r\nimport { isFieldVisibleToSigner, shouldFlattenField } from './field-visibility';\r\nimport { findPageIndexByRef, getWidgetRectangleAndPage, type PDFWidgetWithExtensions } from './pdf-widget-helpers';\r\nimport { detectFieldType, extractFieldValue, isRequiredField } from './pdf-field-type-helpers';\r\n\r\n// PDF.js worker is automatically configured by pdfjs-config module\r\n\r\n// Type definitions for PDF internal structures\r\ninterface PDFFieldWithAcro {\r\n getName(): string;\r\n acroField?: {\r\n getWidgets?: () => PDFWidget[];\r\n };\r\n constructor: { name: string };\r\n}\r\n\r\ninterface PDFWidget {\r\n getRectangle?: () => { x: number; y: number; width: number; height: number };\r\n P?: () => unknown;\r\n}\r\n\r\n/**\r\n * Convert PDF pages to images for rendering in the UI using PDF.js\r\n */\r\nexport async function pdfToImages(\r\n pdfBytes: Uint8Array,\r\n options?: { hideFormFields?: boolean }\r\n): Promise<PdfPage[]> {\r\n try {\r\n // Validate PDF bytes\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n logger.error('Invalid PDF:', validation.error);\r\n throw new Error(validation.error || 'Invalid PDF format');\r\n }\r\n\r\n // Load PDF with PDF.js\r\n const loadingTask = pdfjsLib.getDocument({\r\n data: pdfBytes,\r\n verbosity: 0,\r\n });\r\n const pdfDoc = await loadingTask.promise;\r\n\r\n const pages: PdfPage[] = [];\r\n\r\n // Try to load with pdf-lib for dimension comparison\r\n let pdfLibDoc = null;\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n pdfLibDoc = await PDFDocument.load(pdfBytes);\r\n } catch {\r\n // PDF.js dimensions will be used instead\r\n }\r\n\r\n for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {\r\n const page = await pdfDoc.getPage(pageNum);\r\n const viewport = page.getViewport({ scale: 2.0 });\r\n\r\n // Get actual PDF dimensions\r\n let pdfWidth = viewport.width / 2.0;\r\n let pdfHeight = viewport.height / 2.0;\r\n\r\n // Use pdf-lib dimensions if available for consistency\r\n if (pdfLibDoc) {\r\n try {\r\n const pdfLibPage = pdfLibDoc.getPage(pageNum - 1);\r\n pdfWidth = pdfLibPage.getWidth();\r\n pdfHeight = pdfLibPage.getHeight();\r\n } catch {\r\n // Use PDF.js dimensions as fallback\r\n }\r\n }\r\n\r\n // Create canvas at the scaled size for high quality rendering\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n canvas.height = viewport.height;\r\n canvas.width = viewport.width;\r\n\r\n // Render PDF page to canvas\r\n const hideFormFields = options?.hideFormFields ?? false;\r\n const renderContext: any = {\r\n canvasContext: context,\r\n viewport: viewport,\r\n renderInteractiveForms: !hideFormFields,\r\n ...(hideFormFields && {\r\n annotationMode: 0,\r\n renderAnnotations: false,\r\n renderForms: false,\r\n }),\r\n };\r\n\r\n await page.render(renderContext).promise;\r\n\r\n // Convert canvas to data URL\r\n const imageUrl = canvas.toDataURL('image/png');\r\n\r\n pages.push({\r\n pageNumber: pageNum,\r\n width: pdfWidth,\r\n height: pdfHeight,\r\n imageUrl,\r\n renderWidth: viewport.width,\r\n renderHeight: viewport.height,\r\n });\r\n }\r\n\r\n return pages;\r\n } catch (error) {\r\n logger.error('Error converting PDF to images with PDF.js:', error);\r\n return await fallbackPdfToImages(pdfBytes);\r\n }\r\n}\r\n\r\n/**\r\n * Fallback function to create placeholder images when PDF.js fails\r\n */\r\nasync function fallbackPdfToImages(pdfBytes: Uint8Array): Promise<PdfPage[]> {\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n const pdf = await PDFDocument.load(pdfBytes);\r\n const pages: PdfPage[] = [];\r\n\r\n for (let i = 0; i < pdf.getPageCount(); i++) {\r\n const page = pdf.getPage(i);\r\n const { width, height } = page.getSize();\r\n \r\n // Create placeholder canvas\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n \r\n const scale = 1.5;\r\n canvas.width = width * scale;\r\n canvas.height = height * scale;\r\n \r\n // Draw placeholder\r\n context.fillStyle = '#ffffff';\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n context.strokeStyle = '#e5e7eb';\r\n context.lineWidth = 2;\r\n context.strokeRect(0, 0, canvas.width, canvas.height);\r\n context.fillStyle = '#6b7280';\r\n context.font = 'bold 24px system-ui';\r\n context.textAlign = 'center';\r\n context.fillText(`Page ${i + 1}`, canvas.width / 2, canvas.height / 2 - 20);\r\n context.font = '16px system-ui';\r\n context.fillStyle = '#9ca3af';\r\n context.fillText('PDF preview not available', canvas.width / 2, canvas.height / 2 + 20);\r\n \r\n const imageUrl = canvas.toDataURL('image/png');\r\n \r\n pages.push({\r\n pageNumber: i + 1,\r\n width,\r\n height,\r\n imageUrl,\r\n renderWidth: canvas.width,\r\n renderHeight: canvas.height,\r\n });\r\n }\r\n\r\n return pages;\r\n } catch (error) {\r\n logger.error('Error with pdf-lib fallback:', error);\r\n // Return single error page\r\n return [createErrorPage()];\r\n }\r\n}\r\n\r\n/**\r\n * Create an error page when all processing fails\r\n */\r\nfunction createErrorPage(): PdfPage {\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n canvas.width = 600;\r\n canvas.height = 800;\r\n \r\n context.fillStyle = '#ffffff';\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n context.strokeStyle = '#e5e7eb';\r\n context.lineWidth = 2;\r\n context.strokeRect(0, 0, canvas.width, canvas.height);\r\n context.fillStyle = '#ef4444';\r\n context.font = 'bold 20px system-ui';\r\n context.textAlign = 'center';\r\n context.fillText('PDF Processing Error', canvas.width / 2, canvas.height / 2 - 20);\r\n context.font = '14px system-ui';\r\n context.fillStyle = '#6b7280';\r\n context.fillText('Unable to process the uploaded PDF file', canvas.width / 2, canvas.height / 2 + 20);\r\n \r\n return {\r\n pageNumber: 1,\r\n width: 600,\r\n height: 800,\r\n imageUrl: canvas.toDataURL('image/png'),\r\n renderWidth: canvas.width,\r\n renderHeight: canvas.height,\r\n };\r\n}\r\n\r\n// Type definitions for PDF form field operations\r\ninterface PDFFormField {\r\n getName(): string;\r\n constructor: { name: string };\r\n getText?(): string;\r\n setText?(text: string): void;\r\n isRequired?(): boolean;\r\n isChecked?(): boolean;\r\n getSelected?(): string[];\r\n enableReadOnly?(): void;\r\n}\r\n\r\ninterface PDFFormFieldWithAcro extends PDFFormField {\r\n acroField: {\r\n getWidgets(): unknown[];\r\n removeWidget(index: number): void;\r\n };\r\n}\r\n\r\ninterface PDFDict {\r\n get(key: unknown): unknown;\r\n delete(key: unknown): void;\r\n}\r\n\r\n/**\r\n * Remove all existing form fields from a PDF using robust widget cleanup\r\n * @param pdfBytes - The PDF bytes\r\n * @param stripAllAnnotations - If true, removes all annotations from pages (more aggressive cleanup)\r\n * @returns The PDF bytes with all form fields removed\r\n */\r\nexport async function removeAllFormFields(pdfBytes: Uint8Array, stripAllAnnotations = false): Promise<Uint8Array> {\r\n try {\r\n // Validate PDF data first\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n return pdfBytes;\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n \r\n if (stripAllAnnotations) {\r\n // More aggressive approach: strip all annotations from all pages\r\n const pages = pdfDoc.getPages();\r\n \r\n for (let i = 0; i < pages.length; i++) {\r\n const page = pages[i];\r\n \r\n try {\r\n // Access the page's annotation array\r\n const pageRef = (page as any).ref;\r\n const pageDictObj = pdfDoc.context.lookup(pageRef);\r\n \r\n if (pageDictObj) {\r\n const pageDict = pageDictObj as unknown as PDFDict;\r\n \r\n if (pageDict && pageDict.get && pageDict.delete) {\r\n const annotsRef = pageDict.get((pdfDoc.context as any).obj('Annots'));\r\n \r\n if (annotsRef) {\r\n pageDict.delete((pdfDoc.context as any).obj('Annots'));\r\n }\r\n } else {\r\n }\r\n } else {\r\n }\r\n } catch (pageError) {\r\n }\r\n }\r\n } else {\r\n // Robust widget-based removal approach\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n if (fields.length === 0) {\r\n return pdfBytes;\r\n }\r\n \r\n // Remove all fields using robust widget cleanup\r\n for (const field of fields) {\r\n try {\r\n const acroField = (field as unknown as PDFFormFieldWithAcro).acroField;\r\n if (acroField && typeof acroField.getWidgets === 'function') {\r\n let widgets = acroField.getWidgets();\r\n \r\n // Remove widgets one by one with safety counter\r\n let safetyCounter = 0;\r\n const maxIterations = widgets.length + 5;\r\n \r\n while (widgets.length > 0 && safetyCounter < maxIterations) {\r\n try {\r\n const widgetIndex = widgets.length - 1;\r\n acroField.removeWidget(widgetIndex);\r\n widgets = acroField.getWidgets();\r\n } catch (widgetError) {\r\n break;\r\n }\r\n safetyCounter++;\r\n }\r\n \r\n if (safetyCounter >= maxIterations) {\r\n }\r\n }\r\n \r\n form.removeField(field as any);\r\n } catch (error) {\r\n \r\n try {\r\n form.removeField(field as any);\r\n } catch (fallbackError) {\r\n }\r\n }\r\n }\r\n \r\n const remainingFields = form.getFields();\r\n if (remainingFields.length > 0) {\r\n }\r\n }\r\n \r\n const updatedPdfBytes = await pdfDoc.save();\r\n return updatedPdfBytes;\r\n } catch (error) {\r\n logger.error('Error removing form fields from PDF:', error);\r\n return pdfBytes;\r\n }\r\n}\r\n\r\n/**\r\n * Read existing PDF form fields and their properties\r\n */\r\nexport async function readPdfFormFields(pdfBytes: Uint8Array): Promise<{\r\n name: string;\r\n type: string;\r\n required: boolean;\r\n value?: string;\r\n}[]> {\r\n try {\r\n // Validate PDF data first\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n return [];\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n if (fields.length === 0) {\r\n return [];\r\n }\r\n \r\n const formFields = fields.map(field => {\r\n const fieldName = field.getName();\r\n const pdfField = field as unknown as PDFFormField;\r\n \r\n try {\r\n // Use centralized field type detection and value extraction\r\n const fieldType = detectFieldType(pdfField);\r\n const value = extractFieldValue(pdfField, fieldType);\r\n const required = isRequiredField(pdfField, fieldName, fieldType);\r\n \r\n return {\r\n name: fieldName,\r\n type: fieldType,\r\n required,\r\n value\r\n };\r\n } catch (fieldError) {\r\n // Fallback to defaults on error\r\n return {\r\n name: fieldName,\r\n type: 'text',\r\n required: false,\r\n value: ''\r\n };\r\n }\r\n });\r\n \r\n return formFields;\r\n } catch (error) {\r\n logger.error('Error reading PDF form fields:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Read current PDF form field values (including user-filled data)\r\n */\r\nexport async function readCurrentPdfFormValues(pdfBytes: Uint8Array): Promise<Record<string, string>> {\r\n try {\r\n if (!pdfBytes || pdfBytes.length === 0) {\r\n return {};\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n const currentValues: Record<string, string> = {};\r\n \r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const pdfField = field as unknown as PDFFormField;\r\n \r\n try {\r\n // Use centralized field type detection and value extraction\r\n const fieldType = detectFieldType(pdfField);\r\n const value = extractFieldValue(pdfField, fieldType);\r\n \r\n currentValues[fieldName] = value;\r\n } catch (fieldError) {\r\n currentValues[fieldName] = '';\r\n }\r\n }\r\n \r\n return currentValues;\r\n } catch (error) {\r\n logger.error('Error reading current PDF form values:', error);\r\n return {};\r\n }\r\n}\r\n\r\n/**\r\n * Validate PDF form fields against provided values\r\n * In multi-signer mode, only validates fields visible to the current signer\r\n */\r\nexport async function validatePdfFormFields(\r\n pdfBytes: Uint8Array,\r\n fieldValues: Record<string, string>,\r\n signatures: Record<string, string>,\r\n extractedFields?: EsignFormField[], // Pass extracted fields to know which are visible\r\n multiSignerContext?: MultiSignerContext // Pass context to filter validation\r\n): Promise<string[]> {\r\n try {\r\n const pdfFormFields = await readPdfFormFields(pdfBytes);\r\n const errors: string[] = [];\r\n \r\n \r\n for (const field of pdfFormFields) {\r\n if (field.required) {\r\n // In multi-signer mode, only validate fields visible to current signer\r\n if (multiSignerContext?.isMultiSigner && extractedFields) {\r\n const extractedField = extractedFields.find(f => f.name === field.name);\r\n if (!extractedField) {\r\n // Field not in extractedFields means it's not visible to current signer\r\n continue;\r\n }\r\n }\r\n \r\n let hasValue = false;\r\n const fieldValue = fieldValues[field.name];\r\n const signatureValue = signatures[field.name];\r\n const mainSignature = signatures['signature_field_main'];\r\n const mainInitials = signatures['initials_field_main'] || fieldValues['initials_field_main'];\r\n \r\n if (field.name.includes('signature') || field.type === 'signature') {\r\n hasValue = !!(signatureValue || fieldValue || mainSignature);\r\n } else if (field.name.includes('initials')) {\r\n hasValue = !!(signatureValue || fieldValue || mainInitials);\r\n } else {\r\n hasValue = !!(fieldValue || field.value);\r\n }\r\n \r\n if (!hasValue) {\r\n let friendlyName = field.name.replace(/[_-]/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\r\n \r\n if (field.name.includes('signature')) {\r\n friendlyName = 'Signature';\r\n } else if (field.name.includes('initials')) {\r\n friendlyName = 'Initials';\r\n }\r\n \r\n errors.push(`${friendlyName} is required`);\r\n }\r\n }\r\n }\r\n \r\n return errors;\r\n } catch (error) {\r\n logger.error('Error validating PDF form fields:', error);\r\n return ['Unable to validate form fields. Please ensure all required fields are completed.'];\r\n }\r\n}\r\n\r\n/**\r\n * Validate PDF form fields against current form state\r\n */\r\nexport async function validateCurrentPdfState(\r\n pdfBytes: Uint8Array,\r\n signatures: Record<string, string>,\r\n formFieldValues: Record<string, string> = {}\r\n): Promise<string[]> {\r\n try {\r\n const pdfFormFields = await readPdfFormFields(pdfBytes);\r\n const currentValues = await readCurrentPdfFormValues(pdfBytes);\r\n const errors: string[] = [];\r\n \r\n for (const field of pdfFormFields) {\r\n const isSignatureField = field.name.includes('signature') && field.type === 'text';\r\n const isInitialsField = field.name.includes('initials') && field.type === 'text';\r\n \r\n if (field.required || isSignatureField || isInitialsField) {\r\n let hasValue = false;\r\n const currentValue = currentValues[field.name] || '';\r\n \r\n if (isSignatureField) {\r\n hasValue = !!signatures[field.name];\r\n } else if (isInitialsField) {\r\n hasValue = !!signatures[field.name] || !!(formFieldValues[field.name]?.trim()) || currentValue.trim() !== '';\r\n } else {\r\n hasValue = currentValue.trim() !== '';\r\n }\r\n \r\n if (!hasValue) {\r\n let friendlyName = field.name.replace(/[_-]/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\r\n \r\n if (field.name.includes('signature')) {\r\n friendlyName = 'Signature';\r\n } else if (field.name.includes('initials')) {\r\n friendlyName = 'Initials';\r\n }\r\n \r\n errors.push(`${friendlyName} is required`);\r\n }\r\n }\r\n }\r\n \r\n return errors;\r\n } catch (error) {\r\n logger.error('Error validating current PDF state:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Fill PDF with signature images and form field values, then flatten the form\r\n * @param pdfBytes - The PDF bytes\r\n * @param signatures - The signature data URLs (field name -> base64 PNG)\r\n * @param formFieldValues - The form field values to fill\r\n * @returns The filled and flattened PDF bytes\r\n */\r\nexport async function fillPdfWithSignatures(\r\n pdfBytes: Uint8Array,\r\n signatures: Record<string, string>,\r\n formFieldValues: Record<string, string> = {},\r\n currentSignerEmail?: string,\r\n extractedFormFields?: EsignFormField[],\r\n metadata?: { submissionId?: string; documentId?: string; author?: string; signerEmail?: string; signerInitials?: string; createdAt?: Date },\r\n auditTrail?: { userAgent?: string; screenResolution?: string; timezone?: string; language?: string; platform?: string; ipAddress?: string; geolocation?: { latitude: number; longitude: number; accuracy?: number } },\r\n multiSignerContext?: { isMultiSigner: boolean; currentSigner: any; currentSignerEmail: string; isPrimarySigner: boolean; isFinalSigner: boolean }\r\n): Promise<Uint8Array> {\r\n try {\r\n const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const pages = pdfDoc.getPages();\r\n \r\n // Get field positions and page numbers\r\n const { pageMap: fieldPageMap, positionMap: fieldPositionMap } = await getFieldPageNumbers(pdfBytes);\r\n \r\n // STEP 1: Fill all text form fields\r\n \r\n const fields = form.getFields();\r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const fieldValue = formFieldValues[fieldName];\r\n \r\n if (!fieldValue) {\r\n // Log missing values for radio fields to diagnose\r\n if (fieldName.includes('radio')) {\r\n }\r\n continue;\r\n }\r\n \r\n try {\r\n const fieldTypeName = field.constructor.name;\r\n \r\n // Handle text fields\r\n if (fieldTypeName === 'PDFTextField' || fieldTypeName === 'PDFTextField2') {\r\n const textField = field as any;\r\n textField.setText?.(fieldValue);\r\n }\r\n // Handle checkbox fields\r\n else if (fieldTypeName === 'PDFCheckBox' || fieldTypeName === 'PDFCheckBox2') {\r\n const checkBox = field as any;\r\n if (fieldValue === 'true' || fieldValue === 'Yes' || fieldValue === 'checked' || fieldValue === 'On') {\r\n checkBox.check?.();\r\n } else {\r\n checkBox.uncheck?.();\r\n }\r\n }\r\n // Handle radio group fields\r\n else if (fieldTypeName === 'PDFRadioGroup' || fieldTypeName === 'PDFRadioGroup2') {\r\n const radioGroup = field as any;\r\n \r\n // Skip invalid values (boolean strings from checkbox-like behavior)\r\n if (fieldValue === 'true' || fieldValue === 'false') {\r\n continue;\r\n }\r\n \r\n // Handle __RADIO_OPTION_INDEX_ pattern\r\n const idxMatch = fieldValue.match(/__RADIO_OPTION_INDEX_(\\d+)__/);\r\n if (idxMatch && idxMatch[1]) {\r\n const selectedIndex = parseInt(idxMatch[1], 10);\r\n const options = radioGroup.getOptions?.() || [];\r\n if (selectedIndex >= 0 && selectedIndex < options.length) {\r\n radioGroup.select?.(options[selectedIndex]);\r\n }\r\n } else {\r\n // Try to use the value directly if it's a valid option\r\n const options = radioGroup.getOptions?.() || [];\r\n if (options.includes(fieldValue)) {\r\n radioGroup.select?.(fieldValue);\r\n } else {\r\n }\r\n }\r\n }\r\n // Handle dropdown fields\r\n else if (fieldTypeName === 'PDFDropdown' || fieldTypeName === 'PDFDropdown2') {\r\n const dropdown = field as any;\r\n dropdown.select?.(fieldValue);\r\n }\r\n } catch (fieldError) {\r\n logger.error(`Error setting field \"${fieldName}\":`, fieldError);\r\n }\r\n }\r\n\r\n // Update form field appearances to ensure radio button selections render correctly\r\n // This is critical for radio buttons to display properly in PDF viewers\r\n // Fix based on dm-web-frontend commit aafc786 (Oct 29, 2025)\r\n try {\r\n form.updateFieldAppearances();\r\n \r\n // CRITICAL: Set NeedAppearances to false to tell PDF viewers to use the appearance streams we generated\r\n // This is essential for Chrome's PDF viewer which strictly requires appearance dictionaries\r\n const PDFName = pdfLib.PDFName;\r\n const acroForm = pdfDoc.catalog.lookup(PDFName.of('AcroForm'));\r\n if (acroForm && typeof acroForm === 'object' && 'set' in acroForm) {\r\n (acroForm as any).set(PDFName.of('NeedAppearances'), false);\r\n }\r\n } catch (appearanceError) {\r\n // Some PDFs may not support this operation - fail gracefully\r\n logger.warn('Could not update field appearances:', appearanceError);\r\n }\r\n\r\n // STEP 2: Apply signature images to ALL signature fields\r\n const mainSignatureData = signatures['signature_field_main'];\r\n if (mainSignatureData && mainSignatureData.trim()) {\r\n \r\n // Find ALL signature field names (excluding text_ prefix and non-signature fields)\r\n // Match dockmaster patterns including '_es_:signer:signature' for esign integration\r\n const signatureFieldNames = [\r\n 'signature', 'Signature', 'SIGNATURE',\r\n 'sign', 'Sign', 'SIGN',\r\n '_es_:signer:signature'\r\n ];\r\n let foundSignatureFields = Object.keys(fieldPageMap).filter(fieldName => {\r\n const hasSignaturePattern = signatureFieldNames.some(pattern => \r\n fieldName.toLowerCase().includes(pattern.toLowerCase())\r\n );\r\n const isNotTextField = !fieldName.toLowerCase().startsWith('text_');\r\n return hasSignaturePattern && isNotTextField;\r\n });\r\n \r\n // CRITICAL: Filter to only ACTUAL signature fields, not checkbox/radio/dropdown\r\n if (extractedFormFields && extractedFormFields.length > 0) {\r\n const currentSignerSignatureFields = foundSignatureFields.filter(fieldName => {\r\n const fieldInfo = extractedFormFields.find(f => f.name === fieldName);\r\n if (!fieldInfo) {\r\n return false;\r\n }\r\n \r\n // CRITICAL FIX: Only process ACTUAL signature fields, NOT initials\r\n // Signature images should ONLY be applied to signature fields\r\n // Initials are handled separately as text (not images)\r\n // Fix based on dm-web-frontend commit 30895b5 (Oct 29, 2025)\r\n const isActualSignatureField = (fieldInfo.type === 'signature' ||\r\n fieldName.toLowerCase().includes('signature'))\r\n && !fieldName.toLowerCase().includes('initials'); // Explicitly exclude initials\r\n\r\n if (!isActualSignatureField) {\r\n return false;\r\n }\r\n \r\n // Use centralized visibility logic for multi-signer and single-signer modes\r\n const isVisible = multiSignerContext \r\n ? isFieldVisibleToSigner(fieldInfo, multiSignerContext)\r\n : true; // Single signer mode: all fields visible\r\n \r\n return isVisible;\r\n });\r\n foundSignatureFields = currentSignerSignatureFields;\r\n }\r\n \r\n \r\n if (foundSignatureFields.length > 0) {\r\n try {\r\n // Detect image format with binary signature detection\r\n let signatureImage;\r\n if (mainSignatureData.includes('data:image/png')) {\r\n signatureImage = await pdfDoc.embedPng(mainSignatureData);\r\n } else if (mainSignatureData.includes('data:image/jpeg') || mainSignatureData.includes('data:image/jpg')) {\r\n signatureImage = await pdfDoc.embedJpg(mainSignatureData);\r\n } else {\r\n // Fallback: detect by binary signature\r\n const base64Data = mainSignatureData.split(',')[1];\r\n if (!base64Data) {\r\n throw new Error('Invalid signature data format: missing base64 data');\r\n }\r\n const binaryData = atob(base64Data);\r\n \r\n // Check PNG signature (first 8 bytes: 89 50 4E 47 0D 0A 1A 0A)\r\n if (binaryData.charCodeAt(0) === 0x89 && \r\n binaryData.charCodeAt(1) === 0x50 && \r\n binaryData.charCodeAt(2) === 0x4E && \r\n binaryData.charCodeAt(3) === 0x47) {\r\n signatureImage = await pdfDoc.embedPng(mainSignatureData);\r\n } \r\n // Check JPEG signature (first 3 bytes: FF D8 FF)\r\n else if (binaryData.charCodeAt(0) === 0xFF && \r\n binaryData.charCodeAt(1) === 0xD8 && \r\n binaryData.charCodeAt(2) === 0xFF) {\r\n signatureImage = await pdfDoc.embedJpg(mainSignatureData);\r\n } \r\n else {\r\n throw new Error('Unsupported image format. Please use PNG or JPEG.');\r\n }\r\n }\r\n \r\n // Draw signature images using EXACT field coordinates\r\n for (const fieldName of foundSignatureFields) {\r\n \r\n const pageNumber = fieldPageMap[fieldName];\r\n \r\n if (pageNumber && pageNumber <= pages.length) {\r\n const page = pages[pageNumber - 1]; // Convert to 0-based index\r\n if (!page) continue;\r\n \r\n // Get EXACT field position from the map\r\n const fieldPosition = fieldPositionMap[fieldName];\r\n \r\n if (fieldPosition) {\r\n // Use EXACT field coordinates (NO CENTERING)\r\n const x = fieldPosition.x;\r\n const y = fieldPosition.y;\r\n const width = Math.max(fieldPosition.width, 80);\r\n const height = Math.max(fieldPosition.height, 30);\r\n \r\n // Scale signature to fit the field\r\n const signatureDims = signatureImage.scaleToFit(width - 4, height - 4);\r\n \r\n // FIXED POSITIONING: Use exact field coordinates\r\n const finalX = x;\r\n const finalY = y;\r\n \r\n \r\n page.drawImage(signatureImage, {\r\n x: finalX,\r\n y: finalY,\r\n width: signatureDims.width,\r\n height: signatureDims.height,\r\n });\r\n \r\n } else {\r\n }\r\n } else {\r\n }\r\n }\r\n } catch (error) {\r\n logger.error('Error applying signatures:', error);\r\n }\r\n }\r\n }\r\n \r\n // STEP 3: Apply initials to ALL initials fields\r\n console.log('[FLATTEN] === APPLYING INITIALS ===');\r\n console.log('[FLATTEN] formFieldValues keys:', Object.keys(formFieldValues));\r\n console.log('[FLATTEN] Initials fields in formFieldValues:', Object.keys(formFieldValues).filter(k => k.toLowerCase().includes('initials')));\r\n const mainInitialsData = formFieldValues['initials_field_main'];\r\n console.log('[FLATTEN] mainInitialsData from initials_field_main:', mainInitialsData ? mainInitialsData.substring(0, 50) : '(MISSING)');\r\n if (mainInitialsData && mainInitialsData.trim()) {\r\n \r\n console.log('[FLATTEN] fieldPageMap keys:', Object.keys(fieldPageMap));\r\n console.log('[FLATTEN] Looking for initials fields in fieldPageMap...');\r\n\r\n const initialsFieldNames = ['initials', 'Initials', 'INITIALS'];\r\n let foundInitialsFields = Object.keys(fieldPageMap).filter(fieldName =>\r\n initialsFieldNames.some(pattern => fieldName.toLowerCase().includes(pattern.toLowerCase()))\r\n );\r\n console.log('[FLATTEN] After pattern matching in fieldPageMap:', foundInitialsFields);\r\n\r\n // Filter by signer if needed\r\n if (extractedFormFields && extractedFormFields.length > 0) {\r\n foundInitialsFields = foundInitialsFields.filter(fieldName => {\r\n const fieldInfo = extractedFormFields.find(f => f.name === fieldName);\r\n if (!fieldInfo) return false;\r\n\r\n const isActualInitialsField = fieldInfo.type === 'initials' ||\r\n fieldName.toLowerCase().includes('initials');\r\n if (!isActualInitialsField) return false;\r\n\r\n // Use centralized visibility logic for multi-signer and single-signer modes\r\n const isVisible = multiSignerContext\r\n ? isFieldVisibleToSigner(fieldInfo, multiSignerContext)\r\n : true; // Single signer mode: all fields visible\r\n\r\n return isVisible;\r\n });\r\n }\r\n\r\n console.log('[FLATTEN] Found', foundInitialsFields.length, 'initials fields to flatten:', foundInitialsFields);\r\n if (foundInitialsFields.length > 0) {\r\n try {\r\n const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n\r\n for (const fieldName of foundInitialsFields) {\r\n console.log('[FLATTEN] Processing initials field:', fieldName);\r\n const pageNumber = fieldPageMap[fieldName];\r\n console.log('[FLATTEN] Page number:', pageNumber);\r\n if (pageNumber && pageNumber <= pages.length) {\r\n const page = pages[pageNumber - 1];\r\n if (!page) {\r\n console.log('[FLATTEN] ❌ Page not found');\r\n continue;\r\n }\r\n\r\n const fieldPosition = fieldPositionMap[fieldName];\r\n console.log('[FLATTEN] Field position:', fieldPosition);\r\n if (fieldPosition) {\r\n const x = fieldPosition.x;\r\n const y = fieldPosition.y;\r\n const height = Math.max(fieldPosition.height, 20);\r\n\r\n const fontSize = Math.min(height * 0.7, 14);\r\n\r\n // EXACT positioning (no centering)\r\n const finalX = x + 2;\r\n const finalY = y + (height - fontSize) / 2;\r\n\r\n console.log('[FLATTEN] ✅ Drawing initials at:', { x: finalX, y: finalY, fontSize, text: mainInitialsData });\r\n page.drawText(mainInitialsData, {\r\n x: finalX,\r\n y: finalY,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n\r\n } else {\r\n console.log('[FLATTEN] ❌ Field position not found in position map');\r\n }\r\n } else {\r\n console.log('[FLATTEN] ❌ Invalid page number or page out of bounds');\r\n }\r\n }\r\n } catch (error) {\r\n logger.error('Error applying initials:', error);\r\n }\r\n }\r\n }\r\n \r\n // STEP 4: Flatten form fields based on multi-signer mode\r\n \r\n const allFormFields = form.getFields();\r\n \r\n let fieldsToFlatten;\r\n \r\n if (multiSignerContext?.isMultiSigner) {\r\n // PARTIAL FLATTENING: Only flatten current signer's fields (Dockmaster logic lines 2500-2526)\r\n \r\n fieldsToFlatten = allFormFields.filter(f => {\r\n const fieldName = f.getName();\r\n \r\n if (!extractedFormFields || extractedFormFields.length === 0) {\r\n return true; // Flatten all if no field info\r\n }\r\n \r\n const fieldInfo = extractedFormFields.find(fi => fi.name === fieldName);\r\n if (!fieldInfo) {\r\n return true; // Flatten unknown fields\r\n }\r\n \r\n // Use centralized flattening logic\r\n return shouldFlattenField(fieldInfo, multiSignerContext);\r\n });\r\n } else {\r\n // COMPLETE FLATTENING: Flatten all fields (single signer mode)\r\n fieldsToFlatten = allFormFields;\r\n }\r\n \r\n // Helper interfaces for widget access\r\n interface PDFFieldWithAcro {\r\n acroField?: {\r\n getWidgets?: () => PDFWidget[];\r\n dict?: any;\r\n };\r\n }\r\n \r\n let flattenedCount = 0;\r\n \r\n for (const field of fieldsToFlatten) {\r\n const fieldName = field.getName();\r\n const fieldType = field.constructor.name;\r\n \r\n try {\r\n // Get user entered value\r\n const userEnteredValue = formFieldValues[fieldName];\r\n \r\n // Check if this is a signature/initials field\r\n const isSignatureField = fieldName.toLowerCase().includes('signature') || fieldType.includes('Signature');\r\n const isInitialsField = fieldName.toLowerCase().includes('initials') || fieldType.includes('Initials');\r\n \r\n if (isSignatureField || isInitialsField) {\r\n // Signature/initials fields were already drawn in STEP 2/3, just remove the field\r\n form.removeField(field);\r\n flattenedCount++;\r\n continue;\r\n }\r\n \r\n // Get field widgets for drawing\r\n const fieldWithWidgets = field as unknown as PDFFieldWithAcro;\r\n const widgets = fieldWithWidgets.acroField?.getWidgets?.() || [];\r\n \r\n // Handle different field types - draw their content\r\n if (fieldType === 'PDFCheckBox' || fieldType === 'PDFCheckBox2') {\r\n // Checkbox field - draw checkbox with checkmark if checked\r\n const stringValue = String(userEnteredValue || '');\r\n const isChecked = stringValue === 'true' || stringValue === 'Yes' || \r\n stringValue === 'On' || stringValue === 'checked';\r\n \r\n \r\n if (isChecked) {\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw checkbox border\r\n const checkboxSize = Math.min(rect.width, rect.height) * 0.6;\r\n const checkboxX = rect.x + (rect.width - checkboxSize) / 2;\r\n const checkboxY = rect.y + (rect.height - checkboxSize) / 2;\r\n \r\n page.drawRectangle({\r\n x: checkboxX,\r\n y: checkboxY,\r\n width: checkboxSize,\r\n height: checkboxSize,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n });\r\n \r\n // Draw checkmark using \"X\"\r\n const checkSize = checkboxSize * 0.6;\r\n const textWidth = checkSize * 0.6;\r\n const textHeight = checkSize * 0.8;\r\n \r\n page.drawText('X', {\r\n x: checkboxX + (checkboxSize - textWidth) / 2,\r\n y: checkboxY + (checkboxSize - textHeight) / 2 + textHeight * 0.2,\r\n size: checkSize,\r\n font: await pdfDoc.embedFont(StandardFonts.HelveticaBold),\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n }\r\n } else if (fieldType === 'PDFRadioGroup' || fieldType === 'PDFRadioGroup2') {\r\n // Radio group field - draw all radio buttons, fill the selected one\r\n const radioGroup = field as any;\r\n \r\n // Get field info for labels and options (need this before determining selectedIndex)\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n \r\n // Get the ACTUAL selected value from the PDF field (after it was set)\r\n let actualSelectedValue = '';\r\n try {\r\n actualSelectedValue = radioGroup.getSelected?.() || '';\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: radioGroup.getSelected() returned: \"${actualSelectedValue}\"`);\r\n } catch (e) {\r\n // Fallback to user entered value if we can't read the field\r\n actualSelectedValue = userEnteredValue ? String(userEnteredValue) : '';\r\n logger.warn(`[FLATTEN RADIO] Field ${fieldName}: could not read selected value, using userEnteredValue: \"${actualSelectedValue}\"`);\r\n }\r\n \r\n // Determine selected index\r\n let selectedIndex = -1;\r\n \r\n // Get all options from the radio group\r\n const radioOptions = radioGroup.getOptions?.() || [];\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: radioGroup.getOptions() returned ${radioOptions.length} options:`, radioOptions);\r\n \r\n // If we have an actual selected value from the field, find its index\r\n if (actualSelectedValue && radioOptions.length > 0) {\r\n selectedIndex = radioOptions.findIndex((opt: string) => opt === actualSelectedValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: found actualSelectedValue \"${actualSelectedValue}\" at index ${selectedIndex}`);\r\n }\r\n \r\n // Fallback: try to parse from user entered value if we didn't find it above\r\n if (selectedIndex === -1 && userEnteredValue) {\r\n const selectedValue = String(userEnteredValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: selectedIndex still -1, trying to parse from userEnteredValue: \"${selectedValue}\"`);\r\n \r\n // Handle __RADIO_OPTION_INDEX_ pattern directly\r\n if (selectedValue.startsWith('__RADIO_OPTION_INDEX_')) {\r\n const indexMatch = selectedValue.match(/__RADIO_OPTION_INDEX_(\\d+)__/);\r\n if (indexMatch && indexMatch[1]) {\r\n selectedIndex = parseInt(indexMatch[1], 10);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: extracted index ${selectedIndex} from __RADIO_OPTION_INDEX_ pattern`);\r\n }\r\n } \r\n // Handle numeric string (just an index)\r\n else if (/^\\d+$/.test(selectedValue)) {\r\n selectedIndex = parseInt(selectedValue, 10);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: parsed numeric index ${selectedIndex}`);\r\n }\r\n // Match against actual option values from field info\r\n else if (fieldInfo?.options && selectedValue) {\r\n selectedIndex = fieldInfo.options.findIndex(option => option === selectedValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: matched \"${selectedValue}\" in fieldInfo.options at index ${selectedIndex}`);\r\n }\r\n // Match against radio group options\r\n else if (radioOptions.length > 0) {\r\n selectedIndex = radioOptions.findIndex((opt: string) => opt === selectedValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: matched \"${selectedValue}\" in radioOptions at index ${selectedIndex}`);\r\n }\r\n }\r\n \r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: FINAL selectedIndex = ${selectedIndex}, will draw filled circle at this index`);\r\n const labelFont = await pdfDoc.embedFont('Helvetica-Bold');\r\n const drawnGroupLabels = new Set<string>();\r\n const drawnOptionLabels = new Set<string>();\r\n \r\n // Draw borders for ALL radio buttons\r\n for (let i = 0; i < widgets.length; i++) {\r\n const widget = widgets[i];\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page, pageIndex } = result;\r\n \r\n // Draw radio GROUP label (once, above first widget)\r\n // Only draw if it's a user-typed custom label (not auto-generated)\r\n if (i === 0 && fieldInfo?.label && fieldInfo.label.trim() && !isAutoGeneratedLabel(fieldInfo.label)) {\r\n const groupLabelKey = `${pageIndex}-${fieldName}-grouplabel`;\r\n if (!drawnGroupLabels.has(groupLabelKey)) {\r\n const labelY = rect.y + rect.height + 3;\r\n page.drawText(fieldInfo.label, {\r\n x: rect.x,\r\n y: labelY,\r\n size: 8,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n drawnGroupLabels.add(groupLabelKey);\r\n }\r\n } else if (i === 0 && isAutoGeneratedLabel(fieldInfo?.label || '')) {\r\n }\r\n \r\n // Draw radio button border (circle)\r\n const radioSize = Math.min(rect.width, rect.height) * 0.5;\r\n const radioX = rect.x + (rect.width - radioSize) / 2;\r\n const radioY = rect.y + (rect.height - radioSize) / 2;\r\n \r\n page.drawCircle({\r\n x: radioX + radioSize / 2,\r\n y: radioY + radioSize / 2,\r\n size: radioSize,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n });\r\n \r\n // Draw filled circle ONLY for selected option\r\n if (i === selectedIndex) {\r\n const circleSize = radioSize * 0.5;\r\n page.drawCircle({\r\n x: radioX + radioSize / 2,\r\n y: radioY + radioSize / 2,\r\n size: circleSize,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw option text next to each radio button\r\n if (fieldInfo?.options && fieldInfo.options.length > i) {\r\n const optionText = fieldInfo.options[i];\r\n const optionKey = `${pageIndex}-${fieldName}-opt-${i}`;\r\n \r\n if (optionText && !drawnOptionLabels.has(optionKey)) {\r\n page.drawText(optionText, {\r\n x: rect.x + rect.width + 4,\r\n y: rect.y + (rect.height - 8) / 2,\r\n size: 8,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n drawnOptionLabels.add(optionKey);\r\n }\r\n }\r\n }\r\n \r\n if (fieldInfo?.options) {\r\n }\r\n } else if (fieldType === 'PDFDropdown' || fieldType === 'PDFDropdown2') {\r\n // Dropdown field - draw the selected value\r\n const selectedValue = userEnteredValue ? String(userEnteredValue) : '';\r\n \r\n \r\n if (selectedValue && selectedValue.trim()) {\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw the selected value\r\n page.drawText(selectedValue, {\r\n x: rect.x + 2,\r\n y: rect.y + 2,\r\n size: 10,\r\n font: await pdfDoc.embedFont(StandardFonts.Helvetica),\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n }\r\n } else {\r\n // Text field or other field types - draw the field value\r\n const fieldValue = userEnteredValue ? String(userEnteredValue) : '';\r\n \r\n \r\n if (fieldValue && fieldValue.trim()) {\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw the field value\r\n page.drawText(fieldValue, {\r\n x: rect.x + 2,\r\n y: rect.y + 2,\r\n size: 10,\r\n font: await pdfDoc.embedFont(StandardFonts.Helvetica),\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n }\r\n }\r\n \r\n // Remove the field to flatten it\r\n form.removeField(field);\r\n flattenedCount++;\r\n } catch (error) {\r\n }\r\n }\r\n \r\n const remainingFields = form.getFields();\r\n \r\n // Verify flattening worked\r\n if (multiSignerContext?.isMultiSigner) {\r\n // MULTI-SIGNER MODE: Remaining fields are EXPECTED (for other signers)\r\n const expectedRemainingCount = allFormFields.length - fieldsToFlatten.length;\r\n if (remainingFields.length === expectedRemainingCount) {\r\n } else {\r\n }\r\n } else {\r\n // SINGLE-SIGNER MODE: All fields should be flattened\r\n if (remainingFields.length > 0) {\r\n logger.error(`MANUAL FLATTENING INCOMPLETE: ${remainingFields.length} fields still exist!`);\r\n logger.error(`Remaining fields:`, remainingFields.map(f => f.getName()));\r\n \r\n // Try basic flattening as final fallback (only in single-signer mode)\r\n try {\r\n form.flatten();\r\n const finalRemainingFields = form.getFields();\r\n \r\n if (finalRemainingFields.length > 0) {\r\n logger.error(`ALL FLATTENING METHODS FAILED: ${finalRemainingFields.length} fields still exist!`);\r\n logger.error(`Final remaining fields:`, finalRemainingFields.map(f => f.getName()));\r\n }\r\n } catch (fallbackError) {\r\n logger.error('Fallback flattening failed:', fallbackError);\r\n }\r\n } else {\r\n }\r\n }\r\n \r\n // STEP 6: Set document metadata for tracking and compliance\r\n try {\r\n // Set document metadata based on submission data\r\n // Set Title (with default if not provided)\r\n const documentTitle = metadata?.documentId \r\n ? `Document ID: ${metadata.documentId}`\r\n : 'Signed Document';\r\n pdfDoc.setTitle(documentTitle);\r\n \r\n // Set Subject (with default if not provided)\r\n const documentSubject = metadata?.submissionId\r\n ? `Submission ID: ${metadata.submissionId}`\r\n : metadata?.signerEmail\r\n ? `Signed by ${metadata.signerEmail}`\r\n : 'Digitally Signed Document';\r\n pdfDoc.setSubject(documentSubject);\r\n \r\n // Set Author (with default if not provided)\r\n const documentAuthor = metadata?.author || metadata?.signerEmail || 'Unknown';\r\n pdfDoc.setAuthor(documentAuthor);\r\n \r\n pdfDoc.setProducer('Created by signiphi (https://signiphi.ai/)');\r\n \r\n if (metadata?.signerEmail) {\r\n pdfDoc.setCreator(`Signer: ${metadata.signerEmail}`);\r\n }\r\n \r\n // Set creation date from submission\r\n if (metadata?.createdAt) {\r\n pdfDoc.setCreationDate(metadata.createdAt);\r\n }\r\n \r\n // Set current date as modification date\r\n pdfDoc.setModificationDate(new Date());\r\n \r\n // Set keywords for searchability and tracking\r\n const keywords: string[] = [];\r\n \r\n // Add signer email if available\r\n if (metadata?.signerEmail) {\r\n keywords.push(metadata.signerEmail);\r\n }\r\n \r\n // Add initials to metadata if available\r\n if (metadata?.signerInitials && metadata.signerInitials.trim()) {\r\n keywords.push(`Initials:${metadata.signerInitials.trim()}`);\r\n }\r\n \r\n // Add audit trail data for compliance and forensics\r\n if (auditTrail) {\r\n try {\r\n // Device/Browser information\r\n if (auditTrail.userAgent) {\r\n keywords.push(`UserAgent:${auditTrail.userAgent}`);\r\n }\r\n \r\n // Screen resolution as device identifier\r\n if (auditTrail.screenResolution) {\r\n keywords.push(`Screen:${auditTrail.screenResolution}`);\r\n }\r\n \r\n // Timezone\r\n if (auditTrail.timezone) {\r\n keywords.push(`Timezone:${auditTrail.timezone}`);\r\n }\r\n \r\n // Language settings\r\n if (auditTrail.language) {\r\n keywords.push(`Language:${auditTrail.language}`);\r\n }\r\n \r\n // Platform information\r\n if (auditTrail.platform) {\r\n keywords.push(`Platform:${auditTrail.platform}`);\r\n }\r\n \r\n // IP address\r\n if (auditTrail.ipAddress) {\r\n keywords.push(`IP:${auditTrail.ipAddress}`);\r\n }\r\n \r\n // Geolocation data\r\n if (auditTrail.geolocation) {\r\n const { latitude, longitude, accuracy } = auditTrail.geolocation;\r\n const lat = latitude.toFixed(4);\r\n const lon = longitude.toFixed(4);\r\n keywords.push(`Location:${lat},${lon}`);\r\n \r\n // Add accuracy if available\r\n if (accuracy !== undefined) {\r\n keywords.push(`LocationAccuracy:${accuracy}m`);\r\n }\r\n }\r\n } catch (auditError) {\r\n logger.warn('⚠️ Error adding audit trail to keywords:', auditError)\r\n }\r\n }\r\n \r\n if (keywords.length > 0) {\r\n pdfDoc.setKeywords(keywords);\r\n }\r\n } catch (error) {\r\n logger.error('Failed to set document metadata:', error);\r\n }\r\n \r\n const finalPdfBytes = await pdfDoc.save();\r\n return finalPdfBytes;\r\n } catch (error) {\r\n logger.error('Error filling PDF with signatures:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Fill form fields and replace signature/initials with actual signature images\r\n * This is used when fields are rendered as overlays on the PDF\r\n * @param pdfBytes - The PDF bytes\r\n * @param formFields - The form fields with their positions\r\n * @param fieldValues - The field values to fill\r\n * @param signatures - The signature images (base64 data URLs)\r\n * @returns The filled PDF bytes\r\n */\r\nexport async function fillFormFieldsWithSignatures(\r\n pdfBytes: Uint8Array,\r\n formFields: EsignFormField[],\r\n fieldValues: Record<string, string>,\r\n signatures: Record<string, string>\r\n): Promise<Uint8Array> {\r\n try {\r\n const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const pages = pdfDoc.getPages();\r\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\r\n\r\n for (const field of formFields) {\r\n const pageIndex = field.position.page - 1;\r\n \r\n if (pageIndex < 0 || pageIndex >= pages.length) {\r\n continue;\r\n }\r\n\r\n const page = pages[pageIndex];\r\n if (!page) continue;\r\n const { height: pageHeight } = page.getSize();\r\n\r\n // Convert coordinates from top-left (UI) to bottom-left (PDF)\r\n const pdfX = field.position.x;\r\n const pdfY = pageHeight - field.position.y - field.position.height;\r\n\r\n try {\r\n switch (field.type) {\r\n case FormFieldType.TEXT: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n // Use field fontSize if specified, otherwise calculate based on field height\r\n const fontSize = field.fontSize && field.fontSize >= 8 && field.fontSize <= 72 \r\n ? field.fontSize \r\n : Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2, // Small padding\r\n y: pdfY + (field.position.height - fontSize) / 2, // Center vertically\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4, // Leave padding\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.DATE: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n const fontSize = field.fontSize && field.fontSize >= 8 && field.fontSize <= 72 \r\n ? field.fontSize \r\n : Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.CHECKBOX: {\r\n const value = fieldValues[field.id] || '';\r\n if (value === 'true') {\r\n // Draw a checkmark\r\n const checkSize = Math.min(field.position.width, field.position.height) * 0.6;\r\n const checkX = pdfX + (field.position.width - checkSize) / 2;\r\n const checkY = pdfY + (field.position.height - checkSize) / 2;\r\n \r\n page.drawText('✓', {\r\n x: checkX,\r\n y: checkY,\r\n size: checkSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.SIGNATURE: {\r\n const signatureDataUrl = signatures[field.id];\r\n if (signatureDataUrl) {\r\n // Convert base64 data URL to image bytes\r\n const base64Data = signatureDataUrl.split(',')[1];\r\n if (!base64Data) {\r\n logger.error('Invalid signature data URL format for field:', field.id);\r\n break;\r\n }\r\n const imageBytes = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0));\r\n \r\n // Embed the image\r\n const image = await pdfDoc.embedPng(imageBytes);\r\n \r\n // Calculate dimensions to fit within the field while maintaining aspect ratio\r\n const imageSize = image.size();\r\n const fieldAspectRatio = field.position.width / field.position.height;\r\n const imageAspectRatio = imageSize.width / imageSize.height;\r\n \r\n let drawWidth = field.position.width;\r\n let drawHeight = field.position.height;\r\n \r\n if (imageAspectRatio > fieldAspectRatio) {\r\n // Image is wider than field - fit to width\r\n drawHeight = drawWidth / imageAspectRatio;\r\n } else {\r\n // Image is taller than field - fit to height\r\n drawWidth = drawHeight * imageAspectRatio;\r\n }\r\n \r\n // Center the image within the field\r\n const imageX = pdfX + (field.position.width - drawWidth) / 2;\r\n const imageY = pdfY + (field.position.height - drawHeight) / 2;\r\n \r\n // Draw the image\r\n page.drawImage(image, {\r\n x: imageX,\r\n y: imageY,\r\n width: drawWidth,\r\n height: drawHeight,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.INITIALS: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n // Use a cursive font for initials\r\n const fontSize = Math.min(18, field.position.height * 0.8);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.DROPDOWN: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n const fontSize = Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n default:\r\n break;\r\n }\r\n } catch (fieldError) {\r\n logger.error(`Error processing field ${field.name}:`, fieldError);\r\n }\r\n }\r\n\r\n return await pdfDoc.save();\r\n} catch (error) {\r\n logger.error('Error filling form fields:', error);\r\n throw error;\r\n}\r\n}\r\n\r\n/**\r\n * Extract field positions and page numbers from a PDF document\r\n * Returns maps for field name -> page number and field name -> position\r\n */\r\nexport async function getFieldPageNumbers(\r\n pdfBytes: Uint8Array\r\n): Promise<{\r\n pageMap: Record<string, number>;\r\n positionMap: Record<string, FormFieldPosition>;\r\n}> {\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n const pages = pdfDoc.getPages();\r\n\r\n const pageMap: Record<string, number> = {};\r\n const positionMap: Record<string, FormFieldPosition> = {};\r\n\r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const fieldWithAcro = field as unknown as PDFFieldWithAcro;\r\n const widgets = fieldWithAcro.acroField?.getWidgets?.() ?? [];\r\n\r\n if (widgets.length > 0) {\r\n // Use the first widget to determine page and position\r\n const widget = widgets[0];\r\n if (!widget) continue;\r\n const rect = widget.getRectangle?.();\r\n const pageRef = widget.P?.();\r\n\r\n if (rect && pageRef) {\r\n // Find which page this widget belongs to\r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n\r\n if (pageIndex !== -1) {\r\n const pageNumber = pageIndex + 1; // Convert to 1-indexed\r\n pageMap[fieldName] = pageNumber;\r\n\r\n // Store position information\r\n positionMap[fieldName] = {\r\n x: rect.x,\r\n y: rect.y,\r\n width: rect.width,\r\n height: rect.height,\r\n page: pageNumber,\r\n };\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { pageMap, positionMap };\r\n} catch (error) {\r\n logger.error('Error extracting field page numbers:', error);\r\n return { pageMap: {}, positionMap: {} };\r\n}\r\n}\r\n\r\n","/**\r\n * PDF Form Field Extraction Utilities\r\n * Functions for extracting and decoding form fields from PDFs\r\n */\r\n\r\nimport { loadPdfLib } from './pdf-lib-loader';\r\nimport { EsignFormField, FormFieldType } from '../types';\r\nimport { logger } from './logger';\r\nimport type { PDFName as PDFNameType } from 'pdf-lib';\r\nimport { getSigniphiMetadata, initPdfMetadata, type FieldMetadata } from './pdf-metadata';\r\n\r\n// Module-level variable to hold PDFName after pdf-lib is loaded\r\nlet PDFName: typeof PDFNameType;\r\n\r\n// Type definitions for PDF field extensions\r\ninterface PDFFieldWithExtensions {\r\n acroField?: {\r\n getWidgets?: () => Array<{\r\n hasFlag?: (flag: number) => boolean;\r\n }>;\r\n dict?: {\r\n get: (key: unknown) => unknown;\r\n };\r\n };\r\n getOptions?: () => string[];\r\n isRequired?: () => boolean;\r\n constructor: { name: string };\r\n getName(): string;\r\n}\r\n\r\n/**\r\n * Extract visible form fields from a PDF document\r\n * @param pdfBytes - The PDF bytes to extract fields from\r\n * @param currentSignerEmail - Optional email of the current signer (for multi-signer filtering)\r\n * @returns Array of extracted form fields\r\n */\r\nexport async function extractVisibleFormFields(\r\n pdfBytes: Uint8Array,\r\n currentSignerEmail?: string\r\n): Promise<EsignFormField[]> {\r\n try {\r\n const pdfLibModule = await loadPdfLib();\r\n const { PDFDocument, AnnotationFlags, PDFName: PDFNameClass } = pdfLibModule;\r\n PDFName = PDFNameClass; // Assign to module-level variable for use in helper functions\r\n \r\n // Initialize pdf-metadata module with PDFName and PDFString\r\n initPdfMetadata(pdfLibModule);\r\n \r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n \r\n // Load metadata from PDF document information dictionary\r\n const metadata = getSigniphiMetadata(pdfDoc);\r\n \r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n const visibleFields: EsignFormField[] = [];\r\n let hasAnyInitialsFields = false; // For single-signer mode\r\n let hasInitialsFieldsForCurrentSigner = false; // For multi-signer mode\r\n \r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n \r\n // Get widgets for this field to check visibility\r\n const fieldWithExtensions = field as unknown as PDFFieldWithExtensions;\r\n const widgets = fieldWithExtensions.acroField?.getWidgets?.() ?? [];\r\n \r\n let isVisible = true;\r\n \r\n // Check if any widget is hidden using AnnotationFlags\r\n for (const widget of widgets) {\r\n const hasHiddenFlag = widget.hasFlag?.(AnnotationFlags.Hidden) ?? false;\r\n const hasNoViewFlag = widget.hasFlag?.(AnnotationFlags.NoView) ?? false;\r\n \r\n if (hasHiddenFlag || hasNoViewFlag) {\r\n isVisible = false;\r\n break;\r\n }\r\n }\r\n \r\n if (isVisible) {\r\n // Extract the clean field name (without suffixes) for metadata lookup\r\n const cleanFieldNameForMetadata = fieldName.replace(/_signature$|_initials$|_date$/i, '');\r\n\r\n // Get field metadata from PDF metadata or fall back to parsing field name (for old PDFs)\r\n // CRITICAL: Try both the suffixed name and the clean name for metadata lookup\r\n const fieldMetadata: FieldMetadata = metadata?.fields[fieldName]\r\n || metadata?.fields[cleanFieldNameForMetadata]\r\n || (() => {\r\n // Backward compatibility: decode from field name if no metadata exists\r\n const decoded = decodeFieldName(fieldName);\r\n return {\r\n label: decoded.displayLabel,\r\n signer: decoded.assignedSignerEmail,\r\n placeholder: decoded.fieldPlaceholder,\r\n acknowledgements: decoded.acknowledgements\r\n };\r\n })();\r\n \r\n // NOTE: We do NOT filter by signer during extraction in multi-signer mode!\r\n // All fields must be extracted so that:\r\n // 1. useFieldFiltering can properly filter fields for display\r\n // 2. Partial flattening knows about all fields (flatten current signer's fields only)\r\n // 3. PDF viewer filtering can remove non-visible fields from the rendered PDF\r\n // The filtering happens at the display level via useFieldFiltering hook.\r\n \r\n // Determine field type based on pdf-lib field type\r\n let fieldType = FormFieldType.TEXT;\r\n const fieldTypeName = field.constructor.name;\r\n \r\n // Extract the clean field name (without suffixes for type detection)\r\n const cleanFieldName = fieldName.replace(/_signature$|_initials$|_date$/i, '');\r\n \r\n // CRITICAL: Properly detect signature/initials fields (not checkboxes/radios)\r\n // More defensive than dockmaster - explicitly exclude CheckBox/Radio to prevent false positives\r\n const isActualSignatureField = fieldTypeName.includes('Signature') || \r\n (cleanFieldName.toLowerCase().includes('signature') && \r\n !fieldTypeName.includes('CheckBox') && \r\n !fieldTypeName.includes('Radio'));\r\n const isActualInitialsField = cleanFieldName.toLowerCase().includes('initials') &&\r\n !fieldTypeName.includes('CheckBox') && \r\n !fieldTypeName.includes('Radio');\r\n \r\n if (isActualSignatureField) {\r\n fieldType = FormFieldType.SIGNATURE;\r\n } else if (isActualInitialsField) {\r\n fieldType = FormFieldType.INITIALS;\r\n \r\n // Track initials fields for proper sidebar display logic:\r\n // - hasAnyInitialsFields: ANY initials exist (for single-signer fallback)\r\n // - hasInitialsFieldsForCurrentSigner: initials assigned to this signer (for multi-signer)\r\n hasAnyInitialsFields = true;\r\n \r\n // Check if this initials field is assigned to current signer\r\n if (currentSignerEmail && fieldMetadata.signer === currentSignerEmail) {\r\n hasInitialsFieldsForCurrentSigner = true;\r\n }\r\n } else if (cleanFieldName.toLowerCase().includes('date')) {\r\n fieldType = FormFieldType.DATE;\r\n } else if (fieldTypeName.includes('CheckBox')) {\r\n fieldType = FormFieldType.CHECKBOX;\r\n } else if (fieldTypeName.toLowerCase().includes('dropdown')) {\r\n fieldType = FormFieldType.DROPDOWN;\r\n } else if (fieldTypeName.includes('Radio')) {\r\n fieldType = FormFieldType.RADIO;\r\n }\r\n \r\n // Generate display label - Try TU metadata first, then metadata label, then fallback\r\n let displayLabel = fieldMetadata.label || '';\r\n \r\n // PRIORITY 1: Try to get label from TU (tooltip/user-visible) metadata\r\n if (!displayLabel || !displayLabel.trim()) {\r\n try {\r\n const tuLabel = extractTULabel(fieldWithExtensions);\r\n if (tuLabel && tuLabel.trim()) {\r\n displayLabel = tuLabel;\r\n }\r\n } catch (tuError) {\r\n }\r\n }\r\n \r\n // PRIORITY 2: Use label from metadata (already set above from fieldMetadata.label)\r\n \r\n // PRIORITY 3: Generate fallback label from field name\r\n if (!displayLabel || !displayLabel.trim()) {\r\n displayLabel = generateFallbackLabel(cleanFieldName, fieldType);\r\n }\r\n \r\n // Create EsignFormField\r\n const esignField: EsignFormField = {\r\n id: fieldName, // Keep original encoded name as ID\r\n fieldId: fieldMetadata.fieldId || fieldName, // Use fieldId from metadata, fallback to fieldName for backward compatibility\r\n name: fieldName, // Keep original for removal later\r\n type: fieldType,\r\n label: displayLabel, // Use friendly label for display\r\n position: { x: 0, y: 0, width: 100, height: 30, page: 1 }, // Default position\r\n required: fieldWithExtensions.isRequired?.() ?? false,\r\n placeholder: fieldMetadata.placeholder || '', // Use metadata placeholder\r\n assignedSignerEmail: fieldMetadata.signer, // Add assigned signer from metadata\r\n acknowledgements: fieldMetadata.acknowledgements, // Add acknowledgements from metadata\r\n };\r\n \r\n // Add options for dropdown and radio fields\r\n if (fieldType === FormFieldType.DROPDOWN || fieldType === FormFieldType.RADIO) {\r\n try {\r\n const options = fieldWithExtensions.getOptions?.() ?? [];\r\n esignField.options = options;\r\n if (options.length > 0) {\r\n }\r\n } catch (error) {\r\n logger.warn('Error extracting options for field:', error);\r\n }\r\n }\r\n \r\n visibleFields.push(esignField);\r\n }\r\n }\r\n \r\n // Add main signature and initials fields at the BEGINNING\r\n // Only create if PDF has these fields OR if explicitly required\r\n const mainFields: EsignFormField[] = [];\r\n \r\n // ALWAYS create signature field - it's attached to the document on submission regardless\r\n mainFields.push({\r\n id: 'signature_field_main',\r\n fieldId: 'signature_field_main', // Fixed ID for main signature field\r\n name: 'signature_field_main',\r\n type: FormFieldType.SIGNATURE,\r\n label: 'Your Signature (will be applied to all signature fields)',\r\n position: { x: 0, y: 0, width: 200, height: 60, page: 1 },\r\n required: true,\r\n placeholder: 'Draw or upload your signature',\r\n assignedSignerEmail: currentSignerEmail,\r\n });\r\n \r\n // Create initials field based on mode:\r\n // - Multi-signer mode (currentSignerEmail provided AND matches assigned fields):\r\n // Only create if current signer has initials fields assigned to them\r\n // - Single-signer mode (currentSignerEmail not provided OR doesn't match any assignments):\r\n // Create if ANY initials fields exist in the PDF\r\n // When present, always make it required\r\n const shouldCreateInitialsField = hasInitialsFieldsForCurrentSigner || \r\n (hasAnyInitialsFields && !currentSignerEmail);\r\n \r\n if (shouldCreateInitialsField) {\r\n if (hasInitialsFieldsForCurrentSigner) {\r\n } else {\r\n }\r\n \r\n mainFields.push({\r\n id: 'initials_field_main',\r\n fieldId: 'initials_field_main', // Fixed ID for main initials field\r\n name: 'initials_field_main',\r\n type: FormFieldType.INITIALS,\r\n label: 'Your Initials (will be applied to all initials fields)',\r\n position: { x: 0, y: 0, width: 100, height: 40, page: 1 },\r\n required: true,\r\n placeholder: 'Enter your initials',\r\n assignedSignerEmail: currentSignerEmail,\r\n });\r\n }\r\n \r\n // Return main fields FIRST, then other fields\r\n return [...mainFields, ...visibleFields];\r\n } catch (error) {\r\n logger.error('Error extracting visible form fields from PDF:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Decode a field name to extract label, signer email, and placeholder\r\n * Format: fieldName__LABEL__labelText__SIGNER__email__PLACEHOLDER__placeholderText\r\n * \r\n * @deprecated This function is deprecated and kept only for backward compatibility with old PDFs.\r\n * New PDFs store metadata in the PDF's document information dictionary instead of encoding it in field names.\r\n * Use getSigniphiMetadata() for new PDFs.\r\n */\r\nexport function decodeFieldName(fieldName: string): {\r\n decodedFieldName: string;\r\n displayLabel: string;\r\n assignedSignerEmail?: string;\r\n fieldPlaceholder: string;\r\n acknowledgements?: Array<{id: string; title: string; description: string}>;\r\n} {\r\n let decodedFieldName = fieldName;\r\n let displayLabel = '';\r\n let assignedSignerEmail: string | undefined = undefined;\r\n let fieldPlaceholder = '';\r\n let acknowledgements: Array<{id: string; title: string; description: string}> | undefined = undefined;\r\n \r\n // Extract acknowledgements if present (must be last)\r\n if (fieldName.includes('__ACK__')) {\r\n const ackMarkerIndex = fieldName.indexOf('__ACK__');\r\n const beforeAck = fieldName.substring(0, ackMarkerIndex);\r\n const ackEncoded = fieldName.substring(ackMarkerIndex + 7); // Skip \"__ACK__\"\r\n \r\n try {\r\n // Decode base64 and parse JSON\r\n const ackData = atob(ackEncoded);\r\n acknowledgements = JSON.parse(ackData);\r\n } catch (e) {\r\n console.warn('Failed to decode acknowledgements:', e);\r\n }\r\n \r\n // Continue processing the rest of the field name\r\n fieldName = beforeAck;\r\n decodedFieldName = fieldName;\r\n }\r\n \r\n // Extract label if present\r\n if (fieldName.includes('__LABEL__')) {\r\n const labelMarkerIndex = fieldName.indexOf('__LABEL__');\r\n decodedFieldName = fieldName.substring(0, labelMarkerIndex);\r\n \r\n const afterLabel = fieldName.substring(labelMarkerIndex + 9); // Skip \"__LABEL__\"\r\n \r\n // Extract signer email if present\r\n if (afterLabel.includes('__SIGNER__')) {\r\n const signerMarkerIndex = afterLabel.indexOf('__SIGNER__');\r\n displayLabel = afterLabel.substring(0, signerMarkerIndex);\r\n const afterSigner = afterLabel.substring(signerMarkerIndex + 10); // Skip \"__SIGNER__\"\r\n \r\n // Extract placeholder if present\r\n if (afterSigner.includes('__PLACEHOLDER__')) {\r\n const placeholderMarkerIndex = afterSigner.indexOf('__PLACEHOLDER__');\r\n assignedSignerEmail = afterSigner.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterSigner.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n assignedSignerEmail = afterSigner;\r\n }\r\n } else if (afterLabel.includes('__PLACEHOLDER__')) {\r\n // Label and placeholder but no signer\r\n const placeholderMarkerIndex = afterLabel.indexOf('__PLACEHOLDER__');\r\n displayLabel = afterLabel.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterLabel.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n displayLabel = afterLabel;\r\n }\r\n } else if (fieldName.includes('__SIGNER__')) {\r\n // Old format without label\r\n const signerMarkerIndex = fieldName.indexOf('__SIGNER__');\r\n decodedFieldName = fieldName.substring(0, signerMarkerIndex);\r\n const afterSigner = fieldName.substring(signerMarkerIndex + 10); // Skip \"__SIGNER__\"\r\n \r\n // Extract placeholder if present\r\n if (afterSigner.includes('__PLACEHOLDER__')) {\r\n const placeholderMarkerIndex = afterSigner.indexOf('__PLACEHOLDER__');\r\n assignedSignerEmail = afterSigner.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterSigner.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n assignedSignerEmail = afterSigner;\r\n }\r\n } else if (fieldName.includes('__PLACEHOLDER__')) {\r\n // Only placeholder present\r\n const placeholderMarkerIndex = fieldName.indexOf('__PLACEHOLDER__');\r\n decodedFieldName = fieldName.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = fieldName.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n }\r\n \r\n return {\r\n decodedFieldName,\r\n displayLabel,\r\n assignedSignerEmail,\r\n fieldPlaceholder,\r\n acknowledgements\r\n };\r\n}\r\n\r\n/**\r\n * Generate a fallback label from a decoded field name\r\n */\r\nexport function generateFallbackLabel(decodedFieldName: string, fieldType: FormFieldType): string {\r\n let displayLabel = decodedFieldName;\r\n \r\n // Remove \"_signature\", \"_initials\", \"_date\" suffixes added by pdf-lib\r\n displayLabel = displayLabel.replace(/_signature$/i, '').replace(/_initials$/i, '').replace(/_date$/i, '');\r\n \r\n // Handle different naming patterns:\r\n // 1. Pure timestamp fields: \"text_1234567890\" → \"Text\"\r\n // 2. Descriptive fields: \"text_Primary_1\" → \"Text Primary\"\r\n // 3. Custom fields: \"customer_name\" → \"Customer Name\"\r\n \r\n if (/^(text|signature|initials|date)_\\d+$/i.test(displayLabel)) {\r\n // Pattern 1: Pure timestamp fields\r\n if (fieldType === FormFieldType.SIGNATURE) return 'Signature';\r\n if (fieldType === FormFieldType.INITIALS) return 'Initials';\r\n if (fieldType === FormFieldType.DATE) return 'Date';\r\n if (fieldType === FormFieldType.TEXT) return 'Text';\r\n if (fieldType === FormFieldType.CHECKBOX) return 'Checkbox';\r\n if (fieldType === FormFieldType.DROPDOWN) return 'Dropdown';\r\n if (fieldType === FormFieldType.RADIO) return 'Option';\r\n } else {\r\n // Pattern 2 & 3: Convert underscores to spaces, remove trailing numbers, capitalize\r\n displayLabel = displayLabel\r\n .replace(/_/g, ' ') // Convert underscores to spaces\r\n .replace(/\\s+\\d+$/g, '') // Remove trailing numbers (e.g., \" 1\")\r\n .trim()\r\n .split(' ') // Split into words\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize each word\r\n .join(' ');\r\n }\r\n \r\n return displayLabel;\r\n}\r\n\r\n/**\r\n * Extract label from TU (tooltip) metadata in PDF field\r\n * @param field - The PDF field with extensions\r\n * @returns The extracted label or empty string\r\n */\r\nfunction extractTULabel(field: PDFFieldWithExtensions): string {\r\n try {\r\n if (!field.acroField?.dict) {\r\n return '';\r\n }\r\n \r\n const tuLabel = field.acroField.dict.get(PDFName.of('TU'));\r\n if (!tuLabel) {\r\n return '';\r\n }\r\n \r\n // PDFString has a decodeText() method or toString()\r\n const tuValue = tuLabel.toString();\r\n if (!tuValue || !tuValue.trim()) {\r\n return '';\r\n }\r\n \r\n // Handle PDF string encoding - extract content between parentheses or angle brackets\r\n // PDF strings are encoded as \"(text)\" or \"<hex>\"\r\n if (tuValue.startsWith('(') || tuValue.startsWith('<')) {\r\n const match = tuValue.match(/^\\((.*)\\)$/) || tuValue.match(/^<(.*)>$/);\r\n if (match && match[1]) {\r\n return match[1];\r\n }\r\n }\r\n \r\n // If no special encoding, return as-is\r\n return tuValue;\r\n } catch (error) {\r\n return '';\r\n }\r\n}\r\n\r\n","/**\r\n * PDF.js Configuration Provider\r\n * Manages global configuration for PDF.js worker and viewer paths\r\n * \r\n * COMPATIBILITY NOTE: This module is designed to work with both Vite and Next.js/webpack.\r\n * The worker source URL is computed lazily to avoid issues with webpack's handling of import.meta.\r\n */\r\n\r\nimport type { PdfJsConfig } from '../types';\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\n\r\n/**\r\n * CDN paths for PDF.js (exported for manual fallback configuration)\r\n * Note: CDN URLs may cause CORS issues in some environments\r\n * \r\n * @example\r\n * // Manually configure CDN (not recommended)\r\n * setPdfJsConfig({ \r\n * viewerBasePath: CDN_VIEWER,\r\n * workerSrc: CDN_WORKER \r\n * });\r\n */\r\nexport const CDN_WORKER = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@5.3.93/build/pdf.worker.mjs';\r\nexport const CDN_VIEWER = 'https://mozilla.github.io/pdf.js';\r\n\r\n/**\r\n * Internal flag to track if worker source has been computed\r\n */\r\nlet _workerSrcComputed = false;\r\nlet _cachedWorkerSrc: string | null = null;\r\n\r\n/**\r\n * Get the worker source URL (computed lazily to avoid webpack import.meta issues)\r\n * - In browser environments, the bundler resolves the URL from node_modules\r\n * - The worker is loaded from the user's bundle (no CORS issues)\r\n * \r\n * This function uses lazy evaluation to avoid triggering webpack's\r\n * \"Critical dependency: Accessing import.meta directly is unsupported\" warning\r\n * at module load time.\r\n */\r\nfunction getDefaultWorkerSrc(): string {\r\n // Return cached value if already computed\r\n if (_workerSrcComputed && _cachedWorkerSrc !== null) {\r\n return _cachedWorkerSrc;\r\n }\r\n\r\n // Default fallback\r\n let workerSrc = '/pdfjs/build/pdf.worker.mjs';\r\n\r\n // Only attempt import.meta resolution in browser environment\r\n if (typeof window !== 'undefined' && typeof URL !== 'undefined') {\r\n try {\r\n // Check if import.meta is available (ESM environment like Vite)\r\n // Use indirect access to avoid webpack static analysis issues\r\n const meta = (function() {\r\n try {\r\n // This pattern avoids webpack's direct import.meta detection\r\n return new Function('return import.meta')();\r\n } catch {\r\n return null;\r\n }\r\n })();\r\n\r\n if (meta && meta.url) {\r\n workerSrc = new URL('pdfjs-dist/build/pdf.worker.mjs', meta.url).href;\r\n }\r\n } catch {\r\n // Fallback for environments that don't support import.meta.url (Next.js/webpack)\r\n // Use the public path fallback\r\n }\r\n }\r\n\r\n // Cache the result\r\n _workerSrcComputed = true;\r\n _cachedWorkerSrc = workerSrc;\r\n\r\n return workerSrc;\r\n}\r\n\r\n/**\r\n * Default configuration for PDF.js\r\n * \r\n * By default, the package uses:\r\n * - Worker: Loaded from node_modules (bundled by your build tool)\r\n * - Viewer: Served from /pdfjs/ (automatically copied by postinstall)\r\n * \r\n * The postinstall script automatically copies viewer files to your public/pdfjs/ directory.\r\n * If setup fails, run: npx signiphi-setup\r\n * \r\n * NOTE: workerSrc is initialized to null and computed lazily on first access\r\n * to ensure compatibility with Next.js/webpack environments.\r\n */\r\nlet globalConfig: Required<PdfJsConfig> = {\r\n viewerBasePath: '/pdfjs',\r\n workerSrc: '', // Lazy-initialized below\r\n};\r\n\r\n// Flag to track if globalConfig.workerSrc has been initialized\r\nlet _configInitialized = false;\r\n\r\n/**\r\n * Ensure config is initialized (called lazily)\r\n */\r\nfunction ensureConfigInitialized(): void {\r\n if (!_configInitialized) {\r\n globalConfig.workerSrc = getDefaultWorkerSrc();\r\n _configInitialized = true;\r\n \r\n // Initialize PDF.js worker in browser environment\r\n if (typeof window !== 'undefined') {\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = globalConfig.workerSrc;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Set PDF.js configuration\r\n * @param config - Partial configuration to merge with defaults\r\n * \r\n * @example\r\n * // Use self-hosted PDF.js files\r\n * setPdfJsConfig({ viewerBasePath: '/pdfjs' });\r\n * \r\n * @example\r\n * // Use custom CDN\r\n * setPdfJsConfig({ \r\n * viewerBasePath: 'https://my-cdn.com/pdfjs',\r\n * workerSrc: 'https://my-cdn.com/pdfjs/build/pdf.worker.mjs'\r\n * });\r\n */\r\nexport function setPdfJsConfig(config: Partial<PdfJsConfig>): void {\r\n // Ensure default config is computed first\r\n ensureConfigInitialized();\r\n \r\n if (config.viewerBasePath !== undefined) {\r\n globalConfig.viewerBasePath = config.viewerBasePath;\r\n }\r\n \r\n if (config.workerSrc !== undefined) {\r\n globalConfig.workerSrc = config.workerSrc;\r\n } else if (config.viewerBasePath !== undefined) {\r\n // Auto-update workerSrc based on viewerBasePath\r\n globalConfig.workerSrc = `${config.viewerBasePath}/build/pdf.worker.mjs`;\r\n }\r\n\r\n // Update PDF.js worker if in browser environment\r\n if (typeof window !== 'undefined') {\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = globalConfig.workerSrc;\r\n }\r\n}\r\n\r\n/**\r\n * Get current PDF.js configuration\r\n * @returns Current configuration\r\n */\r\nexport function getPdfJsConfig(): Required<PdfJsConfig> {\r\n // Ensure config is initialized before returning\r\n ensureConfigInitialized();\r\n return { ...globalConfig };\r\n}\r\n\r\n/**\r\n * Reset configuration to defaults (local files)\r\n */\r\nexport function resetPdfJsConfig(): void {\r\n // Clear cached worker src to force recomputation\r\n _workerSrcComputed = false;\r\n _cachedWorkerSrc = null;\r\n _configInitialized = false;\r\n \r\n // Re-initialize with fresh defaults\r\n ensureConfigInitialized();\r\n}\r\n\r\n/**\r\n * Initialize PDF.js configuration\r\n * This is called automatically when the first PDF operation is attempted,\r\n * but can also be called manually to pre-initialize the configuration.\r\n * \r\n * Unlike previous versions, this does NOT run at module load time to\r\n * ensure compatibility with Next.js/webpack environments.\r\n */\r\nexport function initializePdfJs(): void {\r\n ensureConfigInitialized();\r\n}\r\n\r\n","/**\r\n * PDF.js Version Check Utility\r\n * Detects version mismatches between viewer and worker\r\n */\r\n\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\n\r\nexport interface PdfJsVersionCheckResult {\r\n viewerExists: boolean;\r\n versionMatch: boolean;\r\n viewerVersion?: string;\r\n workerVersion: string;\r\n errorMessage?: string;\r\n}\r\n\r\n/**\r\n * Check if PDF.js viewer files exist and versions match\r\n * @param viewerBasePath - Base path for the viewer (e.g., '/pdfjs')\r\n * @returns Version check result\r\n */\r\nexport async function checkPdfJsVersion(\r\n viewerBasePath: string = '/pdfjs'\r\n): Promise<PdfJsVersionCheckResult> {\r\n const workerVersion = pdfjsLib.version;\r\n \r\n try {\r\n // Check if .version file exists\r\n const versionUrl = `${viewerBasePath}/.version`;\r\n const response = await fetch(versionUrl);\r\n \r\n if (!response.ok) {\r\n return {\r\n viewerExists: false,\r\n versionMatch: false,\r\n workerVersion,\r\n errorMessage: 'PDF.js viewer files not found. Run: npx signiphi-setup',\r\n };\r\n }\r\n \r\n const viewerVersion = (await response.text()).trim();\r\n const versionMatch = viewerVersion === workerVersion;\r\n \r\n if (!versionMatch) {\r\n return {\r\n viewerExists: true,\r\n versionMatch: false,\r\n viewerVersion,\r\n workerVersion,\r\n errorMessage: `Version mismatch: viewer=${viewerVersion}, worker=${workerVersion}. Run: npx signiphi-setup`,\r\n };\r\n }\r\n \r\n return {\r\n viewerExists: true,\r\n versionMatch: true,\r\n viewerVersion,\r\n workerVersion,\r\n };\r\n } catch (error) {\r\n return {\r\n viewerExists: false,\r\n versionMatch: false,\r\n workerVersion,\r\n errorMessage: 'Unable to check PDF.js version. Viewer files may not be installed.',\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Log version check warnings to console\r\n * @param result - Version check result\r\n */\r\nexport function logVersionCheckWarning(result: PdfJsVersionCheckResult): void {\r\n if (!result.viewerExists) {\r\n console.warn(\r\n '⚠️ PDF.js viewer files not found.\\n' +\r\n 'The PDF viewer requires viewer files to be installed.\\n' +\r\n 'Run: npx signiphi-setup\\n' +\r\n 'Or reinstall the package: npm install @signiphi/pdf-signer'\r\n );\r\n } else if (!result.versionMatch) {\r\n console.warn(\r\n `⚠️ PDF.js version mismatch detected:\\n` +\r\n ` Viewer: ${result.viewerVersion}\\n` +\r\n ` Worker: ${result.workerVersion}\\n` +\r\n 'Run: npx signiphi-setup to sync versions'\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Check version and log warnings automatically\r\n * @param viewerBasePath - Base path for the viewer\r\n */\r\nexport async function checkAndLogPdfJsVersion(\r\n viewerBasePath: string = '/pdfjs'\r\n): Promise<PdfJsVersionCheckResult> {\r\n const result = await checkPdfJsVersion(viewerBasePath);\r\n \r\n if (!result.viewerExists || !result.versionMatch) {\r\n logVersionCheckWarning(result);\r\n }\r\n \r\n return result;\r\n}\r\n\r\n","/**\r\n * Audit Trail Utilities\r\n * Captures device metadata, IP address, and geolocation for compliance and forensics\r\n */\r\n\r\nimport type { AuditTrailMetadata } from '../types';\r\nimport { logger } from './logger';\r\n\r\n/**\r\n * Synchronously capture device and browser metadata\r\n */\r\nexport function captureDeviceMetadata(): Partial<AuditTrailMetadata> {\r\n const metadata: Partial<AuditTrailMetadata> = {};\r\n\r\n try {\r\n // User agent (truncated to 100 chars)\r\n if (navigator.userAgent) {\r\n metadata.userAgent = navigator.userAgent.substring(0, 100);\r\n }\r\n\r\n // Screen resolution\r\n if (screen.width && screen.height) {\r\n metadata.screenResolution = `${screen.width}x${screen.height}`;\r\n }\r\n\r\n // Timezone\r\n try {\r\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n if (timezone) {\r\n metadata.timezone = timezone;\r\n }\r\n } catch {\r\n // Timezone unavailable\r\n }\r\n\r\n // Language\r\n if (navigator.language) {\r\n metadata.language = navigator.language;\r\n }\r\n\r\n // Platform\r\n if (navigator.platform) {\r\n metadata.platform = navigator.platform;\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing device metadata:', error);\r\n }\r\n\r\n return metadata;\r\n}\r\n\r\n/**\r\n * Capture IP address using public API\r\n */\r\nexport async function captureIpAddress(): Promise<string> {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout\r\n\r\n const ipResponse = await fetch('https://api.ipify.org?format=json', {\r\n method: 'GET',\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (ipResponse.ok) {\r\n const ipData = await ipResponse.json();\r\n if (ipData.ip) {\r\n return ipData.ip;\r\n }\r\n }\r\n\r\n return 'Unknown';\r\n } catch (error) {\r\n return 'Unknown';\r\n }\r\n}\r\n\r\n/**\r\n * Capture geolocation using browser geolocation API\r\n */\r\nexport async function captureGeolocation(): Promise<{\r\n latitude: number;\r\n longitude: number;\r\n accuracy?: number;\r\n} | null> {\r\n if (!navigator.geolocation) {\r\n return null;\r\n }\r\n\r\n try {\r\n const position = await new Promise<GeolocationPosition>((resolve, reject) => {\r\n navigator.geolocation.getCurrentPosition(resolve, reject, {\r\n timeout: 10000, // 10 second timeout\r\n enableHighAccuracy: false,\r\n maximumAge: 300000, // 5 minutes cache\r\n });\r\n });\r\n\r\n if (position.coords) {\r\n const latitude = parseFloat(position.coords.latitude.toFixed(4));\r\n const longitude = parseFloat(position.coords.longitude.toFixed(4));\r\n const accuracy = position.coords.accuracy\r\n ? Math.round(position.coords.accuracy)\r\n : undefined;\r\n\r\n\r\n return {\r\n latitude,\r\n longitude,\r\n accuracy,\r\n };\r\n }\r\n\r\n return null;\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Capture complete audit trail metadata\r\n * Combines device metadata, IP address, and geolocation\r\n */\r\nexport async function captureAuditTrail(): Promise<AuditTrailMetadata> {\r\n\r\n const auditTrail: AuditTrailMetadata = {};\r\n\r\n try {\r\n // Capture device metadata (synchronous)\r\n const deviceMetadata = captureDeviceMetadata();\r\n Object.assign(auditTrail, deviceMetadata);\r\n\r\n // Capture IP address (async, with timeout)\r\n try {\r\n const ipAddress = await captureIpAddress();\r\n auditTrail.ipAddress = ipAddress;\r\n } catch (error) {\r\n logger.warn('Error capturing IP address:', error);\r\n auditTrail.ipAddress = 'Unknown';\r\n }\r\n\r\n // Capture geolocation (async, requires permission)\r\n try {\r\n const geolocation = await captureGeolocation();\r\n if (geolocation) {\r\n auditTrail.geolocation = geolocation;\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing geolocation:', error);\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing audit trail:', error);\r\n }\r\n\r\n return auditTrail;\r\n}\r\n\r\n","/**\r\n * Custom Error Classes\r\n * Domain-specific error types for better error handling and debugging\r\n */\r\n\r\n/**\r\n * Error thrown when PDF validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * const validation = validatePdfBytes(bytes);\r\n * if (!validation.valid) {\r\n * throw new PdfValidationError(validation.error || 'Invalid PDF');\r\n * }\r\n * ```\r\n */\r\nexport class PdfValidationError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'PdfValidationError';\r\n // Maintains proper stack trace for where error was thrown (V8 only)\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, PdfValidationError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown during PDF processing operations\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * const pdfDoc = await PDFDocument.load(bytes);\r\n * } catch (err) {\r\n * throw new PdfProcessingError('Failed to load PDF document', err);\r\n * }\r\n * ```\r\n */\r\nexport class PdfProcessingError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'PdfProcessingError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, PdfProcessingError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown for form field related issues\r\n * \r\n * @example\r\n * ```ts\r\n * if (!field.value && field.required) {\r\n * throw new FormFieldError(\r\n * 'Required field is empty',\r\n * field.name\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport class FormFieldError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly fieldName?: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'FormFieldError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, FormFieldError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown for attachment validation failures\r\n * \r\n * @example\r\n * ```ts\r\n * if (file.size > maxFileSize) {\r\n * throw new AttachmentValidationError(\r\n * `File size exceeds limit: ${file.name}`,\r\n * file.name\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport class AttachmentValidationError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly fileName?: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'AttachmentValidationError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, AttachmentValidationError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a PdfValidationError\r\n */\r\nexport function isPdfValidationError(error: unknown): error is PdfValidationError {\r\n return error instanceof PdfValidationError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a PdfProcessingError\r\n */\r\nexport function isPdfProcessingError(error: unknown): error is PdfProcessingError {\r\n return error instanceof PdfProcessingError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a FormFieldError\r\n */\r\nexport function isFormFieldError(error: unknown): error is FormFieldError {\r\n return error instanceof FormFieldError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is an AttachmentValidationError\r\n */\r\nexport function isAttachmentValidationError(error: unknown): error is AttachmentValidationError {\r\n return error instanceof AttachmentValidationError;\r\n}\r\n\r\n/**\r\n * Extract error message from unknown error type\r\n * \r\n * @param error - The error to extract message from\r\n * @param defaultMessage - Default message if extraction fails\r\n * @returns Error message string\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * // ... operation\r\n * } catch (err) {\r\n * const message = getErrorMessage(err, 'Operation failed');\r\n * logger.error(message);\r\n * }\r\n * ```\r\n */\r\nexport function getErrorMessage(error: unknown, defaultMessage = 'Unknown error'): string {\r\n if (error instanceof Error) {\r\n return error.message;\r\n }\r\n if (typeof error === 'string') {\r\n return error;\r\n }\r\n return defaultMessage;\r\n}\r\n\r\n","/**\r\n * Attachment Validation Utilities\r\n * Validation functions for file attachments\r\n */\r\n\r\nimport type { AttachmentConstraints, Attachment } from '../types';\r\nimport { AttachmentValidationError } from './errors';\r\n\r\n/**\r\n * Default attachment constraints\r\n */\r\nexport const DEFAULT_ATTACHMENT_CONSTRAINTS: AttachmentConstraints = {\r\n maxFileSize: 10 * 1024 * 1024, // 10MB\r\n maxTotalSize: 50 * 1024 * 1024, // 50MB\r\n maxFiles: 10,\r\n allowedTypes: ['image/*', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],\r\n allowedExtensions: ['.pdf', '.jpg', '.jpeg', '.png', '.gif', '.doc', '.docx'],\r\n};\r\n\r\n/**\r\n * Validate a single file against constraints\r\n * \r\n * @param file - File to validate\r\n * @param constraints - Validation constraints\r\n * @returns Validation result with errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFile(file, DEFAULT_ATTACHMENT_CONSTRAINTS);\r\n * if (result.errors.length > 0) {\r\n * console.error('File validation failed:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFile(\r\n file: File,\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n\r\n // Validate file size\r\n if (file.size > constraints.maxFileSize) {\r\n const maxMB = (constraints.maxFileSize / 1024 / 1024).toFixed(1);\r\n const fileMB = (file.size / 1024 / 1024).toFixed(1);\r\n errors.push(`File \"${file.name}\" is too large (${fileMB}MB). Maximum size is ${maxMB}MB.`);\r\n }\r\n\r\n // Validate file type (MIME type)\r\n const isTypeAllowed = constraints.allowedTypes.some((allowedType) => {\r\n if (allowedType.endsWith('/*')) {\r\n // Wildcard type (e.g., 'image/*')\r\n const prefix = allowedType.slice(0, -2);\r\n return file.type.startsWith(prefix);\r\n }\r\n return file.type === allowedType;\r\n });\r\n\r\n if (!isTypeAllowed && constraints.allowedTypes.length > 0) {\r\n errors.push(\r\n `File type \"${file.type}\" is not allowed for \"${file.name}\". Allowed types: ${constraints.allowedTypes.join(', ')}`\r\n );\r\n }\r\n\r\n // Validate file extension\r\n if (constraints.allowedExtensions && constraints.allowedExtensions.length > 0) {\r\n const fileExt = '.' + file.name.split('.').pop()?.toLowerCase();\r\n const isExtAllowed = constraints.allowedExtensions.some(\r\n (ext) => ext.toLowerCase() === fileExt\r\n );\r\n\r\n if (!isExtAllowed) {\r\n errors.push(\r\n `File extension \"${fileExt}\" is not allowed for \"${file.name}\". Allowed extensions: ${constraints.allowedExtensions.join(', ')}`\r\n );\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate multiple files against constraints\r\n * \r\n * @param files - Files to validate\r\n * @param existingAttachments - Existing attachments to consider for total size/count\r\n * @param constraints - Validation constraints\r\n * @returns Validation result with errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFiles(newFiles, existingAttachments, DEFAULT_ATTACHMENT_CONSTRAINTS);\r\n * if (result.errors.length > 0) {\r\n * alert('Some files cannot be uploaded: ' + result.errors.join(', '));\r\n * }\r\n * ```\r\n */\r\nexport function validateFiles(\r\n files: File[],\r\n existingAttachments: Attachment[] = [],\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n\r\n // Validate total number of files\r\n const totalFiles = files.length + existingAttachments.length;\r\n if (totalFiles > constraints.maxFiles) {\r\n errors.push(\r\n `Too many files. Maximum allowed is ${constraints.maxFiles}, you have ${totalFiles} files total.`\r\n );\r\n }\r\n\r\n // Validate total size\r\n const existingSize = existingAttachments.reduce((sum, att) => sum + att.size, 0);\r\n const newFilesSize = files.reduce((sum, file) => sum + file.size, 0);\r\n const totalSize = existingSize + newFilesSize;\r\n\r\n if (totalSize > constraints.maxTotalSize) {\r\n const maxMB = (constraints.maxTotalSize / 1024 / 1024).toFixed(1);\r\n const totalMB = (totalSize / 1024 / 1024).toFixed(1);\r\n errors.push(\r\n `Total size of all files is too large (${totalMB}MB). Maximum total size is ${maxMB}MB.`\r\n );\r\n }\r\n\r\n // Validate each individual file\r\n for (const file of files) {\r\n const fileResult = validateFile(file, constraints);\r\n errors.push(...fileResult.errors);\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate file and throw error if invalid\r\n * \r\n * Convenience function that throws AttachmentValidationError if validation fails.\r\n * \r\n * @param file - File to validate\r\n * @param constraints - Validation constraints\r\n * @throws {AttachmentValidationError} If validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * validateFileOrThrow(file);\r\n * // File is valid, proceed with upload\r\n * } catch (err) {\r\n * if (err instanceof AttachmentValidationError) {\r\n * alert(err.message);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function validateFileOrThrow(\r\n file: File,\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): void {\r\n const result = validateFile(file, constraints);\r\n if (!result.valid) {\r\n throw new AttachmentValidationError(\r\n `File validation failed: ${result.errors.join('; ')}`,\r\n file.name,\r\n { file, errors: result.errors }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Validate multiple files and throw error if invalid\r\n * \r\n * @param files - Files to validate\r\n * @param existingAttachments - Existing attachments\r\n * @param constraints - Validation constraints\r\n * @throws {AttachmentValidationError} If validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * validateFilesOrThrow(selectedFiles, currentAttachments);\r\n * // All files are valid\r\n * } catch (err) {\r\n * if (err instanceof AttachmentValidationError) {\r\n * alert(err.message);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function validateFilesOrThrow(\r\n files: File[],\r\n existingAttachments: Attachment[] = [],\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): void {\r\n const result = validateFiles(files, existingAttachments, constraints);\r\n if (!result.valid) {\r\n throw new AttachmentValidationError(\r\n `File validation failed: ${result.errors.join('; ')}`,\r\n undefined,\r\n { files, errors: result.errors }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Check if a file type is an image\r\n * \r\n * @param fileType - MIME type of the file\r\n * @returns true if the file is an image\r\n * \r\n * @example\r\n * ```ts\r\n * if (isImageType(file.type)) {\r\n * // Generate preview\r\n * }\r\n * ```\r\n */\r\nexport function isImageType(fileType: string): boolean {\r\n return fileType.startsWith('image/');\r\n}\r\n\r\n/**\r\n * Format file size for display\r\n * \r\n * @param bytes - File size in bytes\r\n * @returns Formatted size string (e.g., \"1.5 MB\")\r\n * \r\n * @example\r\n * ```ts\r\n * const sizeDisplay = formatFileSize(file.size); // \"1.5 MB\"\r\n * ```\r\n */\r\nexport function formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 Bytes';\r\n \r\n const k = 1024;\r\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n \r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n}\r\n\r\n","/**\r\n * Performance Monitoring Utility\r\n * \r\n * Provides utilities for tracking and measuring performance metrics\r\n * in critical operations like PDF loading, form filling, and signature capture.\r\n * \r\n * Usage:\r\n * ```typescript\r\n * const monitor = createPerformanceMonitor();\r\n * const endTimer = monitor.startTimer('pdf-load');\r\n * await loadPdf(url);\r\n * endTimer();\r\n * const metrics = monitor.getMetrics();\r\n * ```\r\n */\r\n\r\nimport { logger } from './logger';\r\n\r\nexport interface PerformanceMetric {\r\n label: string;\r\n duration: number;\r\n timestamp: number;\r\n}\r\n\r\nexport interface PerformanceMetrics {\r\n [label: string]: {\r\n count: number;\r\n total: number;\r\n avg: number;\r\n min: number;\r\n max: number;\r\n last: number;\r\n };\r\n}\r\n\r\n/**\r\n * Performance Monitor Class\r\n * \r\n * Tracks performance metrics for various operations.\r\n * Maintains history and calculates statistics (avg, min, max).\r\n */\r\nexport class PerformanceMonitor {\r\n private metrics: Map<string, number[]> = new Map();\r\n private enabled: boolean;\r\n\r\n constructor(enabled: boolean = true) {\r\n this.enabled = enabled;\r\n }\r\n\r\n /**\r\n * Start a timer for a labeled operation\r\n * \r\n * @param label - Unique label for the operation\r\n * @returns Function to call when operation completes\r\n * \r\n * @example\r\n * ```typescript\r\n * const endTimer = monitor.startTimer('pdf-load');\r\n * await loadPdf(url);\r\n * endTimer(); // Records duration\r\n * ```\r\n */\r\n startTimer(label: string): () => void {\r\n if (!this.enabled) {\r\n return () => {}; // No-op if disabled\r\n }\r\n\r\n const startTime = performance.now();\r\n\r\n return () => {\r\n const duration = performance.now() - startTime;\r\n this.measure(label, duration);\r\n };\r\n }\r\n\r\n /**\r\n * Manually record a performance measurement\r\n * \r\n * @param label - Unique label for the operation\r\n * @param duration - Duration in milliseconds\r\n * \r\n * @example\r\n * ```typescript\r\n * monitor.measure('pdf-load', 1234.56);\r\n * ```\r\n */\r\n measure(label: string, duration: number): void {\r\n if (!this.enabled) {\r\n return;\r\n }\r\n\r\n const measurements = this.metrics.get(label) || [];\r\n measurements.push(duration);\r\n this.metrics.set(label, measurements);\r\n\r\n logger.info(`[Performance] ${label}: ${duration.toFixed(2)}ms`);\r\n }\r\n\r\n /**\r\n * Get all recorded metrics with statistics\r\n * \r\n * @returns Object containing metrics for all labels\r\n * \r\n * @example\r\n * ```typescript\r\n * const metrics = monitor.getMetrics();\r\n * console.log(`PDF load avg: ${metrics['pdf-load'].avg}ms`);\r\n * ```\r\n */\r\n getMetrics(): PerformanceMetrics {\r\n const result: PerformanceMetrics = {};\r\n\r\n for (const [label, measurements] of this.metrics.entries()) {\r\n if (measurements.length === 0) continue;\r\n\r\n const total = measurements.reduce((sum, val) => sum + val, 0);\r\n const avg = total / measurements.length;\r\n const min = Math.min(...measurements);\r\n const max = Math.max(...measurements);\r\n const last = measurements[measurements.length - 1] ?? 0;\r\n\r\n result[label] = {\r\n count: measurements.length,\r\n total,\r\n avg,\r\n min,\r\n max,\r\n last,\r\n };\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Get metrics for a specific label\r\n * \r\n * @param label - Label to get metrics for\r\n * @returns Metrics for the label, or null if not found\r\n */\r\n getMetric(label: string): PerformanceMetrics[string] | null {\r\n const measurements = this.metrics.get(label);\r\n if (!measurements || measurements.length === 0) {\r\n return null;\r\n }\r\n\r\n const total = measurements.reduce((sum, val) => sum + val, 0);\r\n const avg = total / measurements.length;\r\n const min = Math.min(...measurements);\r\n const max = Math.max(...measurements);\r\n const last = measurements[measurements.length - 1] ?? 0;\r\n\r\n return {\r\n count: measurements.length,\r\n total,\r\n avg,\r\n min,\r\n max,\r\n last,\r\n };\r\n }\r\n\r\n /**\r\n * Get raw measurements for a label\r\n * \r\n * @param label - Label to get measurements for\r\n * @returns Array of duration measurements in milliseconds\r\n */\r\n getRawMeasurements(label: string): number[] {\r\n return this.metrics.get(label) || [];\r\n }\r\n\r\n /**\r\n * Clear all metrics\r\n */\r\n clear(): void {\r\n this.metrics.clear();\r\n }\r\n\r\n /**\r\n * Clear metrics for a specific label\r\n * \r\n * @param label - Label to clear metrics for\r\n */\r\n clearLabel(label: string): void {\r\n this.metrics.delete(label);\r\n }\r\n\r\n /**\r\n * Enable or disable performance monitoring\r\n * \r\n * @param enabled - Whether to enable monitoring\r\n */\r\n setEnabled(enabled: boolean): void {\r\n this.enabled = enabled;\r\n }\r\n\r\n /**\r\n * Check if monitoring is enabled\r\n */\r\n isEnabled(): boolean {\r\n return this.enabled;\r\n }\r\n\r\n /**\r\n * Generate a performance report as a string\r\n * \r\n * @returns Formatted performance report\r\n */\r\n generateReport(): string {\r\n const metrics = this.getMetrics();\r\n const lines: string[] = [];\r\n\r\n lines.push('Performance Report');\r\n lines.push('='.repeat(50));\r\n lines.push('');\r\n\r\n for (const [label, stats] of Object.entries(metrics)) {\r\n lines.push(`${label}:`);\r\n lines.push(` Count: ${stats.count}`);\r\n lines.push(` Avg: ${stats.avg.toFixed(2)}ms`);\r\n lines.push(` Min: ${stats.min.toFixed(2)}ms`);\r\n lines.push(` Max: ${stats.max.toFixed(2)}ms`);\r\n lines.push(` Last: ${stats.last.toFixed(2)}ms`);\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n }\r\n}\r\n\r\n/**\r\n * Create a new performance monitor instance\r\n * \r\n * @param enabled - Whether to enable monitoring (default: true in development)\r\n * @returns PerformanceMonitor instance\r\n * \r\n * @example\r\n * ```typescript\r\n * const monitor = createPerformanceMonitor();\r\n * ```\r\n */\r\nexport function createPerformanceMonitor(enabled?: boolean): PerformanceMonitor {\r\n const isEnabled = enabled ?? process.env.NODE_ENV === 'development';\r\n return new PerformanceMonitor(isEnabled);\r\n}\r\n\r\n/**\r\n * Global performance monitor instance\r\n * Can be used across the application for centralized monitoring\r\n */\r\nexport const globalPerformanceMonitor = createPerformanceMonitor();\r\n\r\n/**\r\n * Decorator for measuring function performance\r\n * \r\n * @param label - Label for the performance measurement\r\n * @param monitor - Performance monitor instance (defaults to global)\r\n * @returns Function decorator\r\n * \r\n * @example\r\n * ```typescript\r\n * class MyClass {\r\n * @measurePerformance('my-operation')\r\n * async myOperation() {\r\n * // ... operation code ...\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function measurePerformance(\r\n label: string,\r\n monitor: PerformanceMonitor = globalPerformanceMonitor\r\n) {\r\n return function (\r\n _target: any,\r\n _propertyKey: string,\r\n descriptor: PropertyDescriptor\r\n ) {\r\n const originalMethod = descriptor.value;\r\n\r\n descriptor.value = async function (...args: any[]) {\r\n const endTimer = monitor.startTimer(label);\r\n try {\r\n const result = await originalMethod.apply(this, args);\r\n return result;\r\n } finally {\r\n endTimer();\r\n }\r\n };\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Higher-order function to wrap async functions with performance monitoring\r\n * \r\n * @param label - Label for the performance measurement\r\n * @param fn - Function to wrap\r\n * @param monitor - Performance monitor instance (defaults to global)\r\n * @returns Wrapped function\r\n * \r\n * @example\r\n * ```typescript\r\n * const loadPdfWithMonitoring = withPerformanceMonitoring(\r\n * 'pdf-load',\r\n * loadPdf\r\n * );\r\n * ```\r\n */\r\nexport function withPerformanceMonitoring<T extends (...args: any[]) => Promise<any>>(\r\n label: string,\r\n fn: T,\r\n monitor: PerformanceMonitor = globalPerformanceMonitor\r\n): T {\r\n return (async (...args: any[]) => {\r\n const endTimer = monitor.startTimer(label);\r\n try {\r\n return await fn(...args);\r\n } finally {\r\n endTimer();\r\n }\r\n }) as T;\r\n}\r\n\r\n","/**\r\n * Date Validation and Parsing Utility\r\n * Handles parsing of various date formats and validation\r\n */\r\n\r\nimport { parse, isValid as isValidDate, parseISO } from 'date-fns';\r\n\r\nexport interface DateValidationResult {\r\n isValid: boolean;\r\n date: Date | null;\r\n isoString: string | null;\r\n originalValue: string;\r\n error?: string;\r\n}\r\n\r\nfunction toIsoDateString(date: Date): string {\r\n const year = date.getFullYear();\r\n const month = String(date.getMonth() + 1).padStart(2, '0');\r\n const day = String(date.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\n/**\r\n * Parse and validate a date string from various formats\r\n * Attempts to parse common formats: ISO, US, EU, timestamps\r\n * \r\n * Format priority:\r\n * 1. ISO 8601 (YYYY-MM-DD)\r\n * 2. US format (MM/DD/YYYY) - assumes US format for ambiguous dates\r\n * 3. EU format (DD/MM/YYYY)\r\n * 4. Timestamp (numeric string)\r\n * \r\n * @param value - The date string to parse\r\n * @returns Validation result with parsed date or error\r\n */\r\nexport function parseAndValidateDate(value: string | null | undefined): DateValidationResult {\r\n const originalValue = String(value || '');\r\n \r\n // Handle empty values\r\n if (!value || value.trim() === '') {\r\n return {\r\n isValid: false,\r\n date: null,\r\n isoString: null,\r\n originalValue,\r\n error: 'Date is required',\r\n };\r\n }\r\n\r\n const trimmedValue = value.trim();\r\n const sanitizedValue = trimmedValue\r\n // Remove ordinal suffixes (1st, 2nd, 3rd, 21st, etc.)\r\n .replace(/(\\d+)(st|nd|rd|th)/gi, '$1')\r\n // Normalize commas to spaces for natural language inputs\r\n .replace(/,/g, ' ')\r\n .replace(/\\s+/g, ' ')\r\n .trim();\r\n\r\n // Try ISO 8601 format first (YYYY-MM-DD)\r\n try {\r\n const isoDate = parseISO(trimmedValue);\r\n if (isValidDate(isoDate) && !isNaN(isoDate.getTime())) {\r\n return {\r\n isValid: true,\r\n date: isoDate,\r\n isoString: trimmedValue,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Continue to next format\r\n }\r\n\r\n // Handle two-digit year inputs like 01/05/24 by assuming 2000-based year\r\n const shortYearMatch = sanitizedValue.match(/^(\\d{1,2})[\\/.\\-](\\d{1,2})[\\/.\\-](\\d{2})$/);\r\n if (shortYearMatch) {\r\n const [, monthStr, dayStr, yearStr] = shortYearMatch;\r\n const month = parseInt(monthStr ?? '', 10);\r\n const day = parseInt(dayStr ?? '', 10);\r\n const year = 2000 + parseInt(yearStr ?? '', 10);\r\n const candidate = new Date(year, month - 1, day);\r\n if (isValidDate(candidate) && !isNaN(candidate.getTime())) {\r\n return {\r\n isValid: true,\r\n date: candidate,\r\n isoString: toIsoDateString(candidate),\r\n originalValue,\r\n };\r\n }\r\n }\r\n\r\n // Try common date formats\r\n const formats = [\r\n // US formats (MM/DD/YYYY - assume US for ambiguous dates)\r\n { pattern: 'MM/dd/yyyy', name: 'US format (MM/DD/YYYY)' },\r\n { pattern: 'M/d/yyyy', name: 'US format (M/D/YYYY)' },\r\n { pattern: 'MM-dd-yyyy', name: 'US format (MM-DD-YYYY)' },\r\n { pattern: 'M-d-yyyy', name: 'US format (M-D-YYYY)' },\r\n { pattern: 'MM/dd/yy', name: 'US format (MM/DD/YY)' },\r\n { pattern: 'M/d/yy', name: 'US format (M/D/YY)' },\r\n { pattern: 'MM-dd-yy', name: 'US format (MM-DD-YY)' },\r\n { pattern: 'M-d-yy', name: 'US format (M-D-YY)' },\r\n \r\n // EU formats (DD/MM/YYYY)\r\n { pattern: 'dd/MM/yyyy', name: 'EU format (DD/MM/YYYY)' },\r\n { pattern: 'd/M/yyyy', name: 'EU format (D/M/YYYY)' },\r\n { pattern: 'dd.MM.yyyy', name: 'EU format (DD.MM.YYYY)' },\r\n { pattern: 'd.M.yyyy', name: 'EU format (D.M.YYYY)' },\r\n \r\n // Full month names\r\n { pattern: 'MMMM d, yyyy', name: 'Month name format (January 1, 2024)' },\r\n { pattern: 'MMM d, yyyy', name: 'Short month format (Jan 1, 2024)' },\r\n { pattern: 'MMMM d yyyy', name: 'Month name format without comma (January 1 2024)' },\r\n { pattern: 'MMM d yyyy', name: 'Short month without comma (Jan 1 2024)' },\r\n { pattern: 'd MMMM yyyy', name: 'EU month format (1 January 2024)' },\r\n { pattern: 'd MMM yyyy', name: 'EU month short format (1 Jan 2024)' },\r\n { pattern: 'd MMM, yyyy', name: 'EU month short with comma (1 Jan, 2024)' },\r\n \r\n // Year first formats\r\n { pattern: 'yyyy/MM/dd', name: 'ISO-like format (YYYY/MM/DD)' },\r\n { pattern: 'yyyy-MM-dd', name: 'ISO format with dashes' },\r\n ];\r\n\r\n const referenceDate = new Date();\r\n\r\n for (const { pattern } of formats) {\r\n try {\r\n const parsedDate = parse(sanitizedValue, pattern, referenceDate);\r\n if (isValidDate(parsedDate) && !isNaN(parsedDate.getTime())) {\r\n // Convert to ISO string format (YYYY-MM-DD)\r\n const isoString = toIsoDateString(parsedDate);\r\n \r\n return {\r\n isValid: true,\r\n date: parsedDate,\r\n isoString,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Continue to next format\r\n }\r\n }\r\n\r\n // Try parsing as timestamp (milliseconds)\r\n if (/^\\d+$/.test(trimmedValue)) {\r\n try {\r\n const timestamp = parseInt(trimmedValue, 10);\r\n const date = new Date(timestamp);\r\n if (isValidDate(date) && !isNaN(date.getTime())) {\r\n const isoString = toIsoDateString(date);\r\n \r\n return {\r\n isValid: true,\r\n date,\r\n isoString,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Not a valid timestamp\r\n }\r\n }\r\n\r\n // Lenient fallback using native Date parsing after sanitization\r\n const nativeParsed = new Date(sanitizedValue);\r\n if (isValidDate(nativeParsed) && !isNaN(nativeParsed.getTime())) {\r\n return {\r\n isValid: true,\r\n date: nativeParsed,\r\n isoString: toIsoDateString(nativeParsed),\r\n originalValue,\r\n };\r\n }\r\n\r\n // All formats failed\r\n return {\r\n isValid: false,\r\n date: null,\r\n isoString: null,\r\n originalValue,\r\n error: `Invalid date format: \"${trimmedValue}\". Please use a date picker or format like MM/DD/YYYY.`,\r\n };\r\n}\r\n\r\n/**\r\n * Validate if a string is a valid ISO date (YYYY-MM-DD)\r\n */\r\nexport function isValidISODate(value: string | null | undefined): boolean {\r\n if (!value || typeof value !== 'string') {\r\n return false;\r\n }\r\n\r\n const isoPattern = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n if (!isoPattern.test(value)) {\r\n return false;\r\n }\r\n\r\n try {\r\n const date = parseISO(value);\r\n return isValidDate(date) && !isNaN(date.getTime());\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n","/**\r\n * Usage tracking utilities for signiphi API integration.\r\n * Enables automatic tracking of document sends and signings via API key.\r\n */\r\n\r\nimport { logger } from './logger';\r\n\r\n/**\r\n * Configuration for the tracking API\r\n */\r\nexport interface TrackingConfig {\r\n /** API key for authentication */\r\n apiKey: string;\r\n /** Custom API endpoint (defaults to https://api.signiphi.ai) */\r\n endpoint?: string;\r\n}\r\n\r\n/**\r\n * Data for tracking a document send event\r\n */\r\nexport interface TrackSendData {\r\n /** Email address of the recipient */\r\n recipientEmail: string;\r\n /** Optional document ID for correlation */\r\n documentId?: string;\r\n /** Optional idempotency key to prevent duplicate tracking */\r\n idempotencyKey?: string;\r\n /** Optional additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Data for tracking a document signing event\r\n */\r\nexport interface TrackSigningData {\r\n /** Email address of the signer */\r\n signerEmail: string;\r\n /** Optional document ID for correlation */\r\n documentId?: string;\r\n /** Optional idempotency key to prevent duplicate tracking */\r\n idempotencyKey?: string;\r\n /** Optional additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Response from tracking API\r\n */\r\nexport interface TrackingResponse {\r\n success: boolean;\r\n eventId: string;\r\n idempotencyKey: string;\r\n usage: {\r\n currentMonth: number;\r\n limit: number;\r\n remaining: number;\r\n };\r\n}\r\n\r\nconst DEFAULT_API_ENDPOINT = 'https://api-dev.signiphi.ai';\r\n// const DEFAULT_API_ENDPOINT = 'http://localhost:4000';\r\nconst API_PREFIX = '/api/v1';\r\n\r\n/**\r\n * Track a document send event.\r\n * Call this when a document is sent to a recipient for signing.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Send event data\r\n * @returns Tracking response with usage stats\r\n */\r\nexport async function trackDocumentSent(\r\n config: TrackingConfig,\r\n data: TrackSendData,\r\n): Promise<TrackingResponse> {\r\n const endpoint = config.endpoint || DEFAULT_API_ENDPOINT;\r\n const url = `${endpoint}${API_PREFIX}/usage/track-send`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': config.apiKey,\r\n },\r\n body: JSON.stringify({\r\n recipientEmail: data.recipientEmail,\r\n documentId: data.documentId,\r\n idempotencyKey: data.idempotencyKey,\r\n metadata: data.metadata,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n logger.error(`Track send failed: ${response.status} - ${errorText}`);\r\n throw new Error(`Tracking failed: ${response.status}`);\r\n }\r\n\r\n const result = await response.json();\r\n logger.debug('Document send tracked successfully', { eventId: result.eventId });\r\n return result;\r\n } catch (error) {\r\n logger.error('Failed to track document send:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Track a document signing event.\r\n * Call this when a document is signed by a recipient.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Signing event data\r\n * @returns Tracking response with usage stats\r\n */\r\nexport async function trackDocumentSigned(\r\n config: TrackingConfig,\r\n data: TrackSigningData,\r\n): Promise<TrackingResponse> {\r\n const endpoint = config.endpoint || DEFAULT_API_ENDPOINT;\r\n const url = `${endpoint}${API_PREFIX}/usage/track-signing`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': config.apiKey,\r\n },\r\n body: JSON.stringify({\r\n signerEmail: data.signerEmail,\r\n documentId: data.documentId,\r\n idempotencyKey: data.idempotencyKey,\r\n metadata: data.metadata,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n logger.error(`Track signing failed: ${response.status} - ${errorText}`);\r\n throw new Error(`Tracking failed: ${response.status}`);\r\n }\r\n\r\n const result = await response.json();\r\n logger.debug('Document signing tracked successfully', { eventId: result.eventId });\r\n return result;\r\n } catch (error) {\r\n logger.error('Failed to track document signing:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Silently track a document signing event (non-blocking).\r\n * This version catches errors and logs them without throwing.\r\n * Use this when tracking failure should not affect the main flow.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Signing event data\r\n */\r\nexport async function trackDocumentSignedSilent(\r\n config: TrackingConfig,\r\n data: TrackSigningData,\r\n): Promise<void> {\r\n try {\r\n await trackDocumentSigned(config, data);\r\n } catch (error) {\r\n logger.warn('Silent tracking failed (non-critical):', error);\r\n }\r\n}\r\n\r\n/**\r\n * Silently track a document send event (non-blocking).\r\n * This version catches errors and logs them without throwing.\r\n * Use this when tracking failure should not affect the main flow.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Send event data\r\n */\r\nexport async function trackDocumentSentSilent(\r\n config: TrackingConfig,\r\n data: TrackSendData,\r\n): Promise<void> {\r\n try {\r\n await trackDocumentSent(config, data);\r\n } catch (error) {\r\n logger.warn('Silent tracking failed (non-critical):', error);\r\n }\r\n}\r\n\r\n"]}
1
+ {"version":3,"sources":["../../src/utils/logger.ts","../../src/utils/pdf-validators.ts","../../src/utils/pdf-helpers.ts","../../src/utils/pdf-metadata.ts","../../src/utils/font-loader.ts","../../src/utils/pdf-lib-loader.ts","../../src/utils/field-visibility.ts","../../src/utils/pdf-widget-helpers.ts","../../src/utils/pdf-field-type-helpers.ts","../../src/utils/pdf-manipulation.ts","../../src/utils/pdf-signer-utils.ts","../../src/utils/field-extraction.ts","../../src/utils/pdfjs-config.ts","../../src/utils/pdfjs-version-check.ts","../../src/utils/audit-trail.ts","../../src/utils/errors.ts","../../src/utils/attachment-validators.ts","../../src/utils/performance-monitor.ts","../../src/utils/date-validation-iso.ts","../../src/utils/date-validation.ts","../../src/utils/tracking.ts"],"names":["pdfjsLib","isSignatureField","isInitialsField","f","PDFName","pdfjsLib2","pdfjsLib3","parseISO","isValidDate","parse"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Logger Utility\r\n * Centralized logging system with environment-based log level control\r\n */\r\n\r\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\r\n\r\ninterface Logger {\r\n debug(message: string, ...args: unknown[]): void;\r\n info(message: string, ...args: unknown[]): void;\r\n warn(message: string, ...args: unknown[]): void;\r\n error(message: string, ...args: unknown[]): void;\r\n}\r\n\r\n/**\r\n * Determines if the current environment is production\r\n */\r\nfunction isProduction(): boolean {\r\n return typeof process !== 'undefined' && process.env.NODE_ENV === 'production';\r\n}\r\n\r\n/**\r\n * Creates a formatted log prefix\r\n */\r\nfunction createPrefix(level: LogLevel): string {\r\n return `[@signiphi/pdf-signer] [${level.toUpperCase()}]`;\r\n}\r\n\r\n/**\r\n * Creates the logger instance with environment-based behavior\r\n */\r\nfunction createLogger(): Logger {\r\n const isProd = isProduction();\r\n\r\n return {\r\n debug(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.log(createPrefix('debug'), message, ...args);\r\n }\r\n },\r\n\r\n info(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.log(createPrefix('info'), message, ...args);\r\n }\r\n },\r\n\r\n warn(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.warn(createPrefix('warn'), message, ...args);\r\n }\r\n },\r\n\r\n error(message: string, ...args: unknown[]): void {\r\n // Errors are shown in both development and production\r\n console.error(createPrefix('error'), message, ...args);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Singleton logger instance\r\n */\r\nexport const logger = createLogger();\r\n\r\n\r\n\r\n","/**\r\n * PDF Validation Utilities\r\n * Common validation functions used across the package\r\n */\r\n\r\nimport type { FormField } from '../types';\r\n\r\n/**\r\n * Validate that bytes represent a valid PDF file\r\n * \r\n * Checks for:\r\n * - Non-empty bytes\r\n * - Valid PDF header (%PDF-)\r\n * \r\n * @param pdfBytes - The PDF bytes to validate\r\n * @returns Validation result with valid flag and optional error message\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validatePdfBytes(pdfBytes);\r\n * if (!result.valid) {\r\n * console.error(result.error);\r\n * return;\r\n * }\r\n * ```\r\n */\r\nexport function validatePdfBytes(pdfBytes: Uint8Array): { \r\n valid: boolean; \r\n error?: string \r\n} {\r\n // Check for empty bytes\r\n if (!pdfBytes || pdfBytes.length === 0) {\r\n return { \r\n valid: false, \r\n error: 'PDF bytes are empty' \r\n };\r\n }\r\n \r\n // Check for valid PDF header\r\n const header = new TextDecoder().decode(pdfBytes.slice(0, 12));\r\n if (!header.startsWith('%PDF-')) {\r\n return { \r\n valid: false, \r\n error: 'Invalid PDF format: Missing PDF header' \r\n };\r\n }\r\n \r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Check if a label is auto-generated (not user-typed)\r\n *\r\n * Auto-generated labels include:\r\n * - Simple type names: \"Text\", \"Signature\", etc.\r\n * - Type + timestamp: \"Dropdown 12413423423\", \"Text 1768236803505\"\r\n * - Pure timestamps: \"12413423423\"\r\n * - Type + numbers: \"Dropdown1\", \"Text_2\"\r\n *\r\n * These are default labels assigned by the form builder and should not be\r\n * displayed to users in the same way as custom labels.\r\n *\r\n * Works identically in both single-signer and multi-signer flows.\r\n *\r\n * @param label - The label to check\r\n * @returns true if the label is auto-generated, false if it's a custom user label\r\n *\r\n * @example\r\n * ```ts\r\n * isAutoGeneratedLabel('Signature') // true\r\n * isAutoGeneratedLabel('Dropdown 12413423423') // true\r\n * isAutoGeneratedLabel('Sign here please') // false\r\n * isAutoGeneratedLabel('') // true\r\n * ```\r\n */\r\nexport function isAutoGeneratedLabel(label: string): boolean {\r\n if (!label || !label.trim()) return true;\r\n\r\n const trimmed = label.trim();\r\n\r\n const autoLabels = [\r\n 'Signature',\r\n 'Initials',\r\n 'Date',\r\n 'Text',\r\n 'Checkbox',\r\n 'Dropdown',\r\n 'Option',\r\n 'Radio',\r\n ];\r\n\r\n // Check for simple type names\r\n if (autoLabels.includes(trimmed)) return true;\r\n\r\n // Check for pure timestamps (10+ digit numbers)\r\n if (/^\\d{10,}$/.test(trimmed)) return true;\r\n\r\n // Check for type + timestamp pattern: \"Dropdown 12413423423\" or \"Text_1768236803505\"\r\n const typeTimestampPattern = new RegExp(\r\n `^(${autoLabels.join('|')})[\\\\s_-]?\\\\d{10,}$`,\r\n 'i'\r\n );\r\n if (typeTimestampPattern.test(trimmed)) return true;\r\n\r\n // Check for type + short number: \"Dropdown1\", \"Text_2\", \"Signature 3\"\r\n const typeNumberPattern = new RegExp(\r\n `^(${autoLabels.join('|')})[\\\\s_-]?\\\\d{1,3}$`,\r\n 'i'\r\n );\r\n if (typeNumberPattern.test(trimmed)) return true;\r\n\r\n // Check for corrupted labels with repeated type words: \"Date 1767730185976 Date Date Date...\"\r\n // These occur when PDFs are saved multiple times and field names get concatenated\r\n const typeWordsJoined = autoLabels.join('|');\r\n const corruptedPattern = new RegExp(\r\n `^(${typeWordsJoined})[\\\\s_-]?\\\\d{10,}[\\\\s_-]?(${typeWordsJoined})+`,\r\n 'i'\r\n );\r\n if (corruptedPattern.test(trimmed)) return true;\r\n\r\n // Check for labels that are just repeated type words: \"Date Date Date\" or \"Signature Signature\"\r\n const repeatedTypePattern = new RegExp(\r\n `^((${typeWordsJoined})[\\\\s_-]+)+(${typeWordsJoined})$`,\r\n 'i'\r\n );\r\n if (repeatedTypePattern.test(trimmed)) return true;\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a field has a drawable label (user-set custom label that should be rendered on the PDF)\r\n *\r\n * Returns false when:\r\n * - Label is empty or whitespace\r\n * - Label was auto-generated from field name during extraction (isLabelAutoGenerated flag)\r\n * - Label matches known auto-generated patterns (e.g., \"Text\", \"Signature 1\")\r\n *\r\n * @param field - Object with label and optional isLabelAutoGenerated flag\r\n * @returns true if the label should be drawn on the PDF\r\n */\r\nexport function hasDrawableLabel(field: { label?: string; isLabelAutoGenerated?: boolean }): boolean {\r\n if (!field.label || !field.label.trim()) return false;\r\n if (field.isLabelAutoGenerated) return false;\r\n if (isAutoGeneratedLabel(field.label)) return false;\r\n return true;\r\n}\r\n\r\n/**\r\n * Get a user-friendly display name for a field\r\n *\r\n * If the label is meaningful (not auto-generated), returns the label.\r\n * Otherwise, returns a clean field type name.\r\n *\r\n * @param field - Object with label and type properties\r\n * @returns A user-friendly name for display in error messages\r\n */\r\nexport function getFieldDisplayName(field: { label?: string; type?: string; name?: string }): string {\r\n // If label exists and is not auto-generated, use it\r\n if (field.label && !isAutoGeneratedLabel(field.label)) {\r\n return field.label;\r\n }\r\n\r\n // Map field types to friendly names\r\n const typeNames: Record<string, string> = {\r\n 'text': 'Text field',\r\n 'signature': 'Signature',\r\n 'initials': 'Initials',\r\n 'date': 'Date field',\r\n 'checkbox': 'Checkbox',\r\n 'dropdown': 'Dropdown',\r\n 'radio': 'Radio selection',\r\n 'radiogroup': 'Radio selection',\r\n 'text_label': 'Text label',\r\n };\r\n\r\n if (field.type) {\r\n const typeName = typeNames[field.type.toLowerCase()];\r\n if (typeName) {\r\n return typeName;\r\n }\r\n }\r\n\r\n // Fallback: clean up the field name\r\n if (field.name) {\r\n // Remove timestamps and clean up\r\n let cleaned = field.name\r\n .replace(/_?(signature|initials|date)$/i, '') // Remove type suffixes\r\n .replace(/[_-]\\d{10,}$/, '') // Remove timestamps\r\n .replace(/[_-]/g, ' ') // Replace separators with spaces\r\n .trim();\r\n\r\n if (cleaned && !isAutoGeneratedLabel(cleaned)) {\r\n return cleaned.replace(/\\b\\w/g, l => l.toUpperCase()); // Title case\r\n }\r\n }\r\n\r\n return 'This field';\r\n}\r\n\r\n/**\r\n * Validate field values object\r\n * \r\n * Checks that the values object is properly formatted and contains\r\n * only string values for field IDs.\r\n * \r\n * @param values - Field values to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFieldValues({ field1: 'value1', field2: 'value2' });\r\n * if (!result.valid) {\r\n * console.error('Validation errors:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFieldValues(values: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if values is an object\r\n if (!values || typeof values !== 'object') {\r\n errors.push('Field values must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n // Check each value is a string\r\n const valuesObj = values as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(valuesObj)) {\r\n if (typeof value !== 'string') {\r\n errors.push(`Field value for \"${key}\" must be a string, got ${typeof value}`);\r\n }\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate signatures object\r\n * \r\n * Checks that signatures are properly formatted data URLs.\r\n * \r\n * @param signatures - Signatures to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateSignatures({\r\n * sig1: 'data:image/png;base64,iVBORw0KG...',\r\n * sig2: 'data:image/png;base64,iVBORw0KG...'\r\n * });\r\n * if (!result.valid) {\r\n * console.error('Invalid signatures:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateSignatures(signatures: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if signatures is an object\r\n if (!signatures || typeof signatures !== 'object') {\r\n errors.push('Signatures must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n // Check each signature is a valid data URL\r\n const sigsObj = signatures as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(sigsObj)) {\r\n if (typeof value !== 'string') {\r\n errors.push(`Signature for \"${key}\" must be a string, got ${typeof value}`);\r\n continue;\r\n }\r\n \r\n // Validate data URL format\r\n if (!value.startsWith('data:image/')) {\r\n errors.push(`Signature for \"${key}\" must be a data URL starting with \"data:image/\"`);\r\n }\r\n \r\n // Check for base64 data\r\n const parts = value.split(',');\r\n if (parts.length !== 2 || !parts[1]) {\r\n errors.push(`Signature for \"${key}\" has invalid data URL format (missing base64 data)`);\r\n }\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate a form field definition\r\n * \r\n * Checks that a field has all required properties and they are valid.\r\n * \r\n * @param field - Form field to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFormField({\r\n * id: 'field1',\r\n * name: 'firstName',\r\n * type: FormFieldType.TEXT,\r\n * label: 'First Name',\r\n * position: { x: 100, y: 200, width: 150, height: 30, page: 1 },\r\n * required: true\r\n * });\r\n * if (!result.valid) {\r\n * console.error('Field validation errors:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFormField(field: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if field is an object\r\n if (!field || typeof field !== 'object') {\r\n errors.push('Form field must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n const f = field as Partial<FormField>;\r\n \r\n // Required properties\r\n if (!f.id || typeof f.id !== 'string') {\r\n errors.push('Field must have a valid \"id\" string');\r\n }\r\n \r\n if (!f.type || typeof f.type !== 'string') {\r\n errors.push('Field must have a valid \"type\" string');\r\n }\r\n \r\n if (!f.name || typeof f.name !== 'string') {\r\n errors.push('Field must have a valid \"name\" string');\r\n }\r\n \r\n if (!f.label || typeof f.label !== 'string') {\r\n errors.push('Field must have a valid \"label\" string');\r\n }\r\n \r\n // Validate position\r\n if (!f.position || typeof f.position !== 'object') {\r\n errors.push('Field must have a valid \"position\" object');\r\n } else {\r\n const pos = f.position;\r\n if (typeof pos.x !== 'number') {\r\n errors.push('Field position must have a numeric \"x\" coordinate');\r\n }\r\n if (typeof pos.y !== 'number') {\r\n errors.push('Field position must have a numeric \"y\" coordinate');\r\n }\r\n if (typeof pos.width !== 'number' || pos.width <= 0) {\r\n errors.push('Field position must have a positive \"width\"');\r\n }\r\n if (typeof pos.height !== 'number' || pos.height <= 0) {\r\n errors.push('Field position must have a positive \"height\"');\r\n }\r\n if (typeof pos.page !== 'number' || pos.page < 1) {\r\n errors.push('Field position must have a valid \"page\" number (1-indexed)');\r\n }\r\n }\r\n \r\n if (typeof f.required !== 'boolean') {\r\n errors.push('Field must have a boolean \"required\" property');\r\n }\r\n \r\n // Optional properties validation\r\n if (f.fontSize !== undefined && (typeof f.fontSize !== 'number' || f.fontSize < 8 || f.fontSize > 72)) {\r\n errors.push('Field fontSize must be a number between 8 and 72');\r\n }\r\n \r\n if (f.maxLength !== undefined && (typeof f.maxLength !== 'number' || f.maxLength <= 0)) {\r\n errors.push('Field maxLength must be a positive number');\r\n }\r\n \r\n if (f.options !== undefined && !Array.isArray(f.options)) {\r\n errors.push('Field options must be an array');\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate PDF URL format\r\n * \r\n * Accepts absolute URLs, relative paths, and data URLs.\r\n * \r\n * @param url - URL to validate\r\n * @returns Validation result with valid flag and optional error message\r\n * \r\n * @example\r\n * ```ts\r\n * // Absolute URLs\r\n * validatePdfUrl('https://example.com/document.pdf'); // valid\r\n * validatePdfUrl('http://localhost:3000/doc.pdf'); // valid\r\n * \r\n * // Relative paths\r\n * validatePdfUrl('/public/document.pdf'); // valid\r\n * validatePdfUrl('./document.pdf'); // valid\r\n * \r\n * // Data URLs and blobs\r\n * validatePdfUrl('data:application/pdf;base64,...'); // valid\r\n * validatePdfUrl('blob:http://localhost/...'); // valid\r\n * \r\n * // Local files\r\n * validatePdfUrl('file:///C:/path/to/file.pdf'); // valid\r\n * ```\r\n */\r\nexport function validatePdfUrl(url: unknown): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n if (typeof url !== 'string') {\r\n return { valid: false, error: 'URL must be a string' };\r\n }\r\n \r\n if (!url || url.trim().length === 0) {\r\n return { valid: false, error: 'URL cannot be empty' };\r\n }\r\n \r\n const trimmedUrl = url.trim();\r\n \r\n // Check for absolute URLs with protocols\r\n const validPrefixes = ['http://', 'https://', 'blob:', 'data:', 'file://'];\r\n const hasValidPrefix = validPrefixes.some(prefix => trimmedUrl.startsWith(prefix));\r\n \r\n if (hasValidPrefix) {\r\n return { valid: true };\r\n }\r\n \r\n // Allow relative paths (start with / or ./ or ../)\r\n if (trimmedUrl.startsWith('/') || trimmedUrl.startsWith('./') || trimmedUrl.startsWith('../')) {\r\n return { valid: true };\r\n }\r\n \r\n // Reject URLs that look malformed\r\n return {\r\n valid: false,\r\n error: 'URL must be an absolute URL (http://, https://, blob:, data:, file://) or a relative path (/, ./, ../)',\r\n };\r\n}\r\n\r\n","/**\r\n * PDF utility helper functions\r\n */\r\n\r\nimport { logger } from \"./logger\";\r\nimport { validatePdfBytes } from \"./pdf-validators\";\r\n\r\n/**\r\n * Create a blob URL from PDF bytes for preview\r\n */\r\nexport function createPdfBlobUrl(pdfBytes: Uint8Array): string {\r\n const blob = new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\n/**\r\n * Download PDF file\r\n */\r\nexport function downloadPdf(pdfBytes: Uint8Array, filename: string): void {\r\n const url = createPdfBlobUrl(pdfBytes);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = filename;\r\n a.click();\r\n URL.revokeObjectURL(url);\r\n}\r\n\r\n/**\r\n * Convert URL to PDF bytes\r\n * @param url - The URL to fetch the PDF from\r\n * @returns PDF bytes as Uint8Array\r\n */\r\nexport async function urlToPdfBytes(url: string): Promise<Uint8Array> {\r\n try {\r\n const response = await fetch(url);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch PDF: ${response.status} ${response.statusText}`);\r\n }\r\n\r\n const arrayBuffer = await response.arrayBuffer();\r\n\r\n // Create a new Uint8Array and copy the data to avoid detached ArrayBuffer issues\r\n const pdfBytes = new Uint8Array(arrayBuffer.byteLength);\r\n pdfBytes.set(new Uint8Array(arrayBuffer));\r\n\r\n // Validate that we have a PDF\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n throw new Error(validation.error || 'Invalid PDF format');\r\n }\r\n\r\n return pdfBytes;\r\n } catch (error) {\r\n logger.error('Error fetching PDF from URL:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Validate that data is a valid PDF\r\n */\r\nexport function isValidPdf(pdfBytes: Uint8Array): boolean {\r\n const validation = validatePdfBytes(pdfBytes);\r\n return validation.valid;\r\n}\r\n\r\n/**\r\n * Convert base64 data URL to image bytes\r\n */\r\nexport function dataUrlToBytes(dataUrl: string): Uint8Array {\r\n const base64Data = dataUrl.split(',')[1];\r\n if (!base64Data) {\r\n throw new Error('Invalid data URL format: missing base64 data');\r\n }\r\n return Uint8Array.from(atob(base64Data), (c) => c.charCodeAt(0));\r\n}\r\n\r\n/**\r\n * Format field name for display\r\n */\r\nexport function formatFieldName(fieldName: string): string {\r\n return fieldName\r\n .replace(/[_-]/g, ' ')\r\n .replace(/\\b\\w/g, (l) => l.toUpperCase())\r\n .replace('Signature', '')\r\n .replace('Initials', '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Check if a field is a signature field\r\n */\r\nexport function isSignatureField(fieldName: string): boolean {\r\n return fieldName.toLowerCase().includes('signature');\r\n}\r\n\r\n/**\r\n * Check if a field is an initials field\r\n */\r\nexport function isInitialsField(fieldName: string): boolean {\r\n return fieldName.toLowerCase().includes('initials');\r\n}\r\n\r\n","/**\r\n * PDF Metadata Utilities\r\n * Functions for storing and retrieving Signiphi metadata in PDF documents\r\n */\r\n\r\nimport type { PDFDocument, PDFName as PDFNameType, PDFString as PDFStringType } from 'pdf-lib';\r\nimport { Acknowledgement } from '../types';\r\n\r\n// Module-level variables for pdf-lib classes (loaded dynamically)\r\nlet PDFName: typeof PDFNameType;\r\nlet PDFString: typeof PDFStringType;\r\n\r\n/**\r\n * Initialize PDF classes from dynamically loaded pdf-lib module\r\n * Must be called before using getSigniphiMetadata or setSigniphiMetadata\r\n */\r\nexport function initPdfMetadata(pdfLibModule: any): void {\r\n PDFName = pdfLibModule.PDFName;\r\n PDFString = pdfLibModule.PDFString;\r\n}\r\n\r\n/**\r\n * Metadata for a single form field\r\n */\r\nexport interface FieldMetadata {\r\n fieldId?: string; // Immutable UUID for reliable field identification\r\n label?: string;\r\n signer?: string;\r\n placeholder?: string;\r\n acknowledgements?: Acknowledgement[];\r\n required?: boolean;\r\n options?: string[]; // For radio and dropdown fields\r\n}\r\n\r\n/**\r\n * Complete metadata structure stored in PDF\r\n */\r\nexport interface SigniphiMetadata {\r\n version: string;\r\n fields: Record<string, FieldMetadata>; // Key is the actual PDF field name (with suffixes for date/signature/initials)\r\n fieldIdIndex?: Record<string, string>; // UUID → field name mapping for fast lookups\r\n}\r\n\r\n/**\r\n * Stores Signiphi metadata in the PDF's document information dictionary\r\n * @param pdfDoc - The PDF document to store metadata in\r\n * @param metadata - The metadata object to store\r\n */\r\nexport function setSigniphiMetadata(pdfDoc: PDFDocument, metadata: SigniphiMetadata): void {\r\n try {\r\n if (!PDFName || !PDFString) {\r\n console.error('PDF metadata classes not initialized. Call initPdfMetadata first.');\r\n return;\r\n }\r\n \r\n const infoRef = pdfDoc.context.trailerInfo.Info;\r\n const infoObj = pdfDoc.context.lookup(infoRef);\r\n if (!infoObj || typeof (infoObj as any).set !== 'function') {\r\n throw new Error('Info object is not a PDFDict or does not have set method');\r\n }\r\n const infoDict = infoObj as any;\r\n const metadataString = JSON.stringify(metadata);\r\n \r\n // Set the metadata\r\n infoDict.set(PDFName.of('SigniphiMetadata'), PDFString.of(metadataString));\r\n } catch (error) {\r\n console.error('Failed to set Signiphi metadata:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Retrieves Signiphi metadata from the PDF's document information dictionary\r\n * @param pdfDoc - The PDF document to read metadata from\r\n * @returns The metadata object if found, null otherwise\r\n */\r\nexport function getSigniphiMetadata(pdfDoc: PDFDocument): SigniphiMetadata | null {\r\n try {\r\n if (!PDFName || !PDFString) {\r\n console.error('PDF metadata classes not initialized. Call initPdfMetadata first.');\r\n return null;\r\n }\r\n \r\n const infoRef = pdfDoc.context.trailerInfo.Info;\r\n const infoObj = pdfDoc.context.lookup(infoRef);\r\n \r\n if (!infoObj || typeof (infoObj as any).get !== 'function' || !(infoObj as any).dict) {\r\n return null;\r\n }\r\n \r\n const infoDict = infoObj as any;\r\n const metadataObj = infoDict.get(PDFName.of('SigniphiMetadata'));\r\n \r\n if (!metadataObj) {\r\n return null;\r\n }\r\n \r\n // PDFString objects are encoded as \"(content)\" in their toString() representation\r\n const metadataStr = metadataObj.toString();\r\n \r\n // Extract content from PDF string format: (content) or <hex>\r\n let jsonStr = metadataStr;\r\n const parenMatch = metadataStr.match(/^\\((.*)\\)$/);\r\n if (parenMatch && parenMatch[1]) {\r\n jsonStr = parenMatch[1];\r\n } else {\r\n const hexMatch = metadataStr.match(/^<(.*)>$/);\r\n if (hexMatch && hexMatch[1]) {\r\n // Convert hex to string if needed\r\n jsonStr = hexMatch[1];\r\n }\r\n }\r\n \r\n const metadata = JSON.parse(jsonStr);\r\n return metadata;\r\n } catch (error) {\r\n console.error('Failed to load Signiphi metadata:', error);\r\n return null;\r\n }\r\n}\r\n","/**\r\n * Font loading and text-to-signature generation utilities\r\n * Uses Google Fonts for cursive/handwritten signature styles\r\n */\r\n\r\nexport interface SignatureFont {\r\n name: string;\r\n family: string;\r\n label: string;\r\n}\r\n\r\n/**\r\n * Available signature fonts from Google Fonts\r\n */\r\nexport const SIGNATURE_FONTS: SignatureFont[] = [\r\n { name: 'dancing-script', family: 'Dancing Script', label: 'Elegant' },\r\n { name: 'great-vibes', family: 'Great Vibes', label: 'Formal' },\r\n { name: 'caveat', family: 'Caveat', label: 'Casual' },\r\n { name: 'homemade-apple', family: 'Homemade Apple', label: 'Natural' },\r\n { name: 'sacramento', family: 'Sacramento', label: 'Flowing' },\r\n];\r\n\r\n/**\r\n * Default font to use\r\n */\r\nexport const DEFAULT_SIGNATURE_FONT: SignatureFont = {\r\n name: 'dancing-script',\r\n family: 'Dancing Script',\r\n label: 'Elegant',\r\n};\r\n\r\n/**\r\n * Google Fonts URL for all signature fonts\r\n */\r\nconst GOOGLE_FONTS_URL =\r\n 'https://fonts.googleapis.com/css2?family=Dancing+Script&family=Great+Vibes&family=Caveat&family=Homemade+Apple&family=Sacramento&display=swap';\r\n\r\nlet fontsLoaded = false;\r\nlet fontsLoadingPromise: Promise<void> | null = null;\r\n\r\n/**\r\n * Load all signature fonts from Google Fonts\r\n * This function is idempotent - it will only load fonts once\r\n */\r\nexport async function loadSignatureFonts(): Promise<void> {\r\n if (fontsLoaded) {\r\n return;\r\n }\r\n\r\n if (fontsLoadingPromise) {\r\n return fontsLoadingPromise;\r\n }\r\n\r\n fontsLoadingPromise = new Promise<void>((resolve, reject) => {\r\n // Check if fonts link already exists\r\n const existingLink = document.querySelector(\r\n `link[href=\"${GOOGLE_FONTS_URL}\"]`\r\n );\r\n if (existingLink) {\r\n fontsLoaded = true;\r\n resolve();\r\n return;\r\n }\r\n\r\n const link = document.createElement('link');\r\n link.href = GOOGLE_FONTS_URL;\r\n link.rel = 'stylesheet';\r\n\r\n link.onload = () => {\r\n fontsLoaded = true;\r\n resolve();\r\n };\r\n\r\n link.onerror = () => {\r\n fontsLoadingPromise = null;\r\n reject(new Error('Failed to load signature fonts from Google Fonts'));\r\n };\r\n\r\n document.head.appendChild(link);\r\n });\r\n\r\n return fontsLoadingPromise;\r\n}\r\n\r\n/**\r\n * Check if a specific font is available/loaded\r\n */\r\nexport function isFontLoaded(fontFamily: string): boolean {\r\n if (typeof document === 'undefined') {\r\n return false;\r\n }\r\n\r\n return document.fonts.check(`48px \"${fontFamily}\"`);\r\n}\r\n\r\n/**\r\n * Wait for a specific font to be ready\r\n */\r\nexport async function waitForFont(fontFamily: string): Promise<boolean> {\r\n if (typeof document === 'undefined') {\r\n return false;\r\n }\r\n\r\n try {\r\n await document.fonts.load(`48px \"${fontFamily}\"`);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport interface GenerateSignatureOptions {\r\n text: string;\r\n fontFamily: string;\r\n width?: number;\r\n height?: number;\r\n fontSize?: number;\r\n color?: string;\r\n backgroundColor?: string | null;\r\n}\r\n\r\n/**\r\n * Generate a signature image from text using a canvas\r\n * @returns PNG data URL (data:image/png;base64,...)\r\n */\r\nexport function generateSignatureFromText(\r\n options: GenerateSignatureOptions\r\n): string {\r\n const {\r\n text,\r\n fontFamily,\r\n width = 450,\r\n height = 200,\r\n fontSize = 48,\r\n color = '#000000',\r\n backgroundColor = null,\r\n } = options;\r\n\r\n const canvas = document.createElement('canvas');\r\n canvas.width = width;\r\n canvas.height = height;\r\n\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) {\r\n throw new Error('Failed to get canvas 2d context');\r\n }\r\n\r\n // Clear canvas or fill with background color\r\n if (backgroundColor) {\r\n ctx.fillStyle = backgroundColor;\r\n ctx.fillRect(0, 0, width, height);\r\n } else {\r\n ctx.clearRect(0, 0, width, height);\r\n }\r\n\r\n // Configure text rendering\r\n ctx.font = `${fontSize}px \"${fontFamily}\"`;\r\n ctx.fillStyle = color;\r\n ctx.textAlign = 'center';\r\n ctx.textBaseline = 'middle';\r\n\r\n // Measure text and adjust font size if needed to fit\r\n let adjustedFontSize = fontSize;\r\n let textMetrics = ctx.measureText(text);\r\n\r\n // If text is too wide, reduce font size\r\n const maxWidth = width * 0.9; // Leave 5% padding on each side\r\n while (textMetrics.width > maxWidth && adjustedFontSize > 16) {\r\n adjustedFontSize -= 2;\r\n ctx.font = `${adjustedFontSize}px \"${fontFamily}\"`;\r\n textMetrics = ctx.measureText(text);\r\n }\r\n\r\n // Draw text centered\r\n ctx.fillText(text, width / 2, height / 2);\r\n\r\n return canvas.toDataURL('image/png');\r\n}\r\n\r\n/**\r\n * Generate signature with automatic font loading\r\n * Ensures the font is loaded before rendering\r\n */\r\nexport async function generateSignatureFromTextAsync(\r\n options: GenerateSignatureOptions\r\n): Promise<string> {\r\n // Load fonts first\r\n await loadSignatureFonts();\r\n\r\n // Wait for the specific font to be ready\r\n await waitForFont(options.fontFamily);\r\n\r\n return generateSignatureFromText(options);\r\n}\r\n","/**\r\n * Lazy loader for pdf-lib\r\n * \r\n * This module provides a lazy loading mechanism for the pdf-lib library (~150KB).\r\n * By deferring the import until actually needed, we can significantly reduce\r\n * the initial bundle size for consumers who only view PDFs without filling forms.\r\n * \r\n * The pdf-lib library is only loaded when:\r\n * - fillPdf() is called\r\n * - combinePdfs() is called\r\n * - Other PDF manipulation functions are used\r\n */\r\n\r\n// Cache the promise to ensure we only import once\r\nlet pdfLibPromise: Promise<typeof import('pdf-lib')> | null = null;\r\n\r\n/**\r\n * Dynamically import pdf-lib library\r\n * \r\n * This function lazily loads pdf-lib only when needed. The import is cached\r\n * so subsequent calls return the same promise, avoiding multiple imports.\r\n * \r\n * @returns Promise resolving to the pdf-lib module\r\n * \r\n * @example\r\n * ```typescript\r\n * const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n * const pdfDoc = await PDFDocument.load(pdfBytes);\r\n * ```\r\n */\r\nexport async function loadPdfLib() {\r\n if (!pdfLibPromise) {\r\n pdfLibPromise = import('pdf-lib');\r\n }\r\n return pdfLibPromise;\r\n}\r\n\r\n/**\r\n * Check if pdf-lib has been loaded\r\n * \r\n * Useful for debugging and testing to verify lazy loading behavior.\r\n * \r\n * @returns true if pdf-lib has been loaded, false otherwise\r\n */\r\nexport function isPdfLibLoaded(): boolean {\r\n return pdfLibPromise !== null;\r\n}\r\n\r\n/**\r\n * Reset the pdf-lib cache (primarily for testing)\r\n * \r\n * This should only be used in test environments to reset state\r\n * between tests.\r\n * \r\n * @internal\r\n */\r\nexport function resetPdfLibCache(): void {\r\n pdfLibPromise = null;\r\n}\r\n\r\n","/**\n * Field Visibility Utilities\n * Core logic for determining which fields are visible/editable in multi-signer mode\n * \n * XIGNIPHI MODEL: All signers are equal - no primary/secondary hierarchy\n * Signers are ordered by signOrder for sequential signing only\n * \n * CRITICAL: This logic must work identically in both flows:\n * - Single-signer flow: isMultiSigner = false, all fields visible\n * - Multi-signer flow: isMultiSigner = true, filtered by assignment rules\n */\n\nimport type { EsignFormField, MultiSignerContext } from '../types';\n\n/**\n * Determine if a field should be visible to the current signer\n * \n * Implements signiphi's simple 4-rule visibility logic:\n * - Rule 1: Unassigned fields → visible to all signers\n * - Rule 2: Direct assignment → show if assigned to current signer\n * - Rule 3: Grouped assignments (\"to-recipients\", \"additional-signers\") → visible to all signers\n * - Rule 4: Assigned to different specific signer → hide\n * \n * @param field - The form field to check\n * @param multiSignerContext - Multi-signer context with current signer info\n * @returns true if field should be visible, false if hidden\n * \n * @example Single-signer flow\n * ```ts\n * const context = { isMultiSigner: false, ... };\n * isFieldVisibleToSigner(anyField, context); // always returns true\n * ```\n * \n * @example Multi-signer flow\n * ```ts\n * const context = {\n * isMultiSigner: true,\n * currentSignerEmail: 'signer1@example.com',\n * isPrimarySigner: false, // Not used in signiphi\n * isFinalSigner: false // Not used in signiphi\n * };\n * \n * // Unassigned field - all signers see it\n * isFieldVisibleToSigner({ assignedSignerEmail: undefined, ... }, context); // true\n * \n * // Direct assignment to current signer\n * isFieldVisibleToSigner({ assignedSignerEmail: 'signer1@example.com', ... }, context); // true\n * \n * // Grouped assignment - all signers see it\n * isFieldVisibleToSigner({ assignedSignerEmail: 'to-recipients', ... }, context); // true\n * ```\n */\nexport function isFieldVisibleToSigner(\n field: EsignFormField,\n multiSignerContext: MultiSignerContext\n): boolean {\n // Single-signer mode: all fields are visible\n if (!multiSignerContext.isMultiSigner) {\n return true;\n }\n\n const { currentSignerEmail } = multiSignerContext;\n\n // RULE 1: Unassigned fields - visible to all signers (signiphi's flat model)\n if (!field.assignedSignerEmail) {\n return true;\n }\n\n // RULE 2: Direct assignment - show if assigned to current signer\n if (field.assignedSignerEmail === currentSignerEmail) {\n return true;\n }\n\n // RULE 3: Grouped assignments - visible to all signers (convenience feature)\n // \"to-recipients\" means field assigned to ALL signers\n // \"additional-signers\" is legacy but works the same way\n if (field.assignedSignerEmail === 'to-recipients' || \n field.assignedSignerEmail === 'additional-signers') {\n return true;\n }\n\n // RULE 4: Assigned to different specific signer - hide\n return false;\n}\n\n/**\n * Filter an array of fields to only those visible to the current signer\n * \n * @param fields - All form fields\n * @param multiSignerContext - Multi-signer context\n * @returns Filtered array of visible fields\n * \n * @example\n * ```ts\n * const allFields = [...]; // 10 fields\n * const context = { isMultiSigner: true, isPrimarySigner: true, ... };\n * const visible = filterFieldsBySigner(allFields, context); // 5 fields (only primary signer's)\n * ```\n */\nexport function filterFieldsBySigner(\n fields: EsignFormField[],\n multiSignerContext: MultiSignerContext\n): EsignFormField[] {\n // Single-signer mode: return all fields\n if (!multiSignerContext.isMultiSigner) {\n return fields;\n }\n\n // Multi-signer mode: filter using visibility logic\n return fields.filter(field => isFieldVisibleToSigner(field, multiSignerContext));\n}\n\n/**\n * Determine if a field should be flattened (made non-editable) by the current signer\n * \n * Used during PDF submission to determine which fields to flatten.\n * In multi-signer mode, only flatten fields assigned to current signer.\n * In single-signer mode, flatten all fields.\n * \n * XIGNIPHI MODEL: Flatten fields visible/assigned to current signer\n * \n * CRITICAL: This affects PDF flattening behavior - must preserve exact logic!\n * \n * @param field - The form field to check\n * @param multiSignerContext - Multi-signer context\n * @returns true if current signer should flatten this field\n * \n * @example Single-signer flow\n * ```ts\n * const context = { isMultiSigner: false, ... };\n * shouldFlattenField(anyField, context); // always returns true\n * ```\n * \n * @example Multi-signer flow\n * ```ts\n * const context = {\n * isMultiSigner: true,\n * currentSignerEmail: 'signer1@example.com',\n * isPrimarySigner: false, // Not used in signiphi\n * isFinalSigner: false // Not used in signiphi\n * };\n * \n * // Current signer's field - flatten it\n * shouldFlattenField({ assignedSignerEmail: 'signer1@example.com', ... }, context); // true\n * \n * // Different signer's field - don't flatten (keep editable for them)\n * shouldFlattenField({ assignedSignerEmail: 'signer2@example.com', ... }, context); // false\n * \n * // Unassigned field - all signers flatten (visible to all)\n * shouldFlattenField({ assignedSignerEmail: undefined, ... }, context); // true\n * ```\n */\nexport function shouldFlattenField(\n field: EsignFormField,\n multiSignerContext: MultiSignerContext\n): boolean {\n // Single-signer mode: flatten all fields\n if (!multiSignerContext.isMultiSigner) {\n return true;\n }\n\n const { currentSignerEmail } = multiSignerContext;\n\n // RULE 1: Unassigned fields - all signers flatten them (visible to all)\n if (!field.assignedSignerEmail) {\n return true;\n }\n\n // RULE 2: Direct assignment - flatten if assigned to current signer\n if (field.assignedSignerEmail === currentSignerEmail) {\n return true;\n }\n\n // RULE 3: Grouped assignments - all signers flatten them (visible to all)\n if (field.assignedSignerEmail === 'to-recipients' || \n field.assignedSignerEmail === 'additional-signers') {\n return true;\n }\n\n // RULE 4: Assigned to different specific signer - DON'T flatten (keep editable for them)\n return false;\n}\n\n","/**\r\n * PDF Widget Helper Utilities\r\n * Common utilities for working with PDF widgets and pages\r\n * \r\n * Used across pdf-manipulation.ts and pdf-viewer-filter.ts\r\n */\r\n\r\nimport type { PDFPage } from 'pdf-lib';\r\n\r\n/**\r\n * Extended type for PDF pages with ref property\r\n */\r\ninterface PDFPageWithRef {\r\n ref: unknown;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Find the page index for a given page reference\r\n * \r\n * This is a common pattern used when working with PDF widgets to determine\r\n * which page a widget belongs to by comparing page references.\r\n * \r\n * @param pages - Array of PDF pages\r\n * @param pageRef - The page reference to search for\r\n * @returns Page index (0-based), or -1 if not found\r\n * \r\n * @example\r\n * ```ts\r\n * const widget = widgets[0];\r\n * const pageRef = widget.P?.();\r\n * const pageIndex = findPageIndexByRef(pages, pageRef);\r\n * if (pageIndex >= 0) {\r\n * const page = pages[pageIndex];\r\n * // Draw on the page\r\n * }\r\n * ```\r\n */\r\nexport function findPageIndexByRef(\r\n pages: PDFPage[],\r\n pageRef: unknown\r\n): number {\r\n if (!pageRef) return -1;\r\n \r\n for (let i = 0; i < pages.length; i++) {\r\n const page = pages[i] as unknown as PDFPageWithRef;\r\n if (page.ref === pageRef) {\r\n return i;\r\n }\r\n }\r\n \r\n return -1;\r\n}\r\n\r\n/**\r\n * Extended type for PDF widgets with rectangle and page methods\r\n */\r\nexport interface PDFWidgetWithExtensions {\r\n getRectangle?: () => { x: number; y: number; width: number; height: number } | undefined;\r\n P?: () => unknown;\r\n}\r\n\r\n/**\r\n * Get widget rectangle and its page\r\n * \r\n * Helper to extract both the rectangle coordinates and the page that a widget\r\n * belongs to in a single operation.\r\n * \r\n * @param widget - The PDF widget\r\n * @param pages - Array of PDF pages\r\n * @returns Object with rect, page, and pageIndex, or null if unable to determine\r\n * \r\n * @example\r\n * ```ts\r\n * for (const widget of widgets) {\r\n * const result = getWidgetRectangleAndPage(widget, pages);\r\n * if (result) {\r\n * const { rect, page, pageIndex } = result;\r\n * // Draw something at rect coordinates on page\r\n * page.drawRectangle({ x: rect.x, y: rect.y, ... });\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function getWidgetRectangleAndPage(\r\n widget: PDFWidgetWithExtensions,\r\n pages: PDFPage[]\r\n): {\r\n rect: { x: number; y: number; width: number; height: number };\r\n page: PDFPage;\r\n pageIndex: number;\r\n} | null {\r\n const rect = widget.getRectangle?.();\r\n if (!rect) return null;\r\n \r\n const pageRef = widget.P?.();\r\n if (!pageRef) return null;\r\n \r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n if (pageIndex === -1) return null;\r\n \r\n const page = pages[pageIndex];\r\n if (!page) return null;\r\n \r\n return { rect, page, pageIndex };\r\n}\r\n\r\n/**\r\n * Find page index with fallback to single-page PDFs\r\n * \r\n * Same as findPageIndexByRef but with a fallback: if pageRef lookup fails\r\n * and there's only one page in the document, returns index 0.\r\n * \r\n * This is useful for label drawing where single-page PDFs might not have\r\n * proper page references but we can safely assume page 0.\r\n * \r\n * @param pages - Array of PDF pages\r\n * @param pageRef - The page reference to search for\r\n * @returns Page index (0-based), 0 if single-page PDF, or -1 if not found\r\n * \r\n * @example\r\n * ```ts\r\n * // Used in pdf-viewer-filter for label drawing\r\n * const pageIndex = findPageIndexWithFallback(pages, pageRef);\r\n * if (pageIndex >= 0) {\r\n * const page = pages[pageIndex];\r\n * page.drawText(label, ...);\r\n * }\r\n * ```\r\n */\r\nexport function findPageIndexWithFallback(\r\n pages: PDFPage[],\r\n pageRef: unknown\r\n): number {\r\n if (!pageRef) {\r\n // No page ref - fallback to page 0 if single-page PDF\r\n return pages.length === 1 ? 0 : -1;\r\n }\r\n \r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n \r\n // If not found but single-page PDF, assume page 0\r\n if (pageIndex === -1 && pages.length === 1) {\r\n return 0;\r\n }\r\n \r\n return pageIndex;\r\n}\r\n\r\n","/**\r\n * PDF Field Type Helper Utilities\r\n * Common utilities for detecting field types and extracting values\r\n *\r\n * Used across pdf-manipulation.ts for consistent field processing\r\n *\r\n * IMPORTANT: Uses duck typing (method detection) instead of constructor.name\r\n * to ensure minification-safe field type detection. Constructor names are\r\n * renamed during minification, breaking string comparisons.\r\n */\r\n\r\n/**\r\n * PDF form field type for operations\r\n */\r\ninterface PDFFormField {\r\n getName(): string;\r\n getText?(): string;\r\n setText?(text: string): void;\r\n isRequired?(): boolean;\r\n isChecked?(): boolean;\r\n check?(): void;\r\n uncheck?(): void;\r\n getSelected?(): string[];\r\n getOptions?(): string[];\r\n select?(value: string): void;\r\n setOptions?(options: string[]): void;\r\n addOptions?(options: string[]): void;\r\n enableReadOnly?(): void;\r\n}\r\n\r\n/**\r\n * Detect the field type from a PDF field using duck typing\r\n *\r\n * Uses method presence detection instead of constructor.name to ensure\r\n * minification-safe field type detection. Each pdf-lib field type has\r\n * unique methods that can be used to identify it.\r\n *\r\n * @param field - The PDF form field\r\n * @returns Standardized field type string\r\n *\r\n * @example\r\n * ```ts\r\n * const fieldType = detectFieldType(field);\r\n * // Returns: 'text', 'checkbox', 'dropdown', 'radiogroup', 'signature', etc.\r\n * ```\r\n */\r\nexport function detectFieldType(field: PDFFormField): string {\r\n const f = field as any;\r\n\r\n // Checkbox: has check/uncheck methods (unique to checkboxes)\r\n if (typeof f.check === 'function' && typeof f.uncheck === 'function') {\r\n return 'checkbox';\r\n }\r\n\r\n // Radio: has select/getOptions but NOT check (distinguishes from checkbox)\r\n // and NOT setOptions (distinguishes from dropdown)\r\n if (typeof f.select === 'function' &&\r\n typeof f.getOptions === 'function' &&\r\n typeof f.check !== 'function' &&\r\n typeof f.setOptions !== 'function') {\r\n return 'radiogroup';\r\n }\r\n\r\n // Dropdown: has select/getOptions AND setOptions or addOptions\r\n if (typeof f.select === 'function' &&\r\n typeof f.getOptions === 'function' &&\r\n (typeof f.setOptions === 'function' || typeof f.addOptions === 'function')) {\r\n return 'dropdown';\r\n }\r\n\r\n // OptionList: has getOptions and setOptions but no select\r\n if (typeof f.getOptions === 'function' &&\r\n typeof f.setOptions === 'function' &&\r\n typeof f.select !== 'function') {\r\n return 'optionlist';\r\n }\r\n\r\n // Text: has getText/setText methods\r\n if (typeof f.getText === 'function' && typeof f.setText === 'function') {\r\n return 'text';\r\n }\r\n\r\n // Signature: no editable methods (no getText, no check, no select)\r\n if (typeof f.getText !== 'function' &&\r\n typeof f.check !== 'function' &&\r\n typeof f.select !== 'function') {\r\n return 'signature';\r\n }\r\n\r\n return 'unknown';\r\n}\r\n\r\n/**\r\n * Extract the current value from a PDF field based on its type\r\n * \r\n * Handles different field types appropriately:\r\n * - Text fields: getText()\r\n * - Checkboxes: isChecked() → 'true'/'false'\r\n * - Dropdowns: getSelected()[0]\r\n * - Radio groups: getSelected()[0]\r\n * \r\n * @param field - The PDF form field\r\n * @param fieldType - The field type (from detectFieldType)\r\n * @returns The field value as a string, or empty string if no value\r\n * \r\n * @example\r\n * ```ts\r\n * const fieldType = detectFieldType(field);\r\n * const value = extractFieldValue(field, fieldType);\r\n * ```\r\n */\r\nexport function extractFieldValue(field: PDFFormField, fieldType: string): string {\r\n try {\r\n switch (fieldType) {\r\n case 'text':\r\n case 'date':\r\n return field.getText?.() || '';\r\n\r\n case 'checkbox':\r\n return field.isChecked?.() ? 'true' : 'false';\r\n\r\n case 'dropdown':\r\n case 'optionlist': {\r\n // Dropdowns return an array from getSelected()\r\n const selected = field.getSelected?.();\r\n return Array.isArray(selected) ? selected[0] || '' : String(selected || '');\r\n }\r\n\r\n case 'radiogroup':\r\n case 'radio': {\r\n // Radio groups return a string from getSelected(), not an array\r\n const radioSelected = field.getSelected?.();\r\n return radioSelected ? String(radioSelected) : '';\r\n }\r\n\r\n default:\r\n return '';\r\n }\r\n } catch (error) {\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Check if a field is required based on field metadata and name patterns\r\n * \r\n * Attempts to determine required status through:\r\n * 1. field.isRequired() method (if available)\r\n * 2. Field name patterns (signature, initials, required)\r\n * 3. Field type (signatures are always required)\r\n * \r\n * @param field - The PDF form field\r\n * @param fieldName - The field name\r\n * @param fieldType - The field type (from detectFieldType)\r\n * @returns true if field is required\r\n * \r\n * @example\r\n * ```ts\r\n * const isRequired = isRequiredField(field, 'signature_1', 'text');\r\n * // Returns: true (signature fields are required)\r\n * ```\r\n */\r\nexport function isRequiredField(\r\n field: PDFFormField,\r\n fieldName: string,\r\n fieldType: string\r\n): boolean {\r\n // Signature fields are always required\r\n if (fieldType === 'signature') {\r\n return true;\r\n }\r\n \r\n // Try the isRequired method if available\r\n try {\r\n if (field.isRequired?.()) {\r\n return true;\r\n }\r\n } catch {\r\n // isRequired() not available or threw error\r\n }\r\n \r\n // Check field name patterns\r\n if (\r\n fieldName.includes('signature') ||\r\n fieldName.includes('initials') ||\r\n fieldName.includes('required')\r\n ) {\r\n return true;\r\n }\r\n \r\n return false;\r\n}\r\n\r\n","/**\r\n * PDF Manipulation Utilities\r\n * Core utilities for PDF processing, page manipulation, and file combining\r\n */\r\n\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\nimport { loadPdfLib } from './pdf-lib-loader';\r\nimport { \r\n PdfPage, \r\n EsignFormField, \r\n FormFieldType, \r\n FormFieldPosition,\r\n MultiSignerContext \r\n} from '../types';\r\nimport { logger } from './logger';\r\nimport { validatePdfBytes, isAutoGeneratedLabel, hasDrawableLabel, getFieldDisplayName } from './pdf-validators';\r\nimport { isFieldVisibleToSigner, shouldFlattenField } from './field-visibility';\r\nimport { findPageIndexByRef, getWidgetRectangleAndPage, type PDFWidgetWithExtensions } from './pdf-widget-helpers';\r\nimport { detectFieldType, extractFieldValue, isRequiredField } from './pdf-field-type-helpers';\r\n\r\n// PDF.js worker is automatically configured by pdfjs-config module\r\n\r\n// Type definitions for PDF internal structures\r\ninterface PDFFieldWithAcro {\r\n getName(): string;\r\n acroField?: {\r\n getWidgets?: () => PDFWidget[];\r\n dict?: any; // PDF dictionary for accessing metadata\r\n };\r\n constructor: { name: string };\r\n}\r\n\r\ninterface PDFWidget {\r\n getRectangle?: () => { x: number; y: number; width: number; height: number };\r\n P?: () => unknown;\r\n}\r\n\r\n/**\r\n * Convert PDF pages to images for rendering in the UI using PDF.js\r\n */\r\nexport async function pdfToImages(\r\n pdfBytes: Uint8Array,\r\n options?: { hideFormFields?: boolean }\r\n): Promise<PdfPage[]> {\r\n try {\r\n // Validate PDF bytes\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n logger.error('Invalid PDF:', validation.error);\r\n throw new Error(validation.error || 'Invalid PDF format');\r\n }\r\n\r\n // Load PDF with PDF.js\r\n const loadingTask = pdfjsLib.getDocument({\r\n data: pdfBytes,\r\n verbosity: 0,\r\n });\r\n const pdfDoc = await loadingTask.promise;\r\n\r\n const pages: PdfPage[] = [];\r\n\r\n // Try to load with pdf-lib for dimension comparison\r\n let pdfLibDoc = null;\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n pdfLibDoc = await PDFDocument.load(pdfBytes);\r\n } catch {\r\n // PDF.js dimensions will be used instead\r\n }\r\n\r\n for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {\r\n const page = await pdfDoc.getPage(pageNum);\r\n const viewport = page.getViewport({ scale: 2.0 });\r\n\r\n // Get actual PDF dimensions\r\n let pdfWidth = viewport.width / 2.0;\r\n let pdfHeight = viewport.height / 2.0;\r\n\r\n // Use pdf-lib dimensions if available for consistency\r\n if (pdfLibDoc) {\r\n try {\r\n const pdfLibPage = pdfLibDoc.getPage(pageNum - 1);\r\n pdfWidth = pdfLibPage.getWidth();\r\n pdfHeight = pdfLibPage.getHeight();\r\n } catch {\r\n // Use PDF.js dimensions as fallback\r\n }\r\n }\r\n\r\n // Create canvas at the scaled size for high quality rendering\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n canvas.height = viewport.height;\r\n canvas.width = viewport.width;\r\n\r\n // Render PDF page to canvas\r\n const hideFormFields = options?.hideFormFields ?? false;\r\n const renderContext: any = {\r\n canvasContext: context,\r\n viewport: viewport,\r\n renderInteractiveForms: !hideFormFields,\r\n ...(hideFormFields && {\r\n annotationMode: 0,\r\n renderAnnotations: false,\r\n renderForms: false,\r\n }),\r\n };\r\n\r\n await page.render(renderContext).promise;\r\n\r\n // Convert canvas to data URL\r\n const imageUrl = canvas.toDataURL('image/png');\r\n\r\n pages.push({\r\n pageNumber: pageNum,\r\n width: pdfWidth,\r\n height: pdfHeight,\r\n imageUrl,\r\n renderWidth: viewport.width,\r\n renderHeight: viewport.height,\r\n });\r\n }\r\n\r\n return pages;\r\n } catch (error) {\r\n logger.error('Error converting PDF to images with PDF.js:', error);\r\n return await fallbackPdfToImages(pdfBytes);\r\n }\r\n}\r\n\r\n/**\r\n * Fallback function to create placeholder images when PDF.js fails\r\n */\r\nasync function fallbackPdfToImages(pdfBytes: Uint8Array): Promise<PdfPage[]> {\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n const pdf = await PDFDocument.load(pdfBytes);\r\n const pages: PdfPage[] = [];\r\n\r\n for (let i = 0; i < pdf.getPageCount(); i++) {\r\n const page = pdf.getPage(i);\r\n const { width, height } = page.getSize();\r\n \r\n // Create placeholder canvas\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n \r\n const scale = 1.5;\r\n canvas.width = width * scale;\r\n canvas.height = height * scale;\r\n \r\n // Draw placeholder\r\n context.fillStyle = '#ffffff';\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n context.strokeStyle = '#e5e7eb';\r\n context.lineWidth = 2;\r\n context.strokeRect(0, 0, canvas.width, canvas.height);\r\n context.fillStyle = '#6b7280';\r\n context.font = 'bold 24px system-ui';\r\n context.textAlign = 'center';\r\n context.fillText(`Page ${i + 1}`, canvas.width / 2, canvas.height / 2 - 20);\r\n context.font = '16px system-ui';\r\n context.fillStyle = '#9ca3af';\r\n context.fillText('PDF preview not available', canvas.width / 2, canvas.height / 2 + 20);\r\n \r\n const imageUrl = canvas.toDataURL('image/png');\r\n \r\n pages.push({\r\n pageNumber: i + 1,\r\n width,\r\n height,\r\n imageUrl,\r\n renderWidth: canvas.width,\r\n renderHeight: canvas.height,\r\n });\r\n }\r\n\r\n return pages;\r\n } catch (error) {\r\n logger.error('Error with pdf-lib fallback:', error);\r\n // Return single error page\r\n return [createErrorPage()];\r\n }\r\n}\r\n\r\n/**\r\n * Create an error page when all processing fails\r\n */\r\nfunction createErrorPage(): PdfPage {\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n canvas.width = 600;\r\n canvas.height = 800;\r\n \r\n context.fillStyle = '#ffffff';\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n context.strokeStyle = '#e5e7eb';\r\n context.lineWidth = 2;\r\n context.strokeRect(0, 0, canvas.width, canvas.height);\r\n context.fillStyle = '#ef4444';\r\n context.font = 'bold 20px system-ui';\r\n context.textAlign = 'center';\r\n context.fillText('PDF Processing Error', canvas.width / 2, canvas.height / 2 - 20);\r\n context.font = '14px system-ui';\r\n context.fillStyle = '#6b7280';\r\n context.fillText('Unable to process the uploaded PDF file', canvas.width / 2, canvas.height / 2 + 20);\r\n \r\n return {\r\n pageNumber: 1,\r\n width: 600,\r\n height: 800,\r\n imageUrl: canvas.toDataURL('image/png'),\r\n renderWidth: canvas.width,\r\n renderHeight: canvas.height,\r\n };\r\n}\r\n\r\n// Type definitions for PDF form field operations\r\ninterface PDFFormField {\r\n getName(): string;\r\n constructor: { name: string };\r\n getText?(): string;\r\n setText?(text: string): void;\r\n isRequired?(): boolean;\r\n isChecked?(): boolean;\r\n getSelected?(): string[];\r\n enableReadOnly?(): void;\r\n}\r\n\r\ninterface PDFFormFieldWithAcro extends PDFFormField {\r\n acroField: {\r\n getWidgets(): unknown[];\r\n removeWidget(index: number): void;\r\n };\r\n}\r\n\r\ninterface PDFDict {\r\n get(key: unknown): unknown;\r\n delete(key: unknown): void;\r\n}\r\n\r\n/**\r\n * Remove all existing form fields from a PDF using robust widget cleanup\r\n * @param pdfBytes - The PDF bytes\r\n * @param stripAllAnnotations - If true, removes all annotations from pages (more aggressive cleanup)\r\n * @returns The PDF bytes with all form fields removed\r\n */\r\nexport async function removeAllFormFields(pdfBytes: Uint8Array, stripAllAnnotations = false): Promise<Uint8Array> {\r\n try {\r\n // Validate PDF data first\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n return pdfBytes;\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n \r\n if (stripAllAnnotations) {\r\n // More aggressive approach: strip all annotations from all pages\r\n const pages = pdfDoc.getPages();\r\n \r\n for (let i = 0; i < pages.length; i++) {\r\n const page = pages[i];\r\n \r\n try {\r\n // Access the page's annotation array\r\n const pageRef = (page as any).ref;\r\n const pageDictObj = pdfDoc.context.lookup(pageRef);\r\n \r\n if (pageDictObj) {\r\n const pageDict = pageDictObj as unknown as PDFDict;\r\n \r\n if (pageDict && pageDict.get && pageDict.delete) {\r\n const annotsRef = pageDict.get((pdfDoc.context as any).obj('Annots'));\r\n \r\n if (annotsRef) {\r\n pageDict.delete((pdfDoc.context as any).obj('Annots'));\r\n }\r\n } else {\r\n }\r\n } else {\r\n }\r\n } catch (pageError) {\r\n }\r\n }\r\n } else {\r\n // Robust widget-based removal approach\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n if (fields.length === 0) {\r\n return pdfBytes;\r\n }\r\n \r\n // Remove all fields using robust widget cleanup\r\n for (const field of fields) {\r\n try {\r\n const acroField = (field as unknown as PDFFormFieldWithAcro).acroField;\r\n if (acroField && typeof acroField.getWidgets === 'function') {\r\n let widgets = acroField.getWidgets();\r\n \r\n // Remove widgets one by one with safety counter\r\n let safetyCounter = 0;\r\n const maxIterations = widgets.length + 5;\r\n \r\n while (widgets.length > 0 && safetyCounter < maxIterations) {\r\n try {\r\n const widgetIndex = widgets.length - 1;\r\n acroField.removeWidget(widgetIndex);\r\n widgets = acroField.getWidgets();\r\n } catch (widgetError) {\r\n break;\r\n }\r\n safetyCounter++;\r\n }\r\n \r\n if (safetyCounter >= maxIterations) {\r\n }\r\n }\r\n \r\n form.removeField(field as any);\r\n } catch (error) {\r\n \r\n try {\r\n form.removeField(field as any);\r\n } catch (fallbackError) {\r\n }\r\n }\r\n }\r\n \r\n const remainingFields = form.getFields();\r\n if (remainingFields.length > 0) {\r\n }\r\n }\r\n \r\n const updatedPdfBytes = await pdfDoc.save();\r\n return updatedPdfBytes;\r\n } catch (error) {\r\n logger.error('Error removing form fields from PDF:', error);\r\n return pdfBytes;\r\n }\r\n}\r\n\r\n/**\r\n * Read existing PDF form fields and their properties\r\n */\r\nexport async function readPdfFormFields(pdfBytes: Uint8Array): Promise<{\r\n name: string;\r\n type: string;\r\n required: boolean;\r\n value?: string;\r\n}[]> {\r\n try {\r\n // Validate PDF data first\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n return [];\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n if (fields.length === 0) {\r\n return [];\r\n }\r\n \r\n const formFields = fields.map(field => {\r\n const fieldName = field.getName();\r\n const pdfField = field as unknown as PDFFormField;\r\n \r\n try {\r\n // Use centralized field type detection and value extraction\r\n const fieldType = detectFieldType(pdfField);\r\n const value = extractFieldValue(pdfField, fieldType);\r\n const required = isRequiredField(pdfField, fieldName, fieldType);\r\n \r\n return {\r\n name: fieldName,\r\n type: fieldType,\r\n required,\r\n value\r\n };\r\n } catch (fieldError) {\r\n // Fallback to defaults on error\r\n return {\r\n name: fieldName,\r\n type: 'text',\r\n required: false,\r\n value: ''\r\n };\r\n }\r\n });\r\n \r\n return formFields;\r\n } catch (error) {\r\n logger.error('Error reading PDF form fields:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Read current PDF form field values (including user-filled data)\r\n */\r\nexport async function readCurrentPdfFormValues(pdfBytes: Uint8Array): Promise<Record<string, string>> {\r\n try {\r\n if (!pdfBytes || pdfBytes.length === 0) {\r\n return {};\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n const currentValues: Record<string, string> = {};\r\n \r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const pdfField = field as unknown as PDFFormField;\r\n \r\n try {\r\n // Use centralized field type detection and value extraction\r\n const fieldType = detectFieldType(pdfField);\r\n const value = extractFieldValue(pdfField, fieldType);\r\n \r\n currentValues[fieldName] = value;\r\n } catch (fieldError) {\r\n currentValues[fieldName] = '';\r\n }\r\n }\r\n \r\n return currentValues;\r\n } catch (error) {\r\n logger.error('Error reading current PDF form values:', error);\r\n return {};\r\n }\r\n}\r\n\r\n/**\r\n * Validate PDF form fields against provided values\r\n * In multi-signer mode, only validates fields visible to the current signer\r\n */\r\nexport async function validatePdfFormFields(\r\n pdfBytes: Uint8Array,\r\n fieldValues: Record<string, string>,\r\n signatures: Record<string, string>,\r\n extractedFields?: EsignFormField[], // Pass extracted fields to know which are visible\r\n multiSignerContext?: MultiSignerContext // Pass context to filter validation\r\n): Promise<string[]> {\r\n try {\r\n const pdfFormFields = await readPdfFormFields(pdfBytes);\r\n const errors: string[] = [];\r\n \r\n \r\n for (const field of pdfFormFields) {\r\n if (field.required) {\r\n // Look up the matching extracted field for proper label/type info\r\n const extractedField = extractedFields?.find(f => f.name === field.name);\r\n\r\n // In multi-signer mode, only validate fields visible to current signer\r\n if (multiSignerContext?.isMultiSigner && extractedFields) {\r\n if (!extractedField) {\r\n // Field not in extractedFields means it's not visible to current signer\r\n continue;\r\n }\r\n }\r\n\r\n // Skip fields already validated at the SubmissionForm level (date, signature, initials)\r\n // to avoid duplicate error messages. The raw PDF type for dates is 'text', so we\r\n // use the extractedField type which has the correct logical type.\r\n const logicalType = extractedField?.type || field.type;\r\n if (logicalType === 'date' || logicalType === 'signature' || logicalType === 'initials') {\r\n continue;\r\n }\r\n\r\n let hasValue = false;\r\n const fieldValue = fieldValues[field.name];\r\n const signatureValue = signatures[field.name];\r\n const mainSignature = signatures['signature_field_main'];\r\n const mainInitials = signatures['initials_field_main'] || fieldValues['initials_field_main'];\r\n\r\n if (field.name.includes('signature') || field.type === 'signature') {\r\n hasValue = !!(signatureValue || fieldValue || mainSignature);\r\n } else if (field.name.includes('initials')) {\r\n hasValue = !!(signatureValue || fieldValue || mainInitials);\r\n } else if (field.type === 'checkbox' || logicalType === 'checkbox') {\r\n // Checkbox: value is 'true'/'false' string - must be specifically 'true' (checked)\r\n hasValue = fieldValue === 'true' || field.value === 'true';\r\n } else {\r\n hasValue = !!(fieldValue || field.value);\r\n }\r\n\r\n if (!hasValue) {\r\n // Use extractedField label and type for proper display names\r\n const friendlyName = getFieldDisplayName({\r\n label: extractedField?.label,\r\n name: field.name,\r\n type: logicalType\r\n });\r\n\r\n errors.push(`${friendlyName} is required`);\r\n }\r\n }\r\n }\r\n\r\n return errors;\r\n } catch (error) {\r\n logger.error('Error validating PDF form fields:', error);\r\n return ['Unable to validate form fields. Please ensure all required fields are completed.'];\r\n }\r\n}\r\n\r\n/**\r\n * Validate PDF form fields against current form state\r\n */\r\nexport async function validateCurrentPdfState(\r\n pdfBytes: Uint8Array,\r\n signatures: Record<string, string>,\r\n formFieldValues: Record<string, string> = {}\r\n): Promise<string[]> {\r\n try {\r\n const pdfFormFields = await readPdfFormFields(pdfBytes);\r\n const currentValues = await readCurrentPdfFormValues(pdfBytes);\r\n const errors: string[] = [];\r\n \r\n for (const field of pdfFormFields) {\r\n const isSignatureField = field.name.includes('signature') && field.type === 'text';\r\n const isInitialsField = field.name.includes('initials') && field.type === 'text';\r\n \r\n if (field.required || isSignatureField || isInitialsField) {\r\n let hasValue = false;\r\n const currentValue = currentValues[field.name] || '';\r\n \r\n if (isSignatureField) {\r\n hasValue = !!signatures[field.name];\r\n } else if (isInitialsField) {\r\n hasValue = !!signatures[field.name] || !!(formFieldValues[field.name]?.trim()) || currentValue.trim() !== '';\r\n } else {\r\n hasValue = currentValue.trim() !== '';\r\n }\r\n \r\n if (!hasValue) {\r\n // Use centralized friendly name logic that handles auto-generated labels\r\n const friendlyName = getFieldDisplayName({\r\n name: field.name,\r\n type: field.type\r\n });\r\n\r\n errors.push(`${friendlyName} is required`);\r\n }\r\n }\r\n }\r\n\r\n return errors;\r\n } catch (error) {\r\n logger.error('Error validating current PDF state:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Helper function to extract font size from a field\r\n * Priority: 1) extractedFormFields metadata, 2) DA field, 3) TU field, 4) default 10px\r\n */\r\nfunction extractFieldFontSize(\r\n fieldName: string,\r\n field: any,\r\n extractedFormFields?: EsignFormField[]\r\n): number {\r\n const DEFAULT_FONT_SIZE = 10;\r\n const MIN_FONT_SIZE = 8;\r\n const MAX_FONT_SIZE = 72;\r\n\r\n // 1. Try extractedFormFields metadata first (runtime information)\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n if (fieldInfo?.fontSize && fieldInfo.fontSize >= MIN_FONT_SIZE && fieldInfo.fontSize <= MAX_FONT_SIZE) {\r\n return fieldInfo.fontSize;\r\n }\r\n\r\n // 2. Try DA (Default Appearance) field - standard PDF font size location\r\n const daFontSize = extractFromDAField(field);\r\n if (daFontSize !== null) {\r\n return daFontSize;\r\n }\r\n\r\n // 3. Try TU (alternate text) field - custom fontSize metadata format\r\n const tuFontSize = extractFromTUField(field);\r\n if (tuFontSize !== null) {\r\n return tuFontSize;\r\n }\r\n\r\n // 4. Default fallback\r\n return DEFAULT_FONT_SIZE;\r\n}\r\n\r\n/**\r\n * Extract font size from DA (Default Appearance) field\r\n * Format: \"0 0 0 rg\\n/Helvetica 16 Tf\"\r\n */\r\nfunction extractFromDAField(field: any): number | null {\r\n try {\r\n const fieldWithAcro = field as unknown as PDFFieldWithAcro;\r\n const dict = fieldWithAcro.acroField?.dict;\r\n if (!dict) return null;\r\n\r\n const daKey = dict.context?.obj?.('DA') || 'DA';\r\n const daEntry = dict.lookup?.(daKey) || dict.get?.(daKey);\r\n if (!daEntry) return null;\r\n\r\n // Get DA string value\r\n let daValue = '';\r\n if (typeof daEntry.decodeText === 'function') {\r\n daValue = daEntry.decodeText();\r\n } else if (typeof daEntry.asString === 'function') {\r\n daValue = daEntry.asString();\r\n } else {\r\n daValue = String(daEntry);\r\n }\r\n\r\n // Match pattern like \"/Helvetica 24 Tf\" or \"24 Tf\"\r\n const daMatch = daValue.match(/\\s+(\\d+)\\s+Tf/i);\r\n if (daMatch?.[1]) {\r\n const fontSize = parseInt(daMatch[1], 10);\r\n if (fontSize >= 8 && fontSize <= 72) {\r\n return fontSize;\r\n }\r\n }\r\n } catch {\r\n // Silently fail\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Extract font size from TU (alternate text) field\r\n * Format: \"Label Text|fontSize:16\"\r\n */\r\nfunction extractFromTUField(field: any): number | null {\r\n try {\r\n const fieldWithAcro = field as unknown as PDFFieldWithAcro;\r\n const dict = fieldWithAcro.acroField?.dict;\r\n if (!dict) return null;\r\n\r\n const tuKey = dict.context?.obj?.('TU') || 'TU';\r\n const tuEntry = dict.lookup?.(tuKey) || dict.get?.(tuKey);\r\n if (!tuEntry) return null;\r\n\r\n // Get TU string value\r\n let tuValue = '';\r\n if (typeof tuEntry.decodeText === 'function') {\r\n tuValue = tuEntry.decodeText();\r\n } else if (typeof tuEntry.asString === 'function') {\r\n tuValue = tuEntry.asString();\r\n } else {\r\n tuValue = String(tuEntry);\r\n }\r\n\r\n // Parse custom format: \"Label|fontSize:16\"\r\n tuValue = tuValue.replace(/^\\(|\\)$|^<|>$/g, '');\r\n const match = tuValue.match(/\\|fontSize:(\\d+)$/);\r\n if (match?.[1]) {\r\n const fontSize = parseInt(match[1], 10);\r\n if (fontSize >= 8 && fontSize <= 72) {\r\n return fontSize;\r\n }\r\n }\r\n } catch {\r\n // Silently fail\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Fill PDF with signature images and form field values, then flatten the form\r\n * @param pdfBytes - The PDF bytes\r\n * @param signatures - The signature data URLs (field name -> base64 PNG)\r\n * @param formFieldValues - The form field values to fill\r\n * @returns The filled and flattened PDF bytes\r\n */\r\nexport async function fillPdfWithSignatures(\r\n pdfBytes: Uint8Array,\r\n signatures: Record<string, string>,\r\n formFieldValues: Record<string, string> = {},\r\n _currentSignerEmail?: string, // Deprecated: use multiSignerContext.currentSignerEmail instead\r\n extractedFormFields?: EsignFormField[],\r\n metadata?: { submissionId?: string; documentId?: string; author?: string; signerEmail?: string; signerInitials?: string; createdAt?: Date },\r\n auditTrail?: { userAgent?: string; screenResolution?: string; timezone?: string; language?: string; platform?: string; ipAddress?: string; geolocation?: { latitude: number; longitude: number; accuracy?: number } },\r\n multiSignerContext?: { isMultiSigner: boolean; currentSigner: any; currentSignerEmail: string; isPrimarySigner: boolean; isFinalSigner: boolean }\r\n): Promise<Uint8Array> {\r\n try {\r\n const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const pages = pdfDoc.getPages();\r\n \r\n // Get field positions and page numbers\r\n const { pageMap: fieldPageMap, positionMap: fieldPositionMap } = await getFieldPageNumbers(pdfBytes);\r\n \r\n // STEP 1: Fill all text form fields\r\n \r\n const fields = form.getFields();\r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const fieldValue = formFieldValues[fieldName];\r\n \r\n if (!fieldValue) {\r\n // Log missing values for radio fields to diagnose\r\n if (fieldName.includes('radio')) {\r\n }\r\n continue;\r\n }\r\n \r\n try {\r\n // Use duck typing for field type detection (minification-safe)\r\n // Constructor names get renamed during minification, breaking string comparisons\r\n const f = field as any;\r\n const isTextField = typeof f.getText === 'function' && typeof f.setText === 'function';\r\n const isCheckbox = typeof f.check === 'function' && typeof f.uncheck === 'function';\r\n const isRadio = typeof f.select === 'function' &&\r\n typeof f.getOptions === 'function' &&\r\n typeof f.check !== 'function' &&\r\n typeof f.setOptions !== 'function';\r\n const isDropdown = typeof f.select === 'function' &&\r\n (typeof f.setOptions === 'function' || typeof f.addOptions === 'function');\r\n\r\n // Handle text fields\r\n if (isTextField) {\r\n f.setText?.(fieldValue);\r\n }\r\n // Handle checkbox fields\r\n else if (isCheckbox) {\r\n if (fieldValue === 'true' || fieldValue === 'Yes' || fieldValue === 'checked' || fieldValue === 'On') {\r\n f.check?.();\r\n } else {\r\n f.uncheck?.();\r\n }\r\n }\r\n // Handle radio group fields\r\n else if (isRadio) {\r\n // Skip invalid values (boolean strings from checkbox-like behavior)\r\n if (fieldValue === 'true' || fieldValue === 'false') {\r\n continue;\r\n }\r\n\r\n // Handle __RADIO_OPTION_INDEX_ pattern\r\n const idxMatch = fieldValue.match(/__RADIO_OPTION_INDEX_(\\d+)__/);\r\n if (idxMatch && idxMatch[1]) {\r\n const selectedIndex = parseInt(idxMatch[1], 10);\r\n const options = f.getOptions?.() || [];\r\n if (selectedIndex >= 0 && selectedIndex < options.length) {\r\n f.select?.(options[selectedIndex]);\r\n }\r\n } else {\r\n // Try to use the value directly if it's a valid option\r\n const options = f.getOptions?.() || [];\r\n if (options.includes(fieldValue)) {\r\n f.select?.(fieldValue);\r\n } else {\r\n }\r\n }\r\n }\r\n // Handle dropdown fields\r\n else if (isDropdown) {\r\n f.select?.(fieldValue);\r\n }\r\n } catch (fieldError) {\r\n logger.error(`Error setting field \"${fieldName}\":`, fieldError);\r\n }\r\n }\r\n\r\n // Update form field appearances to ensure radio button selections render correctly\r\n // This is critical for radio buttons to display properly in PDF viewers\r\n // Fix based on dm-web-frontend commit aafc786 (Oct 29, 2025)\r\n try {\r\n form.updateFieldAppearances();\r\n \r\n // NOTE: We skip setting NeedAppearances to false because accessing the catalog\r\n // can corrupt the PDF structure. Modern PDF viewers handle this correctly without it.\r\n \r\n } catch (appearanceError) {\r\n // Some PDFs may not support this operation - fail gracefully\r\n logger.warn('Could not update field appearances:', appearanceError);\r\n }\r\n\r\n // STEP 2: Apply signature images to ALL signature fields\r\n const mainSignatureData = signatures['signature_field_main'];\r\n if (mainSignatureData && mainSignatureData.trim()) {\r\n \r\n // Find ALL signature field names (excluding text_ prefix and non-signature fields)\r\n // Match dockmaster patterns including '_es_:signer:signature' for esign integration\r\n const signatureFieldNames = [\r\n 'signature', 'Signature', 'SIGNATURE',\r\n 'sign', 'Sign', 'SIGN',\r\n '_es_:signer:signature'\r\n ];\r\n let foundSignatureFields = Object.keys(fieldPageMap).filter(fieldName => {\r\n const hasSignaturePattern = signatureFieldNames.some(pattern => \r\n fieldName.toLowerCase().includes(pattern.toLowerCase())\r\n );\r\n const isNotTextField = !fieldName.toLowerCase().startsWith('text_');\r\n return hasSignaturePattern && isNotTextField;\r\n });\r\n \r\n // CRITICAL: Filter to only ACTUAL signature fields, not checkbox/radio/dropdown\r\n if (extractedFormFields && extractedFormFields.length > 0) {\r\n const currentSignerSignatureFields = foundSignatureFields.filter(fieldName => {\r\n const fieldInfo = extractedFormFields.find(f => f.name === fieldName);\r\n if (!fieldInfo) {\r\n return false;\r\n }\r\n \r\n // CRITICAL FIX: Only process ACTUAL signature fields, NOT initials\r\n // Signature images should ONLY be applied to signature fields\r\n // Initials are handled separately as text (not images)\r\n // Fix based on dm-web-frontend commit 30895b5 (Oct 29, 2025)\r\n const isActualSignatureField = (fieldInfo.type === 'signature' ||\r\n fieldName.toLowerCase().includes('signature'))\r\n && !fieldName.toLowerCase().includes('initials'); // Explicitly exclude initials\r\n\r\n if (!isActualSignatureField) {\r\n return false;\r\n }\r\n \r\n // Use centralized visibility logic for multi-signer and single-signer modes\r\n const isVisible = multiSignerContext \r\n ? isFieldVisibleToSigner(fieldInfo, multiSignerContext)\r\n : true; // Single signer mode: all fields visible\r\n \r\n return isVisible;\r\n });\r\n foundSignatureFields = currentSignerSignatureFields;\r\n }\r\n \r\n \r\n if (foundSignatureFields.length > 0) {\r\n try {\r\n // Detect image format with binary signature detection\r\n let signatureImage;\r\n if (mainSignatureData.includes('data:image/png')) {\r\n signatureImage = await pdfDoc.embedPng(mainSignatureData);\r\n } else if (mainSignatureData.includes('data:image/jpeg') || mainSignatureData.includes('data:image/jpg')) {\r\n signatureImage = await pdfDoc.embedJpg(mainSignatureData);\r\n } else {\r\n // Fallback: detect by binary signature\r\n const base64Data = mainSignatureData.split(',')[1];\r\n if (!base64Data) {\r\n throw new Error('Invalid signature data format: missing base64 data');\r\n }\r\n const binaryData = atob(base64Data);\r\n \r\n // Check PNG signature (first 8 bytes: 89 50 4E 47 0D 0A 1A 0A)\r\n if (binaryData.charCodeAt(0) === 0x89 && \r\n binaryData.charCodeAt(1) === 0x50 && \r\n binaryData.charCodeAt(2) === 0x4E && \r\n binaryData.charCodeAt(3) === 0x47) {\r\n signatureImage = await pdfDoc.embedPng(mainSignatureData);\r\n } \r\n // Check JPEG signature (first 3 bytes: FF D8 FF)\r\n else if (binaryData.charCodeAt(0) === 0xFF && \r\n binaryData.charCodeAt(1) === 0xD8 && \r\n binaryData.charCodeAt(2) === 0xFF) {\r\n signatureImage = await pdfDoc.embedJpg(mainSignatureData);\r\n } \r\n else {\r\n throw new Error('Unsupported image format. Please use PNG or JPEG.');\r\n }\r\n }\r\n \r\n // Draw signature images using EXACT field coordinates\r\n for (const fieldName of foundSignatureFields) {\r\n \r\n const pageNumber = fieldPageMap[fieldName];\r\n \r\n if (pageNumber && pageNumber <= pages.length) {\r\n const page = pages[pageNumber - 1]; // Convert to 0-based index\r\n if (!page) continue;\r\n \r\n // Get EXACT field position from the map\r\n const fieldPosition = fieldPositionMap[fieldName];\r\n \r\n if (fieldPosition) {\r\n // Use EXACT field coordinates (NO CENTERING)\r\n const x = fieldPosition.x;\r\n const y = fieldPosition.y;\r\n const width = Math.max(fieldPosition.width, 80);\r\n const height = Math.max(fieldPosition.height, 30);\r\n \r\n // Draw label above signature field (same sizing as text fields)\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n if (fieldInfo && hasDrawableLabel(fieldInfo)) {\r\n const labelFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n const labelFontSize = Math.min(10, height * 0.4);\r\n const labelX = x;\r\n const labelY = y + height + 5; // Above the field\r\n page.drawText(fieldInfo.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Scale signature to fit the field\r\n const signatureDims = signatureImage.scaleToFit(width - 4, height - 4);\r\n \r\n // FIXED POSITIONING: Use exact field coordinates\r\n const finalX = x;\r\n const finalY = y;\r\n \r\n \r\n page.drawImage(signatureImage, {\r\n x: finalX,\r\n y: finalY,\r\n width: signatureDims.width,\r\n height: signatureDims.height,\r\n });\r\n \r\n } else {\r\n }\r\n } else {\r\n }\r\n }\r\n } catch (error) {\r\n logger.error('Error applying signatures:', error);\r\n }\r\n }\r\n }\r\n \r\n // STEP 3: Apply initials to ALL initials fields\r\n console.log('[FLATTEN] === APPLYING INITIALS ===');\r\n console.log('[FLATTEN] formFieldValues keys:', Object.keys(formFieldValues));\r\n console.log('[FLATTEN] Initials fields in formFieldValues:', Object.keys(formFieldValues).filter(k => k.toLowerCase().includes('initials')));\r\n const mainInitialsData = formFieldValues['initials_field_main'];\r\n console.log('[FLATTEN] mainInitialsData from initials_field_main:', mainInitialsData ? mainInitialsData.substring(0, 50) : '(MISSING)');\r\n if (mainInitialsData && mainInitialsData.trim()) {\r\n \r\n console.log('[FLATTEN] fieldPageMap keys:', Object.keys(fieldPageMap));\r\n console.log('[FLATTEN] Looking for initials fields in fieldPageMap...');\r\n\r\n const initialsFieldNames = ['initials', 'Initials', 'INITIALS'];\r\n let foundInitialsFields = Object.keys(fieldPageMap).filter(fieldName =>\r\n initialsFieldNames.some(pattern => fieldName.toLowerCase().includes(pattern.toLowerCase()))\r\n );\r\n console.log('[FLATTEN] After pattern matching in fieldPageMap:', foundInitialsFields);\r\n\r\n // Filter by signer if needed\r\n if (extractedFormFields && extractedFormFields.length > 0) {\r\n foundInitialsFields = foundInitialsFields.filter(fieldName => {\r\n // Try exact name match first, then strip suffix for fallback\r\n const fieldInfo = extractedFormFields.find(f => f.name === fieldName)\r\n || extractedFormFields.find(f => f.name === fieldName.replace(/_initials$/i, ''))\r\n || extractedFormFields.find(f => fieldName.startsWith(f.name));\r\n if (!fieldInfo) return false;\r\n\r\n const isActualInitialsField = fieldInfo.type === 'initials' ||\r\n fieldName.toLowerCase().includes('initials');\r\n if (!isActualInitialsField) return false;\r\n\r\n // Use centralized visibility logic for multi-signer and single-signer modes\r\n const isVisible = multiSignerContext\r\n ? isFieldVisibleToSigner(fieldInfo, multiSignerContext)\r\n : true; // Single signer mode: all fields visible\r\n\r\n return isVisible;\r\n });\r\n }\r\n\r\n console.log('[FLATTEN] Found', foundInitialsFields.length, 'initials fields to flatten:', foundInitialsFields);\r\n if (foundInitialsFields.length > 0) {\r\n try {\r\n const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n\r\n for (const fieldName of foundInitialsFields) {\r\n console.log('[FLATTEN] Processing initials field:', fieldName);\r\n const pageNumber = fieldPageMap[fieldName];\r\n console.log('[FLATTEN] Page number:', pageNumber);\r\n if (pageNumber && pageNumber <= pages.length) {\r\n const page = pages[pageNumber - 1];\r\n if (!page) {\r\n console.log('[FLATTEN] ❌ Page not found');\r\n continue;\r\n }\r\n\r\n const fieldPosition = fieldPositionMap[fieldName];\r\n console.log('[FLATTEN] Field position:', fieldPosition);\r\n if (fieldPosition) {\r\n const x = fieldPosition.x;\r\n const y = fieldPosition.y;\r\n const height = Math.max(fieldPosition.height, 20);\r\n\r\n const fontSize = Math.min(height * 0.7, 14);\r\n\r\n // Draw label above initials field\r\n // Try multiple matching strategies: exact name, stripped suffix, prefix, fieldId\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName)\r\n || extractedFormFields?.find(f => f.name === fieldName.replace(/_initials$/i, ''))\r\n || extractedFormFields?.find(f => fieldName.startsWith(f.name))\r\n || extractedFormFields?.find(f => f.fieldId && fieldName.includes(f.fieldId))\r\n || extractedFormFields?.find(f => f.type === 'initials' && f.name !== 'initials_field_main');\r\n if (fieldInfo && hasDrawableLabel(fieldInfo)) {\r\n const labelFontSize = Math.min(10, height * 0.4);\r\n const labelX = x;\r\n const labelY = y + height + 5; // Above the field\r\n page.drawText(fieldInfo.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n\r\n // EXACT positioning (no centering)\r\n const finalX = x + 2;\r\n const finalY = y + (height - fontSize) / 2;\r\n\r\n console.log('[FLATTEN] ✅ Drawing initials at:', { x: finalX, y: finalY, fontSize, text: mainInitialsData });\r\n page.drawText(mainInitialsData, {\r\n x: finalX,\r\n y: finalY,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n\r\n } else {\r\n console.log('[FLATTEN] ❌ Field position not found in position map');\r\n }\r\n } else {\r\n console.log('[FLATTEN] ❌ Invalid page number or page out of bounds');\r\n }\r\n }\r\n } catch (error) {\r\n logger.error('Error applying initials:', error);\r\n }\r\n }\r\n }\r\n \r\n // STEP 4: Flatten form fields based on multi-signer mode\r\n \r\n const allFormFields = form.getFields();\r\n \r\n let fieldsToFlatten;\r\n \r\n if (multiSignerContext?.isMultiSigner) {\r\n // PARTIAL FLATTENING: Only flatten current signer's fields (Dockmaster logic lines 2500-2526)\r\n \r\n fieldsToFlatten = allFormFields.filter(f => {\r\n const fieldName = f.getName();\r\n \r\n if (!extractedFormFields || extractedFormFields.length === 0) {\r\n return true; // Flatten all if no field info\r\n }\r\n \r\n const fieldInfo = extractedFormFields.find(fi => fi.name === fieldName);\r\n if (!fieldInfo) {\r\n return true; // Flatten unknown fields\r\n }\r\n \r\n // Use centralized flattening logic\r\n return shouldFlattenField(fieldInfo, multiSignerContext);\r\n });\r\n } else {\r\n // COMPLETE FLATTENING: Flatten all fields (single signer mode)\r\n fieldsToFlatten = allFormFields;\r\n }\r\n \r\n // Helper interfaces for widget access\r\n interface PDFFieldWithAcro {\r\n acroField?: {\r\n getWidgets?: () => PDFWidget[];\r\n dict?: any;\r\n };\r\n }\r\n \r\n let flattenedCount = 0;\r\n \r\n for (const field of fieldsToFlatten) {\r\n const fieldName = field.getName();\r\n\r\n // Use duck typing for field type detection (minification-safe)\r\n // Constructor names get renamed during minification, breaking string comparisons\r\n const f = field as any;\r\n const isCheckboxField = typeof f.check === 'function' && typeof f.uncheck === 'function';\r\n const isRadioField = typeof f.select === 'function' &&\r\n typeof f.getOptions === 'function' &&\r\n typeof f.check !== 'function' &&\r\n typeof f.setOptions !== 'function';\r\n const isDropdownField = typeof f.select === 'function' &&\r\n (typeof f.setOptions === 'function' || typeof f.addOptions === 'function');\r\n const isTextField = typeof f.getText === 'function' && typeof f.setText === 'function';\r\n // Signature fields have no editable methods\r\n const isSignatureType = !isCheckboxField && !isRadioField && !isDropdownField && !isTextField;\r\n\r\n try {\r\n // Get user entered value\r\n const userEnteredValue = formFieldValues[fieldName];\r\n\r\n // Check if this is a signature/initials field\r\n const isSignatureField = fieldName.toLowerCase().includes('signature') || isSignatureType;\r\n const isInitialsField = fieldName.toLowerCase().includes('initials');\r\n\r\n if (isSignatureField || isInitialsField) {\r\n // Signature/initials fields were already drawn in STEP 2/3, just remove the field\r\n form.removeField(field);\r\n flattenedCount++;\r\n continue;\r\n }\r\n\r\n // Get field widgets for drawing\r\n const fieldWithWidgets = field as unknown as PDFFieldWithAcro;\r\n const widgets = fieldWithWidgets.acroField?.getWidgets?.() || [];\r\n\r\n // Handle different field types - draw their content\r\n if (isCheckboxField) {\r\n // Checkbox field - draw checkbox with checkmark if checked\r\n const stringValue = String(userEnteredValue || '');\r\n const isChecked = stringValue === 'true' || stringValue === 'Yes' || \r\n stringValue === 'On' || stringValue === 'checked';\r\n \r\n // Get field info for label\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n const labelFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n \r\n if (isChecked) {\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw checkbox label to the right\r\n if (fieldInfo && hasDrawableLabel(fieldInfo)) {\r\n const labelFontSize = Math.min(10, rect.height * 0.4);\r\n const labelX = rect.x + rect.width + 5; // To the right of checkbox\r\n const labelY = rect.y + (rect.height - labelFontSize) / 2;\r\n page.drawText(fieldInfo.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw checkbox border - use full field rect size\r\n const checkboxSize = Math.min(rect.width, rect.height);\r\n const checkboxX = rect.x + (rect.width - checkboxSize) / 2;\r\n const checkboxY = rect.y + (rect.height - checkboxSize) / 2;\r\n\r\n page.drawRectangle({\r\n x: checkboxX,\r\n y: checkboxY,\r\n width: checkboxSize,\r\n height: checkboxSize,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n });\r\n\r\n // Draw X using proper font metrics for centering\r\n const checkFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n const checkFontSize = checkboxSize * 0.7;\r\n const textWidth = checkFont.widthOfTextAtSize('X', checkFontSize);\r\n const textHeight = checkFont.heightAtSize(checkFontSize);\r\n\r\n page.drawText('X', {\r\n x: checkboxX + (checkboxSize - textWidth) / 2,\r\n y: checkboxY + (checkboxSize - textHeight) / 2 + textHeight * 0.15,\r\n size: checkFontSize,\r\n font: checkFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n } else {\r\n // Draw checkbox border and label even when unchecked\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw checkbox border (empty, no checkmark) - use full field rect size\r\n const checkboxSize = Math.min(rect.width, rect.height);\r\n const checkboxX = rect.x + (rect.width - checkboxSize) / 2;\r\n const checkboxY = rect.y + (rect.height - checkboxSize) / 2;\r\n\r\n page.drawRectangle({\r\n x: checkboxX,\r\n y: checkboxY,\r\n width: checkboxSize,\r\n height: checkboxSize,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n });\r\n \r\n // Draw label if present\r\n if (fieldInfo && hasDrawableLabel(fieldInfo)) {\r\n const labelFontSize = Math.min(12, rect.height * 0.6);\r\n const labelX = rect.x + rect.width + 5;\r\n const labelY = rect.y + (rect.height - labelFontSize) / 2;\r\n page.drawText(fieldInfo.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n }\r\n }\r\n } else if (isRadioField) {\r\n // Radio group field - draw all radio buttons, fill the selected one\r\n const radioGroup = f;\r\n \r\n // Get field info for labels and options (need this before determining selectedIndex)\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n \r\n // Get the ACTUAL selected value from the PDF field (after it was set)\r\n let actualSelectedValue = '';\r\n try {\r\n actualSelectedValue = radioGroup.getSelected?.() || '';\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: radioGroup.getSelected() returned: \"${actualSelectedValue}\"`);\r\n } catch (e) {\r\n // Fallback to user entered value if we can't read the field\r\n actualSelectedValue = userEnteredValue ? String(userEnteredValue) : '';\r\n logger.warn(`[FLATTEN RADIO] Field ${fieldName}: could not read selected value, using userEnteredValue: \"${actualSelectedValue}\"`);\r\n }\r\n \r\n // Determine selected index\r\n let selectedIndex = -1;\r\n \r\n // Get all options from the radio group\r\n const radioOptions = radioGroup.getOptions?.() || [];\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: radioGroup.getOptions() returned ${radioOptions.length} options:`, radioOptions);\r\n \r\n // If we have an actual selected value from the field, find its index\r\n if (actualSelectedValue && radioOptions.length > 0) {\r\n selectedIndex = radioOptions.findIndex((opt: string) => opt === actualSelectedValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: found actualSelectedValue \"${actualSelectedValue}\" at index ${selectedIndex}`);\r\n }\r\n \r\n // Fallback: try to parse from user entered value if we didn't find it above\r\n if (selectedIndex === -1 && userEnteredValue) {\r\n const selectedValue = String(userEnteredValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: selectedIndex still -1, trying to parse from userEnteredValue: \"${selectedValue}\"`);\r\n \r\n // Handle __RADIO_OPTION_INDEX_ pattern directly\r\n if (selectedValue.startsWith('__RADIO_OPTION_INDEX_')) {\r\n const indexMatch = selectedValue.match(/__RADIO_OPTION_INDEX_(\\d+)__/);\r\n if (indexMatch && indexMatch[1]) {\r\n selectedIndex = parseInt(indexMatch[1], 10);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: extracted index ${selectedIndex} from __RADIO_OPTION_INDEX_ pattern`);\r\n }\r\n } \r\n // Handle numeric string (just an index)\r\n else if (/^\\d+$/.test(selectedValue)) {\r\n selectedIndex = parseInt(selectedValue, 10);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: parsed numeric index ${selectedIndex}`);\r\n }\r\n // Match against actual option values from field info\r\n else if (fieldInfo?.options && selectedValue) {\r\n selectedIndex = fieldInfo.options.findIndex(option => option === selectedValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: matched \"${selectedValue}\" in fieldInfo.options at index ${selectedIndex}`);\r\n }\r\n // Match against radio group options\r\n else if (radioOptions.length > 0) {\r\n selectedIndex = radioOptions.findIndex((opt: string) => opt === selectedValue);\r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: matched \"${selectedValue}\" in radioOptions at index ${selectedIndex}`);\r\n }\r\n }\r\n \r\n logger.info(`[FLATTEN RADIO] Field ${fieldName}: FINAL selectedIndex = ${selectedIndex}, will draw filled circle at this index`);\r\n const labelFont = await pdfDoc.embedFont('Helvetica-Bold');\r\n const drawnGroupLabels = new Set<string>();\r\n const drawnOptionLabels = new Set<string>();\r\n \r\n // Draw borders for ALL radio buttons\r\n for (let i = 0; i < widgets.length; i++) {\r\n const widget = widgets[i];\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page, pageIndex } = result;\r\n \r\n // Draw radio GROUP label (once, above first widget)\r\n // Only draw if it's a user-typed custom label (not auto-generated)\r\n if (i === 0 && fieldInfo && hasDrawableLabel(fieldInfo)) {\r\n const groupLabelKey = `${pageIndex}-${fieldName}-grouplabel`;\r\n if (!drawnGroupLabels.has(groupLabelKey)) {\r\n const labelFontSize = Math.min(10, rect.height * 0.4);\r\n const labelY = rect.y + rect.height + 3;\r\n page.drawText(fieldInfo.label, {\r\n x: rect.x,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n drawnGroupLabels.add(groupLabelKey);\r\n }\r\n } else if (i === 0 && isAutoGeneratedLabel(fieldInfo?.label || '')) {\r\n }\r\n \r\n // Draw radio button border (circle)\r\n const radioSize = Math.min(rect.width, rect.height);\r\n const centerX = rect.x + rect.width / 2;\r\n const centerY = rect.y + rect.height / 2;\r\n\r\n page.drawCircle({\r\n x: centerX,\r\n y: centerY,\r\n size: radioSize / 2,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n });\r\n\r\n // Draw filled circle ONLY for selected option\r\n if (i === selectedIndex) {\r\n page.drawCircle({\r\n x: centerX,\r\n y: centerY,\r\n size: radioSize / 4,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n\r\n // Draw option text next to each radio button\r\n // Same positioning as preview (pdf-viewer-filter.ts)\r\n if (fieldInfo?.options && fieldInfo.options.length > i) {\r\n const optionText = fieldInfo.options[i];\r\n const optionKey = `${pageIndex}-${fieldName}-opt-${i}`;\r\n\r\n if (optionText && !drawnOptionLabels.has(optionKey)) {\r\n page.drawText(optionText, {\r\n x: rect.x + rect.width + 4,\r\n y: rect.y + (rect.height - 7) / 2,\r\n size: 7,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n drawnOptionLabels.add(optionKey);\r\n }\r\n }\r\n }\r\n \r\n if (fieldInfo?.options) {\r\n }\r\n } else if (isDropdownField) {\r\n // Dropdown field - draw the selected value with 14px font\r\n const selectedValue = userEnteredValue ? String(userEnteredValue) : '';\r\n \r\n // Get field info for label\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n const labelFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n \r\n // Draw label for dropdown fields (even when empty)\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw label above the field\r\n if (fieldInfo && hasDrawableLabel(fieldInfo)) {\r\n const labelFontSize = Math.min(10, rect.height * 0.4);\r\n const labelX = rect.x;\r\n const labelY = rect.y + rect.height + 5;\r\n page.drawText(fieldInfo.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw value only if present\r\n if (selectedValue && selectedValue.trim()) {\r\n page.drawText(selectedValue, {\r\n x: rect.x + 2,\r\n y: rect.y + 2,\r\n size: 14,\r\n font: await pdfDoc.embedFont(StandardFonts.Helvetica),\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n }\r\n } else {\r\n // Text field or other field types (including date) - draw the field value\r\n const fieldValue = userEnteredValue ? String(userEnteredValue) : '';\r\n \r\n // Get field info for label\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n const labelFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n \r\n // Draw label for text/date fields (even when empty)\r\n // Check if this is a date field\r\n const isDateField = fieldName.toLowerCase().includes('date') || fieldName.toLowerCase().includes('_date');\r\n \r\n // Use 14px for date fields, otherwise extract font size\r\n const fontSize = isDateField ? 14 : extractFieldFontSize(fieldName, field, extractedFormFields);\r\n \r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw label above the field (dm-web-frontend pattern)\r\n if (fieldInfo && hasDrawableLabel(fieldInfo)) {\r\n const labelFontSize = Math.min(10, rect.height * 0.4);\r\n const labelX = rect.x;\r\n const labelY = rect.y + rect.height + 5; // Above the field\r\n page.drawText(fieldInfo.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw value only if present\r\n if (fieldValue && fieldValue.trim()) {\r\n page.drawText(fieldValue, {\r\n x: rect.x + 2,\r\n y: rect.y + 2,\r\n size: fontSize,\r\n font: await pdfDoc.embedFont(StandardFonts.Helvetica),\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n }\r\n }\r\n \r\n // Remove the field to flatten it\r\n form.removeField(field);\r\n flattenedCount++;\r\n } catch (error) {\r\n }\r\n }\r\n \r\n const remainingFields = form.getFields();\r\n \r\n // Verify flattening worked\r\n if (multiSignerContext?.isMultiSigner) {\r\n // MULTI-SIGNER MODE: Remaining fields are EXPECTED (for other signers)\r\n const expectedRemainingCount = allFormFields.length - fieldsToFlatten.length;\r\n if (remainingFields.length === expectedRemainingCount) {\r\n } else {\r\n }\r\n } else {\r\n // SINGLE-SIGNER MODE: All fields should be flattened\r\n if (remainingFields.length > 0) {\r\n logger.error(`MANUAL FLATTENING INCOMPLETE: ${remainingFields.length} fields still exist!`);\r\n logger.error(`Remaining fields:`, remainingFields.map(f => f.getName()));\r\n \r\n // Try basic flattening as final fallback (only in single-signer mode)\r\n try {\r\n form.flatten();\r\n const finalRemainingFields = form.getFields();\r\n \r\n if (finalRemainingFields.length > 0) {\r\n logger.error(`ALL FLATTENING METHODS FAILED: ${finalRemainingFields.length} fields still exist!`);\r\n logger.error(`Final remaining fields:`, finalRemainingFields.map(f => f.getName()));\r\n }\r\n } catch (fallbackError) {\r\n logger.error('Fallback flattening failed:', fallbackError);\r\n }\r\n } else {\r\n }\r\n }\r\n \r\n // STEP 6: Set document metadata for tracking and compliance\r\n try {\r\n // Set document metadata based on submission data\r\n // Set Title (with default if not provided)\r\n const documentTitle = metadata?.documentId \r\n ? `Document ID: ${metadata.documentId}`\r\n : 'Signed Document';\r\n pdfDoc.setTitle(documentTitle);\r\n \r\n // Set Subject (with default if not provided)\r\n const documentSubject = metadata?.submissionId\r\n ? `Submission ID: ${metadata.submissionId}`\r\n : metadata?.signerEmail\r\n ? `Signed by ${metadata.signerEmail}`\r\n : 'Digitally Signed Document';\r\n pdfDoc.setSubject(documentSubject);\r\n \r\n // Set Author (with default if not provided)\r\n const documentAuthor = metadata?.author || metadata?.signerEmail || 'Unknown';\r\n pdfDoc.setAuthor(documentAuthor);\r\n \r\n pdfDoc.setProducer('Created by signiphi (https://signiphi.ai/)');\r\n \r\n if (metadata?.signerEmail) {\r\n pdfDoc.setCreator(`Signer: ${metadata.signerEmail}`);\r\n }\r\n \r\n // Set creation date from submission\r\n if (metadata?.createdAt) {\r\n pdfDoc.setCreationDate(metadata.createdAt);\r\n }\r\n \r\n // Set current date as modification date\r\n pdfDoc.setModificationDate(new Date());\r\n \r\n // Set keywords for searchability and tracking\r\n const keywords: string[] = [];\r\n \r\n // Add signer email if available\r\n if (metadata?.signerEmail) {\r\n keywords.push(metadata.signerEmail);\r\n }\r\n \r\n // Add initials to metadata if available\r\n if (metadata?.signerInitials && metadata.signerInitials.trim()) {\r\n keywords.push(`Initials:${metadata.signerInitials.trim()}`);\r\n }\r\n \r\n // Add audit trail data for compliance and forensics\r\n if (auditTrail) {\r\n try {\r\n // Device/Browser information\r\n if (auditTrail.userAgent) {\r\n keywords.push(`UserAgent:${auditTrail.userAgent}`);\r\n }\r\n \r\n // Screen resolution as device identifier\r\n if (auditTrail.screenResolution) {\r\n keywords.push(`Screen:${auditTrail.screenResolution}`);\r\n }\r\n \r\n // Timezone\r\n if (auditTrail.timezone) {\r\n keywords.push(`Timezone:${auditTrail.timezone}`);\r\n }\r\n \r\n // Language settings\r\n if (auditTrail.language) {\r\n keywords.push(`Language:${auditTrail.language}`);\r\n }\r\n \r\n // Platform information\r\n if (auditTrail.platform) {\r\n keywords.push(`Platform:${auditTrail.platform}`);\r\n }\r\n \r\n // IP address\r\n if (auditTrail.ipAddress) {\r\n keywords.push(`IP:${auditTrail.ipAddress}`);\r\n }\r\n \r\n // Geolocation data\r\n if (auditTrail.geolocation) {\r\n const { latitude, longitude, accuracy } = auditTrail.geolocation;\r\n const lat = latitude.toFixed(4);\r\n const lon = longitude.toFixed(4);\r\n keywords.push(`Location:${lat},${lon}`);\r\n \r\n // Add accuracy if available\r\n if (accuracy !== undefined) {\r\n keywords.push(`LocationAccuracy:${accuracy}m`);\r\n }\r\n }\r\n } catch (auditError) {\r\n logger.warn('⚠️ Error adding audit trail to keywords:', auditError)\r\n }\r\n }\r\n \r\n if (keywords.length > 0) {\r\n pdfDoc.setKeywords(keywords);\r\n }\r\n } catch (error) {\r\n logger.error('Failed to set document metadata:', error);\r\n }\r\n \r\n const finalPdfBytes = await pdfDoc.save();\r\n return finalPdfBytes;\r\n } catch (error) {\r\n logger.error('Error filling PDF with signatures:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Fill form fields and replace signature/initials with actual signature images\r\n * This is used when fields are rendered as overlays on the PDF\r\n * @param pdfBytes - The PDF bytes\r\n * @param formFields - The form fields with their positions\r\n * @param fieldValues - The field values to fill\r\n * @param signatures - The signature images (base64 data URLs)\r\n * @returns The filled PDF bytes\r\n */\r\nexport async function fillFormFieldsWithSignatures(\r\n pdfBytes: Uint8Array,\r\n formFields: EsignFormField[],\r\n fieldValues: Record<string, string>,\r\n signatures: Record<string, string>\r\n): Promise<Uint8Array> {\r\n try {\r\n const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const pages = pdfDoc.getPages();\r\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\r\n\r\n for (const field of formFields) {\r\n const pageIndex = field.position.page - 1;\r\n \r\n if (pageIndex < 0 || pageIndex >= pages.length) {\r\n continue;\r\n }\r\n\r\n const page = pages[pageIndex];\r\n if (!page) continue;\r\n const { height: pageHeight } = page.getSize();\r\n\r\n // Convert coordinates from top-left (UI) to bottom-left (PDF)\r\n const pdfX = field.position.x;\r\n const pdfY = pageHeight - field.position.y - field.position.height;\r\n\r\n try {\r\n switch (field.type) {\r\n case FormFieldType.TEXT: {\r\n const value = fieldValues[field.id] || '';\r\n \r\n // Draw label above field\r\n if (hasDrawableLabel(field)) {\r\n const labelFontSize = Math.min(10, field.position.height * 0.4);\r\n const labelX = pdfX;\r\n const labelY = pdfY + field.position.height + 5;\r\n page.drawText(field.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw value if present\r\n if (value) {\r\n const fontSize = field.fontSize && field.fontSize >= 8 && field.fontSize <= 72\r\n ? field.fontSize\r\n : Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.DATE: {\r\n const value = fieldValues[field.id] || '';\r\n \r\n // Draw label above field\r\n if (hasDrawableLabel(field)) {\r\n const labelFontSize = Math.min(10, field.position.height * 0.4);\r\n const labelX = pdfX;\r\n const labelY = pdfY + field.position.height + 5;\r\n page.drawText(field.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw value if present\r\n if (value) {\r\n const fontSize = field.fontSize && field.fontSize >= 8 && field.fontSize <= 72 \r\n ? field.fontSize \r\n : Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.CHECKBOX: {\r\n const value = fieldValues[field.id] || '';\r\n \r\n // Draw checkbox border for both checked and unchecked states\r\n const checkboxSize = Math.min(field.position.width, field.position.height) * 0.7;\r\n const checkboxX = pdfX + (field.position.width - checkboxSize) / 2;\r\n const checkboxY = pdfY + (field.position.height - checkboxSize) / 2;\r\n \r\n page.drawRectangle({\r\n x: checkboxX,\r\n y: checkboxY,\r\n width: checkboxSize,\r\n height: checkboxSize,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n color: rgb(1, 1, 1),\r\n });\r\n \r\n // Draw checkmark if checked\r\n if (value === 'true') {\r\n const checkSize = checkboxSize * 0.7;\r\n const checkX = checkboxX + (checkboxSize - checkSize) / 2;\r\n const checkY = checkboxY + (checkboxSize - checkSize) / 2;\r\n \r\n page.drawText('✓', {\r\n x: checkX,\r\n y: checkY,\r\n size: checkSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n break;\r\n }\r\n\r\n case FormFieldType.SIGNATURE: {\r\n const signatureDataUrl = signatures[field.id];\r\n if (signatureDataUrl) {\r\n // Convert base64 data URL to image bytes\r\n const base64Data = signatureDataUrl.split(',')[1];\r\n if (!base64Data) {\r\n logger.error('Invalid signature data URL format for field:', field.id);\r\n break;\r\n }\r\n const imageBytes = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0));\r\n \r\n // Embed the image\r\n const image = await pdfDoc.embedPng(imageBytes);\r\n \r\n // Calculate dimensions to fit within the field while maintaining aspect ratio\r\n const imageSize = image.size();\r\n const fieldAspectRatio = field.position.width / field.position.height;\r\n const imageAspectRatio = imageSize.width / imageSize.height;\r\n \r\n let drawWidth = field.position.width;\r\n let drawHeight = field.position.height;\r\n \r\n if (imageAspectRatio > fieldAspectRatio) {\r\n // Image is wider than field - fit to width\r\n drawHeight = drawWidth / imageAspectRatio;\r\n } else {\r\n // Image is taller than field - fit to height\r\n drawWidth = drawHeight * imageAspectRatio;\r\n }\r\n \r\n // Center the image within the field\r\n const imageX = pdfX + (field.position.width - drawWidth) / 2;\r\n const imageY = pdfY + (field.position.height - drawHeight) / 2;\r\n \r\n // Draw the image\r\n page.drawImage(image, {\r\n x: imageX,\r\n y: imageY,\r\n width: drawWidth,\r\n height: drawHeight,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.INITIALS: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n // Use a cursive font for initials\r\n const fontSize = Math.min(18, field.position.height * 0.8);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.DROPDOWN: {\r\n const value = fieldValues[field.id] || '';\r\n \r\n // Draw label above field\r\n if (hasDrawableLabel(field)) {\r\n const labelFontSize = Math.min(10, field.position.height * 0.4);\r\n const labelX = pdfX;\r\n const labelY = pdfY + field.position.height + 5; // Above the field\r\n page.drawText(field.label, {\r\n x: labelX,\r\n y: labelY,\r\n size: labelFontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw value if present\r\n if (value) {\r\n const fontSize = Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n default:\r\n break;\r\n }\r\n } catch (fieldError) {\r\n logger.error(`Error processing field ${field.name}:`, fieldError);\r\n }\r\n }\r\n\r\n return await pdfDoc.save();\r\n} catch (error) {\r\n logger.error('Error filling form fields:', error);\r\n throw error;\r\n}\r\n}\r\n\r\n/**\r\n * Extract field positions and page numbers from a PDF document\r\n * Returns maps for field name -> page number and field name -> position\r\n */\r\nexport async function getFieldPageNumbers(\r\n pdfBytes: Uint8Array\r\n): Promise<{\r\n pageMap: Record<string, number>;\r\n positionMap: Record<string, FormFieldPosition>;\r\n}> {\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n const pages = pdfDoc.getPages();\r\n\r\n const pageMap: Record<string, number> = {};\r\n const positionMap: Record<string, FormFieldPosition> = {};\r\n\r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const fieldWithAcro = field as unknown as PDFFieldWithAcro;\r\n const widgets = fieldWithAcro.acroField?.getWidgets?.() ?? [];\r\n\r\n if (widgets.length > 0) {\r\n // Use the first widget to determine page and position\r\n const widget = widgets[0];\r\n if (!widget) continue;\r\n const rect = widget.getRectangle?.();\r\n const pageRef = widget.P?.();\r\n\r\n if (rect && pageRef) {\r\n // Find which page this widget belongs to\r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n\r\n if (pageIndex !== -1) {\r\n const pageNumber = pageIndex + 1; // Convert to 1-indexed\r\n pageMap[fieldName] = pageNumber;\r\n\r\n // Store position information\r\n positionMap[fieldName] = {\r\n x: rect.x,\r\n y: rect.y,\r\n width: rect.width,\r\n height: rect.height,\r\n page: pageNumber,\r\n };\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { pageMap, positionMap };\r\n} catch (error) {\r\n logger.error('Error extracting field page numbers:', error);\r\n return { pageMap: {}, positionMap: {} };\r\n}\r\n}\r\n\r\n","/**\r\n * PDF Signer Utilities for Multi-Signer Document Preparation\r\n * Adapted from dm-web-frontend for signiphi's simpler signer model\r\n */\r\n\r\nimport { loadPdfLib } from './pdf-lib-loader';\r\nimport { FormField, FormFieldType, Signer } from '../types';\r\nimport { logger } from './logger';\r\n\r\nexport interface PrepareSignerPdfOptions {\r\n activeSignerEmail: string; // Email of the current signer\r\n completedSignerEmails?: string[]; // Emails of signers who have already signed\r\n hideMode?: 'Hidden' | 'NoView'; // How to hide fields from other signers\r\n lockCompletedFields?: boolean; // Whether to lock fields from completed signers\r\n allSignerEmails?: string[]; // All signer emails for grouped assignments (to-recipients)\r\n}\r\n\r\n/**\r\n * Extract signer email from field assignment\r\n * For grouped assignments, this returns the group identifier\r\n */\r\nfunction getFieldSignerEmail(field: FormField): string | null {\r\n return field.assignedSignerEmail || null;\r\n}\r\n\r\n/**\r\n * Check if a field is assigned to a specific signer, considering grouped assignments\r\n * Adapted for signiphi's simpler model: no role hierarchy, just email matching\r\n */\r\nfunction isFieldAssignedToSigner(\r\n field: FormField, \r\n signerEmail: string, \r\n allSignerEmails: string[] = []\r\n): boolean {\r\n const assignedTo = field.assignedSignerEmail;\r\n \r\n if (!assignedTo) return false;\r\n \r\n // Direct email assignment (individual signer)\r\n if (assignedTo === signerEmail) return true;\r\n \r\n // Group assignment: \"to-recipients\" (all signers convenience group)\r\n // In signiphi, this means field is assigned to ALL signers\r\n if (assignedTo === 'to-recipients' && allSignerEmails.includes(signerEmail)) {\r\n return true;\r\n }\r\n \r\n // Legacy group assignment: \"additional-signers\" (if still used)\r\n // In signiphi's flat model, treat this the same as to-recipients\r\n if (assignedTo === 'additional-signers' && allSignerEmails.includes(signerEmail)) {\r\n return true;\r\n }\r\n \r\n return false;\r\n}\r\n\r\n/**\r\n * Prepare a PDF document for a specific signer by hiding/showing fields and locking completed ones\r\n * Adapted for signiphi: simplified logic without role checks\r\n */\r\nexport async function preparePdfForSigner(\r\n inputPdfBytes: Uint8Array | ArrayBuffer,\r\n formFields: FormField[],\r\n options: PrepareSignerPdfOptions\r\n): Promise<Uint8Array> {\r\n const { \r\n activeSignerEmail, \r\n hideMode = 'NoView',\r\n allSignerEmails = []\r\n } = options;\r\n \r\n logger.info(`🔐 Preparing PDF for signer: ${activeSignerEmail}`);\r\n logger.info(`🔐 Form fields to process: ${formFields.length}`);\r\n logger.info(`🔐 Hide mode: ${hideMode}`);\r\n logger.info(`🔐 All signer emails:`, allSignerEmails);\r\n logger.info(`🔐 Form field assignments:`, formFields.map(f => ({ \r\n name: f.name, \r\n assignedTo: f.assignedSignerEmail\r\n })));\r\n \r\n // Load the PDF document with detailed error handling\r\n const pdfLib = await loadPdfLib();\r\n const { PDFDocument, AnnotationFlags } = pdfLib;\r\n \r\n let pdfDoc: Awaited<ReturnType<typeof PDFDocument.load>>;\r\n try {\r\n logger.info(`🔐 Loading PDF document, bytes length: ${inputPdfBytes.byteLength || (inputPdfBytes as Uint8Array).length}`);\r\n \r\n // Check if we have valid PDF header\r\n const bytesArray = inputPdfBytes instanceof Uint8Array ? inputPdfBytes : new Uint8Array(inputPdfBytes);\r\n const header = new TextDecoder().decode(bytesArray.slice(0, 8));\r\n logger.info(`🔐 PDF header: \"${header}\"`);\r\n \r\n if (!header.startsWith('%PDF-')) {\r\n throw new Error(`Invalid PDF header: \"${header}\". Expected \"%PDF-\"`);\r\n }\r\n \r\n pdfDoc = await PDFDocument.load(inputPdfBytes);\r\n logger.info(`✅ Successfully loaded PDF document`);\r\n } catch (loadError) {\r\n logger.error(`❌ Failed to load PDF with pdf-lib:`, loadError);\r\n logger.info(`🔍 PDF bytes details:`, {\r\n type: inputPdfBytes.constructor.name,\r\n length: inputPdfBytes.byteLength || (inputPdfBytes as Uint8Array).length,\r\n isArrayBuffer: inputPdfBytes instanceof ArrayBuffer,\r\n isUint8Array: inputPdfBytes instanceof Uint8Array,\r\n first20Bytes: Array.from(new Uint8Array(inputPdfBytes instanceof ArrayBuffer ? inputPdfBytes : (inputPdfBytes as Uint8Array).buffer).slice(0, 20)).map(b => b.toString(16).padStart(2, '0')).join(' ')\r\n });\r\n \r\n // Re-throw with more context\r\n throw new Error(`PDF parsing failed for signer ${activeSignerEmail}: ${loadError instanceof Error ? loadError.message : 'Unknown error'}`);\r\n }\r\n \r\n const form = pdfDoc.getForm();\r\n const pdfFields = form.getFields();\r\n \r\n logger.info(`🔐 PDF contains ${pdfFields.length} form fields`);\r\n \r\n // Type extensions for pdf-lib\r\n interface PDFFieldWithExtensions {\r\n enableReadOnly?: () => void;\r\n setReadOnly?: (readonly: boolean) => void;\r\n acroField?: {\r\n getWidgets?: () => PDFWidgetWithExtensions[];\r\n };\r\n }\r\n \r\n interface PDFWidgetWithExtensions {\r\n clearFlag?: (flag: number) => void;\r\n setFlag?: (flag: number) => void;\r\n hasFlag?: (flag: number) => boolean;\r\n getFlagValue?: () => number;\r\n }\r\n \r\n // Process each PDF field\r\n for (const pdfField of pdfFields) {\r\n const pdfFieldName = pdfField.getName();\r\n \r\n // Find the corresponding FormField from the input formFields array\r\n // Account for pdf-lib automatically appending '_signature' to signature/initials field names\r\n const matchingFormField = formFields.find(f => \r\n f.name === pdfFieldName || \r\n ((f.type === FormFieldType.SIGNATURE || f.type === FormFieldType.INITIALS) && `${f.name}_signature` === pdfFieldName)\r\n );\r\n \r\n if (!matchingFormField) {\r\n logger.info(`🔐 PDF field \"${pdfFieldName}\" not found in provided form fields - leaving unchanged`);\r\n continue;\r\n }\r\n logger.info(`🔐 Matched PDF field \"${pdfFieldName}\" to FormField \"${matchingFormField.name}\". Assigned to: ${matchingFormField.assignedSignerEmail}`);\r\n \r\n const fieldSignerEmail = getFieldSignerEmail(matchingFormField);\r\n const isAssignedToActiveSigner = isFieldAssignedToSigner(\r\n matchingFormField, \r\n activeSignerEmail, \r\n allSignerEmails\r\n );\r\n \r\n // Check if field is assigned to any completed signer\r\n const isAssignedToCompletedSigner = (options.completedSignerEmails || []).some(completedEmail =>\r\n isFieldAssignedToSigner(matchingFormField, completedEmail, allSignerEmails)\r\n );\r\n \r\n const isUnassigned = !fieldSignerEmail;\r\n \r\n // Determine visibility\r\n let isVisible = false;\r\n let reason = '';\r\n \r\n if (isAssignedToActiveSigner) {\r\n isVisible = true;\r\n reason = 'Assigned to active signer';\r\n } else if (isUnassigned) {\r\n isVisible = true;\r\n reason = 'Unassigned field (visible to all)';\r\n } else {\r\n isVisible = false;\r\n reason = `Assigned to different signer (${fieldSignerEmail})`;\r\n }\r\n \r\n // Determine if field should be locked\r\n const isLocked = (options.lockCompletedFields ?? true) && isAssignedToCompletedSigner;\r\n if (isLocked) {\r\n reason += ' - Locked (completed)';\r\n }\r\n \r\n logger.info(`🔐 Processing field \"${pdfFieldName}\": ${reason}`);\r\n \r\n // Handle field locking (read-only)\r\n if (isLocked) {\r\n try {\r\n // Try different methods for setting read-only based on pdf-lib version\r\n const fieldWithExtensions = pdfField as unknown as PDFFieldWithExtensions;\r\n if (typeof fieldWithExtensions.enableReadOnly === 'function') {\r\n fieldWithExtensions.enableReadOnly();\r\n } else if (typeof fieldWithExtensions.setReadOnly === 'function') {\r\n fieldWithExtensions.setReadOnly(true);\r\n }\r\n logger.info(`🔒 Locked field \"${pdfFieldName}\"`);\r\n } catch (error) {\r\n logger.warn(`⚠️ Could not lock field \"${pdfFieldName}\":`, error);\r\n }\r\n }\r\n \r\n // Handle widget visibility\r\n try {\r\n // Get all widgets for this field\r\n const fieldWithExtensions = pdfField as unknown as PDFFieldWithExtensions;\r\n const widgets = fieldWithExtensions.acroField?.getWidgets?.() ?? [];\r\n \r\n for (const widget of widgets) {\r\n // Clear existing visibility flags\r\n if (typeof widget.clearFlag === 'function') {\r\n widget.clearFlag(AnnotationFlags.Hidden);\r\n widget.clearFlag(AnnotationFlags.NoView);\r\n }\r\n \r\n if (!isVisible) {\r\n // Hide the widget\r\n const flag = hideMode === 'Hidden' ? AnnotationFlags.Hidden : AnnotationFlags.NoView;\r\n if (typeof widget.setFlag === 'function') {\r\n widget.setFlag(flag);\r\n }\r\n \r\n // Optionally prevent hidden fields from printing\r\n if (typeof widget.clearFlag === 'function') {\r\n widget.clearFlag(AnnotationFlags.Print);\r\n }\r\n \r\n logger.info(`🙈 Hidden field \"${pdfFieldName}\" using ${hideMode} flag`);\r\n } else {\r\n // Make sure visible fields can be printed\r\n if (typeof widget.setFlag === 'function') {\r\n widget.setFlag(AnnotationFlags.Print);\r\n }\r\n logger.info(`👁️ Made field \"${pdfFieldName}\" visible`);\r\n }\r\n }\r\n } catch (error) {\r\n logger.warn(`⚠️ Could not set visibility for field \"${pdfFieldName}\":`, error);\r\n }\r\n }\r\n \r\n // Set PDF metadata to indicate the intended signer\r\n try {\r\n const currentSubject = pdfDoc.getSubject() || '';\r\n const signerInfo = `Prepared for: ${activeSignerEmail}`;\r\n const newSubject = currentSubject ? `${currentSubject} | ${signerInfo}` : signerInfo;\r\n pdfDoc.setSubject(newSubject);\r\n \r\n // Add to keywords for searchability\r\n const currentKeywords = pdfDoc.getKeywords() || [];\r\n const updatedKeywords = [...currentKeywords, `ActiveSigner:${activeSignerEmail}`];\r\n pdfDoc.setKeywords(updatedKeywords);\r\n \r\n logger.info(`📝 Added signer metadata to PDF`);\r\n } catch (error) {\r\n logger.warn(`⚠️ Could not set PDF metadata:`, error);\r\n }\r\n \r\n // Save and return the modified PDF\r\n const modifiedPdfBytes = await pdfDoc.save();\r\n \r\n logger.info(`✅ PDF prepared for ${activeSignerEmail}: ${modifiedPdfBytes.length} bytes`);\r\n \r\n return new Uint8Array(modifiedPdfBytes);\r\n}\r\n\r\n/**\r\n * Check if all signers have completed their fields\r\n */\r\nexport function areAllSignersComplete(\r\n signers: Signer[],\r\n completedSignerEmails: string[]\r\n): boolean {\r\n // Check if all required signers have completed\r\n const requiredSigners = new Set(signers.map(s => s.email));\r\n const completedSigners = new Set(completedSignerEmails);\r\n \r\n for (const signerEmail of requiredSigners) {\r\n if (!completedSigners.has(signerEmail)) {\r\n return false;\r\n }\r\n }\r\n \r\n return true;\r\n}\r\n\r\n/**\r\n * Get next signer in the sequence who hasn't completed their fields\r\n * In signiphi, signers are ordered by signOrder (1, 2, 3...)\r\n */\r\nexport function getNextSigner(\r\n signers: Signer[],\r\n completedSignerEmails: string[]\r\n): Signer | null {\r\n const completedSet = new Set(completedSignerEmails);\r\n \r\n // Sort signers by signOrder to get correct sequence\r\n const sortedSigners = [...signers].sort((a, b) => a.signOrder - b.signOrder);\r\n \r\n for (const signer of sortedSigners) {\r\n if (!completedSet.has(signer.email)) {\r\n return signer;\r\n }\r\n }\r\n \r\n return null; // All signers completed\r\n}\r\n\r\n/**\r\n * Validate field assignments for multiple signers\r\n * Adapted for signiphi's flat signer model\r\n */\r\nexport function validateFieldAssignments(\r\n formFields: FormField[],\r\n signers: Signer[]\r\n): { isValid: boolean; errors: string[] } {\r\n const errors: string[] = [];\r\n const signerEmailSet = new Set(signers.map(s => s.email));\r\n \r\n // Check for fields assigned to non-existent signers\r\n const assignedEmails = new Set(\r\n formFields\r\n .map(field => field.assignedSignerEmail)\r\n .filter(email => email) as string[]\r\n );\r\n \r\n for (const assignedEmail of assignedEmails) {\r\n // Skip validation for group assignments\r\n if (assignedEmail === 'to-recipients' || assignedEmail === 'additional-signers') {\r\n continue;\r\n }\r\n \r\n if (!signerEmailSet.has(assignedEmail)) {\r\n errors.push(`Field assigned to unknown signer: ${assignedEmail}`);\r\n }\r\n }\r\n \r\n // In signiphi's model, grouped assignments are convenience features\r\n // We don't require each individual signer to have fields\r\n // Fields assigned to \"to-recipients\" are visible to all signers\r\n \r\n // Check for required fields without assignment in multi-signer mode\r\n const requiredUnassignedFields = formFields.filter(field => \r\n field.required && !field.assignedSignerEmail\r\n );\r\n \r\n if (requiredUnassignedFields.length > 0) {\r\n errors.push(`${requiredUnassignedFields.length} required fields are not assigned to any signer`);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n","/**\r\n * PDF Form Field Extraction Utilities\r\n * Functions for extracting and decoding form fields from PDFs\r\n */\r\n\r\nimport { loadPdfLib } from './pdf-lib-loader';\r\nimport { EsignFormField, FormFieldType } from '../types';\r\nimport { logger } from './logger';\r\nimport type { PDFName as PDFNameType } from 'pdf-lib';\r\nimport { getSigniphiMetadata, initPdfMetadata, type FieldMetadata } from './pdf-metadata';\r\nimport { extractFieldValue } from './pdf-field-type-helpers';\r\n\r\n// Module-level variable to hold PDFName after pdf-lib is loaded\r\nlet PDFName: typeof PDFNameType;\r\n\r\n// Type definitions for PDF field extensions\r\ninterface PDFFieldWithExtensions {\r\n acroField?: {\r\n getWidgets?: () => Array<{\r\n hasFlag?: (flag: number) => boolean;\r\n }>;\r\n dict?: {\r\n get: (key: unknown) => unknown;\r\n };\r\n };\r\n getOptions?: () => string[];\r\n isRequired?: () => boolean;\r\n constructor: { name: string };\r\n getName(): string;\r\n}\r\n\r\n/**\r\n * Extract visible form fields from a PDF document\r\n * @param pdfBytes - The PDF bytes to extract fields from\r\n * @param currentSignerEmail - Optional email of the current signer (for multi-signer filtering)\r\n * @returns Array of extracted form fields\r\n */\r\nexport async function extractVisibleFormFields(\r\n pdfBytes: Uint8Array,\r\n currentSignerEmail?: string\r\n): Promise<EsignFormField[]> {\r\n try {\r\n const pdfLibModule = await loadPdfLib();\r\n const { PDFDocument, AnnotationFlags, PDFName: PDFNameClass } = pdfLibModule;\r\n PDFName = PDFNameClass; // Assign to module-level variable for use in helper functions\r\n \r\n // Initialize pdf-metadata module with PDFName and PDFString\r\n initPdfMetadata(pdfLibModule);\r\n \r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n \r\n // Load metadata from PDF document information dictionary\r\n const metadata = getSigniphiMetadata(pdfDoc);\r\n \r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n const visibleFields: EsignFormField[] = [];\r\n let hasAnyInitialsFields = false; // For single-signer mode\r\n \r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n \r\n // Get widgets for this field to check visibility\r\n const fieldWithExtensions = field as unknown as PDFFieldWithExtensions;\r\n const widgets = fieldWithExtensions.acroField?.getWidgets?.() ?? [];\r\n \r\n let isVisible = true;\r\n \r\n // Check if any widget is hidden using AnnotationFlags\r\n for (const widget of widgets) {\r\n const hasHiddenFlag = widget.hasFlag?.(AnnotationFlags.Hidden) ?? false;\r\n const hasNoViewFlag = widget.hasFlag?.(AnnotationFlags.NoView) ?? false;\r\n \r\n if (hasHiddenFlag || hasNoViewFlag) {\r\n isVisible = false;\r\n break;\r\n }\r\n }\r\n \r\n if (isVisible) {\r\n // Extract the clean field name (without suffixes) for metadata lookup\r\n const cleanFieldNameForMetadata = fieldName.replace(/_signature$|_initials$|_date$/i, '');\r\n\r\n // Get field metadata from PDF metadata or fall back to parsing field name (for old PDFs)\r\n // CRITICAL: Try both the suffixed name and the clean name for metadata lookup\r\n const fieldMetadata: FieldMetadata = metadata?.fields[fieldName]\r\n || metadata?.fields[cleanFieldNameForMetadata]\r\n || (() => {\r\n // Backward compatibility: decode from field name if no metadata exists\r\n const decoded = decodeFieldName(fieldName);\r\n return {\r\n label: decoded.displayLabel,\r\n signer: decoded.assignedSignerEmail,\r\n placeholder: decoded.fieldPlaceholder,\r\n acknowledgements: decoded.acknowledgements\r\n };\r\n })();\r\n \r\n // NOTE: We do NOT filter by signer during extraction in multi-signer mode!\r\n // All fields must be extracted so that:\r\n // 1. useFieldFiltering can properly filter fields for display\r\n // 2. Partial flattening knows about all fields (flatten current signer's fields only)\r\n // 3. PDF viewer filtering can remove non-visible fields from the rendered PDF\r\n // The filtering happens at the display level via useFieldFiltering hook.\r\n \r\n // Determine field type based on pdf-lib field type using duck typing (minification-safe)\r\n // Constructor names get renamed during minification, breaking string comparisons\r\n let fieldType = FormFieldType.TEXT;\r\n const f = field as any;\r\n\r\n // Duck typing: detect field type by method presence\r\n const isCheckboxField = typeof f.check === 'function' && typeof f.uncheck === 'function';\r\n const isRadioField = typeof f.select === 'function' &&\r\n typeof f.getOptions === 'function' &&\r\n typeof f.check !== 'function' &&\r\n typeof f.setOptions !== 'function';\r\n const isDropdownField = typeof f.select === 'function' &&\r\n (typeof f.setOptions === 'function' || typeof f.addOptions === 'function');\r\n const isTextField = typeof f.getText === 'function' && typeof f.setText === 'function';\r\n // Signature fields have no editable methods\r\n const isSignatureType = !isCheckboxField && !isRadioField && !isDropdownField && !isTextField;\r\n\r\n // Extract the clean field name (without suffixes for type detection)\r\n const cleanFieldName = fieldName.replace(/_signature$|_initials$|_date$/i, '');\r\n\r\n // CRITICAL: Properly detect signature/initials fields (not checkboxes/radios)\r\n // Use duck typing to exclude checkbox/radio fields\r\n const isActualSignatureField = isSignatureType ||\r\n (cleanFieldName.toLowerCase().includes('signature') &&\r\n !isCheckboxField &&\r\n !isRadioField);\r\n const isActualInitialsField = cleanFieldName.toLowerCase().includes('initials') &&\r\n !isCheckboxField &&\r\n !isRadioField;\r\n\r\n if (isActualSignatureField) {\r\n fieldType = FormFieldType.SIGNATURE;\r\n } else if (isActualInitialsField) {\r\n fieldType = FormFieldType.INITIALS;\r\n\r\n // Track initials fields for proper sidebar display logic\r\n hasAnyInitialsFields = true;\r\n } else if (cleanFieldName.toLowerCase().includes('date')) {\r\n fieldType = FormFieldType.DATE;\r\n } else if (isCheckboxField) {\r\n fieldType = FormFieldType.CHECKBOX;\r\n } else if (isDropdownField) {\r\n fieldType = FormFieldType.DROPDOWN;\r\n } else if (isRadioField) {\r\n fieldType = FormFieldType.RADIO;\r\n }\r\n \r\n // Generate display label - Try TU metadata first, then metadata label, then fallback\r\n let displayLabel = fieldMetadata.label || '';\r\n let isLabelAutoGenerated = false;\r\n\r\n // PRIORITY 1: Try to get label from TU (tooltip/user-visible) metadata\r\n if (!displayLabel || !displayLabel.trim()) {\r\n try {\r\n const tuLabel = extractTULabel(fieldWithExtensions);\r\n if (tuLabel && tuLabel.trim()) {\r\n displayLabel = tuLabel;\r\n }\r\n } catch (tuError) {\r\n }\r\n }\r\n\r\n // PRIORITY 2: Use label from metadata (already set above from fieldMetadata.label)\r\n\r\n // PRIORITY 3: Generate fallback label from field name\r\n // This provides a display label for the UI sidebar, but should NOT be drawn on the PDF\r\n if (!displayLabel || !displayLabel.trim()) {\r\n displayLabel = generateFallbackLabel(cleanFieldName, fieldType);\r\n isLabelAutoGenerated = true;\r\n }\r\n\r\n // Create EsignFormField\r\n const esignField: EsignFormField = {\r\n id: fieldName, // Keep original encoded name as ID\r\n fieldId: fieldMetadata.fieldId || fieldName, // Use fieldId from metadata, fallback to fieldName for backward compatibility\r\n name: fieldName, // Keep original for removal later\r\n type: fieldType,\r\n label: displayLabel, // Use friendly label for display\r\n isLabelAutoGenerated, // True when label was generated from field name (should not be drawn on PDF)\r\n position: { x: 0, y: 0, width: 100, height: 30, page: 1 }, // Default position\r\n required: fieldWithExtensions.isRequired?.() ?? false,\r\n placeholder: fieldMetadata.placeholder || '', // Use metadata placeholder\r\n assignedSignerEmail: fieldMetadata.signer, // Add assigned signer from metadata\r\n acknowledgements: fieldMetadata.acknowledgements, // Add acknowledgements from metadata\r\n };\r\n \r\n // Add options for dropdown and radio fields\r\n if (fieldType === FormFieldType.DROPDOWN || fieldType === FormFieldType.RADIO) {\r\n try {\r\n const options = fieldWithExtensions.getOptions?.() ?? [];\r\n esignField.options = options;\r\n if (options.length > 0) {\r\n }\r\n } catch (error) {\r\n logger.warn('Error extracting options for field:', error);\r\n }\r\n }\r\n\r\n // Read current field value from PDF (for pre-filled fields)\r\n try {\r\n const currentValue = extractFieldValue(f as any, esignField.type);\r\n if (currentValue) {\r\n esignField.defaultValue = currentValue;\r\n }\r\n } catch {\r\n // Ignore errors reading field values\r\n }\r\n\r\n visibleFields.push(esignField);\r\n }\r\n }\r\n \r\n // Add main signature and initials fields at the BEGINNING\r\n // Only create if PDF has these fields OR if explicitly required\r\n const mainFields: EsignFormField[] = [];\r\n \r\n // ALWAYS create signature field - it's attached to the document on submission regardless\r\n mainFields.push({\r\n id: 'signature_field_main',\r\n fieldId: 'signature_field_main', // Fixed ID for main signature field\r\n name: 'signature_field_main',\r\n type: FormFieldType.SIGNATURE,\r\n label: 'Your Signature (will be applied to all signature fields)',\r\n position: { x: 0, y: 0, width: 200, height: 60, page: 1 },\r\n required: true,\r\n placeholder: 'Draw or upload your signature',\r\n assignedSignerEmail: currentSignerEmail,\r\n });\r\n \r\n // Create initials field if ANY initials fields exist in the PDF\r\n // The UI layer (useFieldFiltering) handles filtering fields by signer assignment\r\n // This ensures the initials section always appears when initials fields are present\r\n const shouldCreateInitialsField = hasAnyInitialsFields;\r\n \r\n if (shouldCreateInitialsField) {\r\n mainFields.push({\r\n id: 'initials_field_main',\r\n fieldId: 'initials_field_main', // Fixed ID for main initials field\r\n name: 'initials_field_main',\r\n type: FormFieldType.INITIALS,\r\n label: 'Your Initials (will be applied to all initials fields)',\r\n position: { x: 0, y: 0, width: 100, height: 40, page: 1 },\r\n required: true,\r\n placeholder: 'Enter your initials',\r\n assignedSignerEmail: currentSignerEmail,\r\n });\r\n }\r\n \r\n // Return main fields FIRST, then other fields\r\n return [...mainFields, ...visibleFields];\r\n } catch (error) {\r\n logger.error('Error extracting visible form fields from PDF:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Decode a field name to extract label, signer email, and placeholder\r\n * Format: fieldName__LABEL__labelText__SIGNER__email__PLACEHOLDER__placeholderText\r\n * \r\n * @deprecated This function is deprecated and kept only for backward compatibility with old PDFs.\r\n * New PDFs store metadata in the PDF's document information dictionary instead of encoding it in field names.\r\n * Use getSigniphiMetadata() for new PDFs.\r\n */\r\nexport function decodeFieldName(fieldName: string): {\r\n decodedFieldName: string;\r\n displayLabel: string;\r\n assignedSignerEmail?: string;\r\n fieldPlaceholder: string;\r\n acknowledgements?: Array<{id: string; title: string; description: string}>;\r\n} {\r\n let decodedFieldName = fieldName;\r\n let displayLabel = '';\r\n let assignedSignerEmail: string | undefined = undefined;\r\n let fieldPlaceholder = '';\r\n let acknowledgements: Array<{id: string; title: string; description: string}> | undefined = undefined;\r\n \r\n // Extract acknowledgements if present (must be last)\r\n if (fieldName.includes('__ACK__')) {\r\n const ackMarkerIndex = fieldName.indexOf('__ACK__');\r\n const beforeAck = fieldName.substring(0, ackMarkerIndex);\r\n const ackEncoded = fieldName.substring(ackMarkerIndex + 7); // Skip \"__ACK__\"\r\n \r\n try {\r\n // Decode base64 and parse JSON\r\n const ackData = atob(ackEncoded);\r\n acknowledgements = JSON.parse(ackData);\r\n } catch (e) {\r\n console.warn('Failed to decode acknowledgements:', e);\r\n }\r\n \r\n // Continue processing the rest of the field name\r\n fieldName = beforeAck;\r\n decodedFieldName = fieldName;\r\n }\r\n \r\n // Extract label if present\r\n if (fieldName.includes('__LABEL__')) {\r\n const labelMarkerIndex = fieldName.indexOf('__LABEL__');\r\n decodedFieldName = fieldName.substring(0, labelMarkerIndex);\r\n \r\n const afterLabel = fieldName.substring(labelMarkerIndex + 9); // Skip \"__LABEL__\"\r\n \r\n // Extract signer email if present\r\n if (afterLabel.includes('__SIGNER__')) {\r\n const signerMarkerIndex = afterLabel.indexOf('__SIGNER__');\r\n displayLabel = afterLabel.substring(0, signerMarkerIndex);\r\n const afterSigner = afterLabel.substring(signerMarkerIndex + 10); // Skip \"__SIGNER__\"\r\n \r\n // Extract placeholder if present\r\n if (afterSigner.includes('__PLACEHOLDER__')) {\r\n const placeholderMarkerIndex = afterSigner.indexOf('__PLACEHOLDER__');\r\n assignedSignerEmail = afterSigner.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterSigner.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n assignedSignerEmail = afterSigner;\r\n }\r\n } else if (afterLabel.includes('__PLACEHOLDER__')) {\r\n // Label and placeholder but no signer\r\n const placeholderMarkerIndex = afterLabel.indexOf('__PLACEHOLDER__');\r\n displayLabel = afterLabel.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterLabel.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n displayLabel = afterLabel;\r\n }\r\n } else if (fieldName.includes('__SIGNER__')) {\r\n // Old format without label\r\n const signerMarkerIndex = fieldName.indexOf('__SIGNER__');\r\n decodedFieldName = fieldName.substring(0, signerMarkerIndex);\r\n const afterSigner = fieldName.substring(signerMarkerIndex + 10); // Skip \"__SIGNER__\"\r\n \r\n // Extract placeholder if present\r\n if (afterSigner.includes('__PLACEHOLDER__')) {\r\n const placeholderMarkerIndex = afterSigner.indexOf('__PLACEHOLDER__');\r\n assignedSignerEmail = afterSigner.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterSigner.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n assignedSignerEmail = afterSigner;\r\n }\r\n } else if (fieldName.includes('__PLACEHOLDER__')) {\r\n // Only placeholder present\r\n const placeholderMarkerIndex = fieldName.indexOf('__PLACEHOLDER__');\r\n decodedFieldName = fieldName.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = fieldName.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n }\r\n \r\n return {\r\n decodedFieldName,\r\n displayLabel,\r\n assignedSignerEmail,\r\n fieldPlaceholder,\r\n acknowledgements\r\n };\r\n}\r\n\r\n/**\r\n * Generate a fallback label from a decoded field name\r\n */\r\nexport function generateFallbackLabel(decodedFieldName: string, fieldType: FormFieldType): string {\r\n let displayLabel = decodedFieldName;\r\n \r\n // Remove ALL consecutive \"_signature\", \"_initials\", \"_date\" suffixes added by pdf-lib\r\n // This handles multiple suffixes from repeated PDF exports\r\n let prevLabel = '';\r\n while (displayLabel !== prevLabel) {\r\n prevLabel = displayLabel;\r\n displayLabel = displayLabel.replace(/_signature$/i, '').replace(/_initials$/i, '').replace(/_date$/i, '');\r\n }\r\n \r\n // Handle different naming patterns:\r\n // 1. Pure timestamp fields: \"text_1234567890\" → \"Text\"\r\n // 2. Timestamp with repeated type: \"Signature_1768236781866_Signature_Signature\" → \"Signature\"\r\n // 3. Descriptive fields: \"text_Primary_1\" → \"Text Primary\"\r\n // 4. Custom fields: \"customer_name\" → \"Customer Name\"\r\n \r\n // Pattern 1 & 2: Field name starts with type_timestamp (regardless of what follows)\r\n // This catches both \"text_1234567890\" and \"Signature_1768236781866_Signature_Signature\"\r\n if (/^(text|signature|initials|date|checkbox|radio|dropdown)_\\d+/i.test(displayLabel)) {\r\n // Auto-generated field name - return simple type name based on actual field type\r\n if (fieldType === FormFieldType.SIGNATURE) return 'Signature';\r\n if (fieldType === FormFieldType.INITIALS) return 'Initials';\r\n if (fieldType === FormFieldType.DATE) return 'Date';\r\n if (fieldType === FormFieldType.TEXT) return 'Text';\r\n if (fieldType === FormFieldType.CHECKBOX) return 'Checkbox';\r\n if (fieldType === FormFieldType.DROPDOWN) return 'Dropdown';\r\n if (fieldType === FormFieldType.RADIO) return 'Option';\r\n if (fieldType === FormFieldType.TEXT_LABEL) return 'Text Label';\r\n }\r\n \r\n // Pattern 3 & 4: Convert underscores to spaces, remove trailing numbers, capitalize\r\n displayLabel = displayLabel\r\n .replace(/_/g, ' ') // Convert underscores to spaces\r\n .replace(/\\s+\\d+$/g, '') // Remove trailing numbers (e.g., \" 1\")\r\n .trim()\r\n .split(' ') // Split into words\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize each word\r\n .join(' ');\r\n \r\n return displayLabel;\r\n}\r\n\r\n/**\r\n * Extract label from TU (tooltip) metadata in PDF field\r\n * @param field - The PDF field with extensions\r\n * @returns The extracted label or empty string\r\n */\r\nfunction extractTULabel(field: PDFFieldWithExtensions): string {\r\n try {\r\n if (!field.acroField?.dict) {\r\n return '';\r\n }\r\n \r\n const tuLabel = field.acroField.dict.get(PDFName.of('TU'));\r\n if (!tuLabel) {\r\n return '';\r\n }\r\n \r\n // PDFString has a decodeText() method or toString()\r\n const tuValue = tuLabel.toString();\r\n if (!tuValue || !tuValue.trim()) {\r\n return '';\r\n }\r\n \r\n // Handle PDF string encoding - extract content between parentheses or angle brackets\r\n // PDF strings are encoded as \"(text)\" or \"<hex>\"\r\n if (tuValue.startsWith('(') || tuValue.startsWith('<')) {\r\n const match = tuValue.match(/^\\((.*)\\)$/) || tuValue.match(/^<(.*)>$/);\r\n if (match && match[1]) {\r\n return match[1];\r\n }\r\n }\r\n \r\n // If no special encoding, return as-is\r\n return tuValue;\r\n } catch (error) {\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Find field by UUID using the fieldIdIndex\r\n * This is the SECURE way to lookup fields in multi-signer workflows\r\n * @param fields - Array of fields to search\r\n * @param uuid - The UUID to find\r\n * @returns The field or undefined\r\n */\r\nexport function findFieldByUuid(fields: EsignFormField[], uuid: string): EsignFormField | undefined {\r\n return fields.find(f => f.fieldId === uuid);\r\n}\r\n\r\n/**\r\n * Resolve a field name or UUID to the actual field\r\n * Priority: UUID lookup first (secure), then field name fallback\r\n * @param fields - Array of fields\r\n * @param identifier - Either a UUID or field name\r\n * @returns The field or undefined\r\n */\r\nexport function resolveField(fields: EsignFormField[], identifier: string): EsignFormField | undefined {\r\n // PRIORITY 1: Try UUID lookup (most secure, works across renames)\r\n let field = findFieldByUuid(fields, identifier);\r\n if (field) {\r\n return field;\r\n }\r\n \r\n // PRIORITY 2: Try by field.id\r\n field = fields.find(f => f.id === identifier);\r\n if (field) {\r\n return field;\r\n }\r\n \r\n // PRIORITY 3: Try by field.name\r\n field = fields.find(f => f.name === identifier);\r\n if (field) {\r\n return field;\r\n }\r\n \r\n // PRIORITY 4: Try without suffixes (for date/signature/initials fields)\r\n const cleanIdentifier = identifier.replace(/_signature$|_initials$|_date$/i, '');\r\n return fields.find(f => f.fieldId === cleanIdentifier || f.id === cleanIdentifier || f.name === cleanIdentifier);\r\n}\r\n\r\n/**\r\n * Get all fields assigned to a specific signer by UUID\r\n * @param fields - Array of fields\r\n * @param signerEmail - Email of the signer\r\n * @returns Array of field UUIDs assigned to this signer\r\n */\r\nexport function getFieldUuidsForSigner(fields: EsignFormField[], signerEmail: string): string[] {\r\n return fields\r\n .filter(f => f.assignedSignerEmail === signerEmail && f.fieldId)\r\n .map(f => f.fieldId!);\r\n}\r\n\r\n","/**\r\n * PDF.js Configuration Provider\r\n * Manages global configuration for PDF.js worker and viewer paths\r\n * \r\n * COMPATIBILITY NOTE: This module is designed to work with both Vite and Next.js/webpack.\r\n * The worker source URL is computed lazily to avoid issues with webpack's handling of import.meta.\r\n */\r\n\r\nimport type { PdfJsConfig } from '../types';\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\n\r\n/**\r\n * CDN paths for PDF.js (exported for manual fallback configuration)\r\n * Note: CDN URLs may cause CORS issues in some environments\r\n * \r\n * @example\r\n * // Manually configure CDN (not recommended)\r\n * setPdfJsConfig({ \r\n * viewerBasePath: CDN_VIEWER,\r\n * workerSrc: CDN_WORKER \r\n * });\r\n */\r\nexport const CDN_WORKER = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@5.3.93/build/pdf.worker.mjs';\r\nexport const CDN_VIEWER = 'https://mozilla.github.io/pdf.js';\r\n\r\n/**\r\n * Internal flag to track if worker source has been computed\r\n */\r\nlet _workerSrcComputed = false;\r\nlet _cachedWorkerSrc: string | null = null;\r\n\r\n/**\r\n * Get the worker source URL (computed lazily to avoid webpack import.meta issues)\r\n * - In browser environments, the bundler resolves the URL from node_modules\r\n * - The worker is loaded from the user's bundle (no CORS issues)\r\n * \r\n * This function uses lazy evaluation to avoid triggering webpack's\r\n * \"Critical dependency: Accessing import.meta directly is unsupported\" warning\r\n * at module load time.\r\n */\r\nfunction getDefaultWorkerSrc(): string {\r\n // Return cached value if already computed\r\n if (_workerSrcComputed && _cachedWorkerSrc !== null) {\r\n return _cachedWorkerSrc;\r\n }\r\n\r\n // Default fallback\r\n let workerSrc = '/pdfjs/build/pdf.worker.mjs';\r\n\r\n // Only attempt import.meta resolution in browser environment\r\n if (typeof window !== 'undefined' && typeof URL !== 'undefined') {\r\n try {\r\n // Check if import.meta is available (ESM environment like Vite)\r\n // Use indirect access to avoid webpack static analysis issues\r\n const meta = (function() {\r\n try {\r\n // This pattern avoids webpack's direct import.meta detection\r\n return new Function('return import.meta')();\r\n } catch {\r\n return null;\r\n }\r\n })();\r\n\r\n if (meta && meta.url) {\r\n workerSrc = new URL('pdfjs-dist/build/pdf.worker.mjs', meta.url).href;\r\n }\r\n } catch {\r\n // Fallback for environments that don't support import.meta.url (Next.js/webpack)\r\n // Use the public path fallback\r\n }\r\n }\r\n\r\n // Cache the result\r\n _workerSrcComputed = true;\r\n _cachedWorkerSrc = workerSrc;\r\n\r\n return workerSrc;\r\n}\r\n\r\n/**\r\n * Default configuration for PDF.js\r\n * \r\n * By default, the package uses:\r\n * - Worker: Loaded from node_modules (bundled by your build tool)\r\n * - Viewer: Served from /pdfjs/ (automatically copied by postinstall)\r\n * \r\n * The postinstall script automatically copies viewer files to your public/pdfjs/ directory.\r\n * If setup fails, run: npx signiphi-setup\r\n * \r\n * NOTE: workerSrc is initialized to null and computed lazily on first access\r\n * to ensure compatibility with Next.js/webpack environments.\r\n */\r\nlet globalConfig: Required<PdfJsConfig> = {\r\n viewerBasePath: '/pdfjs',\r\n workerSrc: '', // Lazy-initialized below\r\n};\r\n\r\n// Flag to track if globalConfig.workerSrc has been initialized\r\nlet _configInitialized = false;\r\n\r\n/**\r\n * Ensure config is initialized (called lazily)\r\n */\r\nfunction ensureConfigInitialized(): void {\r\n if (!_configInitialized) {\r\n globalConfig.workerSrc = getDefaultWorkerSrc();\r\n _configInitialized = true;\r\n \r\n // Initialize PDF.js worker in browser environment\r\n if (typeof window !== 'undefined') {\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = globalConfig.workerSrc;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Set PDF.js configuration\r\n * @param config - Partial configuration to merge with defaults\r\n * \r\n * @example\r\n * // Use self-hosted PDF.js files\r\n * setPdfJsConfig({ viewerBasePath: '/pdfjs' });\r\n * \r\n * @example\r\n * // Use custom CDN\r\n * setPdfJsConfig({ \r\n * viewerBasePath: 'https://my-cdn.com/pdfjs',\r\n * workerSrc: 'https://my-cdn.com/pdfjs/build/pdf.worker.mjs'\r\n * });\r\n */\r\nexport function setPdfJsConfig(config: Partial<PdfJsConfig>): void {\r\n // Ensure default config is computed first\r\n ensureConfigInitialized();\r\n \r\n if (config.viewerBasePath !== undefined) {\r\n globalConfig.viewerBasePath = config.viewerBasePath;\r\n }\r\n \r\n if (config.workerSrc !== undefined) {\r\n globalConfig.workerSrc = config.workerSrc;\r\n } else if (config.viewerBasePath !== undefined) {\r\n // Auto-update workerSrc based on viewerBasePath\r\n globalConfig.workerSrc = `${config.viewerBasePath}/build/pdf.worker.mjs`;\r\n }\r\n\r\n // Update PDF.js worker if in browser environment\r\n if (typeof window !== 'undefined') {\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = globalConfig.workerSrc;\r\n }\r\n}\r\n\r\n/**\r\n * Get current PDF.js configuration\r\n * @returns Current configuration\r\n */\r\nexport function getPdfJsConfig(): Required<PdfJsConfig> {\r\n // Ensure config is initialized before returning\r\n ensureConfigInitialized();\r\n return { ...globalConfig };\r\n}\r\n\r\n/**\r\n * Reset configuration to defaults (local files)\r\n */\r\nexport function resetPdfJsConfig(): void {\r\n // Clear cached worker src to force recomputation\r\n _workerSrcComputed = false;\r\n _cachedWorkerSrc = null;\r\n _configInitialized = false;\r\n \r\n // Re-initialize with fresh defaults\r\n ensureConfigInitialized();\r\n}\r\n\r\n/**\r\n * Initialize PDF.js configuration\r\n * This is called automatically when the first PDF operation is attempted,\r\n * but can also be called manually to pre-initialize the configuration.\r\n * \r\n * Unlike previous versions, this does NOT run at module load time to\r\n * ensure compatibility with Next.js/webpack environments.\r\n */\r\nexport function initializePdfJs(): void {\r\n ensureConfigInitialized();\r\n}\r\n\r\n","/**\r\n * PDF.js Version Check Utility\r\n * Detects version mismatches between viewer and worker\r\n */\r\n\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\n\r\nexport interface PdfJsVersionCheckResult {\r\n viewerExists: boolean;\r\n versionMatch: boolean;\r\n viewerVersion?: string;\r\n workerVersion: string;\r\n errorMessage?: string;\r\n}\r\n\r\n/**\r\n * Check if PDF.js viewer files exist and versions match\r\n * @param viewerBasePath - Base path for the viewer (e.g., '/pdfjs')\r\n * @returns Version check result\r\n */\r\nexport async function checkPdfJsVersion(\r\n viewerBasePath: string = '/pdfjs'\r\n): Promise<PdfJsVersionCheckResult> {\r\n const workerVersion = pdfjsLib.version;\r\n \r\n try {\r\n // Check if version file exists (use version.txt, not dotfile — Next.js blocks dotfiles)\r\n const versionUrl = `${viewerBasePath}/version.txt`;\r\n const response = await fetch(versionUrl);\r\n \r\n if (!response.ok) {\r\n return {\r\n viewerExists: false,\r\n versionMatch: false,\r\n workerVersion,\r\n errorMessage: 'PDF.js viewer files not found. Run: npx signiphi-setup',\r\n };\r\n }\r\n \r\n const viewerVersion = (await response.text()).trim();\r\n const versionMatch = viewerVersion === workerVersion;\r\n \r\n if (!versionMatch) {\r\n return {\r\n viewerExists: true,\r\n versionMatch: false,\r\n viewerVersion,\r\n workerVersion,\r\n errorMessage: `Version mismatch: viewer=${viewerVersion}, worker=${workerVersion}. Run: npx signiphi-setup`,\r\n };\r\n }\r\n \r\n return {\r\n viewerExists: true,\r\n versionMatch: true,\r\n viewerVersion,\r\n workerVersion,\r\n };\r\n } catch (error) {\r\n return {\r\n viewerExists: false,\r\n versionMatch: false,\r\n workerVersion,\r\n errorMessage: 'Unable to check PDF.js version. Viewer files may not be installed.',\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Log version check warnings to console\r\n * @param result - Version check result\r\n */\r\nexport function logVersionCheckWarning(result: PdfJsVersionCheckResult): void {\r\n if (!result.viewerExists) {\r\n console.warn(\r\n '⚠️ PDF.js viewer files not found.\\n' +\r\n 'The PDF viewer requires viewer files to be installed.\\n' +\r\n 'Run: npx signiphi-setup\\n' +\r\n 'Or reinstall the package: npm install @signiphi/pdf-signer'\r\n );\r\n } else if (!result.versionMatch) {\r\n console.warn(\r\n `⚠️ PDF.js version mismatch detected:\\n` +\r\n ` Viewer: ${result.viewerVersion}\\n` +\r\n ` Worker: ${result.workerVersion}\\n` +\r\n 'Run: npx signiphi-setup to sync versions'\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Check version and log warnings automatically\r\n * @param viewerBasePath - Base path for the viewer\r\n */\r\nexport async function checkAndLogPdfJsVersion(\r\n viewerBasePath: string = '/pdfjs'\r\n): Promise<PdfJsVersionCheckResult> {\r\n const result = await checkPdfJsVersion(viewerBasePath);\r\n \r\n if (!result.viewerExists || !result.versionMatch) {\r\n logVersionCheckWarning(result);\r\n }\r\n \r\n return result;\r\n}\r\n\r\n","/**\r\n * Audit Trail Utilities\r\n * Captures device metadata, IP address, and geolocation for compliance and forensics\r\n */\r\n\r\nimport type { AuditTrailMetadata } from '../types';\r\nimport { logger } from './logger';\r\n\r\n/**\r\n * Synchronously capture device and browser metadata\r\n */\r\nexport function captureDeviceMetadata(): Partial<AuditTrailMetadata> {\r\n const metadata: Partial<AuditTrailMetadata> = {};\r\n\r\n try {\r\n // User agent (truncated to 100 chars)\r\n if (navigator.userAgent) {\r\n metadata.userAgent = navigator.userAgent.substring(0, 100);\r\n }\r\n\r\n // Screen resolution\r\n if (screen.width && screen.height) {\r\n metadata.screenResolution = `${screen.width}x${screen.height}`;\r\n }\r\n\r\n // Timezone\r\n try {\r\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n if (timezone) {\r\n metadata.timezone = timezone;\r\n }\r\n } catch {\r\n // Timezone unavailable\r\n }\r\n\r\n // Language\r\n if (navigator.language) {\r\n metadata.language = navigator.language;\r\n }\r\n\r\n // Platform\r\n if (navigator.platform) {\r\n metadata.platform = navigator.platform;\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing device metadata:', error);\r\n }\r\n\r\n return metadata;\r\n}\r\n\r\n/**\r\n * Capture IP address using public API\r\n */\r\nexport async function captureIpAddress(): Promise<string> {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout\r\n\r\n const ipResponse = await fetch('https://api.ipify.org?format=json', {\r\n method: 'GET',\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (ipResponse.ok) {\r\n const ipData = await ipResponse.json();\r\n if (ipData.ip) {\r\n return ipData.ip;\r\n }\r\n }\r\n\r\n return 'Unknown';\r\n } catch (error) {\r\n return 'Unknown';\r\n }\r\n}\r\n\r\n/**\r\n * Capture geolocation using browser geolocation API\r\n */\r\nexport async function captureGeolocation(): Promise<{\r\n latitude: number;\r\n longitude: number;\r\n accuracy?: number;\r\n} | null> {\r\n if (!navigator.geolocation) {\r\n return null;\r\n }\r\n\r\n try {\r\n const position = await new Promise<GeolocationPosition>((resolve, reject) => {\r\n navigator.geolocation.getCurrentPosition(resolve, reject, {\r\n timeout: 10000, // 10 second timeout\r\n enableHighAccuracy: false,\r\n maximumAge: 300000, // 5 minutes cache\r\n });\r\n });\r\n\r\n if (position.coords) {\r\n const latitude = parseFloat(position.coords.latitude.toFixed(4));\r\n const longitude = parseFloat(position.coords.longitude.toFixed(4));\r\n const accuracy = position.coords.accuracy\r\n ? Math.round(position.coords.accuracy)\r\n : undefined;\r\n\r\n\r\n return {\r\n latitude,\r\n longitude,\r\n accuracy,\r\n };\r\n }\r\n\r\n return null;\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Capture complete audit trail metadata\r\n * Combines device metadata, IP address, and geolocation\r\n */\r\nexport async function captureAuditTrail(): Promise<AuditTrailMetadata> {\r\n\r\n const auditTrail: AuditTrailMetadata = {};\r\n\r\n try {\r\n // Capture device metadata (synchronous)\r\n const deviceMetadata = captureDeviceMetadata();\r\n Object.assign(auditTrail, deviceMetadata);\r\n\r\n // Capture IP address (async, with timeout)\r\n try {\r\n const ipAddress = await captureIpAddress();\r\n auditTrail.ipAddress = ipAddress;\r\n } catch (error) {\r\n logger.warn('Error capturing IP address:', error);\r\n auditTrail.ipAddress = 'Unknown';\r\n }\r\n\r\n // Capture geolocation (async, requires permission)\r\n try {\r\n const geolocation = await captureGeolocation();\r\n if (geolocation) {\r\n auditTrail.geolocation = geolocation;\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing geolocation:', error);\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing audit trail:', error);\r\n }\r\n\r\n return auditTrail;\r\n}\r\n\r\n","/**\r\n * Custom Error Classes\r\n * Domain-specific error types for better error handling and debugging\r\n */\r\n\r\n/**\r\n * Error thrown when PDF validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * const validation = validatePdfBytes(bytes);\r\n * if (!validation.valid) {\r\n * throw new PdfValidationError(validation.error || 'Invalid PDF');\r\n * }\r\n * ```\r\n */\r\nexport class PdfValidationError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'PdfValidationError';\r\n // Maintains proper stack trace for where error was thrown (V8 only)\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, PdfValidationError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown during PDF processing operations\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * const pdfDoc = await PDFDocument.load(bytes);\r\n * } catch (err) {\r\n * throw new PdfProcessingError('Failed to load PDF document', err);\r\n * }\r\n * ```\r\n */\r\nexport class PdfProcessingError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'PdfProcessingError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, PdfProcessingError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown for form field related issues\r\n * \r\n * @example\r\n * ```ts\r\n * if (!field.value && field.required) {\r\n * throw new FormFieldError(\r\n * 'Required field is empty',\r\n * field.name\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport class FormFieldError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly fieldName?: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'FormFieldError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, FormFieldError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown for attachment validation failures\r\n * \r\n * @example\r\n * ```ts\r\n * if (file.size > maxFileSize) {\r\n * throw new AttachmentValidationError(\r\n * `File size exceeds limit: ${file.name}`,\r\n * file.name\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport class AttachmentValidationError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly fileName?: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'AttachmentValidationError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, AttachmentValidationError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a PdfValidationError\r\n */\r\nexport function isPdfValidationError(error: unknown): error is PdfValidationError {\r\n return error instanceof PdfValidationError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a PdfProcessingError\r\n */\r\nexport function isPdfProcessingError(error: unknown): error is PdfProcessingError {\r\n return error instanceof PdfProcessingError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a FormFieldError\r\n */\r\nexport function isFormFieldError(error: unknown): error is FormFieldError {\r\n return error instanceof FormFieldError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is an AttachmentValidationError\r\n */\r\nexport function isAttachmentValidationError(error: unknown): error is AttachmentValidationError {\r\n return error instanceof AttachmentValidationError;\r\n}\r\n\r\n/**\r\n * Extract error message from unknown error type\r\n * \r\n * @param error - The error to extract message from\r\n * @param defaultMessage - Default message if extraction fails\r\n * @returns Error message string\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * // ... operation\r\n * } catch (err) {\r\n * const message = getErrorMessage(err, 'Operation failed');\r\n * logger.error(message);\r\n * }\r\n * ```\r\n */\r\nexport function getErrorMessage(error: unknown, defaultMessage = 'Unknown error'): string {\r\n if (error instanceof Error) {\r\n return error.message;\r\n }\r\n if (typeof error === 'string') {\r\n return error;\r\n }\r\n return defaultMessage;\r\n}\r\n\r\n","/**\r\n * Attachment Validation Utilities\r\n * Validation functions for file attachments\r\n */\r\n\r\nimport type { AttachmentConstraints, Attachment } from '../types';\r\nimport { AttachmentValidationError } from './errors';\r\n\r\n/**\r\n * Default attachment constraints\r\n */\r\nexport const DEFAULT_ATTACHMENT_CONSTRAINTS: AttachmentConstraints = {\r\n maxFileSize: 25 * 1024 * 1024, // 25MB\r\n maxTotalSize: 50 * 1024 * 1024, // 50MB\r\n maxFiles: 10,\r\n allowedTypes: ['image/*', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],\r\n allowedExtensions: ['.pdf', '.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.doc', '.docx'],\r\n};\r\n\r\n/**\r\n * Validate a single file against constraints\r\n * \r\n * @param file - File to validate\r\n * @param constraints - Validation constraints\r\n * @returns Validation result with errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFile(file, DEFAULT_ATTACHMENT_CONSTRAINTS);\r\n * if (result.errors.length > 0) {\r\n * console.error('File validation failed:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFile(\r\n file: File,\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n\r\n // Validate file size\r\n if (file.size > constraints.maxFileSize) {\r\n const maxMB = (constraints.maxFileSize / 1024 / 1024).toFixed(1);\r\n const fileMB = (file.size / 1024 / 1024).toFixed(1);\r\n errors.push(`File \"${file.name}\" is too large (${fileMB}MB). Maximum size is ${maxMB}MB.`);\r\n }\r\n\r\n // Validate file type (MIME type)\r\n const isTypeAllowed = constraints.allowedTypes.some((allowedType) => {\r\n if (allowedType.endsWith('/*')) {\r\n // Wildcard type (e.g., 'image/*')\r\n const prefix = allowedType.slice(0, -2);\r\n return file.type.startsWith(prefix);\r\n }\r\n return file.type === allowedType;\r\n });\r\n\r\n if (!isTypeAllowed && constraints.allowedTypes.length > 0) {\r\n errors.push(\r\n `File type \"${file.type}\" is not allowed for \"${file.name}\". Allowed types: ${constraints.allowedTypes.join(', ')}`\r\n );\r\n }\r\n\r\n // Validate file extension\r\n if (constraints.allowedExtensions && constraints.allowedExtensions.length > 0) {\r\n const fileExt = '.' + file.name.split('.').pop()?.toLowerCase();\r\n const isExtAllowed = constraints.allowedExtensions.some(\r\n (ext) => ext.toLowerCase() === fileExt\r\n );\r\n\r\n if (!isExtAllowed) {\r\n errors.push(\r\n `File extension \"${fileExt}\" is not allowed for \"${file.name}\". Allowed extensions: ${constraints.allowedExtensions.join(', ')}`\r\n );\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate multiple files against constraints\r\n * \r\n * @param files - Files to validate\r\n * @param existingAttachments - Existing attachments to consider for total size/count\r\n * @param constraints - Validation constraints\r\n * @returns Validation result with errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFiles(newFiles, existingAttachments, DEFAULT_ATTACHMENT_CONSTRAINTS);\r\n * if (result.errors.length > 0) {\r\n * alert('Some files cannot be uploaded: ' + result.errors.join(', '));\r\n * }\r\n * ```\r\n */\r\nexport function validateFiles(\r\n files: File[],\r\n existingAttachments: Attachment[] = [],\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n\r\n // Validate total number of files\r\n const totalFiles = files.length + existingAttachments.length;\r\n if (totalFiles > constraints.maxFiles) {\r\n errors.push(\r\n `Too many files. Maximum allowed is ${constraints.maxFiles}, you have ${totalFiles} files total.`\r\n );\r\n }\r\n\r\n // Validate total size\r\n const existingSize = existingAttachments.reduce((sum, att) => sum + att.size, 0);\r\n const newFilesSize = files.reduce((sum, file) => sum + file.size, 0);\r\n const totalSize = existingSize + newFilesSize;\r\n\r\n if (totalSize > constraints.maxTotalSize) {\r\n const maxMB = (constraints.maxTotalSize / 1024 / 1024).toFixed(1);\r\n const totalMB = (totalSize / 1024 / 1024).toFixed(1);\r\n errors.push(\r\n `Total size of all files is too large (${totalMB}MB). Maximum total size is ${maxMB}MB.`\r\n );\r\n }\r\n\r\n // Validate each individual file\r\n for (const file of files) {\r\n const fileResult = validateFile(file, constraints);\r\n errors.push(...fileResult.errors);\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate file and throw error if invalid\r\n * \r\n * Convenience function that throws AttachmentValidationError if validation fails.\r\n * \r\n * @param file - File to validate\r\n * @param constraints - Validation constraints\r\n * @throws {AttachmentValidationError} If validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * validateFileOrThrow(file);\r\n * // File is valid, proceed with upload\r\n * } catch (err) {\r\n * if (err instanceof AttachmentValidationError) {\r\n * alert(err.message);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function validateFileOrThrow(\r\n file: File,\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): void {\r\n const result = validateFile(file, constraints);\r\n if (!result.valid) {\r\n throw new AttachmentValidationError(\r\n `File validation failed: ${result.errors.join('; ')}`,\r\n file.name,\r\n { file, errors: result.errors }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Validate multiple files and throw error if invalid\r\n * \r\n * @param files - Files to validate\r\n * @param existingAttachments - Existing attachments\r\n * @param constraints - Validation constraints\r\n * @throws {AttachmentValidationError} If validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * validateFilesOrThrow(selectedFiles, currentAttachments);\r\n * // All files are valid\r\n * } catch (err) {\r\n * if (err instanceof AttachmentValidationError) {\r\n * alert(err.message);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function validateFilesOrThrow(\r\n files: File[],\r\n existingAttachments: Attachment[] = [],\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): void {\r\n const result = validateFiles(files, existingAttachments, constraints);\r\n if (!result.valid) {\r\n throw new AttachmentValidationError(\r\n `File validation failed: ${result.errors.join('; ')}`,\r\n undefined,\r\n { files, errors: result.errors }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Check if a file type is an image\r\n * \r\n * @param fileType - MIME type of the file\r\n * @returns true if the file is an image\r\n * \r\n * @example\r\n * ```ts\r\n * if (isImageType(file.type)) {\r\n * // Generate preview\r\n * }\r\n * ```\r\n */\r\nexport function isImageType(fileType: string): boolean {\r\n return fileType.startsWith('image/');\r\n}\r\n\r\n/**\r\n * Format file size for display\r\n * \r\n * @param bytes - File size in bytes\r\n * @returns Formatted size string (e.g., \"1.5 MB\")\r\n * \r\n * @example\r\n * ```ts\r\n * const sizeDisplay = formatFileSize(file.size); // \"1.5 MB\"\r\n * ```\r\n */\r\nexport function formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 Bytes';\r\n \r\n const k = 1024;\r\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n \r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n}\r\n\r\n","/**\r\n * Performance Monitoring Utility\r\n * \r\n * Provides utilities for tracking and measuring performance metrics\r\n * in critical operations like PDF loading, form filling, and signature capture.\r\n * \r\n * Usage:\r\n * ```typescript\r\n * const monitor = createPerformanceMonitor();\r\n * const endTimer = monitor.startTimer('pdf-load');\r\n * await loadPdf(url);\r\n * endTimer();\r\n * const metrics = monitor.getMetrics();\r\n * ```\r\n */\r\n\r\nimport { logger } from './logger';\r\n\r\nexport interface PerformanceMetric {\r\n label: string;\r\n duration: number;\r\n timestamp: number;\r\n}\r\n\r\nexport interface PerformanceMetrics {\r\n [label: string]: {\r\n count: number;\r\n total: number;\r\n avg: number;\r\n min: number;\r\n max: number;\r\n last: number;\r\n };\r\n}\r\n\r\n/**\r\n * Performance Monitor Class\r\n * \r\n * Tracks performance metrics for various operations.\r\n * Maintains history and calculates statistics (avg, min, max).\r\n */\r\nexport class PerformanceMonitor {\r\n private metrics: Map<string, number[]> = new Map();\r\n private enabled: boolean;\r\n\r\n constructor(enabled: boolean = true) {\r\n this.enabled = enabled;\r\n }\r\n\r\n /**\r\n * Start a timer for a labeled operation\r\n * \r\n * @param label - Unique label for the operation\r\n * @returns Function to call when operation completes\r\n * \r\n * @example\r\n * ```typescript\r\n * const endTimer = monitor.startTimer('pdf-load');\r\n * await loadPdf(url);\r\n * endTimer(); // Records duration\r\n * ```\r\n */\r\n startTimer(label: string): () => void {\r\n if (!this.enabled) {\r\n return () => {}; // No-op if disabled\r\n }\r\n\r\n const startTime = performance.now();\r\n\r\n return () => {\r\n const duration = performance.now() - startTime;\r\n this.measure(label, duration);\r\n };\r\n }\r\n\r\n /**\r\n * Manually record a performance measurement\r\n * \r\n * @param label - Unique label for the operation\r\n * @param duration - Duration in milliseconds\r\n * \r\n * @example\r\n * ```typescript\r\n * monitor.measure('pdf-load', 1234.56);\r\n * ```\r\n */\r\n measure(label: string, duration: number): void {\r\n if (!this.enabled) {\r\n return;\r\n }\r\n\r\n const measurements = this.metrics.get(label) || [];\r\n measurements.push(duration);\r\n this.metrics.set(label, measurements);\r\n\r\n logger.info(`[Performance] ${label}: ${duration.toFixed(2)}ms`);\r\n }\r\n\r\n /**\r\n * Get all recorded metrics with statistics\r\n * \r\n * @returns Object containing metrics for all labels\r\n * \r\n * @example\r\n * ```typescript\r\n * const metrics = monitor.getMetrics();\r\n * console.log(`PDF load avg: ${metrics['pdf-load'].avg}ms`);\r\n * ```\r\n */\r\n getMetrics(): PerformanceMetrics {\r\n const result: PerformanceMetrics = {};\r\n\r\n for (const [label, measurements] of this.metrics.entries()) {\r\n if (measurements.length === 0) continue;\r\n\r\n const total = measurements.reduce((sum, val) => sum + val, 0);\r\n const avg = total / measurements.length;\r\n const min = Math.min(...measurements);\r\n const max = Math.max(...measurements);\r\n const last = measurements[measurements.length - 1] ?? 0;\r\n\r\n result[label] = {\r\n count: measurements.length,\r\n total,\r\n avg,\r\n min,\r\n max,\r\n last,\r\n };\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Get metrics for a specific label\r\n * \r\n * @param label - Label to get metrics for\r\n * @returns Metrics for the label, or null if not found\r\n */\r\n getMetric(label: string): PerformanceMetrics[string] | null {\r\n const measurements = this.metrics.get(label);\r\n if (!measurements || measurements.length === 0) {\r\n return null;\r\n }\r\n\r\n const total = measurements.reduce((sum, val) => sum + val, 0);\r\n const avg = total / measurements.length;\r\n const min = Math.min(...measurements);\r\n const max = Math.max(...measurements);\r\n const last = measurements[measurements.length - 1] ?? 0;\r\n\r\n return {\r\n count: measurements.length,\r\n total,\r\n avg,\r\n min,\r\n max,\r\n last,\r\n };\r\n }\r\n\r\n /**\r\n * Get raw measurements for a label\r\n * \r\n * @param label - Label to get measurements for\r\n * @returns Array of duration measurements in milliseconds\r\n */\r\n getRawMeasurements(label: string): number[] {\r\n return this.metrics.get(label) || [];\r\n }\r\n\r\n /**\r\n * Clear all metrics\r\n */\r\n clear(): void {\r\n this.metrics.clear();\r\n }\r\n\r\n /**\r\n * Clear metrics for a specific label\r\n * \r\n * @param label - Label to clear metrics for\r\n */\r\n clearLabel(label: string): void {\r\n this.metrics.delete(label);\r\n }\r\n\r\n /**\r\n * Enable or disable performance monitoring\r\n * \r\n * @param enabled - Whether to enable monitoring\r\n */\r\n setEnabled(enabled: boolean): void {\r\n this.enabled = enabled;\r\n }\r\n\r\n /**\r\n * Check if monitoring is enabled\r\n */\r\n isEnabled(): boolean {\r\n return this.enabled;\r\n }\r\n\r\n /**\r\n * Generate a performance report as a string\r\n * \r\n * @returns Formatted performance report\r\n */\r\n generateReport(): string {\r\n const metrics = this.getMetrics();\r\n const lines: string[] = [];\r\n\r\n lines.push('Performance Report');\r\n lines.push('='.repeat(50));\r\n lines.push('');\r\n\r\n for (const [label, stats] of Object.entries(metrics)) {\r\n lines.push(`${label}:`);\r\n lines.push(` Count: ${stats.count}`);\r\n lines.push(` Avg: ${stats.avg.toFixed(2)}ms`);\r\n lines.push(` Min: ${stats.min.toFixed(2)}ms`);\r\n lines.push(` Max: ${stats.max.toFixed(2)}ms`);\r\n lines.push(` Last: ${stats.last.toFixed(2)}ms`);\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n }\r\n}\r\n\r\n/**\r\n * Create a new performance monitor instance\r\n * \r\n * @param enabled - Whether to enable monitoring (default: true in development)\r\n * @returns PerformanceMonitor instance\r\n * \r\n * @example\r\n * ```typescript\r\n * const monitor = createPerformanceMonitor();\r\n * ```\r\n */\r\nexport function createPerformanceMonitor(enabled?: boolean): PerformanceMonitor {\r\n const isEnabled = enabled ?? process.env.NODE_ENV === 'development';\r\n return new PerformanceMonitor(isEnabled);\r\n}\r\n\r\n/**\r\n * Global performance monitor instance\r\n * Can be used across the application for centralized monitoring\r\n */\r\nexport const globalPerformanceMonitor = createPerformanceMonitor();\r\n\r\n/**\r\n * Decorator for measuring function performance\r\n * \r\n * @param label - Label for the performance measurement\r\n * @param monitor - Performance monitor instance (defaults to global)\r\n * @returns Function decorator\r\n * \r\n * @example\r\n * ```typescript\r\n * class MyClass {\r\n * @measurePerformance('my-operation')\r\n * async myOperation() {\r\n * // ... operation code ...\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function measurePerformance(\r\n label: string,\r\n monitor: PerformanceMonitor = globalPerformanceMonitor\r\n) {\r\n return function (\r\n _target: any,\r\n _propertyKey: string,\r\n descriptor: PropertyDescriptor\r\n ) {\r\n const originalMethod = descriptor.value;\r\n\r\n descriptor.value = async function (...args: any[]) {\r\n const endTimer = monitor.startTimer(label);\r\n try {\r\n const result = await originalMethod.apply(this, args);\r\n return result;\r\n } finally {\r\n endTimer();\r\n }\r\n };\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Higher-order function to wrap async functions with performance monitoring\r\n * \r\n * @param label - Label for the performance measurement\r\n * @param fn - Function to wrap\r\n * @param monitor - Performance monitor instance (defaults to global)\r\n * @returns Wrapped function\r\n * \r\n * @example\r\n * ```typescript\r\n * const loadPdfWithMonitoring = withPerformanceMonitoring(\r\n * 'pdf-load',\r\n * loadPdf\r\n * );\r\n * ```\r\n */\r\nexport function withPerformanceMonitoring<T extends (...args: any[]) => Promise<any>>(\r\n label: string,\r\n fn: T,\r\n monitor: PerformanceMonitor = globalPerformanceMonitor\r\n): T {\r\n return (async (...args: any[]) => {\r\n const endTimer = monitor.startTimer(label);\r\n try {\r\n return await fn(...args);\r\n } finally {\r\n endTimer();\r\n }\r\n }) as T;\r\n}\r\n\r\n","/**\r\n * ISO Date Validation Utility\r\n * Lightweight validation for ISO 8601 date strings (YYYY-MM-DD)\r\n * Separated from full date-validation to avoid pulling in the heavier `parse` dependency\r\n * from date-fns when only ISO validation is needed.\r\n */\r\n\r\nimport { isValid as isValidDate, parseISO } from 'date-fns';\r\n\r\n/**\r\n * Validate if a string is a valid ISO date (YYYY-MM-DD)\r\n */\r\nexport function isValidISODate(value: string | null | undefined): boolean {\r\n if (!value || typeof value !== 'string') {\r\n return false;\r\n }\r\n\r\n const isoPattern = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n if (!isoPattern.test(value)) {\r\n return false;\r\n }\r\n\r\n try {\r\n const date = parseISO(value);\r\n return isValidDate(date) && !isNaN(date.getTime());\r\n } catch {\r\n return false;\r\n }\r\n}\r\n","/**\r\n * Date Validation and Parsing Utility\r\n * Handles parsing of various date formats and validation\r\n */\r\n\r\nimport { parse, isValid as isValidDate, parseISO } from 'date-fns';\r\n\r\n// Re-export isValidISODate from its own module so consumers that only need ISO\r\n// validation (e.g. hooks) can import from date-validation-iso directly and avoid\r\n// pulling in the heavier `parse` dependency.\r\nexport { isValidISODate } from './date-validation-iso';\r\n\r\nexport interface DateValidationResult {\r\n isValid: boolean;\r\n date: Date | null;\r\n isoString: string | null;\r\n originalValue: string;\r\n error?: string;\r\n}\r\n\r\nfunction toIsoDateString(date: Date): string {\r\n const year = date.getFullYear();\r\n const month = String(date.getMonth() + 1).padStart(2, '0');\r\n const day = String(date.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\n/**\r\n * Parse and validate a date string from various formats\r\n * Attempts to parse common formats: ISO, US, EU, timestamps\r\n * \r\n * Format priority:\r\n * 1. ISO 8601 (YYYY-MM-DD)\r\n * 2. US format (MM/DD/YYYY) - assumes US format for ambiguous dates\r\n * 3. EU format (DD/MM/YYYY)\r\n * 4. Timestamp (numeric string)\r\n * \r\n * @param value - The date string to parse\r\n * @returns Validation result with parsed date or error\r\n */\r\nexport function parseAndValidateDate(value: string | null | undefined): DateValidationResult {\r\n const originalValue = String(value || '');\r\n \r\n // Handle empty values\r\n if (!value || value.trim() === '') {\r\n return {\r\n isValid: false,\r\n date: null,\r\n isoString: null,\r\n originalValue,\r\n error: 'Date is required',\r\n };\r\n }\r\n\r\n const trimmedValue = value.trim();\r\n const sanitizedValue = trimmedValue\r\n // Remove ordinal suffixes (1st, 2nd, 3rd, 21st, etc.)\r\n .replace(/(\\d+)(st|nd|rd|th)/gi, '$1')\r\n // Normalize commas to spaces for natural language inputs\r\n .replace(/,/g, ' ')\r\n .replace(/\\s+/g, ' ')\r\n .trim();\r\n\r\n // Try ISO 8601 format first (YYYY-MM-DD)\r\n try {\r\n const isoDate = parseISO(trimmedValue);\r\n if (isValidDate(isoDate) && !isNaN(isoDate.getTime())) {\r\n return {\r\n isValid: true,\r\n date: isoDate,\r\n isoString: trimmedValue,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Continue to next format\r\n }\r\n\r\n // Handle two-digit year inputs like 01/05/24 by assuming 2000-based year\r\n const shortYearMatch = sanitizedValue.match(/^(\\d{1,2})[\\/.\\-](\\d{1,2})[\\/.\\-](\\d{2})$/);\r\n if (shortYearMatch) {\r\n const [, monthStr, dayStr, yearStr] = shortYearMatch;\r\n const month = parseInt(monthStr ?? '', 10);\r\n const day = parseInt(dayStr ?? '', 10);\r\n const year = 2000 + parseInt(yearStr ?? '', 10);\r\n const candidate = new Date(year, month - 1, day);\r\n if (isValidDate(candidate) && !isNaN(candidate.getTime())) {\r\n return {\r\n isValid: true,\r\n date: candidate,\r\n isoString: toIsoDateString(candidate),\r\n originalValue,\r\n };\r\n }\r\n }\r\n\r\n // Try common date formats\r\n const formats = [\r\n // US formats (MM/DD/YYYY - assume US for ambiguous dates)\r\n { pattern: 'MM/dd/yyyy', name: 'US format (MM/DD/YYYY)' },\r\n { pattern: 'M/d/yyyy', name: 'US format (M/D/YYYY)' },\r\n { pattern: 'MM-dd-yyyy', name: 'US format (MM-DD-YYYY)' },\r\n { pattern: 'M-d-yyyy', name: 'US format (M-D-YYYY)' },\r\n { pattern: 'MM/dd/yy', name: 'US format (MM/DD/YY)' },\r\n { pattern: 'M/d/yy', name: 'US format (M/D/YY)' },\r\n { pattern: 'MM-dd-yy', name: 'US format (MM-DD-YY)' },\r\n { pattern: 'M-d-yy', name: 'US format (M-D-YY)' },\r\n \r\n // EU formats (DD/MM/YYYY)\r\n { pattern: 'dd/MM/yyyy', name: 'EU format (DD/MM/YYYY)' },\r\n { pattern: 'd/M/yyyy', name: 'EU format (D/M/YYYY)' },\r\n { pattern: 'dd.MM.yyyy', name: 'EU format (DD.MM.YYYY)' },\r\n { pattern: 'd.M.yyyy', name: 'EU format (D.M.YYYY)' },\r\n \r\n // Full month names\r\n { pattern: 'MMMM d, yyyy', name: 'Month name format (January 1, 2024)' },\r\n { pattern: 'MMM d, yyyy', name: 'Short month format (Jan 1, 2024)' },\r\n { pattern: 'MMMM d yyyy', name: 'Month name format without comma (January 1 2024)' },\r\n { pattern: 'MMM d yyyy', name: 'Short month without comma (Jan 1 2024)' },\r\n { pattern: 'd MMMM yyyy', name: 'EU month format (1 January 2024)' },\r\n { pattern: 'd MMM yyyy', name: 'EU month short format (1 Jan 2024)' },\r\n { pattern: 'd MMM, yyyy', name: 'EU month short with comma (1 Jan, 2024)' },\r\n \r\n // Year first formats\r\n { pattern: 'yyyy/MM/dd', name: 'ISO-like format (YYYY/MM/DD)' },\r\n { pattern: 'yyyy-MM-dd', name: 'ISO format with dashes' },\r\n ];\r\n\r\n const referenceDate = new Date();\r\n\r\n for (const { pattern } of formats) {\r\n try {\r\n const parsedDate = parse(sanitizedValue, pattern, referenceDate);\r\n if (isValidDate(parsedDate) && !isNaN(parsedDate.getTime())) {\r\n // Convert to ISO string format (YYYY-MM-DD)\r\n const isoString = toIsoDateString(parsedDate);\r\n \r\n return {\r\n isValid: true,\r\n date: parsedDate,\r\n isoString,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Continue to next format\r\n }\r\n }\r\n\r\n // Try parsing as timestamp (milliseconds)\r\n if (/^\\d+$/.test(trimmedValue)) {\r\n try {\r\n const timestamp = parseInt(trimmedValue, 10);\r\n const date = new Date(timestamp);\r\n if (isValidDate(date) && !isNaN(date.getTime())) {\r\n const isoString = toIsoDateString(date);\r\n \r\n return {\r\n isValid: true,\r\n date,\r\n isoString,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Not a valid timestamp\r\n }\r\n }\r\n\r\n // Lenient fallback using native Date parsing after sanitization\r\n const nativeParsed = new Date(sanitizedValue);\r\n if (isValidDate(nativeParsed) && !isNaN(nativeParsed.getTime())) {\r\n return {\r\n isValid: true,\r\n date: nativeParsed,\r\n isoString: toIsoDateString(nativeParsed),\r\n originalValue,\r\n };\r\n }\r\n\r\n // All formats failed\r\n return {\r\n isValid: false,\r\n date: null,\r\n isoString: null,\r\n originalValue,\r\n error: `Invalid date format: \"${trimmedValue}\". Please use a date picker or format like MM/DD/YYYY.`,\r\n };\r\n}\r\n\r\n\r\n","/**\r\n * Usage tracking utilities for signiphi API integration.\r\n * Enables automatic tracking of document sends and signings via API key.\r\n */\r\n\r\nimport { logger } from './logger';\r\n\r\n/**\r\n * Configuration for the tracking API\r\n */\r\nexport interface TrackingConfig {\r\n /** API key for authentication */\r\n apiKey: string;\r\n /** Custom API endpoint (defaults to https://api.signiphi.ai) */\r\n endpoint?: string;\r\n}\r\n\r\n/**\r\n * Data for tracking a document send event\r\n */\r\nexport interface TrackSendData {\r\n /** Email address of the recipient */\r\n recipientEmail: string;\r\n /** Optional document ID for correlation */\r\n documentId?: string;\r\n /** Optional idempotency key to prevent duplicate tracking */\r\n idempotencyKey?: string;\r\n /** Optional additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Data for tracking a document signing event\r\n */\r\nexport interface TrackSigningData {\r\n /** Email address of the signer */\r\n signerEmail: string;\r\n /** Optional document ID for correlation */\r\n documentId?: string;\r\n /** Optional idempotency key to prevent duplicate tracking */\r\n idempotencyKey?: string;\r\n /** Optional additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Response from tracking API\r\n */\r\nexport interface TrackingResponse {\r\n success: boolean;\r\n eventId: string;\r\n idempotencyKey: string;\r\n usage: {\r\n currentMonth: number;\r\n limit: number;\r\n remaining: number;\r\n };\r\n}\r\n\r\nconst DEFAULT_API_ENDPOINT = 'https://api-dev.signiphi.ai';\r\n// const DEFAULT_API_ENDPOINT = 'http://localhost:4000';\r\nconst API_PREFIX = '/api/v1';\r\n\r\n/**\r\n * Track a document send event.\r\n * Call this when a document is sent to a recipient for signing.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Send event data\r\n * @returns Tracking response with usage stats\r\n */\r\nexport async function trackDocumentSent(\r\n config: TrackingConfig,\r\n data: TrackSendData,\r\n): Promise<TrackingResponse> {\r\n const endpoint = config.endpoint || DEFAULT_API_ENDPOINT;\r\n const url = `${endpoint}${API_PREFIX}/usage/track-send`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': config.apiKey,\r\n },\r\n body: JSON.stringify({\r\n recipientEmail: data.recipientEmail,\r\n documentId: data.documentId,\r\n idempotencyKey: data.idempotencyKey,\r\n metadata: data.metadata,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n logger.error(`Track send failed: ${response.status} - ${errorText}`);\r\n throw new Error(`Tracking failed: ${response.status}`);\r\n }\r\n\r\n const result = await response.json();\r\n logger.debug('Document send tracked successfully', { eventId: result.eventId });\r\n return result;\r\n } catch (error) {\r\n logger.error('Failed to track document send:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Track a document signing event.\r\n * Call this when a document is signed by a recipient.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Signing event data\r\n * @returns Tracking response with usage stats\r\n */\r\nexport async function trackDocumentSigned(\r\n config: TrackingConfig,\r\n data: TrackSigningData,\r\n): Promise<TrackingResponse> {\r\n const endpoint = config.endpoint || DEFAULT_API_ENDPOINT;\r\n const url = `${endpoint}${API_PREFIX}/usage/track-signing`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': config.apiKey,\r\n },\r\n body: JSON.stringify({\r\n signerEmail: data.signerEmail,\r\n documentId: data.documentId,\r\n idempotencyKey: data.idempotencyKey,\r\n metadata: data.metadata,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n logger.error(`Track signing failed: ${response.status} - ${errorText}`);\r\n throw new Error(`Tracking failed: ${response.status}`);\r\n }\r\n\r\n const result = await response.json();\r\n logger.debug('Document signing tracked successfully', { eventId: result.eventId });\r\n return result;\r\n } catch (error) {\r\n logger.error('Failed to track document signing:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Silently track a document signing event (non-blocking).\r\n * This version catches errors and logs them without throwing.\r\n * Use this when tracking failure should not affect the main flow.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Signing event data\r\n */\r\nexport async function trackDocumentSignedSilent(\r\n config: TrackingConfig,\r\n data: TrackSigningData,\r\n): Promise<void> {\r\n try {\r\n await trackDocumentSigned(config, data);\r\n } catch (error) {\r\n logger.warn('Silent tracking failed (non-critical):', error);\r\n }\r\n}\r\n\r\n/**\r\n * Silently track a document send event (non-blocking).\r\n * This version catches errors and logs them without throwing.\r\n * Use this when tracking failure should not affect the main flow.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Send event data\r\n */\r\nexport async function trackDocumentSentSilent(\r\n config: TrackingConfig,\r\n data: TrackSendData,\r\n): Promise<void> {\r\n try {\r\n await trackDocumentSent(config, data);\r\n } catch (error) {\r\n logger.warn('Silent tracking failed (non-critical):', error);\r\n }\r\n}\r\n\r\n"]}