@riverbankcms/sdk 0.88.0 → 0.90.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 (198) hide show
  1. package/README.md +27 -4
  2. package/dist/{PreviewEditorSidebar-EVRS3C7T.mjs → PreviewEditorSidebar-KVXNF3VW.mjs} +3 -3
  3. package/dist/{PreviewEditorUI-54WD4IGE.mjs → PreviewEditorUI-J3JN5Z7T.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-UBL6MSNP.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +216 -0
  6. package/dist/_dts/altcha/src/AltchaWidget.d.ts +1 -1
  7. package/dist/_dts/api/src/accessAdmin.d.ts +7 -0
  8. package/dist/_dts/api/src/bookingOperations.d.ts +2 -0
  9. package/dist/_dts/api/src/bookingRecords.d.ts +4 -2
  10. package/dist/_dts/api/src/bookings.d.ts +3 -1
  11. package/dist/_dts/api/src/endpoints.d.ts +8 -0
  12. package/dist/_dts/api/src/index.d.ts +7 -6
  13. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +15 -5
  14. package/dist/_dts/api/src/request.d.ts +21 -0
  15. package/dist/_dts/api/src/sdk-event-upsert.d.ts +3 -1
  16. package/dist/_dts/api/src/sdkContracts.d.ts +2 -0
  17. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  18. package/dist/_dts/api/src/siteMembers.d.ts +6 -1
  19. package/dist/_dts/api/src/types.d.ts +4 -2
  20. package/dist/_dts/api/src/url.d.ts +6 -3
  21. package/dist/_dts/block-form/src/utils/visibleWhen.d.ts +1 -0
  22. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailCard.d.ts +5 -1
  23. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailGrid.d.ts +9 -1
  24. package/dist/_dts/block-form/src/widgets/RepeaterField/components/index.d.ts +1 -0
  25. package/dist/_dts/blocks/src/contracts/non-block-islands.d.ts +7 -11
  26. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +6 -0
  27. package/dist/_dts/blocks/src/index.d.ts +2 -1
  28. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +14 -6
  29. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -4
  30. package/dist/_dts/blocks/src/system/blocks/hero.d.ts +0 -2
  31. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +3 -3
  32. package/dist/_dts/blocks/src/system/blocks/shop.shared.d.ts +8 -0
  33. package/dist/_dts/blocks/src/system/constants/events.d.ts +4 -1
  34. package/dist/_dts/blocks/src/system/icons/cta.d.ts +3 -3
  35. package/dist/_dts/blocks/src/system/icons/index.d.ts +1 -0
  36. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -2
  37. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +3 -3
  38. package/dist/_dts/blocks/src/system/icons/svg.d.ts +72 -0
  39. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +3 -1
  40. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -0
  41. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +18 -5
  42. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +51 -6
  43. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -0
  44. package/dist/_dts/blocks/src/system/runtime/hooks/loadStateError.d.ts +1 -0
  45. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.d.ts +1 -1
  46. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.state.d.ts +55 -0
  47. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableSlots.state.d.ts +39 -0
  48. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.d.ts +4 -27
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.state.d.ts +40 -0
  50. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +20 -0
  51. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.state.d.ts +31 -0
  52. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +3 -3
  53. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.state.d.ts +39 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +2 -2
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +1 -17
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.client.d.ts +5 -9
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.server.d.ts +5 -9
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.d.ts +24 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +5 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.d.ts +4 -4
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.d.ts +50 -0
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +2 -2
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +21 -0
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +1 -1
  66. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +11 -1
  67. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +2 -1
  68. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +11 -1
  69. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventPaginatedListView.client.d.ts +1 -1
  70. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/calendarViewOptions.d.ts +10 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventProductEligibility.d.ts +24 -0
  72. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.client.state.d.ts +24 -2
  73. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +24 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +5 -2
  75. package/dist/_dts/blocks/src/system/runtime/nodes/shop-checkout-form.d.ts +2 -2
  76. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +35 -0
  77. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  78. package/dist/_dts/content-model/src/entry-slots/sdkBlocks.d.ts +21 -0
  79. package/dist/_dts/content-model/src/entry-slots/types.d.ts +61 -0
  80. package/dist/_dts/core/src/branded.d.ts +7 -0
  81. package/dist/_dts/core/src/index.d.ts +1 -0
  82. package/dist/_dts/core/src/money-input.d.ts +18 -0
  83. package/dist/_dts/core/src/site-route-target.d.ts +40 -0
  84. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +209 -2
  85. package/dist/_dts/media-core/src/fileDomain.d.ts +4 -0
  86. package/dist/_dts/media-editor/src/MediaEditor.d.ts +2 -1
  87. package/dist/_dts/media-editor/src/fieldUi.d.ts +6 -0
  88. package/dist/_dts/media-editor/src/index.d.ts +1 -1
  89. package/dist/_dts/preview-next/src/client/index.d.ts +1 -0
  90. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +3 -2
  91. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +3 -2
  92. package/dist/_dts/preview-next/src/client/preview/PreviewThemedSiteDocument.d.ts +3 -2
  93. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +2 -2
  94. package/dist/_dts/preview-next/src/client/preview/themeRuntime.d.ts +6 -0
  95. package/dist/_dts/preview-next/src/client/sdk/SdkPreviewMode.d.ts +2 -1
  96. package/dist/_dts/sdk/src/cli/commands/pull-dated-offering-scope.d.ts +10 -0
  97. package/dist/_dts/sdk/src/cli/content/reader.d.ts +12 -5
  98. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -55
  99. package/dist/_dts/sdk/src/client/runtimeCachePolicy.d.ts +160 -0
  100. package/dist/_dts/sdk/src/client/types.d.ts +26 -1
  101. package/dist/_dts/sdk/src/components.d.ts +1 -0
  102. package/dist/_dts/sdk/src/config/field-definitions.d.ts +3 -1
  103. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +3 -1
  104. package/dist/_dts/sdk/src/index.d.ts +3 -1
  105. package/dist/_dts/sdk/src/next/types.d.ts +8 -11
  106. package/dist/_dts/sdk/src/preview-next/client/index.d.ts +1 -1
  107. package/dist/_dts/sdk/src/rendering/blocks-theme-scope.d.ts +2 -1
  108. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +8 -7
  109. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +5 -6
  110. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
  111. package/dist/_dts/sdk/src/rendering/server.d.ts +1 -0
  112. package/dist/_dts/sdk/src/rendering/themeRuntime.d.ts +26 -0
  113. package/dist/_dts/sdk/src/version.d.ts +1 -1
  114. package/dist/_dts/site-commands/src/commands.d.ts +18 -0
  115. package/dist/_dts/theme-core/src/ResponsiveScope.d.ts +12 -0
  116. package/dist/_dts/theme-core/src/accordions/types.d.ts +1 -1
  117. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +2 -2
  118. package/dist/_dts/theme-core/src/buttons/types.d.ts +5 -5
  119. package/dist/_dts/theme-core/src/cards/types.d.ts +2 -2
  120. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  121. package/dist/_dts/theme-core/src/index.d.ts +2 -0
  122. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +21 -21
  123. package/dist/_dts/theme-core/src/schema.d.ts +18 -18
  124. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
  125. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +2 -2
  126. package/dist/_dts/theme-core/src/site-styles/logoBranding.d.ts +4 -4
  127. package/dist/_dts/theme-core/src/themeRuntime.d.ts +11 -0
  128. package/dist/{chunk-ER4UIW4X.mjs → chunk-AEOYWPE4.mjs} +91 -55
  129. package/dist/{chunk-O4LVYUVH.mjs → chunk-BOQXMCSP.mjs} +147 -101
  130. package/dist/{chunk-HVOBXA3Y.mjs → chunk-GSPFFUVB.mjs} +2 -2
  131. package/dist/{chunk-7KOO7RPP.mjs → chunk-PMBB6MQ7.mjs} +2273 -1113
  132. package/dist/{chunk-K3JWH6HE.mjs → chunk-RQ3XZ4SJ.mjs} +9 -1
  133. package/dist/{chunk-YDMBIIS5.mjs → chunk-UG7I7S7W.mjs} +1 -1
  134. package/dist/cli/index.mjs +1564 -546
  135. package/dist/cli/init-docs/content/cli-reference.md +6 -1
  136. package/dist/cli/init-docs/content/content-management.md +27 -0
  137. package/dist/client/{accordion-PT5CGW5N.mjs → accordion-GXQNWQ6O.mjs} +2 -2
  138. package/dist/client/{bookingForm-2HLRTEYS.mjs → bookingForm-STLUJ36H.mjs} +206 -335
  139. package/dist/client/bookings.mjs +821 -413
  140. package/dist/client/{carousel-Z2LKYSWA.mjs → carousel-CVRN6EPP.mjs} +4 -3
  141. package/dist/client/{cart-ND5IK4A6.mjs → cart-IYIBA5CL.mjs} +8 -8
  142. package/dist/client/{checkout-EYUSGAY7.mjs → checkout-O3BGM4GS.mjs} +8 -8
  143. package/dist/client/chunk-4RTFGHZN.mjs +433 -0
  144. package/dist/client/{chunk-DIRW2LNG.mjs → chunk-6DPXDOIL.mjs} +336 -225
  145. package/dist/client/chunk-6N7YRNYU.mjs +183 -0
  146. package/dist/client/{chunk-O5JNI3E4.mjs → chunk-7DH35FGA.mjs} +2 -2
  147. package/dist/client/{chunk-S4G65LGR.mjs → chunk-D3ETC2SU.mjs} +1 -1
  148. package/dist/client/{chunk-BAWHZ5GM.mjs → chunk-DAS5CIER.mjs} +460 -157
  149. package/dist/client/{chunk-6DVPO44G.mjs → chunk-FHU6PFPM.mjs} +1 -1
  150. package/dist/client/{chunk-SDIYSQAY.mjs → chunk-HIHOQGIP.mjs} +2 -3
  151. package/dist/client/{chunk-BL66UWGD.mjs → chunk-MFPKS6QS.mjs} +13 -16
  152. package/dist/client/{chunk-X7GVFB7Y.mjs → chunk-NBFRJ5NB.mjs} +157 -5
  153. package/dist/client/{chunk-WCVK4MBJ.mjs → chunk-VFHZLZAC.mjs} +1 -1
  154. package/dist/client/{chunk-GOFO7HRH.mjs → chunk-WHZQDPBZ.mjs} +19 -1
  155. package/dist/client/{chunk-MHBEWDT7.mjs → chunk-Z62JYS5O.mjs} +122 -50
  156. package/dist/client/client.mjs +5979 -5198
  157. package/dist/client/{courseRegistration-H3AZBUEG.mjs → courseRegistration-2D3ACMJR.mjs} +20 -58
  158. package/dist/client/{eventCalendar-FPKJGLGS.mjs → eventCalendar-QY4UZUFF.mjs} +11 -11
  159. package/dist/client/{eventCombined-QCGIZBUY.mjs → eventCombined-RRCDKJC2.mjs} +11 -11
  160. package/dist/client/{eventDetails-HIT3BJWU.mjs → eventDetails-YO335BUT.mjs} +11 -11
  161. package/dist/client/{eventListing-R4HNWJDN.mjs → eventListing-PXA6GFQ3.mjs} +11 -11
  162. package/dist/client/{eventRegistration-Q7BYY5HF.mjs → eventRegistration-2ZHEDDXO.mjs} +11 -11
  163. package/dist/client/{form-NI6YOG6S.mjs → form-ZS6KX4U2.mjs} +7 -7
  164. package/dist/client/{headerSection-SDYGII36.mjs → headerSection-QK5SLIIB.mjs} +3 -3
  165. package/dist/client/hooks.mjs +1102 -1029
  166. package/dist/client/{locationMap-BDETEUQD.mjs → locationMap-GFNIUD2X.mjs} +3 -3
  167. package/dist/client/{newsletterForm-EKYIU67X.mjs → newsletterForm-PGLTTCUG.mjs} +61 -25
  168. package/dist/client/{productDetail-5UTGNN76.mjs → productDetail-OPBE5ZPI.mjs} +8 -8
  169. package/dist/client/{productList-7YA5KXZQ.mjs → productList-NI72Q62Z.mjs} +8 -8
  170. package/dist/client/rendering/client.mjs +4390 -4245
  171. package/dist/client/rendering/islands.mjs +19 -19
  172. package/dist/client/rendering.mjs +3327 -3181
  173. package/dist/client/{shop-AIMUMZYC.mjs → shop-3ZQPEWYI.mjs} +8 -8
  174. package/dist/client/spam-protection.mjs +4 -5
  175. package/dist/preview-next/before-render.mjs +20 -2
  176. package/dist/preview-next/client/runtime.mjs +5 -5
  177. package/dist/preview-next/middleware.mjs +18 -0
  178. package/dist/{sdk-runtime-NW472WNT.mjs → sdk-runtime-FSHXCWDS.mjs} +6 -6
  179. package/dist/server/components.mjs +2580 -2783
  180. package/dist/server/config-validation.mjs +1334 -1261
  181. package/dist/server/config.mjs +1334 -1261
  182. package/dist/server/data.mjs +1102 -1029
  183. package/dist/server/index.mjs +1097 -476
  184. package/dist/server/navigation.mjs +20 -30
  185. package/dist/server/next.mjs +3282 -2847
  186. package/dist/server/page-converter.mjs +1009 -946
  187. package/dist/server/prebuild.mjs +1 -1
  188. package/dist/server/rendering/server.mjs +2580 -2783
  189. package/dist/server/rendering.mjs +2586 -2789
  190. package/dist/server/routing.mjs +1440 -1053
  191. package/dist/server/server.mjs +1886 -1153
  192. package/dist/server/theme-bridge.mjs +34 -5
  193. package/dist/styles/index.css +26 -0
  194. package/package.json +3 -2
  195. package/dist/SdkPreviewModeRuntime-ZALZDJEK.mjs +0 -8
  196. package/dist/client/chunk-H4MHEXYS.mjs +0 -184
  197. package/dist/client/chunk-ZFHRN6W2.mjs +0 -66
  198. /package/dist/client/{chunk-LI2C6M5O.mjs → chunk-25W2EQUN.mjs} +0 -0
@@ -1,17 +1,17 @@
1
1
  "use client";
2
- import { LeafletStaticMap } from './chunk-S4G65LGR.mjs';
3
- import { resolveCoursePricingState, useWaitlistClaim, MagicLinkForm, formatCoursePriceAmount, formatCoursePriceDisplay } from './chunk-MHBEWDT7.mjs';
4
- import { usePolling } from './chunk-H4MHEXYS.mjs';
5
- import { SpinnerNode } from './chunk-6DVPO44G.mjs';
6
- import { useDiscountCodeUi } from './chunk-ZFHRN6W2.mjs';
7
- import { createBodyThemePortalRoot, TabBarFragment, logoutPortal, consumeSearchParam, StepIndicator, DiscountCodeDisclosure, TerminalPanel, StateIcon, formatPrice, CrossIcon, ClockIcon, LoggedInAsUser, CheckIcon } from './chunk-X7GVFB7Y.mjs';
2
+ import { LeafletStaticMap } from './chunk-D3ETC2SU.mjs';
3
+ import { resolveCoursePricingState, useWaitlistClaim, MagicLinkForm, formatCoursePriceAmount, formatCoursePriceDisplay } from './chunk-Z62JYS5O.mjs';
4
+ import { CreditCard, Ticket, Star, Sparkles } from './chunk-6N7YRNYU.mjs';
5
+ import { usePolling, buildBookingPaymentSelectionViewModel } from './chunk-4RTFGHZN.mjs';
6
+ import { SpinnerNode } from './chunk-FHU6PFPM.mjs';
7
+ import { createBodyThemePortalRoot, TabBarFragment, useDiscountCodeUi, logoutPortal, consumeSearchParam, StepIndicator, DiscountCodeDisclosure, TerminalPanel, StateIcon, formatPrice, CrossIcon, ClockIcon, LoggedInAsUser, CheckIcon } from './chunk-NBFRJ5NB.mjs';
8
8
  import { getFieldValidationControlProps, FieldValidationMessage } from './chunk-3DCJ45Z2.mjs';
9
9
  import { ModalShell } from './chunk-WBQG7VJA.mjs';
10
- import { isSpamProtectionEnabled, AltchaWidget, getChallengeUrl } from './chunk-SDIYSQAY.mjs';
11
- import { useBlockApi, FeedbackMessage } from './chunk-GOFO7HRH.mjs';
12
- import { buildEventRuntimeFilters, buildEventCalendarListingRender, groupEventsByDate, getOrderedDayNames, formatDateKey, getEventRuntimeFiltersKey, themeButtonClassName, normalizeCsvIds, normalizeOptionalId, normalizeEventBlockKind, normalizeCsvString, EventCompactRow, EmptyState, getContainerClass, getCardOrientation, isToday, MAX_EVENTS_PER_DAY, formatTime, WIZARD_STEPS, getWizardStepsForContext, getStepNumber, formatEventPriceDisplay, resolveRuntimeEventPricing, formatEventPrice, formatEventDateParts, DateTimeTile, EventCard, buildCalendarViewport, shiftCalendarAnchorDate, addMonths, getThreeMonthRange, buildTimetableModel, formatDate, toRegistrationEvents, isEventContentType, findPreSelectedEvent, resolveRegistrationTarget, findEventByOccurrenceId, resolveEventRequiresPayment, resolveDiscountContext, MONTH_NAMES, getEventAvailability, formatEventTeacherLine, assertNever11, CreditCard, Ticket, Star, Sparkles } from './chunk-DIRW2LNG.mjs';
13
- import { publicEventPricingType, getBookingLocalDateKey, toScheduledBookingDateTime, toBookingTimeZone, publicEventPricingCurrency, formatBookingDateTime, publicEventPricingMode, publicEventScalarPrice, publicEventTicketTypes, formatCurrencyAmount, formatBookingDate, formatBookingTime } from './chunk-LI2C6M5O.mjs';
14
- import React9, { createContext, useId, useMemo, useState, useRef, useEffect, useCallback, useContext, useReducer } from 'react';
10
+ import { isSpamProtectionEnabled, AltchaWidget, getChallengeUrl } from './chunk-HIHOQGIP.mjs';
11
+ import { useBlockApi, FeedbackMessage } from './chunk-WHZQDPBZ.mjs';
12
+ import { buildEventRuntimeFilters, buildEventCalendarListingRender, groupEventsByDate, getOrderedDayNames, formatDateKey, getEventRuntimeFiltersKey, themeButtonClassName, normalizeCsvIds, normalizeOptionalId, normalizeEventBlockKind, normalizeCsvString, EventCompactRow, EmptyState, getContainerClass, getCardOrientation, isToday, MAX_EVENTS_PER_DAY, formatTime, WIZARD_STEPS, getWizardStepsForContext, getStepNumber, formatEventPriceDisplay, resolveRuntimeEventPricing, formatEventPrice, formatEventDateParts, DateTimeTile, assertNever, EventCard, buildCalendarViewport, shiftCalendarAnchorDate, addMonths, getThreeMonthRange, buildTimetableModel, formatDate, MONTH_NAMES, getEventAvailability, formatEventTeacherLine, toRegistrationEvents, isEventContentType, findPreSelectedEvent, resolveRegistrationTarget, findEventByOccurrenceId, resolveEventRequiresPayment, resolveDiscountContext } from './chunk-6DPXDOIL.mjs';
13
+ import { publicEventPricingType, getBookingLocalDateKey, toScheduledBookingDateTime, toBookingTimeZone, publicEventPricingCurrency, formatBookingDateTime, publicEventPricingMode, publicEventScalarPrice, publicEventTicketTypes, formatCurrencyAmount, formatBookingDate, formatBookingTime } from './chunk-25W2EQUN.mjs';
14
+ import React9, { createContext, useId, useMemo, useReducer, useState, useRef, useEffect, useCallback, useContext } from 'react';
15
15
  import { createPortal } from 'react-dom';
16
16
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
17
17
 
@@ -32,12 +32,18 @@ function createInitialRegistrationFlowState(hasPreSelectedContext) {
32
32
  };
33
33
  }
