@nodii/onboarding 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +46 -0
  2. package/dist/{chunk-KQTS47FC.js → chunk-A3DE2IAH.js} +30 -5
  3. package/dist/chunk-A3DE2IAH.js.map +1 -0
  4. package/dist/{chunk-U6AXKGYQ.js → chunk-DWFZA5T6.js} +10 -8
  5. package/dist/chunk-DWFZA5T6.js.map +1 -0
  6. package/dist/{chunk-F75ZJERM.js → chunk-KFHVZGX6.js} +34 -14
  7. package/dist/chunk-KFHVZGX6.js.map +1 -0
  8. package/dist/{chunk-U56GQITG.js → chunk-NDSBIB3N.js} +25 -5
  9. package/dist/chunk-NDSBIB3N.js.map +1 -0
  10. package/dist/chunk-OLWR5COK.js +10 -0
  11. package/dist/chunk-OLWR5COK.js.map +1 -0
  12. package/dist/{chunk-IPAKPLIF.js → chunk-OVULPWNZ.js} +341 -80
  13. package/dist/chunk-OVULPWNZ.js.map +1 -0
  14. package/dist/{chunk-LVJM4CTG.js → chunk-T7EWURTF.js} +34 -19
  15. package/dist/chunk-T7EWURTF.js.map +1 -0
  16. package/dist/{chunk-BMQINH6O.js → chunk-UHOFGWI7.js} +5 -4
  17. package/dist/chunk-UHOFGWI7.js.map +1 -0
  18. package/dist/{chunk-SIMLMQPT.js → chunk-WKN4U7QF.js} +3 -5
  19. package/dist/chunk-WKN4U7QF.js.map +1 -0
  20. package/dist/{chunk-AZE3NPSY.js → chunk-ZR6X3GSM.js} +3 -3
  21. package/dist/{chunk-AZE3NPSY.js.map → chunk-ZR6X3GSM.js.map} +1 -1
  22. package/dist/{client-CqE2dF9A.d.ts → client-NvqPpfQP.d.ts} +1 -1
  23. package/dist/consent/index.d.ts +3 -3
  24. package/dist/consent/index.js +2 -2
  25. package/dist/{controller-BQb62D0N.d.ts → controller-BLH3wnxl.d.ts} +1 -1
  26. package/dist/dynamic/index.d.ts +13 -5
  27. package/dist/dynamic/index.js +4 -3
  28. package/dist/form/index.d.ts +12 -4
  29. package/dist/form/index.js +2 -2
  30. package/dist/{index-Dqfa890U.d.ts → index-BMSbQGWP.d.ts} +23 -3
  31. package/dist/index.d.ts +8 -8
  32. package/dist/index.js +9 -8
  33. package/dist/{model-mnjAEtKe.d.ts → model-BI_I-D_V.d.ts} +16 -2
  34. package/dist/{model-ESLSEbi0.d.ts → model-CEwvHlWA.d.ts} +14 -1
  35. package/dist/render-EWQXF73I.js +5 -0
  36. package/dist/{render-DC7P2BGQ.js.map → render-EWQXF73I.js.map} +1 -1
  37. package/dist/{schema-BrXb9gnh.d.ts → schema-BrtjpXfL.d.ts} +0 -10
  38. package/dist/{signup-client-BL5DfarJ.d.ts → signup-client-CS95nkVO.d.ts} +4 -4
  39. package/dist/spec/index.d.ts +3 -3
  40. package/dist/spec/index.js +2 -2
  41. package/dist/submit/index.d.ts +5 -5
  42. package/dist/submit/index.js +3 -2
  43. package/dist/viewer/index.d.ts +3 -3
  44. package/dist/viewer/index.js +1 -1
  45. package/dist/widget/index.d.ts +61 -22
  46. package/dist/widget/index.js +9 -8
  47. package/package.json +1 -1
  48. package/dist/chunk-BMQINH6O.js.map +0 -1
  49. package/dist/chunk-F75ZJERM.js.map +0 -1
  50. package/dist/chunk-IPAKPLIF.js.map +0 -1
  51. package/dist/chunk-KQTS47FC.js.map +0 -1
  52. package/dist/chunk-LVJM4CTG.js.map +0 -1
  53. package/dist/chunk-SIMLMQPT.js.map +0 -1
  54. package/dist/chunk-U56GQITG.js.map +0 -1
  55. package/dist/chunk-U6AXKGYQ.js.map +0 -1
  56. package/dist/render-DC7P2BGQ.js +0 -5
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/widget/dom-utils.ts","../src/widget/styles.ts","../src/widget/contact-form.ts","../src/widget/consent-step.ts","../src/widget/signup-form.ts","../src/widget/index.ts"],"names":["el"],"mappings":";;;;;;;;;;AAiBO,SAAS,UAAU,KAAA,EAAuB;AAC/C,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,IAAI,EAAE,GAAA,IAAO,OAAO,CAAA,CAAE,GAAA,CAAI,WAAW,UAAA,EAAY;AAC/C,IAAA,OAAO,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA;AAAA,EAC3B;AAGA,EAAA,OAAO,MAAM,OAAA,CAAQ,iBAAA,EAAmB,CAAC,EAAA,KAAO,CAAA,EAAA,EAAK,EAAE,CAAA,CAAE,CAAA;AAC3D;AAGO,SAAS,WAAW,EAAA,EAAoB;AAC7C,EAAA,OAAO,CAAA,CAAA,EAAI,SAAA,CAAU,EAAE,CAAC,CAAA,CAAA;AAC1B;;;ACRO,IAAM,kBAAA,GAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AA+b3B,SAAS,kBAAA,GAA2B;AAC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","file":"chunk-OVULPWNZ.js","sourcesContent":["/**\n * Shared DOM helpers for the widget layer.\n *\n * `idSelector` builds a `#id` CSS selector with the id CSS-escaped, so a field\n * key (which originates in the fetched onboarder spec) can never break out of\n * the selector or match unintended nodes. This is defense-in-depth: the spec\n * model already constrains field keys to `[A-Za-z0-9_-]+` (FIELD_KEY_PATTERN),\n * but the escaping guarantees selector safety even for the widget's own\n * internally-composed ids and for any future relaxation of that alphabet.\n */\n\n/**\n * CSS-escape a string for safe use as an identifier in a selector.\n * Uses the standard `CSS.escape` when available (all modern browsers), with a\n * spec-compliant-enough fallback for non-DOM/test runtimes: escape everything\n * that is not an ASCII identifier char.\n */\nexport function cssEscape(value: string): string {\n const g = globalThis as { CSS?: { escape?: (v: string) => string } };\n if (g.CSS && typeof g.CSS.escape === \"function\") {\n return g.CSS.escape(value);\n }\n // Fallback: backslash-escape any char outside [A-Za-z0-9_-]. Sufficient to\n // neutralize CSS metacharacters ([]().,#*:>+~ whitespace, quotes, etc.).\n return value.replace(/[^A-Za-z0-9_-]/g, (ch) => `\\\\${ch}`);\n}\n\n/** Build a safe `#id` selector with the id CSS-escaped. */\nexport function idSelector(id: string): string {\n return `#${cssEscape(id)}`;\n}\n","/// <reference lib=\"dom\" />\n/// <reference lib=\"dom.iterable\" />\n/**\n * Default CSS for the onboarding contact form widget.\n *\n * Uses CSS custom properties (variables) for theming. Consumers override\n * these on the host element or globally:\n *\n * --nodii-onboarding-font-family\n * --nodii-onboarding-primary-color\n * --nodii-onboarding-primary-hover\n * --nodii-onboarding-error-color\n * --nodii-onboarding-border-color\n * --nodii-onboarding-input-bg\n * --nodii-onboarding-label-color\n * --nodii-onboarding-radius\n * --nodii-onboarding-spacing\n *\n * The widget scopes all styles under `.nodii-onboarding-widget` to avoid\n * leaking into the host page.\n */\n\nexport const DEFAULT_WIDGET_CSS = `\n.nodii-onboarding-widget {\n --_font: var(--nodii-onboarding-font-family, system-ui, -apple-system, sans-serif);\n --_primary: var(--nodii-onboarding-primary-color, #2563eb);\n --_primary-hover: var(--nodii-onboarding-primary-hover, #1d4ed8);\n --_error: var(--nodii-onboarding-error-color, #dc2626);\n --_border: var(--nodii-onboarding-border-color, #d1d5db);\n --_input-bg: var(--nodii-onboarding-input-bg, #fff);\n --_label: var(--nodii-onboarding-label-color, #374151);\n --_radius: var(--nodii-onboarding-radius, 6px);\n --_spacing: var(--nodii-onboarding-spacing, 16px);\n\n font-family: var(--_font);\n box-sizing: border-box;\n}\n\n.nodii-onboarding-widget *,\n.nodii-onboarding-widget *::before,\n.nodii-onboarding-widget *::after {\n box-sizing: inherit;\n}\n\n.nodii-onboarding-field {\n display: flex;\n flex-direction: column;\n gap: calc(var(--_spacing) * 0.25);\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--_label);\n}\n\n.nodii-onboarding-label.required::after {\n content: \" *\";\n color: var(--_error);\n}\n\n.nodii-onboarding-input,\n.nodii-onboarding-textarea {\n width: 100%;\n padding: calc(var(--_spacing) * 0.5) calc(var(--_spacing) * 0.75);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_input-bg);\n font-family: var(--_font);\n font-size: 1rem;\n line-height: 1.5;\n outline: none;\n transition: border-color 0.15s ease;\n}\n\n.nodii-onboarding-input:focus,\n.nodii-onboarding-textarea:focus {\n border-color: var(--_primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--_primary) 20%, transparent);\n}\n\n.nodii-onboarding-input.has-error,\n.nodii-onboarding-textarea.has-error {\n border-color: var(--_error);\n}\n\n.nodii-onboarding-textarea {\n min-height: 100px;\n resize: vertical;\n}\n\n.nodii-onboarding-field-error {\n font-size: 0.75rem;\n color: var(--_error);\n margin-top: 2px;\n}\n\n.nodii-onboarding-server-error {\n padding: calc(var(--_spacing) * 0.75);\n border-radius: var(--_radius);\n background: color-mix(in srgb, var(--_error) 8%, transparent);\n border: 1px solid color-mix(in srgb, var(--_error) 30%, transparent);\n color: var(--_error);\n font-size: 0.875rem;\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-success {\n padding: var(--_spacing);\n border-radius: var(--_radius);\n background: #f0fdf4;\n border: 1px solid #bbf7d0;\n color: #15803d;\n font-size: 0.9375rem;\n text-align: center;\n}\n\n.nodii-onboarding-submit-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n background: var(--_primary);\n color: #fff;\n border: none;\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 1rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.nodii-onboarding-submit-btn:hover:not(:disabled) {\n background: var(--_primary-hover);\n}\n\n.nodii-onboarding-submit-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.nodii-onboarding-spinner {\n display: inline-block;\n width: 1em;\n height: 1em;\n border: 2px solid rgba(255,255,255,0.4);\n border-top-color: #fff;\n border-radius: 50%;\n animation: nodii-spin 0.6s linear infinite;\n margin-right: 0.5em;\n}\n\n@keyframes nodii-spin {\n to { transform: rotate(360deg); }\n}\n\n.nodii-onboarding-recaptcha-notice {\n font-size: 0.7rem;\n color: #6b7280;\n margin-top: calc(var(--_spacing) * 0.5);\n text-align: center;\n}\n\n.nodii-onboarding-recaptcha-notice a {\n color: inherit;\n}\n\n/* ── dynamic stepper (signup form) ── */\n\n.nodii-onboarding-steps {\n display: flex;\n gap: calc(var(--_spacing) * 0.5);\n margin-bottom: var(--_spacing);\n}\n\n.nodii-onboarding-step-dot {\n flex: 1;\n height: 4px;\n border-radius: 2px;\n background: var(--_border);\n}\n\n.nodii-onboarding-step-dot.active {\n background: var(--_primary);\n}\n\n.nodii-onboarding-stage-title {\n font-size: 1.0625rem;\n font-weight: 600;\n color: var(--_label);\n margin: 0 0 var(--_spacing) 0;\n}\n\n.nodii-onboarding-nav {\n display: flex;\n gap: calc(var(--_spacing) * 0.5);\n margin-top: var(--_spacing);\n}\n\n.nodii-onboarding-back-btn {\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n background: transparent;\n color: var(--_label);\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 1rem;\n cursor: pointer;\n}\n\n.nodii-onboarding-stale-banner {\n padding: calc(var(--_spacing) * 0.75);\n border-radius: var(--_radius);\n background: #fffbeb;\n border: 1px solid #fcd34d;\n color: #92400e;\n font-size: 0.875rem;\n margin-bottom: var(--_spacing);\n}\n\nfieldset.nodii-onboarding-field {\n border: none;\n padding: 0;\n margin-inline: 0;\n}\n\n.nodii-onboarding-choices {\n display: flex;\n flex-wrap: wrap;\n gap: calc(var(--_spacing) * 0.5);\n}\n\n.nodii-onboarding-choice {\n display: inline-flex;\n align-items: center;\n gap: calc(var(--_spacing) * 0.375);\n padding: calc(var(--_spacing) * 0.375) calc(var(--_spacing) * 0.75);\n border: 1px solid var(--_border);\n border-radius: 999px;\n background: var(--_input-bg);\n font-size: 0.875rem;\n color: var(--_label);\n cursor: pointer;\n}\n\nfieldset.nodii-onboarding-field.has-error .nodii-onboarding-choice {\n border-color: var(--_error);\n}\n\n.nodii-onboarding-consent-row {\n display: flex;\n align-items: flex-start;\n gap: calc(var(--_spacing) * 0.5);\n margin-bottom: calc(var(--_spacing) * 0.5);\n font-size: 0.875rem;\n color: var(--_label);\n}\n\n.nodii-onboarding-consent-row input[type=\"checkbox\"] {\n margin-top: 3px;\n}\n\n.nodii-onboarding-account-section {\n border-top: 1px solid var(--_border);\n margin-top: var(--_spacing);\n padding-top: var(--_spacing);\n}\n\n.nodii-onboarding-loading {\n padding: var(--_spacing);\n text-align: center;\n color: var(--_label);\n}\n\n/* ── D543 ConsentPack step (full-width, generous spacing) ── */\n\n.nodii-onboarding-consent-stage {\n /* Full-bleed within the widget host — consent cards may span the page. */\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: calc(var(--_spacing) * 2);\n margin: calc(var(--_spacing) * 1.5) 0;\n}\n\n.nodii-onboarding-consent-intro {\n font-size: 0.9375rem;\n color: var(--_label);\n margin: 0 0 calc(var(--_spacing) * 0.5) 0;\n line-height: 1.6;\n}\n\n.nodii-onboarding-consent-card {\n width: 100%;\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: var(--_input-bg);\n padding: calc(var(--_spacing) * 1.5);\n display: flex;\n flex-direction: column;\n gap: var(--_spacing);\n}\n\n.nodii-onboarding-consent-card.is-stale {\n border-color: #fcd34d;\n background: #fffbeb;\n}\n\n.nodii-onboarding-consent-card.has-error {\n border-color: var(--_error);\n}\n\n.nodii-onboarding-consent-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--_label);\n margin: 0;\n}\n\n.nodii-onboarding-consent-stale-tag {\n font-size: 0.8125rem;\n font-weight: 500;\n color: #92400e;\n}\n\n.nodii-onboarding-consent-gate {\n width: 100%;\n}\n\n.nodii-onboarding-consent-scrollbox {\n width: 100%;\n height: 360px;\n overflow-y: auto;\n border: 1px solid var(--_border);\n border-radius: var(--_radius);\n background: #fff;\n position: relative;\n}\n\n.nodii-onboarding-consent-scrollbox:focus {\n outline: none;\n border-color: var(--_primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--_primary) 20%, transparent);\n}\n\n/* Inline, same-origin document content (no iframe). Rendered by the default\n viewer: sanitized HTML/markdown, escaped plain text, or PDF.js canvases. */\n.nodii-onboarding-consent-doc-body {\n padding: var(--_spacing);\n font-size: 0.9375rem;\n line-height: 1.7;\n color: var(--_label);\n word-break: break-word;\n}\n\n.nodii-onboarding-consent-doc-body:not(.nodii-consent-pdf) {\n white-space: pre-wrap;\n}\n\n.nodii-onboarding-consent-doc-loading {\n padding: var(--_spacing);\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.nodii-consent-pdf {\n display: flex;\n flex-direction: column;\n gap: var(--_spacing);\n white-space: normal;\n}\n\n.nodii-consent-pdf-page {\n max-width: 100%;\n height: auto;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n}\n\n.nodii-onboarding-consent-note {\n font-size: 0.8125rem;\n color: #6b7280;\n margin: calc(var(--_spacing) * 0.5) 0 0 0;\n}\n\n/* A gated doc that could not be rendered inline: the gate stays unsatisfiable\n (accept disabled); we surface a clear error + Retry. NO click-to-satisfy. */\n.nodii-onboarding-consent-unrenderable {\n display: flex;\n flex-direction: column;\n gap: calc(var(--_spacing) * 0.5);\n padding: var(--_spacing);\n border: 1px solid color-mix(in srgb, var(--_error) 30%, transparent);\n border-radius: var(--_radius);\n background: color-mix(in srgb, var(--_error) 6%, transparent);\n}\n\n.nodii-onboarding-consent-retry {\n align-self: flex-start;\n padding: calc(var(--_spacing) * 0.5) var(--_spacing);\n background: transparent;\n color: var(--_primary);\n border: 1px solid var(--_primary);\n border-radius: var(--_radius);\n font-family: var(--_font);\n font-size: 0.875rem;\n cursor: pointer;\n}\n\n.nodii-onboarding-consent-open-row,\n.nodii-onboarding-consent-preview-row {\n display: flex;\n}\n\n.nodii-onboarding-consent-open {\n display: inline-flex;\n align-items: center;\n padding: calc(var(--_spacing) * 0.625) var(--_spacing);\n border: 1px solid var(--_primary);\n border-radius: var(--_radius);\n color: var(--_primary);\n text-decoration: none;\n font-size: 0.9375rem;\n font-weight: 500;\n}\n\n.nodii-onboarding-consent-open:hover {\n background: color-mix(in srgb, var(--_primary) 8%, transparent);\n}\n\n.nodii-onboarding-consent-preview {\n font-size: 0.875rem;\n color: var(--_primary);\n}\n\n.nodii-onboarding-consent-accept-row {\n display: flex;\n align-items: flex-start;\n gap: calc(var(--_spacing) * 0.5);\n}\n\n.nodii-onboarding-consent-accept {\n margin-top: 3px;\n width: 1.125rem;\n height: 1.125rem;\n}\n\n.nodii-onboarding-consent-accept:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.nodii-onboarding-consent-accept-label {\n font-size: 0.9375rem;\n color: var(--_label);\n line-height: 1.5;\n}\n\n.nodii-onboarding-consent-required {\n color: var(--_error);\n}\n`;\n\n/**\n * Inject the default widget CSS once into the document head.\n * Idempotent — will not add a duplicate style tag.\n */\nexport function injectWidgetStyles(): void {\n if (typeof document === \"undefined\") return;\n const styleId = \"__nodii_onboarding_styles__\";\n if (document.getElementById(styleId)) return;\n const style = document.createElement(\"style\");\n style.id = styleId;\n style.textContent = DEFAULT_WIDGET_CSS;\n document.head.appendChild(style);\n}\n","/// <reference lib=\"dom\" />\n/// <reference lib=\"dom.iterable\" />\n/**\n * Default vanilla-TS contact form widget.\n *\n * Renders a form into a host element and handles the full lifecycle:\n * 1. Render the D1165 lead fields: company, contact name, email, phone,\n * message, the interest and team-size choices, the privacy-notice\n * acknowledgement and the marketing opt-in\n * 2. Client-side validation on submit\n * 3. reCAPTCHA token acquisition (D537) — only while a challenge is in\n * force (D1444: an onboarder can switch the bot check off)\n * 4. POST to /api/v1/public/onboarding/leads via submit client\n * 5. Retry on 5xx with SAME idempotency key\n * 6. Show success or error state\n *\n * The field SET is fixed (it is the `/leads` wire contract); the choices\n * inside it are the onboarder's. Pass the spec from `fetchOnboardingSpec`\n * and the interests, team sizes, privacy-notice link and bot-challenge\n * siteKey all come from it.\n *\n * No React or framework required. CSS via injectWidgetStyles().\n */\n\nimport {\n createContactFormState,\n type ContactFormControl,\n type FieldError,\n} from \"../form/state.js\";\nimport { contactFormSchema, type ContactFormValues } from \"../form/schema.js\";\nimport type { OnboardingSpec } from \"../spec/model.js\";\nimport { fetchOnboardingSpec, OnboardingSpecCache } from \"../spec/client.js\";\nimport { isNavigableUrl } from \"../consent/url.js\";\nimport { optionValue } from \"../dynamic/derive.js\";\nimport {\n submitLead,\n generateIdempotencyKey,\n computePayloadFingerprint,\n} from \"../submit/client.js\";\nimport {\n OnboardingBotChallengeError,\n OnboardingRateLimitError,\n OnboardingValidationError,\n} from \"../submit/errors.js\";\nimport { executeRecaptcha, loadRecaptcha } from \"../recaptcha/loader.js\";\nimport { idSelector } from \"./dom-utils.js\";\nimport { injectWidgetStyles } from \"./styles.js\";\n\nexport interface ContactFormMountOptions {\n /**\n * The onboarder identifier (slug or UUID).\n *\n * NOT transmitted on the wire — by design. Per LOCKED D536, onboarder\n * trust/scoping is derived server-side from the request Host at the edge\n * (\"onboarder derived from the bundle, never client-supplied\", D540 §1);\n * a client-supplied identifier is never trusted and therefore never sent.\n * It is the client-side spec-cache key (`fetchOnboardingSpec`).\n */\n onboarder: string;\n /**\n * Base URL for the intake service.\n * e.g. \"https://api.acme.nucleus-cloud.in\"\n */\n baseUrl: string;\n /**\n * The onboarder's spec, from `fetchOnboardingSpec`. Supplies the interest\n * and team-size choices (`forms.contact`), the field labels, the\n * privacy-notice link (the ConsentPack's privacy document) and the\n * bot-challenge siteKey. Without it the widget renders the text fields and\n * the two checkboxes only.\n *\n * The widget draws a fixed set of fields: company, contact name and email\n * are always required, and the spec's `required` flag is honoured for the\n * interest choice only. Phone, team size and message are always optional\n * here (as the platform spec publishes them), and the address fields are\n * not drawn. An onboarder that requires more builds its own form on the\n * headless `@nodii/onboarding/form` and `/submit` modules.\n */\n spec?: OnboardingSpec;\n /**\n * reCAPTCHA v3 site key override. Normally taken from `spec.botChallenge`;\n * with neither, no token is requested and Google is never loaded (D1444).\n */\n siteKey?: string;\n /** Which form to render. \"signup\" is `mountSignupForm`. */\n form: \"contact\";\n /**\n * Which door this form is (D1165 §1). Default \"enquiry\": what every lead\n * from this widget carried before 0.2.0, and the headless form's default.\n */\n intakeKind?: ContactFormValues[\"intakeKind\"];\n /** Campaign tags, referring site, landing page, button — stamped on the lead. */\n attribution?: ContactFormValues[\"attribution\"];\n /** Privacy-notice link override (defaults to the spec's privacy document). */\n privacyUrl?: string;\n /**\n * How often a mounted form re-reads the spec to keep the privacy-notice link\n * live, in ms (default 5 minutes). The spec's link is the ConsentPack's\n * presigned download URL, which expires (D543 §4: ten minutes on dev), and\n * a visitor can sit on a form longer than that. Applies only when the link\n * comes from `spec`; 0 turns it off. Reads happen only while the form is in\n * the document; call `unmount()` to stop the timer.\n */\n specRefreshMs?: number;\n /** Called after a successful lead submission. */\n onSuccess?: () => void;\n /** Called on non-retryable errors (bot challenge, rate limit). */\n onError?: (error: unknown) => void;\n /** Custom fetch implementation (defaults to globalThis.fetch). */\n fetch?: typeof globalThis.fetch;\n /**\n * Per-request timeout in ms (default 15s), applied to BOTH the reCAPTCHA\n * execute() and the submit POST so a hung dependency re-enables the form.\n */\n timeoutMs?: number;\n /** Success message override. */\n successMessage?: string;\n /** Submit button label override. */\n submitLabel?: string;\n}\n\nexport interface MountedWidget {\n /** Unmount and clean up the widget from the host element. */\n unmount(): void;\n /** Reset the form to its initial state. */\n reset(): void;\n}\n\ninterface Choice {\n value: string;\n label: string;\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Record<string, string> = {},\n children: Array<HTMLElement | Text | string> = [],\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tag);\n for (const [key, value] of Object.entries(attrs)) {\n element.setAttribute(key, value);\n }\n for (const child of children) {\n if (typeof child === \"string\") {\n element.appendChild(document.createTextNode(child));\n } else {\n element.appendChild(child);\n }\n }\n return element;\n}\n\nfunction errorSlot(id: string): HTMLElement {\n return el(\"div\", {\n class: \"nodii-onboarding-field-error\",\n id: `${id}-error`,\n role: \"alert\",\n \"aria-live\": \"polite\",\n });\n}\n\nfunction createFieldEl(\n id: string,\n label: string,\n input: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement,\n required: boolean,\n): HTMLElement {\n const labelEl = el(\n \"label\",\n { for: id, class: `nodii-onboarding-label${required ? \" required\" : \"\"}` },\n [label],\n );\n return el(\"div\", { class: \"nodii-onboarding-field\" }, [\n labelEl,\n input,\n errorSlot(id),\n ]);\n}\n\n/** Shows `message` on the field; false when the form draws no such field. */\nfunction setFieldError(\n container: HTMLElement,\n fieldId: string,\n message: string,\n): boolean {\n // CSS-escape the id: never build a selector from unescaped input.\n const errorEl = container.querySelector(idSelector(`${fieldId}-error`));\n if (errorEl) errorEl.textContent = message;\n const inputEl = container.querySelector(idSelector(fieldId));\n if (inputEl) inputEl.classList.add(\"has-error\");\n return errorEl !== null;\n}\n\nfunction clearFieldErrors(container: HTMLElement): void {\n for (const el of container.querySelectorAll(\n \".nodii-onboarding-field-error\",\n )) {\n el.textContent = \"\";\n }\n for (const el of container.querySelectorAll(\".has-error\")) {\n el.classList.remove(\"has-error\");\n }\n}\n\n/** Puts each error on its field. Returns how many have no field on the form. */\nfunction applyErrors(container: HTMLElement, errors: FieldError[]): number {\n clearFieldErrors(container);\n let unplaced = 0;\n for (const err of errors) {\n // Zod paths are bare field names (\"companyName\"); the DOM ids carry the\n // \"nodii-\" prefix (\"nodii-companyName\"). Map explicitly — a bare path\n // would querySelector nothing and silently drop the error display.\n // A nested path (\"attribution.button\") reports on its top-level field.\n const field = err.path.split(\".\")[0] ?? err.path;\n if (!setFieldError(container, `nodii-${field}`, err.message)) unplaced++;\n }\n return unplaced;\n}\n\n/**\n * The values a host passes that the form takes as given, checked when it\n * mounts. A bad one is the host's bug: refused here, loudly, instead of\n * failing every submit with an error no field can show, or putting a script\n * link on the page (a `privacyUrl` filled from a query string or a CMS).\n */\nfunction assertHostValues(options: ContactFormMountOptions): void {\n if (options.privacyUrl !== undefined && !isNavigableUrl(options.privacyUrl)) {\n throw new OnboardingValidationError(\n \"mountContactForm: invalid privacyUrl: must be an http(s) URL, absolute or relative\",\n );\n }\n const shape = contactFormSchema.shape;\n for (const [name, schema, value] of [\n [\"intakeKind\", shape.intakeKind, options.intakeKind],\n [\"attribution\", shape.attribution, options.attribution],\n ] as const) {\n if (value === undefined) continue;\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n throw new OnboardingValidationError(\n `mountContactForm: invalid ${[name, ...(issue?.path ?? [])].join(\".\")}: ${issue?.message ?? \"invalid\"}`,\n );\n }\n }\n}\n\n/** Half the dev presign TTL (D543 §4), as the Nodii website refreshes its own form. */\nconst DEFAULT_SPEC_REFRESH_MS = 5 * 60 * 1000;\n\n/**\n * The onboarder's live privacy notice: the ConsentPack's privacy document.\n * A parsed spec has already refused a non-http(s) link; this re-checks for a\n * host that hands the widget a spec object it built itself.\n */\nfunction privacyDocumentUrl(\n spec: OnboardingSpec | undefined,\n): string | undefined {\n const url = spec?.consentPack?.documents.find(\n (d) => d.docType === \"privacy\",\n )?.downloadUrl;\n return url && isNavigableUrl(url) ? url : undefined;\n}\n\n/** The onboarder's published choices for one `forms.contact` field. */\nfunction choicesOf(spec: OnboardingSpec | undefined, key: string): Choice[] {\n const field = spec?.forms.contact.fields.find((f) => f.key === key);\n return (field?.options ?? []).map((option) => {\n const value = optionValue(option);\n const label =\n option !== null &&\n typeof option === \"object\" &&\n typeof (option as { label?: unknown }).label === \"string\"\n ? (option as { label: string }).label\n : value;\n return { value, label };\n });\n}\n\nfunction isRequired(spec: OnboardingSpec | undefined, key: string): boolean {\n return (\n spec?.forms.contact.fields.find((f) => f.key === key)?.required === true\n );\n}\n\n/** The onboarder's label for a field, else the widget's own. */\nfunction labelOf(\n spec: OnboardingSpec | undefined,\n key: string,\n fallback: string,\n): string {\n const label = spec?.forms.contact.fields.find((f) => f.key === key)?.label;\n return label?.trim() ? label : fallback;\n}\n\n/**\n * Mount the contact form widget into a host element.\n *\n * @example\n * ```ts\n * import { fetchOnboardingSpec } from \"@nodii/onboarding/spec\";\n * import { OnboardingWidget } from \"@nodii/onboarding/widget\";\n * const baseUrl = \"https://api.acme.nucleus-cloud.in\";\n * const spec = await fetchOnboardingSpec({ baseUrl, onboarder: \"acme-corp\" });\n * OnboardingWidget.mount(document.getElementById(\"contact\")!, {\n * onboarder: \"acme-corp\",\n * form: \"contact\",\n * baseUrl,\n * spec,\n * });\n * ```\n */\nexport function mountContactForm(\n host: HTMLElement,\n options: ContactFormMountOptions,\n): MountedWidget {\n assertHostValues(options);\n injectWidgetStyles();\n\n const spec = options.spec;\n const interests = choicesOf(spec, \"interestModules\");\n const sizes = choicesOf(spec, \"sizeBand\");\n const interestRequired =\n interests.length > 0 && isRequired(spec, \"interestModules\");\n const privacyUrl = options.privacyUrl ?? privacyDocumentUrl(spec);\n // D1444: the spec omits botChallenge when the onboarder has switched the\n // bot check off; then there is no key, no token and no Google script.\n const siteKey = options.siteKey ?? spec?.botChallenge?.siteKey;\n\n const formControl: ContactFormControl = createContactFormState({\n requireInterest: interestRequired,\n });\n formControl.setValue(\"intakeKind\", options.intakeKind ?? \"enquiry\");\n if (options.attribution) {\n formControl.setValue(\"attribution\", options.attribution);\n }\n\n // Pre-load reCAPTCHA script to minimize latency at submit time.\n // Non-fatal: the loader evicts its cache on failure, so a failed\n // pre-load genuinely retries from scratch at submit time.\n if (siteKey) {\n loadRecaptcha(siteKey).catch(() => {\n // Swallowed by design — executeRecaptcha at submit re-attempts.\n });\n }\n\n // --- Build DOM ---\n const wrapper = el(\"div\", { class: \"nodii-onboarding-widget\" });\n\n const companyInput = el(\"input\", {\n type: \"text\",\n id: \"nodii-companyName\",\n name: \"companyName\",\n class: \"nodii-onboarding-input\",\n autocomplete: \"organization\",\n maxlength: \"200\",\n required: \"required\",\n }) as HTMLInputElement;\n\n const contactInput = el(\"input\", {\n type: \"text\",\n id: \"nodii-contactName\",\n name: \"contactName\",\n class: \"nodii-onboarding-input\",\n autocomplete: \"name\",\n maxlength: \"200\",\n required: \"required\",\n }) as HTMLInputElement;\n\n const emailInput = el(\"input\", {\n type: \"email\",\n id: \"nodii-email\",\n name: \"email\",\n class: \"nodii-onboarding-input\",\n placeholder: \"you@company.com\",\n autocomplete: \"email\",\n required: \"required\",\n }) as HTMLInputElement;\n\n const phoneInput = el(\"input\", {\n type: \"tel\",\n id: \"nodii-phone\",\n name: \"phone\",\n class: \"nodii-onboarding-input\",\n autocomplete: \"tel\",\n maxlength: \"40\",\n }) as HTMLInputElement;\n\n const messageInput = el(\"textarea\", {\n id: \"nodii-message\",\n name: \"message\",\n class: \"nodii-onboarding-textarea\",\n placeholder: \"How can we help?\",\n maxlength: \"4000\",\n rows: \"4\",\n }) as HTMLTextAreaElement;\n\n const interestBoxes = interests.map(\n (choice) =>\n el(\"input\", {\n type: \"checkbox\",\n name: \"interestModules\",\n value: choice.value,\n }) as HTMLInputElement,\n );\n\n const sizeSelect = el(\n \"select\",\n { id: \"nodii-sizeBand\", name: \"sizeBand\", class: \"nodii-onboarding-input\" },\n [\n el(\"option\", { value: \"\" }, [\"Choose…\"]),\n ...sizes.map((choice) =>\n el(\"option\", { value: choice.value }, [choice.label]),\n ),\n ],\n ) as HTMLSelectElement;\n\n const privacyBox = el(\"input\", {\n type: \"checkbox\",\n id: \"nodii-privacyNoticeAcknowledged\",\n name: \"privacyNoticeAcknowledged\",\n required: \"required\",\n }) as HTMLInputElement;\n\n const marketingBox = el(\"input\", {\n type: \"checkbox\",\n id: \"nodii-marketingOptIn\",\n name: \"marketingOptIn\",\n }) as HTMLInputElement;\n\n const serverErrorEl = el(\"div\", {\n class: \"nodii-onboarding-server-error\",\n role: \"alert\",\n \"aria-live\": \"assertive\",\n style: \"display:none\",\n });\n\n const successEl = el(\n \"div\",\n {\n class: \"nodii-onboarding-success\",\n role: \"status\",\n style: \"display:none\",\n },\n [options.successMessage ?? \"Thank you! We'll be in touch shortly.\"],\n );\n\n const submitBtn = el(\n \"button\",\n {\n type: \"submit\",\n class: \"nodii-onboarding-submit-btn\",\n },\n [options.submitLabel ?? \"Get in touch\"],\n );\n\n const form = el(\"form\", {\n novalidate: \"true\",\n \"aria-label\": \"Contact us\",\n });\n\n form.appendChild(\n createFieldEl(\n \"nodii-companyName\",\n labelOf(spec, \"companyName\", \"Company name\"),\n companyInput,\n true,\n ),\n );\n form.appendChild(\n createFieldEl(\n \"nodii-contactName\",\n labelOf(spec, \"contactName\", \"Your name\"),\n contactInput,\n true,\n ),\n );\n form.appendChild(\n createFieldEl(\n \"nodii-email\",\n labelOf(spec, \"email\", \"Email\"),\n emailInput,\n true,\n ),\n );\n form.appendChild(\n createFieldEl(\n \"nodii-phone\",\n `${labelOf(spec, \"phone\", \"Phone\")} (optional)`,\n phoneInput,\n false,\n ),\n );\n if (interests.length > 0) {\n form.appendChild(\n el(\n \"fieldset\",\n { id: \"nodii-interestModules\", class: \"nodii-onboarding-field\" },\n [\n el(\n \"legend\",\n {\n class: `nodii-onboarding-label${interestRequired ? \" required\" : \"\"}`,\n },\n [labelOf(spec, \"interestModules\", \"What are you interested in?\")],\n ),\n el(\n \"div\",\n { class: \"nodii-onboarding-choices\" },\n interests.map((choice, i) =>\n el(\"label\", { class: \"nodii-onboarding-choice\" }, [\n interestBoxes[i] as HTMLInputElement,\n choice.label,\n ]),\n ),\n ),\n errorSlot(\"nodii-interestModules\"),\n ],\n ),\n );\n }\n if (sizes.length > 0) {\n form.appendChild(\n createFieldEl(\n \"nodii-sizeBand\",\n `${labelOf(spec, \"sizeBand\", \"Team size\")} (optional)`,\n sizeSelect,\n false,\n ),\n );\n }\n form.appendChild(\n createFieldEl(\n \"nodii-message\",\n `${labelOf(spec, \"message\", \"Message\")} (optional)`,\n messageInput,\n false,\n ),\n );\n\n const privacyLabel: Array<HTMLElement | string> = [\"I have read the \"];\n let privacyLink: HTMLAnchorElement | null = null;\n if (privacyUrl) {\n privacyLink = Object.assign(\n el(\"a\", {\n href: privacyUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n }),\n { textContent: \"privacy notice\" },\n );\n privacyLabel.push(privacyLink);\n } else {\n privacyLabel.push(\"privacy notice\");\n }\n form.appendChild(\n el(\"div\", { class: \"nodii-onboarding-field\" }, [\n el(\"label\", { class: \"nodii-onboarding-consent-row\" }, [\n privacyBox,\n el(\"span\", {}, privacyLabel),\n ]),\n errorSlot(\"nodii-privacyNoticeAcknowledged\"),\n ]),\n );\n form.appendChild(\n el(\"label\", { class: \"nodii-onboarding-consent-row\" }, [\n marketingBox,\n el(\"span\", {}, [\n labelOf(spec, \"marketingOptIn\", \"Send me occasional product updates\"),\n ]),\n ]),\n );\n form.appendChild(serverErrorEl);\n form.appendChild(submitBtn);\n if (siteKey) {\n form.appendChild(\n el(\"p\", { class: \"nodii-onboarding-recaptcha-notice\" }, [\n \"Protected by reCAPTCHA. \",\n Object.assign(\n el(\"a\", {\n href: \"https://policies.google.com/privacy\",\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n }),\n { textContent: \"Privacy\" },\n ),\n \" & \",\n Object.assign(\n el(\"a\", {\n href: \"https://policies.google.com/terms\",\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n }),\n { textContent: \"Terms\" },\n ),\n ]),\n );\n }\n\n wrapper.appendChild(successEl);\n wrapper.appendChild(form);\n host.appendChild(wrapper);\n\n // --- Wire input events ---\n function syncValues(): void {\n formControl.setValue(\"companyName\", companyInput.value);\n formControl.setValue(\"contactName\", contactInput.value);\n formControl.setValue(\"email\", emailInput.value);\n formControl.setValue(\"phone\", phoneInput.value || undefined);\n formControl.setValue(\"message\", messageInput.value || undefined);\n formControl.setValue(\n \"interestModules\",\n interestBoxes.filter((box) => box.checked).map((box) => box.value),\n );\n formControl.setValue(\"sizeBand\", sizeSelect.value || undefined);\n formControl.setValue(\"privacyNoticeAcknowledged\", privacyBox.checked);\n formControl.setValue(\"marketingOptIn\", marketingBox.checked);\n }\n // One listener for every control: `input` covers typing, `change` covers\n // the checkboxes and the select.\n form.addEventListener(\"input\", syncValues);\n form.addEventListener(\"change\", syncValues);\n\n const submitLabel = options.submitLabel ?? \"Get in touch\";\n\n // Render the submit button content via DOM nodes ONLY — never innerHTML.\n // options.submitLabel may be integrator/CMS-influenced text; text nodes\n // guarantee it can never be interpreted as markup.\n function renderSubmitButton(submitting: boolean): void {\n while (submitBtn.firstChild) {\n submitBtn.removeChild(submitBtn.firstChild);\n }\n if (submitting) {\n const spinner = document.createElement(\"span\");\n spinner.className = \"nodii-onboarding-spinner\";\n submitBtn.appendChild(spinner);\n submitBtn.appendChild(document.createTextNode(\"Sending…\"));\n } else {\n submitBtn.appendChild(document.createTextNode(submitLabel));\n }\n }\n\n // Subscribe to state changes\n const unsubscribe = formControl.subscribe((state) => {\n // Update submit button state\n submitBtn.disabled = state.status === \"submitting\";\n renderSubmitButton(state.status === \"submitting\");\n\n // Apply field errors. One with no field on the form must still say\n // something: a submit must never just do nothing.\n const unplaced = applyErrors(wrapper, state.errors);\n\n // Server error\n const formError =\n state.serverError ??\n (unplaced > 0 ? \"This form can’t be sent right now.\" : null);\n if (formError) {\n serverErrorEl.textContent = formError;\n serverErrorEl.style.display = \"\";\n } else {\n serverErrorEl.style.display = \"none\";\n }\n\n // Success state\n if (state.status === \"success\") {\n successEl.style.display = \"\";\n form.style.display = \"none\";\n }\n });\n\n // --- Submit handler ---\n //\n // Idempotency-Key discipline (mirrors the server's D538 payload-match\n // guard — same key + different payload is INVALID_ARGUMENT server-side):\n // - The key is stable across RETRIES of the SAME payload (fingerprint\n // of the outgoing body minus botToken).\n // - If the user EDITS any field after a failed attempt, the fingerprint\n // changes → a NEW key is minted: an edited resubmission is a NEW\n // logical submission, not a retry.\n // - Cleared on success and on reset().\n let idempotencyKey: string | null = null;\n let lastFingerprint: string | null = null;\n\n form.addEventListener(\"submit\", async (event: Event) => {\n event.preventDefault();\n\n syncValues();\n const valid = formControl.validate();\n if (!valid) return;\n\n formControl.setSubmitting();\n\n const values = formControl.getState().values as ContactFormValues;\n\n // Key management per the discipline above.\n const fingerprint = computePayloadFingerprint(values);\n if (idempotencyKey === null || fingerprint !== lastFingerprint) {\n idempotencyKey = generateIdempotencyKey();\n lastFingerprint = fingerprint;\n }\n\n // Acquire the FIRST token up front so a mount-time reCAPTCHA failure\n // surfaces a clear message before any HTTP. On retries, submitLead mints\n // a FRESH token per attempt via this same provider (tokens are\n // single-use — reusing one after a 5xx would 403). Bounded by timeoutMs.\n let firstToken: string | undefined;\n if (siteKey) {\n try {\n firstToken = await executeRecaptcha(siteKey, \"contact_submit\", {\n timeoutMs: options.timeoutMs,\n });\n } catch (recaptchaErr) {\n formControl.setError(\n \"Could not load bot protection. Please try again.\",\n );\n options.onError?.(recaptchaErr);\n return;\n }\n }\n let usedFirst = false;\n const tokenProvider = async (): Promise<string> => {\n if (!usedFirst) {\n usedFirst = true;\n return firstToken!;\n }\n return executeRecaptcha(siteKey!, \"contact_submit\", {\n timeoutMs: options.timeoutMs,\n });\n };\n\n try {\n await submitLead(values, {\n baseUrl: options.baseUrl,\n ...(siteKey ? { botToken: tokenProvider } : {}),\n idempotencyKey,\n fetch: options.fetch,\n timeoutMs: options.timeoutMs,\n });\n // Clear for the next logical submission.\n idempotencyKey = null;\n lastFingerprint = null;\n formControl.setSuccess();\n options.onSuccess?.();\n } catch (err) {\n if (err instanceof OnboardingBotChallengeError) {\n formControl.setError(\n \"Bot protection check failed. Please refresh the page and try again.\",\n );\n options.onError?.(err);\n } else if (err instanceof OnboardingRateLimitError) {\n const msg =\n err.retryAfterSeconds !== null\n ? `Too many requests. Please wait ${err.retryAfterSeconds}s.`\n : \"Too many requests. Please wait a moment.\";\n formControl.setError(msg);\n options.onError?.(err);\n } else {\n formControl.setError(\n \"Something went wrong. Please try again in a moment.\",\n );\n options.onError?.(err);\n }\n }\n });\n\n // Keep the spec's privacy link live while the form is open: re-read the spec\n // and swap in the fresh presigned URL. A failed read keeps the current link,\n // and the next tick tries again. Never runs for a host-supplied link.\n // - One read at a time, so a slow reply can never land after a newer one.\n // - Its own cache: a background read must not replace the spec another\n // widget on the page reads from the shared one.\n // - Only while the form is in the document: one not attached yet, being\n // moved, or dropped skips the read. unmount() is what stops the timer.\n const refreshMs = options.specRefreshMs ?? DEFAULT_SPEC_REFRESH_MS;\n let refreshing = false;\n const specRefresh =\n privacyLink && !options.privacyUrl && refreshMs > 0\n ? setInterval(() => {\n if (refreshing || !wrapper.isConnected) return;\n refreshing = true;\n fetchOnboardingSpec({\n baseUrl: options.baseUrl,\n onboarder: options.onboarder,\n fetch: options.fetch,\n timeoutMs: options.timeoutMs,\n cache: new OnboardingSpecCache(),\n })\n .then(\n (fresh) => {\n const url = privacyDocumentUrl(fresh);\n if (url && privacyLink) privacyLink.href = url;\n },\n () => {},\n )\n .finally(() => {\n refreshing = false;\n });\n }, refreshMs)\n : undefined;\n\n return {\n unmount() {\n clearInterval(specRefresh);\n unsubscribe();\n host.removeChild(wrapper);\n },\n reset() {\n idempotencyKey = null;\n lastFingerprint = null;\n form.reset();\n formControl.reset();\n formControl.setValue(\"intakeKind\", options.intakeKind ?? \"enquiry\");\n if (options.attribution) {\n formControl.setValue(\"attribution\", options.attribution);\n }\n form.style.display = \"\";\n successEl.style.display = \"none\";\n },\n };\n}\n","/**\n * Default ConsentPack step components (D543 §5) — built ON the headless\n * ConsentController (dogfooding it). This is the batteries-included layer for\n * Nodii's own turnkey signup + tenants who want a default UI. Advanced tenants\n * skip this entirely and bind their OWN rendering to the headless controller\n * (see @nodii/onboarding/consent) — the TanStack model.\n *\n * NO IFRAME. A cross-origin iframe cannot report scroll position, so it can't\n * drive `scroll_then_accept`. The default document VIEWER\n * (@nodii/onboarding/viewer, lazy-imported) renders content INLINE, SAME-ORIGIN\n * (HTML→DOMPurify, markdown→marked, PDF→PDF.js) in a scroll `<div>` whose real\n * scroll events feed reportScrollProgress — so scroll-to-end is genuinely\n * detected. The scroll box reports progress ONLY after real content is present.\n *\n * Gate affordance per acceptance level:\n * - checkbox → a lightweight preview link (no gate; accept enabled).\n * - scroll_then_accept → the viewer renders the doc inline; scroll-to-end\n * drives the gate.\n * - open_then_accept → an open-in-a-new-tab control; a REAL open marks\n * `opened` (the open IS the gate).\n *\n * COMPLIANCE (P0 — never fabricate consent): if the viewer MODULE fails to load\n * (CDN chunk 404 / offline) for a scroll_then_accept doc, the gate stays\n * UNSATISFIABLE — a clear error + Retry is shown and accept remains DISABLED.\n * We NEVER satisfy a scroll gate on a click; an \"open in a new tab\" link on the\n * error is INFORMATIONAL only and does not unlock the gate. (The viewer's own\n * fetch/render failures follow the same rule; see @nodii/onboarding/viewer.)\n *\n * Theming rides the existing --nodii-onboarding-* CSS custom properties; all\n * classes are scoped under `.nodii-onboarding-widget`. Full-width, generous\n * spacing (operator directive) via styles.ts.\n *\n * a11y: every accept checkbox has a `<label for>` pointing at its real id; the\n * id token derives from the doc's stable key (docType | custom:<key>),\n * sanitized to an id-safe token and CSS-escaped in every selector.\n */\n\nimport type {\n ConsentController,\n ConsentDocState,\n ConsentState,\n} from \"../consent/controller.js\";\nimport { SCROLL_END_THRESHOLD } from \"../consent/controller.js\";\nimport { cssEscape, idSelector } from \"./dom-utils.js\";\n\n/** Prefix for every consent DOM id (kept distinct from field/account ids). */\nconst CONSENT_ID_PREFIX = \"nodii-consent-doc-\";\n\n/** Render-time options for the default consent step. */\nexport interface ConsentStepRenderOptions {\n /** Injectable fetch for doc-content load (defaults to global). */\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n /**\n * Injectable viewer-module importer (defaults to the real dynamic\n * `import(\"../viewer/render.js\")`). Exposed so a consumer can control code-\n * splitting AND so tests can drive the module-load-FAILURE branch WITHOUT\n * `mock.module` (which leaks across bun tests). Must resolve to an object\n * exposing `renderConsentDocument`; rejecting simulates a chunk-load failure.\n */\n importViewer?: () => Promise<typeof import(\"../viewer/render.js\")>;\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Record<string, string> = {},\n children: Array<HTMLElement | Text | string> = [],\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tag);\n for (const [key, value] of Object.entries(attrs)) {\n element.setAttribute(key, value);\n }\n for (const child of children) {\n if (typeof child === \"string\") {\n element.appendChild(document.createTextNode(child));\n } else {\n element.appendChild(child);\n }\n }\n return element;\n}\n\n/**\n * Turn a consent doc's stable key into a DOM-id-safe token. `doc_type` is a\n * fixed enum (safe); a custom key arrives as `custom:<key>` — the `:` and any\n * residual metachar are replaced so the raw token is valid inside an id AND\n * inside a `#id` selector. (The key is already `[A-Za-z0-9_-]+` past the `:`\n * per model.ts; this only neutralizes the `custom:` prefix separator.)\n */\nexport function consentDocElementId(key: string): string {\n return `${CONSENT_ID_PREFIX}${key.replace(/[^A-Za-z0-9_-]/g, \"-\")}`;\n}\n\n/** Build the accept-checkbox row for one document. */\nfunction buildAcceptRow(\n control: ConsentController,\n doc: ConsentDocState,\n): { row: HTMLElement; errorEl: HTMLElement } {\n const id = consentDocElementId(doc.key);\n const checkbox = el(\"input\", {\n type: \"checkbox\",\n id,\n class: \"nodii-onboarding-consent-accept\",\n }) as HTMLInputElement;\n checkbox.checked = doc.accepted;\n checkbox.disabled = !doc.gateSatisfied;\n checkbox.addEventListener(\"change\", () => {\n // The controller REFUSES acceptance when the gate is unsatisfied; reflect\n // the authoritative post-mutation state back into the DOM so a disabled-\n // bypass (e.g. programmatic .checked) cannot desync the UI from consent.\n control.setAccepted(doc.key, checkbox.checked);\n checkbox.checked =\n control.getState().documents.find((d) => d.key === doc.key)?.accepted ??\n false;\n });\n\n const labelText =\n doc.acceptanceLevel === \"checkbox\"\n ? `I accept the ${doc.doc.title}`\n : `I have reviewed and accept the ${doc.doc.title}`;\n const label = el(\n \"label\",\n { for: id, class: \"nodii-onboarding-consent-accept-label\" },\n [labelText],\n );\n if (doc.required) {\n label.appendChild(\n el(\"span\", { class: \"nodii-onboarding-consent-required\" }, [\" *\"]),\n );\n }\n\n const row = el(\"div\", { class: \"nodii-onboarding-consent-accept-row\" }, [\n checkbox,\n label,\n ]);\n const errorEl = el(\"div\", {\n class: \"nodii-onboarding-field-error nodii-onboarding-consent-error\",\n id: `${id}-error`,\n role: \"alert\",\n \"aria-live\": \"polite\",\n });\n return { row, errorEl };\n}\n\n/**\n * An open-in-tab affordance for an `open_then_accept` doc — opening the doc in\n * a new tab IS the gate for this level, so marking `opened` on a REAL open is\n * legitimate. A native <a target=\"_blank\"> navigates on click and on Enter\n * (keyboard activation). We do NOT bind Space — Space does not activate an\n * anchor (no navigation → no real open → marking opened would fabricate).\n */\nfunction buildOpenAffordance(\n control: ConsentController,\n doc: ConsentDocState,\n): HTMLElement {\n const id = consentDocElementId(doc.key);\n const openLink = el(\n \"a\",\n {\n class: \"nodii-onboarding-consent-open\",\n id: `${id}-open`,\n href: doc.doc.downloadUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n [`Open ${doc.doc.title}`],\n );\n const markOpened = (): void => control.markOpened(doc.key);\n openLink.addEventListener(\"click\", markOpened);\n openLink.addEventListener(\"keydown\", (event) => {\n if ((event as KeyboardEvent).key === \"Enter\") markOpened();\n });\n return el(\"div\", { class: \"nodii-onboarding-consent-open-row\" }, [openLink]);\n}\n\n/**\n * Build the gate affordance for one document.\n *\n * - open_then_accept → an open-in-tab control (marks opened).\n * - checkbox → a lightweight preview link (no gate).\n * - scroll_then_accept → an inline document container populated by the DEFAULT\n * VIEWER (@nodii/onboarding/viewer), loaded via a DYNAMIC import() so the\n * base widget bundle never statically pulls DOMPurify / marked / pdfjs. The\n * viewer renders the doc inline same-origin (HTML→DOMPurify, md→marked, PDF→\n * PDF.js) and wires the scroll container's scroll-to-end to the controller\n * so the gate is real. COMPLIANCE (P0): if the viewer MODULE fails to load,\n * the scroll gate stays UNSATISFIABLE — a clear error + Retry is shown and\n * accept stays DISABLED; we NEVER unlock a scroll gate on a click. (The\n * viewer's own fetch/render failures follow the same rule.)\n */\nfunction buildGateAffordance(\n control: ConsentController,\n doc: ConsentDocState,\n opts: ConsentStepRenderOptions,\n): HTMLElement {\n const id = consentDocElementId(doc.key);\n\n if (doc.acceptanceLevel === \"open_then_accept\") {\n return buildOpenAffordance(control, doc);\n }\n\n if (doc.acceptanceLevel === \"checkbox\") {\n return el(\"div\", { class: \"nodii-onboarding-consent-preview-row\" }, [\n el(\n \"a\",\n {\n class: \"nodii-onboarding-consent-preview\",\n id: `${id}-preview`,\n href: doc.doc.downloadUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n [`View ${doc.doc.title}`],\n ),\n ]);\n }\n\n // scroll_then_accept: delegate to the default viewer (dynamically imported).\n const container = el(\"div\", {\n class: \"nodii-onboarding-consent-gate\",\n id: `${id}-gate`,\n });\n container.appendChild(\n el(\"div\", { class: \"nodii-onboarding-consent-doc-loading\" }, [\n \"Loading document…\",\n ]),\n );\n\n const importViewer =\n opts.importViewer ?? (() => import(\"../viewer/render.js\"));\n const loadViewer = (): void => {\n void (async () => {\n try {\n const { renderConsentDocument } = await importViewer();\n await renderConsentDocument(container, doc.doc, control, {\n consentKey: doc.key,\n fetch: opts.fetch,\n timeoutMs: opts.timeoutMs,\n });\n } catch {\n // COMPLIANCE-CRITICAL (P0): the viewer MODULE itself failed to load\n // (CDN chunk 404, offline). A scroll_then_accept doc cannot be\n // scrolled → its gate stays UNSATISFIABLE. We MUST NOT satisfy the\n // scroll gate on a click — that would fabricate scrolled_to_end.\n // Render a clear error + Retry (re-attempts the import); accept stays\n // disabled. An informational open link does NOT satisfy the gate.\n while (container.firstChild) {\n container.removeChild(container.firstChild);\n }\n const wrap = el(\"div\", {\n class: \"nodii-onboarding-consent-unrenderable\",\n role: \"alert\",\n });\n wrap.appendChild(\n el(\n \"p\",\n {\n // DISTINCT id (NOT `${id}-error`): buildAcceptRow already owns\n // `${id}-error`, and updateConsentStep's querySelector would match\n // THIS paragraph first and blank it on the next state change,\n // silently wiping the compliance message. A unique id keeps this\n // load-failure error persistent (P1b).\n class:\n \"nodii-onboarding-field-error nodii-onboarding-consent-error\",\n id: `${id}-load-error`,\n },\n [\n `“${doc.doc.title}” could not be loaded, so it cannot be accepted yet. Please retry.`,\n ],\n ),\n );\n const retry = el(\n \"button\",\n { type: \"button\", class: \"nodii-onboarding-consent-retry\" },\n [\"Retry loading document\"],\n );\n retry.addEventListener(\"click\", loadViewer);\n wrap.appendChild(retry);\n // Informational only — opening in a new tab does NOT satisfy scroll.\n wrap.appendChild(\n el(\n \"a\",\n {\n class: \"nodii-onboarding-consent-open\",\n href: doc.doc.downloadUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n [`Open ${doc.doc.title} in a new tab`],\n ),\n );\n container.appendChild(wrap);\n }\n })();\n };\n loadViewer();\n\n return container;\n}\n\n/** Build one full-width consent card for a document. */\nfunction buildConsentCard(\n control: ConsentController,\n doc: ConsentDocState,\n stale: boolean,\n opts: ConsentStepRenderOptions,\n): HTMLElement {\n const card = el(\"div\", {\n class: `nodii-onboarding-consent-card${stale ? \" is-stale\" : \"\"}`,\n \"data-consent-key\": doc.key,\n });\n card.appendChild(\n el(\"h4\", { class: \"nodii-onboarding-consent-title\" }, [doc.doc.title]),\n );\n if (stale) {\n card.appendChild(\n el(\n \"div\",\n { class: \"nodii-onboarding-consent-stale-tag\", role: \"status\" },\n [\"Updated — please review and re-accept.\"],\n ),\n );\n }\n card.appendChild(buildGateAffordance(control, doc, opts));\n const { row, errorEl } = buildAcceptRow(control, doc);\n card.appendChild(row);\n card.appendChild(errorEl);\n return card;\n}\n\n/**\n * Render (or re-render) the consent stage into a host container from the given\n * consent state. Full re-render (the doc set is small); disabled/checked/error\n * state is refreshed in place via updateConsentStep so scroll position and\n * inline doc content are not lost on unrelated state changes.\n */\nexport function renderConsentStep(\n host: HTMLElement,\n control: ConsentController,\n state: ConsentState,\n staleKeys: string[] = [],\n opts: ConsentStepRenderOptions = {},\n): void {\n while (host.firstChild) host.removeChild(host.firstChild);\n const staleSet = new Set(staleKeys);\n\n host.appendChild(\n el(\"h3\", { class: \"nodii-onboarding-stage-title\" }, [\n \"Review & accept documents\",\n ]),\n );\n host.appendChild(\n el(\"p\", { class: \"nodii-onboarding-consent-intro\" }, [\n \"Please review each document below and accept to continue.\",\n ]),\n );\n\n for (const doc of state.documents) {\n host.appendChild(\n buildConsentCard(control, doc, staleSet.has(doc.key), opts),\n );\n }\n}\n\n/**\n * Refresh the consent cards' disabled/checked/error state in place (no full\n * re-render) — called on every stepper state change so gate unlocks and\n * live-clearing errors reflect immediately without losing scroll position or\n * re-fetching inline doc content.\n */\nexport function updateConsentStep(\n host: HTMLElement,\n state: ConsentState,\n consentErrors: Array<{ path: string; message: string }>,\n): void {\n const errorByKey = new Map(consentErrors.map((e) => [e.path, e.message]));\n for (const doc of state.documents) {\n const id = consentDocElementId(doc.key);\n const checkbox = host.querySelector(\n idSelector(id),\n ) as HTMLInputElement | null;\n if (checkbox) {\n checkbox.disabled = !doc.gateSatisfied;\n checkbox.checked = doc.accepted;\n }\n const errorNode = host.querySelector(idSelector(`${id}-error`));\n if (errorNode) errorNode.textContent = errorByKey.get(doc.key) ?? \"\";\n const card = host.querySelector(\n `[data-consent-key=\"${cssEscape(doc.key)}\"]`,\n );\n if (card) {\n if (errorByKey.has(doc.key)) card.classList.add(\"has-error\");\n else card.classList.remove(\"has-error\");\n }\n }\n}\n\n/** Re-export for consumers wiring their own scroll handler to the controller. */\nexport { SCROLL_END_THRESHOLD };\n","/// <reference lib=\"dom\" />\n/// <reference lib=\"dom.iterable\" />\n/**\n * Default vanilla-TS dynamic signup stepper widget (D540 Phase 2).\n *\n * Mount flow:\n * 1. Fetch + validate the spec (GET /api/v1/public/onboarding/spec);\n * the reCAPTCHA siteKey comes FROM THE SPEC (botChallenge.siteKey) —\n * the mount-option siteKey is only an override/fallback.\n * 2. Build the headless stepper from spec.forms.signup.steps.\n * 3. Render the current step's fields per descriptor type; Back/Next\n * navigate with per-step validation.\n * 4. The FINAL step carries the account section (credentials + consent\n * clickwrap) and the submit button.\n * 5. Submit: validateAll → payload-fingerprint key management (same\n * D538 discipline as the contact widget) → reCAPTCHA token →\n * submitSignup.\n * 6. 409 spec_stale: refetch the spec, applyNewSpec (drops removed\n * fields, re-validates), show a \"form updated — please review\"\n * banner. The SDK NEVER auto-resubmits a stale submission.\n */\n\nimport {\n fetchOnboardingSpec,\n OnboardingSpecCache,\n defaultSpecCache,\n diffSpecFields,\n type OnboardingSpec,\n} from \"../spec/index.js\";\nimport type { SpecField } from \"../spec/model.js\";\nimport {\n createSignupStepper,\n type SignupStepperControl,\n type SignupStepperState,\n} from \"../dynamic/stepper.js\";\nimport { optionValue } from \"../dynamic/derive.js\";\nimport {\n submitSignup,\n computeSignupFingerprint,\n type SignupSubmitResult,\n} from \"../submit/signup-client.js\";\nimport { generateIdempotencyKey } from \"../submit/client.js\";\nimport {\n OnboardingBotChallengeError,\n OnboardingConsentIncompleteError,\n OnboardingConsentStaleError,\n OnboardingRateLimitError,\n OnboardingSpecStaleError,\n OnboardingSubdomainTakenError,\n} from \"../submit/errors.js\";\nimport { executeRecaptcha } from \"../recaptcha/loader.js\";\nimport { idSelector } from \"./dom-utils.js\";\nimport { injectWidgetStyles } from \"./styles.js\";\nimport { renderConsentStep, updateConsentStep } from \"./consent-step.js\";\nimport type { MountedWidget } from \"./contact-form.js\";\n\nexport interface SignupFormMountOptions {\n /**\n * The onboarder identifier — the CLIENT-side spec-cache key\n * (D540 §3 `(onboarder, specVersion)`). NOT transmitted: per LOCKED\n * D536, onboarder trust/scoping is host-derived at the edge.\n */\n onboarder: string;\n baseUrl: string;\n /**\n * OPTIONAL siteKey override. Normally the widget uses the siteKey the\n * spec serves (botChallenge.siteKey, D537/D540); pass this only for\n * environments where the spec cannot carry it yet.\n */\n siteKey?: string;\n form: \"signup\";\n onSuccess?: (result: SignupSubmitResult) => void;\n onError?: (error: unknown) => void;\n /** Called after the spec loads and the stepper renders. */\n onReady?: (spec: OnboardingSpec) => void;\n fetch?: typeof globalThis.fetch;\n /**\n * Per-request timeout in ms (default 15s), applied to the boot spec fetch,\n * the reCAPTCHA execute(), the submit POST, and the 409 refetch — so a hung\n * dependency never leaves \"Loading signup form…\"/\"Sending…\" stuck.\n */\n timeoutMs?: number;\n submitLabel?: string;\n tosUrl?: string;\n privacyUrl?: string;\n /** Spec cache override (defaults to the module-level cache). */\n cache?: OnboardingSpecCache;\n}\n\nconst STAGE_TITLES: Record<string, string> = {\n lead: \"About you\",\n prospect: \"Your business\",\n activation: \"Choose your services\",\n};\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: Record<string, string> = {},\n children: Array<HTMLElement | Text | string> = [],\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tag);\n for (const [key, value] of Object.entries(attrs)) {\n element.setAttribute(key, value);\n }\n for (const child of children) {\n if (typeof child === \"string\") {\n element.appendChild(document.createTextNode(child));\n } else {\n element.appendChild(child);\n }\n }\n return element;\n}\n\nfunction optionLabel(option: unknown): string {\n if (option !== null && typeof option === \"object\") {\n const o = option as Record<string, unknown>;\n if (typeof o[\"label\"] === \"string\") return o[\"label\"];\n }\n return optionValue(option);\n}\n\n/** Build the input element for one spec field descriptor. */\nfunction buildFieldInput(\n field: SpecField,\n currentValue: unknown,\n onChange: (value: unknown) => void,\n): HTMLElement {\n const id = `nodii-f-${field.key}`;\n\n switch (field.type) {\n case \"textarea\": {\n const input = el(\"textarea\", {\n id,\n class: \"nodii-onboarding-textarea\",\n rows: \"4\",\n }) as HTMLTextAreaElement;\n if (typeof currentValue === \"string\") input.value = currentValue;\n input.addEventListener(\"input\", () => onChange(input.value));\n return input;\n }\n case \"checkbox\":\n case \"boolean\": {\n const input = el(\"input\", {\n type: \"checkbox\",\n id,\n }) as HTMLInputElement;\n input.checked = currentValue === true;\n input.addEventListener(\"change\", () => onChange(input.checked));\n return input;\n }\n case \"select\":\n case \"radio\": {\n const select = el(\"select\", {\n id,\n class: \"nodii-onboarding-input\",\n }) as HTMLSelectElement;\n select.appendChild(el(\"option\", { value: \"\" }, [\"— select —\"]));\n for (const opt of field.options ?? []) {\n const value = optionValue(opt);\n const optionEl = el(\"option\", { value }, [optionLabel(opt)]);\n select.appendChild(optionEl);\n }\n if (typeof currentValue === \"string\") select.value = currentValue;\n select.addEventListener(\"change\", () => onChange(select.value));\n return select;\n }\n case \"multiselect\": {\n const select = el(\"select\", {\n id,\n class: \"nodii-onboarding-input\",\n multiple: \"multiple\",\n }) as HTMLSelectElement;\n const current = Array.isArray(currentValue)\n ? currentValue.map(String)\n : [];\n for (const opt of field.options ?? []) {\n const value = optionValue(opt);\n const optionEl = el(\"option\", { value }, [\n optionLabel(opt),\n ]) as HTMLOptionElement;\n if (current.includes(value)) optionEl.selected = true;\n select.appendChild(optionEl);\n }\n select.addEventListener(\"change\", () => {\n const values: string[] = [];\n for (const o of Array.from(select.options)) {\n if (o.selected && o.value !== \"\") values.push(o.value);\n }\n onChange(values);\n });\n return select;\n }\n default: {\n // text | email | tel | number | date | unknown → typed <input>\n const typeAttr =\n field.type === \"email\" ||\n field.type === \"tel\" ||\n field.type === \"number\" ||\n field.type === \"date\"\n ? field.type\n : \"text\";\n const input = el(\"input\", {\n type: typeAttr,\n id,\n class: \"nodii-onboarding-input\",\n }) as HTMLInputElement;\n if (typeof currentValue === \"string\") input.value = currentValue;\n if (typeof currentValue === \"number\") input.value = String(currentValue);\n input.addEventListener(\"input\", () => onChange(input.value));\n return input;\n }\n }\n}\n\n/**\n * Build a labelled field row. The label `for`, the input id, and the error\n * element id must ALL agree so click-to-focus and screen-reader association\n * work. Callers whose input id is NOT `nodii-f-<key>` (the account section,\n * whose inputs are `nodii-account-*`) pass `idOverride` so the label points\n * at the REAL input — never a dangling id patched up post-hoc.\n */\nfunction fieldRow(\n field: SpecField,\n input: HTMLElement,\n idOverride?: string,\n): HTMLElement {\n const id = idOverride ?? `nodii-f-${field.key}`;\n const labelEl = el(\n \"label\",\n {\n for: id,\n class: `nodii-onboarding-label${field.required ? \" required\" : \"\"}`,\n },\n [field.label],\n );\n const errorEl = el(\"div\", {\n class: \"nodii-onboarding-field-error\",\n id: `${id}-error`,\n role: \"alert\",\n \"aria-live\": \"polite\",\n });\n return el(\"div\", { class: \"nodii-onboarding-field\" }, [\n labelEl,\n input,\n errorEl,\n ]);\n}\n\n/**\n * Mount the dynamic signup stepper into a host element.\n * Returns synchronously; the spec loads in the background (loading state\n * rendered meanwhile; onReady fires when interactive).\n */\nexport function mountSignupForm(\n host: HTMLElement,\n options: SignupFormMountOptions,\n): MountedWidget {\n injectWidgetStyles();\n\n const wrapper = el(\"div\", { class: \"nodii-onboarding-widget\" });\n const loadingEl = el(\"div\", { class: \"nodii-onboarding-loading\" }, [\n \"Loading signup form…\",\n ]);\n wrapper.appendChild(loadingEl);\n host.appendChild(wrapper);\n\n const cache = options.cache ?? defaultSpecCache;\n let stepper: SignupStepperControl | null = null;\n let unsubscribe: (() => void) | null = null;\n let unmounted = false;\n let siteKey = options.siteKey ?? \"\";\n let idempotencyKey: string | null = null;\n let lastFingerprint: string | null = null;\n let renderedStepIndex = -1;\n let renderedStale = false;\n // Tracks the last-rendered consentStale flag so a consent_stale swap forces\n // a full step re-render (like specStale) — the cards must re-render with the\n // \"Updated — please review\" tags and cleared acceptance.\n let renderedConsentStale = false;\n // The (onboarder, specVersion) currently driving the form — used to READ\n // the prior cached version back out on a 409 and diff what changed.\n let currentSpecVersion: string | null = null;\n let staleDiffSummary = \"\";\n\n // DOM regions (populated by renderShell)\n const stepArea = el(\"div\", {});\n const staleBanner = el(\"div\", {\n class: \"nodii-onboarding-stale-banner\",\n role: \"alert\",\n style: \"display:none\",\n });\n const serverErrorEl = el(\"div\", {\n class: \"nodii-onboarding-server-error\",\n role: \"alert\",\n \"aria-live\": \"assertive\",\n style: \"display:none\",\n });\n const successEl = el(\"div\", {\n class: \"nodii-onboarding-success\",\n role: \"status\",\n style: \"display:none\",\n });\n const stepsIndicator = el(\"div\", { class: \"nodii-onboarding-steps\" });\n const form = el(\"form\", { novalidate: \"true\", \"aria-label\": \"Sign up\" });\n\n function setFieldErrorsInPlace(\n container: HTMLElement,\n errors: Array<{ path: string; message: string }>,\n idPrefix: (path: string) => string,\n ): void {\n for (const errEl of container.querySelectorAll(\n \".nodii-onboarding-field-error\",\n )) {\n errEl.textContent = \"\";\n }\n for (const marked of container.querySelectorAll(\".has-error\")) {\n marked.classList.remove(\"has-error\");\n }\n for (const err of errors) {\n const id = idPrefix(err.path);\n // CSS-escape: id derives from spec field keys (err.path).\n const errorNode = container.querySelector(idSelector(`${id}-error`));\n if (errorNode) errorNode.textContent = err.message;\n const inputNode = container.querySelector(idSelector(id));\n if (inputNode) inputNode.classList.add(\"has-error\");\n }\n }\n\n function accountIdOf(path: string): string {\n if (path === \"email\") return \"nodii-account-email\";\n if (path === \"displayName\") return \"nodii-account-display-name\";\n if (path === \"tosAccepted\") return \"nodii-consent-tos\";\n if (path === \"privacyAccepted\") return \"nodii-consent-privacy\";\n return `nodii-account-${path}`;\n }\n\n function renderStepsIndicator(state: SignupStepperState): void {\n while (stepsIndicator.firstChild) {\n stepsIndicator.removeChild(stepsIndicator.firstChild);\n }\n for (let i = 0; i < state.stepCount; i++) {\n stepsIndicator.appendChild(\n el(\"div\", {\n class: `nodii-onboarding-step-dot${i <= state.stepIndex ? \" active\" : \"\"}`,\n }),\n );\n }\n }\n\n function renderAccountSection(\n control: SignupStepperControl,\n state: SignupStepperState,\n ): HTMLElement {\n const section = el(\"div\", { class: \"nodii-onboarding-account-section\" });\n\n const emailInput = el(\"input\", {\n type: \"email\",\n id: \"nodii-account-email\",\n class: \"nodii-onboarding-input\",\n autocomplete: \"email\",\n }) as HTMLInputElement;\n emailInput.value = state.credentials.email;\n emailInput.addEventListener(\"input\", () =>\n control.setCredentials({ email: emailInput.value }),\n );\n section.appendChild(\n fieldRow(\n {\n key: \"account-email\",\n type: \"email\",\n label: \"Account email\",\n required: true,\n },\n emailInput,\n \"nodii-account-email\", // label for + error id match the real input id\n ),\n );\n\n const displayNameInput = el(\"input\", {\n type: \"text\",\n id: \"nodii-account-display-name\",\n class: \"nodii-onboarding-input\",\n autocomplete: \"name\",\n maxlength: \"200\",\n }) as HTMLInputElement;\n displayNameInput.value = state.credentials.displayName;\n displayNameInput.addEventListener(\"input\", () =>\n control.setCredentials({ displayName: displayNameInput.value }),\n );\n section.appendChild(\n fieldRow(\n {\n key: \"account-display-name\",\n type: \"text\",\n label: \"Your name\",\n required: true,\n },\n displayNameInput,\n \"nodii-account-display-name\",\n ),\n );\n\n for (const [key, label, autocomplete] of [\n [\"organisationName\", \"Organisation name\", \"organization\"],\n [\"subdomain\", \"Workspace subdomain\", \"off\"],\n ] as const) {\n const input = el(\"input\", {\n type: \"text\",\n id: `nodii-account-${key}`,\n class: \"nodii-onboarding-input\",\n autocomplete,\n maxlength: key === \"subdomain\" ? \"63\" : \"200\",\n }) as HTMLInputElement;\n input.value = state.credentials[key];\n input.addEventListener(\"input\", () =>\n control.setCredentials({ [key]: input.value }),\n );\n section.appendChild(\n fieldRow(\n { key: `account-${key}`, type: \"text\", label, required: true },\n input,\n `nodii-account-${key}`,\n ),\n );\n }\n\n const tosCheckbox = el(\"input\", {\n type: \"checkbox\",\n id: \"nodii-consent-tos\",\n }) as HTMLInputElement;\n tosCheckbox.checked = state.consent.tosAccepted;\n tosCheckbox.addEventListener(\"change\", () =>\n control.setConsent({ tosAccepted: tosCheckbox.checked }),\n );\n const tosLabelChildren: Array<HTMLElement | string> = [\"I accept the \"];\n if (options.tosUrl) {\n tosLabelChildren.push(\n el(\n \"a\",\n {\n href: options.tosUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n [\"Terms of Service\"],\n ),\n );\n } else {\n tosLabelChildren.push(\"Terms of Service\");\n }\n section.appendChild(\n el(\"div\", { class: \"nodii-onboarding-consent-row\" }, [\n tosCheckbox,\n el(\"label\", { for: \"nodii-consent-tos\" }, tosLabelChildren),\n ]),\n );\n section.appendChild(\n el(\"div\", {\n class: \"nodii-onboarding-field-error\",\n id: \"nodii-consent-tos-error\",\n role: \"alert\",\n }),\n );\n\n const privacyCheckbox = el(\"input\", {\n type: \"checkbox\",\n id: \"nodii-consent-privacy\",\n }) as HTMLInputElement;\n privacyCheckbox.checked = state.consent.privacyAccepted;\n privacyCheckbox.addEventListener(\"change\", () =>\n control.setConsent({ privacyAccepted: privacyCheckbox.checked }),\n );\n const privacyLabelChildren: Array<HTMLElement | string> = [\"I accept the \"];\n if (options.privacyUrl) {\n privacyLabelChildren.push(\n el(\n \"a\",\n {\n href: options.privacyUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n [\"Privacy Policy\"],\n ),\n );\n } else {\n privacyLabelChildren.push(\"Privacy Policy\");\n }\n section.appendChild(\n el(\"div\", { class: \"nodii-onboarding-consent-row\" }, [\n privacyCheckbox,\n el(\"label\", { for: \"nodii-consent-privacy\" }, privacyLabelChildren),\n ]),\n );\n section.appendChild(\n el(\"div\", {\n class: \"nodii-onboarding-field-error\",\n id: \"nodii-consent-privacy-error\",\n role: \"alert\",\n }),\n );\n\n return section;\n }\n\n function renderStep(\n control: SignupStepperControl,\n state: SignupStepperState,\n ): void {\n while (stepArea.firstChild) stepArea.removeChild(stepArea.firstChild);\n\n const step = state.currentStep;\n if (step) {\n stepArea.appendChild(\n el(\"h3\", { class: \"nodii-onboarding-stage-title\" }, [\n STAGE_TITLES[step.stage] ?? step.stage,\n ]),\n );\n for (const field of step.fields) {\n const input = buildFieldInput(\n field,\n state.answers[field.key],\n (value) => control.setAnswer(field.key, value),\n );\n stepArea.appendChild(fieldRow(field, input));\n }\n }\n\n const isLast = control.isLastStep();\n if (isLast) {\n // D543 consent stage — full-width consent cards ABOVE the account\n // section on the final step. Rendered only when the spec served a\n // consentPack (control.consent.isEmpty() ⇒ skipped entirely).\n if (!control.consent.isEmpty()) {\n const consentStage = el(\"div\", {\n class: \"nodii-onboarding-consent-stage\",\n });\n renderConsentStep(\n consentStage,\n control.consent,\n state.consentState,\n state.staleConsentKeys,\n { fetch: options.fetch, timeoutMs: options.timeoutMs },\n );\n stepArea.appendChild(consentStage);\n }\n stepArea.appendChild(renderAccountSection(control, state));\n }\n\n const nav = el(\"div\", { class: \"nodii-onboarding-nav\" });\n if (!control.isFirstStep()) {\n const backBtn = el(\n \"button\",\n { type: \"button\", class: \"nodii-onboarding-back-btn\" },\n [\"Back\"],\n );\n backBtn.addEventListener(\"click\", () => control.back());\n nav.appendChild(backBtn);\n }\n const forwardBtn = el(\n \"button\",\n {\n type: isLast ? \"submit\" : \"button\",\n class: \"nodii-onboarding-submit-btn\",\n id: \"nodii-signup-forward\",\n },\n [isLast ? (options.submitLabel ?? \"Create account\") : \"Next\"],\n );\n if (!isLast) {\n forwardBtn.addEventListener(\"click\", () => control.next());\n }\n nav.appendChild(forwardBtn);\n stepArea.appendChild(nav);\n }\n\n async function handleSpecStale(control: SignupStepperControl): Promise<void> {\n // READ the previously-served version back out of the cache (populated on\n // boot under (onboarder, specVersion)) so we can diff it against the\n // refetched spec and tell the user exactly what changed.\n const prior =\n currentSpecVersion !== null\n ? cache.get(options.onboarder, currentSpecVersion)\n : undefined;\n\n const fresh = await fetchOnboardingSpec({\n baseUrl: options.baseUrl,\n onboarder: options.onboarder,\n fetch: options.fetch,\n timeoutMs: options.timeoutMs,\n cache,\n });\n if (unmounted) return;\n\n if (prior) {\n const diff = diffSpecFields(prior, fresh);\n const parts: string[] = [];\n if (diff.added.length) parts.push(`added: ${diff.added.join(\", \")}`);\n if (diff.removed.length)\n parts.push(`removed: ${diff.removed.join(\", \")}`);\n if (diff.changed.length)\n parts.push(`changed: ${diff.changed.join(\", \")}`);\n staleDiffSummary = parts.length ? ` (${parts.join(\"; \")})` : \"\";\n } else {\n staleDiffSummary = \"\";\n }\n\n siteKey = options.siteKey ?? fresh.botChallenge?.siteKey ?? \"\";\n currentSpecVersion = fresh.specVersion;\n control.applyNewSpec(fresh);\n // A stale submission's payload is dead; the next submit is a NEW\n // logical submission against the new specVersion.\n idempotencyKey = null;\n lastFingerprint = null;\n }\n\n /**\n * 409 consent_stale (D543 §4): a required legal doc changed. Refetch the\n * spec and swap ONLY the consentPack — changed docs are reset (re-acceptance\n * required, NEVER auto-accepted). The form fields are left as-is. The user\n * re-accepts and resubmits; the SDK never auto-resubmits.\n */\n async function handleConsentStale(\n control: SignupStepperControl,\n ): Promise<void> {\n const fresh = await fetchOnboardingSpec({\n baseUrl: options.baseUrl,\n onboarder: options.onboarder,\n fetch: options.fetch,\n timeoutMs: options.timeoutMs,\n cache,\n });\n if (unmounted) return;\n\n siteKey = options.siteKey ?? fresh.botChallenge?.siteKey ?? \"\";\n currentSpecVersion = fresh.specVersion;\n control.applyNewConsentPack(fresh);\n // Re-accepting changed docs is a NEW logical submission → rotate the key.\n idempotencyKey = null;\n lastFingerprint = null;\n }\n\n async function handleSubmit(control: SignupStepperControl): Promise<void> {\n if (!control.validateAll()) return;\n control.acknowledgeSpecStale();\n control.setSubmitting();\n\n const body = control.buildSubmitPayload();\n const fingerprint = computeSignupFingerprint(body);\n if (idempotencyKey === null || fingerprint !== lastFingerprint) {\n idempotencyKey = generateIdempotencyKey();\n lastFingerprint = fingerprint;\n }\n\n // First token up front (clear pre-HTTP failure); fresh token per retry\n // attempt via the provider (single-use tokens).\n let firstToken: string | undefined;\n if (siteKey) {\n try {\n firstToken = await executeRecaptcha(siteKey, \"signup_submit\", {\n timeoutMs: options.timeoutMs,\n });\n } catch (recaptchaErr) {\n control.setError(\"Could not load bot protection. Please try again.\");\n options.onError?.(recaptchaErr);\n return;\n }\n }\n let usedFirst = false;\n const tokenProvider = async (): Promise<string> => {\n if (!usedFirst) {\n usedFirst = true;\n return firstToken!;\n }\n return executeRecaptcha(siteKey, \"signup_submit\", {\n timeoutMs: options.timeoutMs,\n });\n };\n\n try {\n const result = await submitSignup(body, {\n baseUrl: options.baseUrl,\n ...(siteKey ? { botToken: tokenProvider } : {}),\n idempotencyKey,\n fetch: options.fetch,\n timeoutMs: options.timeoutMs,\n });\n idempotencyKey = null;\n lastFingerprint = null;\n control.setSuccess(result.terminalStage);\n options.onSuccess?.(result);\n } catch (err) {\n if (err instanceof OnboardingSpecStaleError) {\n try {\n await handleSpecStale(control);\n } catch (refetchErr) {\n control.setError(\n \"The signup form changed and could not be reloaded. Please refresh the page.\",\n );\n options.onError?.(refetchErr);\n return;\n }\n options.onError?.(err);\n } else if (err instanceof OnboardingConsentStaleError) {\n // D543 §4: refetch + swap consentPack; changed docs require\n // re-acceptance. NEVER auto-accept a changed doc, NEVER auto-resubmit.\n try {\n await handleConsentStale(control);\n } catch (refetchErr) {\n control.setError(\n \"The legal documents changed and could not be reloaded. Please refresh the page.\",\n );\n options.onError?.(refetchErr);\n return;\n }\n options.onError?.(err);\n } else if (err instanceof OnboardingConsentIncompleteError) {\n // The server found a required doc missing/unaccepted — route the user\n // back to the consent step. validateAll() will surface the per-doc\n // errors on the next state emit.\n control.validateAll();\n control.setError(\"Please accept all required documents to continue.\");\n options.onError?.(err);\n } else if (err instanceof OnboardingSubdomainTakenError) {\n // D836: retrying the same label can never succeed, so name the field\n // to change instead of saying \"try again\". The field carries the\n // message; a banner would outlive the fix.\n control.setAccountError(\n \"subdomain\",\n \"This workspace address is already taken. Choose another one.\",\n );\n options.onError?.(err);\n } else if (err instanceof OnboardingBotChallengeError) {\n control.setError(\n \"Bot protection check failed. Please refresh the page and try again.\",\n );\n options.onError?.(err);\n } else if (err instanceof OnboardingRateLimitError) {\n control.setError(\n err.retryAfterSeconds !== null\n ? `Too many requests. Please wait ${err.retryAfterSeconds}s.`\n : \"Too many requests. Please wait a moment.\",\n );\n options.onError?.(err);\n } else {\n control.setError(\"Something went wrong. Please try again in a moment.\");\n options.onError?.(err);\n }\n }\n }\n\n function onStateChange(\n control: SignupStepperControl,\n state: SignupStepperState,\n ): void {\n // Full step re-render only when the step (or staleness) changed —\n // in-place updates otherwise so typing never loses focus. A consent_stale\n // swap ALSO forces a re-render so the cards re-render cleared + tagged.\n if (\n state.stepIndex !== renderedStepIndex ||\n state.specStale !== renderedStale ||\n state.consentStale !== renderedConsentStale\n ) {\n renderedStepIndex = state.stepIndex;\n renderedStale = state.specStale;\n renderedConsentStale = state.consentStale;\n renderStep(control, state);\n renderStepsIndicator(state);\n }\n\n staleBanner.style.display =\n state.specStale || state.consentStale ? \"\" : \"none\";\n staleBanner.textContent = state.specStale\n ? `This form was just updated by the provider${staleDiffSummary}. Please review your answers below and submit again.`\n : state.consentStale\n ? \"One or more legal documents were updated. Please review and re-accept the updated documents below, then submit again.\"\n : \"\";\n\n setFieldErrorsInPlace(\n stepArea,\n state.errors,\n (path) => `nodii-f-${path.split(\".\")[0] ?? path}`,\n );\n // Account errors overlay (only present on the last step's DOM)\n for (const err of state.accountErrors) {\n const id = accountIdOf(err.path.split(\".\")[0] ?? err.path);\n const errorNode = stepArea.querySelector(idSelector(`${id}-error`));\n if (errorNode) errorNode.textContent = err.message;\n const inputNode = stepArea.querySelector(idSelector(id));\n if (inputNode) inputNode.classList.add(\"has-error\");\n }\n\n // Consent cards' disabled/checked/error state in place (only present on\n // the last step's DOM; a no-op elsewhere or with an empty consentPack).\n // MUST run AFTER setFieldErrorsInPlace — that function blanket-clears every\n // `.nodii-onboarding-field-error` node in stepArea (the consent error nodes\n // carry that class too), so writing consent errors first would be wiped.\n const consentStage = stepArea.querySelector(\n \".nodii-onboarding-consent-stage\",\n ) as HTMLElement | null;\n if (consentStage) {\n updateConsentStep(consentStage, state.consentState, state.consentErrors);\n }\n\n if (state.serverError) {\n serverErrorEl.textContent = state.serverError;\n serverErrorEl.style.display = \"\";\n } else {\n serverErrorEl.style.display = \"none\";\n }\n\n const forwardBtn = stepArea.querySelector(\n \"#nodii-signup-forward\",\n ) as HTMLButtonElement | null;\n if (forwardBtn) {\n forwardBtn.disabled = state.status === \"submitting\";\n }\n\n if (state.status === \"success\") {\n const message =\n state.terminalStage === \"active\"\n ? \"Your account is ready — you're all set!\"\n : state.terminalStage === \"inactive\"\n ? \"Your account was created. Complete verification to activate it.\"\n : \"Thanks for signing up! Check your email to verify your account.\";\n successEl.textContent = message;\n successEl.style.display = \"\";\n form.style.display = \"none\";\n } else {\n // Any non-success status (editing/submitting/error) shows the form and\n // hides the success panel. Without this, a reset()→\"editing\" re-emit\n // would leave the success panel up and the form hidden until reload.\n successEl.style.display = \"none\";\n form.style.display = \"\";\n }\n }\n\n // ── Boot: fetch spec, then build the interactive form ──\n void (async () => {\n let spec: OnboardingSpec;\n try {\n spec = await fetchOnboardingSpec({\n baseUrl: options.baseUrl,\n onboarder: options.onboarder,\n fetch: options.fetch,\n timeoutMs: options.timeoutMs,\n cache,\n // Reuse a spec already loaded for this onboarder this session (a\n // remount into the same page shouldn't re-hit the network). A 409 on\n // submit is the authoritative staleness signal that triggers refetch.\n preferCached: true,\n });\n } catch (err) {\n if (unmounted) return;\n loadingEl.textContent =\n \"The signup form could not be loaded. Please refresh the page.\";\n options.onError?.(err);\n return;\n }\n if (unmounted) return;\n\n siteKey = options.siteKey ?? spec.botChallenge?.siteKey ?? \"\";\n currentSpecVersion = spec.specVersion;\n\n const control = createSignupStepper(spec);\n stepper = control;\n\n form.addEventListener(\"submit\", (event: Event) => {\n event.preventDefault();\n void handleSubmit(control);\n });\n\n form.appendChild(stepsIndicator);\n form.appendChild(staleBanner);\n form.appendChild(stepArea);\n form.appendChild(serverErrorEl);\n\n wrapper.removeChild(loadingEl);\n wrapper.appendChild(successEl);\n wrapper.appendChild(form);\n\n unsubscribe = control.subscribe((state) => onStateChange(control, state));\n // Initial render\n onStateChange(control, control.getState());\n options.onReady?.(spec);\n })();\n\n return {\n unmount() {\n unmounted = true;\n unsubscribe?.();\n if (wrapper.parentNode === host) host.removeChild(wrapper);\n },\n reset() {\n idempotencyKey = null;\n lastFingerprint = null;\n // Force a full re-render on the next state emit so cleared answers\n // actually re-render as empty inputs.\n renderedStepIndex = -1;\n renderedStale = false;\n if (stepper) {\n // stepper.reset() clears answers/credentials/consent and transitions\n // status back to \"editing\"; the emitted state re-renders the form,\n // hides the success panel (via onStateChange's else branch), and\n // repositions to step 0.\n stepper.reset();\n } else {\n form.style.display = \"\";\n successEl.style.display = \"none\";\n }\n },\n };\n}\n","/// <reference lib=\"dom\" />\n/// <reference lib=\"dom.iterable\" />\nexport {\n mountContactForm,\n type ContactFormMountOptions,\n type MountedWidget,\n} from \"./contact-form.js\";\n\nexport { mountSignupForm, type SignupFormMountOptions } from \"./signup-form.js\";\n\nexport { injectWidgetStyles, DEFAULT_WIDGET_CSS } from \"./styles.js\";\n\nexport { cssEscape, idSelector } from \"./dom-utils.js\";\n\n// D543 default ConsentPack step components (opt-in — the headless controller\n// in @nodii/onboarding/consent is enough to build a bespoke consent UI). NO\n// iframe: doc content renders inline same-origin so scroll-to-end is real.\nexport {\n renderConsentStep,\n updateConsentStep,\n consentDocElementId,\n type ConsentStepRenderOptions,\n} from \"./consent-step.js\";\n\n/**\n * Namespace entrypoint mirroring the plan's mount API:\n * OnboardingWidget.mount(el, { onboarder, form: 'contact'|'signup', baseUrl, ... })\n */\nimport { mountContactForm } from \"./contact-form.js\";\nimport type { ContactFormMountOptions, MountedWidget } from \"./contact-form.js\";\nimport { mountSignupForm } from \"./signup-form.js\";\nimport type { SignupFormMountOptions } from \"./signup-form.js\";\n\nexport type WidgetMountOptions =\n ContactFormMountOptions | SignupFormMountOptions;\n\nexport const OnboardingWidget = {\n /**\n * Mount the onboarding widget into a host element.\n *\n * @param el - The DOM element to render into.\n * @param options - Widget configuration. `form: \"contact\"` renders the\n * fixed contact form (Phase 1); `form: \"signup\"` fetches the D540 spec\n * and renders the dynamic stepper (Phase 2 — siteKey comes from the\n * spec's botChallenge unless overridden).\n * @returns A mounted widget control (unmount / reset).\n *\n * @example\n * ```ts\n * import { OnboardingWidget } from \"@nodii/onboarding/widget\";\n *\n * OnboardingWidget.mount(document.getElementById(\"signup-form\")!, {\n * onboarder: \"acme-corp\",\n * form: \"signup\",\n * baseUrl: \"https://api.acme.nucleus-cloud.in\",\n * onSuccess: (r) => console.log(\"landed at\", r.terminalStage),\n * });\n * ```\n */\n mount(el: HTMLElement, options: WidgetMountOptions): MountedWidget {\n if (options.form === \"contact\") {\n return mountContactForm(el, options);\n }\n if (options.form === \"signup\") {\n return mountSignupForm(el, options);\n }\n throw new Error(\n `OnboardingWidget.mount: unknown form \"${(options as { form: string }).form}\". Supported: \"contact\", \"signup\".`,\n );\n },\n} as const;\n"]}
@@ -1,4 +1,5 @@
1
1
  import { fetchDocumentContent } from './chunk-SEKNVHD3.js';
