@riverbankcms/sdk 0.151.0 → 0.152.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 (226) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/{EventEmbeddedCheckoutStep-BBHbM22D.mjs → EventEmbeddedCheckoutStep-DVQXWFm6.mjs} +10 -9
  3. package/dist/{PreviewEditorSidebar-BHplI9HE.mjs → PreviewEditorSidebar-Dr4NJi3Q.mjs} +4 -3
  4. package/dist/{PreviewEditorUI-DuyN8nsD.mjs → PreviewEditorUI-DSZXQbyh.mjs} +5 -4
  5. package/dist/{SdkPreviewModeRuntime-CR5ypwxJ.mjs → SdkPreviewModeRuntime-Dl4GyMc3.mjs} +124 -53
  6. package/dist/{SiteChromeCustomizeContext-D5t6joF_.mjs → SiteChromeCustomizeContext-DgBe-FlM.mjs} +20418 -32298
  7. package/dist/ThemedButton-B8ViBnLK.mjs +16350 -0
  8. package/dist/_dts/api/src/bookingOperations.d.ts +5 -3
  9. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +4 -0
  10. package/dist/_dts/api/src/endpoints.d.ts +7 -0
  11. package/dist/_dts/api/src/index.d.ts +1 -1
  12. package/dist/_dts/api/src/navigation/types.d.ts +7 -0
  13. package/dist/_dts/api/src/navigation.d.ts +1 -1
  14. package/dist/_dts/api/src/publicAppointmentBookingContracts.d.ts +10 -1
  15. package/dist/_dts/api/src/siteAssets.d.ts +1 -0
  16. package/dist/_dts/blocks/src/definitions.d.ts +1 -1
  17. package/dist/_dts/blocks/src/index.d.ts +1 -0
  18. package/dist/_dts/blocks/src/pageRenderPreparation.d.ts +1 -0
  19. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +1 -1
  20. package/dist/_dts/blocks/src/primitives/content/utils/sanitizeHref.d.ts +1 -1
  21. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +4 -4
  22. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +16 -0
  23. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +5 -0
  24. package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +2 -0
  25. package/dist/_dts/blocks/src/system/helpers/normalizeMailingListBlockContent.d.ts +2 -0
  26. package/dist/_dts/blocks/src/system/registry.d.ts +14 -2
  27. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +0 -5
  28. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +2 -0
  29. package/dist/_dts/blocks/src/system/runtime/api/schemas/events.d.ts +971 -0
  30. package/dist/_dts/blocks/src/system/runtime/api/schemas/waitlist-claims.d.ts +42 -0
  31. package/dist/_dts/blocks/src/system/runtime/api/types/appointments.d.ts +10 -2
  32. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +10 -136
  33. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +48 -6
  34. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -3
  35. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingSubmission.state.d.ts +2 -0
  36. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +3 -1
  37. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -1
  38. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +23 -0
  39. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +6 -2
  40. package/dist/_dts/blocks/src/system/runtime/nodes/carousel.client.hooks.d.ts +6 -0
  41. package/dist/_dts/blocks/src/system/runtime/nodes/carousel.client.state.d.ts +7 -0
  42. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/BookingEntryViews.d.ts +42 -0
  43. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventEmbeddedCheckoutStep.d.ts +4 -1
  44. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationBookingLayer.d.ts +19 -9
  45. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationPayment.d.ts +4 -2
  46. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +24 -9
  47. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizardContent.d.ts +4 -2
  48. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventSelectionStep.d.ts +5 -4
  49. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/GuestDetailsSection.d.ts +1 -1
  50. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.d.ts +2 -0
  51. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SingleTicketEntitlementNote.d.ts +11 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SuccessStep.d.ts +4 -0
  53. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +5 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/VerifyingTimeoutStep.d.ts +2 -0
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/bookingCardDisplay.d.ts +31 -0
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/bookingEntry.d.ts +154 -0
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/bookingFocus.d.ts +12 -0
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -2
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +2 -2
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +9 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/finishedBooking.d.ts +77 -0
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/index.d.ts +0 -1
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/offeringNoun.d.ts +12 -0
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/paymentResponse.d.ts +2 -1
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationCompletion.d.ts +33 -1
  66. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDerivations.d.ts +11 -0
  67. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDisplay.d.ts +31 -0
  68. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDraft.state.d.ts +60 -0
  69. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +1 -1
  70. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.d.ts +3 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationStateMachine.d.ts +58 -10
  72. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationSurface.d.ts +17 -0
  73. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +23 -7
  74. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useBookingBarFacts.d.ts +12 -0
  75. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationRecoveryRequest.d.ts +3 -0
  76. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +4 -0
  77. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +4 -11
  78. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +1563 -31
  79. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.d.ts +2 -12
  80. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.d.ts +147 -4
  81. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +50 -2
  82. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/waitlistClaimRestoration.d.ts +6 -5
  83. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/wizardSteps.d.ts +85 -15
  84. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +53 -8
  85. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/MonthLookView.d.ts +10 -3
  86. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +16 -0
  87. package/dist/_dts/blocks/src/system/runtime/shared/bookingPaymentOptionCopy.d.ts +5 -1
  88. package/dist/_dts/blocks/src/system/runtime/shared/bookingPaymentOptions.d.ts +37 -1
  89. package/dist/_dts/blocks/src/system/runtime/shared/components/ModalShell.d.ts +9 -2
  90. package/dist/_dts/blocks/src/system/runtime/shared/components/PaymentChoiceRows.d.ts +28 -0
  91. package/dist/_dts/blocks/src/system/runtime/shared/components/StepIndicator.d.ts +6 -8
  92. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -2
  93. package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +2 -2
  94. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +9 -12
  95. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +15 -0
  96. package/dist/_dts/blocks/src/system/runtime/shared/utils/themePortalRoot.d.ts +10 -15
  97. package/dist/_dts/blocks/src/system/transforms/registry/index.d.ts +1 -0
  98. package/dist/_dts/blocks/src/system/transforms/registry/links.d.ts +3 -1
  99. package/dist/_dts/commerce/src/purchase/bookingInstalmentSchedule.d.ts +2 -0
  100. package/dist/_dts/commerce/src/purchase/bookingPaymentSelection.d.ts +6 -0
  101. package/dist/_dts/commerce/src/purchase/confirmationEmailPayment.d.ts +14 -14
  102. package/dist/_dts/commerce/src/purchase/confirmationPayment.d.ts +65 -0
  103. package/dist/_dts/commerce/src/purchase/confirmationPaymentSchema.d.ts +66 -0
  104. package/dist/_dts/commerce/src/purchase/index.d.ts +2 -0
  105. package/dist/_dts/commerce/src/purchase/orderPaymentState.d.ts +8 -0
  106. package/dist/_dts/content-model/src/templates/defaults.d.ts +2 -2
  107. package/dist/_dts/core/src/appointment-booking-terms.d.ts +20 -0
  108. package/dist/_dts/core/src/booking-payment-schemas.d.ts +70 -0
  109. package/dist/_dts/core/src/branded.d.ts +0 -2
  110. package/dist/_dts/core/src/demo-claim-access.d.ts +1 -1
  111. package/dist/_dts/core/src/demo-claim-readiness.d.ts +18 -0
  112. package/dist/_dts/core/src/demo-lifecycle-status.d.ts +1 -1
  113. package/dist/_dts/core/src/demo-warm-pool-target.d.ts +1 -1
  114. package/dist/_dts/core/src/index.d.ts +4 -0
  115. package/dist/_dts/core/src/mailing-list-targeting-availability.d.ts +68 -0
  116. package/dist/_dts/core/src/mailing-list-targeting.d.ts +2 -0
  117. package/dist/_dts/core/src/ticket-quantity.d.ts +13 -0
  118. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +51 -32
  119. package/dist/_dts/editor/src/chrome/chromeLayers.d.ts +7 -0
  120. package/dist/_dts/editor/src/index.d.ts +1 -0
  121. package/dist/_dts/editor-blocks/src/widgets/link/LinkAddressInput.d.ts +8 -0
  122. package/dist/_dts/editor-blocks/src/widgets/link/LinkContentList.d.ts +12 -0
  123. package/dist/_dts/editor-blocks/src/widgets/link/LinkPicker.d.ts +5 -1
  124. package/dist/_dts/editor-blocks/src/widgets/link/LinkPickerDialog.d.ts +3 -3
  125. package/dist/_dts/editor-blocks/src/widgets/link/LinkSummary.d.ts +8 -2
  126. package/dist/_dts/editor-blocks/src/widgets/link/LinkWidget.d.ts +4 -3
  127. package/dist/_dts/editor-blocks/src/widgets/link/LinkWidgetContext.d.ts +2 -1
  128. package/dist/_dts/editor-blocks/src/widgets/link/draft.d.ts +44 -0
  129. package/dist/_dts/editor-blocks/src/widgets/link/presentation.d.ts +13 -0
  130. package/dist/_dts/editor-blocks/src/widgets/link/types.d.ts +14 -0
  131. package/dist/_dts/editor-blocks/src/widgets/link/useRoutableContent.d.ts +2 -0
  132. package/dist/_dts/editor-blocks/src/widgets/link/utils.d.ts +5 -4
  133. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.d.ts +1 -1
  134. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +13 -8
  135. package/dist/_dts/media-core/src/fileStorage.d.ts +4 -3
  136. package/dist/_dts/media-core/src/index.d.ts +1 -0
  137. package/dist/_dts/media-core/src/storageObjectKey.d.ts +12 -0
  138. package/dist/_dts/media-react/src/hooks/useSupabaseMediaUploader.d.ts +1 -1
  139. package/dist/_dts/media-react/src/internal/supabaseResumableUpload.d.ts +13 -0
  140. package/dist/_dts/preview-next/src/client/preview/previewModeRootAttribute.d.ts +11 -0
  141. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +0 -1
  142. package/dist/_dts/sdk/src/rendering/image.d.ts +10 -0
  143. package/dist/_dts/sdk/src/rendering/index.d.ts +3 -1
  144. package/dist/_dts/sdk/src/rendering/link.d.ts +9 -0
  145. package/dist/_dts/sdk/src/rendering/overrides.d.ts +1 -0
  146. package/dist/_dts/sdk/src/version.d.ts +1 -1
  147. package/dist/_dts/theme-core/src/blocks/opaquePanels.d.ts +3 -3
  148. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  149. package/dist/client/BookingMailingListNote-CBuMKN0w.mjs +386 -0
  150. package/dist/client/{CardListItem-ZDLYh6dL.mjs → CardListItem-Dc9XTXhB.mjs} +3 -4
  151. package/dist/client/CheckIcon-CpyXr-Kg.mjs +35 -0
  152. package/dist/client/{CheckboxChoice-M-3HycLw.mjs → CheckboxChoice-CIqx_o0E.mjs} +1 -1
  153. package/dist/client/{DemoBookingPortalAccess-BMtvPTWE.mjs → DemoBookingPortalAccess-D3VQ_kLj.mjs} +85 -85
  154. package/dist/client/{EventCombined.client-DUm_DOxW.mjs → EventCombined.client-BHGEKise.mjs} +8 -9
  155. package/dist/client/{EventEmbeddedCheckoutStep-DsNNzgRm.mjs → EventEmbeddedCheckoutStep-Bo1Cm23R.mjs} +11 -10
  156. package/dist/client/{EventListing.client-DjNYGUVm.mjs → EventListing.client-D5OQgVPr.mjs} +2 -2
  157. package/dist/client/{LeafletStaticMap-DuFiOHq_.mjs → LeafletStaticMap-CLL5cWrr.mjs} +1 -1
  158. package/dist/client/{ModalShell-CqkBvBIC.mjs → ModalShell-BXzucfR6.mjs} +83 -12
  159. package/dist/client/{RichText-LjPCUGGi.mjs → RichText-BoDmnopf.mjs} +6 -3
  160. package/dist/client/{ThemedButton-DZKjtaDD.mjs → ThemedButton-Ciltp0IK.mjs} +2 -2
  161. package/dist/client/{accordion-Qe--SILD.mjs → accordion-DOkRS64-.mjs} +1 -1
  162. package/dist/client/aspectTransforms-D-TnDdq4.mjs +93 -0
  163. package/dist/client/{bookingForm-3BCl4g_f.mjs → bookingForm-wlMVwo9h.mjs} +289 -149
  164. package/dist/client/bookings.mjs +12212 -10832
  165. package/dist/client/{carousel-h2YjKOS2.mjs → carousel-CGWk-Z0u.mjs} +2 -2
  166. package/dist/client/{carousel.client-BLrd4hmY.mjs → carousel.client-kX5mN1Eg.mjs} +46 -41
  167. package/dist/client/{cart-5NeiigVd.mjs → cart-OBBPlaH4.mjs} +3 -3
  168. package/dist/client/{checkout-G4UWjOEw.mjs → checkout-Bmw2WjQX.mjs} +3 -3
  169. package/dist/client/client.mjs +9541 -6039
  170. package/dist/client/{colorStyles-DTunOThj.mjs → colorStyles-ECDNPE_P.mjs} +23 -86
  171. package/dist/client/{context-GK4-AVAh.mjs → context-BI77UFAn.mjs} +275 -10
  172. package/dist/client/{eventCalendar-Prw3Yo_L.mjs → eventCalendar-qkej2Edn.mjs} +19 -17
  173. package/dist/client/{eventCombined-BUugi6__.mjs → eventCombined-DApKHvat.mjs} +4 -4
  174. package/dist/client/{eventDetails-CBHUda-R.mjs → eventDetails-BQyUDPH0.mjs} +3 -4
  175. package/dist/client/{eventListing-CQeG45Dg.mjs → eventListing-CeAnshlZ.mjs} +4 -4
  176. package/dist/client/{eventRegistration-Dif3p3oJ.mjs → eventRegistration-C3A3NyBO.mjs} +2209 -2144
  177. package/dist/client/{form-Cf0WMtfG.mjs → form-DW8rU7jO.mjs} +6 -6
  178. package/dist/client/{headerSection-Bqdr3JWp.mjs → headerSection-CkIhsoNm.mjs} +9 -9
  179. package/dist/client/hooks.mjs +1289 -380
  180. package/dist/client/{locationMap-BVvPou4O.mjs → locationMap-D4O8wbli.mjs} +4 -4
  181. package/dist/client/{media-47fcnhzD.mjs → media-C5K_0xPd.mjs} +2 -2
  182. package/dist/client/{newsletterForm-Cx-1dnic.mjs → newsletterForm-B7IxSPuz.mjs} +5 -5
  183. package/dist/client/{productDetail-DaUMaJYk.mjs → productDetail-Bqxpwy5N.mjs} +3 -3
  184. package/dist/client/{productList-BKQlWEKE.mjs → productList-u9Lz8V15.mjs} +3 -3
  185. package/dist/client/{propsDecoder-DO5iXphQ.mjs → propsDecoder-Bf1jucUp.mjs} +17333 -14489
  186. package/dist/client/rendering/client.mjs +58216 -55133
  187. package/dist/client/rendering/islands.mjs +19 -19
  188. package/dist/client/rendering.mjs +9099 -5636
  189. package/dist/client/{routeIslandApiConfig-BNm0Z3-g.mjs → routeIslandApiConfig-BgP-aPMl.mjs} +1 -1
  190. package/dist/client/{shop-D7ytcFBC.mjs → shop-B_eykR-_.mjs} +16 -14
  191. package/dist/client/{shop-commerce-D68-hHy2.mjs → shop-commerce-CT0APkFV.mjs} +9 -9
  192. package/dist/client/{shop-commerce-store-Cu7X2lyu.mjs → shop-commerce-store-DcvZxdEK.mjs} +1 -1
  193. package/dist/client/{shopShared-D12rxE69.mjs → shopShared-BVJOiUiJ.mjs} +5 -5
  194. package/dist/client/themePortalRoot-DS92SRVZ.mjs +47 -0
  195. package/dist/client/{TerminalPanel-DOTSUCO0.mjs → useDiscountCodeUi-DPmYDunz.mjs} +60 -77
  196. package/dist/client/{useEventPagination-jgKa67KV.mjs → useEventPagination-8-U55vH5.mjs} +7 -8
  197. package/dist/preview-next/before-render.mjs +7 -0
  198. package/dist/preview-next/client/runtime.mjs +3 -3
  199. package/dist/preview-next/keepAlive.mjs +7 -0
  200. package/dist/preview-next/middleware.mjs +7 -0
  201. package/dist/{sdk-runtime-4cCWO_3i.mjs → sdk-runtime-C5jPdSrk.mjs} +1 -1
  202. package/dist/server/components.mjs +3138 -1373
  203. package/dist/server/config-validation.mjs +1395 -486
  204. package/dist/server/config.mjs +1395 -486
  205. package/dist/server/data.mjs +1289 -380
  206. package/dist/server/index.mjs +8 -1
  207. package/dist/server/next.mjs +3362 -1538
  208. package/dist/server/page-converter.mjs +1357 -453
  209. package/dist/server/prebuild.mjs +1 -1
  210. package/dist/server/rendering/server.mjs +2335 -1044
  211. package/dist/server/rendering.mjs +3152 -1370
  212. package/dist/server/routing.mjs +1437 -490
  213. package/dist/server/server.mjs +1297 -381
  214. package/dist/server/theme-bridge.mjs +1135 -795
  215. package/dist/{spinner-tSdG9YvG.mjs → spinner-B-ab2rJp.mjs} +1 -1
  216. package/dist/styles/index.css +1088 -721
  217. package/package.json +1 -1
  218. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/OrderSummary.d.ts +0 -15
  219. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.d.ts +0 -22
  220. package/dist/_dts/blocks/src/system/runtime/shared/components/SelectableOptionCard.d.ts +0 -30
  221. package/dist/client/BookingMailingListNote-DlDSs5Vm.mjs +0 -567
  222. package/dist/client/pricing-CMD0kADd.mjs +0 -314
  223. package/dist/client/result-DRW7JWXz.mjs +0 -30
  224. package/dist/client/scrollToBlock-C86BYkyV.mjs +0 -17
  225. package/dist/client/themePortalRoot-AGs4cE7t.mjs +0 -30
  226. package/dist/spinner-BL3kW9Uh.mjs +0 -803
@@ -917,8 +917,32 @@ function canonicalEventPricingDisplay(pricing) {
917
917
  default: return assertNever$4(pricing);
918
918
  }
919
919
  }
920
+ /**
921
+ * The single renderer for a precomputed booking price `display` ADT. This is
922
+ * the one place booking price variants map to user-facing strings — every call
923
+ * site (booking entry, events calendar, event/course details, listings, portal)
924
+ * should route through here so labels never drift. Adding a variant to the ADT
925
+ * breaks compilation here (via `assertNever`) until it is handled.
926
+ */
927
+ function formatBookingPriceDisplay(display, options = {}) {
928
+ switch (display.kind) {
929
+ case "free": return "Free";
930
+ case "exact": return formatCurrencyAmount(display.amount, display.currency, options);
931
+ case "from": return `From ${formatCurrencyAmount(display.amount, display.currency, options)}`;
932
+ case "range": return `${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)}`;
933
+ case "mixed": return display.paidToAmount > display.paidFromAmount ? `Free / ${formatCurrencyAmount(display.paidFromAmount, display.currency, options)} - ${formatCurrencyAmount(display.paidToAmount, display.currency, options)}` : `Free / ${formatCurrencyAmount(display.paidFromAmount, display.currency, options)}`;
934
+ case "unavailable": return "Pricing unavailable";
935
+ case "external": return display.label;
936
+ default: return assertNever$4(display);
937
+ }
938
+ }
939
+ /** Render an event's price directly from its pricing value. */
940
+ function formatEventPricing(pricing, options = {}) {
941
+ return formatBookingPriceDisplay(publicEventPricingDisplay(pricing), options);
942
+ }
920
943
  var init_event_pricing = __esmMin((() => {
921
944
  init_assert_never();
945
+ init_currency_format();
922
946
  init_planner();
923
947
  }));
