riverbankcms 0.24.0 → 0.25.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.
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { $ as createFormRef, $n as parseSafeDownloadFilename, $r as surfaceForegroundValue, An as mediaSchema, Ar as resolveSurface, At as generateMobileOverlayBackdropFilterFix, Br as mapDrawingStyle, Bt as getComponentShadowVar, C as sortRecord, Cn as isExplicitRectCrop, Cr as offeringsPreviewCompositionTreatmentValues, Ct as requireCuratedSiteStyle, D as mapEventCommandContent, Dn as getDirectImageUrlForSiteScopedPath, Dr as visibleHeadingDecorationFamilyValues, Dt as parseGradientPresetId, En as getDirectImageUrlForRelativePath, Er as toNonEmptyReadonlyArray, Et as getGradientPreset, F as pageIdentifierForBlockCommand, Fn as mediaTypeDiscriminants, Fr as backgroundColorStyle, Ft as BREAKPOINT_SM, G as ianaTimezoneSchema, Gn as getMimeType, Gr as resolveTokenOrCssColorValue, Gt as themeButtonSizeClassName, H as bookingPaymentTermsSchema, Hn as deriveVideoSlotPolicy, Hr as isCssColorLiteral, Ht as generateDefaultButtonSystem, I as pageIdentifierForCommand, In as mediaIdentifierSchema, Ir as borderColorStyle, It as BREAKPOINT_XL, J as createCommandRef, Jn as parseRelativeStoragePath, Jr as surfaceToneFromForegroundToken, K as createBlockRef, Kn as asRecord, Kr as PUBLIC_BUTTON_ROLES, Kt as themeButtonVariantClassNames, L as pagePathForCommand, Ln as buildMediaIdentifierFromFilename, Lr as mergeStyles, Lt as MQ_MD_DOWN, M as blockIdentifierForCommand, Mn as runtimeMediaSchema, Mr as surfaceDecorationColors, Mt as renderHeaderPaintTargetRules, N as blockOrderIdentifiersForCommand, Nn as buildRenderableMediaAssetIndex, Nr as resolveSurfaceForeground, Nt as BREAKPOINT_LG, On as getImageUrl, Or as parseResolvedSurface, Ot as themeSchema, P as entryIdentifierForCommand, Pn as resolveManagedMediaReference, Pr as TokenResolver, Pt as BREAKPOINT_MD, Q as createFooterRef, Qn as managementMediaLibraryUploadLimitForMimeType, Qr as surfaceForegroundStyle, R as hasConfiguredBookingVertical, Rn as parseCanonicalMediaIdentifier, Rr as rgbColorValue, Rt as headerVariantValues, S as venueManagementFields, Sn as normalizeWidthCandidates, Sr as makeBoundaryId, St as deriveSiteStyleBlockPolicy, Tn as resolveMediaTransformForAspect, Tr as tileTreatmentValues, Tt as gradientToCss, U as require_jsx_runtime, Un as resolveVideoSelectionIntentForMediaField, Ur as resolveOnColorForThemeToken, Ut as parseThemeButtonVariantId, V as bookingPaymentCollectionOptionSchema, Vr as opaqueSurfaceDeclarations, Vt as ICON_CONFIG, W as require_react, Wr as resolveThemeColorReferenceValue, Wt as themeButtonExtraClassesWithTrailingIcon, X as createEventCategoryRef, Xr as surfaceForegroundDeclarations, Xt as buildTextContrastShadow, Y as createContentEntryRef, Yn as FILE_SIZE_LIMITS, Yr as defaultThemeTokens, Yt as footerForegroundCandidates, Z as createEventSeriesRef, Zn as classifyKnownMimeType, Zr as surfaceForegroundInputFromResolved, Zt as generateNavLinkCSS, _n as summarizePortableMediaReferences, _r as eventListTreatmentValues, _t as arrangementManifestFromVariants, ai as __toESM, an as deriveSectionGround, ar as resolveEffectiveKnobs, b as isEventVisibility, bn as looksLikeUuid, br as headingDecorationColorTokenValues, bt as resolveModeArrangement, c as customLinkSchema$1, cn as resolveSectionBackground, ct as headerLeafTextColor, d as internalLinkSchema, dn as boxBackgroundOverlaySchema, dt as mergeHeaderNavTypographyPreference, ei as expandPalette, er as renderCssDeclarations, et as createNavigationRef, f as internalResolvedLinkSchema, fn as boxBackgroundSchema, fr as asSiteStyleId, ft as readHeaderNavFontSizePreference, g as linkSchema, gn as collectPortableMediaReferencesFromContent, gr as defineNoBlockDesignCapability, gt as resolveLookSlotSurfaces, h as isResolvedInternalLinkEntityType, hn as stripStaleTransitionStyleGroup, hr as defineFrameCapability, ht as resolveItemSurface, ii as __commonJSMin, in as sectionFactsForContent, ir as defineBlockDesignMetadata, it as refSlug, j as eventManagementTiming, jn as persistableMediaSchema, jr as serializeSurfaceTree, jt as getHeaderPaintTargets, kn as isSiteScopedDirectImageStoragePath, kr as parseSurfaceTree, kt as generateHeaderScrollTreatmentStyles, l as entryLinkSchema$1, ln as resolveSectionPhotoPlacement, lr as asDesignBlockId, lt as transparentHeaderForegroundInput, mn as siteChromeBackgroundOverrideOwner, mr as defineBlockDesignCapability, mt as arrangementSlotNames, ni as parseThemeColorToken, nn as boundaryLayout, nr as cardVariantRoleValues, o as classifySdkEventBookingOffer, on as heroPhotoPaintsGround, or as cardListFamilyBlocks, ot as effectiveHeaderNavLinkStyle, p as internalRouteOnlyLinkSchema, pn as runtimeBoxBackgroundSchema, pr as assertNever$11, pt as arrangementLookHooks, q as createBlocksRef, qr as selectLogoVariant, qt as parseThemeForPersistence, ri as parseBlockColorToken, rn as composeBoundary, rr as normalizeCardRole, rt as createVenueRef, s as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, sn as parseCanonicalRuntimeBackground, sr as cardListKnobBlocks, st as headerForegroundCandidates, t as classifySdkEventTiming, ti as getTextColorForBackground, tn as headerRootPaint, tr as cardRoleSchema, tt as createPageRef, u as externalLinkSchema$1, un as sectionForegroundBackground, ur as asLayoutVariantKey, ut as readOpeningForegroundProjection, v as pageLinkSchema$1, vn as walkAndCollectImageAttrs, vr as eyebrowTreatmentValues, vt as readStoredMode, w as stableStringify, wn as parseAspectRatioValue, wr as testimonialsCompositionTreatmentValues, wt as compiledRuntimeStyleFieldNames, xn as rotateNormalizedPoint, xr as introCompositionTreatmentValues, xt as resolvePublishedLook, yn as deleteEnvSpecificKeys, yr as featureCardCompositionTreatmentValues, yt as resolveEffectiveArrangement, z as eventCommandScheduleSchema, zn as parseMediaIdentifier, zr as textColorStyle, zt as getComponentBorderWidthPx } from "../sdk-event-upsert-DmNSeHgP.mjs";
3
- import { $ as selectCategoryView, $t as parseNonNegativeCents, A as DEFAULT_MAILING_LIST_SUCCESS_MESSAGE, At as clampConfiguredAmount, B as parseWeeklyOpeningHours, Bt as formatBookingPriceDisplay, C as parseManagementKey, Ct as toUtcIsoDateTimeString, D as parseMailingListSignedSourceToken, Dt as isSettleableFlexibleBalanceContractStatus, E as parseMailingListContentVersionId, En as unsafeAsDemoCapability, Et as isLiveOrderInstalmentPlanStatus, F as DEFAULT_MAILING_LIST_TARGETING, Ft as splitAmountWithRemainderInFirst, G as locationValueSchema, Gt as publicEventPricingOptions, H as decideLocationSave, Ht as isPublicEventPricingOptionDisplayable, I as planMailingListChoicePresentation, In as unsafeAsPassId, It as resolveFlexibleBalanceDueAt, J as projectPublicLocation, Jt as resolvePricingOptionsPriceDisplay, K as normalizeLocationAddressText, Kt as publicEventPricingType, L as isCanonicalRichTextDoc, Ln as unsafeAsPositiveByteCount, Lt as resolveFlexibleBalanceInitialPaymentCents, M as parseFooterCompositionV1, Mt as getBookingInstalmentPlanIntervalCount, Nn as unsafeAsMediaAssetId, Nt as getBookingInstalmentProtectedDepositAmountCents, O as parseMailingListRuntimeContext, Ot as isSettleableOrderInstalmentPlanStatus, P as parseMailingListPlacementTargeting, Pn as unsafeAsOccurrenceId, Pt as omitZeroAmountFutureRows, Q as mapDrawingSchema, Qt as isNonNegativeWholeCents$1, R as formatOpeningHoursRows, Rt as deriveTotalTicketQuantity, S as exposeSecret, St as toScheduledBookingDateTime, T as parseMailingListBlockId, Tt as validateBookingPaymentOptionKinds, Ut as publicEventPricingCurrency, V as assertAllowedPublicUrl, Vt as formatEventPricing, W as locationMapLinks, Wt as publicEventPricingDisplay, X as toLocationCoordinates, Xn as err, Y as publicLocationSchema$1, Yt as fromArray, Zn as ok, Zt as mapReadonlyNonEmptyArray, _ as nextLiveRunSessionStartMs, _n as parseRetiredCourseId, _t as parseLocalScheduleTime, an as formatCurrencyAmount, at as formatTimeRange, b as resolveWholeSeriesRunLifecycle, bn as parseUserId, bt as resolveBookingTimeZoneId, cn as formatDurationUnitLabel, ct as buildBookingUtcDateWindow, d as EVENT_PRESET_VALUES, dn as parseDatedOfferingCapacityHoldAuditRef, dt as formatLocalScheduleTime, en as parsePositiveCents, et as formatDate, fn as parseDatedOfferingCapacityHoldId, ft as getBookingLocalDateKey, g as CANCELLED_SESSION_STATUS, gt as parseBookingLocalDate, hn as parseMembershipId, i as NAVIGATION_LOCATIONS, in as unsafeAsPositiveCents, it as formatTime$1, j as parseMailingListProviderScope, jt as getBookingInstalmentDepositRefundability, k as assessMailingListTargeting, kn as unsafeAsEventInstanceId, kt as addIntervalPreservingMonthAnchor, l as resolveSiteVerticalBookingConfig, ln as parseApiKeyId, lt as compareLocalScheduleDates, m as WHOLE_SERIES_EVENT_PRESET_VALUES, mt as getLocalScheduleTime, nn as toNonNegativeCents, nt as formatDateTime, on as parseCurrencyCode, ot as inferSiteDateLocale, p as SURFACE_EVENT_PRESET_VALUES, pn as parseEventSeriesId, pt as getLocalScheduleDate, q as parseLocationValue, qt as resolveExactOrFreePriceDisplay, r as EVENT_PRESET_VOCABULARY, rn as unsafeAsNonNegativeCents, rt as formatDateTimeRange, sn as assertNever, st as resolveBookingDisplayContext, tn as toCents, tt as formatDateRange, un as parseCustomerId, ut as formatLocalScheduleDate, v as orderedLiveRunSessions, vn as parseSiteId, vt as parseUtcIsoDateTimeString, w as slugify, wn as unsafeAsCheckoutLineId, x as createSecret, xt as toBookingTimeZone, y as resolveWholeSeriesBookingPhase, yn as parseSiteTermsVersionId, yt as resolveBookingBusinessTimeZone, zn as unsafeAsPricingOptionId, zt as parseEventPageSurfaceSubject } from "../src-B03aw4Tv.mjs";
4
- import { $ as normalizeMediaValueToIdentifierOnly, $t as bindRequestTimeout, A as formatDiffDetail, An as transportSuggestion, At as navigationIdentity, B as buildFieldChanges, Bn as sdkEventScheduleSchema, Bt as preparePushConfigTarget, C as reportFromOutcomes, Cn as parseEnvironmentSelection, Ct as fileExists, D as normalizeRemoteHomepageReference, Dn as withRiverbankEnv, Dt as writeJsonFileAtomic, E as createEmptySyncResult, En as requireEnvironmentWriteAuthorization, Et as writeJsonFile, F as calculatePullDiff, Fn as isLocalConfigured, Ft as navigationCommandItemToManagementInput, G as syncLocalMediaForPull, Gt as APPOINTMENT_SERVICE_VISIBILITY_VALUES, H as formatFieldPath, Hn as linkPayloadSchema, Ht as extractApiErrorMessage, I as buildJsonDiff, In as isRemoteConfigured, It as normalizeNavigationConfigItemForCommand, J as admitBinaryWriteDestination, Jt as ApiEnvelopeError, K as applyLocalMediaPush, Kt as ApiRequestError, L as hasPageOperations, Ln as loadSdkEnvironment, Lt as applyPushConfigPlan, M as hasPendingChanges, Mt as convertPulledFooterToLocal, N as findChangedFieldsWithValues, Nn as getEnvPrefix, Nt as convertPulledNavigationToLocal, O as calculateDiff, On as ErrorCodes, Ot as isMediaValue, P as formatHumanDiff, Pn as getEnvironmentDebugInfo, Pt as convertPulledPagesToLocal, Q as normalizeMediaIdentifierInput, Qt as mapEnvironmentExecutionOutcomesJson, R as pageMetadataForUpsert, Rn as createManagementClient, Rt as createPushConfigCommand, S as planCliCommandBatchForBindings, Sn as executeEnvironmentPlan, St as ensureDir, T as executeResidualSettingsSyncPlan, Tn as planEnvironmentWriteAuthorization, Tt as readJsonFile, U as revalidateLocalMediaPushPlan, Un as portablePageDesignSchema, Ut as normalizeApiError, V as formatFieldChange, Vn as sdkSettingsUpdateSchema, Vt as revalidatePushConfigPlan, Wn as sdkConfiguredBookingVerticalConfigSchema, Wt as isRecord$2, X as writeBinaryFileAtomic, Xt as deriveCmsApiUrlFromDashboardUrl, Y as readStableBinaryFile, Yt as unwrapResponse, Z as sha256, Zt as API_ENDPOINTS, _ as commandExecutionToReport, _n as runWithInvocation, _t as metadataFilePath, a as executeEntryCommandPlanAsReport, an as createOutputForCommand, at as readEntries, b as executeCompiledCliCommandPlanAsReport, bn as withErrorHandling, bt as writeMetadataFile, c as titleFromEntryData, cn as getOutputContext, ct as readEventsMeta, d as unsafeAsCliEntryIdentifier, dn as managementClientConfigFor, dt as readNavigationMeta, en as confirmAction, et as walkLocalContentMedia, f as unsafeAsCliFormSlug, fn as mapEntryForOutput, ft as readPagesMeta, g as commandCompileFailureToReport, gn as resolveCommandPath, gt as ensureMetadataDir, h as mutationCounterForEffect, hn as parsePaginationOptions, ht as writeMediaManifest, i as entrySiteCommandTypes, in as createListCommand, it as findLegacyEntryFiles, j as formatDiffSummary, jn as CliExit, jt as navigationIdentityMap, k as calculateFooterDiff, kn as formatError, kt as duplicateNavigationIdentityMessage, l as unsafeAsCliBlockIdentifier, ln as getOutputOnlyContext, lt as readFooterMeta, m as commandReportToSyncResult, mn as parseJsonData, mt as readVenuesMeta, n as entryCommandCompileErrorToReport, nn as createCommandContext, nt as downloadMedia, o as executeEntryCommandPlanAsSyncResult, on as currentInvocationEnvelope, ot as readAllMeta, p as unsafeAsCliPageIdentifier, pn as parseJsonArray, pt as readSettingsMeta, q as prepareLocalMediaForPush, qt as createBearerAPIClient, r as entryCommandReportToSyncResult, rn as createGetCommand, rt as extractMediaIdentifiers, s as syncResultForEntryCommandCompileError, sn as formatDateShort, st as readEventCategoriesMeta, t as compileEntryPushCommands, tn as createClientForEnv, tt as buildStorageUrl, u as unsafeAsCliContentTypeKey, un as handleCommandError, ut as readFormsMeta, v as commandReportHasFailures, vn as withCommandContext, vt as metadataTargetFromEnvironment, w as mergeManySyncResults, wn as planEnvironmentExecution, wt as listFiles, x as formatManagementError, xn as withOutputOnlyErrorHandling, xt as writeMetadataRecordMap, y as executeCliCommandPlan, yn as withConfirmation, yt as readMetadataFile, zn as ManagementApiError, zt as loadPushConfigTarget } from "../entryCommands-C0xbLW5L.mjs";
5
- import { r as CLI_VERSION, t as loadConfigFile } from "../load-config-h2Ri_tDO.mjs";
6
- import { a as RichTextDocSchema, c as isRecord$18, i as findUnfilledSentinels, n as buildEntryScaffold, o as isRichTextDoc, r as validateEntryInstance, s as isObjectRecord, t as eventUpsertInputSchema } from "../eventUpsertInputSchema-C-cDv9vR.mjs";
7
- import { a as prepareScaffoldExecution, c as LOCAL_PACKAGE_VENDOR_DIR, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, n as createScaffoldCompletion, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan } from "../plan-Dyv1rMTT.mjs";
2
+ import { $ as createFormRef, $n as deriveVideoSlotPolicy, $r as resolveTokenOrCssColorValue, An as deleteEnvSpecificKeys, Ar as makeBoundaryId, At as generateHeaderScrollTreatmentStyles, Bn as isSiteScopedDirectImageStoragePath, Br as surfaceDecorationColors, Bt as getComponentBorderWidthPx, C as sortRecord, Cn as boxBackgroundSchema, Cr as defineFrameCapability, Ct as deriveSiteStyleBlockPolicy, D as mapEventCommandContent, Dn as collectPortableMediaReferencesFromContent, Dr as featureCardCompositionTreatmentValues, Dt as getGradientPreset, En as stripStaleTransitionStyleGroup, Er as eyebrowTreatmentValues, Et as gradientToCss, F as pageIdentifierForBlockCommand, Fn as parseAspectRatioValue, Fr as visibleHeadingDecorationFamilyValues, Ft as BREAKPOINT_MD, G as ianaTimezoneSchema, Gn as resolveManagedMediaReference, Gr as mergeStyles, Gt as themeButtonExtraClassesWithTrailingIcon, H as bookingPaymentTermsSchema, Hn as persistableMediaSchema, Hr as TokenResolver, Ht as ICON_CONFIG, I as pageIdentifierForCommand, In as resolveMediaTransformForAspect, Ir as parseResolvedSurface, It as BREAKPOINT_SM, J as createCommandRef, Jn as buildMediaIdentifierFromFilename, Jr as mapDrawingStyle, Jt as parseThemeForPersistence, K as createBlockRef, Kn as mediaTypeDiscriminants, Kr as rgbColorValue, Kt as themeButtonSizeClassName, L as pagePathForCommand, Ln as getDirectImageUrlForRelativePath, Lr as parseSurfaceTree, Lt as BREAKPOINT_XL, M as blockIdentifierForCommand, Mn as rotateNormalizedPoint, Mr as testimonialsCompositionTreatmentValues, Mt as getHeaderPaintTargets, N as blockOrderIdentifiersForCommand, Nn as normalizeWidthCandidates, Nr as tileTreatmentValues, Nt as renderHeaderPaintTargetRules, On as summarizePortableMediaReferences, Or as headingDecorationColorTokenValues, Ot as parseGradientPresetId, P as entryIdentifierForCommand, Pn as isExplicitRectCrop, Pr as toNonEmptyReadonlyArray, Pt as BREAKPOINT_LG, Q as createFooterRef, Qr as resolveThemeColorReferenceValue, Qt as normalizeCardRole, R as hasConfiguredBookingVertical, Rn as getDirectImageUrlForSiteScopedPath, Rr as resolveSurface, Rt as MQ_MD_DOWN, S as venueManagementFields, Sn as boxBackgroundOverlaySchema, Sr as defineBlockDesignCapability, St as resolvePublishedLook, Tn as siteChromeBackgroundOverrideOwner, Tr as eventListTreatmentValues, Tt as compiledRuntimeStyleFieldNames, U as require_jsx_runtime, Un as runtimeMediaSchema, Ur as backgroundColorStyle, Ut as generateDefaultButtonSystem, V as bookingPaymentCollectionOptionSchema, Vn as mediaSchema, Vr as resolveSurfaceForeground, Vt as getComponentShadowVar, W as require_react, Wn as buildRenderableMediaAssetIndex, Wr as borderColorStyle, Wt as parseThemeButtonVariantId, X as createEventCategoryRef, Xn as parseMediaIdentifier, Xr as isCssColorLiteral, Xt as cardRoleSchema, Y as createContentEntryRef, Yn as parseCanonicalMediaIdentifier, Yr as opaqueSurfaceDeclarations, Yt as renderCssDeclarations, Z as createEventSeriesRef, Zr as resolveOnColorForThemeToken, Zt as cardVariantRoleValues, _n as heroPhotoPaintsGround, _r as asDesignBlockId, _t as resolveLookSlotSurfaces, ai as surfaceForegroundInputFromResolved, ar as parseRelativeStoragePath, b as isEventVisibility, bn as resolveSectionPhotoPlacement, br as asSiteStyleId, bt as resolveEffectiveArrangement, c as customLinkSchema$1, ci as expandPalette, cn as generateNavLinkCSS, cr as classifyKnownMimeType, ct as headerLeafTextColor, d as internalLinkSchema, di as parseBlockColorToken, dr as defineBlockDesignMetadata, ei as PUBLIC_BUTTON_ROLES, er as resolveVideoSelectionIntentForMediaField, et as createNavigationRef, f as internalResolvedLinkSchema, fi as __commonJSMin, fn as headerRootPaint, fr as resolveEffectiveKnobs, ft as mergeHeaderNavTypographyPreference, g as linkSchema, gn as deriveSectionGround, gt as resolveItemSurface, h as isResolvedInternalLinkEntityType, hn as sectionFactsForContent, hr as arrangementModes, ht as arrangementSlotNames, ii as surfaceForegroundDeclarations, it as refSlug, j as eventManagementTiming, jn as looksLikeUuid, jr as offeringsPreviewCompositionTreatmentValues, jt as generateMobileOverlayBackdropFilterFix, kn as walkAndCollectImageAttrs, kr as introCompositionTreatmentValues, kt as themeSchema, l as entryLinkSchema$1, li as getTextColorForBackground, lr as managementMediaLibraryUploadLimitForMimeType, lt as transparentHeaderForegroundInput, mn as composeBoundary, mr as cardListKnobBlocks, mt as arrangementLookHooks, ni as surfaceToneFromForegroundToken, nr as getMimeType, o as classifySdkEventBookingOffer, oi as surfaceForegroundStyle, on as footerForegroundCandidates, or as FILE_SIZE_LIMITS, ot as effectiveHeaderNavLinkStyle, p as internalRouteOnlyLinkSchema, pi as __toESM, pn as boundaryLayout, pr as cardListFamilyBlocks, pt as readHeaderNavFontSizePreference, q as createBlocksRef, qn as mediaIdentifierSchema, qr as textColorStyle, qt as themeButtonVariantClassNames, ri as defaultThemeTokens, rr as asRecord, rt as createVenueRef, s as RESOLVED_INTERNAL_LINK_ENTITY_TYPES, si as surfaceForegroundValue, sn as buildTextContrastShadow, st as headerForegroundCandidates, t as classifySdkEventTiming, ti as selectLogoVariant, tt as createPageRef, u as externalLinkSchema$1, ui as parseThemeColorToken, ur as parseSafeDownloadFilename, ut as readOpeningForegroundProjection, v as pageLinkSchema$1, vn as parseCanonicalRuntimeBackground, vr as asLayoutVariantKey, vt as arrangementManifestFromVariants, w as stableStringify, wn as runtimeBoxBackgroundSchema, wr as defineNoBlockDesignCapability, wt as requireCuratedSiteStyle, xn as sectionForegroundBackground, xr as assertNever$10, xt as resolveModeArrangement, yn as resolveSectionBackground, yt as readStoredMode, z as eventCommandScheduleSchema, zn as getImageUrl, zr as serializeSurfaceTree, zt as headerVariantValues } from "../sdk-event-upsert-4t4e1z-h.mjs";
3
+ import { $ as mapDrawingSchema, $n as ok, $t as isNonNegativeWholeCents$1, A as assessMailingListTargeting, At as addIntervalPreservingMonthAnchor, Bt as parseEventPageSurfaceSubject, C as exposeSecret, Ct as toScheduledBookingDateTime, D as parseMailingListContentVersionId, Dt as isLiveOrderInstalmentPlanStatus, E as parseMailingListBlockId, En as unsafeAsCheckoutLineId, Et as validateBookingPaymentOptionKinds, F as parseMailingListPlacementTargeting, Fn as unsafeAsMediaAssetId, Ft as omitZeroAmountFutureRows, G as locationMapLinks, Gt as publicEventPricingDisplay, H as assertAllowedPublicUrl, Ht as formatEventPricing, I as DEFAULT_MAILING_LIST_TARGETING, In as unsafeAsOccurrenceId, It as splitAmountWithRemainderInFirst, J as parseLocationValue, Jt as resolveExactOrFreePriceDisplay, K as locationValueSchema, Kt as publicEventPricingOptions, L as planMailingListChoicePresentation, Lt as resolveFlexibleBalanceDueAt, M as parseMailingListProviderScope, Mt as getBookingInstalmentDepositRefundability, N as parseFooterCompositionV1, Nt as getBookingInstalmentPlanIntervalCount, O as parseMailingListSignedSourceToken, On as unsafeAsDemoCapability, Ot as isSettleableFlexibleBalanceContractStatus, Pt as getBookingInstalmentProtectedDepositAmountCents, Qn as err, Qt as mapReadonlyNonEmptyArray, R as isCanonicalRichTextDoc, Rn as unsafeAsPassId, Rt as resolveFlexibleBalanceInitialPaymentCents, S as createSecret, Sn as parseUserId, St as toBookingTimeZone, T as slugify, U as decideLocationSave, Ut as isPublicEventPricingOptionDisplayable, V as parseWeeklyOpeningHours, Vn as unsafeAsPricingOptionId, Vt as formatBookingPriceDisplay, Wt as publicEventPricingCurrency, X as publicLocationSchema$1, Xt as fromArray, Y as projectPublicLocation, Yt as resolvePricingOptionsPriceDisplay, Z as toLocationCoordinates, _ as CANCELLED_SESSION_STATUS, _n as parseMembershipId, _t as parseBookingLocalDate, a as NAVIGATION_LOCATIONS, an as unsafeAsPositiveCents, at as formatTime$1, b as resolveWholeSeriesBookingPhase, bn as parseSiteId, bt as resolveBookingBusinessTimeZone, cn as assertNever, ct as resolveBookingDisplayContext, dn as parseCustomerId, dt as formatLocalScheduleDate, en as parseNonNegativeCents, et as selectCategoryView, f as EVENT_PRESET_VALUES, fn as parseDatedOfferingCapacityHoldAuditRef, ft as formatLocalScheduleTime, h as WHOLE_SERIES_EVENT_PRESET_VALUES, hn as parseEventSeriesId, ht as getLocalScheduleTime, i as EVENT_PRESET_VOCABULARY, in as unsafeAsNonNegativeCents, it as formatDateTimeRange, j as DEFAULT_MAILING_LIST_SUCCESS_MESSAGE, jn as unsafeAsEventInstanceId, jt as clampConfiguredAmount, k as parseMailingListRuntimeContext, kt as isSettleableOrderInstalmentPlanStatus, ln as formatDurationUnitLabel, lt as buildBookingUtcDateWindow, m as SURFACE_EVENT_PRESET_VALUES, mt as getLocalScheduleDate, nn as toCents, nt as formatDateRange, on as formatCurrencyAmount, ot as formatTimeRange, pn as parseDatedOfferingCapacityHoldId, pt as getBookingLocalDateKey, q as normalizeLocationAddressText, qt as publicEventPricingType, rn as toNonNegativeCents, rt as formatDateTime, sn as parseCurrencyCode, st as inferSiteDateLocale, tn as parsePositiveCents, tt as formatDate, u as resolveSiteVerticalBookingConfig, un as parseApiKeyId, ut as compareLocalScheduleDates, v as nextLiveRunSessionStartMs, vt as parseLocalScheduleTime, w as parseManagementKey, wt as toUtcIsoDateTimeString, x as resolveWholeSeriesRunLifecycle, xn as parseSiteTermsVersionId, xt as resolveBookingTimeZoneId, y as orderedLiveRunSessions, yn as parseRetiredCourseId, yt as parseUtcIsoDateTimeString, z as formatOpeningHoursRows, zn as unsafeAsPositiveByteCount, zt as deriveTotalTicketQuantity } from "../src-LhtqTjH7.mjs";
4
+ import { $ as normalizeMediaValueToIdentifierOnly, $t as createCommandContext, A as formatDiffDetail, An as getEnvPrefix, At as navigationIdentity, B as buildFieldChanges, Bn as portablePageDesignSchema, Bt as preparePushConfigTarget, C as reportFromOutcomes, Cn as requireEnvironmentWriteAuthorization, Ct as fileExists, D as normalizeRemoteHomepageReference, Dn as transportSuggestion, Dt as writeJsonFileAtomic, E as createEmptySyncResult, En as formatError, Et as writeJsonFile, F as calculatePullDiff, Fn as createManagementClient, Ft as navigationCommandItemToManagementInput, G as syncLocalMediaForPull, Gt as APPOINTMENT_SERVICE_VISIBILITY_VALUES, H as formatFieldPath, Hn as API_ENDPOINTS, Ht as extractApiErrorMessage, I as buildJsonDiff, In as ManagementApiError, It as normalizeNavigationConfigItemForCommand, J as admitBinaryWriteDestination, Jt as deriveCmsApiUrlFromDashboardUrl, K as applyLocalMediaPush, Kt as ApiRequestError, L as hasPageOperations, Ln as sdkEventScheduleSchema, Lt as applyPushConfigPlan, M as hasPendingChanges, Mn as isLocalConfigured, Mt as convertPulledFooterToLocal, N as findChangedFieldsWithValues, Nn as isRemoteConfigured, Nt as convertPulledNavigationToLocal, O as calculateDiff, On as CliExit, Ot as isMediaValue, P as formatHumanDiff, Pn as loadSdkEnvironment, Pt as convertPulledPagesToLocal, Q as normalizeMediaIdentifierInput, Qt as createClientForEnv, R as pageMetadataForUpsert, Rn as sdkSettingsUpdateSchema, Rt as createPushConfigCommand, S as planCliCommandBatchForBindings, Sn as planEnvironmentWriteAuthorization, St as ensureDir, T as executeResidualSettingsSyncPlan, Tn as ErrorCodes, Tt as readJsonFile, U as revalidateLocalMediaPushPlan, Un as ApiEnvelopeError, Ut as normalizeApiError, V as formatFieldChange, Vn as sdkConfiguredBookingVerticalConfigSchema, Vt as revalidatePushConfigPlan, Wn as unwrapResponse, Wt as isRecord$2, X as writeBinaryFileAtomic, Xt as bindRequestTimeout, Y as readStableBinaryFile, Yt as mapEnvironmentExecutionOutcomesJson, Z as sha256, Zt as confirmAction, _ as commandExecutionToReport, _n as withErrorHandling, _t as metadataFilePath, a as executeEntryCommandPlanAsReport, an as getOutputContext, at as readEntries, b as executeCompiledCliCommandPlanAsReport, bn as parseEnvironmentSelection, bt as writeMetadataFile, c as titleFromEntryData, cn as managementClientConfigFor, ct as readEventsMeta, d as unsafeAsCliEntryIdentifier, dn as parseJsonData, dt as readNavigationMeta, en as createGetCommand, et as walkLocalContentMedia, f as unsafeAsCliFormSlug, fn as parsePaginationOptions, ft as readPagesMeta, g as commandCompileFailureToReport, gn as withConfirmation, gt as ensureMetadataDir, h as mutationCounterForEffect, hn as withCommandContext, ht as writeMediaManifest, i as entrySiteCommandTypes, in as formatDateShort, it as findLegacyEntryFiles, j as formatDiffSummary, jn as getEnvironmentDebugInfo, jt as navigationIdentityMap, k as calculateFooterDiff, kt as duplicateNavigationIdentityMessage, l as unsafeAsCliBlockIdentifier, ln as mapEntryForOutput, lt as readFooterMeta, m as commandReportToSyncResult, mn as runWithInvocation, mt as readVenuesMeta, n as entryCommandCompileErrorToReport, nn as createOutputForCommand, nt as downloadMedia, o as executeEntryCommandPlanAsSyncResult, on as getOutputOnlyContext, ot as readAllMeta, p as unsafeAsCliPageIdentifier, pn as resolveCommandPath, pt as readSettingsMeta, q as prepareLocalMediaForPush, qt as createBearerAPIClient, r as entryCommandReportToSyncResult, rn as currentInvocationEnvelope, rt as extractMediaIdentifiers, s as syncResultForEntryCommandCompileError, sn as handleCommandError, st as readEventCategoriesMeta, t as compileEntryPushCommands, tn as createListCommand, tt as buildStorageUrl, u as unsafeAsCliContentTypeKey, un as parseJsonArray, ut as readFormsMeta, v as commandReportHasFailures, vn as withOutputOnlyErrorHandling, vt as metadataTargetFromEnvironment, w as mergeManySyncResults, wn as withRiverbankEnv, wt as listFiles, x as formatManagementError, xn as planEnvironmentExecution, xt as writeMetadataRecordMap, y as executeCliCommandPlan, yn as executeEnvironmentPlan, yt as readMetadataFile, zn as linkPayloadSchema, zt as loadPushConfigTarget } from "../entryCommands-nATGxgma.mjs";
5
+ import { r as CLI_VERSION, t as loadConfigFile } from "../load-config-DwiS-Ibn.mjs";
6
+ import { a as RichTextDocSchema, c as isRecord$18, i as findUnfilledSentinels, n as buildEntryScaffold, o as isRichTextDoc, r as validateEntryInstance, s as isObjectRecord, t as eventUpsertInputSchema } from "../eventUpsertInputSchema-XRzH6yFb.mjs";
7
+ import { a as prepareScaffoldExecution, c as LOCAL_PACKAGE_VENDOR_DIR, d as loadGeneratedPackageRanges, i as preflightScaffoldTargets, n as createScaffoldCompletion, s as deriveScaffoldLocalManifest, t as deriveScaffoldPlan } from "../plan-ChNV88KF.mjs";
8
8
  import { config } from "dotenv";
