@alextheman/components 6.23.0 → 6.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Fragment","QueryBoundaryProvider","Button","MUIButton","useDropdownMenu","DropdownMenu","DropdownMenuItem","useDropdownMenu","useDropdownMenuV7","DropdownMenu","DropdownMenuItemV7","ReactDOMLink","QueryBoundaryProvider","Fragment"],"sources":["../src/components/Artwork.tsx","../src/components/CollapsableItem.tsx","../src/components/ExternalLink.tsx","../src/components/FileInput.tsx","../src/components/FileInputList.tsx","../src/components/SwitchWithIcons.tsx","../src/providers/ModeProvider.tsx","../src/providers/QueryBoundaryProvider/QueryBoundaryProvider.tsx","../src/providers/QueryBoundaryProvider/QueryBoundaryData.tsx","../src/providers/QueryBoundaryProvider/QueryBoundaryDataMap.tsx","../src/providers/QueryBoundaryProvider/QueryBoundaryError.tsx","../src/providers/QueryBoundaryProvider/QueryBoundaryNullable.tsx","../src/providers/QueryBoundaryProvider/QueryBoundaryFallback.tsx","../src/providers/QueryBoundaryProvider/index.tsx","../src/providers/ScreenSizeProvider.tsx","../src/providers/SnackbarProvider.tsx","../src/components/ModeToggle.tsx","../src/components/Page.tsx","../src/hooks/createQueryBoundary.tsx","../src/hooks/useDebounce.ts","../src/hooks/useHash.ts","../src/components/QueryBoundaryMap.tsx","../src/components/QueryBoundaryWrapper.tsx","../src/components/ReactPlayground.tsx","../src/components/SkeletonRow.tsx","../src/deprecated/DarkModeToggle.tsx","../src/deprecated/DropdownMenu.tsx","../src/v7/components/DropdownMenu/DropdownMenuProvider.tsx","../src/v7/components/DropdownMenu/DropdownMenu.tsx","../src/v7/components/DropdownMenu/DropdownMenuItem.tsx","../src/deprecated/DropdownMenu2/DropdownMenu2.tsx","../src/deprecated/DropdownMenu2/DropdownMenuItem.tsx","../src/deprecated/DropdownMenu2/index.tsx","../src/deprecated/DropdownMenuExternalLink.tsx","../src/deprecated/InternalLink.tsx","../src/deprecated/DropdownMenuInternalLink.tsx","../src/deprecated/IconWithPopover.tsx","../src/deprecated/ListItemInternalLink.tsx","../src/deprecated/Loader.tsx","../src/deprecated/LoaderData.tsx","../src/deprecated/LoaderError.tsx","../src/deprecated/LoaderProvider.tsx","../src/deprecated/NavigationBottom.tsx","../src/deprecated/NavigationDrawer.tsx","../src/deprecated/PopoverText.tsx","../src/deprecated/QueryBoundary.tsx","../src/deprecated/SubmitButton.tsx"],"sourcesContent":["import Box from \"@mui/material/Box\";\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Chip from \"@mui/material/Chip\";\nimport Divider from \"@mui/material/Divider\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface ContainerProps {\n containerLabel: string;\n chipLabels: Array<string>;\n}\n\nfunction Container({ containerLabel, chipLabels }: ContainerProps) {\n return (\n <Card\n sx={{\n width: 320,\n height: 420,\n backgroundColor: \"rgba(255,255,255,0.07)\",\n backdropFilter: \"blur(8px)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n boxShadow: \"0 10px 40px rgba(0,0,0,0.35)\",\n }}\n >\n <CardContent>\n <Typography variant=\"h6\" gutterBottom sx={{ color: \"#f8fafc\" }}>\n {containerLabel}\n </Typography>\n\n <Stack spacing={1}>\n {chipLabels.map((label) => {\n return (\n <Chip\n key={label}\n label={label}\n sx={{\n backgroundColor: \"rgba(255,255,255,0.11)\",\n color: \"rgba(255,255,255,0.88)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n }}\n />\n );\n })}\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nfunction Connector() {\n return (\n <Box\n sx={{\n width: 120,\n height: 6,\n borderRadius: 3,\n background: \"linear-gradient(90deg, #f43f5e, #a78bfa, #22d3ee)\",\n boxShadow: \"0 0 24px rgba(167,139,250,0.55)\",\n }}\n />\n );\n}\n\n/** The artwork associated with the package's theme song, _An Interface For You And I_. */\nfunction Artwork() {\n return (\n <Card\n sx={{\n width: 1000,\n height: 1000,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n p: 4,\n background:\n \"radial-gradient(circle at 20% 10%, rgba(167,139,250,0.35) 0%, rgba(167,139,250,0.12) 35%, rgba(0,0,0,0) 55%), linear-gradient(135deg, #3a3380 0%, #1d2e5f 40%, #2d3f55 100%)\",\n color: \"white\",\n }}\n elevation={0}\n >\n <CardHeader\n title=\"An Interface For You And I\"\n sx={{\n color: \"#f8fafc\",\n textAlign: \"center\",\n \"& .MuiCardHeader-title\": {\n fontSize: 40,\n fontWeight: 600,\n letterSpacing: 2,\n },\n }}\n />\n\n <Divider sx={{ borderColor: \"rgba(255,255,255,0.2)\" }} />\n\n <CardContent sx={{ flex: 1, display: \"flex\", alignItems: \"center\" }}>\n <Stack\n direction=\"row\"\n spacing={4}\n sx={{ width: \"100%\", justifyContent: \"center\", alignItems: \"center\" }}\n >\n <Container\n containerLabel=\"You\"\n chipLabels={[\"state\", \"context\", \"input\", \"event\", \"focus\", \"value\", \"history\"]}\n />\n <Connector />\n <Container\n containerLabel=\"I\"\n chipLabels={[\"render\", \"effect\", \"response\", \"update\", \"history\", \"layout\", \"provider\"]}\n />\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nexport default Artwork;\n","import type { CollapseProps } from \"@mui/material/Collapse\";\nimport type { SxProps } from \"@mui/material/styles\";\nimport type { ElementType, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport ButtonBase from \"@mui/material/ButtonBase\";\nimport Collapse from \"@mui/material/Collapse\";\nimport { useEffect, useState } from \"react\";\nimport { MdArrowDropDown, MdArrowDropUp } from \"react-icons/md\";\n\nexport interface CollapsableItemProps {\n /** Whether the item should initially be open or not. */\n isInitiallyOpen?: boolean;\n /** A callback function to execute when the item is open. */\n onOpen?: () => void;\n /** A callback function to execute when the item is closed. */\n onClose?: () => void;\n /** The components to render when the item is open. */\n children: ReactNode;\n /** Styling for the button. */\n buttonStyles?: SxProps;\n /** The children to pass to the button. */\n buttonContents: ReactNode;\n /** The specific button component to use. */\n buttonComponent?: ElementType;\n /** The icon to show next to the button when open. */\n openIcon?: ReactNode;\n /** The icon to show next to the button when closed. */\n closedIcon?: ReactNode;\n /** Props to pass to collapse. */\n collapseProps?: Omit<CollapseProps, \"in\">;\n /**\n * Whether or not to use the default button styling.\n *\n * Defaults to `true` if `buttonComponent` is `ButtonBase`,\n * otherwise defaults to `false`.\n */\n useDefaultStyling?: boolean;\n}\n\n/**\n * Shows a display area that can be opened to show the children components, or hidden away.\n */\nfunction CollapsableItem({\n isInitiallyOpen,\n onOpen,\n onClose,\n children,\n buttonStyles,\n buttonContents,\n buttonComponent: ButtonComponent = ButtonBase,\n collapseProps,\n openIcon = <MdArrowDropUp />,\n closedIcon = <MdArrowDropDown />,\n useDefaultStyling = ButtonComponent === ButtonBase ? true : false,\n}: CollapsableItemProps) {\n const [isItemOpen, setIsItemOpen] = useState<boolean>(!!isInitiallyOpen);\n\n useEffect(() => {\n if (isItemOpen && onOpen) {\n onOpen();\n } else if (!isItemOpen && onClose) {\n onClose();\n }\n }, [isItemOpen]);\n\n return (\n <Box>\n <ButtonComponent\n onClick={() => {\n setIsItemOpen((previouslyOpen) => {\n return !previouslyOpen;\n });\n }}\n sx={\n useDefaultStyling\n ? {\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n paddingY: 1.5,\n paddingX: 2,\n textAlign: \"center\",\n \"&:hover\":\n ButtonComponent === ButtonBase ? { backgroundColor: \"action.hover\" } : null,\n ...buttonStyles,\n }\n : buttonStyles\n }\n aria-expanded={isItemOpen}\n >\n {buttonContents}\n {isItemOpen ? openIcon : closedIcon}\n </ButtonComponent>\n <Collapse in={isItemOpen} {...collapseProps}>\n {children}\n </Collapse>\n </Box>\n );\n}\n\nexport default CollapsableItem;\n","import type { LinkProps } from \"@mui/material/Link\";\nimport type { ReactNode, Ref } from \"react\";\n\nimport MUILink from \"@mui/material/Link\";\n\nexport interface ExternalLinkProps extends Omit<LinkProps, \"to\" | \"target\" | \"rel\"> {\n /** The URL of the place you want to navigate to. */\n href: `https://${string}` | `http://${string}` | (string & {});\n to?: never;\n /** The readable content to display on the link. */\n children: ReactNode;\n /** An optional ref to allow it to be used with polymorphic components. */\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A stylised link that is best used when you want to navigate to a different domain.\n *\n * Opens the destination in a new tab and applies recommended security defaults automatically.\n */\nfunction ExternalLink({ href, children, ref, ...linkProps }: ExternalLinkProps) {\n return (\n <MUILink\n component=\"a\"\n href={href}\n ref={ref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {...linkProps}\n >\n {children}\n </MUILink>\n );\n}\n\nexport default ExternalLink;\n","import type { CreateEnumType } from \"@alextheman/utility\";\nimport type { ButtonOwnProps } from \"@mui/material/Button\";\n\nimport Button from \"@mui/material/Button\";\nimport { styled } from \"@mui/material/styles\";\nimport { useId, useState } from \"react\";\nimport { MdCloudUpload } from \"react-icons/md\";\n\nexport const FileType = {\n PDF: \"application/pdf\",\n PNG: \"image/png\",\n JPEG: \"image/jpeg\",\n JPG: \"image/jpg\",\n XLSX: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n DOCX: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n MP3: \"audio/mp3\",\n MP4: \"video/mp4\",\n WAV: \"audio/wav\",\n} as const;\nexport type FileType = CreateEnumType<typeof FileType>;\n\nconst VisuallyHiddenInput = styled(\"input\")({\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: 1,\n overflow: \"hidden\",\n position: \"absolute\",\n bottom: 0,\n left: 0,\n whiteSpace: \"nowrap\",\n width: 1,\n});\n\nconst Dropzone = styled(\"div\")<{ $dragging: boolean }>(({ theme, $dragging }) => {\n return {\n border: \"2px dashed\",\n borderColor: $dragging ? theme.palette.primary.main : \"#ccc\",\n backgroundColor: $dragging ? theme.palette.action.hover : \"transparent\",\n borderRadius: 8,\n padding: \"1.5rem\",\n textAlign: \"center\",\n transition: \"border-color 0.2s\",\n cursor: \"pointer\",\n };\n});\n\nexport interface FileInputProps extends ButtonOwnProps {\n /** A function to run when a file has been uploaded. */\n onFileInput: (allowedFiles: Array<File>) => void;\n /** The label to display on the input button (defaults to \"Upload files\") */\n label?: string;\n /** Whether to accept multiple files or not. */\n multiple?: boolean;\n /** An array of file types to accept. */\n accept?: Array<string>;\n /** Enable the dropzone, allowing users to drag and drop files. */\n useDropzone?: boolean;\n}\n\n/** Handles file inputs. */\nfunction FileInput({\n onFileInput,\n label = \"Upload files\",\n multiple,\n accept,\n useDropzone,\n ...buttonProps\n}: FileInputProps) {\n const [isDragging, setIsDragging] = useState<boolean>(false);\n const id = useId();\n\n const fileInputButton = (\n <Button\n variant=\"contained\"\n component=\"label\"\n aria-label=\"File input button\"\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n document.getElementById(id)?.click();\n }\n }}\n {...buttonProps}\n startIcon={buttonProps.startIcon ?? <MdCloudUpload />}\n >\n {label}\n <VisuallyHiddenInput\n id={id}\n type=\"file\"\n onChange={(event) => {\n const input = event.target;\n onFileInput(Array.from(input.files ?? []));\n input.value = \"\";\n }}\n multiple={multiple}\n accept={accept?.join(\",\")}\n disabled={buttonProps.disabled}\n />\n </Button>\n );\n\n return useDropzone ? (\n <Dropzone\n $dragging={isDragging}\n onDragOver={(event) => {\n event.preventDefault();\n if (buttonProps.disabled) {\n return;\n }\n setIsDragging(true);\n }}\n onDragLeave={(event) => {\n event.preventDefault();\n setIsDragging(false);\n }}\n onDrop={(event) => {\n event.preventDefault();\n setIsDragging(false);\n if (buttonProps.disabled) {\n return;\n }\n const filesArray = Array.from(event.dataTransfer.files ?? []);\n onFileInput(filesArray);\n }}\n >\n {fileInputButton}\n </Dropzone>\n ) : (\n fileInputButton\n );\n}\n\nexport default FileInput;\n","import type { Dispatch, SetStateAction } from \"react\";\n\nimport type { FileInputProps } from \"src/components/FileInput\";\n\nimport Box from \"@mui/material/Box\";\nimport IconButton from \"@mui/material/IconButton\";\nimport List from \"@mui/material/List\";\nimport ListItem from \"@mui/material/ListItem\";\nimport ListItemText from \"@mui/material/ListItemText\";\nimport { MdDelete } from \"react-icons/md\";\n\nimport FileInput from \"src/components/FileInput\";\n\nexport interface FileInputListProps extends Omit<FileInputProps, \"onFileInput\"> {\n /** The array of files (must be a React state). */\n files: Array<File>;\n /** The state setter for the array of files. */\n setFiles: Dispatch<SetStateAction<Array<File>>>;\n}\n\n/** Renders the `FileInput` component with a list of uploaded files underneath it. */\nfunction FileInputList({\n files,\n setFiles,\n multiple = true,\n ...fileInputProps\n}: FileInputListProps) {\n function onFileInput(newFiles: Array<File>) {\n setFiles((oldFiles) => {\n return [...oldFiles, ...newFiles];\n });\n }\n\n return (\n <Box>\n <FileInput {...fileInputProps} multiple={multiple} onFileInput={onFileInput} />\n <List>\n {files.map((file) => {\n return (\n <ListItem\n key={`${file.name}-${file.lastModified}`}\n secondaryAction={\n <IconButton\n aria-label=\"Delete\"\n edge=\"end\"\n onClick={() => {\n setFiles((oldFiles) => {\n return oldFiles.filter((fileToDelete) => {\n return fileToDelete !== file;\n });\n });\n }}\n >\n <MdDelete />\n </IconButton>\n }\n >\n <ListItemText primary={file.name} />\n </ListItem>\n );\n })}\n </List>\n </Box>\n );\n}\n\nexport default FileInputList;\n","import type { CommonProps } from \"@mui/material/OverridableComponent\";\nimport type { SwitchProps } from \"@mui/material/Switch\";\nimport type { ComponentType, CSSProperties } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport { styled } from \"@mui/material/styles\";\nimport Switch from \"@mui/material/Switch\";\n\nexport interface SwitchWithIconsProps extends Omit<SwitchProps, \"icon\" | \"checkedIcon\"> {\n /** The icon to show when the switch is in a checked state. */\n checkedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when checked. */\n checkedIconStyles?: CommonProps[\"style\"];\n /** The icon to show when the switch is in an unchecked state. */\n uncheckedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when unchecked. */\n uncheckedIconStyles?: CommonProps[\"style\"];\n}\n\nconst StyledSwitch = styled(Switch)(() => {\n return {\n padding: 8,\n \"& .MuiSwitch-track\": {\n borderRadius: 11,\n \"&::before, &::after\": {\n content: '\"\"',\n position: \"absolute\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n fontSize: 16,\n width: 28,\n height: 28,\n },\n },\n };\n});\n\n/** Renders a switch with your provided icons. */\nfunction SwitchWithIcons({\n checkedIcon: CheckedIcon,\n checkedIconStyles,\n uncheckedIcon: UncheckedIcon,\n uncheckedIconStyles,\n ...switchProps\n}: SwitchWithIconsProps) {\n const boxSx = {\n borderRadius: \"50%\",\n borderColor: \"white\",\n backgroundColor: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 0.25,\n };\n const defaultIconStyles = { color: \"black\", maxWidth: 16.5, maxHeight: 16.5 };\n return (\n <StyledSwitch\n checkedIcon={\n <Box sx={boxSx}>\n <CheckedIcon style={{ ...defaultIconStyles, ...checkedIconStyles }} />\n </Box>\n }\n icon={\n <Box sx={boxSx}>\n <UncheckedIcon style={{ ...defaultIconStyles, ...uncheckedIconStyles }} />\n </Box>\n }\n {...switchProps}\n />\n );\n}\n\nexport default SwitchWithIcons;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { PaletteMode } from \"@mui/material/styles\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport CssBaseline from \"@mui/material/CssBaseline\";\nimport { createTheme, ThemeProvider } from \"@mui/material/styles\";\nimport { createContext, useContext, useMemo, useState } from \"react\";\n\nexport interface ModeContextValue {\n toggleMode: () => void;\n mode: PaletteMode;\n}\n\nconst ModeContext = createContext<ModeContextValue>({\n toggleMode: () => {},\n mode: \"dark\",\n});\n\n/** Access the mode context directly. */\nexport function useMode<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, ModeContextValue> {\n const context = useContext(ModeContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"MODE_PROVIDER_NOT_FOUND\",\n \"Could not find the ModeProvider context. Please double-check that it is present.\",\n );\n }\n return context;\n}\n\nexport interface ModeProviderProps {\n /** The children that will have access to the current mode. */\n children: ReactNode;\n /** The initial mode. */\n mode?: PaletteMode;\n}\n\n/** Provides information about the current theme mode to its children components. */\nfunction ModeProvider({ children, mode: modeProp = \"dark\" }: ModeProviderProps) {\n const [mode, setMode] = useState<PaletteMode>(modeProp);\n\n const theme = useMemo(() => {\n return createTheme({\n palette: {\n mode,\n },\n components: {\n MuiPaper: {\n styleOverrides: {\n root: ({ theme }) => {\n return {\n border: 1,\n borderStyle: \"solid\",\n borderColor: theme.palette.divider,\n };\n },\n },\n },\n },\n });\n }, [mode]);\n\n return (\n <ModeContext.Provider\n value={{\n mode,\n toggleMode: () => {\n setMode((prev) => {\n return prev === \"light\" ? \"dark\" : \"light\";\n });\n },\n }}\n >\n <ThemeProvider theme={theme}>\n <CssBaseline />\n {children}\n </ThemeProvider>\n </ModeContext.Provider>\n );\n}\n\nexport default ModeProvider;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\nimport { createContext, useContext } from \"react\";\n\nexport interface QueryBoundaryProviderBaseProps<DataType> {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The data being loaded. */\n data?: DataType | null | undefined;\n /** A parser for the data. */\n dataParser?: (data: unknown) => NonNullable<DataType>;\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n}\n\nexport interface QueryBoundaryProviderPropsWithNoError<\n DataType,\n> extends QueryBoundaryProviderBaseProps<DataType> {\n error?: never;\n errorComponent?: never;\n logError?: never;\n}\n\nexport interface QueryBoundaryProviderPropsWithError<\n DataType,\n> extends QueryBoundaryProviderBaseProps<DataType> {\n /** The error given if the request gave an error. */\n error: unknown;\n /** The component to show if an error has been thrown. Note that this may not be provided unless the error prop has also been provided. */\n errorComponent?: ReactNode | ((error: unknown) => ReactNode);\n /** Whether you want to log the error to the console or not. */\n logError?: boolean;\n}\n\nexport type QueryBoundaryContextValue<DataType> =\n | QueryBoundaryProviderPropsWithNoError<DataType>\n | QueryBoundaryProviderPropsWithError<DataType>;\nexport type QueryBoundaryProviderProps<DataType> = QueryBoundaryContextValue<DataType> & {\n children: ReactNode;\n};\n\nconst QueryBoundaryContext = createContext<QueryBoundaryContextValue<unknown> | undefined>(\n undefined,\n);\n\n/** Access the QueryBoundary context directly. */\nexport function useQueryBoundary<DataType, Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<\n Strict,\n QueryBoundaryContextValue<DataType>\n> {\n const context = useContext(QueryBoundaryContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"QUERY_BOUNDARY_PROVIDER_NOT_FOUND\",\n \"Could not find the QueryBoundaryProvider context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, QueryBoundaryContextValue<DataType>>;\n}\n\n/**\n * A provider for a context that deals with state management when fetching data from an API.\n * This may be used over QueryBoundary if you require more control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryProvider<DataType>({\n children,\n loadingComponent = <CircularProgress />,\n ...contextProps\n}: QueryBoundaryProviderProps<DataType>) {\n return (\n <QueryBoundaryContext.Provider value={{ loadingComponent, ...contextProps }}>\n {children}\n </QueryBoundaryContext.Provider>\n );\n}\n\nexport default QueryBoundaryProvider;\n","import type { ReactNode } from \"react\";\n\nimport { useQueryBoundary } from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryDataProps<DataType> {\n /**\n * The elements to show after data has been loaded.\n * This is best provided as a function with a data argument that guarantees the data will not be undefined by the time you receive it here.\n */\n children: ReactNode | ((data: NonNullable<DataType>) => ReactNode);\n /** A parser for the data. */\n dataParser?: (data: unknown) => NonNullable<DataType>;\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n}\n\n/**\n * The component responsible for showing the data provided by QueryBoundaryProvider.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryData<DataType>({\n children,\n dataParser: propDataParser,\n loadingComponent,\n}: QueryBoundaryDataProps<DataType>) {\n const {\n isLoading,\n data,\n dataParser: contextDataParser,\n loadingComponent: contextLoadingComponent,\n error,\n } = useQueryBoundary<DataType>();\n const dataParser = propDataParser ?? contextDataParser;\n\n if (error) {\n return null;\n }\n\n if (isLoading) {\n return <>{loadingComponent ?? contextLoadingComponent}</>;\n }\n\n if (data === null || data === undefined) {\n return null;\n }\n\n return (\n <>\n {typeof children === \"function\" ? children(dataParser ? dataParser(data) : data) : children}\n </>\n );\n}\n\nexport default QueryBoundaryData;\n","import type { Key, ReactNode } from \"react\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport Typography from \"@mui/material/Typography\";\nimport { Fragment } from \"react\";\n\nimport { useQueryBoundary } from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryDataMapBaseProps<ItemType> {\n /**\n * The elements to show after data has been loaded.\n *\n * This is best provided as a function with a data argument that guarantees the data will not be undefined by the time you receive it here.\n */\n children: ReactNode | ((data: ItemType) => ReactNode);\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n /** The component to show if the array is empty. */\n emptyComponent?: ReactNode;\n /** Throw an error if the provided data is not an array. (defaults to `true`) */\n strictlyRequireArray?: boolean;\n /**\n * A function that takes a data item and returns the key to be used for the item.\n *\n * If not provided, it will fall back to using the index.\n */\n itemKey?: (item: ItemType, index: number) => Key;\n}\n\nexport interface QueryBoundaryDataMapPropsWithItemParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n /** A parser for each data item. */\n itemParser: (data: unknown) => ItemType;\n dataParser?: never;\n}\n\nexport interface QueryBoundaryDataMapPropsWithDataParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n /** A parser for each data item. */\n dataParser: (data: unknown) => Array<ItemType>;\n itemParser?: never;\n}\n\nexport interface QueryBoundaryDataMapPropsWithNoParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n dataParser?: never;\n itemParser?: never;\n}\n\nexport type QueryBoundaryDataMapProps<ItemType> =\n | QueryBoundaryDataMapPropsWithItemParser<ItemType>\n | QueryBoundaryDataMapPropsWithDataParser<ItemType>\n | QueryBoundaryDataMapPropsWithNoParser<ItemType>;\n\n/**\n * The component responsible for handling an array of data provided by `QueryBoundaryProvider`.\n *\n * It will map through the data array, rendering the result of the children function in a fragment with a key of its index in the list, unless overridden by the `itemKey` prop.\n *\n * @template ItemType - The type of data being loaded.\n *\n * @throws {DataError} If the data provided by `QueryBoundaryProvider` is not an array, and the `strictlyRequireArray` prop is `true` (it is by default).\n */\nfunction QueryBoundaryDataMap<ItemType>({\n children,\n loadingComponent: propLoadingComponent,\n itemKey,\n itemParser,\n dataParser: propDataParser,\n emptyComponent = <Typography>No data present</Typography>,\n strictlyRequireArray = true,\n}: QueryBoundaryDataMapProps<ItemType>) {\n const {\n isLoading,\n data,\n dataParser: contextDataParser,\n loadingComponent: contextLoadingComponent,\n error,\n } = useQueryBoundary<Array<ItemType>>();\n\n const dataParser = propDataParser ?? contextDataParser;\n const loadingComponent = propLoadingComponent ?? contextLoadingComponent;\n\n if (isLoading) {\n return <>{loadingComponent}</>;\n }\n\n if (error) {\n return null;\n }\n\n if (data === null || data === undefined) {\n return null;\n }\n\n if (!Array.isArray(data)) {\n if (strictlyRequireArray) {\n throw new DataError(\n { data, strictlyRequireArray },\n \"NOT_AN_ARRAY\",\n \"Expected the data to be an array but it was not an array.\",\n );\n }\n return null;\n }\n\n if (data.length === 0) {\n return <>{emptyComponent}</>;\n }\n\n let items: Array<ItemType>;\n\n if (dataParser) {\n items = dataParser(data);\n } else if (itemParser) {\n items = data.map(itemParser);\n } else {\n items = data;\n }\n\n return (\n <>\n {items.map((item, index) => {\n return (\n <Fragment key={itemKey ? itemKey(item, index) : index}>\n {typeof children === \"function\" ? children(item) : children}\n </Fragment>\n );\n })}\n </>\n );\n}\n\nexport default QueryBoundaryDataMap;\n","import type { ReactNode } from \"react\";\n\nimport Alert from \"@mui/material/Alert\";\nimport { useRef } from \"react\";\n\nimport { useQueryBoundary } from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryErrorProps {\n /** The component to show if an error has been thrown. */\n children?: ReactNode | ((error: unknown) => ReactNode);\n /** An option to log the error to the console. */\n logError?: boolean;\n}\n\n/**\n * The component responsible for showing any errors provided by QueryBoundaryProvider.\n */\nfunction QueryBoundaryError({ children, logError: propsLogError }: QueryBoundaryErrorProps) {\n const {\n data,\n error,\n errorComponent: contextErrorComponent,\n logError: contextLogError,\n } = useQueryBoundary();\n const logError = propsLogError ?? contextLogError;\n const warnedOnce = useRef(false);\n\n const errorComponent = children ?? contextErrorComponent;\n\n if (error) {\n if (logError && !warnedOnce.current) {\n if (data !== null && data !== undefined) {\n console.error(\n \"An error has occurred but data is still present. This may indicate an invalid query state.\",\n { data, error },\n );\n }\n console.error(error);\n warnedOnce.current = true;\n }\n if (typeof errorComponent === \"function\") {\n return errorComponent(error);\n }\n if (errorComponent) {\n return <>{errorComponent}</>;\n }\n\n return (\n <Alert severity=\"error\">\n {typeof error === \"object\" && \"message\" in error && typeof error.message === \"string\"\n ? error.message\n : \"An unknown error has occured. Please try again later.\"}\n </Alert>\n );\n }\n\n return null;\n}\n\nexport default QueryBoundaryError;\n","import type { ReactNode } from \"react\";\n\nimport Alert from \"@mui/material/Alert\";\n\nimport { useQueryBoundary } from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryNullablePropsWithUndefinedOrNull {\n /** The component to show if no error was thrown but data is undefined */\n undefinedComponent?: ReactNode;\n /** The component to show if no error was thrown but data is null */\n nullComponent?: ReactNode;\n nullableComponent?: never;\n}\n\nexport interface QueryBoundaryNullablePropsWithNullable {\n undefinedComponent?: never;\n nullComponent?: never;\n /** The component to show if no error was thrown but data is undefined or null */\n nullableComponent?: ReactNode;\n}\n\nexport type QueryBoundaryNullableProps =\n | QueryBoundaryNullablePropsWithUndefinedOrNull\n | QueryBoundaryNullablePropsWithNullable;\n\n/** The component responsible for handling cases when the data provided by `QueryBoundaryProvider` may be missing. */\nfunction QueryBoundaryNullable({\n undefinedComponent,\n nullComponent,\n nullableComponent,\n}: QueryBoundaryNullableProps) {\n const { isLoading, data, error } = useQueryBoundary();\n\n if (isLoading) {\n return null;\n }\n\n if (error) {\n return null;\n }\n\n if (data === null || data === undefined) {\n if (nullableComponent) {\n return <>{nullableComponent}</>;\n }\n\n if (data === undefined) {\n if (undefinedComponent) {\n return <>{undefinedComponent}</>;\n }\n }\n\n if (data === null) {\n if (nullComponent) {\n return <>{nullComponent}</>;\n }\n }\n\n return <Alert severity=\"error\">Failed to load data. Please try again later.</Alert>;\n }\n\n return null;\n}\n\nexport default QueryBoundaryNullable;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryErrorProps } from \"src/providers/QueryBoundaryProvider/QueryBoundaryError\";\nimport type { QueryBoundaryNullableProps } from \"src/providers/QueryBoundaryProvider/QueryBoundaryNullable\";\n\nimport QueryBoundaryError from \"src/providers/QueryBoundaryProvider/QueryBoundaryError\";\nimport QueryBoundaryNullable from \"src/providers/QueryBoundaryProvider/QueryBoundaryNullable\";\n\nexport type QueryBoundaryFallbackProps = Omit<QueryBoundaryErrorProps, \"children\"> & {\n /** The component to show if an error has been thrown. */\n errorComponent?: ReactNode | ((error: unknown) => ReactNode);\n} & QueryBoundaryNullableProps;\n\n/**\n * The component responsible for handling both errors and nullable data from `QueryBoundaryProvider`\n */\nfunction QueryBoundaryFallback({\n errorComponent,\n logError,\n ...queryBoundaryNullableProps\n}: QueryBoundaryFallbackProps) {\n return (\n <>\n <QueryBoundaryError logError={logError}>{errorComponent}</QueryBoundaryError>\n <QueryBoundaryNullable {...queryBoundaryNullableProps} />\n </>\n );\n}\n\nexport default QueryBoundaryFallback;\n","import QueryBoundaryProvider from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\nexport { default as QueryBoundaryData } from \"src/providers/QueryBoundaryProvider/QueryBoundaryData\";\nexport { default as QueryBoundaryDataMap } from \"src/providers/QueryBoundaryProvider/QueryBoundaryDataMap\";\nexport { default as QueryBoundaryError } from \"src/providers/QueryBoundaryProvider/QueryBoundaryError\";\nexport { default as QueryBoundaryFallback } from \"src/providers/QueryBoundaryProvider/QueryBoundaryFallback\";\nexport { default as QueryBoundaryNullable } from \"src/providers/QueryBoundaryProvider/QueryBoundaryNullable\";\nexport { useQueryBoundary } from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\nexport type { QueryBoundaryDataProps } from \"src/providers/QueryBoundaryProvider/QueryBoundaryData\";\nexport type {\n QueryBoundaryDataMapBaseProps,\n QueryBoundaryDataMapProps,\n QueryBoundaryDataMapPropsWithDataParser,\n QueryBoundaryDataMapPropsWithItemParser,\n QueryBoundaryDataMapPropsWithNoParser,\n} from \"src/providers/QueryBoundaryProvider/QueryBoundaryDataMap\";\nexport default QueryBoundaryProvider;\nexport type { QueryBoundaryErrorProps } from \"src/providers/QueryBoundaryProvider/QueryBoundaryError\";\nexport type { QueryBoundaryFallbackProps } from \"src/providers/QueryBoundaryProvider/QueryBoundaryFallback\";\nexport type {\n QueryBoundaryNullablePropsWithNullable,\n QueryBoundaryNullablePropsWithUndefinedOrNull,\n QueryBoundaryNullableProps,\n} from \"src/providers/QueryBoundaryProvider/QueryBoundaryNullable\";\nexport type {\n QueryBoundaryProviderProps,\n QueryBoundaryProviderBaseProps,\n QueryBoundaryProviderPropsWithError,\n QueryBoundaryProviderPropsWithNoError,\n} from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport { createContext, useContext, useEffect, useMemo, useState } from \"react\";\n\nexport interface ScreenSizeProps {\n /** The children that will be receiving the ScreenSizeContext. */\n children: ReactNode;\n /** The minimum screen width in pixels required to be considered a large screen. */\n largeScreenWidth?: number;\n /** The minimum screen height in pixels required to be considered a large screen. */\n largeScreenHeight?: number;\n}\n\nexport interface ScreenSizeContextValue {\n /** Whether the screen is a large screen or not. */\n isLargeScreen: boolean;\n /** The current window width. */\n windowWidth: number;\n /** The current window height. */\n windowHeight: number;\n}\n\nconst ScreenSizeContext = createContext<ScreenSizeContextValue>({\n windowWidth: 0,\n windowHeight: 0,\n isLargeScreen: false,\n});\n\n/** Access the screen size context directly. */\nexport function useScreenSize<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, ScreenSizeContextValue> {\n const context = useContext(ScreenSizeContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"SCREEN_SIZE_PROVIDER_NOT_FOUND\",\n \"Could not find the ScreenSizeProvider context. Please double-check that it is present.\",\n );\n }\n return context;\n}\n\n/** Provides context about the current screen size. */\nfunction ScreenSizeProvider({\n children,\n largeScreenWidth = 669,\n largeScreenHeight = 660,\n}: ScreenSizeProps) {\n const [windowWidth, setWindowWidth] = useState<number>(window.innerWidth);\n const [windowHeight, setWindowHeight] = useState<number>(window.innerHeight);\n\n useEffect(() => {\n function setDimensions() {\n setWindowWidth(window.innerWidth);\n setWindowHeight(window.innerHeight);\n }\n setDimensions();\n window.addEventListener(\"resize\", setDimensions);\n return () => {\n window.removeEventListener(\"resize\", setDimensions);\n };\n }, []);\n\n const isLargeScreen = useMemo(() => {\n return windowWidth > largeScreenWidth && windowHeight > largeScreenHeight;\n }, [windowWidth, windowHeight, largeScreenWidth, largeScreenHeight]);\n\n return (\n <ScreenSizeContext.Provider\n value={{\n isLargeScreen,\n windowWidth,\n windowHeight,\n }}\n >\n {children}\n </ScreenSizeContext.Provider>\n );\n}\n\nexport default ScreenSizeProvider;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { AlertColor } from \"@mui/material/Alert\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { wait } from \"@alextheman/utility\";\nimport { DataError } from \"@alextheman/utility/v6\";\nimport Alert from \"@mui/material/Alert\";\nimport Snackbar from \"@mui/material/Snackbar\";\nimport { createContext, useContext, useState } from \"react\";\n\nexport interface SnackbarProviderProps {\n /** The children that will have access to the snackbar context. */\n children: ReactNode;\n /** The amount of seconds to wait before hiding the snackbar. */\n autoHideDuration?: number;\n}\n\nexport interface SnackbarContextValue {\n /** A function that adds the snackbar to the page. */\n addSnackbar: (message: string, severity?: AlertColor, duration?: number) => void;\n}\n\nconst SnackbarContext = createContext<SnackbarContextValue | undefined>(undefined);\n\n/** Access the snackbar context directly. */\nexport function useSnackbar<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, SnackbarContextValue> {\n const context = useContext(SnackbarContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"SNACKBAR_PROVIDER_NOT_FOUND\",\n \"Could not find the SnackbarProvider context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, SnackbarContextValue>;\n}\n\n/** Controls the display of the snackbars on the page. */\nfunction SnackbarProvider({ children, autoHideDuration = 5000 }: SnackbarProviderProps) {\n const [open, setOpen] = useState<boolean>(false);\n const [autoHideDurationState, setAutoHideDurationState] = useState<number>(autoHideDuration);\n const [message, setMessage] = useState<string>(\"\");\n const [severity, setSeverity] = useState<AlertColor>(\"info\");\n\n function addSnackbar(message: string, severity?: AlertColor, duration?: number) {\n setOpen(true);\n setAutoHideDurationState(duration ?? autoHideDuration);\n setSeverity(severity ?? \"info\");\n setMessage(message);\n }\n\n async function handleClose() {\n setOpen(false);\n // Wait for 0.2 seconds to ensure that the message is only cleared after the snackbar is fully closed.\n // This prevents potential weird flickering that may occur if they happen synchronously.\n await wait(0.2);\n setMessage(\"\");\n }\n\n return (\n <SnackbarContext.Provider value={{ addSnackbar }}>\n <Snackbar open={open} autoHideDuration={autoHideDurationState} onClose={handleClose}>\n <Alert onClose={handleClose} severity={severity}>\n {message}\n </Alert>\n </Snackbar>\n {children}\n </SnackbarContext.Provider>\n );\n}\n\nexport default SnackbarProvider;\n","import Tooltip from \"@mui/material/Tooltip\";\nimport { MdOutlineDarkMode, MdOutlineLightMode } from \"react-icons/md\";\n\nimport SwitchWithIcons from \"src/components/SwitchWithIcons\";\nimport { useMode } from \"src/providers\";\n\n/** A toggle to switch between dark mode and light mode. Must be used in a `ModeProvider`. */\nfunction ModeToggle() {\n const { mode, toggleMode } = useMode();\n const isDarkMode = mode === \"dark\";\n const modeText = `Enable ${isDarkMode ? \"light\" : \"dark\"} mode`;\n\n return (\n <Tooltip title={modeText}>\n <SwitchWithIcons\n uncheckedIcon={MdOutlineLightMode}\n checkedIcon={MdOutlineDarkMode}\n checked={isDarkMode}\n onChange={toggleMode}\n aria-label={modeText}\n />\n </Tooltip>\n );\n}\n\nexport default ModeToggle;\n","import type { ReactNode } from \"react\";\n\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Divider from \"@mui/material/Divider\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface PageProps {\n /** The Page title to show */\n title: ReactNode;\n /** The subtitle to show under the Page title */\n subtitle?: ReactNode;\n /** The actions to show in the page header */\n action?: ReactNode;\n /** The actual page contents */\n children: ReactNode;\n /** Disable the inner padding of the Page contents. */\n disablePadding?: boolean;\n /** Optional tabs to display in the header. */\n tabs?: ReactNode;\n}\n\n/** Renders a pre-styled Page that can be used to structure pages throughout your React apps. */\nfunction Page({ title, subtitle, action, children, tabs, disablePadding }: PageProps) {\n return (\n <Card>\n <CardHeader\n title={\n <>\n {typeof title === \"string\" ? <Typography variant=\"h6\">{title}</Typography> : title}\n {subtitle ? (\n typeof subtitle === \"string\" ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {subtitle}\n </Typography>\n ) : (\n subtitle\n )\n ) : null}\n </>\n }\n action={action}\n />\n {tabs}\n <Divider />\n {disablePadding ? children : <CardContent>{children}</CardContent>}\n </Card>\n );\n}\n\nexport default Page;\n","/* \neslint-disable react/prop-types -- ESLint gives false positives because it thinks the props are not typed.\nHowever, they are - this compound component are all typed and the prop types are recognised by TypeScript.\n*/\nimport type { JSX, ReactNode } from \"react\";\n\nimport {\n QueryBoundaryData,\n QueryBoundaryDataMap,\n QueryBoundaryError,\n QueryBoundaryFallback,\n QueryBoundaryNullable,\n QueryBoundaryProvider,\n} from \"src/providers\";\n\nexport interface QueryBase {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The error given if the response gave an error. */\n error?: unknown;\n}\n\nexport interface QuerySingle<DataType> extends QueryBase {\n /** The data being loaded. */\n data: DataType | null | undefined;\n dataCollection?: never;\n}\n\nexport interface QueryMultiple<ItemType> extends QueryBase {\n /** An array of data items being loaded. */\n dataCollection: Array<ItemType> | null | undefined;\n data?: never;\n}\n\nexport type Query<DataType> = QuerySingle<DataType> | QueryMultiple<DataType>;\n\nexport interface CreateQueryBoundaryParameters<DataType> {\n query: Query<DataType>;\n}\n\nexport interface DefaultQueryBoundaryComponents<DataType> {\n Context: (props: { children: ReactNode }) => JSX.Element;\n Error: typeof QueryBoundaryError;\n Data: typeof QueryBoundaryData<DataType>;\n DataMap: typeof QueryBoundaryDataMap<DataType>;\n Fallback: typeof QueryBoundaryFallback;\n Nullable: typeof QueryBoundaryNullable;\n}\n\n/** A creator function to create a system of QueryBoundary components with the data fully typed throughout. */\nfunction createQueryBoundary<DataType>({\n query,\n}: CreateQueryBoundaryParameters<DataType>): DefaultQueryBoundaryComponents<DataType> {\n return {\n Context: ({ children }) => {\n return (\n <QueryBoundaryProvider\n isLoading={query.isLoading}\n error={query.error}\n data={query.data ?? query.dataCollection}\n >\n {children}\n </QueryBoundaryProvider>\n );\n },\n Error: QueryBoundaryError,\n Data: QueryBoundaryData<DataType>,\n DataMap: QueryBoundaryDataMap<DataType>,\n Fallback: QueryBoundaryFallback,\n Nullable: QueryBoundaryNullable,\n };\n}\n\nexport default createQueryBoundary;\n","import { useEffect, useState } from \"react\";\n\n/**\n * Assign a variable a given value after a given amount of milliseconds.\n *\n * @template ValueType The type of the value to set.\n *\n * @param value - The value to assign.\n * @param delay - The amount of milliseconds to wait before assigning the value.\n *\n * @returns The input value after a given number of seconds.\n */\nfunction useDebounce<ValueType>(value: ValueType, delay: number = 500): ValueType {\n const [debouncedValue, setDebouncedValue] = useState<ValueType>(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n\nexport default useDebounce;\n","import type { Dispatch, SetStateAction } from \"react\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Stores changes to the window hash as React state.\n *\n * @template StateType - The type of the hash state.\n *\n * @param initialHash - The initial value of the hash.\n *\n * @returns A tuple containing the hash state, and a updater function to set the hash state.\n */\nfunction useHash<StateType extends string>(\n initialHash: StateType | undefined,\n): [StateType, Dispatch<SetStateAction<StateType>>] {\n const [hash, setHash] = useState<StateType>(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n return !initialHash ? hash : hash === \"\" ? initialHash : hash;\n });\n const hashChangeHandler = useCallback(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n setHash(!initialHash ? hash : hash === \"\" ? initialHash : hash);\n }, [setHash, initialHash]);\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", hashChangeHandler);\n return () => {\n window.removeEventListener(\"hashchange\", hashChangeHandler);\n };\n }, [hashChangeHandler]);\n\n const updateHash = useCallback(\n (newHash: StateType | ((previousState: StateType) => StateType)) => {\n const resolvedHash = typeof newHash === \"function\" ? newHash(hash) : newHash;\n if (resolvedHash !== hash) {\n window.location.hash = resolvedHash;\n }\n },\n [hash],\n );\n\n return [hash, updateHash];\n}\n\nexport default useHash;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryFallbackProps, QueryBoundaryProviderProps } from \"src/providers\";\nimport type { QueryBoundaryDataMapProps } from \"src/providers/QueryBoundaryProvider/QueryBoundaryDataMap\";\n\nimport { createQueryBoundary } from \"src/hooks\";\n\nexport type QueryBoundaryMapProps<ItemType> = Omit<\n QueryBoundaryProviderProps<Array<ItemType>>,\n \"children\" | \"logError\"\n> &\n Omit<QueryBoundaryFallbackProps, \"errorComponent\"> &\n QueryBoundaryDataMapProps<ItemType>;\n\n/**\n * An in-line component that handles an array of data provided by `QueryBoundaryProvider`.\n *\n * This may be used over QueryBoundaryProvider/QueryBoundaryDataMap if you don't require as much control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryMap<ItemType>({\n loadingComponent,\n undefinedComponent,\n nullComponent,\n nullableComponent,\n logError,\n errorComponent,\n children,\n isLoading,\n error,\n data,\n dataParser,\n itemParser,\n itemKey,\n}: QueryBoundaryMapProps<ItemType>) {\n const QueryBoundary = createQueryBoundary({ query: { isLoading, error, dataCollection: data } });\n\n let boundaryErrorComponent: ReactNode = (\n <QueryBoundary.Fallback logError={logError} errorComponent={errorComponent} />\n );\n\n if (nullableComponent) {\n boundaryErrorComponent = (\n <QueryBoundary.Fallback\n nullableComponent={nullableComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n } else if (undefinedComponent || nullComponent) {\n boundaryErrorComponent = (\n <QueryBoundary.Fallback\n undefinedComponent={undefinedComponent}\n nullComponent={nullComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n }\n\n let boundaryDataMapComponent: ReactNode = (\n <QueryBoundary.DataMap loadingComponent={loadingComponent} itemKey={itemKey}>\n {children}\n </QueryBoundary.DataMap>\n );\n\n if (dataParser) {\n boundaryDataMapComponent = (\n <QueryBoundary.DataMap\n loadingComponent={loadingComponent}\n itemKey={itemKey}\n dataParser={dataParser}\n >\n {children}\n </QueryBoundary.DataMap>\n );\n } else if (itemParser) {\n boundaryDataMapComponent = (\n <QueryBoundary.DataMap\n loadingComponent={loadingComponent}\n itemKey={itemKey}\n itemParser={itemParser}\n >\n {children}\n </QueryBoundary.DataMap>\n );\n }\n\n return (\n <QueryBoundary.Context>\n {boundaryErrorComponent}\n {boundaryDataMapComponent}\n </QueryBoundary.Context>\n );\n}\n\nexport default QueryBoundaryMap;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryDataProps, QueryBoundaryProviderProps } from \"src/providers\";\nimport type { QueryBoundaryFallbackProps } from \"src/providers/QueryBoundaryProvider/QueryBoundaryFallback\";\n\nimport CircularProgress from \"@mui/material/CircularProgress\";\n\nimport { createQueryBoundary } from \"src/hooks\";\n\nexport type QueryBoundaryWrapperProps<DataType> = Omit<\n QueryBoundaryProviderProps<DataType>,\n \"children\" | \"logError\"\n> &\n Omit<QueryBoundaryFallbackProps, \"errorComponent\"> &\n Omit<QueryBoundaryDataProps<DataType>, \"showOnError\" | \"onUndefined\" | \"onNull\" | \"onNullable\">;\n\n/**\n * An in-line component that deals with state management when fetching data from an API.\n * This may be used over QueryBoundaryProvider if you don't require as much control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryWrapper<DataType>({\n children,\n errorComponent,\n undefinedComponent,\n nullComponent,\n nullableComponent,\n logError,\n loadingComponent = <CircularProgress />,\n isLoading,\n error,\n data,\n dataParser,\n}: QueryBoundaryWrapperProps<DataType>) {\n const QueryBoundary = createQueryBoundary({ query: { isLoading, error, data } });\n\n let boundaryFallbackComponent: ReactNode = (\n <QueryBoundary.Fallback logError={logError} errorComponent={errorComponent} />\n );\n\n if (nullableComponent) {\n boundaryFallbackComponent = (\n <QueryBoundary.Fallback\n nullableComponent={nullableComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n } else if (undefinedComponent || nullComponent) {\n boundaryFallbackComponent = (\n <QueryBoundary.Fallback\n undefinedComponent={undefinedComponent}\n nullComponent={nullComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n }\n\n return (\n <QueryBoundary.Context>\n {boundaryFallbackComponent}\n <QueryBoundary.Data loadingComponent={loadingComponent} dataParser={dataParser}>\n {children}\n </QueryBoundary.Data>\n </QueryBoundary.Context>\n );\n}\n\nexport default QueryBoundaryWrapper;\n","import type { SxProps, Theme } from \"@mui/material/styles\";\nimport type { ComponentProps } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\nimport { stripIndent } from \"common-tags\";\nimport { LiveEditor, LiveError, LivePreview, LiveProvider } from \"react-live\";\n\nimport { useMode } from \"src/providers\";\n\nexport interface ReactPlaygroundProps extends ComponentProps<typeof LiveProvider> {\n /** Extra styling to apply to the preview. Must be compatible with the Material UI `sx` prop. */\n previewStyles?: SxProps<Theme>;\n}\n\n/** Renders a playground to help demonstrate your React code in an interactive setting. */\nfunction ReactPlayground({ code, previewStyles, ...liveProviderProps }: ReactPlaygroundProps) {\n const { mode } = useMode();\n const defaultPreviewStyles: SxProps<Theme> = {\n backgroundColor: mode === \"dark\" ? \"black\" : \"white\",\n border: 0.3,\n borderRadius: 1,\n padding: 2,\n borderColor: \"darkgray\",\n };\n const allPreviewStyles = previewStyles\n ? { ...defaultPreviewStyles, ...previewStyles }\n : { ...defaultPreviewStyles };\n return (\n <Box sx={{ borderRadius: 1, border: 0.5, padding: 2 }}>\n <LiveProvider {...liveProviderProps} code={stripIndent(code ?? \"\")}>\n <Typography variant=\"h5\">Code</Typography>\n <Box\n sx={{\n border: 0.3,\n borderRadius: 0.3,\n borderColor: \"darkgray\",\n }}\n >\n <LiveEditor />\n </Box>\n <br />\n <Typography variant=\"h5\">Result</Typography>\n <Box sx={allPreviewStyles}>\n <LivePreview />\n <LiveError />\n </Box>\n </LiveProvider>\n </Box>\n );\n}\n\nexport default ReactPlayground;\n","import { fillArray } from \"@alextheman/utility\";\nimport Skeleton from \"@mui/material/Skeleton\";\nimport TableCell from \"@mui/material/TableCell\";\nimport TableRow from \"@mui/material/TableRow\";\n\nexport interface SkeletonRowProps {\n /** The number of columns the SkeletonRow should display. */\n columns: number;\n}\n\n/** Renders the skeleton of a table row. Often helpful to represent the loading state of the data in your table. */\nfunction SkeletonRow({ columns }: SkeletonRowProps) {\n return (\n <TableRow>\n {fillArray((index) => {\n return (\n <TableCell key={index}>\n <Skeleton />\n </TableCell>\n );\n }, columns)}\n </TableRow>\n );\n}\n\nexport default SkeletonRow;\n","import { ModeToggle } from \"src/components\";\n\n/** @deprecated This component has been renamed to `ModeToggle`. */\nconst DarkModeToggle = ModeToggle;\n\nexport default DarkModeToggle;\n","import type { ButtonOwnProps } from \"@mui/material/Button\";\nimport type { ElementType, MouseEvent as ReactMouseEvent, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport MUIButton from \"@mui/material/Button\";\nimport Menu from \"@mui/material/Menu\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { MdArrowDropDown, MdArrowDropUp } from \"react-icons/md\";\n\nexport interface DropdownMenuProps {\n children: ReactNode | ((closeMenu: () => void) => ReactNode);\n buttonChildren?: ReactNode;\n button?: ElementType;\n // Omit endIcon because the built-in isOpenIcon and isClosedIcon gives more control.\n // onClick is also omitted because that controls anchorElement, and the onOpen/onClose functions can be used instead.\n buttonProps?: Omit<ButtonOwnProps, \"onClick\" | \"endIcon\">;\n isOpenIcon?: ReactNode;\n isClosedIcon?: ReactNode;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\n/**\n * @deprecated This component does not support the new context-based pattern and individual DropdownMenuItem components. Please use DropdownMenu2 instead.\n */\nfunction DropdownMenu({\n children,\n button: Button = MUIButton,\n buttonChildren = \"Menu\",\n buttonProps: incomingButtonProps,\n isOpenIcon = <MdArrowDropUp />,\n isClosedIcon = <MdArrowDropDown />,\n onOpen,\n onClose,\n}: DropdownMenuProps) {\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n const isDropdownOpen = useMemo(() => {\n return !!anchorElement;\n }, [anchorElement]);\n\n const buttonProps: Record<string, unknown> = {\n ...incomingButtonProps,\n onClick: (event: ReactMouseEvent<HTMLElement>) => {\n setAnchorElement(event.currentTarget);\n },\n \"aria-controls\": isDropdownOpen ? \"dropdown-menu\" : undefined,\n \"aria-haspopup\": \"true\",\n \"aria-expanded\": isDropdownOpen,\n };\n\n if (Button === MUIButton) {\n buttonProps.endIcon = isDropdownOpen ? isOpenIcon : isClosedIcon;\n }\n\n useEffect(() => {\n if (isDropdownOpen && onOpen) {\n onOpen();\n } else if (!isDropdownOpen && onClose) {\n onClose();\n }\n }, [isDropdownOpen, onOpen, onClose]);\n\n return (\n <Box>\n <Button {...buttonProps}>{buttonChildren}</Button>\n <Menu\n id=\"dropdown-menu\"\n anchorEl={anchorElement}\n open={isDropdownOpen}\n onClose={() => {\n setAnchorElement(null);\n }}\n >\n {typeof children === \"function\" ? (\n <Box>\n {children(() => {\n setAnchorElement(null);\n })}\n </Box>\n ) : (\n children\n )}\n </Menu>\n </Box>\n );\n}\n\nexport default DropdownMenu;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { Dispatch, ReactNode, SetStateAction } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport { createContext, useContext, useMemo, useState } from \"react\";\n\nexport interface DropdownMenuContextValue {\n /** A function responsible for closing the dropdown menu. */\n closeMenu: () => void;\n /** Represents whether or not the dropdown is open. */\n isDropdownOpen: boolean;\n}\n\nexport type DropdownMenuInternalContextValue = DropdownMenuContextValue & {\n anchorElement: HTMLElement | null;\n setAnchorElement: Dispatch<SetStateAction<HTMLElement | null>>;\n};\nconst DropdownMenuContext = createContext<DropdownMenuInternalContextValue | undefined>(undefined);\n\n/**\n Access the DropdownMenu context directly.\n */\nexport function useDropdownMenu<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, DropdownMenuContextValue> {\n const context = useContext(DropdownMenuContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"DROPDOWN_MENU_NOT_FOUND\",\n \"Could not find the DropdownMenu context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, DropdownMenuContextValue>;\n}\n\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function useDropdownMenuInternal<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, DropdownMenuInternalContextValue> {\n return useDropdownMenu({ strict }) as OptionalOnCondition<\n Strict,\n DropdownMenuInternalContextValue\n >;\n}\n\nexport interface DropdownMenuProviderProps {\n /** The children to render inside of the dropdown. */\n children: ReactNode;\n}\n\n/** Provides shared context for the `DropdownMenu` related components. */\nfunction DropdownMenuProvider({ children }: DropdownMenuProviderProps) {\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n\n const isDropdownOpen = useMemo(() => {\n return !!anchorElement;\n }, [anchorElement]);\n\n function closeMenu() {\n setAnchorElement(null);\n }\n\n return (\n <DropdownMenuContext.Provider\n value={{ closeMenu, isDropdownOpen, anchorElement, setAnchorElement }}\n >\n {children}\n </DropdownMenuContext.Provider>\n );\n}\n\nexport default DropdownMenuProvider;\n","import type { MenuProps } from \"@mui/material/Menu\";\nimport type { MouseEvent, ReactNode } from \"react\";\n\nimport Menu from \"@mui/material/Menu\";\n\nimport { useDropdownMenuInternal } from \"src/v7/components/DropdownMenu/DropdownMenuProvider\";\n\nexport interface DropdownMenuProps extends Omit<MenuProps, \"anchorEl\" | \"open\"> {\n /** The children to render inside of the dropdown. */\n children: ReactNode;\n}\n\n/**\n * Renders a menu component that can be used alongside the `DropdownMenuProvider`.\n *\n * This component's open state would be controlled by the `DropdownMenuTrigger`.\n */\nfunction DropdownMenu({ children, onClose, ...menuProps }: DropdownMenuProps) {\n const { anchorElement, isDropdownOpen, closeMenu } = useDropdownMenuInternal();\n\n return (\n <Menu\n anchorEl={anchorElement}\n open={isDropdownOpen}\n onClose={(event: MouseEvent, reason) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClose) {\n onClose(event, reason);\n }\n }}\n {...menuProps}\n >\n {children}\n </Menu>\n );\n}\n\nexport default DropdownMenu;\n","import type Button from \"@mui/material/Button\";\nimport type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n ComponentPropsWithRef,\n ElementType,\n ReactNode,\n} from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { useDropdownMenu } from \"src/v7/components/DropdownMenu/DropdownMenuProvider\";\n\nexport type DropdownMenuItemProps<RootComponent extends ElementType = typeof Button> = {\n /**\n * An optional component to provide to override the current component.\n *\n * Note that the provided component must:\n * - accept a `to` prop.\n * - correctly handle the forwarded `ref`.\n * - render a valid anchor element (or equivalent) for proper accessibility.\n */\n component?: RootComponent;\n /** The children to be rendered within the menu item. */\n children?: ReactNode;\n /** The ref to forward to allow it to be used with polymorphic components */\n ref?: ComponentPropsWithRef<RootComponent>[\"ref\"];\n /** A function to execute after clicking the item. */\n onClick?: ComponentProps<RootComponent>[\"onClick\"];\n} & Omit<ComponentPropsWithoutRef<RootComponent>, \"children\" | \"ref\"> &\n MenuItemOwnProps;\n\n/** Represents a menu item to be used inside the `DropdownMenu`. It must be used as children of the `DropdownMenu` component. */\nfunction DropdownMenuItem<RootComponent extends ElementType = typeof Button>({\n component,\n children,\n ref,\n onClick,\n ...menuItemProps\n}: DropdownMenuItemProps<RootComponent>) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={component}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (onClick) {\n onClick(event);\n }\n if (event.defaultPrevented) {\n return;\n }\n closeMenu();\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuItem;\n","import type {\n DropdownMenuContextValue as DropdownMenuContextValueV7,\n DropdownMenuProps,\n} from \"src/v7\";\n\nimport { DropdownMenu, useDropdownMenu as useDropdownMenuV7 } from \"src/v7\";\n\nexport type DropdownMenuContextValue = DropdownMenuContextValueV7;\n\nexport const useDropdownMenu = useDropdownMenuV7;\n\n/**\n * @deprecated Please use `DropdownMenuProps` from `@alextheman/components/v7` instead.\n *\n * This will be replaced in the root entrypoint in a future release.\n */\nexport type DropdownMenu2Props = DropdownMenuProps;\n\n/**\n * @deprecated Please use `DropdownMenu` from `@alextheman/components/v7` instead.\n *\n * This will be replaced in the root entrypoint in a future release.\n */\nconst DropdownMenu2 = DropdownMenu;\n\nexport default DropdownMenu2;\n","import type { ElementType } from \"react\";\n\nimport type { DropdownMenuItemProps as DropdownMenuItemPropsV7 } from \"src/v7\";\n\nimport { DropdownMenuItem as DropdownMenuItemV7 } from \"src/v7\";\n\nexport type DropdownMenuItemProps<RootComponent extends ElementType> =\n DropdownMenuItemPropsV7<RootComponent>;\n\nconst DropdownMenuItem = DropdownMenuItemV7;\n\nexport default DropdownMenuItem;\n","import DropdownMenu2 from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\n\nexport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nexport { default as DropdownMenuItem } from \"src/deprecated/DropdownMenu2/DropdownMenuItem\";\n\nexport type { DropdownMenu2Props } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nexport type { DropdownMenuItemProps } from \"src/deprecated/DropdownMenu2/DropdownMenuItem\";\n\nexport default DropdownMenu2;\n","import type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type { ComponentProps, MouseEventHandler, ReactNode, Ref } from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { ExternalLink } from \"src/components\";\nimport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\n\nexport interface DropdownMenuExternalLinkProps extends MenuItemOwnProps {\n ref?: Ref<HTMLAnchorElement>;\n href: ComponentProps<typeof ExternalLink>[\"href\"];\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children: ReactNode;\n}\n\n/** @deprecated Please use `<DropdownMenuItem component={ExternalLink} />` instead. */\nfunction DropdownMenuExternalLink({\n ref,\n href,\n children,\n onClick,\n ...menuItemProps\n}: DropdownMenuExternalLinkProps) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={ExternalLink}\n href={href}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClick) {\n onClick(event);\n }\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuExternalLink;\n","import type { LinkProps } from \"@mui/material/Link\";\nimport type { ElementType, ReactNode, Ref } from \"react\";\n\nimport MUILink from \"@mui/material/Link\";\nimport { Link as ReactDOMLink } from \"react-router-dom\";\n\nexport interface InternalLinkProps extends Omit<LinkProps, \"href\" | \"component\"> {\n /** The path to navigate to */\n to: `/${string}` | `~/${string}` | (string & {});\n /**\n * An optional component to provide to override the current component.\n *\n * Note that the provided component must:\n * - accept a `to` prop\n * - correctly handle the forwarded `ref`\n * - render a valid anchor element (or equivalent) for proper accessibility\n */\n component?: ElementType;\n href?: never;\n /** The readable content to display on the link. */\n children: ReactNode;\n /** An optional ref to allow it to be used with polymorphic components. */\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A stylised link for navigating within your application.\n *\n * Uses the app router for client-side navigation and opens the destination in the same tab.\n *\n * Defaults to a React Router implementation but can be overridden via the `component` prop.\n *\n * @deprecated This component is not compatible with the rest of the Wouter setup for use in v7. Please use `InternalLink` from `@alextheman/components/v7` instead. This component will be replaced when v7 officially comes out.\n */\nfunction InternalLink({\n to,\n component = ReactDOMLink,\n children,\n ref,\n ...linkProps\n}: InternalLinkProps) {\n return (\n <MUILink component={component} to={to} ref={ref} {...linkProps}>\n {children}\n </MUILink>\n );\n}\n\nexport default InternalLink;\n","import type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type { ComponentProps, MouseEventHandler, ReactNode, Ref } from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nimport InternalLink from \"src/deprecated/InternalLink\";\n\nexport interface DropdownMenuInternalLinkProps extends MenuItemOwnProps {\n ref?: Ref<HTMLAnchorElement>;\n to: ComponentProps<typeof InternalLink>[\"to\"];\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children: ReactNode;\n}\n\n/** @deprecated Please use `<DropdownMenuItem component={InternalLink} />` instead. */\nfunction DropdownMenuInternalLink({\n to,\n ref,\n children,\n onClick,\n ...menuItemProps\n}: DropdownMenuInternalLinkProps) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={InternalLink}\n to={to}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClick) {\n onClick(event);\n }\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuInternalLink;\n","import type { OverridableComponent } from \"@mui/material/OverridableComponent\";\nimport type { SvgIconTypeMap } from \"@mui/material/SvgIcon\";\nimport type { ElementType, MouseEvent as ReactMouseEvent, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport Popover from \"@mui/material/Popover\";\nimport { useId, useState } from \"react\";\nimport { MdVisibility } from \"react-icons/md\";\n\nexport interface IconWithPopoverProps {\n icon?:\n | (OverridableComponent<SvgIconTypeMap<unknown, \"svg\">> & {\n muiName: string;\n })\n | ElementType;\n onOpen?: () => void;\n onClose?: () => void;\n iconProps?: SvgIconTypeMap<unknown, \"svg\">[\"props\"];\n children: ReactNode;\n}\n\n/**\n * @deprecated This component is not well-designed for accessibility purposes. Please use the `Tooltip` component from `@mui/material` instead.\n *\n * @example\n * ```tsx\n * <Tooltip title=\"Text to display on hover\">\n * <MdVisibility />\n * </Tooltip>\n * ```\n */\nfunction IconWithPopover({\n icon: Icon = MdVisibility,\n onOpen,\n onClose,\n iconProps,\n children,\n}: IconWithPopoverProps) {\n const [anchorElement, setAnchorElement] = useState<Element | null>(null);\n const isPopoverOpen = !!anchorElement;\n const popoverId = useId();\n\n function handleOpen(event: ReactMouseEvent<SVGSVGElement, MouseEvent>) {\n setAnchorElement(event.currentTarget);\n if (onOpen) {\n onOpen();\n }\n }\n\n function handleClose() {\n setAnchorElement(null);\n if (onClose) {\n onClose();\n }\n }\n\n return (\n <Box>\n <Icon\n aria-owns={isPopoverOpen ? popoverId : undefined}\n aria-haspopup=\"true\"\n onMouseEnter={handleOpen}\n onMouseLeave={handleClose}\n {...iconProps}\n />\n <Popover\n id={popoverId}\n disablePortal\n disableScrollLock\n slotProps={{\n root: {\n disableEnforceFocus: true,\n disableAutoFocus: true,\n disableRestoreFocus: true,\n },\n }}\n sx={{ pointerEvents: \"none\" }}\n open={isPopoverOpen}\n anchorEl={anchorElement}\n anchorOrigin={{\n vertical: \"bottom\",\n horizontal: \"left\",\n }}\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"left\",\n }}\n onClose={handleClose}\n disableRestoreFocus\n >\n {children}\n </Popover>\n </Box>\n );\n}\n\nexport default IconWithPopover;\n","import type { ListItemButtonProps } from \"@mui/material/ListItemButton\";\nimport type { ReactNode } from \"react\";\n\nimport ListItemButton from \"@mui/material/ListItemButton\";\n\nimport InternalLink from \"src/deprecated/InternalLink\";\n\nexport interface ListItemInternalLinkProps extends Omit<ListItemButtonProps, \"href\"> {\n children: ReactNode;\n to: string;\n}\n\n/** @deprecated Probably not that worth centralising here - can be easily recreated per use case. */\nfunction ListItemInternalLink({ children, ...listItemButtonProps }: ListItemInternalLinkProps) {\n return (\n <ListItemButton component={InternalLink} {...listItemButtonProps}>\n {children}\n </ListItemButton>\n );\n}\n\nexport default ListItemInternalLink;\n","import type { QueryBoundaryWrapperProps } from \"src/components/QueryBoundaryWrapper\";\n\nimport { QueryBoundaryWrapper } from \"src/components\";\n/** @deprecated This type has been renamed to QueryBoundaryProps. */\nexport type LoaderProps<DataType> = QueryBoundaryWrapperProps<DataType>;\n/** @deprecated This component has been renamed to QueryBoundary */\nconst Loader = QueryBoundaryWrapper;\n\nexport default Loader;\n","import type { QueryBoundaryDataProps } from \"src/providers\";\n\nimport { QueryBoundaryData } from \"src/providers\";\n\n/** @deprecated This type has been renamed to QueryBoundaryDataProps. */\nexport type LoaderDataProps<DataType> = QueryBoundaryDataProps<DataType>;\n\n/** @deprecated This component has been renamed to QueryBoundaryData. */\nconst LoaderData = QueryBoundaryData;\n\nexport default LoaderData;\n","import type {\n QueryBoundaryErrorProps,\n QueryBoundaryFallbackProps,\n QueryBoundaryNullablePropsWithNullable,\n QueryBoundaryNullablePropsWithUndefinedOrNull,\n} from \"src/providers\";\n\nimport { QueryBoundaryFallback } from \"src/providers\";\n\n/** @deprecated This type has been renamed to QueryBoundaryErrorProps. */\nexport type LoaderErrorBaseProps = QueryBoundaryErrorProps;\n\n/** @deprecated This type has been renamed to QueryBoundaryNullablePropsWithUndefinedOrNull. */\nexport type LoaderErrorPropsWithUndefinedOrNull = LoaderErrorBaseProps &\n QueryBoundaryNullablePropsWithUndefinedOrNull;\n\n/** @deprecated This type has been renamed to QueryBoundaryNullablePropsWithNullable. */\nexport type LoaderErrorPropsWithNullable = LoaderErrorBaseProps &\n QueryBoundaryNullablePropsWithNullable;\n\n/** @deprecated This type has been renamed to QueryBoundaryFallbackProps. */\nexport type LoaderErrorProps = QueryBoundaryFallbackProps;\n\n/** @deprecated This component has been renamed to LoaderError. */\nconst LoaderError = QueryBoundaryFallback;\n\nexport default LoaderError;\n","import type {\n QueryBoundaryContextValue,\n QueryBoundaryProviderBaseProps,\n QueryBoundaryProviderProps,\n QueryBoundaryProviderPropsWithError,\n QueryBoundaryProviderPropsWithNoError,\n} from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\nimport { QueryBoundaryProvider } from \"src/providers\";\nimport { useQueryBoundary } from \"src/providers/QueryBoundaryProvider/QueryBoundaryProvider\";\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderBaseProps. */\nexport type LoaderProviderBaseProps<DataType> = QueryBoundaryProviderBaseProps<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderPropsWithNoError. */\nexport type LoaderProviderPropsWithNoError<DataType> =\n QueryBoundaryProviderPropsWithNoError<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderPropsWithError. */\nexport type LoaderProviderPropsWithError<DataType> = QueryBoundaryProviderPropsWithError<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryContextValue. */\nexport type LoaderContextValue<DataType> = QueryBoundaryContextValue<DataType>;\n/** @deprecated This type has been renamed to QueryBoundaryProviderProps. */\nexport type LoaderProviderProps<DataType> = QueryBoundaryProviderProps<DataType>;\n\n/** @deprecated This hook has been renamed to useQueryBoundary */\nexport const useLoader = useQueryBoundary;\n\n/** @deprecated This component has been renamed to QueryBoundaryProvider */\nconst LoaderProvider = QueryBoundaryProvider;\n\nexport default LoaderProvider;\n","import type { JSX, ReactNode } from \"react\";\n\nimport BottomNavigation from \"@mui/material/BottomNavigation\";\nimport BottomNavigationAction from \"@mui/material/BottomNavigationAction\";\nimport Box from \"@mui/material/Box\";\nimport Paper from \"@mui/material/Paper\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\n\nexport interface NavItemBottom {\n /** The value associated with the nav item. */\n value: string;\n /** The label to display on the nav item. */\n label: string;\n /** An icon to display alongside the nav item. */\n icon?: JSX.Element;\n /** Where in your app the nav item should navigate to. */\n to: string;\n}\n\nexport interface NavigationBottomProps {\n /** Children to display above the nav bar. */\n children: ReactNode;\n /** An array of nav items to show. */\n navItems: Array<NavItemBottom>;\n}\n\n/**\n * Renders a navigation bar at the bottom of the screen. Especially helpful for common navigation options in a mobile app.\n *\n * @deprecated Please use `NavigationBottom` from the `@alextheman/components/v7` entrypoint instead.\n */\nfunction NavigationBottom({ children, navItems }: NavigationBottomProps) {\n const [value, setValue] = useState<string>(\"\");\n return (\n <>\n <Box sx={{ paddingBottom: 7 }}>{children}</Box>\n <Paper sx={{ position: \"fixed\", bottom: 0, left: 0, right: 0 }}>\n <BottomNavigation\n showLabels\n value={value}\n onChange={(_, value) => {\n setValue(value);\n }}\n >\n {navItems.map((item) => {\n return <BottomNavigationAction key={item.value} {...item} component={Link} />;\n })}\n </BottomNavigation>\n </Paper>\n </>\n );\n}\n\nexport default NavigationBottom;\n","import type { AppBarProps as MuiAppBarProps } from \"@mui/material/AppBar\";\nimport type { CSSObject, Theme } from \"@mui/material/styles\";\nimport type { ReactNode } from \"react\";\n\nimport { truncate } from \"@alextheman/utility\";\nimport MuiAppBar from \"@mui/material/AppBar\";\nimport Box from \"@mui/material/Box\";\nimport CssBaseline from \"@mui/material/CssBaseline\";\nimport Divider from \"@mui/material/Divider\";\nimport MuiDrawer from \"@mui/material/Drawer\";\nimport IconButton from \"@mui/material/IconButton\";\nimport List from \"@mui/material/List\";\nimport ListItem from \"@mui/material/ListItem\";\nimport ListItemButton from \"@mui/material/ListItemButton\";\nimport ListItemIcon from \"@mui/material/ListItemIcon\";\nimport ListItemText from \"@mui/material/ListItemText\";\nimport { styled, useTheme } from \"@mui/material/styles\";\nimport Toolbar from \"@mui/material/Toolbar\";\nimport Typography from \"@mui/material/Typography\";\nimport { Fragment, useState } from \"react\";\nimport { MdChevronLeft, MdChevronRight, MdMenu } from \"react-icons/md\";\nimport { Link, useLocation } from \"react-router-dom\";\n\nconst drawerWidth = 240;\n\nfunction openedMixin(theme: Theme): CSSObject {\n return {\n width: drawerWidth,\n transition: theme.transitions.create(\"width\", {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.enteringScreen,\n }),\n overflowX: \"hidden\",\n };\n}\n\nfunction closedMixin(theme: Theme): CSSObject {\n return {\n transition: theme.transitions.create(\"width\", {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n overflowX: \"hidden\",\n width: `calc(${theme.spacing(7)} + 1px)`,\n [theme.breakpoints.up(\"sm\")]: {\n width: `calc(${theme.spacing(8)} + 1px)`,\n },\n };\n}\n\nconst DrawerHeader = styled(\"div\")(({ theme }) => {\n return {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n padding: theme.spacing(0, 1),\n // necessary for content to be below app bar\n ...theme.mixins.toolbar,\n };\n});\n\ninterface AppBarProps extends MuiAppBarProps {\n open?: boolean;\n}\n\nconst AppBar = styled(MuiAppBar, {\n shouldForwardProp: (prop) => {\n return prop !== \"open\";\n },\n})<AppBarProps>(({ theme }) => {\n return {\n zIndex: theme.zIndex.drawer + 1,\n transition: theme.transitions.create([\"width\", \"margin\"], {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n variants: [\n {\n props: ({ open }) => {\n return open;\n },\n style: {\n marginLeft: drawerWidth,\n width: `calc(100% - ${drawerWidth}px)`,\n transition: theme.transitions.create([\"width\", \"margin\"], {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.enteringScreen,\n }),\n },\n },\n ],\n };\n});\n\nconst Drawer = styled(MuiDrawer, {\n shouldForwardProp: (prop) => {\n return prop !== \"open\";\n },\n})(({ theme }) => {\n return {\n width: drawerWidth,\n flexShrink: 0,\n whiteSpace: \"nowrap\",\n boxSizing: \"border-box\",\n variants: [\n {\n props: ({ open }) => {\n return open;\n },\n style: {\n ...openedMixin(theme),\n \"& .MuiDrawer-paper\": openedMixin(theme),\n },\n },\n {\n props: ({ open }) => {\n return !open;\n },\n style: {\n ...closedMixin(theme),\n \"& .MuiDrawer-paper\": closedMixin(theme),\n },\n },\n ],\n };\n});\n\nexport interface NavMenuItemOptions {\n /** The label to display on the nav item option. */\n label: string;\n /** Where in your app the nav item option should navigate to. */\n to: string;\n /** An icon to display alongside the nav item option. */\n icon?: ReactNode;\n}\n\nexport interface NavMenuItem {\n /** The category to display all the nav item options under. */\n category: string;\n /** An array of nav options to display under the chosen category. */\n options: Array<NavMenuItemOptions>;\n}\n\nexport interface NavigationDrawerProps {\n /** The title to display at the top of the wrapper. */\n title: string;\n /** An array of nav items to show. */\n navItems: Array<NavMenuItem>;\n /** Any extra elements to add to the header. */\n headerElements?: ReactNode;\n /** Children to display within the wrapper. */\n children: ReactNode;\n}\n\n/**\n * Renders a collapsable drawer to help with navigation. Best used as the main means of navigation on desktop apps.\n *\n * @deprecated This component is not compatible with the rest of the Wouter setup for use in v7. Please use `NavigationDrawer` from `@alextheman/components/v7` instead. This component will be replaced when v7 officially comes out.\n */\nfunction NavigationDrawer({ title, navItems, children, headerElements }: NavigationDrawerProps) {\n const theme = useTheme();\n const [open, setOpen] = useState(true);\n const location = useLocation();\n\n function handleDrawerOpen() {\n setOpen(true);\n }\n\n function handleDrawerClose() {\n setOpen(false);\n }\n\n return (\n <Box sx={{ display: \"flex\" }}>\n <CssBaseline />\n <AppBar position=\"fixed\" open={open}>\n <Toolbar>\n <IconButton\n color=\"inherit\"\n aria-label=\"open drawer\"\n onClick={handleDrawerOpen}\n edge=\"start\"\n sx={[\n {\n marginRight: 5,\n },\n open && { display: \"none\" },\n ]}\n >\n <MdMenu />\n </IconButton>\n <Typography variant=\"h6\" noWrap component=\"div\">\n {title}\n </Typography>\n {headerElements}\n </Toolbar>\n </AppBar>\n <Drawer variant=\"permanent\" open={open}>\n <DrawerHeader>\n <IconButton onClick={handleDrawerClose}>\n {theme.direction === \"rtl\" ? <MdChevronRight /> : <MdChevronLeft />}\n </IconButton>\n </DrawerHeader>\n <Divider />\n {navItems.map((item) => {\n return (\n <Fragment key={item.category}>\n <List>\n <Typography variant={open ? \"h5\" : \"h6\"} sx={{ paddingLeft: open ? 2 : 1 }}>\n {open ? item.category : truncate(item.category, 4)}\n </Typography>\n {item.options.map((option) => {\n return (\n <ListItem key={option.to} disablePadding sx={{ display: \"block\" }}>\n <ListItemButton\n sx={[\n {\n minHeight: 48,\n px: 2.5,\n },\n open\n ? {\n justifyContent: \"initial\",\n }\n : {\n justifyContent: \"center\",\n },\n ]}\n component={Link}\n to={option.to}\n selected={location.pathname === option.to}\n >\n <ListItemIcon\n sx={[\n {\n minWidth: 0,\n justifyContent: \"center\",\n },\n open\n ? {\n mr: 3,\n }\n : {\n mr: \"auto\",\n },\n ]}\n >\n {option.icon ? (\n option.icon\n ) : !open ? (\n <Typography>{truncate(option.label, 4)}</Typography>\n ) : null}\n </ListItemIcon>\n <ListItemText\n primary={option.label}\n sx={[\n open\n ? {\n opacity: 1,\n }\n : {\n opacity: 0,\n },\n ]}\n />\n </ListItemButton>\n </ListItem>\n );\n })}\n </List>\n <Divider />\n </Fragment>\n );\n })}\n </Drawer>\n <Box component=\"main\" sx={{ flexGrow: 1, p: 3 }}>\n <DrawerHeader />\n {children}\n </Box>\n </Box>\n );\n}\n\nexport default NavigationDrawer;\n","import type { TypographyProps } from \"@mui/material/Typography\";\n\nimport Typography from \"@mui/material/Typography\";\n\nexport interface PopoverTextProps extends TypographyProps {\n text: string;\n}\n\n/**\n * @deprecated This component has been deprecated alongside `IconWithPopover`.\n */\nfunction PopoverText({ text, sx, ...typographyProps }: PopoverTextProps) {\n return (\n <>\n {text.split(\"\\n\").map((line, index) => {\n return (\n <Typography key={index} sx={{ margin: 1, ...sx }} {...typographyProps}>\n {line}\n </Typography>\n );\n })}\n </>\n );\n}\n\nexport default PopoverText;\n","import type { QueryBoundaryWrapperProps } from \"src/components/QueryBoundaryWrapper\";\n\nimport QueryBoundaryWrapper from \"src/components/QueryBoundaryWrapper\";\n\n/** @deprecated This type has been renamed to `QueryBoundaryWrapperProps`. */\nexport type QueryBoundaryProps<DataType> = QueryBoundaryWrapperProps<DataType>;\n\n/** @deprecated This component has been renamed to `QueryBoundaryWrapper` */\nconst QueryBoundary = QueryBoundaryWrapper;\n\nexport default QueryBoundary;\n","import type { ButtonProps } from \"@mui/material/Button\";\n\nimport Button from \"@mui/material/Button\";\nimport { useFormContext } from \"react-hook-form\";\n\nexport interface SubmitButtonProps extends Omit<ButtonProps, \"type\"> {\n /** An option to disable the button on submit if the form is not dirty. */\n disableClean?: boolean;\n /** The label for the button. */\n label: string;\n}\n\n/**\n * A Submit Button for use with `react-hook-form`.\n *\n * @deprecated This component is not compatible with `@tanstack/react-form`. Please use `SubmitButton` from the `@alextheman/components/v7` entrypoint instead. This component will be replaced when v7 officially comes out.\n */\nfunction SubmitButton({ disableClean, label, ...buttonProps }: SubmitButtonProps) {\n const {\n formState: { disabled: formDisabled, isDirty, isSubmitting },\n } = useFormContext();\n\n return (\n <Button\n color=\"primary\"\n disabled={buttonProps.disabled || (disableClean && !isDirty) || formDisabled}\n loading={isSubmitting}\n type=\"submit\"\n variant=\"contained\"\n {...buttonProps}\n >\n {label}\n </Button>\n );\n}\n\nexport default SubmitButton;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["Fragment","Button","MUIButton","useDropdownMenu","DropdownMenu","DropdownMenuItem","useDropdownMenu","useDropdownMenuV7","DropdownMenu","DropdownMenuItemV7","ReactDOMLink","Fragment"],"sources":["../src/components/Artwork.tsx","../src/components/CollapsableItem.tsx","../src/components/ExternalLink.tsx","../src/components/FileInput.tsx","../src/components/FileInputList.tsx","../src/components/SwitchWithIcons.tsx","../src/providers/ModeProvider.tsx","../src/providers/ScreenSizeProvider.tsx","../src/providers/SnackbarProvider.tsx","../src/components/ModeToggle.tsx","../src/components/Page.tsx","../src/groups/QueryBoundary/QueryBoundaryProvider.tsx","../src/groups/QueryBoundary/QueryBoundaryDataMap.tsx","../src/groups/QueryBoundary/QueryBoundaryError.tsx","../src/groups/QueryBoundary/QueryBoundaryNullable.tsx","../src/groups/QueryBoundary/QueryBoundaryFallback.tsx","../src/v7/groups/QueryBoundary/createBaseQueryBoundary.tsx","../src/v7/groups/QueryBoundary/createListQueryBoundary.tsx","../src/components/QueryBoundaryMap.tsx","../src/groups/QueryBoundary/QueryBoundaryData.tsx","../src/v7/groups/QueryBoundary/createItemQueryBoundary.tsx","../src/components/QueryBoundaryWrapper.tsx","../src/components/ReactPlayground.tsx","../src/components/SkeletonRow.tsx","../src/deprecated/DarkModeToggle.tsx","../src/deprecated/DropdownMenu.tsx","../src/v7/components/DropdownMenu/DropdownMenuProvider.tsx","../src/v7/components/DropdownMenu/DropdownMenu.tsx","../src/v7/components/DropdownMenu/DropdownMenuItem.tsx","../src/deprecated/DropdownMenu2/DropdownMenu2.tsx","../src/deprecated/DropdownMenu2/DropdownMenuItem.tsx","../src/deprecated/DropdownMenu2/index.tsx","../src/deprecated/DropdownMenuExternalLink.tsx","../src/deprecated/InternalLink.tsx","../src/deprecated/DropdownMenuInternalLink.tsx","../src/deprecated/IconWithPopover.tsx","../src/deprecated/ListItemInternalLink.tsx","../src/deprecated/Loader.tsx","../src/groups/QueryBoundary/index.tsx","../src/deprecated/LoaderData.tsx","../src/deprecated/LoaderError.tsx","../src/deprecated/LoaderProvider.tsx","../src/deprecated/NavigationBottom.tsx","../src/deprecated/NavigationDrawer.tsx","../src/deprecated/PopoverText.tsx","../src/deprecated/QueryBoundary.tsx","../src/deprecated/SubmitButton.tsx","../src/hooks/useDebounce.ts","../src/hooks/useHash.ts"],"sourcesContent":["import Box from \"@mui/material/Box\";\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Chip from \"@mui/material/Chip\";\nimport Divider from \"@mui/material/Divider\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface ContainerProps {\n containerLabel: string;\n chipLabels: Array<string>;\n}\n\nfunction Container({ containerLabel, chipLabels }: ContainerProps) {\n return (\n <Card\n sx={{\n width: 320,\n height: 420,\n backgroundColor: \"rgba(255,255,255,0.07)\",\n backdropFilter: \"blur(8px)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n boxShadow: \"0 10px 40px rgba(0,0,0,0.35)\",\n }}\n >\n <CardContent>\n <Typography variant=\"h6\" gutterBottom sx={{ color: \"#f8fafc\" }}>\n {containerLabel}\n </Typography>\n\n <Stack spacing={1}>\n {chipLabels.map((label) => {\n return (\n <Chip\n key={label}\n label={label}\n sx={{\n backgroundColor: \"rgba(255,255,255,0.11)\",\n color: \"rgba(255,255,255,0.88)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n }}\n />\n );\n })}\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nfunction Connector() {\n return (\n <Box\n sx={{\n width: 120,\n height: 6,\n borderRadius: 3,\n background: \"linear-gradient(90deg, #f43f5e, #a78bfa, #22d3ee)\",\n boxShadow: \"0 0 24px rgba(167,139,250,0.55)\",\n }}\n />\n );\n}\n\n/** The artwork associated with the package's theme song, _An Interface For You And I_. */\nfunction Artwork() {\n return (\n <Card\n sx={{\n width: 1000,\n height: 1000,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n p: 4,\n background:\n \"radial-gradient(circle at 20% 10%, rgba(167,139,250,0.35) 0%, rgba(167,139,250,0.12) 35%, rgba(0,0,0,0) 55%), linear-gradient(135deg, #3a3380 0%, #1d2e5f 40%, #2d3f55 100%)\",\n color: \"white\",\n }}\n elevation={0}\n >\n <CardHeader\n title=\"An Interface For You And I\"\n sx={{\n color: \"#f8fafc\",\n textAlign: \"center\",\n \"& .MuiCardHeader-title\": {\n fontSize: 40,\n fontWeight: 600,\n letterSpacing: 2,\n },\n }}\n />\n\n <Divider sx={{ borderColor: \"rgba(255,255,255,0.2)\" }} />\n\n <CardContent sx={{ flex: 1, display: \"flex\", alignItems: \"center\" }}>\n <Stack\n direction=\"row\"\n spacing={4}\n sx={{ width: \"100%\", justifyContent: \"center\", alignItems: \"center\" }}\n >\n <Container\n containerLabel=\"You\"\n chipLabels={[\"state\", \"context\", \"input\", \"event\", \"focus\", \"value\", \"history\"]}\n />\n <Connector />\n <Container\n containerLabel=\"I\"\n chipLabels={[\"render\", \"effect\", \"response\", \"update\", \"history\", \"layout\", \"provider\"]}\n />\n </Stack>\n </CardContent>\n </Card>\n );\n}\n\nexport default Artwork;\n","import type { CollapseProps } from \"@mui/material/Collapse\";\nimport type { SxProps } from \"@mui/material/styles\";\nimport type { ElementType, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport ButtonBase from \"@mui/material/ButtonBase\";\nimport Collapse from \"@mui/material/Collapse\";\nimport { useEffect, useState } from \"react\";\nimport { MdArrowDropDown, MdArrowDropUp } from \"react-icons/md\";\n\nexport interface CollapsableItemProps {\n /** Whether the item should initially be open or not. */\n isInitiallyOpen?: boolean;\n /** A callback function to execute when the item is open. */\n onOpen?: () => void;\n /** A callback function to execute when the item is closed. */\n onClose?: () => void;\n /** The components to render when the item is open. */\n children: ReactNode;\n /** Styling for the button. */\n buttonStyles?: SxProps;\n /** The children to pass to the button. */\n buttonContents: ReactNode;\n /** The specific button component to use. */\n buttonComponent?: ElementType;\n /** The icon to show next to the button when open. */\n openIcon?: ReactNode;\n /** The icon to show next to the button when closed. */\n closedIcon?: ReactNode;\n /** Props to pass to collapse. */\n collapseProps?: Omit<CollapseProps, \"in\">;\n /**\n * Whether or not to use the default button styling.\n *\n * Defaults to `true` if `buttonComponent` is `ButtonBase`,\n * otherwise defaults to `false`.\n */\n useDefaultStyling?: boolean;\n}\n\n/**\n * Shows a display area that can be opened to show the children components, or hidden away.\n */\nfunction CollapsableItem({\n isInitiallyOpen,\n onOpen,\n onClose,\n children,\n buttonStyles,\n buttonContents,\n buttonComponent: ButtonComponent = ButtonBase,\n collapseProps,\n openIcon = <MdArrowDropUp />,\n closedIcon = <MdArrowDropDown />,\n useDefaultStyling = ButtonComponent === ButtonBase ? true : false,\n}: CollapsableItemProps) {\n const [isItemOpen, setIsItemOpen] = useState<boolean>(!!isInitiallyOpen);\n\n useEffect(() => {\n if (isItemOpen && onOpen) {\n onOpen();\n } else if (!isItemOpen && onClose) {\n onClose();\n }\n }, [isItemOpen]);\n\n return (\n <Box>\n <ButtonComponent\n onClick={() => {\n setIsItemOpen((previouslyOpen) => {\n return !previouslyOpen;\n });\n }}\n sx={\n useDefaultStyling\n ? {\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n paddingY: 1.5,\n paddingX: 2,\n textAlign: \"center\",\n \"&:hover\":\n ButtonComponent === ButtonBase ? { backgroundColor: \"action.hover\" } : null,\n ...buttonStyles,\n }\n : buttonStyles\n }\n aria-expanded={isItemOpen}\n >\n {buttonContents}\n {isItemOpen ? openIcon : closedIcon}\n </ButtonComponent>\n <Collapse in={isItemOpen} {...collapseProps}>\n {children}\n </Collapse>\n </Box>\n );\n}\n\nexport default CollapsableItem;\n","import type { LinkProps } from \"@mui/material/Link\";\nimport type { ReactNode, Ref } from \"react\";\n\nimport MUILink from \"@mui/material/Link\";\n\nexport interface ExternalLinkProps extends Omit<LinkProps, \"to\" | \"target\" | \"rel\"> {\n /** The URL of the place you want to navigate to. */\n href: `https://${string}` | `http://${string}` | (string & {});\n to?: never;\n /** The readable content to display on the link. */\n children: ReactNode;\n /** An optional ref to allow it to be used with polymorphic components. */\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A stylised link that is best used when you want to navigate to a different domain.\n *\n * Opens the destination in a new tab and applies recommended security defaults automatically.\n */\nfunction ExternalLink({ href, children, ref, ...linkProps }: ExternalLinkProps) {\n return (\n <MUILink\n component=\"a\"\n href={href}\n ref={ref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {...linkProps}\n >\n {children}\n </MUILink>\n );\n}\n\nexport default ExternalLink;\n","import type { CreateEnumType } from \"@alextheman/utility\";\nimport type { ButtonOwnProps } from \"@mui/material/Button\";\n\nimport Button from \"@mui/material/Button\";\nimport { styled } from \"@mui/material/styles\";\nimport { useId, useState } from \"react\";\nimport { MdCloudUpload } from \"react-icons/md\";\n\nexport const FileType = {\n PDF: \"application/pdf\",\n PNG: \"image/png\",\n JPEG: \"image/jpeg\",\n JPG: \"image/jpg\",\n XLSX: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n DOCX: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n MP3: \"audio/mp3\",\n MP4: \"video/mp4\",\n WAV: \"audio/wav\",\n} as const;\nexport type FileType = CreateEnumType<typeof FileType>;\n\nconst VisuallyHiddenInput = styled(\"input\")({\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: 1,\n overflow: \"hidden\",\n position: \"absolute\",\n bottom: 0,\n left: 0,\n whiteSpace: \"nowrap\",\n width: 1,\n});\n\nconst Dropzone = styled(\"div\")<{ $dragging: boolean }>(({ theme, $dragging }) => {\n return {\n border: \"2px dashed\",\n borderColor: $dragging ? theme.palette.primary.main : \"#ccc\",\n backgroundColor: $dragging ? theme.palette.action.hover : \"transparent\",\n borderRadius: 8,\n padding: \"1.5rem\",\n textAlign: \"center\",\n transition: \"border-color 0.2s\",\n cursor: \"pointer\",\n };\n});\n\nexport interface FileInputProps extends ButtonOwnProps {\n /** A function to run when a file has been uploaded. */\n onFileInput: (allowedFiles: Array<File>) => void;\n /** The label to display on the input button (defaults to \"Upload files\") */\n label?: string;\n /** Whether to accept multiple files or not. */\n multiple?: boolean;\n /** An array of file types to accept. */\n accept?: Array<string>;\n /** Enable the dropzone, allowing users to drag and drop files. */\n useDropzone?: boolean;\n}\n\n/** Handles file inputs. */\nfunction FileInput({\n onFileInput,\n label = \"Upload files\",\n multiple,\n accept,\n useDropzone,\n ...buttonProps\n}: FileInputProps) {\n const [isDragging, setIsDragging] = useState<boolean>(false);\n const id = useId();\n\n const fileInputButton = (\n <Button\n variant=\"contained\"\n component=\"label\"\n aria-label=\"File input button\"\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n document.getElementById(id)?.click();\n }\n }}\n {...buttonProps}\n startIcon={buttonProps.startIcon ?? <MdCloudUpload />}\n >\n {label}\n <VisuallyHiddenInput\n id={id}\n type=\"file\"\n onChange={(event) => {\n const input = event.target;\n onFileInput(Array.from(input.files ?? []));\n input.value = \"\";\n }}\n multiple={multiple}\n accept={accept?.join(\",\")}\n disabled={buttonProps.disabled}\n />\n </Button>\n );\n\n return useDropzone ? (\n <Dropzone\n $dragging={isDragging}\n onDragOver={(event) => {\n event.preventDefault();\n if (buttonProps.disabled) {\n return;\n }\n setIsDragging(true);\n }}\n onDragLeave={(event) => {\n event.preventDefault();\n setIsDragging(false);\n }}\n onDrop={(event) => {\n event.preventDefault();\n setIsDragging(false);\n if (buttonProps.disabled) {\n return;\n }\n const filesArray = Array.from(event.dataTransfer.files ?? []);\n onFileInput(filesArray);\n }}\n >\n {fileInputButton}\n </Dropzone>\n ) : (\n fileInputButton\n );\n}\n\nexport default FileInput;\n","import type { Dispatch, SetStateAction } from \"react\";\n\nimport type { FileInputProps } from \"src/components/FileInput\";\n\nimport Box from \"@mui/material/Box\";\nimport IconButton from \"@mui/material/IconButton\";\nimport List from \"@mui/material/List\";\nimport ListItem from \"@mui/material/ListItem\";\nimport ListItemText from \"@mui/material/ListItemText\";\nimport { MdDelete } from \"react-icons/md\";\n\nimport FileInput from \"src/components/FileInput\";\n\nexport interface FileInputListProps extends Omit<FileInputProps, \"onFileInput\"> {\n /** The array of files (must be a React state). */\n files: Array<File>;\n /** The state setter for the array of files. */\n setFiles: Dispatch<SetStateAction<Array<File>>>;\n}\n\n/** Renders the `FileInput` component with a list of uploaded files underneath it. */\nfunction FileInputList({\n files,\n setFiles,\n multiple = true,\n ...fileInputProps\n}: FileInputListProps) {\n function onFileInput(newFiles: Array<File>) {\n setFiles((oldFiles) => {\n return [...oldFiles, ...newFiles];\n });\n }\n\n return (\n <Box>\n <FileInput {...fileInputProps} multiple={multiple} onFileInput={onFileInput} />\n <List>\n {files.map((file) => {\n return (\n <ListItem\n key={`${file.name}-${file.lastModified}`}\n secondaryAction={\n <IconButton\n aria-label=\"Delete\"\n edge=\"end\"\n onClick={() => {\n setFiles((oldFiles) => {\n return oldFiles.filter((fileToDelete) => {\n return fileToDelete !== file;\n });\n });\n }}\n >\n <MdDelete />\n </IconButton>\n }\n >\n <ListItemText primary={file.name} />\n </ListItem>\n );\n })}\n </List>\n </Box>\n );\n}\n\nexport default FileInputList;\n","import type { CommonProps } from \"@mui/material/OverridableComponent\";\nimport type { SwitchProps } from \"@mui/material/Switch\";\nimport type { ComponentType, CSSProperties } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport { styled } from \"@mui/material/styles\";\nimport Switch from \"@mui/material/Switch\";\n\nexport interface SwitchWithIconsProps extends Omit<SwitchProps, \"icon\" | \"checkedIcon\"> {\n /** The icon to show when the switch is in a checked state. */\n checkedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when checked. */\n checkedIconStyles?: CommonProps[\"style\"];\n /** The icon to show when the switch is in an unchecked state. */\n uncheckedIcon: ComponentType<{ style?: CSSProperties }>;\n /** Additional styling to apply to the icon that shows when unchecked. */\n uncheckedIconStyles?: CommonProps[\"style\"];\n}\n\nconst StyledSwitch = styled(Switch)(() => {\n return {\n padding: 8,\n \"& .MuiSwitch-track\": {\n borderRadius: 11,\n \"&::before, &::after\": {\n content: '\"\"',\n position: \"absolute\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n fontSize: 16,\n width: 28,\n height: 28,\n },\n },\n };\n});\n\n/** Renders a switch with your provided icons. */\nfunction SwitchWithIcons({\n checkedIcon: CheckedIcon,\n checkedIconStyles,\n uncheckedIcon: UncheckedIcon,\n uncheckedIconStyles,\n ...switchProps\n}: SwitchWithIconsProps) {\n const boxSx = {\n borderRadius: \"50%\",\n borderColor: \"white\",\n backgroundColor: \"white\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 0.25,\n };\n const defaultIconStyles = { color: \"black\", maxWidth: 16.5, maxHeight: 16.5 };\n return (\n <StyledSwitch\n checkedIcon={\n <Box sx={boxSx}>\n <CheckedIcon style={{ ...defaultIconStyles, ...checkedIconStyles }} />\n </Box>\n }\n icon={\n <Box sx={boxSx}>\n <UncheckedIcon style={{ ...defaultIconStyles, ...uncheckedIconStyles }} />\n </Box>\n }\n {...switchProps}\n />\n );\n}\n\nexport default SwitchWithIcons;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { PaletteMode } from \"@mui/material/styles\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport CssBaseline from \"@mui/material/CssBaseline\";\nimport { createTheme, ThemeProvider } from \"@mui/material/styles\";\nimport { createContext, useContext, useMemo, useState } from \"react\";\n\nexport interface ModeContextValue {\n toggleMode: () => void;\n mode: PaletteMode;\n}\n\nconst ModeContext = createContext<ModeContextValue>({\n toggleMode: () => {},\n mode: \"dark\",\n});\n\n/** Access the mode context directly. */\nexport function useMode<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, ModeContextValue> {\n const context = useContext(ModeContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"MODE_PROVIDER_NOT_FOUND\",\n \"Could not find the ModeProvider context. Please double-check that it is present.\",\n );\n }\n return context;\n}\n\nexport interface ModeProviderProps {\n /** The children that will have access to the current mode. */\n children: ReactNode;\n /** The initial mode. */\n mode?: PaletteMode;\n}\n\n/** Provides information about the current theme mode to its children components. */\nfunction ModeProvider({ children, mode: modeProp = \"dark\" }: ModeProviderProps) {\n const [mode, setMode] = useState<PaletteMode>(modeProp);\n\n const theme = useMemo(() => {\n return createTheme({\n palette: {\n mode,\n },\n components: {\n MuiPaper: {\n styleOverrides: {\n root: ({ theme }) => {\n return {\n border: 1,\n borderStyle: \"solid\",\n borderColor: theme.palette.divider,\n };\n },\n },\n },\n },\n });\n }, [mode]);\n\n return (\n <ModeContext.Provider\n value={{\n mode,\n toggleMode: () => {\n setMode((prev) => {\n return prev === \"light\" ? \"dark\" : \"light\";\n });\n },\n }}\n >\n <ThemeProvider theme={theme}>\n <CssBaseline />\n {children}\n </ThemeProvider>\n </ModeContext.Provider>\n );\n}\n\nexport default ModeProvider;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport { createContext, useContext, useEffect, useMemo, useState } from \"react\";\n\nexport interface ScreenSizeProps {\n /** The children that will be receiving the ScreenSizeContext. */\n children: ReactNode;\n /** The minimum screen width in pixels required to be considered a large screen. */\n largeScreenWidth?: number;\n /** The minimum screen height in pixels required to be considered a large screen. */\n largeScreenHeight?: number;\n}\n\nexport interface ScreenSizeContextValue {\n /** Whether the screen is a large screen or not. */\n isLargeScreen: boolean;\n /** The current window width. */\n windowWidth: number;\n /** The current window height. */\n windowHeight: number;\n}\n\nconst ScreenSizeContext = createContext<ScreenSizeContextValue>({\n windowWidth: 0,\n windowHeight: 0,\n isLargeScreen: false,\n});\n\n/** Access the screen size context directly. */\nexport function useScreenSize<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, ScreenSizeContextValue> {\n const context = useContext(ScreenSizeContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"SCREEN_SIZE_PROVIDER_NOT_FOUND\",\n \"Could not find the ScreenSizeProvider context. Please double-check that it is present.\",\n );\n }\n return context;\n}\n\n/** Provides context about the current screen size. */\nfunction ScreenSizeProvider({\n children,\n largeScreenWidth = 669,\n largeScreenHeight = 660,\n}: ScreenSizeProps) {\n const [windowWidth, setWindowWidth] = useState<number>(window.innerWidth);\n const [windowHeight, setWindowHeight] = useState<number>(window.innerHeight);\n\n useEffect(() => {\n function setDimensions() {\n setWindowWidth(window.innerWidth);\n setWindowHeight(window.innerHeight);\n }\n setDimensions();\n window.addEventListener(\"resize\", setDimensions);\n return () => {\n window.removeEventListener(\"resize\", setDimensions);\n };\n }, []);\n\n const isLargeScreen = useMemo(() => {\n return windowWidth > largeScreenWidth && windowHeight > largeScreenHeight;\n }, [windowWidth, windowHeight, largeScreenWidth, largeScreenHeight]);\n\n return (\n <ScreenSizeContext.Provider\n value={{\n isLargeScreen,\n windowWidth,\n windowHeight,\n }}\n >\n {children}\n </ScreenSizeContext.Provider>\n );\n}\n\nexport default ScreenSizeProvider;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { AlertColor } from \"@mui/material/Alert\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { wait } from \"@alextheman/utility\";\nimport { DataError } from \"@alextheman/utility/v6\";\nimport Alert from \"@mui/material/Alert\";\nimport Snackbar from \"@mui/material/Snackbar\";\nimport { createContext, useContext, useState } from \"react\";\n\nexport interface SnackbarProviderProps {\n /** The children that will have access to the snackbar context. */\n children: ReactNode;\n /** The amount of seconds to wait before hiding the snackbar. */\n autoHideDuration?: number;\n}\n\nexport interface SnackbarContextValue {\n /** A function that adds the snackbar to the page. */\n addSnackbar: (message: string, severity?: AlertColor, duration?: number) => void;\n}\n\nconst SnackbarContext = createContext<SnackbarContextValue | undefined>(undefined);\n\n/** Access the snackbar context directly. */\nexport function useSnackbar<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, SnackbarContextValue> {\n const context = useContext(SnackbarContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"SNACKBAR_PROVIDER_NOT_FOUND\",\n \"Could not find the SnackbarProvider context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, SnackbarContextValue>;\n}\n\n/** Controls the display of the snackbars on the page. */\nfunction SnackbarProvider({ children, autoHideDuration = 5000 }: SnackbarProviderProps) {\n const [open, setOpen] = useState<boolean>(false);\n const [autoHideDurationState, setAutoHideDurationState] = useState<number>(autoHideDuration);\n const [message, setMessage] = useState<string>(\"\");\n const [severity, setSeverity] = useState<AlertColor>(\"info\");\n\n function addSnackbar(message: string, severity?: AlertColor, duration?: number) {\n setOpen(true);\n setAutoHideDurationState(duration ?? autoHideDuration);\n setSeverity(severity ?? \"info\");\n setMessage(message);\n }\n\n async function handleClose() {\n setOpen(false);\n // Wait for 0.2 seconds to ensure that the message is only cleared after the snackbar is fully closed.\n // This prevents potential weird flickering that may occur if they happen synchronously.\n await wait(0.2);\n setMessage(\"\");\n }\n\n return (\n <SnackbarContext.Provider value={{ addSnackbar }}>\n <Snackbar open={open} autoHideDuration={autoHideDurationState} onClose={handleClose}>\n <Alert onClose={handleClose} severity={severity}>\n {message}\n </Alert>\n </Snackbar>\n {children}\n </SnackbarContext.Provider>\n );\n}\n\nexport default SnackbarProvider;\n","import Tooltip from \"@mui/material/Tooltip\";\nimport { MdOutlineDarkMode, MdOutlineLightMode } from \"react-icons/md\";\n\nimport SwitchWithIcons from \"src/components/SwitchWithIcons\";\nimport { useMode } from \"src/providers\";\n\n/** A toggle to switch between dark mode and light mode. Must be used in a `ModeProvider`. */\nfunction ModeToggle() {\n const { mode, toggleMode } = useMode();\n const isDarkMode = mode === \"dark\";\n const modeText = `Enable ${isDarkMode ? \"light\" : \"dark\"} mode`;\n\n return (\n <Tooltip title={modeText}>\n <SwitchWithIcons\n uncheckedIcon={MdOutlineLightMode}\n checkedIcon={MdOutlineDarkMode}\n checked={isDarkMode}\n onChange={toggleMode}\n aria-label={modeText}\n />\n </Tooltip>\n );\n}\n\nexport default ModeToggle;\n","import type { ReactNode } from \"react\";\n\nimport Card from \"@mui/material/Card\";\nimport CardContent from \"@mui/material/CardContent\";\nimport CardHeader from \"@mui/material/CardHeader\";\nimport Divider from \"@mui/material/Divider\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface PageProps {\n /** The Page title to show */\n title: ReactNode;\n /** The subtitle to show under the Page title */\n subtitle?: ReactNode;\n /** The actions to show in the page header */\n action?: ReactNode;\n /** The actual page contents */\n children: ReactNode;\n /** Disable the inner padding of the Page contents. */\n disablePadding?: boolean;\n /** Optional tabs to display in the header. */\n tabs?: ReactNode;\n}\n\n/** Renders a pre-styled Page that can be used to structure pages throughout your React apps. */\nfunction Page({ title, subtitle, action, children, tabs, disablePadding }: PageProps) {\n return (\n <Card>\n <CardHeader\n title={\n <>\n {typeof title === \"string\" ? <Typography variant=\"h6\">{title}</Typography> : title}\n {subtitle ? (\n typeof subtitle === \"string\" ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {subtitle}\n </Typography>\n ) : (\n subtitle\n )\n ) : null}\n </>\n }\n action={action}\n />\n {tabs}\n <Divider />\n {disablePadding ? children : <CardContent>{children}</CardContent>}\n </Card>\n );\n}\n\nexport default Page;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { ReactNode } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\nimport { createContext, useContext } from \"react\";\n\nexport interface QueryBoundaryProviderBaseProps<DataType> {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The data being loaded. */\n data?: DataType | null | undefined;\n /** A parser for the data. */\n dataParser?: (data: unknown) => NonNullable<DataType>;\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n}\n\nexport interface QueryBoundaryProviderPropsWithNoError<\n DataType,\n> extends QueryBoundaryProviderBaseProps<DataType> {\n error?: never;\n errorComponent?: never;\n logError?: never;\n}\n\nexport interface QueryBoundaryProviderPropsWithError<\n DataType,\n> extends QueryBoundaryProviderBaseProps<DataType> {\n /** The error given if the request gave an error. */\n error: unknown;\n /** The component to show if an error has been thrown. Note that this may not be provided unless the error prop has also been provided. */\n errorComponent?: ReactNode | ((error: unknown) => ReactNode);\n /** Whether you want to log the error to the console or not. */\n logError?: boolean;\n}\n\nexport type QueryBoundaryContextValue<DataType> =\n | QueryBoundaryProviderPropsWithNoError<DataType>\n | QueryBoundaryProviderPropsWithError<DataType>;\nexport type QueryBoundaryProviderProps<DataType> = QueryBoundaryContextValue<DataType> & {\n children: ReactNode;\n};\n\nconst QueryBoundaryContext = createContext<QueryBoundaryContextValue<unknown> | undefined>(\n undefined,\n);\n\n/** Access the QueryBoundary context directly. */\nexport function useQueryBoundary<DataType, Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<\n Strict,\n QueryBoundaryContextValue<DataType>\n> {\n const context = useContext(QueryBoundaryContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"QUERY_BOUNDARY_PROVIDER_NOT_FOUND\",\n \"Could not find the QueryBoundaryProvider context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, QueryBoundaryContextValue<DataType>>;\n}\n\n/**\n * A provider for a context that deals with state management when fetching data from an API.\n * This may be used over QueryBoundary if you require more control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryProvider<DataType>({\n children,\n loadingComponent = <CircularProgress />,\n ...contextProps\n}: QueryBoundaryProviderProps<DataType>) {\n return (\n <QueryBoundaryContext.Provider value={{ loadingComponent, ...contextProps }}>\n {children}\n </QueryBoundaryContext.Provider>\n );\n}\n\nexport default QueryBoundaryProvider;\n","import type { Key, ReactNode } from \"react\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport Typography from \"@mui/material/Typography\";\nimport { Fragment } from \"react\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryDataMapBaseProps<ItemType> {\n /**\n * The elements to show after data has been loaded.\n *\n * This is best provided as a function with a data argument that guarantees the data will not be undefined by the time you receive it here.\n */\n children: ReactNode | ((data: ItemType) => ReactNode);\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n /** The component to show if the array is empty. */\n emptyComponent?: ReactNode;\n /** Throw an error if the provided data is not an array. (defaults to `true`) */\n strictlyRequireArray?: boolean;\n /**\n * A function that takes a data item and returns the key to be used for the item.\n *\n * If not provided, it will fall back to using the index.\n */\n itemKey?: (item: ItemType, index: number) => Key;\n}\n\nexport interface QueryBoundaryDataMapPropsWithItemParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n /** A parser for each data item. */\n itemParser: (data: unknown) => ItemType;\n dataParser?: never;\n}\n\nexport interface QueryBoundaryDataMapPropsWithDataParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n /** A parser for each data item. */\n dataParser: (data: unknown) => Array<ItemType>;\n itemParser?: never;\n}\n\nexport interface QueryBoundaryDataMapPropsWithNoParser<\n ItemType,\n> extends QueryBoundaryDataMapBaseProps<ItemType> {\n dataParser?: never;\n itemParser?: never;\n}\n\nexport type QueryBoundaryDataMapProps<ItemType> =\n | QueryBoundaryDataMapPropsWithItemParser<ItemType>\n | QueryBoundaryDataMapPropsWithDataParser<ItemType>\n | QueryBoundaryDataMapPropsWithNoParser<ItemType>;\n\n/**\n * The component responsible for handling an array of data provided by `QueryBoundaryProvider`.\n *\n * It will map through the data array, rendering the result of the children function in a fragment with a key of its index in the list, unless overridden by the `itemKey` prop.\n *\n * @template ItemType - The type of data being loaded.\n *\n * @throws {DataError} If the data provided by `QueryBoundaryProvider` is not an array, and the `strictlyRequireArray` prop is `true` (it is by default).\n */\nfunction QueryBoundaryDataMap<ItemType>({\n children,\n loadingComponent: propLoadingComponent,\n itemKey,\n itemParser,\n dataParser: propDataParser,\n emptyComponent = <Typography>No data present</Typography>,\n strictlyRequireArray = true,\n}: QueryBoundaryDataMapProps<ItemType>) {\n const {\n isLoading,\n data,\n dataParser: contextDataParser,\n loadingComponent: contextLoadingComponent,\n error,\n } = useQueryBoundary<Array<ItemType>>();\n\n const dataParser = propDataParser ?? contextDataParser;\n const loadingComponent = propLoadingComponent ?? contextLoadingComponent;\n\n if (isLoading) {\n return <>{loadingComponent}</>;\n }\n\n if (error) {\n return null;\n }\n\n if (data === null || data === undefined) {\n return null;\n }\n\n if (!Array.isArray(data)) {\n if (strictlyRequireArray) {\n throw new DataError(\n { data, strictlyRequireArray },\n \"NOT_AN_ARRAY\",\n \"Expected the data to be an array but it was not an array.\",\n );\n }\n return null;\n }\n\n if (data.length === 0) {\n return <>{emptyComponent}</>;\n }\n\n let items: Array<ItemType>;\n\n if (dataParser) {\n items = dataParser(data);\n } else if (itemParser) {\n items = data.map(itemParser);\n } else {\n items = data;\n }\n\n return (\n <>\n {items.map((item, index) => {\n return (\n <Fragment key={itemKey ? itemKey(item, index) : index}>\n {typeof children === \"function\" ? children(item) : children}\n </Fragment>\n );\n })}\n </>\n );\n}\n\nexport default QueryBoundaryDataMap;\n","import type { ReactNode } from \"react\";\n\nimport Alert from \"@mui/material/Alert\";\nimport { useRef } from \"react\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryErrorProps {\n /** The component to show if an error has been thrown. */\n children?: ReactNode | ((error: unknown) => ReactNode);\n /** An option to log the error to the console. */\n logError?: boolean;\n}\n\n/**\n * The component responsible for showing any errors provided by QueryBoundaryProvider.\n */\nfunction QueryBoundaryError({ children, logError: propsLogError }: QueryBoundaryErrorProps) {\n const {\n data,\n error,\n errorComponent: contextErrorComponent,\n logError: contextLogError,\n } = useQueryBoundary();\n const logError = propsLogError ?? contextLogError;\n const warnedOnce = useRef(false);\n\n const errorComponent = children ?? contextErrorComponent;\n\n if (error) {\n if (logError && !warnedOnce.current) {\n if (data !== null && data !== undefined) {\n console.error(\n \"An error has occurred but data is still present. This may indicate an invalid query state.\",\n { data, error },\n );\n }\n console.error(error);\n warnedOnce.current = true;\n }\n if (typeof errorComponent === \"function\") {\n return errorComponent(error);\n }\n if (errorComponent) {\n return <>{errorComponent}</>;\n }\n\n return (\n <Alert severity=\"error\">\n {typeof error === \"object\" && \"message\" in error && typeof error.message === \"string\"\n ? error.message\n : \"An unknown error has occured. Please try again later.\"}\n </Alert>\n );\n }\n\n return null;\n}\n\nexport default QueryBoundaryError;\n","import type { ReactNode } from \"react\";\n\nimport Alert from \"@mui/material/Alert\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryNullablePropsWithUndefinedOrNull {\n /** The component to show if no error was thrown but data is undefined */\n undefinedComponent?: ReactNode;\n /** The component to show if no error was thrown but data is null */\n nullComponent?: ReactNode;\n nullableComponent?: never;\n}\n\nexport interface QueryBoundaryNullablePropsWithNullable {\n undefinedComponent?: never;\n nullComponent?: never;\n /** The component to show if no error was thrown but data is undefined or null */\n nullableComponent?: ReactNode;\n}\n\nexport type QueryBoundaryNullableProps =\n | QueryBoundaryNullablePropsWithUndefinedOrNull\n | QueryBoundaryNullablePropsWithNullable;\n\n/** The component responsible for handling cases when the data provided by `QueryBoundaryProvider` may be missing. */\nfunction QueryBoundaryNullable({\n undefinedComponent,\n nullComponent,\n nullableComponent,\n}: QueryBoundaryNullableProps) {\n const { isLoading, data, error } = useQueryBoundary();\n\n if (isLoading) {\n return null;\n }\n\n if (error) {\n return null;\n }\n\n if (data === null || data === undefined) {\n if (nullableComponent) {\n return <>{nullableComponent}</>;\n }\n\n if (data === undefined) {\n if (undefinedComponent) {\n return <>{undefinedComponent}</>;\n }\n }\n\n if (data === null) {\n if (nullComponent) {\n return <>{nullComponent}</>;\n }\n }\n\n return <Alert severity=\"error\">Failed to load data. Please try again later.</Alert>;\n }\n\n return null;\n}\n\nexport default QueryBoundaryNullable;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryErrorProps } from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport type { QueryBoundaryNullableProps } from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\n\nimport QueryBoundaryError from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport QueryBoundaryNullable from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\n\nexport type QueryBoundaryFallbackProps = Omit<QueryBoundaryErrorProps, \"children\"> & {\n /** The component to show if an error has been thrown. */\n errorComponent?: ReactNode | ((error: unknown) => ReactNode);\n} & QueryBoundaryNullableProps;\n\n/**\n * The component responsible for handling both errors and nullable data from `QueryBoundaryProvider`\n */\nfunction QueryBoundaryFallback({\n errorComponent,\n logError,\n ...queryBoundaryNullableProps\n}: QueryBoundaryFallbackProps) {\n return (\n <>\n <QueryBoundaryError logError={logError}>{errorComponent}</QueryBoundaryError>\n <QueryBoundaryNullable {...queryBoundaryNullableProps} />\n </>\n );\n}\n\nexport default QueryBoundaryFallback;\n","/* \neslint-disable react/prop-types -- ESLint gives false positives because it thinks the props are not typed.\nHowever, they are - this compound component are all typed and the prop types are recognised by TypeScript.\n*/\nimport type { JSX, ReactNode } from \"react\";\n\nimport QueryBoundaryError from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport QueryBoundaryFallback from \"src/groups/QueryBoundary/QueryBoundaryFallback\";\nimport QueryBoundaryNullable from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\nimport QueryBoundaryProvider from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBase<DataType> {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The error given if the response gave an error. */\n error?: unknown;\n /** The data being loaded. */\n data: DataType;\n}\n\nexport interface CreateBaseQueryBoundaryParameters<DataType> {\n query: QueryBase<DataType>;\n}\n\nexport interface DefaultQueryBoundaryComponentsBase {\n Context: (props: { children: ReactNode }) => JSX.Element;\n Error: typeof QueryBoundaryError;\n Fallback: typeof QueryBoundaryFallback;\n Nullable: typeof QueryBoundaryNullable;\n}\n\n/** A creator function to create the base system of QueryBoundary components with the data fully typed throughout. */\nfunction createBaseQueryBoundary<DataType>({\n query,\n}: CreateBaseQueryBoundaryParameters<DataType>): DefaultQueryBoundaryComponentsBase {\n return {\n Context: ({ children }) => {\n return (\n <QueryBoundaryProvider isLoading={query.isLoading} error={query.error} data={query.data}>\n {children}\n </QueryBoundaryProvider>\n );\n },\n Error: QueryBoundaryError,\n Fallback: QueryBoundaryFallback,\n Nullable: QueryBoundaryNullable,\n };\n}\n\nexport default createBaseQueryBoundary;\n","import type {\n DefaultQueryBoundaryComponentsBase,\n QueryBase,\n} from \"src/v7/groups/QueryBoundary/createBaseQueryBoundary\";\n\nimport QueryBoundaryDataMap from \"src/groups/QueryBoundary/QueryBoundaryDataMap\";\nimport createBaseQueryBoundary from \"src/v7/groups/QueryBoundary/createBaseQueryBoundary\";\n\nexport interface QueryList<DataType> extends Omit<QueryBase<DataType>, \"data\"> {\n /** The data being loaded. */\n data: Array<DataType> | null | undefined;\n}\n\nexport interface CreateListQueryBoundaryParameters<DataType> {\n query: QueryList<DataType>;\n}\n\nexport interface DefaultQueryBoundaryListComponents<\n DataType,\n> extends DefaultQueryBoundaryComponentsBase {\n DataMap: typeof QueryBoundaryDataMap<DataType>;\n}\n\n/** A creator function to create the system of QueryBoundary components with the data treated as an array of data items, fully typed throughout. */\nfunction createListQueryBoundary<DataType>({\n query,\n}: CreateListQueryBoundaryParameters<DataType>): DefaultQueryBoundaryListComponents<DataType> {\n const baseComponents = createBaseQueryBoundary({ query });\n\n return {\n ...baseComponents,\n DataMap: QueryBoundaryDataMap,\n };\n}\n\nexport default createListQueryBoundary;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryFallbackProps, QueryBoundaryProviderProps } from \"src/groups\";\nimport type { QueryBoundaryDataMapProps } from \"src/groups/QueryBoundary/QueryBoundaryDataMap\";\n\nimport createListQueryBoundary from \"src/v7/groups/QueryBoundary/createListQueryBoundary\";\n\nexport type QueryBoundaryMapProps<ItemType> = Omit<\n QueryBoundaryProviderProps<Array<ItemType>>,\n \"children\" | \"logError\"\n> &\n Omit<QueryBoundaryFallbackProps, \"errorComponent\"> &\n QueryBoundaryDataMapProps<ItemType>;\n\n/**\n * An in-line component that handles an array of data provided by `QueryBoundaryProvider`.\n *\n * This may be used over QueryBoundaryProvider/QueryBoundaryDataMap if you don't require as much control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryMap<ItemType>({\n loadingComponent,\n undefinedComponent,\n nullComponent,\n nullableComponent,\n logError,\n errorComponent,\n children,\n isLoading,\n error,\n data,\n dataParser,\n itemParser,\n itemKey,\n}: QueryBoundaryMapProps<ItemType>) {\n const QueryBoundary = createListQueryBoundary({ query: { isLoading, error, data } });\n\n let boundaryErrorComponent: ReactNode = (\n <QueryBoundary.Fallback logError={logError} errorComponent={errorComponent} />\n );\n\n if (nullableComponent) {\n boundaryErrorComponent = (\n <QueryBoundary.Fallback\n nullableComponent={nullableComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n } else if (undefinedComponent || nullComponent) {\n boundaryErrorComponent = (\n <QueryBoundary.Fallback\n undefinedComponent={undefinedComponent}\n nullComponent={nullComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n }\n\n let boundaryDataMapComponent: ReactNode = (\n <QueryBoundary.DataMap loadingComponent={loadingComponent} itemKey={itemKey}>\n {children}\n </QueryBoundary.DataMap>\n );\n\n if (dataParser) {\n boundaryDataMapComponent = (\n <QueryBoundary.DataMap\n loadingComponent={loadingComponent}\n itemKey={itemKey}\n dataParser={dataParser}\n >\n {children}\n </QueryBoundary.DataMap>\n );\n } else if (itemParser) {\n boundaryDataMapComponent = (\n <QueryBoundary.DataMap\n loadingComponent={loadingComponent}\n itemKey={itemKey}\n itemParser={itemParser}\n >\n {children}\n </QueryBoundary.DataMap>\n );\n }\n\n return (\n <QueryBoundary.Context>\n {boundaryErrorComponent}\n {boundaryDataMapComponent}\n </QueryBoundary.Context>\n );\n}\n\nexport default QueryBoundaryMap;\n","import type { ReactNode } from \"react\";\n\nimport { useQueryBoundary } from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBoundaryDataProps<DataType> {\n /**\n * The elements to show after data has been loaded.\n * This is best provided as a function with a data argument that guarantees the data will not be undefined by the time you receive it here.\n */\n children: ReactNode | ((data: NonNullable<DataType>) => ReactNode);\n /** A parser for the data. */\n dataParser?: (data: unknown) => NonNullable<DataType>;\n /** The component to show when the data is being fetched. */\n loadingComponent?: ReactNode;\n}\n\n/**\n * The component responsible for showing the data provided by QueryBoundaryProvider.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryData<DataType>({\n children,\n dataParser: propDataParser,\n loadingComponent,\n}: QueryBoundaryDataProps<DataType>) {\n const {\n isLoading,\n data,\n dataParser: contextDataParser,\n loadingComponent: contextLoadingComponent,\n error,\n } = useQueryBoundary<DataType>();\n const dataParser = propDataParser ?? contextDataParser;\n\n if (error) {\n return null;\n }\n\n if (isLoading) {\n return <>{loadingComponent ?? contextLoadingComponent}</>;\n }\n\n if (data === null || data === undefined) {\n return null;\n }\n\n return (\n <>\n {typeof children === \"function\" ? children(dataParser ? dataParser(data) : data) : children}\n </>\n );\n}\n\nexport default QueryBoundaryData;\n","import type {\n DefaultQueryBoundaryComponentsBase,\n QueryBase,\n} from \"src/v7/groups/QueryBoundary/createBaseQueryBoundary\";\n\nimport QueryBoundaryData from \"src/groups/QueryBoundary/QueryBoundaryData\";\nimport createBaseQueryBoundary from \"src/v7/groups/QueryBoundary/createBaseQueryBoundary\";\n\nexport interface QueryItem<DataType> extends Omit<QueryBase<DataType>, \"data\"> {\n /** The data being loaded. */\n data: DataType | null | undefined;\n}\n\nexport interface CreateItemQueryBoundaryParameters<DataType> {\n query: QueryItem<DataType>;\n}\n\nexport interface DefaultQueryBoundaryItemComponents<\n DataType,\n> extends DefaultQueryBoundaryComponentsBase {\n Data: typeof QueryBoundaryData<DataType>;\n}\n\n/** A creator function to create the system of QueryBoundary components with the data treated as a single data item, fully typed throughout. */\nfunction createItemQueryBoundary<DataType>({\n query,\n}: CreateItemQueryBoundaryParameters<DataType>): DefaultQueryBoundaryItemComponents<DataType> {\n const baseComponents = createBaseQueryBoundary({ query });\n\n return {\n ...baseComponents,\n Data: QueryBoundaryData,\n };\n}\n\nexport default createItemQueryBoundary;\n","import type { ReactNode } from \"react\";\n\nimport type { QueryBoundaryDataProps, QueryBoundaryProviderProps } from \"src/groups\";\nimport type { QueryBoundaryFallbackProps } from \"src/groups/QueryBoundary/QueryBoundaryFallback\";\n\nimport CircularProgress from \"@mui/material/CircularProgress\";\n\nimport createItemQueryBoundary from \"src/v7/groups/QueryBoundary/createItemQueryBoundary\";\n\nexport type QueryBoundaryWrapperProps<DataType> = Omit<\n QueryBoundaryProviderProps<DataType>,\n \"children\" | \"logError\"\n> &\n Omit<QueryBoundaryFallbackProps, \"errorComponent\"> &\n Omit<QueryBoundaryDataProps<DataType>, \"showOnError\" | \"onUndefined\" | \"onNull\" | \"onNullable\">;\n\n/**\n * An in-line component that deals with state management when fetching data from an API.\n * This may be used over QueryBoundaryProvider if you don't require as much control over the placement of the error message and data display.\n *\n * @template DataType - The type of data being loaded.\n */\nfunction QueryBoundaryWrapper<DataType>({\n children,\n errorComponent,\n undefinedComponent,\n nullComponent,\n nullableComponent,\n logError,\n loadingComponent = <CircularProgress />,\n isLoading,\n error,\n data,\n dataParser,\n}: QueryBoundaryWrapperProps<DataType>) {\n const QueryBoundary = createItemQueryBoundary({ query: { isLoading, error, data } });\n\n let boundaryFallbackComponent: ReactNode = (\n <QueryBoundary.Fallback logError={logError} errorComponent={errorComponent} />\n );\n\n if (nullableComponent) {\n boundaryFallbackComponent = (\n <QueryBoundary.Fallback\n nullableComponent={nullableComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n } else if (undefinedComponent || nullComponent) {\n boundaryFallbackComponent = (\n <QueryBoundary.Fallback\n undefinedComponent={undefinedComponent}\n nullComponent={nullComponent}\n logError={logError}\n errorComponent={errorComponent}\n />\n );\n }\n\n return (\n <QueryBoundary.Context>\n {boundaryFallbackComponent}\n <QueryBoundary.Data loadingComponent={loadingComponent} dataParser={dataParser}>\n {children}\n </QueryBoundary.Data>\n </QueryBoundary.Context>\n );\n}\n\nexport default QueryBoundaryWrapper;\n","import type { SxProps, Theme } from \"@mui/material/styles\";\nimport type { ComponentProps } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\nimport { stripIndent } from \"common-tags\";\nimport { LiveEditor, LiveError, LivePreview, LiveProvider } from \"react-live\";\n\nimport { useMode } from \"src/providers\";\n\nexport interface ReactPlaygroundProps extends ComponentProps<typeof LiveProvider> {\n /** Extra styling to apply to the preview. Must be compatible with the Material UI `sx` prop. */\n previewStyles?: SxProps<Theme>;\n}\n\n/** Renders a playground to help demonstrate your React code in an interactive setting. */\nfunction ReactPlayground({ code, previewStyles, ...liveProviderProps }: ReactPlaygroundProps) {\n const { mode } = useMode();\n const defaultPreviewStyles: SxProps<Theme> = {\n backgroundColor: mode === \"dark\" ? \"black\" : \"white\",\n border: 0.3,\n borderRadius: 1,\n padding: 2,\n borderColor: \"darkgray\",\n };\n const allPreviewStyles = previewStyles\n ? { ...defaultPreviewStyles, ...previewStyles }\n : { ...defaultPreviewStyles };\n return (\n <Box sx={{ borderRadius: 1, border: 0.5, padding: 2 }}>\n <LiveProvider {...liveProviderProps} code={stripIndent(code ?? \"\")}>\n <Typography variant=\"h5\">Code</Typography>\n <Box\n sx={{\n border: 0.3,\n borderRadius: 0.3,\n borderColor: \"darkgray\",\n }}\n >\n <LiveEditor />\n </Box>\n <br />\n <Typography variant=\"h5\">Result</Typography>\n <Box sx={allPreviewStyles}>\n <LivePreview />\n <LiveError />\n </Box>\n </LiveProvider>\n </Box>\n );\n}\n\nexport default ReactPlayground;\n","import { fillArray } from \"@alextheman/utility\";\nimport Skeleton from \"@mui/material/Skeleton\";\nimport TableCell from \"@mui/material/TableCell\";\nimport TableRow from \"@mui/material/TableRow\";\n\nexport interface SkeletonRowProps {\n /** The number of columns the SkeletonRow should display. */\n columns: number;\n}\n\n/** Renders the skeleton of a table row. Often helpful to represent the loading state of the data in your table. */\nfunction SkeletonRow({ columns }: SkeletonRowProps) {\n return (\n <TableRow>\n {fillArray((index) => {\n return (\n <TableCell key={index}>\n <Skeleton />\n </TableCell>\n );\n }, columns)}\n </TableRow>\n );\n}\n\nexport default SkeletonRow;\n","import { ModeToggle } from \"src/components\";\n\n/** @deprecated This component has been renamed to `ModeToggle`. */\nconst DarkModeToggle = ModeToggle;\n\nexport default DarkModeToggle;\n","import type { ButtonOwnProps } from \"@mui/material/Button\";\nimport type { ElementType, MouseEvent as ReactMouseEvent, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport MUIButton from \"@mui/material/Button\";\nimport Menu from \"@mui/material/Menu\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { MdArrowDropDown, MdArrowDropUp } from \"react-icons/md\";\n\nexport interface DropdownMenuProps {\n children: ReactNode | ((closeMenu: () => void) => ReactNode);\n buttonChildren?: ReactNode;\n button?: ElementType;\n // Omit endIcon because the built-in isOpenIcon and isClosedIcon gives more control.\n // onClick is also omitted because that controls anchorElement, and the onOpen/onClose functions can be used instead.\n buttonProps?: Omit<ButtonOwnProps, \"onClick\" | \"endIcon\">;\n isOpenIcon?: ReactNode;\n isClosedIcon?: ReactNode;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\n/**\n * @deprecated This component does not support the new context-based pattern and individual DropdownMenuItem components. Please use DropdownMenu2 instead.\n */\nfunction DropdownMenu({\n children,\n button: Button = MUIButton,\n buttonChildren = \"Menu\",\n buttonProps: incomingButtonProps,\n isOpenIcon = <MdArrowDropUp />,\n isClosedIcon = <MdArrowDropDown />,\n onOpen,\n onClose,\n}: DropdownMenuProps) {\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n const isDropdownOpen = useMemo(() => {\n return !!anchorElement;\n }, [anchorElement]);\n\n const buttonProps: Record<string, unknown> = {\n ...incomingButtonProps,\n onClick: (event: ReactMouseEvent<HTMLElement>) => {\n setAnchorElement(event.currentTarget);\n },\n \"aria-controls\": isDropdownOpen ? \"dropdown-menu\" : undefined,\n \"aria-haspopup\": \"true\",\n \"aria-expanded\": isDropdownOpen,\n };\n\n if (Button === MUIButton) {\n buttonProps.endIcon = isDropdownOpen ? isOpenIcon : isClosedIcon;\n }\n\n useEffect(() => {\n if (isDropdownOpen && onOpen) {\n onOpen();\n } else if (!isDropdownOpen && onClose) {\n onClose();\n }\n }, [isDropdownOpen, onOpen, onClose]);\n\n return (\n <Box>\n <Button {...buttonProps}>{buttonChildren}</Button>\n <Menu\n id=\"dropdown-menu\"\n anchorEl={anchorElement}\n open={isDropdownOpen}\n onClose={() => {\n setAnchorElement(null);\n }}\n >\n {typeof children === \"function\" ? (\n <Box>\n {children(() => {\n setAnchorElement(null);\n })}\n </Box>\n ) : (\n children\n )}\n </Menu>\n </Box>\n );\n}\n\nexport default DropdownMenu;\n","import type { OptionalOnCondition } from \"@alextheman/utility\";\nimport type { Dispatch, ReactNode, SetStateAction } from \"react\";\n\nimport type { ContextHookOptions } from \"src/types\";\n\nimport { DataError } from \"@alextheman/utility/v6\";\nimport { createContext, useContext, useMemo, useState } from \"react\";\n\nexport interface DropdownMenuContextValue {\n /** A function responsible for closing the dropdown menu. */\n closeMenu: () => void;\n /** Represents whether or not the dropdown is open. */\n isDropdownOpen: boolean;\n}\n\nexport type DropdownMenuInternalContextValue = DropdownMenuContextValue & {\n anchorElement: HTMLElement | null;\n setAnchorElement: Dispatch<SetStateAction<HTMLElement | null>>;\n};\nconst DropdownMenuContext = createContext<DropdownMenuInternalContextValue | undefined>(undefined);\n\n/**\n Access the DropdownMenu context directly.\n */\nexport function useDropdownMenu<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, DropdownMenuContextValue> {\n const context = useContext(DropdownMenuContext);\n if (strict && !context) {\n throw new DataError(\n { strict, context },\n \"DROPDOWN_MENU_NOT_FOUND\",\n \"Could not find the DropdownMenu context. Please double-check that it is present.\",\n );\n }\n return context as OptionalOnCondition<Strict, DropdownMenuContextValue>;\n}\n\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function useDropdownMenuInternal<Strict extends boolean = true>({\n strict = true as Strict,\n}: ContextHookOptions<Strict> = {}): OptionalOnCondition<Strict, DropdownMenuInternalContextValue> {\n return useDropdownMenu({ strict }) as OptionalOnCondition<\n Strict,\n DropdownMenuInternalContextValue\n >;\n}\n\nexport interface DropdownMenuProviderProps {\n /** The children to render inside of the dropdown. */\n children: ReactNode;\n}\n\n/** Provides shared context for the `DropdownMenu` related components. */\nfunction DropdownMenuProvider({ children }: DropdownMenuProviderProps) {\n const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);\n\n const isDropdownOpen = useMemo(() => {\n return !!anchorElement;\n }, [anchorElement]);\n\n function closeMenu() {\n setAnchorElement(null);\n }\n\n return (\n <DropdownMenuContext.Provider\n value={{ closeMenu, isDropdownOpen, anchorElement, setAnchorElement }}\n >\n {children}\n </DropdownMenuContext.Provider>\n );\n}\n\nexport default DropdownMenuProvider;\n","import type { MenuProps } from \"@mui/material/Menu\";\nimport type { MouseEvent, ReactNode } from \"react\";\n\nimport Menu from \"@mui/material/Menu\";\n\nimport { useDropdownMenuInternal } from \"src/v7/components/DropdownMenu/DropdownMenuProvider\";\n\nexport interface DropdownMenuProps extends Omit<MenuProps, \"anchorEl\" | \"open\"> {\n /** The children to render inside of the dropdown. */\n children: ReactNode;\n}\n\n/**\n * Renders a menu component that can be used alongside the `DropdownMenuProvider`.\n *\n * This component's open state would be controlled by the `DropdownMenuTrigger`.\n */\nfunction DropdownMenu({ children, onClose, ...menuProps }: DropdownMenuProps) {\n const { anchorElement, isDropdownOpen, closeMenu } = useDropdownMenuInternal();\n\n return (\n <Menu\n anchorEl={anchorElement}\n open={isDropdownOpen}\n onClose={(event: MouseEvent, reason) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClose) {\n onClose(event, reason);\n }\n }}\n {...menuProps}\n >\n {children}\n </Menu>\n );\n}\n\nexport default DropdownMenu;\n","import type Button from \"@mui/material/Button\";\nimport type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n ComponentPropsWithRef,\n ElementType,\n ReactNode,\n} from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { useDropdownMenu } from \"src/v7/components/DropdownMenu/DropdownMenuProvider\";\n\nexport type DropdownMenuItemProps<RootComponent extends ElementType = typeof Button> = {\n /**\n * An optional component to provide to override the current component.\n *\n * Note that the provided component must:\n * - accept a `to` prop.\n * - correctly handle the forwarded `ref`.\n * - render a valid anchor element (or equivalent) for proper accessibility.\n */\n component?: RootComponent;\n /** The children to be rendered within the menu item. */\n children?: ReactNode;\n /** The ref to forward to allow it to be used with polymorphic components */\n ref?: ComponentPropsWithRef<RootComponent>[\"ref\"];\n /** A function to execute after clicking the item. */\n onClick?: ComponentProps<RootComponent>[\"onClick\"];\n} & Omit<ComponentPropsWithoutRef<RootComponent>, \"children\" | \"ref\"> &\n MenuItemOwnProps;\n\n/** Represents a menu item to be used inside the `DropdownMenu`. It must be used as children of the `DropdownMenu` component. */\nfunction DropdownMenuItem<RootComponent extends ElementType = typeof Button>({\n component,\n children,\n ref,\n onClick,\n ...menuItemProps\n}: DropdownMenuItemProps<RootComponent>) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={component}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (onClick) {\n onClick(event);\n }\n if (event.defaultPrevented) {\n return;\n }\n closeMenu();\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuItem;\n","import type {\n DropdownMenuContextValue as DropdownMenuContextValueV7,\n DropdownMenuProps,\n} from \"src/v7\";\n\nimport { DropdownMenu, useDropdownMenu as useDropdownMenuV7 } from \"src/v7\";\n\nexport type DropdownMenuContextValue = DropdownMenuContextValueV7;\n\nexport const useDropdownMenu = useDropdownMenuV7;\n\n/**\n * @deprecated Please use `DropdownMenuProps` from `@alextheman/components/v7` instead.\n *\n * This will be replaced in the root entrypoint in a future release.\n */\nexport type DropdownMenu2Props = DropdownMenuProps;\n\n/**\n * @deprecated Please use `DropdownMenu` from `@alextheman/components/v7` instead.\n *\n * This will be replaced in the root entrypoint in a future release.\n */\nconst DropdownMenu2 = DropdownMenu;\n\nexport default DropdownMenu2;\n","import type { ElementType } from \"react\";\n\nimport type { DropdownMenuItemProps as DropdownMenuItemPropsV7 } from \"src/v7\";\n\nimport { DropdownMenuItem as DropdownMenuItemV7 } from \"src/v7\";\n\nexport type DropdownMenuItemProps<RootComponent extends ElementType> =\n DropdownMenuItemPropsV7<RootComponent>;\n\nconst DropdownMenuItem = DropdownMenuItemV7;\n\nexport default DropdownMenuItem;\n","import DropdownMenu2 from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\n\nexport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nexport { default as DropdownMenuItem } from \"src/deprecated/DropdownMenu2/DropdownMenuItem\";\n\nexport type { DropdownMenu2Props } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nexport type { DropdownMenuItemProps } from \"src/deprecated/DropdownMenu2/DropdownMenuItem\";\n\nexport default DropdownMenu2;\n","import type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type { ComponentProps, MouseEventHandler, ReactNode, Ref } from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { ExternalLink } from \"src/components\";\nimport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\n\nexport interface DropdownMenuExternalLinkProps extends MenuItemOwnProps {\n ref?: Ref<HTMLAnchorElement>;\n href: ComponentProps<typeof ExternalLink>[\"href\"];\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children: ReactNode;\n}\n\n/** @deprecated Please use `<DropdownMenuItem component={ExternalLink} />` instead. */\nfunction DropdownMenuExternalLink({\n ref,\n href,\n children,\n onClick,\n ...menuItemProps\n}: DropdownMenuExternalLinkProps) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={ExternalLink}\n href={href}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClick) {\n onClick(event);\n }\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuExternalLink;\n","import type { LinkProps } from \"@mui/material/Link\";\nimport type { ElementType, ReactNode, Ref } from \"react\";\n\nimport MUILink from \"@mui/material/Link\";\nimport { Link as ReactDOMLink } from \"react-router-dom\";\n\nexport interface InternalLinkProps extends Omit<LinkProps, \"href\" | \"component\"> {\n /** The path to navigate to */\n to: `/${string}` | `~/${string}` | (string & {});\n /**\n * An optional component to provide to override the current component.\n *\n * Note that the provided component must:\n * - accept a `to` prop\n * - correctly handle the forwarded `ref`\n * - render a valid anchor element (or equivalent) for proper accessibility\n */\n component?: ElementType;\n href?: never;\n /** The readable content to display on the link. */\n children: ReactNode;\n /** An optional ref to allow it to be used with polymorphic components. */\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A stylised link for navigating within your application.\n *\n * Uses the app router for client-side navigation and opens the destination in the same tab.\n *\n * Defaults to a React Router implementation but can be overridden via the `component` prop.\n *\n * @deprecated This component is not compatible with the rest of the Wouter setup for use in v7. Please use `InternalLink` from `@alextheman/components/v7` instead. This component will be replaced when v7 officially comes out.\n */\nfunction InternalLink({\n to,\n component = ReactDOMLink,\n children,\n ref,\n ...linkProps\n}: InternalLinkProps) {\n return (\n <MUILink component={component} to={to} ref={ref} {...linkProps}>\n {children}\n </MUILink>\n );\n}\n\nexport default InternalLink;\n","import type { MenuItemOwnProps } from \"@mui/material/MenuItem\";\nimport type { ComponentProps, MouseEventHandler, ReactNode, Ref } from \"react\";\n\nimport MenuItem from \"@mui/material/MenuItem\";\n\nimport { useDropdownMenu } from \"src/deprecated/DropdownMenu2/DropdownMenu2\";\nimport InternalLink from \"src/deprecated/InternalLink\";\n\nexport interface DropdownMenuInternalLinkProps extends MenuItemOwnProps {\n ref?: Ref<HTMLAnchorElement>;\n to: ComponentProps<typeof InternalLink>[\"to\"];\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children: ReactNode;\n}\n\n/** @deprecated Please use `<DropdownMenuItem component={InternalLink} />` instead. */\nfunction DropdownMenuInternalLink({\n to,\n ref,\n children,\n onClick,\n ...menuItemProps\n}: DropdownMenuInternalLinkProps) {\n const { closeMenu } = useDropdownMenu();\n\n return (\n <MenuItem\n component={InternalLink}\n to={to}\n ref={ref}\n {...menuItemProps}\n onClick={(event) => {\n if (!event.defaultPrevented) {\n closeMenu();\n }\n if (onClick) {\n onClick(event);\n }\n }}\n >\n {children}\n </MenuItem>\n );\n}\n\nexport default DropdownMenuInternalLink;\n","import type { OverridableComponent } from \"@mui/material/OverridableComponent\";\nimport type { SvgIconTypeMap } from \"@mui/material/SvgIcon\";\nimport type { ElementType, MouseEvent as ReactMouseEvent, ReactNode } from \"react\";\n\nimport Box from \"@mui/material/Box\";\nimport Popover from \"@mui/material/Popover\";\nimport { useId, useState } from \"react\";\nimport { MdVisibility } from \"react-icons/md\";\n\nexport interface IconWithPopoverProps {\n icon?:\n | (OverridableComponent<SvgIconTypeMap<unknown, \"svg\">> & {\n muiName: string;\n })\n | ElementType;\n onOpen?: () => void;\n onClose?: () => void;\n iconProps?: SvgIconTypeMap<unknown, \"svg\">[\"props\"];\n children: ReactNode;\n}\n\n/**\n * @deprecated This component is not well-designed for accessibility purposes. Please use the `Tooltip` component from `@mui/material` instead.\n *\n * @example\n * ```tsx\n * <Tooltip title=\"Text to display on hover\">\n * <MdVisibility />\n * </Tooltip>\n * ```\n */\nfunction IconWithPopover({\n icon: Icon = MdVisibility,\n onOpen,\n onClose,\n iconProps,\n children,\n}: IconWithPopoverProps) {\n const [anchorElement, setAnchorElement] = useState<Element | null>(null);\n const isPopoverOpen = !!anchorElement;\n const popoverId = useId();\n\n function handleOpen(event: ReactMouseEvent<SVGSVGElement, MouseEvent>) {\n setAnchorElement(event.currentTarget);\n if (onOpen) {\n onOpen();\n }\n }\n\n function handleClose() {\n setAnchorElement(null);\n if (onClose) {\n onClose();\n }\n }\n\n return (\n <Box>\n <Icon\n aria-owns={isPopoverOpen ? popoverId : undefined}\n aria-haspopup=\"true\"\n onMouseEnter={handleOpen}\n onMouseLeave={handleClose}\n {...iconProps}\n />\n <Popover\n id={popoverId}\n disablePortal\n disableScrollLock\n slotProps={{\n root: {\n disableEnforceFocus: true,\n disableAutoFocus: true,\n disableRestoreFocus: true,\n },\n }}\n sx={{ pointerEvents: \"none\" }}\n open={isPopoverOpen}\n anchorEl={anchorElement}\n anchorOrigin={{\n vertical: \"bottom\",\n horizontal: \"left\",\n }}\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"left\",\n }}\n onClose={handleClose}\n disableRestoreFocus\n >\n {children}\n </Popover>\n </Box>\n );\n}\n\nexport default IconWithPopover;\n","import type { ListItemButtonProps } from \"@mui/material/ListItemButton\";\nimport type { ReactNode } from \"react\";\n\nimport ListItemButton from \"@mui/material/ListItemButton\";\n\nimport InternalLink from \"src/deprecated/InternalLink\";\n\nexport interface ListItemInternalLinkProps extends Omit<ListItemButtonProps, \"href\"> {\n children: ReactNode;\n to: string;\n}\n\n/** @deprecated Probably not that worth centralising here - can be easily recreated per use case. */\nfunction ListItemInternalLink({ children, ...listItemButtonProps }: ListItemInternalLinkProps) {\n return (\n <ListItemButton component={InternalLink} {...listItemButtonProps}>\n {children}\n </ListItemButton>\n );\n}\n\nexport default ListItemInternalLink;\n","import type { QueryBoundaryWrapperProps } from \"src/components/QueryBoundaryWrapper\";\n\nimport { QueryBoundaryWrapper } from \"src/components\";\n/** @deprecated This type has been renamed to QueryBoundaryProps. */\nexport type LoaderProps<DataType> = QueryBoundaryWrapperProps<DataType>;\n/** @deprecated This component has been renamed to QueryBoundary */\nconst Loader = QueryBoundaryWrapper;\n\nexport default Loader;\n","/* \neslint-disable react/prop-types -- ESLint gives false positives because it thinks the props are not typed.\nHowever, they are - this compound component are all typed and the prop types are recognised by TypeScript.\n*/\nimport type { JSX, ReactNode } from \"react\";\n\nimport QueryBoundaryData from \"src/groups/QueryBoundary/QueryBoundaryData\";\nimport QueryBoundaryDataMap from \"src/groups/QueryBoundary/QueryBoundaryDataMap\";\nimport QueryBoundaryError from \"src/groups/QueryBoundary/QueryBoundaryError\";\nimport QueryBoundaryFallback from \"src/groups/QueryBoundary/QueryBoundaryFallback\";\nimport QueryBoundaryNullable from \"src/groups/QueryBoundary/QueryBoundaryNullable\";\nimport QueryBoundaryProvider from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nexport interface QueryBase {\n /** The current loading status (true if loading, false if not) */\n isLoading?: boolean;\n /** The error given if the response gave an error. */\n error?: unknown;\n}\n\nexport interface QuerySingle<DataType> extends QueryBase {\n /** The data being loaded. */\n data: DataType | null | undefined;\n dataCollection?: never;\n}\n\nexport interface QueryMultiple<ItemType> extends QueryBase {\n /** An array of data items being loaded. */\n dataCollection: Array<ItemType> | null | undefined;\n data?: never;\n}\n\nexport type Query<DataType> = QuerySingle<DataType> | QueryMultiple<DataType>;\n\nexport interface CreateQueryBoundaryParameters<DataType> {\n query: Query<DataType>;\n}\n\nexport interface DefaultQueryBoundaryComponents<DataType> {\n Context: (props: { children: ReactNode }) => JSX.Element;\n Error: typeof QueryBoundaryError;\n Data: typeof QueryBoundaryData<DataType>;\n DataMap: typeof QueryBoundaryDataMap<DataType>;\n Fallback: typeof QueryBoundaryFallback;\n Nullable: typeof QueryBoundaryNullable;\n}\n\n/**\n * A creator function to create a system of QueryBoundary components with the data fully typed throughout.\n *\n * @deprecated Please use either `createBaseQueryBoundary`, `createItemQueryBoundary`, or `createListQueryBoundary` from `@alextheman/components/v7` instead.\n */\nfunction createQueryBoundary<DataType>({\n query,\n}: CreateQueryBoundaryParameters<DataType>): DefaultQueryBoundaryComponents<DataType> {\n return {\n Context: ({ children }) => {\n return (\n <QueryBoundaryProvider\n isLoading={query.isLoading}\n error={query.error}\n data={\"data\" in query ? query.data : query.dataCollection}\n >\n {children}\n </QueryBoundaryProvider>\n );\n },\n Error: QueryBoundaryError,\n Data: QueryBoundaryData<DataType>,\n DataMap: QueryBoundaryDataMap<DataType>,\n Fallback: QueryBoundaryFallback,\n Nullable: QueryBoundaryNullable,\n };\n}\n\nexport default createQueryBoundary;\n","import type { QueryBoundaryDataProps } from \"src/groups\";\n\nimport { QueryBoundaryData } from \"src/groups\";\n\n/** @deprecated This type has been renamed to QueryBoundaryDataProps. */\nexport type LoaderDataProps<DataType> = QueryBoundaryDataProps<DataType>;\n\n/** @deprecated This component has been renamed to QueryBoundaryData. */\nconst LoaderData = QueryBoundaryData;\n\nexport default LoaderData;\n","import type {\n QueryBoundaryErrorProps,\n QueryBoundaryFallbackProps,\n QueryBoundaryNullablePropsWithNullable,\n QueryBoundaryNullablePropsWithUndefinedOrNull,\n} from \"src/groups\";\n\nimport { QueryBoundaryFallback } from \"src/groups\";\n\n/** @deprecated This type has been renamed to QueryBoundaryErrorProps. */\nexport type LoaderErrorBaseProps = QueryBoundaryErrorProps;\n\n/** @deprecated This type has been renamed to QueryBoundaryNullablePropsWithUndefinedOrNull. */\nexport type LoaderErrorPropsWithUndefinedOrNull = LoaderErrorBaseProps &\n QueryBoundaryNullablePropsWithUndefinedOrNull;\n\n/** @deprecated This type has been renamed to QueryBoundaryNullablePropsWithNullable. */\nexport type LoaderErrorPropsWithNullable = LoaderErrorBaseProps &\n QueryBoundaryNullablePropsWithNullable;\n\n/** @deprecated This type has been renamed to QueryBoundaryFallbackProps. */\nexport type LoaderErrorProps = QueryBoundaryFallbackProps;\n\n/** @deprecated This component has been renamed to LoaderError. */\nconst LoaderError = QueryBoundaryFallback;\n\nexport default LoaderError;\n","import type {\n QueryBoundaryContextValue,\n QueryBoundaryProviderBaseProps,\n QueryBoundaryProviderProps,\n QueryBoundaryProviderPropsWithError,\n QueryBoundaryProviderPropsWithNoError,\n} from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\nimport QueryBoundaryProvider, {\n useQueryBoundary,\n} from \"src/groups/QueryBoundary/QueryBoundaryProvider\";\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderBaseProps. */\nexport type LoaderProviderBaseProps<DataType> = QueryBoundaryProviderBaseProps<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderPropsWithNoError. */\nexport type LoaderProviderPropsWithNoError<DataType> =\n QueryBoundaryProviderPropsWithNoError<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryProviderPropsWithError. */\nexport type LoaderProviderPropsWithError<DataType> = QueryBoundaryProviderPropsWithError<DataType>;\n\n/** @deprecated This type has been renamed to QueryBoundaryContextValue. */\nexport type LoaderContextValue<DataType> = QueryBoundaryContextValue<DataType>;\n/** @deprecated This type has been renamed to QueryBoundaryProviderProps. */\nexport type LoaderProviderProps<DataType> = QueryBoundaryProviderProps<DataType>;\n\n/** @deprecated This hook has been renamed to useQueryBoundary */\nexport const useLoader = useQueryBoundary;\n\n/** @deprecated This component has been renamed to QueryBoundaryProvider */\nconst LoaderProvider = QueryBoundaryProvider;\n\nexport default LoaderProvider;\n","import type { JSX, ReactNode } from \"react\";\n\nimport BottomNavigation from \"@mui/material/BottomNavigation\";\nimport BottomNavigationAction from \"@mui/material/BottomNavigationAction\";\nimport Box from \"@mui/material/Box\";\nimport Paper from \"@mui/material/Paper\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\n\nexport interface NavItemBottom {\n /** The value associated with the nav item. */\n value: string;\n /** The label to display on the nav item. */\n label: string;\n /** An icon to display alongside the nav item. */\n icon?: JSX.Element;\n /** Where in your app the nav item should navigate to. */\n to: string;\n}\n\nexport interface NavigationBottomProps {\n /** Children to display above the nav bar. */\n children: ReactNode;\n /** An array of nav items to show. */\n navItems: Array<NavItemBottom>;\n}\n\n/**\n * Renders a navigation bar at the bottom of the screen. Especially helpful for common navigation options in a mobile app.\n *\n * @deprecated Please use `NavigationBottom` from the `@alextheman/components/v7` entrypoint instead.\n */\nfunction NavigationBottom({ children, navItems }: NavigationBottomProps) {\n const [value, setValue] = useState<string>(\"\");\n return (\n <>\n <Box sx={{ paddingBottom: 7 }}>{children}</Box>\n <Paper sx={{ position: \"fixed\", bottom: 0, left: 0, right: 0 }}>\n <BottomNavigation\n showLabels\n value={value}\n onChange={(_, value) => {\n setValue(value);\n }}\n >\n {navItems.map((item) => {\n return <BottomNavigationAction key={item.value} {...item} component={Link} />;\n })}\n </BottomNavigation>\n </Paper>\n </>\n );\n}\n\nexport default NavigationBottom;\n","import type { AppBarProps as MuiAppBarProps } from \"@mui/material/AppBar\";\nimport type { CSSObject, Theme } from \"@mui/material/styles\";\nimport type { ReactNode } from \"react\";\n\nimport { truncate } from \"@alextheman/utility\";\nimport MuiAppBar from \"@mui/material/AppBar\";\nimport Box from \"@mui/material/Box\";\nimport CssBaseline from \"@mui/material/CssBaseline\";\nimport Divider from \"@mui/material/Divider\";\nimport MuiDrawer from \"@mui/material/Drawer\";\nimport IconButton from \"@mui/material/IconButton\";\nimport List from \"@mui/material/List\";\nimport ListItem from \"@mui/material/ListItem\";\nimport ListItemButton from \"@mui/material/ListItemButton\";\nimport ListItemIcon from \"@mui/material/ListItemIcon\";\nimport ListItemText from \"@mui/material/ListItemText\";\nimport { styled, useTheme } from \"@mui/material/styles\";\nimport Toolbar from \"@mui/material/Toolbar\";\nimport Typography from \"@mui/material/Typography\";\nimport { Fragment, useState } from \"react\";\nimport { MdChevronLeft, MdChevronRight, MdMenu } from \"react-icons/md\";\nimport { Link, useLocation } from \"react-router-dom\";\n\nconst drawerWidth = 240;\n\nfunction openedMixin(theme: Theme): CSSObject {\n return {\n width: drawerWidth,\n transition: theme.transitions.create(\"width\", {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.enteringScreen,\n }),\n overflowX: \"hidden\",\n };\n}\n\nfunction closedMixin(theme: Theme): CSSObject {\n return {\n transition: theme.transitions.create(\"width\", {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n overflowX: \"hidden\",\n width: `calc(${theme.spacing(7)} + 1px)`,\n [theme.breakpoints.up(\"sm\")]: {\n width: `calc(${theme.spacing(8)} + 1px)`,\n },\n };\n}\n\nconst DrawerHeader = styled(\"div\")(({ theme }) => {\n return {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n padding: theme.spacing(0, 1),\n // necessary for content to be below app bar\n ...theme.mixins.toolbar,\n };\n});\n\ninterface AppBarProps extends MuiAppBarProps {\n open?: boolean;\n}\n\nconst AppBar = styled(MuiAppBar, {\n shouldForwardProp: (prop) => {\n return prop !== \"open\";\n },\n})<AppBarProps>(({ theme }) => {\n return {\n zIndex: theme.zIndex.drawer + 1,\n transition: theme.transitions.create([\"width\", \"margin\"], {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n variants: [\n {\n props: ({ open }) => {\n return open;\n },\n style: {\n marginLeft: drawerWidth,\n width: `calc(100% - ${drawerWidth}px)`,\n transition: theme.transitions.create([\"width\", \"margin\"], {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.enteringScreen,\n }),\n },\n },\n ],\n };\n});\n\nconst Drawer = styled(MuiDrawer, {\n shouldForwardProp: (prop) => {\n return prop !== \"open\";\n },\n})(({ theme }) => {\n return {\n width: drawerWidth,\n flexShrink: 0,\n whiteSpace: \"nowrap\",\n boxSizing: \"border-box\",\n variants: [\n {\n props: ({ open }) => {\n return open;\n },\n style: {\n ...openedMixin(theme),\n \"& .MuiDrawer-paper\": openedMixin(theme),\n },\n },\n {\n props: ({ open }) => {\n return !open;\n },\n style: {\n ...closedMixin(theme),\n \"& .MuiDrawer-paper\": closedMixin(theme),\n },\n },\n ],\n };\n});\n\nexport interface NavMenuItemOptions {\n /** The label to display on the nav item option. */\n label: string;\n /** Where in your app the nav item option should navigate to. */\n to: string;\n /** An icon to display alongside the nav item option. */\n icon?: ReactNode;\n}\n\nexport interface NavMenuItem {\n /** The category to display all the nav item options under. */\n category: string;\n /** An array of nav options to display under the chosen category. */\n options: Array<NavMenuItemOptions>;\n}\n\nexport interface NavigationDrawerProps {\n /** The title to display at the top of the wrapper. */\n title: string;\n /** An array of nav items to show. */\n navItems: Array<NavMenuItem>;\n /** Any extra elements to add to the header. */\n headerElements?: ReactNode;\n /** Children to display within the wrapper. */\n children: ReactNode;\n}\n\n/**\n * Renders a collapsable drawer to help with navigation. Best used as the main means of navigation on desktop apps.\n *\n * @deprecated This component is not compatible with the rest of the Wouter setup for use in v7. Please use `NavigationDrawer` from `@alextheman/components/v7` instead. This component will be replaced when v7 officially comes out.\n */\nfunction NavigationDrawer({ title, navItems, children, headerElements }: NavigationDrawerProps) {\n const theme = useTheme();\n const [open, setOpen] = useState(true);\n const location = useLocation();\n\n function handleDrawerOpen() {\n setOpen(true);\n }\n\n function handleDrawerClose() {\n setOpen(false);\n }\n\n return (\n <Box sx={{ display: \"flex\" }}>\n <CssBaseline />\n <AppBar position=\"fixed\" open={open}>\n <Toolbar>\n <IconButton\n color=\"inherit\"\n aria-label=\"open drawer\"\n onClick={handleDrawerOpen}\n edge=\"start\"\n sx={[\n {\n marginRight: 5,\n },\n open && { display: \"none\" },\n ]}\n >\n <MdMenu />\n </IconButton>\n <Typography variant=\"h6\" noWrap component=\"div\">\n {title}\n </Typography>\n {headerElements}\n </Toolbar>\n </AppBar>\n <Drawer variant=\"permanent\" open={open}>\n <DrawerHeader>\n <IconButton onClick={handleDrawerClose}>\n {theme.direction === \"rtl\" ? <MdChevronRight /> : <MdChevronLeft />}\n </IconButton>\n </DrawerHeader>\n <Divider />\n {navItems.map((item) => {\n return (\n <Fragment key={item.category}>\n <List>\n <Typography variant={open ? \"h5\" : \"h6\"} sx={{ paddingLeft: open ? 2 : 1 }}>\n {open ? item.category : truncate(item.category, 4)}\n </Typography>\n {item.options.map((option) => {\n return (\n <ListItem key={option.to} disablePadding sx={{ display: \"block\" }}>\n <ListItemButton\n sx={[\n {\n minHeight: 48,\n px: 2.5,\n },\n open\n ? {\n justifyContent: \"initial\",\n }\n : {\n justifyContent: \"center\",\n },\n ]}\n component={Link}\n to={option.to}\n selected={location.pathname === option.to}\n >\n <ListItemIcon\n sx={[\n {\n minWidth: 0,\n justifyContent: \"center\",\n },\n open\n ? {\n mr: 3,\n }\n : {\n mr: \"auto\",\n },\n ]}\n >\n {option.icon ? (\n option.icon\n ) : !open ? (\n <Typography>{truncate(option.label, 4)}</Typography>\n ) : null}\n </ListItemIcon>\n <ListItemText\n primary={option.label}\n sx={[\n open\n ? {\n opacity: 1,\n }\n : {\n opacity: 0,\n },\n ]}\n />\n </ListItemButton>\n </ListItem>\n );\n })}\n </List>\n <Divider />\n </Fragment>\n );\n })}\n </Drawer>\n <Box component=\"main\" sx={{ flexGrow: 1, p: 3 }}>\n <DrawerHeader />\n {children}\n </Box>\n </Box>\n );\n}\n\nexport default NavigationDrawer;\n","import type { TypographyProps } from \"@mui/material/Typography\";\n\nimport Typography from \"@mui/material/Typography\";\n\nexport interface PopoverTextProps extends TypographyProps {\n text: string;\n}\n\n/**\n * @deprecated This component has been deprecated alongside `IconWithPopover`.\n */\nfunction PopoverText({ text, sx, ...typographyProps }: PopoverTextProps) {\n return (\n <>\n {text.split(\"\\n\").map((line, index) => {\n return (\n <Typography key={index} sx={{ margin: 1, ...sx }} {...typographyProps}>\n {line}\n </Typography>\n );\n })}\n </>\n );\n}\n\nexport default PopoverText;\n","import type { QueryBoundaryWrapperProps } from \"src/components/QueryBoundaryWrapper\";\n\nimport QueryBoundaryWrapper from \"src/components/QueryBoundaryWrapper\";\n\n/** @deprecated This type has been renamed to `QueryBoundaryWrapperProps`. */\nexport type QueryBoundaryProps<DataType> = QueryBoundaryWrapperProps<DataType>;\n\n/** @deprecated This component has been renamed to `QueryBoundaryWrapper` */\nconst QueryBoundary = QueryBoundaryWrapper;\n\nexport default QueryBoundary;\n","import type { ButtonProps } from \"@mui/material/Button\";\n\nimport Button from \"@mui/material/Button\";\nimport { useFormContext } from \"react-hook-form\";\n\nexport interface SubmitButtonProps extends Omit<ButtonProps, \"type\"> {\n /** An option to disable the button on submit if the form is not dirty. */\n disableClean?: boolean;\n /** The label for the button. */\n label: string;\n}\n\n/**\n * A Submit Button for use with `react-hook-form`.\n *\n * @deprecated This component is not compatible with `@tanstack/react-form`. Please use `SubmitButton` from the `@alextheman/components/v7` entrypoint instead. This component will be replaced when v7 officially comes out.\n */\nfunction SubmitButton({ disableClean, label, ...buttonProps }: SubmitButtonProps) {\n const {\n formState: { disabled: formDisabled, isDirty, isSubmitting },\n } = useFormContext();\n\n return (\n <Button\n color=\"primary\"\n disabled={buttonProps.disabled || (disableClean && !isDirty) || formDisabled}\n loading={isSubmitting}\n type=\"submit\"\n variant=\"contained\"\n {...buttonProps}\n >\n {label}\n </Button>\n );\n}\n\nexport default SubmitButton;\n","import { useEffect, useState } from \"react\";\n\n/**\n * Assign a variable a given value after a given amount of milliseconds.\n *\n * @template ValueType The type of the value to set.\n *\n * @param value - The value to assign.\n * @param delay - The amount of milliseconds to wait before assigning the value.\n *\n * @returns The input value after a given number of seconds.\n */\nfunction useDebounce<ValueType>(value: ValueType, delay: number = 500): ValueType {\n const [debouncedValue, setDebouncedValue] = useState<ValueType>(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n\nexport default useDebounce;\n","import type { Dispatch, SetStateAction } from \"react\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Stores changes to the window hash as React state.\n *\n * @template StateType - The type of the hash state.\n *\n * @param initialHash - The initial value of the hash.\n *\n * @returns A tuple containing the hash state, and a updater function to set the hash state.\n */\nfunction useHash<StateType extends string>(\n initialHash: StateType | undefined,\n): [StateType, Dispatch<SetStateAction<StateType>>] {\n const [hash, setHash] = useState<StateType>(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n return !initialHash ? hash : hash === \"\" ? initialHash : hash;\n });\n const hashChangeHandler = useCallback(() => {\n const hash: StateType = window.location.hash.replace(\"#\", \"\") as StateType;\n setHash(!initialHash ? hash : hash === \"\" ? initialHash : hash);\n }, [setHash, initialHash]);\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", hashChangeHandler);\n return () => {\n window.removeEventListener(\"hashchange\", hashChangeHandler);\n };\n }, [hashChangeHandler]);\n\n const updateHash = useCallback(\n (newHash: StateType | ((previousState: StateType) => StateType)) => {\n const resolvedHash = typeof newHash === \"function\" ? newHash(hash) : newHash;\n if (resolvedHash !== hash) {\n window.location.hash = resolvedHash;\n }\n },\n [hash],\n );\n\n return [hash, updateHash];\n}\n\nexport default useHash;\n"],"mappings":"mwEAcA,SAAS,EAAU,CAAE,iBAAgB,cAA8B,CACjE,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,IACR,gBAAiB,yBACjB,eAAgB,YAChB,OAAQ,mCACR,UAAW,8BACb,WAEA,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAY,QAAQ,KAAK,aAAA,GAAa,GAAI,CAAE,MAAO,SAAU,WAC1D,CACS,CAAA,EAEZ,EAAC,EAAD,CAAO,QAAS,WACb,EAAW,IAAK,GAEb,EAAC,EAAD,CAES,QACP,GAAI,CACF,gBAAiB,yBACjB,MAAO,yBACP,OAAQ,kCACV,CACD,EAPM,CAON,CAEJ,CACI,CAAA,CACI,CAAA,CAAA,CACT,CAAA,CAEV,CAEA,SAAS,IAAY,CACnB,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,EACR,aAAc,EACd,WAAY,oDACZ,UAAW,iCACb,CACD,CAAA,CAEL,CAGA,SAAS,IAAU,CACjB,OACE,EAAC,EAAD,CACE,GAAI,CACF,MAAO,IACP,OAAQ,IACR,QAAS,OACT,cAAe,SACf,eAAgB,gBAChB,EAAG,EACH,WACE,+KACF,MAAO,OACT,EACA,UAAW,WAZb,CAcE,EAAC,EAAD,CACE,MAAM,6BACN,GAAI,CACF,MAAO,UACP,UAAW,SACX,yBAA0B,CACxB,SAAU,GACV,WAAY,IACZ,cAAe,CACjB,CACF,CACD,CAAA,EAED,EAAC,EAAD,CAAS,GAAI,CAAE,YAAa,uBAAwB,CAAI,CAAA,EAExD,EAAC,EAAD,CAAa,GAAI,CAAE,KAAM,EAAG,QAAS,OAAQ,WAAY,QAAS,WAChE,EAAC,EAAD,CACE,UAAU,MACV,QAAS,EACT,GAAI,CAAE,MAAO,OAAQ,eAAgB,SAAU,WAAY,QAAS,WAHtE,CAKE,EAAC,EAAD,CACE,eAAe,MACf,WAAY,CAAC,QAAS,UAAW,QAAS,QAAS,QAAS,QAAS,SAAS,CAC/E,CAAA,EACD,EAAC,GAAD,CAAY,CAAA,EACZ,EAAC,EAAD,CACE,eAAe,IACf,WAAY,CAAC,SAAU,SAAU,WAAY,SAAU,UAAW,SAAU,UAAU,CACvF,CAAA,CACI,GACI,CAAA,CACT,GAEV,CCzEA,SAAS,GAAgB,CACvB,kBACA,SACA,UACA,WACA,eACA,iBACA,gBAAiB,EAAkB,EACnC,gBACA,WAAW,EAAC,GAAD,CAAgB,CAAA,EAC3B,aAAa,EAAC,EAAD,CAAkB,CAAA,EAC/B,oBAAoB,IAAoB,GACjB,CACvB,GAAM,CAAC,EAAY,GAAiB,EAAkB,CAAC,CAAC,CAAe,EAUvE,OARA,MAAgB,CACV,GAAc,EAChB,EAAO,EACE,CAAC,GAAc,GACxB,EAAQ,CAEZ,EAAG,CAAC,CAAU,CAAC,EAGb,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,YAAe,CACb,EAAe,GACN,CAAC,CACT,CACH,EACA,GACE,EACI,CACE,MAAO,OACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,SAAU,IACV,SAAU,EACV,UAAW,SACX,UACE,IAAoB,EAAa,CAAE,gBAAiB,cAAe,EAAI,KACzE,GAAG,CACL,EACA,EAEN,gBAAe,WAtBjB,CAwBG,EACA,EAAa,EAAW,CACV,IACjB,EAAC,EAAD,CAAU,GAAI,EAAY,GAAI,EAC3B,UACO,CAAA,CACP,CAAA,CAAA,CAET,CChFA,SAAS,GAAa,CAAE,OAAM,WAAU,MAAK,GAAG,GAAgC,CAC9E,OACE,EAAC,EAAD,CACE,UAAU,IACJ,OACD,MACL,OAAO,SACP,IAAI,sBACJ,GAAI,EAEH,UACM,CAAA,CAEb,CCzBA,MAAa,GAAW,CACtB,IAAK,kBACL,IAAK,YACL,KAAM,aACN,IAAK,YACL,KAAM,oEACN,KAAM,0EACN,IAAK,YACL,IAAK,YACL,IAAK,WACP,EAGM,GAAsB,EAAO,OAAO,EAAE,CAC1C,KAAM,gBACN,SAAU,aACV,OAAQ,EACR,SAAU,SACV,SAAU,WACV,OAAQ,EACR,KAAM,EACN,WAAY,SACZ,MAAO,CACT,CAAC,EAEK,GAAW,EAAO,KAAK,GAA2B,CAAE,QAAO,gBACxD,CACL,OAAQ,aACR,YAAa,EAAY,EAAM,QAAQ,QAAQ,KAAO,OACtD,gBAAiB,EAAY,EAAM,QAAQ,OAAO,MAAQ,cAC1D,aAAc,EACd,QAAS,SACT,UAAW,SACX,WAAY,oBACZ,OAAQ,SACV,EACD,EAgBD,SAAS,GAAU,CACjB,cACA,QAAQ,eACR,WACA,SACA,cACA,GAAG,GACc,CACjB,GAAM,CAAC,EAAY,GAAiB,EAAkB,EAAK,EACrD,EAAK,EAAM,EAEX,EACJ,EAAC,EAAD,CACE,QAAQ,YACR,UAAU,QACV,aAAW,oBACX,UAAY,GAAU,EAChB,EAAM,MAAQ,SAAW,EAAM,MAAQ,OACzC,EAAM,eAAe,EACrB,SAAS,eAAe,CAAE,GAAG,MAAM,EAEvC,EACA,GAAI,EACJ,UAAW,EAAY,WAAa,EAAC,GAAD,CAAgB,CAAA,WAXtD,CAaG,EACD,EAAC,GAAD,CACM,KACJ,KAAK,OACL,SAAW,GAAU,CACnB,IAAM,EAAQ,EAAM,OACpB,EAAY,MAAM,KAAK,EAAM,OAAS,CAAC,CAAC,CAAC,EACzC,EAAM,MAAQ,EAChB,EACU,WACV,OAAQ,GAAQ,KAAK,GAAG,EACxB,SAAU,EAAY,QACvB,CAAA,CACK,IAGV,OAAO,EACL,EAAC,GAAD,CACE,UAAW,EACX,WAAa,GAAU,CACrB,EAAM,eAAe,EACjB,GAAY,UAGhB,EAAc,EAAI,CACpB,EACA,YAAc,GAAU,CACtB,EAAM,eAAe,EACrB,EAAc,EAAK,CACrB,EACA,OAAS,GAAU,CACjB,EAAM,eAAe,EACrB,EAAc,EAAK,EACf,GAAY,UAIhB,EADmB,MAAM,KAAK,EAAM,aAAa,OAAS,CAAC,CACtC,CAAC,CACxB,WAEC,CACO,CAAA,EAEV,CAEJ,CC7GA,SAAS,GAAc,CACrB,QACA,WACA,WAAW,GACX,GAAG,GACkB,CACrB,SAAS,EAAY,EAAuB,CAC1C,EAAU,GACD,CAAC,GAAG,EAAU,GAAG,CAAQ,CACjC,CACH,CAEA,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,GAAD,CAAW,GAAI,EAA0B,WAAuB,aAAc,CAAA,EAC9E,EAAC,EAAD,CAAA,SACG,EAAM,IAAK,GAER,EAAC,GAAD,CAEE,gBACE,EAAC,EAAD,CACE,aAAW,SACX,KAAK,MACL,YAAe,CACb,EAAU,GACD,EAAS,OAAQ,GACf,IAAiB,CACzB,CACF,CACH,WAEA,EAAC,GAAD,CAAW,CAAA,CACD,CAAA,WAGd,EAAC,GAAD,CAAc,QAAS,EAAK,IAAO,CAAA,CAC3B,EAlBH,GAAG,EAAK,KAAK,GAAG,EAAK,cAkBlB,CAEb,CACG,CAAA,CACH,CAAA,CAAA,CAET,CC7CA,MAAM,GAAe,EAAO,EAAM,OACzB,CACL,QAAS,EACT,qBAAsB,CACpB,aAAc,GACd,sBAAuB,CACrB,QAAS,KACT,SAAU,WACV,IAAK,MACL,UAAW,mBACX,SAAU,GACV,MAAO,GACP,OAAQ,EACV,CACF,CACF,EACD,EAGD,SAAS,GAAgB,CACvB,YAAa,EACb,oBACA,cAAe,EACf,sBACA,GAAG,GACoB,CACvB,IAAM,EAAQ,CACZ,aAAc,MACd,YAAa,QACb,gBAAiB,QACjB,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,QAAS,GACX,EACM,EAAoB,CAAE,MAAO,QAAS,SAAU,KAAM,UAAW,IAAK,EAC5E,OACE,EAAC,GAAD,CACE,YACE,EAAC,EAAD,CAAK,GAAI,WACP,EAAC,EAAD,CAAa,MAAO,CAAE,GAAG,EAAmB,GAAG,CAAkB,CAAI,CAAA,CAClE,CAAA,EAEP,KACE,EAAC,EAAD,CAAK,GAAI,WACP,EAAC,EAAD,CAAe,MAAO,CAAE,GAAG,EAAmB,GAAG,CAAoB,CAAI,CAAA,CACtE,CAAA,EAEP,GAAI,CACL,CAAA,CAEL,CCtDA,MAAM,EAAc,EAAgC,CAClD,eAAkB,CAAC,EACnB,KAAM,MACR,CAAC,EAGD,SAAgB,EAAuC,CACrD,SAAS,IACqB,CAAC,EAAkD,CACjF,IAAM,EAAU,EAAW,CAAW,EACtC,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,0BACA,kFACF,EAEF,OAAO,CACT,CAUA,SAAS,GAAa,CAAE,WAAU,KAAM,EAAW,QAA6B,CAC9E,GAAM,CAAC,EAAM,GAAW,EAAsB,CAAQ,EAEhD,EAAQ,MACL,GAAY,CACjB,QAAS,CACP,MACF,EACA,WAAY,CACV,SAAU,CACR,eAAgB,CACd,MAAO,CAAE,YACA,CACL,OAAQ,EACR,YAAa,QACb,YAAa,EAAM,QAAQ,OAC7B,EAEJ,CACF,CACF,CACF,CAAC,EACA,CAAC,CAAI,CAAC,EAET,OACE,EAAC,EAAY,SAAb,CACE,MAAO,CACL,OACA,eAAkB,CAChB,EAAS,GACA,IAAS,QAAU,OAAS,OACpC,CACH,CACF,WAEA,EAAC,GAAD,CAAsB,iBAAtB,CACE,EAAC,EAAD,CAAc,CAAA,EACb,CACY,GACK,CAAA,CAE1B,CC3DA,MAAM,EAAoB,EAAsC,CAC9D,YAAa,EACb,aAAc,EACd,cAAe,EACjB,CAAC,EAGD,SAAgB,GAA6C,CAC3D,SAAS,IACqB,CAAC,EAAwD,CACvF,IAAM,EAAU,EAAW,CAAiB,EAC5C,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,iCACA,wFACF,EAEF,OAAO,CACT,CAGA,SAAS,GAAmB,CAC1B,WACA,mBAAmB,IACnB,oBAAoB,KACF,CAClB,GAAM,CAAC,EAAa,GAAkB,EAAiB,OAAO,UAAU,EAClE,CAAC,EAAc,GAAmB,EAAiB,OAAO,WAAW,EAE3E,MAAgB,CACd,SAAS,GAAgB,CACvB,EAAe,OAAO,UAAU,EAChC,EAAgB,OAAO,WAAW,CACpC,CAGA,OAFA,EAAc,EACd,OAAO,iBAAiB,SAAU,CAAa,MAClC,CACX,OAAO,oBAAoB,SAAU,CAAa,CACpD,CACF,EAAG,CAAC,CAAC,EAEL,IAAM,EAAgB,MACb,EAAc,GAAoB,EAAe,EACvD,CAAC,EAAa,EAAc,EAAkB,CAAiB,CAAC,EAEnE,OACE,EAAC,EAAkB,SAAnB,CACE,MAAO,CACL,gBACA,cACA,cACF,EAEC,UACyB,CAAA,CAEhC,CC3DA,MAAM,EAAkB,EAAgD,IAAA,EAAS,EAGjF,SAAgB,GAA2C,CACzD,SAAS,IACqB,CAAC,EAAsD,CACrF,IAAM,EAAU,EAAW,CAAe,EAC1C,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,8BACA,sFACF,EAEF,OAAO,CACT,CAGA,SAAS,GAAiB,CAAE,WAAU,mBAAmB,KAA+B,CACtF,GAAM,CAAC,EAAM,GAAW,EAAkB,EAAK,EACzC,CAAC,EAAuB,GAA4B,EAAiB,CAAgB,EACrF,CAAC,EAAS,GAAc,EAAiB,EAAE,EAC3C,CAAC,EAAU,GAAe,EAAqB,MAAM,EAE3D,SAAS,EAAY,EAAiB,EAAuB,EAAmB,CAC9E,EAAQ,EAAI,EACZ,EAAyB,GAAY,CAAgB,EACrD,EAAY,GAAY,MAAM,EAC9B,EAAW,CAAO,CACpB,CAEA,eAAe,GAAc,CAC3B,EAAQ,EAAK,EAGb,MAAM,GAAK,EAAG,EACd,EAAW,EAAE,CACf,CAEA,OACE,EAAC,EAAgB,SAAjB,CAA0B,MAAO,CAAE,aAAY,WAA/C,CACE,EAAC,GAAD,CAAgB,OAAM,iBAAkB,EAAuB,QAAS,WACtE,EAAC,EAAD,CAAO,QAAS,EAAuB,oBACpC,CACI,CAAA,CACC,CAAA,EACT,CACuB,GAE9B,CClEA,SAAS,GAAa,CACpB,GAAM,CAAE,OAAM,cAAe,EAAQ,EAC/B,EAAa,IAAS,OACtB,EAAW,UAAU,EAAa,QAAU,OAAO,OAEzD,OACE,EAAC,GAAD,CAAS,MAAO,WACd,EAAC,GAAD,CACE,cAAe,GACf,YAAa,GACb,QAAS,EACT,SAAU,EACV,aAAY,CACb,CAAA,CACM,CAAA,CAEb,CCCA,SAAS,GAAK,CAAE,QAAO,WAAU,SAAQ,WAAU,OAAM,kBAA6B,CACpF,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,MACE,EAAA,EAAA,CAAA,SAAA,CACG,OAAO,GAAU,SAAW,EAAC,EAAD,CAAY,QAAQ,cAAM,CAAkB,CAAA,EAAI,EAC5E,EACC,OAAO,GAAa,SAClB,EAAC,EAAD,CAAY,QAAQ,QAAQ,MAAM,0BAC/B,CACS,CAAA,EAEZ,EAEA,IACJ,CAAA,CAAA,EAEI,QACT,CAAA,EACA,EACD,EAAC,EAAD,CAAU,CAAA,EACT,EAAiB,EAAW,EAAC,EAAD,CAAc,UAAsB,CAAA,CAC7D,CAAA,CAAA,CAEV,CCHA,MAAM,EAAuB,EAC3B,IAAA,EACF,EAGA,SAAgB,EAA0D,CACxE,SAAS,IACqB,CAAC,EAG/B,CACA,IAAM,EAAU,EAAW,CAAoB,EAC/C,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,oCACA,2FACF,EAEF,OAAO,CACT,CAQA,SAAS,EAAgC,CACvC,WACA,mBAAmB,EAAC,EAAD,CAAmB,CAAA,EACtC,GAAG,GACoC,CACvC,OACE,EAAC,EAAqB,SAAtB,CAA+B,MAAO,CAAE,mBAAkB,GAAG,CAAa,EACvE,UAC4B,CAAA,CAEnC,CClBA,SAAS,EAA+B,CACtC,WACA,iBAAkB,EAClB,UACA,aACA,WAAY,EACZ,iBAAiB,EAAC,EAAD,CAAA,SAAY,iBAA2B,CAAA,EACxD,uBAAuB,IACe,CACtC,GAAM,CACJ,YACA,OACA,WAAY,EACZ,iBAAkB,EAClB,SACE,EAAkC,EAEhC,EAAa,GAAkB,EAC/B,EAAmB,GAAwB,EAEjD,GAAI,EACF,OAAO,EAAA,EAAA,CAAA,SAAG,CAAmB,CAAA,EAO/B,GAJI,GAIA,GAAS,KACX,OAAO,KAGT,GAAI,CAAC,MAAM,QAAQ,CAAI,EAAG,CACxB,GAAI,EACF,MAAM,IAAI,EACR,CAAE,OAAM,sBAAqB,EAC7B,eACA,2DACF,EAEF,OAAO,IACT,CAEA,GAAI,EAAK,SAAW,EAClB,OAAO,EAAA,EAAA,CAAA,SAAG,CAAiB,CAAA,EAG7B,IAAI,EAUJ,MARA,CAKE,EALE,EACM,EAAW,CAAI,EACd,EACD,EAAK,IAAI,CAAU,EAEnB,EAIR,EAAA,EAAA,CAAA,SACG,EAAM,KAAK,EAAM,IAEd,EAACA,EAAD,CAAA,SACG,OAAO,GAAa,WAAa,EAAS,CAAI,EAAI,CAC3C,EAFK,EAAU,EAAQ,EAAM,CAAK,EAAI,CAEtC,CAEb,CACD,CAAA,CAEN,CCrHA,SAAS,EAAmB,CAAE,WAAU,SAAU,GAA0C,CAC1F,GAAM,CACJ,OACA,QACA,eAAgB,EAChB,SAAU,GACR,EAAiB,EACf,EAAW,GAAiB,EAC5B,EAAa,GAAO,EAAK,EAEzB,EAAiB,GAAY,EA6BnC,OA3BI,GACE,GAAY,CAAC,EAAW,UACtB,GAAS,MACX,QAAQ,MACN,6FACA,CAAE,OAAM,OAAM,CAChB,EAEF,QAAQ,MAAM,CAAK,EACnB,EAAW,QAAU,IAEnB,OAAO,GAAmB,WACrB,EAAe,CAAK,EAEzB,EACK,EAAA,EAAA,CAAA,SAAG,CAAiB,CAAA,EAI3B,EAAC,EAAD,CAAO,SAAS,iBACb,OAAO,GAAU,UAAY,YAAa,GAAS,OAAO,EAAM,SAAY,SACzE,EAAM,QACN,uDACC,CAAA,GAIJ,IACT,CC/BA,SAAS,EAAsB,CAC7B,qBACA,gBACA,qBAC6B,CAC7B,GAAM,CAAE,YAAW,OAAM,SAAU,EAAiB,EA8BpD,OA5BI,GAIA,EACK,KAGL,GAAS,KACP,EACK,EAAA,EAAA,CAAA,SAAG,CAAoB,CAAA,EAG5B,IAAS,IAAA,IACP,EACK,EAAA,EAAA,CAAA,SAAG,CAAqB,CAAA,EAI/B,IAAS,MACP,EACK,EAAA,EAAA,CAAA,SAAG,CAAgB,CAAA,EAIvB,EAAC,EAAD,CAAO,SAAS,iBAAQ,8CAAmD,CAAA,EAG7E,IACT,CC9CA,SAAS,EAAsB,CAC7B,iBACA,WACA,GAAG,GAC0B,CAC7B,OACE,EAAA,EAAA,CAAA,SAAA,CACE,EAAC,EAAD,CAA8B,oBAAW,CAAmC,CAAA,EAC5E,EAAC,EAAD,CAAuB,GAAI,CAA6B,CAAA,CACxD,CAAA,CAAA,CAEN,CCKA,SAAS,GAAkC,CACzC,SACkF,CAClF,MAAO,CACL,SAAU,CAAE,cAER,EAAC,EAAD,CAAuB,UAAW,EAAM,UAAW,MAAO,EAAM,MAAO,KAAM,EAAM,KAChF,UACoB,CAAA,EAG3B,MAAO,EACP,SAAU,EACV,SAAU,CACZ,CACF,CCvBA,SAAS,GAAkC,CACzC,SAC4F,CAG5F,MAAO,CACL,GAHqB,GAAwB,CAAE,OAAM,CAGrC,EAChB,QAAS,CACX,CACF,CCZA,SAAS,GAA2B,CAClC,mBACA,qBACA,gBACA,oBACA,WACA,iBACA,WACA,YACA,QACA,OACA,aACA,aACA,WACkC,CAClC,IAAM,EAAgB,GAAwB,CAAE,MAAO,CAAE,YAAW,QAAO,MAAK,CAAE,CAAC,EAE/E,EACF,EAAC,EAAc,SAAf,CAAkC,WAA0B,gBAAiB,CAAA,EAG3E,EACF,EACE,EAAC,EAAc,SAAf,CACqB,oBACT,WACM,gBACjB,CAAA,GAEM,GAAsB,KAC/B,EACE,EAAC,EAAc,SAAf,CACsB,qBACL,gBACL,WACM,gBACjB,CAAA,GAIL,IAAI,EACF,EAAC,EAAc,QAAf,CAAyC,mBAA2B,UACjE,UACoB,CAAA,EAyBzB,OAtBI,EACF,EACE,EAAC,EAAc,QAAf,CACoB,mBACT,UACG,aAEX,UACoB,CAAA,EAEhB,IACT,EACE,EAAC,EAAc,QAAf,CACoB,mBACT,UACG,aAEX,UACoB,CAAA,GAKzB,EAAC,EAAc,QAAf,CAAA,SAAA,CACG,EACA,CACoB,CAAA,CAAA,CAE3B,CC1EA,SAAS,EAA4B,CACnC,WACA,WAAY,EACZ,oBACmC,CACnC,GAAM,CACJ,YACA,OACA,WAAY,EACZ,iBAAkB,EAClB,SACE,EAA2B,EACzB,EAAa,GAAkB,EAcrC,OAZI,EACK,KAGL,EACK,EAAA,EAAA,CAAA,SAAG,GAAoB,CAA0B,CAAA,EAGtD,GAAS,KACJ,KAIP,EAAA,EAAA,CAAA,SACG,OAAO,GAAa,WAAa,EAAS,EAAa,EAAW,CAAI,EAAI,CAAI,EAAI,CACnF,CAAA,CAEN,CC5BA,SAAS,GAAkC,CACzC,SAC4F,CAG5F,MAAO,CACL,GAHqB,GAAwB,CAAE,OAAM,CAGrC,EAChB,KAAM,CACR,CACF,CCXA,SAAS,EAA+B,CACtC,WACA,iBACA,qBACA,gBACA,oBACA,WACA,mBAAmB,EAAC,EAAD,CAAmB,CAAA,EACtC,YACA,QACA,OACA,cACsC,CACtC,IAAM,EAAgB,GAAwB,CAAE,MAAO,CAAE,YAAW,QAAO,MAAK,CAAE,CAAC,EAE/E,EACF,EAAC,EAAc,SAAf,CAAkC,WAA0B,gBAAiB,CAAA,EAsB/E,OAnBI,EACF,EACE,EAAC,EAAc,SAAf,CACqB,oBACT,WACM,gBACjB,CAAA,GAEM,GAAsB,KAC/B,EACE,EAAC,EAAc,SAAf,CACsB,qBACL,gBACL,WACM,gBACjB,CAAA,GAKH,EAAC,EAAc,QAAf,CAAA,SAAA,CACG,EACD,EAAC,EAAc,KAAf,CAAsC,mBAA8B,aACjE,UACiB,CAAA,CACC,CAAA,CAAA,CAE3B,CCpDA,SAAS,GAAgB,CAAE,OAAM,gBAAe,GAAG,GAA2C,CAC5F,GAAM,CAAE,QAAS,EAAQ,EACnB,EAAuC,CAC3C,gBAAiB,IAAS,OAAS,QAAU,QAC7C,OAAQ,GACR,aAAc,EACd,QAAS,EACT,YAAa,UACf,EACM,EAAmB,EACrB,CAAE,GAAG,EAAsB,GAAG,CAAc,EAC5C,CAAE,GAAG,CAAqB,EAC9B,OACE,EAAC,EAAD,CAAK,GAAI,CAAE,aAAc,EAAG,OAAQ,GAAK,QAAS,CAAE,WAClD,EAAC,GAAD,CAAc,GAAI,EAAmB,KAAM,GAAY,GAAQ,EAAE,WAAjE,CACE,EAAC,EAAD,CAAY,QAAQ,cAAK,MAAgB,CAAA,EACzC,EAAC,EAAD,CACE,GAAI,CACF,OAAQ,GACR,aAAc,GACd,YAAa,UACf,WAEA,EAAC,GAAD,CAAa,CAAA,CACV,CAAA,EACL,EAAC,KAAD,CAAK,CAAA,EACL,EAAC,EAAD,CAAY,QAAQ,cAAK,QAAkB,CAAA,EAC3C,EAAC,EAAD,CAAK,GAAI,WAAT,CACE,EAAC,GAAD,CAAc,CAAA,EACd,EAAC,GAAD,CAAY,CAAA,CACT,GACO,GACX,CAAA,CAET,CCvCA,SAAS,GAAY,CAAE,WAA6B,CAClD,OACE,EAAC,GAAD,CAAA,SACG,GAAW,GAER,EAAC,GAAD,CAAA,SACE,EAAC,GAAD,CAAW,CAAA,CACF,EAFK,CAEL,EAEZ,CAAO,CACF,CAAA,CAEd,CCpBA,MAAM,GAAiB,ECsBvB,SAAS,GAAa,CACpB,WACA,OAAQC,EAASC,EACjB,iBAAiB,OACjB,YAAa,EACb,aAAa,EAAC,GAAD,CAAgB,CAAA,EAC7B,eAAe,EAAC,EAAD,CAAkB,CAAA,EACjC,SACA,WACoB,CACpB,GAAM,CAAC,EAAe,GAAoB,EAA6B,IAAI,EACrE,EAAiB,MACd,CAAC,CAAC,EACR,CAAC,CAAa,CAAC,EAEZ,EAAuC,CAC3C,GAAG,EACH,QAAU,GAAwC,CAChD,EAAiB,EAAM,aAAa,CACtC,EACA,gBAAiB,EAAiB,gBAAkB,IAAA,GACpD,gBAAiB,OACjB,gBAAiB,CACnB,EAcA,OAZID,IAAWC,IACb,EAAY,QAAU,EAAiB,EAAa,GAGtD,MAAgB,CACV,GAAkB,EACpB,EAAO,EACE,CAAC,GAAkB,GAC5B,EAAQ,CAEZ,EAAG,CAAC,EAAgB,EAAQ,CAAO,CAAC,EAGlC,EAAC,EAAD,CAAA,SAAA,CACE,EAACD,EAAD,CAAQ,GAAI,WAAc,CAAuB,CAAA,EACjD,EAAC,EAAD,CACE,GAAG,gBACH,SAAU,EACV,KAAM,EACN,YAAe,CACb,EAAiB,IAAI,CACvB,WAEC,OAAO,GAAa,WACnB,EAAC,EAAD,CAAA,SACG,MAAe,CACd,EAAiB,IAAI,CACvB,CAAC,CACE,CAAA,EAEL,CAEE,CAAA,CACH,CAAA,CAAA,CAET,CClEA,MAAM,GAAsB,EAA4D,IAAA,EAAS,EAKjG,SAAgBE,EAA+C,CAC7D,SAAS,IACqB,CAAC,EAA0D,CACzF,IAAM,EAAU,EAAW,EAAmB,EAC9C,GAAI,GAAU,CAAC,EACb,MAAM,IAAI,EACR,CAAE,SAAQ,SAAQ,EAClB,0BACA,kFACF,EAEF,OAAO,CACT,CAGA,SAAgB,GAAuD,CACrE,SAAS,IACqB,CAAC,EAAkE,CACjG,OAAOA,EAAgB,CAAE,QAAO,CAAC,CAInC,CC7BA,SAASC,GAAa,CAAE,WAAU,UAAS,GAAG,GAAgC,CAC5E,GAAM,CAAE,gBAAe,iBAAgB,aAAc,GAAwB,EAE7E,OACE,EAAC,EAAD,CACE,SAAU,EACV,KAAM,EACN,SAAU,EAAmB,IAAW,CACjC,EAAM,kBACT,EAAU,EAER,GACF,EAAQ,EAAO,CAAM,CAEzB,EACA,GAAI,EAEH,UACG,CAAA,CAEV,CCHA,SAASC,GAAoE,CAC3E,YACA,WACA,MACA,UACA,GAAG,GACoC,CACvC,GAAM,CAAE,aAAcC,EAAgB,EAEtC,OACE,EAAC,EAAD,CACa,YACN,MACL,GAAI,EACJ,QAAU,GAAU,CACd,GACF,EAAQ,CAAK,EAEX,GAAM,kBAGV,EAAU,CACZ,EAEC,UACO,CAAA,CAEd,CCpDA,MAAa,EAAkBC,EAczB,GAAgBC,GCdhB,GAAmBC,GCDzB,IAAA,GAAe,GCQf,SAAS,GAAyB,CAChC,MACA,OACA,WACA,UACA,GAAG,GAC6B,CAChC,GAAM,CAAE,aAAc,EAAgB,EAEtC,OACE,EAAC,EAAD,CACE,UAAW,GACL,OACD,MACL,GAAI,EACJ,QAAU,GAAU,CACb,EAAM,kBACT,EAAU,EAER,GACF,EAAQ,CAAK,CAEjB,EAEC,UACO,CAAA,CAEd,CCTA,SAAS,EAAa,CACpB,KACA,YAAYC,EACZ,WACA,MACA,GAAG,GACiB,CACpB,OACE,EAAC,EAAD,CAAoB,YAAe,KAAS,MAAK,GAAI,EAClD,UACM,CAAA,CAEb,CC9BA,SAAS,GAAyB,CAChC,KACA,MACA,WACA,UACA,GAAG,GAC6B,CAChC,GAAM,CAAE,aAAc,EAAgB,EAEtC,OACE,EAAC,EAAD,CACE,UAAW,EACP,KACC,MACL,GAAI,EACJ,QAAU,GAAU,CACb,EAAM,kBACT,EAAU,EAER,GACF,EAAQ,CAAK,CAEjB,EAEC,UACO,CAAA,CAEd,CCZA,SAAS,GAAgB,CACvB,KAAM,EAAO,GACb,SACA,UACA,YACA,YACuB,CACvB,GAAM,CAAC,EAAe,GAAoB,EAAyB,IAAI,EACjE,EAAgB,CAAC,CAAC,EAClB,EAAY,EAAM,EAExB,SAAS,EAAW,EAAmD,CACrE,EAAiB,EAAM,aAAa,EAChC,GACF,EAAO,CAEX,CAEA,SAAS,GAAc,CACrB,EAAiB,IAAI,EACjB,GACF,EAAQ,CAEZ,CAEA,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,YAAW,EAAgB,EAAY,IAAA,GACvC,gBAAc,OACd,aAAc,EACd,aAAc,EACd,GAAI,CACL,CAAA,EACD,EAAC,GAAD,CACE,GAAI,EACJ,cAAA,GACA,kBAAA,GACA,UAAW,CACT,KAAM,CACJ,oBAAqB,GACrB,iBAAkB,GAClB,oBAAqB,EACvB,CACF,EACA,GAAI,CAAE,cAAe,MAAO,EAC5B,KAAM,EACN,SAAU,EACV,aAAc,CACZ,SAAU,SACV,WAAY,MACd,EACA,gBAAiB,CACf,SAAU,MACV,WAAY,MACd,EACA,QAAS,EACT,oBAAA,GAEC,UACM,CAAA,CACN,CAAA,CAAA,CAET,CCjFA,SAAS,GAAqB,CAAE,WAAU,GAAG,GAAkD,CAC7F,OACE,EAAC,EAAD,CAAgB,UAAW,EAAc,GAAI,EAC1C,UACa,CAAA,CAEpB,CCbA,MAAM,GAAS,EC8Cf,SAAS,GAA8B,CACrC,SACoF,CACpF,MAAO,CACL,SAAU,CAAE,cAER,EAAC,EAAD,CACE,UAAW,EAAM,UACjB,MAAO,EAAM,MACb,KAAM,SAAU,EAAQ,EAAM,KAAO,EAAM,eAE1C,UACoB,CAAA,EAG3B,MAAO,EACP,KAAM,EACN,QAAS,EACT,SAAU,EACV,SAAU,CACZ,CACF,CCjEA,MAAM,GAAa,ECgBb,GAAc,ECOd,GAAiB,ECCvB,SAAS,GAAiB,CAAE,WAAU,YAAmC,CACvE,GAAM,CAAC,EAAO,GAAY,EAAiB,EAAE,EAC7C,OACE,EAAA,EAAA,CAAA,SAAA,CACE,EAAC,EAAD,CAAK,GAAI,CAAE,cAAe,CAAE,EAAI,UAAc,CAAA,EAC9C,EAAC,GAAD,CAAO,GAAI,CAAE,SAAU,QAAS,OAAQ,EAAG,KAAM,EAAG,MAAO,CAAE,WAC3D,EAAC,GAAD,CACE,WAAA,GACO,QACP,UAAW,EAAG,IAAU,CACtB,EAAS,CAAK,CAChB,WAEC,EAAS,IAAK,GACN,EAAC,GAAD,CAAyC,GAAI,EAAM,UAAW,CAAO,EAAxC,EAAK,KAAmC,CAC7E,CACe,CAAA,CACb,CAAA,CACP,CAAA,CAAA,CAEN,CC3BA,SAAS,GAAY,EAAyB,CAC5C,MAAO,CACL,MAAO,IACP,WAAY,EAAM,YAAY,OAAO,QAAS,CAC5C,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,cACvC,CAAC,EACD,UAAW,QACb,CACF,CAEA,SAAS,GAAY,EAAyB,CAC5C,MAAO,CACL,WAAY,EAAM,YAAY,OAAO,QAAS,CAC5C,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,aACvC,CAAC,EACD,UAAW,SACX,MAAO,QAAQ,EAAM,QAAQ,CAAC,EAAE,UAC/B,EAAM,YAAY,GAAG,IAAI,GAAI,CAC5B,MAAO,QAAQ,EAAM,QAAQ,CAAC,EAAE,QAClC,CACF,CACF,CAEA,MAAM,GAAe,EAAO,KAAK,GAAG,CAAE,YAC7B,CACL,QAAS,OACT,WAAY,SACZ,eAAgB,WAChB,QAAS,EAAM,QAAQ,EAAG,CAAC,EAE3B,GAAG,EAAM,OAAO,OAClB,EACD,EAMK,GAAS,EAAO,GAAW,CAC/B,kBAAoB,GACX,IAAS,MAEpB,CAAC,GAAgB,CAAE,YACV,CACL,OAAQ,EAAM,OAAO,OAAS,EAC9B,WAAY,EAAM,YAAY,OAAO,CAAC,QAAS,QAAQ,EAAG,CACxD,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,aACvC,CAAC,EACD,SAAU,CACR,CACE,OAAQ,CAAE,UACD,EAET,MAAO,CACL,WAAY,IACZ,MAAO,qBACP,WAAY,EAAM,YAAY,OAAO,CAAC,QAAS,QAAQ,EAAG,CACxD,OAAQ,EAAM,YAAY,OAAO,MACjC,SAAU,EAAM,YAAY,SAAS,cACvC,CAAC,CACH,CACF,CACF,CACF,EACD,EAEK,GAAS,EAAO,GAAW,CAC/B,kBAAoB,GACX,IAAS,MAEpB,CAAC,GAAG,CAAE,YACG,CACL,MAAO,IACP,WAAY,EACZ,WAAY,SACZ,UAAW,aACX,SAAU,CACR,CACE,OAAQ,CAAE,UACD,EAET,MAAO,CACL,GAAG,GAAY,CAAK,EACpB,qBAAsB,GAAY,CAAK,CACzC,CACF,EACA,CACE,OAAQ,CAAE,UACD,CAAC,EAEV,MAAO,CACL,GAAG,GAAY,CAAK,EACpB,qBAAsB,GAAY,CAAK,CACzC,CACF,CACF,CACF,EACD,EAkCD,SAAS,GAAiB,CAAE,QAAO,WAAU,WAAU,kBAAyC,CAC9F,IAAM,EAAQ,GAAS,EACjB,CAAC,EAAM,GAAW,EAAS,EAAI,EAC/B,EAAW,GAAY,EAE7B,SAAS,GAAmB,CAC1B,EAAQ,EAAI,CACd,CAEA,SAAS,GAAoB,CAC3B,EAAQ,EAAK,CACf,CAEA,OACE,EAAC,EAAD,CAAK,GAAI,CAAE,QAAS,MAAO,WAA3B,CACE,EAAC,EAAD,CAAc,CAAA,EACd,EAAC,GAAD,CAAQ,SAAS,QAAc,gBAC7B,EAAC,GAAD,CAAA,SAAA,CACE,EAAC,EAAD,CACE,MAAM,UACN,aAAW,cACX,QAAS,EACT,KAAK,QACL,GAAI,CACF,CACE,YAAa,CACf,EACA,GAAQ,CAAE,QAAS,MAAO,CAC5B,WAEA,EAAC,GAAD,CAAS,CAAA,CACC,CAAA,EACZ,EAAC,EAAD,CAAY,QAAQ,KAAK,OAAA,GAAO,UAAU,eACvC,CACS,CAAA,EACX,CACM,CAAA,CAAA,CACH,CAAA,EACR,EAAC,GAAD,CAAQ,QAAQ,YAAkB,gBAAlC,CACE,EAAC,GAAD,CAAA,SACE,EAAC,EAAD,CAAY,QAAS,WAClB,EAAM,YAAc,MAAQ,EAAC,GAAD,CAAiB,CAAA,EAAI,EAAC,GAAD,CAAgB,CAAA,CACxD,CAAA,CACA,CAAA,EACd,EAAC,EAAD,CAAU,CAAA,EACT,EAAS,IAAK,GAEX,EAACC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAY,QAAS,EAAO,KAAO,KAAM,GAAI,CAAE,YAAa,EAAO,EAAI,CAAE,WACtE,EAAO,EAAK,SAAW,EAAS,EAAK,SAAU,CAAC,CACvC,CAAA,EACX,EAAK,QAAQ,IAAK,GAEf,EAAC,GAAD,CAA0B,eAAA,GAAe,GAAI,CAAE,QAAS,OAAQ,WAC9D,EAAC,EAAD,CACE,GAAI,CACF,CACE,UAAW,GACX,GAAI,GACN,EACA,EACI,CACE,eAAgB,SAClB,EACA,CACE,eAAgB,QAClB,CACN,EACA,UAAW,EACX,GAAI,EAAO,GACX,SAAU,EAAS,WAAa,EAAO,YAhBzC,CAkBE,EAAC,GAAD,CACE,GAAI,CACF,CACE,SAAU,EACV,eAAgB,QAClB,EACA,EACI,CACE,GAAI,CACN,EACA,CACE,GAAI,MACN,CACN,WAEC,EAAO,KACN,EAAO,KACJ,EAED,KADF,EAAC,EAAD,CAAA,SAAa,EAAS,EAAO,MAAO,CAAC,CAAc,CAAA,CAEzC,CAAA,EACd,EAAC,GAAD,CACE,QAAS,EAAO,MAChB,GAAI,CACF,EACI,CACE,QAAS,CACX,EACA,CACE,QAAS,CACX,CACN,CACD,CAAA,CACa,GACR,EArDK,EAAO,EAqDZ,CAEb,CACG,CAAA,CAAA,EACN,EAAC,EAAD,CAAU,CAAA,CACF,CAAA,EAjEK,EAAK,QAiEV,CAEb,CACK,IACR,EAAC,EAAD,CAAK,UAAU,OAAO,GAAI,CAAE,SAAU,EAAG,EAAG,CAAE,WAA9C,CACE,EAAC,GAAD,CAAe,CAAA,EACd,CACE,GACF,GAET,CC9QA,SAAS,GAAY,CAAE,OAAM,KAAI,GAAG,GAAqC,CACvE,OACE,EAAA,EAAA,CAAA,SACG,EAAK,MAAM;CAAI,EAAE,KAAK,EAAM,IAEzB,EAAC,EAAD,CAAwB,GAAI,CAAE,OAAQ,EAAG,GAAG,CAAG,EAAG,GAAI,WACnD,CACS,EAFK,CAEL,CAEf,CACD,CAAA,CAEN,CCfA,MAAM,GAAgB,ECStB,SAAS,GAAa,CAAE,eAAc,QAAO,GAAG,GAAkC,CAChF,GAAM,CACJ,UAAW,CAAE,SAAU,EAAc,UAAS,iBAC5C,GAAe,EAEnB,OACE,EAAC,EAAD,CACE,MAAM,UACN,SAAU,EAAY,UAAa,GAAgB,CAAC,GAAY,EAChE,QAAS,EACT,KAAK,SACL,QAAQ,YACR,GAAI,WAEH,CACK,CAAA,CAEZ,CCtBA,SAAS,GAAuB,EAAkB,EAAgB,IAAgB,CAChF,GAAM,CAAC,EAAgB,GAAqB,EAAoB,CAAK,EAWrE,OATA,MAAgB,CACd,IAAM,EAAU,eAAiB,CAC/B,EAAkB,CAAK,CACzB,EAAG,CAAK,EACR,UAAa,CACX,aAAa,CAAO,CACtB,CACF,EAAG,CAAC,EAAO,CAAK,CAAC,EAEV,CACT,CCZA,SAAS,GACP,EACkD,CAClD,GAAM,CAAC,EAAM,GAAW,MAA0B,CAChD,IAAM,EAAkB,OAAO,SAAS,KAAK,QAAQ,IAAK,EAAE,EAC5D,OAAQ,GAAqB,IAAS,GAAK,EAAc,CAC3D,CAAC,EACK,EAAoB,MAAkB,CAC1C,IAAM,EAAkB,OAAO,SAAS,KAAK,QAAQ,IAAK,EAAE,EAC5D,EAAS,GAAqB,IAAS,GAAK,EAAc,CAAI,CAChE,EAAG,CAAC,EAAS,CAAW,CAAC,EAmBzB,OAjBA,OACE,OAAO,iBAAiB,aAAc,CAAiB,MAC1C,CACX,OAAO,oBAAoB,aAAc,CAAiB,CAC5D,GACC,CAAC,CAAiB,CAAC,EAYf,CAAC,EAVW,EAChB,GAAmE,CAClE,IAAM,EAAe,OAAO,GAAY,WAAa,EAAQ,CAAI,EAAI,EACjE,IAAiB,IACnB,OAAO,SAAS,KAAO,EAE3B,EACA,CAAC,CAAI,CAGgB,CAAC,CAC1B"}