@riverbankcms/sdk 0.91.0 → 0.93.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 (118) hide show
  1. package/dist/{PreviewEditorSidebar-3TT47WCF.mjs → PreviewEditorSidebar-D3PAF7NW.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-ORCLLUNZ.mjs → PreviewEditorUI-G5JVJEIJ.mjs} +3 -3
  3. package/dist/SdkPreviewModeRuntime-NHTLRNQD.mjs +8 -0
  4. package/dist/_dts/api/src/bookingConfig.d.ts +13 -1
  5. package/dist/_dts/api/src/bookingOperations.d.ts +1 -0
  6. package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +6 -6
  7. package/dist/_dts/api/src/common/envelope.d.ts +10 -0
  8. package/dist/_dts/api/src/customerMembershipOutcomes.d.ts +4 -4
  9. package/dist/_dts/api/src/index.d.ts +2 -2
  10. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +6 -0
  11. package/dist/_dts/api/src/request.d.ts +1 -1
  12. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +32 -0
  13. package/dist/_dts/blocks/src/system/blocks/courses/shared/pricing.d.ts +12 -1
  14. package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +12 -0
  15. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +4 -1
  16. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +44 -0
  17. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +8 -0
  18. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +8 -1
  19. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +8 -1
  20. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -0
  21. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +4 -0
  22. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +40 -0
  23. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.reserved-fields.d.ts +1 -1
  24. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +29 -0
  25. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +1 -0
  26. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/components.d.ts +6 -0
  27. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +8 -0
  28. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +8 -0
  29. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +1 -0
  30. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +1 -1
  31. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +1 -0
  32. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +9 -0
  33. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +14 -14
  34. package/dist/_dts/content-editor/src/controller/useEntrySyncHelpers.d.ts +1 -1
  35. package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +5 -15
  36. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +46 -0
  37. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +43 -36
  38. package/dist/_dts/content-model/src/entry-slots/types.d.ts +110 -2
  39. package/dist/_dts/core/src/branded.d.ts +3 -0
  40. package/dist/_dts/core/src/event-pricing.d.ts +18 -1
  41. package/dist/_dts/core/src/money-input.d.ts +34 -4
  42. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +70 -0
  43. package/dist/_dts/media-core/src/fileAssetCompatibility.d.ts +1 -1
  44. package/dist/_dts/media-core/src/filePersistence.d.ts +5 -1
  45. package/dist/_dts/media-core/src/fileStorage.d.ts +1 -0
  46. package/dist/_dts/media-core/src/fileUploadFinalization.d.ts +29 -1
  47. package/dist/_dts/media-core/src/index.d.ts +1 -0
  48. package/dist/_dts/media-core/src/legacyMediaValue.d.ts +11 -0
  49. package/dist/_dts/media-core/src/videoPrep.d.ts +15 -6
  50. package/dist/_dts/media-core/src/videoSlotPolicy.d.ts +5 -5
  51. package/dist/_dts/media-react/src/hooks/useApiMediaUploader.d.ts +2 -1
  52. package/dist/_dts/sdk/src/cli/commands/push/execute/diff.d.ts +2 -0
  53. package/dist/_dts/sdk/src/cli/commands/push/execute/localMediaReporting.d.ts +23 -0
  54. package/dist/_dts/sdk/src/cli/commands/push/scopes/commandBackedDatedOfferingScope.d.ts +54 -0
  55. package/dist/_dts/sdk/src/cli/commands/push/scopes/mediaPrep.d.ts +7 -2
  56. package/dist/_dts/sdk/src/cli/commands/push/scopes/types.d.ts +6 -0
  57. package/dist/_dts/sdk/src/cli/media/local-sync.d.ts +35 -0
  58. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +23 -1
  59. package/dist/_dts/sdk/src/version.d.ts +1 -1
  60. package/dist/{chunk-GDT2QGIL.mjs → chunk-A63UXN3P.mjs} +21 -19
  61. package/dist/{chunk-U5YM4AWE.mjs → chunk-AJZGT6YG.mjs} +1 -1
  62. package/dist/{chunk-AFPMCLS7.mjs → chunk-AQ6RT6LZ.mjs} +2 -2
  63. package/dist/{chunk-ZA2S7H34.mjs → chunk-NT76QGIJ.mjs} +98 -1
  64. package/dist/{chunk-RQUZYSES.mjs → chunk-PCNCETBI.mjs} +1196 -426
  65. package/dist/{chunk-S3YHJWEU.mjs → chunk-XIK2HYI3.mjs} +7 -7
  66. package/dist/cli/index.mjs +749 -166
  67. package/dist/client/{accordion-AFX37652.mjs → accordion-RNQIPG55.mjs} +2 -2
  68. package/dist/client/{bookingForm-32V5QCOW.mjs → bookingForm-HYEEVRLP.mjs} +89 -14
  69. package/dist/client/bookings.mjs +243 -17
  70. package/dist/client/{carousel-TJGQJ7ER.mjs → carousel-W7DQ3YPU.mjs} +3 -3
  71. package/dist/client/{cart-JUU2JEW4.mjs → cart-PXJ3SXXO.mjs} +7 -7
  72. package/dist/client/{checkout-RD6BTFX4.mjs → checkout-X3JYSOXI.mjs} +7 -7
  73. package/dist/client/{chunk-MLBNVN4H.mjs → chunk-6SYGVVWA.mjs} +67 -4
  74. package/dist/client/{chunk-E6VIWZUG.mjs → chunk-DUOHLWLF.mjs} +3 -3
  75. package/dist/client/{chunk-6QZIBNGV.mjs → chunk-IXDSXF2D.mjs} +154 -16
  76. package/dist/client/{chunk-CKXEUWWA.mjs → chunk-J6TMMMXW.mjs} +3 -3
  77. package/dist/client/{chunk-PMNAV6LO.mjs → chunk-JNE6UI6U.mjs} +7 -6
  78. package/dist/client/{chunk-ISAUXU5R.mjs → chunk-OLAOAZEO.mjs} +1 -1
  79. package/dist/client/{chunk-RWYFG625.mjs → chunk-PCHACQEB.mjs} +30 -2
  80. package/dist/client/{chunk-FMZZHAIR.mjs → chunk-PICR3NTQ.mjs} +52 -5
  81. package/dist/client/{chunk-6RN62XBV.mjs → chunk-Q47XGAGS.mjs} +1 -1
  82. package/dist/client/{chunk-WHZQDPBZ.mjs → chunk-TNGL2WJF.mjs} +1 -0
  83. package/dist/client/{chunk-C4LP6BPG.mjs → chunk-WERRJXNJ.mjs} +1 -1
  84. package/dist/client/{chunk-RMOFBBNA.mjs → chunk-YYVGSYBO.mjs} +6 -6
  85. package/dist/client/client.mjs +641 -54
  86. package/dist/client/{courseRegistration-X63QAIVV.mjs → courseRegistration-QZ67PVHO.mjs} +111 -11
  87. package/dist/client/{eventCalendar-5T24GCZL.mjs → eventCalendar-V3BDHQNT.mjs} +9 -9
  88. package/dist/client/{eventCombined-AZVTF22X.mjs → eventCombined-XYFRN2RG.mjs} +9 -9
  89. package/dist/client/{eventDetails-7GPFNLGF.mjs → eventDetails-TFE5TWKV.mjs} +9 -9
  90. package/dist/client/{eventListing-QEUMTMUM.mjs → eventListing-IQ6AGWZ6.mjs} +9 -9
  91. package/dist/client/{eventRegistration-P2EDKCQZ.mjs → eventRegistration-WGJVFKQJ.mjs} +9 -9
  92. package/dist/client/{form-NUJ7H4IN.mjs → form-6UZY6RUA.mjs} +3 -3
  93. package/dist/client/{headerSection-JB7LECPL.mjs → headerSection-RSFXY6V3.mjs} +3 -3
  94. package/dist/client/hooks.mjs +57 -5
  95. package/dist/client/{locationMap-UEYWUCSW.mjs → locationMap-24FH67I4.mjs} +3 -3
  96. package/dist/client/{newsletterForm-S2YZQ2X7.mjs → newsletterForm-QVL3MLTN.mjs} +3 -3
  97. package/dist/client/{productDetail-H5MADGG7.mjs → productDetail-ZDYN3G4T.mjs} +7 -7
  98. package/dist/client/{productList-DK7YON7H.mjs → productList-4BMJLQHZ.mjs} +7 -7
  99. package/dist/client/rendering/client.mjs +503 -36
  100. package/dist/client/rendering/islands.mjs +19 -19
  101. package/dist/client/rendering.mjs +583 -39
  102. package/dist/client/{shop-6PA7RDRJ.mjs → shop-U5C634FF.mjs} +7 -7
  103. package/dist/preview-next/client/runtime.mjs +5 -5
  104. package/dist/{sdk-runtime-JP5347OB.mjs → sdk-runtime-VGV46WVB.mjs} +6 -6
  105. package/dist/server/components.mjs +287 -68
  106. package/dist/server/config-validation.mjs +58 -5
  107. package/dist/server/config.mjs +58 -5
  108. package/dist/server/data.mjs +57 -5
  109. package/dist/server/index.mjs +104 -29
  110. package/dist/server/next.mjs +347 -85
  111. package/dist/server/page-converter.mjs +22 -5
  112. package/dist/server/prebuild.mjs +1 -1
  113. package/dist/server/rendering/server.mjs +287 -68
  114. package/dist/server/rendering.mjs +287 -68
  115. package/dist/server/routing.mjs +131 -67
  116. package/dist/server/server.mjs +189 -94
  117. package/package.json +1 -1
  118. package/dist/SdkPreviewModeRuntime-GMCDQPZZ.mjs +0 -8
@@ -23,12 +23,13 @@ var init_result = __esm({
23
23
  });
24
24
 
25
25
  // ../core/src/branded.ts