34
34
  function selectionEquals(a, b) {
35
- return a.method === b.method && a.passId === b.passId && a.membershipId === b.membershipId && a.bundlePassId === b.bundlePassId && a.bundleMembershipId === b.bundleMembershipId && a.productName === b.productName && a.productDescription === b.productDescription && a.productPrice === b.productPrice && a.productCurrency === b.productCurrency && a.productInterval === b.productInterval;
35
+ return a.method === b.method && a.passId === b.passId && a.membershipId === b.membershipId && a.bundlePassId === b.bundlePassId && a.bundleMembershipId === b.bundleMembershipId && a.productName === b.productName && a.productDescription === b.productDescription && a.productPrice === b.productPrice && a.productCurrency === b.productCurrency && a.productInterval === b.productInterval && a.collectionOptionKind === b.collectionOptionKind;
36
36
  }
37
37
  function withDefaultSelection(selection) {
38
38
  if (!selection || !selection.method) {
39
39
  return { method: null };
40
40
  }
41
+ if (selection.method === "stripe") {
42
+ return {
43
+ ...selection,
44
+ collectionOptionKind: selection.collectionOptionKind ?? "upfront"
45
+ };
46
+ }
41
47
  return selection;
42
48
  }
43
49
  function computeAutoSelection(input) {
@@ -63,7 +69,7 @@ function computeAutoSelection(input) {
63
69
  }
64
70
  }