9
9
  import { Command, CommanderError } from "commander";
10
10
  import * as fs$2 from "fs/promises";
@@ -7601,11 +7601,14 @@ const manifestSchema = z.object({
7601
7601
  }).optional()
7602
7602
  }).optional(),
7603
7603
  promotedFields: z.array(z.string().min(1)).optional(),
7604
+ arrangementOwnedFieldIds: z.array(z.string().min(1)).readonly().optional(),
7604
7605
  variantMeaning: z.discriminatedUnion("kind", [z.object({
7605
7606
  kind: z.literal("arrangement"),
7606
7607
  lookOnlyKeys: z.array(z.string().min(1)).readonly().optional()
7607
7608
  }), z.object({
7608
7609
  kind: z.literal("mode"),
7610
+ modes: z.array(z.enum(arrangementModes)).min(1).readonly(),
7611
+ defaultMode: z.enum(arrangementModes),
7609
7612
  arrangementField: z.string().min(1),
7610
7613
  keys: z.array(z.string().min(1)).min(1).readonly(),
7611
7614
  defaultKey: z.string().min(1),
@@ -9348,7 +9351,7 @@ const ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
9348
9351
  const DATE_PATTERN = /^(?<year>[1-9]\d{3})-(?<month>\d{2})-(?<day>\d{2})$/;
9349
9352
  const TIME_PATTERN = /^(?<hours>[01]\d|2[0-3]):(?<minutes>[0-5]\d)$/;
9350
9353
  const DATETIME_PATTERN = /^(?<date>[1-9]\d{3}-\d{2}-\d{2})T(?<time>(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d)(?:\.\d+)?(?<offset>Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
9351
- function assertNever$12(value) {
9354
+ function assertNever$11(value) {
9352
9355
  throw new Error(`Unhandled field validation variant: ${JSON.stringify(value)}`);
9353
9356
  }
9354
9357
  function validationContext(options = {}) {
@@ -9415,7 +9418,7 @@ function fieldIssueToMessage(issue$1) {
9415
9418
  case "invalidPhone":
9416
9419
  case "invalidTime":
9417
9420
  case "invalidUrl": return simpleIssueMessages[issue$1.kind];
9418
- default: return assertNever$12(issue$1);
9421
+ default: return assertNever$11(issue$1);
9419
9422
  }
9420
9423
  }
9421
9424
  function pluralize(label, count) {
@@ -9544,7 +9547,7 @@ function deriveFieldValidationPlan(field, path$3 = [field.id]) {
9544
9547
  case "presetOrCustom":
9545
9548
  case "contentTypeSelect":
9546
9549
  case "entryPicker": return makePlan("passthrough", "unknown", field, path$3, false, []);
9547
- default: return assertNever$12(field);
9550
+ default: return assertNever$11(field);
9548
9551
  }
9549
9552
  }
9550
9553
  function deriveRepeaterFieldValidationPlan(field, path$3) {
@@ -9653,7 +9656,7 @@ function resolveSelectConstraintSource(field) {
9653
9656
  kind: "runtime",
9654
9657
  source: source.kind
9655
9658
  };
9656
- default: return assertNever$12(source);
9659
+ default: return assertNever$11(source);
9657
9660
  }
9658
9661
  }
9659
9662
  function fieldPlanToNativeInputProps(plan) {
@@ -9705,7 +9708,7 @@ function fieldPlanToNativeInputProps(plan) {
9705
9708
  case "linkObject":
9706
9709
  case "referenceText":
9707
9710
  case "blockIconValue": break;
9708
- default: assertNever$12(constraint);
9711
+ default: assertNever$11(constraint);
9709
9712
  }
9710
9713
  }
9711
9714
  return props$1;
@@ -9713,32 +9716,6 @@ function fieldPlanToNativeInputProps(plan) {
9713
9716
  function normalizeFieldInput(plan, value, options = {}) {
9714
9717
  return normalizeFieldValue(plan, value, validationContext(options));
9715
9718
  }
9716
- /** Drop obsolete presentation containers only when reading persisted content.
9717
- * Flat data remains authoritative; unknown variants and legitimate groups survive.
9718
- */
9719
- function normalizeLegacyStoredGroupContainers(plans, content) {
9720
- if (!isPlainObject$6(content)) return content;
9721
- const planMap = new Map(plans.map((plan) => [plan.fieldId, plan]));
9722
- const entries = Object.entries(content).map(([key, value]) => {
9723
- const plan = planMap.get(key);
9724
- return [key, plan ? normalizeLegacyStoredField(plan, value) : value];
9725
- });
9726
- return entries.every(([key, value]) => value === content[key]) ? content : Object.fromEntries(entries);
9727
- }
9728
- function normalizeLegacyStoredField(plan, value) {
9729
- if (plan.kind === "group") {
9730
- return normalizeLegacyStoredGroupContainers(selectedGroupChildPlans(plan, value), value);
9731
- }
9732
- if (plan.kind !== "repeater" || !isUnknownArray$2(value)) return value;
9733
- const items = value.map((item) => {
9734
- if (!isPlainObject$6(item)) return item;
9735
- const selection = selectRepeaterItemPlan(plan, item);
9736
- if (selection.kind !== "fields") return item;
9737
- const retained = selection.flattenedGroupIds.some((key) => Object.prototype.hasOwnProperty.call(item, key)) ? Object.fromEntries(Object.entries(item).filter(([key]) => !selection.flattenedGroupIds.includes(key))) : item;
9738
- return normalizeLegacyStoredGroupContainers(selection.fields, retained);
9739
- });
9740
- return items.every((item, index) => item === value[index]) ? value : items;
9741
- }
9742
9719
  function normalizeStoredContentValues(plans, content, options = {}) {
9743
9720
  if (!content || typeof content !== "object" || Array.isArray(content)) {
9744
9721
  return {};
@@ -9780,7 +9757,7 @@ function normalizeStoredFieldValueWithContext(plan, value, ctx) {
9780
9757
  case "link":
9781
9758
  case "select":
9782
9759
  case "passthrough": return normalizeFieldValue(plan, value, ctx);
9783
- default: return assertNever$12(plan);
9760
+ default: return assertNever$11(plan);
9784
9761
  }
9785
9762
  }
9786
9763
  function normalizeStoredObjectChildren(children, value, ctx) {
@@ -9831,7 +9808,7 @@ function normalizeFieldValue(plan, value, ctx) {
9831
9808
  case "select":
9832
9809
  case "passthrough": return value;
9833
9810
  case "media": return value;
9834
- default: return assertNever$12(plan);
9811
+ default: return assertNever$11(plan);
9835
9812
  }
9836
9813
  }
9837
9814
  function normalizeObjectChildren(children, value, ctx) {
@@ -9895,7 +9872,7 @@ function validateNormalizedFieldValue(plan, value, ctx) {
9895
9872
  case "repeater": return validateRepeaterPlan(plan, value, ctx);
9896
9873
  case "group": return validateGroupPlan(plan, value, ctx);
9897
9874
  case "passthrough": return [];
9898
- default: return assertNever$12(plan);
9875
+ default: return assertNever$11(plan);
9899
9876
  }
9900
9877
  }
9901
9878
  function validateMediaPlan(plan, value, ctx) {
@@ -10000,7 +9977,7 @@ function validateNumberConstraint(plan, constraint, value) {
10000
9977
  case "numberType": return [];
10001
9978
  case "numberMin": return value < constraint.minimum ? [issue(plan, "tooSmall", { minimum: constraint.minimum })] : [];
10002
9979
  case "numberMax": return value > constraint.maximum ? [issue(plan, "tooLarge", { maximum: constraint.maximum })] : [];
10003
- default: return assertNever$12(constraint);
9980
+ default: return assertNever$11(constraint);
10004
9981
  }
10005
9982
  }
10006
9983
  function validateSelectPlan(plan, value) {
@@ -10022,7 +9999,7 @@ function validateRepeaterPlan(plan, value, ctx) {
10022
9999
  maximum: constraint.maximum,
10023
10000
  itemLabel: "item"
10024
10001
  })] : [];
10025
- default: return assertNever$12(constraint);
10002
+ default: return assertNever$11(constraint);
10026
10003
  }
10027
10004
  });
10028
10005
  return [...constraintIssues, ...value.flatMap((item, index) => validateRepeaterItem(plan, item, index, ctx))];
@@ -10154,7 +10131,7 @@ function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
10154
10131
  ...plan,
10155
10132
  path: path$3
10156
10133
  };
10157
- default: return assertNever$12(plan);
10134
+ default: return assertNever$11(plan);
10158
10135
  }
10159
10136
  }
10160
10137
  function validateInlineTextPlan(plan, value, ctx) {
@@ -10207,7 +10184,7 @@ function fieldPlanToObjectPropertyZod(plan, options = {}, layoutGridCoordinates
10207
10184
  switch (presence.kind) {
10208
10185
  case "required": return schema;
10209
10186
  case "optional": return schema.optional();
10210
- default: return assertNever$12(presence);
10187
+ default: return assertNever$11(presence);
10211
10188
  }
10212
10189
  }
10213
10190
  /** Validate stored or runtime fields without applying editor/write normalization. */
@@ -10297,7 +10274,7 @@ function findNestedFieldValidationPlan(plan, path$3) {
10297
10274
  case "link":
10298
10275
  case "select":
10299
10276
  case "passthrough": return null;
10300
- default: return assertNever$12(plan);
10277
+ default: return assertNever$11(plan);
10301
10278
  }
10302
10279
  }
10303
10280
  function fieldValidationDescriptor(plan) {
@@ -10535,33 +10512,36 @@ function compileManifestContentContract(manifestOrFields, options = {}) {
10535
10512
  const plans = derivePlansFromManifestOrFields(manifestOrFields);
10536
10513
  const strictOptions = { allowNull: false };
10537
10514
  const strictStoredSchema = deriveStrictContentZodFromPlans(plans);
10538
- return Object.freeze({ [compiledManifestContentContract]: Object.freeze({
10539
- plans,
10540
- strictStoredSchema,
10541
- renderSourceSchema: deriveStrictContentZodFromPlans(plans, "render-source"),
10542
- writeSchema: deriveNormalizedContentZodFromPlans(plans, strictOptions, normalizeManifestContentForWrite).superRefine((value, ctx) => {
10543
- if (options.unknownFields !== "reject") return;
10544
- unknownManifestFieldPaths(plans, value).forEach((path$3) => {
10545
- ctx.addIssue({
10546
- code: "custom",
10547
- path: path$3,
10548
- message: `Unknown content field: ${path$3.join(".")}`
10515
+ return Object.freeze({
10516
+ fields: Array.isArray(manifestOrFields) ? manifestOrFields : manifestOrFields.fields,
10517
+ [compiledManifestContentContract]: Object.freeze({
10518
+ plans,
10519
+ strictStoredSchema,
10520
+ renderSourceSchema: deriveStrictContentZodFromPlans(plans, "render-source"),
10521
+ writeSchema: deriveNormalizedContentZodFromPlans(plans, strictOptions, normalizeManifestContentForWrite).superRefine((value, ctx) => {
10522
+ if (options.unknownFields !== "reject") return;
10523
+ unknownManifestFieldPaths(plans, value).forEach((path$3) => {
10524
+ ctx.addIssue({
10525
+ code: "custom",
10526
+ path: path$3,
10527
+ message: `Unknown content field: ${path$3.join(".")}`
10528
+ });
10549
10529
  });
10550
- });
10551
- }).transform((value) => canonicalizeObjectForWrite(plans, value)),
10552
- draftSchema: deriveNormalizedContentZodFromPlans(plans, {
10553
- allowNull: true,
10554
- allowIncomplete: true,
10555
- mode: "draft"
10556
- }, normalizeStoredContentValues),
10557
- renderDraftSchema: deriveNormalizedContentZodFromPlans(plans, {
10558
- allowNull: true,
10559
- allowIncomplete: true,
10560
- mode: "draft"
10561
- }, normalizeStoredContentValues, false),
10562
- renderSchema: deriveStrictContentZodFromPlans(plans, "render"),
10563
- findNonPortableMediaPaths: (content) => findNonPortableMediaPaths(plans, content)
10564
- }) });
10530
+ }).transform((value) => canonicalizeObjectForWrite(plans, value)),
10531
+ draftSchema: deriveNormalizedContentZodFromPlans(plans, {
10532
+ allowNull: true,
10533
+ allowIncomplete: true,
10534
+ mode: "draft"
10535
+ }, normalizeStoredContentValues),
10536
+ renderDraftSchema: deriveNormalizedContentZodFromPlans(plans, {
10537
+ allowNull: true,
10538
+ allowIncomplete: true,
10539
+ mode: "draft"
10540
+ }, normalizeStoredContentValues, false),
10541
+ renderSchema: deriveStrictContentZodFromPlans(plans, "render"),
10542
+ findNonPortableMediaPaths: (content) => findNonPortableMediaPaths(plans, content)
10543
+ })
10544
+ });
10565
10545
  }
10566
10546
  function unknownManifestFieldPaths(plans, value, parent = [], discriminator) {
10567
10547
  if (!isPlainRecord$1(value)) return [];
@@ -10597,8 +10577,7 @@ function findNonPortableManifestMediaPaths(contract, content) {
10597
10577
  /** Strictly admits already-persisted content without repairing it. */
10598
10578
  function admitStoredManifestContent(contract, content) {
10599
10579
  const state = contract[compiledManifestContentContract];
10600
- const normalized = normalizeLegacyStoredGroupContainers(state.plans, content);
10601
- const nonPortablePaths = state.findNonPortableMediaPaths(normalized);
10580
+ const nonPortablePaths = state.findNonPortableMediaPaths(content);
10602
10581
  if (nonPortablePaths.length > 0) {
10603
10582
  return {
10604
10583
  ok: false,
@@ -10608,20 +10587,23 @@ function admitStoredManifestContent(contract, content) {
10608
10587
  }
10609
10588
  };
10610
10589
  }
10611
- const parsed = state.strictStoredSchema.safeParse(normalized);
10590
+ const parsed = state.strictStoredSchema.safeParse(content);
10612
10591
  return parsed.success ? {
10613
10592
  ok: true,
10614
- value: normalized
10593
+ value: content
10615
10594
  } : {
10616
10595
  ok: false,
10617
10596
  error: zodAdmissionError(parsed.error)
10618
10597
  };
10619
10598
  }
10599
+ /** Presentation recovery preserves authored payloads and does not admit them for a write. */
10600
+ function projectStoredManifestContentForRendering(contract, content) {
10601
+ return projectLayoutGridPlansForRendering(contract[compiledManifestContentContract].plans, content);
10602
+ }
10620
10603
  /** Public reads alone may project invalid grid geometry. All other stored-shape and portability checks remain strict. */
10621
10604
  function admitStoredManifestContentForRendering(contract, content) {
10622
10605
  const state = contract[compiledManifestContentContract];
10623
- const normalized = normalizeLegacyStoredGroupContainers(state.plans, content);
10624
- const paths = state.findNonPortableMediaPaths(normalized);
10606
+ const paths = state.findNonPortableMediaPaths(content);
10625
10607
  if (paths.length > 0) return {
10626
10608
  ok: false,
10627
10609
  error: {
@@ -10629,7 +10611,7 @@ function admitStoredManifestContentForRendering(contract, content) {
10629
10611
  paths
10630
10612
  }
10631
10613
  };
10632
- const projected = projectLayoutGridPlansForRendering(state.plans, normalized);
10614
+ const projected = projectStoredManifestContentForRendering(contract, content);
10633
10615
  const parsed = state.renderSourceSchema.safeParse(projected);
10634
10616
  return parsed.success ? {
10635
10617
  ok: true,
@@ -10726,7 +10708,7 @@ function validateManifestWriteCandidate(contract, data) {
10726
10708
  */
10727
10709
  function deriveRenderableManifestContent(contract, stored, project) {
10728
10710
  const state = contract[compiledManifestContentContract];
10729
- const projected = projectLayoutGridPlansForRendering(state.plans, normalizeLegacyStoredGroupContainers(state.plans, project(stored)));
10711
+ const projected = projectLayoutGridPlansForRendering(state.plans, project(stored));
10730
10712
  const parsed = state.renderSchema.safeParse(projected);
10731
10713
  return parsed.success ? {
10732
10714
  ok: true,
@@ -10743,7 +10725,7 @@ function deriveRenderableManifestContent(contract, stored, project) {
10743
10725
  */
10744
10726
  function admitTransportedRenderableManifestContent(contract, content) {
10745
10727
  const state = contract[compiledManifestContentContract];
10746
- const projected = projectLayoutGridPlansForRendering(state.plans, content);
10728
+ const projected = projectStoredManifestContentForRendering(contract, content);
10747
10729
  const parsed = state.renderSchema.safeParse(projected);
10748
10730
  return parsed.success ? {
10749
10731
  ok: true,
@@ -18490,6 +18472,7 @@ function createBlockManifest(config$1) {
18490
18472
  icon: config$1.icon ?? "Box",
18491
18473
  layout,
18492
18474
  variants,
18475
+ arrangementOwnedFieldIds: config$1.arrangementOwnedFieldIds,
18493
18476
  variantMeaning: config$1.variantMeaning,
18494
18477
  defaultVariant: config$1.defaultVariant,
18495
18478
  variantOptions: config$1.variantOptions,
@@ -18568,7 +18551,12 @@ const lookSticker = text({
18568
18551
  as: "p",
18569
18552
  ...lookSlot("sticker")
18570
18553
  }, when("content._effectiveKnobs.stickerLine.value"), bind("content.stickerLine"));
18571
- const heroContentNodes = [lookCaption, ...heroCopyAndCta.layout];
18554
+ const heroActionsNote = richText({ className: "hero-actions-note" }, when("content.actionsNote"), bind("content.actionsNote"));
18555
+ const heroContentNodes = [
18556
+ lookCaption,
18557
+ ...heroCopyAndCta.layout,
18558
+ heroActionsNote
18559
+ ];
18572
18560
  function heroContentCard(children, gap, copyAtCard) {
18573
18561
  return styledContainer({
18574
18562
  bindFrom: "_contentCardStyles",
@@ -18697,7 +18685,8 @@ const headlineRowLayout = heroLookLayout([
18697
18685
  el("div", lookSlot("copy"), [
18698
18686
  lookCaption,
18699
18687
  ...heroCopyFragment.layout.slice(2),
18700
- ...heroCtaRowFragment.layout
18688
+ ...heroCtaRowFragment.layout,
18689
+ heroActionsNote
18701
18690
  ]),
18702
18691
  lookPhoto
18703
18692
  ]);
@@ -18784,6 +18773,17 @@ const heroConfig = {
18784
18773
  hidden: true
18785
18774
  }
18786
18775
  },
18776
+ {
18777
+ id: "actionsNote",
18778
+ type: "richText",
18779
+ label: "Line in place of the buttons",
18780
+ required: false,
18781
+ ui: {
18782
+ intent: "display",
18783
+ hidden: true,
18784
+ richTextVariant: "limited"
18785
+ }
18786
+ },
18787
18787
  createImageShapeField({
18788
18788
  id: "imageShape",
18789
18789
  label: "Image shape",
@@ -21658,7 +21658,7 @@ function planSiteChromePlacement(positioning) {
21658
21658
  headerRootClassName: "rb-fixed rb-top-0 rb-left-0 rb-right-0",
21659
21659
  standaloneShellClassName: "fixed left-0 right-0 top-0 z-40 w-full"
21660
21660
  };
21661
- default: return assertNever$11(positioning);
21661
+ default: return assertNever$10(positioning);
21662
21662
  }
21663
21663
  }
21664
21664
  function splitSiteChromePlacementClasses(className) {
@@ -22237,6 +22237,100 @@ function readRuntimeNow(value) {
22237
22237
  return parsed.value;
22238
22238
  }
22239
22239
 
22240
+ //#endregion
22241
+ //#region ../blocks/src/system/blocks/shared/teamMembers.ts
22242
+ const teamMemberSpecialtiesInputSchema = z.union([z.string(), z.array(z.string())]).nullish();
22243
+ function parseTeamMemberSpecialties(value) {
22244
+ const parsed = teamMemberSpecialtiesInputSchema.safeParse(value);
22245
+ if (!parsed.success) return [];
22246
+ const parts = typeof parsed.data === "string" ? parsed.data.split(/\r?\n|,/) : parsed.data ?? [];
22247
+ return [...new Set(parts.map((part) => part.trim()).filter(Boolean))];
22248
+ }
22249
+ const biographyTextSchema = z.string().transform((text$1) => text$1.split(/\r?\n\s*\r?\n/).map((paragraph) => paragraph.trim()).filter(Boolean));
22250
+ const biographySourceSchema = z.union([RichTextDocSchema, biographyTextSchema]).nullish().catch(null);
22251
+ const teamMemberBiographySchema = z.object({
22252
+ profileBio: biographySourceSchema,
22253
+ bio: biographySourceSchema,
22254
+ summary: biographySourceSchema
22255
+ });
22256
+ /**
22257
+ * The bio a section about one person shows, or null when they have none: the
22258
+ * bio from their profile when it says anything, else their short bio. A page
22259
+ * deciding whether someone has a bio and the block showing it both read this,
22260
+ * so a section is never promised words that aren't there.
22261
+ */
22262
+ function teamMemberBiography(member) {
22263
+ return firstBiography(member, [
22264
+ "profileBio",
22265
+ "bio",
22266
+ "summary"
22267
+ ]);
22268
+ }
22269
+ /**
22270
+ * The bio a compact card shows when a page asks for whichever bio the person
22271
+ * has: their short bio first, then their summary, and their profile bio only
22272
+ * when neither says anything.
22273
+ */
22274
+ function teamMemberCardBiography(member) {
22275
+ return firstBiography(member, [
22276
+ "bio",
22277
+ "summary",
22278
+ "profileBio"
22279
+ ]);
22280
+ }
22281
+ /**
22282
+ * What an older grid or stack card adds under its short bio slot: the card
22283
+ * bio, unless the short bio is already a rich-text document that slot shows.
22284
+ * That slot only renders documents, so a staff member's plain-text short bio
22285
+ * comes through here too, and the two never show together.
22286
+ */
22287
+ function teamMemberCardBiographyFallback(member) {
22288
+ const shortBio = firstBiography(member, ["bio"]);
22289
+ if (shortBio?.kind === "document") return null;
22290
+ const biography = teamMemberCardBiography(member);
22291
+ return biography ? teamMemberBiographyDocument(biography) : null;
22292
+ }
22293
+ /** A bio as one rich-text document, each plain paragraph its own paragraph. */
22294
+ function teamMemberBiographyDocument(biography) {
22295
+ if (biography.kind === "document") return biography.document;
22296
+ return {
22297
+ type: "doc",
22298
+ content: biography.paragraphs.map((text$1) => ({
22299
+ type: "paragraph",
22300
+ content: [{
22301
+ type: "text",
22302
+ text: text$1
22303
+ }]
22304
+ }))
22305
+ };
22306
+ }
22307
+ function firstBiography(member, order) {
22308
+ const parsed = teamMemberBiographySchema.safeParse(member);
22309
+ if (!parsed.success) return null;
22310
+ return order.map((key) => toBiography(parsed.data[key])).find((biography) => biography !== null) ?? null;
22311
+ }
22312
+ function toBiography(source) {
22313
+ if (source === null || source === undefined) return null;
22314
+ if (Array.isArray(source)) return source.length > 0 ? {
22315
+ kind: "text",
22316
+ paragraphs: source
22317
+ } : null;
22318
+ const document$1 = source;
22319
+ return hasText$1(document$1) ? {
22320
+ kind: "document",
22321
+ document: document$1
22322
+ } : null;
22323
+ }
22324
+ const textNodeSchema = z.object({
22325
+ text: z.string().optional(),
22326
+ content: z.array(z.unknown()).optional()
22327
+ });
22328
+ function hasText$1(node) {
22329
+ const parsed = textNodeSchema.safeParse(node);
22330
+ if (!parsed.success) return false;
22331
+ return (parsed.data.text?.trim().length ?? 0) > 0 || (parsed.data.content ?? []).some(hasText$1);
22332
+ }
22333
+
22240
22334
  //#endregion
22241
22335
  //#region ../blocks/src/system/transforms/registry/content.ts
22242
22336
  const supportedRichTextTokenSchema = z.enum(["year", "site_name"]);
@@ -22318,7 +22412,14 @@ const interpolateRichTextTokensTransform = {
22318
22412
  schema: interpolateRichTextTokensOptionsSchema,
22319
22413
  run: (value, options, context) => interpolateRichTextTokens(value, options, context)
22320
22414
  };
22321
- const contentTransforms = [interpolateRichTextTokensTransform];
22415
+ /** An older team card's bio when it has no short bio; see teamMemberCardBiographyFallback. */
22416
+ const teamMemberCardBiographyFallbackTransform = {
22417
+ id: "teamMember.cardBiographyFallback",
22418
+ kind: "formatter",
22419
+ summary: "A team member's card bio when they have no short bio",
22420
+ run: (value) => teamMemberCardBiographyFallback(value)
22421
+ };
22422
+ const contentTransforms = [interpolateRichTextTokensTransform, teamMemberCardBiographyFallbackTransform];
22322
22423
 
22323
22424
  //#endregion
22324
22425
  //#region ../blocks/src/system/transforms/typed.ts
@@ -23266,6 +23367,7 @@ const dataLoaders = { ...entriesLoader ? { entries: {
23266
23367
  }
23267
23368
  } } : {} };
23268
23369
  const testimonialsManifest = createBlockManifest({
23370
+ arrangementOwnedFieldIds: ["maxEntries", "avatarLayout"],
23269
23371
  variantMeaning: {
23270
23372
  kind: "arrangement",
23271
23373
  lookOnlyKeys: [
@@ -25623,6 +25725,14 @@ const eventVenueSchema = z.object({
25623
25725
  }).nullable()
25624
25726
  });
25625
25727
  /**
25728
+ * The map for an event details page: one drawing, for the venue of the event the page is about.
25729
+ * It travels beside the events rather than on any of them, so a list of events has no place for one.
25730
+ */
25731
+ const eventVenueDrawingSchema = z.object({
25732
+ venueId: z.string(),
25733
+ drawing: z.lazy(() => mapDrawingSchema)
25734
+ });
25735
+ /**
25626
25736
  * Zod schema for event category data
25627
25737
  */
25628
25738
  const eventCategorySchema = z.object({
@@ -26100,6 +26210,53 @@ function normalizeEventStaffMemberId(value) {
26100
26210
  return trimmed ? trimmed : null;
26101
26211
  }
26102
26212
 
26213
+ //#endregion
26214
+ //#region ../blocks/src/system/blocks/events/shared/detailsSelection.ts
26215
+ function isFutureOrNow(iso, nowIso) {
26216
+ const ts = Date.parse(iso);
26217
+ const now = Date.parse(nowIso);
26218
+ if (!Number.isFinite(ts) || !Number.isFinite(now)) return false;
26219
+ return ts >= now;
26220
+ }
26221
+ const localDateKey = (startsAt, timeZone) => getBookingLocalDateKey(toScheduledBookingDateTime({
26222
+ startsAt,
26223
+ timeZone
26224
+ }));
26225
+ function selectRequested(events, requested) {
26226
+ if (!requested) return null;
26227
+ const byId = events.find((event) => event.occurrenceId === requested.id || event.id === requested.id);
26228
+ if (byId) return byId;
26229
+ if (!requested.startsAt || !requested.timeZone) return null;
26230
+ const requestedDate = localDateKey(requested.startsAt, requested.timeZone);
26231
+ return events.find((event) => localDateKey(event.startsAt, event.timeZone) === requestedDate) ?? null;
26232
+ }
26233
+ function selectNextUpcoming(events, nowIso) {
26234
+ return [...events].filter((event) => isFutureOrNow(event.startsAt, nowIso)).sort((left, right) => Date.parse(left.startsAt) - Date.parse(right.startsAt))[0] ?? null;
26235
+ }
26236
+ function selectCompletedWholeSeries(events) {
26237
+ if (events.length === 0 || !events.every((event) => event.bookingScope === "whole_series")) {
26238
+ return null;
26239
+ }
26240
+ return [...events].sort((left, right) => Date.parse(right.startsAt) - Date.parse(left.startsAt))[0] ?? null;
26241
+ }
26242
+ function selectEventDetailsCandidate(events, requested, nowIso) {
26243
+ const selected = selectRequested(events, requested);
26244
+ if (selected) return {
26245
+ event: selected,
26246
+ mode: "selected"
26247
+ };
26248
+ const upcoming = selectNextUpcoming(events, nowIso);
26249
+ if (upcoming) return {
26250
+ event: upcoming,
26251
+ mode: "next"
26252
+ };
26253
+ const completed = selectCompletedWholeSeries(events);
26254
+ return completed ? {
26255
+ event: completed,
26256
+ mode: "completed"
26257
+ } : null;
26258
+ }
26259
+
26103
26260
  //#endregion
26104
26261
  //#region ../blocks/src/system/blocks/shop.shared.ts
26105
26262
  /**
@@ -31760,20 +31917,20 @@ const FIELD_LABELS = {
31760
31917
  description: "Short, concrete examples you can refer back to when writing new copy."
31761
31918
  }
31762
31919
  };
31763
- const IDLE_FEEDBACK$2 = idleFeedback$3();
31764
- function idleFeedback$3() {
31920
+ const IDLE_FEEDBACK$2 = idleFeedback$2();
31921
+ function idleFeedback$2() {
31765
31922
  return { tag: "idle" };
31766
31923
  }
31767
31924
  function pendingFeedback$1() {
31768
31925
  return { tag: "pending" };
31769
31926
  }
31770
- function errorFeedback$3(message) {
31927
+ function errorFeedback$2(message) {
31771
31928
  return {
31772
31929
  tag: "error",
31773
31930
  message
31774
31931
  };
31775
31932
  }
31776
- function assertNever$10(value) {
31933
+ function assertNever$9(value) {
31777
31934
  throw new Error(`Unexpected value: ${String(value)}`);
31778
31935
  }
31779
31936
  function createAiBrandGuidelinesGenerationDialogState(sessionId, open$1) {
@@ -31813,7 +31970,7 @@ function aiBrandGuidelinesGenerationDialogReducer(state, action) {
31813
31970
  case "context-load-failed": return {
31814
31971
  ...state,
31815
31972
  context: null,
31816
- contextFeedback: errorFeedback$3(action.message)
31973
+ contextFeedback: errorFeedback$2(action.message)
31817
31974
  };
31818
31975
  case "use-site-content-changed": return state.useSiteContent === action.value ? state : {
31819
31976
  ...state,
@@ -31859,13 +32016,13 @@ function aiBrandGuidelinesGenerationDialogReducer(state, action) {
31859
32016
  if (!state.open || state.sessionId !== action.sessionId) return state;
31860
32017
  return {
31861
32018
  ...state,
31862
- generateFeedback: errorFeedback$3(action.message)
32019
+ generateFeedback: errorFeedback$2(action.message)
31863
32020
  };
31864
32021
  case "current-proposal-accepted":
31865
32022
  if (state.proposal === null) return state;
31866
32023
  return advanceWizardField(state, mergeLockedSettings(state.lockedSettings, state.proposal));
31867
32024
  case "current-proposal-skipped": return advanceWizardField(state, state.lockedSettings);
31868
- default: return assertNever$10(action);
32025
+ default: return assertNever$9(action);
31869
32026
  }
31870
32027
  }
31871
32028
  function advanceWizardField(state, nextLockedSettings) {
@@ -31947,8 +32104,8 @@ function mergeLockedSettings(lockedSettings, proposal) {
31947
32104
  ...proposal
31948
32105
  };
31949
32106
  }
31950
- const idleFeedback$2 = () => ({ tag: "idle" });
31951
- const errorFeedback$2 = (message) => ({
32107
+ const idleFeedback$1 = () => ({ tag: "idle" });
32108
+ const errorFeedback$1 = (message) => ({
31952
32109
  tag: "error",
31953
32110
  message
31954
32111
  });
@@ -31966,14 +32123,14 @@ const err$1 = (error$1) => ({
31966
32123
  error: error$1
31967
32124
  });
31968
32125
  function resetDialogFeedback(feedback) {
31969
- return feedback.tag === "idle" ? feedback : idleFeedback$2();
32126
+ return feedback.tag === "idle" ? feedback : idleFeedback$1();
31970
32127
  }
31971
32128
  function createDialogState(dialog) {
31972
32129
  switch (dialog.kind) {
31973
32130
  case "create-preview": return {
31974
32131
  tag: "create-preview",
31975
32132
  draft: { name: "" },
31976
- feedback: idleFeedback$2()
32133
+ feedback: idleFeedback$1()
31977
32134
  };
31978
32135
  case "create-content": return {
31979
32136
  tag: "create-content",
@@ -31981,19 +32138,19 @@ function createDialogState(dialog) {
31981
32138
  name: "",
31982
32139
  environment: "live"
31983
32140
  },
31984
- feedback: idleFeedback$2()
32141
+ feedback: idleFeedback$1()
31985
32142
  };
31986
32143
  case "create-management": return {
31987
32144
  tag: "create-management",
31988
32145
  draft: { name: "" },
31989
- feedback: idleFeedback$2()
32146
+ feedback: idleFeedback$1()
31990
32147
  };
31991
32148
  case "confirm-operation": return {
31992
32149
  tag: "confirm-operation",
31993
32150
  operation: dialog.operation,
31994
- feedback: idleFeedback$2()
32151
+ feedback: idleFeedback$1()
31995
32152
  };
31996
- default: return assertNever$9(dialog);
32153
+ default: return assertNever$8(dialog);
31997
32154
  }
31998
32155
  }
31999
32156
  function getOperationKeyType(operation) {
@@ -32004,7 +32161,7 @@ function getOperationKeyType(operation) {
32004
32161
  case "revoke-content": return "content";
32005
32162
  case "create-management":
32006
32163
  case "revoke-management": return "management";
32007
- default: return assertNever$9(operation);
32164
+ default: return assertNever$8(operation);
32008
32165
  }
32009
32166
  }
32010
32167
  function getRefreshToken(refresh$1, keyType) {
@@ -32012,7 +32169,7 @@ function getRefreshToken(refresh$1, keyType) {
32012
32169
  case "preview": return refresh$1.preview;
32013
32170
  case "content": return refresh$1.content;
32014
32171
  case "management": return refresh$1.management;
32015
- default: return assertNever$9(keyType);
32172
+ default: return assertNever$8(keyType);
32016
32173
  }
32017
32174
  }
32018
32175
  function isSameOperation(left, right) {
@@ -32024,7 +32181,7 @@ function isSameOperation(left, right) {
32024
32181
  case "revoke-preview":
32025
32182
  case "revoke-content":
32026
32183
  case "revoke-management": return "keyId" in right && left.keyId === right.keyId;
32027
- default: return assertNever$9(left);
32184
+ default: return assertNever$8(left);
32028
32185
  }
32029
32186
  }
32030
32187
  function matchesDialogOperation(dialog, operation) {
@@ -32035,7 +32192,7 @@ function matchesDialogOperation(dialog, operation) {
32035
32192
  case "confirm-operation": return isSameOperation(dialog.operation, operation);
32036
32193
  case "closed":
32037
32194
  case "show-new-key": return false;
32038
- default: return assertNever$9(dialog);
32195
+ default: return assertNever$8(dialog);
32039
32196
  }
32040
32197
  }
32041
32198
  function isFeedbackDialog(dialog) {
@@ -32091,7 +32248,7 @@ function reduceRefreshState(refresh$1, action) {
32091
32248
  ...refresh$1,
32092
32249
  management: action.refreshToken
32093
32250
  };
32094
- default: return assertNever$9(keyType);
32251
+ default: return assertNever$8(keyType);
32095
32252
  }
32096
32253
  }
32097
32254
  function reduceCommandState(command, action) {
@@ -32114,7 +32271,7 @@ function reduceCommandState(command, action) {
32114
32271
  case "preview-draft-invalid":
32115
32272
  case "data-refreshed":
32116
32273
  case "refresh-warning-reported": return command;
32117
- default: return assertNever$9(action);
32274
+ default: return assertNever$8(action);
32118
32275
  }
32119
32276
  }
32120
32277
  function reduceDialogState(dialog, action) {
@@ -32147,19 +32304,19 @@ function reduceDialogState(dialog, action) {
32147
32304
  } : dialog;
32148
32305
  case "preview-draft-invalid": return dialog.tag === "create-preview" ? {
32149
32306
  ...dialog,
32150
- feedback: errorFeedback$2(action.message)
32307
+ feedback: errorFeedback$1(action.message)
32151
32308
  } : dialog;
32152
32309
  case "content-draft-invalid": return dialog.tag === "create-content" ? {
32153
32310
  ...dialog,
32154
- feedback: errorFeedback$2(action.message)
32311
+ feedback: errorFeedback$1(action.message)
32155
32312
  } : dialog;
32156
32313
  case "command-started": return matchesDialogOperation(dialog, action.operation) && isFeedbackDialog(dialog) ? {
32157
32314
  ...dialog,
32158
- feedback: idleFeedback$2()
32315
+ feedback: idleFeedback$1()
32159
32316
  } : dialog;
32160
32317
  case "command-failed": return matchesDialogOperation(dialog, action.operation) && isFeedbackDialog(dialog) ? {
32161
32318
  ...dialog,
32162
- feedback: errorFeedback$2(action.message)
32319
+ feedback: errorFeedback$1(action.message)
32163
32320
  } : dialog;
32164
32321
  case "new-key-received": return {
32165
32322
  tag: "show-new-key",
@@ -32171,7 +32328,7 @@ function reduceDialogState(dialog, action) {
32171
32328
  case "page-feedback-reported":
32172
32329
  case "data-refreshed":
32173
32330
  case "refresh-warning-reported": return dialog;
32174
- default: return assertNever$9(action);
32331
+ default: return assertNever$8(action);
32175
32332
  }
32176
32333
  }
32177
32334
  function reduceDataState(data, action) {
@@ -32189,7 +32346,7 @@ function reduceDataState(data, action) {
32189
32346
  ...data,
32190
32347
  managementKeys: action.managementKeys
32191
32348
  };
32192
- default: return assertNever$9(action);
32349
+ default: return assertNever$8(action);
32193
32350
  }
32194
32351
  case "key-revoked": switch (action.operation.kind) {
32195
32352
  case "revoke-preview": return {
@@ -32204,7 +32361,7 @@ function reduceDataState(data, action) {
32204
32361
  ...data,
32205
32362
  managementKeys: data.managementKeys.filter((key) => key.id !== action.operation.keyId)
32206
32363
  };
32207
- default: return assertNever$9(action.operation);
32364
+ default: return assertNever$8(action.operation);
32208
32365
  }
32209
32366
  case "dialog-opened":
32210
32367
  case "dialog-closed":
@@ -32219,7 +32376,7 @@ function reduceDataState(data, action) {
32219
32376
  case "command-failed":
32220
32377
  case "new-key-received":
32221
32378
  case "refresh-warning-reported": return data;
32222
- default: return assertNever$9(action);
32379
+ default: return assertNever$8(action);
32223
32380
  }
32224
32381
  }
32225
32382
  function reducePageFeedback(pageFeedback, action) {
@@ -32242,7 +32399,7 @@ function reducePageFeedback(pageFeedback, action) {
32242
32399
  case "preview-draft-invalid":
32243
32400
  case "data-refreshed":
32244
32401
  case "command-failed": return pageFeedback;
32245
- default: return assertNever$9(action);
32402
+ default: return assertNever$8(action);
32246
32403
  }
32247
32404
  }
32248
32405
  function isBlockedWhilePending(action) {
@@ -32270,7 +32427,7 @@ function apiKeysSettingsReducer(state, action) {
32270
32427
  function isApiKeysCommandPending(command, operation) {
32271
32428
  return isPendingCommand(command, operation);
32272
32429
  }
32273
- function assertNever$9(value, message) {
32430
+ function assertNever$8(value, message) {
32274
32431
  throw new Error(message ?? `Unexpected value: ${String(value)}`);
32275
32432
  }
32276
32433
  function selectApiKeysSubmitting(state) {
@@ -32371,300 +32528,6 @@ function toggleAsset(selected, asset) {
32371
32528
  function selectAllAssets(assets) {
32372
32529
  return [...assets];
32373
32530
  }
32374
- const EMPTY_FIELD_ERRORS = [];
32375
- const EMPTY_COUNT_ENTRIES = [];
32376
- const IMPORT_COUNT_ENTRIES_CACHE = /* @__PURE__ */ new WeakMap();
32377
- const ZERO_SUMMARY = {
32378
- totalUpdated: 0,
32379
- totalFailed: 0
32380
- };
32381
- function parseBackupMembershipMode(value) {
32382
- switch (value) {
32383
- case "skip":
32384
- case "invite":
32385
- case "preview": return value;
32386
- default: throw new Error(`Unexpected membership mode: ${value}`);
32387
- }
32388
- }
32389
- function parseBackupApiKeyMode(value) {
32390
- switch (value) {
32391
- case "skip":
32392
- case "regenerate":
32393
- case "preview": return value;
32394
- default: throw new Error(`Unexpected API key mode: ${value}`);
32395
- }
32396
- }
32397
- function buildBackupImportCountEntries(result) {
32398
- if (result?.counts === void 0 || result.counts === null) return EMPTY_COUNT_ENTRIES;
32399
- const cachedEntries = IMPORT_COUNT_ENTRIES_CACHE.get(result);
32400
- if (cachedEntries !== void 0) return cachedEntries;
32401
- const entries = Object.entries(result.counts).map(([table, counts]) => ({
32402
- table,
32403
- counts
32404
- }));
32405
- IMPORT_COUNT_ENTRIES_CACHE.set(result, entries);
32406
- return entries;
32407
- }
32408
- function deriveBackupImportSummary(entries) {
32409
- if (entries.length === 0) return ZERO_SUMMARY;
32410
- return entries.reduce((sum, entry) => ({
32411
- totalUpdated: sum.totalUpdated + entry.counts.updated,
32412
- totalFailed: sum.totalFailed + entry.counts.failed
32413
- }), ZERO_SUMMARY);
32414
- }
32415
- function clearBackupImportOutcome(state) {
32416
- return {
32417
- ...state,
32418
- phase: "idle",
32419
- fileError: null,
32420
- fieldErrors: null,
32421
- feedback: idleFeedback$1()
32422
- };
32423
- }
32424
- function backupImportOptionsReducer(state, action) {
32425
- switch (action.type) {
32426
- case "clean-import-changed": return state.cleanImport === action.value ? state : {
32427
- ...state,
32428
- cleanImport: action.value
32429
- };
32430
- case "dry-run-changed": return state.dryRun === action.value ? state : {
32431
- ...state,
32432
- dryRun: action.value
32433
- };
32434
- case "membership-mode-changed": return state.membershipMode === action.value ? state : {
32435
- ...state,
32436
- membershipMode: action.value
32437
- };
32438
- case "api-key-mode-changed": return state.apiKeyMode === action.value ? state : {
32439
- ...state,
32440
- apiKeyMode: action.value
32441
- };
32442
- case "send-emails-changed": return state.sendEmails === action.value ? state : {
32443
- ...state,
32444
- sendEmails: action.value
32445
- };
32446
- default: return assertNever$8(action);
32447
- }
32448
- }
32449
- function backupExportStateReducer(state, action) {
32450
- switch (action.type) {
32451
- case "include-media-changed": return state.includeMedia === action.value ? state : {
32452
- ...state,
32453
- includeMedia: action.value
32454
- };
32455
- case "include-access-changed": return state.includeAccess === action.value ? state : {
32456
- ...state,
32457
- includeAccess: action.value
32458
- };
32459
- case "export-started": return state.exporting ? state : {
32460
- ...state,
32461
- exporting: true
32462
- };
32463
- case "export-finished": return state.exporting ? {
32464
- ...state,
32465
- exporting: false
32466
- } : state;
32467
- default: return assertNever$8(action);
32468
- }
32469
- }
32470
- function backupImportStateReducer(state, action) {
32471
- switch (action.type) {
32472
- case "import-file-cleared": return {
32473
- ...clearBackupImportOutcome(state),
32474
- file: null
32475
- };
32476
- case "import-file-invalid": return {
32477
- ...clearBackupImportOutcome(state),
32478
- file: null,
32479
- fileError: action.message
32480
- };
32481
- case "import-file-selected": return {
32482
- ...clearBackupImportOutcome(state),
32483
- file: action.file
32484
- };
32485
- case "import-failed": return {
32486
- ...clearBackupImportOutcome(state),
32487
- feedback: errorFeedback$1(action.message)
32488
- };
32489
- case "import-validation-errors-received": return {
32490
- ...clearBackupImportOutcome(state),
32491
- fieldErrors: action.errors
32492
- };
32493
- case "import-succeeded": return {
32494
- ...clearBackupImportOutcome(state),
32495
- feedback: successFeedback$1(action.result)
32496
- };
32497
- case "clean-import-changed":
32498
- case "dry-run-changed":
32499
- case "membership-mode-changed":
32500
- case "api-key-mode-changed":
32501
- case "send-emails-changed": {
32502
- const options = backupImportOptionsReducer(state.options, action);
32503
- return options === state.options ? state : {
32504
- ...state,
32505
- options
32506
- };
32507
- }
32508
- case "clean-confirm-opened": return state.cleanConfirmOpen ? state : {
32509
- ...state,
32510
- cleanConfirmOpen: true
32511
- };
32512
- case "clean-confirm-closed": return state.cleanConfirmOpen ? {
32513
- ...state,
32514
- cleanConfirmOpen: false
32515
- } : state;
32516
- case "import-confirmed": return {
32517
- ...clearBackupImportOutcome(state),
32518
- phase: "uploading",
32519
- cleanConfirmOpen: false
32520
- };
32521
- case "api-import-started": return state.phase === "calling-api" ? state : {
32522
- ...state,
32523
- phase: "calling-api"
32524
- };
32525
- case "import-finished": return state.phase === "idle" ? state : {
32526
- ...state,
32527
- phase: "idle"
32528
- };
32529
- default: return assertNever$8(action);
32530
- }
32531
- }
32532
- function createInitialBackupClientState() {
32533
- return {
32534
- exportState: {
32535
- exporting: false,
32536
- includeMedia: true,
32537
- includeAccess: false
32538
- },
32539
- importState: {
32540
- phase: "idle",
32541
- file: null,
32542
- fileError: null,
32543
- fieldErrors: null,
32544
- feedback: idleFeedback$1(),
32545
- cleanConfirmOpen: false,
32546
- options: {
32547
- cleanImport: false,
32548
- dryRun: false,
32549
- membershipMode: "skip",
32550
- apiKeyMode: "skip",
32551
- sendEmails: true
32552
- }
32553
- }
32554
- };
32555
- }
32556
- function backupClientReducer(state, action) {
32557
- switch (action.type) {
32558
- case "include-media-changed":
32559
- case "include-access-changed":
32560
- case "export-started":
32561
- case "export-finished": {
32562
- const exportState = backupExportStateReducer(state.exportState, action);
32563
- return exportState === state.exportState ? state : {
32564
- ...state,
32565
- exportState
32566
- };
32567
- }
32568
- case "import-file-cleared":
32569
- case "import-file-invalid":
32570
- case "import-file-selected":
32571
- case "import-failed":
32572
- case "import-validation-errors-received":
32573
- case "import-succeeded":
32574
- case "clean-import-changed":
32575
- case "dry-run-changed":
32576
- case "membership-mode-changed":
32577
- case "api-key-mode-changed":
32578
- case "send-emails-changed":
32579
- case "clean-confirm-opened":
32580
- case "clean-confirm-closed":
32581
- case "import-confirmed":
32582
- case "api-import-started":
32583
- case "import-finished": {
32584
- const importState = backupImportStateReducer(state.importState, action);
32585
- return importState === state.importState ? state : {
32586
- ...state,
32587
- importState
32588
- };
32589
- }
32590
- default: return assertNever$8(action);
32591
- }
32592
- }
32593
- function selectBackupExporting(state) {
32594
- return state.exportState.exporting;
32595
- }
32596
- function selectBackupImporting(state) {
32597
- return state.importState.phase !== "idle";
32598
- }
32599
- function selectBackupCleanConfirmOpen(state) {
32600
- return state.importState.cleanConfirmOpen;
32601
- }
32602
- function selectBackupShouldConfirmCleanImport(state) {
32603
- return state.importState.file !== null && state.importState.options.cleanImport && !state.importState.options.dryRun;
32604
- }
32605
- function selectBackupIncludeMedia(state) {
32606
- return state.exportState.includeMedia;
32607
- }
32608
- function selectBackupIncludeAccess(state) {
32609
- return state.exportState.includeAccess;
32610
- }
32611
- function selectBackupImportFile(state) {
32612
- return state.importState.file;
32613
- }
32614
- function selectBackupImportFileError(state) {
32615
- return state.importState.fileError;
32616
- }
32617
- function selectBackupCleanImport(state) {
32618
- return state.importState.options.cleanImport;
32619
- }
32620
- function selectBackupDryRun(state) {
32621
- return state.importState.options.dryRun;
32622
- }
32623
- function selectBackupMembershipMode(state) {
32624
- return state.importState.options.membershipMode;
32625
- }
32626
- function selectBackupApiKeyMode(state) {
32627
- return state.importState.options.apiKeyMode;
32628
- }
32629
- function selectBackupSendEmails(state) {
32630
- return state.importState.options.sendEmails;
32631
- }
32632
- function selectBackupImportResult(state) {
32633
- return state.importState.feedback.tag === "success" ? state.importState.feedback.result : null;
32634
- }
32635
- function selectBackupImportAccess(state) {
32636
- return selectBackupImportResult(state)?.access;
32637
- }
32638
- function selectBackupImportErrorMessage(state) {
32639
- return state.importState.feedback.tag === "error" ? state.importState.feedback.message : null;
32640
- }
32641
- function selectBackupImportFieldErrors(state) {
32642
- return state.importState.fieldErrors ?? EMPTY_FIELD_ERRORS;
32643
- }
32644
- function selectBackupImportSummary(state) {
32645
- return deriveBackupImportSummary(selectBackupImportCountEntries(state));
32646
- }
32647
- function selectBackupImportCountEntries(state) {
32648
- return buildBackupImportCountEntries(selectBackupImportResult(state));
32649
- }
32650
- function assertNever$8(value, message) {
32651
- throw new Error(message ?? `Unexpected value: ${String(value)}`);
32652
- }
32653
- function idleFeedback$1() {
32654
- return { tag: "idle" };
32655
- }
32656
- function errorFeedback$1(message) {
32657
- return {
32658
- tag: "error",
32659
- message
32660
- };
32661
- }
32662
- function successFeedback$1(result) {
32663
- return {
32664
- tag: "success",
32665
- result
32666
- };
32667
- }
32668
32531
  const ADD_CUSTOM_DOMAIN_SUCCESS_MESSAGE = "Custom domain added successfully! Redirecting...";
32669
32532
  const IDLE_FEEDBACK$1 = { tag: "idle" };
32670
32533
  const SUCCESS_FEEDBACK = {
@@ -40968,15 +40831,6 @@ function resolveAutoCtaPath(source, routes) {
40968
40831
  }
40969
40832
  return routeByNormalizedPath.get("/offerings") ?? null;
40970
40833
  }
40971
- function resolveOfferingsPreviewRunPath(run, routes) {
40972
- const routeIds = [run.eventSeriesId, run.eventOfferingId];
40973
- for (const entityId of routeIds) {
40974
- const route = (routes ?? []).find((candidate) => candidate.entityId === entityId);
40975
- const path$3 = normalizeRoutePath(route?.path);
40976
- if (path$3) return path$3;
40977
- }
40978
- return null;
40979
- }
40980
40834
  function preferredPathsForSource(source) {
40981
40835
  switch (source.kind) {
40982
40836
  case "eventPreset": switch (source.preset) {
@@ -41244,6 +41098,11 @@ function resolveEventRegistrationScopedEvents(events, context) {
41244
41098
  //#endregion
41245
41099
  //#region ../blocks/src/system/constants/events.ts
41246
41100
  /**
41101
+ * Event-related constants
41102
+ *
41103
+ * Shared constants for event content types and booking system integration.
41104
+ */
41105
+ /**
41247
41106
  * Content type slugs that represent event content.
41248
41107
  * These are the standard slugs used when creating event content types in the CMS.
41249
41108
  *
@@ -41398,6 +41257,8 @@ function getPreviewContext(contentTypeKey) {
41398
41257
  /** The calendar manifest owns its secondary arrangement axis. */
41399
41258
  const eventCalendarVariantMeaning = {
41400
41259
  kind: "mode",
41260
+ modes: arrangementModes,
41261
+ defaultMode: "list",
41401
41262
  arrangementField: "listLayout",
41402
41263
  keys: eventCalendarListLayoutValues,
41403
41264
  lookOnlyKeys: [
@@ -42451,6 +42312,10 @@ const eventDetailsManifest = createBlockManifest({
42451
42312
  fallback: null
42452
42313
  } },
42453
42314
  events: { $bind: { from: "data.eventDetailsData.events" } },
42315
+ venueDrawing: { $bind: {
42316
+ from: "data.eventDetailsData.venueDrawing",
42317
+ fallback: null
42318
+ } },
42454
42319
  showVenue: { $bind: { from: "content.showVenue" } },
42455
42320
  showTitle: { $bind: { from: "content.showTitle" } },
42456
42321
  showDescription: { $bind: { from: "content.showDescription" } },
@@ -42490,6 +42355,7 @@ const eventDetailsBlockDefinition = {
42490
42355
  dataSchemas: {
42491
42356
  eventDetailsData: z.object({
42492
42357
  events: publicEventsArraySchema,
42358
+ venueDrawing: eventVenueDrawingSchema.optional().catch(undefined),
42493
42359
  sitePasses: publicPassProductCollectionSchema,
42494
42360
  siteMemberships: publicMembershipProductCollectionSchema,
42495
42361
  autoApplyDiscount: eventAutoApplyDiscountPreviewSchema.nullable().optional().default(null)
@@ -44551,14 +44417,23 @@ const partRenderers = {
44551
44417
  ...listLookSlot(presentation, "dates"),
44552
44418
  children: item.dates.map((date, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
44553
44419
  ...listLookSlot(presentation, "date"),
44554
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("time", {
44555
- dateTime: date.startsAt,
44556
- children: date.label
44557
- }), date.places ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
44558
- ...listLookSlot(presentation, "date-places"),
44559
- "data-availability": date.places.status,
44560
- children: date.places.label
44561
- }) : null]
44420
+ children: [
44421
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("time", {
44422
+ dateTime: date.startsAt,
44423
+ children: date.label
44424
+ }),
44425
+ date.places ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
44426
+ ...listLookSlot(presentation, "date-places"),
44427
+ "data-availability": date.places.status,
44428
+ children: date.places.label
44429
+ }) : null,
44430
+ date.booking ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
44431
+ ...date.booking,
44432
+ variant: presentation.buttonVariant ?? "primary",
44433
+ size: "sm",
44434
+ extraClassName: "rb-card-list-date-booking"
44435
+ }) : null
44436
+ ]
44562
44437
  }, `${date.startsAt}-${index}`))
44563
44438
  }) : null,
44564
44439
  availability: ({ item, presentation }) => item.availability ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
@@ -45247,56 +45122,6 @@ function cropHeightStyle(height, heightAs) {
45247
45122
  return heightAs === "minimum" ? { minHeight: height } : { height };
45248
45123
  }
45249
45124
 
45250
- //#endregion
45251
- //#region ../blocks/src/system/runtime/nodes/shared/LocationMapActions.tsx
45252
- /**
45253
- * `compact` (event details, cards and modals) keeps two small ghost buttons;
45254
- * `block` (the map block) leads with a secondary directions button and keeps
45255
- * Google Maps as a plain text link beside it.
45256
- */
45257
- function LocationMapActions(props$1) {
45258
- const links = locationMapLinks(props$1);
45259
- const directionsLabel = props$1.directionsLabel ?? "Get directions";
45260
- const googleMapsLabel = props$1.googleMapsLabel ?? "Open in Google Maps";
45261
- if (props$1.layout === "block") {
45262
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
45263
- className: "rb-location-map-actions",
45264
- children: [links.directions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
45265
- href: links.directions,
45266
- target: "_blank",
45267
- rel: "noreferrer",
45268
- variant: "secondary",
45269
- size: "sm",
45270
- label: directionsLabel
45271
- }) : null, links.googleMaps ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
45272
- className: "rb-location-map-link",
45273
- href: links.googleMaps,
45274
- target: "_blank",
45275
- rel: "noreferrer",
45276
- children: googleMapsLabel
45277
- }) : null]
45278
- });
45279
- }
45280
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
45281
- className: "rb-flex rb-flex-wrap rb-gap-2",
45282
- children: [links.directions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
45283
- href: links.directions,
45284
- target: "_blank",
45285
- rel: "noreferrer",
45286
- variant: "ghost",
45287
- size: "sm",
45288
- label: directionsLabel
45289
- }) : null, links.googleMaps ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
45290
- href: links.googleMaps,
45291
- target: "_blank",
45292
- rel: "noreferrer",
45293
- variant: "ghost",
45294
- size: "sm",
45295
- label: googleMapsLabel
45296
- }) : null]
45297
- });
45298
- }
45299
-
45300
45125
  //#endregion
45301
45126
  //#region ../blocks/src/system/runtime/nodes/events/shared/EventCardIcons.tsx
45302
45127
  function MapPinIcon({ className, size = 16, strokeWidth = 2 }) {
@@ -45533,20 +45358,13 @@ function EventCardVenue(props$1) {
45533
45358
  if (!venue) return null;
45534
45359
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
45535
45360
  className: "rb-mb-3",
45536
- children: [
45537
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
45538
- className: "rb-flex rb-items-center rb-gap-2 rb-caption",
45539
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MapPinIcon, { className: "rb-shrink-0" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: venue.name }), venue.address ? ` · ${venue.address}` : null] })]
45540
- }),
45541
- props$1.allowMap ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LocationMapActions, {
45542
- location: venue.location,
45543
- addressText: venue.address
45544
- }) : null,
45545
- props$1.showMap && props$1.allowMap && venue.location && props$1.mapSlot && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
45546
- className: "rb-mt-2",
45547
- children: props$1.mapSlot
45548
- })
45549
- ]
45361
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
45362
+ className: "rb-flex rb-items-center rb-gap-2 rb-caption",
45363
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MapPinIcon, { className: "rb-shrink-0" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: venue.name }), venue.address ? ` · ${venue.address}` : null] })]
45364
+ }), props$1.showMap && props$1.allowMap && venue.location && props$1.mapSlot && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
45365
+ className: "rb-mt-2",
45366
+ children: props$1.mapSlot
45367
+ })]
45550
45368
  });
