@openway/ui 1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/components/button/constants.ts","../src/utils/function.ts","../src/components/icons/Spinner.tsx","../src/components/button/Button.tsx","../src/components/button/IconButton.tsx","../src/components/badge/constants.ts","../src/components/icons/CloseIcon.tsx","../src/components/badge/Badge.tsx","../src/components/input/Input.tsx","../src/components/input/constants.ts","../src/hooks/useAnimatedError.ts","../src/components/common/HelperErrorText.tsx","../src/components/input/PasswordInput.tsx","../src/components/icons/EyeIcon.tsx","../src/components/input/NumberInput.tsx","../src/components/input/utils.ts","../src/components/input/OtpInput.tsx","../src/components/input/MultiInput.tsx","../src/components/icons/PlusIcon.tsx","../src/components/textarea/TextArea.tsx","../src/components/textarea/constants.ts","../src/components/checkbox/Checkbox.tsx","../src/components/checkbox/constants.ts","../src/components/checkbox/context.ts","../src/components/icons/CheckIcon.tsx","../src/components/icons/MinusIcon.tsx","../src/components/checkbox/CheckboxGroup.tsx","../src/components/radio/Radio.tsx","../src/components/radio/constants.ts","../src/components/radio/context.ts","../src/components/icons/RadioDotIcon.tsx","../src/components/radio/RadioGroup.tsx","../src/components/toggle/Toggle.tsx","../src/components/toggle/constants.ts","../src/components/icons/ChevronDownIcon.tsx","../src/components/icons/ChevronLeftIcon.tsx","../src/components/icons/ChevronRightIcon.tsx","../src/components/icons/CalendarIcon.tsx","../src/components/icons/ClockIcon.tsx","../src/components/icons/DoubleChevronLeftIcon.tsx","../src/components/icons/DoubleChevronRightIcon.tsx","../src/components/icons/EmptyDefaultIcon.tsx","../src/components/icons/EmptySearchIcon.tsx","../src/components/icons/EmptyErrorIcon.tsx","../src/components/icons/EmptyFolderIcon.tsx","../src/components/icons/EmptySimpleIcon.tsx","../src/components/icons/InfoCircleIcon.tsx","../src/components/icons/CheckCircleIcon.tsx","../src/components/icons/AlertTriangleIcon.tsx","../src/components/icons/AlertCircleIcon.tsx","../src/components/icons/ZoomInIcon.tsx","../src/components/icons/ZoomOutIcon.tsx","../src/components/icons/RotateCwIcon.tsx","../src/components/icons/RotateCcwIcon.tsx","../src/components/icons/FlipHorizontalIcon.tsx","../src/components/icons/DownloadIcon.tsx","../src/components/icons/ResetIcon.tsx","../src/components/icons/ImageIcon.tsx","../src/components/icons/CropIcon.tsx","../src/components/icons/SearchIcon.tsx","../src/components/icons/TrashIcon.tsx","../src/components/icons/UploadIcon.tsx","../src/components/alert/constants.ts","../src/components/alert/Alert.tsx","../src/components/toast/Toaster.tsx","../src/components/toast/constants.ts","../src/components/toast/toast.tsx","../src/components/tooltip/Tooltip.tsx","../src/components/tooltip/constants.ts","../src/constants/constants.ts","../src/components/slider/Slider.tsx","../src/components/slider/constants.ts","../src/components/slider/SliderThumb.tsx","../src/components/slider/utils.ts","../src/components/slider/SliderMarks.tsx","../src/components/collapse/Collapse.tsx","../src/components/collapse/constants.ts","../src/components/collapse/context.ts","../src/components/collapse/CollapsePanel.tsx","../src/components/collapse/CollapseHeader.tsx","../src/components/collapse/CollapseContent.tsx","../src/components/collapse/Collapsible.tsx","../src/components/tabs/Tabs.tsx","../src/components/tabs/context.ts","../src/components/tabs/TabList.tsx","../src/components/tabs/constants.ts","../src/components/tabs/useTabIndicator.ts","../src/components/tabs/Tab.tsx","../src/components/tabs/TabPanels.tsx","../src/components/tabs/TabPanel.tsx","../src/components/carousel/context.ts","../src/components/carousel/useCarousel.ts","../src/components/carousel/constants.ts","../src/components/carousel/Carousel.tsx","../src/components/carousel/CarouselContent.tsx","../src/components/carousel/CarouselSlide.tsx","../src/components/carousel/CarouselNavigation.tsx","../src/components/carousel/CarouselPagination.tsx","../src/components/dropdown/Dropdown.tsx","../src/components/dropdown/context.ts","../src/components/dropdown/DropdownTrigger.tsx","../src/components/dropdown/DropdownMenu.tsx","../src/components/dropdown/constants.ts","../src/components/dropdown/DropdownItem.tsx","../src/components/dropdown/DropdownHeader.tsx","../src/components/dropdown/DropdownSeparator.tsx","../src/components/dropdown/DropdownGroup.tsx","../src/components/popover/Popover.tsx","../src/components/popover/context.ts","../src/components/popover/PopoverTrigger.tsx","../src/components/popover/PopoverContent.tsx","../src/components/popover/constants.ts","../src/components/popover/PopoverHeader.tsx","../src/components/popover/PopoverBody.tsx","../src/components/popover/PopoverFooter.tsx","../src/components/popover/PopoverClose.tsx","../src/components/datepicker/DatePicker.tsx","../src/components/datepicker/Calendar.tsx","../src/components/datepicker/constants.ts","../src/components/datepicker/utils.ts","../src/components/datepicker/CalendarHeader.tsx","../src/components/datepicker/DayGrid.tsx","../src/components/datepicker/MonthGrid.tsx","../src/components/datepicker/YearGrid.tsx","../src/components/daterangepicker/DateRangePicker.tsx","../src/components/daterangepicker/DateRangeCalendar.tsx","../src/components/daterangepicker/constants.ts","../src/components/daterangepicker/DateRangeHeader.tsx","../src/components/daterangepicker/DateRangeDayGrid.tsx","../src/components/daterangepicker/DateRangeMonthGrid.tsx","../src/components/daterangepicker/DateRangeYearGrid.tsx","../src/components/daterangepicker/utils.ts","../src/components/timepicker/TimePicker.tsx","../src/components/timepicker/TimeView.tsx","../src/components/timepicker/constants.ts","../src/components/timepicker/utils.ts","../src/components/timepicker/TimeColumn.tsx","../src/components/timerangepicker/TimeRangePicker.tsx","../src/components/timerangepicker/constants.ts","../src/components/timerangepicker/utils.ts","../src/components/datetimepicker/DateTimePicker.tsx","../src/components/datetimepicker/utils.ts","../src/components/datetimepicker/constants.ts","../src/components/datetimerangepicker/DateTimeRangePicker.tsx","../src/components/datetimerangepicker/constants.ts","../src/components/empty/Empty.tsx","../src/components/empty/constants.ts","../src/components/empty/EmptyIllustration.tsx","../src/components/select/Select.tsx","../src/components/select/constants.ts","../src/components/select/SelectTrigger.tsx","../src/components/select/SelectMenu.tsx","../src/components/select/SelectOption.tsx","../src/components/select/SelectMenuFilter.tsx","../src/hooks/useDebouncedCallback.ts","../src/hooks/useDebounce.ts","../src/components/upload-image/UploadImage.tsx","../src/components/upload-image/constants.ts","../src/components/upload-image/utils.ts","../src/components/file-preview/FilePreview.tsx","../src/components/file-preview/constants.ts","../src/components/file-preview/utils.ts","../src/components/file-preview/FileContext.ts","../src/components/file-preview/image-preview/ImagePreview.tsx","../src/components/file-preview/image-preview/ImagePreviewToolbar.tsx","../src/components/file-preview/FileContainer.tsx","../src/components/modal/constants.ts","../src/components/modal/ModalContext.ts","../src/components/modal/Modal.tsx","../src/components/modal/ModalContainer.tsx","../src/components/modal/ModalHeader.tsx","../src/components/modal/ModalBody.tsx","../src/components/upload-image/UploadImageDropzone.tsx","../src/components/skeleton/LoadingImage.tsx","../src/components/skeleton/constants.ts","../src/components/skeleton/Skeleton.tsx","../src/components/upload-image/UploadImageList.tsx","../src/components/upload-avatar/UploadAvatar.tsx","../src/components/upload-avatar/constants.ts","../src/components/upload-avatar/utils.ts","../src/components/upload-avatar/UploadAvatarCrop.tsx","../src/components/upload-avatar/cropUtils.ts","../src/components/modal/ModalFooter.tsx","../src/components/modal/ModalClose.tsx","../src/components/confirm/constants.ts","../src/components/confirm/ConfirmContext.ts","../src/components/confirm/Confirm.tsx","../src/components/confirm/ConfirmContainer.tsx","../src/components/confirm/ConfirmHeader.tsx","../src/components/confirm/ConfirmBody.tsx","../src/components/confirm/ConfirmFooter.tsx","../src/components/confirm/ConfirmClose.tsx"],"sourcesContent":["// Button\nexport { Button, IconButton } from \"./components/button\";\nexport type * from \"./components/button/types\";\n\n// Badge\nexport { Badge } from \"./components/badge\";\nexport type * from \"./components/badge/types\";\n\n// Input\nexport {\n Input,\n PasswordInput,\n NumberInput,\n OtpInput,\n MultiInput,\n formatNumberString,\n parseNumber,\n parseRawNumberString,\n splitTagsFromText,\n isValidOtpChar,\n sanitizeOtpString,\n} from \"./components/input\";\nexport type * from \"./components/input/types\";\n\n// TextArea\nexport { TextArea } from \"./components/textarea\";\nexport type * from \"./components/textarea/types\";\n\n// Checkbox\nexport {\n Checkbox,\n CheckboxGroup,\n CheckboxGroupContext,\n useCheckboxGroupContext,\n} from \"./components/checkbox\";\nexport type * from \"./components/checkbox/types\";\n\n// Radio\nexport {\n Radio,\n RadioGroup,\n RadioGroupContext,\n useRadioGroupContext,\n} from \"./components/radio\";\nexport type * from \"./components/radio/types\";\n\n// Toggle\nexport { Toggle } from \"./components/toggle\";\nexport type * from \"./components/toggle/types\";\n\n// Icons\nexport { default as CheckIcon } from \"./components/icons/CheckIcon\";\nexport { default as MinusIcon } from \"./components/icons/MinusIcon\";\nexport { default as PlusIcon } from \"./components/icons/PlusIcon\";\nexport { default as RadioDotIcon } from \"./components/icons/RadioDotIcon\";\nexport { default as ChevronDownIcon } from \"./components/icons/ChevronDownIcon\";\nexport { default as ChevronLeftIcon } from \"./components/icons/ChevronLeftIcon\";\nexport { default as ChevronRightIcon } from \"./components/icons/ChevronRightIcon\";\nexport { default as CalendarIcon } from \"./components/icons/CalendarIcon\";\nexport { default as ClockIcon } from \"./components/icons/ClockIcon\";\nexport { default as DoubleChevronLeftIcon } from \"./components/icons/DoubleChevronLeftIcon\";\nexport { default as DoubleChevronRightIcon } from \"./components/icons/DoubleChevronRightIcon\";\nexport { default as EmptyDefaultIcon } from \"./components/icons/EmptyDefaultIcon\";\nexport { default as EmptySearchIcon } from \"./components/icons/EmptySearchIcon\";\nexport { default as EmptyErrorIcon } from \"./components/icons/EmptyErrorIcon\";\nexport { default as EmptyFolderIcon } from \"./components/icons/EmptyFolderIcon\";\nexport { default as EmptySimpleIcon } from \"./components/icons/EmptySimpleIcon\";\nexport { default as InfoCircleIcon } from \"./components/icons/InfoCircleIcon\";\nexport { default as CheckCircleIcon } from \"./components/icons/CheckCircleIcon\";\nexport { default as AlertTriangleIcon } from \"./components/icons/AlertTriangleIcon\";\nexport { default as AlertCircleIcon } from \"./components/icons/AlertCircleIcon\";\nexport { default as ZoomInIcon } from \"./components/icons/ZoomInIcon\";\nexport { default as ZoomOutIcon } from \"./components/icons/ZoomOutIcon\";\nexport { default as RotateCwIcon } from \"./components/icons/RotateCwIcon\";\nexport { default as RotateCcwIcon } from \"./components/icons/RotateCcwIcon\";\nexport { default as FlipHorizontalIcon } from \"./components/icons/FlipHorizontalIcon\";\nexport { default as DownloadIcon } from \"./components/icons/DownloadIcon\";\nexport { default as ResetIcon } from \"./components/icons/ResetIcon\";\nexport { default as ImageIcon } from \"./components/icons/ImageIcon\";\nexport { default as CropIcon } from \"./components/icons/CropIcon\";\nexport { default as CloseIcon } from \"./components/icons/CloseIcon\";\nexport { default as EyeIcon } from \"./components/icons/EyeIcon\";\nexport { default as SearchIcon } from \"./components/icons/SearchIcon\";\nexport { default as Spinner } from \"./components/icons/Spinner\";\nexport { default as TrashIcon } from \"./components/icons/TrashIcon\";\nexport { default as UploadIcon } from \"./components/icons/UploadIcon\";\n\n// Alert\nexport { Alert } from \"./components/alert\";\nexport type * from \"./components/alert/types\";\n\n// Toast (Powered by Sonner)\nexport { Toaster, toast, DEFAULT_TOAST_DURATION } from \"./components/toast\";\nexport type * from \"./components/toast/types\";\n\n// Tooltip\nexport { Tooltip } from \"./components/tooltip\";\nexport type * from \"./components/tooltip/types\";\n\n// Slider\nexport {\n Slider,\n SliderThumb,\n SliderMarks,\n SliderStepDots,\n clamp,\n getPercentage,\n} from \"./components/slider\";\nexport type * from \"./components/slider/types\";\n\n// Collapse\nexport {\n Collapse,\n CollapsePanel,\n CollapseHeader,\n CollapseContent,\n Collapsible,\n useCollapseContext,\n useCollapsePanelContext,\n} from \"./components/collapse\";\nexport type * from \"./components/collapse/types\";\n\n// Tabs\nexport {\n Tabs,\n TabList,\n Tab,\n TabPanels,\n TabPanel,\n TabsContext,\n useTabsContext,\n} from \"./components/tabs\";\nexport type * from \"./components/tabs/types\";\n\n// Carousel\nexport {\n Carousel,\n CarouselContent,\n CarouselSlide,\n CarouselPrevious,\n CarouselNext,\n CarouselPagination,\n useCarousel,\n useCarouselContext,\n} from \"./components/carousel\";\nexport type * from \"./components/carousel/types\";\n\n// Dropdown\nexport {\n Dropdown,\n DropdownTrigger,\n DropdownMenu,\n DropdownItem,\n DropdownHeader,\n DropdownSeparator,\n DropdownGroup,\n useDropdownContext,\n} from \"./components/dropdown\";\nexport type * from \"./components/dropdown/types\";\n\n// Popover\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverHeader,\n PopoverBody,\n PopoverFooter,\n PopoverClose,\n usePopoverContext,\n} from \"./components/popover\";\nexport type * from \"./components/popover/types\";\n\n// DatePicker\nexport {\n DatePicker,\n Calendar,\n CalendarHeader,\n DayGrid,\n MonthGrid,\n YearGrid,\n resolveLocale,\n toDate,\n formatDate,\n parseDate,\n getISOWeekNumber,\n generateCalendarGrid,\n isSameDay,\n isSameMonth,\n isDateBefore,\n isDateAfter,\n} from \"./components/datepicker\";\nexport type * from \"./components/datepicker/types\";\n\n// DateRangePicker\nexport {\n DateRangePicker,\n DateRangeCalendar,\n DateRangeHeader,\n DateRangeDayGrid,\n DateRangeMonthGrid,\n DateRangeYearGrid,\n generateRangeCalendarGrid,\n} from \"./components/daterangepicker\";\nexport type * from \"./components/daterangepicker/types\";\n\n// TimePicker\nexport {\n TimePicker,\n TimeView,\n TimeColumn,\n formatTime,\n parseTimeToDate,\n getDefaultFormat,\n toTimeObject,\n createDateWithTime,\n isTimeBefore,\n isTimeAfter,\n isSameTime,\n checkIsDisabled,\n padZero,\n} from \"./components/timepicker\";\nexport type * from \"./components/timepicker/types\";\n\n// TimeRangePicker\nexport { TimeRangePicker, isTimeInRange } from \"./components/timerangepicker\";\nexport type * from \"./components/timerangepicker/types\";\n\n// DateTimePicker\nexport {\n DateTimePicker,\n formatDateTime,\n parseDateTime,\n combineDateTime,\n toDateTime,\n getDefaultDateTimeFormat,\n} from \"./components/datetimepicker\";\nexport type * from \"./components/datetimepicker/types\";\n\n// DateTimeRangePicker\nexport { DateTimeRangePicker } from \"./components/datetimerangepicker\";\nexport type * from \"./components/datetimerangepicker/types\";\n\n// Empty\nexport { Empty, EmptyIllustration } from \"./components/empty\";\nexport type * from \"./components/empty/types\";\n\n// Select\nexport {\n Select,\n SelectComponent,\n SelectTrigger,\n SelectMenu,\n SelectMenuFilter,\n SelectOption,\n} from \"./components/select\";\nexport type * from \"./components/select/types\";\n\n// Hooks\nexport { useDebounce } from \"./hooks/useDebounce\";\nexport { useDebouncedCallback } from \"./hooks/useDebouncedCallback\";\n\n// UploadImage\nexport {\n UploadImage,\n UploadImageDropzone,\n UploadImageList,\n formatBytes,\n validateFile,\n createFileItem,\n revokeFileItem,\n} from \"./components/upload-image\";\nexport type * from \"./components/upload-image/types\";\n\n// UploadAvatar\nexport {\n UploadAvatar,\n UploadAvatarCropContent,\n UploadAvatarCropModal,\n} from \"./components/upload-avatar\";\nexport type * from \"./components/upload-avatar/types\";\n\n// Confirm\nexport {\n Confirm,\n ConfirmContainer,\n ConfirmHeader,\n ConfirmBody,\n ConfirmFooter,\n ConfirmClose,\n useConfirmContext,\n} from \"./components/confirm\";\nexport type * from \"./components/confirm/types\";\n\n// Modal\nexport {\n Modal,\n ModalContainer,\n ModalHeader,\n ModalBody,\n ModalFooter,\n ModalClose,\n useModalContext,\n} from \"./components/modal\";\nexport type * from \"./components/modal/types\";\n\n// FilePreview & ImagePreview\nexport {\n FilePreview,\n FileContainer,\n useFileContext,\n IMAGE_EXTENSIONS,\n PDF_EXTENSIONS,\n VIDEO_EXTENSIONS,\n AUDIO_EXTENSIONS,\n DOCUMENT_EXTENSIONS,\n getFileName,\n getFileType,\n getFileExtension,\n normalizePreviewFile,\n downloadFile,\n ImagePreview,\n ImagePreviewToolbar,\n} from \"./components/file-preview\";\nexport type * from \"./components/file-preview/types\";\nexport type * from \"./components/file-preview/image-preview/types\";\n\n// Skeleton\nexport { Skeleton, LoadingImage } from \"./components/skeleton\";\nexport type * from \"./components/skeleton/types\";\n","import { ButtonSize, ButtonVariant, ButtonColor, ButtonRadius } from \"./types\";\n\nexport const sizeConfig: Record<\n ButtonSize,\n {\n button: string;\n iconOnly: string;\n icon: string;\n }\n> = {\n xs: {\n button: \"h-6 px-2.5 text-[11px] gap-1\",\n iconOnly: \"size-6 p-0\",\n icon: \"size-3\",\n },\n sm: {\n button: \"h-8 px-3 text-xs gap-1.5\",\n iconOnly: \"size-8 p-0\",\n icon: \"size-3.5\",\n },\n md: {\n button: \"h-10 px-4 text-sm gap-2\",\n iconOnly: \"size-10 p-0\",\n icon: \"size-4\",\n },\n lg: {\n button: \"h-12 px-5 text-base gap-2.5\",\n iconOnly: \"size-12 p-0\",\n icon: \"size-5\",\n },\n xl: {\n button: \"h-14 px-6 text-lg gap-3\",\n iconOnly: \"size-14 p-0\",\n icon: \"size-6\",\n },\n};\n\nexport const radiusConfig: Record<ButtonRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const variantColorConfig: Record<Exclude<ButtonVariant, \"other\">, Record<ButtonColor, string>> = {\n filled: {\n primary:\n \"bg-primary-500 text-neutral-white border-transparent hover:bg-primary-600 active:bg-primary-700 focus-visible:ring-primary-700\",\n secondary:\n \"bg-secondary-500 text-neutral-white border-transparent hover:bg-secondary-600 active:bg-secondary-700 focus-visible:ring-secondary-700\",\n neutral:\n \"bg-neutral-800 text-neutral-white border-transparent hover:bg-neutral-900 active:bg-neutral-950 focus-visible:ring-neutral-700\",\n error:\n \"bg-error-500 text-neutral-white border-transparent hover:bg-error-600 active:bg-error-700 focus-visible:ring-error-700\",\n success:\n \"bg-success-500 text-neutral-white border-transparent hover:bg-success-600 active:bg-success-700 focus-visible:ring-success-700\",\n warning:\n \"bg-warning-500 text-neutral-white border-transparent hover:bg-warning-600 active:bg-warning-700 focus-visible:ring-warning-700\",\n info: \"bg-info-500 text-neutral-white border-transparent hover:bg-info-600 active:bg-info-700 focus-visible:ring-info-700\",\n },\n soft: {\n primary:\n \"bg-primary-100 text-primary-800 border-primary-200 hover:bg-primary-200 hover:text-primary-900 active:bg-primary-300 focus-visible:ring-primary-700\",\n secondary:\n \"bg-secondary-100 text-secondary-800 border-secondary-200 hover:bg-secondary-200 hover:text-secondary-900 active:bg-secondary-300 focus-visible:ring-secondary-700\",\n neutral:\n \"bg-neutral-100 text-neutral-800 border-neutral-200 hover:bg-neutral-200 hover:text-neutral-900 active:bg-neutral-300 focus-visible:ring-neutral-700\",\n error:\n \"bg-error-100 text-error-800 border-error-200 hover:bg-error-200 hover:text-error-900 active:bg-error-300 focus-visible:ring-error-700\",\n success:\n \"bg-success-100 text-success-800 border-success-200 hover:bg-success-200 hover:text-success-900 active:bg-success-300 focus-visible:ring-success-700\",\n warning:\n \"bg-warning-100 text-warning-800 border-warning-200 hover:bg-warning-200 hover:text-warning-900 active:bg-warning-300 focus-visible:ring-warning-700\",\n info: \"bg-info-100 text-info-800 border-info-200 hover:bg-info-200 hover:text-info-900 active:bg-info-300 focus-visible:ring-info-700\",\n },\n ghost: {\n primary:\n \"bg-transparent text-primary-700 border-transparent hover:bg-primary-100 hover:text-primary-900 active:bg-primary-200 focus-visible:ring-primary-700\",\n secondary:\n \"bg-transparent text-secondary-700 border-transparent hover:bg-secondary-100 hover:text-secondary-900 active:bg-secondary-200 focus-visible:ring-secondary-700\",\n neutral:\n \"bg-transparent text-neutral-700 border-transparent hover:bg-neutral-100 hover:text-neutral-900 active:bg-neutral-200 focus-visible:ring-neutral-700\",\n error:\n \"bg-transparent text-error-700 border-transparent hover:bg-error-100 hover:text-error-900 active:bg-error-200 focus-visible:ring-error-700\",\n success:\n \"bg-transparent text-success-700 border-transparent hover:bg-success-100 hover:text-success-900 active:bg-success-200 focus-visible:ring-success-700\",\n warning:\n \"bg-transparent text-warning-700 border-transparent hover:bg-warning-100 hover:text-warning-900 active:bg-warning-200 focus-visible:ring-warning-700\",\n info: \"bg-transparent text-info-700 border-transparent hover:bg-info-100 hover:text-info-900 active:bg-info-200 focus-visible:ring-info-700\",\n },\n text: {\n primary:\n \"bg-transparent text-primary-500 border-transparent px-1 hover:text-primary-600 active:text-primary-700 focus-visible:ring-primary-700\",\n secondary:\n \"bg-transparent text-secondary-500 border-transparent px-1 hover:text-secondary-600 active:text-secondary-700 focus-visible:ring-secondary-700\",\n neutral:\n \"bg-transparent text-neutral-700 border-transparent px-1 hover:text-neutral-800 active:text-neutral-900 focus-visible:ring-neutral-700\",\n error:\n \"bg-transparent text-error-500 border-transparent px-1 hover:text-error-600 active:text-error-700 focus-visible:ring-error-700\",\n success:\n \"bg-transparent text-success-500 border-transparent px-1 hover:text-success-600 active:text-success-700 focus-visible:ring-success-700\",\n warning:\n \"bg-transparent text-warning-500 border-transparent px-1 hover:text-warning-600 active:text-warning-700 focus-visible:ring-warning-700\",\n info: \"bg-transparent text-info-500 border-transparent px-1 hover:text-info-600 active:text-info-700 focus-visible:ring-info-700\",\n },\n outline: {\n primary:\n \"bg-transparent text-primary-700 border-2 border-primary-400 hover:bg-primary-50 hover:border-primary-500 hover:text-primary-900 active:bg-primary-100 focus-visible:ring-primary-700\",\n secondary:\n \"bg-transparent text-secondary-700 border-2 border-secondary-400 hover:bg-secondary-50 hover:border-secondary-500 hover:text-secondary-900 active:bg-secondary-100 focus-visible:ring-secondary-700\",\n neutral:\n \"bg-transparent text-neutral-700 border-2 border-neutral-300 hover:bg-neutral-50 hover:border-neutral-400 hover:text-neutral-900 active:bg-neutral-100 focus-visible:ring-neutral-700\",\n error:\n \"bg-transparent text-error-700 border-2 border-error-400 hover:bg-error-50 hover:border-error-500 hover:text-error-900 active:bg-error-100 focus-visible:ring-error-700\",\n success:\n \"bg-transparent text-success-700 border-2 border-success-400 hover:bg-success-50 hover:border-success-500 hover:text-success-900 active:bg-success-100 focus-visible:ring-success-700\",\n warning:\n \"bg-transparent text-warning-700 border-2 border-warning-400 hover:bg-warning-50 hover:border-warning-500 hover:text-warning-900 active:bg-warning-100 focus-visible:ring-warning-700\",\n info: \"bg-transparent text-info-700 border-2 border-info-400 hover:bg-info-50 hover:border-info-500 hover:text-info-900 active:bg-info-100 focus-visible:ring-info-700\",\n },\n};\n","/**\n * Lấy cấu hình tương ứng theo `key` từ đối tượng `configMap` (sizeConfig, radiusConfig, variantConfig, colorConfig...),\n * nếu `key` không hợp lệ hoặc không tồn tại trong `configMap`, sẽ trả về giá trị an toàn của `fallbackKey`.\n *\n * @param key - Khóa được truyền vào (size, radius, variant... có thể undefined, null hoặc chuỗi bất kỳ)\n * @param configMap - Đối tượng ánh xạ cấu hình\n * @param fallbackKey - Khóa dự phòng khi không tìm thấy (fallback an toàn)\n * @returns Cấu hình tương ứng của khóa đó\n */\nexport function getSafeConfig<TConfig, TKey extends PropertyKey = string>(\n key: TKey | undefined | null,\n configMap: Record<TKey, TConfig>,\n fallbackKey: TKey\n): TConfig {\n if (key != null && Object.prototype.hasOwnProperty.call(configMap, key)) {\n return configMap[key];\n }\n return configMap[fallbackKey];\n}\n","import type { SVGProps } from \"react\";\n\nexport default function Spinner({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n className={`animate-[spin_1s_steps(8)_infinite] ${className}`}\n viewBox=\"0 0 25 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path d=\"M0 0h25v24H0z\" fill=\"none\" />\n <path\n fill=\"currentColor\"\n d=\"M4.818 6.664h-.001a1.847 1.847 0 1 1 1.306-.541a1.77 1.77 0 0 1-1.277.541h-.029zm-2.97 7.182h-.001a1.847 1.847 0 1 1 1.306-.541a1.77 1.77 0 0 1-1.278.541h-.031h.002zM12 3.692a1.847 1.847 0 1 1 1.306-.541a1.77 1.77 0 0 1-1.277.541zM4.818 21.029h-.001a1.847 1.847 0 1 1 1.306-.541a1.77 1.77 0 0 1-1.276.541h-.031zM19.182 7.125a2.308 2.308 0 1 1 0-4.615a2.308 2.308 0 0 1 0 4.615M12 24a1.847 1.847 0 1 1 1.306-.541a1.77 1.77 0 0 1-1.277.541zm10.154-9.231h-.048c-.75 0-1.428-.309-1.913-.807l-.001-.001c-.499-.503-.808-1.196-.808-1.961s.308-1.458.808-1.962a2.66 2.66 0 0 1 1.914-.808h.05h-.003h.048c.75 0 1.427.309 1.913.807l.001.001c.499.503.808 1.196.808 1.961s-.308 1.458-.808 1.962a2.66 2.66 0 0 1-1.915.809h-.049zm-2.971 7.643h-.05a3.1 3.1 0 0 1-2.236-.951l-.001-.001c-.584-.584-.945-1.391-.945-2.283s.361-1.698.945-2.283a3.1 3.1 0 0 1 2.234-.945h.054h-.003h.042c.877 0 1.67.362 2.237.944l.001.001c.588.582.952 1.39.952 2.283s-.364 1.7-.952 2.282a3.1 3.1 0 0 1-2.24.953h-.04z\"\n />\n </svg>\n );\n}\n","import { ButtonProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport Spinner from \"../icons/Spinner\";\n\nexport default function Button({\n size,\n variant,\n color,\n radius,\n leftIcon,\n rightIcon,\n isLoading = false,\n showSpinner = false,\n loadingText,\n isFullWidth = false,\n disabled = false,\n type = \"button\",\n className = \"\",\n children,\n ref,\n ...props\n}: ButtonProps) {\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const variantStyles =\n variant === \"other\" ? \"\" : getSafeConfig(color, getSafeConfig(variant, variantColorConfig, \"filled\"), \"primary\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"lg\");\n\n const classNames = [\n \"inline-flex items-center justify-center font-medium leading-none border transition-colors duration-150 cursor-pointer select-none whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:pointer-events-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 active:scale-[0.98] transition-transform\",\n currentSize.button,\n roundedClass,\n variantStyles,\n isFullWidth ? \"w-full\" : \"\",\n disabled ? \"opacity-50\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const renderIconWrapper = (iconNode: React.ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 leading-none ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const displayContent = isLoading && loadingText ? loadingText : children;\n\n return (\n <button\n ref={ref}\n type={type}\n disabled={disabled || isLoading}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n className={classNames}\n {...props}\n >\n {isLoading && showSpinner && renderIconWrapper(<Spinner />)}\n {(!isLoading || !showSpinner) && leftIcon && renderIconWrapper(leftIcon)}\n {displayContent && <span className=\"leading-none\">{displayContent}</span>}\n {!isLoading && rightIcon && renderIconWrapper(rightIcon)}\n </button>\n );\n}\n","import { IconButtonProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport Spinner from \"../icons/Spinner\";\nimport { ReactNode } from \"react\";\n\nexport default function IconButton({\n icon,\n size,\n variant,\n color,\n radius,\n isLoading = false,\n showSpinner = false,\n disabled = false,\n type = \"button\",\n className = \"\",\n ref,\n ...props\n}: IconButtonProps) {\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n const variantStyles =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(color, getSafeConfig(variant, variantColorConfig, \"filled\"), \"primary\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"full\");\n\n const classNames = [\n \"inline-flex items-center justify-center font-medium leading-none border transition-colors duration-150 active:scale-[0.98] transition-transform cursor-pointer select-none whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:pointer-events-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2\",\n currentSize.iconOnly,\n roundedClass,\n variantStyles,\n disabled ? \"opacity-50\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 leading-none ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n return (\n <button\n ref={ref}\n type={type}\n disabled={disabled || isLoading}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n className={classNames}\n {...props}\n >\n {isLoading && showSpinner ? renderIconWrapper(<Spinner />) : renderIconWrapper(icon)}\n </button>\n );\n}\n","import { BadgeSize, BadgeVariant, BadgeColor, BadgeRadius } from \"./types\";\n\nexport const sizeConfig: Record<\n BadgeSize,\n {\n badge: string;\n icon: string;\n dot: string;\n deleteIcon: string;\n }\n> = {\n xs: {\n badge: \"h-5 px-2 text-[11px] gap-1\",\n icon: \"size-3\",\n dot: \"size-1.5\",\n deleteIcon: \"size-3\",\n },\n sm: {\n badge: \"h-6 px-2.5 text-xs gap-1.5\",\n icon: \"size-3.5\",\n dot: \"size-1.5\",\n deleteIcon: \"size-3.5\",\n },\n md: {\n badge: \"h-7 px-3 text-xs font-medium gap-1.5\",\n icon: \"size-3.5\",\n dot: \"w-2 h-2\",\n deleteIcon: \"size-3.5\",\n },\n lg: {\n badge: \"h-8 px-3.5 text-sm font-medium gap-2\",\n icon: \"size-4\",\n dot: \"size-2.5\",\n deleteIcon: \"size-4\",\n },\n xl: {\n badge: \"h-9 px-4 text-sm font-semibold gap-2\",\n icon: \"size-4.5\",\n dot: \"size-2.5\",\n deleteIcon: \"size-4.5\",\n },\n};\n\nexport const radiusConfig: Record<BadgeRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const dotColorConfig: Record<BadgeColor, string> = {\n primary: \"bg-primary-500\",\n secondary: \"bg-secondary-500\",\n error: \"bg-error-500\",\n success: \"bg-success-500\",\n warning: \"bg-warning-500\",\n info: \"bg-info-500\",\n neutral: \"bg-neutral-500\",\n};\n\nexport const variantColorConfig: Record<Exclude<BadgeVariant, \"other\">, Record<BadgeColor, string>> = {\n soft: {\n primary: \"bg-primary-100 text-primary-800 border-primary-200 hover:bg-primary-200\",\n secondary: \"bg-secondary-100 text-secondary-800 border-secondary-200 hover:bg-secondary-200\",\n error: \"bg-error-100 text-error-800 border-error-200 hover:bg-error-200\",\n success: \"bg-success-100 text-success-800 border-success-200 hover:bg-success-200\",\n warning: \"bg-warning-100 text-warning-800 border-warning-200 hover:bg-warning-200\",\n info: \"bg-info-100 text-info-800 border-info-200 hover:bg-info-200\",\n neutral: \"bg-neutral-100 text-neutral-800 border-neutral-200 hover:bg-neutral-200\",\n },\n filled: {\n primary: \"bg-primary-500 text-neutral-white border-transparent hover:bg-primary-600 active:bg-primary-700\",\n secondary: \"bg-secondary-500 text-neutral-white border-transparent hover:bg-secondary-600 active:bg-secondary-700\",\n error: \"bg-error-500 text-neutral-white border-transparent hover:bg-error-600 active:bg-error-700\",\n success: \"bg-success-500 text-neutral-white border-transparent hover:bg-success-600 active:bg-success-700\",\n warning: \"bg-warning-500 text-neutral-950 border-transparent hover:bg-warning-600 active:bg-warning-700\",\n info: \"bg-info-500 text-neutral-white border-transparent hover:bg-info-600 active:bg-info-700\",\n neutral: \"bg-neutral-800 text-neutral-white border-transparent hover:bg-neutral-900 active:bg-neutral-950\",\n },\n outline: {\n primary: \"bg-transparent text-primary-700 border-2 border-primary-400 hover:bg-primary-50/70\",\n secondary: \"bg-transparent text-secondary-800 border-2 border-secondary-400 hover:bg-secondary-50/70\",\n error: \"bg-transparent text-error-700 border-2 border-error-400 hover:bg-error-50/70\",\n success: \"bg-transparent text-success-700 border-2 border-success-400 hover:bg-success-50/70\",\n warning: \"bg-transparent text-warning-800 border-2 border-warning-400 hover:bg-warning-50/70\",\n info: \"bg-transparent text-info-800 border-2 border-info-400 hover:bg-info-50/70\",\n neutral: \"bg-transparent text-neutral-700 border-2 border-neutral-300 hover:bg-neutral-100/70\",\n },\n ghost: {\n primary: \"bg-transparent text-primary-700 border-transparent hover:bg-primary-50\",\n secondary: \"bg-transparent text-secondary-800 border-transparent hover:bg-secondary-50\",\n error: \"bg-transparent text-error-700 border-transparent hover:bg-error-50\",\n success: \"bg-transparent text-success-700 border-transparent hover:bg-success-50\",\n warning: \"bg-transparent text-warning-800 border-transparent hover:bg-warning-50\",\n info: \"bg-transparent text-info-800 border-transparent hover:bg-info-50\",\n neutral: \"bg-transparent text-neutral-700 border-transparent hover:bg-neutral-50\",\n },\n};\n","import type { SVGProps } from \"react\";\n\nexport default function CloseIcon({ width = 14, height = 14, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n","import { BadgeProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig, dotColorConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport CloseIcon from \"@/components/icons/CloseIcon\";\nimport { ReactNode } from \"react\";\n\nexport default function Badge({\n size = \"md\",\n variant = \"soft\",\n color = \"primary\",\n radius = \"full\",\n dot = false,\n dotPing = false,\n leftIcon,\n rightIcon,\n onDelete,\n deleteAriaLabel = \"Remove\",\n className = \"\",\n children,\n onClick,\n ref,\n ...props\n}: BadgeProps) {\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n const variantStyles =\n variant === \"other\" ? \"\" : getSafeConfig(color, getSafeConfig(variant, variantColorConfig, \"soft\"), \"primary\");\n\n const dotBg = getSafeConfig(color, dotColorConfig, \"primary\");\n\n const roundedClass = getSafeConfig(radius, radiusConfig, \"full\");\n\n const classNames = [\n \"inline-flex items-center justify-center font-medium leading-none border transition-colors duration-150 whitespace-nowrap\",\n currentSize.badge,\n roundedClass,\n variantStyles,\n onClick ? \"cursor-pointer select-none active:scale-[0.98] transition-transform duration-100\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 leading-none ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n return (\n <span\n ref={ref}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n className={classNames}\n onClick={onClick}\n {...props}\n >\n {dot && (\n <span\n className={`relative inline-block shrink-0 rounded-full ${\n dotPing ? \"animate-pulse\" : \"\"\n } ${currentSize.dot} ${dotBg}`}\n aria-hidden=\"true\"\n />\n )}\n\n {leftIcon && renderIconWrapper(leftIcon)}\n\n {children && <span className=\"leading-none\">{children}</span>}\n\n {rightIcon && !onDelete && renderIconWrapper(rightIcon)}\n\n {onDelete && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n aria-label={deleteAriaLabel}\n className={`inline-flex items-center justify-center shrink-0 rounded-full hover:bg-black/10 active:bg-black/20 transition-colors p-0.5 -mr-0.5 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current ${currentSize.deleteIcon}`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n </span>\n );\n}\n","import { useId, useState, useRef, ReactNode } from \"react\";\nimport { useMergeRefs } from \"@floating-ui/react\";\nimport { InputProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig, labelColorConfig } from \"./constants\";\nimport CloseIcon from \"@/components/icons/CloseIcon\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function Input({\n size,\n variant,\n color,\n radius,\n label,\n labelPlacement = \"floating\",\n config,\n helperText,\n errorMessage,\n leftIcon,\n leftAddon,\n rightIcon,\n rightAddon,\n onClear,\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n id,\n value,\n defaultValue,\n onChange,\n disabled = false,\n readOnly = false,\n className = \"\",\n type = \"text\",\n placeholder,\n ref,\n ...props\n}: InputProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = false,\n isFullWidth = false,\n } = config ?? {};\n\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n\n const internalRef = useRef<HTMLInputElement | null>(null);\n const mergedRef = useMergeRefs([internalRef, ref]);\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue);\n const currentValue = isControlled ? value : internalValue;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalValue(e.target.value);\n }\n onChange?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled) {\n setInternalValue(\"\");\n }\n onClear?.();\n };\n\n const hasValue =\n currentValue !== undefined && currentValue !== null ? Boolean(String(currentValue).length > 0) : false;\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n\n const variantStyles =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, variantColorConfig, \"outline\"), \"primary\");\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const isFloating = labelPlacement === \"floating\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-text font-bold bg-neutral-white transition-colors duration-150 ${currentSize.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${currentSize.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2\",\n currentSize.wrapper,\n roundedClass,\n variantStyles,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : \"w-auto\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const inputClasses = [\n \"w-full h-full bg-transparent outline-none border-none text-neutral-900 placeholder:text-neutral-400 disabled:cursor-not-allowed\",\n currentSize.input,\n leftIcon ? \"pl-1.5\" : \"\",\n rightIcon || isClearable || isLoading ? \"pr-1.5\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const isHorizontal = labelPlacement === \"left\";\n\n return (\n <div\n className={`group/field flex ${\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\"\n } ${isFullWidth ? \"w-full\" : \"inline-flex\"} ${wrapperClassName}`}\n >\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n <div className=\"flex items-stretch\">\n {leftAddon && (\n <div\n className={`inline-flex items-center px-3 text-neutral-600 bg-neutral-100 border border-r-0 border-neutral-300 text-sm font-medium ${\n roundedClass ? `${roundedClass} rounded-r-none` : \"\"\n }`}\n >\n {leftAddon}\n </div>\n )}\n\n <div\n className={`${containerClasses} ${\n leftAddon ? \"rounded-l-none!\" : \"\"\n } ${rightAddon ? \"rounded-r-none!\" : \"\"}`}\n >\n {isFloating && renderLabel()}\n\n {leftIcon && (\n <div className=\"flex items-center justify-center pl-3 shrink-0\">{renderIconWrapper(leftIcon)}</div>\n )}\n\n <input\n ref={mergedRef}\n id={inputId}\n type={type}\n value={currentValue}\n onChange={handleChange}\n disabled={disabled || isLoading}\n readOnly={readOnly}\n aria-invalid={hasError}\n aria-required={isRequired}\n aria-describedby={errorMessage || helperText ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n placeholder={placeholder}\n className={inputClasses}\n {...props}\n />\n\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center pr-3 shrink-0\">{renderIconWrapper(<Spinner />)}</div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa nội dung\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center mr-2 shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${currentSize.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n {!isLoading && rightIcon && (\n <div className=\"flex items-center justify-center pr-3 shrink-0\">{renderIconWrapper(rightIcon)}</div>\n )}\n </div>\n\n {rightAddon && (\n <div\n className={`inline-flex items-center px-3 text-neutral-600 bg-neutral-100 border border-l-0 border-neutral-300 text-sm font-medium ${\n roundedClass ? `${roundedClass} rounded-l-none` : \"\"\n }`}\n >\n {rightAddon}\n </div>\n )}\n </div>\n\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import { InputSize, InputVariant, InputColor, InputRadius } from \"./types\";\nimport type { BadgeRadius, BadgeSize } from \"@/components/badge/types\";\n\nexport const sizeConfig: Record<\n InputSize,\n {\n wrapper: string;\n input: string;\n icon: string;\n iconPaddingLeft: string;\n iconPaddingRight: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n wrapper: \"h-6 text-[11px]\",\n input: \"px-2 py-0.5 text-[11px] leading-tight\",\n icon: \"size-3\",\n iconPaddingLeft: \"pl-6\",\n iconPaddingRight: \"pr-6\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n wrapper: \"h-8 text-xs\",\n input: \"px-2.5 py-1 text-xs leading-normal\",\n icon: \"size-3.5\",\n iconPaddingLeft: \"pl-7.5\",\n iconPaddingRight: \"pr-7.5\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n wrapper: \"h-10 text-sm\",\n input: \"px-3.5 py-2 text-sm leading-normal\",\n icon: \"size-[18px]\",\n iconPaddingLeft: \"pl-9\",\n iconPaddingRight: \"pr-9\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n wrapper: \"h-12 text-base\",\n input: \"px-4 py-2.5 text-base leading-normal\",\n icon: \"size-5\",\n iconPaddingLeft: \"pl-11\",\n iconPaddingRight: \"pr-11\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n wrapper: \"h-14 text-lg\",\n input: \"px-5 py-3 text-lg leading-normal\",\n icon: \"size-6\",\n iconPaddingLeft: \"pl-13\",\n iconPaddingRight: \"pr-13\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-xs\",\n helper: \"text-sm mt-1\",\n },\n};\n\nexport const radiusConfig: Record<InputRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const badgeRadiusMap: Record<InputRadius, BadgeRadius> = {\n none: \"none\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n full: \"full\",\n};\n\nexport const multiInputSizeConfig: Record<\n InputSize,\n {\n wrapper: string;\n input: string;\n gap: string;\n badgeSize: BadgeSize;\n icon: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n wrapper: \"min-h-6 text-[11px] px-1.5 py-0.5\",\n input: \"text-[11px] leading-tight min-w-[50px]\",\n gap: \"gap-1\",\n badgeSize: \"xs\",\n icon: \"size-3\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n wrapper: \"min-h-8 text-xs px-2 py-1\",\n input: \"text-xs leading-normal min-w-[60px]\",\n gap: \"gap-1\",\n badgeSize: \"xs\",\n icon: \"size-3.5\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n wrapper: \"min-h-10 text-sm px-2.5 py-1.5\",\n input: \"text-sm leading-normal min-w-[70px]\",\n gap: \"gap-1.5\",\n badgeSize: \"sm\",\n icon: \"size-[18px]\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n wrapper: \"min-h-12 text-base px-3 py-2\",\n input: \"text-base leading-normal min-w-[80px]\",\n gap: \"gap-1.5\",\n badgeSize: \"md\",\n icon: \"size-5\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n wrapper: \"min-h-14 text-lg px-3.5 py-2.5\",\n input: \"text-lg leading-normal min-w-[90px]\",\n gap: \"gap-2\",\n badgeSize: \"lg\",\n icon: \"size-6\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-xs\",\n helper: \"text-sm mt-1\",\n },\n};\n\nexport const variantColorConfig: Record<Exclude<InputVariant, \"other\">, Record<InputColor, string>> = {\n outline: {\n primary:\n \"bg-neutral-white border-primary-300 hover:border-primary-400 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-neutral-white border-secondary-300 hover:border-secondary-400 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-neutral-white border-error-300 hover:border-error-400 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-neutral-white border-success-300 hover:border-success-400 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-neutral-white border-warning-300 hover:border-warning-400 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-neutral-white border-info-300 hover:border-info-400 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n\n filled: {\n primary:\n \"bg-primary-50/60 border-primary-200 hover:bg-primary-100/60 focus-within:bg-primary-100/60 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-secondary-50/60 border-secondary-200 hover:bg-secondary-100/60 focus-within:bg-secondary-100/60 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-neutral-50/60 border-neutral-200 hover:bg-neutral-200/60 focus-within:bg-neutral-200/60 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-error-50/60 border-error-500 hover:border-error-600 hover:bg-error-100/60 focus-within:bg-error-100/60 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-success-50/60 border-success-200 hover:bg-success-100/60 focus-within:bg-success-100/60 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-warning-50/60 border-warning-200 hover:bg-warning-100/60 focus-within:bg-warning-100/60 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-info-50/60 border-info-200 hover:bg-info-100/60 focus-within:bg-info-100/60 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n ghost: {\n primary:\n \"bg-transparent border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-200/20 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-transparent border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-200/20 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-transparent border-transparent hover:bg-neutral-50/50 focus-within:bg-neutral-50/50 focus-within:border-neutral-200/20 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-transparent border-transparent hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-transparent border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-200/20 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-transparent border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-200/20 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-transparent border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-200/20 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n};\n\nexport const labelColorConfig: Record<InputColor, string> = {\n primary: \"text-primary-500 group-focus-within/field:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/field:text-secondary-600\",\n error: \"text-error-500 group-focus-within/field:text-error-600\",\n success: \"text-success-500 group-focus-within/field:text-success-600\",\n warning: \"text-warning-500 group-focus-within/field:text-warning-600\",\n info: \"text-info-500 group-focus-within/field:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/field:text-neutral-600\",\n};\n\nexport const otpSlotSizeConfig: Record<\n InputSize,\n {\n slot: string;\n text: string;\n gap: string;\n label: string;\n helper: string;\n }\n> = {\n xs: {\n slot: \"size-6 min-w-6\",\n text: \"text-xs\",\n gap: \"gap-1\",\n label: \"text-[11px] mb-1\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n slot: \"size-8 min-w-8\",\n text: \"text-sm\",\n gap: \"gap-1.5\",\n label: \"text-xs mb-1\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n slot: \"size-10 min-w-10\",\n text: \"text-base font-semibold\",\n gap: \"gap-2\",\n label: \"text-sm mb-1.5\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n slot: \"size-12 min-w-12\",\n text: \"text-lg font-semibold\",\n gap: \"gap-2.5\",\n label: \"text-base mb-1.5\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n slot: \"size-14 min-w-14\",\n text: \"text-xl font-bold\",\n gap: \"gap-3\",\n label: \"text-lg mb-2\",\n helper: \"text-sm mt-1\",\n },\n};\n","import { ReactNode, useEffect, useState } from \"react\";\n\ntype UseAnimatedErrorOptions = {\n exitDuration?: number;\n};\n\nexport function useAnimatedError(errorMessage: ReactNode, options: UseAnimatedErrorOptions = {}) {\n const { exitDuration = 250 } = options;\n const [displayedError, setDisplayedError] = useState<ReactNode>(errorMessage);\n const [isExiting, setIsExiting] = useState(false);\n const [prevErrorMessage, setPrevErrorMessage] = useState<ReactNode>(errorMessage);\n\n if (errorMessage !== prevErrorMessage) {\n setPrevErrorMessage(errorMessage);\n if (errorMessage) {\n setDisplayedError(errorMessage);\n setIsExiting(false);\n } else {\n setIsExiting(true);\n }\n }\n\n useEffect(() => {\n if (!isExiting) return;\n\n const timer = setTimeout(() => {\n setDisplayedError(undefined);\n setIsExiting(false);\n }, exitDuration);\n\n return () => clearTimeout(timer);\n }, [exitDuration, isExiting]);\n\n return {\n displayedError,\n isExiting,\n };\n}\n\nexport default useAnimatedError;\n","import { ReactNode } from \"react\";\nimport { useAnimatedError } from \"@/hooks/useAnimatedError\";\n\nexport interface HelperErrorTextProps {\n /**\n * ID của phần tử thông báo (dùng để liên kết với aria-describedby / aria-errormessage)\n */\n id?: string;\n\n /**\n * Nội dung văn bản hướng dẫn/trợ giúp\n */\n helperText?: ReactNode;\n\n /**\n * Nội dung thông báo lỗi\n */\n errorMessage?: ReactNode;\n\n /**\n * ClassName tùy biến kích thước văn bản và khoảng cách (vd: currentSize.helper)\n * @default \"text-xs\"\n */\n sizeClassName?: string;\n\n /**\n * ClassName tùy biến bổ sung (vd: helperClassName)\n */\n className?: string;\n}\n\n/**\n * Component nội bộ dùng chung hiển thị đoạn văn bản helperText hoặc errorMessage\n * với animation mượt mà (CSS Grid transition), tối ưu phần cứng và tuân thủ WAI-ARIA.\n * (Không export ra ngoài package)\n */\nexport default function HelperErrorText({\n id,\n helperText,\n errorMessage,\n sizeClassName = \"text-xs\",\n className = \"\",\n}: HelperErrorTextProps) {\n const { displayedError, isExiting } = useAnimatedError(errorMessage);\n\n const activeText = displayedError || helperText;\n const hasMessage = Boolean(displayedError || helperText);\n const isShowingError = Boolean(displayedError);\n\n return (\n <div\n className={`grid transition-[grid-template-rows,opacity,margin] duration-200 ease-out overflow-hidden ${\n hasMessage ? \"grid-rows-[1fr] opacity-100 mt-1\" : \"grid-rows-[0fr] opacity-0 mt-0 pointer-events-none\"\n }`}\n aria-live=\"polite\"\n >\n <div className=\"overflow-hidden\">\n <div\n id={id}\n role={isShowingError ? \"alert\" : \"status\"}\n className={`leading-tight transition-colors duration-200 font-normal ${sizeClassName} ${\n isShowingError\n ? isExiting\n ? \"text-error-600 animate-error-out\"\n : \"text-error-600 animate-error-in\"\n : \"text-neutral-500 dark:text-neutral-400\"\n } ${className}`}\n >\n {activeText || \"\\u00A0\"}\n </div>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { PasswordInputProps } from \"./types\";\nimport Input from \"./Input\";\nimport { EyeIcon, EyeOffIcon } from \"@/components/icons/EyeIcon\";\n\nexport default function PasswordInput({\n defaultVisible = false,\n toggleAriaLabel = \"Hiển thị/ẩn mật khẩu\",\n onVisibilityChange,\n rightIcon,\n disabled,\n readOnly,\n ...props\n}: PasswordInputProps) {\n const [isVisible, setIsVisible] = useState(defaultVisible);\n\n const toggleVisibility = () => {\n if (disabled || readOnly) return;\n const nextState = !isVisible;\n setIsVisible(nextState);\n onVisibilityChange?.(nextState);\n };\n\n const toggleButton = (\n <button\n type=\"button\"\n onClick={toggleVisibility}\n disabled={disabled || readOnly}\n aria-label={toggleAriaLabel}\n className=\"inline-flex items-center justify-center size-full p-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-colors cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded\"\n >\n {isVisible ? <EyeOffIcon className=\"size-full\" /> : <EyeIcon className=\"size-full\" />}\n </button>\n );\n\n return (\n <Input\n type={isVisible ? \"text\" : \"password\"}\n disabled={disabled}\n readOnly={readOnly}\n rightIcon={rightIcon || toggleButton}\n {...props}\n />\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport function EyeIcon({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n}\n\nexport function EyeOffIcon({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M9.88 9.88a3 3 0 1 0 4.24 4.24\" />\n <path d=\"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68\" />\n <path d=\"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61\" />\n <line x1=\"2\" x2=\"22\" y1=\"2\" y2=\"22\" />\n </svg>\n );\n}\n\nexport default EyeIcon;\n","import { ChangeEvent, FocusEvent, useState } from \"react\";\nimport { NumberInputProps } from \"./types\";\nimport Input from \"./Input\";\nimport { formatNumberString, calculateCaretPosition, parseNumber } from \"./utils\";\n\nexport default function NumberInput({\n value,\n defaultValue,\n min,\n max,\n thousandSeparator = \".\",\n decimalSeparator = \",\",\n maxDecimalDigits = 0,\n allowNegative,\n onChange,\n onClear,\n onBlur,\n ref,\n ...props\n}: NumberInputProps) {\n const formatOptions = {\n max,\n min,\n thousandSeparator,\n decimalSeparator,\n maxDecimalDigits,\n allowNegative,\n };\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string | number | null | undefined>(defaultValue);\n const currentValue = isControlled ? value : internalValue;\n\n const formattedDisplayValue = formatNumberString(currentValue, formatOptions);\n\n const handleClear = () => {\n if (!isControlled) {\n setInternalValue(\"\");\n }\n onClear?.();\n };\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n const inputElement = e.target;\n const rawInputValue = inputElement.value;\n const oldCaretPos = inputElement.selectionStart || 0;\n\n // Format giá trị mới với ký tự phân cách và clamp max (không clamp min dương khi đang gõ)\n const newFormattedValue = formatNumberString(rawInputValue, formatOptions);\n\n // Tính toán lại vị trí con trỏ chuột không bị nhảy\n const newCaretPos = calculateCaretPosition(rawInputValue, newFormattedValue, oldCaretPos, { decimalSeparator });\n\n if (!isControlled) {\n setInternalValue(newFormattedValue);\n }\n\n // Gán giá trị vào target và trigger onChange\n inputElement.value = newFormattedValue;\n\n if (onChange) {\n const syntheticEvent = {\n ...e,\n target: inputElement,\n currentTarget: inputElement,\n } as ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n\n // Đặt lại vị trí con trỏ chuột\n requestAnimationFrame(() => {\n if (inputElement && inputElement.setSelectionRange) {\n inputElement.setSelectionRange(newCaretPos, newCaretPos);\n }\n });\n };\n\n const handleBlur = (e: FocusEvent<HTMLInputElement>) => {\n if (min !== undefined && currentValue !== undefined && currentValue !== null && currentValue !== \"\") {\n const num = parseNumber(String(currentValue), { thousandSeparator, decimalSeparator });\n if (num !== undefined && num < min) {\n const clampedValue = formatNumberString(min, { ...formatOptions, clampMin: true });\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n if (onChange) {\n e.target.value = clampedValue;\n const syntheticEvent = {\n ...e,\n target: e.target,\n currentTarget: e.target,\n } as unknown as ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n }\n }\n onBlur?.(e);\n };\n\n return (\n <Input\n ref={ref}\n type=\"text\"\n inputMode={maxDecimalDigits > 0 ? \"decimal\" : \"numeric\"}\n value={formattedDisplayValue}\n onChange={handleChange}\n onBlur={handleBlur}\n onClear={handleClear}\n {...props}\n />\n );\n}\n","import { OtpInputType } from \"./types\";\n\nexport interface NumberFormatOptions {\n /** Ký tự phân cách hàng nghìn. Mặc định \".\" (Việt Nam) */\n thousandSeparator?: string;\n\n /** Ký tự phân cách thập phân. Mặc định \",\" (Việt Nam) */\n decimalSeparator?: string;\n\n /** Số chữ số thập phân tối đa. Mặc định 0 (số nguyên). */\n maxDecimalDigits?: number;\n\n /** Cho phép nhập số âm hay không. Mặc định true (nếu min < 0 hoặc min chưa định nghĩa). */\n allowNegative?: boolean;\n\n /** Giá trị lớn nhất cho phép */\n max?: number;\n\n /** Giá trị nhỏ nhất cho phép */\n min?: number;\n\n /** Có bắt buộc clamp giá trị nhỏ hơn min về min hay không (mặc định false khi đang gõ) */\n clampMin?: boolean;\n}\n\n/**\n * Format chuỗi số với ký tự phân cách hàng nghìn, phân cách thập phân, số âm và giới hạn min/max.\n * Ví dụ VN: \"-1000000,5\" -> \"-1.000.000,5\"\n * Ví dụ US: \"-1000000.5\" -> \"-1,000,000.5\"\n */\nexport function formatNumberString(\n rawInput: string | number | undefined | null,\n options?: NumberFormatOptions\n): string {\n if (rawInput === undefined || rawInput === null || rawInput === \"\") {\n return \"\";\n }\n\n const thousandSep = options?.thousandSeparator ?? \".\";\n const decimalSep = options?.decimalSeparator ?? \",\";\n const maxDecimals = options?.maxDecimalDigits ?? 0;\n const min = options?.min;\n const max = options?.max;\n const clampMin = options?.clampMin ?? false;\n\n // Tự động bật cho phép số âm nếu min chưa set hoặc min < 0\n const allowNeg = options?.allowNegative ?? (min === undefined || min < 0);\n\n const rawStr = String(rawInput).trim();\n if (!rawStr) return \"\";\n\n // Kiểm tra dấu âm\n const isNegative = allowNeg && rawStr.startsWith(\"-\");\n\n // Nếu người dùng vừa gõ duy nhất dấu \"-\"\n if (isNegative && rawStr === \"-\") {\n return \"-\";\n }\n\n // Nếu có số thập phân (maxDecimals > 0)\n if (maxDecimals > 0) {\n const hasDecimal = rawStr.includes(decimalSep);\n\n if (hasDecimal) {\n const parts = rawStr.split(decimalSep);\n const integerDigits = parts[0]?.replace(/\\D/g, \"\") ?? \"\";\n const decimalDigits = parts.slice(1).join(\"\").replace(/\\D/g, \"\").slice(0, maxDecimals);\n\n // Chuyển sang số float để kiểm tra min/max\n if (integerDigits || decimalDigits) {\n let floatVal = parseFloat(`${integerDigits || \"0\"}.${decimalDigits || \"0\"}`);\n if (isNegative) floatVal = -floatVal;\n\n if (max !== undefined && !isNaN(floatVal) && floatVal > max) {\n return formatNumberString(max, { ...options, max: undefined, min: undefined });\n }\n if (min !== undefined && !isNaN(floatVal) && floatVal < min && (clampMin || (isNegative && min < 0))) {\n return formatNumberString(min, { ...options, max: undefined, min: undefined });\n }\n }\n\n // Format phần nguyên\n const formattedInteger = integerDigits\n ? parseInt(integerDigits, 10)\n .toString()\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, thousandSep)\n : \"\";\n\n const sign = isNegative ? \"-\" : \"\";\n\n // Nếu đang gõ dấu phẩy ở cuối (ví dụ \"-1.000,\")\n if (parts.length > 1 && parts[1] === \"\" && decimalDigits === \"\") {\n return `${sign}${formattedInteger || \"0\"}${decimalSep}`;\n }\n\n return decimalDigits.length > 0\n ? `${sign}${formattedInteger || \"0\"}${decimalSep}${decimalDigits}`\n : `${sign}${formattedInteger}`;\n }\n }\n\n // Chế độ số nguyên thuần túy\n const digitsOnly = rawStr.replace(/\\D/g, \"\");\n if (!digitsOnly) {\n return isNegative ? \"-\" : \"\";\n }\n\n let num = parseInt(digitsOnly, 10);\n if (isNaN(num)) return \"\";\n\n if (isNegative) {\n num = -num;\n }\n\n // Kiểm tra giới hạn max / min\n if (max !== undefined && num > max) {\n num = max;\n }\n if (min !== undefined && num < min && (clampMin || (isNegative && min < 0))) {\n num = min;\n }\n\n const sign = num < 0 ? \"-\" : \"\";\n const absFormatted = Math.abs(num)\n .toString()\n .replace(/\\B(?=(\\d{3})+(?!\\d))/g, thousandSep);\n\n return `${sign}${absFormatted}`;\n}\n\n/**\n * Lấy chuỗi số thô (loại bỏ dấu phân cách hàng nghìn, giữ lại dấu âm).\n */\nexport function parseRawNumberString(\n formattedValue: string,\n options?: Pick<NumberFormatOptions, \"thousandSeparator\">\n): string {\n const thousandSep = options?.thousandSeparator ?? \".\";\n return formattedValue.split(thousandSep).join(\"\");\n}\n\n/**\n * Chuyển chuỗi đã format thành số (number) trong JavaScript.\n */\nexport function parseNumber(\n formattedValue: string,\n options?: Pick<NumberFormatOptions, \"thousandSeparator\" | \"decimalSeparator\">\n): number | undefined {\n if (!formattedValue) return undefined;\n\n const thousandSep = options?.thousandSeparator ?? \".\";\n const decimalSep = options?.decimalSeparator ?? \",\";\n\n let clean = formattedValue.split(thousandSep).join(\"\");\n\n if (decimalSep !== \".\") {\n clean = clean.split(decimalSep).join(\".\");\n }\n\n clean = clean.replace(/[^\\d.-]/g, \"\");\n if (!clean || clean === \".\" || clean === \"-\") return undefined;\n\n const num = parseFloat(clean);\n return isNaN(num) ? undefined : num;\n}\n\n/**\n * Tính toán lại vị trí con trỏ chuột (caret) sau khi chèn/xóa dấu phân cách hoặc dấu âm.\n */\nexport function calculateCaretPosition(\n oldValue: string,\n newValue: string,\n oldCaretPosition: number,\n options?: Pick<NumberFormatOptions, \"decimalSeparator\">\n): number {\n const decimalSep = options?.decimalSeparator ?? \",\";\n\n // Đếm số lượng ký tự có nghĩa (chữ số + dấu phân cách + dấu âm) trước con trỏ cũ\n let charsBeforeCaret = 0;\n for (let i = 0; i < oldCaretPosition && i < oldValue.length; i++) {\n const ch = oldValue.charAt(i);\n if (/\\d/.test(ch) || ch === decimalSep || ch === \"-\") {\n charsBeforeCaret++;\n }\n }\n\n // Nếu không có ký tự có nghĩa nào trước con trỏ cũ\n if (charsBeforeCaret === 0) {\n return 0;\n }\n\n // Tìm vị trí tương ứng trong chuỗi mới (mặc định ở cuối chuỗi mới nếu ký tự gõ thêm bị loại bỏ)\n let newCaretPosition = newValue.length;\n let charsCount = 0;\n\n for (let i = 0; i < newValue.length; i++) {\n const ch = newValue.charAt(i);\n if (/\\d/.test(ch) || ch === decimalSep || ch === \"-\") {\n charsCount++;\n }\n if (charsCount === charsBeforeCaret) {\n newCaretPosition = i + 1;\n break;\n }\n }\n\n return Math.min(newCaretPosition, newValue.length);\n}\n\n// ==================== OTP INPUT UTILS ====================\n\n/**\n * Kiểm tra một ký tự đơn lẻ có hợp lệ theo kiểu nhập OTP (numeric, alphanumeric, password) hay không.\n *\n * @param char - Ký tự cần kiểm tra (1 ký tự).\n * @param type - Kiểu OTP cho phép: 'numeric' (chỉ số 0-9), 'alphanumeric' (chữ và số), hoặc 'password'. Mặc định là 'numeric'.\n * @returns `true` nếu ký tự hợp lệ, ngược lại `false`.\n *\n * @example\n * isValidOtpChar(\"5\", \"numeric\") // true\n * isValidOtpChar(\"a\", \"numeric\") // false\n * isValidOtpChar(\"a\", \"alphanumeric\") // true\n */\nexport function isValidOtpChar(char: string, type: OtpInputType = \"numeric\"): boolean {\n if (type === \"numeric\") {\n return /^\\d$/.test(char);\n }\n if (type === \"alphanumeric\") {\n return /^[a-zA-Z0-9]$/.test(char);\n }\n return true;\n}\n\n/**\n * Làm sạch chuỗi ký tự đầu vào khi Paste hoặc Autofill, chỉ giữ lại các ký tự hợp lệ theo kiểu OTP.\n *\n * @param str - Chuỗi ký tự thô cần làm sạch (ví dụ: \"ab6-5 c4 321d\").\n * @param type - Kiểu OTP cho phép: 'numeric', 'alphanumeric', hoặc 'password'. Mặc định là 'numeric'.\n * @returns Chuỗi ký tự đã được lọc sạch các ký tự không hợp lệ.\n *\n * @example\n * sanitizeOtpString(\"12-34 56\", \"numeric\") // \"123456\"\n * sanitizeOtpString(\"A-1#B2\", \"alphanumeric\") // \"A1B2\"\n */\nexport function sanitizeOtpString(str: string, type: import(\"./types\").OtpInputType = \"numeric\"): string {\n if (type === \"numeric\") {\n return str.replace(/\\D/g, \"\");\n }\n if (type === \"alphanumeric\") {\n return str.replace(/[^a-zA-Z0-9]/g, \"\");\n }\n return str;\n}\n\n// ==================== MULTI INPUT UTILS ====================\n\n/**\n * Phân tách chuỗi văn bản thành danh sách các thẻ (tags) dựa trên regex hoặc ký tự phân cách khi Paste hoặc khởi tạo.\n *\n * @param text - Chuỗi văn bản thô (ví dụ: \"React, Vue; Angular\\nSvelte\").\n * @param splitRegex - Regex phân tách (mặc định: `/[\\r\\n,;\\t]+/`).\n * @param trim - Tự động loại bỏ khoảng trắng thừa đầu và cuối mỗi tag (mặc định: `true`).\n * @returns Mảng các chuỗi tag hợp lệ đã lọc bỏ các phần tử rỗng.\n *\n * @example\n * splitTagsFromText(\"React, Vue; Angular\") // [\"React\", \"Vue\", \"Angular\"]\n */\nexport function splitTagsFromText(\n text: string,\n splitRegex: RegExp = /[\\r\\n,;\\t]+/,\n trim: boolean = true\n): string[] {\n if (!text) return [];\n return text\n .split(splitRegex)\n .map((item) => (trim ? item.trim() : item))\n .filter(Boolean);\n}\n","import {\n useId,\n useState,\n useEffect,\n useRef,\n useImperativeHandle,\n KeyboardEvent,\n ClipboardEvent,\n ChangeEvent,\n} from \"react\";\nimport { OtpInputProps, OtpInputRef } from \"./types\";\nimport { otpSlotSizeConfig, sizeConfig, radiusConfig, variantColorConfig } from \"./constants\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { isValidOtpChar, sanitizeOtpString } from \"./utils\";\n\nexport default function OtpInput({\n ref,\n config,\n id,\n name,\n length = 6,\n value,\n defaultValue = \"\",\n onChange,\n onComplete,\n type = \"numeric\",\n mask = false,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius,\n autoFocus = false,\n disabled = false,\n readOnly = false,\n groupSize,\n separator = \"-\",\n ariaLabel = \"One-time password\",\n getSlotAriaLabel,\n allowOneTimeCode = true,\n label,\n labelPlacement = \"top\",\n helperText,\n errorMessage,\n className = \"\",\n slotClassName = \"\",\n wrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n}: OtpInputProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n } = config ?? {};\n\n const generatedId = useId();\n const baseId = id || generatedId;\n const inputSlotId = `${baseId}-slot-0`;\n const errorHelperId = `${baseId}-error-helper`;\n\n // Internal state for uncontrolled mode\n const [internalValues, setInternalValues] = useState<string[]>(() => {\n const initial = (value !== undefined ? value : defaultValue).split(\"\");\n return Array.from({ length }, (_, i) => initial[i] || \"\");\n });\n\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n const isControlled = value !== undefined;\n const currentValues = isControlled\n ? Array.from({ length }, (_, i) => (value && value[i] !== undefined ? value[i] : \"\"))\n : internalValues;\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n // Auto focus on mount\n useEffect(() => {\n if (autoFocus && !disabled && !readOnly) {\n const firstEmptyIndex = currentValues.findIndex((val) => !val);\n const targetIndex = firstEmptyIndex !== -1 ? firstEmptyIndex : 0;\n inputRefs.current[targetIndex]?.focus();\n }\n }, [autoFocus, currentValues, disabled, readOnly]);\n\n // Imperative handle for parent ref\n useImperativeHandle(\n ref,\n (): OtpInputRef => ({\n getValue: () => currentValues.join(\"\"),\n clear: () => {\n const empty = Array(length).fill(\"\");\n if (!isControlled) {\n setInternalValues(empty);\n }\n onChange?.(\"\");\n if (!disabled && !readOnly) {\n inputRefs.current[0]?.focus();\n }\n },\n focus: (index = 0) => {\n const targetIndex = Math.max(0, Math.min(index, length - 1));\n inputRefs.current[targetIndex]?.focus();\n },\n }),\n [currentValues, length, isControlled, onChange, disabled, readOnly]\n );\n\n const triggerChange = (newValues: string[]) => {\n if (!isControlled) {\n setInternalValues(newValues);\n }\n const combined = newValues.join(\"\");\n onChange?.(combined);\n\n if (newValues.every((val) => val.length > 0) && newValues.length === length) {\n onComplete?.(combined);\n }\n };\n\n const fillOtpSlots = (text: string, index: number) => {\n const sanitized = sanitizeOtpString(text, type);\n if (!sanitized) return;\n\n const nextValues = [...currentValues];\n const startIndex = sanitized.length >= length ? 0 : index;\n const chars = sanitized.slice(0, length - startIndex).split(\"\");\n\n chars.forEach((char, i) => {\n if (startIndex + i < length) {\n nextValues[startIndex + i] = char;\n }\n });\n\n triggerChange(nextValues);\n\n const nextFocusIndex = Math.min(startIndex + chars.length, length - 1);\n inputRefs.current[nextFocusIndex]?.focus();\n };\n\n const handleSlotChange = (e: ChangeEvent<HTMLInputElement>, index: number) => {\n if (disabled || readOnly || isLoading) return;\n const inputValue = e.target.value;\n\n if (!inputValue) {\n const nextValues = [...currentValues];\n nextValues[index] = \"\";\n triggerChange(nextValues);\n return;\n }\n\n if (inputValue.length > 1) {\n fillOtpSlots(inputValue, index);\n return;\n }\n\n const lastChar = inputValue.slice(-1);\n if (isValidOtpChar(lastChar, type)) {\n const nextValues = [...currentValues];\n nextValues[index] = lastChar;\n triggerChange(nextValues);\n\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>, index: number) => {\n if (disabled || readOnly || isLoading) return;\n\n if (e.key === \"Backspace\") {\n e.preventDefault();\n const nextValues = [...currentValues];\n if (currentValues[index]) {\n nextValues[index] = \"\";\n triggerChange(nextValues);\n } else if (index > 0) {\n nextValues[index - 1] = \"\";\n triggerChange(nextValues);\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === \"Delete\") {\n e.preventDefault();\n const nextValues = [...currentValues];\n nextValues[index] = \"\";\n triggerChange(nextValues);\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n if (index > 0) {\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault();\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === \"c\") {\n const combined = currentValues.join(\"\");\n if (combined) {\n navigator.clipboard?.writeText(combined);\n }\n } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === \"x\") {\n e.preventDefault();\n const combined = currentValues.join(\"\");\n if (combined) {\n navigator.clipboard?.writeText(combined);\n }\n const empty = Array(length).fill(\"\");\n triggerChange(empty);\n inputRefs.current[0]?.focus();\n }\n };\n\n const handlePaste = (e: ClipboardEvent<HTMLInputElement>, index: number) => {\n if (disabled || readOnly || isLoading) return;\n e.preventDefault();\n const pastedData = e.clipboardData.getData(\"text/plain\");\n fillOtpSlots(pastedData, index);\n };\n\n const currentSize = getSafeConfig(size, otpSlotSizeConfig, \"md\");\n const sizeStyles = getSafeConfig(size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n\n const variantStyles =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, variantColorConfig, \"outline\"), \"primary\");\n\n const disabledStyles = disabled ? \"opacity-50\" : \"\";\n\n const renderLabel = () => {\n if (!label) return null;\n return (\n <label\n htmlFor={inputSlotId}\n className={`block font-medium text-neutral-700 select-none ${currentSize.label} ${labelClassName}`}\n >\n {label}\n {isRequired && <span className=\"text-error-500 ml-0.5\">*</span>}\n </label>\n );\n };\n\n const isHorizontal = labelPlacement === \"left\";\n\n return (\n <div className={`group/otp flex ${isHorizontal ? \"flex-row items-start gap-3\" : \"flex-col\"} ${wrapperClassName}`}>\n {renderLabel()}\n\n <div className=\"flex flex-col\">\n <div\n role=\"group\"\n aria-label={ariaLabel}\n aria-describedby={errorMessage || helperText ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n className={`inline-flex items-center ${currentSize.gap} ${className}`}\n >\n {Array.from({ length }).map((_, index) => {\n const isMasked = Boolean(mask || type === \"password\");\n const slotAriaLabel = getSlotAriaLabel\n ? getSlotAriaLabel(index, length)\n : `Ký tự ${index + 1} trên ${length}`;\n\n const shouldRenderSeparator =\n Boolean(groupSize && groupSize > 0) && (index + 1) % (groupSize || 1) === 0 && index < length - 1;\n\n return (\n <div key={`${baseId}-slot-${index}`} className=\"inline-flex items-center gap-1.5\">\n <input\n id={`${baseId}-slot-${index}`}\n ref={(el) => {\n inputRefs.current[index] = el;\n }}\n type={isMasked ? \"password\" : \"text\"}\n inputMode={type === \"numeric\" ? \"numeric\" : \"text\"}\n pattern={type === \"numeric\" ? \"[0-9]*\" : undefined}\n maxLength={1}\n value={currentValues[index] || \"\"}\n onFocus={(e) => e.target.select()}\n onChange={(e) => handleSlotChange(e, index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n onPaste={(e) => handlePaste(e, index)}\n disabled={disabled || isLoading}\n readOnly={readOnly}\n aria-label={slotAriaLabel}\n aria-invalid={hasError}\n aria-required={isRequired}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n autoComplete={allowOneTimeCode ? \"one-time-code\" : \"off\"}\n autoCorrect=\"off\"\n autoCapitalize=\"none\"\n spellCheck={false}\n data-1p-ignore=\"true\"\n data-lpignore=\"true\"\n data-form-type=\"other\"\n className={`border-2 text-center p-0 outline-none transition-all duration-150 ease-in-out text-neutral-900 ${\n currentSize.slot\n } ${currentSize.text} ${roundedClass} ${variantStyles} ${disabledStyles} ${slotClassName}`}\n />\n {shouldRenderSeparator && (\n <span\n aria-hidden=\"true\"\n className=\"inline-flex items-center justify-center text-neutral-400 select-none font-bold shrink-0\"\n >\n {separator}\n </span>\n )}\n </div>\n );\n })}\n\n {isLoading && showSpinner && (\n <div\n role=\"status\"\n aria-label=\"Đang tải\"\n className=\"inline-flex items-center justify-center pl-1.5 shrink-0 text-neutral-400\"\n >\n <Spinner className={`animate-spin ${sizeStyles.icon}`} />\n </div>\n )}\n </div>\n\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n\n {name && (\n <input\n type=\"hidden\"\n name={name}\n value={currentValues.join(\"\")}\n disabled={disabled || isLoading}\n />\n )}\n </div>\n </div>\n );\n}\n","import { useId, useState, useRef, ReactNode, KeyboardEvent, ClipboardEvent } from \"react\";\nimport { useMergeRefs } from \"@floating-ui/react\";\nimport { MultiInputProps } from \"./types\";\nimport {\n multiInputSizeConfig,\n radiusConfig,\n badgeRadiusMap,\n variantColorConfig,\n labelColorConfig,\n} from \"./constants\";\nimport { Badge } from \"@/components/badge\";\nimport CloseIcon from \"@/components/icons/CloseIcon\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport PlusIcon from \"@/components/icons/PlusIcon\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { splitTagsFromText } from \"./utils\";\n\nexport default function MultiInput({\n size,\n variant,\n color,\n radius,\n label,\n labelPlacement = \"floating\",\n config,\n helperText,\n errorMessage,\n leftIcon,\n leftAddon,\n rightIcon,\n rightAddon,\n onClear,\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n id,\n name,\n value,\n defaultValue = [],\n onChange,\n inputValue,\n onInputValueChange,\n delimiters = [\"Enter\"],\n showAddButton = false,\n renderAddButton,\n addOnBlur = false,\n addOnPaste = true,\n pasteSplitRegex = /[\\r\\n,;\\t]+/,\n trimValues = true,\n allowDuplicates = false,\n onDuplicate,\n maxTags,\n onMaxTagsReached,\n maxTagLength,\n validateTag,\n onValidateError,\n maxTagCount,\n renderTag,\n tagVariant,\n tagColor,\n tagRadius,\n tagSize,\n tagClassName = \"\",\n addButtonClassName = \"\",\n disabled = false,\n readOnly = false,\n className = \"\",\n placeholder = \"Nhập và nhấn Enter...\",\n autoFocus = false,\n ref,\n}: MultiInputProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = false,\n isFullWidth = false,\n } = config ?? {};\n\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n const labelId = label ? `${inputId}-label` : undefined;\n\n const internalRef = useRef<HTMLInputElement | null>(null);\n const mergedRef = useMergeRefs([internalRef, ref]);\n\n // Controlled vs Uncontrolled Values\n const isValuesControlled = value !== undefined;\n const [internalValues, setInternalValues] = useState<string[]>(defaultValue);\n const currentValues = isValuesControlled ? value || [] : internalValues;\n\n // Controlled vs Uncontrolled Input Text\n const isInputControlled = inputValue !== undefined;\n const [internalInputValue, setInternalInputValue] = useState(\"\");\n const currentInputValue = isInputControlled ? inputValue || \"\" : internalInputValue;\n\n const [liveAnnouncement, setLiveAnnouncement] = useState(\"\");\n\n // Helper cập nhật text input\n const setInputText = (nextText: string) => {\n if (!isInputControlled) {\n setInternalInputValue(nextText);\n }\n onInputValueChange?.(nextText);\n };\n\n // Helper cập nhật values\n const updateValues = (nextValues: string[]) => {\n if (!isValuesControlled) {\n setInternalValues(nextValues);\n }\n onChange?.(nextValues);\n };\n\n // Helper thêm 1 tag\n const addTag = (rawTag: string): boolean => {\n if (disabled || readOnly || isLoading) return false;\n let tag = trimValues ? rawTag.trim() : rawTag;\n if (!tag) return false;\n\n if (maxTagLength && maxTagLength > 0 && tag.length > maxTagLength) {\n tag = tag.slice(0, maxTagLength);\n }\n\n if (maxTags !== undefined && currentValues.length >= maxTags) {\n onMaxTagsReached?.(tag);\n setLiveAnnouncement(`Maximum limit of ${maxTags} tags reached`);\n return false;\n }\n\n if (!allowDuplicates && currentValues.includes(tag)) {\n onDuplicate?.(tag);\n setLiveAnnouncement(`Tag \"${tag}\" already exists`);\n return false;\n }\n\n if (validateTag) {\n const validationResult = validateTag(tag);\n if (validationResult === false || typeof validationResult === \"string\") {\n onValidateError?.(tag, typeof validationResult === \"string\" ? validationResult : undefined);\n setLiveAnnouncement(`Tag \"${tag}\" is invalid`);\n return false;\n }\n }\n\n const nextValues = [...currentValues, tag];\n updateValues(nextValues);\n setInputText(\"\");\n setLiveAnnouncement(`Added tag \"${tag}\"`);\n return true;\n };\n\n // Helper thêm nhiều tags (khi paste)\n const addMultipleTags = (rawTags: string[]) => {\n if (disabled || readOnly || isLoading) return;\n const nextValues = [...currentValues];\n const existingTagsSet = new Set(currentValues);\n let addedCount = 0;\n\n for (const raw of rawTags) {\n let tag = trimValues ? raw.trim() : raw;\n if (!tag) continue;\n\n if (maxTagLength && maxTagLength > 0 && tag.length > maxTagLength) {\n tag = tag.slice(0, maxTagLength);\n }\n\n if (maxTags !== undefined && nextValues.length >= maxTags) {\n onMaxTagsReached?.(tag);\n break;\n }\n\n if (!allowDuplicates && existingTagsSet.has(tag)) {\n onDuplicate?.(tag);\n continue;\n }\n\n if (validateTag) {\n const validationResult = validateTag(tag);\n if (validationResult === false || typeof validationResult === \"string\") {\n onValidateError?.(tag, typeof validationResult === \"string\" ? validationResult : undefined);\n continue;\n }\n }\n\n nextValues.push(tag);\n existingTagsSet.add(tag);\n addedCount++;\n }\n\n updateValues(nextValues);\n setInputText(\"\");\n if (addedCount > 0) {\n setLiveAnnouncement(`Added ${addedCount} tags`);\n }\n };\n\n // Xóa 1 tag theo index\n const removeTag = (indexToRemove: number) => {\n if (disabled || readOnly || isLoading) return;\n const removedItem = currentValues[indexToRemove];\n const nextValues = currentValues.filter((_, i) => i !== indexToRemove);\n updateValues(nextValues);\n if (removedItem) {\n setLiveAnnouncement(`Removed tag \"${removedItem}\"`);\n }\n };\n\n // Xóa toàn bộ tags & text\n const handleClear = (e?: React.MouseEvent) => {\n e?.stopPropagation();\n if (disabled || readOnly || isLoading) return;\n updateValues([]);\n setInputText(\"\");\n setLiveAnnouncement(\"Removed all tags\");\n onClear?.();\n internalRef.current?.focus();\n };\n\n // Xử lý sự kiện bàn phím\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n\n const isDelimiter =\n delimiters.includes(e.key) ||\n (delimiters.includes(\"Enter\") && e.key === \"Enter\") ||\n (delimiters.includes(\"Comma\") && (e.key === \",\" || e.key === \"Comma\")) ||\n (delimiters.includes(\"Tab\") && e.key === \"Tab\") ||\n (delimiters.includes(\"Space\") && (e.key === \" \" || e.key === \"Space\"));\n\n if (isDelimiter) {\n if (currentInputValue) {\n e.preventDefault();\n addTag(currentInputValue);\n }\n } else if (e.key === \"Backspace\" && currentInputValue === \"\" && currentValues.length > 0) {\n e.preventDefault();\n removeTag(currentValues.length - 1);\n }\n };\n\n // Xử lý Paste\n const handlePaste = (e: ClipboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (addOnPaste) {\n const pasteText = e.clipboardData.getData(\"text\");\n if (pasteText) {\n const parts = splitTagsFromText(pasteText, pasteSplitRegex, trimValues);\n if (parts.length > 1 || pasteSplitRegex.test(pasteText)) {\n e.preventDefault();\n addMultipleTags(parts);\n }\n }\n }\n };\n\n const handleBlur = () => {\n if (addOnBlur && currentInputValue.trim()) {\n addTag(currentInputValue);\n }\n };\n\n const hasValue = currentValues.length > 0 || currentInputValue.length > 0;\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n const currentSize = getSafeConfig(size, multiInputSizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n const resolvedBadgeRadius = tagRadius || getSafeConfig(radius, badgeRadiusMap, \"md\");\n const resolvedBadgeSize = tagSize || currentSize.badgeSize || \"sm\";\n const resolvedTagColor = tagColor || color;\n const resolvedTagVariant = tagVariant || variant;\n\n const variantStyles =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, variantColorConfig, \"outline\"), \"primary\");\n\n const isFloating = labelPlacement === \"floating\";\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n id={labelId}\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-text font-bold bg-neutral-white transition-colors duration-150 ${currentSize.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n id={labelId}\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${currentSize.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n // Xử lý maxTagCount\n const visibleTags = maxTagCount && maxTagCount > 0 ? currentValues.slice(0, maxTagCount) : currentValues;\n const hiddenTagCount = maxTagCount && maxTagCount > 0 ? Math.max(0, currentValues.length - maxTagCount) : 0;\n\n const disabledStyles = disabled ? \"opacity-50 cursor-not-allowed pointer-events-none\" : \"cursor-text\";\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2\",\n currentSize.wrapper,\n roundedClass,\n variantStyles,\n disabledStyles,\n isFullWidth ? \"w-full\" : \"w-auto min-w-[200px]\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const isHorizontal = labelPlacement === \"left\";\n\n const canAddMore = maxTags === undefined || currentValues.length < maxTags;\n const showAddBtn = showAddButton && !disabled && !readOnly;\n\n return (\n <div\n role=\"group\"\n aria-labelledby={labelId}\n className={`group/field flex ${\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\"\n } ${isFullWidth ? \"w-full\" : \"inline-flex\"} ${wrapperClassName}`}\n >\n {/* Screen Reader Live Region */}\n <span className=\"sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {liveAnnouncement}\n </span>\n\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n <div className=\"flex items-stretch\">\n {leftAddon && (\n <div\n className={`inline-flex items-center px-3 text-neutral-600 bg-neutral-100 border border-r-0 border-neutral-300 text-sm font-medium ${\n roundedClass ? `${roundedClass} rounded-r-none` : \"\"\n }`}\n >\n {leftAddon}\n </div>\n )}\n\n <div\n className={`${containerClasses} ${\n leftAddon ? \"rounded-l-none!\" : \"\"\n } ${rightAddon ? \"rounded-r-none!\" : \"\"}`}\n >\n {isFloating && renderLabel()}\n\n {leftIcon && (\n <div className=\"flex items-center justify-center pl-1 pr-1.5 shrink-0\">{renderIconWrapper(leftIcon)}</div>\n )}\n\n {/* Container for tags list and native input */}\n <div className={`flex flex-wrap items-center flex-1 min-w-0 ${currentSize.gap}`}>\n {(() => {\n const tagOccurrenceMap = new Map<string, number>();\n return visibleTags.map((tagVal, index) => {\n const count = (tagOccurrenceMap.get(tagVal) ?? 0) + 1;\n tagOccurrenceMap.set(tagVal, count);\n const tagKey = `${tagVal}_${count}`;\n\n if (renderTag) {\n return (\n <span key={tagKey} className=\"inline-flex shrink-0\">\n {renderTag({\n value: tagVal,\n index,\n onRemove: () => removeTag(index),\n disabled,\n readOnly,\n })}\n </span>\n );\n }\n\n return (\n <span key={tagKey} className=\"inline-flex shrink-0\">\n <Badge\n size={resolvedBadgeSize}\n variant={resolvedTagVariant}\n color={resolvedTagColor}\n radius={resolvedBadgeRadius}\n deleteAriaLabel={`Remove tag ${tagVal}`}\n onDelete={!disabled && !readOnly ? () => removeTag(index) : undefined}\n className={`shrink-0 max-w-full truncate select-none ${tagClassName}`}\n >\n {tagVal}\n </Badge>\n </span>\n );\n });\n })()}\n\n {hiddenTagCount > 0 && (\n <span className=\"inline-flex shrink-0\">\n <Badge\n size={resolvedBadgeSize}\n variant=\"filled\"\n color=\"neutral\"\n radius={resolvedBadgeRadius}\n className=\"shrink-0 font-medium select-none\"\n >\n +{hiddenTagCount}\n </Badge>\n </span>\n )}\n\n {canAddMore ? (\n <input\n ref={mergedRef}\n id={inputId}\n type=\"text\"\n value={currentInputValue}\n onChange={(e) => setInputText(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={handleBlur}\n disabled={disabled || isLoading}\n readOnly={readOnly}\n autoFocus={autoFocus}\n aria-invalid={hasError}\n aria-required={isRequired}\n aria-describedby={errorMessage || helperText ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-autocomplete=\"none\"\n placeholder={currentValues.length === 0 ? placeholder : \"\"}\n className={`flex-1 bg-transparent outline-none border-none text-neutral-900 placeholder:text-neutral-400 disabled:cursor-not-allowed ${currentSize.input} ${className}`}\n />\n ) : null}\n </div>\n\n {/* Add (+) button at the end of input */}\n {showAddBtn && (\n <div className=\"flex items-center justify-center pl-1.5 shrink-0\">\n {renderAddButton ? (\n renderAddButton({\n onAdd: () => addTag(currentInputValue),\n disabled: !currentInputValue.trim() || !canAddMore,\n })\n ) : (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n if (currentInputValue.trim() && canAddMore) {\n addTag(currentInputValue);\n } else {\n internalRef.current?.focus();\n }\n }}\n disabled={!currentInputValue.trim() || !canAddMore}\n aria-label=\"Thêm thẻ\"\n className={`inline-flex items-center justify-center p-1 rounded hover:bg-neutral-200 active:scale-95 disabled:opacity-40 disabled:pointer-events-none transition-all cursor-pointer text-neutral-600 hover:text-neutral-900 ${addButtonClassName}`}\n >\n <PlusIcon className={currentSize.icon} />\n </button>\n )}\n </div>\n )}\n\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center pl-1.5 shrink-0\" role=\"status\" aria-label=\"Đang tải\">\n {renderIconWrapper(<Spinner />)}\n </div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa tất cả các thẻ\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center pl-1.5 shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${currentSize.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n {!isLoading && rightIcon && (\n <div className=\"flex items-center justify-center pl-1.5 shrink-0\">{renderIconWrapper(rightIcon)}</div>\n )}\n </div>\n\n {rightAddon && (\n <div\n className={`inline-flex items-center px-3 text-neutral-600 bg-neutral-100 border border-l-0 border-neutral-300 text-sm font-medium ${\n roundedClass ? `${roundedClass} rounded-l-none` : \"\"\n }`}\n >\n {rightAddon}\n </div>\n )}\n </div>\n\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n\n {name && (() => {\n const hiddenOccurrenceMap = new Map<string, number>();\n return (\n <>\n {currentValues.map((tagVal) => {\n const count = (hiddenOccurrenceMap.get(tagVal) ?? 0) + 1;\n hiddenOccurrenceMap.set(tagVal, count);\n const tagKey = `${tagVal}_${count}`;\n return (\n <input\n key={`hidden_${tagKey}`}\n type=\"hidden\"\n name={`${name}[]`}\n value={tagVal}\n disabled={disabled || isLoading}\n />\n );\n })}\n {currentValues.length === 0 && (\n <input\n type=\"hidden\"\n name={name}\n value=\"\"\n disabled={disabled || isLoading}\n />\n )}\n </>\n );\n })()}\n </div>\n </div>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function PlusIcon({ width = 14, height = 14, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n","import { useId, useState, useRef, ChangeEvent } from \"react\";\nimport TextareaAutosize from \"react-textarea-autosize\";\nimport { useMergeRefs } from \"@floating-ui/react\";\nimport { TextAreaProps } from \"./types\";\nimport { sizeConfig, radiusConfig, resizeConfig, variantColorConfig, labelColorConfig } from \"./constants\";\nimport CloseIcon from \"@/components/icons/CloseIcon\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function TextArea({\n size,\n variant,\n color,\n radius,\n label,\n labelPlacement = \"floating\",\n config,\n helperText,\n errorMessage,\n onClear,\n minRows = 3,\n maxRows,\n onHeightChange,\n cacheMeasurements,\n resize = \"none\",\n wrapperClassName = \"\",\n textareaWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n countClassName = \"\",\n id,\n value,\n defaultValue,\n onChange,\n disabled = false,\n readOnly = false,\n className = \"\",\n placeholder,\n maxLength,\n ref,\n style,\n ...props\n}: TextAreaProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = false,\n showCount = false,\n isFullWidth = false,\n autoResize = true,\n } = config ?? {};\n\n const generatedId = useId();\n const textareaId = id || generatedId;\n const errorHelperId = `${textareaId}-error-helper`;\n\n const internalRef = useRef<HTMLTextAreaElement | null>(null);\n const [internalValue, setInternalValue] = useState<string | number | readonly string[] | undefined>(defaultValue);\n const mergedRef = useMergeRefs([internalRef, ref]);\n\n const isControlled = value !== undefined;\n const currentValue = isControlled ? value : internalValue;\n\n // Visual error state updates immediately\n const isInvalidState = Boolean(isInvalid || errorMessage);\n const activeColor = isInvalidState ? \"error\" : color;\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n const resizeClass = autoResize ? \"resize-none\" : getSafeConfig(resize, resizeConfig, \"none\");\n\n const variantStyles =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, variantColorConfig, \"outline\"), \"primary\");\n\n const currentLength = currentValue !== undefined && currentValue !== null ? String(currentValue).length : 0;\n const hasValue = currentLength > 0;\n\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n let nextValue = e.target.value;\n if (maxLength !== undefined && nextValue.length > maxLength) {\n nextValue = nextValue.slice(0, maxLength);\n e.target.value = nextValue;\n }\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled) {\n setInternalValue(\"\");\n }\n onClear?.();\n };\n\n const isFloating = labelPlacement === \"floating\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = isInvalidState\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={textareaId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-text font-bold bg-neutral-white transition-colors duration-150 ${currentSize.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={textareaId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${currentSize.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const containerClasses = [\n \"group/textarea relative flex flex-col transition-all duration-150 ease-in-out border-2\",\n roundedClass,\n variantStyles,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : \"w-auto\",\n textareaWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const hasTopRightAction = isClearable || (isLoading && showSpinner);\n\n const textareaClasses = [\n \"w-full bg-transparent outline-none border-none text-neutral-900 placeholder:text-neutral-400 disabled:cursor-not-allowed ui-scrollbar\",\n currentSize.textarea,\n hasTopRightAction ? \"pr-8\" : \"\",\n showCount ? \"pb-6\" : \"\",\n resizeClass,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const isHorizontal = labelPlacement === \"left\";\n\n const commonProps = {\n id: textareaId,\n value: currentValue,\n onChange: handleChange,\n disabled: disabled || isLoading,\n readOnly,\n maxLength,\n \"aria-invalid\": isInvalidState,\n \"aria-required\": isRequired,\n \"aria-describedby\": errorMessage || helperText ? errorHelperId : undefined,\n \"aria-errormessage\": errorMessage ? errorHelperId : undefined,\n \"aria-busy\": isLoading,\n \"aria-disabled\": disabled || isLoading,\n placeholder,\n className: textareaClasses,\n style,\n ...props,\n };\n\n return (\n <div\n className={`group/field flex ${\n isHorizontal ? \"flex-row items-start gap-3\" : \"flex-col\"\n } ${isFloating ? \"pt-2\" : \"\"} ${isFullWidth ? \"w-full\" : \"inline-flex\"} ${wrapperClassName}`}\n >\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n <div className={containerClasses}>\n {isFloating && renderLabel()}\n\n {autoResize ? (\n <TextareaAutosize\n ref={mergedRef}\n minRows={minRows}\n maxRows={maxRows}\n onHeightChange={onHeightChange}\n cacheMeasurements={cacheMeasurements}\n {...commonProps}\n />\n ) : (\n <textarea ref={mergedRef} rows={minRows} {...commonProps} />\n )}\n\n {/* Top-Right Loading Spinner */}\n {isLoading && showSpinner && (\n <div className=\"absolute top-2.5 right-2.5 text-neutral-400 size-4 select-none pointer-events-none\">\n <Spinner className=\"size-full animate-spin\" />\n </div>\n )}\n\n {/* Top-Right Clear Button */}\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa nội dung\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`absolute top-2.5 right-2.5 inline-flex items-center justify-center text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full size-4 ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n {/* Character Counter */}\n {showCount && (\n <div\n className={`absolute bottom-2 right-2.5 text-[11px] font-mono select-none pointer-events-none z-10 text-neutral-400 ${countClassName}`}\n >\n {currentLength}\n {maxLength !== undefined && `/${maxLength}`}\n </div>\n )}\n </div>\n\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import { TextAreaSize, TextAreaVariant, TextAreaColor, TextAreaRadius, TextAreaResize } from \"./types\";\n\nexport const sizeConfig: Record<\n TextAreaSize,\n {\n textarea: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n textarea: \"text-[11px] px-2 py-1 leading-tight\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n textarea: \"text-xs px-2.5 py-1.5 leading-normal\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n textarea: \"text-sm px-3.5 py-2 leading-normal\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n textarea: \"text-base px-4 py-2.5 leading-normal\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n textarea: \"text-lg px-5 py-3 leading-normal\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-xs\",\n helper: \"text-sm mt-1\",\n },\n};\n\nexport const radiusConfig: Record<TextAreaRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const resizeConfig: Record<TextAreaResize, string> = {\n none: \"resize-none\",\n vertical: \"resize-y\",\n horizontal: \"resize-x\",\n both: \"resize\",\n};\n\nexport const variantColorConfig: Record<Exclude<TextAreaVariant, \"other\">, Record<TextAreaColor, string>> = {\n outline: {\n primary:\n \"bg-neutral-white border-primary-300 hover:border-primary-400 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-neutral-white border-secondary-300 hover:border-secondary-400 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-neutral-white border-error-300 hover:border-error-400 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-neutral-white border-success-300 hover:border-success-400 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-neutral-white border-warning-300 hover:border-warning-400 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-neutral-white border-info-300 hover:border-info-400 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n filled: {\n primary:\n \"bg-primary-50/60 border border-primary-300 hover:border-primary-400 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-secondary-50/60 border border-secondary-300 hover:border-secondary-400 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-error-50/60 border border-error-300 hover:border-error-400 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-success-50/60 border border-success-300 hover:border-success-400 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-warning-50/60 border border-warning-300 hover:border-warning-400 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-info-50/60 border border-info-300 hover:border-info-400 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-50/60 border border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n ghost: {\n primary:\n \"bg-transparent border border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-transparent border border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-transparent border border-transparent hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-transparent border border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-transparent border border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-transparent border border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-transparent border border-transparent hover:bg-neutral-100/50 focus-within:bg-neutral-100/50 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n};\n\nexport const labelColorConfig: Record<TextAreaColor, string> = {\n primary: \"text-primary-500 group-focus-within/field:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/field:text-secondary-600\",\n error: \"text-error-500 group-focus-within/field:text-error-600\",\n success: \"text-success-500 group-focus-within/field:text-success-600\",\n warning: \"text-warning-500 group-focus-within/field:text-warning-600\",\n info: \"text-info-500 group-focus-within/field:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/field:text-neutral-600\",\n};\n","import React, { useId, useState, useEffect, useRef, useImperativeHandle } from \"react\";\nimport { CheckboxProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig } from \"./constants\";\nimport { useCheckboxGroupContext } from \"./context\";\nimport CheckIcon from \"@/components/icons/CheckIcon\";\nimport MinusIcon from \"@/components/icons/MinusIcon\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\n\nexport default function Checkbox({\n size: sizeProp,\n variant: variantProp,\n color: colorProp,\n radius: radiusProp,\n indeterminate = false,\n isLoading: isLoadingProp,\n isInvalid: isInvalidProp,\n isRequired: isRequiredProp,\n label: labelProp,\n children,\n helperText,\n errorMessage,\n labelPlacement: labelPlacementProp,\n icon,\n indeterminateIcon,\n wrapperClassName = \"\",\n boxClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n className = \"\",\n checked: checkedProp,\n defaultChecked,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onChange,\n value,\n id: idProp,\n name: nameProp,\n ref,\n ...props\n}: CheckboxProps) {\n const label = labelProp || children;\n\n const group = useCheckboxGroupContext();\n const generatedId = useId();\n const id = idProp || generatedId;\n const helperId = `${id}-helper`;\n\n const size = sizeProp ?? group?.size ?? \"md\";\n const variant = variantProp ?? group?.variant ?? \"filled\";\n const color = colorProp ?? group?.color ?? \"primary\";\n const radius = radiusProp ?? group?.radius;\n const disabled = disabledProp ?? group?.disabled ?? false;\n const isReadOnly = readOnlyProp ?? group?.isReadOnly ?? false;\n const isLoading = isLoadingProp ?? group?.isLoading ?? false;\n const isRequired = isRequiredProp ?? group?.isRequired ?? false;\n const isInvalid = Boolean(isInvalidProp ?? group?.isInvalid ?? !!errorMessage);\n const labelPlacement = labelPlacementProp ?? group?.labelPlacement ?? \"right\";\n\n // Determine controlled vs uncontrolled state\n const isGroupControlled = group?.value !== undefined && value !== null && value !== undefined;\n const isControlled = checkedProp !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n\n const isChecked = isGroupControlled\n ? group.value!.includes(String(value))\n : isControlled\n ? checkedProp\n : internalChecked;\n\n const innerRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);\n\n useEffect(() => {\n if (innerRef.current) {\n innerRef.current.indeterminate = Boolean(indeterminate);\n }\n }, [indeterminate]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled || isReadOnly || isLoading) return;\n\n if (group?.onChange && value !== undefined) {\n group.onChange(String(value), e.target.checked);\n }\n if (!isControlled && !isGroupControlled) {\n setInternalChecked(e.target.checked);\n }\n onChange?.(e);\n };\n\n const currentSize = sizeConfig[size] || sizeConfig.md;\n const roundedClass = radius ? radiusConfig[radius] : currentSize.rounded;\n\n const isCheckedOrIndeterminate = isChecked || indeterminate;\n\n // Visual Box Color & Variant styling\n let boxVariantStyles: string;\n if (variant === \"other\") {\n boxVariantStyles = \"\";\n } else if (isCheckedOrIndeterminate) {\n boxVariantStyles = variantColorConfig[variant]?.[color] || variantColorConfig.filled.primary;\n } else {\n // Unchecked base style with focus ring according to color\n boxVariantStyles =\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 dark:bg-neutral-900 dark:border-neutral-700 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\";\n }\n\n // Error border overrides when invalid\n if (isInvalid) {\n boxVariantStyles = isCheckedOrIndeterminate\n ? variantColorConfig[variant === \"other\" ? \"filled\" : variant]?.[\"error\"] || variantColorConfig.filled.error\n : \"bg-neutral-white border-error-500 hover:border-error-600 text-error-600 dark:bg-neutral-900 dark:border-error-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\";\n }\n\n const boxClasses = [\n \"inline-flex items-center justify-center shrink-0 border transition-all duration-150 select-none\",\n currentSize.box,\n roundedClass,\n boxVariantStyles,\n !disabled && !isReadOnly && !isLoading ? \"active:scale-95\" : \"\",\n boxClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const labelClasses = [\n \"select-none font-medium text-neutral-900 dark:text-neutral-100 transition-colors\",\n currentSize.label,\n disabled ? \"opacity-60\" : \"\",\n labelClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const wrapperClasses = [\n \"group inline-flex relative\",\n labelPlacement === \"left\" ? \"flex-row-reverse justify-between\" : \"flex-row\",\n currentSize.gap,\n disabled ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer\",\n wrapperClassName,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const renderIcon = () => {\n if (isLoading) {\n return (\n <span\n className={`inline-flex items-center justify-center animate-in zoom-in-75 duration-100 ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n <Spinner className=\"size-full animate-spin\" />\n </span>\n );\n }\n if (indeterminate) {\n return (\n <span\n className={`inline-flex items-center justify-center animate-in zoom-in-75 duration-100 ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {indeterminateIcon || <MinusIcon className=\"size-full\" />}\n </span>\n );\n }\n if (isChecked) {\n return (\n <span\n className={`inline-flex items-center justify-center animate-in zoom-in-75 duration-100 ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {icon || <CheckIcon className=\"size-full\" />}\n </span>\n );\n }\n return null;\n };\n\n const hasContent = Boolean(label);\n\n const handleWrapperClick = (e: React.MouseEvent<HTMLLabelElement>) => {\n if (disabled || isReadOnly || isLoading) {\n e.preventDefault();\n }\n };\n\n return (\n <div className=\"inline-flex flex-col\">\n <label className={wrapperClasses} onClick={handleWrapperClick}>\n {/* Hidden native input for Accessibility and form handling */}\n <input\n ref={innerRef}\n type=\"checkbox\"\n id={id}\n name={nameProp ?? group?.name}\n value={value}\n checked={isChecked}\n disabled={disabled || isLoading}\n readOnly={isReadOnly}\n required={isRequired}\n aria-checked={indeterminate ? \"mixed\" : isChecked}\n aria-invalid={isInvalid}\n aria-required={isRequired}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={errorMessage || helperText ? helperId : undefined}\n onChange={handleChange}\n className=\"sr-only peer\"\n {...props}\n />\n\n {/* Visual Box */}\n <span className={boxClasses} aria-hidden=\"true\">\n {renderIcon()}\n </span>\n\n {/* Label */}\n {hasContent && (\n <span className={labelClasses}>\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n </label>\n\n {/* Helper text / Error message animation */}\n <HelperErrorText\n id={helperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n </div>\n );\n}\n","import { CheckboxSize, CheckboxVariant, CheckboxColor, CheckboxRadius } from \"./types\";\n\nexport const sizeConfig: Record<\n CheckboxSize,\n {\n box: string;\n icon: string;\n label: string;\n gap: string;\n rounded: string;\n helper: string;\n }\n> = {\n xs: {\n box: \"size-3.5\",\n icon: \"size-2.5\",\n label: \"text-xs leading-4\",\n gap: \"gap-1.5\",\n rounded: \"rounded-[3px]\",\n helper: \"text-[10px]\",\n },\n sm: {\n box: \"size-4\",\n icon: \"size-3\",\n label: \"text-sm leading-4\",\n gap: \"gap-2\",\n rounded: \"rounded-sm\",\n helper: \"text-[11px]\",\n },\n md: {\n box: \"size-5\",\n icon: \"size-3.5\",\n label: \"text-sm leading-5\",\n gap: \"gap-2.5\",\n rounded: \"rounded-md\",\n helper: \"text-xs\",\n },\n lg: {\n box: \"size-6\",\n icon: \"size-4\",\n label: \"text-base leading-6\",\n gap: \"gap-3\",\n rounded: \"rounded-md\",\n helper: \"text-xs\",\n },\n xl: {\n box: \"size-7\",\n icon: \"size-5\",\n label: \"text-lg leading-7\",\n gap: \"gap-3.5\",\n rounded: \"rounded-lg\",\n helper: \"text-sm\",\n },\n};\n\nexport const radiusConfig: Record<CheckboxRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const variantColorConfig: Record<Exclude<CheckboxVariant, \"other\">, Record<CheckboxColor, string>> = {\n filled: {\n primary:\n \"bg-primary-600 text-neutral-white border-primary-600 dark:bg-primary-500 dark:border-primary-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\",\n secondary:\n \"bg-secondary-600 text-neutral-white border-secondary-600 dark:bg-secondary-500 dark:border-secondary-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400 peer-focus-visible:border-secondary-500\",\n error:\n \"bg-error-600 text-neutral-white border-error-600 dark:bg-error-500 dark:border-error-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\",\n success:\n \"bg-success-600 text-neutral-white border-success-600 dark:bg-success-500 dark:border-success-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400 peer-focus-visible:border-success-500\",\n warning:\n \"bg-warning-500 text-neutral-950 border-warning-500 dark:bg-warning-400 dark:border-warning-400 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400 peer-focus-visible:border-warning-500\",\n info: \"bg-info-600 text-neutral-white border-info-600 dark:bg-info-500 dark:border-info-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400 peer-focus-visible:border-info-500\",\n neutral:\n \"bg-neutral-800 text-neutral-white border-neutral-800 dark:bg-neutral-200 dark:text-neutral-900 dark:border-neutral-200 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400 peer-focus-visible:border-neutral-500\",\n },\n outline: {\n primary:\n \"bg-transparent text-primary-600 border-2 border-primary-600 hover:bg-primary-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\",\n secondary:\n \"bg-transparent text-secondary-600 border-2 border-secondary-600 hover:bg-secondary-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400 peer-focus-visible:border-secondary-500\",\n error:\n \"bg-transparent text-error-600 border-2 border-error-600 hover:bg-error-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\",\n success:\n \"bg-transparent text-success-600 border-2 border-success-600 hover:bg-success-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400 peer-focus-visible:border-success-500\",\n warning:\n \"bg-transparent text-warning-700 border-2 border-warning-500 hover:bg-warning-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400 peer-focus-visible:border-warning-500\",\n info: \"bg-transparent text-info-600 border-2 border-info-600 hover:bg-info-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400 peer-focus-visible:border-info-500\",\n neutral:\n \"bg-transparent text-neutral-800 border-2 border-neutral-800 hover:bg-neutral-100/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400 peer-focus-visible:border-neutral-500\",\n },\n soft: {\n primary:\n \"bg-primary-100 text-primary-800 border-primary-300 hover:bg-primary-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\",\n secondary:\n \"bg-secondary-100 text-secondary-800 border-secondary-300 hover:bg-secondary-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400 peer-focus-visible:border-secondary-500\",\n error:\n \"bg-error-100 text-error-800 border-error-300 hover:bg-error-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\",\n success:\n \"bg-success-100 text-success-800 border-success-300 hover:bg-success-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400 peer-focus-visible:border-success-500\",\n warning:\n \"bg-warning-100 text-warning-900 border-warning-300 hover:bg-warning-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400 peer-focus-visible:border-warning-500\",\n info: \"bg-info-100 text-info-800 border-info-300 hover:bg-info-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400 peer-focus-visible:border-info-500\",\n neutral:\n \"bg-neutral-100 text-neutral-800 border-neutral-300 hover:bg-neutral-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400 peer-focus-visible:border-neutral-500\",\n },\n};\n","import { createContext, useContext } from \"react\";\nimport { CheckboxColor, CheckboxLabelPlacement, CheckboxRadius, CheckboxSize, CheckboxVariant } from \"./types\";\n\nexport interface CheckboxGroupContextValue {\n name?: string;\n value?: string[];\n onChange?: (val: string, checked: boolean) => void;\n size?: CheckboxSize;\n color?: CheckboxColor;\n variant?: CheckboxVariant;\n radius?: CheckboxRadius;\n disabled?: boolean;\n isReadOnly?: boolean;\n isLoading?: boolean;\n isInvalid?: boolean;\n isRequired?: boolean;\n labelPlacement?: CheckboxLabelPlacement;\n}\n\nexport const CheckboxGroupContext = createContext<CheckboxGroupContextValue | undefined>(undefined);\n\nexport const useCheckboxGroupContext = () => useContext(CheckboxGroupContext);\n","import type { SVGProps } from \"react\";\n\nexport default function CheckIcon({ width = 14, height = 14, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function MinusIcon({ width = 14, height = 14, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"3.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n","import { useState, useId, useMemo, useCallback } from \"react\";\nimport { CheckboxGroupProps } from \"./types\";\nimport { CheckboxGroupContext } from \"./context\";\nimport { sizeConfig } from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\n\nexport default function CheckboxGroup({\n value: valueProp,\n defaultValue = [],\n onChange,\n size = \"md\",\n color = \"primary\",\n variant = \"filled\",\n radius,\n disabled = false,\n isReadOnly = false,\n isLoading = false,\n isInvalid: isInvalidProp,\n isRequired = false,\n label,\n helperText,\n errorMessage,\n orientation = \"vertical\",\n labelPlacement = \"right\",\n className = \"\",\n wrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n children,\n ref,\n ...props\n}: CheckboxGroupProps) {\n const generatedId = useId();\n const labelId = `${generatedId}-label`;\n const helperId = `${generatedId}-helper`;\n\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = useState<string[]>(defaultValue);\n\n const currentValue = isControlled ? (valueProp as string[]) : internalValue;\n const isInvalid = Boolean(isInvalidProp ?? !!errorMessage);\n\n const handleCheckboxChange = useCallback(\n (val: string, isChecked: boolean) => {\n if (disabled || isReadOnly || isLoading) return;\n\n let nextValue: string[];\n if (isChecked) {\n nextValue = [...currentValue, val];\n } else {\n nextValue = currentValue.filter((item) => item !== val);\n }\n\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n },\n [disabled, isReadOnly, isLoading, currentValue, isControlled, onChange]\n );\n\n const contextValue = useMemo(\n () => ({\n value: currentValue,\n onChange: handleCheckboxChange,\n size,\n color,\n variant,\n radius,\n disabled,\n isReadOnly,\n isLoading,\n isInvalid,\n isRequired,\n labelPlacement,\n }),\n [\n currentValue,\n handleCheckboxChange,\n size,\n color,\n variant,\n radius,\n disabled,\n isReadOnly,\n isLoading,\n isInvalid,\n isRequired,\n labelPlacement,\n ]\n );\n\n const orientationClasses =\n orientation === \"horizontal\" ? \"flex flex-row flex-wrap gap-4 items-center\" : \"flex flex-col gap-2.5\";\n\n const groupLabelClasses = [\n \"text-sm font-semibold text-neutral-900 dark:text-neutral-100 mb-1.5 select-none\",\n disabled ? \"opacity-60\" : \"\",\n labelClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const currentSize = sizeConfig[size] || sizeConfig.md;\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={errorMessage || helperText ? helperId : undefined}\n aria-errormessage={errorMessage ? helperId : undefined}\n aria-invalid={isInvalid ? \"true\" : undefined}\n aria-disabled={disabled ? \"true\" : undefined}\n aria-busy={isLoading ? \"true\" : undefined}\n className={`inline-flex flex-col ${wrapperClassName}`}\n {...props}\n >\n {label && (\n <span id={labelId} className={groupLabelClasses}>\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n\n <div className={`${orientationClasses} ${className}`}>\n <CheckboxGroupContext.Provider value={contextValue}>{children}</CheckboxGroupContext.Provider>\n </div>\n\n {/* Helper / Error animated text */}\n <HelperErrorText\n id={helperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n </div>\n );\n}\n","import React, { useId, useState, useRef, useImperativeHandle } from \"react\";\nimport { RadioProps } from \"./types\";\nimport { sizeConfig, variantColorConfig } from \"./constants\";\nimport { useRadioGroupContext } from \"./context\";\nimport RadioDotIcon from \"@/components/icons/RadioDotIcon\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\n\nexport default function Radio({\n size: sizeProp,\n variant: variantProp,\n color: colorProp,\n isLoading: isLoadingProp,\n isInvalid: isInvalidProp,\n isRequired: isRequiredProp,\n label,\n helperText,\n errorMessage,\n labelPlacement: labelPlacementProp,\n dotIcon,\n wrapperClassName = \"\",\n boxClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n className = \"\",\n checked: checkedProp,\n defaultChecked,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onChange,\n value,\n id: idProp,\n name: nameProp,\n ref,\n ...props\n}: RadioProps) {\n const group = useRadioGroupContext();\n const generatedId = useId();\n const id = idProp || generatedId;\n const helperId = `${id}-helper`;\n\n const size = sizeProp ?? group?.size ?? \"md\";\n const variant = variantProp ?? group?.variant ?? \"filled\";\n const color = colorProp ?? group?.color ?? \"primary\";\n const disabled = disabledProp ?? group?.disabled ?? false;\n const isReadOnly = readOnlyProp ?? group?.isReadOnly ?? false;\n const isLoading = isLoadingProp ?? group?.isLoading ?? false;\n const isRequired = isRequiredProp ?? group?.isRequired ?? false;\n const isInvalid = Boolean(isInvalidProp ?? group?.isInvalid ?? (errorMessage ? true : false));\n const labelPlacement = labelPlacementProp ?? group?.labelPlacement ?? \"right\";\n\n // Name: from prop or from group context (RadioGroup manages grouping via name)\n const name = nameProp ?? group?.name;\n\n // Determine checked state when inside group\n // group.value can be string | null | undefined\n // null = nothing selected, undefined = uncontrolled\n const isGroupControlled =\n group !== undefined && group.value !== null && group.value !== undefined && value !== null && value !== undefined;\n const isControlled = checkedProp !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n\n const isChecked = isGroupControlled ? group.value === String(value) : isControlled ? checkedProp : internalChecked;\n\n const innerRef = useRef<HTMLInputElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled || isReadOnly || isLoading) return;\n\n if (group?.onChange && value !== undefined) {\n group.onChange(String(value));\n }\n if (!isControlled && !isGroupControlled) {\n setInternalChecked(e.target.checked);\n }\n onChange?.(e);\n };\n\n const currentSize = sizeConfig[size] || sizeConfig.md;\n\n // Visual Box Color & Variant styling\n let boxVariantStyles = \"\";\n if (variant === \"other\") {\n boxVariantStyles = \"\";\n } else if (isChecked) {\n boxVariantStyles = variantColorConfig[variant]?.[color] || variantColorConfig.filled.primary;\n } else {\n // Unchecked base style with focus ring\n boxVariantStyles =\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 dark:bg-neutral-900 dark:border-neutral-700 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\";\n }\n\n // Error border overrides when invalid\n if (isInvalid) {\n boxVariantStyles = isChecked\n ? variantColorConfig[variant === \"other\" ? \"filled\" : variant]?.[\"error\"] || variantColorConfig.filled.error\n : \"bg-neutral-white border-error-500 hover:border-error-600 text-error-600 dark:bg-neutral-900 dark:border-error-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\";\n }\n\n const boxClasses = [\n \"inline-flex items-center justify-center shrink-0 border rounded-full transition-all duration-150 select-none\",\n currentSize.box,\n boxVariantStyles,\n !disabled && !isReadOnly && !isLoading ? \"active:scale-95\" : \"\",\n boxClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const labelClasses = [\n \"select-none font-medium text-neutral-900 dark:text-neutral-100 transition-colors\",\n currentSize.label,\n disabled ? \"opacity-60\" : \"\",\n labelClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const wrapperClasses = [\n \"group inline-flex relative\",\n labelPlacement === \"left\" ? \"flex-row-reverse justify-between\" : \"flex-row\",\n currentSize.gap,\n disabled ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer\",\n wrapperClassName,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const renderDot = () => {\n if (isLoading) {\n return (\n <span\n className={`inline-flex items-center justify-center animate-in zoom-in-75 duration-100 ${currentSize.dot}`}\n aria-hidden=\"true\"\n >\n <Spinner className=\"size-full animate-spin\" />\n </span>\n );\n }\n if (isChecked) {\n return (\n <span\n className={`inline-flex items-center justify-center animate-in zoom-in-75 duration-100 ${currentSize.dot}`}\n aria-hidden=\"true\"\n >\n {dotIcon || <RadioDotIcon className=\"size-full\" />}\n </span>\n );\n }\n return null;\n };\n\n const hasContent = Boolean(label);\n\n const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {\n if (disabled || isReadOnly || isLoading) {\n e.preventDefault();\n return;\n }\n props.onClick?.(e);\n };\n\n const handleWrapperClick = (e: React.MouseEvent<HTMLLabelElement>) => {\n if (disabled || isReadOnly || isLoading) {\n e.preventDefault();\n }\n };\n\n return (\n <div className=\"inline-flex flex-col\">\n <label className={wrapperClasses} onClick={handleWrapperClick}>\n {/* Hidden native input for keyboard access and screen readers */}\n <input\n ref={innerRef}\n type=\"radio\"\n id={id}\n name={name}\n value={value}\n checked={isChecked}\n disabled={disabled || isLoading}\n readOnly={isReadOnly}\n required={isRequired}\n aria-invalid={isInvalid}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={errorMessage || helperText ? helperId : undefined}\n onChange={handleChange}\n onClick={handleClick}\n className=\"sr-only peer\"\n {...props}\n />\n\n {/* Visual Box */}\n <span className={boxClasses} aria-hidden=\"true\">\n {renderDot()}\n </span>\n\n {/* Label */}\n {hasContent && (\n <span className={labelClasses}>\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n </label>\n\n {/* Helper text / Error message animation */}\n <HelperErrorText\n id={helperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n </div>\n );\n}\n","import { RadioSize, RadioVariant, RadioColor } from \"./types\";\n\nexport const sizeConfig: Record<\n RadioSize,\n {\n box: string;\n dot: string;\n label: string;\n gap: string;\n helper: string;\n }\n> = {\n xs: {\n box: \"size-3.5\",\n dot: \"size-1.5\",\n label: \"text-xs leading-4\",\n gap: \"gap-1.5\",\n helper: \"text-[10px]\",\n },\n sm: {\n box: \"size-4\",\n dot: \"size-2\",\n label: \"text-sm leading-4\",\n gap: \"gap-2\",\n helper: \"text-[11px]\",\n },\n md: {\n box: \"size-5\",\n dot: \"size-2.5\",\n label: \"text-sm leading-5\",\n gap: \"gap-2.5\",\n helper: \"text-xs\",\n },\n lg: {\n box: \"size-6\",\n dot: \"size-3\",\n label: \"text-base leading-6\",\n gap: \"gap-3\",\n helper: \"text-xs\",\n },\n xl: {\n box: \"size-7\",\n dot: \"size-3.5\",\n label: \"text-lg leading-7\",\n gap: \"gap-3.5\",\n helper: \"text-sm\",\n },\n};\n\nexport const variantColorConfig: Record<Exclude<RadioVariant, \"other\">, Record<RadioColor, string>> = {\n filled: {\n primary:\n \"bg-primary-600 text-neutral-white border-primary-600 dark:bg-primary-500 dark:border-primary-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\",\n secondary:\n \"bg-secondary-600 text-neutral-white border-secondary-600 dark:bg-secondary-500 dark:border-secondary-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400 peer-focus-visible:border-secondary-500\",\n error:\n \"bg-error-600 text-neutral-white border-error-600 dark:bg-error-500 dark:border-error-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\",\n success:\n \"bg-success-600 text-neutral-white border-success-600 dark:bg-success-500 dark:border-success-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400 peer-focus-visible:border-success-500\",\n warning:\n \"bg-warning-500 text-neutral-950 border-warning-500 dark:bg-warning-400 dark:border-warning-400 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400 peer-focus-visible:border-warning-500\",\n info: \"bg-info-600 text-neutral-white border-info-600 dark:bg-info-500 dark:border-info-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400 peer-focus-visible:border-info-500\",\n neutral:\n \"bg-neutral-800 text-neutral-white border-neutral-800 dark:bg-neutral-200 dark:text-neutral-900 dark:border-neutral-200 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400 peer-focus-visible:border-neutral-500\",\n },\n outline: {\n primary:\n \"bg-transparent text-primary-600 border-2 border-primary-600 hover:bg-primary-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\",\n secondary:\n \"bg-transparent text-secondary-600 border-2 border-secondary-600 hover:bg-secondary-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400 peer-focus-visible:border-secondary-500\",\n error:\n \"bg-transparent text-error-600 border-2 border-error-600 hover:bg-error-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\",\n success:\n \"bg-transparent text-success-600 border-2 border-success-600 hover:bg-success-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400 peer-focus-visible:border-success-500\",\n warning:\n \"bg-transparent text-warning-700 border-2 border-warning-500 hover:bg-warning-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400 peer-focus-visible:border-warning-500\",\n info: \"bg-transparent text-info-600 border-2 border-info-600 hover:bg-info-50/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400 peer-focus-visible:border-info-500\",\n neutral:\n \"bg-transparent text-neutral-800 border-2 border-neutral-800 hover:bg-neutral-100/50 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400 peer-focus-visible:border-neutral-500\",\n },\n soft: {\n primary:\n \"bg-primary-100 text-primary-800 border-primary-300 hover:bg-primary-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400 peer-focus-visible:border-primary-500\",\n secondary:\n \"bg-secondary-100 text-secondary-800 border-secondary-300 hover:bg-secondary-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400 peer-focus-visible:border-secondary-500\",\n error:\n \"bg-error-100 text-error-800 border-error-300 hover:bg-error-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400 peer-focus-visible:border-error-500\",\n success:\n \"bg-success-100 text-success-800 border-success-300 hover:bg-success-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400 peer-focus-visible:border-success-500\",\n warning:\n \"bg-warning-100 text-warning-900 border-warning-300 hover:bg-warning-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400 peer-focus-visible:border-warning-500\",\n info: \"bg-info-100 text-info-800 border-info-300 hover:bg-info-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400 peer-focus-visible:border-info-500\",\n neutral:\n \"bg-neutral-100 text-neutral-800 border-neutral-300 hover:bg-neutral-200/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400 peer-focus-visible:border-neutral-500\",\n },\n};\n","import { createContext, useContext } from \"react\";\nimport { RadioColor, RadioLabelPlacement, RadioSize, RadioVariant } from \"./types\";\n\nexport interface RadioGroupContextValue {\n name: string;\n value?: string | null;\n onChange?: (val: string | null) => void;\n size?: RadioSize;\n color?: RadioColor;\n variant?: RadioVariant;\n disabled?: boolean;\n isReadOnly?: boolean;\n isLoading?: boolean;\n isInvalid?: boolean;\n isRequired?: boolean;\n labelPlacement?: RadioLabelPlacement;\n}\n\nexport const RadioGroupContext = createContext<RadioGroupContextValue | undefined>(undefined);\n\nexport const useRadioGroupContext = () => useContext(RadioGroupContext);\n","export default function RadioDotIcon({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 10 10\" className={className} fill=\"currentColor\" aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"5\" r=\"5\" />\n </svg>\n );\n}\n","import { useState, useId, useMemo, useCallback } from \"react\";\nimport { RadioGroupProps } from \"./types\";\nimport { RadioGroupContext } from \"./context\";\nimport { sizeConfig } from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\n\nexport default function RadioGroup({\n value: valueProp,\n defaultValue,\n onChange,\n size = \"md\",\n color = \"primary\",\n variant = \"filled\",\n disabled = false,\n isReadOnly = false,\n isLoading = false,\n isInvalid: isInvalidProp,\n isRequired = false,\n label,\n helperText,\n errorMessage,\n orientation = \"vertical\",\n labelPlacement = \"right\",\n className = \"\",\n wrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n children,\n ref,\n ...props\n}: RadioGroupProps) {\n const generatedId = useId();\n const labelId = `${generatedId}-label`;\n const helperId = `${generatedId}-helper`;\n const groupName = useId();\n\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = useState<string | null>(defaultValue ?? null);\n\n const currentValue = isControlled ? valueProp : internalValue;\n const isInvalid = Boolean(isInvalidProp ?? (errorMessage ? true : false));\n\n const handleRadioChange = useCallback(\n (val: string | null) => {\n if (disabled || isReadOnly || isLoading) return;\n\n if (!isControlled) {\n setInternalValue(val);\n }\n onChange?.(val);\n },\n [disabled, isReadOnly, isLoading, isControlled, onChange]\n );\n\n const contextValue = useMemo(\n () => ({\n name: groupName,\n value: currentValue,\n onChange: handleRadioChange,\n size,\n color,\n variant,\n disabled,\n isReadOnly,\n isLoading,\n isInvalid,\n isRequired,\n labelPlacement,\n }),\n [\n groupName,\n currentValue,\n handleRadioChange,\n size,\n color,\n variant,\n disabled,\n isReadOnly,\n isLoading,\n isInvalid,\n isRequired,\n labelPlacement,\n ]\n );\n\n const orientationClasses =\n orientation === \"horizontal\" ? \"flex flex-row flex-wrap gap-4 items-center\" : \"flex flex-col gap-2.5\";\n\n const groupLabelClasses = [\n \"text-sm font-semibold text-neutral-900 dark:text-neutral-100 mb-1.5 select-none\",\n disabled ? \"opacity-60\" : \"\",\n labelClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const currentSize = sizeConfig[size] || sizeConfig.md;\n\n return (\n <div\n ref={ref}\n role=\"radiogroup\"\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={errorMessage || helperText ? helperId : undefined}\n aria-errormessage={errorMessage ? helperId : undefined}\n aria-orientation={orientation}\n aria-required={isRequired ? \"true\" : undefined}\n aria-invalid={isInvalid ? \"true\" : undefined}\n aria-disabled={disabled ? \"true\" : undefined}\n aria-readonly={isReadOnly ? \"true\" : undefined}\n aria-busy={isLoading ? \"true\" : undefined}\n className={`inline-flex flex-col ${wrapperClassName}`}\n {...props}\n >\n {label && (\n <span id={labelId} className={groupLabelClasses}>\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n\n <div className={`${orientationClasses} ${className}`}>\n <RadioGroupContext.Provider value={contextValue}>{children}</RadioGroupContext.Provider>\n </div>\n\n {/* Helper / Error animated text */}\n <HelperErrorText\n id={helperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n </div>\n );\n}\n","import { useId, useState, useRef, ChangeEvent, MouseEvent } from \"react\";\nimport { useMergeRefs } from \"@floating-ui/react\";\nimport { ToggleProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig } from \"./constants\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function Toggle({\n size,\n variant,\n color,\n radius,\n thumbRadius,\n config,\n label,\n helperText,\n errorMessage,\n labelPlacement = \"right\",\n thumbIcon,\n startContent,\n endContent,\n wrapperClassName = \"\",\n trackClassName = \"\",\n thumbClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n className = \"\",\n checked: checkedProp,\n defaultChecked,\n disabled = false,\n readOnly = false,\n onChange,\n onClick,\n value,\n id,\n name,\n ref,\n ...props\n}: ToggleProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n } = config ?? {};\n\n const generatedId = useId();\n const toggleId = id || generatedId;\n const errorHelperId = `${toggleId}-error-helper`;\n\n const internalRef = useRef<HTMLInputElement | null>(null);\n const mergedRef = useMergeRefs([internalRef, ref]);\n\n const isControlled = checkedProp !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const isChecked = isControlled ? Boolean(checkedProp) : internalChecked;\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (!isControlled) {\n setInternalChecked(e.target.checked);\n }\n onChange?.(e);\n };\n\n const handleClick = (e: MouseEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) {\n e.preventDefault();\n return;\n }\n onClick?.(e);\n };\n\n const handleWrapperClick = (e: MouseEvent<HTMLLabelElement>) => {\n if (disabled || readOnly || isLoading) {\n e.preventDefault();\n }\n };\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const trackRadiusClass = getSafeConfig(radius, radiusConfig, \"full\");\n const thumbRadiusClass = getSafeConfig(thumbRadius, radiusConfig, \"full\");\n\n const variantStyles =\n variant === \"other\"\n ? undefined\n : getSafeConfig(activeColor, getSafeConfig(variant, variantColorConfig, \"filled\"), \"primary\");\n\n const trackStyles = variantStyles ? (isChecked ? variantStyles.checked.track : variantStyles.unchecked.track) : \"\";\n const thumbStyles = variantStyles ? (isChecked ? variantStyles.checked.thumb : variantStyles.unchecked.thumb) : \"\";\n\n const trackClasses = [\n \"relative inline-flex items-center shrink-0 border box-border transition-colors duration-200 ease-in-out cursor-pointer select-none\",\n currentSize.track,\n trackRadiusClass,\n trackStyles,\n disabled ? \"opacity-50\" : \"\",\n trackClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const thumbClasses = [\n \"pointer-events-none inline-flex items-center justify-center transition-transform duration-200 ease-in-out select-none\",\n currentSize.thumb,\n thumbRadiusClass,\n thumbStyles,\n isChecked ? currentSize.translate : \"translate-x-0\",\n thumbClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const labelClasses = [\n \"select-none font-medium text-neutral-900 dark:text-neutral-100 transition-colors\",\n currentSize.label,\n disabled ? \"opacity-50\" : \"\",\n labelClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const isHorizontalReverse = labelPlacement === \"left\";\n\n const wrapperClasses = [\n \"group inline-flex items-center relative\",\n isHorizontalReverse ? \"flex-row-reverse justify-between\" : \"flex-row\",\n currentSize.gap,\n disabled ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer\",\n wrapperClassName,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const renderThumbIcon = () => {\n if (isLoading && showSpinner) {\n return (\n <span className={`inline-flex items-center justify-center ${currentSize.icon}`} aria-hidden=\"true\">\n <Spinner className=\"size-full animate-spin\" />\n </span>\n );\n }\n\n if (typeof thumbIcon === \"function\") {\n return thumbIcon({\n isChecked,\n className: currentSize.icon,\n });\n }\n\n if (thumbIcon) {\n return (\n <span className={`inline-flex items-center justify-center ${currentSize.icon}`} aria-hidden=\"true\">\n {thumbIcon}\n </span>\n );\n }\n\n return null;\n };\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n return (\n <span className={labelClasses}>\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n );\n };\n\n return (\n <div className=\"inline-flex flex-col\">\n <label className={wrapperClasses} onClick={handleWrapperClick}>\n {/* Hidden native input for A11y & Form Submission */}\n <input\n ref={mergedRef}\n type=\"checkbox\"\n role=\"switch\"\n id={toggleId}\n name={name}\n value={value}\n checked={isChecked}\n onChange={handleChange}\n onClick={handleClick}\n disabled={disabled || isLoading}\n readOnly={readOnly}\n required={isRequired}\n aria-checked={isChecked}\n aria-invalid={hasError}\n aria-required={isRequired}\n aria-describedby={errorMessage || helperText ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n className=\"sr-only peer\"\n {...props}\n />\n\n {/* Visual Track */}\n <span className={trackClasses} aria-hidden=\"true\">\n {/* Start Content (Left side, typically visible when checked) */}\n {startContent && (\n <span\n className={`absolute left-1.5 inline-flex items-center justify-center select-none font-medium transition-opacity duration-200 ${\n currentSize.content\n } ${isChecked ? \"opacity-100\" : \"opacity-0\"}`}\n >\n {startContent}\n </span>\n )}\n\n {/* Thumb */}\n <span className={thumbClasses}>{renderThumbIcon()}</span>\n\n {/* End Content (Right side, typically visible when unchecked) */}\n {endContent && (\n <span\n className={`absolute right-1.5 inline-flex items-center justify-center select-none font-medium transition-opacity duration-200 ${\n currentSize.content\n } ${!isChecked ? \"opacity-100\" : \"opacity-0\"}`}\n >\n {endContent}\n </span>\n )}\n </span>\n\n {/* Label */}\n {renderLabel()}\n </label>\n\n {/* Helper / Error Text */}\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n </div>\n );\n}\n","import { ToggleSize, ToggleVariant, ToggleColor, ToggleRadius } from \"./types\";\n\nexport const sizeConfig: Record<\n ToggleSize,\n {\n track: string;\n thumb: string;\n translate: string;\n icon: string;\n content: string;\n label: string;\n gap: string;\n helper: string;\n }\n> = {\n xs: {\n track: \"w-7 h-4 p-0.5\",\n thumb: \"size-3\",\n translate: \"translate-x-3\",\n icon: \"size-2\",\n content: \"text-[9px]\",\n label: \"text-xs leading-4\",\n gap: \"gap-1.5\",\n helper: \"text-[10px]\",\n },\n sm: {\n track: \"w-9 h-5 p-0.5\",\n thumb: \"size-4\",\n translate: \"translate-x-4\",\n icon: \"size-2.5\",\n content: \"text-[10px]\",\n label: \"text-sm leading-4\",\n gap: \"gap-2\",\n helper: \"text-[11px]\",\n },\n md: {\n track: \"w-11 h-6 p-0.5\",\n thumb: \"size-5\",\n translate: \"translate-x-5\",\n icon: \"size-3\",\n content: \"text-xs\",\n label: \"text-sm leading-5\",\n gap: \"gap-2.5\",\n helper: \"text-xs\",\n },\n lg: {\n track: \"w-13 h-7 p-0.5\",\n thumb: \"size-6\",\n translate: \"translate-x-6\",\n icon: \"size-3.5\",\n content: \"text-xs\",\n label: \"text-base leading-6\",\n gap: \"gap-3\",\n helper: \"text-xs\",\n },\n xl: {\n track: \"w-16 h-9 p-1\",\n thumb: \"size-7\",\n translate: \"translate-x-7\",\n icon: \"size-4\",\n content: \"text-sm\",\n label: \"text-lg leading-7\",\n gap: \"gap-3.5\",\n helper: \"text-sm\",\n },\n};\n\nexport const radiusConfig: Record<ToggleRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport interface TrackThumbStyles {\n track: string;\n thumb: string;\n}\n\nexport const variantColorConfig: Record<\n Exclude<ToggleVariant, \"other\">,\n Record<\n ToggleColor,\n {\n checked: TrackThumbStyles;\n unchecked: TrackThumbStyles;\n }\n >\n> = {\n filled: {\n primary: {\n checked: {\n track:\n \"bg-primary-600 dark:bg-primary-500 border-transparent peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400\",\n thumb: \"bg-neutral-white text-primary-600 dark:text-primary-500 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border-transparent hover:bg-neutral-300 dark:hover:bg-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400\",\n thumb: \"bg-neutral-white text-neutral-400 dark:bg-neutral-200 dark:text-neutral-600 shadow-sm\",\n },\n },\n secondary: {\n checked: {\n track:\n \"bg-secondary-600 dark:bg-secondary-500 border-transparent peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400\",\n thumb: \"bg-neutral-white text-secondary-600 dark:text-secondary-500 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border-transparent hover:bg-neutral-300 dark:hover:bg-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400\",\n thumb: \"bg-neutral-white text-neutral-400 dark:bg-neutral-200 dark:text-neutral-600 shadow-sm\",\n },\n },\n error: {\n checked: {\n track:\n \"bg-error-600 dark:bg-error-500 border-transparent peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400\",\n thumb: \"bg-neutral-white text-error-600 dark:text-error-500 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border-transparent hover:bg-neutral-300 dark:hover:bg-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400\",\n thumb: \"bg-neutral-white text-neutral-400 dark:bg-neutral-200 dark:text-neutral-600 shadow-sm\",\n },\n },\n success: {\n checked: {\n track:\n \"bg-success-600 dark:bg-success-500 border-transparent peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400\",\n thumb: \"bg-neutral-white text-success-600 dark:text-success-500 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border-transparent hover:bg-neutral-300 dark:hover:bg-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400\",\n thumb: \"bg-neutral-white text-neutral-400 dark:bg-neutral-200 dark:text-neutral-600 shadow-sm\",\n },\n },\n warning: {\n checked: {\n track:\n \"bg-warning-500 dark:bg-warning-400 border-transparent peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400\",\n thumb: \"bg-neutral-white text-warning-500 dark:bg-neutral-900 dark:text-warning-400 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border-transparent hover:bg-neutral-300 dark:hover:bg-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400\",\n thumb: \"bg-neutral-white text-neutral-400 dark:bg-neutral-200 dark:text-neutral-600 shadow-sm\",\n },\n },\n info: {\n checked: {\n track:\n \"bg-info-600 dark:bg-info-500 border-transparent peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400\",\n thumb: \"bg-neutral-white text-info-600 dark:text-info-500 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border-transparent hover:bg-neutral-300 dark:hover:bg-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400\",\n thumb: \"bg-neutral-white text-neutral-400 dark:bg-neutral-200 dark:text-neutral-600 shadow-sm\",\n },\n },\n neutral: {\n checked: {\n track:\n \"bg-neutral-800 dark:bg-neutral-200 border-transparent peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400\",\n thumb: \"bg-neutral-white text-neutral-800 dark:bg-neutral-900 dark:text-neutral-200 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border-transparent hover:bg-neutral-300 dark:hover:bg-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400\",\n thumb: \"bg-neutral-white text-neutral-400 dark:bg-neutral-200 dark:text-neutral-600 shadow-sm\",\n },\n },\n },\n outline: {\n primary: {\n checked: {\n track:\n \"bg-primary-50 dark:bg-primary-950/40 border-2 border-primary-600 dark:border-primary-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400\",\n thumb: \"bg-primary-600 dark:bg-primary-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-transparent border-2 border-neutral-300 dark:border-neutral-600 hover:border-neutral-400 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400\",\n thumb: \"bg-neutral-400 dark:bg-neutral-500 text-neutral-white shadow-sm\",\n },\n },\n secondary: {\n checked: {\n track:\n \"bg-secondary-50 dark:bg-secondary-950/40 border-2 border-secondary-600 dark:border-secondary-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400\",\n thumb: \"bg-secondary-600 dark:bg-secondary-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-transparent border-2 border-neutral-300 dark:border-neutral-600 hover:border-neutral-400 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400\",\n thumb: \"bg-neutral-400 dark:bg-neutral-500 text-neutral-white shadow-sm\",\n },\n },\n error: {\n checked: {\n track:\n \"bg-error-50 dark:bg-error-950/40 border-2 border-error-600 dark:border-error-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400\",\n thumb: \"bg-error-600 dark:bg-error-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-transparent border-2 border-neutral-300 dark:border-neutral-600 hover:border-neutral-400 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400\",\n thumb: \"bg-neutral-400 dark:bg-neutral-500 text-neutral-white shadow-sm\",\n },\n },\n success: {\n checked: {\n track:\n \"bg-success-50 dark:bg-success-950/40 border-2 border-success-600 dark:border-success-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400\",\n thumb: \"bg-success-600 dark:bg-success-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-transparent border-2 border-neutral-300 dark:border-neutral-600 hover:border-neutral-400 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400\",\n thumb: \"bg-neutral-400 dark:bg-neutral-500 text-neutral-white shadow-sm\",\n },\n },\n warning: {\n checked: {\n track:\n \"bg-warning-50 dark:bg-warning-950/40 border-2 border-warning-500 dark:border-warning-400 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400\",\n thumb: \"bg-warning-500 dark:bg-warning-400 text-neutral-950 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-transparent border-2 border-neutral-300 dark:border-neutral-600 hover:border-neutral-400 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400\",\n thumb: \"bg-neutral-400 dark:bg-neutral-500 text-neutral-white shadow-sm\",\n },\n },\n info: {\n checked: {\n track:\n \"bg-info-50 dark:bg-info-950/40 border-2 border-info-600 dark:border-info-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400\",\n thumb: \"bg-info-600 dark:bg-info-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-transparent border-2 border-neutral-300 dark:border-neutral-600 hover:border-neutral-400 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400\",\n thumb: \"bg-neutral-400 dark:bg-neutral-500 text-neutral-white shadow-sm\",\n },\n },\n neutral: {\n checked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border-2 border-neutral-800 dark:border-neutral-200 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400\",\n thumb: \"bg-neutral-800 dark:bg-neutral-200 text-neutral-white dark:text-neutral-900 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-transparent border-2 border-neutral-300 dark:border-neutral-600 hover:border-neutral-400 dark:hover:border-neutral-500 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400\",\n thumb: \"bg-neutral-400 dark:bg-neutral-500 text-neutral-white shadow-sm\",\n },\n },\n },\n soft: {\n primary: {\n checked: {\n track:\n \"bg-primary-100 dark:bg-primary-900/50 border border-primary-200 dark:border-primary-800 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400\",\n thumb: \"bg-primary-600 dark:bg-primary-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 hover:bg-neutral-200/70 dark:hover:bg-neutral-700/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary-400\",\n thumb: \"bg-neutral-white dark:bg-neutral-300 text-neutral-400 dark:text-neutral-600 shadow-sm\",\n },\n },\n secondary: {\n checked: {\n track:\n \"bg-secondary-100 dark:bg-secondary-900/50 border border-secondary-200 dark:border-secondary-800 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400\",\n thumb: \"bg-secondary-600 dark:bg-secondary-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 hover:bg-neutral-200/70 dark:hover:bg-neutral-700/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-secondary-400\",\n thumb: \"bg-neutral-white dark:bg-neutral-300 text-neutral-400 dark:text-neutral-600 shadow-sm\",\n },\n },\n error: {\n checked: {\n track:\n \"bg-error-100 dark:bg-error-900/50 border border-error-200 dark:border-error-800 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400\",\n thumb: \"bg-error-600 dark:bg-error-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 hover:bg-neutral-200/70 dark:hover:bg-neutral-700/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-error-400\",\n thumb: \"bg-neutral-white dark:bg-neutral-300 text-neutral-400 dark:text-neutral-600 shadow-sm\",\n },\n },\n success: {\n checked: {\n track:\n \"bg-success-100 dark:bg-success-900/50 border border-success-200 dark:border-success-800 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400\",\n thumb: \"bg-success-600 dark:bg-success-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 hover:bg-neutral-200/70 dark:hover:bg-neutral-700/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-success-400\",\n thumb: \"bg-neutral-white dark:bg-neutral-300 text-neutral-400 dark:text-neutral-600 shadow-sm\",\n },\n },\n warning: {\n checked: {\n track:\n \"bg-warning-100 dark:bg-warning-900/50 border border-warning-200 dark:border-warning-800 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400\",\n thumb: \"bg-warning-500 dark:bg-warning-400 text-neutral-950 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 hover:bg-neutral-200/70 dark:hover:bg-neutral-700/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-warning-400\",\n thumb: \"bg-neutral-white dark:bg-neutral-300 text-neutral-400 dark:text-neutral-600 shadow-sm\",\n },\n },\n info: {\n checked: {\n track:\n \"bg-info-100 dark:bg-info-900/50 border border-info-200 dark:border-info-800 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400\",\n thumb: \"bg-info-600 dark:bg-info-500 text-neutral-white shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 hover:bg-neutral-200/70 dark:hover:bg-neutral-700/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-info-400\",\n thumb: \"bg-neutral-white dark:bg-neutral-300 text-neutral-400 dark:text-neutral-600 shadow-sm\",\n },\n },\n neutral: {\n checked: {\n track:\n \"bg-neutral-200 dark:bg-neutral-700 border border-neutral-300 dark:border-neutral-600 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400\",\n thumb: \"bg-neutral-800 dark:bg-neutral-200 text-neutral-white dark:text-neutral-900 shadow-sm\",\n },\n unchecked: {\n track:\n \"bg-neutral-100 dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 hover:bg-neutral-200/70 dark:hover:bg-neutral-700/70 peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-neutral-400\",\n thumb: \"bg-neutral-white dark:bg-neutral-300 text-neutral-400 dark:text-neutral-600 shadow-sm\",\n },\n },\n },\n};\n","import type { SVGProps } from \"react\";\n\nexport default function ChevronDownIcon({\n width = 16,\n height = 16,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function ChevronLeftIcon({\n width = 16,\n height = 16,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function ChevronRightIcon({\n width = 16,\n height = 16,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function CalendarIcon({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M8 2v4\" />\n <path d=\"M16 2v4\" />\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\" />\n <path d=\"M3 10h18\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function ClockIcon({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12 6 12 12 16 14\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function DoubleChevronLeftIcon({\n width = 16,\n height = 16,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m11 17-5-5 5-5\" />\n <path d=\"m18 17-5-5 5-5\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function DoubleChevronRightIcon({\n width = 16,\n height = 16,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m6 17 5-5-5-5\" />\n <path d=\"m13 17 5-5-5-5\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport function EmptyDefaultIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 96 96\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className=\"size-full\" {...props}>\n {/* Ground Shadow */}\n <ellipse cx=\"48\" cy=\"80\" rx=\"36\" ry=\"8\" className=\"fill-neutral-200/60 dark:fill-neutral-800/60\" />\n <ellipse cx=\"48\" cy=\"80\" rx=\"22\" ry=\"4.5\" className=\"fill-neutral-300/50 dark:fill-neutral-700/50\" />\n\n {/* Back Flaps (Opening outward at a lower, gentle angle) */}\n {/* Back Left Flap */}\n <path\n d=\"M24 38L16 32L40 22L48 28L24 38Z\"\n className=\"fill-primary-100/80 dark:fill-primary-950/70 stroke-primary-300 dark:stroke-primary-700\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n />\n {/* Back Right Flap */}\n <path\n d=\"M72 38L80 32L56 22L48 28L72 38Z\"\n className=\"fill-primary-100/80 dark:fill-primary-950/70 stroke-primary-300 dark:stroke-primary-700\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n />\n\n {/* Hollow Interior (Inside back walls & bottom floor) */}\n {/* Inside Back-Left Wall */}\n <path\n d=\"M24 38L48 28V52L24 62V38Z\"\n className=\"fill-primary-300/80 dark:fill-primary-900/80 stroke-primary-300/40 dark:stroke-primary-700/40\"\n strokeWidth=\"1\"\n strokeLinejoin=\"round\"\n />\n {/* Inside Back-Right Wall */}\n <path\n d=\"M72 38L48 28V52L72 62V38Z\"\n className=\"fill-primary-300/60 dark:fill-primary-900/60 stroke-primary-300/40 dark:stroke-primary-700/40\"\n strokeWidth=\"1\"\n strokeLinejoin=\"round\"\n />\n {/* Inside Bottom Floor */}\n <path\n d=\"M48 52L72 62L48 72L24 62L48 52Z\"\n className=\"fill-primary-400/40 dark:fill-primary-950/90 stroke-primary-400/30 dark:stroke-primary-700/30\"\n strokeWidth=\"1\"\n strokeLinejoin=\"round\"\n />\n\n {/* Outer Front Shell (Left & Right Walls) */}\n {/* Outer Left Wall */}\n <path\n d=\"M24 38V64L48 76V50L24 38Z\"\n className=\"fill-primary-100 dark:fill-primary-900/50 stroke-primary-400 dark:stroke-primary-600\"\n strokeWidth=\"1.8\"\n strokeLinejoin=\"round\"\n />\n {/* Outer Right Wall */}\n <path\n d=\"M72 38V64L48 76V50L72 38Z\"\n className=\"fill-primary-200/90 dark:fill-primary-800/60 stroke-primary-400 dark:stroke-primary-600\"\n strokeWidth=\"1.8\"\n strokeLinejoin=\"round\"\n />\n\n {/* Front Flaps (Hanging downward) */}\n <path\n d=\"M24 38L48 50L38 60L14 48L24 38Z\"\n className=\"fill-primary-50 dark:fill-primary-950/90 stroke-primary-300 dark:stroke-primary-700\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M72 38L48 50L58 60L82 48L72 38Z\"\n className=\"fill-primary-100/90 dark:fill-primary-900/80 stroke-primary-300 dark:stroke-primary-700\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nexport default EmptyDefaultIcon;\n","import type { SVGProps } from \"react\";\n\nexport function EmptySearchIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 120 120\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className=\"size-full\" {...props}>\n {/* Base shadow */}\n <ellipse cx=\"60\" cy=\"100\" rx=\"42\" ry=\"10\" className=\"fill-neutral-200/50 dark:fill-neutral-800/50\" />\n\n {/* Sheet of paper */}\n <rect\n x=\"32\"\n y=\"24\"\n width=\"44\"\n height=\"56\"\n rx=\"6\"\n className=\"fill-white dark:fill-neutral-900 stroke-neutral-300 dark:stroke-neutral-700\"\n strokeWidth=\"2\"\n />\n {/* Paper lines */}\n <line\n x1=\"42\"\n y1=\"36\"\n x2=\"66\"\n y2=\"36\"\n className=\"stroke-neutral-200 dark:stroke-neutral-700\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n <line\n x1=\"42\"\n y1=\"44\"\n x2=\"60\"\n y2=\"44\"\n className=\"stroke-neutral-200 dark:stroke-neutral-700\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n <line\n x1=\"42\"\n y1=\"52\"\n x2=\"52\"\n y2=\"52\"\n className=\"stroke-neutral-200 dark:stroke-neutral-700\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n\n {/* Magnifying Glass */}\n <g transform=\"translate(48, 38)\">\n {/* Glass lens */}\n <circle\n cx=\"28\"\n cy=\"28\"\n r=\"20\"\n className=\"fill-primary-50/80 dark:fill-primary-950/70 stroke-primary-500\"\n strokeWidth=\"3\"\n />\n {/* Glass glare */}\n <path d=\"M18 20A14 14 0 0 1 34 16\" className=\"stroke-primary-300\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n {/* Question mark / cross inside glass */}\n <path\n d=\"M24 24L32 32M32 24L24 32\"\n className=\"stroke-neutral-400 dark:stroke-neutral-500\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n {/* Handle */}\n <path\n d=\"M42 42L58 58\"\n className=\"stroke-primary-700 dark:stroke-primary-400\"\n strokeWidth=\"5\"\n strokeLinecap=\"round\"\n />\n </g>\n </svg>\n );\n}\n\nexport default EmptySearchIcon;\n","import type { SVGProps } from \"react\";\n\nexport function EmptyErrorIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 120 120\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className=\"size-full\" {...props}>\n <ellipse cx=\"60\" cy=\"100\" rx=\"42\" ry=\"10\" className=\"fill-neutral-200/50 dark:fill-neutral-800/50\" />\n\n {/* Cloud / Network error container */}\n <circle\n cx=\"60\"\n cy=\"52\"\n r=\"32\"\n className=\"fill-error-50 dark:fill-error-950/40 stroke-error-200 dark:stroke-error-800\"\n strokeWidth=\"2\"\n />\n\n {/* Triangle alert */}\n <path\n d=\"M60 30L78 64H42L60 30Z\"\n className=\"fill-error-100 dark:fill-error-900/60 stroke-error-500\"\n strokeWidth=\"2.5\"\n strokeLinejoin=\"round\"\n />\n {/* Exclamation mark */}\n <line x1=\"60\" y1=\"42\" x2=\"60\" y2=\"52\" className=\"stroke-error-600\" strokeWidth=\"2.5\" strokeLinecap=\"round\" />\n <circle cx=\"60\" cy=\"58\" r=\"1.5\" className=\"fill-error-600\" />\n\n {/* Disconnect lines */}\n <path\n d=\"M22 66L32 60\"\n className=\"stroke-neutral-300 dark:stroke-neutral-700\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeDasharray=\"3 3\"\n />\n <path\n d=\"M98 66L88 60\"\n className=\"stroke-neutral-300 dark:stroke-neutral-700\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeDasharray=\"3 3\"\n />\n </svg>\n );\n}\n\nexport default EmptyErrorIcon;\n","import type { SVGProps } from \"react\";\n\nexport function EmptyFolderIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 120 120\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className=\"size-full\" {...props}>\n <ellipse cx=\"60\" cy=\"98\" rx=\"42\" ry=\"10\" className=\"fill-neutral-200/50 dark:fill-neutral-800/50\" />\n\n {/* Folder Back */}\n <path\n d=\"M24 40C24 36.69 26.69 34 30 34H48L56 42H90C93.31 42 96 44.69 96 48V78C96 81.31 93.31 84 90 84H30C26.69 84 24 81.31 24 78V40Z\"\n className=\"fill-primary-200/70 dark:fill-primary-900/60 stroke-primary-300 dark:stroke-primary-700\"\n strokeWidth=\"2\"\n />\n\n {/* Empty paper inside */}\n <rect\n x=\"36\"\n y=\"30\"\n width=\"48\"\n height=\"40\"\n rx=\"4\"\n className=\"fill-white dark:fill-neutral-900 stroke-neutral-200 dark:stroke-neutral-700\"\n strokeWidth=\"1.5\"\n />\n <line\n x1=\"44\"\n y1=\"40\"\n x2=\"68\"\n y2=\"40\"\n className=\"stroke-neutral-200 dark:stroke-neutral-700\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <line\n x1=\"44\"\n y1=\"48\"\n x2=\"60\"\n y2=\"48\"\n className=\"stroke-neutral-200 dark:stroke-neutral-700\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n\n {/* Folder Front */}\n <path\n d=\"M24 52H96V80C96 83.31 93.31 86 90 86H30C26.69 86 24 83.31 24 80V52Z\"\n className=\"fill-primary-300/80 dark:fill-primary-800/70 stroke-primary-400 dark:stroke-primary-600\"\n strokeWidth=\"2\"\n />\n </svg>\n );\n}\n\nexport default EmptyFolderIcon;\n","import type { SVGProps } from \"react\";\n\nexport function EmptySimpleIcon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className=\"size-full\" {...props}>\n <ellipse cx=\"32\" cy=\"54\" rx=\"24\" ry=\"5\" className=\"fill-neutral-200/50 dark:fill-neutral-800/50\" />\n <path\n d=\"M12 24L32 14L52 24L32 34L12 24Z\"\n className=\"fill-neutral-100 dark:fill-neutral-800 stroke-neutral-400 dark:stroke-neutral-500\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M12 24V40L32 50V34L12 24Z\"\n className=\"fill-neutral-200 dark:fill-neutral-700 stroke-neutral-400 dark:stroke-neutral-500\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M52 24V40L32 50V34L52 24Z\"\n className=\"fill-neutral-300 dark:fill-neutral-600 stroke-neutral-400 dark:stroke-neutral-500\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nexport default EmptySimpleIcon;\n","import type { SVGProps } from \"react\";\n\nexport default function InfoCircleIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function CheckCircleIcon({\n width = 20,\n height = 20,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m9 12 2 2 4-4\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function AlertTriangleIcon({\n width = 20,\n height = 20,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function AlertCircleIcon({\n width = 20,\n height = 20,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function ZoomInIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n <line x1=\"11\" y1=\"8\" x2=\"11\" y2=\"14\" />\n <line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function ZoomOutIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n <line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function RotateCwIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M21 2v6h-6\" />\n <path d=\"M21 8A10 10 0 1 0 22 13\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function RotateCcwIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M3 2v6h6\" />\n <path d=\"M3 8a10 10 0 1 1-1 5\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function FlipHorizontalIcon({\n width = 20,\n height = 20,\n className = \"\",\n ...props\n}: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m3 7 5 5-5 5V7z\" />\n <path d=\"m21 7-5 5 5 5V7z\" />\n <path d=\"M12 20v2\" />\n <path d=\"M12 14v2\" />\n <path d=\"M12 8v2\" />\n <path d=\"M12 2v2\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function DownloadIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function ResetIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function ImageIcon({ width = 20, height = 20, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function CropIcon({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M6 2v14a2 2 0 0 0 2 2h14\" />\n <path d=\"M18 22V8a2 2 0 0 0-2-2H2\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport function SearchIcon({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" x2=\"16.65\" y1=\"21\" y2=\"16.65\" />\n </svg>\n );\n}\n\nexport default SearchIcon;\n","import type { SVGProps } from \"react\";\n\nexport default function TrashIcon({ width = 16, height = 16, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n <line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\" />\n <line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\" />\n </svg>\n );\n}\n","import type { SVGProps } from \"react\";\n\nexport default function UploadIcon({ width = 24, height = 24, className = \"\", ...props }: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={width}\n height={height}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className={className}\n {...props}\n >\n <path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96M19 18H6c-2.21 0-4-1.79-4-4 0-2.05 1.53-3.76 3.56-3.97l1.07-.11.5-.95C8.08 7.14 9.94 6 12 6c2.62 0 4.88 1.86 5.39 4.43l.3 1.5 1.53.11c1.56.1 2.78 1.41 2.78 2.96 0 1.65-1.35 3-3 3M8 13h2.55v3h2.9v-3H16l-4-4z\" />\n </svg>\n );\n}\n","import React from \"react\";\nimport { AlertColor, AlertRadius, AlertSize, AlertVariant } from \"./types\";\nimport InfoCircleIcon from \"../icons/InfoCircleIcon\";\nimport CheckCircleIcon from \"../icons/CheckCircleIcon\";\nimport AlertTriangleIcon from \"../icons/AlertTriangleIcon\";\nimport AlertCircleIcon from \"../icons/AlertCircleIcon\";\n\n\nexport const sizeConfig: Record<\n AlertSize,\n {\n container: string;\n title: string;\n description: string;\n icon: string;\n closeButton: string;\n closeIcon: string;\n action: string;\n }\n> = {\n xs: {\n container: \"p-2 gap-2 text-xs\",\n title: \"text-xs font-semibold leading-tight\",\n description: \"text-[11px] leading-tight\",\n icon: \"size-3.5 mt-0.5\",\n closeButton: \"size-4 p-0.5 -mr-0.5\",\n closeIcon: \"size-3\",\n action: \"gap-1.5 text-xs\",\n },\n sm: {\n container: \"p-2.5 gap-2.5 text-xs\",\n title: \"text-sm font-semibold leading-tight\",\n description: \"text-xs leading-normal\",\n icon: \"size-4 mt-0.5\",\n closeButton: \"size-5 p-0.5 -mr-0.5\",\n closeIcon: \"size-3.5\",\n action: \"gap-1.5 text-xs\",\n },\n md: {\n container: \"p-3.5 gap-3 text-sm\",\n title: \"text-sm font-semibold leading-tight\",\n description: \"text-sm leading-normal\",\n icon: \"size-5 mt-0.5\",\n closeButton: \"size-6 p-1 -mr-1\",\n closeIcon: \"size-4\",\n action: \"gap-2 text-sm\",\n },\n lg: {\n container: \"p-4 gap-3.5 text-base\",\n title: \"text-base font-semibold leading-snug\",\n description: \"text-sm leading-normal\",\n icon: \"size-6 mt-0.5\",\n closeButton: \"size-7 p-1.5 -mr-1.5\",\n closeIcon: \"size-4.5\",\n action: \"gap-2.5 text-sm\",\n },\n xl: {\n container: \"p-5 gap-4 text-lg\",\n title: \"text-lg font-semibold leading-snug\",\n description: \"text-base leading-normal\",\n icon: \"size-7 mt-0.5\",\n closeButton: \"size-8 p-1.5 -mr-1.5\",\n closeIcon: \"size-5\",\n action: \"gap-3 text-base\",\n },\n};\n\nexport const radiusConfig: Record<AlertRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-2xl\",\n};\n\nexport const variantColorConfig: Record<Exclude<AlertVariant, \"other\">, Record<AlertColor, string>> = {\n soft: {\n primary: \"bg-primary-50 text-primary-900 border-2 border-primary-200\",\n secondary: \"bg-secondary-50 text-secondary-900 border-2 border-secondary-200\",\n neutral: \"bg-neutral-100 text-neutral-900 border-2 border-neutral-200\",\n error: \"bg-error-50 text-error-900 border-2 border-error-200\",\n success: \"bg-success-50 text-success-900 border-2 border-success-200\",\n warning: \"bg-warning-50 text-warning-900 border-2 border-warning-200\",\n info: \"bg-info-50 text-info-900 border-2 border-info-200\",\n },\n filled: {\n primary: \"bg-primary-600 text-white border-2 border-primary-600\",\n secondary: \"bg-secondary-600 text-white border-2 border-secondary-600\",\n neutral: \"bg-neutral-700 text-white border-2 border-neutral-700\",\n error: \"bg-error-600 text-white border-2 border-error-600\",\n success: \"bg-success-600 text-white border-2 border-success-600\",\n warning: \"bg-warning-500 text-neutral-950 border-2 border-warning-500\",\n info: \"bg-info-600 text-white border-2 border-info-600\",\n },\n outline: {\n primary: \"bg-neutral-white text-primary-700 border-2 border-primary-400\",\n secondary: \"bg-neutral-white text-secondary-700 border-2 border-secondary-400\",\n neutral: \"bg-neutral-white text-neutral-700 border-2 border-neutral-300\",\n error: \"bg-neutral-white text-error-700 border-2 border-error-500\",\n success: \"bg-neutral-white text-success-700 border-2 border-success-400\",\n warning: \"bg-neutral-white text-warning-800 border-2 border-warning-400\",\n info: \"bg-neutral-white text-info-700 border-2 border-info-400\",\n },\n \"accent-left\": {\n primary: \"bg-primary-50/70 text-primary-900 border-2 border-primary-200 border-l-4 border-l-primary-500\",\n secondary: \"bg-secondary-50/70 text-secondary-900 border-2 border-secondary-200 border-l-4 border-l-secondary-500\",\n neutral: \"bg-neutral-50/70 text-neutral-900 border-2 border-neutral-200 border-l-4 border-l-neutral-500\",\n error: \"bg-error-50/70 text-error-900 border-2 border-error-200 border-l-4 border-l-error-500\",\n success: \"bg-success-50/70 text-success-900 border-2 border-success-200 border-l-4 border-l-success-500\",\n warning: \"bg-warning-50/70 text-warning-900 border-2 border-warning-200 border-l-4 border-l-warning-500\",\n info: \"bg-info-50/70 text-info-900 border-2 border-info-200 border-l-4 border-l-info-500\",\n },\n ghost: {\n primary: \"bg-transparent text-primary-800 border-2 border-transparent\",\n secondary: \"bg-transparent text-secondary-800 border-2 border-transparent\",\n neutral: \"bg-transparent text-neutral-800 border-2 border-transparent\",\n error: \"bg-transparent text-error-700 border-2 border-transparent\",\n success: \"bg-transparent text-success-700 border-2 border-transparent\",\n warning: \"bg-transparent text-warning-800 border-2 border-transparent\",\n info: \"bg-transparent text-info-800 border-2 border-transparent\",\n },\n};\n\nexport const iconColorConfig: Record<Exclude<AlertVariant, \"other\">, Record<AlertColor, string>> = {\n soft: {\n primary: \"text-primary-600\",\n secondary: \"text-secondary-600\",\n neutral: \"text-neutral-600\",\n error: \"text-error-600\",\n success: \"text-success-600\",\n warning: \"text-warning-600\",\n info: \"text-info-600\",\n },\n filled: {\n primary: \"text-white\",\n secondary: \"text-white\",\n neutral: \"text-white\",\n error: \"text-white\",\n success: \"text-white\",\n warning: \"text-neutral-950\",\n info: \"text-white\",\n },\n outline: {\n primary: \"text-primary-600\",\n secondary: \"text-secondary-600\",\n neutral: \"text-neutral-600\",\n error: \"text-error-600\",\n success: \"text-success-600\",\n warning: \"text-warning-600\",\n info: \"text-info-600\",\n },\n \"accent-left\": {\n primary: \"text-primary-600\",\n secondary: \"text-secondary-600\",\n neutral: \"text-neutral-600\",\n error: \"text-error-600\",\n success: \"text-success-600\",\n warning: \"text-warning-600\",\n info: \"text-info-600\",\n },\n ghost: {\n primary: \"text-primary-600\",\n secondary: \"text-secondary-600\",\n neutral: \"text-neutral-600\",\n error: \"text-error-600\",\n success: \"text-success-600\",\n warning: \"text-warning-600\",\n info: \"text-info-600\",\n },\n};\n\nexport const defaultIcons: Record<AlertColor, React.ComponentType<{ className?: string }>> = {\n primary: InfoCircleIcon,\n secondary: InfoCircleIcon,\n neutral: InfoCircleIcon,\n info: InfoCircleIcon,\n success: CheckCircleIcon,\n warning: AlertTriangleIcon,\n error: AlertCircleIcon,\n};","import { MouseEvent } from \"react\";\nimport { AlertProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig, iconColorConfig, defaultIcons } from \"./constants\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function Alert({\n size,\n variant,\n color,\n radius,\n title,\n description,\n icon = true,\n action,\n closable = true,\n onClose,\n closeAriaLabel = \"Đóng cảnh báo\",\n banner = false,\n titleClassName = \"\",\n descriptionClassName = \"\",\n actionClassName = \"\",\n iconClassName = \"\",\n closeButtonClassName = \"\",\n className = \"\",\n children,\n role,\n ref,\n ...props\n}: AlertProps) {\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n const roundedClass = banner ? \"rounded-none border-x-0 w-full\" : getSafeConfig(radius, radiusConfig, \"lg\");\n\n const variantStyles = variant === \"other\" ? \"\" : getSafeConfig(color, getSafeConfig(variant, variantColorConfig, \"soft\"), \"info\");\n\n const iconColorStyle = variant === \"other\" ? \"\" : getSafeConfig(color, getSafeConfig(variant, iconColorConfig, \"soft\"), \"info\");\n\n const isClosable = closable || Boolean(onClose);\n\n const handleClose = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n onClose?.();\n };\n\n const defaultRole = color === \"error\" || color === \"warning\" ? \"alert\" : \"status\";\n const activeRole = role || defaultRole;\n const ariaLive = color === \"error\" || color === \"warning\" ? \"assertive\" : \"polite\";\n\n const bodyContent = description ?? children;\n const hasBody = Boolean(bodyContent);\n\n const renderIcon = () => {\n if (icon === false) return null;\n\n if (icon !== true && icon !== undefined) {\n return (\n <span\n className={`inline-flex items-center justify-center shrink-0 leading-none ${currentSize.icon} ${iconClassName}`}\n aria-hidden=\"true\"\n >\n {icon}\n </span>\n );\n }\n\n const IconComponent = getSafeConfig(color, defaultIcons, \"info\");\n return (\n <span\n className={`inline-flex items-center justify-center shrink-0 leading-none ${currentSize.icon} ${iconColorStyle} ${iconClassName}`}\n aria-hidden=\"true\"\n >\n <IconComponent className=\"size-full\" />\n </span>\n );\n };\n\n const containerClasses = [\n \"relative flex w-full\",\n currentSize.container,\n roundedClass,\n variantStyles,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div ref={ref} role={activeRole} aria-live={ariaLive} className={containerClasses} {...props}>\n {renderIcon()}\n\n <div className=\"flex-1 min-w-0 flex flex-col justify-center\">\n {title && <div className={`${currentSize.title} ${titleClassName}`}>{title}</div>}\n {hasBody && (\n <div className={`${currentSize.description} ${title ? \"mt-0.5\" : \"\"} ${descriptionClassName}`}>\n {bodyContent}\n </div>\n )}\n </div>\n\n {action && (\n <div className={`inline-flex items-center shrink-0 ${currentSize.action} ${actionClassName}`}>{action}</div>\n )}\n\n {isClosable && (\n <button\n type=\"button\"\n onClick={handleClose}\n aria-label={closeAriaLabel}\n className={`inline-flex items-center justify-center shrink-0 rounded-md transition-colors cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-current opacity-70 hover:opacity-100 ${\n variant === \"filled\" ? \"hover:bg-white/20 active:bg-white/30\" : \"hover:bg-black/5 active:bg-black/10\"\n } ${currentSize.closeButton} ${closeButtonClassName}`}\n >\n <CloseIcon className={currentSize.closeIcon} />\n </button>\n )}\n </div>\n );\n}\n","import { Toaster as SonnerToaster } from \"sonner\";\nimport { ToasterProps } from \"./types\";\nimport { DEFAULT_TOAST_DURATION } from \"./constants\";\n\nexport default function Toaster({\n position = \"top-right\",\n visibleToasts = 3,\n expand = false,\n duration = DEFAULT_TOAST_DURATION,\n closeButton = false,\n className = \"\",\n toastOptions,\n ...props\n}: ToasterProps) {\n return (\n <SonnerToaster\n position={position}\n visibleToasts={visibleToasts}\n expand={expand}\n duration={duration}\n closeButton={closeButton}\n className={`toaster group ${className}`}\n toastOptions={{\n unstyled: true,\n className: \"w-full max-w-md pointer-events-auto\",\n ...toastOptions,\n }}\n {...props}\n />\n );\n}\n","/**\n * Thời gian hiển thị mặc định của thông báo Toast trước khi tự động đóng (miliseconds).\n */\nexport const DEFAULT_TOAST_DURATION = 4000;\n","import { isValidElement, ReactElement, ReactNode } from \"react\";\nimport { toast as sonnerToast } from \"sonner\";\nimport Alert from \"../alert/Alert\";\nimport { AlertColor, AlertProps, AlertVariant } from \"../alert/types\";\nimport { ToastMessageObject, ToastMessageResult, ToastOptions, ToastPromiseOptions } from \"./types\";\nimport { DEFAULT_TOAST_DURATION } from \"./constants\";\nimport Spinner from \"../icons/Spinner\";\n\nfunction showToast(\n title: ReactNode,\n color: AlertColor = \"info\",\n variant: AlertVariant = \"soft\",\n description?: ReactNode,\n options: ToastOptions = {},\n customId?: string | number\n): string | number {\n const { duration, position, onDismiss, onAutoClose, ...alertProps } = options;\n\n return sonnerToast.custom(\n (id) => (\n <Alert\n color={color}\n variant={variant}\n title={title}\n description={description}\n closable={alertProps.closable ?? true}\n onClose={() => {\n alertProps.onClose?.();\n sonnerToast.dismiss(id);\n }}\n {...alertProps}\n />\n ),\n {\n id: customId,\n duration: duration ?? DEFAULT_TOAST_DURATION,\n position,\n onDismiss,\n onAutoClose,\n }\n );\n}\n\nfunction isToastMessageObject(value: unknown): value is ToastMessageObject {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !isValidElement(value) &&\n !Array.isArray(value) &&\n (\"title\" in value || \"description\" in value || \"color\" in value || \"variant\" in value)\n );\n}\n\nfunction extractMessageDetails(\n result: ToastMessageResult,\n fallbackColor: AlertColor,\n fallbackVariant: AlertVariant\n): { title: ReactNode; description?: ReactNode; color: AlertColor; variant: AlertVariant } {\n if (isToastMessageObject(result)) {\n return {\n title: result.title ?? \"\",\n description: result.description,\n color: result.color ?? fallbackColor,\n variant: result.variant ?? fallbackVariant,\n };\n }\n\n return {\n title: result,\n description: undefined,\n color: fallbackColor,\n variant: fallbackVariant,\n };\n}\n\n/**\n * Interface cho hàm và các phương thức của đối tượng `toast`.\n * Cú pháp chuẩn: `toast.success(title, description?, options?)`\n */\nexport interface ToastFunction {\n /**\n * Kích hoạt một thông báo Toast mặc định (màu info).\n * @param title Tiêu đề của thông báo\n * @param description Nội dung mô tả chi tiết (tùy chọn)\n * @param options Cấu hình phụ như variant, size, duration,... (tùy chọn)\n */\n (title: ReactNode, description?: ReactNode, options?: ToastOptions): string | number;\n\n /**\n * Kích hoạt thông báo tùy biến hoàn toàn (dùng hàm render JSX hoặc truyền AlertProps).\n */\n custom: {\n (jsxFn: (id: string | number) => ReactNode, options?: ToastOptions): string | number;\n (alertProps: AlertProps & ToastOptions): string | number;\n };\n\n /**\n * Kích hoạt thông báo thành công (màu success).\n */\n success: (title: ReactNode, description?: ReactNode, options?: ToastOptions) => string | number;\n\n /**\n * Kích hoạt thông báo lỗi (màu error).\n */\n error: (title: ReactNode, description?: ReactNode, options?: ToastOptions) => string | number;\n\n /**\n * Kích hoạt thông báo cảnh báo (màu warning).\n */\n warning: (title: ReactNode, description?: ReactNode, options?: ToastOptions) => string | number;\n\n /**\n * Kích hoạt thông báo thông tin (màu info).\n */\n info: (title: ReactNode, description?: ReactNode, options?: ToastOptions) => string | number;\n\n /**\n * Kích hoạt thông báo đang tải dữ liệu (Loading spinner, không tự đóng).\n */\n loading: (title: ReactNode, description?: ReactNode, options?: ToastOptions) => string | number;\n\n /**\n * Tự động theo dõi Promise và chuyển trạng thái Toast từ Loading sang Success hoặc Error.\n */\n promise: <T>(\n promise: Promise<T> | (() => Promise<T>),\n options: ToastPromiseOptions<T>\n ) => Promise<T>;\n\n /**\n * Đóng một Toast cụ thể bằng ID hoặc đóng tất cả Toasts nếu không truyền ID.\n */\n dismiss: (id?: string | number) => string | number | undefined;\n}\n\nconst baseToast = ((\n title: ReactNode,\n description?: ReactNode,\n options?: ToastOptions\n): string | number => {\n const opts = options || {};\n return showToast(title, opts.color || \"info\", opts.variant || \"soft\", description, opts);\n}) as ToastFunction;\n\nbaseToast.custom = (\n arg: ((id: string | number) => ReactNode) | (AlertProps & ToastOptions),\n options: ToastOptions = {}\n): string | number => {\n if (typeof arg === \"function\") {\n return sonnerToast.custom(\n (id) => arg(id) as ReactElement,\n {\n duration: options.duration ?? DEFAULT_TOAST_DURATION,\n position: options.position,\n onDismiss: options.onDismiss,\n onAutoClose: options.onAutoClose,\n }\n );\n }\n\n const { duration, position, onDismiss, onAutoClose, ...alertProps } = arg;\n return sonnerToast.custom(\n (id) => (\n <Alert\n closable={alertProps.closable ?? true}\n onClose={() => {\n alertProps.onClose?.();\n sonnerToast.dismiss(id);\n }}\n {...alertProps}\n />\n ),\n {\n duration: duration ?? DEFAULT_TOAST_DURATION,\n position,\n onDismiss,\n onAutoClose,\n }\n );\n};\n\nbaseToast.success = (\n title: ReactNode,\n description?: ReactNode,\n options?: ToastOptions\n): string | number => {\n const opts = options || {};\n return showToast(title, opts.color || \"success\", opts.variant || \"soft\", description, opts);\n};\n\nbaseToast.error = (\n title: ReactNode,\n description?: ReactNode,\n options?: ToastOptions\n): string | number => {\n const opts = options || {};\n return showToast(title, opts.color || \"error\", opts.variant || \"soft\", description, opts);\n};\n\nbaseToast.warning = (\n title: ReactNode,\n description?: ReactNode,\n options?: ToastOptions\n): string | number => {\n const opts = options || {};\n return showToast(title, opts.color || \"warning\", opts.variant || \"soft\", description, opts);\n};\n\nbaseToast.info = (\n title: ReactNode,\n description?: ReactNode,\n options?: ToastOptions\n): string | number => {\n const opts = options || {};\n return showToast(title, opts.color || \"info\", opts.variant || \"soft\", description, opts);\n};\n\nbaseToast.loading = (\n title: ReactNode,\n description?: ReactNode,\n options?: ToastOptions\n): string | number => {\n const opts = options || {};\n return showToast(title, opts.color || \"info\", opts.variant || \"soft\", description, {\n ...opts,\n icon: opts.icon ?? <Spinner className=\"size-full animate-spin\" />,\n duration: opts.duration ?? Infinity,\n closable: opts.closable ?? false,\n });\n};\n\nbaseToast.promise = async <T,>(\n promiseInput: Promise<T> | (() => Promise<T>),\n options: ToastPromiseOptions<T>\n): Promise<T> => {\n const promise = typeof promiseInput === \"function\" ? promiseInput() : promiseInput;\n\n const { title: loadingTitle, description: loadingDesc } = extractMessageDetails(\n options.loading,\n \"info\",\n options.variant || \"soft\"\n );\n\n const toastId = baseToast.loading(loadingTitle, loadingDesc, {\n size: options.size,\n variant: options.variant,\n radius: options.radius,\n });\n\n try {\n const data = await promise;\n\n const rawSuccess = typeof options.success === \"function\" ? options.success(data) : options.success;\n const { title: successTitle, description: successDesc, color: successColor, variant: successVariant } =\n extractMessageDetails(rawSuccess, \"success\", options.variant || \"soft\");\n\n showToast(\n successTitle,\n successColor,\n successVariant,\n successDesc,\n {\n duration: options.duration ?? DEFAULT_TOAST_DURATION,\n size: options.size,\n radius: options.radius,\n },\n toastId\n );\n\n return data;\n } catch (err: unknown) {\n const rawError = typeof options.error === \"function\" ? options.error(err) : options.error;\n const { title: errorTitle, description: errorDesc, color: errorColor, variant: errorVariant } =\n extractMessageDetails(rawError, \"error\", options.variant || \"soft\");\n\n showToast(\n errorTitle,\n errorColor,\n errorVariant,\n errorDesc,\n {\n duration: options.duration ?? DEFAULT_TOAST_DURATION,\n size: options.size,\n radius: options.radius,\n },\n toastId\n );\n\n throw err;\n } finally {\n if (options.finally) {\n await options.finally();\n }\n }\n};\n\nbaseToast.dismiss = (id?: string | number): string | number | undefined => {\n return sonnerToast.dismiss(id);\n};\n\nexport const toast: ToastFunction = baseToast;\n","import React, { cloneElement, isValidElement, useState, ReactNode, HTMLAttributes } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n arrow as arrowMiddleware,\n useHover,\n useFocus,\n useDismiss,\n useRole,\n useInteractions,\n useTransitionStyles,\n useMergeRefs,\n FloatingPortal,\n FloatingArrow,\n} from \"@floating-ui/react\";\nimport { TooltipProps } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig, arrowColorConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\n\ninterface SlotProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode;\n disabled?: boolean;\n}\n\nfunction Slot({\n children,\n ref: forwardedRef,\n disabled,\n className = \"\",\n ...props\n}: SlotProps & { ref?: React.Ref<HTMLElement> }) {\n const childRef = isValidElement(children) ? (children.props as { ref?: React.Ref<HTMLElement> })?.ref : undefined;\n\n const mergedChildRef = useMergeRefs([forwardedRef, childRef]);\n\n if (!isValidElement<Record<string, unknown>>(children)) {\n return null;\n }\n\n const childProps = (children.props || {}) as {\n className?: string;\n disabled?: boolean;\n [key: string]: unknown;\n };\n\n return cloneElement(children, {\n ...props,\n ...childProps,\n ref: mergedChildRef,\n disabled: disabled ? true : childProps.disabled,\n className: [childProps.className, className].filter(Boolean).join(\" \"),\n });\n}\n\nexport default function Tooltip({\n content,\n children,\n placement = \"top\",\n variant,\n color,\n size,\n radius,\n hasArrow = true,\n offset = 8,\n flip = true,\n shift = true,\n delay = { open: 200, close: 150 },\n disabled = false,\n animated = true,\n animationDuration = 150,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n className = \"\",\n arrowClassName = \"\",\n zIndex = DEFAULT_Z_INDEX.TOOLTIP,\n}: TooltipProps) {\n const [open, setOpen] = useState(defaultOpen);\n const [arrowRef, setArrowRef] = useState<SVGSVGElement | null>(null);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : open;\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (!isControlled) {\n setOpen(nextOpen);\n }\n onOpenChange?.(nextOpen);\n };\n\n const middleware = [\n offsetMiddleware(offset),\n flip ? flipMiddleware() : undefined,\n shift ? shiftMiddleware({ padding: 8 }) : undefined,\n hasArrow ? arrowMiddleware({ element: arrowRef }) : undefined,\n ].filter(Boolean);\n\n const {\n refs: { setReference, setFloating },\n floatingStyles,\n context,\n placement: computedPlacement,\n } = useFloating({\n placement,\n open: isOpen && !disabled,\n onOpenChange: handleOpenChange,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware,\n });\n\n const hover = useHover(context, {\n move: false,\n delay,\n enabled: !disabled,\n });\n const focus = useFocus(context, {\n enabled: !disabled,\n });\n const dismiss = useDismiss(context);\n const role = useRole(context, { role: \"tooltip\" });\n\n const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, dismiss, role]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: animated ? animationDuration : 0,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.95)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.95)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.95)\"\n : \"translateX(-4px) scale(0.95)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.95)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.95)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.95)\"\n : \"translateX(-4px) scale(0.95)\",\n }),\n });\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n\n const variantStyles =\n variant === \"other\" ? \"\" : getSafeConfig(color, getSafeConfig(variant, variantColorConfig, \"filled\"), \"neutral\");\n\n const arrowColorClass =\n variant === \"other\" ? \"\" : getSafeConfig(color, getSafeConfig(variant, arrowColorConfig, \"filled\"), \"neutral\");\n\n const classNames = [\n \"select-none pointer-events-none max-w-xs break-words\",\n currentSize.box,\n roundedClass,\n variantStyles,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const triggerProps = getReferenceProps();\n\n return (\n <>\n {isValidElement(children) ? (\n <Slot ref={setReference} disabled={disabled} {...triggerProps}>\n {children}\n </Slot>\n ) : (\n <span ref={setReference} {...triggerProps}>\n {children}\n </span>\n )}\n <FloatingPortal>\n {isMounted && !disabled && content && (\n <div\n ref={setFloating}\n style={{\n ...floatingStyles,\n ...(animated ? transitionStyles : {}),\n zIndex,\n }}\n className={classNames}\n data-state={isOpen ? \"open\" : \"closed\"}\n data-placement={computedPlacement}\n {...getFloatingProps()}\n >\n {content}\n {hasArrow && (\n <FloatingArrow\n ref={setArrowRef}\n context={context}\n width={currentSize.arrowWidth}\n height={currentSize.arrowHeight}\n strokeWidth={variant === \"outline\" || variant === \"soft\" ? 1 : 0}\n className={[arrowColorClass, arrowClassName].filter(Boolean).join(\" \")}\n />\n )}\n </div>\n )}\n </FloatingPortal>\n </>\n );\n}\n","import { TooltipSize, TooltipVariant, TooltipColor, TooltipRadius } from \"./types\";\n\nexport const sizeConfig: Record<\n TooltipSize,\n {\n box: string;\n arrowWidth: number;\n arrowHeight: number;\n }\n> = {\n xs: {\n box: \"px-2 py-0.5 text-[11px] leading-tight font-medium\",\n arrowWidth: 8,\n arrowHeight: 4,\n },\n sm: {\n box: \"px-2.5 py-1 text-xs leading-tight font-medium\",\n arrowWidth: 10,\n arrowHeight: 5,\n },\n md: {\n box: \"px-3 py-1.5 text-xs leading-normal font-medium\",\n arrowWidth: 12,\n arrowHeight: 6,\n },\n lg: {\n box: \"px-3.5 py-2 text-sm leading-normal font-medium\",\n arrowWidth: 14,\n arrowHeight: 7,\n },\n xl: {\n box: \"px-4 py-2.5 text-base leading-normal font-semibold\",\n arrowWidth: 16,\n arrowHeight: 8,\n },\n};\n\nexport const radiusConfig: Record<TooltipRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const variantColorConfig: Record<Exclude<TooltipVariant, \"other\">, Record<TooltipColor, string>> = {\n filled: {\n primary: \"bg-primary-500 text-neutral-white border border-transparent shadow-md\",\n secondary: \"bg-secondary-500 text-neutral-white border border-transparent shadow-md\",\n error: \"bg-error-500 text-neutral-white border border-transparent shadow-md\",\n success: \"bg-success-500 text-neutral-white border border-transparent shadow-md\",\n warning: \"bg-warning-500 text-neutral-950 border border-transparent shadow-md\",\n info: \"bg-info-500 text-neutral-white border border-transparent shadow-md\",\n neutral: \"bg-neutral-800 text-neutral-white border border-transparent shadow-md\",\n },\n soft: {\n primary: \"bg-primary-100 text-primary-800 border border-primary-200 shadow-sm\",\n secondary: \"bg-secondary-100 text-secondary-800 border border-secondary-200 shadow-sm\",\n error: \"bg-error-100 text-error-800 border border-error-200 shadow-sm\",\n success: \"bg-success-100 text-success-800 border border-success-200 shadow-sm\",\n warning: \"bg-warning-100 text-warning-800 border border-warning-200 shadow-sm\",\n info: \"bg-info-100 text-info-800 border border-info-200 shadow-sm\",\n neutral: \"bg-neutral-100 text-neutral-800 border border-neutral-200 shadow-sm\",\n },\n outline: {\n primary: \"bg-neutral-white text-primary-700 border border-primary-400 shadow-md\",\n secondary: \"bg-neutral-white text-secondary-800 border border-secondary-400 shadow-md\",\n error: \"bg-neutral-white text-error-700 border border-error-400 shadow-md\",\n success: \"bg-neutral-white text-success-700 border border-success-400 shadow-md\",\n warning: \"bg-neutral-white text-warning-800 border border-warning-400 shadow-md\",\n info: \"bg-neutral-white text-info-800 border border-info-400 shadow-md\",\n neutral: \"bg-neutral-white text-neutral-800 border border-neutral-300 shadow-md\",\n },\n};\n\nexport const arrowColorConfig: Record<Exclude<TooltipVariant, \"other\">, Record<TooltipColor, string>> = {\n filled: {\n primary: \"fill-primary-500\",\n secondary: \"fill-secondary-500\",\n error: \"fill-error-500\",\n success: \"fill-success-500\",\n warning: \"fill-warning-500\",\n info: \"fill-info-500\",\n neutral: \"fill-neutral-800\",\n },\n soft: {\n primary: \"fill-primary-100 stroke-primary-200\",\n secondary: \"fill-secondary-100 stroke-secondary-200\",\n error: \"fill-error-100 stroke-error-200\",\n success: \"fill-success-100 stroke-success-200\",\n warning: \"fill-warning-100 stroke-warning-200\",\n info: \"fill-info-100 stroke-info-200\",\n neutral: \"fill-neutral-100 stroke-neutral-200\",\n },\n outline: {\n primary: \"fill-neutral-white stroke-primary-400\",\n secondary: \"fill-neutral-white stroke-secondary-400\",\n error: \"fill-neutral-white stroke-error-400\",\n success: \"fill-neutral-white stroke-success-400\",\n warning: \"fill-neutral-white stroke-warning-400\",\n info: \"fill-neutral-white stroke-info-400\",\n neutral: \"fill-neutral-white stroke-neutral-300\",\n },\n};\n","export const DEFAULT_DEBOUNCE_DELAY = 300;\n\nexport const DEFAULT_Z_INDEX = {\n BASE: 0,\n STICKY: 10,\n DROPDOWN: 50,\n POPOVER: 50,\n SELECT: 50,\n PICKER: 50,\n TOOLTIP: 60,\n} as const;\n","import React, { useId, useState, ReactNode } from \"react\";\nimport * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport { SliderProps, SliderValue } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig } from \"./constants\";\nimport SliderThumb from \"./SliderThumb\";\nimport { SliderMarks, SliderStepDots } from \"./SliderMarks\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function Slider({\n config,\n value: valueProp,\n defaultValue: defaultValueProp,\n min = 0,\n max = 100,\n step = 1,\n minStepsBetweenThumbs = 0,\n inverted = false,\n size,\n variant,\n color,\n radius,\n thumbRadius,\n orientation = \"horizontal\",\n label,\n labelPlacement = \"top\",\n formatValue,\n showTooltip = \"none\",\n tooltipPlacement,\n formatTooltip,\n marks = false,\n startContent,\n endContent,\n disabled = false,\n readOnly = false,\n helperText,\n errorMessage,\n name,\n id: idProp,\n onChange,\n onChangeEnd,\n className = \"\",\n wrapperClassName = \"\",\n trackWrapperClassName = \"\",\n trackClassName = \"\",\n fillerClassName = \"\",\n thumbClassName = \"\",\n labelClassName = \"\",\n valueClassName = \"\",\n helperClassName = \"\",\n tooltipClassName = \"\",\n markClassName = \"\",\n ref,\n}: SliderProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n showSteps = false,\n showValue = false,\n isFullWidth = true,\n } = config ?? {};\n\n const generatedId = useId();\n const id = idProp || generatedId;\n const helperId = `${id}-helper`;\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n const isRange = Array.isArray(valueProp ?? defaultValueProp);\n const isControlled = valueProp !== undefined;\n\n // Internal state tracking for Uncontrolled mode and for label / step dots rendering\n const [internalValue, setInternalValue] = useState<number[]>(() => {\n if (defaultValueProp !== undefined) {\n return Array.isArray(defaultValueProp) ? defaultValueProp : [defaultValueProp];\n }\n return isRange ? [min, max] : [min];\n });\n\n const normalizedValue = isControlled\n ? Array.isArray(valueProp)\n ? valueProp\n : valueProp !== undefined\n ? [valueProp]\n : undefined\n : undefined;\n\n const currentValues: [number, number] = isControlled\n ? Array.isArray(valueProp)\n ? [valueProp[0] ?? min, valueProp[1] ?? max]\n : [valueProp ?? min, 0]\n : isRange\n ? [internalValue[0] ?? min, internalValue[1] ?? max]\n : [internalValue[0] ?? min, 0];\n\n const handleValueChange = (newValues: number[]) => {\n if (disabled || readOnly || isLoading) return;\n if (!isControlled) {\n setInternalValue(newValues);\n }\n const emitVal: SliderValue = isRange\n ? [newValues[0] ?? min, newValues[1] ?? max]\n : (newValues[0] ?? min);\n onChange?.(emitVal);\n };\n\n const handleValueCommit = (newValues: number[]) => {\n if (disabled || readOnly || isLoading) return;\n const emitVal: SliderValue = isRange\n ? [newValues[0] ?? min, newValues[1] ?? max]\n : (newValues[0] ?? min);\n onChangeEnd?.(emitVal);\n };\n\n // Resolved Styles via getSafeConfig\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const trackRadiusClass = getSafeConfig(radius, radiusConfig, \"full\");\n const thumbRadiusClass = getSafeConfig(thumbRadius, radiusConfig, \"full\");\n\n const colorConfig =\n variant === \"other\"\n ? { track: \"\", filler: \"\", thumb: \"\" }\n : getSafeConfig(activeColor, getSafeConfig(variant, variantColorConfig, \"filled\"), \"primary\");\n\n const trackThemeStyles = colorConfig.track;\n const fillerThemeStyles = colorConfig.filler;\n const thumbThemeStyles = colorConfig.thumb;\n\n // Render Label & Value\n const renderLabel = () => {\n if (!label && !showValue) return null;\n\n let displayText: ReactNode = \"\";\n if (formatValue) {\n displayText = formatValue(isRange ? currentValues : currentValues[0]);\n } else if (isRange) {\n displayText = `${currentValues[0]} - ${currentValues[1]}`;\n } else {\n displayText = `${currentValues[0]}`;\n }\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-medium\"\n : \"text-neutral-900 dark:text-neutral-100\";\n\n return (\n <div className=\"flex items-center justify-between gap-2 mb-1.5 select-none\">\n {label && (\n <label\n htmlFor={`${id}-thumb-0`}\n className={`font-medium ${labelColorStyle} ${\n currentSize.label\n } ${disabled ? \"opacity-60 cursor-not-allowed\" : \"cursor-pointer\"} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n {showValue && (\n <span\n className={`select-none text-neutral-700 dark:text-neutral-300 ${currentSize.value} ${valueClassName}`}\n aria-hidden=\"true\"\n >\n {displayText}\n </span>\n )}\n </div>\n );\n };\n\n const renderedThumbs = isRange ? [currentValues[0], currentValues[1]] : [currentValues[0]];\n\n return (\n <div\n ref={ref}\n className={`group/field flex flex-col ${isFullWidth ? \"w-full\" : \"inline-flex\"} ${\n disabled ? \"opacity-60 cursor-not-allowed\" : \"\"\n } ${wrapperClassName || className}`}\n >\n {/* Label Placement Top */}\n {labelPlacement === \"top\" && renderLabel()}\n\n {/* Main Slider Track Wrapper */}\n <div\n className={`flex items-center ${currentSize.gap} ${\n orientation === \"vertical\" ? \"flex-col h-48\" : \"flex-row w-full\"\n } ${trackWrapperClassName}`}\n >\n {labelPlacement === \"left\" && renderLabel()}\n\n {/* Start Content */}\n {startContent && (\n <div\n className=\"inline-flex shrink-0 items-center justify-center select-none text-neutral-500 dark:text-neutral-400\"\n aria-hidden=\"true\"\n >\n {startContent}\n </div>\n )}\n\n {/* Radix Slider Primitive Root */}\n <SliderPrimitive.Root\n min={min}\n max={max}\n step={step}\n minStepsBetweenThumbs={minStepsBetweenThumbs}\n inverted={inverted}\n orientation={orientation}\n disabled={disabled || isLoading || readOnly}\n value={normalizedValue}\n defaultValue={\n defaultValueProp !== undefined\n ? Array.isArray(defaultValueProp)\n ? defaultValueProp\n : [defaultValueProp]\n : undefined\n }\n onValueChange={handleValueChange}\n onValueCommit={handleValueCommit}\n className={`relative flex items-center select-none touch-none ${\n orientation === \"vertical\" ? \"flex-col h-full w-auto justify-center\" : \"w-full h-auto justify-center\"\n } ${disabled || readOnly ? \"cursor-not-allowed\" : \"cursor-pointer\"}`}\n >\n {/* Track */}\n <SliderPrimitive.Track\n className={`relative overflow-hidden ${\n orientation === \"vertical\"\n ? `${currentSize.trackVertical} h-full`\n : `${currentSize.trackHorizontal} w-full`\n } ${trackRadiusClass} ${trackThemeStyles} ${trackClassName}`}\n >\n {/* Step Dots */}\n <SliderStepDots\n showSteps={showSteps}\n min={min}\n max={max}\n step={step}\n orientation={orientation}\n size={size || \"md\"}\n isRange={isRange}\n currentValues={currentValues}\n />\n\n {/* Active / Filled Bar */}\n <SliderPrimitive.Range\n className={`absolute ${fillerThemeStyles} ${trackRadiusClass} ${fillerClassName}`}\n />\n </SliderPrimitive.Track>\n\n {/* Thumbs */}\n {renderedThumbs.map((thumbVal, idx) => {\n const thumbKey = isRange ? (idx === 0 ? `${id}-thumb-min` : `${id}-thumb-max`) : `${id}-thumb-single`;\n return (\n <SliderThumb\n key={thumbKey}\n id={id}\n thumbIdx={idx}\n value={thumbVal}\n orientation={orientation}\n size={size || \"md\"}\n thumbRadiusClass={thumbRadiusClass}\n thumbThemeStyles={thumbThemeStyles}\n thumbClassName={thumbClassName}\n tooltipClassName={tooltipClassName}\n state={{\n isLoading,\n showSpinner,\n disabled,\n readOnly,\n isRequired,\n isInvalid: hasError,\n isRange,\n hasDescription: Boolean(hasError || helperText),\n }}\n label={label}\n helperId={helperId}\n tooltipMode={showTooltip}\n tooltipPlacement={tooltipPlacement}\n formatTooltip={formatTooltip}\n />\n );\n })}\n </SliderPrimitive.Root>\n\n {/* End Content */}\n {endContent && (\n <div\n className=\"inline-flex shrink-0 items-center justify-center select-none text-neutral-500 dark:text-neutral-400\"\n aria-hidden=\"true\"\n >\n {endContent}\n </div>\n )}\n\n {labelPlacement === \"right\" && renderLabel()}\n </div>\n\n {/* Marks */}\n <SliderMarks\n marks={marks}\n min={min}\n max={max}\n step={step}\n orientation={orientation}\n size={size || \"md\"}\n markClassName={markClassName}\n />\n\n {/* Helper / Error Text */}\n <HelperErrorText\n id={helperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n\n {/* Hidden inputs for Form Integration */}\n {name && (\n <>\n {isRange ? (\n <>\n <input type=\"hidden\" name={`${name}[0]`} value={currentValues[0]} disabled={disabled} />\n <input type=\"hidden\" name={`${name}[1]`} value={currentValues[1]} disabled={disabled} />\n </>\n ) : (\n <input type=\"hidden\" name={name} value={currentValues[0]} disabled={disabled} />\n )}\n </>\n )}\n </div>\n );\n}\n","import { SliderColor, SliderRadius, SliderSize, SliderVariant } from \"./types\";\nimport { TooltipSize } from \"../tooltip/types\";\n\nexport interface SliderSizeStyle {\n trackHorizontal: string;\n trackVertical: string;\n thumb: string;\n thumbSizePx: number;\n label: string;\n value: string;\n helper: string;\n markText: string;\n gap: string;\n stepDot: string;\n tooltipSize: TooltipSize;\n}\n\nexport const sizeConfig: Record<SliderSize, SliderSizeStyle> = {\n xs: {\n trackHorizontal: \"h-1\",\n trackVertical: \"w-1\",\n thumb: \"w-3 h-3\",\n thumbSizePx: 12,\n label: \"text-xs font-medium\",\n value: \"text-xs font-semibold\",\n helper: \"text-[11px]\",\n markText: \"text-[10px]\",\n gap: \"gap-1\",\n stepDot: \"w-1 h-1\",\n tooltipSize: \"xs\",\n },\n sm: {\n trackHorizontal: \"h-1.5\",\n trackVertical: \"w-1.5\",\n thumb: \"w-4 h-4\",\n thumbSizePx: 16,\n label: \"text-xs font-medium\",\n value: \"text-xs font-semibold\",\n helper: \"text-xs\",\n markText: \"text-[11px]\",\n gap: \"gap-1.5\",\n stepDot: \"w-1.5 h-1.5\",\n tooltipSize: \"xs\",\n },\n md: {\n trackHorizontal: \"h-2\",\n trackVertical: \"w-2\",\n thumb: \"w-5 h-5\",\n thumbSizePx: 20,\n label: \"text-sm font-medium\",\n value: \"text-sm font-semibold\",\n helper: \"text-xs\",\n markText: \"text-xs\",\n gap: \"gap-2\",\n stepDot: \"w-2 h-2\",\n tooltipSize: \"sm\",\n },\n lg: {\n trackHorizontal: \"h-2.5\",\n trackVertical: \"w-2.5\",\n thumb: \"w-6 h-6\",\n thumbSizePx: 24,\n label: \"text-base font-medium\",\n value: \"text-base font-semibold\",\n helper: \"text-sm\",\n markText: \"text-xs\",\n gap: \"gap-2.5\",\n stepDot: \"w-2.5 h-2.5\",\n tooltipSize: \"md\",\n },\n xl: {\n trackHorizontal: \"h-3\",\n trackVertical: \"w-3\",\n thumb: \"w-7 h-7\",\n thumbSizePx: 28,\n label: \"text-lg font-medium\",\n value: \"text-lg font-semibold\",\n helper: \"text-sm\",\n markText: \"text-sm\",\n gap: \"gap-3\",\n stepDot: \"w-3 h-3\",\n tooltipSize: \"md\",\n },\n};\n\nexport const radiusConfig: Record<SliderRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport interface SliderStyleEntry {\n track: string;\n filler: string;\n thumb: string;\n}\n\nexport const variantColorConfig: Record<SliderVariant, Record<SliderColor, SliderStyleEntry>> = {\n filled: {\n primary: {\n track: \"bg-neutral-200 dark:bg-neutral-700\",\n filler: \"bg-primary-500 dark:bg-primary-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-primary-500 text-primary-600 focus-visible:ring-2 focus-visible:ring-primary-500/50 shadow-sm\",\n },\n secondary: {\n track: \"bg-neutral-200 dark:bg-neutral-700\",\n filler: \"bg-secondary-500 dark:bg-secondary-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-secondary-500 text-secondary-600 focus-visible:ring-2 focus-visible:ring-secondary-500/50 shadow-sm\",\n },\n error: {\n track: \"bg-neutral-200 dark:bg-neutral-700\",\n filler: \"bg-error-500 dark:bg-error-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-error-500 text-error-600 focus-visible:ring-2 focus-visible:ring-error-500/50 shadow-sm\",\n },\n success: {\n track: \"bg-neutral-200 dark:bg-neutral-700\",\n filler: \"bg-success-500 dark:bg-success-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-success-500 text-success-600 focus-visible:ring-2 focus-visible:ring-success-500/50 shadow-sm\",\n },\n warning: {\n track: \"bg-neutral-200 dark:bg-neutral-700\",\n filler: \"bg-warning-500 dark:bg-warning-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-warning-500 text-warning-600 focus-visible:ring-2 focus-visible:ring-warning-500/50 shadow-sm\",\n },\n info: {\n track: \"bg-neutral-200 dark:bg-neutral-700\",\n filler: \"bg-info-500 dark:bg-info-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-info-500 text-info-600 focus-visible:ring-2 focus-visible:ring-info-500/50 shadow-sm\",\n },\n neutral: {\n track: \"bg-neutral-200 dark:bg-neutral-700\",\n filler: \"bg-neutral-800 dark:bg-neutral-200\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-neutral-800 dark:border-neutral-200 text-neutral-800 dark:text-neutral-200 focus-visible:ring-2 focus-visible:ring-neutral-500/50 shadow-sm\",\n },\n },\n\n soft: {\n primary: {\n track: \"bg-primary-100 dark:bg-primary-950/40\",\n filler: \"bg-primary-400 dark:bg-primary-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-primary-400 text-primary-500 focus-visible:ring-2 focus-visible:ring-primary-400/50 shadow-sm\",\n },\n secondary: {\n track: \"bg-secondary-100 dark:bg-secondary-950/40\",\n filler: \"bg-secondary-400 dark:bg-secondary-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-secondary-400 text-secondary-500 focus-visible:ring-2 focus-visible:ring-secondary-400/50 shadow-sm\",\n },\n error: {\n track: \"bg-error-100 dark:bg-error-950/40\",\n filler: \"bg-error-400 dark:bg-error-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-error-400 text-error-500 focus-visible:ring-2 focus-visible:ring-error-400/50 shadow-sm\",\n },\n success: {\n track: \"bg-success-100 dark:bg-success-950/40\",\n filler: \"bg-success-400 dark:bg-success-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-success-400 text-success-500 focus-visible:ring-2 focus-visible:ring-success-400/50 shadow-sm\",\n },\n warning: {\n track: \"bg-warning-100 dark:bg-warning-950/40\",\n filler: \"bg-warning-400 dark:bg-warning-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-warning-400 text-warning-500 focus-visible:ring-2 focus-visible:ring-warning-400/50 shadow-sm\",\n },\n info: {\n track: \"bg-info-100 dark:bg-info-950/40\",\n filler: \"bg-info-400 dark:bg-info-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-info-400 text-info-500 focus-visible:ring-2 focus-visible:ring-info-400/50 shadow-sm\",\n },\n neutral: {\n track: \"bg-neutral-200 dark:bg-neutral-800\",\n filler: \"bg-neutral-600 dark:bg-neutral-400\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-neutral-600 dark:border-neutral-400 text-neutral-600 focus-visible:ring-2 focus-visible:ring-neutral-400/50 shadow-sm\",\n },\n },\n\n outline: {\n primary: {\n track: \"bg-transparent border border-neutral-300 dark:border-neutral-700\",\n filler: \"bg-primary-500 dark:bg-primary-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-primary-500 text-primary-600 focus-visible:ring-2 focus-visible:ring-primary-500/50 shadow-sm\",\n },\n secondary: {\n track: \"bg-transparent border border-neutral-300 dark:border-neutral-700\",\n filler: \"bg-secondary-500 dark:bg-secondary-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-secondary-500 text-secondary-600 focus-visible:ring-2 focus-visible:ring-secondary-500/50 shadow-sm\",\n },\n error: {\n track: \"bg-transparent border border-neutral-300 dark:border-neutral-700\",\n filler: \"bg-error-500 dark:bg-error-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-error-500 text-error-600 focus-visible:ring-2 focus-visible:ring-error-500/50 shadow-sm\",\n },\n success: {\n track: \"bg-transparent border border-neutral-300 dark:border-neutral-700\",\n filler: \"bg-success-500 dark:bg-success-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-success-500 text-success-600 focus-visible:ring-2 focus-visible:ring-success-500/50 shadow-sm\",\n },\n warning: {\n track: \"bg-transparent border border-neutral-300 dark:border-neutral-700\",\n filler: \"bg-warning-500 dark:bg-warning-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-warning-500 text-warning-600 focus-visible:ring-2 focus-visible:ring-warning-500/50 shadow-sm\",\n },\n info: {\n track: \"bg-transparent border border-neutral-300 dark:border-neutral-700\",\n filler: \"bg-info-500 dark:bg-info-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-info-500 text-info-600 focus-visible:ring-2 focus-visible:ring-info-500/50 shadow-sm\",\n },\n neutral: {\n track: \"bg-transparent border border-neutral-300 dark:border-neutral-700\",\n filler: \"bg-neutral-800 dark:bg-neutral-200\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-neutral-800 dark:border-neutral-200 text-neutral-800 dark:text-neutral-200 focus-visible:ring-2 focus-visible:ring-neutral-500/50 shadow-sm\",\n },\n },\n\n other: {\n primary: { track: \"\", filler: \"\", thumb: \"\" },\n secondary: { track: \"\", filler: \"\", thumb: \"\" },\n error: { track: \"\", filler: \"\", thumb: \"\" },\n success: { track: \"\", filler: \"\", thumb: \"\" },\n warning: { track: \"\", filler: \"\", thumb: \"\" },\n info: { track: \"\", filler: \"\", thumb: \"\" },\n neutral: { track: \"\", filler: \"\", thumb: \"\" },\n },\n};\n\nexport const invalidStyles: Record<SliderVariant, SliderStyleEntry> = {\n filled: {\n track: \"bg-error-100 dark:bg-error-950/30\",\n filler: \"bg-error-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-error-500 text-error-600 focus-visible:ring-2 focus-visible:ring-error-500/50 shadow-sm\",\n },\n soft: {\n track: \"bg-error-100 dark:bg-error-950/40\",\n filler: \"bg-error-400\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-error-400 text-error-500 focus-visible:ring-2 focus-visible:ring-error-400/50 shadow-sm\",\n },\n outline: {\n track: \"bg-transparent border border-error-400 dark:border-error-600\",\n filler: \"bg-error-500\",\n thumb:\n \"bg-white dark:bg-neutral-900 border-2 border-error-500 text-error-600 focus-visible:ring-2 focus-visible:ring-error-500/50 shadow-sm\",\n },\n other: {\n track: \"\",\n filler: \"\",\n thumb: \"\",\n },\n};\n\n// Aliases for full backward compatibility\nexport const sliderSizeConfig = sizeConfig;\nexport const sliderRadiusConfig = radiusConfig;\nexport const sliderVariantColorConfig = variantColorConfig;\nexport const sliderInvalidStyles = invalidStyles;\n","import React, { ReactNode, useState } from \"react\";\nimport * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport { SliderOrientation, SliderSize, SliderTooltipMode, SliderTooltipPlacement } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport Tooltip from \"@/components/tooltip/Tooltip\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport interface SliderThumbState {\n isLoading?: boolean;\n showSpinner?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n isRequired?: boolean;\n isInvalid?: boolean;\n isRange?: boolean;\n hasDescription?: boolean;\n}\n\nexport interface SliderThumbProps {\n id: string;\n thumbIdx: number;\n value: number;\n orientation: SliderOrientation;\n size: SliderSize;\n thumbRadiusClass: string;\n thumbThemeStyles: string;\n thumbClassName?: string;\n tooltipClassName?: string;\n state?: SliderThumbState;\n label?: ReactNode;\n helperId?: string;\n tooltipMode?: SliderTooltipMode;\n tooltipPlacement?: SliderTooltipPlacement;\n formatTooltip?: (value: number) => ReactNode;\n}\n\nexport default function SliderThumb({\n id,\n thumbIdx,\n value,\n orientation,\n size,\n thumbRadiusClass,\n thumbThemeStyles,\n thumbClassName = \"\",\n tooltipClassName = \"\",\n state,\n label,\n helperId,\n tooltipMode = \"none\",\n tooltipPlacement,\n formatTooltip,\n}: SliderThumbProps) {\n const {\n isLoading = false,\n showSpinner = false,\n disabled = false,\n readOnly = false,\n isRequired = false,\n isInvalid = false,\n isRange = false,\n hasDescription = false,\n } = state ?? {};\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n const [isHovered, setIsHovered] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n\n // Xác định trạng thái hiển thị tooltip\n let isTooltipOpen: boolean | undefined = undefined;\n if (tooltipMode === \"always\") {\n isTooltipOpen = true;\n } else if (tooltipMode === \"active\") {\n isTooltipOpen = isDragging || isFocused;\n } else if (tooltipMode === \"hover\") {\n isTooltipOpen = isHovered || isDragging || isFocused;\n } else if (tooltipMode === \"none\") {\n isTooltipOpen = false;\n }\n\n const defaultPlacement = tooltipPlacement || (orientation === \"vertical\" ? \"right\" : \"top\");\n const formattedTooltipContent = formatTooltip ? formatTooltip(value) : value.toString();\n\n const valueText =\n typeof formattedTooltipContent === \"string\" || typeof formattedTooltipContent === \"number\"\n ? String(formattedTooltipContent)\n : undefined;\n\n const thumbNode = (\n <SliderPrimitive.Thumb\n id={`${id}-thumb-${thumbIdx}`}\n tabIndex={disabled || isLoading ? -1 : 0}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-readonly={readOnly}\n aria-required={isRequired}\n aria-invalid={isInvalid}\n aria-errormessage={isInvalid ? helperId : undefined}\n aria-describedby={hasDescription ? helperId : undefined}\n aria-valuetext={valueText}\n aria-orientation={orientation}\n aria-label={\n typeof label === \"string\"\n ? `${label} ${isRange ? (thumbIdx === 0 ? \"minimum\" : \"maximum\") : \"\"}`\n : `Slider ${isRange ? (thumbIdx === 0 ? \"min\" : \"max\") : \"\"}`\n }\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onPointerEnter={() => setIsHovered(true)}\n onPointerLeave={() => setIsHovered(false)}\n onPointerDown={() => setIsDragging(true)}\n onPointerUp={() => setIsDragging(false)}\n className={`block relative z-10 select-none outline-none transition-transform duration-100 ease-out ${\n disabled || readOnly\n ? \"cursor-not-allowed opacity-60 shadow-none\"\n : \"cursor-grab active:cursor-grabbing hover:scale-105\"\n } ${currentSize.thumb} ${thumbRadiusClass} ${thumbThemeStyles} ${\n isDragging && !disabled && !isLoading ? \"scale-110 ring-4 ring-primary-500/20\" : \"\"\n } ${thumbClassName}`}\n >\n {isLoading && showSpinner && (\n <div className=\"absolute inset-0 flex items-center justify-center p-0.5\" aria-hidden=\"true\">\n <Spinner className=\"size-full animate-spin text-current\" />\n </div>\n )}\n </SliderPrimitive.Thumb>\n );\n\n if (tooltipMode !== \"none\") {\n return (\n <Tooltip\n content={formattedTooltipContent}\n placement={defaultPlacement}\n open={isTooltipOpen}\n size={currentSize.tooltipSize}\n className={tooltipClassName}\n disabled={disabled || isLoading}\n >\n {thumbNode}\n </Tooltip>\n );\n }\n\n return thumbNode;\n}\n","\n/**\n * Giới hạn giá trị nằm trong khoảng [min, max]\n */\nexport function clamp(val: number, min: number, max: number): number {\n return Math.min(Math.max(val, min), max);\n}\n\n/**\n * Tính tỷ lệ phần trăm (0 - 100) của một giá trị trong khoảng [min, max]\n */\nexport function getPercentage(val: number, min: number, max: number): number {\n if (max <= min) return 0;\n return clamp(((val - min) / (max - min)) * 100, 0, 100);\n}\n","import React from \"react\";\nimport { SliderMark, SliderOrientation, SliderSize } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { getPercentage } from \"./utils\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport interface SliderMarksProps {\n marks?: SliderMark[] | boolean;\n min: number;\n max: number;\n step: number;\n orientation: SliderOrientation;\n size: SliderSize;\n markClassName?: string;\n}\n\nexport function SliderMarks({ marks, min, max, step, orientation, size, markClassName = \"\" }: SliderMarksProps) {\n if (!marks) return null;\n\n let markList: SliderMark[] = [];\n if (Array.isArray(marks)) {\n markList = marks;\n } else if (marks === true && step > 0) {\n const totalSteps = Math.floor((max - min) / step);\n if (totalSteps <= 20) {\n for (let i = 0; i <= totalSteps; i++) {\n const val = min + i * step;\n markList.push({ value: val, label: val.toString() });\n }\n }\n }\n\n if (!markList.length) return null;\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n return (\n <div className={`relative w-full ${orientation === \"vertical\" ? \"h-full\" : \"mt-2\"}`} aria-hidden=\"true\">\n {markList.map((m) => {\n const pct = getPercentage(m.value, min, max);\n return (\n <div\n key={m.value}\n className={`absolute flex items-center justify-center select-none text-neutral-500 dark:text-neutral-400 ${\n currentSize.markText\n } ${markClassName}`}\n style={\n orientation === \"vertical\"\n ? {\n bottom: `${pct}%`,\n left: \"100%\",\n transform: \"translateY(50%) translateX(6px)\",\n }\n : { left: `${pct}%`, transform: \"translateX(-50%)\" }\n }\n >\n {m.label ?? m.value}\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface SliderStepDotsProps {\n showSteps?: boolean;\n min: number;\n max: number;\n step: number;\n orientation: SliderOrientation;\n size: SliderSize;\n isRange: boolean;\n currentValues: [number, number];\n}\n\nexport function SliderStepDots({\n showSteps,\n min,\n max,\n step,\n orientation,\n size,\n isRange,\n currentValues,\n}: SliderStepDotsProps) {\n if (!showSteps || step <= 0) return null;\n const totalSteps = Math.floor((max - min) / step);\n if (totalSteps > 100) return null;\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const dots = [];\n\n for (let i = 0; i <= totalSteps; i++) {\n const val = min + i * step;\n const pct = getPercentage(val, min, max);\n const isFilled = isRange\n ? val >= (currentValues[0] ?? min) && val <= (currentValues[1] ?? max)\n : val <= (currentValues[0] ?? min);\n\n dots.push(\n <span\n key={`step-dot-${val}`}\n aria-hidden=\"true\"\n className={`absolute rounded-full -translate-x-1/2 -translate-y-1/2 pointer-events-none transition-colors duration-150 ${\n currentSize.stepDot\n } ${isFilled ? \"bg-white/80 dark:bg-neutral-900/80\" : \"bg-neutral-400/60 dark:bg-neutral-500/60\"}`}\n style={orientation === \"vertical\" ? { bottom: `${pct}%`, left: \"50%\" } : { left: `${pct}%`, top: \"50%\" }}\n />\n );\n }\n\n return <>{dots}</>;\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { CollapseProps, CollapseActiveKey, CollapseContextValue } from \"./types\";\nimport { radiusConfig, variantContainerConfig } from \"./constants\";\nimport { CollapseContext } from \"./context\";\n\nfunction normalizeKeys(keys?: CollapseActiveKey): (string | number)[] {\n if (keys === undefined || keys === null) return [];\n if (Array.isArray(keys)) return keys;\n return [keys];\n}\n\nexport default function Collapse({\n activeKey: activeKeyProp,\n defaultActiveKey,\n onChange,\n accordion = false,\n size = \"md\",\n variant = \"outlined\",\n color = \"primary\",\n radius = \"md\",\n expandIconPosition = \"right\",\n expandIcon,\n destroyInactivePanel = false,\n className = \"\",\n style,\n children,\n ref,\n ...props\n}: CollapseProps) {\n const isControlled = activeKeyProp !== undefined;\n const [internalActiveKeys, setInternalActiveKeys] = useState<(string | number)[]>(() =>\n normalizeKeys(defaultActiveKey)\n );\n\n const activeKeys = useMemo(\n () => new Set(isControlled ? normalizeKeys(activeKeyProp) : internalActiveKeys),\n [isControlled, activeKeyProp, internalActiveKeys]\n );\n\n const handleToggle = useCallback(\n (key: string | number) => {\n let nextKeys: (string | number)[];\n const isCurrentActive = activeKeys.has(key);\n\n if (accordion) {\n nextKeys = isCurrentActive ? [] : [key];\n } else {\n const currentArray = Array.from(activeKeys);\n if (isCurrentActive) {\n nextKeys = currentArray.filter((k) => k !== key);\n } else {\n nextKeys = [...currentArray, key];\n }\n }\n\n if (!isControlled) {\n setInternalActiveKeys(nextKeys);\n }\n\n onChange?.(accordion ? (nextKeys[0] ?? \"\") : nextKeys);\n },\n [accordion, activeKeys, isControlled, onChange]\n );\n\n const containerVariantStyle =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(\n color,\n getSafeConfig(variant, variantContainerConfig, \"outlined\"),\n \"primary\"\n );\n\n const containerRounded =\n variant !== \"separated\" && variant !== \"ghost\"\n ? getSafeConfig(radius, radiusConfig, \"md\")\n : \"\";\n\n const containerClassNames = [\n \"w-full transition-colors\",\n containerVariantStyle,\n containerRounded,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const contextValue: CollapseContextValue = useMemo(\n () => ({\n activeKeys,\n handleToggle,\n accordion,\n size,\n variant,\n color,\n radius,\n expandIconPosition,\n expandIcon,\n destroyInactivePanel,\n }),\n [\n activeKeys,\n handleToggle,\n accordion,\n size,\n variant,\n color,\n radius,\n expandIconPosition,\n expandIcon,\n destroyInactivePanel,\n ]\n );\n\n return (\n <CollapseContext.Provider value={contextValue}>\n <div ref={ref} className={containerClassNames} style={style} {...props}>\n {children}\n </div>\n </CollapseContext.Provider>\n );\n}\n","import { CollapseSize, CollapseVariant, CollapseRadius, CollapseColor } from \"./types\";\n\nexport const sizeConfig: Record<\n CollapseSize,\n {\n header: string;\n content: string;\n title: string;\n description: string;\n icon: string;\n startIcon: string;\n gap: string;\n }\n> = {\n sm: {\n header: \"py-2.5 px-3.5 text-sm\",\n content: \"px-3.5 pb-3 text-sm text-neutral-600\",\n title: \"font-medium leading-snug\",\n description: \"text-xs text-neutral-500 mt-0.5\",\n icon: \"size-4\",\n startIcon: \"size-4\",\n gap: \"gap-2.5\",\n },\n md: {\n header: \"py-3.5 px-4 text-base\",\n content: \"px-4 pb-4 text-sm text-neutral-600\",\n title: \"font-semibold leading-snug\",\n description: \"text-xs text-neutral-500 mt-1\",\n icon: \"size-4.5\",\n startIcon: \"size-4.5\",\n gap: \"gap-3\",\n },\n lg: {\n header: \"py-4.5 px-5 text-lg\",\n content: \"px-5 pb-5 text-base text-neutral-600\",\n title: \"font-semibold leading-snug\",\n description: \"text-sm text-neutral-500 mt-1\",\n icon: \"size-5\",\n startIcon: \"size-5\",\n gap: \"gap-3.5\",\n },\n};\n\nexport const radiusConfig: Record<CollapseRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-md\",\n md: \"rounded-xl\",\n lg: \"rounded-2xl\",\n xl: \"rounded-3xl\",\n full: \"rounded-3xl\",\n};\n\nexport const variantContainerConfig: Record<\n Exclude<CollapseVariant, \"other\">,\n Record<CollapseColor, string>\n> = {\n outlined: {\n primary: \"border border-primary-200 bg-white divide-y divide-primary-100 overflow-hidden\",\n secondary: \"border border-secondary-200 bg-white divide-y divide-secondary-100 overflow-hidden\",\n neutral: \"border border-neutral-200 bg-white divide-y divide-neutral-200 overflow-hidden\",\n error: \"border border-error-200 bg-white divide-y divide-error-100 overflow-hidden\",\n success: \"border border-success-200 bg-white divide-y divide-success-100 overflow-hidden\",\n warning: \"border border-warning-200 bg-white divide-y divide-warning-100 overflow-hidden\",\n info: \"border border-info-200 bg-white divide-y divide-info-100 overflow-hidden\",\n },\n filled: {\n primary: \"bg-primary-50/40 border border-primary-100 divide-y divide-primary-100/80 overflow-hidden\",\n secondary: \"bg-secondary-50/40 border border-secondary-100 divide-y divide-secondary-100/80 overflow-hidden\",\n neutral: \"bg-neutral-50 border border-neutral-200/60 divide-y divide-neutral-200/60 overflow-hidden\",\n error: \"bg-error-50/40 border border-error-100 divide-y divide-error-100/80 overflow-hidden\",\n success: \"bg-success-50/40 border border-success-100 divide-y divide-success-100/80 overflow-hidden\",\n warning: \"bg-warning-50/40 border border-warning-100 divide-y divide-warning-100/80 overflow-hidden\",\n info: \"bg-info-50/40 border border-info-100 divide-y divide-info-100/80 overflow-hidden\",\n },\n separated: {\n primary: \"bg-transparent border-0 space-y-3\",\n secondary: \"bg-transparent border-0 space-y-3\",\n neutral: \"bg-transparent border-0 space-y-3\",\n error: \"bg-transparent border-0 space-y-3\",\n success: \"bg-transparent border-0 space-y-3\",\n warning: \"bg-transparent border-0 space-y-3\",\n info: \"bg-transparent border-0 space-y-3\",\n },\n ghost: {\n primary: \"bg-transparent border-0 divide-y divide-neutral-200/70\",\n secondary: \"bg-transparent border-0 divide-y divide-neutral-200/70\",\n neutral: \"bg-transparent border-0 divide-y divide-neutral-200/70\",\n error: \"bg-transparent border-0 divide-y divide-neutral-200/70\",\n success: \"bg-transparent border-0 divide-y divide-neutral-200/70\",\n warning: \"bg-transparent border-0 divide-y divide-neutral-200/70\",\n info: \"bg-transparent border-0 divide-y divide-neutral-200/70\",\n },\n};\n\nexport const variantPanelConfig: Record<\n Exclude<CollapseVariant, \"other\">,\n Record<CollapseColor, string>\n> = {\n outlined: { primary: \"\", secondary: \"\", neutral: \"\", error: \"\", success: \"\", warning: \"\", info: \"\" },\n filled: { primary: \"\", secondary: \"\", neutral: \"\", error: \"\", success: \"\", warning: \"\", info: \"\" },\n ghost: { primary: \"\", secondary: \"\", neutral: \"\", error: \"\", success: \"\", warning: \"\", info: \"\" },\n separated: {\n primary: \"bg-white border border-primary-200 shadow-xs overflow-hidden\",\n secondary: \"bg-white border border-secondary-200 shadow-xs overflow-hidden\",\n neutral: \"bg-white border border-neutral-200 shadow-xs overflow-hidden\",\n error: \"bg-white border border-error-200 shadow-xs overflow-hidden\",\n success: \"bg-white border border-success-200 shadow-xs overflow-hidden\",\n warning: \"bg-white border border-warning-200 shadow-xs overflow-hidden\",\n info: \"bg-white border border-info-200 shadow-xs overflow-hidden\",\n },\n};\n\nexport const variantHeaderConfig: Record<\n Exclude<CollapseVariant, \"other\">,\n Record<CollapseColor, string>\n> = {\n outlined: {\n primary: \"bg-primary-50/40\",\n secondary: \"bg-secondary-50/40\",\n neutral: \"bg-neutral-50/80\",\n error: \"bg-error-50/40\",\n success: \"bg-success-50/40\",\n warning: \"bg-warning-50/40\",\n info: \"bg-info-50/40\",\n },\n filled: {\n primary: \"bg-primary-50/80\",\n secondary: \"bg-secondary-50/80\",\n neutral: \"bg-neutral-100/70\",\n error: \"bg-error-50/80\",\n success: \"bg-success-50/80\",\n warning: \"bg-warning-50/80\",\n info: \"bg-info-50/80\",\n },\n separated: {\n primary: \"bg-primary-50/40\",\n secondary: \"bg-secondary-50/40\",\n neutral: \"bg-neutral-50/80\",\n error: \"bg-error-50/40\",\n success: \"bg-success-50/40\",\n warning: \"bg-warning-50/40\",\n info: \"bg-info-50/40\",\n },\n ghost: {\n primary: \"bg-transparent\",\n secondary: \"bg-transparent\",\n neutral: \"bg-transparent\",\n error: \"bg-transparent\",\n success: \"bg-transparent\",\n warning: \"bg-transparent\",\n info: \"bg-transparent\",\n },\n};\n\nexport const colorConfig: Record<\n CollapseColor,\n {\n focusRing: string;\n title: string;\n activeIndicator: string;\n }\n> = {\n primary: {\n focusRing: \"focus-visible:ring-primary-500\",\n title: \"text-primary-700\",\n activeIndicator: \"text-primary-600\",\n },\n secondary: {\n focusRing: \"focus-visible:ring-secondary-500\",\n title: \"text-secondary-700\",\n activeIndicator: \"text-secondary-600\",\n },\n neutral: {\n focusRing: \"focus-visible:ring-neutral-500\",\n title: \"text-neutral-900\",\n activeIndicator: \"text-neutral-700\",\n },\n error: {\n focusRing: \"focus-visible:ring-error-500\",\n title: \"text-error-700\",\n activeIndicator: \"text-error-600\",\n },\n success: {\n focusRing: \"focus-visible:ring-success-500\",\n title: \"text-success-700\",\n activeIndicator: \"text-success-600\",\n },\n warning: {\n focusRing: \"focus-visible:ring-warning-500\",\n title: \"text-warning-700\",\n activeIndicator: \"text-warning-600\",\n },\n info: {\n focusRing: \"focus-visible:ring-info-500\",\n title: \"text-info-700\",\n activeIndicator: \"text-info-600\",\n },\n};\n","import { createContext, useContext, ReactNode } from \"react\";\nimport {\n CollapseSize,\n CollapseVariant,\n CollapseColor,\n CollapseRadius,\n CollapseExpandIconPosition,\n} from \"./types\";\n\nexport interface CollapseContextValue {\n activeKeys: Set<string | number>;\n handleToggle: (key: string | number) => void;\n accordion: boolean;\n size: CollapseSize;\n variant: CollapseVariant;\n color: CollapseColor;\n radius: CollapseRadius;\n expandIconPosition: CollapseExpandIconPosition;\n expandIcon?: ReactNode | ((props: { isActive: boolean; disabled?: boolean }) => ReactNode);\n destroyInactivePanel: boolean;\n}\n\nexport interface CollapsePanelContextValue {\n value: string | number;\n isActive: boolean;\n disabled?: boolean;\n headerId: string;\n panelId: string;\n onToggle: () => void;\n}\n\nexport const CollapseContext = createContext<CollapseContextValue | null>(null);\nexport const CollapsePanelContext = createContext<CollapsePanelContextValue | null>(null);\n\nexport function useCollapseContext(): CollapseContextValue {\n const context = useContext(CollapseContext);\n if (!context) {\n throw new Error(\"Collapse compound components must be rendered within a <Collapse> provider\");\n }\n return context;\n}\n\nexport function useCollapsePanelContext(): CollapsePanelContextValue {\n const context = useContext(CollapsePanelContext);\n if (!context) {\n throw new Error(\n \"Collapse subcomponents (CollapseHeader, CollapseContent) must be rendered within a <CollapsePanel>\"\n );\n }\n return context;\n}\r\n","import { useId, useMemo } from \"react\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { CollapsePanelProps } from \"./types\";\nimport { useCollapseContext, CollapsePanelContext, CollapsePanelContextValue } from \"./context\";\nimport { radiusConfig, variantPanelConfig } from \"./constants\";\nimport CollapseHeader from \"./CollapseHeader\";\nimport CollapseContent from \"./CollapseContent\";\n\nexport default function CollapsePanel({\n value,\n label,\n description,\n startIcon,\n extra,\n disabled = false,\n showArrow = true,\n headerClassName = \"\",\n contentClassName = \"\",\n destroyInactivePanel,\n className = \"\",\n children,\n ref,\n ...props\n}: CollapsePanelProps) {\n const generatedId = useId();\n const { activeKeys, handleToggle, variant, color, radius } = useCollapseContext();\n\n const isActive = activeKeys.has(value);\n const headerId = `collapse-header-${value ?? generatedId}`;\n const panelId = `collapse-panel-${value ?? generatedId}`;\n\n const panelContextValue: CollapsePanelContextValue = useMemo(\n () => ({\n value,\n isActive,\n disabled,\n headerId,\n panelId,\n onToggle: () => !disabled && handleToggle(value),\n }),\n [value, isActive, disabled, headerId, panelId, handleToggle]\n );\n\n const itemRounded = variant === \"separated\" ? getSafeConfig(radius, radiusConfig, \"md\") : \"\";\n const itemVariantStyle =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(\n color,\n getSafeConfig(variant, variantPanelConfig, \"outlined\"),\n \"primary\"\n );\n\n const itemClassNames = [\n \"group\",\n itemVariantStyle,\n itemRounded,\n disabled ? \"opacity-50 cursor-not-allowed\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <CollapsePanelContext.Provider value={panelContextValue}>\n <div ref={ref} className={itemClassNames} data-state={isActive ? \"open\" : \"closed\"} {...props}>\n {label !== undefined ? (\n <>\n <CollapseHeader\n startIcon={startIcon}\n description={description}\n extra={extra}\n showArrow={showArrow}\n className={headerClassName}\n >\n {label}\n </CollapseHeader>\n <CollapseContent\n destroyInactivePanel={destroyInactivePanel}\n className={contentClassName}\n >\n {children}\n </CollapseContent>\n </>\n ) : (\n children\n )}\n </div>\n </CollapsePanelContext.Provider>\n );\n}\r\n","import { getSafeConfig } from \"@/utils/function\";\nimport { CollapseHeaderProps } from \"./types\";\nimport { useCollapseContext, useCollapsePanelContext } from \"./context\";\nimport { sizeConfig, colorConfig, variantHeaderConfig } from \"./constants\";\nimport ChevronDownIcon from \"@/components/icons/ChevronDownIcon\";\n\nexport default function CollapseHeader({\n startIcon,\n description,\n extra,\n showArrow = true,\n children,\n className = \"\",\n ref,\n onClick,\n onKeyDown,\n ...props\n}: CollapseHeaderProps) {\n const { size, variant, color, expandIconPosition, expandIcon } = useCollapseContext();\n const { isActive, disabled, headerId, panelId, onToggle } = useCollapsePanelContext();\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const currentColor = getSafeConfig(color, colorConfig, \"primary\");\n const currentHeaderBg =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(\n color,\n getSafeConfig(variant, variantHeaderConfig, \"outlined\"),\n \"primary\"\n );\n const isArrowVisible = showArrow && expandIconPosition !== \"none\";\n\n const renderArrow = () => {\n if (!isArrowVisible) return null;\n\n if (typeof expandIcon === \"function\") {\n return (\n <span\n className={`inline-flex items-center justify-center shrink-0 transition-transform duration-200 text-neutral-400 ${\n isActive ? \"rotate-180\" : \"rotate-0\"\n }`}\n aria-hidden=\"true\"\n >\n {expandIcon({ isActive, disabled })}\n </span>\n );\n }\n\n if (expandIcon) {\n return (\n <span\n className={`inline-flex items-center justify-center shrink-0 transition-transform duration-200 text-neutral-400 ${\n isActive ? \"rotate-180\" : \"rotate-0\"\n }`}\n aria-hidden=\"true\"\n >\n {expandIcon}\n </span>\n );\n }\n\n return (\n <span\n className={`inline-flex items-center justify-center shrink-0 transition-transform duration-200 text-neutral-400 ${\n isActive ? \"rotate-180 text-neutral-700\" : \"rotate-0\"\n }`}\n aria-hidden=\"true\"\n >\n <ChevronDownIcon className={currentSize.icon} />\n </span>\n );\n };\n\n const headerContainerClassNames = [\n \"w-full flex items-center justify-between transition-colors duration-150 select-none\",\n currentSize.header,\n currentSize.gap,\n disabled ? \"cursor-not-allowed opacity-60\" : currentHeaderBg,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const triggerButtonClassNames = [\n \"flex items-center flex-1 min-w-0 text-left outline-none cursor-pointer bg-transparent border-0 p-0\",\n currentSize.gap,\n disabled\n ? \"cursor-not-allowed pointer-events-none\"\n : `${currentColor.focusRing} focus-visible:ring-2 focus-visible:ring-offset-1 rounded-lg`,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={headerContainerClassNames}>\n <button\n ref={ref}\n id={headerId}\n type=\"button\"\n aria-expanded={isActive}\n aria-controls={panelId}\n aria-disabled={disabled ? true : undefined}\n disabled={disabled}\n onClick={(e) => {\n onToggle();\n onClick?.(e);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onToggle();\n }\n onKeyDown?.(e);\n }}\n className={triggerButtonClassNames}\n {...props}\n >\n {/* Left icon position */}\n {expandIconPosition === \"left\" && renderArrow()}\n\n {/* Start Icon + Label / Children + Description */}\n <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n {startIcon && (\n <span\n className={`inline-flex items-center justify-center shrink-0 ${currentColor.activeIndicator} ${currentSize.startIcon}`}\n aria-hidden=\"true\"\n >\n {startIcon}\n </span>\n )}\n <div className=\"flex flex-col min-w-0 flex-1\">\n <span className={`truncate ${currentSize.title} ${currentColor.title}`}>{children}</span>\n {description && (\n <span className={`line-clamp-2 ${currentSize.description}`}>{description}</span>\n )}\n </div>\n </div>\n\n {/* Right icon position when extra is absent */}\n {expandIconPosition === \"right\" && !extra && renderArrow()}\n </button>\n\n {/* Extra Actions / Slots */}\n {extra && (\n <div className=\"inline-flex items-center gap-2.5 shrink-0 ml-3\">\n {extra}\n {expandIconPosition === \"right\" && renderArrow()}\n </div>\n )}\n </div>\n );\n}\n","import { getSafeConfig } from \"@/utils/function\";\nimport { CollapseContentProps } from \"./types\";\nimport { useCollapseContext, useCollapsePanelContext } from \"./context\";\nimport { sizeConfig } from \"./constants\";\n\nexport default function CollapseContent({\n destroyInactivePanel: customDestroy,\n children,\n className = \"\",\n style,\n ref,\n ...props\n}: CollapseContentProps) {\n const { size, destroyInactivePanel: globalDestroy } = useCollapseContext();\n const { isActive, headerId, panelId } = useCollapsePanelContext();\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const shouldDestroy = customDestroy ?? globalDestroy;\n\n return (\n <div\n ref={ref}\n id={panelId}\n role=\"region\"\n aria-labelledby={headerId}\n aria-hidden={!isActive}\n data-state={isActive ? \"open\" : \"closed\"}\n className={`grid transition-[grid-template-rows] duration-200 ease-in-out ${\n isActive ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\"\n }`}\n style={style}\n {...props}\n >\n <div className=\"overflow-hidden\">\n {(!shouldDestroy || isActive) && (\n <div className={`${currentSize.content} ${className}`}>{children}</div>\n )}\n </div>\n </div>\n );\n}\r\n","import { useId, useState } from \"react\";\nimport { CollapsibleProps } from \"./types\";\n\nexport default function Collapsible({\n open: openProp,\n defaultOpen = false,\n destroyInactivePanel = false,\n className = \"\",\n children,\n ref,\n ...props\n}: CollapsibleProps) {\n const contentId = useId();\n\n const isControlled = openProp !== undefined;\n const [internalOpen] = useState(defaultOpen);\n const isOpen = isControlled ? openProp : internalOpen;\n\n return (\n <div\n ref={ref}\n id={contentId}\n role=\"region\"\n aria-hidden={!isOpen}\n data-state={isOpen ? \"open\" : \"closed\"}\n className={`grid transition-[grid-template-rows] duration-200 ease-in-out ${\n isOpen ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\"\n } ${className}`}\n {...props}\n >\n <div className=\"overflow-hidden\">{(!destroyInactivePanel || isOpen) && children}</div>\n </div>\n );\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { TabsProps } from \"./types\";\nimport { TabsContext } from \"./context\";\n\nexport default function Tabs({\n activeKey: activeKeyProp,\n defaultActiveKey,\n onChange,\n onClose,\n size = \"md\",\n variant = \"line\",\n color = \"primary\",\n radius = \"md\",\n orientation = \"horizontal\",\n placement = \"top\",\n fullWidth = false,\n disabled = false,\n destroyInactiveTabPane = false,\n className = \"\",\n children,\n ref,\n ...props\n}: TabsProps) {\n const isControlled = activeKeyProp !== undefined;\n const [internalActiveKey, setInternalActiveKey] = useState<string | number | undefined>(defaultActiveKey);\n\n const currentActiveKey = isControlled ? activeKeyProp : internalActiveKey;\n\n const handleActiveKeyChange = useCallback(\n (key: string | number) => {\n if (!isControlled) {\n setInternalActiveKey(key);\n }\n onChange?.(key);\n },\n [isControlled, onChange]\n );\n\n const handleClose = useCallback(\n (key: string | number) => {\n onClose?.(key);\n },\n [onClose]\n );\n\n const contextValue = useMemo(\n () => ({\n activeKey: currentActiveKey,\n setActiveKey: handleActiveKeyChange,\n size,\n variant,\n color,\n radius,\n orientation,\n placement,\n fullWidth,\n disabled,\n destroyInactiveTabPane,\n onCloseTab: handleClose,\n }),\n [\n currentActiveKey,\n handleActiveKeyChange,\n size,\n variant,\n color,\n radius,\n orientation,\n placement,\n fullWidth,\n disabled,\n destroyInactiveTabPane,\n handleClose,\n ]\n );\n\n // Orientation & Placement layout styles\n const isVertical = orientation === \"vertical\";\n let layoutClasses;\n\n if (isVertical) {\n layoutClasses =\n placement === \"right\" ? \"flex flex-row-reverse gap-4 items-start\" : \"flex flex-row gap-4 items-start\";\n } else {\n layoutClasses = placement === \"bottom\" ? \"flex flex-col-reverse gap-3\" : \"flex flex-col gap-3\";\n }\n\n const containerClasses = [\"w-full\", layoutClasses, className].filter(Boolean).join(\" \");\n\n return (\n <div ref={ref} className={containerClasses} {...props}>\n <TabsContext.Provider value={contextValue}>{children}</TabsContext.Provider>\n </div>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport { TabColor, TabOrientation, TabPlacement, TabRadius, TabSize, TabVariant } from \"./types\";\n\nexport interface TabsContextValue {\n activeKey: string | number | undefined;\n setActiveKey: (key: string | number) => void;\n size: TabSize;\n variant: TabVariant;\n color: TabColor;\n radius: TabRadius;\n orientation: TabOrientation;\n placement: TabPlacement;\n fullWidth: boolean;\n disabled: boolean;\n destroyInactiveTabPane: boolean;\n onCloseTab?: (key: string | number) => void;\n}\n\nexport const TabsContext = createContext<TabsContextValue | null>(null);\n\nexport function useTabsContext() {\n const context = useContext(TabsContext);\n if (!context) {\n throw new Error(\"Tabs compound components must be used within <Tabs>\");\n }\n return context;\n}\n","import { useMergeRefs } from \"@floating-ui/react\";\nimport { TabListProps } from \"./types\";\nimport { useTabsContext } from \"./context\";\nimport { radiusConfig, variantListConfig, indicatorConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { useTabIndicator } from \"./useTabIndicator\";\nimport ChevronLeftIcon from \"../icons/ChevronLeftIcon\";\nimport ChevronRightIcon from \"../icons/ChevronRightIcon\";\n\nexport default function TabList({ children, className = \"\", extra, centered = false, ref, ...props }: TabListProps) {\n const {\n activeKey,\n orientation = \"horizontal\",\n placement = \"top\",\n variant = \"line\",\n color = \"primary\",\n radius = \"md\",\n fullWidth = false,\n } = useTabsContext();\n\n const {\n listRef,\n indicatorStyle,\n canScrollLeft,\n canScrollRight,\n checkScroll,\n handleScrollLeft,\n handleScrollRight,\n handleKeyDown,\n } = useTabIndicator({ activeKey, orientation, placement, variant, color, radius });\n\n const mergedRef = useMergeRefs([listRef, ref]);\n\n const currentRadius = getSafeConfig(radius, radiusConfig, \"md\");\n const variantConfigFn = variant === \"other\" ? \"\" : getSafeConfig(variant, variantListConfig, \"line\");\n const variantClass = typeof variantConfigFn === \"function\" ? variantConfigFn(orientation, placement) : \"\";\n const currentIndicatorClass =\n variant === \"other\" ? \"\" : getSafeConfig(color, getSafeConfig(variant, indicatorConfig, \"line\"), \"primary\");\n\n const isVertical = orientation === \"vertical\";\n const hasOverflow = canScrollLeft || canScrollRight;\n\n const layoutClasses = isVertical\n ? \"flex flex-col items-stretch justify-start w-full\"\n : `flex flex-row items-center overflow-x-auto overflow-y-hidden [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden scroll-smooth ${\n fullWidth ? \"w-full\" : \"\"\n }`;\n\n const containerClasses = [\n \"relative flex-1 min-w-0\",\n layoutClasses,\n centered && !isVertical ? \"justify-center\" : \"\",\n variant !== \"line\" ? currentRadius : \"\",\n variantClass,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const indicatorClasses = [\n \"absolute pointer-events-none z-0 transition-all duration-300 ease-out\",\n variant !== \"line\" ? currentRadius : \"\",\n currentIndicatorClass,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const wrapperClasses = isVertical\n ? \"flex flex-col items-start gap-2 shrink-0 min-w-44\"\n : \"flex items-center justify-between gap-1 w-full min-w-0\";\n\n return (\n <div className={wrapperClasses}>\n {/* Scroll Left Chevron Button */}\n {!isVertical && hasOverflow && (\n <button\n type=\"button\"\n aria-label=\"Scroll tabs left\"\n disabled={!canScrollLeft}\n onClick={handleScrollLeft}\n className=\"shrink-0 flex items-center justify-center size-7 rounded-md text-neutral-500 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-neutral-100 hover:bg-neutral-100 dark:hover:bg-neutral-800 disabled:opacity-20 disabled:pointer-events-none transition-colors cursor-pointer focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-primary-500\"\n >\n <ChevronLeftIcon className=\"size-4\" />\n </button>\n )}\n\n <div\n ref={mergedRef}\n role=\"tablist\"\n aria-orientation={orientation}\n onKeyDown={handleKeyDown}\n onScroll={checkScroll}\n className={containerClasses}\n {...props}\n >\n {/* Animated Sliding Indicator / Pill */}\n <div aria-hidden=\"true\" className={indicatorClasses} style={indicatorStyle} />\n {children}\n </div>\n\n {/* Scroll Right Chevron Button */}\n {!isVertical && hasOverflow && (\n <button\n type=\"button\"\n aria-label=\"Scroll tabs right\"\n disabled={!canScrollRight}\n onClick={handleScrollRight}\n className=\"shrink-0 flex items-center justify-center size-7 rounded-md text-neutral-500 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-neutral-100 hover:bg-neutral-100 dark:hover:bg-neutral-800 disabled:opacity-20 disabled:pointer-events-none transition-colors cursor-pointer focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-primary-500\"\n >\n <ChevronRightIcon className=\"size-4\" />\n </button>\n )}\n\n {extra && <div className={isVertical ? \"w-full mt-1\" : \"shrink-0 ml-auto pl-1\"}>{extra}</div>}\n </div>\n );\n}\n","import { TabColor, TabOrientation, TabPlacement, TabRadius, TabSize, TabVariant } from \"./types\";\n\nexport const sizeConfig: Record<\n TabSize,\n {\n tab: string;\n icon: string;\n gap: string;\n badge: string;\n closeBtn: string;\n }\n> = {\n sm: {\n tab: \"px-3 py-1.5 text-xs font-medium\",\n icon: \"size-3.5\",\n gap: \"gap-1.5\",\n badge: \"text-[10px] px-1.5 py-0.5 min-w-4 h-4\",\n closeBtn: \"size-3.5 -mr-1 p-0.5\",\n },\n md: {\n tab: \"px-4 py-2 text-sm font-medium\",\n icon: \"size-4\",\n gap: \"gap-2\",\n badge: \"text-xs px-2 py-0.5 min-w-5 h-5\",\n closeBtn: \"size-4 -mr-1 p-0.5\",\n },\n lg: {\n tab: \"px-5 py-2.5 text-base font-medium\",\n icon: \"size-5\",\n gap: \"gap-2.5\",\n badge: \"text-xs px-2.5 py-0.5 min-w-5.5 h-5.5\",\n closeBtn: \"size-4.5 -mr-1.5 p-0.5\",\n },\n};\n\nexport const radiusConfig: Record<TabRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-md\",\n md: \"rounded-lg\",\n lg: \"rounded-xl\",\n xl: \"rounded-2xl\",\n full: \"rounded-full\",\n};\n\nexport const variantListConfig: Record<Exclude<TabVariant, \"other\">, (orientation: TabOrientation, placement: TabPlacement) => string> = {\n line: (orientation, placement) => {\n if (orientation === \"vertical\") {\n return placement === \"right\"\n ? \"border-l border-neutral-200 dark:border-neutral-800 gap-1\"\n : \"border-r border-neutral-200 dark:border-neutral-800 gap-1\";\n }\n return placement === \"bottom\"\n ? \"border-t border-neutral-200 dark:border-neutral-800 gap-2\"\n : \"border-b border-neutral-200 dark:border-neutral-800 gap-2\";\n },\n solid: () => \"bg-neutral-100 dark:bg-neutral-800/80 p-1 gap-1\",\n bordered: () =>\n \"border border-neutral-200 dark:border-neutral-700/80 p-1 gap-1 bg-neutral-50/50 dark:bg-neutral-900/50\",\n flat: () => \"bg-neutral-100/60 dark:bg-neutral-800/40 p-1 gap-1\",\n};\n\nexport const colorTabConfig: Record<\n TabColor,\n Record<Exclude<TabVariant, \"other\">, {\n active: string;\n inactive: string;\n }>\n> = {\n primary: {\n line: {\n active: \"text-primary-700 dark:text-primary-400 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-primary-600 dark:hover:text-primary-300\",\n },\n solid: {\n active: \"text-primary-700 dark:text-primary-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n bordered: {\n active: \"text-primary-700 dark:text-primary-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n flat: {\n active: \"text-primary-700 dark:text-primary-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-primary-700 dark:hover:text-primary-300\",\n },\n },\n secondary: {\n line: {\n active: \"text-secondary-700 dark:text-secondary-400 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-secondary-600 dark:hover:text-secondary-300\",\n },\n solid: {\n active: \"text-secondary-700 dark:text-secondary-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n bordered: {\n active: \"text-secondary-700 dark:text-secondary-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n flat: {\n active: \"text-secondary-700 dark:text-secondary-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-secondary-700 dark:hover:text-secondary-300\",\n },\n },\n neutral: {\n line: {\n active: \"text-neutral-950 dark:text-neutral-50 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-neutral-100\",\n },\n solid: {\n active: \"text-neutral-950 dark:text-neutral-50 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n bordered: {\n active: \"text-neutral-950 dark:text-neutral-50 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n flat: {\n active: \"text-neutral-950 dark:text-neutral-50 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-100\",\n },\n },\n error: {\n line: {\n active: \"text-error-700 dark:text-error-400 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-error-600 dark:hover:text-error-300\",\n },\n solid: {\n active: \"text-error-700 dark:text-error-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n bordered: {\n active: \"text-error-700 dark:text-error-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n flat: {\n active: \"text-error-700 dark:text-error-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-error-700 dark:hover:text-error-300\",\n },\n },\n success: {\n line: {\n active: \"text-success-700 dark:text-success-400 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-success-600 dark:hover:text-success-300\",\n },\n solid: {\n active: \"text-success-700 dark:text-success-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n bordered: {\n active: \"text-success-700 dark:text-success-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n flat: {\n active: \"text-success-700 dark:text-success-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-success-700 dark:hover:text-success-300\",\n },\n },\n warning: {\n line: {\n active: \"text-warning-700 dark:text-warning-400 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-warning-600 dark:hover:text-warning-300\",\n },\n solid: {\n active: \"text-warning-700 dark:text-warning-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n bordered: {\n active: \"text-warning-700 dark:text-warning-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n flat: {\n active: \"text-warning-700 dark:text-warning-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-warning-700 dark:hover:text-warning-300\",\n },\n },\n info: {\n line: {\n active: \"text-info-700 dark:text-info-400 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-info-600 dark:hover:text-info-300\",\n },\n solid: {\n active: \"text-info-700 dark:text-info-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n bordered: {\n active: \"text-info-700 dark:text-info-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200\",\n },\n flat: {\n active: \"text-info-700 dark:text-info-300 font-semibold\",\n inactive: \"text-neutral-600 dark:text-neutral-400 hover:text-info-700 dark:hover:text-info-300\",\n },\n },\n};\n\nexport const indicatorConfig: Record<Exclude<TabVariant, \"other\">, Record<TabColor, string>> = {\n line: {\n primary: \"bg-primary-600 dark:bg-primary-400\",\n secondary: \"bg-secondary-600 dark:bg-secondary-400\",\n neutral: \"bg-neutral-900 dark:bg-neutral-100\",\n error: \"bg-error-600 dark:bg-error-400\",\n success: \"bg-success-600 dark:bg-success-400\",\n warning: \"bg-warning-600 dark:bg-warning-400\",\n info: \"bg-info-600 dark:bg-info-400\",\n },\n solid: {\n primary: \"bg-white dark:bg-neutral-900 shadow-xs border border-neutral-200/70 dark:border-neutral-700/70\",\n secondary: \"bg-white dark:bg-neutral-900 shadow-xs border border-neutral-200/70 dark:border-neutral-700/70\",\n neutral: \"bg-white dark:bg-neutral-900 shadow-xs border border-neutral-200/70 dark:border-neutral-700/70\",\n error: \"bg-white dark:bg-neutral-900 shadow-xs border border-neutral-200/70 dark:border-neutral-700/70\",\n success: \"bg-white dark:bg-neutral-900 shadow-xs border border-neutral-200/70 dark:border-neutral-700/70\",\n warning: \"bg-white dark:bg-neutral-900 shadow-xs border border-neutral-200/70 dark:border-neutral-700/70\",\n info: \"bg-white dark:bg-neutral-900 shadow-xs border border-neutral-200/70 dark:border-neutral-700/70\",\n },\n bordered: {\n primary: \"bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-600 shadow-xs\",\n secondary: \"bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-600 shadow-xs\",\n neutral: \"bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-600 shadow-xs\",\n error: \"bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-600 shadow-xs\",\n success: \"bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-600 shadow-xs\",\n warning: \"bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-600 shadow-xs\",\n info: \"bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-600 shadow-xs\",\n },\n flat: {\n primary: \"bg-primary-100/90 dark:bg-primary-950/80\",\n secondary: \"bg-secondary-100/90 dark:bg-secondary-950/80\",\n neutral: \"bg-neutral-200/90 dark:bg-neutral-800\",\n error: \"bg-error-100/90 dark:bg-error-950/80\",\n success: \"bg-success-100/90 dark:bg-success-950/80\",\n warning: \"bg-warning-100/90 dark:bg-warning-950/80\",\n info: \"bg-info-100/90 dark:bg-info-950/80\",\n },\n};\n","import {\n CSSProperties,\n KeyboardEvent,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { TabColor, TabOrientation, TabPlacement, TabRadius, TabVariant } from \"./types\";\n\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Tùy chọn cấu hình cho hook `useTabIndicator`\n */\nexport interface UseTabIndicatorOptions {\n /**\n * Khóa định danh của tab đang active\n */\n activeKey?: string | number;\n\n /**\n * Chiều hiển thị tabs ('horizontal' | 'vertical')\n * @default 'horizontal'\n */\n orientation?: TabOrientation;\n\n /**\n * Vị trí đặt thanh tab list ('top' | 'bottom' | 'left' | 'right')\n * @default 'top'\n */\n placement?: TabPlacement;\n\n /**\n * Biến thể kiểu dáng của tab list\n * @default 'line'\n */\n variant?: TabVariant;\n\n /**\n * Chủ đề màu sắc\n * @default 'primary'\n */\n color?: TabColor;\n\n /**\n * Độ bo góc\n * @default 'md'\n */\n radius?: TabRadius;\n}\n\n/**\n * Custom hook quản lý tính toán toạ độ cho Sliding Tab Indicator,\n * tự động bắt sự kiện ResizeObserver/Window Resize, hỗ trợ cuộn tràn (overflow) và điều hướng bàn phím.\n */\nexport function useTabIndicator({\n activeKey,\n orientation = \"horizontal\",\n placement = \"top\",\n variant = \"line\",\n color = \"primary\",\n radius = \"md\",\n}: UseTabIndicatorOptions = {}) {\n const listRef = useRef<HTMLDivElement | null>(null);\n const [indicatorStyle, setIndicatorStyle] = useState<CSSProperties>({\n opacity: 0,\n });\n\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n // Kiểm tra trạng thái cuộn tràn viền (overflow) của danh sách tabs\n const checkScroll = useCallback(() => {\n if (!listRef.current || orientation === \"vertical\") {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n\n const { scrollLeft, scrollWidth, clientWidth } = listRef.current;\n const maxScroll = scrollWidth - clientWidth;\n\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft < maxScroll - 1);\n }, [orientation]);\n\n // Logic đo đạc & tính toán toạ độ vị trí cho indicator\n const updateIndicator = useCallback(() => {\n if (!listRef.current) return;\n\n checkScroll();\n\n const activeTab = listRef.current.querySelector<HTMLElement>(`[role=\"tab\"][aria-selected=\"true\"]`);\n\n if (!activeTab) {\n setIndicatorStyle((prev) => ({ ...prev, opacity: 0 }));\n return;\n }\n\n const measureTarget = activeTab.closest<HTMLElement>(\"[data-tab-wrapper]\") || activeTab;\n\n // Tự động cuộn tab active vào vùng nhìn thấy nếu bị tràn\n measureTarget.scrollIntoView({\n behavior: \"smooth\",\n block: \"nearest\",\n inline: \"nearest\",\n });\n\n const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = measureTarget;\n\n if (variant === \"line\") {\n if (orientation === \"vertical\") {\n setIndicatorStyle({\n transform: `translate3d(0, ${offsetTop}px, 0)`,\n height: `${offsetHeight}px`,\n width: \"2px\",\n top: 0,\n left: placement === \"right\" ? 0 : undefined,\n right: placement !== \"right\" ? 0 : undefined,\n opacity: 1,\n });\n } else {\n setIndicatorStyle({\n transform: `translate3d(${offsetLeft}px, 0, 0)`,\n width: `${offsetWidth}px`,\n height: \"2px\",\n left: 0,\n top: placement === \"bottom\" ? 0 : undefined,\n bottom: placement !== \"bottom\" ? 0 : undefined,\n opacity: 1,\n });\n }\n } else {\n // solid, flat, bordered\n setIndicatorStyle({\n transform: `translate3d(${offsetLeft}px, ${offsetTop}px, 0)`,\n width: `${offsetWidth}px`,\n height: `${offsetHeight}px`,\n top: 0,\n left: 0,\n opacity: 1,\n });\n }\n }, [checkScroll, orientation, placement, variant]);\n\n // Kích hoạt cập nhật vị trí khi activeKey hoặc cấu hình layout thay đổi\n useIsomorphicLayoutEffect(() => {\n updateIndicator();\n }, [updateIndicator, activeKey, variant, orientation, placement, color, radius]);\n\n // Đăng ký ResizeObserver và Window Resize Listener chỉ 1 lần duy nhất khi mount\n useIsomorphicLayoutEffect(() => {\n updateIndicator();\n const rafId = requestAnimationFrame(updateIndicator);\n\n const observer = new ResizeObserver(updateIndicator);\n if (listRef.current) {\n observer.observe(listRef.current);\n const tabElements = listRef.current.querySelectorAll(\"[data-tab-wrapper], [role='tab']\");\n for (const el of tabElements) {\n observer.observe(el);\n }\n }\n\n const handleResize = () => updateIndicator();\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n cancelAnimationFrame(rafId);\n observer.disconnect();\n window.removeEventListener(\"resize\", handleResize);\n };\n }, [updateIndicator]);\n\n const handleScrollLeft = () => {\n if (!listRef.current) return;\n listRef.current.scrollBy({ left: -200, behavior: \"smooth\" });\n };\n\n const handleScrollRight = () => {\n if (!listRef.current) return;\n listRef.current.scrollBy({ left: 200, behavior: \"smooth\" });\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (!listRef.current) return;\n\n const tabs = Array.from(listRef.current.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]:not([disabled])'));\n\n if (!tabs.length) return;\n\n const activeIndex = tabs.findIndex(\n (tab) => tab === document.activeElement || tab.getAttribute(\"aria-selected\") === \"true\"\n );\n\n let nextIndex = -1;\n\n const isHorizontal = orientation === \"horizontal\";\n const nextKey = isHorizontal ? \"ArrowRight\" : \"ArrowDown\";\n const prevKey = isHorizontal ? \"ArrowLeft\" : \"ArrowUp\";\n\n if (e.key === nextKey) {\n e.preventDefault();\n nextIndex = (activeIndex + 1) % tabs.length;\n } else if (e.key === prevKey) {\n e.preventDefault();\n nextIndex = (activeIndex - 1 + tabs.length) % tabs.length;\n } else if (e.key === \"Home\") {\n e.preventDefault();\n nextIndex = 0;\n } else if (e.key === \"End\") {\n e.preventDefault();\n nextIndex = tabs.length - 1;\n }\n\n if (nextIndex >= 0 && tabs[nextIndex]) {\n tabs[nextIndex]?.focus();\n tabs[nextIndex]?.click();\n }\n };\n\n return {\n listRef,\n indicatorStyle,\n canScrollLeft,\n canScrollRight,\n checkScroll,\n handleScrollLeft,\n handleScrollRight,\n handleKeyDown,\n };\n}\n\nexport default useTabIndicator;\n","import { useRef, MouseEvent, KeyboardEvent } from \"react\";\nimport { useMergeRefs } from \"@floating-ui/react\";\nimport { TabProps } from \"./types\";\nimport { useTabsContext } from \"./context\";\nimport { sizeConfig, radiusConfig, colorTabConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport CloseIcon from \"../icons/CloseIcon\";\n\nexport default function Tab({\n value,\n label,\n startIcon,\n endIcon,\n badge,\n disabled: itemDisabled = false,\n closable = false,\n onClose,\n className = \"\",\n children,\n onClick,\n onKeyDown,\n ref,\n ...props\n}: TabProps) {\n const {\n activeKey,\n setActiveKey,\n size,\n variant,\n color,\n radius,\n orientation,\n fullWidth,\n disabled: groupDisabled,\n onCloseTab,\n } = useTabsContext();\n\n const internalRef = useRef<HTMLButtonElement | null>(null);\n const mergedRef = useMergeRefs([internalRef, ref]);\n\n const isDisabled = groupDisabled || itemDisabled;\n const isActive = activeKey === value;\n\n const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n if (isDisabled) return;\n setActiveKey(value);\n onClick?.(e);\n };\n\n const handleClose = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (isDisabled) return;\n onClose?.(e);\n onCloseTab?.(value);\n };\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const currentRadius = getSafeConfig(radius, radiusConfig, \"md\");\n const colorVariantMap = getSafeConfig(color, colorTabConfig, \"primary\");\n const colorStyles = variant === \"other\" ? { active: \"\", inactive: \"\" } : getSafeConfig(variant, colorVariantMap, \"line\");\n\n const tabId = `tab-${value}`;\n const panelId = `tabpanel-${value}`;\n\n const stateClass = isActive ? colorStyles.active : colorStyles.inactive;\n const isVertical = orientation === \"vertical\";\n\n const containerClasses = [\n \"group relative z-10 inline-flex items-center select-none\",\n isVertical ? \"justify-start text-left w-full\" : \"justify-center text-center\",\n variant !== \"line\" ? currentRadius : \"\",\n fullWidth && !isVertical ? \"flex-1 text-center\" : \"\",\n isDisabled ? \"opacity-40 cursor-not-allowed pointer-events-none\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const tabButtonClasses = [\n \"inline-flex items-center cursor-pointer select-none bg-transparent\",\n isVertical ? \"justify-start text-left w-full\" : \"justify-center text-center\",\n \"transition-colors duration-200 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2\",\n variant !== \"line\" ? currentRadius : \"\",\n currentSize.tab,\n currentSize.gap,\n closable ? \"pr-1.5\" : \"\",\n fullWidth && !isVertical ? \"flex-1 text-center\" : \"\",\n stateClass,\n isDisabled ? \"opacity-40 cursor-not-allowed pointer-events-none\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (closable && (e.key === \"Delete\" || e.key === \"Backspace\")) {\n e.preventDefault();\n e.stopPropagation();\n if (isDisabled) return;\n onClose?.(e as unknown as MouseEvent<HTMLButtonElement>);\n onCloseTab?.(value);\n }\n onKeyDown?.(e);\n };\n\n return (\n <div data-tab-wrapper className={containerClasses}>\n <button\n ref={mergedRef}\n id={tabId}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={panelId}\n aria-disabled={isDisabled ? \"true\" : undefined}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n className={tabButtonClasses}\n {...props}\n >\n {startIcon && (\n <span\n className={`shrink-0 inline-flex items-center justify-center transition-colors duration-200 ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {startIcon}\n </span>\n )}\n\n <span className={`truncate ${isVertical ? \"flex-1 text-left\" : \"\"}`}>{label || children}</span>\n\n {badge !== undefined && badge !== null && (\n <span\n className={`inline-flex items-center justify-center font-medium rounded-full bg-neutral-200/80 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 transition-colors duration-200 ${currentSize.badge}`}\n >\n {badge}\n </span>\n )}\n\n {endIcon && (\n <span\n className={`shrink-0 inline-flex items-center justify-center transition-colors duration-200 ${currentSize.icon}`}\n aria-hidden=\"true\"\n >\n {endIcon}\n </span>\n )}\n </button>\n\n {closable && (\n <button\n type=\"button\"\n aria-label=\"Close tab\"\n disabled={isDisabled}\n tabIndex={isActive ? 0 : -1}\n onClick={handleClose}\n className={`shrink-0 cursor-pointer rounded-full hover:bg-neutral-200/80 dark:hover:bg-neutral-700 text-neutral-400 hover:text-neutral-700 dark:hover:text-neutral-200 transition-colors inline-flex items-center justify-center focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-primary-500 mr-2 ${currentSize.closeBtn}`}\n >\n <CloseIcon className=\"size-full pointer-events-none\" />\n </button>\n )}\n </div>\n );\n}\n","import { TabPanelsProps } from \"./types\";\n\nexport default function TabPanels({ children, className = \"\", ref, ...props }: TabPanelsProps) {\n return (\n <div ref={ref} className={`w-full ${className}`} {...props}>\n {children}\n </div>\n );\n}\n","import { TabPanelProps } from \"./types\";\nimport { useTabsContext } from \"./context\";\n\nexport default function TabPanel({\n value,\n children,\n className = \"\",\n destroyInactiveTabPane: itemDestroy,\n ref,\n ...props\n}: TabPanelProps) {\n const { activeKey, destroyInactiveTabPane: contextDestroy } = useTabsContext();\n\n const isActive = activeKey === value;\n const shouldDestroy = itemDestroy ?? contextDestroy;\n\n if (shouldDestroy && !isActive) {\n return null;\n }\n\n const tabId = `tab-${value}`;\n const panelId = `tabpanel-${value}`;\n\n const classes = [\"focus-visible:outline-hidden\", !isActive ? \"hidden\" : \"\", className].filter(Boolean).join(\" \");\n\n return (\n <div\n ref={ref}\n id={panelId}\n role=\"tabpanel\"\n tabIndex={0}\n aria-labelledby={tabId}\n hidden={!isActive}\n className={classes}\n {...props}\n >\n {children}\n </div>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport { CarouselContextValue } from \"./types\";\n\nexport const CarouselContext = createContext<CarouselContextValue | null>(null);\n\nexport function useCarouselContext() {\n const context = useContext(CarouselContext);\n if (!context) {\n throw new Error(\n \"Carousel compound components (CarouselContent, CarouselSlide, CarouselPrevious, CarouselNext, CarouselPagination) must be used within <Carousel>\"\n );\n }\n return context;\n}\n","import { useCallback, useEffect, useRef, useState, PointerEvent, KeyboardEvent } from \"react\";\nimport { CarouselContextValue, CarouselRadius, CarouselSize } from \"./types\";\n\nexport interface UseCarouselOptions {\n currentIndex?: number;\n defaultIndex?: number;\n onIndexChange?: (index: number) => void;\n loop?: boolean;\n slidesToShow?: number;\n slidesToScroll?: number;\n spacing?: number | string;\n autoPlay?: boolean;\n interval?: number;\n pauseOnHover?: boolean;\n pauseOnFocus?: boolean;\n draggable?: boolean;\n size?: CarouselSize;\n radius?: CarouselRadius;\n transitionDuration?: number;\n}\n\nexport function useCarousel({\n currentIndex: controlledIndex,\n defaultIndex = 0,\n onIndexChange,\n loop = false,\n slidesToShow = 1,\n slidesToScroll = 1,\n spacing = 0,\n autoPlay = true,\n interval = 3000,\n transitionDuration = 650,\n pauseOnHover = true,\n pauseOnFocus = true,\n draggable = true,\n size = \"md\",\n radius = \"md\",\n}: UseCarouselOptions = {}): CarouselContextValue {\n const [internalIndex, setInternalIndex] = useState<number>(defaultIndex);\n const [totalSlides, setTotalSlides] = useState<number>(0);\n const [isDragging, setIsDragging] = useState<boolean>(false);\n const [dragOffset, setDragOffset] = useState<number>(0);\n const [isHovered, setIsHovered] = useState<boolean>(false);\n const [isFocused, setIsFocused] = useState<boolean>(false);\n\n const registeredSlidesRef = useRef<Set<string>>(new Set());\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const dragStartPos = useRef<number>(0);\n const dragCurrentPos = useRef<number>(0);\n\n const isControlled = controlledIndex !== undefined;\n const activeIndex = isControlled ? controlledIndex : internalIndex;\n\n const maxIndex = Math.max(0, loop ? totalSlides - 1 : totalSlides - slidesToShow);\n\n const setIndex = useCallback(\n (newIndex: number) => {\n let targetIndex = newIndex;\n if (loop) {\n if (totalSlides > 0) {\n targetIndex = (targetIndex + totalSlides) % totalSlides;\n } else {\n targetIndex = 0;\n }\n } else {\n targetIndex = Math.max(0, Math.min(targetIndex, maxIndex));\n }\n\n if (!isControlled) {\n setInternalIndex(targetIndex);\n }\n onIndexChange?.(targetIndex);\n },\n [isControlled, loop, maxIndex, onIndexChange, totalSlides]\n );\n\n const canScrollPrev = loop ? totalSlides > 1 : activeIndex > 0;\n const canScrollNext = loop ? totalSlides > 1 : activeIndex < totalSlides - slidesToShow;\n\n const scrollPrev = useCallback(() => {\n if (canScrollPrev) {\n setIndex(activeIndex - slidesToScroll);\n }\n }, [activeIndex, canScrollPrev, setIndex, slidesToScroll]);\n\n const scrollNext = useCallback(() => {\n if (canScrollNext) {\n setIndex(activeIndex + slidesToScroll);\n }\n }, [activeIndex, canScrollNext, setIndex, slidesToScroll]);\n\n const scrollTo = useCallback(\n (index: number) => {\n setIndex(index);\n },\n [setIndex]\n );\n\n const registerSlide = useCallback((id: string) => {\n registeredSlidesRef.current.add(id);\n setTotalSlides(registeredSlidesRef.current.size);\n }, []);\n\n const unregisterSlide = useCallback((id: string) => {\n registeredSlidesRef.current.delete(id);\n setTotalSlides(registeredSlidesRef.current.size);\n }, []);\n\n // Autoplay Logic\n useEffect(() => {\n if (!autoPlay || totalSlides <= slidesToShow) return;\n if (pauseOnHover && isHovered) return;\n if (pauseOnFocus && isFocused) return;\n if (isDragging) return;\n\n const timer = setInterval(() => {\n if (loop || activeIndex < totalSlides - slidesToShow) {\n scrollNext();\n } else {\n scrollTo(0);\n }\n }, interval);\n\n return () => clearInterval(timer);\n }, [\n activeIndex,\n autoPlay,\n interval,\n isDragging,\n isFocused,\n isHovered,\n loop,\n pauseOnFocus,\n pauseOnHover,\n scrollNext,\n scrollTo,\n slidesToShow,\n totalSlides,\n ]);\n\n // Pointer / Drag Handling\n const handlePointerDown = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n if (!draggable || totalSlides <= slidesToShow) return;\n if (e.button !== 0) return; // Only main button\n\n const clientPos = e.clientX;\n dragStartPos.current = clientPos;\n dragCurrentPos.current = clientPos;\n setIsDragging(true);\n setDragOffset(0);\n\n const target = e.currentTarget;\n try {\n target.setPointerCapture(e.pointerId);\n } catch {\n // Fallback for environments where setPointerCapture isn't supported\n }\n },\n [draggable, slidesToShow, totalSlides]\n );\n\n const handlePointerMove = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n if (!isDragging) return;\n const clientPos = e.clientX;\n dragCurrentPos.current = clientPos;\n const offset = clientPos - dragStartPos.current;\n\n // Resistance at edges when not in loop\n if (!loop) {\n if (activeIndex === 0 && offset > 0) {\n setDragOffset(offset * 0.3);\n return;\n }\n if (activeIndex >= totalSlides - slidesToShow && offset < 0) {\n setDragOffset(offset * 0.3);\n return;\n }\n }\n\n setDragOffset(offset);\n },\n [activeIndex, isDragging, loop, slidesToShow, totalSlides]\n );\n\n const handlePointerEnd = useCallback(\n (e: PointerEvent<HTMLDivElement>) => {\n if (!isDragging) return;\n setIsDragging(false);\n\n const delta = dragCurrentPos.current - dragStartPos.current;\n const threshold = 40; // minimum drag distance in pixels to trigger slide transition\n\n if (Math.abs(delta) > threshold) {\n if (delta > 0) {\n scrollPrev();\n } else {\n scrollNext();\n }\n }\n\n setDragOffset(0);\n\n try {\n e.currentTarget.releasePointerCapture(e.pointerId);\n } catch {\n // Fallback\n }\n },\n [isDragging, scrollNext, scrollPrev]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n scrollPrev();\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault();\n scrollNext();\n } else if (e.key === \"Home\") {\n e.preventDefault();\n scrollTo(0);\n } else if (e.key === \"End\") {\n e.preventDefault();\n scrollTo(maxIndex);\n }\n },\n [maxIndex, scrollNext, scrollPrev, scrollTo]\n );\n\n const handleMouseEnter = useCallback(() => setIsHovered(true), []);\n const handleMouseLeave = useCallback(() => setIsHovered(false), []);\n const handleFocus = useCallback(() => setIsFocused(true), []);\n const handleBlur = useCallback(() => setIsFocused(false), []);\n\n return {\n currentIndex: activeIndex,\n totalSlides,\n slidesToShow,\n slidesToScroll,\n spacing,\n loop,\n canScrollPrev,\n canScrollNext,\n size,\n radius,\n transitionDuration,\n isDragging,\n dragOffset,\n scrollPrev,\n scrollNext,\n scrollTo,\n registerSlide,\n unregisterSlide,\n setTotalSlides,\n viewportRef,\n containerRef,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp: handlePointerEnd,\n handlePointerCancel: handlePointerEnd,\n handleKeyDown,\n handleMouseEnter,\n handleMouseLeave,\n handleFocus,\n handleBlur,\n };\n}\n","import { CarouselNavigationVariant, CarouselRadius, CarouselSize } from \"./types\";\n\nexport const sizeConfig: Record<\n CarouselSize,\n {\n arrowBtn: string;\n arrowIcon: string;\n dot: string;\n activeDot: string;\n line: string;\n activeLine: string;\n fraction: string;\n paginationWrapper: string;\n edgeInset: string;\n }\n> = {\n sm: {\n arrowBtn: \"size-6 p-0.5 text-xs\",\n arrowIcon: \"size-3\",\n dot: \"size-1.5\",\n activeDot: \"size-1.5\",\n line: \"w-3.5 h-1\",\n activeLine: \"w-6 h-1\",\n fraction: \"text-xs px-2 py-0.5\",\n paginationWrapper: \"px-2 py-1 gap-1.5\",\n edgeInset: \"left-1.5 right-1.5\",\n },\n md: {\n arrowBtn: \"size-8 p-1.5 text-sm\",\n arrowIcon: \"size-3.5\",\n dot: \"size-2\",\n activeDot: \"size-2\",\n line: \"w-5 h-1.5\",\n activeLine: \"w-8 h-1.5\",\n fraction: \"text-xs px-2.5 py-0.5 font-medium\",\n paginationWrapper: \"px-2.5 py-1 gap-2\",\n edgeInset: \"left-2 right-2\",\n },\n lg: {\n arrowBtn: \"size-9 p-2 text-sm\",\n arrowIcon: \"size-4\",\n dot: \"size-2.5\",\n activeDot: \"size-2.5\",\n line: \"w-7 h-2\",\n activeLine: \"w-11 h-2\",\n fraction: \"text-sm px-3 py-1 font-medium\",\n paginationWrapper: \"px-3 py-1.5 gap-2.5\",\n edgeInset: \"left-2.5 right-2.5\",\n },\n};\n\nexport const radiusConfig: Record<CarouselRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\n/**\n * Kiểu nút điều hướng (Mặc định là kính mờ \"glass\")\n */\nexport const navVariantConfig: Record<CarouselNavigationVariant, string> = {\n glass:\n \"bg-white/40 dark:bg-black/35 backdrop-blur-md border border-white/40 dark:border-white/15 text-primary-950 dark:text-white shadow-md hover:bg-white/70 dark:hover:bg-black/60 active:scale-90 disabled:opacity-25 disabled:pointer-events-none\",\n filled:\n \"bg-primary-600 text-white shadow-md hover:bg-primary-700 active:bg-primary-800 disabled:bg-neutral-300 dark:disabled:bg-neutral-800 disabled:text-neutral-500 disabled:opacity-50\",\n outline:\n \"border border-primary-600 text-primary-600 bg-white/70 dark:bg-neutral-900/70 backdrop-blur-sm hover:bg-primary-50 dark:hover:bg-primary-950 disabled:border-neutral-300 disabled:text-neutral-400\",\n ghost:\n \"text-primary-600 hover:bg-primary-100/60 dark:hover:bg-primary-950/60 active:bg-primary-200/60 disabled:text-neutral-400\",\n};\n\n/**\n * Phong cách kính mờ cho thanh phân trang (Pagination Wrapper)\n */\nexport const glassPaginationWrapper =\n \"bg-black/25 dark:bg-white/15 backdrop-blur-md border border-white/20 dark:border-white/15 shadow-sm rounded-full\";\n\n/**\n * Màu sắc chuẩn Primary cho Dots / Lines\n */\nexport const dotStyleConfig = {\n active: \"bg-primary-600 dark:bg-primary-400 shadow-sm\",\n inactive: \"bg-white/60 dark:bg-white/40 hover:bg-white/90 dark:hover:bg-white/70 transition-colors\",\n};\n","import { getSafeConfig } from \"@/utils/function\";\nimport { CarouselProps } from \"./types\";\nimport { CarouselContext } from \"./context\";\nimport { useCarousel } from \"./useCarousel\";\nimport { radiusConfig } from \"./constants\";\n\nexport function Carousel({\n currentIndex,\n defaultIndex = 0,\n onIndexChange,\n loop = false,\n slidesToShow = 1,\n slidesToScroll = 1,\n spacing = 0,\n autoPlay = true,\n interval = 3000,\n transitionDuration = 650,\n pauseOnHover = true,\n pauseOnFocus = true,\n draggable = true,\n size = \"md\",\n radius = \"md\",\n children,\n className = \"\",\n style,\n ref,\n ...props\n}: CarouselProps) {\n const carousel = useCarousel({\n currentIndex,\n defaultIndex,\n onIndexChange,\n loop,\n slidesToShow,\n slidesToScroll,\n spacing,\n autoPlay,\n interval,\n transitionDuration,\n pauseOnHover,\n pauseOnFocus,\n draggable,\n size,\n radius,\n });\n\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n\n return (\n <CarouselContext.Provider value={carousel}>\n <div\n ref={ref}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Băng chuyền\"\n tabIndex={0}\n onKeyDown={carousel.handleKeyDown}\n onMouseEnter={carousel.handleMouseEnter}\n onMouseLeave={carousel.handleMouseLeave}\n onFocus={carousel.handleFocus}\n onBlur={carousel.handleBlur}\n className={`relative overflow-hidden group focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${roundedClass} ${className}`}\n style={style}\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n}\n","import { CSSProperties } from \"react\";\nimport { CarouselContentProps } from \"./types\";\nimport { useCarouselContext } from \"./context\";\n\nexport function CarouselContent({ children, className = \"\", style, ref, ...props }: CarouselContentProps) {\n const {\n currentIndex,\n slidesToShow,\n spacing,\n transitionDuration,\n isDragging,\n dragOffset,\n viewportRef,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n handlePointerCancel,\n } = useCarouselContext();\n\n const spacingValue = typeof spacing === \"number\" ? `${spacing}px` : spacing || \"0px\";\n\n const transformStyle = `translateX(calc(-${currentIndex} * ((100% + ${spacingValue}) / ${slidesToShow}) + ${dragOffset}px))`;\n\n const trackStyle: CSSProperties = {\n display: \"flex\",\n flexDirection: \"row\",\n gap: spacingValue,\n transform: transformStyle,\n transition: isDragging ? \"none\" : `transform ${transitionDuration}ms cubic-bezier(0.25, 1, 0.5, 1)`,\n touchAction: \"pan-y\",\n width: \"100%\",\n };\n\n return (\n <div\n ref={viewportRef}\n className={`overflow-hidden relative w-full h-full cursor-grab ${\n isDragging ? \"cursor-grabbing select-none\" : \"\"\n }`}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerCancel}\n >\n <div\n ref={ref}\n role=\"presentation\"\n className={`flex ${className}`}\n style={{\n ...trackStyle,\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n </div>\n );\n}\n","import { useId, useEffect, CSSProperties } from \"react\";\nimport { CarouselSlideProps } from \"./types\";\nimport { useCarouselContext } from \"./context\";\n\nexport function CarouselSlide({ children, className = \"\", style, ref, ...props }: CarouselSlideProps) {\n const generatedId = useId();\n const { slidesToShow, spacing, registerSlide, unregisterSlide } = useCarouselContext();\n\n useEffect(() => {\n registerSlide(generatedId);\n return () => {\n unregisterSlide(generatedId);\n };\n }, [generatedId, registerSlide, unregisterSlide]);\n\n const spacingValue = typeof spacing === \"number\" ? `${spacing}px` : spacing || \"0px\";\n\n const slideStyle: CSSProperties = {\n ...style,\n };\n\n if (slidesToShow > 1 || spacingValue !== \"0px\") {\n slideStyle.flex = `0 0 calc((100% - ${slidesToShow - 1} * ${spacingValue}) / ${slidesToShow})`;\n } else {\n slideStyle.flex = \"0 0 100%\";\n }\n\n const baseClasses = \"min-w-0 shrink-0 grow-0 select-none box-border relative overflow-hidden\";\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-roledescription=\"slide\"\n className={`${baseClasses} ${className}`}\n style={slideStyle}\n {...props}\n >\n {children}\n </div>\n );\n}\n","import { getSafeConfig } from \"@/utils/function\";\nimport ChevronLeftIcon from \"@/components/icons/ChevronLeftIcon\";\nimport ChevronRightIcon from \"@/components/icons/ChevronRightIcon\";\nimport { CarouselNavigationProps } from \"./types\";\nimport { useCarouselContext } from \"./context\";\nimport { navVariantConfig, sizeConfig } from \"./constants\";\n\nexport function CarouselPrevious({\n variant = \"glass\",\n icon,\n className = \"\",\n disabled,\n onClick,\n ref,\n ...props\n}: CarouselNavigationProps) {\n const { scrollPrev, canScrollPrev, size } = useCarouselContext();\n\n const isDisabled = disabled !== undefined ? disabled : !canScrollPrev;\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const variantStyles = getSafeConfig(variant, navVariantConfig, \"glass\");\n\n const defaultIcon = <ChevronLeftIcon className={currentSize.arrowIcon} />;\n\n const previousClassNames = [\n \"absolute left-2 top-1/2 -translate-y-1/2 inline-flex items-center justify-center font-medium leading-none rounded-full transition-all duration-200 cursor-pointer select-none outline-none disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-25 focus-visible:ring-2 focus-visible:ring-primary-500/50 active:scale-90 z-10\",\n variantStyles,\n currentSize.arrowBtn,\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Slide trước\"\n disabled={isDisabled}\n onClick={(e) => {\n scrollPrev();\n onClick?.(e);\n }}\n className={previousClassNames}\n {...props}\n >\n {icon || defaultIcon}\n </button>\n );\n}\n\nexport function CarouselNext({\n variant = \"glass\",\n icon,\n className = \"\",\n disabled,\n onClick,\n ref,\n ...props\n}: CarouselNavigationProps) {\n const { scrollNext, canScrollNext, size } = useCarouselContext();\n\n const isDisabled = disabled !== undefined ? disabled : !canScrollNext;\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const variantStyles = getSafeConfig(variant, navVariantConfig, \"glass\");\n\n const defaultIcon = <ChevronRightIcon className={currentSize.arrowIcon} />;\n\n const nextClassNames = [\n \"absolute right-2 top-1/2 -translate-y-1/2 inline-flex items-center justify-center font-medium leading-none rounded-full transition-all duration-200 cursor-pointer select-none outline-none disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-25 focus-visible:ring-2 focus-visible:ring-primary-500/50 active:scale-90 z-10\",\n variantStyles,\n currentSize.arrowBtn,\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-label=\"Slide tiếp theo\"\n disabled={isDisabled}\n onClick={(e) => {\n scrollNext();\n onClick?.(e);\n }}\n className={nextClassNames}\n {...props}\n >\n {icon || defaultIcon}\n </button>\n );\n}\n","import { getSafeConfig } from \"@/utils/function\";\nimport { CarouselPaginationProps } from \"./types\";\nimport { useCarouselContext } from \"./context\";\nimport { dotStyleConfig, glassPaginationWrapper, sizeConfig } from \"./constants\";\n\nexport function CarouselPagination({\n type = \"dots\",\n clickable = true,\n className = \"\",\n ref,\n ...props\n}: CarouselPaginationProps) {\n const { currentIndex, totalSlides, slidesToShow, loop, scrollTo, size } = useCarouselContext();\n\n if (type === \"none\" || totalSlides <= 1) return null;\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n const pageCount = loop ? totalSlides : Math.max(1, totalSlides - slidesToShow + 1);\n\n if (type === \"fraction\") {\n return (\n <div\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n className={`absolute z-10 bottom-2.5 left-1/2 -translate-x-1/2 inline-flex items-center justify-center font-medium ${glassPaginationWrapper} text-white ${\n currentSize.fraction\n } ${className}`}\n {...props}\n >\n <span>\n {Math.min(currentIndex + 1, pageCount)} / {pageCount}\n </span>\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n role=\"tablist\"\n aria-label=\"Phân trang băng chuyền\"\n className={`absolute z-10 bottom-2.5 left-1/2 -translate-x-1/2 inline-flex items-center justify-center ${glassPaginationWrapper} ${\n currentSize.paginationWrapper\n } ${className}`}\n {...props}\n >\n {Array.from({ length: pageCount }).map((_, index) => {\n const isActive = index === currentIndex;\n\n if (type === \"line\") {\n return (\n <button\n key={index}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n aria-label={`Chuyển đến slide ${index + 1}`}\n disabled={!clickable}\n onClick={() => clickable && scrollTo(index)}\n className={`transition-all duration-300 rounded-full outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${\n isActive\n ? `${currentSize.activeLine} ${dotStyleConfig.active}`\n : `${currentSize.line} ${dotStyleConfig.inactive}`\n } ${clickable ? \"cursor-pointer\" : \"cursor-default\"}`}\n />\n );\n }\n\n // Default: dots (giữ nguyên kích thước tròn, chỉ đổi màu sang primary khi active)\n return (\n <button\n key={index}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n aria-label={`Chuyển đến slide ${index + 1}`}\n disabled={!clickable}\n onClick={() => clickable && scrollTo(index)}\n className={`transition-colors duration-200 rounded-full outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${\n currentSize.dot\n } ${\n isActive ? dotStyleConfig.active : dotStyleConfig.inactive\n } ${clickable ? \"cursor-pointer\" : \"cursor-default\"}`}\n />\n );\n })}\n </div>\n );\n}\n","import React, { useState, useRef, useMemo, useCallback } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useClick,\n useHover,\n useDismiss,\n useRole,\n useListNavigation,\n useTypeahead,\n useInteractions,\n safePolygon,\n} from \"@floating-ui/react\";\nimport { DropdownProps, DropdownContextValue } from \"./types\";\nimport { DropdownContext } from \"./context\";\n\nexport default function Dropdown({\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n trigger = \"click\",\n placement = \"bottom-start\",\n offset = 4,\n flip = true,\n shift = true,\n size = \"md\",\n radius = \"md\",\n color = \"primary\",\n disabled = false,\n animated = true,\n animationDuration = 150,\n closeOnSelect = true,\n}: DropdownProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n\n const elementsRef = useRef<(HTMLElement | null)[]>([]);\n const labelsRef = useRef<(string | null)[]>([]);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : uncontrolledOpen;\n\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n if (!isControlled) {\n setUncontrolledOpen(nextOpen);\n }\n if (!nextOpen) {\n setActiveIndex(null);\n }\n onOpenChange?.(nextOpen);\n },\n [isControlled, onOpenChange]\n );\n\n const middleware = useMemo(\n () =>\n [\n offsetMiddleware(offset),\n flip ? flipMiddleware() : undefined,\n shift ? shiftMiddleware({ padding: 8 }) : undefined,\n ].filter(Boolean),\n [offset, flip, shift]\n );\n\n const {\n refs,\n floatingStyles,\n context,\n placement: computedPlacement,\n } = useFloating({\n placement,\n open: isOpen && !disabled,\n onOpenChange: handleOpenChange,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware,\n });\n\n const click = useClick(context, {\n enabled: !disabled && trigger === \"click\",\n });\n\n const hover = useHover(context, {\n enabled: !disabled && trigger === \"hover\",\n delay: { open: 100, close: 150 },\n handleClose: safePolygon(),\n });\n\n const dismiss = useDismiss(context);\n const role = useRole(context, { role: \"menu\" });\n\n const listNavigation = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const typeahead = useTypeahead(context, {\n listRef: labelsRef,\n activeIndex,\n onMatch: isOpen ? setActiveIndex : undefined,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([\n click,\n hover,\n dismiss,\n role,\n listNavigation,\n typeahead,\n ]);\n\n const contextValue: DropdownContextValue = useMemo(\n () => ({\n isOpen,\n setIsOpen: handleOpenChange,\n refs,\n floatingStyles,\n context,\n getReferenceProps,\n getFloatingProps,\n getItemProps,\n elementsRef,\n labelsRef,\n activeIndex,\n setActiveIndex,\n size,\n radius,\n color,\n disabled,\n animated,\n animationDuration,\n closeOnSelect,\n computedPlacement,\n }),\n [\n isOpen,\n handleOpenChange,\n refs,\n floatingStyles,\n context,\n getReferenceProps,\n getFloatingProps,\n getItemProps,\n elementsRef,\n labelsRef,\n activeIndex,\n setActiveIndex,\n size,\n radius,\n color,\n disabled,\n animated,\n animationDuration,\n closeOnSelect,\n computedPlacement,\n ]\n );\n\n return <DropdownContext.Provider value={contextValue}>{children}</DropdownContext.Provider>;\n}\n","import { createContext, useContext } from \"react\";\nimport { DropdownContextValue } from \"./types\";\n\nexport const DropdownContext = createContext<DropdownContextValue | null>(null);\n\nexport const useDropdownContext = (): DropdownContextValue => {\n const context = useContext(DropdownContext);\n if (!context) {\n throw new Error(\"Dropdown compound components must be used within a <Dropdown> component.\");\n }\n return context;\n};\n","import React, { cloneElement, isValidElement, ReactNode, HTMLAttributes } from \"react\";\nimport { useDropdownContext } from \"./context\";\nimport { DropdownTriggerProps } from \"./types\";\nimport { useMergeRefs } from \"@floating-ui/react\";\n\ninterface SlotProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode;\n disabled?: boolean;\n}\n\nfunction Slot({\n children,\n ref: forwardedRef,\n disabled,\n className = \"\",\n ...props\n}: SlotProps & { ref?: React.Ref<HTMLElement> }) {\n const childRef = isValidElement(children)\n ? (children.props as { ref?: React.Ref<HTMLElement> })?.ref\n : undefined;\n\n const mergedChildRef = useMergeRefs([forwardedRef, childRef]);\n\n if (!isValidElement<Record<string, unknown>>(children)) {\n return null;\n }\n\n const childProps = (children.props || {}) as {\n className?: string;\n disabled?: boolean;\n [key: string]: unknown;\n };\n\n return cloneElement(children, {\n ...props,\n ...childProps,\n ref: mergedChildRef,\n disabled: disabled ? true : childProps.disabled,\n className: [childProps.className, className].filter(Boolean).join(\" \"),\n });\n}\n\nexport function DropdownTrigger({\n ref: propRef,\n children,\n className = \"\",\n asChild = false,\n ...rest\n}: DropdownTriggerProps) {\n const { refs, getReferenceProps, isOpen, disabled } = useDropdownContext();\n const mergedRef = useMergeRefs([refs.setReference, propRef]);\n\n const triggerProps = getReferenceProps({\n ...rest,\n \"aria-expanded\": isOpen,\n \"aria-haspopup\": \"menu\",\n className,\n });\n\n if (isValidElement(children) && (asChild || true)) {\n return (\n <Slot ref={mergedRef} disabled={disabled} {...triggerProps}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={mergedRef}\n type=\"button\"\n disabled={disabled}\n aria-expanded={isOpen}\n aria-haspopup=\"menu\"\n className={className}\n {...triggerProps}\n >\n {children}\n </button>\n );\n}\n\nexport default DropdownTrigger;\n","import React from \"react\";\nimport { FloatingPortal, FloatingList, useTransitionStyles, useMergeRefs } from \"@floating-ui/react\";\nimport { useDropdownContext } from \"./context\";\nimport { DropdownMenuProps } from \"./types\";\nimport { sizeConfig, radiusConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\n\nexport default function DropdownMenu({\n ref: propRef,\n children,\n className = \"\",\n style,\n minWidth,\n zIndex = DEFAULT_Z_INDEX.DROPDOWN,\n ...rest\n}: DropdownMenuProps) {\n const {\n isOpen,\n refs,\n floatingStyles,\n context,\n getFloatingProps,\n elementsRef,\n labelsRef,\n size,\n radius,\n animated,\n animationDuration,\n computedPlacement,\n } = useDropdownContext();\n\n const mergedRef = useMergeRefs([refs.setFloating, propRef]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: animated ? animationDuration : 0,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n if (!isMounted) {\n return null;\n }\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n\n const menuClassNames = [\n \"bg-neutral-white border-2 border-neutral-200 shadow-lg outline-none focus:outline-none flex flex-col\",\n currentSize.menu,\n roundedClass,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <FloatingPortal>\n <div\n ref={mergedRef}\n style={{\n ...floatingStyles,\n ...(animated ? transitionStyles : {}),\n minWidth: minWidth,\n zIndex,\n ...style,\n }}\n className={menuClassNames}\n data-state={isOpen ? \"open\" : \"closed\"}\n data-placement={computedPlacement}\n {...getFloatingProps(rest)}\n >\n <FloatingList elementsRef={elementsRef} labelsRef={labelsRef}>\n {children}\n </FloatingList>\n </div>\n </FloatingPortal>\n );\n}\n","import { DropdownSize, DropdownRadius, DropdownColor } from \"./types\";\n\nexport const sizeConfig: Record<\n DropdownSize,\n {\n menu: string;\n item: string;\n itemGap: string;\n icon: string;\n header: string;\n description: string;\n shortcut: string;\n }\n> = {\n xs: {\n menu: \"p-1 min-w-36 text-xs\",\n item: \"px-2 py-1 text-xs rounded\",\n itemGap: \"gap-1.5\",\n icon: \"size-3.5\",\n header: \"px-2 py-1 text-[10px]\",\n description: \"text-[10px]\",\n shortcut: \"text-[10px] px-1 py-0.5\",\n },\n sm: {\n menu: \"p-1.5 min-w-44 text-xs\",\n item: \"px-2.5 py-1.5 text-xs rounded-md\",\n itemGap: \"gap-2\",\n icon: \"size-4\",\n header: \"px-2.5 py-1 text-xs\",\n description: \"text-[11px]\",\n shortcut: \"text-[11px] px-1.5 py-0.5\",\n },\n md: {\n menu: \"p-1.5 min-w-52 text-sm\",\n item: \"px-3 py-2 text-sm rounded-lg\",\n itemGap: \"gap-2.5\",\n icon: \"size-4.5\",\n header: \"px-3 py-1.5 text-xs\",\n description: \"text-xs\",\n shortcut: \"text-xs px-1.5 py-0.5\",\n },\n lg: {\n menu: \"p-2 min-w-60 text-base\",\n item: \"px-3.5 py-2.5 text-base rounded-xl\",\n itemGap: \"gap-3\",\n icon: \"size-5\",\n header: \"px-3.5 py-1.5 text-sm\",\n description: \"text-sm\",\n shortcut: \"text-sm px-2 py-0.5\",\n },\n xl: {\n menu: \"p-2.5 min-w-72 text-lg\",\n item: \"px-4 py-3 text-lg rounded-2xl\",\n itemGap: \"gap-3.5\",\n icon: \"size-6\",\n header: \"px-4 py-2 text-base\",\n description: \"text-base\",\n shortcut: \"text-base px-2 py-1\",\n },\n};\n\nexport const radiusConfig: Record<DropdownRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-xl\",\n xl: \"rounded-2xl\",\n full: \"rounded-3xl\",\n};\n\nexport const colorConfig: Record<\n DropdownColor,\n {\n active: string;\n selected: string;\n focus: string;\n }\n> = {\n primary: {\n active: \"bg-primary-50 text-primary-900\",\n selected: \"bg-primary-100 text-primary-900 font-medium\",\n focus: \"focus:bg-primary-50 focus:text-primary-900\",\n },\n secondary: {\n active: \"bg-secondary-50 text-secondary-900\",\n selected: \"bg-secondary-100 text-secondary-900 font-medium\",\n focus: \"focus:bg-secondary-50 focus:text-secondary-900\",\n },\n neutral: {\n active: \"bg-neutral-100 text-neutral-900\",\n selected: \"bg-neutral-200 text-neutral-900 font-medium\",\n focus: \"focus:bg-neutral-100 focus:text-neutral-900\",\n },\n error: {\n active: \"bg-error-50 text-error-900\",\n selected: \"bg-error-100 text-error-900 font-medium\",\n focus: \"focus:bg-error-50 focus:text-error-900\",\n },\n success: {\n active: \"bg-success-50 text-success-900\",\n selected: \"bg-success-100 text-success-900 font-medium\",\n focus: \"focus:bg-success-50 focus:text-success-900\",\n },\n warning: {\n active: \"bg-warning-50 text-warning-900\",\n selected: \"bg-warning-100 text-warning-900 font-medium\",\n focus: \"focus:bg-warning-50 focus:text-warning-900\",\n },\n info: {\n active: \"bg-info-50 text-info-900\",\n selected: \"bg-info-100 text-info-900 font-medium\",\n focus: \"focus:bg-info-50 focus:text-info-900\",\n },\n};\n\nexport const dangerStyles = {\n default: \"text-error-600 hover:bg-error-50 hover:text-error-700\",\n active: \"bg-error-50 text-error-700\",\n focus: \"focus:bg-error-50 focus:text-error-700\",\n};\n","import React from \"react\";\nimport { useListItem, useMergeRefs } from \"@floating-ui/react\";\nimport { useDropdownContext } from \"./context\";\nimport { DropdownItemProps } from \"./types\";\nimport { sizeConfig, colorConfig, dangerStyles } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport function DropdownItem({\n ref: propRef,\n children,\n onClick,\n disabled = false,\n danger = false,\n selected = false,\n startIcon,\n endIcon,\n shortcut,\n description,\n className = \"\",\n closeOnSelect: itemCloseOnSelect,\n ...rest\n}: DropdownItemProps) {\n const { getItemProps, activeIndex, setIsOpen, color, size, closeOnSelect: rootCloseOnSelect } = useDropdownContext();\n\n const label = typeof children === \"string\" ? children : undefined;\n const { ref: listItemRef, index } = useListItem({ label });\n const mergedRef = useMergeRefs([listItemRef, propRef]);\n\n const isActive = activeIndex === index;\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, colorConfig, \"primary\");\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n onClick?.(e);\n const shouldClose = itemCloseOnSelect ?? rootCloseOnSelect;\n if (shouldClose) {\n setIsOpen(false);\n }\n };\n\n const stateClasses = disabled\n ? \"opacity-50 cursor-not-allowed text-neutral-400 select-none\"\n : danger\n ? `${dangerStyles.default} ${isActive ? dangerStyles.active : \"\"} cursor-pointer`\n : selected\n ? `${colorStyles.selected} cursor-pointer`\n : `${isActive ? colorStyles.active : \"text-neutral-700 hover:bg-neutral-100 hover:text-neutral-900\"} cursor-pointer`;\n\n const itemClasses = [\n \"w-full text-left flex items-center select-none transition-colors duration-100 outline-none focus:outline-none\",\n currentSize.item,\n currentSize.itemGap,\n stateClasses,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <button\n ref={mergedRef}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n aria-disabled={disabled}\n tabIndex={isActive ? 0 : -1}\n {...getItemProps({\n ...rest,\n onClick: handleClick,\n className: itemClasses,\n })}\n >\n {startIcon && (\n <span className={`flex items-center justify-center shrink-0 ${currentSize.icon}`}>{startIcon}</span>\n )}\n <div className=\"flex-1 flex flex-col min-w-0\">\n <span className=\"truncate\">{children}</span>\n {description && <span className={`text-neutral-500 truncate ${currentSize.description}`}>{description}</span>}\n </div>\n {shortcut && (\n <kbd\n className={`shrink-0 rounded border border-neutral-200 bg-neutral-50 font-mono text-neutral-500 tracking-wider ${currentSize.shortcut}`}\n >\n {shortcut}\n </kbd>\n )}\n {endIcon && <span className={`flex items-center justify-center shrink-0 ${currentSize.icon}`}>{endIcon}</span>}\n </button>\n );\n}\n\nexport default DropdownItem;\n","import React from \"react\";\nimport { useDropdownContext } from \"./context\";\nimport { DropdownHeaderProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport function DropdownHeader({ children, className = \"\", ...rest }: DropdownHeaderProps) {\n const { size } = useDropdownContext();\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n return (\n <div\n role=\"presentation\"\n className={[\"font-semibold text-neutral-500 uppercase tracking-wider select-none\", currentSize.header, className]\n .filter(Boolean)\n .join(\" \")}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nexport default DropdownHeader;\n","import React from \"react\";\nimport { DropdownSeparatorProps } from \"./types\";\n\nexport function DropdownSeparator({ className = \"\", ...rest }: DropdownSeparatorProps) {\n return <hr className={[\"-mx-1 my-1 h-px border-0 bg-neutral-200\", className].filter(Boolean).join(\" \")} {...rest} />;\n}\n\nexport default DropdownSeparator;\n","import React from \"react\";\nimport { DropdownGroupProps } from \"./types\";\nimport { DropdownHeader } from \"./DropdownHeader\";\n\nexport function DropdownGroup({ children, label, className = \"\", ...rest }: DropdownGroupProps) {\n return (\n <div role=\"group\" className={[\"flex flex-col\", className].filter(Boolean).join(\" \")} {...rest}>\n {label && <DropdownHeader>{label}</DropdownHeader>}\n {children}\n </div>\n );\n}\n\nexport default DropdownGroup;\n","import React, { useState, useMemo, useCallback } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useClick,\n useHover,\n useDismiss,\n useRole,\n useInteractions,\n safePolygon,\n} from \"@floating-ui/react\";\nimport { PopoverProps, PopoverContextValue } from \"./types\";\nimport { PopoverContext } from \"./context\";\n\nexport default function Popover({\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n trigger = \"click\",\n placement = \"bottom\",\n offset = 8,\n flip = true,\n shift = true,\n size = \"md\",\n radius = \"md\",\n color = \"neutral\",\n disabled = false,\n animated = true,\n animationDuration = 150,\n modal = false,\n closeOnEsc = true,\n closeOnClickOutside = true,\n}: PopoverProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : uncontrolledOpen;\n\n const handleOpenChange = useCallback(\n (nextOpen: boolean) => {\n if (!isControlled) {\n setUncontrolledOpen(nextOpen);\n }\n onOpenChange?.(nextOpen);\n },\n [isControlled, onOpenChange]\n );\n\n const middleware = useMemo(\n () =>\n [\n offsetMiddleware(offset),\n flip ? flipMiddleware() : undefined,\n shift ? shiftMiddleware({ padding: 8 }) : undefined,\n ].filter(Boolean),\n [offset, flip, shift]\n );\n\n const {\n refs,\n floatingStyles,\n context,\n placement: computedPlacement,\n } = useFloating({\n placement,\n open: isOpen && !disabled,\n onOpenChange: handleOpenChange,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware,\n });\n\n const click = useClick(context, {\n enabled: !disabled && trigger === \"click\",\n });\n\n const hover = useHover(context, {\n enabled: !disabled && trigger === \"hover\",\n delay: { open: 100, close: 150 },\n handleClose: safePolygon(),\n });\n\n const dismiss = useDismiss(context, {\n escapeKey: closeOnEsc,\n outsidePress: closeOnClickOutside,\n });\n\n const role = useRole(context, { role: \"dialog\" });\n\n const { getReferenceProps, getFloatingProps } = useInteractions([click, hover, dismiss, role]);\n\n const contextValue: PopoverContextValue = useMemo(\n () => ({\n isOpen,\n setIsOpen: handleOpenChange,\n refs,\n floatingStyles,\n context,\n getReferenceProps,\n getFloatingProps,\n size,\n radius,\n color,\n disabled,\n animated,\n animationDuration,\n modal,\n computedPlacement,\n }),\n [\n isOpen,\n handleOpenChange,\n refs,\n floatingStyles,\n context,\n getReferenceProps,\n getFloatingProps,\n size,\n radius,\n color,\n disabled,\n animated,\n animationDuration,\n modal,\n computedPlacement,\n ]\n );\n\n return <PopoverContext.Provider value={contextValue}>{children}</PopoverContext.Provider>;\n}\n","import { createContext, useContext } from \"react\";\nimport { PopoverContextValue } from \"./types\";\n\nexport const PopoverContext = createContext<PopoverContextValue | null>(null);\n\nexport const usePopoverContext = (): PopoverContextValue => {\n const context = useContext(PopoverContext);\n if (!context) {\n throw new Error(\"Popover compound components must be used within a <Popover> component.\");\n }\n return context;\n};\n","import React, { cloneElement, isValidElement, ReactNode, HTMLAttributes } from \"react\";\nimport { usePopoverContext } from \"./context\";\nimport { PopoverTriggerProps } from \"./types\";\nimport { useMergeRefs } from \"@floating-ui/react\";\n\ninterface SlotProps extends HTMLAttributes<HTMLElement> {\n children?: ReactNode;\n disabled?: boolean;\n}\n\nfunction Slot({\n children,\n ref: forwardedRef,\n disabled,\n className = \"\",\n ...props\n}: SlotProps & { ref?: React.Ref<HTMLElement> }) {\n const childRef = isValidElement(children)\n ? (children.props as { ref?: React.Ref<HTMLElement> })?.ref\n : undefined;\n\n const mergedChildRef = useMergeRefs([forwardedRef, childRef]);\n\n if (!isValidElement<Record<string, unknown>>(children)) {\n return null;\n }\n\n const childProps = (children.props || {}) as {\n className?: string;\n disabled?: boolean;\n [key: string]: unknown;\n };\n\n return cloneElement(children, {\n ...props,\n ...childProps,\n ref: mergedChildRef,\n disabled: disabled ? true : childProps.disabled,\n className: [childProps.className, className].filter(Boolean).join(\" \"),\n });\n}\n\nexport function PopoverTrigger({\n ref: propRef,\n children,\n className = \"\",\n asChild = false,\n ...rest\n}: PopoverTriggerProps) {\n const { refs, getReferenceProps, isOpen, disabled } = usePopoverContext();\n const mergedRef = useMergeRefs([refs.setReference, propRef]);\n\n const triggerProps = getReferenceProps({\n ...rest,\n \"aria-expanded\": isOpen,\n \"aria-haspopup\": \"dialog\",\n className,\n });\n\n if (isValidElement(children) && (asChild || true)) {\n return (\n <Slot ref={mergedRef} disabled={disabled} {...triggerProps}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={mergedRef}\n type=\"button\"\n disabled={disabled}\n aria-expanded={isOpen}\n aria-haspopup=\"dialog\"\n className={className}\n {...triggerProps}\n >\n {children}\n </button>\n );\n}\n\nexport default PopoverTrigger;\n","import React from \"react\";\nimport { FloatingPortal, FloatingFocusManager, useTransitionStyles, useMergeRefs } from \"@floating-ui/react\";\nimport { usePopoverContext } from \"./context\";\nimport { PopoverContentProps } from \"./types\";\nimport { sizeConfig, radiusConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\n\nexport function PopoverContent({\n ref: propRef,\n children,\n className = \"\",\n style,\n minWidth,\n maxWidth,\n zIndex = DEFAULT_Z_INDEX.POPOVER,\n ...rest\n}: PopoverContentProps) {\n const {\n isOpen,\n refs,\n floatingStyles,\n context,\n getFloatingProps,\n size,\n radius,\n animated,\n animationDuration,\n modal,\n computedPlacement,\n } = usePopoverContext();\n\n const mergedRef = useMergeRefs([refs.setFloating, propRef]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: animated ? animationDuration : 0,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n if (!isMounted) {\n return null;\n }\n\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"md\");\n\n const baseClasses =\n \"bg-neutral-white shadow-xl outline-none focus:outline-none flex flex-col border-2 border-neutral-200\";\n\n const contentClassNames = [baseClasses, currentSize.container, roundedClass, className].filter(Boolean).join(\" \");\n\n const content = (\n <FloatingFocusManager context={context} modal={modal}>\n <div\n ref={mergedRef}\n style={{\n ...floatingStyles,\n ...(animated ? transitionStyles : {}),\n minWidth,\n maxWidth,\n zIndex,\n ...style,\n }}\n className={contentClassNames}\n data-state={isOpen ? \"open\" : \"closed\"}\n data-placement={computedPlacement}\n {...getFloatingProps(rest)}\n >\n {children}\n </div>\n </FloatingFocusManager>\n );\n\n return <FloatingPortal>{content}</FloatingPortal>;\n}\n\nexport default PopoverContent;\n","import { PopoverSize, PopoverRadius, PopoverColor } from \"./types\";\n\nexport const sizeConfig: Record<\n PopoverSize,\n {\n container: string;\n header: string;\n body: string;\n footer: string;\n }\n> = {\n xs: {\n container: \"min-w-44 text-xs\",\n header: \"px-2.5 py-1.5 text-xs font-semibold\",\n body: \"px-2.5 py-2 text-xs\",\n footer: \"px-2.5 py-1.5 text-xs\",\n },\n sm: {\n container: \"min-w-56 text-xs\",\n header: \"px-3 py-2 text-xs font-semibold\",\n body: \"px-3 py-2.5 text-xs\",\n footer: \"px-3 py-2 text-xs\",\n },\n md: {\n container: \"min-w-64 text-sm\",\n header: \"px-4 py-3 text-sm font-semibold\",\n body: \"px-4 py-3 text-sm\",\n footer: \"px-4 py-2.5 text-sm\",\n },\n lg: {\n container: \"min-w-80 text-base\",\n header: \"px-5 py-3.5 text-base font-semibold\",\n body: \"px-5 py-4 text-base\",\n footer: \"px-5 py-3 text-base\",\n },\n xl: {\n container: \"min-w-96 text-lg\",\n header: \"px-6 py-4 text-lg font-semibold\",\n body: \"px-6 py-5 text-lg\",\n footer: \"px-6 py-4 text-lg\",\n },\n};\n\nexport const radiusConfig: Record<PopoverRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-xl\",\n xl: \"rounded-2xl\",\n full: \"rounded-3xl\",\n};\n\nexport const colorConfig: Record<\n PopoverColor,\n {\n border: string;\n headerBg?: string;\n }\n> = {\n neutral: {\n border: \"border-neutral-200\",\n headerBg: \"border-b border-neutral-100\",\n },\n primary: {\n border: \"border-primary-300\",\n headerBg: \"border-b border-primary-100 text-primary-900\",\n },\n secondary: {\n border: \"border-secondary-300\",\n headerBg: \"border-b border-secondary-100 text-secondary-900\",\n },\n error: {\n border: \"border-error-300\",\n headerBg: \"border-b border-error-100 text-error-900\",\n },\n success: {\n border: \"border-success-300\",\n headerBg: \"border-b border-success-100 text-success-900\",\n },\n warning: {\n border: \"border-warning-300\",\n headerBg: \"border-b border-warning-100 text-warning-900\",\n },\n info: {\n border: \"border-info-300\",\n headerBg: \"border-b border-info-100 text-info-900\",\n },\n};\n","import React from \"react\";\nimport { usePopoverContext } from \"./context\";\nimport { PopoverHeaderProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport function PopoverHeader({ children, className = \"\", ...rest }: PopoverHeaderProps) {\n const { size } = usePopoverContext();\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n return (\n <h2\n className={[\"text-neutral-900 border-b border-neutral-100 font-semibold\", currentSize.header, className]\n .filter(Boolean)\n .join(\" \")}\n {...rest}\n >\n {children}\n </h2>\n );\n}\n\nexport default PopoverHeader;\n","import React from \"react\";\nimport { usePopoverContext } from \"./context\";\nimport { PopoverBodyProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport function PopoverBody({ children, className = \"\", ...rest }: PopoverBodyProps) {\n const { size } = usePopoverContext();\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n return (\n <div className={[\"text-neutral-700\", currentSize.body, className].filter(Boolean).join(\" \")} {...rest}>\n {children}\n </div>\n );\n}\n\nexport default PopoverBody;\n","import React from \"react\";\nimport { usePopoverContext } from \"./context\";\nimport { PopoverFooterProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport function PopoverFooter({ children, className = \"\", ...rest }: PopoverFooterProps) {\n const { size } = usePopoverContext();\n const currentSize = getSafeConfig(size, sizeConfig, \"md\");\n\n return (\n <div\n className={[\"border-t border-neutral-100 bg-neutral-50/50\", currentSize.footer, className]\n .filter(Boolean)\n .join(\" \")}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nexport default PopoverFooter;\n","import React, { cloneElement, isValidElement, MouseEvent, ReactNode, ButtonHTMLAttributes } from \"react\";\nimport { usePopoverContext } from \"./context\";\nimport { PopoverCloseProps } from \"./types\";\nimport { useMergeRefs } from \"@floating-ui/react\";\n\ninterface SlotProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n children?: ReactNode;\n}\n\nfunction Slot({\n children,\n ref: forwardedRef,\n className = \"\",\n onClick,\n ...props\n}: SlotProps & { ref?: React.Ref<HTMLButtonElement> }) {\n const childRef = isValidElement(children)\n ? (children.props as { ref?: React.Ref<HTMLButtonElement> })?.ref\n : undefined;\n\n const mergedChildRef = useMergeRefs([forwardedRef, childRef]);\n\n if (!isValidElement<Record<string, unknown>>(children)) {\n return null;\n }\n\n const childProps = (children.props || {}) as {\n className?: string;\n onClick?: (e: MouseEvent<HTMLButtonElement>) => void;\n [key: string]: unknown;\n };\n\n return cloneElement(children, {\n ...props,\n ...childProps,\n ref: mergedChildRef,\n className: [childProps.className, className].filter(Boolean).join(\" \"),\n onClick: (e: MouseEvent<HTMLButtonElement>) => {\n childProps.onClick?.(e);\n onClick?.(e);\n },\n });\n}\n\nexport function PopoverClose({\n ref: propRef,\n children,\n className = \"\",\n asChild = false,\n onClick,\n ...rest\n}: PopoverCloseProps) {\n const { setIsOpen } = usePopoverContext();\n\n const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) {\n setIsOpen(false);\n }\n };\n\n if (isValidElement(children) && asChild) {\n return (\n <Slot ref={propRef} className={className} onClick={handleClick} {...rest}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button ref={propRef} type=\"button\" className={className} onClick={handleClick} {...rest}>\n {children}\n </button>\n );\n}\n\nexport default PopoverClose;\n","import { useState, useId, useMemo, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useDismiss,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingFocusManager,\n} from \"@floating-ui/react\";\nimport { DatePickerProps, CalendarView } from \"./types\";\nimport Calendar from \"./Calendar\";\nimport ChevronDownIcon from \"../icons/ChevronDownIcon\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { formatDate, toDate, getAdaptiveViewFormat } from \"./utils\";\nimport { datePickerRadiusConfig, datePickerSizeConfig, datePickerVariantStyles, labelColorConfig } from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function DatePicker({\n ref,\n value: controlledValue,\n defaultValue,\n onChange,\n format = \"DD/MM/YYYY\",\n displayFormat: customDisplayFormat,\n defaultView = \"days\",\n locale = \"vi\",\n firstDayOfWeek = 1,\n minDate,\n maxDate,\n isDateDisabled,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius,\n label,\n labelPlacement = \"top\",\n placeholder,\n helperText,\n errorMessage,\n name,\n id,\n autoComplete,\n viewTabs = [\"days\", \"months\", \"years\"],\n view: controlledView,\n onViewChange,\n onClear,\n placement = \"bottom-start\",\n disabled = false,\n readOnly = false,\n config,\n className = \"\",\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n popoverClassName = \"\",\n}: DatePickerProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = true,\n isFullWidth = false,\n showWeekNumbers = false,\n showViewTabs = false,\n closeOnSelect = true,\n } = config ?? {};\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n const popoverId = `${inputId}-popover`;\n\n const isControlledView = controlledView !== undefined;\n const [internalView, setInternalView] = useState<CalendarView>(defaultView);\n const activeView = isControlledView ? controlledView : internalView;\n\n const baseDisplayFormat = customDisplayFormat || format;\n const currentDisplayFormat = useMemo(() => {\n return getAdaptiveViewFormat(baseDisplayFormat, activeView);\n }, [baseDisplayFormat, activeView]);\n\n const isControlled = controlledValue !== undefined;\n const [internalDate, setInternalDate] = useState<Date | null>(() => toDate(defaultValue, format));\n const selectedDate = isControlled ? toDate(controlledValue, format) : internalDate;\n const formattedValue = selectedDate ? formatDate(selectedDate, currentDisplayFormat, locale) : \"\";\n\n const [isOpen, setIsOpen] = useState(false);\n\n const {\n refs: { setReference, setFloating },\n floatingStyles,\n context,\n } = useFloating({\n placement,\n open: isOpen && !disabled && !readOnly && !isLoading,\n onOpenChange: setIsOpen,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware: [offsetMiddleware(6), flipMiddleware(), shiftMiddleware({ padding: 8 })],\n });\n\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n });\n const role = useRole(context, { role: \"dialog\" });\n const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: 150,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n // Style configs\n const sizeStyles = getSafeConfig(size, datePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, datePickerRadiusConfig, \"lg\");\n const variantClass =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, datePickerVariantStyles, \"outline\"), \"primary\");\n\n const hasValue = Boolean(selectedDate);\n\n const handleViewChange = (mode: CalendarView) => {\n if (!isControlledView) {\n setInternalView(mode);\n }\n onViewChange?.(mode);\n };\n\n const handleDateSelect = (date: Date | null) => {\n if (!isControlled) {\n setInternalDate(date);\n }\n const formattedOutput = date ? formatDate(date, format, locale) : \"\";\n onChange?.(formattedOutput);\n\n if (closeOnSelect) {\n setIsOpen(false);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (e.key === \"ArrowDown\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!isOpen) setIsOpen(true);\n } else if (e.key === \"Escape\" && isOpen) {\n e.preventDefault();\n setIsOpen(false);\n }\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (!isControlled) {\n setInternalDate(null);\n }\n onChange?.(null);\n onClear?.();\n };\n\n const defaultPlaceholder = placeholder || currentDisplayFormat;\n\n const isFloating = labelPlacement === \"floating\";\n const isHorizontal = labelPlacement === \"left\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-pointer font-bold bg-neutral-white transition-colors duration-150 ${sizeStyles.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${sizeStyles.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${sizeStyles.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const fieldWrapperClasses = [\n \"group/field relative flex\",\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\",\n isFullWidth ? \"w-full\" : \"inline-flex\",\n wrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2 select-none cursor-pointer\",\n sizeStyles.inputHeight,\n radiusClass,\n variantClass,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : \"w-auto\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const inputClasses = [\n \"w-full h-full bg-transparent outline-none border-none text-neutral-800 placeholder-neutral-400 cursor-pointer select-none caret-transparent focus:outline-none\",\n sizeStyles.inputText,\n sizeStyles.inputPadding,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={fieldWrapperClasses}>\n {/* Label (Top / Left) */}\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n {/* Input container */}\n <div ref={setReference} {...getReferenceProps()} className={containerClasses}>\n {isFloating && renderLabel()}\n\n <input\n ref={ref}\n id={inputId}\n name={name}\n type=\"text\"\n value={formattedValue}\n onClick={() => !disabled && !readOnly && !isLoading && setIsOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n readOnly={true}\n autoComplete={autoComplete}\n placeholder={defaultPlaceholder}\n disabled={disabled || isLoading}\n role=\"combobox\"\n aria-expanded={isOpen && !isLoading}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-required={isRequired}\n aria-invalid={hasError}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={helperText || errorMessage ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n className={inputClasses}\n />\n\n {/* Right actions: Spinner, Clear, ChevronDown Icon */}\n <div className=\"flex items-center space-x-1.5 pr-2.5 shrink-0\">\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center shrink-0\">{renderIconWrapper(<Spinner />)}</div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa ngày\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${sizeStyles.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n <div\n aria-hidden=\"true\"\n className={`inline-flex items-center justify-center text-neutral-400 hover:text-neutral-600 transition-transform duration-200 ease-in-out cursor-pointer ${\n isOpen ? \"rotate-180\" : \"rotate-0\"\n }`}\n >\n {renderIconWrapper(<ChevronDownIcon className=\"size-full\" />)}\n </div>\n </div>\n </div>\n\n {/* Floating UI Portal */}\n {isMounted && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false} returnFocus={true}>\n <div\n ref={setFloating}\n id={popoverId}\n style={{\n ...floatingStyles,\n ...transitionStyles,\n zIndex: DEFAULT_Z_INDEX.PICKER,\n }}\n {...getFloatingProps()}\n className={popoverClassName}\n >\n <Calendar\n value={selectedDate}\n onChange={handleDateSelect}\n view={activeView}\n onViewChange={handleViewChange}\n minDate={minDate}\n maxDate={maxDate}\n isDateDisabled={isDateDisabled}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n showWeekNumbers={showWeekNumbers}\n size={size}\n color={color}\n radius={radius}\n showViewTabs={showViewTabs}\n viewTabs={viewTabs}\n />\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n\n {/* Helper / Error text with animation */}\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={sizeStyles.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { CalendarProps, CalendarView } from \"./types\";\nimport CalendarHeader from \"./CalendarHeader\";\nimport DayGrid from \"./DayGrid\";\nimport MonthGrid from \"./MonthGrid\";\nimport YearGrid from \"./YearGrid\";\nimport Tabs from \"../tabs/Tabs\";\nimport TabList from \"../tabs/TabList\";\nimport Tab from \"../tabs/Tab\";\nimport { generateCalendarGrid, resolveLocale, toDate } from \"./utils\";\nimport { calendarRadiusConfig, datePickerSizeConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function Calendar({\n value: selectedDate,\n onChange,\n view = \"days\",\n onViewChange,\n minDate,\n maxDate,\n isDateDisabled,\n locale = \"vi\",\n firstDayOfWeek = 1,\n showWeekNumbers = false,\n showViewTabs = false,\n viewTabs = [\"days\", \"months\", \"years\"],\n size = \"md\",\n color = \"primary\",\n radius,\n className = \"\",\n}: CalendarProps) {\n const sizeStyles = getSafeConfig(size, datePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, calendarRadiusConfig, \"lg\");\n\n // gridMode controls the current grid (DayGrid / MonthGrid / YearGrid)\n // view controls the Tab mode (the target selection: days -> DD/MM/YYYY, months -> MM/YYYY, years -> YYYY)\n const [gridMode, setGridMode] = useState<CalendarView>(view);\n const [prevView, setPrevView] = useState<CalendarView>(view);\n\n if (view !== prevView) {\n setPrevView(view);\n setGridMode(view);\n }\n\n const [currentMonth, setCurrentMonth] = useState<Date>(() => {\n const base = selectedDate || new Date();\n return new Date(base.getFullYear(), base.getMonth(), 1);\n });\n\n // Tabs\n const loc = resolveLocale(locale);\n\n const tabItems = useMemo(() => {\n const tabLabels = loc.viewTabs || {\n days: \"Ngày\",\n months: \"Tháng\",\n years: \"Năm\",\n };\n return (viewTabs || [\"days\", \"months\", \"years\"]).map((v) => ({\n key: v,\n label: tabLabels[v] || v,\n }));\n }, [viewTabs, loc.viewTabs]);\n\n const handleTabChange = (key: string | number) => {\n const nextView = key as CalendarView;\n setGridMode(nextView);\n onViewChange?.(nextView);\n };\n\n // Month navigation handlers\n const handlePrevMonth = () => {\n const prev = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1);\n setCurrentMonth(prev);\n };\n\n const handleNextMonth = () => {\n const next = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1);\n setCurrentMonth(next);\n };\n\n const handlePrevYear = () => {\n const prev = new Date(currentMonth.getFullYear() - 1, currentMonth.getMonth(), 1);\n setCurrentMonth(prev);\n };\n\n const handleNextYear = () => {\n const next = new Date(currentMonth.getFullYear() + 1, currentMonth.getMonth(), 1);\n setCurrentMonth(next);\n };\n\n const handlePrevDecade = () => {\n const prev = new Date(currentMonth.getFullYear() - 10, currentMonth.getMonth(), 1);\n setCurrentMonth(prev);\n };\n\n const handleNextDecade = () => {\n const next = new Date(currentMonth.getFullYear() + 10, currentMonth.getMonth(), 1);\n setCurrentMonth(next);\n };\n\n // Month / Year selection handlers\n const handleSelectMonth = (monthIndex: number) => {\n const updated = new Date(currentMonth.getFullYear(), monthIndex, 1);\n setCurrentMonth(updated);\n if (view === \"months\") {\n onChange?.(updated);\n } else {\n setGridMode(\"days\");\n }\n };\n\n const handleSelectYear = (yr: number) => {\n const updated = new Date(yr, currentMonth.getMonth(), 1);\n setCurrentMonth(updated);\n if (view === \"years\") {\n onChange?.(updated);\n } else if (view === \"months\") {\n setGridMode(\"months\");\n } else {\n setGridMode(\"months\");\n }\n };\n\n // Pre-calculated days grid for single date\n const parsedMin = toDate(minDate);\n const parsedMax = toDate(maxDate);\n\n const daysGrid = useMemo(\n () =>\n generateCalendarGrid(\n currentMonth.getFullYear(),\n currentMonth.getMonth(),\n firstDayOfWeek,\n selectedDate,\n parsedMin,\n parsedMax,\n isDateDisabled\n ),\n [currentMonth, firstDayOfWeek, selectedDate, parsedMin, parsedMax, isDateDisabled]\n );\n\n return (\n <div\n className={`inline-flex flex-col bg-neutral-white border-2 border-neutral-200 shadow-xl ${radiusClass} overflow-hidden select-none ${className}`}\n >\n {/* View Switcher Tabs (Days / Months / Years) */}\n {showViewTabs && tabItems.length > 0 && (\n <div className=\"px-2.5 py-1.5 border-b border-neutral-200\">\n <Tabs\n activeKey={view}\n onChange={handleTabChange}\n size=\"sm\"\n variant=\"solid\"\n color={color}\n fullWidth={true}\n className=\"gap-0!\"\n >\n <TabList className=\"p-0.5\">\n {tabItems.map((item) => (\n <Tab key={item.key} value={item.key} className=\"py-1 px-2 text-xs\">\n {item.label}\n </Tab>\n ))}\n </TabList>\n </Tabs>\n </div>\n )}\n\n {/* Calendar Body */}\n <div className={`${sizeStyles.calendarPadding} min-w-70`}>\n <CalendarHeader\n currentMonth={currentMonth}\n view={gridMode}\n onViewChange={setGridMode}\n onPrevMonth={handlePrevMonth}\n onNextMonth={handleNextMonth}\n onPrevYear={handlePrevYear}\n onNextYear={handleNextYear}\n onPrevDecade={handlePrevDecade}\n onNextDecade={handleNextDecade}\n size={size}\n color={color}\n locale={locale}\n showMonthButtons={true}\n />\n\n {gridMode === \"days\" && (\n <DayGrid\n days={daysGrid}\n onSelectDate={(date) => onChange?.(date)}\n size={size}\n color={color}\n radius={radius}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n showWeekNumbers={showWeekNumbers}\n />\n )}\n\n {gridMode === \"months\" && (\n <MonthGrid\n currentMonth={currentMonth}\n selectedDate={selectedDate}\n onSelectMonth={handleSelectMonth}\n size={size}\n color={color}\n radius={radius}\n locale={locale}\n />\n )}\n\n {gridMode === \"years\" && (\n <YearGrid\n currentMonth={currentMonth}\n selectedDate={selectedDate}\n onSelectYear={handleSelectYear}\n size={size}\n color={color}\n radius={radius}\n />\n )}\n </div>\n </div>\n );\n}\n","import { DatePickerColor, DatePickerRadius, DatePickerSize, DatePickerVariant, LocaleConfig } from \"./types\";\n\nexport const viLocale: LocaleConfig = {\n months: [\n \"Tháng 1\",\n \"Tháng 2\",\n \"Tháng 3\",\n \"Tháng 4\",\n \"Tháng 5\",\n \"Tháng 6\",\n \"Tháng 7\",\n \"Tháng 8\",\n \"Tháng 9\",\n \"Tháng 10\",\n \"Tháng 11\",\n \"Tháng 12\",\n ],\n monthsShort: [\n \"Thg 1\",\n \"Thg 2\",\n \"Thg 3\",\n \"Thg 4\",\n \"Thg 5\",\n \"Thg 6\",\n \"Thg 7\",\n \"Thg 8\",\n \"Thg 9\",\n \"Thg 10\",\n \"Thg 11\",\n \"Thg 12\",\n ],\n weekdays: [\"Chủ Nhật\", \"Thứ Hai\", \"Thứ Ba\", \"Thứ Tư\", \"Thứ Năm\", \"Thứ Sáu\", \"Thứ Bảy\"],\n weekdaysShort: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\"],\n weekdaysMin: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\"],\n todayText: \"Hôm nay\",\n clearText: \"Xóa\",\n weekText: \"Tuần\",\n viewTabs: {\n days: \"Ngày\",\n months: \"Tháng\",\n years: \"Năm\",\n },\n};\n\nexport const enLocale: LocaleConfig = {\n months: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n monthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n weekdays: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n weekdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n weekdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n todayText: \"Today\",\n clearText: \"Clear\",\n weekText: \"Week\",\n viewTabs: {\n days: \"Day\",\n months: \"Month\",\n years: \"Year\",\n },\n};\n\nexport const datePickerSizeConfig: Record<\n DatePickerSize,\n {\n inputHeight: string;\n inputText: string;\n inputPadding: string;\n icon: string;\n iconSize: number;\n calendarPadding: string;\n cellSize: string;\n cellText: string;\n headerText: string;\n headerButtonSize: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n inputHeight: \"h-6\",\n inputText: \"text-[11px]\",\n inputPadding: \"px-2\",\n icon: \"size-3\",\n iconSize: 12,\n calendarPadding: \"p-2\",\n cellSize: \"w-7 h-7\",\n cellText: \"text-[11px]\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-6 w-6\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n inputHeight: \"h-8\",\n inputText: \"text-xs\",\n inputPadding: \"px-2.5\",\n icon: \"size-3.5\",\n iconSize: 14,\n calendarPadding: \"p-2.5\",\n cellSize: \"w-8 h-8\",\n cellText: \"text-xs\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-7 w-7\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n inputHeight: \"h-10\",\n inputText: \"text-sm\",\n inputPadding: \"px-3\",\n icon: \"size-[18px]\",\n iconSize: 16,\n calendarPadding: \"p-3\",\n cellSize: \"w-9 h-9\",\n cellText: \"text-sm\",\n headerText: \"text-sm font-semibold\",\n headerButtonSize: \"h-8 w-8\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n inputHeight: \"h-12\",\n inputText: \"text-base\",\n inputPadding: \"px-3.5\",\n icon: \"size-5\",\n iconSize: 18,\n calendarPadding: \"p-4\",\n cellSize: \"w-10 h-10\",\n cellText: \"text-base\",\n headerText: \"text-base font-semibold\",\n headerButtonSize: \"h-9 w-9\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n inputHeight: \"h-14\",\n inputText: \"text-lg\",\n inputPadding: \"px-4\",\n icon: \"size-6\",\n iconSize: 20,\n calendarPadding: \"p-4.5\",\n cellSize: \"w-11 h-11\",\n cellText: \"text-base\",\n headerText: \"text-lg font-semibold\",\n headerButtonSize: \"h-10 w-10\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-xs\",\n helper: \"text-sm mt-1\",\n },\n};\n\nexport const labelColorConfig: Record<DatePickerColor, string> = {\n primary: \"text-primary-500 group-focus-within/datepicker:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/datepicker:text-secondary-600\",\n error: \"text-error-500 group-focus-within/datepicker:text-error-600\",\n success: \"text-success-500 group-focus-within/datepicker:text-success-600\",\n warning: \"text-warning-500 group-focus-within/datepicker:text-warning-600\",\n info: \"text-info-500 group-focus-within/datepicker:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/datepicker:text-neutral-600\",\n};\n\nexport const datePickerRadiusConfig: Record<DatePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const calendarRadiusConfig: Record<DatePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-2xl\",\n};\n\nexport const datePickerColorConfig: Record<\n DatePickerColor,\n {\n selected: string;\n selectedText: string;\n rangeBg: string;\n rangeText: string;\n hoverBg: string;\n todayRing: string;\n activeText: string;\n accentBg: string;\n }\n> = {\n primary: {\n selected: \"bg-primary-500 text-neutral-white hover:bg-primary-600\",\n selectedText: \"text-neutral-white\",\n rangeBg: \"bg-primary-100 text-primary-900\",\n rangeText: \"text-primary-900\",\n hoverBg: \"hover:bg-primary-200 hover:text-primary-900\",\n todayRing: \"border-primary-500 text-primary-500\",\n activeText: \"text-primary-500\",\n accentBg: \"bg-primary-500\",\n },\n secondary: {\n selected: \"bg-secondary-500 text-neutral-white hover:bg-secondary-600\",\n selectedText: \"text-neutral-white\",\n rangeBg: \"bg-secondary-100 text-secondary-900\",\n rangeText: \"text-secondary-900\",\n hoverBg: \"hover:bg-secondary-200 hover:text-secondary-900\",\n todayRing: \"border-secondary-500 text-secondary-500\",\n activeText: \"text-secondary-500\",\n accentBg: \"bg-secondary-500\",\n },\n neutral: {\n selected: \"bg-neutral-800 text-neutral-white hover:bg-neutral-900\",\n selectedText: \"text-neutral-white\",\n rangeBg: \"bg-neutral-200 text-neutral-900\",\n rangeText: \"text-neutral-900\",\n hoverBg: \"hover:bg-neutral-300 hover:text-neutral-900\",\n todayRing: \"border-neutral-600 text-neutral-600\",\n activeText: \"text-neutral-800\",\n accentBg: \"bg-neutral-800\",\n },\n error: {\n selected: \"bg-error-500 text-neutral-white hover:bg-error-600\",\n selectedText: \"text-neutral-white\",\n rangeBg: \"bg-error-100 text-error-900\",\n rangeText: \"text-error-900\",\n hoverBg: \"hover:bg-error-200 hover:text-error-900\",\n todayRing: \"border-error-500 text-error-500\",\n activeText: \"text-error-500\",\n accentBg: \"bg-error-500\",\n },\n success: {\n selected: \"bg-success-500 text-neutral-white hover:bg-success-600\",\n selectedText: \"text-neutral-white\",\n rangeBg: \"bg-success-100 text-success-900\",\n rangeText: \"text-success-900\",\n hoverBg: \"hover:bg-success-200 hover:text-success-900\",\n todayRing: \"border-success-500 text-success-500\",\n activeText: \"text-success-500\",\n accentBg: \"bg-success-500\",\n },\n warning: {\n selected: \"bg-warning-500 text-neutral-950 hover:bg-warning-600\",\n selectedText: \"text-neutral-950\",\n rangeBg: \"bg-warning-100 text-warning-900\",\n rangeText: \"text-warning-900\",\n hoverBg: \"hover:bg-warning-200 hover:text-warning-900\",\n todayRing: \"border-warning-500 text-warning-700\",\n activeText: \"text-warning-700\",\n accentBg: \"bg-warning-500\",\n },\n info: {\n selected: \"bg-info-500 text-neutral-white hover:bg-info-600\",\n selectedText: \"text-neutral-white\",\n rangeBg: \"bg-info-100 text-info-900\",\n rangeText: \"text-info-900\",\n hoverBg: \"hover:bg-info-200 hover:text-info-900\",\n todayRing: \"border-info-500 text-info-500\",\n activeText: \"text-info-500\",\n accentBg: \"bg-info-500\",\n },\n};\n\nexport const datePickerVariantStyles: Record<Exclude<DatePickerVariant, \"other\">, Record<DatePickerColor, string>> = {\n outline: {\n primary:\n \"bg-neutral-white border-primary-300 hover:border-primary-400 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-neutral-white border-secondary-300 hover:border-secondary-400 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-neutral-white border-error-300 hover:border-error-400 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-neutral-white border-success-300 hover:border-success-400 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-neutral-white border-warning-300 hover:border-warning-400 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-neutral-white border-info-300 hover:border-info-400 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n\n filled: {\n primary:\n \"bg-primary-50/60 border-primary-200 hover:bg-primary-100/60 focus-within:bg-primary-100/60 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-secondary-50/60 border-secondary-200 hover:bg-secondary-100/60 focus-within:bg-secondary-100/60 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-neutral-50/60 border-neutral-200 hover:bg-neutral-200/60 focus-within:bg-neutral-200/60 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-error-50/60 border-error-500 hover:border-error-600 hover:bg-error-100/60 focus-within:bg-error-100/60 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-success-50/60 border-success-200 hover:bg-success-100/60 focus-within:bg-success-100/60 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-warning-50/60 border-warning-200 hover:bg-warning-100/60 focus-within:bg-warning-100/60 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-info-50/60 border-info-200 hover:bg-info-100/60 focus-within:bg-info-100/60 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n ghost: {\n primary:\n \"bg-transparent border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-200/20 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-transparent border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-200/20 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-transparent border-transparent hover:bg-neutral-50/50 focus-within:bg-neutral-50/50 focus-within:border-neutral-200/20 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-transparent border-transparent hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-transparent border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-200/20 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-transparent border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-200/20 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-transparent border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-200/20 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n};\n","import { LocaleConfig, CalendarDay, CalendarView } from \"./types\";\nimport { viLocale, enLocale } from \"./constants\";\n\n/**\n * Phân giải cấu hình ngôn ngữ (locale) thành đối tượng `LocaleConfig` hoàn chỉnh.\n *\n * @param locale - Mã ngôn ngữ ('vi' | 'en') hoặc đối tượng cấu hình `LocaleConfig` tùy biến.\n * @returns Đối tượng `LocaleConfig` tương ứng (mặc định trả về `viLocale` nếu không truyền).\n */\nexport function resolveLocale(locale: \"vi\" | \"en\" | LocaleConfig | undefined): LocaleConfig {\n if (!locale || locale === \"vi\") return viLocale;\n if (locale === \"en\") return enLocale;\n return locale;\n}\n\n/**\n * Chuyển đổi dữ liệu đầu vào không xác định thành đối tượng `Date` hợp lệ.\n * Hỗ trợ:\n * - Đối tượng `Date` chuẩn.\n * - Timestamp `number` (milliseconds).\n * - Chuỗi ngày định dạng theo mẫu `formatStr` truyền vào (hoặc fallback DD/MM/YYYY, MM/YYYY, YYYY, YYYY-MM-DD, ISO string).\n * - Đối tượng dạng Temporal (có phương thức `toDate()` hoặc thuộc tính `epochMilliseconds`).\n *\n * @param val - Giá trị đầu vào cần chuyển đổi (Date, string, number, Temporal-like).\n * @param formatStr - Định dạng chuỗi ngày mong đợi để phân tích (VD: 'DD/MM/YYYY', 'MM/YYYY', 'YYYY', 'YYYY-MM-DD').\n * @returns Đối tượng `Date` hợp lệ hoặc `null` nếu không thể chuyển đổi.\n */\nexport function toDate(val: unknown, formatStr?: string): Date | null {\n if (!val) return null;\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? null : new Date(val.getTime());\n }\n if (typeof val === \"string\") {\n const trimmed = val.trim();\n if (!trimmed) return null;\n\n // 1. Ưu tiên parse theo formatStr chỉ định nếu có\n if (formatStr) {\n const parsedCustom = parseDate(trimmed, formatStr);\n if (parsedCustom) return parsedCustom;\n }\n\n // 2. Fallback sang Date constructor tiêu chuẩn (ISO string...)\n const parsed = new Date(trimmed);\n return isNaN(parsed.getTime()) ? null : parsed;\n }\n if (typeof val === \"number\") {\n const parsed = new Date(val);\n return isNaN(parsed.getTime()) ? null : parsed;\n }\n\n return null;\n}\n\n/**\n * Kiểm tra xem hai ngày có cùng ngày, tháng, năm hay không (bỏ qua giờ, phút, giây).\n *\n * @param d1 - Ngày thứ nhất.\n * @param d2 - Ngày thứ hai.\n * @returns `true` nếu hai ngày trùng nhau, ngược lại `false`.\n */\nexport function isSameDay(d1: Date | null | undefined, d2: Date | null | undefined): boolean {\n if (!d1 || !d2) return false;\n return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate();\n}\n\n/**\n * Kiểm tra xem hai ngày có cùng tháng và cùng năm hay không.\n *\n * @param d1 - Ngày thứ nhất.\n * @param d2 - Ngày thứ hai.\n * @returns `true` nếu cùng tháng và năm, ngược lại `false`.\n */\nexport function isSameMonth(d1: Date | null | undefined, d2: Date | null | undefined): boolean {\n if (!d1 || !d2) return false;\n return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth();\n}\n\n/**\n * So sánh xem ngày `d1` có xảy ra trước ngày `d2` hay không (chỉ so sánh ngày/tháng/năm).\n *\n * @param d1 - Ngày cần kiểm tra.\n * @param d2 - Ngày mốc so sánh.\n * @returns `true` nếu `d1` trước `d2`.\n */\nexport function isDateBefore(d1: Date, d2: Date): boolean {\n const t1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()).getTime();\n const t2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate()).getTime();\n return t1 < t2;\n}\n\n/**\n * So sánh xem ngày `d1` có xảy ra sau ngày `d2` hay không (chỉ so sánh ngày/tháng/năm).\n *\n * @param d1 - Ngày cần kiểm tra.\n * @param d2 - Ngày mốc so sánh.\n * @returns `true` nếu `d1` sau `d2`.\n */\nexport function isDateAfter(d1: Date, d2: Date): boolean {\n const t1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()).getTime();\n const t2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate()).getTime();\n return t1 > t2;\n}\n\n/**\n * Tính số thứ tự tuần trong năm của một ngày theo tiêu chuẩn ISO 8601.\n * Tuần 1 là tuần có ngày Thứ Năm đầu tiên của năm và tuần luôn bắt đầu từ Thứ Hai.\n *\n * @param date - Đối tượng `Date` cần tính số tuần.\n * @returns Số thứ tự tuần (1 - 53).\n */\nexport function getISOWeekNumber(date: Date): number {\n const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n const dayNum = d.getUTCDay() || 7;\n d.setUTCDate(d.getUTCDate() + 4 - dayNum);\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n}\n\n/**\n * Lấy tổng số ngày trong một tháng cụ thể của năm (tính cả năm nhuận).\n *\n * @param year - Năm đầy đủ (VD: 2026).\n * @param month - Chỉ số tháng (0: Tháng 1 đến 11: Tháng 12).\n * @returns Số lượng ngày trong tháng (28, 29, 30 hoặc 31).\n */\nexport function getDaysInMonth(year: number, month: number): number {\n return new Date(year, month + 1, 0).getDate();\n}\n\n/**\n * Sinh ma trận 42 ô ngày (chuẩn 6 tuần) hiển thị trong bảng lịch của một tháng.\n * Bao gồm:\n * 1. Các ngày cuối của tháng trước để lấp đầy tuần đầu tiên.\n * 2. Toàn bộ các ngày trong tháng hiện tại.\n * 3. Các ngày đầu của tháng tiếp theo để đủ 42 ô (6 hàng x 7 cột).\n *\n * @param year - Năm cần hiển thị.\n * @param month - Chỉ số tháng cần hiển thị (0 - 11).\n * @param firstDayOfWeek - Ngày bắt đầu tuần (0: Chủ Nhật, 1: Thứ Hai, mặc định 1).\n * @param selectedDate - Ngày đơn đang được chọn (để đánh dấu isSelected).\n * @param rangeStart - Ngày bắt đầu khoảng (chế độ range).\n * @param rangeEnd - Ngày kết thúc khoảng (chế độ range).\n * @param hoveredDate - Ngày đang được rê chuột (chế độ range preview).\n * @param minDate - Giới hạn ngày nhỏ nhất cho phép chọn.\n * @param maxDate - Giới hạn ngày lớn nhất cho phép chọn.\n * @param isDateDisabled - Hàm kiểm tra ngày có bị vô hiệu hóa hay không.\n * @returns Mảng gồm 42 đối tượng `CalendarDay`.\n */\nexport function generateCalendarGrid(\n year: number,\n month: number,\n firstDayOfWeek: 0 | 1 = 1,\n selectedDate?: Date | null,\n minDate?: Date | null,\n maxDate?: Date | null,\n isDateDisabled?: (date: Date) => boolean\n): CalendarDay[] {\n const days: CalendarDay[] = [];\n const today = new Date();\n\n const firstDayIndex = new Date(year, month, 1).getDay();\n const prevMonthDays = getDaysInMonth(year, month - 1);\n const currentMonthDays = getDaysInMonth(year, month);\n\n // Số ngày của tháng trước cần hiển thị\n const prevDaysCount = firstDayOfWeek === 1 ? (firstDayIndex === 0 ? 6 : firstDayIndex - 1) : firstDayIndex;\n\n // 1. Ngày của tháng trước\n for (let i = prevDaysCount - 1; i >= 0; i--) {\n const d = prevMonthDays - i;\n const date = new Date(year, month - 1, d);\n days.push(\n createCalendarDay(\n date,\n false,\n today,\n selectedDate,\n minDate,\n maxDate,\n isDateDisabled\n )\n );\n }\n\n // 2. Ngày của tháng hiện tại\n for (let i = 1; i <= currentMonthDays; i++) {\n const date = new Date(year, month, i);\n days.push(\n createCalendarDay(\n date,\n true,\n today,\n selectedDate,\n minDate,\n maxDate,\n isDateDisabled\n )\n );\n }\n\n // 3. Ngày của tháng tiếp theo (cho đủ 42 ô = 6 tuần)\n const remainingDays = 42 - days.length;\n for (let i = 1; i <= remainingDays; i++) {\n const date = new Date(year, month + 1, i);\n days.push(\n createCalendarDay(\n date,\n false,\n today,\n selectedDate,\n minDate,\n maxDate,\n isDateDisabled\n )\n );\n }\n\n return days;\n}\n\n/**\n * Hàm khởi tạo đối tượng `CalendarDay` kèm theo các trạng thái tính toán sẵn.\n *\n * @param date - Đối tượng Date đại diện cho ô ngày.\n * @param isCurrentMonth - Cờ đánh dấu ngày có thuộc tháng đang xem hay không.\n * @param today - Đối tượng Date của ngày hôm nay.\n * @param selectedDate - Ngày đang được chọn (chế độ single).\n * @param minDate - Giới hạn ngày nhỏ nhất.\n * @param maxDate - Giới hạn ngày lớn nhất.\n * @param isDateDisabled - Callback tùy biến kiểm tra ngày bị disable.\n * @returns Đối tượng `CalendarDay` hoàn chỉnh.\n */\nfunction createCalendarDay(\n date: Date,\n isCurrentMonth: boolean,\n today: Date,\n selectedDate?: Date | null,\n minDate?: Date | null,\n maxDate?: Date | null,\n isDateDisabled?: (date: Date) => boolean\n): CalendarDay {\n const isSelected = selectedDate ? isSameDay(date, selectedDate) : false;\n\n let disabled = false;\n if (minDate && isDateBefore(date, minDate)) {\n disabled = true;\n }\n if (maxDate && isDateAfter(date, maxDate)) {\n disabled = true;\n }\n if (isDateDisabled && isDateDisabled(date)) {\n disabled = true;\n }\n\n return {\n date,\n day: date.getDate(),\n month: date.getMonth(),\n year: date.getFullYear(),\n isCurrentMonth,\n isToday: isSameDay(date, today),\n isSelected,\n isDisabled: disabled,\n weekNumber: getISOWeekNumber(date),\n };\n}\n\n/**\n * Định dạng đối tượng `Date` thành chuỗi văn bản theo định dạng mẫu.\n *\n * Các token định dạng hỗ trợ:\n * - `YYYY`: Năm 4 chữ số (VD: 2026)\n * - `YY`: Năm 2 chữ số cuối (VD: 26)\n * - `MMMM`: Tên đầy đủ của tháng (VD: Tháng 8, August)\n * - `MMM`: Tên viết tắt của tháng (VD: Thg 8, Aug)\n * - `MM`: Tháng 2 chữ số có số 0 ở đầu (01-12)\n * - `M`: Tháng 1 hoặc 2 chữ số (1-12)\n * - `DD`: Ngày trong tháng 2 chữ số (01-31)\n * - `D`: Ngày trong tháng 1 hoặc 2 chữ số (1-31)\n * - `dddd`: Tên đầy đủ ngày trong tuần (VD: Thứ Hai, Monday)\n * - `ddd`: Tên viết tắt ngày trong tuần (VD: T2, Mon)\n * - `dd`: Tên tối giản ngày trong tuần (VD: T2, Mo)\n * - `HH`: Giờ 24h định dạng 2 chữ số (00-23)\n * - `H`: Giờ 24h định dạng 1 hoặc 2 chữ số (0-23)\n * - `hh`: Giờ 12h định dạng 2 chữ số (01-12)\n * - `h`: Giờ 12h định dạng 1 hoặc 2 chữ số (1-12)\n * - `mm`: Phút 2 chữ số (00-59)\n * - `m`: Phút 1 hoặc 2 chữ số (0-59)\n * - `ss`: Giây 2 chữ số (00-59)\n * - `s`: Giây 1 hoặc 2 chữ số (0-59)\n * - `A`: Buổi sáng/chiều in hoa (AM/PM)\n * - `a`: Buổi sáng/chiều in thường (am/pm)\n *\n * @param date - Đối tượng `Date` cần định dạng.\n * @param formatStr - Chuỗi mẫu định dạng (mặc định 'DD/MM/YYYY').\n * @param locale - Ngôn ngữ hiển thị ('vi' | 'en' hoặc cấu hình `LocaleConfig`).\n * @returns Chuỗi ngày đã được định dạng. Trả về chuỗi rỗng nếu `date` không hợp lệ.\n */\nexport function formatDate(\n date: Date | null | undefined,\n formatStr: string = \"DD/MM/YYYY\",\n locale?: \"vi\" | \"en\" | LocaleConfig\n): string {\n if (!date || isNaN(date.getTime())) return \"\";\n\n const loc = resolveLocale(locale);\n const year = date.getFullYear();\n const month = date.getMonth();\n const day = date.getDate();\n const hours = date.getHours();\n const minutes = date.getMinutes();\n const seconds = date.getSeconds();\n const dayOfWeek = date.getDay();\n\n const pad = (n: number) => String(n).padStart(2, \"0\");\n\n const hours12 = hours % 12 || 12;\n const ampm = hours >= 12 ? \"PM\" : \"AM\";\n\n const replacements: Record<string, string> = {\n YYYY: String(year),\n YY: String(year).slice(-2),\n MMMM: loc.months[month] ?? \"\",\n MMM: loc.monthsShort[month] ?? \"\",\n MM: pad(month + 1),\n M: String(month + 1),\n DD: pad(day),\n D: String(day),\n dddd: loc.weekdays[dayOfWeek] ?? \"\",\n ddd: loc.weekdaysShort[dayOfWeek] ?? \"\",\n dd: loc.weekdaysMin[dayOfWeek] ?? \"\",\n HH: pad(hours),\n H: String(hours),\n hh: pad(hours12),\n h: String(hours12),\n mm: pad(minutes),\n m: String(minutes),\n ss: pad(seconds),\n s: String(seconds),\n A: ampm,\n a: ampm.toLowerCase(),\n };\n\n // Regex match key tokens\n return formatStr.replace(\n /YYYY|YY|MMMM|MMM|MM|M|DD|D|dddd|ddd|dd|HH|H|hh|h|mm|m|ss|s|A|a/g,\n (match) => replacements[match] ?? match\n );\n}\n\n/**\n * Phân tích cú pháp chuỗi văn bản ngày tháng thành đối tượng `Date` dựa theo mẫu định dạng.\n *\n * @param str - Chuỗi văn bản chứa ngày tháng cần phân tích.\n * @param formatStr - Chuỗi mẫu định dạng tương ứng (mặc định 'DD/MM/YYYY').\n * @returns Đối tượng `Date` hợp lệ hoặc `null` nếu chuỗi không khớp định dạng.\n */\nexport function parseDate(str: string | null | undefined, formatStr: string = \"DD/MM/YYYY\"): Date | null {\n if (!str || typeof str !== \"string\") return null;\n const trimmed = str.trim();\n if (!trimmed) return null;\n\n let year = new Date().getFullYear();\n let month = 1;\n let day = 1;\n let hours = 0;\n let minutes = 0;\n let seconds = 0;\n\n // Simple token parser\n const patternParts = formatStr.match(/YYYY|YY|MM|M|DD|D|HH|H|hh|h|mm|m|ss|s/g);\n if (!patternParts) {\n const d = new Date(trimmed);\n return isNaN(d.getTime()) ? null : d;\n }\n\n // Create regex from formatStr\n let regexStr = \"^\" + formatStr.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n for (const part of patternParts) {\n if (part === \"YYYY\") regexStr = regexStr.replace(\"YYYY\", \"(\\\\d{4})\");\n else if (part === \"YY\") regexStr = regexStr.replace(\"YY\", \"(\\\\d{2})\");\n else if (part === \"MM\" || part === \"M\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"DD\" || part === \"D\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"HH\" || part === \"H\" || part === \"hh\" || part === \"h\")\n regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"mm\" || part === \"m\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"ss\" || part === \"s\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n }\n regexStr += \"$\";\n\n const match = new RegExp(regexStr).exec(trimmed);\n if (!match) {\n // Fallback standard parse\n const fallback = new Date(trimmed);\n return isNaN(fallback.getTime()) ? null : fallback;\n }\n\n patternParts.forEach((part, index) => {\n const rawVal = match[index + 1];\n if (!rawVal) return;\n const val = parseInt(rawVal, 10);\n if (isNaN(val)) return;\n if (part === \"YYYY\") year = val;\n else if (part === \"YY\") year = 2000 + val;\n else if (part === \"MM\" || part === \"M\") month = val;\n else if (part === \"DD\" || part === \"D\") day = val;\n else if (part === \"HH\" || part === \"H\" || part === \"hh\" || part === \"h\") hours = val;\n else if (part === \"mm\" || part === \"m\") minutes = val;\n else if (part === \"ss\" || part === \"s\") seconds = val;\n });\n\n const parsedDate = new Date(year, month - 1, day, hours, minutes, seconds);\n if (isNaN(parsedDate.getTime())) return null;\n return parsedDate;\n}\n\n/**\n * Tự động chuyển đổi định dạng ngày cơ sở (baseFormat) phù hợp với chế độ xem CalendarView (days, months, years).\n * Giữ nguyên phong cách phân cách (separator) và thứ tự token của baseFormat.\n * Ví dụ:\n * - baseFormat = \"DD-MM-YYYY\", view = \"months\" -> \"MM-YYYY\"\n * - baseFormat = \"DD/MM/YYYY\", view = \"months\" -> \"MM/YYYY\"\n * - baseFormat = \"YYYY-MM-DD\", view = \"months\" -> \"YYYY-MM\"\n * - baseFormat = \"YYYY/MM/DD\", view = \"months\" -> \"YYYY/MM\"\n * - baseFormat = \"MM-DD-YYYY\", view = \"months\" -> \"MM-YYYY\"\n * - baseFormat = \"MM/DD/YYYY\", view = \"months\" -> \"MM/YYYY\"\n * - view = \"years\" -> \"YYYY\"\n */\nexport function getAdaptiveViewFormat(baseFormat: string, view: CalendarView = \"days\"): string {\n if (view === \"days\") {\n return baseFormat;\n }\n if (view === \"years\") {\n if (baseFormat.includes(\"YYYY\")) return \"YYYY\";\n if (baseFormat.includes(\"YY\")) return \"YY\";\n return \"YYYY\";\n }\n if (view === \"months\") {\n // 1. Xóa token ngày có ký tự phân cách ở sau: \"DD/\", \"DD-\", \"DD.\", \"DD \"\n let monthFormat = baseFormat.replace(/(?:DD|D|dddd|ddd|dd)\\s*[-/.,\\s]+\\s*/, \"\");\n // 2. Xóa token ngày có ký tự phân cách ở trước: \"-DD\", \"/DD\", \".DD\", \", DD\"\n monthFormat = monthFormat.replace(/\\s*[-/.,\\s]+\\s*(?:DD|D|dddd|ddd|dd)/, \"\");\n // 3. Chuẩn hóa khoảng trắng hoặc dấu phân cách trùng lặp\n monthFormat = monthFormat.replace(/[-/.,\\s]{2,}/g, (match) => match.charAt(0)).trim();\n // 4. Nếu kết quả không chứa ký tự tháng hoặc năm, fallback an toàn\n if (!monthFormat || (!monthFormat.includes(\"M\") && !monthFormat.includes(\"Y\"))) {\n return baseFormat.includes(\"-\") ? \"MM-YYYY\" : \"MM/YYYY\";\n }\n return monthFormat;\n }\n return baseFormat;\n}\n","import React from \"react\";\nimport ChevronLeftIcon from \"../icons/ChevronLeftIcon\";\nimport ChevronRightIcon from \"../icons/ChevronRightIcon\";\nimport DoubleChevronLeftIcon from \"../icons/DoubleChevronLeftIcon\";\nimport DoubleChevronRightIcon from \"../icons/DoubleChevronRightIcon\";\nimport { CalendarHeaderProps } from \"./types\";\nimport { datePickerSizeConfig, datePickerColorConfig } from \"./constants\";\nimport { resolveLocale } from \"./utils\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function CalendarHeader({\n currentMonth,\n view,\n onViewChange,\n onPrevMonth,\n onNextMonth,\n onPrevYear,\n onNextYear,\n onPrevDecade,\n onNextDecade,\n size = \"md\",\n color = \"primary\",\n locale,\n showMonthButtons = true,\n}: CalendarHeaderProps) {\n const loc = resolveLocale(locale);\n const sizeStyles = getSafeConfig(size, datePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, datePickerColorConfig, \"primary\");\n\n const year = currentMonth.getFullYear();\n const month = currentMonth.getMonth();\n\n // Decade range\n const decadeStart = Math.floor(year / 10) * 10;\n const decadeEnd = decadeStart + 9;\n\n const handleTitleClick = () => {\n if (view === \"days\") {\n onViewChange(\"months\");\n } else if (view === \"months\") {\n onViewChange(\"years\");\n } else if (view === \"years\") {\n onViewChange(\"days\");\n }\n };\n\n const handlePrev = () => {\n if (view === \"years\") {\n if (onPrevDecade) {\n onPrevDecade();\n } else {\n onPrevYear();\n }\n } else if (view === \"months\") {\n onPrevYear();\n } else {\n onPrevMonth();\n }\n };\n\n const handleNext = () => {\n if (view === \"years\") {\n if (onNextDecade) {\n onNextDecade();\n } else {\n onNextYear();\n }\n } else if (view === \"months\") {\n onNextYear();\n } else {\n onNextMonth();\n }\n };\n\n const getTitle = () => {\n if (view === \"years\") {\n return `${decadeStart} - ${decadeEnd}`;\n }\n if (view === \"months\") {\n return `${year}`;\n }\n return `${loc.months[month]} ${year}`;\n };\n\n return (\n <div className=\"flex items-center justify-between px-1 pb-1.5 border-b border-neutral-200\">\n <div className=\"flex items-center space-x-0.5\">\n {/* Double Prev (Year/Decade) */}\n {view === \"days\" && (\n <button\n type=\"button\"\n onClick={onPrevYear}\n aria-label=\"Năm trước\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors`}\n >\n <DoubleChevronLeftIcon width={14} height={14} />\n </button>\n )}\n\n {/* Single Prev */}\n {showMonthButtons && (\n <button\n type=\"button\"\n onClick={handlePrev}\n aria-label=\"Tháng trước\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors`}\n >\n <ChevronLeftIcon width={14} height={14} />\n </button>\n )}\n </div>\n\n {/* Center Title View Switcher */}\n <button\n type=\"button\"\n onClick={handleTitleClick}\n className={`${sizeStyles.headerText} px-2 py-1 rounded-md text-neutral-800 hover:bg-neutral-100 hover:${colorStyles.activeText} transition-colors cursor-pointer`}\n >\n {getTitle()}\n </button>\n\n <div className=\"flex items-center space-x-0.5\">\n {/* Single Next */}\n {showMonthButtons && (\n <button\n type=\"button\"\n onClick={handleNext}\n aria-label=\"Tháng tiếp theo\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors`}\n >\n <ChevronRightIcon width={14} height={14} />\n </button>\n )}\n\n {/* Double Next (Year/Decade) */}\n {view === \"days\" && (\n <button\n type=\"button\"\n onClick={onNextYear}\n aria-label=\"Năm tiếp theo\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors`}\n >\n <DoubleChevronRightIcon width={14} height={14} />\n </button>\n )}\n </div>\n </div>\n );\n}\n","import React, { useRef } from \"react\";\nimport { DayGridProps } from \"./types\";\nimport { datePickerSizeConfig, datePickerColorConfig, datePickerRadiusConfig } from \"./constants\";\nimport { resolveLocale } from \"./utils\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function DayGrid({\n days,\n onSelectDate,\n size = \"md\",\n color = \"primary\",\n radius,\n locale,\n firstDayOfWeek = 1,\n showWeekNumbers = false,\n}: DayGridProps) {\n const loc = resolveLocale(locale);\n const sizeStyles = getSafeConfig(size, datePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, datePickerColorConfig, \"primary\");\n const radiusClass = getSafeConfig(radius, datePickerRadiusConfig, \"lg\");\n\n const gridRef = useRef<HTMLDivElement>(null);\n\n // Reorder weekdays header according to firstDayOfWeek\n const weekdays = [...loc.weekdaysShort];\n if (firstDayOfWeek === 1) {\n const sun = weekdays.shift()!;\n weekdays.push(sun);\n }\n\n const hasSelected = days.some((d) => d.isSelected && !d.isDisabled);\n const todayIndex = days.findIndex((d) => d.isToday && !d.isDisabled);\n const firstCurrentMonthIndex = days.findIndex((d) => d.isCurrentMonth && !d.isDisabled);\n const fallbackIndex = firstCurrentMonthIndex !== -1 ? firstCurrentMonthIndex : days.findIndex((d) => !d.isDisabled);\n\n const focusButton = (targetIndex: number) => {\n const allButtons = gridRef.current?.querySelectorAll<HTMLButtonElement>(\"button\");\n const targetBtn = allButtons?.[targetIndex];\n if (targetBtn && !targetBtn.disabled) {\n targetBtn.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n let targetIndex: number | null = null;\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n for (let i = currentIndex + 1; i < days.length; i++) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n for (let i = currentIndex - 1; i >= 0; i--) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (currentIndex + 7 < days.length && !days[currentIndex + 7]!.isDisabled) {\n targetIndex = currentIndex + 7;\n }\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (currentIndex - 7 >= 0 && !days[currentIndex - 7]!.isDisabled) {\n targetIndex = currentIndex - 7;\n }\n } else if (e.key === \"Home\") {\n e.preventDefault();\n const rowStart = currentIndex - (currentIndex % 7);\n for (let i = rowStart; i < rowStart + 7 && i < days.length; i++) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"End\") {\n e.preventDefault();\n const rowEnd = Math.min(days.length - 1, currentIndex - (currentIndex % 7) + 6);\n for (let i = rowEnd; i >= currentIndex - (currentIndex % 7); i--) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const item = days[currentIndex];\n if (item && !item.isDisabled) {\n onSelectDate(item.date);\n }\n return;\n }\n\n if (targetIndex !== null) {\n focusButton(targetIndex);\n }\n };\n\n return (\n <div ref={gridRef} role=\"grid\" aria-label={loc.months[days[15]?.month || 0]} className=\"w-full\">\n {/* Weekdays Header */}\n <div role=\"row\" className={`grid ${showWeekNumbers ? \"grid-cols-8\" : \"grid-cols-7\"} gap-1 mb-1 text-center`}>\n {showWeekNumbers && (\n <div\n role=\"columnheader\"\n aria-label={loc.weekText || \"Week\"}\n className={`flex items-center justify-center ${sizeStyles.cellSize} text-neutral-400 ${sizeStyles.cellText} font-medium`}\n >\n #\n </div>\n )}\n {weekdays.map((dayName) => (\n <div\n key={dayName}\n role=\"columnheader\"\n aria-label={dayName}\n className={`flex items-center justify-center ${sizeStyles.cellSize} text-neutral-500 ${sizeStyles.cellText} font-medium`}\n >\n {dayName}\n </div>\n ))}\n </div>\n\n {/* Days Matrix */}\n <div role=\"rowgroup\" className={`grid ${showWeekNumbers ? \"grid-cols-8\" : \"grid-cols-7\"} gap-y-1 gap-x-1`}>\n {days.map((dayItem, index) => {\n const isRowStart = index % 7 === 0;\n\n // Compute cell styles for single date\n let cellStyle = \"text-neutral-800 hover:bg-neutral-100\";\n\n if (dayItem.isDisabled) {\n cellStyle = \"text-neutral-300 cursor-not-allowed line-through\";\n } else if (dayItem.isSelected) {\n cellStyle = `${colorStyles.selected} font-semibold shadow-xs`;\n } else if (!dayItem.isCurrentMonth) {\n cellStyle = \"text-neutral-400 hover:bg-neutral-100\";\n }\n\n const todayStyle = dayItem.isToday && !dayItem.isSelected ? `ring-1 ${colorStyles.todayRing} font-bold` : \"\";\n const formattedDayLabel = `${dayItem.day} ${loc.months[dayItem.month]} ${dayItem.year}`;\n\n const isTabbable =\n !dayItem.isDisabled &&\n (dayItem.isSelected ||\n (!hasSelected && dayItem.isToday && index === todayIndex) ||\n (!hasSelected && todayIndex === -1 && index === fallbackIndex));\n\n return (\n <React.Fragment key={dayItem.date.toISOString()}>\n {showWeekNumbers && isRowStart && (\n <div\n className={`flex items-center justify-center ${sizeStyles.cellSize} text-neutral-400 ${sizeStyles.cellText} text-[10px] font-mono`}\n >\n W{dayItem.weekNumber}\n </div>\n )}\n <div\n role=\"gridcell\"\n aria-selected={dayItem.isSelected}\n className=\"flex items-center justify-center\"\n >\n <button\n type=\"button\"\n disabled={dayItem.isDisabled}\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => handleKeyDown(e, index)}\n onClick={() => !dayItem.isDisabled && onSelectDate(dayItem.date)}\n aria-label={formattedDayLabel}\n aria-current={dayItem.isToday ? \"date\" : undefined}\n aria-disabled={dayItem.isDisabled}\n className={`flex items-center justify-center ${sizeStyles.cellSize} ${sizeStyles.cellText} ${radiusClass} transition-colors cursor-pointer select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${cellStyle} ${todayStyle}`}\n >\n {dayItem.day}\n </button>\n </div>\n </React.Fragment>\n );\n })}\n </div>\n </div>\n );\n}\n","import React, { useRef } from \"react\";\nimport { MonthGridProps } from \"./types\";\nimport { datePickerSizeConfig, datePickerColorConfig, datePickerRadiusConfig } from \"./constants\";\nimport { resolveLocale, isSameMonth } from \"./utils\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function MonthGrid({\n currentMonth,\n selectedDate,\n onSelectMonth,\n size = \"md\",\n color = \"primary\",\n radius,\n locale,\n}: MonthGridProps) {\n const loc = resolveLocale(locale);\n const sizeStyles = getSafeConfig(size, datePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, datePickerColorConfig, \"primary\");\n const radiusClass = getSafeConfig(radius, datePickerRadiusConfig, \"lg\");\n\n const gridRef = useRef<HTMLDivElement>(null);\n\n const currentYear = currentMonth.getFullYear();\n const today = new Date();\n const todayMonth = today.getMonth();\n const todayYear = today.getFullYear();\n\n const selectedIndex = selectedDate && selectedDate.getFullYear() === currentYear ? selectedDate.getMonth() : -1;\n const activeTabbableIndex = selectedIndex !== -1 ? selectedIndex : todayYear === currentYear ? todayMonth : 0;\n\n const focusButton = (targetIndex: number) => {\n const allButtons = gridRef.current?.querySelectorAll<HTMLButtonElement>(\"button\");\n const targetBtn = allButtons?.[targetIndex];\n if (targetBtn) {\n targetBtn.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n let targetIndex: number | null = null;\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n if (currentIndex + 1 < loc.monthsShort.length) targetIndex = currentIndex + 1;\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n if (currentIndex - 1 >= 0) targetIndex = currentIndex - 1;\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (currentIndex + 3 < loc.monthsShort.length) targetIndex = currentIndex + 3;\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (currentIndex - 3 >= 0) targetIndex = currentIndex - 3;\n } else if (e.key === \"Home\") {\n e.preventDefault();\n targetIndex = 0;\n } else if (e.key === \"End\") {\n e.preventDefault();\n targetIndex = loc.monthsShort.length - 1;\n } else if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelectMonth(currentIndex);\n return;\n }\n\n if (targetIndex !== null) {\n focusButton(targetIndex);\n }\n };\n\n return (\n <div ref={gridRef} role=\"grid\" aria-label=\"Chọn tháng\" className=\"grid grid-cols-3 gap-2 py-2\">\n {loc.monthsShort.map((monthName, idx) => {\n const monthDate = new Date(currentYear, idx, 1);\n const isSelected = selectedDate ? isSameMonth(monthDate, selectedDate) : false;\n const isCurrentMonth = todayYear === currentYear && todayMonth === idx;\n const isTabbable = idx === activeTabbableIndex;\n\n let style = \"text-neutral-800 hover:bg-neutral-100\";\n if (isSelected) {\n style = `${colorStyles.selected} font-semibold shadow-xs`;\n } else if (isCurrentMonth) {\n style = `ring-1 ${colorStyles.todayRing} font-semibold`;\n }\n\n return (\n <div key={monthName} role=\"gridcell\" aria-selected={isSelected} className=\"flex items-center justify-center\">\n <button\n type=\"button\"\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => handleKeyDown(e, idx)}\n onClick={() => onSelectMonth(idx)}\n aria-label={`${monthName} ${currentYear}`}\n className={`w-full flex items-center justify-center h-10 ${sizeStyles.cellText} ${radiusClass} transition-colors cursor-pointer select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${style}`}\n >\n {monthName}\n </button>\n </div>\n );\n })}\n </div>\n );\n}\n","import React, { useRef } from \"react\";\nimport { YearGridProps } from \"./types\";\nimport { datePickerSizeConfig, datePickerColorConfig, datePickerRadiusConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function YearGrid({\n currentMonth,\n selectedDate,\n onSelectYear,\n size = \"md\",\n color = \"primary\",\n radius,\n}: YearGridProps) {\n const sizeStyles = getSafeConfig(size, datePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, datePickerColorConfig, \"primary\");\n const radiusClass = getSafeConfig(radius, datePickerRadiusConfig, \"lg\");\n\n const gridRef = useRef<HTMLDivElement>(null);\n\n const currentYear = currentMonth.getFullYear();\n const selectedYear = selectedDate ? selectedDate.getFullYear() : currentYear;\n const startDecade = Math.floor(currentYear / 10) * 10;\n const todayYear = new Date().getFullYear();\n\n const years: number[] = [];\n for (let i = 0; i < 12; i++) {\n years.push(startDecade + i);\n }\n\n const selectedIndex = years.indexOf(selectedYear);\n const todayIndex = years.indexOf(todayYear);\n const activeTabbableIndex = selectedIndex !== -1 ? selectedIndex : todayIndex !== -1 ? todayIndex : 0;\n\n const focusButton = (targetIndex: number) => {\n const allButtons = gridRef.current?.querySelectorAll<HTMLButtonElement>(\"button\");\n const targetBtn = allButtons?.[targetIndex];\n if (targetBtn) {\n targetBtn.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n let targetIndex: number | null = null;\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n if (currentIndex + 1 < years.length) targetIndex = currentIndex + 1;\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n if (currentIndex - 1 >= 0) targetIndex = currentIndex - 1;\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (currentIndex + 3 < years.length) targetIndex = currentIndex + 3;\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (currentIndex - 3 >= 0) targetIndex = currentIndex - 3;\n } else if (e.key === \"Home\") {\n e.preventDefault();\n targetIndex = 0;\n } else if (e.key === \"End\") {\n e.preventDefault();\n targetIndex = years.length - 1;\n } else if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const yr = years[currentIndex];\n if (yr !== undefined) {\n onSelectYear(yr);\n }\n return;\n }\n\n if (targetIndex !== null) {\n focusButton(targetIndex);\n }\n };\n\n return (\n <div ref={gridRef} role=\"grid\" aria-label=\"Chọn năm\" className=\"grid grid-cols-3 gap-2 py-2\">\n {years.map((yr, idx) => {\n const isSelected = yr === selectedYear;\n const isCurrentYear = yr === todayYear;\n const isTabbable = idx === activeTabbableIndex;\n\n let style = \"text-neutral-800 hover:bg-neutral-100\";\n if (isSelected) {\n style = `${colorStyles.selected} font-semibold shadow-xs`;\n } else if (isCurrentYear) {\n style = `ring-1 ${colorStyles.todayRing} font-semibold`;\n }\n\n return (\n <div key={yr} role=\"gridcell\" aria-selected={isSelected} className=\"flex items-center justify-center\">\n <button\n type=\"button\"\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => handleKeyDown(e, idx)}\n onClick={() => onSelectYear(yr)}\n aria-label={`${yr}`}\n className={`w-full flex items-center justify-center h-10 ${sizeStyles.cellText} ${radiusClass} transition-colors cursor-pointer select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${style}`}\n >\n {yr}\n </button>\n </div>\n );\n })}\n </div>\n );\n}\n","import { useState, useId, useMemo, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useDismiss,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingFocusManager,\n} from \"@floating-ui/react\";\nimport { DateRangePickerProps, DateRange } from \"./types\";\nimport DateRangeCalendar from \"./DateRangeCalendar\";\nimport ChevronDownIcon from \"../icons/ChevronDownIcon\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { formatDate, toDate, getAdaptiveViewFormat } from \"../datepicker/utils\";\nimport {\n dateRangePickerRadiusConfig,\n dateRangePickerSizeConfig,\n dateRangePickerVariantStyles,\n labelColorConfig,\n} from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { CalendarView } from \"../datepicker/types\";\n\nexport default function DateRangePicker({\n ref,\n value: controlledValue,\n defaultValue,\n onChange,\n separator = \" - \",\n format = \"DD/MM/YYYY\",\n displayFormat: customDisplayFormat,\n defaultView = \"days\",\n locale = \"vi\",\n firstDayOfWeek = 1,\n minDate,\n maxDate,\n isDateDisabled,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius,\n label,\n labelPlacement = \"top\",\n placeholder,\n helperText,\n errorMessage,\n name,\n id,\n autoComplete,\n viewTabs = [\"days\", \"months\", \"years\"],\n view: controlledView,\n onViewChange,\n onClear,\n placement = \"bottom-start\",\n disabled = false,\n readOnly = false,\n config,\n className = \"\",\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n popoverClassName = \"\",\n}: DateRangePickerProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = true,\n isFullWidth = false,\n showWeekNumbers = false,\n showViewTabs = false,\n closeOnSelect = true,\n } = config ?? {};\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n const popoverId = `${inputId}-popover`;\n\n const isControlledView = controlledView !== undefined;\n const [internalView, setInternalView] = useState<CalendarView>(defaultView);\n const activeView = isControlledView ? controlledView : internalView;\n\n const baseDisplayFormat = customDisplayFormat || format;\n const currentDisplayFormat = useMemo(() => {\n return getAdaptiveViewFormat(baseDisplayFormat, activeView);\n }, [baseDisplayFormat, activeView]);\n\n const isControlled = controlledValue !== undefined;\n const [internalRange, setInternalRange] = useState<DateRange>(() => {\n const raw = defaultValue;\n if (raw && Array.isArray(raw)) {\n return [toDate(raw[0], format), toDate(raw[1], format)];\n }\n return [null, null];\n });\n const selectedRange: DateRange =\n isControlled && controlledValue && Array.isArray(controlledValue)\n ? [toDate(controlledValue[0], format), toDate(controlledValue[1], format)]\n : internalRange;\n\n const formattedValue =\n selectedRange[0] && selectedRange[1]\n ? `${formatDate(selectedRange[0], currentDisplayFormat, locale)}${separator}${formatDate(\n selectedRange[1],\n currentDisplayFormat,\n locale\n )}`\n : selectedRange[0]\n ? `${formatDate(selectedRange[0], currentDisplayFormat, locale)}${separator}`\n : \"\";\n\n const [isOpen, setIsOpen] = useState(false);\n\n // Floating UI setup\n const {\n refs: { setReference, setFloating },\n floatingStyles,\n context,\n } = useFloating({\n placement,\n open: isOpen && !disabled && !readOnly && !isLoading,\n onOpenChange: setIsOpen,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware: [offsetMiddleware(6), flipMiddleware(), shiftMiddleware({ padding: 8 })],\n });\n\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n });\n const role = useRole(context, { role: \"dialog\" });\n const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: 150,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n // Style configs\n const sizeStyles = getSafeConfig(size, dateRangePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, dateRangePickerRadiusConfig, \"lg\");\n const activeVariantConfig = getSafeConfig(variant, dateRangePickerVariantStyles, \"outline\");\n const variantClass = variant === \"other\" ? \"\" : getSafeConfig(activeColor, activeVariantConfig, \"primary\");\n\n const hasValue = Boolean(selectedRange[0]);\n\n // Handlers\n const handleViewChange = (mode: CalendarView) => {\n if (!isControlledView) {\n setInternalView(mode);\n }\n onViewChange?.(mode);\n };\n\n const handleRangeSelect = (range: DateRange) => {\n if (!isControlled) {\n setInternalRange(range);\n }\n const [start, end] = range;\n\n if (start && end) {\n const outputFormatted: [string, string] = [\n formatDate(start, format, locale),\n formatDate(end, format, locale),\n ];\n onChange?.(outputFormatted);\n\n if (closeOnSelect) {\n setIsOpen(false);\n }\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (e.key === \"ArrowDown\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!isOpen) setIsOpen(true);\n } else if (e.key === \"Escape\" && isOpen) {\n e.preventDefault();\n setIsOpen(false);\n }\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (!isControlled) {\n setInternalRange([null, null]);\n }\n onChange?.(null);\n onClear?.();\n };\n\n const defaultPlaceholder = placeholder || `${currentDisplayFormat}${separator}${currentDisplayFormat}`;\n\n const isFloating = labelPlacement === \"floating\";\n const isHorizontal = labelPlacement === \"left\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-pointer font-bold bg-neutral-white transition-colors duration-150 ${sizeStyles.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${sizeStyles.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${sizeStyles.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const fieldWrapperClasses = [\n \"group/field relative flex\",\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\",\n isFullWidth ? \"w-full\" : \"inline-flex\",\n wrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2 select-none cursor-pointer\",\n sizeStyles.inputHeight,\n radiusClass,\n variantClass,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : \"w-auto\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const inputClasses = [\n \"w-full h-full bg-transparent outline-none border-none text-neutral-800 placeholder-neutral-400 cursor-pointer select-none caret-transparent focus:outline-none\",\n sizeStyles.inputText,\n sizeStyles.inputPadding,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={fieldWrapperClasses}>\n {/* Label */}\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n {/* Input container */}\n <div\n ref={setReference}\n {...getReferenceProps()}\n className={containerClasses}\n >\n {isFloating && renderLabel()}\n\n <input\n ref={ref}\n id={inputId}\n name={name}\n type=\"text\"\n value={formattedValue}\n onClick={() => !disabled && !readOnly && !isLoading && setIsOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n readOnly={true}\n autoComplete={autoComplete}\n placeholder={defaultPlaceholder}\n disabled={disabled || isLoading}\n role=\"combobox\"\n aria-expanded={isOpen && !isLoading}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-required={isRequired}\n aria-invalid={hasError}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={helperText || errorMessage ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n className={inputClasses}\n />\n\n {/* Right actions: Spinner, Clear, ChevronDown Icon */}\n <div className=\"flex items-center space-x-1.5 pr-2.5 shrink-0\">\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center shrink-0\">{renderIconWrapper(<Spinner />)}</div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa khoảng ngày\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${sizeStyles.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n <div\n aria-hidden=\"true\"\n className={`inline-flex items-center justify-center text-neutral-400 hover:text-neutral-600 transition-transform duration-200 ease-in-out cursor-pointer ${\n isOpen ? \"rotate-180\" : \"rotate-0\"\n }`}\n >\n {renderIconWrapper(<ChevronDownIcon className=\"size-full\" />)}\n </div>\n </div>\n </div>\n\n {/* Floating UI Portal */}\n {isMounted && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false} returnFocus={true}>\n <div\n ref={setFloating}\n id={popoverId}\n style={{\n ...floatingStyles,\n ...transitionStyles,\n zIndex: DEFAULT_Z_INDEX.PICKER,\n }}\n {...getFloatingProps()}\n className={popoverClassName}\n >\n <DateRangeCalendar\n value={selectedRange}\n onChange={handleRangeSelect}\n view={activeView}\n onViewChange={handleViewChange}\n minDate={minDate}\n maxDate={maxDate}\n isDateDisabled={isDateDisabled}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n showWeekNumbers={showWeekNumbers}\n size={size}\n color={color}\n radius={radius}\n showViewTabs={showViewTabs}\n viewTabs={viewTabs}\n />\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n\n {/* Helper / Error text with animation */}\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={sizeStyles.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { DateRangeCalendarProps } from \"./types\";\nimport DateRangeHeader from \"./DateRangeHeader\";\nimport DateRangeDayGrid from \"./DateRangeDayGrid\";\nimport DateRangeMonthGrid from \"./DateRangeMonthGrid\";\nimport DateRangeYearGrid from \"./DateRangeYearGrid\";\nimport Tabs from \"../tabs/Tabs\";\nimport TabList from \"../tabs/TabList\";\nimport Tab from \"../tabs/Tab\";\nimport { generateRangeCalendarGrid } from \"./utils\";\nimport { resolveLocale, toDate } from \"../datepicker/utils\";\nimport { dateRangeCalendarRadiusConfig, dateRangePickerSizeConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { CalendarView } from \"../datepicker/types\";\n\nexport default function DateRangeCalendar({\n value,\n onChange,\n view = \"days\",\n onViewChange,\n minDate,\n maxDate,\n isDateDisabled,\n locale = \"vi\",\n firstDayOfWeek = 1,\n showWeekNumbers = false,\n showViewTabs = false,\n viewTabs = [\"days\", \"months\", \"years\"],\n size = \"md\",\n color = \"primary\",\n radius,\n className = \"\",\n}: DateRangeCalendarProps) {\n const sizeStyles = getSafeConfig(size, dateRangePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, dateRangeCalendarRadiusConfig, \"lg\");\n\n const [gridMode, setGridMode] = useState<CalendarView>(view);\n const [prevView, setPrevView] = useState<CalendarView>(view);\n\n if (view !== prevView) {\n setPrevView(view);\n setGridMode(view);\n }\n\n // Range passed from DateRangePicker\n const parsedRangeStart = value ? value[0] : null;\n const parsedRangeEnd = value ? value[1] : null;\n\n // Current navigation month (defaults to range start or today)\n const [currentMonth, setCurrentMonth] = useState<Date>(() => {\n const base = parsedRangeStart || new Date();\n return new Date(base.getFullYear(), base.getMonth(), 1);\n });\n\n // Tabs\n const loc = resolveLocale(locale);\n const tabItems = useMemo(() => {\n const tabLabels = loc.viewTabs || {\n days: \"Ngày\",\n months: \"Tháng\",\n years: \"Năm\",\n };\n return (viewTabs || [\"days\", \"months\", \"years\"]).map((v) => ({\n key: v,\n label: tabLabels[v] || v,\n }));\n }, [viewTabs, loc.viewTabs]);\n\n const handleTabChange = (key: string | number) => {\n const nextView = key as CalendarView;\n setGridMode(nextView);\n setRangeSelectionStart(null);\n onViewChange?.(nextView);\n };\n\n // Navigation handlers\n const handlePrevMonth = () => {\n const prev = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1);\n setCurrentMonth(prev);\n };\n\n const handleNextMonth = () => {\n const next = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1);\n setCurrentMonth(next);\n };\n\n const handlePrevYear = () => {\n const prev = new Date(currentMonth.getFullYear() - 1, currentMonth.getMonth(), 1);\n setCurrentMonth(prev);\n };\n\n const handleNextYear = () => {\n const next = new Date(currentMonth.getFullYear() + 1, currentMonth.getMonth(), 1);\n setCurrentMonth(next);\n };\n\n const handlePrevDecade = () => {\n const prev = new Date(currentMonth.getFullYear() - 10, currentMonth.getMonth(), 1);\n setCurrentMonth(prev);\n };\n\n const handleNextDecade = () => {\n const next = new Date(currentMonth.getFullYear() + 10, currentMonth.getMonth(), 1);\n setCurrentMonth(next);\n };\n\n // Range selection logic\n const [rangeSelectionStart, setRangeSelectionStart] = useState<Date | null>(null);\n const [hoveredDate, setHoveredDate] = useState<Date | null>(null);\n\n const handleSelectDate = (date: Date) => {\n if (!rangeSelectionStart) {\n // Step 1: Chọn ngày bắt đầu\n setRangeSelectionStart(date);\n onChange?.([date, null]);\n } else {\n // Step 2: Chọn ngày kết thúc và hoàn tất range\n let start = rangeSelectionStart;\n let end = date;\n if (date.getTime() < start.getTime()) {\n start = date;\n end = rangeSelectionStart;\n }\n setRangeSelectionStart(null);\n onChange?.([start, end]);\n }\n };\n\n const handleSelectMonthForYear = (targetYear: number, monthIndex: number) => {\n const selectedDateObj = new Date(targetYear, monthIndex, 1);\n setCurrentMonth(selectedDateObj);\n if (showViewTabs && view === \"months\") {\n if (!rangeSelectionStart) {\n setRangeSelectionStart(selectedDateObj);\n onChange?.([selectedDateObj, null]);\n } else {\n let start = rangeSelectionStart;\n let end = selectedDateObj;\n if (selectedDateObj.getTime() < start.getTime()) {\n start = selectedDateObj;\n end = rangeSelectionStart;\n }\n setRangeSelectionStart(null);\n onChange?.([start, end]);\n }\n } else {\n setGridMode(\"days\");\n }\n };\n\n const handleSelectYear = (yr: number) => {\n const selectedDateObj = new Date(yr, 0, 1);\n setCurrentMonth(selectedDateObj);\n if (showViewTabs && view === \"years\") {\n if (!rangeSelectionStart) {\n setRangeSelectionStart(selectedDateObj);\n onChange?.([selectedDateObj, null]);\n } else {\n let start = rangeSelectionStart;\n let end = selectedDateObj;\n if (selectedDateObj.getTime() < start.getTime()) {\n start = selectedDateObj;\n end = rangeSelectionStart;\n }\n setRangeSelectionStart(null);\n onChange?.([start, end]);\n }\n } else if (view === \"months\") {\n setGridMode(\"months\");\n } else {\n setGridMode(\"months\");\n }\n };\n\n // Min/Max dates\n const parsedMin = toDate(minDate);\n const parsedMax = toDate(maxDate);\n\n // Panels calculation (Month 1 and Month 2)\n const month1 = currentMonth;\n const month2 = useMemo(() => {\n if (gridMode === \"months\") {\n return new Date(currentMonth.getFullYear() + 1, currentMonth.getMonth(), 1);\n }\n if (gridMode === \"years\") {\n return new Date(currentMonth.getFullYear() + 10, currentMonth.getMonth(), 1);\n }\n return new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1);\n }, [currentMonth, gridMode]);\n\n // Current visual selection range\n const currentRangeStart = rangeSelectionStart || parsedRangeStart;\n const currentRangeEnd = rangeSelectionStart ? null : parsedRangeEnd;\n\n const daysMonth1 = useMemo(\n () =>\n generateRangeCalendarGrid(\n month1.getFullYear(),\n month1.getMonth(),\n firstDayOfWeek,\n currentRangeStart,\n currentRangeEnd,\n hoveredDate,\n parsedMin,\n parsedMax,\n isDateDisabled\n ),\n [month1, firstDayOfWeek, currentRangeStart, currentRangeEnd, hoveredDate, parsedMin, parsedMax, isDateDisabled]\n );\n\n const daysMonth2 = useMemo(\n () =>\n generateRangeCalendarGrid(\n month2.getFullYear(),\n month2.getMonth(),\n firstDayOfWeek,\n currentRangeStart,\n currentRangeEnd,\n hoveredDate,\n parsedMin,\n parsedMax,\n isDateDisabled\n ),\n [month2, firstDayOfWeek, currentRangeStart, currentRangeEnd, hoveredDate, parsedMin, parsedMax, isDateDisabled]\n );\n\n return (\n <div\n className={`inline-flex flex-col bg-neutral-white border-2 border-neutral-200 shadow-xl ${radiusClass} overflow-hidden select-none ${className}`}\n >\n {/* View Switcher Tabs (Days / Months / Years) */}\n {showViewTabs && tabItems.length > 0 && (\n <div className=\"px-2.5 py-1.5 border-b border-neutral-200\">\n <Tabs\n activeKey={view}\n onChange={handleTabChange}\n size=\"sm\"\n variant=\"solid\"\n color={color}\n fullWidth={true}\n className=\"gap-0!\"\n >\n <TabList className=\"p-0.5\">\n {tabItems.map((item) => (\n <Tab key={item.key} value={item.key} className=\"py-1 px-2 text-xs\">\n {item.label}\n </Tab>\n ))}\n </TabList>\n </Tabs>\n </div>\n )}\n\n {/* 1. Unified Header Spanning Across Both Months */}\n <DateRangeHeader\n month1={month1}\n month2={month2}\n view={gridMode}\n onViewChange={setGridMode}\n onPrevMonth={handlePrevMonth}\n onNextMonth={handleNextMonth}\n onPrevYear={handlePrevYear}\n onNextYear={handleNextYear}\n onPrevDecade={handlePrevDecade}\n onNextDecade={handleNextDecade}\n size={size}\n color={color}\n locale={locale}\n />\n\n {/* 2. Two Month Panels Side by Side */}\n <div className=\"flex flex-row divide-x divide-neutral-200\">\n {/* Month 1 Panel */}\n <div className={`${sizeStyles.calendarPadding} min-w-70`}>\n {gridMode === \"days\" && (\n <DateRangeDayGrid\n days={daysMonth1}\n onSelectDate={handleSelectDate}\n onHoverDate={setHoveredDate}\n size={size}\n color={color}\n radius={radius}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n showWeekNumbers={showWeekNumbers}\n />\n )}\n\n {gridMode === \"months\" && (\n <DateRangeMonthGrid\n currentMonth={month1}\n onSelectMonth={(mIdx) => handleSelectMonthForYear(month1.getFullYear(), mIdx)}\n size={size}\n color={color}\n radius={radius}\n locale={locale}\n rangeStart={currentRangeStart}\n rangeEnd={currentRangeEnd}\n hoveredDate={hoveredDate}\n onHoverMonth={setHoveredDate}\n />\n )}\n\n {gridMode === \"years\" && (\n <DateRangeYearGrid\n currentMonth={month1}\n onSelectYear={handleSelectYear}\n size={size}\n color={color}\n radius={radius}\n rangeStart={currentRangeStart}\n rangeEnd={currentRangeEnd}\n hoveredDate={hoveredDate}\n onHoverYear={setHoveredDate}\n />\n )}\n </div>\n\n {/* Month 2 Panel */}\n <div className={`${sizeStyles.calendarPadding} min-w-70`}>\n {gridMode === \"days\" && (\n <DateRangeDayGrid\n days={daysMonth2}\n onSelectDate={handleSelectDate}\n onHoverDate={setHoveredDate}\n size={size}\n color={color}\n radius={radius}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n showWeekNumbers={showWeekNumbers}\n />\n )}\n\n {gridMode === \"months\" && (\n <DateRangeMonthGrid\n currentMonth={month2}\n onSelectMonth={(mIdx) => handleSelectMonthForYear(month2.getFullYear(), mIdx)}\n size={size}\n color={color}\n radius={radius}\n locale={locale}\n rangeStart={currentRangeStart}\n rangeEnd={currentRangeEnd}\n hoveredDate={hoveredDate}\n onHoverMonth={setHoveredDate}\n />\n )}\n\n {gridMode === \"years\" && (\n <DateRangeYearGrid\n currentMonth={month2}\n onSelectYear={handleSelectYear}\n size={size}\n color={color}\n radius={radius}\n rangeStart={currentRangeStart}\n rangeEnd={currentRangeEnd}\n hoveredDate={hoveredDate}\n onHoverYear={setHoveredDate}\n />\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { LocaleConfig } from \"../datepicker/types\";\nimport {\n DateRangePickerColor,\n DateRangePickerRadius,\n DateRangePickerSize,\n DateRangePickerVariant,\n} from \"./types\";\n\nexport const viLocale: LocaleConfig = {\n months: [\n \"Tháng 1\", \"Tháng 2\", \"Tháng 3\", \"Tháng 4\", \"Tháng 5\", \"Tháng 6\",\n \"Tháng 7\", \"Tháng 8\", \"Tháng 9\", \"Tháng 10\", \"Tháng 11\", \"Tháng 12\",\n ],\n monthsShort: [\n \"Th1\", \"Th2\", \"Th3\", \"Th4\", \"Th5\", \"Th6\",\n \"Th7\", \"Th8\", \"Th9\", \"Th10\", \"Th11\", \"Th12\",\n ],\n weekdays: [\"Chủ Nhật\", \"Thứ Hai\", \"Thứ Ba\", \"Thứ Tư\", \"Thứ Năm\", \"Thứ Sáu\", \"Thứ Bảy\"],\n weekdaysShort: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\"],\n weekdaysMin: [\"C\", \"H\", \"B\", \"T\", \"N\", \"S\", \"B\"],\n todayText: \"Hôm nay\",\n clearText: \"Xóa\",\n weekText: \"Tuần\",\n viewTabs: {\n days: \"Ngày\",\n months: \"Tháng\",\n years: \"Năm\",\n },\n};\n\nexport const enLocale: LocaleConfig = {\n months: [\n \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n \"July\", \"August\", \"September\", \"October\", \"November\", \"December\",\n ],\n monthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n weekdays: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n weekdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n weekdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n todayText: \"Today\",\n clearText: \"Clear\",\n weekText: \"Wk\",\n viewTabs: {\n days: \"Days\",\n months: \"Months\",\n years: \"Years\",\n },\n};\n\nexport const dateRangePickerSizeConfig: Record<\n DateRangePickerSize,\n {\n inputHeight: string;\n inputText: string;\n inputPadding: string;\n icon: string;\n iconSize: number;\n calendarPadding: string;\n cellSize: string;\n cellText: string;\n headerText: string;\n headerButtonSize: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n inputHeight: \"h-6\",\n inputText: \"text-[11px]\",\n inputPadding: \"px-2\",\n icon: \"size-3\",\n iconSize: 12,\n calendarPadding: \"p-2\",\n cellSize: \"w-7 h-7\",\n cellText: \"text-[11px]\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-6 w-6\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n inputHeight: \"h-8\",\n inputText: \"text-xs\",\n inputPadding: \"px-2.5\",\n icon: \"size-3.5\",\n iconSize: 14,\n calendarPadding: \"p-2.5\",\n cellSize: \"w-8 h-8\",\n cellText: \"text-xs\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-7 w-7\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n inputHeight: \"h-10\",\n inputText: \"text-sm\",\n inputPadding: \"px-3\",\n icon: \"size-[18px]\",\n iconSize: 16,\n calendarPadding: \"p-3\",\n cellSize: \"w-9 h-9\",\n cellText: \"text-sm\",\n headerText: \"text-sm font-semibold\",\n headerButtonSize: \"h-8 w-8\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n inputHeight: \"h-12\",\n inputText: \"text-base\",\n inputPadding: \"px-3.5\",\n icon: \"size-5\",\n iconSize: 18,\n calendarPadding: \"p-4\",\n cellSize: \"w-10 h-10\",\n cellText: \"text-base\",\n headerText: \"text-base font-semibold\",\n headerButtonSize: \"h-9 w-9\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n inputHeight: \"h-14\",\n inputText: \"text-lg\",\n inputPadding: \"px-4\",\n icon: \"size-6\",\n iconSize: 20,\n calendarPadding: \"p-4.5\",\n cellSize: \"w-11 h-11\",\n cellText: \"text-base\",\n headerText: \"text-lg font-semibold\",\n headerButtonSize: \"h-10 w-10\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-xs\",\n helper: \"text-sm mt-1\",\n },\n};\n\nexport const dateRangePickerRadiusConfig: Record<DateRangePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const dateRangeCalendarRadiusConfig: Record<DateRangePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-2xl\",\n};\n\nexport const dateRangePickerColorConfig: Record<\n DateRangePickerColor,\n {\n selected: string;\n rangeBg: string;\n rangeText: string;\n hoverBg: string;\n todayRing: string;\n activeText: string;\n badge: string;\n }\n> = {\n primary: {\n selected: \"bg-primary-500 text-neutral-white hover:bg-primary-600\",\n rangeBg: \"bg-primary-100\",\n rangeText: \"text-primary-900\",\n hoverBg: \"hover:bg-primary-200 hover:text-primary-900\",\n todayRing: \"ring-primary-500 text-primary-600\",\n activeText: \"text-primary-600\",\n badge: \"bg-primary-100 text-primary-700\",\n },\n secondary: {\n selected: \"bg-secondary-500 text-neutral-white hover:bg-secondary-600\",\n rangeBg: \"bg-secondary-100\",\n rangeText: \"text-secondary-900\",\n hoverBg: \"hover:bg-secondary-200 hover:text-secondary-900\",\n todayRing: \"ring-secondary-500 text-secondary-600\",\n activeText: \"text-secondary-600\",\n badge: \"bg-secondary-100 text-secondary-700\",\n },\n neutral: {\n selected: \"bg-neutral-800 text-neutral-white hover:bg-neutral-900\",\n rangeBg: \"bg-neutral-200\",\n rangeText: \"text-neutral-900\",\n hoverBg: \"hover:bg-neutral-300 hover:text-neutral-900\",\n todayRing: \"ring-neutral-800 text-neutral-800\",\n activeText: \"text-neutral-800\",\n badge: \"bg-neutral-200 text-neutral-800\",\n },\n error: {\n selected: \"bg-error-500 text-neutral-white hover:bg-error-600\",\n rangeBg: \"bg-error-100\",\n rangeText: \"text-error-900\",\n hoverBg: \"hover:bg-error-200 hover:text-error-900\",\n todayRing: \"ring-error-500 text-error-600\",\n activeText: \"text-error-600\",\n badge: \"bg-error-100 text-error-700\",\n },\n success: {\n selected: \"bg-success-500 text-neutral-white hover:bg-success-600\",\n rangeBg: \"bg-success-100\",\n rangeText: \"text-success-900\",\n hoverBg: \"hover:bg-success-200 hover:text-success-900\",\n todayRing: \"ring-success-500 text-success-600\",\n activeText: \"text-success-600\",\n badge: \"bg-success-100 text-success-700\",\n },\n warning: {\n selected: \"bg-warning-500 text-neutral-950 hover:bg-warning-600\",\n rangeBg: \"bg-warning-100\",\n rangeText: \"text-warning-900\",\n hoverBg: \"hover:bg-warning-200 hover:text-warning-900\",\n todayRing: \"ring-warning-500 text-warning-700\",\n activeText: \"text-warning-700\",\n badge: \"bg-warning-100 text-warning-700\",\n },\n info: {\n selected: \"bg-info-500 text-neutral-white hover:bg-info-600\",\n rangeBg: \"bg-info-100\",\n rangeText: \"text-info-900\",\n hoverBg: \"hover:bg-info-200 hover:text-info-900\",\n todayRing: \"ring-info-500 text-info-600\",\n activeText: \"text-info-600\",\n badge: \"bg-info-100 text-info-700\",\n },\n};\n\nexport const dateRangePickerVariantStyles: Record<\n DateRangePickerVariant,\n Record<DateRangePickerColor, string>\n> = {\n outline: {\n primary:\n \"bg-neutral-white border-primary-300 hover:border-primary-400 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-neutral-white border-secondary-300 hover:border-secondary-400 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-neutral-white border-error-300 hover:border-error-400 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-neutral-white border-success-300 hover:border-success-400 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-neutral-white border-warning-300 hover:border-warning-400 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-neutral-white border-info-300 hover:border-info-400 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n filled: {\n primary:\n \"bg-primary-50/60 border-primary-200 hover:bg-primary-100/60 focus-within:bg-primary-100/60 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-secondary-50/60 border-secondary-200 hover:bg-secondary-100/60 focus-within:bg-secondary-100/60 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-neutral-50/60 border-neutral-200 hover:bg-neutral-200/60 focus-within:bg-neutral-200/60 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-error-50/60 border-error-500 hover:border-error-600 hover:bg-error-100/60 focus-within:bg-error-100/60 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-success-50/60 border-success-200 hover:bg-success-100/60 focus-within:bg-success-100/60 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-warning-50/60 border-warning-200 hover:bg-warning-100/60 focus-within:bg-warning-100/60 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-info-50/60 border-info-200 hover:bg-info-100/60 focus-within:bg-info-100/60 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n ghost: {\n primary:\n \"bg-transparent border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-200/20 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-transparent border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-200/20 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-transparent border-transparent hover:bg-neutral-50/50 focus-within:bg-neutral-50/50 focus-within:border-neutral-200/20 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-transparent border-transparent hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-transparent border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-200/20 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-transparent border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-200/20 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-transparent border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-200/20 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n other: {\n primary: \"\",\n secondary: \"\",\n neutral: \"\",\n error: \"\",\n success: \"\",\n warning: \"\",\n info: \"\",\n },\n};\n\nexport const labelColorConfig: Record<DateRangePickerColor, string> = {\n primary: \"text-primary-500 group-focus-within/field:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/field:text-secondary-600\",\n error: \"text-error-500 group-focus-within/field:text-error-600\",\n success: \"text-success-500 group-focus-within/field:text-success-600\",\n warning: \"text-warning-500 group-focus-within/field:text-warning-600\",\n info: \"text-info-500 group-focus-within/field:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/field:text-neutral-600\",\n};\n","import { DateRangeHeaderProps } from \"./types\";\nimport ChevronLeftIcon from \"../icons/ChevronLeftIcon\";\nimport ChevronRightIcon from \"../icons/ChevronRightIcon\";\nimport DoubleChevronLeftIcon from \"../icons/DoubleChevronLeftIcon\";\nimport DoubleChevronRightIcon from \"../icons/DoubleChevronRightIcon\";\nimport { dateRangePickerSizeConfig, dateRangePickerColorConfig } from \"./constants\";\nimport { resolveLocale } from \"../datepicker/utils\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function DateRangeHeader({\n month1,\n month2,\n view,\n onViewChange,\n onPrevMonth,\n onNextMonth,\n onPrevYear,\n onNextYear,\n onPrevDecade,\n onNextDecade,\n size = \"md\",\n color = \"primary\",\n locale,\n}: DateRangeHeaderProps) {\n const loc = resolveLocale(locale);\n const sizeStyles = getSafeConfig(size, dateRangePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, dateRangePickerColorConfig, \"primary\");\n\n // Title Month 1\n const monthName1 = loc.months[month1.getMonth()];\n const year1 = month1.getFullYear();\n const startDecade1 = Math.floor(year1 / 10) * 10;\n const endDecade1 = startDecade1 + 9;\n\n let title1 = `${monthName1} ${year1}`;\n if (view === \"months\") title1 = `${year1}`;\n if (view === \"years\") title1 = `${startDecade1} - ${endDecade1}`;\n\n // Title Month 2\n const monthName2 = loc.months[month2.getMonth()];\n const year2 = month2.getFullYear();\n const startDecade2 = Math.floor(year2 / 10) * 10;\n const endDecade2 = startDecade2 + 9;\n\n let title2 = `${monthName2} ${year2}`;\n if (view === \"months\") title2 = `${year2}`;\n if (view === \"years\") title2 = `${startDecade2} - ${endDecade2}`;\n\n const handleTitleClick = () => {\n if (view === \"days\") onViewChange(\"months\");\n else if (view === \"months\") onViewChange(\"years\");\n else if (view === \"years\") onViewChange(\"days\");\n };\n\n const handlePrev = () => {\n if (view === \"days\") {\n onPrevMonth();\n } else if (view === \"months\") {\n onPrevYear();\n } else if (view === \"years\") {\n if (onPrevDecade) {\n onPrevDecade();\n } else {\n onPrevYear();\n }\n }\n };\n\n const handleNext = () => {\n if (view === \"days\") {\n onNextMonth();\n } else if (view === \"months\") {\n onNextYear();\n } else if (view === \"years\") {\n if (onNextDecade) {\n onNextDecade();\n } else {\n onNextYear();\n }\n }\n };\n\n return (\n <div className=\"flex items-center justify-between px-2 py-1.5 border-b border-neutral-200\">\n {/* Cụm nút lùi bên trái */}\n <div className=\"flex items-center space-x-0.5\">\n {view === \"days\" && (\n <button\n type=\"button\"\n onClick={onPrevYear}\n aria-label=\"Năm trước\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors cursor-pointer`}\n >\n <DoubleChevronLeftIcon width={14} height={14} />\n </button>\n )}\n <button\n type=\"button\"\n onClick={handlePrev}\n aria-label=\"Tháng trước\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors cursor-pointer`}\n >\n <ChevronLeftIcon width={sizeStyles.iconSize} height={sizeStyles.iconSize} />\n </button>\n </div>\n\n {/* 2 Tiêu đề hiển thị ở giữa tương ứng cho 2 cột tháng */}\n <div className=\"grid grid-cols-2 flex-1 text-center divide-x divide-transparent px-2\">\n <div className=\"flex items-center justify-center\">\n <button\n type=\"button\"\n onClick={handleTitleClick}\n aria-label=\"Đổi chế độ xem lịch\"\n className={`font-semibold text-neutral-800 hover:${colorStyles.activeText} hover:bg-neutral-100 rounded-md px-2 py-1 transition-colors cursor-pointer ${sizeStyles.headerText}`}\n >\n {title1}\n </button>\n </div>\n <div className=\"flex items-center justify-center\">\n <button\n type=\"button\"\n onClick={handleTitleClick}\n aria-label=\"Đổi chế độ xem lịch\"\n className={`font-semibold text-neutral-800 hover:${colorStyles.activeText} hover:bg-neutral-100 rounded-md px-2 py-1 transition-colors cursor-pointer ${sizeStyles.headerText}`}\n >\n {title2}\n </button>\n </div>\n </div>\n\n {/* Cụm nút tiến bên phải */}\n <div className=\"flex items-center space-x-0.5\">\n <button\n type=\"button\"\n onClick={handleNext}\n aria-label=\"Tháng tiếp theo\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors cursor-pointer`}\n >\n <ChevronRightIcon width={sizeStyles.iconSize} height={sizeStyles.iconSize} />\n </button>\n {view === \"days\" && (\n <button\n type=\"button\"\n onClick={onNextYear}\n aria-label=\"Năm tiếp theo\"\n className={`flex items-center justify-center ${sizeStyles.headerButtonSize} rounded-md text-neutral-500 hover:text-neutral-800 hover:bg-neutral-100 transition-colors cursor-pointer`}\n >\n <DoubleChevronRightIcon width={14} height={14} />\n </button>\n )}\n </div>\n </div>\n );\n}\n","import React, { useRef } from \"react\";\nimport { DateRangeDayGridProps } from \"./types\";\nimport { dateRangePickerSizeConfig, dateRangePickerColorConfig, dateRangePickerRadiusConfig } from \"./constants\";\nimport { resolveLocale } from \"../datepicker/utils\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function DateRangeDayGrid({\n days,\n onSelectDate,\n onHoverDate,\n size = \"md\",\n color = \"primary\",\n radius,\n locale,\n firstDayOfWeek = 1,\n showWeekNumbers = false,\n}: DateRangeDayGridProps) {\n const loc = resolveLocale(locale);\n const sizeStyles = getSafeConfig(size, dateRangePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, dateRangePickerColorConfig, \"primary\");\n const radiusClass = getSafeConfig(radius, dateRangePickerRadiusConfig, \"lg\");\n\n const gridRef = useRef<HTMLDivElement>(null);\n\n // Reorder weekdays header according to firstDayOfWeek\n const weekdays = [...loc.weekdaysShort];\n if (firstDayOfWeek === 1) {\n const sun = weekdays.shift()!;\n weekdays.push(sun);\n }\n\n const hasSelected = days.some((d) => (d.isSelected || d.isRangeStart) && !d.isDisabled);\n const todayIndex = days.findIndex((d) => d.isToday && !d.isDisabled);\n const firstCurrentMonthIndex = days.findIndex((d) => d.isCurrentMonth && !d.isDisabled);\n const fallbackIndex = firstCurrentMonthIndex !== -1 ? firstCurrentMonthIndex : days.findIndex((d) => !d.isDisabled);\n\n const focusButton = (targetIndex: number) => {\n const allButtons = gridRef.current?.querySelectorAll<HTMLButtonElement>(\"button\");\n const targetBtn = allButtons?.[targetIndex];\n if (targetBtn && !targetBtn.disabled) {\n targetBtn.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n let targetIndex: number | null = null;\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n for (let i = currentIndex + 1; i < days.length; i++) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n for (let i = currentIndex - 1; i >= 0; i--) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (currentIndex + 7 < days.length && !days[currentIndex + 7]!.isDisabled) {\n targetIndex = currentIndex + 7;\n }\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (currentIndex - 7 >= 0 && !days[currentIndex - 7]!.isDisabled) {\n targetIndex = currentIndex - 7;\n }\n } else if (e.key === \"Home\") {\n e.preventDefault();\n const rowStart = currentIndex - (currentIndex % 7);\n for (let i = rowStart; i < rowStart + 7 && i < days.length; i++) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"End\") {\n e.preventDefault();\n const rowEnd = Math.min(days.length - 1, currentIndex - (currentIndex % 7) + 6);\n for (let i = rowEnd; i >= currentIndex - (currentIndex % 7); i--) {\n if (!days[i]!.isDisabled) {\n targetIndex = i;\n break;\n }\n }\n } else if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const item = days[currentIndex];\n if (item && !item.isDisabled) {\n onSelectDate(item.date);\n }\n return;\n }\n\n if (targetIndex !== null) {\n focusButton(targetIndex);\n }\n };\n\n return (\n <div ref={gridRef} role=\"grid\" aria-label={loc.months[days[15]?.month || 0]} className=\"w-full\">\n {/* Weekdays Header */}\n <div role=\"row\" className={`grid ${showWeekNumbers ? \"grid-cols-8\" : \"grid-cols-7\"} gap-1 mb-1 text-center`}>\n {showWeekNumbers && (\n <div\n role=\"columnheader\"\n aria-label={loc.weekText || \"Week\"}\n className={`flex items-center justify-center ${sizeStyles.cellSize} text-neutral-400 ${sizeStyles.cellText} font-medium`}\n >\n #\n </div>\n )}\n {weekdays.map((dayName) => (\n <div\n key={dayName}\n role=\"columnheader\"\n aria-label={dayName}\n className={`flex items-center justify-center ${sizeStyles.cellSize} text-neutral-500 ${sizeStyles.cellText} font-medium`}\n >\n {dayName}\n </div>\n ))}\n </div>\n\n {/* Days Matrix */}\n <div role=\"rowgroup\" className={`grid ${showWeekNumbers ? \"grid-cols-8\" : \"grid-cols-7\"} gap-y-1 gap-x-1`}>\n {days.map((dayItem, index) => {\n const isRowStart = index % 7 === 0;\n\n // Compute cell styles with range background\n let cellStyle = \"text-neutral-800 hover:bg-neutral-100\";\n let rangeWrapperStyle = \"\";\n\n if (dayItem.isDisabled) {\n cellStyle = \"text-neutral-300 cursor-not-allowed line-through\";\n } else if (dayItem.isRangeStart || dayItem.isRangeEnd) {\n cellStyle = `${colorStyles.selected} font-semibold shadow-xs`;\n if (dayItem.isRangeStart && dayItem.isRangeEnd) {\n rangeWrapperStyle = \"\";\n } else if (dayItem.isRangeStart) {\n rangeWrapperStyle = `${colorStyles.rangeBg} rounded-l-full`;\n } else if (dayItem.isRangeEnd) {\n rangeWrapperStyle = `${colorStyles.rangeBg} rounded-r-full`;\n }\n } else if (dayItem.isSelected) {\n cellStyle = `${colorStyles.selected} font-semibold shadow-xs`;\n } else if (dayItem.isInRange || dayItem.isHoveredRange) {\n cellStyle = `${colorStyles.rangeBg} ${colorStyles.rangeText} rounded-none`;\n rangeWrapperStyle = `${colorStyles.rangeBg}`;\n } else if (!dayItem.isCurrentMonth) {\n cellStyle = \"text-neutral-400 hover:bg-neutral-100\";\n }\n\n const todayStyle = dayItem.isToday && !dayItem.isSelected ? `ring-1 ${colorStyles.todayRing} font-bold` : \"\";\n const formattedDayLabel = `${dayItem.day} ${loc.months[dayItem.month]} ${dayItem.year}`;\n\n const isTabbable =\n !dayItem.isDisabled &&\n (dayItem.isSelected ||\n dayItem.isRangeStart ||\n (!hasSelected && dayItem.isToday && index === todayIndex) ||\n (!hasSelected && todayIndex === -1 && index === fallbackIndex));\n\n return (\n <React.Fragment key={dayItem.date.toISOString()}>\n {showWeekNumbers && isRowStart && (\n <div\n className={`flex items-center justify-center ${sizeStyles.cellSize} text-neutral-400 ${sizeStyles.cellText} text-[10px] font-mono`}\n >\n W{dayItem.weekNumber}\n </div>\n )}\n <div\n role=\"gridcell\"\n aria-selected={dayItem.isSelected || dayItem.isInRange}\n className={`relative flex items-center justify-center ${rangeWrapperStyle}`}\n >\n <button\n type=\"button\"\n disabled={dayItem.isDisabled}\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => handleKeyDown(e, index)}\n onClick={() => !dayItem.isDisabled && onSelectDate(dayItem.date)}\n onMouseEnter={() => !dayItem.isDisabled && onHoverDate?.(dayItem.date)}\n onMouseLeave={() => onHoverDate?.(null)}\n aria-label={formattedDayLabel}\n aria-current={dayItem.isToday ? \"date\" : undefined}\n aria-disabled={dayItem.isDisabled}\n className={`flex items-center justify-center ${sizeStyles.cellSize} ${sizeStyles.cellText} ${radiusClass} transition-colors cursor-pointer select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${cellStyle} ${todayStyle}`}\n >\n {dayItem.day}\n </button>\n </div>\n </React.Fragment>\n );\n })}\n </div>\n </div>\n );\n}\n","import React, { useRef } from \"react\";\nimport { DateRangeMonthGridProps } from \"./types\";\nimport { dateRangePickerSizeConfig, dateRangePickerColorConfig, dateRangePickerRadiusConfig } from \"./constants\";\nimport { resolveLocale } from \"../datepicker/utils\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function DateRangeMonthGrid({\n currentMonth,\n onSelectMonth,\n size = \"md\",\n color = \"primary\",\n radius,\n locale,\n rangeStart,\n rangeEnd,\n hoveredDate,\n onHoverMonth,\n}: DateRangeMonthGridProps) {\n const loc = resolveLocale(locale);\n const sizeStyles = getSafeConfig(size, dateRangePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, dateRangePickerColorConfig, \"primary\");\n const radiusClass = getSafeConfig(radius, dateRangePickerRadiusConfig, \"lg\");\n\n const gridRef = useRef<HTMLDivElement>(null);\n\n const currentYear = currentMonth.getFullYear();\n const today = new Date();\n const todayMonth = today.getMonth();\n const todayYear = today.getFullYear();\n\n const selectedIndex = rangeStart && rangeStart.getFullYear() === currentYear ? rangeStart.getMonth() : -1;\n const activeTabbableIndex = selectedIndex !== -1 ? selectedIndex : todayYear === currentYear ? todayMonth : 0;\n\n const focusButton = (targetIndex: number) => {\n const allButtons = gridRef.current?.querySelectorAll<HTMLButtonElement>(\"button\");\n const targetBtn = allButtons?.[targetIndex];\n if (targetBtn) {\n targetBtn.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n let targetIndex: number | null = null;\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n if (currentIndex + 1 < loc.monthsShort.length) targetIndex = currentIndex + 1;\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n if (currentIndex - 1 >= 0) targetIndex = currentIndex - 1;\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (currentIndex + 3 < loc.monthsShort.length) targetIndex = currentIndex + 3;\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (currentIndex - 3 >= 0) targetIndex = currentIndex - 3;\n } else if (e.key === \"Home\") {\n e.preventDefault();\n targetIndex = 0;\n } else if (e.key === \"End\") {\n e.preventDefault();\n targetIndex = loc.monthsShort.length - 1;\n } else if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelectMonth(currentIndex);\n return;\n }\n\n if (targetIndex !== null) {\n focusButton(targetIndex);\n }\n };\n\n return (\n <div\n ref={gridRef}\n role=\"grid\"\n aria-label=\"Chọn tháng\"\n className=\"grid grid-cols-3 gap-2 py-2\"\n onMouseLeave={() => onHoverMonth?.(null)}\n >\n {loc.monthsShort.map((monthName, idx) => {\n const monthDate = new Date(currentYear, idx, 1);\n const mTime = monthDate.getTime();\n const sTime = rangeStart ? new Date(rangeStart.getFullYear(), rangeStart.getMonth(), 1).getTime() : null;\n const eTime = rangeEnd ? new Date(rangeEnd.getFullYear(), rangeEnd.getMonth(), 1).getTime() : null;\n const hTime = hoveredDate ? new Date(hoveredDate.getFullYear(), hoveredDate.getMonth(), 1).getTime() : null;\n\n const isRangeStart = !!sTime && sTime === mTime;\n const isRangeEnd = !!eTime && eTime === mTime;\n let isInRange = false;\n let isHoveredRange = false;\n\n if (sTime && eTime) {\n isInRange = mTime > sTime && mTime < eTime;\n } else if (sTime && !eTime && hTime) {\n if (hTime > sTime) {\n isHoveredRange = mTime > sTime && mTime <= hTime;\n } else if (hTime < sTime) {\n isHoveredRange = mTime < sTime && mTime >= hTime;\n }\n }\n\n const isCurrentMonth = todayYear === currentYear && todayMonth === idx;\n const isTabbable = idx === activeTabbableIndex;\n\n let style = \"text-neutral-800 hover:bg-neutral-100\";\n if (isRangeStart || isRangeEnd) {\n style = `${colorStyles.selected} font-semibold shadow-xs`;\n } else if (isInRange || isHoveredRange) {\n style = `${colorStyles.rangeBg} ${colorStyles.rangeText}`;\n } else if (isCurrentMonth) {\n style = `ring-1 ${colorStyles.todayRing} font-semibold`;\n }\n\n return (\n <div\n key={monthName}\n role=\"gridcell\"\n aria-selected={isRangeStart || isRangeEnd || isInRange}\n className=\"flex items-center justify-center\"\n >\n <button\n type=\"button\"\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => handleKeyDown(e, idx)}\n onClick={() => onSelectMonth(idx)}\n onMouseEnter={() => onHoverMonth?.(monthDate)}\n aria-label={`${monthName} ${currentYear}`}\n className={`w-full flex items-center justify-center h-10 ${sizeStyles.cellText} ${radiusClass} transition-colors cursor-pointer select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${style}`}\n >\n {monthName}\n </button>\n </div>\n );\n })}\n </div>\n );\n}\n","import React, { useRef } from \"react\";\nimport { DateRangeYearGridProps } from \"./types\";\nimport { dateRangePickerSizeConfig, dateRangePickerColorConfig, dateRangePickerRadiusConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function DateRangeYearGrid({\n currentMonth,\n onSelectYear,\n size = \"md\",\n color = \"primary\",\n radius,\n rangeStart,\n rangeEnd,\n hoveredDate,\n onHoverYear,\n}: DateRangeYearGridProps) {\n const sizeStyles = getSafeConfig(size, dateRangePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, dateRangePickerColorConfig, \"primary\");\n const radiusClass = getSafeConfig(radius, dateRangePickerRadiusConfig, \"lg\");\n\n const gridRef = useRef<HTMLDivElement>(null);\n\n const currentYear = currentMonth.getFullYear();\n const startDecade = Math.floor(currentYear / 10) * 10;\n const todayYear = new Date().getFullYear();\n\n const years: number[] = [];\n for (let i = 0; i < 12; i++) {\n years.push(startDecade + i);\n }\n\n const selectedYear = rangeStart ? rangeStart.getFullYear() : currentYear;\n const selectedIndex = years.indexOf(selectedYear);\n const todayIndex = years.indexOf(todayYear);\n const activeTabbableIndex = selectedIndex !== -1 ? selectedIndex : todayIndex !== -1 ? todayIndex : 0;\n\n const focusButton = (targetIndex: number) => {\n const allButtons = gridRef.current?.querySelectorAll<HTMLButtonElement>(\"button\");\n const targetBtn = allButtons?.[targetIndex];\n if (targetBtn) {\n targetBtn.focus();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>, currentIndex: number) => {\n let targetIndex: number | null = null;\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n if (currentIndex + 1 < years.length) targetIndex = currentIndex + 1;\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n if (currentIndex - 1 >= 0) targetIndex = currentIndex - 1;\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n if (currentIndex + 3 < years.length) targetIndex = currentIndex + 3;\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n if (currentIndex - 3 >= 0) targetIndex = currentIndex - 3;\n } else if (e.key === \"Home\") {\n e.preventDefault();\n targetIndex = 0;\n } else if (e.key === \"End\") {\n e.preventDefault();\n targetIndex = years.length - 1;\n } else if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const yr = years[currentIndex];\n if (yr !== undefined) {\n onSelectYear(yr);\n }\n return;\n }\n\n if (targetIndex !== null) {\n focusButton(targetIndex);\n }\n };\n\n return (\n <div\n ref={gridRef}\n role=\"grid\"\n aria-label=\"Chọn năm\"\n className=\"grid grid-cols-3 gap-2 py-2\"\n onMouseLeave={() => onHoverYear?.(null)}\n >\n {years.map((yr, idx) => {\n const sYr = rangeStart ? rangeStart.getFullYear() : null;\n const eYr = rangeEnd ? rangeEnd.getFullYear() : null;\n const hYr = hoveredDate ? hoveredDate.getFullYear() : null;\n\n const isRangeStart = sYr !== null && yr === sYr;\n const isRangeEnd = eYr !== null && yr === eYr;\n let isInRange = false;\n let isHoveredRange = false;\n\n if (sYr !== null && eYr !== null) {\n isInRange = yr > sYr && yr < eYr;\n } else if (sYr !== null && eYr === null && hYr !== null) {\n if (hYr > sYr) {\n isHoveredRange = yr > sYr && yr <= hYr;\n } else if (hYr < sYr) {\n isHoveredRange = yr < sYr && yr >= hYr;\n }\n }\n\n const isCurrentYear = yr === todayYear;\n const isTabbable = idx === activeTabbableIndex;\n\n let style = \"text-neutral-800 hover:bg-neutral-100\";\n if (isRangeStart || isRangeEnd) {\n style = `${colorStyles.selected} font-semibold shadow-xs`;\n } else if (isInRange || isHoveredRange) {\n style = `${colorStyles.rangeBg} ${colorStyles.rangeText}`;\n } else if (isCurrentYear) {\n style = `ring-1 ${colorStyles.todayRing} font-semibold`;\n }\n\n return (\n <div\n key={yr}\n role=\"gridcell\"\n aria-selected={isRangeStart || isRangeEnd || isInRange}\n className=\"flex items-center justify-center\"\n >\n <button\n type=\"button\"\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => handleKeyDown(e, idx)}\n onClick={() => onSelectYear(yr)}\n onMouseEnter={() => onHoverYear?.(new Date(yr, 0, 1))}\n aria-label={`${yr}`}\n className={`w-full flex items-center justify-center h-10 ${sizeStyles.cellText} ${radiusClass} transition-colors cursor-pointer select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${style}`}\n >\n {yr}\n </button>\n </div>\n );\n })}\n </div>\n );\n}\n","import { DateRangeCalendarDay } from \"./types\";\nimport {\n isSameDay,\n isDateBefore,\n isDateAfter,\n getISOWeekNumber,\n} from \"../datepicker/utils\";\n\n/**\n * Kiểm tra xem một ngày có nằm trong khoảng giữa ngày bắt đầu và ngày kết thúc hay không (bao gồm cả 2 đầu mút).\n * Dùng riêng cho logic chọn khoảng ngày của DateRangePicker.\n *\n * @param date - Ngày cần kiểm tra.\n * @param start - Ngày bắt đầu khoảng.\n * @param end - Ngày kết thúc khoảng.\n * @returns `true` nếu `date` nằm trong khoảng [`start`, `end`].\n */\nexport function isDateInRange(date: Date, start: Date | null, end: Date | null): boolean {\n if (!start || !end) return false;\n const t = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();\n const tStart = new Date(start.getFullYear(), start.getMonth(), start.getDate()).getTime();\n const tEnd = new Date(end.getFullYear(), end.getMonth(), end.getDate()).getTime();\n const min = Math.min(tStart, tEnd);\n const max = Math.max(tStart, tEnd);\n return t >= min && t <= max;\n}\n\nfunction getDaysInMonth(year: number, month: number): number {\n return new Date(year, month + 1, 0).getDate();\n}\n\nfunction createRangeCalendarDay(\n date: Date,\n isCurrentMonth: boolean,\n today: Date,\n rangeStart?: Date | null,\n rangeEnd?: Date | null,\n hoveredDate?: Date | null,\n minDate?: Date | null,\n maxDate?: Date | null,\n isDateDisabled?: (date: Date) => boolean\n): DateRangeCalendarDay {\n const isRangeStart = rangeStart ? isSameDay(date, rangeStart) : false;\n const isRangeEnd = rangeEnd ? isSameDay(date, rangeEnd) : false;\n const isInRange = isDateInRange(date, rangeStart || null, rangeEnd || null);\n const isHoveredRange = rangeStart && !rangeEnd && hoveredDate ? isDateInRange(date, rangeStart, hoveredDate) : false;\n\n let disabled = false;\n if (minDate && isDateBefore(date, minDate)) {\n disabled = true;\n }\n if (maxDate && isDateAfter(date, maxDate)) {\n disabled = true;\n }\n if (isDateDisabled && isDateDisabled(date)) {\n disabled = true;\n }\n\n return {\n date,\n day: date.getDate(),\n month: date.getMonth(),\n year: date.getFullYear(),\n isCurrentMonth,\n isToday: isSameDay(date, today),\n isSelected: isRangeStart || isRangeEnd,\n isDisabled: disabled,\n isRangeStart,\n isRangeEnd,\n isInRange,\n isHoveredRange,\n weekNumber: getISOWeekNumber(date),\n };\n}\n\nexport function generateRangeCalendarGrid(\n year: number,\n month: number,\n firstDayOfWeek: 0 | 1 = 1,\n rangeStart?: Date | null,\n rangeEnd?: Date | null,\n hoveredDate?: Date | null,\n minDate?: Date | null,\n maxDate?: Date | null,\n isDateDisabled?: (date: Date) => boolean\n): DateRangeCalendarDay[] {\n const days: DateRangeCalendarDay[] = [];\n const today = new Date();\n\n const firstDayIndex = new Date(year, month, 1).getDay();\n const prevMonthDays = getDaysInMonth(year, month - 1);\n const currentMonthDays = getDaysInMonth(year, month);\n\n const prevDaysCount = firstDayOfWeek === 1 ? (firstDayIndex === 0 ? 6 : firstDayIndex - 1) : firstDayIndex;\n\n for (let i = prevDaysCount - 1; i >= 0; i--) {\n const d = prevMonthDays - i;\n const date = new Date(year, month - 1, d);\n days.push(\n createRangeCalendarDay(\n date,\n false,\n today,\n rangeStart,\n rangeEnd,\n hoveredDate,\n minDate,\n maxDate,\n isDateDisabled\n )\n );\n }\n\n for (let i = 1; i <= currentMonthDays; i++) {\n const date = new Date(year, month, i);\n days.push(\n createRangeCalendarDay(\n date,\n true,\n today,\n rangeStart,\n rangeEnd,\n hoveredDate,\n minDate,\n maxDate,\n isDateDisabled\n )\n );\n }\n\n const remainingDays = 42 - days.length;\n for (let i = 1; i <= remainingDays; i++) {\n const date = new Date(year, month + 1, i);\n days.push(\n createRangeCalendarDay(\n date,\n false,\n today,\n rangeStart,\n rangeEnd,\n hoveredDate,\n minDate,\n maxDate,\n isDateDisabled\n )\n );\n }\n\n return days;\n}\n","import { useState, useId, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useDismiss,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingFocusManager,\n} from \"@floating-ui/react\";\nimport { TimePickerProps } from \"./types\";\nimport TimeView from \"./TimeView\";\nimport ChevronDownIcon from \"../icons/ChevronDownIcon\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { formatTime, getDefaultFormat, parseTimeToDate } from \"./utils\";\nimport {\n timePickerRadiusConfig,\n timePickerSizeConfig,\n timePickerVariantStyles,\n labelColorConfig,\n} from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function TimePicker({\n ref,\n value: controlledValue,\n defaultValue,\n onChange,\n format = \"HH:mm:ss\",\n displayFormat: customDisplayFormat,\n use12Hours = false,\n showSeconds = true,\n hourStep = 1,\n minuteStep = 1,\n secondStep = 1,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius,\n label,\n labelPlacement = \"top\",\n placeholder,\n helperText,\n errorMessage,\n name,\n id,\n autoComplete,\n onClear,\n placement = \"bottom-start\",\n disabled = false,\n readOnly = false,\n config,\n className = \"\",\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n popoverClassName = \"\",\n}: TimePickerProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = true,\n isFullWidth = false,\n closeOnSelect = false,\n } = config ?? {};\n\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n const popoverId = `${inputId}-popover`;\n\n const defaultFmt = getDefaultFormat(use12Hours, showSeconds);\n const resolvedFormat = format || defaultFmt;\n const baseDisplayFormat = customDisplayFormat || resolvedFormat;\n\n const isControlled = controlledValue !== undefined;\n const [internalDate, setInternalDate] = useState<Date | null>(() => parseTimeToDate(defaultValue));\n const selectedTime = isControlled ? parseTimeToDate(controlledValue) : internalDate;\n const formattedValue = selectedTime ? formatTime(selectedTime, baseDisplayFormat) : \"\";\n\n const [isOpen, setIsOpen] = useState(false);\n\n const {\n refs: { setReference, setFloating },\n floatingStyles,\n context,\n } = useFloating({\n placement,\n open: isOpen && !disabled && !readOnly && !isLoading,\n onOpenChange: setIsOpen,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware: [offsetMiddleware(6), flipMiddleware(), shiftMiddleware({ padding: 8 })],\n });\n\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n });\n const role = useRole(context, { role: \"dialog\" });\n const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: 150,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n // Style configs\n const sizeStyles = getSafeConfig(size, timePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, timePickerRadiusConfig, \"lg\");\n const variantClass =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, timePickerVariantStyles, \"outline\"), \"primary\");\n\n const hasValue = Boolean(selectedTime);\n\n const handleTimeSelect = (time: Date | null) => {\n if (!isControlled) {\n setInternalDate(time);\n }\n const formattedOutput = time ? formatTime(time, resolvedFormat) : \"\";\n onChange?.(formattedOutput);\n\n if (closeOnSelect) {\n setIsOpen(false);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (e.key === \"ArrowDown\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!isOpen) setIsOpen(true);\n } else if (e.key === \"Escape\" && isOpen) {\n e.preventDefault();\n setIsOpen(false);\n }\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (!isControlled) {\n setInternalDate(null);\n }\n onChange?.(null);\n onClear?.();\n };\n\n const defaultPlaceholder = placeholder || baseDisplayFormat;\n\n const isFloating = labelPlacement === \"floating\";\n const isHorizontal = labelPlacement === \"left\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-pointer font-bold bg-neutral-white transition-colors duration-150 ${sizeStyles.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${sizeStyles.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${sizeStyles.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const fieldWrapperClasses = [\n \"group/timepicker relative flex\",\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\",\n isFullWidth ? \"w-full\" : \"inline-flex\",\n wrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2 select-none cursor-pointer\",\n sizeStyles.inputHeight,\n radiusClass,\n variantClass,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : \"w-auto\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const inputClasses = [\n \"w-full h-full bg-transparent outline-none border-none text-neutral-800 placeholder-neutral-400 cursor-pointer select-none caret-transparent focus:outline-none\",\n sizeStyles.inputText,\n sizeStyles.inputPadding,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={fieldWrapperClasses}>\n {/* Label (Top / Left) */}\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n {/* Input container */}\n <div ref={setReference} {...getReferenceProps()} className={containerClasses}>\n {isFloating && renderLabel()}\n\n <input\n ref={ref}\n id={inputId}\n name={name}\n type=\"text\"\n value={formattedValue}\n onClick={() => !disabled && !readOnly && !isLoading && setIsOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n readOnly={true}\n autoComplete={autoComplete}\n placeholder={defaultPlaceholder}\n disabled={disabled || isLoading}\n role=\"combobox\"\n aria-expanded={isOpen && !isLoading}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-required={isRequired}\n aria-invalid={hasError}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={helperText || errorMessage ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n className={inputClasses}\n />\n\n {/* Right actions: Spinner, Clear, ChevronDown Icon */}\n <div className=\"flex items-center space-x-1.5 pr-2.5 shrink-0\">\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center shrink-0\">{renderIconWrapper(<Spinner />)}</div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa thời gian\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${sizeStyles.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n <div\n aria-hidden=\"true\"\n className={`inline-flex items-center justify-center text-neutral-400 hover:text-neutral-600 transition-transform duration-200 ease-in-out cursor-pointer ${\n isOpen ? \"rotate-180\" : \"rotate-0\"\n }`}\n >\n {renderIconWrapper(<ChevronDownIcon className=\"size-full\" />)}\n </div>\n </div>\n </div>\n\n {/* Floating UI Portal */}\n {isMounted && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false} returnFocus={true}>\n <div\n ref={setFloating}\n id={popoverId}\n style={{\n ...floatingStyles,\n ...transitionStyles,\n zIndex: DEFAULT_Z_INDEX.PICKER,\n }}\n {...getFloatingProps()}\n className={popoverClassName}\n >\n <TimeView\n value={selectedTime}\n onChange={handleTimeSelect}\n ariaLabel={typeof label === \"string\" ? `${label} selector` : \"Time selector\"}\n use12Hours={use12Hours}\n showSeconds={showSeconds}\n hourStep={hourStep}\n minuteStep={minuteStep}\n secondStep={secondStep}\n minTime={minTime}\n maxTime={maxTime}\n disabledHours={disabledHours}\n disabledMinutes={disabledMinutes}\n disabledSeconds={disabledSeconds}\n size={size}\n color={color}\n radius={radius}\n />\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n\n {/* Helper / Error text with animation */}\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={sizeStyles.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { TimePeriod, TimeViewProps } from \"./types\";\nimport { timePickerSizeConfig, timeViewRadiusConfig } from \"./constants\";\nimport {\n checkIsDisabled,\n createDateWithTime,\n formatTime,\n getDefaultFormat,\n padZero,\n parseTimeToDate,\n} from \"./utils\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport TimeColumn from \"./TimeColumn\";\n\n/**\n * Component hiển thị bảng điều khiển chọn thời gian dạng lưới các cột cuộn (Giờ, Phút, Giây, AM/PM)\n * Có thể sử dụng độc lập (Standalone) hoặc bên trong Popover của TimePicker/TimeRangePicker.\n */\nexport default function TimeView({\n value,\n onChange,\n ariaLabel = \"Time selector\",\n use12Hours = false,\n showSeconds = true,\n hourStep = 1,\n minuteStep = 1,\n secondStep = 1,\n minTime: customMinTime,\n maxTime: customMaxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n size = \"md\",\n color = \"primary\",\n radius,\n className = \"\",\n}: TimeViewProps) {\n const minTime = useMemo(() => parseTimeToDate(customMinTime), [customMinTime]);\n const maxTime = useMemo(() => parseTimeToDate(customMaxTime), [customMaxTime]);\n\n const defaultFormat = getDefaultFormat(use12Hours, showSeconds);\n\n const radiusClass = getSafeConfig(radius, timeViewRadiusConfig, \"lg\");\n const sizeStyles = getSafeConfig(size, timePickerSizeConfig, \"md\");\n\n // Current values\n const currentHour24 = value ? value.getHours() : 0;\n const currentHour12 = currentHour24 % 12 === 0 ? 12 : currentHour24 % 12;\n const currentMinute = value ? value.getMinutes() : 0;\n const currentSecond = value ? value.getSeconds() : 0;\n const currentPeriod: TimePeriod = currentHour24 >= 12 ? \"PM\" : \"AM\";\n\n // Generate Hour items\n const hourItems = useMemo(() => {\n const items = [];\n if (use12Hours) {\n for (let h = 1; h <= 12; h += hourStep) {\n const corresponding24 =\n currentPeriod === \"PM\" ? (h === 12 ? 12 : h + 12) : h === 12 ? 0 : h;\n\n const disabled = checkIsDisabled(\n \"hour\",\n corresponding24,\n currentHour24,\n currentMinute,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds\n );\n\n items.push({\n value: h,\n label: padZero(h),\n disabled,\n });\n }\n } else {\n for (let h = 0; h < 24; h += hourStep) {\n const disabled = checkIsDisabled(\n \"hour\",\n h,\n currentHour24,\n currentMinute,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds\n );\n\n items.push({\n value: h,\n label: padZero(h),\n disabled,\n });\n }\n }\n return items;\n }, [\n use12Hours,\n hourStep,\n currentPeriod,\n currentHour24,\n currentMinute,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n ]);\n\n // Generate Minute items\n const minuteItems = useMemo(() => {\n const items = [];\n for (let m = 0; m < 60; m += minuteStep) {\n const disabled = checkIsDisabled(\n \"minute\",\n m,\n currentHour24,\n currentMinute,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds\n );\n\n items.push({\n value: m,\n label: padZero(m),\n disabled,\n });\n }\n return items;\n }, [\n minuteStep,\n currentHour24,\n currentMinute,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n ]);\n\n // Generate Second items\n const secondItems = useMemo(() => {\n if (!showSeconds) return [];\n const items = [];\n for (let s = 0; s < 60; s += secondStep) {\n const disabled = checkIsDisabled(\n \"second\",\n s,\n currentHour24,\n currentMinute,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds\n );\n\n items.push({\n value: s,\n label: padZero(s),\n disabled,\n });\n }\n return items;\n }, [\n showSeconds,\n secondStep,\n currentHour24,\n currentMinute,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n ]);\n\n // Period items (AM / PM)\n const periodItems = useMemo(\n () => [\n { value: \"AM\", label: \"AM\" },\n { value: \"PM\", label: \"PM\" },\n ],\n []\n );\n\n // Handlers for selecting units\n const handleHourSelect = (val: number | string) => {\n let hourNum = Number(val);\n if (use12Hours) {\n if (currentPeriod === \"PM\" && hourNum < 12) hourNum += 12;\n if (currentPeriod === \"AM\" && hourNum === 12) hourNum = 0;\n }\n const newDate = createDateWithTime(hourNum, currentMinute, currentSecond);\n onChange?.(newDate);\n };\n\n const handleMinuteSelect = (val: number | string) => {\n const minuteNum = Number(val);\n const newDate = createDateWithTime(currentHour24, minuteNum, currentSecond);\n onChange?.(newDate);\n };\n\n const handleSecondSelect = (val: number | string) => {\n const secondNum = Number(val);\n const newDate = createDateWithTime(currentHour24, currentMinute, secondNum);\n onChange?.(newDate);\n };\n\n const handlePeriodSelect = (val: number | string) => {\n const p = val as TimePeriod;\n let newHour = currentHour24;\n if (p === \"AM\" && newHour >= 12) {\n newHour -= 12;\n } else if (p === \"PM\" && newHour < 12) {\n newHour += 12;\n }\n const newDate = createDateWithTime(newHour, currentMinute, currentSecond);\n onChange?.(newDate);\n };\n\n const placeholderHeader = showSeconds ? \"--:--:--\" : \"--:--\";\n\n return (\n <div\n aria-label={ariaLabel}\n className={`inline-flex flex-col bg-neutral-white border-2 border-neutral-200 shadow-xl overflow-hidden select-none ${radiusClass} ${className}`}\n >\n {/* Header with currently selected time */}\n <div className=\"flex items-center justify-center px-4 py-2 border-b border-neutral-200 bg-neutral-50/50\">\n <span className={`text-neutral-700 tracking-wider font-mono ${sizeStyles.headerText}`}>\n {value ? formatTime(value, defaultFormat) : placeholderHeader}\n </span>\n </div>\n\n {/* Columns Container */}\n <div className={`flex divide-x divide-neutral-200 ${sizeStyles.panelPadding}`}>\n {/* Hours Column */}\n <TimeColumn\n ariaLabel=\"Giờ\"\n items={hourItems}\n selectedValue={use12Hours ? currentHour12 : value ? currentHour24 : null}\n onSelect={handleHourSelect}\n size={size}\n color={color}\n radius={radius}\n />\n\n {/* Minutes Column */}\n <TimeColumn\n ariaLabel=\"Phút\"\n items={minuteItems}\n selectedValue={value ? currentMinute : null}\n onSelect={handleMinuteSelect}\n size={size}\n color={color}\n radius={radius}\n />\n\n {/* Seconds Column */}\n {showSeconds && (\n <TimeColumn\n ariaLabel=\"Giây\"\n items={secondItems}\n selectedValue={value ? currentSecond : null}\n onSelect={handleSecondSelect}\n size={size}\n color={color}\n radius={radius}\n />\n )}\n\n {/* Period (AM/PM) Column */}\n {use12Hours && (\n <TimeColumn\n ariaLabel=\"Buổi\"\n items={periodItems}\n selectedValue={value ? currentPeriod : null}\n onSelect={handlePeriodSelect}\n size={size}\n color={color}\n radius={radius}\n />\n )}\n </div>\n </div>\n );\n}\n","import { TimePickerColor, TimePickerRadius, TimePickerSize, TimePickerVariant } from \"./types\";\n\n/**\n * Cấu hình kích thước chuẩn hóa cho TimePicker (5 sizes: xs, sm, md, lg, xl)\n */\nexport const timePickerSizeConfig: Record<\n TimePickerSize,\n {\n inputHeight: string;\n inputText: string;\n inputPadding: string;\n icon: string;\n iconSize: number;\n panelPadding: string;\n columnWidth: string;\n columnHeight: string;\n itemHeight: string;\n itemText: string;\n headerText: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n inputHeight: \"h-6\",\n inputText: \"text-[11px]\",\n inputPadding: \"px-2\",\n icon: \"size-3\",\n iconSize: 12,\n panelPadding: \"p-1.5\",\n columnWidth: \"w-12\",\n columnHeight: \"h-36\",\n itemHeight: \"h-6\",\n itemText: \"text-[11px]\",\n headerText: \"text-[11px] font-semibold\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n inputHeight: \"h-8\",\n inputText: \"text-xs\",\n inputPadding: \"px-2.5\",\n icon: \"size-3.5\",\n iconSize: 14,\n panelPadding: \"p-2\",\n columnWidth: \"w-14\",\n columnHeight: \"h-44\",\n itemHeight: \"h-7\",\n itemText: \"text-xs\",\n headerText: \"text-xs font-semibold\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n inputHeight: \"h-10\",\n inputText: \"text-sm\",\n inputPadding: \"px-3\",\n icon: \"size-[18px]\",\n iconSize: 16,\n panelPadding: \"p-2.5\",\n columnWidth: \"w-16\",\n columnHeight: \"h-52\",\n itemHeight: \"h-8\",\n itemText: \"text-sm\",\n headerText: \"text-sm font-semibold\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n inputHeight: \"h-12\",\n inputText: \"text-base\",\n inputPadding: \"px-3.5\",\n icon: \"size-5\",\n iconSize: 18,\n panelPadding: \"p-3\",\n columnWidth: \"w-18\",\n columnHeight: \"h-60\",\n itemHeight: \"h-9\",\n itemText: \"text-base\",\n headerText: \"text-base font-semibold\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n inputHeight: \"h-14\",\n inputText: \"text-lg\",\n inputPadding: \"px-4\",\n icon: \"size-6\",\n iconSize: 20,\n panelPadding: \"p-3.5\",\n columnWidth: \"w-20\",\n columnHeight: \"h-68\",\n itemHeight: \"h-10\",\n itemText: \"text-base\",\n headerText: \"text-lg font-semibold\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-xs\",\n helper: \"text-sm mt-1\",\n },\n};\n\n/**\n * Cấu hình mức độ bo góc cho ô nhập liệu TimePicker\n */\nexport const timePickerRadiusConfig: Record<TimePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\n/**\n * Cấu hình mức độ bo góc cho khung bảng TimeView (tương tự calendarRadiusConfig)\n */\nexport const timeViewRadiusConfig: Record<TimePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-2xl\",\n};\n\n/**\n * Cấu hình mức độ bo góc cho từng mục (item) trong cột TimeColumn\n */\nexport const timeItemRadiusConfig: Record<TimePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-xs\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-lg\",\n full: \"rounded-full\",\n};\n\n/**\n * Bảng phối màu chuẩn Design System cho TimePicker (7 chủ đề màu)\n */\nexport const timePickerColorConfig: Record<\n TimePickerColor,\n {\n selected: string;\n hoverBg: string;\n activeText: string;\n accentBg: string;\n }\n> = {\n primary: {\n selected: \"bg-primary-500 text-neutral-white font-semibold shadow-xs hover:bg-primary-600\",\n hoverBg: \"hover:bg-primary-100 hover:text-primary-900\",\n activeText: \"text-primary-600\",\n accentBg: \"bg-primary-500\",\n },\n secondary: {\n selected: \"bg-secondary-500 text-neutral-white font-semibold shadow-xs hover:bg-secondary-600\",\n hoverBg: \"hover:bg-secondary-100 hover:text-secondary-900\",\n activeText: \"text-secondary-600\",\n accentBg: \"bg-secondary-500\",\n },\n neutral: {\n selected: \"bg-neutral-800 text-neutral-white font-semibold shadow-xs hover:bg-neutral-900\",\n hoverBg: \"hover:bg-neutral-200 hover:text-neutral-900\",\n activeText: \"text-neutral-800\",\n accentBg: \"bg-neutral-800\",\n },\n error: {\n selected: \"bg-error-500 text-neutral-white font-semibold shadow-xs hover:bg-error-600\",\n hoverBg: \"hover:bg-error-100 hover:text-error-900\",\n activeText: \"text-error-600\",\n accentBg: \"bg-error-500\",\n },\n success: {\n selected: \"bg-success-500 text-neutral-white font-semibold shadow-xs hover:bg-success-600\",\n hoverBg: \"hover:bg-success-100 hover:text-success-900\",\n activeText: \"text-success-600\",\n accentBg: \"bg-success-500\",\n },\n warning: {\n selected: \"bg-warning-500 text-neutral-950 font-semibold shadow-xs hover:bg-warning-600\",\n hoverBg: \"hover:bg-warning-100 hover:text-warning-900\",\n activeText: \"text-warning-700\",\n accentBg: \"bg-warning-500\",\n },\n info: {\n selected: \"bg-info-500 text-neutral-white font-semibold shadow-xs hover:bg-info-600\",\n hoverBg: \"hover:bg-info-100 hover:text-info-900\",\n activeText: \"text-info-600\",\n accentBg: \"bg-info-500\",\n },\n};\n\n/**\n * Cấu hình màu chữ của nhãn label theo màu chủ đề\n */\nexport const labelColorConfig: Record<TimePickerColor, string> = {\n primary: \"text-primary-500 group-focus-within/timepicker:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/timepicker:text-secondary-600\",\n error: \"text-error-500 group-focus-within/timepicker:text-error-600\",\n success: \"text-success-500 group-focus-within/timepicker:text-success-600\",\n warning: \"text-warning-500 group-focus-within/timepicker:text-warning-600\",\n info: \"text-info-500 group-focus-within/timepicker:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/timepicker:text-neutral-600\",\n};\n\n/**\n * Cấu hình biến thể giao diện ô nhập (outline, filled, ghost) kết hợp màu chủ đề\n */\nexport const timePickerVariantStyles: Record<\n Exclude<TimePickerVariant, \"other\">,\n Record<TimePickerColor, string>\n> = {\n outline: {\n primary:\n \"bg-neutral-white border-primary-300 hover:border-primary-400 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-neutral-white border-secondary-300 hover:border-secondary-400 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-neutral-white border-error-300 hover:border-error-400 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-neutral-white border-success-300 hover:border-success-400 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-neutral-white border-warning-300 hover:border-warning-400 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-neutral-white border-info-300 hover:border-info-400 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n filled: {\n primary:\n \"bg-primary-50/60 border-primary-200 hover:bg-primary-100/60 focus-within:bg-primary-100/60 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-secondary-50/60 border-secondary-200 hover:bg-secondary-100/60 focus-within:bg-secondary-100/60 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-neutral-50/60 border-neutral-200 hover:bg-neutral-200/60 focus-within:bg-neutral-200/60 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-error-50/60 border-error-500 hover:border-error-600 hover:bg-error-100/60 focus-within:bg-error-100/60 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-success-50/60 border-success-200 hover:bg-success-100/60 focus-within:bg-success-100/60 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-warning-50/60 border-warning-200 hover:bg-warning-100/60 focus-within:bg-warning-100/60 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-info-50/60 border-info-200 hover:bg-info-100/60 focus-within:bg-info-100/60 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n ghost: {\n primary:\n \"bg-transparent border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-200/20 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-transparent border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-200/20 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-transparent border-transparent hover:bg-neutral-50/50 focus-within:bg-neutral-50/50 focus-within:border-neutral-200/20 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-transparent border-transparent hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-transparent border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-200/20 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-transparent border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-200/20 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-transparent border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-200/20 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n};\n","import { TimeObject, TimePeriod, TimeValue } from \"./types\";\n\n/**\n * Định dạng số thành chuỗi 2 chữ số với số 0 đứng trước nếu nhỏ hơn 10.\n *\n * @param val - Số cần đệm (ví dụ: 5 -> \"05\", 12 -> \"12\").\n * @returns Chuỗi số 2 chữ số.\n */\nexport function padZero(val: number): string {\n return val < 10 ? `0${val}` : `${val}`;\n}\n\n/**\n * Xác định định dạng thời gian mặc định theo cờ 12 giờ và cờ hiển thị giây.\n *\n * @param use12Hours - Có sử dụng chế độ 12 giờ kèm AM/PM không.\n * @param showSeconds - Có hiển thị giây không.\n * @returns Chuỗi định dạng mặc định (ví dụ: `'HH:mm:ss'`, `'hh:mm A'`).\n */\nexport function getDefaultFormat(use12Hours = false, showSeconds = true): string {\n if (use12Hours) {\n return showSeconds ? \"hh:mm:ss A\" : \"hh:mm A\";\n }\n return showSeconds ? \"HH:mm:ss\" : \"HH:mm\";\n}\n\n/**\n * Chuyển đổi linh hoạt một giá trị TimeValue (chuỗi thời gian, Date, hoặc null) thành đối tượng Date.\n * Thiết lập ngày là ngày hiện tại và gán chính xác giờ, phút, giây.\n *\n * @param val - Giá trị thời gian cần chuyển đổi.\n * @returns Đối tượng `Date` hợp lệ hoặc `null` nếu không phân tích được.\n */\nexport function parseTimeToDate(val?: TimeValue): Date | null {\n if (!val) return null;\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? null : new Date(val);\n }\n\n if (typeof val !== \"string\") return null;\n const str = val.trim();\n if (!str) return null;\n\n // Thử phân tích chuỗi chuẩn ISO (ví dụ: 2026-08-31T14:30:00)\n if (str.includes(\"T\")) {\n const d = new Date(str);\n if (!isNaN(d.getTime())) return d;\n }\n\n // Phân tích biểu thức chính quy (H:m[:s] [AM|PM])\n const timeRegex = /^(\\d{1,2}):(\\d{1,2})(?::(\\d{1,2}))?(?:\\s*([ap]m))?$/i;\n const match = str.match(timeRegex);\n\n if (match) {\n let hours = parseInt(match[1]!, 10);\n const minutes = parseInt(match[2]!, 10);\n const seconds = match[3] ? parseInt(match[3], 10) : 0;\n const period = match[4]?.toUpperCase() as TimePeriod | undefined;\n\n if (period) {\n if (period === \"PM\" && hours < 12) hours += 12;\n if (period === \"AM\" && hours === 12) hours = 0;\n }\n\n if (hours >= 0 && hours < 24 && minutes >= 0 && minutes < 60 && seconds >= 0 && seconds < 60) {\n const now = new Date();\n now.setHours(hours, minutes, seconds, 0);\n return now;\n }\n }\n\n return null;\n}\n\n/**\n * Định dạng một đối tượng Date thành chuỗi thời gian dựa theo mẫu format quy định.\n *\n * Các token hỗ trợ:\n * - `HH`: Giờ 24h (00 - 23)\n * - `H`: Giờ 24h không đệm 0 (0 - 23)\n * - `hh`: Giờ 12h (01 - 12)\n * - `h`: Giờ 12h không đệm 0 (1 - 12)\n * - `mm`: Phút 2 chữ số (00 - 59)\n * - `m`: Phút không đệm 0 (0 - 59)\n * - `ss`: Giây 2 chữ số (00 - 59)\n * - `s`: Giây không đệm 0 (0 - 59)\n * - `A`: Buổi viết hoa (AM / PM)\n * - `a`: Buổi viết thường (am / pm)\n *\n * @param date - Đối tượng Date cần định dạng.\n * @param formatStr - Mẫu định dạng chuỗi (mặc định `'HH:mm:ss'`).\n * @returns Chuỗi thời gian đã được định dạng.\n */\nexport function formatTime(date: Date | null | undefined, formatStr = \"HH:mm:ss\"): string {\n if (!date || isNaN(date.getTime())) return \"\";\n\n const fullHours = date.getHours();\n const minutes = date.getMinutes();\n const seconds = date.getSeconds();\n\n let hours12 = fullHours % 12;\n if (hours12 === 0) hours12 = 12;\n const period: TimePeriod = fullHours >= 12 ? \"PM\" : \"AM\";\n\n return formatStr\n .replace(/HH/g, padZero(fullHours))\n .replace(/H/g, `${fullHours}`)\n .replace(/hh/g, padZero(hours12))\n .replace(/h/g, `${hours12}`)\n .replace(/mm/g, padZero(minutes))\n .replace(/m/g, `${minutes}`)\n .replace(/ss/g, padZero(seconds))\n .replace(/s/g, `${seconds}`)\n .replace(/A/g, period)\n .replace(/a/g, period.toLowerCase());\n}\n\n/**\n * Trích xuất các thành phần giờ, phút, giây và buổi AM/PM từ đối tượng Date thành TimeObject.\n *\n * @param date - Đối tượng Date đầu vào.\n * @returns Đối tượng `TimeObject`.\n */\nexport function toTimeObject(date: Date | null): TimeObject {\n if (!date) {\n return { hours: 0, minutes: 0, seconds: 0, period: \"AM\" };\n }\n const fullHours = date.getHours();\n return {\n hours: fullHours,\n minutes: date.getMinutes(),\n seconds: date.getSeconds(),\n period: fullHours >= 12 ? \"PM\" : \"AM\",\n };\n}\n\n/**\n * Tạo một đối tượng Date mới (với ngày hôm nay) và gán chính xác giờ, phút, giây truyền vào.\n *\n * @param hours - Giờ (0 - 23).\n * @param minutes - Phút (0 - 59).\n * @param seconds - Giây (0 - 59, mặc định 0).\n * @returns Đối tượng Date mới.\n */\nexport function createDateWithTime(hours: number, minutes: number, seconds = 0): Date {\n const d = new Date();\n d.setHours(hours, minutes, seconds, 0);\n return d;\n}\n\n/**\n * Kiểm tra xem 2 thời điểm có cùng giờ, phút và giây hay không.\n *\n * @param d1 - Thời điểm thứ nhất.\n * @param d2 - Thời điểm thứ hai.\n * @param checkSeconds - Có kiểm tra phần giây hay không (mặc định `true`).\n * @returns `true` nếu 2 thời điểm trùng khớp thời gian.\n */\nexport function isSameTime(d1: Date | null, d2: Date | null, checkSeconds = true): boolean {\n if (!d1 || !d2) return false;\n if (checkSeconds) {\n return (\n d1.getHours() === d2.getHours() &&\n d1.getMinutes() === d2.getMinutes() &&\n d1.getSeconds() === d2.getSeconds()\n );\n }\n return d1.getHours() === d2.getHours() && d1.getMinutes() === d2.getMinutes();\n}\n\n/**\n * Kiểm tra xem thời điểm thứ nhất có xảy ra trước thời điểm thứ hai trong ngày hay không.\n *\n * @param time1 - Thời điểm cần so sánh.\n * @param time2 - Thời điểm mốc.\n * @returns `true` nếu `time1` xảy ra trước `time2`.\n */\nexport function isTimeBefore(time1: Date | null, time2: Date | null): boolean {\n if (!time1 || !time2) return false;\n const t1 = time1.getHours() * 3600 + time1.getMinutes() * 60 + time1.getSeconds();\n const t2 = time2.getHours() * 3600 + time2.getMinutes() * 60 + time2.getSeconds();\n return t1 < t2;\n}\n\n/**\n * Kiểm tra xem thời điểm thứ nhất có xảy ra sau thời điểm thứ hai trong ngày hay không.\n *\n * @param time1 - Thời điểm cần so sánh.\n * @param time2 - Thời điểm mốc.\n * @returns `true` nếu `time1` xảy ra sau `time2`.\n */\nexport function isTimeAfter(time1: Date | null, time2: Date | null): boolean {\n if (!time1 || !time2) return false;\n const t1 = time1.getHours() * 3600 + time1.getMinutes() * 60 + time1.getSeconds();\n const t2 = time2.getHours() * 3600 + time2.getMinutes() * 60 + time2.getSeconds();\n return t1 > t2;\n}\n\n/**\n * Kiểm tra xem một giá trị giờ, phút hoặc giây cụ thể có bị vô hiệu hóa (disable) hay không\n * dựa trên giới hạn min/max hoặc các hàm disable tùy chỉnh.\n *\n * @param type - Loại đơn vị thời gian ('hour', 'minute', 'second').\n * @param val - Giá trị cần kiểm tra.\n * @param selectedHour - Giờ đang được chọn hiện tại.\n * @param selectedMinute - Phút đang được chọn hiện tại.\n * @param minTime - Giới hạn thời gian tối thiểu.\n * @param maxTime - Giới hạn thời gian tối đa.\n * @param disabledHours - Hàm trả về danh sách giờ bị vô hiệu hóa.\n * @param disabledMinutes - Hàm trả về danh sách phút bị vô hiệu hóa.\n * @param disabledSeconds - Hàm trả về danh sách giây bị vô hiệu hóa.\n * @returns `true` nếu giá trị bị disable.\n */\nexport function checkIsDisabled(\n type: \"hour\" | \"minute\" | \"second\",\n val: number,\n selectedHour: number,\n selectedMinute: number,\n minTime?: Date | null,\n maxTime?: Date | null,\n disabledHours?: () => number[],\n disabledMinutes?: (h: number) => number[],\n disabledSeconds?: (h: number, m: number) => number[]\n): boolean {\n if (type === \"hour\") {\n if (disabledHours?.().includes(val)) return true;\n if (minTime && val < minTime.getHours()) return true;\n if (maxTime && val > maxTime.getHours()) return true;\n } else if (type === \"minute\") {\n if (disabledMinutes?.(selectedHour).includes(val)) return true;\n if (minTime) {\n if (selectedHour < minTime.getHours()) return true;\n if (selectedHour === minTime.getHours() && val < minTime.getMinutes()) {\n return true;\n }\n }\n if (maxTime) {\n if (selectedHour > maxTime.getHours()) return true;\n if (selectedHour === maxTime.getHours() && val > maxTime.getMinutes()) {\n return true;\n }\n }\n } else if (type === \"second\") {\n if (disabledSeconds?.(selectedHour, selectedMinute).includes(val)) {\n return true;\n }\n if (minTime) {\n if (selectedHour < minTime.getHours()) return true;\n if (selectedHour === minTime.getHours() && selectedMinute < minTime.getMinutes()) {\n return true;\n }\n if (\n selectedHour === minTime.getHours() &&\n selectedMinute === minTime.getMinutes() &&\n val < minTime.getSeconds()\n ) {\n return true;\n }\n }\n if (maxTime) {\n if (selectedHour > maxTime.getHours()) return true;\n if (selectedHour === maxTime.getHours() && selectedMinute > maxTime.getMinutes()) {\n return true;\n }\n if (\n selectedHour === maxTime.getHours() &&\n selectedMinute === maxTime.getMinutes() &&\n val > maxTime.getSeconds()\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n","import React, { useEffect, useRef } from \"react\";\nimport { TimeColumnProps } from \"./types\";\nimport { timeItemRadiusConfig, timePickerColorConfig, timePickerSizeConfig } from \"./constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\n/**\n * Component hiển thị một cột danh sách cuộn các giá trị thời gian (Giờ, Phút, Giây, hoặc AM/PM)\n * Hỗ trợ tự động cuộn đến phần tử đang chọn (auto-scroll) và phím điều hướng WAI-ARIA.\n */\nexport default function TimeColumn({\n items,\n selectedValue,\n onSelect,\n ariaLabel,\n size = \"md\",\n color = \"primary\",\n radius,\n className = \"\",\n itemClassName = \"\",\n selectedItemClassName = \"\",\n}: TimeColumnProps) {\n const containerRef = useRef<HTMLUListElement>(null);\n const selectedRef = useRef<HTMLLIElement>(null);\n\n const sizeStyles = getSafeConfig(size, timePickerSizeConfig, \"md\");\n const colorStyles = getSafeConfig(color, timePickerColorConfig, \"primary\");\n const itemRadiusClass = getSafeConfig(radius, timeItemRadiusConfig, \"md\");\n\n const firstEnabledIndex = items.findIndex((item) => !item.disabled);\n const hasSelection = items.some((item) => item.value === selectedValue);\n\n // Auto-scroll to selected element and synchronize focus when navigating\n useEffect(() => {\n if (selectedRef.current && containerRef.current) {\n const container = containerRef.current;\n const target = selectedRef.current;\n const topPos =\n target.offsetTop - container.offsetTop - (container.clientHeight - target.clientHeight) / 2;\n\n container.scrollTo({\n top: Math.max(0, topPos),\n behavior: \"smooth\",\n });\n\n // Nếu người dùng đang focus bên trong cột, di chuyển tiêu điểm tới phần tử được chọn mới\n if (container.contains(document.activeElement)) {\n target.focus();\n }\n }\n }, [selectedValue]);\n\n const focusAndSelect = (targetIndex: number) => {\n const targetItem = items[targetIndex];\n if (!targetItem || targetItem.disabled) return;\n onSelect(targetItem.value);\n const itemEl = containerRef.current?.children[targetIndex] as HTMLElement | undefined;\n itemEl?.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLLIElement>, currentIndex: number) => {\n const enabledItems = items.filter((item) => !item.disabled);\n if (!enabledItems.length) return;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n // Tìm phần tử khả dụng tiếp theo\n for (let i = currentIndex + 1; i < items.length; i++) {\n if (!items[i]!.disabled) {\n focusAndSelect(i);\n break;\n }\n }\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n // Tìm phần tử khả dụng phía trước\n for (let i = currentIndex - 1; i >= 0; i--) {\n if (!items[i]!.disabled) {\n focusAndSelect(i);\n break;\n }\n }\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault();\n const nextCol = containerRef.current?.nextElementSibling as HTMLElement | null;\n const target = nextCol?.querySelector<HTMLElement>(\n '[tabindex=\"0\"], [role=\"option\"]:not([aria-disabled=\"true\"])'\n );\n target?.focus();\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n const prevCol = containerRef.current?.previousElementSibling as HTMLElement | null;\n const target = prevCol?.querySelector<HTMLElement>(\n '[tabindex=\"0\"], [role=\"option\"]:not([aria-disabled=\"true\"])'\n );\n target?.focus();\n } else if (e.key === \"Home\") {\n e.preventDefault();\n const firstIdx = items.findIndex((item) => !item.disabled);\n if (firstIdx !== -1) {\n focusAndSelect(firstIdx);\n }\n } else if (e.key === \"End\") {\n e.preventDefault();\n for (let i = items.length - 1; i >= 0; i--) {\n if (!items[i]!.disabled) {\n focusAndSelect(i);\n break;\n }\n }\n } else if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const item = items[currentIndex];\n if (item && !item.disabled) {\n focusAndSelect(currentIndex);\n }\n }\n };\n\n return (\n <ul\n ref={containerRef}\n role=\"listbox\"\n aria-label={ariaLabel}\n tabIndex={-1}\n className={`relative flex flex-col overflow-y-auto select-none ${sizeStyles.columnWidth} ${sizeStyles.columnHeight} scrollbar-thin scrollbar-thumb-neutral-300 hover:scrollbar-thumb-neutral-400 py-1 focus:outline-none ${className}`}\n style={{\n scrollbarWidth: \"none\",\n msOverflowStyle: \"none\",\n }}\n >\n {items.map((item, index) => {\n const isSelected = selectedValue === item.value;\n const isDisabled = Boolean(item.disabled);\n const isTabbable = !isDisabled && (isSelected || (!hasSelection && index === firstEnabledIndex));\n\n return (\n <li\n key={`${item.value}`}\n ref={isSelected ? selectedRef : undefined}\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={isDisabled}\n aria-label={`${item.label} ${ariaLabel || \"\"}`.trim()}\n tabIndex={isTabbable ? 0 : -1}\n onKeyDown={(e) => handleKeyDown(e, index)}\n onClick={() => {\n if (!isDisabled) {\n focusAndSelect(index);\n }\n }}\n className={`flex items-center justify-center shrink-0 transition-colors duration-150 mx-1 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 ${itemRadiusClass} ${\n sizeStyles.itemHeight\n } ${sizeStyles.itemText} ${\n isDisabled\n ? \"opacity-30 cursor-not-allowed text-neutral-400\"\n : isSelected\n ? `${colorStyles.selected} cursor-default ${selectedItemClassName}`\n : `text-neutral-700 ${colorStyles.hoverBg} cursor-pointer`\n } ${itemClassName}`}\n >\n {item.label}\n </li>\n );\n })}\n </ul>\n );\n}\n","import { useState, useId, useMemo, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useDismiss,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingFocusManager,\n} from \"@floating-ui/react\";\nimport { TimeRange, TimeRangePickerProps } from \"./types\";\nimport TimeView from \"../timepicker/TimeView\";\nimport ChevronDownIcon from \"../icons/ChevronDownIcon\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { formatTime, getDefaultFormat, parseTimeToDate } from \"../timepicker/utils\";\nimport {\n timeRangePickerRadiusConfig,\n timeRangePickerSizeConfig,\n timeRangePickerVariantStyles,\n timeRangeViewRadiusConfig,\n labelColorConfig,\n} from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\nimport { getSafeConfig } from \"@/utils/function\";\n\n/**\n * Component TimeRangePicker - Ô chọn khoảng thời gian (Start Time - End Time) chuyên nghiệp theo Design System.\n * Hỗ trợ giao diện 2 bảng chọn song song, linh hoạt định dạng, nhãn tuỳ biến, và WAI-ARIA combobox.\n */\nexport default function TimeRangePicker({\n ref,\n value: controlledValue,\n defaultValue,\n onChange,\n format: customFormat,\n displayFormat: customDisplayFormat,\n separator = \" - \",\n startLabel = \"Thời gian bắt đầu\",\n endLabel = \"Thời gian kết thúc\",\n use12Hours = false,\n showSeconds = true,\n hourStep = 1,\n minuteStep = 1,\n secondStep = 1,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius,\n label,\n labelPlacement = \"top\",\n placeholder,\n placeholders,\n helperText,\n errorMessage,\n name,\n id,\n autoComplete,\n disabled = false,\n readOnly = false,\n config,\n onClear,\n placement = \"bottom-start\",\n className = \"\",\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n popoverClassName = \"\",\n}: TimeRangePickerProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = true,\n isFullWidth = false,\n closeOnSelect = false,\n } = config ?? {};\n\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n const popoverId = `${inputId}-popover`;\n\n const defaultFmt = getDefaultFormat(use12Hours, showSeconds);\n const resolvedFormat = customFormat || defaultFmt;\n const resolvedDisplayFormat = customDisplayFormat || resolvedFormat;\n\n const isControlled = controlledValue !== undefined;\n const [internalRange, setInternalRange] = useState<TimeRange>(() => {\n const raw = defaultValue;\n if (raw && Array.isArray(raw)) {\n return [parseTimeToDate(raw[0]), parseTimeToDate(raw[1])];\n }\n return [null, null];\n });\n\n const selectedRange: TimeRange =\n isControlled && controlledValue && Array.isArray(controlledValue)\n ? [parseTimeToDate(controlledValue[0]), parseTimeToDate(controlledValue[1])]\n : internalRange;\n\n const startText = selectedRange[0]\n ? formatTime(selectedRange[0], resolvedDisplayFormat)\n : \"\";\n const endText = selectedRange[1]\n ? formatTime(selectedRange[1], resolvedDisplayFormat)\n : \"\";\n\n const formattedValue = useMemo(() => {\n if (startText && endText) {\n return `${startText}${separator}${endText}`;\n }\n if (startText) {\n return `${startText}${separator}`;\n }\n return \"\";\n }, [startText, endText, separator]);\n\n const [isOpen, setIsOpen] = useState(false);\n\n // Floating UI setup\n const {\n refs: { setReference, setFloating },\n floatingStyles,\n context,\n } = useFloating({\n placement,\n open: isOpen && !disabled && !readOnly && !isLoading,\n onOpenChange: setIsOpen,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware: [offsetMiddleware(6), flipMiddleware(), shiftMiddleware({ padding: 8 })],\n });\n\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n });\n const role = useRole(context, { role: \"dialog\" });\n const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: 150,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n // Style configs\n const sizeStyles = getSafeConfig(size, timeRangePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, timeRangePickerRadiusConfig, \"lg\");\n const menuRadiusClass = getSafeConfig(radius, timeRangeViewRadiusConfig, \"lg\");\n const variantClass =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, timeRangePickerVariantStyles, \"outline\"), \"primary\");\n\n const hasValue = Boolean(selectedRange[0] || selectedRange[1]);\n\n // Handlers\n const handleStartTimeSelect = (date: Date) => {\n const newRange: TimeRange = [date, selectedRange[1]];\n if (!isControlled) {\n setInternalRange(newRange);\n }\n const fStart = formatTime(date, resolvedFormat);\n const fEnd = selectedRange[1] ? formatTime(selectedRange[1], resolvedFormat) : \"\";\n onChange?.([fStart, fEnd]);\n };\n\n const handleEndTimeSelect = (date: Date) => {\n const newRange: TimeRange = [selectedRange[0], date];\n if (!isControlled) {\n setInternalRange(newRange);\n }\n const fStart = selectedRange[0] ? formatTime(selectedRange[0], resolvedFormat) : \"\";\n const fEnd = formatTime(date, resolvedFormat);\n onChange?.([fStart, fEnd]);\n\n if (closeOnSelect) {\n setIsOpen(false);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (e.key === \"ArrowDown\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!isOpen) setIsOpen(true);\n } else if (e.key === \"Escape\" && isOpen) {\n e.preventDefault();\n setIsOpen(false);\n }\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (!isControlled) {\n setInternalRange([null, null]);\n }\n onChange?.(null);\n onClear?.();\n };\n\n const defaultPlaceholder =\n placeholder ||\n (placeholders\n ? `${placeholders[0]}${separator}${placeholders[1]}`\n : `${resolvedDisplayFormat}${separator}${resolvedDisplayFormat}`);\n\n const isFloating = labelPlacement === \"floating\";\n const isHorizontal = labelPlacement === \"left\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-pointer font-bold bg-neutral-white transition-colors duration-150 ${sizeStyles.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${sizeStyles.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${sizeStyles.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const fieldWrapperClasses = [\n \"group/timerangepicker relative flex\",\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\",\n isFullWidth ? \"w-full\" : \"inline-flex\",\n wrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2 select-none cursor-pointer\",\n sizeStyles.inputHeight,\n radiusClass,\n variantClass,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : \"w-auto\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const inputClasses = [\n \"w-full h-full bg-transparent outline-none border-none text-neutral-800 placeholder-neutral-400 cursor-pointer select-none caret-transparent focus:outline-none\",\n sizeStyles.inputText,\n sizeStyles.inputPadding,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={fieldWrapperClasses}>\n {/* Label (Top / Left) */}\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n {/* Input container */}\n <div ref={setReference} {...getReferenceProps()} className={containerClasses}>\n {isFloating && renderLabel()}\n\n <input\n ref={ref}\n id={inputId}\n name={name}\n type=\"text\"\n value={formattedValue}\n onClick={() => !disabled && !readOnly && !isLoading && setIsOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n readOnly={true}\n autoComplete={autoComplete}\n placeholder={defaultPlaceholder}\n disabled={disabled || isLoading}\n role=\"combobox\"\n aria-expanded={isOpen && !isLoading}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-required={isRequired}\n aria-invalid={hasError}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={helperText || errorMessage ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n className={inputClasses}\n />\n\n {/* Right actions: Spinner, Clear, ChevronDown Icon */}\n <div className=\"flex items-center space-x-1.5 pr-2.5 shrink-0\">\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center shrink-0\">{renderIconWrapper(<Spinner />)}</div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa khoảng thời gian\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${sizeStyles.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n <div\n aria-hidden=\"true\"\n className={`inline-flex items-center justify-center text-neutral-400 hover:text-neutral-600 transition-transform duration-200 ease-in-out cursor-pointer ${\n isOpen ? \"rotate-180\" : \"rotate-0\"\n }`}\n >\n {renderIconWrapper(<ChevronDownIcon className=\"size-full\" />)}\n </div>\n </div>\n </div>\n\n {/* Floating UI Portal */}\n {isMounted && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false} returnFocus={true}>\n <div\n ref={setFloating}\n id={popoverId}\n style={{\n ...floatingStyles,\n ...transitionStyles,\n zIndex: DEFAULT_Z_INDEX.PICKER,\n }}\n {...getFloatingProps()}\n className={`flex flex-row bg-neutral-white border-2 border-neutral-200 shadow-xl divide-x divide-neutral-200 overflow-hidden select-none ${menuRadiusClass} ${popoverClassName}`}\n >\n {/* Start Time panel */}\n <div className=\"flex flex-col\">\n <div className=\"px-3 py-1.5 bg-neutral-50 text-xs font-semibold text-neutral-600 border-b border-neutral-200 text-center\">\n {startLabel}\n </div>\n <TimeView\n value={selectedRange[0]}\n onChange={handleStartTimeSelect}\n ariaLabel={startLabel}\n use12Hours={use12Hours}\n showSeconds={showSeconds}\n hourStep={hourStep}\n minuteStep={minuteStep}\n secondStep={secondStep}\n minTime={minTime}\n maxTime={selectedRange[1] || maxTime}\n disabledHours={disabledHours}\n disabledMinutes={disabledMinutes}\n disabledSeconds={disabledSeconds}\n size={size}\n color={color}\n radius={radius}\n className=\"border-none shadow-none\"\n />\n </div>\n\n {/* End Time panel */}\n <div className=\"flex flex-col\">\n <div className=\"px-3 py-1.5 bg-neutral-50 text-xs font-semibold text-neutral-600 border-b border-neutral-200 text-center\">\n {endLabel}\n </div>\n <TimeView\n value={selectedRange[1]}\n onChange={handleEndTimeSelect}\n ariaLabel={endLabel}\n use12Hours={use12Hours}\n showSeconds={showSeconds}\n hourStep={hourStep}\n minuteStep={minuteStep}\n secondStep={secondStep}\n minTime={selectedRange[0] || minTime}\n maxTime={maxTime}\n disabledHours={disabledHours}\n disabledMinutes={disabledMinutes}\n disabledSeconds={disabledSeconds}\n size={size}\n color={color}\n radius={radius}\n className=\"border-none shadow-none\"\n />\n </div>\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n\n {/* Helper / Error text with animation */}\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={sizeStyles.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import {\n TimeRangePickerColor,\n TimeRangePickerRadius,\n TimeRangePickerSize,\n TimeRangePickerVariant,\n} from \"./types\";\nimport {\n timePickerSizeConfig,\n timePickerRadiusConfig,\n timeViewRadiusConfig,\n timePickerColorConfig,\n timePickerVariantStyles,\n} from \"../timepicker/constants\";\n\n/**\n * Re-export & alias các cấu hình kích thước từ timepicker\n */\nexport const timeRangePickerSizeConfig = timePickerSizeConfig;\n\n/**\n * Re-export & alias cấu hình bo góc từ timepicker\n */\nexport const timeRangePickerRadiusConfig = timePickerRadiusConfig;\n\n/**\n * Re-export & alias cấu hình bo góc cho khung bảng TimeView\n */\nexport const timeRangeViewRadiusConfig = timeViewRadiusConfig;\n\n/**\n * Re-export & alias cấu hình màu sắc từ timepicker\n */\nexport const timeRangePickerColorConfig = timePickerColorConfig;\n\n/**\n * Re-export & alias cấu hình biến thể từ timepicker\n */\nexport const timeRangePickerVariantStyles = timePickerVariantStyles;\n\n/**\n * Cấu hình màu chữ của nhãn label theo màu chủ đề\n */\nexport const labelColorConfig: Record<TimeRangePickerColor, string> = {\n primary: \"text-primary-500 group-focus-within/timerangepicker:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/timerangepicker:text-secondary-600\",\n error: \"text-error-500 group-focus-within/timerangepicker:text-error-600\",\n success: \"text-success-500 group-focus-within/timerangepicker:text-success-600\",\n warning: \"text-warning-500 group-focus-within/timerangepicker:text-warning-600\",\n info: \"text-info-500 group-focus-within/timerangepicker:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/timerangepicker:text-neutral-600\",\n};\n","/**\n * Kiểm tra xem một thời điểm `time` có nằm trong khoảng giữa `start` và `end` trong ngày hay không.\n *\n * @param time - Thời điểm cần kiểm tra.\n * @param start - Thời điểm bắt đầu khoảng.\n * @param end - Thời điểm kết thúc khoảng.\n * @returns `true` nếu `time` nằm trong khoảng [`start`, `end`].\n */\nexport function isTimeInRange(\n time: Date | null,\n start: Date | null,\n end: Date | null\n): boolean {\n if (!time || !start || !end) return false;\n const t = time.getHours() * 3600 + time.getMinutes() * 60 + time.getSeconds();\n const s = start.getHours() * 3600 + start.getMinutes() * 60 + start.getSeconds();\n const e = end.getHours() * 3600 + end.getMinutes() * 60 + end.getSeconds();\n return t >= s && t <= e;\n}\n","import { useState, useId, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useDismiss,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingFocusManager,\n} from \"@floating-ui/react\";\nimport { DateTimePickerProps } from \"./types\";\nimport Calendar from \"../datepicker/Calendar\";\nimport TimeView from \"../timepicker/TimeView\";\nimport ChevronDownIcon from \"../icons/ChevronDownIcon\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { combineDateTime, formatDateTime, getDefaultDateTimeFormat, toDateTime } from \"./utils\";\nimport {\n dateTimePickerRadiusConfig,\n dateTimePickerSizeConfig,\n dateTimePickerVariantStyles,\n dateTimeViewRadiusConfig,\n labelColorConfig,\n} from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { CalendarView } from \"../datepicker/types\";\n\n/**\n * Component DateTimePicker - Ô chọn Ngày & Giờ tích hợp theo Design System.\n * Hỗ trợ giao diện linh hoạt (side-by-side hoặc stacked), WAI-ARIA combobox, và quản lý tiêu điểm thông minh.\n */\nexport default function DateTimePicker({\n ref,\n value: controlledValue,\n defaultValue,\n onChange,\n format: customFormat,\n displayFormat: customDisplayFormat,\n layout = \"side-by-side\",\n locale = \"vi\",\n defaultView = \"days\",\n firstDayOfWeek = 1,\n minDate,\n maxDate,\n isDateDisabled,\n viewTabs,\n use12Hours = false,\n showSeconds = true,\n hourStep = 1,\n minuteStep = 1,\n secondStep = 1,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius,\n label,\n labelPlacement = \"top\",\n placeholder,\n helperText,\n errorMessage,\n name,\n id,\n autoComplete,\n disabled = false,\n readOnly = false,\n config,\n onClear,\n placement = \"bottom-start\",\n className = \"\",\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n popoverClassName = \"\",\n}: DateTimePickerProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = true,\n isFullWidth = false,\n closeOnSelect = false,\n showWeekNumbers = false,\n showViewTabs = false,\n } = config ?? {};\n\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n const popoverId = `${inputId}-popover`;\n\n const defaultFmt = getDefaultDateTimeFormat(use12Hours, showSeconds);\n const resolvedFormat = customFormat || defaultFmt;\n const baseDisplayFormat = customDisplayFormat || resolvedFormat;\n\n const isControlled = controlledValue !== undefined;\n const [internalDate, setInternalDate] = useState<Date | null>(() => toDateTime(defaultValue, resolvedFormat));\n const selectedDate = isControlled ? toDateTime(controlledValue, resolvedFormat) : internalDate;\n const formattedValue = selectedDate ? formatDateTime(selectedDate, baseDisplayFormat, locale) : \"\";\n\n const [activeView, setActiveView] = useState<CalendarView>(defaultView);\n const [isOpen, setIsOpen] = useState(false);\n\n // Floating UI setup\n const {\n refs: { setReference, setFloating },\n floatingStyles,\n context,\n } = useFloating({\n placement,\n open: isOpen && !disabled && !readOnly && !isLoading,\n onOpenChange: setIsOpen,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware: [offsetMiddleware(6), flipMiddleware(), shiftMiddleware({ padding: 8 })],\n });\n\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n });\n const role = useRole(context, { role: \"dialog\" });\n const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: 150,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n // Style configs\n const sizeStyles = getSafeConfig(size, dateTimePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, dateTimePickerRadiusConfig, \"lg\");\n const menuRadiusClass = getSafeConfig(radius, dateTimeViewRadiusConfig, \"lg\");\n const variantClass =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, dateTimePickerVariantStyles, \"outline\"), \"primary\");\n\n const hasValue = Boolean(selectedDate);\n\n // Handlers\n const handleCalendarChange = (newDate: Date) => {\n // Merge new date (year, month, day) with existing time (or current time)\n const combined = combineDateTime(newDate, selectedDate || new Date());\n if (!isControlled) {\n setInternalDate(combined);\n }\n const formattedOutput = combined ? formatDateTime(combined, resolvedFormat, locale) : \"\";\n onChange?.(formattedOutput);\n\n if (closeOnSelect) {\n setIsOpen(false);\n }\n };\n\n const handleTimeChange = (newTime: Date | null) => {\n if (!newTime) return;\n // Merge existing date (or today) with new time\n const combined = combineDateTime(selectedDate || new Date(), newTime);\n if (!isControlled) {\n setInternalDate(combined);\n }\n const formattedOutput = combined ? formatDateTime(combined, resolvedFormat, locale) : \"\";\n onChange?.(formattedOutput);\n\n if (closeOnSelect) {\n setIsOpen(false);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (e.key === \"ArrowDown\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!isOpen) setIsOpen(true);\n } else if (e.key === \"Escape\" && isOpen) {\n e.preventDefault();\n setIsOpen(false);\n }\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (!isControlled) {\n setInternalDate(null);\n }\n onChange?.(null);\n onClear?.();\n };\n\n const defaultPlaceholder = placeholder || baseDisplayFormat;\n const isFloating = labelPlacement === \"floating\";\n const isHorizontal = labelPlacement === \"left\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-pointer font-bold bg-neutral-white transition-colors duration-150 ${sizeStyles.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${sizeStyles.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${sizeStyles.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const fieldWrapperClasses = [\n \"group/datetimepicker relative flex\",\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\",\n isFullWidth ? \"w-full\" : \"inline-flex\",\n wrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2 select-none cursor-pointer\",\n sizeStyles.inputHeight,\n radiusClass,\n variantClass,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : \"w-auto\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const inputClasses = [\n \"w-full h-full bg-transparent outline-none border-none text-neutral-800 placeholder-neutral-400 cursor-pointer select-none caret-transparent focus:outline-none\",\n sizeStyles.inputText,\n sizeStyles.inputPadding,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={fieldWrapperClasses}>\n {/* Label (Top / Left) */}\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n {/* Input container */}\n <div ref={setReference} {...getReferenceProps()} className={containerClasses}>\n {isFloating && renderLabel()}\n\n <input\n ref={ref}\n id={inputId}\n name={name}\n type=\"text\"\n value={formattedValue}\n onClick={() => !disabled && !readOnly && !isLoading && setIsOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n readOnly={true}\n autoComplete={autoComplete}\n placeholder={defaultPlaceholder}\n disabled={disabled || isLoading}\n role=\"combobox\"\n aria-expanded={isOpen && !isLoading}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-required={isRequired}\n aria-invalid={hasError}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={helperText || errorMessage ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n className={inputClasses}\n />\n\n {/* Right actions: Spinner, Clear, ChevronDown Icon */}\n <div className=\"flex items-center space-x-1.5 pr-2.5 shrink-0\">\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center shrink-0\">{renderIconWrapper(<Spinner />)}</div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa ngày giờ\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${sizeStyles.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n <div\n aria-hidden=\"true\"\n className={`inline-flex items-center justify-center text-neutral-400 hover:text-neutral-600 transition-transform duration-200 ease-in-out cursor-pointer ${\n isOpen ? \"rotate-180\" : \"rotate-0\"\n }`}\n >\n {renderIconWrapper(<ChevronDownIcon className=\"size-full\" />)}\n </div>\n </div>\n </div>\n\n {/* Floating UI Portal */}\n {isMounted && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false} returnFocus={true}>\n <div\n ref={setFloating}\n id={popoverId}\n style={{\n ...floatingStyles,\n ...transitionStyles,\n zIndex: DEFAULT_Z_INDEX.PICKER,\n }}\n {...getFloatingProps()}\n className={`flex bg-neutral-white border-2 border-neutral-200 shadow-xl overflow-hidden select-none ${menuRadiusClass} ${\n layout === \"stacked\" ? \"flex-col divide-y-2 divide-neutral-200\" : \"flex-row divide-x-2 divide-neutral-200\"\n } ${popoverClassName}`}\n >\n {/* Calendar Panel */}\n <div className=\"flex flex-col\">\n <Calendar\n value={selectedDate}\n onChange={handleCalendarChange}\n view={activeView}\n onViewChange={setActiveView}\n minDate={minDate}\n maxDate={maxDate}\n isDateDisabled={isDateDisabled}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n showWeekNumbers={showWeekNumbers}\n size={size}\n color={color}\n radius={radius}\n showViewTabs={showViewTabs}\n viewTabs={viewTabs}\n className=\"border-none shadow-none rounded-none\"\n />\n </div>\n\n {/* Time Panel */}\n <div className=\"flex flex-col justify-center items-center p-1 bg-neutral-50/50\">\n <TimeView\n value={selectedDate}\n onChange={handleTimeChange}\n ariaLabel={typeof label === \"string\" ? `${label} time` : \"Time selector\"}\n use12Hours={use12Hours}\n showSeconds={showSeconds}\n hourStep={hourStep}\n minuteStep={minuteStep}\n secondStep={secondStep}\n minTime={minTime}\n maxTime={maxTime}\n disabledHours={disabledHours}\n disabledMinutes={disabledMinutes}\n disabledSeconds={disabledSeconds}\n size={size}\n color={color}\n radius={radius}\n className=\"border-none shadow-none bg-transparent\"\n />\n </div>\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n\n {/* Helper / Error text with animation */}\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={sizeStyles.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import { LocaleConfig } from \"../datepicker/types\";\nimport { formatDate } from \"../datepicker/utils\";\n\n/**\n * Lấy định dạng ngày giờ mặc định theo cờ use12Hours và showSeconds\n */\nexport function getDefaultDateTimeFormat(use12Hours: boolean = false, showSeconds: boolean = true): string {\n if (use12Hours) {\n return showSeconds ? \"DD/MM/YYYY hh:mm:ss A\" : \"DD/MM/YYYY hh:mm A\";\n }\n return showSeconds ? \"DD/MM/YYYY HH:mm:ss\" : \"DD/MM/YYYY HH:mm\";\n}\n\n/**\n * Gộp date (năm, tháng, ngày) và time (giờ, phút, giây) thành 1 đối tượng Date\n */\nexport function combineDateTime(date: Date | null, time: Date | null): Date | null {\n if (!date && !time) return null;\n const baseDate = date ? new Date(date) : new Date();\n if (time) {\n baseDate.setHours(time.getHours());\n baseDate.setMinutes(time.getMinutes());\n baseDate.setSeconds(time.getSeconds());\n baseDate.setMilliseconds(time.getMilliseconds());\n }\n return baseDate;\n}\n\n/**\n * Chuyển đổi giá trị bất kỳ (Date, string, number, Temporal object) thành Date\n */\nexport function toDateTime(val: unknown, formatStr: string = \"DD/MM/YYYY HH:mm:ss\"): Date | null {\n if (!val) return null;\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? null : new Date(val.getTime());\n }\n if (typeof val === \"string\" || typeof val === \"number\") {\n if (typeof val === \"string\") {\n const parsedWithFormat = parseDateTime(val, formatStr);\n if (parsedWithFormat) return parsedWithFormat;\n }\n const parsed = new Date(val);\n return isNaN(parsed.getTime()) ? null : parsed;\n }\n const anyObj = val as { toDate?: () => Date; epochMilliseconds?: number };\n if (typeof anyObj.toDate === \"function\") {\n return anyObj.toDate();\n }\n if (typeof anyObj.epochMilliseconds === \"number\") {\n return new Date(anyObj.epochMilliseconds);\n }\n return null;\n}\n\n/**\n * Format Date thành chuỗi theo formatStr và locale\n */\nexport function formatDateTime(\n date: Date | null | undefined,\n formatStr: string = \"DD/MM/YYYY HH:mm:ss\",\n locale?: \"vi\" | \"en\" | LocaleConfig\n): string {\n if (!date || isNaN(date.getTime())) return \"\";\n return formatDate(date, formatStr, locale);\n}\n\n/**\n * Parse chuỗi theo định dạng formatStr (hỗ trợ YYYY, YY, MM, M, DD, D, HH, H, hh, h, mm, m, ss, s, A, a)\n */\nexport function parseDateTime(str: string | null | undefined, formatStr: string = \"DD/MM/YYYY HH:mm:ss\"): Date | null {\n if (!str || typeof str !== \"string\") return null;\n const trimmed = str.trim();\n if (!trimmed) return null;\n\n let year = new Date().getFullYear();\n let month = 1;\n let day = 1;\n let hours = 0;\n let minutes = 0;\n let seconds = 0;\n let is12Hour = false;\n let isPM = false;\n\n const patternParts = formatStr.match(/YYYY|YY|MM|M|DD|D|HH|H|hh|h|mm|m|ss|s|A|a/g);\n if (!patternParts) {\n const d = new Date(trimmed);\n return isNaN(d.getTime()) ? null : d;\n }\n\n // Tạo regex từ formatStr\n let regexStr = \"^\" + formatStr.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n for (const part of patternParts) {\n if (part === \"YYYY\") regexStr = regexStr.replace(\"YYYY\", \"(\\\\d{4})\");\n else if (part === \"YY\") regexStr = regexStr.replace(\"YY\", \"(\\\\d{2})\");\n else if (part === \"MM\" || part === \"M\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"DD\" || part === \"D\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"HH\" || part === \"H\" || part === \"hh\" || part === \"h\")\n regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"mm\" || part === \"m\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"ss\" || part === \"s\") regexStr = regexStr.replace(part, \"(\\\\d{1,2})\");\n else if (part === \"A\" || part === \"a\") regexStr = regexStr.replace(part, \"(AM|PM|am|pm)\");\n }\n regexStr += \"$\";\n\n const match = new RegExp(regexStr, \"i\").exec(trimmed);\n if (!match) {\n const fallback = new Date(trimmed);\n return isNaN(fallback.getTime()) ? null : fallback;\n }\n\n patternParts.forEach((part, index) => {\n const rawVal = match[index + 1];\n if (!rawVal) return;\n\n if (part === \"A\" || part === \"a\") {\n is12Hour = true;\n if (rawVal.toUpperCase() === \"PM\") {\n isPM = true;\n }\n return;\n }\n\n const val = parseInt(rawVal, 10);\n if (isNaN(val)) return;\n\n if (part === \"YYYY\") year = val;\n else if (part === \"YY\") year = 2000 + val;\n else if (part === \"MM\" || part === \"M\") month = val;\n else if (part === \"DD\" || part === \"D\") day = val;\n else if (part === \"HH\" || part === \"H\") hours = val;\n else if (part === \"hh\" || part === \"h\") {\n is12Hour = true;\n hours = val;\n } else if (part === \"mm\" || part === \"m\") minutes = val;\n else if (part === \"ss\" || part === \"s\") seconds = val;\n });\n\n if (is12Hour) {\n if (isPM) {\n if (hours < 12) hours += 12;\n } else {\n if (hours === 12) hours = 0;\n }\n }\n\n const result = new Date(year, month - 1, day, hours, minutes, seconds);\n return isNaN(result.getTime()) ? null : result;\n}\n","import {\n DateTimePickerColor,\n DateTimePickerRadius,\n DateTimePickerSize,\n DateTimePickerVariant,\n} from \"./types\";\n\n/**\n * Cấu hình bo góc cho ô nhập liệu DateTimePicker\n */\nexport const dateTimePickerRadiusConfig: Record<DateTimePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\n/**\n * Cấu hình bo góc cho khung popover bảng chọn DateTimePicker\n */\nexport const dateTimeViewRadiusConfig: Record<DateTimePickerRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-2xl\",\n};\n\n/**\n * Cấu hình kích cỡ, khoảng đệm, typography và kích thước icon cho DateTimePicker\n */\nexport const dateTimePickerSizeConfig: Record<\n DateTimePickerSize,\n {\n inputHeight: string;\n inputText: string;\n inputPadding: string;\n icon: string;\n iconSize: number;\n calendarPadding: string;\n cellSize: string;\n cellText: string;\n headerText: string;\n headerButtonSize: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n inputHeight: \"h-6\",\n inputText: \"text-[11px]\",\n inputPadding: \"px-2\",\n icon: \"size-3\",\n iconSize: 12,\n calendarPadding: \"p-2\",\n cellSize: \"w-7 h-7\",\n cellText: \"text-[11px]\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-6 w-6\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n inputHeight: \"h-8\",\n inputText: \"text-xs\",\n inputPadding: \"px-2.5\",\n icon: \"size-3.5\",\n iconSize: 14,\n calendarPadding: \"p-2.5\",\n cellSize: \"w-8 h-8\",\n cellText: \"text-xs\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-7 w-7\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n inputHeight: \"h-10\",\n inputText: \"text-sm\",\n inputPadding: \"px-3\",\n icon: \"size-[18px]\",\n iconSize: 16,\n calendarPadding: \"p-3\",\n cellSize: \"w-9 h-9\",\n cellText: \"text-sm\",\n headerText: \"text-sm font-semibold\",\n headerButtonSize: \"h-8 w-8\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n inputHeight: \"h-12\",\n inputText: \"text-base\",\n inputPadding: \"px-3.5\",\n icon: \"size-5\",\n iconSize: 18,\n calendarPadding: \"p-4\",\n cellSize: \"w-10 h-10\",\n cellText: \"text-base\",\n headerText: \"text-base font-semibold\",\n headerButtonSize: \"h-9 w-9\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n inputHeight: \"h-14\",\n inputText: \"text-lg\",\n inputPadding: \"px-4\",\n icon: \"size-6\",\n iconSize: 20,\n calendarPadding: \"p-4\",\n cellSize: \"w-12 h-12\",\n cellText: \"text-lg\",\n headerText: \"text-lg font-semibold\",\n headerButtonSize: \"h-10 w-10\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-sm\",\n helper: \"text-sm mt-1.5\",\n },\n};\n\n/**\n * Cấu hình màu sắc chủ đề theo Design System\n */\nexport const dateTimePickerColorConfig: Record<\n DateTimePickerColor,\n {\n selected: string;\n hoverBg: string;\n todayRing: string;\n badgeBg: string;\n }\n> = {\n primary: {\n selected: \"bg-primary-500 text-neutral-white hover:bg-primary-600\",\n hoverBg: \"hover:bg-primary-50 text-neutral-800\",\n todayRing: \"ring-primary-500 text-primary-600\",\n badgeBg: \"bg-primary-100 text-primary-700\",\n },\n secondary: {\n selected: \"bg-secondary-500 text-neutral-white hover:bg-secondary-600\",\n hoverBg: \"hover:bg-secondary-50 text-neutral-800\",\n todayRing: \"ring-secondary-500 text-secondary-600\",\n badgeBg: \"bg-secondary-100 text-secondary-700\",\n },\n error: {\n selected: \"bg-error-500 text-neutral-white hover:bg-error-600\",\n hoverBg: \"hover:bg-error-50 text-neutral-800\",\n todayRing: \"ring-error-500 text-error-600\",\n badgeBg: \"bg-error-100 text-error-700\",\n },\n success: {\n selected: \"bg-success-500 text-neutral-white hover:bg-success-600\",\n hoverBg: \"hover:bg-success-50 text-neutral-800\",\n todayRing: \"ring-success-500 text-success-600\",\n badgeBg: \"bg-success-100 text-success-700\",\n },\n warning: {\n selected: \"bg-warning-500 text-neutral-950 hover:bg-warning-600\",\n hoverBg: \"hover:bg-warning-50 text-neutral-800\",\n todayRing: \"ring-warning-500 text-warning-700\",\n badgeBg: \"bg-warning-100 text-warning-800\",\n },\n info: {\n selected: \"bg-info-500 text-neutral-white hover:bg-info-600\",\n hoverBg: \"hover:bg-info-50 text-neutral-800\",\n todayRing: \"ring-info-500 text-info-600\",\n badgeBg: \"bg-info-100 text-info-700\",\n },\n neutral: {\n selected: \"bg-neutral-700 text-neutral-white hover:bg-neutral-800\",\n hoverBg: \"hover:bg-neutral-100 text-neutral-800\",\n todayRing: \"ring-neutral-700 text-neutral-800\",\n badgeBg: \"bg-neutral-200 text-neutral-800\",\n },\n};\n\n/**\n * Cấu hình màu chữ của nhãn label theo màu chủ đề\n */\nexport const labelColorConfig: Record<DateTimePickerColor, string> = {\n primary: \"text-primary-500 group-focus-within/datetimepicker:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/datetimepicker:text-secondary-600\",\n error: \"text-error-500 group-focus-within/datetimepicker:text-error-600\",\n success: \"text-success-500 group-focus-within/datetimepicker:text-success-600\",\n warning: \"text-warning-500 group-focus-within/datetimepicker:text-warning-600\",\n info: \"text-info-500 group-focus-within/datetimepicker:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/datetimepicker:text-neutral-600\",\n};\n\n/**\n * Cấu hình style viền và nền ô input cho 3 variant (outline, filled, ghost)\n */\nexport const dateTimePickerVariantStyles: Record<\n Exclude<DateTimePickerVariant, \"other\">,\n Record<DateTimePickerColor, string>\n> = {\n outline: {\n primary:\n \"bg-neutral-white border-2 border-neutral-300 hover:border-primary-400 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-neutral-white border-2 border-neutral-300 hover:border-secondary-400 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-neutral-white border-2 border-error-500 hover:border-error-600 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-neutral-white border-2 border-neutral-300 hover:border-success-400 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-neutral-white border-2 border-neutral-300 hover:border-warning-400 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-neutral-white border-2 border-neutral-300 hover:border-info-400 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-white border-2 border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n filled: {\n primary:\n \"bg-primary-50/60 border-2 border-transparent hover:bg-primary-100/60 focus-within:bg-primary-100/60 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-secondary-50/60 border-2 border-transparent hover:bg-secondary-100/60 focus-within:bg-secondary-100/60 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-error-50/60 border-2 border-transparent hover:border-error-600 hover:bg-error-100/60 focus-within:bg-error-100/60 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-success-50/60 border-2 border-transparent hover:bg-success-100/60 focus-within:bg-success-100/60 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-warning-50/60 border-2 border-transparent hover:bg-warning-100/60 focus-within:bg-warning-100/60 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-info-50/60 border-2 border-transparent hover:bg-info-100/60 focus-within:bg-info-100/60 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-neutral-50/60 border-2 border-transparent hover:bg-neutral-200/60 focus-within:bg-neutral-200/60 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n ghost: {\n primary:\n \"bg-transparent border-2 border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-200/20 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-transparent border-2 border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-200/20 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n error:\n \"bg-transparent border-2 border-transparent hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-transparent border-2 border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-200/20 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-transparent border-2 border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-200/20 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-transparent border-2 border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-200/20 focus-within:ring-2 focus-within:ring-info-500/20\",\n neutral:\n \"bg-transparent border-2 border-transparent hover:bg-neutral-50/50 focus-within:bg-neutral-50/50 focus-within:border-neutral-200/20 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n },\n};\n","import { useState, useId, useMemo, KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useDismiss,\n useRole,\n useInteractions,\n useTransitionStyles,\n FloatingPortal,\n FloatingFocusManager,\n} from \"@floating-ui/react\";\nimport { DateTimeRange, DateTimeRangePickerProps } from \"./types\";\nimport Calendar from \"../datepicker/Calendar\";\nimport TimeView from \"../timepicker/TimeView\";\nimport ChevronDownIcon from \"../icons/ChevronDownIcon\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { combineDateTime, formatDateTime, getDefaultDateTimeFormat, toDateTime } from \"./utils\";\nimport {\n dateTimeRangePickerRadiusConfig,\n dateTimeRangePickerSizeConfig,\n dateTimeRangePickerVariantStyles,\n dateTimeRangeViewRadiusConfig,\n dateTimeRangePickerButtonColorConfig,\n labelColorConfig,\n} from \"./constants\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\nimport { getSafeConfig } from \"@/utils/function\";\nimport { CalendarView } from \"../datepicker/types\";\n\n/**\n * Component DateTimeRangePicker - Ô chọn khoảng Ngày & Giờ (Start - End) chuyên nghiệp theo Design System.\n * Hỗ trợ giao diện chuyển bước (Stepped View) giúp popover nhỏ gọn, không bị tràn màn hình.\n */\nexport default function DateTimeRangePicker({\n ref,\n value: controlledValue,\n defaultValue,\n onChange,\n format: customFormat,\n displayFormat: customDisplayFormat,\n separator = \" - \",\n startLabel = \"Thời gian bắt đầu\",\n endLabel = \"Thời gian kết thúc\",\n layout = \"side-by-side\",\n locale = \"vi\",\n defaultView = \"days\",\n firstDayOfWeek = 1,\n minDate,\n maxDate,\n isDateDisabled,\n viewTabs,\n use12Hours = false,\n showSeconds = true,\n hourStep = 1,\n minuteStep = 1,\n secondStep = 1,\n minTime,\n maxTime,\n disabledHours,\n disabledMinutes,\n disabledSeconds,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius,\n label,\n labelPlacement = \"top\",\n placeholder,\n placeholders,\n helperText,\n errorMessage,\n name,\n id,\n autoComplete,\n disabled = false,\n readOnly = false,\n config,\n onClear,\n placement = \"bottom-start\",\n className = \"\",\n wrapperClassName = \"\",\n inputWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n popoverClassName = \"\",\n}: DateTimeRangePickerProps) {\n const {\n isRequired = false,\n isInvalid = false,\n isLoading = false,\n showSpinner = false,\n isClearable = true,\n isFullWidth = false,\n closeOnSelect = false,\n showWeekNumbers = false,\n showViewTabs = false,\n } = config ?? {};\n\n const generatedId = useId();\n const inputId = id || generatedId;\n const errorHelperId = `${inputId}-error-helper`;\n const popoverId = `${inputId}-popover`;\n\n const defaultFmt = getDefaultDateTimeFormat(use12Hours, showSeconds);\n const resolvedFormat = customFormat || defaultFmt;\n const baseDisplayFormat = customDisplayFormat || resolvedFormat;\n\n const isControlled = controlledValue !== undefined;\n const [internalRange, setInternalRange] = useState<DateTimeRange>(() => {\n const raw = defaultValue;\n if (raw && Array.isArray(raw)) {\n return [toDateTime(raw[0], resolvedFormat), toDateTime(raw[1], resolvedFormat)];\n }\n return [null, null];\n });\n\n const selectedRange: DateTimeRange =\n isControlled\n ? controlledValue && Array.isArray(controlledValue)\n ? [toDateTime(controlledValue[0], resolvedFormat), toDateTime(controlledValue[1], resolvedFormat)]\n : [null, null]\n : internalRange;\n\n const [activeStep, setActiveStep] = useState<\"start\" | \"end\">(\"start\");\n const [activeView, setActiveView] = useState<CalendarView>(defaultView);\n const [isOpen, setIsOpen] = useState(false);\n\n const startText = selectedRange[0] ? formatDateTime(selectedRange[0], baseDisplayFormat, locale) : \"\";\n const endText = selectedRange[1] ? formatDateTime(selectedRange[1], baseDisplayFormat, locale) : \"\";\n\n const formattedValue = useMemo(() => {\n if (startText && endText) {\n return `${startText}${separator}${endText}`;\n }\n if (startText) {\n return `${startText}${separator}`;\n }\n return \"\";\n }, [startText, endText, separator]);\n\n // Floating UI setup\n const {\n refs: { setReference, setFloating },\n floatingStyles,\n context,\n } = useFloating({\n placement,\n open: isOpen && !disabled && !readOnly && !isLoading,\n onOpenChange: setIsOpen,\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware: [offsetMiddleware(6), flipMiddleware(), shiftMiddleware({ padding: 8 })],\n });\n\n const dismiss = useDismiss(context, {\n escapeKey: true,\n outsidePress: true,\n });\n const role = useRole(context, { role: \"dialog\" });\n const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);\n\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: 150,\n initial: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n open: {\n opacity: 1,\n transform: \"translate(0px, 0px) scale(1)\",\n },\n close: ({ side }) => ({\n opacity: 0,\n transform:\n side === \"top\"\n ? \"translateY(4px) scale(0.96)\"\n : side === \"bottom\"\n ? \"translateY(-4px) scale(0.96)\"\n : side === \"left\"\n ? \"translateX(4px) scale(0.96)\"\n : \"translateX(-4px) scale(0.96)\",\n }),\n });\n\n const hasError = Boolean(isInvalid || errorMessage);\n const activeColor = hasError ? \"error\" : color;\n\n // Style configs\n const sizeStyles = getSafeConfig(size, dateTimeRangePickerSizeConfig, \"md\");\n const radiusClass = getSafeConfig(radius, dateTimeRangePickerRadiusConfig, \"lg\");\n const menuRadiusClass = getSafeConfig(radius, dateTimeRangeViewRadiusConfig, \"lg\");\n const buttonColorStyle = getSafeConfig(activeColor, dateTimeRangePickerButtonColorConfig, \"primary\");\n const variantClass =\n variant === \"other\"\n ? \"\"\n : getSafeConfig(activeColor, getSafeConfig(variant, dateTimeRangePickerVariantStyles, \"outline\"), \"primary\");\n\n const hasValue = Boolean(selectedRange[0] || selectedRange[1]);\n\n // Handlers\n const emitChange = (newRange: DateTimeRange) => {\n if (!isControlled) {\n setInternalRange(newRange);\n }\n const fStart = newRange[0] ? formatDateTime(newRange[0], resolvedFormat, locale) : \"\";\n const fEnd = newRange[1] ? formatDateTime(newRange[1], resolvedFormat, locale) : \"\";\n onChange?.(fStart || fEnd ? [fStart, fEnd] : null);\n\n if (closeOnSelect && newRange[0] && newRange[1]) {\n setIsOpen(false);\n }\n };\n\n const handleCalendarChange = (newDate: Date) => {\n if (activeStep === \"start\") {\n const combined = combineDateTime(newDate, selectedRange[0] || new Date());\n let nextEnd = selectedRange[1];\n if (nextEnd && combined && combined.getTime() > nextEnd.getTime()) {\n nextEnd = null;\n }\n emitChange([combined, nextEnd]);\n } else {\n const combined = combineDateTime(newDate, selectedRange[1] || selectedRange[0] || new Date());\n emitChange([selectedRange[0], combined]);\n }\n };\n\n const handleTimeChange = (newTime: Date | null) => {\n if (!newTime) return;\n if (activeStep === \"start\") {\n const combined = combineDateTime(selectedRange[0] || new Date(), newTime);\n let nextEnd = selectedRange[1];\n if (nextEnd && combined && combined.getTime() > nextEnd.getTime()) {\n nextEnd = null;\n }\n emitChange([combined, nextEnd]);\n } else {\n const combined = combineDateTime(selectedRange[1] || selectedRange[0] || new Date(), newTime);\n emitChange([selectedRange[0], combined]);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly || isLoading) return;\n if (e.key === \"ArrowDown\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!isOpen) setIsOpen(true);\n } else if (e.key === \"Escape\" && isOpen) {\n e.preventDefault();\n setIsOpen(false);\n }\n };\n\n const handleClear = (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (!isControlled) {\n setInternalRange([null, null]);\n }\n onChange?.(null);\n onClear?.();\n };\n\n const defaultPlaceholder =\n placeholder ||\n (placeholders\n ? `${placeholders[0]}${separator}${placeholders[1]}`\n : `${baseDisplayFormat}${separator}${baseDisplayFormat}`);\n\n const isFloating = labelPlacement === \"floating\";\n const isHorizontal = labelPlacement === \"left\";\n\n // Label Element\n const renderLabel = () => {\n if (!label) return null;\n\n const labelColorStyle = hasError\n ? \"text-error-600 font-bold\"\n : getSafeConfig(activeColor, labelColorConfig, \"primary\");\n\n if (isFloating) {\n return (\n <label\n htmlFor={inputId}\n className={`absolute top-0 -translate-y-1/2 left-3 px-1.5 rounded-sm select-none z-10 cursor-pointer font-bold bg-neutral-white transition-colors duration-150 ${sizeStyles.floatingLabel} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n }\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${sizeStyles.label} ${labelColorStyle} ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const renderIconWrapper = (iconNode: ReactNode) => (\n <span\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 leading-none select-none ${sizeStyles.icon}`}\n aria-hidden=\"true\"\n >\n {iconNode}\n </span>\n );\n\n const fieldWrapperClasses = [\n \"group/datetimerangepicker relative flex\",\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\",\n isFullWidth ? \"w-full\" : \"inline-flex\",\n wrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const containerClasses = [\n \"group/input relative flex items-center transition-all duration-150 ease-in-out border-2 select-none cursor-pointer\",\n sizeStyles.inputHeight,\n radiusClass,\n variantClass,\n disabled ? \"opacity-50\" : \"\",\n isFullWidth ? \"w-full\" : sizeStyles.minWidth || \"min-w-80\",\n inputWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const inputClasses = [\n \"w-full h-full bg-transparent outline-none border-none text-neutral-800 placeholder-neutral-400 cursor-pointer select-none caret-transparent focus:outline-none\",\n sizeStyles.inputText,\n sizeStyles.inputPadding,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const currentStepDate = activeStep === \"start\" ? selectedRange[0] : selectedRange[1];\n\n return (\n <div className={fieldWrapperClasses}>\n {/* Label (Top / Left) */}\n {!isFloating && renderLabel()}\n\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n {/* Input container */}\n <div ref={setReference} {...getReferenceProps()} className={containerClasses}>\n {isFloating && renderLabel()}\n\n <input\n ref={ref}\n id={inputId}\n name={name}\n type=\"text\"\n value={formattedValue}\n onClick={() => !disabled && !readOnly && !isLoading && setIsOpen((prev) => !prev)}\n onKeyDown={handleKeyDown}\n readOnly={true}\n autoComplete={autoComplete}\n placeholder={defaultPlaceholder}\n disabled={disabled || isLoading}\n role=\"combobox\"\n aria-expanded={isOpen && !isLoading}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-required={isRequired}\n aria-invalid={hasError}\n aria-busy={isLoading}\n aria-disabled={disabled || isLoading}\n aria-describedby={helperText || errorMessage ? errorHelperId : undefined}\n aria-errormessage={errorMessage ? errorHelperId : undefined}\n className={inputClasses}\n />\n\n {/* Right actions: Spinner, Clear, ChevronDown Icon */}\n <div className=\"flex items-center space-x-1.5 pr-2.5 shrink-0\">\n {isLoading && showSpinner && (\n <div className=\"flex items-center justify-center shrink-0\">{renderIconWrapper(<Spinner />)}</div>\n )}\n\n {!isLoading && isClearable && !disabled && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Xóa khoảng ngày giờ\"\n tabIndex={hasValue ? 0 : -1}\n aria-hidden={!hasValue}\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-600 active:scale-95 transition-opacity duration-150 cursor-pointer outline-none focus-visible:ring-1 focus-visible:ring-current rounded-full ${sizeStyles.icon} ${\n hasValue ? \"opacity-100 visible\" : \"opacity-0 invisible pointer-events-none\"\n }`}\n >\n <CloseIcon className=\"size-full\" />\n </button>\n )}\n\n <div\n aria-hidden=\"true\"\n className={`inline-flex items-center justify-center text-neutral-400 hover:text-neutral-600 transition-transform duration-200 ease-in-out cursor-pointer ${\n isOpen ? \"rotate-180\" : \"rotate-0\"\n }`}\n >\n {renderIconWrapper(<ChevronDownIcon className=\"size-full\" />)}\n </div>\n </div>\n </div>\n\n {/* Floating UI Portal */}\n {isMounted && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false} returnFocus={true}>\n <div\n ref={setFloating}\n id={popoverId}\n style={{\n ...floatingStyles,\n ...transitionStyles,\n zIndex: DEFAULT_Z_INDEX.PICKER,\n }}\n {...getFloatingProps()}\n className={`flex flex-col bg-neutral-white border-2 border-neutral-200 shadow-xl overflow-hidden select-none ${menuRadiusClass} ${popoverClassName}`}\n >\n {/* Central Picker Panel (Calendar + TimeView for Active Step) */}\n <div\n className={`flex ${\n layout === \"stacked\"\n ? \"flex-col divide-y-2 divide-neutral-200\"\n : \"flex-row divide-x-2 divide-neutral-200\"\n }`}\n >\n {/* Calendar Panel */}\n <div className=\"flex flex-col\">\n <Calendar\n key={`calendar-step-${activeStep}`}\n value={currentStepDate}\n onChange={handleCalendarChange}\n view={activeView}\n onViewChange={setActiveView}\n minDate={activeStep === \"end\" ? selectedRange[0] || minDate : minDate}\n maxDate={activeStep === \"start\" ? selectedRange[1] || maxDate : maxDate}\n isDateDisabled={isDateDisabled}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n showWeekNumbers={showWeekNumbers}\n size={size}\n color={color}\n radius={radius}\n showViewTabs={showViewTabs}\n viewTabs={viewTabs}\n className=\"border-none shadow-none rounded-none\"\n />\n </div>\n\n {/* Time Panel */}\n <div className=\"flex flex-col justify-center items-center p-1 bg-neutral-50/50\">\n <TimeView\n key={`timeview-step-${activeStep}`}\n value={currentStepDate || selectedRange[0]}\n onChange={handleTimeChange}\n ariaLabel={activeStep === \"start\" ? `${startLabel} time` : `${endLabel} time`}\n use12Hours={use12Hours}\n showSeconds={showSeconds}\n hourStep={hourStep}\n minuteStep={minuteStep}\n secondStep={secondStep}\n minTime={activeStep === \"end\" ? selectedRange[0] || minTime : minTime}\n maxTime={activeStep === \"start\" ? selectedRange[1] || maxTime : maxTime}\n disabledHours={disabledHours}\n disabledMinutes={disabledMinutes}\n disabledSeconds={disabledSeconds}\n size={size}\n color={color}\n radius={radius}\n className=\"border-none shadow-none bg-transparent\"\n />\n </div>\n </div>\n\n {/* Bottom Step Switching & Action Buttons */}\n <div className=\"flex items-center justify-between border-t border-neutral-200 bg-neutral-50 px-3 py-2\">\n <div className=\"flex items-center space-x-2\">\n {/* Button Quay lại Bắt đầu */}\n <button\n type=\"button\"\n onClick={() => setActiveStep(\"start\")}\n className={`px-3 py-1.5 text-xs font-semibold rounded-md border transition-all cursor-pointer ${\n activeStep === \"start\"\n ? buttonColorStyle.activeStep\n : \"bg-neutral-white border-neutral-300 hover:bg-neutral-100 text-neutral-700\"\n }`}\n >\n ← {startLabel}\n </button>\n\n {/* Button Chuyển sang Kết thúc */}\n <button\n type=\"button\"\n onClick={() => setActiveStep(\"end\")}\n className={`px-3 py-1.5 text-xs font-semibold rounded-md border transition-all cursor-pointer ${\n activeStep === \"end\"\n ? buttonColorStyle.activeStep\n : \"bg-neutral-white border-neutral-300 hover:bg-neutral-100 text-neutral-700\"\n }`}\n >\n {endLabel} →\n </button>\n </div>\n\n {/* Nút Áp dụng / Hoàn tất */}\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n className={`px-3.5 py-1.5 text-xs font-semibold rounded-md transition-colors cursor-pointer ${buttonColorStyle.applyButton}`}\n >\n Áp dụng\n </button>\n </div>\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n\n {/* Helper / Error text with animation */}\n <HelperErrorText\n id={errorHelperId}\n helperText={helperText}\n errorMessage={errorMessage}\n sizeClassName={sizeStyles.helper}\n className={helperClassName}\n />\n </div>\n </div>\n );\n}\n","import {\n DateTimeRangePickerColor,\n DateTimeRangePickerSize,\n} from \"./types\";\nimport {\n dateTimePickerRadiusConfig,\n dateTimeViewRadiusConfig,\n dateTimePickerColorConfig,\n dateTimePickerVariantStyles,\n} from \"../datetimepicker/constants\";\n\n/**\n * Cấu hình kích cỡ, khoảng đệm, typography và kích thước chiều rộng tối thiểu thoải mái cho 2 chuỗi ngày giờ\n */\nexport const dateTimeRangePickerSizeConfig: Record<\n DateTimeRangePickerSize,\n {\n inputHeight: string;\n inputText: string;\n inputPadding: string;\n minWidth: string;\n icon: string;\n iconSize: number;\n calendarPadding: string;\n cellSize: string;\n cellText: string;\n headerText: string;\n headerButtonSize: string;\n label: string;\n floatingLabel: string;\n helper: string;\n }\n> = {\n xs: {\n inputHeight: \"h-6\",\n inputText: \"text-[11px]\",\n inputPadding: \"px-2\",\n minWidth: \"min-w-72\",\n icon: \"size-3\",\n iconSize: 12,\n calendarPadding: \"p-2\",\n cellSize: \"w-7 h-7\",\n cellText: \"text-[11px]\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-6 w-6\",\n label: \"text-[11px] mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[9px] mt-0.5\",\n },\n sm: {\n inputHeight: \"h-8\",\n inputText: \"text-xs\",\n inputPadding: \"px-2.5\",\n minWidth: \"min-w-80\",\n icon: \"size-3.5\",\n iconSize: 14,\n calendarPadding: \"p-2.5\",\n cellSize: \"w-8 h-8\",\n cellText: \"text-xs\",\n headerText: \"text-xs font-semibold\",\n headerButtonSize: \"h-7 w-7\",\n label: \"text-xs mb-1\",\n floatingLabel: \"text-[10px]\",\n helper: \"text-[10px] mt-0.5\",\n },\n md: {\n inputHeight: \"h-10\",\n inputText: \"text-sm\",\n inputPadding: \"px-3\",\n minWidth: \"min-w-96\",\n icon: \"size-[18px]\",\n iconSize: 16,\n calendarPadding: \"p-3\",\n cellSize: \"w-9 h-9\",\n cellText: \"text-sm\",\n headerText: \"text-sm font-semibold\",\n headerButtonSize: \"h-8 w-8\",\n label: \"text-sm mb-1.5\",\n floatingLabel: \"text-[11px]\",\n helper: \"text-[11px] mt-1\",\n },\n lg: {\n inputHeight: \"h-12\",\n inputText: \"text-base\",\n inputPadding: \"px-3.5\",\n minWidth: \"min-w-105\",\n icon: \"size-5\",\n iconSize: 18,\n calendarPadding: \"p-4\",\n cellSize: \"w-10 h-10\",\n cellText: \"text-base\",\n headerText: \"text-base font-semibold\",\n headerButtonSize: \"h-9 w-9\",\n label: \"text-base mb-1.5\",\n floatingLabel: \"text-xs\",\n helper: \"text-xs mt-1\",\n },\n xl: {\n inputHeight: \"h-14\",\n inputText: \"text-lg\",\n inputPadding: \"px-4\",\n minWidth: \"min-w-120\",\n icon: \"size-6\",\n iconSize: 20,\n calendarPadding: \"p-4\",\n cellSize: \"w-12 h-12\",\n cellText: \"text-lg\",\n headerText: \"text-lg font-semibold\",\n headerButtonSize: \"h-10 w-10\",\n label: \"text-lg mb-2\",\n floatingLabel: \"text-sm\",\n helper: \"text-sm mt-1.5\",\n },\n};\n\n/**\n * Re-export & alias cấu hình bo góc từ DateTimePicker\n */\nexport const dateTimeRangePickerRadiusConfig = dateTimePickerRadiusConfig;\n\n/**\n * Re-export & alias cấu hình bo góc cho khung popover từ DateTimePicker\n */\nexport const dateTimeRangeViewRadiusConfig = dateTimeViewRadiusConfig;\n\n/**\n * Re-export & alias cấu hình màu sắc từ DateTimePicker\n */\nexport const dateTimeRangePickerColorConfig = dateTimePickerColorConfig;\n\n/**\n * Re-export & alias cấu hình biến thể từ DateTimePicker\n */\nexport const dateTimeRangePickerVariantStyles = dateTimePickerVariantStyles;\n\n/**\n * Cấu hình màu chữ của nhãn label theo màu chủ đề với prefix group-focus-within/datetimerangepicker\n */\nexport const labelColorConfig: Record<DateTimeRangePickerColor, string> = {\n primary: \"text-primary-500 group-focus-within/datetimerangepicker:text-primary-600\",\n secondary: \"text-secondary-500 group-focus-within/datetimerangepicker:text-secondary-600\",\n error: \"text-error-500 group-focus-within/datetimerangepicker:text-error-600\",\n success: \"text-success-500 group-focus-within/datetimerangepicker:text-success-600\",\n warning: \"text-warning-500 group-focus-within/datetimerangepicker:text-warning-600\",\n info: \"text-info-500 group-focus-within/datetimerangepicker:text-info-600\",\n neutral: \"text-neutral-500 group-focus-within/datetimerangepicker:text-neutral-600\",\n};\n\n/**\n * Cấu hình màu sắc của nút chuyển bước (Active) và nút Áp dụng theo màu chủ đề (Theme Color)\n */\nexport const dateTimeRangePickerButtonColorConfig: Record<\n DateTimeRangePickerColor,\n {\n activeStep: string;\n applyButton: string;\n }\n> = {\n primary: {\n activeStep: \"bg-primary-500 border-primary-500 text-neutral-white shadow-xs\",\n applyButton: \"bg-primary-500 hover:bg-primary-600 active:bg-primary-700 text-neutral-white shadow-xs\",\n },\n secondary: {\n activeStep: \"bg-secondary-500 border-secondary-500 text-neutral-white shadow-xs\",\n applyButton: \"bg-secondary-500 hover:bg-secondary-600 active:bg-secondary-700 text-neutral-white shadow-xs\",\n },\n error: {\n activeStep: \"bg-error-500 border-error-500 text-neutral-white shadow-xs\",\n applyButton: \"bg-error-500 hover:bg-error-600 active:bg-error-700 text-neutral-white shadow-xs\",\n },\n success: {\n activeStep: \"bg-success-500 border-success-500 text-neutral-white shadow-xs\",\n applyButton: \"bg-success-500 hover:bg-success-600 active:bg-success-700 text-neutral-white shadow-xs\",\n },\n warning: {\n activeStep: \"bg-warning-500 border-warning-500 text-neutral-950 shadow-xs\",\n applyButton: \"bg-warning-500 hover:bg-warning-600 active:bg-warning-700 text-neutral-950 shadow-xs\",\n },\n info: {\n activeStep: \"bg-info-500 border-info-500 text-neutral-white shadow-xs\",\n applyButton: \"bg-info-500 hover:bg-info-600 active:bg-info-700 text-neutral-white shadow-xs\",\n },\n neutral: {\n activeStep: \"bg-neutral-800 border-neutral-800 text-neutral-white shadow-xs\",\n applyButton: \"bg-neutral-800 hover:bg-neutral-900 active:bg-neutral-950 text-neutral-white shadow-xs\",\n },\n};\n","import React from \"react\";\nimport Image from \"next/image\";\nimport { EmptyProps, EmptyPresetImage } from \"./types\";\nimport { emptySizeConfig, emptyLayoutConfig } from \"./constants\";\nimport EmptyIllustration from \"./EmptyIllustration\";\n\nconst PRESETS: EmptyPresetImage[] = [\"default\", \"search\", \"error\", \"folder\", \"simple\"];\n\nfunction isPresetImage(val: unknown): val is EmptyPresetImage {\n return typeof val === \"string\" && PRESETS.includes(val as EmptyPresetImage);\n}\n\nfunction isUrlString(val: unknown): val is string {\n if (typeof val !== \"string\") return false;\n return (\n val.startsWith(\"http://\") ||\n val.startsWith(\"https://\") ||\n val.startsWith(\"/\") ||\n val.startsWith(\"./\") ||\n val.startsWith(\"data:\") ||\n /\\.(png|jpe?g|svg|webp|gif|avif)$/i.test(val)\n );\n}\n\nexport default function Empty({\n size = \"md\",\n layout = \"vertical\",\n image = \"default\",\n imageSize,\n imageClassName = \"\",\n imageAlt = \"Trống\",\n title,\n titleClassName = \"\",\n description = \"Không có dữ liệu\",\n descriptionClassName = \"\",\n actions,\n actionsClassName = \"\",\n children,\n className = \"\",\n role = \"status\",\n ref,\n ...props\n}: EmptyProps) {\n const currentSize = emptySizeConfig[size] || emptySizeConfig.md;\n const currentLayout = emptyLayoutConfig[layout] || emptyLayoutConfig.vertical;\n\n // Custom inline style for image dimensions if imageSize is provided\n const imageInlineStyle: React.CSSProperties = imageSize\n ? {\n width: typeof imageSize === \"number\" ? `${imageSize}px` : imageSize,\n height: typeof imageSize === \"number\" ? `${imageSize}px` : imageSize,\n }\n : {};\n\n const renderImageContent = () => {\n if (!image) return null;\n\n if (isPresetImage(image)) {\n return <EmptyIllustration preset={image} />;\n }\n\n if (isUrlString(image)) {\n const dimension = typeof imageSize === \"number\" ? imageSize : currentSize.defaultImageSize;\n\n return (\n <Image\n src={image}\n alt={imageAlt}\n width={dimension}\n height={dimension}\n className=\"size-full object-contain pointer-events-none select-none\"\n unoptimized={image.startsWith(\"data:\") || image.endsWith(\".svg\")}\n />\n );\n }\n\n if (React.isValidElement(image)) {\n return image;\n }\n\n return <EmptyIllustration preset=\"default\" />;\n };\n\n const imageWrapperClasses = [\n \"flex items-center justify-center shrink-0\",\n !imageSize ? currentSize.imageWrapper : \"\",\n imageClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const containerClasses = [\n \"w-full transition-all\",\n currentLayout.container,\n currentSize.container,\n currentSize.gap,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const contentClasses = [currentLayout.content, currentSize.contentGap].filter(Boolean).join(\" \");\n\n const titleClasses = [currentSize.title, titleClassName].filter(Boolean).join(\" \");\n\n const descriptionClasses = [currentSize.description, descriptionClassName].filter(Boolean).join(\" \");\n\n const actionsClasses = [\n \"flex flex-wrap items-center gap-2\",\n currentSize.actionsGap,\n layout === \"vertical\" ? \"justify-center\" : \"justify-start\",\n actionsClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div ref={ref} role={role} aria-live=\"polite\" className={containerClasses} {...props}>\n {image && (\n <div className={imageWrapperClasses} style={imageInlineStyle} aria-hidden=\"true\">\n {renderImageContent()}\n </div>\n )}\n\n {(title || description || actions || children) && (\n <div className={contentClasses}>\n {title && <div className={titleClasses}>{title}</div>}\n\n {description && <div className={descriptionClasses}>{description}</div>}\n\n {actions && <div className={actionsClasses}>{actions}</div>}\n\n {children && <div className=\"mt-2 w-full\">{children}</div>}\n </div>\n )}\n </div>\n );\n}\n","import { EmptySize, EmptyLayout } from \"./types\";\n\nexport const emptySizeConfig: Record<\n EmptySize,\n {\n container: string;\n imageWrapper: string;\n defaultImageSize: number;\n title: string;\n description: string;\n gap: string;\n contentGap: string;\n actionsGap: string;\n }\n> = {\n sm: {\n container: \"p-3\",\n imageWrapper: \"w-16 h-16\",\n defaultImageSize: 64,\n title: \"text-xs font-semibold text-neutral-800\",\n description: \"text-xs text-neutral-500\",\n gap: \"gap-2.5\",\n contentGap: \"gap-1\",\n actionsGap: \"mt-2\",\n },\n md: {\n container: \"p-6\",\n imageWrapper: \"w-28 h-28\",\n defaultImageSize: 112,\n title: \"text-sm font-semibold text-neutral-800\",\n description: \"text-xs sm:text-sm text-neutral-500\",\n gap: \"gap-4\",\n contentGap: \"gap-1.5\",\n actionsGap: \"mt-3.5\",\n },\n lg: {\n container: \"p-10\",\n imageWrapper: \"w-40 h-40\",\n defaultImageSize: 160,\n title: \"text-base font-semibold text-neutral-900\",\n description: \"text-sm text-neutral-500\",\n gap: \"gap-6\",\n contentGap: \"gap-2\",\n actionsGap: \"mt-5\",\n },\n};\n\nexport const emptyLayoutConfig: Record<\n EmptyLayout,\n {\n container: string;\n content: string;\n }\n> = {\n vertical: {\n container: \"flex flex-col items-center justify-center text-center\",\n content: \"flex flex-col items-center justify-center text-center\",\n },\n horizontal: {\n container: \"flex flex-row items-center justify-start text-left\",\n content: \"flex flex-col items-start justify-center text-left flex-1\",\n },\n};\n","import type { SVGProps } from \"react\";\nimport { EmptyPresetImage } from \"./types\";\nimport EmptyDefaultIcon from \"../icons/EmptyDefaultIcon\";\nimport EmptySearchIcon from \"../icons/EmptySearchIcon\";\nimport EmptyErrorIcon from \"../icons/EmptyErrorIcon\";\nimport EmptyFolderIcon from \"../icons/EmptyFolderIcon\";\nimport EmptySimpleIcon from \"../icons/EmptySimpleIcon\";\n\nexport interface EmptyIllustrationProps extends SVGProps<SVGSVGElement> {\n preset?: EmptyPresetImage;\n}\n\nexport default function EmptyIllustration({ preset = \"default\", ...props }: EmptyIllustrationProps) {\n switch (preset) {\n case \"search\":\n return <EmptySearchIcon {...props} />;\n case \"error\":\n return <EmptyErrorIcon {...props} />;\n case \"folder\":\n return <EmptyFolderIcon {...props} />;\n case \"simple\":\n return <EmptySimpleIcon {...props} />;\n case \"default\":\n default:\n return <EmptyDefaultIcon {...props} />;\n }\n}\n","import React, { useState, useRef, useMemo, useEffect, useCallback, useId } from \"react\";\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip as flipMiddleware,\n shift as shiftMiddleware,\n useClick,\n useDismiss,\n useRole,\n useListNavigation,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { rankItem, compareItems } from \"@tanstack/match-sorter-utils\";\nimport { SelectProps, SelectOptionItem, SingleSelectProps, MultiSelectProps } from \"./types\";\n\nimport { labelPlacementConfig } from \"./constants\";\nimport SelectTrigger from \"./SelectTrigger\";\nimport SelectMenu from \"./SelectMenu\";\nimport { useDebouncedCallback } from \"@/hooks/useDebouncedCallback\";\n\nconst DEFAULT_OPTIONS: never[] = [];\n\nfunction isMultiSelect<TData = unknown, TFilters extends Record<string, unknown> = Record<string, unknown>>(\n props: SelectProps<TData, TFilters>\n): props is MultiSelectProps<TData, TFilters> {\n return Boolean(props.multiple);\n}\n\nexport function Select<TData = unknown, TFilters extends Record<string, unknown> = Record<string, unknown>>(\n props: SelectProps<TData, TFilters>\n) {\n const {\n ref,\n options = DEFAULT_OPTIONS,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius = \"md\",\n id,\n label,\n labelPlacement = \"top\",\n\n placeholder = \"Chọn...\",\n helperText,\n errorMessage,\n isInvalid = Boolean(errorMessage),\n isDisabled = false,\n isReadOnly = false,\n readOnly = false,\n isRequired = false,\n name,\n searchable = false,\n searchMode = \"client\",\n searchPlacement = \"trigger\",\n searchPlaceholder,\n searchValue: controlledSearchValue,\n onSearchChange,\n menuFilters,\n menuFilterValues: controlledFilterValues,\n menuFilterLayout = \"vertical\",\n menuFilterGridCols = 2,\n showResetFilters = true,\n resetFiltersText,\n onMenuFilterChange,\n menuHeader,\n menuFooter,\n onSearch,\n debounceMs = 300,\n filterFn,\n loading: loadingProp = false,\n isLoading: isLoadingProp,\n emptyText,\n emptyProps,\n clearable = false,\n portal = true,\n placement = \"bottom-start\",\n maxMenuHeight = 280,\n startContent,\n endContent,\n renderValue,\n renderOption,\n className = \"\",\n triggerClassName = \"\",\n menuClassName = \"\",\n } = props;\n\n const isMultiple = isMultiSelect(props);\n const loading = Boolean(isLoadingProp ?? loadingProp);\n\n // ==================== VALUE STATE (CONTROLLED / UNCONTROLLED) ====================\n const singleProps = !isMultiple ? (props as SingleSelectProps<TData, TFilters>) : null;\n const multiProps = isMultiple ? (props as MultiSelectProps<TData, TFilters>) : null;\n\n const [uncontrolledSingle, setUncontrolledSingle] = useState<string | number | null>(\n singleProps?.defaultValue ?? null\n );\n\n const [uncontrolledMulti, setUncontrolledMulti] = useState<(string | number)[]>(multiProps?.defaultValue ?? []);\n\n const isSingleControlled = singleProps?.value !== undefined;\n const isMultiControlled = multiProps?.value !== undefined;\n\n const controlledMultiValue = multiProps?.value;\n const currentMultiValue = useMemo(() => {\n return isMultiControlled ? (controlledMultiValue ?? []) : uncontrolledMulti;\n }, [isMultiControlled, controlledMultiValue, uncontrolledMulti]);\n\n const controlledSingleValue = singleProps?.value;\n const currentSingleValue = useMemo(() => {\n return isSingleControlled ? (controlledSingleValue ?? null) : uncontrolledSingle;\n }, [isSingleControlled, controlledSingleValue, uncontrolledSingle]);\n\n // ==================== SELECTED OPTIONS CACHE ====================\n // Lưu cache toàn bộ options đã từng được chọn để khi search server/client không làm mất Badge/Label\n const selectedCacheRef = useRef<Map<string | number, SelectOptionItem<TData>>>(new Map());\n\n useEffect(() => {\n options.forEach((opt) => {\n selectedCacheRef.current.set(opt.value, opt);\n });\n }, [options]);\n\n const selectedOptions = useMemo<SelectOptionItem<TData>[]>(() => {\n if (isMultiple) {\n return currentMultiValue.map((val) => {\n const found = options.find((o) => o.value === val) || selectedCacheRef.current.get(val);\n return (\n found || {\n value: val,\n label: String(val),\n }\n );\n });\n }\n\n if (currentSingleValue !== null && currentSingleValue !== undefined) {\n const found =\n options.find((o) => o.value === currentSingleValue) || selectedCacheRef.current.get(currentSingleValue);\n return [\n found || {\n value: currentSingleValue,\n label: String(currentSingleValue),\n },\n ];\n }\n\n return [];\n }, [isMultiple, currentMultiValue, currentSingleValue, options]);\n\n // ==================== OPEN & INTERACTION STATE ====================\n const [isOpen, setIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n\n // ==================== SEARCH & FILTER STATE ====================\n const [uncontrolledSearch, setUncontrolledSearch] = useState(\"\");\n const isSearchControlled = controlledSearchValue !== undefined;\n const searchInput = isSearchControlled ? controlledSearchValue : uncontrolledSearch;\n\n // ==================== SERVER DEBOUNCE ====================\n const { debounced } = useDebouncedCallback((query: string, filters: TFilters) => {\n if (searchMode === \"server\") {\n onSearch?.(query, filters);\n }\n }, debounceMs);\n\n const handleSearchChange = (val: string) => {\n if (!isSearchControlled) {\n setUncontrolledSearch(val);\n }\n onSearchChange?.(val);\n if (!isOpen) {\n setIsOpen(true);\n }\n debounced(val, currentFilters);\n };\n\n const [internalFilters, setInternalFilters] = useState<Partial<TFilters>>(() => {\n const initial: Record<string, unknown> = {};\n menuFilters?.forEach((f) => {\n if (f.defaultValue !== undefined) {\n initial[f.name] = f.defaultValue;\n }\n });\n return initial as Partial<TFilters>;\n });\n\n const currentFilters = (controlledFilterValues ?? internalFilters) as TFilters;\n\n const handleFilterChange = (name: string, val: unknown) => {\n const nextFilters = {\n ...currentFilters,\n [name]: val,\n } as TFilters;\n\n if (!controlledFilterValues) {\n setInternalFilters(nextFilters);\n }\n onMenuFilterChange?.(nextFilters);\n debounced(searchInput, nextFilters);\n };\n\n const handleResetFilters = () => {\n const resetValues: Record<string, unknown> = {};\n menuFilters?.forEach((f) => {\n if (f.defaultValue !== undefined) {\n resetValues[f.name] = f.defaultValue;\n }\n });\n if (!controlledFilterValues) {\n setInternalFilters(resetValues as Partial<TFilters>);\n }\n onMenuFilterChange?.(resetValues as TFilters);\n debounced(searchInput, resetValues as TFilters);\n };\n\n // ==================== FILTERED OPTIONS (CLIENT MODE) ====================\n const filteredOptions = useMemo(() => {\n if (searchMode === \"server\") {\n return options;\n }\n\n let list = options;\n\n // 1. Fuzzy Search qua @tanstack/match-sorter-utils (rankItem & compareItems)\n const keyword = searchInput.trim();\n if (keyword) {\n const ranked: { item: SelectOptionItem<TData>; info: ReturnType<typeof rankItem> }[] = [];\n const accessors = [\n (opt: SelectOptionItem<TData>) => opt.label,\n (opt: SelectOptionItem<TData>) => String(opt.value),\n (opt: SelectOptionItem<TData>) => String(opt.description || \"\"),\n ];\n for (const item of list) {\n const info = rankItem(item, keyword, { accessors });\n if (info.passed) {\n ranked.push({ item, info });\n }\n }\n ranked.sort((a, b) => compareItems(a.info, b.info));\n list = ranked.map((r) => r.item);\n }\n\n // 2. Custom Filter Function\n if (filterFn) {\n list = list.filter((opt) => filterFn(opt, searchInput, currentFilters));\n }\n\n return list;\n }, [options, searchMode, searchInput, filterFn, currentFilters]);\n\n // ==================== FLOATING UI ====================\n const elementsRef = useRef<(HTMLElement | null)[]>([]);\n\n // Trạng thái vô hiệu hóa / Chỉ đọc\n const effectiveReadOnly = Boolean(isReadOnly || readOnly);\n const isInteractive = !isDisabled && !effectiveReadOnly;\n\n const { refs, floatingStyles, context } = useFloating({\n placement,\n open: isOpen && isInteractive,\n onOpenChange: (nextOpen) => {\n // Chỉ cho phép mở khi không loading, hoặc cho phép đóng/giữ mở khi đang tương tác\n if (isInteractive && (!loading || isOpen || !nextOpen)) {\n setIsOpen(nextOpen);\n if (!nextOpen) {\n setActiveIndex(null);\n if (!isSearchControlled && !isMultiple) {\n setUncontrolledSearch(\"\");\n }\n }\n }\n },\n whileElementsMounted: autoUpdate,\n transform: false,\n middleware: [offsetMiddleware(4), flipMiddleware(), shiftMiddleware({ padding: 8 })],\n });\n\n const click = useClick(context, {\n enabled: isInteractive && (!loading || isOpen),\n });\n\n const dismiss = useDismiss(context);\n const role = useRole(context, { role: \"listbox\" });\n\n const listNavigation = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss, role, listNavigation]);\n\n // ==================== SELECTION HANDLERS ====================\n const handleSelectOption = useCallback(\n (option: SelectOptionItem<TData>) => {\n if (option.disabled || isDisabled || isReadOnly) return;\n\n // Cache option\n selectedCacheRef.current.set(option.value, option);\n\n if (isMultiple) {\n const multiProps = props as MultiSelectProps<TData, TFilters>;\n const exists = currentMultiValue.includes(option.value);\n const nextValues = exists\n ? currentMultiValue.filter((v) => v !== option.value)\n : [...currentMultiValue, option.value];\n\n if (!isMultiControlled) {\n setUncontrolledMulti(nextValues);\n }\n\n const nextSelectedItems = nextValues.map((val) => {\n return (\n options.find((o) => o.value === val) ||\n selectedCacheRef.current.get(val) || {\n value: val,\n label: String(val),\n }\n );\n });\n\n multiProps.onChange?.(nextValues, nextSelectedItems);\n // Giữ menu mở và reset search input\n if (!isSearchControlled) {\n setUncontrolledSearch(\"\");\n }\n } else {\n const singleProps = props as SingleSelectProps<TData, TFilters>;\n if (!isSingleControlled) {\n setUncontrolledSingle(option.value);\n }\n singleProps.onChange?.(option.value, option);\n setIsOpen(false);\n if (!isSearchControlled) {\n setUncontrolledSearch(\"\");\n }\n }\n },\n [\n isMultiple,\n isDisabled,\n isReadOnly,\n props,\n currentMultiValue,\n isMultiControlled,\n options,\n isSearchControlled,\n isSingleControlled,\n ]\n );\n\n const handleRemoveTag = useCallback(\n (option: SelectOptionItem<TData>) => {\n if (isDisabled || isReadOnly || !isMultiple) return;\n const nextValues = currentMultiValue.filter((v) => v !== option.value);\n\n if (!isMultiControlled) {\n setUncontrolledMulti(nextValues);\n }\n\n const nextSelectedItems = nextValues.map((val) => {\n return (\n options.find((o) => o.value === val) ||\n selectedCacheRef.current.get(val) || {\n value: val,\n label: String(val),\n }\n );\n });\n\n if (isMultiple) {\n (props as MultiSelectProps<TData, TFilters>).onChange?.(nextValues, nextSelectedItems);\n }\n },\n [isDisabled, isReadOnly, isMultiple, currentMultiValue, isMultiControlled, options, props]\n );\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n if (isDisabled || isReadOnly) return;\n\n if (isMultiple) {\n if (!isMultiControlled) {\n setUncontrolledMulti([]);\n }\n (props as MultiSelectProps<TData, TFilters>).onChange?.([], []);\n } else {\n if (!isSingleControlled) {\n setUncontrolledSingle(null);\n }\n (props as SingleSelectProps<TData, TFilters>).onChange?.(null, null);\n }\n\n if (!isSearchControlled) {\n setUncontrolledSearch(\"\");\n }\n },\n [isDisabled, isReadOnly, isMultiple, props, isMultiControlled, isSingleControlled, isSearchControlled]\n );\n\n // ==================== KEYBOARD HANDLING ====================\n const handleTriggerKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n const inputVal = (e.currentTarget as HTMLInputElement)?.value ?? searchInput;\n if (e.key === \"Backspace\" && (!inputVal || inputVal.length === 0) && isMultiple && selectedOptions.length > 0) {\n e.preventDefault();\n const lastTag = selectedOptions[selectedOptions.length - 1];\n if (lastTag) {\n handleRemoveTag(lastTag);\n }\n } else if (e.key === \"Enter\" && isOpen && activeIndex !== null) {\n e.preventDefault();\n const targetOption = filteredOptions[activeIndex];\n if (targetOption) {\n handleSelectOption(targetOption);\n }\n } else if (e.key === \"ArrowDown\" && !isOpen) {\n setIsOpen(true);\n }\n };\n\n // ==================== LABEL & WRAPPER LAYOUT ====================\n const placementStyle = labelPlacementConfig[labelPlacement] || labelPlacementConfig.top;\n\n const generatedId = useId();\n const selectId = id || generatedId;\n const triggerId = `${selectId}-trigger`;\n\n return (\n <div\n ref={ref}\n id={id}\n className={`${placementStyle.container} ${className}`}\n data-disabled={isDisabled}\n data-invalid={isInvalid}\n >\n {/* Label */}\n {label && (\n <label htmlFor={triggerId} className={placementStyle.label}>\n {label}\n {isRequired && (\n <span className=\"text-red-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n {/* Trigger & Menu Container */}\n <div className=\"relative flex-1 min-w-0\">\n <SelectTrigger\n id={triggerId}\n triggerRef={refs.setReference}\n getReferenceProps={getReferenceProps}\n selectedOptions={selectedOptions}\n isOpen={isOpen}\n size={size}\n variant={variant}\n color={color}\n radius={radius}\n placeholder={searchPlaceholder || placeholder}\n disabled={isDisabled}\n readOnly={effectiveReadOnly}\n isInvalid={isInvalid}\n multiple={isMultiple}\n\n maxTagCount={isMultiple ? (props as MultiSelectProps<TData, TFilters>).maxTagCount : undefined}\n searchable={searchable}\n searchPlacement={searchPlacement}\n searchValue={searchInput}\n onSearchChange={handleSearchChange}\n onRemoveTag={handleRemoveTag}\n onClear={handleClear}\n clearable={clearable}\n loading={loading}\n startContent={startContent}\n endContent={endContent}\n renderValue={renderValue}\n onKeyDown={handleTriggerKeyDown}\n className={triggerClassName}\n />\n\n <SelectMenu\n isOpen={isOpen}\n options={filteredOptions}\n selectedValues={\n isMultiple\n ? currentMultiValue\n : currentSingleValue !== null && currentSingleValue !== undefined\n ? [currentSingleValue]\n : []\n }\n activeIndex={activeIndex}\n size={size}\n color={color}\n radius={radius}\n loading={loading}\n portal={portal}\n maxMenuHeight={maxMenuHeight}\n emptyText={emptyText}\n emptyProps={emptyProps}\n menuHeader={menuHeader}\n menuFooter={menuFooter}\n menuFilters={menuFilters}\n menuFilterValues={currentFilters}\n menuFilterLayout={menuFilterLayout}\n menuFilterGridCols={menuFilterGridCols}\n showResetFilters={showResetFilters}\n resetFiltersText={resetFiltersText}\n onMenuFilterChange={handleFilterChange}\n onResetFilters={handleResetFilters}\n renderOption={renderOption}\n onSelectOption={handleSelectOption}\n onOptionMouseEnter={setActiveIndex}\n floatingRef={refs.setFloating}\n floatingStyles={floatingStyles}\n getFloatingProps={getFloatingProps}\n listElementsRef={elementsRef}\n className={menuClassName}\n />\n </div>\n\n {/* Hidden inputs for native form submissions */}\n {name && (\n <>\n {isMultiple ? (\n currentMultiValue.map((val, idx) => (\n <input key={`${name}-${val}-${idx}`} type=\"hidden\" name={`${name}[]`} value={String(val)} />\n ))\n ) : currentSingleValue !== null && currentSingleValue !== undefined ? (\n <input type=\"hidden\" name={name} value={String(currentSingleValue)} />\n ) : null}\n </>\n )}\n\n {/* Helper text or Error message */}\n {(errorMessage || helperText) && (\n <div className={`text-xs ${isInvalid ? \"text-error-600 font-normal\" : \"text-neutral-500 font-normal\"}`}>\n {errorMessage || helperText}\n </div>\n )}\n </div>\n );\n}\n\nexport default Select;\n","import { SelectSize, SelectRadius, SelectVariant, SelectColor, LabelPlacement } from \"./types\";\nimport { BadgeRadius, BadgeSize } from \"@/components/badge/types\";\n\nexport const sizeConfig: Record<\n SelectSize,\n {\n trigger: string;\n input: string;\n text: string;\n icon: string;\n option: string;\n gap: string;\n badgeSize: BadgeSize;\n defaultRadius: SelectRadius;\n }\n> = {\n xs: {\n trigger: \"min-h-6 text-[11px] px-2 py-0.5\",\n input: \"text-[11px] leading-tight\",\n text: \"text-[11px]\",\n icon: \"size-3\",\n option: \"px-2 py-1 text-[11px] min-h-6\",\n gap: \"gap-1\",\n badgeSize: \"xs\",\n defaultRadius: \"sm\",\n },\n sm: {\n trigger: \"min-h-8 text-xs px-2.5 py-1\",\n input: \"text-xs leading-normal\",\n text: \"text-xs\",\n icon: \"size-3.5\",\n option: \"px-2.5 py-1.5 text-xs min-h-7\",\n gap: \"gap-1\",\n badgeSize: \"xs\",\n defaultRadius: \"md\",\n },\n md: {\n trigger: \"min-h-10 text-sm px-3.5 py-1.5\",\n input: \"text-sm leading-normal\",\n text: \"text-sm\",\n icon: \"size-[18px]\",\n option: \"px-3 py-2 text-sm min-h-9\",\n gap: \"gap-1.5\",\n badgeSize: \"sm\",\n defaultRadius: \"lg\",\n },\n lg: {\n trigger: \"min-h-12 text-base px-4 py-2\",\n input: \"text-base leading-normal\",\n text: \"text-base\",\n icon: \"size-5\",\n option: \"px-3.5 py-2.5 text-base min-h-11\",\n gap: \"gap-2\",\n badgeSize: \"md\",\n defaultRadius: \"xl\",\n },\n xl: {\n trigger: \"min-h-14 text-lg px-5 py-2.5\",\n input: \"text-lg leading-normal\",\n text: \"text-lg\",\n icon: \"size-6\",\n option: \"px-4 py-3 text-lg min-h-12\",\n gap: \"gap-2\",\n badgeSize: \"lg\",\n defaultRadius: \"xl\",\n },\n};\n\nexport const radiusConfig: Record<SelectRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const badgeRadiusMap: Record<SelectRadius, BadgeRadius> = {\n none: \"none\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n full: \"full\",\n};\n\n/**\n * Cấu hình màu sắc của Select đồng bộ 100% với Input (theo colors.ts và variantColorConfig của Input)\n */\nexport const variantColorConfig: Record<Exclude<SelectVariant, \"other\">, Record<SelectColor, string>> = {\n outline: {\n primary:\n \"bg-neutral-white border-primary-400 hover:border-primary-500 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20 text-neutral-900\",\n secondary:\n \"bg-neutral-white border-secondary-400 hover:border-secondary-500 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20 text-neutral-900\",\n error:\n \"bg-neutral-white border-error-500 hover:border-error-600 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20 text-neutral-900\",\n success:\n \"bg-neutral-white border-success-400 hover:border-success-500 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20 text-neutral-900\",\n warning:\n \"bg-neutral-white border-warning-400 hover:border-warning-500 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20 text-neutral-900\",\n info: \"bg-neutral-white border-info-400 hover:border-info-500 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20 text-neutral-900\",\n neutral:\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20 text-neutral-900\",\n },\n\n filled: {\n primary:\n \"bg-primary-50/60 border border-primary-200 hover:bg-primary-100/60 focus-within:bg-primary-100/60 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20 text-neutral-900\",\n secondary:\n \"bg-secondary-50/60 border border-secondary-200 hover:bg-secondary-100/60 focus-within:bg-secondary-100/60 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20 text-neutral-900\",\n error:\n \"bg-error-50/60 border border-error-500 hover:border-error-600 hover:bg-error-100/60 focus-within:bg-error-100/60 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20 text-neutral-900\",\n success:\n \"bg-success-50/60 border border-success-200 hover:bg-success-100/60 focus-within:bg-success-100/60 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20 text-neutral-900\",\n warning:\n \"bg-warning-50/60 border border-warning-200 hover:bg-warning-100/60 focus-within:bg-warning-100/60 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20 text-neutral-900\",\n info: \"bg-info-50/60 border border-info-200 hover:bg-info-100/60 focus-within:bg-info-100/60 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20 text-neutral-900\",\n neutral:\n \"bg-neutral-50/60 border border-neutral-200 hover:bg-neutral-200/60 focus-within:bg-neutral-200/60 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20 text-neutral-900\",\n },\n ghost: {\n primary:\n \"bg-transparent border border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-200/20 focus-within:ring-2 focus-within:ring-primary-500/20 text-neutral-900\",\n secondary:\n \"bg-transparent border border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-200/20 focus-within:ring-2 focus-within:ring-secondary-500/20 text-neutral-900\",\n error:\n \"bg-transparent border border-transparent hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20 text-neutral-900\",\n success:\n \"bg-transparent border border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-200/20 focus-within:ring-2 focus-within:ring-success-500/20 text-neutral-900\",\n warning:\n \"bg-transparent border border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-200/20 focus-within:ring-2 focus-within:ring-warning-500/20 text-neutral-900\",\n info: \"bg-transparent border border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-200/20 focus-within:ring-2 focus-within:ring-info-500/20 text-neutral-900\",\n neutral:\n \"bg-transparent border border-transparent hover:bg-neutral-50/50 focus-within:bg-neutral-50/50 focus-within:border-neutral-200/20 focus-within:ring-2 focus-within:ring-neutral-500/20 text-neutral-900\",\n },\n};\n\nexport const optionSelectedColorConfig: Record<SelectColor, string> = {\n primary: \"bg-primary-50 text-primary-700 font-medium\",\n secondary: \"bg-secondary-50 text-secondary-700 font-medium\",\n error: \"bg-error-50 text-error-700 font-medium\",\n success: \"bg-success-50 text-success-700 font-medium\",\n warning: \"bg-warning-50 text-warning-700 font-medium\",\n info: \"bg-info-50 text-info-700 font-medium\",\n neutral: \"bg-neutral-100 text-neutral-900 font-medium\",\n};\n\nexport const optionActiveColorConfig: Record<SelectColor, string> = {\n primary: \"bg-primary-50/60\",\n secondary: \"bg-secondary-50/60\",\n error: \"bg-error-50/60\",\n success: \"bg-success-50/60\",\n warning: \"bg-warning-50/60\",\n info: \"bg-info-50/60\",\n neutral: \"bg-neutral-100\",\n};\n\nexport const labelPlacementConfig: Record<\n LabelPlacement,\n {\n container: string;\n label: string;\n }\n> = {\n top: {\n container: \"flex flex-col gap-1.5\",\n label: \"text-sm font-bold text-neutral-700 mb-1\",\n },\n left: {\n container: \"flex flex-row items-center gap-3\",\n label: \"text-sm font-bold text-neutral-700 shrink-0\",\n },\n floating: {\n container: \"relative\",\n label:\n \"absolute left-3 -top-2.5 bg-neutral-white px-1.5 text-xs font-bold text-neutral-600 z-10 transition-all pointer-events-none rounded-sm\",\n },\n};\n","import React, { ReactNode, useRef } from \"react\";\nimport { SelectOptionItem, SelectSize, SelectVariant, SelectColor, SelectRadius, SelectSearchPlacement } from \"./types\";\nimport { sizeConfig, radiusConfig, variantColorConfig, badgeRadiusMap } from \"./constants\";\nimport { Badge } from \"@/components/badge\";\nimport ChevronDownIcon from \"@/components/icons/ChevronDownIcon\";\nimport CloseIcon from \"@/components/icons/CloseIcon\";\nimport Spinner from \"@/components/icons/Spinner\";\n\nexport interface SelectTriggerProps<TData = unknown> {\n id?: string;\n selectedOptions: SelectOptionItem<TData>[];\n isOpen: boolean;\n size?: SelectSize;\n variant?: SelectVariant;\n color?: SelectColor;\n radius?: SelectRadius;\n placeholder?: string;\n disabled?: boolean;\n readOnly?: boolean;\n isInvalid?: boolean;\n multiple?: boolean;\n maxTagCount?: number;\n searchable?: boolean;\n searchPlacement?: SelectSearchPlacement;\n searchValue?: string;\n onSearchChange?: (val: string) => void;\n onRemoveTag?: (option: SelectOptionItem<TData>) => void;\n onClear?: (e: React.MouseEvent) => void;\n clearable?: boolean;\n loading?: boolean;\n isLoading?: boolean;\n startContent?: ReactNode;\n endContent?: ReactNode;\n renderValue?: (selected: SelectOptionItem<TData> | SelectOptionItem<TData>[]) => ReactNode;\n triggerRef: (node: HTMLElement | null) => void;\n getReferenceProps: (userProps?: Record<string, unknown>) => Record<string, unknown>;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n className?: string;\n}\n\nexport function SelectTrigger<TData = unknown>({\n id,\n selectedOptions,\n isOpen,\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n radius = \"md\",\n placeholder = \"Chọn...\",\n disabled = false,\n readOnly = false,\n isInvalid = false,\n multiple = false,\n maxTagCount,\n searchable = false,\n searchPlacement = \"trigger\",\n searchValue = \"\",\n onSearchChange,\n onRemoveTag,\n onClear,\n clearable = false,\n loading: loadingProp = false,\n isLoading: isLoadingProp,\n startContent,\n endContent,\n renderValue,\n triggerRef,\n getReferenceProps,\n onKeyDown,\n className = \"\",\n}: SelectTriggerProps<TData>) {\n const loading = Boolean(isLoadingProp ?? loadingProp);\n const inputRef = useRef<HTMLInputElement>(null);\n const currentSize = sizeConfig[size] || sizeConfig.md;\n const roundedClass = radiusConfig[radius] || radiusConfig.md;\n const badgeRadius = badgeRadiusMap[radius] || \"md\";\n\n const hasError = Boolean(isInvalid);\n const activeColor: SelectColor = hasError ? \"error\" : color;\n\n const variantStyle =\n variant === \"other\" ? \"\" : variantColorConfig[variant]?.[activeColor] || variantColorConfig.outline.primary;\n\n const isTriggerSearchable = searchable && (searchPlacement === \"trigger\" || searchPlacement === \"both\");\n\n const hasSelection = selectedOptions.length > 0;\n const showClear = clearable && (hasSelection || searchValue.length > 0) && !disabled && !readOnly;\n\n // Xử lý maxTagCount\n const visibleTags =\n multiple && maxTagCount && maxTagCount > 0 ? selectedOptions.slice(0, maxTagCount) : selectedOptions;\n const hiddenTagCount =\n multiple && maxTagCount && maxTagCount > 0 ? Math.max(0, selectedOptions.length - maxTagCount) : 0;\n\n const handleContainerClick = () => {\n if (!disabled && !readOnly && !loading && isTriggerSearchable) {\n inputRef.current?.focus();\n }\n };\n\n const renderContent = () => {\n // Custom renderValue\n if (renderValue && hasSelection) {\n return (\n <div className=\"flex-1 min-w-0 truncate text-neutral-900\">\n {renderValue(multiple ? selectedOptions : selectedOptions[0]!)}\n </div>\n );\n }\n\n if (multiple) {\n return (\n <div className=\"flex flex-wrap items-center gap-1 flex-1 min-w-0\">\n {visibleTags.map((opt) => (\n <Badge\n key={String(opt.value)}\n size={currentSize.badgeSize}\n variant=\"soft\"\n color={color}\n radius={badgeRadius}\n onDelete={!disabled && !readOnly && !loading && onRemoveTag ? () => onRemoveTag(opt) : undefined}\n className=\"max-w-full truncate\"\n >\n <span className=\"truncate\">{opt.label}</span>\n </Badge>\n ))}\n\n {hiddenTagCount > 0 && (\n <Badge size={currentSize.badgeSize} variant=\"soft\" color=\"neutral\" radius={badgeRadius}>\n +{hiddenTagCount}\n </Badge>\n )}\n\n {isTriggerSearchable && !disabled && !readOnly && !loading ? (\n <input\n ref={inputRef}\n type=\"text\"\n aria-label=\"Search\"\n value={searchValue}\n placeholder={hasSelection ? \"\" : placeholder}\n onChange={(e) => onSearchChange?.(e.target.value)}\n onKeyDown={onKeyDown}\n className={`bg-transparent outline-none border-none p-0 flex-1 min-w-15 text-neutral-900 placeholder:text-neutral-400 ${currentSize.input}`}\n />\n ) : !hasSelection ? (\n <span className=\"text-neutral-400 truncate\">{placeholder}</span>\n ) : null}\n </div>\n );\n }\n\n // Single Select\n const singleOption = selectedOptions[0];\n\n if (isTriggerSearchable && !disabled && !readOnly && !loading) {\n return (\n <div className=\"relative flex-1 min-w-0 flex items-center\">\n <input\n ref={inputRef}\n type=\"text\"\n aria-label=\"Search\"\n value={searchValue}\n placeholder={singleOption ? singleOption.label : placeholder}\n onChange={(e) => onSearchChange?.(e.target.value)}\n onKeyDown={onKeyDown}\n className={`w-full bg-transparent outline-none border-none p-0 text-neutral-900 ${\n !searchValue && singleOption\n ? \"placeholder:text-neutral-900 placeholder:font-normal\"\n : \"placeholder:text-neutral-400\"\n } ${currentSize.input}`}\n />\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 min-w-0 truncate\">\n {singleOption ? (\n <span className=\"text-neutral-900\">{singleOption.label}</span>\n ) : (\n <span className=\"text-neutral-400\">{placeholder}</span>\n )}\n </div>\n );\n };\n\n const statusStyles = disabled ? \"opacity-60 cursor-not-allowed bg-neutral-100 pointer-events-none\" : \"cursor-pointer\";\n\n return (\n <div\n ref={triggerRef}\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-controls={id ? `${id}-listbox` : undefined}\n tabIndex={disabled ? -1 : 0}\n onClick={handleContainerClick}\n aria-busy={loading}\n aria-disabled={disabled || loading}\n {...getReferenceProps({\n id,\n className: `group relative flex items-center justify-between transition-all duration-150 ease-in-out border-2 select-none ${roundedClass} ${\n currentSize.trigger\n } ${currentSize.gap} ${variantStyle} ${statusStyles} ${className}`,\n \"aria-expanded\": isOpen,\n \"aria-haspopup\": \"listbox\",\n })}\n >\n {startContent && <span className=\"shrink-0 inline-flex items-center text-neutral-400\">{startContent}</span>}\n\n {renderContent()}\n\n <div className=\"shrink-0 flex items-center gap-1.5 ml-1 text-neutral-400\">\n {loading && <Spinner className={`${currentSize.icon} animate-spin text-current`} />}\n\n {showClear && !loading && (\n <button\n type=\"button\"\n aria-label=\"Clear selection\"\n onClick={(e) => {\n e.stopPropagation();\n onClear?.(e);\n }}\n className=\"hover:text-neutral-600 transition-colors p-0.5 rounded-full hover:bg-neutral-100\"\n >\n <CloseIcon className=\"size-3.5\" />\n </button>\n )}\n\n {endContent}\n\n <span className={`transition-transform duration-200 ${isOpen ? \"rotate-180\" : \"\"}`} aria-hidden=\"true\">\n <ChevronDownIcon className={currentSize.icon} />\n </span>\n </div>\n </div>\n );\n}\n\nexport default SelectTrigger;\n","import React, { CSSProperties, ReactNode } from \"react\";\nimport { FloatingPortal } from \"@floating-ui/react\";\nimport {\n SelectOptionItem,\n SelectSize,\n SelectColor,\n SelectRadius,\n SelectFilterField,\n SelectFilterLayout,\n} from \"./types\";\n\nimport SelectOption from \"./SelectOption\";\nimport SelectMenuFilter from \"./SelectMenuFilter\";\nimport Empty from \"@/components/empty/Empty\";\nimport { EmptyProps } from \"@/components/empty/types\";\nimport Spinner from \"@/components/icons/Spinner\";\nimport { DEFAULT_Z_INDEX } from \"@/constants\";\n\nexport interface SelectMenuProps<TData = unknown, TFilters extends Record<string, unknown> = Record<string, unknown>> {\n isOpen: boolean;\n options: SelectOptionItem<TData>[];\n selectedValues: (string | number)[];\n activeIndex: number | null;\n size?: SelectSize;\n color?: SelectColor;\n radius?: SelectRadius;\n loading?: boolean;\n portal?: boolean;\n maxMenuHeight?: number | string;\n emptyText?: ReactNode;\n emptyProps?: Partial<EmptyProps>;\n menuHeader?: ReactNode;\n menuFooter?: ReactNode;\n menuFilters?: SelectFilterField<unknown>[];\n menuFilterValues?: Partial<TFilters>;\n menuFilterLayout?: SelectFilterLayout;\n menuFilterGridCols?: number;\n showResetFilters?: boolean;\n resetFiltersText?: ReactNode;\n onMenuFilterChange?: (name: string, value: unknown) => void;\n onResetFilters?: () => void;\n renderOption?: (option: SelectOptionItem<TData>, state: { selected: boolean; active: boolean }) => ReactNode;\n onSelectOption: (option: SelectOptionItem<TData>) => void;\n onOptionMouseEnter: (index: number) => void;\n floatingStyles: CSSProperties;\n floatingRef: (node: HTMLElement | null) => void;\n getFloatingProps: (userProps?: Record<string, unknown>) => Record<string, unknown>;\n listElementsRef: React.RefObject<(HTMLElement | null)[]>;\n className?: string;\n}\n\nconst DEFAULT_MENU_FILTER_VALUES: Record<string, unknown> = {};\n\nexport function SelectMenu<TData = unknown, TFilters extends Record<string, unknown> = Record<string, unknown>>({\n isOpen,\n options,\n selectedValues,\n activeIndex,\n size = \"md\",\n color = \"primary\",\n radius = \"md\",\n loading = false,\n portal = true,\n maxMenuHeight = 280,\n emptyText,\n emptyProps,\n menuHeader,\n menuFooter,\n menuFilters,\n menuFilterValues = DEFAULT_MENU_FILTER_VALUES as Partial<TFilters>,\n menuFilterLayout = \"vertical\",\n menuFilterGridCols = 2,\n showResetFilters = true,\n resetFiltersText,\n onMenuFilterChange,\n onResetFilters,\n renderOption,\n onSelectOption,\n onOptionMouseEnter,\n floatingStyles,\n floatingRef,\n getFloatingProps,\n listElementsRef,\n className = \"\",\n}: SelectMenuProps<TData, TFilters>) {\n if (!isOpen) return null;\n\n const menuRadiusClass =\n radius === \"none\" ? \"rounded-none\" : size === \"lg\" || size === \"xl\" ? \"rounded-xl\" : \"rounded-lg\";\n\n const menuContent = (\n <div\n ref={floatingRef}\n style={{\n ...floatingStyles,\n zIndex: DEFAULT_Z_INDEX.SELECT,\n }}\n {...getFloatingProps({\n className: `flex flex-col bg-neutral-white border-2 border-neutral-200 shadow-xl overflow-hidden focus:outline-none min-w-[200px] ${menuRadiusClass} ${className}`,\n })}\n >\n {/* Custom Header */}\n {menuHeader}\n\n {/* Multi-field Filter Form */}\n {menuFilters && menuFilters.length > 0 && onMenuFilterChange && (\n <SelectMenuFilter\n filters={menuFilters}\n values={menuFilterValues}\n onChange={onMenuFilterChange}\n onReset={onResetFilters}\n layout={menuFilterLayout}\n gridCols={menuFilterGridCols}\n showReset={showResetFilters}\n resetText={resetFiltersText}\n color={color}\n radius={radius}\n />\n )}\n\n {/* Options List / Empty / Loading */}\n <div\n role=\"listbox\"\n tabIndex={-1}\n style={{\n maxHeight: typeof maxMenuHeight === \"number\" ? `${maxMenuHeight}px` : maxMenuHeight,\n }}\n className={`p-1 overflow-y-auto overflow-x-hidden space-y-0.5 transition-opacity duration-150 ui-scrollbar ${\n loading ? \"opacity-75\" : \"opacity-100\"\n }`}\n >\n {options.length === 0 ? (\n loading ? (\n <div className=\"flex items-center justify-center py-6 gap-2 text-zinc-500 dark:text-zinc-400 text-sm\">\n <Spinner className=\"size-4 animate-spin text-current\" />\n <span>Loading...</span>\n </div>\n ) : (\n <div className=\"py-4 px-2\">\n <Empty\n size=\"sm\"\n image=\"search\"\n description={emptyText || \"No data found\"}\n className=\"py-2\"\n {...emptyProps}\n />\n </div>\n )\n ) : (\n (() => {\n const selectedValuesSet = new Set(selectedValues);\n return options.map((option, index) => {\n const isSelected = selectedValuesSet.has(option.value);\n const isActive = activeIndex === index;\n\n return (\n <SelectOption\n key={String(option.value)}\n ref={(node) => {\n listElementsRef.current[index] = node;\n }}\n option={option}\n isSelected={isSelected}\n isActive={isActive}\n size={size}\n color={color}\n radius={radius}\n disabled={option.disabled}\n renderOption={renderOption}\n onClick={() => onSelectOption(option)}\n onMouseEnter={() => onOptionMouseEnter(index)}\n />\n );\n });\n })()\n )}\n </div>\n\n {/* Custom Footer */}\n {menuFooter}\n </div>\n );\n\n if (portal) {\n return <FloatingPortal>{menuContent}</FloatingPortal>;\n }\n\n return menuContent;\n}\n\nexport default SelectMenu;\n","import { ReactNode } from \"react\";\nimport { SelectOptionItem, SelectSize, SelectColor, SelectRadius } from \"./types\";\nimport { sizeConfig, optionSelectedColorConfig, optionActiveColorConfig } from \"./constants\";\n\nimport CheckIcon from \"@/components/icons/CheckIcon\";\n\nexport interface SelectOptionProps<TData = unknown> {\n option: SelectOptionItem<TData>;\n isSelected: boolean;\n isActive: boolean;\n size?: SelectSize;\n color?: SelectColor;\n radius?: SelectRadius;\n disabled?: boolean;\n renderOption?: (option: SelectOptionItem<TData>, state: { selected: boolean; active: boolean }) => ReactNode;\n onClick?: () => void;\n onMouseEnter?: () => void;\n ref?: (node: HTMLElement | null) => void;\n}\n\nexport function SelectOption<TData = unknown>({\n option,\n isSelected,\n isActive,\n size = \"md\",\n color = \"primary\",\n radius = \"md\",\n disabled = false,\n renderOption,\n onClick,\n onMouseEnter,\n ref,\n}: SelectOptionProps<TData>) {\n const currentSize = sizeConfig[size] || sizeConfig.md;\n const roundedClass =\n radius === \"none\" ? \"rounded-none\" : size === \"lg\" || size === \"xl\" ? \"rounded-lg\" : \"rounded-md\";\n const isDisabled = disabled || option.disabled;\n\n if (renderOption) {\n return (\n <div\n ref={ref}\n role=\"option\"\n tabIndex={-1}\n aria-selected={isSelected}\n aria-disabled={isDisabled}\n data-active={isActive}\n data-selected={isSelected}\n data-value={option.value}\n className={`cursor-pointer select-none transition-colors duration-100 ${\n isDisabled ? \"opacity-50 cursor-not-allowed pointer-events-none\" : \"\"\n }`}\n onClick={isDisabled ? undefined : onClick}\n onMouseEnter={isDisabled ? undefined : onMouseEnter}\n >\n {renderOption(option, { selected: isSelected, active: isActive })}\n </div>\n );\n }\n\n const selectedClasses = isSelected\n ? optionSelectedColorConfig[color] || optionSelectedColorConfig.primary\n : \"text-neutral-800 hover:bg-neutral-100\";\n\n const activeClasses =\n isActive && !isSelected ? optionActiveColorConfig[color] || optionActiveColorConfig.primary : \"\";\n\n return (\n <div\n ref={ref}\n role=\"option\"\n tabIndex={-1}\n aria-selected={isSelected}\n aria-disabled={isDisabled}\n data-active={isActive}\n data-selected={isSelected}\n data-value={option.value}\n className={`group flex items-center justify-between gap-2 select-none cursor-pointer transition-colors duration-100 ${roundedClass} ${currentSize.option} ${selectedClasses} ${activeClasses} ${\n isDisabled ? \"opacity-40 cursor-not-allowed pointer-events-none\" : \"\"\n }`}\n onClick={isDisabled ? undefined : onClick}\n onMouseEnter={isDisabled ? undefined : onMouseEnter}\n >\n <div className=\"flex items-center gap-2 min-w-0 flex-1\">\n {option.icon && <span className=\"shrink-0 inline-flex items-center text-neutral-400\">{option.icon}</span>}\n <div className=\"flex flex-col min-w-0 flex-1\">\n <span className=\"truncate leading-normal font-normal\">{option.label}</span>\n {option.description && (\n <span className=\"text-[11px] text-neutral-500 truncate font-normal\">{option.description}</span>\n )}\n </div>\n </div>\n\n {isSelected && (\n <span className=\"shrink-0 flex items-center justify-center text-current\" aria-hidden=\"true\">\n <CheckIcon className=\"size-3.5\" />\n </span>\n )}\n </div>\n );\n}\n\nexport default SelectOption;\n","import React, { ReactNode } from \"react\";\nimport { SelectFilterField, SelectFilterLayout, SelectColor, SelectRadius } from \"./types\";\nimport { Input, NumberInput } from \"@/components/input\";\nimport { DatePicker } from \"@/components/datepicker\";\nimport { DateRangePicker } from \"@/components/daterangepicker\";\nimport { Checkbox, CheckboxGroup } from \"@/components/checkbox\";\nimport { Button } from \"@/components/button\";\n\nexport interface SelectMenuFilterProps<TFilters extends Record<string, unknown> = Record<string, unknown>> {\n filters: SelectFilterField<unknown>[];\n values: Partial<TFilters>;\n onChange: (name: string, value: unknown) => void;\n onReset?: () => void;\n layout?: SelectFilterLayout;\n gridCols?: number;\n showReset?: boolean;\n resetText?: ReactNode;\n color?: SelectColor;\n radius?: SelectRadius;\n}\n\nexport function SelectMenuFilter<TFilters extends Record<string, unknown> = Record<string, unknown>>({\n filters,\n values,\n onChange,\n onReset,\n layout = \"vertical\",\n gridCols = 2,\n showReset = true,\n resetText = \"Đặt lại bộ lọc\",\n color = \"primary\",\n radius = \"md\",\n}: SelectMenuFilterProps<TFilters>) {\n if (!filters || filters.length === 0) return null;\n\n const renderField = (field: SelectFilterField<unknown>) => {\n const currentValue = values[field.name as keyof TFilters] ?? field.defaultValue;\n\n if (field.type === \"custom\") {\n return (\n field.render?.({\n value: currentValue,\n onChange: (val) => onChange(field.name, val),\n }) ?? null\n );\n }\n\n switch (field.type) {\n case \"string\":\n case \"text\":\n return (\n <Input\n size=\"sm\"\n color={color}\n radius={radius}\n label={field.label}\n placeholder={field.placeholder || \"Nhập để tìm...\"}\n value={(currentValue as string) || \"\"}\n onChange={(e) => onChange(field.name, e.target.value)}\n {...(field.props || {})}\n />\n );\n\n case \"number\":\n return (\n <Input\n size=\"sm\"\n type=\"number\"\n color={color}\n radius={radius}\n label={field.label}\n placeholder={field.placeholder || \"Nhập số...\"}\n value={(currentValue as number) || \"\"}\n onChange={(e) => onChange(field.name, Number(e.target.value))}\n {...(field.props || {})}\n />\n );\n\n case \"date\":\n return (\n <DatePicker\n size=\"sm\"\n color={color}\n radius={radius}\n label={field.label}\n placeholder={field.placeholder || \"Chọn ngày\"}\n value={currentValue as Date | null | undefined}\n onChange={(d) => onChange(field.name, d)}\n {...(field.props || {})}\n />\n );\n\n case \"date-range\":\n return (\n <DateRangePicker\n size=\"sm\"\n color={color}\n radius={radius}\n label={field.label}\n placeholder={field.placeholder || \"Chọn khoảng ngày\"}\n value={(currentValue as [Date | null, Date | null]) || [null, null]}\n onChange={(range) => onChange(field.name, range)}\n {...(field.props || {})}\n />\n );\n\n case \"checkbox-group\":\n return (\n <div className=\"flex flex-col gap-1.5\">\n {field.label && <span className=\"text-xs font-medium text-zinc-700 dark:text-zinc-300\">{field.label}</span>}\n <CheckboxGroup\n size=\"sm\"\n color={color}\n value={(currentValue as string[]) || []}\n onChange={(val) => onChange(field.name, val)}\n {...(field.props || {})}\n >\n <div className=\"flex flex-wrap gap-2\">\n {field.options?.map((opt) => (\n <Checkbox\n key={String(opt.value)}\n value={String(opt.value)}\n disabled={opt.disabled}\n size=\"sm\"\n color={color}\n label={opt.label}\n />\n ))}\n </div>\n </CheckboxGroup>\n </div>\n );\n\n default:\n return null;\n }\n };\n\n const gridColClass =\n gridCols === 1\n ? \"grid-cols-1\"\n : gridCols === 3\n ? \"grid-cols-1 sm:grid-cols-3\"\n : gridCols === 4\n ? \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-4\"\n : \"grid-cols-1 sm:grid-cols-2\";\n\n return (\n <div className=\"p-2.5 border-b border-neutral-200 bg-neutral-50/70 rounded-t-lg\">\n <div className={layout === \"grid\" ? `grid ${gridColClass} gap-2.5 items-end` : \"flex flex-col gap-2.5\"}>\n {filters.map((field) => {\n const colSpanClass = field.colSpan ? `col-span-${field.colSpan}` : \"\";\n return (\n <div key={field.name} className={`w-full ${colSpanClass}`}>\n {renderField(field)}\n </div>\n );\n })}\n </div>\n\n {showReset && onReset && (\n <div className=\"flex justify-end mt-2 pt-2 border-t border-neutral-200\">\n <Button\n size=\"xs\"\n variant=\"ghost\"\n onClick={onReset}\n className=\"text-[11px] h-6 px-2 text-neutral-500 hover:text-neutral-900\"\n >\n {resetText}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nexport default SelectMenuFilter;\n","import { DEFAULT_DEBOUNCE_DELAY } from \"@/constants\";\nimport { useRef, useEffect, useCallback } from \"react\";\n\n/**\n * Custom hook to debounce a callback function by a given delay in milliseconds.\n * Ensures the callback always sees the latest props/state without triggering extra re-renders.\n *\n * @param callback The function to debounce\n * @param delay Delay in milliseconds (default: 300ms)\n * @returns A memoized debounced function with cancel method\n */\nexport function useDebouncedCallback<Args extends unknown[], R = void>(\n callback: (...args: Args) => R,\n delay: number = DEFAULT_DEBOUNCE_DELAY\n): {\n debounced: (...args: Args) => void;\n cancel: () => void;\n} {\n const callbackRef = useRef(callback);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n const cancel = useCallback(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n useEffect(() => {\n return cancel;\n }, [cancel]);\n\n const debounced = useCallback(\n (...args: Args) => {\n cancel();\n\n timerRef.current = setTimeout(() => {\n callbackRef.current(...args);\n }, delay);\n },\n [cancel, delay]\n );\n\n return {\n debounced,\n cancel,\n };\n}\n\nexport default useDebouncedCallback;\n","import { DEFAULT_DEBOUNCE_DELAY } from \"@/constants\";\nimport { useEffect, useState } from \"react\";\n\n/**\n * Custom hook to debounce a value by a given delay in milliseconds.\n *\n * @param value The value to debounce\n * @param delay Delay in milliseconds (default: 300ms)\n * @returns The debounced value\n */\nexport function useDebounce<T>(value: T, delay: number = DEFAULT_DEBOUNCE_DELAY): T {\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(timer);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n\nexport default useDebounce;\n","import { ChangeEvent, DragEvent, useEffect, useId, useRef, useState } from \"react\";\nimport Button from \"../button/Button\";\nimport UploadIcon from \"../icons/UploadIcon\";\nimport { UploadFileItem, UploadImageProps } from \"./types\";\nimport { uploadImageSizeConfig } from \"./constants\";\nimport { createFileItem, normalizeInitialValues, validateFile } from \"./utils\";\nimport { FileContainer } from \"../file-preview\";\nimport UploadImageDropzone from \"./UploadImageDropzone\";\nimport UploadImageList from \"./UploadImageList\";\n\nfunction handleDragOver(e: DragEvent<HTMLDivElement>) {\n e.preventDefault();\n e.stopPropagation();\n}\n\nexport default function UploadImage({\n value,\n defaultValue,\n onChange,\n onRemove,\n onPreview,\n multiple = false,\n maxCount,\n maxSize,\n accept = \"image/*\",\n beforeUpload,\n viewMode = \"dropzone\",\n shape = \"rectangle\",\n size = \"md\",\n color = \"primary\",\n variant = \"outline\",\n radius,\n label,\n helperText,\n errorMessage,\n isInvalid: isInvalidProp,\n disabled = false,\n readOnly = false,\n isLoading = false,\n dropzoneTitle,\n dropzoneDescription,\n icon,\n buttonText = \"Tải ảnh lên\",\n renderItem,\n className = \"\",\n dropzoneClassName = \"\",\n previewClassName = \"\",\n ariaLabel,\n}: UploadImageProps) {\n const generatedId = useId();\n const inputId = `${generatedId}-input`;\n const helperId = `${generatedId}-helper`;\n const errorId = `${generatedId}-error`;\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // Controlled vs Uncontrolled State\n const [internalItems, setInternalItems] = useState<UploadFileItem[]>(() =>\n normalizeInitialValues(value !== undefined ? value : defaultValue)\n );\n\n useEffect(() => {\n if (value !== undefined) {\n setInternalItems(normalizeInitialValues(value));\n }\n }, [value]);\n\n // Dragging state\n const [isDragging, setIsDragging] = useState(false);\n const dragCounter = useRef(0);\n\n // Internal validation error\n const [validationError, setValidationError] = useState<string | null>(null);\n const [previewItem, setPreviewItem] = useState<UploadFileItem | null>(null);\n\n // Live announcement for Screen Readers\n const [srAnnouncement, setSrAnnouncement] = useState<string>(\"\");\n\n const currentSize = uploadImageSizeConfig[size];\n const isInvalid = Boolean(isInvalidProp || errorMessage || validationError);\n const activeErrorMessage = errorMessage || validationError;\n\n const effectiveMaxCount = maxCount ?? (multiple ? undefined : 1);\n\n const updateItems = (newItems: UploadFileItem[]) => {\n if (value === undefined) {\n setInternalItems(newItems);\n }\n onChange?.(newItems);\n };\n\n const handleTriggerUpload = () => {\n if (disabled || readOnly) return;\n if (fileInputRef.current) {\n fileInputRef.current.value = \"\";\n fileInputRef.current.click();\n }\n };\n\n const processFiles = async (files: FileList | File[]) => {\n if (disabled || readOnly) return;\n setValidationError(null);\n\n const fileArray = Array.from(files);\n if (fileArray.length === 0) return;\n\n // Check count limit\n const currentCount = internalItems.length;\n let allowedFiles = fileArray;\n\n if (effectiveMaxCount !== undefined) {\n if (!multiple) {\n // Single file mode replaces existing\n const firstFile = fileArray[0];\n if (!firstFile) return;\n allowedFiles = [firstFile];\n } else {\n const remainingSlots = effectiveMaxCount - currentCount;\n if (remainingSlots <= 0) {\n const err = `Maximum allowed image count reached (${effectiveMaxCount} images)`;\n setValidationError(err);\n setSrAnnouncement(err);\n return;\n }\n allowedFiles = fileArray.slice(0, remainingSlots);\n }\n }\n\n const processSingleFile = async (file: File): Promise<UploadFileItem | null> => {\n // 1. Validation size & accept\n const validation = validateFile(file, { maxSize, accept });\n if (!validation.isValid) {\n const err = validation.error || \"Invalid file\";\n setValidationError(err);\n setSrAnnouncement(`File upload error: ${err}`);\n return null;\n }\n\n // 2. Custom beforeUpload hook\n if (beforeUpload) {\n try {\n const result = await beforeUpload(file);\n if (result === false || typeof result === \"string\") {\n const err = typeof result === \"string\" ? result : `File ${file.name} was rejected`;\n setValidationError(err);\n setSrAnnouncement(`Lỗi: ${err}`);\n return null;\n }\n } catch (err: any) {\n const errMsg = err?.message || `Không thể xử lý tệp ${file.name}`;\n setValidationError(errMsg);\n setSrAnnouncement(`Lỗi: ${errMsg}`);\n return null;\n }\n }\n\n return createFileItem(file);\n };\n\n const newValidItems: UploadFileItem[] = [];\n\n for (const file of allowedFiles) {\n const item = await processSingleFile(file);\n if (item) {\n newValidItems.push(item);\n }\n }\n\n if (newValidItems.length > 0) {\n const finalItems = !multiple ? newValidItems : [...internalItems, ...newValidItems];\n\n updateItems(finalItems);\n setSrAnnouncement(`Tải lên thành công ${newValidItems.length} hình ảnh. Tổng cộng: ${finalItems.length}.`);\n }\n };\n\n const handleFileInputChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files) {\n processFiles(e.target.files);\n }\n };\n\n const handleDragEnter = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (disabled || readOnly) return;\n dragCounter.current += 1;\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {\n setIsDragging(true);\n }\n };\n\n const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (disabled || readOnly) return;\n dragCounter.current -= 1;\n if (dragCounter.current <= 0) {\n setIsDragging(false);\n dragCounter.current = 0;\n }\n };\n\n const handleDrop = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n dragCounter.current = 0;\n\n if (disabled || readOnly) return;\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n processFiles(e.dataTransfer.files);\n e.dataTransfer.clearData();\n }\n };\n\n const handleRemove = (item: UploadFileItem, index: number) => {\n if (disabled || readOnly) return;\n const newItems = internalItems.filter((_, i) => i !== index);\n updateItems(newItems);\n onRemove?.(item, index);\n setSrAnnouncement(`Đã xóa hình ảnh ${item.name}`);\n };\n\n const handleOpenPreview = (item: UploadFileItem) => {\n if (item.url || item.file) {\n setPreviewItem(item);\n }\n onPreview?.(item);\n };\n\n return (\n <div\n className={`relative flex flex-col w-full ${className}`}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n >\n {/* Hidden File Input */}\n <input\n ref={fileInputRef}\n id={inputId}\n type=\"file\"\n multiple={multiple}\n accept={accept}\n disabled={disabled}\n aria-hidden=\"true\"\n tabIndex={-1}\n className=\"hidden\"\n onChange={handleFileInputChange}\n />\n\n {/* Screen Reader Live Region */}\n <div aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {srAnnouncement}\n </div>\n\n {/* Label */}\n {label && (\n <label htmlFor={inputId} className={`block font-medium text-neutral-800 ${currentSize.labelSize}`}>\n {label}\n </label>\n )}\n\n {/* Content depending on viewMode */}\n <div className=\"flex flex-col gap-3\">\n {viewMode === \"dropzone\" && (\n <>\n <UploadImageDropzone\n size={size}\n color={color}\n variant={variant}\n radius={radius}\n shape={shape}\n disabled={disabled}\n readOnly={readOnly}\n isLoading={isLoading}\n isDragging={isDragging}\n isInvalid={isInvalid}\n dropzoneTitle={dropzoneTitle}\n dropzoneDescription={dropzoneDescription}\n icon={icon}\n onTriggerUpload={handleTriggerUpload}\n className={dropzoneClassName}\n describedById={helperText ? helperId : undefined}\n />\n\n {/* List preview for Dropzone mode when items exist */}\n {internalItems.length > 0 && (\n <UploadImageList\n items={internalItems}\n size={size}\n color={color}\n variant={variant}\n radius={radius ?? \"md\"}\n disabled={disabled}\n readOnly={readOnly}\n maxCount={effectiveMaxCount}\n onRemove={handleRemove}\n onPreview={handleOpenPreview}\n onTriggerUpload={handleTriggerUpload}\n renderItem={renderItem}\n showAddButton={false}\n className={previewClassName}\n />\n )}\n </>\n )}\n\n {viewMode === \"card-grid\" && (\n <UploadImageList\n items={internalItems}\n size={size}\n color={color}\n variant={variant}\n radius={radius ?? \"md\"}\n disabled={disabled}\n readOnly={readOnly}\n maxCount={effectiveMaxCount}\n onRemove={handleRemove}\n onPreview={handleOpenPreview}\n onTriggerUpload={handleTriggerUpload}\n renderItem={renderItem}\n showAddButton={true}\n className={previewClassName}\n />\n )}\n\n {viewMode === \"button\" && (\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center gap-3\">\n <Button\n type=\"button\"\n size={size}\n color={isInvalid ? \"error\" : color === \"neutral\" ? \"secondary\" : color}\n variant={variant === \"other\" ? \"filled\" : variant}\n radius={radius}\n disabled={\n disabled || readOnly || (effectiveMaxCount !== undefined && internalItems.length >= effectiveMaxCount)\n }\n onClick={handleTriggerUpload}\n leftIcon={<UploadIcon width={currentSize.iconSize * 0.5} height={currentSize.iconSize * 0.5} />}\n aria-label={ariaLabel || \"Tải ảnh lên\"}\n >\n {buttonText}\n </Button>\n </div>\n\n {internalItems.length > 0 && (\n <UploadImageList\n items={internalItems}\n size={size}\n color={color}\n variant={variant}\n radius={radius ?? \"md\"}\n disabled={disabled}\n readOnly={readOnly}\n maxCount={effectiveMaxCount}\n onRemove={handleRemove}\n onPreview={handleOpenPreview}\n onTriggerUpload={handleTriggerUpload}\n renderItem={renderItem}\n showAddButton={false}\n className={previewClassName}\n />\n )}\n </div>\n )}\n </div>\n\n {/* Helper text & Error message */}\n {isInvalid && activeErrorMessage ? (\n <p id={errorId} role=\"alert\" className={`font-medium text-error-600 ${currentSize.helperSize}`}>\n {activeErrorMessage}\n </p>\n ) : helperText ? (\n <p id={helperId} className={`text-neutral-500 ${currentSize.helperSize}`}>\n {helperText}\n </p>\n ) : null}\n\n {/* File Preview Modal */}\n {previewItem && (\n <FileContainer\n open={Boolean(previewItem)}\n onClose={() => setPreviewItem(null)}\n file={previewItem.file ?? (previewItem.url ? { url: previewItem.url, name: previewItem.name } : undefined)}\n />\n )}\n </div>\n );\n}\n","import { UploadImageColor, UploadImageRadius, UploadImageSize, UploadImageVariant } from \"./types\";\n\nexport const uploadImageRadiusConfig: Record<UploadImageRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-md\",\n md: \"rounded-lg\",\n lg: \"rounded-xl\",\n xl: \"rounded-2xl\",\n full: \"rounded-full\",\n};\n\nexport const uploadImageDefaultRadiusBySize: Record<UploadImageSize, UploadImageRadius> = {\n xs: \"sm\",\n sm: \"sm\",\n md: \"md\",\n lg: \"lg\",\n xl: \"xl\",\n};\n\nexport const uploadImageSizeConfig: Record<\n UploadImageSize,\n {\n dropzoneHeight: string;\n dropzonePadding: string;\n avatarSize: string;\n thumbnailSize: string;\n iconSize: number;\n titleSize: string;\n descSize: string;\n labelSize: string;\n helperSize: string;\n gap: string;\n }\n> = {\n xs: {\n dropzoneHeight: \"min-h-[80px]\",\n dropzonePadding: \"p-3\",\n avatarSize: \"size-12\",\n thumbnailSize: \"size-12\",\n iconSize: 24,\n titleSize: \"text-[11px]\",\n descSize: \"text-[10px]\",\n labelSize: \"text-[11px] mb-1\",\n helperSize: \"text-[9px] mt-0.5\",\n gap: \"gap-1.5\",\n },\n sm: {\n dropzoneHeight: \"min-h-[100px]\",\n dropzonePadding: \"p-4\",\n avatarSize: \"size-16\",\n thumbnailSize: \"size-16\",\n iconSize: 32,\n titleSize: \"text-xs\",\n descSize: \"text-[11px]\",\n labelSize: \"text-xs mb-1\",\n helperSize: \"text-[10px] mt-0.5\",\n gap: \"gap-2\",\n },\n md: {\n dropzoneHeight: \"min-h-[130px]\",\n dropzonePadding: \"p-5\",\n avatarSize: \"size-24\",\n thumbnailSize: \"size-20\",\n iconSize: 44,\n titleSize: \"text-sm\",\n descSize: \"text-xs\",\n labelSize: \"text-sm mb-1.5\",\n helperSize: \"text-[11px] mt-1\",\n gap: \"gap-3\",\n },\n lg: {\n dropzoneHeight: \"min-h-[160px]\",\n dropzonePadding: \"p-6\",\n avatarSize: \"size-28\",\n thumbnailSize: \"size-24\",\n iconSize: 54,\n titleSize: \"text-base\",\n descSize: \"text-xs\",\n labelSize: \"text-base mb-1.5\",\n helperSize: \"text-xs mt-1\",\n gap: \"gap-3.5\",\n },\n xl: {\n dropzoneHeight: \"min-h-[200px]\",\n dropzonePadding: \"p-8\",\n avatarSize: \"size-36\",\n thumbnailSize: \"size-28\",\n iconSize: 64,\n titleSize: \"text-lg\",\n descSize: \"text-sm\",\n labelSize: \"text-lg mb-2\",\n helperSize: \"text-sm mt-1\",\n gap: \"gap-4\",\n },\n};\n\nexport const uploadImageVariantColorConfig: Record<\n Exclude<UploadImageVariant, \"other\">,\n Record<\n UploadImageColor,\n {\n idle: string;\n active: string;\n iconColor: string;\n titleHover: string;\n }\n >\n> = {\n // 1. OUTLINE\n outline: {\n primary: {\n idle: \"bg-neutral-white border-primary-400 hover:border-primary-500 text-neutral-700\",\n active: \"bg-primary-50/50 border-primary-500 ring-2 ring-primary-500/20 text-primary-900\",\n iconColor: \"text-primary-500\",\n titleHover: \"group-hover:text-primary-600\",\n },\n secondary: {\n idle: \"bg-neutral-white border-secondary-400 hover:border-secondary-500 text-neutral-700\",\n active: \"bg-secondary-50/50 border-secondary-500 ring-2 ring-secondary-500/20 text-secondary-900\",\n iconColor: \"text-secondary-500\",\n titleHover: \"group-hover:text-secondary-600\",\n },\n neutral: {\n idle: \"bg-neutral-white border-neutral-300 hover:border-neutral-400 text-neutral-700\",\n active: \"bg-neutral-100/70 border-neutral-500 ring-2 ring-neutral-500/20 text-neutral-900\",\n iconColor: \"text-neutral-500\",\n titleHover: \"group-hover:text-neutral-900\",\n },\n error: {\n idle: \"bg-neutral-white border-error-500 hover:border-error-600 text-neutral-700\",\n active: \"bg-error-50/50 border-error-500 ring-2 ring-error-500/20 text-error-900\",\n iconColor: \"text-error-500\",\n titleHover: \"group-hover:text-error-600\",\n },\n success: {\n idle: \"bg-neutral-white border-success-400 hover:border-success-500 text-neutral-700\",\n active: \"bg-success-50/50 border-success-500 ring-2 ring-success-500/20 text-success-900\",\n iconColor: \"text-success-500\",\n titleHover: \"group-hover:text-success-600\",\n },\n warning: {\n idle: \"bg-neutral-white border-warning-400 hover:border-warning-500 text-neutral-700\",\n active: \"bg-warning-50/50 border-warning-500 ring-2 ring-warning-500/20 text-warning-900\",\n iconColor: \"text-warning-500\",\n titleHover: \"group-hover:text-warning-600\",\n },\n info: {\n idle: \"bg-neutral-white border-info-400 hover:border-info-500 text-neutral-700\",\n active: \"bg-info-50/50 border-info-500 ring-2 ring-info-500/20 text-info-900\",\n iconColor: \"text-info-500\",\n titleHover: \"group-hover:text-info-600\",\n },\n },\n\n // 2. FILLED\n filled: {\n primary: {\n idle: \"bg-primary-50/60 border-primary-200 hover:bg-primary-100/60 hover:border-primary-400 text-primary-900\",\n active: \"bg-primary-100 border-primary-500 ring-2 ring-primary-500/20 text-primary-950\",\n iconColor: \"text-primary-600\",\n titleHover: \"group-hover:text-primary-700\",\n },\n secondary: {\n idle: \"bg-secondary-50/60 border-secondary-200 hover:bg-secondary-100/60 hover:border-secondary-400 text-secondary-900\",\n active: \"bg-secondary-100 border-secondary-500 ring-2 ring-secondary-500/20 text-secondary-950\",\n iconColor: \"text-secondary-600\",\n titleHover: \"group-hover:text-secondary-700\",\n },\n neutral: {\n idle: \"bg-neutral-100/70 border-neutral-200 hover:bg-neutral-200/70 hover:border-neutral-400 text-neutral-800\",\n active: \"bg-neutral-200 border-neutral-500 ring-2 ring-neutral-500/20 text-neutral-900\",\n iconColor: \"text-neutral-600\",\n titleHover: \"group-hover:text-neutral-950\",\n },\n error: {\n idle: \"bg-error-50/60 border-error-200 hover:bg-error-100/60 hover:border-error-400 text-error-900\",\n active: \"bg-error-100 border-error-500 ring-2 ring-error-500/20 text-error-950\",\n iconColor: \"text-error-600\",\n titleHover: \"group-hover:text-error-700\",\n },\n success: {\n idle: \"bg-success-50/60 border-success-200 hover:bg-success-100/60 hover:border-success-400 text-success-900\",\n active: \"bg-success-100 border-success-500 ring-2 ring-success-500/20 text-success-950\",\n iconColor: \"text-success-600\",\n titleHover: \"group-hover:text-success-700\",\n },\n warning: {\n idle: \"bg-warning-50/60 border-warning-200 hover:bg-warning-100/60 hover:border-warning-400 text-warning-900\",\n active: \"bg-warning-100 border-warning-500 ring-2 ring-warning-500/20 text-warning-950\",\n iconColor: \"text-warning-600\",\n titleHover: \"group-hover:text-warning-700\",\n },\n info: {\n idle: \"bg-info-50/60 border-info-200 hover:bg-info-100/60 hover:border-info-400 text-info-900\",\n active: \"bg-info-100 border-info-500 ring-2 ring-info-500/20 text-info-950\",\n iconColor: \"text-info-600\",\n titleHover: \"group-hover:text-info-700\",\n },\n },\n\n // 3. GHOST\n ghost: {\n primary: {\n idle: \"bg-transparent border-transparent hover:bg-primary-50/60 hover:border-primary-300 text-neutral-700\",\n active: \"bg-primary-50 border-primary-500 ring-2 ring-primary-500/20 text-primary-900\",\n iconColor: \"text-primary-500\",\n titleHover: \"group-hover:text-primary-600\",\n },\n secondary: {\n idle: \"bg-transparent border-transparent hover:bg-secondary-50/60 hover:border-secondary-300 text-neutral-700\",\n active: \"bg-secondary-50 border-secondary-500 ring-2 ring-secondary-500/20 text-secondary-900\",\n iconColor: \"text-secondary-500\",\n titleHover: \"group-hover:text-secondary-600\",\n },\n neutral: {\n idle: \"bg-transparent border-transparent hover:bg-neutral-100 hover:border-neutral-300 text-neutral-700\",\n active: \"bg-neutral-100 border-neutral-500 ring-2 ring-neutral-500/20 text-neutral-900\",\n iconColor: \"text-neutral-500\",\n titleHover: \"group-hover:text-neutral-900\",\n },\n error: {\n idle: \"bg-transparent border-transparent hover:bg-error-50/60 hover:border-error-300 text-neutral-700\",\n active: \"bg-error-50 border-error-500 ring-2 ring-error-500/20 text-error-900\",\n iconColor: \"text-error-500\",\n titleHover: \"group-hover:text-error-600\",\n },\n success: {\n idle: \"bg-transparent border-transparent hover:bg-success-50/60 hover:border-success-300 text-neutral-700\",\n active: \"bg-success-50 border-success-500 ring-2 ring-success-500/20 text-success-900\",\n iconColor: \"text-success-500\",\n titleHover: \"group-hover:text-success-600\",\n },\n warning: {\n idle: \"bg-transparent border-transparent hover:bg-warning-50/60 hover:border-warning-300 text-neutral-700\",\n active: \"bg-warning-50 border-warning-500 ring-2 ring-warning-500/20 text-warning-900\",\n iconColor: \"text-warning-500\",\n titleHover: \"group-hover:text-warning-600\",\n },\n info: {\n idle: \"bg-transparent border-transparent hover:bg-info-50/60 hover:border-info-300 text-neutral-700\",\n active: \"bg-info-50 border-info-500 ring-2 ring-info-500/20 text-info-900\",\n iconColor: \"text-info-500\",\n titleHover: \"group-hover:text-info-600\",\n },\n },\n};\n","import { UploadFileItem } from \"./types\";\n\nexport function generateId(): string {\n return \"upload_\" + Math.random().toString(36).substring(2, 9) + \"_\" + Date.now();\n}\n\nexport function formatBytes(bytes: number, decimals: number = 1): string {\n if (!+bytes) return \"0 B\";\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\nexport function normalizeInitialValues(raw?: UploadFileItem[] | UploadFileItem | string[] | string): UploadFileItem[] {\n if (!raw) return [];\n\n if (typeof raw === \"string\") {\n return [\n {\n id: generateId(),\n name: raw.split(\"/\").pop() || \"image.png\",\n url: raw,\n status: \"success\",\n },\n ];\n }\n\n if (Array.isArray(raw)) {\n return raw.map((item) => {\n if (typeof item === \"string\") {\n return {\n id: generateId(),\n name: item.split(\"/\").pop() || \"image.png\",\n url: item,\n status: \"success\",\n };\n }\n return item;\n });\n }\n\n return [raw];\n}\n\nexport interface ValidateFileOptions {\n maxSize?: number;\n accept?: string;\n}\n\nexport function validateFile(file: File, options?: ValidateFileOptions): { isValid: boolean; error?: string } {\n if (!options) return { isValid: true };\n\n // 1. Check max file size\n if (options.maxSize && file.size > options.maxSize) {\n return {\n isValid: false,\n error: `Kích thước tệp vượt quá giới hạn tối đa (${formatBytes(options.maxSize)})`,\n };\n }\n\n // 2. Check accept format\n if (options.accept && options.accept.trim() !== \"*\") {\n const acceptedTypes = options.accept.split(\",\").map((t) => t.trim().toLowerCase());\n\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n\n const isMatch = acceptedTypes.some((type) => {\n if (type.startsWith(\".\")) {\n return fileName.endsWith(type);\n }\n if (type.endsWith(\"/*\")) {\n const baseType = type.split(\"/\")[0];\n return fileType.startsWith(baseType + \"/\");\n }\n return fileType === type;\n });\n\n if (!isMatch) {\n return {\n isValid: false,\n error: `Định dạng tệp không hợp lệ. Các định dạng được hỗ trợ: ${options.accept}`,\n };\n }\n }\n\n return { isValid: true };\n}\n\nexport function createFileItem(file: File, url?: string): UploadFileItem {\n return {\n id: generateId(),\n name: file.name,\n size: file.size,\n type: file.type,\n url,\n file,\n status: \"success\",\n };\n}\n\nexport function revokeFileItem(item: UploadFileItem) {\n if (item?.url && item.url.startsWith(\"blob:\")) {\n try {\n URL.revokeObjectURL(item.url);\n } catch {\n // Ignore if revokeObjectURL fails or not supported\n }\n }\n}\n","import { useEffect, useState } from \"react\";\nimport { FilePreviewProps } from \"./types\";\nimport { normalizePreviewFile, downloadFile } from \"./utils\";\nimport { useFileContext } from \"./FileContext\";\nimport ImagePreview from \"./image-preview/ImagePreview\";\nimport DownloadIcon from \"../icons/DownloadIcon\";\n\n/**\n * Component `<FilePreview>`: Nhận file và headerTitle qua useFileContext(),\n * tự động xác định loại file và chọn component hiển thị tương ứng.\n */\nexport default function FilePreview({\n onDownload,\n imageProps,\n className = \"\",\n}: FilePreviewProps) {\n const fileContext = useFileContext();\n const file = fileContext?.file;\n const headerTitle = fileContext?.headerTitle;\n\n const [previewUrl, setPreviewUrl] = useState<string>(\"\");\n\n useEffect(() => {\n if (!file) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setPreviewUrl(\"\");\n return;\n }\n\n if (!(file instanceof File)) {\n const normalized = normalizePreviewFile(file);\n setPreviewUrl(normalized.serverFile?.src || \"\");\n return;\n }\n\n const url = URL.createObjectURL(file);\n setPreviewUrl(url);\n\n return () => {\n URL.revokeObjectURL(url);\n };\n }, [file]);\n\n const normalized = normalizePreviewFile(file);\n const displayName = (typeof headerTitle === \"string\" ? headerTitle : \"\") || normalized.name || \"file\";\n\n const handleDownload = () => {\n if (onDownload && file) {\n onDownload(file);\n }\n if (previewUrl) {\n downloadFile(previewUrl, displayName);\n }\n };\n\n if (normalized.type === \"image\") {\n return (\n <ImagePreview\n src={previewUrl}\n name={displayName}\n {...imageProps}\n />\n );\n }\n\n return (\n <div className={`p-6 text-center ${className}`}>\n <div className=\"w-16 h-16 rounded-2xl bg-neutral-100 flex items-center justify-center mx-auto mb-4 text-primary-600\">\n <DownloadIcon width={32} height={32} />\n </div>\n\n <h3 className=\"text-lg font-semibold text-neutral-900 truncate mb-1\" title={displayName}>\n {headerTitle ?? displayName}\n </h3>\n <p className=\"text-sm text-neutral-500 mb-6\">\n Định dạng file chưa hỗ trợ xem trực tiếp. Bạn có thể tải file về để xem.\n </p>\n\n <button\n type=\"button\"\n onClick={handleDownload}\n className=\"inline-flex items-center justify-center gap-2 w-full py-2.5 px-4 bg-primary-600 hover:bg-primary-500 text-white font-medium rounded-xl transition-colors shadow-md cursor-pointer\"\n >\n <DownloadIcon width={18} height={18} />\n <span>Tải xuống file</span>\n </button>\n </div>\n );\n}\n","export const IMAGE_EXTENSIONS = [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"svg\", \"bmp\", \"ico\", \"tiff\", \"avif\"];\n\nexport const PDF_EXTENSIONS = [\"pdf\"];\n\nexport const VIDEO_EXTENSIONS = [\"mp4\", \"webm\", \"ogg\", \"mov\", \"avi\", \"mkv\"];\n\nexport const AUDIO_EXTENSIONS = [\"mp3\", \"wav\", \"ogg\", \"aac\", \"flac\", \"m4a\"];\n\nexport const DOCUMENT_EXTENSIONS = [\"doc\", \"docx\", \"xls\", \"xlsx\", \"ppt\", \"pptx\", \"txt\", \"csv\"];\n","import { FileType, PreviewFile, ServerFile } from \"./types\";\nimport { IMAGE_EXTENSIONS, PDF_EXTENSIONS, VIDEO_EXTENSIONS, AUDIO_EXTENSIONS, DOCUMENT_EXTENSIONS } from \"./constants\";\n\nexport function getFileName(filenameOrSrc: string = \"\"): string {\n if (!filenameOrSrc) return \"\";\n const cleanPath = filenameOrSrc.split(\"?\")[0]?.split(\"#\")[0] || \"\";\n const fullName = cleanPath.split(\"/\").pop() || cleanPath.split(\"\\\\\").pop() || \"\";\n const lastDotIndex = fullName.lastIndexOf(\".\");\n if (lastDotIndex <= 0) return fullName;\n return fullName.slice(0, lastDotIndex);\n}\n\nexport function getFileExtension(filenameOrSrc: string = \"\"): string {\n const cleanPath = filenameOrSrc.split(\"?\")[0]?.split(\"#\")[0] || \"\";\n const dotIndex = cleanPath.lastIndexOf(\".\");\n if (dotIndex === -1) return \"\";\n return cleanPath.slice(dotIndex + 1).toLowerCase();\n}\n\nexport function getFileType(filenameOrSrc: string = \"\"): FileType {\n const ext = getFileExtension(filenameOrSrc);\n if (IMAGE_EXTENSIONS.includes(ext)) return \"image\";\n if (PDF_EXTENSIONS.includes(ext)) return \"pdf\";\n if (VIDEO_EXTENSIONS.includes(ext)) return \"video\";\n if (AUDIO_EXTENSIONS.includes(ext)) return \"audio\";\n if (DOCUMENT_EXTENSIONS.includes(ext)) return \"document\";\n\n return \"other\";\n}\n\nexport function normalizePreviewFile(input?: PreviewFile): {\n file: File | undefined;\n serverFile: ServerFile | undefined;\n name: string;\n type: FileType;\n} {\n if (!input) {\n return { name: \"file\", type: \"other\" as FileType, file: undefined, serverFile: undefined };\n }\n\n if (input instanceof File) {\n return {\n name: getFileName(input.name),\n type: getFileType(input.name),\n file: input,\n serverFile: undefined,\n };\n }\n\n return {\n name: input.name ?? getFileName(input?.src),\n type: getFileType(input?.src),\n file: undefined,\n serverFile: input,\n };\n}\n\nexport function downloadFile(src: string, filename?: string): void {\n if (!src) return;\n const link = document.createElement(\"a\");\n link.href = src;\n const cleanPath = src.split(\"?\")[0]?.split(\"#\")[0] || \"\";\n const fallbackFullName = cleanPath.split(\"/\").pop() || cleanPath.split(\"\\\\\").pop() || \"download\";\n link.download = filename || fallbackFullName;\n link.style.display = \"none\";\n document.body.appendChild(link);\n link.click();\n setTimeout(() => {\n try {\n document.body.removeChild(link);\n } catch {\n // Ignore\n }\n }, 100);\n}\n","import { createContext, ReactNode, useContext } from \"react\";\nimport { PreviewFile } from \"./types\";\n\nexport interface FileContextValue {\n file?: PreviewFile;\n headerTitle?: ReactNode;\n}\n\nexport const FileContext = createContext<FileContextValue | null>(null);\n\nexport const useFileContext = () => useContext(FileContext);\n","import React, { useState } from \"react\";\nimport Cropper, { Point } from \"react-easy-crop\";\nimport { ImagePreviewProps, ImageItem } from \"./types\";\nimport ImagePreviewToolbar from \"./ImagePreviewToolbar\";\n\nexport default function ImagePreview({\n src,\n name,\n minZoom = 0.2,\n maxZoom = 5,\n showToolbar = true,\n toolbarProps,\n children,\n}: ImagePreviewProps) {\n const [crop, setCrop] = useState<Point>({ x: 0, y: 0 });\n const [zoom, setZoom] = useState(1);\n const [rotation, setRotation] = useState(0);\n const [isFlipped, setIsFlipped] = useState(false);\n\n const handleZoomIn = () => setZoom((prev) => Math.min(maxZoom, Math.round((prev + 0.25) * 100) / 100));\n const handleZoomOut = () => setZoom((prev) => Math.max(minZoom, Math.round((prev - 0.25) * 100) / 100));\n const handleRotateCw = () => setRotation((prev) => (prev + 90) % 360);\n const handleRotateCcw = () => setRotation((prev) => (prev - 90 + 360) % 360);\n const handleFlipHorizontal = () => setIsFlipped((prev) => !prev);\n const handleReset = () => {\n setCrop({ x: 0, y: 0 });\n setZoom(1);\n setRotation(0);\n setIsFlipped(false);\n };\n\n const currentImage: ImageItem = { src, name };\n\n if (!src) {\n return null;\n }\n\n return (\n <div className=\"flex flex-col w-full select-none\">\n <div className=\"relative w-full h-90 overflow-hidden bg-neutral-50/70 select-none\">\n <Cropper\n image={src}\n crop={crop}\n zoom={zoom}\n rotation={rotation}\n minZoom={minZoom}\n maxZoom={maxZoom}\n zoomSpeed={0.5}\n restrictPosition={false}\n showGrid={false}\n objectFit=\"contain\"\n onCropChange={setCrop}\n onZoomChange={setZoom}\n onRotationChange={setRotation}\n classes={{\n mediaClassName: isFlipped ? \"scale-x-[-1]\" : \"\",\n }}\n style={{\n containerStyle: {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n backgroundColor: \"transparent\",\n },\n cropAreaStyle: {\n display: \"none\",\n },\n mediaStyle: {\n cursor: \"grab\",\n },\n }}\n />\n </div>\n\n {showToolbar && (\n <div className=\"w-full flex items-center justify-center py-3 border-t border-neutral-200 bg-neutral-white z-20\">\n <ImagePreviewToolbar\n zoom={zoom}\n rotation={rotation}\n isFlipped={isFlipped}\n onZoomIn={handleZoomIn}\n onZoomOut={handleZoomOut}\n onRotateCw={handleRotateCw}\n onRotateCcw={handleRotateCcw}\n onFlipHorizontal={handleFlipHorizontal}\n onReset={handleReset}\n currentImage={currentImage}\n {...toolbarProps}\n />\n </div>\n )}\n {children}\n </div>\n );\n}\n","import React from \"react\";\nimport { ImagePreviewToolbarProps } from \"./types\";\nimport ZoomInIcon from \"../../icons/ZoomInIcon\";\nimport ZoomOutIcon from \"../../icons/ZoomOutIcon\";\nimport RotateCwIcon from \"../../icons/RotateCwIcon\";\nimport RotateCcwIcon from \"../../icons/RotateCcwIcon\";\nimport FlipHorizontalIcon from \"../../icons/FlipHorizontalIcon\";\nimport DownloadIcon from \"../../icons/DownloadIcon\";\nimport { downloadFile } from \"../utils\";\n\nexport default function ImagePreviewToolbar({\n zoom = 1,\n onZoomIn,\n onZoomOut,\n onRotateCw,\n onRotateCcw,\n onFlipHorizontal,\n onReset,\n currentImage,\n tools,\n className = \"\",\n}: ImagePreviewToolbarProps) {\n const { zoomIn = true, zoomOut = true, reset = true, rotate = true, flip = true, download = true } = tools ?? {};\n\n const zoomPercent = Math.round(zoom * 100);\n\n const handleDownload = () => {\n if (!currentImage?.src) return;\n downloadFile(currentImage.src, currentImage.name);\n };\n\n const buttonBaseClass =\n \"p-2 rounded-full text-neutral-600 hover:text-neutral-900 hover:bg-neutral-100 active:scale-95 transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-primary-500 cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent\";\n\n return (\n <div\n className={`inline-flex items-center gap-1 bg-neutral-white border border-neutral-200 rounded-full px-3 py-1.5 shadow-sm text-neutral-700 select-none pointer-events-auto ${className}`}\n >\n {/* Zoom In */}\n {zoomIn && (\n <button\n type=\"button\"\n aria-label=\"Phóng to\"\n title=\"Phóng to (+)\"\n disabled={zoom >= 5}\n onClick={onZoomIn}\n className={buttonBaseClass}\n >\n <ZoomInIcon width={18} height={18} />\n </button>\n )}\n\n {/* Zoom Out */}\n {zoomOut && (\n <button\n type=\"button\"\n aria-label=\"Thu nhỏ\"\n title=\"Thu nhỏ (-)\"\n disabled={zoom <= 0.2}\n onClick={onZoomOut}\n className={buttonBaseClass}\n >\n <ZoomOutIcon width={18} height={18} />\n </button>\n )}\n\n {/* Zoom Percent / Reset */}\n {reset && (\n <button\n type=\"button\"\n aria-label=\"Đặt lại kích thước và góc xoay\"\n title=\"Đặt lại (1:1)\"\n onClick={onReset}\n className=\"px-2 py-1 text-xs font-semibold text-neutral-700 hover:text-neutral-900 hover:bg-neutral-100 rounded-full transition-colors cursor-pointer\"\n >\n {zoomPercent}%\n </button>\n )}\n\n {(rotate || flip || download) && <div className=\"w-px h-4 bg-neutral-200 my-auto mx-1\" />}\n\n {/* Rotate CCW */}\n {rotate && (\n <button\n type=\"button\"\n aria-label=\"Xoay ngược chiều kim đồng hồ\"\n title=\"Xoay ngược chiều kim đồng hồ\"\n onClick={onRotateCcw}\n className={buttonBaseClass}\n >\n <RotateCcwIcon width={18} height={18} />\n </button>\n )}\n\n {/* Rotate CW */}\n {rotate && (\n <button\n type=\"button\"\n aria-label=\"Xoay theo chiều kim đồng hồ\"\n title=\"Xoay theo chiều kim đồng hồ (r)\"\n onClick={onRotateCw}\n className={buttonBaseClass}\n >\n <RotateCwIcon width={18} height={18} />\n </button>\n )}\n\n {/* Flip Horizontal */}\n {flip && (\n <button\n type=\"button\"\n aria-label=\"Lật ngang\"\n title=\"Lật ngang\"\n onClick={onFlipHorizontal}\n className={buttonBaseClass}\n >\n <FlipHorizontalIcon width={18} height={18} />\n </button>\n )}\n\n {/* Download */}\n {download && (\n <button\n type=\"button\"\n aria-label=\"Tải ảnh xuống\"\n title=\"Tải xuống\"\n onClick={handleDownload}\n className={buttonBaseClass}\n >\n <DownloadIcon width={18} height={18} />\n </button>\n )}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { FileContainerProps } from \"./types\";\nimport { normalizePreviewFile } from \"./utils\";\nimport { FileContext } from \"./FileContext\";\nimport FilePreview from \"./FilePreview\";\nimport Modal from \"../modal/Modal\";\nimport ModalContainer from \"../modal/ModalContainer\";\nimport ModalHeader from \"../modal/ModalHeader\";\nimport ModalBody from \"../modal/ModalBody\";\n\n/**\n * Component `<FileContainer>`: Hộp thoại bọc Modal Dialog quản lý Backdrop, Top Layer, ESC và Lock Scroll\n * Nhận prop `file` và truyền xuống `<FilePreview />` qua `FileContext`.\n */\nexport default function FileContainer({\n open = false,\n onClose,\n file,\n title,\n description,\n size,\n radius = \"xl\",\n showCloseButton = true,\n closeOnOverlayClick = true,\n closeOnEsc = true,\n lockScroll = true,\n className = \"\",\n overlayClassName = \"\",\n children,\n}: FileContainerProps) {\n const normalized = normalizePreviewFile(file);\n const headerTitle = title ?? normalized?.name;\n\n const contextValue = useMemo(() => ({ file, headerTitle }), [file, headerTitle]);\n\n return (\n <ModalContainer\n open={open}\n onClose={onClose}\n size={size}\n closeOnOverlayClick={closeOnOverlayClick}\n closeOnEsc={closeOnEsc}\n lockScroll={lockScroll}\n overlayClassName={overlayClassName}\n >\n <Modal\n radius={radius}\n className={`bg-neutral-white border border-neutral-200 text-neutral-900 shadow-2xl overflow-hidden p-0 ${className}`}\n >\n {(headerTitle || showCloseButton) && (\n <ModalHeader\n title={headerTitle}\n description={description}\n showCloseButton={showCloseButton}\n className=\"px-5 py-3.5 border-b border-neutral-200\"\n />\n )}\n <ModalBody>\n <FileContext.Provider value={contextValue}>\n {children ? children : <FilePreview />}\n </FileContext.Provider>\n </ModalBody>\n </Modal>\n </ModalContainer>\n );\n}\n","import { ModalRadius, ModalSize } from \"./types\";\n\nexport const MODAL_EXIT_ANIMATION_DURATION = 250;\n\nexport const sizeConfig: Record<\n ModalSize,\n {\n dialog: string;\n header: string;\n body: string;\n footer: string;\n title: string;\n description: string;\n buttonGap: string;\n closeButton: string;\n closeIcon: string;\n }\n> = {\n xs: {\n dialog: \"max-w-[320px] p-3 gap-1.5\",\n header: \"gap-1.5\",\n body: \"text-xs\",\n footer: \"gap-1.5 pt-1.5\",\n title: \"text-sm font-semibold leading-tight text-neutral-900\",\n description: \"text-xs leading-normal text-neutral-600\",\n buttonGap: \"gap-1.5\",\n closeButton: \"size-5 p-0.5 -mr-1 -mt-1\",\n closeIcon: \"size-3.5\",\n },\n sm: {\n dialog: \"max-w-[400px] p-3.5 gap-2\",\n header: \"gap-2\",\n body: \"text-sm\",\n footer: \"gap-2 pt-2\",\n title: \"text-base font-semibold leading-tight text-neutral-900\",\n description: \"text-sm leading-normal text-neutral-600\",\n buttonGap: \"gap-2\",\n closeButton: \"size-6 p-0.5 -mr-1 -mt-1\",\n closeIcon: \"size-4\",\n },\n md: {\n dialog: \"max-w-[540px] p-4 gap-2.5\",\n header: \"gap-2.5\",\n body: \"text-sm\",\n footer: \"gap-2 pt-2\",\n title: \"text-lg font-semibold leading-tight text-neutral-900\",\n description: \"text-sm leading-relaxed text-neutral-600\",\n buttonGap: \"gap-2.5\",\n closeButton: \"size-7 p-1 -mr-1 -mt-1\",\n closeIcon: \"size-4\",\n },\n lg: {\n dialog: \"max-w-[720px] p-4.5 gap-3\",\n header: \"gap-3\",\n body: \"text-base\",\n footer: \"gap-2.5 pt-2.5\",\n title: \"text-xl font-bold leading-snug text-neutral-900\",\n description: \"text-base leading-relaxed text-neutral-600\",\n buttonGap: \"gap-3\",\n closeButton: \"size-8 p-1 -mr-1 -mt-1\",\n closeIcon: \"size-4.5\",\n },\n xl: {\n dialog: \"max-w-[960px] p-5 gap-3.5\",\n header: \"gap-3.5\",\n body: \"text-base\",\n footer: \"gap-3 pt-3\",\n title: \"text-2xl font-bold leading-snug text-neutral-900\",\n description: \"text-base leading-relaxed text-neutral-600\",\n buttonGap: \"gap-3.5\",\n closeButton: \"size-8 p-1 -mr-1 -mt-1\",\n closeIcon: \"size-5\",\n },\n full: {\n dialog: \"max-w-[calc(100vw-2rem)] w-full h-[calc(100vh-2rem)] p-4 gap-2.5\",\n header: \"gap-2.5\",\n body: \"text-base\",\n footer: \"gap-2 pt-2\",\n title: \"text-2xl font-bold leading-snug text-neutral-900\",\n description: \"text-base leading-relaxed text-neutral-600\",\n buttonGap: \"gap-2.5\",\n closeButton: \"size-8 p-1 -mr-1 -mt-1\",\n closeIcon: \"size-4.5\",\n },\n};\n\nexport const radiusConfig: Record<ModalRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-2xl\",\n};\n","import { createContext, useContext } from \"react\";\nimport { ModalSize } from \"./types\";\n\nexport interface ModalContextValue {\n onClose: () => void;\n isLoading?: boolean;\n size?: ModalSize;\n}\n\nexport const ModalContext = createContext<ModalContextValue | null>(null);\n\nexport const useModalContext = () => useContext(ModalContext);\n","import React from \"react\";\nimport { sizeConfig, radiusConfig } from \"./constants\";\nimport { ModalProps } from \"./types\";\nimport { useModalContext } from \"./ModalContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function Modal({\n size,\n radius,\n className = \"\",\n children,\n ref,\n ...props\n}: ModalProps) {\n const modalContext = useModalContext();\n const currentSize = getSafeConfig(size ?? modalContext?.size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"lg\");\n\n const containerClasses = [\n \"relative flex flex-col w-full bg-neutral-white shadow-2xl border-2 border-neutral-200 outline-none text-neutral-900 pointer-events-auto\",\n currentSize.dialog,\n roundedClass,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={ref}\n tabIndex={-1}\n className={containerClasses}\n {...props}\n >\n {children}\n </div>\n );\n}\n","import { useEffect, useEffectEvent, useCallback, useMemo, useRef, useState } from \"react\";\nimport { MODAL_EXIT_ANIMATION_DURATION } from \"./constants\";\nimport { ModalContainerProps } from \"./types\";\nimport { ModalContext } from \"./ModalContext\";\n\nexport default function ModalContainer({\n open = false,\n id,\n size,\n isLoading = false,\n closeOnOverlayClick = true,\n closeOnEsc = true,\n lockScroll = true,\n overlayClassName = \"\",\n className = \"\",\n children,\n onClose,\n ...props\n}: ModalContainerProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const [isExiting, setIsExiting] = useState(false);\n const exitTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleTriggerClose = useCallback(() => {\n if (isExiting || isLoading) return;\n\n setIsExiting(true);\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n exitTimerRef.current = setTimeout(() => {\n setIsExiting(false);\n onClose?.();\n }, MODAL_EXIT_ANIMATION_DURATION);\n }, [isExiting, isLoading, onClose]);\n\n const contextValue = useMemo(\n () => ({\n onClose: handleTriggerClose,\n isLoading,\n size,\n }),\n [handleTriggerClose, isLoading, size]\n );\n\n // Clear timeout exit khi unmount\n useEffect(() => {\n return () => {\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n };\n }, []);\n\n // Mở / đóng dialog\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n if (open || isExiting) {\n if (!dialog.open) {\n try {\n dialog.showModal();\n } catch {\n /* empty */\n }\n }\n } else {\n if (dialog.open) {\n dialog.close();\n }\n }\n }, [open, isExiting]);\n\n // Lock body scroll khi mở modal\n useEffect(() => {\n if (!lockScroll) return;\n\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n return () => {\n document.body.style.overflow = originalOverflow;\n };\n }, [lockScroll]);\n\n /**\n * Xử lý sự kiện javascript gọi phím ESC\n * Vì dialog có hàm onCancel xử lý sự kiện nhất ESC trên window nhưng\n * không thể bắt được ESC trong mọi môi trường và Cypress synthetic tests.\n * Nên chúng ta cần xử lý sự kiện ESC trên window.\n */\n const handleKeyDown = useEffectEvent((e: KeyboardEvent) => {\n if (!open || closeOnEsc === false) return;\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n handleTriggerClose();\n }\n });\n\n useEffect(() => {\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, []);\n\n if (!open && !isExiting) {\n return null;\n }\n\n const handleOverlayClick = () => {\n if (closeOnOverlayClick) {\n handleTriggerClose();\n }\n };\n\n const backdropAnimation = isExiting ? \"animate-modal-backdrop-out pointer-events-none\" : \"animate-modal-backdrop-in\";\n\n const dialogAnimation = isExiting ? \"animate-modal-out pointer-events-none\" : \"animate-modal-in\";\n\n return (\n <ModalContext.Provider value={contextValue}>\n <dialog\n id={id}\n ref={dialogRef}\n aria-labelledby=\"modal-dialog-title\"\n aria-describedby=\"modal-dialog-description\"\n onCancel={(e) => {\n e.preventDefault();\n if (closeOnEsc !== false) {\n handleTriggerClose();\n }\n }}\n className={`fixed inset-0 flex items-center justify-center p-4 bg-neutral-950/40 backdrop-blur-xs border-none m-0 max-w-none max-h-none w-screen h-screen overflow-visible backdrop:bg-transparent ${backdropAnimation} ${overlayClassName}`}\n {...props}\n >\n <div\n aria-hidden=\"true\"\n onClick={handleOverlayClick}\n className=\"fixed inset-0 -z-10\"\n />\n <div className={`w-full flex items-center justify-center pointer-events-none ${dialogAnimation} ${className}`}>\n {children}\n </div>\n </dialog>\n </ModalContext.Provider>\n );\n}\n","import React from \"react\";\nimport { ModalHeaderProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport { useModalContext } from \"./ModalContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function ModalHeader({\n size,\n title,\n description,\n titleClassName = \"\",\n descriptionClassName = \"\",\n showCloseButton = true,\n onClose,\n closeButtonClassName = \"\",\n className = \"\",\n children,\n ...props\n}: ModalHeaderProps) {\n const modalContext = useModalContext();\n const currentSize = getSafeConfig(size ?? modalContext?.size, sizeConfig, \"md\");\n const isLoading = modalContext?.isLoading;\n\n const handleClose = () => {\n onClose?.();\n modalContext?.onClose?.();\n };\n\n const hasCloseHandler = Boolean(onClose || modalContext?.onClose);\n\n return (\n <div\n className={`flex items-start justify-between w-full border-b border-neutral-100 pb-2 ${currentSize.header} ${className}`}\n {...props}\n >\n <div className=\"flex-1 min-w-0 flex flex-col justify-center\">\n {title && (\n <h3\n id=\"modal-dialog-title\"\n className={`${currentSize.title} truncate ${titleClassName}`}\n >\n {title}\n </h3>\n )}\n {description && (\n <p\n id=\"modal-dialog-description\"\n className={`${currentSize.description} mt-0.5 ${descriptionClassName}`}\n >\n {description}\n </p>\n )}\n {children}\n </div>\n\n {showCloseButton && hasCloseHandler && (\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={isLoading}\n aria-label=\"Đóng hộp thoại\"\n data-testid=\"modal-close-button\"\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 rounded-md transition-colors cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 ${currentSize.closeButton} ${closeButtonClassName}`}\n >\n <CloseIcon className={currentSize.closeIcon} />\n </button>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport { ModalBodyProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { useModalContext } from \"./ModalContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function ModalBody({ size, className = \"\", children, ...props }: ModalBodyProps) {\n const modalContext = useModalContext();\n const currentSize = getSafeConfig(size ?? modalContext?.size, sizeConfig, \"md\");\n\n return (\n <div\n className={`w-full max-h-[calc(100vh-8rem)] overflow-y-auto ui-scrollbar ${currentSize.body} ${className}`}\n {...props}\n >\n {children}\n </div>\n );\n}\n","import { ReactNode } from \"react\";\nimport UploadIcon from \"../icons/UploadIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { UploadImageColor, UploadImageRadius, UploadImageShape, UploadImageSize, UploadImageVariant } from \"./types\";\nimport {\n uploadImageDefaultRadiusBySize,\n uploadImageRadiusConfig,\n uploadImageSizeConfig,\n uploadImageVariantColorConfig,\n} from \"./constants\";\n\nexport interface UploadImageDropzoneProps {\n size?: UploadImageSize;\n color?: UploadImageColor;\n variant?: UploadImageVariant;\n radius?: UploadImageRadius;\n shape?: UploadImageShape;\n disabled?: boolean;\n readOnly?: boolean;\n isLoading?: boolean;\n isDragging?: boolean;\n isInvalid?: boolean;\n dropzoneTitle?: ReactNode;\n dropzoneDescription?: ReactNode;\n icon?: ReactNode;\n onTriggerUpload: () => void;\n className?: string;\n describedById?: string;\n}\n\nexport default function UploadImageDropzone({\n size = \"md\",\n color = \"primary\",\n variant = \"outline\",\n radius,\n shape = \"rectangle\",\n disabled,\n readOnly,\n isLoading,\n isDragging,\n isInvalid,\n dropzoneTitle,\n dropzoneDescription,\n icon,\n onTriggerUpload,\n className = \"\",\n describedById,\n}: UploadImageDropzoneProps) {\n const currentSize = uploadImageSizeConfig[size];\n const effectiveRadius = radius\n ? uploadImageRadiusConfig[radius]\n : uploadImageRadiusConfig[uploadImageDefaultRadiusBySize[size]];\n\n const effectiveColor = isInvalid ? \"error\" : color;\n const colorStyles = variant !== \"other\" ? uploadImageVariantColorConfig[variant][effectiveColor] : null;\n\n const defaultTitle = \"Kéo thả hình ảnh vào đây, hoặc nhấn để duyệt file\";\n const defaultDesc = \"Hỗ trợ định dạng PNG, JPG, WEBP, GIF\";\n\n return (\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-label=\"Khu vực kéo thả và tải ảnh lên\"\n aria-disabled={disabled}\n aria-invalid={isInvalid}\n aria-describedby={describedById}\n aria-busy={isLoading}\n onClick={() => {\n if (!disabled && !readOnly && !isLoading) {\n onTriggerUpload();\n }\n }}\n onKeyDown={(e) => {\n if (disabled || readOnly || isLoading) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onTriggerUpload();\n }\n }}\n className={`group relative w-full ${currentSize.dropzoneHeight} ${currentSize.dropzonePadding} ${effectiveRadius} border-2 border-dashed flex flex-col items-center justify-center text-center transition-all duration-150 ease-in-out cursor-pointer ${\n isDragging\n ? colorStyles?.active || \"border-primary-500 bg-primary-50 ring-2 ring-primary-500/20\"\n : colorStyles?.idle || \"border-neutral-300 bg-neutral-50/50 hover:border-primary-500 hover:bg-primary-50/30\"\n } ${\n disabled ? \"opacity-50 cursor-not-allowed pointer-events-none bg-neutral-100\" : \"\"\n } focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:outline-hidden ${className}`}\n >\n {isLoading ? (\n <div\n className={`flex flex-col items-center justify-center gap-2 ${colorStyles?.iconColor || \"text-primary-600\"}`}\n >\n <Spinner width={currentSize.iconSize * 0.8} height={currentSize.iconSize * 0.8} />\n <span className={`${currentSize.titleSize} font-medium`}>Đang xử lý hình ảnh...</span>\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center gap-2\">\n {/* Icon */}\n <div className={`transition-colors ${colorStyles?.iconColor || \"text-primary-500\"}`}>\n {icon || <UploadIcon width={currentSize.iconSize} height={currentSize.iconSize} />}\n </div>\n\n {/* Title */}\n <div\n className={`${currentSize.titleSize} font-medium text-neutral-800 ${\n colorStyles?.titleHover || \"group-hover:text-primary-600\"\n } transition-colors`}\n >\n {dropzoneTitle ?? defaultTitle}\n </div>\n\n {/* Description */}\n <div id={describedById} className={`${currentSize.descSize} text-neutral-500`}>\n {dropzoneDescription ?? defaultDesc}\n </div>\n </div>\n )}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport Image, { ImageProps } from \"next/image\";\nimport Skeleton from \"./Skeleton\";\nimport { LoadingImageProps } from \"./types\";\nimport { radiusConfig } from \"./constants\";\nimport ImageIcon from \"../icons/ImageIcon\";\n\nexport default function LoadingImage({\n src,\n alt = \"\",\n width,\n height,\n fill,\n skeletonVariant = \"pulse\",\n radius = \"md\",\n className = \"\",\n wrapperClassName = \"\",\n style,\n wrapperStyle,\n onLoad,\n onError,\n ...imageProps\n}: LoadingImageProps) {\n const [isLoaded, setIsLoaded] = useState(false);\n const [hasError, setHasError] = useState(false);\n\n const roundedClass = radiusConfig[radius] ?? radiusConfig.md;\n\n const handleLoad: ImageProps[\"onLoad\"] = (e) => {\n setIsLoaded(true);\n onLoad?.(e);\n };\n\n const handleError: ImageProps[\"onError\"] = (e) => {\n setHasError(true);\n setIsLoaded(false);\n onError?.(e);\n };\n\n const computedWrapperStyle: React.CSSProperties = {\n ...(fill ? {} : { width, height }),\n ...wrapperStyle,\n };\n\n return (\n <div\n data-testid=\"loading-image-wrapper\"\n className={[\"relative overflow-hidden inline-block\", roundedClass, wrapperClassName].filter(Boolean).join(\" \")}\n style={computedWrapperStyle}\n >\n {/* Skeleton placeholder — hiển thị khi chưa load xong và chưa có lỗi */}\n {!isLoaded && !hasError && (\n <Skeleton\n data-testid=\"loading-image-skeleton\"\n variant={skeletonVariant}\n radius={radius}\n width=\"100%\"\n height=\"100%\"\n style={{ position: \"absolute\", inset: 0 }}\n />\n )}\n\n {/* Next.js Image component */}\n {src && (\n <Image\n data-testid=\"loading-image-img\"\n src={src}\n alt={alt}\n width={!fill ? width : undefined}\n height={!fill ? height : undefined}\n fill={fill}\n className={[\n \"block w-full h-full object-cover transition-opacity duration-200\",\n roundedClass,\n isLoaded ? \"opacity-100\" : \"opacity-0\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={style}\n onLoad={handleLoad}\n onError={handleError}\n {...imageProps}\n />\n )}\n\n {/* Fallback icon khi src lỗi */}\n {hasError && (\n <div\n data-testid=\"loading-image-error\"\n role=\"img\"\n aria-label=\"Image failed to load\"\n className={[\"absolute inset-0 flex items-center justify-center\", \"bg-neutral-100 text-neutral-400\"].join(\" \")}\n >\n <ImageIcon width={24} height={24} aria-hidden=\"true\" />\n </div>\n )}\n </div>\n );\n}\n","import { SkeletonRadius, SkeletonVariant } from \"./types\";\n\n/**\n * Animation class theo variant.\n * Variant 'wave' dùng class CSS tùy chỉnh `.skeleton-wave` được định nghĩa trong styles.css.\n */\nexport const variantConfig: Record<SkeletonVariant, string> = {\n pulse: \"animate-pulse\",\n wave: \"skeleton-wave\",\n none: \"\",\n};\n\n/**\n * Bo góc theo radius.\n * Chỉ áp dụng khi shape === 'rectangle'.\n */\nexport const radiusConfig: Record<SkeletonRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n","import { CSSProperties } from \"react\";\nimport { SkeletonProps } from \"./types\";\nimport { variantConfig, radiusConfig } from \"./constants\";\n\nexport default function Skeleton({\n variant = \"pulse\",\n shape = \"rectangle\",\n radius = \"md\",\n width,\n height = \"1rem\",\n lines = 1,\n gap = \"0.5rem\",\n className = \"\",\n style,\n ...props\n}: SkeletonProps) {\n const animationClass = variantConfig[variant] ?? \"\";\n\n // Circle: bỏ qua radius prop, luôn full-round\n const roundedClass = shape === \"circle\" ? \"rounded-full\" : (radiusConfig[radius] ?? radiusConfig.md);\n\n const toStyle = (val: string | number | undefined): string | number | undefined =>\n typeof val === \"number\" ? val : val;\n\n const baseStyle: CSSProperties = {\n width: toStyle(width),\n height: toStyle(height),\n ...style,\n };\n\n const itemClass = [\"bg-neutral-200\", animationClass, roundedClass].filter(Boolean).join(\" \");\n\n // Multi-line mode\n if (lines > 1) {\n return (\n <div\n role=\"status\"\n aria-label=\"Loading...\"\n className={[\"flex flex-col\", className].filter(Boolean).join(\" \")}\n style={{ gap: toStyle(gap), ...style }}\n {...props}\n >\n {Array.from({ length: lines }).map((_, i) => {\n const isLast = i === lines - 1;\n return (\n <div\n key={i}\n className={itemClass}\n style={{\n width: isLast ? \"60%\" : (toStyle(width) ?? \"100%\"),\n height: toStyle(height),\n }}\n />\n );\n })}\n </div>\n );\n }\n\n // Single line / block mode\n return (\n <div\n role=\"status\"\n aria-label=\"Loading...\"\n className={[itemClass, className].filter(Boolean).join(\" \")}\n style={baseStyle}\n {...props}\n />\n );\n}\n","import { ReactNode } from \"react\";\nimport LoadingImage from \"../skeleton/LoadingImage\";\nimport EyeIcon from \"../icons/EyeIcon\";\nimport TrashIcon from \"../icons/TrashIcon\";\nimport PlusIcon from \"../icons/PlusIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport { UploadFileItem, UploadImageColor, UploadImageRadius, UploadImageSize, UploadImageVariant } from \"./types\";\nimport { uploadImageRadiusConfig, uploadImageSizeConfig } from \"./constants\";\n\nexport interface UploadImageListProps {\n items: UploadFileItem[];\n size: UploadImageSize;\n color?: UploadImageColor;\n variant?: UploadImageVariant;\n radius: UploadImageRadius;\n disabled?: boolean;\n readOnly?: boolean;\n maxCount?: number;\n onRemove: (item: UploadFileItem, index: number) => void;\n onPreview: (item: UploadFileItem) => void;\n onTriggerUpload: () => void;\n renderItem?: (item: UploadFileItem, index: number, actions: { remove: () => void; preview: () => void }) => ReactNode;\n showAddButton?: boolean;\n className?: string;\n}\n\nexport default function UploadImageList({\n items,\n size,\n radius,\n disabled,\n readOnly,\n maxCount,\n onRemove,\n onPreview,\n onTriggerUpload,\n renderItem,\n showAddButton = true,\n className = \"\",\n}: UploadImageListProps) {\n const currentSize = uploadImageSizeConfig[size];\n const activeRadius = uploadImageRadiusConfig[radius];\n const canAddMore = !maxCount || items.length < maxCount;\n\n return (\n <ul\n aria-label=\"Danh sách hình ảnh đã tải lên\"\n className={`flex flex-wrap items-center list-none p-0 m-0 ${currentSize.gap} ${className}`}\n >\n {items.map((item, index) => {\n if (renderItem) {\n return (\n <li key={item.id} className=\"list-none\">\n {renderItem(item, index, {\n remove: () => onRemove(item, index),\n preview: () => onPreview(item),\n })}\n </li>\n );\n }\n\n const isUploading = item.status === \"uploading\";\n const isError = item.status === \"error\";\n\n return (\n <li\n key={item.id}\n tabIndex={disabled ? -1 : 0}\n aria-label={`Hình ảnh ${item.name}`}\n onKeyDown={(e) => {\n if (disabled || readOnly) return;\n if (e.key === \"Delete\" || e.key === \"Backspace\") {\n e.preventDefault();\n onRemove(item, index);\n }\n }}\n className={`group relative list-none ${currentSize.thumbnailSize} ${activeRadius} border-2 overflow-hidden flex items-center justify-center bg-neutral-100 ${\n isError ? \"border-error-500\" : \"border-neutral-200\"\n } transition-all duration-150 ease-in-out focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:outline-hidden`}\n >\n {item.url ? (\n <LoadingImage\n src={item.url}\n alt={item.name}\n width={80}\n height={80}\n radius={radius}\n unoptimized\n className=\"w-full h-full object-cover\"\n wrapperClassName=\"w-full h-full\"\n />\n ) : (\n <div className=\"text-xs text-neutral-400 p-1 text-center truncate\">{item.name}</div>\n )}\n\n {/* Uploading Spinner */}\n {isUploading && (\n <div className=\"absolute inset-0 bg-neutral-900/50 flex flex-col items-center justify-center text-neutral-white\">\n <Spinner width={18} height={18} />\n {typeof item.progress === \"number\" && (\n <span className=\"text-xs mt-1 font-medium\">{Math.round(item.progress)}%</span>\n )}\n </div>\n )}\n\n {/* Overlay Actions */}\n {!isUploading && !disabled && (\n <div className=\"absolute inset-0 bg-neutral-900/40 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-150 flex items-center justify-center gap-1.5 p-1\">\n {onPreview && item.url && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onPreview(item);\n }}\n aria-label={`Xem trước hình ảnh ${item.name}`}\n className=\"p-1 rounded-md text-neutral-white hover:bg-neutral-white/20 focus-visible:ring-2 focus-visible:ring-primary-400 focus-visible:outline-hidden transition-colors cursor-pointer\"\n >\n <EyeIcon width={16} height={16} />\n </button>\n )}\n\n {!readOnly && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onRemove(item, index);\n }}\n aria-label={`Xóa hình ảnh ${item.name}`}\n className=\"p-1 rounded-md text-error-300 hover:text-error-200 hover:bg-neutral-white/20 focus-visible:ring-2 focus-visible:ring-error-400 focus-visible:outline-hidden transition-colors cursor-pointer\"\n >\n <TrashIcon width={16} height={16} />\n </button>\n )}\n </div>\n )}\n </li>\n );\n })}\n\n {/* Add Button (+) in Grid */}\n {showAddButton && canAddMore && !readOnly && (\n <li className=\"list-none\">\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onTriggerUpload}\n aria-label=\"Thêm hình ảnh\"\n className={`${currentSize.thumbnailSize} ${activeRadius} border-2 border-dashed border-neutral-300 hover:border-primary-500 hover:bg-primary-50/40 text-neutral-400 hover:text-primary-600 flex flex-col items-center justify-center transition-all duration-150 ease-in-out cursor-pointer disabled:cursor-not-allowed disabled:opacity-50 focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:outline-hidden`}\n >\n <PlusIcon width={currentSize.iconSize * 0.5} height={currentSize.iconSize * 0.5} />\n </button>\n </li>\n )}\n </ul>\n );\n}\n","import {\n ChangeEvent,\n DragEvent,\n MouseEvent,\n KeyboardEvent,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport LoadingImage from \"../skeleton/LoadingImage\";\nimport { PreviewFile, UploadAvatarProps } from \"./types\";\nimport { uploadAvatarRadiusConfig, uploadAvatarSizeConfig, uploadAvatarVariantColorConfig } from \"./constants\";\nimport { normalizeInitialValue, validateFile } from \"./utils\";\nimport { FileContainer, getFileName } from \"../file-preview\";\nimport { UploadAvatarCropModal } from \"./UploadAvatarCrop\";\nimport UploadIcon from \"../icons/UploadIcon\";\nimport TrashIcon from \"../icons/TrashIcon\";\nimport EyeIcon from \"../icons/EyeIcon\";\nimport CropIcon from \"../icons/CropIcon\";\nimport Spinner from \"../icons/Spinner\";\nimport HelperErrorText from \"@/components/common/HelperErrorText\";\n\nexport default function UploadAvatar({\n size = \"md\",\n variant = \"outline\",\n color = \"primary\",\n shape = \"circle\",\n radius,\n value,\n defaultValue,\n onChange,\n onRemove,\n onPreview,\n onClear,\n maxSize,\n accept = \"image/*\",\n crop = true,\n label,\n labelPlacement = \"top\",\n isRequired = false,\n helperText,\n errorMessage,\n isInvalid = false,\n isLoading = false,\n disabled = false,\n readOnly = false,\n isClearable = false,\n icon,\n name,\n id,\n isFullWidth = false,\n className = \"\",\n wrapperClassName = \"\",\n avatarClassName = \"\",\n avatarWrapperClassName = \"\",\n labelClassName = \"\",\n helperClassName = \"\",\n ariaLabel,\n ref,\n}: UploadAvatarProps) {\n const generatedId = useId();\n const inputId = id || generatedId;\n const helperId = `${inputId}-helper`;\n\n const internalInputRef = useRef<HTMLInputElement>(null);\n\n // Controlled vs Uncontrolled State Management (theo chuẩn Input, chỉ dùng PreviewFile)\n const isControlled = value !== undefined;\n const [internalItem, setInternalItem] = useState<PreviewFile | null>(() =>\n normalizeInitialValue(defaultValue ?? null)\n );\n const currentItem = isControlled ? normalizeInitialValue(value) : internalItem;\n\n const [cropData, setCropData] = useState<{\n imageSrc: string;\n fileName: string;\n fileType: string;\n } | null>(null);\n const [isPreviewOpen, setIsPreviewOpen] = useState(false);\n\n const previewUrl = useMemo(() => {\n if (!currentItem) return \"\";\n if (currentItem instanceof File) {\n return URL.createObjectURL(currentItem);\n }\n return typeof currentItem.url === \"string\" ? currentItem.url : \"\";\n }, [currentItem]);\n\n useEffect(() => {\n return () => {\n if (previewUrl && previewUrl.startsWith(\"blob:\")) {\n URL.revokeObjectURL(previewUrl);\n }\n };\n }, [previewUrl]);\n\n const fileName =\n currentItem instanceof File\n ? currentItem.name\n : currentItem?.name || (typeof currentItem?.url === \"string\" ? getFileName(currentItem.url) : \"\") || \"\";\n\n const [validationError, setValidationError] = useState<string | null>(null);\n const [isDragging, setIsDragging] = useState(false);\n const dragCounter = useRef(0);\n const [srAnnouncement, setSrAnnouncement] = useState<string>(\"\");\n\n // Error State (Chuẩn hóa ERROR_DISPLAY_CONVENTIONS.md)\n const activeError = errorMessage || validationError;\n const hasError = Boolean(isInvalid || activeError);\n const activeColor = hasError ? \"error\" : color;\n\n const currentSize = uploadAvatarSizeConfig[size] || uploadAvatarSizeConfig.md;\n const roundedClass = shape === \"circle\" ? \"rounded-full\" : radius ? uploadAvatarRadiusConfig[radius] : \"rounded-md\";\n\n const variantStyles =\n variant === \"other\"\n ? \"\"\n : uploadAvatarVariantColorConfig[variant]?.[activeColor] || uploadAvatarVariantColorConfig.outline.primary;\n\n const isUploading = isLoading;\n\n const updateItem = (newItem: PreviewFile | null) => {\n if (!isControlled) {\n setInternalItem(newItem);\n }\n onChange?.(newItem);\n };\n\n const handleTriggerUpload = () => {\n if (disabled || readOnly || isUploading) return;\n const fileInput =\n typeof ref === \"object\" && ref && \"current\" in ref && ref.current ? ref.current : internalInputRef.current;\n\n if (fileInput) {\n fileInput.value = \"\";\n fileInput.click();\n }\n };\n\n const isCropActive = crop !== false;\n const cropOptions = typeof crop === \"object\" ? crop : {};\n\n const handleOpenCropModal = (imageSrc: string, file?: File) => {\n setCropData({\n imageSrc,\n fileName: file?.name || fileName || \"avatar.png\",\n fileType: file?.type || \"image/png\",\n });\n };\n\n const processFile = (file: File) => {\n if (disabled || readOnly || isUploading) return;\n setValidationError(null);\n\n const validation = validateFile(file, { maxSize, accept });\n if (!validation.isValid) {\n const err = validation.error || \"Tệp không hợp lệ\";\n setValidationError(err);\n setSrAnnouncement(`Lỗi tệp: ${err}`);\n return;\n }\n\n if (isCropActive) {\n const tempUrl = URL.createObjectURL(file);\n handleOpenCropModal(tempUrl, file);\n } else {\n updateItem(file);\n setSrAnnouncement(\"Tải ảnh đại diện thành công.\");\n }\n };\n\n const handleFileInputChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files[0]) {\n processFile(e.target.files[0]);\n }\n };\n\n const handleDragEnter = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (disabled || readOnly || isUploading) return;\n dragCounter.current += 1;\n if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {\n setIsDragging(true);\n }\n };\n\n const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (disabled || readOnly || isUploading) return;\n dragCounter.current -= 1;\n if (dragCounter.current <= 0) {\n setIsDragging(false);\n dragCounter.current = 0;\n }\n };\n\n const handleDrop = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n dragCounter.current = 0;\n\n if (disabled || readOnly || isUploading) return;\n if (e.dataTransfer.files && e.dataTransfer.files[0]) {\n processFile(e.dataTransfer.files[0]);\n e.dataTransfer.clearData();\n }\n };\n\n const handleRemove = (e?: MouseEvent) => {\n e?.stopPropagation();\n if (disabled || readOnly || isUploading) return;\n if (currentItem) {\n const removedItem = currentItem;\n updateItem(null);\n onRemove?.(removedItem);\n onClear?.();\n setSrAnnouncement(\"Đã xóa ảnh đại diện.\");\n }\n };\n\n const handlePreview = (e?: MouseEvent) => {\n e?.stopPropagation();\n if (!currentItem) return;\n\n setIsPreviewOpen(true);\n onPreview?.(currentItem);\n };\n\n const handleRecrop = (e?: MouseEvent) => {\n e?.stopPropagation();\n if (previewUrl) {\n handleOpenCropModal(previewUrl, currentItem instanceof File ? currentItem : undefined);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (disabled || readOnly || isUploading) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleTriggerUpload();\n }\n if (currentItem && (e.key === \"Delete\" || e.key === \"Backspace\")) {\n e.preventDefault();\n handleRemove();\n }\n };\n\n // Label Element (Đồng bộ quy chuẩn Label & A11y của Input)\n const renderLabel = () => {\n if (!label) return null;\n\n return (\n <label\n htmlFor={inputId}\n className={`inline-flex items-center font-bold transition-colors duration-150 ${currentSize.label} ${\n hasError ? \"text-error-600\" : \"text-neutral-700 group-focus-within/field:text-primary-600\"\n } ${labelClassName}`}\n >\n {label}\n {isRequired && (\n <span className=\"text-error-500 ml-0.5\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n );\n };\n\n const inputContainerBase =\n \"group/avatar relative flex items-center justify-center transition-all duration-150 ease-in-out border-2 overflow-hidden select-none\";\n const disabledStyles = disabled\n ? \"opacity-60 cursor-not-allowed bg-neutral-100 pointer-events-none\"\n : \"cursor-pointer\";\n\n const avatarBoxClasses = [\n inputContainerBase,\n currentSize.avatarSize,\n roundedClass,\n variantStyles,\n disabledStyles,\n isDragging ? \"ring-2 ring-primary-500/40 border-primary-500 bg-primary-50/80\" : \"\",\n avatarClassName || avatarWrapperClassName,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const isHorizontal = labelPlacement === \"left\";\n const effectiveWrapperClassName = wrapperClassName || className;\n\n return (\n <div\n className={`group/field flex ${\n isHorizontal ? \"flex-row items-center gap-3\" : \"flex-col\"\n } ${isFullWidth ? \"w-full\" : \"inline-flex\"} ${effectiveWrapperClassName}`}\n >\n {/* Hidden File Input */}\n <input\n ref={ref || internalInputRef}\n id={inputId}\n name={name}\n type=\"file\"\n accept={accept}\n disabled={disabled || isUploading}\n aria-hidden=\"true\"\n tabIndex={-1}\n className=\"hidden\"\n onChange={handleFileInputChange}\n />\n\n {/* Screen Reader Live Announcement */}\n <div aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {srAnnouncement}\n </div>\n\n {/* Label */}\n {renderLabel()}\n\n {/* Avatar Container & Helpers */}\n <div className={`flex flex-col ${isFullWidth ? \"w-full\" : \"\"}`}>\n <div\n role=\"button\"\n tabIndex={disabled || isUploading ? -1 : 0}\n aria-label={ariaLabel || \"Tải lên ảnh đại diện\"}\n aria-disabled={disabled || isUploading}\n aria-invalid={hasError}\n aria-required={isRequired}\n aria-describedby={errorMessage || helperText || validationError ? helperId : undefined}\n aria-busy={isLoading}\n onClick={handleTriggerUpload}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n className={avatarBoxClasses}\n >\n {/* 1. Image present */}\n {previewUrl ? (\n <LoadingImage\n src={previewUrl}\n alt={fileName || \"Avatar\"}\n width={160}\n height={160}\n radius={shape === \"circle\" ? \"full\" : radius}\n unoptimized\n className=\"w-full h-full object-cover\"\n wrapperClassName=\"w-full h-full\"\n />\n ) : (\n /* 2. Empty Placeholder Icon */\n <div\n className={`flex flex-col items-center justify-center text-primary-400 group-hover/avatar:text-primary-600 transition-colors ${currentSize.iconClass}`}\n >\n {icon || <UploadIcon width={currentSize.iconSize} height={currentSize.iconSize} />}\n </div>\n )}\n\n {/* Loading Spinner Overlay */}\n {isUploading && (\n <div\n className=\"absolute inset-0 bg-neutral-950/60 flex items-center justify-center text-neutral-white z-20\"\n role=\"status\"\n aria-label=\"Đang tải\"\n >\n <Spinner width={currentSize.iconSize} height={currentSize.iconSize} className=\"animate-spin\" />\n </div>\n )}\n\n {/* Hover Action Overlay - ONLY when an image exists and not uploading/disabled */}\n {!isUploading && !disabled && previewUrl && (\n <div className=\"absolute inset-0 bg-neutral-950/60 opacity-0 group-hover/avatar:opacity-100 group-focus-visible/avatar:opacity-100 transition-opacity flex items-center justify-center gap-1.5 text-neutral-white z-10\">\n {/* Preview Button */}\n <button\n type=\"button\"\n onClick={handlePreview}\n aria-label=\"Xem trước ảnh đại diện\"\n title=\"Xem trước\"\n className=\"p-1 rounded-full text-neutral-white hover:bg-neutral-white/20 focus-visible:ring-2 focus-visible:ring-neutral-white focus-visible:outline-hidden cursor-pointer\"\n data-testid=\"avatar-preview-button\"\n >\n <EyeIcon width={14} height={14} />\n </button>\n\n {/* Crop Button */}\n {isCropActive && !readOnly && (\n <button\n type=\"button\"\n onClick={handleRecrop}\n aria-label=\"Cắt ảnh đại diện\"\n title=\"Cắt ảnh\"\n className=\"p-1 rounded-full text-neutral-white hover:bg-neutral-white/20 focus-visible:ring-2 focus-visible:ring-neutral-white focus-visible:outline-hidden cursor-pointer\"\n data-testid=\"avatar-crop-button\"\n >\n <CropIcon width={14} height={14} />\n </button>\n )}\n\n {/* Remove Button (hoặc isClearable) */}\n {(!readOnly || isClearable) && (\n <button\n type=\"button\"\n onClick={handleRemove}\n aria-label=\"Xóa ảnh đại diện\"\n title=\"Xóa ảnh\"\n className=\"p-1 rounded-full text-error-300 hover:text-error-200 hover:bg-neutral-white/20 focus-visible:ring-2 focus-visible:ring-error-400 focus-visible:outline-hidden cursor-pointer\"\n data-testid=\"avatar-remove-button\"\n >\n <TrashIcon width={14} height={14} />\n </button>\n )}\n </div>\n )}\n </div>\n\n {/* Helper & Error Message Rendering */}\n <HelperErrorText\n id={helperId}\n helperText={helperText}\n errorMessage={activeError}\n sizeClassName={currentSize.helper}\n className={helperClassName}\n />\n\n {/* Crop Modal */}\n {isCropActive && cropData && (\n <UploadAvatarCropModal\n open={Boolean(cropData)}\n imageSrc={cropData.imageSrc}\n fileName={cropData.fileName}\n fileType={cropData.fileType}\n aspectRatio={cropOptions.aspectRatio ?? 1}\n cropShape={cropOptions.cropShape ?? (shape === \"circle\" ? \"round\" : \"rect\")}\n showGrid={cropOptions.showGrid ?? true}\n minZoom={cropOptions.minZoom ?? 1}\n maxZoom={cropOptions.maxZoom ?? 4}\n modalTitle={cropOptions.modalTitle || \"Cắt ảnh đại diện\"}\n onClose={() => setCropData(null)}\n onApply={(croppedFile: File) => {\n updateItem(croppedFile);\n setSrAnnouncement(\"Ảnh đại diện đã được cập nhật thành công.\");\n setCropData(null);\n }}\n />\n )}\n {/* File Preview Modal */}\n {isPreviewOpen && currentItem && (\n <FileContainer\n open={isPreviewOpen}\n onClose={() => setIsPreviewOpen(false)}\n file={currentItem}\n />\n )}\n </div>\n </div>\n );\n}\n","import { UploadAvatarColor, UploadAvatarRadius, UploadAvatarSize, UploadAvatarVariant } from \"./types\";\n\nexport const uploadAvatarRadiusConfig: Record<UploadAvatarRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n};\n\nexport const uploadAvatarSizeConfig: Record<\n UploadAvatarSize,\n {\n avatarSize: string;\n iconSize: number;\n iconClass: string;\n label: string;\n helper: string;\n rounded: string;\n }\n> = {\n xs: {\n avatarSize: \"size-12\",\n iconSize: 20,\n iconClass: \"size-5\",\n label: \"text-[11px] mb-1\",\n helper: \"text-[9px] mt-0.5\",\n rounded: \"rounded\",\n },\n sm: {\n avatarSize: \"size-16\",\n iconSize: 24,\n iconClass: \"size-6\",\n label: \"text-xs mb-1\",\n helper: \"text-[10px] mt-0.5\",\n rounded: \"rounded-md\",\n },\n md: {\n avatarSize: \"size-20\",\n iconSize: 32,\n iconClass: \"size-8\",\n label: \"text-sm mb-1.5\",\n helper: \"text-[11px] mt-1\",\n rounded: \"rounded-lg\",\n },\n lg: {\n avatarSize: \"size-24\",\n iconSize: 40,\n iconClass: \"size-10\",\n label: \"text-base mb-1.5\",\n helper: \"text-xs mt-1\",\n rounded: \"rounded-xl\",\n },\n xl: {\n avatarSize: \"size-32\",\n iconSize: 52,\n iconClass: \"size-12\",\n label: \"text-lg mb-2\",\n helper: \"text-sm mt-1\",\n rounded: \"rounded-2xl\",\n },\n};\n\nexport const uploadAvatarVariantColorConfig: Record<\n Exclude<UploadAvatarVariant, \"other\">,\n Record<UploadAvatarColor, string>\n> = {\n outline: {\n primary:\n \"bg-neutral-white border-primary-400 hover:border-primary-500 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-neutral-white border-secondary-400 hover:border-secondary-500 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-neutral-white border-neutral-300 hover:border-neutral-400 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-neutral-white border-error-500 hover:border-error-600 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-neutral-white border-success-400 hover:border-success-500 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-neutral-white border-warning-400 hover:border-warning-500 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-neutral-white border-info-400 hover:border-info-500 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n filled: {\n primary:\n \"bg-primary-50/60 border-primary-200 hover:bg-primary-100/60 focus-within:bg-primary-100/60 focus-within:border-primary-500 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-secondary-50/60 border-secondary-200 hover:bg-secondary-100/60 focus-within:bg-secondary-100/60 focus-within:border-secondary-500 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-neutral-50/60 border-neutral-200 hover:bg-neutral-200/60 focus-within:bg-neutral-200/60 focus-within:border-neutral-500 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-error-50/60 border-error-500 hover:border-error-600 hover:bg-error-100/60 focus-within:bg-error-100/60 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-success-50/60 border-success-200 hover:bg-success-100/60 focus-within:bg-success-100/60 focus-within:border-success-500 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-warning-50/60 border-warning-200 hover:bg-warning-100/60 focus-within:bg-warning-100/60 focus-within:border-warning-500 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-info-50/60 border-info-200 hover:bg-info-100/60 focus-within:bg-info-100/60 focus-within:border-info-500 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n ghost: {\n primary:\n \"bg-transparent border-transparent hover:bg-primary-50/50 focus-within:bg-primary-50/50 focus-within:border-primary-200/20 focus-within:ring-2 focus-within:ring-primary-500/20\",\n secondary:\n \"bg-transparent border-transparent hover:bg-secondary-50/50 focus-within:bg-secondary-50/50 focus-within:border-secondary-200/20 focus-within:ring-2 focus-within:ring-secondary-500/20\",\n neutral:\n \"bg-transparent border-transparent hover:bg-neutral-50/50 focus-within:bg-neutral-50/50 focus-within:border-neutral-200/20 focus-within:ring-2 focus-within:ring-neutral-500/20\",\n error:\n \"bg-transparent border-error-500 hover:bg-error-50/50 focus-within:bg-error-50/50 focus-within:border-error-500 focus-within:ring-2 focus-within:ring-error-500/20\",\n success:\n \"bg-transparent border-transparent hover:bg-success-50/50 focus-within:bg-success-50/50 focus-within:border-success-200/20 focus-within:ring-2 focus-within:ring-success-500/20\",\n warning:\n \"bg-transparent border-transparent hover:bg-warning-50/50 focus-within:bg-warning-50/50 focus-within:border-warning-200/20 focus-within:ring-2 focus-within:ring-warning-500/20\",\n info: \"bg-transparent border-transparent hover:bg-info-50/50 focus-within:bg-info-50/50 focus-within:border-info-200/20 focus-within:ring-2 focus-within:ring-info-500/20\",\n },\n};\n","import { PreviewFile } from \"../file-preview/types\";\nimport { getFileName, getFileType } from \"../file-preview/utils\";\n\nexport function generateId(): string {\n return `avatar-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`;\n}\n\nexport function normalizeInitialValue(value?: PreviewFile | string | null): PreviewFile | null {\n if (!value) return null;\n if (typeof value === \"string\") {\n return {\n url: value,\n name: getFileName(value) || \"avatar\",\n type: getFileType(value),\n };\n }\n return value;\n}\n\nexport function validateFile(\n file: File,\n options?: {\n maxSize?: number;\n accept?: string;\n }\n): { isValid: boolean; error?: string } {\n const { maxSize, accept } = options || {};\n\n if (maxSize && file.size > maxSize) {\n const maxMb = (maxSize / (1024 * 1024)).toFixed(1);\n return {\n isValid: false,\n error: `Dung lượng tệp vượt quá giới hạn cho phép ${maxMb}MB.`,\n };\n }\n\n if (accept && accept !== \"*\") {\n const acceptedTypes = accept.split(\",\").map((t) => t.trim().toLowerCase());\n const fileType = file.type.toLowerCase();\n const fileExt = `.${file.name.split(\".\").pop()?.toLowerCase()}`;\n\n const isMatch = acceptedTypes.some((type) => {\n if (type.startsWith(\".\")) {\n return fileExt === type;\n }\n if (type.endsWith(\"/*\")) {\n const category = type.replace(\"/*\", \"\");\n return fileType.startsWith(`${category}/`);\n }\n return fileType === type;\n });\n\n if (!isMatch) {\n return {\n isValid: false,\n error: `Định dạng tệp không được hỗ trợ. Cho phép: ${accept}`,\n };\n }\n }\n\n return { isValid: true };\n}\n\nexport function revokeFileItem(item?: PreviewFile | null): void {\n if (!item) return;\n if (typeof item === \"object\" && \"url\" in item && typeof item.url === \"string\" && item.url.startsWith(\"blob:\")) {\n try {\n URL.revokeObjectURL(item.url);\n } catch {\n // Ignore\n }\n }\n}\n","import { ChangeEvent, useRef, useState } from \"react\";\nimport Cropper, { Area, Point } from \"react-easy-crop\";\nimport { getCroppedImage } from \"./cropUtils\";\nimport { Modal, ModalContainer, ModalHeader, ModalBody } from \"../modal\";\nimport ZoomInIcon from \"../icons/ZoomInIcon\";\nimport ZoomOutIcon from \"../icons/ZoomOutIcon\";\nimport RotateCwIcon from \"../icons/RotateCwIcon\";\nimport RotateCcwIcon from \"../icons/RotateCcwIcon\";\nimport FlipHorizontalIcon from \"../icons/FlipHorizontalIcon\";\nimport ResetIcon from \"../icons/ResetIcon\";\nimport UploadIcon from \"../icons/UploadIcon\";\nimport CheckIcon from \"../icons/CheckIcon\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport Spinner from \"../icons/Spinner\";\n\nexport interface UploadAvatarCropContentProps {\n imageSrc: string;\n fileName?: string;\n fileType?: string;\n aspectRatio?: number;\n cropShape?: \"round\" | \"rect\";\n showGrid?: boolean;\n minZoom?: number;\n maxZoom?: number;\n onApply: (croppedFile: File) => void;\n onCancel?: () => void;\n}\n\nexport type UploadAvatarCropModalProps = UploadAvatarCropContentProps & {\n open?: boolean;\n modalTitle?: string;\n onClose?: () => void;\n};\n\nexport function UploadAvatarCropContent({\n imageSrc: initialImageSrc,\n fileName: initialFileName = \"avatar-cropped.png\",\n fileType: initialFileType = \"image/png\",\n aspectRatio = 1,\n cropShape = \"round\",\n showGrid = true,\n minZoom = 1,\n maxZoom = 4,\n onApply,\n onCancel,\n}: UploadAvatarCropContentProps) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [imageSrc, setImageSrc] = useState(initialImageSrc);\n const [fileName, setFileName] = useState(initialFileName);\n const [fileType, setFileType] = useState(initialFileType);\n\n const [crop, setCrop] = useState<Point>({ x: 0, y: 0 });\n const [zoom, setZoom] = useState(1);\n const [rotation, setRotation] = useState(0);\n const [isFlipped, setIsFlipped] = useState(false);\n const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null);\n const [isProcessing, setIsProcessing] = useState(false);\n\n const handleZoomIn = () => setZoom((prev) => Math.min(maxZoom, Math.round((prev + 0.2) * 10) / 10));\n const handleZoomOut = () => setZoom((prev) => Math.max(minZoom, Math.round((prev - 0.2) * 10) / 10));\n const handleRotateCw = () => setRotation((prev) => (prev + 90) % 360);\n const handleRotateCcw = () => setRotation((prev) => (prev - 90 + 360) % 360);\n const handleFlipHorizontal = () => setIsFlipped((prev) => !prev);\n const handleReset = () => {\n setCrop({ x: 0, y: 0 });\n setZoom(1);\n setRotation(0);\n setIsFlipped(false);\n };\n\n const handleChangeImageClick = () => {\n if (fileInputRef.current) {\n fileInputRef.current.value = \"\";\n fileInputRef.current.click();\n }\n };\n\n const handleNewFileSelected = (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files[0]) {\n const newFile = e.target.files[0];\n const newUrl = URL.createObjectURL(newFile);\n setImageSrc(newUrl);\n setFileName(newFile.name);\n setFileType(newFile.type || \"image/png\");\n handleReset();\n }\n };\n\n const handleCropComplete = (_croppedArea: Area, croppedAreaPixels: Area) => {\n setCroppedAreaPixels(croppedAreaPixels);\n };\n\n const handleSave = async () => {\n if (!croppedAreaPixels) return;\n try {\n setIsProcessing(true);\n const croppedFile = await getCroppedImage(imageSrc, croppedAreaPixels, rotation, isFlipped, fileName, fileType);\n onApply(croppedFile);\n } catch (err) {\n console.error(\"Error cropping avatar:\", err);\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleClose = () => {\n onCancel?.();\n };\n\n const toolbarBtnClass =\n \"p-1.5 rounded-full text-neutral-600 hover:text-neutral-900 hover:bg-neutral-200/70 transition-all focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:outline-hidden cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed shrink-0\";\n\n return (\n <div className=\"flex flex-col w-full select-none\" data-testid=\"upload-avatar-crop-modal\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n aria-hidden=\"true\"\n tabIndex={-1}\n className=\"hidden\"\n onChange={handleNewFileSelected}\n />\n\n <div className=\"relative w-full h-80 md:h-90 bg-neutral-950 overflow-hidden select-none\">\n <Cropper\n image={imageSrc}\n crop={crop}\n zoom={zoom}\n rotation={rotation}\n aspect={aspectRatio}\n cropShape={cropShape}\n showGrid={showGrid}\n minZoom={minZoom}\n maxZoom={maxZoom}\n onCropChange={setCrop}\n onZoomChange={setZoom}\n onRotationChange={setRotation}\n onCropComplete={handleCropComplete}\n classes={{\n mediaClassName: isFlipped ? \"scale-x-[-1]\" : \"\",\n }}\n style={{\n containerStyle: {\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n },\n }}\n />\n </div>\n\n <div className=\"w-full flex items-center justify-center py-2.5 px-3 bg-neutral-white border-t border-neutral-200 overflow-x-auto ui-scrollbar\">\n <div className=\"inline-flex items-center flex-nowrap shrink-0 gap-1 bg-neutral-50 border border-neutral-200 rounded-full px-2.5 py-1 shadow-xs text-neutral-700\">\n {/* 1. Chọn ảnh khác */}\n <button\n type=\"button\"\n onClick={handleChangeImageClick}\n aria-label=\"Chọn ảnh khác\"\n title=\"Chọn ảnh khác\"\n className={`${toolbarBtnClass} text-neutral-700 hover:text-primary-600`}\n data-testid=\"avatar-crop-change-image-button\"\n >\n <UploadIcon width={16} height={16} />\n </button>\n\n <div className=\"w-px h-3.5 bg-neutral-300 my-auto mx-0.5 shrink-0\" />\n\n {/* 2. Zoom Out */}\n <button\n type=\"button\"\n onClick={handleZoomOut}\n disabled={zoom <= minZoom}\n aria-label=\"Thu nhỏ\"\n title=\"Thu nhỏ (-)\"\n className={toolbarBtnClass}\n >\n <ZoomOutIcon width={16} height={16} />\n </button>\n\n {/* 3. Zoom In */}\n <button\n type=\"button\"\n onClick={handleZoomIn}\n disabled={zoom >= maxZoom}\n aria-label=\"Phóng to\"\n title=\"Phóng to (+)\"\n className={toolbarBtnClass}\n >\n <ZoomInIcon width={16} height={16} />\n </button>\n\n {/* 4. Rotate CCW */}\n <button\n type=\"button\"\n onClick={handleRotateCcw}\n title=\"Xoay ngược chiều kim đồng hồ\"\n aria-label=\"Xoay ngược chiều kim đồng hồ\"\n className={toolbarBtnClass}\n >\n <RotateCcwIcon width={16} height={16} />\n </button>\n\n {/* 5. Rotate CW */}\n <button\n type=\"button\"\n onClick={handleRotateCw}\n title=\"Xoay theo chiều kim đồng hồ\"\n aria-label=\"Xoay theo chiều kim đồng hồ\"\n className={toolbarBtnClass}\n >\n <RotateCwIcon width={16} height={16} />\n </button>\n\n {/* 6. Flip Horizontal */}\n <button\n type=\"button\"\n onClick={handleFlipHorizontal}\n title=\"Lật ngang\"\n aria-label=\"Lật ngang\"\n className={toolbarBtnClass}\n >\n <FlipHorizontalIcon width={16} height={16} />\n </button>\n\n {/* 7. Reset */}\n <button\n type=\"button\"\n onClick={handleReset}\n title=\"Đặt lại\"\n aria-label=\"Đặt lại\"\n className={toolbarBtnClass}\n >\n <ResetIcon width={16} height={16} />\n </button>\n\n <div className=\"w-px h-3.5 bg-neutral-300 my-auto mx-0.5 shrink-0\" />\n\n {/* 8. Cancel / Close */}\n <button\n type=\"button\"\n onClick={handleClose}\n aria-label=\"Hủy cắt ảnh\"\n title=\"Hủy (Esc)\"\n className={`${toolbarBtnClass} text-neutral-500 hover:text-error-600`}\n data-testid=\"avatar-crop-cancel-button\"\n >\n <CloseIcon width={16} height={16} />\n </button>\n\n {/* 9. Xác nhận */}\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={isProcessing}\n aria-label=\"Áp dụng và lưu ảnh đã cắt\"\n title=\"Áp dụng\"\n className=\"p-1.5 rounded-full bg-primary-600 hover:bg-primary-500 text-white shadow-xs transition-all active:scale-95 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:outline-hidden shrink-0\"\n data-testid=\"avatar-crop-apply-button\"\n >\n {isProcessing ? <Spinner width={16} height={16} /> : <CheckIcon width={16} height={16} />}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport function UploadAvatarCropModal({\n open = true,\n modalTitle = \"Cắt ảnh đại diện\",\n onClose,\n onCancel,\n onApply,\n ...restProps\n}: UploadAvatarCropModalProps) {\n const handleClose = () => {\n onCancel?.();\n onClose?.();\n };\n\n const handleApply = (croppedFile: File) => {\n onApply(croppedFile);\n onClose?.();\n };\n\n return (\n <ModalContainer\n open={open}\n closeOnOverlayClick={true}\n closeOnEsc={true}\n onClose={handleClose}\n >\n <Modal\n size=\"lg\"\n radius=\"xl\"\n className=\"bg-neutral-white border border-neutral-200 shadow-2xl overflow-hidden p-0\"\n >\n <ModalHeader\n title={\n <span className=\"font-semibold text-neutral-900\" data-testid=\"avatar-crop-modal-title\">\n {modalTitle}\n </span>\n }\n className=\"px-5 py-3.5 border-b border-neutral-200\"\n showCloseButton\n />\n <ModalBody className=\"p-0 overflow-hidden\">\n <UploadAvatarCropContent {...restProps} onApply={handleApply} onCancel={handleClose} />\n </ModalBody>\n </Modal>\n </ModalContainer>\n );\n}\n","export interface PixelCrop {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport function createImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.addEventListener(\"load\", () => resolve(image));\n image.addEventListener(\"error\", (error) => reject(error));\n image.setAttribute(\"crossOrigin\", \"anonymous\");\n image.src = url;\n });\n}\n\nexport function getRadianAngle(degreeValue: number) {\n return (degreeValue * Math.PI) / 180;\n}\n\nexport function rotateSize(width: number, height: number, rotation: number) {\n const rotRad = getRadianAngle(rotation);\n return {\n width: Math.abs(Math.cos(rotRad) * width) + Math.abs(Math.sin(rotRad) * height),\n height: Math.abs(Math.sin(rotRad) * width) + Math.abs(Math.cos(rotRad) * height),\n };\n}\n\nexport async function getCroppedImage(\n imageSrc: string,\n pixelCrop: PixelCrop,\n rotation = 0,\n isFlipped = false,\n fileName = \"avatar-cropped.png\",\n fileType = \"image/png\"\n): Promise<File> {\n const image = await createImage(imageSrc);\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) {\n throw new Error(\"No 2d context available on canvas\");\n }\n\n const rotRad = getRadianAngle(rotation);\n\n const { width: bBoxWidth, height: bBoxHeight } = rotateSize(image.width, image.height, rotation);\n\n canvas.width = bBoxWidth;\n canvas.height = bBoxHeight;\n\n ctx.translate(bBoxWidth / 2, bBoxHeight / 2);\n ctx.rotate(rotRad);\n ctx.scale(isFlipped ? -1 : 1, 1);\n ctx.translate(-image.width / 2, -image.height / 2);\n\n ctx.drawImage(image, 0, 0);\n\n const croppedCanvas = document.createElement(\"canvas\");\n const croppedCtx = croppedCanvas.getContext(\"2d\");\n\n if (!croppedCtx) {\n throw new Error(\"No 2d context for cropped canvas\");\n }\n\n croppedCanvas.width = pixelCrop.width;\n croppedCanvas.height = pixelCrop.height;\n\n croppedCtx.drawImage(\n canvas,\n pixelCrop.x,\n pixelCrop.y,\n pixelCrop.width,\n pixelCrop.height,\n 0,\n 0,\n pixelCrop.width,\n pixelCrop.height\n );\n\n return new Promise((resolve, reject) => {\n croppedCanvas.toBlob(\n (blob) => {\n if (!blob) {\n reject(new Error(\"Canvas is empty or failed to generate blob\"));\n return;\n }\n const file = new File([blob], fileName, { type: fileType || \"image/png\" });\n resolve(file);\n },\n fileType || \"image/png\",\n 0.95\n );\n });\n}\n","import React from \"react\";\nimport { ModalFooterProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { useModalContext } from \"./ModalContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\nexport default function ModalFooter({ size, className = \"\", children, ...props }: ModalFooterProps) {\n const modalContext = useModalContext();\n const currentSize = getSafeConfig(size ?? modalContext?.size, sizeConfig, \"md\");\n\n return (\n <div\n className={`flex items-center justify-end w-full border-t border-neutral-100 pt-2 ${currentSize.footer} ${currentSize.buttonGap} ${className}`}\n {...props}\n >\n {children}\n </div>\n );\n}\n","import { cloneElement, isValidElement, MouseEvent, ReactElement } from \"react\";\nimport { ModalCloseProps } from \"./types\";\nimport { useModalContext } from \"./ModalContext\";\n\nexport default function ModalClose({\n children,\n asChild = true,\n onClick,\n ...props\n}: ModalCloseProps) {\n const modalContext = useModalContext();\n const isLoading = modalContext?.isLoading;\n\n const handleClick = (e: MouseEvent<HTMLElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) {\n modalContext?.onClose?.();\n }\n };\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<{\n onClick?: (e: MouseEvent<HTMLElement>) => void;\n disabled?: boolean;\n }>;\n return cloneElement(child, {\n disabled: child.props.disabled || isLoading,\n onClick: (e: MouseEvent<HTMLElement>) => {\n child.props.onClick?.(e);\n handleClick(e);\n },\n ...props,\n });\n }\n\n return (\n <button type=\"button\" onClick={handleClick} disabled={isLoading} {...props}>\n {children}\n </button>\n );\n}\n","import { ConfirmColor, ConfirmRadius, ConfirmSize } from \"./types\";\nimport { ButtonSize } from \"../button/types\";\nimport AlertTriangleIcon from \"../icons/AlertTriangleIcon\";\nimport AlertCircleIcon from \"../icons/AlertCircleIcon\";\nimport CheckCircleIcon from \"../icons/CheckCircleIcon\";\nimport InfoCircleIcon from \"../icons/InfoCircleIcon\";\nimport { ComponentType } from \"react\";\n\nexport const CONFIRM_EXIT_ANIMATION_DURATION = 300;\n\nexport const sizeConfig: Record<\n ConfirmSize,\n {\n dialog: string;\n header: string;\n body: string;\n footer: string;\n title: string;\n description: string;\n iconWrapper: string;\n icon: string;\n buttonSize: ButtonSize;\n buttonGap: string;\n closeButton: string;\n closeIcon: string;\n }\n> = {\n xs: {\n dialog: \"max-w-[320px] p-4 gap-3\",\n header: \"gap-2.5\",\n body: \"text-xs\",\n footer: \"gap-2 pt-2\",\n title: \"text-sm font-semibold leading-tight text-neutral-900\",\n description: \"text-xs leading-normal text-neutral-600\",\n iconWrapper: \"size-7 rounded-full\",\n icon: \"size-4\",\n buttonSize: \"xs\",\n buttonGap: \"gap-2\",\n closeButton: \"size-5 p-0.5 -mr-1 -mt-1\",\n closeIcon: \"size-3.5\",\n },\n sm: {\n dialog: \"max-w-[380px] p-5 gap-3.5\",\n header: \"gap-3\",\n body: \"text-sm\",\n footer: \"gap-2.5 pt-2.5\",\n title: \"text-base font-semibold leading-tight text-neutral-900\",\n description: \"text-sm leading-normal text-neutral-600\",\n iconWrapper: \"size-9 rounded-full\",\n icon: \"size-5\",\n buttonSize: \"sm\",\n buttonGap: \"gap-2.5\",\n closeButton: \"size-6 p-0.5 -mr-1 -mt-1\",\n closeIcon: \"size-4\",\n },\n md: {\n dialog: \"max-w-[440px] p-6 gap-4\",\n header: \"gap-3.5\",\n body: \"text-sm\",\n footer: \"gap-3 pt-3\",\n title: \"text-lg font-semibold leading-tight text-neutral-900\",\n description: \"text-sm leading-relaxed text-neutral-600\",\n iconWrapper: \"size-10 rounded-full\",\n icon: \"size-5\",\n buttonSize: \"md\",\n buttonGap: \"gap-3\",\n closeButton: \"size-7 p-1 -mr-1.5 -mt-1.5\",\n closeIcon: \"size-4\",\n },\n lg: {\n dialog: \"max-w-[520px] p-7 gap-5\",\n header: \"gap-4\",\n body: \"text-base\",\n footer: \"gap-3.5 pt-3.5\",\n title: \"text-xl font-semibold leading-snug text-neutral-900\",\n description: \"text-base leading-relaxed text-neutral-600\",\n iconWrapper: \"size-12 rounded-full\",\n icon: \"size-6\",\n buttonSize: \"lg\",\n buttonGap: \"gap-3.5\",\n closeButton: \"size-8 p-1.5 -mr-1.5 -mt-1.5\",\n closeIcon: \"size-4.5\",\n },\n xl: {\n dialog: \"max-w-[600px] p-8 gap-6\",\n header: \"gap-4.5\",\n body: \"text-lg\",\n footer: \"gap-4 pt-4\",\n title: \"text-2xl font-bold leading-snug text-neutral-900\",\n description: \"text-lg leading-relaxed text-neutral-600\",\n iconWrapper: \"size-14 rounded-full\",\n icon: \"size-7\",\n buttonSize: \"xl\",\n buttonGap: \"gap-4\",\n closeButton: \"size-9 p-1.5 -mr-2 -mt-2\",\n closeIcon: \"size-5\",\n },\n};\n\nexport const radiusConfig: Record<ConfirmRadius, string> = {\n none: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-2xl\",\n};\n\nexport const iconBadgeColorConfig: Record<ConfirmColor, string> = {\n primary: \"bg-primary-50 text-primary-600 border border-primary-200\",\n secondary: \"bg-secondary-50 text-secondary-600 border border-secondary-200\",\n neutral: \"bg-neutral-100 text-neutral-600 border border-neutral-200\",\n error: \"bg-error-50 text-error-600 border border-error-200\",\n success: \"bg-success-50 text-success-600 border border-success-200\",\n warning: \"bg-warning-50 text-warning-600 border border-warning-200\",\n info: \"bg-info-50 text-info-600 border border-info-200\",\n};\n\nexport const defaultIcons: Record<ConfirmColor, ComponentType<{ className?: string }>> = {\n warning: AlertTriangleIcon,\n error: AlertCircleIcon,\n success: CheckCircleIcon,\n info: InfoCircleIcon,\n primary: InfoCircleIcon,\n secondary: InfoCircleIcon,\n neutral: InfoCircleIcon,\n};\n","import { createContext, useContext } from \"react\";\nimport { ConfirmColor, ConfirmSize } from \"./types\";\n\n/**\n * Giá trị được chia sẻ từ `<ConfirmContainer>` và `<Confirm>` xuống các sub-component con thông qua Context\n */\nexport interface ConfirmContextValue {\n /**\n * Callback kích hoạt đóng Confirm kèm hiệu ứng thoát (Exit Animation)\n */\n onClose: () => void;\n\n /**\n * Trạng thái đang tải / xử lý (Loading).\n * Khi `true`, sẽ chặn đóng hộp thoại và tự động vô hiệu hóa các nút đóng / hủy.\n */\n isLoading?: boolean;\n\n /**\n * Kích thước chiều rộng của Confirm\n */\n size?: ConfirmSize;\n\n /**\n * Chủ đề màu sắc của Confirm\n */\n color?: ConfirmColor;\n}\n\n/**\n * Context React phục vụ cơ chế liên kết Pure Compound của bộ component Confirm\n */\nexport const ConfirmContext = createContext<ConfirmContextValue | null>(null);\n\n/**\n * Hook truy xuất context của Confirm từ bên trong `<ConfirmContainer>` hoặc `<Confirm>`\n */\nexport const useConfirmContext = () => useContext(ConfirmContext);\n","import React from \"react\";\nimport { sizeConfig, radiusConfig } from \"./constants\";\nimport { ConfirmProps } from \"./types\";\nimport { useConfirmContext } from \"./ConfirmContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\n/**\n * Khung giao diện hộp thoại xác nhận (Confirm Dialog Box).\n * Thiết kế theo mô hình Pure Compound Pattern giống Modal:\n * Nhận size/color từ ConfirmContainer qua Context và render {children}.\n */\nexport default function Confirm({\n size,\n radius,\n className = \"\",\n children,\n ref,\n ...props\n}: ConfirmProps) {\n const confirmContext = useConfirmContext();\n const currentSize = getSafeConfig(size ?? confirmContext?.size, sizeConfig, \"md\");\n const roundedClass = getSafeConfig(radius, radiusConfig, \"lg\");\n\n const containerClasses = [\n \"relative flex flex-col w-full bg-neutral-white shadow-2xl border-2 border-neutral-200 outline-none text-neutral-900 pointer-events-auto\",\n currentSize.dialog,\n roundedClass,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={ref}\n tabIndex={-1}\n className={containerClasses}\n {...props}\n >\n {children}\n </div>\n );\n}\n","import { useEffect, useEffectEvent, useCallback, useMemo, useRef, useState } from \"react\";\nimport { CONFIRM_EXIT_ANIMATION_DURATION } from \"./constants\";\nimport { ConfirmContainerProps } from \"./types\";\nimport { ConfirmContext } from \"./ConfirmContext\";\n\nexport default function ConfirmContainer({\n open = false,\n size = \"md\",\n color = \"warning\",\n isLoading = false,\n closeOnOverlayClick = true,\n closeOnEsc = true,\n lockScroll = true,\n overlayClassName = \"\",\n className = \"\",\n children,\n onClose,\n ...props\n}: ConfirmContainerProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const [isExiting, setIsExiting] = useState(false);\n const exitTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleTriggerClose = useCallback(() => {\n if (isExiting || isLoading) return;\n\n setIsExiting(true);\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n exitTimerRef.current = setTimeout(() => {\n setIsExiting(false);\n onClose?.();\n }, CONFIRM_EXIT_ANIMATION_DURATION);\n }, [isExiting, isLoading, onClose]);\n\n const contextValue = useMemo(\n () => ({\n onClose: handleTriggerClose,\n isLoading,\n size,\n color,\n }),\n [handleTriggerClose, isLoading, size, color]\n );\n\n // Clear timeout exit khi unmount\n useEffect(() => {\n return () => {\n if (exitTimerRef.current) {\n clearTimeout(exitTimerRef.current);\n }\n };\n }, []);\n\n // Mở / đóng dialog\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n if (open || isExiting) {\n if (!dialog.open) {\n try {\n dialog.showModal();\n } catch { /* empty */ }\n }\n } else {\n if (dialog.open) {\n dialog.close();\n }\n }\n }, [open, isExiting]);\n\n // Lock body scroll khi mở dialog\n useEffect(() => {\n if (!lockScroll) return;\n\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n return () => {\n document.body.style.overflow = originalOverflow;\n };\n }, [lockScroll]);\n\n /**\n * Xử lý sự kiện javascript gọi phím ESC\n * Bắt sự kiện ESC trên window qua useEffectEvent.\n */\n const handleKeyDown = useEffectEvent((e: KeyboardEvent) => {\n if (!open || closeOnEsc === false) return;\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n handleTriggerClose();\n }\n });\n\n useEffect(() => {\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, []);\n\n if (!open && !isExiting) {\n return null;\n }\n\n const handleOverlayClick = () => {\n if (closeOnOverlayClick) {\n handleTriggerClose();\n }\n };\n\n const backdropAnimation = isExiting\n ? \"animate-confirm-backdrop-out pointer-events-none\"\n : \"animate-confirm-backdrop-in\";\n\n const dialogAnimation = isExiting ? \"animate-confirm-out pointer-events-none\" : \"animate-confirm-in\";\n\n return (\n <ConfirmContext.Provider value={contextValue}>\n <dialog\n ref={dialogRef}\n aria-labelledby=\"confirm-dialog-title\"\n aria-describedby=\"confirm-dialog-description\"\n onCancel={(e) => {\n e.preventDefault();\n if (closeOnEsc !== false) {\n handleTriggerClose();\n }\n }}\n className={`fixed inset-0 flex items-center justify-center p-4 bg-neutral-950/40 backdrop-blur-xs border-none m-0 max-w-none max-h-none w-screen h-screen overflow-visible backdrop:bg-transparent ${backdropAnimation} ${overlayClassName}`}\n {...props}\n >\n <div aria-hidden=\"true\" onClick={handleOverlayClick} className=\"fixed inset-0 -z-10\" />\n <div className={`w-full flex items-center justify-center pointer-events-none ${dialogAnimation} ${className}`}>\n {children}\n </div>\n </dialog>\n </ConfirmContext.Provider>\n );\n}\n","import React from \"react\";\nimport { ConfirmHeaderProps } from \"./types\";\nimport { sizeConfig, iconBadgeColorConfig, defaultIcons } from \"./constants\";\nimport CloseIcon from \"../icons/CloseIcon\";\nimport { useConfirmContext } from \"./ConfirmContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\n/**\n * Phần đầu của hộp thoại Confirm (Hiển thị icon badge, tiêu đề và nút đóng X)\n */\nexport default function ConfirmHeader({\n size,\n color,\n icon = true,\n title,\n iconClassName = \"\",\n titleClassName = \"\",\n showCloseButton = false,\n onClose,\n closeButtonClassName = \"\",\n className = \"\",\n children,\n ...props\n}: ConfirmHeaderProps) {\n const confirmContext = useConfirmContext();\n const currentSize = getSafeConfig(size ?? confirmContext?.size, sizeConfig, \"md\");\n const badgeStyle = getSafeConfig(color ?? confirmContext?.color, iconBadgeColorConfig, \"warning\");\n const isLoading = confirmContext?.isLoading;\n\n const handleClose = () => {\n onClose?.();\n confirmContext?.onClose?.();\n };\n\n const hasCloseHandler = Boolean(onClose || confirmContext?.onClose);\n\n const renderIcon = () => {\n if (icon === false) return null;\n\n if (icon !== undefined && icon !== true) {\n return (\n <div\n className={`inline-flex items-center justify-center shrink-0 ${currentSize.iconWrapper} ${badgeStyle} ${iconClassName}`}\n aria-hidden=\"true\"\n >\n {icon}\n </div>\n );\n }\n const IconComponent = getSafeConfig(color ?? confirmContext?.color, defaultIcons, \"warning\");\n return (\n <div\n className={`inline-flex items-center justify-center shrink-0 ${currentSize.iconWrapper} ${badgeStyle} ${iconClassName}`}\n aria-hidden=\"true\"\n >\n <IconComponent className={currentSize.icon} />\n </div>\n );\n };\n\n return (\n <div className={`flex items-start justify-between w-full ${currentSize.header} ${className}`} {...props}>\n <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n {renderIcon()}\n {title && (\n <h3 className={`${currentSize.title} truncate ${titleClassName}`} id=\"confirm-dialog-title\">\n {title}\n </h3>\n )}\n {children}\n </div>\n\n {showCloseButton && hasCloseHandler && (\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={isLoading}\n aria-label=\"Đóng hộp thoại\"\n className={`inline-flex items-center justify-center shrink-0 text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 rounded-md transition-colors cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 ${currentSize.closeButton} ${closeButtonClassName}`}\n >\n <CloseIcon className={currentSize.closeIcon} />\n </button>\n )}\n </div>\n );\n}\n","import { ConfirmBodyProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport { useConfirmContext } from \"./ConfirmContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\n/**\n * Phần thân của hộp thoại Confirm (Hiển thị nội dung mô tả hoặc nội dung tùy biến)\n */\nexport default function ConfirmBody({\n size,\n description,\n descriptionClassName = \"\",\n className = \"\",\n children,\n ...props\n}: ConfirmBodyProps) {\n const confirmContext = useConfirmContext();\n const currentSize = getSafeConfig(size ?? confirmContext?.size, sizeConfig, \"md\");\n\n return (\n <div\n className={`w-full ${currentSize.body} ${className}`}\n id=\"confirm-dialog-description\"\n {...props}\n >\n {description ? (\n <p className={`${currentSize.description} ${descriptionClassName}`}>{description}</p>\n ) : null}\n {children}\n </div>\n );\n}\n","import { ConfirmFooterProps } from \"./types\";\nimport { sizeConfig } from \"./constants\";\nimport Button from \"../button/Button\";\nimport { useConfirmContext } from \"./ConfirmContext\";\nimport { getSafeConfig } from \"@/utils/function\";\n\n/**\n * Phần chân của hộp thoại Confirm (Chứa các nút hành động Xác nhận, Hủy, hoặc các nút tùy chỉnh)\n */\nexport default function ConfirmFooter({\n size,\n confirmText = \"Xác nhận\",\n cancelText = \"Hủy\",\n confirmVariant = \"filled\",\n cancelVariant = \"outline\",\n confirmColor,\n cancelColor = \"secondary\",\n onConfirm,\n onCancel,\n onClose,\n confirmButtonProps,\n cancelButtonProps,\n className = \"\",\n children,\n ...props\n}: ConfirmFooterProps) {\n const confirmContext = useConfirmContext();\n const currentSize = getSafeConfig(size ?? confirmContext?.size, sizeConfig, \"md\");\n const currentConfirmColor = confirmColor ?? confirmContext?.color ?? \"warning\";\n\n\n const triggerClose = () => {\n onClose?.();\n confirmContext?.onClose?.();\n };\n\n const handleConfirm = async () => {\n try {\n const result = onConfirm?.();\n // Nếu onConfirm là Promise, nếu thành công thì mới đóng Confirm\n if (result && 'then' in result) {\n await result;\n }\n triggerClose();\n } catch { /* empty */ }\n };\n\n const handleCancel = () => {\n onCancel?.();\n triggerClose();\n };\n\n if (children) {\n return (\n <div\n className={`flex items-center justify-end w-full ${currentSize.footer} ${currentSize.buttonGap} ${className}`}\n {...props}\n >\n {children}\n </div>\n );\n }\n\n return (\n <div\n className={`flex items-center justify-end w-full ${currentSize.footer} ${currentSize.buttonGap} ${className}`}\n {...props}\n >\n {cancelText !== false && (\n <Button\n size={currentSize.buttonSize}\n variant={cancelVariant}\n color={cancelColor}\n onClick={handleCancel}\n disabled={cancelButtonProps?.disabled || confirmContext?.isLoading}\n {...cancelButtonProps}\n >\n {cancelText}\n </Button>\n )}\n\n <Button\n size={currentSize.buttonSize}\n variant={confirmVariant}\n color={currentConfirmColor}\n isLoading={confirmContext?.isLoading || confirmButtonProps?.isLoading}\n disabled={confirmButtonProps?.disabled}\n onClick={handleConfirm}\n {...confirmButtonProps}\n >\n {confirmText}\n </Button>\n </div>\n );\n}\n","import { cloneElement, isValidElement, MouseEvent, ReactElement } from \"react\";\nimport { ConfirmCloseProps } from \"./types\";\nimport { useConfirmContext } from \"./ConfirmContext\";\n\n/**\n * Component wrapper kích hoạt đóng Confirm kèm hiệu ứng thoát (Exit Animation)\n * Tự động vô hiệu hóa (`disabled`) khi `isLoading = true`.\n */\nexport default function ConfirmClose({\n children,\n asChild = true,\n onClick,\n ...props\n}: ConfirmCloseProps) {\n const confirmContext = useConfirmContext();\n const isLoading = confirmContext?.isLoading;\n\n const handleClick = (e: MouseEvent<HTMLElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) {\n confirmContext?.onClose?.();\n }\n };\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<{\n onClick?: (e: MouseEvent<HTMLElement>) => void;\n disabled?: boolean;\n }>;\n return cloneElement(child, {\n disabled: child.props.disabled || isLoading,\n onClick: (e: MouseEvent<HTMLElement>) => {\n child.props.onClick?.(e);\n handleClick(e);\n },\n ...props,\n });\n }\n\n return (\n <button type=\"button\" onClick={handleClick} disabled={isLoading} {...props}>\n {children}\n </button>\n );\n}\n"],"mappings":"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ACF,QAAS,4BACT,MAAO,sCACP,IAAK,QACL,UAAW,KACX,KAAM,WACN,MAAO,eACP,cAAe,cACf,OAAQ,oBACV,EACA,GAAI,CACF,QAAS,iCACT,MAAO,sCACP,IAAK,UACL,UAAW,KACX,KAAM,cACN,MAAO,iBACP,cAAe,cACf,OAAQ,kBACV,EACA,GAAI,CACF,QAAS,+BACT,MAAO,wCACP,IAAK,UACL,UAAW,KACX,KAAM,SACN,MAAO,mBACP,cAAe,UACf,OAAQ,cACV,EACA,GAAI,CACF,QAAS,iCACT,MAAO,sCACP,IAAK,QACL,UAAW,KACX,KAAM,SACN,MAAO,eACP,cAAe,UACf,OAAQ,cACV,CACF,EAEaC,GAAyF,CACpG,QAAS,CACP,QACE,oJACF,UACE,4JACF,MACE,4IACF,QACE,oJACF,QACE,oJACF,KAAM,wIACN,QACE,mJACJ,EAEA,OAAQ,CACN,QACE,kLACF,UACE,8LACF,QACE,kLACF,MACE,6LACF,QACE,kLACF,QACE,kLACF,KAAM,+JACR,EACA,MAAO,CACL,QACE,iLACF,UACE,yLACF,QACE,iLACF,MACE,sKACF,QACE,iLACF,QACE,iLACF,KAAM,oKACR,CACF,EAEaC,GAA+C,CAC1D,QAAS,6DACT,UAAW,iEACX,MAAO,yDACP,QAAS,6DACT,QAAS,6DACT,KAAM,uDACN,QAAS,4DACX,EAEaC,GAST,CACF,GAAI,CACF,KAAM,iBACN,KAAM,UACN,IAAK,QACL,MAAO,mBACP,OAAQ,mBACV,EACA,GAAI,CACF,KAAM,iBACN,KAAM,UACN,IAAK,UACL,MAAO,eACP,OAAQ,oBACV,EACA,GAAI,CACF,KAAM,mBACN,KAAM,0BACN,IAAK,QACL,MAAO,iBACP,OAAQ,kBACV,EACA,GAAI,CACF,KAAM,mBACN,KAAM,wBACN,IAAK,UACL,MAAO,mBACP,OAAQ,cACV,EACA,GAAI,CACF,KAAM,mBACN,KAAM,oBACN,IAAK,QACL,MAAO,eACP,OAAQ,cACV,CACF,EC/PA,IAAAC,GAA+C,iBAMxC,SAASC,GAAiBC,EAAyBC,EAAmC,CAAC,EAAG,CAC/F,GAA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KAAM,cACR,EAOaC,GAST,CACF,OAAQ,CACN,QAAS,CACP,QAAS,CACP,MACE,uJACF,MAAO,mEACT,EACA,UAAW,CACT,MACE,sMACF,MAAO,uFACT,CACF,EACA,UAAW,CACT,QAAS,CACP,MACE,6JACF,MAAO,uEACT,EACA,UAAW,CACT,MACE,wMACF,MAAO,uFACT,CACF,EACA,MAAO,CACL,QAAS,CACP,MACE,iJACF,MAAO,+DACT,EACA,UAAW,CACT,MACE,oMACF,MAAO,uFACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,uJACF,MAAO,mEACT,EACA,UAAW,CACT,MACE,sMACF,MAAO,uFACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,uJACF,MAAO,uFACT,EACA,UAAW,CACT,MACE,sMACF,MAAO,uFACT,CACF,EACA,KAAM,CACJ,QAAS,CACP,MACE,8IACF,MAAO,6DACT,EACA,UAAW,CACT,MACE,mMACF,MAAO,uFACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,uJACF,MAAO,uFACT,EACA,UAAW,CACT,MACE,sMACF,MAAO,uFACT,CACF,CACF,EACA,QAAS,CACP,QAAS,CACP,QAAS,CACP,MACE,0LACF,MAAO,iEACT,EACA,UAAW,CACT,MACE,2NACF,MAAO,iEACT,CACF,EACA,UAAW,CACT,QAAS,CACP,MACE,oMACF,MAAO,qEACT,EACA,UAAW,CACT,MACE,6NACF,MAAO,iEACT,CACF,EACA,MAAO,CACL,QAAS,CACP,MACE,gLACF,MAAO,6DACT,EACA,UAAW,CACT,MACE,yNACF,MAAO,iEACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,0LACF,MAAO,iEACT,EACA,UAAW,CACT,MACE,2NACF,MAAO,iEACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,0LACF,MAAO,+DACT,EACA,UAAW,CACT,MACE,2NACF,MAAO,iEACT,CACF,EACA,KAAM,CACJ,QAAS,CACP,MACE,2KACF,MAAO,2DACT,EACA,UAAW,CACT,MACE,wNACF,MAAO,iEACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,wLACF,MAAO,uFACT,EACA,UAAW,CACT,MACE,2NACF,MAAO,iEACT,CACF,CACF,EACA,KAAM,CACJ,QAAS,CACP,QAAS,CACP,MACE,yLACF,MAAO,iEACT,EACA,UAAW,CACT,MACE,2OACF,MAAO,uFACT,CACF,EACA,UAAW,CACT,QAAS,CACP,MACE,mMACF,MAAO,qEACT,EACA,UAAW,CACT,MACE,6OACF,MAAO,uFACT,CACF,EACA,MAAO,CACL,QAAS,CACP,MACE,+KACF,MAAO,6DACT,EACA,UAAW,CACT,MACE,yOACF,MAAO,uFACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,yLACF,MAAO,iEACT,EACA,UAAW,CACT,MACE,2OACF,MAAO,uFACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,yLACF,MAAO,+DACT,EACA,UAAW,CACT,MACE,2OACF,MAAO,uFACT,CACF,EACA,KAAM,CACJ,QAAS,CACP,MACE,0KACF,MAAO,2DACT,EACA,UAAW,CACT,MACE,wOACF,MAAO,uFACT,CACF,EACA,QAAS,CACP,QAAS,CACP,MACE,sLACF,MAAO,uFACT,EACA,UAAW,CACT,MACE,2OACF,MAAO,uFACT,CACF,CACF,CACF,ED9MU,IAAAC,GAAA,6BAvIK,SAARC,GAAwB,CAC7B,KAAAC,EACA,QAAAC,EACA,MAAAC,EACA,OAAAC,EACA,YAAAC,EACA,OAAAC,EACA,MAAAC,EACA,WAAAC,EACA,aAAAC,EACA,eAAAC,EAAiB,QACjB,UAAAC,EACA,aAAAC,EACA,WAAAC,EACA,iBAAAC,EAAmB,GACnB,eAAAC,EAAiB,GACjB,eAAAC,EAAiB,GACjB,eAAAC,EAAiB,GACjB,gBAAAC,EAAkB,GAClB,UAAAC,EAAY,GACZ,QAASC,EACT,eAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,SAAAC,EACA,QAAAC,EACA,MAAAC,EACA,GAAAC,EACA,KAAAC,EACA,IAAAC,EACA,GAAGC,CACL,EAAgB,CACd,GAAM,CACJ,WAAAC,EA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CV,QAAS,iBACT,UAAW,mBACX,QAAS,8CACT,UAAW,oCACX,WAAY,mBACZ,MAAO,iCACT,EACA,UAAW,CACT,SAAU,6DACV,QAAS,mBACT,UAAW,qBACX,QAAS,kDACT,UAAW,wCACX,WAAY,qBACZ,MAAO,qCACT,EACA,QAAS,CACP,SAAU,yDACV,QAAS,iBACT,UAAW,mBACX,QAAS,8CACT,UAAW,oCACX,WAAY,mBACZ,MAAO,iCACT,EACA,MAAO,CACL,SAAU,qDACV,QAAS,eACT,UAAW,iBACX,QAAS,0CACT,UAAW,gCACX,WAAY,iBACZ,MAAO,6BACT,EACA,QAAS,CACP,SAAU,yDACV,QAAS,iBACT,UAAW,mBACX,QAAS,8CACT,UAAW,oCACX,WAAY,mBACZ,MAAO,iCACT,EACA,QAAS,CACP,SAAU,uDACV,QAAS,iBACT,UAAW,mBACX,QAAS,8CACT,UAAW,oCACX,WAAY,mBACZ,MAAO,iCACT,EACA,KAAM,CACJ,SAAU,mDACV,QAAS,cACT,UAAW,gBACX,QAAS,wCACT,UAAW,8BACX,WAAY,gBACZ,MAAO,2BACT,CACF,EAEaC,GAGT,CACF,QAAS,CACP,QACE,oJACF,UACE,4JACF,MACE,4IACF,QACE,oJACF,QACE,oJACF,KAAM,wIACN,QACE,mJACJ,EACA,OAAQ,CACN,QACE,kLACF,UACE,8LACF,QACE,kLACF,MACE,6LACF,QACE,kLACF,QACE,kLACF,KAAM,+JACR,EACA,MAAO,CACL,QACE,iLACF,UACE,yLACF,QACE,iLACF,MACE,sKACF,QACE,iLACF,QACE,iLACF,KAAM,oKACR,EACA,MAAO,CACL,QAAS,GACT,UAAW,GACX,QAAS,GACT,MAAO,GACP,QAAS,GACT,QAAS,GACT,KAAM,EACR,CACF,EAEaC,GAAyD,CACpE,QAAS,6DACT,UAAW,iEACX,MAAO,yDACP,QAAS,6DACT,QAAS,6DACT,KAAM,uDACN,QAAS,4DACX,EC9NM,IAAAC,GAAA,6BA5ES,SAARC,GAAiC,CACtC,OAAAC,EACA,OAAAC,EACA,KAAAC,EACA,aAAAC,EACA,YAAAC,EACA,YAAAC,EACA,WAAAC,EACA,WAAAC,EACA,aAAAC,EACA,aAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,CACF,EAAyB,CACvB,IAAMC,EAAMC,GAAcF,CAAM,EAC1BG,EAAaC,EAAcN,EAAMO,GAA2B,IAAI,EAChEC,EAAcF,EAAcL,EAAOQ,GAA4B,SAAS,EAGxEC,EAAaP,EAAI,OAAOb,EAAO,SAAS,CAAC,EACzCqB,EAAQrB,EAAO,YAAY,EAC3BsB,EAAe,KAAK,MAAMD,EAAQ,EAAE,EAAI,GACxCE,EAAaD,EAAe,EAE9BE,EAAS,GAAGJ,CAAU,IAAIC,CAAK,GAC/BnB,IAAS,WAAUsB,EAAS,GAAGH,CAAK,IACpCnB,IAAS,UAASsB,EAAS,GAAGF,CAAY,MAAMC,CAAU,IAG9D,IAAME,EAAaZ,EAAI,OAAOZ,EAAO,SAAS,CAAC,EACzCyB,EAAQzB,EAAO,YAAY,EAC3B0B,EAAe,KAAK,MAAMD,EAAQ,EAAE,EAAI,GACxCE,EAAaD,EAAe,EAE9BE,EAAS,GAAGJ,CAAU,IAAIC,CAAK,GAC/BxB,IAAS,WAAU2B,EAAS,GAAGH,CAAK,IACpCxB,IAAS,UAAS2B,EAAS,GAAGF,CAAY,MAAMC,CAAU,IAE9D,IAAME,EAAmB,IAAM,CACzB5B,IAAS,OAAQC,EAAa,QAAQ,EACjCD,IAAS,SAAUC,EAAa,OAAO,EACvCD,IAAS,SAASC,EAAa,MAAM,CAChD,EAEM4B,EAAa,IAAM,CACnB7B,IAAS,OACXE,EAAY,EACHF,IAAS,SAClBI,EAAW,EACFJ,IAAS,UACdM,EACFA,EAAa,EAEbF,EAAW,EAGjB,EAEM0B,EAAa,IAAM,CACnB9B,IAAS,OACXG,EAAY,EACHH,IAAS,SAClBK,EAAW,EACFL,IAAS,UACdO,EACFA,EAAa,EAEbF,EAAW,EAGjB,EAEA,SACE,SAAC,OAAI,UAAU,4EAEb,sBAAC,OAAI,UAAU,gCACZ,UAAAL,IAAS,WACR,QAAC,UACC,KAAK,SACL,QAASI,EACT,aAAW,2BACX,UAAW,oCAAoCS,EAAW,gBAAgB,4GAE1E,oBAACkB,GAAA,CAAsB,MAAO,GAAI,OAAQ,GAAI,EAChD,KAEF,QAAC,UACC,KAAK,SACL,QAASF,EACT,aAAW,2BACX,UAAW,oCAAoChB,EAAW,gBAAgB,4GAE1E,oBAACmB,GAAA,CAAgB,MAAOnB,EAAW,SAAU,OAAQA,EAAW,SAAU,EAC5E,GACF,KAGA,SAAC,OAAI,UAAU,uEACb,qBAAC,OAAI,UAAU,mCACb,oBAAC,UACC,KAAK,SACL,QAASe,EACT,aAAW,oDACX,UAAW,wCAAwCZ,EAAY,UAAU,+EAA+EH,EAAW,UAAU,GAE5K,SAAAS,EACH,EACF,KACA,QAAC,OAAI,UAAU,mCACb,oBAAC,UACC,KAAK,SACL,QAASM,EACT,aAAW,oDACX,UAAW,wCAAwCZ,EAAY,UAAU,+EAA+EH,EAAW,UAAU,GAE5K,SAAAc,EACH,EACF,GACF,KAGA,SAAC,OAAI,UAAU,gCACb,qBAAC,UACC,KAAK,SACL,QAASG,EACT,aAAW,0BACX,UAAW,oCAAoCjB,EAAW,gBAAgB,4GAE1E,oBAACoB,GAAA,CAAiB,MAAOpB,EAAW,SAAU,OAAQA,EAAW,SAAU,EAC7E,EACCb,IAAS,WACR,QAAC,UACC,KAAK,SACL,QAASK,EACT,aAAW,0BACX,UAAW,oCAAoCQ,EAAW,gBAAgB,4GAE1E,oBAACqB,GAAA,CAAuB,MAAO,GAAI,OAAQ,GAAI,EACjD,GAEJ,GACF,CAEJ,CCzJA,IAAAC,GAA8B,uBA4GxB,IAAAC,GAAA,6BAtGS,SAARC,GAAkC,CACvC,KAAAC,EACA,aAAAC,EACA,YAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EACA,OAAAC,EACA,eAAAC,EAAiB,EACjB,gBAAAC,EAAkB,EACpB,EAA0B,CACxB,IAAMC,EAAMC,GAAcJ,CAAM,EAC1BK,EAAaC,EAAcT,EAAMU,GAA2B,IAAI,EAChEC,EAAcF,EAAcR,EAAOW,GAA4B,SAAS,EACxEC,EAAcJ,EAAcP,EAAQY,GAA6B,IAAI,EAErEC,KAAU,WAAuB,IAAI,EAGrCC,EAAW,CAAC,GAAGV,EAAI,aAAa,EACtC,GAAIF,IAAmB,EAAG,CACxB,IAAMa,EAAMD,EAAS,MAAM,EAC3BA,EAAS,KAAKC,CAAG,CACnB,CAEA,IAAMC,EAAcrB,EAAK,KAAM,IAAO,EAAE,YAAc,EAAE,eAAiB,CAAC,EAAE,UAAU,EAChFsB,EAAatB,EAAK,UAAW,GAAM,EAAE,SAAW,CAAC,EAAE,UAAU,EAC7DuB,EAAyBvB,EAAK,UAAW,GAAM,EAAE,gBAAkB,CAAC,EAAE,UAAU,EAChFwB,EAAgBD,IAA2B,GAAKA,EAAyBvB,EAAK,UAAW,GAAM,CAAC,EAAE,UAAU,EAE5GyB,EAAeC,GAAwB,CAE3C,IAAMC,EADaT,EAAQ,SAAS,iBAAoC,QAAQ,IACjDQ,CAAW,EACtCC,GAAa,CAACA,EAAU,UAC1BA,EAAU,MAAM,CAEpB,EAEMC,EAAgB,CAACC,EAA2CC,IAAyB,CACzF,IAAIJ,EAA6B,KAEjC,GAAIG,EAAE,MAAQ,aAAc,CAC1BA,EAAE,eAAe,EACjB,QAASE,EAAID,EAAe,EAAGC,EAAI/B,EAAK,OAAQ+B,IAC9C,GAAI,CAAC/B,EAAK+B,CAAC,EAAG,WAAY,CACxBL,EAAcK,EACd,KACF,CAEJ,SAAWF,EAAE,MAAQ,YAAa,CAChCA,EAAE,eAAe,EACjB,QAASE,EAAID,EAAe,EAAGC,GAAK,EAAGA,IACrC,GAAI,CAAC/B,EAAK+B,CAAC,EAAG,WAAY,CACxBL,EAAcK,EACd,KACF,CAEJ,SAAWF,EAAE,MAAQ,YACnBA,EAAE,eAAe,EACbC,EAAe,EAAI9B,EAAK,QAAU,CAACA,EAAK8B,EAAe,CAAC,EAAG,aAC7DJ,EAAcI,EAAe,WAEtBD,EAAE,MAAQ,UACnBA,EAAE,eAAe,EACbC,EAAe,GAAK,GAAK,CAAC9B,EAAK8B,EAAe,CAAC,EAAG,aACpDJ,EAAcI,EAAe,WAEtBD,EAAE,MAAQ,OAAQ,CAC3BA,EAAE,eAAe,EACjB,IAAMG,EAAWF,EAAgBA,EAAe,EAChD,QAASC,EAAIC,EAAUD,EAAIC,EAAW,GAAKD,EAAI/B,EAAK,OAAQ+B,IAC1D,GAAI,CAAC/B,EAAK+B,CAAC,EAAG,WAAY,CACxBL,EAAcK,EACd,KACF,CAEJ,SAAWF,EAAE,MAAQ,MAAO,CAC1BA,EAAE,eAAe,EACjB,IAAMI,EAAS,KAAK,IAAIjC,EAAK,OAAS,EAAG8B,EAAgBA,EAAe,EAAK,CAAC,EAC9E,QAASC,EAAIE,EAAQF,GAAKD,EAAgBA,EAAe,EAAIC,IAC3D,GAAI,CAAC/B,EAAK+B,CAAC,EAAG,WAAY,CACxBL,EAAcK,EACd,KACF,CAEJ,SAAWF,EAAE,MAAQ,SAAWA,EAAE,MAAQ,IAAK,CAC7CA,EAAE,eAAe,EACjB,IAAMK,EAAOlC,EAAK8B,CAAY,EAC1BI,GAAQ,CAACA,EAAK,YAChBjC,EAAaiC,EAAK,IAAI,EAExB,MACF,CAEIR,IAAgB,MAClBD,EAAYC,CAAW,CAE3B,EAEA,SACE,SAAC,OAAI,IAAKR,EAAS,KAAK,OAAO,aAAYT,EAAI,OAAOT,EAAK,EAAE,GAAG,OAAS,CAAC,EAAG,UAAU,SAErF,sBAAC,OAAI,KAAK,MAAM,UAAW,QAAQQ,EAAkB,cAAgB,aAAa,0BAC/E,UAAAA,MACC,QAAC,OACC,KAAK,eACL,aAAYC,EAAI,UAAY,OAC5B,UAAW,oCAAoCE,EAAW,QAAQ,qBAAqBA,EAAW,QAAQ,eAC3G,aAED,EAEDQ,EAAS,IAAKgB,MACb,QAAC,OAEC,KAAK,eACL,aAAYA,EACZ,UAAW,oCAAoCxB,EAAW,QAAQ,qBAAqBA,EAAW,QAAQ,eAEzG,SAAAwB,GALIA,CAMP,CACD,GACH,KAGA,QAAC,OAAI,KAAK,WAAW,UAAW,QAAQ3B,EAAkB,cAAgB,aAAa,mBACpF,SAAAR,EAAK,IAAI,CAACoC,EAASC,IAAU,CAC5B,IAAMC,EAAaD,EAAQ,IAAM,EAG7BE,EAAY,wCACZC,EAAoB,GAEpBJ,EAAQ,WACVG,EAAY,mDACHH,EAAQ,cAAgBA,EAAQ,YACzCG,EAAY,GAAGzB,EAAY,QAAQ,2BAC/BsB,EAAQ,cAAgBA,EAAQ,WAClCI,EAAoB,GACXJ,EAAQ,aACjBI,EAAoB,GAAG1B,EAAY,OAAO,kBACjCsB,EAAQ,aACjBI,EAAoB,GAAG1B,EAAY,OAAO,oBAEnCsB,EAAQ,WACjBG,EAAY,GAAGzB,EAAY,QAAQ,2BAC1BsB,EAAQ,WAAaA,EAAQ,gBACtCG,EAAY,GAAGzB,EAAY,OAAO,IAAIA,EAAY,SAAS,gBAC3D0B,EAAoB,GAAG1B,EAAY,OAAO,IAChCsB,EAAQ,iBAClBG,EAAY,yCAGd,IAAME,EAAaL,EAAQ,SAAW,CAACA,EAAQ,WAAa,UAAUtB,EAAY,SAAS,aAAe,GACpG4B,EAAoB,GAAGN,EAAQ,GAAG,IAAI3B,EAAI,OAAO2B,EAAQ,KAAK,CAAC,IAAIA,EAAQ,IAAI,GAE/EO,EACJ,CAACP,EAAQ,aACRA,EAAQ,YACPA,EAAQ,cACP,CAACf,GAAee,EAAQ,SAAWC,IAAUf,GAC7C,CAACD,GAAeC,IAAe,IAAMe,IAAUb,GAEpD,SACE,SAAC,GAAAoB,QAAM,SAAN,CACE,UAAApC,GAAmB8B,MAClB,SAAC,OACC,UAAW,oCAAoC3B,EAAW,QAAQ,qBAAqBA,EAAW,QAAQ,yBAC3G,cACGyB,EAAQ,YACZ,KAEF,QAAC,OACC,KAAK,WACL,gBAAeA,EAAQ,YAAcA,EAAQ,UAC7C,UAAW,6CAA6CI,CAAiB,GAEzE,oBAAC,UACC,KAAK,SACL,SAAUJ,EAAQ,WAClB,SAAUO,EAAa,EAAI,GAC3B,UAAYd,GAAMD,EAAcC,EAAGQ,CAAK,EACxC,QAAS,IAAM,CAACD,EAAQ,YAAcnC,EAAamC,EAAQ,IAAI,EAC/D,aAAc,IAAM,CAACA,EAAQ,YAAclC,IAAckC,EAAQ,IAAI,EACrE,aAAc,IAAMlC,IAAc,IAAI,EACtC,aAAYwC,EACZ,eAAcN,EAAQ,QAAU,OAAS,OACzC,gBAAeA,EAAQ,WACvB,UAAW,oCAAoCzB,EAAW,QAAQ,IAAIA,EAAW,QAAQ,IAAIK,CAAW,mIAAmIuB,CAAS,IAAIE,CAAU,GAEjQ,SAAAL,EAAQ,IACX,EACF,IA5BmBA,EAAQ,KAAK,YAAY,CA6B9C,CAEJ,CAAC,EACH,GACF,CAEJ,CC7MA,IAAAS,GAA8B,iBA0HlB,IAAAC,GAAA,6BApHG,SAARC,GAAoC,CACzC,aAAAC,EACA,cAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EACA,OAAAC,EACA,WAAAC,EACA,SAAAC,EACA,YAAAC,EACA,aAAAC,CACF,EAA4B,CAC1B,IAAMC,EAAMC,GAAcN,CAAM,EAC1BO,EAAaC,EAAcX,EAAMY,GAA2B,IAAI,EAChEC,EAAcF,EAAcV,EAAOa,GAA4B,SAAS,EACxEC,EAAcJ,EAAcT,EAAQc,GAA6B,IAAI,EAErEC,KAAU,WAAuB,IAAI,EAErCC,EAAcpB,EAAa,YAAY,EACvCqB,EAAQ,IAAI,KACZC,EAAaD,EAAM,SAAS,EAC5BE,EAAYF,EAAM,YAAY,EAE9BG,EAAgBlB,GAAcA,EAAW,YAAY,IAAMc,EAAcd,EAAW,SAAS,EAAI,GACjGmB,EAAsBD,IAAkB,GAAKA,EAAgBD,IAAcH,EAAcE,EAAa,EAEtGI,EAAeC,GAAwB,CAE3C,IAAMC,EADaT,EAAQ,SAAS,iBAAoC,QAAQ,IACjDQ,CAAW,EACtCC,GACFA,EAAU,MAAM,CAEpB,EAEMC,EAAgB,CAACC,EAA2CC,IAAyB,CACzF,IAAIJ,EAA6B,KAEjC,GAAIG,EAAE,MAAQ,aACZA,EAAE,eAAe,EACbC,EAAe,EAAIrB,EAAI,YAAY,SAAQiB,EAAcI,EAAe,WACnED,EAAE,MAAQ,YACnBA,EAAE,eAAe,EACbC,EAAe,GAAK,IAAGJ,EAAcI,EAAe,WAC/CD,EAAE,MAAQ,YACnBA,EAAE,eAAe,EACbC,EAAe,EAAIrB,EAAI,YAAY,SAAQiB,EAAcI,EAAe,WACnED,EAAE,MAAQ,UACnBA,EAAE,eAAe,EACbC,EAAe,GAAK,IAAGJ,EAAcI,EAAe,WAC/CD,EAAE,MAAQ,OACnBA,EAAE,eAAe,EACjBH,EAAc,UACLG,EAAE,MAAQ,MACnBA,EAAE,eAAe,EACjBH,EAAcjB,EAAI,YAAY,OAAS,UAC9BoB,EAAE,MAAQ,SAAWA,EAAE,MAAQ,IAAK,CAC7CA,EAAE,eAAe,EACjB7B,EAAc8B,CAAY,EAC1B,MACF,CAEIJ,IAAgB,MAClBD,EAAYC,CAAW,CAE3B,EAEA,SACE,QAAC,OACC,IAAKR,EACL,KAAK,OACL,aAAW,qBACX,UAAU,8BACV,aAAc,IAAMV,IAAe,IAAI,EAEtC,SAAAC,EAAI,YAAY,IAAI,CAACsB,EAAWC,IAAQ,CACvC,IAAMC,EAAY,IAAI,KAAKd,EAAaa,EAAK,CAAC,EACxCE,EAAQD,EAAU,QAAQ,EAC1BE,EAAQ9B,EAAa,IAAI,KAAKA,EAAW,YAAY,EAAGA,EAAW,SAAS,EAAG,CAAC,EAAE,QAAQ,EAAI,KAC9F+B,EAAQ9B,EAAW,IAAI,KAAKA,EAAS,YAAY,EAAGA,EAAS,SAAS,EAAG,CAAC,EAAE,QAAQ,EAAI,KACxF+B,EAAQ9B,EAAc,IAAI,KAAKA,EAAY,YAAY,EAAGA,EAAY,SAAS,EAAG,CAAC,EAAE,QAAQ,EAAI,KAEjG+B,EAAe,CAAC,CAACH,GAASA,IAAUD,EACpCK,EAAa,CAAC,CAACH,GAASA,IAAUF,EACpCM,EAAY,GACZC,EAAiB,GAEjBN,GAASC,EACXI,EAAYN,EAAQC,GAASD,EAAQE,EAC5BD,GAAS,CAACC,GAASC,IACxBA,EAAQF,EACVM,EAAiBP,EAAQC,GAASD,GAASG,EAClCA,EAAQF,IACjBM,EAAiBP,EAAQC,GAASD,GAASG,IAI/C,IAAMK,EAAiBpB,IAAcH,GAAeE,IAAeW,EAC7DW,EAAaX,IAAQR,EAEvBoB,EAAQ,wCACZ,OAAIN,GAAgBC,EAClBK,EAAQ,GAAG9B,EAAY,QAAQ,2BACtB0B,GAAaC,EACtBG,EAAQ,GAAG9B,EAAY,OAAO,IAAIA,EAAY,SAAS,GAC9C4B,IACTE,EAAQ,UAAU9B,EAAY,SAAS,qBAIvC,QAAC,OAEC,KAAK,WACL,gBAAewB,GAAgBC,GAAcC,EAC7C,UAAU,mCAEV,oBAAC,UACC,KAAK,SACL,SAAUG,EAAa,EAAI,GAC3B,UAAYd,GAAMD,EAAcC,EAAGG,CAAG,EACtC,QAAS,IAAMhC,EAAcgC,CAAG,EAChC,aAAc,IAAMxB,IAAeyB,CAAS,EAC5C,aAAY,GAAGF,CAAS,IAAIZ,CAAW,GACvC,UAAW,gDAAgDR,EAAW,QAAQ,IAAIK,CAAW,mIAAmI4B,CAAK,GAEpO,SAAAb,EACH,GAfKA,CAgBP,CAEJ,CAAC,EACH,CAEJ,CC1IA,IAAAc,GAA8B,iBA8HlB,IAAAC,GAAA,6BAzHG,SAARC,GAAmC,CACxC,aAAAC,EACA,aAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EACA,WAAAC,EACA,SAAAC,EACA,YAAAC,EACA,YAAAC,CACF,EAA2B,CACzB,IAAMC,EAAaC,EAAcR,EAAMS,GAA2B,IAAI,EAChEC,EAAcF,EAAcP,EAAOU,GAA4B,SAAS,EACxEC,EAAcJ,EAAcN,EAAQW,GAA6B,IAAI,EAErEC,KAAU,WAAuB,IAAI,EAErCC,EAAcjB,EAAa,YAAY,EACvCkB,EAAc,KAAK,MAAMD,EAAc,EAAE,EAAI,GAC7CE,EAAY,IAAI,KAAK,EAAE,YAAY,EAEnCC,EAAkB,CAAC,EACzB,QAASC,EAAI,EAAGA,EAAI,GAAIA,IACtBD,EAAM,KAAKF,EAAcG,CAAC,EAG5B,IAAMC,EAAejB,EAAaA,EAAW,YAAY,EAAIY,EACvDM,EAAgBH,EAAM,QAAQE,CAAY,EAC1CE,EAAaJ,EAAM,QAAQD,CAAS,EACpCM,EAAsBF,IAAkB,GAAKA,EAAgBC,IAAe,GAAKA,EAAa,EAE9FE,EAAeC,GAAwB,CAE3C,IAAMC,EADaZ,EAAQ,SAAS,iBAAoC,QAAQ,IACjDW,CAAW,EACtCC,GACFA,EAAU,MAAM,CAEpB,EAEMC,EAAgB,CAACC,EAA2CC,IAAyB,CACzF,IAAIJ,EAA6B,KAEjC,GAAIG,EAAE,MAAQ,aACZA,EAAE,eAAe,EACbC,EAAe,EAAIX,EAAM,SAAQO,EAAcI,EAAe,WACzDD,EAAE,MAAQ,YACnBA,EAAE,eAAe,EACbC,EAAe,GAAK,IAAGJ,EAAcI,EAAe,WAC/CD,EAAE,MAAQ,YACnBA,EAAE,eAAe,EACbC,EAAe,EAAIX,EAAM,SAAQO,EAAcI,EAAe,WACzDD,EAAE,MAAQ,UACnBA,EAAE,eAAe,EACbC,EAAe,GAAK,IAAGJ,EAAcI,EAAe,WAC/CD,EAAE,MAAQ,OACnBA,EAAE,eAAe,EACjBH,EAAc,UACLG,EAAE,MAAQ,MACnBA,EAAE,eAAe,EACjBH,EAAcP,EAAM,OAAS,UACpBU,EAAE,MAAQ,SAAWA,EAAE,MAAQ,IAAK,CAC7CA,EAAE,eAAe,EACjB,IAAME,EAAKZ,EAAMW,CAAY,EACzBC,IAAO,QACT/B,EAAa+B,CAAE,EAEjB,MACF,CAEIL,IAAgB,MAClBD,EAAYC,CAAW,CAE3B,EAEA,SACE,QAAC,OACC,IAAKX,EACL,KAAK,OACL,aAAW,qBACX,UAAU,8BACV,aAAc,IAAMR,IAAc,IAAI,EAErC,SAAAY,EAAM,IAAI,CAACY,EAAIC,IAAQ,CACtB,IAAMC,EAAM7B,EAAaA,EAAW,YAAY,EAAI,KAC9C8B,EAAM7B,EAAWA,EAAS,YAAY,EAAI,KAC1C8B,EAAM7B,EAAcA,EAAY,YAAY,EAAI,KAEhD8B,EAAeH,IAAQ,MAAQF,IAAOE,EACtCI,EAAaH,IAAQ,MAAQH,IAAOG,EACtCI,EAAY,GACZC,EAAiB,GAEjBN,IAAQ,MAAQC,IAAQ,KAC1BI,EAAYP,EAAKE,GAAOF,EAAKG,EACpBD,IAAQ,MAAQC,IAAQ,MAAQC,IAAQ,OAC7CA,EAAMF,EACRM,EAAiBR,EAAKE,GAAOF,GAAMI,EAC1BA,EAAMF,IACfM,EAAiBR,EAAKE,GAAOF,GAAMI,IAIvC,IAAMK,EAAgBT,IAAOb,EACvBuB,EAAaT,IAAQR,EAEvBkB,EAAQ,wCACZ,OAAIN,GAAgBC,EAClBK,EAAQ,GAAG/B,EAAY,QAAQ,2BACtB2B,GAAaC,EACtBG,EAAQ,GAAG/B,EAAY,OAAO,IAAIA,EAAY,SAAS,GAC9C6B,IACTE,EAAQ,UAAU/B,EAAY,SAAS,qBAIvC,QAAC,OAEC,KAAK,WACL,gBAAeyB,GAAgBC,GAAcC,EAC7C,UAAU,mCAEV,oBAAC,UACC,KAAK,SACL,SAAUG,EAAa,EAAI,GAC3B,UAAYZ,GAAMD,EAAcC,EAAGG,CAAG,EACtC,QAAS,IAAMhC,EAAa+B,CAAE,EAC9B,aAAc,IAAMxB,IAAc,IAAI,KAAKwB,EAAI,EAAG,CAAC,CAAC,EACpD,aAAY,GAAGA,CAAE,GACjB,UAAW,gDAAgDvB,EAAW,QAAQ,IAAIK,CAAW,mIAAmI6B,CAAK,GAEpO,SAAAX,EACH,GAfKA,CAgBP,CAEJ,CAAC,EACH,CAEJ,CC7HO,SAASY,GAAcC,EAAYC,EAAoBC,EAA2B,CACvF,GAAI,CAACD,GAAS,CAACC,EAAK,MAAO,GAC3B,IAAMC,EAAI,IAAI,KAAKH,EAAK,YAAY,EAAGA,EAAK,SAAS,EAAGA,EAAK,QAAQ,CAAC,EAAE,QAAQ,EAC1EI,EAAS,IAAI,KAAKH,EAAM,YAAY,EAAGA,EAAM,SAAS,EAAGA,EAAM,QAAQ,CAAC,EAAE,QAAQ,EAClFI,EAAO,IAAI,KAAKH,EAAI,YAAY,EAAGA,EAAI,SAAS,EAAGA,EAAI,QAAQ,CAAC,EAAE,QAAQ,EAC1EI,EAAM,KAAK,IAAIF,EAAQC,CAAI,EAC3BE,EAAM,KAAK,IAAIH,EAAQC,CAAI,EACjC,OAAOF,GAAKG,GAAOH,GAAKI,CAC1B,CAEA,SAASC,GAAeC,EAAcC,EAAuB,CAC3D,OAAO,IAAI,KAAKD,EAAMC,EAAQ,EAAG,CAAC,EAAE,QAAQ,CAC9C,CAEA,SAASC,GACPX,EACAY,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACsB,CACtB,IAAMC,EAAeN,EAAaO,GAAUrB,EAAMc,CAAU,EAAI,GAC1DQ,EAAaP,EAAWM,GAAUrB,EAAMe,CAAQ,EAAI,GACpDQ,EAAYxB,GAAcC,EAAMc,GAAc,KAAMC,GAAY,IAAI,EACpES,EAAiBV,GAAc,CAACC,GAAYC,EAAcjB,GAAcC,EAAMc,EAAYE,CAAW,EAAI,GAE3GS,EAAW,GACf,OAAIR,GAAWS,GAAa1B,EAAMiB,CAAO,IACvCQ,EAAW,IAETP,GAAWS,GAAY3B,EAAMkB,CAAO,IACtCO,EAAW,IAETN,GAAkBA,EAAenB,CAAI,IACvCyB,EAAW,IAGN,CACL,KAAAzB,EACA,IAAKA,EAAK,QAAQ,EAClB,MAAOA,EAAK,SAAS,EACrB,KAAMA,EAAK,YAAY,EACvB,eAAAY,EACA,QAASS,GAAUrB,EAAMa,CAAK,EAC9B,WAAYO,GAAgBE,EAC5B,WAAYG,EACZ,aAAAL,EACA,WAAAE,EACA,UAAAC,EACA,eAAAC,EACA,WAAYI,GAAiB5B,CAAI,CACnC,CACF,CAEO,SAAS6B,GACdpB,EACAC,EACAoB,EAAwB,EACxBhB,EACAC,EACAC,EACAC,EACAC,EACAC,EACwB,CACxB,IAAMY,EAA+B,CAAC,EAChClB,EAAQ,IAAI,KAEZmB,EAAgB,IAAI,KAAKvB,EAAMC,EAAO,CAAC,EAAE,OAAO,EAChDuB,EAAgBzB,GAAeC,EAAMC,EAAQ,CAAC,EAC9CwB,EAAmB1B,GAAeC,EAAMC,CAAK,EAE7CyB,EAAgBL,IAAmB,EAAKE,IAAkB,EAAI,EAAIA,EAAgB,EAAKA,EAE7F,QAASI,EAAID,EAAgB,EAAGC,GAAK,EAAGA,IAAK,CAC3C,IAAMC,EAAIJ,EAAgBG,EACpBpC,EAAO,IAAI,KAAKS,EAAMC,EAAQ,EAAG2B,CAAC,EACxCN,EAAK,KACHpB,GACEX,EACA,GACAa,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CACF,CACF,CACF,CAEA,QAASiB,EAAI,EAAGA,GAAKF,EAAkBE,IAAK,CAC1C,IAAMpC,EAAO,IAAI,KAAKS,EAAMC,EAAO0B,CAAC,EACpCL,EAAK,KACHpB,GACEX,EACA,GACAa,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CACF,CACF,CACF,CAEA,IAAMmB,EAAgB,GAAKP,EAAK,OAChC,QAASK,EAAI,EAAGA,GAAKE,EAAeF,IAAK,CACvC,IAAMpC,EAAO,IAAI,KAAKS,EAAMC,EAAQ,EAAG0B,CAAC,EACxCL,EAAK,KACHpB,GACEX,EACA,GACAa,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CACF,CACF,CACF,CAEA,OAAOY,CACT,CN+FgB,IAAAQ,GAAA,6BArOD,SAARC,GAAmC,CACxC,MAAAC,EACA,SAAAC,EACA,KAAAC,EAAO,OACP,aAAAC,EACA,QAAAC,EACA,QAAAC,EACA,eAAAC,EACA,OAAAC,EAAS,KACT,eAAAC,EAAiB,EACjB,gBAAAC,EAAkB,GAClB,aAAAC,EAAe,GACf,SAAAC,EAAW,CAAC,OAAQ,SAAU,OAAO,EACrC,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EACA,UAAAC,EAAY,EACd,EAA2B,CACzB,IAAMC,EAAaC,EAAcL,EAAMM,GAA2B,IAAI,EAChEC,EAAcF,EAAcH,EAAQM,GAA+B,IAAI,EAEvE,CAACC,EAAUC,CAAW,KAAI,aAAuBpB,CAAI,EACrD,CAACqB,EAAUC,CAAW,KAAI,aAAuBtB,CAAI,EAEvDA,IAASqB,IACXC,EAAYtB,CAAI,EAChBoB,EAAYpB,CAAI,GAIlB,IAAMuB,EAAmBzB,EAAQA,EAAM,CAAC,EAAI,KACtC0B,EAAiB1B,EAAQA,EAAM,CAAC,EAAI,KAGpC,CAAC2B,EAAcC,CAAe,KAAI,aAAe,IAAM,CAC3D,IAAMC,EAAOJ,GAAoB,IAAI,KACrC,OAAO,IAAI,KAAKI,EAAK,YAAY,EAAGA,EAAK,SAAS,EAAG,CAAC,CACxD,CAAC,EAGKC,EAAMC,GAAcxB,CAAM,EAC1ByB,KAAW,YAAQ,IAAM,CAC7B,IAAMC,EAAYH,EAAI,UAAY,CAChC,KAAM,UACN,OAAQ,WACR,MAAO,UACT,EACA,OAAQnB,GAAY,CAAC,OAAQ,SAAU,OAAO,GAAG,IAAKuB,IAAO,CAC3D,IAAKA,EACL,MAAOD,EAAUC,CAAC,GAAKA,CACzB,EAAE,CACJ,EAAG,CAACvB,EAAUmB,EAAI,QAAQ,CAAC,EAErBK,EAAmBC,GAAyB,CAChD,IAAMC,EAAWD,EACjBd,EAAYe,CAAQ,EACpBC,EAAuB,IAAI,EAC3BnC,IAAekC,CAAQ,CACzB,EAGME,EAAkB,IAAM,CAC5B,IAAMC,EAAO,IAAI,KAAKb,EAAa,YAAY,EAAGA,EAAa,SAAS,EAAI,EAAG,CAAC,EAChFC,EAAgBY,CAAI,CACtB,EAEMC,EAAkB,IAAM,CAC5B,IAAMC,EAAO,IAAI,KAAKf,EAAa,YAAY,EAAGA,EAAa,SAAS,EAAI,EAAG,CAAC,EAChFC,EAAgBc,CAAI,CACtB,EAEMC,EAAiB,IAAM,CAC3B,IAAMH,EAAO,IAAI,KAAKb,EAAa,YAAY,EAAI,EAAGA,EAAa,SAAS,EAAG,CAAC,EAChFC,EAAgBY,CAAI,CACtB,EAEMI,EAAiB,IAAM,CAC3B,IAAMF,EAAO,IAAI,KAAKf,EAAa,YAAY,EAAI,EAAGA,EAAa,SAAS,EAAG,CAAC,EAChFC,EAAgBc,CAAI,CACtB,EAEMG,EAAmB,IAAM,CAC7B,IAAML,EAAO,IAAI,KAAKb,EAAa,YAAY,EAAI,GAAIA,EAAa,SAAS,EAAG,CAAC,EACjFC,EAAgBY,CAAI,CACtB,EAEMM,EAAmB,IAAM,CAC7B,IAAMJ,EAAO,IAAI,KAAKf,EAAa,YAAY,EAAI,GAAIA,EAAa,SAAS,EAAG,CAAC,EACjFC,EAAgBc,CAAI,CACtB,EAGM,CAACK,EAAqBT,CAAsB,KAAI,aAAsB,IAAI,EAC1E,CAACU,EAAaC,CAAc,KAAI,aAAsB,IAAI,EAE1DC,EAAoBC,GAAe,CACvC,GAAI,CAACJ,EAEHT,EAAuBa,CAAI,EAC3BlD,IAAW,CAACkD,EAAM,IAAI,CAAC,MAClB,CAEL,IAAIC,EAAQL,EACRM,EAAMF,EACNA,EAAK,QAAQ,EAAIC,EAAM,QAAQ,IACjCA,EAAQD,EACRE,EAAMN,GAERT,EAAuB,IAAI,EAC3BrC,IAAW,CAACmD,EAAOC,CAAG,CAAC,CACzB,CACF,EAEMC,EAA2B,CAACC,EAAoBC,IAAuB,CAC3E,IAAMC,EAAkB,IAAI,KAAKF,EAAYC,EAAY,CAAC,EAE1D,GADA5B,EAAgB6B,CAAe,EAC3B/C,GAAgBR,IAAS,SAC3B,GAAI,CAAC6C,EACHT,EAAuBmB,CAAe,EACtCxD,IAAW,CAACwD,EAAiB,IAAI,CAAC,MAC7B,CACL,IAAIL,GAAQL,EACRM,GAAMI,EACNA,EAAgB,QAAQ,EAAIL,GAAM,QAAQ,IAC5CA,GAAQK,EACRJ,GAAMN,GAERT,EAAuB,IAAI,EAC3BrC,IAAW,CAACmD,GAAOC,EAAG,CAAC,CACzB,MAEA/B,EAAY,MAAM,CAEtB,EAEMoC,EAAoBC,GAAe,CACvC,IAAMF,EAAkB,IAAI,KAAKE,EAAI,EAAG,CAAC,EAEzC,GADA/B,EAAgB6B,CAAe,EAC3B/C,GAAgBR,IAAS,QAC3B,GAAI,CAAC6C,EACHT,EAAuBmB,CAAe,EACtCxD,IAAW,CAACwD,EAAiB,IAAI,CAAC,MAC7B,CACL,IAAIL,EAAQL,EACRM,GAAMI,EACNA,EAAgB,QAAQ,EAAIL,EAAM,QAAQ,IAC5CA,EAAQK,EACRJ,GAAMN,GAERT,EAAuB,IAAI,EAC3BrC,IAAW,CAACmD,EAAOC,EAAG,CAAC,CACzB,MAEA/B,EAAY,QAAQ,CAIxB,EAGMsC,GAAYC,GAAOzD,CAAO,EAC1B0D,EAAYD,GAAOxD,CAAO,EAG1B0D,GAASpC,EACTqC,MAAS,YAAQ,IACjB3C,IAAa,SACR,IAAI,KAAKM,EAAa,YAAY,EAAI,EAAGA,EAAa,SAAS,EAAG,CAAC,EAExEN,IAAa,QACR,IAAI,KAAKM,EAAa,YAAY,EAAI,GAAIA,EAAa,SAAS,EAAG,CAAC,EAEtE,IAAI,KAAKA,EAAa,YAAY,EAAGA,EAAa,SAAS,EAAI,EAAG,CAAC,EACzE,CAACA,EAAcN,CAAQ,CAAC,EAGrB4C,GAAoBlB,GAAuBtB,EAC3CyC,EAAkBnB,EAAsB,KAAOrB,EAE/CyC,KAAa,YACjB,IACEC,GACEL,GAAO,YAAY,EACnBA,GAAO,SAAS,EAChBvD,EACAyD,GACAC,EACAlB,EACAY,GACAE,EACAxD,CACF,EACF,CAACyD,GAAQvD,EAAgByD,GAAmBC,EAAiBlB,EAAaY,GAAWE,EAAWxD,CAAc,CAChH,EAEM+D,MAAa,YACjB,IACED,GACEJ,GAAO,YAAY,EACnBA,GAAO,SAAS,EAChBxD,EACAyD,GACAC,EACAlB,EACAY,GACAE,EACAxD,CACF,EACF,CAAC0D,GAAQxD,EAAgByD,GAAmBC,EAAiBlB,EAAaY,GAAWE,EAAWxD,CAAc,CAChH,EAEA,SACE,SAAC,OACC,UAAW,+EAA+Ea,CAAW,gCAAgCJ,CAAS,GAG7I,UAAAL,GAAgBsB,EAAS,OAAS,MACjC,QAAC,OAAI,UAAU,4CACb,oBAACsC,GAAA,CACC,UAAWpE,EACX,SAAUiC,EACV,KAAK,KACL,QAAQ,QACR,MAAOtB,EACP,UAAW,GACX,UAAU,SAEV,oBAAC0D,GAAA,CAAQ,UAAU,QAChB,SAAAvC,EAAS,IAAKwC,MACb,QAACC,GAAA,CAAmB,MAAOD,EAAK,IAAK,UAAU,oBAC5C,SAAAA,EAAK,OADEA,EAAK,GAEf,CACD,EACH,EACF,EACF,KAIF,QAACE,GAAA,CACC,OAAQX,GACR,OAAQC,GACR,KAAM3C,EACN,aAAcC,EACd,YAAaiB,EACb,YAAaE,EACb,WAAYE,EACZ,WAAYC,EACZ,aAAcC,EACd,aAAcC,EACd,KAAMlC,EACN,MAAOC,EACP,OAAQN,EACV,KAGA,SAAC,OAAI,UAAU,4CAEb,sBAAC,OAAI,UAAW,GAAGS,EAAW,eAAe,YAC1C,UAAAK,IAAa,WACZ,QAACsD,GAAA,CACC,KAAMR,EACN,aAAcjB,EACd,YAAaD,EACb,KAAMrC,EACN,MAAOC,EACP,OAAQC,EACR,OAAQP,EACR,eAAgBC,EAChB,gBAAiBC,EACnB,EAGDY,IAAa,aACZ,QAACuD,GAAA,CACC,aAAcb,GACd,cAAgBc,GAASvB,EAAyBS,GAAO,YAAY,EAAGc,CAAI,EAC5E,KAAMjE,EACN,MAAOC,EACP,OAAQC,EACR,OAAQP,EACR,WAAY0D,GACZ,SAAUC,EACV,YAAalB,EACb,aAAcC,EAChB,EAGD5B,IAAa,YACZ,QAACyD,GAAA,CACC,aAAcf,GACd,aAAcL,EACd,KAAM9C,EACN,MAAOC,EACP,OAAQC,EACR,WAAYmD,GACZ,SAAUC,EACV,YAAalB,EACb,YAAaC,EACf,GAEJ,KAGA,SAAC,OAAI,UAAW,GAAGjC,EAAW,eAAe,YAC1C,UAAAK,IAAa,WACZ,QAACsD,GAAA,CACC,KAAMN,GACN,aAAcnB,EACd,YAAaD,EACb,KAAMrC,EACN,MAAOC,EACP,OAAQC,EACR,OAAQP,EACR,eAAgBC,EAChB,gBAAiBC,EACnB,EAGDY,IAAa,aACZ,QAACuD,GAAA,CACC,aAAcZ,GACd,cAAgBa,GAASvB,EAAyBU,GAAO,YAAY,EAAGa,CAAI,EAC5E,KAAMjE,EACN,MAAOC,EACP,OAAQC,EACR,OAAQP,EACR,WAAY0D,GACZ,SAAUC,EACV,YAAalB,EACb,aAAcC,EAChB,EAGD5B,IAAa,YACZ,QAACyD,GAAA,CACC,aAAcd,GACd,aAAcN,EACd,KAAM9C,EACN,MAAOC,EACP,OAAQC,EACR,WAAYmD,GACZ,SAAUC,EACV,YAAalB,EACb,YAAaC,EACf,GAEJ,GACF,GACF,CAEJ,CDvHQ,IAAA8B,GAAA,6BAxNO,SAARC,GAAiC,CACtC,IAAAC,EACA,MAAOC,EACP,aAAAC,EACA,SAAAC,EACA,UAAAC,EAAY,MACZ,OAAAC,EAAS,aACT,cAAeC,EACf,YAAAC,EAAc,OACd,OAAAC,EAAS,KACT,eAAAC,EAAiB,EACjB,QAAAC,EACA,QAAAC,EACA,eAAAC,EACA,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,OAAAC,EACA,MAAAC,EACA,eAAAC,EAAiB,MACjB,YAAAC,EACA,WAAAC,EACA,aAAAC,EACA,KAAAC,EACA,GAAAC,EACA,aAAAC,EACA,SAAAC,EAAW,CAAC,OAAQ,SAAU,OAAO,EACrC,KAAMC,EACN,aAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,eACZ,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,OAAAC,EACA,UAAAC,EAAY,GACZ,iBAAAC,EAAmB,GACnB,sBAAAC,EAAwB,GACxB,eAAAC,EAAiB,GACjB,gBAAAC,EAAkB,GAClB,iBAAAC,EAAmB,EACrB,EAAyB,CACvB,GAAM,CACJ,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,UAAAC,EAAY,GACZ,YAAAC,GAAc,GACd,YAAAC,EAAc,GACd,YAAAC,GAAc,GACd,gBAAAC,GAAkB,GAClB,aAAAC,GAAe,GACf,cAAAC,EAAgB,EAClB,EAAIf,GAAU,CAAC,EACTgB,KAAc,UAAM,EACpBC,GAAU1B,GAAMyB,EAChBE,EAAgB,GAAGD,EAAO,gBAC1BE,EAAY,GAAGF,EAAO,WAEtBG,EAAmB1B,IAAmB,OACtC,CAAC2B,GAAcC,EAAe,KAAI,aAAuB/C,CAAW,EACpEgD,GAAaH,EAAmB1B,EAAiB2B,GAEjDG,GAAoBlD,GAAuBD,EAC3CoD,MAAuB,YAAQ,IAC5BC,GAAsBF,GAAmBD,EAAU,EACzD,CAACC,GAAmBD,EAAU,CAAC,EAE5BI,GAAe1D,IAAoB,OACnC,CAAC2D,EAAeC,CAAgB,KAAI,aAAoB,IAAM,CAClE,IAAMC,GAAM5D,EACZ,OAAI4D,IAAO,MAAM,QAAQA,EAAG,EACnB,CAACC,GAAOD,GAAI,CAAC,EAAGzD,CAAM,EAAG0D,GAAOD,GAAI,CAAC,EAAGzD,CAAM,CAAC,EAEjD,CAAC,KAAM,IAAI,CACpB,CAAC,EACK2D,EACJL,IAAgB1D,GAAmB,MAAM,QAAQA,CAAe,EAC5D,CAAC8D,GAAO9D,EAAgB,CAAC,EAAGI,CAAM,EAAG0D,GAAO9D,EAAgB,CAAC,EAAGI,CAAM,CAAC,EACvEuD,EAEAK,GACJD,EAAc,CAAC,GAAKA,EAAc,CAAC,EAC/B,GAAGE,GAAWF,EAAc,CAAC,EAAGP,GAAsBjD,CAAM,CAAC,GAAGJ,CAAS,GAAG8D,GAC1EF,EAAc,CAAC,EACfP,GACAjD,CACF,CAAC,GACDwD,EAAc,CAAC,EACb,GAAGE,GAAWF,EAAc,CAAC,EAAGP,GAAsBjD,CAAM,CAAC,GAAGJ,CAAS,GACzE,GAEF,CAAC+D,EAAQC,EAAS,KAAI,aAAS,EAAK,EAGpC,CACJ,KAAM,CAAE,aAAAC,GAAc,YAAAC,EAAY,EAClC,eAAAC,GACA,QAAAC,EACF,KAAI,gBAAY,CACd,UAAA3C,EACA,KAAMsC,GAAU,CAACrC,GAAY,CAACC,GAAY,CAACU,EAC3C,aAAc2B,GACd,qBAAsB,cACtB,UAAW,GACX,WAAY,IAAC,GAAAK,QAAiB,CAAC,KAAG,GAAAC,MAAe,KAAG,GAAAC,OAAgB,CAAE,QAAS,CAAE,CAAC,CAAC,CACrF,CAAC,EAEKC,MAAU,eAAWJ,GAAS,CAClC,UAAW,GACX,aAAc,EAChB,CAAC,EACKK,MAAO,YAAQL,GAAS,CAAE,KAAM,QAAS,CAAC,EAC1C,CAAE,kBAAAM,GAAmB,iBAAAC,EAAiB,KAAI,oBAAgB,CAACH,GAASC,EAAI,CAAC,EAEzE,CAAE,UAAAG,GAAW,OAAQC,EAAiB,KAAI,wBAAoBT,GAAS,CAC3E,SAAU,IACV,QAAS,CAAC,CAAE,KAAAU,EAAK,KAAO,CACtB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,GACA,KAAM,CACJ,QAAS,EACT,UAAW,8BACb,EACA,MAAO,CAAC,CAAE,KAAAA,EAAK,KAAO,CACpB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,EACF,CAAC,EAEKC,GAAW,GAAQ3C,GAAanB,GAChC+D,GAAcD,GAAW,QAAUpE,EAGnCsE,GAAaC,EAAczE,EAAM0E,GAA2B,IAAI,EAChEC,GAAcF,EAActE,EAAQyE,GAA6B,IAAI,EACrEC,GAAsBJ,EAAcxE,EAAS6E,GAA8B,SAAS,EACpFC,GAAe9E,IAAY,QAAU,GAAKwE,EAAcF,GAAaM,GAAqB,SAAS,EAEnGG,GAAW,EAAQ7B,EAAc,CAAC,EAGlC8B,GAAoBC,IAAuB,CAC1C3C,GACHE,GAAgByC,EAAI,EAEtBpE,IAAeoE,EAAI,CACrB,EAEMC,GAAqBC,IAAqB,CACzCtC,IACHE,EAAiBoC,EAAK,EAExB,GAAM,CAACC,GAAOC,EAAG,EAAIF,GAErB,GAAIC,IAASC,GAAK,CAChB,IAAMC,GAAoC,CACxClC,GAAWgC,GAAO7F,EAAQG,CAAM,EAChC0D,GAAWiC,GAAK9F,EAAQG,CAAM,CAChC,EACAL,IAAWiG,EAAe,EAEtBrD,GACFqB,GAAU,EAAK,CAEnB,CACF,EAEMiC,GAAiBC,IAAuC,CACxDxE,GAAYC,GAAYU,IACxB6D,GAAE,MAAQ,aAAeA,GAAE,MAAQ,SAAWA,GAAE,MAAQ,KAC1DA,GAAE,eAAe,EACZnC,GAAQC,GAAU,EAAI,GAClBkC,GAAE,MAAQ,UAAYnC,IAC/BmC,GAAE,eAAe,EACjBlC,GAAU,EAAK,GAEnB,EAEMmC,GAAeD,IAAqC,CACxDA,GAAE,gBAAgB,EACb3C,IACHE,EAAiB,CAAC,KAAM,IAAI,CAAC,EAE/B1D,IAAW,IAAI,EACfyB,IAAU,CACZ,EAEM4E,GAAqBrF,GAAe,GAAGsC,EAAoB,GAAGrD,CAAS,GAAGqD,EAAoB,GAE9FgD,GAAavF,IAAmB,WAChCwF,GAAexF,IAAmB,OAGlCyF,GAAc,IAAM,CACxB,GAAI,CAAC1F,EAAO,OAAO,KAEnB,IAAM2F,GAAkBzB,GACpB,2BACAG,EAAcF,GAAayB,GAAkB,SAAS,EAE1D,OAAIJ,MAEA,SAAC,SACC,QAASxD,GACT,UAAW,sJAAsJoC,GAAW,aAAa,IAAIuB,EAAe,IAAIxE,CAAc,GAE7N,UAAAnB,EACAsB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,KAKF,SAAC,SACC,QAASU,GACT,UAAW,qEAAqEoC,GAAW,KAAK,IAAIuB,EAAe,IAAIxE,CAAc,GAEpI,UAAAnB,EACAsB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,CAEJ,EAEMuE,GAAqBC,OACzB,QAAC,QACC,UAAW,8FAA8F1B,GAAW,IAAI,GACxH,cAAY,OAEX,SAAA0B,GACH,EAGIC,GAAsB,CAC1B,4BACAN,GAAe,8BAAgC,WAC/C9D,GAAc,SAAW,cACzBV,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL+E,GAAmB,CACvB,qHACA5B,GAAW,YACXG,GACAI,GACA9D,EAAW,aAAe,GAC1Bc,GAAc,SAAW,SACzBT,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL+E,GAAe,CACnB,iKACA7B,GAAW,UACXA,GAAW,aACXpD,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,SACE,SAAC,OAAI,UAAW+E,GAEb,WAACP,IAAcE,GAAY,KAE5B,SAAC,OAAI,UAAW,iBAAiB/D,GAAc,SAAW,EAAE,GAE1D,sBAAC,OACC,IAAKyB,GACJ,GAAGS,GAAkB,EACtB,UAAWmC,GAEV,UAAAR,IAAcE,GAAY,KAE3B,QAAC,SACC,IAAK3G,EACL,GAAIiD,GACJ,KAAM3B,EACN,KAAK,OACL,MAAO2C,GACP,QAAS,IAAM,CAACnC,GAAY,CAACC,GAAY,CAACU,GAAa2B,GAAW+C,IAAS,CAACA,EAAI,EAChF,UAAWd,GACX,SAAU,GACV,aAAc7E,EACd,YAAagF,GACb,SAAU1E,GAAYW,EACtB,KAAK,WACL,gBAAe0B,GAAU,CAAC1B,EAC1B,gBAAc,SACd,gBAAeU,EACf,gBAAeZ,EACf,eAAc4C,GACd,YAAW1C,EACX,gBAAeX,GAAYW,EAC3B,mBAAkBrB,GAAcC,EAAe6B,EAAgB,OAC/D,oBAAmB7B,EAAe6B,EAAgB,OAClD,UAAWgE,GACb,KAGA,SAAC,OAAI,UAAU,gDACZ,UAAAzE,GAAaC,OACZ,QAAC,OAAI,UAAU,4CAA6C,SAAAoE,MAAkB,QAACM,GAAA,EAAQ,CAAE,EAAE,EAG5F,CAAC3E,GAAaE,GAAe,CAACb,GAAY,CAACC,MAC1C,QAAC,UACC,KAAK,SACL,QAASwE,GACT,aAAW,6BACX,SAAUV,GAAW,EAAI,GACzB,cAAa,CAACA,GACd,UAAW,qOAAqOR,GAAW,IAAI,IAC7PQ,GAAW,sBAAwB,yCACrC,GAEA,oBAACwB,GAAA,CAAU,UAAU,YAAY,EACnC,KAGF,QAAC,OACC,cAAY,OACZ,UAAW,gJACTlD,EAAS,aAAe,UAC1B,GAEC,SAAA2C,MAAkB,QAACQ,GAAA,CAAgB,UAAU,YAAY,CAAE,EAC9D,GACF,GACF,EAGCtC,OACC,QAAC,mBACC,oBAAC,yBAAqB,QAASR,GAAS,MAAO,GAAO,YAAa,GACjE,oBAAC,OACC,IAAKF,GACL,GAAInB,EACJ,MAAO,CACL,GAAGoB,GACH,GAAGU,GACH,OAAQsC,GAAgB,MAC1B,EACC,GAAGxC,GAAiB,EACrB,UAAWzC,EAEX,oBAACkF,GAAA,CACC,MAAOxD,EACP,SAAUgC,GACV,KAAMzC,GACN,aAAcuC,GACd,QAASpF,EACT,QAASC,EACT,eAAgBC,EAChB,OAAQJ,EACR,eAAgBC,EAChB,gBAAiBoC,GACjB,KAAMhC,EACN,MAAOE,EACP,OAAQC,EACR,aAAc8B,GACd,SAAUrB,EACZ,EACF,EACF,EACF,KAIF,QAACgG,GAAA,CACC,GAAIvE,EACJ,WAAY9B,EACZ,aAAcC,EACd,cAAegE,GAAW,OAC1B,UAAWhD,EACb,GACF,GACF,CAEJ,CQlbA,IAAAqF,GAAsE,iBACtEA,GAYO,8BCbP,IAAAC,GAAwB,iBCKjB,IAAMC,GAkBT,CACF,GAAI,CACF,YAAa,MACb,UAAW,cACX,aAAc,OACd,KAAM,SACN,SAAU,GACV,aAAc,QACd,YAAa,OACb,aAAc,OACd,WAAY,MACZ,SAAU,cACV,WAAY,4BACZ,MAAO,mBACP,cAAe,cACf,OAAQ,mBACV,EACA,GAAI,CACF,YAAa,MACb,UAAW,UACX,aAAc,SACd,KAAM,WACN,SAAU,GACV,aAAc,MACd,YAAa,OACb,aAAc,OACd,WAAY,MACZ,SAAU,UACV,WAAY,wBACZ,MAAO,eACP,cAAe,cACf,OAAQ,oBACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,UACX,aAAc,OACd,KAAM,cACN,SAAU,GACV,aAAc,QACd,YAAa,OACb,aAAc,OACd,WAAY,MACZ,SAAU,UACV,WAAY,wBACZ,MAAO,iBACP,cAAe,cACf,OAAQ,kBACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,YACX,aAAc,SACd,KAAM,SACN,SAAU,GACV,aAAc,MACd,YAAa,OACb,aAAc,OACd,WAAY,MACZ,SAAU,YACV,WAAY,0BACZ,MAAO,mBACP,cAAe,UACf,OAAQ,cACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,UACX,aAAc,OACd,KAAM,SACN,SAAU,GACV,aAAc,QACd,YAAa,OACb,aAAc,OACd,WAAY,OACZ,SAAU,YACV,WAAY,wBACZ,MAAO,eACP,cAAe,UACf,OAAQ,cACV,CACF,EAKaC,GAA2D,CACtE,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,cACR,EAKaC,GAAyD,CACpE,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,aACR,EAKaC,GAAyD,CACpE,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,cACR,EAKaC,GAQT,CACF,QAAS,CACP,SAAU,iFACV,QAAS,8CACT,WAAY,mBACZ,SAAU,gBACZ,EACA,UAAW,CACT,SAAU,qFACV,QAAS,kDACT,WAAY,qBACZ,SAAU,kBACZ,EACA,QAAS,CACP,SAAU,iFACV,QAAS,8CACT,WAAY,mBACZ,SAAU,gBACZ,EACA,MAAO,CACL,SAAU,6EACV,QAAS,0CACT,WAAY,iBACZ,SAAU,cACZ,EACA,QAAS,CACP,SAAU,iFACV,QAAS,8CACT,WAAY,mBACZ,SAAU,gBACZ,EACA,QAAS,CACP,SAAU,+EACV,QAAS,8CACT,WAAY,mBACZ,SAAU,gBACZ,EACA,KAAM,CACJ,SAAU,2EACV,QAAS,wCACT,WAAY,gBACZ,SAAU,aACZ,CACF,EAKaC,GAAoD,CAC/D,QAAS,kEACT,UAAW,sEACX,MAAO,8DACP,QAAS,kEACT,QAAS,kEACT,KAAM,4DACN,QAAS,iEACX,EAKaC,GAGT,CACF,QAAS,CACP,QACE,oJACF,UACE,4JACF,MACE,4IACF,QACE,oJACF,QACE,oJACF,KAAM,wIACN,QACE,mJACJ,EACA,OAAQ,CACN,QACE,kLACF,UACE,8LACF,QACE,kLACF,MACE,6LACF,QACE,kLACF,QACE,kLACF,KAAM,+JACR,EACA,MAAO,CACL,QACE,iLACF,UACE,yLACF,QACE,iLACF,MACE,sKACF,QACE,iLACF,QACE,iLACF,KAAM,oKACR,CACF,EC/PO,SAASC,GAAQC,EAAqB,CAC3C,OAAOA,EAAM,GAAK,IAAIA,CAAG,GAAK,GAAGA,CAAG,EACtC,CASO,SAASC,GAAiBC,EAAa,GAAOC,EAAc,GAAc,CAC/E,OAAID,EACKC,EAAc,aAAe,UAE/BA,EAAc,WAAa,OACpC,CASO,SAASC,GAAgBJ,EAA8B,CAC5D,GAAI,CAACA,EAAK,OAAO,KACjB,GAAIA,aAAe,KACjB,OAAO,MAAMA,EAAI,QAAQ,CAAC,EAAI,KAAO,IAAI,KAAKA,CAAG,EAGnD,GAAI,OAAOA,GAAQ,SAAU,OAAO,KACpC,IAAMK,EAAML,EAAI,KAAK,EACrB,GAAI,CAACK,EAAK,OAAO,KAGjB,GAAIA,EAAI,SAAS,GAAG,EAAG,CACrB,IAAMC,EAAI,IAAI,KAAKD,CAAG,EACtB,GAAI,CAAC,MAAMC,EAAE,QAAQ,CAAC,EAAG,OAAOA,CAClC,CAGA,IAAMC,EAAY,uDACZC,EAAQH,EAAI,MAAME,CAAS,EAEjC,GAAIC,EAAO,CACT,IAAIC,EAAQ,SAASD,EAAM,CAAC,EAAI,EAAE,EAC5BE,EAAU,SAASF,EAAM,CAAC,EAAI,EAAE,EAChCG,EAAUH,EAAM,CAAC,EAAI,SAASA,EAAM,CAAC,EAAG,EAAE,EAAI,EAC9CI,EAASJ,EAAM,CAAC,GAAG,YAAY,EAOrC,GALII,IACEA,IAAW,MAAQH,EAAQ,KAAIA,GAAS,IACxCG,IAAW,MAAQH,IAAU,KAAIA,EAAQ,IAG3CA,GAAS,GAAKA,EAAQ,IAAMC,GAAW,GAAKA,EAAU,IAAMC,GAAW,GAAKA,EAAU,GAAI,CAC5F,IAAME,EAAM,IAAI,KAChB,OAAAA,EAAI,SAASJ,EAAOC,EAASC,EAAS,CAAC,EAChCE,CACT,CACF,CAEA,OAAO,IACT,CAqBO,SAASC,GAAWC,EAA+BC,EAAY,WAAoB,CACxF,GAAI,CAACD,GAAQ,MAAMA,EAAK,QAAQ,CAAC,EAAG,MAAO,GAE3C,IAAME,EAAYF,EAAK,SAAS,EAC1BL,EAAUK,EAAK,WAAW,EAC1BJ,EAAUI,EAAK,WAAW,EAE5BG,EAAUD,EAAY,GACtBC,IAAY,IAAGA,EAAU,IAC7B,IAAMN,EAAqBK,GAAa,GAAK,KAAO,KAEpD,OAAOD,EACJ,QAAQ,MAAOjB,GAAQkB,CAAS,CAAC,EACjC,QAAQ,KAAM,GAAGA,CAAS,EAAE,EAC5B,QAAQ,MAAOlB,GAAQmB,CAAO,CAAC,EAC/B,QAAQ,KAAM,GAAGA,CAAO,EAAE,EAC1B,QAAQ,MAAOnB,GAAQW,CAAO,CAAC,EAC/B,QAAQ,KAAM,GAAGA,CAAO,EAAE,EAC1B,QAAQ,MAAOX,GAAQY,CAAO,CAAC,EAC/B,QAAQ,KAAM,GAAGA,CAAO,EAAE,EAC1B,QAAQ,KAAMC,CAAM,EACpB,QAAQ,KAAMA,EAAO,YAAY,CAAC,CACvC,CAQO,SAASO,GAAaJ,EAA+B,CAC1D,GAAI,CAACA,EACH,MAAO,CAAE,MAAO,EAAG,QAAS,EAAG,QAAS,EAAG,OAAQ,IAAK,EAE1D,IAAME,EAAYF,EAAK,SAAS,EAChC,MAAO,CACL,MAAOE,EACP,QAASF,EAAK,WAAW,EACzB,QAASA,EAAK,WAAW,EACzB,OAAQE,GAAa,GAAK,KAAO,IACnC,CACF,CAUO,SAASG,GAAmBX,EAAeC,EAAiBC,EAAU,EAAS,CACpF,IAAML,EAAI,IAAI,KACd,OAAAA,EAAE,SAASG,EAAOC,EAASC,EAAS,CAAC,EAC9BL,CACT,CAUO,SAASe,GAAWC,EAAiBC,EAAiBC,EAAe,GAAe,CACzF,MAAI,CAACF,GAAM,CAACC,EAAW,GACnBC,EAEAF,EAAG,SAAS,IAAMC,EAAG,SAAS,GAC9BD,EAAG,WAAW,IAAMC,EAAG,WAAW,GAClCD,EAAG,WAAW,IAAMC,EAAG,WAAW,EAG/BD,EAAG,SAAS,IAAMC,EAAG,SAAS,GAAKD,EAAG,WAAW,IAAMC,EAAG,WAAW,CAC9E,CASO,SAASE,GAAaC,EAAoBC,EAA6B,CAC5E,GAAI,CAACD,GAAS,CAACC,EAAO,MAAO,GAC7B,IAAMC,EAAKF,EAAM,SAAS,EAAI,KAAOA,EAAM,WAAW,EAAI,GAAKA,EAAM,WAAW,EAC1EG,EAAKF,EAAM,SAAS,EAAI,KAAOA,EAAM,WAAW,EAAI,GAAKA,EAAM,WAAW,EAChF,OAAOC,EAAKC,CACd,CASO,SAASC,GAAYJ,EAAoBC,EAA6B,CAC3E,GAAI,CAACD,GAAS,CAACC,EAAO,MAAO,GAC7B,IAAMC,EAAKF,EAAM,SAAS,EAAI,KAAOA,EAAM,WAAW,EAAI,GAAKA,EAAM,WAAW,EAC1EG,EAAKF,EAAM,SAAS,EAAI,KAAOA,EAAM,WAAW,EAAI,GAAKA,EAAM,WAAW,EAChF,OAAOC,EAAKC,CACd,CAiBO,SAASE,GACdC,EACAhC,EACAiC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACS,CACT,GAAIP,IAAS,QAGX,GAFIK,IAAgB,EAAE,SAASrC,CAAG,GAC9BmC,GAAWnC,EAAMmC,EAAQ,SAAS,GAClCC,GAAWpC,EAAMoC,EAAQ,SAAS,EAAG,MAAO,WACvCJ,IAAS,UAQlB,GAPIM,IAAkBL,CAAY,EAAE,SAASjC,CAAG,GAC5CmC,IACEF,EAAeE,EAAQ,SAAS,GAChCF,IAAiBE,EAAQ,SAAS,GAAKnC,EAAMmC,EAAQ,WAAW,IAIlEC,IACEH,EAAeG,EAAQ,SAAS,GAChCH,IAAiBG,EAAQ,SAAS,GAAKpC,EAAMoC,EAAQ,WAAW,GAClE,MAAO,WAGFJ,IAAS,WACdO,IAAkBN,EAAcC,CAAc,EAAE,SAASlC,CAAG,GAG5DmC,IACEF,EAAeE,EAAQ,SAAS,GAChCF,IAAiBE,EAAQ,SAAS,GAAKD,EAAiBC,EAAQ,WAAW,GAI7EF,IAAiBE,EAAQ,SAAS,GAClCD,IAAmBC,EAAQ,WAAW,GACtCnC,EAAMmC,EAAQ,WAAW,IAKzBC,IACEH,EAAeG,EAAQ,SAAS,GAChCH,IAAiBG,EAAQ,SAAS,GAAKF,EAAiBE,EAAQ,WAAW,GAI7EH,IAAiBG,EAAQ,SAAS,GAClCF,IAAmBE,EAAQ,WAAW,GACtCpC,EAAMoC,EAAQ,WAAW,IAEzB,MAAO,GAKb,MAAO,EACT,CCnRA,IAAAI,GAAyC,iBAwI/B,IAAAC,GAAA,6BA/HK,SAARC,GAA4B,CACjC,MAAAC,EACA,cAAAC,EACA,SAAAC,EACA,UAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EACA,UAAAC,EAAY,GACZ,cAAAC,EAAgB,GAChB,sBAAAC,EAAwB,EAC1B,EAAoB,CAClB,IAAMC,KAAe,WAAyB,IAAI,EAC5CC,KAAc,WAAsB,IAAI,EAExCC,EAAaC,EAAcT,EAAMU,GAAsB,IAAI,EAC3DC,EAAcF,EAAcR,EAAOW,GAAuB,SAAS,EACnEC,EAAkBJ,EAAcP,EAAQY,GAAsB,IAAI,EAElEC,EAAoBnB,EAAM,UAAWoB,GAAS,CAACA,EAAK,QAAQ,EAC5DC,EAAerB,EAAM,KAAMoB,GAASA,EAAK,QAAUnB,CAAa,KAGtE,cAAU,IAAM,CACd,GAAIU,EAAY,SAAWD,EAAa,QAAS,CAC/C,IAAMY,EAAYZ,EAAa,QACzBa,EAASZ,EAAY,QACrBa,EACJD,EAAO,UAAYD,EAAU,WAAaA,EAAU,aAAeC,EAAO,cAAgB,EAE5FD,EAAU,SAAS,CACjB,IAAK,KAAK,IAAI,EAAGE,CAAM,EACvB,SAAU,QACZ,CAAC,EAGGF,EAAU,SAAS,SAAS,aAAa,GAC3CC,EAAO,MAAM,CAEjB,CACF,EAAG,CAACtB,CAAa,CAAC,EAElB,IAAMwB,EAAkBC,GAAwB,CAC9C,IAAMC,EAAa3B,EAAM0B,CAAW,EACpC,GAAI,CAACC,GAAcA,EAAW,SAAU,OACxCzB,EAASyB,EAAW,KAAK,EACVjB,EAAa,SAAS,SAASgB,CAAW,GACjD,MAAM,CAChB,EAEME,EAAgB,CAACC,EAAuCC,IAAyB,CAErF,GADqB9B,EAAM,OAAQoB,GAAS,CAACA,EAAK,QAAQ,EACxC,QAElB,GAAIS,EAAE,MAAQ,YAAa,CACzBA,EAAE,eAAe,EAEjB,QAASE,EAAID,EAAe,EAAGC,EAAI/B,EAAM,OAAQ+B,IAC/C,GAAI,CAAC/B,EAAM+B,CAAC,EAAG,SAAU,CACvBN,EAAeM,CAAC,EAChB,KACF,CAEJ,SAAWF,EAAE,MAAQ,UAAW,CAC9BA,EAAE,eAAe,EAEjB,QAASE,EAAID,EAAe,EAAGC,GAAK,EAAGA,IACrC,GAAI,CAAC/B,EAAM+B,CAAC,EAAG,SAAU,CACvBN,EAAeM,CAAC,EAChB,KACF,CAEJ,SAAWF,EAAE,MAAQ,aACnBA,EAAE,eAAe,EACDnB,EAAa,SAAS,oBACd,cACtB,6DACF,GACQ,MAAM,UACLmB,EAAE,MAAQ,YACnBA,EAAE,eAAe,EACDnB,EAAa,SAAS,wBACd,cACtB,6DACF,GACQ,MAAM,UACLmB,EAAE,MAAQ,OAAQ,CAC3BA,EAAE,eAAe,EACjB,IAAMG,EAAWhC,EAAM,UAAWoB,GAAS,CAACA,EAAK,QAAQ,EACrDY,IAAa,IACfP,EAAeO,CAAQ,CAE3B,SAAWH,EAAE,MAAQ,MAAO,CAC1BA,EAAE,eAAe,EACjB,QAASE,EAAI/B,EAAM,OAAS,EAAG+B,GAAK,EAAGA,IACrC,GAAI,CAAC/B,EAAM+B,CAAC,EAAG,SAAU,CACvBN,EAAeM,CAAC,EAChB,KACF,CAEJ,SAAWF,EAAE,MAAQ,SAAWA,EAAE,MAAQ,IAAK,CAC7CA,EAAE,eAAe,EACjB,IAAMT,EAAOpB,EAAM8B,CAAY,EAC3BV,GAAQ,CAACA,EAAK,UAChBK,EAAeK,CAAY,CAE/B,EACF,EAEA,SACE,QAAC,MACC,IAAKpB,EACL,KAAK,UACL,aAAYP,EACZ,SAAU,GACV,UAAW,sDAAsDS,EAAW,WAAW,IAAIA,EAAW,YAAY,yGAAyGL,CAAS,GACpO,MAAO,CACL,eAAgB,OAChB,gBAAiB,MACnB,EAEC,SAAAP,EAAM,IAAI,CAACoB,EAAMa,IAAU,CAC1B,IAAMC,EAAajC,IAAkBmB,EAAK,MACpCe,EAAa,EAAQf,EAAK,SAC1BgB,EAAa,CAACD,IAAeD,GAAe,CAACb,GAAgBY,IAAUd,GAE7E,SACE,QAAC,MAEC,IAAKe,EAAavB,EAAc,OAChC,KAAK,SACL,gBAAeuB,EACf,gBAAeC,EACf,aAAY,GAAGf,EAAK,KAAK,IAAIjB,GAAa,EAAE,GAAG,KAAK,EACpD,SAAUiC,EAAa,EAAI,GAC3B,UAAYP,GAAMD,EAAcC,EAAGI,CAAK,EACxC,QAAS,IAAM,CACRE,GACHV,EAAeQ,CAAK,CAExB,EACA,UAAW,mKAAmKhB,CAAe,IAC3LL,EAAW,UACb,IAAIA,EAAW,QAAQ,IACrBuB,EACI,iDACAD,EACE,GAAGnB,EAAY,QAAQ,mBAAmBN,CAAqB,GAC/D,oBAAoBM,EAAY,OAAO,iBAC/C,IAAIP,CAAa,GAEhB,SAAAY,EAAK,OAvBD,GAAGA,EAAK,KAAK,EAwBpB,CAEJ,CAAC,EACH,CAEJ,CHsEQ,IAAAiB,GAAA,6BA1NO,SAARC,GAA0B,CAC/B,MAAAC,EACA,SAAAC,EACA,UAAAC,EAAY,gBACZ,WAAAC,EAAa,GACb,YAAAC,EAAc,GACd,SAAAC,EAAW,EACX,WAAAC,EAAa,EACb,WAAAC,EAAa,EACb,QAASC,EACT,QAASC,EACT,cAAAC,EACA,gBAAAC,EACA,gBAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EACA,UAAAC,EAAY,EACd,EAAkB,CAChB,IAAMC,KAAU,YAAQ,IAAMC,GAAgBV,CAAa,EAAG,CAACA,CAAa,CAAC,EACvEW,KAAU,YAAQ,IAAMD,GAAgBT,CAAa,EAAG,CAACA,CAAa,CAAC,EAEvEW,EAAgBC,GAAiBlB,EAAYC,CAAW,EAExDkB,EAAcC,EAAcR,EAAQS,GAAsB,IAAI,EAC9DC,EAAaF,EAAcV,EAAMa,GAAsB,IAAI,EAG3DC,EAAgB3B,EAAQA,EAAM,SAAS,EAAI,EAC3C4B,EAAgBD,EAAgB,KAAO,EAAI,GAAKA,EAAgB,GAChEE,EAAgB7B,EAAQA,EAAM,WAAW,EAAI,EAC7C8B,EAAgB9B,EAAQA,EAAM,WAAW,EAAI,EAC7C+B,EAA4BJ,GAAiB,GAAK,KAAO,KAGzDK,KAAY,YAAQ,IAAM,CAC9B,IAAMC,EAAQ,CAAC,EACf,GAAI9B,EACF,QAAS+B,EAAI,EAAGA,GAAK,GAAIA,GAAK7B,EAAU,CACtC,IAAM8B,EACJJ,IAAkB,KAAQG,IAAM,GAAK,GAAKA,EAAI,GAAMA,IAAM,GAAK,EAAIA,EAE/DE,EAAWC,GACf,OACAF,EACAR,EACAE,EACAZ,EACAE,EACAT,EACAC,EACAC,CACF,EAEAqB,EAAM,KAAK,CACT,MAAOC,EACP,MAAOI,GAAQJ,CAAC,EAChB,SAAAE,CACF,CAAC,CACH,KAEA,SAASF,EAAI,EAAGA,EAAI,GAAIA,GAAK7B,EAAU,CACrC,IAAM+B,EAAWC,GACf,OACAH,EACAP,EACAE,EACAZ,EACAE,EACAT,EACAC,EACAC,CACF,EAEAqB,EAAM,KAAK,CACT,MAAOC,EACP,MAAOI,GAAQJ,CAAC,EAChB,SAAAE,CACF,CAAC,CACH,CAEF,OAAOH,CACT,EAAG,CACD9B,EACAE,EACA0B,EACAJ,EACAE,EACAZ,EACAE,EACAT,EACAC,EACAC,CACF,CAAC,EAGK2B,KAAc,YAAQ,IAAM,CAChC,IAAMN,EAAQ,CAAC,EACf,QAASO,EAAI,EAAGA,EAAI,GAAIA,GAAKlC,EAAY,CACvC,IAAM8B,EAAWC,GACf,SACAG,EACAb,EACAE,EACAZ,EACAE,EACAT,EACAC,EACAC,CACF,EAEAqB,EAAM,KAAK,CACT,MAAOO,EACP,MAAOF,GAAQE,CAAC,EAChB,SAAAJ,CACF,CAAC,CACH,CACA,OAAOH,CACT,EAAG,CACD3B,EACAqB,EACAE,EACAZ,EACAE,EACAT,EACAC,EACAC,CACF,CAAC,EAGK6B,KAAc,YAAQ,IAAM,CAChC,GAAI,CAACrC,EAAa,MAAO,CAAC,EAC1B,IAAM6B,EAAQ,CAAC,EACf,QAASS,EAAI,EAAGA,EAAI,GAAIA,GAAKnC,EAAY,CACvC,IAAM6B,EAAWC,GACf,SACAK,EACAf,EACAE,EACAZ,EACAE,EACAT,EACAC,EACAC,CACF,EAEAqB,EAAM,KAAK,CACT,MAAOS,EACP,MAAOJ,GAAQI,CAAC,EAChB,SAAAN,CACF,CAAC,CACH,CACA,OAAOH,CACT,EAAG,CACD7B,EACAG,EACAoB,EACAE,EACAZ,EACAE,EACAT,EACAC,EACAC,CACF,CAAC,EAGK+B,KAAc,YAClB,IAAM,CACJ,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,KAAM,MAAO,IAAK,CAC7B,EACA,CAAC,CACH,EAGMC,EAAoBC,GAAyB,CACjD,IAAIC,EAAU,OAAOD,CAAG,EACpB1C,IACE4B,IAAkB,MAAQe,EAAU,KAAIA,GAAW,IACnDf,IAAkB,MAAQe,IAAY,KAAIA,EAAU,IAE1D,IAAMC,EAAUC,GAAmBF,EAASjB,EAAeC,CAAa,EACxE7B,IAAW8C,CAAO,CACpB,EAEME,EAAsBJ,GAAyB,CACnD,IAAMK,EAAY,OAAOL,CAAG,EACtBE,EAAUC,GAAmBrB,EAAeuB,EAAWpB,CAAa,EAC1E7B,IAAW8C,CAAO,CACpB,EAEMI,EAAsBN,GAAyB,CACnD,IAAMO,EAAY,OAAOP,CAAG,EACtBE,EAAUC,GAAmBrB,EAAeE,EAAeuB,CAAS,EAC1EnD,IAAW8C,CAAO,CACpB,EAEMM,EAAsBR,GAAyB,CACnD,IAAMS,EAAIT,EACNU,EAAU5B,EACV2B,IAAM,MAAQC,GAAW,GAC3BA,GAAW,GACFD,IAAM,MAAQC,EAAU,KACjCA,GAAW,IAEb,IAAMR,EAAUC,GAAmBO,EAAS1B,EAAeC,CAAa,EACxE7B,IAAW8C,CAAO,CACpB,EAEMS,EAAoBpD,EAAc,WAAa,QAErD,SACE,SAAC,OACC,aAAYF,EACZ,UAAW,2GAA2GoB,CAAW,IAAIN,CAAS,GAG9I,qBAAC,OAAI,UAAU,0FACb,oBAAC,QAAK,UAAW,6CAA6CS,EAAW,UAAU,GAChF,SAAAzB,EAAQyD,GAAWzD,EAAOoB,CAAa,EAAIoC,EAC9C,EACF,KAGA,SAAC,OAAI,UAAW,oCAAoC/B,EAAW,YAAY,GAEzE,qBAACiC,GAAA,CACC,UAAU,WACV,MAAO1B,EACP,cAAe7B,EAAayB,EAAgB5B,EAAQ2B,EAAgB,KACpE,SAAUiB,EACV,KAAM/B,EACN,MAAOC,EACP,OAAQC,EACV,KAGA,QAAC2C,GAAA,CACC,UAAU,UACV,MAAOnB,EACP,cAAevC,EAAQ6B,EAAgB,KACvC,SAAUoB,EACV,KAAMpC,EACN,MAAOC,EACP,OAAQC,EACV,EAGCX,MACC,QAACsD,GAAA,CACC,UAAU,UACV,MAAOjB,EACP,cAAezC,EAAQ8B,EAAgB,KACvC,SAAUqB,EACV,KAAMtC,EACN,MAAOC,EACP,OAAQC,EACV,EAIDZ,MACC,QAACuD,GAAA,CACC,UAAU,YACV,MAAOf,EACP,cAAe3C,EAAQ+B,EAAgB,KACvC,SAAUsB,EACV,KAAMxC,EACN,MAAOC,EACP,OAAQC,EACV,GAEJ,GACF,CAEJ,CDtFQ,IAAA4C,GAAA,6BAjLO,SAARC,GAA4B,CACjC,IAAAC,EACA,MAAOC,EACP,aAAAC,EACA,SAAAC,EACA,OAAAC,EAAS,WACT,cAAeC,EACf,WAAAC,EAAa,GACb,YAAAC,EAAc,GACd,SAAAC,EAAW,EACX,WAAAC,EAAa,EACb,WAAAC,EAAa,EACb,QAAAC,EACA,QAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,gBAAAC,EACA,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,OAAAC,EACA,MAAAC,EACA,eAAAC,EAAiB,MACjB,YAAAC,EACA,WAAAC,EACA,aAAAC,EACA,KAAAC,EACA,GAAAC,EACA,aAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,eACZ,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,OAAAC,EACA,UAAAC,EAAY,GACZ,iBAAAC,EAAmB,GACnB,sBAAAC,EAAwB,GACxB,eAAAC,EAAiB,GACjB,gBAAAC,EAAkB,GAClB,iBAAAC,EAAmB,EACrB,EAAoB,CAClB,GAAM,CACJ,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,UAAAC,EAAY,GACZ,YAAAC,GAAc,GACd,YAAAC,EAAc,GACd,YAAAC,GAAc,GACd,cAAAC,GAAgB,EAClB,EAAIb,GAAU,CAAC,EAETc,MAAc,UAAM,EACpBC,EAAUrB,GAAMoB,GAChBE,EAAgB,GAAGD,CAAO,gBAC1BE,GAAY,GAAGF,CAAO,WAEtBG,EAAaC,GAAiB7C,EAAYC,CAAW,EACrD6C,EAAiBhD,GAAU8C,EAC3BG,EAAoBhD,GAAuB+C,EAE3CE,GAAerD,IAAoB,OACnC,CAACsD,GAAcC,EAAe,KAAI,aAAsB,IAAMC,GAAgBvD,CAAY,CAAC,EAC3FwD,GAAeJ,GAAeG,GAAgBxD,CAAe,EAAIsD,GACjEI,GAAiBD,GAAeE,GAAWF,GAAcL,CAAiB,EAAI,GAE9E,CAACQ,GAAQC,CAAS,KAAI,aAAS,EAAK,EAEpC,CACJ,KAAM,CAAE,aAAAC,EAAc,YAAAC,CAAY,EAClC,eAAAC,GACA,QAAAC,CACF,KAAI,gBAAY,CACd,UAAArC,EACA,KAAMgC,IAAU,CAAC/B,GAAY,CAACC,GAAY,CAACU,EAC3C,aAAcqB,EACd,qBAAsB,cACtB,UAAW,GACX,WAAY,IAAC,GAAAK,QAAiB,CAAC,KAAG,GAAAC,MAAe,KAAG,GAAAC,OAAgB,CAAE,QAAS,CAAE,CAAC,CAAC,CACrF,CAAC,EAEKC,MAAU,eAAWJ,EAAS,CAClC,UAAW,GACX,aAAc,EAChB,CAAC,EACKK,MAAO,YAAQL,EAAS,CAAE,KAAM,QAAS,CAAC,EAC1C,CAAE,kBAAAM,GAAmB,iBAAAC,EAAiB,KAAI,oBAAgB,CAACH,GAASC,EAAI,CAAC,EAEzE,CAAE,UAAAG,GAAW,OAAQC,EAAiB,KAAI,wBAAoBT,EAAS,CAC3E,SAAU,IACV,QAAS,CAAC,CAAE,KAAAU,EAAK,KAAO,CACtB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,GACA,KAAM,CACJ,QAAS,EACT,UAAW,8BACb,EACA,MAAO,CAAC,CAAE,KAAAA,EAAK,KAAO,CACpB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,EACF,CAAC,EAEKC,GAAW,GAAQrC,GAAahB,GAChCsD,GAAcD,GAAW,QAAU3D,EAGnC6D,GAAaC,EAAchE,EAAMiE,GAAsB,IAAI,EAC3DC,GAAcF,EAAc7D,EAAQgE,GAAwB,IAAI,EAChEC,GACJnE,IAAY,QACR,GACA+D,EAAcF,GAAaE,EAAc/D,EAASoE,GAAyB,SAAS,EAAG,SAAS,EAEhGC,GAAW,EAAQ5B,GAEnB6B,GAAoBC,IAAsB,CACzClC,IACHE,GAAgBgC,EAAI,EAEtB,IAAMC,GAAkBD,GAAO5B,GAAW4B,GAAMpC,CAAc,EAAI,GAClEjD,IAAWsF,EAAe,EAEtB5C,IACFiB,EAAU,EAAK,CAEnB,EAEM4B,GAAiBC,IAAuC,CACxD7D,GAAYC,GAAYU,IACxBkD,GAAE,MAAQ,aAAeA,GAAE,MAAQ,SAAWA,GAAE,MAAQ,KAC1DA,GAAE,eAAe,EACZ9B,IAAQC,EAAU,EAAI,GAClB6B,GAAE,MAAQ,UAAY9B,KAC/B8B,GAAE,eAAe,EACjB7B,EAAU,EAAK,GAEnB,EAEM8B,GAAeD,IAAqC,CACxDA,GAAE,gBAAgB,EACbrC,IACHE,GAAgB,IAAI,EAEtBrD,IAAW,IAAI,EACfyB,IAAU,CACZ,EAEMiE,GAAqBvE,GAAe+B,EAEpCyC,GAAazE,IAAmB,WAChC0E,GAAe1E,IAAmB,OAGlC2E,GAAc,IAAM,CACxB,GAAI,CAAC5E,EAAO,OAAO,KAEnB,IAAM6E,GAAkBpB,GACpB,2BACAG,EAAcF,GAAaoB,GAAkB,SAAS,EAE1D,OAAIJ,MAEA,SAAC,SACC,QAAS/C,EACT,UAAW,sJAAsJgC,GAAW,aAAa,IAAIkB,EAAe,IAAI7D,CAAc,GAE7N,UAAAhB,EACAmB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,KAKF,SAAC,SACC,QAASQ,EACT,UAAW,qEAAqEgC,GAAW,KAAK,IAAIkB,EAAe,IAAI7D,CAAc,GAEpI,UAAAhB,EACAmB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,CAEJ,EAEM4D,GAAqBC,OACzB,QAAC,QACC,UAAW,8FAA8FrB,GAAW,IAAI,GACxH,cAAY,OAEX,SAAAqB,GACH,EAGIC,GAAsB,CAC1B,iCACAN,GAAe,8BAAgC,WAC/CnD,GAAc,SAAW,cACzBV,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELoE,GAAmB,CACvB,qHACAvB,GAAW,YACXG,GACAE,GACAtD,EAAW,aAAe,GAC1Bc,GAAc,SAAW,SACzBT,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELoE,GAAe,CACnB,iKACAxB,GAAW,UACXA,GAAW,aACX9C,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,SACE,SAAC,OAAI,UAAWoE,GAEb,WAACP,IAAcE,GAAY,KAE5B,SAAC,OAAI,UAAW,iBAAiBpD,GAAc,SAAW,EAAE,GAE1D,sBAAC,OAAI,IAAKmB,EAAe,GAAGS,GAAkB,EAAG,UAAW8B,GACzD,UAAAR,IAAcE,GAAY,KAE3B,QAAC,SACC,IAAKhG,EACL,GAAI+C,EACJ,KAAMtB,EACN,KAAK,OACL,MAAOkC,GACP,QAAS,IAAM,CAAC7B,GAAY,CAACC,GAAY,CAACU,GAAaqB,EAAW0C,IAAS,CAACA,EAAI,EAChF,UAAWd,GACX,SAAU,GACV,aAAc/D,EACd,YAAakE,GACb,SAAU/D,GAAYW,EACtB,KAAK,WACL,gBAAeoB,IAAU,CAACpB,EAC1B,gBAAc,SACd,gBAAeQ,GACf,gBAAeV,EACf,eAAcsC,GACd,YAAWpC,EACX,gBAAeX,GAAYW,EAC3B,mBAAkBlB,GAAcC,EAAewB,EAAgB,OAC/D,oBAAmBxB,EAAewB,EAAgB,OAClD,UAAWuD,GACb,KAGA,SAAC,OAAI,UAAU,gDACZ,UAAA9D,GAAaC,OACZ,QAAC,OAAI,UAAU,4CAA6C,SAAAyD,MAAkB,QAACM,GAAA,EAAQ,CAAE,EAAE,EAG5F,CAAChE,GAAaE,GAAe,CAACb,GAAY,CAACC,MAC1C,QAAC,UACC,KAAK,SACL,QAAS6D,GACT,aAAW,wBACX,SAAUN,GAAW,EAAI,GACzB,cAAa,CAACA,GACd,UAAW,qOAAqOP,GAAW,IAAI,IAC7PO,GAAW,sBAAwB,yCACrC,GAEA,oBAACoB,GAAA,CAAU,UAAU,YAAY,EACnC,KAGF,QAAC,OACC,cAAY,OACZ,UAAW,gJACT7C,GAAS,aAAe,UAC1B,GAEC,SAAAsC,MAAkB,QAACQ,GAAA,CAAgB,UAAU,YAAY,CAAE,EAC9D,GACF,GACF,EAGCjC,OACC,QAAC,mBACC,oBAAC,yBAAqB,QAASR,EAAS,MAAO,GAAO,YAAa,GACjE,oBAAC,OACC,IAAKF,EACL,GAAIf,GACJ,MAAO,CACL,GAAGgB,GACH,GAAGU,GACH,OAAQiC,GAAgB,MAC1B,EACC,GAAGnC,GAAiB,EACrB,UAAWnC,EAEX,oBAACuE,GAAA,CACC,MAAOnD,GACP,SAAU6B,GACV,UAAW,OAAOnE,GAAU,SAAW,GAAGA,CAAK,YAAc,gBAC7D,WAAYd,EACZ,YAAaC,EACb,SAAUC,EACV,WAAYC,EACZ,WAAYC,EACZ,QAASC,EACT,QAASC,EACT,cAAeC,EACf,gBAAiBC,EACjB,gBAAiBC,EACjB,KAAMC,EACN,MAAOE,EACP,OAAQC,EACV,EACF,EACF,EACF,KAIF,QAAC2F,GAAA,CACC,GAAI9D,EACJ,WAAYzB,EACZ,aAAcC,EACd,cAAeuD,GAAW,OAC1B,UAAW1C,EACb,GACF,GACF,CAEJ,CKvYA,IAAA0E,GAA+E,iBAC/EA,GAYO,8BCIA,IAAMC,GAA4BC,GAK5BC,GAA8BC,GAK9BC,GAA4BC,GAUlC,IAAMC,GAA+BC,GAK/BC,GAAyD,CACpE,QAAS,uEACT,UAAW,2EACX,MAAO,mEACP,QAAS,uEACT,QAAS,uEACT,KAAM,iEACN,QAAS,sEACX,EDmNQ,IAAAC,GAAA,6BAlOO,SAARC,GAAiC,CACtC,IAAAC,EACA,MAAOC,EACP,aAAAC,EACA,SAAAC,EACA,OAAQC,EACR,cAAeC,EACf,UAAAC,EAAY,MACZ,WAAAC,EAAa,wCACb,SAAAC,EAAW,kCACX,WAAAC,EAAa,GACb,YAAAC,EAAc,GACd,SAAAC,EAAW,EACX,WAAAC,EAAa,EACb,WAAAC,EAAa,EACb,QAAAC,EACA,QAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,gBAAAC,EACA,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,OAAAC,EACA,MAAAC,EACA,eAAAC,EAAiB,MACjB,YAAAC,EACA,aAAAC,EACA,WAAAC,EACA,aAAAC,EACA,KAAAC,EACA,GAAAC,EACA,aAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,OAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,eACZ,UAAAC,EAAY,GACZ,iBAAAC,EAAmB,GACnB,sBAAAC,EAAwB,GACxB,eAAAC,EAAiB,GACjB,gBAAAC,EAAkB,GAClB,iBAAAC,GAAmB,EACrB,EAAyB,CACvB,GAAM,CACJ,WAAAC,EAAa,GACb,UAAAC,GAAY,GACZ,UAAAC,GAAY,GACZ,YAAAC,GAAc,GACd,YAAAC,EAAc,GACd,YAAAC,EAAc,GACd,cAAAC,GAAgB,EAClB,EAAIf,GAAU,CAAC,EAETgB,KAAc,UAAM,EACpBC,EAAUrB,GAAMoB,EAChBE,EAAgB,GAAGD,CAAO,gBAC1BE,GAAY,GAAGF,CAAO,WAEtBG,GAAaC,GAAiB9C,EAAYC,CAAW,EACrD8C,GAAiBpD,GAAgBkD,GACjCG,GAAwBpD,GAAuBmD,GAE/CE,GAAezD,IAAoB,OACnC,CAAC0D,GAAeC,CAAgB,KAAI,aAAoB,IAAM,CAClE,IAAMC,GAAM3D,EACZ,OAAI2D,IAAO,MAAM,QAAQA,EAAG,EACnB,CAACC,GAAgBD,GAAI,CAAC,CAAC,EAAGC,GAAgBD,GAAI,CAAC,CAAC,CAAC,EAEnD,CAAC,KAAM,IAAI,CACpB,CAAC,EAEKE,EACJL,IAAgBzD,GAAmB,MAAM,QAAQA,CAAe,EAC5D,CAAC6D,GAAgB7D,EAAgB,CAAC,CAAC,EAAG6D,GAAgB7D,EAAgB,CAAC,CAAC,CAAC,EACzE0D,GAEAK,EAAYD,EAAc,CAAC,EAC7BE,GAAWF,EAAc,CAAC,EAAGN,EAAqB,EAClD,GACES,GAAUH,EAAc,CAAC,EAC3BE,GAAWF,EAAc,CAAC,EAAGN,EAAqB,EAClD,GAEEU,KAAiB,YAAQ,IACzBH,GAAaE,GACR,GAAGF,CAAS,GAAG1D,CAAS,GAAG4D,EAAO,GAEvCF,EACK,GAAGA,CAAS,GAAG1D,CAAS,GAE1B,GACN,CAAC0D,EAAWE,GAAS5D,CAAS,CAAC,EAE5B,CAAC8D,GAAQC,EAAS,KAAI,aAAS,EAAK,EAGpC,CACJ,KAAM,CAAE,aAAAC,GAAc,YAAAC,EAAY,EAClC,eAAAC,GACA,QAAAC,EACF,KAAI,gBAAY,CACd,UAAArC,EACA,KAAMgC,IAAU,CAACpC,GAAY,CAACC,GAAY,CAACY,GAC3C,aAAcwB,GACd,qBAAsB,cACtB,UAAW,GACX,WAAY,IAAC,GAAAK,QAAiB,CAAC,KAAG,GAAAC,MAAe,KAAG,GAAAC,OAAgB,CAAE,QAAS,CAAE,CAAC,CAAC,CACrF,CAAC,EAEKC,MAAU,eAAWJ,GAAS,CAClC,UAAW,GACX,aAAc,EAChB,CAAC,EACKK,MAAO,YAAQL,GAAS,CAAE,KAAM,QAAS,CAAC,EAC1C,CAAE,kBAAAM,GAAmB,iBAAAC,EAAiB,KAAI,oBAAgB,CAACH,GAASC,EAAI,CAAC,EAEzE,CAAE,UAAAG,GAAW,OAAQC,EAAiB,KAAI,wBAAoBT,GAAS,CAC3E,SAAU,IACV,QAAS,CAAC,CAAE,KAAAU,EAAK,KAAO,CACtB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,GACA,KAAM,CACJ,QAAS,EACT,UAAW,8BACb,EACA,MAAO,CAAC,CAAE,KAAAA,EAAK,KAAO,CACpB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,EACF,CAAC,EAEKC,GAAW,GAAQxC,IAAahB,GAChCyD,GAAcD,GAAW,QAAU/D,EAGnCiE,GAAaC,EAAcpE,EAAMqE,GAA2B,IAAI,EAChEC,GAAcF,EAAcjE,EAAQoE,GAA6B,IAAI,EACrEC,GAAkBJ,EAAcjE,EAAQsE,GAA2B,IAAI,EACvEC,GACJzE,IAAY,QACR,GACAmE,EAAcF,GAAaE,EAAcnE,EAAS0E,GAA8B,SAAS,EAAG,SAAS,EAErGC,GAAW,GAAQhC,EAAc,CAAC,GAAKA,EAAc,CAAC,GAGtDiC,GAAyBC,IAAe,CAC5C,IAAMC,GAAsB,CAACD,GAAMlC,EAAc,CAAC,CAAC,EAC9CL,IACHE,EAAiBsC,EAAQ,EAE3B,IAAMC,GAASlC,GAAWgC,GAAMzC,EAAc,EACxC4C,GAAOrC,EAAc,CAAC,EAAIE,GAAWF,EAAc,CAAC,EAAGP,EAAc,EAAI,GAC/ErD,IAAW,CAACgG,GAAQC,EAAI,CAAC,CAC3B,EAEMC,GAAuBJ,IAAe,CAC1C,IAAMC,GAAsB,CAACnC,EAAc,CAAC,EAAGkC,EAAI,EAC9CvC,IACHE,EAAiBsC,EAAQ,EAE3B,IAAMC,GAASpC,EAAc,CAAC,EAAIE,GAAWF,EAAc,CAAC,EAAGP,EAAc,EAAI,GAC3E4C,GAAOnC,GAAWgC,GAAMzC,EAAc,EAC5CrD,IAAW,CAACgG,GAAQC,EAAI,CAAC,EAErBnD,IACFoB,GAAU,EAAK,CAEnB,EAEMiC,GAAiBC,IAAuC,CACxDvE,GAAYC,GAAYY,KACxB0D,GAAE,MAAQ,aAAeA,GAAE,MAAQ,SAAWA,GAAE,MAAQ,KAC1DA,GAAE,eAAe,EACZnC,IAAQC,GAAU,EAAI,GAClBkC,GAAE,MAAQ,UAAYnC,KAC/BmC,GAAE,eAAe,EACjBlC,GAAU,EAAK,GAEnB,EAEMmC,GAAeD,IAAqC,CACxDA,GAAE,gBAAgB,EACb7C,IACHE,EAAiB,CAAC,KAAM,IAAI,CAAC,EAE/BzD,IAAW,IAAI,EACfgC,IAAU,CACZ,EAEMsE,GACJhF,IACCC,EACG,GAAGA,EAAa,CAAC,CAAC,GAAGpB,CAAS,GAAGoB,EAAa,CAAC,CAAC,GAChD,GAAG+B,EAAqB,GAAGnD,CAAS,GAAGmD,EAAqB,IAE5DiD,GAAalF,IAAmB,WAChCmF,GAAenF,IAAmB,OAGlCoF,GAAc,IAAM,CACxB,GAAI,CAACrF,EAAO,OAAO,KAEnB,IAAMsF,GAAkBzB,GACpB,2BACAG,EAAcF,GAAayB,GAAkB,SAAS,EAE1D,OAAIJ,MAEA,SAAC,SACC,QAASvD,EACT,UAAW,sJAAsJmC,GAAW,aAAa,IAAIuB,EAAe,IAAIrE,CAAc,GAE7N,UAAAjB,EACAoB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,KAKF,SAAC,SACC,QAASQ,EACT,UAAW,qEAAqEmC,GAAW,KAAK,IAAIuB,EAAe,IAAIrE,CAAc,GAEpI,UAAAjB,EACAoB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,CAEJ,EAEMoE,GAAqBC,OACzB,QAAC,QACC,UAAW,8FAA8F1B,GAAW,IAAI,GACxH,cAAY,OAEX,SAAA0B,GACH,EAGIC,GAAsB,CAC1B,sCACAN,GAAe,8BAAgC,WAC/C3D,EAAc,SAAW,cACzBV,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL4E,GAAmB,CACvB,qHACA5B,GAAW,YACXG,GACAI,GACA7D,EAAW,aAAe,GAC1BgB,EAAc,SAAW,SACzBT,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL4E,GAAe,CACnB,iKACA7B,GAAW,UACXA,GAAW,aACXjD,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,SACE,SAAC,OAAI,UAAW4E,GAEb,WAACP,IAAcE,GAAY,KAE5B,SAAC,OAAI,UAAW,iBAAiB5D,EAAc,SAAW,EAAE,GAE1D,sBAAC,OAAI,IAAKsB,GAAe,GAAGS,GAAkB,EAAG,UAAWmC,GACzD,UAAAR,IAAcE,GAAY,KAE3B,QAAC,SACC,IAAK5G,EACL,GAAImD,EACJ,KAAMtB,EACN,KAAK,OACL,MAAOsC,EACP,QAAS,IAAM,CAACnC,GAAY,CAACC,GAAY,CAACY,IAAawB,GAAW+C,IAAS,CAACA,EAAI,EAChF,UAAWd,GACX,SAAU,GACV,aAAcvE,EACd,YAAa0E,GACb,SAAUzE,GAAYa,GACtB,KAAK,WACL,gBAAeuB,IAAU,CAACvB,GAC1B,gBAAc,SACd,gBAAeQ,GACf,gBAAeV,EACf,eAAcyC,GACd,YAAWvC,GACX,gBAAeb,GAAYa,GAC3B,mBAAkBlB,GAAcC,EAAewB,EAAgB,OAC/D,oBAAmBxB,EAAewB,EAAgB,OAClD,UAAW+D,GACb,KAGA,SAAC,OAAI,UAAU,gDACZ,UAAAtE,IAAaC,OACZ,QAAC,OAAI,UAAU,4CAA6C,SAAAiE,MAAkB,QAACM,GAAA,EAAQ,CAAE,EAAE,EAG5F,CAACxE,IAAaE,GAAe,CAACf,GAAY,CAACC,MAC1C,QAAC,UACC,KAAK,SACL,QAASuE,GACT,aAAW,oCACX,SAAUT,GAAW,EAAI,GACzB,cAAa,CAACA,GACd,UAAW,qOAAqOT,GAAW,IAAI,IAC7PS,GAAW,sBAAwB,yCACrC,GAEA,oBAACuB,GAAA,CAAU,UAAU,YAAY,EACnC,KAGF,QAAC,OACC,cAAY,OACZ,UAAW,gJACTlD,GAAS,aAAe,UAC1B,GAEC,SAAA2C,MAAkB,QAACQ,GAAA,CAAgB,UAAU,YAAY,CAAE,EAC9D,GACF,GACF,EAGCtC,OACC,QAAC,mBACC,oBAAC,yBAAqB,QAASR,GAAS,MAAO,GAAO,YAAa,GACjE,qBAAC,OACC,IAAKF,GACL,GAAIlB,GACJ,MAAO,CACL,GAAGmB,GACH,GAAGU,GACH,OAAQsC,GAAgB,MAC1B,EACC,GAAGxC,GAAiB,EACrB,UAAW,gIAAgIW,EAAe,IAAIjD,EAAgB,GAG9K,sBAAC,OAAI,UAAU,gBACb,qBAAC,OAAI,UAAU,2GACZ,SAAAnC,EACH,KACA,QAACkH,GAAA,CACC,MAAO1D,EAAc,CAAC,EACtB,SAAUiC,GACV,UAAWzF,EACX,WAAYE,EACZ,YAAaC,EACb,SAAUC,EACV,WAAYC,EACZ,WAAYC,EACZ,QAASC,EACT,QAASiD,EAAc,CAAC,GAAKhD,EAC7B,cAAeC,EACf,gBAAiBC,EACjB,gBAAiBC,EACjB,KAAMC,EACN,MAAOE,EACP,OAAQC,EACR,UAAU,0BACZ,GACF,KAGA,SAAC,OAAI,UAAU,gBACb,qBAAC,OAAI,UAAU,2GACZ,SAAAd,EACH,KACA,QAACiH,GAAA,CACC,MAAO1D,EAAc,CAAC,EACtB,SAAUsC,GACV,UAAW7F,EACX,WAAYC,EACZ,YAAaC,EACb,SAAUC,EACV,WAAYC,EACZ,WAAYC,EACZ,QAASkD,EAAc,CAAC,GAAKjD,EAC7B,QAASC,EACT,cAAeC,EACf,gBAAiBC,EACjB,gBAAiBC,EACjB,KAAMC,EACN,MAAOE,EACP,OAAQC,EACR,UAAU,0BACZ,GACF,GACF,EACF,EACF,KAIF,QAACoG,GAAA,CACC,GAAItE,EACJ,WAAYzB,EACZ,aAAcC,EACd,cAAe0D,GAAW,OAC1B,UAAW7C,EACb,GACF,GACF,CAEJ,CEtdO,SAASkF,GACdC,EACAC,EACAC,EACS,CACT,GAAI,CAACF,GAAQ,CAACC,GAAS,CAACC,EAAK,MAAO,GACpC,IAAMC,EAAIH,EAAK,SAAS,EAAI,KAAOA,EAAK,WAAW,EAAI,GAAKA,EAAK,WAAW,EACtEI,EAAIH,EAAM,SAAS,EAAI,KAAOA,EAAM,WAAW,EAAI,GAAKA,EAAM,WAAW,EACzEI,EAAIH,EAAI,SAAS,EAAI,KAAOA,EAAI,WAAW,EAAI,GAAKA,EAAI,WAAW,EACzE,OAAOC,GAAKC,GAAKD,GAAKE,CACxB,CClBA,IAAAC,GAAsE,iBACtEA,GAYO,8BCPA,SAASC,GAAyBC,EAAsB,GAAOC,EAAuB,GAAc,CACzG,OAAID,EACKC,EAAc,wBAA0B,qBAE1CA,EAAc,sBAAwB,kBAC/C,CAKO,SAASC,GAAgBC,EAAmBC,EAAgC,CACjF,GAAI,CAACD,GAAQ,CAACC,EAAM,OAAO,KAC3B,IAAMC,EAAWF,EAAO,IAAI,KAAKA,CAAI,EAAI,IAAI,KAC7C,OAAIC,IACFC,EAAS,SAASD,EAAK,SAAS,CAAC,EACjCC,EAAS,WAAWD,EAAK,WAAW,CAAC,EACrCC,EAAS,WAAWD,EAAK,WAAW,CAAC,EACrCC,EAAS,gBAAgBD,EAAK,gBAAgB,CAAC,GAE1CC,CACT,CAKO,SAASC,GAAWC,EAAcC,EAAoB,sBAAoC,CAC/F,GAAI,CAACD,EAAK,OAAO,KACjB,GAAIA,aAAe,KACjB,OAAO,MAAMA,EAAI,QAAQ,CAAC,EAAI,KAAO,IAAI,KAAKA,EAAI,QAAQ,CAAC,EAE7D,GAAI,OAAOA,GAAQ,UAAY,OAAOA,GAAQ,SAAU,CACtD,GAAI,OAAOA,GAAQ,SAAU,CAC3B,IAAME,EAAmBC,GAAcH,EAAKC,CAAS,EACrD,GAAIC,EAAkB,OAAOA,CAC/B,CACA,IAAME,EAAS,IAAI,KAAKJ,CAAG,EAC3B,OAAO,MAAMI,EAAO,QAAQ,CAAC,EAAI,KAAOA,CAC1C,CACA,IAAMC,EAASL,EACf,OAAI,OAAOK,EAAO,QAAW,WACpBA,EAAO,OAAO,EAEnB,OAAOA,EAAO,mBAAsB,SAC/B,IAAI,KAAKA,EAAO,iBAAiB,EAEnC,IACT,CAKO,SAASC,GACdV,EACAK,EAAoB,sBACpBM,EACQ,CACR,MAAI,CAACX,GAAQ,MAAMA,EAAK,QAAQ,CAAC,EAAU,GACpCY,GAAWZ,EAAMK,EAAWM,CAAM,CAC3C,CAKO,SAASJ,GAAcM,EAAgCR,EAAoB,sBAAoC,CACpH,GAAI,CAACQ,GAAO,OAAOA,GAAQ,SAAU,OAAO,KAC5C,IAAMC,EAAUD,EAAI,KAAK,EACzB,GAAI,CAACC,EAAS,OAAO,KAErB,IAAIC,EAAO,IAAI,KAAK,EAAE,YAAY,EAC9BC,EAAQ,EACRC,EAAM,EACNC,EAAQ,EACRC,EAAU,EACVC,EAAU,EACVC,EAAW,GACXC,EAAO,GAELC,EAAelB,EAAU,MAAM,4CAA4C,EACjF,GAAI,CAACkB,EAAc,CACjB,IAAMC,EAAI,IAAI,KAAKV,CAAO,EAC1B,OAAO,MAAMU,EAAE,QAAQ,CAAC,EAAI,KAAOA,CACrC,CAGA,IAAIC,EAAW,IAAMpB,EAAU,QAAQ,sBAAuB,MAAM,EACpE,QAAWqB,KAAQH,EACbG,IAAS,OAAQD,EAAWA,EAAS,QAAQ,OAAQ,UAAU,EAC1DC,IAAS,KAAMD,EAAWA,EAAS,QAAQ,KAAM,UAAU,EAC3DC,IAAS,MAAQA,IAAS,KAC1BA,IAAS,MAAQA,IAAS,KAC1BA,IAAS,MAAQA,IAAS,KAAOA,IAAS,MAAQA,IAAS,KAE3DA,IAAS,MAAQA,IAAS,KAC1BA,IAAS,MAAQA,IAAS,IALKD,EAAWA,EAAS,QAAQC,EAAM,YAAY,GAM7EA,IAAS,KAAOA,IAAS,OAAKD,EAAWA,EAAS,QAAQC,EAAM,eAAe,GAE1FD,GAAY,IAEZ,IAAME,EAAQ,IAAI,OAAOF,EAAU,GAAG,EAAE,KAAKX,CAAO,EACpD,GAAI,CAACa,EAAO,CACV,IAAMC,EAAW,IAAI,KAAKd,CAAO,EACjC,OAAO,MAAMc,EAAS,QAAQ,CAAC,EAAI,KAAOA,CAC5C,CAEAL,EAAa,QAAQ,CAACG,EAAMG,IAAU,CACpC,IAAMC,EAASH,EAAME,EAAQ,CAAC,EAC9B,GAAI,CAACC,EAAQ,OAEb,GAAIJ,IAAS,KAAOA,IAAS,IAAK,CAChCL,EAAW,GACPS,EAAO,YAAY,IAAM,OAC3BR,EAAO,IAET,MACF,CAEA,IAAMlB,EAAM,SAAS0B,EAAQ,EAAE,EAC3B,MAAM1B,CAAG,IAETsB,IAAS,OAAQX,EAAOX,EACnBsB,IAAS,KAAMX,EAAO,IAAOX,EAC7BsB,IAAS,MAAQA,IAAS,IAAKV,EAAQZ,EACvCsB,IAAS,MAAQA,IAAS,IAAKT,EAAMb,EACrCsB,IAAS,MAAQA,IAAS,IAAKR,EAAQd,EACvCsB,IAAS,MAAQA,IAAS,KACjCL,EAAW,GACXH,EAAQd,GACCsB,IAAS,MAAQA,IAAS,IAAKP,EAAUf,GAC3CsB,IAAS,MAAQA,IAAS,OAAKN,EAAUhB,GACpD,CAAC,EAEGiB,IACEC,EACEJ,EAAQ,KAAIA,GAAS,IAErBA,IAAU,KAAIA,EAAQ,IAI9B,IAAMa,EAAS,IAAI,KAAKhB,EAAMC,EAAQ,EAAGC,EAAKC,EAAOC,EAASC,CAAO,EACrE,OAAO,MAAMW,EAAO,QAAQ,CAAC,EAAI,KAAOA,CAC1C,CCzIO,IAAMC,GAAmE,CAC9E,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,cACR,EAKaC,GAAiE,CAC5E,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,aACR,EAKaC,GAiBT,CACF,GAAI,CACF,YAAa,MACb,UAAW,cACX,aAAc,OACd,KAAM,SACN,SAAU,GACV,gBAAiB,MACjB,SAAU,UACV,SAAU,cACV,WAAY,wBACZ,iBAAkB,UAClB,MAAO,mBACP,cAAe,cACf,OAAQ,mBACV,EACA,GAAI,CACF,YAAa,MACb,UAAW,UACX,aAAc,SACd,KAAM,WACN,SAAU,GACV,gBAAiB,QACjB,SAAU,UACV,SAAU,UACV,WAAY,wBACZ,iBAAkB,UAClB,MAAO,eACP,cAAe,cACf,OAAQ,oBACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,UACX,aAAc,OACd,KAAM,cACN,SAAU,GACV,gBAAiB,MACjB,SAAU,UACV,SAAU,UACV,WAAY,wBACZ,iBAAkB,UAClB,MAAO,iBACP,cAAe,cACf,OAAQ,kBACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,YACX,aAAc,SACd,KAAM,SACN,SAAU,GACV,gBAAiB,MACjB,SAAU,YACV,SAAU,YACV,WAAY,0BACZ,iBAAkB,UAClB,MAAO,mBACP,cAAe,UACf,OAAQ,cACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,UACX,aAAc,OACd,KAAM,SACN,SAAU,GACV,gBAAiB,MACjB,SAAU,YACV,SAAU,UACV,WAAY,wBACZ,iBAAkB,YAClB,MAAO,eACP,cAAe,UACf,OAAQ,gBACV,CACF,EA6DO,IAAMC,GAAwD,CACnE,QAAS,sEACT,UAAW,0EACX,MAAO,kEACP,QAAS,sEACT,QAAS,sEACT,KAAM,gEACN,QAAS,qEACX,EAKaC,GAGT,CACF,QAAS,CACP,QACE,6JACF,UACE,mKACF,MACE,qJACF,QACE,6JACF,QACE,6JACF,KAAM,oJACN,QACE,4JACJ,EACA,OAAQ,CACN,QACE,2LACF,UACE,qMACF,MACE,wMACF,QACE,2LACF,QACE,2LACF,KAAM,4KACN,QACE,0LACJ,EACA,MAAO,CACL,QACE,0LACF,UACE,kMACF,MACE,+KACF,QACE,0LACF,QACE,0LACF,KAAM,8KACN,QACE,yLACJ,CACF,EFNQ,IAAAC,GAAA,6BA/MO,SAARC,GAAgC,CACrC,IAAAC,EACA,MAAOC,EACP,aAAAC,EACA,SAAAC,EACA,OAAQC,EACR,cAAeC,EACf,OAAAC,EAAS,eACT,OAAAC,EAAS,KACT,YAAAC,EAAc,OACd,eAAAC,EAAiB,EACjB,QAAAC,EACA,QAAAC,EACA,eAAAC,EACA,SAAAC,EACA,WAAAC,EAAa,GACb,YAAAC,EAAc,GACd,SAAAC,EAAW,EACX,WAAAC,EAAa,EACb,WAAAC,EAAa,EACb,QAAAC,EACA,QAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,gBAAAC,EACA,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,OAAAC,EACA,MAAAC,EACA,eAAAC,EAAiB,MACjB,YAAAC,EACA,WAAAC,EACA,aAAAC,EACA,KAAAC,EACA,GAAAC,EACA,aAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,OAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,eACZ,UAAAC,EAAY,GACZ,iBAAAC,GAAmB,GACnB,sBAAAC,EAAwB,GACxB,eAAAC,GAAiB,GACjB,gBAAAC,GAAkB,GAClB,iBAAAC,GAAmB,EACrB,EAAwB,CACtB,GAAM,CACJ,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,UAAAC,GAAY,GACZ,YAAAC,EAAc,GACd,YAAAC,EAAc,GACd,YAAAC,EAAc,GACd,cAAAC,GAAgB,GAChB,gBAAAC,GAAkB,GAClB,aAAAC,GAAe,EACjB,EAAIjB,GAAU,CAAC,EAETkB,MAAc,UAAM,EACpBC,GAAUvB,GAAMsB,GAChBE,GAAgB,GAAGD,EAAO,gBAC1BE,EAAY,GAAGF,EAAO,WAEtBG,EAAaC,GAAyB/C,EAAYC,CAAW,EAC7D+C,EAAiB1D,GAAgBwD,EACjCG,GAAoB1D,GAAuByD,EAE3CE,EAAe/D,IAAoB,OACnC,CAACgE,GAAcC,EAAe,KAAI,aAAsB,IAAMC,GAAWjE,EAAc4D,CAAc,CAAC,EACtGM,GAAeJ,EAAeG,GAAWlE,EAAiB6D,CAAc,EAAIG,GAC5EI,GAAiBD,GAAeE,GAAeF,GAAcL,GAAmBxD,CAAM,EAAI,GAE1F,CAACgE,GAAYC,EAAa,KAAI,aAAuBhE,CAAW,EAChE,CAACiE,GAAQC,EAAS,KAAI,aAAS,EAAK,EAGpC,CACJ,KAAM,CAAE,aAAAC,GAAc,YAAAC,EAAY,EAClC,eAAAC,GACA,QAAAC,EACF,KAAI,gBAAY,CACd,UAAAtC,EACA,KAAMiC,IAAU,CAACrC,GAAY,CAACC,GAAY,CAACY,GAC3C,aAAcyB,GACd,qBAAsB,cACtB,UAAW,GACX,WAAY,IAAC,GAAAK,QAAiB,CAAC,KAAG,GAAAC,MAAe,KAAG,GAAAC,OAAgB,CAAE,QAAS,CAAE,CAAC,CAAC,CACrF,CAAC,EAEKC,MAAU,eAAWJ,GAAS,CAClC,UAAW,GACX,aAAc,EAChB,CAAC,EACKK,MAAO,YAAQL,GAAS,CAAE,KAAM,QAAS,CAAC,EAC1C,CAAE,kBAAAM,GAAmB,iBAAAC,EAAiB,KAAI,oBAAgB,CAACH,GAASC,EAAI,CAAC,EAEzE,CAAE,UAAAG,GAAW,OAAQC,EAAiB,KAAI,wBAAoBT,GAAS,CAC3E,SAAU,IACV,QAAS,CAAC,CAAE,KAAAU,EAAK,KAAO,CACtB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,GACA,KAAM,CACJ,QAAS,EACT,UAAW,8BACb,EACA,MAAO,CAAC,CAAE,KAAAA,EAAK,KAAO,CACpB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,EACF,CAAC,EAEKC,GAAW,GAAQzC,GAAahB,GAChC0D,GAAcD,GAAW,QAAU/D,EAGnCiE,GAAaC,EAAcpE,EAAMqE,GAA0B,IAAI,EAC/DC,GAAcF,EAAcjE,EAAQoE,GAA4B,IAAI,EACpEC,GAAkBJ,EAAcjE,EAAQsE,GAA0B,IAAI,EACtEC,GACJzE,IAAY,QACR,GACAmE,EAAcF,GAAaE,EAAcnE,EAAS0E,GAA6B,SAAS,EAAG,SAAS,EAEpGC,GAAW,EAAQhC,GAGnBiC,GAAwBC,IAAkB,CAE9C,IAAMC,GAAWC,GAAgBF,GAASlC,IAAgB,IAAI,IAAM,EAC/DJ,GACHE,GAAgBqC,EAAQ,EAE1B,IAAME,GAAkBF,GAAWjC,GAAeiC,GAAUzC,EAAgBvD,CAAM,EAAI,GACtFJ,IAAWsG,EAAe,EAEtBpD,IACFqB,GAAU,EAAK,CAEnB,EAEMgC,GAAoBC,IAAyB,CACjD,GAAI,CAACA,GAAS,OAEd,IAAMJ,GAAWC,GAAgBpC,IAAgB,IAAI,KAAQuC,EAAO,EAC/D3C,GACHE,GAAgBqC,EAAQ,EAE1B,IAAME,GAAkBF,GAAWjC,GAAeiC,GAAUzC,EAAgBvD,CAAM,EAAI,GACtFJ,IAAWsG,EAAe,EAEtBpD,IACFqB,GAAU,EAAK,CAEnB,EAEMkC,GAAiBC,IAAuC,CACxDzE,GAAYC,GAAYY,KACxB4D,GAAE,MAAQ,aAAeA,GAAE,MAAQ,SAAWA,GAAE,MAAQ,KAC1DA,GAAE,eAAe,EACZpC,IAAQC,GAAU,EAAI,GAClBmC,GAAE,MAAQ,UAAYpC,KAC/BoC,GAAE,eAAe,EACjBnC,GAAU,EAAK,GAEnB,EAEMoC,GAAeD,IAAqC,CACxDA,GAAE,gBAAgB,EACb7C,GACHE,GAAgB,IAAI,EAEtB/D,IAAW,IAAI,EACfoC,IAAU,CACZ,EAEMwE,GAAqBjF,GAAeiC,GACpCiD,GAAanF,IAAmB,WAChCoF,GAAepF,IAAmB,OAGlCqF,GAAc,IAAM,CACxB,GAAI,CAACtF,EAAO,OAAO,KAEnB,IAAMuF,GAAkB1B,GACpB,2BACAG,EAAcF,GAAa0B,GAAkB,SAAS,EAE1D,OAAIJ,MAEA,SAAC,SACC,QAASvD,GACT,UAAW,sJAAsJkC,GAAW,aAAa,IAAIwB,EAAe,IAAIvE,EAAc,GAE7N,UAAAhB,EACAmB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,KAKF,SAAC,SACC,QAASU,GACT,UAAW,qEAAqEkC,GAAW,KAAK,IAAIwB,EAAe,IAAIvE,EAAc,GAEpI,UAAAhB,EACAmB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,CAEJ,EAEMsE,GAAqBC,OACzB,QAAC,QACC,UAAW,8FAA8F3B,GAAW,IAAI,GACxH,cAAY,OAEX,SAAA2B,GACH,EAGIC,GAAsB,CAC1B,qCACAN,GAAe,8BAAgC,WAC/C7D,EAAc,SAAW,cACzBV,EACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL8E,GAAmB,CACvB,qHACA7B,GAAW,YACXG,GACAI,GACA9D,EAAW,aAAe,GAC1BgB,EAAc,SAAW,SACzBT,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL8E,GAAe,CACnB,iKACA9B,GAAW,UACXA,GAAW,aACXlD,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,SACE,SAAC,OAAI,UAAW8E,GAEb,WAACP,IAAcE,GAAY,KAE5B,SAAC,OAAI,UAAW,iBAAiB9D,EAAc,SAAW,EAAE,GAE1D,sBAAC,OAAI,IAAKuB,GAAe,GAAGS,GAAkB,EAAG,UAAWoC,GACzD,UAAAR,IAAcE,GAAY,KAE3B,QAAC,SACC,IAAKlH,EACL,GAAIyD,GACJ,KAAMxB,EACN,KAAK,OACL,MAAOoC,GACP,QAAS,IAAM,CAACjC,GAAY,CAACC,GAAY,CAACY,IAAayB,GAAWgD,IAAS,CAACA,EAAI,EAChF,UAAWd,GACX,SAAU,GACV,aAAczE,EACd,YAAa4E,GACb,SAAU3E,GAAYa,GACtB,KAAK,WACL,gBAAewB,IAAU,CAACxB,GAC1B,gBAAc,SACd,gBAAeU,EACf,gBAAeZ,EACf,eAAc0C,GACd,YAAWxC,GACX,gBAAeb,GAAYa,GAC3B,mBAAkBlB,GAAcC,EAAe0B,GAAgB,OAC/D,oBAAmB1B,EAAe0B,GAAgB,OAClD,UAAW+D,GACb,KAGA,SAAC,OAAI,UAAU,gDACZ,UAAAxE,IAAaC,MACZ,QAAC,OAAI,UAAU,4CAA6C,SAAAmE,MAAkB,QAACM,GAAA,EAAQ,CAAE,EAAE,EAG5F,CAAC1E,IAAaE,GAAe,CAACf,GAAY,CAACC,MAC1C,QAAC,UACC,KAAK,SACL,QAASyE,GACT,aAAW,0BACX,SAAUV,GAAW,EAAI,GACzB,cAAa,CAACA,GACd,UAAW,qOAAqOT,GAAW,IAAI,IAC7PS,GAAW,sBAAwB,yCACrC,GAEA,oBAACwB,GAAA,CAAU,UAAU,YAAY,EACnC,KAGF,QAAC,OACC,cAAY,OACZ,UAAW,gJACTnD,GAAS,aAAe,UAC1B,GAEC,SAAA4C,MAAkB,QAACQ,GAAA,CAAgB,UAAU,YAAY,CAAE,EAC9D,GACF,GACF,EAGCvC,OACC,QAAC,mBACC,oBAAC,yBAAqB,QAASR,GAAS,MAAO,GAAO,YAAa,GACjE,qBAAC,OACC,IAAKF,GACL,GAAIjB,EACJ,MAAO,CACL,GAAGkB,GACH,GAAGU,GACH,OAAQuC,GAAgB,MAC1B,EACC,GAAGzC,GAAiB,EACrB,UAAW,2FAA2FW,EAAe,IACnH1F,IAAW,UAAY,yCAA2C,wCACpE,IAAIwC,EAAgB,GAGpB,qBAAC,OAAI,UAAU,gBACb,oBAACiF,GAAA,CACC,MAAO3D,GACP,SAAUiC,GACV,KAAM9B,GACN,aAAcC,GACd,QAAS9D,EACT,QAASC,EACT,eAAgBC,EAChB,OAAQL,EACR,eAAgBE,EAChB,gBAAiB6C,GACjB,KAAM9B,EACN,MAAOE,EACP,OAAQC,EACR,aAAc4B,GACd,SAAU1C,EACV,UAAU,uCACZ,EACF,KAGA,QAAC,OAAI,UAAU,iEACb,oBAACmH,GAAA,CACC,MAAO5D,GACP,SAAUsC,GACV,UAAW,OAAO9E,GAAU,SAAW,GAAGA,CAAK,QAAU,gBACzD,WAAYd,EACZ,YAAaC,EACb,SAAUC,EACV,WAAYC,EACZ,WAAYC,EACZ,QAASC,EACT,QAASC,EACT,cAAeC,EACf,gBAAiBC,EACjB,gBAAiBC,EACjB,KAAMC,EACN,MAAOE,EACP,OAAQC,EACR,UAAU,yCACZ,EACF,GACF,EACF,EACF,KAIF,QAACsG,GAAA,CACC,GAAIvE,GACJ,WAAY3B,EACZ,aAAcC,EACd,cAAe2D,GAAW,OAC1B,UAAW9C,GACb,GACF,GACF,CAEJ,CGxcA,IAAAqF,GAA+E,iBAC/EA,GAYO,8BCCA,IAAMC,GAkBT,CACF,GAAI,CACF,YAAa,MACb,UAAW,cACX,aAAc,OACd,SAAU,WACV,KAAM,SACN,SAAU,GACV,gBAAiB,MACjB,SAAU,UACV,SAAU,cACV,WAAY,wBACZ,iBAAkB,UAClB,MAAO,mBACP,cAAe,cACf,OAAQ,mBACV,EACA,GAAI,CACF,YAAa,MACb,UAAW,UACX,aAAc,SACd,SAAU,WACV,KAAM,WACN,SAAU,GACV,gBAAiB,QACjB,SAAU,UACV,SAAU,UACV,WAAY,wBACZ,iBAAkB,UAClB,MAAO,eACP,cAAe,cACf,OAAQ,oBACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,UACX,aAAc,OACd,SAAU,WACV,KAAM,cACN,SAAU,GACV,gBAAiB,MACjB,SAAU,UACV,SAAU,UACV,WAAY,wBACZ,iBAAkB,UAClB,MAAO,iBACP,cAAe,cACf,OAAQ,kBACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,YACX,aAAc,SACd,SAAU,YACV,KAAM,SACN,SAAU,GACV,gBAAiB,MACjB,SAAU,YACV,SAAU,YACV,WAAY,0BACZ,iBAAkB,UAClB,MAAO,mBACP,cAAe,UACf,OAAQ,cACV,EACA,GAAI,CACF,YAAa,OACb,UAAW,UACX,aAAc,OACd,SAAU,YACV,KAAM,SACN,SAAU,GACV,gBAAiB,MACjB,SAAU,YACV,SAAU,UACV,WAAY,wBACZ,iBAAkB,YAClB,MAAO,eACP,cAAe,UACf,OAAQ,gBACV,CACF,EAKaC,GAAkCC,GAKlCC,GAAgCC,GAUtC,IAAMC,GAAmCC,GAKnCC,GAA6D,CACxE,QAAS,2EACT,UAAW,+EACX,MAAO,uEACP,QAAS,2EACT,QAAS,2EACT,KAAM,qEACN,QAAS,0EACX,EAKaC,GAMT,CACF,QAAS,CACP,WAAY,iEACZ,YAAa,wFACf,EACA,UAAW,CACT,WAAY,qEACZ,YAAa,8FACf,EACA,MAAO,CACL,WAAY,6DACZ,YAAa,kFACf,EACA,QAAS,CACP,WAAY,iEACZ,YAAa,wFACf,EACA,QAAS,CACP,WAAY,+DACZ,YAAa,sFACf,EACA,KAAM,CACJ,WAAY,2DACZ,YAAa,+EACf,EACA,QAAS,CACP,WAAY,iEACZ,YAAa,wFACf,CACF,ED2GQ,IAAAC,GAAA,6BA/PO,SAARC,GAAqC,CAC1C,IAAAC,EACA,MAAOC,EACP,aAAAC,EACA,SAAAC,EACA,OAAQC,EACR,cAAeC,EACf,UAAAC,EAAY,MACZ,WAAAC,EAAa,wCACb,SAAAC,EAAW,kCACX,OAAAC,EAAS,eACT,OAAAC,EAAS,KACT,YAAAC,EAAc,OACd,eAAAC,EAAiB,EACjB,QAAAC,EACA,QAAAC,EACA,eAAAC,EACA,SAAAC,EACA,WAAAC,EAAa,GACb,YAAAC,EAAc,GACd,SAAAC,EAAW,EACX,WAAAC,EAAa,EACb,WAAAC,EAAa,EACb,QAAAC,EACA,QAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,gBAAAC,EACA,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,OAAAC,EACA,MAAAC,EACA,eAAAC,EAAiB,MACjB,YAAAC,EACA,aAAAC,EACA,WAAAC,EACA,aAAAC,EACA,KAAAC,EACA,GAAAC,EACA,aAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,OAAAC,GACA,QAAAC,EACA,UAAAC,GAAY,eACZ,UAAAC,GAAY,GACZ,iBAAAC,GAAmB,GACnB,sBAAAC,EAAwB,GACxB,eAAAC,EAAiB,GACjB,gBAAAC,GAAkB,GAClB,iBAAAC,EAAmB,EACrB,EAA6B,CAC3B,GAAM,CACJ,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,UAAAC,GAAY,GACZ,YAAAC,GAAc,GACd,YAAAC,GAAc,GACd,YAAAC,GAAc,GACd,cAAAC,GAAgB,GAChB,gBAAAC,GAAkB,GAClB,aAAAC,EAAe,EACjB,EAAIjB,IAAU,CAAC,EAETkB,KAAc,UAAM,EACpBC,EAAUvB,GAAMsB,EAChBE,GAAgB,GAAGD,CAAO,gBAC1BE,EAAY,GAAGF,CAAO,WAEtBG,GAAaC,GAAyBhD,EAAYC,CAAW,EAC7DgD,GAAiB9D,GAAgB4D,GACjCG,GAAoB9D,GAAuB6D,GAE3CE,GAAenE,IAAoB,OACnC,CAACoE,GAAeC,EAAgB,KAAI,aAAwB,IAAM,CACtE,IAAMC,GAAMrE,EACZ,OAAIqE,IAAO,MAAM,QAAQA,EAAG,EACnB,CAACC,GAAWD,GAAI,CAAC,EAAGL,EAAc,EAAGM,GAAWD,GAAI,CAAC,EAAGL,EAAc,CAAC,EAEzE,CAAC,KAAM,IAAI,CACpB,CAAC,EAEKO,GACJL,GACInE,GAAmB,MAAM,QAAQA,CAAe,EAC9C,CAACuE,GAAWvE,EAAgB,CAAC,EAAGiE,EAAc,EAAGM,GAAWvE,EAAgB,CAAC,EAAGiE,EAAc,CAAC,EAC/F,CAAC,KAAM,IAAI,EACbG,GAEA,CAACK,GAAYC,EAAa,KAAI,aAA0B,OAAO,EAC/D,CAACC,GAAYC,EAAa,KAAI,aAAuBlE,CAAW,EAChE,CAACmE,GAAQC,EAAS,KAAI,aAAS,EAAK,EAEpCC,GAAYP,GAAc,CAAC,EAAIQ,GAAeR,GAAc,CAAC,EAAGN,GAAmBzD,CAAM,EAAI,GAC7FwE,GAAUT,GAAc,CAAC,EAAIQ,GAAeR,GAAc,CAAC,EAAGN,GAAmBzD,CAAM,EAAI,GAE3FyE,MAAiB,YAAQ,IACzBH,IAAaE,GACR,GAAGF,EAAS,GAAG1E,CAAS,GAAG4E,EAAO,GAEvCF,GACK,GAAGA,EAAS,GAAG1E,CAAS,GAE1B,GACN,CAAC0E,GAAWE,GAAS5E,CAAS,CAAC,EAG5B,CACJ,KAAM,CAAE,aAAA8E,GAAc,YAAAC,EAAY,EAClC,eAAAC,GACA,QAAAC,EACF,KAAI,gBAAY,CACd,UAAA3C,GACA,KAAMkC,IAAU,CAACtC,GAAY,CAACC,GAAY,CAACY,GAC3C,aAAc0B,GACd,qBAAsB,cACtB,UAAW,GACX,WAAY,IAAC,GAAAS,QAAiB,CAAC,KAAG,GAAAC,MAAe,KAAG,GAAAC,OAAgB,CAAE,QAAS,CAAE,CAAC,CAAC,CACrF,CAAC,EAEKC,MAAU,eAAWJ,GAAS,CAClC,UAAW,GACX,aAAc,EAChB,CAAC,EACKK,MAAO,YAAQL,GAAS,CAAE,KAAM,QAAS,CAAC,EAC1C,CAAE,kBAAAM,GAAmB,iBAAAC,EAAiB,KAAI,oBAAgB,CAACH,GAASC,EAAI,CAAC,EAEzE,CAAE,UAAAG,GAAW,OAAQC,EAAiB,KAAI,wBAAoBT,GAAS,CAC3E,SAAU,IACV,QAAS,CAAC,CAAE,KAAAU,EAAK,KAAO,CACtB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,GACA,KAAM,CACJ,QAAS,EACT,UAAW,8BACb,EACA,MAAO,CAAC,CAAE,KAAAA,EAAK,KAAO,CACpB,QAAS,EACT,UACEA,KAAS,MACL,8BACAA,KAAS,SACP,+BACAA,KAAS,OACP,8BACA,8BACZ,EACF,CAAC,EAEKC,GAAW,GAAQ9C,GAAahB,GAChC+D,GAAcD,GAAW,QAAUrE,EAGnCuE,GAAaC,EAAc1E,EAAM2E,GAA+B,IAAI,EACpEC,GAAcF,EAAcvE,EAAQ0E,GAAiC,IAAI,EACzEC,GAAkBJ,EAAcvE,EAAQ4E,GAA+B,IAAI,EAC3EC,GAAmBN,EAAcF,GAAaS,GAAsC,SAAS,EAC7FC,GACJjF,IAAY,QACR,GACAyE,EAAcF,GAAaE,EAAczE,EAASkF,GAAkC,SAAS,EAAG,SAAS,EAEzGC,GAAW,GAAQtC,GAAc,CAAC,GAAKA,GAAc,CAAC,GAGtDuC,GAAcC,IAA4B,CACzC7C,IACHE,GAAiB2C,EAAQ,EAE3B,IAAMC,GAASD,GAAS,CAAC,EAAIhC,GAAegC,GAAS,CAAC,EAAG/C,GAAgBxD,CAAM,EAAI,GAC7EyG,GAAOF,GAAS,CAAC,EAAIhC,GAAegC,GAAS,CAAC,EAAG/C,GAAgBxD,CAAM,EAAI,GACjFP,IAAW+G,IAAUC,GAAO,CAACD,GAAQC,EAAI,EAAI,IAAI,EAE7C1D,IAAiBwD,GAAS,CAAC,GAAKA,GAAS,CAAC,GAC5ClC,GAAU,EAAK,CAEnB,EAEMqC,GAAwBC,IAAkB,CAC9C,GAAI3C,KAAe,QAAS,CAC1B,IAAM4C,GAAWC,GAAgBF,GAAS5C,GAAc,CAAC,GAAK,IAAI,IAAM,EACpE+C,GAAU/C,GAAc,CAAC,EACzB+C,IAAWF,IAAYA,GAAS,QAAQ,EAAIE,GAAQ,QAAQ,IAC9DA,GAAU,MAEZR,GAAW,CAACM,GAAUE,EAAO,CAAC,CAChC,KAAO,CACL,IAAMF,GAAWC,GAAgBF,GAAS5C,GAAc,CAAC,GAAKA,GAAc,CAAC,GAAK,IAAI,IAAM,EAC5FuC,GAAW,CAACvC,GAAc,CAAC,EAAG6C,EAAQ,CAAC,CACzC,CACF,EAEMG,GAAoBC,IAAyB,CACjD,GAAKA,GACL,GAAIhD,KAAe,QAAS,CAC1B,IAAM4C,GAAWC,GAAgB9C,GAAc,CAAC,GAAK,IAAI,KAAQiD,EAAO,EACpEF,GAAU/C,GAAc,CAAC,EACzB+C,IAAWF,IAAYA,GAAS,QAAQ,EAAIE,GAAQ,QAAQ,IAC9DA,GAAU,MAEZR,GAAW,CAACM,GAAUE,EAAO,CAAC,CAChC,KAAO,CACL,IAAMF,GAAWC,GAAgB9C,GAAc,CAAC,GAAKA,GAAc,CAAC,GAAK,IAAI,KAAQiD,EAAO,EAC5FV,GAAW,CAACvC,GAAc,CAAC,EAAG6C,EAAQ,CAAC,CACzC,CACF,EAEMK,GAAiBC,IAAuC,CACxDpF,GAAYC,GAAYY,KACxBuE,GAAE,MAAQ,aAAeA,GAAE,MAAQ,SAAWA,GAAE,MAAQ,KAC1DA,GAAE,eAAe,EACZ9C,IAAQC,GAAU,EAAI,GAClB6C,GAAE,MAAQ,UAAY9C,KAC/B8C,GAAE,eAAe,EACjB7C,GAAU,EAAK,GAEnB,EAEM8C,GAAeD,IAAqC,CACxDA,GAAE,gBAAgB,EACbxD,IACHE,GAAiB,CAAC,KAAM,IAAI,CAAC,EAE/BnE,IAAW,IAAI,EACfwC,IAAU,CACZ,EAEMmF,GACJ7F,IACCC,EACG,GAAGA,EAAa,CAAC,CAAC,GAAG5B,CAAS,GAAG4B,EAAa,CAAC,CAAC,GAChD,GAAGiC,EAAiB,GAAG7D,CAAS,GAAG6D,EAAiB,IAEpD4D,EAAa/F,IAAmB,WAChCgG,GAAehG,IAAmB,OAGlCiG,GAAc,IAAM,CACxB,GAAI,CAAClG,EAAO,OAAO,KAEnB,IAAMmG,GAAkBhC,GACpB,2BACAG,EAAcF,GAAagC,GAAkB,SAAS,EAE1D,OAAIJ,KAEA,SAAC,SACC,QAASlE,EACT,UAAW,sJAAsJuC,GAAW,aAAa,IAAI8B,EAAe,IAAIlF,CAAc,GAE7N,UAAAjB,EACAoB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,KAKF,SAAC,SACC,QAASU,EACT,UAAW,qEAAqEuC,GAAW,KAAK,IAAI8B,EAAe,IAAIlF,CAAc,GAEpI,UAAAjB,EACAoB,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,CAEJ,EAEMiF,GAAqBC,OACzB,QAAC,QACC,UAAW,8FAA8FjC,GAAW,IAAI,GACxH,cAAY,OAEX,SAAAiC,GACH,EAGIC,GAAsB,CAC1B,0CACAN,GAAe,8BAAgC,WAC/CxE,GAAc,SAAW,cACzBV,EACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELyF,GAAmB,CACvB,qHACAnC,GAAW,YACXG,GACAM,GACArE,EAAW,aAAe,GAC1BgB,GAAc,SAAW4C,GAAW,UAAY,WAChDrD,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELyF,GAAe,CACnB,iKACApC,GAAW,UACXA,GAAW,aACXvD,EACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL4F,GAAkB/D,KAAe,QAAUD,GAAc,CAAC,EAAIA,GAAc,CAAC,EAEnF,SACE,SAAC,OAAI,UAAW6D,GAEb,WAACP,GAAcE,GAAY,KAE5B,SAAC,OAAI,UAAW,iBAAiBzE,GAAc,SAAW,EAAE,GAE1D,sBAAC,OAAI,IAAK4B,GAAe,GAAGS,GAAkB,EAAG,UAAW0C,GACzD,UAAAR,GAAcE,GAAY,KAE3B,QAAC,SACC,IAAKjI,EACL,GAAI6D,EACJ,KAAMxB,EACN,KAAK,OACL,MAAO8C,GACP,QAAS,IAAM,CAAC3C,GAAY,CAACC,GAAY,CAACY,IAAa0B,GAAW2D,IAAS,CAACA,EAAI,EAChF,UAAWf,GACX,SAAU,GACV,aAAcpF,EACd,YAAauF,GACb,SAAUtF,GAAYa,GACtB,KAAK,WACL,gBAAeyB,IAAU,CAACzB,GAC1B,gBAAc,SACd,gBAAeU,EACf,gBAAeZ,EACf,eAAc+C,GACd,YAAW7C,GACX,gBAAeb,GAAYa,GAC3B,mBAAkBlB,GAAcC,EAAe0B,GAAgB,OAC/D,oBAAmB1B,EAAe0B,GAAgB,OAClD,UAAW0E,GACb,KAGA,SAAC,OAAI,UAAU,gDACZ,UAAAnF,IAAaC,OACZ,QAAC,OAAI,UAAU,4CAA6C,SAAA8E,MAAkB,QAACO,GAAA,EAAQ,CAAE,EAAE,EAG5F,CAACtF,IAAaE,IAAe,CAACf,GAAY,CAACC,MAC1C,QAAC,UACC,KAAK,SACL,QAASoF,GACT,aAAW,sCACX,SAAUd,GAAW,EAAI,GACzB,cAAa,CAACA,GACd,UAAW,qOAAqOX,GAAW,IAAI,IAC7PW,GAAW,sBAAwB,yCACrC,GAEA,oBAAC6B,GAAA,CAAU,UAAU,YAAY,EACnC,KAGF,QAAC,OACC,cAAY,OACZ,UAAW,gJACT9D,GAAS,aAAe,UAC1B,GAEC,SAAAsD,MAAkB,QAACS,GAAA,CAAgB,UAAU,YAAY,CAAE,EAC9D,GACF,GACF,EAGC9C,OACC,QAAC,mBACC,oBAAC,yBAAqB,QAASR,GAAS,MAAO,GAAO,YAAa,GACjE,qBAAC,OACC,IAAKF,GACL,GAAItB,EACJ,MAAO,CACL,GAAGuB,GACH,GAAGU,GACH,OAAQ8C,GAAgB,MAC1B,EACC,GAAGhD,GAAiB,EACrB,UAAW,oGAAoGW,EAAe,IAAIvD,CAAgB,GAGlJ,sBAAC,OACC,UAAW,QACTzC,IAAW,UACP,yCACA,wCACN,GAGA,qBAAC,OAAI,UAAU,gBACb,oBAACsI,GAAA,CAEC,MAAON,GACP,SAAUrB,GACV,KAAMxC,GACN,aAAcC,GACd,QAASH,KAAe,OAAQD,GAAc,CAAC,GAAK5D,EACpD,QAAS6D,KAAe,SAAUD,GAAc,CAAC,GAAK3D,EACtD,eAAgBC,EAChB,OAAQL,EACR,eAAgBE,EAChB,gBAAiB8C,GACjB,KAAM/B,EACN,MAAOE,EACP,OAAQC,EACR,aAAc6B,EACd,SAAU3C,EACV,UAAU,wCAhBL,iBAAiB0D,EAAU,EAiBlC,EACF,KAGA,QAAC,OAAI,UAAU,iEACb,oBAACsE,GAAA,CAEC,MAAOP,IAAmBhE,GAAc,CAAC,EACzC,SAAUgD,GACV,UAAW/C,KAAe,QAAU,GAAGnE,CAAU,QAAU,GAAGC,CAAQ,QACtE,WAAYS,EACZ,YAAaC,EACb,SAAUC,EACV,WAAYC,EACZ,WAAYC,EACZ,QAASqD,KAAe,OAAQD,GAAc,CAAC,GAAKnD,EACpD,QAASoD,KAAe,SAAUD,GAAc,CAAC,GAAKlD,EACtD,cAAeC,EACf,gBAAiBC,EACjB,gBAAiBC,EACjB,KAAMC,EACN,MAAOE,EACP,OAAQC,EACR,UAAU,0CAjBL,iBAAiB4C,EAAU,EAkBlC,EACF,GACF,KAGA,SAAC,OAAI,UAAU,wFACb,sBAAC,OAAI,UAAU,8BAEb,sBAAC,UACC,KAAK,SACL,QAAS,IAAMC,GAAc,OAAO,EACpC,UAAW,qFACTD,KAAe,QACXiC,GAAiB,WACjB,2EACN,GACD,oBACIpG,GACL,KAGA,SAAC,UACC,KAAK,SACL,QAAS,IAAMoE,GAAc,KAAK,EAClC,UAAW,qFACTD,KAAe,MACXiC,GAAiB,WACjB,2EACN,GAEC,UAAAnG,EAAS,WACZ,GACF,KAGA,QAAC,UACC,KAAK,SACL,QAAS,IAAMuE,GAAU,EAAK,EAC9B,UAAW,mFAAmF4B,GAAiB,WAAW,GAC3H,2BAED,GACF,GACF,EACF,EACF,KAIF,QAACsC,GAAA,CACC,GAAInF,GACJ,WAAY3B,EACZ,aAAcC,EACd,cAAegE,GAAW,OAC1B,UAAWnD,GACb,GACF,GACF,CAEJ,CE5iBA,IAAAiG,GAAkB,uBAClBC,GAAkB,4BCCX,IAAMC,GAYT,CACF,GAAI,CACF,UAAW,MACX,aAAc,YACd,iBAAkB,GAClB,MAAO,yCACP,YAAa,2BACb,IAAK,UACL,WAAY,QACZ,WAAY,MACd,EACA,GAAI,CACF,UAAW,MACX,aAAc,YACd,iBAAkB,IAClB,MAAO,yCACP,YAAa,sCACb,IAAK,QACL,WAAY,UACZ,WAAY,QACd,EACA,GAAI,CACF,UAAW,OACX,aAAc,YACd,iBAAkB,IAClB,MAAO,2CACP,YAAa,2BACb,IAAK,QACL,WAAY,QACZ,WAAY,MACd,CACF,EAEaC,GAMT,CACF,SAAU,CACR,UAAW,wDACX,QAAS,uDACX,EACA,WAAY,CACV,UAAW,qDACX,QAAS,2DACX,CACF,EC/Ca,IAAAC,GAAA,6BAHE,SAARC,GAAmC,CAAE,OAAAC,EAAS,UAAW,GAAGC,CAAM,EAA2B,CAClG,OAAQD,EAAQ,CACd,IAAK,SACH,SAAO,QAACE,GAAA,CAAiB,GAAGD,EAAO,EACrC,IAAK,QACH,SAAO,QAACE,GAAA,CAAgB,GAAGF,EAAO,EACpC,IAAK,SACH,SAAO,QAACG,GAAA,CAAiB,GAAGH,EAAO,EACrC,IAAK,SACH,SAAO,QAACI,GAAA,CAAiB,GAAGJ,EAAO,EAErC,QACE,SAAO,QAACK,GAAA,CAAkB,GAAGL,EAAO,CACxC,CACF,CFgCa,IAAAM,GAAA,6BApDPC,GAA8B,CAAC,UAAW,SAAU,QAAS,SAAU,QAAQ,EAErF,SAASC,GAAcC,EAAuC,CAC5D,OAAO,OAAOA,GAAQ,UAAYF,GAAQ,SAASE,CAAuB,CAC5E,CAEA,SAASC,GAAYD,EAA6B,CAChD,OAAI,OAAOA,GAAQ,SAAiB,GAElCA,EAAI,WAAW,SAAS,GACxBA,EAAI,WAAW,UAAU,GACzBA,EAAI,WAAW,GAAG,GAClBA,EAAI,WAAW,IAAI,GACnBA,EAAI,WAAW,OAAO,GACtB,oCAAoC,KAAKA,CAAG,CAEhD,CAEe,SAARE,GAAuB,CAC5B,KAAAC,EAAO,KACP,OAAAC,EAAS,WACT,MAAAC,EAAQ,UACR,UAAAC,EACA,eAAAC,EAAiB,GACjB,SAAAC,EAAW,aACX,MAAAC,EACA,eAAAC,EAAiB,GACjB,YAAAC,EAAc,mCACd,qBAAAC,EAAuB,GACvB,QAAAC,EACA,iBAAAC,EAAmB,GACnB,SAAAC,EACA,UAAAC,EAAY,GACZ,KAAAC,EAAO,SACP,IAAAC,EACA,GAAGC,CACL,EAAe,CACb,IAAMC,EAAcC,GAAgBlB,CAAI,GAAKkB,GAAgB,GACvDC,EAAgBC,GAAkBnB,CAAM,GAAKmB,GAAkB,SAG/DC,EAAwClB,EAC1C,CACE,MAAO,OAAOA,GAAc,SAAW,GAAGA,CAAS,KAAOA,EAC1D,OAAQ,OAAOA,GAAc,SAAW,GAAGA,CAAS,KAAOA,CAC7D,EACA,CAAC,EAECmB,EAAqB,IAAM,CAC/B,GAAI,CAACpB,EAAO,OAAO,KAEnB,GAAIN,GAAcM,CAAK,EACrB,SAAO,QAACqB,GAAA,CAAkB,OAAQrB,EAAO,EAG3C,GAAIJ,GAAYI,CAAK,EAAG,CACtB,IAAMsB,EAAY,OAAOrB,GAAc,SAAWA,EAAYc,EAAY,iBAE1E,SACE,QAAC,GAAAQ,QAAA,CACC,IAAKvB,EACL,IAAKG,EACL,MAAOmB,EACP,OAAQA,EACR,UAAU,2DACV,YAAatB,EAAM,WAAW,OAAO,GAAKA,EAAM,SAAS,MAAM,EACjE,CAEJ,CAEA,OAAI,GAAAwB,QAAM,eAAexB,CAAK,EACrBA,KAGF,QAACqB,GAAA,CAAkB,OAAO,UAAU,CAC7C,EAEMI,EAAsB,CAC1B,4CACCxB,EAAuC,GAA3Bc,EAAY,aACzBb,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELwB,EAAmB,CACvB,wBACAT,EAAc,UACdF,EAAY,UACZA,EAAY,IACZJ,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELgB,EAAiB,CAACV,EAAc,QAASF,EAAY,UAAU,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAEzFa,EAAe,CAACb,EAAY,MAAOV,CAAc,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAE3EwB,EAAqB,CAACd,EAAY,YAAaR,CAAoB,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAE7FuB,EAAiB,CACrB,oCACAf,EAAY,WACZhB,IAAW,WAAa,iBAAmB,gBAC3CU,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,SACE,SAAC,OAAI,IAAKI,EAAK,KAAMD,EAAM,YAAU,SAAS,UAAWc,EAAmB,GAAGZ,EAC5E,UAAAd,MACC,QAAC,OAAI,UAAWyB,EAAqB,MAAON,EAAkB,cAAY,OACvE,SAAAC,EAAmB,EACtB,GAGAhB,GAASE,GAAeE,GAAWE,OACnC,SAAC,OAAI,UAAWiB,EACb,UAAAvB,MAAS,QAAC,OAAI,UAAWwB,EAAe,SAAAxB,EAAM,EAE9CE,MAAe,QAAC,OAAI,UAAWuB,EAAqB,SAAAvB,EAAY,EAEhEE,MAAW,QAAC,OAAI,UAAWsB,EAAiB,SAAAtB,EAAQ,EAEpDE,MAAY,QAAC,OAAI,UAAU,cAAe,SAAAA,EAAS,GACtD,GAEJ,CAEJ,CGzIA,IAAAqB,GAAgF,iBAChFA,GAWO,8BACPC,GAAuC,wCCVhC,IAAMC,GAYT,CACF,GAAI,CACF,QAAS,kCACT,MAAO,4BACP,KAAM,cACN,KAAM,SACN,OAAQ,gCACR,IAAK,QACL,UAAW,KACX,cAAe,IACjB,EACA,GAAI,CACF,QAAS,8BACT,MAAO,yBACP,KAAM,UACN,KAAM,WACN,OAAQ,gCACR,IAAK,QACL,UAAW,KACX,cAAe,IACjB,EACA,GAAI,CACF,QAAS,iCACT,MAAO,yBACP,KAAM,UACN,KAAM,cACN,OAAQ,4BACR,IAAK,UACL,UAAW,KACX,cAAe,IACjB,EACA,GAAI,CACF,QAAS,+BACT,MAAO,2BACP,KAAM,YACN,KAAM,SACN,OAAQ,mCACR,IAAK,QACL,UAAW,KACX,cAAe,IACjB,EACA,GAAI,CACF,QAAS,+BACT,MAAO,yBACP,KAAM,UACN,KAAM,SACN,OAAQ,6BACR,IAAK,QACL,UAAW,KACX,cAAe,IACjB,CACF,EAEaC,GAA6C,CACxD,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,cACR,EAEaC,GAAoD,CAC/D,KAAM,OACN,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,KAAM,MACR,EAKaC,GAA2F,CACtG,QAAS,CACP,QACE,qKACF,UACE,6KACF,MACE,6JACF,QACE,qKACF,QACE,qKACF,KAAM,yJACN,QACE,oKACJ,EAEA,OAAQ,CACN,QACE,0MACF,UACE,sNACF,MACE,qNACF,QACE,0MACF,QACE,0MACF,KAAM,wLACN,QACE,yMACJ,EACA,MAAO,CACL,QACE,yMACF,UACE,iNACF,MACE,8LACF,QACE,yMACF,QACE,yMACF,KAAM,6LACN,QACE,wMACJ,CACF,EAEaC,GAAyD,CACpE,QAAS,6CACT,UAAW,iDACX,MAAO,yCACP,QAAS,6CACT,QAAS,6CACT,KAAM,uCACN,QAAS,6CACX,EAEaC,GAAuD,CAClE,QAAS,mBACT,UAAW,qBACX,MAAO,iBACP,QAAS,mBACT,QAAS,mBACT,KAAM,gBACN,QAAS,gBACX,EAEaC,GAMT,CACF,IAAK,CACH,UAAW,wBACX,MAAO,yCACT,EACA,KAAM,CACJ,UAAW,mCACX,MAAO,6CACT,EACA,SAAU,CACR,UAAW,WACX,MACE,wIACJ,CACF,EClLA,IAAAC,GAAyC,iBAwGjC,IAAAC,GAAA,6BAhED,SAASC,GAA+B,CAC7C,GAAAC,EACA,gBAAAC,EACA,OAAAC,EACA,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,OAAAC,EAAS,KACT,YAAAC,EAAc,eACd,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,UAAAC,EAAY,GACZ,SAAAC,EAAW,GACX,YAAAC,EACA,WAAAC,EAAa,GACb,gBAAAC,EAAkB,UAClB,YAAAC,EAAc,GACd,eAAAC,EACA,YAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,GACZ,QAASC,EAAc,GACvB,UAAWC,EACX,aAAAC,EACA,WAAAC,EACA,YAAAC,EACA,WAAAC,EACA,kBAAAC,EACA,UAAAC,EACA,UAAAC,EAAY,EACd,EAA8B,CAC5B,IAAMC,EAAU,GAAQR,GAAiBD,GACnCU,KAAW,WAAyB,IAAI,EACxCC,EAAcC,GAAW7B,CAAI,GAAK6B,GAAW,GAC7CC,EAAeC,GAAa5B,CAAM,GAAK4B,GAAa,GACpDC,EAAcC,GAAe9B,CAAM,GAAK,KAGxC+B,EADW,EAAQ3B,EACmB,QAAUL,EAEhDiC,EACJlC,IAAY,QAAU,GAAKmC,GAAmBnC,CAAO,IAAIiC,CAAW,GAAKE,GAAmB,QAAQ,QAEhGC,EAAsB3B,IAAeC,IAAoB,WAAaA,IAAoB,QAE1F2B,EAAexC,EAAgB,OAAS,EACxCyC,EAAYvB,IAAcsB,GAAgB1B,EAAY,OAAS,IAAM,CAACP,GAAY,CAACC,EAGnFkC,EACJhC,GAAYC,GAAeA,EAAc,EAAIX,EAAgB,MAAM,EAAGW,CAAW,EAAIX,EACjF2C,EACJjC,GAAYC,GAAeA,EAAc,EAAI,KAAK,IAAI,EAAGX,EAAgB,OAASW,CAAW,EAAI,EAE7FiC,GAAuB,IAAM,CAC7B,CAACrC,GAAY,CAACC,GAAY,CAACoB,GAAWW,GACxCV,EAAS,SAAS,MAAM,CAE5B,EAEMgB,EAAgB,IAAM,CAE1B,GAAItB,GAAeiB,EACjB,SACE,QAAC,OAAI,UAAU,2CACZ,SAAAjB,EAAYb,EAAWV,EAAkBA,EAAgB,CAAC,CAAE,EAC/D,EAIJ,GAAIU,EACF,SACE,SAAC,OAAI,UAAU,mDACZ,UAAAgC,EAAY,IAAKI,OAChB,QAACC,GAAA,CAEC,KAAMjB,EAAY,UAClB,QAAQ,OACR,MAAO1B,EACP,OAAQ8B,EACR,SAAU,CAAC3B,GAAY,CAACC,GAAY,CAACoB,GAAWZ,EAAc,IAAMA,EAAY8B,EAAG,EAAI,OACvF,UAAU,sBAEV,oBAAC,QAAK,UAAU,WAAY,SAAAA,GAAI,MAAM,GARjC,OAAOA,GAAI,KAAK,CASvB,CACD,EAEAH,EAAiB,MAChB,SAACI,GAAA,CAAM,KAAMjB,EAAY,UAAW,QAAQ,OAAO,MAAM,UAAU,OAAQI,EAAa,cACpFS,GACJ,EAGDJ,GAAuB,CAAChC,GAAY,CAACC,GAAY,CAACoB,KACjD,QAAC,SACC,IAAKC,EACL,KAAK,OACL,aAAW,SACX,MAAOf,EACP,YAAa0B,EAAe,GAAKlC,EACjC,SAAW0C,IAAMjC,IAAiBiC,GAAE,OAAO,KAAK,EAChD,UAAWtB,EACX,UAAW,6GAA6GI,EAAY,KAAK,GAC3I,EACGU,EAED,QADF,QAAC,QAAK,UAAU,4BAA6B,SAAAlC,EAAY,GAE7D,EAKJ,IAAM2C,GAAejD,EAAgB,CAAC,EAEtC,OAAIuC,GAAuB,CAAChC,GAAY,CAACC,GAAY,CAACoB,KAElD,QAAC,OAAI,UAAU,4CACb,oBAAC,SACC,IAAKC,EACL,KAAK,OACL,aAAW,SACX,MAAOf,EACP,YAAamC,GAAeA,GAAa,MAAQ3C,EACjD,SAAW0C,IAAMjC,IAAiBiC,GAAE,OAAO,KAAK,EAChD,UAAWtB,EACX,UAAW,uEACT,CAACZ,GAAemC,GACZ,uDACA,8BACN,IAAInB,EAAY,KAAK,GACvB,EACF,KAKF,QAAC,OAAI,UAAU,0BACZ,SAAAmB,MACC,QAAC,QAAK,UAAU,mBAAoB,SAAAA,GAAa,MAAM,KAEvD,QAAC,QAAK,UAAU,mBAAoB,SAAA3C,EAAY,EAEpD,CAEJ,EAEM4C,GAAe3C,EAAW,mEAAqE,iBAErG,SACE,SAAC,OACC,IAAKiB,EACL,KAAK,WACL,gBAAevB,EACf,gBAAc,UACd,gBAAeF,EAAK,GAAGA,CAAE,WAAa,OACtC,SAAUQ,EAAW,GAAK,EAC1B,QAASqC,GACT,YAAWhB,EACX,gBAAerB,GAAYqB,EAC1B,GAAGH,EAAkB,CACpB,GAAA1B,EACA,UAAW,iHAAiHiC,CAAY,IACtIF,EAAY,OACd,IAAIA,EAAY,GAAG,IAAIO,CAAY,IAAIa,EAAY,IAAIvB,CAAS,GAChE,gBAAiB1B,EACjB,gBAAiB,SACnB,CAAC,EAEA,UAAAoB,MAAgB,QAAC,QAAK,UAAU,qDAAsD,SAAAA,EAAa,EAEnGwB,EAAc,KAEf,SAAC,OAAI,UAAU,2DACZ,UAAAjB,MAAW,QAACuB,GAAA,CAAQ,UAAW,GAAGrB,EAAY,IAAI,6BAA8B,EAEhFW,GAAa,CAACb,MACb,QAAC,UACC,KAAK,SACL,aAAW,kBACX,QAAUoB,IAAM,CACdA,GAAE,gBAAgB,EAClB/B,IAAU+B,EAAC,CACb,EACA,UAAU,mFAEV,oBAACI,GAAA,CAAU,UAAU,WAAW,EAClC,EAGD9B,KAED,QAAC,QAAK,UAAW,qCAAqCrB,EAAS,aAAe,EAAE,GAAI,cAAY,OAC9F,oBAACoD,GAAA,CAAgB,UAAWvB,EAAY,KAAM,EAChD,GACF,GACF,CAEJ,CAEA,IAAOwB,GAAQxD,GC9Of,IAAAyD,GAA+B,8BCuCzB,IAAAC,GAAA,6BApBC,SAASC,GAA8B,CAC5C,OAAAC,EACA,WAAAC,EACA,SAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EAAS,KACT,SAAAC,EAAW,GACX,aAAAC,EACA,QAAAC,EACA,aAAAC,EACA,IAAAC,CACF,EAA6B,CAC3B,IAAMC,EAAcC,GAAWT,CAAI,GAAKS,GAAW,GAC7CC,EACJR,IAAW,OAAS,eAAiBF,IAAS,MAAQA,IAAS,KAAO,aAAe,aACjFW,EAAaR,GAAYN,EAAO,SAEtC,GAAIO,EACF,SACE,QAAC,OACC,IAAKG,EACL,KAAK,SACL,SAAU,GACV,gBAAeT,EACf,gBAAea,EACf,cAAaZ,EACb,gBAAeD,EACf,aAAYD,EAAO,MACnB,UAAW,6DACTc,EAAa,oDAAsD,EACrE,GACA,QAASA,EAAa,OAAYN,EAClC,aAAcM,EAAa,OAAYL,EAEtC,SAAAF,EAAaP,EAAQ,CAAE,SAAUC,EAAY,OAAQC,CAAS,CAAC,EAClE,EAIJ,IAAMa,EAAkBd,EACpBe,GAA0BZ,CAAK,GAAKY,GAA0B,QAC9D,wCAEEC,EACJf,GAAY,CAACD,EAAaiB,GAAwBd,CAAK,GAAKc,GAAwB,QAAU,GAEhG,SACE,SAAC,OACC,IAAKR,EACL,KAAK,SACL,SAAU,GACV,gBAAeT,EACf,gBAAea,EACf,cAAaZ,EACb,gBAAeD,EACf,aAAYD,EAAO,MACnB,UAAW,2GAA2Ga,CAAY,IAAIF,EAAY,MAAM,IAAII,CAAe,IAAIE,CAAa,IAC1LH,EAAa,oDAAsD,EACrE,GACA,QAASA,EAAa,OAAYN,EAClC,aAAcM,EAAa,OAAYL,EAEvC,sBAAC,OAAI,UAAU,yCACZ,UAAAT,EAAO,SAAQ,QAAC,QAAK,UAAU,qDAAsD,SAAAA,EAAO,KAAK,KAClG,SAAC,OAAI,UAAU,+BACb,qBAAC,QAAK,UAAU,sCAAuC,SAAAA,EAAO,MAAM,EACnEA,EAAO,gBACN,QAAC,QAAK,UAAU,oDAAqD,SAAAA,EAAO,YAAY,GAE5F,GACF,EAECC,MACC,QAAC,QAAK,UAAU,yDAAyD,cAAY,OACnF,oBAACkB,GAAA,CAAU,UAAU,WAAW,EAClC,GAEJ,CAEJ,CAEA,IAAOC,GAAQrB,GCnDL,IAAAsB,GAAA,6BA9BH,SAASC,GAAqF,CACnG,QAAAC,EACA,OAAAC,EACA,SAAAC,EACA,QAAAC,EACA,OAAAC,EAAS,WACT,SAAAC,EAAW,EACX,UAAAC,EAAY,GACZ,UAAAC,EAAY,0CACZ,MAAAC,EAAQ,UACR,OAAAC,EAAS,IACX,EAAoC,CAClC,GAAI,CAACT,GAAWA,EAAQ,SAAW,EAAG,OAAO,KAE7C,IAAMU,EAAeC,GAAsC,CACzD,IAAMC,EAAeX,EAAOU,EAAM,IAAsB,GAAKA,EAAM,aAEnE,GAAIA,EAAM,OAAS,SACjB,OACEA,EAAM,SAAS,CACb,MAAOC,EACP,SAAWC,GAAQX,EAASS,EAAM,KAAME,CAAG,CAC7C,CAAC,GAAK,KAIV,OAAQF,EAAM,KAAM,CAClB,IAAK,SACL,IAAK,OACH,SACE,QAACG,GAAA,CACC,KAAK,KACL,MAAON,EACP,OAAQC,EACR,MAAOE,EAAM,MACb,YAAaA,EAAM,aAAe,mCAClC,MAAQC,GAA2B,GACnC,SAAWG,GAAMb,EAASS,EAAM,KAAMI,EAAE,OAAO,KAAK,EACnD,GAAIJ,EAAM,OAAS,CAAC,EACvB,EAGJ,IAAK,SACH,SACE,QAACG,GAAA,CACC,KAAK,KACL,KAAK,SACL,MAAON,EACP,OAAQC,EACR,MAAOE,EAAM,MACb,YAAaA,EAAM,aAAe,uBAClC,MAAQC,GAA2B,GACnC,SAAWG,GAAMb,EAASS,EAAM,KAAM,OAAOI,EAAE,OAAO,KAAK,CAAC,EAC3D,GAAIJ,EAAM,OAAS,CAAC,EACvB,EAGJ,IAAK,OACH,SACE,QAACK,GAAA,CACC,KAAK,KACL,MAAOR,EACP,OAAQC,EACR,MAAOE,EAAM,MACb,YAAaA,EAAM,aAAe,oBAClC,MAAOC,EACP,SAAWK,GAAMf,EAASS,EAAM,KAAMM,CAAC,EACtC,GAAIN,EAAM,OAAS,CAAC,EACvB,EAGJ,IAAK,aACH,SACE,QAACO,GAAA,CACC,KAAK,KACL,MAAOV,EACP,OAAQC,EACR,MAAOE,EAAM,MACb,YAAaA,EAAM,aAAe,gCAClC,MAAQC,GAA+C,CAAC,KAAM,IAAI,EAClE,SAAWO,GAAUjB,EAASS,EAAM,KAAMQ,CAAK,EAC9C,GAAIR,EAAM,OAAS,CAAC,EACvB,EAGJ,IAAK,iBACH,SACE,SAAC,OAAI,UAAU,wBACZ,UAAAA,EAAM,UAAS,QAAC,QAAK,UAAU,uDAAwD,SAAAA,EAAM,MAAM,KACpG,QAACS,GAAA,CACC,KAAK,KACL,MAAOZ,EACP,MAAQI,GAA6B,CAAC,EACtC,SAAWC,GAAQX,EAASS,EAAM,KAAME,CAAG,EAC1C,GAAIF,EAAM,OAAS,CAAC,EAErB,oBAAC,OAAI,UAAU,uBACZ,SAAAA,EAAM,SAAS,IAAKU,MACnB,QAACC,GAAA,CAEC,MAAO,OAAOD,EAAI,KAAK,EACvB,SAAUA,EAAI,SACd,KAAK,KACL,MAAOb,EACP,MAAOa,EAAI,OALN,OAAOA,EAAI,KAAK,CAMvB,CACD,EACH,EACF,GACF,EAGJ,QACE,OAAO,IACX,CACF,EAWA,SACE,SAAC,OAAI,UAAU,kEACb,qBAAC,OAAI,UAAWjB,IAAW,OAAS,QAVtCC,IAAa,EACT,cACAA,IAAa,EACX,6BACAA,IAAa,EACX,4CACA,4BAIkD,qBAAuB,wBAC5E,SAAAL,EAAQ,IAAKW,GAAU,CACtB,IAAMY,EAAeZ,EAAM,QAAU,YAAYA,EAAM,OAAO,GAAK,GACnE,SACE,QAAC,OAAqB,UAAW,UAAUY,CAAY,GACpD,SAAAb,EAAYC,CAAK,GADVA,EAAM,IAEhB,CAEJ,CAAC,EACH,EAECL,GAAaH,MACZ,QAAC,OAAI,UAAU,yDACb,oBAACqB,GAAA,CACC,KAAK,KACL,QAAQ,QACR,QAASrB,EACT,UAAU,+DAET,SAAAI,EACH,EACF,GAEJ,CAEJ,CAEA,IAAOkB,GAAQ1B,GFtEP,IAAA2B,GAAA,6BAvDFC,GAAsD,CAAC,EAEtD,SAASC,GAAgG,CAC9G,OAAAC,EACA,QAAAC,EACA,eAAAC,EACA,YAAAC,EACA,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,OAAAC,EAAS,KACT,QAAAC,EAAU,GACV,OAAAC,EAAS,GACT,cAAAC,EAAgB,IAChB,UAAAC,EACA,WAAAC,EACA,WAAAC,EACA,WAAAC,EACA,YAAAC,EACA,iBAAAC,EAAmBjB,GACnB,iBAAAkB,EAAmB,WACnB,mBAAAC,EAAqB,EACrB,iBAAAC,EAAmB,GACnB,iBAAAC,EACA,mBAAAC,EACA,eAAAC,EACA,aAAAC,EACA,eAAAC,EACA,mBAAAC,EACA,eAAAC,EACA,YAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,UAAAC,EAAY,EACd,EAAqC,CACnC,GAAI,CAAC7B,EAAQ,OAAO,KAEpB,IAAM8B,EACJxB,IAAW,OAAS,eAAiBF,IAAS,MAAQA,IAAS,KAAO,aAAe,aAEjF2B,KACJ,SAAC,OACC,IAAKL,EACL,MAAO,CACL,GAAGD,EACH,OAAQO,GAAgB,MAC1B,EACC,GAAGL,EAAiB,CACnB,UAAW,yHAAyHG,CAAe,IAAID,CAAS,EAClK,CAAC,EAGA,UAAAjB,EAGAE,GAAeA,EAAY,OAAS,GAAKM,MACxC,QAACa,GAAA,CACC,QAASnB,EACT,OAAQC,EACR,SAAUK,EACV,QAASC,EACT,OAAQL,EACR,SAAUC,EACV,UAAWC,EACX,UAAWC,EACX,MAAOd,EACP,OAAQC,EACV,KAIF,QAAC,OACC,KAAK,UACL,SAAU,GACV,MAAO,CACL,UAAW,OAAOG,GAAkB,SAAW,GAAGA,CAAa,KAAOA,CACxE,EACA,UAAW,kGACTF,EAAU,aAAe,aAC3B,GAEC,SAAAN,EAAQ,SAAW,EAClBM,KACE,SAAC,OAAI,UAAU,uFACb,qBAAC2B,GAAA,CAAQ,UAAU,mCAAmC,KACtD,QAAC,QAAK,sBAAU,GAClB,KAEA,QAAC,OAAI,UAAU,YACb,oBAACC,GAAA,CACC,KAAK,KACL,MAAM,SACN,YAAazB,GAAa,gBAC1B,UAAU,OACT,GAAGC,EACN,EACF,GAGD,IAAM,CACL,IAAMyB,EAAoB,IAAI,IAAIlC,CAAc,EAChD,OAAOD,EAAQ,IAAI,CAACoC,EAAQC,IAAU,CACpC,IAAMC,EAAaH,EAAkB,IAAIC,EAAO,KAAK,EAGrD,SACE,QAACG,GAAA,CAEC,IAAMC,GAAS,CACbb,EAAgB,QAAQU,CAAK,EAAIG,CACnC,EACA,OAAQJ,EACR,WAAYE,EACZ,SAVapC,IAAgBmC,EAW7B,KAAMlC,EACN,MAAOC,EACP,OAAQC,EACR,SAAU+B,EAAO,SACjB,aAAcf,EACd,QAAS,IAAMC,EAAec,CAAM,EACpC,aAAc,IAAMb,EAAmBc,CAAK,GAbvC,OAAOD,EAAO,KAAK,CAc1B,CAEJ,CAAC,CACH,GAAG,EAEP,EAGCxB,GACH,EAGF,OAAIL,KACK,QAAC,mBAAgB,SAAAuB,EAAY,EAG/BA,CACT,CAEA,IAAOW,GAAQ3C,GG7Lf,IAAA4C,GAA+C,iBAUxC,SAASC,GACdC,EACAC,EAAgB,IAIhB,CACA,IAAMC,KAAc,WAAOF,CAAQ,EAC7BG,KAAW,WAA6C,IAAI,KAElE,cAAU,IAAM,CACdD,EAAY,QAAUF,CACxB,EAAG,CAACA,CAAQ,CAAC,EAEb,IAAMI,KAAS,gBAAY,IAAM,CAC3BD,EAAS,UACX,aAAaA,EAAS,OAAO,EAC7BA,EAAS,QAAU,KAEvB,EAAG,CAAC,CAAC,EAEL,uBAAU,IACDC,EACN,CAACA,CAAM,CAAC,EAaJ,CACL,aAZgB,gBAChB,IAAIC,IAAe,CACjBD,EAAO,EAEPD,EAAS,QAAU,WAAW,IAAM,CAClCD,EAAY,QAAQ,GAAGG,CAAI,CAC7B,EAAGJ,CAAK,CACV,EACA,CAACG,EAAQH,CAAK,CAChB,EAIE,OAAAG,CACF,CACF,CNqYQ,IAAAE,GAAA,6BAnaFC,GAA2B,CAAC,EAElC,SAASC,GACPC,EAC4C,CAC5C,MAAO,EAAQA,EAAM,QACvB,CAEO,SAASC,GACdD,EACA,CACA,GAAM,CACJ,IAAAE,EACA,QAAAC,EAAUL,GACV,KAAAM,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,OAAAC,EAAS,KACT,GAAAC,EACA,MAAAC,EACA,eAAAC,EAAiB,MAEjB,YAAAC,EAAc,eACd,WAAAC,EACA,aAAAC,EACA,UAAAC,EAAY,EAAQD,EACpB,WAAAE,EAAa,GACb,WAAAC,EAAa,GACb,SAAAC,EAAW,GACX,WAAAC,EAAa,GACb,KAAAC,EACA,WAAAC,EAAa,GACb,WAAAC,EAAa,SACb,gBAAAC,EAAkB,UAClB,kBAAAC,EACA,YAAaC,EACb,eAAAC,EACA,YAAAC,EACA,iBAAkBC,EAClB,iBAAAC,EAAmB,WACnB,mBAAAC,EAAqB,EACrB,iBAAAC,EAAmB,GACnB,iBAAAC,EACA,mBAAAC,EACA,WAAAC,EACA,WAAAC,EACA,SAAAC,EACA,WAAAC,EAAa,IACb,SAAAC,EACA,QAASC,EAAc,GACvB,UAAWC,EACX,UAAAC,EACA,WAAAC,EACA,UAAAC,EAAY,GACZ,OAAAC,GAAS,GACT,UAAAC,EAAY,eACZ,cAAAC,GAAgB,IAChB,aAAAC,GACA,WAAAC,GACA,YAAAC,EACA,aAAAC,EACA,UAAAC,GAAY,GACZ,iBAAAC,EAAmB,GACnB,cAAAC,EAAgB,EAClB,EAAIpD,EAEEqD,EAAatD,GAAcC,CAAK,EAChCsD,GAAU,GAAQf,GAAiBD,GAGnCiB,GAAeF,EAA6D,KAA/CrD,EAC7BwD,GAAaH,EAAcrD,EAA8C,KAEzE,CAACyD,GAAoBC,EAAqB,KAAI,aAClDH,IAAa,cAAgB,IAC/B,EAEM,CAACI,GAAmBC,CAAoB,KAAI,aAA8BJ,IAAY,cAAgB,CAAC,CAAC,EAExGK,EAAqBN,IAAa,QAAU,OAC5CO,EAAoBN,IAAY,QAAU,OAE1CO,GAAuBP,IAAY,MACnCQ,KAAoB,YAAQ,IACzBF,EAAqBC,IAAwB,CAAC,EAAKJ,GACzD,CAACG,EAAmBC,GAAsBJ,EAAiB,CAAC,EAEzDM,GAAwBV,IAAa,MACrCW,MAAqB,YAAQ,IAC1BL,EAAsBI,IAAyB,KAAQR,GAC7D,CAACI,EAAoBI,GAAuBR,EAAkB,CAAC,EAI5DU,MAAmB,WAAsD,IAAI,GAAK,KAExF,cAAU,IAAM,CACdhE,EAAQ,QAASiE,GAAQ,CACvBD,GAAiB,QAAQ,IAAIC,EAAI,MAAOA,CAAG,CAC7C,CAAC,CACH,EAAG,CAACjE,CAAO,CAAC,EAEZ,IAAMkE,MAAkB,YAAmC,IACrDhB,EACKW,EAAkB,IAAKM,GACdnE,EAAQ,KAAMoE,IAAMA,GAAE,QAAUD,CAAG,GAAKH,GAAiB,QAAQ,IAAIG,CAAG,GAE3E,CACP,MAAOA,EACP,MAAO,OAAOA,CAAG,CACnB,CAEH,EAGCJ,IAAuB,KAGlB,CADL/D,EAAQ,KAAMoE,IAAMA,GAAE,QAAUL,EAAkB,GAAKC,GAAiB,QAAQ,IAAID,EAAkB,GAE7F,CACP,MAAOA,GACP,MAAO,OAAOA,EAAkB,CAClC,CACF,EAGK,CAAC,EACP,CAACb,EAAYW,EAAmBE,GAAoB/D,CAAO,CAAC,EAGzD,CAACqE,GAAQC,EAAS,KAAI,aAAS,EAAK,EACpC,CAACC,GAAaC,EAAc,KAAI,aAAwB,IAAI,EAG5D,CAACC,GAAoBC,EAAqB,KAAI,aAAS,EAAE,EACzDC,GAAqBtD,IAA0B,OAC/CuD,GAAcD,GAAqBtD,EAAwBoD,GAG3D,CAAE,UAAAI,EAAU,EAAIC,GAAqB,CAACC,EAAeC,KAAsB,CAC3E9D,IAAe,UACjBc,IAAW+C,EAAOC,EAAO,CAE7B,EAAG/C,CAAU,EAEPgD,GAAsBd,GAAgB,CACrCQ,IACHD,GAAsBP,CAAG,EAE3B7C,IAAiB6C,CAAG,EACfE,IACHC,GAAU,EAAI,EAEhBO,GAAUV,EAAKe,EAAc,CAC/B,EAEM,CAACC,GAAiBC,EAAkB,KAAI,aAA4B,IAAM,CAC9E,IAAMC,EAAmC,CAAC,EAC1C,OAAA9D,GAAa,QAAS+D,IAAM,CACtBA,GAAE,eAAiB,SACrBD,EAAQC,GAAE,IAAI,EAAIA,GAAE,aAExB,CAAC,EACMD,CACT,CAAC,EAEKH,GAAkB1D,GAA0B2D,GAE5CI,GAAqB,CAACvE,EAAcmD,KAAiB,CACzD,IAAMqB,GAAc,CAClB,GAAGN,GACH,CAAClE,CAAI,EAAGmD,EACV,EAEK3C,GACH4D,GAAmBI,EAAW,EAEhC3D,IAAqB2D,EAAW,EAChCX,GAAUD,GAAaY,EAAW,CACpC,EAEMC,GAAqB,IAAM,CAC/B,IAAMC,EAAuC,CAAC,EAC9CnE,GAAa,QAAS+D,IAAM,CACtBA,GAAE,eAAiB,SACrBI,EAAYJ,GAAE,IAAI,EAAIA,GAAE,aAE5B,CAAC,EACI9D,GACH4D,GAAmBM,CAAgC,EAErD7D,IAAqB6D,CAAuB,EAC5Cb,GAAUD,GAAac,CAAuB,CAChD,EAGMC,MAAkB,YAAQ,IAAM,CACpC,GAAIzE,IAAe,SACjB,OAAOlB,EAGT,IAAI4F,EAAO5F,EAGL6F,GAAUjB,GAAY,KAAK,EACjC,GAAIiB,GAAS,CACX,IAAMC,GAAiF,CAAC,EAClFC,GAAY,CACf9B,IAAiCA,GAAI,MACrCA,IAAiC,OAAOA,GAAI,KAAK,EACjDA,IAAiC,OAAOA,GAAI,aAAe,EAAE,CAChE,EACA,QAAW+B,MAAQJ,EAAM,CACvB,IAAMK,MAAO,aAASD,GAAMH,GAAS,CAAE,UAAAE,EAAU,CAAC,EAC9CE,GAAK,QACPH,GAAO,KAAK,CAAE,KAAAE,GAAM,KAAAC,EAAK,CAAC,CAE9B,CACAH,GAAO,KAAK,CAACI,GAAGC,QAAM,iBAAaD,GAAE,KAAMC,GAAE,IAAI,CAAC,EAClDP,EAAOE,GAAO,IAAKM,IAAMA,GAAE,IAAI,CACjC,CAGA,OAAIlE,IACF0D,EAAOA,EAAK,OAAQ3B,IAAQ/B,EAAS+B,GAAKW,GAAaM,EAAc,CAAC,GAGjEU,CACT,EAAG,CAAC5F,EAASkB,EAAY0D,GAAa1C,EAAUgD,EAAc,CAAC,EAGzDmB,MAAc,WAA+B,CAAC,CAAC,EAG/CC,GAAoB,GAAQzF,GAAcC,GAC1CyF,GAAgB,CAAC3F,GAAc,CAAC0F,GAEhC,CAAE,KAAAE,GAAM,eAAAC,GAAgB,QAAAC,EAAQ,KAAI,gBAAY,CACpD,UAAAjE,EACA,KAAM4B,IAAUkC,GAChB,aAAeI,GAAa,CAEtBJ,KAAkB,CAACpD,IAAWkB,IAAU,CAACsC,KAC3CrC,GAAUqC,CAAQ,EACbA,IACHnC,GAAe,IAAI,EACf,CAACG,IAAsB,CAACzB,GAC1BwB,GAAsB,EAAE,GAIhC,EACA,qBAAsB,cACtB,UAAW,GACX,WAAY,IAAC,GAAAkC,QAAiB,CAAC,KAAG,GAAAC,MAAe,KAAG,GAAAC,OAAgB,CAAE,QAAS,CAAE,CAAC,CAAC,CACrF,CAAC,EAEKC,MAAQ,aAASL,GAAS,CAC9B,QAASH,KAAkB,CAACpD,IAAWkB,GACzC,CAAC,EAEK2C,MAAU,eAAWN,EAAO,EAC5BO,MAAO,YAAQP,GAAS,CAAE,KAAM,SAAU,CAAC,EAE3CQ,MAAiB,sBAAkBR,GAAS,CAChD,QAASL,GACT,YAAA9B,GACA,WAAYC,GACZ,KAAM,EACR,CAAC,EAEK,CAAE,kBAAA2C,GAAmB,iBAAAC,EAAiB,KAAI,oBAAgB,CAACL,GAAOC,GAASC,GAAMC,EAAc,CAAC,EAGhGG,MAAqB,gBACxBC,GAAoC,CACnC,GAAI,EAAAA,EAAO,UAAY1G,GAAcC,GAKrC,GAFAmD,GAAiB,QAAQ,IAAIsD,EAAO,MAAOA,CAAM,EAE7CpE,EAAY,CACd,IAAMG,GAAaxD,EAEb0H,GADS1D,EAAkB,SAASyD,EAAO,KAAK,EAElDzD,EAAkB,OAAQ2D,IAAMA,KAAMF,EAAO,KAAK,EAClD,CAAC,GAAGzD,EAAmByD,EAAO,KAAK,EAElC3D,GACHF,EAAqB8D,EAAU,EAGjC,IAAME,GAAoBF,GAAW,IAAKpD,IAEtCnE,EAAQ,KAAMoE,IAAMA,GAAE,QAAUD,EAAG,GACnCH,GAAiB,QAAQ,IAAIG,EAAG,GAAK,CACnC,MAAOA,GACP,MAAO,OAAOA,EAAG,CACnB,CAEH,EAEDd,GAAW,WAAWkE,GAAYE,EAAiB,EAE9C9C,IACHD,GAAsB,EAAE,CAE5B,KAAO,CACL,IAAMtB,GAAcvD,EACf6D,GACHH,GAAsB+D,EAAO,KAAK,EAEpClE,GAAY,WAAWkE,EAAO,MAAOA,CAAM,EAC3ChD,GAAU,EAAK,EACVK,IACHD,GAAsB,EAAE,CAE5B,CACF,EACA,CACExB,EACAtC,EACAC,EACAhB,EACAgE,EACAF,EACA3D,EACA2E,GACAjB,CACF,CACF,EAEMgE,MAAkB,gBACrBJ,GAAoC,CACnC,GAAI1G,GAAcC,GAAc,CAACqC,EAAY,OAC7C,IAAMqE,GAAa1D,EAAkB,OAAQ2D,IAAMA,KAAMF,EAAO,KAAK,EAEhE3D,GACHF,EAAqB8D,EAAU,EAGjC,IAAME,GAAoBF,GAAW,IAAKpD,IAEtCnE,EAAQ,KAAMoE,IAAMA,GAAE,QAAUD,EAAG,GACnCH,GAAiB,QAAQ,IAAIG,EAAG,GAAK,CACnC,MAAOA,GACP,MAAO,OAAOA,EAAG,CACnB,CAEH,EAEGjB,GACDrD,EAA4C,WAAW0H,GAAYE,EAAiB,CAEzF,EACA,CAAC7G,EAAYC,EAAYqC,EAAYW,EAAmBF,EAAmB3D,EAASH,CAAK,CAC3F,EAEM8H,MAAc,gBACjBC,GAAwB,CACvBA,EAAE,gBAAgB,EACd,EAAAhH,GAAcC,KAEdqC,GACGS,GACHF,EAAqB,CAAC,CAAC,EAExB5D,EAA4C,WAAW,CAAC,EAAG,CAAC,CAAC,IAEzD6D,GACHH,GAAsB,IAAI,EAE3B1D,EAA6C,WAAW,KAAM,IAAI,GAGhE8E,IACHD,GAAsB,EAAE,EAE5B,EACA,CAAC9D,EAAYC,EAAYqC,EAAYrD,EAAO8D,EAAmBD,EAAoBiB,EAAkB,CACvG,EAGMkD,GAAwBD,GAA6C,CACzE,IAAME,GAAYF,EAAE,eAAoC,OAAShD,GACjE,GAAIgD,EAAE,MAAQ,cAAgB,CAACE,IAAYA,GAAS,SAAW,IAAM5E,GAAcgB,GAAgB,OAAS,EAAG,CAC7G0D,EAAE,eAAe,EACjB,IAAMG,GAAU7D,GAAgBA,GAAgB,OAAS,CAAC,EACtD6D,IACFL,GAAgBK,EAAO,CAE3B,SAAWH,EAAE,MAAQ,SAAWvD,IAAUE,KAAgB,KAAM,CAC9DqD,EAAE,eAAe,EACjB,IAAMI,GAAerC,GAAgBpB,EAAW,EAC5CyD,IACFX,GAAmBW,EAAY,CAEnC,MAAWJ,EAAE,MAAQ,aAAe,CAACvD,IACnCC,GAAU,EAAI,CAElB,EAGM2D,GAAiBC,GAAqB3H,CAAc,GAAK2H,GAAqB,IAE9EC,MAAc,UAAM,EAEpBC,GAAY,GADD/H,GAAM8H,EACM,WAE7B,SACE,SAAC,OACC,IAAKpI,EACL,GAAIM,EACJ,UAAW,GAAG4H,GAAe,SAAS,IAAIlF,EAAS,GACnD,gBAAenC,EACf,eAAcD,EAGb,UAAAL,MACC,SAAC,SAAM,QAAS8H,GAAW,UAAWH,GAAe,MAClD,UAAA3H,EACAS,MACC,QAAC,QAAK,UAAU,sBAAsB,cAAY,OAAO,aAEzD,GAEJ,KAIF,SAAC,OAAI,UAAU,0BACb,qBAACsH,GAAA,CACC,GAAID,GACJ,WAAY5B,GAAK,aACjB,kBAAmBW,GACnB,gBAAiBjD,GACjB,OAAQG,GACR,KAAMpE,EACN,QAASC,EACT,MAAOC,EACP,OAAQC,EACR,YAAagB,GAAqBZ,EAClC,SAAUI,EACV,SAAU0F,GACV,UAAW3F,EACX,SAAUuC,EAEV,YAAaA,EAAcrD,EAA4C,YAAc,OACrF,WAAYoB,EACZ,gBAAiBE,EACjB,YAAayD,GACb,eAAgBK,GAChB,YAAayC,GACb,QAASC,GACT,UAAWpF,EACX,QAASY,GACT,aAAcR,GACd,WAAYC,GACZ,YAAaC,EACb,UAAWgF,GACX,UAAW7E,EACb,KAEA,QAACsF,GAAA,CACC,OAAQjE,GACR,QAASsB,GACT,eACEzC,EACIW,EACAE,IAAuB,KACrB,CAACA,EAAkB,EACnB,CAAC,EAET,YAAaQ,GACb,KAAMtE,EACN,MAAOE,EACP,OAAQC,EACR,QAAS+C,GACT,OAAQX,GACR,cAAeE,GACf,UAAWL,EACX,WAAYC,EACZ,WAAYR,EACZ,WAAYC,EACZ,YAAaR,EACb,iBAAkB2D,GAClB,iBAAkBzD,EAClB,mBAAoBC,EACpB,iBAAkBC,EAClB,iBAAkBC,EAClB,mBAAoB2D,GACpB,eAAgBE,GAChB,aAAc3C,EACd,eAAgBuE,GAChB,mBAAoB7C,GACpB,YAAagC,GAAK,YAClB,eAAgBC,GAChB,iBAAkBW,GAClB,gBAAiBf,GACjB,UAAWpD,EACb,GACF,EAGCjC,MACC,qBACG,SAAAkC,EACCW,EAAkB,IAAI,CAACM,EAAKoE,QAC1B,QAAC,SAAoC,KAAK,SAAS,KAAM,GAAGvH,CAAI,KAAM,MAAO,OAAOmD,CAAG,GAA3E,GAAGnD,CAAI,IAAImD,CAAG,IAAIoE,EAAG,EAAyD,CAC3F,EACCxE,IAAuB,QACzB,QAAC,SAAM,KAAK,SAAS,KAAM/C,EAAM,MAAO,OAAO+C,EAAkB,EAAG,EAClE,KACN,GAIArD,GAAgBD,OAChB,QAAC,OAAI,UAAW,WAAWE,EAAY,6BAA+B,8BAA8B,GACjG,SAAAD,GAAgBD,EACnB,GAEJ,CAEJ,CAEA,IAAO+H,GAAQ1I,GOliBf,IAAA2I,GAAoC,iBAS7B,SAASC,GAAeC,EAAUC,EAAgB,IAA2B,CAClF,GAAM,CAACC,EAAgBC,CAAiB,KAAI,aAAYH,CAAK,EAE7D,uBAAU,IAAM,CACd,IAAMI,EAAQ,WAAW,IAAM,CAC7BD,EAAkBH,CAAK,CACzB,EAAGC,CAAK,EAER,MAAO,IAAM,CACX,aAAaG,CAAK,CACpB,CACF,EAAG,CAACJ,EAAOC,CAAK,CAAC,EAEVC,CACT,CCxBA,IAAAG,GAA2E,iBCEpE,IAAMC,GAA6D,CACxE,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,cACJ,KAAM,cACR,EAEaC,GAA6E,CACxF,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,GAAI,IACN,EAEaC,GAcT,CACF,GAAI,CACF,eAAgB,eAChB,gBAAiB,MACjB,WAAY,UACZ,cAAe,UACf,SAAU,GACV,UAAW,cACX,SAAU,cACV,UAAW,mBACX,WAAY,oBACZ,IAAK,SACP,EACA,GAAI,CACF,eAAgB,gBAChB,gBAAiB,MACjB,WAAY,UACZ,cAAe,UACf,SAAU,GACV,UAAW,UACX,SAAU,cACV,UAAW,eACX,WAAY,qBACZ,IAAK,OACP,EACA,GAAI,CACF,eAAgB,gBAChB,gBAAiB,MACjB,WAAY,UACZ,cAAe,UACf,SAAU,GACV,UAAW,UACX,SAAU,UACV,UAAW,iBACX,WAAY,mBACZ,IAAK,OACP,EACA,GAAI,CACF,eAAgB,gBAChB,gBAAiB,MACjB,WAAY,UACZ,cAAe,UACf,SAAU,GACV,UAAW,YACX,SAAU,UACV,UAAW,mBACX,WAAY,eACZ,IAAK,SACP,EACA,GAAI,CACF,eAAgB,gBAChB,gBAAiB,MACjB,WAAY,UACZ,cAAe,UACf,SAAU,GACV,UAAW,UACX,SAAU,UACV,UAAW,eACX,WAAY,eACZ,IAAK,OACP,CACF,EAEaC,GAWT,CAEF,QAAS,CACP,QAAS,CACP,KAAM,gFACN,OAAQ,kFACR,UAAW,mBACX,WAAY,8BACd,EACA,UAAW,CACT,KAAM,oFACN,OAAQ,0FACR,UAAW,qBACX,WAAY,gCACd,EACA,QAAS,CACP,KAAM,gFACN,OAAQ,mFACR,UAAW,mBACX,WAAY,8BACd,EACA,MAAO,CACL,KAAM,4EACN,OAAQ,0EACR,UAAW,iBACX,WAAY,4BACd,EACA,QAAS,CACP,KAAM,gFACN,OAAQ,kFACR,UAAW,mBACX,WAAY,8BACd,EACA,QAAS,CACP,KAAM,gFACN,OAAQ,kFACR,UAAW,mBACX,WAAY,8BACd,EACA,KAAM,CACJ,KAAM,0EACN,OAAQ,sEACR,UAAW,gBACX,WAAY,2BACd,CACF,EAGA,OAAQ,CACN,QAAS,CACP,KAAM,wGACN,OAAQ,gFACR,UAAW,mBACX,WAAY,8BACd,EACA,UAAW,CACT,KAAM,kHACN,OAAQ,wFACR,UAAW,qBACX,WAAY,gCACd,EACA,QAAS,CACP,KAAM,yGACN,OAAQ,gFACR,UAAW,mBACX,WAAY,8BACd,EACA,MAAO,CACL,KAAM,8FACN,OAAQ,wEACR,UAAW,iBACX,WAAY,4BACd,EACA,QAAS,CACP,KAAM,wGACN,OAAQ,gFACR,UAAW,mBACX,WAAY,8BACd,EACA,QAAS,CACP,KAAM,wGACN,OAAQ,gFACR,UAAW,mBACX,WAAY,8BACd,EACA,KAAM,CACJ,KAAM,yFACN,OAAQ,oEACR,UAAW,gBACX,WAAY,2BACd,CACF,EAGA,MAAO,CACL,QAAS,CACP,KAAM,qGACN,OAAQ,+EACR,UAAW,mBACX,WAAY,8BACd,EACA,UAAW,CACT,KAAM,yGACN,OAAQ,uFACR,UAAW,qBACX,WAAY,gCACd,EACA,QAAS,CACP,KAAM,mGACN,OAAQ,gFACR,UAAW,mBACX,WAAY,8BACd,EACA,MAAO,CACL,KAAM,iGACN,OAAQ,uEACR,UAAW,iBACX,WAAY,4BACd,EACA,QAAS,CACP,KAAM,qGACN,OAAQ,+EACR,UAAW,mBACX,WAAY,8BACd,EACA,QAAS,CACP,KAAM,qGACN,OAAQ,+EACR,UAAW,mBACX,WAAY,8BACd,EACA,KAAM,CACJ,KAAM,+FACN,OAAQ,mEACR,UAAW,gBACX,WAAY,2BACd,CACF,CACF,ECnPO,SAASC,IAAqB,CACnC,MAAO,UAAY,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,EAAG,CAAC,EAAI,IAAM,KAAK,IAAI,CACjF,CAEO,SAASC,GAAYC,EAAeC,EAAmB,EAAW,CACvE,GAAI,CAAC,CAACD,EAAO,MAAO,MACpB,IAAME,EAAI,KACJC,EAAKF,EAAW,EAAI,EAAIA,EACxBG,EAAQ,CAAC,IAAK,KAAM,KAAM,KAAM,IAAI,EACpCC,EAAI,KAAK,MAAM,KAAK,IAAIL,CAAK,EAAI,KAAK,IAAIE,CAAC,CAAC,EAClD,MAAO,GAAG,YAAYF,EAAQ,KAAK,IAAIE,EAAGG,CAAC,GAAG,QAAQF,CAAE,CAAC,CAAC,IAAIC,EAAMC,CAAC,CAAC,EACxE,CAEO,SAASC,GAAuBC,EAA+E,CACpH,OAAKA,EAED,OAAOA,GAAQ,SACV,CACL,CACE,GAAIT,GAAW,EACf,KAAMS,EAAI,MAAM,GAAG,EAAE,IAAI,GAAK,YAC9B,IAAKA,EACL,OAAQ,SACV,CACF,EAGE,MAAM,QAAQA,CAAG,EACZA,EAAI,IAAKC,GACV,OAAOA,GAAS,SACX,CACL,GAAIV,GAAW,EACf,KAAMU,EAAK,MAAM,GAAG,EAAE,IAAI,GAAK,YAC/B,IAAKA,EACL,OAAQ,SACV,EAEKA,CACR,EAGI,CAACD,CAAG,EA3BM,CAAC,CA4BpB,CAOO,SAASE,GAAaC,EAAYC,EAAqE,CAC5G,GAAI,CAACA,EAAS,MAAO,CAAE,QAAS,EAAK,EAGrC,GAAIA,EAAQ,SAAWD,EAAK,KAAOC,EAAQ,QACzC,MAAO,CACL,QAAS,GACT,MAAO,+FAA4CZ,GAAYY,EAAQ,OAAO,CAAC,GACjF,EAIF,GAAIA,EAAQ,QAAUA,EAAQ,OAAO,KAAK,IAAM,IAAK,CACnD,IAAMC,EAAgBD,EAAQ,OAAO,MAAM,GAAG,EAAE,IAAKE,GAAMA,EAAE,KAAK,EAAE,YAAY,CAAC,EAE3EC,EAAWJ,EAAK,KAAK,YAAY,EACjCK,EAAWL,EAAK,KAAK,YAAY,EAavC,GAAI,CAXYE,EAAc,KAAMI,GAAS,CAC3C,GAAIA,EAAK,WAAW,GAAG,EACrB,OAAOD,EAAS,SAASC,CAAI,EAE/B,GAAIA,EAAK,SAAS,IAAI,EAAG,CACvB,IAAMC,EAAWD,EAAK,MAAM,GAAG,EAAE,CAAC,EAClC,OAAOF,EAAS,WAAWG,EAAW,GAAG,CAC3C,CACA,OAAOH,IAAaE,CACtB,CAAC,EAGC,MAAO,CACL,QAAS,GACT,MAAO,sIAA0DL,EAAQ,MAAM,EACjF,CAEJ,CAEA,MAAO,CAAE,QAAS,EAAK,CACzB,CAEO,SAASO,GAAeR,EAAYS,EAA8B,CACvE,MAAO,CACL,GAAIrB,GAAW,EACf,KAAMY,EAAK,KACX,KAAMA,EAAK,KACX,KAAMA,EAAK,KACX,IAAAS,EACA,KAAAT,EACA,OAAQ,SACV,CACF,CAEO,SAASU,GAAeZ,EAAsB,CACnD,GAAIA,GAAM,KAAOA,EAAK,IAAI,WAAW,OAAO,EAC1C,GAAI,CACF,IAAI,gBAAgBA,EAAK,GAAG,CAC9B,MAAQ,CAER,CAEJ,CC/GA,IAAAa,GAAoC,iBCA7B,IAAMC,GAAmB,CAAC,MAAO,OAAQ,MAAO,MAAO,OAAQ,MAAO,MAAO,MAAO,OAAQ,MAAM,EAE5FC,GAAiB,CAAC,KAAK,EAEvBC,GAAmB,CAAC,MAAO,OAAQ,MAAO,MAAO,MAAO,KAAK,EAE7DC,GAAmB,CAAC,MAAO,MAAO,MAAO,MAAO,OAAQ,KAAK,EAE7DC,GAAsB,CAAC,MAAO,OAAQ,MAAO,OAAQ,MAAO,OAAQ,MAAO,KAAK,ECLtF,SAASC,GAAYC,EAAwB,GAAY,CAC9D,GAAI,CAACA,EAAe,MAAO,GAC3B,IAAMC,EAAYD,EAAc,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,GAAK,GAC1DE,EAAWD,EAAU,MAAM,GAAG,EAAE,IAAI,GAAKA,EAAU,MAAM,IAAI,EAAE,IAAI,GAAK,GACxEE,EAAeD,EAAS,YAAY,GAAG,EAC7C,OAAIC,GAAgB,EAAUD,EACvBA,EAAS,MAAM,EAAGC,CAAY,CACvC,CAEO,SAASC,GAAiBJ,EAAwB,GAAY,CACnE,IAAMC,EAAYD,EAAc,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,GAAK,GAC1DK,EAAWJ,EAAU,YAAY,GAAG,EAC1C,OAAII,IAAa,GAAW,GACrBJ,EAAU,MAAMI,EAAW,CAAC,EAAE,YAAY,CACnD,CAEO,SAASC,GAAYN,EAAwB,GAAc,CAChE,IAAMO,EAAMH,GAAiBJ,CAAa,EAC1C,OAAIQ,GAAiB,SAASD,CAAG,EAAU,QACvCE,GAAe,SAASF,CAAG,EAAU,MACrCG,GAAiB,SAASH,CAAG,EAAU,QACvCI,GAAiB,SAASJ,CAAG,EAAU,QACvCK,GAAoB,SAASL,CAAG,EAAU,WAEvC,OACT,CAEO,SAASM,GAAqBC,EAKnC,CACA,OAAKA,EAIDA,aAAiB,KACZ,CACL,KAAMf,GAAYe,EAAM,IAAI,EAC5B,KAAMR,GAAYQ,EAAM,IAAI,EAC5B,KAAMA,EACN,WAAY,MACd,EAGK,CACL,KAAMA,EAAM,MAAQf,GAAYe,GAAO,GAAG,EAC1C,KAAMR,GAAYQ,GAAO,GAAG,EAC5B,KAAM,OACN,WAAYA,CACd,EAjBS,CAAE,KAAM,OAAQ,KAAM,QAAqB,KAAM,OAAW,WAAY,MAAU,CAkB7F,CAEO,SAASC,GAAaC,EAAaC,EAAyB,CACjE,GAAI,CAACD,EAAK,OACV,IAAME,EAAO,SAAS,cAAc,GAAG,EACvCA,EAAK,KAAOF,EACZ,IAAMf,EAAYe,EAAI,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,GAAK,GAChDG,EAAmBlB,EAAU,MAAM,GAAG,EAAE,IAAI,GAAKA,EAAU,MAAM,IAAI,EAAE,IAAI,GAAK,WACtFiB,EAAK,SAAWD,GAAYE,EAC5BD,EAAK,MAAM,QAAU,OACrB,SAAS,KAAK,YAAYA,CAAI,EAC9BA,EAAK,MAAM,EACX,WAAW,IAAM,CACf,GAAI,CACF,SAAS,KAAK,YAAYA,CAAI,CAChC,MAAQ,CAER,CACF,EAAG,GAAG,CACR,CC1EA,IAAAE,GAAqD,iBAQxCC,MAAc,kBAAuC,IAAI,EAEzDC,GAAiB,OAAM,eAAWD,EAAW,ECV1D,IAAAE,GAAgC,iBAChCC,GAA+B,iCC+CrB,IAAAC,GAAA,6BAtCK,SAARC,GAAqC,CAC1C,KAAAC,EAAO,EACP,SAAAC,EACA,UAAAC,EACA,WAAAC,EACA,YAAAC,EACA,iBAAAC,EACA,QAAAC,EACA,aAAAC,EACA,MAAAC,EACA,UAAAC,EAAY,EACd,EAA6B,CAC3B,GAAM,CAAE,OAAAC,EAAS,GAAM,QAAAC,EAAU,GAAM,MAAAC,EAAQ,GAAM,OAAAC,EAAS,GAAM,KAAAC,EAAO,GAAM,SAAAC,EAAW,EAAK,EAAIP,GAAS,CAAC,EAEzGQ,EAAc,KAAK,MAAMhB,EAAO,GAAG,EAEnCiB,EAAiB,IAAM,CACtBV,GAAc,KACnBW,GAAaX,EAAa,IAAKA,EAAa,IAAI,CAClD,EAEMY,EACJ,gSAEF,SACE,SAAC,OACC,UAAW,iKAAiKV,CAAS,GAGpL,UAAAC,MACC,QAAC,UACC,KAAK,SACL,aAAW,cACX,MAAM,kBACN,SAAUV,GAAQ,EAClB,QAASC,EACT,UAAWkB,EAEX,oBAACC,GAAA,CAAW,MAAO,GAAI,OAAQ,GAAI,EACrC,EAIDT,MACC,QAAC,UACC,KAAK,SACL,aAAW,eACX,MAAM,mBACN,SAAUX,GAAQ,GAClB,QAASE,EACT,UAAWiB,EAEX,oBAACE,GAAA,CAAY,MAAO,GAAI,OAAQ,GAAI,EACtC,EAIDT,MACC,SAAC,UACC,KAAK,SACL,aAAW,mEACX,MAAM,+BACN,QAASN,EACT,UAAU,6IAET,UAAAU,EAAY,KACf,GAGAH,GAAUC,GAAQC,OAAa,QAAC,OAAI,UAAU,uCAAuC,EAGtFF,MACC,QAAC,UACC,KAAK,SACL,aAAW,6DACX,MAAM,6DACN,QAAST,EACT,UAAWe,EAEX,oBAACG,GAAA,CAAc,MAAO,GAAI,OAAQ,GAAI,EACxC,EAIDT,MACC,QAAC,UACC,KAAK,SACL,aAAW,kDACX,MAAM,sDACN,QAASV,EACT,UAAWgB,EAEX,oBAACI,GAAA,CAAa,MAAO,GAAI,OAAQ,GAAI,EACvC,EAIDT,MACC,QAAC,UACC,KAAK,SACL,aAAW,iBACX,MAAM,iBACN,QAAST,EACT,UAAWc,EAEX,oBAACK,GAAA,CAAmB,MAAO,GAAI,OAAQ,GAAI,EAC7C,EAIDT,MACC,QAAC,UACC,KAAK,SACL,aAAW,+BACX,MAAM,sBACN,QAASE,EACT,UAAWE,EAEX,oBAACM,GAAA,CAAa,MAAO,GAAI,OAAQ,GAAI,EACvC,GAEJ,CAEJ,CDhGI,IAAAC,GAAA,6BAjCW,SAARC,GAA8B,CACnC,IAAAC,EACA,KAAAC,EACA,QAAAC,EAAU,GACV,QAAAC,EAAU,EACV,YAAAC,EAAc,GACd,aAAAC,EACA,SAAAC,CACF,EAAsB,CACpB,GAAM,CAACC,EAAMC,CAAO,KAAI,aAAgB,CAAE,EAAG,EAAG,EAAG,CAAE,CAAC,EAChD,CAACC,EAAMC,CAAO,KAAI,aAAS,CAAC,EAC5B,CAACC,EAAUC,CAAW,KAAI,aAAS,CAAC,EACpC,CAACC,EAAWC,CAAY,KAAI,aAAS,EAAK,EAE1CC,EAAe,IAAML,EAASM,GAAS,KAAK,IAAIb,EAAS,KAAK,OAAOa,EAAO,KAAQ,GAAG,EAAI,GAAG,CAAC,EAC/FC,EAAgB,IAAMP,EAASM,GAAS,KAAK,IAAId,EAAS,KAAK,OAAOc,EAAO,KAAQ,GAAG,EAAI,GAAG,CAAC,EAChGE,EAAiB,IAAMN,EAAaI,IAAUA,EAAO,IAAM,GAAG,EAC9DG,EAAkB,IAAMP,EAAaI,IAAUA,EAAO,GAAK,KAAO,GAAG,EACrEI,EAAuB,IAAMN,EAAcE,GAAS,CAACA,CAAI,EACzDK,EAAc,IAAM,CACxBb,EAAQ,CAAE,EAAG,EAAG,EAAG,CAAE,CAAC,EACtBE,EAAQ,CAAC,EACTE,EAAY,CAAC,EACbE,EAAa,EAAK,CACpB,EAEMQ,EAA0B,CAAE,IAAAtB,EAAK,KAAAC,CAAK,EAE5C,OAAKD,KAKH,SAAC,OAAI,UAAU,mCACb,qBAAC,OAAI,UAAU,oEACb,oBAAC,GAAAuB,QAAA,CACC,MAAOvB,EACP,KAAMO,EACN,KAAME,EACN,SAAUE,EACV,QAAST,EACT,QAASC,EACT,UAAW,GACX,iBAAkB,GAClB,SAAU,GACV,UAAU,UACV,aAAcK,EACd,aAAcE,EACd,iBAAkBE,EAClB,QAAS,CACP,eAAgBC,EAAY,eAAiB,EAC/C,EACA,MAAO,CACL,eAAgB,CACd,SAAU,WACV,MAAO,OACP,OAAQ,OACR,gBAAiB,aACnB,EACA,cAAe,CACb,QAAS,MACX,EACA,WAAY,CACV,OAAQ,MACV,CACF,EACF,EACF,EAECT,MACC,QAAC,OAAI,UAAU,iGACb,oBAACoB,GAAA,CACC,KAAMf,EACN,SAAUE,EACV,UAAWE,EACX,SAAUE,EACV,UAAWE,EACX,WAAYC,EACZ,YAAaC,EACb,iBAAkBC,EAClB,QAASC,EACT,aAAcC,EACb,GAAGjB,EACN,EACF,EAEDC,GACH,EA1DO,IA4DX,CJrCM,IAAAmB,GAAA,6BA9CS,SAARC,GAA6B,CAClC,WAAAC,EACA,WAAAC,EACA,UAAAC,EAAY,EACd,EAAqB,CACnB,IAAMC,EAAcC,GAAe,EAC7BC,EAAOF,GAAa,KACpBG,EAAcH,GAAa,YAE3B,CAACI,EAAYC,CAAa,KAAI,aAAiB,EAAE,KAEvD,cAAU,IAAM,CACd,GAAI,CAACH,EAAM,CAETG,EAAc,EAAE,EAChB,MACF,CAEA,GAAI,EAAEH,aAAgB,MAAO,CAC3B,IAAMI,EAAaC,GAAqBL,CAAI,EAC5CG,EAAcC,EAAW,YAAY,KAAO,EAAE,EAC9C,MACF,CAEA,IAAME,EAAM,IAAI,gBAAgBN,CAAI,EACpC,OAAAG,EAAcG,CAAG,EAEV,IAAM,CACX,IAAI,gBAAgBA,CAAG,CACzB,CACF,EAAG,CAACN,CAAI,CAAC,EAET,IAAMI,EAAaC,GAAqBL,CAAI,EACtCO,GAAe,OAAON,GAAgB,SAAWA,EAAc,KAAOG,EAAW,MAAQ,OAEzFI,EAAiB,IAAM,CACvBb,GAAcK,GAChBL,EAAWK,CAAI,EAEbE,GACFO,GAAaP,EAAYK,CAAW,CAExC,EAEA,OAAIH,EAAW,OAAS,WAEpB,QAACM,GAAA,CACC,IAAKR,EACL,KAAMK,EACL,GAAGX,EACN,KAKF,SAAC,OAAI,UAAW,mBAAmBC,CAAS,GAC1C,qBAAC,OAAI,UAAU,sGACb,oBAACc,GAAA,CAAa,MAAO,GAAI,OAAQ,GAAI,EACvC,KAEA,QAAC,MAAG,UAAU,uDAAuD,MAAOJ,EACzE,SAAAN,GAAeM,EAClB,KACA,QAAC,KAAE,UAAU,gCAAgC,6JAE7C,KAEA,SAAC,UACC,KAAK,SACL,QAASC,EACT,UAAU,oLAEV,qBAACG,GAAA,CAAa,MAAO,GAAI,OAAQ,GAAI,KACrC,QAAC,QAAK,oCAAc,GACtB,GACF,CAEJ,CMxFA,IAAAC,GAAwB,iBCEjB,IAAMC,GAAgC,IAEhCC,GAaT,CACF,GAAI,CACF,OAAQ,4BACR,OAAQ,UACR,KAAM,UACN,OAAQ,iBACR,MAAO,uDACP,YAAa,0CACb,UAAW,UACX,YAAa,2BACb,UAAW,UACb,EACA,GAAI,CACF,OAAQ,4BACR,OAAQ,QACR,KAAM,UACN,OAAQ,aACR,MAAO,yDACP,YAAa,0CACb,UAAW,QACX,YAAa,2BACb,UAAW,QACb,EACA,GAAI,CACF,OAAQ,4BACR,OAAQ,UACR,KAAM,UACN,OAAQ,aACR,MAAO,uDACP,YAAa,2CACb,UAAW,UACX,YAAa,yBACb,UAAW,QACb,EACA,GAAI,CACF,OAAQ,4BACR,OAAQ,QACR,KAAM,YACN,OAAQ,iBACR,MAAO,kDACP,YAAa,6CACb,UAAW,QACX,YAAa,yBACb,UAAW,UACb,EACA,GAAI,CACF,OAAQ,4BACR,OAAQ,UACR,KAAM,YACN,OAAQ,aACR,MAAO,mDACP,YAAa,6CACb,UAAW,UACX,YAAa,yBACb,UAAW,QACb,EACA,KAAM,CACJ,OAAQ,mEACR,OAAQ,UACR,KAAM,YACN,OAAQ,aACR,MAAO,mDACP,YAAa,6CACb,UAAW,UACX,YAAa,yBACb,UAAW,UACb,CACF,EAEaC,GAA4C,CACvD,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,aACR,EC7FA,IAAAC,GAA0C,iBAS7BC,MAAe,kBAAwC,IAAI,EAE3DC,GAAkB,OAAM,eAAWD,EAAY,ECiBxD,IAAAE,GAAA,6BAtBW,SAARC,GAAuB,CAC5B,KAAAC,EACA,OAAAC,EACA,UAAAC,EAAY,GACZ,SAAAC,EACA,IAAAC,EACA,GAAGC,CACL,EAAe,CACb,IAAMC,EAAeC,GAAgB,EAC/BC,EAAcC,EAAcT,GAAQM,GAAc,KAAMI,GAAY,IAAI,EACxEC,EAAeF,EAAcR,EAAQW,GAAc,IAAI,EAEvDC,EAAmB,CACvB,0IACAL,EAAY,OACZG,EACAT,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,SACE,QAAC,OACC,IAAKE,EACL,SAAU,GACV,UAAWS,EACV,GAAGR,EAEH,SAAAF,EACH,CAEJ,CCrCA,IAAAW,GAAkF,iBA6H5E,IAAAC,GAAA,6BAxHS,SAARC,GAAgC,CACrC,KAAAC,EAAO,GACP,GAAAC,EACA,KAAAC,EACA,UAAAC,EAAY,GACZ,oBAAAC,EAAsB,GACtB,WAAAC,EAAa,GACb,WAAAC,EAAa,GACb,iBAAAC,EAAmB,GACnB,UAAAC,EAAY,GACZ,SAAAC,EACA,QAAAC,EACA,GAAGC,CACL,EAAwB,CACtB,IAAMC,KAAY,WAA0B,IAAI,EAC1C,CAACC,EAAWC,CAAY,KAAI,aAAS,EAAK,EAC1CC,KAAe,WAA6C,IAAI,EAEhEC,KAAqB,gBAAY,IAAM,CACvCH,GAAaV,IAEjBW,EAAa,EAAI,EACbC,EAAa,SACf,aAAaA,EAAa,OAAO,EAEnCA,EAAa,QAAU,WAAW,IAAM,CACtCD,EAAa,EAAK,EAClBJ,IAAU,CACZ,EAAGO,EAA6B,EAClC,EAAG,CAACJ,EAAWV,EAAWO,CAAO,CAAC,EAE5BQ,KAAe,YACnB,KAAO,CACL,QAASF,EACT,UAAAb,EACA,KAAAD,CACF,GACA,CAACc,EAAoBb,EAAWD,CAAI,CACtC,KAGA,cAAU,IACD,IAAM,CACPa,EAAa,SACf,aAAaA,EAAa,OAAO,CAErC,EACC,CAAC,CAAC,KAGL,cAAU,IAAM,CACd,IAAMI,EAASP,EAAU,QACzB,GAAKO,EAEL,GAAInB,GAAQa,GACV,GAAI,CAACM,EAAO,KACV,GAAI,CACFA,EAAO,UAAU,CACnB,MAAQ,CAER,OAGEA,EAAO,MACTA,EAAO,MAAM,CAGnB,EAAG,CAACnB,EAAMa,CAAS,CAAC,KAGpB,cAAU,IAAM,CACd,GAAI,CAACP,EAAY,OAEjB,IAAMc,EAAmB,SAAS,KAAK,MAAM,SAC7C,gBAAS,KAAK,MAAM,SAAW,SAExB,IAAM,CACX,SAAS,KAAK,MAAM,SAAWA,CACjC,CACF,EAAG,CAACd,CAAU,CAAC,EAQf,IAAMe,KAAgB,mBAAgBC,GAAqB,CACrD,CAACtB,GAAQK,IAAe,IAExBiB,EAAE,MAAQ,WACZA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBN,EAAmB,EAEvB,CAAC,EASD,MAPA,cAAU,KACR,OAAO,iBAAiB,UAAWK,CAAa,EACzC,IAAM,CACX,OAAO,oBAAoB,UAAWA,CAAa,CACrD,GACC,CAAC,CAAC,EAED,CAACrB,GAAQ,CAACa,EACZ,OAAO,KAGT,IAAMU,EAAqB,IAAM,CAC3BnB,GACFY,EAAmB,CAEvB,EAEMQ,EAAoBX,EAAY,iDAAmD,4BAEnFY,EAAkBZ,EAAY,wCAA0C,mBAE9E,SACE,QAACa,GAAa,SAAb,CAAsB,MAAOR,EAC5B,qBAAC,UACC,GAAIjB,EACJ,IAAKW,EACL,kBAAgB,qBAChB,mBAAiB,2BACjB,SAAWU,GAAM,CACfA,EAAE,eAAe,EACbjB,IAAe,IACjBW,EAAmB,CAEvB,EACA,UAAW,0LAA0LQ,CAAiB,IAAIjB,CAAgB,GACzO,GAAGI,EAEJ,qBAAC,OACC,cAAY,OACZ,QAASY,EACT,UAAU,sBACZ,KACA,QAAC,OAAI,UAAW,+DAA+DE,CAAe,IAAIjB,CAAS,GACxG,SAAAC,EACH,GACF,EACF,CAEJ,CClHM,IAAAkB,GAAA,6BA7BS,SAARC,GAA6B,CAClC,KAAAC,EACA,MAAAC,EACA,YAAAC,EACA,eAAAC,EAAiB,GACjB,qBAAAC,EAAuB,GACvB,gBAAAC,EAAkB,GAClB,QAAAC,EACA,qBAAAC,EAAuB,GACvB,UAAAC,EAAY,GACZ,SAAAC,EACA,GAAGC,CACL,EAAqB,CACnB,IAAMC,EAAeC,GAAgB,EAC/BC,EAAcC,EAAcd,GAAQW,GAAc,KAAMI,GAAY,IAAI,EACxEC,EAAYL,GAAc,UAE1BM,EAAc,IAAM,CACxBX,IAAU,EACVK,GAAc,UAAU,CAC1B,EAEMO,EAAkB,GAAQZ,GAAWK,GAAc,SAEzD,SACE,SAAC,OACC,UAAW,4EAA4EE,EAAY,MAAM,IAAIL,CAAS,GACrH,GAAGE,EAEJ,sBAAC,OAAI,UAAU,8CACZ,UAAAT,MACC,QAAC,MACC,GAAG,qBACH,UAAW,GAAGY,EAAY,KAAK,aAAaV,CAAc,GAEzD,SAAAF,EACH,EAEDC,MACC,QAAC,KACC,GAAG,2BACH,UAAW,GAAGW,EAAY,WAAW,WAAWT,CAAoB,GAEnE,SAAAF,EACH,EAEDO,GACH,EAECJ,GAAmBa,MAClB,QAAC,UACC,KAAK,SACL,QAASD,EACT,SAAUD,EACV,aAAW,mCACX,cAAY,qBACZ,UAAW,8NAA8NH,EAAY,WAAW,IAAIN,CAAoB,GAExR,oBAACY,GAAA,CAAU,UAAWN,EAAY,UAAW,EAC/C,GAEJ,CAEJ,CC3DI,IAAAO,GAAA,6BALW,SAARC,GAA2B,CAAE,KAAAC,EAAM,UAAAC,EAAY,GAAI,SAAAC,EAAU,GAAGC,CAAM,EAAmB,CAC9F,IAAMC,EAAeC,GAAgB,EAC/BC,EAAcC,EAAcP,GAAQI,GAAc,KAAMI,GAAY,IAAI,EAE9E,SACE,QAAC,OACC,UAAW,gEAAgEF,EAAY,IAAI,IAAIL,CAAS,GACvG,GAAGE,EAEH,SAAAD,EACH,CAEJ,CN2BM,IAAAO,GAAA,6BA/BS,SAARC,GAA+B,CACpC,KAAAC,EAAO,GACP,QAAAC,EACA,KAAAC,EACA,MAAAC,EACA,YAAAC,EACA,KAAAC,EACA,OAAAC,EAAS,KACT,gBAAAC,EAAkB,GAClB,oBAAAC,EAAsB,GACtB,WAAAC,EAAa,GACb,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,iBAAAC,EAAmB,GACnB,SAAAC,CACF,EAAuB,CACrB,IAAMC,EAAaC,GAAqBb,CAAI,EACtCc,EAAcb,GAASW,GAAY,KAEnCG,KAAe,YAAQ,KAAO,CAAE,KAAAf,EAAM,YAAAc,CAAY,GAAI,CAACd,EAAMc,CAAW,CAAC,EAE/E,SACE,QAACE,GAAA,CACC,KAAMlB,EACN,QAASC,EACT,KAAMI,EACN,oBAAqBG,EACrB,WAAYC,EACZ,WAAYC,EACZ,iBAAkBE,EAElB,qBAACO,GAAA,CACC,OAAQb,EACR,UAAW,8FAA8FK,CAAS,GAEhH,WAAAK,GAAeT,OACf,QAACa,GAAA,CACC,MAAOJ,EACP,YAAaZ,EACb,gBAAiBG,EACjB,UAAU,0CACZ,KAEF,QAACc,GAAA,CACC,oBAACC,GAAY,SAAZ,CAAqB,MAAOL,EAC1B,SAAAJ,MAAsB,QAACU,GAAA,EAAY,EACtC,EACF,GACF,EACF,CAEJ,COwBQ,IAAAC,GAAA,6BA3DO,SAARC,GAAqC,CAC1C,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,QAAAC,EAAU,UACV,OAAAC,EACA,MAAAC,EAAQ,YACR,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,WAAAC,EACA,UAAAC,EACA,cAAAC,EACA,oBAAAC,EACA,KAAAC,EACA,gBAAAC,EACA,UAAAC,EAAY,GACZ,cAAAC,CACF,EAA6B,CAC3B,IAAMC,EAAcC,GAAsBjB,CAAI,EACxCkB,EAAkBf,EACpBgB,GAAwBhB,CAAM,EAC9BgB,GAAwBC,GAA+BpB,CAAI,CAAC,EAE1DqB,EAAiBZ,EAAY,QAAUR,EACvCqB,EAAcpB,IAAY,QAAUqB,GAA8BrB,CAAO,EAAEmB,CAAc,EAAI,KAKnG,SACE,QAAC,OACC,KAAK,SACL,SAAUhB,EAAW,GAAK,EAC1B,aAAW,8DACX,gBAAeA,EACf,eAAcI,EACd,mBAAkBM,EAClB,YAAWR,EACX,QAAS,IAAM,CACT,CAACF,GAAY,CAACC,GAAY,CAACC,GAC7BM,EAAgB,CAEpB,EACA,UAAYW,GAAM,CACZnB,GAAYC,GAAYC,IACxBiB,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OACjCA,EAAE,eAAe,EACjBX,EAAgB,EAEpB,EACA,UAAW,yBAAyBG,EAAY,cAAc,IAAIA,EAAY,eAAe,IAAIE,CAAe,wIAC9GV,EACIc,GAAa,QAAU,8DACvBA,GAAa,MAAQ,qFAC3B,IACEjB,EAAW,mEAAqE,EAClF,qFAAqFS,CAAS,GAE7F,SAAAP,KACC,SAAC,OACC,UAAW,mDAAmDe,GAAa,WAAa,kBAAkB,GAE1G,qBAACG,GAAA,CAAQ,MAAOT,EAAY,SAAW,GAAK,OAAQA,EAAY,SAAW,GAAK,KAChF,QAAC,QAAK,UAAW,GAAGA,EAAY,SAAS,eAAgB,uDAAsB,GACjF,KAEA,SAAC,OAAI,UAAU,kDAEb,qBAAC,OAAI,UAAW,qBAAqBM,GAAa,WAAa,kBAAkB,GAC9E,SAAAV,MAAQ,QAACc,GAAA,CAAW,MAAOV,EAAY,SAAU,OAAQA,EAAY,SAAU,EAClF,KAGA,QAAC,OACC,UAAW,GAAGA,EAAY,SAAS,iCACjCM,GAAa,YAAc,8BAC7B,qBAEC,SAAAZ,GApDU,wGAqDb,KAGA,QAAC,OAAI,GAAIK,EAAe,UAAW,GAAGC,EAAY,QAAQ,oBACvD,SAAAL,GAxDS,gEAyDZ,GACF,EAEJ,CAEJ,CCvHA,IAAAgB,GAAyB,iBACzBC,GAAkC,4BCK3B,IAAMC,GAAiD,CAC5D,MAAO,gBACP,KAAM,gBACN,KAAM,EACR,EAMaC,GAA+C,CAC1D,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,cACR,ECsBY,IAAAC,GAAA,6BAzCG,SAARC,GAA0B,CAC/B,QAAAC,EAAU,QACV,MAAAC,EAAQ,YACR,OAAAC,EAAS,KACT,MAAAC,EACA,OAAAC,EAAS,OACT,MAAAC,EAAQ,EACR,IAAAC,EAAM,SACN,UAAAC,EAAY,GACZ,MAAAC,EACA,GAAGC,CACL,EAAkB,CAChB,IAAMC,EAAiBC,GAAcX,CAAO,GAAK,GAG3CY,EAAeX,IAAU,SAAW,eAAkBY,GAAaX,CAAM,GAAKW,GAAa,GAE3FC,EAAWC,GACWA,EAEtBC,EAA2B,CAC/B,MAAOF,EAAQX,CAAK,EACpB,OAAQW,EAAQV,CAAM,EACtB,GAAGI,CACL,EAEMS,EAAY,CAAC,iBAAkBP,EAAgBE,CAAY,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAG3F,OAAIP,EAAQ,KAER,QAAC,OACC,KAAK,SACL,aAAW,aACX,UAAW,CAAC,gBAAiBE,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAChE,MAAO,CAAE,IAAKO,EAAQR,CAAG,EAAG,GAAGE,CAAM,EACpC,GAAGC,EAEH,eAAM,KAAK,CAAE,OAAQJ,CAAM,CAAC,EAAE,IAAI,CAACa,EAAGC,IAAM,CAC3C,IAAMC,EAASD,IAAMd,EAAQ,EAC7B,SACE,QAAC,OAEC,UAAWY,EACX,MAAO,CACL,MAAOG,EAAS,MAASN,EAAQX,CAAK,GAAK,OAC3C,OAAQW,EAAQV,CAAM,CACxB,GALKe,CAMP,CAEJ,CAAC,EACH,KAMF,QAAC,OACC,KAAK,SACL,aAAW,aACX,UAAW,CAACF,EAAWV,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAC1D,MAAOS,EACN,GAAGP,EACN,CAEJ,CFxBI,IAAAY,GAAA,6BAtCW,SAARC,GAA8B,CACnC,IAAAC,EACA,IAAAC,EAAM,GACN,MAAAC,EACA,OAAAC,EACA,KAAAC,EACA,gBAAAC,EAAkB,QAClB,OAAAC,EAAS,KACT,UAAAC,EAAY,GACZ,iBAAAC,EAAmB,GACnB,MAAAC,EACA,aAAAC,EACA,OAAAC,EACA,QAAAC,EACA,GAAGC,CACL,EAAsB,CACpB,GAAM,CAACC,EAAUC,CAAW,KAAI,aAAS,EAAK,EACxC,CAACC,EAAUC,CAAW,KAAI,aAAS,EAAK,EAExCC,EAAeC,GAAab,CAAM,GAAKa,GAAa,GAEpDC,EAAoCC,GAAM,CAC9CN,EAAY,EAAI,EAChBJ,IAASU,CAAC,CACZ,EAEMC,EAAsCD,GAAM,CAChDJ,EAAY,EAAI,EAChBF,EAAY,EAAK,EACjBH,IAAUS,CAAC,CACb,EAEME,EAA4C,CAChD,GAAInB,EAAO,CAAC,EAAI,CAAE,MAAAF,EAAO,OAAAC,CAAO,EAChC,GAAGO,CACL,EAEA,SACE,SAAC,OACC,cAAY,wBACZ,UAAW,CAAC,wCAAyCQ,EAAcV,CAAgB,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAC7G,MAAOe,EAGN,WAACT,GAAY,CAACE,MACb,QAACQ,GAAA,CACC,cAAY,yBACZ,QAASnB,EACT,OAAQC,EACR,MAAM,OACN,OAAO,OACP,MAAO,CAAE,SAAU,WAAY,MAAO,CAAE,EAC1C,EAIDN,MACC,QAAC,GAAAyB,QAAA,CACC,cAAY,oBACZ,IAAKzB,EACL,IAAKC,EACL,MAAQG,EAAe,OAARF,EACf,OAASE,EAAgB,OAATD,EAChB,KAAMC,EACN,UAAW,CACT,mEACAc,EACAJ,EAAW,cAAgB,YAC3BP,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EACX,MAAOE,EACP,OAAQW,EACR,QAASE,EACR,GAAGT,EACN,EAIDG,MACC,QAAC,OACC,cAAY,sBACZ,KAAK,MACL,aAAW,uBACX,UAAW,CAAC,oDAAqD,iCAAiC,EAAE,KAAK,GAAG,EAE5G,oBAACU,GAAA,CAAU,MAAO,GAAI,OAAQ,GAAI,cAAY,OAAO,EACvD,GAEJ,CAEJ,CG/CY,IAAAC,GAAA,6BA1BG,SAARC,GAAiC,CACtC,MAAAC,EACA,KAAAC,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,gBAAAC,EACA,WAAAC,EACA,cAAAC,EAAgB,GAChB,UAAAC,EAAY,EACd,EAAyB,CACvB,IAAMC,EAAcC,GAAsBZ,CAAI,EACxCa,EAAeC,GAAwBb,CAAM,EAC7Cc,EAAa,CAACX,GAAYL,EAAM,OAASK,EAE/C,SACE,SAAC,MACC,aAAW,2DACX,UAAW,iDAAiDO,EAAY,GAAG,IAAID,CAAS,GAEvF,UAAAX,EAAM,IAAI,CAACiB,EAAMC,IAAU,CAC1B,GAAIT,EACF,SACE,QAAC,MAAiB,UAAU,YACzB,SAAAA,EAAWQ,EAAMC,EAAO,CACvB,OAAQ,IAAMZ,EAASW,EAAMC,CAAK,EAClC,QAAS,IAAMX,EAAUU,CAAI,CAC/B,CAAC,GAJMA,EAAK,EAKd,EAIJ,IAAME,EAAcF,EAAK,SAAW,YAC9BG,EAAUH,EAAK,SAAW,QAEhC,SACE,SAAC,MAEC,SAAUd,EAAW,GAAK,EAC1B,aAAY,oBAAYc,EAAK,IAAI,GACjC,UAAYI,GAAM,CACZlB,GAAYC,IACZiB,EAAE,MAAQ,UAAYA,EAAE,MAAQ,eAClCA,EAAE,eAAe,EACjBf,EAASW,EAAMC,CAAK,EAExB,EACA,UAAW,4BAA4BN,EAAY,aAAa,IAAIE,CAAY,6EAC9EM,EAAU,mBAAqB,oBACjC,4HAEC,UAAAH,EAAK,OACJ,QAACK,GAAA,CACC,IAAKL,EAAK,IACV,IAAKA,EAAK,KACV,MAAO,GACP,OAAQ,GACR,OAAQf,EACR,YAAW,GACX,UAAU,6BACV,iBAAiB,gBACnB,KAEA,QAAC,OAAI,UAAU,oDAAqD,SAAAe,EAAK,KAAK,EAI/EE,MACC,SAAC,OAAI,UAAU,kGACb,qBAACI,GAAA,CAAQ,MAAO,GAAI,OAAQ,GAAI,EAC/B,OAAON,EAAK,UAAa,aACxB,SAAC,QAAK,UAAU,2BAA4B,eAAK,MAAMA,EAAK,QAAQ,EAAE,KAAC,GAE3E,EAID,CAACE,GAAe,CAAChB,MAChB,SAAC,OAAI,UAAU,mLACZ,UAAAI,GAAaU,EAAK,QACjB,QAAC,UACC,KAAK,SACL,QAAUI,GAAM,CACdA,EAAE,gBAAgB,EAClBd,EAAUU,CAAI,CAChB,EACA,aAAY,wCAAsBA,EAAK,IAAI,GAC3C,UAAU,gLAEV,oBAACO,GAAA,CAAQ,MAAO,GAAI,OAAQ,GAAI,EAClC,EAGD,CAACpB,MACA,QAAC,UACC,KAAK,SACL,QAAUiB,GAAM,CACdA,EAAE,gBAAgB,EAClBf,EAASW,EAAMC,CAAK,CACtB,EACA,aAAY,2BAAgBD,EAAK,IAAI,GACrC,UAAU,+LAEV,oBAACQ,GAAA,CAAU,MAAO,GAAI,OAAQ,GAAI,EACpC,GAEJ,IArEGR,EAAK,EAuEZ,CAEJ,CAAC,EAGAP,GAAiBM,GAAc,CAACZ,MAC/B,QAAC,MAAG,UAAU,YACZ,oBAAC,UACC,KAAK,SACL,SAAUD,EACV,QAASK,EACT,aAAW,2BACX,UAAW,GAAGI,EAAY,aAAa,IAAIE,CAAY,uWAEvD,oBAACY,GAAA,CAAS,MAAOd,EAAY,SAAW,GAAK,OAAQA,EAAY,SAAW,GAAK,EACnF,EACF,GAEJ,CAEJ,CpBmFM,IAAAe,GAAA,6BAtON,SAASC,GAAe,EAA8B,CACpD,EAAE,eAAe,EACjB,EAAE,gBAAgB,CACpB,CAEe,SAARC,GAA6B,CAClC,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EACA,QAAAC,EACA,OAAAC,EAAS,UACT,aAAAC,EACA,SAAAC,EAAW,WACX,MAAAC,EAAQ,YACR,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,QAAAC,EAAU,UACV,OAAAC,EACA,MAAAC,EACA,WAAAC,EACA,aAAAC,EACA,UAAWC,EACX,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,UAAAC,EAAY,GACZ,cAAAC,EACA,oBAAAC,EACA,KAAAC,EACA,WAAAC,EAAa,2BACb,WAAAC,EACA,UAAAC,EAAY,GACZ,kBAAAC,EAAoB,GACpB,iBAAAC,EAAmB,GACnB,UAAAC,CACF,EAAqB,CACnB,IAAMC,KAAc,UAAM,EACpBC,EAAU,GAAGD,CAAW,SACxBE,EAAW,GAAGF,CAAW,UACzBG,EAAU,GAAGH,CAAW,SAExBI,KAAe,WAAyB,IAAI,EAG5C,CAACC,EAAeC,CAAgB,KAAI,aAA2B,IACnEC,GAAuBvC,IAAU,OAAYA,EAAQC,CAAY,CACnE,KAEA,cAAU,IAAM,CACVD,IAAU,QACZsC,EAAiBC,GAAuBvC,CAAK,CAAC,CAElD,EAAG,CAACA,CAAK,CAAC,EAGV,GAAM,CAACwC,EAAYC,CAAa,KAAI,aAAS,EAAK,EAC5CC,KAAc,WAAO,CAAC,EAGtB,CAACC,GAAiBC,CAAkB,KAAI,aAAwB,IAAI,EACpE,CAACC,GAAaC,EAAc,KAAI,aAAgC,IAAI,EAGpE,CAACC,GAAgBC,CAAiB,KAAI,aAAiB,EAAE,EAEzDC,EAAcC,GAAsBtC,CAAI,EACxCuC,GAAY,GAAQhC,GAAiBD,GAAgByB,IACrDS,EAAqBlC,GAAgByB,GAErCU,EAAoB/C,IAAaD,EAAW,OAAY,GAExDiD,EAAeC,GAA+B,CAC9CvD,IAAU,QACZsC,EAAiBiB,CAAQ,EAE3BrD,IAAWqD,CAAQ,CACrB,EAEMC,GAAsB,IAAM,CAC5BpC,GAAYC,GACZe,EAAa,UACfA,EAAa,QAAQ,MAAQ,GAC7BA,EAAa,QAAQ,MAAM,EAE/B,EAEMqB,GAAe,MAAOC,GAA6B,CACvD,GAAItC,GAAYC,EAAU,OAC1BuB,EAAmB,IAAI,EAEvB,IAAMe,GAAY,MAAM,KAAKD,CAAK,EAClC,GAAIC,GAAU,SAAW,EAAG,OAG5B,IAAMC,EAAevB,EAAc,OAC/BwB,GAAeF,GAEnB,GAAIN,IAAsB,OACxB,GAAKhD,EAKE,CACL,IAAMyD,GAAiBT,EAAoBO,EAC3C,GAAIE,IAAkB,EAAG,CACvB,IAAMC,GAAM,wCAAwCV,CAAiB,WACrET,EAAmBmB,EAAG,EACtBf,EAAkBe,EAAG,EACrB,MACF,CACAF,GAAeF,GAAU,MAAM,EAAGG,EAAc,CAClD,KAde,CAEb,IAAME,GAAYL,GAAU,CAAC,EAC7B,GAAI,CAACK,GAAW,OAChBH,GAAe,CAACG,EAAS,CAC3B,CAYF,IAAMC,GAAoB,MAAOC,IAA+C,CAE9E,IAAMC,GAAaC,GAAaF,GAAM,CAAE,QAAA3D,EAAS,OAAAC,CAAO,CAAC,EACzD,GAAI,CAAC2D,GAAW,QAAS,CACvB,IAAMJ,GAAMI,GAAW,OAAS,eAChC,OAAAvB,EAAmBmB,EAAG,EACtBf,EAAkB,sBAAsBe,EAAG,EAAE,EACtC,IACT,CAGA,GAAItD,EACF,GAAI,CACF,IAAM4D,GAAS,MAAM5D,EAAayD,EAAI,EACtC,GAAIG,KAAW,IAAS,OAAOA,IAAW,SAAU,CAClD,IAAMN,GAAM,OAAOM,IAAW,SAAWA,GAAS,QAAQH,GAAK,IAAI,gBACnE,OAAAtB,EAAmBmB,EAAG,EACtBf,EAAkB,aAAQe,EAAG,EAAE,EACxB,IACT,CACF,OAASA,GAAU,CACjB,IAAMO,GAASP,IAAK,SAAW,4CAAuBG,GAAK,IAAI,GAC/D,OAAAtB,EAAmB0B,EAAM,EACzBtB,EAAkB,aAAQsB,EAAM,EAAE,EAC3B,IACT,CAGF,OAAOC,GAAeL,EAAI,CAC5B,EAEMM,GAAkC,CAAC,EAEzC,QAAWN,MAAQL,GAAc,CAC/B,IAAMY,GAAO,MAAMR,GAAkBC,EAAI,EACrCO,IACFD,GAAc,KAAKC,EAAI,CAE3B,CAEA,GAAID,GAAc,OAAS,EAAG,CAC5B,IAAME,GAAcrE,EAA2B,CAAC,GAAGgC,EAAe,GAAGmC,EAAa,EAAnDA,GAE/BlB,EAAYoB,EAAU,EACtB1B,EAAkB,oCAAsBwB,GAAc,MAAM,2CAAyBE,GAAW,MAAM,GAAG,CAC3G,CACF,EAEMC,GAAyBC,GAAqC,CAC9DA,EAAE,OAAO,OACXnB,GAAamB,EAAE,OAAO,KAAK,CAE/B,EAEMC,GAAmBD,GAAiC,CACxDA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EACd,EAAAxD,GAAYC,KAChBqB,EAAY,SAAW,EACnBkC,EAAE,aAAa,OAASA,EAAE,aAAa,MAAM,OAAS,GACxDnC,EAAc,EAAI,EAEtB,EAEMqC,GAAmBF,GAAiC,CACxDA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EACd,EAAAxD,GAAYC,KAChBqB,EAAY,SAAW,EACnBA,EAAY,SAAW,IACzBD,EAAc,EAAK,EACnBC,EAAY,QAAU,GAE1B,EAEMqC,GAAcH,GAAiC,CACnDA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBnC,EAAc,EAAK,EACnBC,EAAY,QAAU,EAElB,EAAAtB,GAAYC,IACZuD,EAAE,aAAa,OAASA,EAAE,aAAa,MAAM,OAAS,IACxDnB,GAAamB,EAAE,aAAa,KAAK,EACjCA,EAAE,aAAa,UAAU,EAE7B,EAEMI,EAAe,CAACP,EAAsBQ,KAAkB,CAC5D,GAAI7D,GAAYC,EAAU,OAC1B,IAAMkC,EAAWlB,EAAc,OAAO,CAAC6C,GAAGC,KAAMA,KAAMF,EAAK,EAC3D3B,EAAYC,CAAQ,EACpBpD,IAAWsE,EAAMQ,EAAK,EACtBjC,EAAkB,sCAAmByB,EAAK,IAAI,EAAE,CAClD,EAEMW,EAAqBX,GAAyB,EAC9CA,EAAK,KAAOA,EAAK,OACnB3B,GAAe2B,CAAI,EAErBrE,IAAYqE,CAAI,CAClB,EAEA,SACE,SAAC,OACC,UAAW,iCAAiC7C,CAAS,GACrD,YAAaiD,GACb,YAAaC,GACb,WAAYhF,GACZ,OAAQiF,GAGR,qBAAC,SACC,IAAK3C,EACL,GAAIH,EACJ,KAAK,OACL,SAAU5B,EACV,OAAQG,EACR,SAAUY,EACV,cAAY,OACZ,SAAU,GACV,UAAU,SACV,SAAUuD,GACZ,KAGA,QAAC,OAAI,YAAU,SAAS,cAAY,OAAO,UAAU,UAClD,SAAA5B,GACH,EAGC/B,MACC,QAAC,SAAM,QAASiB,EAAS,UAAW,sCAAsCgB,EAAY,SAAS,GAC5F,SAAAjC,EACH,KAIF,SAAC,OAAI,UAAU,sBACZ,UAAAN,IAAa,eACZ,sBACE,qBAAC2E,GAAA,CACC,KAAMzE,EACN,MAAOC,EACP,QAASC,EACT,OAAQC,EACR,MAAOJ,EACP,SAAUS,EACV,SAAUC,EACV,UAAWC,EACX,WAAYkB,EACZ,UAAWW,GACX,cAAe5B,EACf,oBAAqBC,EACrB,KAAMC,EACN,gBAAiB+B,GACjB,UAAW3B,EACX,cAAeZ,EAAaiB,EAAW,OACzC,EAGCG,EAAc,OAAS,MACtB,QAACiD,GAAA,CACC,MAAOjD,EACP,KAAMzB,EACN,MAAOC,EACP,QAASC,EACT,OAAQC,GAAU,KAClB,SAAUK,EACV,SAAUC,EACV,SAAUgC,EACV,SAAU2B,EACV,UAAWI,EACX,gBAAiB5B,GACjB,WAAY7B,EACZ,cAAe,GACf,UAAWG,EACb,GAEJ,EAGDpB,IAAa,gBACZ,QAAC4E,GAAA,CACC,MAAOjD,EACP,KAAMzB,EACN,MAAOC,EACP,QAASC,EACT,OAAQC,GAAU,KAClB,SAAUK,EACV,SAAUC,EACV,SAAUgC,EACV,SAAU2B,EACV,UAAWI,EACX,gBAAiB5B,GACjB,WAAY7B,EACZ,cAAe,GACf,UAAWG,EACb,EAGDpB,IAAa,aACZ,SAAC,OAAI,UAAU,sBACb,qBAAC,OAAI,UAAU,0BACb,oBAAC6E,GAAA,CACC,KAAK,SACL,KAAM3E,EACN,MAAOuC,GAAY,QAAUtC,IAAU,UAAY,YAAcA,EACjE,QAASC,IAAY,QAAU,SAAWA,EAC1C,OAAQC,EACR,SACEK,GAAYC,GAAagC,IAAsB,QAAahB,EAAc,QAAUgB,EAEtF,QAASG,GACT,YAAU,QAACgC,GAAA,CAAW,MAAOvC,EAAY,SAAW,GAAK,OAAQA,EAAY,SAAW,GAAK,EAC7F,aAAYlB,GAAa,2BAExB,SAAAL,EACH,EACF,EAECW,EAAc,OAAS,MACtB,QAACiD,GAAA,CACC,MAAOjD,EACP,KAAMzB,EACN,MAAOC,EACP,QAASC,EACT,OAAQC,GAAU,KAClB,SAAUK,EACV,SAAUC,EACV,SAAUgC,EACV,SAAU2B,EACV,UAAWI,EACX,gBAAiB5B,GACjB,WAAY7B,EACZ,cAAe,GACf,UAAWG,EACb,GAEJ,GAEJ,EAGCqB,IAAaC,KACZ,QAAC,KAAE,GAAIjB,EAAS,KAAK,QAAQ,UAAW,8BAA8Bc,EAAY,UAAU,GACzF,SAAAG,EACH,EACEnC,KACF,QAAC,KAAE,GAAIiB,EAAU,UAAW,oBAAoBe,EAAY,UAAU,GACnE,SAAAhC,EACH,EACE,KAGH4B,OACC,QAAC4C,GAAA,CACC,KAAM,EAAQ5C,GACd,QAAS,IAAMC,GAAe,IAAI,EAClC,KAAMD,GAAY,OAASA,GAAY,IAAM,CAAE,IAAKA,GAAY,IAAK,KAAMA,GAAY,IAAK,EAAI,QAClG,GAEJ,CAEJ,CqBxYA,IAAA6C,GAUO,iBCRA,IAAMC,GAA+D,CAC1E,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,cACR,EAEaC,GAUT,CACF,GAAI,CACF,WAAY,UACZ,SAAU,GACV,UAAW,SACX,MAAO,mBACP,OAAQ,oBACR,QAAS,SACX,EACA,GAAI,CACF,WAAY,UACZ,SAAU,GACV,UAAW,SACX,MAAO,eACP,OAAQ,qBACR,QAAS,YACX,EACA,GAAI,CACF,WAAY,UACZ,SAAU,GACV,UAAW,SACX,MAAO,iBACP,OAAQ,mBACR,QAAS,YACX,EACA,GAAI,CACF,WAAY,UACZ,SAAU,GACV,UAAW,UACX,MAAO,mBACP,OAAQ,eACR,QAAS,YACX,EACA,GAAI,CACF,WAAY,UACZ,SAAU,GACV,UAAW,UACX,MAAO,eACP,OAAQ,eACR,QAAS,aACX,CACF,EAEaC,GAGT,CACF,QAAS,CACP,QACE,oJACF,UACE,4JACF,QACE,oJACF,MACE,4IACF,QACE,oJACF,QACE,oJACF,KAAM,uIACR,EACA,OAAQ,CACN,QACE,kLACF,UACE,8LACF,QACE,kLACF,MACE,6LACF,QACE,kLACF,QACE,kLACF,KAAM,+JACR,EACA,MAAO,CACL,QACE,iLACF,UACE,yLACF,QACE,iLACF,MACE,oKACF,QACE,iLACF,QACE,iLACF,KAAM,oKACR,CACF,EC1GO,SAASC,GAAsBC,EAAyD,CAC7F,OAAKA,EACD,OAAOA,GAAU,SACZ,CACL,IAAKA,EACL,KAAMC,GAAYD,CAAK,GAAK,SAC5B,KAAME,GAAYF,CAAK,CACzB,EAEKA,EARY,IASrB,CAEO,SAASG,GACdC,EACAC,EAIsC,CACtC,GAAM,CAAE,QAAAC,EAAS,OAAAC,CAAO,EAAIF,GAAW,CAAC,EAExC,GAAIC,GAAWF,EAAK,KAAOE,EAEzB,MAAO,CACL,QAAS,GACT,MAAO,uFAHMA,EAAW,SAAc,QAAQ,CAAC,CAGU,KAC3D,EAGF,GAAIC,GAAUA,IAAW,IAAK,CAC5B,IAAMC,EAAgBD,EAAO,MAAM,GAAG,EAAE,IAAKE,GAAMA,EAAE,KAAK,EAAE,YAAY,CAAC,EACnEC,EAAWN,EAAK,KAAK,YAAY,EACjCO,EAAU,IAAIP,EAAK,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY,CAAC,GAa7D,GAAI,CAXYI,EAAc,KAAMI,GAAS,CAC3C,GAAIA,EAAK,WAAW,GAAG,EACrB,OAAOD,IAAYC,EAErB,GAAIA,EAAK,SAAS,IAAI,EAAG,CACvB,IAAMC,EAAWD,EAAK,QAAQ,KAAM,EAAE,EACtC,OAAOF,EAAS,WAAW,GAAGG,CAAQ,GAAG,CAC3C,CACA,OAAOH,IAAaE,CACtB,CAAC,EAGC,MAAO,CACL,QAAS,GACT,MAAO,iGAA8CL,CAAM,EAC7D,CAEJ,CAEA,MAAO,CAAE,QAAS,EAAK,CACzB,CC7DA,IAAAO,GAA8C,iBAC9CC,GAAqC,iCCM9B,SAASC,GAAYC,EAAwC,CAClE,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACtC,IAAMC,EAAQ,IAAI,MAClBA,EAAM,iBAAiB,OAAQ,IAAMF,EAAQE,CAAK,CAAC,EACnDA,EAAM,iBAAiB,QAAUC,GAAUF,EAAOE,CAAK,CAAC,EACxDD,EAAM,aAAa,cAAe,WAAW,EAC7CA,EAAM,IAAMH,CACd,CAAC,CACH,CAEO,SAASK,GAAeC,EAAqB,CAClD,OAAQA,EAAc,KAAK,GAAM,GACnC,CAEO,SAASC,GAAWC,EAAeC,EAAgBC,EAAkB,CAC1E,IAAMC,EAASN,GAAeK,CAAQ,EACtC,MAAO,CACL,MAAO,KAAK,IAAI,KAAK,IAAIC,CAAM,EAAIH,CAAK,EAAI,KAAK,IAAI,KAAK,IAAIG,CAAM,EAAIF,CAAM,EAC9E,OAAQ,KAAK,IAAI,KAAK,IAAIE,CAAM,EAAIH,CAAK,EAAI,KAAK,IAAI,KAAK,IAAIG,CAAM,EAAIF,CAAM,CACjF,CACF,CAEA,eAAsBG,GACpBC,EACAC,EACAJ,EAAW,EACXK,EAAY,GACZC,EAAW,qBACXC,EAAW,YACI,CACf,IAAMd,EAAQ,MAAMJ,GAAYc,CAAQ,EAClCK,EAAS,SAAS,cAAc,QAAQ,EACxCC,EAAMD,EAAO,WAAW,IAAI,EAElC,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,mCAAmC,EAGrD,IAAMR,EAASN,GAAeK,CAAQ,EAEhC,CAAE,MAAOU,EAAW,OAAQC,CAAW,EAAId,GAAWJ,EAAM,MAAOA,EAAM,OAAQO,CAAQ,EAE/FQ,EAAO,MAAQE,EACfF,EAAO,OAASG,EAEhBF,EAAI,UAAUC,EAAY,EAAGC,EAAa,CAAC,EAC3CF,EAAI,OAAOR,CAAM,EACjBQ,EAAI,MAAMJ,EAAY,GAAK,EAAG,CAAC,EAC/BI,EAAI,UAAU,CAAChB,EAAM,MAAQ,EAAG,CAACA,EAAM,OAAS,CAAC,EAEjDgB,EAAI,UAAUhB,EAAO,EAAG,CAAC,EAEzB,IAAMmB,EAAgB,SAAS,cAAc,QAAQ,EAC/CC,EAAaD,EAAc,WAAW,IAAI,EAEhD,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,kCAAkC,EAGpD,OAAAD,EAAc,MAAQR,EAAU,MAChCQ,EAAc,OAASR,EAAU,OAEjCS,EAAW,UACTL,EACAJ,EAAU,EACVA,EAAU,EACVA,EAAU,MACVA,EAAU,OACV,EACA,EACAA,EAAU,MACVA,EAAU,MACZ,EAEO,IAAI,QAAQ,CAACb,EAASC,IAAW,CACtCoB,EAAc,OACXE,GAAS,CACR,GAAI,CAACA,EAAM,CACTtB,EAAO,IAAI,MAAM,4CAA4C,CAAC,EAC9D,MACF,CACA,IAAMuB,EAAO,IAAI,KAAK,CAACD,CAAI,EAAGR,EAAU,CAAE,KAAMC,GAAY,WAAY,CAAC,EACzEhB,EAAQwB,CAAI,CACd,EACAR,GAAY,YACZ,GACF,CACF,CAAC,CACH,CCpFI,IAAAS,GAAA,6BALW,SAARC,GAA6B,CAAE,KAAAC,EAAM,UAAAC,EAAY,GAAI,SAAAC,EAAU,GAAGC,CAAM,EAAqB,CAClG,IAAMC,EAAeC,GAAgB,EAC/BC,EAAcC,EAAcP,GAAQI,GAAc,KAAMI,GAAY,IAAI,EAE9E,SACE,QAAC,OACC,UAAW,yEAAyEF,EAAY,MAAM,IAAIA,EAAY,SAAS,IAAIL,CAAS,GAC3I,GAAGE,EAEH,SAAAD,EACH,CAEJ,CClBA,IAAAO,GAAuE,iBAoCnE,IAAAC,GAAA,6BAhCW,SAARC,GAA4B,CACjC,SAAAC,EACA,QAAAC,EAAU,GACV,QAAAC,EACA,GAAGC,CACL,EAAoB,CAClB,IAAMC,EAAeC,GAAgB,EAC/BC,EAAYF,GAAc,UAE1BG,EAAeC,GAA+B,CAClDN,IAAUM,CAAC,EACNA,EAAE,kBACLJ,GAAc,UAAU,CAE5B,EAEA,GAAIH,MAAW,mBAAeD,CAAQ,EAAG,CACvC,IAAMS,EAAQT,EAId,SAAO,iBAAaS,EAAO,CACzB,SAAUA,EAAM,MAAM,UAAYH,EAClC,QAAUE,GAA+B,CACvCC,EAAM,MAAM,UAAUD,CAAC,EACvBD,EAAYC,CAAC,CACf,EACA,GAAGL,CACL,CAAC,CACH,CAEA,SACE,QAAC,UAAO,KAAK,SAAS,QAASI,EAAa,SAAUD,EAAY,GAAGH,EAClE,SAAAH,EACH,CAEJ,CH0EM,IAAAU,GAAA,6BAhFC,SAASC,GAAwB,CACtC,SAAUC,EACV,SAAUC,EAAkB,qBAC5B,SAAUC,EAAkB,YAC5B,YAAAC,EAAc,EACd,UAAAC,EAAY,QACZ,SAAAC,EAAW,GACX,QAAAC,EAAU,EACV,QAAAC,EAAU,EACV,QAAAC,EACA,SAAAC,CACF,EAAiC,CAC/B,IAAMC,KAAe,WAAyB,IAAI,EAC5C,CAACC,EAAUC,CAAW,KAAI,aAASZ,CAAe,EAClD,CAACa,EAAUC,CAAW,KAAI,aAASb,CAAe,EAClD,CAACc,EAAUC,CAAW,KAAI,aAASd,CAAe,EAElD,CAACe,EAAMC,CAAO,KAAI,aAAgB,CAAE,EAAG,EAAG,EAAG,CAAE,CAAC,EAChD,CAACC,EAAMC,CAAO,KAAI,aAAS,CAAC,EAC5B,CAACC,EAAUC,CAAW,KAAI,aAAS,CAAC,EACpC,CAACC,EAAWC,CAAY,KAAI,aAAS,EAAK,EAC1C,CAACC,EAAmBC,CAAoB,KAAI,aAAsB,IAAI,EACtE,CAACC,EAAcC,CAAe,KAAI,aAAS,EAAK,EAEhDC,EAAe,IAAMT,EAASU,GAAS,KAAK,IAAIvB,EAAS,KAAK,OAAOuB,EAAO,IAAO,EAAE,EAAI,EAAE,CAAC,EAC5FC,EAAgB,IAAMX,EAASU,GAAS,KAAK,IAAIxB,EAAS,KAAK,OAAOwB,EAAO,IAAO,EAAE,EAAI,EAAE,CAAC,EAC7FE,EAAiB,IAAMV,EAAaQ,IAAUA,EAAO,IAAM,GAAG,EAC9DG,EAAkB,IAAMX,EAAaQ,IAAUA,EAAO,GAAK,KAAO,GAAG,EACrEI,EAAuB,IAAMV,EAAcM,GAAS,CAACA,CAAI,EACzDK,EAAc,IAAM,CACxBjB,EAAQ,CAAE,EAAG,EAAG,EAAG,CAAE,CAAC,EACtBE,EAAQ,CAAC,EACTE,EAAY,CAAC,EACbE,EAAa,EAAK,CACpB,EAEMY,EAAyB,IAAM,CAC/B1B,EAAa,UACfA,EAAa,QAAQ,MAAQ,GAC7BA,EAAa,QAAQ,MAAM,EAE/B,EAEM2B,EAAyBC,GAAqC,CAClE,GAAIA,EAAE,OAAO,OAASA,EAAE,OAAO,MAAM,CAAC,EAAG,CACvC,IAAMC,GAAUD,EAAE,OAAO,MAAM,CAAC,EAC1BE,EAAS,IAAI,gBAAgBD,EAAO,EAC1C3B,EAAY4B,CAAM,EAClB1B,EAAYyB,GAAQ,IAAI,EACxBvB,EAAYuB,GAAQ,MAAQ,WAAW,EACvCJ,EAAY,CACd,CACF,EAEMM,EAAqB,CAACC,EAAoBjB,KAA4B,CAC1EC,EAAqBD,EAAiB,CACxC,EAEMkB,EAAa,SAAY,CAC7B,GAAKlB,EACL,GAAI,CACFG,EAAgB,EAAI,EACpB,IAAMgB,EAAc,MAAMC,GAAgBlC,EAAUc,EAAmBJ,EAAUE,EAAWV,EAAUE,CAAQ,EAC9GP,EAAQoC,CAAW,CACrB,OAASE,EAAK,CACZ,QAAQ,MAAM,yBAA0BA,CAAG,CAC7C,QAAE,CACAlB,EAAgB,EAAK,CACvB,CACF,EAEMmB,EAAc,IAAM,CACxBtC,IAAW,CACb,EAEMuC,EACJ,6PAEF,SACE,SAAC,OAAI,UAAU,mCAAmC,cAAY,2BAC5D,qBAAC,SACC,IAAKtC,EACL,KAAK,OACL,OAAO,UACP,cAAY,OACZ,SAAU,GACV,UAAU,SACV,SAAU2B,EACZ,KAEA,QAAC,OAAI,UAAU,0EACb,oBAAC,GAAAY,QAAA,CACC,MAAOtC,EACP,KAAMM,EACN,KAAME,EACN,SAAUE,EACV,OAAQlB,EACR,UAAWC,EACX,SAAUC,EACV,QAASC,EACT,QAASC,EACT,aAAcW,EACd,aAAcE,EACd,iBAAkBE,EAClB,eAAgBmB,EAChB,QAAS,CACP,eAAgBlB,EAAY,eAAiB,EAC/C,EACA,MAAO,CACL,eAAgB,CACd,SAAU,WACV,MAAO,OACP,OAAQ,MACV,CACF,EACF,EACF,KAEA,QAAC,OAAI,UAAU,gIACb,qBAAC,OAAI,UAAU,kJAEb,qBAAC,UACC,KAAK,SACL,QAASa,EACT,aAAW,6BACX,MAAM,6BACN,UAAW,GAAGY,CAAe,2CAC7B,cAAY,kCAEZ,oBAACE,GAAA,CAAW,MAAO,GAAI,OAAQ,GAAI,EACrC,KAEA,QAAC,OAAI,UAAU,oDAAoD,KAGnE,QAAC,UACC,KAAK,SACL,QAASnB,EACT,SAAUZ,GAAQb,EAClB,aAAW,eACX,MAAM,mBACN,UAAW0C,EAEX,oBAACG,GAAA,CAAY,MAAO,GAAI,OAAQ,GAAI,EACtC,KAGA,QAAC,UACC,KAAK,SACL,QAAStB,EACT,SAAUV,GAAQZ,EAClB,aAAW,cACX,MAAM,kBACN,UAAWyC,EAEX,oBAACI,GAAA,CAAW,MAAO,GAAI,OAAQ,GAAI,EACrC,KAGA,QAAC,UACC,KAAK,SACL,QAASnB,EACT,MAAM,6DACN,aAAW,6DACX,UAAWe,EAEX,oBAACK,GAAA,CAAc,MAAO,GAAI,OAAQ,GAAI,EACxC,KAGA,QAAC,UACC,KAAK,SACL,QAASrB,EACT,MAAM,kDACN,aAAW,kDACX,UAAWgB,EAEX,oBAACM,GAAA,CAAa,MAAO,GAAI,OAAQ,GAAI,EACvC,KAGA,QAAC,UACC,KAAK,SACL,QAASpB,EACT,MAAM,iBACN,aAAW,iBACX,UAAWc,EAEX,oBAACO,GAAA,CAAmB,MAAO,GAAI,OAAQ,GAAI,EAC7C,KAGA,QAAC,UACC,KAAK,SACL,QAASpB,EACT,MAAM,yBACN,aAAW,yBACX,UAAWa,EAEX,oBAACQ,GAAA,CAAU,MAAO,GAAI,OAAQ,GAAI,EACpC,KAEA,QAAC,OAAI,UAAU,oDAAoD,KAGnE,QAAC,UACC,KAAK,SACL,QAAST,EACT,aAAW,6BACX,MAAM,iBACN,UAAW,GAAGC,CAAe,yCAC7B,cAAY,4BAEZ,oBAACS,GAAA,CAAU,MAAO,GAAI,OAAQ,GAAI,EACpC,KAGA,QAAC,UACC,KAAK,SACL,QAASd,EACT,SAAUhB,EACV,aAAW,8DACX,MAAM,kBACN,UAAU,sQACV,cAAY,2BAEX,SAAAA,KAAe,QAAC+B,GAAA,CAAQ,MAAO,GAAI,OAAQ,GAAI,KAAK,QAACC,GAAA,CAAU,MAAO,GAAI,OAAQ,GAAI,EACzF,GACF,EACF,GACF,CAEJ,CAEO,SAASC,GAAsB,CACpC,KAAAC,EAAO,GACP,WAAAC,EAAa,4CACb,QAAAC,EACA,SAAAtD,EACA,QAAAD,EACA,GAAGwD,CACL,EAA+B,CAC7B,IAAMjB,EAAc,IAAM,CACxBtC,IAAW,EACXsD,IAAU,CACZ,EAOA,SACE,QAACE,GAAA,CACC,KAAMJ,EACN,oBAAqB,GACrB,WAAY,GACZ,QAASd,EAET,qBAACmB,GAAA,CACC,KAAK,KACL,OAAO,KACP,UAAU,4EAEV,qBAACC,GAAA,CACC,SACE,QAAC,QAAK,UAAU,iCAAiC,cAAY,0BAC1D,SAAAL,EACH,EAEF,UAAU,0CACV,gBAAe,GACjB,KACA,QAACM,GAAA,CAAU,UAAU,sBACnB,oBAACrE,GAAA,CAAyB,GAAGiE,EAAW,QA3B3BpB,GAAsB,CACzCpC,EAAQoC,CAAW,EACnBmB,IAAU,CACZ,EAwBsE,SAAUhB,EAAa,EACvF,GACF,EACF,CAEJ,CHxDM,IAAAsB,GAAA,6BAzOS,SAARC,GAA8B,CACnC,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,MAAAC,EAAQ,UACR,MAAAC,EAAQ,SACR,OAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,QAAAC,EACA,QAAAC,EACA,OAAAC,EAAS,UACT,KAAAC,EAAO,GACP,MAAAC,EACA,eAAAC,EAAiB,MACjB,WAAAC,EAAa,GACb,WAAAC,EACA,aAAAC,EACA,UAAAC,EAAY,GACZ,UAAAC,EAAY,GACZ,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,YAAAC,EAAc,GACd,KAAAC,EACA,KAAAC,EACA,GAAAC,EACA,YAAAC,EAAc,GACd,UAAAC,EAAY,GACZ,iBAAAC,EAAmB,GACnB,gBAAAC,EAAkB,GAClB,uBAAAC,EAAyB,GACzB,eAAAC,EAAiB,GACjB,gBAAAC,EAAkB,GAClB,UAAAC,EACA,IAAAC,CACF,EAAsB,CACpB,IAAMC,KAAc,UAAM,EACpBC,EAAUX,GAAMU,EAChBE,EAAW,GAAGD,CAAO,UAErBE,KAAmB,WAAyB,IAAI,EAGhDC,EAAenC,IAAU,OACzB,CAACoC,EAAcC,EAAe,KAAI,aAA6B,IACnEC,GAAsBrC,GAAgB,IAAI,CAC5C,EACMsC,EAAcJ,EAAeG,GAAsBtC,CAAK,EAAIoC,EAE5D,CAACI,GAAUC,EAAW,KAAI,aAItB,IAAI,EACR,CAACC,GAAeC,CAAgB,KAAI,aAAS,EAAK,EAElDC,KAAa,YAAQ,IACpBL,EACDA,aAAuB,KAClB,IAAI,gBAAgBA,CAAW,EAEjC,OAAOA,EAAY,KAAQ,SAAWA,EAAY,IAAM,GAJtC,GAKxB,CAACA,CAAW,CAAC,KAEhB,cAAU,IACD,IAAM,CACPK,GAAcA,EAAW,WAAW,OAAO,GAC7C,IAAI,gBAAgBA,CAAU,CAElC,EACC,CAACA,CAAU,CAAC,EAEf,IAAMC,GACJN,aAAuB,KACnBA,EAAY,KACZA,GAAa,OAAS,OAAOA,GAAa,KAAQ,SAAWO,GAAYP,EAAY,GAAG,EAAI,KAAO,GAEnG,CAACQ,EAAiBC,CAAkB,KAAI,aAAwB,IAAI,EACpE,CAACC,EAAYC,EAAa,KAAI,aAAS,EAAK,EAC5CC,MAAc,WAAO,CAAC,EACtB,CAACC,GAAgBC,EAAiB,KAAI,aAAiB,EAAE,EAGzDC,GAAczC,GAAgBkC,EAC9BQ,GAAW,GAAQzC,GAAawC,IAChCE,EAAcD,GAAW,QAAU1D,EAEnC4D,EAAcC,GAAuB/D,CAAI,GAAK+D,GAAuB,GACrEC,EAAe7D,IAAU,SAAW,eAAiBC,EAAS6D,GAAyB7D,CAAM,EAAI,aAEjG8D,GACJjE,IAAY,QACR,GACAkE,GAA+BlE,CAAO,IAAI4D,CAAW,GAAKM,GAA+B,QAAQ,QAEjGC,EAAchD,EAEdiD,GAAcC,IAAgC,CAC7C9B,GACHE,GAAgB4B,EAAO,EAEzB/D,IAAW+D,EAAO,CACpB,EAEMC,GAAsB,IAAM,CAChC,GAAIlD,GAAYC,GAAY8C,EAAa,OACzC,IAAMI,GACJ,OAAOrC,GAAQ,UAAYA,GAAO,YAAaA,GAAOA,EAAI,QAAUA,EAAI,QAAUI,EAAiB,QAEjGiC,KACFA,GAAU,MAAQ,GAClBA,GAAU,MAAM,EAEpB,EAEMC,GAAe5D,IAAS,GACxB6D,GAAc,OAAO7D,GAAS,SAAWA,EAAO,CAAC,EAEjD8D,GAAsB,CAACC,GAAkBC,KAAgB,CAC7D/B,GAAY,CACV,SAAA8B,GACA,SAAUC,IAAM,MAAQ3B,IAAY,aACpC,SAAU2B,IAAM,MAAQ,WAC1B,CAAC,CACH,EAEMC,GAAeD,IAAe,CAClC,GAAIxD,GAAYC,GAAY8C,EAAa,OACzCf,EAAmB,IAAI,EAEvB,IAAM0B,GAAaC,GAAaH,GAAM,CAAE,QAAAlE,EAAS,OAAAC,CAAO,CAAC,EACzD,GAAI,CAACmE,GAAW,QAAS,CACvB,IAAME,GAAMF,GAAW,OAAS,qCAChC1B,EAAmB4B,EAAG,EACtBvB,GAAkB,sBAAYuB,EAAG,EAAE,EACnC,MACF,CAEA,GAAIR,GAAc,CAChB,IAAMS,GAAU,IAAI,gBAAgBL,EAAI,EACxCF,GAAoBO,GAASL,EAAI,CACnC,MACER,GAAWQ,EAAI,EACfnB,GAAkB,6DAA8B,CAEpD,EAEMyB,GAAyBC,IAAqC,CAC9DA,GAAE,OAAO,OAASA,GAAE,OAAO,MAAM,CAAC,GACpCN,GAAYM,GAAE,OAAO,MAAM,CAAC,CAAC,CAEjC,EAEMC,GAAmBD,IAAiC,CACxDA,GAAE,eAAe,EACjBA,GAAE,gBAAgB,EACd,EAAA/D,GAAYC,GAAY8C,KAC5BZ,GAAY,SAAW,EACnB4B,GAAE,aAAa,OAASA,GAAE,aAAa,MAAM,OAAS,GACxD7B,GAAc,EAAI,EAEtB,EAEM+B,GAAmBF,IAAiC,CACxDA,GAAE,eAAe,EACjBA,GAAE,gBAAgB,EACd,EAAA/D,GAAYC,GAAY8C,KAC5BZ,GAAY,SAAW,EACnBA,GAAY,SAAW,IACzBD,GAAc,EAAK,EACnBC,GAAY,QAAU,GAE1B,EAEM+B,GAAcH,IAAiC,CACnDA,GAAE,eAAe,EACjBA,GAAE,gBAAgB,EAClB7B,GAAc,EAAK,EACnBC,GAAY,QAAU,EAElB,EAAAnC,GAAYC,GAAY8C,IACxBgB,GAAE,aAAa,OAASA,GAAE,aAAa,MAAM,CAAC,IAChDN,GAAYM,GAAE,aAAa,MAAM,CAAC,CAAC,EACnCA,GAAE,aAAa,UAAU,EAE7B,EAEMI,GAAgBJ,IAAmB,CAEvC,GADAA,IAAG,gBAAgB,EACf,EAAA/D,GAAYC,GAAY8C,IACxBxB,EAAa,CACf,IAAM6C,GAAc7C,EACpByB,GAAW,IAAI,EACf7D,IAAWiF,EAAW,EACtB/E,IAAU,EACVgD,GAAkB,qDAAsB,CAC1C,CACF,EAEMgC,GAAiBN,IAAmB,CACxCA,IAAG,gBAAgB,EACdxC,IAELI,EAAiB,EAAI,EACrBvC,IAAYmC,CAAW,EACzB,EAEM+C,GAAgBP,IAAmB,CACvCA,IAAG,gBAAgB,EACfnC,GACF0B,GAAoB1B,EAAYL,aAAuB,KAAOA,EAAc,MAAS,CAEzF,EAEMgD,GAAiBR,IAAqC,CACtD/D,GAAYC,GAAY8C,KACxBgB,GAAE,MAAQ,SAAWA,GAAE,MAAQ,OACjCA,GAAE,eAAe,EACjBb,GAAoB,GAElB3B,IAAgBwC,GAAE,MAAQ,UAAYA,GAAE,MAAQ,eAClDA,GAAE,eAAe,EACjBI,GAAa,GAEjB,EAGMK,GAAc,IACb/E,KAGH,SAAC,SACC,QAASuB,EACT,UAAW,qEAAqEyB,EAAY,KAAK,IAC/FF,GAAW,iBAAmB,4DAChC,IAAI5B,CAAc,GAEjB,UAAAlB,EACAE,MACC,QAAC,QAAK,UAAU,wBAAwB,cAAY,OAAO,aAE3D,GAEJ,EAfiB,KAmBf8E,GACJ,sIACIC,GAAiB1E,EACnB,mEACA,iBAEE2E,GAAmB,CACvBF,GACAhC,EAAY,WACZE,EACAE,GACA6B,GACAzC,EAAa,iEAAmE,GAChFxB,GAAmBC,CACrB,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAKX,SACE,SAAC,OACC,UAAW,oBALMhB,IAAmB,OAMnB,8BAAgC,UACjD,IAAIY,EAAc,SAAW,aAAa,IANZE,GAAoBD,CAMqB,GAGvE,qBAAC,SACC,IAAKO,GAAOI,EACZ,GAAIF,EACJ,KAAMZ,EACN,KAAK,OACL,OAAQb,EACR,SAAUS,GAAY+C,EACtB,cAAY,OACZ,SAAU,GACV,UAAU,SACV,SAAUe,GACZ,KAGA,QAAC,OAAI,YAAU,SAAS,cAAY,OAAO,UAAU,UAClD,SAAA1B,GACH,EAGCoC,GAAY,KAGb,SAAC,OAAI,UAAW,iBAAiBlE,EAAc,SAAW,EAAE,GAC1D,sBAAC,OACC,KAAK,SACL,SAAUN,GAAY+C,EAAc,GAAK,EACzC,aAAYlC,GAAa,mDACzB,gBAAeb,GAAY+C,EAC3B,eAAcR,GACd,gBAAe5C,EACf,mBAAkBE,GAAgBD,GAAcmC,EAAkBd,EAAW,OAC7E,YAAWlB,EACX,QAASmD,GACT,YAAac,GACb,YAAaC,GACb,WAAaF,IAAM,CACjBA,GAAE,eAAe,EACjBA,GAAE,gBAAgB,CACpB,EACA,OAAQG,GACR,UAAWK,GACX,UAAWI,GAGV,UAAA/C,KACC,QAACgD,GAAA,CACC,IAAKhD,EACL,IAAKC,IAAY,SACjB,MAAO,IACP,OAAQ,IACR,OAAQ/C,IAAU,SAAW,OAASC,EACtC,YAAW,GACX,UAAU,6BACV,iBAAiB,gBACnB,KAGA,QAAC,OACC,UAAW,oHAAoH0D,EAAY,SAAS,GAEnJ,SAAAtC,MAAQ,QAAC0E,GAAA,CAAW,MAAOpC,EAAY,SAAU,OAAQA,EAAY,SAAU,EAClF,EAIDM,MACC,QAAC,OACC,UAAU,8FACV,KAAK,SACL,aAAW,qBAEX,oBAAC+B,GAAA,CAAQ,MAAOrC,EAAY,SAAU,OAAQA,EAAY,SAAU,UAAU,eAAe,EAC/F,EAID,CAACM,GAAe,CAAC/C,GAAY4B,MAC5B,SAAC,OAAI,UAAU,yMAEb,qBAAC,UACC,KAAK,SACL,QAASyC,GACT,aAAW,uDACX,MAAM,sBACN,UAAU,kKACV,cAAY,wBAEZ,oBAACU,GAAA,CAAQ,MAAO,GAAI,OAAQ,GAAI,EAClC,EAGC3B,IAAgB,CAACnD,MAChB,QAAC,UACC,KAAK,SACL,QAASqE,GACT,aAAW,4CACX,MAAM,oBACN,UAAU,kKACV,cAAY,qBAEZ,oBAACU,GAAA,CAAS,MAAO,GAAI,OAAQ,GAAI,EACnC,GAIA,CAAC/E,GAAYC,OACb,QAAC,UACC,KAAK,SACL,QAASiE,GACT,aAAW,0CACX,MAAM,kBACN,UAAU,+KACV,cAAY,uBAEZ,oBAACc,GAAA,CAAU,MAAO,GAAI,OAAQ,GAAI,EACpC,GAEJ,GAEJ,KAGA,QAACC,GAAA,CACC,GAAIjE,EACJ,WAAYrB,EACZ,aAAc0C,GACd,cAAeG,EAAY,OAC3B,UAAW7B,EACb,EAGCwC,IAAgB5B,OACf,QAAC2D,GAAA,CACC,KAAM,EAAQ3D,GACd,SAAUA,GAAS,SACnB,SAAUA,GAAS,SACnB,SAAUA,GAAS,SACnB,YAAa6B,GAAY,aAAe,EACxC,UAAWA,GAAY,YAAcvE,IAAU,SAAW,QAAU,QACpE,SAAUuE,GAAY,UAAY,GAClC,QAASA,GAAY,SAAW,EAChC,QAASA,GAAY,SAAW,EAChC,WAAYA,GAAY,YAAc,4CACtC,QAAS,IAAM5B,GAAY,IAAI,EAC/B,QAAU2D,IAAsB,CAC9BpC,GAAWoC,EAAW,EACtB/C,GAAkB,sGAA2C,EAC7DZ,GAAY,IAAI,CAClB,EACF,EAGDC,IAAiBH,MAChB,QAAC8D,GAAA,CACC,KAAM3D,GACN,QAAS,IAAMC,EAAiB,EAAK,EACrC,KAAMJ,EACR,GAEJ,GACF,CAEJ,COvcO,IAAM+D,GAAkC,IAElCC,GAgBT,CACF,GAAI,CACF,OAAQ,0BACR,OAAQ,UACR,KAAM,UACN,OAAQ,aACR,MAAO,uDACP,YAAa,0CACb,YAAa,sBACb,KAAM,SACN,WAAY,KACZ,UAAW,QACX,YAAa,2BACb,UAAW,UACb,EACA,GAAI,CACF,OAAQ,4BACR,OAAQ,QACR,KAAM,UACN,OAAQ,iBACR,MAAO,yDACP,YAAa,0CACb,YAAa,sBACb,KAAM,SACN,WAAY,KACZ,UAAW,UACX,YAAa,2BACb,UAAW,QACb,EACA,GAAI,CACF,OAAQ,0BACR,OAAQ,UACR,KAAM,UACN,OAAQ,aACR,MAAO,uDACP,YAAa,2CACb,YAAa,uBACb,KAAM,SACN,WAAY,KACZ,UAAW,QACX,YAAa,6BACb,UAAW,QACb,EACA,GAAI,CACF,OAAQ,0BACR,OAAQ,QACR,KAAM,YACN,OAAQ,iBACR,MAAO,sDACP,YAAa,6CACb,YAAa,uBACb,KAAM,SACN,WAAY,KACZ,UAAW,UACX,YAAa,+BACb,UAAW,UACb,EACA,GAAI,CACF,OAAQ,0BACR,OAAQ,UACR,KAAM,UACN,OAAQ,aACR,MAAO,mDACP,YAAa,2CACb,YAAa,uBACb,KAAM,SACN,WAAY,KACZ,UAAW,QACX,YAAa,2BACb,UAAW,QACb,CACF,EAEaC,GAA8C,CACzD,KAAM,eACN,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,GAAI,aACJ,KAAM,aACR,EAEaC,GAAqD,CAChE,QAAS,2DACT,UAAW,iEACX,QAAS,4DACT,MAAO,qDACP,QAAS,2DACT,QAAS,2DACT,KAAM,iDACR,EAEaC,GAA4E,CACvF,QAASC,GACT,MAAOC,GACP,QAASC,GACT,KAAMC,GACN,QAASA,GACT,UAAWA,GACX,QAASA,EACX,EC9HA,IAAAC,GAA0C,iBAgC7BC,MAAiB,kBAA0C,IAAI,EAK/DC,GAAoB,OAAM,eAAWD,EAAc,ECJ5D,IAAAE,GAAA,6BAtBW,SAARC,GAAyB,CAC9B,KAAAC,EACA,OAAAC,EACA,UAAAC,EAAY,GACZ,SAAAC,EACA,IAAAC,EACA,GAAGC,CACL,EAAiB,CACf,IAAMC,EAAiBC,GAAkB,EACnCC,EAAcC,EAAcT,GAAQM,GAAgB,KAAMI,GAAY,IAAI,EAC1EC,EAAeF,EAAcR,EAAQW,GAAc,IAAI,EAEvDC,EAAmB,CACvB,0IACAL,EAAY,OACZG,EACAT,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,SACE,QAAC,OACC,IAAKE,EACL,SAAU,GACV,UAAWS,EACV,GAAGR,EAEH,SAAAF,EACH,CAEJ,CC1CA,IAAAW,GAAkF,iBA4H5E,IAAAC,GAAA,6BAvHS,SAARC,GAAkC,CACvC,KAAAC,EAAO,GACP,KAAAC,EAAO,KACP,MAAAC,EAAQ,UACR,UAAAC,EAAY,GACZ,oBAAAC,EAAsB,GACtB,WAAAC,EAAa,GACb,WAAAC,EAAa,GACb,iBAAAC,EAAmB,GACnB,UAAAC,EAAY,GACZ,SAAAC,EACA,QAAAC,EACA,GAAGC,CACL,EAA0B,CACxB,IAAMC,KAAY,WAA0B,IAAI,EAC1C,CAACC,EAAWC,CAAY,KAAI,aAAS,EAAK,EAC1CC,KAAe,WAA6C,IAAI,EAEhEC,KAAqB,gBAAY,IAAM,CACvCH,GAAaV,IAEjBW,EAAa,EAAI,EACbC,EAAa,SACf,aAAaA,EAAa,OAAO,EAEnCA,EAAa,QAAU,WAAW,IAAM,CACtCD,EAAa,EAAK,EAClBJ,IAAU,CACZ,EAAGO,EAA+B,EACpC,EAAG,CAACJ,EAAWV,EAAWO,CAAO,CAAC,EAE5BQ,KAAe,YACnB,KAAO,CACL,QAASF,EACT,UAAAb,EACA,KAAAF,EACA,MAAAC,CACF,GACA,CAACc,EAAoBb,EAAWF,EAAMC,CAAK,CAC7C,KAGA,cAAU,IACD,IAAM,CACPa,EAAa,SACf,aAAaA,EAAa,OAAO,CAErC,EACC,CAAC,CAAC,KAGL,cAAU,IAAM,CACd,IAAMI,EAASP,EAAU,QACzB,GAAKO,EAEL,GAAInB,GAAQa,GACV,GAAI,CAACM,EAAO,KACV,GAAI,CACFA,EAAO,UAAU,CACnB,MAAQ,CAAc,OAGpBA,EAAO,MACTA,EAAO,MAAM,CAGnB,EAAG,CAACnB,EAAMa,CAAS,CAAC,KAGpB,cAAU,IAAM,CACd,GAAI,CAACP,EAAY,OAEjB,IAAMc,EAAmB,SAAS,KAAK,MAAM,SAC7C,gBAAS,KAAK,MAAM,SAAW,SAExB,IAAM,CACX,SAAS,KAAK,MAAM,SAAWA,CACjC,CACF,EAAG,CAACd,CAAU,CAAC,EAMf,IAAMe,KAAgB,mBAAgBC,GAAqB,CACrD,CAACtB,GAAQK,IAAe,IAExBiB,EAAE,MAAQ,WACZA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBN,EAAmB,EAEvB,CAAC,EASD,MAPA,cAAU,KACR,OAAO,iBAAiB,UAAWK,CAAa,EACzC,IAAM,CACX,OAAO,oBAAoB,UAAWA,CAAa,CACrD,GACC,CAAC,CAAC,EAED,CAACrB,GAAQ,CAACa,EACZ,OAAO,KAGT,IAAMU,EAAqB,IAAM,CAC3BnB,GACFY,EAAmB,CAEvB,EAEMQ,EAAoBX,EACtB,mDACA,8BAEEY,EAAkBZ,EAAY,0CAA4C,qBAEhF,SACE,QAACa,GAAe,SAAf,CAAwB,MAAOR,EAC9B,qBAAC,UACC,IAAKN,EACL,kBAAgB,uBAChB,mBAAiB,6BACjB,SAAWU,GAAM,CACfA,EAAE,eAAe,EACbjB,IAAe,IACjBW,EAAmB,CAEvB,EACA,UAAW,0LAA0LQ,CAAiB,IAAIjB,CAAgB,GACzO,GAAGI,EAEJ,qBAAC,OAAI,cAAY,OAAO,QAASY,EAAoB,UAAU,sBAAsB,KACrF,QAAC,OAAI,UAAW,+DAA+DE,CAAe,IAAIjB,CAAS,GACxG,SAAAC,EACH,GACF,EACF,CAEJ,CCvGQ,IAAAkB,GAAA,6BA/BO,SAARC,GAA+B,CACpC,KAAAC,EACA,MAAAC,EACA,KAAAC,EAAO,GACP,MAAAC,EACA,cAAAC,EAAgB,GAChB,eAAAC,EAAiB,GACjB,gBAAAC,EAAkB,GAClB,QAAAC,EACA,qBAAAC,EAAuB,GACvB,UAAAC,EAAY,GACZ,SAAAC,EACA,GAAGC,CACL,EAAuB,CACrB,IAAMC,EAAiBC,GAAkB,EACnCC,EAAcC,EAAcf,GAAQY,GAAgB,KAAMI,GAAY,IAAI,EAC1EC,EAAaF,EAAcd,GAASW,GAAgB,MAAOM,GAAsB,SAAS,EAC1FC,EAAYP,GAAgB,UAE5BQ,EAAc,IAAM,CACxBb,IAAU,EACVK,GAAgB,UAAU,CAC5B,EAEMS,EAAkB,GAAQd,GAAWK,GAAgB,SAErDU,EAAa,IAAM,CACvB,GAAIpB,IAAS,GAAO,OAAO,KAE3B,GAAIA,IAAS,QAAaA,IAAS,GACjC,SACE,QAAC,OACC,UAAW,oDAAoDY,EAAY,WAAW,IAAIG,CAAU,IAAIb,CAAa,GACrH,cAAY,OAEX,SAAAF,EACH,EAGJ,IAAMqB,EAAgBR,EAAcd,GAASW,GAAgB,MAAOY,GAAc,SAAS,EAC3F,SACE,QAAC,OACC,UAAW,oDAAoDV,EAAY,WAAW,IAAIG,CAAU,IAAIb,CAAa,GACrH,cAAY,OAEZ,oBAACmB,EAAA,CAAc,UAAWT,EAAY,KAAM,EAC9C,CAEJ,EAEA,SACE,SAAC,OAAI,UAAW,2CAA2CA,EAAY,MAAM,IAAIL,CAAS,GAAK,GAAGE,EAChG,sBAAC,OAAI,UAAU,yCACZ,UAAAW,EAAW,EACXnB,MACC,QAAC,MAAG,UAAW,GAAGW,EAAY,KAAK,aAAaT,CAAc,GAAI,GAAG,uBAClE,SAAAF,EACH,EAEDO,GACH,EAECJ,GAAmBe,MAClB,QAAC,UACC,KAAK,SACL,QAASD,EACT,SAAUD,EACV,aAAW,mCACX,UAAW,8NAA8NL,EAAY,WAAW,IAAIN,CAAoB,GAExR,oBAACiB,GAAA,CAAU,UAAWX,EAAY,UAAW,EAC/C,GAEJ,CAEJ,CCjEI,IAAAY,GAAA,6BAZW,SAARC,GAA6B,CAClC,KAAAC,EACA,YAAAC,EACA,qBAAAC,EAAuB,GACvB,UAAAC,EAAY,GACZ,SAAAC,EACA,GAAGC,CACL,EAAqB,CACnB,IAAMC,EAAiBC,GAAkB,EACnCC,EAAcC,EAAcT,GAAQM,GAAgB,KAAMI,GAAY,IAAI,EAEhF,SACE,SAAC,OACC,UAAW,UAAUF,EAAY,IAAI,IAAIL,CAAS,GAClD,GAAG,6BACF,GAAGE,EAEH,UAAAJ,KACC,QAAC,KAAE,UAAW,GAAGO,EAAY,WAAW,IAAIN,CAAoB,GAAK,SAAAD,EAAY,EAC/E,KACHG,GACH,CAEJ,CCuBM,IAAAO,GAAA,6BA7CS,SAARC,GAA+B,CACpC,KAAAC,EACA,YAAAC,EAAc,mBACd,WAAAC,EAAa,WACb,eAAAC,EAAiB,SACjB,cAAAC,EAAgB,UAChB,aAAAC,EACA,YAAAC,EAAc,YACd,UAAAC,EACA,SAAAC,EACA,QAAAC,EACA,mBAAAC,EACA,kBAAAC,EACA,UAAAC,EAAY,GACZ,SAAAC,EACA,GAAGC,CACL,EAAuB,CACrB,IAAMC,EAAiBC,GAAkB,EACnCC,EAAcC,EAAclB,GAAQe,GAAgB,KAAMI,GAAY,IAAI,EAC1EC,EAAsBf,GAAgBU,GAAgB,OAAS,UAG/DM,EAAe,IAAM,CACzBZ,IAAU,EACVM,GAAgB,UAAU,CAC5B,EAEMO,EAAgB,SAAY,CAChC,GAAI,CACF,IAAMC,EAAShB,IAAY,EAEvBgB,GAAU,SAAUA,GACtB,MAAMA,EAERF,EAAa,CACf,MAAQ,CAAc,CACxB,EAEMG,EAAe,IAAM,CACzBhB,IAAW,EACXa,EAAa,CACf,EAEA,OAAIR,KAEA,QAAC,OACC,UAAW,wCAAwCI,EAAY,MAAM,IAAIA,EAAY,SAAS,IAAIL,CAAS,GAC1G,GAAGE,EAEH,SAAAD,EACH,KAKF,SAAC,OACC,UAAW,wCAAwCI,EAAY,MAAM,IAAIA,EAAY,SAAS,IAAIL,CAAS,GAC1G,GAAGE,EAEH,UAAAZ,IAAe,OACd,QAACuB,GAAA,CACC,KAAMR,EAAY,WAClB,QAASb,EACT,MAAOE,EACP,QAASkB,EACT,SAAUb,GAAmB,UAAYI,GAAgB,UACxD,GAAGJ,EAEH,SAAAT,EACH,KAGF,QAACuB,GAAA,CACC,KAAMR,EAAY,WAClB,QAASd,EACT,MAAOiB,EACP,UAAWL,GAAgB,WAAaL,GAAoB,UAC5D,SAAUA,GAAoB,SAC9B,QAASY,EACR,GAAGZ,EAEH,SAAAT,EACH,GACF,CAEJ,CC9FA,IAAAyB,GAAuE,iBAwCnE,IAAAC,GAAA,6BAhCW,SAARC,GAA8B,CACnC,SAAAC,EACA,QAAAC,EAAU,GACV,QAAAC,EACA,GAAGC,CACL,EAAsB,CACpB,IAAMC,EAAiBC,GAAkB,EACnCC,EAAYF,GAAgB,UAE5BG,EAAeC,GAA+B,CAClDN,IAAUM,CAAC,EACNA,EAAE,kBACLJ,GAAgB,UAAU,CAE9B,EAEA,GAAIH,MAAW,mBAAeD,CAAQ,EAAG,CACvC,IAAMS,EAAQT,EAId,SAAO,iBAAaS,EAAO,CACzB,SAAUA,EAAM,MAAM,UAAYH,EAClC,QAAUE,GAA+B,CACvCC,EAAM,MAAM,UAAUD,CAAC,EACvBD,EAAYC,CAAC,CACf,EACA,GAAGL,CACL,CAAC,CACH,CAEA,SACE,QAAC,UAAO,KAAK,SAAS,QAASI,EAAa,SAAUD,EAAY,GAAGH,EAClE,SAAAH,EACH,CAEJ","names":["index_exports","__export","AUDIO_EXTENSIONS","Alert","AlertCircleIcon","AlertTriangleIcon","Badge","Button","Calendar","CalendarHeader","CalendarIcon","Carousel","CarouselContent","CarouselNext","CarouselPagination","CarouselPrevious","CarouselSlide","CheckCircleIcon","CheckIcon","Checkbox","CheckboxGroup","CheckboxGroupContext","ChevronDownIcon","ChevronLeftIcon","ChevronRightIcon","ClockIcon","CloseIcon","Collapse","CollapseContent","CollapseHeader","CollapsePanel","Collapsible","Confirm","ConfirmBody","ConfirmClose","ConfirmContainer","ConfirmFooter","ConfirmHeader","CropIcon","DEFAULT_TOAST_DURATION","DOCUMENT_EXTENSIONS","DatePicker","DateRangeCalendar","DateRangeDayGrid","DateRangeHeader","DateRangeMonthGrid","DateRangePicker","DateRangeYearGrid","DateTimePicker","DateTimeRangePicker","DayGrid","DoubleChevronLeftIcon","DoubleChevronRightIcon","DownloadIcon","Dropdown","DropdownGroup_default","DropdownHeader_default","DropdownItem_default","DropdownMenu","DropdownSeparator_default","DropdownTrigger_default","Empty","EmptyDefaultIcon_default","EmptyErrorIcon_default","EmptyFolderIcon_default","EmptyIllustration","EmptySearchIcon_default","EmptySimpleIcon_default","EyeIcon_default","FileContainer","FilePreview","FlipHorizontalIcon","IMAGE_EXTENSIONS","IconButton","ImageIcon","ImagePreview","ImagePreviewToolbar","InfoCircleIcon","Input","LoadingImage","MinusIcon","Modal","ModalBody","ModalClose","ModalContainer","ModalFooter","ModalHeader","MonthGrid","MultiInput","NumberInput","OtpInput","PDF_EXTENSIONS","PasswordInput","PlusIcon","Popover","PopoverBody_default","PopoverClose_default","PopoverContent_default","PopoverFooter_default","PopoverHeader_default","PopoverTrigger_default","Radio","RadioDotIcon","RadioGroup","RadioGroupContext","ResetIcon","RotateCcwIcon","RotateCwIcon","SearchIcon_default","Select_default","Select","SelectMenu_default","SelectMenuFilter_default","SelectOption_default","SelectTrigger_default","Skeleton","Slider","SliderMarks","SliderStepDots","SliderThumb","Spinner","Tab","TabList","TabPanel","TabPanels","Tabs","TabsContext","TextArea","TimeColumn","TimePicker","TimeRangePicker","TimeView","Toaster","Toggle","Tooltip","TrashIcon","UploadAvatar","UploadAvatarCropContent","UploadAvatarCropModal","UploadIcon","UploadImage","UploadImageDropzone","UploadImageList","VIDEO_EXTENSIONS","YearGrid","ZoomInIcon","ZoomOutIcon","checkIsDisabled","clamp","combineDateTime","createDateWithTime","createFileItem","downloadFile","formatBytes","formatDate","formatDateTime","formatNumberString","formatTime","generateCalendarGrid","generateRangeCalendarGrid","getDefaultDateTimeFormat","getDefaultFormat","getFileExtension","getFileName","getFileType","getISOWeekNumber","getPercentage","isDateAfter","isDateBefore","isSameDay","isSameMonth","isSameTime","isTimeAfter","isTimeBefore","isTimeInRange","isValidOtpChar","normalizePreviewFile","padZero","parseDate","parseDateTime","parseNumber","parseRawNumberString","parseTimeToDate","resolveLocale","revokeFileItem","sanitizeOtpString","splitTagsFromText","toDate","toDateTime","toTimeObject","toast","useCarousel","useCarouselContext","useCheckboxGroupContext","useCollapseContext","useCollapsePanelContext","useConfirmContext","useDebounce","useDebouncedCallback","useDropdownContext","useFileContext","useModalContext","usePopoverContext","useRadioGroupContext","useTabsContext","validateFile","__toCommonJS","sizeConfig","radiusConfig","variantColorConfig","getSafeConfig","key","configMap","fallbackKey","import_jsx_runtime","Spinner","width","height","className","props","import_jsx_runtime","Button","size","variant","color","radius","leftIcon","rightIcon","isLoading","showSpinner","loadingText","isFullWidth","disabled","type","className","children","ref","props","currentSize","getSafeConfig","sizeConfig","variantStyles","variantColorConfig","roundedClass","radiusConfig","classNames","renderIconWrapper","iconNode","displayContent","Spinner","import_jsx_runtime","IconButton","icon","size","variant","color","radius","isLoading","showSpinner","disabled","type","className","ref","props","currentSize","getSafeConfig","sizeConfig","variantStyles","variantColorConfig","roundedClass","radiusConfig","classNames","renderIconWrapper","iconNode","Spinner","sizeConfig","radiusConfig","dotColorConfig","variantColorConfig","import_jsx_runtime","CloseIcon","width","height","className","props","import_jsx_runtime","Badge","size","variant","color","radius","dot","dotPing","leftIcon","rightIcon","onDelete","deleteAriaLabel","className","children","onClick","ref","props","currentSize","getSafeConfig","sizeConfig","variantStyles","variantColorConfig","dotBg","dotColorConfig","roundedClass","radiusConfig","classNames","renderIconWrapper","iconNode","e","CloseIcon","import_react","sizeConfig","radiusConfig","badgeRadiusMap","multiInputSizeConfig","variantColorConfig","labelColorConfig","otpSlotSizeConfig","import_react","useAnimatedError","errorMessage","options","exitDuration","displayedError","setDisplayedError","isExiting","setIsExiting","prevErrorMessage","setPrevErrorMessage","timer","import_jsx_runtime","HelperErrorText","id","helperText","errorMessage","sizeClassName","className","displayedError","isExiting","useAnimatedError","activeText","hasMessage","isShowingError","import_jsx_runtime","Input","size","variant","color","radius","label","labelPlacement","config","helperText","errorMessage","leftIcon","leftAddon","rightIcon","rightAddon","onClear","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","id","value","defaultValue","onChange","disabled","readOnly","className","type","placeholder","ref","props","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","generatedId","inputId","errorHelperId","internalRef","mergedRef","isControlled","internalValue","setInternalValue","currentValue","handleChange","e","handleClear","hasValue","hasError","activeColor","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","variantStyles","variantColorConfig","renderIconWrapper","iconNode","isFloating","renderLabel","labelColorStyle","labelColorConfig","containerClasses","inputClasses","Spinner","CloseIcon","HelperErrorText","import_react","import_jsx_runtime","EyeIcon","width","height","className","props","EyeOffIcon","EyeIcon_default","import_jsx_runtime","PasswordInput","defaultVisible","toggleAriaLabel","onVisibilityChange","rightIcon","disabled","readOnly","props","isVisible","setIsVisible","Input","nextState","EyeOffIcon","EyeIcon","import_react","formatNumberString","rawInput","options","thousandSep","decimalSep","maxDecimals","min","max","clampMin","allowNeg","rawStr","isNegative","parts","integerDigits","decimalDigits","floatVal","formattedInteger","sign","digitsOnly","num","absFormatted","parseRawNumberString","formattedValue","parseNumber","clean","calculateCaretPosition","oldValue","newValue","oldCaretPosition","charsBeforeCaret","i","ch","newCaretPosition","charsCount","isValidOtpChar","char","type","sanitizeOtpString","str","splitTagsFromText","text","splitRegex","trim","item","import_jsx_runtime","NumberInput","value","defaultValue","min","max","thousandSeparator","decimalSeparator","maxDecimalDigits","allowNegative","onChange","onClear","onBlur","ref","props","formatOptions","isControlled","internalValue","setInternalValue","currentValue","formattedDisplayValue","formatNumberString","handleClear","handleChange","e","inputElement","rawInputValue","oldCaretPos","newFormattedValue","newCaretPos","calculateCaretPosition","syntheticEvent","handleBlur","num","parseNumber","clampedValue","Input","import_react","import_jsx_runtime","OtpInput","ref","config","id","name","length","value","defaultValue","onChange","onComplete","type","mask","size","variant","color","radius","autoFocus","disabled","readOnly","groupSize","separator","ariaLabel","getSlotAriaLabel","allowOneTimeCode","label","labelPlacement","helperText","errorMessage","className","slotClassName","wrapperClassName","labelClassName","helperClassName","isRequired","isInvalid","isLoading","showSpinner","generatedId","baseId","inputSlotId","errorHelperId","internalValues","setInternalValues","initial","_","i","inputRefs","isControlled","currentValues","hasError","activeColor","firstEmptyIndex","val","targetIndex","empty","index","triggerChange","newValues","combined","fillOtpSlots","text","sanitized","sanitizeOtpString","nextValues","startIndex","chars","char","nextFocusIndex","handleSlotChange","e","inputValue","lastChar","isValidOtpChar","handleKeyDown","handlePaste","pastedData","currentSize","getSafeConfig","otpSlotSizeConfig","sizeStyles","sizeConfig","roundedClass","radiusConfig","variantStyles","variantColorConfig","disabledStyles","renderLabel","isMasked","slotAriaLabel","shouldRenderSeparator","el","Spinner","HelperErrorText","import_react","import_jsx_runtime","PlusIcon","width","height","className","props","import_jsx_runtime","MultiInput","size","variant","color","radius","label","labelPlacement","config","helperText","errorMessage","leftIcon","leftAddon","rightIcon","rightAddon","onClear","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","id","name","value","defaultValue","onChange","inputValue","onInputValueChange","delimiters","showAddButton","renderAddButton","addOnBlur","addOnPaste","pasteSplitRegex","trimValues","allowDuplicates","onDuplicate","maxTags","onMaxTagsReached","maxTagLength","validateTag","onValidateError","maxTagCount","renderTag","tagVariant","tagColor","tagRadius","tagSize","tagClassName","addButtonClassName","disabled","readOnly","className","placeholder","autoFocus","ref","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","generatedId","inputId","errorHelperId","labelId","internalRef","mergedRef","isValuesControlled","internalValues","setInternalValues","currentValues","isInputControlled","internalInputValue","setInternalInputValue","currentInputValue","liveAnnouncement","setLiveAnnouncement","setInputText","nextText","updateValues","nextValues","addTag","rawTag","tag","validationResult","addMultipleTags","rawTags","existingTagsSet","addedCount","raw","removeTag","indexToRemove","removedItem","_","i","handleClear","e","handleKeyDown","handlePaste","pasteText","parts","splitTagsFromText","handleBlur","hasValue","hasError","activeColor","currentSize","getSafeConfig","multiInputSizeConfig","roundedClass","radiusConfig","resolvedBadgeRadius","badgeRadiusMap","resolvedBadgeSize","resolvedTagColor","resolvedTagVariant","variantStyles","variantColorConfig","isFloating","renderIconWrapper","iconNode","renderLabel","labelColorStyle","labelColorConfig","visibleTags","hiddenTagCount","disabledStyles","containerClasses","isHorizontal","canAddMore","showAddBtn","tagOccurrenceMap","tagVal","index","count","tagKey","Badge","PlusIcon","Spinner","CloseIcon","HelperErrorText","hiddenOccurrenceMap","import_react","import_react_textarea_autosize","sizeConfig","radiusConfig","resizeConfig","variantColorConfig","labelColorConfig","import_jsx_runtime","TextArea","size","variant","color","radius","label","labelPlacement","config","helperText","errorMessage","onClear","minRows","maxRows","onHeightChange","cacheMeasurements","resize","wrapperClassName","textareaWrapperClassName","labelClassName","helperClassName","countClassName","id","value","defaultValue","onChange","disabled","readOnly","className","placeholder","maxLength","ref","style","props","isRequired","isInvalid","isLoading","showSpinner","isClearable","showCount","isFullWidth","autoResize","generatedId","textareaId","errorHelperId","internalRef","internalValue","setInternalValue","mergedRef","isControlled","currentValue","isInvalidState","activeColor","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","resizeClass","resizeConfig","variantStyles","variantColorConfig","currentLength","hasValue","handleChange","e","nextValue","handleClear","isFloating","renderLabel","labelColorStyle","labelColorConfig","containerClasses","hasTopRightAction","textareaClasses","isHorizontal","commonProps","TextareaAutosize","Spinner","CloseIcon","HelperErrorText","import_react","sizeConfig","radiusConfig","variantColorConfig","import_react","CheckboxGroupContext","useCheckboxGroupContext","import_jsx_runtime","CheckIcon","width","height","className","props","import_jsx_runtime","MinusIcon","width","height","className","props","import_jsx_runtime","Checkbox","sizeProp","variantProp","colorProp","radiusProp","indeterminate","isLoadingProp","isInvalidProp","isRequiredProp","labelProp","children","helperText","errorMessage","labelPlacementProp","icon","indeterminateIcon","wrapperClassName","boxClassName","labelClassName","helperClassName","className","checkedProp","defaultChecked","disabledProp","readOnlyProp","onChange","value","idProp","nameProp","ref","props","label","group","useCheckboxGroupContext","generatedId","id","helperId","size","variant","color","radius","disabled","isReadOnly","isLoading","isRequired","isInvalid","labelPlacement","isGroupControlled","isControlled","internalChecked","setInternalChecked","isChecked","innerRef","handleChange","e","currentSize","sizeConfig","roundedClass","radiusConfig","isCheckedOrIndeterminate","boxVariantStyles","variantColorConfig","boxClasses","labelClasses","wrapperClasses","renderIcon","Spinner","MinusIcon","CheckIcon","hasContent","HelperErrorText","import_react","import_jsx_runtime","CheckboxGroup","valueProp","defaultValue","onChange","size","color","variant","radius","disabled","isReadOnly","isLoading","isInvalidProp","isRequired","label","helperText","errorMessage","orientation","labelPlacement","className","wrapperClassName","labelClassName","helperClassName","children","ref","props","generatedId","labelId","helperId","isControlled","internalValue","setInternalValue","currentValue","isInvalid","handleCheckboxChange","val","isChecked","nextValue","item","contextValue","orientationClasses","groupLabelClasses","currentSize","sizeConfig","CheckboxGroupContext","HelperErrorText","import_react","sizeConfig","variantColorConfig","import_react","RadioGroupContext","useRadioGroupContext","import_jsx_runtime","RadioDotIcon","className","import_jsx_runtime","Radio","sizeProp","variantProp","colorProp","isLoadingProp","isInvalidProp","isRequiredProp","label","helperText","errorMessage","labelPlacementProp","dotIcon","wrapperClassName","boxClassName","labelClassName","helperClassName","className","checkedProp","defaultChecked","disabledProp","readOnlyProp","onChange","value","idProp","nameProp","ref","props","group","useRadioGroupContext","generatedId","id","helperId","size","variant","color","disabled","isReadOnly","isLoading","isRequired","isInvalid","labelPlacement","name","isGroupControlled","isControlled","internalChecked","setInternalChecked","isChecked","innerRef","handleChange","e","currentSize","sizeConfig","boxVariantStyles","variantColorConfig","boxClasses","labelClasses","wrapperClasses","renderDot","Spinner","RadioDotIcon","hasContent","HelperErrorText","import_react","import_jsx_runtime","RadioGroup","valueProp","defaultValue","onChange","size","color","variant","disabled","isReadOnly","isLoading","isInvalidProp","isRequired","label","helperText","errorMessage","orientation","labelPlacement","className","wrapperClassName","labelClassName","helperClassName","children","ref","props","generatedId","labelId","helperId","groupName","isControlled","internalValue","setInternalValue","currentValue","isInvalid","handleRadioChange","val","contextValue","orientationClasses","groupLabelClasses","currentSize","sizeConfig","RadioGroupContext","HelperErrorText","import_react","sizeConfig","radiusConfig","variantColorConfig","import_jsx_runtime","Toggle","size","variant","color","radius","thumbRadius","config","label","helperText","errorMessage","labelPlacement","thumbIcon","startContent","endContent","wrapperClassName","trackClassName","thumbClassName","labelClassName","helperClassName","className","checkedProp","defaultChecked","disabled","readOnly","onChange","onClick","value","id","name","ref","props","isRequired","isInvalid","isLoading","showSpinner","generatedId","toggleId","errorHelperId","internalRef","mergedRef","isControlled","internalChecked","setInternalChecked","isChecked","handleChange","e","handleClick","handleWrapperClick","hasError","activeColor","currentSize","getSafeConfig","sizeConfig","trackRadiusClass","radiusConfig","thumbRadiusClass","variantStyles","variantColorConfig","trackStyles","thumbStyles","trackClasses","thumbClasses","labelClasses","wrapperClasses","renderThumbIcon","Spinner","renderLabel","HelperErrorText","import_jsx_runtime","ChevronDownIcon","width","height","className","props","import_jsx_runtime","ChevronLeftIcon","width","height","className","props","import_jsx_runtime","ChevronRightIcon","width","height","className","props","import_jsx_runtime","CalendarIcon","width","height","className","props","import_jsx_runtime","ClockIcon","width","height","className","props","import_jsx_runtime","DoubleChevronLeftIcon","width","height","className","props","import_jsx_runtime","DoubleChevronRightIcon","width","height","className","props","import_jsx_runtime","EmptyDefaultIcon","props","EmptyDefaultIcon_default","import_jsx_runtime","EmptySearchIcon","props","EmptySearchIcon_default","import_jsx_runtime","EmptyErrorIcon","props","EmptyErrorIcon_default","import_jsx_runtime","EmptyFolderIcon","props","EmptyFolderIcon_default","import_jsx_runtime","EmptySimpleIcon","props","EmptySimpleIcon_default","import_jsx_runtime","InfoCircleIcon","width","height","className","props","import_jsx_runtime","CheckCircleIcon","width","height","className","props","import_jsx_runtime","AlertTriangleIcon","width","height","className","props","import_jsx_runtime","AlertCircleIcon","width","height","className","props","import_jsx_runtime","ZoomInIcon","width","height","className","props","import_jsx_runtime","ZoomOutIcon","width","height","className","props","import_jsx_runtime","RotateCwIcon","width","height","className","props","import_jsx_runtime","RotateCcwIcon","width","height","className","props","import_jsx_runtime","FlipHorizontalIcon","width","height","className","props","import_jsx_runtime","DownloadIcon","width","height","className","props","import_jsx_runtime","ResetIcon","width","height","className","props","import_jsx_runtime","ImageIcon","width","height","className","props","import_jsx_runtime","CropIcon","width","height","className","props","import_jsx_runtime","SearchIcon","width","height","className","props","SearchIcon_default","import_jsx_runtime","TrashIcon","width","height","className","props","import_jsx_runtime","UploadIcon","width","height","className","props","sizeConfig","radiusConfig","variantColorConfig","iconColorConfig","defaultIcons","InfoCircleIcon","CheckCircleIcon","AlertTriangleIcon","AlertCircleIcon","import_jsx_runtime","Alert","size","variant","color","radius","title","description","icon","action","closable","onClose","closeAriaLabel","banner","titleClassName","descriptionClassName","actionClassName","iconClassName","closeButtonClassName","className","children","role","ref","props","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","variantStyles","variantColorConfig","iconColorStyle","iconColorConfig","isClosable","handleClose","e","activeRole","ariaLive","bodyContent","hasBody","renderIcon","IconComponent","defaultIcons","containerClasses","CloseIcon","import_sonner","DEFAULT_TOAST_DURATION","import_jsx_runtime","Toaster","position","visibleToasts","expand","duration","closeButton","className","toastOptions","props","SonnerToaster","import_react","import_sonner","import_jsx_runtime","showToast","title","color","variant","description","options","customId","duration","position","onDismiss","onAutoClose","alertProps","sonnerToast","id","Alert","isToastMessageObject","value","extractMessageDetails","result","fallbackColor","fallbackVariant","baseToast","opts","arg","Spinner","promiseInput","promise","loadingTitle","loadingDesc","toastId","data","rawSuccess","successTitle","successDesc","successColor","successVariant","err","rawError","errorTitle","errorDesc","errorColor","errorVariant","toast","import_react","sizeConfig","radiusConfig","variantColorConfig","arrowColorConfig","DEFAULT_Z_INDEX","import_jsx_runtime","Slot","children","forwardedRef","disabled","className","props","childRef","mergedChildRef","childProps","Tooltip","content","placement","variant","color","size","radius","hasArrow","offset","flip","shift","delay","animated","animationDuration","controlledOpen","defaultOpen","onOpenChange","arrowClassName","zIndex","DEFAULT_Z_INDEX","open","setOpen","arrowRef","setArrowRef","isControlled","isOpen","handleOpenChange","nextOpen","middleware","offsetMiddleware","flipMiddleware","shiftMiddleware","arrowMiddleware","setReference","setFloating","floatingStyles","context","computedPlacement","hover","focus","dismiss","role","getReferenceProps","getFloatingProps","isMounted","transitionStyles","side","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","variantStyles","variantColorConfig","arrowColorClass","arrowColorConfig","classNames","triggerProps","import_react","SliderPrimitive","sizeConfig","radiusConfig","variantColorConfig","import_react","SliderPrimitive","import_jsx_runtime","SliderThumb","id","thumbIdx","value","orientation","size","thumbRadiusClass","thumbThemeStyles","thumbClassName","tooltipClassName","state","label","helperId","tooltipMode","tooltipPlacement","formatTooltip","isLoading","showSpinner","disabled","readOnly","isRequired","isInvalid","isRange","hasDescription","currentSize","getSafeConfig","sizeConfig","isHovered","setIsHovered","isFocused","setIsFocused","isDragging","setIsDragging","isTooltipOpen","defaultPlacement","formattedTooltipContent","valueText","thumbNode","Spinner","Tooltip","clamp","val","min","max","getPercentage","import_jsx_runtime","SliderMarks","marks","min","max","step","orientation","size","markClassName","markList","totalSteps","i","val","currentSize","getSafeConfig","sizeConfig","m","pct","getPercentage","SliderStepDots","showSteps","isRange","currentValues","dots","isFilled","import_jsx_runtime","Slider","config","valueProp","defaultValueProp","min","max","step","minStepsBetweenThumbs","inverted","size","variant","color","radius","thumbRadius","orientation","label","labelPlacement","formatValue","showTooltip","tooltipPlacement","formatTooltip","marks","startContent","endContent","disabled","readOnly","helperText","errorMessage","name","idProp","onChange","onChangeEnd","className","wrapperClassName","trackWrapperClassName","trackClassName","fillerClassName","thumbClassName","labelClassName","valueClassName","helperClassName","tooltipClassName","markClassName","ref","isRequired","isInvalid","isLoading","showSpinner","showSteps","showValue","isFullWidth","generatedId","id","helperId","hasError","activeColor","isRange","isControlled","internalValue","setInternalValue","normalizedValue","currentValues","handleValueChange","newValues","emitVal","handleValueCommit","currentSize","getSafeConfig","sizeConfig","trackRadiusClass","radiusConfig","thumbRadiusClass","colorConfig","variantColorConfig","trackThemeStyles","fillerThemeStyles","thumbThemeStyles","renderLabel","displayText","labelColorStyle","renderedThumbs","SliderStepDots","thumbVal","idx","thumbKey","SliderThumb","SliderMarks","HelperErrorText","import_react","sizeConfig","radiusConfig","variantContainerConfig","variantPanelConfig","variantHeaderConfig","colorConfig","import_react","CollapseContext","CollapsePanelContext","useCollapseContext","context","useCollapsePanelContext","import_jsx_runtime","normalizeKeys","keys","Collapse","activeKeyProp","defaultActiveKey","onChange","accordion","size","variant","color","radius","expandIconPosition","expandIcon","destroyInactivePanel","className","style","children","ref","props","isControlled","internalActiveKeys","setInternalActiveKeys","activeKeys","handleToggle","key","nextKeys","isCurrentActive","currentArray","k","containerVariantStyle","getSafeConfig","variantContainerConfig","containerRounded","radiusConfig","containerClassNames","contextValue","CollapseContext","import_react","import_jsx_runtime","CollapseHeader","startIcon","description","extra","showArrow","children","className","ref","onClick","onKeyDown","props","size","variant","color","expandIconPosition","expandIcon","useCollapseContext","isActive","disabled","headerId","panelId","onToggle","useCollapsePanelContext","currentSize","getSafeConfig","sizeConfig","currentColor","colorConfig","currentHeaderBg","variantHeaderConfig","isArrowVisible","renderArrow","ChevronDownIcon","headerContainerClassNames","triggerButtonClassNames","e","import_jsx_runtime","CollapseContent","customDestroy","children","className","style","ref","props","size","globalDestroy","useCollapseContext","isActive","headerId","panelId","useCollapsePanelContext","currentSize","getSafeConfig","sizeConfig","import_jsx_runtime","CollapsePanel","value","label","description","startIcon","extra","disabled","showArrow","headerClassName","contentClassName","destroyInactivePanel","className","children","ref","props","generatedId","activeKeys","handleToggle","variant","color","radius","useCollapseContext","isActive","headerId","panelId","panelContextValue","itemRounded","getSafeConfig","radiusConfig","itemClassNames","variantPanelConfig","CollapsePanelContext","CollapseHeader","CollapseContent","import_react","import_jsx_runtime","Collapsible","openProp","defaultOpen","destroyInactivePanel","className","children","ref","props","contentId","isControlled","internalOpen","isOpen","import_react","import_react","TabsContext","useTabsContext","context","import_jsx_runtime","Tabs","activeKeyProp","defaultActiveKey","onChange","onClose","size","variant","color","radius","orientation","placement","fullWidth","disabled","destroyInactiveTabPane","className","children","ref","props","isControlled","internalActiveKey","setInternalActiveKey","currentActiveKey","handleActiveKeyChange","key","handleClose","contextValue","isVertical","layoutClasses","containerClasses","TabsContext","import_react","sizeConfig","radiusConfig","variantListConfig","orientation","placement","colorTabConfig","indicatorConfig","import_react","useIsomorphicLayoutEffect","useTabIndicator","activeKey","orientation","placement","variant","color","radius","listRef","indicatorStyle","setIndicatorStyle","canScrollLeft","setCanScrollLeft","canScrollRight","setCanScrollRight","checkScroll","scrollLeft","scrollWidth","clientWidth","maxScroll","updateIndicator","activeTab","prev","measureTarget","offsetLeft","offsetTop","offsetWidth","offsetHeight","rafId","observer","tabElements","el","handleResize","e","tabs","activeIndex","tab","nextIndex","isHorizontal","nextKey","prevKey","import_jsx_runtime","TabList","children","className","extra","centered","ref","props","activeKey","orientation","placement","variant","color","radius","fullWidth","useTabsContext","listRef","indicatorStyle","canScrollLeft","canScrollRight","checkScroll","handleScrollLeft","handleScrollRight","handleKeyDown","useTabIndicator","mergedRef","currentRadius","getSafeConfig","radiusConfig","variantConfigFn","variantListConfig","variantClass","currentIndicatorClass","indicatorConfig","isVertical","hasOverflow","containerClasses","indicatorClasses","ChevronLeftIcon","ChevronRightIcon","import_react","import_jsx_runtime","Tab","value","label","startIcon","endIcon","badge","itemDisabled","closable","onClose","className","children","onClick","onKeyDown","ref","props","activeKey","setActiveKey","size","variant","color","radius","orientation","fullWidth","groupDisabled","onCloseTab","useTabsContext","internalRef","mergedRef","isDisabled","isActive","handleClick","e","handleClose","currentSize","getSafeConfig","sizeConfig","currentRadius","radiusConfig","colorVariantMap","colorTabConfig","colorStyles","tabId","panelId","stateClass","isVertical","containerClasses","tabButtonClasses","CloseIcon","import_jsx_runtime","TabPanels","children","className","ref","props","import_jsx_runtime","TabPanel","value","children","className","itemDestroy","ref","props","activeKey","contextDestroy","useTabsContext","isActive","tabId","panelId","classes","import_react","CarouselContext","useCarouselContext","context","import_react","useCarousel","controlledIndex","defaultIndex","onIndexChange","loop","slidesToShow","slidesToScroll","spacing","autoPlay","interval","transitionDuration","pauseOnHover","pauseOnFocus","draggable","size","radius","internalIndex","setInternalIndex","totalSlides","setTotalSlides","isDragging","setIsDragging","dragOffset","setDragOffset","isHovered","setIsHovered","isFocused","setIsFocused","registeredSlidesRef","viewportRef","containerRef","dragStartPos","dragCurrentPos","isControlled","activeIndex","maxIndex","setIndex","newIndex","targetIndex","canScrollPrev","canScrollNext","scrollPrev","scrollNext","scrollTo","index","registerSlide","id","unregisterSlide","timer","handlePointerDown","e","clientPos","target","handlePointerMove","offset","handlePointerEnd","delta","handleKeyDown","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","sizeConfig","radiusConfig","navVariantConfig","glassPaginationWrapper","dotStyleConfig","import_jsx_runtime","Carousel","currentIndex","defaultIndex","onIndexChange","loop","slidesToShow","slidesToScroll","spacing","autoPlay","interval","transitionDuration","pauseOnHover","pauseOnFocus","draggable","size","radius","children","className","style","ref","props","carousel","useCarousel","roundedClass","getSafeConfig","radiusConfig","CarouselContext","import_jsx_runtime","CarouselContent","children","className","style","ref","props","currentIndex","slidesToShow","spacing","transitionDuration","isDragging","dragOffset","viewportRef","handlePointerDown","handlePointerMove","handlePointerUp","handlePointerCancel","useCarouselContext","spacingValue","transformStyle","trackStyle","import_react","import_jsx_runtime","CarouselSlide","children","className","style","ref","props","generatedId","slidesToShow","spacing","registerSlide","unregisterSlide","useCarouselContext","spacingValue","slideStyle","import_jsx_runtime","CarouselPrevious","variant","icon","className","disabled","onClick","ref","props","scrollPrev","canScrollPrev","size","useCarouselContext","isDisabled","currentSize","getSafeConfig","sizeConfig","variantStyles","navVariantConfig","defaultIcon","ChevronLeftIcon","previousClassNames","e","CarouselNext","scrollNext","canScrollNext","ChevronRightIcon","nextClassNames","import_jsx_runtime","CarouselPagination","type","clickable","className","ref","props","currentIndex","totalSlides","slidesToShow","loop","scrollTo","size","useCarouselContext","currentSize","getSafeConfig","sizeConfig","pageCount","glassPaginationWrapper","_","index","isActive","dotStyleConfig","import_react","import_react","DropdownContext","useDropdownContext","context","import_jsx_runtime","Dropdown","children","controlledOpen","defaultOpen","onOpenChange","trigger","placement","offset","flip","shift","size","radius","color","disabled","animated","animationDuration","closeOnSelect","uncontrolledOpen","setUncontrolledOpen","activeIndex","setActiveIndex","elementsRef","labelsRef","isControlled","isOpen","handleOpenChange","nextOpen","middleware","offsetMiddleware","flipMiddleware","shiftMiddleware","refs","floatingStyles","context","computedPlacement","click","hover","dismiss","role","listNavigation","typeahead","getReferenceProps","getFloatingProps","getItemProps","contextValue","DropdownContext","import_react","import_react","import_jsx_runtime","Slot","children","forwardedRef","disabled","className","props","childRef","mergedChildRef","childProps","DropdownTrigger","propRef","asChild","rest","refs","getReferenceProps","isOpen","useDropdownContext","mergedRef","triggerProps","DropdownTrigger_default","import_react","sizeConfig","radiusConfig","colorConfig","dangerStyles","import_jsx_runtime","DropdownMenu","propRef","children","className","style","minWidth","zIndex","DEFAULT_Z_INDEX","rest","isOpen","refs","floatingStyles","context","getFloatingProps","elementsRef","labelsRef","size","radius","animated","animationDuration","computedPlacement","useDropdownContext","mergedRef","isMounted","transitionStyles","side","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","menuClassNames","import_react","import_jsx_runtime","DropdownItem","propRef","children","onClick","disabled","danger","selected","startIcon","endIcon","shortcut","description","className","itemCloseOnSelect","rest","getItemProps","activeIndex","setIsOpen","color","size","rootCloseOnSelect","useDropdownContext","label","listItemRef","index","mergedRef","isActive","currentSize","getSafeConfig","sizeConfig","colorStyles","colorConfig","handleClick","e","stateClasses","dangerStyles","itemClasses","DropdownItem_default","import_jsx_runtime","DropdownHeader","children","className","rest","size","useDropdownContext","currentSize","getSafeConfig","sizeConfig","DropdownHeader_default","import_jsx_runtime","DropdownSeparator","className","rest","DropdownSeparator_default","import_jsx_runtime","DropdownGroup","children","label","className","rest","DropdownHeader","DropdownGroup_default","import_react","import_react","PopoverContext","usePopoverContext","context","import_jsx_runtime","Popover","children","controlledOpen","defaultOpen","onOpenChange","trigger","placement","offset","flip","shift","size","radius","color","disabled","animated","animationDuration","modal","closeOnEsc","closeOnClickOutside","uncontrolledOpen","setUncontrolledOpen","isControlled","isOpen","handleOpenChange","nextOpen","middleware","offsetMiddleware","flipMiddleware","shiftMiddleware","refs","floatingStyles","context","computedPlacement","click","hover","dismiss","role","getReferenceProps","getFloatingProps","contextValue","PopoverContext","import_react","import_react","import_jsx_runtime","Slot","children","forwardedRef","disabled","className","props","childRef","mergedChildRef","childProps","PopoverTrigger","propRef","asChild","rest","refs","getReferenceProps","isOpen","usePopoverContext","mergedRef","triggerProps","PopoverTrigger_default","import_react","sizeConfig","radiusConfig","import_jsx_runtime","PopoverContent","propRef","children","className","style","minWidth","maxWidth","zIndex","DEFAULT_Z_INDEX","rest","isOpen","refs","floatingStyles","context","getFloatingProps","size","radius","animated","animationDuration","modal","computedPlacement","usePopoverContext","mergedRef","isMounted","transitionStyles","side","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","contentClassNames","content","PopoverContent_default","import_jsx_runtime","PopoverHeader","children","className","rest","size","usePopoverContext","currentSize","getSafeConfig","sizeConfig","PopoverHeader_default","import_jsx_runtime","PopoverBody","children","className","rest","size","usePopoverContext","currentSize","getSafeConfig","sizeConfig","PopoverBody_default","import_jsx_runtime","PopoverFooter","children","className","rest","size","usePopoverContext","currentSize","getSafeConfig","sizeConfig","PopoverFooter_default","import_react","import_react","import_jsx_runtime","Slot","children","forwardedRef","className","onClick","props","childRef","mergedChildRef","childProps","e","PopoverClose","propRef","asChild","rest","setIsOpen","usePopoverContext","handleClick","PopoverClose_default","import_react","import_react","viLocale","enLocale","datePickerSizeConfig","labelColorConfig","datePickerRadiusConfig","calendarRadiusConfig","datePickerColorConfig","datePickerVariantStyles","resolveLocale","locale","viLocale","enLocale","toDate","val","formatStr","trimmed","parsedCustom","parseDate","parsed","isSameDay","d1","d2","isSameMonth","isDateBefore","t1","t2","isDateAfter","getISOWeekNumber","date","d","dayNum","yearStart","getDaysInMonth","year","month","generateCalendarGrid","firstDayOfWeek","selectedDate","minDate","maxDate","isDateDisabled","days","today","firstDayIndex","prevMonthDays","currentMonthDays","prevDaysCount","i","createCalendarDay","remainingDays","isCurrentMonth","isSelected","disabled","formatDate","loc","day","hours","minutes","seconds","dayOfWeek","pad","n","hours12","ampm","replacements","match","str","patternParts","regexStr","part","fallback","index","rawVal","parsedDate","getAdaptiveViewFormat","baseFormat","view","monthFormat","import_jsx_runtime","CalendarHeader","currentMonth","view","onViewChange","onPrevMonth","onNextMonth","onPrevYear","onNextYear","onPrevDecade","onNextDecade","size","color","locale","showMonthButtons","loc","resolveLocale","sizeStyles","getSafeConfig","datePickerSizeConfig","colorStyles","datePickerColorConfig","year","month","decadeStart","decadeEnd","handleTitleClick","handlePrev","handleNext","getTitle","DoubleChevronLeftIcon","ChevronLeftIcon","ChevronRightIcon","DoubleChevronRightIcon","import_react","import_jsx_runtime","DayGrid","days","onSelectDate","size","color","radius","locale","firstDayOfWeek","showWeekNumbers","loc","resolveLocale","sizeStyles","getSafeConfig","datePickerSizeConfig","colorStyles","datePickerColorConfig","radiusClass","datePickerRadiusConfig","gridRef","weekdays","sun","hasSelected","d","todayIndex","firstCurrentMonthIndex","fallbackIndex","focusButton","targetIndex","targetBtn","handleKeyDown","e","currentIndex","i","rowStart","rowEnd","item","dayName","dayItem","index","isRowStart","cellStyle","todayStyle","formattedDayLabel","isTabbable","React","import_react","import_jsx_runtime","MonthGrid","currentMonth","selectedDate","onSelectMonth","size","color","radius","locale","loc","resolveLocale","sizeStyles","getSafeConfig","datePickerSizeConfig","colorStyles","datePickerColorConfig","radiusClass","datePickerRadiusConfig","gridRef","currentYear","today","todayMonth","todayYear","selectedIndex","activeTabbableIndex","focusButton","targetIndex","targetBtn","handleKeyDown","e","currentIndex","monthName","idx","monthDate","isSelected","isSameMonth","isCurrentMonth","isTabbable","style","import_react","import_jsx_runtime","YearGrid","currentMonth","selectedDate","onSelectYear","size","color","radius","sizeStyles","getSafeConfig","datePickerSizeConfig","colorStyles","datePickerColorConfig","radiusClass","datePickerRadiusConfig","gridRef","currentYear","selectedYear","startDecade","todayYear","years","i","selectedIndex","todayIndex","activeTabbableIndex","focusButton","targetIndex","targetBtn","handleKeyDown","e","currentIndex","yr","idx","isSelected","isCurrentYear","isTabbable","style","import_jsx_runtime","Calendar","selectedDate","onChange","view","onViewChange","minDate","maxDate","isDateDisabled","locale","firstDayOfWeek","showWeekNumbers","showViewTabs","viewTabs","size","color","radius","className","sizeStyles","getSafeConfig","datePickerSizeConfig","radiusClass","calendarRadiusConfig","gridMode","setGridMode","prevView","setPrevView","currentMonth","setCurrentMonth","base","loc","resolveLocale","tabItems","tabLabels","v","handleTabChange","key","nextView","handlePrevMonth","prev","handleNextMonth","next","handlePrevYear","handleNextYear","handlePrevDecade","handleNextDecade","handleSelectMonth","monthIndex","updated","handleSelectYear","yr","parsedMin","toDate","parsedMax","daysGrid","generateCalendarGrid","Tabs","TabList","item","Tab","CalendarHeader","DayGrid","date","MonthGrid","YearGrid","import_jsx_runtime","DatePicker","ref","controlledValue","defaultValue","onChange","format","customDisplayFormat","defaultView","locale","firstDayOfWeek","minDate","maxDate","isDateDisabled","size","variant","color","radius","label","labelPlacement","placeholder","helperText","errorMessage","name","id","autoComplete","viewTabs","controlledView","onViewChange","onClear","placement","disabled","readOnly","config","className","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","popoverClassName","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","showWeekNumbers","showViewTabs","closeOnSelect","generatedId","inputId","errorHelperId","popoverId","isControlledView","internalView","setInternalView","activeView","baseDisplayFormat","currentDisplayFormat","getAdaptiveViewFormat","isControlled","internalDate","setInternalDate","toDate","selectedDate","formattedValue","formatDate","isOpen","setIsOpen","setReference","setFloating","floatingStyles","context","offsetMiddleware","flipMiddleware","shiftMiddleware","dismiss","role","getReferenceProps","getFloatingProps","isMounted","transitionStyles","side","hasError","activeColor","sizeStyles","getSafeConfig","datePickerSizeConfig","radiusClass","datePickerRadiusConfig","variantClass","datePickerVariantStyles","hasValue","handleViewChange","mode","handleDateSelect","date","formattedOutput","handleKeyDown","e","handleClear","defaultPlaceholder","isFloating","isHorizontal","renderLabel","labelColorStyle","labelColorConfig","renderIconWrapper","iconNode","fieldWrapperClasses","containerClasses","inputClasses","prev","Spinner","CloseIcon","ChevronDownIcon","DEFAULT_Z_INDEX","Calendar","HelperErrorText","import_react","import_react","dateRangePickerSizeConfig","dateRangePickerRadiusConfig","dateRangeCalendarRadiusConfig","dateRangePickerColorConfig","dateRangePickerVariantStyles","labelColorConfig","import_jsx_runtime","DateRangeHeader","month1","month2","view","onViewChange","onPrevMonth","onNextMonth","onPrevYear","onNextYear","onPrevDecade","onNextDecade","size","color","locale","loc","resolveLocale","sizeStyles","getSafeConfig","dateRangePickerSizeConfig","colorStyles","dateRangePickerColorConfig","monthName1","year1","startDecade1","endDecade1","title1","monthName2","year2","startDecade2","endDecade2","title2","handleTitleClick","handlePrev","handleNext","DoubleChevronLeftIcon","ChevronLeftIcon","ChevronRightIcon","DoubleChevronRightIcon","import_react","import_jsx_runtime","DateRangeDayGrid","days","onSelectDate","onHoverDate","size","color","radius","locale","firstDayOfWeek","showWeekNumbers","loc","resolveLocale","sizeStyles","getSafeConfig","dateRangePickerSizeConfig","colorStyles","dateRangePickerColorConfig","radiusClass","dateRangePickerRadiusConfig","gridRef","weekdays","sun","hasSelected","todayIndex","firstCurrentMonthIndex","fallbackIndex","focusButton","targetIndex","targetBtn","handleKeyDown","e","currentIndex","i","rowStart","rowEnd","item","dayName","dayItem","index","isRowStart","cellStyle","rangeWrapperStyle","todayStyle","formattedDayLabel","isTabbable","React","import_react","import_jsx_runtime","DateRangeMonthGrid","currentMonth","onSelectMonth","size","color","radius","locale","rangeStart","rangeEnd","hoveredDate","onHoverMonth","loc","resolveLocale","sizeStyles","getSafeConfig","dateRangePickerSizeConfig","colorStyles","dateRangePickerColorConfig","radiusClass","dateRangePickerRadiusConfig","gridRef","currentYear","today","todayMonth","todayYear","selectedIndex","activeTabbableIndex","focusButton","targetIndex","targetBtn","handleKeyDown","e","currentIndex","monthName","idx","monthDate","mTime","sTime","eTime","hTime","isRangeStart","isRangeEnd","isInRange","isHoveredRange","isCurrentMonth","isTabbable","style","import_react","import_jsx_runtime","DateRangeYearGrid","currentMonth","onSelectYear","size","color","radius","rangeStart","rangeEnd","hoveredDate","onHoverYear","sizeStyles","getSafeConfig","dateRangePickerSizeConfig","colorStyles","dateRangePickerColorConfig","radiusClass","dateRangePickerRadiusConfig","gridRef","currentYear","startDecade","todayYear","years","i","selectedYear","selectedIndex","todayIndex","activeTabbableIndex","focusButton","targetIndex","targetBtn","handleKeyDown","e","currentIndex","yr","idx","sYr","eYr","hYr","isRangeStart","isRangeEnd","isInRange","isHoveredRange","isCurrentYear","isTabbable","style","isDateInRange","date","start","end","t","tStart","tEnd","min","max","getDaysInMonth","year","month","createRangeCalendarDay","isCurrentMonth","today","rangeStart","rangeEnd","hoveredDate","minDate","maxDate","isDateDisabled","isRangeStart","isSameDay","isRangeEnd","isInRange","isHoveredRange","disabled","isDateBefore","isDateAfter","getISOWeekNumber","generateRangeCalendarGrid","firstDayOfWeek","days","firstDayIndex","prevMonthDays","currentMonthDays","prevDaysCount","i","d","remainingDays","import_jsx_runtime","DateRangeCalendar","value","onChange","view","onViewChange","minDate","maxDate","isDateDisabled","locale","firstDayOfWeek","showWeekNumbers","showViewTabs","viewTabs","size","color","radius","className","sizeStyles","getSafeConfig","dateRangePickerSizeConfig","radiusClass","dateRangeCalendarRadiusConfig","gridMode","setGridMode","prevView","setPrevView","parsedRangeStart","parsedRangeEnd","currentMonth","setCurrentMonth","base","loc","resolveLocale","tabItems","tabLabels","v","handleTabChange","key","nextView","setRangeSelectionStart","handlePrevMonth","prev","handleNextMonth","next","handlePrevYear","handleNextYear","handlePrevDecade","handleNextDecade","rangeSelectionStart","hoveredDate","setHoveredDate","handleSelectDate","date","start","end","handleSelectMonthForYear","targetYear","monthIndex","selectedDateObj","handleSelectYear","yr","parsedMin","toDate","parsedMax","month1","month2","currentRangeStart","currentRangeEnd","daysMonth1","generateRangeCalendarGrid","daysMonth2","Tabs","TabList","item","Tab","DateRangeHeader","DateRangeDayGrid","DateRangeMonthGrid","mIdx","DateRangeYearGrid","import_jsx_runtime","DateRangePicker","ref","controlledValue","defaultValue","onChange","separator","format","customDisplayFormat","defaultView","locale","firstDayOfWeek","minDate","maxDate","isDateDisabled","size","variant","color","radius","label","labelPlacement","placeholder","helperText","errorMessage","name","id","autoComplete","viewTabs","controlledView","onViewChange","onClear","placement","disabled","readOnly","config","className","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","popoverClassName","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","showWeekNumbers","showViewTabs","closeOnSelect","generatedId","inputId","errorHelperId","popoverId","isControlledView","internalView","setInternalView","activeView","baseDisplayFormat","currentDisplayFormat","getAdaptiveViewFormat","isControlled","internalRange","setInternalRange","raw","toDate","selectedRange","formattedValue","formatDate","isOpen","setIsOpen","setReference","setFloating","floatingStyles","context","offsetMiddleware","flipMiddleware","shiftMiddleware","dismiss","role","getReferenceProps","getFloatingProps","isMounted","transitionStyles","side","hasError","activeColor","sizeStyles","getSafeConfig","dateRangePickerSizeConfig","radiusClass","dateRangePickerRadiusConfig","activeVariantConfig","dateRangePickerVariantStyles","variantClass","hasValue","handleViewChange","mode","handleRangeSelect","range","start","end","outputFormatted","handleKeyDown","e","handleClear","defaultPlaceholder","isFloating","isHorizontal","renderLabel","labelColorStyle","labelColorConfig","renderIconWrapper","iconNode","fieldWrapperClasses","containerClasses","inputClasses","prev","Spinner","CloseIcon","ChevronDownIcon","DEFAULT_Z_INDEX","DateRangeCalendar","HelperErrorText","import_react","import_react","timePickerSizeConfig","timePickerRadiusConfig","timeViewRadiusConfig","timeItemRadiusConfig","timePickerColorConfig","labelColorConfig","timePickerVariantStyles","padZero","val","getDefaultFormat","use12Hours","showSeconds","parseTimeToDate","str","d","timeRegex","match","hours","minutes","seconds","period","now","formatTime","date","formatStr","fullHours","hours12","toTimeObject","createDateWithTime","isSameTime","d1","d2","checkSeconds","isTimeBefore","time1","time2","t1","t2","isTimeAfter","checkIsDisabled","type","selectedHour","selectedMinute","minTime","maxTime","disabledHours","disabledMinutes","disabledSeconds","import_react","import_jsx_runtime","TimeColumn","items","selectedValue","onSelect","ariaLabel","size","color","radius","className","itemClassName","selectedItemClassName","containerRef","selectedRef","sizeStyles","getSafeConfig","timePickerSizeConfig","colorStyles","timePickerColorConfig","itemRadiusClass","timeItemRadiusConfig","firstEnabledIndex","item","hasSelection","container","target","topPos","focusAndSelect","targetIndex","targetItem","handleKeyDown","e","currentIndex","i","firstIdx","index","isSelected","isDisabled","isTabbable","import_jsx_runtime","TimeView","value","onChange","ariaLabel","use12Hours","showSeconds","hourStep","minuteStep","secondStep","customMinTime","customMaxTime","disabledHours","disabledMinutes","disabledSeconds","size","color","radius","className","minTime","parseTimeToDate","maxTime","defaultFormat","getDefaultFormat","radiusClass","getSafeConfig","timeViewRadiusConfig","sizeStyles","timePickerSizeConfig","currentHour24","currentHour12","currentMinute","currentSecond","currentPeriod","hourItems","items","h","corresponding24","disabled","checkIsDisabled","padZero","minuteItems","m","secondItems","s","periodItems","handleHourSelect","val","hourNum","newDate","createDateWithTime","handleMinuteSelect","minuteNum","handleSecondSelect","secondNum","handlePeriodSelect","p","newHour","placeholderHeader","formatTime","TimeColumn","import_jsx_runtime","TimePicker","ref","controlledValue","defaultValue","onChange","format","customDisplayFormat","use12Hours","showSeconds","hourStep","minuteStep","secondStep","minTime","maxTime","disabledHours","disabledMinutes","disabledSeconds","size","variant","color","radius","label","labelPlacement","placeholder","helperText","errorMessage","name","id","autoComplete","onClear","placement","disabled","readOnly","config","className","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","popoverClassName","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","closeOnSelect","generatedId","inputId","errorHelperId","popoverId","defaultFmt","getDefaultFormat","resolvedFormat","baseDisplayFormat","isControlled","internalDate","setInternalDate","parseTimeToDate","selectedTime","formattedValue","formatTime","isOpen","setIsOpen","setReference","setFloating","floatingStyles","context","offsetMiddleware","flipMiddleware","shiftMiddleware","dismiss","role","getReferenceProps","getFloatingProps","isMounted","transitionStyles","side","hasError","activeColor","sizeStyles","getSafeConfig","timePickerSizeConfig","radiusClass","timePickerRadiusConfig","variantClass","timePickerVariantStyles","hasValue","handleTimeSelect","time","formattedOutput","handleKeyDown","e","handleClear","defaultPlaceholder","isFloating","isHorizontal","renderLabel","labelColorStyle","labelColorConfig","renderIconWrapper","iconNode","fieldWrapperClasses","containerClasses","inputClasses","prev","Spinner","CloseIcon","ChevronDownIcon","DEFAULT_Z_INDEX","TimeView","HelperErrorText","import_react","timeRangePickerSizeConfig","timePickerSizeConfig","timeRangePickerRadiusConfig","timePickerRadiusConfig","timeRangeViewRadiusConfig","timeViewRadiusConfig","timeRangePickerVariantStyles","timePickerVariantStyles","labelColorConfig","import_jsx_runtime","TimeRangePicker","ref","controlledValue","defaultValue","onChange","customFormat","customDisplayFormat","separator","startLabel","endLabel","use12Hours","showSeconds","hourStep","minuteStep","secondStep","minTime","maxTime","disabledHours","disabledMinutes","disabledSeconds","size","variant","color","radius","label","labelPlacement","placeholder","placeholders","helperText","errorMessage","name","id","autoComplete","disabled","readOnly","config","onClear","placement","className","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","popoverClassName","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","closeOnSelect","generatedId","inputId","errorHelperId","popoverId","defaultFmt","getDefaultFormat","resolvedFormat","resolvedDisplayFormat","isControlled","internalRange","setInternalRange","raw","parseTimeToDate","selectedRange","startText","formatTime","endText","formattedValue","isOpen","setIsOpen","setReference","setFloating","floatingStyles","context","offsetMiddleware","flipMiddleware","shiftMiddleware","dismiss","role","getReferenceProps","getFloatingProps","isMounted","transitionStyles","side","hasError","activeColor","sizeStyles","getSafeConfig","timeRangePickerSizeConfig","radiusClass","timeRangePickerRadiusConfig","menuRadiusClass","timeRangeViewRadiusConfig","variantClass","timeRangePickerVariantStyles","hasValue","handleStartTimeSelect","date","newRange","fStart","fEnd","handleEndTimeSelect","handleKeyDown","e","handleClear","defaultPlaceholder","isFloating","isHorizontal","renderLabel","labelColorStyle","labelColorConfig","renderIconWrapper","iconNode","fieldWrapperClasses","containerClasses","inputClasses","prev","Spinner","CloseIcon","ChevronDownIcon","DEFAULT_Z_INDEX","TimeView","HelperErrorText","isTimeInRange","time","start","end","t","s","e","import_react","getDefaultDateTimeFormat","use12Hours","showSeconds","combineDateTime","date","time","baseDate","toDateTime","val","formatStr","parsedWithFormat","parseDateTime","parsed","anyObj","formatDateTime","locale","formatDate","str","trimmed","year","month","day","hours","minutes","seconds","is12Hour","isPM","patternParts","d","regexStr","part","match","fallback","index","rawVal","result","dateTimePickerRadiusConfig","dateTimeViewRadiusConfig","dateTimePickerSizeConfig","labelColorConfig","dateTimePickerVariantStyles","import_jsx_runtime","DateTimePicker","ref","controlledValue","defaultValue","onChange","customFormat","customDisplayFormat","layout","locale","defaultView","firstDayOfWeek","minDate","maxDate","isDateDisabled","viewTabs","use12Hours","showSeconds","hourStep","minuteStep","secondStep","minTime","maxTime","disabledHours","disabledMinutes","disabledSeconds","size","variant","color","radius","label","labelPlacement","placeholder","helperText","errorMessage","name","id","autoComplete","disabled","readOnly","config","onClear","placement","className","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","popoverClassName","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","closeOnSelect","showWeekNumbers","showViewTabs","generatedId","inputId","errorHelperId","popoverId","defaultFmt","getDefaultDateTimeFormat","resolvedFormat","baseDisplayFormat","isControlled","internalDate","setInternalDate","toDateTime","selectedDate","formattedValue","formatDateTime","activeView","setActiveView","isOpen","setIsOpen","setReference","setFloating","floatingStyles","context","offsetMiddleware","flipMiddleware","shiftMiddleware","dismiss","role","getReferenceProps","getFloatingProps","isMounted","transitionStyles","side","hasError","activeColor","sizeStyles","getSafeConfig","dateTimePickerSizeConfig","radiusClass","dateTimePickerRadiusConfig","menuRadiusClass","dateTimeViewRadiusConfig","variantClass","dateTimePickerVariantStyles","hasValue","handleCalendarChange","newDate","combined","combineDateTime","formattedOutput","handleTimeChange","newTime","handleKeyDown","e","handleClear","defaultPlaceholder","isFloating","isHorizontal","renderLabel","labelColorStyle","labelColorConfig","renderIconWrapper","iconNode","fieldWrapperClasses","containerClasses","inputClasses","prev","Spinner","CloseIcon","ChevronDownIcon","DEFAULT_Z_INDEX","Calendar","TimeView","HelperErrorText","import_react","dateTimeRangePickerSizeConfig","dateTimeRangePickerRadiusConfig","dateTimePickerRadiusConfig","dateTimeRangeViewRadiusConfig","dateTimeViewRadiusConfig","dateTimeRangePickerVariantStyles","dateTimePickerVariantStyles","labelColorConfig","dateTimeRangePickerButtonColorConfig","import_jsx_runtime","DateTimeRangePicker","ref","controlledValue","defaultValue","onChange","customFormat","customDisplayFormat","separator","startLabel","endLabel","layout","locale","defaultView","firstDayOfWeek","minDate","maxDate","isDateDisabled","viewTabs","use12Hours","showSeconds","hourStep","minuteStep","secondStep","minTime","maxTime","disabledHours","disabledMinutes","disabledSeconds","size","variant","color","radius","label","labelPlacement","placeholder","placeholders","helperText","errorMessage","name","id","autoComplete","disabled","readOnly","config","onClear","placement","className","wrapperClassName","inputWrapperClassName","labelClassName","helperClassName","popoverClassName","isRequired","isInvalid","isLoading","showSpinner","isClearable","isFullWidth","closeOnSelect","showWeekNumbers","showViewTabs","generatedId","inputId","errorHelperId","popoverId","defaultFmt","getDefaultDateTimeFormat","resolvedFormat","baseDisplayFormat","isControlled","internalRange","setInternalRange","raw","toDateTime","selectedRange","activeStep","setActiveStep","activeView","setActiveView","isOpen","setIsOpen","startText","formatDateTime","endText","formattedValue","setReference","setFloating","floatingStyles","context","offsetMiddleware","flipMiddleware","shiftMiddleware","dismiss","role","getReferenceProps","getFloatingProps","isMounted","transitionStyles","side","hasError","activeColor","sizeStyles","getSafeConfig","dateTimeRangePickerSizeConfig","radiusClass","dateTimeRangePickerRadiusConfig","menuRadiusClass","dateTimeRangeViewRadiusConfig","buttonColorStyle","dateTimeRangePickerButtonColorConfig","variantClass","dateTimeRangePickerVariantStyles","hasValue","emitChange","newRange","fStart","fEnd","handleCalendarChange","newDate","combined","combineDateTime","nextEnd","handleTimeChange","newTime","handleKeyDown","e","handleClear","defaultPlaceholder","isFloating","isHorizontal","renderLabel","labelColorStyle","labelColorConfig","renderIconWrapper","iconNode","fieldWrapperClasses","containerClasses","inputClasses","currentStepDate","prev","Spinner","CloseIcon","ChevronDownIcon","DEFAULT_Z_INDEX","Calendar","TimeView","HelperErrorText","import_react","import_image","emptySizeConfig","emptyLayoutConfig","import_jsx_runtime","EmptyIllustration","preset","props","EmptySearchIcon_default","EmptyErrorIcon_default","EmptyFolderIcon_default","EmptySimpleIcon_default","EmptyDefaultIcon_default","import_jsx_runtime","PRESETS","isPresetImage","val","isUrlString","Empty","size","layout","image","imageSize","imageClassName","imageAlt","title","titleClassName","description","descriptionClassName","actions","actionsClassName","children","className","role","ref","props","currentSize","emptySizeConfig","currentLayout","emptyLayoutConfig","imageInlineStyle","renderImageContent","EmptyIllustration","dimension","Image","React","imageWrapperClasses","containerClasses","contentClasses","titleClasses","descriptionClasses","actionsClasses","import_react","import_match_sorter_utils","sizeConfig","radiusConfig","badgeRadiusMap","variantColorConfig","optionSelectedColorConfig","optionActiveColorConfig","labelPlacementConfig","import_react","import_jsx_runtime","SelectTrigger","id","selectedOptions","isOpen","size","variant","color","radius","placeholder","disabled","readOnly","isInvalid","multiple","maxTagCount","searchable","searchPlacement","searchValue","onSearchChange","onRemoveTag","onClear","clearable","loadingProp","isLoadingProp","startContent","endContent","renderValue","triggerRef","getReferenceProps","onKeyDown","className","loading","inputRef","currentSize","sizeConfig","roundedClass","radiusConfig","badgeRadius","badgeRadiusMap","activeColor","variantStyle","variantColorConfig","isTriggerSearchable","hasSelection","showClear","visibleTags","hiddenTagCount","handleContainerClick","renderContent","opt","Badge","e","singleOption","statusStyles","Spinner","CloseIcon","ChevronDownIcon","SelectTrigger_default","import_react","import_jsx_runtime","SelectOption","option","isSelected","isActive","size","color","radius","disabled","renderOption","onClick","onMouseEnter","ref","currentSize","sizeConfig","roundedClass","isDisabled","selectedClasses","optionSelectedColorConfig","activeClasses","optionActiveColorConfig","CheckIcon","SelectOption_default","import_jsx_runtime","SelectMenuFilter","filters","values","onChange","onReset","layout","gridCols","showReset","resetText","color","radius","renderField","field","currentValue","val","Input","e","DatePicker","d","DateRangePicker","range","CheckboxGroup","opt","Checkbox","colSpanClass","Button","SelectMenuFilter_default","import_jsx_runtime","DEFAULT_MENU_FILTER_VALUES","SelectMenu","isOpen","options","selectedValues","activeIndex","size","color","radius","loading","portal","maxMenuHeight","emptyText","emptyProps","menuHeader","menuFooter","menuFilters","menuFilterValues","menuFilterLayout","menuFilterGridCols","showResetFilters","resetFiltersText","onMenuFilterChange","onResetFilters","renderOption","onSelectOption","onOptionMouseEnter","floatingStyles","floatingRef","getFloatingProps","listElementsRef","className","menuRadiusClass","menuContent","DEFAULT_Z_INDEX","SelectMenuFilter_default","Spinner","Empty","selectedValuesSet","option","index","isSelected","SelectOption_default","node","SelectMenu_default","import_react","useDebouncedCallback","callback","delay","callbackRef","timerRef","cancel","args","import_jsx_runtime","DEFAULT_OPTIONS","isMultiSelect","props","Select","ref","options","size","variant","color","radius","id","label","labelPlacement","placeholder","helperText","errorMessage","isInvalid","isDisabled","isReadOnly","readOnly","isRequired","name","searchable","searchMode","searchPlacement","searchPlaceholder","controlledSearchValue","onSearchChange","menuFilters","controlledFilterValues","menuFilterLayout","menuFilterGridCols","showResetFilters","resetFiltersText","onMenuFilterChange","menuHeader","menuFooter","onSearch","debounceMs","filterFn","loadingProp","isLoadingProp","emptyText","emptyProps","clearable","portal","placement","maxMenuHeight","startContent","endContent","renderValue","renderOption","className","triggerClassName","menuClassName","isMultiple","loading","singleProps","multiProps","uncontrolledSingle","setUncontrolledSingle","uncontrolledMulti","setUncontrolledMulti","isSingleControlled","isMultiControlled","controlledMultiValue","currentMultiValue","controlledSingleValue","currentSingleValue","selectedCacheRef","opt","selectedOptions","val","o","isOpen","setIsOpen","activeIndex","setActiveIndex","uncontrolledSearch","setUncontrolledSearch","isSearchControlled","searchInput","debounced","useDebouncedCallback","query","filters","handleSearchChange","currentFilters","internalFilters","setInternalFilters","initial","f","handleFilterChange","nextFilters","handleResetFilters","resetValues","filteredOptions","list","keyword","ranked","accessors","item","info","a","b","r","elementsRef","effectiveReadOnly","isInteractive","refs","floatingStyles","context","nextOpen","offsetMiddleware","flipMiddleware","shiftMiddleware","click","dismiss","role","listNavigation","getReferenceProps","getFloatingProps","handleSelectOption","option","nextValues","v","nextSelectedItems","handleRemoveTag","handleClear","e","handleTriggerKeyDown","inputVal","lastTag","targetOption","placementStyle","labelPlacementConfig","generatedId","triggerId","SelectTrigger_default","SelectMenu_default","idx","Select_default","import_react","useDebounce","value","delay","debouncedValue","setDebouncedValue","timer","import_react","uploadImageRadiusConfig","uploadImageDefaultRadiusBySize","uploadImageSizeConfig","uploadImageVariantColorConfig","generateId","formatBytes","bytes","decimals","k","dm","sizes","i","normalizeInitialValues","raw","item","validateFile","file","options","acceptedTypes","t","fileType","fileName","type","baseType","createFileItem","url","revokeFileItem","import_react","IMAGE_EXTENSIONS","PDF_EXTENSIONS","VIDEO_EXTENSIONS","AUDIO_EXTENSIONS","DOCUMENT_EXTENSIONS","getFileName","filenameOrSrc","cleanPath","fullName","lastDotIndex","getFileExtension","dotIndex","getFileType","ext","IMAGE_EXTENSIONS","PDF_EXTENSIONS","VIDEO_EXTENSIONS","AUDIO_EXTENSIONS","DOCUMENT_EXTENSIONS","normalizePreviewFile","input","downloadFile","src","filename","link","fallbackFullName","import_react","FileContext","useFileContext","import_react","import_react_easy_crop","import_jsx_runtime","ImagePreviewToolbar","zoom","onZoomIn","onZoomOut","onRotateCw","onRotateCcw","onFlipHorizontal","onReset","currentImage","tools","className","zoomIn","zoomOut","reset","rotate","flip","download","zoomPercent","handleDownload","downloadFile","buttonBaseClass","ZoomInIcon","ZoomOutIcon","RotateCcwIcon","RotateCwIcon","FlipHorizontalIcon","DownloadIcon","import_jsx_runtime","ImagePreview","src","name","minZoom","maxZoom","showToolbar","toolbarProps","children","crop","setCrop","zoom","setZoom","rotation","setRotation","isFlipped","setIsFlipped","handleZoomIn","prev","handleZoomOut","handleRotateCw","handleRotateCcw","handleFlipHorizontal","handleReset","currentImage","Cropper","ImagePreviewToolbar","import_jsx_runtime","FilePreview","onDownload","imageProps","className","fileContext","useFileContext","file","headerTitle","previewUrl","setPreviewUrl","normalized","normalizePreviewFile","url","displayName","handleDownload","downloadFile","ImagePreview","DownloadIcon","import_react","MODAL_EXIT_ANIMATION_DURATION","sizeConfig","radiusConfig","import_react","ModalContext","useModalContext","import_jsx_runtime","Modal","size","radius","className","children","ref","props","modalContext","useModalContext","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","containerClasses","import_react","import_jsx_runtime","ModalContainer","open","id","size","isLoading","closeOnOverlayClick","closeOnEsc","lockScroll","overlayClassName","className","children","onClose","props","dialogRef","isExiting","setIsExiting","exitTimerRef","handleTriggerClose","MODAL_EXIT_ANIMATION_DURATION","contextValue","dialog","originalOverflow","handleKeyDown","e","handleOverlayClick","backdropAnimation","dialogAnimation","ModalContext","import_jsx_runtime","ModalHeader","size","title","description","titleClassName","descriptionClassName","showCloseButton","onClose","closeButtonClassName","className","children","props","modalContext","useModalContext","currentSize","getSafeConfig","sizeConfig","isLoading","handleClose","hasCloseHandler","CloseIcon","import_jsx_runtime","ModalBody","size","className","children","props","modalContext","useModalContext","currentSize","getSafeConfig","sizeConfig","import_jsx_runtime","FileContainer","open","onClose","file","title","description","size","radius","showCloseButton","closeOnOverlayClick","closeOnEsc","lockScroll","className","overlayClassName","children","normalized","normalizePreviewFile","headerTitle","contextValue","ModalContainer","Modal","ModalHeader","ModalBody","FileContext","FilePreview","import_jsx_runtime","UploadImageDropzone","size","color","variant","radius","shape","disabled","readOnly","isLoading","isDragging","isInvalid","dropzoneTitle","dropzoneDescription","icon","onTriggerUpload","className","describedById","currentSize","uploadImageSizeConfig","effectiveRadius","uploadImageRadiusConfig","uploadImageDefaultRadiusBySize","effectiveColor","colorStyles","uploadImageVariantColorConfig","e","Spinner","UploadIcon","import_react","import_image","variantConfig","radiusConfig","import_jsx_runtime","Skeleton","variant","shape","radius","width","height","lines","gap","className","style","props","animationClass","variantConfig","roundedClass","radiusConfig","toStyle","val","baseStyle","itemClass","_","i","isLast","import_jsx_runtime","LoadingImage","src","alt","width","height","fill","skeletonVariant","radius","className","wrapperClassName","style","wrapperStyle","onLoad","onError","imageProps","isLoaded","setIsLoaded","hasError","setHasError","roundedClass","radiusConfig","handleLoad","e","handleError","computedWrapperStyle","Skeleton","Image","ImageIcon","import_jsx_runtime","UploadImageList","items","size","radius","disabled","readOnly","maxCount","onRemove","onPreview","onTriggerUpload","renderItem","showAddButton","className","currentSize","uploadImageSizeConfig","activeRadius","uploadImageRadiusConfig","canAddMore","item","index","isUploading","isError","e","LoadingImage","Spinner","EyeIcon_default","TrashIcon","PlusIcon","import_jsx_runtime","handleDragOver","UploadImage","value","defaultValue","onChange","onRemove","onPreview","multiple","maxCount","maxSize","accept","beforeUpload","viewMode","shape","size","color","variant","radius","label","helperText","errorMessage","isInvalidProp","disabled","readOnly","isLoading","dropzoneTitle","dropzoneDescription","icon","buttonText","renderItem","className","dropzoneClassName","previewClassName","ariaLabel","generatedId","inputId","helperId","errorId","fileInputRef","internalItems","setInternalItems","normalizeInitialValues","isDragging","setIsDragging","dragCounter","validationError","setValidationError","previewItem","setPreviewItem","srAnnouncement","setSrAnnouncement","currentSize","uploadImageSizeConfig","isInvalid","activeErrorMessage","effectiveMaxCount","updateItems","newItems","handleTriggerUpload","processFiles","files","fileArray","currentCount","allowedFiles","remainingSlots","err","firstFile","processSingleFile","file","validation","validateFile","result","errMsg","createFileItem","newValidItems","item","finalItems","handleFileInputChange","e","handleDragEnter","handleDragLeave","handleDrop","handleRemove","index","_","i","handleOpenPreview","UploadImageDropzone","UploadImageList","Button","UploadIcon","FileContainer","import_react","uploadAvatarRadiusConfig","uploadAvatarSizeConfig","uploadAvatarVariantColorConfig","normalizeInitialValue","value","getFileName","getFileType","validateFile","file","options","maxSize","accept","acceptedTypes","t","fileType","fileExt","type","category","import_react","import_react_easy_crop","createImage","url","resolve","reject","image","error","getRadianAngle","degreeValue","rotateSize","width","height","rotation","rotRad","getCroppedImage","imageSrc","pixelCrop","isFlipped","fileName","fileType","canvas","ctx","bBoxWidth","bBoxHeight","croppedCanvas","croppedCtx","blob","file","import_jsx_runtime","ModalFooter","size","className","children","props","modalContext","useModalContext","currentSize","getSafeConfig","sizeConfig","import_react","import_jsx_runtime","ModalClose","children","asChild","onClick","props","modalContext","useModalContext","isLoading","handleClick","e","child","import_jsx_runtime","UploadAvatarCropContent","initialImageSrc","initialFileName","initialFileType","aspectRatio","cropShape","showGrid","minZoom","maxZoom","onApply","onCancel","fileInputRef","imageSrc","setImageSrc","fileName","setFileName","fileType","setFileType","crop","setCrop","zoom","setZoom","rotation","setRotation","isFlipped","setIsFlipped","croppedAreaPixels","setCroppedAreaPixels","isProcessing","setIsProcessing","handleZoomIn","prev","handleZoomOut","handleRotateCw","handleRotateCcw","handleFlipHorizontal","handleReset","handleChangeImageClick","handleNewFileSelected","e","newFile","newUrl","handleCropComplete","_croppedArea","handleSave","croppedFile","getCroppedImage","err","handleClose","toolbarBtnClass","Cropper","UploadIcon","ZoomOutIcon","ZoomInIcon","RotateCcwIcon","RotateCwIcon","FlipHorizontalIcon","ResetIcon","CloseIcon","Spinner","CheckIcon","UploadAvatarCropModal","open","modalTitle","onClose","restProps","ModalContainer","Modal","ModalHeader","ModalBody","import_jsx_runtime","UploadAvatar","size","variant","color","shape","radius","value","defaultValue","onChange","onRemove","onPreview","onClear","maxSize","accept","crop","label","labelPlacement","isRequired","helperText","errorMessage","isInvalid","isLoading","disabled","readOnly","isClearable","icon","name","id","isFullWidth","className","wrapperClassName","avatarClassName","avatarWrapperClassName","labelClassName","helperClassName","ariaLabel","ref","generatedId","inputId","helperId","internalInputRef","isControlled","internalItem","setInternalItem","normalizeInitialValue","currentItem","cropData","setCropData","isPreviewOpen","setIsPreviewOpen","previewUrl","fileName","getFileName","validationError","setValidationError","isDragging","setIsDragging","dragCounter","srAnnouncement","setSrAnnouncement","activeError","hasError","activeColor","currentSize","uploadAvatarSizeConfig","roundedClass","uploadAvatarRadiusConfig","variantStyles","uploadAvatarVariantColorConfig","isUploading","updateItem","newItem","handleTriggerUpload","fileInput","isCropActive","cropOptions","handleOpenCropModal","imageSrc","file","processFile","validation","validateFile","err","tempUrl","handleFileInputChange","e","handleDragEnter","handleDragLeave","handleDrop","handleRemove","removedItem","handlePreview","handleRecrop","handleKeyDown","renderLabel","inputContainerBase","disabledStyles","avatarBoxClasses","LoadingImage","UploadIcon","Spinner","EyeIcon_default","CropIcon","TrashIcon","HelperErrorText","UploadAvatarCropModal","croppedFile","FileContainer","CONFIRM_EXIT_ANIMATION_DURATION","sizeConfig","radiusConfig","iconBadgeColorConfig","defaultIcons","AlertTriangleIcon","AlertCircleIcon","CheckCircleIcon","InfoCircleIcon","import_react","ConfirmContext","useConfirmContext","import_jsx_runtime","Confirm","size","radius","className","children","ref","props","confirmContext","useConfirmContext","currentSize","getSafeConfig","sizeConfig","roundedClass","radiusConfig","containerClasses","import_react","import_jsx_runtime","ConfirmContainer","open","size","color","isLoading","closeOnOverlayClick","closeOnEsc","lockScroll","overlayClassName","className","children","onClose","props","dialogRef","isExiting","setIsExiting","exitTimerRef","handleTriggerClose","CONFIRM_EXIT_ANIMATION_DURATION","contextValue","dialog","originalOverflow","handleKeyDown","e","handleOverlayClick","backdropAnimation","dialogAnimation","ConfirmContext","import_jsx_runtime","ConfirmHeader","size","color","icon","title","iconClassName","titleClassName","showCloseButton","onClose","closeButtonClassName","className","children","props","confirmContext","useConfirmContext","currentSize","getSafeConfig","sizeConfig","badgeStyle","iconBadgeColorConfig","isLoading","handleClose","hasCloseHandler","renderIcon","IconComponent","defaultIcons","CloseIcon","import_jsx_runtime","ConfirmBody","size","description","descriptionClassName","className","children","props","confirmContext","useConfirmContext","currentSize","getSafeConfig","sizeConfig","import_jsx_runtime","ConfirmFooter","size","confirmText","cancelText","confirmVariant","cancelVariant","confirmColor","cancelColor","onConfirm","onCancel","onClose","confirmButtonProps","cancelButtonProps","className","children","props","confirmContext","useConfirmContext","currentSize","getSafeConfig","sizeConfig","currentConfirmColor","triggerClose","handleConfirm","result","handleCancel","Button","import_react","import_jsx_runtime","ConfirmClose","children","asChild","onClick","props","confirmContext","useConfirmContext","isLoading","handleClick","e","child"]}