@spark-ui/components 11.5.1 → 11.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/file-upload/index.ts","../../src/file-upload/FileUpload.tsx","../../src/file-upload/utils.ts","../../src/file-upload/FileUploadAcceptedFile.tsx","../../src/icon/Icon.tsx","../../src/slot/Slot.tsx","../../src/visually-hidden/VisuallyHidden.tsx","../../src/icon/Icon.styles.tsx","../../src/progress/Progress.tsx","../../src/progress/ProgressBar.styles.ts","../../src/progress/ProgressContext.tsx","../../src/progress/ProgressIndicator.tsx","../../src/progress/ProgressIndicator.styles.ts","../../src/progress/ProgressBar.tsx","../../src/progress/ProgressLabel.tsx","../../src/progress/index.ts","../../src/file-upload/FileUploadItemDeleteTrigger.tsx","../../src/button/Button.tsx","../../src/spinner/Spinner.styles.tsx","../../src/spinner/Spinner.tsx","../../src/button/Button.styles.tsx","../../src/button/variants/filled.ts","../../src/button/variants/ghost.ts","../../src/button/variants/outlined.ts","../../src/button/variants/tinted.ts","../../src/button/variants/contrast.ts","../../src/icon-button/IconButton.styles.tsx","../../src/icon-button/IconButton.tsx","../../src/file-upload/FileUploadContext.tsx","../../src/file-upload/FileUploadDropzone.tsx","../../src/file-upload/FileUploadPreviewImage.tsx","../../src/file-upload/FileUploadRejectedFile.tsx","../../src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx","../../src/file-upload/FileUploadTrigger.tsx"],"sourcesContent":["import {\n type FileAcceptDetails,\n type FileChangeDetails,\n type FileRejectDetails,\n FileUpload as Root,\n type FileUploadFileError,\n type RejectedFile,\n} from './FileUpload'\nimport { AcceptedFile } from './FileUploadAcceptedFile'\nimport { Context } from './FileUploadContext'\nimport { Dropzone } from './FileUploadDropzone'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { PreviewImage } from './FileUploadPreviewImage'\nimport { RejectedFile as RejectedFileComponent } from './FileUploadRejectedFile'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { Trigger } from './FileUploadTrigger'\n\nexport type {\n FileAcceptDetails,\n FileChangeDetails,\n FileRejectDetails,\n RejectedFile,\n FileUploadFileError,\n}\n\nexport const FileUpload: typeof Root & {\n Trigger: typeof Trigger\n Dropzone: typeof Dropzone\n Context: typeof Context\n ItemDeleteTrigger: typeof ItemDeleteTrigger\n PreviewImage: typeof PreviewImage\n AcceptedFile: typeof AcceptedFile\n RejectedFile: typeof RejectedFileComponent\n RejectedFileDeleteTrigger: typeof RejectedFileDeleteTrigger\n} = Object.assign(Root, {\n // Main input components\n Trigger,\n Dropzone,\n // Context components\n Context,\n AcceptedFile,\n RejectedFile: RejectedFileComponent,\n // Helpers for custom renders\n PreviewImage,\n ItemDeleteTrigger,\n RejectedFileDeleteTrigger,\n})\n\nFileUpload.displayName = 'FileUpload'\nTrigger.displayName = 'FileUpload.Trigger'\nDropzone.displayName = 'FileUpload.Dropzone'\nContext.displayName = 'FileUpload.Context'\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\nPreviewImage.displayName = 'FileUpload.PreviewImage'\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\nRejectedFileComponent.displayName = 'FileUpload.RejectedFile'\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","/* eslint-disable max-lines */\n/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { createContext, ReactNode, Ref, useContext, useId, useRef, useState } from 'react'\n\nimport { validateFileAccept, validateFileSize } from './utils'\n\nexport interface FileUploadProps {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n children: ReactNode\n className?: string\n /**\n * Initial files to display when the component mounts (uncontrolled mode)\n */\n defaultValue?: File[]\n /**\n * Controlled files value (controlled mode)\n * When provided, the component becomes controlled\n */\n value?: File[]\n /**\n * Callback when files are accepted\n * @param details - Details about the accepted files\n */\n onFileAccept?: (details: FileAcceptDetails) => void\n /**\n * Callback when files are rejected\n * @param details - Details about the rejected files and their errors\n */\n onFileReject?: (details: FileRejectDetails) => void\n /**\n * Callback when files change (both accepted and rejected)\n * For controlled mode, use this to update the value prop by extracting details.acceptedFiles\n * @param details - Details about both accepted and rejected files\n */\n onFileChange?: (details: FileChangeDetails) => void\n /**\n * Whether multiple files can be selected\n * @default true\n */\n multiple?: boolean\n /**\n * Comma-separated list of accepted file types\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n * @example \"image/*\"\n * @example \".pdf,.doc\"\n * @example \"image/png,image/jpeg,.pdf\"\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded\n * Files beyond this limit will be rejected\n */\n maxFiles?: number\n /**\n * Maximum file size in bytes\n * Files larger than this will be rejected\n */\n maxFileSize?: number\n /**\n * Minimum file size in bytes\n * Files smaller than this will be rejected\n */\n minFileSize?: number\n /**\n * When `true`, prevents the user from interacting with the file upload\n */\n disabled?: boolean\n /**\n * When `true`, sets the file upload to read-only mode\n */\n readOnly?: boolean\n /**\n * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.\n * Used for formatting file sizes and error messages.\n * @default Browser locale or 'en' if not available\n */\n locale?: string\n}\n\nexport type FileUploadFileError =\n | 'TOO_MANY_FILES'\n | 'FILE_INVALID_TYPE'\n | 'FILE_TOO_LARGE'\n | 'FILE_TOO_SMALL'\n | 'FILE_INVALID'\n | 'FILE_EXISTS'\n\nexport interface RejectedFile {\n file: File\n errors: FileUploadFileError[]\n}\n\nexport interface FileAcceptDetails {\n files: File[]\n}\n\nexport interface FileRejectDetails {\n files: RejectedFile[]\n}\n\nexport interface FileChangeDetails {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n}\n\nexport const FileUploadContext = createContext<{\n inputRef: React.RefObject<HTMLInputElement | null>\n files: File[]\n rejectedFiles: RejectedFile[]\n addFiles: (files: File[]) => void\n removeFile: (index: number) => void\n removeRejectedFile: (index: number) => void\n clearFiles: () => void\n clearRejectedFiles: () => void\n triggerRef: React.RefObject<HTMLElement | null>\n dropzoneRef: React.RefObject<HTMLElement | null>\n deleteButtonRefs: React.MutableRefObject<HTMLButtonElement[]>\n multiple: boolean\n maxFiles?: number\n maxFilesReached: boolean\n disabled: boolean\n readOnly: boolean\n locale: string\n description?: string\n isInvalid?: boolean\n isRequired?: boolean\n} | null>(null)\n\nconst ID_PREFIX = ':file-upload'\n\nexport const FileUpload = ({\n asChild: _asChild = false,\n children,\n defaultValue = [],\n value: controlledValue,\n onFileAccept,\n onFileReject,\n onFileChange,\n multiple = true,\n accept,\n maxFiles,\n maxFileSize,\n minFileSize,\n disabled: disabledProp = false,\n readOnly: readOnlyProp = false,\n locale,\n}: FileUploadProps) => {\n const field = useFormFieldControl()\n const {\n id: fieldId,\n name: fieldName,\n isInvalid,\n isRequired,\n description,\n disabled: fieldDisabled,\n readOnly: fieldReadOnly,\n labelId,\n } = field\n\n // Get default locale from browser or fallback to 'en'\n const defaultLocale =\n locale || (typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en')\n\n // Generate unique ID if none provided by FormField\n const internalId = useId()\n const inputId = fieldId || `${ID_PREFIX}-${internalId}`\n\n // Use FormField name or undefined (no hardcoded fallback)\n const inputName = fieldName\n\n const inputRef = useRef<HTMLInputElement>(null)\n const triggerRef = useRef<HTMLElement>(null)\n const dropzoneRef = useRef<HTMLElement>(null)\n const deleteButtonRefs = useRef<HTMLButtonElement[]>([])\n\n // Merge FormField props with component props (FormField takes precedence)\n const disabled = fieldDisabled ?? disabledProp\n const readOnly = fieldReadOnly ?? readOnlyProp\n\n // For controlled mode, use onFileChange to update value prop\n // useCombinedState doesn't need a callback - we'll call onFileChange manually in addFiles/removeFile\n const [filesState, setFilesState, ,] = useCombinedState(controlledValue, defaultValue)\n const files = filesState ?? []\n const setFiles = setFilesState as (value: File[] | ((prev: File[]) => File[])) => void\n const [rejectedFiles, setRejectedFiles] = useState<RejectedFile[]>([])\n\n const addFiles = (newFiles: File[]) => {\n // Don't allow adding files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Reset rejectedFiles at the start of each new file addition attempt\n setRejectedFiles([])\n\n const newRejectedFiles: RejectedFile[] = []\n\n // Helper function to check if a file already exists\n // Compares by name and size to detect duplicates (lastModified can differ when re-selecting the same file)\n const fileExists = (file: File, existingFiles: File[]): boolean => {\n return existingFiles.some(\n existingFile => existingFile.name === file.name && existingFile.size === file.size\n )\n }\n\n // Helper function to add or update rejected file\n const addRejectedFile = (file: File, error: FileUploadFileError) => {\n const existingRejection = newRejectedFiles.find(\n rejected => rejected.file.name === file.name && rejected.file.size === file.size\n )\n\n if (existingRejection) {\n // Add error to existing rejection if not already present\n if (!existingRejection.errors.includes(error)) {\n existingRejection.errors.push(error)\n }\n } else {\n // Create new rejection\n newRejectedFiles.push({\n file,\n errors: [error],\n })\n }\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n // Check maxFiles limit FIRST for all files (even if they will be rejected by other validations)\n // This allows a file to have multiple error codes (e.g., FILE_INVALID_TYPE + TOO_MANY_FILES)\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, mark all new files with TOO_MANY_FILES error\n newFiles.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n }\n }\n\n // Track files rejected by accept pattern\n let filteredFiles = newFiles\n if (accept) {\n const rejectedByAccept = newFiles.filter(file => !validateFileAccept(file, accept))\n rejectedByAccept.forEach(file => {\n addRejectedFile(file, 'FILE_INVALID_TYPE')\n })\n filteredFiles = newFiles.filter(file => validateFileAccept(file, accept))\n }\n\n // Track files rejected by size\n let validSizeFiles = filteredFiles\n if (minFileSize !== undefined || maxFileSize !== undefined) {\n validSizeFiles = filteredFiles.filter(file => {\n const validation = validateFileSize(file, minFileSize, maxFileSize, defaultLocale)\n if (!validation.valid) {\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n addRejectedFile(file, 'FILE_TOO_LARGE')\n } else if (minFileSize !== undefined && file.size < minFileSize) {\n addRejectedFile(file, 'FILE_TOO_SMALL')\n } else {\n addRejectedFile(file, 'FILE_INVALID')\n }\n\n return false\n }\n\n return true\n })\n }\n\n // Check for duplicate files (both against existing files and within the current batch)\n // This must be done AFTER size validation but BEFORE maxFiles check\n const seenFiles = new Map<string, File>()\n const duplicateFiles: File[] = []\n const uniqueFiles = validSizeFiles.filter(file => {\n // Create a unique key for the file (name + size)\n // Using name and size only, as lastModified can differ when re-selecting the same file\n const fileKey = `${file.name}-${file.size}`\n\n // Check if file already exists in previously accepted files\n const existsInPrev = fileExists(file, currentFiles)\n if (existsInPrev) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Check if file already exists in the current batch\n if (seenFiles.has(fileKey)) {\n duplicateFiles.push(file)\n addRejectedFile(file, 'FILE_EXISTS')\n\n return false\n }\n\n // Mark this file as seen\n seenFiles.set(fileKey, file)\n\n return true\n })\n\n // If multiple is false, replace existing files with only the first new file\n let filesToAdd = multiple ? uniqueFiles : uniqueFiles.slice(0, 1)\n\n // Track files rejected by maxFiles limit (only for files that passed other validations)\n // Note: We already checked maxFiles at the beginning for ALL files to allow multiple error codes\n // This second check is to prevent adding files when we're at the limit\n if (maxFiles !== undefined) {\n const currentCount = currentFiles.length\n const remainingSlots = maxFiles - currentCount\n\n if (remainingSlots <= 0) {\n // Already at max, reject all new files (they should already have TOO_MANY_FILES error from the first check)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n filesToAdd = []\n } else if (filesToAdd.length > remainingSlots) {\n // Reject all files if batch exceeds limit (\"all or nothing\" approach)\n filesToAdd.forEach(file => {\n addRejectedFile(file, 'TOO_MANY_FILES')\n })\n filesToAdd = []\n }\n }\n\n const updated = multiple ? [...currentFiles, ...filesToAdd] : filesToAdd\n\n // Add rejected files to state synchronously\n // Note: newRejectedFiles is mutated inside this setFiles callback, so it should be populated by now\n // Copy the array to avoid closure issues\n const rejectedFilesToAdd = [...newRejectedFiles]\n // Replace rejectedFiles completely (not accumulate)\n setRejectedFiles(rejectedFilesToAdd)\n\n // Call callbacks with the calculated values\n // Note: These callbacks are called synchronously with the new values\n // React will update the state asynchronously, but the callbacks receive the correct new values\n if (filesToAdd.length > 0 && onFileAccept) {\n onFileAccept({ files: filesToAdd })\n }\n\n if (rejectedFilesToAdd.length > 0 && onFileReject) {\n onFileReject({ files: rejectedFilesToAdd })\n }\n\n if (onFileChange) {\n onFileChange({\n acceptedFiles: updated,\n rejectedFiles: rejectedFilesToAdd,\n })\n }\n\n return updated\n })\n }\n\n const removeFile = (index: number) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n const updated = currentFiles.filter((_: File, i: number) => i !== index)\n\n // Clean up TOO_MANY_FILES errors if we're now below the maxFiles limit\n let updatedRejectedFiles = rejectedFiles\n if (maxFiles !== undefined && updated.length < maxFiles) {\n updatedRejectedFiles = rejectedFiles.filter(\n rejected => !rejected.errors.includes('TOO_MANY_FILES')\n )\n setRejectedFiles(updatedRejectedFiles)\n }\n\n // Call onFileChange for controlled mode\n if (onFileChange) {\n onFileChange({\n acceptedFiles: updated,\n rejectedFiles: updatedRejectedFiles,\n })\n }\n\n return updated\n })\n }\n\n const clearFiles = () => {\n // Don't allow clearing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles([])\n setRejectedFiles([])\n deleteButtonRefs.current = []\n\n // Call onFileChange for controlled mode\n if (onFileChange) {\n onFileChange({\n acceptedFiles: [],\n rejectedFiles: [],\n })\n }\n }\n\n const removeRejectedFile = (index: number) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setRejectedFiles(prev => prev.filter((_, i) => i !== index))\n }\n\n const clearRejectedFiles = () => {\n setRejectedFiles([])\n }\n\n const maxFilesReached = maxFiles !== undefined && files.length >= maxFiles\n\n return (\n <FileUploadContext.Provider\n value={{\n inputRef,\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles,\n clearRejectedFiles,\n triggerRef,\n dropzoneRef,\n deleteButtonRefs,\n multiple,\n maxFiles,\n maxFilesReached,\n disabled,\n readOnly,\n locale: defaultLocale,\n description,\n isInvalid,\n isRequired,\n }}\n >\n {/* <Comp data-spark-component=\"file-upload\" className={cx('relative', className)} {...props}> */}\n <div className=\"relative\">\n {children}\n <input\n ref={inputRef}\n type=\"file\"\n tabIndex={-1}\n id={inputId}\n multiple={multiple}\n name={inputName}\n accept={accept}\n disabled={disabled}\n readOnly={readOnly && !disabled}\n required={isRequired}\n aria-invalid={isInvalid}\n aria-describedby={description}\n // Hardcoded aria-label is acceptable here because:\n // 1. The input is visually hidden (sr-only) and not keyboard accessible (tabIndex={-1})\n // 2. Users never interact directly with this input - they interact via Trigger/Dropzone\n // 3. Screen readers will announce the Trigger/Dropzone content (which can be translated) instead\n // 4. This is only used as a fallback when no FormField.Label is present\n aria-label={!labelId ? 'Upload files test' : undefined}\n className=\"sr-only\"\n onChange={e => {\n if (e.target.files && !disabled && !readOnly) {\n addFiles(Array.from(e.target.files))\n // Reset input value to allow selecting the same file again\n try {\n e.target.value = ''\n } catch {\n // Ignore error if value is read-only (e.g., in tests)\n }\n }\n }}\n />\n </div>\n {/* </Comp> */}\n </FileUploadContext.Provider>\n )\n}\n\nFileUpload.displayName = 'FileUpload'\n\nexport const useFileUploadContext = () => {\n const context = useContext(FileUploadContext)\n\n if (!context) {\n throw Error('useFileUploadContext must be used within a FileUpload provider')\n }\n\n return context\n}\n","import { CvOutline } from '@spark-ui/icons/CvOutline'\nimport { FilePdfOutline } from '@spark-ui/icons/FilePdfOutline'\nimport { ImageOutline } from '@spark-ui/icons/ImageOutline'\nimport { PlayOutline } from '@spark-ui/icons/PlayOutline'\nimport { createElement, ReactElement } from 'react'\n\n/**\n * Validates if a file matches the accept patterns\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n */\nexport function validateFileAccept(file: File, accept: string): boolean {\n if (!accept) {\n return true\n }\n\n const patterns = accept.split(',').map(pattern => pattern.trim())\n\n return patterns.some(pattern => {\n // Handle MIME type patterns (e.g., \"image/*\", \"image/png\")\n if (pattern.includes('/')) {\n if (pattern.endsWith('/*')) {\n // Wildcard MIME type (e.g., \"image/*\")\n const baseType = pattern.slice(0, -2)\n\n return file.type.startsWith(baseType + '/')\n }\n // Exact MIME type (e.g., \"image/png\")\n\n return file.type === pattern\n }\n\n // Handle file extension patterns (e.g., \".pdf\", \".doc\")\n if (pattern.startsWith('.')) {\n const extension = pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n }\n\n // Handle extension without dot (e.g., \"pdf\", \"doc\")\n const extension = '.' + pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n })\n}\n\n/**\n * Validates if a file size is within the allowed range\n * @param file - The file to validate\n * @param minFileSize - Minimum file size in bytes\n * @param maxFileSize - Maximum file size in bytes\n * @param locale - Locale code for error messages. Defaults to browser locale or 'en'\n * @returns Object with validation result and error message if invalid\n */\nexport function validateFileSize(\n file: File,\n minFileSize?: number,\n maxFileSize?: number,\n locale?: string\n): { valid: boolean; error?: string } {\n const defaultLocale = locale || getDefaultLocale()\n if (minFileSize !== undefined && file.size < minFileSize) {\n const errorMessage = `File \"${file.name}\" is too small. Minimum size is ${formatFileSize(minFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n const errorMessage = `File \"${file.name}\" is too large. Maximum size is ${formatFileSize(maxFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Gets the default locale from the browser or falls back to 'en'\n * @returns The browser's locale or 'en' as fallback\n */\nfunction getDefaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language\n }\n\n return 'en'\n}\n\n/**\n * Formats file size in bytes to human-readable format\n * @param bytes - File size in bytes\n * @param locale - Locale code (e.g., 'en', 'fr'). Defaults to browser locale or 'en'\n * @returns Formatted file size string with appropriate unit\n */\nexport function formatFileSize(bytes: number, locale?: string): string {\n const defaultLocale = locale || getDefaultLocale()\n // Normalize locale (e.g., 'fr' -> 'fr-FR', 'en' -> 'en-US')\n let normalizedLocale = defaultLocale\n if (defaultLocale.length === 2) {\n normalizedLocale = defaultLocale === 'fr' ? 'fr-FR' : 'en-US'\n }\n\n if (bytes === 0) {\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit: 'byte',\n unitDisplay: 'long',\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n })\n\n return formatter.format(0)\n }\n\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n // Map to Intl.NumberFormat supported units\n const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const\n const unit = units[i] || 'byte'\n\n const size = bytes / Math.pow(k, i)\n\n // Use 'long' display for bytes to get proper pluralization (bytes/octets)\n // Use 'short' display for other units (KB/MB/GB, Ko/Mo/Go)\n const unitDisplay = i === 0 ? 'long' : 'short'\n\n // Use Intl.NumberFormat with unit style to format number and unit according to locale\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit,\n unitDisplay,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n })\n\n return formatter.format(size)\n}\n\n/**\n * Returns the appropriate icon component based on the file type\n * @param file - The file to get the icon for\n * @returns React element representing the icon component\n */\nexport function getFileIcon(file: File): ReactElement {\n const fileType = file.type.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n // Check for images\n if (fileType.startsWith('image/') || /\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(fileName)) {\n return createElement(ImageOutline)\n }\n\n // Check for PDFs\n if (fileType === 'application/pdf' || fileName.endsWith('.pdf')) {\n return createElement(FilePdfOutline)\n }\n\n // Check for videos\n if (fileType.startsWith('video/') || /\\.(mp4|avi|mov|wmv|flv|webm|mkv)$/i.test(fileName)) {\n return createElement(PlayOutline)\n }\n\n // Default icon for other file types\n return createElement(CvOutline)\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { Progress } from '../progress'\nimport { useFileUploadContext } from './FileUpload'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { formatFileSize, getFileIcon } from './utils'\n\nexport interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The file to display\n */\n file: File\n /**\n * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.\n */\n uploadProgress?: number\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n /**\n * Accessible label for the progress bar. Required when uploadProgress is provided.\n */\n progressAriaLabel?: string\n className?: string\n}\n\nexport const AcceptedFile = ({\n asChild: _asChild = false,\n className,\n file,\n uploadProgress,\n deleteButtonAriaLabel,\n progressAriaLabel,\n ...props\n}: FileUploadAcceptedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <li\n data-spark-component=\"file-upload-accepted-file\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n className\n )}\n {...props}\n >\n <div className=\"size-sz-40 bg-support-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\">{getFileIcon(file)}</Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <p className=\"text-body-2 truncate font-medium\">{file.name}</p>\n <p className=\"text-caption opacity-dim-1\">{formatFileSize(file.size, locale)}</p>\n </div>\n {uploadProgress !== undefined && (\n <div className=\"mt-md\">\n <Progress value={uploadProgress} max={100} aria-label={progressAriaLabel} />\n </div>\n )}\n </div>\n\n <ItemDeleteTrigger aria-label={deleteButtonAriaLabel} file={file} />\n </li>\n )\n}\n\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\n","import { Children, cloneElement, ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { iconStyles, IconVariantsProps } from './Icon.styles'\n\nexport interface IconProps extends IconVariantsProps, ComponentPropsWithoutRef<'svg'> {\n /**\n * The svg icon that will be wrapped\n */\n children: ReactNode\n /**\n * The accessible label for the icon. This label will be visually hidden but announced to screen\n * reader users, similar to `alt` text for `img` tags.\n */\n label?: string\n}\n\nexport const Icon = ({\n label,\n className,\n size = 'current',\n intent = 'current',\n children,\n ...others\n}: IconProps) => {\n const child = Children.only(children)\n\n return (\n <>\n {cloneElement(child as ReactElement<Record<string, any>>, {\n className: iconStyles({ className, size, intent }),\n 'data-spark-component': 'icon',\n 'aria-hidden': 'true',\n focusable: 'false',\n ...others,\n })}\n\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </>\n )\n}\n\nIcon.displayName = 'Icon'\n","import { Slot as RadixSlot } from 'radix-ui'\nimport {\n cloneElement,\n HTMLAttributes,\n isValidElement,\n PropsWithChildren,\n ReactNode,\n Ref,\n} from 'react'\n\nexport const Slottable: typeof RadixSlot.Slottable = RadixSlot.Slottable\n\nexport type SlotProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n ref?: Ref<HTMLElement>\n}\n\nexport const Slot = ({ ref, ...props }: SlotProps) => {\n return <RadixSlot.Root ref={ref} {...props} />\n}\n\n/**\n * When using Radix `Slot` component, it will consider its first child to merge its props with.\n * In some cases, you might need to wrap the top child with additional markup without breaking this behaviour.\n */\nexport const wrapPolymorphicSlot = (\n asChild: boolean | undefined,\n children: ReactNode,\n callback: (children: ReactNode) => ReactNode\n) => {\n if (!asChild) return callback(children) // If polymorphic behaviour is not used, we keep the original children\n\n return isValidElement(children)\n ? cloneElement(\n children,\n undefined,\n callback((children.props as { children: ReactNode }).children)\n )\n : null\n}\n","import { HTMLAttributes, PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\n\nexport type VisuallyHiddenProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLElement>\n}\n\nexport const VisuallyHidden = ({ asChild = false, ref, ...props }: VisuallyHiddenProps) => {\n const Component = asChild ? Slot : 'span'\n\n return (\n <Component\n {...props}\n ref={ref}\n style={{\n // See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss\n position: 'absolute',\n border: 0,\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n wordWrap: 'normal',\n ...props.style,\n }}\n />\n )\n}\n\nVisuallyHidden.displayName = 'VisuallyHidden'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nexport const iconStyles = cva(['fill-current shrink-0'], {\n variants: {\n /**\n * Color scheme of the icon.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['text-current'],\n main: ['text-main'],\n support: ['text-support'],\n accent: ['text-accent'],\n basic: ['text-basic'],\n success: ['text-success'],\n alert: ['text-alert'],\n error: ['text-error'],\n info: ['text-info'],\n neutral: ['text-neutral'],\n }),\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['current', 'sm', 'md', 'lg', 'xl']>({\n current: ['u-current-font-size'],\n sm: ['w-sz-16', 'h-sz-16'],\n md: ['w-sz-24', 'h-sz-24'],\n lg: ['w-sz-32', 'h-sz-32'],\n xl: ['w-sz-40', 'h-sz-40'],\n }),\n },\n})\n\nexport type IconVariantsProps = VariantProps<typeof iconStyles>\n","import { cx } from 'class-variance-authority'\nimport { Progress as RadixProgress } from 'radix-ui'\nimport { PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressContext } from './ProgressContext'\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressProps\n extends RadixProgress.ProgressProps,\n Pick<ProgressIndicatorStylesProps, 'intent'> {\n shape?: 'square' | 'rounded'\n isIndeterminate?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\nexport const Progress = ({\n className,\n value: valueProp,\n max = 100,\n shape = 'square',\n intent = 'basic',\n isIndeterminate = false,\n children = <ProgressBar />,\n ref,\n ...others\n}: PropsWithChildren<ProgressProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const value = useMemo(() => {\n return { value: valueProp ?? 0, max, intent, shape, isIndeterminate, onLabelId: setLabelId }\n }, [max, valueProp, intent, shape, isIndeterminate, setLabelId])\n\n return (\n <ProgressContext.Provider data-spark-component=\"progress\" value={value}>\n <RadixProgress.Progress\n data-spark-component=\"progress\"\n ref={ref}\n className={cx('gap-sm focus-visible:u-outline flex flex-col', className)}\n value={valueProp}\n aria-labelledby={labelId}\n max={max}\n tabIndex={-1}\n {...others}\n >\n {children}\n </RadixProgress.Progress>\n </ProgressContext.Provider>\n )\n}\n\nProgress.displayName = 'Progress'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressBarStyles = cva(\n ['relative', 'h-sz-4 w-full', 'transform-gpu overflow-hidden', 'bg-on-background/dim-4'],\n {\n variants: {\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n },\n }\n)\n\nexport type ProgressBarStylesProps = VariantProps<typeof progressBarStyles>\n","import { createContext, useContext } from 'react'\n\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressContextValue {\n value: number\n max: number\n isIndeterminate: boolean\n shape: 'square' | 'rounded'\n intent: ProgressIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n}\n\nexport const ProgressContext = createContext<ProgressContextValue | null>(null)\n\nexport const ID_PREFIX = ':progress'\n\nexport const useProgress = () => {\n const context = useContext(ProgressContext)\n\n if (!context) {\n throw new Error('useProgress must be used within a Progress provider')\n }\n\n return context\n}\n","import { Progress as RadixProgress } from 'radix-ui'\nimport { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { useProgress } from './ProgressContext'\nimport { progressIndicatorStyles } from './ProgressIndicator.styles'\n\nexport type ProgressIndicatorProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressIndicator = ({\n className,\n style,\n ref,\n ...others\n}: PropsWithChildren<ProgressIndicatorProps>) => {\n const { value, max, intent, shape, isIndeterminate } = useProgress()\n const x = ((max - value) / max) * 100\n\n return (\n <RadixProgress.ProgressIndicator\n data-spark-component=\"progress-indicator\"\n className={progressIndicatorStyles({ className, intent, shape, isIndeterminate })}\n style={{ ...style, ...(!isIndeterminate && { transform: `translateX(-${x}%)` }) }}\n ref={ref}\n {...others}\n />\n )\n}\n\nProgressIndicator.displayName = 'Progress.Indicator'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressIndicatorStyles = cva(['h-full w-full', 'transition-transform duration-400'], {\n variants: {\n /**\n * Color scheme of the progress component.\n */\n intent: {\n basic: ['bg-basic'],\n main: ['bg-main'],\n support: ['bg-support'],\n accent: ['bg-accent'],\n success: ['bg-success'],\n alert: ['bg-alert'],\n danger: ['bg-error'],\n info: ['bg-info'],\n neutral: ['bg-neutral'],\n },\n /**\n * Shape of the progress component.\n */\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n /**\n * Sets if the progress value is not determinated.\n */\n isIndeterminate: {\n true: ['absolute', '-translate-x-1/2', 'animate-standalone-indeterminate-bar'],\n false: [],\n },\n },\n})\n\nexport type ProgressIndicatorStylesProps = VariantProps<typeof progressIndicatorStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { progressBarStyles } from './ProgressBar.styles'\nimport { useProgress } from './ProgressContext'\nimport { ProgressIndicator } from './ProgressIndicator'\n\nexport type ProgressBarProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressBar = ({\n className,\n children = <ProgressIndicator />,\n ref,\n ...others\n}: PropsWithChildren<ProgressBarProps>) => {\n const { shape } = useProgress()\n\n return (\n <div\n data-spark-component=\"progress-bar\"\n className={progressBarStyles({ className, shape })}\n ref={ref}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nProgressBar.displayName = 'Progress.Bar'\n","import { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { ComponentPropsWithRef, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useProgress } from './ProgressContext'\n\nexport type ProgressLabelProps = ComponentPropsWithRef<'span'>\n\nexport const ProgressLabel = ({\n id: idProp,\n children,\n ref: forwardedRef,\n ...others\n}: ProgressLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId } = useProgress()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <span\n data-spark-component=\"progress-label\"\n id={id}\n className=\"text-body-2 text-on-surface\"\n ref={ref}\n {...others}\n >\n {children}\n </span>\n )\n}\n\nProgressLabel.displayName = 'Progress.Label'\n","import { Progress as Root } from './Progress'\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressIndicator } from './ProgressIndicator'\nimport { ProgressLabel } from './ProgressLabel'\n\nexport const Progress: typeof Root & {\n Label: typeof ProgressLabel\n Bar: typeof ProgressBar\n Indicator: typeof ProgressIndicator\n} = Object.assign(Root, {\n Label: ProgressLabel,\n Bar: ProgressBar,\n Indicator: ProgressIndicator,\n})\n\nProgress.displayName = 'Progress'\nProgressBar.displayName = 'Progress.Bar'\nProgressIndicator.displayName = 'Progress.Indicator'\nProgressLabel.displayName = 'Progress.Label'\n\nexport { type ProgressProps } from './Progress'\nexport { type ProgressBarProps } from './ProgressBar'\nexport { type ProgressLabelProps } from './ProgressLabel'\nexport { type ProgressIndicatorProps } from './ProgressIndicator'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadItemDeleteTriggerProps extends React.ComponentProps<typeof IconButton> {\n /**\n * The file to delete\n */\n file: File\n}\n\nexport const ItemDeleteTrigger = ({\n className,\n file,\n onClick,\n ...props\n}: FileUploadItemDeleteTriggerProps) => {\n const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly, files } =\n useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n // Find the index of the file using name + size (consistent with duplicate detection logic)\n const fileIndex = files.findIndex(f => f.name === file.name && f.size === file.size)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the file\n removeFile(fileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Get all remaining delete buttons from the refs array\n const remainingButtons = deleteButtonRefs.current.filter(Boolean)\n\n if (remainingButtons.length > 0) {\n // Find the button that should receive focus\n // We want to focus on the button that takes the same position as the removed one\n // If that position doesn't exist (we removed the last item), focus on the previous one\n const targetIndex = Math.min(fileIndex, remainingButtons.length - 1)\n const nextButton = remainingButtons[targetIndex]\n\n if (nextButton) {\n nextButton.focus()\n }\n } else {\n // No more files, focus on trigger or dropzone\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }\n }, 0)\n\n onClick?.(e)\n }\n\n const setRef = (node: HTMLButtonElement | null) => {\n buttonRef.current = node\n if (node) {\n // Ensure the array is large enough\n while (deleteButtonRefs.current.length <= fileIndex) {\n deleteButtonRefs.current.push(null as any)\n }\n deleteButtonRefs.current[fileIndex] = node\n } else {\n // Remove the ref when component unmounts\n if (deleteButtonRefs.current[fileIndex]) {\n deleteButtonRefs.current[fileIndex] = null as any\n }\n }\n }\n\n return (\n <IconButton\n ref={setRef}\n data-spark-component=\"file-upload-item-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, type DOMAttributes, Ref, useMemo } from 'react'\n\nimport { Slot, wrapPolymorphicSlot } from '../slot'\nimport { Spinner, type SpinnerProps } from '../spinner'\nimport { buttonStyles, type ButtonStylesProps } from './Button.styles'\n\nexport interface ButtonProps\n extends Omit<ComponentPropsWithoutRef<'button'>, 'disabled'>,\n ButtonStylesProps {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild?: boolean\n /**\n * Display a spinner to indicate to the user that the button is loading something after they interacted with it.\n */\n isLoading?: boolean\n /**\n * If your loading state should only display a spinner, it's better to specify a label for it (a11y).\n */\n loadingLabel?: string\n /**\n * If your loading state should also display a label, you can use this prop instead of `loadingLabel`.\n * **Please note that using this can result in layout shifting when the Button goes from loading state to normal state.**\n */\n loadingText?: string\n ref?: Ref<HTMLButtonElement>\n}\n\ntype DOMAttributesEventHandler = keyof Omit<\n DOMAttributes<HTMLButtonElement>,\n 'children' | 'dangerouslySetInnerHTML'\n>\n\nconst blockedEventHandlers: DOMAttributesEventHandler[] = [\n 'onClick',\n 'onMouseDown',\n 'onMouseUp',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOver',\n 'onMouseOut',\n 'onKeyDown',\n 'onKeyPress',\n 'onKeyUp',\n 'onSubmit',\n]\n\nexport const Button = ({\n children,\n design = 'filled',\n disabled = false,\n intent = 'main',\n isLoading = false,\n loadingLabel,\n loadingText,\n shape = 'rounded',\n size = 'md',\n asChild,\n className,\n underline = false,\n ref,\n ...others\n}: ButtonProps) => {\n const Component = asChild ? Slot : 'button'\n\n const shouldNotInteract = !!disabled || isLoading\n\n const disabledEventHandlers = useMemo(() => {\n const result: Partial<Record<DOMAttributesEventHandler, () => void>> = {}\n\n if (shouldNotInteract) {\n blockedEventHandlers.forEach(eventHandler => (result[eventHandler] = undefined))\n }\n\n return result\n }, [shouldNotInteract])\n\n const spinnerProps = {\n size: 'current' as SpinnerProps['size'],\n className: loadingText ? 'inline-block' : 'absolute',\n ...(loadingLabel && { 'aria-label': loadingLabel }),\n }\n\n return (\n <Component\n data-spark-component=\"button\"\n {...(Component === 'button' && { type: 'button' })}\n ref={ref}\n className={buttonStyles({\n className,\n design,\n disabled: shouldNotInteract,\n intent,\n shape,\n size,\n underline,\n })}\n disabled={!!disabled}\n aria-busy={isLoading}\n aria-live={isLoading ? 'assertive' : 'off'}\n {...others}\n {...disabledEventHandlers}\n >\n {wrapPolymorphicSlot(asChild, children, slotted =>\n isLoading ? (\n <>\n <Spinner {...spinnerProps} />\n {loadingText && loadingText}\n\n <div\n aria-hidden\n className={cx('gap-md', loadingText ? 'hidden' : 'inline-flex opacity-0')}\n >\n {slotted}\n </div>\n </>\n ) : (\n slotted\n )\n )}\n </Component>\n )\n}\n\nButton.displayName = 'Button'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nconst defaultVariants = {\n intent: 'current',\n size: 'current',\n isBackgroundVisible: false,\n} as const\n\nexport const spinnerStyles = cva(\n ['inline-block', 'border-solid', 'rounded-full', 'border-md', 'animate-spin'],\n {\n variants: {\n /**\n * Use `size` prop to set the size of the spinner. If you want to set the full size for the spinner, don't forget to add a wrapping container with its own size.\n */\n size: {\n current: ['u-current-font-size'],\n sm: ['w-sz-20', 'h-sz-20'],\n md: ['w-sz-28', 'h-sz-28'],\n full: ['w-full', 'h-full'],\n },\n /**\n * Color scheme of the spinner.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['border-current'],\n main: ['border-main'],\n support: ['border-support'],\n accent: ['border-accent'],\n basic: ['border-basic'],\n success: ['border-success'],\n alert: ['border-alert'],\n error: ['border-error'],\n info: ['border-info'],\n neutral: ['border-neutral'],\n }),\n /**\n * Size of the button.\n */\n isBackgroundVisible: {\n true: ['border-b-neutral-container', 'border-l-neutral-container'],\n false: ['border-b-transparent', 'border-l-transparent'],\n },\n },\n defaultVariants,\n }\n)\n\nexport type SpinnerStylesProps = VariantProps<typeof spinnerStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { spinnerStyles, SpinnerStylesProps } from './Spinner.styles'\n\nexport interface SpinnerProps extends ComponentPropsWithRef<'div'>, SpinnerStylesProps {\n /**\n * Use `label` prop for accessibility, it is important to add a fallback loading text. This text will be visible to screen readers.\n */\n label?: string\n}\n\nexport const Spinner = ({\n className,\n size = 'current',\n intent = 'current',\n label,\n isBackgroundVisible,\n ref,\n ...others\n}: PropsWithChildren<SpinnerProps>) => {\n return (\n <span\n role=\"status\"\n data-spark-component=\"spinner\"\n ref={ref}\n className={spinnerStyles({ className, size, intent, isBackgroundVisible })}\n {...others}\n >\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </span>\n )\n}\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nimport {\n contrastVariants,\n filledVariants,\n ghostVariants,\n outlinedVariants,\n tintedVariants,\n} from './variants'\n\nexport const buttonStyles = cva(\n [\n 'u-shadow-border-transition',\n 'box-border inline-flex items-center justify-center gap-md whitespace-nowrap',\n 'default:px-lg',\n 'text-body-1 font-bold',\n 'focus-visible:u-outline',\n ],\n {\n variants: {\n /**\n * Main style of the button.\n *\n * - `filled`: Button will be plain.\n *\n * - `outlined`: Button will be transparent with an outline.\n *\n * - `tinted`: Button will be filled but using a lighter color scheme.\n *\n * - `ghost`: Button will look like a link. No borders, plain text.\n *\n * - `contrast`: Button will be surface filled. No borders, plain text.\n *\n */\n design: makeVariants<'design', ['filled', 'outlined', 'tinted', 'ghost', 'contrast']>({\n filled: [],\n outlined: ['bg-transparent', 'border-sm', 'border-current'],\n tinted: [],\n ghost: ['default:-mx-md px-md hover:bg-main/dim-5'],\n contrast: [],\n }),\n underline: {\n true: ['underline'],\n },\n /**\n * Color scheme of the button.\n */\n intent: makeVariants<\n 'intent',\n [\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'danger',\n 'info',\n 'neutral',\n 'surface',\n 'surfaceInverse',\n ]\n >({\n main: [],\n support: [],\n accent: [],\n basic: [],\n success: [],\n alert: [],\n danger: [],\n info: [],\n neutral: [],\n surface: [],\n surfaceInverse: [],\n }),\n /**\n * Size of the button.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['min-w-sz-32', 'h-sz-32'],\n md: ['min-w-sz-44', 'h-sz-44'],\n lg: ['min-w-sz-56', 'h-sz-56'],\n }),\n /**\n * Shape of the button.\n */\n shape: makeVariants<'shape', ['rounded', 'square', 'pill']>({\n rounded: ['rounded-lg'],\n square: ['rounded-0'],\n pill: ['rounded-full'],\n }),\n /**\n * Disable the button, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['cursor-not-allowed', 'opacity-dim-3'],\n false: ['cursor-pointer'],\n },\n },\n compoundVariants: [\n ...filledVariants,\n ...outlinedVariants,\n ...tintedVariants,\n ...ghostVariants,\n ...contrastVariants,\n ],\n defaultVariants: {\n design: 'filled',\n intent: 'main',\n size: 'md',\n shape: 'rounded',\n },\n }\n)\n\nexport type ButtonStylesProps = VariantProps<typeof buttonStyles>\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const filledVariants = [\n // Main\n {\n intent: 'main',\n design: 'filled',\n class: tw([\n 'bg-main',\n 'text-on-main',\n 'hover:bg-main-hovered',\n 'enabled:active:bg-main-hovered',\n 'focus-visible:bg-main-hovered',\n ]),\n },\n // Support\n {\n intent: 'support',\n design: 'filled',\n class: tw([\n 'bg-support',\n 'text-on-support',\n 'hover:bg-support-hovered',\n 'enabled:active:bg-support-hovered',\n 'focus-visible:bg-support-hovered',\n ]),\n },\n // Accent\n {\n intent: 'accent',\n design: 'filled',\n class: tw([\n 'bg-accent',\n 'text-on-accent',\n 'hover:bg-accent-hovered',\n 'enabled:active:bg-accent-hovered',\n 'focus-visible:bg-accent-hovered',\n ]),\n },\n // Basic\n {\n intent: 'basic',\n design: 'filled',\n class: tw([\n 'bg-basic',\n 'text-on-basic',\n 'hover:bg-basic-hovered',\n 'enabled:active:bg-basic-hovered',\n 'focus-visible:bg-basic-hovered',\n ]),\n },\n // Success\n {\n intent: 'success',\n design: 'filled',\n class: tw([\n 'bg-success',\n 'text-on-success',\n 'hover:bg-success-hovered',\n 'enabled:active:bg-success-hovered',\n 'focus-visible:bg-success-hovered',\n ]),\n },\n // Alert\n {\n intent: 'alert',\n design: 'filled',\n class: tw([\n 'bg-alert',\n 'text-on-alert',\n 'hover:bg-alert-hovered',\n 'enabled:active:bg-alert-hovered',\n 'focus-visible:bg-alert-hovered',\n ]),\n },\n // Danger\n {\n intent: 'danger',\n design: 'filled',\n class: tw([\n 'text-on-error bg-error',\n 'hover:bg-error-hovered enabled:active:bg-error-hovered',\n 'focus-visible:bg-error-hovered',\n ]),\n },\n // Info\n {\n intent: 'info',\n design: 'filled',\n class: tw([\n 'text-on-error bg-info',\n 'hover:bg-info-hovered enabled:active:bg-info-hovered',\n 'focus-visible:bg-info-hovered',\n ]),\n },\n // Neutral\n {\n intent: 'neutral',\n design: 'filled',\n class: tw([\n 'bg-neutral',\n 'text-on-neutral',\n 'hover:bg-neutral-hovered',\n 'enabled:active:bg-neutral-hovered',\n 'focus-visible:bg-neutral-hovered',\n ]),\n },\n // Surface\n {\n intent: 'surface',\n design: 'filled',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'filled',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const ghostVariants = [\n {\n intent: 'main',\n design: 'ghost',\n class: tw([\n 'text-on-main-container',\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n ]),\n },\n {\n intent: 'support',\n design: 'ghost',\n class: tw([\n 'text-on-support-container',\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n ]),\n },\n {\n intent: 'accent',\n design: 'ghost',\n class: tw([\n 'text-on-accent-container',\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n ]),\n },\n {\n intent: 'basic',\n design: 'ghost',\n class: tw([\n 'text-on-basic-container',\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n ]),\n },\n {\n intent: 'success',\n design: 'ghost',\n class: tw([\n 'text-on-success-container',\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n ]),\n },\n {\n intent: 'alert',\n design: 'ghost',\n class: tw([\n 'text-on-alert-container',\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n ]),\n },\n {\n intent: 'danger',\n design: 'ghost',\n class: tw([\n 'text-on-error-container',\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n ]),\n },\n {\n intent: 'info',\n design: 'ghost',\n class: tw([\n 'text-on-info-container',\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n ]),\n },\n {\n intent: 'neutral',\n design: 'ghost',\n class: tw([\n 'text-on-neutral-container',\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n ]),\n },\n {\n intent: 'surface',\n design: 'ghost',\n class: tw([\n 'text-surface',\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'ghost',\n class: tw([\n 'text-surface-inverse',\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const outlinedVariants = [\n {\n intent: 'main',\n design: 'outlined',\n class: tw([\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n 'text-main',\n ]),\n },\n {\n intent: 'support',\n design: 'outlined',\n class: tw([\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n 'text-support',\n ]),\n },\n {\n intent: 'accent',\n design: 'outlined',\n class: tw([\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n 'text-accent',\n ]),\n },\n {\n intent: 'basic',\n design: 'outlined',\n class: tw([\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n 'text-basic',\n ]),\n },\n {\n intent: 'success',\n design: 'outlined',\n class: tw([\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n 'text-success',\n ]),\n },\n {\n intent: 'alert',\n design: 'outlined',\n class: tw([\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n 'text-alert',\n ]),\n },\n {\n intent: 'danger',\n design: 'outlined',\n class: tw([\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n 'text-error',\n ]),\n },\n {\n intent: 'info',\n design: 'outlined',\n class: tw([\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n 'text-info',\n ]),\n },\n {\n intent: 'neutral',\n design: 'outlined',\n class: tw([\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n 'text-neutral',\n ]),\n },\n {\n intent: 'surface',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n 'text-surface',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n 'text-surface-inverse',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const tintedVariants = [\n {\n intent: 'main',\n design: 'tinted',\n class: tw([\n 'bg-main-container',\n 'text-on-main-container',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'tinted',\n class: tw([\n 'bg-support-container',\n 'text-on-support-container',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'tinted',\n class: tw([\n 'bg-accent-container',\n 'text-on-accent-container',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'tinted',\n class: tw([\n 'bg-basic-container',\n 'text-on-basic-container',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'tinted',\n class: tw([\n 'bg-success-container',\n 'text-on-success-container',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'tinted',\n class: tw([\n 'bg-alert-container',\n 'text-on-alert-container',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'tinted',\n class: tw([\n 'bg-error-container',\n 'text-on-error-container',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'tinted',\n class: tw([\n 'bg-info-container',\n 'text-on-info-container',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'tinted',\n class: tw([\n 'bg-neutral-container',\n 'text-on-neutral-container',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'tinted',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'tinted',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const contrastVariants = [\n {\n intent: 'main',\n design: 'contrast',\n class: tw([\n 'text-on-main-contaier bg-surface',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'contrast',\n class: tw([\n 'text-on-support-container bg-surface',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'contrast',\n class: tw([\n 'text-on-accent-container bg-surface',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'contrast',\n class: tw([\n 'text-on-basic-container bg-surface',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'contrast',\n class: tw([\n 'text-on-success-container bg-surface',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'contrast',\n class: tw([\n 'text-on-alert-container bg-surface',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'contrast',\n class: tw([\n 'text-on-error-container bg-surface',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'contrast',\n class: tw([\n 'text-on-info-container bg-surface',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'contrast',\n class: tw([\n 'text-on-neutral-container bg-surface',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'contrast',\n class: tw([\n 'text-on-surface bg-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'contrast',\n class: tw([\n 'text-on-surface-inverse bg-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\n// override the Button component's px-lg padding by using a more specific class selector (pl-0 pr-0)\nexport const iconButtonStyles = cva(['pl-0 pr-0'], {\n variants: {\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['text-body-1'],\n md: ['text-body-1'],\n lg: ['text-display-3'],\n }),\n },\n})\n\nexport type IconButtonStylesProps = VariantProps<typeof iconButtonStyles>\n","import { Ref } from 'react'\n\nimport { Button, ButtonProps } from '../button'\nimport { iconButtonStyles } from './IconButton.styles'\n\nexport interface IconButtonProps extends Omit<ButtonProps, 'loadingText'> {\n 'aria-label': string\n ref?: Ref<HTMLButtonElement>\n}\n\nexport const IconButton = ({\n design = 'filled',\n disabled = false,\n intent = 'main',\n shape = 'rounded',\n size = 'md',\n className,\n ref,\n ...others\n}: IconButtonProps) => {\n return (\n <Button\n data-spark-component=\"icon-button\"\n ref={ref}\n className={iconButtonStyles({ size, className })}\n design={design}\n disabled={disabled}\n intent={intent}\n shape={shape}\n size={size}\n {...others}\n />\n )\n}\n\nIconButton.displayName = 'IconButton'\n","import { ReactNode } from 'react'\n\nimport { type RejectedFile, useFileUploadContext } from './FileUpload'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadContextProps {\n /**\n * Render prop that receives acceptedFiles, rejectedFiles, formatFileSize, and locale\n */\n children: (props: {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n formatFileSize: (bytes: number, locale?: string) => string\n locale?: string\n }) => ReactNode\n}\n\nexport const Context = ({ children }: FileUploadContextProps) => {\n const { files = [], rejectedFiles = [], locale } = useFileUploadContext()\n\n return (\n <>\n {children({\n acceptedFiles: files,\n rejectedFiles,\n formatFileSize,\n locale,\n })}\n </>\n )\n}\n\nContext.displayName = 'FileUpload.Context'\n","import { cx } from 'class-variance-authority'\nimport { createContext, useContext, useRef } from 'react'\n\nimport { useFileUploadContext } from './FileUpload'\n\n// Context to signal that we're inside a Dropzone\nexport const DropzoneContext = createContext<boolean>(false)\n\nexport const useDropzoneContext = () => useContext(DropzoneContext)\n\nexport function Dropzone({\n children,\n className,\n unstyled = false,\n}: {\n children?: React.ReactNode\n className?: string\n unstyled?: boolean\n}) {\n const ctx = useFileUploadContext()\n const dropzoneRef = useRef<HTMLDivElement>(null)\n\n if (!ctx) throw new Error('FileUploadDropzone must be used inside <FileUpload>')\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n e.currentTarget.setAttribute('data-drag-over', 'false')\n\n // Don't allow dropping files when disabled or readOnly\n if (ctx.disabled || ctx.readOnly) {\n return\n }\n\n const files = e.dataTransfer.files\n\n // Add files to the context\n // Convert to array - handle both FileList and array (for tests)\n let filesArray: File[] = []\n if (files) {\n filesArray = Array.isArray(files) ? [...files] : Array.from(files)\n }\n\n if (filesArray.length > 0) {\n ctx.addFiles(filesArray)\n }\n }\n\n const handleClick = () => {\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n }\n\n const isDisabled = ctx.disabled || ctx.readOnly\n\n return (\n <DropzoneContext.Provider value={true}>\n <div\n ref={node => {\n dropzoneRef.current = node\n if (ctx.dropzoneRef) {\n ctx.dropzoneRef.current = node\n }\n }}\n role=\"button\"\n tabIndex={isDisabled ? -1 : 0}\n aria-disabled={ctx.disabled ? true : undefined}\n aria-describedby={ctx.description}\n aria-invalid={ctx.isInvalid}\n aria-required={ctx.isRequired}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onDrop={handleDrop}\n onDragOver={e => {\n e.preventDefault()\n }}\n className={\n unstyled\n ? className\n : cx(\n 'default:bg-surface default:border-sm default:border-outline default:relative default:rounded-lg default:border-dashed',\n 'gap-lg flex flex-col items-center justify-center text-center',\n 'default:p-xl',\n 'transition-colors duration-200',\n !isDisabled && 'default:hover:bg-surface-hovered',\n 'data-[drag-over=true]:border-outline-high data-[drag-over=true]:bg-surface-hovered data-[drag-over=true]:border-solid',\n // Disabled: more visually disabled (opacity + cursor)\n ctx.disabled && 'cursor-not-allowed opacity-50',\n // ReadOnly: less visually disabled (just cursor, no opacity)\n ctx.readOnly && !ctx.disabled && 'cursor-default',\n className\n )\n }\n onDragEnter={e => {\n if (!isDisabled) {\n e.currentTarget.setAttribute('data-drag-over', 'true')\n }\n }}\n onDragLeave={e => {\n e.currentTarget.setAttribute('data-drag-over', 'false')\n }}\n >\n {children}\n </div>\n </DropzoneContext.Provider>\n )\n}\n\nDropzone.displayName = 'FileUploadDropzone'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref, useEffect, useState } from 'react'\n\nexport interface FileUploadPreviewImageProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n className?: string\n /**\n * The file to preview\n */\n file: File\n /**\n * Fallback content when file is not an image or preview fails\n */\n fallback?: React.ReactNode\n}\n\nexport const PreviewImage = ({\n asChild: _asChild = false,\n className,\n file,\n fallback = '📄',\n ...props\n}: FileUploadPreviewImageProps) => {\n const [imageError, setImageError] = useState(false)\n const [imageLoaded, setImageLoaded] = useState(false)\n\n const isImage = file.type.startsWith('image/')\n const imageUrl = isImage ? URL.createObjectURL(file) : null\n\n // Clean up the object URL when component unmounts or file changes\n useEffect(() => {\n return () => {\n if (imageUrl) {\n URL.revokeObjectURL(imageUrl)\n }\n }\n }, [imageUrl])\n\n if (!isImage || imageError) {\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx(\n 'bg-neutral-container flex items-center justify-center rounded-md',\n className\n )}\n {...props}\n >\n {fallback}\n </div>\n )\n }\n\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx('bg-neutral-container overflow-hidden', className)}\n {...props}\n >\n <img\n src={imageUrl!}\n alt={file.name}\n className={cx('size-full object-cover', !imageLoaded && 'opacity-0')}\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageError(true)}\n />\n {!imageLoaded && (\n <div className=\"absolute inset-0 flex items-center justify-center\">{fallback}</div>\n )}\n </div>\n )\n}\n\nPreviewImage.displayName = 'FileUpload.PreviewImage'\n","import { WarningOutline } from '@spark-ui/icons/WarningOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n type FileUploadFileError,\n type RejectedFile as RejectedFileType,\n useFileUploadContext,\n} from './FileUpload'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLLIElement>\n /**\n * The rejected file to display\n */\n rejectedFile: RejectedFileType\n /**\n * Function to render the error message for each error code\n * @param error - The error code\n * @returns The error message to display\n */\n renderError: (error: FileUploadFileError) => string\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n className?: string\n}\n\nexport const RejectedFile = ({\n asChild: _asChild = false,\n className,\n rejectedFile,\n renderError,\n deleteButtonAriaLabel,\n ...props\n}: FileUploadRejectedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <li\n data-spark-component=\"file-upload-rejected-file\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n 'border-error border-md',\n className\n )}\n {...props}\n >\n <div className=\"size-sz-40 bg-error-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\" className=\"text-error\">\n <WarningOutline />\n </Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-col\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <p className=\"text-body-2 truncate font-medium\">{rejectedFile.file.name}</p>\n <p className=\"text-caption opacity-dim-1\">\n {formatFileSize(rejectedFile.file.size, locale)}\n </p>\n </div>\n <div className=\"gap-xs flex flex-col\">\n {rejectedFile.errors.map((error, errorIndex) => (\n <div key={errorIndex} className=\"text-caption text-error\" data-error-code={error}>\n {renderError(error)}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <RejectedFileDeleteTrigger aria-label={deleteButtonAriaLabel} rejectedFile={rejectedFile} />\n </li>\n )\n}\n\nRejectedFile.displayName = 'FileUpload.RejectedFile'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { type RejectedFile as RejectedFileType, useFileUploadContext } from './FileUpload'\n\nexport interface FileUploadRejectedFileDeleteTriggerProps\n extends React.ComponentProps<typeof IconButton> {\n /**\n * The rejected file to remove\n */\n rejectedFile: RejectedFileType\n}\n\nexport const RejectedFileDeleteTrigger = ({\n className,\n rejectedFile,\n onClick,\n ...props\n}: FileUploadRejectedFileDeleteTriggerProps) => {\n const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly, rejectedFiles } =\n useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n // Find the index of the rejected file using name + size (consistent with duplicate detection logic)\n const rejectedFileIndex = rejectedFiles.findIndex(\n rf => rf.file.name === rejectedFile.file.name && rf.file.size === rejectedFile.file.size\n )\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the rejected file\n removeRejectedFile(rejectedFileIndex)\n\n // Handle focus after removal\n setTimeout(() => {\n // Try to focus on trigger or dropzone if available\n const focusTarget = triggerRef.current || dropzoneRef.current\n if (focusTarget) {\n focusTarget.focus()\n }\n }, 0)\n\n onClick?.(e)\n }\n\n return (\n <IconButton\n ref={buttonRef}\n data-spark-component=\"file-upload-rejected-file-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport React, { ReactNode, Ref } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { buttonStyles } from '../button/Button.styles'\nimport { Slot } from '../slot'\nimport { useFileUploadContext } from './FileUpload'\nimport { useDropzoneContext } from './FileUploadDropzone'\n\nexport interface FileUploadTriggerProps extends Omit<ButtonProps, 'children' | 'disabled'> {\n ref?: Ref<HTMLButtonElement>\n className?: string\n children: ReactNode\n unstyled?: boolean\n}\n\nexport const Trigger = ({\n className,\n children,\n asChild = false,\n unstyled = false,\n design = 'filled',\n intent = 'basic',\n size = 'md',\n shape = 'rounded',\n ref,\n ...props\n}: FileUploadTriggerProps) => {\n const { inputRef, triggerRef, disabled, readOnly, description, isInvalid, isRequired } =\n useFileUploadContext()\n const isInsideDropzone = useDropzoneContext()\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n if (!disabled && !readOnly) {\n inputRef.current?.click()\n }\n }\n\n // Shared ref forwarding logic\n const handleRef = (node: HTMLElement | null) => {\n // Forward ref to both the context ref and the user ref\n if (triggerRef) {\n triggerRef.current = node\n }\n if (ref) {\n if (typeof ref === 'function') {\n ref(node as HTMLButtonElement)\n } else {\n ref.current = node as HTMLButtonElement\n }\n }\n }\n\n // Determine component and props based on context\n // If inside a Dropzone, render as a non-interactive span\n // The Dropzone handles all interactions\n let Component: React.ElementType\n let componentProps: Record<string, unknown>\n\n if (isInsideDropzone) {\n // Don't use asChild when inside Dropzone - we always want a span\n Component = 'span'\n const spanStyles = unstyled\n ? className\n : buttonStyles({\n design,\n intent,\n size,\n shape,\n disabled: disabled || readOnly,\n className,\n })\n\n componentProps = {\n ref: handleRef,\n 'data-spark-component': 'file-upload-trigger',\n className: spanStyles,\n // No onClick, no role, no tabIndex - Dropzone handles interaction\n // No aria attributes here - they're on the Dropzone\n }\n } else {\n // Normal behavior when not inside Dropzone\n const buttonComponent = unstyled ? 'button' : Button\n Component = asChild ? Slot : buttonComponent\n\n componentProps = {\n ref: handleRef,\n type: 'button',\n design,\n intent,\n size,\n shape,\n 'data-spark-component': 'file-upload-trigger',\n className: cx(className),\n disabled: disabled || readOnly,\n onClick: handleClick,\n 'aria-describedby': description,\n 'aria-invalid': isInvalid,\n 'aria-required': isRequired,\n ...props,\n }\n }\n\n return <Component {...componentProps}>{children}</Component>\n}\n\nTrigger.displayName = 'FileUpload.Trigger'\n"],"mappings":"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","names":["FileUpload","import_react","extension","fileName","formatter","import_class_variance_authority","import_react","import_react","import_jsx_runtime","RadixSlot","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_radix_ui","import_react","import_class_variance_authority","import_react","ID_PREFIX","import_radix_ui","import_class_variance_authority","import_jsx_runtime","RadixProgress","import_jsx_runtime","import_jsx_runtime","RadixProgress","import_react","import_jsx_runtime","ID_PREFIX","Progress","import_class_variance_authority","import_react","import_class_variance_authority","import_react","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","Progress","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_Close","import_class_variance_authority","import_react","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","FileUpload"]}
1
+ {"version":3,"sources":["../../src/file-upload/index.ts","../../src/file-upload/FileUpload.tsx","../../src/file-upload/useFileUploadState.tsx","../../src/file-upload/constants.ts","../../src/file-upload/utils.ts","../../src/file-upload/FileUploadAcceptedFile.tsx","../../src/icon/Icon.tsx","../../src/slot/Slot.tsx","../../src/visually-hidden/VisuallyHidden.tsx","../../src/icon/Icon.styles.tsx","../../src/progress/Progress.tsx","../../src/progress/ProgressBar.styles.ts","../../src/progress/ProgressContext.tsx","../../src/progress/ProgressIndicator.tsx","../../src/progress/ProgressIndicator.styles.ts","../../src/progress/ProgressBar.tsx","../../src/progress/ProgressLabel.tsx","../../src/progress/index.ts","../../src/file-upload/FileUploadItemDeleteTrigger.tsx","../../src/button/Button.tsx","../../src/spinner/Spinner.styles.tsx","../../src/spinner/Spinner.tsx","../../src/button/Button.styles.tsx","../../src/button/variants/filled.ts","../../src/button/variants/ghost.ts","../../src/button/variants/outlined.ts","../../src/button/variants/tinted.ts","../../src/button/variants/contrast.ts","../../src/icon-button/IconButton.styles.tsx","../../src/icon-button/IconButton.tsx","../../src/file-upload/FileUploadContext.tsx","../../src/file-upload/FileUploadDropzone.tsx","../../src/file-upload/FileUploadPreviewImage.tsx","../../src/file-upload/FileUploadRejectedFile.tsx","../../src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx","../../src/file-upload/FileUploadTrigger.tsx"],"sourcesContent":["import {\n type FileAcceptDetails,\n type FileChangeDetails,\n type FileRejectDetails,\n FileUpload as Root,\n type FileUploadFileError,\n type RejectedFile,\n} from './FileUpload'\nimport { AcceptedFile } from './FileUploadAcceptedFile'\nimport { Context } from './FileUploadContext'\nimport { FILE_UPLOAD_ERRORS } from './constants'\nimport { Dropzone } from './FileUploadDropzone'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { PreviewImage } from './FileUploadPreviewImage'\nimport { RejectedFile as RejectedFileComponent } from './FileUploadRejectedFile'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { Trigger } from './FileUploadTrigger'\n\nexport type {\n FileAcceptDetails,\n FileChangeDetails,\n FileRejectDetails,\n RejectedFile,\n FileUploadFileError,\n}\n\nexport { FILE_UPLOAD_ERRORS }\n\nexport const FileUpload: typeof Root & {\n Trigger: typeof Trigger\n Dropzone: typeof Dropzone\n Context: typeof Context\n ItemDeleteTrigger: typeof ItemDeleteTrigger\n PreviewImage: typeof PreviewImage\n AcceptedFile: typeof AcceptedFile\n RejectedFile: typeof RejectedFileComponent\n RejectedFileDeleteTrigger: typeof RejectedFileDeleteTrigger\n} = Object.assign(Root, {\n // Main input components\n Trigger,\n Dropzone,\n // Context components\n Context,\n AcceptedFile,\n RejectedFile: RejectedFileComponent,\n // Helpers for custom renders\n PreviewImage,\n ItemDeleteTrigger,\n RejectedFileDeleteTrigger,\n})\n\nFileUpload.displayName = 'FileUpload'\nTrigger.displayName = 'FileUpload.Trigger'\nDropzone.displayName = 'FileUpload.Dropzone'\nContext.displayName = 'FileUpload.Context'\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\nPreviewImage.displayName = 'FileUpload.PreviewImage'\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\nRejectedFileComponent.displayName = 'FileUpload.RejectedFile'\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { createContext, ReactNode, Ref, useContext, useId, useRef } from 'react'\n\nimport {\n type FileAcceptDetails,\n type FileChangeDetails,\n type FileRejectDetails,\n type FileUploadFileError,\n type RejectedFile,\n useFileUploadState,\n} from './useFileUploadState'\n\n// Re-export types for backward compatibility\nexport type {\n FileAcceptDetails,\n FileChangeDetails,\n FileRejectDetails,\n FileUploadFileError,\n RejectedFile,\n}\n\nexport interface FileUploadProps {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n children: ReactNode\n className?: string\n /**\n * Initial files to display when the component mounts (uncontrolled mode)\n */\n defaultValue?: File[]\n /**\n * Controlled files value (controlled mode)\n * When provided, the component becomes controlled\n */\n value?: File[]\n /**\n * Callback when files are accepted\n * @param details - Details about the accepted files\n */\n onFileAccept?: (details: FileAcceptDetails) => void\n /**\n * Callback when files are rejected\n * @param details - Details about the rejected files and their errors\n */\n onFileReject?: (details: FileRejectDetails) => void\n /**\n * Callback when files change (both accepted and rejected)\n * For controlled mode, use this to update the value prop by extracting details.acceptedFiles\n * @param details - Details about both accepted and rejected files\n */\n onFileChange?: (details: FileChangeDetails) => void\n /**\n * Whether multiple files can be selected\n * @default true\n */\n multiple?: boolean\n /**\n * Comma-separated list of accepted file types\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n * @example \"image/*\"\n * @example \".pdf,.doc\"\n * @example \"image/png,image/jpeg,.pdf\"\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded\n * Files beyond this limit will be rejected\n */\n maxFiles?: number\n /**\n * Maximum file size in bytes\n * Files larger than this will be rejected\n */\n maxFileSize?: number\n /**\n * Minimum file size in bytes\n * Files smaller than this will be rejected\n */\n minFileSize?: number\n /**\n * When `true`, prevents the user from interacting with the file upload\n */\n disabled?: boolean\n /**\n * When `true`, sets the file upload to read-only mode\n */\n readOnly?: boolean\n /**\n * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.\n * Used for formatting file sizes and error messages.\n * @default Browser locale or 'en' if not available\n */\n locale?: string\n}\n\nexport const FileUploadContext = createContext<{\n inputRef: React.RefObject<HTMLInputElement | null>\n files: File[]\n rejectedFiles: RejectedFile[]\n addFiles: (files: File[]) => void\n removeFile: (index: number) => void\n removeRejectedFile: (index: number) => void\n clearFiles: () => void\n clearRejectedFiles: () => void\n triggerRef: React.RefObject<HTMLElement | null>\n dropzoneRef: React.RefObject<HTMLElement | null>\n deleteButtonRefs: React.MutableRefObject<HTMLButtonElement[]>\n rejectedFileDeleteButtonRefs: React.MutableRefObject<HTMLButtonElement[]>\n multiple: boolean\n maxFiles?: number\n maxFilesReached: boolean\n disabled: boolean\n readOnly: boolean\n locale: string\n description?: string\n isInvalid?: boolean\n isRequired?: boolean\n} | null>(null)\n\nconst ID_PREFIX = ':file-upload'\n\nexport const FileUpload = ({\n asChild: _asChild = false,\n children,\n defaultValue = [],\n value: controlledValue,\n onFileAccept,\n onFileReject,\n onFileChange,\n multiple = true,\n accept,\n maxFiles,\n maxFileSize,\n minFileSize,\n disabled: disabledProp = false,\n readOnly: readOnlyProp = false,\n locale,\n}: FileUploadProps) => {\n const field = useFormFieldControl()\n\n // Generate unique ID if none provided by FormField\n const internalId = useId()\n const inputId = field.id || `${ID_PREFIX}-${internalId}`\n\n // Use FormField name or undefined (no hardcoded fallback)\n const inputName = field.name\n\n const inputRef = useRef<HTMLInputElement>(null)\n const triggerRef = useRef<HTMLElement>(null)\n const dropzoneRef = useRef<HTMLElement>(null)\n const deleteButtonRefs = useRef<HTMLButtonElement[]>([])\n const rejectedFileDeleteButtonRefs = useRef<HTMLButtonElement[]>([])\n\n // Merge FormField props with component props (FormField takes precedence)\n const disabled = field.disabled ?? disabledProp\n const readOnly = field.readOnly ?? readOnlyProp\n\n // Use the file upload state hook to manage all file operations\n const {\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles: clearFilesFromHook,\n clearRejectedFiles,\n maxFilesReached,\n } = useFileUploadState({\n defaultValue,\n value: controlledValue,\n onFileAccept,\n onFileReject,\n onFileChange,\n multiple,\n accept,\n maxFiles,\n maxFileSize,\n minFileSize,\n disabled,\n readOnly,\n locale,\n })\n\n // Override clearFiles to also clear deleteButtonRefs\n const clearFiles = () => {\n clearFilesFromHook()\n deleteButtonRefs.current = []\n }\n\n // Override clearRejectedFiles to also clear rejectedFileDeleteButtonRefs\n const clearRejectedFilesWithRefs = () => {\n clearRejectedFiles()\n rejectedFileDeleteButtonRefs.current = []\n }\n\n return (\n <FileUploadContext.Provider\n value={{\n inputRef,\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles,\n clearRejectedFiles: clearRejectedFilesWithRefs,\n triggerRef,\n dropzoneRef,\n deleteButtonRefs,\n rejectedFileDeleteButtonRefs,\n multiple,\n maxFiles,\n maxFilesReached,\n disabled,\n readOnly,\n locale:\n locale ||\n (typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en'),\n description: field.description,\n isInvalid: field.isInvalid,\n isRequired: field.isRequired,\n }}\n >\n {/* <Comp data-spark-component=\"file-upload\" className={cx('relative', className)} {...props}> */}\n <div className=\"relative\">\n {children}\n <input\n ref={inputRef}\n type=\"file\"\n tabIndex={-1}\n id={inputId}\n multiple={multiple}\n name={inputName}\n accept={accept}\n disabled={disabled}\n readOnly={readOnly && !disabled}\n required={field.isRequired}\n aria-invalid={field.isInvalid}\n aria-describedby={field.description}\n // Hardcoded aria-label is acceptable here because:\n // 1. The input is visually hidden (sr-only) and not keyboard accessible (tabIndex={-1})\n // 2. Users never interact directly with this input - they interact via Trigger/Dropzone\n // 3. Screen readers will announce the Trigger/Dropzone content (which can be translated) instead\n // 4. This is only used as a fallback when no FormField.Label is present\n aria-label={!field.labelId ? 'Upload files' : undefined}\n className=\"sr-only\"\n onChange={e => {\n if (e.target.files && !disabled && !readOnly) {\n addFiles(Array.from(e.target.files))\n // Reset input value to allow selecting the same file again\n try {\n e.target.value = ''\n } catch {\n // Ignore error if value is read-only (e.g., in tests)\n }\n }\n }}\n />\n </div>\n {/* </Comp> */}\n </FileUploadContext.Provider>\n )\n}\n\nFileUpload.displayName = 'FileUpload'\n\nexport const useFileUploadContext = () => {\n const context = useContext(FileUploadContext)\n\n if (!context) {\n throw Error('useFileUploadContext must be used within a FileUpload provider')\n }\n\n return context\n}\n","/* eslint-disable max-lines-per-function */\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { useState } from 'react'\n\nimport { FILE_UPLOAD_ERRORS } from './constants'\nimport { validateFileAccept, validateFileSize } from './utils'\n\nexport type FileUploadFileError =\n | typeof FILE_UPLOAD_ERRORS.TOO_MANY_FILES\n | typeof FILE_UPLOAD_ERRORS.FILE_INVALID_TYPE\n | typeof FILE_UPLOAD_ERRORS.FILE_TOO_LARGE\n | typeof FILE_UPLOAD_ERRORS.FILE_TOO_SMALL\n | typeof FILE_UPLOAD_ERRORS.FILE_INVALID\n | typeof FILE_UPLOAD_ERRORS.FILE_EXISTS\n\nexport interface RejectedFile {\n file: File\n errors: FileUploadFileError[]\n}\n\nexport interface FileAcceptDetails {\n files: File[]\n}\n\nexport interface FileRejectDetails {\n files: RejectedFile[]\n}\n\nexport interface FileChangeDetails {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n}\n\nexport interface UseFileUploadStateProps {\n /**\n * Initial files to display when the component mounts (uncontrolled mode)\n */\n defaultValue?: File[]\n /**\n * Controlled files value (controlled mode)\n * When provided, the component becomes controlled\n */\n value?: File[]\n /**\n * Callback when files are accepted\n */\n onFileAccept?: (details: FileAcceptDetails) => void\n /**\n * Callback when files are rejected\n */\n onFileReject?: (details: FileRejectDetails) => void\n /**\n * Callback when files change (both accepted and rejected)\n * For controlled mode, use this to update the value prop by extracting details.acceptedFiles\n */\n onFileChange?: (details: FileChangeDetails) => void\n /**\n * Whether multiple files can be selected\n * @default true\n */\n multiple?: boolean\n /**\n * Comma-separated list of accepted file types\n */\n accept?: string\n /**\n * Maximum number of files that can be uploaded\n */\n maxFiles?: number\n /**\n * Maximum file size in bytes\n */\n maxFileSize?: number\n /**\n * Minimum file size in bytes\n */\n minFileSize?: number\n /**\n * When `true`, prevents the user from interacting with the file upload\n */\n disabled?: boolean\n /**\n * When `true`, sets the file upload to read-only mode\n */\n readOnly?: boolean\n /**\n * The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale.\n * Used for formatting file sizes and error messages.\n */\n locale?: string\n}\n\nexport interface UseFileUploadStateReturn {\n files: File[]\n rejectedFiles: RejectedFile[]\n addFiles: (files: File[]) => void\n removeFile: (index: number) => void\n removeRejectedFile: (index: number) => void\n clearFiles: () => void\n clearRejectedFiles: () => void\n maxFilesReached: boolean\n}\n\n/**\n * Hook that manages file upload state, validation, and file operations\n */\nexport function useFileUploadState({\n defaultValue = [],\n value: controlledValue,\n onFileAccept,\n onFileReject,\n onFileChange,\n multiple = true,\n accept,\n maxFiles,\n maxFileSize,\n minFileSize,\n disabled = false,\n readOnly = false,\n locale,\n}: UseFileUploadStateProps): UseFileUploadStateReturn {\n // Get default locale from browser or fallback to 'en'\n const defaultLocale =\n locale || (typeof navigator !== 'undefined' && navigator.language ? navigator.language : 'en')\n\n // For controlled mode, use onFileChange to update value prop\n // useCombinedState doesn't need a callback - we'll call onFileChange manually in addFiles/removeFile\n const [filesState, setFilesState] = useCombinedState<File[]>(controlledValue, defaultValue)\n const files = filesState ?? []\n const setFiles = setFilesState as (value: File[] | ((prev: File[]) => File[])) => void\n const [rejectedFiles, setRejectedFiles] = useState<RejectedFile[]>([])\n\n const addFiles = (newFiles: File[]) => {\n // Don't allow adding files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Reset rejectedFiles at the start of each new file addition attempt\n setRejectedFiles([])\n\n const newRejectedFiles: RejectedFile[] = []\n\n // Helper function to check if a file already exists\n // Compares by name and size to detect duplicates (lastModified can differ when re-selecting the same file)\n const fileExists = (file: File, existingFiles: File[]): boolean => {\n return existingFiles.some(\n existingFile => existingFile.name === file.name && existingFile.size === file.size\n )\n }\n\n // Helper function to add or update rejected file\n const addRejectedFile = (file: File, error: FileUploadFileError) => {\n const existingRejection = newRejectedFiles.find(\n rejected => rejected.file.name === file.name && rejected.file.size === file.size\n )\n\n if (existingRejection) {\n // Add error to existing rejection if not already present\n if (!existingRejection.errors.includes(error)) {\n existingRejection.errors.push(error)\n }\n } else {\n // Create new rejection\n newRejectedFiles.push({\n file,\n errors: [error],\n })\n }\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n\n // Calculate remaining slots once at the beginning\n const remainingSlots = maxFiles !== undefined ? maxFiles - currentFiles.length : undefined\n\n // Mark all files with TOO_MANY_FILES if already at max (before other validations)\n // This allows a file to have multiple error codes (e.g., FILE_INVALID_TYPE + TOO_MANY_FILES)\n if (remainingSlots !== undefined && remainingSlots <= 0) {\n newFiles.forEach(file => {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.TOO_MANY_FILES)\n })\n }\n\n // Track files rejected by accept pattern\n let filteredFiles = newFiles\n if (accept) {\n const rejectedByAccept = newFiles.filter(file => !validateFileAccept(file, accept))\n rejectedByAccept.forEach(file => {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_INVALID_TYPE)\n })\n filteredFiles = newFiles.filter(file => validateFileAccept(file, accept))\n }\n\n // Track files rejected by size\n let validSizeFiles = filteredFiles\n if (minFileSize !== undefined || maxFileSize !== undefined) {\n validSizeFiles = filteredFiles.filter(file => {\n const validation = validateFileSize(file, minFileSize, maxFileSize, defaultLocale)\n if (!validation.valid) {\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_TOO_LARGE)\n } else if (minFileSize !== undefined && file.size < minFileSize) {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_TOO_SMALL)\n } else {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_INVALID)\n }\n\n return false\n }\n\n return true\n })\n }\n\n // Check for duplicate files (both against existing files and within the current batch)\n const seenFiles = new Map<string, File>()\n const uniqueFiles = validSizeFiles.filter(file => {\n // Create a unique key for the file (name + size)\n // Using name and size only, as lastModified can differ when re-selecting the same file\n const fileKey = `${file.name}-${file.size}`\n\n // Check if file already exists in previously accepted files\n const existsInPrev = fileExists(file, currentFiles)\n if (existsInPrev) {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_EXISTS)\n\n return false\n }\n\n // Check if file already exists in the current batch\n if (seenFiles.has(fileKey)) {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_EXISTS)\n\n return false\n }\n\n // Mark this file as seen\n seenFiles.set(fileKey, file)\n\n return true\n })\n\n // If multiple is false, replace existing files with only the first new file\n let filesToAdd = multiple ? uniqueFiles : uniqueFiles.slice(0, 1)\n\n // Apply maxFiles limit to files that passed all other validations\n if (remainingSlots !== undefined) {\n if (remainingSlots <= 0) {\n // Already at max, reject all valid files (they should already have TOO_MANY_FILES error from the first check)\n filesToAdd = []\n } else if (filesToAdd.length > remainingSlots) {\n // Reject all files if batch exceeds limit (\"all or nothing\" approach)\n filesToAdd.forEach(file => {\n addRejectedFile(file, FILE_UPLOAD_ERRORS.TOO_MANY_FILES)\n })\n filesToAdd = []\n }\n }\n\n const updated = multiple ? [...currentFiles, ...filesToAdd] : filesToAdd\n\n // Add rejected files to state synchronously\n // Note: newRejectedFiles is mutated inside this setFiles callback, so it should be populated by now\n // Copy the array to avoid closure issues\n const rejectedFilesToAdd = [...newRejectedFiles]\n // Replace rejectedFiles completely (not accumulate)\n setRejectedFiles(rejectedFilesToAdd)\n\n // Call callbacks with the calculated values\n // Note: These callbacks are called synchronously with the new values\n // React will update the state asynchronously, but the callbacks receive the correct new values\n if (filesToAdd.length > 0 && onFileAccept) {\n onFileAccept({ files: filesToAdd })\n }\n\n if (rejectedFilesToAdd.length > 0 && onFileReject) {\n onFileReject({ files: rejectedFilesToAdd })\n }\n\n if (onFileChange) {\n onFileChange({\n acceptedFiles: updated,\n rejectedFiles: rejectedFilesToAdd,\n })\n }\n\n return updated\n })\n }\n\n const removeFile = (index: number) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles((prev: File[]) => {\n const currentFiles = prev ?? []\n const updated = currentFiles.filter((_: File, i: number) => i !== index)\n\n // Clean up TOO_MANY_FILES errors if we're now below the maxFiles limit\n let updatedRejectedFiles = rejectedFiles\n if (maxFiles !== undefined && updated.length < maxFiles) {\n updatedRejectedFiles = rejectedFiles.filter(\n rejected => !rejected.errors.includes(FILE_UPLOAD_ERRORS.TOO_MANY_FILES)\n )\n setRejectedFiles(updatedRejectedFiles)\n }\n\n // Call onFileChange for controlled mode\n if (onFileChange) {\n onFileChange({\n acceptedFiles: updated,\n rejectedFiles: updatedRejectedFiles,\n })\n }\n\n return updated\n })\n }\n\n const clearFiles = () => {\n // Don't allow clearing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setFiles([])\n setRejectedFiles([])\n\n // Call onFileChange for controlled mode\n if (onFileChange) {\n onFileChange({\n acceptedFiles: [],\n rejectedFiles: [],\n })\n }\n }\n\n const removeRejectedFile = (index: number) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n setRejectedFiles(prev => prev.filter((_, i) => i !== index))\n }\n\n const clearRejectedFiles = () => {\n setRejectedFiles([])\n }\n\n const maxFilesReached = maxFiles !== undefined && files.length >= maxFiles\n\n return {\n files,\n rejectedFiles,\n addFiles,\n removeFile,\n removeRejectedFile,\n clearFiles,\n clearRejectedFiles,\n maxFilesReached,\n }\n}\n","/**\n * File upload error codes\n */\nexport const FILE_UPLOAD_ERRORS = {\n /**\n * Exceeds the maxFiles limit\n */\n TOO_MANY_FILES: 'TOO_MANY_FILES',\n /**\n * File type not in the accept list\n */\n FILE_INVALID_TYPE: 'FILE_INVALID_TYPE',\n /**\n * File size exceeds maxFileSize\n */\n FILE_TOO_LARGE: 'FILE_TOO_LARGE',\n /**\n * File size below minFileSize\n */\n FILE_TOO_SMALL: 'FILE_TOO_SMALL',\n /**\n * Generic validation failure\n */\n FILE_INVALID: 'FILE_INVALID',\n /**\n * Duplicate file detected\n */\n FILE_EXISTS: 'FILE_EXISTS',\n} as const\n\n","import { CvOutline } from '@spark-ui/icons/CvOutline'\nimport { FilePdfOutline } from '@spark-ui/icons/FilePdfOutline'\nimport { ImageOutline } from '@spark-ui/icons/ImageOutline'\nimport { PlayOutline } from '@spark-ui/icons/PlayOutline'\nimport { createElement, ReactElement, type RefObject } from 'react'\n\n/**\n * Validates if a file matches the accept patterns\n * Supports MIME types (e.g., \"image/*\", \"image/png\", \"application/pdf\")\n * and file extensions (e.g., \".pdf\", \".doc\", \".jpg\")\n */\nexport function validateFileAccept(file: File, accept: string): boolean {\n if (!accept) {\n return true\n }\n\n const patterns = accept.split(',').map(pattern => pattern.trim())\n\n return patterns.some(pattern => {\n // Handle MIME type patterns (e.g., \"image/*\", \"image/png\")\n if (pattern.includes('/')) {\n if (pattern.endsWith('/*')) {\n // Wildcard MIME type (e.g., \"image/*\")\n const baseType = pattern.slice(0, -2)\n\n return file.type.startsWith(baseType + '/')\n }\n // Exact MIME type (e.g., \"image/png\")\n\n return file.type === pattern\n }\n\n // Handle file extension patterns (e.g., \".pdf\", \".doc\")\n if (pattern.startsWith('.')) {\n const extension = pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n }\n\n // Handle extension without dot (e.g., \"pdf\", \"doc\")\n const extension = '.' + pattern.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n return fileName.endsWith(extension)\n })\n}\n\n/**\n * Validates if a file size is within the allowed range\n * @param file - The file to validate\n * @param minFileSize - Minimum file size in bytes\n * @param maxFileSize - Maximum file size in bytes\n * @param locale - Locale code for error messages. Defaults to browser locale or 'en'\n * @returns Object with validation result and error message if invalid\n */\nexport function validateFileSize(\n file: File,\n minFileSize?: number,\n maxFileSize?: number,\n locale?: string\n): { valid: boolean; error?: string } {\n const defaultLocale = locale || getDefaultLocale()\n if (minFileSize !== undefined && file.size < minFileSize) {\n const errorMessage = `File \"${file.name}\" is too small. Minimum size is ${formatFileSize(minFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n if (maxFileSize !== undefined && file.size > maxFileSize) {\n const errorMessage = `File \"${file.name}\" is too large. Maximum size is ${formatFileSize(maxFileSize, defaultLocale)}.`\n\n return {\n valid: false,\n error: errorMessage,\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Gets the default locale from the browser or falls back to 'en'\n * @returns The browser's locale or 'en' as fallback\n */\nfunction getDefaultLocale(): string {\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language\n }\n\n return 'en'\n}\n\n/**\n * Formats file size in bytes to human-readable format\n * @param bytes - File size in bytes\n * @param locale - Locale code (e.g., 'en', 'fr'). Defaults to browser locale or 'en'\n * @returns Formatted file size string with appropriate unit\n */\nexport function formatFileSize(bytes: number, locale?: string): string {\n const defaultLocale = locale || getDefaultLocale()\n // Normalize locale (e.g., 'fr' -> 'fr-FR', 'en' -> 'en-US')\n let normalizedLocale = defaultLocale\n if (defaultLocale.length === 2) {\n normalizedLocale = defaultLocale === 'fr' ? 'fr-FR' : 'en-US'\n }\n\n if (bytes === 0) {\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit: 'byte',\n unitDisplay: 'long',\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n })\n\n return formatter.format(0)\n }\n\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n // Map to Intl.NumberFormat supported units\n const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const\n const unit = units[i] || 'byte'\n\n const size = bytes / Math.pow(k, i)\n\n // Use 'long' display for bytes to get proper pluralization (bytes/octets)\n // Use 'short' display for other units (KB/MB/GB, Ko/Mo/Go)\n const unitDisplay = i === 0 ? 'long' : 'short'\n\n // Use Intl.NumberFormat with unit style to format number and unit according to locale\n const formatter = new Intl.NumberFormat(normalizedLocale, {\n style: 'unit',\n unit,\n unitDisplay,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n })\n\n return formatter.format(size)\n}\n\n/**\n * Returns the appropriate icon component based on the file type\n * @param file - The file to get the icon for\n * @returns React element representing the icon component\n */\nexport function getFileIcon(file: File): ReactElement {\n const fileType = file.type.toLowerCase()\n const fileName = file.name.toLowerCase()\n\n // Check for images\n if (fileType.startsWith('image/') || /\\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(fileName)) {\n return createElement(ImageOutline)\n }\n\n // Check for PDFs\n if (fileType === 'application/pdf' || fileName.endsWith('.pdf')) {\n return createElement(FilePdfOutline)\n }\n\n // Check for videos\n if (fileType.startsWith('video/') || /\\.(mp4|avi|mov|wmv|flv|webm|mkv)$/i.test(fileName)) {\n return createElement(PlayOutline)\n }\n\n // Default icon for other file types\n return createElement(CvOutline)\n}\n\n/**\n * Checks if an element is focusable\n * @param element - The element to check\n * @returns True if the element is focusable\n */\nfunction isFocusable(element: HTMLElement | null): boolean {\n if (!element) {\n return false\n }\n\n // Check if element has tabIndex >= 0 (not -1)\n const tabIndex = element.tabIndex\n if (tabIndex >= 0) {\n return true\n }\n\n // Check if element is naturally focusable (input, button, select, textarea, a with href, etc.)\n const isContentEditable = String(element.contentEditable) === 'true'\n const naturallyFocusable: boolean =\n element instanceof HTMLInputElement ||\n element instanceof HTMLButtonElement ||\n element instanceof HTMLSelectElement ||\n element instanceof HTMLTextAreaElement ||\n (element instanceof HTMLAnchorElement && Boolean(element.href)) ||\n isContentEditable\n\n return naturallyFocusable\n}\n\n/**\n * Finds the first focusable element from a list of candidates\n * Falls back to inputRef if no other element is focusable\n * @param candidates - Array of candidate elements to check\n * @param inputRef - Input element to use as last resort\n * @returns The first focusable element, or null if none found\n */\nexport function findFocusableElement(\n candidates: (HTMLElement | null)[],\n inputRef: RefObject<HTMLInputElement | null>\n): HTMLElement | null {\n // Try each candidate in order\n for (const candidate of candidates) {\n if (isFocusable(candidate)) {\n return candidate\n }\n }\n\n // Last resort: use inputRef (even though it has tabIndex={-1}, we can still focus it programmatically)\n if (inputRef.current) {\n return inputRef.current\n }\n\n return null\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref, useCallback, useEffect, useState } from 'react'\n\nimport { Icon } from '../icon'\nimport { Progress } from '../progress'\nimport { useFileUploadContext } from './FileUpload'\nimport { ItemDeleteTrigger } from './FileUploadItemDeleteTrigger'\nimport { formatFileSize, getFileIcon } from './utils'\n\nexport interface FileUploadAcceptedFileProps extends ComponentPropsWithoutRef<'li'> {\n ref?: Ref<HTMLLIElement>\n /**\n * The file to display\n */\n file: File\n /**\n * Upload progress value (0-100). When provided, displays a progress bar at the bottom of the file item.\n */\n uploadProgress?: number\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n /**\n * Accessible label for the progress bar. Required when uploadProgress is provided.\n */\n progressAriaLabel?: string\n className?: string\n}\n\nexport const AcceptedFile = ({\n className,\n file,\n uploadProgress,\n deleteButtonAriaLabel,\n progressAriaLabel,\n ...props\n}: FileUploadAcceptedFileProps) => {\n const { locale } = useFileUploadContext()\n const [showProgress, setShowProgress] = useState(uploadProgress !== undefined)\n\n useEffect(() => {\n // Reset showProgress when uploadProgress becomes defined\n if (uploadProgress !== undefined) {\n setShowProgress(true)\n } else {\n setShowProgress(false)\n }\n }, [uploadProgress])\n\n const handleProgressComplete = useCallback(() => {\n setShowProgress(false)\n }, [])\n\n return (\n <li\n data-spark-component=\"file-upload-accepted-file\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n className\n )}\n {...props}\n >\n <div className=\"size-sz-36 bg-support-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\">{getFileIcon(file)}</Icon>\n </div>\n\n <div className=\"gap-md relative flex min-w-0 flex-1 flex-row items-center justify-between self-stretch\">\n <p className=\"text-body-2 truncate font-medium\">{file.name}</p>\n <p className=\"text-caption opacity-dim-1\">{formatFileSize(file.size, locale)}</p>\n {showProgress && uploadProgress !== undefined && (\n <div className=\"absolute bottom-0 left-0 w-full\">\n <Progress\n value={uploadProgress}\n max={100}\n aria-label={progressAriaLabel}\n onComplete={handleProgressComplete}\n />\n </div>\n )}\n </div>\n\n <ItemDeleteTrigger aria-label={deleteButtonAriaLabel} file={file} />\n </li>\n )\n}\n\nAcceptedFile.displayName = 'FileUpload.AcceptedFile'\n","import { Children, cloneElement, ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { iconStyles, IconVariantsProps } from './Icon.styles'\n\nexport interface IconProps extends IconVariantsProps, ComponentPropsWithoutRef<'svg'> {\n /**\n * The svg icon that will be wrapped\n */\n children: ReactNode\n /**\n * The accessible label for the icon. This label will be visually hidden but announced to screen\n * reader users, similar to `alt` text for `img` tags.\n */\n label?: string\n}\n\nexport const Icon = ({\n label,\n className,\n size = 'current',\n intent = 'current',\n children,\n ...others\n}: IconProps) => {\n const child = Children.only(children)\n\n return (\n <>\n {cloneElement(child as ReactElement<Record<string, any>>, {\n className: iconStyles({ className, size, intent }),\n 'data-spark-component': 'icon',\n 'aria-hidden': 'true',\n focusable: 'false',\n ...others,\n })}\n\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </>\n )\n}\n\nIcon.displayName = 'Icon'\n","import { Slot as RadixSlot } from 'radix-ui'\nimport {\n cloneElement,\n HTMLAttributes,\n isValidElement,\n PropsWithChildren,\n ReactNode,\n Ref,\n} from 'react'\n\nexport const Slottable: typeof RadixSlot.Slottable = RadixSlot.Slottable\n\nexport type SlotProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n ref?: Ref<HTMLElement>\n}\n\nexport const Slot = ({ ref, ...props }: SlotProps) => {\n return <RadixSlot.Root ref={ref} {...props} />\n}\n\n/**\n * When using Radix `Slot` component, it will consider its first child to merge its props with.\n * In some cases, you might need to wrap the top child with additional markup without breaking this behaviour.\n */\nexport const wrapPolymorphicSlot = (\n asChild: boolean | undefined,\n children: ReactNode,\n callback: (children: ReactNode) => ReactNode\n) => {\n if (!asChild) return callback(children) // If polymorphic behaviour is not used, we keep the original children\n\n return isValidElement(children)\n ? cloneElement(\n children,\n undefined,\n callback((children.props as { children: ReactNode }).children)\n )\n : null\n}\n","import { HTMLAttributes, PropsWithChildren, Ref } from 'react'\n\nimport { Slot } from '../slot'\n\nexport type VisuallyHiddenProps = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n /**\n * Change the default rendered element for the one passed as a child, merging their props and behavior.\n */\n asChild?: boolean\n ref?: Ref<HTMLElement>\n}\n\nexport const VisuallyHidden = ({ asChild = false, ref, ...props }: VisuallyHiddenProps) => {\n const Component = asChild ? Slot : 'span'\n\n return (\n <Component\n {...props}\n ref={ref}\n style={{\n // See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss\n position: 'absolute',\n border: 0,\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n wordWrap: 'normal',\n ...props.style,\n }}\n />\n )\n}\n\nVisuallyHidden.displayName = 'VisuallyHidden'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nexport const iconStyles = cva(['fill-current shrink-0'], {\n variants: {\n /**\n * Color scheme of the icon.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['text-current'],\n main: ['text-main'],\n support: ['text-support'],\n accent: ['text-accent'],\n basic: ['text-basic'],\n success: ['text-success'],\n alert: ['text-alert'],\n error: ['text-error'],\n info: ['text-info'],\n neutral: ['text-neutral'],\n }),\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['current', 'sm', 'md', 'lg', 'xl']>({\n current: ['u-current-font-size'],\n sm: ['w-sz-16', 'h-sz-16'],\n md: ['w-sz-24', 'h-sz-24'],\n lg: ['w-sz-32', 'h-sz-32'],\n xl: ['w-sz-40', 'h-sz-40'],\n }),\n },\n})\n\nexport type IconVariantsProps = VariantProps<typeof iconStyles>\n","import { cx } from 'class-variance-authority'\nimport { Progress as RadixProgress } from 'radix-ui'\nimport { PropsWithChildren, Ref, useMemo, useState } from 'react'\n\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressContext } from './ProgressContext'\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressProps\n extends RadixProgress.ProgressProps,\n Pick<ProgressIndicatorStylesProps, 'intent'> {\n shape?: 'square' | 'rounded'\n isIndeterminate?: boolean\n /**\n * Callback called when the progress reaches its maximum value and the transition animation completes.\n */\n onComplete?: () => void\n ref?: Ref<HTMLDivElement>\n}\n\nexport const Progress = ({\n className,\n value: valueProp,\n max = 100,\n shape = 'square',\n intent = 'basic',\n isIndeterminate = false,\n onComplete,\n children = <ProgressBar />,\n ref,\n ...others\n}: PropsWithChildren<ProgressProps>) => {\n const [labelId, setLabelId] = useState<string>()\n\n const value = useMemo(() => {\n return {\n value: valueProp ?? 0,\n max,\n intent,\n shape,\n isIndeterminate,\n onLabelId: setLabelId,\n onComplete,\n }\n }, [max, valueProp, intent, shape, isIndeterminate, setLabelId, onComplete])\n\n return (\n <ProgressContext.Provider data-spark-component=\"progress\" value={value}>\n <RadixProgress.Progress\n data-spark-component=\"progress\"\n ref={ref}\n className={cx('gap-sm focus-visible:u-outline flex flex-col', className)}\n value={valueProp}\n aria-labelledby={labelId}\n max={max}\n tabIndex={-1}\n {...others}\n >\n {children}\n </RadixProgress.Progress>\n </ProgressContext.Provider>\n )\n}\n\nProgress.displayName = 'Progress'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressBarStyles = cva(\n ['relative', 'h-sz-4 w-full', 'transform-gpu overflow-hidden', 'bg-on-background/dim-4'],\n {\n variants: {\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n },\n }\n)\n\nexport type ProgressBarStylesProps = VariantProps<typeof progressBarStyles>\n","import { createContext, useContext } from 'react'\n\nimport { ProgressIndicatorStylesProps } from './ProgressIndicator.styles'\n\nexport interface ProgressContextValue {\n value: number\n max: number\n isIndeterminate: boolean\n shape: 'square' | 'rounded'\n intent: ProgressIndicatorStylesProps['intent']\n onLabelId: (id?: string) => void\n onComplete?: () => void\n}\n\nexport const ProgressContext = createContext<ProgressContextValue | null>(null)\n\nexport const ID_PREFIX = ':progress'\n\nexport const useProgress = () => {\n const context = useContext(ProgressContext)\n\n if (!context) {\n throw new Error('useProgress must be used within a Progress provider')\n }\n\n return context\n}\n","import { Progress as RadixProgress } from 'radix-ui'\nimport { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { useProgress } from './ProgressContext'\nimport { progressIndicatorStyles } from './ProgressIndicator.styles'\n\nexport type ProgressIndicatorProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressIndicator = ({\n className,\n style,\n ref,\n onTransitionEnd,\n ...others\n}: PropsWithChildren<ProgressIndicatorProps>) => {\n const { value, max, intent, shape, isIndeterminate, onComplete } = useProgress()\n const x = ((max - value) / max) * 100\n\n const handleTransitionEnd = (event: React.TransitionEvent<HTMLDivElement>) => {\n // Call the original onTransitionEnd if provided\n onTransitionEnd?.(event)\n\n // If progress is complete and we have a callback, call it\n if (value >= max && onComplete && !isIndeterminate) {\n onComplete()\n }\n }\n\n return (\n <RadixProgress.ProgressIndicator\n data-spark-component=\"progress-indicator\"\n className={progressIndicatorStyles({ className, intent, shape, isIndeterminate })}\n style={{ ...style, ...(!isIndeterminate && { transform: `translateX(-${x}%)` }) }}\n ref={ref}\n onTransitionEnd={handleTransitionEnd}\n {...others}\n />\n )\n}\n\nProgressIndicator.displayName = 'Progress.Indicator'\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const progressIndicatorStyles = cva(['h-full w-full', 'transition-transform duration-400'], {\n variants: {\n /**\n * Color scheme of the progress component.\n */\n intent: {\n basic: ['bg-basic'],\n main: ['bg-main'],\n support: ['bg-support'],\n accent: ['bg-accent'],\n success: ['bg-success'],\n alert: ['bg-alert'],\n danger: ['bg-error'],\n info: ['bg-info'],\n neutral: ['bg-neutral'],\n },\n /**\n * Shape of the progress component.\n */\n shape: {\n square: [],\n rounded: ['rounded-sm'],\n },\n /**\n * Sets if the progress value is not determinated.\n */\n isIndeterminate: {\n true: ['absolute', '-translate-x-1/2', 'animate-standalone-indeterminate-bar'],\n false: [],\n },\n },\n})\n\nexport type ProgressIndicatorStylesProps = VariantProps<typeof progressIndicatorStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { progressBarStyles } from './ProgressBar.styles'\nimport { useProgress } from './ProgressContext'\nimport { ProgressIndicator } from './ProgressIndicator'\n\nexport type ProgressBarProps = ComponentPropsWithRef<'div'>\n\nexport const ProgressBar = ({\n className,\n children = <ProgressIndicator />,\n ref,\n ...others\n}: PropsWithChildren<ProgressBarProps>) => {\n const { shape } = useProgress()\n\n return (\n <div\n data-spark-component=\"progress-bar\"\n className={progressBarStyles({ className, shape })}\n ref={ref}\n {...others}\n >\n {children}\n </div>\n )\n}\n\nProgressBar.displayName = 'Progress.Bar'\n","import { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { ComponentPropsWithRef, useCallback, useId } from 'react'\n\nimport { ID_PREFIX, useProgress } from './ProgressContext'\n\nexport type ProgressLabelProps = ComponentPropsWithRef<'span'>\n\nexport const ProgressLabel = ({\n id: idProp,\n children,\n ref: forwardedRef,\n ...others\n}: ProgressLabelProps) => {\n const internalID = `${ID_PREFIX}-label-${useId()}`\n const id = idProp || internalID\n\n const { onLabelId } = useProgress()\n const rootRef = useCallback(\n (el: HTMLSpanElement) => {\n onLabelId(el ? id : undefined)\n },\n [id, onLabelId]\n )\n const ref = useMergeRefs(forwardedRef, rootRef)\n\n return (\n <span\n data-spark-component=\"progress-label\"\n id={id}\n className=\"text-body-2 text-on-surface\"\n ref={ref}\n {...others}\n >\n {children}\n </span>\n )\n}\n\nProgressLabel.displayName = 'Progress.Label'\n","import { Progress as Root } from './Progress'\nimport { ProgressBar } from './ProgressBar'\nimport { ProgressIndicator } from './ProgressIndicator'\nimport { ProgressLabel } from './ProgressLabel'\n\nexport const Progress: typeof Root & {\n Label: typeof ProgressLabel\n Bar: typeof ProgressBar\n Indicator: typeof ProgressIndicator\n} = Object.assign(Root, {\n Label: ProgressLabel,\n Bar: ProgressBar,\n Indicator: ProgressIndicator,\n})\n\nProgress.displayName = 'Progress'\nProgressBar.displayName = 'Progress.Bar'\nProgressIndicator.displayName = 'Progress.Indicator'\nProgressLabel.displayName = 'Progress.Label'\n\nexport { type ProgressProps } from './Progress'\nexport { type ProgressBarProps } from './ProgressBar'\nexport { type ProgressLabelProps } from './ProgressLabel'\nexport { type ProgressIndicatorProps } from './ProgressIndicator'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { useFileUploadContext } from './FileUpload'\nimport { findFocusableElement } from './utils'\n\nexport interface FileUploadItemDeleteTriggerProps extends React.ComponentProps<typeof IconButton> {\n /**\n * The file to delete\n */\n file: File\n}\n\nexport const ItemDeleteTrigger = ({\n className,\n file,\n onClick,\n ...props\n}: FileUploadItemDeleteTriggerProps) => {\n const {\n removeFile,\n triggerRef,\n dropzoneRef,\n deleteButtonRefs,\n inputRef,\n disabled,\n readOnly,\n files,\n } = useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n // Find the index of the file using name + size (consistent with duplicate detection logic)\n const fileIndex = files.findIndex(f => f.name === file.name && f.size === file.size)\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the file\n removeFile(fileIndex)\n\n // Handle focus after removal\n requestAnimationFrame(() => {\n // Get all remaining delete buttons from the refs array\n const remainingButtons = deleteButtonRefs.current.filter(Boolean)\n\n if (remainingButtons.length > 0) {\n // Find the button that should receive focus\n // We want to focus on the button that takes the same position as the removed one\n // If that position doesn't exist (we removed the last item), focus on the previous one\n const targetIndex = Math.min(fileIndex, remainingButtons.length - 1)\n const nextButton = remainingButtons[targetIndex]\n\n if (nextButton) {\n nextButton.focus()\n }\n } else {\n // No more files, find a focusable element (trigger, dropzone, or input as last resort)\n const focusTarget = findFocusableElement(\n [triggerRef.current, dropzoneRef.current],\n inputRef\n )\n if (focusTarget) {\n focusTarget.focus()\n }\n }\n })\n\n onClick?.(e)\n }\n\n const setRef = (node: HTMLButtonElement | null) => {\n buttonRef.current = node\n if (node) {\n // Ensure the array is large enough\n while (deleteButtonRefs.current.length <= fileIndex) {\n deleteButtonRefs.current.push(null as any)\n }\n deleteButtonRefs.current[fileIndex] = node\n } else {\n // Remove the ref when component unmounts\n if (deleteButtonRefs.current[fileIndex]) {\n deleteButtonRefs.current[fileIndex] = null as any\n }\n }\n }\n\n return (\n <IconButton\n ref={setRef}\n data-spark-component=\"file-upload-item-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nItemDeleteTrigger.displayName = 'FileUpload.ItemDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, type DOMAttributes, Ref, useMemo } from 'react'\n\nimport { Slot, wrapPolymorphicSlot } from '../slot'\nimport { Spinner, type SpinnerProps } from '../spinner'\nimport { buttonStyles, type ButtonStylesProps } from './Button.styles'\n\nexport interface ButtonProps\n extends Omit<ComponentPropsWithoutRef<'button'>, 'disabled'>,\n ButtonStylesProps {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n */\n asChild?: boolean\n /**\n * Display a spinner to indicate to the user that the button is loading something after they interacted with it.\n */\n isLoading?: boolean\n /**\n * If your loading state should only display a spinner, it's better to specify a label for it (a11y).\n */\n loadingLabel?: string\n /**\n * If your loading state should also display a label, you can use this prop instead of `loadingLabel`.\n * **Please note that using this can result in layout shifting when the Button goes from loading state to normal state.**\n */\n loadingText?: string\n ref?: Ref<HTMLButtonElement>\n}\n\ntype DOMAttributesEventHandler = keyof Omit<\n DOMAttributes<HTMLButtonElement>,\n 'children' | 'dangerouslySetInnerHTML'\n>\n\nconst blockedEventHandlers: DOMAttributesEventHandler[] = [\n 'onClick',\n 'onMouseDown',\n 'onMouseUp',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseOver',\n 'onMouseOut',\n 'onKeyDown',\n 'onKeyPress',\n 'onKeyUp',\n 'onSubmit',\n]\n\nexport const Button = ({\n children,\n design = 'filled',\n disabled = false,\n intent = 'main',\n isLoading = false,\n loadingLabel,\n loadingText,\n shape = 'rounded',\n size = 'md',\n asChild,\n className,\n underline = false,\n ref,\n ...others\n}: ButtonProps) => {\n const Component = asChild ? Slot : 'button'\n\n const shouldNotInteract = !!disabled || isLoading\n\n const disabledEventHandlers = useMemo(() => {\n const result: Partial<Record<DOMAttributesEventHandler, () => void>> = {}\n\n if (shouldNotInteract) {\n blockedEventHandlers.forEach(eventHandler => (result[eventHandler] = undefined))\n }\n\n return result\n }, [shouldNotInteract])\n\n const spinnerProps = {\n size: 'current' as SpinnerProps['size'],\n className: loadingText ? 'inline-block' : 'absolute',\n ...(loadingLabel && { 'aria-label': loadingLabel }),\n }\n\n return (\n <Component\n data-spark-component=\"button\"\n {...(Component === 'button' && { type: 'button' })}\n ref={ref}\n className={buttonStyles({\n className,\n design,\n disabled: shouldNotInteract,\n intent,\n shape,\n size,\n underline,\n })}\n disabled={!!disabled}\n aria-busy={isLoading}\n aria-live={isLoading ? 'assertive' : 'off'}\n {...others}\n {...disabledEventHandlers}\n >\n {wrapPolymorphicSlot(asChild, children, slotted =>\n isLoading ? (\n <>\n <Spinner {...spinnerProps} />\n {loadingText && loadingText}\n\n <div\n aria-hidden\n className={cx('gap-md', loadingText ? 'hidden' : 'inline-flex opacity-0')}\n >\n {slotted}\n </div>\n </>\n ) : (\n slotted\n )\n )}\n </Component>\n )\n}\n\nButton.displayName = 'Button'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nconst defaultVariants = {\n intent: 'current',\n size: 'current',\n isBackgroundVisible: false,\n} as const\n\nexport const spinnerStyles = cva(\n ['inline-block', 'border-solid', 'rounded-full', 'border-md', 'animate-spin'],\n {\n variants: {\n /**\n * Use `size` prop to set the size of the spinner. If you want to set the full size for the spinner, don't forget to add a wrapping container with its own size.\n */\n size: {\n current: ['u-current-font-size'],\n sm: ['w-sz-20', 'h-sz-20'],\n md: ['w-sz-28', 'h-sz-28'],\n full: ['w-full', 'h-full'],\n },\n /**\n * Color scheme of the spinner.\n */\n intent: makeVariants<\n 'intent',\n [\n 'current',\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'error',\n 'info',\n 'neutral',\n ]\n >({\n current: ['border-current'],\n main: ['border-main'],\n support: ['border-support'],\n accent: ['border-accent'],\n basic: ['border-basic'],\n success: ['border-success'],\n alert: ['border-alert'],\n error: ['border-error'],\n info: ['border-info'],\n neutral: ['border-neutral'],\n }),\n /**\n * Size of the button.\n */\n isBackgroundVisible: {\n true: ['border-b-neutral-container', 'border-l-neutral-container'],\n false: ['border-b-transparent', 'border-l-transparent'],\n },\n },\n defaultVariants,\n }\n)\n\nexport type SpinnerStylesProps = VariantProps<typeof spinnerStyles>\n","import { ComponentPropsWithRef, PropsWithChildren } from 'react'\n\nimport { VisuallyHidden } from '../visually-hidden'\nimport { spinnerStyles, SpinnerStylesProps } from './Spinner.styles'\n\nexport interface SpinnerProps extends ComponentPropsWithRef<'div'>, SpinnerStylesProps {\n /**\n * Use `label` prop for accessibility, it is important to add a fallback loading text. This text will be visible to screen readers.\n */\n label?: string\n}\n\nexport const Spinner = ({\n className,\n size = 'current',\n intent = 'current',\n label,\n isBackgroundVisible,\n ref,\n ...others\n}: PropsWithChildren<SpinnerProps>) => {\n return (\n <span\n role=\"status\"\n data-spark-component=\"spinner\"\n ref={ref}\n className={spinnerStyles({ className, size, intent, isBackgroundVisible })}\n {...others}\n >\n {label && <VisuallyHidden>{label}</VisuallyHidden>}\n </span>\n )\n}\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\nimport {\n contrastVariants,\n filledVariants,\n ghostVariants,\n outlinedVariants,\n tintedVariants,\n} from './variants'\n\nexport const buttonStyles = cva(\n [\n 'u-shadow-border-transition',\n 'box-border inline-flex items-center justify-center gap-md whitespace-nowrap',\n 'default:px-lg',\n 'text-body-1 font-bold',\n 'focus-visible:u-outline',\n ],\n {\n variants: {\n /**\n * Main style of the button.\n *\n * - `filled`: Button will be plain.\n *\n * - `outlined`: Button will be transparent with an outline.\n *\n * - `tinted`: Button will be filled but using a lighter color scheme.\n *\n * - `ghost`: Button will look like a link. No borders, plain text.\n *\n * - `contrast`: Button will be surface filled. No borders, plain text.\n *\n */\n design: makeVariants<'design', ['filled', 'outlined', 'tinted', 'ghost', 'contrast']>({\n filled: [],\n outlined: ['bg-transparent', 'border-sm', 'border-current'],\n tinted: [],\n ghost: ['default:-mx-md px-md hover:bg-main/dim-5'],\n contrast: [],\n }),\n underline: {\n true: ['underline'],\n },\n /**\n * Color scheme of the button.\n */\n intent: makeVariants<\n 'intent',\n [\n 'main',\n 'support',\n 'accent',\n 'basic',\n 'success',\n 'alert',\n 'danger',\n 'info',\n 'neutral',\n 'surface',\n 'surfaceInverse',\n ]\n >({\n main: [],\n support: [],\n accent: [],\n basic: [],\n success: [],\n alert: [],\n danger: [],\n info: [],\n neutral: [],\n surface: [],\n surfaceInverse: [],\n }),\n /**\n * Size of the button.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['min-w-sz-32', 'h-sz-32'],\n md: ['min-w-sz-44', 'h-sz-44'],\n lg: ['min-w-sz-56', 'h-sz-56'],\n }),\n /**\n * Shape of the button.\n */\n shape: makeVariants<'shape', ['rounded', 'square', 'pill']>({\n rounded: ['rounded-lg'],\n square: ['rounded-0'],\n pill: ['rounded-full'],\n }),\n /**\n * Disable the button, preventing user interaction and adding opacity.\n */\n disabled: {\n true: ['cursor-not-allowed', 'opacity-dim-3'],\n false: ['cursor-pointer'],\n },\n },\n compoundVariants: [\n ...filledVariants,\n ...outlinedVariants,\n ...tintedVariants,\n ...ghostVariants,\n ...contrastVariants,\n ],\n defaultVariants: {\n design: 'filled',\n intent: 'main',\n size: 'md',\n shape: 'rounded',\n },\n }\n)\n\nexport type ButtonStylesProps = VariantProps<typeof buttonStyles>\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const filledVariants = [\n // Main\n {\n intent: 'main',\n design: 'filled',\n class: tw([\n 'bg-main',\n 'text-on-main',\n 'hover:bg-main-hovered',\n 'enabled:active:bg-main-hovered',\n 'focus-visible:bg-main-hovered',\n ]),\n },\n // Support\n {\n intent: 'support',\n design: 'filled',\n class: tw([\n 'bg-support',\n 'text-on-support',\n 'hover:bg-support-hovered',\n 'enabled:active:bg-support-hovered',\n 'focus-visible:bg-support-hovered',\n ]),\n },\n // Accent\n {\n intent: 'accent',\n design: 'filled',\n class: tw([\n 'bg-accent',\n 'text-on-accent',\n 'hover:bg-accent-hovered',\n 'enabled:active:bg-accent-hovered',\n 'focus-visible:bg-accent-hovered',\n ]),\n },\n // Basic\n {\n intent: 'basic',\n design: 'filled',\n class: tw([\n 'bg-basic',\n 'text-on-basic',\n 'hover:bg-basic-hovered',\n 'enabled:active:bg-basic-hovered',\n 'focus-visible:bg-basic-hovered',\n ]),\n },\n // Success\n {\n intent: 'success',\n design: 'filled',\n class: tw([\n 'bg-success',\n 'text-on-success',\n 'hover:bg-success-hovered',\n 'enabled:active:bg-success-hovered',\n 'focus-visible:bg-success-hovered',\n ]),\n },\n // Alert\n {\n intent: 'alert',\n design: 'filled',\n class: tw([\n 'bg-alert',\n 'text-on-alert',\n 'hover:bg-alert-hovered',\n 'enabled:active:bg-alert-hovered',\n 'focus-visible:bg-alert-hovered',\n ]),\n },\n // Danger\n {\n intent: 'danger',\n design: 'filled',\n class: tw([\n 'text-on-error bg-error',\n 'hover:bg-error-hovered enabled:active:bg-error-hovered',\n 'focus-visible:bg-error-hovered',\n ]),\n },\n // Info\n {\n intent: 'info',\n design: 'filled',\n class: tw([\n 'text-on-error bg-info',\n 'hover:bg-info-hovered enabled:active:bg-info-hovered',\n 'focus-visible:bg-info-hovered',\n ]),\n },\n // Neutral\n {\n intent: 'neutral',\n design: 'filled',\n class: tw([\n 'bg-neutral',\n 'text-on-neutral',\n 'hover:bg-neutral-hovered',\n 'enabled:active:bg-neutral-hovered',\n 'focus-visible:bg-neutral-hovered',\n ]),\n },\n // Surface\n {\n intent: 'surface',\n design: 'filled',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'filled',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const ghostVariants = [\n {\n intent: 'main',\n design: 'ghost',\n class: tw([\n 'text-on-main-container',\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n ]),\n },\n {\n intent: 'support',\n design: 'ghost',\n class: tw([\n 'text-on-support-container',\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n ]),\n },\n {\n intent: 'accent',\n design: 'ghost',\n class: tw([\n 'text-on-accent-container',\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n ]),\n },\n {\n intent: 'basic',\n design: 'ghost',\n class: tw([\n 'text-on-basic-container',\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n ]),\n },\n {\n intent: 'success',\n design: 'ghost',\n class: tw([\n 'text-on-success-container',\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n ]),\n },\n {\n intent: 'alert',\n design: 'ghost',\n class: tw([\n 'text-on-alert-container',\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n ]),\n },\n {\n intent: 'danger',\n design: 'ghost',\n class: tw([\n 'text-on-error-container',\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n ]),\n },\n {\n intent: 'info',\n design: 'ghost',\n class: tw([\n 'text-on-info-container',\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n ]),\n },\n {\n intent: 'neutral',\n design: 'ghost',\n class: tw([\n 'text-on-neutral-container',\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n ]),\n },\n {\n intent: 'surface',\n design: 'ghost',\n class: tw([\n 'text-surface',\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'ghost',\n class: tw([\n 'text-surface-inverse',\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const outlinedVariants = [\n {\n intent: 'main',\n design: 'outlined',\n class: tw([\n 'hover:bg-main/dim-5',\n 'enabled:active:bg-main/dim-5',\n 'focus-visible:bg-main/dim-5',\n 'text-main',\n ]),\n },\n {\n intent: 'support',\n design: 'outlined',\n class: tw([\n 'hover:bg-support/dim-5',\n 'enabled:active:bg-support/dim-5',\n 'focus-visible:bg-support/dim-5',\n 'text-support',\n ]),\n },\n {\n intent: 'accent',\n design: 'outlined',\n class: tw([\n 'hover:bg-accent/dim-5',\n 'enabled:active:bg-accent/dim-5',\n 'focus-visible:bg-accent/dim-5',\n 'text-accent',\n ]),\n },\n {\n intent: 'basic',\n design: 'outlined',\n class: tw([\n 'hover:bg-basic/dim-5',\n 'enabled:active:bg-basic/dim-5',\n 'focus-visible:bg-basic/dim-5',\n 'text-basic',\n ]),\n },\n {\n intent: 'success',\n design: 'outlined',\n class: tw([\n 'hover:bg-success/dim-5',\n 'enabled:active:bg-success/dim-5',\n 'focus-visible:bg-success/dim-5',\n 'text-success',\n ]),\n },\n {\n intent: 'alert',\n design: 'outlined',\n class: tw([\n 'hover:bg-alert/dim-5',\n 'enabled:active:bg-alert/dim-5',\n 'focus-visible:bg-alert/dim-5',\n 'text-alert',\n ]),\n },\n {\n intent: 'danger',\n design: 'outlined',\n class: tw([\n 'hover:bg-error/dim-5',\n 'enabled:active:bg-error/dim-5',\n 'focus-visible:bg-error/dim-5',\n 'text-error',\n ]),\n },\n {\n intent: 'info',\n design: 'outlined',\n class: tw([\n 'hover:bg-info/dim-5',\n 'enabled:active:bg-info/dim-5',\n 'focus-visible:bg-info/dim-5',\n 'text-info',\n ]),\n },\n {\n intent: 'neutral',\n design: 'outlined',\n class: tw([\n 'hover:bg-neutral/dim-5',\n 'enabled:active:bg-neutral/dim-5',\n 'focus-visible:bg-neutral/dim-5',\n 'text-neutral',\n ]),\n },\n {\n intent: 'surface',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface/dim-5',\n 'enabled:active:bg-surface/dim-5',\n 'focus-visible:bg-surface/dim-5',\n 'text-surface',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'outlined',\n class: tw([\n 'hover:bg-surface-inverse/dim-5',\n 'enabled:active:bg-surface-inverse/dim-5',\n 'focus-visible:bg-surface-inverse/dim-5',\n 'text-surface-inverse',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const tintedVariants = [\n {\n intent: 'main',\n design: 'tinted',\n class: tw([\n 'bg-main-container',\n 'text-on-main-container',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'tinted',\n class: tw([\n 'bg-support-container',\n 'text-on-support-container',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'tinted',\n class: tw([\n 'bg-accent-container',\n 'text-on-accent-container',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'tinted',\n class: tw([\n 'bg-basic-container',\n 'text-on-basic-container',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'tinted',\n class: tw([\n 'bg-success-container',\n 'text-on-success-container',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'tinted',\n class: tw([\n 'bg-alert-container',\n 'text-on-alert-container',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'tinted',\n class: tw([\n 'bg-error-container',\n 'text-on-error-container',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'tinted',\n class: tw([\n 'bg-info-container',\n 'text-on-info-container',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'tinted',\n class: tw([\n 'bg-neutral-container',\n 'text-on-neutral-container',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'tinted',\n class: tw([\n 'bg-surface',\n 'text-on-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'tinted',\n class: tw([\n 'bg-surface-inverse',\n 'text-on-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { tw } from '@spark-ui/internal-utils'\n\nexport const contrastVariants = [\n {\n intent: 'main',\n design: 'contrast',\n class: tw([\n 'text-on-main-contaier bg-surface',\n 'hover:bg-main-container-hovered',\n 'enabled:active:bg-main-container-hovered',\n 'focus-visible:bg-main-container-hovered',\n ]),\n },\n {\n intent: 'support',\n design: 'contrast',\n class: tw([\n 'text-on-support-container bg-surface',\n 'hover:bg-support-container-hovered',\n 'enabled:active:bg-support-container-hovered',\n 'focus-visible:bg-support-container-hovered',\n ]),\n },\n {\n intent: 'accent',\n design: 'contrast',\n class: tw([\n 'text-on-accent-container bg-surface',\n 'hover:bg-accent-container-hovered',\n 'enabled:active:bg-accent-container-hovered',\n 'focus-visible:bg-accent-container-hovered',\n ]),\n },\n {\n intent: 'basic',\n design: 'contrast',\n class: tw([\n 'text-on-basic-container bg-surface',\n 'hover:bg-basic-container-hovered',\n 'enabled:active:bg-basic-container-hovered',\n 'focus-visible:bg-basic-container-hovered',\n ]),\n },\n {\n intent: 'success',\n design: 'contrast',\n class: tw([\n 'text-on-success-container bg-surface',\n 'hover:bg-success-container-hovered',\n 'enabled:active:bg-success-container-hovered',\n 'focus-visible:bg-success-container-hovered',\n ]),\n },\n {\n intent: 'alert',\n design: 'contrast',\n class: tw([\n 'text-on-alert-container bg-surface',\n 'hover:bg-alert-container-hovered',\n 'enabled:active:bg-alert-container-hovered',\n 'focus-visible:bg-alert-container-hovered',\n ]),\n },\n {\n intent: 'danger',\n design: 'contrast',\n class: tw([\n 'text-on-error-container bg-surface',\n 'hover:bg-error-container-hovered',\n 'enabled:active:bg-error-container-hovered',\n 'focus-visible:bg-error-container-hovered',\n ]),\n },\n {\n intent: 'info',\n design: 'contrast',\n class: tw([\n 'text-on-info-container bg-surface',\n 'hover:bg-info-container-hovered',\n 'enabled:active:bg-info-container-hovered',\n 'focus-visible:bg-info-container-hovered',\n ]),\n },\n {\n intent: 'neutral',\n design: 'contrast',\n class: tw([\n 'text-on-neutral-container bg-surface',\n 'hover:bg-neutral-container-hovered',\n 'enabled:active:bg-neutral-container-hovered',\n 'focus-visible:bg-neutral-container-hovered',\n ]),\n },\n {\n intent: 'surface',\n design: 'contrast',\n class: tw([\n 'text-on-surface bg-surface',\n 'hover:bg-surface-hovered',\n 'enabled:active:bg-surface-hovered',\n 'focus-visible:bg-surface-hovered',\n ]),\n },\n {\n intent: 'surfaceInverse',\n design: 'contrast',\n class: tw([\n 'text-on-surface-inverse bg-surface-inverse',\n 'hover:bg-surface-inverse-hovered',\n 'enabled:active:bg-surface-inverse-hovered',\n 'focus-visible:bg-surface-inverse-hovered',\n ]),\n },\n] as const\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, VariantProps } from 'class-variance-authority'\n\n// override the Button component's px-lg padding by using a more specific class selector (pl-0 pr-0)\nexport const iconButtonStyles = cva(['pl-0 pr-0'], {\n variants: {\n /**\n * Sets the size of the icon.\n */\n size: makeVariants<'size', ['sm', 'md', 'lg']>({\n sm: ['text-body-1'],\n md: ['text-body-1'],\n lg: ['text-display-3'],\n }),\n },\n})\n\nexport type IconButtonStylesProps = VariantProps<typeof iconButtonStyles>\n","import { Ref } from 'react'\n\nimport { Button, ButtonProps } from '../button'\nimport { iconButtonStyles } from './IconButton.styles'\n\nexport interface IconButtonProps extends Omit<ButtonProps, 'loadingText'> {\n 'aria-label': string\n ref?: Ref<HTMLButtonElement>\n}\n\nexport const IconButton = ({\n design = 'filled',\n disabled = false,\n intent = 'main',\n shape = 'rounded',\n size = 'md',\n className,\n ref,\n ...others\n}: IconButtonProps) => {\n return (\n <Button\n data-spark-component=\"icon-button\"\n ref={ref}\n className={iconButtonStyles({ size, className })}\n design={design}\n disabled={disabled}\n intent={intent}\n shape={shape}\n size={size}\n {...others}\n />\n )\n}\n\nIconButton.displayName = 'IconButton'\n","import { ReactNode } from 'react'\n\nimport { type RejectedFile, useFileUploadContext } from './FileUpload'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadContextProps {\n /**\n * Render prop that receives acceptedFiles, rejectedFiles, formatFileSize, and locale\n */\n children: (props: {\n acceptedFiles: File[]\n rejectedFiles: RejectedFile[]\n formatFileSize: (bytes: number, locale?: string) => string\n locale?: string\n }) => ReactNode\n}\n\nexport const Context = ({ children }: FileUploadContextProps) => {\n const { files = [], rejectedFiles = [], locale } = useFileUploadContext()\n\n return (\n <>\n {children({\n acceptedFiles: files,\n rejectedFiles,\n formatFileSize,\n locale,\n })}\n </>\n )\n}\n\nContext.displayName = 'FileUpload.Context'\n","import { cx } from 'class-variance-authority'\nimport { createContext, useContext, useRef } from 'react'\n\nimport { useFileUploadContext } from './FileUpload'\n\n// Context to signal that we're inside a Dropzone\nexport const DropzoneContext = createContext<boolean>(false)\n\nexport const useDropzoneContext = () => useContext(DropzoneContext)\n\nexport function Dropzone({\n children,\n className,\n unstyled = false,\n}: {\n children?: React.ReactNode\n className?: string\n unstyled?: boolean\n}) {\n const ctx = useFileUploadContext()\n const dropzoneRef = useRef<HTMLDivElement>(null)\n\n if (!ctx) throw new Error('FileUploadDropzone must be used inside <FileUpload>')\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n e.currentTarget.setAttribute('data-drag-over', 'false')\n\n // Don't allow dropping files when disabled or readOnly\n if (ctx.disabled || ctx.readOnly) {\n return\n }\n\n const files = e.dataTransfer.files\n\n // Add files to the context\n // Convert to array - handle both FileList and array (for tests)\n let filesArray: File[] = []\n if (files) {\n filesArray = Array.isArray(files) ? [...files] : Array.from(files)\n }\n\n if (filesArray.length > 0) {\n ctx.addFiles(filesArray)\n }\n }\n\n const handleClick = () => {\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (!ctx.disabled && !ctx.readOnly) {\n ctx.inputRef.current?.click()\n }\n }\n }\n\n const isDisabled = ctx.disabled || ctx.readOnly\n\n return (\n <DropzoneContext.Provider value={true}>\n <div\n ref={node => {\n dropzoneRef.current = node\n if (ctx.dropzoneRef) {\n ctx.dropzoneRef.current = node\n }\n }}\n role=\"button\"\n tabIndex={isDisabled ? -1 : 0}\n aria-disabled={ctx.disabled ? true : undefined}\n aria-describedby={ctx.description}\n aria-invalid={ctx.isInvalid}\n aria-required={ctx.isRequired}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onDrop={handleDrop}\n onDragOver={e => {\n e.preventDefault()\n }}\n className={\n unstyled\n ? className\n : cx(\n 'default:bg-surface default:border-sm default:border-outline default:relative default:rounded-lg default:border-dashed',\n 'gap-lg flex flex-col items-center justify-center text-center',\n 'default:p-xl',\n 'transition-colors duration-200',\n !isDisabled && 'default:hover:bg-surface-hovered',\n 'data-[drag-over=true]:border-outline-high data-[drag-over=true]:bg-surface-hovered data-[drag-over=true]:border-solid',\n // Disabled: more visually disabled (opacity + cursor)\n ctx.disabled && 'cursor-not-allowed opacity-50',\n // ReadOnly: less visually disabled (just cursor, no opacity)\n ctx.readOnly && !ctx.disabled && 'cursor-default',\n className\n )\n }\n onDragEnter={e => {\n if (!isDisabled) {\n e.currentTarget.setAttribute('data-drag-over', 'true')\n }\n }}\n onDragLeave={e => {\n e.currentTarget.setAttribute('data-drag-over', 'false')\n }}\n >\n {children}\n </div>\n </DropzoneContext.Provider>\n )\n}\n\nDropzone.displayName = 'FileUploadDropzone'\n","import { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref, useEffect, useState } from 'react'\n\nexport interface FileUploadPreviewImageProps extends ComponentPropsWithoutRef<'div'> {\n ref?: Ref<HTMLDivElement>\n className?: string\n /**\n * The file to preview\n */\n file: File\n /**\n * Fallback content when file is not an image or preview fails\n */\n fallback?: React.ReactNode\n}\n\nexport const PreviewImage = ({\n className,\n file,\n fallback = '📄',\n ...props\n}: FileUploadPreviewImageProps) => {\n const [imageError, setImageError] = useState(false)\n const [imageLoaded, setImageLoaded] = useState(false)\n\n const isImage = file.type.startsWith('image/')\n const imageUrl = isImage ? URL.createObjectURL(file) : null\n\n // Clean up the object URL when component unmounts or file changes\n useEffect(() => {\n return () => {\n if (imageUrl) {\n URL.revokeObjectURL(imageUrl)\n }\n }\n }, [imageUrl])\n\n if (!isImage || imageError) {\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx(\n 'bg-neutral-container flex items-center justify-center rounded-md',\n className\n )}\n {...props}\n >\n {fallback}\n </div>\n )\n }\n\n return (\n <div\n data-spark-component=\"file-upload-preview-image\"\n className={cx('bg-neutral-container overflow-hidden', className)}\n {...props}\n >\n <img\n src={imageUrl!}\n alt={file.name}\n className={cx('size-full object-cover', !imageLoaded && 'opacity-0')}\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageError(true)}\n />\n {!imageLoaded && (\n <div className=\"absolute inset-0 flex items-center justify-center\">{fallback}</div>\n )}\n </div>\n )\n}\n\nPreviewImage.displayName = 'FileUpload.PreviewImage'\n","import { WarningOutline } from '@spark-ui/icons/WarningOutline'\nimport { cx } from 'class-variance-authority'\nimport { ComponentPropsWithoutRef, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n type FileUploadFileError,\n type RejectedFile as RejectedFileType,\n useFileUploadContext,\n} from './FileUpload'\nimport { RejectedFileDeleteTrigger } from './FileUploadRejectedFileDeleteTrigger'\nimport { formatFileSize } from './utils'\n\nexport interface FileUploadRejectedFileProps extends ComponentPropsWithoutRef<'li'> {\n ref?: Ref<HTMLLIElement>\n /**\n * The rejected file to display\n */\n rejectedFile: RejectedFileType\n /**\n * Function to render the error message for each error code\n * @param error - The error code\n * @returns The error message to display\n */\n renderError: (error: FileUploadFileError) => string\n /**\n * Accessible label for the delete button\n */\n deleteButtonAriaLabel: string\n className?: string\n}\n\nexport const RejectedFile = ({\n className,\n rejectedFile,\n renderError,\n deleteButtonAriaLabel,\n ...props\n}: FileUploadRejectedFileProps) => {\n const { locale } = useFileUploadContext()\n\n return (\n <li\n data-spark-component=\"file-upload-rejected-file\"\n className={cx(\n 'relative',\n 'default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md',\n 'gap-md flex items-center justify-between default:w-full',\n 'border-error border-md',\n className\n )}\n {...props}\n >\n <div className=\"size-sz-36 bg-error-container flex items-center justify-center rounded-md\">\n <Icon size=\"md\" className=\"text-error\">\n <WarningOutline />\n </Icon>\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"gap-md flex flex-col\">\n <div className=\"gap-md flex flex-row items-center justify-between\">\n <p className=\"text-body-2 truncate font-medium\">{rejectedFile.file.name}</p>\n <p className=\"text-caption opacity-dim-1\">\n {formatFileSize(rejectedFile.file.size, locale)}\n </p>\n </div>\n <div className=\"gap-xs flex flex-col\">\n {rejectedFile.errors.map((error, errorIndex) => (\n <div key={errorIndex} className=\"text-caption text-error\" data-error-code={error}>\n {renderError(error)}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n <RejectedFileDeleteTrigger aria-label={deleteButtonAriaLabel} rejectedFile={rejectedFile} />\n </li>\n )\n}\n\nRejectedFile.displayName = 'FileUpload.RejectedFile'\n","import { Close } from '@spark-ui/icons/Close'\nimport { cx } from 'class-variance-authority'\nimport { useRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { IconButton } from '../icon-button'\nimport { type RejectedFile as RejectedFileType, useFileUploadContext } from './FileUpload'\nimport { findFocusableElement } from './utils'\n\nexport interface FileUploadRejectedFileDeleteTriggerProps\n extends React.ComponentProps<typeof IconButton> {\n /**\n * The rejected file to remove\n */\n rejectedFile: RejectedFileType\n}\n\nexport const RejectedFileDeleteTrigger = ({\n className,\n rejectedFile,\n onClick,\n ...props\n}: FileUploadRejectedFileDeleteTriggerProps) => {\n const {\n removeRejectedFile,\n triggerRef,\n dropzoneRef,\n rejectedFileDeleteButtonRefs,\n inputRef,\n disabled,\n readOnly,\n rejectedFiles,\n } = useFileUploadContext()\n const buttonRef = useRef<HTMLButtonElement>(null)\n\n // Find the index of the rejected file using name + size (consistent with duplicate detection logic)\n const rejectedFileIndex = rejectedFiles.findIndex(\n rf => rf.file.name === rejectedFile.file.name && rf.file.size === rejectedFile.file.size\n )\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n // Don't allow removing rejected files when disabled or readOnly\n if (disabled || readOnly) {\n return\n }\n\n // Remove the rejected file\n removeRejectedFile(rejectedFileIndex)\n\n // Handle focus after removal\n requestAnimationFrame(() => {\n // Get all remaining rejected file delete buttons from the refs array\n const remainingButtons = rejectedFileDeleteButtonRefs.current.filter(Boolean)\n\n if (remainingButtons.length > 0) {\n // Find the button that should receive focus\n // We want to focus on the button that takes the same position as the removed one\n // If that position doesn't exist (we removed the last item), focus on the previous one\n const targetIndex = Math.min(rejectedFileIndex, remainingButtons.length - 1)\n const nextButton = remainingButtons[targetIndex]\n\n if (nextButton) {\n nextButton.focus()\n }\n } else {\n // No more rejected files, find a focusable element (trigger, dropzone, or input as last resort)\n const focusTarget = findFocusableElement(\n [triggerRef.current, dropzoneRef.current],\n inputRef\n )\n if (focusTarget) {\n focusTarget.focus()\n }\n }\n })\n\n onClick?.(e)\n }\n\n const setRef = (node: HTMLButtonElement | null) => {\n buttonRef.current = node\n if (node) {\n // Ensure the array is large enough\n while (rejectedFileDeleteButtonRefs.current.length <= rejectedFileIndex) {\n rejectedFileDeleteButtonRefs.current.push(null as any)\n }\n rejectedFileDeleteButtonRefs.current[rejectedFileIndex] = node\n } else {\n // Remove the ref when component unmounts\n if (rejectedFileDeleteButtonRefs.current[rejectedFileIndex]) {\n rejectedFileDeleteButtonRefs.current[rejectedFileIndex] = null as any\n }\n }\n }\n\n return (\n <IconButton\n ref={setRef}\n data-spark-component=\"file-upload-rejected-file-delete-trigger\"\n className={cx(className)}\n onClick={handleClick}\n disabled={disabled || readOnly}\n size=\"sm\"\n design=\"contrast\"\n intent=\"surface\"\n {...props}\n >\n <Icon size=\"sm\">\n <Close />\n </Icon>\n </IconButton>\n )\n}\n\nRejectedFileDeleteTrigger.displayName = 'FileUpload.RejectedFileDeleteTrigger'\n","import { cx } from 'class-variance-authority'\nimport React, { ReactNode, Ref } from 'react'\n\nimport { Button, type ButtonProps } from '../button'\nimport { buttonStyles } from '../button/Button.styles'\nimport { Slot } from '../slot'\nimport { useFileUploadContext } from './FileUpload'\nimport { useDropzoneContext } from './FileUploadDropzone'\n\nexport interface FileUploadTriggerProps extends Omit<ButtonProps, 'children' | 'disabled'> {\n ref?: Ref<HTMLButtonElement>\n className?: string\n children: ReactNode\n unstyled?: boolean\n}\n\nexport const Trigger = ({\n className,\n children,\n asChild = false,\n unstyled = false,\n design = 'filled',\n intent = 'basic',\n size = 'md',\n shape = 'rounded',\n ref,\n ...props\n}: FileUploadTriggerProps) => {\n const { inputRef, triggerRef, disabled, readOnly, description, isInvalid, isRequired } =\n useFileUploadContext()\n const isInsideDropzone = useDropzoneContext()\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n if (!disabled && !readOnly) {\n inputRef.current?.click()\n }\n }\n\n // Shared ref forwarding logic\n const handleRef = (node: HTMLElement | null) => {\n // Forward ref to both the context ref and the user ref\n if (triggerRef) {\n triggerRef.current = node\n }\n if (ref) {\n if (typeof ref === 'function') {\n ref(node as HTMLButtonElement)\n } else {\n ref.current = node as HTMLButtonElement\n }\n }\n }\n\n // Determine component and props based on context\n // If inside a Dropzone, render as a non-interactive span\n // The Dropzone handles all interactions\n let Component: React.ElementType\n let componentProps: Record<string, unknown>\n\n if (isInsideDropzone) {\n // Don't use asChild when inside Dropzone - we always want a span\n Component = 'span'\n const spanStyles = unstyled\n ? className\n : buttonStyles({\n design,\n intent,\n size,\n shape,\n disabled: disabled || readOnly,\n className,\n })\n\n componentProps = {\n ref: handleRef,\n 'data-spark-component': 'file-upload-trigger',\n className: spanStyles,\n // No onClick, no role, no tabIndex - Dropzone handles interaction\n // No aria attributes here - they're on the Dropzone\n }\n } else {\n // Normal behavior when not inside Dropzone\n const buttonComponent = unstyled ? 'button' : Button\n Component = asChild ? Slot : buttonComponent\n\n componentProps = {\n ref: handleRef,\n type: 'button',\n design,\n intent,\n size,\n shape,\n 'data-spark-component': 'file-upload-trigger',\n className: cx(className),\n disabled: disabled || readOnly,\n onClick: handleClick,\n 'aria-describedby': description,\n 'aria-invalid': isInvalid,\n 'aria-required': isRequired,\n ...props,\n }\n }\n\n return <Component {...componentProps}>{children}</Component>\n}\n\nTrigger.displayName = 'FileUpload.Trigger'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,oBAAAA;AAAA;AAAA;;;ACCA,wBAAoC;AACpC,IAAAC,gBAAyE;;;ACDzE,gCAAiC;AACjC,IAAAC,gBAAyB;;;ACClB,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA,EAIhC,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAIhB,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAInB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAIhB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAIhB,cAAc;AAAA;AAAA;AAAA;AAAA,EAId,aAAa;AACf;;;AC5BA,uBAA0B;AAC1B,4BAA+B;AAC/B,0BAA6B;AAC7B,yBAA4B;AAC5B,mBAA4D;AAOrD,SAAS,mBAAmB,MAAY,QAAyB;AACtE,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,OAAO,MAAM,GAAG,EAAE,IAAI,aAAW,QAAQ,KAAK,CAAC;AAEhE,SAAO,SAAS,KAAK,aAAW;AAE9B,QAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,UAAI,QAAQ,SAAS,IAAI,GAAG;AAE1B,cAAM,WAAW,QAAQ,MAAM,GAAG,EAAE;AAEpC,eAAO,KAAK,KAAK,WAAW,WAAW,GAAG;AAAA,MAC5C;AAGA,aAAO,KAAK,SAAS;AAAA,IACvB;AAGA,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,YAAMC,aAAY,QAAQ,YAAY;AACtC,YAAMC,YAAW,KAAK,KAAK,YAAY;AAEvC,aAAOA,UAAS,SAASD,UAAS;AAAA,IACpC;AAGA,UAAM,YAAY,MAAM,QAAQ,YAAY;AAC5C,UAAM,WAAW,KAAK,KAAK,YAAY;AAEvC,WAAO,SAAS,SAAS,SAAS;AAAA,EACpC,CAAC;AACH;AAUO,SAAS,iBACd,MACA,aACA,aACA,QACoC;AACpC,QAAM,gBAAgB,UAAU,iBAAiB;AACjD,MAAI,gBAAgB,UAAa,KAAK,OAAO,aAAa;AACxD,UAAM,eAAe,SAAS,KAAK,IAAI,mCAAmC,eAAe,aAAa,aAAa,CAAC;AAEpH,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,gBAAgB,UAAa,KAAK,OAAO,aAAa;AACxD,UAAM,eAAe,SAAS,KAAK,IAAI,mCAAmC,eAAe,aAAa,aAAa,CAAC;AAEpH,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,KAAK;AACvB;AAMA,SAAS,mBAA2B;AAClC,MAAI,OAAO,cAAc,eAAe,UAAU,UAAU;AAC1D,WAAO,UAAU;AAAA,EACnB;AAEA,SAAO;AACT;AAQO,SAAS,eAAe,OAAe,QAAyB;AACrE,QAAM,gBAAgB,UAAU,iBAAiB;AAEjD,MAAI,mBAAmB;AACvB,MAAI,cAAc,WAAW,GAAG;AAC9B,uBAAmB,kBAAkB,OAAO,UAAU;AAAA,EACxD;AAEA,MAAI,UAAU,GAAG;AACf,UAAME,aAAY,IAAI,KAAK,aAAa,kBAAkB;AAAA,MACxD,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB,CAAC;AAED,WAAOA,WAAU,OAAO,CAAC;AAAA,EAC3B;AAEA,QAAM,IAAI;AACV,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAGlD,QAAM,QAAQ,CAAC,QAAQ,YAAY,YAAY,UAAU;AACzD,QAAM,OAAO,MAAM,CAAC,KAAK;AAEzB,QAAM,OAAO,QAAQ,KAAK,IAAI,GAAG,CAAC;AAIlC,QAAM,cAAc,MAAM,IAAI,SAAS;AAGvC,QAAM,YAAY,IAAI,KAAK,aAAa,kBAAkB;AAAA,IACxD,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,EACzB,CAAC;AAED,SAAO,UAAU,OAAO,IAAI;AAC9B;AAOO,SAAS,YAAY,MAA0B;AACpD,QAAM,WAAW,KAAK,KAAK,YAAY;AACvC,QAAM,WAAW,KAAK,KAAK,YAAY;AAGvC,MAAI,SAAS,WAAW,QAAQ,KAAK,0CAA0C,KAAK,QAAQ,GAAG;AAC7F,eAAO,4BAAc,gCAAY;AAAA,EACnC;AAGA,MAAI,aAAa,qBAAqB,SAAS,SAAS,MAAM,GAAG;AAC/D,eAAO,4BAAc,oCAAc;AAAA,EACrC;AAGA,MAAI,SAAS,WAAW,QAAQ,KAAK,qCAAqC,KAAK,QAAQ,GAAG;AACxF,eAAO,4BAAc,8BAAW;AAAA,EAClC;AAGA,aAAO,4BAAc,0BAAS;AAChC;AAOA,SAAS,YAAY,SAAsC;AACzD,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,QAAQ;AACzB,MAAI,YAAY,GAAG;AACjB,WAAO;AAAA,EACT;AAGA,QAAM,oBAAoB,OAAO,QAAQ,eAAe,MAAM;AAC9D,QAAM,qBACJ,mBAAmB,oBACnB,mBAAmB,qBACnB,mBAAmB,qBACnB,mBAAmB,uBAClB,mBAAmB,qBAAqB,QAAQ,QAAQ,IAAI,KAC7D;AAEF,SAAO;AACT;AASO,SAAS,qBACd,YACA,UACoB;AAEpB,aAAW,aAAa,YAAY;AAClC,QAAI,YAAY,SAAS,GAAG;AAC1B,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI,SAAS,SAAS;AACpB,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO;AACT;;;AF1HO,SAAS,mBAAmB;AAAA,EACjC,eAAe,CAAC;AAAA,EAChB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AACF,GAAsD;AAEpD,QAAM,gBACJ,WAAW,OAAO,cAAc,eAAe,UAAU,WAAW,UAAU,WAAW;AAI3F,QAAM,CAAC,YAAY,aAAa,QAAI,4CAAyB,iBAAiB,YAAY;AAC1F,QAAM,QAAQ,cAAc,CAAC;AAC7B,QAAM,WAAW;AACjB,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAyB,CAAC,CAAC;AAErE,QAAM,WAAW,CAAC,aAAqB;AAErC,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAGA,qBAAiB,CAAC,CAAC;AAEnB,UAAM,mBAAmC,CAAC;AAI1C,UAAM,aAAa,CAAC,MAAY,kBAAmC;AACjE,aAAO,cAAc;AAAA,QACnB,kBAAgB,aAAa,SAAS,KAAK,QAAQ,aAAa,SAAS,KAAK;AAAA,MAChF;AAAA,IACF;AAGA,UAAM,kBAAkB,CAAC,MAAY,UAA+B;AAClE,YAAM,oBAAoB,iBAAiB;AAAA,QACzC,cAAY,SAAS,KAAK,SAAS,KAAK,QAAQ,SAAS,KAAK,SAAS,KAAK;AAAA,MAC9E;AAEA,UAAI,mBAAmB;AAErB,YAAI,CAAC,kBAAkB,OAAO,SAAS,KAAK,GAAG;AAC7C,4BAAkB,OAAO,KAAK,KAAK;AAAA,QACrC;AAAA,MACF,OAAO;AAEL,yBAAiB,KAAK;AAAA,UACpB;AAAA,UACA,QAAQ,CAAC,KAAK;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,aAAS,CAAC,SAAiB;AACzB,YAAM,eAAe,QAAQ,CAAC;AAG9B,YAAM,iBAAiB,aAAa,SAAY,WAAW,aAAa,SAAS;AAIjF,UAAI,mBAAmB,UAAa,kBAAkB,GAAG;AACvD,iBAAS,QAAQ,UAAQ;AACvB,0BAAgB,MAAM,mBAAmB,cAAc;AAAA,QACzD,CAAC;AAAA,MACH;AAGA,UAAI,gBAAgB;AACpB,UAAI,QAAQ;AACV,cAAM,mBAAmB,SAAS,OAAO,UAAQ,CAAC,mBAAmB,MAAM,MAAM,CAAC;AAClF,yBAAiB,QAAQ,UAAQ;AAC/B,0BAAgB,MAAM,mBAAmB,iBAAiB;AAAA,QAC5D,CAAC;AACD,wBAAgB,SAAS,OAAO,UAAQ,mBAAmB,MAAM,MAAM,CAAC;AAAA,MAC1E;AAGA,UAAI,iBAAiB;AACrB,UAAI,gBAAgB,UAAa,gBAAgB,QAAW;AAC1D,yBAAiB,cAAc,OAAO,UAAQ;AAC5C,gBAAM,aAAa,iBAAiB,MAAM,aAAa,aAAa,aAAa;AACjF,cAAI,CAAC,WAAW,OAAO;AACrB,gBAAI,gBAAgB,UAAa,KAAK,OAAO,aAAa;AACxD,8BAAgB,MAAM,mBAAmB,cAAc;AAAA,YACzD,WAAW,gBAAgB,UAAa,KAAK,OAAO,aAAa;AAC/D,8BAAgB,MAAM,mBAAmB,cAAc;AAAA,YACzD,OAAO;AACL,8BAAgB,MAAM,mBAAmB,YAAY;AAAA,YACvD;AAEA,mBAAO;AAAA,UACT;AAEA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAGA,YAAM,YAAY,oBAAI,IAAkB;AACxC,YAAM,cAAc,eAAe,OAAO,UAAQ;AAGhD,cAAM,UAAU,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI;AAGzC,cAAM,eAAe,WAAW,MAAM,YAAY;AAClD,YAAI,cAAc;AAChB,0BAAgB,MAAM,mBAAmB,WAAW;AAEpD,iBAAO;AAAA,QACT;AAGA,YAAI,UAAU,IAAI,OAAO,GAAG;AAC1B,0BAAgB,MAAM,mBAAmB,WAAW;AAEpD,iBAAO;AAAA,QACT;AAGA,kBAAU,IAAI,SAAS,IAAI;AAE3B,eAAO;AAAA,MACT,CAAC;AAGD,UAAI,aAAa,WAAW,cAAc,YAAY,MAAM,GAAG,CAAC;AAGhE,UAAI,mBAAmB,QAAW;AAChC,YAAI,kBAAkB,GAAG;AAEvB,uBAAa,CAAC;AAAA,QAChB,WAAW,WAAW,SAAS,gBAAgB;AAE7C,qBAAW,QAAQ,UAAQ;AACzB,4BAAgB,MAAM,mBAAmB,cAAc;AAAA,UACzD,CAAC;AACD,uBAAa,CAAC;AAAA,QAChB;AAAA,MACF;AAEA,YAAM,UAAU,WAAW,CAAC,GAAG,cAAc,GAAG,UAAU,IAAI;AAK9D,YAAM,qBAAqB,CAAC,GAAG,gBAAgB;AAE/C,uBAAiB,kBAAkB;AAKnC,UAAI,WAAW,SAAS,KAAK,cAAc;AACzC,qBAAa,EAAE,OAAO,WAAW,CAAC;AAAA,MACpC;AAEA,UAAI,mBAAmB,SAAS,KAAK,cAAc;AACjD,qBAAa,EAAE,OAAO,mBAAmB,CAAC;AAAA,MAC5C;AAEA,UAAI,cAAc;AAChB,qBAAa;AAAA,UACX,eAAe;AAAA,UACf,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,CAAC,UAAkB;AAEpC,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAEA,aAAS,CAAC,SAAiB;AACzB,YAAM,eAAe,QAAQ,CAAC;AAC9B,YAAM,UAAU,aAAa,OAAO,CAAC,GAAS,MAAc,MAAM,KAAK;AAGvE,UAAI,uBAAuB;AAC3B,UAAI,aAAa,UAAa,QAAQ,SAAS,UAAU;AACvD,+BAAuB,cAAc;AAAA,UACnC,cAAY,CAAC,SAAS,OAAO,SAAS,mBAAmB,cAAc;AAAA,QACzE;AACA,yBAAiB,oBAAoB;AAAA,MACvC;AAGA,UAAI,cAAc;AAChB,qBAAa;AAAA,UACX,eAAe;AAAA,UACf,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,MAAM;AAEvB,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAEA,aAAS,CAAC,CAAC;AACX,qBAAiB,CAAC,CAAC;AAGnB,QAAI,cAAc;AAChB,mBAAa;AAAA,QACX,eAAe,CAAC;AAAA,QAChB,eAAe,CAAC;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,qBAAqB,CAAC,UAAkB;AAE5C,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAEA,qBAAiB,UAAQ,KAAK,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAAA,EAC7D;AAEA,QAAM,qBAAqB,MAAM;AAC/B,qBAAiB,CAAC,CAAC;AAAA,EACrB;AAEA,QAAM,kBAAkB,aAAa,UAAa,MAAM,UAAU;AAElE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ADzIM;AAjIC,IAAM,wBAAoB,6BAsBvB,IAAI;AAEd,IAAM,YAAY;AAEX,IAAM,aAAa,CAAC;AAAA,EACzB,SAAS,WAAW;AAAA,EACpB;AAAA,EACA,eAAe,CAAC;AAAA,EAChB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,eAAe;AAAA,EACzB,UAAU,eAAe;AAAA,EACzB;AACF,MAAuB;AACrB,QAAM,YAAQ,uCAAoB;AAGlC,QAAM,iBAAa,qBAAM;AACzB,QAAM,UAAU,MAAM,MAAM,GAAG,SAAS,IAAI,UAAU;AAGtD,QAAM,YAAY,MAAM;AAExB,QAAM,eAAW,sBAAyB,IAAI;AAC9C,QAAM,iBAAa,sBAAoB,IAAI;AAC3C,QAAM,kBAAc,sBAAoB,IAAI;AAC5C,QAAM,uBAAmB,sBAA4B,CAAC,CAAC;AACvD,QAAM,mCAA+B,sBAA4B,CAAC,CAAC;AAGnE,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,WAAW,MAAM,YAAY;AAGnC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB;AAAA,IACrB;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,QAAM,aAAa,MAAM;AACvB,uBAAmB;AACnB,qBAAiB,UAAU,CAAC;AAAA,EAC9B;AAGA,QAAM,6BAA6B,MAAM;AACvC,uBAAmB;AACnB,iCAA6B,UAAU,CAAC;AAAA,EAC1C;AAEA,SACE;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QACE,WACC,OAAO,cAAc,eAAe,UAAU,WAAW,UAAU,WAAW;AAAA,QACjF,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,YAAY,MAAM;AAAA,MACpB;AAAA,MAGA,uDAAC,SAAI,WAAU,YACZ;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,MAAK;AAAA,YACL,UAAU;AAAA,YACV,IAAI;AAAA,YACJ;AAAA,YACA,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,UAAU,YAAY,CAAC;AAAA,YACvB,UAAU,MAAM;AAAA,YAChB,gBAAc,MAAM;AAAA,YACpB,oBAAkB,MAAM;AAAA,YAMxB,cAAY,CAAC,MAAM,UAAU,iBAAiB;AAAA,YAC9C,WAAU;AAAA,YACV,UAAU,OAAK;AACb,kBAAI,EAAE,OAAO,SAAS,CAAC,YAAY,CAAC,UAAU;AAC5C,yBAAS,MAAM,KAAK,EAAE,OAAO,KAAK,CAAC;AAEnC,oBAAI;AACF,oBAAE,OAAO,QAAQ;AAAA,gBACnB,QAAQ;AAAA,gBAER;AAAA,cACF;AAAA,YACF;AAAA;AAAA,QACF;AAAA,SACF;AAAA;AAAA,EAEF;AAEJ;AAEA,WAAW,cAAc;AAElB,IAAM,uBAAuB,MAAM;AACxC,QAAM,cAAU,0BAAW,iBAAiB;AAE5C,MAAI,CAAC,SAAS;AACZ,UAAM,MAAM,gEAAgE;AAAA,EAC9E;AAEA,SAAO;AACT;;;AIvRA,IAAAC,oCAAmB;AACnB,IAAAC,iBAAgF;;;ACDhF,IAAAC,gBAA0F;;;ACA1F,sBAAkC;AAClC,IAAAC,gBAOO;AASE,IAAAC,sBAAA;AAPF,IAAM,YAAwC,gBAAAC,KAAU;AAMxD,IAAM,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,MAAiB;AACpD,SAAO,6CAAC,gBAAAA,KAAU,MAAV,EAAe,KAAW,GAAG,OAAO;AAC9C;AAMO,IAAM,sBAAsB,CACjC,SACA,UACA,aACG;AACH,MAAI,CAAC,QAAS,QAAO,SAAS,QAAQ;AAEtC,aAAO,8BAAe,QAAQ,QAC1B;AAAA,IACE;AAAA,IACA;AAAA,IACA,SAAU,SAAS,MAAkC,QAAQ;AAAA,EAC/D,IACA;AACN;;;ACtBI,IAAAC,sBAAA;AAJG,IAAM,iBAAiB,CAAC,EAAE,UAAU,OAAO,KAAK,GAAG,MAAM,MAA2B;AACzF,QAAM,YAAY,UAAU,OAAO;AAEnC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,OAAO;AAAA;AAAA,QAEL,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,GAAG,MAAM;AAAA,MACX;AAAA;AAAA,EACF;AAEJ;AAEA,eAAe,cAAc;;;ACrC7B,4BAA6B;AAC7B,sCAAkC;AAE3B,IAAM,iBAAa,qCAAI,CAAC,uBAAuB,GAAG;AAAA,EACvD,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,YAAQ,oCAcN;AAAA,MACA,SAAS,CAAC,cAAc;AAAA,MACxB,MAAM,CAAC,WAAW;AAAA,MAClB,SAAS,CAAC,cAAc;AAAA,MACxB,QAAQ,CAAC,aAAa;AAAA,MACtB,OAAO,CAAC,YAAY;AAAA,MACpB,SAAS,CAAC,cAAc;AAAA,MACxB,OAAO,CAAC,YAAY;AAAA,MACpB,OAAO,CAAC,YAAY;AAAA,MACpB,MAAM,CAAC,WAAW;AAAA,MAClB,SAAS,CAAC,cAAc;AAAA,IAC1B,CAAC;AAAA;AAAA;AAAA;AAAA,IAID,UAAM,oCAA0D;AAAA,MAC9D,SAAS,CAAC,qBAAqB;AAAA,MAC/B,IAAI,CAAC,WAAW,SAAS;AAAA,MACzB,IAAI,CAAC,WAAW,SAAS;AAAA,MACzB,IAAI,CAAC,WAAW,SAAS;AAAA,MACzB,IAAI,CAAC,WAAW,SAAS;AAAA,IAC3B,CAAC;AAAA,EACH;AACF,CAAC;;;AHjBG,IAAAC,sBAAA;AAXG,IAAM,OAAO,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AAAA,EACA,GAAG;AACL,MAAiB;AACf,QAAM,QAAQ,uBAAS,KAAK,QAAQ;AAEpC,SACE,8EACG;AAAA,oCAAa,OAA4C;AAAA,MACxD,WAAW,WAAW,EAAE,WAAW,MAAM,OAAO,CAAC;AAAA,MACjD,wBAAwB;AAAA,MACxB,eAAe;AAAA,MACf,WAAW;AAAA,MACX,GAAG;AAAA,IACL,CAAC;AAAA,IAEA,SAAS,6CAAC,kBAAgB,iBAAM;AAAA,KACnC;AAEJ;AAEA,KAAK,cAAc;;;AI1CnB,IAAAC,mCAAmB;AACnB,IAAAC,mBAA0C;AAC1C,IAAAC,gBAA0D;;;ACF1D,IAAAC,mCAAkC;AAE3B,IAAM,wBAAoB;AAAA,EAC/B,CAAC,YAAY,iBAAiB,iCAAiC,wBAAwB;AAAA,EACvF;AAAA,IACE,UAAU;AAAA,MACR,OAAO;AAAA,QACL,QAAQ,CAAC;AAAA,QACT,SAAS,CAAC,YAAY;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;;;ACZA,IAAAC,gBAA0C;AAcnC,IAAM,sBAAkB,6BAA2C,IAAI;AAEvE,IAAMC,aAAY;AAElB,IAAM,cAAc,MAAM;AAC/B,QAAM,cAAU,0BAAW,eAAe;AAE1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,SAAO;AACT;;;AC1BA,IAAAC,mBAA0C;;;ACA1C,IAAAC,mCAAkC;AAE3B,IAAM,8BAA0B,sCAAI,CAAC,iBAAiB,mCAAmC,GAAG;AAAA,EACjG,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,QAAQ;AAAA,MACN,OAAO,CAAC,UAAU;AAAA,MAClB,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS,CAAC,YAAY;AAAA,MACtB,QAAQ,CAAC,WAAW;AAAA,MACpB,SAAS,CAAC,YAAY;AAAA,MACtB,OAAO,CAAC,UAAU;AAAA,MAClB,QAAQ,CAAC,UAAU;AAAA,MACnB,MAAM,CAAC,SAAS;AAAA,MAChB,SAAS,CAAC,YAAY;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA,IAIA,OAAO;AAAA,MACL,QAAQ,CAAC;AAAA,MACT,SAAS,CAAC,YAAY;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA,IAIA,iBAAiB;AAAA,MACf,MAAM,CAAC,YAAY,oBAAoB,sCAAsC;AAAA,MAC7E,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF,CAAC;;;ADJG,IAAAC,sBAAA;AArBG,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAiD;AAC/C,QAAM,EAAE,OAAO,KAAK,QAAQ,OAAO,iBAAiB,WAAW,IAAI,YAAY;AAC/E,QAAM,KAAM,MAAM,SAAS,MAAO;AAElC,QAAM,sBAAsB,CAAC,UAAiD;AAE5E,sBAAkB,KAAK;AAGvB,QAAI,SAAS,OAAO,cAAc,CAAC,iBAAiB;AAClD,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,SACE;AAAA,IAAC,iBAAAC,SAAc;AAAA,IAAd;AAAA,MACC,wBAAqB;AAAA,MACrB,WAAW,wBAAwB,EAAE,WAAW,QAAQ,OAAO,gBAAgB,CAAC;AAAA,MAChF,OAAO,EAAE,GAAG,OAAO,GAAI,CAAC,mBAAmB,EAAE,WAAW,eAAe,CAAC,KAAK,EAAG;AAAA,MAChF;AAAA,MACA,iBAAiB;AAAA,MAChB,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,kBAAkB,cAAc;;;AE9BnB,IAAAC,sBAAA;AAFN,IAAM,cAAc,CAAC;AAAA,EAC1B;AAAA,EACA,WAAW,6CAAC,qBAAkB;AAAA,EAC9B;AAAA,EACA,GAAG;AACL,MAA2C;AACzC,QAAM,EAAE,MAAM,IAAI,YAAY;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,WAAW,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAAA,MACjD;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,YAAY,cAAc;;;ALAb,IAAAC,sBAAA;AARN,IAAM,WAAW,CAAC;AAAA,EACvB;AAAA,EACA,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB;AAAA,EACA,WAAW,6CAAC,eAAY;AAAA,EACxB;AAAA,EACA,GAAG;AACL,MAAwC;AACtC,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAiB;AAE/C,QAAM,YAAQ,uBAAQ,MAAM;AAC1B,WAAO;AAAA,MACL,OAAO,aAAa;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAK,WAAW,QAAQ,OAAO,iBAAiB,YAAY,UAAU,CAAC;AAE3E,SACE,6CAAC,gBAAgB,UAAhB,EAAyB,wBAAqB,YAAW,OACxD;AAAA,IAAC,iBAAAC,SAAc;AAAA,IAAd;AAAA,MACC,wBAAqB;AAAA,MACrB;AAAA,MACA,eAAW,qCAAG,gDAAgD,SAAS;AAAA,MACvE,OAAO;AAAA,MACP,mBAAiB;AAAA,MACjB;AAAA,MACA,UAAU;AAAA,MACT,GAAG;AAAA,MAEH;AAAA;AAAA,EACH,GACF;AAEJ;AAEA,SAAS,cAAc;;;AMhEvB,4BAA6B;AAC7B,IAAAC,gBAA0D;AAyBtD,IAAAC,sBAAA;AAnBG,IAAM,gBAAgB,CAAC;AAAA,EAC5B,IAAI;AAAA,EACJ;AAAA,EACA,KAAK;AAAA,EACL,GAAG;AACL,MAA0B;AACxB,QAAM,aAAa,GAAGC,UAAS,cAAU,qBAAM,CAAC;AAChD,QAAM,KAAK,UAAU;AAErB,QAAM,EAAE,UAAU,IAAI,YAAY;AAClC,QAAM,cAAU;AAAA,IACd,CAAC,OAAwB;AACvB,gBAAU,KAAK,KAAK,MAAS;AAAA,IAC/B;AAAA,IACA,CAAC,IAAI,SAAS;AAAA,EAChB;AACA,QAAM,UAAM,oCAAa,cAAc,OAAO;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB;AAAA,MACA,WAAU;AAAA,MACV;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAEA,cAAc,cAAc;;;ACjCrB,IAAMC,YAIT,OAAO,OAAO,UAAM;AAAA,EACtB,OAAO;AAAA,EACP,KAAK;AAAA,EACL,WAAW;AACb,CAAC;AAEDA,UAAS,cAAc;AACvB,YAAY,cAAc;AAC1B,kBAAkB,cAAc;AAChC,cAAc,cAAc;;;AClB5B,mBAAsB;AACtB,IAAAC,mCAAmB;AACnB,IAAAC,iBAAuB;;;ACFvB,IAAAC,mCAAmB;AACnB,IAAAC,gBAA2E;;;ACD3E,IAAAC,yBAA6B;AAC7B,IAAAC,mCAAkC;AAElC,IAAM,kBAAkB;AAAA,EACtB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,qBAAqB;AACvB;AAEO,IAAM,oBAAgB;AAAA,EAC3B,CAAC,gBAAgB,gBAAgB,gBAAgB,aAAa,cAAc;AAAA,EAC5E;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA,MAIR,MAAM;AAAA,QACJ,SAAS,CAAC,qBAAqB;AAAA,QAC/B,IAAI,CAAC,WAAW,SAAS;AAAA,QACzB,IAAI,CAAC,WAAW,SAAS;AAAA,QACzB,MAAM,CAAC,UAAU,QAAQ;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAIA,YAAQ,qCAcN;AAAA,QACA,SAAS,CAAC,gBAAgB;AAAA,QAC1B,MAAM,CAAC,aAAa;AAAA,QACpB,SAAS,CAAC,gBAAgB;AAAA,QAC1B,QAAQ,CAAC,eAAe;AAAA,QACxB,OAAO,CAAC,cAAc;AAAA,QACtB,SAAS,CAAC,gBAAgB;AAAA,QAC1B,OAAO,CAAC,cAAc;AAAA,QACtB,OAAO,CAAC,cAAc;AAAA,QACtB,MAAM,CAAC,aAAa;AAAA,QACpB,SAAS,CAAC,gBAAgB;AAAA,MAC5B,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,qBAAqB;AAAA,QACnB,MAAM,CAAC,8BAA8B,4BAA4B;AAAA,QACjE,OAAO,CAAC,wBAAwB,sBAAsB;AAAA,MACxD;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;;;AChCgB,IAAAC,sBAAA;AAjBT,IAAM,UAAU,CAAC;AAAA,EACtB;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAuC;AACrC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,wBAAqB;AAAA,MACrB;AAAA,MACA,WAAW,cAAc,EAAE,WAAW,MAAM,QAAQ,oBAAoB,CAAC;AAAA,MACxE,GAAG;AAAA,MAEH,mBAAS,6CAAC,kBAAgB,iBAAM;AAAA;AAAA,EACnC;AAEJ;;;AChCA,IAAAC,yBAA6B;AAC7B,IAAAC,mCAAkC;;;ACDlC,IAAAC,yBAAmB;AAEZ,IAAM,iBAAiB;AAAA;AAAA,EAE5B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAEA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AClIA,IAAAC,yBAAmB;AAEZ,IAAM,gBAAgB;AAAA,EAC3B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjHA,IAAAC,yBAAmB;AAEZ,IAAM,mBAAmB;AAAA,EAC9B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjHA,IAAAC,yBAAmB;AAEZ,IAAM,iBAAiB;AAAA,EAC5B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC5HA,IAAAC,yBAAmB;AAEZ,IAAM,mBAAmB;AAAA,EAC9B;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAO,2BAAG;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ALtGO,IAAM,mBAAe;AAAA,EAC1B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAeR,YAAQ,qCAA8E;AAAA,QACpF,QAAQ,CAAC;AAAA,QACT,UAAU,CAAC,kBAAkB,aAAa,gBAAgB;AAAA,QAC1D,QAAQ,CAAC;AAAA,QACT,OAAO,CAAC,0CAA0C;AAAA,QAClD,UAAU,CAAC;AAAA,MACb,CAAC;AAAA,MACD,WAAW;AAAA,QACT,MAAM,CAAC,WAAW;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA,MAIA,YAAQ,qCAeN;AAAA,QACA,MAAM,CAAC;AAAA,QACP,SAAS,CAAC;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,OAAO,CAAC;AAAA,QACR,SAAS,CAAC;AAAA,QACV,OAAO,CAAC;AAAA,QACR,QAAQ,CAAC;AAAA,QACT,MAAM,CAAC;AAAA,QACP,SAAS,CAAC;AAAA,QACV,SAAS,CAAC;AAAA,QACV,gBAAgB,CAAC;AAAA,MACnB,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,UAAM,qCAAyC;AAAA,QAC7C,IAAI,CAAC,eAAe,SAAS;AAAA,QAC7B,IAAI,CAAC,eAAe,SAAS;AAAA,QAC7B,IAAI,CAAC,eAAe,SAAS;AAAA,MAC/B,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,WAAO,qCAAqD;AAAA,QAC1D,SAAS,CAAC,YAAY;AAAA,QACtB,QAAQ,CAAC,WAAW;AAAA,QACpB,MAAM,CAAC,cAAc;AAAA,MACvB,CAAC;AAAA;AAAA;AAAA;AAAA,MAID,UAAU;AAAA,QACR,MAAM,CAAC,sBAAsB,eAAe;AAAA,QAC5C,OAAO,CAAC,gBAAgB;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA,MAChB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;AHPU,IAAAC,uBAAA;AAxEV,IAAM,uBAAoD;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,SAAS,CAAC;AAAA,EACrB;AAAA,EACA,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,MAAmB;AACjB,QAAM,YAAY,UAAU,OAAO;AAEnC,QAAM,oBAAoB,CAAC,CAAC,YAAY;AAExC,QAAM,4BAAwB,uBAAQ,MAAM;AAC1C,UAAM,SAAiE,CAAC;AAExE,QAAI,mBAAmB;AACrB,2BAAqB,QAAQ,kBAAiB,OAAO,YAAY,IAAI,MAAU;AAAA,IACjF;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,eAAe;AAAA,IACnB,MAAM;AAAA,IACN,WAAW,cAAc,iBAAiB;AAAA,IAC1C,GAAI,gBAAgB,EAAE,cAAc,aAAa;AAAA,EACnD;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACpB,GAAI,cAAc,YAAY,EAAE,MAAM,SAAS;AAAA,MAChD;AAAA,MACA,WAAW,aAAa;AAAA,QACtB;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD,UAAU,CAAC,CAAC;AAAA,MACZ,aAAW;AAAA,MACX,aAAW,YAAY,cAAc;AAAA,MACpC,GAAG;AAAA,MACH,GAAG;AAAA,MAEH;AAAA,QAAoB;AAAA,QAAS;AAAA,QAAU,aACtC,YACE,gFACE;AAAA,wDAAC,WAAS,GAAG,cAAc;AAAA,UAC1B,eAAe;AAAA,UAEhB;AAAA,YAAC;AAAA;AAAA,cACC,eAAW;AAAA,cACX,eAAW,qCAAG,UAAU,cAAc,WAAW,uBAAuB;AAAA,cAEvE;AAAA;AAAA,UACH;AAAA,WACF,IAEA;AAAA,MAEJ;AAAA;AAAA,EACF;AAEJ;AAEA,OAAO,cAAc;;;AS9HrB,IAAAC,yBAA6B;AAC7B,IAAAC,mCAAkC;AAG3B,IAAM,uBAAmB,sCAAI,CAAC,WAAW,GAAG;AAAA,EACjD,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,UAAM,qCAAyC;AAAA,MAC7C,IAAI,CAAC,aAAa;AAAA,MAClB,IAAI,CAAC,aAAa;AAAA,MAClB,IAAI,CAAC,gBAAgB;AAAA,IACvB,CAAC;AAAA,EACH;AACF,CAAC;;;ACMG,IAAAC,uBAAA;AAXG,IAAM,aAAa,CAAC;AAAA,EACzB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAuB;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB;AAAA,MACA,WAAW,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,WAAW,cAAc;;;AXsEjB,IAAAC,uBAAA;AAzFD,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAwC;AACtC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,qBAAqB;AACzB,QAAM,gBAAY,uBAA0B,IAAI;AAGhD,QAAM,YAAY,MAAM,UAAU,OAAK,EAAE,SAAS,KAAK,QAAQ,EAAE,SAAS,KAAK,IAAI;AAEnF,QAAM,cAAc,CAAC,MAA2C;AAE9D,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAGA,eAAW,SAAS;AAGpB,0BAAsB,MAAM;AAE1B,YAAM,mBAAmB,iBAAiB,QAAQ,OAAO,OAAO;AAEhE,UAAI,iBAAiB,SAAS,GAAG;AAI/B,cAAM,cAAc,KAAK,IAAI,WAAW,iBAAiB,SAAS,CAAC;AACnE,cAAM,aAAa,iBAAiB,WAAW;AAE/C,YAAI,YAAY;AACd,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,OAAO;AAEL,cAAM,cAAc;AAAA,UAClB,CAAC,WAAW,SAAS,YAAY,OAAO;AAAA,UACxC;AAAA,QACF;AACA,YAAI,aAAa;AACf,sBAAY,MAAM;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAC;AAED,cAAU,CAAC;AAAA,EACb;AAEA,QAAM,SAAS,CAAC,SAAmC;AACjD,cAAU,UAAU;AACpB,QAAI,MAAM;AAER,aAAO,iBAAiB,QAAQ,UAAU,WAAW;AACnD,yBAAiB,QAAQ,KAAK,IAAW;AAAA,MAC3C;AACA,uBAAiB,QAAQ,SAAS,IAAI;AAAA,IACxC,OAAO;AAEL,UAAI,iBAAiB,QAAQ,SAAS,GAAG;AACvC,yBAAiB,QAAQ,SAAS,IAAI;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,wBAAqB;AAAA,MACrB,eAAW,qCAAG,SAAS;AAAA,MACvB,SAAS;AAAA,MACT,UAAU,YAAY;AAAA,MACtB,MAAK;AAAA,MACL,QAAO;AAAA,MACP,QAAO;AAAA,MACN,GAAG;AAAA,MAEJ,wDAAC,QAAK,MAAK,MACT,wDAAC,sBAAM,GACT;AAAA;AAAA,EACF;AAEJ;AAEA,kBAAkB,cAAc;;;Ab7CxB,IAAAC,uBAAA;AApCD,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAmC;AACjC,QAAM,EAAE,OAAO,IAAI,qBAAqB;AACxC,QAAM,CAAC,cAAc,eAAe,QAAI,yBAAS,mBAAmB,MAAS;AAE7E,gCAAU,MAAM;AAEd,QAAI,mBAAmB,QAAW;AAChC,sBAAgB,IAAI;AAAA,IACtB,OAAO;AACL,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,6BAAyB,4BAAY,MAAM;AAC/C,oBAAgB,KAAK;AAAA,EACvB,GAAG,CAAC,CAAC;AAEL,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,sDAAC,SAAI,WAAU,+EACb,wDAAC,QAAK,MAAK,MAAM,sBAAY,IAAI,GAAE,GACrC;AAAA,QAEA,+CAAC,SAAI,WAAU,0FACb;AAAA,wDAAC,OAAE,WAAU,oCAAoC,eAAK,MAAK;AAAA,UAC3D,8CAAC,OAAE,WAAU,8BAA8B,yBAAe,KAAK,MAAM,MAAM,GAAE;AAAA,UAC5E,gBAAgB,mBAAmB,UAClC,8CAAC,SAAI,WAAU,mCACb;AAAA,YAACC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,KAAK;AAAA,cACL,cAAY;AAAA,cACZ,YAAY;AAAA;AAAA,UACd,GACF;AAAA,WAEJ;AAAA,QAEA,8CAAC,qBAAkB,cAAY,uBAAuB,MAAY;AAAA;AAAA;AAAA,EACpE;AAEJ;AAEA,aAAa,cAAc;;;AyBpEvB,IAAAC,uBAAA;AAJG,IAAM,UAAU,CAAC,EAAE,SAAS,MAA8B;AAC/D,QAAM,EAAE,QAAQ,CAAC,GAAG,gBAAgB,CAAC,GAAG,OAAO,IAAI,qBAAqB;AAExE,SACE,+EACG,mBAAS;AAAA,IACR,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,GACH;AAEJ;AAEA,QAAQ,cAAc;;;AChCtB,IAAAC,oCAAmB;AACnB,IAAAC,iBAAkD;AAkE5C,IAAAC,uBAAA;AA7DC,IAAM,sBAAkB,8BAAuB,KAAK;AAEpD,IAAM,qBAAqB,UAAM,2BAAW,eAAe;AAE3D,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAIG;AACD,QAAM,MAAM,qBAAqB;AACjC,QAAM,kBAAc,uBAAuB,IAAI;AAE/C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,qDAAqD;AAE/E,QAAM,aAAa,CAAC,MAAuB;AACzC,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,MAAE,cAAc,aAAa,kBAAkB,OAAO;AAGtD,QAAI,IAAI,YAAY,IAAI,UAAU;AAChC;AAAA,IACF;AAEA,UAAM,QAAQ,EAAE,aAAa;AAI7B,QAAI,aAAqB,CAAC;AAC1B,QAAI,OAAO;AACT,mBAAa,MAAM,QAAQ,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,MAAM,KAAK,KAAK;AAAA,IACnE;AAEA,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI,SAAS,UAAU;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,cAAc,MAAM;AACxB,QAAI,CAAC,IAAI,YAAY,CAAC,IAAI,UAAU;AAClC,UAAI,SAAS,SAAS,MAAM;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,MAA2B;AAChD,QAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,QAAE,eAAe;AACjB,UAAI,CAAC,IAAI,YAAY,CAAC,IAAI,UAAU;AAClC,YAAI,SAAS,SAAS,MAAM;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,YAAY,IAAI;AAEvC,SACE,8CAAC,gBAAgB,UAAhB,EAAyB,OAAO,MAC/B;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,UAAQ;AACX,oBAAY,UAAU;AACtB,YAAI,IAAI,aAAa;AACnB,cAAI,YAAY,UAAU;AAAA,QAC5B;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACL,UAAU,aAAa,KAAK;AAAA,MAC5B,iBAAe,IAAI,WAAW,OAAO;AAAA,MACrC,oBAAkB,IAAI;AAAA,MACtB,gBAAc,IAAI;AAAA,MAClB,iBAAe,IAAI;AAAA,MACnB,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,YAAY,OAAK;AACf,UAAE,eAAe;AAAA,MACnB;AAAA,MACA,WACE,WACI,gBACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,cAAc;AAAA,QACf;AAAA;AAAA,QAEA,IAAI,YAAY;AAAA;AAAA,QAEhB,IAAI,YAAY,CAAC,IAAI,YAAY;AAAA,QACjC;AAAA,MACF;AAAA,MAEN,aAAa,OAAK;AAChB,YAAI,CAAC,YAAY;AACf,YAAE,cAAc,aAAa,kBAAkB,MAAM;AAAA,QACvD;AAAA,MACF;AAAA,MACA,aAAa,OAAK;AAChB,UAAE,cAAc,aAAa,kBAAkB,OAAO;AAAA,MACxD;AAAA,MAEC;AAAA;AAAA,EACH,GACF;AAEJ;AAEA,SAAS,cAAc;;;ACtHvB,IAAAC,oCAAmB;AACnB,IAAAC,iBAAmE;AAsC7D,IAAAC,uBAAA;AAvBC,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,GAAG;AACL,MAAmC;AACjC,QAAM,CAAC,YAAY,aAAa,QAAI,yBAAS,KAAK;AAClD,QAAM,CAAC,aAAa,cAAc,QAAI,yBAAS,KAAK;AAEpD,QAAM,UAAU,KAAK,KAAK,WAAW,QAAQ;AAC7C,QAAM,WAAW,UAAU,IAAI,gBAAgB,IAAI,IAAI;AAGvD,gCAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,UAAU;AACZ,YAAI,gBAAgB,QAAQ;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,MAAI,CAAC,WAAW,YAAY;AAC1B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,wBAAqB;AAAA,QACrB,eAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,eAAW,sCAAG,wCAAwC,SAAS;AAAA,MAC9D,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK,KAAK;AAAA,YACV,eAAW,sCAAG,0BAA0B,CAAC,eAAe,WAAW;AAAA,YACnE,QAAQ,MAAM,eAAe,IAAI;AAAA,YACjC,SAAS,MAAM,cAAc,IAAI;AAAA;AAAA,QACnC;AAAA,QACC,CAAC,eACA,8CAAC,SAAI,WAAU,qDAAqD,oBAAS;AAAA;AAAA;AAAA,EAEjF;AAEJ;AAEA,aAAa,cAAc;;;ACxE3B,4BAA+B;AAC/B,IAAAC,oCAAmB;;;ACDnB,IAAAC,gBAAsB;AACtB,IAAAC,oCAAmB;AACnB,IAAAC,iBAAuB;AA0Gf,IAAAC,uBAAA;AA3FD,IAAM,4BAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAgD;AAC9C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,qBAAqB;AACzB,QAAM,gBAAY,uBAA0B,IAAI;AAGhD,QAAM,oBAAoB,cAAc;AAAA,IACtC,QAAM,GAAG,KAAK,SAAS,aAAa,KAAK,QAAQ,GAAG,KAAK,SAAS,aAAa,KAAK;AAAA,EACtF;AAEA,QAAM,cAAc,CAAC,MAA2C;AAE9D,QAAI,YAAY,UAAU;AACxB;AAAA,IACF;AAGA,uBAAmB,iBAAiB;AAGpC,0BAAsB,MAAM;AAE1B,YAAM,mBAAmB,6BAA6B,QAAQ,OAAO,OAAO;AAE5E,UAAI,iBAAiB,SAAS,GAAG;AAI/B,cAAM,cAAc,KAAK,IAAI,mBAAmB,iBAAiB,SAAS,CAAC;AAC3E,cAAM,aAAa,iBAAiB,WAAW;AAE/C,YAAI,YAAY;AACd,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,OAAO;AAEL,cAAM,cAAc;AAAA,UAClB,CAAC,WAAW,SAAS,YAAY,OAAO;AAAA,UACxC;AAAA,QACF;AACA,YAAI,aAAa;AACf,sBAAY,MAAM;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAC;AAED,cAAU,CAAC;AAAA,EACb;AAEA,QAAM,SAAS,CAAC,SAAmC;AACjD,cAAU,UAAU;AACpB,QAAI,MAAM;AAER,aAAO,6BAA6B,QAAQ,UAAU,mBAAmB;AACvE,qCAA6B,QAAQ,KAAK,IAAW;AAAA,MACvD;AACA,mCAA6B,QAAQ,iBAAiB,IAAI;AAAA,IAC5D,OAAO;AAEL,UAAI,6BAA6B,QAAQ,iBAAiB,GAAG;AAC3D,qCAA6B,QAAQ,iBAAiB,IAAI;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,wBAAqB;AAAA,MACrB,eAAW,sCAAG,SAAS;AAAA,MACvB,SAAS;AAAA,MACT,UAAU,YAAY;AAAA,MACtB,MAAK;AAAA,MACL,QAAO;AAAA,MACP,QAAO;AAAA,MACN,GAAG;AAAA,MAEJ,wDAAC,QAAK,MAAK,MACT,wDAAC,uBAAM,GACT;AAAA;AAAA,EACF;AAEJ;AAEA,0BAA0B,cAAc;;;AD3D9B,IAAAC,uBAAA;AAvBH,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAmC;AACjC,QAAM,EAAE,OAAO,IAAI,qBAAqB;AAExC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,wBAAqB;AAAA,MACrB,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,sDAAC,SAAI,WAAU,6EACb,wDAAC,QAAK,MAAK,MAAK,WAAU,cACxB,wDAAC,wCAAe,GAClB,GACF;AAAA,QAEA,8CAAC,SAAI,WAAU,kBACb,yDAAC,SAAI,WAAU,wBACb;AAAA,yDAAC,SAAI,WAAU,qDACb;AAAA,0DAAC,OAAE,WAAU,oCAAoC,uBAAa,KAAK,MAAK;AAAA,YACxE,8CAAC,OAAE,WAAU,8BACV,yBAAe,aAAa,KAAK,MAAM,MAAM,GAChD;AAAA,aACF;AAAA,UACA,8CAAC,SAAI,WAAU,wBACZ,uBAAa,OAAO,IAAI,CAAC,OAAO,eAC/B,8CAAC,SAAqB,WAAU,2BAA0B,mBAAiB,OACxE,sBAAY,KAAK,KADV,UAEV,CACD,GACH;AAAA,WACF,GACF;AAAA,QAEA,8CAAC,6BAA0B,cAAY,uBAAuB,cAA4B;AAAA;AAAA;AAAA,EAC5F;AAEJ;AAEA,aAAa,cAAc;;;AElF3B,IAAAC,oCAAmB;AAyGV,IAAAC,uBAAA;AAzFF,IAAM,UAAU,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR;AAAA,EACA,GAAG;AACL,MAA8B;AAC5B,QAAM,EAAE,UAAU,YAAY,UAAU,UAAU,aAAa,WAAW,WAAW,IACnF,qBAAqB;AACvB,QAAM,mBAAmB,mBAAmB;AAE5C,QAAM,cAAc,CAAC,MAAwB;AAC3C,MAAE,gBAAgB;AAClB,MAAE,eAAe;AACjB,QAAI,CAAC,YAAY,CAAC,UAAU;AAC1B,eAAS,SAAS,MAAM;AAAA,IAC1B;AAAA,EACF;AAGA,QAAM,YAAY,CAAC,SAA6B;AAE9C,QAAI,YAAY;AACd,iBAAW,UAAU;AAAA,IACvB;AACA,QAAI,KAAK;AACP,UAAI,OAAO,QAAQ,YAAY;AAC7B,YAAI,IAAyB;AAAA,MAC/B,OAAO;AACL,YAAI,UAAU;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAKA,MAAI;AACJ,MAAI;AAEJ,MAAI,kBAAkB;AAEpB,gBAAY;AACZ,UAAM,aAAa,WACf,YACA,aAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,YAAY;AAAA,MACtB;AAAA,IACF,CAAC;AAEL,qBAAiB;AAAA,MACf,KAAK;AAAA,MACL,wBAAwB;AAAA,MACxB,WAAW;AAAA;AAAA;AAAA,IAGb;AAAA,EACF,OAAO;AAEL,UAAM,kBAAkB,WAAW,WAAW;AAC9C,gBAAY,UAAU,OAAO;AAE7B,qBAAiB;AAAA,MACf,KAAK;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,wBAAwB;AAAA,MACxB,eAAW,sCAAG,SAAS;AAAA,MACvB,UAAU,YAAY;AAAA,MACtB,SAAS;AAAA,MACT,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,GAAG;AAAA,IACL;AAAA,EACF;AAEA,SAAO,8CAAC,aAAW,GAAG,gBAAiB,UAAS;AAClD;AAEA,QAAQ,cAAc;;;AnChFf,IAAMC,cAST,OAAO,OAAO,YAAM;AAAA;AAAA,EAEtB;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEDA,YAAW,cAAc;AACzB,QAAQ,cAAc;AACtB,SAAS,cAAc;AACvB,QAAQ,cAAc;AACtB,kBAAkB,cAAc;AAChC,aAAa,cAAc;AAC3B,aAAa,cAAc;AAC3B,aAAsB,cAAc;AACpC,0BAA0B,cAAc;","names":["FileUpload","import_react","import_react","extension","fileName","formatter","import_class_variance_authority","import_react","import_react","import_react","import_jsx_runtime","RadixSlot","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_radix_ui","import_react","import_class_variance_authority","import_react","ID_PREFIX","import_radix_ui","import_class_variance_authority","import_jsx_runtime","RadixProgress","import_jsx_runtime","import_jsx_runtime","RadixProgress","import_react","import_jsx_runtime","ID_PREFIX","Progress","import_class_variance_authority","import_react","import_class_variance_authority","import_react","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_internal_utils","import_jsx_runtime","import_internal_utils","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","Progress","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_react","import_jsx_runtime","import_class_variance_authority","import_Close","import_class_variance_authority","import_react","import_jsx_runtime","import_jsx_runtime","import_class_variance_authority","import_jsx_runtime","FileUpload"]}