45551
45369
  }
45552
45370
  function EventCardFooter(props$1) {
@@ -45835,25 +45653,33 @@ function EventQuickDates({ events, pathname, buttonVariant = "primary", dateStyl
45835
45653
  })]
45836
45654
  });
45837
45655
  }
45838
- /** Decide the formatted date and complete booking link before rendering. */
45839
- function quickDateCardPresentation(props$1) {
45840
- const event = props$1.event;
45841
- const date = formatEventQuickDate(event, props$1.dateStyle);
45656
+ /**
45657
+ * The complete link that books one date, shared by the strip and by date rows.
45658
+ * Null when the date has no registration path (closed, paused, not open yet,
45659
+ * no registration, or full with no waitlist), so no caller repeats that gate.
45660
+ */
45661
+ function eventDateBookingLink(event, pathname, dateLabel$1) {
45662
+ if (!isBookableEvent(event)) return null;
45842
45663
  const cta = resolveEventCta(event);
45843
45664
  const destination = resolveRuntimeEventDestination(event);
45844
- const ctaHref = destination.kind === "external" ? cta.href : resolveDedicatedBookingHref(props$1.pathname, {
45665
+ const href = destination.kind === "external" ? cta.href : resolveDedicatedBookingHref(pathname, {
45845
45666
  kind: "event_occurrence",
45846
45667
  occurrenceId: event.occurrenceId
45847
45668
  });
45669
+ return {
45670
+ href,
45671
+ target: cta.external ? "_blank" : undefined,
45672
+ rel: cta.external ? "noopener noreferrer" : undefined,
45673
+ "aria-label": `${cta.label} ${event.title}, ${dateLabel$1}`,
45674
+ label: cta.label
45675
+ };
45676
+ }
45677
+ /** Decide the formatted date and complete booking link before rendering. */
45678
+ function quickDateCardPresentation(props$1) {
45679
+ const date = formatEventQuickDate(props$1.event, props$1.dateStyle);
45848
45680
  return {
45849
45681
  date,
45850
- bookingLink: {
45851
- href: ctaHref,
45852
- target: cta.external ? "_blank" : undefined,
45853
- rel: cta.external ? "noopener noreferrer" : undefined,
45854
- "aria-label": `${cta.label} ${event.title}, ${date.label}`,
45855
- label: cta.label
45856
- }
45682
+ bookingLink: eventDateBookingLink(props$1.event, props$1.pathname, date.label)
45857
45683
  };
45858
45684
  }
45859
45685
  function EventQuickDateCard(props$1) {
@@ -45889,12 +45715,12 @@ function EventQuickDateCard(props$1) {
45889
45715
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
45890
45716
  className: "event-quick-date-price",
45891
45717
  children: formatEventPrice(event)
45892
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
45718
+ }), bookingLink ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
45893
45719
  variant: props$1.buttonVariant,
45894
45720
  size: "sm",
45895
45721
  extraClassName: "event-quick-date-cta",
45896
45722
  ...bookingLink
45897
- })]
45723
+ }) : null]
45898
45724
  })