924
948
  //#endregion
@@ -1039,6 +1063,9 @@ var init_public_event_booking_availability = __esmMin((() => {}));
1039
1063
  //#region ../core/src/money-input.ts
1040
1064
  var init_money_input = __esmMin((() => {}));
1041
1065
  //#endregion
1066
+ //#region ../core/src/ticket-quantity.ts
1067
+ var init_ticket_quantity = __esmMin((() => {}));
1068
+ //#endregion
1042
1069
  //#region ../core/src/booking-flexible-balance.ts
1043
1070
  var init_booking_flexible_balance = __esmMin((() => {}));
1044
1071
  //#endregion
@@ -1067,6 +1094,9 @@ var init_booking_payment_options = __esmMin((() => {
1067
1094
  init_result();
1068
1095
  }));
1069
1096
  //#endregion
1097
+ //#region ../core/src/appointment-booking-terms.ts
1098
+ var init_appointment_booking_terms = __esmMin((() => {}));
1099
+ //#endregion
1070
1100
  //#region ../core/src/booking-time-zone.ts
1071
1101
  function isValidBookingTimeZone(timeZone) {
1072
1102
  const normalized = timeZone.trim();
@@ -1212,6 +1242,34 @@ function toScheduledBookingDateTime(input) {
1212
1242
  if (result.ok) return result.value;
1213
1243
  throw new Error(formatParseError(result));
1214
1244
  }
1245
+ function formatBookingInstant(isoString, options) {
1246
+ const date = new Date(isoString);
1247
+ if (Number.isNaN(date.getTime())) return isoString;
1248
+ return getCachedDateTimeFormatter(options.locale ?? DEFAULT_LOCALE, getSafeTimeZone(options.timeZone), options.format).format(date);
1249
+ }
1250
+ function formatBookingDate(input, format = {
1251
+ weekday: "long",
1252
+ year: "numeric",
1253
+ month: "long",
1254
+ day: "numeric"
1255
+ }) {
1256
+ return formatBookingInstant(input.startsAt, {
1257
+ locale: input.locale,
1258
+ timeZone: input.timeZone,
1259
+ format
1260
+ });
1261
+ }
1262
+ function formatBookingTime(input, format = {
1263
+ hour: "numeric",
1264
+ minute: "2-digit",
1265
+ hour12: true
1266
+ }) {
1267
+ return formatBookingInstant(input.startsAt, {
1268
+ locale: input.locale,
1269
+ timeZone: input.timeZone,
1270
+ format
1271
+ });
1272
+ }
1215
1273
  function getBookingLocalDateKey(input) {
1216
1274
  return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
1217
1275
  }
@@ -1311,10 +1369,11 @@ function localScheduleDateTimeToUtcDate(localDate, localTime, timeZone) {
1311
1369
  }
1312
1370
  return new Date(guess);
1313
1371
  }
