themelia-react-ui 2.0.6 → 3.0.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.
- package/CHANGELOG.md +250 -0
- package/MIGRATION.md +746 -7
- package/README.md +27 -23
- package/dist/{accordion-0tQUZ20r.js → accordion-DNVqwEIC.js} +36 -36
- package/dist/accordion-DNVqwEIC.js.map +1 -0
- package/dist/action-menu-D5343RwT.js +286 -0
- package/dist/action-menu-D5343RwT.js.map +1 -0
- package/dist/ai-artifact-otrz9ZwS.js +1214 -0
- package/dist/ai-artifact-otrz9ZwS.js.map +1 -0
- package/dist/anchored-positioning-1U_eBFNx.js +9 -0
- package/dist/anchored-positioning-1U_eBFNx.js.map +1 -0
- package/dist/app-shell-CPN30Nb1.js +372 -0
- package/dist/app-shell-CPN30Nb1.js.map +1 -0
- package/dist/{attachment-BCpA4e7i.js → attachment-D2-fpfmv.js} +15 -15
- package/dist/{attachment-BCpA4e7i.js.map → attachment-D2-fpfmv.js.map} +1 -1
- package/dist/{auth-B0girIk_.js → auth-g_oUTDDC.js} +234 -241
- package/dist/auth-g_oUTDDC.js.map +1 -0
- package/dist/{avatar-B9Jnp-T-.js → avatar-Ca3Ihrq4.js} +4 -4
- package/dist/{avatar-B9Jnp-T-.js.map → avatar-Ca3Ihrq4.js.map} +1 -1
- package/dist/{badge-wWauMgAt.js → badge-oGiXblW7.js} +8 -9
- package/dist/badge-oGiXblW7.js.map +1 -0
- package/dist/base/accordion.js +1 -1
- package/dist/base/action-menu.js +1 -1
- package/dist/base/attachment.js +1 -1
- package/dist/base/avatar.js +1 -1
- package/dist/base/badge.js +1 -1
- package/dist/base/batch-action-bar.js +1 -1
- package/dist/base/buttons.js +2 -2
- package/dist/base/cards.js +3 -3
- package/dist/base/carousel.js +11 -11
- package/dist/base/carousel.js.map +1 -1
- package/dist/base/cascader.js +1 -1
- package/dist/base/chart.js +1 -1
- package/dist/base/choice-inputs.js +2 -2
- package/dist/base/code-block.js +1 -1
- package/dist/base/combobox.js +1 -1
- package/dist/base/command.js +1 -1
- package/dist/base/copyable.js +1 -1
- package/dist/base/date-pickers.js +2 -2
- package/dist/base/display.js +7 -7
- package/dist/base/feedback.js +4 -4
- package/dist/base/forms-numeric.js +2 -2
- package/dist/base/forms.js +2 -2
- package/dist/base/inline-edit.js +13 -13
- package/dist/base/inline-edit.js.map +1 -1
- package/dist/base/item.js +1 -1
- package/dist/base/media-gallery.js +203 -2
- package/dist/base/media-gallery.js.map +1 -0
- package/dist/base/metadata-list.js +1 -1
- package/dist/base/navigation.js +7 -7
- package/dist/base/popover-menu.js +1 -1
- package/dist/base/popover.js +1 -1
- package/dist/base/qr-code.js +32 -22
- package/dist/base/qr-code.js.map +1 -1
- package/dist/base/repeaters.js +91 -88
- package/dist/base/repeaters.js.map +1 -1
- package/dist/base/sidebar.js +2 -2
- package/dist/base/signature-pad.js +14 -14
- package/dist/base/signature-pad.js.map +1 -1
- package/dist/base/skeleton.js +1 -1
- package/dist/base/spinner.js +6 -12
- package/dist/base/spinner.js.map +1 -1
- package/dist/base/structure.js +1 -1
- package/dist/base/table.js +1 -1
- package/dist/base/text-inputs.js +3 -3
- package/dist/base/toaster.js +2 -2
- package/dist/base/tree.js +2 -2
- package/dist/base/upload-queue.js +303 -2
- package/dist/base/upload-queue.js.map +1 -0
- package/dist/base/upload.js +3 -4
- package/dist/base/value-inputs.js +1 -1
- package/dist/{batch-action-bar-BoqWIIpV.js → batch-action-bar-D6MZQNnC.js} +10 -10
- package/dist/{batch-action-bar-BoqWIIpV.js.map → batch-action-bar-D6MZQNnC.js.map} +1 -1
- package/dist/blocks/admin.js +242 -228
- package/dist/blocks/admin.js.map +1 -1
- package/dist/blocks/ai.js +395 -357
- package/dist/blocks/ai.js.map +1 -1
- package/dist/blocks/analytics/charts.js +1022 -0
- package/dist/blocks/analytics/charts.js.map +1 -0
- package/dist/blocks/analytics/usage-card.js +1 -1
- package/dist/blocks/analytics.js +171 -1365
- package/dist/blocks/analytics.js.map +1 -1
- package/dist/blocks/collaboration.js +1 -1
- package/dist/blocks/commerce/receipt.js +1 -1
- package/dist/blocks/commerce.js +1487 -1358
- package/dist/blocks/commerce.js.map +1 -1
- package/dist/blocks/data-display.js +2 -3
- package/dist/blocks/onboarding.js +91 -82
- package/dist/blocks/onboarding.js.map +1 -1
- package/dist/blocks/planning.js +25 -25
- package/dist/blocks/planning.js.map +1 -1
- package/dist/blocks/timelines.js +2 -2
- package/dist/{breadcrumbs-Bp9Ke7kd.js → breadcrumbs-CQ9JSlez.js} +52 -45
- package/dist/breadcrumbs-CQ9JSlez.js.map +1 -0
- package/dist/{button-ChBovTx0.js → button-rd6FiHfQ.js} +12 -8
- package/dist/button-rd6FiHfQ.js.map +1 -0
- package/dist/{buttons-DeW0bQeK.js → buttons-pZVgPTZn.js} +230 -246
- package/dist/buttons-pZVgPTZn.js.map +1 -0
- package/dist/{cards-CNXnmvV5.js → cards-CgWyqvgZ.js} +25 -22
- package/dist/{cards-CNXnmvV5.js.map → cards-CgWyqvgZ.js.map} +1 -1
- package/dist/cascader-Cf05pwaq.js +444 -0
- package/dist/cascader-Cf05pwaq.js.map +1 -0
- package/dist/{chart-I7ROnsl8.js → chart-CygRCyIZ.js} +5 -5
- package/dist/{chart-I7ROnsl8.js.map → chart-CygRCyIZ.js.map} +1 -1
- package/dist/{checkbox-MoyHIAPs.js → checkbox-Dy5_XBMZ.js} +4 -4
- package/dist/{checkbox-MoyHIAPs.js.map → checkbox-Dy5_XBMZ.js.map} +1 -1
- package/dist/{choice-inputs-DHGtx0QV.js → choice-inputs-oJEsrb5Y.js} +113 -114
- package/dist/choice-inputs-oJEsrb5Y.js.map +1 -0
- package/dist/{code-block-BSJyq9e-.js → code-block-BrLD7mCi.js} +44 -60
- package/dist/code-block-BrLD7mCi.js.map +1 -0
- package/dist/collapsible-CRCCg_bO.js +80 -0
- package/dist/collapsible-CRCCg_bO.js.map +1 -0
- package/dist/{collection-content-CSnwtOTH.js → collection-content-D7SoDlYd.js} +3 -3
- package/dist/{collection-content-CSnwtOTH.js.map → collection-content-D7SoDlYd.js.map} +1 -1
- package/dist/combobox-Dl6f6kHz.js +362 -0
- package/dist/combobox-Dl6f6kHz.js.map +1 -0
- package/dist/combobox-DrDXtSSt.js +929 -0
- package/dist/combobox-DrDXtSSt.js.map +1 -0
- package/dist/command-CjZ2VzKC.js +432 -0
- package/dist/command-CjZ2VzKC.js.map +1 -0
- package/dist/comments-C2MZyRmh.js +1214 -0
- package/dist/comments-C2MZyRmh.js.map +1 -0
- package/dist/components/base/accordion/accordion.d.ts +11 -3
- package/dist/components/base/action-menu/action-menu.d.ts +11 -3
- package/dist/components/base/buttons/button.d.ts +2 -2
- package/dist/components/base/buttons/index.d.ts +1 -1
- package/dist/components/base/buttons/loader-button.d.ts +6 -15
- package/dist/components/base/cards/index.d.ts +1 -1
- package/dist/components/base/cards/partials/card-body-context.d.ts +6 -0
- package/dist/components/base/cards/smart-card.d.ts +0 -2
- package/dist/components/base/cards/smart-card.types.d.ts +12 -10
- package/dist/components/base/cascader/cascader.d.ts +8 -2
- package/dist/components/base/cascader/cascader.types.d.ts +24 -2
- package/dist/components/base/cascader/index.d.ts +1 -1
- package/dist/components/base/choice-inputs/switch.d.ts +1 -1
- package/dist/components/base/code-block/use-code-copy.d.ts +2 -6
- package/dist/components/base/command/command.d.ts +1 -1
- package/dist/components/base/date-pickers/datepicker.types.d.ts +1 -3
- package/dist/components/base/display/dialog.d.ts +3 -9
- package/dist/components/base/display/index.d.ts +2 -3
- package/dist/components/base/display/separator.d.ts +1 -1
- package/dist/components/base/feedback/alert.d.ts +2 -1
- package/dist/components/base/feedback/empty.d.ts +10 -2
- package/dist/components/base/forms/workflow.d.ts +2 -2
- package/dist/components/base/forms-numeric/dimensions-input.d.ts +9 -17
- package/dist/components/base/forms-numeric/index.d.ts +3 -3
- package/dist/components/base/item/item.types.d.ts +6 -2
- package/dist/components/base/metadata-list/index.d.ts +1 -3
- package/dist/components/base/metadata-list/metadata-list.d.ts +4 -1
- package/dist/components/base/navigation/index.d.ts +2 -2
- package/dist/components/base/navigation/language-switcher.d.ts +7 -6
- package/dist/components/base/navigation/navigation-tabs.d.ts +8 -1
- package/dist/components/base/navigation/page-header/index.d.ts +1 -1
- package/dist/components/base/navigation/page-header/page-header.d.ts +13 -17
- package/dist/components/base/navigation/pagination.d.ts +5 -5
- package/dist/components/base/popover/popover.recipes.d.ts +0 -1
- package/dist/components/base/qr-code/qr-code.d.ts +4 -0
- package/dist/components/base/repeaters/index.d.ts +1 -1
- package/dist/components/base/repeaters/key-value-editor.d.ts +4 -0
- package/dist/components/base/sheet/sheet.d.ts +6 -15
- package/dist/components/base/sidebar/index.d.ts +1 -6
- package/dist/components/base/sidebar/sidebar.d.ts +38 -10
- package/dist/components/base/skeleton/skeleton.d.ts +1 -1
- package/dist/components/base/structure/structure.types.d.ts +11 -2
- package/dist/components/base/text-inputs/index.d.ts +1 -1
- package/dist/components/base/tree/index.d.ts +1 -0
- package/dist/components/base/tree/tree.d.ts +2 -2
- package/dist/components/base/tree/tree.types.d.ts +7 -1
- package/dist/components/base/upload/file-upload.validation.d.ts +37 -1
- package/dist/components/base/upload/image-upload.d.ts +2 -0
- package/dist/components/base/upload/index.d.ts +3 -9
- package/dist/components/base/value-inputs/date-time-input.d.ts +4 -0
- package/dist/components/base/value-inputs/slider.d.ts +5 -2
- package/dist/components/blocks/admin/action-surfaces/index.d.ts +17 -4
- package/dist/components/blocks/admin/api-key-list/api-key-list.types.d.ts +9 -3
- package/dist/components/blocks/admin/index.d.ts +1 -1
- package/dist/components/blocks/ai/ai-artifact/ai-artifact.d.ts +1 -1
- package/dist/components/blocks/ai/ai-artifact/types.d.ts +9 -4
- package/dist/components/blocks/ai/ai-chain-of-thought/ai-chain-of-thought.d.ts +1 -1
- package/dist/components/blocks/ai/ai-chain-of-thought/types.d.ts +11 -1
- package/dist/components/blocks/ai/ai-citation/ai-citation.d.ts +1 -1
- package/dist/components/blocks/ai/ai-citation/types.d.ts +6 -0
- package/dist/components/blocks/ai/ai-confirmation/ai-confirmation.d.ts +1 -1
- package/dist/components/blocks/ai/ai-confirmation/types.d.ts +21 -5
- package/dist/components/blocks/ai/ai-feedback/types.d.ts +7 -2
- package/dist/components/blocks/ai/ai-inline-citation/types.d.ts +9 -3
- package/dist/components/blocks/ai/ai-package-info/ai-package-info.d.ts +1 -1
- package/dist/components/blocks/ai/ai-package-info/types.d.ts +6 -0
- package/dist/components/blocks/ai/ai-sources/ai-sources.d.ts +1 -1
- package/dist/components/blocks/ai/ai-sources/types.d.ts +8 -2
- package/dist/components/blocks/ai/ai-task/ai-task.d.ts +1 -1
- package/dist/components/blocks/ai/ai-task/types.d.ts +10 -1
- package/dist/components/blocks/ai/ai-tool-call/ai-tool-call.d.ts +1 -1
- package/dist/components/blocks/ai/ai-tool-call/types.d.ts +6 -0
- package/dist/components/blocks/ai/ai.strings.d.ts +2 -0
- package/dist/components/blocks/analytics/activity-heatmap/types.d.ts +1 -1
- package/dist/components/blocks/analytics/analytics.strings.d.ts +2 -0
- package/dist/components/blocks/analytics/atoms/metric-trend-chip.d.ts +11 -1
- package/dist/components/blocks/analytics/chart-card/chart-card.d.ts +7 -5
- package/dist/components/blocks/analytics/charts/index.d.ts +27 -0
- package/dist/components/blocks/analytics/index.d.ts +17 -24
- package/dist/components/blocks/analytics/metric/metric.d.ts +5 -5
- package/dist/components/blocks/analytics/metric-grid/metric-grid.d.ts +2 -2
- package/dist/components/blocks/analytics/types.d.ts +12 -3
- package/dist/components/blocks/analytics/usage-card/usage-card.strings.d.ts +2 -0
- package/dist/components/blocks/commerce/address-card/address-card.d.ts +1 -1
- package/dist/components/blocks/commerce/address-card/types.d.ts +5 -16
- package/dist/components/blocks/commerce/booking-calendar-event-card/booking-calendar-event-card.d.ts +2 -2
- package/dist/components/blocks/commerce/booking-calendar-event-card/booking-calendar-event-card.types.d.ts +6 -4
- package/dist/components/blocks/commerce/cart-summary/cart-summary.d.ts +0 -2
- package/dist/components/blocks/commerce/cart-summary/index.d.ts +2 -2
- package/dist/components/blocks/commerce/cart-summary/types.d.ts +9 -11
- package/dist/components/blocks/commerce/coupon-input/coupon-input.d.ts +1 -1
- package/dist/components/blocks/commerce/coupon-input/types.d.ts +7 -3
- package/dist/components/blocks/commerce/discount-stack/discount-stack.d.ts +0 -2
- package/dist/components/blocks/commerce/discount-stack/index.d.ts +2 -2
- package/dist/components/blocks/commerce/discount-stack/types.d.ts +4 -6
- package/dist/components/blocks/commerce/fulfillment-group/fulfillment-group.d.ts +1 -1
- package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +2 -0
- package/dist/components/blocks/commerce/giftcard-card/partials/giftcard-balance.d.ts +18 -0
- package/dist/components/blocks/commerce/giftcard-card/partials/giftcard-compact.d.ts +1 -1
- package/dist/components/blocks/commerce/giftcard-card/partials/giftcard-copy-button.d.ts +0 -1
- package/dist/components/blocks/commerce/giftcard-card/partials/giftcard-dark.d.ts +1 -1
- package/dist/components/blocks/commerce/giftcard-card/partials/giftcard-full.d.ts +1 -1
- package/dist/components/blocks/commerce/giftcard-card/partials/giftcard-illustrated.d.ts +1 -1
- package/dist/components/blocks/commerce/giftcard-card/partials/giftcard-minimal.d.ts +1 -1
- package/dist/components/blocks/commerce/giftcard-card/types.d.ts +16 -5
- package/dist/components/blocks/commerce/index.d.ts +8 -8
- package/dist/components/blocks/commerce/inventory-level/inventory-level.strings.d.ts +2 -0
- package/dist/components/blocks/commerce/inventory-level/types.d.ts +1 -1
- package/dist/components/blocks/commerce/inventory-section/types.d.ts +0 -5
- package/dist/components/blocks/commerce/invoice-line-items/types.d.ts +6 -3
- package/dist/components/blocks/commerce/loyalty-points/loyalty-points.d.ts +1 -1
- package/dist/components/blocks/commerce/loyalty-points/types.d.ts +11 -5
- package/dist/components/blocks/commerce/order-status/order-status.d.ts +1 -1
- package/dist/components/blocks/commerce/order-status/types.d.ts +8 -8
- package/dist/components/blocks/commerce/order-timeline/order-timeline.d.ts +1 -1
- package/dist/components/blocks/commerce/order-timeline/types.d.ts +3 -1
- package/dist/components/blocks/commerce/payment-method/index.d.ts +2 -2
- package/dist/components/blocks/commerce/payment-method/payment-method.d.ts +0 -8
- package/dist/components/blocks/commerce/payment-method/types.d.ts +0 -2
- package/dist/components/blocks/commerce/receipt/index.d.ts +1 -1
- package/dist/components/blocks/commerce/receipt/receipt-items.d.ts +1 -1
- package/dist/components/blocks/commerce/receipt/types.d.ts +10 -0
- package/dist/components/blocks/commerce/refund-status/index.d.ts +2 -2
- package/dist/components/blocks/commerce/refund-status/refund-status.d.ts +0 -2
- package/dist/components/blocks/commerce/refund-status/types.d.ts +0 -2
- package/dist/components/blocks/commerce/seo-listing/types.d.ts +7 -0
- package/dist/components/blocks/commerce/shared/code-entry.d.ts +39 -0
- package/dist/components/blocks/commerce/shared/order-status.d.ts +1 -1
- package/dist/components/blocks/commerce/subscription-summary/subscription-summary.d.ts +1 -1
- package/dist/components/blocks/commerce/subscription-summary/types.d.ts +10 -1
- package/dist/components/blocks/commerce/upcoming-booking/index.d.ts +2 -1
- package/dist/components/blocks/commerce/upcoming-booking/types.d.ts +8 -0
- package/dist/components/blocks/commerce/upcoming-booking/upcoming-booking.d.ts +2 -2
- package/dist/components/blocks/commerce/vendor-profile/types.d.ts +4 -5
- package/dist/components/blocks/commerce/voucher-entry/types.d.ts +6 -3
- package/dist/components/blocks/commerce/voucher-entry/voucher-entry.d.ts +1 -1
- package/dist/components/blocks/content-block-hooks.d.ts +22 -0
- package/dist/components/blocks/data-display/dense-info-card/dense-info.strings.d.ts +5 -1
- package/dist/components/blocks/data-display/dense-info-card/helpers.d.ts +3 -1
- package/dist/components/blocks/data-display/dense-info-card/index.d.ts +1 -1
- package/dist/components/blocks/data-display/dense-info-card/partials/dense-info-classification.d.ts +1 -1
- package/dist/components/blocks/data-display/dense-info-card/partials/dense-info-dashboard.d.ts +1 -1
- package/dist/components/blocks/data-display/dense-info-card/partials/dense-info-financial.d.ts +1 -1
- package/dist/components/blocks/data-display/dense-info-card/partials/dense-info-project.d.ts +1 -1
- package/dist/components/blocks/data-display/dense-info-card/partials/dense-info-score.d.ts +1 -1
- package/dist/components/blocks/data-display/dense-info-card/types.d.ts +12 -5
- package/dist/components/blocks/data-display/empty-state/empty-state.types.d.ts +6 -0
- package/dist/components/blocks/data-display/index.d.ts +0 -1
- package/dist/components/blocks/data-display/relationship-card-frame.d.ts +1 -1
- package/dist/components/blocks/onboarding/checklist/checklist.types.d.ts +5 -3
- package/dist/components/blocks/planning/task-card.types.d.ts +7 -3
- package/dist/components/blocks/timelines/changelog/types.d.ts +2 -2
- package/dist/components/blocks/timelines/index.d.ts +2 -2
- package/dist/components/blocks/timelines/milestones/types.d.ts +2 -2
- package/dist/components/blocks/timelines/shared/timeline.d.ts +6 -0
- package/dist/components/blocks/timelines/steps-card/index.d.ts +2 -1
- package/dist/components/blocks/timelines/steps-card/steps-card.d.ts +2 -2
- package/dist/components/blocks/timelines/steps-card/types.d.ts +13 -1
- package/dist/components/features/activities/activities.strings.d.ts +5 -3
- package/dist/components/features/activities/activities.types.d.ts +28 -11
- package/dist/components/features/activities/hooks/use-activity-feed.d.ts +6 -0
- package/dist/components/features/activities/index.d.ts +1 -1
- package/dist/components/features/activities/partials/activity-headline.d.ts +5 -0
- package/dist/components/features/activities/partials/activity-row.d.ts +12 -13
- package/dist/components/features/activities/partials/row-layers.d.ts +7 -0
- package/dist/components/features/activities/relative-time.d.ts +18 -0
- package/dist/components/features/ai-chat/ai-chat.d.ts +6 -2
- package/dist/components/features/ai-chat/ai-chat.strings.d.ts +41 -2
- package/dist/components/features/ai-chat/ai-chat.types.d.ts +6 -0
- package/dist/components/features/ai-chat/partials/ai-chat-attachments-strip.d.ts +5 -1
- package/dist/components/features/ai-chat/partials/ai-chat-prompt-input.d.ts +2 -2
- package/dist/components/features/ai-chat/partials/ai-chat-queue.d.ts +3 -1
- package/dist/components/features/ai-chat/partials/ai-chat-suggestions-row.d.ts +6 -1
- package/dist/components/features/appointment-calendar/appointment-calendar.d.ts +1 -1
- package/dist/components/features/appointment-calendar/appointment-calendar.types.d.ts +19 -5
- package/dist/components/features/appointment-calendar/index.d.ts +1 -1
- package/dist/components/features/appointment-calendar/partials/appointment-agenda.d.ts +18 -10
- package/dist/components/features/async-preview/async-preview.d.ts +2 -2
- package/dist/components/features/async-preview/async-preview.types.d.ts +30 -1
- package/dist/components/features/async-preview/preview-trigger-cell.d.ts +7 -2
- package/dist/components/features/combobox/async-resource-combobox.d.ts +2 -2
- package/dist/components/features/combobox/combobox.d.ts +12 -3
- package/dist/components/features/combobox/components/error-message.d.ts +3 -1
- package/dist/components/features/combobox/hooks/use-combobox-core.d.ts +2 -2
- package/dist/components/features/combobox/index.d.ts +1 -1
- package/dist/components/features/combobox/types.d.ts +47 -45
- package/dist/components/features/comments/comments.strings.d.ts +6 -5
- package/dist/components/features/comments/comments.types.d.ts +40 -26
- package/dist/components/features/comments/hooks/use-attachment-upload.d.ts +5 -1
- package/dist/components/features/comments/hooks/use-comments.d.ts +8 -1
- package/dist/components/features/data-view/data-view.strings.d.ts +9 -2
- package/dist/components/features/data-view/data-view.types.d.ts +15 -2
- package/dist/components/features/email-composer/email-html.d.ts +5 -0
- package/dist/components/features/email-composer/http.d.ts +2 -0
- package/dist/components/features/email-composer/strings.d.ts +17 -2
- package/dist/components/features/email-composer/types.d.ts +17 -2
- package/dist/components/features/email-composer/use-composer.d.ts +2 -78
- package/dist/components/features/event-calendar/event-calendar-day-cell.d.ts +1 -1
- package/dist/components/features/event-calendar/event-calendar-event-badge.d.ts +1 -1
- package/dist/components/features/event-calendar/event-calendar-header.d.ts +1 -1
- package/dist/components/features/event-calendar/event-calendar-legend.d.ts +2 -2
- package/dist/components/features/event-calendar/event-calendar.d.ts +1 -1
- package/dist/components/features/event-calendar/event-calendar.types.d.ts +126 -21
- package/dist/components/features/filters/facets/range-facet.d.ts +13 -8
- package/dist/components/features/filters/filter-context.d.ts +9 -0
- package/dist/components/features/filters/filters.strings.d.ts +36 -3
- package/dist/components/features/filters/filters.types.d.ts +72 -5
- package/dist/components/features/filters/hooks/use-filter-draft.d.ts +1 -0
- package/dist/components/features/filters/index.d.ts +2 -2
- package/dist/components/features/filters/operator-options.d.ts +25 -2
- package/dist/components/features/filters/partials/active-filter-item.d.ts +0 -13
- package/dist/components/features/filters/partials/async-options-status.d.ts +32 -0
- package/dist/components/features/filters/partials/filter-draft-footer.d.ts +11 -0
- package/dist/components/features/filters/partials/filter-operator-select.d.ts +4 -2
- package/dist/components/features/filters/partials/filter-pill.d.ts +5 -1
- package/dist/components/features/filters/partials/filter-tabs.d.ts +2 -1
- package/dist/components/features/filters/partials/regular-filter-content.d.ts +1 -1
- package/dist/components/features/filters/utils/filter-utils.d.ts +29 -4
- package/dist/components/features/global-search/global-search-dialog.d.ts +7 -1
- package/dist/components/features/global-search/global-search.d.ts +7 -1
- package/dist/components/features/global-search/global-search.strings.d.ts +19 -3
- package/dist/components/features/global-search/global-search.types.d.ts +30 -6
- package/dist/components/features/global-search/index.d.ts +1 -1
- package/dist/components/features/global-search/partials/global-search-idle-state.d.ts +6 -1
- package/dist/components/features/global-search/partials/global-search-input.d.ts +2 -0
- package/dist/components/features/kanban/index.d.ts +2 -2
- package/dist/components/features/kanban/kanban-context.d.ts +4 -0
- package/dist/components/features/kanban/kanban-keyboard.d.ts +7 -2
- package/dist/components/features/kanban/kanban.d.ts +10 -1
- package/dist/components/features/kanban/kanban.strings.d.ts +11 -2
- package/dist/components/features/kanban/kanban.types.d.ts +26 -0
- package/dist/components/features/map/map.d.ts +4 -0
- package/dist/components/features/map/place-autocomplete.d.ts +10 -1
- package/dist/components/features/media-library/hooks/use-media-library.d.ts +3 -1
- package/dist/components/features/media-library/media-library.d.ts +1 -1
- package/dist/components/features/media-library/media-library.strings.d.ts +33 -3
- package/dist/components/features/media-library/media-library.types.d.ts +47 -2
- package/dist/components/features/media-library/partials/media-library-partials.d.ts +1 -1
- package/dist/components/features/mentions/hooks/use-mentions-search.d.ts +7 -0
- package/dist/components/features/mentions/index.d.ts +1 -1
- package/dist/components/features/mentions/mentions.strings.d.ts +10 -2
- package/dist/components/features/mentions/partials/mention-chip.d.ts +1 -0
- package/dist/components/features/mentions/partials/mention-inline-suggestions.d.ts +8 -1
- package/dist/components/features/mentions/partials/mention-picker.d.ts +8 -1
- package/dist/components/features/mentions/partials/mention-search-error.d.ts +6 -0
- package/dist/components/features/mentions/utils/index.d.ts +0 -1
- package/dist/components/features/overlays/alert-dialog.d.ts +1 -1
- package/dist/components/features/overlays/dialog.d.ts +1 -1
- package/dist/components/features/overlays/drawer.d.ts +1 -1
- package/dist/components/features/overlays/index.d.ts +2 -2
- package/dist/components/features/overlays/overlays.strings.d.ts +2 -1
- package/dist/components/features/overlays/overlays.types.d.ts +27 -10
- package/dist/components/features/products/components/index.d.ts +0 -10
- package/dist/components/features/products/components/product-contract-overview.d.ts +1 -1
- package/dist/components/features/products/components/product-details-card.d.ts +1 -1
- package/dist/components/features/products/components/product-operations-card.d.ts +1 -1
- package/dist/components/features/products/components/product-option-action-menu.d.ts +1 -1
- package/dist/components/features/products/components/product-options-summary.d.ts +1 -1
- package/dist/components/features/products/components/product-policies-card.d.ts +1 -1
- package/dist/components/features/products/components/product-quote-preview-card.d.ts +1 -1
- package/dist/components/features/products/components/product-readiness-card.d.ts +1 -1
- package/dist/components/features/products/components/product-structure-card.d.ts +1 -1
- package/dist/components/features/products/components/product-variant-action-menu.d.ts +1 -1
- package/dist/components/features/products/components/product-variants-manager.d.ts +1 -1
- package/dist/components/features/products/components/product-variants-table.d.ts +1 -1
- package/dist/components/features/products/partials/product-surface.d.ts +15 -0
- package/dist/components/features/products/products.strings.d.ts +8 -0
- package/dist/components/features/products/products.types.d.ts +25 -7
- package/dist/components/features/questionnaire/questionnaire.types.d.ts +6 -4
- package/dist/components/features/resource/index.d.ts +2 -3
- package/dist/components/features/resource/resource.d.ts +2 -10
- package/dist/components/features/resource/resource.types.d.ts +7 -149
- package/dist/components/features/resource-assignment/partials/assignment-surface.d.ts +15 -0
- package/dist/components/features/resource-assignment/resource-assignment.strings.d.ts +6 -1
- package/dist/components/features/resource-assignment/resource-assignment.types.d.ts +6 -0
- package/dist/components/features/rich-text-editor/partials/caret-helpers.d.ts +5 -7
- package/dist/components/features/rich-text-editor/partials/html-helpers.d.ts +2 -3
- package/dist/components/features/rich-text-editor/partials/image-uploads.d.ts +6 -2
- package/dist/components/features/rich-text-editor/partials/index.d.ts +2 -3
- package/dist/components/features/rich-text-editor/partials/rich-text-editor-tiptap.d.ts +0 -1
- package/dist/components/features/rich-text-editor/partials/rich-text-editor-toolbar.d.ts +2 -3
- package/dist/components/features/rich-text-editor/rich-text-editor.types.d.ts +13 -1
- package/dist/components/features/schema-form/hooks/use-schema-form.d.ts +5 -0
- package/dist/components/features/schema-form/schema-form.d.ts +1 -1
- package/dist/components/features/schema-form/schema-form.types.d.ts +13 -5
- package/dist/components/features/suggestions/suggestions.strings.d.ts +14 -0
- package/dist/components/features/suggestions/suggestions.types.d.ts +12 -4
- package/dist/components/features/table/data-table.d.ts +1 -1
- package/dist/components/features/table/filter-bar.d.ts +1 -1
- package/dist/components/features/table/pagination.d.ts +1 -1
- package/dist/components/features/table/partials/cell-value.d.ts +1 -1
- package/dist/components/features/table/table-body.d.ts +1 -1
- package/dist/components/features/table/table-header.d.ts +1 -1
- package/dist/components/features/table/table-helpers.d.ts +31 -9
- package/dist/components/features/table/table-region.recipes.d.ts +11 -0
- package/dist/components/features/table/table-toolbar.d.ts +1 -1
- package/dist/components/features/table/table.strings.d.ts +1 -0
- package/dist/components/features/table/table.types.d.ts +74 -48
- package/dist/components/features/theme-tweaker/theme-provider-settings.d.ts +4 -0
- package/dist/components/features/theme-tweaker/theme-tweaker.strings.d.ts +10 -7
- package/dist/components/features/theme-tweaker/theme-tweaker.utils.d.ts +17 -0
- package/dist/components/layout/app-shell/app-shell.types.d.ts +46 -49
- package/dist/components/layout/app-shell/index.d.ts +2 -2
- package/dist/components/layout/app-shell/shell-regions.d.ts +9 -0
- package/dist/components/layout/app-shell/shell-skip-link.d.ts +9 -0
- package/dist/components/layout/app-shell/sidebar-inset-layout.d.ts +1 -1
- package/dist/components/layout/app-shell/stacked-layout.d.ts +1 -1
- package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +1 -1
- package/dist/components/layout/auth/auth-shell.d.ts +1 -1
- package/dist/components/layout/auth/auth.types.d.ts +0 -5
- package/dist/components/layout/containers/inline-gutter-context.d.ts +7 -0
- package/dist/components/layout/containers/main-landmark-context.d.ts +6 -0
- package/dist/components/layout/header/header.types.d.ts +16 -6
- package/dist/components/layout/header/partials/header-global-search-trigger.d.ts +1 -1
- package/dist/components/layout/header/partials/header-notifications.d.ts +1 -1
- package/dist/components/layout/header/partials/header-search.d.ts +1 -1
- package/dist/components/layout/hooks/use-command-shortcut.d.ts +10 -1
- package/dist/components/layout/layout.types.d.ts +2 -2
- package/dist/components/layout/navigation/breadcrumb-progress/breadcrumb-progress.d.ts +1 -1
- package/dist/components/layout/navigation/breadcrumb-progress/types.d.ts +9 -0
- package/dist/components/layout/navigation/section-nav/section-nav.d.ts +8 -1
- package/dist/components/layout/page/index.d.ts +2 -3
- package/dist/components/layout/page/page.strings.d.ts +12 -0
- package/dist/components/layout/page/page.types.d.ts +7 -110
- package/dist/components/layout/page/partials/page-header.d.ts +1 -1
- package/dist/components/layout/settings/index.d.ts +1 -1
- package/dist/components/layout/settings/settings.d.ts +3 -5
- package/dist/components/layout/sidebar/app-sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-grouped-navigation.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation-footer.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation.d.ts +1 -1
- package/dist/components/layout/sidebar/index.d.ts +1 -1
- package/dist/components/layout/sidebar/sidebar-navigation-rail.d.ts +15 -7
- package/dist/components/layout/sidebar/sidebar.types.d.ts +10 -12
- package/dist/components/layout/sidebar/sidebar.utils.d.ts +4 -0
- package/dist/components/layout/workspace/workspace.strings.d.ts +2 -2
- package/dist/components/layout/workspace/workspace.types.d.ts +13 -7
- package/dist/components/primitives/date.d.ts +22 -3
- package/dist/components/primitives/file-size.d.ts +8 -2
- package/dist/components/primitives/index.d.ts +1 -1
- package/dist/components/primitives/initials.d.ts +3 -1
- package/dist/components/primitives/link.d.ts +8 -1
- package/dist/components/primitives/money.d.ts +1 -1
- package/dist/components/primitives/number.d.ts +2 -1
- package/dist/components/typography/heading.d.ts +9 -3
- package/dist/components/typography/index.d.ts +1 -1
- package/dist/components/typography/text-link.d.ts +10 -3
- package/dist/components/ui/badge.d.ts +2 -4
- package/dist/components/ui/breadcrumb.d.ts +2 -3
- package/dist/components/ui/button.d.ts +8 -2
- package/dist/components/ui/collapsible.d.ts +1 -4
- package/dist/components/ui/command.d.ts +20 -18
- package/dist/components/ui/dialog.d.ts +3 -9
- package/dist/components/ui/empty.d.ts +2 -2
- package/dist/components/ui/input-group.d.ts +3 -3
- package/dist/components/ui/item.d.ts +3 -3
- package/dist/components/ui/popover.d.ts +3 -7
- package/dist/components/ui/sheet.d.ts +4 -12
- package/dist/components/ui/sidebar-state.d.ts +6 -1
- package/dist/components/ui/sidebar.d.ts +7 -4
- package/dist/components/ui/tabs.d.ts +2 -2
- package/dist/components/ui/toggle-group.d.ts +3 -3
- package/dist/components/ui/toggle.d.ts +2 -2
- package/dist/components/ui/tooltip.d.ts +1 -3
- package/dist/{containers-CSdc32h9.js → containers-BdfLTP4w.js} +37 -32
- package/dist/containers-BdfLTP4w.js.map +1 -0
- package/dist/content-block-hooks-Z3iKjqd1.js +17 -0
- package/dist/content-block-hooks-Z3iKjqd1.js.map +1 -0
- package/dist/{copyable-3fdHfMR3.js → copyable-Bmr14W0d.js} +6 -6
- package/dist/{copyable-3fdHfMR3.js.map → copyable-Bmr14W0d.js.map} +1 -1
- package/dist/{data-display-Cmj-xZYl.js → data-display-CWe9SOYh.js} +264 -251
- package/dist/data-display-CWe9SOYh.js.map +1 -0
- package/dist/date-3qsCE1ID.js +209 -0
- package/dist/date-3qsCE1ID.js.map +1 -0
- package/dist/{date-picker-CyQlFYsP.js → date-picker-D1keJQIG.js} +129 -129
- package/dist/date-picker-D1keJQIG.js.map +1 -0
- package/dist/date-pickers-D8aJoeHc.js +185 -0
- package/dist/date-pickers-D8aJoeHc.js.map +1 -0
- package/dist/disclosure-panel-B0HFNZ9x.js.map +1 -1
- package/dist/{display-CT_N2a3w.js → display-VlmP1I0i.js} +23 -46
- package/dist/display-VlmP1I0i.js.map +1 -0
- package/dist/{dropdown-menu-C08iIugv.js → dropdown-menu-B8hjvbkS.js} +9 -9
- package/dist/{dropdown-menu-C08iIugv.js.map → dropdown-menu-B8hjvbkS.js.map} +1 -1
- package/dist/dropzone-CHBNK3de.js +116 -0
- package/dist/dropzone-CHBNK3de.js.map +1 -0
- package/dist/features/activities.js +682 -628
- package/dist/features/activities.js.map +1 -1
- package/dist/features/ai-chat.js +258 -226
- package/dist/features/ai-chat.js.map +1 -1
- package/dist/features/appointment-calendar.js +436 -340
- package/dist/features/appointment-calendar.js.map +1 -1
- package/dist/features/async-preview.js +351 -265
- package/dist/features/async-preview.js.map +1 -1
- package/dist/features/combobox.js +2 -2
- package/dist/features/comments.js +1 -1
- package/dist/features/data-view.js +212 -151
- package/dist/features/data-view.js.map +1 -1
- package/dist/features/email-composer/engine.js +1 -1
- package/dist/features/email-composer.js +344 -315
- package/dist/features/email-composer.js.map +1 -1
- package/dist/features/event-calendar.js +504 -355
- package/dist/features/event-calendar.js.map +1 -1
- package/dist/features/filters.js +2 -2
- package/dist/features/global-search.js +250 -206
- package/dist/features/global-search.js.map +1 -1
- package/dist/features/kanban.js +269 -189
- package/dist/features/kanban.js.map +1 -1
- package/dist/features/map.js +385 -371
- package/dist/features/map.js.map +1 -1
- package/dist/features/media-library.js +1571 -1199
- package/dist/features/media-library.js.map +1 -1
- package/dist/features/mentions.js +2 -2
- package/dist/features/overlays.js +2 -2
- package/dist/features/products.js +1780 -1691
- package/dist/features/products.js.map +1 -1
- package/dist/features/questionnaire.js +165 -152
- package/dist/features/questionnaire.js.map +1 -1
- package/dist/features/resource-assignment.js +223 -191
- package/dist/features/resource-assignment.js.map +1 -1
- package/dist/features/resource.js +55 -220
- package/dist/features/resource.js.map +1 -1
- package/dist/features/rich-text-editor.js +3 -3
- package/dist/features/schema-form.js +280 -228
- package/dist/features/schema-form.js.map +1 -1
- package/dist/features/suggestions.js +48 -39
- package/dist/features/suggestions.js.map +1 -1
- package/dist/features/table.js +2 -2
- package/dist/features/theme-tweaker.js +723 -633
- package/dist/features/theme-tweaker.js.map +1 -1
- package/dist/feedback-DmqmXKLn.js +254 -0
- package/dist/feedback-DmqmXKLn.js.map +1 -0
- package/dist/{field-affordance-recipes-D6H7tVJi.js → field-affordance-recipes-DfbMadot.js} +13 -9
- package/dist/field-affordance-recipes-DfbMadot.js.map +1 -0
- package/dist/{field-state-recipes-7sza8QbC.js → field-state-recipes-EtCxpEy3.js} +6 -2
- package/dist/field-state-recipes-EtCxpEy3.js.map +1 -0
- package/dist/filters-BviMRMLS.js +2692 -0
- package/dist/filters-BviMRMLS.js.map +1 -0
- package/dist/{focus-recipes-B653VaLq.js → focus-recipes-DSkiUvUp.js} +3 -3
- package/dist/focus-recipes-DSkiUvUp.js.map +1 -0
- package/dist/{form-field-CAPdwdnZ.js → form-field-BdfCwSoQ.js} +5 -5
- package/dist/{form-field-CAPdwdnZ.js.map → form-field-BdfCwSoQ.js.map} +1 -1
- package/dist/{form-sizing-CgcrUbLU.js → form-sizing-DE_dZw32.js} +3 -3
- package/dist/{form-sizing-CgcrUbLU.js.map → form-sizing-DE_dZw32.js.map} +1 -1
- package/dist/{forms-B3W8CH7-.js → forms-B8DzJnBN.js} +35 -35
- package/dist/forms-B8DzJnBN.js.map +1 -0
- package/dist/forms-numeric-DOBswjKj.js +992 -0
- package/dist/forms-numeric-DOBswjKj.js.map +1 -0
- package/dist/{header-ZIIsRKxP.js → header-Cq3G0ZRP.js} +100 -95
- package/dist/header-Cq3G0ZRP.js.map +1 -0
- package/dist/{hooks-BitHSh-Y.js → hooks-DHfeSMAO.js} +34 -14
- package/dist/hooks-DHfeSMAO.js.map +1 -0
- package/dist/{http-D_6rOnzU.js → http-Cu-GPpss.js} +61 -35
- package/dist/http-Cu-GPpss.js.map +1 -0
- package/dist/{icon-badge-npxF1SLX.js → icon-badge-B0Kq7wom.js} +3 -3
- package/dist/{icon-badge-npxF1SLX.js.map → icon-badge-B0Kq7wom.js.map} +1 -1
- package/dist/index.js +6 -6
- package/dist/inline-gutter-context-CSqmrMFZ.js +11 -0
- package/dist/inline-gutter-context-CSqmrMFZ.js.map +1 -0
- package/dist/{input-DIREVYHs.js → input-2YrgTUrz.js} +3 -3
- package/dist/{input-DIREVYHs.js.map → input-2YrgTUrz.js.map} +1 -1
- package/dist/{input-7KAc7XQL.js → input-DfJyrjoR.js} +6 -6
- package/dist/{input-7KAc7XQL.js.map → input-DfJyrjoR.js.map} +1 -1
- package/dist/{interaction-recipes-4wZ2tvfb.js → interaction-recipes-DmuS1ase.js} +2 -2
- package/dist/{interaction-recipes-4wZ2tvfb.js.map → interaction-recipes-DmuS1ase.js.map} +1 -1
- package/dist/item-GJ9mvCcg.js +279 -0
- package/dist/item-GJ9mvCcg.js.map +1 -0
- package/dist/layout/app-shell.js +1 -1
- package/dist/layout/auth.js +1 -1
- package/dist/layout/containers.js +1 -1
- package/dist/layout/header.js +1 -1
- package/dist/layout/hooks.js +1 -1
- package/dist/layout/navigation.js +1 -1
- package/dist/layout/page.js +2 -2
- package/dist/layout/settings.js +2 -2
- package/dist/layout/sidebar.js +3 -3
- package/dist/layout/workspace.js +1 -1
- package/dist/layout.js +12 -12
- package/dist/{layout.types-E_GAApzO.js → layout.types-DbtnyAtd.js} +11 -8
- package/dist/layout.types-DbtnyAtd.js.map +1 -0
- package/dist/lib/anchored-positioning.d.ts +11 -0
- package/dist/lib/field-affordance-recipes.d.ts +10 -0
- package/dist/lib/field-state-recipes.d.ts +6 -0
- package/dist/lib/focus-recipes.d.ts +7 -0
- package/dist/lib/format.d.ts +25 -0
- package/dist/lib/money-format.d.ts +6 -0
- package/dist/lib/motion-recipes.d.ts +6 -0
- package/dist/lib/surface-recipes.d.ts +32 -2
- package/dist/lib/theme-scope.d.ts +17 -1
- package/dist/lib/token-merge.generated.d.ts +13 -19
- package/dist/lib/ui-provider/index.d.ts +1 -1
- package/dist/lib/ui-provider/types.d.ts +5 -0
- package/dist/lib/use-controllable-state.d.ts +16 -0
- package/dist/lib/use-copy-feedback.d.ts +15 -0
- package/dist/lib/utils.js +1 -1
- package/dist/lib/variant-props.d.ts +9 -0
- package/dist/main-landmark-context-BAsyqp2I.js +11 -0
- package/dist/main-landmark-context-BAsyqp2I.js.map +1 -0
- package/dist/mentions-zz0ewNIq.js +670 -0
- package/dist/mentions-zz0ewNIq.js.map +1 -0
- package/dist/{message-BJHnn43M.js → message-BiiVrRrm.js} +10 -7
- package/dist/{message-BJHnn43M.js.map → message-BiiVrRrm.js.map} +1 -1
- package/dist/{metadata-list-XkqZ_UXH.js → metadata-list-G85roWjS.js} +13 -12
- package/dist/metadata-list-G85roWjS.js.map +1 -0
- package/dist/{motion-recipes-DitYv6P2.js → motion-recipes-CUc_aHuG.js} +7 -4
- package/dist/motion-recipes-CUc_aHuG.js.map +1 -0
- package/dist/navigation-C0Be5C3i.js +304 -0
- package/dist/navigation-C0Be5C3i.js.map +1 -0
- package/dist/{navigation-Bt-v7rWP.js → navigation-CmqaQR_G.js} +99 -103
- package/dist/navigation-CmqaQR_G.js.map +1 -0
- package/dist/number-NFWKIoiK.js +340 -0
- package/dist/number-NFWKIoiK.js.map +1 -0
- package/dist/{overflow-tab-bar-BQCA2Zn2.js → overflow-tab-bar-DV7HE_3t.js} +8 -8
- package/dist/{overflow-tab-bar-BQCA2Zn2.js.map → overflow-tab-bar-DV7HE_3t.js.map} +1 -1
- package/dist/overlays-D-gAIfPF.js +1018 -0
- package/dist/overlays-D-gAIfPF.js.map +1 -0
- package/dist/page-D4pQhgSq.js +216 -0
- package/dist/page-D4pQhgSq.js.map +1 -0
- package/dist/{page-header-commands-DIKspJfx.js → page-header-commands-elelNOfd.js} +29 -29
- package/dist/{page-header-commands-DIKspJfx.js.map → page-header-commands-elelNOfd.js.map} +1 -1
- package/dist/{pagination-Br8TdV9A.js → pagination-BuSWw1US.js} +22 -23
- package/dist/pagination-BuSWw1US.js.map +1 -0
- package/dist/{popover-k8TdUcAt.js → popover-BpMxbqEK.js} +73 -69
- package/dist/popover-BpMxbqEK.js.map +1 -0
- package/dist/{popover-menu-yn-o0kyA.js → popover-menu-CO-_iiuz.js} +7 -7
- package/dist/{popover-menu-yn-o0kyA.js.map → popover-menu-CO-_iiuz.js.map} +1 -1
- package/dist/{popover.recipes-DJ0AkUan.js → popover.recipes-BqkdvlZn.js} +3 -4
- package/dist/{popover.recipes-DJ0AkUan.js.map → popover.recipes-BqkdvlZn.js.map} +1 -1
- package/dist/{portal-recipes-DyUXqUtD.js → portal-recipes-BPeS4rGB.js} +2 -2
- package/dist/{portal-recipes-DyUXqUtD.js.map → portal-recipes-BPeS4rGB.js.map} +1 -1
- package/dist/primitives-BlC1lXBr.js +447 -0
- package/dist/primitives-BlC1lXBr.js.map +1 -0
- package/dist/primitives.js +4 -4
- package/dist/{progress-DZFXXzPs.js → progress-RARK8AjB.js} +5 -5
- package/dist/{progress-DZFXXzPs.js.map → progress-RARK8AjB.js.map} +1 -1
- package/dist/receipt-CUf2Vegp.js +114 -0
- package/dist/receipt-CUf2Vegp.js.map +1 -0
- package/dist/{rich-text-BnTzZjIo.js → rich-text-Cypm9__d.js} +7 -8
- package/dist/{rich-text-BnTzZjIo.js.map → rich-text-Cypm9__d.js.map} +1 -1
- package/dist/rich-text-editor-Z6cQepsA.js +919 -0
- package/dist/rich-text-editor-Z6cQepsA.js.map +1 -0
- package/dist/rich-text-editor-toolbar-DYbRJARB.js +100 -0
- package/dist/rich-text-editor-toolbar-DYbRJARB.js.map +1 -0
- package/dist/rich-text-tree-DdKHIJx4.js +154 -0
- package/dist/rich-text-tree-DdKHIJx4.js.map +1 -0
- package/dist/safe-image-src-C6kQSMBZ.js +17 -0
- package/dist/safe-image-src-C6kQSMBZ.js.map +1 -0
- package/dist/{scroll-area-Bj6CRUif.js → scroll-area-B9HKbji0.js} +3 -3
- package/dist/{scroll-area-Bj6CRUif.js.map → scroll-area-B9HKbji0.js.map} +1 -1
- package/dist/{separator-DM6gs2vu.js → separator-DaDe26sf.js} +3 -3
- package/dist/separator-DaDe26sf.js.map +1 -0
- package/dist/{separator-B9ewiCGO.js → separator-KGsNXt2J.js} +2 -2
- package/dist/{separator-B9ewiCGO.js.map → separator-KGsNXt2J.js.map} +1 -1
- package/dist/services/actions/action-adapters.d.ts +5 -2
- package/dist/services/actions/index.d.ts +1 -1
- package/dist/services/actions.js +2 -2
- package/dist/services/actions.js.map +1 -1
- package/dist/settings-D5j_RJvT.js +160 -0
- package/dist/settings-D5j_RJvT.js.map +1 -0
- package/dist/sheet-B6j_BE9O.js +241 -0
- package/dist/sheet-B6j_BE9O.js.map +1 -0
- package/dist/{sidebar-CmD6a-HK.js → sidebar-C-iQ_TJP.js} +377 -351
- package/dist/sidebar-C-iQ_TJP.js.map +1 -0
- package/dist/sidebar-D5VO2W8S.js +715 -0
- package/dist/sidebar-D5VO2W8S.js.map +1 -0
- package/dist/{skeleton-DDgdhmu9.js → skeleton-Cab_KgVo.js} +12 -12
- package/dist/skeleton-Cab_KgVo.js.map +1 -0
- package/dist/{smart-card-B6vLxqa_.js → smart-card-C59z6KFO.js} +217 -210
- package/dist/smart-card-C59z6KFO.js.map +1 -0
- package/dist/{structure-DZJ2wbAU.js → structure-DElaQwwN.js} +2 -2
- package/dist/{structure-DZJ2wbAU.js.map → structure-DElaQwwN.js.map} +1 -1
- package/dist/style.css +1 -1
- package/dist/{surface-recipes-C8mNycaY.js → surface-recipes-DV6rrOFq.js} +10 -2
- package/dist/surface-recipes-DV6rrOFq.js.map +1 -0
- package/dist/{table-CXSPHH25.js → table-CSRUgpdK.js} +62 -61
- package/dist/table-CSRUgpdK.js.map +1 -0
- package/dist/table-DdXDBsR_.js +1657 -0
- package/dist/table-DdXDBsR_.js.map +1 -0
- package/dist/{tabs-C4Kr_hCr.js → tabs-WnHfV2pM.js} +27 -27
- package/dist/tabs-WnHfV2pM.js.map +1 -0
- package/dist/{text-inputs-jdkS3ReG.js → text-inputs-ljyBYaCd.js} +112 -112
- package/dist/text-inputs-ljyBYaCd.js.map +1 -0
- package/dist/theme.css +21 -5
- package/dist/timelines-mOmS9Eh3.js +479 -0
- package/dist/timelines-mOmS9Eh3.js.map +1 -0
- package/dist/tooltip-yjX-Uv-p.js +112 -0
- package/dist/tooltip-yjX-Uv-p.js.map +1 -0
- package/dist/{tree-CeYVzdFE.js → tree-YpkxUG2Z.js} +80 -72
- package/dist/tree-YpkxUG2Z.js.map +1 -0
- package/dist/typography/rich-text.js +1 -1
- package/dist/{typography-C7-YMW1S.js → typography-C0dELqYV.js} +46 -40
- package/dist/typography-C0dELqYV.js.map +1 -0
- package/dist/typography.js +1 -1
- package/dist/{ui-provider-C-74NVLc.js → ui-provider-Bu1S-o96.js} +4 -3
- package/dist/ui-provider-Bu1S-o96.js.map +1 -0
- package/dist/ui-provider.js +2 -2
- package/dist/{upload-Hdm5gObf.js → upload-DMuMYJFT.js} +276 -268
- package/dist/upload-DMuMYJFT.js.map +1 -0
- package/dist/{usage-card-9s8hLDfn.js → usage-card-DDPki5P1.js} +57 -54
- package/dist/usage-card-DDPki5P1.js.map +1 -0
- package/dist/use-controllable-state-BlP8SyBI.js +13 -0
- package/dist/use-controllable-state-BlP8SyBI.js.map +1 -0
- package/dist/use-copy-feedback-CzcaqlLf.js +28 -0
- package/dist/use-copy-feedback-CzcaqlLf.js.map +1 -0
- package/dist/use-metric-format-options-Dk4rC1NO.js +251 -0
- package/dist/use-metric-format-options-Dk4rC1NO.js.map +1 -0
- package/dist/{utils-DhuoqFy4.js → utils-BVbAG2J6.js} +98 -76
- package/dist/utils-BVbAG2J6.js.map +1 -0
- package/dist/value-inputs-h5MwjGCo.js +982 -0
- package/dist/value-inputs-h5MwjGCo.js.map +1 -0
- package/dist/value-typography-D15uwfj-.js +154 -0
- package/dist/value-typography-D15uwfj-.js.map +1 -0
- package/dist/workspace-DIryPqBt.js +400 -0
- package/dist/workspace-DIryPqBt.js.map +1 -0
- package/docs/consumer-skill/SKILL.md +7 -0
- package/docs/consumer-skill/agents/themelia-ui-designer.md +11 -2
- package/docs/consumer-skill/examples/analytics.tsx +1 -1
- package/docs/consumer-skill/examples/app-layout.tsx +3 -3
- package/docs/consumer-skill/examples/commerce-lines.tsx +7 -5
- package/docs/consumer-skill/examples/detail.tsx +3 -2
- package/docs/consumer-skill/examples/email-composer.tsx +1 -1
- package/docs/consumer-skill/examples/index-table.tsx +2 -2
- package/docs/consumer-skill/examples/scoped-directory.tsx +7 -6
- package/docs/consumer-skill/references/agents-md.md +20 -16
- package/docs/consumer-skill/references/analytics.md +20 -6
- package/docs/consumer-skill/references/building-views.md +213 -0
- package/docs/consumer-skill/references/catalogue.md +617 -0
- package/docs/consumer-skill/references/component-contracts.json +10202 -18084
- package/docs/consumer-skill/references/composition.md +21 -17
- package/docs/consumer-skill/references/discovery.md +8 -5
- package/docs/consumer-skill/references/installation.md +10 -4
- package/docs/consumer-skill/references/integration.md +5 -5
- package/docs/consumer-skill/references/product-composition.md +2 -2
- package/docs/consumer-skill/references/public-api.json +580 -633
- package/docs/consumer-skill/references/review.md +6 -4
- package/docs/consumer-skill/references/screen-archetypes.md +2 -2
- package/docs/consumer-skill/references/theming.md +1 -1
- package/docs/consumer-skill/references/tokens.json +4 -4
- package/docs/consumer-skill/references/workflows.md +7 -7
- package/docs/consumer-skill/scripts/composition-policy.mjs +40 -20
- package/docs/consumer-skill/scripts/composition.mjs +4 -1
- package/docs/consumer-skill/scripts/discovery.mjs +3 -1
- package/docs/consumer-skill/scripts/setup-skills.mjs +31 -4
- package/docs/consumer-skills/themelia-components/SKILL.md +8 -4
- package/docs/consumer-skills/themelia-composition/SKILL.md +7 -3
- package/docs/consumer-skills/themelia-design/SKILL.md +7 -1
- package/docs/consumer-skills/themelia-tokenization/SKILL.md +1 -1
- package/package.json +9 -12
- package/templates/README.md +3 -2
- package/templates/admin-shell-template.tsx +49 -9
- package/templates/analytics-operations-template.tsx +20 -24
- package/templates/customers-template.tsx +12 -9
- package/templates/index.ts +2 -8
- package/templates/orders-template.tsx +28 -24
- package/templates/products-template.tsx +14 -4
- package/templates/user-permissions-template.tsx +11 -14
- package/dist/accordion-0tQUZ20r.js.map +0 -1
- package/dist/action-menu-C0gjzLyE.js +0 -284
- package/dist/action-menu-C0gjzLyE.js.map +0 -1
- package/dist/ai-artifact-CGGpQryR.js +0 -1200
- package/dist/ai-artifact-CGGpQryR.js.map +0 -1
- package/dist/anchored-positioning-DPnKTvNs.js +0 -6
- package/dist/anchored-positioning-DPnKTvNs.js.map +0 -1
- package/dist/app-shell-EHuuRDGy.js +0 -321
- package/dist/app-shell-EHuuRDGy.js.map +0 -1
- package/dist/auth-B0girIk_.js.map +0 -1
- package/dist/badge-wWauMgAt.js.map +0 -1
- package/dist/base/sheet.js +0 -3
- package/dist/breadcrumbs-Bp9Ke7kd.js.map +0 -1
- package/dist/button-ChBovTx0.js.map +0 -1
- package/dist/buttons-DeW0bQeK.js.map +0 -1
- package/dist/cascader-CrAl9zD5.js +0 -439
- package/dist/cascader-CrAl9zD5.js.map +0 -1
- package/dist/choice-inputs-DHGtx0QV.js.map +0 -1
- package/dist/code-block-BSJyq9e-.js.map +0 -1
- package/dist/collapsible-BzJ91LUG.js +0 -81
- package/dist/collapsible-BzJ91LUG.js.map +0 -1
- package/dist/combobox-Bcvu5J8O.js +0 -363
- package/dist/combobox-Bcvu5J8O.js.map +0 -1
- package/dist/combobox-C2JiSQPc.js +0 -915
- package/dist/combobox-C2JiSQPc.js.map +0 -1
- package/dist/command-9e52NPgK.js +0 -425
- package/dist/command-9e52NPgK.js.map +0 -1
- package/dist/comments-BsgErEqd.js +0 -1174
- package/dist/comments-BsgErEqd.js.map +0 -1
- package/dist/components/base/buttons/tooltip-button.d.ts +0 -7
- package/dist/components/base/display/content-block.d.ts +0 -75
- package/dist/components/base/display/content-block.strings.d.ts +0 -5
- package/dist/components/base/sheet/index.d.ts +0 -29
- package/dist/components/blocks/ai/use-copy-feedback.d.ts +0 -6
- package/dist/components/blocks/data-display/metadata/index.d.ts +0 -30
- package/dist/components/features/mentions/utils/split-html-by-mentions.d.ts +0 -10
- package/dist/components/features/resource/resource.strings.d.ts +0 -12
- package/dist/components/features/rich-text-editor/partials/rich-text-editor-fallback.d.ts +0 -8
- package/dist/components/features/sync/index.d.ts +0 -26
- package/dist/components/features/sync/sync-range-dialog-form.d.ts +0 -5
- package/dist/components/features/sync/sync.strings.d.ts +0 -18
- package/dist/components/features/sync/sync.types.d.ts +0 -44
- package/dist/components/layout/page/partials/page-actions.d.ts +0 -3
- package/dist/components/ui/slot.d.ts +0 -6
- package/dist/containers-CSdc32h9.js.map +0 -1
- package/dist/data-display-Cmj-xZYl.js.map +0 -1
- package/dist/date-Br0FicVv.js +0 -144
- package/dist/date-Br0FicVv.js.map +0 -1
- package/dist/date-picker-CyQlFYsP.js.map +0 -1
- package/dist/date-pickers-tj2MXmXd.js +0 -185
- package/dist/date-pickers-tj2MXmXd.js.map +0 -1
- package/dist/display-CT_N2a3w.js.map +0 -1
- package/dist/features/sync.js +0 -142
- package/dist/features/sync.js.map +0 -1
- package/dist/feedback-Dzo1xtAU.js +0 -246
- package/dist/feedback-Dzo1xtAU.js.map +0 -1
- package/dist/field-affordance-recipes-D6H7tVJi.js.map +0 -1
- package/dist/field-state-recipes-7sza8QbC.js.map +0 -1
- package/dist/filters-Dl80yYtN.js +0 -2415
- package/dist/filters-Dl80yYtN.js.map +0 -1
- package/dist/focus-recipes-B653VaLq.js.map +0 -1
- package/dist/forms-B3W8CH7-.js.map +0 -1
- package/dist/forms-numeric-CwjQJe-O.js +0 -991
- package/dist/forms-numeric-CwjQJe-O.js.map +0 -1
- package/dist/header-ZIIsRKxP.js.map +0 -1
- package/dist/hooks-BitHSh-Y.js.map +0 -1
- package/dist/http-D_6rOnzU.js.map +0 -1
- package/dist/item-FfWnaYST.js +0 -278
- package/dist/item-FfWnaYST.js.map +0 -1
- package/dist/layout.types-E_GAApzO.js.map +0 -1
- package/dist/media-gallery-C81DAnKI.js +0 -203
- package/dist/media-gallery-C81DAnKI.js.map +0 -1
- package/dist/mentions-qOnedSt4.js +0 -639
- package/dist/mentions-qOnedSt4.js.map +0 -1
- package/dist/metadata-list-XkqZ_UXH.js.map +0 -1
- package/dist/motion-recipes-DitYv6P2.js.map +0 -1
- package/dist/navigation-BgtPJAhi.js +0 -288
- package/dist/navigation-BgtPJAhi.js.map +0 -1
- package/dist/navigation-Bt-v7rWP.js.map +0 -1
- package/dist/number-CYqBcrSj.js +0 -346
- package/dist/number-CYqBcrSj.js.map +0 -1
- package/dist/overlays-CC8zI3Du.js +0 -1017
- package/dist/overlays-CC8zI3Du.js.map +0 -1
- package/dist/page-BoQ1VaFJ.js +0 -331
- package/dist/page-BoQ1VaFJ.js.map +0 -1
- package/dist/pagination-Br8TdV9A.js.map +0 -1
- package/dist/popover-k8TdUcAt.js.map +0 -1
- package/dist/primitives-BkkQjYl7.js +0 -385
- package/dist/primitives-BkkQjYl7.js.map +0 -1
- package/dist/receipt-C7LhOg7Q.js +0 -116
- package/dist/receipt-C7LhOg7Q.js.map +0 -1
- package/dist/rich-text-editor-CAurDwT5.js +0 -1273
- package/dist/rich-text-editor-CAurDwT5.js.map +0 -1
- package/dist/rich-text-editor-toolbar-DbXig7Jk.js +0 -99
- package/dist/rich-text-editor-toolbar-DbXig7Jk.js.map +0 -1
- package/dist/rich-text-tree-BqyQ_7-R.js +0 -66
- package/dist/rich-text-tree-BqyQ_7-R.js.map +0 -1
- package/dist/sanitize-html-BWkH4dLM.js +0 -105
- package/dist/sanitize-html-BWkH4dLM.js.map +0 -1
- package/dist/separator-DM6gs2vu.js.map +0 -1
- package/dist/settings-DZPHgpx4.js +0 -155
- package/dist/settings-DZPHgpx4.js.map +0 -1
- package/dist/sheet-C4DHsgLk.js +0 -250
- package/dist/sheet-C4DHsgLk.js.map +0 -1
- package/dist/sidebar-C8BnDwTH.js +0 -709
- package/dist/sidebar-C8BnDwTH.js.map +0 -1
- package/dist/sidebar-CmD6a-HK.js.map +0 -1
- package/dist/skeleton-DDgdhmu9.js.map +0 -1
- package/dist/slot-CLF9kLrS.js +0 -16
- package/dist/slot-CLF9kLrS.js.map +0 -1
- package/dist/smart-card-B6vLxqa_.js.map +0 -1
- package/dist/surface-recipes-C8mNycaY.js.map +0 -1
- package/dist/table-CBonSdTp.js +0 -1584
- package/dist/table-CBonSdTp.js.map +0 -1
- package/dist/table-CXSPHH25.js.map +0 -1
- package/dist/tabs-C4Kr_hCr.js.map +0 -1
- package/dist/text-inputs-jdkS3ReG.js.map +0 -1
- package/dist/timelines-CoPwdJP0.js +0 -458
- package/dist/timelines-CoPwdJP0.js.map +0 -1
- package/dist/tooltip-31NwIpTo.js +0 -113
- package/dist/tooltip-31NwIpTo.js.map +0 -1
- package/dist/tree-CeYVzdFE.js.map +0 -1
- package/dist/typography-C7-YMW1S.js.map +0 -1
- package/dist/ui-provider-C-74NVLc.js.map +0 -1
- package/dist/upload-Hdm5gObf.js.map +0 -1
- package/dist/upload-queue-D0sYPuqo.js +0 -409
- package/dist/upload-queue-D0sYPuqo.js.map +0 -1
- package/dist/usage-card-9s8hLDfn.js.map +0 -1
- package/dist/utils-DhuoqFy4.js.map +0 -1
- package/dist/value-inputs-D3aPgq9H.js +0 -980
- package/dist/value-inputs-D3aPgq9H.js.map +0 -1
- package/dist/value-typography-uSzzG9Gf.js +0 -122
- package/dist/value-typography-uSzzG9Gf.js.map +0 -1
- package/dist/workspace-CC8Vchiu.js +0 -411
- package/dist/workspace-CC8Vchiu.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appointment-calendar.js","names":["_Fragment","useFormattingConfig","useDatesConfig","cn","Button","Text","Heading","headingRoleSizes","focusRecipes","Stack","toneRecipes","dotRecipes","AlertDescription","AlertAction","Alert","Card","AlertTitle","ErrorState","compositionClasses","ActionMenu","Skeleton","interactionRecipes","formatInitials","AvatarFallback","Avatar","AvatarImage","Badge","Select","VisuallyHidden","ScrollArea","ItemDescription","ItemActions","ItemContent","Item","ItemTitle","TabsTrigger","TabsList","Tabs","EmptyState","Fragment$1","defaultAppointmentCalendarStrings","count","staffName","time","start","end","date","title","CHART_SERIES","appointmentCategoryColorClasses","categoryColor","index","categories","category","id","startOfDay","addDays","days","isSameDay","a","b","addMonths","target","months","lastDay","startOfWeek","day","weekStartsOn","weekDays","first","monthGrid","week","occursOn","dayStart","dayEnd","appointment","appointmentsOn","appointments","filterAppointments","staffId","findConflicts","byStaff","list","conflicts","sorted","group","groupEnd","flush","conflictingIds","conflict","staffFrom","seen","formatTime","locale","hour12","options","personName","person","STATUS_TONE","AppointmentRow","useId","client","staff","context","hasActions","labelledBy","openRef","useRef","actionsHadFocus","useLayoutEffect","open","event","AppointmentAgenda","groups","total","sum","dayFormat","grouped","contextFor","actions","appointmentActions","action","strings","onAppointmentClick","items","renderAppointment","body","loading","error","isValidElement","heading","MAX_DOTS","AppointmentMonth","focused","setFocused","useState","selected","gridRef","focusOnRender","today","useMemo","visibleMonth","useEffect","onVisibleMonthChange","weeks","monthFormat","weekdayFormat","monthOptions","month","yearOptions","years","min","max","moveTo","select","onSelect","changeMonth","next","ChevronLeft","value","ChevronRight","move","dayAppointments","dayCategories","isSelected","isFocused","outside","useControllable","local","setLocal","fallback","onChange","AppointmentCalendar","staffProp","dateProp","viewProp","categoryProp","staffIdProp","weekStartsOnProp","stringsProp","useStrings","dates","setDate","defaultDate","onDateChange","view","setView","defaultView","onViewChange","setCategory","defaultCategory","onCategoryChange","setStaffId","defaultStaffId","onStaffIdChange","onStaffChange","dismissed","setDismissed","setVisibleMonth","visible","range","edges","reportedRange","key","onRangeChange","inRange","conflictIds","visibleConflicts","booked","conflictKey","showAlert","headingFormat","rangeFormat","dismissConflicts","onConflictsDismiss","shown","className","option","onCreateAppointment","Plus","TriangleAlert"],"sources":["../../src/components/features/appointment-calendar/appointment-calendar.types.ts","../../src/components/features/appointment-calendar/appointment-calendar.utils.ts","../../src/components/features/appointment-calendar/partials/appointment-agenda.tsx","../../src/components/features/appointment-calendar/partials/appointment-month.tsx","../../src/components/features/appointment-calendar/appointment-calendar.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport type { ActionMenuAction } from '../../base/action-menu';\nimport type { BadgeTone } from '../../base/badge';\nimport type { StringsProp } from '../../../lib/strings';\n\n/** Where an appointment stands. Conflicts are derived, never a status. */\nexport type AppointmentStatus = 'confirmed' | 'pending' | 'completed' | 'cancelled' | 'noShow';\n\n/** The day agenda or the seven-day week agenda beside the month. */\nexport type AppointmentCalendarView = 'day' | 'week';\n\n/**\n * Categorical colour for a service category. Categories are kinds, not\n * statuses, so they draw from the chart series palette and never from the\n * success, warning or destructive tones that status chips own.\n */\nexport type AppointmentCategoryColor = 'chart-1' | 'chart-2' | 'chart-3' | 'chart-4' | 'chart-5';\n\n/** A service category: its label, filter chip and marker colour. */\nexport interface AppointmentCategory {\n\t/** Stable identity, referenced by `Appointment.category`. */\n\tid: string;\n\t/** Chip and legend label. */\n\tlabel: string;\n\t/** Marker colour. Defaults to the chart series by the category's position. */\n\tcolor?: AppointmentCategoryColor;\n}\n\n/** A person on an appointment: the staff member who delivers it, or the client. */\nexport interface AppointmentPerson {\n\t/** Stable identity. Staff overlap is detected by this id. */\n\tid: string;\n\t/** Display name. */\n\tname: string;\n\t/** Portrait. Initials stand in without one, or when it fails to load. */\n\tavatarUrl?: string;\n}\n\n/** One booked slot. The calendar formats it; it never fetches or saves. */\nexport interface Appointment {\n\t/** Stable identity. */\n\tid: string;\n\t/** The service: \"Cut and blow-dry\". */\n\ttitle: string;\n\t/** Start of the slot. */\n\tstart: Date;\n\t/** End of the slot; later than `start`. */\n\tend: Date;\n\t/** Category id, matching an `AppointmentCategory`. */\n\tcategory: string;\n\t/** Booking state. Cancelled appointments are listed but never conflict. */\n\tstatus: AppointmentStatus;\n\t/** Who the appointment is for, shown after the time. */\n\tclient?: AppointmentPerson | string;\n\t/** Who delivers it. Two overlapping appointments for one staff member conflict. */\n\tstaff?: AppointmentPerson;\n}\n\n/** The days on screen: the month grid and the agenda. `end` is exclusive (midnight after the last day). */\nexport interface AppointmentDateRange {\n\tstart: Date;\n\tend: Date;\n}\n\n/** Overlapping appointments for one staff member. */\nexport interface AppointmentConflict<T extends Appointment = Appointment> {\n\t/** The double-booked staff member. */\n\tstaff: AppointmentPerson;\n\t/** The appointments that overlap, earliest first. */\n\tappointments: T[];\n\t/** When the overlap begins. */\n\tstart: Date;\n}\n\nexport interface AppointmentCalendarStrings {\n\t/** Booked count beside the title: \"8 booked\". */\n\tformatBooked: (count: number) => string;\n\t/** Conflict count beside the title: \"2 conflicts\". */\n\tformatConflicts: (count: number) => string;\n\t/** Accessible name of the Day/Week switch. */\n\tviewLabel: string;\n\tday: string;\n\tweek: string;\n\t/** Accessible name of the staff filter. */\n\tstaffLabel: string;\n\t/** The staff filter's \"everyone\" option. */\n\tallStaff: string;\n\t/** Primary command. */\n\tnewAppointment: string;\n\t/** Conflict alert title. */\n\tconflictTitle: string;\n\t/** One overlapping-booking sentence per double-booked staff member. */\n\tformatConflict: (staffName: string, count: number, time: string) => string;\n\t/** Hides the conflict alert. */\n\tdismiss: string;\n\tpreviousMonth: string;\n\tnextMonth: string;\n\t/** Accessible name of the month select. */\n\tmonthLabel: string;\n\t/** Accessible name of the year select. */\n\tyearLabel: string;\n\t/** Accessible name of the category filter. */\n\tcategoriesLabel: string;\n\t/** The category filter's \"every category\" chip. */\n\tallCategories: string;\n\t/** Count beside the agenda heading: \"8 appointments\". */\n\tformatCount: (count: number) => string;\n\t/** A slot: \"9 AM to 10 AM\". Receives already formatted times. */\n\tformatTimeRange: (start: string, end: string) => string;\n\t/** Accessible day label in the month: \"Tuesday, June 9, 3 appointments\". */\n\tformatDayLabel: (date: string, count: number) => string;\n\t/** Agenda heading for the week view: \"June 8 to 14\". */\n\tformatWeekRange: (start: string, end: string) => string;\n\t/** Status chip words. */\n\tstatus: Record<AppointmentStatus, string>;\n\t/** Chip shown instead of the status when an appointment overlaps another. */\n\tconflict: string;\n\t/** Agenda copy when nothing matches the day or week. */\n\tempty: string;\n\t/** Loading copy for assistive technology. */\n\tloading: string;\n\t/** Default error state title. */\n\terrorTitle: string;\n\t/** Default error state description, when `error` carries no message. */\n\terrorDescription: string;\n\t/** Retry command in the default error state. */\n\tretry: string;\n\t/** Accessible name of an appointment's actions menu: \"Actions for Balayage\". */\n\tformatActionsLabel: (title: string) => string;\n}\n\nexport const defaultAppointmentCalendarStrings: AppointmentCalendarStrings = {\n\tformatBooked: (count) => `${count} booked`,\n\tformatConflicts: (count) => (count === 1 ? '1 conflict' : `${count} conflicts`),\n\tviewLabel: 'View',\n\tday: 'Day',\n\tweek: 'Week',\n\tstaffLabel: 'Staff',\n\tallStaff: 'All staff',\n\tnewAppointment: 'New appointment',\n\tconflictTitle: 'Double-booked',\n\tformatConflict: (staffName, count, time) => `${staffName} has ${count} overlapping bookings at ${time}.`,\n\tdismiss: 'Dismiss',\n\tpreviousMonth: 'Previous month',\n\tnextMonth: 'Next month',\n\tmonthLabel: 'Month',\n\tyearLabel: 'Year',\n\tcategoriesLabel: 'Categories',\n\tallCategories: 'All',\n\tformatCount: (count) => (count === 1 ? '1 appointment' : `${count} appointments`),\n\tformatTimeRange: (start, end) => `${start} to ${end}`,\n\tformatDayLabel: (date, count) => (count === 0 ? date : `${date}, ${count === 1 ? '1 appointment' : `${count} appointments`}`),\n\tformatWeekRange: (start, end) => `${start} to ${end}`,\n\tstatus: { confirmed: 'Confirmed', pending: 'Pending', completed: 'Completed', cancelled: 'Cancelled', noShow: 'No-show' },\n\tconflict: 'Conflict',\n\tempty: 'No appointments',\n\tloading: 'Loading appointments',\n\terrorTitle: 'Appointments unavailable',\n\terrorDescription: 'The appointments could not be loaded.',\n\tretry: 'Retry',\n\tformatActionsLabel: (title) => `Actions for ${title}`,\n};\n\n/** What the calendar has worked out for one appointment, handed to `renderAppointment`. */\nexport interface AppointmentRenderContext {\n\t/** The appointment's category, when one matches. */\n\tcategory?: AppointmentCategory;\n\t/** The category's marker class (`bg-chart-N`), for a stripe or dot of your own. */\n\tcategoryColorClass: string;\n\t/** Whether it overlaps another booking for the same staff member. */\n\tconflict: boolean;\n\t/** The status chip's word, or the conflict word when it overlaps. */\n\tstatusLabel: string;\n\t/** The status chip's tone: destructive for a conflict, otherwise the status tone. */\n\tstatusTone: BadgeTone;\n\t/** The formatted slot: \"09:00 to 10:00\". */\n\ttime: string;\n\t/** Opens it through `onAppointmentClick`. Undefined when rows are not interactive. */\n\topen?: () => void;\n\t/** The visible commands `appointmentActions` returned for it. */\n\tactions: readonly ActionMenuAction[];\n\t/** The built-in actions menu for those commands, or null when there are none. */\n\tactionsMenu: ReactNode;\n\t/** The built-in row, to wrap or extend instead of replacing. */\n\tdefaultRender: () => ReactNode;\n}\n\n/**\n * Props for `AppointmentCalendar`. `T` is the app's own appointment type: extra\n * fields such as a price or notes come back, typed, in every callback.\n */\nexport interface AppointmentCalendarProps<T extends Appointment = Appointment> {\n\t/** Appointments to place. The calendar filters and formats; it never fetches. */\n\tappointments: T[];\n\t/** Service categories: filter chips, markers and day dots. */\n\tcategories: AppointmentCategory[];\n\t/** Staff offered by the staff filter. Defaults to the staff found on appointments. */\n\tstaff?: AppointmentPerson[];\n\t/** Heading above the calendar: the location or calendar name. */\n\ttitle?: ReactNode;\n\t/** Selected day. Controlled with `onDateChange`. */\n\tdate?: Date;\n\t/** Selected day for uncontrolled use. Defaults to today. */\n\tdefaultDate?: Date;\n\t/** Fired when a day is chosen or the month moves. */\n\tonDateChange?: (date: Date) => void;\n\t/** Day or week agenda. Controlled with `onViewChange`. */\n\tview?: AppointmentCalendarView;\n\t/** View for uncontrolled use. Defaults to `day`. */\n\tdefaultView?: AppointmentCalendarView;\n\t/** Fired when the Day/Week switch changes. */\n\tonViewChange?: (view: AppointmentCalendarView) => void;\n\t/** Category filter: a category id, or `all`. Controlled with `onCategoryChange`. */\n\tcategory?: string;\n\t/** Category filter for uncontrolled use. Defaults to `all`. */\n\tdefaultCategory?: string;\n\t/** Fired when a category chip is chosen. */\n\tonCategoryChange?: (category: string) => void;\n\t/** Staff filter: a staff id, or `all`. Controlled with `onStaffIdChange`. */\n\tstaffId?: string;\n\t/** Staff filter for uncontrolled use. Defaults to `all`. */\n\tdefaultStaffId?: string;\n\t/** Fired when the staff filter changes. Takes precedence over `onStaffChange`. */\n\tonStaffIdChange?: (staffId: string) => void;\n\t/** Legacy alias for `onStaffIdChange`. */\n\tonStaffChange?: (staffId: string) => void;\n\t/** Fired when an appointment is activated. Without it, rows are not interactive. */\n\tonAppointmentClick?: (appointment: T) => void;\n\t/**\n\t * Commands for one appointment, such as confirm, reschedule or cancel,\n\t * offered in a menu at the end of its row. Return an empty list for none.\n\t */\n\tappointmentActions?: (appointment: T) => readonly ActionMenuAction[];\n\t/**\n\t * Renders one appointment in the agenda instead of the built-in row. The\n\t * context carries its category colour, conflict, time, `open`, its actions\n\t * and a ready actions menu, and `defaultRender` for the built-in row.\n\t */\n\trenderAppointment?: (appointment: T, context: AppointmentRenderContext) => ReactNode;\n\t/**\n\t * Fired with the days on screen, the month grid and the agenda together, once\n\t * on mount and whenever they change. Load appointments for this range.\n\t */\n\tonRangeChange?: (range: AppointmentDateRange) => void;\n\t/** Shows the primary \"New appointment\" command; receives the selected day. */\n\tonCreateAppointment?: (date: Date) => void;\n\t/** Fired when the conflict alert is dismissed, with the conflicts it showed. */\n\tonConflictsDismiss?: (conflicts: AppointmentConflict<T>[]) => void;\n\t/** Shows the loading state in the agenda. */\n\tloading?: boolean;\n\t/**\n\t * Shows the error state in the agenda. A string or Error becomes its\n\t * description; any other element replaces the default state.\n\t */\n\terror?: ReactNode | Error;\n\t/** Adds Retry to the default error state. */\n\tonRetry?: () => void;\n\t/** First column of the month and first day of the week. Defaults to the provider, then Sunday. */\n\tweekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n\t/** Overrides this calendar's own copy. */\n\tstrings?: StringsProp<AppointmentCalendarStrings>;\n\t/** Merged onto the root. */\n\tclassName?: string;\n}\n","/**\n * Pure helpers for the appointment calendar: day arithmetic, filtering,\n * conflict detection and time formatting. No React, so they are testable and\n * reusable by an application that pre-computes its own view.\n */\nimport type {\n\tAppointment,\n\tAppointmentCategory,\n\tAppointmentCategoryColor,\n\tAppointmentConflict,\n\tAppointmentPerson,\n} from './appointment-calendar.types';\n\nconst CHART_SERIES: AppointmentCategoryColor[] = ['chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5'];\n\n/** Marker colour classes per chart series. Literal so Tailwind generates them. */\nexport const appointmentCategoryColorClasses: Record<AppointmentCategoryColor, string> = {\n\t'chart-1': 'bg-chart-1',\n\t'chart-2': 'bg-chart-2',\n\t'chart-3': 'bg-chart-3',\n\t'chart-4': 'bg-chart-4',\n\t'chart-5': 'bg-chart-5',\n};\n\n/** A category's colour: its own, or the chart series at its position. */\nexport function categoryColor(categories: AppointmentCategory[], id: string): AppointmentCategoryColor {\n\tconst index = categories.findIndex((category) => category.id === id);\n\tif (index < 0) return 'chart-1';\n\treturn categories[index]?.color ?? CHART_SERIES[index % CHART_SERIES.length] ?? 'chart-1';\n}\n\nexport function startOfDay(date: Date): Date {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nexport function addDays(date: Date, days: number): Date {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n\treturn a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\n/** The same day of the month in another month, clamped to that month's length. */\nexport function addMonths(date: Date, months: number): Date {\n\tconst target = new Date(date.getFullYear(), date.getMonth() + months, 1);\n\tconst lastDay = new Date(target.getFullYear(), target.getMonth() + 1, 0).getDate();\n\treturn new Date(target.getFullYear(), target.getMonth(), Math.min(date.getDate(), lastDay));\n}\n\nexport function startOfWeek(date: Date, weekStartsOn: number): Date {\n\tconst day = startOfDay(date);\n\treturn addDays(day, -((day.getDay() - weekStartsOn + 7) % 7));\n}\n\n/** The seven days of the week that holds `date`. */\nexport function weekDays(date: Date, weekStartsOn: number): Date[] {\n\tconst first = startOfWeek(date, weekStartsOn);\n\treturn Array.from({ length: 7 }, (_, index) => addDays(first, index));\n}\n\n/** Six full weeks covering the month of `date`, so the grid never changes height. */\nexport function monthGrid(date: Date, weekStartsOn: number): Date[][] {\n\tconst first = startOfWeek(new Date(date.getFullYear(), date.getMonth(), 1), weekStartsOn);\n\treturn Array.from({ length: 6 }, (_, week) => Array.from({ length: 7 }, (_, day) => addDays(first, week * 7 + day)));\n}\n\n/** Whether an appointment touches a day (it may run past midnight). */\nexport function occursOn(appointment: Appointment, day: Date): boolean {\n\tconst dayStart = startOfDay(day).getTime();\n\tconst dayEnd = addDays(day, 1).getTime();\n\treturn appointment.start.getTime() < dayEnd && appointment.end.getTime() > dayStart;\n}\n\nexport function appointmentsOn<T extends Appointment>(appointments: T[], day: Date): T[] {\n\treturn appointments\n\t\t.filter((appointment) => occursOn(appointment, day))\n\t\t.sort((a, b) => a.start.getTime() - b.start.getTime() || a.end.getTime() - b.end.getTime());\n}\n\n/** Applies the category and staff filters; `all` keeps everything. */\nexport function filterAppointments<T extends Appointment>(appointments: T[], category: string, staffId: string): T[] {\n\treturn appointments.filter((appointment) =>\n\t\t(category === 'all' || appointment.category === category) &&\n\t\t(staffId === 'all' || appointment.staff?.id === staffId),\n\t);\n}\n\n/**\n * Overlapping appointments per staff member. Two appointments conflict when\n * the same staff member is booked for both and their times overlap; touching\n * ends (10:00 to 10:00) do not overlap, and cancelled appointments never conflict.\n */\nexport function findConflicts<T extends Appointment>(appointments: T[]): AppointmentConflict<T>[] {\n\tconst byStaff = new Map<string, T[]>();\n\tfor (const appointment of appointments) {\n\t\tif (!appointment.staff || appointment.status === 'cancelled') continue;\n\t\tconst list = byStaff.get(appointment.staff.id) ?? [];\n\t\tlist.push(appointment);\n\t\tbyStaff.set(appointment.staff.id, list);\n\t}\n\tconst conflicts: AppointmentConflict<T>[] = [];\n\tfor (const list of byStaff.values()) {\n\t\tconst sorted = [...list].sort((a, b) => a.start.getTime() - b.start.getTime());\n\t\tlet group: T[] = [];\n\t\tlet groupEnd = -Infinity;\n\t\tconst flush = () => {\n\t\t\tconst first = group[0];\n\t\t\tif (group.length > 1 && first?.staff) conflicts.push({ staff: first.staff, appointments: group, start: first.start });\n\t\t};\n\t\tfor (const appointment of sorted) {\n\t\t\tif (appointment.start.getTime() < groupEnd) {\n\t\t\t\tgroup.push(appointment);\n\t\t\t\tgroupEnd = Math.max(groupEnd, appointment.end.getTime());\n\t\t\t} else {\n\t\t\t\tflush();\n\t\t\t\tgroup = [appointment];\n\t\t\t\tgroupEnd = appointment.end.getTime();\n\t\t\t}\n\t\t}\n\t\tflush();\n\t}\n\treturn conflicts.sort((a, b) => a.start.getTime() - b.start.getTime());\n}\n\n/** Ids of every appointment that takes part in a conflict. */\nexport function conflictingIds(conflicts: AppointmentConflict[]): Set<string> {\n\treturn new Set(conflicts.flatMap((conflict) => conflict.appointments.map((appointment) => appointment.id)));\n}\n\n/** Distinct staff found on appointments, in first-seen order. */\nexport function staffFrom(appointments: Appointment[]): AppointmentPerson[] {\n\tconst seen = new Map<string, AppointmentPerson>();\n\tfor (const appointment of appointments) if (appointment.staff && !seen.has(appointment.staff.id)) seen.set(appointment.staff.id, appointment.staff);\n\treturn [...seen.values()];\n}\n\n/**\n * \"9 AM\", or \"9:30 AM\" when the minutes matter. A 24-hour clock always keeps\n * its minutes (\"09:00\"), since a bare \"09\" does not read as a time.\n */\nexport function formatTime(date: Date, locale?: string): string {\n\tconst { hour12 } = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions();\n\tif (!hour12) return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit' }).format(date);\n\tconst options: Intl.DateTimeFormatOptions = date.getMinutes() === 0 ? { hour: 'numeric' } : { hour: 'numeric', minute: '2-digit' };\n\treturn new Intl.DateTimeFormat(locale, options).format(date);\n}\n\nexport function personName(person: AppointmentPerson | string | undefined): string | undefined {\n\treturn typeof person === 'string' ? person : person?.name;\n}\n","/**\n * AppointmentAgenda — the list beside the month: one day's appointments, or\n * the selected week grouped by day. Each row shows its category stripe, the\n * service with its status chip (or the conflict chip when it overlaps another\n * booking for the same staff member), the time range and client, and the\n * staff member's avatar. A row opens only when the app can open it: a\n * transparent button stretched over the row takes the click, and the actions\n * menu sits above it, since a button cannot hold another. Private to the\n * appointment calendar.\n */\nimport { isValidElement, useId, useLayoutEffect, useRef, type ReactNode } from 'react';\n\nimport { ActionMenu, type ActionMenuAction } from '../../../base/action-menu';\nimport { Avatar, AvatarFallback, AvatarImage } from '../../../base/avatar';\nimport { Badge, type BadgeTone } from '../../../base/badge';\nimport { Card } from '../../../base/cards';\nimport { ScrollArea, VisuallyHidden } from '../../../base/display';\nimport { ErrorState } from '../../../base/feedback';\nimport { Item, ItemActions, ItemContent, ItemDescription, ItemTitle } from '../../../base/item';\nimport { Skeleton } from '../../../base/skeleton';\nimport { Stack } from '../../../base/structure';\nimport { formatInitials } from '../../../primitives';\nimport { Heading, Text } from '../../../typography';\nimport {headingRoleSizes} from '../../../typography/text.styles';\nimport { EmptyState } from '../../../blocks/data-display';\nimport { focusRecipes } from '../../../../lib/focus-recipes';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { toneRecipes } from '../../../../lib/tone-recipes';\nimport { cn } from '../../../../lib/utils';\n\nimport type {\n\tAppointment,\n\tAppointmentCalendarStrings,\n\tAppointmentCategory,\n\tAppointmentRenderContext,\n\tAppointmentStatus,\n} from '../appointment-calendar.types';\nimport {\n\tappointmentCategoryColorClasses,\n\tappointmentsOn,\n\tcategoryColor,\n\tformatTime,\n\tpersonName,\n} from '../appointment-calendar.utils';\n\n/** Status chip tones. Completed and cancelled are history, not a state to act on. */\nconst STATUS_TONE: Record<AppointmentStatus, BadgeTone> = {\n\tconfirmed: 'success',\n\tpending: 'warning',\n\tcompleted: 'neutral',\n\tcancelled: 'neutral',\n\tnoShow: 'destructive',\n};\n\nexport interface AppointmentAgendaProps {\n\t/** The days to list: one for the day view, seven for the week view. */\n\tdays: Date[];\n\t/** Appointments after the category and staff filters. */\n\tappointments: Appointment[];\n\tcategories: AppointmentCategory[];\n\t/** Ids of appointments that overlap another booking for the same staff member. */\n\tconflicts: Set<string>;\n\theading: string;\n\tloading: boolean;\n\terror?: ReactNode | Error;\n\tonRetry?: () => void;\n\tlocale?: string;\n\tonAppointmentClick?: (appointment: Appointment) => void;\n\tappointmentActions?: (appointment: Appointment) => readonly ActionMenuAction[];\n\trenderAppointment?: (appointment: Appointment, context: AppointmentRenderContext) => ReactNode;\n\tstrings: AppointmentCalendarStrings;\n}\n\ntype RowContext = Omit<AppointmentRenderContext, 'defaultRender'>;\n\n/** The built-in row, drawn from the same context a custom row receives. */\nfunction AppointmentRow({ appointment, context }: { appointment: Appointment; context: RowContext }) {\n\tconst id = useId();\n\tconst client = personName(appointment.client);\n\tconst staff = appointment.staff;\n\tconst { open, conflict } = context;\n\tconst hasActions = context.actions.length > 0;\n\t// The open button is named by the row's own visible copy and the staff name,\n\t// one part per id so the title and its chip read as separate words.\n\tconst labelledBy = [`${id}-title`, `${id}-status`, `${id}-detail`, staff && `${id}-staff`].filter(Boolean).join(' ');\n\tconst openRef = useRef<HTMLButtonElement>(null);\n\tconst actionsHadFocus = useRef(false);\n\n\t// A command can remove the row's last action, and the menu trigger with it.\n\t// Focus then returns to the row's open button instead of falling to the page.\n\tuseLayoutEffect(() => {\n\t\tif (hasActions || !actionsHadFocus.current) return;\n\t\tactionsHadFocus.current = false;\n\t\tif (!document.activeElement || document.activeElement === document.body) openRef.current?.focus();\n\t}, [hasActions]);\n\n\treturn (\n\t\t<Item\n\t\t\tvariant=\"outline\"\n\t\t\tsize=\"sm\"\n\t\t\tpadding=\"default\"\n\t\t\tdata-status={appointment.status}\n\t\t\tdata-conflict={conflict ? '' : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t'appointment-agenda--row relative w-full flex-nowrap',\n\t\t\t\t!!open && interactionRecipes.rowHover,\n\t\t\t\tconflict && cn(toneRecipes.destructive.wash, toneRecipes.destructive.edge),\n\t\t\t)}\n\t\t>\n\t\t\t{!!open && (\n\t\t\t\t<button\n\t\t\t\t\tref={openRef}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-labelledby={labelledBy}\n\t\t\t\t\tonClick={open}\n\t\t\t\t\tclassName={cn('appointment-agenda--open absolute inset-0 z-0 cursor-pointer rounded-radius focus-visible:outline-none', interactionRecipes.nativeButtonReset, focusRecipes.inset)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{/* The category stripe: a categorical mark, so it draws from the chart palette. */}\n\t\t\t<span aria-hidden=\"true\" className={cn('appointment-agenda--stripe w-1 shrink-0 self-stretch rounded-full', context.categoryColorClass)} />\n\t\t\t<ItemContent className=\"min-w-0\">\n\t\t\t\t<ItemTitle className=\"flex-wrap\">\n\t\t\t\t\t<Text type=\"inherit\" id={`${id}-title`} tag=\"span\" weight=\"medium\" className=\"truncate\">{appointment.title}</Text>\n\t\t\t\t\t<Badge id={`${id}-status`} tone={context.statusTone} size=\"sm\">\n\t\t\t\t\t\t{context.statusLabel}\n\t\t\t\t\t</Badge>\n\t\t\t\t</ItemTitle>\n\t\t\t\t<ItemDescription id={`${id}-detail`} clamp={1}>\n\t\t\t\t\t{client ? `${context.time} · ${client}` : context.time}\n\t\t\t\t</ItemDescription>\n\t\t\t</ItemContent>\n\t\t\t{(!!staff || hasActions) && (\n\t\t\t\t<ItemActions\n\t\t\t\t\t// React focus events bubble from the portaled menu, so this tracks the trigger and its menu together.\n\t\t\t\t\tonFocus={() => { actionsHadFocus.current = true; }}\n\t\t\t\t\tonBlur={(event) => {\n\t\t\t\t\t\tif (event.relatedTarget instanceof Node && !event.currentTarget.contains(event.relatedTarget)) actionsHadFocus.current = false;\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{!!staff && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<VisuallyHidden><span id={`${id}-staff`}>{staff.name}</span></VisuallyHidden>\n\t\t\t\t\t\t\t<Avatar size=\"sm\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t{!!staff.avatarUrl && <AvatarImage src={staff.avatarUrl} alt=\"\" />}\n\t\t\t\t\t\t\t\t<AvatarFallback>{formatInitials(staff.name)}</AvatarFallback>\n\t\t\t\t\t\t\t</Avatar>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t\t{context.actionsMenu}\n\t\t\t\t</ItemActions>\n\t\t\t)}\n\t\t</Item>\n\t);\n}\n\nexport function AppointmentAgenda({ days, appointments, categories, conflicts, heading, loading, error, onRetry, locale, onAppointmentClick, appointmentActions, renderAppointment, strings }: AppointmentAgendaProps) {\n\tconst groups = days.map((day) => ({ day, items: appointmentsOn(appointments, day) }));\n\tconst total = groups.reduce((sum, group) => sum + group.items.length, 0);\n\tconst dayFormat = new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric' });\n\tconst grouped = days.length > 1;\n\n\t// One context per appointment: the built-in row draws from it, and a custom\n\t// row receives the same values, so both stay consistent.\n\tconst contextFor = (appointment: Appointment): AppointmentRenderContext => {\n\t\tconst conflict = conflicts.has(appointment.id);\n\t\tconst actions = (appointmentActions?.(appointment) ?? []).filter((action) => action.visible !== false);\n\t\tconst context: RowContext = {\n\t\t\tcategory: categories.find((category) => category.id === appointment.category),\n\t\t\tcategoryColorClass: appointmentCategoryColorClasses[categoryColor(categories, appointment.category)],\n\t\t\tconflict,\n\t\t\tstatusLabel: conflict ? strings.conflict : strings.status[appointment.status],\n\t\t\tstatusTone: conflict ? 'destructive' : STATUS_TONE[appointment.status],\n\t\t\ttime: strings.formatTimeRange(formatTime(appointment.start, locale), formatTime(appointment.end, locale)),\n\t\t\topen: onAppointmentClick ? () => onAppointmentClick(appointment) : undefined,\n\t\t\tactions,\n\t\t\t// Above a stretched open button, so the menu takes its own clicks.\n\t\t\tactionsMenu: actions.length > 0 ? (\n\t\t\t\t<ActionMenu\n\t\t\t\t\tactions={actions}\n\t\t\t\t\tsrText={strings.formatActionsLabel(appointment.title)}\n\t\t\t\t\tbuttonProps={{ size: 'sm', className: 'appointment-agenda--actions relative z-10' }}\n\t\t\t\t/>\n\t\t\t) : null,\n\t\t};\n\t\treturn { ...context, defaultRender: () => <AppointmentRow appointment={appointment} context={context} /> };\n\t};\n\n\tconst list = (items: Appointment[]) => (\n\t\t<Stack render={<ul />} gap=\"sm\" className=\"appointment-agenda--list m-0 list-none p-0\">\n\t\t\t{items.map((appointment) => {\n\t\t\t\tconst context = contextFor(appointment);\n\t\t\t\treturn (\n\t\t\t\t\t<li key={appointment.id} className=\"min-w-0\">\n\t\t\t\t\t\t{renderAppointment ? renderAppointment(appointment, context) : context.defaultRender()}\n\t\t\t\t\t</li>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Stack>\n\t);\n\n\tlet body;\n\tif (loading) {\n\t\tbody = (\n\t\t\t<Stack gap=\"sm\" aria-busy=\"true\" className=\"appointment-agenda--loading\">\n\t\t\t\t<VisuallyHidden>{strings.loading}</VisuallyHidden>\n\t\t\t\t{Array.from({ length: 4 }, (_, index) => <Skeleton key={index} className=\"h-control-lg w-full rounded-radius\" />)}\n\t\t\t</Stack>\n\t\t);\n\t} else if (error) {\n\t\t// An app's own element replaces the default; a message becomes its description.\n\t\tbody = isValidElement(error) ? error : (\n\t\t\t<ErrorState\n\t\t\t\tvariant=\"inline\"\n\t\t\t\ttitle={strings.errorTitle}\n\t\t\t\tdescription={error instanceof Error ? error.message : typeof error === 'string' || typeof error === 'number' ? String(error) : strings.errorDescription}\n\t\t\t\tonRetry={onRetry}\n\t\t\t\tretryLabel={strings.retry}\n\t\t\t\tclassName=\"appointment-agenda--error\"\n\t\t\t/>\n\t\t);\n\t} else if (total === 0) {\n\t\tbody = <EmptyState padding=\"sm\" title={strings.empty} description={false} ariaLabel={strings.empty} className=\"appointment-agenda--empty\" />;\n\t} else if (grouped) {\n\t\tbody = (\n\t\t\t<Stack gap=\"xl\">\n\t\t\t\t{groups.filter((group) => group.items.length > 0).map((group) => (\n\t\t\t\t\t<Stack key={group.day.toISOString()} render={<section />} gap=\"sm\" aria-label={dayFormat.format(group.day)} className=\"appointment-agenda--day\">\n\t\t\t\t\t\t<Heading className=\"text-inherit\" tag=\"h3\" size={headingRoleSizes.subsection}>{dayFormat.format(group.day)}</Heading>\n\t\t\t\t\t\t{list(group.items)}\n\t\t\t\t\t</Stack>\n\t\t\t\t))}\n\t\t\t</Stack>\n\t\t);\n\t} else {\n\t\tbody = list(groups[0]?.items ?? []);\n\t}\n\n\treturn (\n\t\t<Card\n\t\t\tsurface=\"card\"\n\t\t\ttitle={heading}\n\t\t\t// The count is unknown while loading or after a failed load, so it is left out rather than read as zero.\n\t\t\theaderEnd={loading || error ? undefined : <Text size=\"xs\" type=\"secondary\" className=\"tabular-nums\">{strings.formatCount(total)}</Text>}\n\t\t\tclassName=\"appointment-agenda--component h-full min-h-0\"\n\t\t\tcontentClassName=\"min-h-0 flex-1\"\n\t\t>\n\t\t\t<ScrollArea className=\"appointment-agenda--scroll h-full min-h-0\">\n\t\t\t\t{body}\n\t\t\t</ScrollArea>\n\t\t</Card>\n\t);\n}\n","/**\n * AppointmentMonth — the compact month beside the agenda: month and year\n * selects with previous/next, and a day grid whose dots show which categories\n * are booked that day. The grid is one tab stop: arrow keys move by a day or a\n * week, Home/End to the week's edges, PageUp/PageDown by a month, and Enter or\n * Space chooses the focused day. Private to the appointment calendar.\n */\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { useEffect, useMemo, useRef, useState, type KeyboardEvent } from 'react';\n\nimport { Button } from '../../../base/buttons';\nimport { Select } from '../../../base/choice-inputs';\nimport { Stack } from '../../../base/structure';\nimport { Text } from '../../../typography';\nimport { focusRecipes } from '../../../../lib/focus-recipes';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { dotRecipes } from '../../../../lib/tone-recipes';\nimport { cn } from '../../../../lib/utils';\n\nimport type { Appointment, AppointmentCalendarStrings, AppointmentCategory } from '../appointment-calendar.types';\nimport {\n\taddDays,\n\taddMonths,\n\tappointmentCategoryColorClasses,\n\tappointmentsOn,\n\tcategoryColor,\n\tisSameDay,\n\tmonthGrid,\n\tstartOfWeek,\n} from '../appointment-calendar.utils';\n\nexport interface AppointmentMonthProps {\n\tselected: Date;\n\tonSelect: (date: Date) => void;\n\t/** The first day of the month on screen, which keyboard focus can move away from the selection. */\n\tonVisibleMonthChange?: (month: Date) => void;\n\tappointments: Appointment[];\n\tcategories: AppointmentCategory[];\n\tweekStartsOn: number;\n\tlocale?: string;\n\tstrings: AppointmentCalendarStrings;\n}\n\n/** Days with this many categories or more show only the first three dots. */\nconst MAX_DOTS = 3;\n\nexport function AppointmentMonth({ selected, onSelect, onVisibleMonthChange, appointments, categories, weekStartsOn, locale, strings }: AppointmentMonthProps) {\n\tconst [focused, setFocused] = useState(selected);\n\tconst gridRef = useRef<HTMLDivElement>(null);\n\tconst focusOnRender = useRef(false);\n\tconst today = useMemo(() => new Date(), []);\n\n\t// The roving focus follows the selection when it changes from outside.\n\tuseEffect(() => setFocused(selected), [selected]);\n\tconst visibleMonth = focused.getFullYear() * 12 + focused.getMonth();\n\tuseEffect(() => {\n\t\tonVisibleMonthChange?.(new Date(Math.floor(visibleMonth / 12), visibleMonth % 12, 1));\n\t}, [visibleMonth, onVisibleMonthChange]);\n\tuseEffect(() => {\n\t\tif (!focusOnRender.current) return;\n\t\tfocusOnRender.current = false;\n\t\tgridRef.current?.querySelector<HTMLButtonElement>('[data-focus-target]')?.focus();\n\t}, [focused]);\n\n\tconst weeks = useMemo(() => monthGrid(focused, weekStartsOn), [focused, weekStartsOn]);\n\tconst monthFormat = useMemo(() => new Intl.DateTimeFormat(locale, { month: 'long' }), [locale]);\n\tconst weekdayFormat = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: 'short' }), [locale]);\n\tconst dayFormat = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }), [locale]);\n\tconst monthOptions = useMemo(() => Array.from({ length: 12 }, (_, month) => ({ value: String(month), label: monthFormat.format(new Date(2000, month, 1)) })), [monthFormat]);\n\tconst yearOptions = useMemo(() => {\n\t\tconst years = new Set<number>([today.getFullYear(), focused.getFullYear()]);\n\t\tfor (const appointment of appointments) years.add(appointment.start.getFullYear());\n\t\tconst min = Math.min(...years) - 1;\n\t\tconst max = Math.max(...years) + 1;\n\t\treturn Array.from({ length: max - min + 1 }, (_, index) => ({ value: String(min + index), label: String(min + index) }));\n\t}, [appointments, focused, today]);\n\n\tconst moveTo = (date: Date, select = false) => {\n\t\tfocusOnRender.current = true;\n\t\tsetFocused(date);\n\t\tif (select) onSelect(date);\n\t};\n\tconst changeMonth = (months: number) => {\n\t\tconst next = addMonths(selected, months);\n\t\tsetFocused(next);\n\t\tonSelect(next);\n\t};\n\n\tconst onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n\t\tconst moves: Record<string, () => Date> = {\n\t\t\tArrowLeft: () => addDays(focused, -1),\n\t\t\tArrowRight: () => addDays(focused, 1),\n\t\t\tArrowUp: () => addDays(focused, -7),\n\t\t\tArrowDown: () => addDays(focused, 7),\n\t\t\tHome: () => startOfWeek(focused, weekStartsOn),\n\t\t\tEnd: () => addDays(startOfWeek(focused, weekStartsOn), 6),\n\t\t\tPageUp: () => addMonths(focused, -1),\n\t\t\tPageDown: () => addMonths(focused, 1),\n\t\t};\n\t\tconst move = moves[event.key];\n\t\tif (!move) return;\n\t\tevent.preventDefault();\n\t\tmoveTo(move());\n\t};\n\n\treturn (\n\t\t<Stack gap=\"lg\" className=\"appointment-month--component min-w-0\">\n\t\t\t<div className=\"appointment-month--header flex min-w-0 items-center gap-space-xs\">\n\t\t\t\t<Button type=\"button\" tone=\"secondary\" buttonStyle=\"ghost\" size=\"sm\" iconOnly aria-label={strings.previousMonth} onClick={() => changeMonth(-1)}>\n\t\t\t\t\t<ChevronLeft aria-hidden=\"true\" className=\"size-icon\" />\n\t\t\t\t</Button>\n\t\t\t\t<Select\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\taria-label={strings.monthLabel}\n\t\t\t\t\toptions={monthOptions}\n\t\t\t\t\tvalue={String(selected.getMonth())}\n\t\t\t\t\tonValueChange={(value) => value !== undefined && changeMonth(Number(value) - selected.getMonth())}\n\t\t\t\t\tclassName=\"min-w-0 flex-1\"\n\t\t\t\t/>\n\t\t\t\t<Select\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\taria-label={strings.yearLabel}\n\t\t\t\t\toptions={yearOptions}\n\t\t\t\t\tvalue={String(selected.getFullYear())}\n\t\t\t\t\tonValueChange={(value) => value !== undefined && changeMonth((Number(value) - selected.getFullYear()) * 12)}\n\t\t\t\t\tclassName=\"min-w-0 flex-1\"\n\t\t\t\t/>\n\t\t\t\t<Button type=\"button\" tone=\"secondary\" buttonStyle=\"ghost\" size=\"sm\" iconOnly aria-label={strings.nextMonth} onClick={() => changeMonth(1)}>\n\t\t\t\t\t<ChevronRight aria-hidden=\"true\" className=\"size-icon\" />\n\t\t\t\t</Button>\n\t\t\t</div>\n\n\t\t\t<div\n\t\t\t\tref={gridRef}\n\t\t\t\trole=\"grid\"\n\t\t\t\taria-label={`${monthFormat.format(focused)} ${focused.getFullYear()}`}\n\t\t\t\tonKeyDown={onKeyDown}\n\t\t\t\tclassName=\"appointment-month--grid grid min-w-0 grid-cols-7 gap-space-2xs\"\n\t\t\t>\n\t\t\t\t<div role=\"row\" className=\"contents\">\n\t\t\t\t\t{weeks[0]?.map((day) => (\n\t\t\t\t\t\t<Text key={day.getDay()} tag=\"div\" role=\"columnheader\" size=\"xs\" type=\"secondary\" weight=\"medium\" align=\"center\" className=\"appointment-month--weekday py-space-xs\">\n\t\t\t\t\t\t\t{weekdayFormat.format(day)}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t\t{weeks.map((week) => (\n\t\t\t\t\t<div key={week[0]?.toISOString()} role=\"row\" className=\"contents\">\n\t\t\t\t\t\t{week.map((day) => {\n\t\t\t\t\t\t\tconst dayAppointments = appointmentsOn(appointments, day);\n\t\t\t\t\t\t\tconst dayCategories = [...new Set(dayAppointments.map((appointment) => appointment.category))];\n\t\t\t\t\t\t\tconst isSelected = isSameDay(day, selected);\n\t\t\t\t\t\t\tconst isFocused = isSameDay(day, focused);\n\t\t\t\t\t\t\tconst outside = day.getMonth() !== focused.getMonth();\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div key={day.toISOString()} role=\"gridcell\" aria-selected={isSelected} className=\"flex min-w-0 justify-center\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\ttabIndex={isFocused ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\tdata-focus-target={isFocused ? '' : undefined}\n\t\t\t\t\t\t\t\t\t\tdata-selected={isSelected ? '' : undefined}\n\t\t\t\t\t\t\t\t\t\tdata-outside={outside ? '' : undefined}\n\t\t\t\t\t\t\t\t\t\taria-current={isSameDay(day, today) ? 'date' : undefined}\n\t\t\t\t\t\t\t\t\t\taria-label={strings.formatDayLabel(dayFormat.format(day), dayAppointments.length)}\n\t\t\t\t\t\t\t\t\t\tonClick={() => moveTo(day, true)}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\tinteractionRecipes.nativeButtonReset,\n\t\t\t\t\t\t\t\t\t\t\t'appointment-month--day relative flex size-action flex-col items-center justify-center rounded-radius text-sm tabular-nums outline-none',\n\t\t\t\t\t\t\t\t\t\t\tfocusRecipes.edge,\n\t\t\t\t\t\t\t\t\t\t\tisSelected\n\t\t\t\t\t\t\t\t\t\t\t\t? 'bg-primary font-semibold text-primary-foreground'\n\t\t\t\t\t\t\t\t\t\t\t\t: cn(interactionRecipes.rowHover, outside ? 'text-muted-foreground' : 'text-foreground'),\n\t\t\t\t\t\t\t\t\t\t\t!isSelected && isSameDay(day, today) && 'font-semibold',\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{day.getDate()}\n\t\t\t\t\t\t\t\t\t\t{dayCategories.length > 0 && (\n\t\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\" className=\"appointment-month--dots absolute inset-x-0 bottom-space-2xs flex justify-center gap-space-2xs\">\n\t\t\t\t\t\t\t\t\t\t\t\t{dayCategories.slice(0, MAX_DOTS).map((category) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span key={category} className={cn(dotRecipes.inline, appointmentCategoryColorClasses[categoryColor(categories, category)])} />\n\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</Stack>\n\t);\n}\n","/**\n * AppointmentCalendar — a booking calendar laid out side by side: a compact\n * month with category dots and filters beside the agenda for the chosen day\n * or week.\n *\n * The header carries the title with booked and conflict counts, the Day/Week\n * switch, an optional staff filter and the \"New appointment\" command. Two\n * overlapping appointments for one staff member are a conflict: both rows say\n * so, and a dismissible alert names who is double-booked and when. Categories\n * are kinds, so their stripes and dots draw from the chart palette, and status\n * chips keep the status tones. The layout follows its own container: the month\n * sits beside the agenda when there is room and above it otherwise.\n *\n * Data, creation and editing stay with the app: the calendar formats and\n * filters the appointments it is given and reports intent through callbacks.\n */\nimport {compositionClasses} from '../../base/structure/composition.recipes';\nimport { Plus, TriangleAlert } from 'lucide-react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { Button } from '../../base/buttons';\nimport { Card } from '../../base/cards';\nimport { Select } from '../../base/choice-inputs';\nimport { Alert, AlertAction, AlertDescription, AlertTitle } from '../../base/feedback';\nimport { Tabs, TabsList, TabsTrigger } from '../../base/navigation/tabs';\nimport { Stack } from '../../base/structure';\nimport { Heading, Text } from '../../typography';\nimport { useStrings } from '../../../lib/strings';\nimport { dotRecipes } from '../../../lib/tone-recipes';\nimport { useDatesConfig, useFormattingConfig } from '../../../lib/ui-provider';\nimport { cn } from '../../../lib/utils';\n\nimport {\n\tdefaultAppointmentCalendarStrings,\n\ttype Appointment,\n\ttype AppointmentCalendarProps,\n\ttype AppointmentCalendarView,\n\ttype AppointmentConflict,\n\ttype AppointmentDateRange,\n} from './appointment-calendar.types';\nimport {\n\taddDays,\n\tappointmentCategoryColorClasses,\n\tcategoryColor,\n\tconflictingIds,\n\tfilterAppointments,\n\tfindConflicts,\n\tformatTime,\n\tmonthGrid,\n\toccursOn,\n\tstaffFrom,\n\tstartOfDay,\n\tweekDays,\n} from './appointment-calendar.utils';\nimport { AppointmentAgenda, type AppointmentAgendaProps } from './partials/appointment-agenda';\nimport { AppointmentMonth } from './partials/appointment-month';\n\n/** Controlled when `value` is given, otherwise local state seeded by `fallback`. */\nfunction useControllable<T>(value: T | undefined, fallback: T, onChange?: (next: T) => void): [T, (next: T) => void] {\n\tconst [local, setLocal] = useState(fallback);\n\tconst current = value ?? local;\n\treturn [current, (next: T) => {\n\t\tif (value === undefined) setLocal(next);\n\t\tonChange?.(next);\n\t}];\n}\n\nexport function AppointmentCalendar<T extends Appointment = Appointment>({\n\tappointments,\n\tcategories,\n\tstaff: staffProp,\n\ttitle,\n\tdate: dateProp,\n\tdefaultDate,\n\tonDateChange,\n\tview: viewProp,\n\tdefaultView = 'day',\n\tonViewChange,\n\tcategory: categoryProp,\n\tdefaultCategory = 'all',\n\tonCategoryChange,\n\tstaffId: staffIdProp,\n\tdefaultStaffId = 'all',\n\tonStaffIdChange,\n\tonStaffChange,\n\tonAppointmentClick,\n\tappointmentActions,\n\trenderAppointment,\n\tonRangeChange,\n\tonCreateAppointment,\n\tonConflictsDismiss,\n\tloading = false,\n\terror,\n\tonRetry,\n\tweekStartsOn: weekStartsOnProp,\n\tstrings: stringsProp,\n\tclassName,\n}: AppointmentCalendarProps<T>) {\n\tconst strings = useStrings(defaultAppointmentCalendarStrings, stringsProp);\n\tconst { locale } = useFormattingConfig();\n\tconst dates = useDatesConfig();\n\tconst weekStartsOn = weekStartsOnProp ?? dates.weekStartsOn ?? 0;\n\n\tconst [date, setDate] = useControllable(dateProp, defaultDate ?? startOfDay(new Date()), onDateChange);\n\tconst [view, setView] = useControllable<AppointmentCalendarView>(viewProp, defaultView, onViewChange);\n\tconst [category, setCategory] = useControllable(categoryProp, defaultCategory, onCategoryChange);\n\tconst [staffId, setStaffId] = useControllable(staffIdProp, defaultStaffId, onStaffIdChange ?? onStaffChange);\n\tconst [dismissed, setDismissed] = useState<string>('');\n\tconst [visibleMonth, setVisibleMonth] = useState(() => new Date(date.getFullYear(), date.getMonth(), 1));\n\n\tconst staff = useMemo(() => staffProp ?? staffFrom(appointments), [staffProp, appointments]);\n\tconst days = useMemo(() => (view === 'week' ? weekDays(date, weekStartsOn) : [startOfDay(date)]), [view, date, weekStartsOn]);\n\tconst visible = useMemo(() => filterAppointments(appointments, category, staffId), [appointments, category, staffId]);\n\t// The days on screen: the month grid, widened by the agenda when keyboard\n\t// focus has moved the month away from the selected day or week.\n\tconst range = useMemo<AppointmentDateRange>(() => {\n\t\tconst edges = [...monthGrid(visibleMonth, weekStartsOn).flat(), ...days].map((day) => day.getTime());\n\t\treturn { start: new Date(Math.min(...edges)), end: addDays(new Date(Math.max(...edges)), 1) };\n\t}, [visibleMonth, weekStartsOn, days]);\n\tconst reportedRange = useRef('');\n\tuseEffect(() => {\n\t\tconst key = `${range.start.getTime()}:${range.end.getTime()}`;\n\t\tif (key === reportedRange.current) return;\n\t\treportedRange.current = key;\n\t\tonRangeChange?.(range);\n\t}, [range, onRangeChange]);\n\tconst inRange = useMemo(() => visible.filter((appointment) => days.some((day) => occursOn(appointment, day))), [visible, days]);\n\n\t// A staff member is double-booked whatever the category filter shows, so\n\t// overlaps are found across every category, then narrowed to the range.\n\tconst conflicts = useMemo(() => {\n\t\tconst staffScoped = filterAppointments(appointments, 'all', staffId).filter((appointment) => days.some((day) => occursOn(appointment, day)));\n\t\treturn findConflicts(staffScoped);\n\t}, [appointments, staffId, days]);\n\tconst conflictIds = useMemo(() => conflictingIds(conflicts), [conflicts]);\n\tconst visibleConflicts = inRange.filter((appointment) => conflictIds.has(appointment.id)).length;\n\tconst booked = inRange.filter((appointment) => appointment.status !== 'cancelled').length;\n\tconst conflictKey = [...conflictIds].sort().join('|');\n\tconst showAlert = conflicts.length > 0 && dismissed !== conflictKey;\n\n\tconst headingFormat = new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric' });\n\tconst rangeFormat = new Intl.DateTimeFormat(locale, { month: 'long', day: 'numeric' });\n\tconst heading = view === 'week'\n\t\t? strings.formatWeekRange(rangeFormat.format(days[0] ?? date), rangeFormat.format(days[days.length - 1] ?? date))\n\t\t: headingFormat.format(date);\n\n\tconst dismissConflicts = (shown: AppointmentConflict<T>[]) => {\n\t\tsetDismissed(conflictKey);\n\t\tonConflictsDismiss?.(shown);\n\t};\n\n\treturn (\n\t\t<Stack gap=\"xl\" data-slot=\"appointment-calendar\" data-view={view} className={cn('appointment-calendar--component @container/appointment-calendar min-h-0 min-w-0', className)}>\n\t\t\t<div className=\"appointment-calendar--header flex min-w-0 flex-wrap items-start justify-between gap-space-lg\">\n\t\t\t\t<Stack gap=\"xs\" className=\"min-w-0\">\n\t\t\t\t\t{!!title && <Heading className=\"text-inherit\" tag=\"h2\" size=\"lg\">{title}</Heading>}\n\t\t\t\t\t{/* Counts are unknown until the range loads; a zero here would read as a real empty day. */}\n\t\t\t\t\t{!loading && !error && (\n\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\" className=\"appointment-calendar--counts tabular-nums\">\n\t\t\t\t\t\t\t{strings.formatBooked(booked)}\n\t\t\t\t\t\t\t{visibleConflicts > 0 && ` · ${strings.formatConflicts(visibleConflicts)}`}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)}\n\t\t\t\t</Stack>\n\t\t\t\t<div className={cn('appointment-calendar--actions flex min-w-0 flex-wrap items-center', compositionClasses.commands)}>\n\t\t\t\t\t<Tabs value={view} onValueChange={(next) => (next === 'day' || next === 'week') && setView(next)}>\n\t\t\t\t\t\t<TabsList role=\"group\" aria-label={strings.viewLabel} aria-orientation={undefined} activateOnFocus>\n\t\t\t\t\t\t\t{(['day', 'week'] as const).map((option) => (\n\t\t\t\t\t\t\t\t<TabsTrigger key={option} value={option} role=\"button\" aria-selected={undefined} aria-controls={undefined} aria-pressed={view === option}>\n\t\t\t\t\t\t\t\t\t{strings[option]}\n\t\t\t\t\t\t\t\t</TabsTrigger>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</TabsList>\n\t\t\t\t\t</Tabs>\n\t\t\t\t\t{staff.length > 0 && (\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\taria-label={strings.staffLabel}\n\t\t\t\t\t\t\toptions={[{ value: 'all', label: strings.allStaff }, ...staff.map((person) => ({ value: person.id, label: person.name }))]}\n\t\t\t\t\t\t\tvalue={staffId}\n\t\t\t\t\t\t\tonValueChange={(next) => setStaffId(next ?? 'all')}\n\t\t\t\t\t\t\tclassName=\"appointment-calendar--staff w-44\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{!!onCreateAppointment && (\n\t\t\t\t\t\t<Button type=\"button\" tone=\"primary\" onClick={() => onCreateAppointment(date)} className=\"appointment-calendar--create\">\n\t\t\t\t\t\t\t<Plus aria-hidden=\"true\" className=\"size-icon\" />\n\t\t\t\t\t\t\t{strings.newAppointment}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{showAlert && (\n\t\t\t\t<Alert tone=\"destructive\" className=\"appointment-calendar--alert\">\n\t\t\t\t\t<TriangleAlert aria-hidden=\"true\" />\n\t\t\t\t\t<AlertTitle>{strings.conflictTitle}</AlertTitle>\n\t\t\t\t\t<AlertDescription>\n\t\t\t\t\t\t{conflicts.map((conflict) => strings.formatConflict(conflict.staff.name, conflict.appointments.length, formatTime(conflict.start, locale))).join(' ')}\n\t\t\t\t\t</AlertDescription>\n\t\t\t\t\t<AlertAction>\n\t\t\t\t\t\t<Button type=\"button\" size=\"sm\" onClick={() => dismissConflicts(conflicts)}>{strings.dismiss}</Button>\n\t\t\t\t\t</AlertAction>\n\t\t\t\t</Alert>\n\t\t\t)}\n\n\t\t\t<div className=\"appointment-calendar--body grid min-h-0 min-w-0 flex-1 gap-space-xl @3xl/appointment-calendar:grid-cols-[minmax(17rem,20rem)_minmax(0,1fr)]\">\n\t\t\t\t<Card surface=\"card\" className=\"appointment-calendar--aside min-w-0 self-start\">\n\t\t\t\t\t<Stack gap=\"xl\">\n\t\t\t\t\t\t<AppointmentMonth\n\t\t\t\t\t\t\tselected={date}\n\t\t\t\t\t\t\tonSelect={setDate}\n\t\t\t\t\t\t\tonVisibleMonthChange={setVisibleMonth}\n\t\t\t\t\t\t\tappointments={visible}\n\t\t\t\t\t\t\tcategories={categories}\n\t\t\t\t\t\t\tweekStartsOn={weekStartsOn}\n\t\t\t\t\t\t\tlocale={locale}\n\t\t\t\t\t\t\tstrings={strings}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{categories.length > 0 && (\n\t\t\t\t\t\t\t<Tabs value={category} onValueChange={(next) => typeof next === 'string' && setCategory(next)}>\n\t\t\t\t\t\t\t\t<TabsList variant=\"chips\" role=\"group\" aria-label={strings.categoriesLabel} aria-orientation={undefined} activateOnFocus>\n\t\t\t\t\t\t\t\t\t{[{ id: 'all', label: strings.allCategories }, ...categories].map((option) => (\n\t\t\t\t\t\t\t\t\t\t<TabsTrigger key={option.id} value={option.id} role=\"button\" aria-selected={undefined} aria-controls={undefined} aria-pressed={category === option.id} className=\"appointment-calendar--category gap-space-xs\">\n\t\t\t\t\t\t\t\t\t\t\t{option.id !== 'all' && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\" className={cn(dotRecipes.inline, appointmentCategoryColorClasses[categoryColor(categories, option.id)])} />\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t\t\t\t</TabsTrigger>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</TabsList>\n\t\t\t\t\t\t\t</Tabs>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Stack>\n\t\t\t\t</Card>\n\n\t\t\t\t<AppointmentAgenda\n\t\t\t\t\tdays={days}\n\t\t\t\t\tappointments={visible}\n\t\t\t\t\tcategories={categories}\n\t\t\t\t\tconflicts={conflictIds}\n\t\t\t\t\theading={heading}\n\t\t\t\t\tloading={loading}\n\t\t\t\t\terror={error}\n\t\t\t\t\tonRetry={onRetry}\n\t\t\t\t\tlocale={locale}\n\t\t\t\t\t// The agenda only hands back items from `appointments`, so the app's own type holds.\n\t\t\t\t\tonAppointmentClick={onAppointmentClick as ((appointment: Appointment) => void) | undefined}\n\t\t\t\t\tappointmentActions={appointmentActions as AppointmentAgendaProps['appointmentActions']}\n\t\t\t\t\trenderAppointment={renderAppointment as AppointmentAgendaProps['renderAppointment']}\n\t\t\t\t\tstrings={strings}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</Stack>\n\t);\n}\n\nAppointmentCalendar.displayName = 'AppointmentCalendar';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"appointment-calendar.js","names":["useDatesConfig","useFormattingConfig","cn","Text","Heading","headingRoleSizes","focusRecipes","Button","Stack","toneRecipes","dotRecipes","surfaceRecipes","regionRecipes","AlertTitle","Alert","AlertDescription","AlertAction","ErrorState","compositionClasses","ActionMenu","Skeleton","interactionRecipes","formatInitials","AvatarFallback","Avatar","AvatarImage","Badge","Select","VisuallyHidden","ScrollArea","ItemDescription","ItemActions","ItemContent","Item","ItemTitle","TabsTrigger","TabsList","Tabs","EmptyState","defaultAppointmentCalendarStrings","count","staffName","time","start","end","date","title","CHART_SERIES","appointmentCategoryColorClasses","categoryColor","index","categories","category","id","startOfDay","addDays","days","isSameDay","a","b","addMonths","target","months","lastDay","startOfWeek","day","weekStartsOn","weekDays","first","monthGrid","week","occursOn","dayStart","dayEnd","appointment","appointmentsOn","appointments","filterAppointments","staffId","findConflicts","byStaff","list","conflicts","sorted","group","groupEnd","flush","conflictingIds","conflict","staffFrom","seen","formatTime","locale","hour12","options","personName","person","STATUS_TONE","AppointmentRow","useId","client","staff","people","context","hasActions","labelledBy","openRef","useRef","actionsHadFocus","useLayoutEffect","open","event","AppointmentAgenda","groups","total","dayFormat","grouped","contextFor","actions","appointmentActions","action","slot","strings","onAppointmentClick","items","renderAppointment","body","loading","error","isValidElement","name","regionRef","heading","className","MAX_DOTS","AppointmentMonth","focused","setFocused","useState","selected","gridRef","focusOnRender","today","selectedYear","selectedMonth","selectedDate","visibleMonth","useEffect","onVisibleMonthChange","weeks","useMemo","monthFormat","monthYearFormat","weekdayFormat","weekdayNameFormat","monthOptions","month","yearOptions","years","min","max","moveTo","select","onSelect","changeMonth","next","ChevronLeft","value","ChevronRight","move","dayAppointments","booked","dayCategories","isSelected","isFocused","isToday","outside","useControllable","local","setLocal","fallback","onChange","AppointmentCalendar","staffProp","dateProp","viewProp","categoryProp","staffIdProp","weekStartsOnProp","localeProp","stringsProp","useStrings","formatting","dates","setDate","defaultDate","onDateChange","view","setView","defaultView","onViewChange","setCategory","defaultCategory","onCategoryChange","setStaffId","defaultStaffId","onStaffIdChange","dismissed","setDismissed","setVisibleMonth","visible","range","edges","reportedRange","key","onRangeChange","inRange","conflictIds","visibleConflicts","conflictKey","showAlert","headingFormat","rangeFormat","agendaRef","focusAgenda","dismissConflicts","onConflictsDismiss","shown","framed","surface","option","onCreateAppointment","Plus","TriangleAlert"],"sources":["../../src/components/features/appointment-calendar/appointment-calendar.types.ts","../../src/components/features/appointment-calendar/appointment-calendar.utils.ts","../../src/components/features/appointment-calendar/partials/appointment-agenda.tsx","../../src/components/features/appointment-calendar/partials/appointment-month.tsx","../../src/components/features/appointment-calendar/appointment-calendar.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport type { ActionMenuAction } from '../../base/action-menu';\nimport type { BadgeTone } from '../../base/badge';\nimport type { StringsProp } from '../../../lib/strings';\n\n/** Where an appointment stands. Conflicts are derived, never a status. */\nexport type AppointmentStatus = 'confirmed' | 'pending' | 'completed' | 'cancelled' | 'noShow';\n\n/** The day agenda or the seven-day week agenda beside the month. */\nexport type AppointmentCalendarView = 'day' | 'week';\n\n/**\n * Categorical colour for a service category. Categories are kinds, not\n * statuses, so they draw from the chart series palette and never from the\n * success, warning or destructive tones that status chips own. Series 6, 7\n * and 8 are the theme's red, yellow and green series. The colour is a marker\n * (a dot or stripe), never a text colour: the yellow series is too pale for text.\n */\nexport type AppointmentCategoryColor =\n\t| 'chart-1' | 'chart-2' | 'chart-3' | 'chart-4' | 'chart-5'\n\t| 'chart-6' | 'chart-7' | 'chart-8';\n\n/** A service category: its label, filter chip and marker colour. */\nexport interface AppointmentCategory {\n\t/** Stable identity, referenced by `Appointment.category`. */\n\tid: string;\n\t/** Chip and legend label. */\n\tlabel: string;\n\t/** Marker colour. Defaults to the chart series by the category's position. */\n\tcolor?: AppointmentCategoryColor;\n}\n\n/** A person on an appointment: the staff member who delivers it, or the client. */\nexport interface AppointmentPerson {\n\t/** Stable identity. Staff overlap is detected by this id. */\n\tid: string;\n\t/** Display name. */\n\tname: string;\n\t/** Portrait. Initials stand in without one, or when it fails to load. */\n\tavatarUrl?: string;\n}\n\n/** One booked slot. The calendar formats it; it never fetches or saves. */\nexport interface Appointment {\n\t/** Stable identity. */\n\tid: string;\n\t/** The service: \"Cut and blow-dry\". */\n\ttitle: string;\n\t/** Start of the slot. */\n\tstart: Date;\n\t/** End of the slot; later than `start`. */\n\tend: Date;\n\t/** Category id, matching an `AppointmentCategory`. */\n\tcategory: string;\n\t/** Booking state. Cancelled appointments are listed but never conflict. */\n\tstatus: AppointmentStatus;\n\t/** Who the appointment is for, shown after the time. */\n\tclient?: AppointmentPerson | string;\n\t/** Who delivers it. Two overlapping appointments for one staff member conflict. */\n\tstaff?: AppointmentPerson;\n}\n\n/** The days on screen: the month grid and the agenda. `end` is exclusive (midnight after the last day). */\nexport interface AppointmentDateRange {\n\tstart: Date;\n\tend: Date;\n}\n\n/** Overlapping appointments for one staff member. */\nexport interface AppointmentConflict<T extends Appointment = Appointment> {\n\t/** The double-booked staff member. */\n\tstaff: AppointmentPerson;\n\t/** The appointments that overlap, earliest first. */\n\tappointments: T[];\n\t/** When the overlap begins. */\n\tstart: Date;\n}\n\nexport interface AppointmentCalendarStrings {\n\t/** Booked count beside the title: \"8 booked\". */\n\tformatBooked: (count: number) => string;\n\t/** Conflict count beside the title: \"2 conflicts\". */\n\tformatConflicts: (count: number) => string;\n\t/** Accessible name of the Day/Week switch. */\n\tviewLabel: string;\n\tday: string;\n\tweek: string;\n\t/** Accessible name of the staff filter. */\n\tstaffLabel: string;\n\t/** The staff filter's \"everyone\" option. */\n\tallStaff: string;\n\t/** Primary command. */\n\tnewAppointment: string;\n\t/** Conflict alert title. */\n\tconflictTitle: string;\n\t/** One overlapping-booking sentence per double-booked staff member. */\n\tformatConflict: (staffName: string, count: number, time: string) => string;\n\t/** Hides the conflict alert. */\n\tdismiss: string;\n\tpreviousMonth: string;\n\tnextMonth: string;\n\t/** Accessible name of the month select. */\n\tmonthLabel: string;\n\t/** Accessible name of the year select. */\n\tyearLabel: string;\n\t/** Accessible name of the category filter. */\n\tcategoriesLabel: string;\n\t/** The category filter's \"every category\" chip. */\n\tallCategories: string;\n\t/** Count beside the agenda heading: \"8 appointments\". */\n\tformatCount: (count: number) => string;\n\t/** A slot: \"9 AM to 10 AM\". Receives already formatted times. */\n\tformatTimeRange: (start: string, end: string) => string;\n\t/** Accessible day label in the month: \"Tuesday, June 9, 3 appointments\". */\n\tformatDayLabel: (date: string, count: number) => string;\n\t/** Agenda heading for the week view: \"June 8 to 14\". */\n\tformatWeekRange: (start: string, end: string) => string;\n\t/** Status chip words. */\n\tstatus: Record<AppointmentStatus, string>;\n\t/** Chip shown instead of the status when an appointment overlaps another. */\n\tconflict: string;\n\t/** Agenda copy when nothing matches the day or week. */\n\tempty: string;\n\t/** Loading copy for assistive technology. */\n\tloading: string;\n\t/** Default error state title. */\n\terrorTitle: string;\n\t/** Default error state description, when `error` carries no message. */\n\terrorDescription: string;\n\t/** Retry command in the default error state. */\n\tretry: string;\n\t/** Accessible name of an appointment's actions menu: \"Actions for Balayage\". */\n\tformatActionsLabel: (title: string) => string;\n}\n\nexport const defaultAppointmentCalendarStrings: AppointmentCalendarStrings = {\n\tformatBooked: (count) => `${count} booked`,\n\tformatConflicts: (count) => (count === 1 ? '1 conflict' : `${count} conflicts`),\n\tviewLabel: 'View',\n\tday: 'Day',\n\tweek: 'Week',\n\tstaffLabel: 'Staff',\n\tallStaff: 'All staff',\n\tnewAppointment: 'New appointment',\n\tconflictTitle: 'Double-booked',\n\tformatConflict: (staffName, count, time) => `${staffName} has ${count} overlapping bookings at ${time}.`,\n\tdismiss: 'Dismiss',\n\tpreviousMonth: 'Previous month',\n\tnextMonth: 'Next month',\n\tmonthLabel: 'Month',\n\tyearLabel: 'Year',\n\tcategoriesLabel: 'Categories',\n\tallCategories: 'All',\n\tformatCount: (count) => (count === 1 ? '1 appointment' : `${count} appointments`),\n\tformatTimeRange: (start, end) => `${start} to ${end}`,\n\tformatDayLabel: (date, count) => (count === 0 ? date : `${date}, ${count === 1 ? '1 appointment' : `${count} appointments`}`),\n\tformatWeekRange: (start, end) => `${start} to ${end}`,\n\tstatus: { confirmed: 'Confirmed', pending: 'Pending', completed: 'Completed', cancelled: 'Cancelled', noShow: 'No-show' },\n\tconflict: 'Conflict',\n\tempty: 'No appointments',\n\tloading: 'Loading appointments',\n\terrorTitle: 'Appointments unavailable',\n\terrorDescription: 'The appointments could not be loaded.',\n\tretry: 'Retry',\n\tformatActionsLabel: (title) => `Actions for ${title}`,\n};\n\n/** Whether the calendar draws its own frame (`card`) or sits inside another surface (`flat`). */\nexport type AppointmentCalendarSurface = 'card' | 'flat';\n\n/** What the calendar has worked out for one appointment, handed to `renderAppointment`. */\nexport interface AppointmentRenderContext {\n\t/** The appointment's category, when one matches. */\n\tcategory?: AppointmentCategory;\n\t/** The category's marker class (`bg-chart-N`), for a stripe or dot of your own. */\n\tcategoryColorClass: string;\n\t/** Whether it overlaps another booking for the same staff member. */\n\tconflict: boolean;\n\t/** The status chip's word, or the conflict word when it overlaps. */\n\tstatusLabel: string;\n\t/** The status chip's tone: destructive for a conflict, otherwise the status tone. */\n\tstatusTone: BadgeTone;\n\t/** The formatted slot: \"09:00 to 10:00\". */\n\ttime: string;\n\t/** Opens it through `onAppointmentClick`. Undefined when rows are not interactive. */\n\topen?: () => void;\n\t/** The visible commands `appointmentActions` returned for it. */\n\tactions: readonly ActionMenuAction[];\n\t/** The built-in actions menu for those commands, or null when there are none. */\n\tactionsMenu: ReactNode;\n\t/** The built-in row, to wrap or extend instead of replacing. */\n\tdefaultRender: () => ReactNode;\n}\n\n/**\n * Props for `AppointmentCalendar`. `T` is the app's own appointment type: extra\n * fields such as a price or notes come back, typed, in every callback.\n */\nexport interface AppointmentCalendarProps<T extends Appointment = Appointment> {\n\t/** Appointments to place. The calendar filters and formats; it never fetches. */\n\tappointments: T[];\n\t/** Service categories: filter chips, markers and day dots. */\n\tcategories: AppointmentCategory[];\n\t/** Staff offered by the staff filter. Defaults to the staff found on appointments. */\n\tstaff?: AppointmentPerson[];\n\t/** Heading above the calendar: the location or calendar name. */\n\ttitle?: ReactNode;\n\t/** Selected day. Controlled with `onDateChange`. */\n\tdate?: Date;\n\t/** Selected day for uncontrolled use. Defaults to today. */\n\tdefaultDate?: Date;\n\t/** Fired when a day is chosen or the month moves. */\n\tonDateChange?: (date: Date) => void;\n\t/** Day or week agenda. Controlled with `onViewChange`. */\n\tview?: AppointmentCalendarView;\n\t/** View for uncontrolled use. Defaults to `day`. */\n\tdefaultView?: AppointmentCalendarView;\n\t/** Fired when the Day/Week switch changes. */\n\tonViewChange?: (view: AppointmentCalendarView) => void;\n\t/** Category filter: a category id, or `all`. Controlled with `onCategoryChange`. */\n\tcategory?: string;\n\t/** Category filter for uncontrolled use. Defaults to `all`. */\n\tdefaultCategory?: string;\n\t/** Fired when a category chip is chosen. */\n\tonCategoryChange?: (category: string) => void;\n\t/** Staff filter: a staff id, or `all`. Controlled with `onStaffIdChange`. */\n\tstaffId?: string;\n\t/** Staff filter for uncontrolled use. Defaults to `all`. */\n\tdefaultStaffId?: string;\n\t/** Fired when the staff filter changes. */\n\tonStaffIdChange?: (staffId: string) => void;\n\t/** Fired when an appointment is activated. Without it, rows are not interactive. */\n\tonAppointmentClick?: (appointment: T) => void;\n\t/**\n\t * Commands for one appointment, such as confirm, reschedule or cancel,\n\t * offered in a menu at the end of its row. Return an empty list for none.\n\t */\n\tappointmentActions?: (appointment: T) => readonly ActionMenuAction[];\n\t/**\n\t * Renders one appointment in the agenda instead of the built-in row. The\n\t * context carries its category colour, conflict, time, `open`, its actions\n\t * and a ready actions menu, and `defaultRender` for the built-in row.\n\t */\n\trenderAppointment?: (appointment: T, context: AppointmentRenderContext) => ReactNode;\n\t/**\n\t * Fired with the days on screen, the month grid and the agenda together, once\n\t * on mount and whenever they change. Load appointments for this range.\n\t */\n\tonRangeChange?: (range: AppointmentDateRange) => void;\n\t/** Shows the primary \"New appointment\" command; receives the selected day. */\n\tonCreateAppointment?: (date: Date) => void;\n\t/** Fired when the conflict alert is dismissed, with the conflicts it showed. */\n\tonConflictsDismiss?: (conflicts: AppointmentConflict<T>[]) => void;\n\t/** Shows the loading state in the agenda. */\n\tloading?: boolean;\n\t/**\n\t * Shows the error state in the agenda. A string or Error becomes its\n\t * description; any other element replaces the default state.\n\t */\n\terror?: ReactNode | Error;\n\t/** Adds Retry to the default error state. */\n\tonRetry?: () => void;\n\t/** First column of the month and first day of the week. Defaults to the provider, then Sunday. */\n\tweekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n\t/**\n\t * BCP 47 locale for weekday and month names, dates and times (\"de-DE\").\n\t * Defaults to the provider's formatting locale.\n\t */\n\tlocale?: string;\n\t/**\n\t * `card` (default) draws the calendar's own frame: one surface whose header,\n\t * notice, month and agenda are regions, never cards of their own. `flat`\n\t * draws no frame or outer inset, for a calendar placed inside a `Card` or\n\t * another surface that already owns them.\n\t */\n\tsurface?: AppointmentCalendarSurface;\n\t/** Overrides this calendar's own copy. */\n\tstrings?: StringsProp<AppointmentCalendarStrings>;\n\t/** Merged onto the root. */\n\tclassName?: string;\n}\n","/**\n * Pure helpers for the appointment calendar: day arithmetic, filtering,\n * conflict detection and time formatting. No React, so they are testable and\n * reusable by an application that pre-computes its own view.\n */\nimport type {\n\tAppointment,\n\tAppointmentCategory,\n\tAppointmentCategoryColor,\n\tAppointmentConflict,\n\tAppointmentPerson,\n} from './appointment-calendar.types';\n\nconst CHART_SERIES: AppointmentCategoryColor[] = ['chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5', 'chart-6', 'chart-7', 'chart-8'];\n\n/** Marker colour classes per chart series. Literal so Tailwind generates them. */\nexport const appointmentCategoryColorClasses: Record<AppointmentCategoryColor, string> = {\n\t'chart-1': 'bg-chart-1',\n\t'chart-2': 'bg-chart-2',\n\t'chart-3': 'bg-chart-3',\n\t'chart-4': 'bg-chart-4',\n\t'chart-5': 'bg-chart-5',\n\t'chart-6': 'bg-chart-6',\n\t'chart-7': 'bg-chart-7',\n\t'chart-8': 'bg-chart-8',\n};\n\n/** A category's colour: its own, or the chart series at its position. */\nexport function categoryColor(categories: AppointmentCategory[], id: string): AppointmentCategoryColor {\n\tconst index = categories.findIndex((category) => category.id === id);\n\tif (index < 0) return 'chart-1';\n\treturn categories[index]?.color ?? CHART_SERIES[index % CHART_SERIES.length] ?? 'chart-1';\n}\n\nexport function startOfDay(date: Date): Date {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nexport function addDays(date: Date, days: number): Date {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n\treturn a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\n/** The same day of the month in another month, clamped to that month's length. */\nexport function addMonths(date: Date, months: number): Date {\n\tconst target = new Date(date.getFullYear(), date.getMonth() + months, 1);\n\tconst lastDay = new Date(target.getFullYear(), target.getMonth() + 1, 0).getDate();\n\treturn new Date(target.getFullYear(), target.getMonth(), Math.min(date.getDate(), lastDay));\n}\n\nexport function startOfWeek(date: Date, weekStartsOn: number): Date {\n\tconst day = startOfDay(date);\n\treturn addDays(day, -((day.getDay() - weekStartsOn + 7) % 7));\n}\n\n/** The seven days of the week that holds `date`. */\nexport function weekDays(date: Date, weekStartsOn: number): Date[] {\n\tconst first = startOfWeek(date, weekStartsOn);\n\treturn Array.from({ length: 7 }, (_, index) => addDays(first, index));\n}\n\n/** Six full weeks covering the month of `date`, so the grid never changes height. */\nexport function monthGrid(date: Date, weekStartsOn: number): Date[][] {\n\tconst first = startOfWeek(new Date(date.getFullYear(), date.getMonth(), 1), weekStartsOn);\n\treturn Array.from({ length: 6 }, (_, week) => Array.from({ length: 7 }, (_, day) => addDays(first, week * 7 + day)));\n}\n\n/** Whether an appointment touches a day (it may run past midnight). */\nexport function occursOn(appointment: Appointment, day: Date): boolean {\n\tconst dayStart = startOfDay(day).getTime();\n\tconst dayEnd = addDays(day, 1).getTime();\n\treturn appointment.start.getTime() < dayEnd && appointment.end.getTime() > dayStart;\n}\n\nexport function appointmentsOn<T extends Appointment>(appointments: T[], day: Date): T[] {\n\treturn appointments\n\t\t.filter((appointment) => occursOn(appointment, day))\n\t\t.sort((a, b) => a.start.getTime() - b.start.getTime() || a.end.getTime() - b.end.getTime());\n}\n\n/** Applies the category and staff filters; `all` keeps everything. */\nexport function filterAppointments<T extends Appointment>(appointments: T[], category: string, staffId: string): T[] {\n\treturn appointments.filter((appointment) =>\n\t\t(category === 'all' || appointment.category === category) &&\n\t\t(staffId === 'all' || appointment.staff?.id === staffId),\n\t);\n}\n\n/**\n * Overlapping appointments per staff member. Two appointments conflict when\n * the same staff member is booked for both and their times overlap; touching\n * ends (10:00 to 10:00) do not overlap, and cancelled appointments never conflict.\n */\nexport function findConflicts<T extends Appointment>(appointments: T[]): AppointmentConflict<T>[] {\n\tconst byStaff = new Map<string, T[]>();\n\tfor (const appointment of appointments) {\n\t\tif (!appointment.staff || appointment.status === 'cancelled') continue;\n\t\tconst list = byStaff.get(appointment.staff.id) ?? [];\n\t\tlist.push(appointment);\n\t\tbyStaff.set(appointment.staff.id, list);\n\t}\n\tconst conflicts: AppointmentConflict<T>[] = [];\n\tfor (const list of byStaff.values()) {\n\t\tconst sorted = [...list].sort((a, b) => a.start.getTime() - b.start.getTime());\n\t\tlet group: T[] = [];\n\t\tlet groupEnd = -Infinity;\n\t\tconst flush = () => {\n\t\t\tconst first = group[0];\n\t\t\tif (group.length > 1 && first?.staff) conflicts.push({ staff: first.staff, appointments: group, start: first.start });\n\t\t};\n\t\tfor (const appointment of sorted) {\n\t\t\tif (appointment.start.getTime() < groupEnd) {\n\t\t\t\tgroup.push(appointment);\n\t\t\t\tgroupEnd = Math.max(groupEnd, appointment.end.getTime());\n\t\t\t} else {\n\t\t\t\tflush();\n\t\t\t\tgroup = [appointment];\n\t\t\t\tgroupEnd = appointment.end.getTime();\n\t\t\t}\n\t\t}\n\t\tflush();\n\t}\n\treturn conflicts.sort((a, b) => a.start.getTime() - b.start.getTime());\n}\n\n/** Ids of every appointment that takes part in a conflict. */\nexport function conflictingIds(conflicts: AppointmentConflict[]): Set<string> {\n\treturn new Set(conflicts.flatMap((conflict) => conflict.appointments.map((appointment) => appointment.id)));\n}\n\n/** Distinct staff found on appointments, in first-seen order. */\nexport function staffFrom(appointments: Appointment[]): AppointmentPerson[] {\n\tconst seen = new Map<string, AppointmentPerson>();\n\tfor (const appointment of appointments) if (appointment.staff && !seen.has(appointment.staff.id)) seen.set(appointment.staff.id, appointment.staff);\n\treturn [...seen.values()];\n}\n\n/**\n * \"9 AM\", or \"9:30 AM\" when the minutes matter. A 24-hour clock always keeps\n * its minutes (\"09:00\"), since a bare \"09\" does not read as a time.\n */\nexport function formatTime(date: Date, locale?: string): string {\n\tconst { hour12 } = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions();\n\tif (!hour12) return new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit' }).format(date);\n\tconst options: Intl.DateTimeFormatOptions = date.getMinutes() === 0 ? { hour: 'numeric' } : { hour: 'numeric', minute: '2-digit' };\n\treturn new Intl.DateTimeFormat(locale, options).format(date);\n}\n\nexport function personName(person: AppointmentPerson | string | undefined): string | undefined {\n\treturn typeof person === 'string' ? person : person?.name;\n}\n","/**\n * AppointmentAgenda — the agenda pane: one day's appointments, or the selected\n * week listed day by day. It is a region of the calendar's surface, not a card.\n *\n * Rows are flush base `Item`s separated by one quiet rule. Each reads left to\n * right: a fixed-width time column (start over end, tabular figures) so every\n * title starts on the same line; a slim category marker in the category's\n * chart colour; the service with its status chip (or the conflict chip when it\n * overlaps another booking for the same staff member); the client and staff\n * names; then the staff avatar and the actions menu. A conflict washes the\n * whole row. A row opens only when the app can open it: a transparent button\n * stretched over the row takes the press, and the actions menu sits above it,\n * since a button cannot hold another. Private to the appointment calendar.\n */\nimport { isValidElement, useId, useLayoutEffect, useRef, type ReactNode, type Ref } from 'react';\n\nimport { ActionMenu, type ActionMenuAction } from '../../../base/action-menu';\nimport { Avatar, AvatarFallback, AvatarImage } from '../../../base/avatar';\nimport { Badge, type BadgeTone } from '../../../base/badge';\nimport { ScrollArea, VisuallyHidden } from '../../../base/display';\nimport { ErrorState } from '../../../base/feedback';\nimport { Item, ItemActions, ItemContent, ItemDescription, ItemTitle } from '../../../base/item';\nimport { Skeleton } from '../../../base/skeleton';\nimport { Stack } from '../../../base/structure';\nimport { formatInitials } from '../../../primitives';\nimport { Heading, Text } from '../../../typography';\nimport {headingRoleSizes} from '../../../typography/text.styles';\nimport { EmptyState } from '../../../blocks/data-display';\nimport { focusRecipes } from '../../../../lib/focus-recipes';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { regionRecipes } from '../../../../lib/surface-recipes';\nimport { toneRecipes } from '../../../../lib/tone-recipes';\nimport { cn } from '../../../../lib/utils';\n\nimport type {\n\tAppointment,\n\tAppointmentCalendarStrings,\n\tAppointmentCategory,\n\tAppointmentRenderContext,\n\tAppointmentStatus,\n} from '../appointment-calendar.types';\nimport {\n\tappointmentCategoryColorClasses,\n\tappointmentsOn,\n\tcategoryColor,\n\tformatTime,\n\tpersonName,\n} from '../appointment-calendar.utils';\n\n/** Status chip tones. Completed and cancelled are history, not a state to act on. */\nconst STATUS_TONE: Record<AppointmentStatus, BadgeTone> = {\n\tconfirmed: 'success',\n\tpending: 'warning',\n\tcompleted: 'neutral',\n\tcancelled: 'neutral',\n\tnoShow: 'destructive',\n};\n\nexport interface AppointmentAgendaProps {\n\t/** The days to list: one for the day view, seven for the week view. */\n\tdays: Date[];\n\t/** Appointments after the category and staff filters. */\n\tappointments: Appointment[];\n\tcategories: AppointmentCategory[];\n\t/** Ids of appointments that overlap another booking for the same staff member. */\n\tconflicts: Set<string>;\n\theading: string;\n\tloading: boolean;\n\terror?: ReactNode | Error;\n\tonRetry?: () => void;\n\tlocale?: string;\n\tonAppointmentClick?: (appointment: Appointment) => void;\n\tappointmentActions?: (appointment: Appointment) => readonly ActionMenuAction[];\n\trenderAppointment?: (appointment: Appointment, context: AppointmentRenderContext) => ReactNode;\n\tstrings: AppointmentCalendarStrings;\n\t/** The pane's inset, which the calendar's surface decides. */\n\tclassName?: string;\n\t/** The agenda's own node: a stable place to return focus to when a control above it goes away. */\n\tregionRef?: Ref<HTMLDivElement>;\n}\n\ntype RowContext = Omit<AppointmentRenderContext, 'defaultRender'> & {\n\t/** Start and end, formatted apart for the time column. */\n\tslot: { start: string; end: string };\n};\n\n/** The built-in row, drawn from the same context a custom row receives. */\nfunction AppointmentRow({ appointment, context }: { appointment: Appointment; context: RowContext }) {\n\tconst id = useId();\n\tconst client = personName(appointment.client);\n\tconst staff = appointment.staff;\n\tconst people = [client, staff?.name].filter(Boolean).join(' · ');\n\tconst { open, conflict } = context;\n\tconst hasActions = context.actions.length > 0;\n\t// The open button is named by the row's own copy, one part per id so the\n\t// title, its chip, the slot and the people read as separate words.\n\tconst labelledBy = [`${id}-title`, `${id}-status`, `${id}-time`, people && `${id}-people`].filter(Boolean).join(' ');\n\tconst openRef = useRef<HTMLButtonElement>(null);\n\tconst actionsHadFocus = useRef(false);\n\n\t// A command can remove the row's last action, and the menu trigger with it.\n\t// Focus then returns to the row's open button instead of falling to the page.\n\tuseLayoutEffect(() => {\n\t\tif (hasActions || !actionsHadFocus.current) return;\n\t\tactionsHadFocus.current = false;\n\t\tif (!document.activeElement || document.activeElement === document.body) openRef.current?.focus();\n\t}, [hasActions]);\n\n\treturn (\n\t\t<Item\n\t\t\tsize=\"sm\"\n\t\t\tpadding=\"default\"\n\t\t\tdata-status={appointment.status}\n\t\t\tdata-conflict={conflict ? '' : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t'appointment-agenda--row relative w-full flex-nowrap',\n\t\t\t\t!!open && interactionRecipes.rowHover,\n\t\t\t\t// A conflict is a state of the whole row: one wash, no extra edge.\n\t\t\t\tconflict && toneRecipes.destructive.wash,\n\t\t\t)}\n\t\t>\n\t\t\t{!!open && (\n\t\t\t\t<button\n\t\t\t\t\tref={openRef}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-labelledby={labelledBy}\n\t\t\t\t\tonClick={open}\n\t\t\t\t\tclassName={cn('appointment-agenda--open absolute inset-0 z-0 cursor-pointer rounded-radius focus-visible:outline-none', interactionRecipes.nativeButtonReset, focusRecipes.inset)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{/* One width for every row, so the titles share a vertical line. */}\n\t\t\t<Stack gap=\"none\" className=\"appointment-agenda--time w-16 shrink-0 tabular-nums\">\n\t\t\t\t<Text tag=\"span\" type=\"inherit\" weight=\"medium\" aria-hidden=\"true\" className=\"whitespace-nowrap\">{context.slot.start}</Text>\n\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\" aria-hidden=\"true\" className=\"whitespace-nowrap\">{context.slot.end}</Text>\n\t\t\t\t<VisuallyHidden><span id={`${id}-time`}>{context.time}</span></VisuallyHidden>\n\t\t\t</Stack>\n\t\t\t{/* The category marker: a categorical mark, so it draws from the chart palette and is never text or a fill. */}\n\t\t\t<span aria-hidden=\"true\" className={cn('appointment-agenda--stripe w-1 shrink-0 self-stretch rounded-full', context.categoryColorClass)} />\n\t\t\t<ItemContent className=\"min-w-0\">\n\t\t\t\t<ItemTitle className=\"flex-wrap\">\n\t\t\t\t\t{/* A long service name wraps rather than losing its end. */}\n\t\t\t\t\t<Text type=\"inherit\" id={`${id}-title`} tag=\"span\" weight=\"medium\" className=\"min-w-0 break-words\">{appointment.title}</Text>\n\t\t\t\t\t<Badge id={`${id}-status`} tone={context.statusTone} size=\"sm\">\n\t\t\t\t\t\t{context.statusLabel}\n\t\t\t\t\t</Badge>\n\t\t\t\t</ItemTitle>\n\t\t\t\t{!!people && (\n\t\t\t\t\t<ItemDescription id={`${id}-people`} clamp={1} className=\"appointment-agenda--people\">\n\t\t\t\t\t\t{people}\n\t\t\t\t\t</ItemDescription>\n\t\t\t\t)}\n\t\t\t</ItemContent>\n\t\t\t{(!!staff || hasActions) && (\n\t\t\t\t<ItemActions\n\t\t\t\t\t// Above the stretched open button, so the menu takes its own presses.\n\t\t\t\t\tclassName=\"relative z-10\"\n\t\t\t\t\t// React focus events bubble from the portaled menu, so this tracks the trigger and its menu together.\n\t\t\t\t\tonFocus={() => { actionsHadFocus.current = true; }}\n\t\t\t\t\tonBlur={(event) => {\n\t\t\t\t\t\tif (event.relatedTarget instanceof Node && !event.currentTarget.contains(event.relatedTarget)) actionsHadFocus.current = false;\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{!!staff && (\n\t\t\t\t\t\t// The people line already names the staff member, so a narrow calendar drops the avatar for the title's sake.\n\t\t\t\t\t\t<Avatar size=\"sm\" aria-hidden=\"true\" className=\"appointment-agenda--staff hidden @md/appointment-calendar:flex\">\n\t\t\t\t\t\t\t{!!staff.avatarUrl && <AvatarImage src={staff.avatarUrl} alt=\"\" />}\n\t\t\t\t\t\t\t<AvatarFallback>{formatInitials(staff.name)}</AvatarFallback>\n\t\t\t\t\t\t</Avatar>\n\t\t\t\t\t)}\n\t\t\t\t\t{context.actionsMenu}\n\t\t\t\t</ItemActions>\n\t\t\t)}\n\t\t</Item>\n\t);\n}\n\nexport function AppointmentAgenda({ days, appointments, categories, conflicts, heading, loading, error, onRetry, locale, onAppointmentClick, appointmentActions, renderAppointment, strings, regionRef, className }: AppointmentAgendaProps) {\n\tconst groups = days.map((day) => ({ day, items: appointmentsOn(appointments, day) }));\n\t// An appointment that runs past midnight is listed under both days and counted once.\n\tconst total = new Set(groups.flatMap((group) => group.items.map((appointment) => appointment.id))).size;\n\tconst dayFormat = new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric' });\n\tconst grouped = days.length > 1;\n\n\t// One context per appointment: the built-in row draws from it, and a custom\n\t// row receives the same values, so both stay consistent.\n\tconst contextFor = (appointment: Appointment): AppointmentRenderContext => {\n\t\tconst conflict = conflicts.has(appointment.id);\n\t\tconst actions = (appointmentActions?.(appointment) ?? []).filter((action) => action.visible !== false);\n\t\tconst slot = { start: formatTime(appointment.start, locale), end: formatTime(appointment.end, locale) };\n\t\tconst context: RowContext = {\n\t\t\tcategory: categories.find((category) => category.id === appointment.category),\n\t\t\tcategoryColorClass: appointmentCategoryColorClasses[categoryColor(categories, appointment.category)],\n\t\t\tconflict,\n\t\t\tstatusLabel: conflict ? strings.conflict : strings.status[appointment.status],\n\t\t\tstatusTone: conflict ? 'destructive' : STATUS_TONE[appointment.status],\n\t\t\ttime: strings.formatTimeRange(slot.start, slot.end),\n\t\t\tslot,\n\t\t\topen: onAppointmentClick ? () => onAppointmentClick(appointment) : undefined,\n\t\t\tactions,\n\t\t\tactionsMenu: actions.length > 0 ? (\n\t\t\t\t<ActionMenu\n\t\t\t\t\tactions={actions}\n\t\t\t\t\tsrText={strings.formatActionsLabel(appointment.title)}\n\t\t\t\t\tbuttonProps={{ size: 'sm', className: 'appointment-agenda--actions relative z-10' }}\n\t\t\t\t/>\n\t\t\t) : null,\n\t\t};\n\t\treturn { ...context, defaultRender: () => <AppointmentRow appointment={appointment} context={context} /> };\n\t};\n\n\t// A tabular list: flush rows separated by one quiet rule. The list is pulled\n\t// out by the row inset, so row copy starts on the pane's inset while the\n\t// hover fill and the conflict wash reach a little past it.\n\tconst list = (items: Appointment[]) => (\n\t\t<ul className=\"appointment-agenda--list -mx-row-x m-0 list-none p-0\">\n\t\t\t{items.map((appointment) => {\n\t\t\t\tconst context = contextFor(appointment);\n\t\t\t\treturn (\n\t\t\t\t\t<li key={appointment.id} className={cn('min-w-0 last:border-b-0', regionRecipes.header)}>\n\t\t\t\t\t\t{renderAppointment ? renderAppointment(appointment, context) : context.defaultRender()}\n\t\t\t\t\t</li>\n\t\t\t\t);\n\t\t\t})}\n\t\t</ul>\n\t);\n\n\tlet body;\n\tif (loading) {\n\t\tbody = (\n\t\t\t<Stack gap=\"sm\" aria-busy=\"true\" className=\"appointment-agenda--loading\">\n\t\t\t\t<VisuallyHidden>{strings.loading}</VisuallyHidden>\n\t\t\t\t{Array.from({ length: 4 }, (_, index) => <Skeleton key={index} className=\"h-control-lg w-full rounded-radius\" />)}\n\t\t\t</Stack>\n\t\t);\n\t} else if (error) {\n\t\t// An app's own element replaces the default; a message becomes its description.\n\t\tbody = isValidElement(error) ? error : (\n\t\t\t<ErrorState\n\t\t\t\tvariant=\"inline\"\n\t\t\t\ttitle={strings.errorTitle}\n\t\t\t\tdescription={error instanceof Error ? error.message : typeof error === 'string' || typeof error === 'number' ? String(error) : strings.errorDescription}\n\t\t\t\tonRetry={onRetry}\n\t\t\t\tretryLabel={strings.retry}\n\t\t\t\tclassName=\"appointment-agenda--error\"\n\t\t\t/>\n\t\t);\n\t} else if (grouped) {\n\t\t// Every day of the week is listed, so an empty day is seen as empty rather than missing.\n\t\tbody = (\n\t\t\t<Stack gap=\"xl\">\n\t\t\t\t{groups.map((group) => {\n\t\t\t\t\tconst name = dayFormat.format(group.day);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Stack key={group.day.toISOString()} render={<section />} gap=\"sm\" aria-label={name} className=\"appointment-agenda--day\">\n\t\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"baseline\" justify=\"between\" gap=\"md\" wrap={false}>\n\t\t\t\t\t\t\t\t<Heading className=\"min-w-0 text-inherit\" tag=\"h3\" size={headingRoleSizes.subsection}>{name}</Heading>\n\t\t\t\t\t\t\t\t{group.items.length > 0 && (\n\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\" className=\"appointment-agenda--day-count shrink-0 tabular-nums\">{strings.formatCount(group.items.length)}</Text>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t{group.items.length > 0\n\t\t\t\t\t\t\t\t? list(group.items)\n\t\t\t\t\t\t\t\t: <Text size=\"xs\" type=\"secondary\" className=\"appointment-agenda--day-empty\">{strings.empty}</Text>}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</Stack>\n\t\t);\n\t} else if (total === 0) {\n\t\tbody = <EmptyState padding=\"sm\" title={strings.empty} description={false} ariaLabel={strings.empty} className=\"appointment-agenda--empty\" />;\n\t} else {\n\t\tbody = list(groups[0]?.items ?? []);\n\t}\n\n\treturn (\n\t\t<Stack\n\t\t\tref={regionRef}\n\t\t\tgap=\"lg\"\n\t\t\t// Named and focusable from script only, so focus has somewhere to land when the conflict notice is dismissed.\n\t\t\trole=\"group\"\n\t\t\taria-label={heading}\n\t\t\ttabIndex={-1}\n\t\t\tclassName={cn('appointment-agenda--component min-h-0 min-w-0 outline-none', focusRecipes.inset, className)}\n\t\t>\n\t\t\t<Stack direction=\"horizontal\" align=\"baseline\" justify=\"between\" gap=\"md\" wrap={false} className=\"appointment-agenda--heading\">\n\t\t\t\t{/* The pane's label, in the heading role's type; the days below it are the headings. */}\n\t\t\t\t<Heading tag=\"p\" className=\"min-w-0 text-inherit\">{heading}</Heading>\n\t\t\t\t{/* The count is unknown while loading or after a failed load, so it is left out rather than read as zero. */}\n\t\t\t\t{!loading && !error && (\n\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\" className=\"appointment-agenda--count shrink-0 tabular-nums\">{strings.formatCount(total)}</Text>\n\t\t\t\t)}\n\t\t\t</Stack>\n\t\t\t<ScrollArea className=\"appointment-agenda--scroll min-h-0 flex-1\">\n\t\t\t\t{body}\n\t\t\t</ScrollArea>\n\t\t</Stack>\n\t);\n}\n","/**\n * AppointmentMonth — the compact month beside the agenda: previous/next with\n * month and year selects, and a day grid whose dots show which categories are\n * booked that day (at most three, then one overflow mark).\n *\n * The grid is one tab stop: arrow keys move by a day or a week, Home/End to\n * the week's edges, PageUp/PageDown by a month, Shift+PageUp/PageDown by a\n * year, and Enter or Space chooses the focused day. The selects and\n * previous/next always describe and move the month the grid shows, which\n * keyboard paging can take away from the selected day; they choose the same\n * day of the month they move to.\n *\n * It is a custom grid rather than the base calendar: the base date pickers own\n * react-day-picker inside their popovers and publish no standalone month, and\n * this month needs per-day category marks and paging that does not select.\n * Private to the appointment calendar.\n */\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { useEffect, useMemo, useRef, useState, type KeyboardEvent } from 'react';\n\nimport { Button } from '../../../base/buttons';\nimport { Select } from '../../../base/choice-inputs';\nimport { Stack } from '../../../base/structure';\nimport { Text } from '../../../typography';\nimport { focusRecipes } from '../../../../lib/focus-recipes';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { dotRecipes } from '../../../../lib/tone-recipes';\nimport { cn } from '../../../../lib/utils';\n\nimport type { Appointment, AppointmentCalendarStrings, AppointmentCategory } from '../appointment-calendar.types';\nimport {\n\taddDays,\n\taddMonths,\n\tappointmentCategoryColorClasses,\n\tappointmentsOn,\n\tcategoryColor,\n\tisSameDay,\n\tmonthGrid,\n\tstartOfWeek,\n} from '../appointment-calendar.utils';\n\nexport interface AppointmentMonthProps {\n\tselected: Date;\n\tonSelect: (date: Date) => void;\n\t/** The first day of the month on screen, which keyboard focus can move away from the selection. */\n\tonVisibleMonthChange?: (month: Date) => void;\n\tappointments: Appointment[];\n\tcategories: AppointmentCategory[];\n\tweekStartsOn: number;\n\tlocale?: string;\n\tstrings: AppointmentCalendarStrings;\n}\n\n/** A day shows at most this many category dots, then one overflow mark. */\nconst MAX_DOTS = 3;\n\nexport function AppointmentMonth({ selected, onSelect, onVisibleMonthChange, appointments, categories, weekStartsOn, locale, strings }: AppointmentMonthProps) {\n\tconst [focused, setFocused] = useState(selected);\n\tconst gridRef = useRef<HTMLDivElement>(null);\n\tconst focusOnRender = useRef(false);\n\tconst [today] = useState(() => new Date());\n\n\t// The roving focus follows the selection when it moves to another day. A\n\t// controlled `date` is often a new Date on every render, sometimes with a\n\t// different time of day, so this compares the calendar day and nothing else.\n\tconst selectedYear = selected.getFullYear();\n\tconst selectedMonth = selected.getMonth();\n\tconst selectedDate = selected.getDate();\n\tuseEffect(() => setFocused(new Date(selectedYear, selectedMonth, selectedDate)), [selectedYear, selectedMonth, selectedDate]);\n\tconst visibleMonth = focused.getFullYear() * 12 + focused.getMonth();\n\tuseEffect(() => {\n\t\tonVisibleMonthChange?.(new Date(Math.floor(visibleMonth / 12), visibleMonth % 12, 1));\n\t}, [visibleMonth, onVisibleMonthChange]);\n\tuseEffect(() => {\n\t\tif (!focusOnRender.current) return;\n\t\tfocusOnRender.current = false;\n\t\tgridRef.current?.querySelector<HTMLButtonElement>('[data-focus-target]')?.focus();\n\t}, [focused]);\n\n\tconst weeks = useMemo(() => monthGrid(focused, weekStartsOn), [focused, weekStartsOn]);\n\tconst monthFormat = useMemo(() => new Intl.DateTimeFormat(locale, { month: 'long' }), [locale]);\n\t// The grid's name, in the locale's own order (\"June 2026\", \"2026年6月\").\n\tconst monthYearFormat = useMemo(() => new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }), [locale]);\n\tconst weekdayFormat = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: 'short' }), [locale]);\n\tconst weekdayNameFormat = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: 'long' }), [locale]);\n\tconst dayFormat = useMemo(() => new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }), [locale]);\n\tconst monthOptions = useMemo(() => Array.from({ length: 12 }, (_, month) => ({ value: String(month), label: monthFormat.format(new Date(2000, month, 1)) })), [monthFormat]);\n\tconst yearOptions = useMemo(() => {\n\t\tconst years = new Set<number>([today.getFullYear(), focused.getFullYear()]);\n\t\tfor (const appointment of appointments) years.add(appointment.start.getFullYear());\n\t\tconst min = Math.min(...years) - 1;\n\t\tconst max = Math.max(...years) + 1;\n\t\treturn Array.from({ length: max - min + 1 }, (_, index) => ({ value: String(min + index), label: String(min + index) }));\n\t}, [appointments, focused, today]);\n\n\tconst moveTo = (date: Date, select = false) => {\n\t\tfocusOnRender.current = true;\n\t\tsetFocused(date);\n\t\tif (select) onSelect(date);\n\t};\n\t// From the month on screen, not the selected one: keyboard paging may have\n\t// moved the grid, and the header must not describe a month it does not show.\n\tconst changeMonth = (months: number) => {\n\t\tconst next = addMonths(focused, months);\n\t\tsetFocused(next);\n\t\tonSelect(next);\n\t};\n\n\tconst onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n\t\tconst moves: Record<string, () => Date> = {\n\t\t\tArrowLeft: () => addDays(focused, -1),\n\t\t\tArrowRight: () => addDays(focused, 1),\n\t\t\tArrowUp: () => addDays(focused, -7),\n\t\t\tArrowDown: () => addDays(focused, 7),\n\t\t\tHome: () => startOfWeek(focused, weekStartsOn),\n\t\t\tEnd: () => addDays(startOfWeek(focused, weekStartsOn), 6),\n\t\t\tPageUp: () => addMonths(focused, event.shiftKey ? -12 : -1),\n\t\t\tPageDown: () => addMonths(focused, event.shiftKey ? 12 : 1),\n\t\t};\n\t\tconst move = moves[event.key];\n\t\tif (!move) return;\n\t\tevent.preventDefault();\n\t\tmoveTo(move());\n\t};\n\n\treturn (\n\t\t<Stack gap=\"lg\" className=\"appointment-month--component min-w-0\">\n\t\t\t<div className=\"appointment-month--header flex min-w-0 items-center gap-space-xs\">\n\t\t\t\t<Button type=\"button\" tone=\"secondary\" buttonStyle=\"ghost\" size=\"sm\" iconOnly aria-label={strings.previousMonth} onClick={() => changeMonth(-1)}>\n\t\t\t\t\t<ChevronLeft aria-hidden=\"true\" className=\"size-icon\" />\n\t\t\t\t</Button>\n\t\t\t\t<Select\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\taria-label={strings.monthLabel}\n\t\t\t\t\toptions={monthOptions}\n\t\t\t\t\tvalue={String(focused.getMonth())}\n\t\t\t\t\tonValueChange={(value) => value !== undefined && changeMonth(Number(value) - focused.getMonth())}\n\t\t\t\t\tclassName=\"min-w-0 flex-1\"\n\t\t\t\t/>\n\t\t\t\t<Select\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\taria-label={strings.yearLabel}\n\t\t\t\t\toptions={yearOptions}\n\t\t\t\t\tvalue={String(focused.getFullYear())}\n\t\t\t\t\tonValueChange={(value) => value !== undefined && changeMonth((Number(value) - focused.getFullYear()) * 12)}\n\t\t\t\t\tclassName=\"min-w-0 flex-1\"\n\t\t\t\t/>\n\t\t\t\t<Button type=\"button\" tone=\"secondary\" buttonStyle=\"ghost\" size=\"sm\" iconOnly aria-label={strings.nextMonth} onClick={() => changeMonth(1)}>\n\t\t\t\t\t<ChevronRight aria-hidden=\"true\" className=\"size-icon\" />\n\t\t\t\t</Button>\n\t\t\t</div>\n\n\t\t\t{/* oxlint-disable-next-line jsx-a11y/interactive-supports-focus -- Roving tabindex: focus stays on the items and the container handles their keys. */}\n\t\t\t<div\n\t\t\t\tref={gridRef}\n\t\t\t\trole=\"grid\"\n\t\t\t\taria-label={monthYearFormat.format(focused)}\n\t\t\t\tonKeyDown={onKeyDown}\n\t\t\t\t// Seven equal columns across the whole pane.\n\t\t\t\tclassName=\"appointment-month--grid grid w-full min-w-0 grid-cols-7 gap-space-2xs\"\n\t\t\t>\n\t\t\t\t<div role=\"row\" className=\"contents\">\n\t\t\t\t\t{weeks[0]?.map((day) => (\n\t\t\t\t\t\t<Text key={day.getDay()} tag=\"div\" role=\"columnheader\" aria-label={weekdayNameFormat.format(day)} size=\"xs\" type=\"secondary\" weight=\"medium\" align=\"center\" className=\"appointment-month--weekday py-space-xs\">\n\t\t\t\t\t\t\t{weekdayFormat.format(day)}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t\t{weeks.map((week) => (\n\t\t\t\t\t<div key={week[0]?.toISOString()} role=\"row\" className=\"contents\">\n\t\t\t\t\t\t{week.map((day) => {\n\t\t\t\t\t\t\tconst dayAppointments = appointmentsOn(appointments, day);\n\t\t\t\t\t\t\t// In the category order, so a day's dots read the same way as the filter chips.\n\t\t\t\t\t\t\tconst booked = new Set(dayAppointments.map((appointment) => appointment.category));\n\t\t\t\t\t\t\tconst dayCategories = [\n\t\t\t\t\t\t\t\t...categories.filter((category) => booked.has(category.id)).map((category) => category.id),\n\t\t\t\t\t\t\t\t...[...booked].filter((id) => !categories.some((category) => category.id === id)),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\tconst isSelected = isSameDay(day, selected);\n\t\t\t\t\t\t\tconst isFocused = isSameDay(day, focused);\n\t\t\t\t\t\t\tconst isToday = isSameDay(day, today);\n\t\t\t\t\t\t\tconst outside = day.getMonth() !== focused.getMonth();\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div key={day.toISOString()} role=\"gridcell\" aria-selected={isSelected} className=\"min-w-0\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\ttabIndex={isFocused ? 0 : -1}\n\t\t\t\t\t\t\t\t\t\tdata-focus-target={isFocused ? '' : undefined}\n\t\t\t\t\t\t\t\t\t\tdata-selected={isSelected ? '' : undefined}\n\t\t\t\t\t\t\t\t\t\tdata-outside={outside ? '' : undefined}\n\t\t\t\t\t\t\t\t\t\tdata-today={isToday ? '' : undefined}\n\t\t\t\t\t\t\t\t\t\taria-current={isToday ? 'date' : undefined}\n\t\t\t\t\t\t\t\t\t\taria-label={strings.formatDayLabel(dayFormat.format(day), dayAppointments.length)}\n\t\t\t\t\t\t\t\t\t\tonClick={() => moveTo(day, true)}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\tinteractionRecipes.nativeButtonReset,\n\t\t\t\t\t\t\t\t\t\t\t// One cell size for every day: the large action height, as wide as its column.\n\t\t\t\t\t\t\t\t\t\t\t'appointment-month--day flex h-action-lg w-full cursor-pointer flex-col items-center justify-center gap-space-2xs rounded-radius border border-transparent text-sm tabular-nums outline-none',\n\t\t\t\t\t\t\t\t\t\t\tfocusRecipes.frame,\n\t\t\t\t\t\t\t\t\t\t\tisSelected\n\t\t\t\t\t\t\t\t\t\t\t\t? 'bg-primary font-semibold text-primary-foreground'\n\t\t\t\t\t\t\t\t\t\t\t\t: cn(interactionRecipes.rowHover, outside ? 'text-muted-foreground' : 'text-foreground'),\n\t\t\t\t\t\t\t\t\t\t\t// Today is ringed; the selected day is filled.\n\t\t\t\t\t\t\t\t\t\t\t!isSelected && isToday && 'border-input font-semibold',\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{day.getDate()}\n\t\t\t\t\t\t\t\t\t\t{/* The marks are decoration: the day's name carries the count. The row keeps its height on days without any. */}\n\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\" className=\"appointment-month--dots flex h-1.5 items-center justify-center gap-space-2xs\">\n\t\t\t\t\t\t\t\t\t\t\t{dayCategories.slice(0, MAX_DOTS).map((category) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<span key={category} data-category={category} className={cn(dotRecipes.inline, appointmentCategoryColorClasses[categoryColor(categories, category)])} />\n\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t{dayCategories.length > MAX_DOTS && (\n\t\t\t\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"inherit\" lineHeight=\"none\" className=\"appointment-month--more\">+</Text>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</Stack>\n\t);\n}\n","/**\n * AppointmentCalendar — a booking calendar on one surface: a header, an\n * optional double-booking notice, and a body with a compact month beside the\n * agenda for the chosen day or week.\n *\n * The surface is one frame with regions, never cards inside a card. The header\n * carries the title with booked and conflict counts and one command cluster:\n * the Day/Week switch, an optional staff filter and the \"New appointment\"\n * command. The month pane holds the month grid with category dots and the\n * category filter; one quiet rule separates it from the agenda pane. Two\n * overlapping appointments for one staff member are a conflict: both rows say\n * so, and a dismissible notice names who is double-booked and when. Categories\n * are kinds, so their markers draw from the chart palette, and status chips\n * keep the status tones. The layout follows its own container: the month sits\n * beside the agenda when there is room and above it otherwise.\n *\n * Data, creation and editing stay with the app: the calendar formats and\n * filters the appointments it is given and reports intent through callbacks.\n */\nimport {compositionClasses} from '../../base/structure/composition.recipes';\nimport { Plus, TriangleAlert } from 'lucide-react';\nimport { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\n\nimport { Button } from '../../base/buttons';\nimport { Select } from '../../base/choice-inputs';\nimport { Alert, AlertAction, AlertDescription, AlertTitle } from '../../base/feedback';\nimport { Tabs, TabsList, TabsTrigger } from '../../base/navigation/tabs';\nimport { Stack } from '../../base/structure';\nimport { Heading, Text } from '../../typography';\nimport { useStrings } from '../../../lib/strings';\nimport { regionRecipes, surfaceRecipes } from '../../../lib/surface-recipes';\nimport { dotRecipes } from '../../../lib/tone-recipes';\nimport { useDatesConfig, useFormattingConfig } from '../../../lib/ui-provider';\nimport { cn } from '../../../lib/utils';\n\nimport {\n\tdefaultAppointmentCalendarStrings,\n\ttype Appointment,\n\ttype AppointmentCalendarProps,\n\ttype AppointmentCalendarView,\n\ttype AppointmentConflict,\n\ttype AppointmentDateRange,\n} from './appointment-calendar.types';\nimport {\n\taddDays,\n\tappointmentCategoryColorClasses,\n\tcategoryColor,\n\tconflictingIds,\n\tfilterAppointments,\n\tfindConflicts,\n\tformatTime,\n\tmonthGrid,\n\toccursOn,\n\tstaffFrom,\n\tstartOfDay,\n\tweekDays,\n} from './appointment-calendar.utils';\nimport { AppointmentAgenda, type AppointmentAgendaProps } from './partials/appointment-agenda';\nimport { AppointmentMonth } from './partials/appointment-month';\n\n/** Controlled when `value` is given, otherwise local state seeded by `fallback`. */\nfunction useControllable<T>(value: T | undefined, fallback: T, onChange?: (next: T) => void): [T, (next: T) => void] {\n\tconst [local, setLocal] = useState(fallback);\n\tconst current = value ?? local;\n\treturn [current, (next: T) => {\n\t\tif (value === undefined) setLocal(next);\n\t\tonChange?.(next);\n\t}];\n}\n\nexport function AppointmentCalendar<T extends Appointment = Appointment>({\n\tappointments,\n\tcategories,\n\tstaff: staffProp,\n\ttitle,\n\tdate: dateProp,\n\tdefaultDate,\n\tonDateChange,\n\tview: viewProp,\n\tdefaultView = 'day',\n\tonViewChange,\n\tcategory: categoryProp,\n\tdefaultCategory = 'all',\n\tonCategoryChange,\n\tstaffId: staffIdProp,\n\tdefaultStaffId = 'all',\n\tonStaffIdChange,\n\tonAppointmentClick,\n\tappointmentActions,\n\trenderAppointment,\n\tonRangeChange,\n\tonCreateAppointment,\n\tonConflictsDismiss,\n\tloading = false,\n\terror,\n\tonRetry,\n\tweekStartsOn: weekStartsOnProp,\n\tlocale: localeProp,\n\tsurface = 'card',\n\tstrings: stringsProp,\n\tclassName,\n}: AppointmentCalendarProps<T>) {\n\tconst strings = useStrings(defaultAppointmentCalendarStrings, stringsProp);\n\tconst formatting = useFormattingConfig();\n\tconst locale = localeProp ?? formatting.locale;\n\tconst dates = useDatesConfig();\n\tconst weekStartsOn = weekStartsOnProp ?? dates.weekStartsOn ?? 0;\n\n\tconst [today] = useState(() => startOfDay(new Date()));\n\tconst [date, setDate] = useControllable(dateProp, defaultDate ?? today, onDateChange);\n\tconst [view, setView] = useControllable<AppointmentCalendarView>(viewProp, defaultView, onViewChange);\n\tconst [category, setCategory] = useControllable(categoryProp, defaultCategory, onCategoryChange);\n\tconst [staffId, setStaffId] = useControllable(staffIdProp, defaultStaffId, onStaffIdChange);\n\tconst [dismissed, setDismissed] = useState<string>('');\n\tconst [visibleMonth, setVisibleMonth] = useState(() => new Date(date.getFullYear(), date.getMonth(), 1));\n\n\tconst staff = useMemo(() => staffProp ?? staffFrom(appointments), [staffProp, appointments]);\n\tconst days = useMemo(() => (view === 'week' ? weekDays(date, weekStartsOn) : [startOfDay(date)]), [view, date, weekStartsOn]);\n\tconst visible = useMemo(() => filterAppointments(appointments, category, staffId), [appointments, category, staffId]);\n\t// The days on screen: the month grid, widened by the agenda when keyboard\n\t// focus has moved the month away from the selected day or week.\n\tconst range = useMemo<AppointmentDateRange>(() => {\n\t\tconst edges = [...monthGrid(visibleMonth, weekStartsOn).flat(), ...days].map((day) => day.getTime());\n\t\treturn { start: new Date(Math.min(...edges)), end: addDays(new Date(Math.max(...edges)), 1) };\n\t}, [visibleMonth, weekStartsOn, days]);\n\tconst reportedRange = useRef('');\n\tuseEffect(() => {\n\t\tconst key = `${range.start.getTime()}:${range.end.getTime()}`;\n\t\tif (key === reportedRange.current) return;\n\t\treportedRange.current = key;\n\t\tonRangeChange?.(range);\n\t}, [range, onRangeChange]);\n\tconst inRange = useMemo(() => visible.filter((appointment) => days.some((day) => occursOn(appointment, day))), [visible, days]);\n\n\t// A staff member is double-booked whatever the category filter shows, so\n\t// overlaps are found across every category, then narrowed to the range.\n\tconst conflicts = useMemo(() => {\n\t\tconst staffScoped = filterAppointments(appointments, 'all', staffId).filter((appointment) => days.some((day) => occursOn(appointment, day)));\n\t\treturn findConflicts(staffScoped);\n\t}, [appointments, staffId, days]);\n\tconst conflictIds = useMemo(() => conflictingIds(conflicts), [conflicts]);\n\tconst visibleConflicts = inRange.filter((appointment) => conflictIds.has(appointment.id)).length;\n\tconst booked = inRange.filter((appointment) => appointment.status !== 'cancelled').length;\n\tconst conflictKey = [...conflictIds].sort().join('|');\n\tconst showAlert = conflicts.length > 0 && dismissed !== conflictKey;\n\n\tconst headingFormat = new Intl.DateTimeFormat(locale, { weekday: 'long', month: 'long', day: 'numeric' });\n\tconst rangeFormat = new Intl.DateTimeFormat(locale, { month: 'long', day: 'numeric' });\n\tconst heading = view === 'week'\n\t\t? strings.formatWeekRange(rangeFormat.format(days[0] ?? date), rangeFormat.format(days[days.length - 1] ?? date))\n\t\t: headingFormat.format(date);\n\n\t// Dismiss sits inside the alert it removes. Focus moves to the agenda, which\n\t// lists the same conflicts, instead of falling to the page.\n\tconst agendaRef = useRef<HTMLDivElement>(null);\n\tconst focusAgenda = useRef(false);\n\tconst dismissConflicts = (shown: AppointmentConflict<T>[]) => {\n\t\tfocusAgenda.current = true;\n\t\tsetDismissed(conflictKey);\n\t\tonConflictsDismiss?.(shown);\n\t};\n\tuseLayoutEffect(() => {\n\t\tif (showAlert || !focusAgenda.current) return;\n\t\tfocusAgenda.current = false;\n\t\tagendaRef.current?.focus();\n\t}, [showAlert]);\n\n\t// One surface with regions. `card` owns the frame and every region's inset;\n\t// `flat` leaves both to the surface the calendar sits in and keeps only the\n\t// space between its own regions.\n\tconst framed = surface === 'card';\n\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"appointment-calendar\"\n\t\t\tdata-view={view}\n\t\t\tdata-surface={surface}\n\t\t\tclassName={cn(\n\t\t\t\t'appointment-calendar--component @container/appointment-calendar flex min-h-0 min-w-0 flex-col',\n\t\t\t\tframed && cn(surfaceRecipes.frame, 'overflow-hidden'),\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<div className={cn(\n\t\t\t\t'appointment-calendar--header flex min-w-0 flex-wrap items-start justify-between gap-space-lg',\n\t\t\t\tregionRecipes.header,\n\t\t\t\tframed ? 'p-surface' : 'pb-surface',\n\t\t\t)}>\n\t\t\t\t<Stack gap=\"normal\" className=\"min-w-0\">\n\t\t\t\t\t{!!title && <Heading className=\"text-inherit\" tag=\"h2\" size=\"lg\">{title}</Heading>}\n\t\t\t\t\t{/* Counts are unknown until the range loads; a zero here would read as a real empty day. */}\n\t\t\t\t\t{!loading && !error && (\n\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\" className=\"appointment-calendar--counts tabular-nums\">\n\t\t\t\t\t\t\t{strings.formatBooked(booked)}\n\t\t\t\t\t\t\t{visibleConflicts > 0 && ` · ${strings.formatConflicts(visibleConflicts)}`}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)}\n\t\t\t\t</Stack>\n\t\t\t\t{/* One command cluster; it wraps by the calendar's own width, with the primary command last. */}\n\t\t\t\t<div className={cn('appointment-calendar--actions flex min-w-0 flex-wrap items-center', compositionClasses.commands)}>\n\t\t\t\t\t{/* A pressed-button group, not a tab set: arrows move focus, and only Enter, Space or a press applies the choice. */}\n\t\t\t\t\t<Tabs value={view} onValueChange={(next) => (next === 'day' || next === 'week') && setView(next)}>\n\t\t\t\t\t\t<TabsList role=\"group\" aria-label={strings.viewLabel} aria-orientation={undefined}>\n\t\t\t\t\t\t\t{(['day', 'week'] as const).map((option) => (\n\t\t\t\t\t\t\t\t<TabsTrigger key={option} value={option} role=\"button\" aria-selected={undefined} aria-controls={undefined} aria-pressed={view === option}>\n\t\t\t\t\t\t\t\t\t{strings[option]}\n\t\t\t\t\t\t\t\t</TabsTrigger>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</TabsList>\n\t\t\t\t\t</Tabs>\n\t\t\t\t\t{staff.length > 0 && (\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\taria-label={strings.staffLabel}\n\t\t\t\t\t\t\toptions={[{ value: 'all', label: strings.allStaff }, ...staff.map((person) => ({ value: person.id, label: person.name }))]}\n\t\t\t\t\t\t\tvalue={staffId}\n\t\t\t\t\t\t\tonValueChange={(next) => setStaffId(next ?? 'all')}\n\t\t\t\t\t\t\tclassName=\"appointment-calendar--staff w-44\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{!!onCreateAppointment && (\n\t\t\t\t\t\t<Button type=\"button\" tone=\"primary\" onClick={() => onCreateAppointment(date)} className=\"appointment-calendar--create\">\n\t\t\t\t\t\t\t<Plus aria-hidden=\"true\" className=\"size-icon\" />\n\t\t\t\t\t\t\t{strings.newAppointment}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{showAlert && (\n\t\t\t\t// The notice is a region of the surface: the same inset as the regions around it, and its own rule below.\n\t\t\t\t<div className={cn('appointment-calendar--notice min-w-0', regionRecipes.header, framed ? 'p-surface' : 'py-surface')}>\n\t\t\t\t\t<Alert tone=\"destructive\" className=\"appointment-calendar--alert\">\n\t\t\t\t\t\t<TriangleAlert aria-hidden=\"true\" />\n\t\t\t\t\t\t<AlertTitle>{strings.conflictTitle}</AlertTitle>\n\t\t\t\t\t\t<AlertDescription>\n\t\t\t\t\t\t\t{conflicts.map((conflict) => strings.formatConflict(conflict.staff.name, conflict.appointments.length, formatTime(conflict.start, locale))).join(' ')}\n\t\t\t\t\t\t</AlertDescription>\n\t\t\t\t\t\t<AlertAction>\n\t\t\t\t\t\t\t<Button type=\"button\" size=\"sm\" onClick={() => dismissConflicts(conflicts)}>{strings.dismiss}</Button>\n\t\t\t\t\t\t</AlertAction>\n\t\t\t\t\t</Alert>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<div className={'appointment-calendar--body grid min-h-0 min-w-0 flex-1 @2xl/appointment-calendar:grid-cols-[minmax(17rem,20rem)_minmax(0,1fr)]'}>\n\t\t\t\t{/* The month pane: a region, separated from the agenda by one quiet rule (below it when stacked, beside it otherwise). */}\n\t\t\t\t<div className={cn(\n\t\t\t\t\t'appointment-calendar--aside min-w-0',\n\t\t\t\t\tregionRecipes.header,\n\t\t\t\t\t'@2xl/appointment-calendar:border-b-0 @2xl/appointment-calendar:border-e @2xl/appointment-calendar:border-border/60',\n\t\t\t\t\tframed ? 'p-surface' : 'py-surface @2xl/appointment-calendar:pe-surface',\n\t\t\t\t)}>\n\t\t\t\t\t<Stack gap=\"xl\" className=\"appointment-calendar--aside-content max-w-sm\">\n\t\t\t\t\t\t<AppointmentMonth\n\t\t\t\t\t\t\tselected={date}\n\t\t\t\t\t\t\tonSelect={setDate}\n\t\t\t\t\t\t\tonVisibleMonthChange={setVisibleMonth}\n\t\t\t\t\t\t\tappointments={visible}\n\t\t\t\t\t\t\tcategories={categories}\n\t\t\t\t\t\t\tweekStartsOn={weekStartsOn}\n\t\t\t\t\t\t\tlocale={locale}\n\t\t\t\t\t\t\tstrings={strings}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{categories.length > 0 && (\n\t\t\t\t\t\t\t<Tabs value={category} onValueChange={(next) => typeof next === 'string' && setCategory(next)}>\n\t\t\t\t\t\t\t\t{/* One wrapping row of neutral chips; the colour is the dot, the pressed fill is the Tabs owner's. */}\n\t\t\t\t\t\t\t\t<TabsList variant=\"chips\" role=\"group\" aria-label={strings.categoriesLabel} aria-orientation={undefined} className=\"appointment-calendar--categories w-full\">\n\t\t\t\t\t\t\t\t\t{[{ id: 'all', label: strings.allCategories }, ...categories].map((option) => (\n\t\t\t\t\t\t\t\t\t\t<TabsTrigger key={option.id} value={option.id} role=\"button\" aria-selected={undefined} aria-controls={undefined} aria-pressed={category === option.id} className=\"appointment-calendar--category gap-space-xs\">\n\t\t\t\t\t\t\t\t\t\t\t{option.id !== 'all' && (\n\t\t\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\" className={cn(dotRecipes.inline, appointmentCategoryColorClasses[categoryColor(categories, option.id)])} />\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t\t\t\t</TabsTrigger>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</TabsList>\n\t\t\t\t\t\t\t</Tabs>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Stack>\n\t\t\t\t</div>\n\n\t\t\t\t<AppointmentAgenda\n\t\t\t\t\tregionRef={agendaRef}\n\t\t\t\t\tdays={days}\n\t\t\t\t\tappointments={visible}\n\t\t\t\t\tcategories={categories}\n\t\t\t\t\tconflicts={conflictIds}\n\t\t\t\t\theading={heading}\n\t\t\t\t\tloading={loading}\n\t\t\t\t\terror={error}\n\t\t\t\t\tonRetry={onRetry}\n\t\t\t\t\tlocale={locale}\n\t\t\t\t\tclassName={framed ? 'p-surface' : 'pt-surface @2xl/appointment-calendar:ps-surface'}\n\t\t\t\t\t// The agenda only hands back items from `appointments`, so the app's own type holds.\n\t\t\t\t\tonAppointmentClick={onAppointmentClick as ((appointment: Appointment) => void) | undefined}\n\t\t\t\t\tappointmentActions={appointmentActions as AppointmentAgendaProps['appointmentActions']}\n\t\t\t\t\trenderAppointment={renderAppointment as AppointmentAgendaProps['renderAppointment']}\n\t\t\t\t\tstrings={strings}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nAppointmentCalendar.displayName = 'AppointmentCalendar';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwIA,IAAauC,KAAgE;CAC5E,eAAe,MAAU,GAAGC,EAAM;CAClC,kBAAkB,MAAWA,MAAU,IAAI,eAAe,GAAGA,EAAM;CACnE,WAAW;CACX,KAAK;CACL,MAAM;CACN,YAAY;CACZ,UAAU;CACV,gBAAgB;CAChB,eAAe;CACf,iBAAiB,GAAW,GAAO,MAAS,GAAGC,EAAU,OAAOD,EAAM,2BAA2BE,EAAK;CACtG,SAAS;CACT,eAAe;CACf,WAAW;CACX,YAAY;CACZ,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,cAAc,MAAWF,MAAU,IAAI,kBAAkB,GAAGA,EAAM;CAClE,kBAAkB,GAAO,MAAQ,GAAGG,EAAM,MAAMC;CAChD,iBAAiB,GAAM,MAAWJ,MAAU,IAAIK,IAAO,GAAGA,EAAK,IAAIL,MAAU,IAAI,kBAAkB,GAAGA,EAAM;CAC5G,kBAAkB,GAAO,MAAQ,GAAGG,EAAM,MAAMC;CAChD,QAAQ;EAAE,WAAW;EAAa,SAAS;EAAW,WAAW;EAAa,WAAW;EAAa,QAAQ;CAAU;CACxH,UAAU;CACV,OAAO;CACP,SAAS;CACT,YAAY;CACZ,kBAAkB;CAClB,OAAO;CACP,qBAAqB,MAAU,eAAeE;AAC/C,GCzJMC,KAA2C;CAAC;CAAW;CAAW;CAAW;CAAW;CAAW;CAAW;CAAW;AAAS,GAG3HC,KAA4E;CACxF,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;AACZ;AAGA,SAAgBC,GAAc,GAAmC,GAAsC;CACtG,IAAMC,IAAQC,EAAW,WAAW,MAAaC,EAAS,OAAOC,CAAE;CAEnE,OADIH,IAAQ,IAAU,YACfC,EAAWD,EAAM,EAAE,SAASH,GAAaG,IAAQH,GAAa,WAAW;AACjF;AAEA,SAAgBO,EAAW,GAAkB;CAC5C,OAAO,IAAI,KAAKT,EAAK,YAAY,GAAGA,EAAK,SAAS,GAAGA,EAAK,QAAQ,CAAC;AACpE;AAEA,SAAgBU,EAAQ,GAAY,GAAoB;CACvD,OAAO,IAAI,KAAKV,EAAK,YAAY,GAAGA,EAAK,SAAS,GAAGA,EAAK,QAAQ,IAAIW,CAAI;AAC3E;AAEA,SAAgBC,EAAU,GAAS,GAAkB;CACpD,OAAOC,EAAE,YAAY,MAAMC,EAAE,YAAY,KAAKD,EAAE,SAAS,MAAMC,EAAE,SAAS,KAAKD,EAAE,QAAQ,MAAMC,EAAE,QAAQ;AAC1G;AAGA,SAAgBC,EAAU,GAAY,GAAsB;CAC3D,IAAMC,IAAS,IAAI,KAAKhB,EAAK,YAAY,GAAGA,EAAK,SAAS,IAAIiB,GAAQ,CAAC,GACjEC,IAAU,IAAI,KAAKF,EAAO,YAAY,GAAGA,EAAO,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ;CACjF,OAAO,IAAI,KAAKA,EAAO,YAAY,GAAGA,EAAO,SAAS,GAAG,KAAK,IAAIhB,EAAK,QAAQ,GAAGkB,CAAO,CAAC;AAC3F;AAEA,SAAgBC,EAAY,GAAY,GAA4B;CACnE,IAAMC,IAAMX,EAAWT,CAAI;CAC3B,OAAOU,EAAQU,GAAK,GAAGA,EAAI,OAAO,IAAIC,IAAe,KAAK,EAAE;AAC7D;AAGA,SAAgBC,GAAS,GAAY,GAA8B;CAClE,IAAMC,IAAQJ,EAAYnB,GAAMqB,CAAY;CAC5C,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAUX,EAAQa,GAAOlB,CAAK,CAAC;AACrE;AAGA,SAAgBmB,GAAU,GAAY,GAAgC;CACrE,IAAMD,IAAQJ,EAAY,IAAI,KAAKnB,EAAK,YAAY,GAAGA,EAAK,SAAS,GAAG,CAAC,GAAGqB,CAAY;CACxF,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAQX,EAAQa,GAAOE,IAAO,IAAIL,CAAG,CAAC,CAAC;AACpH;AAGA,SAAgBM,GAAS,GAA0B,GAAoB;CACtE,IAAMC,IAAWlB,EAAWW,CAAG,CAAC,CAAC,QAAQ,GACnCQ,IAASlB,EAAQU,GAAK,CAAC,CAAC,CAAC,QAAQ;CACvC,OAAOS,EAAY,MAAM,QAAQ,IAAID,KAAUC,EAAY,IAAI,QAAQ,IAAIF;AAC5E;AAEA,SAAgBG,EAAsC,GAAmB,GAAgB;CACxF,OAAOC,EACL,QAAQ,MAAgBL,GAASG,GAAaT,CAAG,CAAC,CAAC,CACnD,MAAM,GAAG,MAAMP,EAAE,MAAM,QAAQ,IAAIC,EAAE,MAAM,QAAQ,KAAKD,EAAE,IAAI,QAAQ,IAAIC,EAAE,IAAI,QAAQ,CAAC;AAC5F;AAGA,SAAgBkB,GAA0C,GAAmB,GAAkB,GAAsB;CACpH,OAAOD,EAAa,QAAQ,OAC1BxB,MAAa,SAASsB,EAAY,aAAatB,OAC/C0B,MAAY,SAASJ,EAAY,OAAO,OAAOI,EACjD;AACD;AAOA,SAAgBC,GAAqC,GAA6C;CACjG,IAAMC,oBAAU,IAAI,IAAiB;CACrC,KAAK,IAAMN,KAAeE,GAAc;EACvC,IAAI,CAACF,EAAY,SAASA,EAAY,WAAW,aAAa;EAC9D,IAAMO,IAAOD,EAAQ,IAAIN,EAAY,MAAM,EAAE,KAAK,CAAC;EAEnD,AADAO,EAAK,KAAKP,CAAW,GACrBM,EAAQ,IAAIN,EAAY,MAAM,IAAIO,CAAI;CACvC;CACA,IAAMC,IAAsC,CAAC;CAC7C,KAAK,IAAMD,KAAQD,EAAQ,OAAO,GAAG;EACpC,IAAMG,IAAS,CAAC,GAAGF,CAAI,CAAC,CAAC,MAAM,GAAG,MAAMvB,EAAE,MAAM,QAAQ,IAAIC,EAAE,MAAM,QAAQ,CAAC,GACzEyB,IAAa,CAAC,GACdC,IAAW,WACTC,UAAc;GACnB,IAAMlB,IAAQgB,EAAM;GACpB,AAAIA,EAAM,SAAS,KAAKhB,GAAO,SAAOc,EAAU,KAAK;IAAE,OAAOd,EAAM;IAAO,cAAcgB;IAAO,OAAOhB,EAAM;GAAM,CAAC;EACrH;EACA,KAAK,IAAMM,KAAeS,GACzB,AAAIT,EAAY,MAAM,QAAQ,IAAIW,KACjCD,EAAM,KAAKV,CAAW,GACtB,IAAW,KAAK,IAAIW,GAAUX,EAAY,IAAI,QAAQ,CAAC,MAEvDY,EAAM,GACN,IAAQ,CAACZ,CAAW,GACpB,IAAWA,EAAY,IAAI,QAAQ;EAGrC,EAAM;CACP;CACA,OAAOQ,EAAU,MAAM,GAAG,MAAMxB,EAAE,MAAM,QAAQ,IAAIC,EAAE,MAAM,QAAQ,CAAC;AACtE;AAGA,SAAgB4B,GAAe,GAA+C;CAC7E,OAAO,IAAI,IAAIL,EAAU,SAAS,MAAaM,EAAS,aAAa,KAAK,MAAgBd,EAAY,EAAE,CAAC,CAAC;AAC3G;AAGA,SAAgBe,GAAU,GAAkD;CAC3E,IAAMC,oBAAO,IAAI,IAA+B;CAChD,KAAK,IAAMhB,KAAeE,GAAc,AAAIF,EAAY,SAAS,CAACgB,EAAK,IAAIhB,EAAY,MAAM,EAAE,KAAGgB,EAAK,IAAIhB,EAAY,MAAM,IAAIA,EAAY,KAAK;CAClJ,OAAO,CAAC,GAAGgB,EAAK,OAAO,CAAC;AACzB;AAMA,SAAgBC,GAAW,GAAY,GAAyB;CAC/D,IAAM,EAAE,cAAW,IAAI,KAAK,eAAeC,GAAQ,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,gBAAgB;CACxF,IAAI,CAACC,GAAQ,OAAO,IAAI,KAAK,eAAeD,GAAQ;EAAE,MAAM;EAAW,QAAQ;CAAU,CAAC,CAAC,CAAC,OAAO/C,CAAI;CACvG,IAAMiD,IAAsCjD,EAAK,WAAW,MAAM,IAAI,EAAE,MAAM,UAAU,IAAI;EAAE,MAAM;EAAW,QAAQ;CAAU;CACjI,OAAO,IAAI,KAAK,eAAe+C,GAAQE,CAAO,CAAC,CAAC,OAAOjD,CAAI;AAC5D;AAEA,SAAgBkD,GAAW,GAAoE;CAC9F,OAAO,OAAOC,KAAW,WAAWA,IAASA,GAAQ;AACtD;;;ACvGA,IAAMC,IAAoD;CACzD,WAAW;CACX,SAAS;CACT,WAAW;CACX,WAAW;CACX,QAAQ;AACT;AA+BA,SAASC,GAAe,EAAE,gBAAa,cAA8D;CACpG,IAAM7C,IAAK8C,GAAM,GACXC,IAASL,GAAWrB,EAAY,MAAM,GACtC2B,IAAQ3B,EAAY,OACpB4B,IAAS,CAACF,GAAQC,GAAO,IAAI,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,GACzD,EAAE,SAAM,gBAAaE,GACrBC,IAAaD,EAAQ,QAAQ,SAAS,GAGtCE,IAAa;EAAC,GAAGpD,EAAG;EAAS,GAAGA,EAAG;EAAU,GAAGA,EAAG;EAAQiD,KAAU,GAAGjD,EAAG;CAAQ,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,GAC7GqD,IAAUC,EAA0B,IAAI,GACxCC,IAAkBD,EAAO,EAAK;CAUpC,OANAE,SAAsB;EACrB,AAAI,MAAeD,EAAgB,YACnC,EAAgB,UAAU,KACtB,CAAC,SAAS,iBAAiB,SAAS,kBAAkB,SAAS,SAAMF,EAAQ,SAAS,MAAM;CACjG,GAAG,CAACF,CAAU,CAAC,GAGd,kBAACvE,GAAD;EACC,MAAK;EACL,SAAQ;EACR,eAAayC,EAAY;EACzB,iBAAec,IAAW,KAAK,KAAA;EAC/B,WAAWtF,EACV,uDACA,CAAC,CAAC4G,KAAQzF,EAAmB,UAE7BmE,KAAY/E,EAAY,YAAY,IACrC;EAVD,UAAA;GAYE,CAAC,CAACqG,KACF,kBAAC,UAAD;IACC,KAAKJ;IACL,MAAK;IACL,mBAAiBD;IACjB,SAASK;IACT,WAAW5G,EAAG,0GAA0GmB,EAAmB,mBAAmBf,EAAa,KAAK;GAChL,CAAA;GAGF,kBAACE,GAAD;IAAO,KAAI;IAAO,WAAU;IAA5B,UAAA;KACC,kBAACL,GAAD;MAAM,KAAI;MAAO,MAAK;MAAU,QAAO;MAAS,eAAY;MAAO,WAAU;MAAqB,UAAAoG,EAAQ,KAAK;KAAY,CAAA;KAC3H,kBAACpG,GAAD;MAAM,KAAI;MAAO,MAAK;MAAK,MAAK;MAAY,eAAY;MAAO,WAAU;MAAqB,UAAAoG,EAAQ,KAAK;KAAU,CAAA;KACrH,kBAAC3E,GAAD,EAAA,UAAgB,kBAAC,QAAD;MAAM,IAAI,GAAGyB,EAAG;MAAS,UAAAkD,EAAQ;KAAW,CAAA,EAAiB,CAAA;IACvE;;GAEP,kBAAC,QAAD;IAAM,eAAY;IAAO,WAAWrG,EAAG,qEAAqEqG,EAAQ,kBAAkB;GAAI,CAAA;GAC1I,kBAACvE,GAAD;IAAa,WAAU;IAAvB,UAAA,CACC,kBAACE,IAAD;KAAW,WAAU;KAArB,UAAA,CAEC,kBAAC/B,GAAD;MAAM,MAAK;MAAU,IAAI,GAAGkD,EAAG;MAAS,KAAI;MAAO,QAAO;MAAS,WAAU;MAAuB,UAAAqB,EAAY;KAAY,CAAA,GAC5H,kBAAChD,GAAD;MAAO,IAAI,GAAG2B,EAAG;MAAU,MAAMkD,EAAQ;MAAY,MAAK;MACxD,UAAAA,EAAQ;KACH,CAAA,CACG;IACV,CAAA,GAAA,CAAC,CAACD,KACF,kBAACxE,GAAD;KAAiB,IAAI,GAAGuB,EAAG;KAAU,OAAO;KAAG,WAAU;KACvD,UAAAiD;IACe,CAAA,CAEN;;IACX,CAAC,CAACD,KAASG,MACZ,kBAACzE,GAAD;IAEC,WAAU;IAEV,eAAe;KAAE,EAAgB,UAAU;IAAM;IACjD,SAAS,MAAU;KAClB,AAAIgF,EAAM,yBAAyB,QAAQ,CAACA,EAAM,cAAc,SAASA,EAAM,aAAa,MAAG,EAAgB,UAAU;IAC1H;IAPD,UAAA,CASE,CAAC,CAACV,KAEF,kBAAC7E,GAAD;KAAQ,MAAK;KAAK,eAAY;KAAO,WAAU;KAA/C,UAAA,CACE,CAAC,CAAC6E,EAAM,aAAa,kBAAC5E,GAAD;MAAa,KAAK4E,EAAM;MAAW,KAAI;KAAI,CAAA,GACjE,kBAAC9E,GAAD,EAAA,UAAiBD,EAAe+E,EAAM,IAAI,EAAkB,CAAA,CACrD;IAER,CAAA,GAAAE,EAAQ,WACG;;EAET;;AAER;AAEA,SAAgBS,GAAkB,EAAE,SAAM,iBAAc,eAAY,cAAW,YAAS,YAAS,UAAO,YAAS,WAAQ,uBAAoB,uBAAoB,sBAAmB,YAAS,cAAW,gBAAqC;CAC5O,IAAMC,IAASzD,EAAK,KAAK,OAAS;EAAE;EAAK,OAAOmB,EAAeC,GAAcX,CAAG;CAAE,EAAE,GAE9EiD,IAAQ,IAAI,IAAID,EAAO,SAAS,MAAU7B,EAAM,MAAM,KAAK,MAAgBV,EAAY,EAAE,CAAC,CAAC,CAAC,CAAC,MAC7FyC,IAAY,IAAI,KAAK,eAAevB,GAAQ;EAAE,SAAS;EAAQ,OAAO;EAAQ,KAAK;CAAU,CAAC,GAC9FwB,IAAU5D,EAAK,SAAS,GAIxB6D,KAAc,MAAuD;EAC1E,IAAM7B,IAAWN,EAAU,IAAIR,EAAY,EAAE,GACvC4C,KAAWC,IAAqB7C,CAAW,KAAK,CAAC,EAAA,CAAG,QAAQ,MAAW8C,EAAO,YAAY,EAAK,GAC/FC,IAAO;GAAE,OAAO9B,GAAWjB,EAAY,OAAOkB,CAAM;GAAG,KAAKD,GAAWjB,EAAY,KAAKkB,CAAM;EAAE,GAChGW,IAAsB;GAC3B,UAAUpD,EAAW,MAAM,MAAaC,EAAS,OAAOsB,EAAY,QAAQ;GAC5E,oBAAoB1B,GAAgCC,GAAcE,GAAYuB,EAAY,QAAQ;GAClG;GACA,aAAac,IAAWkC,EAAQ,WAAWA,EAAQ,OAAOhD,EAAY;GACtE,YAAYc,IAAW,gBAAgBS,EAAYvB,EAAY;GAC/D,MAAMgD,EAAQ,gBAAgBD,EAAK,OAAOA,EAAK,GAAG;GAClD;GACA,MAAME,UAA2BA,EAAmBjD,CAAW,IAAI,KAAA;GACnE;GACA,aAAa4C,EAAQ,SAAS,IAC7B,kBAACnG,GAAD;IACU;IACT,QAAQuG,EAAQ,mBAAmBhD,EAAY,KAAK;IACpD,aAAa;KAAE,MAAM;KAAM,WAAW;IAA4C;GAClF,CAAA,IACE;EACL;EACA,OAAO;GAAE,GAAG6B;GAAS,qBAAqB,kBAACL,IAAD;IAA6B;IAAsB;GAAU,CAAA;EAAE;CAC1G,GAKMjB,KAAQ,MACb,kBAAC,MAAD;EAAI,WAAU;EACZ,UAAA2C,EAAM,KAAK,MAAgB;GAC3B,IAAMrB,IAAUc,EAAW3C,CAAW;GACtC,OACC,kBAAC,MAAD;IAAyB,WAAWxE,EAAG,2BAA2BU,EAAc,MAAM;IACpF,UAAAiH,IAAoBA,EAAkBnD,GAAa6B,CAAO,IAAIA,EAAQ,cAAc;GAClF,GAFK7B,EAAY,EAEjB;EAEN,CAAC;CACE,CAAA,GAGDoD;CAgDJ,OA/CA,AA4CCA,IA5CGC,IAEF,kBAACvH,GAAD;EAAO,KAAI;EAAK,aAAU;EAAO,WAAU;EAA3C,UAAA,CACC,kBAACoB,GAAD,EAAA,UAAiB8F,EAAQ,QAAwB,CAAA,GAChD,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAU,kBAACtG,GAAD,EAAsB,WAAU,qCAAsC,GAAvD8B,CAAuD,CAAC,CAC1G;MAEE8E,IAEHC,GAAeD,CAAK,IAAIA,IAC9B,kBAAC/G,GAAD;EACC,SAAQ;EACR,OAAOyG,EAAQ;EACf,aAAaM,aAAiB,QAAQA,EAAM,UAAU,OAAOA,KAAU,YAAY,OAAOA,KAAU,WAAW,OAAOA,CAAK,IAAIN,EAAQ;EAC9H;EACT,YAAYA,EAAQ;EACpB,WAAU;CACV,CAAA,IAEQN,IAGT,kBAAC5G,GAAD;EAAO,KAAI;EACT,UAAAyG,EAAO,KAAK,MAAU;GACtB,IAAMiB,IAAOf,EAAU,OAAO/B,EAAM,GAAG;GACvC,OACC,kBAAC5E,GAAD;IAAqC,QAAQ,kBAAC,WAAD,CAAU,CAAA;IAAG,KAAI;IAAK,cAAY0H;IAAM,WAAU;IAA/F,UAAA,CACC,kBAAC1H,GAAD;KAAO,WAAU;KAAa,OAAM;KAAW,SAAQ;KAAU,KAAI;KAAK,MAAM;KAAhF,UAAA,CACC,kBAACJ,GAAD;MAAS,WAAU;MAAuB,KAAI;MAAK,MAAMC,EAAiB;MAAa,UAAA6H;KAAc,CAAA,GACpG9C,EAAM,MAAM,SAAS,KACrB,kBAACjF,GAAD;MAAM,KAAI;MAAO,MAAK;MAAK,MAAK;MAAY,WAAU;MAAuD,UAAAuH,EAAQ,YAAYtC,EAAM,MAAM,MAAM;KAAQ,CAAA,CAEtJ;IACN,CAAA,GAAAA,EAAM,MAAM,SAAS,IACnBH,EAAKG,EAAM,KAAK,IAChB,kBAACjF,GAAD;KAAM,MAAK;KAAK,MAAK;KAAY,WAAU;KAAiC,UAAAuH,EAAQ;IAAY,CAAA,CAC7F;GAVK,GAAAtC,EAAM,IAAI,YAAY,CAU3B;EAET,CAAC;CACK,CAAA,IAEE8B,MAAU,IACb,kBAAC5E,IAAD;EAAY,SAAQ;EAAK,OAAOoF,EAAQ;EAAO,aAAa;EAAO,WAAWA,EAAQ;EAAO,WAAU;CAA6B,CAAA,IAEpIzC,EAAKgC,EAAO,EAAE,EAAE,SAAS,CAAC,CAAC,GAIlC,kBAACzG,GAAD;EACC,KAAK2H;EACL,KAAI;EAEJ,MAAK;EACL,cAAYC;EACZ,UAAU;EACV,WAAWlI,EAAG,8DAA8DI,EAAa,OAAO+H,CAAS;EAP1G,UAAA,CASC,kBAAC7H,GAAD;GAAO,WAAU;GAAa,OAAM;GAAW,SAAQ;GAAU,KAAI;GAAK,MAAM;GAAO,WAAU;GAAjG,UAAA,CAEC,kBAACJ,GAAD;IAAS,KAAI;IAAI,WAAU;IAAwB,UAAAgI;GAAiB,CAAA,GAEnE,CAACL,KAAW,CAACC,KACb,kBAAC7H,GAAD;IAAM,KAAI;IAAO,MAAK;IAAK,MAAK;IAAY,WAAU;IAAmD,UAAAuH,EAAQ,YAAYR,CAAK;GAAQ,CAAA,CAErI;EACP,CAAA,GAAA,kBAACrF,IAAD;GAAY,WAAU;GACpB,UAAAiG;EACU,CAAA,CACN;;AAET;;;ACnPA,IAAMQ,IAAW;AAEjB,SAAgBC,GAAiB,EAAE,aAAU,aAAU,yBAAsB,iBAAc,eAAY,iBAAc,WAAQ,cAAkC;CAC9J,IAAM,CAACC,GAASC,KAAcC,EAASC,CAAQ,GACzCC,IAAUjC,EAAuB,IAAI,GACrCkC,IAAgBlC,EAAO,EAAK,GAC5B,CAACmC,KAASJ,wBAAe,IAAI,KAAK,CAAC,GAKnCK,IAAeJ,EAAS,YAAY,GACpCK,IAAgBL,EAAS,SAAS,GAClCM,IAAeN,EAAS,QAAQ;CACtC,SAAgBF,EAAW,IAAI,KAAKM,GAAcC,GAAeC,CAAY,CAAC,GAAG;EAACF;EAAcC;EAAeC;CAAY,CAAC;CAC5H,IAAMC,IAAeV,EAAQ,YAAY,IAAI,KAAKA,EAAQ,SAAS;CAInE,AAHAW,SAAgB;EACf,IAAuB,IAAI,KAAK,KAAK,MAAMD,IAAe,EAAE,GAAGA,IAAe,IAAI,CAAC,CAAC;CACrF,GAAG,CAACA,GAAcE,CAAoB,CAAC,GACvCD,SAAgB;EACf,AAAKN,EAAc,YACnB,EAAc,UAAU,IACxBD,EAAQ,SAAS,cAAiC,qBAAqB,CAAC,EAAE,MAAM;CACjF,GAAG,CAACJ,CAAO,CAAC;CAEZ,IAAMa,IAAQC,QAAcjF,GAAUmE,GAAStE,CAAY,GAAG,CAACsE,GAAStE,CAAY,CAAC,GAC/EqF,IAAcD,QAAc,IAAI,KAAK,eAAe1D,GAAQ,EAAE,OAAO,OAAO,CAAC,GAAG,CAACA,CAAM,CAAC,GAExF4D,IAAkBF,QAAc,IAAI,KAAK,eAAe1D,GAAQ;EAAE,OAAO;EAAQ,MAAM;CAAU,CAAC,GAAG,CAACA,CAAM,CAAC,GAC7G6D,IAAgBH,QAAc,IAAI,KAAK,eAAe1D,GAAQ,EAAE,SAAS,QAAQ,CAAC,GAAG,CAACA,CAAM,CAAC,GAC7F8D,IAAoBJ,QAAc,IAAI,KAAK,eAAe1D,GAAQ,EAAE,SAAS,OAAO,CAAC,GAAG,CAACA,CAAM,CAAC,GAChGuB,KAAYmC,QAAc,IAAI,KAAK,eAAe1D,GAAQ;EAAE,SAAS;EAAQ,OAAO;EAAQ,KAAK;EAAW,MAAM;CAAU,CAAC,GAAG,CAACA,CAAM,CAAC,GACxI+D,IAAeL,QAAc,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAW;EAAE,OAAO,OAAOM,CAAK;EAAG,OAAOL,EAAY,OAAO,IAAI,KAAK,KAAMK,GAAO,CAAC,CAAC;CAAE,EAAE,GAAG,CAACL,CAAW,CAAC,GACrKM,IAAcP,QAAc;EACjC,IAAMQ,oBAAQ,IAAI,IAAY,CAAChB,EAAM,YAAY,GAAGN,EAAQ,YAAY,CAAC,CAAC;EAC1E,KAAK,IAAM9D,KAAeE,GAAc,EAAM,IAAIF,EAAY,MAAM,YAAY,CAAC;EACjF,IAAMqF,IAAM,KAAK,IAAI,GAAGD,CAAK,IAAI,GAC3BE,IAAM,KAAK,IAAI,GAAGF,CAAK,IAAI;EACjC,OAAO,MAAM,KAAK,EAAE,QAAQE,IAAMD,IAAM,EAAE,IAAI,GAAG,OAAW;GAAE,OAAO,OAAOA,IAAM7G,CAAK;GAAG,OAAO,OAAO6G,IAAM7G,CAAK;EAAE,EAAE;CACxH,GAAG;EAAC0B;EAAc4D;EAASM;CAAK,CAAC,GAE3BmB,KAAU,GAAY,IAAS,OAAU;EAG9C,AAFA,EAAc,UAAU,IACxBxB,EAAW5F,CAAI,GACXqH,KAAQC,EAAStH,CAAI;CAC1B,GAGMuH,KAAe,MAAmB;EACvC,IAAMC,IAAOzG,EAAU4E,GAAS1E,CAAM;EAEtC,AADA2E,EAAW4B,CAAI,GACfF,EAASE,CAAI;CACd;CAmBA,OACC,kBAAC7J,GAAD;EAAO,KAAI;EAAK,WAAU;EAA1B,UAAA,CACC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACC,kBAACD,GAAD;KAAQ,MAAK;KAAS,MAAK;KAAY,aAAY;KAAQ,MAAK;KAAK,UAAA;KAAS,cAAYmH,EAAQ;KAAe,eAAe0C,EAAY,EAAE;KAC7I,UAAA,kBAACE,IAAD;MAAa,eAAY;MAAO,WAAU;KAAa,CAAA;IAChD,CAAA;IACR,kBAAC3I,GAAD;KACC,MAAK;KACL,cAAY+F,EAAQ;KACpB,SAASiC;KACT,OAAO,OAAOnB,EAAQ,SAAS,CAAC;KAChC,gBAAgB,MAAU+B,MAAU,KAAA,KAAaH,EAAY,OAAOG,CAAK,IAAI/B,EAAQ,SAAS,CAAC;KAC/F,WAAU;IACV,CAAA;IACD,kBAAC7G,GAAD;KACC,MAAK;KACL,cAAY+F,EAAQ;KACpB,SAASmC;KACT,OAAO,OAAOrB,EAAQ,YAAY,CAAC;KACnC,gBAAgB,MAAU+B,MAAU,KAAA,KAAaH,GAAa,OAAOG,CAAK,IAAI/B,EAAQ,YAAY,KAAK,EAAE;KACzG,WAAU;IACV,CAAA;IACD,kBAACjI,GAAD;KAAQ,MAAK;KAAS,MAAK;KAAY,aAAY;KAAQ,MAAK;KAAK,UAAA;KAAS,cAAYmH,EAAQ;KAAW,eAAe0C,EAAY,CAAC;KACxI,UAAA,kBAACI,IAAD;MAAc,eAAY;MAAO,WAAU;KAAa,CAAA;IACjD,CAAA;GACJ;EAGL,CAAA,GAAA,kBAAC,OAAD;GACC,KAAK5B;GACL,MAAK;GACL,cAAYY,EAAgB,OAAOhB,CAAO;GAC/B,YAjDK,MAAyC;IAW3D,IAAMiC,IAAO;KATZ,iBAAiBlH,EAAQiF,GAAS,EAAE;KACpC,kBAAkBjF,EAAQiF,GAAS,CAAC;KACpC,eAAejF,EAAQiF,GAAS,EAAE;KAClC,iBAAiBjF,EAAQiF,GAAS,CAAC;KACnC,YAAYxE,EAAYwE,GAAStE,CAAY;KAC7C,WAAWX,EAAQS,EAAYwE,GAAStE,CAAY,GAAG,CAAC;KACxD,cAAcN,EAAU4E,GAASzB,EAAM,WAAW,MAAM,EAAE;KAC1D,gBAAgBnD,EAAU4E,GAASzB,EAAM,WAAW,KAAK,CAAC;IAE9C,EAAMA,EAAM;IACzB,AAAK0D,MACL1D,EAAM,eAAe,GACrBkD,EAAOQ,EAAK,CAAC;GACd;GAoCG,WAAU;GANX,UAAA,CAQC,kBAAC,OAAD;IAAK,MAAK;IAAM,WAAU;IACxB,UAAApB,EAAM,EAAE,EAAE,KAAK,MACf,kBAAClJ,GAAD;KAAyB,KAAI;KAAM,MAAK;KAAe,cAAYuJ,EAAkB,OAAOzF,CAAG;KAAG,MAAK;KAAK,MAAK;KAAY,QAAO;KAAS,OAAM;KAAS,WAAU;KACpK,UAAAwF,EAAc,OAAOxF,CAAG;IACpB,GAFKA,EAAI,OAAO,CAEhB,CACN;GACG,CAAA,GACJoF,EAAM,KAAK,MACX,kBAAC,OAAD;IAAkC,MAAK;IAAM,WAAU;IACrD,UAAA/E,EAAK,KAAK,MAAQ;KAClB,IAAMoG,IAAkB/F,EAAeC,GAAcX,CAAG,GAElD0G,IAAS,IAAI,IAAID,EAAgB,KAAK,MAAgBhG,EAAY,QAAQ,CAAC,GAC3EkG,IAAgB,CACrB,GAAGzH,EAAW,QAAQ,MAAawH,EAAO,IAAIvH,EAAS,EAAE,CAAC,CAAC,CAAC,KAAK,MAAaA,EAAS,EAAE,GACzF,GAAG,CAAC,GAAGuH,CAAM,CAAC,CAAC,QAAQ,MAAO,CAACxH,EAAW,MAAM,MAAaC,EAAS,OAAOC,CAAE,CAAC,CACjF,GACMwH,IAAapH,EAAUQ,GAAK0E,CAAQ,GACpCmC,IAAYrH,EAAUQ,GAAKuE,CAAO,GAClCuC,IAAUtH,EAAUQ,GAAK6E,CAAK,GAC9BkC,IAAU/G,EAAI,SAAS,MAAMuE,EAAQ,SAAS;KACpD,OACC,kBAAC,OAAD;MAA6B,MAAK;MAAW,iBAAeqC;MAAY,WAAU;MACjF,UAAA,kBAAC,UAAD;OACC,MAAK;OACL,UAAUC,IAAY,IAAI;OAC1B,qBAAmBA,IAAY,KAAK,KAAA;OACpC,iBAAeD,IAAa,KAAK,KAAA;OACjC,gBAAcG,IAAU,KAAK,KAAA;OAC7B,cAAYD,IAAU,KAAK,KAAA;OAC3B,gBAAcA,IAAU,SAAS,KAAA;OACjC,cAAYrD,EAAQ,eAAeP,GAAU,OAAOlD,CAAG,GAAGyG,EAAgB,MAAM;OAChF,eAAeT,EAAOhG,GAAK,EAAI;OAC/B,WAAW/D,EACVmB,EAAmB,mBAEnB,+LACAf,EAAa,OACbuK,IACG,qDACA3K,EAAGmB,EAAmB,UAAU2J,IAAU,0BAA0B,iBAAiB,GAExF,CAACH,KAAcE,KAAW,4BAC3B;OApBD,UAAA,CAsBE9G,EAAI,QAAQ,GAEb,kBAAC,QAAD;QAAM,eAAY;QAAO,WAAU;QAAnC,UAAA,CACE2G,EAAc,MAAM,GAAGtC,CAAQ,CAAC,CAAC,KAAK,MACtC,kBAAC,QAAD;SAAqB,iBAAelF;SAAU,WAAWlD,EAAGQ,EAAW,QAAQsC,GAAgCC,GAAcE,GAAYC,CAAQ,EAAE;QAAI,GAA5IA,CAA4I,CACvJ,GACAwH,EAAc,SAAStC,KACvB,kBAACnI,GAAD;SAAM,KAAI;SAAO,MAAK;SAAK,MAAK;SAAU,YAAW;SAAO,WAAU;SAA0B,UAAA;QAAO,CAAA,CAEnG;OACC,CAAA,CAAA;;KACJ,GAlCK8D,EAAI,YAAY,CAkCrB;IAEP,CAAC;GACG,GAnDKK,EAAK,EAAE,EAAE,YAAY,CAmD1B,CACL,CACG;EACC,CAAA,CAAA;;AAET;;;ACpKA,SAAS2G,GAAmB,GAAsB,GAAa,GAAsD;CACpH,IAAM,CAACC,GAAOC,KAAYzC,EAAS0C,CAAQ;CAE3C,OAAO,CADSb,KAASW,IACP,MAAY;EAE7B,AADIX,MAAU,KAAA,KAAWY,EAASd,CAAI,GACtCgB,IAAWhB,CAAI;CAChB,CAAC;AACF;AAEA,SAAgBiB,GAAyD,EACxE,iBACA,eACA,OAAOC,GACP,UACA,MAAMC,GACN,gBACA,iBACA,MAAMC,GACN,iBAAc,OACd,iBACA,UAAUC,GACV,qBAAkB,OAClB,qBACA,SAASC,IACT,oBAAiB,OACjB,oBACA,uBACA,uBACA,uBACA,mBACA,yBACA,wBACA,cAAU,IACV,WACA,aACA,cAAcC,GACd,QAAQC,GACR,aAAU,QACV,SAASC,GACT,iBAC+B;CAC/B,IAAMpE,IAAUqE,EAAWxJ,IAAmCuJ,CAAW,GACnEE,KAAa/L,EAAoB,GACjC2F,IAASiG,KAAcG,GAAW,QAClCC,KAAQjM,EAAe,GACvBkE,IAAe0H,KAAoBK,GAAM,gBAAgB,GAEzD,CAACnD,MAASJ,QAAepF,kBAAW,IAAI,KAAK,CAAC,CAAC,GAC/C,CAACT,GAAMqJ,MAAWjB,GAAgBO,GAAUW,KAAerD,IAAOsD,CAAY,GAC9E,CAACC,GAAMC,MAAWrB,GAAyCQ,GAAUc,GAAaC,CAAY,GAC9F,CAACpJ,IAAUqJ,MAAexB,GAAgBS,GAAcgB,GAAiBC,CAAgB,GACzF,CAAC7H,GAAS8H,MAAc3B,GAAgBU,IAAakB,GAAgBC,CAAe,GACpF,CAACC,IAAWC,MAAgBtE,EAAiB,EAAE,GAC/C,CAACQ,IAAc+D,MAAmBvE,QAAe,IAAI,KAAK7F,EAAK,YAAY,GAAGA,EAAK,SAAS,GAAG,CAAC,CAAC,GAEjGwD,KAAQiD,QAAciC,KAAa9F,GAAUb,CAAY,GAAG,CAAC2G,GAAW3G,CAAY,CAAC,GACrFpB,IAAO8F,QAAe+C,MAAS,SAASlI,GAAStB,GAAMqB,CAAY,IAAI,CAACZ,EAAWT,CAAI,CAAC,GAAI;EAACwJ;EAAMxJ;EAAMqB;CAAY,CAAC,GACtHgJ,KAAU5D,QAAczE,GAAmBD,GAAcxB,IAAU0B,CAAO,GAAG;EAACF;EAAcxB;EAAU0B;CAAO,CAAC,GAG9GqI,KAAQ7D,QAAoC;EACjD,IAAM8D,IAAQ,CAAC,GAAG/I,GAAU6E,IAAchF,CAAY,CAAC,CAAC,KAAK,GAAG,GAAGV,CAAI,CAAC,CAAC,KAAK,MAAQS,EAAI,QAAQ,CAAC;EACnG,OAAO;GAAE,OAAO,IAAI,KAAK,KAAK,IAAI,GAAGmJ,CAAK,CAAC;GAAG,KAAK7J,EAAQ,IAAI,KAAK,KAAK,IAAI,GAAG6J,CAAK,CAAC,GAAG,CAAC;EAAE;CAC7F,GAAG;EAAClE;EAAchF;EAAcV;CAAI,CAAC,GAC/B6J,KAAgB1G,EAAO,EAAE;CAC/B,SAAgB;EACf,IAAM2G,IAAM,GAAGH,GAAM,MAAM,QAAQ,EAAE,GAAGA,GAAM,IAAI,QAAQ;EAC1D,AAAIG,MAAQD,GAAc,YAC1B,GAAc,UAAUC,GACxBC,KAAgBJ,EAAK;CACtB,GAAG,CAACA,IAAOI,EAAa,CAAC;CACzB,IAAMC,KAAUlE,QAAc4D,GAAQ,QAAQ,MAAgB1J,EAAK,MAAM,MAAQe,GAASG,GAAaT,CAAG,CAAC,CAAC,GAAG,CAACiJ,IAAS1J,CAAI,CAAC,GAIxH0B,IAAYoE,QAEVvE,GADaF,GAAmBD,GAAc,OAAOE,CAAO,CAAC,CAAC,QAAQ,MAAgBtB,EAAK,MAAM,MAAQe,GAASG,GAAaT,CAAG,CAAC,CACrH,CAAW,GAC9B;EAACW;EAAcE;EAAStB;CAAI,CAAC,GAC1BiK,KAAcnE,QAAc/D,GAAeL,CAAS,GAAG,CAACA,CAAS,CAAC,GAClEwI,KAAmBF,GAAQ,QAAQ,MAAgBC,GAAY,IAAI/I,EAAY,EAAE,CAAC,CAAC,CAAC,QACpFiG,KAAS6C,GAAQ,QAAQ,MAAgB9I,EAAY,WAAW,WAAW,CAAC,CAAC,QAC7EiJ,KAAc,CAAC,GAAGF,EAAW,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAC9CG,KAAY1I,EAAU,SAAS,KAAK6H,OAAcY,IAElDE,KAAgB,IAAI,KAAK,eAAejI,GAAQ;EAAE,SAAS;EAAQ,OAAO;EAAQ,KAAK;CAAU,CAAC,GAClGkI,KAAc,IAAI,KAAK,eAAelI,GAAQ;EAAE,OAAO;EAAQ,KAAK;CAAU,CAAC,GAC/EwC,KAAUiE,MAAS,SACtB3E,EAAQ,gBAAgBoG,GAAY,OAAOtK,EAAK,MAAMX,CAAI,GAAGiL,GAAY,OAAOtK,EAAKA,EAAK,SAAS,MAAMX,CAAI,CAAC,IAC9GgL,GAAc,OAAOhL,CAAI,GAItBkL,KAAYpH,EAAuB,IAAI,GACvCqH,KAAcrH,EAAO,EAAK,GAC1BsH,MAAoB,MAAoC;EAG7D,AAFA,GAAY,UAAU,IACtBjB,GAAaW,EAAW,GACxBO,KAAqBC,CAAK;CAC3B;CACA,SAAsB;EACrB,AAAI,OAAcH,GAAY,YAC9B,GAAY,UAAU,IACtBD,GAAU,SAAS,MAAM;CAC1B,GAAG,CAACH,EAAS,CAAC;CAKd,IAAMQ,IAASC,MAAY;CAE3B,OACC,kBAAC,OAAD;EACC,aAAU;EACV,aAAWhC;EACX,gBAAcgC;EACd,WAAWnO,EACV,iGACAkO,KAAUlO,EAAGS,EAAe,OAAO,iBAAiB,GACpD0H,EACD;EARD,UAAA;GAUC,kBAAC,OAAD;IAAK,WAAWnI,EACf,gGACAU,EAAc,QACdwN,IAAS,cAAc,YACxB;IAJA,UAAA,CAKC,kBAAC5N,GAAD;KAAO,KAAI;KAAS,WAAU;KAA9B,UAAA,CACE,CAAC,CAACsC,KAAS,kBAAC1C,GAAD;MAAS,WAAU;MAAe,KAAI;MAAK,MAAK;MAAM,UAAA0C;KAAe,CAAA,GAEhF,CAACiF,MAAW,CAACC,MACb,kBAAC7H,GAAD;MAAM,MAAK;MAAK,MAAK;MAAY,WAAU;MAA3C,UAAA,CACEuH,EAAQ,aAAaiD,EAAM,GAC3B+C,KAAmB,KAAK,MAAMhG,EAAQ,gBAAgBgG,EAAgB,GAClE;KAED,CAAA,CAAA;IAEP,CAAA,GAAA,kBAAC,OAAD;KAAK,WAAWxN,EAAG,qEAAqEgB,EAAmB,QAAQ;KAAnH,UAAA;MAEC,kBAACmB,IAAD;OAAM,OAAOgK;OAAM,gBAAgB,OAAUhC,MAAS,SAASA,MAAS,WAAWiC,GAAQjC,CAAI;OAC9F,UAAA,kBAACjI,IAAD;QAAU,MAAK;QAAQ,cAAYsF,EAAQ;QAAW,oBAAkB,KAAA;QACrE,UAAA,CAAC,OAAO,MAAM,CAAC,CAAW,KAAK,MAChC,kBAACvF,IAAD;SAA0B,OAAOmM;SAAQ,MAAK;SAAS,iBAAe,KAAA;SAAW,iBAAe,KAAA;SAAW,gBAAcjC,MAASiC;SAChI,UAAA5G,EAAQ4G;QACG,GAFKA,CAEL,CACb;OACQ,CAAA;MACL,CAAA;MACLjI,GAAM,SAAS,KACf,kBAAC1E,GAAD;OACC,cAAY+F,EAAQ;OACpB,SAAS,CAAC;QAAE,OAAO;QAAO,OAAOA,EAAQ;OAAS,GAAG,GAAGrB,GAAM,KAAK,OAAY;QAAE,OAAOL,EAAO;QAAI,OAAOA,EAAO;OAAK,EAAE,CAAC;OACzH,OAAOlB;OACP,gBAAgB,MAAS8H,GAAWvC,KAAQ,KAAK;OACjD,WAAU;MACV,CAAA;MAED,CAAC,CAACkE,MACF,kBAAChO,GAAD;OAAQ,MAAK;OAAS,MAAK;OAAU,eAAegO,GAAoB1L,CAAI;OAAG,WAAU;OAAzF,UAAA,CACC,kBAAC2L,IAAD;QAAM,eAAY;QAAO,WAAU;OAAa,CAAA,GAC/C9G,EAAQ,cACF;;KAEL;IACD,CAAA,CAAA;;GAEJkG,MAEA,kBAAC,OAAD;IAAK,WAAW1N,EAAG,wCAAwCU,EAAc,QAAQwN,IAAS,cAAc,YAAY;IACnH,UAAA,kBAACtN,GAAD;KAAO,MAAK;KAAc,WAAU;KAApC,UAAA;MACC,kBAAC2N,IAAD,EAAe,eAAY,OAAQ,CAAA;MACnC,kBAAC5N,GAAD,EAAA,UAAa6G,EAAQ,cAA0B,CAAA;MAC/C,kBAAC3G,GAAD,EAAA,UACEmE,EAAU,KAAK,MAAawC,EAAQ,eAAelC,EAAS,MAAM,MAAMA,EAAS,aAAa,QAAQG,GAAWH,EAAS,OAAOI,CAAM,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EACnI,CAAA;MAClB,kBAAC5E,GAAD,EAAA,UACC,kBAACT,GAAD;OAAQ,MAAK;OAAS,MAAK;OAAK,eAAe0N,GAAiB/I,CAAS;OAAI,UAAAwC,EAAQ;MAAgB,CAAA,EACzF,CAAA;KACP;;GACH,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAW;IAAhB,UAAA,CAEC,kBAAC,OAAD;KAAK,WAAWxH,EACf,uCACAU,EAAc,QACd,sHACAwN,IAAS,cAAc,iDACxB;KACC,UAAA,kBAAC5N,GAAD;MAAO,KAAI;MAAK,WAAU;MAA1B,UAAA,CACC,kBAAC+H,IAAD;OACC,UAAU1F;OACV,UAAUqJ;OACV,sBAAsBe;OACtB,cAAcC;OACF;OACE;OACN;OACC;MACT,CAAA,GACA/J,EAAW,SAAS,KACpB,kBAACd,IAAD;OAAM,OAAOe;OAAU,gBAAgB,MAAS,OAAOiH,KAAS,YAAYoC,GAAYpC,CAAI;OAE3F,UAAA,kBAACjI,IAAD;QAAU,SAAQ;QAAQ,MAAK;QAAQ,cAAYsF,EAAQ;QAAiB,oBAAkB,KAAA;QAAW,WAAU;QACjH,UAAA,CAAC;SAAE,IAAI;SAAO,OAAOA,EAAQ;QAAc,GAAG,GAAGvE,CAAU,CAAC,CAAC,KAAK,MAClE,kBAAChB,IAAD;SAA6B,OAAOmM,EAAO;SAAI,MAAK;SAAS,iBAAe,KAAA;SAAW,iBAAe,KAAA;SAAW,gBAAclL,OAAakL,EAAO;SAAI,WAAU;SAAjK,UAAA,CACEA,EAAO,OAAO,SACd,kBAAC,QAAD;UAAM,eAAY;UAAO,WAAWpO,EAAGQ,EAAW,QAAQsC,GAAgCC,GAAcE,GAAYmL,EAAO,EAAE,EAAE;SAAI,CAAA,GAEnIA,EAAO,KACI;QALK,GAAAA,EAAO,EAKZ,CACb;OACQ,CAAA;MACL,CAAA,CAED;;IACH,CAAA,GAEL,kBAACtH,IAAD;KACC,WAAW+G;KACL;KACN,cAAcb;KACF;KACZ,WAAWO;KACF;KACA;KACF;KACE;KACD;KACR,WAAWW,IAAS,cAAc;KAEd;KACA;KACD;KACV;IACT,CAAA,CACG;;EACD;;AAEP;AAEA,GAAoB,cAAc"}
|