26
- var unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId;
26
+ var unsafeAsMediaAssetId, unsafeAsStorageBucketName, unsafeAsStoragePath, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, unsafeAsFormId, unsafeAsPassId, unsafeAsCustomerPassId, unsafeAsAppointmentServiceId, unsafeAsAppointmentResourceId;
27
27
  var init_branded = __esm({
28
28
  "../core/src/branded.ts"() {
29
29
  "use strict";
30
30
  unsafeAsMediaAssetId = (id) => id;
31
31
  unsafeAsStorageBucketName = (value) => value;
32
+ unsafeAsStoragePath = (value) => value;
32
33
  unsafeAsPositiveByteCount = (value) => value;
33
34
  unsafeAsPositiveSeconds = (value) => value;
34
35
  unsafeAsFormId = (id) => id;
@@ -174,6 +175,7 @@ function publicEventPricingType(pricing) {
174
175
  return "free";
175
176
  case "single_paid":
176
177
  case "ticket_types":
178
+ case "sliding_scale":
177
179
  case "course":
178
180
  return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
179
181
  case "external":
@@ -186,6 +188,7 @@ function publicEventPricingCurrency(pricing) {
186
188
  case "free_registration":
187
189
  case "single_paid":
188
190
  case "ticket_types":
191
+ case "sliding_scale":
189
192
  return pricing.currency;
190
193
  case "course":
191
194
  return pricing.display.display.currency;
@@ -203,6 +206,8 @@ function publicEventPricingMode(pricing) {
203
206
  return "single";
204
207
  case "ticket_types":
205
208
  return "ticket_types";
209
+ case "sliding_scale":
210
+ return "sliding_scale";
206
211
  case "drop_in":
207
212
  case "course":
208
213
  case "external":
@@ -236,6 +241,8 @@ function formatCoursePriceDisplayLabel(display, options) {
236
241
  return `Course (${formatCurrencyAmount(display.amount, display.currency, options)})`;
237
242
  case "from":
238
243
  return `Course (From ${formatCurrencyAmount(display.amount, display.currency, options)})`;
244
+ case "range":
245
+ return `Course (${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)})`;
239
246
  default:
240
247
  return assertNever(display);
241
248
  }
@@ -1039,9 +1046,20 @@ var init_types = __esm({
1039
1046
  });
1040
1047
 
1041
1048
  // ../media-core/src/fileSafety.ts
1049
+ function containsUnsafePathSegmentCharacter(value) {
1050
+ return value.includes("/") || value.includes("\\") || CONTROL_CHARACTER_PATTERN.test(value);
1051
+ }
1052
+ function isReservedPathSegment(value) {
1053
+ return value === "." || value === "..";
1054
+ }
1055
+ function isUnsafePathSegment(segment) {
1056
+ return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
1057
+ }
1058
+ var CONTROL_CHARACTER_PATTERN;
1042
1059
  var init_fileSafety = __esm({
1043
1060
  "../media-core/src/fileSafety.ts"() {
1044
1061
  "use strict";
1062
+ CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f]/u;
1045
1063
  }
1046
1064
  });
1047
1065
 
@@ -1081,11 +1099,21 @@ var init_fileDomain = __esm({
1081
1099
  });
1082
1100
 
1083
1101
  // ../media-core/src/fileStorage.ts
1102
+ function parseStoragePath(value) {
1103
+ return joinStoragePathSegments(value.split("/"));
1104
+ }
1105
+ function joinStoragePathSegments(segments) {
1106
+ if (segments.some(isUnsafePathSegment)) {
1107
+ return err("unsafe-path-segment");
1108
+ }
1109
+ return ok(unsafeAsStoragePath(segments.join("/")));
1110
+ }
1084
1111
  var FILE_STORAGE_BUCKETS, PUBLIC_SITE_FILE_STORAGE_BUCKETS, PRIVATE_SITE_FILE_BUCKET_MIME_TYPES, TEMP_UPLOAD_BUCKET_MIME_TYPES;
1085
1112
  var init_fileStorage = __esm({
1086
1113
  "../media-core/src/fileStorage.ts"() {
1087
1114
  "use strict";
1088
1115
  init_src();
1116
+ init_fileSafety();
1089
1117
  FILE_STORAGE_BUCKETS = {
1090
1118
  publicSite: unsafeAsStorageBucketName("media"),
1091
1119
  privateSite: unsafeAsStorageBucketName("site-files-private"),
@@ -1271,14 +1299,18 @@ var init_uploadVerificationContract = __esm({
1271
1299
  });
1272
1300
 
1273
1301
  // ../media-core/src/videoPrep.ts
1302
+ function unsafeAsPositiveVideoDurationSeconds(value) {
1303
+ return value;
1304
+ }
1274
1305
  var VIDEO_PREP_LIMITS;
1275
1306
  var init_videoPrep = __esm({
1276
1307
  "../media-core/src/videoPrep.ts"() {
1277
1308
  "use strict";
1309
+ init_src();
1278
1310
  VIDEO_PREP_LIMITS = {
1279
- maxRawByteCount: 500 * 1024 * 1024,
1280
- inlineContentMaxDurationSeconds: 60,
1281
- backgroundVideoMaxDurationSeconds: 30,
1311
+ maxRawByteCount: unsafeAsPositiveByteCount(500 * 1024 * 1024),
1312
+ inlineContentMaxDurationSeconds: unsafeAsPositiveVideoDurationSeconds(60),
1313
+ backgroundVideoMaxDurationSeconds: unsafeAsPositiveVideoDurationSeconds(30),
1282
1314
  targetMaxDimensionPixels: 1080
1283
1315
  };
1284
1316
  }
@@ -1349,10 +1381,10 @@ var init_identifiers = __esm({
1349
1381
 
1350
1382
  // ../media-core/src/url.ts
1351
1383
  function isRelativeDirectImageStoragePath(storagePath) {
1352
- return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix));
1384
+ return RELATIVE_STORAGE_PATH_PREFIXES.some((prefix) => storagePath.startsWith(prefix)) && parseStoragePath(storagePath).ok;
1353
1385
  }
1354
1386
  function isSiteScopedDirectImageStoragePath(storagePath) {
1355
- return storagePath.startsWith("sites/");
1387
+ return storagePath.startsWith("sites/") && parseStoragePath(storagePath).ok;
1356
1388
  }
1357
1389
  function encodeStoragePath(storagePath) {
1358
1390
  return storagePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
@@ -1433,6 +1465,7 @@ var DEFAULT_BASE_PATH, RELATIVE_STORAGE_PATH_PREFIXES, formatNumber, ORDER, getI
1433
1465
  var init_url = __esm({
1434
1466
  "../media-core/src/url.ts"() {
1435
1467
  "use strict";
1468
+ init_fileStorage();
1436
1469
  DEFAULT_BASE_PATH = "/api/img";
1437
1470
  RELATIVE_STORAGE_PATH_PREFIXES = [
1438
1471
  "originals/",
@@ -1676,6 +1709,28 @@ var init_renderableMediaAsset = __esm({
1676
1709
  }
1677
1710
  });
1678
1711
 
1712
+ // ../media-core/src/legacyMediaValue.ts
1713
+ function legacyStringMediaTypeForField(field) {
1714
+ if (field.type === "file") {
1715
+ return field.fileKinds?.[0] ?? "document";
1716
+ }
1717
+ return field.mediaKinds?.[0] ?? "image";
1718
+ }
1719
+ function normalizeLegacyStringMediaValueForField(value, field) {
1720
+ if (typeof value !== "string") return value;
1721
+ const src = value.trim();
1722
+ if (!src) return value;
1723
+ return {
1724
+ type: legacyStringMediaTypeForField(field),
1725
+ src
1726
+ };
1727
+ }
1728
+ var init_legacyMediaValue = __esm({
1729
+ "../media-core/src/legacyMediaValue.ts"() {
1730
+ "use strict";
1731
+ }
1732
+ });
1733
+
1679
1734
  // ../media-core/src/index.ts
1680
1735
  var init_src2 = __esm({
1681
1736
  "../media-core/src/index.ts"() {
@@ -1718,6 +1773,7 @@ var init_src2 = __esm({
1718
1773
  init_mediaUsageProjection();
1719
1774
  init_portableMediaReferences();
1720
1775
  init_renderableMediaAsset();
1776
+ init_legacyMediaValue();
1721
1777
  }
1722
1778
  });
1723
1779
 
@@ -22919,9 +22975,12 @@ var init_schemas = __esm({
22919
22975
  });
22920
22976
  coursePricingSchema = z45.object({
22921
22977
  bookingRequirement: z45.enum(["none", "required"]),
22922
- pricingStrategy: z45.enum(["free", "single", "tiered"]),
22978
+ pricingStrategy: z45.enum(["free", "single", "tiered", "sliding_scale"]),
22923
22979
  currency: z45.string(),
22924
22980
  singlePriceAmount: z45.number().nullable(),
22981
+ slidingMinAmount: z45.number().nullable().optional(),
22982
+ slidingMaxAmount: z45.number().nullable().optional(),
22983
+ slidingSuggestedAmount: z45.number().nullable().optional(),
22925
22984
  paymentTerms: blockBookingPaymentTermsSchema,
22926
22985
  options: z45.array(coursePricingOptionSchema)
22927
22986
  });
@@ -23086,6 +23145,19 @@ var init_schemas2 = __esm({
23086
23145
  ticketTypes: z46.array(publicEventTicketTypeSchema),
23087
23146
  display: publicEventTicketTypePriceDisplaySchema
23088
23147
  }),
23148
+ z46.object({
23149
+ kind: z46.literal("sliding_scale"),
23150
+ minAmount: z46.number(),
23151
+ maxAmount: z46.number(),
23152
+ suggestedAmount: z46.number().nullable(),
23153
+ currency: z46.string(),
23154
+ display: z46.object({
23155
+ kind: z46.literal("range"),
23156
+ minAmount: z46.number(),
23157
+ maxAmount: z46.number(),
23158
+ currency: z46.string()
23159
+ })
23160
+ }),
23089
23161
  z46.object({
23090
23162
  kind: z46.literal("course"),
23091
23163
  display: z46.object({ kind: z46.literal("course"), display: publicCoursePriceDisplaySchema })
@@ -23554,7 +23626,7 @@ function isRecord6(value) {
23554
23626
  }
23555
23627
  function isPublicEventPricing(value) {
23556
23628
  if (!isRecord6(value) || typeof value.kind !== "string") return false;
23557
- return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
23629
+ return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "sliding_scale" || value.kind === "ticket_types" || value.kind === "course" || value.kind === "external";
23558
23630
  }
23559
23631
  function isPublicEventTicketType(value) {
23560
23632
  return isRecord6(value) && typeof value.id === "string";
@@ -24067,7 +24139,9 @@ function getSelectableCoursePricingOptionsForNow(course, now) {
24067
24139
  return left.name.localeCompare(right.name);
24068
24140
  });
24069
24141
  }
24070
- function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {}) {
24142
+ function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
24143
+ const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
24144
+ const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
24071
24145
  const currency = course.pricing?.currency ?? course.currency;
24072
24146
  if (!course.pricing) {
24073
24147
  const legacyAmount = course.priceCents ?? 0;
@@ -24077,6 +24151,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
24077
24151
  selectableOptions: [],
24078
24152
  requiresSelection: false,
24079
24153
  selectedOption: null,
24154
+ slidingScale: null,
24155
+ selectedSlidingAmount: null,
24080
24156
  selectedPriceAmount: legacyAmount,
24081
24157
  selectedRequiresPayment: legacyAmount > 0,
24082
24158
  hasPaidSelection: legacyAmount > 0,
@@ -24091,6 +24167,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
24091
24167
  selectableOptions: [],
24092
24168
  requiresSelection: false,
24093
24169
  selectedOption: null,
24170
+ slidingScale: null,
24171
+ selectedSlidingAmount: null,
24094
24172
  selectedPriceAmount: 0,
24095
24173
  selectedRequiresPayment: false,
24096
24174
  hasPaidSelection: false,
@@ -24104,6 +24182,8 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
24104
24182
  selectableOptions: [],
24105
24183
  requiresSelection: false,
24106
24184
  selectedOption: null,
24185
+ slidingScale: null,
24186
+ selectedSlidingAmount: null,
24107
24187
  selectedPriceAmount: amount,
24108
24188
  selectedRequiresPayment: amount > 0,
24109
24189
  hasPaidSelection: amount > 0,
@@ -24113,7 +24193,7 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
24113
24193
  case "tiered": {
24114
24194
  const selectableOptions = getSelectableCoursePricingOptionsForNow(
24115
24195
  course,
24116
- resolvePlanningDateInput(nowInput)
24196
+ resolvePlanningDateInput(effectiveNowInput)
24117
24197
  );
24118
24198
  const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
24119
24199
  const lowestAmount = selectableOptions.reduce((lowest, option) => {
@@ -24129,12 +24209,51 @@ function resolveCoursePricingState(course, selectedPricingOptionId, nowInput = {
24129
24209
  selectableOptions,
24130
24210
  requiresSelection: selectableOptions.length > 1,
24131
24211
  selectedOption,
24212
+ slidingScale: null,
24213
+ selectedSlidingAmount: null,
24132
24214
  selectedPriceAmount: selectedOption?.priceAmount ?? null,
24133
24215
  selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
24134
24216
  hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
24135
24217
  hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
24136
24218
  };
24137
24219
  }
24220
+ case "sliding_scale": {
24221
+ const minAmount = course.pricing.slidingMinAmount ?? null;
24222
+ const maxAmount = course.pricing.slidingMaxAmount ?? null;
24223
+ if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) {
24224
+ return {
24225
+ currency,
24226
+ display: { kind: "unavailable", currency },
24227
+ selectableOptions: [],
24228
+ requiresSelection: true,
24229
+ selectedOption: null,
24230
+ slidingScale: null,
24231
+ selectedSlidingAmount: null,
24232
+ selectedPriceAmount: null,
24233
+ selectedRequiresPayment: false,
24234
+ hasPaidSelection: false,
24235
+ hasFreeSelection: false
24236
+ };
24237
+ }
24238
+ const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
24239
+ return {
24240
+ currency,
24241
+ display: { kind: "range", minAmount, maxAmount, currency },
24242
+ selectableOptions: [],
24243
+ requiresSelection: normalizedSelectedAmount === null,
24244
+ selectedOption: null,
24245
+ slidingScale: {
24246
+ minAmount,
24247
+ maxAmount,
24248
+ suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
24249
+ },
24250
+ selectedSlidingAmount: normalizedSelectedAmount,
24251
+ selectedPriceAmount: normalizedSelectedAmount,
24252
+ selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
24253
+ hasPaidSelection: maxAmount > 0,
24254
+ hasFreeSelection: minAmount === 0
24255
+ };
24256
+ }
24138
24257
  }
24139
24258
  }
24140
24259
  function formatCoursePriceDisplay(display, locale) {
@@ -29382,6 +29501,7 @@ var init_booking_form_reserved_fields = __esm({
29382
29501
  "selectedDate",
29383
29502
  "selectedSlot",
29384
29503
  "discountCode",
29504
+ "selectedSlidingAmountInput",
29385
29505
  "selectedCollectionOptionKind",
29386
29506
  "selectedAppointmentPackageId"
29387
29507
  ];
@@ -29667,6 +29787,32 @@ function readOptionalString(value) {
29667
29787
  function readOptionalNumber(value) {
29668
29788
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
29669
29789
  }
29790
+ function getBookingServiceSlidingScale(service) {
29791
+ const pricing = service?.pricing;
29792
+ if (!pricing || pricing.pricingStrategy !== "sliding_scale" || pricing.slidingMinAmount === null || pricing.slidingMinAmount === void 0 || pricing.slidingMaxAmount === null || pricing.slidingMaxAmount === void 0) {
29793
+ return null;
29794
+ }
29795
+ return {
29796
+ minAmount: pricing.slidingMinAmount,
29797
+ maxAmount: pricing.slidingMaxAmount,
29798
+ suggestedAmount: pricing.slidingSuggestedAmount ?? null,
29799
+ currency: pricing.currency
29800
+ };
29801
+ }
29802
+ function parseBookingCurrencyInputToCents(value) {
29803
+ const trimmed = value?.trim() ?? "";
29804
+ if (!trimmed) return null;
29805
+ if (!/^(?:\d+(?:\.\d{0,2})?|\.\d{1,2})$/.test(trimmed)) return null;
29806
+ const parsed = Number(trimmed);
29807
+ if (!Number.isFinite(parsed) || parsed < 0) return null;
29808
+ return Math.round(parsed * 100);
29809
+ }
29810
+ function formatBookingCentsAsCurrencyInput(amount) {
29811
+ return amount % 100 === 0 ? String(amount / 100) : (amount / 100).toFixed(2);
29812
+ }
29813
+ function isBookingServiceSlidingAmountInRange(slidingScale, selectedAmount) {
29814
+ return selectedAmount !== null && selectedAmount >= slidingScale.minAmount && selectedAmount <= slidingScale.maxAmount;
29815
+ }
29670
29816
  function readStringArray(value) {
29671
29817
  if (!Array.isArray(value)) return void 0;
29672
29818
  const strings = value.filter((item) => typeof item === "string");
@@ -29855,6 +30001,20 @@ function prepareBookingSubmission(input) {
29855
30001
  };
29856
30002
  }
29857
30003
  const paymentSelectionMode = getBookingServicePaymentSelectionMode(selectedService);
30004
+ const slidingScale = getBookingServiceSlidingScale(selectedService);
30005
+ const selectedSlidingAmount = parseBookingCurrencyInputToCents(
30006
+ input.data.selectedSlidingAmountInput
30007
+ );
30008
+ if (slidingScale && !isBookingServiceSlidingAmountInRange(slidingScale, selectedSlidingAmount)) {
30009
+ return {
30010
+ ok: false,
30011
+ error: {
30012
+ tag: selectedSlidingAmount === null ? "sliding-amount-required" : "sliding-amount-out-of-range",
30013
+ serviceId,
30014
+ serviceTitle: selectedService.title || serviceId
30015
+ }
30016
+ };
30017
+ }
29858
30018
  if (paymentSelectionMode === "choice_required" && !toSelectedCollectionOptionKind(input.data.selectedCollectionOptionKind)) {
29859
30019
  return {
29860
30020
  ok: false,
@@ -29882,6 +30042,7 @@ function prepareBookingSubmission(input) {
29882
30042
  ...common,
29883
30043
  kind: "standard",
29884
30044
  ...discountCode ? { discountCode } : {},
30045
+ ...slidingScale && selectedSlidingAmount !== null ? { selectedSlidingAmount } : {},
29885
30046
  ...selectedCollectionOptionKind ? { selectedCollectionOptionKind } : {},
29886
30047
  altchaSolution: input.altchaSolution ?? null
29887
30048
  }
@@ -29895,6 +30056,10 @@ function formatBookingSubmissionPreparationError(error) {
29895
30056
  return `Service not found: ${error.serviceId}`;
29896
30057
  case "payment-option-required":
29897
30058
  return `Please choose how you want to pay for "${error.serviceTitle}".`;
30059
+ case "sliding-amount-required":
30060
+ return `Please choose an amount for "${error.serviceTitle}".`;
30061
+ case "sliding-amount-out-of-range":
30062
+ return `Please choose an amount within the sliding scale for "${error.serviceTitle}".`;
29898
30063
  case "payment-option-unsupported":
29899
30064
  return `Service "${error.serviceTitle}" has a payment option that is not supported yet.`;
29900
30065
  case "service-missing-duration":
@@ -30045,6 +30210,7 @@ var init_booking_form_interactive = __esm({
30045
30210
  title: z66.string(),
30046
30211
  description: z66.string().nullable().optional().transform((value) => value ?? void 0),
30047
30212
  durationMinutes: z66.number().optional(),
30213
+ pricing: z66.custom().optional(),
30048
30214
  priceAmount: z66.number().nullable().optional(),
30049
30215
  priceCurrency: z66.string().nullable().optional(),
30050
30216
  paymentTerms: blockBookingPaymentTermsSchema.optional(),
@@ -32892,7 +33058,7 @@ var init_embla_carousel_autoplay_esm = __esm({
32892
33058
  function isObject(subject) {
32893
33059
  return Object.prototype.toString.call(subject) === "[object Object]";
32894
33060
  }
32895
- function isRecord15(subject) {
33061
+ function isRecord16(subject) {
32896
33062
  return isObject(subject) || Array.isArray(subject);
32897
33063
  }
32898
33064
  function canUseDOM() {
@@ -32909,7 +33075,7 @@ function areOptionsEqual(optionsA, optionsB) {
32909
33075
  const valueA = optionsA[key];
32910
33076
  const valueB = optionsB[key];
32911
33077
  if (typeof valueA === "function") return `${valueA}` === `${valueB}`;
32912
- if (!isRecord15(valueA) || !isRecord15(valueB)) return valueA === valueB;
33078
+ if (!isRecord16(valueA) || !isRecord16(valueB)) return valueA === valueB;
32913
33079
  return areOptionsEqual(valueA, valueB);
32914
33080
  });
32915
33081
  }
@@ -34963,12 +35129,13 @@ var init_carousel_client = __esm({
34963
35129
  ]
34964
35130
  );
34965
35131
  const resolvedSlides = resolveSlidesToShowMobile(normalized.slidesToShow);
35132
+ const canAutoplay = normalized.autoplay && slides.length > 1;
34966
35133
  const cssVars = React12.useMemo(
34967
35134
  () => getCarouselSlidesToShowCssVars(normalized.slidesToShow),
34968
35135
  [normalized.slidesToShow]
34969
35136
  );
34970
35137
  const plugins = React12.useMemo(() => {
34971
- if (!normalized.autoplay) return void 0;
35138
+ if (!canAutoplay) return void 0;
34972
35139
  return [
34973
35140
  Autoplay({
34974
35141
  delay: normalized.autoplayDelay,
@@ -34978,7 +35145,7 @@ var init_carousel_client = __esm({
34978
35145
  // Continue after manual navigation
34979
35146
  })
34980
35147
  ];
34981
- }, [normalized.autoplay, normalized.autoplayDelay]);
35148
+ }, [canAutoplay, normalized.autoplayDelay]);
34982
35149
  const [viewportRef, api] = useEmblaCarousel(
34983
35150
  {
34984
35151
  align: "start",
@@ -35017,7 +35184,7 @@ var init_carousel_client = __esm({
35017
35184
  };
35018
35185
  }, [api]);
35019
35186
  React12.useEffect(() => {
35020
- if (!api || !normalized.autoplay) return;
35187
+ if (!api || !canAutoplay) return;
35021
35188
  const autoplayPlugin = api.plugins()?.autoplay;
35022
35189
  if (!autoplayPlugin) return;
35023
35190
  const handleVisibility = () => {
@@ -35026,7 +35193,7 @@ var init_carousel_client = __esm({
35026
35193
  };
35027
35194
  document.addEventListener("visibilitychange", handleVisibility);
35028
35195
  return () => document.removeEventListener("visibilitychange", handleVisibility);
35029
- }, [api, normalized.autoplay]);
35196
+ }, [api, canAutoplay]);
35030
35197
  const inner = /* @__PURE__ */ jsxs53(Fragment13, { children: [
35031
35198
  /* @__PURE__ */ jsx68("div", { className: "carousel-frame rb-overflow-hidden rb-w-full", children: /* @__PURE__ */ jsx68(
35032
35199
  "div",
@@ -35077,7 +35244,7 @@ var init_carousel_client = __esm({
35077
35244
  "data-show-controls": normalized.showControls ? "true" : "false",
35078
35245
  "data-show-dots": normalized.showDots ? "true" : "false",
35079
35246
  "data-arrow-visibility": normalized.arrowVisibility,
35080
- "data-autoplay": normalized.autoplay ? "true" : "false",
35247
+ "data-autoplay": canAutoplay ? "true" : "false",
35081
35248
  "data-loop": normalized.loop ? "true" : "false",
35082
35249
  children: inner
35083
35250
  }
@@ -35724,7 +35891,7 @@ function encodePublicProductCategorySelector2(selector) {
35724
35891
  };
35725
35892
  }
35726
35893
  }
35727
- function isRecord16(value) {
35894
+ function isRecord17(value) {
35728
35895
  return typeof value === "object" && value !== null;
35729
35896
  }
35730
35897
  function isJsonResponseContentType(contentType) {
@@ -35747,10 +35914,10 @@ async function parseJsonBody(response) {
35747
35914
  }
35748
35915
  }
35749
35916
  function getBlockApiErrorDetails(data) {
35750
- if (!isRecord16(data)) {
35917
+ if (!isRecord17(data)) {
35751
35918
  return {};
35752
35919
  }
35753
- const nestedError = isRecord16(data.error) ? data.error : void 0;
35920
+ const nestedError = isRecord17(data.error) ? data.error : void 0;
35754
35921
  const message = typeof nestedError?.message === "string" ? nestedError.message : typeof data.message === "string" ? data.message : void 0;
35755
35922
  const code = typeof nestedError?.code === "string" ? nestedError.code : typeof data.code === "string" ? data.code : void 0;
35756
35923
  return { message, code };
@@ -36080,6 +36247,7 @@ function createBlockApi(config) {
36080
36247
  body: {
36081
36248
  courseId: data.courseId,
36082
36249
  ...data.pricingOptionId ? { pricingOptionId: data.pricingOptionId } : {},
36250
+ ...data.selectedSlidingAmount !== void 0 ? { selectedSlidingAmount: data.selectedSlidingAmount } : {},
36083
36251
  email: data.email,
36084
36252
  name: data.name,
36085
36253
  phone: data.phone,
@@ -40280,6 +40448,7 @@ function useBookingSubmission(_siteId) {
40280
40448
  customFields: data.customFields,
40281
40449
  timezone: data.timezone,
40282
40450
  discountCode: data.discountCode,
40451
+ selectedSlidingAmount: data.selectedSlidingAmount,
40283
40452
  selectedCollectionOptionKind: data.selectedCollectionOptionKind,
40284
40453
  altchaSolution: data.altchaSolution ?? null,
40285
40454
  successUrl: data.successUrl,
@@ -40808,6 +40977,9 @@ function createInitialBookingFlowReducerState(input) {
40808
40977
  fieldValues: collectInitialFieldValues(initialData),
40809
40978
  touchedFields: {},
40810
40979
  discountCode: toOptionalString(initialData.discountCode) ?? "",
40980
+ selectedSlidingAmountInput: toOptionalString(
40981
+ initialData.selectedSlidingAmountInput
40982
+ ) ?? "",
40811
40983
  selectedCollectionOptionKind: toSelectedCollectionOptionKind(
40812
40984
  initialData.selectedCollectionOptionKind
40813
40985
  ),
@@ -40860,6 +41032,7 @@ function bookingFlowReducer(state, event) {
40860
41032
  selectedDate: void 0,
40861
41033
  selectedSlot: null,
40862
41034
  selectedAppointmentPackageId: void 0,
41035
+ selectedSlidingAmountInput: "",
40863
41036
  selectedCollectionOptionKind: void 0,
40864
41037
  validationErrors: clearBookingFormError(state.validationErrors)
40865
41038
  };
@@ -40913,6 +41086,13 @@ function bookingFlowReducer(state, event) {
40913
41086
  selectedAppointmentPackageId: void 0,
40914
41087
  validationErrors: clearBookingFormError(state.validationErrors)
40915
41088
  };
41089
+ case "sliding-amount-changed":
41090
+ return {
41091
+ ...state,
41092
+ selectedSlidingAmountInput: event.value,
41093
+ selectedAppointmentPackageId: void 0,
41094
+ validationErrors: clearBookingFormError(state.validationErrors)
41095
+ };
40916
41096
  case "appointment-package-selected":
40917
41097
  return {
40918
41098
  ...state,
@@ -41015,6 +41195,7 @@ function toBookingFormData(state) {
41015
41195
  selectedDate: state.selectedDate,
41016
41196
  selectedSlot: state.selectedSlot?.startAt,
41017
41197
  discountCode: state.discountCode || void 0,
41198
+ selectedSlidingAmountInput: state.selectedSlidingAmountInput || void 0,
41018
41199
  selectedCollectionOptionKind: state.selectedCollectionOptionKind,
41019
41200
  selectedAppointmentPackageId: state.selectedAppointmentPackageId
41020
41201
  };
@@ -41032,7 +41213,8 @@ function buildBookingStepResolution(input) {
41032
41213
  input.form.settings?.serviceIds && input.form.settings.serviceIds.length > 1
41033
41214
  );
41034
41215
  const selectedService = paymentResolution.service;
41035
- const needsPayment = paymentResolution.mode !== "hidden" || Boolean(
41216
+ const selectedServiceSlidingScale = getBookingServiceSlidingScale(selectedService);
41217
+ const needsPayment = Boolean(selectedServiceSlidingScale) || paymentResolution.mode !== "hidden" || Boolean(
41036
41218
  input.enableAppointmentPackages && selectedService && (selectedService.priceAmount ?? 0) > 0
41037
41219
  );
41038
41220
  const hasFields = Boolean(input.form.schema?.fields.length);
@@ -41076,6 +41258,18 @@ function validateBookingStep(input) {
41076
41258
  services: input.services,
41077
41259
  defaultServiceId: input.defaultServiceId
41078
41260
  });
41261
+ const slidingScale = getBookingServiceSlidingScale(resolution.service);
41262
+ if (slidingScale && !isBookingServiceSlidingAmountInRange(
41263
+ slidingScale,
41264
+ parseBookingCurrencyInputToCents(input.data.selectedSlidingAmountInput)
41265
+ )) {
41266
+ return {
41267
+ ok: false,
41268
+ errors: createFormBookingValidationError(
41269
+ "Please choose an amount within the sliding scale"
41270
+ )
41271
+ };
41272
+ }
41079
41273
  if (resolution.mode === "hidden" || resolution.mode === "disclosure_only") {
41080
41274
  return { ok: true };
41081
41275
  }
@@ -41474,6 +41668,7 @@ var init_useHeadlessBookingFlow_state = __esm({
41474
41668
  "../blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.ts"() {
41475
41669
  "use strict";
41476
41670
  init_booking_form_headless_state();
41671
+ init_booking_form_state();
41477
41672
  }
41478
41673
  });
41479
41674
 
@@ -41513,11 +41708,27 @@ function useHeadlessBookingFlow(options) {
41513
41708
  const selectedServiceId = state.selectedServiceId ?? defaultServiceId;
41514
41709
  const selectedResourceId = state.selectedResourceId ?? defaultResourceId;
41515
41710
  const selectedService = options.services.find((service) => service.id === selectedServiceId) ?? null;
41711
+ const lastSlidingServiceIdRef = useRef9(null);
41712
+ useEffect10(() => {
41713
+ const selectedId = selectedService?.id ?? null;
41714
+ if (lastSlidingServiceIdRef.current === selectedId) return;
41715
+ lastSlidingServiceIdRef.current = selectedId;
41716
+ const slidingScale = getBookingServiceSlidingScale(selectedService);
41717
+ dispatch({
41718
+ type: "sliding-amount-changed",
41719
+ value: slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatBookingCentsAsCurrencyInput(slidingScale.suggestedAmount) : ""
41720
+ });
41721
+ }, [selectedService]);
41516
41722
  const hasPortalBearerAuth = (api.config.authOverrides?.portal ?? api.config.auth).type === "bearer";
41723
+ const selectedServiceSlidingScale = getBookingServiceSlidingScale(selectedService);
41724
+ const selectedSlidingAmount = parseBookingCurrencyInputToCents(
41725
+ state.selectedSlidingAmountInput
41726
+ );
41727
+ const selectedAppointmentPriceAmount = selectedServiceSlidingScale && selectedSlidingAmount !== null ? selectedSlidingAmount : selectedService?.priceAmount ?? 0;
41517
41728
  const canLoadAppointmentPackages = Boolean(
41518
- options.enableAppointmentPackages && hasPortalBearerAuth && selectedService && (selectedService.priceAmount ?? 0) > 0
41729
+ options.enableAppointmentPackages && hasPortalBearerAuth && selectedService && !selectedServiceSlidingScale && (selectedService.priceAmount ?? 0) > 0
41519
41730
  );
41520
- const appointmentPackagesUnavailableReason = !options.enableAppointmentPackages ? "disabled" : !selectedService || (selectedService.priceAmount ?? 0) <= 0 ? "missing-priced-service" : !hasPortalBearerAuth ? "missing-portal-auth" : null;
41731
+ const appointmentPackagesUnavailableReason = !options.enableAppointmentPackages ? "disabled" : !selectedService || selectedServiceSlidingScale || (selectedService.priceAmount ?? 0) <= 0 ? "missing-priced-service" : !hasPortalBearerAuth ? "missing-portal-auth" : null;
41521
41732
  const data = useMemo8(() => toBookingFormData(state), [state]);
41522
41733
  const availabilityDatesQuery = useMemo8(
41523
41734
  () => buildBookingAvailabilityQuery({
@@ -41747,13 +41958,13 @@ function useHeadlessBookingFlow(options) {
41747
41958
  state.selectedSlot
41748
41959
  ]);
41749
41960
  const appointmentDiscountContext = useMemo8(
41750
- () => selectedService && (selectedService.priceAmount ?? 0) > 0 ? { type: "appointment", serviceId: selectedService.id } : null,
41751
- [selectedService?.id, selectedService?.priceAmount]
41961
+ () => selectedService && selectedAppointmentPriceAmount > 0 ? { type: "appointment", serviceId: selectedService.id } : null,
41962
+ [selectedAppointmentPriceAmount, selectedService?.id]
41752
41963
  );
41753
41964
  const discountUi = useDiscountCodeUi({
41754
41965
  api,
41755
41966
  discountContext: appointmentDiscountContext,
41756
- subtotalCents: selectedService?.priceAmount ?? 0
41967
+ subtotalCents: selectedAppointmentPriceAmount
41757
41968
  });
41758
41969
  const { submit, clearFeedback } = useBookingSubmission(options.siteId);
41759
41970
  const submittingRef = useRef9(false);
@@ -41896,6 +42107,7 @@ function useHeadlessBookingFlow(options) {
41896
42107
  type: "appointment-package-selected",
41897
42108
  packageId: packageId ? unsafeAsCustomerPassId(packageId) : null
41898
42109
  }),
42110
+ setSlidingAmountInput: (value) => dispatch({ type: "sliding-amount-changed", value }),
41899
42111
  setDiscountCode: (code) => {
41900
42112
  dispatch({ type: "discount-code-changed", code });
41901
42113
  latestRef.current.setDiscountCode(code);
@@ -41966,11 +42178,11 @@ function useHeadlessBookingFlow(options) {
41966
42178
  () => selectedService && paymentResolution.mode !== "unsupported" ? buildBookingPaymentSelectionViewModel({
41967
42179
  serviceTitle: selectedService.title,
41968
42180
  paymentTerms: selectedService.paymentTerms,
41969
- priceAmount: selectedService.priceAmount,
42181
+ priceAmount: selectedAppointmentPriceAmount,
41970
42182
  priceCurrency: selectedService.priceCurrency,
41971
42183
  bookingStartAt: state.selectedSlot?.startAt
41972
42184
  }) : null,
41973
- [paymentResolution.mode, selectedService, state.selectedSlot?.startAt]
42185
+ [paymentResolution.mode, selectedAppointmentPriceAmount, selectedService, state.selectedSlot?.startAt]
41974
42186
  );
41975
42187
  const appointmentPackageItems = appointmentPackages.tag === "loaded" ? appointmentPackages.value : [];
41976
42188
  const selectedAppointmentPackage = appointmentPackageItems.find(
@@ -41999,6 +42211,9 @@ function useHeadlessBookingFlow(options) {
41999
42211
  selection: null,
42000
42212
  selectedCollectionOptionKind: state.selectedCollectionOptionKind,
42001
42213
  selectedAppointmentPackageId: state.selectedAppointmentPackageId,
42214
+ selectedSlidingAmountInput: state.selectedSlidingAmountInput,
42215
+ selectedSlidingAmount,
42216
+ slidingScale: selectedServiceSlidingScale,
42002
42217
  appointmentPackages: appointmentPackagesModel,
42003
42218
  errorMessage: paymentResolution.errorMessage ?? "This service cannot be booked right now."
42004
42219
  } : {
@@ -42007,6 +42222,9 @@ function useHeadlessBookingFlow(options) {
42007
42222
  selection: paymentSelection,
42008
42223
  selectedCollectionOptionKind: state.selectedCollectionOptionKind,
42009
42224
  selectedAppointmentPackageId: state.selectedAppointmentPackageId,
42225
+ selectedSlidingAmountInput: state.selectedSlidingAmountInput,
42226
+ selectedSlidingAmount,
42227
+ slidingScale: selectedServiceSlidingScale,
42010
42228
  appointmentPackages: appointmentPackagesModel
42011
42229
  };
42012
42230
  return {
@@ -42621,6 +42839,9 @@ var init_FieldValidationMessage = __esm({
42621
42839
 
42622
42840
  // ../blocks/src/system/runtime/nodes/booking-form.default-ui.tsx
42623
42841
  import { Fragment as Fragment15, jsx as jsx78, jsxs as jsxs59 } from "react/jsx-runtime";
42842
+ function formatBookingAmount(amount, currency) {
42843
+ return formatCurrencyAmount(amount, currency, { decimals: "auto" });
42844
+ }
42624
42845
  function HeadlessBookingDefaultForm({
42625
42846
  booking,
42626
42847
  onSubmit
@@ -42897,6 +43118,7 @@ function HeadlessBookingPaymentSelectionStep({
42897
43118
  }
42898
43119
  const packageOptions = booking.payment.appointmentPackages.items;
42899
43120
  const hasPackageOptions = packageOptions.length > 0;
43121
+ const slidingScale = booking.payment.slidingScale;
42900
43122
  return /* @__PURE__ */ jsxs59("div", { className: "ab-stack", children: [
42901
43123
  /* @__PURE__ */ jsxs59("div", { className: "ab-info-box", children: [
42902
43124
  /* @__PURE__ */ jsx78("h3", { className: "ab-subtitle", children: viewModel.sectionTitle }),
@@ -42907,6 +43129,28 @@ function HeadlessBookingPaymentSelectionStep({
42907
43129
  booking.payment.appointmentPackages.state.message,
42908
43130
  " You can continue with the normal payment option."
42909
43131
  ] }) : null,
43132
+ slidingScale ? /* @__PURE__ */ jsxs59("div", { className: "rb-space-y-2", children: [
43133
+ /* @__PURE__ */ jsx78("label", { htmlFor: "appointment-sliding-amount", className: "form-label", children: "Choose your price" }),
43134
+ /* @__PURE__ */ jsxs59("p", { className: "rb-caption status-muted", children: [
43135
+ formatBookingAmount(slidingScale.minAmount, slidingScale.currency),
43136
+ " to ",
43137
+ formatBookingAmount(slidingScale.maxAmount, slidingScale.currency),
43138
+ slidingScale.suggestedAmount !== null ? `, suggested ${formatBookingAmount(slidingScale.suggestedAmount, slidingScale.currency)}` : ""
43139
+ ] }),
43140
+ /* @__PURE__ */ jsx78(
43141
+ "input",
43142
+ {
43143
+ id: "appointment-sliding-amount",
43144
+ type: "number",
43145
+ className: "form-input",
43146
+ min: slidingScale.minAmount / 100,
43147
+ max: slidingScale.maxAmount / 100,
43148
+ step: "0.01",
43149
+ value: booking.payment.selectedSlidingAmountInput,
43150
+ onChange: (event) => booking.actions.setSlidingAmountInput(event.target.value)
43151
+ }
43152
+ )
43153
+ ] }) : null,
42910
43154
  /* @__PURE__ */ jsxs59("div", { className: "ab-stack", role: "list", "aria-label": "Payment options", children: [
42911
43155
  packageOptions.map((appointmentPackage) => {
42912
43156
  const isSelected = booking.payment.selectedAppointmentPackageId === appointmentPackage.customerPassId;
@@ -44753,6 +44997,7 @@ function useEligibility(params) {
44753
44997
  occurrenceId: params.occurrenceId,
44754
44998
  attendanceMode: params.attendanceMode ?? void 0,
44755
44999
  ticketTypeId: params.ticketTypeId ?? void 0,
45000
+ selectedSlidingAmount: params.selectedSlidingAmount ?? void 0,
44756
45001
  email: params.email.trim().toLowerCase(),
44757
45002
  ticketsCount: params.ticketsCount
44758
45003
  });
@@ -44773,7 +45018,7 @@ function useEligibility(params) {
44773
45018
  return () => {
44774
45019
  cancelled = true;
44775
45020
  };
44776
- }, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.email, params.ticketsCount]);
45021
+ }, [api, params.enabled, params.occurrenceId, params.attendanceMode, params.ticketTypeId, params.selectedSlidingAmount, params.email, params.ticketsCount]);
44777
45022
  return {
44778
45023
  state,
44779
45024
  eligibility: state.eligibility,
@@ -45124,6 +45369,41 @@ function TicketCounterLimit(props2) {
45124
45369
  ] }) : null
45125
45370
  ] });
45126
45371
  }
45372
+ function formatCurrencyInputAmount(amount) {
45373
+ const major = amount / 100;
45374
+ return Number.isInteger(major) ? String(major) : major.toFixed(2);
45375
+ }
45376
+ function SlidingScaleAmountField(props2) {
45377
+ const minLabel = formatPrice(props2.slidingScale.minAmount, props2.currency);
45378
+ const maxLabel = formatPrice(props2.slidingScale.maxAmount, props2.currency);
45379
+ const suggestedLabel = props2.slidingScale.suggestedAmount !== null ? formatPrice(props2.slidingScale.suggestedAmount, props2.currency) : null;
45380
+ return /* @__PURE__ */ jsxs66("div", { className: "er-field", children: [
45381
+ /* @__PURE__ */ jsx93("label", { htmlFor: "er-sliding-amount", className: "er-label", children: "Amount" }),
45382
+ /* @__PURE__ */ jsx93(
45383
+ "input",
45384
+ {
45385
+ id: "er-sliding-amount",
45386
+ type: "number",
45387
+ min: formatCurrencyInputAmount(props2.slidingScale.minAmount),
45388
+ max: formatCurrencyInputAmount(props2.slidingScale.maxAmount),
45389
+ step: "0.01",
45390
+ inputMode: "decimal",
45391
+ className: "er-input",
45392
+ value: props2.value,
45393
+ onChange: (event) => props2.onChange?.(event.target.value)
45394
+ }
45395
+ ),
45396
+ /* @__PURE__ */ jsxs66("p", { className: "er-text er-text--muted", children: [
45397
+ "Choose between ",
45398
+ minLabel,
45399
+ " and ",
45400
+ maxLabel,
45401
+ suggestedLabel ? `; suggested ${suggestedLabel}` : "",
45402
+ "."
45403
+ ] }),
45404
+ props2.message ? /* @__PURE__ */ jsx93("p", { className: "er-text er-text--muted", children: props2.message }) : null
45405
+ ] });
45406
+ }
45127
45407
  function getTicketTypeCounterAvailabilityLabel(input) {
45128
45408
  if (input.selectedRemainingCapacity !== null) {
45129
45409
  return `${input.selectedRemainingCapacity} remaining for this ticket type`;
@@ -45195,6 +45475,10 @@ var init_TicketSelectionStep = __esm({
45195
45475
  maxTickets,
45196
45476
  selectedTicketTypeId = null,
45197
45477
  onTicketTypeChange,
45478
+ slidingScale = null,
45479
+ selectedSlidingAmountInput = "",
45480
+ slidingScaleSelectionMessage = null,
45481
+ onSlidingAmountChange,
45198
45482
  onTicketsChange
45199
45483
  }) => {
45200
45484
  const deliveryMode = event?.deliveryMode ?? "in_person";
@@ -45310,6 +45594,16 @@ var init_TicketSelectionStep = __esm({
45310
45594
  ] })
45311
45595
  ] })
45312
45596
  ] }) : /* @__PURE__ */ jsxs66(Fragment18, { children: [
45597
+ slidingScale ? /* @__PURE__ */ jsx93(
45598
+ SlidingScaleAmountField,
45599
+ {
45600
+ slidingScale,
45601
+ currency: eventPricingCurrency ?? DEFAULT_EVENT_CURRENCY2,
45602
+ value: selectedSlidingAmountInput,
45603
+ message: slidingScaleSelectionMessage,
45604
+ onChange: onSlidingAmountChange
45605
+ }
45606
+ ) : null,
45313
45607
  /* @__PURE__ */ jsx93("h3", { className: "er-title", children: canJoinWaitlist ? "How many waitlist spots?" : "How many tickets?" }),
45314
45608
  /* @__PURE__ */ jsxs66("div", { className: "er-ticket-counter-group", children: [
45315
45609
  /* @__PURE__ */ jsx93(
@@ -46324,6 +46618,10 @@ function EventRegistrationWizardContent(props2) {
46324
46618
  maxTickets: wizard.maxTicketsNum,
46325
46619
  selectedTicketTypeId: wizard.selectedTicketTypeId,
46326
46620
  onTicketTypeChange: wizard.setSelectedTicketTypeId,
46621
+ slidingScale: wizard.selectedEventSlidingScale,
46622
+ selectedSlidingAmountInput: wizard.selectedSlidingAmountInput,
46623
+ slidingScaleSelectionMessage: wizard.slidingScaleSelectionMessage,
46624
+ onSlidingAmountChange: wizard.setSelectedSlidingAmountInput,
46327
46625
  onTicketsChange: wizard.setTicketsCount
46328
46626
  }
46329
46627
  )
@@ -46540,7 +46838,7 @@ function EventRegistrationSummaryBar(props2) {
46540
46838
  const summaryTimeZone = wizard.occurrenceContext?.timeZone ?? summaryEvent?.timeZone ?? null;
46541
46839
  const occurrenceOverrideTitle = wizard.occurrenceContext?.overrides?.title;
46542
46840
  const summaryTitle = occurrenceOverrideTitle ?? summaryEvent?.title ?? "";
46543
- const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
46841
+ const summaryPrice = wizard.selectedTicketType?.priceAmount ?? wizard.eligibility?.price ?? (wizard.selectedEventSlidingScale ? wizard.selectedSlidingAmount : null) ?? (summaryEvent ? publicEventScalarPrice(summaryEvent.pricing) : null) ?? 0;
46544
46842
  const summaryCurrency = (summaryEvent ? publicEventPricingCurrency(summaryEvent.pricing) : null) ?? DEFAULT_EVENT_CURRENCY2;
46545
46843
  const teamMemberNames = (summaryEvent?.teamMembers ?? []).map((teamMember) => teamMember.name).filter(Boolean);
46546
46844
  const subtotalCents = Math.max(0, summaryPrice * wizard.ticketsCount);
@@ -46991,6 +47289,7 @@ function useEventRegistrationSubmit(options) {
46991
47289
  occurrenceId: submitOccurrenceId,
46992
47290
  attendanceMode: options.selectedAttendanceMode ?? void 0,
46993
47291
  ticketTypeId: options.selectedTicketTypeId ?? void 0,
47292
+ selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
46994
47293
  email: options.formData.email.trim().toLowerCase(),
46995
47294
  name: options.formData.name.trim(),
46996
47295
  ticketsCount: options.ticketsCount,
@@ -47100,6 +47399,35 @@ var init_useEventRegistrationSubmit = __esm({
47100
47399
 
47101
47400
  // ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
47102
47401
  import { useCallback as useCallback8, useEffect as useEffect17, useMemo as useMemo12, useReducer as useReducer10, useState as useState9 } from "react";
47402
+ function parseCurrencyInputToCents(value) {
47403
+ const trimmed = value.trim();
47404
+ if (!trimmed) return null;
47405
+ const amount = Number(trimmed);
47406
+ if (!Number.isFinite(amount) || amount < 0) return null;
47407
+ return Math.round(amount * 100);
47408
+ }
47409
+ function formatCentsAsCurrencyInput(amount) {
47410
+ const major = amount / 100;
47411
+ return Number.isInteger(major) ? String(major) : major.toFixed(2);
47412
+ }
47413
+ function getSlidingScaleForEvent(event) {
47414
+ const pricing = event ? resolveRuntimeEventPricing(event) : null;
47415
+ return pricing?.kind === "sliding_scale" ? {
47416
+ minAmount: pricing.minAmount,
47417
+ maxAmount: pricing.maxAmount,
47418
+ suggestedAmount: pricing.suggestedAmount
47419
+ } : null;
47420
+ }
47421
+ function getSlidingScaleSelectionMessage(input) {
47422
+ if (!input.slidingScale) return null;
47423
+ if (input.selectedAmount === null) {
47424
+ return "Choose an amount to continue.";
47425
+ }
47426
+ if (input.selectedAmount < input.slidingScale.minAmount || input.selectedAmount > input.slidingScale.maxAmount) {
47427
+ return "Choose an amount within the sliding scale.";
47428
+ }
47429
+ return null;
47430
+ }
47103
47431
  function useEventRegistrationWizard(options) {
47104
47432
  const api = useBlockApi();
47105
47433
  const registrationEvents = useMemo12(
@@ -47144,6 +47472,10 @@ function useEventRegistrationWizard(options) {
47144
47472
  preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
47145
47473
  );
47146
47474
  const [selectedTicketTypeId, setSelectedTicketTypeId] = useState9(null);
47475
+ const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState9(() => {
47476
+ const slidingScale = getSlidingScaleForEvent(preSelectedEvent ?? null);
47477
+ return slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : "";
47478
+ });
47147
47479
  const [registrationResult, setRegistrationResult] = useState9(null);
47148
47480
  const [errorMessage, setErrorMessage] = useState9("");
47149
47481
  const [altchaSolution, setAltchaSolution] = useState9(null);
@@ -47180,6 +47512,7 @@ function useEventRegistrationWizard(options) {
47180
47512
  occurrenceId,
47181
47513
  attendanceMode: selectedAttendanceMode,
47182
47514
  ticketTypeId: selectedTicketTypeId,
47515
+ selectedSlidingAmount: parseCurrencyInputToCents(selectedSlidingAmountInput),
47183
47516
  email: formData.email,
47184
47517
  ticketsCount
47185
47518
  });
@@ -47315,6 +47648,18 @@ function useEventRegistrationWizard(options) {
47315
47648
  }),
47316
47649
  [selectedAttendanceMode, selectedEvent, preSelectedEvent, eligibility, selectedTicketTypeId]
47317
47650
  );
47651
+ const selectedSlidingAmount = useMemo12(
47652
+ () => parseCurrencyInputToCents(selectedSlidingAmountInput),
47653
+ [selectedSlidingAmountInput]
47654
+ );
47655
+ const selectedEventSlidingScale = useMemo12(
47656
+ () => getSlidingScaleForEvent(selectedEvent ?? preSelectedEvent),
47657
+ [selectedEvent, preSelectedEvent]
47658
+ );
47659
+ const slidingScaleSelectionMessage = getSlidingScaleSelectionMessage({
47660
+ slidingScale: selectedEventSlidingScale,
47661
+ selectedAmount: selectedSlidingAmount
47662
+ });
47318
47663
  const ticketTypeSelectionRequired = useMemo12(() => {
47319
47664
  const event = selectedEvent ?? preSelectedEvent;
47320
47665
  if (!event || publicEventPricingMode(resolveRuntimeEventPricing(event)) !== "ticket_types") {
@@ -47383,12 +47728,24 @@ function useEventRegistrationWizard(options) {
47383
47728
  setGuestSectionShake(false);
47384
47729
  };
47385
47730
  const eventRequiresPayment = useMemo12(
47386
- () => resolveEventRequiresPayment({
47731
+ () => {
47732
+ if (selectedEventSlidingScale) {
47733
+ return (selectedSlidingAmount ?? 0) > 0;
47734
+ }
47735
+ return resolveEventRequiresPayment({
47736
+ eligibility,
47737
+ selectedTicketType,
47738
+ event: selectedEvent ?? preSelectedEvent
47739
+ });
47740
+ },
47741
+ [
47387
47742
  eligibility,
47388
47743
  selectedTicketType,
47389
- event: selectedEvent ?? preSelectedEvent
47390
- }),
47391
- [eligibility, selectedTicketType, selectedEvent, preSelectedEvent]
47744
+ selectedEvent,
47745
+ preSelectedEvent,
47746
+ selectedEventSlidingScale,
47747
+ selectedSlidingAmount
47748
+ ]
47392
47749
  );
47393
47750
  const handleDetailsComplete = async () => {
47394
47751
  if (ticketTypeSelectionRequired && !hasValidSelectedTicketType) {
@@ -47397,6 +47754,11 @@ function useEventRegistrationWizard(options) {
47397
47754
  setStep("error");
47398
47755
  return { ok: false, reason: "blocked", message };
47399
47756
  }
47757
+ if (slidingScaleSelectionMessage) {
47758
+ setErrorMessage(slidingScaleSelectionMessage);
47759
+ setStep("error");
47760
+ return { ok: false, reason: "blocked", message: slidingScaleSelectionMessage };
47761
+ }
47400
47762
  if (!validateForm()) {
47401
47763
  setGuestSectionShake(true);
47402
47764
  return {
@@ -47481,9 +47843,18 @@ function useEventRegistrationWizard(options) {
47481
47843
  const discountSubtotalCents = useMemo12(() => {
47482
47844
  if (discountContext?.type !== "event") return void 0;
47483
47845
  const event = selectedEvent ?? preSelectedEvent;
47484
- const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
47846
+ const eventPriceCents = selectedTicketType?.priceAmount ?? eligibility?.price ?? (selectedEventSlidingScale ? selectedSlidingAmount : null) ?? (event ? publicEventScalarPrice(resolveRuntimeEventPricing(event)) : null) ?? 0;
47485
47847
  return Math.max(0, eventPriceCents * ticketsCount);
47486
- }, [discountContext, selectedTicketType, eligibility, selectedEvent, preSelectedEvent, ticketsCount]);
47848
+ }, [
47849
+ discountContext,
47850
+ selectedTicketType,
47851
+ eligibility,
47852
+ selectedEvent,
47853
+ preSelectedEvent,
47854
+ selectedEventSlidingScale,
47855
+ selectedSlidingAmount,
47856
+ ticketsCount
47857
+ ]);
47487
47858
  const discountUi = useDiscountCodeUi({ api, discountContext, subtotalCents: discountSubtotalCents });
47488
47859
  const selectionMethod = paymentSelection.method;
47489
47860
  const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
@@ -47492,6 +47863,7 @@ function useEventRegistrationWizard(options) {
47492
47863
  registrationTarget,
47493
47864
  selectedAttendanceMode,
47494
47865
  selectedTicketTypeId,
47866
+ selectedSlidingAmount,
47495
47867
  ticketsCount,
47496
47868
  formData,
47497
47869
  altchaSolution,
@@ -47506,6 +47878,10 @@ function useEventRegistrationWizard(options) {
47506
47878
  });
47507
47879
  const handleEventSelect = (event) => {
47508
47880
  setSelectedEvent(event);
47881
+ const slidingScale = getSlidingScaleForEvent(event);
47882
+ setSelectedSlidingAmountInput(
47883
+ slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : ""
47884
+ );
47509
47885
  setSelectedAttendanceMode(
47510
47886
  (event.deliveryMode ?? "in_person") === "hybrid" ? null : (event.deliveryMode ?? "in_person") === "online" ? "online" : "in_person"
47511
47887
  );
@@ -47515,6 +47891,7 @@ function useEventRegistrationWizard(options) {
47515
47891
  const handleRetry = () => {
47516
47892
  dispatchFlow({ type: "reset", hasPreSelectedContext });
47517
47893
  setSelectedTicketTypeId(null);
47894
+ setSelectedSlidingAmountInput("");
47518
47895
  setSelectedAttendanceMode(
47519
47896
  preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
47520
47897
  );
@@ -47551,6 +47928,11 @@ function useEventRegistrationWizard(options) {
47551
47928
  setSelectedAttendanceMode,
47552
47929
  selectedTicketTypeId,
47553
47930
  setSelectedTicketTypeId,
47931
+ selectedSlidingAmountInput,
47932
+ setSelectedSlidingAmountInput,
47933
+ selectedSlidingAmount,
47934
+ selectedEventSlidingScale,
47935
+ slidingScaleSelectionMessage,
47554
47936
  selectedTicketType,
47555
47937
  visibleTicketTypes,
47556
47938
  ticketTypeSelectionRequired,
@@ -51869,6 +52251,44 @@ function CoursePricingSelector({
51869
52251
  )
51870
52252
  ] });
51871
52253
  }
52254
+ function CourseSlidingScaleInput({
52255
+ pricing,
52256
+ value,
52257
+ onChange
52258
+ }) {
52259
+ const slidingScale = pricing.slidingScale;
52260
+ if (!slidingScale) {
52261
+ return null;
52262
+ }
52263
+ const minLabel = formatCoursePriceAmount(slidingScale.minAmount, pricing.currency);
52264
+ const maxLabel = formatCoursePriceAmount(slidingScale.maxAmount, pricing.currency);
52265
+ const suggestedLabel = slidingScale.suggestedAmount !== null ? formatCoursePriceAmount(slidingScale.suggestedAmount, pricing.currency) : null;
52266
+ return /* @__PURE__ */ jsxs97("div", { className: "cr-form__field", children: [
52267
+ /* @__PURE__ */ jsx140("label", { htmlFor: "cr-sliding-amount", className: "cr-form__label", children: "Amount" }),
52268
+ /* @__PURE__ */ jsx140(
52269
+ "input",
52270
+ {
52271
+ id: "cr-sliding-amount",
52272
+ type: "number",
52273
+ min: slidingScale.minAmount / 100,
52274
+ max: slidingScale.maxAmount / 100,
52275
+ step: "0.01",
52276
+ inputMode: "decimal",
52277
+ className: "cr-form__input",
52278
+ value,
52279
+ onChange: (event) => onChange(event.target.value)
52280
+ }
52281
+ ),
52282
+ /* @__PURE__ */ jsxs97("p", { className: "cr-text cr-text--muted", children: [
52283
+ "Choose between ",
52284
+ minLabel,
52285
+ " and ",
52286
+ maxLabel,
52287
+ suggestedLabel ? `; suggested ${suggestedLabel}` : "",
52288
+ "."
52289
+ ] })
52290
+ ] });
52291
+ }
51872
52292
  function EnrollmentForm({ formData, errors, onChange, isEmailLocked, isLoading, onLogout }) {
51873
52293
  const nameErrorId = "cr-name-error";
51874
52294
  const emailErrorId = "cr-email-error";
@@ -51964,6 +52384,17 @@ var init_components2 = __esm({
51964
52384
 
51965
52385
  // ../blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.ts
51966
52386
  import { useEffect as useEffect27, useMemo as useMemo21, useState as useState20 } from "react";
52387
+ function parseCurrencyInputToCents2(value) {
52388
+ const trimmed = value.trim();
52389
+ if (!trimmed) return null;
52390
+ const amount = Number(trimmed);
52391
+ if (!Number.isFinite(amount) || amount < 0) return null;
52392
+ return Math.round(amount * 100);
52393
+ }
52394
+ function formatCentsAsCurrencyInput2(amount) {
52395
+ const major = amount / 100;
52396
+ return Number.isInteger(major) ? String(major) : major.toFixed(2);
52397
+ }
51967
52398
  function shouldFetchCourseEligibility(course, hasPaidSelection, portalAuthState, hasWaitlistClaimToken) {
51968
52399
  if (!course || portalAuthState === "checking") return false;
51969
52400
  if (hasWaitlistClaimToken) return false;
@@ -51981,12 +52412,27 @@ function getSessionIdFromUrl() {
51981
52412
  }
51982
52413
  function getMissingCoursePricingSelectionMessage(pricing) {
51983
52414
  if (pricing?.requiresSelection && !pricing.selectedOption) {
52415
+ if (pricing.slidingScale) {
52416
+ return "Choose an amount to continue.";
52417
+ }
51984
52418
  return "Choose a pricing option to continue.";
51985
52419
  }
52420
+ if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null && pricing.selectedSlidingAmount < pricing.slidingScale.minAmount) {
52421
+ return "Choose an amount within the sliding scale.";
52422
+ }
52423
+ if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null && pricing.selectedSlidingAmount > pricing.slidingScale.maxAmount) {
52424
+ return "Choose an amount within the sliding scale.";
52425
+ }
51986
52426
  return null;
51987
52427
  }
51988
52428
  function buildCoursePricingOptionPayload(pricing) {
51989
- return pricing?.selectedOption ? { pricingOptionId: pricing.selectedOption.id } : {};
52429
+ if (pricing?.selectedOption) {
52430
+ return { pricingOptionId: pricing.selectedOption.id };
52431
+ }
52432
+ if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null) {
52433
+ return { selectedSlidingAmount: pricing.selectedSlidingAmount };
52434
+ }
52435
+ return {};
51990
52436
  }
51991
52437
  function resolveHasCoursePayment(pricing) {
51992
52438
  if (!pricing) {
@@ -52027,6 +52473,7 @@ function useCourseRegistrationWizard(props2) {
52027
52473
  scopedCourses.length === 1 ? scopedCourses[0] ?? null : null
52028
52474
  );
52029
52475
  const [selectedPricingOptionId, setSelectedPricingOptionId] = useState20(null);
52476
+ const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState20("");
52030
52477
  const [formData, setFormData] = useState20({
52031
52478
  name: "",
52032
52479
  email: "",
@@ -52048,8 +52495,12 @@ function useCourseRegistrationWizard(props2) {
52048
52495
  const [bookingMode, setBookingMode] = useState20(null);
52049
52496
  const waitlistClaim = useWaitlistClaim();
52050
52497
  const selectedCoursePricing = useMemo21(
52051
- () => selectedCourse ? resolveCoursePricingState(selectedCourse, selectedPricingOptionId) : null,
52052
- [selectedCourse, selectedPricingOptionId]
52498
+ () => selectedCourse ? resolveCoursePricingState(
52499
+ selectedCourse,
52500
+ selectedPricingOptionId,
52501
+ parseCurrencyInputToCents2(selectedSlidingAmountInput)
52502
+ ) : null,
52503
+ [selectedCourse, selectedPricingOptionId, selectedSlidingAmountInput]
52053
52504
  );
52054
52505
  const missingPricingSelectionMessage = getMissingCoursePricingSelectionMessage(
52055
52506
  selectedCoursePricing
@@ -52122,9 +52573,13 @@ function useCourseRegistrationWizard(props2) {
52122
52573
  useEffect27(() => {
52123
52574
  if (!selectedCourse) {
52124
52575
  setSelectedPricingOptionId(null);
52576
+ setSelectedSlidingAmountInput("");
52125
52577
  return;
52126
52578
  }
52127
52579
  const defaultPricing = resolveCoursePricingState(selectedCourse, null);
52580
+ setSelectedSlidingAmountInput(
52581
+ defaultPricing.slidingScale?.suggestedAmount !== null && defaultPricing.slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput2(defaultPricing.slidingScale.suggestedAmount) : ""
52582
+ );
52128
52583
  setSelectedPricingOptionId((previous) => {
52129
52584
  if (previous && defaultPricing.selectableOptions.some((option) => option.id === previous)) {
52130
52585
  return previous;
@@ -52499,6 +52954,8 @@ function useCourseRegistrationWizard(props2) {
52499
52954
  selectedCourse,
52500
52955
  selectedPricingOptionId,
52501
52956
  setSelectedPricingOptionId,
52957
+ selectedSlidingAmountInput,
52958
+ setSelectedSlidingAmountInput,
52502
52959
  selectedCoursePricing,
52503
52960
  setSelectedCourse,
52504
52961
  formData,
@@ -52564,6 +53021,19 @@ var init_useCourseRegistrationWizard = __esm({
52564
53021
 
52565
53022
  // ../blocks/src/system/runtime/nodes/course-registration/CourseRegistrationWizard.tsx
52566
53023
  import { Fragment as Fragment31, jsx as jsx141, jsxs as jsxs98 } from "react/jsx-runtime";
53024
+ function getCourseSlidingScaleMessage(pricing) {
53025
+ if (!pricing.slidingScale) {
53026
+ return null;
53027
+ }
53028
+ const selectedAmount = pricing.selectedSlidingAmount;
53029
+ if (selectedAmount === null) {
53030
+ return "Choose an amount to continue.";
53031
+ }
53032
+ if (selectedAmount < pricing.slidingScale.minAmount || selectedAmount > pricing.slidingScale.maxAmount) {
53033
+ return "Choose an amount within the sliding scale.";
53034
+ }
53035
+ return null;
53036
+ }
52567
53037
  function CourseRegistrationWizard(props2) {
52568
53038
  const {
52569
53039
  showSessions = true,
@@ -52585,6 +53055,8 @@ function CourseRegistrationWizard(props2) {
52585
53055
  selectedCourse,
52586
53056
  selectedPricingOptionId,
52587
53057
  setSelectedPricingOptionId,
53058
+ selectedSlidingAmountInput,
53059
+ setSelectedSlidingAmountInput,
52588
53060
  selectedCoursePricing,
52589
53061
  formData,
52590
53062
  setFormData,
@@ -52659,7 +53131,8 @@ function CourseRegistrationWizard(props2) {
52659
53131
  const canShowDiscountUi = !discountsAvailableLoading && paymentChoice === "checkout" && discountsAvailable && manualCodeEntryAllowed;
52660
53132
  const courseSoldOut = waitlistClaim.claim === null && courseEligibility?.isFull === true && courseEligibility.canJoinWaitlist !== true;
52661
53133
  const detailsSubmitLabel = courseEligibility?.canJoinWaitlist ? "Join waitlist" : buttonText;
52662
- const pricingSelectionMissing = selectedCoursePricing?.requiresSelection === true && !selectedCoursePricing.selectedOption;
53134
+ const pricingSelectionMissing = selectedCoursePricing?.requiresSelection === true && !selectedCoursePricing.selectedOption && !selectedCoursePricing.slidingScale;
53135
+ const slidingScaleMessage = selectedCoursePricing ? getCourseSlidingScaleMessage(selectedCoursePricing) : null;
52663
53136
  const pricingUnavailable = selectedCoursePricing?.display.kind === "unavailable";
52664
53137
  const selectedCourseWithPricing = selectedCourse && selectedCoursePricing ? {
52665
53138
  course: selectedCourse,
@@ -52752,6 +53225,14 @@ function CourseRegistrationWizard(props2) {
52752
53225
  onSelect: setSelectedPricingOptionId
52753
53226
  }
52754
53227
  ),
53228
+ /* @__PURE__ */ jsx141(
53229
+ CourseSlidingScaleInput,
53230
+ {
53231
+ pricing: selectedCourseWithPricing.pricing,
53232
+ value: selectedSlidingAmountInput,
53233
+ onChange: setSelectedSlidingAmountInput
53234
+ }
53235
+ ),
52755
53236
  showSpamProtection && /* @__PURE__ */ jsx141("div", { className: "cr-altcha", children: /* @__PURE__ */ jsx141(
52756
53237
  AltchaWidget,
52757
53238
  {
@@ -52789,7 +53270,7 @@ function CourseRegistrationWizard(props2) {
52789
53270
  {
52790
53271
  type: "submit",
52791
53272
  className: buttonClass,
52792
- disabled: courseSoldOut || eligibilityLoading || pricingSelectionMissing || pricingUnavailable,
53273
+ disabled: courseSoldOut || eligibilityLoading || pricingSelectionMissing || slidingScaleMessage !== null || pricingUnavailable,
52793
53274
  children: eligibilityLoading ? "Checking availability\u2026" : courseSoldOut ? "Sold out" : detailsSubmitLabel
52794
53275
  }
52795
53276
  )
@@ -52799,6 +53280,7 @@ function CourseRegistrationWizard(props2) {
52799
53280
  ),
52800
53281
  courseSoldOut && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: "This course is fully booked and there is no waitlist available right now." }),
52801
53282
  pricingSelectionMissing && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: "Choose a pricing option to continue." }),
53283
+ slidingScaleMessage && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: slidingScaleMessage }),
52802
53284
  pricingUnavailable && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--muted", children: "Pricing is not available for this course right now." }),
52803
53285
  eligibilityError && /* @__PURE__ */ jsx141("p", { className: "cr-text cr-text--error", children: eligibilityError })
52804
53286
  ] })
@@ -61767,6 +62249,7 @@ import { z as z69 } from "zod";
61767
62249
  import * as React6 from "react";
61768
62250
 
61769
62251
  // ../blocks/src/system/manifest/fieldValidation/index.ts
62252
+ init_src2();
61770
62253
  import { z as z6 } from "zod";
61771
62254
 
61772
62255
  // ../blocks/src/system/types/link.ts
@@ -62495,7 +62978,10 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
62495
62978
  return makePlan("richText", "object", field, path, required, commonConstraints(required, { kind: "richTextDoc" }));
62496
62979
  case "media":
62497
62980
  case "file":
62498
- return makePlan("media", "object", field, path, required, commonConstraints(required, { kind: "mediaObject" }));
62981
+ return {
62982
+ ...makePlan("media", "object", field, path, required, commonConstraints(required, { kind: "mediaObject" })),
62983
+ legacyStringType: legacyStringMediaTypeForField(field)
62984
+ };
62499
62985
  case "link":
62500
62986
  return makePlan("link", "object", field, path, required, commonConstraints(required, { kind: "linkObject" }));
62501
62987
  case "boolean":
@@ -62680,15 +63166,23 @@ function normalizeFieldValue(plan, value, ctx) {
62680
63166
  return normalizeRepeaterItems(plan, value, ctx);
62681
63167
  case "boolean":
62682
63168
  case "richText":
62683
- case "media":
62684
63169
  case "link":
62685
63170
  case "select":
62686
63171
  case "passthrough":
62687
63172
  return value;
63173
+ case "media":
63174
+ return normalizeMediaInput(plan, value);
62688
63175
  default:
62689
63176
  return assertNever4(plan);
62690
63177
  }
62691
63178
  }
63179
+ function normalizeMediaInput(plan, value) {
63180
+ return normalizeLegacyStringMediaValueForField(value, {
63181
+ type: plan.fieldType,
63182
+ mediaKinds: plan.fieldType === "media" ? [plan.legacyStringType] : void 0,
63183
+ fileKinds: plan.fieldType === "file" ? [plan.legacyStringType] : void 0
63184
+ });
63185
+ }
62692
63186
  function normalizeObjectChildren(children, value, ctx) {
62693
63187
  if (!value || typeof value !== "object" || Array.isArray(value)) return value;
62694
63188
  const normalized = {
@@ -62952,6 +63446,21 @@ function fieldPlanToZod(plan, options = {}) {
62952
63446
  }
62953
63447
  });
62954
63448
  }
63449
+ function fieldPresenceForPlan(plan) {
63450
+ return plan.required ? { kind: "required" } : { kind: "optional" };
63451
+ }
63452
+ function fieldPlanToObjectPropertyZod(plan, options = {}) {
63453
+ const schema = fieldPlanToZod(plan, options);
63454
+ const presence = fieldPresenceForPlan(plan);
63455
+ switch (presence.kind) {
63456
+ case "required":
63457
+ return schema;
63458
+ case "optional":
63459
+ return schema.optional();
63460
+ default:
63461
+ return assertNever4(presence);
63462
+ }
63463
+ }
62955
63464
  function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
62956
63465
  const message = fieldIssueToMessage(validationIssue);
62957
63466
  const path = relativeZodIssuePath(validationIssue.path, rootPath);
@@ -63164,7 +63673,7 @@ function createManifestValidator(manifestOrFields, options = {}) {
63164
63673
  function deriveContentZodFromPlans(plans, options) {
63165
63674
  const shape = {};
63166
63675
  for (const plan of plans) {
63167
- shape[plan.fieldId] = fieldPlanToZod(plan, options);
63676
+ shape[plan.fieldId] = fieldPlanToObjectPropertyZod(plan, options);
63168
63677
  }
63169
63678
  return z7.object(shape).catchall(z7.unknown()).passthrough();
63170
63679
  }
@@ -96644,12 +97153,85 @@ function resolveApiBaseUrl() {
96644
97153
  }
96645
97154
 
96646
97155
  // ../api/src/common/envelope.ts
97156
+ var API_ERROR_CODES = [
97157
+ "auth:unauthenticated",
97158
+ "auth:token_expired",
97159
+ "auth:token_invalid",
97160
+ "auth:forbidden",
97161
+ "auth:mfa_required",
97162
+ "auth:sudo_required",
97163
+ "auth:insufficient_permissions",
97164
+ "auth:impersonation_restricted",
97165
+ "validation:invalid_input",
97166
+ "validation:missing_field",
97167
+ "validation:invalid_format",
97168
+ "validation:payload_too_large",
97169
+ "resource:not_found",
97170
+ "resource:already_exists",
97171
+ "resource:conflict",
97172
+ "resource:gone",
97173
+ "rate_limit:exceeded",
97174
+ "billing:payment_required",
97175
+ "billing:plan_limit_exceeded",
97176
+ "billing:pass_redemption_failed",
97177
+ "server:internal_error",
97178
+ "server:unavailable",
97179
+ "external:service_error",
97180
+ "external:registrar_orphaned_contact_profile",
97181
+ "network:connection_error",
97182
+ "network:timeout",
97183
+ "network:dns_error"
97184
+ ];
97185
+ var API_ERROR_CODE_SET = new Set(API_ERROR_CODES);
97186
+ function isApiErrorCode(value) {
97187
+ return typeof value === "string" && API_ERROR_CODE_SET.has(value);
97188
+ }
96647
97189
  function isApiError(result) {
96648
97190
  return result.success === false;
96649
97191
  }
96650
97192
  function isApiSuccess(result) {
96651
97193
  return result.success === true;
96652
97194
  }
97195
+ function isRecord13(value) {
97196
+ return typeof value === "object" && value !== null && !Array.isArray(value);
97197
+ }
97198
+ function isFieldError(value) {
97199
+ return isRecord13(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
97200
+ }
97201
+ function fieldErrorsFromUnknown(value) {
97202
+ if (!Array.isArray(value)) return null;
97203
+ return value.every(isFieldError) ? value : null;
97204
+ }
97205
+ function extractEnvelopeErrorObject(body) {
97206
+ if (!isRecord13(body)) return null;
97207
+ const error = body.error;
97208
+ if (!isRecord13(error)) return null;
97209
+ if ("success" in body && body.success !== false) {
97210
+ return null;
97211
+ }
97212
+ return error;
97213
+ }
97214
+ function extractApiEnvelopeErrorDetails(body) {
97215
+ const error = extractEnvelopeErrorObject(body);
97216
+ if (!error) {
97217
+ return {
97218
+ rawCode: null,
97219
+ code: null,
97220
+ message: null,
97221
+ status: null,
97222
+ fieldErrors: null
97223
+ };
97224
+ }
97225
+ const rawCode = typeof error.code === "string" ? error.code : null;
97226
+ const message = typeof error.message === "string" && error.message.trim().length > 0 ? error.message : null;
97227
+ return {
97228
+ rawCode,
97229
+ code: isApiErrorCode(rawCode) ? rawCode : null,
97230
+ message,
97231
+ status: typeof error.status === "number" && Number.isFinite(error.status) ? error.status : null,
97232
+ fieldErrors: fieldErrorsFromUnknown(error.fieldErrors)
97233
+ };
97234
+ }
96653
97235
  var ApiEnvelopeError = class extends Error {
96654
97236
  constructor(error) {
96655
97237
  super(error.message);
@@ -97046,6 +97628,7 @@ function createParsedClient(rawClient) {
97046
97628
  const auth = config.auth ?? "user";
97047
97629
  if (!response.ok) {
97048
97630
  const body = await parseErrorBody(response);
97631
+ const envelopeError = extractApiEnvelopeErrorDetails(body);
97049
97632
  const requestId = response.headers.get("x-request-id") ?? void 0;
97050
97633
  const retryAfterMs = parseRetryAfterHeader(response.headers.get("retry-after"));
97051
97634
  throw new ApiRequestError(
@@ -97057,6 +97640,7 @@ function createParsedClient(rawClient) {
97057
97640
  auth,
97058
97641
  requestId,
97059
97642
  body,
97643
+ errorCode: envelopeError.code ?? void 0,
97060
97644
  retryAfterMs
97061
97645
  }
97062
97646
  );
@@ -97086,6 +97670,7 @@ var CANONICAL_REFUND_CONFLICT_CODES = [
97086
97670
  ];
97087
97671
  var CANONICAL_REFUND_PLANNER_ERROR_CODES = [
97088
97672
  ...CANONICAL_REFUND_CONFLICT_CODES,
97673
+ "invalid_amount",
97089
97674
  "amount_exceeds_remaining",
97090
97675
  "pass_revoke_requires_full_refund",
97091
97676
  "refund_failed"
@@ -97112,6 +97697,7 @@ var CUSTOMER_MEMBERSHIP_PAYMENT_REFUND_FAILED_CODES = [
97112
97697
  // ../api/src/bookingRefundOutcomes.ts
97113
97698
  var STANDARD_LINE_ITEM_REFUND_INVALID_CODES = [
97114
97699
  "missing_amount",
97700
+ "invalid_amount",
97115
97701
  "amount_exceeds_remaining",
97116
97702
  "credit_refunds_disabled",
97117
97703
  "missing_credit_customer",
@@ -97126,6 +97712,7 @@ var EVENT_ATTENDEE_REFUND_INVALID_CODES = [
97126
97712
  var MANAGED_PRODUCT_REFUND_INVALID_CODES = [
97127
97713
  "credit_refunds_disabled",
97128
97714
  "not_refundable",
97715
+ "invalid_amount",
97129
97716
  "amount_exceeds_remaining"
97130
97717
  ];
97131
97718
  var CUSTOMER_PASS_REFUND_INVALID_CODES = [
@@ -97370,7 +97957,7 @@ function preset(id, verticalId, canonicalBehaviour, label, pluralLabel, descript
97370
97957
  }
97371
97958
 
97372
97959
  // ../api/src/utils/isRecord.ts
97373
- function isRecord13(value) {
97960
+ function isRecord14(value) {
97374
97961
  return typeof value === "object" && value !== null && !Array.isArray(value);
97375
97962
  }
97376
97963
 
@@ -97677,7 +98264,7 @@ function sanitizeMarks(marks) {
97677
98264
  if (mark.type === "bold" || mark.type === "strong" || mark.type === "italic" || mark.type === "em") {
97678
98265
  return [{ type: mark.type }];
97679
98266
  }
97680
- if (mark.type === "link" && isRecord13(mark.attrs) && typeof mark.attrs.href === "string") {
98267
+ if (mark.type === "link" && isRecord14(mark.attrs) && typeof mark.attrs.href === "string") {
97681
98268
  const attrs = { href: mark.attrs.href };
97682
98269
  if (typeof mark.attrs.target === "string" && mark.attrs.target.trim().length > 0) {
97683
98270
  attrs.target = mark.attrs.target;
@@ -97692,10 +98279,10 @@ function sanitizeMarks(marks) {
97692
98279
  return sanitized.length > 0 ? sanitized : void 0;
97693
98280
  }
97694
98281
  function unwrapRichTextValue(value) {
97695
- if (isRecord13(value) && isRecord13(value.doc)) {
98282
+ if (isRecord14(value) && isRecord14(value.doc)) {
97696
98283
  return unwrapRichTextValue(value.doc);
97697
98284
  }
97698
- if (isRecord13(value) && value.type === "doc") {
98285
+ if (isRecord14(value) && value.type === "doc") {
97699
98286
  return {
97700
98287
  type: "doc",
97701
98288
  content: Array.isArray(value.content) ? value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) : []
@@ -97704,7 +98291,7 @@ function unwrapRichTextValue(value) {
97704
98291
  return EMPTY_SITE_BANNER_BODY;
97705
98292
  }
97706
98293
  function isTipTapNodeLike(value) {
97707
- return isRecord13(value) && typeof value.type === "string";
98294
+ return isRecord14(value) && typeof value.type === "string";
97708
98295
  }
97709
98296
  function coerceTipTapNode(value) {
97710
98297
  return {
@@ -97712,9 +98299,9 @@ function coerceTipTapNode(value) {
97712
98299
  ...Array.isArray(value.content) ? { content: value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) } : {},
97713
98300
  ...typeof value.text === "string" ? { text: value.text } : {},
97714
98301
  ...Array.isArray(value.marks) ? {
97715
- marks: value.marks.filter((mark) => isRecord13(mark) && typeof mark.type === "string").map((mark) => ({
98302
+ marks: value.marks.filter((mark) => isRecord14(mark) && typeof mark.type === "string").map((mark) => ({
97716
98303
  type: mark.type,
97717
- ...isRecord13(mark.attrs) ? { attrs: mark.attrs } : {}
98304
+ ...isRecord14(mark.attrs) ? { attrs: mark.attrs } : {}
97718
98305
  }))
97719
98306
  } : {}
97720
98307
  };
@@ -97904,7 +98491,7 @@ var ENTRY_REF_KEYS = [
97904
98491
  "entryId",
97905
98492
  "slug"
97906
98493
  ];
97907
- function isRecord14(value) {
98494
+ function isRecord15(value) {
97908
98495
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
97909
98496
  }
97910
98497
  function extractManualEntryRef(item) {
@@ -97912,7 +98499,7 @@ function extractManualEntryRef(item) {
97912
98499
  const trimmed = item.trim();
97913
98500
  return trimmed.length > 0 ? trimmed : null;
97914
98501
  }
97915
- if (!isRecord14(item)) return null;
98502
+ if (!isRecord15(item)) return null;
97916
98503
  for (const key of ENTRY_REF_KEYS) {
97917
98504
  const raw = item[key];
97918
98505
  if (typeof raw === "string" && raw.trim().length > 0) {
@@ -99098,7 +99685,7 @@ var SimpleCache = class {
99098
99685
  };
99099
99686
 
99100
99687
  // src/version.ts
99101
- var SDK_VERSION = "0.91.0";
99688
+ var SDK_VERSION = "0.93.0";
99102
99689
 
99103
99690
  // src/client/error.ts
99104
99691
  var RiverbankApiError = class _RiverbankApiError extends Error {