45899
45725
  ]
45900
45726
  });
@@ -48799,6 +48625,7 @@ const eventCalendarConfig = {
48799
48625
  icon: "CalendarDays",
48800
48626
  layout: eventCalendarLayout,
48801
48627
  variants: eventCalendarVariants,
48628
+ arrangementOwnedFieldIds: ["defaultCalendarView"],
48802
48629
  variantMeaning: eventCalendarVariantMeaning,
48803
48630
  defaultVariant: "combined",
48804
48631
  variantOptions: {
@@ -49260,6 +49087,16 @@ const offeringsPreviewFields = [
49260
49087
  schema: { fields: groupOverrideFields }
49261
49088
  },
49262
49089
  createButtonVariantField(),
49090
+ {
49091
+ id: "oneOffering",
49092
+ type: "boolean",
49093
+ label: "Show one offering with its dates",
49094
+ required: false,
49095
+ ui: {
49096
+ intent: "display",
49097
+ hidden: true
49098
+ }
49099
+ },
49263
49100
  {
49264
49101
  id: "buttonText",
49265
49102
  type: "text",
@@ -49355,6 +49192,18 @@ function buildOfferingsCatalogueListing(input) {
49355
49192
  now: input.now
49356
49193
  });
49357
49194
  }
49195
+ function offeringsCatalogueShape(listing, cards) {
49196
+ return cards.oneOfferingRequested && cards.listDates && countListedOfferings(listing) === 1 ? "single" : "several";
49197
+ }
49198
+ function countListedOfferings(listing) {
49199
+ switch (listing.kind) {
49200
+ case "no-groups":
49201
+ case "nothing-to-show": return 0;
49202
+ case "by-date": return listing.items.length;
49203
+ case "by-type": return listing.groups.reduce((count, load) => count + (load.kind === "items" ? load.items.length : 0), 0);
49204
+ default: return assertNever(listing);
49205
+ }
49206
+ }
49358
49207
  function matchesGroup(group, event) {
49359
49208
  const source = group.source;
49360
49209
  switch (source.kind) {
@@ -49430,6 +49279,10 @@ const offeringsPreviewLayout = [styledSection({
49430
49279
  carouselRegion: { $bind: { from: "content.heading" } },
49431
49280
  renderInput: { $bind: { from: "content._offeringsPreviewInput" } },
49432
49281
  displayMode: { $bind: displayModeBinding },
49282
+ oneOffering: { $bind: {
49283
+ from: "content.oneOffering",
49284
+ fallback: false
49285
+ } },
49433
49286
  pathname: { $bind: { from: "$root.pathname" } },
49434
49287
  catalogueEvents: { $bind: { from: "data.catalogueEvents" } },
49435
49288
  quickDateEvents: { $bind: { from: "data.quickDateEvents" } },
@@ -49471,6 +49324,7 @@ const offeringsPreviewLayout = [styledSection({
49471
49324
  spacing: "comfortable"
49472
49325
  })];
49473
49326
  const offeringsPreviewConfig = {
49327
+ arrangementOwnedFieldIds: ["groupOverrides.presentation"],
49474
49328
  variantMeaning: {
49475
49329
  kind: "arrangement",
49476
49330
  lookOnlyKeys: [
@@ -49527,6 +49381,7 @@ const offeringsPreviewBlockDefinition = {
49527
49381
  contentNormalizer: {
49528
49382
  fieldIds: [
49529
49383
  "displayMode",
49384
+ "oneOffering",
49530
49385
  "heading",
49531
49386
  "description",
49532
49387
  "itemLimit",
@@ -49628,6 +49483,7 @@ function normalizeOfferingsPreviewBlockContent(value) {
49628
49483
  if (!record) return { displayMode: DEFAULT_OFFERINGS_PREVIEW_DISPLAY_MODE };
49629
49484
  const normalized = {
49630
49485
  displayMode: normalizeOfferingsPreviewDisplayMode(record.displayMode),
49486
+ ...oneOfferingContent(record.oneOffering),
49631
49487
  ...normalizeCardListContent(record)
49632
49488
  };
49633
49489
  if (typeof record.heading === "string" || record.heading === null) {
@@ -49668,6 +49524,9 @@ function normalizeOfferingsPreviewBlockContent(value) {
49668
49524
  }
49669
49525
  return normalized;
49670
49526
  }
49527
+ function oneOfferingContent(value) {
49528
+ return typeof value === "boolean" || value === null ? { oneOffering: value } : {};
49529
+ }
49671
49530
  function normalizeOfferingsPreviewDisplayMode(value) {
49672
49531
  return value === "catalogue" ? "catalogue" : DEFAULT_OFFERINGS_PREVIEW_DISPLAY_MODE;
49673
49532
  }
@@ -52146,7 +52005,7 @@ const shopBlockRuntime = defineProgressiveBlockRuntime({
52146
52005
  buildRender: (source) => {
52147
52006
  const passPurchaseMode = source.passPurchaseMode ?? "add_to_cart";
52148
52007
  const subscribeButtonText = source.subscribeButtonText ?? "Subscribe";
52149
- const products = shopDisplayedProducts(source);
52008
+ const products = decideShopDisplayedCatalogue(source);
52150
52009
  const dateContext = source.dateContext ?? resolveDateRuntimeContext(undefined);
52151
52010
  return {
52152
52011
  display: buildPassesMembershipsDisplay({
@@ -52423,16 +52282,18 @@ function shopCardListPresentation(source) {
52423
52282
  [key]: source[key]
52424
52283
  }), {});
52425
52284
  }
52426
- function shopDisplayedProducts(source) {
52285
+ function decideShopDisplayedCatalogue(source) {
52286
+ const passes = source.showPasses === false ? [] : source.passes ?? [];
52287
+ const memberships = source.showMemberships === false ? [] : source.memberships ?? [];
52288
+ const featured = [...passes, ...memberships].some(({ id }) => id === source.featured) ? source.featured ?? null : null;
52427
52289
  return {
52428
- passes: source.showPasses === false ? [] : source.passes ?? [],
52429
- memberships: source.showMemberships === false ? [] : source.memberships ?? []
52290
+ passes,
52291
+ memberships,
52292
+ featured
52430
52293
  };
52431
52294
  }
52432
52295
  function shopFeaturedProduct(source, products) {
52433
- const selectedId = source.featured;
52434
- const visible = [...products.passes, ...products.memberships].some(({ id }) => id === selectedId);
52435
- return source.lookSlots && source.itemRoles?.featured && selectedId && visible ? { featured: selectedId } : {};
52296
+ return source.lookSlots && source.itemRoles?.featured && products.featured !== null ? { featured: products.featured } : {};
52436
52297
  }
52437
52298
  /** Server and hydrated cards share the same decided role and featured marker. */
52438
52299
  function shopProductPresentation(hydration, productId, index, count) {
@@ -52463,6 +52324,7 @@ function shopProductPresentation(hydration, productId, index, count) {
52463
52324
  * - Stripe handles payment security
52464
52325
  */
52465
52326
  const shopManifest = createBlockManifest({
52327
+ arrangementOwnedFieldIds: ["layout", "columns"],
52466
52328
  variantMeaning: {
52467
52329
  kind: "arrangement",
52468
52330
  lookOnlyKeys: [
@@ -54152,6 +54014,18 @@ const wrapVariant = (variantLayout) => styledSection({
54152
54014
  baseClass: "",
54153
54015
  spacing: "comfortable"
54154
54016
  });
54017
+ const cardBiographyFallbackNode = richText({ className: "rb-prose rb-max-w-none" }, when("content.cardBiography", { equals: "any" }), bind(ITEM_NAME, { transforms: [{ id: "teamMember.cardBiographyFallback" }] }));
54018
+ const teamMemberGridLayout = withCardBiographyFallback(teamMemberFragment.layout);
54019
+ function withCardBiographyFallback(layout) {
54020
+ const roots = Array.isArray(layout) ? layout : [layout];
54021
+ const [card] = roots;
54022
+ if (!card || roots.length !== 1) throw new Error("teamMember fragment must have one root node");
54023
+ const children = card.children ?? [];
54024
+ return {
54025
+ ...card,
54026
+ children: [...children, cardBiographyFallbackNode]
54027
+ };
54028
+ }
54155
54029
  const teamMemberStackLayout = el("div", { className: "rb-team-member rb-team-member--stack rb-flex rb-flex-col rb-md-flex-row rb-items-start rb-gap-3" }, [el("div", { className: "rb-team-member-photo-col rb-w-full rb-shrink-0" }, [el("div", { className: memberPhotoClassName("rb-team-member-photo-wrap rb-w-full") }, [media({
54156
54030
  className: "rb-team-member-photo rb-w-full rb-object-cover",
54157
54031
  style: { aspectRatio: "1 / 1" },
@@ -54174,12 +54048,42 @@ const teamMemberStackLayout = el("div", { className: "rb-team-member rb-team-mem
54174
54048
  as: "p",
54175
54049
  className: "rb-team-member-role"
54176
54050
  }, when("role"), bind("role")),
54177
- richText({ className: "rb-prose rb-max-w-none" }, when("bio"), bind("bio"))
54051
+ richText({ className: "rb-prose rb-max-w-none" }, when("bio"), bind("bio")),
54052
+ cardBiographyFallbackNode
54178
54053
  ])]);
54054
+ const onePersonAboutWhen = { equals: "about" };
54055
+ const notOnePersonAboutWhen = {
54056
+ equals: "about",
54057
+ not: true
54058
+ };
54059
+ const aboutVariant = styledSection({
54060
+ children: sectionContainer([el("div", {
54061
+ className: "rb-team-layout",
54062
+ "data-one-person": "about"
54063
+ }, [el("div", { className: "rb-team-head" }, [headingNode], when("content.heading")), el("team-members", {
54064
+ onePerson: { $bind: { from: "content.onePerson" } },
54065
+ source: { $bind: {
54066
+ from: "content.source",
54067
+ fallback: "manual"
54068
+ } },
54069
+ members: { $bind: {
54070
+ from: "content.members",
54071
+ fallback: []
54072
+ } },
54073
+ siteMembers: { $bind: {
54074
+ from: "data.members",
54075
+ fallback: []
54076
+ } },
54077
+ sectionHeading: { $bind: { from: "content.heading" } }
54078
+ })])], { gap: "md" }),
54079
+ baseClass: "",
54080
+ spacing: "comfortable"
54081
+ });
54179
54082
  const manualGridMembersNode = when("content.source", manualSourceWhen)(repeaterFragmentLayout({
54180
54083
  collectionPath: "content.members",
54181
54084
  itemName: ITEM_NAME,
54182
54085
  fragments: { teamMember: teamMemberFragment },
54086
+ layoutOverrides: { teamMember: teamMemberGridLayout },
54183
54087
  itemGap: "sm",
54184
54088
  itemClassName: memberCardClassName
54185
54089
  }));
@@ -54187,6 +54091,7 @@ const dynamicGridMembersNode = when("content.source", dynamicSourceWhen)(repeate
54187
54091
  collectionPath: "data.members",
54188
54092
  itemName: ITEM_NAME,
54189
54093
  fragments: { teamMember: teamMemberFragment },
54094
+ layoutOverrides: { teamMember: teamMemberGridLayout },
54190
54095
  itemGap: "sm",
54191
54096
  itemClassName: memberCardClassName
54192
54097
  }));
@@ -54222,14 +54127,23 @@ const stackVariant = wrapVariant({
54222
54127
  children: [manualStackMembersNode, dynamicStackMembersNode]
54223
54128
  });
54224
54129
  const cardListVariant = styledSection({
54225
- children: sectionContainer([el("div", { ...lookSlot("layout") }, [
54226
- el("div", { ...lookSlot("head") }, [text({
54130
+ children: sectionContainer([el("div", {
54131
+ className: "rb-team-layout",
54132
+ ...lookSlot("layout"),
54133
+ "data-one-person": { $bind: { from: "content.onePerson" } }
54134
+ }, [
54135
+ el("div", {
54136
+ className: "rb-team-head",
54137
+ ...lookSlot("head")
54138
+ }, [text({
54227
54139
  as: "h2",
54228
54140
  ...lookSlot("heading")
54229
54141
  }, bind("content.heading"), when("content.heading"))], when("content.heading")),
54230
54142
  el("team-members", {
54231
54143
  ...cardListPresentationBindings,
54232
54144
  biographySource: { $bind: { from: "content._effectiveLook.look.structure.teamBiography" } },
54145
+ onePerson: { $bind: { from: "content.onePerson" } },
54146
+ cardBiography: { $bind: { from: "content.cardBiography" } },
54233
54147
  source: { $bind: {
54234
54148
  from: "content.source",
54235
54149
  fallback: "manual"
@@ -54303,6 +54217,37 @@ const teamMembersManifest = createBlockManifest({
54303
54217
  }],
54304
54218
  ui: { intent: "behavior" }
54305
54219
  }),
54220
+ parseFieldDefinition({
54221
+ id: "onePerson",
54222
+ type: "select",
54223
+ label: "One person",
54224
+ required: false,
54225
+ options: [{
54226
+ value: "about",
54227
+ label: "The section is about them, with their bio"
54228
+ }, {
54229
+ value: "portrait",
54230
+ label: "One small portrait"
54231
+ }],
54232
+ ui: {
54233
+ intent: "display",
54234
+ hidden: true
54235
+ }
54236
+ }),
54237
+ parseFieldDefinition({
54238
+ id: "cardBiography",
54239
+ type: "select",
54240
+ label: "Card bio",
54241
+ required: false,
54242
+ options: [{
54243
+ value: "any",
54244
+ label: "Whichever bio the person has"
54245
+ }],
54246
+ ui: {
54247
+ intent: "display",
54248
+ hidden: true
54249
+ }
54250
+ }),
54306
54251
  parseFieldDefinition({
54307
54252
  id: "layoutAlign",
54308
54253
  type: "select",
@@ -54448,10 +54393,19 @@ const teamMembersManifest = createBlockManifest({
54448
54393
  ],
54449
54394
  layout: gridVariant,
54450
54395
  variants: {
54451
- grid: gridVariant,
54396
+ grid: [when("content.onePerson", notOnePersonAboutWhen)(gridVariant), when("content.onePerson", onePersonAboutWhen)(aboutVariant)],
54452
54397
  stack: [when("content._effectiveLook", { not: true })(stackVariant), when("content._effectiveLook")(cardListVariant)],
54453
54398
  ...Object.fromEntries(arrangementOnlyKeys.map((key) => [key, cardListVariant]))
54454
54399
  },
54400
+ arrangementOwnedFieldIds: [
54401
+ "layoutWidth",
54402
+ "thumbnailShape",
54403
+ "thumbnailPadding",
54404
+ "imageColSize",
54405
+ "stackImagePosition",
54406
+ "stackContentAlignment",
54407
+ "gap"
54408
+ ],
54455
54409
  variantMeaning: {
54456
54410
  kind: "arrangement",
54457
54411
  lookOnlyKeys: [...arrangementOnlyKeys]
@@ -55874,6 +55828,58 @@ function clearBlockDefinitions() {
55874
55828
  resetSystemBlockDefinitionRegistration();
55875
55829
  }
55876
55830
 
55831
+ //#endregion
55832
+ //#region ../blocks/src/system/manifest/storedLayout.ts
55833
+ /** The content field `parseStoredVariant` also reads; a block without stored variants keeps its layout there. */
55834
+ const layoutFieldId = "layout";
55835
+ function storedVariantKeys(manifest) {
55836
+ const lookOnly = manifest.variantMeaning.lookOnlyKeys ?? [];
55837
+ return Object.keys(manifest.variants ?? {}).filter((key) => !lookOnly.includes(key));
55838
+ }
55839
+ function optionValues(options) {
55840
+ return Array.isArray(options) ? options.flatMap((option) => typeof option === "object" && option !== null && "value" in option && typeof option.value === "string" ? [option.value] : []) : [];
55841
+ }
55842
+ /**
55843
+ * A block with no stored variants that offers a `layout` select (the shop)
55844
+ * declares its layouts there. Read as a mode's arrangement declaration, so the
55845
+ * same resolver decides: a stored value the block still has, or the default.
55846
+ */
55847
+ function layoutFieldDeclaration(manifest) {
55848
+ const field = (manifest.fields ?? []).find((candidate) => typeof candidate === "object" && candidate !== null && "id" in candidate && candidate.id === layoutFieldId && "type" in candidate && candidate.type === "select");
55849
+ const keys = optionValues(field?.options);
55850
+ const [firstKey] = keys;
55851
+ if (field === undefined || firstKey === undefined) return null;
55852
+ return {
55853
+ arrangementField: layoutFieldId,
55854
+ keys,
55855
+ defaultKey: typeof field.defaultValue === "string" && keys.includes(field.defaultValue) ? field.defaultValue : firstKey
55856
+ };
55857
+ }
55858
+ function fieldDeclaration(manifest) {
55859
+ if (manifest.variantMeaning.kind === "mode") return manifest.variantMeaning;
55860
+ return storedVariantKeys(manifest).length === 0 ? layoutFieldDeclaration(manifest) : null;
55861
+ }
55862
+ /** Every layout a block can store, for the block's own layout axis. Look-only arrangements are never stored. */
55863
+ function storedLayoutKeys(manifest) {
55864
+ return fieldDeclaration(manifest)?.keys ?? storedVariantKeys(manifest);
55865
+ }
55866
+ /**
55867
+ * The layout a block renders by when no Look arranges it: the stored value if
55868
+ * the block still has it, otherwise the default. The renderer's own resolvers
55869
+ * decide, so a reader of stored layouts cannot disagree with the page.
55870
+ */
55871
+ function resolveStoredLayout(manifest, content) {
55872
+ const field = fieldDeclaration(manifest);
55873
+ return field === null ? resolveEffectiveArrangement({
55874
+ manifest: arrangementManifestFromVariants(manifest),
55875
+ storedVariant: parseStoredVariant(manifest, content)
55876
+ }).key : resolveModeArrangement({
55877
+ declaration: field,
55878
+ content,
55879
+ mode: null
55880
+ }).key;
55881
+ }
55882
+
55877
55883
  //#endregion
55878
55884
  //#region ../blocks/src/system/data/selectBlockContent.ts
55879
55885
  /** Canonical admitted content: legacy publishedContent never selects a version. */
@@ -56056,7 +56062,7 @@ function toEditorPresentationPage(page) {
56056
56062
  */
56057
56063
  function resolveArrangementKnobs(input) {
56058
56064
  const length = input.blockKind === "block.hero" ? resolveHeroTitleLength({ ...input.content }, "look") : null;
56059
- const exposure = arrangementKnobExposure(input.blockKind, input.look, length);
56065
+ const exposure = arrangementKnobExposure(input.blockKind, input.look, length, storedSplitPhotoSide(input.blockKind, input.content));
56060
56066
  const knobs = resolveEffectiveKnobs({
56061
56067
  exposure,
56062
56068
  content: normalizedHeadlinePreference(input.content)
@@ -56071,15 +56077,16 @@ function resolveArrangementKnobs(input) {
56071
56077
  function arrangementKnobChoices(exposure) {
56072
56078
  return exposure.definition.values.filter((value) => (exposure.lookValues?.includes(value) ?? true) && (exposure.styleValues?.includes(value) ?? true));
56073
56079
  }
56074
- function arrangementKnobExposure(blockKind, look, length) {
56080
+ function arrangementKnobExposure(blockKind, look, length, splitPhotoSide) {
56075
56081
  return systemCustomizeFacetDefinitionsForBlock(blockKind).flatMap((facet) => {
56076
56082
  if (facet.knob === undefined || facet.target.kind !== "content-field") return [];
56077
56083
  const id = facet.target.field;
56078
56084
  const defaults = look.look.structure.knobDefaults ?? {};
56085
+ const storedDefault = id === "imagePosition" ? splitPhotoSide : null;
56079
56086
  return [{
56080
56087
  definition: {
56081
56088
  id,
56082
- defaultValue: defaults[id] ?? facet.defaultValue,
56089
+ defaultValue: defaults[id] ?? storedDefault ?? facet.defaultValue,
56083
56090
  values: facet.values.map((value) => value.value),
56084
56091
  ...knobKindMetadata(facet.knob)
56085
56092
  },
@@ -56091,6 +56098,19 @@ function arrangementKnobExposure(blockKind, look, length) {
56091
56098
  }];
56092
56099
  });
56093
56100
  }
56101
+ /**
56102
+ * A hero stored as "Split, photo on the left" or "Split, photo on the right"
56103
+ * already says which side its photo is on. Under a Look that side is the Photo
56104
+ * side default, so the photo stays where it was until the owner picks a side.
56105
+ */
56106
+ function storedSplitPhotoSide(blockKind, content) {
56107
+ if (blockKind !== "block.hero") return null;
56108
+ switch (content.variant) {
56109
+ case "split": return "left";
56110
+ case "splitReverse": return "right";
56111
+ default: return null;
56112
+ }
56113
+ }
56094
56114
  function knobKindMetadata(knob) {
56095
56115
  return knob.kind === "fixed" ? { ordered: knob.ordered } : {
56096
56116
  ordered: false,
@@ -57894,6 +57914,45 @@ function renderMark(mark, key, child) {
57894
57914
  }
57895
57915
  }
57896
57916
 
57917
+ //#endregion
57918
+ //#region ../blocks/src/system/runtime/nodes/shared/LocationMapActions.tsx
57919
+ /**
57920
+ * `compact` (event details) is one plain Google Maps text link under the venue;
57921
+ * `block` (the map block) leads with a secondary directions button and keeps
57922
+ * the same Google Maps text link beside it.
57923
+ */
57924
+ function LocationMapActions(props$1) {
57925
+ const links = locationMapLinks(props$1);
57926
+ const directionsLabel = props$1.directionsLabel ?? "Get directions";
57927
+ const googleMapsLabel = props$1.googleMapsLabel ?? "Open in Google Maps";
57928
+ if (props$1.layout === "block") {
57929
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
57930
+ className: "rb-location-map-actions",
57931
+ children: [links.directions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemedButtonLink, {
57932
+ href: links.directions,
57933
+ target: "_blank",
57934
+ rel: "noreferrer",
57935
+ variant: "secondary",
57936
+ size: "sm",
57937
+ label: directionsLabel
57938
+ }) : null, links.googleMaps ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
57939
+ className: "rb-location-map-link",
57940
+ href: links.googleMaps,
57941
+ target: "_blank",
57942
+ rel: "noreferrer",
57943
+ children: googleMapsLabel
57944
+ }) : null]
57945
+ });
57946
+ }
57947
+ return links.googleMaps ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
57948
+ className: "rb-location-map-link",
57949
+ href: links.googleMaps,
57950
+ target: "_blank",
57951
+ rel: "noreferrer",
57952
+ children: googleMapsLabel
57953
+ }) }) : null;
57954
+ }
57955
+
57897
57956
  //#endregion
57898
57957
  //#region ../blocks/src/system/runtime/nodes/location-map.view.tsx
57899
57958
  function OpeningHoursTable({ hours: hours$1, lookLayout }) {
@@ -59059,6 +59118,15 @@ const publicAppointmentServicesSchema = z.union([z.array(publicAppointmentServic
59059
59118
  services: z.array(publicAppointmentServiceSchema),
59060
59119
  categories: z.array(publicServiceCategorySchema)
59061
59120
  })]);
59121
+ /**
59122
+ * How many services the loader's data lists, or null when the data isn't the
59123
+ * catalogue at all (a failed load). For composers deciding whether the block
59124
+ * has anything to show, so they read the data the way the block does.
59125
+ */
59126
+ function countPublicAppointmentServices(value) {
59127
+ const result = publicAppointmentServicesSchema.safeParse(value);
59128
+ return result.success ? result.data.services.length : null;
59129
+ }
59062
59130
  const EMPTY_MESSAGE = "No appointments are available right now.";
59063
59131
  const ERROR_MESSAGE = "Appointments are temporarily unavailable. Please try again shortly.";
59064
59132
  const OTHER_GROUP_KEY = "other";
@@ -59407,16 +59475,6 @@ function appointmentServicesListing(view, arrangement) {
59407
59475
  } : view;
59408
59476
  }
59409
59477
 
59410
- //#endregion
59411
- //#region ../blocks/src/system/blocks/shared/teamMembers.ts
59412
- const teamMemberSpecialtiesInputSchema = z.union([z.string(), z.array(z.string())]).nullish();
59413
- function parseTeamMemberSpecialties(value) {
59414
- const parsed = teamMemberSpecialtiesInputSchema.safeParse(value);
59415
- if (!parsed.success) return [];
59416
- const parts = typeof parsed.data === "string" ? parsed.data.split(/\r?\n|,/) : parsed.data ?? [];
59417
- return [...new Set(parts.map((part) => part.trim()).filter(Boolean))];
59418
- }
59419
-
59420
59478
  //#endregion
59421
59479
  //#region ../blocks/src/system/runtime/nodes/team-members.tsx
59422
59480
  const teamMemberCardSchema = z.object({
@@ -59426,12 +59484,13 @@ const teamMemberCardSchema = z.object({
59426
59484
  bio: z.union([z.string(), RichTextDocSchema]).nullish(),
59427
59485
  profileBio: RichTextDocSchema.nullish(),
59428
59486
  photo: runtimeMediaSchema.refine((value) => value.type === "image").nullish(),
59487
+ summary: z.string().nullish(),
59429
59488
  profilePath: z.string().nullish(),
59430
59489
  specialties: z.unknown().transform(parseTeamMemberSpecialties)
59431
59490
  });
59432
59491
  /** Staff and manual members meet at one boundary; Look data chooses biography length. */
59433
- function teamMemberCardContent(member, index, biographySource) {
59434
- const biography = biographySource === "profile" && member.profileBio ? member.profileBio : member.bio;
59492
+ function teamMemberCardContent(member, index, biographySource, cardBiography) {
59493
+ const biography = cardBiography === "any" ? cardText(teamMemberCardBiography(member)) : biographySource === "profile" && member.profileBio ? member.profileBio : member.bio;
59435
59494
  const href = sanitizeHref(member.profilePath);
59436
59495
  return {
59437
59496
  id: member.id ?? `member-${index}`,
@@ -59449,12 +59508,84 @@ function teamMemberCardContent(member, index, biographySource) {
59449
59508
  } } : {}
59450
59509
  };
59451
59510
  }
59511
+ function cardText(biography) {
59512
+ if (!biography) return null;
59513
+ return biography.kind === "document" ? biography.document : biography.paragraphs.join("\n\n");
59514
+ }
59515
+ /**
59516
+ * The quiet line under an "About" heading: the person's name and role. The
59517
+ * name is left out when the heading already says it, so it isn't read twice.
59518
+ */
59519
+ function teamMemberAboutLine(input) {
59520
+ const name = input.name.trim();
59521
+ const said = name.length > 0 && (input.heading ?? "").toLocaleLowerCase().includes(name.toLocaleLowerCase());
59522
+ const parts = [said ? "" : name, input.role?.trim() ?? ""].filter(Boolean);
59523
+ return parts.length > 0 ? parts.join(", ") : null;
59524
+ }
59525
+ /** The one person a section can be about: the list's only member, with a bio to read. */
59526
+ function personToWriteAbout(members) {
59527
+ const [member, ...others] = members;
59528
+ const biography = member && others.length === 0 ? teamMemberBiography(member) : null;
59529
+ return member && biography ? {
59530
+ member,
59531
+ biography
59532
+ } : null;
59533
+ }
59534
+ /**
59535
+ * One person given the section: their photo in the look's frame, a name and
59536
+ * role line, and their bio in full. The section's heading stays where the
59537
+ * block puts it; the stylesheet sets it beside the photo.
59538
+ */
59539
+ function TeamMemberAbout({ member, biography, props: props$1 }) {
59540
+ const line = teamMemberAboutLine({
59541
+ heading: props$1.sectionHeading,
59542
+ name: member.name,
59543
+ role: member.role
59544
+ });
59545
+ const photo = props$1.showPhotos === false ? null : member.photo;
59546
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
59547
+ className: "rb-team-about",
59548
+ "data-team-about": true,
59549
+ "data-has-photo": String(Boolean(photo)),
59550
+ children: [
59551
+ photo ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
59552
+ className: "rb-team-about-photo",
59553
+ ...listLookSlot(props$1, "item-media"),
59554
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MediaNodeServer, {
59555
+ value: photo,
59556
+ size: ImagePresets.hero,
59557
+ ...listLookSlot(props$1, "photo")
59558
+ })
59559
+ }) : null,
59560
+ line ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
59561
+ className: "rb-team-about-line",
59562
+ ...listLookSlot(props$1, "item-meta"),
59563
+ children: line
59564
+ }) : null,
59565
+ biography.kind === "document" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RichText, {
59566
+ doc: biography.document,
59567
+ className: "rb-team-about-bio",
59568
+ ...listLookSlot(props$1, "item-text"),
59569
+ lookSlots: props$1.lookSlots
59570
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
59571
+ className: "rb-team-about-bio",
59572
+ ...listLookSlot(props$1, "item-text"),
59573
+ children: biography.paragraphs.map((paragraph, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: paragraph }, index))
59574
+ })
59575
+ ]
59576
+ });
59577
+ }
59452
59578
  function TeamMembersNode(props$1) {
59453
59579
  const parsed = z.array(teamMemberCardSchema).safeParse(props$1.source === "site_staff" ? props$1.siteMembers : props$1.members);
59454
59580
  if (!parsed.success) return null;
59581
+ const about = props$1.onePerson === "about" ? personToWriteAbout(parsed.data) : null;
59582
+ if (about) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TeamMemberAbout, {
59583
+ ...about,
59584
+ props: props$1
59585
+ });
59455
59586
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CardListItems, {
59456
59587
  Carousel: props$1.Carousel,
59457
- items: parsed.data.map((member, index) => teamMemberCardContent(member, index, props$1.biographySource)),
59588
+ items: parsed.data.map((member, index) => teamMemberCardContent(member, index, props$1.biographySource, props$1.cardBiography)),
59458
59589
  presentation: {
59459
59590
  ...props$1,
59460
59591
  bodyParts: [
@@ -59585,77 +59716,68 @@ function getBookingRedirectStateFromLocation(location) {
59585
59716
  return { kind: "none" };
59586
59717
  }
59587
59718
  function resolveAppointmentCheckoutVerificationState(input) {
59588
- if (!input.config) {
59589
- return { tag: "idle" };
59719
+ if (!input.config) return { tag: "idle" };
59720
+ const sessionId = input.config.sessionId;
59721
+ if (input.pollingStatus === "completed") {
59722
+ const confirmed = confirmedAppointmentCheckout(sessionId, input.result);
59723
+ if (confirmed) return confirmed;
59590
59724
  }
59591
59725
  const appointmentId = input.result?.appointmentId ?? null;
59592
- const paymentStatus = input.result?.paymentStatus ?? null;
59593
- const appointmentStatus = input.result?.appointmentStatus ?? null;
59594
- if (input.pollingStatus === "completed" && appointmentId && (paymentStatus === "completed" || paymentStatus === "not_required")) {
59595
- return {
59596
- tag: "confirmed",
59597
- sessionId: input.config.sessionId,
59598
- appointmentId,
59599
- resourceName: input.result?.resourceName ?? null,
59600
- paymentStatus
59601
- };
59602
- }
59603
- if (input.pollingStatus === "timeout") {
59604
- return {
59726
+ switch (input.pollingStatus) {
59727
+ case "timeout": return {
59605
59728
  tag: "timeout",
59606
- sessionId: input.config.sessionId,
59729
+ sessionId,
59607
59730
  appointmentId,
59608
59731
  message: checkoutCopy.checkoutStillConfirming
59609
59732
  };
59610
- }
59611
- if (input.pollingStatus === "failed") {
59612
- if (paymentStatus === "refunded") {
59613
- return {
59614
- tag: "failed",
59615
- sessionId: input.config.sessionId,
59616
- reason: "payment_refunded",
59617
- message: "Payment was refunded. Please contact support.",
59618
- appointmentId
59619
- };
59620
- }
59621
- if (paymentStatus === "cancelled") {
59622
- return {
59623
- tag: "failed",
59624
- sessionId: input.config.sessionId,
59625
- reason: "checkout_cancelled",
59626
- message: "Checkout was cancelled before the appointment could be confirmed.",
59627
- appointmentId
59628
- };
59629
- }
59630
- if (appointmentStatus === "cancelled") {
59631
- return {
59632
- tag: "failed",
59633
- sessionId: input.config.sessionId,
59634
- reason: "appointment_cancelled",
59635
- message: "The appointment was cancelled before it could be confirmed.",
59636
- appointmentId
59637
- };
59638
- }
59639
- if (paymentStatus === "failed") {
59640
- return {
59641
- tag: "failed",
59642
- sessionId: input.config.sessionId,
59643
- reason: "payment_failed",
59644
- message: "Payment could not be verified. Please try again.",
59645
- appointmentId
59646
- };
59647
- }
59648
- return {
59733
+ case "failed": return {
59649
59734
  tag: "failed",
59650
- sessionId: input.config.sessionId,
59651
- reason: "unknown",
59652
- message: input.error?.message ?? "Payment could not be verified. Please try again.",
59653
- appointmentId
59735
+ sessionId,
59736
+ appointmentId,
59737
+ ...appointmentCheckoutFailure(input.result, input.error)
59738
+ };
59739
+ case "completed":
59740
+ case "idle":
59741
+ case "polling": return {
59742
+ tag: "verifying",
59743
+ sessionId
59654
59744
  };
59655
59745
  }
59746
+ }
59747
+ /** Verified payment carries its booked facts instead of asking the view to rebuild them. */
59748
+ function confirmedAppointmentCheckout(sessionId, result) {
59749
+ if (!result || !result.appointmentId) return null;
59750
+ if (result.paymentStatus !== "completed" && result.paymentStatus !== "not_required") return null;
59656
59751
  return {
59657
- tag: "verifying",
59658
- sessionId: input.config.sessionId
59752
+ tag: "confirmed",
59753
+ sessionId,
59754
+ appointmentId: result.appointmentId,
59755
+ appointment: result.appointment,
59756
+ resourceName: result.resourceName,
59757
+ paymentStatus: result.paymentStatus
59758
+ };
59759
+ }
59760
+ /** Failure priority is shared by every polling failure, including missing provider evidence. */
59761
+ function appointmentCheckoutFailure(result, error$1) {
59762
+ if (result?.paymentStatus === "refunded") return {
59763
+ reason: "payment_refunded",
59764
+ message: "Payment was refunded. Please contact support."
59765
+ };
59766
+ if (result?.paymentStatus === "cancelled") return {
59767
+ reason: "checkout_cancelled",
59768
+ message: "Checkout was cancelled before the appointment could be confirmed."
59769
+ };
59770
+ if (result?.appointmentStatus === "cancelled") return {
59771
+ reason: "appointment_cancelled",
59772
+ message: "The appointment was cancelled before it could be confirmed."
59773
+ };
59774
+ if (result?.paymentStatus === "failed") return {
59775
+ reason: "payment_failed",
59776
+ message: "Payment could not be verified. Please try again."
59777
+ };
59778
+ return {
59779
+ reason: "unknown",
59780
+ message: error$1?.message ?? "Payment could not be verified. Please try again."
59659
59781
  };
59660
59782
  }
59661
59783
  function deriveBookingFormViewState(input) {
@@ -60733,12 +60855,6 @@ function parseLimit$1(value, fallback) {
60733
60855
  const n$1 = typeof value === "string" ? parseInt(value, 10) : typeof value === "number" ? value : NaN;
60734
60856
  return Number.isFinite(n$1) && n$1 > 0 ? n$1 : fallback;
60735
60857
  }
60736
- function isFutureOrNow(iso, nowIso) {
60737
- const ts = Date.parse(iso);
60738
- const now = Date.parse(nowIso);
60739
- if (!Number.isFinite(ts) || !Number.isFinite(now)) return false;
60740
- return ts >= now;
60741
- }
60742
60858
  function uniqByOccurrenceId(events) {
60743
60859
  const seen = new Set();
60744
60860
  const out = [];
@@ -60750,45 +60866,6 @@ function uniqByOccurrenceId(events) {
60750
60866
  }
60751
60867
  return out;
60752
60868
  }
60753
- function selectFromOccurrenceContext(events, occurrenceContext) {
60754
- if (!occurrenceContext) return null;
60755
- const byId = events.find((event) => event.occurrenceId === occurrenceContext.id || event.id === occurrenceContext.id);
60756
- if (byId) return byId;
60757
- const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
60758
- startsAt: occurrenceContext.startsAt,
60759
- timeZone: occurrenceContext.timeZone
60760
- }));
60761
- return events.find((event) => getBookingLocalDateKey(toScheduledBookingDateTime({
60762
- startsAt: event.startsAt,
60763
- timeZone: event.timeZone
60764
- })) === contextDate) ?? null;
60765
- }
60766
- function selectNextUpcoming(events, nowIso) {
60767
- return [...events].filter((event) => isFutureOrNow(event.startsAt, nowIso)).sort((left, right) => Date.parse(left.startsAt) - Date.parse(right.startsAt))[0] ?? null;
60768
- }
60769
- function selectCompletedWholeSeries(events) {
60770
- if (events.length === 0 || !events.every((event) => event.bookingScope === "whole_series")) {
60771
- return null;
60772
- }
60773
- return [...events].sort((left, right) => Date.parse(right.startsAt) - Date.parse(left.startsAt))[0] ?? null;
60774
- }
60775
- function selectEventCandidate(events, occurrenceContext, nowIso) {
60776
- const selected = selectFromOccurrenceContext(events, occurrenceContext);
60777
- if (selected) return {
60778
- event: selected,
60779
- mode: "selected"
60780
- };
60781
- const upcoming = selectNextUpcoming(events, nowIso);
60782
- if (upcoming) return {
60783
- event: upcoming,
60784
- mode: "next"
60785
- };
60786
- const completed = selectCompletedWholeSeries(events);
60787
- return completed ? {
60788
- event: completed,
60789
- mode: "completed"
60790
- } : null;
60791
- }
60792
60869
  function isWholeSeriesEvent(event) {
60793
60870
  return event.bookingScope === "whole_series";
60794
60871
  }
@@ -60823,7 +60900,7 @@ function selectEventDetails(args) {
60823
60900
  const all = uniqByOccurrenceId(scopedEvents);
60824
60901
  const occurrenceContext = args.occurrenceContext ?? null;
60825
60902
  const otherLimit = parseLimit$1(args.otherDatesLimit, 5);
60826
- const candidate = selectEventCandidate(all, occurrenceContext, args.nowIso);
60903
+ const candidate = selectEventDetailsCandidate(all, occurrenceContext, args.nowIso);
60827
60904
  const rawTz = candidate?.event.timeZone ?? all[0]?.timeZone ?? null;
60828
60905
  const timeZone = toBookingTimeZone(rawTz);
60829
60906
  if (!candidate) return emptySelection(timeZone);
@@ -60890,6 +60967,10 @@ function resolveEligibility(input, selected) {
60890
60967
  applicableMemberships: filterMembershipsForEvent(input.siteMemberships?.memberships ?? null, selected)
60891
60968
  };
60892
60969
  }
60970
+ /** The response's one drawing belongs to the selected event only when it is for that event's venue. */
60971
+ function resolveSelectedVenueDrawing(venueDrawing, selected) {
60972
+ return venueDrawing && selected?.venue?.id === venueDrawing.venueId ? venueDrawing.drawing : null;
60973
+ }
60893
60974
  function resolveEventDetailsPresentation(input) {
60894
60975
  const selection = resolveSelection(input);
60895
60976
  const selected = selection.kind === "empty" ? null : selection.selected;
@@ -60903,7 +60984,8 @@ function resolveEventDetailsPresentation(input) {
60903
60984
  panelHeading: input.panelHeading,
60904
60985
  ...resolveDisplaySettings(input),
60905
60986
  ...resolveEligibility(input, selected),
60906
- autoApplyDiscount: input.autoApplyDiscount ?? null
60987
+ autoApplyDiscount: input.autoApplyDiscount ?? null,
60988
+ selectedVenueDrawing: resolveSelectedVenueDrawing(input.venueDrawing, selected)
60907
60989
  };
60908
60990
  }
60909
60991
 
@@ -61490,10 +61572,10 @@ function acceptedProductNames(props$1) {
61490
61572
  const memberships = props$1.showAcceptedMemberships !== false ? (props$1.applicableMemberships ?? []).map(({ name }) => name) : [];
61491
61573
  return [...passes, ...memberships];
61492
61574
  }
61493
- function EventVenueMap({ venue, showMap, mapHeight, mapClassName }) {
61494
- if (!showMap || !venue?.drawing) return null;
61575
+ function EventVenueMap({ venue, drawing, showMap, mapHeight, mapClassName }) {
61576
+ if (!showMap || !venue || !drawing) return null;
61495
61577
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MapDrawingSvg, {
61496
- drawing: venue.drawing,
61578
+ drawing,
61497
61579
  label: venue.name,
61498
61580
  className: mapClassName,
61499
61581
  height: mapHeight
@@ -61544,7 +61626,8 @@ function SelectedEventDetailsView(props$1) {
61544
61626
  venue,
61545
61627
  showMap,
61546
61628
  mapHeight,
61547
- mapClassName
61629
+ mapClassName,
61630
+ drawing: props$1.selectedVenueDrawing
61548
61631
  })]
61549
61632
  }),
61550
61633
  showOtherDates ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OtherEventDates, { selection }) : null
@@ -61569,6 +61652,7 @@ function LegacyEventDetailsView(props$1) {
61569
61652
  showDescription: props$1.showDescription ?? false,
61570
61653
  showCapacity: props$1.showCapacity ?? false,
61571
61654
  autoApplyDiscount: props$1.autoApplyDiscount ?? null,
61655
+ selectedVenueDrawing: props$1.selectedVenueDrawing,
61572
61656
  mapHeight: props$1.mapHeight ?? 200,
61573
61657
  mapClassName: props$1.mapClassName ?? "event-details-map",
61574
61658
  acceptedItems: acceptedProductNames(props$1)
@@ -61624,6 +61708,7 @@ function EventDetailsHydration({ props: props$1, presentation, scopedEvents, sub
61624
61708
  occurrenceContext: props$1.occurrenceContext ?? null,
61625
61709
  subject,
61626
61710
  events: scopedEvents,
61711
+ venueDrawing: props$1.venueDrawing ?? null,
61627
61712
  showVenue: presentation.showVenue,
61628
61713
  showMap: presentation.showMap,
61629
61714
  showOtherDates: presentation.showOtherDates,
@@ -61910,9 +61995,8 @@ var EventCombined_server_default = EventCombinedSSR;
61910
61995
  //#endregion
61911
61996
  //#region ../blocks/src/system/blocks/offerings-preview/itemData.ts
61912
61997
  function buildItemDataMap(props$1) {
61913
- const routeCandidates = props$1.routeCandidates?.routes ?? [];
61914
61998
  const entries = OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition$1) => [definition$1.sourceKey, eventDataFromMaybeArray(props$1[definition$1.dataKey])]);
61915
- return new Map([...entries, ["course", runDataFromMaybeArray(props$1.wholeSeriesRunEvents, routeCandidates)]]);
61999
+ return new Map([...entries, ["course", runDataFromMaybeArray(props$1.wholeSeriesRunEvents)]]);
61916
62000
  }
61917
62001
  function eventDataFromMaybeArray(events) {
61918
62002
  return events ? {
@@ -61926,7 +62010,7 @@ function eventDataFromMaybeArray(events) {
61926
62010
  reason: "not_loaded"
61927
62011
  };
61928
62012
  }
61929
- function runDataFromMaybeArray(events, routes) {
62013
+ function runDataFromMaybeArray(events) {
61930
62014
  if (!events) return {
61931
62015
  kind: "failed",
61932
62016
  reason: "not_loaded"
@@ -61934,7 +62018,7 @@ function runDataFromMaybeArray(events, routes) {
61934
62018
  const items = [...groupPublicEventsByRun(events)].map((run) => ({
61935
62019
  kind: "run",
61936
62020
  run,
61937
- path: resolveOfferingsPreviewRunPath(run.run, routes)
62021
+ path: run.representative.destination.kind === "native" ? run.representative.destination.path : null
61938
62022
  }));
61939
62023
  return {
61940
62024
  kind: "ready",
@@ -61965,9 +62049,9 @@ function buildLoadedOfferingsPreviewListing(input) {
61965
62049
  //#endregion
61966
62050
  //#region ../blocks/src/system/runtime/nodes/events/shared/offeringNextDates.ts
61967
62051
  /** One occurrence batch supplies every occurrence-targeted card in the block. */
61968
- function offeringDatesBySeries(events, now) {
62052
+ function offeringDatesBySeries(events, now, booking) {
61969
62053
  const groups = events.reduce((result, event) => new Map([...result, [event.seriesId, [...result.get(event.seriesId) ?? [], event]]]), new Map());
61970
- return new Map([...groups].map(([seriesId, occurrences]) => [seriesId, orderedUniqueEventOccurrences(occurrences.filter((event) => event.bookingScope !== "whole_series" && Date.parse(event.startsAt) >= now.getTime())).slice(0, 3).map((event) => offeringDateRow(event, event))]));
62054
+ return new Map([...groups].map(([seriesId, occurrences]) => [seriesId, orderedUniqueEventOccurrences(occurrences.filter((event) => event.bookingScope !== "whole_series" && Date.parse(event.startsAt) >= now.getTime())).slice(0, 3).map((event) => offeringDateRow(event, event, booking))]));
61971
62055
  }
61972
62056
  /** Whole-series sessions share the run-level booking capacity, by contract. */
61973
62057
  function offeringRunDates(event, now) {
@@ -61975,7 +62059,7 @@ function offeringRunDates(event, now) {
61975
62059
  const nextStart = nextLiveRunSessionStartMs(event.run.sessions, now);
61976
62060
  return nextStart === null ? [] : orderedLiveRunSessions(event.run.sessions).filter((session) => Date.parse(session.startsAt) >= nextStart).slice(0, 3).map((session) => offeringDateRow(session, event));
61977
62061
  }
61978
- function offeringDateRow(session, event) {
62062
+ function offeringDateRow(session, event, booking) {
61979
62063
  const options = eventDateOptions({
61980
62064
  ...event,
61981
62065
  timeZone: session.timeZone
@@ -61983,9 +62067,12 @@ function offeringDateRow(session, event) {
61983
62067
  const date = formatEventCompactDateRail(session.startsAt, options, "as-written");
61984
62068
  const capacity = getEventAvailability(event);
61985
62069
  const status = getEventAvailabilityStatus(event);
62070
+ const label = `${date.weekday} ${date.day} ${date.month}, ${formatTime(session.startsAt, options)}`;
62071
+ const bookingLink = booking?.(event, label) ?? null;
61986
62072
  return {
61987
62073
  startsAt: session.startsAt,
61988
- label: `${date.weekday} ${date.day} ${date.month}, ${formatTime(session.startsAt, options)}`,
62074
+ label,
62075
+ ...bookingLink ? { booking: bookingLink } : {},
61989
62076
  places: capacity.available === null ? null : {
61990
62077
  label: capacity.isFull ? "Sold out" : `${capacity.available} place${capacity.available === 1 ? "" : "s"} left`,
61991
62078
  status: capacity.isFull ? "full" : status.status === "filling" ? "low" : "available"
@@ -62004,6 +62091,10 @@ function OfferingsCatalogue(props$1) {
62004
62091
  presets: props$1.bookingOfferingPresets,
62005
62092
  events: props$1.catalogueEvents
62006
62093
  });
62094
+ const shape = offeringsCatalogueShape(state, {
62095
+ listDates: props$1.lookSlots !== undefined && props$1.datesMode === "next-dates",
62096
+ oneOfferingRequested: props$1.oneOffering === true
62097
+ });
62007
62098
  switch (state.kind) {
62008
62099
  case "no-groups": return renderCatalogueEmpty({
62009
62100
  props: props$1,
@@ -62016,7 +62107,8 @@ function OfferingsCatalogue(props$1) {
62016
62107
  case "by-date": return renderCatalogueMergedList({
62017
62108
  props: props$1,
62018
62109
  listing: state,
62019
- now
62110
+ now,
62111
+ shape
62020
62112
  });
62021
62113
  case "by-type": return props$1.lookSlots ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
62022
62114
  ...listLookSlot(props$1, "layout"),
@@ -62029,26 +62121,37 @@ function OfferingsCatalogue(props$1) {
62029
62121
  now,
62030
62122
  children: undefined
62031
62123
  },
62032
- groups: state.groups
62124
+ groups: state.groups,
62125
+ shape
62033
62126
  }) })]
62034
62127
  }) : renderOfferingsCatalogueGroups({
62035
62128
  props: {
62036
62129
  ...props$1,
62037
62130
  now
62038
62131
  },
62039
- groups: state.groups
62132
+ groups: state.groups,
62133
+ shape
62040
62134
  });
62041
62135
  default: return assertNever(state);
62042
62136
  }
62043
62137
  }
62044
- function renderOfferingsCatalogueGroups({ props: props$1, groups }) {
62138
+ /** The hook the single-offering layout hangs from; absent for several. */
62139
+ function catalogueShapeHook(shape) {
62140
+ return shape === "single" ? { "data-has-one-offering": "true" } : {};
62141
+ }
62142
+ /** One offering has room for a Book link on each date; several keep plain rows. */
62143
+ function catalogueDateBooking(shape, pathname) {
62144
+ return shape === "single" ? (event, dateLabel$1) => eventDateBookingLink(event, pathname ?? "/", dateLabel$1) : undefined;
62145
+ }
62146
+ function renderOfferingsCatalogueGroups({ props: props$1, groups, shape }) {
62045
62147
  const enabledSeriesIds = new Set(groups.flatMap((load) => load.kind === "items" ? load.items.map((item) => item.kind === "event" ? item.event.seriesId : item.run.eventSeriesId) : []));
62046
- const quickDateEvents = selectQuickDateEvents((props$1.quickDateEvents ?? []).filter((event) => enabledSeriesIds.has(event.seriesId)));
62148
+ const quickDateEvents = shape === "single" ? [] : selectQuickDateEvents((props$1.quickDateEvents ?? []).filter((event) => enabledSeriesIds.has(event.seriesId)));
62047
62149
  const populated = groups.flatMap(catalogueGroupItems);
62048
62150
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
62049
62151
  className: "offerings-preview rb-flex rb-flex-col rb-gap-6",
62050
62152
  "data-block": "offerings-preview",
62051
62153
  "data-offerings-mode": "catalogue",
62154
+ ...catalogueShapeHook(shape),
62052
62155
  children: [
62053
62156
  quickDateEvents.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
62054
62157
  className: "offerings-preview-quick-dates rb-flex rb-flex-col rb-gap-4",
@@ -62065,28 +62168,30 @@ function renderOfferingsCatalogueGroups({ props: props$1, groups }) {
62065
62168
  children: populated.map(({ group, items }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
62066
62169
  className: "rb-flex rb-flex-col rb-gap-5",
62067
62170
  "data-offering-source": group.sourceKey,
62068
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
62171
+ children: [shape === "single" ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
62069
62172
  ...listLookSlot(props$1, "heading"),
62070
62173
  children: group.title
62071
62174
  }), renderCatalogueItems({
62072
62175
  props: props$1,
62073
- items
62176
+ items,
62177
+ shape,
62178
+ groupTitle: group.title
62074
62179
  })]
62075
62180
  }, group.sourceKey))
62076
62181
  })
62077
62182
  ]
62078
62183
  });
62079
62184
  }
62080
- function renderCatalogueItems({ props: props$1, items }) {
62185
+ function renderCatalogueItems({ props: props$1, items, shape, groupTitle }) {
62081
62186
  const events = items.map((item) => item.kind === "event" ? item.event : item.run.representative);
62082
62187
  if (props$1.lookSlots) {
62083
62188
  const now = props$1.now;
62084
- const dates = offeringDatesBySeries(props$1.quickDateEvents ?? [], now);
62189
+ const dates = offeringDatesBySeries(props$1.quickDateEvents ?? [], now, catalogueDateBooking(shape, props$1.pathname));
62085
62190
  return CardListItems({
62086
62191
  Carousel: props$1.Carousel,
62087
- Title: "h4",
62192
+ Title: shape === "single" ? "h3" : "h4",
62088
62193
  presentation: props$1,
62089
- items: items.map((item) => catalogueCardContent(item, now, dates))
62194
+ items: items.map((item) => catalogueCardContent(item, now, dates, shape === "single" ? groupTitle : undefined))
62090
62195
  });
62091
62196
  }
62092
62197
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
@@ -62121,11 +62226,12 @@ function renderCatalogueEmpty({ props: props$1, failed }) {
62121
62226
  })]
62122
62227
  });
62123
62228
  }
62124
- function renderCatalogueMergedList({ props: props$1, listing, now }) {
62125
- const dates = offeringDatesBySeries(props$1.quickDateEvents ?? [], now);
62229
+ function renderCatalogueMergedList({ props: props$1, listing, now, shape }) {
62230
+ const dates = offeringDatesBySeries(props$1.quickDateEvents ?? [], now, catalogueDateBooking(shape, props$1.pathname));
62126
62231
  const items = listing.items.map(({ item, group }) => catalogueCardContent(item, now, dates, group.singularLabel));
62127
62232
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
62128
62233
  ...listLookSlot(props$1, "layout"),
62234
+ ...catalogueShapeHook(shape),
62129
62235
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", {
62130
62236
  ...listLookSlot(props$1, "head"),
62131
62237
  children: props$1.children
@@ -68810,6 +68916,7 @@ function planArrangementContent(blockKind, manifest, content, audience) {
68810
68916
  });
68811
68917
  return {
68812
68918
  ...activeContent,
68919
+ ...mode !== null ? { variant: mode } : {},
68813
68920
  ...effectiveContent,
68814
68921
  ...photoContent,
68815
68922
  ...arrangementShapeContent(effective.look.id, {
@@ -77805,7 +77912,7 @@ function parseJson(text$1) {
77805
77912
  }
77806
77913
  /** The revision a push must present: whatever the page holds right now. */
77807
77914
  function expectedRevisionFor(read) {
77808
- return read.kind === "absent" ? { kind: "absent" } : read.revision;
77915
+ return read.revision;
77809
77916
  }
77810
77917
  /** Plain data with object keys in a fixed order, so equal designs compare equal. */
77811
77918
  function canonical(value) {
@@ -79792,7 +79899,7 @@ async function loadConfig(configPath, output) {
79792
79899
  return { errorMessage: "No config path provided." };
79793
79900
  }
79794
79901
  try {
79795
- const { loadConfigFile: loadConfigFile$1 } = await import("../load-config-BGzlsmtt.mjs");
79902
+ const { loadConfigFile: loadConfigFile$1 } = await import("../load-config-zu397zDX.mjs");
79796
79903
  const rawConfig = await loadConfigFile$1(configPath);
79797
79904
  const parsed = riverbankSiteConfigSchema.safeParse(rawConfig);
79798
79905
  if (!parsed.success) {
@@ -79877,64 +79984,6 @@ const createInitDocsCommand = () => new Command("init-docs").description("Scaffo
79877
79984
  await runInitDocs(options, command);
79878
79985
  }));
79879
79986
 
79880
- //#endregion
79881
- //#region src/commands/identifiers.ts
79882
- /**
79883
- * Identifiers Command
79884
- *
79885
- * Manage SDK identifiers for pages, blocks, and entries.
79886
- *
79887
- * Usage:
79888
- * riverbankcms identifiers backfill # Backfill identifiers for content without them
79889
- */
79890
- function createBackfillCommand() {
79891
- return new Command("backfill").description("Backfill identifiers for pages, blocks, and entries that don't have one").addHelpText("after", `
79892
- This command generates stable identifiers for content created before the SDK was available.
79893
- Identifiers are generated from titles (slugified) and are idempotent - running this
79894
- command multiple times won't overwrite existing identifiers.
79895
-
79896
- Examples:
79897
- $ riverbankcms identifiers backfill
79898
- $ riverbankcms identifiers backfill --env=remote
79899
- `).action(withErrorHandling(async (_options, command) => {
79900
- const { output, client } = createCommandContext(command);
79901
- output.info("Backfilling identifiers for pages, blocks, and entries...");
79902
- const result = await client.identifiers.backfill();
79903
- const totalUpdated = result.pages.pagesUpdated + result.blocks.total + result.entries.entriesUpdated;
79904
- if (totalUpdated === 0) {
79905
- output.success("All content already has identifiers - nothing to backfill");
79906
- return;
79907
- }
79908
- output.success("Backfill complete", {
79909
- pages: {
79910
- updated: result.pages.pagesUpdated,
79911
- identifiers: result.pages.identifiersAssigned
79912
- },
79913
- blocks: {
79914
- updated: result.blocks.total,
79915
- byPage: Object.keys(result.blocks.byPage).length > 0 ? result.blocks.byPage : undefined
79916
- },
79917
- entries: {
79918
- updated: result.entries.entriesUpdated,
79919
- identifiers: result.entries.identifiersAssigned
79920
- }
79921
- });
79922
- }));
79923
- }
79924
- function createIdentifiersCommand() {
79925
- return new Command("identifiers").description("Manage SDK identifiers").addHelpText("after", `
79926
- Identifiers are stable, human-readable names used to reference content in the SDK.
79927
- They are automatically generated when content is created via the SDK, but older
79928
- content may need backfilling.
79929
-
79930
- Commands:
79931
- backfill Generate identifiers for content that doesn't have one
79932
-
79933
- Examples:
79934
- $ riverbankcms identifiers backfill
79935
- `).addCommand(createBackfillCommand());
79936
- }
79937
-
79938
79987
  //#endregion
79939
79988
  //#region src/constants.ts
79940
79989
  /** Default directory used by the deploy command for generated prebuild data. */
@@ -91189,6 +91238,13 @@ function parsePreviewRefreshResponse(value) {
91189
91238
  };
91190
91239
  }
91191
91240
  const previewStopRequestSchema = z.object({ accessToken: z.string().min(1).max(8192) }).strict();
91241
+ /** Shared by the framed frontend reporter and the dashboard receiver. */
91242
+ const previewFrameHeightMessageSchema = z.object({
91243
+ type: z.literal("riverbank:preview-height"),
91244
+ height: z.number().finite().positive()
91245
+ }).strict();
91246
+ /** Sent by a framed request that has no preview authority, so the dashboard stops waiting. */
91247
+ const previewFrameFailedMessageSchema = z.object({ type: z.literal("riverbank:preview-failed") }).strict();
91192
91248
 
91193
91249
  //#endregion
91194
91250
  //#region ../api/src/footerSettings.ts
@@ -91289,6 +91345,7 @@ const allowedPathPrefixes = [
91289
91345
  "/sites/{siteId}/bookings/event-offerings",
91290
91346
  "/sites/{siteId}/bookings/event-series",
91291
91347
  "/sites/{siteId}/bookings/event-attendees",
91348
+ "/sites/{siteId}/bookings/attendees/",
91292
91349
  "/sites/{siteId}/bookings/event-categories",
91293
91350
  "/sites/{siteId}/bookings/venues",
91294
91351
  "/sites/{siteId}/location/geocode",
@@ -92982,22 +93039,6 @@ const DEFAULT_ANALYTICS_COOKIE_BANNER_COPY = {
92982
93039
  policyLinkLabel: "Cookie policy"
92983
93040
  };
92984
93041
 
92985
- //#endregion
92986
- //#region ../api/src/eventAttendanceLabels.ts
92987
- function getEventAttendanceModeLabel(mode) {
92988
- switch (mode) {
92989
- case "in_person": return "In person";
92990
- case "online": return "Online";
92991
- }
92992
- }
92993
- function getEventDeliveryModeLabel(mode) {
92994
- switch (mode) {
92995
- case "in_person": return "In person";
92996
- case "online": return "Online";
92997
- case "hybrid": return "In person and online";
92998
- }
92999
- }
93000
-
93001
93042
  //#endregion
93002
93043
  //#region ../api/src/siteBanner.ts
93003
93044
  const SITE_BANNER_SCOPE_VALUES = ["homepage", "all-pages"];
@@ -93417,6 +93458,14 @@ function isSiteBannerTone(value) {
93417
93458
 
93418
93459
  //#endregion
93419
93460
  //#region ../api/src/privacyPolicy.ts
93461
+ const SITE_LEGAL_JURISDICTIONS = [
93462
+ "UK",
93463
+ "US",
93464
+ "EU",
93465
+ "CA",
93466
+ "AU",
93467
+ "OTHER"
93468
+ ];
93420
93469
  /**
93421
93470
  * A legal profile saved before the source flags existed carries values an
93422
93471
  * administrator typed by hand, so a saved value is an override and only an
@@ -93457,6 +93506,17 @@ function isSitePrivacyIdentityReady(identity) {
93457
93506
  return identity.entityName !== null;
93458
93507
  }
93459
93508
  /**
93509
+ * Whether a site links to and serves its managed privacy policy. An
93510
+ * administrator has to have turned it on, and it has to be able to name a
93511
+ * controller. Every producer of the link calls this.
93512
+ */
93513
+ function resolveManagedPrivacyPolicyLink(input) {
93514
+ return {
93515
+ path: MANAGED_PRIVACY_POLICY_PATH,
93516
+ enabled: input.isPublished && isSitePrivacyIdentityReady(input.identity)
93517
+ };
93518
+ }
93519
+ /**
93460
93520
  * EU member states, used both to place a site in the EU privacy jurisdiction
93461
93521
  * and to seed the shop's default shipping countries.
93462
93522
  */
@@ -93881,6 +93941,11 @@ async function restorePageVersion(apiClient, input) {
93881
93941
  }));
93882
93942
  }
93883
93943
 
93944
+ //#endregion
93945
+ //#region ../api/src/contentVersionHistory.ts
93946
+ /** Page restore uses the journal's document revision; entries retain their own draft marker. */
93947
+ const restorePageVersionRequestSchema = z.object({ expectedRevision: z.number().int().nonnegative() }).strict();
93948
+
93884
93949
  //#endregion
93885
93950
  //#region ../api/src/blocksKeys.ts
93886
93951
  const blocksKeys = {
@@ -94145,8 +94210,7 @@ async function mutateBlockContent(apiClient, args) {
94145
94210
  const payload$1 = {
94146
94211
  data: args.data,
94147
94212
  optimistic_hash: args.optimisticHash ?? undefined,
94148
- expected_entry_slot_hash: args.expectedEntrySlotHash,
94149
- expected_surface_slot_hash: args.expectedSurfaceSlotHash,
94213
+ expected_slot_hash: args.expectedSlotHash,
94150
94214
  expected_mailing_list_provider_scope: args.expectedMailingListProviderScope
94151
94215
  };
94152
94216
  return unwrapResponse(await apiClient({
@@ -94160,8 +94224,7 @@ async function mutateBlockContent(apiClient, args) {
94160
94224
  path: args.path,
94161
94225
  value: args.value,
94162
94226
  optimistic_hash: args.optimisticHash ?? undefined,
94163
- expected_entry_slot_hash: args.expectedEntrySlotHash,
94164
- expected_surface_slot_hash: args.expectedSurfaceSlotHash,
94227
+ expected_slot_hash: args.expectedSlotHash,
94165
94228
  expected_mailing_list_provider_scope: args.expectedMailingListProviderScope
94166
94229
  };
94167
94230
  return unwrapResponse(await apiClient({
@@ -94284,6 +94347,16 @@ async function updateRouteMetadata(apiClient, { siteId, routeId, body, options }
94284
94347
  return normalizeApiError(error$1, "Failed to update route metadata");
94285
94348
  }
94286
94349
  }
94350
+ /** Metadata has one canonical editor representation, including an empty homepage slug. */
94351
+ function savedRouteMetadataValues(route) {
94352
+ return {
94353
+ draftTitle: route.draftTitle,
94354
+ draftSlug: route.draftSlug ?? "",
94355
+ draftMetaTitle: route.draftMetaTitle ?? null,
94356
+ draftMetaDescription: route.draftMetaDescription ?? null,
94357
+ ogImageId: route.ogImageId ?? null
94358
+ };
94359
+ }
94287
94360
 
94288
94361
  //#endregion
94289
94362
  //#region ../api/src/emailSettings.ts
@@ -94858,16 +94931,6 @@ async function changePlan(apiClient, request) {
94858
94931
  return normalizeApiError(error$1, "Failed to update billing plan");
94859
94932
  }
94860
94933
  }
94861
- async function createBillingPortalSession(apiClient, options) {
94862
- try {
94863
- return unwrapResponse(await apiClient({
94864
- endpoint: "createBillingPortalSession",
94865
- options
94866
- }));
94867
- } catch (error$1) {
94868
- return normalizeApiError(error$1, "Failed to open billing details");
94869
- }
94870
- }
94871
94934
  async function billingCheckout(apiClient, { attemptId, planId, continuation, options }) {
94872
94935
  try {
94873
94936
  return unwrapResponse(await apiClient({
@@ -94890,9 +94953,8 @@ async function billingCheckout(apiClient, { attemptId, planId, continuation, opt
94890
94953
  //#endregion
94891
94954
  //#region ../api/src/aiPlayground.ts
94892
94955
  const PreparedPagePreconditionSchema = z.object({
94893
- schemaVersion: z.literal(1),
94894
94956
  pageId: z.string().uuid(),
94895
- fingerprint: z.string().regex(/^[a-f0-9]{64}$/)
94957
+ revision: z.number().int().nonnegative()
94896
94958
  }).strict();
94897
94959
  /**
94898
94960
  * RFC-6902 JSON Patch Operations
@@ -99168,7 +99230,6 @@ function createProgram(dependencies = {}) {
99168
99230
  program.addCommand(createContentCommand());
99169
99231
  program.addCommand(createDraftsCommand());
99170
99232
  program.addCommand(createInitDocsCommand());
99171
- program.addCommand(createIdentifiersCommand());
99172
99233
  program.addCommand(createDeployCommand());
99173
99234
  program.addCommand(createContentTypeCommand());
99174
99235
  program.addCommand(createVerifyCommand());