65
71
  if (eligibility.canPayDirectly && eligibility.price) {
66
- return { method: "stripe" };
72
+ return { method: "stripe", collectionOptionKind: "upfront" };
67
73
  }
68
74
  return { method: null };
69
75
  }
@@ -81,11 +87,17 @@ function isSelectionValid(input) {
81
87
  case "pass":
82
88
  return isAuthenticated && ticketsCount === 1 && !!selection.passId && eligibility.eligiblePasses.some((pass) => pass.id === selection.passId);
83
89
  case "membership":
84
- return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some((membership) => membership.id === selection.membershipId);
90
+ return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some(
91
+ (membership) => membership.id === selection.membershipId
92
+ );
85
93
  case "pass_bundle":
86
- return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some((pass) => pass.id === selection.bundlePassId);
94
+ return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some(
95
+ (pass) => pass.id === selection.bundlePassId
96
+ );
87
97
  case "membership_bundle":
88
- return ticketsCount === 1 && !!selection.bundleMembershipId && eligibility.availableMemberships.some((membership) => membership.id === selection.bundleMembershipId);
98
+ return ticketsCount === 1 && !!selection.bundleMembershipId && eligibility.availableMemberships.some(
99
+ (membership) => membership.id === selection.bundleMembershipId
100
+ );
89
101
  default:
90
102
  return false;
91
103
  }
@@ -132,9 +144,15 @@ function registrationFlowReducer(state, action) {
132
144
  ticketsCount: Math.max(1, action.ticketsCount)
133
145
  });
134
146
  case "set-authenticated":
135
- return normalizeRegistrationFlowState({ ...state, isAuthenticated: action.isAuthenticated });
147
+ return normalizeRegistrationFlowState({
148
+ ...state,
149
+ isAuthenticated: action.isAuthenticated
150
+ });
136
151
  case "eligibility-updated":
137
- return normalizeRegistrationFlowState({ ...state, eligibility: action.eligibility });
152
+ return normalizeRegistrationFlowState({
153
+ ...state,
154
+ eligibility: action.eligibility
155
+ });
138
156
  case "set-manual-payment-selection":
139
157
  return normalizeRegistrationFlowState({
140
158
  ...state,
@@ -146,7 +164,7 @@ function registrationFlowReducer(state, action) {
146
164
  return normalizeRegistrationFlowState({
147
165
  ...state,
148
166
  passOptOut: true,
149
- paymentSelection: { method: "stripe" },
167
+ paymentSelection: { method: "stripe", collectionOptionKind: "upfront" },
150
168
  selectionSource: "manual"
151
169
  });
152
170
  case "event-changed":
@@ -192,7 +210,10 @@ function normalizeEventRegistrationMaxTickets(value) {
192
210
  function resolveEventRegistrationSubmitPlan(input) {
193
211
  const selection = input.paymentSelection.method ? input.paymentSelection : void 0;
194
212
  if (input.canJoinWaitlist) {
195
- return { ok: true, args: withOptionalSelection({ method: "free" }, selection) };
213
+ return {
214
+ ok: true,
215
+ args: withOptionalSelection({ method: "free" }, selection)
216
+ };
196
217
  }
197
218
  switch (input.paymentSelection.method) {
198
219
  case "pass":
@@ -207,19 +228,28 @@ function resolveEventRegistrationSubmitPlan(input) {
207
228
  return input.paymentSelection.membershipId ? {
208
229
  ok: true,
209
230
  args: withOptionalSelection(
210
- { method: "membership", membershipId: input.paymentSelection.membershipId },
231
+ {
232
+ method: "membership",
233
+ membershipId: input.paymentSelection.membershipId
234
+ },
211
235
  selection
212
236
  )
213
237
  } : missingPaymentSelection();
214
238
  case "free":
215
- return { ok: true, args: withOptionalSelection({ method: "free" }, selection) };
239
+ return {
240
+ ok: true,
241
+ args: withOptionalSelection({ method: "free" }, selection)
242
+ };
216
243
  case null:
217
244
  return input.eventRequiresPayment ? missingPaymentSelection() : { ok: true, args: { method: "free" } };
218
245
  case "pass_bundle":
219
246
  return input.paymentSelection.bundlePassId ? {
220
247
  ok: true,
221
248
  args: withOptionalSelection(
222
- { method: "pass_bundle", passId: input.paymentSelection.bundlePassId },
249
+ {
250
+ method: "pass_bundle",
251
+ passId: input.paymentSelection.bundlePassId
252
+ },
223
253
  selection
224
254
  )
225
255
  } : missingPaymentSelection();
@@ -235,7 +265,10 @@ function resolveEventRegistrationSubmitPlan(input) {
235
265
  )
236
266
  } : missingPaymentSelection();
237
267
  case "stripe":
238
- return { ok: true, args: withOptionalSelection({ method: "stripe" }, selection) };
268
+ return {
269
+ ok: true,
270
+ args: withOptionalSelection({ method: "stripe" }, selection)
271
+ };
239
272
  }
240
273
  }
241
274
  function withOptionalSelection(args, selection) {
@@ -389,7 +422,7 @@ function eligibilityLookupReducer(state, action) {
389
422
  error: action.message
390
423
  };
391
424
  default:
392
- return assertNever11(action);
425
+ return assertNever(action);
393
426
  }
394
427
  }
395
428
  var initialExistingRegistrationLookupState = {
@@ -411,7 +444,7 @@ function existingRegistrationLookupReducer(state, action) {
411
444
  registration: action.registration
412
445
  };
413
446
  default:
414
- return assertNever11(action);
447
+ return assertNever(action);
415
448
  }
416
449
  }
417
450
 
@@ -1319,10 +1352,72 @@ function SelectableOptionCard(props) {
1319
1352
  }
1320
1353
  );
1321
1354
  }