2
+ import { fetchWithTimeout } from './chunk-XJTJPBJB.js';
2
3
  import createDOMPurify from 'dompurify';
3
4
  import { marked } from 'marked';
4
5
 
@@ -165,7 +166,7 @@ async function renderPdf(container, control, consentKey, doc, blob, onRetry) {
165
166
  return fail();
166
167
  }
167
168
  try {
168
- configurePdfWorker(pdfjs);
169
+ await configurePdfWorker(pdfjs);
169
170
  const data = new Uint8Array(await blob.arrayBuffer());
170
171
  const pdf = await pdfjs.getDocument({ data }).promise;
171
172
  const body = document.createElement("div");
@@ -197,7 +198,8 @@ async function renderPdf(container, control, consentKey, doc, blob, onRetry) {
197
198
  return fail();
198
199
  }
199
200
  }
200
- var pdfWorkerConfigured = false;
201
+ var pdfWorkerReady = null;
202
+ var WORKER_PROBE_TIMEOUT_MS = 5e3;
201
203
  function resolvePackagedWorkerUrl() {
202
204
  const WORKER_SPEC = "pdfjs-dist/build/pdf.worker.min.mjs";
203
205
  const meta = import.meta;
@@ -215,20 +217,33 @@ function resolvePackagedWorkerUrl() {
215
217
  }
216
218
  }
