@riverbankcms/sdk 0.140.0 → 0.141.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 (112) hide show
  1. package/dist/{PreviewEditorSidebar-CUyTzd5z.mjs → PreviewEditorSidebar-Q-fy9GYw.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-Agkw4v5i.mjs → PreviewEditorUI-LYGzgk85.mjs} +2 -2
  3. package/dist/{SdkPreviewModeRuntime-DdbeAdS8.mjs → SdkPreviewModeRuntime-CoPYI5Jq.mjs} +72 -46
  4. package/dist/{SiteChromeCustomizeContext-CqGOz-Kv.mjs → SiteChromeCustomizeContext-D8LePX8x.mjs} +681 -196
  5. package/dist/_dts/api/src/contentRuntime.d.ts +12 -31
  6. package/dist/_dts/api/src/domainConnection.d.ts +4 -0
  7. package/dist/_dts/api/src/footerCompositionContracts.d.ts +25 -0
  8. package/dist/_dts/api/src/index.d.ts +1 -1
  9. package/dist/_dts/api/src/launchReadiness.d.ts +1 -0
  10. package/dist/_dts/api/src/navigation/dashboardSiteNav.d.ts +2 -1
  11. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +3 -26
  12. package/dist/_dts/api/src/siteOnboarding.d.ts +7 -0
  13. package/dist/_dts/billing/src/site-arrangements.d.ts +12 -3
  14. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -0
  15. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +2 -0
  16. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +2 -0
  17. package/dist/_dts/blocks/src/system/blocks/events/eventSelectionFields.d.ts +122 -0
  18. package/dist/_dts/blocks/src/system/blocks/events/shared/calendarWindow.d.ts +2 -1
  19. package/dist/_dts/blocks/src/system/blocks/events/shared/eventSelection.d.ts +11 -0
  20. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +2 -2
  21. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +47 -47
  22. package/dist/_dts/blocks/src/system/data/prefetchBlockData.d.ts +5 -0
  23. package/dist/_dts/blocks/src/system/data/utils.d.ts +1 -1
  24. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +27 -1
  25. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +12 -180
  26. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +6 -90
  27. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.d.ts +2 -1
  28. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +5 -1
  29. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +4 -0
  30. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.state.d.ts +5 -0
  31. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.d.ts +3 -0
  32. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.d.ts +10 -3
  33. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventCheckoutHandoffRestore.d.ts +9 -0
  34. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +4 -5
  35. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useSettledCommerceView.d.ts +37 -0
  36. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +4 -3
  37. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +3 -0
  38. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +11 -101
  39. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +7 -2
  40. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listOptions.d.ts +2 -0
  41. package/dist/_dts/blocks/src/system/transforms/registry/eventCalendar.d.ts +12 -0
  42. package/dist/_dts/commerce/src/purchase/bookingInstalmentSchedule.d.ts +4 -0
  43. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +3 -0
  44. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +27 -1
  45. package/dist/_dts/sdk/src/public-api/contracts.d.ts +1 -1
  46. package/dist/_dts/sdk/src/version.d.ts +1 -1
  47. package/dist/_dts/theme-core/src/ThemeFontLoader.d.ts +17 -1
  48. package/dist/_dts/theme-core/src/buttons/affordanceSuppression.d.ts +17 -0
  49. package/dist/_dts/theme-core/src/buttons/buttonColourContract.d.ts +1 -1
  50. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +16 -0
  51. package/dist/_dts/theme-core/src/buttons/generateButtonCss.d.ts +0 -6
  52. package/dist/_dts/theme-core/src/buttons/resolvedButtonCss.d.ts +4 -4
  53. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  54. package/dist/_dts/theme-core/src/hosted-booking-appearance.d.ts +54 -12
  55. package/dist/_dts/theme-core/src/index.d.ts +1 -1
  56. package/dist/client/{BookingConsentAgreement-CuKa82V4.mjs → BookingConsentAgreement-xJeYNdnb.mjs} +2 -2
  57. package/dist/client/{DiscountCodeDisclosure-BbYieKWB.mjs → DiscountCodeDisclosure-DdT6uzl9.mjs} +1 -1
  58. package/dist/client/{EventCombined.client-LTfR1Aby.mjs → EventCombined.client-Cp28uYuM.mjs} +11 -15
  59. package/dist/client/{EventListing.client-DUHpYSuo.mjs → EventListing.client-CD6AJsMr.mjs} +4 -17
  60. package/dist/client/{LeafletStaticMap-CHRupL6m.mjs → LeafletStaticMap-DBsAi9-e.mjs} +1 -1
  61. package/dist/client/{accordion-6HiIFxNL.mjs → accordion-6dwbOKYR.mjs} +1 -1
  62. package/dist/client/{bookingForm-Dlmid43H.mjs → bookingForm-CZE9_qPQ.mjs} +5 -5
  63. package/dist/client/bookings.mjs +175 -93
  64. package/dist/client/{carousel-DmkZRRq_.mjs → carousel-7VHGQARz.mjs} +1 -1
  65. package/dist/client/{cart-CIC24330.mjs → cart-Qg_mvQhh.mjs} +3 -3
  66. package/dist/client/{checkout-D1Zw9imo.mjs → checkout-D84rpgdr.mjs} +3 -3
  67. package/dist/client/client.mjs +602 -139
  68. package/dist/client/{context-Cy1OayHx.mjs → context-Ctp3T0Wr.mjs} +1 -1
  69. package/dist/client/{dates-aDcfoLHr.mjs → dates-DJKFcI_N.mjs} +2 -2
  70. package/dist/client/{eventCalendar-FQxMPAjf.mjs → eventCalendar-CK31z3vs.mjs} +11 -7
  71. package/dist/client/{eventCombined-Dr3ac6Hb.mjs → eventCombined-DiXd-ewn.mjs} +3 -3
  72. package/dist/client/{eventDetails-D-AzUHFQ.mjs → eventDetails-CTRgt2DK.mjs} +4 -4
  73. package/dist/client/{eventListing-B3XxBf3i.mjs → eventListing-Dy9vi_j_.mjs} +3 -3
  74. package/dist/client/{eventRegistration-I6EaokFD.mjs → eventRegistration-CnalYMr2.mjs} +124 -31
  75. package/dist/client/{form-BbWckVWY.mjs → form-eUiMveTT.mjs} +2 -2
  76. package/dist/client/{headerSection-C9qU4Y7x.mjs → headerSection-Dy9kQpB1.mjs} +2 -2
  77. package/dist/client/hooks.mjs +247 -32
  78. package/dist/client/{locationMap-CLCShvlG.mjs → locationMap-DalCmWU0.mjs} +2 -2
  79. package/dist/client/{newsletterForm-Briukxzi.mjs → newsletterForm-SDDPvhS0.mjs} +23 -10
  80. package/dist/client/{pricing-Copadu-2.mjs → pricing-OcMz4SnX.mjs} +1 -1
  81. package/dist/client/{productDetail-oujlRd-r.mjs → productDetail-BQrgHElM.mjs} +3 -3
  82. package/dist/client/{productList-BRiIRUcd.mjs → productList-OnPn_UJj.mjs} +3 -3
  83. package/dist/client/{propsDecoder-CB2KS_ko.mjs → propsDecoder-zBdsnS-N.mjs} +38 -8
  84. package/dist/client/rendering/client.mjs +446 -121
  85. package/dist/client/rendering/islands.mjs +17 -17
  86. package/dist/client/rendering.mjs +601 -138
  87. package/dist/client/{scrollToBlock-B1IS1_ua.mjs → scrollToBlock-BNM4Ob2Y.mjs} +28 -11
  88. package/dist/client/{shop-Vn6yNFED.mjs → shop-Bv1fPTwQ.mjs} +6 -6
  89. package/dist/client/{shop-commerce-BVTqipYp.mjs → shop-commerce-D4KNGaW8.mjs} +5 -5
  90. package/dist/client/{shop-commerce-store-BVnJVy7v.mjs → shop-commerce-store-2N5EV0Rc.mjs} +1 -1
  91. package/dist/client/{shopShared-COIeK77T.mjs → shopShared-DvJGdHTV.mjs} +3 -3
  92. package/dist/client/{useEventFilters-DzIUcS9n.mjs → useEventFilters-BBBvGDHQ.mjs} +17 -11
  93. package/dist/preview-next/client/runtime.mjs +3 -3
  94. package/dist/preview-next/editor-chrome.css +4 -8
  95. package/dist/{sdk-runtime-CnCLvZRv.mjs → sdk-runtime-Defnbfzw.mjs} +1 -1
  96. package/dist/{separator-DKDRJ1oH.mjs → separator-CZXO3Sb0.mjs} +1 -1
  97. package/dist/server/components.mjs +384 -62
  98. package/dist/server/config-validation.mjs +232 -26
  99. package/dist/server/config.mjs +232 -26
  100. package/dist/server/data.mjs +247 -32
  101. package/dist/server/index.mjs +1 -1
  102. package/dist/server/next.mjs +400 -69
  103. package/dist/server/page-converter.mjs +189 -25
  104. package/dist/server/prebuild.mjs +1 -1
  105. package/dist/server/rendering/server.mjs +399 -68
  106. package/dist/server/rendering.mjs +399 -68
  107. package/dist/server/routing.mjs +261 -33
  108. package/dist/server/server.mjs +248 -33
  109. package/dist/server/theme-bridge.mjs +47 -15
  110. package/dist/server/theme.mjs +1 -1
  111. package/dist/styles/index.css +28 -2
  112. package/package.json +1 -1
@@ -1649,30 +1649,30 @@ function parseMailingListPlacementTargeting(value) {
1649
1649
  }
1650
1650
  }