1355
+
1356
+ // ../blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.ts
1357
+ var DEFAULT_EVENT_DIRECT_PAYMENT_OPTION = {
1358
+ kind: "upfront"
1359
+ };
1360
+ function buildEventRegistrationPaymentOptionsViewModel(input) {
1361
+ const supportedOptions = selectSupportedEventDirectPaymentOptions(
1362
+ input.paymentTerms
1363
+ );
1364
+ const selection = buildBookingPaymentSelectionViewModel({
1365
+ serviceTitle: input.eventTitle,
1366
+ paymentTerms: { allowedOptions: [...supportedOptions] },
1367
+ priceAmount: input.totalPriceCents,
1368
+ priceCurrency: input.currency,
1369
+ bookingStartAt: input.startsAt,
1370
+ locale: input.locale
1371
+ });
1372
+ return {
1373
+ mode: selection.mode,
1374
+ sectionTitle: selection.sectionTitle,
1375
+ options: selection.options.map(
1376
+ (option) => toEventDirectPaymentOption(option, selection.mode)
1377
+ )
1378
+ };
1379
+ }
1380
+ function selectSupportedEventDirectPaymentOptions(paymentTerms) {
1381
+ const supported = paymentTerms?.allowedOptions.filter(isSupportedEventDirectPaymentOption) ?? [];
1382
+ return supported.length > 0 ? supported : [DEFAULT_EVENT_DIRECT_PAYMENT_OPTION];
1383
+ }
1384
+ function isSupportedEventDirectPaymentOption(option) {
1385
+ return option.kind === "upfront" || option.kind === "flexible_balance";
1386
+ }
1387
+ function toEventDirectPaymentOption(option, mode) {
1388
+ switch (option.kind) {
1389
+ case "upfront":
1390
+ return {
1391
+ ...option,
1392
+ kind: "upfront",
1393
+ label: mode === "choice_required" ? "Pay in full now" : "Pay by card"
1394
+ };
1395
+ case "flexible_balance":
1396
+ return {
1397
+ ...option,
1398
+ kind: "flexible_balance",
1399
+ label: "Pay deposit now"
1400
+ };
1401
+ case "deferred_manual":
1402
+ case "instalment_plan":
1403
+ throw new Error(
1404
+ `Unsupported event registration payment option: ${option.kind}`
1405
+ );
1406
+ }
1407
+ }
1322
1408
  function PaymentCheckIcon() {
1323
1409
  return /* @__PURE__ */ jsx("div", { className: "er-check", children: /* @__PURE__ */ jsx(CheckIcon, {}) });
1324
1410
  }