217
219
  function configurePdfWorker(pdfjs) {
218
- if (pdfWorkerConfigured) return;
219
- const opts = pdfjs.GlobalWorkerOptions;
220
- if (opts.workerPort || opts.workerSrc) {
221
- pdfWorkerConfigured = true;
222
- return;
223
- }
224
- const packagedUrl = resolvePackagedWorkerUrl();
225
- if (packagedUrl) {
226
- opts.workerSrc = packagedUrl;
227
- } else {
228
- const version = pdfjs.version ?? "";
229
- opts.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${version}/build/pdf.worker.min.mjs`;
220
+ pdfWorkerReady ??= (async () => {
221
+ const opts = pdfjs.GlobalWorkerOptions;
222
+ if (opts.workerPort || opts.workerSrc) return;
223
+ opts.workerSrc = await _pickPdfWorkerSrc(
224
+ resolvePackagedWorkerUrl(),
225
+ pdfjs.version ?? ""
226
+ );
227
+ })();
228
+ return pdfWorkerReady;
229
+ }
230
+ async function _pickPdfWorkerSrc(packagedUrl, apiVersion, fetchImpl = globalThis.fetch, timeoutMs = WORKER_PROBE_TIMEOUT_MS) {
231
+ const cdn = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${apiVersion}/build/pdf.worker.min.mjs`;
232
+ if (!packagedUrl) return cdn;
233
+ if (!/^https?:/i.test(packagedUrl)) return packagedUrl;
234
+ try {
235
+ const res = await fetchWithTimeout(packagedUrl, {
236
+ credentials: "omit",
237
+ fetchImpl,
238
+ timeoutMs
239
+ });
240
+ const type = res.headers.get("content-type") ?? "";
241
+ await res.body?.cancel().catch(() => {
242
+ });
243
+ return res.ok && /javascript|ecmascript/i.test(type) ? packagedUrl : cdn;
244
+ } catch {
245
+ return cdn;
230
246
  }
231
- pdfWorkerConfigured = true;
232
247
  }
233
248
  function handleRenderFailure(container, control, consentKey, doc, onRetry) {
234
249
  if (doc.acceptanceLevel === "open_then_accept") {
@@ -298,9 +313,9 @@ async function renderConsentDocument(container, doc, control, options) {
298
313
  return { renderedAs: "text" };
299
314
  }
300
315
  function _resetPdfWorkerState() {
301
- pdfWorkerConfigured = false;
316
+ pdfWorkerReady = null;
302
317
  }
303
318
 
304
- export { _resetPdfWorkerState, renderConsentDocument };
305
- //# sourceMappingURL=chunk-LVJM4CTG.js.map
306
- //# sourceMappingURL=chunk-LVJM4CTG.js.map
319
+ export { _pickPdfWorkerSrc, _resetPdfWorkerState, renderConsentDocument };
320
+ //# sourceMappingURL=chunk-T7EWURTF.js.map
321
+ //# sourceMappingURL=chunk-T7EWURTF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/viewer/render.ts"],"names":[],"mappings":"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","file":"chunk-T7EWURTF.js","sourcesContent":["/**\n * Default ConsentPack document viewer (D543 §5) — @nodii/onboarding/viewer.\n *\n * A SEPARATE, opt-in module built on STANDARD libraries so the base SDK stays\n * lean: consumers only pay for the viewer if they render our default consent\n * components. The headless controller (@nodii/onboarding/consent) knows nothing\n * about this — it just receives reportScrollProgress / markScrolledToEnd /\n * markOpened from whatever renders the doc.\n *\n * Renderers (per fetched artifact — NO IFRAME anywhere; everything is inline,\n * same-origin, so `scroll_then_accept` scroll tracking is REAL):\n * - text/html → sanitize with DOMPurify, inject into a scroll <div>.\n * - markdown → marked → DOMPurify → inject into a scroll <div>.\n * - text/plain → escaped text (textContent) in a scroll <div>.\n * - application/pdf → PDF.js (pdfjs-dist), rendered to <canvas> + a text\n * layer, page by page, in a scroll <div>. PDF.js is LAZY-loaded via a\n * dynamic import() ONLY when a PDF doc is actually present, so it never\n * bloats the base bundle.\n *\n * The scroll container's scroll-to-end (and the PDF/open fallbacks) drive the\n * consent controller so the gate works for real. A failed fetch/render\n * degrades to an \"open in a new tab\" affordance (marks the doc opened /\n * scrolled) so every doc stays consentable.\n *\n * Bundle discipline: DOMPurify + marked are imported at module top (this is\n * the VIEWER entry, not the base SDK — the base `@nodii/onboarding` never\n * statically imports this file). pdfjs-dist is imported ONLY via dynamic\n * import() inside renderPdf, so even the viewer entry doesn't eagerly load it.\n */\n\nimport createDOMPurify from \"dompurify\";\nimport { marked } from \"marked\";\nimport type { ConsentController } from \"../consent/controller.js\";\nimport type { ConsentDocument } from \"../consent/model.js\";\nimport { fetchWithTimeout } from \"../submit/http.js\";\nimport {\n fetchDocumentContent,\n type FetchedConsentDocument,\n} from \"../consent/document.js\";\n\n/**\n * DOMPurify bound to the current window. The default import is BOTH a\n * pre-bound instance AND a factory `(window) => instance`. Binding it\n * explicitly to `globalThis` (which happy-dom / a real browser populate with\n * `window`) guarantees a working DOM even in environments where DOMPurify's\n * implicit global detection misfires (e.g. bun + happy-dom under test), where\n * an unbound instance silently passes HTML through UN-sanitized. Lazily\n * memoized so we only bind once.\n */\nlet purifier: ReturnType<typeof createDOMPurify> | null = null;\nfunction getPurifier(): ReturnType<typeof createDOMPurify> {\n if (purifier) return purifier;\n const win = (globalThis as { window?: unknown }).window ?? globalThis;\n // createDOMPurify is callable as a factory; when the arg is a window-like\n // object it returns an instance bound to it.\n purifier = (\n createDOMPurify as unknown as (\n w: unknown,\n ) => ReturnType<typeof createDOMPurify>\n )(win);\n return purifier;\n}\n\nexport interface ConsentDocumentViewerOptions {\n /** Injectable fetch for the presigned artifact GET (defaults to global). */\n fetch?: typeof globalThis.fetch;\n /** Per-request timeout in ms (default from fetchDocumentContent). */\n timeoutMs?: number;\n /**\n * The `key` the controller identifies this document by (doc_type |\n * custom:<key>). The viewer reports scroll/open evidence under this key.\n */\n consentKey: string;\n}\n\n/** Result of rendering — lets the caller know how the doc was displayed. */\nexport interface ConsentDocumentViewerResult {\n /**\n * How the artifact was rendered.\n *\n * - html | markdown | text | pdf → rendered inline (gate is driven by real\n * scroll/open).\n * - open-affordance → an `open_then_accept` doc that opens in a new tab (the\n * real-open IS its gate; satisfies ONLY `opened`).\n * - unrenderable → a GATED doc (scroll_then_accept) that could NOT be\n * rendered inline. The gate stays UNSATISFIABLE — accept is disabled and a\n * clear error is shown. NO evidence is ever fabricated (COMPLIANCE, D543).\n */\n renderedAs:\n \"html\" | \"markdown\" | \"text\" | \"pdf\" | \"open-affordance\" | \"unrenderable\";\n}\n\nconst SCROLL_END_EPSILON = 2;\n\nfunction clearNode(node: HTMLElement): void {\n while (node.firstChild) node.removeChild(node.firstChild);\n}\n\n/**\n * Does the box hold ACTUAL readable rendered content? A \"content fits without\n * scrolling\" ratio of 1 is only legitimate when there is genuinely something to\n * have read. Content = non-empty text (HTML/markdown/text render) OR at least\n * one rendered PDF page canvas. A bare wrapper `<div>` with empty text is NOT\n * content — so an empty-artifact doc (e.g. a 0-byte or all-whitespace body, or\n * a not-yet-populated box) can NEVER satisfy the gate. This is the P0a\n * by-construction guarantee: the ratio-1 branch depends on rendered-content\n * presence, not on geometry a headless runtime cannot measure — fabrication is\n * impossible in EVERY runtime.\n */\nfunction boxHasContent(box: HTMLElement): boolean {\n if ((box.textContent ?? \"\").trim().length > 0) return true;\n // PDF pages carry no text — a rendered page canvas counts as content.\n return box.querySelector(\"canvas\") !== null;\n}\n\n/**\n * A scroll <div> that reports scroll progress to the controller. Returns the\n * box AND a `reportScroll` fn the caller MUST invoke ONLY AFTER real content is\n * appended — never at creation. `report` refuses to satisfy the \"fits without\n * scrolling\" case unless the box actually holds content, so an empty or\n * pre-render box can never latch scrolled_to_end (P0a — by construction).\n */\nfunction makeScrollBox(\n control: ConsentController,\n consentKey: string,\n): { box: HTMLDivElement; reportScroll: () => void } {\n const box = document.createElement(\"div\");\n box.className = \"nodii-onboarding-consent-scrollbox\";\n box.setAttribute(\"tabindex\", \"0\");\n box.setAttribute(\"role\", \"region\");\n const report = (): void => {\n // COMPLIANCE (P0a): an empty / not-yet-rendered box can NEVER satisfy the\n // gate — there is nothing to have read. This holds in EVERY runtime,\n // independent of scroll geometry (which a headless DOM cannot measure).\n if (!boxHasContent(box)) return;\n // Unmeasured container (no layout yet / happy-dom) → do NOT report a\n // fits-without-scroll: scrollHeight 0 is not evidence the user reached the\n // end. A real scroll event still reports its measured ratio.\n if (box.scrollHeight <= 0) return;\n const ratio =\n box.scrollHeight - box.clientHeight <= 0\n ? // Content is present AND genuinely fits without scrolling → \"at end\".\n 1\n : Math.min(\n 1,\n (box.scrollTop + box.clientHeight + SCROLL_END_EPSILON) /\n box.scrollHeight,\n );\n control.reportScrollProgress(consentKey, ratio);\n };\n box.addEventListener(\"scroll\", report);\n // NOTE: no report is scheduled at creation. The caller invokes reportScroll()\n // AFTER content is appended (short-doc auto-unlock then only fires with\n // content present). This is what makes P0a a construction guarantee.\n return { box, reportScroll: report };\n}\n\n/** Detect markdown by content-type or a .md-looking downloadUrl. */\nfunction isMarkdown(\n fetched: FetchedConsentDocument,\n doc: Pick<ConsentDocument, \"downloadUrl\">,\n): boolean {\n return (\n fetched.contentType.includes(\"markdown\") ||\n /\\.mdx?(\\?|#|$)/i.test(doc.downloadUrl)\n );\n}\n\n/** Tags that must never survive into the rendered consent document. */\nconst DANGEROUS_TAGS = new Set([\n \"SCRIPT\",\n \"IFRAME\",\n \"OBJECT\",\n \"EMBED\",\n \"FORM\",\n \"STYLE\",\n \"LINK\",\n \"META\",\n \"BASE\",\n]);\n\n/**\n * Defense-in-depth pass AFTER DOMPurify: walk the parsed DOM and remove any\n * dangerous element, every on* event-handler attribute, and javascript:/data:\n * URLs. DOMPurify is the primary, audited sanitizer, but this deterministic\n * DOM walk (a) hardens against any DOMPurify config gap and (b) is provably\n * correct in EVERY runtime — including ones where DOMPurify's own DOM-based\n * pass is a no-op (e.g. certain SSR/test DOMs). Belt-and-suspenders, not a\n * hand-rolled replacement for DOMPurify.\n */\n/**\n * Normalize a URL for scheme inspection the way a browser does BEFORE\n * resolving it: strip ALL ASCII whitespace and control characters (code\n * points <= 0x20, plus DEL 0x7F) anywhere in the string, not just the ends.\n * Browsers ignore these inside a URL, so a scheme split by an embedded tab/\n * newline/NUL (e.g. jav<TAB>ascript:) still executes; a mere .trim() leaves\n * the embedded ones and the startsWith('javascript:') check is bypassed.\n * Char-code filtering avoids embedding literal control bytes in a regex.\n */\nfunction normalizeUrlForSchemeCheck(value: string): string {\n let out = \"\";\n for (let i = 0; i < value.length; i++) {\n const cp = value.charCodeAt(i);\n if (cp > 0x20 && cp !== 0x7f) out += value[i];\n }\n return out.toLowerCase();\n}\n\nconst DANGEROUS_URL_SCHEMES = [\"javascript:\", \"vbscript:\", \"data:text/html\"];\n\nfunction hardenElement(root: HTMLElement): void {\n const walker = (node: Element): void => {\n // Copy children first — removal mutates the live list.\n const children = Array.from(node.children);\n if (DANGEROUS_TAGS.has(node.tagName)) {\n node.remove();\n return;\n }\n for (const attr of Array.from(node.attributes)) {\n const name = attr.name.toLowerCase();\n // Whitespace/control-stripped, lower-cased value for scheme inspection.\n const value = normalizeUrlForSchemeCheck(attr.value);\n if (name.startsWith(\"on\")) {\n node.removeAttribute(attr.name);\n continue;\n }\n if (\n (name === \"href\" || name === \"src\" || name === \"xlink:href\") &&\n DANGEROUS_URL_SCHEMES.some((s) => value.startsWith(s))\n ) {\n node.removeAttribute(attr.name);\n }\n if (name === \"srcdoc\") node.removeAttribute(attr.name);\n }\n for (const child of children) walker(child);\n };\n for (const child of Array.from(root.children)) walker(child);\n}\n\n/** Render sanitized HTML inline into a scroll box. */\nfunction renderSanitizedHtml(\n container: HTMLElement,\n control: ConsentController,\n consentKey: string,\n html: string,\n): void {\n clearNode(container);\n const { box, reportScroll } = makeScrollBox(control, consentKey);\n const body = document.createElement(\"div\");\n body.className = \"nodii-onboarding-consent-doc-body\";\n // Primary: DOMPurify (the standard, audited Cure53 sanitizer). FORBID_TAGS\n // on <iframe>/<object>/<embed>/<form> so a doc can't smuggle a frame in.\n body.innerHTML = getPurifier().sanitize(html, {\n FORBID_TAGS: [\"iframe\", \"object\", \"embed\", \"form\"],\n FORBID_ATTR: [\"srcdoc\"],\n ADD_ATTR: [\"target\", \"rel\"],\n });\n // Defense-in-depth: a deterministic DOM walk that removes any residual\n // dangerous node/attr, correct in every runtime (see hardenElement).\n hardenElement(body);\n box.appendChild(body);\n container.appendChild(box);\n // Content is now IN the box → the short-doc auto-unlock may fire (P0a: report\n // ONLY after content is present, never at box creation).\n reportScroll();\n}\n\n/** Render escaped plain text inline into a scroll box. */\nfunction renderPlainText(\n container: HTMLElement,\n control: ConsentController,\n consentKey: string,\n text: string,\n): void {\n clearNode(container);\n const { box, reportScroll } = makeScrollBox(control, consentKey);\n const body = document.createElement(\"div\");\n body.className = \"nodii-onboarding-consent-doc-body\";\n body.textContent = text; // safe-by-construction (no markup interpretation)\n box.appendChild(body);\n container.appendChild(box);\n reportScroll(); // only after content is present (P0a)\n}\n\n/**\n * The LEGITIMATE gate affordance for an `open_then_accept` doc: an open-in-new\n * tab link. Opening the doc in a new tab IS the gate for this level, so a REAL\n * navigation satisfies ONLY `opened` (never `scrolled_to_end`). A native\n * <a target=\"_blank\"> navigates on click AND on Enter (keyboard activation of\n * an anchor) — we mark `opened` on those, which correspond to a real open. We\n * do NOT bind Space (Space does not activate an anchor → no navigation → no\n * open → must not mark opened; binding it would fabricate evidence).\n *\n * This is used both as the primary affordance for open_then_accept and as the\n * failure fallback for open_then_accept when inline preview is unavailable —\n * either way the gate is genuinely the real open.\n */\nfunction renderOpenGateAffordance(\n container: HTMLElement,\n control: ConsentController,\n consentKey: string,\n doc: Pick<ConsentDocument, \"downloadUrl\" | \"title\">,\n note?: string,\n): void {\n clearNode(container);\n const link = document.createElement(\"a\");\n link.className = \"nodii-onboarding-consent-open\";\n link.href = doc.downloadUrl;\n link.target = \"_blank\";\n link.rel = \"noopener noreferrer\";\n link.textContent = `Open ${doc.title}`;\n // Mark opened ONLY on real activation of the anchor (click / Enter). No\n // Space handler — Space does not navigate an <a>, so it is not a real open.\n const markOpened = (): void => control.markOpened(consentKey);\n link.addEventListener(\"click\", markOpened);\n link.addEventListener(\"keydown\", (event) => {\n if ((event as KeyboardEvent).key === \"Enter\") markOpened();\n });\n const row = document.createElement(\"div\");\n row.className = \"nodii-onboarding-consent-open-row\";\n row.appendChild(link);\n if (note) {\n const noteEl = document.createElement(\"p\");\n noteEl.className = \"nodii-onboarding-consent-note\";\n noteEl.textContent = note;\n row.appendChild(noteEl);\n }\n container.appendChild(row);\n}\n\n/**\n * COMPLIANCE-CRITICAL (P0, D543): a GATED doc whose acceptance requires SEEING\n * the content inline (scroll_then_accept) could NOT be rendered inline (fetch\n * failure, expired presigned URL, CORS, octet-stream, PDF.js failure, viewer\n * unavailable). The gate MUST stay UNSATISFIABLE — the SDK NEVER fabricates\n * `scrolled_to_end` on a mere click. Render a clear error + a Retry, and an\n * \"Open in a new tab\" link that is INFORMATIONAL ONLY (it does NOT satisfy the\n * scroll gate — reading in a new tab is not evidence the user scrolled the\n * rendered doc to the end for this level). Accept stays disabled; the operator\n * must fix the artifact/URL for this doc to become acceptable.\n */\nfunction renderUnrenderableError(\n container: HTMLElement,\n doc: Pick<ConsentDocument, \"downloadUrl\" | \"title\">,\n onRetry: () => void,\n): void {\n clearNode(container);\n const wrap = document.createElement(\"div\");\n wrap.className = \"nodii-onboarding-consent-unrenderable\";\n wrap.setAttribute(\"role\", \"alert\");\n\n const msg = document.createElement(\"p\");\n msg.className = \"nodii-onboarding-consent-error\";\n msg.textContent = `“${doc.title}” could not be loaded, so it cannot be accepted yet. Please retry; if it keeps failing, contact support.`;\n wrap.appendChild(msg);\n\n const retry = document.createElement(\"button\");\n retry.type = \"button\";\n retry.className = \"nodii-onboarding-consent-retry\";\n retry.textContent = \"Retry loading document\";\n retry.addEventListener(\"click\", onRetry);\n wrap.appendChild(retry);\n\n // Informational only — opening in a new tab does NOT satisfy the scroll gate.\n const link = document.createElement(\"a\");\n link.className = \"nodii-onboarding-consent-open\";\n link.href = doc.downloadUrl;\n link.target = \"_blank\";\n link.rel = \"noopener noreferrer\";\n link.textContent = `Open ${doc.title} in a new tab`;\n wrap.appendChild(link);\n\n container.appendChild(wrap);\n}\n\n/**\n * Render a PDF via PDF.js into a scroll box (canvas per page). pdfjs-dist is\n * LAZY-loaded here (dynamic import) so it never enters the base bundle. On any\n * failure (import/worker/CSP/parse/zero-page), route through handleRenderFailure\n * — for a scroll_then_accept doc that is UNRENDERABLE (gate stays unsatisfiable,\n * never fabricated); for open_then_accept it is the real-open affordance (P0).\n * The scroll box is only attached (and progress only reported) AFTER pages are\n * rendered, so an empty/pre-render box can never satisfy the gate (P0a).\n */\nasync function renderPdf(\n container: HTMLElement,\n control: ConsentController,\n consentKey: string,\n doc: ConsentDocument,\n blob: Blob,\n onRetry: () => void,\n): Promise<ConsentDocumentViewerResult> {\n const fail = (): ConsentDocumentViewerResult =>\n handleRenderFailure(container, control, consentKey, doc, onRetry);\n\n let pdfjs: typeof import(\"pdfjs-dist\");\n try {\n pdfjs = await import(\"pdfjs-dist\");\n } catch {\n return fail();\n }\n\n try {\n // Configure the worker so getDocument does not reject on\n // \"No GlobalWorkerOptions.workerSrc specified\" (pdfjs-dist v6). Resolve the\n // packaged worker via a bundler-friendly URL; if that fails, fall back to\n // the CDN for the exact installed version (never leaves the worker unset).\n await configurePdfWorker(pdfjs);\n const data = new Uint8Array(await blob.arrayBuffer());\n const pdf = await pdfjs.getDocument({ data }).promise;\n\n // Render EVERY page into a DETACHED body FIRST — the scroll box is not put\n // into the container (and reportScroll is not called) until real content is\n // present (P0a: an empty/pre-render box can never satisfy the gate, even in\n // a real browser where an empty 360px box measures scrollHeight==clientH).\n const body = document.createElement(\"div\");\n body.className = \"nodii-onboarding-consent-doc-body nodii-consent-pdf\";\n for (let pageNo = 1; pageNo <= pdf.numPages; pageNo++) {\n const page = await pdf.getPage(pageNo);\n const viewport = page.getViewport({ scale: 1.2 });\n const canvas = document.createElement(\"canvas\");\n canvas.className = \"nodii-consent-pdf-page\";\n canvas.width = Math.ceil(viewport.width);\n canvas.height = Math.ceil(viewport.height);\n const ctx = canvas.getContext(\"2d\");\n if (ctx) {\n await page.render({ canvas, canvasContext: ctx, viewport }).promise;\n }\n body.appendChild(canvas);\n }\n\n // Lifecycle guard: if the container was detached while we awaited the PDF\n // (stage re-render / unmount / a Retry started a fresh render), abandon —\n // don't mutate an orphaned tree or fight a concurrent render (P2 lifecycle).\n if (typeof container.isConnected === \"boolean\" && !container.isConnected) {\n return { renderedAs: \"unrenderable\" };\n }\n // A zero-page or all-empty PDF has no readable content → treat as a render\n // failure (never satisfy a gate on an empty box).\n if (body.childElementCount === 0) return fail();\n\n clearNode(container);\n const { box, reportScroll } = makeScrollBox(control, consentKey);\n box.appendChild(body);\n container.appendChild(box);\n // Content is now present → the short-PDF auto-unlock may fire (P0a).\n reportScroll();\n return { renderedAs: \"pdf\" };\n } catch {\n return fail();\n }\n}\n\n/** The session's one worker configuration, shared by concurrent renders. */\nlet pdfWorkerReady: Promise<void> | null = null;\n\n/** How long the packaged-worker probe may take before the CDN is used. */\nconst WORKER_PROBE_TIMEOUT_MS = 5000;\n\ninterface WorkerGlobalOptions {\n workerSrc?: string;\n workerPort?: unknown;\n}\n\n/**\n * Resolve the packaged pdf worker module to a LOADABLE URL, robust across\n * runtimes:\n * 1. `import.meta.resolve(...)` — real module resolution (Node/bun ESM);\n * resolves through node_modules to the actual file (the plain\n * `new URL(spec, import.meta.url)` does NOT — it's relative to THIS file,\n * which 404s, the exact P2 dead-fallback bug).\n * 2. `new URL(\"pdfjs-dist/build/pdf.worker.min.mjs\", import.meta.url)`, a\n * candidate only. A bundler does NOT rewrite this bare-specifier form: in\n * a Vite build it points at `/assets/pdfjs-dist/...`, which does not exist,\n * and a SPA host answers it with its HTML page (proven on the Nodii\n * website, 2026-10-25). The caller probes it before use.\n * Returns null if neither yields a URL (→ caller falls back to the CDN).\n */\nfunction resolvePackagedWorkerUrl(): string | null {\n const WORKER_SPEC = \"pdfjs-dist/build/pdf.worker.min.mjs\";\n const meta = import.meta as ImportMeta & {\n resolve?: (spec: string) => string;\n };\n if (typeof meta.resolve === \"function\") {\n try {\n const resolved = meta.resolve(WORKER_SPEC);\n if (resolved) return resolved;\n } catch {\n // fall through to the bundler-rewrite form\n }\n }\n try {\n return new URL(WORKER_SPEC, import.meta.url).href;\n } catch {\n return null;\n }\n}\n\n/**\n * Ensure pdfjs has a LOADABLE worker before getDocument (P2). Real pdfjs-dist\n * v6 rejects getDocument without one, and merely SETTING `workerSrc` is not the\n * same as the worker LOADING: the naive `new URL('pdfjs-dist/build/...',\n * import.meta.url)` resolves RELATIVE TO THIS MODULE (not through\n * node_modules), so it points at a path that 404s at load — the dead-fallback\n * bug P2 flags. We resolve the worker to a genuinely-loadable URL instead\n * (`import.meta.resolve` → real module resolution; else the bundler-rewrite\n * `new URL` form; else the version-pinned CDN).\n *\n * We set `workerSrc` (not `workerPort`): a resolved file/asset/CDN URL loads in\n * BOTH a real browser (bundler-served or CDN) AND Node/bun (resolved file\n * path) — proven by the [P2] real-pdfjs test which renders a real PDF with the\n * worker configured here and NO pre-set workerSrc. If the worker still can't\n * load (offline + unresolvable), getDocument rejects and the caller degrades\n * to `unrenderable` — a gated PDF that can't render stays unacceptable, NEVER\n * fabricated (P0). Idempotent per session.\n */\nfunction configurePdfWorker(pdfjs: typeof import(\"pdfjs-dist\")): Promise<void> {\n pdfWorkerReady ??= (async () => {\n const opts = pdfjs.GlobalWorkerOptions as WorkerGlobalOptions;\n // A consumer (or a prior call) already wired a worker → respect it.\n if (opts.workerPort || opts.workerSrc) return;\n opts.workerSrc = await _pickPdfWorkerSrc(\n resolvePackagedWorkerUrl(),\n (pdfjs as { version?: string }).version ?? \"\",\n );\n })();\n return pdfWorkerReady;\n}\n\n/**\n * The worker URL to use: the packaged candidate when it really serves a\n * script, else the CDN build of the exact API version that is loaded (so the\n * API and the worker can never disagree on version).\n *\n * An http(s) candidate is fetched and judged the way the browser will judge a\n * module worker: a 2xx with a JavaScript MIME type. A host's HTML fallback page\n * or a 404 fails, so a bundled page no longer ends up with a worker that cannot\n * load and every scroll-to-accept PDF unrenderable. A file: or blob: candidate\n * comes from the runtime's own module resolution and is used as is.\n *\n * The probe is bounded like every other request the SDK makes: its answer is\n * kept for the session and awaited before every PDF, so a host that accepts\n * the connection and then stalls must cost one timeout, not every PDF on the\n * page. A probe that times out counts as \"not a script\".\n *\n * Exported for tests only.\n */\nexport async function _pickPdfWorkerSrc(\n packagedUrl: string | null,\n apiVersion: string,\n fetchImpl: typeof globalThis.fetch = globalThis.fetch,\n timeoutMs = WORKER_PROBE_TIMEOUT_MS,\n): Promise<string> {\n const cdn = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${apiVersion}/build/pdf.worker.min.mjs`;\n if (!packagedUrl) return cdn;\n if (!/^https?:/i.test(packagedUrl)) return packagedUrl;\n try {\n const res = await fetchWithTimeout(packagedUrl, {\n credentials: \"omit\",\n fetchImpl,\n timeoutMs,\n });\n const type = res.headers.get(\"content-type\") ?? \"\";\n // Only the verdict is needed; the worker load fetches it again.\n await res.body?.cancel().catch(() => {});\n return res.ok && /javascript|ecmascript/i.test(type) ? packagedUrl : cdn;\n } catch {\n return cdn;\n }\n}\n\n/**\n * COMPLIANCE-CRITICAL failure router (P0): a doc could not be rendered inline.\n * - open_then_accept → the real-open affordance (opening IS its gate; satisfies\n * ONLY `opened`). This is legitimate, not a fabrication.\n * - scroll_then_accept → UNRENDERABLE: the gate stays unsatisfiable, a clear\n * error + Retry is shown, accept is disabled. NEVER fabricate scrolled_to_end.\n * - checkbox → no gate (already satisfiable): show the error + a plain open link\n * for reference; accept remains enabled (the checkbox gate needs no evidence).\n */\nfunction handleRenderFailure(\n container: HTMLElement,\n control: ConsentController,\n consentKey: string,\n doc: ConsentDocument,\n onRetry: () => void,\n): ConsentDocumentViewerResult {\n if (doc.acceptanceLevel === \"open_then_accept\") {\n renderOpenGateAffordance(\n container,\n control,\n consentKey,\n doc,\n \"The inline preview is unavailable. Opening the document in a new tab satisfies this step.\",\n );\n return { renderedAs: \"open-affordance\" };\n }\n // scroll_then_accept (and checkbox — harmless there): show the error. For a\n // scroll gate this leaves it UNSATISFIABLE (accept stays disabled).\n renderUnrenderableError(container, doc, onRetry);\n return { renderedAs: \"unrenderable\" };\n}\n\n/**\n * Fetch + render a consent document INLINE into `container`, wiring its scroll\n * container (or the legitimate open-affordance) to the consent controller so\n * `scroll_then_accept` / `open_then_accept` gates work for real. NO iframe.\n *\n * On ANY inline-render failure for a `scroll_then_accept` doc the gate stays\n * UNSATISFIABLE (never fabricates scrolled_to_end, D543 §5 COMPLIANCE) — the\n * caller's Retry re-invokes this.\n *\n * @returns how the doc was rendered (for the caller's telemetry/UX).\n */\nexport async function renderConsentDocument(\n container: HTMLElement,\n doc: ConsentDocument,\n control: ConsentController,\n options: ConsentDocumentViewerOptions,\n): Promise<ConsentDocumentViewerResult> {\n const { consentKey } = options;\n const onRetry = (): void => {\n void renderConsentDocument(container, doc, control, options);\n };\n\n let fetched: FetchedConsentDocument;\n try {\n fetched = await fetchDocumentContent(doc, {\n fetch: options.fetch,\n timeoutMs: options.timeoutMs,\n });\n } catch {\n return handleRenderFailure(container, control, consentKey, doc, onRetry);\n }\n\n // If the container was detached while we awaited the fetch (the consent stage\n // re-rendered, or the widget unmounted), skip DOM work — a stale render must\n // not mutate an orphaned node or leak an unhandled error.\n if (typeof container.isConnected === \"boolean\" && !container.isConnected) {\n return { renderedAs: \"unrenderable\" };\n }\n\n // open_then_accept: opening the doc in a new tab IS the gate — scrolling an\n // inline render does NOT satisfy it (reportScrollProgress no-ops for this\n // level). So on a SUCCESSFUL fetch we ALSO present the open affordance (which\n // marks `opened` on a real open) so the gate is satisfiable through the\n // default viewer (P1). We do not attempt an inline scroll gate here.\n if (doc.acceptanceLevel === \"open_then_accept\") {\n renderOpenGateAffordance(\n container,\n control,\n consentKey,\n doc,\n \"Open the document in a new tab to review it — that satisfies this step.\",\n );\n return { renderedAs: \"open-affordance\" };\n }\n\n if (fetched.kind === \"pdf\" && fetched.blob) {\n return renderPdf(\n container,\n control,\n consentKey,\n doc,\n fetched.blob,\n onRetry,\n );\n }\n if (fetched.kind === \"binary\") {\n // A binary/octet-stream artifact cannot be previewed inline → same\n // compliance rule: gated docs stay unsatisfiable, never click-to-satisfy.\n return handleRenderFailure(container, control, consentKey, doc, onRetry);\n }\n // text or html\n const text = fetched.text ?? \"\";\n if (isMarkdown(fetched, doc)) {\n const html = await marked.parse(text, { async: true });\n renderSanitizedHtml(container, control, consentKey, html);\n return { renderedAs: \"markdown\" };\n }\n if (fetched.kind === \"html\") {\n renderSanitizedHtml(container, control, consentKey, text);\n return { renderedAs: \"html\" };\n }\n renderPlainText(container, control, consentKey, text);\n return { renderedAs: \"text\" };\n}\n\n/** Reset the module-level pdf-worker latch (tests). */\nexport function _resetPdfWorkerState(): void {\n pdfWorkerReady = null;\n}\n"]}
@@ -1,4 +1,5 @@
1
- import { validateLeadsPayload } from './chunk-SIMLMQPT.js';
1
+ import { validateLeadsPayload } from './chunk-WKN4U7QF.js';
2
+ import { isSubdomainLabelShape, SUBDOMAIN_SHAPE_MESSAGE } from './chunk-OLWR5COK.js';
2
3
  import { DEFAULT_REQUEST_TIMEOUT_MS, OnboardingValidationError, fetchWithTimeout, OnboardingNetworkError, OnboardingBotChallengeError, OnboardingConflictError, OnboardingRateLimitError, OnboardingServerError, OnboardingConsentIncompleteError, OnboardingSpecStaleError, OnboardingConsentStaleError, OnboardingSubdomainTakenError } from './chunk-XJTJPBJB.js';
3
4
  import { z } from 'zod/v3';
4
5
 
@@ -192,7 +193,7 @@ var signupWireSchema = z.object({
192
193
  displayName: z.string().trim().min(1).max(200).optional()
193
194
  }).strict(),
194
195
  organisationName: z.string().trim().min(1).max(200).optional(),
195
- subdomain: z.string().trim().min(1).max(63)
196
+ subdomain: z.string().trim().min(1).max(63).refine(isSubdomainLabelShape, SUBDOMAIN_SHAPE_MESSAGE)
196
197
  }).strict();
197
198
  function computeSignupFingerprint(body) {
198
199
  const canonical = JSON.stringify([
@@ -397,5 +398,5 @@ async function submitSignup(body, options) {
397
398
  }
398
399
 
399
400
  export { computePayloadFingerprint, computeSignupFingerprint, consentSubmitDocumentSchema, generateIdempotencyKey, resolveBotToken, signupWireSchema, submitLead, submitSignup };
400
- //# sourceMappingURL=chunk-BMQINH6O.js.map
401
- //# sourceMappingURL=chunk-BMQINH6O.js.map
401
+ //# sourceMappingURL=chunk-UHOFGWI7.js.map
402
+ //# sourceMappingURL=chunk-UHOFGWI7.js.map