1651
1651
  function parseMailingListVisitorSelection(value) {
1652
- if (!isRecord$41(value)) return visitorSelectionError("shape");
1652
+ if (!isRecord$41(value)) return visitorSelectionError$1("shape");
1653
1653
  switch (value.provider) {
1654
1654
  case "native": {
1655
1655
  const topicIds = parseVisitorIds(value.topicIds, parseNewsletterListId);
1656
- return topicIds === null ? visitorSelectionError("targets") : ok$3({
1656
+ return topicIds === null ? visitorSelectionError$1("targets") : ok$3({
1657
1657
  provider: "native",
1658
1658
  topicIds
1659
1659
  });
1660
1660
  }
1661
1661
  case "brevo": {
1662
1662
  const listIds = parseVisitorIds(value.listIds, parseBrevoListId);
1663
- return listIds === null ? visitorSelectionError("targets") : ok$3({
1663
+ return listIds === null ? visitorSelectionError$1("targets") : ok$3({
1664
1664
  provider: "brevo",
1665
1665
  listIds
1666
1666
  });
1667
1667
  }
1668
1668
  case "mailchimp": {
1669
1669
  const interestIds = parseVisitorIds(value.interestIds, parseMailchimpInterestId);
1670
- return interestIds === null ? visitorSelectionError("targets") : ok$3({
1670
+ return interestIds === null ? visitorSelectionError$1("targets") : ok$3({
1671
1671
  provider: "mailchimp",
1672
1672
  interestIds
1673
1673
  });
1674
1674
  }
1675
- default: return visitorSelectionError("provider");
1675
+ default: return visitorSelectionError$1("provider");
1676
1676
  }
1677
1677
  }
1678
1678
  function parseNativeTargeting(selection) {
@@ -1791,7 +1791,7 @@ function targetingError(field) {
1791
1791
  field
1792
1792
  });
1793
1793
  }
1794
- function visitorSelectionError(field) {
1794
+ function visitorSelectionError$1(field) {
1795
1795
  return err$3({
1796
1796
  tag: "invalid_mailing_list_visitor_selection",
1797
1797
  field
@@ -5146,7 +5146,7 @@ var init_buttonColourContract = __esmMin((() => {
5146
5146
  nonTextMinimumRatio: 3,
5147
5147
  gradientSamplesPerSegment: 20,
5148
5148
  alphaBackgrounds: "reject-without-known-surface",
5149
- disabled: "retain-full-colour-contract"
5149
+ disabled: "validated-colour-pair-with-muted-control-opacity"
5150
5150
  };
5151
5151
  }));
5152
5152
  //#endregion
@@ -5718,6 +5718,12 @@ var init_parseThemeForPersistence = __esmMin((() => {
5718
5718
  init_types$14();
5719
5719
  }));
5720
5720
  //#endregion
5721
+ //#region ../theme-core/src/buttons/affordanceSuppression.ts
5722
+ var AFFORDANCE_SUPPRESS_CLASS;
5723
+ var init_affordanceSuppression = __esmMin((() => {
5724
+ AFFORDANCE_SUPPRESS_CLASS = "rb-affordance-off";
5725
+ }));
5726
+ //#endregion
5721
5727
  //#region ../theme-core/src/buttons/classNames.ts
5722
5728
  /**
5723
5729
  * Parse content/runtime variant identifiers into the closed theme-button class
@@ -5750,7 +5756,29 @@ function themeButtonClassName(spec) {
5750
5756
  spec.extraClassName
5751
5757
  ].filter(Boolean).join(" ");
5752
5758
  }
5759
+ /**
5760
+ * Button classes for an authored button that renders its own trailing icon.
5761
+ *
5762
+ * A separate function rather than a flag on `themeButtonClassName`, because
5763
+ * there is exactly one caller and it should stay visible in a diff. The name
5764
+ * states what the caller knows to be true of its own markup — that it renders a
5765
+ * trailing icon — rather than what the theme does about it. The consequence is
5766
+ * the theme's to decide and to change; a caller naming the consequence would be
5767
+ * asserting a policy it does not own, and would quietly become a lie the moment
5768
+ * that policy moved.
5769
+ *
5770
+ * Do not reach for this to remove an arrow you simply do not want. A trailing
5771
+ * affordance is declared by the button style, and a block overriding that is the
5772
+ * defect this replaced.
5773
+ */
5774
+ function themeButtonClassNameWithTrailingIcon(spec) {
5775
+ return themeButtonClassName({
5776
+ ...spec,
5777
+ extraClassName: [spec.extraClassName, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ")
5778
+ });
5779
+ }
5753
5780
  var init_classNames = __esmMin((() => {
5781
+ init_affordanceSuppression();
5754
5782
  init_types$14();
5755
5783
  }));
5756
5784
  //#endregion
@@ -8290,8 +8318,7 @@ var init_resolvedButtonCss = __esmMin((() => {
8290
8318
  ["cursor", "not-allowed"],
8291
8319
  ["transform", "none"],
8292
8320
  ["box-shadow", "none"],
8293
- ["outline", "2px dashed currentColor"],
8294
- ["outline-offset", "-4px"]
8321
+ ["opacity", "0.55"]
8295
8322
  ];
8296
8323
  }));
8297
8324
  //#endregion
@@ -8629,7 +8656,7 @@ function resolveBoxShadow(variant, global, theme, tokens) {
8629
8656
  const color = shadowConfig.colorToken ? tokens.getColor(shadowConfig.colorToken) : void 0;
8630
8657
  return generateShadowValue$1(shadowConfig.elevation, shadowConfig.softness, shadowConfig.position ?? "bottom", color);
8631
8658
  }
8632
- var AFFORDANCE_SUPPRESS_CLASS, BUTTON_SIZE_NAMES, LETTER_SPACING_MAP, STRUCTURAL_DECLARATIONS;
8659
+ var BUTTON_SIZE_NAMES, LETTER_SPACING_MAP, STRUCTURAL_DECLARATIONS;
8633
8660
  var init_generateButtonCss = __esmMin((() => {
8634
8661
  init_types$14();
8635
8662
  init_classNames();
@@ -8644,7 +8671,7 @@ var init_generateButtonCss = __esmMin((() => {
8644
8671
  init_resolveButtonColourStates();
8645
8672
  init_resolvedButtonCss();
8646
8673
  init_buttonSurfaceContext();
8647
- AFFORDANCE_SUPPRESS_CLASS = "rb-affordance-off";
8674
+ init_affordanceSuppression();
8648
8675
  BUTTON_SIZE_NAMES = buttonSizeNameSchema.options;
8649
8676
  LETTER_SPACING_MAP = {
8650
8677
  tight: "-0.025em",
@@ -11111,14 +11138,12 @@ function generateVariantCSS(variant, themeId, cardClasses, tokens, theme) {
11111
11138
  const shadowValue = generateShadowValue(shadow);
11112
11139
  rules.push(`box-shadow: ${shadowValue}`);
11113
11140
  }
11114
- rules.push(`display: flex`);
11115
- rules.push(`flex-direction: column`);
11116
- rules.push(`position: relative`);
11117
- rules.push(`overflow: visible`);
11141
+ const structureSelector = cardClasses.map((cardClass) => `:where([data-theme-scope="${themeId}"]) :where(.${cardClass})`).join(",\n");
11118
11142
  const mediaRadius = MEDIA_CORNER_MAP[corners];
11119
11143
  const mediaRules = [`border-top-left-radius: ${mediaRadius}`, `border-top-right-radius: ${mediaRadius}`];
11120
11144
  const contentRules = [`padding: ${resolveContentPadding(variant)}`];
11121
11145
  return [
11146
+ `${structureSelector} {\n display: flex;\n flex-direction: column;\n position: relative;\n overflow: visible;\n}`,
11122
11147
  `${containerSelector} {\n ${rules.join(";\n ")};\n}`,
11123
11148
  ...cardDecorationPseudoRules(containerSelectors, variant.decorations, resolveColor),
11124
11149
  `${fallbackBackgroundSelector} {\n background: transparent;\n}`,
@@ -13838,6 +13863,7 @@ function calendarQueryKey(siteId, stage, filters) {
13838
13863
  filters.eventSurface ?? "all",
13839
13864
  normalizedCsv(filters.eventPresets),
13840
13865
  filters.scheduleScope ?? "any",
13866
+ ...filters.seriesIds === void 0 ? [] : [normalizedCsv(filters.seriesIds)],
13841
13867
  normalizedCsv(filters.categoryIds),
13842
13868
  normalizeCalendarFilterId(filters.venueId) ?? "",
13843
13869
  normalizeCalendarFilterId(filters.staffMemberId) ?? "",
@@ -13915,6 +13941,7 @@ var init_calendarWindow = __esmMin((() => {
13915
13941
  eventSurface: z$1.enum(eventSurfaceScopeValues).optional(),
13916
13942
  eventPresets: z$1.string().optional(),
13917
13943
  scheduleScope: z$1.enum(eventScheduleScopeValues).optional(),
13944
+ seriesIds: z$1.string().optional(),
13918
13945
  categoryIds: z$1.string().optional(),
13919
13946
  venueId: z$1.string().transform(normalizeCalendarFilterId).optional(),
13920
13947
  staffMemberId: z$1.string().transform(normalizeCalendarFilterId).optional()
@@ -24029,6 +24056,7 @@ var init_schema = __esmMin((() => {
24029
24056
  ];
24030
24057
  siteOptionSources = [
24031
24058
  "eventCategories",
24059
+ "eventSeries",
24032
24060
  "venues",
24033
24061
  "staffMembers"
24034
24062
  ];
@@ -28976,6 +29004,38 @@ var init_booking_form_interactive = __esmMin((() => {
28976
29004
  });
28977
29005
  }));
28978
29006
  //#endregion
29007
+ //#region ../blocks/src/system/blocks/events/shared/eventSelection.ts
29008
+ /** Invalid saved selections fail closed rather than widening discovery. */
29009
+ function resolveEventSelection(mode, value) {
29010
+ if (mode !== "selected") return { kind: "matching" };
29011
+ const candidates = Array.isArray(value) ? value : typeof value === "string" ? value.split(",").filter(Boolean) : [];
29012
+ const ids = [];
29013
+ for (const candidate of candidates) {
29014
+ if (typeof candidate !== "string") return {
29015
+ kind: "selected",
29016
+ seriesIds: []
29017
+ };
29018
+ const parsed = parseEventSeriesId(candidate.trim());
29019
+ if (!parsed.ok) return {
29020
+ kind: "selected",
29021
+ seriesIds: []
29022
+ };
29023
+ ids.push(parsed.value);
29024
+ }
29025
+ return {
29026
+ kind: "selected",
29027
+ seriesIds: [...new Set(ids)].sort()
29028
+ };
29029
+ }
29030
+ /** Undefined means discovery; an empty string is an explicitly empty selection. */
29031
+ function eventSeriesScopeCsv(value) {
29032
+ if (value == null) return void 0;
29033
+ return typeof value === "string" ? value : value.join(",");
29034
+ }
29035
+ var init_eventSelection = __esmMin((() => {
29036
+ init_src$2();
29037
+ }));
29038
+ //#endregion
28979
29039
  //#region ../blocks/src/system/runtime/nodes/events/domain/capacity.ts
28980
29040
  /**
28981
29041
  * Compute remaining spots for an event from `availableSpots` with a fallback
@@ -31660,12 +31720,12 @@ var init_EventCompactRow = __esmMin((() => {
31660
31720
  }), cta.hidden ? /* @__PURE__ */ jsx("span", {
31661
31721
  className: "event-compact-row-status",
31662
31722
  children: cta.label
31663
- }) : /* @__PURE__ */ jsxs("a", {
31723
+ }) : /* @__PURE__ */ jsx("a", {
31664
31724
  href: cta.href,
31665
31725
  target: cta.external ? "_blank" : void 0,
31666
31726
  rel: cta.external ? "noopener noreferrer" : void 0,
31667
31727
  className: `${buttonClass} event-compact-row-cta`,
31668
- children: [/* @__PURE__ */ jsx("span", { children: cta.label }), /* @__PURE__ */ jsx(ArrowRightIcon, { "aria-hidden": "true" })]
31728
+ children: /* @__PURE__ */ jsx("span", { children: cta.label })
31669
31729
  })]
31670
31730
  })]
31671
31731
  })]
@@ -31970,6 +32030,7 @@ function normalizeFilterId(value) {
31970
32030
  return id === "all" ? void 0 : id;
31971
32031
  }
31972
32032
  function buildEventRuntimeFilters(input) {
32033
+ if (input.seriesIds != null) return { seriesIds: input.seriesIds };
31973
32034
  const params = {};
31974
32035
  if (input.eventSurface && input.eventSurface !== "all") params.eventSurface = input.eventSurface;
31975
32036
  const eventPresets = normalizeCsvString(input.filterEventPresets);
@@ -31985,6 +32046,7 @@ function buildEventRuntimeFilters(input) {
31985
32046
  }
31986
32047
  function getEventRuntimeFiltersKey(filters) {
31987
32048
  return JSON.stringify({
32049
+ seriesIds: filters?.seriesIds == null ? null : [...new Set(filters.seriesIds.split(",").filter(Boolean))].sort().join(","),
31988
32050
  categoryIds: normalizeCsvString(filters?.categoryIds),
31989
32051
  staffMemberId: normalizeOptionalId(filters?.staffMemberId),
31990
32052
  venueId: normalizeOptionalId(filters?.venueId),
@@ -32045,11 +32107,15 @@ function buildEventCollectionDisplay(source) {
32045
32107
  };
32046
32108
  }
32047
32109
  function buildEventCollectionFilterDisplay(source) {
32048
- return {
32049
- showFilters: source.showFilters ?? true,
32050
- showCategoryFilter: source.showCategoryFilter ?? "auto",
32051
- showVenueFilter: source.showVenueFilter ?? false,
32052
- showStaffFilter: source.showStaffFilter ?? true,
32110
+ const selected = source.seriesIds != null;
32111
+ const matchingFilters = selected ? {
32112
+ eventSurface: "all",
32113
+ filterEventPresets: null,
32114
+ scheduleScope: "any",
32115
+ filterCategoryIds: null,
32116
+ filterStaffMemberId: null,
32117
+ filterVenueId: null
32118
+ } : {
32053
32119
  eventSurface: normalizeEventSurfaceScope(source.eventSurface),
32054
32120
  filterEventPresets: normalizeEventSurfacePresetsCsv(source.filterEventPresets),
32055
32121
  scheduleScope: normalizeEventScheduleScope(source.scheduleScope),
@@ -32057,6 +32123,14 @@ function buildEventCollectionFilterDisplay(source) {
32057
32123
  filterStaffMemberId: normalizeEventStaffMemberId(source.filterStaffMemberId),
32058
32124
  filterVenueId: normalizeEventVenueId(source.filterVenueId)
32059
32125
  };
32126
+ return {
32127
+ seriesIds: eventSeriesScopeCsv(source.seriesIds),
32128
+ showFilters: selected ? false : source.showFilters ?? true,
32129
+ showCategoryFilter: source.showCategoryFilter ?? "auto",
32130
+ showVenueFilter: source.showVenueFilter ?? false,
32131
+ showStaffFilter: source.showStaffFilter ?? true,
32132
+ ...matchingFilters
32133
+ };
32060
32134
  }
32061
32135
  function buildEventCollectionPresentationDisplay(source) {
32062
32136
  return {
@@ -32071,14 +32145,15 @@ function buildEventCollectionPresentationDisplay(source) {
32071
32145
  }
32072
32146
  function buildEventCollectionHydration(source, now = /* @__PURE__ */ new Date()) {
32073
32147
  const timeZone = source.calendarWindow?.scope.timeZone ?? toBookingTimeZone(source.bookingTimeZone);
32148
+ const selected = source.seriesIds != null;
32074
32149
  return {
32075
32150
  calendarWindow: source.calendarWindow ?? void 0,
32076
32151
  siteId: source.siteId,
32077
32152
  stage: source.stage,
32078
32153
  prefetchedEvents: source.events != null,
32079
- eventSurface: normalizeEventSurfaceScope(source.eventSurface),
32080
- filterEventPresets: normalizeEventSurfacePresetsCsv(source.filterEventPresets),
32081
- scheduleScope: normalizeEventScheduleScope(source.scheduleScope),
32154
+ eventSurface: selected ? "all" : normalizeEventSurfaceScope(source.eventSurface),
32155
+ filterEventPresets: selected ? null : normalizeEventSurfacePresetsCsv(source.filterEventPresets),
32156
+ scheduleScope: selected ? "any" : normalizeEventScheduleScope(source.scheduleScope),
32082
32157
  calendarContext: {
32083
32158
  timeZone,
32084
32159
  initialToday: source.calendarWindow?.initialToday ?? getLocalScheduleDate(now, timeZone)
@@ -32107,6 +32182,7 @@ function buildEventCollectionListingDisplay(display, prefetchedEvents, className
32107
32182
  }
32108
32183
  var eventSurfaceScopeSchema$1, eventScheduleScopeSchema$1, eventCollectionFilterSourceSchemaShape, eventCollectionSourceSchemaShape, eventCollectionDisplaySchemaShape, eventCollectionHydrationSchema;
32109
32184
  var init_eventCollectionContract = __esmMin((() => {
32185
+ init_eventSelection();
32110
32186
  init_calendarWindow();
32111
32187
  init_cards();
32112
32188
  init_src$2();
@@ -32125,6 +32201,7 @@ var init_eventCollectionContract = __esmMin((() => {
32125
32201
  eventSurface: eventSurfaceScopeSchema$1.nullable().optional(),
32126
32202
  filterEventPresets: z$1.union([z$1.string(), z$1.array(z$1.string())]).nullable().optional(),
32127
32203
  scheduleScope: eventScheduleScopeSchema$1.nullable().optional(),
32204
+ seriesIds: z$1.union([z$1.string(), z$1.array(z$1.string())]).nullable().optional(),
32128
32205
  filterCategoryIds: z$1.union([z$1.string(), z$1.array(z$1.string())]).nullable().optional(),
32129
32206
  filterStaffMemberId: z$1.string().nullable().optional(),
32130
32207
  filterVenueId: z$1.string().nullable().optional()
@@ -32171,6 +32248,7 @@ var init_eventCollectionContract = __esmMin((() => {
32171
32248
  eventSurface: eventSurfaceScopeSchema$1,
32172
32249
  filterEventPresets: z$1.string().nullable(),
32173
32250
  scheduleScope: eventScheduleScopeSchema$1,
32251
+ seriesIds: z$1.string().nullable().optional(),
32174
32252
  filterCategoryIds: z$1.string().nullable(),
32175
32253
  filterStaffMemberId: z$1.string().nullable(),
32176
32254
  filterVenueId: z$1.string().nullable(),
@@ -32216,6 +32294,7 @@ function buildEventListingInteractiveIslandProps(props) {
32216
32294
  }
32217
32295
  var cardOrientationSchema, eventSurfaceScopeSchema, eventScheduleScopeSchema, eventListingSourceSchema, eventListingDisplaySchema, eventListingHydrationSchema, eventListingRenderSchema, eventListingIslandMetaCodec, eventListingBlockRuntime, eventListingIslandMetaKeys, eventListingInteractiveIslandPropsCodec;
32218
32296
  var init_EventListing_interactive = __esmMin((() => {
32297
+ init_eventSelection();
32219
32298
  init_cards();
32220
32299
  init_schemas();
32221
32300
  init_shared$3();
@@ -32282,6 +32361,7 @@ var init_EventListing_interactive = __esmMin((() => {
32282
32361
  eventSurface: eventSurfaceScopeSchema,
32283
32362
  filterEventPresets: z$1.string().nullable(),
32284
32363
  scheduleScope: eventScheduleScopeSchema,
32364
+ seriesIds: z$1.string().nullable().optional(),
32285
32365
  filterCategoryIds: z$1.string().nullable().optional(),
32286
32366
  filterStaffMemberId: z$1.string().nullable().optional(),
32287
32367
  filterVenueId: z$1.string().nullable().optional(),
@@ -32342,6 +32422,7 @@ var init_EventListing_interactive = __esmMin((() => {
32342
32422
  eventSurface: normalizeEventSurfaceScope(source.eventSurface),
32343
32423
  filterEventPresets: normalizeEventSurfacePresetsCsv(source.filterEventPresets),
32344
32424
  scheduleScope: normalizeEventScheduleScope(source.scheduleScope),
32425
+ seriesIds: eventSeriesScopeCsv(source.seriesIds),
32345
32426
  filterCategoryIds: normalizeEventCategoryIdsCsv(source.filterCategoryIds),
32346
32427
  filterStaffMemberId: normalizeEventStaffMemberId(source.filterStaffMemberId),
32347
32428
  filterVenueId: normalizeEventVenueId(source.filterVenueId),
@@ -32415,6 +32496,7 @@ function buildEventCalendarListingRender(render, className = render.display.clas
32415
32496
  eventSurface: display.eventSurface,
32416
32497
  filterEventPresets: display.filterEventPresets,
32417
32498
  scheduleScope: display.scheduleScope,
32499
+ seriesIds: display.seriesIds,
32418
32500
  filterCategoryIds: display.filterCategoryIds,
32419
32501
  filterStaffMemberId: display.filterStaffMemberId,
32420
32502
  filterVenueId: display.filterVenueId,
@@ -96935,10 +97017,14 @@ function buildDiscountAvailabilityRequestPlan(options) {
96935
97017
  }
96936
97018
  };
96937
97019
  }
96938
- function discountAvailabilityStateFromResponse(response) {
96939
- if (!discountAvailabilityHasDiscounts(response)) return { tag: "unavailable" };
97020
+ function discountAvailabilityStateFromResponse(requestKey, response) {
97021
+ if (!discountAvailabilityHasDiscounts(response)) return {
97022
+ tag: "unavailable",
97023
+ requestKey
97024
+ };
96940
97025
  return {
96941
97026
  tag: "available",
97027
+ requestKey,
96942
97028
  manualCodeEntryAllowed: discountAvailabilityAllowsManualEntry(response),
96943
97029
  autoAppliedDiscount: getAutoAppliedDiscountPreview(response)
96944
97030
  };
@@ -96948,10 +97034,13 @@ function discountCodeUiReducer(state, event) {
96948
97034
  case "availability-disabled": return initialDiscountCodeUiState;
96949
97035
  case "availability-loading": return {
96950
97036
  ...state,
96951
- availability: { tag: "loading" }
97037
+ availability: {
97038
+ tag: "loading",
97039
+ previous: state.availability.tag === "available" || state.availability.tag === "unavailable" ? state.availability : state.availability.tag === "loading" ? state.availability.previous : null
97040
+ }
96952
97041
  };
96953
97042
  case "availability-loaded": {
96954
- const availability = discountAvailabilityStateFromResponse(event.response);
97043
+ const availability = discountAvailabilityStateFromResponse(event.requestKey, event.response);
96955
97044
  if (availability.tag !== "available" || !availability.manualCodeEntryAllowed) return {
96956
97045
  ...state,
96957
97046
  discountUiOpen: false,
@@ -96967,7 +97056,10 @@ function discountCodeUiReducer(state, event) {
96967
97056
  ...state,
96968
97057
  discountUiOpen: false,
96969
97058
  discountCode: "",
96970
- availability: { tag: "error" }
97059
+ availability: {
97060
+ tag: "error",
97061
+ requestKey: event.requestKey
97062
+ }
96971
97063
  };
96972
97064
  case "discount-code-changed": return {
96973
97065
  ...state,
@@ -97012,11 +97104,15 @@ function useDiscountCodeUi(options) {
97012
97104
  if (cancelled) return;
97013
97105
  dispatch({
97014
97106
  type: "availability-loaded",
97107
+ requestKey: requestPlan.key,
97015
97108
  response: res
97016
97109
  });
97017
97110
  } catch {
97018
97111
  if (cancelled) return;
97019
- dispatch({ type: "availability-failed" });
97112
+ dispatch({
97113
+ type: "availability-failed",
97114
+ requestKey: requestPlan.key
97115
+ });
97020
97116
  }
97021
97117
  }
97022
97118
  checkDiscountAvailability();
@@ -97025,8 +97121,9 @@ function useDiscountCodeUi(options) {
97025
97121
  };
97026
97122
  }, [options.api, requestPlan]);
97027
97123
  const availability = state.availability;
97028
- const isAvailable = availability.tag === "available";
97029
- const manualCodeEntryAllowed = isAvailable ? availability.manualCodeEntryAllowed : false;
97124
+ const settledAvailability = availability.tag === "loading" ? availability.previous : availability.tag === "available" || availability.tag === "unavailable" ? availability : null;
97125
+ const isAvailable = settledAvailability?.tag === "available";
97126
+ const manualCodeEntryAllowed = isAvailable ? settledAvailability.manualCodeEntryAllowed : false;
97030
97127
  return {
97031
97128
  discountUiOpen: state.discountUiOpen,
97032
97129
  setDiscountUiOpen: (isOpen) => dispatch({
@@ -97040,8 +97137,10 @@ function useDiscountCodeUi(options) {
97040
97137
  }),
97041
97138
  discountsAvailable: isAvailable,
97042
97139
  manualCodeEntryAllowed,
97043
- autoAppliedDiscount: isAvailable ? availability.autoAppliedDiscount : null,
97044
- discountsAvailableLoading: availability.tag === "loading"
97140
+ autoAppliedDiscount: isAvailable ? settledAvailability.autoAppliedDiscount : null,
97141
+ discountsAvailableLoading: availability.tag === "loading",
97142
+ discountAvailabilityRequestKey: requestPlan.key,
97143
+ settledDiscountAvailabilityRequestKey: availability.tag === "error" ? availability.requestKey : settledAvailability?.requestKey ?? null
97045
97144
  };
97046
97145
  }
97047
97146
  var init_useDiscountCodeUi = __esmMin((() => {
@@ -101784,16 +101883,19 @@ function eligibilityLookupReducer(state, action) {
101784
101883
  case "loading-started": return {
101785
101884
  tag: "loading",
101786
101885
  eligibility: state.eligibility,
101886
+ settledRequestKey: state.settledRequestKey,
101787
101887
  error: null
101788
101888
  };
101789
101889
  case "resolved": return {
101790
101890
  tag: "resolved",
101791
101891
  eligibility: action.eligibility,
101892
+ settledRequestKey: action.requestKey,
101792
101893
  error: null
101793
101894
  };
101794
101895
  case "failed": return {
101795
101896
  tag: "failed",
101796
101897
  eligibility: null,
101898
+ settledRequestKey: null,
101797
101899
  error: action.message
101798
101900
  };
101799
101901
  default: return assertNever$11(action);
@@ -101819,6 +101921,7 @@ var init_hooks_state = __esmMin((() => {
101819
101921
  initialEligibilityLookupState = {
101820
101922
  tag: "idle",
101821
101923
  eligibility: null,
101924
+ settledRequestKey: null,
101822
101925
  error: null
101823
101926
  };
101824
101927
  initialExistingRegistrationLookupState = {
@@ -101898,9 +102001,23 @@ function toRegistrationOptionsSubject(subject, attendanceMode) {
101898
102001
  function useEligibility(params) {
101899
102002
  return useEligibilityWithDeps(params, eventRegistrationHooksDeps);
101900
102003
  }
102004
+ function eligibilityRequestKey(params) {
102005
+ return JSON.stringify({
102006
+ enabled: params.enabled,
102007
+ refreshKey: params.refreshKey ?? 0,
102008
+ subject: params.subject,
102009
+ attendanceMode: params.attendanceMode ?? null,
102010
+ ticketSelections: params.ticketSelectionsKey,
102011
+ selectedSlidingAmount: params.selectedSlidingAmount ?? null
102012
+ });
102013
+ }
101901
102014
  function useEligibilityWithDeps(params, deps) {
101902
102015
  const api = deps.useBlockApi();
101903
102016
  const ticketSelectionsKey = JSON.stringify(normalizeTicketSelectionLines(params.ticketSelections));
102017
+ const requestKey = eligibilityRequestKey({
102018
+ ...params,
102019
+ ticketSelectionsKey
102020
+ });
101904
102021
  const [state, dispatch] = useReducer(eligibilityLookupReducer, initialEligibilityLookupState);
101905
102022
  const requestIdRef = useRef(0);
101906
102023
  useEffect(() => {
@@ -101933,7 +102050,8 @@ function useEligibilityWithDeps(params, deps) {
101933
102050
  if (cancelled || requestIdRef.current !== requestId) return;
101934
102051
  dispatch({
101935
102052
  type: "resolved",
101936
- eligibility: transformRegistrationOptionsResponse(result)
102053
+ eligibility: transformRegistrationOptionsResponse(result),
102054
+ requestKey
101937
102055
  });
101938
102056
  } catch {
101939
102057
  if (cancelled || requestIdRef.current !== requestId) return;
@@ -101962,6 +102080,8 @@ function useEligibilityWithDeps(params, deps) {
101962
102080
  return {
101963
102081
  state,
101964
102082
  eligibility: state.eligibility,
102083
+ settledRequestKey: state.settledRequestKey,
102084
+ requestKey,
101965
102085
  isLoading: state.tag === "loading",
101966
102086
  error: state.error,
101967
102087
  creditState
@@ -103563,6 +103683,71 @@ var init_useEventRegistrationSubmit = __esmMin((() => {
103563
103683
  };
103564
103684
  }));
103565
103685
  //#endregion
103686
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useSettledCommerceView.ts
103687
+ function buildCandidate(input) {
103688
+ if (!input.eligibilityIsSettled || !input.eligibility || !input.currentEvent) return null;
103689
+ return {
103690
+ eventSelectionId: input.currentEvent.selectionId,
103691
+ discountContext: resolveDiscountContext({
103692
+ paymentSelection: input.paymentSelection,
103693
+ event: input.currentEvent,
103694
+ eventRequiresPayment: input.eventRequiresPayment,
103695
+ ticketsCount: input.ticketsCount
103696
+ }),
103697
+ subtotalCents: input.eligibility.price,
103698
+ summaryLines: input.eligibility.ticketLines.map((line) => ({
103699
+ pricingOptionId: line.pricingOptionId,
103700
+ label: line.label,
103701
+ quantity: line.quantity,
103702
+ unitPriceCents: line.unitPriceCents,
103703
+ subtotalCents: line.subtotalCents
103704
+ }))
103705
+ };
103706
+ }
103707
+ function eligibilityIsSettled(result) {
103708
+ return result.settledRequestKey === result.requestKey;
103709
+ }
103710
+ function viewIsStale(view, currentEvent, eligibilityState) {
103711
+ return view.eventSelectionId !== currentEvent?.selectionId || eligibilityState?.tag === "failed" || eligibilityState?.tag === "idle";
103712
+ }
103713
+ function requestIsSettled(discountUi) {
103714
+ return discountUi.discountAvailabilityRequestKey === "disabled" || discountUi.settledDiscountAvailabilityRequestKey === discountUi.discountAvailabilityRequestKey;
103715
+ }
103716
+ function discountRequest(view) {
103717
+ const discountContext = view?.discountContext ?? null;
103718
+ return {
103719
+ discountContext,
103720
+ subtotalCents: discountContext?.type === "event" && view?.subtotalCents !== null ? view?.subtotalCents : void 0
103721
+ };
103722
+ }
103723
+ function useSettledCommerceView(input) {
103724
+ const candidate = buildCandidate({
103725
+ eligibilityIsSettled: eligibilityIsSettled(input.eligibilityResult),
103726
+ eligibility: input.eligibility,
103727
+ currentEvent: input.currentEvent,
103728
+ paymentSelection: input.paymentSelection,
103729
+ eventRequiresPayment: input.eventRequiresPayment,
103730
+ ticketsCount: input.ticketsCount
103731
+ });
103732
+ const settledRef = useRef(candidate);
103733
+ if (settledRef.current && viewIsStale(settledRef.current, input.currentEvent, input.eligibilityResult.state)) settledRef.current = null;
103734
+ const requestView = candidate ?? settledRef.current;
103735
+ const discountUi = input.useDiscountCodeUi({
103736
+ api: input.api,
103737
+ ...discountRequest(requestView)
103738
+ });
103739
+ if (candidate && requestIsSettled(discountUi)) settledRef.current = candidate;
103740
+ return {
103741
+ discountUi,
103742
+ discountContext: settledRef.current?.discountContext ?? null,
103743
+ ticketSelectionSubtotalCents: settledRef.current?.subtotalCents ?? null,
103744
+ ticketSelectionSummaryLines: settledRef.current?.summaryLines ?? []
103745
+ };
103746
+ }
103747
+ var init_useSettledCommerceView = __esmMin((() => {
103748
+ init_registrationDerivations();
103749
+ }));
103750
+ //#endregion
103566
103751
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.ts
103567
103752
  function getEventSelectionDefaults(event) {
103568
103753
  const suggestedAmount = getSlidingScaleForEvent(event)?.suggestedAmount;
@@ -103725,10 +103910,6 @@ function isSoldOutWithoutWaitlist(input) {
103725
103910
  var init_registrationCompletion = __esmMin((() => {}));
103726
103911
  //#endregion
103727
103912
  //#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
103728
- function resolveDiscountSubtotalCents(context, subtotalCents) {
103729
- if (context?.type !== "event" || subtotalCents === null) return void 0;
103730
- return subtotalCents;
103731
- }
103732
103913
  function usesTieredPricing(event) {
103733
103914
  return event !== null && event !== void 0 ? publicEventPricingStrategy(event.pricing) === "tiered" : false;
103734
103915
  }
@@ -104171,30 +104352,15 @@ function useEventRegistrationWizardWithDeps(options, deps) {
104171
104352
  }
104172
104353
  setStep("select-tickets");
104173
104354
  };
104174
- const discountContext = useMemo(() => resolveDiscountContext({
104175
- paymentSelection,
104176
- event: currentEvent,
104177
- eventRequiresPayment,
104178
- ticketsCount
104179
- }), [
104355
+ const { discountUi, discountContext, ticketSelectionSubtotalCents, ticketSelectionSummaryLines } = useSettledCommerceView({
104356
+ api,
104357
+ useDiscountCodeUi: deps.useDiscountCodeUi,
104358
+ eligibilityResult,
104359
+ eligibility,
104180
104360
  currentEvent,
104181
104361
  eventRequiresPayment,
104182
104362
  paymentSelection,
104183
104363
  ticketsCount
104184
- ]);
104185
- const ticketSelectionSubtotalCents = eligibility?.price ?? null;
104186
- const ticketSelectionSummaryLines = useMemo(() => eligibility?.ticketLines.map((line) => ({
104187
- pricingOptionId: line.pricingOptionId,
104188
- label: line.label,
104189
- quantity: line.quantity,
104190
- unitPriceCents: line.unitPriceCents,
104191
- subtotalCents: line.subtotalCents
104192
- })) ?? [], [eligibility]);
104193
- const discountSubtotalCents = resolveDiscountSubtotalCents(discountContext, ticketSelectionSubtotalCents);
104194
- const discountUi = deps.useDiscountCodeUi({
104195
- api,
104196
- discountContext,
104197
- subtotalCents: discountSubtotalCents
104198
104364
  });
104199
104365
  const selectionMethod = paymentSelection.method;
104200
104366
  const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
@@ -104373,6 +104539,7 @@ var init_useEventRegistrationWizard = __esmMin((() => {
104373
104539
  init_useEventRegistrationStripeReturn();
104374
104540
  init_useEventRegistrationSubmit();
104375
104541
  init_useDiscountCodeUi();
104542
+ init_useSettledCommerceView();
104376
104543
  init_utils();
104377
104544
  init_ticketSelectionLines();
104378
104545
  init_registrationStateMachine();
@@ -104395,6 +104562,38 @@ var init_useEventRegistrationWizard = __esmMin((() => {
104395
104562
  };
104396
104563
  }));
104397
104564
  //#endregion
104565
+ //#region ../blocks/src/system/runtime/nodes/event-registration/useEventCheckoutHandoffRestore.ts
104566
+ function eventRegistrationReloadTarget(location) {
104567
+ return `${location.pathname}${location.search}#${EVENT_REGISTRATION_ANCHOR_ID}`;
104568
+ }
104569
+ function reloadAtEventRegistration() {
104570
+ const target = eventRegistrationReloadTarget(window.location);
104571
+ window.history.replaceState(window.history.state, "", target);
104572
+ window.location.reload();
104573
+ }
104574
+ function useEventCheckoutHandoffRestore(active) {
104575
+ useEventCheckoutHandoffRestoreWithDeps(active, browserCheckoutHandoffRestoreDeps);
104576
+ }
104577
+ function useEventCheckoutHandoffRestoreWithDeps(active, deps) {
104578
+ useEffect(() => {
104579
+ if (!active) return;
104580
+ const handlePageShow = (event) => {
104581
+ if (event.persisted) deps.reloadAtRegistration();
104582
+ };
104583
+ deps.addPageShowListener(handlePageShow);
104584
+ return () => deps.removePageShowListener(handlePageShow);
104585
+ }, [active, deps]);
104586
+ }
104587
+ var browserCheckoutHandoffRestoreDeps;
104588
+ var init_useEventCheckoutHandoffRestore = __esmMin((() => {
104589
+ init_constants();
104590
+ browserCheckoutHandoffRestoreDeps = {
104591
+ addPageShowListener: (listener) => window.addEventListener("pageshow", listener),
104592
+ removePageShowListener: (listener) => window.removeEventListener("pageshow", listener),
104593
+ reloadAtRegistration: reloadAtEventRegistration
104594
+ };
104595
+ }));
104596
+ //#endregion
104398
104597
  //#region ../blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.ts
104399
104598
  function magicLinkSubmissionReducer(state, action) {
104400
104599
  switch (action.type) {
@@ -107055,6 +107254,7 @@ function EventRegistrationWizard(props) {
107055
107254
  events: events ?? [],
107056
107255
  maxTicketsNum
107057
107256
  });
107257
+ useEventCheckoutHandoffRestore(wizard.step === "redirecting");
107058
107258
  const [bookingOverlayOpen, setBookingOverlayOpen] = useState(false);
107059
107259
  const [floatingPortalRoot, setFloatingPortalRoot] = useState(null);
107060
107260
  useEffect(() => {
@@ -107187,6 +107387,7 @@ var init_EventRegistrationWizard = __esmMin((() => {
107187
107387
  init_themePortalRoot();
107188
107388
  init_buttons();
107189
107389
  init_constants();
107390
+ init_useEventCheckoutHandoffRestore();
107190
107391
  init_EventRegistrationSurface();
107191
107392
  init_EventRegistrationBookingLayer();
107192
107393
  EVENT_PORTAL_AUTH_COPY = {
@@ -108645,6 +108846,7 @@ function useEventPagination({ siteId: _siteId, initialEvents = [], fetchInitialO
108645
108846
  const eventSurface = filters?.eventSurface;
108646
108847
  const eventPresets = normalizeCsvString(filters?.eventPresets);
108647
108848
  const scheduleScope = filters?.scheduleScope;
108849
+ const seriesIds = filters?.seriesIds;
108648
108850
  const eventsRef = useRef(events);
108649
108851
  const loadingRef = useRef(loading);
108650
108852
  const hasMoreRef = useRef(hasMore);
@@ -108672,6 +108874,7 @@ function useEventPagination({ siteId: _siteId, initialEvents = [], fetchInitialO
108672
108874
  const currentEvents = eventsRef.current;
108673
108875
  const lastEvent = options.reset ? void 0 : currentEvents[currentEvents.length - 1];
108674
108876
  const newEvents = await getPublicEvents({
108877
+ seriesIds,
108675
108878
  afterStartsAt: lastEvent ? lastEvent.startsAt : void 0,
108676
108879
  afterId: lastEvent ? lastEvent.occurrenceId : void 0,
108677
108880
  limit: pageSize,
@@ -108710,6 +108913,7 @@ function useEventPagination({ siteId: _siteId, initialEvents = [], fetchInitialO
108710
108913
  eventSurface,
108711
108914
  eventPresets,
108712
108915
  scheduleScope,
108916
+ seriesIds,
108713
108917
  normalizedCategoryIds,
108714
108918
  normalizedStaffMemberId,
108715
108919
  normalizedVenueId
@@ -108719,7 +108923,7 @@ function useEventPagination({ siteId: _siteId, initialEvents = [], fetchInitialO
108719
108923
  }, [fetchPage]);
108720
108924
  const initialFetchAttemptKeyRef = useRef(null);
108721
108925
  useEffect(() => {
108722
- if (!fetchInitialOnMount) return;
108926
+ if (!fetchInitialOnMount || seriesIds === "") return;
108723
108927
  if (!filtersMatchInitial) return;
108724
108928
  if (initialEventsRef.current.length > 0) return;
108725
108929
  if (eventsRef.current.length > 0) return;
@@ -108733,7 +108937,8 @@ function useEventPagination({ siteId: _siteId, initialEvents = [], fetchInitialO
108733
108937
  fetchPage,
108734
108938
  filtersKey,
108735
108939
  filtersMatchInitial,
108736
- stage
108940
+ stage,
108941
+ seriesIds
108737
108942
  ]);
108738
108943
  const prevFiltersMatchInitialRef = useRef(filtersMatchInitial);
108739
108944
  const prevInitialEventsKeyRef = useRef(initialEventsKey);
@@ -108868,7 +109073,7 @@ var init_useEventFilters_state = __esmMin((() => {
108868
109073
  * const events = await api.getPublicEvents(params);
108869
109074
  * ```
108870
109075
  */
108871
- function useEventFilters({ showCategoryFilter = "auto", showVenueFilter = false, showStaffFilter = false, preFilterCategoryIds, preFilterStaffMemberId, preFilterVenueId, preFilterEventSurface, preFilterEventPresets, preFilterScheduleScope } = {}) {
109076
+ function useEventFilters({ showCategoryFilter = "auto", showVenueFilter = false, showStaffFilter = false, preFilterSeriesIds, preFilterCategoryIds, preFilterStaffMemberId, preFilterVenueId, preFilterEventSurface, preFilterEventPresets, preFilterScheduleScope } = {}) {
108872
109077
  const api = useBlockApi();
108873
109078
  const [loadState, dispatchLoadState] = useReducer(eventFiltersLoadReducer, void 0, createInitialEventFiltersLoadState);
108874
109079
  const filters = getEventFiltersData(loadState);
@@ -109017,6 +109222,7 @@ function useEventFilters({ showCategoryFilter = "auto", showVenueFilter = false,
109017
109222
  setSelectedVenueId("all");
109018
109223
  }, []),
109019
109224
  getFilterParams: useCallback(() => {
109225
+ if (preFilterSeriesIds != null) return { seriesIds: preFilterSeriesIds };
109020
109226
  const params = {};
109021
109227
  if (fixedEventSurface) params.eventSurface = fixedEventSurface;
109022
109228
  if (fixedEventPresets) params.eventPresets = fixedEventPresets;
@@ -109030,6 +109236,7 @@ function useEventFilters({ showCategoryFilter = "auto", showVenueFilter = false,
109030
109236
  params.staffMemberId = fixedStaffMemberId ?? (selectedStaffMemberId !== "all" ? selectedStaffMemberId : void 0);
109031
109237
  return params;
109032
109238
  }, [
109239
+ preFilterSeriesIds,
109033
109240
  allowedCategoryIds,
109034
109241
  allowedCategorySet,
109035
109242
  fixedEventPresets,
@@ -109065,25 +109272,12 @@ var init_EventListing_client = __esmMin((() => {
109065
109272
  const hydration = render.hydration;
109066
109273
  const filtersIdBase = useId();
109067
109274
  const initialListEvents = useMemo(() => [...display.events], [display.events]);
109068
- const initialListFilters = useMemo(() => buildEventRuntimeFilters({
109069
- eventSurface: hydration.eventSurface,
109070
- filterEventPresets: hydration.filterEventPresets,
109071
- scheduleScope: hydration.scheduleScope,
109072
- filterCategoryIds: hydration.filterCategoryIds,
109073
- filterStaffMemberId: hydration.filterStaffMemberId,
109074
- filterVenueId: hydration.filterVenueId
109075
- }), [
109076
- hydration.eventSurface,
109077
- hydration.filterEventPresets,
109078
- hydration.scheduleScope,
109079
- hydration.filterCategoryIds,
109080
- hydration.filterStaffMemberId,
109081
- hydration.filterVenueId
109082
- ]);
109275
+ const initialListFilters = buildEventRuntimeFilters(hydration);
109083
109276
  const { categories, venues, staffMembers, selectedCategoryId, selectedStaffMemberId, selectedVenueId, loading: filtersLoading, shouldShowCategoryFilter, shouldShowVenueFilter, shouldShowStaffFilter, hasActiveFilters, setSelectedCategoryId, setSelectedStaffMemberId, setSelectedVenueId, resetFilters, getFilterParams } = useEventFilters({
109084
109277
  showCategoryFilter: hydration.showFilters ? hydration.showCategoryFilter : "never",
109085
109278
  showVenueFilter: hydration.showFilters ? hydration.showVenueFilter : false,
109086
109279
  showStaffFilter: hydration.showFilters ? hydration.showStaffFilter : false,
109280
+ preFilterSeriesIds: hydration.seriesIds,
109087
109281
  preFilterCategoryIds: hydration.filterCategoryIds ?? void 0,
109088
109282
  preFilterStaffMemberId: hydration.filterStaffMemberId ?? void 0,
109089
109283
  preFilterVenueId: hydration.filterVenueId ?? void 0,
@@ -110155,6 +110349,7 @@ function toEventCombinedControllerProps(props) {
110155
110349
  eventSurface: props.render.display.eventSurface,
110156
110350
  filterEventPresets: props.render.display.filterEventPresets,
110157
110351
  scheduleScope: props.render.display.scheduleScope,
110352
+ seriesIds: props.render.display.seriesIds,
110158
110353
  filterCategoryIds: props.render.display.filterCategoryIds,
110159
110354
  filterStaffMemberId: props.render.display.filterStaffMemberId,
110160
110355
  filterVenueId: props.render.display.filterVenueId,
@@ -110290,7 +110485,7 @@ var init_EventCombined_client = __esmMin((() => {
110290
110485
  EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout = "stack", listColumns = "3", eventsPerPage = 12, paginationAction = {
110291
110486
  kind: "loadMore",
110292
110487
  label: "Load more events"
110293
- }, startOfWeek = "monday", calendarTabViews = "both", defaultCalendarView, showFilters, showCategoryFilter = "auto", showVenueFilter, showStaffFilter, eventSurface, filterEventPresets, scheduleScope, filterCategoryIds, filterStaffMemberId, filterVenueId, showVenue, showMap, showCapacity, cardRole, buttonVariant = "primary", buttonText = "Book", emptyMessage = "No upcoming events scheduled.", className, calendarContext, calendarWindow }) => {
110488
+ }, startOfWeek = "monday", calendarTabViews = "both", defaultCalendarView, showFilters, showCategoryFilter = "auto", showVenueFilter, showStaffFilter, eventSurface, filterEventPresets, scheduleScope, seriesIds, filterCategoryIds, filterStaffMemberId, filterVenueId, showVenue, showMap, showCapacity, cardRole, buttonVariant = "primary", buttonText = "Book", emptyMessage = "No upcoming events scheduled.", className, calendarContext, calendarWindow }) => {
110294
110489
  const hydrationReady = useHydrationReady();
110295
110490
  const fetchInitialEventsOnMount = initialEvents == null;
110296
110491
  const resolvedShowFilters = showFilters ?? true;
@@ -110316,6 +110511,7 @@ var init_EventCombined_client = __esmMin((() => {
110316
110511
  showCategoryFilter: resolvedShowFilters ? showCategoryFilter : "never",
110317
110512
  showVenueFilter: resolvedShowFilters ? resolvedShowVenueFilter : false,
110318
110513
  showStaffFilter: resolvedShowFilters ? resolvedShowStaffFilter : false,
110514
+ preFilterSeriesIds: seriesIds,
110319
110515
  preFilterCategoryIds: filterCategoryIds,
110320
110516
  preFilterStaffMemberId: filterStaffMemberId,
110321
110517
  preFilterVenueId: filterVenueId,
@@ -110323,21 +110519,15 @@ var init_EventCombined_client = __esmMin((() => {
110323
110519
  preFilterEventPresets: filterEventPresets,
110324
110520
  preFilterScheduleScope: resolvedScheduleScope
110325
110521
  });
110326
- const initialListFilters = useMemo(() => buildEventRuntimeFilters({
110522
+ const initialListFilters = buildEventRuntimeFilters({
110327
110523
  eventSurface: resolvedEventSurface,
110328
110524
  filterEventPresets,
110329
110525
  scheduleScope: resolvedScheduleScope,
110526
+ seriesIds,
110330
110527
  filterCategoryIds,
110331
110528
  filterStaffMemberId,
110332
110529
  filterVenueId
110333
- }), [
110334
- resolvedEventSurface,
110335
- filterCategoryIds,
110336
- filterEventPresets,
110337
- filterStaffMemberId,
110338
- filterVenueId,
110339
- resolvedScheduleScope
110340
- ]);
110530
+ });
110341
110531
  const listFilters = useMemo(() => getFilterParams(), [getFilterParams]);
110342
110532
  const pageSize = eventsPerPage;
110343
110533
  const { events: paginatedEvents, loading: eventsLoading, error: eventsError, hasMore, loadMore } = useEventPagination({
@@ -110950,6 +111140,7 @@ function useEventCalendarFilterState(display) {
110950
111140
  showCategoryFilter: display.showFilters ? display.showCategoryFilter : "never",
110951
111141
  showVenueFilter: display.showFilters ? display.showVenueFilter : false,
110952
111142
  showStaffFilter: display.showFilters ? display.showStaffFilter : false,
111143
+ preFilterSeriesIds: display.seriesIds,
110953
111144
  preFilterCategoryIds: display.filterCategoryIds,
110954
111145
  preFilterStaffMemberId: display.filterStaffMemberId,
110955
111146
  preFilterVenueId: display.filterVenueId,
@@ -110983,6 +111174,7 @@ function buildDisplayFilterParams(display) {
110983
111174
  eventSurface: display.eventSurface,
110984
111175
  filterEventPresets: display.filterEventPresets,
110985
111176
  scheduleScope: display.scheduleScope,
111177
+ seriesIds: display.seriesIds,
110986
111178
  filterCategoryIds: display.filterCategoryIds,
110987
111179
  filterStaffMemberId: display.filterStaffMemberId,
110988
111180
  filterVenueId: display.filterVenueId
@@ -111029,6 +111221,7 @@ var init_EventCalendar_client = __esmMin((() => {
111029
111221
  eventSurface: display.eventSurface,
111030
111222
  filterEventPresets: display.filterEventPresets,
111031
111223
  scheduleScope: display.scheduleScope,
111224
+ seriesIds: display.seriesIds,
111032
111225
  filterCategoryIds: display.filterCategoryIds,
111033
111226
  filterStaffMemberId: display.filterStaffMemberId,
111034
111227
  filterVenueId: display.filterVenueId,
@@ -111052,6 +111245,7 @@ var init_EventCalendar_client = __esmMin((() => {
111052
111245
  const { display, hydration } = render;
111053
111246
  const filters = useMemo(() => buildDisplayFilterParams(display), [
111054
111247
  display.eventSurface,
111248
+ display.seriesIds,
111055
111249
  display.filterCategoryIds,
111056
111250
  display.filterEventPresets,
111057
111251
  display.filterStaffMemberId,
@@ -113677,7 +113871,7 @@ function NewsletterFormClient({ render }) {
113677
113871
  if (submitTarget.tag === "unavailable") {
113678
113872
  dispatchSubmission({
113679
113873
  type: "failed",
113680
- error: newsletterFormError("Newsletter list is not configured")
113874
+ error: newsletterFormError(SIGNUPS_PAUSED_MESSAGE)
113681
113875
  });
113682
113876
  return;
113683
113877
  }
@@ -113688,14 +113882,16 @@ function NewsletterFormClient({ render }) {
113688
113882
  });
113689
113883
  return;
113690
113884
  }
113691
- const visitorSelection = readVisitorSelection(formData, render.hydration);
113692
- if (visitorSelection === null) {
113885
+ const selection = readVisitorSelection(formData, render.hydration);
113886
+ const selectionError = visitorSelectionError(selection);
113887
+ if (selectionError) {
113693
113888
  dispatchSubmission({
113694
113889
  type: "failed",
113695
- error: newsletterFieldError(TOPIC_CHOICE_FIELD_ID, "Choose at least one email topic.")
113890
+ error: selectionError
113696
113891
  });
113697
113892
  return;
113698
113893
  }
113894
+ const visitorSelection = selection.tag === "chosen" ? selection.value : void 0;
113699
113895
  dispatchSubmission({ type: "submitted" });
113700
113896
  try {
113701
113897
  const result = await api.subscribeNewsletter({
@@ -113889,10 +114085,18 @@ function transportFailureMessage(err) {
113889
114085
  }
113890
114086
  return RETRY_SHORTLY_MESSAGE;
113891
114087
  }
114088
+ function visitorSelectionError(selection) {
114089
+ switch (selection.tag) {
114090
+ case "nothing_chosen": return newsletterFieldError(TOPIC_CHOICE_FIELD_ID, "Choose at least one email topic.");
114091
+ case "unusable": return newsletterFormError(SIGNUPS_PAUSED_MESSAGE);
114092
+ case "not_offered":
114093
+ case "chosen": return null;
114094
+ }
114095
+ }
113892
114096
  function readVisitorSelection(formData, hydration) {
113893
- if (hydration.choicePresentation !== "visitor_choice") return void 0;
114097
+ if (hydration.choicePresentation !== "visitor_choice") return { tag: "not_offered" };
113894
114098
  const ids = formData.getAll(TOPIC_CHOICE_FIELD_ID).flatMap((value) => typeof value === "string" ? [value] : []);
113895
- if (ids.length === 0) return null;
114099
+ if (ids.length === 0) return { tag: "nothing_chosen" };
113896
114100
  const raw = hydration.choiceProvider === "native" ? {
113897
114101
  provider: "native",
113898
114102
  topicIds: ids
@@ -113903,9 +114107,12 @@ function readVisitorSelection(formData, hydration) {
113903
114107
  provider: "mailchimp",
113904
114108
  interestIds: ids
113905
114109
  } : null;
113906
- if (raw === null) return null;
114110
+ if (raw === null) return { tag: "unusable" };
113907
114111
  const parsed = parseMailingListVisitorSelection(raw);
113908
- return parsed.ok ? parsed.value : null;
114112
+ return parsed.ok ? {
114113
+ tag: "chosen",
114114
+ value: parsed.value
114115
+ } : { tag: "unusable" };
113909
114116
  }
113910
114117
  function publicSignupError(outcome) {
113911
114118
  switch (outcome.tag) {
@@ -116199,6 +116406,27 @@ const headerRuntimeTransforms = [{
116199
116406
  init_events$2();
116200
116407
  init_core$1();
116201
116408
  init_calendarWindow();
116409
+ init_eventSelection();
116410
+ const eventCalendarSelectionParam = {
116411
+ id: "events.calendarSelectionParam",
116412
+ kind: "formatter",
116413
+ summary: "Resolve selected events instead of discovery filters",
116414
+ schema: z$1.object({ key: z$1.enum([
116415
+ "seriesIds",
116416
+ "eventSurface",
116417
+ "filterEventPresets",
116418
+ "scheduleScope",
116419
+ "filterCategoryIds",
116420
+ "filterStaffMemberId",
116421
+ "filterVenueId"
116422
+ ]) }),
116423
+ run(value, { key }) {
116424
+ const content = asPartialObject(value) ?? {};
116425
+ const selection = resolveEventSelection(content.eventSelection, content.selectedEventSeriesIds);
116426
+ if (selection.kind === "selected") return key === "seriesIds" ? selection.seriesIds : void 0;
116427
+ return key === "seriesIds" ? void 0 : content[key];
116428
+ }
116429
+ };
116202
116430
  const readJobSchema = z$1.object({ job: z$1.enum(["list", "calendar"]) });
116203
116431
  const eventCalendarReadProfile = {
116204
116432
  id: "events.calendarReadProfile",
@@ -116224,6 +116452,7 @@ init_core$1();
116224
116452
  init_boxStyles$1();
116225
116453
  init_boxStyleClassNames();
116226
116454
  const defaultTransforms = createTransformRegistry([
116455
+ eventCalendarSelectionParam,
116227
116456
  eventCalendarReadEnabled,
116228
116457
  eventCalendarReadProfile,
116229
116458
  ...formattingTransforms,
@@ -117290,17 +117519,16 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
117290
117519
  console.warn("[ButtonNode] Missing href for link-required button");
117291
117520
  return null;
117292
117521
  }
117293
- const extraClassName = affordanceIcon ? [className, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ") : className;
117294
117522
  const resolvedVariantId = parseThemeButtonVariantId(variantId);
117295
117523
  if (variantId && !resolvedVariantId) {
117296
117524
  console.error("[ButtonNode] Invalid button variant", { variantId });
117297
117525
  return null;
117298
117526
  }
117299
- const combinedClassName = resolvedVariantId ? themeButtonClassName({
117527
+ const combinedClassName = resolvedVariantId ? (affordanceIcon ? themeButtonClassNameWithTrailingIcon : themeButtonClassName)({
117300
117528
  variant: resolvedVariantId,
117301
117529
  size,
117302
- extraClassName
117303
- }) : extraClassName;
117530
+ extraClassName: className
117531
+ }) : className;
117304
117532
  if (resolvedHref) return /* @__PURE__ */ jsxs("a", {
117305
117533
  href: resolvedHref,
117306
117534
  target,
@@ -118425,6 +118653,7 @@ const publicPricingSchema = z$1.object({
118425
118653
  });
118426
118654
  const publicAppointmentServiceSchema = z$1.object({
118427
118655
  id: z$1.string().min(1),
118656
+ slug: z$1.string().min(1).optional(),
118428
118657
  title: z$1.string(),
118429
118658
  description: z$1.string().nullable().optional(),
118430
118659
  durationMinutes: z$1.number().int().positive(),
@@ -118501,7 +118730,7 @@ function formatAmountOrFree(amount, currency) {
118501
118730
  currency
118502
118731
  }, { decimals: "auto" });
118503
118732
  }
118504
- function buildRows(services, pathname) {
118733
+ function buildRows(services, pathname, servicePathPrefix) {
118505
118734
  return services.map((service) => ({
118506
118735
  id: service.id,
118507
118736
  title: service.title,
@@ -118512,7 +118741,8 @@ function buildRows(services, pathname) {
118512
118741
  href: resolveDedicatedBookingHref(pathname, {
118513
118742
  kind: "appointment_service",
118514
118743
  serviceId: service.id
118515
- })
118744
+ }),
118745
+ detailsHref: servicePathPrefix && service.slug ? `${servicePathPrefix.replace(/\/$/, "")}/${encodeURIComponent(service.slug)}` : null
118516
118746
  }));
118517
118747
  }
118518
118748
  function buildAppointmentServicesView(input) {
@@ -118531,13 +118761,14 @@ function buildAppointmentServicesView(input) {
118531
118761
  };
118532
118762
  return {
118533
118763
  kind: "items",
118534
- rows: buildRows(parsed.services, input.pathname)
118764
+ rows: buildRows(parsed.services, input.pathname, input.servicePathPrefix ?? null)
118535
118765
  };
118536
118766
  }
118537
- function AppointmentServicesNode({ sectionHeading, services, pathname, className }) {
118767
+ function AppointmentServicesNode({ sectionHeading, services, pathname, servicePathPrefix, className }) {
118538
118768
  const view = buildAppointmentServicesView({
118539
118769
  services,
118540
- pathname: typeof pathname === "string" ? pathname : void 0
118770
+ pathname: typeof pathname === "string" ? pathname : void 0,
118771
+ servicePathPrefix: typeof servicePathPrefix === "string" ? servicePathPrefix : null
118541
118772
  });
118542
118773
  const rootClassName = `appointment-services ${className ?? ""}`.trim();
118543
118774
  const RowTitle = sectionHeading ? "h3" : "h2";
@@ -118568,7 +118799,10 @@ function AppointmentServicesNode({ sectionHeading, services, pathname, className
118568
118799
  children: [
118569
118800
  /* @__PURE__ */ jsx(RowTitle, {
118570
118801
  className: "appointment-services-row-title rb-text-lg rb-font-medium rb-leading-tight",
118571
- children: row.title
118802
+ children: row.detailsHref ? /* @__PURE__ */ jsx("a", {
118803
+ href: row.detailsHref,
118804
+ children: row.title
118805
+ }) : row.title
118572
118806
  }),
118573
118807
  row.description ? /* @__PURE__ */ jsx("p", {
118574
118808
  className: "appointment-services-row-description rb-text-sm rb-leading-6 status-muted",
@@ -119301,7 +119535,6 @@ function OfferingsCatalogue(props) {
119301
119535
  //#endregion
119302
119536
  //#region ../blocks/src/system/runtime/nodes/offerings-preview-content.tsx
119303
119537
  init_buttons();
119304
- init_svg();
119305
119538
  init_shared$2();
119306
119539
  function OfferingsPreviewContent(props) {
119307
119540
  const groupLinkClass = themeButtonClassName({
@@ -119348,13 +119581,10 @@ function OfferingsPreviewContent(props) {
119348
119581
  }),
119349
119582
  groupCta ? /* @__PURE__ */ jsx("footer", {
119350
119583
  className: "offerings-preview-card-footer rb-mt-auto rb-flex",
119351
- children: /* @__PURE__ */ jsxs("a", {
119584
+ children: /* @__PURE__ */ jsx("a", {
119352
119585
  className: groupLinkClass,
119353
119586
  href: groupCta.href,
119354
- children: [/* @__PURE__ */ jsx("span", { children: groupCta.label }), /* @__PURE__ */ jsx(ArrowRightIcon, {
119355
- "aria-hidden": "true",
119356
- className: "offerings-preview-link-icon rb-h-4 rb-w-4"
119357
- })]
119587
+ children: /* @__PURE__ */ jsx("span", { children: groupCta.label })
119358
119588
  })
119359
119589
  }) : null
119360
119590
  ]
@@ -120771,23 +121001,123 @@ const formBlockDefinition = {
120771
121001
  runtime: formBlockRuntime
120772
121002
  };
120773
121003
  //#endregion
121004
+ //#region ../blocks/src/system/blocks/events/eventSelectionFields.ts
121005
+ init_schema();
121006
+ const eventSelectionFields = [{
121007
+ id: "eventSelection",
121008
+ type: "select",
121009
+ label: "Events to show",
121010
+ required: false,
121011
+ multiple: false,
121012
+ defaultValue: "matching",
121013
+ options: [{
121014
+ value: "matching",
121015
+ label: "All matching events"
121016
+ }, {
121017
+ value: "selected",
121018
+ label: "Selected events"
121019
+ }],
121020
+ ui: { intent: "behavior" }
121021
+ }, createSiteOptionSelectField({
121022
+ id: "selectedEventSeriesIds",
121023
+ label: "Selected events",
121024
+ description: "Show upcoming dates for these events. Other event filters do not apply.",
121025
+ required: false,
121026
+ multiple: true,
121027
+ defaultValue: [],
121028
+ optionSource: "eventSeries",
121029
+ ui: {
121030
+ intent: "behavior",
121031
+ searchThreshold: 1,
121032
+ visibleWhen: {
121033
+ field: "eventSelection",
121034
+ equals: "selected"
121035
+ }
121036
+ }
121037
+ })];
121038
+ function withEventSelectionVisibility(field) {
121039
+ if (![
121040
+ "eventSurface",
121041
+ "filterEventPresets",
121042
+ "scheduleScope",
121043
+ "filterCategoryIds",
121044
+ "filterStaffMemberId",
121045
+ "filterVenueId",
121046
+ "showFilters",
121047
+ "showCategoryFilter",
121048
+ "showVenueFilter",
121049
+ "showStaffFilter"
121050
+ ].includes(field.id)) return field;
121051
+ const visibleWhen = field.ui?.visibleWhen;
121052
+ return {
121053
+ ...field,
121054
+ ui: {
121055
+ ...field.ui,
121056
+ visibleWhen: { allOf: [{
121057
+ field: "eventSelection",
121058
+ notEquals: "selected"
121059
+ }, ...visibleWhen ? [visibleWhen] : []] }
121060
+ }
121061
+ };
121062
+ }
121063
+ //#endregion
120774
121064
  //#region ../blocks/src/system/blocks/events/eventCalendarDataLoaders.ts
120775
121065
  init_calendarWindow();
120776
121066
  const scopeParams = {
120777
121067
  siteId: { $bind: { from: "$root.siteId" } },
121068
+ seriesIds: { $bind: {
121069
+ from: "content",
121070
+ transforms: [{
121071
+ id: "events.calendarSelectionParam",
121072
+ options: { key: "seriesIds" }
121073
+ }]
121074
+ } },
120778
121075
  stage: { $bind: {
120779
121076
  from: "$root.previewStage",
120780
121077
  fallback: "published"
120781
121078
  } },
120782
- eventSurface: { $bind: { from: "content.eventSurface" } },
121079
+ eventSurface: { $bind: {
121080
+ from: "content",
121081
+ transforms: [{
121082
+ id: "events.calendarSelectionParam",
121083
+ options: { key: "eventSurface" }
121084
+ }, { id: "value.csv" }]
121085
+ } },
120783
121086
  eventPresets: { $bind: {
120784
- from: "content.filterEventPresets",
120785
- transforms: [{ id: "value.csv" }]
121087
+ from: "content",
121088
+ transforms: [{
121089
+ id: "events.calendarSelectionParam",
121090
+ options: { key: "filterEventPresets" }
121091
+ }, { id: "value.csv" }]
121092
+ } },
121093
+ scheduleScope: { $bind: {
121094
+ from: "content",
121095
+ transforms: [{
121096
+ id: "events.calendarSelectionParam",
121097
+ options: { key: "scheduleScope" }
121098
+ }, { id: "value.csv" }]
120786
121099
  } },
120787
- scheduleScope: { $bind: { from: "content.scheduleScope" } },
120788
- categoryIds: { $bind: { from: "content.filterCategoryIds" } },
120789
- staffMemberId: { $bind: { from: "content.filterStaffMemberId" } },
120790
- venueId: { $bind: { from: "content.filterVenueId" } }
121100
+ categoryIds: { $bind: {
121101
+ from: "content",
121102
+ transforms: [{
121103
+ id: "events.calendarSelectionParam",
121104
+ options: { key: "filterCategoryIds" }
121105
+ }, { id: "value.csv" }]
121106
+ } },
121107
+ staffMemberId: { $bind: {
121108
+ from: "content",
121109
+ transforms: [{
121110
+ id: "events.calendarSelectionParam",
121111
+ options: { key: "filterStaffMemberId" }
121112
+ }, { id: "value.csv" }]
121113
+ } },
121114
+ venueId: { $bind: {
121115
+ from: "content",
121116
+ transforms: [{
121117
+ id: "events.calendarSelectionParam",
121118
+ options: { key: "filterVenueId" }
121119
+ }, { id: "value.csv" }]
121120
+ } }
120791
121121
  };
120792
121122
  /** Combined renders two jobs; calendar-only variants never pay for the list seed. */
120793
121123
  const eventCalendarDataLoaders = {
@@ -120928,6 +121258,13 @@ const eventCalendarLayout = [styledSection({
120928
121258
  from: "content.defaultCalendarView",
120929
121259
  fallback: "month"
120930
121260
  } },
121261
+ seriesIds: { $bind: {
121262
+ from: "content",
121263
+ transforms: [{
121264
+ id: "events.calendarSelectionParam",
121265
+ options: { key: "seriesIds" }
121266
+ }]
121267
+ } },
120931
121268
  showFilters: { $bind: {
120932
121269
  from: "content.showFilters",
120933
121270
  fallback: true
@@ -120949,17 +121286,47 @@ const eventCalendarLayout = [styledSection({
120949
121286
  fallback: true
120950
121287
  } },
120951
121288
  eventSurface: { $bind: {
120952
- from: "content.eventSurface",
120953
- fallback: "all"
121289
+ from: "content",
121290
+ transforms: [{
121291
+ id: "events.calendarSelectionParam",
121292
+ options: { key: "eventSurface" }
121293
+ }]
121294
+ } },
121295
+ filterEventPresets: { $bind: {
121296
+ from: "content",
121297
+ transforms: [{
121298
+ id: "events.calendarSelectionParam",
121299
+ options: { key: "filterEventPresets" }
121300
+ }]
120954
121301
  } },
120955
- filterEventPresets: { $bind: { from: "content.filterEventPresets" } },
120956
121302
  scheduleScope: { $bind: {
120957
- from: "content.scheduleScope",
120958
- fallback: "any"
121303
+ from: "content",
121304
+ transforms: [{
121305
+ id: "events.calendarSelectionParam",
121306
+ options: { key: "scheduleScope" }
121307
+ }]
121308
+ } },
121309
+ filterCategoryIds: { $bind: {
121310
+ from: "content",
121311
+ transforms: [{
121312
+ id: "events.calendarSelectionParam",
121313
+ options: { key: "filterCategoryIds" }
121314
+ }]
121315
+ } },
121316
+ filterStaffMemberId: { $bind: {
121317
+ from: "content",
121318
+ transforms: [{
121319
+ id: "events.calendarSelectionParam",
121320
+ options: { key: "filterStaffMemberId" }
121321
+ }]
121322
+ } },
121323
+ filterVenueId: { $bind: {
121324
+ from: "content",
121325
+ transforms: [{
121326
+ id: "events.calendarSelectionParam",
121327
+ options: { key: "filterVenueId" }
121328
+ }]
120959
121329
  } },
120960
- filterCategoryIds: { $bind: { from: "content.filterCategoryIds" } },
120961
- filterStaffMemberId: { $bind: { from: "content.filterStaffMemberId" } },
120962
- filterVenueId: { $bind: { from: "content.filterVenueId" } },
120963
121330
  cardRole: { $bind: {
120964
121331
  from: "content._cardStyles.role",
120965
121332
  fallback: "default"
@@ -121463,6 +121830,7 @@ const eventCalendarAdditionalFields = [
121463
121830
  }
121464
121831
  }
121465
121832
  },
121833
+ ...eventSelectionFields,
121466
121834
  {
121467
121835
  id: "eventSurface",
121468
121836
  type: "select",
@@ -121672,7 +122040,7 @@ const eventCalendarBlockDefinition = {
121672
122040
  titleSource: "heading",
121673
122041
  description: "Display events with calendar, list, or combined views with filtering",
121674
122042
  skipSectionStyles: true,
121675
- additionalFields: eventCalendarAdditionalFields,
122043
+ additionalFields: eventCalendarAdditionalFields.map(withEventSelectionVisibility),
121676
122044
  styleTokens: {
121677
122045
  background: "surface",
121678
122046
  typography: "body",
@@ -125801,9 +126169,56 @@ function generateNavLinkCSS(options) {
125801
126169
  if (baseRules.length > 0) cssChunks.unshift(`\n${selector} {\n ${baseRules.join("\n ")}\n}\n`);
125802
126170
  if (hoverRules.length > 0) cssChunks.push(`\n${hoverSelector} {\n ${hoverRules.join("\n ")}\n}\n`);
125803
126171
  if (activeRules.length > 0) cssChunks.push(`\n${activeSelector} {\n ${activeRules.join("\n ")}\n}\n`);
126172
+ cssChunks.push(navLinkFocusVisibleCss(selector, style, theme, tokens));
125804
126173
  cssChunks.push(generateInteractiveChildInheritanceCSS(selector));
125805
126174
  return cssChunks.join("");
125806
126175
  }
126176
+ /**
126177
+ * Keyboard focus indicator for nav links, in the header, the footer and header
126178
+ * dropdown menus — the three surfaces `generateNavLinkCSS` serves.
126179
+ *
126180
+ * Emitted unconditionally rather than as an effect, because focus visibility is
126181
+ * a floor rather than a style choice. Only the interaction-palette pill ever
126182
+ * wrote an `effects.focus` group, so every other nav — every `quiet` palette,
126183
+ * every footer, every dropdown — previously fell back to whatever outline the
126184
+ * browser drew.
126185
+ *
126186
+ * The outline takes the link's own resolved colour, so on a header that adapts
126187
+ * to the section it floats over it moves with the adaptation instead of
126188
+ * asserting a brand colour against an unknown backdrop.
126189
+ *
126190
+ * Where the style asks for `soft-glow`, the same halo goes on the outline. That
126191
+ * treatment exists because the theme has already conceded the resolved colour
126192
+ * alone is not reliable over an unpredictable backdrop — a hero photograph with
126193
+ * mixed luminance. Without it the text would stay legible by its halo while the
126194
+ * focus ring, which is the part with a contrast requirement of its own, would
126195
+ * not.
126196
+ *
126197
+ * A style that also paints a focus pill keeps it: this adds an outline around
126198
+ * that pill rather than replacing it.
126199
+ */
126200
+ function navLinkFocusVisibleCss(selector, style, theme, tokens) {
126201
+ const color = tokens.getColor(style.colorToken);
126202
+ const halo = buildTextContrastShadow({
126203
+ theme,
126204
+ colorToken: style.colorToken,
126205
+ treatment: style.contrastTreatment
126206
+ });
126207
+ return `
126208
+ ${selector}:focus-visible {
126209
+ outline: 2px solid ${color};
126210
+ outline-offset: ${focusOutlineOffset(selector)};${halo ? `\n box-shadow: ${halo};` : ""}
126211
+ }
126212
+ `;
126213
+ }
126214
+ /**
126215
+ * Dropdown items are full-width inside a panel with no horizontal padding, so
126216
+ * an outset outline would paint over and past the panel's own border. Keeping
126217
+ * it flush is the only way it reads as belonging to the item.
126218
+ */
126219
+ function focusOutlineOffset(selector) {
126220
+ return selector.includes("nav-dropdown-link") ? "-2px" : "3px";
126221
+ }
125807
126222
  function buildTextContrastShadow(input) {
125808
126223
  if (input.treatment !== "soft-glow") return null;
125809
126224
  return isLikelyLightColorToken(input.theme, input.colorToken) ? "0 1px 3px rgb(0 0 0 / 0.55), 0 0 18px rgb(0 0 0 / 0.38)" : "0 1px 3px rgb(255 255 255 / 0.72), 0 0 18px rgb(255 255 255 / 0.5)";
@@ -128956,7 +129371,7 @@ function pageBlockPosition(index, blockCount) {
128956
129371
  //#endregion
128957
129372
  //#region ../blocks/src/pageRendererContracts.ts
128958
129373
  function buildPageRendererRootRuntime(dataContext) {
128959
- const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
129374
+ const { siteId = null, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
128960
129375
  return {
128961
129376
  siteId,
128962
129377
  pageId,
@@ -128966,6 +129381,7 @@ function buildPageRendererRootRuntime(dataContext) {
128966
129381
  apiBaseUrl,
128967
129382
  portalToken,
128968
129383
  bookingOfferingPresets,
129384
+ appointmentServicePathPrefix,
128969
129385
  mailingList,
128970
129386
  eventRegistrationOverlayEnabled,
128971
129387
  loaderFailures
@@ -133841,7 +134257,8 @@ const appointmentServicesBlockDefinition = {
133841
134257
  el("appointment-services", {
133842
134258
  sectionHeading: { $bind: { from: "content.heading" } },
133843
134259
  services: { $bind: { from: "data.services" } },
133844
- pathname: { $bind: { from: "$root.pathname" } }
134260
+ pathname: { $bind: { from: "$root.pathname" } },
134261
+ servicePathPrefix: { $bind: { from: "$root.appointmentServicePathPrefix" } }
133845
134262
  })
133846
134263
  ], { gap: "lg" })
133847
134264
  })]
@@ -140403,10 +140820,19 @@ const containerResponsiveThemeCss = `/*
140403
140820
  padding-top: 2.5rem;
140404
140821
  padding-bottom: 2.5rem;
140405
140822
  }
140823
+ /* Clearance for a surface that is not an authored block page.
140824
+ An authored page gets this through its opening block's container (see the
140825
+ overlay-clearance rule in styles.css). A reserved surface or a system
140826
+ destination page has no such block, so it consumes the same variable here.
140827
+ Marked with one class rather than per-surface selectors, because the last
140828
+ two additions to this family were both missed and shipped overlapping. */
140406
140829
  :where(.theme-scope)
140407
140830
  [data-site-document-layout-mode="header-overlay"]
140408
- [data-rb-reserved-surface].rb-reserved-surface-main {
140409
- padding-top: calc(var(--rb-reserved-surface-header-offset, 5.5rem) + 2.5rem);
140831
+ .rb-overlay-clearance-surface {
140832
+ padding-top: calc(
140833
+ var(--site-overlay-header-clearance, 5.5rem) +
140834
+ var(--site-overlay-opening-content-extra-pad, clamp(1rem, 2vw, 1.75rem))
140835
+ );
140410
140836
  }
140411
140837
  .rb-preview-editor-offset {
140412
140838
  padding-bottom: calc(
@@ -150763,6 +151189,23 @@ const containerResponsiveThemeCss = `/*
150763
151189
  gap: 0.5rem;
150764
151190
  }
150765
151191
 
151192
+ /* Error panel and field notes. The form block scopes these to its own
151193
+ data-block, so the newsletter form (which also renders in the footer)
151194
+ needs its own copy of the treatment. */
151195
+ :where(.theme-scope) .newsletter-form .fb-error:not([data-field-validation-message]) {
151196
+ background-color: var(--fb-error-bg);
151197
+ color: var(--fb-error-text);
151198
+ border: 1px solid var(--fb-error-border);
151199
+ border-radius: var(--rb-block-radius);
151200
+ padding: 1rem;
151201
+ font-size: 0.875rem;
151202
+ }
151203
+
151204
+ :where(.theme-scope) .newsletter-form [data-field-validation-message] {
151205
+ font-size: 0.875rem;
151206
+ color: var(--fb-error-text);
151207
+ }
151208
+
150766
151209
  /* Required indicator */
150767
151210
  :where(.theme-scope) .newsletter-required {
150768
151211
  color: rgb(var(--tb-primary));
@@ -153163,9 +153606,20 @@ z$1.object({
153163
153606
  }).passthrough();
153164
153607
  //#endregion
153165
153608
  //#region ../theme-core/src/hosted-booking-appearance.ts
153609
+ init_schema$2();
153166
153610
  init_colors();
153167
153611
  init_expandPalette();
153168
153612
  init_tokens();
153613
+ init_modern_minimal();
153614
+ z$1.object({
153615
+ palette: paletteColorsSchema,
153616
+ paletteMode: paletteModeSchema,
153617
+ typography: z$1.object({
153618
+ headingFamily: z$1.string().trim().min(1),
153619
+ bodyFamily: z$1.string().trim().min(1)
153620
+ }).strict(),
153621
+ corners
153622
+ }).strict();
153169
153623
  //#endregion
153170
153624
  //#region ../theme-core/src/palette/utils/colorPlacement.ts
153171
153625
  init_colorConversion();
@@ -155185,12 +155639,12 @@ function normalizeContent(block) {
155185
155639
  }
155186
155640
  /**
155187
155641
  * Normalize params for API calls.
155188
- * Converts all values to strings.
155642
+ * Converts supplied values to strings, preserving absent versus explicitly empty params.
155189
155643
  */
155190
155644
  function normalizeParams(input) {
155191
155645
  if (!input || typeof input !== "object") return {};
155192
155646
  const output = {};
155193
- for (const [key, value] of Object.entries(input)) output[key] = coerceToString(value);
155647
+ for (const [key, value] of Object.entries(input)) if (value !== void 0 && value !== null) output[key] = coerceToString(value);
155194
155648
  return output;
155195
155649
  }
155196
155650
  function isNonArrayObject(value) {
@@ -155254,6 +155708,14 @@ function coercePayload(payload) {
155254
155708
  * - Frontend: provide internal API client
155255
155709
  * - SDK: provide SDK client with endpoint mapping
155256
155710
  */
155711
+ function projectDataLoaders(loaders, shouldLoad, blockId, blockKind) {
155712
+ if (!shouldLoad) return [...loaders];
155713
+ return loaders.filter(({ key }) => shouldLoad({
155714
+ blockId,
155715
+ blockKind,
155716
+ loaderKey: key
155717
+ }));
155718
+ }
155257
155719
  function shouldSkipResolvedLoader(input) {
155258
155720
  if (input.loader.requiredParams?.some((param) => !input.params[param]?.trim())) return true;
155259
155721
  return Boolean(input.isValidEndpoint && !input.isValidEndpoint(input.endpoint));
@@ -155282,7 +155744,7 @@ async function prefetchBlockData$1(page, context, options) {
155282
155744
  return (await prefetchBlockDataWithFailures(page, context, options)).resolvedData;
155283
155745
  }
155284
155746
  async function prefetchBlockDataWithFailures(page, context, options) {
155285
- const { apiClient, isValidEndpoint, onError, getCustomBlockLoaders, getBlockDefinition: getBlockDefinition$1 = getBlockDefinition, resolveParamsBindings: resolveParamsBindings$1 = resolveParamsBindings } = options;
155747
+ const { apiClient, isValidEndpoint, onError, getCustomBlockLoaders, getBlockDefinition: getBlockDefinition$1 = getBlockDefinition, resolveParamsBindings: resolveParamsBindings$1 = resolveParamsBindings, shouldLoad } = options;
155286
155748
  const results = {};
155287
155749
  const loaderFailures = {};
155288
155750
  const tasks = [];
@@ -155299,6 +155761,7 @@ async function prefetchBlockDataWithFailures(page, context, options) {
155299
155761
  loader
155300
155762
  })) : [];
155301
155763
  } else loaders = [];
155764
+ loaders = projectDataLoaders(loaders, shouldLoad, blockId, block.kind);
155302
155765
  if (loaders.length === 0) continue;
155303
155766
  const root = {
155304
155767
  ...context.root ?? {},
@@ -155400,8 +155863,8 @@ function toStringParams(value) {
155400
155863
  for (const [k, v] of Object.entries(value)) if (typeof v === "string") out[k] = v;
155401
155864
  return out;
155402
155865
  }
155403
- function stripEmptyStringValues(params) {
155404
- for (const [key, value] of Object.entries(params)) if (value === "") delete params[key];
155866
+ function stripEmptyStringValues(params, endpoint) {
155867
+ for (const [key, value] of Object.entries(params)) if (value === "" && !(key === "seriesIds" && (endpoint === "listPublicEvents" || endpoint === "listPublicEventCalendarWindow"))) delete params[key];
155405
155868
  }
155406
155869
  function ensureSiteId(params, context) {
155407
155870
  if (!params.siteId && typeof context.siteId === "string" && context.siteId) params.siteId = context.siteId;
@@ -155414,7 +155877,7 @@ function ensureSiteId(params, context) {
155414
155877
  */
155415
155878
  function normalizeLoaderParams(endpoint, params, context) {
155416
155879
  const out = toStringParams(params);
155417
- stripEmptyStringValues(out);
155880
+ stripEmptyStringValues(out, endpoint);
155418
155881
  if (endpoint === "getPublicFormById") {
155419
155882
  ensureSiteId(out, context);
155420
155883
  if (!out.formId && out.formSlug) {