1325
- function PaymentTile({ icon, label, detail, selected, disabled, tooltip, upsell, onClick }) {
1411
+ function PaymentTile({
1412
+ icon,
1413
+ label,
1414
+ detail,
1415
+ selected,
1416
+ disabled,
1417
+ tooltip,
1418
+ upsell,
1419
+ onClick
1420
+ }) {
1326
1421
  return /* @__PURE__ */ jsx(
1327
1422
  SelectableOptionCard,
1328
1423
  {
@@ -1345,6 +1440,16 @@ function PaymentTile({ icon, label, detail, selected, disabled, tooltip, upsell,
1345
1440
  }
1346
1441
  );
1347
1442
  }
1443
+ function formatDirectPaymentOptionDetail(option) {
1444
+ const dueToday = option.summaryRows.find((row) => row.label === "Due today");
1445
+ const balanceDueBy = option.summaryRows.find(
1446
+ (row) => row.label === "Balance due by"
1447
+ );
1448
+ return [
1449
+ dueToday ? `Due today: ${dueToday.value}` : option.description,
1450
+ balanceDueBy ? `Balance due by: ${balanceDueBy.value}` : null
1451
+ ].filter((part) => Boolean(part)).join(" \xB7 ");
1452
+ }
1348
1453
  var PaymentSelectionStep = ({
1349
1454
  event,
1350
1455
  occurrenceContext,
@@ -1364,9 +1469,12 @@ var PaymentSelectionStep = ({
1364
1469
  const canContinue = (() => {
1365
1470
  if (!selectedMethod) return false;
1366
1471
  if (selectedMethod === "pass") return Boolean(selectedSelection.passId);
1367
- if (selectedMethod === "membership") return Boolean(selectedSelection.membershipId);
1368
- if (selectedMethod === "pass_bundle") return Boolean(selectedSelection.bundlePassId);
1369
- if (selectedMethod === "membership_bundle") return Boolean(selectedSelection.bundleMembershipId);
1472
+ if (selectedMethod === "membership")
1473
+ return Boolean(selectedSelection.membershipId);
1474
+ if (selectedMethod === "pass_bundle")
1475
+ return Boolean(selectedSelection.bundlePassId);
1476
+ if (selectedMethod === "membership_bundle")
1477
+ return Boolean(selectedSelection.bundleMembershipId);
1370
1478
  return true;
1371
1479
  })();
1372
1480
  const getButtonText = useCallback(() => {
@@ -1395,7 +1503,15 @@ var PaymentSelectionStep = ({
1395
1503
  buttonText: getButtonText(),
1396
1504
  showLoginPrompt
1397
1505
  });
1398
- }, [onStateChange, eligibilityLoading, eligibilityError, eligibility, isAuthenticated, canContinue, getButtonText]);
1506
+ }, [
1507
+ onStateChange,
1508
+ eligibilityLoading,
1509
+ eligibilityError,
1510
+ eligibility,
1511
+ isAuthenticated,
1512
+ canContinue,
1513
+ getButtonText
1514
+ ]);
1399
1515
  if (eligibilityLoading) {
1400
1516
  return /* @__PURE__ */ jsx("div", { className: "er-stack", children: /* @__PURE__ */ jsxs("div", { className: "er-center", children: [
1401
1517
  /* @__PURE__ */ jsx(SpinnerNode, { size: "lg", srLabel: "Checking payment options" }),
@@ -1443,7 +1559,10 @@ var PaymentSelectionStep = ({
1443
1559
  "button",
1444
1560
  {
1445
1561
  type: "button",
1446
- className: themeButtonClassName({ variant: "primary", size: "md" }),
1562
+ className: themeButtonClassName({
1563
+ variant: "primary",
1564
+ size: "md"
1565
+ }),
1447
1566
  disabled: !email.trim(),
1448
1567
  onClick: onRequestLogin,
1449
1568
  children: "Email me a login link"
@@ -1458,20 +1577,31 @@ var PaymentSelectionStep = ({
1458
1577
  ] });
1459
1578
  }
1460
1579
  const totalPrice = eligibility.price ? eligibility.price * ticketsCount : 0;
1580
+ const directPaymentOptions = buildEventRegistrationPaymentOptionsViewModel({
1581
+ eventTitle: event?.title ?? "Event",
1582
+ paymentTerms: event?.paymentTerms,
1583
+ totalPriceCents: totalPrice,
1584
+ currency: eligibility.currency,
1585
+ startsAt: occurrenceContext?.startsAt ?? event?.startsAt
1586
+ }).options;
1461
1587
  const isMultiTicket = areEntitlementsDisabledForTicketCount(ticketsCount);
1462
1588
  return /* @__PURE__ */ jsxs("div", { className: "er-stack", children: [
1463
1589
  /* @__PURE__ */ jsx("h3", { className: "er-title", children: "Payment Options" }),
1464
1590
  /* @__PURE__ */ jsxs("div", { className: "er-payment-tiles", children: [
1465
- eligibility.canPayDirectly && eligibility.price && /* @__PURE__ */ jsx(
1591
+ eligibility.canPayDirectly && eligibility.price && /* @__PURE__ */ jsx(Fragment, { children: directPaymentOptions.map((option) => /* @__PURE__ */ jsx(
1466
1592
  PaymentTile,
1467
1593
  {
1468
1594
  icon: /* @__PURE__ */ jsx(CreditCard, { size: 24, "aria-hidden": "true" }),
1469
- label: "Pay by Card",
1470
- detail: formatPrice(totalPrice, eligibility.currency),
1471
- selected: selectedMethod === "stripe",
1472
- onClick: () => onSelectionChange({ method: "stripe", collectionOptionKind: "upfront" })
1473
- }
1474
- ),
1595
+ label: option.label,
1596
+ detail: formatDirectPaymentOptionDetail(option),
1597
+ selected: selectedMethod === "stripe" && (selectedSelection.collectionOptionKind ?? "upfront") === option.kind,
1598
+ onClick: () => onSelectionChange({
1599
+ method: "stripe",
1600
+ collectionOptionKind: option.kind
1601
+ })
1602
+ },
1603
+ option.kind
1604
+ )) }),
1475
1605
  isAuthenticated && eligibility.eligiblePasses.map((pass) => /* @__PURE__ */ jsx(
1476
1606
  PaymentTile,
1477
1607
  {
@@ -1481,7 +1611,11 @@ var PaymentSelectionStep = ({
1481
1611
  selected: selectedMethod === "pass" && selectedSelection.passId === pass.id,
1482
1612
  disabled: isMultiTicket,
1483
1613
  tooltip: isMultiTicket ? ENTITLEMENT_SINGLE_TICKET_TOOLTIP : void 0,
1484
- onClick: () => onSelectionChange({ method: "pass", passId: pass.id, productName: pass.passName })
1614
+ onClick: () => onSelectionChange({
1615
+ method: "pass",
1616
+ passId: pass.id,
1617
+ productName: pass.passName
1618
+ })
1485
1619
  },
1486
1620
  pass.id
1487
1621
  )),
@@ -2725,6 +2859,46 @@ function useEventRegistrationWizard(options) {
2725
2859
  };
2726
2860
  }
2727
2861
 
2862
+ // ../blocks/src/system/runtime/nodes/events/shared/eventProductEligibility.ts
2863
+ function isCategoryEligible(eligibleCategoryIds, eventCategoryId) {
2864
+ const categories = eligibleCategoryIds ?? [];
2865
+ if (categories.length === 0) return true;
2866
+ if (!eventCategoryId) return false;
2867
+ return categories.includes(eventCategoryId);
2868
+ }
2869
+ function passCoversEvent(args, event) {
2870
+ if (!event.acceptsPasses) return false;
2871
+ return isCategoryEligible(args.eligibleCategoryIds, event.eventCategoryId);
2872
+ }
2873
+ function membershipCoversEvent(args, event) {
2874
+ if (!event.acceptsMemberships) return false;
2875
+ return isCategoryEligible(args.eligibleCategoryIds, event.eventCategoryId);
2876
+ }
2877
+ function filterPassesForEvent(sitePasses, event) {
2878
+ if (!sitePasses || !event) return [];
2879
+ if (event.requiresRegistration === false) return [];
2880
+ const acceptsPasses = event.acceptsPasses ?? true;
2881
+ const eventCategoryId = event.eventCategory?.id ?? null;
2882
+ return sitePasses.filter(
2883
+ (pass) => pass.productUseCase === "event_pass" && passCoversEvent(
2884
+ { eligibleCategoryIds: pass.eligibleCategoryIds },
2885
+ { acceptsPasses, eventCategoryId }
2886
+ )
2887
+ );
2888
+ }
2889
+ function filterMembershipsForEvent(siteMemberships, event) {
2890
+ if (!siteMemberships || !event) return [];
2891
+ if (event.requiresRegistration === false) return [];
2892
+ const acceptsMemberships = event.acceptsMemberships ?? true;
2893
+ const eventCategoryId = event.eventCategory?.id ?? null;
2894
+ return siteMemberships.filter(
2895
+ (membership) => membershipCoversEvent(
2896
+ { eligibleCategoryIds: membership.eligibleCategoryIds },
2897
+ { acceptsMemberships, eventCategoryId }
2898
+ )
2899
+ );
2900
+ }
2901
+
2728
2902
  // ../blocks/src/system/runtime/nodes/event-registration/constants.ts
2729
2903
  var EVENT_REGISTRATION_ANCHOR_ID = "event-registration";
2730
2904
  var EVENT_PORTAL_AUTH_COPY = {
@@ -2765,7 +2939,9 @@ function EventRegistrationWizard(props) {
2765
2939
  buttonVariant = "primary",
2766
2940
  className,
2767
2941
  spamProtectionEnabled,
2768
- supportEmail
2942
+ supportEmail,
2943
+ sitePasses,
2944
+ siteMemberships
2769
2945
  } = props;
2770
2946
  const maxTicketsNum = normalizeEventRegistrationMaxTickets(maxTickets);
2771
2947
  const showSpamProtection = spamProtectionEnabled ?? isSpamProtectionEnabled();
@@ -2861,11 +3037,13 @@ function EventRegistrationWizard(props) {
2861
3037
  const summaryPriceLabel = summaryEvent ? formatEventPriceDisplay(summaryEvent.pricing) : null;
2862
3038
  const summaryAvailabilityLabel = summaryEvent?.availableSpots === null || summaryEvent?.availableSpots === void 0 ? null : summaryEvent.availableSpots > 0 ? `${summaryEvent.availableSpots} spots left` : summaryEvent.waitlistEnabled ? "Waitlist available" : "Fully booked";
2863
3039
  const waitlistClaimRequiresPortalLogin = wizard.waitlistClaim.requiresPortalLogin && wizard.portalAuthState !== "authenticated" && wizard.portalAuthState !== "checking";
3040
+ const selectedProductEvent = wizard.selectedEvent ?? wizard.preSelectedEvent;
3041
+ const hasPassOrMembershipProducts = filterPassesForEvent(sitePasses?.passes, selectedProductEvent).length > 0 || filterMembershipsForEvent(siteMemberships?.memberships, selectedProductEvent).length > 0;
2864
3042
  const portalAuthCopy = waitlistClaimRequiresPortalLogin ? {
2865
3043
  ...EVENT_PORTAL_AUTH_COPY["waitlist-claim"],
2866
3044
  description: wizard.waitlistClaim.loginMessage ?? "Log in to continue with your waitlist claim."
2867
3045
  } : EVENT_PORTAL_AUTH_COPY.membership;
2868
- const showPortalAuthPrompt = waitlistClaimRequiresPortalLogin || wizard.step === "select-tickets" && wizard.portalAuthState !== "authenticated" && wizard.portalAuthState !== "checking" && summaryEventPricingType !== "free";
3046
+ const showPortalAuthPrompt = waitlistClaimRequiresPortalLogin || wizard.step === "select-tickets" && wizard.portalAuthState !== "authenticated" && wizard.portalAuthState !== "checking" && hasPassOrMembershipProducts && summaryEventPricingType !== "free";
2869
3047
  const renderRegistrationSurface = (variant) => /* @__PURE__ */ jsxs("div", { className: `er-container${variant === "overlay" ? " er-container--overlay" : ""}`, children: [
2870
3048
  isWizardStep && /* @__PURE__ */ jsxs("div", { className: "er-payment-layout er-payment-layout--no-sidebar", children: [
2871
3049
  /* @__PURE__ */ jsxs("div", { className: "er-payment-layout-main", children: [
@@ -3089,20 +3267,6 @@ var EventRegistrationIslandClient = (props) => {
3089
3267
  };
3090
3268
 
3091
3269
  // ../blocks/src/system/runtime/nodes/event-details/logic.ts
3092
- function isCategoryEligible(eligibleCategoryIds, eventCategoryId) {
3093
- const categories = eligibleCategoryIds ?? [];
3094
- if (categories.length === 0) return true;
3095
- if (!eventCategoryId) return false;
3096
- return categories.includes(eventCategoryId);
3097
- }
3098
- function passCoversEvent(args, event) {
3099
- if (!event.acceptsPasses) return false;
3100
- return isCategoryEligible(args.eligibleCategoryIds, event.eventCategoryId);
3101
- }
3102
- function membershipCoversEvent(args, event) {
3103
- if (!event.acceptsMemberships) return false;
3104
- return isCategoryEligible(args.eligibleCategoryIds, event.eventCategoryId);
3105
- }
3106
3270
  function parseLimit(value, fallback) {
3107
3271
  const n = typeof value === "string" ? parseInt(value, 10) : typeof value === "number" ? value : NaN;
3108
3272
  return Number.isFinite(n) && n > 0 ? n : fallback;
@@ -3161,30 +3325,6 @@ function selectEventDetails(args) {
3161
3325
  }).slice(0, otherLimit) : [];
3162
3326
  return { mode, selected, otherDates, timeZone };
3163
3327
  }
3164
- function filterPassesForEvent(sitePasses, event) {
3165
- if (!sitePasses || !event) return [];
3166
- if (event.requiresRegistration === false) return [];
3167
- const acceptsPasses = event.acceptsPasses ?? true;
3168
- const eventCategoryId = event.eventCategory?.id ?? null;
3169
- return sitePasses.filter(
3170
- (pass) => pass.productUseCase === "event_pass" && passCoversEvent(
3171
- { eligibleCategoryIds: pass.eligibleCategoryIds },
3172
- { acceptsPasses, eventCategoryId }
3173
- )
3174
- );
3175
- }
3176
- function filterMembershipsForEvent(siteMemberships, event) {
3177
- if (!siteMemberships || !event) return [];
3178
- if (event.requiresRegistration === false) return [];
3179
- const acceptsMemberships = event.acceptsMemberships ?? true;
3180
- const eventCategoryId = event.eventCategory?.id ?? null;
3181
- return siteMemberships.filter(
3182
- (membership) => membershipCoversEvent(
3183
- { eligibleCategoryIds: membership.eligibleCategoryIds },
3184
- { acceptsMemberships, eventCategoryId }
3185
- )
3186
- );
3187
- }
3188
3328
  function CoursePricingDisplay({
3189
3329
  pricing,
3190
3330
  acceptedItems
@@ -3697,9 +3837,74 @@ var EventPaginatedListView = ({
3697
3837
  }
3698
3838
  );
3699
3839
  };
3840
+
3841
+ // ../blocks/src/system/runtime/hooks/loadStateError.ts
3842
+ function toError(error, fallbackMessage) {
3843
+ return error instanceof Error ? error : new Error(fallbackMessage);
3844
+ }
3845
+
3846
+ // ../blocks/src/system/runtime/hooks/useEventPagination.state.ts
3847
+ function createInitialEventPaginationLoadState(events, pageSize) {
3848
+ return {
3849
+ kind: "ready",
3850
+ events,
3851
+ hasMore: hasMoreEventPages(events, pageSize)
3852
+ };
3853
+ }
3854
+ function eventPaginationLoadReducer(state, action) {
3855
+ switch (action.type) {
3856
+ case "started":
3857
+ return {
3858
+ kind: "loading",
3859
+ events: state.events,
3860
+ hasMore: action.reset ? true : state.hasMore
3861
+ };
3862
+ case "succeeded":
3863
+ return {
3864
+ kind: "ready",
3865
+ events: action.events,
3866
+ hasMore: action.hasMore
3867
+ };
3868
+ case "failed":
3869
+ return {
3870
+ kind: "error",
3871
+ events: state.events,
3872
+ hasMore: state.hasMore,
3873
+ error: action.error
3874
+ };
3875
+ case "synced":
3876
+ return createInitialEventPaginationLoadState(action.events, action.pageSize);
3877
+ default:
3878
+ return assertNever(action);
3879
+ }
3880
+ }
3700
3881
  function getEventIdentity(event) {
3701
3882
  return event.occurrenceId || event.id;
3702
3883
  }
3884
+ function mergeEventPaginationEvents(existingEvents, newEvents) {
3885
+ const existingIds = new Set(existingEvents.map(getEventIdentity));
3886
+ const uniqueNew = newEvents.filter(
3887
+ (event) => !existingIds.has(getEventIdentity(event))
3888
+ );
3889
+ return [...existingEvents, ...uniqueNew];
3890
+ }
3891
+ function toEventPaginationLoadError(error) {
3892
+ return toError(error, "Unknown error");
3893
+ }
3894
+ function getEventPaginationEvents(state) {
3895
+ return state.events;
3896
+ }
3897
+ function isEventPaginationLoading(state) {
3898
+ return state.kind === "loading";
3899
+ }
3900
+ function getEventPaginationError(state) {
3901
+ return state.kind === "error" ? state.error : null;
3902
+ }
3903
+ function hasMoreEventPages(events, pageSize) {
3904
+ return events.length >= pageSize;
3905
+ }
3906
+
3907
+ // ../blocks/src/system/runtime/hooks/useEventPagination.ts
3703
3908
  function getEventsKey(events) {
3704
3909
  return events.map((e) => `${getEventIdentity(e)}:${e.startsAt}`).join("|");
3705
3910
  }
@@ -3722,10 +3927,15 @@ function useEventPagination({
3722
3927
  useEffect(() => {
3723
3928
  initialEventsRef.current = initialEvents;
3724
3929
  }, [initialEventsKey]);
3725
- const [events, setEvents] = useState(initialEvents);
3726
- const [loading, setLoading] = useState(false);
3727
- const [error, setError] = useState(null);
3728
- const [hasMore, setHasMore] = useState(initialEvents.length >= pageSize);
3930
+ const [loadState, dispatchLoadState] = useReducer(
3931
+ eventPaginationLoadReducer,
3932
+ { events: initialEvents, pageSize },
3933
+ ({ events: events2, pageSize: initialPageSize }) => createInitialEventPaginationLoadState(events2, initialPageSize)
3934
+ );
3935
+ const events = getEventPaginationEvents(loadState);
3936
+ const loading = isEventPaginationLoading(loadState);
3937
+ const error = getEventPaginationError(loadState);
3938
+ const hasMore = loadState.hasMore;
3729
3939
  const normalizedCategoryIds = normalizeCsvString(filters?.categoryIds);
3730
3940
  const normalizedStaffMemberId = normalizeOptionalId(filters?.staffMemberId);
3731
3941
  const normalizedVenueId = normalizeOptionalId(filters?.venueId);
@@ -3750,9 +3960,11 @@ function useEventPagination({
3750
3960
  if (loadingRef.current) return;
3751
3961
  if (!hasMoreRef.current && !options.reset) return;
3752
3962
  const currentRequestId = ++requestIdRef.current;
3753
- setLoading(true);
3963
+ dispatchLoadState({ type: "started", reset: options.reset });
3754
3964
  loadingRef.current = true;
3755
- setError(null);
3965
+ if (options.reset) {
3966
+ hasMoreRef.current = true;
3967
+ }
3756
3968
  try {
3757
3969
  const currentEvents = eventsRef.current;
3758
3970
  const lastEvent = options.reset ? void 0 : currentEvents[currentEvents.length - 1];
@@ -3773,29 +3985,25 @@ function useEventPagination({
3773
3985
  venueId: normalizedVenueId ?? void 0
3774
3986
  });
3775
3987
  if (currentRequestId === requestIdRef.current) {
3776
- if (options.reset) {
3777
- setEvents(newEvents);
3778
- eventsRef.current = newEvents;
3779
- } else {
3780
- setEvents((prev) => {
3781
- const existingIds = new Set(prev.map(getEventIdentity));
3782
- const uniqueNew = newEvents.filter((e) => !existingIds.has(getEventIdentity(e)));
3783
- const updated = [...prev, ...uniqueNew];
3784
- eventsRef.current = updated;
3785
- return updated;
3786
- });
3787
- }
3788
- const nextHasMore = newEvents.length >= pageSize;
3789
- setHasMore(nextHasMore);
3988
+ const nextEvents = options.reset ? newEvents : mergeEventPaginationEvents(eventsRef.current, newEvents);
3989
+ const nextHasMore = hasMoreEventPages(newEvents, pageSize);
3990
+ dispatchLoadState({
3991
+ type: "succeeded",
3992
+ events: nextEvents,
3993
+ hasMore: nextHasMore
3994
+ });
3995
+ eventsRef.current = [...nextEvents];
3790
3996
  hasMoreRef.current = nextHasMore;
3791
3997
  }
3792
3998
  } catch (err) {
3793
3999
  if (currentRequestId === requestIdRef.current) {
3794
- setError(err instanceof Error ? err : new Error("Unknown error"));
4000
+ dispatchLoadState({
4001
+ type: "failed",
4002
+ error: toEventPaginationLoadError(err)
4003
+ });
3795
4004
  }
3796
4005
  } finally {
3797
4006
  if (currentRequestId === requestIdRef.current) {
3798
- setLoading(false);
3799
4007
  loadingRef.current = false;
3800
4008
  }
3801
4009
  }
@@ -3837,19 +4045,20 @@ function useEventPagination({
3837
4045
  try {
3838
4046
  if (filtersMatchInitial) {
3839
4047
  if (!prevFiltersMatchInitial || prevInitialEventsKey !== initialEventsKey) {
3840
- setEvents(latestInitialEvents);
4048
+ dispatchLoadState({
4049
+ type: "synced",
4050
+ events: latestInitialEvents,
4051
+ pageSize
4052
+ });
3841
4053
  eventsRef.current = latestInitialEvents;
3842
4054
  }
3843
- const nextHasMore = latestInitialEvents.length >= pageSize;
4055
+ const nextHasMore = hasMoreEventPages(latestInitialEvents, pageSize);
3844
4056
  if (hasMoreRef.current !== nextHasMore) {
3845
- setHasMore(nextHasMore);
3846
4057
  hasMoreRef.current = nextHasMore;
3847
4058
  }
3848
- if (error !== null) setError(null);
3849
4059
  return;
3850
4060
  }
3851
4061
  if (prevFiltersMatchInitial || prevFiltersKey !== filtersKey) {
3852
- setHasMore(true);
3853
4062
  hasMoreRef.current = true;
3854
4063
  void fetchPage({ reset: true });
3855
4064
  }
@@ -3858,7 +4067,7 @@ function useEventPagination({
3858
4067
  prevInitialEventsKeyRef.current = initialEventsKey;
3859
4068
  prevFiltersKeyRef.current = filtersKey;
3860
4069
  }
3861
- }, [error, fetchPage, filtersKey, filtersMatchInitial, initialEventsKey, pageSize]);
4070
+ }, [fetchPage, filtersKey, filtersMatchInitial, initialEventsKey, pageSize]);
3862
4071
  return {
3863
4072
  events,
3864
4073
  loading,
@@ -3867,6 +4076,43 @@ function useEventPagination({
3867
4076
  loadMore
3868
4077
  };
3869
4078
  }
4079
+
4080
+ // ../blocks/src/system/runtime/hooks/useEventFilters.state.ts
4081
+ var EMPTY_EVENT_FILTERS = Object.freeze({
4082
+ categories: [],
4083
+ venues: [],
4084
+ staffMembers: [],
4085
+ labels: Object.freeze({ courseOption: "Course" })
4086
+ });
4087
+ function createInitialEventFiltersLoadState() {
4088
+ return { kind: "idle", filters: EMPTY_EVENT_FILTERS };
4089
+ }
4090
+ function eventFiltersLoadReducer(state, action) {
4091
+ switch (action.type) {
4092
+ case "started":
4093
+ return { kind: "loading", filters: state.filters };
4094
+ case "succeeded":
4095
+ return { kind: "loaded", filters: action.filters };
4096
+ case "failed":
4097
+ return { kind: "error", filters: state.filters, error: action.error };
4098
+ default:
4099
+ return assertNever(action);
4100
+ }
4101
+ }
4102
+ function toEventFiltersLoadError(error) {
4103
+ return toError(error, "Failed to load filters");
4104
+ }
4105
+ function getEventFiltersData(state) {
4106
+ return state.filters;
4107
+ }
4108
+ function isEventFiltersLoading(state) {
4109
+ return state.kind === "loading";
4110
+ }
4111
+ function getEventFiltersError(state) {
4112
+ return state.kind === "error" ? state.error : null;
4113
+ }
4114
+
4115
+ // ../blocks/src/system/runtime/hooks/useEventFilters.ts
3870
4116
  function useEventFilters({
3871
4117
  showCategoryFilter = "auto",
3872
4118
  showVenueFilter = false,
@@ -3880,14 +4126,14 @@ function useEventFilters({
3880
4126
  preFilterScheduleScope
3881
4127
  } = {}) {
3882
4128
  const api = useBlockApi();
3883
- const [filters, setFilters] = useState({
3884
- categories: [],
3885
- venues: [],
3886
- staffMembers: [],
3887
- labels: { courseOption: "Course" }
3888
- });
3889
- const [loading, setLoading] = useState(false);
3890
- const [error, setError] = useState(null);
4129
+ const [loadState, dispatchLoadState] = useReducer(
4130
+ eventFiltersLoadReducer,
4131
+ void 0,
4132
+ createInitialEventFiltersLoadState
4133
+ );
4134
+ const filters = getEventFiltersData(loadState);
4135
+ const loading = isEventFiltersLoading(loadState);
4136
+ const error = getEventFiltersError(loadState);
3891
4137
  const [selectedKind, setSelectedKindState] = useState("all");
3892
4138
  const [selectedCategoryId, setSelectedCategoryId] = useState("all");
3893
4139
  const [selectedStaffMemberId, setSelectedStaffMemberId] = useState("all");
@@ -3922,7 +4168,7 @@ function useEventFilters({
3922
4168
  const needFilters = showCategoryFilter !== "never" && fixedKind !== "courses" || showVenueFilter || showStaffFilter;
3923
4169
  if (!needFilters) return;
3924
4170
  hasFetchedRef.current = true;
3925
- setLoading(true);
4171
+ dispatchLoadState({ type: "started" });
3926
4172
  api.getEventFilters({
3927
4173
  categoryIds: allowedCategoryIds.length > 0 ? allowedCategoryIds.join(",") : void 0,
3928
4174
  venueId: fixedVenueId ?? void 0,
@@ -3932,12 +4178,12 @@ function useEventFilters({
3932
4178
  eventPresets: fixedEventPresets,
3933
4179
  scheduleScope: fixedScheduleScope
3934
4180
  }).then((data) => {
3935
- setFilters(data);
3936
- setError(null);
4181
+ dispatchLoadState({ type: "succeeded", filters: data });
3937
4182
  }).catch((err) => {
3938
- setError(err instanceof Error ? err : new Error("Failed to load filters"));
3939
- }).finally(() => {
3940
- setLoading(false);
4183
+ dispatchLoadState({
4184
+ type: "failed",
4185
+ error: toEventFiltersLoadError(err)
4186
+ });
3941
4187
  });
3942
4188
  }, [
3943
4189
  allowedCategoryIds,
@@ -4269,6 +4515,31 @@ var TabBar = ({
4269
4515
  }
4270
4516
  );
4271
4517
  };
4518
+
4519
+ // ../blocks/src/system/runtime/hooks/useCalendarEvents.state.ts
4520
+ function calendarEventCacheLoadReducer(_state, action) {
4521
+ switch (action.type) {
4522
+ case "started":
4523
+ return { kind: "loading" };
4524
+ case "succeeded":
4525
+ return { kind: "idle" };
4526
+ case "failed":
4527
+ return { kind: "error", error: action.error };
4528
+ default:
4529
+ return assertNever(action);
4530
+ }
4531
+ }
4532
+ function toCalendarEventCacheLoadError(error) {
4533
+ return toError(error, "Unknown error");
4534
+ }
4535
+ function isCalendarEventCacheLoading(state) {
4536
+ return state.kind === "loading";
4537
+ }
4538
+ function getCalendarEventCacheError(state) {
4539
+ return state.kind === "error" ? state.error : null;
4540
+ }
4541
+
4542
+ // ../blocks/src/system/runtime/hooks/useCalendarEvents.ts
4272
4543
  var CALENDAR_FETCH_LIMIT = 200;
4273
4544
  function getMonthKey(date) {
4274
4545
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
@@ -4312,8 +4583,10 @@ function useCalendarEventCache({
4312
4583
  stage
4313
4584
  }) {
4314
4585
  const { getPublicEvents } = useBlockApi();
4315
- const [loading, setLoading] = useState(false);
4316
- const [error, setError] = useState(null);
4586
+ const [loadState, dispatchLoadState] = useReducer(
4587
+ calendarEventCacheLoadReducer,
4588
+ { kind: "idle" }
4589
+ );
4317
4590
  const [cacheVersion, setCacheVersion] = useState(0);
4318
4591
  const filtersKey = useMemo(
4319
4592
  () => getEventRuntimeFiltersKey(filters),
@@ -4358,8 +4631,7 @@ function useCalendarEventCache({
4358
4631
  if (monthsToFetch.length === 0) return;
4359
4632
  monthsToFetch.forEach((m) => fetchingRef.current.add(m));
4360
4633
  const currentRequestId = ++requestIdRef.current;
4361
- setLoading(true);
4362
- setError(null);
4634
+ dispatchLoadState({ type: "started" });
4363
4635
  try {
4364
4636
  const result = await getPublicEvents({
4365
4637
  from,
@@ -4391,16 +4663,17 @@ function useCalendarEventCache({
4391
4663
  }
4392
4664
  }
4393
4665
  setCacheVersion((v) => v + 1);
4666
+ dispatchLoadState({ type: "succeeded" });
4394
4667
  }
4395
4668
  } catch (err) {
4396
4669
  if (currentRequestId === requestIdRef.current) {
4397
- setError(err instanceof Error ? err : new Error("Unknown error"));
4670
+ dispatchLoadState({
4671
+ type: "failed",
4672
+ error: toCalendarEventCacheLoadError(err)
4673
+ });
4398
4674
  }
4399
4675
  } finally {
4400
4676
  monthsToFetch.forEach((m) => fetchingRef.current.delete(m));
4401
- if (currentRequestId === requestIdRef.current) {
4402
- setLoading(false);
4403
- }
4404
4677
  }
4405
4678
  }, [
4406
4679
  getPublicEvents,
@@ -4450,8 +4723,8 @@ function useCalendarEventCache({
4450
4723
  }, [viewDate, cacheVersion]);
4451
4724
  return {
4452
4725
  events,
4453
- loading,
4454
- error
4726
+ loading: isCalendarEventCacheLoading(loadState),
4727
+ error: getCalendarEventCacheError(loadState)
4455
4728
  };
4456
4729
  }
4457
4730
  function useCalendarEvents({
@@ -4846,6 +5119,23 @@ function EventModals({
4846
5119
  }
4847
5120
  return marker;
4848
5121
  }
5122
+
5123
+ // ../blocks/src/system/runtime/nodes/events/shared/calendarViewOptions.ts
5124
+ var monthOption = { id: "month", label: "Month" };
5125
+ var weekOption = { id: "week", label: "Week" };
5126
+ function resolveInitialCalendarView(input) {
5127
+ switch (input.calendarTabViews) {
5128
+ case "month":
5129
+ return "month";
5130
+ case "week":
5131
+ return "week";
5132
+ case "both":
5133
+ return input.defaultCalendarView ?? "month";
5134
+ }
5135
+ }
5136
+ function orderCalendarViewToggleOptions(defaultCalendarView) {
5137
+ return defaultCalendarView === "week" ? [weekOption, monthOption] : [monthOption, weekOption];
5138
+ }
4849
5139
  function toEventCombinedControllerProps(props) {
4850
5140
  return {
4851
5141
  events: props.render.hydration.prefetchedEvents ? [...props.render.display.events] : void 0,
@@ -4857,6 +5147,7 @@ function toEventCombinedControllerProps(props) {
4857
5147
  paginationAction: props.render.display.paginationAction,
4858
5148
  startOfWeek: props.render.display.startOfWeek,
4859
5149
  calendarTabViews: props.render.display.calendarTabViews,
5150
+ defaultCalendarView: props.render.display.defaultCalendarView,
4860
5151
  showFilters: props.render.display.showFilters,
4861
5152
  showCategoryFilter: props.render.display.showCategoryFilter,
4862
5153
  showVenueFilter: props.render.display.showVenueFilter,
@@ -4889,6 +5180,7 @@ var EventCombinedClient = ({
4889
5180
  // Calendar options
4890
5181
  startOfWeek = "monday",
4891
5182
  calendarTabViews = "both",
5183
+ defaultCalendarView,
4892
5184
  // Filtering options
4893
5185
  showFilters,
4894
5186
  showCategoryFilter = "auto",
@@ -4921,9 +5213,21 @@ var EventCombinedClient = ({
4921
5213
  const resolvedEventSurface = eventSurface ?? "all";
4922
5214
  const resolvedScheduleScope = scheduleScope ?? "any";
4923
5215
  const [activeTab, setActiveTab] = useState("list");
4924
- const [calendarView, setCalendarView] = useState(
4925
- calendarTabViews === "week" ? "week" : "month"
5216
+ const initialCalendarView = useMemo(
5217
+ () => resolveInitialCalendarView({
5218
+ calendarTabViews,
5219
+ defaultCalendarView
5220
+ }),
5221
+ [calendarTabViews, defaultCalendarView]
4926
5222
  );
5223
+ const [calendarView, setCalendarView] = useState(initialCalendarView);
5224
+ const calendarViewOptions = useMemo(
5225
+ () => orderCalendarViewToggleOptions(initialCalendarView),
5226
+ [initialCalendarView]
5227
+ );
5228
+ useEffect(() => {
5229
+ setCalendarView(initialCalendarView);
5230
+ }, [initialCalendarView]);
4927
5231
  const filtersIdBase = useId();
4928
5232
  const {
4929
5233
  categories,
@@ -5105,26 +5409,16 @@ var EventCombinedClient = ({
5105
5409
  ),
5106
5410
  activeTab === "calendar" && /* @__PURE__ */ jsxs(EventModalProvider, { children: [
5107
5411
  /* @__PURE__ */ jsxs("div", { className: "event-combined-content event-calendar", children: [
5108
- calendarTabViews === "both" && /* @__PURE__ */ jsxs("div", { className: "event-calendar-view-toggle", children: [
5109
- /* @__PURE__ */ jsx(
5110
- "button",
5111
- {
5112
- type: "button",
5113
- className: `event-calendar-view-btn ${calendarView === "month" ? "event-calendar-view-btn--active" : ""}`,
5114
- onClick: () => setCalendarView("month"),
5115
- children: "Month"
5116
- }
5117
- ),
5118
- /* @__PURE__ */ jsx(
5119
- "button",
5120
- {
5121
- type: "button",
5122
- className: `event-calendar-view-btn ${calendarView === "week" ? "event-calendar-view-btn--active" : ""}`,
5123
- onClick: () => setCalendarView("week"),
5124
- children: "Week"
5125
- }
5126
- )
5127
- ] }),
5412
+ calendarTabViews === "both" && /* @__PURE__ */ jsx("div", { className: "event-calendar-view-toggle", children: calendarViewOptions.map((option) => /* @__PURE__ */ jsx(
5413
+ "button",
5414
+ {
5415
+ type: "button",
5416
+ className: `event-calendar-view-btn ${calendarView === option.id ? "event-calendar-view-btn--active" : ""}`,
5417
+ onClick: () => setCalendarView(option.id),
5418
+ children: option.label
5419
+ },
5420
+ option.id
5421
+ )) }),
5128
5422
  /* @__PURE__ */ jsxs("div", { className: "event-calendar-header", children: [
5129
5423
  /* @__PURE__ */ jsxs("div", { className: "event-calendar-nav", children: [
5130
5424
  /* @__PURE__ */ jsx(
@@ -5464,6 +5758,7 @@ var EventCalendarClient = ({
5464
5758
  paginationAction: display.paginationAction,
5465
5759
  startOfWeek: display.startOfWeek,
5466
5760
  calendarTabViews: display.calendarTabViews,
5761
+ defaultCalendarView: display.defaultCalendarView,
5467
5762
  showFilters: display.showFilters,
5468
5763
  showCategoryFilter: display.showCategoryFilter,
5469
5764
  showVenueFilter: display.showVenueFilter,
@@ -5558,7 +5853,7 @@ var EventCalendarTimetableClient = ({ render }) => {
5558
5853
  };
5559
5854
  var EventCalendarGridClient = ({ render }) => {
5560
5855
  const { display, hydration } = render;
5561
- const calendarView = display.displayMode === "week" ? "week" : "month";
5856
+ const calendarView = display.defaultCalendarView;
5562
5857
  const { filtersNode, listFilters } = useEventCalendarFilterState(display);
5563
5858
  const calendarInitialEvents = usePrefetchedCalendarEvents(display, listFilters);
5564
5859
  const {
@@ -5598,7 +5893,15 @@ var EventCalendarGridClient = ({ render }) => {
5598
5893
  onPrevious: goToPrevious,
5599
5894
  onToday: goToToday,
5600
5895
  children: [
5601
- /* @__PURE__ */ jsxs("div", { className: "event-calendar-container", children: [
5896
+ viewport.kind === "week" ? /* @__PURE__ */ jsx(
5897
+ WeekAgendaView,
5898
+ {
5899
+ days: viewport.days,
5900
+ events,
5901
+ emptyMessage: display.emptyMessage,
5902
+ showCapacity: display.showCapacity
5903
+ }
5904
+ ) : /* @__PURE__ */ jsxs("div", { className: "event-calendar-container", children: [
5602
5905
  /* @__PURE__ */ jsx("div", { className: "event-calendar-day-headers", children: dayNames.map((day) => /* @__PURE__ */ jsx("div", { className: "event-calendar-day-header", children: day }, day)) }),
5603
5906
  /* @__PURE__ */ jsx("div", { className: "event-calendar-grid", children: viewport.days.map((date) => {
5604
5907
  const dateKey = formatDateKey(date);
@@ -5614,7 +5917,7 @@ var EventCalendarGridClient = ({ render }) => {
5614
5917
  );
5615
5918
  }) })
5616
5919
  ] }),
5617
- events.length === 0 && !loading && !error ? /* @__PURE__ */ jsx("p", { className: "event-calendar-empty", children: display.emptyMessage }) : null
5920
+ viewport.kind === "month" && events.length === 0 && !loading && !error ? /* @__PURE__ */ jsx("p", { className: "event-calendar-empty", children: display.emptyMessage }) : null
5618
5921
  ]
5619
5922
  }
5620
5923
  ),