1314
- var FALLBACK_TIMEZONE, START_OF_DAY, LOCAL_DATE_PATTERN, DATE_TIME_FORMATTER_CACHE_LIMIT, dateTimeFormatterCache;
1372
+ var DEFAULT_LOCALE, FALLBACK_TIMEZONE, START_OF_DAY, LOCAL_DATE_PATTERN, DATE_TIME_FORMATTER_CACHE_LIMIT, dateTimeFormatterCache;
1315
1373
  var init_booking_date_time = __esmMin((() => {
1316
1374
  init_result();
1317
1375
  init_booking_time_zone();
1376
+ DEFAULT_LOCALE = "en-US";
1318
1377
  FALLBACK_TIMEZONE = "UTC";
1319
1378
  START_OF_DAY = {
1320
1379
  hour: 0,
@@ -1582,6 +1641,13 @@ var init_mailing_list_setup_parser = __esmMin((() => {
1582
1641
  }));
1583
1642
  //#endregion
1584
1643
  //#region ../core/src/mailing-list-targeting.ts
1644
+ function mailingListTargetingChoiceIds(targeting) {
1645
+ switch (targeting.provider) {
1646
+ case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
1647
+ case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
1648
+ case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
1649
+ }
1650
+ }
1585
1651
  function planMailingListChoicePresentation(targeting) {
1586
1652
  if (targeting.mode === "default" || targeting.selection.tag === "fixed") return { tag: "hidden" };
1587
1653
  switch (targeting.provider) {
@@ -1620,7 +1686,110 @@ function planMailingListChoicePresentation(targeting) {
1620
1686
  };
1621
1687
  }
1622
1688
  }
1623
- var init_mailing_list_targeting = __esmMin((() => {}));
1689
+ var DEFAULT_MAILING_LIST_TARGETING;
1690
+ var init_mailing_list_targeting = __esmMin((() => {
1691
+ DEFAULT_MAILING_LIST_TARGETING = { mode: "default" };
1692
+ }));
1693
+ //#endregion
1694
+ //#region ../core/src/mailing-list-targeting-availability.ts
1695
+ function resolveMailingListDefaultDestination(provider) {
1696
+ switch (provider.provider) {
1697
+ case "native": return provider.topics.find((item) => item.id === provider.defaultTopicId) ?? null;
1698
+ case "brevo": return provider.lists.find((item) => item.id === provider.defaultListId) ?? null;
1699
+ case "mailchimp": return provider.audiences.find((item) => item.id === provider.defaultAudienceId) ?? null;
1700
+ }
1701
+ }
1702
+ function assessMailingListTargeting(context, targeting) {
1703
+ if (context?.tag !== "configured") return {
1704
+ tag: "unavailable",
1705
+ reason: "setup_missing",
1706
+ targeting
1707
+ };
1708
+ const catalog = context.provider;
1709
+ if (targeting.mode === "custom") return assessCustomTargeting(catalog, targeting);
1710
+ const destination = resolveMailingListDefaultDestination(catalog);
1711
+ return destination === null ? {
1712
+ tag: "unavailable",
1713
+ reason: "default_missing",
1714
+ targeting
1715
+ } : {
1716
+ tag: "available",
1717
+ value: {
1718
+ mode: "default",
1719
+ targeting,
1720
+ provider: catalog.provider,
1721
+ destination
1722
+ }
1723
+ };
1724
+ }
1725
+ function assessCustomTargeting(catalog, targeting) {
1726
+ switch (targeting.provider) {
1727
+ case "native": return catalog.provider === "native" ? assessMatchedChoices({
1728
+ provider: "native",
1729
+ catalog,
1730
+ targeting
1731
+ }, catalog.topics) : {
1732
+ tag: "unavailable",
1733
+ reason: "provider_mismatch",
1734
+ targeting
1735
+ };
1736
+ case "brevo": return catalog.provider === "brevo" ? assessMatchedChoices({
1737
+ provider: "brevo",
1738
+ catalog,
1739
+ targeting
1740
+ }, catalog.lists) : {
1741
+ tag: "unavailable",
1742
+ reason: "provider_mismatch",
1743
+ targeting
1744
+ };
1745
+ case "mailchimp": {
1746
+ if (catalog.provider !== "mailchimp") return {
1747
+ tag: "unavailable",
1748
+ reason: "provider_mismatch",
1749
+ targeting
1750
+ };
1751
+ const audience = catalog.audiences.find((item) => item.id === targeting.audienceId);
1752
+ return audience === void 0 ? {
1753
+ tag: "unavailable",
1754
+ reason: "audience_missing",
1755
+ value: {
1756
+ mode: "custom",
1757
+ provider: "mailchimp",
1758
+ catalog,
1759
+ targeting
1760
+ }
1761
+ } : assessMatchedChoices({
1762
+ provider: "mailchimp",
1763
+ catalog,
1764
+ targeting,
1765
+ audience
1766
+ }, audience.interests);
1767
+ }
1768
+ }
1769
+ }
1770
+ function assessMatchedChoices(matched, choices) {
1771
+ const selected = new Set(mailingListTargetingChoiceIds(matched.targeting));
1772
+ const available = new Set(choices.map((item) => item.id));
1773
+ const missingIds = [...selected].filter((id) => !available.has(id));
1774
+ const value = {
1775
+ mode: "custom",
1776
+ ...matched,
1777
+ choices,
1778
+ selectedChoices: choices.filter((item) => selected.has(item.id))
1779
+ };
1780
+ return missingIds.length > 0 ? {
1781
+ tag: "unavailable",
1782
+ reason: "choices_missing",
1783
+ missingIds,
1784
+ value
1785
+ } : {
1786
+ tag: "available",
1787
+ value
1788
+ };
1789
+ }
1790
+ var init_mailing_list_targeting_availability = __esmMin((() => {
1791
+ init_mailing_list_targeting();
1792
+ }));
1624
1793
  //#endregion
1625
1794
  //#region ../core/src/mailing-list-runtime.ts
1626
1795
  function parseMailingListRuntimeContext(value) {
@@ -1686,57 +1855,47 @@ function parseBrevoRuntimeProvider(value) {
1686
1855
  function parseMailchimpRuntimeProvider(value) {
1687
1856
  if (!Array.isArray(value.audiences)) return null;
1688
1857
  const defaultAudienceId = parseMailchimpAudienceId(value.defaultAudienceId);
1689
- if (defaultAudienceId === null) return null;
1690
- const audiences = [];
1691
- for (const audience of value.audiences) {
1692
- if (!isRecord$13(audience)) return null;
1693
- const id = parseMailchimpAudienceId(audience.id);
1694
- const name = parseName(audience.name);
1695
- if (id === null || name === null || !Array.isArray(audience.interests)) return null;
1696
- const interests = parseMailchimpInterests(audience.interests);
1697
- if (interests === null) return null;
1698
- audiences.push({
1699
- id,
1700
- name,
1701
- interests
1702
- });
1703
- }
1704
- return {
1858
+ const audiences = Array.from(value.audiences, parseMailchimpAudience);
1859
+ return defaultAudienceId !== null && audiences.every((audience) => audience !== null) ? {
1705
1860
  provider: "mailchimp",
1706
1861
  defaultAudienceId,
1707
1862
  audiences
1708
- };
1863
+ } : null;
1709
1864
  }
1710
- function parseMailchimpInterests(value) {
1711
- const interests = [];
1712
- for (const interest of value) {
1713
- if (!isRecord$13(interest)) return null;
1714
- const id = parseMailchimpInterestId(interest.id);
1715
- const name = parseName(interest.name);
1716
- const categoryName = parseName(interest.categoryName);
1717
- if (id === null || name === null || categoryName === null) return null;
1718
- interests.push({
1719
- id,
1720
- name,
1721
- categoryName
1722
- });
1723
- }
1724
- return interests;
1865
+ function parseMailchimpAudience(value) {
1866
+ if (!isRecord$13(value) || !Array.isArray(value.interests)) return null;
1867
+ const id = parseMailchimpAudienceId(value.id);
1868
+ const name = parseName(value.name);
1869
+ const interests = Array.from(value.interests, parseMailchimpInterest);
1870
+ return id !== null && name !== null && interests.every((interest) => interest !== null) ? {
1871
+ id,
1872
+ name,
1873
+ interests
1874
+ } : null;
1875
+ }
1876
+ function parseMailchimpInterest(value) {
1877
+ if (!isRecord$13(value)) return null;
1878
+ const id = parseMailchimpInterestId(value.id);
1879
+ const name = parseName(value.name);
1880
+ const categoryName = parseName(value.categoryName);
1881
+ return id !== null && name !== null && categoryName !== null ? {
1882
+ id,
1883
+ name,
1884
+ categoryName
1885
+ } : null;
1725
1886
  }
1726
1887
  function parseNamedItems(value, parseId) {
1727
1888
  if (!Array.isArray(value)) return null;
1728
- const items = [];
1729
- for (const item of value) {
1889
+ const items = Array.from(value, (item) => {
1730
1890
  if (!isRecord$13(item)) return null;
1731
1891
  const id = parseId(item.id);
1732
1892
  const name = parseName(item.name);
1733
- if (id === null || name === null) return null;
1734
- items.push({
1893
+ return id !== null && name !== null ? {
1735
1894
  id,
1736
1895
  name
1737
- });
1738
- }
1739
- return items;
1896
+ } : null;
1897
+ });
1898
+ return items.every((item) => item !== null) ? items : null;
1740
1899
  }
1741
1900
  function parseName(value) {
1742
1901
  if (typeof value !== "string") return null;
@@ -1757,6 +1916,7 @@ var init_mailing_list_runtime = __esmMin((() => {
1757
1916
  //#endregion
1758
1917
  //#region ../core/src/mailing-list-targeting-parser.ts
1759
1918
  function parseMailingListPlacementTargeting(value) {
1919
+ if (value == null) return ok$1(DEFAULT_MAILING_LIST_TARGETING);
1760
1920
  if (!isRecord$12(value)) return targetingError("shape");
1761
1921
  if (value.mode === "default") return ok$1({ mode: "default" });
1762
1922
  if (value.mode !== "custom") return targetingError("mode");
@@ -1855,14 +2015,11 @@ function parseNonEmptyUniqueIds(value, parseId) {
1855
2015
  }
1856
2016
  function parseUniqueIds(value, parseId) {
1857
2017
  if (!Array.isArray(value)) return targetingError("targets");
1858
- const parsed = [];
1859
- for (const item of value) {
2018
+ return Array.from(value).reduce((parsed, item) => {
2019
+ if (!parsed.ok) return parsed;
1860
2020
  const id = parseId(item);
1861
- if (id === null) return targetingError("targets");
1862
- if (parsed.includes(id)) return targetingError("duplicate_target");
1863
- parsed.push(id);
1864
- }
1865
- return ok$1(parsed);
2021
+ return id === null ? targetingError("targets") : parsed.value.includes(id) ? targetingError("duplicate_target") : ok$1([...parsed.value, id]);
2022
+ }, ok$1([]));
1866
2023
  }
1867
2024
  function isRecord$12(value) {
1868
2025
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1875,6 +2032,7 @@ function targetingError(field) {
1875
2032
  }
1876
2033
  var init_mailing_list_targeting_parser = __esmMin((() => {
1877
2034
  init_mailing_list_identifiers();
2035
+ init_mailing_list_targeting();
1878
2036
  init_result();
1879
2037
  }));
1880
2038
  //#endregion
@@ -2373,7 +2531,46 @@ var init_navigation_locations = __esmMin((() => {}));
2373
2531
  var init_navigation_portal_labels = __esmMin((() => {}));
2374
2532
  //#endregion
2375
2533
  //#region ../core/src/event-preset-vocabulary.ts
2376
- var init_event_preset_vocabulary = __esmMin((() => {}));
2534
+ var EVENT_PRESET_VOCABULARY;
2535
+ var init_event_preset_vocabulary = __esmMin((() => {
2536
+ EVENT_PRESET_VOCABULARY = {
2537
+ event: {
2538
+ label: "Event",
2539
+ pluralLabel: "Events",
2540
+ description: "Any event, repeating or manually dated, that does not fit the other categories."
2541
+ },
2542
+ class: {
2543
+ label: "Class",
2544
+ pluralLabel: "Classes",
2545
+ description: "Regular scheduled classes and group sessions."
2546
+ },
2547
+ course: {
2548
+ label: "Course",
2549
+ pluralLabel: "Courses",
2550
+ description: "A fixed set of dates that people book together."
2551
+ },
2552
+ term: {
2553
+ label: "Term",
2554
+ pluralLabel: "Terms",
2555
+ description: "A fixed term of sessions that people book together."
2556
+ },
2557
+ workshop: {
2558
+ label: "Workshop",
2559
+ pluralLabel: "Workshops",
2560
+ description: "One-off workshops, day sessions, or special events."
2561
+ },
2562
+ retreat: {
2563
+ label: "Retreat",
2564
+ pluralLabel: "Retreats",
2565
+ description: "Multi-day or residential immersive experiences."
2566
+ },
2567
+ performance: {
2568
+ label: "Performance",
2569
+ pluralLabel: "Performances",
2570
+ description: "Audience-facing shows, concerts, recitals, or showcases."
2571
+ }
2572
+ };
2573
+ }));
2377
2574
  //#endregion
2378
2575
  //#region ../core/src/event-catalogue.ts
2379
2576
  var init_event_catalogue = __esmMin((() => {}));
@@ -2381,6 +2578,9 @@ var init_event_catalogue = __esmMin((() => {}));
2381
2578
  //#region ../core/src/patch/index.ts
2382
2579
  var init_patch = __esmMin((() => {}));
2383
2580
  //#endregion
2581
+ //#region ../core/src/demo-claim-readiness.ts
2582
+ var init_demo_claim_readiness = __esmMin((() => {}));
2583
+ //#endregion
2384
2584
  //#region ../core/src/index.ts
2385
2585
  var init_src$4 = __esmMin((() => {
2386
2586
  init_branded();
@@ -2400,12 +2600,14 @@ var init_src$4 = __esmMin((() => {
2400
2600
  init_event_page_selection();
2401
2601
  init_public_event_booking_availability();
2402
2602
  init_money_input();
2603
+ init_ticket_quantity();
2403
2604
  init_booking_flexible_balance();
2404
2605
  init_booking_refunds();
2405
2606
  init_booking_instalments();
2406
2607
  init_booking_instalment_deposit();
2407
2608
  init_booking_live_payment_terms();
2408
2609
  init_booking_payment_options();
2610
+ init_appointment_booking_terms();
2409
2611
  init_booking_date_time();
2410
2612
  init_booking_consent();
2411
2613
  init_appointment_service_categories();
@@ -2438,6 +2640,7 @@ var init_src$4 = __esmMin((() => {
2438
2640
  init_mailing_list_setup();
2439
2641
  init_mailing_list_setup_parser();
2440
2642
  init_mailing_list_targeting();
2643
+ init_mailing_list_targeting_availability();
2441
2644
  init_mailing_list_runtime();
2442
2645
  init_mailing_list_targeting_parser();
2443
2646
  init_mailing_list_submission();
@@ -2467,6 +2670,7 @@ var init_src$4 = __esmMin((() => {
2467
2670
  init_event_preset_vocabulary();
2468
2671
  init_event_catalogue();
2469
2672
  init_patch();
2673
+ init_demo_claim_readiness();
2470
2674
  }));
2471
2675
  //#endregion
2472
2676
  //#region ../media-core/src/types.ts
@@ -2488,6 +2692,11 @@ var init_fileDomain = __esmMin((() => {
2488
2692
  unsafeAsPositiveByteCount$1(250 * 1024 * 1024), unsafeAsPositiveByteCount$1(500 * 1024 * 1024), unsafeAsPositiveByteCount$1(100 * 1024 * 1024), unsafeAsPositiveByteCount$1(500 * 1024 * 1024), unsafeAsPositiveByteCount$1(5 * 1024 * 1024), unsafeAsPositiveByteCount$1(50 * 1024 * 1024), unsafeAsPositiveByteCount$1(5 * 1024 * 1024), unsafeAsPositiveByteCount$1(10 * 1024 * 1024), unsafeAsPositiveByteCount$1(100 * 1024 * 1024), unsafeAsPositiveByteCount$1(100 * 1024 * 1024), unsafeAsPositiveByteCount$1(25 * 1024 * 1024);
2489
2693
  unsafeAsPositiveByteCount$1(250 * 1024 * 1024);
2490
2694
  unsafeAsPositiveSeconds(300);
2695
+ })), STORAGE_OBJECT_CHARACTER;
2696
+ var init_storageObjectKey = __esmMin((() => {
2697
+ STORAGE_OBJECT_CHARACTER = "A-Za-z0-9_!.*'() &$=@;:+,-";
2698
+ new RegExp(`[^${STORAGE_OBJECT_CHARACTER}]+`, "gu");
2699
+ new RegExp(`^[/${STORAGE_OBJECT_CHARACTER}]+$`, "u");
2491
2700
  })), FILE_STORAGE_BUCKETS, PRIVATE_SITE_FILE_BUCKET_MIME_TYPES;
2492
2701
  var init_fileStorage = __esmMin((() => {
2493
2702
  init_src$4();
@@ -2795,6 +3004,7 @@ var init_src$3 = __esmMin((() => {
2795
3004
  init_types$15();
2796
3005
  init_fileDomain();
2797
3006
  init_fileStorage();
3007
+ init_storageObjectKey();
2798
3008
  init_storagePathDomain();
2799
3009
  init_fileSafety();
2800
3010
  init_filePersistence();
@@ -13588,6 +13798,14 @@ var init_booking_payment_schemas = __esmMin((() => {
13588
13798
  bookingPaymentOptionSchemas.paymentCollectionOption;
13589
13799
  bookingPaymentTermsSchema = bookingPaymentOptionSchemas.paymentTerms;
13590
13800
  bookingPaymentOptionSchemas.paymentOptionsChoice;
13801
+ z.strictObject({
13802
+ currency: z.string().trim().length(3),
13803
+ totalCents: nonNegativeIntegerSchema,
13804
+ dueNowCents: nonNegativeIntegerSchema,
13805
+ laterPaymentAmountsCents: z.array(nonNegativeIntegerSchema),
13806
+ paymentOption: z.union([createBookingPaymentOptionSchemas("strict").paymentCollectionOption, z.strictObject({ kind: z.literal("not_required") })]),
13807
+ promisedDiscountId: z.string().min(1).nullable().optional()
13808
+ });
13591
13809
  }));
13592
13810
  //#endregion
13593
13811
  //#region ../blocks/src/system/blocks/shared/bookingPaymentTerms.ts
@@ -13825,6 +14043,10 @@ var init_schemas = __esmMin((() => {
13825
14043
  eventDestinationMode: eventDestinationModeSchema.optional(),
13826
14044
  scheduleScope: eventScheduleScopeSchema$2.optional(),
13827
14045
  recurrence: publicEventRecurrenceSchema.optional(),
14046
+ scheduleSummary: z.object({
14047
+ recurrenceDescription: z.string(),
14048
+ startTime: z.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/).nullable()
14049
+ }).nullable().optional(),
13828
14050
  id: z.string(),
13829
14051
  occurrenceId: z.string(),
13830
14052
  seriesId: z.string(),
@@ -17416,47 +17638,47 @@ var init_backgroundGeneration = __esmMin((() => {}));
17416
17638
  //#endregion
17417
17639
  //#region ../theme-core/src/palette/recipes/analogous-harmony.ts
17418
17640
  var init_analogous_harmony = __esmMin((() => {
17419
- init_utils$3();
17641
+ init_utils$4();
17420
17642
  }));
17421
17643
  //#endregion
17422
17644
  //#region ../theme-core/src/palette/recipes/complementary-contrast.ts
17423
17645
  var init_complementary_contrast = __esmMin((() => {
17424
- init_utils$3();
17646
+ init_utils$4();
17425
17647
  }));
17426
17648
  //#endregion
17427
17649
  //#region ../theme-core/src/palette/recipes/high-contrast-modern.ts
17428
17650
  var init_high_contrast_modern = __esmMin((() => {
17429
- init_utils$3();
17651
+ init_utils$4();
17430
17652
  }));
17431
17653
  //#endregion
17432
17654
  //#region ../theme-core/src/palette/recipes/minimal-monochrome.ts
17433
17655
  var init_minimal_monochrome = __esmMin((() => {
17434
- init_utils$3();
17656
+ init_utils$4();
17435
17657
  }));
17436
17658
  //#endregion
17437
17659
  //#region ../theme-core/src/palette/recipes/neon-pop.ts
17438
17660
  var init_neon_pop = __esmMin((() => {
17439
- init_utils$3();
17661
+ init_utils$4();
17440
17662
  }));
17441
17663
  //#endregion
17442
17664
  //#region ../theme-core/src/palette/recipes/pastel-light.ts
17443
17665
  var init_pastel_light = __esmMin((() => {
17444
- init_utils$3();
17666
+ init_utils$4();
17445
17667
  }));
17446
17668
  //#endregion
17447
17669
  //#region ../theme-core/src/palette/recipes/split-complementary.ts
17448
17670
  var init_split_complementary = __esmMin((() => {
17449
- init_utils$3();
17671
+ init_utils$4();
17450
17672
  }));
17451
17673
  //#endregion
17452
17674
  //#region ../theme-core/src/palette/recipes/tetradic.ts
17453
17675
  var init_tetradic = __esmMin((() => {
17454
- init_utils$3();
17676
+ init_utils$4();
17455
17677
  }));
17456
17678
  //#endregion
17457
17679
  //#region ../theme-core/src/palette/recipes/triadic-balance.ts
17458
17680
  var init_triadic_balance = __esmMin((() => {
17459
- init_utils$3();
17681
+ init_utils$4();
17460
17682
  }));
17461
17683
  //#endregion
17462
17684
  //#region ../theme-core/src/palette/recipes/allRecipes.ts
@@ -17492,7 +17714,7 @@ var init_scrimContrast = __esmMin((() => {
17492
17714
  }));
17493
17715
  //#endregion
17494
17716
  //#region ../theme-core/src/palette/utils/index.ts
17495
- var init_utils$3 = __esmMin((() => {
17717
+ var init_utils$4 = __esmMin((() => {
17496
17718
  init_colorConversion();
17497
17719
  init_contrast();
17498
17720
  init_colorPlacement();
@@ -17514,7 +17736,7 @@ var init_swatch = __esmMin((() => {}));
17514
17736
  //#endregion
17515
17737
  //#region ../theme-core/src/mock-themes/components/PaletteCard.tsx
17516
17738
  var init_PaletteCard = __esmMin((() => {
17517
- init_utils$3();
17739
+ init_utils$4();
17518
17740
  init_swatch();
17519
17741
  }));
17520
17742
  //#endregion
@@ -17745,7 +17967,7 @@ function assignDeep(target, ...sources) {
17745
17967
  });
17746
17968
  return target;
17747
17969
  }
17748
- var init_utils$2 = __esmMin((() => {}));
17970
+ var init_utils$3 = __esmMin((() => {}));
17749
17971
  //#endregion
17750
17972
  //#region ../../node_modules/.pnpm/@vibrant+core@4.0.4/node_modules/@vibrant/core/dist/esm/options.js
17751
17973
  function buildProcessOptions(opts, override) {
@@ -17763,13 +17985,13 @@ function buildProcessOptions(opts, override) {
17763
17985
  }, override);
17764
17986
  }
17765
17987
  var init_options = __esmMin((() => {
17766
- init_utils$2();
17988
+ init_utils$3();
17767
17989
  }));
17768
17990
  //#endregion
17769
17991
  //#region ../../node_modules/.pnpm/@vibrant+core@4.0.4/node_modules/@vibrant/core/dist/esm/builder.js
17770
17992
  var Builder;
17771
17993
  var init_builder$2 = __esmMin((() => {
17772
- init_utils$2();
17994
+ init_utils$3();
17773
17995
  init_esm$2();
17774
17996
  Builder = class {
17775
17997
  /**
@@ -18128,7 +18350,7 @@ var _Vibrant, Vibrant;
18128
18350
  var init_esm$2 = __esmMin((() => {
18129
18351
  init_options();
18130
18352
  init_builder$2();
18131
- init_utils$2();
18353
+ init_utils$3();
18132
18354
  init_pipeline$1();
18133
18355
  _Vibrant = class _Vibrant {
18134
18356
  /**
@@ -18645,7 +18867,7 @@ var init_concretePalette = __esmMin((() => {
18645
18867
  //#endregion
18646
18868
  //#region ../theme-core/src/palette/utils/fromVibrant.ts
18647
18869
  var init_fromVibrant = __esmMin((() => {
18648
- init_utils$3();
18870
+ init_utils$4();
18649
18871
  }));
18650
18872
  //#endregion
18651
18873
  //#region ../theme-core/src/site-styles/styleTags.ts
@@ -20829,7 +21051,7 @@ var init_palette = __esmMin((() => {
20829
21051
  init_generateShades();
20830
21052
  init_neutralScale();
20831
21053
  init_types$6();
20832
- init_utils$3();
21054
+ init_utils$4();
20833
21055
  init_paletteAccess();
20834
21056
  init_extractPalette();
20835
21057
  init_colors();
@@ -24377,13 +24599,13 @@ function gradientToCss(config, tokens) {
24377
24599
  }
24378
24600
  return `linear-gradient(${config.angle ?? 180}deg, ${stops})`;
24379
24601
  }
24380
- var init_utils$1 = __esmMin((() => {}));
24602
+ var init_utils$2 = __esmMin((() => {}));
24381
24603
  //#endregion
24382
24604
  //#region ../theme-core/src/gradients/index.ts
24383
24605
  var init_gradients = __esmMin((() => {
24384
24606
  init_types$8();
24385
24607
  init_presets$2();
24386
- init_utils$1();
24608
+ init_utils$2();
24387
24609
  }));
24388
24610
  //#endregion
24389
24611
  //#region ../theme-core/src/site-styles/sectionSurfaceBackgrounds.ts
@@ -27537,62 +27759,52 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="event-registratio
27537
27759
  --er-control-bg: rgb(var(--tb-background, var(--tb-surface)));
27538
27760
  --er-control-text: rgb(var(--tb-foreground, var(--tb-text)));
27539
27761
  --er-radius: var(--rb-block-radius);
27540
- --er-surface-muted: rgba(var(--tb-muted, 241 245 249), 0.42);
27541
- --er-shell-line: rgba(var(--tb-mutedText, 100 116 139), 0.22);
27762
+ --er-surface-muted: rgb(var(--tb-muted, 241 245 249) / 0.42);
27763
+ --er-shell-line: rgb(var(--tb-mutedText, 100 116 139) / 0.22);
27542
27764
 
27543
27765
  /* Step indicator */
27544
27766
  --er-step-active: rgb(var(--tb-primary));
27545
- --er-step-inactive: rgb(var(--tb-mutedText));
27546
- --er-step-completed: rgb(var(--tb-success));
27547
- --er-step-text: rgb(255 255 255);
27548
- --er-step-text-active: rgb(var(--tb-onPrimary, 255 255 255));
27549
- --er-step-connector: rgba(var(--tb-border), 0.5);
27550
27767
 
27551
27768
  /* Step title */
27552
- --er-step-title-size: 1.5rem;
27769
+ --er-step-title-size: 1.75rem;
27553
27770
 
27554
27771
  /* State backgrounds with alpha */
27555
- --er-success-bg: rgba(var(--tb-success), 0.1);
27556
- --er-success-text: rgb(var(--tb-success));
27557
- --er-info-bg: rgba(var(--tb-primary), 0.1);
27772
+ --er-info-bg: rgb(var(--tb-primary) / 0.1);
27558
27773
  --er-info-text: rgb(var(--tb-primary));
27559
- --er-error-bg: rgba(var(--tb-destructive, 239 68 68), 0.1);
27774
+ --er-error-bg: rgb(var(--tb-destructive, 239 68 68) / 0.1);
27560
27775
  --er-error-text: rgb(var(--tb-destructive, 239 68 68));
27561
- --er-waitlist-bg: rgba(var(--tb-warning), 0.1);
27776
+ --er-waitlist-bg: rgb(var(--tb-warning) / 0.1);
27562
27777
  --er-waitlist-text: rgb(var(--tb-warning));
27563
27778
 
27564
27779
  /* Capacity badges */
27565
- --er-capacity-available-bg: rgba(var(--tb-success), 0.1);
27780
+ --er-capacity-available-bg: rgb(var(--tb-success) / 0.1);
27566
27781
  --er-capacity-available-text: rgb(var(--tb-success));
27567
- --er-capacity-low-bg: rgba(var(--tb-warning), 0.1);
27782
+ --er-capacity-low-bg: rgb(var(--tb-warning) / 0.1);
27568
27783
  --er-capacity-low-text: rgb(var(--tb-warning));
27569
- --er-capacity-soldout-bg: rgba(var(--tb-destructive, 239 68 68), 0.1);
27784
+ --er-capacity-soldout-bg: rgb(var(--tb-destructive, 239 68 68) / 0.1);
27570
27785
  --er-capacity-soldout-text: rgb(var(--tb-destructive, 239 68 68));
27571
27786
 
27572
27787
  /* Borders */
27573
27788
  --er-border: rgb(var(--tb-border));
27574
- --er-border-hover: rgba(var(--tb-primary), 0.5);
27789
+ --er-border-hover: rgb(var(--tb-primary) / 0.5);
27575
27790
  --er-border-selected: rgb(var(--tb-primary));
27576
27791
  --er-border-error: rgb(var(--tb-destructive, 239 68 68));
27577
27792
 
27578
27793
  /* Input focus */
27579
- --er-focus-ring: rgba(var(--tb-primary), 0.3);
27580
-
27581
- /* Required marker */
27582
- --er-required: rgb(var(--tb-destructive, 239 68 68));
27794
+ --er-focus-ring: rgb(var(--tb-primary) / 0.3);
27583
27795
 
27584
27796
  /* Payment option cards */
27585
27797
  --er-payment-border: rgb(var(--tb-border));
27586
- --er-payment-border-hover: rgba(var(--tb-primary), 0.5);
27798
+ --er-payment-border-hover: rgb(var(--tb-primary) / 0.5);
27587
27799
  --er-payment-border-selected: rgb(var(--tb-primary));
27588
- --er-payment-bg-selected: rgba(var(--tb-primary), 0.08);
27800
+ --er-payment-bg-selected: rgb(var(--tb-primary) / 0.08);
27589
27801
 
27590
27802
  /* Checkmark indicator */
27591
27803
  --er-check-bg: rgb(var(--tb-primary));
27592
27804
  --er-check-text: rgb(var(--tb-onPrimary, 255 255 255));
27593
27805
 
27594
27806
  /* Order summary */
27595
- --er-summary-bg: rgba(var(--tb-primary), 0.1);
27807
+ --er-summary-bg: rgb(var(--tb-primary) / 0.1);
27596
27808
  --er-summary-border: rgb(var(--tb-border));
27597
27809
 
27598
27810
  /* Shared registration-surface mappings (issue 1174).
@@ -27604,7 +27816,7 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="event-registratio
27604
27816
  --rb-reg-border-selected: var(--er-border-selected);
27605
27817
  --rb-reg-bg-selected: var(--er-payment-bg-selected);
27606
27818
  --rb-reg-option-bg: var(--er-control-bg);
27607
- --rb-reg-option-hover-shadow: 0 8px 18px rgba(var(--tb-shadow, 15 23 42), 0.08);
27819
+ --rb-reg-option-hover-shadow: 0 8px 18px rgb(var(--tb-shadow, 15 23 42) / 0.08);
27608
27820
  --rb-reg-surface-bg: rgb(var(--tb-surface));
27609
27821
  --rb-reg-on-surface: var(--er-on-surface);
27610
27822
  --rb-reg-on-surface-muted: var(--er-on-surface-muted);
@@ -27613,11 +27825,6 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="event-registratio
27613
27825
  --rb-reg-check-bg: var(--er-check-bg);
27614
27826
  --rb-reg-check-text: var(--er-check-text);
27615
27827
  --rb-reg-step-active: var(--er-step-active);
27616
- --rb-reg-step-completed: var(--er-step-completed);
27617
- --rb-reg-step-inactive: var(--er-step-inactive);
27618
- --rb-reg-step-text: var(--er-step-text);
27619
- --rb-reg-step-text-active: var(--er-step-text-active);
27620
- --rb-reg-step-connector: var(--er-step-connector);
27621
27828
  --rb-reg-summary-bg: var(--er-surface-muted);
27622
27829
  --rb-reg-summary-border: var(--er-border);
27623
27830
  --rb-reg-focus-ring: var(--er-focus-ring);
@@ -27666,13 +27873,13 @@ function generateEventCalendarVars({ themeId }) {
27666
27873
  return `
27667
27874
  ${`:where([data-theme-scope="${themeId}"]) :where([data-block="event-calendar"])`} {
27668
27875
  /* Day cell states */
27669
- --ec-today-bg: rgba(var(--tb-primary), 0.05);
27876
+ --ec-today-bg: rgb(var(--tb-primary) / 0.05);
27670
27877
  --ec-today-text: rgb(var(--tb-primary));
27671
27878
  --ec-other-month-opacity: 0.4;
27672
27879
 
27673
27880
  /* Event items - subtle style (legacy) */
27674
- --ec-event-bg: rgba(var(--tb-primary), 0.1);
27675
- --ec-event-hover-bg: rgba(var(--tb-primary), 0.2);
27881
+ --ec-event-bg: rgb(var(--tb-primary) / 0.1);
27882
+ --ec-event-hover-bg: rgb(var(--tb-primary) / 0.2);
27676
27883
 
27677
27884
  /* Event items - solid style (default) */
27678
27885
  --ec-event-solid-bg: rgb(var(--tb-primary));
@@ -27680,15 +27887,15 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="event-calendar"])
27680
27887
  --ec-event-solid-text: rgb(var(--tb-neutral-50, 255 255 255));
27681
27888
 
27682
27889
  /* Navigation */
27683
- --ec-nav-hover-bg: rgba(var(--tb-text), 0.1);
27890
+ --ec-nav-hover-bg: rgb(var(--tb-text) / 0.1);
27684
27891
 
27685
27892
  /* Day headers */
27686
- --ec-header-bg: rgba(var(--tb-text), 0.05);
27893
+ --ec-header-bg: rgb(var(--tb-text) / 0.05);
27687
27894
  --ec-header-opacity: 0.7;
27688
27895
 
27689
27896
  /* Borders */
27690
27897
  --ec-border: rgb(var(--tb-border));
27691
- --ec-border-subtle: rgba(var(--tb-border), 0.5);
27898
+ --ec-border-subtle: rgb(var(--tb-border) / 0.5);
27692
27899
 
27693
27900
  /* Surface and text (for inputs/dropdowns) */
27694
27901
  --ec-surface: rgb(var(--tb-surface));
@@ -27763,29 +27970,27 @@ function generateAppointmentBookingVars({ themeId }) {
27763
27970
  ${`:where([data-theme-scope="${themeId}"]) :where([data-block="appointment-booking"])`} {
27764
27971
  /* Selection cards (service/resource/time) */
27765
27972
  --ab-card-border: rgb(var(--tb-border));
27766
- --ab-card-border-hover: rgba(var(--tb-primary), 0.5);
27973
+ --ab-card-border-hover: rgb(var(--tb-primary) / 0.5);
27767
27974
  --ab-card-border-selected: rgb(var(--tb-primary));
27768
- --ab-card-bg-selected: rgba(var(--tb-primary), 0.05);
27975
+ --ab-card-bg-selected: rgb(var(--tb-primary) / 0.05);
27769
27976
 
27770
27977
  /* Checkmark indicator */
27771
27978
  --ab-check-bg: rgb(var(--tb-primary));
27772
27979
  --ab-check-text: rgb(var(--tb-background));
27773
27980
 
27774
27981
  /* State backgrounds */
27775
- --ab-success-bg: rgba(var(--tb-success), 0.1);
27776
- --ab-success-text: rgb(var(--tb-success));
27777
- --ab-error-bg: rgba(var(--tb-destructive), 0.1);
27982
+ --ab-error-bg: rgb(var(--tb-destructive) / 0.1);
27778
27983
  --ab-error-text: rgb(var(--tb-destructive));
27779
- --ab-warning-bg: rgba(var(--tb-warning), 0.1);
27984
+ --ab-warning-bg: rgb(var(--tb-warning) / 0.1);
27780
27985
  --ab-warning-text: rgb(var(--tb-warning));
27781
- --ab-info-bg: rgba(var(--tb-info), 0.1);
27986
+ --ab-info-bg: rgb(var(--tb-info) / 0.1);
27782
27987
  --ab-info-text: rgb(var(--tb-info));
27783
27988
 
27784
27989
  /* Muted summary state */
27785
- --ab-muted-bg: rgba(var(--tb-text), 0.05);
27990
+ --ab-muted-bg: rgb(var(--tb-text) / 0.05);
27786
27991
 
27787
27992
  /* Focus ring used by shared registration-surface controls */
27788
- --ab-input-focus-ring: rgba(var(--tb-primary), 0.3);
27993
+ --ab-input-focus-ring: rgb(var(--tb-primary) / 0.3);
27789
27994
 
27790
27995
  /* Shared registration-surface mappings (issue 1174).
27791
27996
  Route the shared --rb-reg-* contract through this block's Tier 3 vars
@@ -27797,24 +28002,19 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="appointment-booki
27797
28002
  --rb-reg-border-selected: var(--ab-card-border-selected);
27798
28003
  --rb-reg-bg-selected: var(--ab-card-bg-selected);
27799
28004
  --rb-reg-option-bg: transparent;
27800
- --rb-reg-option-hover-shadow: 0 8px 18px rgba(var(--tb-shadow, 15 23 42), 0.08);
28005
+ --rb-reg-option-hover-shadow: 0 8px 18px rgb(var(--tb-shadow, 15 23 42) / 0.08);
27801
28006
  --rb-reg-surface-bg: rgb(var(--tb-surface));
27802
28007
  --rb-reg-on-surface: rgb(var(--tb-onSurface, var(--tb-text)));
27803
- --rb-reg-on-surface-muted: rgba(var(--tb-onSurface, var(--tb-text)), 0.7);
27804
- --rb-reg-on-surface-subtle: rgba(var(--tb-onSurface, var(--tb-text)), 0.6);
27805
- --rb-reg-on-surface-faint: rgba(var(--tb-onSurface, var(--tb-text)), 0.5);
28008
+ --rb-reg-on-surface-muted: rgb(var(--tb-onSurface, var(--tb-text)) / 0.7);
28009
+ --rb-reg-on-surface-subtle: rgb(var(--tb-onSurface, var(--tb-text)) / 0.6);
28010
+ --rb-reg-on-surface-faint: rgb(var(--tb-onSurface, var(--tb-text)) / 0.5);
27806
28011
  --rb-reg-check-bg: var(--ab-check-bg);
27807
28012
  --rb-reg-check-text: var(--ab-check-text);
27808
28013
  --rb-reg-step-active: rgb(var(--tb-primary));
27809
- --rb-reg-step-completed: rgb(var(--tb-success));
27810
- --rb-reg-step-inactive: rgb(var(--tb-mutedText));
27811
- --rb-reg-step-text: rgb(255 255 255);
27812
- --rb-reg-step-text-active: rgb(var(--tb-onPrimary, 255 255 255));
27813
- --rb-reg-step-connector: rgba(var(--tb-border), 0.5);
27814
28014
  --rb-reg-summary-bg: var(--ab-muted-bg);
27815
28015
  --rb-reg-summary-border: var(--ab-card-border);
27816
28016
  --rb-reg-focus-ring: var(--ab-input-focus-ring);
27817
- --rb-reg-shell-line: rgba(var(--tb-mutedText, 100 116 139), 0.22);
28017
+ --rb-reg-shell-line: rgb(var(--tb-mutedText, 100 116 139) / 0.22);
27818
28018
  }
27819
28019
  `;
27820
28020
  }
@@ -27834,14 +28034,14 @@ function generateFormBlockVars({ themeId }) {
27834
28034
  return `
27835
28035
  ${`:where([data-theme-scope="${themeId}"]) :where([data-block="form"])`} {
27836
28036
  /* Success state */
27837
- --fb-success-bg: rgba(var(--tb-success), 0.1);
28037
+ --fb-success-bg: rgb(var(--tb-success) / 0.1);
27838
28038
  --fb-success-text: rgb(var(--tb-success));
27839
- --fb-success-border: rgba(var(--tb-success), 0.3);
28039
+ --fb-success-border: rgb(var(--tb-success) / 0.3);
27840
28040
 
27841
28041
  /* Error state */
27842
- --fb-error-bg: rgba(var(--tb-destructive), 0.1);
28042
+ --fb-error-bg: rgb(var(--tb-destructive) / 0.1);
27843
28043
  --fb-error-text: rgb(var(--tb-destructive));
27844
- --fb-error-border: rgba(var(--tb-destructive), 0.3);
28044
+ --fb-error-border: rgb(var(--tb-destructive) / 0.3);
27845
28045
 
27846
28046
  /* Empty state */
27847
28047
  --fb-empty-bg: rgb(var(--tb-surface));
@@ -27906,23 +28106,23 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="customer-portal"]
27906
28106
  --rb-tab-opacity: 0.7;
27907
28107
 
27908
28108
  /* Badge - Success (active, confirmed) */
27909
- --cp-badge-success-bg: rgba(var(--tb-success), 0.1);
28109
+ --cp-badge-success-bg: rgb(var(--tb-success) / 0.1);
27910
28110
  --cp-badge-success-text: rgb(var(--tb-success));
27911
28111
 
27912
28112
  /* Badge - Warning (paused, low credits, waitlist) */
27913
- --cp-badge-warning-bg: rgba(var(--tb-warning), 0.1);
28113
+ --cp-badge-warning-bg: rgb(var(--tb-warning) / 0.1);
27914
28114
  --cp-badge-warning-text: rgb(var(--tb-warning));
27915
28115
 
27916
28116
  /* Badge - Error (canceled, expired, past_due) */
27917
- --cp-badge-error-bg: rgba(var(--tb-destructive), 0.1);
28117
+ --cp-badge-error-bg: rgb(var(--tb-destructive) / 0.1);
27918
28118
  --cp-badge-error-text: rgb(var(--tb-destructive));
27919
28119
 
27920
28120
  /* Badge - Info (trialing, scheduled) */
27921
- --cp-badge-info-bg: rgba(var(--tb-primary), 0.1);
28121
+ --cp-badge-info-bg: rgb(var(--tb-primary) / 0.1);
27922
28122
  --cp-badge-info-text: rgb(var(--tb-primary));
27923
28123
 
27924
28124
  /* Badge - Default (neutral states) */
27925
- --cp-badge-default-bg: rgba(var(--tb-mutedText), 0.1);
28125
+ --cp-badge-default-bg: rgb(var(--tb-mutedText) / 0.1);
27926
28126
  --cp-badge-default-text: rgb(var(--tb-mutedText));
27927
28127
 
27928
28128
  /* Progress bar (for credit display) */
@@ -27934,10 +28134,10 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="customer-portal"]
27934
28134
  --cp-card-border: rgb(var(--tb-border));
27935
28135
 
27936
28136
  /* Alert/notification */
27937
- --cp-alert-success-bg: rgba(var(--tb-success), 0.1);
28137
+ --cp-alert-success-bg: rgb(var(--tb-success) / 0.1);
27938
28138
  --cp-alert-success-text: rgb(var(--tb-success));
27939
28139
  --cp-alert-success-border: rgb(var(--tb-success));
27940
- --cp-alert-error-bg: rgba(var(--tb-destructive), 0.1);
28140
+ --cp-alert-error-bg: rgb(var(--tb-destructive) / 0.1);
27941
28141
  --cp-alert-error-text: rgb(var(--tb-destructive));
27942
28142
  --cp-alert-error-border: rgb(var(--tb-destructive));
27943
28143
 
@@ -28031,7 +28231,7 @@ ${root} {
28031
28231
  --rb-testimonial-carousel-arrow-bg: rgb(var(--tb-secondary));
28032
28232
  --rb-testimonial-carousel-arrow-bg-hover: color-mix(in oklab, rgb(var(--tb-secondary)), rgb(var(--tb-text)) 14%);
28033
28233
  --rb-testimonial-carousel-arrow-color: rgb(var(--tb-onSecondary));
28034
- --rb-testimonial-carousel-arrow-border-color: rgba(var(--tb-onSecondary), 0.22);
28234
+ --rb-testimonial-carousel-arrow-border-color: rgb(var(--tb-onSecondary) / 0.22);
28035
28235
  --rb-testimonial-carousel-arrow-size: 2.75rem;
28036
28236
  --rb-testimonial-carousel-arrow-icon-size: 1.25rem;
28037
28237
  --rb-testimonial-carousel-arrow-icon-stroke-width: 2.5;
@@ -38708,6 +38908,18 @@ var init_form = __esmMin((() => {
38708
38908
  };
38709
38909
  }));
38710
38910
  //#endregion
38911
+ //#region ../blocks/src/system/helpers/normalizeMailingListBlockContent.ts
38912
+ /** Fill the declared default without admitting or rewriting invalid custom settings. */
38913
+ function normalizeMailingListBlockContent(record) {
38914
+ return record.targeting == null ? {
38915
+ ...record,
38916
+ targeting: DEFAULT_MAILING_LIST_TARGETING
38917
+ } : record;
38918
+ }
38919
+ var init_normalizeMailingListBlockContent = __esmMin((() => {
38920
+ init_src$4();
38921
+ }));
38922
+ //#endregion
38711
38923
  //#region ../blocks/src/system/blocks/contact-newsletter.ts
38712
38924
  var contactNewsletterLayout, contactNewsletterManifest, contactNewsletterBlockDefinition;
38713
38925
  var init_contact_newsletter = __esmMin((() => {
@@ -38717,6 +38929,7 @@ var init_contact_newsletter = __esmMin((() => {
38717
38929
  init_defineBlock();
38718
38930
  init_api_bindings();
38719
38931
  init_form();
38932
+ init_normalizeMailingListBlockContent();
38720
38933
  contactNewsletterLayout = styledSection({
38721
38934
  children: sectionContainer([el$1("div", { className: "contact-newsletter-grid" }, [el$1("div", { className: "contact-newsletter-column contact-newsletter-contact" }, [el$1("div", { className: "contact-newsletter-copy" }, [text({
38722
38935
  as: "h2",
@@ -38880,6 +39093,10 @@ var init_contact_newsletter = __esmMin((() => {
38880
39093
  });
38881
39094
  contactNewsletterBlockDefinition = {
38882
39095
  manifest: contactNewsletterManifest,
39096
+ contentNormalizer: {
39097
+ fieldIds: ["targeting"],
39098
+ normalize: normalizeMailingListBlockContent
39099
+ },
38883
39100
  dataSchemas: { form: formDataSchema.optional() },
38884
39101
  dataLoaders: { form: {
38885
39102
  endpoint: "getPublicFormById",
@@ -43433,80 +43650,276 @@ var init_event_registration_shared = __esmMin((() => {
43433
43650
  }).nullable();
43434
43651
  }));
43435
43652
  //#endregion
43436
- //#region ../blocks/src/system/runtime/api/readAuthority.ts
43437
- var browserReadAuthoritySchema;
43438
- var init_readAuthority = __esmMin((() => {
43439
- browserReadAuthoritySchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("published") }).strict(), z.object({
43440
- kind: z.literal("preview"),
43441
- token: z.string().min(1)
43442
- }).strict()]);
43443
- }));
43444
- //#endregion
43445
- //#region ../blocks/src/system/runtime/nodes/event-registration/eventScope.ts
43446
- function resolveEventRegistrationScope(context) {
43447
- const occurrenceSeriesId = context.occurrenceContext?.seriesId;
43448
- if (occurrenceSeriesId) return {
43449
- kind: "occurrenceSeries",
43450
- seriesId: occurrenceSeriesId
43653
+ //#region ../blocks/src/system/runtime/nodes/events/domain/capacity.ts
43654
+ /**
43655
+ * Compute remaining spots for an event from `availableSpots` with a fallback
43656
+ * to `capacity - registeredCount`. Returns `{ available: null, isFull: false }`
43657
+ * for uncapped events so call sites can render no capacity indicator at all.
43658
+ *
43659
+ * The single source of truth for capacity math across event cards, agenda
43660
+ * rows, and timetable cells — keep wording variations in the call sites.
43661
+ */
43662
+ function getEventAvailability(event) {
43663
+ if (event.capacity == null) return {
43664
+ available: null,
43665
+ isFull: false
43451
43666
  };
43452
- if (context.subject?.kind === "eventSeries") return {
43453
- kind: "pageSurfaceSeries",
43454
- seriesId: context.subject.eventSeriesId
43667
+ const available = event.availableSpots ?? event.capacity - event.registeredCount;
43668
+ if (available <= 0) return {
43669
+ available: 0,
43670
+ isFull: true
43455
43671
  };
43456
- if (context.subject?.kind === "eventOffering") return {
43457
- kind: "pageSurfaceOffering",
43458
- offeringId: context.subject.eventOfferingId,
43459
- seriesIds: context.subject.catalogueEventSeriesIds
43672
+ return {
43673
+ available,
43674
+ isFull: false
43460
43675
  };
43461
- if (context.subject?.kind === "unsupported") return {
43462
- kind: "unsupportedPageSurfaceSubject",
43463
- reason: context.subject.reason
43676
+ }
43677
+ /**
43678
+ * Pick the capacity row a booking decision should read: the selected
43679
+ * attendance mode's availability when the visitor has chosen one and the
43680
+ * event publishes it, otherwise the event-level aggregate.
43681
+ *
43682
+ * The mode row is used wholesale. A mode with `capacity: null` on a capped
43683
+ * event is uncapped *by design*: the registration write path applies the
43684
+ * same rule via `getEffectiveOccurrenceCapacityForAttendanceMode`, so falling
43685
+ * back to the event's `availableSpots` here would block bookings the server
43686
+ * accepts. (Waitlist claims are still occurrence-scoped; see issue 1377.)
43687
+ */
43688
+ function selectEventCapacitySource(event, attendanceMode) {
43689
+ if (!attendanceMode) return event;
43690
+ return (event.attendanceModes ?? []).find((mode) => mode.mode === attendanceMode) ?? event;
43691
+ }
43692
+ /**
43693
+ * Whether the visitor's next step is the waitlist: the source is full *and*
43694
+ * a waitlist is open. The one place this is decided — cards, rows, the
43695
+ * wizard's steps and its action bar all route through here so they agree,
43696
+ * including for producers that omit `availableSpots` and rely on the
43697
+ * `capacity - registeredCount` fallback.
43698
+ */
43699
+ function canJoinEventWaitlist(event, options) {
43700
+ const source = selectEventCapacitySource(event, options?.attendanceMode);
43701
+ return getEventAvailability(source).isFull && source.waitlistEnabled === true;
43702
+ }
43703
+ /**
43704
+ * Remaining places at or below which an event reads as scarce and the exact
43705
+ * count is worth showing. Above it, no number is shown at all: "147 places
43706
+ * left" is not something a visitor acts on, and it is the figure most likely
43707
+ * to be stale on a cached page.
43708
+ *
43709
+ * max( min(3, ceil(capacity * 0.25)), ceil(capacity * 0.05) )
43710
+ *
43711
+ * The 25% arm stops small groups shouting early (3 of 4 is not urgency); the
43712
+ * 5% floor stops large events staying silent until three remain.
43713
+ * capacity 4 -> 1, 12 -> 3, 40 -> 3, 100 -> 5, 200 -> 10.
43714
+ */
43715
+ function lowCapacityThreshold(capacity) {
43716
+ return Math.max(Math.min(3, Math.ceil(capacity * .25)), Math.ceil(capacity * .05));
43717
+ }
43718
+ function getRemainingPlaces(source) {
43719
+ const { available, isFull } = getEventAvailability(source);
43720
+ if (available === null || source.capacity === null) return { kind: "unlimited" };
43721
+ if (isFull) return {
43722
+ kind: "full",
43723
+ waitlist: canJoinEventWaitlist(source)
43464
43724
  };
43465
- return { kind: "unscoped" };
43725
+ if (available <= lowCapacityThreshold(source.capacity)) return {
43726
+ kind: "low",
43727
+ remaining: available
43728
+ };
43729
+ return { kind: "open" };
43466
43730
  }
43467
- function resolveEventRegistrationScopedEvents(events, context) {
43468
- const scope = resolveEventRegistrationScope(context);
43469
- switch (scope.kind) {
43470
- case "occurrenceSeries":
43471
- case "pageSurfaceSeries": return events.filter((event) => event.seriesId === scope.seriesId);
43472
- case "pageSurfaceOffering": {
43473
- const seriesIds = new Set(scope.seriesIds);
43474
- return events.filter((event) => seriesIds.has(event.seriesId));
43475
- }
43476
- case "unsupportedPageSurfaceSubject": return [];
43477
- case "unscoped": return [...events];
43731
+ /**
43732
+ * The one place a remaining-places count becomes text. Returns `null` when
43733
+ * nothing should be shown: uncapped events, and capped events above the
43734
+ * scarcity threshold. Surfaces that need their own full-state wording pass
43735
+ * it in rather than re-deriving the count.
43736
+ */
43737
+ function formatRemainingPlaces(source, wording = {}) {
43738
+ const remaining = getRemainingPlaces(source);
43739
+ switch (remaining.kind) {
43740
+ case "unlimited":
43741
+ case "open": return null;
43742
+ case "low": return formatPlacesLeft(remaining.remaining, wording.compact === true);
43743
+ case "full": return remaining.waitlist ? wording.waitlist ?? "Waitlist" : wording.full ?? "Full";
43478
43744
  }
43479
43745
  }
43480
- var unsupportedEventRegistrationPageSurfaceSubjectReasons, unsupportedEventRegistrationPageSurfaceSubjectSchema, eventRegistrationPageSurfaceSubjectSchema;
43481
- var init_eventScope = __esmMin((() => {
43482
- init_src$4();
43483
- unsupportedEventRegistrationPageSurfaceSubjectReasons = [
43484
- "unsupportedSubject",
43485
- "invalidEventSeriesId",
43486
- "invalidEventSeriesBookingScope",
43487
- "invalidEventOfferingId",
43488
- "invalidEventOfferingBookingScope",
43489
- "invalidEventOfferingCatalogue"
43490
- ];
43491
- unsupportedEventRegistrationPageSurfaceSubjectSchema = z.object({
43492
- kind: z.literal("unsupported"),
43493
- reason: z.enum(unsupportedEventRegistrationPageSurfaceSubjectReasons)
43746
+ function formatPlacesLeft(count, compact) {
43747
+ if (compact) return `${count} left`;
43748
+ return count === 1 ? "1 place left" : `${count} places left`;
43749
+ }
43750
+ function formatTicketTypeRemaining(remainingCapacity) {
43751
+ if (remainingCapacity === null || remainingCapacity > 3) return null;
43752
+ if (remainingCapacity <= 0) return "None left for this ticket type";
43753
+ return `${formatPlacesLeft(remainingCapacity, false)} for this ticket type`;
43754
+ }
43755
+ /**
43756
+ * Which capacity figure wins when they disagree.
43757
+ *
43758
+ * For a hybrid event that publishes both attendance-mode rows, **the mode
43759
+ * rows are authoritative and the event-level aggregate is only a summary**.
43760
+ * The registration write path admits or refuses per mode
43761
+ * (`getEffectiveOccurrenceCapacityForAttendanceMode` on the server), so the
43762
+ * aggregate can read full while a mode still has room, and can read open
43763
+ * while the mode the visitor wants is full. Believing the aggregate on a
43764
+ * card is how a "places available" event turns into a dead end at step two.
43765
+ *
43766
+ * Everything else — single-mode events, events that publish no rows, and the
43767
+ * aggregate-only helpers {@link getEventAvailability} /
43768
+ * {@link getRemainingPlaces} that existing callers rely on — keeps reading
43769
+ * the aggregate, unchanged.
43770
+ */
43771
+ function findHybridModeRows(event) {
43772
+ if (event.deliveryMode !== "hybrid") return null;
43773
+ const rows = event.attendanceModes ?? [];
43774
+ const inPerson = rows.find((row) => row.mode === "in_person");
43775
+ const online = rows.find((row) => row.mode === "online");
43776
+ return inPerson && online ? {
43777
+ inPerson,
43778
+ online
43779
+ } : null;
43780
+ }
43781
+ /** Openness rank; higher means more room. A full mode with a waitlist beats one without. */
43782
+ function remainingPlacesRank(remaining) {
43783
+ switch (remaining.kind) {
43784
+ case "unlimited": return 4;
43785
+ case "open": return 3;
43786
+ case "low": return 2;
43787
+ case "full": return remaining.waitlist ? 1 : 0;
43788
+ }
43789
+ }
43790
+ function isMoreOpen(candidate, than) {
43791
+ const rank = remainingPlacesRank(candidate);
43792
+ const otherRank = remainingPlacesRank(than);
43793
+ if (rank !== otherRank) return rank > otherRank;
43794
+ return candidate.kind === "low" && than.kind === "low" ? candidate.remaining > than.remaining : false;
43795
+ }
43796
+ /** True when `candidate` has less room left than `than`. */
43797
+ function isScarcer(candidate, than) {
43798
+ return isMoreOpen(than, candidate);
43799
+ }
43800
+ /**
43801
+ * The browse-surface label for an event's remaining places. Single-mode
43802
+ * events get exactly the aggregate label {@link formatRemainingPlaces}
43803
+ * produces, and so does a hybrid event whose two modes tell the same story.
43804
+ * When the modes differ, both sides are named: "available" on a card is a
43805
+ * promise the registration wizard would otherwise have to break.
43806
+ *
43807
+ * Hybrid examples, in person full with 3 online places left:
43808
+ * default -> "Online: 3 places left · In person: Full"
43809
+ * { full: 'Sold out' } -> "Online: 3 places left · In person: Sold out"
43810
+ * { compact: true } -> "Online: 3 left"
43811
+ */
43812
+ function formatEventRemainingPlaces(event, wording = {}) {
43813
+ const rows = findHybridModeRows(event);
43814
+ if (!rows) return formatRemainingPlaces(event, wording);
43815
+ const inPerson = formatRemainingPlaces(rows.inPerson, wording);
43816
+ const online = formatRemainingPlaces(rows.online, wording);
43817
+ if (inPerson === online) return inPerson;
43818
+ if (wording.compact === true) return formatCompactHybridPlaces(rows, wording);
43819
+ return formatBothHybridSides(rows, {
43820
+ inPerson,
43821
+ online
43494
43822
  });
43495
- eventRegistrationPageSurfaceSubjectSchema = z.unknown().transform((value, ctx) => {
43496
- const unsupported = unsupportedEventRegistrationPageSurfaceSubjectSchema.safeParse(value);
43497
- if (unsupported.success) return unsupported.data;
43498
- const parsed = parseEventPageSurfaceSubject(value);
43499
- if (parsed.ok) return parsed.value;
43500
- ctx.addIssue({
43501
- code: z.ZodIssueCode.custom,
43502
- message: `Invalid event page-surface subject (${parsed.error.kind})`
43503
- });
43504
- return z.NEVER;
43823
+ }
43824
+ /**
43825
+ * Both sides, the one with room first: that is the half a visitor can act on,
43826
+ * and it should not arrive after a full stop's worth of bad news.
43827
+ */
43828
+ function formatBothHybridSides(rows, labels) {
43829
+ return (isMoreOpen(getRemainingPlaces(rows.online), getRemainingPlaces(rows.inPerson)) ? [["online", labels.online], ["in_person", labels.inPerson]] : [["in_person", labels.inPerson], ["online", labels.online]]).map(([mode, label]) => namedModePlaces(mode, label)).join(" · ");
43830
+ }
43831
+ function namedModePlaces(mode, label) {
43832
+ return `${ATTENDANCE_MODE_LABEL[mode]}: ${label ?? PLACES_AVAILABLE}`;
43833
+ }
43834
+ /**
43835
+ * Pills and timetable cells have room for one short phrase, so they name the
43836
+ * single mode that carries news rather than listing both: the scarce side
43837
+ * when there is a count to show, and otherwise the side that has closed —
43838
+ * "In person: Full", never "Online only", which reads as a statement about
43839
+ * how the event is delivered rather than about its remaining places.
43840
+ */
43841
+ function formatCompactHybridPlaces(rows, wording) {
43842
+ const inPerson = getRemainingPlaces(rows.inPerson);
43843
+ const online = getRemainingPlaces(rows.online);
43844
+ if (inPerson.kind === "full" && online.kind === "full") return formatRemainingPlaces(inPerson.waitlist ? rows.inPerson : rows.online, wording);
43845
+ if (inPerson.kind === "full" || online.kind === "full") {
43846
+ const fullSide = inPerson.kind === "full" ? "in_person" : "online";
43847
+ const openSide = inPerson.kind === "full" ? "online" : "in_person";
43848
+ const openLabel = formatRemainingPlaces(rowFor(rows, openSide), wording);
43849
+ return openLabel !== null ? namedModePlaces(openSide, openLabel) : namedModePlaces(fullSide, formatRemainingPlaces(rowFor(rows, fullSide), wording));
43850
+ }
43851
+ const scarcerSide = isScarcer(online, inPerson) ? "online" : "in_person";
43852
+ return namedModePlaces(scarcerSide, formatRemainingPlaces(rowFor(rows, scarcerSide), wording));
43853
+ }
43854
+ function rowFor(rows, mode) {
43855
+ return mode === "online" ? rows.online : rows.inPerson;
43856
+ }
43857
+ var ATTENDANCE_MODE_LABEL, PLACES_AVAILABLE;
43858
+ var init_capacity = __esmMin((() => {
43859
+ ATTENDANCE_MODE_LABEL = {
43860
+ in_person: "In person",
43861
+ online: "Online"
43862
+ };
43863
+ PLACES_AVAILABLE = "Places available";
43864
+ }));
43865
+ //#endregion
43866
+ //#region ../blocks/src/system/runtime/nodes/event-registration/registrationDisplay.ts
43867
+ function resolveRegistrationDisplay(source) {
43868
+ return {
43869
+ venue: source.showVenue === false ? "hidden" : "shown",
43870
+ placesLeft: source.showCapacity === false ? "hidden" : "shown"
43871
+ };
43872
+ }
43873
+ /** Venue stays in domain data; views receive only the permitted presentation. */
43874
+ function shownVenue(event, display) {
43875
+ return display.venue === "shown" ? event.venue?.name ?? null : null;
43876
+ }
43877
+ /** Full/waitlist explanations remain visible even when optional counts are hidden. */
43878
+ function placesLeftLabel(source, display, wording = {}) {
43879
+ if ("kind" in source) return ticketPlacesLabel(source.remaining, display);
43880
+ if (source.deliveryMode === "hybrid" && source.attendanceModes?.length) return hybridPlacesLabel(source, display, wording);
43881
+ return capacityPlacesLabel(source, display, wording);
43882
+ }
43883
+ function capacityPlacesLabel(source, display, wording) {
43884
+ const remaining = getRemainingPlaces(source);
43885
+ if (display.placesLeft === "hidden" && remaining.kind !== "full") return null;
43886
+ switch (remaining.kind) {
43887
+ case "full": return formatRemainingPlaces(source, wording);
43888
+ case "low": return formatRemainingPlaces(source, wording);
43889
+ case "unlimited": return wording.unlimited ?? null;
43890
+ case "open": return wording.open ?? null;
43891
+ default: return assertNever$4(remaining);
43892
+ }
43893
+ }
43894
+ function hybridPlacesLabel(event, display, wording) {
43895
+ if (display.placesLeft === "shown") return formatEventRemainingPlaces(event, wording);
43896
+ return (event.attendanceModes ?? []).flatMap((mode) => {
43897
+ const label = placesLeftLabel(mode, display, wording);
43898
+ return label ? [`${mode.mode === "online" ? "Online" : "In person"}: ${label}`] : [];
43899
+ }).join(" · ") || null;
43900
+ }
43901
+ function ticketPlacesLabel(remaining, display) {
43902
+ if (remaining !== null && remaining > 0 && display.placesLeft === "hidden") return null;
43903
+ return formatTicketTypeRemaining(remaining);
43904
+ }
43905
+ var registrationDisplaySchema;
43906
+ var init_registrationDisplay = __esmMin((() => {
43907
+ init_src$4();
43908
+ init_capacity();
43909
+ registrationDisplaySchema = z.object({
43910
+ venue: z.enum(["shown", "hidden"]),
43911
+ placesLeft: z.enum(["shown", "hidden"])
43505
43912
  });
43506
43913
  }));
43507
43914
  //#endregion
43508
- //#region ../blocks/src/system/runtime/nodes/events/domain/capacity.ts
43509
- var init_capacity = __esmMin((() => {}));
43915
+ //#region ../blocks/src/system/runtime/api/readAuthority.ts
43916
+ var browserReadAuthoritySchema;
43917
+ var init_readAuthority = __esmMin((() => {
43918
+ browserReadAuthoritySchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("published") }).strict(), z.object({
43919
+ kind: z.literal("preview"),
43920
+ token: z.string().min(1)
43921
+ }).strict()]);
43922
+ }));
43510
43923
  //#endregion
43511
43924
  //#region ../blocks/src/system/runtime/nodes/events/domain/bookability.ts
43512
43925
  var init_bookability = __esmMin((() => {}));
@@ -43535,7 +43948,30 @@ function eventDateLocale(siteTimeZone) {
43535
43948
  if (siteTimeZone === "Pacific/Auckland" || siteTimeZone === "Pacific/Chatham") return "en-NZ";
43536
43949
  return "en-US";
43537
43950
  }
43951
+ function formatEventCompactDateRail(isoTimestamp, options, letterCase = "capitals") {
43952
+ const locale = options?.locale ?? "en-US";
43953
+ const dateTime = toScheduledBookingDateTime({
43954
+ startsAt: isoTimestamp,
43955
+ timeZone: toBookingTimeZone(options?.timeZone ?? "UTC"),
43956
+ locale
43957
+ });
43958
+ const cased = (value) => letterCase === "capitals" ? value.toLocaleUpperCase(locale) : value;
43959
+ const weekday = cased(formatBookingDate(dateTime, { weekday: "short" }));
43960
+ const month = cased(formatBookingDate(dateTime, { month: "short" }).slice(0, 3));
43961
+ return {
43962
+ weekday,
43963
+ day: formatBookingDate(dateTime, { day: "numeric" }),
43964
+ month,
43965
+ label: formatBookingDate(dateTime, {
43966
+ weekday: "long",
43967
+ year: "numeric",
43968
+ month: "long",
43969
+ day: "numeric"
43970
+ })
43971
+ };
43972
+ }
43538
43973
  var init_dates = __esmMin((() => {
43974
+ init_src$4();
43539
43975
  init_src$5();
43540
43976
  }));
43541
43977
  //#endregion
@@ -43568,7 +44004,16 @@ var init_location = __esmMin((() => {}));
43568
44004
  var init_people = __esmMin((() => {}));
43569
44005
  //#endregion
43570
44006
  //#region ../blocks/src/system/runtime/nodes/events/domain/pricing.ts
43571
- var init_pricing = __esmMin((() => {}));
44007
+ /**
44008
+ * Format an event's price directly from its pricing value (without the full
44009
+ * event). Same output as {@link formatEventPrice}.
44010
+ */
44011
+ function formatEventPriceDisplay(pricing) {
44012
+ return formatEventPricing(pricing, { decimals: "auto" });
44013
+ }
44014
+ var init_pricing = __esmMin((() => {
44015
+ init_src$4();
44016
+ }));
43572
44017
  //#endregion
43573
44018
  //#region ../blocks/src/system/runtime/nodes/events/domain/quickDates.ts
43574
44019
  var init_quickDates = __esmMin((() => {}));
@@ -43631,58 +44076,6 @@ var init_domain = __esmMin((() => {
43631
44076
  init_listWeek();
43632
44077
  }));
43633
44078
  //#endregion
43634
- //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
43635
- var previewStageSchema, registrationButtonVariantSchema, eventButtonVariantSchema, eventLayoutSchema, eventCalendarDisplayModeSchema, eventCalendarDefaultViewSchema, columnOptionSchema, weekStartSchema, filterAutoShowSchema, calendarTabViewsSchema;
43636
- var init_contract_schemas = __esmMin((() => {
43637
- init_events$1();
43638
- init_buttonRoles();
43639
- previewStageSchema = z.enum(["preview", "published"]);
43640
- registrationButtonVariantSchema = blockButtonRoleSchema;
43641
- eventButtonVariantSchema = blockButtonRoleSchema;
43642
- eventLayoutSchema = z.enum(eventCalendarListLayoutValues);
43643
- eventCalendarDisplayModeSchema = z.enum(eventCalendarDisplayModeValues);
43644
- eventCalendarDefaultViewSchema = z.enum(eventCalendarDefaultViewValues);
43645
- columnOptionSchema = z.enum([
43646
- "2",
43647
- "3",
43648
- "4"
43649
- ]);
43650
- weekStartSchema = z.enum(["sunday", "monday"]);
43651
- filterAutoShowSchema = z.enum([
43652
- "auto",
43653
- "always",
43654
- "never"
43655
- ]);
43656
- calendarTabViewsSchema = z.enum([
43657
- "both",
43658
- "month",
43659
- "week"
43660
- ]);
43661
- }));
43662
- //#endregion
43663
- //#region ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
43664
- /**
43665
- * Determine which wizard steps to show based on context and payment requirements.
43666
- *
43667
- * @param hasPreSelectedContext - Whether event is pre-selected (skips event selection)
43668
- * @param needsPaymentStep - Whether user must complete payment method selection
43669
- * @returns Array of wizard steps to display
43670
- */
43671
- function getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep, paymentActive = false) {
43672
- const baseSteps = hasPreSelectedContext ? ["select-tickets", "enter-details"] : [
43673
- "select-event",
43674
- "select-tickets",
43675
- "enter-details"
43676
- ];
43677
- if (!needsPaymentStep) return baseSteps;
43678
- return paymentActive ? [
43679
- ...baseSteps,
43680
- "select-payment",
43681
- "payment"
43682
- ] : [...baseSteps, "select-payment"];
43683
- }
43684
- var init_wizardSteps = __esmMin((() => {}));
43685
- //#endregion
43686
44079
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
43687
44080
  function eventMatchesOccurrenceId(event, occurrenceId) {
43688
44081
  return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
@@ -43709,6 +44102,447 @@ var init_registrationDerivations = __esmMin((() => {
43709
44102
  init_src$4();
43710
44103
  }));
43711
44104
  //#endregion
44105
+ //#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
44106
+ /**
44107
+ * The locale a site's booking dates are written in: the one the site's time
44108
+ * zone places it in (`eventDateLocale`, shared with event cards), or British
44109
+ * English when the site names no zone.
44110
+ */
44111
+ function bookingDateLocale(siteTimeZone) {
44112
+ return siteTimeZone ? eventDateLocale(siteTimeZone) : "en-GB";
44113
+ }
44114
+ function bookingInstant(startsAt, input) {
44115
+ return toScheduledBookingDateTime({
44116
+ startsAt,
44117
+ timeZone: toBookingTimeZone(input.timeZone),
44118
+ locale: bookingDateLocale(input.siteTimeZone)
44119
+ });
44120
+ }
44121
+ /** "7:00pm": a twelve-hour clock with a lowercase, unspaced day period. */
44122
+ function bookingClock(startsAt, input) {
44123
+ return formatBookingTime(bookingInstant(startsAt, input), {
44124
+ hour: "numeric",
44125
+ minute: "2-digit",
44126
+ hour12: true
44127
+ }).replace(/\s*([ap])\.?\s?m\.?$/i, (_match, period) => `${period.toLowerCase()}m`);
44128
+ }
44129
+ /** "7:00pm – 8:15pm", or just the start when there's no distinct end. */
44130
+ function clockRange(input) {
44131
+ const start = bookingClock(input.startsAt, input);
44132
+ const end = input.endsAt ? bookingClock(input.endsAt, input) : null;
44133
+ return end && end !== start ? `${start} – ${end}` : start;
44134
+ }
44135
+ /** A stored local clock has no date or DST offset; UTC preserves its digits. */
44136
+ function formatBookingScheduleSummary(event) {
44137
+ const summary = event.scheduleSummary;
44138
+ if (!summary) return null;
44139
+ const time = summary.startTime ? formatBookingWhen({
44140
+ startsAt: `1970-01-01T${summary.startTime}:00Z`,
44141
+ timeZone: "UTC",
44142
+ siteTimeZone: event.siteTimeZone
44143
+ }, "time") : null;
44144
+ return [summary.recurrenceDescription, time].filter(Boolean).join(" · ");
44145
+ }
44146
+ /** The one booking date formatter; every variant derives from it. */
44147
+ function formatBookingWhen(input, variant) {
44148
+ const instant = bookingInstant(input.startsAt, input);
44149
+ const day = formatBookingDate(instant, {
44150
+ weekday: "short",
44151
+ day: "numeric",
44152
+ month: "short"
44153
+ });
44154
+ switch (variant) {
44155
+ case "day": return day;
44156
+ case "dayLong": return formatBookingDate(instant, {
44157
+ weekday: "long",
44158
+ day: "numeric",
44159
+ month: "long"
44160
+ });
44161
+ case "month": return formatBookingDate(instant, { month: "long" });
44162
+ case "monthYear": return formatBookingDate(instant, {
44163
+ month: "long",
44164
+ year: "numeric"
44165
+ });
44166
+ case "time": return bookingClock(input.startsAt, input);
44167
+ case "timeRange": return clockRange(input);
44168
+ case "short": return `${day}, ${bookingClock(input.startsAt, input)}`;
44169
+ case "long": return `${day} · ${clockRange(input)}`;
44170
+ }
44171
+ }
44172
+ /** A single instant in the short form, e.g. "Mon 5 Oct, 7:00pm". */
44173
+ function formatEventDateTime(isoTimestamp, options) {
44174
+ return formatBookingWhen({
44175
+ startsAt: isoTimestamp,
44176
+ timeZone: options?.timeZone,
44177
+ siteTimeZone: options?.siteTimeZone
44178
+ }, "short");
44179
+ }
44180
+ /** The title an occurrence was given on its own, when it overrides the event's. */
44181
+ function occurrenceTitleOverride(occurrence) {
44182
+ const title = occurrence?.overrides?.title;
44183
+ return typeof title === "string" && title.trim() ? title.trim() : null;
44184
+ }
44185
+ /** The event as this page names it: an occurrence's own title wins. */
44186
+ function withOccurrenceTitle(event, occurrence) {
44187
+ const title = occurrenceTitleOverride(occurrence);
44188
+ return event && title ? {
44189
+ ...event,
44190
+ title
44191
+ } : event;
44192
+ }
44193
+ function courseSchedule(sessions, siteTimeZone) {
44194
+ const first = sessions[0];
44195
+ if (!first) return null;
44196
+ const last = sessions[sessions.length - 1] ?? first;
44197
+ const firstLabel = formatEventDateTime(first.startsAt, {
44198
+ timeZone: first.timeZone,
44199
+ siteTimeZone
44200
+ });
44201
+ if (last.startsAt === first.startsAt) return `${sessions.length} session${sessions.length === 1 ? "" : "s"} · ${firstLabel}`;
44202
+ const lastLabel = formatEventDateTime(last.startsAt, {
44203
+ timeZone: last.timeZone,
44204
+ siteTimeZone
44205
+ });
44206
+ return `${sessions.length} sessions · ${firstLabel} – ${lastLabel}`;
44207
+ }
44208
+ /**
44209
+ * When a booking happens, in one line: the occurrence's date and time, or a
44210
+ * course's session count and first and last dates. `short` by default (bar,
44211
+ * confirmation); `long` adds the end time (card, panel header).
44212
+ */
44213
+ function formatRegistrationSchedule(event, occurrence, variant = "short") {
44214
+ if (event.registrationSubject.kind === "wholeSeries") return courseSchedule(event.registrationSubject.sessions, event.siteTimeZone);
44215
+ const input = scheduleInput(event, occurrence ?? null);
44216
+ return input ? formatBookingWhen(input, variant) : null;
44217
+ }
44218
+ /** The occurrence's own times when the page names one, otherwise the event's. */
44219
+ function scheduleInput(event, occurrence) {
44220
+ const times = occurrence?.startsAt ? {
44221
+ startsAt: occurrence.startsAt,
44222
+ endsAt: occurrence.endsAt ?? null
44223
+ } : {
44224
+ startsAt: event.startsAt,
44225
+ endsAt: event.endsAt
44226
+ };
44227
+ if (!times.startsAt) return null;
44228
+ return {
44229
+ ...times,
44230
+ timeZone: occurrence?.timeZone ?? event.timeZone ?? null,
44231
+ siteTimeZone: event.siteTimeZone
44232
+ };
44233
+ }
44234
+ var init_utils$1 = __esmMin((() => {
44235
+ init_src$4();
44236
+ init_dates();
44237
+ }));
44238
+ //#endregion
44239
+ //#region ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
44240
+ function registrationRoute(input) {
44241
+ const base = input.chooseEvent ? [
44242
+ "select-event",
44243
+ "select-tickets",
44244
+ "enter-details"
44245
+ ] : ["select-tickets", "enter-details"];
44246
+ switch (input.payment) {
44247
+ case "none": return base;
44248
+ case "options": return [...base, "select-payment"];
44249
+ case "optionsAndPayment": return [
44250
+ ...base,
44251
+ "select-payment",
44252
+ "payment"
44253
+ ];
44254
+ }
44255
+ }
44256
+ /** Several dates of one series are a date choice; anything else is an event choice. */
44257
+ function getEventSelectionMode(events) {
44258
+ const firstSeriesId = events[0]?.seriesId;
44259
+ return events.length > 1 && firstSeriesId && events.every((event) => event.seriesId === firstSeriesId) ? "date" : "event";
44260
+ }
44261
+ /** The label facts for a surface: what the visitor chooses from, and what they book. */
44262
+ function registrationStepLabelContext(scopedEvents, bookedEvent) {
44263
+ return {
44264
+ eventSelection: getEventSelectionMode(scopedEvents),
44265
+ booksWholeSeries: bookedEvent?.registrationSubject.kind === "wholeSeries"
44266
+ };
44267
+ }
44268
+ /** One label owner for the live progress and the server placeholder. */
44269
+ function registrationStepLabel(step, context) {
44270
+ switch (step) {
44271
+ case "select-event": return context.eventSelection === "date" ? "Date" : "Event";
44272
+ case "select-tickets": return context.booksWholeSeries ? "Places" : "Tickets";
44273
+ case "enter-details": return "Your details";
44274
+ case "select-payment": return "How you’ll pay";
44275
+ case "payment": return "Payment";
44276
+ }
44277
+ }
44278
+ var REGISTRATION_STEP_LABELS;
44279
+ var init_wizardSteps = __esmMin((() => {
44280
+ REGISTRATION_STEP_LABELS = [
44281
+ "Event",
44282
+ "Date",
44283
+ "Tickets",
44284
+ "Places",
44285
+ "Your details",
44286
+ "How you’ll pay",
44287
+ "Payment"
44288
+ ];
44289
+ }));
44290
+ //#endregion
44291
+ //#region ../blocks/src/system/runtime/nodes/event-registration/bookingEntry.ts
44292
+ function bookingButtonText(buttonText) {
44293
+ return buttonText?.trim() || "Book your place";
44294
+ }
44295
+ function placesLabel(event, input, compact) {
44296
+ return placesLeftLabel(selectEventCapacitySource(event, input.attendanceMode), input.display, { compact });
44297
+ }
44298
+ function isFull(event, mode) {
44299
+ return formatRemainingPlaces(selectEventCapacitySource(event, mode), {
44300
+ full: "full",
44301
+ waitlist: "full"
44302
+ }) === "full";
44303
+ }
44304
+ function priceLabel(event) {
44305
+ return formatEventPriceDisplay(event.pricing).trim() || null;
44306
+ }
44307
+ /** The lowest price a display can mean; null when it names no paid amount. */
44308
+ function lowestPaidAmount(display) {
44309
+ switch (display.kind) {
44310
+ case "exact":
44311
+ case "from": return display.amount;
44312
+ case "range": return display.minAmount;
44313
+ case "mixed": return display.paidFromAmount;
44314
+ case "free":
44315
+ case "unavailable":
44316
+ case "external": return null;
44317
+ }
44318
+ }
44319
+ /**
44320
+ * One price for a set of dates: the shared label when every date costs the
44321
+ * same, otherwise "From" the lowest paid amount, through the one formatter.
44322
+ */
44323
+ function seriesPriceLabel(events) {
44324
+ const firstEvent = events[0];
44325
+ if (!firstEvent) return null;
44326
+ const displays = events.map((event) => publicEventPricingDisplay(event.pricing));
44327
+ const labels = new Set(displays.map((display) => formatBookingPriceDisplay(display, { decimals: "auto" })));
44328
+ if (labels.size === 1) return [...labels][0] || null;
44329
+ const lowest = displays.flatMap((display) => {
44330
+ const amount = lowestPaidAmount(display);
44331
+ return amount === null || !("currency" in display) ? [] : [{
44332
+ amount,
44333
+ currency: display.currency
44334
+ }];
44335
+ }).reduce((best, candidate) => best === null || candidate.amount < best.amount ? candidate : best, null);
44336
+ return lowest ? formatBookingPriceDisplay({
44337
+ kind: "from",
44338
+ amount: lowest.amount,
44339
+ currency: lowest.currency
44340
+ }, { decimals: "auto" }) : priceLabel(firstEvent);
44341
+ }
44342
+ function dateTile(event) {
44343
+ if (event.registrationSubject.kind === "wholeSeries" || !event.startsAt) return null;
44344
+ const rail = formatEventCompactDateRail(event.startsAt, { timeZone: event.timeZone });
44345
+ return {
44346
+ month: rail.month,
44347
+ day: rail.day
44348
+ };
44349
+ }
44350
+ /** "Mon 5 Oct": the compact date the chips and the bar share. */
44351
+ function formatBookingShortDate(event) {
44352
+ return formatBookingWhen(event, "day");
44353
+ }
44354
+ function byStart(left, right) {
44355
+ return Date.parse(left.startsAt) - Date.parse(right.startsAt);
44356
+ }
44357
+ function singleEntry(event, input) {
44358
+ const isCourse = event.registrationSubject.kind === "wholeSeries";
44359
+ return {
44360
+ kind: "single",
44361
+ title: event.title,
44362
+ when: formatRegistrationSchedule(event, null, "long"),
44363
+ shortWhen: formatRegistrationSchedule(event),
44364
+ venue: shownVenue(event, input.display),
44365
+ price: priceLabel(event),
44366
+ places: placesLabel(event, input, false),
44367
+ tile: dateTile(event),
44368
+ action: isCourse ? `Book the ${input.noun.label}` : bookingButtonText(input.buttonText)
44369
+ };
44370
+ }
44371
+ function chooseDateEntry(input) {
44372
+ const ordered = [...input.events].sort(byStart);
44373
+ const first = ordered[0];
44374
+ const shown = ordered.slice(0, 4);
44375
+ return {
44376
+ kind: "chooseDate",
44377
+ title: first?.title ?? "",
44378
+ schedule: (first ? formatBookingScheduleSummary(first) : null) ?? (ordered.length === 1 ? "1 date" : `${ordered.length} dates`),
44379
+ venue: first ? shownVenue(first, input.display) : null,
44380
+ price: seriesPriceLabel(ordered),
44381
+ nextDate: first ? formatBookingShortDate(first) : null,
44382
+ dateCount: ordered.length,
44383
+ dates: shown.map((event) => ({
44384
+ selectionId: event.selectionId,
44385
+ label: formatBookingShortDate(event),
44386
+ places: placesLabel(event, input, true),
44387
+ full: isFull(event, input.attendanceMode)
44388
+ })),
44389
+ moreCount: Math.max(0, ordered.length - shown.length),
44390
+ action: "Choose a date"
44391
+ };
44392
+ }
44393
+ /** The card before a booking starts; the server renders this too. */
44394
+ function idleBookingEntry(input) {
44395
+ if (input.event) return singleEntry(input.event, input);
44396
+ const only = input.events.length === 1 ? input.events[0] : void 0;
44397
+ if (only) return singleEntry(only, input);
44398
+ if (getEventSelectionMode(input.events) === "date") return chooseDateEntry(input);
44399
+ return {
44400
+ kind: "chooseEvent",
44401
+ title: input.events[0]?.title ?? "",
44402
+ count: input.events.length,
44403
+ noun: input.noun.pluralLabel,
44404
+ action: "Choose an event"
44405
+ };
44406
+ }
44407
+ var init_bookingEntry = __esmMin((() => {
44408
+ init_src$4();
44409
+ init_domain();
44410
+ init_registrationDisplay();
44411
+ init_utils$1();
44412
+ init_wizardSteps();
44413
+ }));
44414
+ //#endregion
44415
+ //#region ../blocks/src/system/blocks/offerings-preview/model.ts
44416
+ function isOfferingsPreviewSourceKey(value) {
44417
+ return typeof value === "string" && OFFERINGS_PREVIEW_SOURCE_KEYS.includes(value);
44418
+ }
44419
+ function normalizeOfferingsPreviewGroupOrder(value) {
44420
+ if (value == null) return { kind: "legacy" };
44421
+ if (value.length === 0) return { kind: "default" };
44422
+ const keys = uniqueOfferingsPreviewSourceKeys(value);
44423
+ return keys.length > 0 ? {
44424
+ kind: "custom",
44425
+ keys
44426
+ } : { kind: "default" };
44427
+ }
44428
+ function inferLegacyOfferingsPreviewGroupOrder(overrides) {
44429
+ const keys = uniqueOfferingsPreviewSourceKeys((overrides ?? []).map((override) => override.sourceKey));
44430
+ return keys.length >= 2 ? keys : [];
44431
+ }
44432
+ function normalizeOfferingsPreviewContentForWrite(value) {
44433
+ if (!isRecord$6(value)) return null;
44434
+ const groupOrderValue = value.groupOrder;
44435
+ if (Array.isArray(groupOrderValue)) {
44436
+ const normalized = normalizeOfferingsPreviewGroupOrder(groupOrderValue);
44437
+ return {
44438
+ ...value,
44439
+ groupOrder: normalized.kind === "custom" ? normalized.keys : []
44440
+ };
44441
+ }
44442
+ if (groupOrderValue != null) return {
44443
+ ...value,
44444
+ groupOrder: []
44445
+ };
44446
+ const legacyOrder = inferLegacyOfferingsPreviewGroupOrder(Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord$6) : []);
44447
+ return legacyOrder.length > 0 ? {
44448
+ ...value,
44449
+ groupOrder: legacyOrder
44450
+ } : value;
44451
+ }
44452
+ /** Which offerings a site preset row names; one owner for "the course preset means whole-series runs". */
44453
+ function sourceFromPresetSummary(preset) {
44454
+ if (preset.engine === "event_series" && preset.canonicalBehaviour === "course") return { kind: "wholeSeries" };
44455
+ if (preset.engine !== "event_series") return null;
44456
+ if (isOfferingsPreviewEventPreset(preset.canonicalBehaviour)) return {
44457
+ kind: "eventPreset",
44458
+ preset: preset.canonicalBehaviour
44459
+ };
44460
+ return null;
44461
+ }
44462
+ function uniqueOfferingsPreviewSourceKeys(values) {
44463
+ const keys = [];
44464
+ for (const value of values) {
44465
+ if (!isOfferingsPreviewSourceKey(value)) continue;
44466
+ if (!keys.includes(value)) keys.push(value);
44467
+ }
44468
+ return keys;
44469
+ }
44470
+ function isRecord$6(value) {
44471
+ return typeof value === "object" && value !== null && !Array.isArray(value);
44472
+ }
44473
+ function isOfferingsPreviewEventPreset(value) {
44474
+ return typeof value === "string" && OFFERINGS_PREVIEW_EVENT_PRESETS.includes(value);
44475
+ }
44476
+ var OFFERINGS_PREVIEW_DEFAULT_BUTTON_TEXT, OFFERINGS_PREVIEW_DEFAULT_EMPTY_MESSAGE, OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS, OFFERINGS_PREVIEW_EVENT_PRESETS, OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS, OFFERINGS_PREVIEW_SOURCE_KEYS;
44477
+ var init_model = __esmMin((() => {
44478
+ OFFERINGS_PREVIEW_DEFAULT_BUTTON_TEXT = "Book";
44479
+ OFFERINGS_PREVIEW_DEFAULT_EMPTY_MESSAGE = "Nothing scheduled just yet.";
44480
+ OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS = [
44481
+ {
44482
+ preset: "class",
44483
+ sourceKey: "eventPreset:class",
44484
+ dataKey: "classEvents",
44485
+ label: "Classes"
44486
+ },
44487
+ {
44488
+ preset: "workshop",
44489
+ sourceKey: "eventPreset:workshop",
44490
+ dataKey: "workshopEvents",
44491
+ label: "Workshops"
44492
+ },
44493
+ {
44494
+ preset: "retreat",
44495
+ sourceKey: "eventPreset:retreat",
44496
+ dataKey: "retreatEvents",
44497
+ label: "Retreats"
44498
+ },
44499
+ {
44500
+ preset: "performance",
44501
+ sourceKey: "eventPreset:performance",
44502
+ dataKey: "performanceEvents",
44503
+ label: "Performances"
44504
+ }
44505
+ ];
44506
+ OFFERINGS_PREVIEW_EVENT_PRESETS = OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.preset);
44507
+ OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS = [...OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.sourceKey), "course"];
44508
+ OFFERINGS_PREVIEW_SOURCE_KEYS = OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS;
44509
+ Object.fromEntries(OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.sourceKey, {
44510
+ kind: "eventPreset",
44511
+ preset: definition.preset
44512
+ }]));
44513
+ }));
44514
+ //#endregion
44515
+ //#region ../blocks/src/system/runtime/nodes/event-registration/offeringNoun.ts
44516
+ function offeringKindForEvent(event) {
44517
+ return event.registrationSubject.kind === "wholeSeries" ? "course" : event.eventPreset ?? "event";
44518
+ }
44519
+ function presetKind(preset) {
44520
+ const source = sourceFromPresetSummary(preset);
44521
+ if (!source) return null;
44522
+ return source.kind === "wholeSeries" ? "course" : source.preset;
44523
+ }
44524
+ /**
44525
+ * What the site calls this kind of offering, in lower case for use mid-sentence
44526
+ * ("Book the course", "3 workshops"). Site preset labels win; the canonical
44527
+ * name stands in when the site has none.
44528
+ */
44529
+ function offeringNounForEvent(event, presets) {
44530
+ if (!event) return lowerCased(EVENT_PRESET_VOCABULARY.event);
44531
+ const kind = offeringKindForEvent(event);
44532
+ const preset = presets?.find((candidate) => presetKind(candidate) === kind);
44533
+ return lowerCased(preset?.label.trim() && preset.pluralLabel.trim() ? preset : EVENT_PRESET_VOCABULARY[kind]);
44534
+ }
44535
+ function lowerCased(noun) {
44536
+ return {
44537
+ label: noun.label.trim().toLocaleLowerCase(),
44538
+ pluralLabel: noun.pluralLabel.trim().toLocaleLowerCase()
44539
+ };
44540
+ }
44541
+ var init_offeringNoun = __esmMin((() => {
44542
+ init_src$4();
44543
+ init_model();
44544
+ }));
44545
+ //#endregion
43712
44546
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.ts
43713
44547
  function toRegistrationEvent(event) {
43714
44548
  return {
@@ -43757,6 +44591,201 @@ var init_registrationEventAdapter = __esmMin((() => {
43757
44591
  init_runGrouping();
43758
44592
  }));
43759
44593
  //#endregion
44594
+ //#region ../blocks/src/system/runtime/nodes/event-registration/bookingCardDisplay.ts
44595
+ /**
44596
+ * The booking card the server renders on CMS pages (issue 1581), and the
44597
+ * offering noun it resolves for the wizard. Kept beside the island contract
44598
+ * so the server and the client agree on one card.
44599
+ */
44600
+ function toScopedEventRegistrationEvents(scopedSourceEvents) {
44601
+ return [...toRegistrationEvents(scopedSourceEvents), ...toWholeSeriesRegistrationEvents(scopedSourceEvents)];
44602
+ }
44603
+ function scopedRegistrationEvents(source, scopedSourceEvents) {
44604
+ const scopedEvents = toScopedEventRegistrationEvents(scopedSourceEvents);
44605
+ return {
44606
+ scopedEvents,
44607
+ preSelected: findPreSelectedEvent({
44608
+ scopedEvents,
44609
+ occurrenceContext: source.occurrenceContext
44610
+ })
44611
+ };
44612
+ }
44613
+ function nounFor(scoped, presets) {
44614
+ return offeringNounForEvent(scoped.preSelected ?? scoped.scopedEvents[0] ?? null, presets);
44615
+ }
44616
+ /** What the site calls the offering this block books, from its preset rows. */
44617
+ function resolveOfferingNoun(source, scopedSourceEvents) {
44618
+ return nounFor(scopedRegistrationEvents(source, scopedSourceEvents), source.bookingOfferingPresets);
44619
+ }
44620
+ function idleEntry(source, scopedSourceEvents, display) {
44621
+ const scoped = scopedRegistrationEvents(source, scopedSourceEvents);
44622
+ if (scoped.scopedEvents.length === 0) return null;
44623
+ return idleBookingEntry({
44624
+ events: scoped.scopedEvents,
44625
+ event: withOccurrenceTitle(scoped.preSelected, source.occurrenceContext),
44626
+ display,
44627
+ buttonText: source.buttonText,
44628
+ noun: nounFor(scoped, source.bookingOfferingPresets),
44629
+ attendanceMode: null
44630
+ });
44631
+ }
44632
+ /** The server's card on CMS pages, or null where the shell still applies. */
44633
+ function bookingCardDisplay(source, scopedSourceEvents, display) {
44634
+ if ((source.host ?? "overlay") !== "overlay") return null;
44635
+ const entry = idleEntry(source, scopedSourceEvents, display);
44636
+ if (!entry) return null;
44637
+ return {
44638
+ kind: "event-registration",
44639
+ state: "booking-card",
44640
+ className: source.className ?? null,
44641
+ entry,
44642
+ buttonVariant: source.buttonVariant ?? null,
44643
+ buttonText: source.buttonText?.trim() ?? ""
44644
+ };
44645
+ }
44646
+ var bookingHostSchema, tileSchema, idleBookingEntrySchema;
44647
+ var init_bookingCardDisplay = __esmMin((() => {
44648
+ init_bookingEntry();
44649
+ init_offeringNoun();
44650
+ init_utils$1();
44651
+ init_registrationDerivations();
44652
+ init_registrationEventAdapter();
44653
+ bookingHostSchema = z.enum(["overlay", "inPlace"]);
44654
+ tileSchema = z.object({
44655
+ month: z.string(),
44656
+ day: z.string()
44657
+ }).nullable();
44658
+ idleBookingEntrySchema = z.discriminatedUnion("kind", [
44659
+ z.object({
44660
+ kind: z.literal("single"),
44661
+ title: z.string(),
44662
+ when: z.string().nullable(),
44663
+ shortWhen: z.string().nullable(),
44664
+ venue: z.string().nullable(),
44665
+ price: z.string().nullable(),
44666
+ places: z.string().nullable(),
44667
+ tile: tileSchema,
44668
+ action: z.string()
44669
+ }),
44670
+ z.object({
44671
+ kind: z.literal("chooseDate"),
44672
+ title: z.string(),
44673
+ schedule: z.string(),
44674
+ venue: z.string().nullable(),
44675
+ price: z.string().nullable(),
44676
+ nextDate: z.string().nullable(),
44677
+ dateCount: z.number(),
44678
+ dates: z.array(z.object({
44679
+ selectionId: z.string(),
44680
+ label: z.string(),
44681
+ places: z.string().nullable(),
44682
+ full: z.boolean()
44683
+ })),
44684
+ moreCount: z.number(),
44685
+ action: z.string()
44686
+ }),
44687
+ z.object({
44688
+ kind: z.literal("chooseEvent"),
44689
+ title: z.string(),
44690
+ count: z.number(),
44691
+ noun: z.string(),
44692
+ action: z.string()
44693
+ })
44694
+ ]);
44695
+ }));
44696
+ //#endregion
44697
+ //#region ../blocks/src/system/runtime/nodes/event-registration/eventScope.ts
44698
+ function resolveEventRegistrationScope(context) {
44699
+ const occurrenceSeriesId = context.occurrenceContext?.seriesId;
44700
+ if (occurrenceSeriesId) return {
44701
+ kind: "occurrenceSeries",
44702
+ seriesId: occurrenceSeriesId
44703
+ };
44704
+ if (context.subject?.kind === "eventSeries") return {
44705
+ kind: "pageSurfaceSeries",
44706
+ seriesId: context.subject.eventSeriesId
44707
+ };
44708
+ if (context.subject?.kind === "eventOffering") return {
44709
+ kind: "pageSurfaceOffering",
44710
+ offeringId: context.subject.eventOfferingId,
44711
+ seriesIds: context.subject.catalogueEventSeriesIds
44712
+ };
44713
+ if (context.subject?.kind === "unsupported") return {
44714
+ kind: "unsupportedPageSurfaceSubject",
44715
+ reason: context.subject.reason
44716
+ };
44717
+ return { kind: "unscoped" };
44718
+ }
44719
+ function resolveEventRegistrationScopedEvents(events, context) {
44720
+ const scope = resolveEventRegistrationScope(context);
44721
+ switch (scope.kind) {
44722
+ case "occurrenceSeries":
44723
+ case "pageSurfaceSeries": return events.filter((event) => event.seriesId === scope.seriesId);
44724
+ case "pageSurfaceOffering": {
44725
+ const seriesIds = new Set(scope.seriesIds);
44726
+ return events.filter((event) => seriesIds.has(event.seriesId));
44727
+ }
44728
+ case "unsupportedPageSurfaceSubject": return [];
44729
+ case "unscoped": return [...events];
44730
+ }
44731
+ }
44732
+ var unsupportedEventRegistrationPageSurfaceSubjectReasons, unsupportedEventRegistrationPageSurfaceSubjectSchema, eventRegistrationPageSurfaceSubjectSchema;
44733
+ var init_eventScope = __esmMin((() => {
44734
+ init_src$4();
44735
+ unsupportedEventRegistrationPageSurfaceSubjectReasons = [
44736
+ "unsupportedSubject",
44737
+ "invalidEventSeriesId",
44738
+ "invalidEventSeriesBookingScope",
44739
+ "invalidEventOfferingId",
44740
+ "invalidEventOfferingBookingScope",
44741
+ "invalidEventOfferingCatalogue"
44742
+ ];
44743
+ unsupportedEventRegistrationPageSurfaceSubjectSchema = z.object({
44744
+ kind: z.literal("unsupported"),
44745
+ reason: z.enum(unsupportedEventRegistrationPageSurfaceSubjectReasons)
44746
+ });
44747
+ eventRegistrationPageSurfaceSubjectSchema = z.unknown().transform((value, ctx) => {
44748
+ const unsupported = unsupportedEventRegistrationPageSurfaceSubjectSchema.safeParse(value);
44749
+ if (unsupported.success) return unsupported.data;
44750
+ const parsed = parseEventPageSurfaceSubject(value);
44751
+ if (parsed.ok) return parsed.value;
44752
+ ctx.addIssue({
44753
+ code: z.ZodIssueCode.custom,
44754
+ message: `Invalid event page-surface subject (${parsed.error.kind})`
44755
+ });
44756
+ return z.NEVER;
44757
+ });
44758
+ }));
44759
+ //#endregion
44760
+ //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
44761
+ var previewStageSchema, registrationButtonVariantSchema, eventButtonVariantSchema, eventLayoutSchema, eventCalendarDisplayModeSchema, eventCalendarDefaultViewSchema, columnOptionSchema, weekStartSchema, filterAutoShowSchema, calendarTabViewsSchema;
44762
+ var init_contract_schemas = __esmMin((() => {
44763
+ init_events$1();
44764
+ init_buttonRoles();
44765
+ previewStageSchema = z.enum(["preview", "published"]);
44766
+ registrationButtonVariantSchema = blockButtonRoleSchema;
44767
+ eventButtonVariantSchema = blockButtonRoleSchema;
44768
+ eventLayoutSchema = z.enum(eventCalendarListLayoutValues);
44769
+ eventCalendarDisplayModeSchema = z.enum(eventCalendarDisplayModeValues);
44770
+ eventCalendarDefaultViewSchema = z.enum(eventCalendarDefaultViewValues);
44771
+ columnOptionSchema = z.enum([
44772
+ "2",
44773
+ "3",
44774
+ "4"
44775
+ ]);
44776
+ weekStartSchema = z.enum(["sunday", "monday"]);
44777
+ filterAutoShowSchema = z.enum([
44778
+ "auto",
44779
+ "always",
44780
+ "never"
44781
+ ]);
44782
+ calendarTabViewsSchema = z.enum([
44783
+ "both",
44784
+ "month",
44785
+ "week"
44786
+ ]);
44787
+ }));
44788
+ //#endregion
43760
44789
  //#region ../blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.ts
43761
44790
  function resolveEventRegistrationEventSource(input) {
43762
44791
  if (input.wholeSeriesRunEvents != null) return {
@@ -43801,7 +44830,7 @@ var init_eventSourceRecovery = __esmMin((() => {
43801
44830
  }));
43802
44831
  //#endregion
43803
44832
  //#region ../blocks/src/system/runtime/nodes/event-registration.interactive.ts
43804
- function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents) {
44833
+ function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents, display) {
43805
44834
  const selectedRun = resolveSelectedWholeSeriesRun(scopedSourceEvents);
43806
44835
  if (selectedRun && (!selectedRun.run.enrollmentOpen || toWholeSeriesRegistrationEvent(selectedRun) === null)) return {
43807
44836
  kind: "event-registration",
@@ -43810,6 +44839,8 @@ function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvent
43810
44839
  titleText: "Registration closed",
43811
44840
  bodyText: "This run is no longer open for bookings."
43812
44841
  };
44842
+ const card = bookingCardDisplay(source, scopedSourceEvents, display);
44843
+ if (card) return card;
43813
44844
  const stepLabels = buildEventRegistrationShellStepLabels(source, scopedSourceEvents);
43814
44845
  return {
43815
44846
  kind: "event-registration",
@@ -43826,11 +44857,14 @@ function buildEventRegistrationShellStepLabels(source, scopedSourceEvents) {
43826
44857
  if (selectedRun) {
43827
44858
  const selectedEvent = toWholeSeriesRegistrationEvent(selectedRun);
43828
44859
  if (!selectedEvent) return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
43829
- return getWizardStepsForContext(true, resolveEventRequiresPayment({
43830
- eligibility: null,
43831
- selectedTicketType: null,
43832
- event: selectedEvent
43833
- })).map((step) => shellLabelForRegistrationStep(step, [selectedEvent]));
44860
+ return shellStepLabels(registrationRoute({
44861
+ chooseEvent: false,
44862
+ payment: resolveEventRequiresPayment({
44863
+ eligibility: null,
44864
+ selectedTicketType: null,
44865
+ event: selectedEvent
44866
+ }) ? "optionsAndPayment" : "none"
44867
+ }), registrationStepLabelContext([selectedEvent], selectedEvent));
43834
44868
  }
43835
44869
  const scopedEvents = toScopedEventRegistrationEvents(scopedSourceEvents);
43836
44870
  if (scopedEvents.length === 0) return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
@@ -43839,14 +44873,15 @@ function buildEventRegistrationShellStepLabels(source, scopedSourceEvents) {
43839
44873
  occurrenceContext: source.occurrenceContext
43840
44874
  });
43841
44875
  const hasPreSelectedContext = Boolean(source.occurrenceContext || preSelectedEvent);
43842
- return getWizardStepsForContext(hasPreSelectedContext, hasPreSelectedContext && preSelectedEvent ? resolveEventRequiresPayment({
44876
+ const needsPaymentStep = hasPreSelectedContext && preSelectedEvent ? resolveEventRequiresPayment({
43843
44877
  eligibility: null,
43844
44878
  selectedTicketType: null,
43845
44879
  event: preSelectedEvent
43846
- }) : false).map((step) => shellLabelForRegistrationStep(step, scopedEvents));
43847
- }
43848
- function toScopedEventRegistrationEvents(scopedSourceEvents) {
43849
- return [...toRegistrationEvents(scopedSourceEvents), ...toWholeSeriesRegistrationEvents(scopedSourceEvents)];
44880
+ }) : false;
44881
+ return shellStepLabels(registrationRoute({
44882
+ chooseEvent: !hasPreSelectedContext,
44883
+ payment: needsPaymentStep ? "optionsAndPayment" : "none"
44884
+ }), registrationStepLabelContext(scopedEvents, preSelectedEvent));
43850
44885
  }
43851
44886
  function scopeEventRegistrationSourceEvents(source, eventSource) {
43852
44887
  return resolveEventRegistrationScopedEvents(eventSource.kind === "loaded" ? eventSource.events : [], {
@@ -43862,49 +44897,34 @@ function resolveSelectedWholeSeriesRun(scopedSourceEvents) {
43862
44897
  const runs = groupPublicEventsByRun(scopedSourceEvents);
43863
44898
  return runs.length === 1 ? runs[0] : null;
43864
44899
  }
43865
- function shellLabelForRegistrationStep(step, events) {
43866
- switch (step) {
43867
- case "select-event": return isDateSelection(events) ? "Date" : "Event";
43868
- case "select-tickets": return "Tickets";
43869
- case "enter-details": return "Details";
43870
- case "select-payment": return "Payment options";
43871
- case "payment": return "Payment";
43872
- case "error":
43873
- case "success":
43874
- case "submitting":
43875
- case "verifying-payment":
43876
- case "verifying-timeout":
43877
- case "payment-status":
43878
- case "payment-failed": return "Details";
43879
- }
43880
- }
43881
- function isDateSelection(events) {
43882
- const firstSeriesId = events[0]?.seriesId;
43883
- return Boolean(events.length > 1 && firstSeriesId && events.every((event) => event.seriesId === firstSeriesId));
44900
+ function shellStepLabels(route, context) {
44901
+ return route.map((step) => registrationStepLabel(step, context));
43884
44902
  }
43885
44903
  function buildEventRegistrationShellBodyText(stepLabels) {
43886
- if (stepLabels.includes("Payment options")) return "Preparing tickets, details, and payment options.";
43887
- if (stepLabels[0] === "Tickets") return "Preparing tickets and booking details.";
44904
+ if (stepLabels.includes("How you’ll pay")) return "Preparing tickets, details, and payment options.";
44905
+ if (stepLabels[0] === "Tickets" || stepLabels[0] === "Places") return "Preparing tickets and booking details.";
43888
44906
  return "Preparing dates, tickets, and booking details.";
43889
44907
  }
43890
44908
  function normalizeEventRegistrationEventInput(value) {
43891
- if (!isRecord$6(value)) return value;
44909
+ if (!isRecord$5(value)) return value;
43892
44910
  return {
43893
44911
  ...value,
43894
44912
  destination: resolveRuntimeEventDestination(value)
43895
44913
  };
43896
44914
  }
43897
- function isRecord$6(value) {
44915
+ function isRecord$5(value) {
43898
44916
  return typeof value === "object" && value !== null && !Array.isArray(value);
43899
44917
  }
43900
- var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS, EVENT_REGISTRATION_SHELL_STEP_LABELS, eventRegistrationPublicEventSchema, eventRegistrationHydrationSchemaShape, eventRegistrationEventSourceSchema, eventRegistrationSourceSchema, eventRegistrationDisplaySchema, eventRegistrationHydrationSchema, eventRegistrationRenderSchema, eventRegistrationBlockRuntime;
44918
+ var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS, eventRegistrationPublicEventSchema, eventRegistrationCommonSchemaShape, eventRegistrationEventSourceSchema, eventRegistrationSourceSchema, eventRegistrationDisplaySchema, eventRegistrationHydrationSchema, eventRegistrationRenderSchema, eventRegistrationBlockRuntime;
43901
44919
  var init_event_registration_interactive = __esmMin((() => {
44920
+ init_registrationDisplay();
43902
44921
  init_src$4();
43903
44922
  init_readAuthority();
43904
44923
  init_schemas();
43905
44924
  init_runGrouping();
43906
44925
  init_shop_shared();
43907
44926
  init_event_registration_shared();
44927
+ init_bookingCardDisplay();
43908
44928
  init_eventScope();
43909
44929
  init_domain();
43910
44930
  init_islands();
@@ -43917,27 +44937,17 @@ var init_event_registration_interactive = __esmMin((() => {
43917
44937
  EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = [
43918
44938
  "Date",
43919
44939
  "Tickets",
43920
- "Details"
43921
- ];
43922
- EVENT_REGISTRATION_SHELL_STEP_LABELS = [
43923
- "Event",
43924
- "Date",
43925
- "Tickets",
43926
- "Details",
43927
- "Payment options",
43928
- "Payment"
44940
+ "Your details"
43929
44941
  ];
43930
44942
  eventRegistrationPublicEventSchema = z.preprocess(normalizeEventRegistrationEventInput, publicEventSchema);
43931
- eventRegistrationHydrationSchemaShape = {
44943
+ eventRegistrationCommonSchemaShape = {
43932
44944
  demoEmailSuppressed: z.boolean().optional(),
43933
44945
  occurrenceContext: occurrenceContextSchema.optional(),
43934
44946
  subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
43935
44947
  maxTickets: z.string().optional(),
43936
- showVenue: z.boolean().optional(),
43937
- showCapacity: z.boolean().optional(),
43938
44948
  successMessage: z.string().optional(),
43939
44949
  buttonVariant: registrationButtonVariantSchema.optional(),
43940
- overlayEnabled: z.boolean().optional(),
44950
+ host: bookingHostSchema.optional(),
43941
44951
  spamProtectionEnabled: z.boolean().optional(),
43942
44952
  supportEmail: z.string().optional(),
43943
44953
  sitePasses: publicPassProductCollectionSchema.nullable().optional(),
@@ -43962,32 +44972,51 @@ var init_event_registration_interactive = __esmMin((() => {
43962
44972
  portalToken: z.string().nullable().optional(),
43963
44973
  previewToken: z.string().nullable().optional(),
43964
44974
  readAuthority: browserReadAuthoritySchema.optional(),
43965
- ...eventRegistrationHydrationSchemaShape,
44975
+ ...eventRegistrationCommonSchemaShape,
44976
+ showVenue: z.boolean().optional(),
44977
+ showCapacity: z.boolean().optional(),
43966
44978
  events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
43967
44979
  wholeSeriesRunEvents: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
43968
44980
  eventLoaderFailures: z.record(z.string(), z.unknown()).nullable().optional(),
43969
44981
  className: z.string().nullable().optional(),
43970
44982
  buttonText: z.string().nullable().optional(),
43971
44983
  maxTickets: z.string().nullable().optional(),
43972
- stage: previewStageSchema.optional()
44984
+ stage: previewStageSchema.optional(),
44985
+ bookingOfferingPresets: z.array(z.custom((value) => typeof value === "object" && value !== null && typeof value.label === "string")).nullable().optional()
43973
44986
  });
43974
- eventRegistrationDisplaySchema = z.discriminatedUnion("state", [z.object({
43975
- kind: z.literal("event-registration"),
43976
- state: z.literal("generic-shell"),
43977
- className: z.string().nullable(),
43978
- titleText: z.string(),
43979
- bodyText: z.string(),
43980
- stepLabels: z.array(z.enum(EVENT_REGISTRATION_SHELL_STEP_LABELS)).min(1),
43981
- summaryButtonText: z.string()
43982
- }), z.object({
43983
- kind: z.literal("event-registration"),
43984
- state: z.literal("registration-closed"),
43985
- className: z.string().nullable(),
43986
- titleText: z.string(),
43987
- bodyText: z.string()
43988
- })]);
44987
+ eventRegistrationDisplaySchema = z.discriminatedUnion("state", [
44988
+ z.object({
44989
+ kind: z.literal("event-registration"),
44990
+ state: z.literal("generic-shell"),
44991
+ className: z.string().nullable(),
44992
+ titleText: z.string(),
44993
+ bodyText: z.string(),
44994
+ stepLabels: z.array(z.enum(REGISTRATION_STEP_LABELS)).min(1),
44995
+ summaryButtonText: z.string()
44996
+ }),
44997
+ z.object({
44998
+ kind: z.literal("event-registration"),
44999
+ state: z.literal("registration-closed"),
45000
+ className: z.string().nullable(),
45001
+ titleText: z.string(),
45002
+ bodyText: z.string()
45003
+ }),
45004
+ z.object({
45005
+ kind: z.literal("event-registration"),
45006
+ state: z.literal("booking-card"),
45007
+ className: z.string().nullable(),
45008
+ entry: idleBookingEntrySchema,
45009
+ buttonVariant: registrationButtonVariantSchema.nullable(),
45010
+ buttonText: z.string()
45011
+ })
45012
+ ]);
43989
45013
  eventRegistrationHydrationSchema = z.object({
43990
- ...eventRegistrationHydrationSchemaShape,
45014
+ ...eventRegistrationCommonSchemaShape,
45015
+ display: registrationDisplaySchema,
45016
+ offeringNoun: z.object({
45017
+ label: z.string(),
45018
+ pluralLabel: z.string()
45019
+ }).optional(),
43991
45020
  eventSource: eventRegistrationEventSourceSchema
43992
45021
  });
43993
45022
  eventRegistrationRenderSchema = z.object({
@@ -44009,6 +45038,7 @@ var init_event_registration_interactive = __esmMin((() => {
44009
45038
  render: createZodCodec(eventRegistrationRenderSchema)
44010
45039
  },
44011
45040
  buildRender: (source) => {
45041
+ const display = resolveRegistrationDisplay(source);
44012
45042
  const eventSource = resolveEventRegistrationEventSource({
44013
45043
  events: source.events,
44014
45044
  wholeSeriesRunEvents: source.wholeSeriesRunEvents,
@@ -44016,7 +45046,7 @@ var init_event_registration_interactive = __esmMin((() => {
44016
45046
  });
44017
45047
  const scopedSourceEvents = scopeEventRegistrationSourceEvents(source, eventSource);
44018
45048
  return {
44019
- display: buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents),
45049
+ display: buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents, display),
44020
45050
  hydration: {
44021
45051
  occurrenceContext: source.occurrenceContext ?? null,
44022
45052
  subject: source.subject ?? null,
@@ -44026,17 +45056,17 @@ var init_event_registration_interactive = __esmMin((() => {
44026
45056
  } : eventSource,
44027
45057
  demoEmailSuppressed: source.demoEmailSuppressed,
44028
45058
  maxTickets: source.maxTickets ?? void 0,
44029
- showVenue: source.showVenue,
44030
- showCapacity: source.showCapacity,
45059
+ display,
44031
45060
  successMessage: source.successMessage,
44032
45061
  buttonVariant: source.buttonVariant,
44033
- overlayEnabled: source.overlayEnabled,
45062
+ host: source.host ?? "overlay",
44034
45063
  spamProtectionEnabled: source.spamProtectionEnabled,
44035
45064
  supportEmail: source.supportEmail,
44036
45065
  sitePasses: source.sitePasses ?? null,
44037
45066
  siteMemberships: source.siteMemberships ?? null,
44038
45067
  mailingList: source.mailingList,
44039
- siteName: source.siteName
45068
+ siteName: source.siteName,
45069
+ offeringNoun: resolveOfferingNoun(source, scopedSourceEvents)
44040
45070
  }
44041
45071
  };
44042
45072
  }
@@ -44092,7 +45122,7 @@ var init_event_registration = __esmMin((() => {
44092
45122
  description: "Main heading for the registration form",
44093
45123
  required: false,
44094
45124
  multiline: false,
44095
- defaultValue: "Register for this event"
45125
+ defaultValue: ""
44096
45126
  },
44097
45127
  {
44098
45128
  id: "description",
@@ -44164,11 +45194,11 @@ var init_event_registration = __esmMin((() => {
44164
45194
  {
44165
45195
  id: "buttonText",
44166
45196
  type: "text",
44167
- label: "Submit button text",
44168
- description: "Text for the registration submit button",
45197
+ label: "Button text",
45198
+ description: "Text on the booking button",
44169
45199
  required: false,
44170
45200
  multiline: false,
44171
- defaultValue: "Complete Registration",
45201
+ defaultValue: "Book your place",
44172
45202
  maxLength: 40
44173
45203
  },
44174
45204
  createButtonVariantField()
@@ -44200,21 +45230,21 @@ var init_event_registration = __esmMin((() => {
44200
45230
  successMessage: { $bind: { from: "content.successMessage" } },
44201
45231
  buttonText: { $bind: {
44202
45232
  from: "content.buttonText",
44203
- fallback: "Complete Registration"
45233
+ fallback: "Book your place"
44204
45234
  } },
44205
45235
  buttonVariant: { $bind: {
44206
45236
  from: "content.buttonVariant",
44207
45237
  fallback: "primary"
44208
45238
  } },
44209
- overlayEnabled: { $bind: {
44210
- from: "$root.eventRegistrationOverlayEnabled",
44211
- fallback: false
44212
- } },
44213
45239
  events: { $bind: { from: "data.events" } },
44214
45240
  wholeSeriesRunEvents: { $bind: { from: "data.wholeSeriesRunEvents" } },
44215
45241
  loaderFailures: { $bind: { from: "$root.loaderFailures" } },
44216
45242
  mailingList: { $bind: { from: "$root.mailingList" } },
44217
45243
  siteName: { $bind: { from: "$root.siteName" } },
45244
+ bookingOfferingPresets: { $bind: {
45245
+ from: "$root.bookingOfferingPresets",
45246
+ fallback: []
45247
+ } },
44218
45248
  sitePasses: { $bind: { from: "data.sitePasses" } },
44219
45249
  siteMemberships: { $bind: { from: "data.siteMemberships" } },
44220
45250
  stage: { $bind: {
@@ -46876,7 +47906,21 @@ var init_event_calendar = __esmMin((() => {
46876
47906
  eventCalendarManifest = createBlockManifestWithContentShape(eventCalendarConfig, eventCalendarContentShape);
46877
47907
  eventCalendarBlockDefinition = {
46878
47908
  manifest: eventCalendarManifest,
46879
- normalizeContent: normalizeEventCalendarContent,
47909
+ contentNormalizer: {
47910
+ fieldIds: [
47911
+ "variant",
47912
+ "displayMode",
47913
+ "listLayout",
47914
+ "defaultCalendarView",
47915
+ "eventSurface",
47916
+ "filterEventPresets",
47917
+ "scheduleScope",
47918
+ "filterCategoryIds",
47919
+ "filterStaffMemberId",
47920
+ "filterVenueId"
47921
+ ],
47922
+ normalize: normalizeEventCalendarContent
47923
+ },
46880
47924
  dataSchemas: {
46881
47925
  events: publicEventsArraySchema.optional(),
46882
47926
  calendarWindow: calendarWindowPageSchema.optional()
@@ -47374,93 +48418,6 @@ var init_recurring_schedule = __esmMin((() => {
47374
48418
  };
47375
48419
  }));
47376
48420
  //#endregion
47377
- //#region ../blocks/src/system/blocks/offerings-preview/model.ts
47378
- function isOfferingsPreviewSourceKey(value) {
47379
- return typeof value === "string" && OFFERINGS_PREVIEW_SOURCE_KEYS.includes(value);
47380
- }
47381
- function normalizeOfferingsPreviewGroupOrder(value) {
47382
- if (value == null) return { kind: "legacy" };
47383
- if (value.length === 0) return { kind: "default" };
47384
- const keys = uniqueOfferingsPreviewSourceKeys(value);
47385
- return keys.length > 0 ? {
47386
- kind: "custom",
47387
- keys
47388
- } : { kind: "default" };
47389
- }
47390
- function inferLegacyOfferingsPreviewGroupOrder(overrides) {
47391
- const keys = uniqueOfferingsPreviewSourceKeys((overrides ?? []).map((override) => override.sourceKey));
47392
- return keys.length >= 2 ? keys : [];
47393
- }
47394
- function normalizeOfferingsPreviewContentForWrite(value) {
47395
- if (!isRecord$5(value)) return null;
47396
- const groupOrderValue = value.groupOrder;
47397
- if (Array.isArray(groupOrderValue)) {
47398
- const normalized = normalizeOfferingsPreviewGroupOrder(groupOrderValue);
47399
- return {
47400
- ...value,
47401
- groupOrder: normalized.kind === "custom" ? normalized.keys : []
47402
- };
47403
- }
47404
- if (groupOrderValue != null) return {
47405
- ...value,
47406
- groupOrder: []
47407
- };
47408
- const legacyOrder = inferLegacyOfferingsPreviewGroupOrder(Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord$5) : []);
47409
- return legacyOrder.length > 0 ? {
47410
- ...value,
47411
- groupOrder: legacyOrder
47412
- } : value;
47413
- }
47414
- function uniqueOfferingsPreviewSourceKeys(values) {
47415
- const keys = [];
47416
- for (const value of values) {
47417
- if (!isOfferingsPreviewSourceKey(value)) continue;
47418
- if (!keys.includes(value)) keys.push(value);
47419
- }
47420
- return keys;
47421
- }
47422
- function isRecord$5(value) {
47423
- return typeof value === "object" && value !== null && !Array.isArray(value);
47424
- }
47425
- var OFFERINGS_PREVIEW_DEFAULT_BUTTON_TEXT, OFFERINGS_PREVIEW_DEFAULT_EMPTY_MESSAGE, OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS, OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS, OFFERINGS_PREVIEW_SOURCE_KEYS;
47426
- var init_model = __esmMin((() => {
47427
- OFFERINGS_PREVIEW_DEFAULT_BUTTON_TEXT = "Book";
47428
- OFFERINGS_PREVIEW_DEFAULT_EMPTY_MESSAGE = "Nothing scheduled just yet.";
47429
- OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS = [
47430
- {
47431
- preset: "class",
47432
- sourceKey: "eventPreset:class",
47433
- dataKey: "classEvents",
47434
- label: "Classes"
47435
- },
47436
- {
47437
- preset: "workshop",
47438
- sourceKey: "eventPreset:workshop",
47439
- dataKey: "workshopEvents",
47440
- label: "Workshops"
47441
- },
47442
- {
47443
- preset: "retreat",
47444
- sourceKey: "eventPreset:retreat",
47445
- dataKey: "retreatEvents",
47446
- label: "Retreats"
47447
- },
47448
- {
47449
- preset: "performance",
47450
- sourceKey: "eventPreset:performance",
47451
- dataKey: "performanceEvents",
47452
- label: "Performances"
47453
- }
47454
- ];
47455
- OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.preset);
47456
- OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS = [...OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.sourceKey), "course"];
47457
- OFFERINGS_PREVIEW_SOURCE_KEYS = OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS;
47458
- Object.fromEntries(OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.sourceKey, {
47459
- kind: "eventPreset",
47460
- preset: definition.preset
47461
- }]));
47462
- }));
47463
- //#endregion
47464
48421
  //#region ../blocks/src/system/blocks/offerings-preview/fields.ts
47465
48422
  function labelForOfferingPreviewSourceKey(sourceKey) {
47466
48423
  const eventDefinition = OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.find((definition) => definition.sourceKey === sourceKey);
@@ -47940,7 +48897,22 @@ var init_offerings_preview = __esmMin((() => {
47940
48897
  offeringsPreviewEventDataLoaders = Object.fromEntries(OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.dataKey, eventPresetLoader(definition.preset)]));
47941
48898
  offeringsPreviewBlockDefinition = {
47942
48899
  manifest: offeringsPreviewManifest,
47943
- normalizeContent: normalizeOfferingsPreviewBlockContent,
48900
+ contentNormalizer: {
48901
+ fieldIds: [
48902
+ "displayMode",
48903
+ "heading",
48904
+ "description",
48905
+ "itemLimit",
48906
+ "groupOrder",
48907
+ "groupOverrides",
48908
+ "_cardStyles",
48909
+ "buttonVariant",
48910
+ "buttonText",
48911
+ "emptyMessage",
48912
+ "_sectionStyles"
48913
+ ],
48914
+ normalize: normalizeOfferingsPreviewBlockContent
48915
+ },
47944
48916
  dataSchemas: {
47945
48917
  ...offeringsPreviewEventDataSchemas,
47946
48918
  routeCandidates: publicRouteCandidatesSchema.optional(),
@@ -51479,11 +52451,11 @@ function buildNewsletterDisplay(source) {
51479
52451
  successMessage: DEFAULT_MAILING_LIST_SUCCESS_MESSAGE,
51480
52452
  privacyNote: null
51481
52453
  };
51482
- const targeting = source.targeting ?? { mode: "default" };
51483
- const choices = resolveRuntimeChoices(context, targeting);
52454
+ const assessment = assessMailingListTargeting(context, source.targeting ?? { mode: "default" });
52455
+ const choices = resolveRuntimeChoices(assessment);
51484
52456
  return {
51485
52457
  kind: "newsletter-form",
51486
- availability: runtimeTargetingIsAvailable(context, targeting, choices) ? "ready" : "unavailable",
52458
+ availability: assessment.tag === "available" ? "ready" : "unavailable",
51487
52459
  className: source.className ?? null,
51488
52460
  buttonLabel: form.buttonLabel,
51489
52461
  successMessage: form.successMessage,
@@ -51519,60 +52491,12 @@ function projectNewsletterFormHydrationTarget(source) {
51519
52491
  default: return assertNever$4(source);
51520
52492
  }
51521
52493
  }
51522
- function resolveRuntimeChoices(context, targeting) {
51523
- if (context?.tag !== "configured" || targeting.mode !== "custom" || targeting.selection.tag !== "visitor_choice" || context.provider.provider !== targeting.provider) return [];
51524
- switch (targeting.provider) {
51525
- case "native": {
51526
- const offered = new Set(targeting.selection.offeredTopicIds);
51527
- return context.provider.provider === "native" ? context.provider.topics.filter((item) => offered.has(item.id)).map((item) => ({
51528
- id: item.id,
51529
- label: item.name
51530
- })) : [];
51531
- }
51532
- case "brevo": {
51533
- const offered = new Set(targeting.selection.offeredListIds);
51534
- return context.provider.provider === "brevo" ? context.provider.lists.filter((item) => offered.has(item.id)).map((item) => ({
51535
- id: String(item.id),
51536
- label: item.name
51537
- })) : [];
51538
- }
51539
- case "mailchimp": {
51540
- const offered = new Set(targeting.selection.offeredInterestIds);
51541
- return (context.provider.provider === "mailchimp" ? context.provider.audiences.find((item) => item.id === targeting.audienceId) : void 0)?.interests.filter((item) => offered.has(item.id)).map((item) => ({
51542
- id: item.id,
51543
- label: item.name
51544
- })) ?? [];
51545
- }
51546
- }
51547
- }
51548
- function runtimeTargetingIsAvailable(context, targeting, choices) {
51549
- if (context?.tag !== "configured") return false;
51550
- const provider = context.provider;
51551
- if (targeting.mode === "default") switch (provider.provider) {
51552
- case "native": return provider.topics.some((item) => item.id === provider.defaultTopicId);
51553
- case "brevo": return provider.lists.some((item) => item.id === provider.defaultListId);
51554
- case "mailchimp": return provider.audiences.some((item) => item.id === provider.defaultAudienceId);
51555
- }
51556
- if (targeting.provider !== provider.provider) return false;
51557
- switch (targeting.provider) {
51558
- case "native": return provider.provider === "native" && nativeTargetIsAvailable(provider, targeting, choices);
51559
- case "brevo": return provider.provider === "brevo" && brevoTargetIsAvailable(provider, targeting, choices);
51560
- case "mailchimp": return provider.provider === "mailchimp" && mailchimpTargetIsAvailable(provider, targeting, choices);
51561
- }
51562
- }
51563
- function nativeTargetIsAvailable(provider, targeting, choices) {
51564
- const ids = targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
51565
- return ids.every((id) => provider.topics.some((item) => item.id === id)) && (targeting.selection.tag !== "visitor_choice" || choices.length === ids.length);
51566
- }
51567
- function brevoTargetIsAvailable(provider, targeting, choices) {
51568
- const ids = targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
51569
- return ids.every((id) => provider.lists.some((item) => item.id === id)) && (targeting.selection.tag !== "visitor_choice" || choices.length === ids.length);
51570
- }
51571
- function mailchimpTargetIsAvailable(provider, targeting, choices) {
51572
- const audience = provider.audiences.find((item) => item.id === targeting.audienceId);
51573
- if (!audience) return false;
51574
- const ids = targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
51575
- return ids.every((id) => audience.interests.some((item) => item.id === id)) && (targeting.selection.tag !== "visitor_choice" || choices.length === ids.length);
52494
+ function resolveRuntimeChoices(assessment) {
52495
+ if (!("value" in assessment) || assessment.value.mode !== "custom" || !("selectedChoices" in assessment.value) || assessment.value.targeting.selection.tag !== "visitor_choice") return [];
52496
+ return assessment.value.selectedChoices.map((item) => ({
52497
+ id: String(item.id),
52498
+ label: item.name
52499
+ }));
51576
52500
  }
51577
52501
  function parseRequiredMailingListSignupBlockId(value) {
51578
52502
  const parsed = parseMailingListBlockId(value);
@@ -51760,6 +52684,7 @@ var init_newsletter_signup = __esmMin((() => {
51760
52684
  init_defineBlock();
51761
52685
  init_fragments();
51762
52686
  init_newsletter_form_interactive();
52687
+ init_normalizeMailingListBlockContent();
51763
52688
  stackedComposition = composeFragments([{ fragment: newsletterCopyFragment }, { fragment: newsletterFormFragment }]);
51764
52689
  stackedLayout = styledSection({
51765
52690
  children: sectionContainer(stackedComposition.layout, {
@@ -51850,6 +52775,10 @@ var init_newsletter_signup = __esmMin((() => {
51850
52775
  newsletterPublicFieldIds = [...(newsletterSignupManifest.fields ?? []).map((field) => field.id), "_containerStyles"];
51851
52776
  newsletterSignupBlockDefinition = {
51852
52777
  manifest: newsletterSignupManifest,
52778
+ contentNormalizer: {
52779
+ fieldIds: ["targeting"],
52780
+ normalize: normalizeMailingListBlockContent
52781
+ },
51853
52782
  runtime: newsletterFormBlockRuntime
51854
52783
  };
51855
52784
  }));
@@ -52603,7 +53532,20 @@ var init_location_map = __esmMin((() => {
52603
53532
  });
52604
53533
  locationMapBlockDefinition = {
52605
53534
  manifest: locationMapManifest,
52606
- normalizeContent: normalizeLocationMapContent
53535
+ contentNormalizer: {
53536
+ fieldIds: [
53537
+ "heading",
53538
+ "locationSource",
53539
+ "venueId",
53540
+ "location",
53541
+ "showAddressText",
53542
+ "showDirections",
53543
+ "directionsLabel",
53544
+ "zoom",
53545
+ "heightPx"
53546
+ ],
53547
+ normalize: normalizeLocationMapContent
53548
+ }
52607
53549
  };
52608
53550
  }));
52609
53551
  //#endregion
@@ -53927,6 +54869,21 @@ function resolveEntryLink(link, context) {
53927
54869
  function resolveExternalLink(link) {
53928
54870
  return resolveFallbackHref(link);
53929
54871
  }
54872
+ function resolveAuthoredLinkHref(value, context = {}) {
54873
+ if (!value || typeof value !== "object") return null;
54874
+ const link = value;
54875
+ switch (link.kind) {
54876
+ case "internal": return resolveInternalLink(link, context);
54877
+ case "page": return resolvePageLink(link, context);
54878
+ case "entry": return resolveEntryLink(link, context);
54879
+ case "external":
54880
+ case "url": return resolveExternalLink(link);
54881
+ default: return resolvePreResolvedLink(link);
54882
+ }
54883
+ }
54884
+ function resolvePreResolvedLink(link) {
54885
+ return !(typeof link.kind === "string" ? link.kind : null) && typeof link.href === "string" ? resolveExternalLink(link) : null;
54886
+ }
53930
54887
  var resolveLinkTransform, linkLabelTransform, linksTransforms;
53931
54888
  var init_links = __esmMin((() => {
53932
54889
  init_resolve();
@@ -53934,17 +54891,7 @@ var init_links = __esmMin((() => {
53934
54891
  id: "links.resolve",
53935
54892
  kind: "formatter",
53936
54893
  summary: "Resolve LinkValue objects to href strings using the route map",
53937
- run: (value, _options, context) => {
53938
- if (!value || typeof value !== "object") return null;
53939
- const link = value;
53940
- const kind = typeof link.kind === "string" ? link.kind : null;
53941
- if (kind === "internal") return resolveInternalLink(link, context);
53942
- if (kind === "page") return resolvePageLink(link, context);
53943
- if (kind === "entry") return resolveEntryLink(link, context);
53944
- if (kind === "external" || kind === "url") return resolveExternalLink(link);
53945
- if (!kind && typeof link.href === "string") return resolveExternalLink(link);
53946
- return null;
53947
- }
54894
+ run: (value, _options, context) => resolveAuthoredLinkHref(value, context)
53948
54895
  };
53949
54896
  linkLabelTransform = {
53950
54897
  id: "links.label",
@@ -55256,7 +56203,7 @@ var init_src$2 = __esmMin((() => {
55256
56203
  init_schema$2();
55257
56204
  init_palette();
55258
56205
  init_generateShades();
55259
- init_utils$3();
56206
+ init_utils$4();
55260
56207
  init_generateThemes();
55261
56208
  init_schema$3();
55262
56209
  init_site_styles();