@australiangreens/ag-internal-components 0.3.12 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/components/ExampleComponent/ExampleComponent.tsx","../../src/components/AgDialog/AgDialog.tsx","../../src/components/FetchAutocomplete/const.ts","../../src/components/FetchAutocomplete/FetchAutocomplete.tsx","../../src/components/SingleAutocomplete/index.tsx","../../src/components/SessionExpiryDialog/index.tsx","../../src/components/AuthGuard/auth0ErrorParsing.ts","../../src/components/AuthGuard/AuthGuard.tsx","../../src/providers/SaladBar/defaults.ts","../../src/providers/SaladBar/SaladBarContext.tsx","../../src/errors/ContextError.ts","../../src/providers/SaladBar/useSaladBar.ts","../../src/providers/SaladBar/testWrappers.tsx","../../src/domainCode/hooks.tsx","../../src/domainCode/DomainCodeDialog.tsx","../../src/layouts/AppLayout/mobile.ts","../../src/layouts/AppLayout/defaults.tsx","../../src/layouts/AppLayout/stateAtoms.ts","../../src/layouts/AppLayout/NavBar/LinksMenu.tsx","../../src/layouts/AppLayout/NavBar/Styling.tsx","../../src/utils/auth.ts","../../src/utils/consoleSuppression.ts","../../src/utils/simpleHashCode.ts","../../src/layouts/AppLayout/NavBar/UserInfo.tsx","../../src/layouts/AppLayout/NavBar/NavBar.tsx","../../src/layouts/AppLayout/PageContainer.tsx","../../src/layouts/AppLayout/TopBar.tsx","../../src/layouts/AppLayout/AppLayout.tsx","../../src/themes/fed21Theme.ts","../../src/themes/internalAgSystemsTheme.ts"],"sourcesContent":["import { useState } from 'react';\nimport { Button, Paper, Typography } from '@mui/material';\n\nexport interface ExampleComponentProps {\n /** Test */\n text: string;\n}\n\nexport default function ExampleComponent({ text }: ExampleComponentProps) {\n const [num, setNum] = useState(0);\n\n return (\n <>\n <Typography variant=\"h6\" color=\"inherit\" component=\"div\" sx={{ fontSize: '22px' }}>\n Hello world\n </Typography>\n\n <Typography variant=\"caption\" display=\"block\">\n <span>Just ensuring MUI is working as planned as a peer dependency. v0.0.11</span>\n </Typography>\n <Button\n variant=\"outlined\"\n onClick={() => setNum((oldNum) => oldNum + 1)}\n aria-label=\"Increment\"\n >\n Hello I am a button\n </Button>\n <p>\n This is some text: <span>{text}</span>\n </p>\n <Paper>This number will incremember when button pressed: {num}</Paper>\n </>\n );\n}\n","import {\n Breakpoint,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n LinearProgress,\n SxProps,\n Theme,\n} from '@mui/material';\nimport { PropsWithChildren, ReactElement, useState } from 'react';\n\nexport type AgDialogButtonConfig = {\n text: string;\n onClick?: () => Promise<void>;\n disabled?: boolean;\n testId?: string;\n buttonColor?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning';\n};\n\nexport type AgDialogProps = PropsWithChildren<{\n isOpen: boolean;\n dialogTitle: string | ReactElement;\n maxWidth?: false | Breakpoint;\n primaryButton?: AgDialogButtonConfig;\n secondaryButton?: AgDialogButtonConfig;\n additionalButtons?: AgDialogButtonConfig[];\n 'data-testid'?: string;\n onClose: () => void;\n sx?: SxProps<Theme>;\n disableCloseOnBackdropOrEscape?: boolean;\n isLoading?: boolean;\n}>;\n\n/**\n * Standard dialog that will auto disable it's buttons while the primaryButton onClick function is pending.\n *\n */\nconst AgDialog = ({\n isOpen,\n dialogTitle,\n children,\n maxWidth,\n primaryButton,\n secondaryButton,\n additionalButtons,\n onClose: handleClose,\n sx,\n 'data-testid': dataTestId,\n disableCloseOnBackdropOrEscape = false,\n isLoading = false,\n}: AgDialogProps) => {\n const [areButtonsDisabled, setButtonsDisabled] = useState(false);\n\n return (\n <Dialog\n open={isOpen}\n onClose={async (_event, reason) => {\n if (\n disableCloseOnBackdropOrEscape &&\n (reason === 'backdropClick' || reason === 'escapeKeyDown')\n ) {\n return;\n }\n if (areButtonsDisabled) return;\n if (secondaryButton?.onClick) {\n await secondaryButton.onClick();\n } else {\n handleClose();\n }\n }}\n fullWidth\n maxWidth={maxWidth ?? 'xs'}\n data-testid={dataTestId}\n sx={sx}\n >\n {isLoading && <LinearProgress sx={{ height: '4px', marginBottom: '-4px' }} />}\n <DialogTitle>{dialogTitle}</DialogTitle>\n <DialogContent sx={{ '& > :last-child': { marginBottom: 0 } }}>{children}</DialogContent>\n <DialogActions>\n <Button\n onClick={secondaryButton?.onClick ?? handleClose}\n data-testid={secondaryButton?.testId}\n disabled={secondaryButton?.disabled || areButtonsDisabled}\n color={secondaryButton?.buttonColor}\n >\n {secondaryButton?.text ?? 'Cancel'}\n </Button>\n {additionalButtons &&\n additionalButtons.map((buttonConfig, idx) => {\n return (\n <Button\n key={idx}\n onClick={buttonConfig?.onClick}\n data-testid={buttonConfig?.testId}\n disabled={buttonConfig?.disabled || areButtonsDisabled}\n color={buttonConfig?.buttonColor}\n >\n {buttonConfig.text ?? `Button ${idx}`}\n </Button>\n );\n })}\n {primaryButton && (\n <Button\n onClick={async () => {\n setButtonsDisabled(true);\n await primaryButton.onClick?.();\n setButtonsDisabled(false);\n }}\n data-testid={primaryButton.testId}\n disabled={primaryButton.disabled || areButtonsDisabled}\n color={primaryButton?.buttonColor}\n >\n {primaryButton.text}\n </Button>\n )}\n </DialogActions>\n </Dialog>\n );\n};\n\nexport default AgDialog;\n","export const DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS = {\n popper: {\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [115, -15],\n },\n },\n ],\n },\n};\n\nexport const MOUSE_EVENT_BUTTONS = {\n left: 0,\n middle: 1,\n right: 2,\n};\n","import { Cancel as CancelIcon, ArrowDropDown as DefaultPopupIcon } from '@mui/icons-material';\nimport {\n Autocomplete,\n Box,\n Chip,\n CircularProgress,\n SxProps,\n TextField,\n Theme,\n Tooltip,\n TooltipProps,\n Typography,\n} from '@mui/material';\nimport { useQuery } from '@tanstack/react-query';\nimport match from 'autosuggest-highlight/match';\nimport parse from 'autosuggest-highlight/parse';\nimport { ReactNode, SyntheticEvent, useState } from 'react';\n\nimport {\n AutocompleteGenericEntity,\n AutocompleteGenericEntityIdType,\n FetchAutocompleteChangeReason,\n} from '../types';\nimport { DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS, MOUSE_EVENT_BUTTONS } from './const';\n\nexport const useAutocompleteOptions = <EntityType extends AutocompleteGenericEntity>({\n minLength,\n preLoadedOptions,\n lookup,\n label,\n inputValue,\n}: {\n minLength: number;\n preLoadedOptions: EntityType[] | undefined;\n lookup: (lookupValue: string) => Promise<EntityType[] | undefined | null | void>;\n label: string;\n inputValue: string;\n}) => {\n return useQuery({\n queryFn: () => {\n if (minLength && inputValue.length < minLength) return preLoadedOptions ?? [];\n if (preLoadedOptions)\n return preLoadedOptions.filter((option) =>\n option.label.toLowerCase().includes(inputValue.toLowerCase())\n );\n return lookup(inputValue);\n },\n queryKey: ['autocomplete', label, inputValue],\n });\n};\n\nexport type FetchAutocompleteProps<EntityType extends AutocompleteGenericEntity> = {\n /**\n * Callback fired when the value changes. This is passed directly to the\n * underlying Autocomplete, but it is triggered by the Autocomplete's own\n * onChange, with the exception of the deletion of chips.\n */\n onChange: (\n newValue: EntityType[],\n reason: FetchAutocompleteChangeReason,\n event: SyntheticEvent<Element, Event>\n ) => unknown;\n\n /** Generally only useful for testing */\n onInputChange?: (\n newValue: EntityType[] | null,\n reason: string,\n event: SyntheticEvent<Element, Event>\n ) => void;\n\n /** The sequence of entity types returned. */\n value: EntityType[];\n\n /**\n * A minimum length of characters in the Autocomplete before the lookup is called. If not set,\n * then the lookup is called every time.\n */\n minLength?: number;\n\n /** A nice label for the autocomplete. */\n label: string;\n\n /** The lookup function, for looking up EntityType options from a remote resource. */\n lookup?: (lookupValue: string) => Promise<EntityType[] | undefined | null | void>;\n\n /** If you have your EntityType options at hand, preload them instead, and save the\n * user's time. They should all be available when the user clicks on the drop down\n * menu, without even a single keystroke provided. This is the property you want.\n */\n preLoadedOptions?: EntityType[] | undefined;\n\n /** The popup icon */\n popupIcon?: ReactNode;\n\n /**If true, the Popper content will be under the DOM hierarchy of the parent\n * component. Passed directly to underlying MUI Autocomplete component.*/\n disablePortal?: boolean;\n\n /**\n * Used for the data-testid value of the outer most component. The underlying\n * AutoComplete component has the id of this, followed by a colon then\n * 'AutoComplete', while the text field is followed by 'TextField'.\n *\n * Currently has no default to avoid collisions. May change in future to\n * simply be 'FetchAutocomplete' if that is not an issue.\n */\n 'data-testid'?: string;\n\n loadingText?: string;\n noOptionsText?: string;\n error?: boolean;\n helperText?: ReactNode;\n enableHighlighting?: boolean;\n sx?: SxProps<Theme>;\n\n textFieldColor?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';\n textFieldVariant?: 'filled' | 'outlined' | 'standard';\n textFieldFocused?: boolean;\n textFieldSx?: SxProps<Theme>;\n\n boxSx?: SxProps<Theme>;\n disableIconFlip?: boolean;\n chipToolTipSlotProps?: TooltipProps['slotProps'];\n\n placeholderText?: string;\n\n /**\n * Called when a right click is detected.\n */\n onRightClick?: (event: React.MouseEvent) => void;\n\n /**\n * If set to true, the default right click behaviour will be overridden: the\n * dropdown/prompt will not appear AND neither will the browser context menu.\n *\n * Use in combination with onRightClick to override the behaviour.\n *\n * Note: This can't just be done by passing through onRightClick having it\n * prevent the event default, because there are two events that need to be\n * listened for.\n */\n disableDefaultRightClickBehaviour?: boolean;\n\n readOnly?: boolean;\n\n hideInputEndAdornment?: boolean;\n};\n\n/**\n * A wrapper around MUI's Autocomplete component, specifically for use with live\n * as-you-type fetching from an api and styled the way we want it across the app\n * by default.\n */\nexport default function FetchAutocomplete<EntityType extends AutocompleteGenericEntity>({\n lookup = async () => {},\n enableHighlighting = true,\n onChange,\n onInputChange,\n minLength = 0,\n label,\n value,\n 'data-testid': dataTestId,\n sx,\n boxSx,\n textFieldColor,\n textFieldVariant = 'filled',\n textFieldFocused,\n textFieldSx,\n loadingText = 'Loading...',\n noOptionsText = 'No options',\n popupIcon = <DefaultPopupIcon />,\n error = false,\n helperText = '',\n preLoadedOptions = undefined,\n disablePortal = false,\n disableIconFlip = false,\n chipToolTipSlotProps = DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS,\n placeholderText = undefined,\n onRightClick = () => {},\n disableDefaultRightClickBehaviour = false,\n readOnly,\n hideInputEndAdornment,\n}: FetchAutocompleteProps<EntityType>) {\n const [inputValue, setInputValue] = useState('');\n\n const handleDelete = (\n e: SyntheticEvent<Element, Event>,\n deleteValue: AutocompleteGenericEntityIdType\n ) => {\n const newInternalValue = value.filter((x) => x.id !== deleteValue);\n onChange(newInternalValue, 'delete', e);\n };\n\n const { data: options, isLoading } = useAutocompleteOptions({\n inputValue,\n label,\n lookup,\n minLength,\n preLoadedOptions,\n });\n\n const isInputMinimumLength = inputValue.length >= minLength;\n\n return (\n <div data-testid={dataTestId}>\n <Autocomplete\n sx={{\n ...sx,\n ...(disableIconFlip\n ? { '.MuiAutocomplete-popupIndicatorOpen': { transform: 'rotate(0deg)' } }\n : {}),\n }}\n data-testid={dataTestId ? `${dataTestId}:Autocomplete` : undefined}\n disablePortal={disablePortal}\n multiple\n getOptionLabel={(option) => (typeof option === 'string' ? option : option.label)}\n loading={isInputMinimumLength ? isLoading : false}\n // See https://github.com/mui/material-ui/issues/18514\n // TODO: Is this still relevant?\n options={[...value, ...(options ?? [])]}\n // However we hide the selected ones from the dropdown, since most of\n // the time they won't contain what the user typed next\n filterSelectedOptions\n // autoComplete// This doesn't work at time of writing https://github.com/mui-org/material-ui/issues/22648\n includeInputInList\n value={value}\n onChange={(event, newValue, reason) => {\n onChange(newValue as EntityType[], reason, event);\n }}\n onInputChange={(event, newInputValue, reason) => {\n setInputValue(newInputValue);\n if (onInputChange) onInputChange(value, reason, event);\n }}\n noOptionsText={isInputMinimumLength ? noOptionsText : 'Start typing to search'}\n loadingText={loadingText}\n popupIcon={popupIcon}\n renderInput={(params) => (\n <TextField\n {...params}\n label={label}\n fullWidth\n variant={textFieldVariant}\n error={error}\n helperText={helperText}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: hideInputEndAdornment ? undefined : (\n <>\n {isLoading ? <CircularProgress color=\"inherit\" size={20} /> : null}\n {params.InputProps.endAdornment}\n </>\n ),\n },\n }}\n data-testid={dataTestId ? `${dataTestId}:Autocomplete:TextField` : undefined}\n onKeyDown={(event: React.KeyboardEvent) => {\n if (event.key === 'Backspace' || event.key === 'Delete') {\n event.stopPropagation();\n }\n }}\n color={textFieldColor}\n placeholder={placeholderText}\n sx={textFieldSx}\n focused={textFieldFocused}\n />\n )}\n // We render tags/chips below the component\n renderValue={() => null}\n isOptionEqualToValue={(option, v) => option.id === v.id}\n renderOption={(props, option, state) => {\n if (enableHighlighting) {\n const matches = match(option.label, state.inputValue, {\n insideWords: true,\n findAllOccurrences: true,\n });\n const parts = parse(option.label, matches);\n\n return (\n <li\n {...props}\n key={option.id}\n data-testid={\n dataTestId\n ? `${dataTestId}:Autocomplete:option(${option.id.toString()})`\n : undefined\n }\n >\n <div>\n {parts.map((part, index) => (\n <span\n key={index}\n style={{\n fontWeight: part.highlight ? 700 : 400,\n }}\n >\n {part.text}\n </span>\n ))}\n </div>\n </li>\n );\n } else {\n return (\n <li\n {...props}\n key={option.id}\n data-testid={\n dataTestId ? `${dataTestId}:option(${option.id.toString()})` : undefined\n }\n >\n {option.label}\n </li>\n );\n }\n }}\n onMouseDownCapture={(event) => {\n if (event.button === MOUSE_EVENT_BUTTONS.right && disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n }}\n onContextMenuCapture={(event) => {\n if (disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n onRightClick(event);\n }}\n readOnly={readOnly}\n />\n {value.length > 0 && (\n <Box sx={boxSx}>\n {value.map((val) => {\n return (\n <Chip\n key={val.id}\n sx={{\n marginTop: 1,\n marginRight: 1,\n height: 'auto',\n }}\n label={\n <Tooltip\n title={val.tooltipContent ?? ''}\n placement=\"bottom-start\"\n slotProps={chipToolTipSlotProps}\n >\n <Typography style={{ whiteSpace: 'normal' }}>\n {val.chipLabel ? val.chipLabel : val.label}\n </Typography>\n </Tooltip>\n }\n data-testid={dataTestId ? `${dataTestId}:Chip(${val.id.toString()})` : undefined}\n onDelete={(e) => handleDelete(e, val.id)}\n deleteIcon={\n <CancelIcon\n data-testid={\n dataTestId ? `${dataTestId}:Chip(${val.id.toString()}):deleteIcon` : undefined\n }\n />\n }\n />\n );\n })}\n </Box>\n )}\n </div>\n );\n}\n","import {\n Autocomplete,\n AutocompleteChangeReason,\n CircularProgress,\n Stack,\n SxProps,\n TextField,\n Theme,\n} from '@mui/material';\nimport { ReactNode, SyntheticEvent, useState } from 'react';\nimport { useAutocompleteOptions } from '../FetchAutocomplete';\nimport { MOUSE_EVENT_BUTTONS } from '../FetchAutocomplete/const';\nimport { AutocompleteGenericEntity } from '../types';\n\n/**\n * MUI Autocomplete has a harmless warning when the available options do not\n * include the old selected value of the auto complete (its skipped in\n * production). This regex can be used as as suppressConsole('warn',\n * MUI_AUTOCOMPLETE_VALUE_WARNING_REGEX) to avoid it in development\n * environments.\n */\nexport const MUI_AUTOCOMPLETE_VALUE_WARNING_REGEX = /MUI: The value provided to.*is invalid/i;\n\nexport type SingleAutocompleteProps<EntityType extends AutocompleteGenericEntity> = {\n /**\n * Callback fired when the value changes. reason is one of \"createOption\",\n * \"selectOption\", \"removeOption\", \"blur\" or \"clear\". This is passed directly\n * to the underlying Autocomplete, but it is triggered by the Autocomplete's\n * own onChange.\n */\n onChange: (\n event: SyntheticEvent<Element, Event>,\n newValue: EntityType | null,\n reason: AutocompleteChangeReason\n ) => unknown;\n\n /** Generally only useful for testing */\n onInputChange?: (\n newValue: string | null,\n reason: string,\n event: SyntheticEvent<Element, Event>\n ) => void;\n\n value: EntityType | null;\n\n /**\n * A minimum length of characters in the Autocomplete before the lookup is called. If not set,\n * then the lookup is called every time.\n */\n minLength?: number;\n\n /** A nice label for the autocomplete. */\n label: string;\n\n /** The lookup function, for looking up EntityType options from a remote resource. */\n lookup?: (lookupValue: string) => Promise<EntityType[] | undefined | null | void>;\n\n preLoadedOptions?: EntityType[] | undefined;\n\n /**If true, the Popper content will be under the DOM hierarchy of the parent\n * component. Passed directly to underlying MUI Autocomplete component.*/\n disablePortal?: boolean;\n\n /**\n * Used for the data-testid value of the outer most component. The underlying\n * AutoComplete component has the id of this, followed by a colon then\n * 'AutoComplete', while the text field is followed by 'TextField'.\n *\n * Currently has no default to avoid collisions. May change in future to\n * simply be 'FetchAutocomplete' if that is not an issue.\n */\n 'data-testid'?: string;\n\n hideButton?: boolean;\n loadingText?: string;\n noOptionsText?: string;\n sx?: SxProps<Theme>;\n textFieldColor?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';\n textFieldVariant?: 'filled' | 'outlined' | 'standard';\n textFieldFocused?: boolean;\n textFieldSx?: SxProps<Theme>;\n error?: boolean;\n helperText?: ReactNode;\n disabled?: boolean;\n popupIcon?: ReactNode;\n disableIconFlip?: boolean;\n\n placeholderText?: string;\n\n /**\n * Called when a right click is detected.\n */\n onRightClick?: (event: React.MouseEvent) => void;\n\n /**\n * If set to true, the default right click behaviour will be overridden: the\n * dropdown/prompt will not appear AND neither will the browser context menu.\n *\n * Use in combination with onRightClick to override the behaviour.\n *\n * Note: This can't just be done by passing through onRightClick having it\n * prevent the event default, because there are two events that need to be\n * listened for.\n */\n disableDefaultRightClickBehaviour?: boolean;\n\n readOnly?: boolean;\n\n hideInputEndAdornment?: boolean;\n};\n\nconst SingleAutocomplete = <EntityType extends AutocompleteGenericEntity>({\n lookup = async () => {},\n onChange,\n onInputChange,\n label,\n value,\n sx,\n textFieldColor,\n textFieldVariant = 'filled',\n textFieldFocused,\n textFieldSx,\n error = false,\n 'data-testid': dataTestId,\n loadingText = 'Loading...',\n noOptionsText = 'No options',\n minLength = 3,\n disablePortal = false,\n preLoadedOptions,\n helperText = '',\n disabled,\n popupIcon,\n disableIconFlip,\n placeholderText = undefined,\n onRightClick = () => {},\n disableDefaultRightClickBehaviour = false,\n readOnly,\n hideInputEndAdornment,\n}: SingleAutocompleteProps<EntityType>) => {\n const [inputValue, setInputValue] = useState('');\n\n const { data: options, isLoading } = useAutocompleteOptions({\n inputValue,\n label,\n lookup,\n minLength: minLength ?? 0,\n preLoadedOptions,\n });\n\n const isInputMinimumLength = inputValue.length >= minLength;\n\n return (\n <div data-testid={dataTestId}>\n <Stack\n direction=\"row\"\n spacing={1}\n onMouseDownCapture={(event) => {\n if (event.button === MOUSE_EVENT_BUTTONS.right) {\n if (disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n }}\n onContextMenuCapture={(event) => {\n if (disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n onRightClick(event);\n }}\n >\n <Autocomplete\n sx={{\n ...sx,\n ...(disableIconFlip\n ? { '.MuiAutocomplete-popupIndicatorOpen': { transform: 'rotate(0deg)' } }\n : {}),\n }}\n data-testid={dataTestId ? `${dataTestId}:Autocomplete` : undefined}\n loading={isInputMinimumLength ? isLoading : false}\n options={options ?? []}\n onChange={(event, newValue, reason) => {\n onChange(event, newValue, reason);\n }}\n disablePortal={disablePortal}\n filterOptions={(option) => option}\n value={value}\n noOptionsText={isInputMinimumLength ? noOptionsText : 'Start typing to search'}\n loadingText={loadingText}\n getOptionLabel={(option) => option.label}\n popupIcon={popupIcon}\n renderInput={(params) => (\n <TextField\n data-testid={dataTestId ? `${dataTestId}:Autocomplete:TextField` : undefined}\n {...params}\n variant={textFieldVariant}\n label={label}\n color={textFieldColor}\n error={error}\n helperText={helperText}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: hideInputEndAdornment ? undefined : (\n <>\n {isLoading ? <CircularProgress color=\"inherit\" size={20} /> : null}\n {params.InputProps.endAdornment}\n </>\n ),\n },\n }}\n placeholder={placeholderText}\n sx={textFieldSx}\n focused={textFieldFocused}\n />\n )}\n isOptionEqualToValue={(option, v) => option.id === v.id}\n onInputChange={(event, newInputValue, reason) => {\n setInputValue(newInputValue);\n if (onInputChange) onInputChange(newInputValue, reason, event);\n }}\n renderOption={(props, option) => (\n <li\n {...props}\n key={option.id}\n data-testid={\n dataTestId\n ? `${dataTestId}:Autocomplete:option(${option.id.toString()})`\n : undefined\n }\n >\n {option.label}\n </li>\n )}\n disabled={disabled}\n readOnly={readOnly}\n />\n </Stack>\n </div>\n );\n};\n\nexport default SingleAutocomplete;\n","import { useAuth0 } from '@auth0/auth0-react';\nimport { Buffer } from 'buffer';\n\nimport AgDialog, { AgDialogButtonConfig } from '../AgDialog';\n\n// This gets the auth0 expiry value for a token. If the token cannot be\n// parsed, then -1 is returned.\n//\n// The following code is from here (but has been updated to go from atob\n// to Buffer.from).\n//\n// https://stackoverflow.com/questions/38552003/how-to-decode-jwt-token-in-javascript-without-using-a-library#38552302\n//\n// Note: for confusion, the exp value is in seconds after the epoch:\n// NumericDate\n// A JSON numeric value representing the number of seconds from\n// 1970-01-01T00:00:00Z UTC until the specified UTC date/time,\n// ignoring leap seconds. This is equivalent to the IEEE Std 1003.1,\n// 2013 Edition [POSIX.1] definition \"Seconds Since the Epoch\", in\n// which each day is accounted for by exactly 86400 seconds, other\n// than that non-integer values can be represented. See RFC 3339\n// [RFC3339] for details regarding date/times in general and UTC in\n// particular.\n// https://www.rfc-editor.org/rfc/rfc7519#section-2\n// To use with Date, multiply with 1000.\n\n// A lot of the libraries that we expect in node are not available out\n// of the box with vite, like Buffer. This is why we need to import it\n// seperately. See:\n// https://stackoverflow.com/questions/70714690/buffer-is-not-defined-in-react-vite\n\nexport const getAuth0Expiry = (token: string) => {\n if (!token) {\n return -1;\n }\n try {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n Buffer.from(base64, 'base64')\n .toString('utf8')\n .split('')\n .map(function (c) {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join('')\n );\n const jsonParsedPayload = JSON.parse(jsonPayload);\n if (jsonParsedPayload?.exp) {\n return jsonParsedPayload.exp as number;\n }\n return -1;\n } catch {\n return -1;\n }\n};\n\nexport type SessionExpiryDialogProps = {\n open: boolean;\n closeHandler: () => void;\n setAuth0ExpiryTime: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst SessionExpiryDialog = ({\n open = false,\n closeHandler,\n setAuth0ExpiryTime,\n}: SessionExpiryDialogProps) => {\n const { logout, getAccessTokenSilently } = useAuth0();\n\n const handleDialogClose = async () => {\n logout({ logoutParams: { returnTo: `${window.location.origin}` } });\n };\n\n const handleDialogSuccess = async () => {\n const tokenSecond = await getAccessTokenSilently({ cacheMode: 'off' });\n const tokenExp = getAuth0Expiry(tokenSecond) * 1000;\n setAuth0ExpiryTime(tokenExp);\n closeHandler();\n };\n\n const successButtonConfig = {\n text: 'Continue',\n onClick: handleDialogSuccess,\n disabled: false,\n testId: 'PreferencesDialog',\n buttonColor: 'secondary',\n } as AgDialogButtonConfig;\n\n const cancelButtonConfig = {\n text: 'Log out',\n onClick: handleDialogClose,\n disabled: false,\n testId: 'PreferencesDialog',\n buttonColor: 'secondary',\n } as AgDialogButtonConfig;\n\n return (\n <AgDialog\n isOpen={open}\n primaryButton={successButtonConfig}\n secondaryButton={cancelButtonConfig}\n onClose={closeHandler}\n dialogTitle={'Session expiry'}\n disableCloseOnBackdropOrEscape\n >\n <p style={{ marginBottom: 0 }}>\n Your session is about to time out due to inactivity. Do you want to continue?\n </p>\n </AgDialog>\n );\n};\n\nexport default SessionExpiryDialog;\n","import { OAuthError } from '@auth0/auth0-react';\n\n/**\n * instanceof OAuthError doesn't work in for whatever useAuth0 hook returns, so\n * we use duck typing guard. There are other specified properties too, but only error\n * seems to be guaranteed\n */\nexport function isOAuthError(error: Error): error is OAuthError {\n return 'error' in error;\n}\n\n/**\n * Will only return true if the error looks like it was caused by our custom\n * Application-Access and Role-Based-Application-Access actions in the login\n * flow of auth0 tenant. See README.md for detail\n */\nexport function errorFromApplicationAccessRejection(errorObject: OAuthError) {\n const error = errorObject.error;\n const errorDescription = errorObject?.error_description ?? '';\n\n return (\n error === 'access_denied' &&\n errorDescription.startsWith('You do not have the required authorization')\n );\n}\n\n/**\n * Will only return true if the error looks like it was caused by a user not\n * granting the application access to their profile in the tenant when asked on\n * first login.\n */\nexport function errorFromUserNotAuthorisingApp(errorObject: OAuthError) {\n const error = errorObject.error;\n const errorDescription = errorObject?.error_description ?? '';\n\n return (\n error === 'access_denied' && errorDescription.startsWith('User did not authorize the request')\n );\n}\n\n/**\n * Will only return true if the error looks like it was due to script execution\n * time issue. Specifically, the execution of custom actions in the login flow\n * exceeded the time limit (20s at time of writing). Mostly likely issues\n * syncing user data with AG internal systems.\n */\nexport function errorFromScriptExecutionTimeout(errorObject: OAuthError) {\n const error = errorObject.error;\n const errorDescription = errorObject?.error_description ?? '';\n\n return error === 'access_denied' && errorDescription.match(/Script.*time.*exceeded/);\n}\n","import { AppState, RedirectLoginOptions, useAuth0 } from '@auth0/auth0-react';\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Typography,\n} from '@mui/material';\nimport Skeleton from '@mui/material/Skeleton';\nimport { PropsWithChildren, useEffect, useMemo } from 'react';\n\nimport {\n errorFromApplicationAccessRejection,\n errorFromScriptExecutionTimeout,\n errorFromUserNotAuthorisingApp,\n isOAuthError,\n} from './auth0ErrorParsing';\n\nexport interface AuthGuardProps {\n appName?: string;\n\n /** Defaults to 'unknown'. If set to 'all', will always re-throw the error, so\n * won't display the normal message to user and be handled elsewhere in the\n * app. If set to 'unknown', this will only be done if the failure reason\n * couldn't be inferred from the error description etc or if its a completely\n * unknown error without a description etc.*/\n throwErrors?: 'none' | 'unknown' | 'all';\n\n /** Called in case of an authentication error, regardless of if its recognised\n * or not */\n onError?: (error: Error) => void;\n\n disableConsoleLogging?: boolean;\n}\n\n/**\n * Use as parent of main app (but within Auth0Provider) so when an anonymous\n * user visits the will be redirected to the login page and returned to the page\n * they we're redirected from after login.\n *\n * This is similar to the withAuthenticationRequired HOC from Auth0, which\n * operates on a per-route basis.\n *\n * This component is also responsible for detecting an an authorisation error\n * that is triggered by one of our rules defined for our Auth0 tenant\n *\n * Do not use this if any routes need to be accessible to anonymous users.\n */\nexport default function AuthGuard({\n children,\n appName = 'the app',\n throwErrors = 'none',\n disableConsoleLogging = false,\n onError = () => {},\n}: PropsWithChildren<AuthGuardProps>) {\n const { isAuthenticated, isLoading, error, loginWithRedirect, logout } = useAuth0();\n\n // Wrapped in a useEffect to avoid re-renders doubling it up\n useEffect(() => {\n // The no-pass-data-to-parent rule doesn't apply in this case since we are\n // deliberately converting the first occurrence of an error into an event so\n // the parent can act on it\n // eslint-disable-next-line react-you-might-not-need-an-effect/no-pass-data-to-parent\n if (error) onError(error);\n }, [error, onError]);\n\n const options: RedirectLoginOptions<AppState> = useMemo(\n () => ({\n appState: {\n returnTo: `${window.location.pathname}${window.location.search}`,\n },\n }),\n []\n );\n useEffect(() => {\n if (isLoading || isAuthenticated || error) return;\n\n loginWithRedirect(options);\n }, [isLoading, isAuthenticated, error, loginWithRedirect, onError, options]);\n\n if (error) {\n if (!disableConsoleLogging) {\n console.error(\n `Error detected in AuthGuard [isAuthenticated=${isAuthenticated},isLoading=${isLoading}]`,\n error\n );\n }\n\n if (throwErrors === 'all') {\n throw error;\n } else if (isOAuthError(error)) {\n let title = 'Auth error';\n let message = 'An unknown Auth0 error occurred.';\n\n if (errorFromApplicationAccessRejection(error)) {\n title = 'Unauthorised';\n message = `You are not authorised to access ${appName}.`;\n } else if (errorFromUserNotAuthorisingApp(error)) {\n title = 'App not authorised';\n message = `You have not authorised ${appName} to access your user profile. This is necessary to use ${appName}.`;\n } else if (errorFromScriptExecutionTimeout(error)) {\n title = 'Auth0 script execution time exceeded';\n message = `The Auth0 login flow exceeded the time limit (20s). Try again in a minute by clicking the RELOAD button below.`;\n } else if (error.message === 'Invalid state') {\n const redirectCount = localStorage.getItem('auth0_redirect_count');\n if (!redirectCount) {\n localStorage.setItem('auth0_redirect_count', '1');\n loginWithRedirect(options);\n } else if (redirectCount && parseInt(redirectCount) < 2) {\n localStorage.setItem('auth0_redirect_count', String(parseInt(redirectCount) + 1));\n loginWithRedirect(options);\n }\n } else {\n if (throwErrors === 'unknown') throw error;\n }\n\n return (\n <Dialog open>\n <DialogTitle>{title}</DialogTitle>\n <DialogContent>\n <Typography>{message}</Typography>\n <br />\n <Typography variant=\"subtitle2\">Details from Auth0</Typography>\n <Typography variant=\"body2\">error: {error?.error ?? 'N/A'}</Typography>\n <Typography variant=\"body2\">\n description: {error?.error_description ?? 'N/A'}\n </Typography>\n </DialogContent>\n <DialogActions>\n {title === 'Auth0 script execution time exceeded' && (\n <Button href={window.location.origin + window.location.pathname}>Reload</Button>\n )}\n <Button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>\n Logout\n </Button>\n </DialogActions>\n </Dialog>\n );\n } else {\n if (throwErrors === 'unknown') throw error;\n }\n }\n\n if (isAuthenticated) {\n localStorage.removeItem('auth0_redirect_count');\n return <>{children}</>;\n }\n\n return <Skeleton variant=\"rectangular\" animation=\"pulse\" height=\"100vh\" width=\"100vw\" />;\n}\n","// The default props passed to the underlying Snackbar component\nimport { SnackbarOrigin } from '@mui/material/Snackbar';\n\nexport const defaultSnackbarProps = {\n autoHideDuration: 6000,\n anchorOrigin: { vertical: 'top', horizontal: 'center' } as SnackbarOrigin,\n\n // The default is false. If we prefer timer to continue when window loses\n // focus, change to true\n disableWindowBlurListener: false,\n};\n\nexport const defaultSaladBarProps = {\n shouldClose: (_event: Event | React.SyntheticEvent<Element, Event>, reason: string) => {\n return reason !== 'clickaway';\n },\n};\n\nexport const defaultEnqueueNotificationOptions = {\n message: '',\n severity: 'info',\n variant: 'standard',\n progressIndicator: undefined, // Can use 'circular' or 'linear'\n};\n","import React, { useRef, useState, createContext, useCallback } from 'react';\nimport { Alert, LinearProgress, CircularProgress, Snackbar, SnackbarProps } from '@mui/material';\n\nimport {\n Notification,\n SaladBarCloseReason,\n SaladBarState,\n SaladBarActions,\n SaladBarContext,\n} from './types';\nimport {\n defaultSaladBarProps,\n defaultSnackbarProps,\n defaultEnqueueNotificationOptions,\n} from './defaults';\n\nconst MAX_QUEUE_LENGTH = 100;\nconst MAX_QUEUE_HIT_REPORT_INTERVAL = 2000;\nconst SALADBAR_INDEX = 2000;\n\n// No need to use uuids, just use an incremented value\nconst generateNotificationKey = (() => {\n let previousKey = 0;\n return () => {\n previousKey += 1;\n return previousKey;\n };\n})();\n\nconst alertWithLinearProgressStyle = {\n borderBottomLeftRadius: '0px',\n borderBottomRightRadius: '0px',\n};\n\n// Note: Must be at at this scope, otherwise useEffect will loop infinitely\nconst defaultOverrideState = {};\nconst defaultOverrideActions = {};\n\nexport const Context = createContext<SaladBarContext | null>(null);\n\nexport interface SaladBarProviderProps extends SnackbarProps {\n /** Allow overriding the state of the SaladBar (for tests etc)*/\n overrideState?: Partial<SaladBarState>;\n\n /** Allow overriding the actions of the SaladBar (for tests etc)*/\n overrideActions?: Partial<SaladBarActions>;\n\n /** Called when an event triggers closing of currently displayed snackbar.\n * Default implementation returns false if reason is 'clickaway', otherwise\n * true.*/\n shouldClose?: (\n event: Event | React.SyntheticEvent<Element, Event>,\n reason: SaladBarCloseReason\n ) => boolean;\n}\n\nexport default function SaladBarProvider({\n overrideState = defaultOverrideState,\n overrideActions = defaultOverrideActions,\n shouldClose = defaultSaladBarProps.shouldClose,\n children,\n ...snackbarProps\n}: SaladBarProviderProps) {\n const [{ open }, setSaladBarState] = useState({ open: false });\n\n // We use a ref instead of a state to store the actual data, because we want\n // queue to be persistent across the whole lifetime of component. I considered\n // using yocto-queue because it would be O(1) instead of O(n), but its not\n // designed to access the head without removing it and its not going to make\n // much difference anyway.\n const queueRef = useRef<Notification[]>([]);\n\n const limitLastHitAt = useRef(Date.now());\n const limitHitCountSinceLastReport = useRef(0);\n\n const setOpen = useCallback((newVal: boolean) => {\n setSaladBarState({ open: newVal });\n }, []);\n\n const enqueueNotification = useCallback((notification: Notification = {}) => {\n limitHitCountSinceLastReport.current += 1;\n if (queueRef.current.length >= MAX_QUEUE_LENGTH) {\n // If the queue length is hit, probably stuck in some sort of loop, so\n // don't want to spam logs instantly so space it out\n if (Date.now() - limitLastHitAt.current >= MAX_QUEUE_HIT_REPORT_INTERVAL) {\n limitLastHitAt.current = Date.now();\n console.error(\n `SaladBarProvider: MAX_QUEUE_LENGTH (${MAX_QUEUE_LENGTH}) hit ${limitHitCountSinceLastReport.current} times in last ${MAX_QUEUE_HIT_REPORT_INTERVAL}ms)`\n );\n limitHitCountSinceLastReport.current = 0;\n }\n }\n\n const newNotification = {\n ...defaultEnqueueNotificationOptions,\n key: generateNotificationKey(), // Can be overridden.\n ...notification, // This could result in collisons, but unlikely.\n };\n\n // Add to the end of queue\n queueRef.current.push(newNotification as Notification);\n\n // If the queue was previously empty, then open the snackbar. We don't do it\n // whenever enqueueNotification is called since it will mess up transitions\n if (queueRef.current.length === 1) setSaladBarState({ open: true });\n\n return newNotification.key;\n }, []);\n\n const enqueueSuccessNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'success', ...options });\n\n const enqueueInfoNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'info', ...options });\n\n const enqueueWarningNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'warning', ...options });\n\n const enqueueErrorNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'error', ...options });\n\n /**\n * Remove the notification with specified key from the queue. If the key is\n * not found, immediately returns null.\n *\n * @param key - The key as returned from enqueue...() function.\n *\n * @returns The removed notification\n */\n const removeNotification = (key: Notification['key']) => {\n const index = queueRef.current.findIndex((x) => x.key === key);\n if (index === -1) return;\n\n if (index === 0) {\n // If its at the front of the queue, it is either currently being\n // displayed or in process of being closed. Either way, we can just set\n // open to false\n setSaladBarState({ open: false });\n return queueRef.current[0];\n }\n // Otherwise we just remove it from the queue, it won't need to transition\n return queueRef.current.splice(index, 1);\n };\n\n const handleClose = (\n event: Event | React.SyntheticEvent<Element, Event>,\n reason: SaladBarCloseReason\n ) => {\n if (shouldClose(event, reason)) setSaladBarState({ open: false });\n };\n\n // Callback fired before the transition is exiting.\n const handleExit = () => {};\n\n // Callback fired when the transition has exited.\n const handleExited = () => {\n // Remove head of queue\n queueRef.current.shift();\n\n // If there is still something on the queue, then re-open\n if (queueRef.current.length > 0) setSaladBarState({ open: true });\n };\n\n // The notification to display is the one at head of queue\n const currentNotification = queueRef.current[0] ?? {\n ...defaultEnqueueNotificationOptions,\n };\n\n // Can also override certain props on a notification level\n const currentNotificationSnackbarProps: { autoHideDuration?: number } = {};\n // Probably a better way of doing this\n if ('autoHideDuration' in currentNotification) {\n currentNotificationSnackbarProps.autoHideDuration = currentNotification.autoHideDuration;\n }\n\n // Note the order of props in Snackbar, we don't allow overriding open and\n // onClose directly.\n const snackbarFinalProps = {\n ...defaultSnackbarProps,\n ...snackbarProps,\n };\n\n const value: SaladBarContext = {\n open,\n setOpen,\n enqueueNotification,\n enqueueSuccessNotification,\n enqueueInfoNotification,\n enqueueWarningNotification,\n enqueueErrorNotification,\n removeNotification,\n ...overrideState,\n ...overrideActions,\n };\n\n return (\n <Context.Provider value={value}>\n {children}\n <Snackbar\n {...snackbarFinalProps}\n {...currentNotificationSnackbarProps}\n open={open}\n onClose={handleClose}\n TransitionProps={{\n onExited: handleExited,\n onExit: handleExit,\n }}\n sx={{ zIndex: SALADBAR_INDEX }}\n >\n <div>\n <Alert\n onClose={(event) => handleClose(event, 'closeAlert')}\n severity={currentNotification.severity}\n variant={'filled'}\n icon={\n currentNotification.progressIndicator === 'circular' ? (\n <CircularProgress size=\"1em\" />\n ) : undefined\n }\n style={\n currentNotification.progressIndicator === 'linear'\n ? alertWithLinearProgressStyle\n : undefined\n }\n >\n {currentNotification.message}\n </Alert>\n {currentNotification.progressIndicator === 'linear' && <LinearProgress color=\"primary\" />}\n </div>\n </Snackbar>\n </Context.Provider>\n );\n}\n","// Superclass for errors involving React context.\nexport class ContextError extends Error {\n static errorName = 'ContextError';\n}\n","import { useContext } from 'react';\n\nimport { ContextError } from '../../errors';\nimport { Context } from './SaladBarContext';\n\n/**\n * Use the `useSaladBar` hook in components to access the enqueueNotification()\n * method to add a snackbar message to queue.\n *\n * Must be used inside a <SaladBarProvider>\n *\n * Example:\n *\n * ```js\n * const {\n * enqueueNotification,\n * enqueueSuccessNotification,\n * enqueueInfoNotification,\n * enqueueWarningNotification,\n * enqueueErrorNotification,\n * } = useSaladBar();\n * ...\n * enqueueNotification({message: 'hello', severity: 'info'});\n * // or\n * enqueueInfoNotification('hello');\n * ```\n */\nexport function useSaladBar() {\n const context = useContext(Context);\n\n if (context === null) {\n throw new ContextError('Error: Tried to useSaladBar outside of a <SaladBarProvider>');\n }\n\n return context;\n}\n","/* eslint-disable react/prop-types */\n/* eslint-disable react/display-name */\nimport { createHelper } from 'souvlaki';\n\nimport SaladBarProvider, { SaladBarProviderProps } from './SaladBarContext';\n\nexport const withSaladBarProvider = createHelper(\n (\n props: SaladBarProviderProps = { autoHideDuration: 1 },\n state: Partial<unknown> = {},\n actions: Partial<unknown> = {}\n ) =>\n ({ children }) => {\n return (\n <SaladBarProvider {...props} overrideState={state} overrideActions={actions}>\n <>{children}</>\n </SaladBarProvider>\n );\n }\n);\n","import { atom } from 'jotai';\nimport { DomainCode } from './DomainCodeDialog';\n\nconst DOMAIN_CODE_KEY = 'domainCode';\n\nconst baseDomainCodeAtom = atom<DomainCode>(\n JSON.parse(localStorage.getItem(DOMAIN_CODE_KEY) ?? '{\"domainCode\": \"\"}').domainCode as DomainCode\n);\n\nexport const domainCodeAtom = atom(\n (get) => get(baseDomainCodeAtom),\n (_, set, newValue: DomainCode) => {\n set(baseDomainCodeAtom, newValue);\n localStorage.setItem(DOMAIN_CODE_KEY, JSON.stringify({ domainCode: newValue }));\n }\n);\n","import {\n Autocomplete,\n CircularProgress,\n FormHelperText,\n TextField,\n Typography,\n} from '@mui/material';\nimport { useAtom } from 'jotai';\nimport { PropsWithChildren, useState } from 'react';\nimport AgDialog from '../components/AgDialog';\nimport { useSaladBar } from '../providers';\nimport { domainCodeAtom } from './hooks';\n\nexport const DOMAIN_CODE_LABELS = {\n act: 'ACT',\n nsw: 'NSW',\n nt: 'NT',\n qld: 'QLD',\n sa: 'SA',\n tas: 'TAS',\n vic: 'VIC',\n wa: 'WA',\n ag: 'AG',\n fedmps: 'FedMPs',\n '': '',\n} as const;\n\nexport type DomainCode = keyof typeof DOMAIN_CODE_LABELS;\n\nexport const getDomainOptionLabel = (domainCode: DomainCode | null) => {\n return domainCode === null ? 'N/A' : (DOMAIN_CODE_LABELS[domainCode] ?? '');\n};\n\ntype Props = PropsWithChildren<{\n isLoading: boolean;\n isOpen: boolean;\n onClose: () => void;\n domainOptions: DomainCode[];\n applicationName: string;\n handleLogout: () => void;\n onDomainChange?: (domainCode: DomainCode) => void;\n}>;\n\nconst DomainCodeDialog = ({\n isLoading,\n isOpen,\n onClose: handleClose,\n onDomainChange,\n domainOptions,\n applicationName,\n handleLogout,\n}: Props) => {\n const [domainCode, setDomainCode] = useAtom(domainCodeAtom);\n const [selectedDomainCode, setSelectedDomainCode] = useState(domainCode);\n const { enqueueSuccessNotification } = useSaladBar();\n\n const userHasNoDomains = domainOptions.length === 0;\n const userHasNoRolesInDomain =\n Boolean(domainCode) &&\n !domainOptions.includes(domainCode) &&\n !domainOptions.includes(selectedDomainCode);\n\n const shouldLogout = !domainCode || userHasNoDomains || userHasNoRolesInDomain;\n\n const handleConfirmDomainCode = async () => {\n if (selectedDomainCode) {\n setDomainCode(selectedDomainCode);\n onDomainChange?.(selectedDomainCode);\n enqueueSuccessNotification(`Set organisation to ${selectedDomainCode}`);\n handleClose();\n } else {\n setDomainCode('');\n onDomainChange?.('');\n }\n };\n\n const handleDialogClose = async () => {\n if (domainCode && !userHasNoDomains && !userHasNoRolesInDomain) {\n setSelectedDomainCode(domainCode);\n handleClose();\n } else if (shouldLogout) {\n handleLogout();\n }\n };\n\n let errorMessage: string | undefined;\n if (userHasNoDomains) {\n errorMessage = 'Unable to retrieve your active organisations. Try logging in again.';\n } else if (userHasNoRolesInDomain) {\n errorMessage =\n 'You no longer have any roles in your chosen organisation. Please choose another.';\n }\n\n return (\n <AgDialog\n isOpen={isOpen}\n dialogTitle=\"Select an organisation\"\n primaryButton={{\n text: 'Confirm',\n onClick: handleConfirmDomainCode,\n disabled: !selectedDomainCode || userHasNoDomains || userHasNoRolesInDomain,\n buttonColor: 'primary',\n }}\n secondaryButton={{\n text: shouldLogout ? 'Logout' : 'Cancel',\n onClick: handleDialogClose,\n }}\n onClose={shouldLogout ? () => {} : handleClose}\n >\n <Typography marginBottom={2}>\n Select the default organisation that you want to use with the {applicationName}.\n </Typography>\n\n <Autocomplete\n loading={isLoading}\n multiple={false}\n disableClearable={false}\n value={selectedDomainCode !== '' ? selectedDomainCode : null}\n onChange={(_, value) => setSelectedDomainCode(value ?? '')}\n getOptionLabel={getDomainOptionLabel}\n options={[...domainOptions.toSorted()]}\n renderInput={(params) => (\n <TextField\n {...params}\n variant=\"filled\"\n label={'Select organisation'}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {isLoading ? (\n <CircularProgress color=\"inherit\" size={20} sx={{ marginTop: '-20px' }} />\n ) : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n />\n )}\n />\n {errorMessage && <FormHelperText error>{errorMessage}</FormHelperText>}\n </AgDialog>\n );\n};\n\nexport default DomainCodeDialog;\n","import { useMediaQuery, useTheme } from '@mui/material';\n\nexport const useSmallScreen = () => {\n const theme = useTheme();\n return useMediaQuery(theme.breakpoints.down('sm'));\n};\n","// export const SIDE_PANEL_DEFAULTS = {\n// titleText: '',\n// flavour: 'push',\n// width: 400,\n// arrowButtons: 'both',\n// startOpen: false,\n// open: undefined,\n// onChangeOpen: undefined,\n// content: <></>,\n// onOpened: undefined,\n// onClosed: undefined,\n// dataTestId: undefined,\n// };\n\n// export const INITIAL_LEFT_PANEL_OPEN = false;\n// export const INITIAL_RIGHT_PANEL_OPEN = false;\n\nexport const DEFAULT_INITIAL_NAV_BAR_OPEN = true;\n\nexport const DEFAULT_TOP_BAR_HEIGHT = 64;\nexport const DEFAULT_NAV_BAR_WIDTH_CLOSED = 72;\nexport const DEFAULT_NAV_BAR_WIDTH_OPEN = 256;\n","import { atom } from 'jotai';\nimport { ReactNode } from 'react';\n\nimport {\n DEFAULT_NAV_BAR_WIDTH_CLOSED,\n DEFAULT_NAV_BAR_WIDTH_OPEN,\n DEFAULT_TOP_BAR_HEIGHT,\n} from './defaults';\n\nexport const navBarOpenAtom = atom(true);\n\nexport const navBarWidthOpenAtom = atom(DEFAULT_NAV_BAR_WIDTH_OPEN);\n\nexport const navBarWidthClosedAtom = atom(DEFAULT_NAV_BAR_WIDTH_CLOSED);\n\nexport const titleTextAtom = atom('');\n\nexport const topBarMiddleAtom = atom<ReactNode>(undefined);\n\nexport const topBarHeightAtom = atom(DEFAULT_TOP_BAR_HEIGHT);\n\n// TODO: Would navBarTop be handled better with a portal?\nexport const navBarTopAtom = atom<ReactNode>(undefined);\n","// import { Link as RouterLink } from 'react-router';\n\nimport { NavBarLink } from './types';\n\nexport interface LinksMenuProps {\n links: NavBarLink[];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function LinksMenu({ links }: LinksMenuProps) {\n return <div>LinksMenu not implemented yet</div>;\n}\n","import { StyledComponent } from '@emotion/styled';\nimport {\n Box,\n BoxProps,\n Collapse,\n CollapseProps,\n Drawer,\n DrawerProps,\n useTheme,\n} from '@mui/material';\nimport { CSSObject, Theme, styled } from '@mui/material/styles';\n\nconst PREFIX = 'Navbar';\n\nexport const classes = {\n root: `${PREFIX}-root`,\n menuButton: `${PREFIX}-menuButton`,\n hide: `${PREFIX}-hide`,\n content: `${PREFIX}-content`,\n // userInfoHolder: `${PREFIX}-userInfoHolder`,\n // settings: `${PREFIX}-settings`,\n // pieChartIcon: `${PREFIX}-pieChartIcon`,\n};\n\n// TODO: Explicit type annotation needed until following issue fixed:\n// https://github.com/microsoft/TypeScript/issues/48212\nexport const Root: StyledComponent<BoxProps> = styled(Box, { name: 'NavBar' })(({ theme }) => ({\n [`&.${classes.root}`]: {\n display: 'flex',\n },\n\n [`& .${classes.menuButton}`]: {\n marginRight: 36,\n },\n\n [`& .${classes.hide}`]: {\n display: 'none',\n },\n\n [`& .${classes.content}`]: {\n flexGrow: 1,\n padding: theme.spacing(3),\n },\n\n // [`& .${classes.userInfoHolder}`]: {\n // height: '148px',\n // marginTop: '64px',\n // marginBottom: '16px',\n // },\n}));\n\nexport const navbarTransition = (\n theme: Theme,\n property: string | string[],\n action: 'entering' | 'leaving'\n) =>\n theme.transitions.create(property, {\n easing: theme.transitions.easing.sharp,\n duration:\n action === 'leaving'\n ? theme.transitions.duration.leavingScreen\n : theme.transitions.duration.enteringScreen,\n });\n\nexport const NavbarCollapse = (props: CollapseProps) => {\n const theme = useTheme();\n return (\n <Collapse\n easing={theme.transitions.easing.sharp}\n timeout={{\n enter: theme.transitions.duration.enteringScreen,\n exit: theme.transitions.duration.leavingScreen,\n }}\n {...props}\n />\n );\n};\n\nconst sharedOverrides = (theme: Theme): CSSObject => ({\n overflowX: 'hidden',\n color: 'inherit',\n backgroundColor: theme?.navBar?.backgroundColor ?? 'white', // Provide default so tests don't need to wrap theme provider\n});\n\nconst openedMixin = (theme: Theme, width: number): CSSObject => ({\n width,\n transition: navbarTransition(theme, 'width', 'entering'),\n ...sharedOverrides(theme),\n});\n\nconst closedMixin = (theme: Theme, width: number): CSSObject => ({\n width,\n transition: navbarTransition(theme, 'width', 'leaving'),\n ...sharedOverrides(theme),\n});\n\ninterface NavDrawerProps {\n open: boolean;\n widthOpen: number;\n widthClosed: number;\n isSmallScreen: boolean;\n}\n\n// TODO: Explicit type annotation needed until following issue fixed:\n// https://github.com/microsoft/TypeScript/issues/48212\n// We also use the second Generic parameter\nexport const NavDrawer: StyledComponent<DrawerProps & NavDrawerProps> = styled(Drawer, {\n shouldForwardProp: (prop) =>\n !['widthOpen', 'widthClosed', 'isSmallScreen'].includes(prop as string),\n})<DrawerProps & NavDrawerProps>(({ theme, open, widthOpen, widthClosed, isSmallScreen }) => ({\n flexShrink: 0,\n whiteSpace: 'nowrap',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n\n ...(open && {\n ...openedMixin(theme, widthOpen),\n backgroundColor: '',\n '& .MuiDrawer-paper': openedMixin(theme, widthOpen),\n }),\n ...(!open && {\n ...closedMixin(theme, isSmallScreen ? widthOpen : widthClosed),\n backgroundColor: '',\n '& .MuiDrawer-paper': closedMixin(theme, isSmallScreen ? widthOpen : widthClosed),\n }),\n}));\n","import { useAuth0 } from '@auth0/auth0-react';\nimport { IdToken } from '@auth0/auth0-spa-js';\nimport { useQuery } from '@tanstack/react-query';\nimport { DomainCode } from 'src/domainCode';\n\nfunction fromKebab(string: string) {\n return string.replace(/(^|-)([a-z])/g, (_, separator, char) =>\n separator === '-' ? ' ' + char.toUpperCase() : char.toUpperCase()\n );\n}\n\nexport function determineUserLevelFromClaims<T extends string>(\n claims: IdToken | undefined,\n domainCode: DomainCode,\n roleMapping: Record<T, string[]>,\n rolePriority: T[]\n) {\n if (!claims) return 'None';\n\n const businessRoleClaimsForDomain = Object.entries(claims).filter(\n ([name, value]) => name.startsWith('https://greens.org.au/roles/') && value.includes(domainCode)\n );\n const roles = businessRoleClaimsForDomain.map(([claimName]) =>\n fromKebab(claimName.split('/').at(-1) ?? '')\n );\n\n return (\n rolePriority.find((userLevel) =>\n roleMapping[userLevel].some((requiredRole) => roles.includes(requiredRole))\n ) ?? 'None'\n );\n}\n\nexport const useValidDomains = (appValidBusinessRoles: string[]) => {\n const { getIdTokenClaims, user } = useAuth0();\n return useQuery({\n queryKey: ['availableDomains', user?.sub],\n queryFn: async (): Promise<DomainCode[]> => {\n const claims = await getIdTokenClaims();\n\n if (!claims) return [];\n\n return Object.entries(claims).reduce((prev, [name, value]) => {\n const roleName = fromKebab(name.split('/').at(-1) ?? '');\n const domains =\n name.startsWith('https://greens.org.au/roles/') &&\n appValidBusinessRoles.includes(roleName)\n ? value\n : [];\n return [...new Set([...prev, ...domains])];\n }, [] as DomainCode[]);\n },\n });\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const getValidBusinessRoles = (roleMapping: Record<any, string[]>) =>\n Object.values(roleMapping).reduce(\n (prev, curr) => [...new Set([...prev, ...curr])],\n [] as string[]\n );\n","type SuppressionFilter = RegExp | ((...data: unknown[]) => boolean);\n\ntype ConsoleFn = 'log' | 'error' | 'warn' | 'info' | 'debug';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst origConsoleFns: Record<ConsoleFn, any> = {\n log: console.warn.bind(console),\n error: console.error.bind(console),\n warn: console.warn.bind(console),\n info: console.info.bind(console),\n debug: console.debug.bind(console),\n};\n\n/**\n * If called, will replace the underlying console function with a wrapper that\n * will prevent the original from being called if a filter matches. A filter can\n * either be a regex or a function that returns true on a match.\n *\n * Motivation: Originally implemented to provide a way to suppress the harmless\n * MUI warnings generated by SingleAutocomplete component\n */\nexport function suppressConsole(fn: ConsoleFn, filters: SuppressionFilter[]) {\n console[fn] = (...data: unknown[]) => {\n // If filtered, skip output\n for (const filter of filters) {\n if (typeof filter === 'function') {\n if (filter(...data)) return;\n } else if (filter instanceof RegExp && data.length > 0) {\n for (const str of data) {\n if (typeof str === 'string' && filter.test(str)) {\n return;\n }\n }\n }\n }\n // Otherwise call original console function\n origConsoleFns[fn](data);\n };\n}\n\n/**\n * Reset console[fn] to original. If fn is not specified, resets all functions\n * (log, error, warn, info, debug)\n *\n * NOTE: Unsure if this will work in most cases\n */\nexport function unsuppressConsole(fn?: ConsoleFn) {\n if (fn) {\n console[fn] = origConsoleFns[fn];\n } else {\n for (const f of Object.keys(origConsoleFns) as ConsoleFn[]) {\n console[f] = origConsoleFns[f];\n }\n }\n}\n","// https://stackoverflow.com/a/8831937\nexport function simpleHashCode(str: string) {\n let hash = 0;\n for (let i = 0, len = str.length; i < len; i++) {\n const chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n}\n","import { Box, Fade, Avatar as OtherAvatar, Skeleton, Typography, useTheme } from '@mui/material';\nimport Avatar from 'react-avatar';\nimport { DomainCode, getDomainOptionLabel } from '../../../domainCode';\nimport { simpleHashCode } from '../../../utils';\nimport { NavbarCollapse, navbarTransition } from './Styling';\nimport { User } from './types';\n\n// These all have good contrast against our typical navbar background colour\nconst avatarColours = ['#A62A21', '#7e3794', '#0B51C1', '#3A6024', '#A81563', '#B3003C'];\n\nconst extractInitials = (name: string) =>\n name\n .split(/\\s/)\n .map((part) => part.substring(0, 1).toUpperCase())\n .filter((v) => !!v)\n .slice(0, 2)\n .join('')\n .toUpperCase();\n\nexport interface UserInfoProps {\n user?: User;\n domainCode?: DomainCode;\n open: boolean;\n useNewAvatar?: boolean;\n}\n\n/**\n * If user has a defined name and a valid url for picture, the picture will for\n * the avatar image.\n *\n * If there is a defined name but the picture is invalid or undefined, the\n * intials will be used to generate the avatar image. The colour will be random\n * for different names, but always the same for the same name.\n *\n * If user is undefined or the name is undefined, a generic empty avatar image\n * will be displayed.\n *\n *\n */\n\nexport default function UserInfo({ user, domainCode, open, useNewAvatar = false }: UserInfoProps) {\n const theme = useTheme();\n return (\n <Box\n sx={{\n paddingTop: 3,\n display: 'flex',\n alignItems: 'center',\n flexDirection: 'column',\n gap: '0.5rem',\n }}\n >\n {!useNewAvatar && (\n <Box\n sx={{\n width: open ? '5rem' : '2rem',\n transition: open\n ? navbarTransition(theme, ['width', 'height'], 'entering')\n : navbarTransition(theme, ['width', 'height'], 'leaving'),\n aspectRatio: 1,\n }}\n >\n {user?.name ? (\n <>\n <OtherAvatar\n src={user?.picture}\n sx={{\n width: '100%',\n height: '100%',\n bgcolor:\n avatarColours[Math.abs(simpleHashCode(user?.name)) % avatarColours.length],\n }}\n >\n {extractInitials(user?.name)}\n </OtherAvatar>\n </>\n ) : (\n <OtherAvatar sx={{ width: '100%', height: '100%' }} />\n )}\n </Box>\n )}\n {useNewAvatar && (\n <Box\n sx={{\n width: open ? '5rem' : '2rem',\n transition: open\n ? navbarTransition(theme, ['width', 'height'], 'entering')\n : navbarTransition(theme, ['width', 'height'], 'leaving'),\n aspectRatio: 1,\n }}\n >\n {user?.name ? (\n <>\n <Avatar src={user?.picture} name={user?.name} round={true} size={open ? '80' : '32'}>\n {' '}\n {extractInitials(user?.name)} {'ab'}\n </Avatar>\n </>\n ) : (\n <Avatar />\n )}\n </Box>\n )}\n\n <NavbarCollapse sx={{ width: '100%' }} in={open}>\n <Fade in={open}>\n <Box width=\"100%\" display=\"flex\" flexDirection=\"column\" alignItems=\"center\">\n {user?.name ? (\n <Typography>{user?.name}</Typography>\n ) : (\n <Skeleton animation={false} width={'50%'} />\n )}\n {domainCode ? (\n <Typography>{getDomainOptionLabel(domainCode)}</Typography>\n ) : (\n <Skeleton animation={false} width={'25%'} />\n )}\n </Box>\n </Fade>\n </NavbarCollapse>\n </Box>\n );\n}\n","import { Box, Divider, Toolbar } from '@mui/material';\nimport { ReactNode } from 'react';\n\nimport { useSetAtom } from 'jotai';\nimport { DomainCode } from '../../../domainCode';\nimport { useSmallScreen } from '../mobile';\nimport { navBarOpenAtom } from '../stateAtoms';\nimport { LinksMenu } from './LinksMenu';\nimport { NavDrawer, Root, classes } from './Styling';\nimport UserInfo from './UserInfo';\nimport { NavBarLink, User } from './types';\n\nexport interface NavBarProps {\n open: boolean;\n\n offsetTop?: number;\n\n widthOpen: number;\n\n widthClosed: number;\n\n /** Set the datatest-id on the root element for using reactdom's getByTestId()\n * function */\n 'data-testid'?: string;\n\n /** The contents to be displayed at the top, intended to be specific to the\n * current page */\n top?: ReactNode;\n\n /**\n * Display be below the top section, intended to always be the same,\n * regardless of the current route. Can be provided either as a node directly,\n * or an array of objects that will be used to generate a standard navbar menu.\n *\n * @example\n *\n * ```\n * // As a ReactNode\n * <NavBar open: {open} middle={<TheContent}/>\n * ```\n *\n * @example\n *\n * ```\n * // As an Array\n * <NavBar open: {open} middle={[\n * {label: 'foo', destPathname: '/foo', icon: {FooIcon}},\n * {label: 'bar', destPathname: '/bar', icon: {BarIcon}},\n * ]}/>\n * ```\n */\n middle: ReactNode | NavBarLink[];\n\n /** User information displayed at bottom of navabar when it is open*/\n user?: User;\n\n /** Displayed below the user information when available */\n domainCode?: DomainCode;\n\n /**\n * The contents to be displayed at the bottom, intended to always be the\n * same, regardless of current route.\n */\n bottom?: ReactNode;\n\n /* The NavBar can use the old Avatar code, or the new Avatar code. */\n\n useNewAvatar?: boolean;\n}\n\n/**\n * A styled navigation bar. At this point in time its pretty unopinionated, it\n * just renders whatever children it is given. The NavBarLightStyledList\n * component can be used for consistent styling against the background.\n */\nexport default function NavBar({\n open,\n widthClosed,\n widthOpen,\n 'data-testid': dataTestId,\n top,\n middle,\n bottom,\n user,\n domainCode,\n useNewAvatar = false,\n}: NavBarProps) {\n const isSmallScreen = useSmallScreen();\n const setNavBarOpen = useSetAtom(navBarOpenAtom);\n\n return (\n <Root className={classes.root} data-testid={dataTestId}>\n <NavDrawer\n open={open}\n widthOpen={widthOpen}\n widthClosed={widthClosed}\n anchor=\"left\"\n variant={!isSmallScreen ? 'permanent' : 'temporary'}\n PaperProps={{\n component: 'nav',\n }}\n onClose={() => {\n setNavBarOpen(false);\n }}\n isSmallScreen={isSmallScreen}\n >\n {!isSmallScreen && <Toolbar />}\n {top && (\n <Box flexGrow=\"0\">\n {top}\n <Divider variant=\"middle\" sx={{ marginY: '0.5rem' }} />\n </Box>\n )}\n\n <Box flexGrow=\"1\">\n {/* middle is either a ReactNode or an array of NavBarLink objects */}\n {Array.isArray(middle) ? <LinksMenu links={middle as unknown as NavBarLink[]} /> : middle}\n </Box>\n\n <Box flexGrow=\"0\">\n <Divider variant=\"middle\" sx={{ marginY: '0.5rem' }} />\n <UserInfo user={user} domainCode={domainCode} open={open} useNewAvatar={useNewAvatar} />\n\n {bottom && <>{bottom}</>}\n </Box>\n </NavDrawer>\n </Root>\n );\n}\n","import { Box, Container, ContainerProps } from '@mui/material';\nimport { PropsWithChildren } from 'react';\n\n// const NavBarAwareMargins = styled('div', {\n// shouldForwardProp: (prop) => !(['leftPanel', 'rightPanel'] as Array<PropertyKey>).includes(prop),\n// name: 'PanelAwareMargins',\n// })<PanelAwareMarginsProps>(({ theme, leftPanel, rightPanel }) => ({\n// transition: theme.transitions.create('margin', {\n// easing: theme.transitions.easing.sharp,\n// duration: theme.transitions.duration.leavingScreen,\n// }),\n\n// ...(leftPanel?.open && {\n// transition: theme.transitions.create('margin', {\n// easing: theme.transitions.easing.easeOut,\n// duration: theme.transitions.duration.enteringScreen,\n// }),\n// marginLeft: `${leftPanel?.width ?? 0}px`,\n// }),\n// ...(rightPanel?.open && {\n// transition: theme.transitions.create('margin', {\n// easing: theme.transitions.easing.easeOut,\n// duration: theme.transitions.duration.enteringScreen,\n// }),\n// marginRight: `${rightPanel?.width ?? 0}px`,\n// }),\n// }));\n\ninterface PageContainerProps {\n topBarHeight: number;\n\n /** Passed to underlying Container. False be default.*/\n maxWidth?: ContainerProps['maxWidth'];\n noPadding?: boolean;\n}\n\n/**\n * An MUI Container component wrapped in a Box whose height adapts to the\n * topBarHeight and has a stable scrollbar gutter.\n */\nfunction PageContainer({\n children,\n topBarHeight,\n maxWidth = false,\n noPadding,\n}: PropsWithChildren<PageContainerProps>) {\n return (\n <Box\n sx={{\n overflow: 'auto',\n height: `calc(100vh - ${topBarHeight}px)`,\n flexGrow: 1,\n }}\n >\n {noPadding ? (\n <Box component=\"main\" id=\"main-content\" height=\"inherit\">\n {children}\n </Box>\n ) : (\n <Container\n component=\"main\"\n id=\"main-content\"\n maxWidth={maxWidth}\n sx={{ paddingTop: 3, paddingBottom: 3, flexGrow: 1 }}\n >\n {children}\n </Container>\n )}\n </Box>\n );\n}\n\nexport default PageContainer;\n","import { ViewHeadline as HamburgerIcon } from '@mui/icons-material';\nimport { IconButton, Paper, Typography, useTheme } from '@mui/material';\n\nimport { useSetAtom } from 'jotai';\nimport { ReactNode } from 'react';\nimport { useSmallScreen } from './mobile';\nimport { navBarOpenAtom } from './stateAtoms';\n\nconst PREFIX = 'TopBar';\n\nexport interface TopBarProps {\n titleText?: string;\n\n /**\n * The contents to be displayed to the right of the titleText, left aligned to\n * the starting position of the navbar. There is no right content, so at the\n * moment it fills up the remaining space\n */\n middle?: ReactNode;\n\n height: number;\n 'data-testid'?: string;\n}\n\nexport const classes = {\n titleText: `${PREFIX}-titleText`,\n};\n\n/**\n * Top bar of every page, above the content. Works a bit like MUI's AppBar but\n * the scroll bar will not appear for the whole page, instead just the page\n * content\n */\nexport default function TopBar({\n titleText = '',\n height,\n 'data-testid': dataTestId,\n middle,\n}: TopBarProps) {\n const setNavBarOpen = useSetAtom(navBarOpenAtom);\n\n const toggleNavBar = () => setNavBarOpen((prevVal) => !prevVal);\n const theme = useTheme();\n const isSmallScreen = useSmallScreen();\n return (\n <header data-testid={dataTestId}>\n <Paper\n square\n elevation={0}\n sx={{\n width: '100%',\n position: 'sticky',\n color: 'primary.contrastText',\n backgroundColor: 'primary.main',\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n flexShrink: 0,\n height,\n zIndex: isSmallScreen ? 0 : theme.zIndex.drawer + 99,\n }}\n >\n <IconButton\n size=\"medium\"\n color=\"inherit\"\n sx={{ padding: 1.5, marginLeft: '12px' }}\n onClick={toggleNavBar}\n >\n <HamburgerIcon fontSize=\"medium\" />\n </IconButton>\n <Typography className={classes.titleText} variant=\"h6\" component=\"h1\">\n {titleText}\n </Typography>\n\n {middle}\n </Paper>\n </header>\n );\n}\n","import CssBaseline from '@mui/material/CssBaseline';\nimport { ComponentProps, PropsWithChildren } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { useAtom, useAtomValue } from 'jotai';\nimport { useHydrateAtoms } from 'jotai/utils';\nimport NavBar, { NavBarProps } from './NavBar';\nimport PageContainer from './PageContainer';\nimport TopBar from './TopBar';\nimport {\n navBarOpenAtom,\n navBarTopAtom,\n navBarWidthClosedAtom,\n navBarWidthOpenAtom,\n titleTextAtom,\n topBarHeightAtom,\n topBarMiddleAtom,\n} from './stateAtoms';\n\nexport interface BaseAppLayoutProps {\n /** Either an array of objects used to automatically generate the content of\n * the navbar (WIP), or a node to render directly.*/\n navBarMiddle: NavBarProps['middle'];\n\n /** A node to render directly.*/\n navBarBottom: NavBarProps['bottom'];\n\n /**\n * The initial titleText. Shortcut for calling a setter from useAppLayout()\n * hook since its such a common action.\n */\n initialTitleText?: string;\n\n /**\n * The initial open state of the navbar, which is true by default. Shortcut\n * for calling a setter from useAppLayout() hook since its such a common\n * action.\n */\n initialNavBarOpen?: boolean;\n\n /** Props applied to the PageContainer component, which is a styled MUI\n * Container */\n pageContainerProps?: ComponentProps<typeof PageContainer>;\n\n /** Passed directly as prop of TopBar component */\n topBarDataTestId?: string;\n\n /** Passed directly as prop of PageContainer component */\n pageContentDataTestId?: string;\n\n /** Passed down as prop to the root element of the NavBar component */\n navBarDataTestId?: string;\n\n /** Used to display user name and provided picture as avatar or one generated\n * from unitials of the name */\n user?: NavBarProps['user'];\n\n /** Display under the user's name */\n domainCode?: NavBarProps['domainCode'];\n\n //** Do we use the old avatar code or the new one? */\n useNewAvatar?: boolean;\n}\n\ntype AppLayoutProps = PropsWithChildren<BaseAppLayoutProps>;\n\nexport default function AppLayout({\n children,\n initialTitleText,\n initialNavBarOpen,\n pageContainerProps,\n pageContentDataTestId,\n topBarDataTestId,\n navBarDataTestId,\n navBarMiddle,\n navBarBottom,\n user,\n domainCode,\n useNewAvatar = false,\n}: AppLayoutProps) {\n useHydrateAtoms([\n [navBarOpenAtom, initialNavBarOpen ?? true],\n [titleTextAtom, initialTitleText ?? ''],\n ]);\n const navBarOpen = useAtomValue(navBarOpenAtom);\n const [navBarWidthOpen] = useAtom(navBarWidthOpenAtom);\n const [navBarWidthClosed] = useAtom(navBarWidthClosedAtom);\n const titleText = useAtomValue(titleTextAtom);\n const [topBarHeight] = useAtom(topBarHeightAtom);\n const [topBarMiddle] = useAtom(topBarMiddleAtom);\n const [navBarTop] = useAtom(navBarTopAtom);\n\n return (\n <Box>\n <CssBaseline />\n <TopBar\n titleText={titleText}\n data-testid={topBarDataTestId}\n height={topBarHeight}\n middle={topBarMiddle}\n />\n\n <Box sx={{ display: 'flex' }}>\n <NavBar\n open={navBarOpen}\n top={navBarTop}\n middle={navBarMiddle}\n bottom={navBarBottom}\n user={user}\n domainCode={domainCode}\n widthOpen={navBarWidthOpen}\n widthClosed={navBarWidthClosed}\n offsetTop={topBarHeight}\n data-testid={navBarDataTestId}\n useNewAvatar={useNewAvatar}\n />\n\n <PageContainer\n data-testid={pageContentDataTestId}\n topBarHeight={topBarHeight}\n {...pageContainerProps}\n >\n {children}\n </PageContainer>\n </Box>\n </Box>\n );\n}\n","import { createTheme } from '@mui/material/styles';\n\nconst theme = createTheme({\n palette: {\n primary: {\n dark: '#00A651',\n light: '#A3D39C',\n main: '#007236',\n contrastText: '#FFF',\n },\n warning: {\n main: '#F5871F',\n light: '#FCC589',\n dark: '#A2590A',\n contrastText: '#FFF',\n },\n secondary: {\n main: '#662D91',\n light: '#BD8CBF',\n dark: '#440E62',\n contrastText: '#FFF',\n },\n error: {\n main: '#D43C95',\n light: '#8F2064',\n dark: '#F9CDE0',\n contrastText: '#FFF',\n },\n info: {\n main: '#00A88D',\n light: '#ADDCCF',\n dark: '#005243',\n contrastText: '#FFF',\n },\n success: {\n main: '#00A651',\n light: '#A3D39C',\n dark: '#007236',\n contrastText: '#FFF',\n },\n },\n typography: {\n // I couldn't think of what to call this. It is an attempt to match\n // https://www.figma.com/file/atonRPl2YD9A1NCntbDtKR/List-Filter-and-Product-Concept?node-id=1187%3A43730\n // but not sure if line height should be changed\n explainer: {\n fontSize: '14px',\n marginBlockStart: '1em',\n },\n },\n\n navBar: {\n backgroundColor: '#E8E8E8',\n },\n});\n\nexport default theme;\n","import { alpha, createTheme } from '@mui/material/styles';\n\nconst theme = createTheme({\n palette: {\n primary: {\n main: '#007236',\n dark: '#005221',\n light: '#00A04E',\n contrastText: '#FFFFFF',\n },\n secondary: {\n main: '#662D91',\n dark: '#440E62',\n light: '#93268F',\n contrastText: '#FFFFFF',\n },\n error: {\n main: '#D32F2F',\n dark: '#C62828',\n light: '#EF5350',\n },\n info: {\n main: '#0288D1',\n dark: '#01579B',\n light: '#03A9F4',\n },\n success: {\n main: '#0288D1',\n dark: '#01579B',\n light: '#03A9F4',\n },\n },\n components: {\n MuiTextField: {\n defaultProps: { color: 'secondary' },\n },\n MuiToggleButtonGroup: {\n defaultProps: { color: 'secondary' },\n },\n MuiCheckbox: {\n defaultProps: { color: 'secondary' },\n },\n MuiSelect: {\n defaultProps: { color: 'secondary' },\n },\n MuiSwitch: {\n defaultProps: { color: 'secondary' },\n },\n MuiFormControl: {\n defaultProps: { color: 'secondary' },\n },\n MuiMenuItem: {\n // Setting defaultProps for color on MenuItem does not work, so update manually\n styleOverrides: {\n root: ({ theme: origTheme }) => ({\n '&.Mui-selected': {\n backgroundColor: alpha(\n origTheme.palette.secondary.main,\n origTheme.palette.action.selectedOpacity\n ),\n '&:hover': {\n backgroundColor: alpha(\n origTheme.palette.secondary.main,\n origTheme.palette.action.selectedOpacity\n ),\n },\n '&.Mui-focusVisible': {\n backgroundColor: alpha(\n origTheme.palette.secondary.main,\n origTheme.palette.action.focusOpacity\n ),\n },\n },\n }),\n },\n },\n },\n typography: {\n h4: {\n fontSize: '1.88rem',\n fontWeight: 500,\n },\n h5: {\n fontWeight: 500,\n },\n // I couldn't think of what to call this. It is an attempt to match\n // https://www.figma.com/file/atonRPl2YD9A1NCntbDtKR/List-Filter-and-Product-Concept?node-id=1187%3A43730\n // but not sure if line height should be changed\n explainer: {\n fontSize: '14px',\n marginBlockStart: '1em',\n },\n },\n navBar: {\n backgroundColor: '#E8E8E8',\n },\n});\n\nexport default theme;\n"],"names":["ExampleComponent","text","num","setNum","useState","jsxs","Fragment","jsx","Typography","Button","oldNum","Paper","AgDialog","isOpen","dialogTitle","children","maxWidth","primaryButton","secondaryButton","additionalButtons","handleClose","sx","dataTestId","disableCloseOnBackdropOrEscape","isLoading","areButtonsDisabled","setButtonsDisabled","Dialog","_event","reason","__async","LinearProgress","DialogTitle","DialogContent","DialogActions","_a","buttonConfig","idx","DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS","MOUSE_EVENT_BUTTONS","useAutocompleteOptions","minLength","preLoadedOptions","lookup","label","inputValue","useQuery","option","FetchAutocomplete","enableHighlighting","onChange","onInputChange","value","boxSx","textFieldColor","textFieldVariant","textFieldFocused","textFieldSx","loadingText","noOptionsText","popupIcon","DefaultPopupIcon","error","helperText","disablePortal","disableIconFlip","chipToolTipSlotProps","placeholderText","onRightClick","disableDefaultRightClickBehaviour","readOnly","hideInputEndAdornment","setInputValue","handleDelete","e","deleteValue","newInternalValue","x","options","isInputMinimumLength","Autocomplete","__spreadValues","event","newValue","newInputValue","params","TextField","__spreadProps","CircularProgress","v","props","state","matches","match","parts","parse","createElement","part","index","Box","val","Chip","Tooltip","CancelIcon","MUI_AUTOCOMPLETE_VALUE_WARNING_REGEX","SingleAutocomplete","disabled","Stack","getAuth0Expiry","token","base64","jsonPayload","Buffer","c","jsonParsedPayload","SessionExpiryDialog","open","closeHandler","setAuth0ExpiryTime","logout","getAccessTokenSilently","useAuth0","handleDialogClose","successButtonConfig","tokenSecond","tokenExp","cancelButtonConfig","isOAuthError","errorFromApplicationAccessRejection","errorObject","errorDescription","errorFromUserNotAuthorisingApp","errorFromScriptExecutionTimeout","AuthGuard","appName","throwErrors","disableConsoleLogging","onError","isAuthenticated","loginWithRedirect","useEffect","useMemo","title","message","redirectCount","_b","Skeleton","defaultSnackbarProps","defaultSaladBarProps","defaultEnqueueNotificationOptions","MAX_QUEUE_LENGTH","MAX_QUEUE_HIT_REPORT_INTERVAL","SALADBAR_INDEX","generateNotificationKey","previousKey","alertWithLinearProgressStyle","defaultOverrideState","defaultOverrideActions","Context","createContext","SaladBarProvider","overrideState","overrideActions","shouldClose","snackbarProps","__objRest","setSaladBarState","queueRef","useRef","limitLastHitAt","limitHitCountSinceLastReport","setOpen","useCallback","newVal","enqueueNotification","notification","newNotification","enqueueSuccessNotification","enqueueInfoNotification","enqueueWarningNotification","enqueueErrorNotification","removeNotification","key","handleExit","handleExited","currentNotification","currentNotificationSnackbarProps","snackbarFinalProps","Snackbar","Alert","ContextError","__publicField","useSaladBar","context","useContext","withSaladBarProvider","createHelper","actions","DOMAIN_CODE_KEY","baseDomainCodeAtom","atom","domainCodeAtom","get","_","set","DOMAIN_CODE_LABELS","getDomainOptionLabel","domainCode","DomainCodeDialog","onDomainChange","domainOptions","applicationName","handleLogout","setDomainCode","useAtom","selectedDomainCode","setSelectedDomainCode","userHasNoDomains","userHasNoRolesInDomain","shouldLogout","handleConfirmDomainCode","errorMessage","FormHelperText","useSmallScreen","theme","useTheme","useMediaQuery","DEFAULT_TOP_BAR_HEIGHT","DEFAULT_NAV_BAR_WIDTH_CLOSED","DEFAULT_NAV_BAR_WIDTH_OPEN","navBarOpenAtom","navBarWidthOpenAtom","navBarWidthClosedAtom","titleTextAtom","topBarMiddleAtom","topBarHeightAtom","navBarTopAtom","LinksMenu","links","PREFIX","classes","Root","styled","navbarTransition","property","action","NavbarCollapse","Collapse","sharedOverrides","openedMixin","width","closedMixin","NavDrawer","Drawer","prop","widthOpen","widthClosed","isSmallScreen","fromKebab","string","separator","char","determineUserLevelFromClaims","claims","roleMapping","rolePriority","roles","name","claimName","userLevel","requiredRole","useValidDomains","appValidBusinessRoles","getIdTokenClaims","user","prev","roleName","domains","getValidBusinessRoles","curr","origConsoleFns","suppressConsole","fn","filters","data","filter","str","unsuppressConsole","f","simpleHashCode","hash","i","len","chr","avatarColours","extractInitials","UserInfo","useNewAvatar","OtherAvatar","Avatar","Fade","NavBar","top","middle","bottom","setNavBarOpen","useSetAtom","Toolbar","Divider","PageContainer","topBarHeight","noPadding","Container","TopBar","titleText","height","toggleNavBar","prevVal","IconButton","HamburgerIcon","AppLayout","initialTitleText","initialNavBarOpen","pageContainerProps","pageContentDataTestId","topBarDataTestId","navBarDataTestId","navBarMiddle","navBarBottom","useHydrateAtoms","navBarOpen","useAtomValue","navBarWidthOpen","navBarWidthClosed","topBarMiddle","navBarTop","CssBaseline","createTheme","origTheme","alpha"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/components/ExampleComponent/ExampleComponent.tsx","../../src/components/AgDialog/AgDialog.tsx","../../src/components/FetchAutocomplete/const.ts","../../src/components/FetchAutocomplete/FetchAutocomplete.tsx","../../src/components/SingleAutocomplete/index.tsx","../../src/components/SessionExpiryDialog/index.tsx","../../src/components/AuthGuard/auth0ErrorParsing.ts","../../src/components/AuthGuard/AuthGuard.tsx","../../src/providers/SaladBar/defaults.ts","../../src/providers/SaladBar/SaladBarContext.tsx","../../src/errors/ContextError.ts","../../src/providers/SaladBar/useSaladBar.ts","../../src/providers/SaladBar/testWrappers.tsx","../../src/domainCode/hooks.tsx","../../src/domainCode/DomainCodeDialog.tsx","../../src/layouts/AppLayout/mobile.ts","../../src/layouts/AppLayout/defaults.tsx","../../src/layouts/AppLayout/stateAtoms.ts","../../src/layouts/AppLayout/NavBar/LinksMenu.tsx","../../src/layouts/AppLayout/NavBar/Styling.tsx","../../src/utils/auth.ts","../../src/utils/consoleSuppression.ts","../../src/utils/sentryBeforeSend.ts","../../src/utils/simpleHashCode.ts","../../src/layouts/AppLayout/NavBar/UserInfo.tsx","../../src/layouts/AppLayout/NavBar/NavBar.tsx","../../src/layouts/AppLayout/PageContainer.tsx","../../src/layouts/AppLayout/TopBar.tsx","../../src/layouts/AppLayout/AppLayout.tsx","../../src/themes/fed21Theme.ts","../../src/themes/internalAgSystemsTheme.ts"],"sourcesContent":["import { useState } from 'react';\nimport { Button, Paper, Typography } from '@mui/material';\n\nexport interface ExampleComponentProps {\n /** Test */\n text: string;\n}\n\nexport default function ExampleComponent({ text }: ExampleComponentProps) {\n const [num, setNum] = useState(0);\n\n return (\n <>\n <Typography variant=\"h6\" color=\"inherit\" component=\"div\" sx={{ fontSize: '22px' }}>\n Hello world\n </Typography>\n\n <Typography variant=\"caption\" display=\"block\">\n <span>Just ensuring MUI is working as planned as a peer dependency. v0.0.11</span>\n </Typography>\n <Button\n variant=\"outlined\"\n onClick={() => setNum((oldNum) => oldNum + 1)}\n aria-label=\"Increment\"\n >\n Hello I am a button\n </Button>\n <p>\n This is some text: <span>{text}</span>\n </p>\n <Paper>This number will incremember when button pressed: {num}</Paper>\n </>\n );\n}\n","import {\n Breakpoint,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n LinearProgress,\n SxProps,\n Theme,\n} from '@mui/material';\nimport { PropsWithChildren, ReactElement, useState } from 'react';\n\nexport type AgDialogButtonConfig = {\n text: string;\n onClick?: () => Promise<void>;\n disabled?: boolean;\n testId?: string;\n buttonColor?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning';\n};\n\nexport type AgDialogProps = PropsWithChildren<{\n isOpen: boolean;\n dialogTitle: string | ReactElement;\n maxWidth?: false | Breakpoint;\n primaryButton?: AgDialogButtonConfig;\n secondaryButton?: AgDialogButtonConfig;\n additionalButtons?: AgDialogButtonConfig[];\n 'data-testid'?: string;\n onClose: () => void;\n sx?: SxProps<Theme>;\n disableCloseOnBackdropOrEscape?: boolean;\n isLoading?: boolean;\n}>;\n\n/**\n * Standard dialog that will auto disable it's buttons while the primaryButton onClick function is pending.\n *\n */\nconst AgDialog = ({\n isOpen,\n dialogTitle,\n children,\n maxWidth,\n primaryButton,\n secondaryButton,\n additionalButtons,\n onClose: handleClose,\n sx,\n 'data-testid': dataTestId,\n disableCloseOnBackdropOrEscape = false,\n isLoading = false,\n}: AgDialogProps) => {\n const [areButtonsDisabled, setButtonsDisabled] = useState(false);\n\n return (\n <Dialog\n open={isOpen}\n onClose={async (_event, reason) => {\n if (\n disableCloseOnBackdropOrEscape &&\n (reason === 'backdropClick' || reason === 'escapeKeyDown')\n ) {\n return;\n }\n if (areButtonsDisabled) return;\n if (secondaryButton?.onClick) {\n await secondaryButton.onClick();\n } else {\n handleClose();\n }\n }}\n fullWidth\n maxWidth={maxWidth ?? 'xs'}\n data-testid={dataTestId}\n sx={sx}\n >\n {isLoading && <LinearProgress sx={{ height: '4px', marginBottom: '-4px' }} />}\n <DialogTitle>{dialogTitle}</DialogTitle>\n <DialogContent sx={{ '& > :last-child': { marginBottom: 0 } }}>{children}</DialogContent>\n <DialogActions>\n <Button\n onClick={secondaryButton?.onClick ?? handleClose}\n data-testid={secondaryButton?.testId}\n disabled={secondaryButton?.disabled || areButtonsDisabled}\n color={secondaryButton?.buttonColor}\n >\n {secondaryButton?.text ?? 'Cancel'}\n </Button>\n {additionalButtons &&\n additionalButtons.map((buttonConfig, idx) => {\n return (\n <Button\n key={idx}\n onClick={buttonConfig?.onClick}\n data-testid={buttonConfig?.testId}\n disabled={buttonConfig?.disabled || areButtonsDisabled}\n color={buttonConfig?.buttonColor}\n >\n {buttonConfig.text ?? `Button ${idx}`}\n </Button>\n );\n })}\n {primaryButton && (\n <Button\n onClick={async () => {\n setButtonsDisabled(true);\n await primaryButton.onClick?.();\n setButtonsDisabled(false);\n }}\n data-testid={primaryButton.testId}\n disabled={primaryButton.disabled || areButtonsDisabled}\n color={primaryButton?.buttonColor}\n >\n {primaryButton.text}\n </Button>\n )}\n </DialogActions>\n </Dialog>\n );\n};\n\nexport default AgDialog;\n","export const DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS = {\n popper: {\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [115, -15],\n },\n },\n ],\n },\n};\n\nexport const MOUSE_EVENT_BUTTONS = {\n left: 0,\n middle: 1,\n right: 2,\n};\n","import { Cancel as CancelIcon, ArrowDropDown as DefaultPopupIcon } from '@mui/icons-material';\nimport {\n Autocomplete,\n Box,\n Chip,\n CircularProgress,\n SxProps,\n TextField,\n Theme,\n Tooltip,\n TooltipProps,\n Typography,\n} from '@mui/material';\nimport { useQuery } from '@tanstack/react-query';\nimport match from 'autosuggest-highlight/match';\nimport parse from 'autosuggest-highlight/parse';\nimport { ReactNode, SyntheticEvent, useState } from 'react';\n\nimport {\n AutocompleteGenericEntity,\n AutocompleteGenericEntityIdType,\n FetchAutocompleteChangeReason,\n} from '../types';\nimport { DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS, MOUSE_EVENT_BUTTONS } from './const';\n\nexport const useAutocompleteOptions = <EntityType extends AutocompleteGenericEntity>({\n minLength,\n preLoadedOptions,\n lookup,\n label,\n inputValue,\n}: {\n minLength: number;\n preLoadedOptions: EntityType[] | undefined;\n lookup: (lookupValue: string) => Promise<EntityType[] | undefined | null | void>;\n label: string;\n inputValue: string;\n}) => {\n return useQuery({\n queryFn: () => {\n if (minLength && inputValue.length < minLength) return preLoadedOptions ?? [];\n if (preLoadedOptions)\n return preLoadedOptions.filter((option) =>\n option.label.toLowerCase().includes(inputValue.toLowerCase())\n );\n return lookup(inputValue);\n },\n queryKey: ['autocomplete', label, inputValue],\n });\n};\n\nexport type FetchAutocompleteProps<EntityType extends AutocompleteGenericEntity> = {\n /**\n * Callback fired when the value changes. This is passed directly to the\n * underlying Autocomplete, but it is triggered by the Autocomplete's own\n * onChange, with the exception of the deletion of chips.\n */\n onChange: (\n newValue: EntityType[],\n reason: FetchAutocompleteChangeReason,\n event: SyntheticEvent<Element, Event>\n ) => unknown;\n\n /** Generally only useful for testing */\n onInputChange?: (\n newValue: EntityType[] | null,\n reason: string,\n event: SyntheticEvent<Element, Event>\n ) => void;\n\n /** The sequence of entity types returned. */\n value: EntityType[];\n\n /**\n * A minimum length of characters in the Autocomplete before the lookup is called. If not set,\n * then the lookup is called every time.\n */\n minLength?: number;\n\n /** A nice label for the autocomplete. */\n label: string;\n\n /** The lookup function, for looking up EntityType options from a remote resource. */\n lookup?: (lookupValue: string) => Promise<EntityType[] | undefined | null | void>;\n\n /** If you have your EntityType options at hand, preload them instead, and save the\n * user's time. They should all be available when the user clicks on the drop down\n * menu, without even a single keystroke provided. This is the property you want.\n */\n preLoadedOptions?: EntityType[] | undefined;\n\n /** The popup icon */\n popupIcon?: ReactNode;\n\n /**If true, the Popper content will be under the DOM hierarchy of the parent\n * component. Passed directly to underlying MUI Autocomplete component.*/\n disablePortal?: boolean;\n\n /**\n * Used for the data-testid value of the outer most component. The underlying\n * AutoComplete component has the id of this, followed by a colon then\n * 'AutoComplete', while the text field is followed by 'TextField'.\n *\n * Currently has no default to avoid collisions. May change in future to\n * simply be 'FetchAutocomplete' if that is not an issue.\n */\n 'data-testid'?: string;\n\n loadingText?: string;\n noOptionsText?: string;\n error?: boolean;\n helperText?: ReactNode;\n enableHighlighting?: boolean;\n sx?: SxProps<Theme>;\n\n textFieldColor?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';\n textFieldVariant?: 'filled' | 'outlined' | 'standard';\n textFieldFocused?: boolean;\n textFieldSx?: SxProps<Theme>;\n\n boxSx?: SxProps<Theme>;\n disableIconFlip?: boolean;\n chipToolTipSlotProps?: TooltipProps['slotProps'];\n\n placeholderText?: string;\n\n /**\n * Called when a right click is detected.\n */\n onRightClick?: (event: React.MouseEvent) => void;\n\n /**\n * If set to true, the default right click behaviour will be overridden: the\n * dropdown/prompt will not appear AND neither will the browser context menu.\n *\n * Use in combination with onRightClick to override the behaviour.\n *\n * Note: This can't just be done by passing through onRightClick having it\n * prevent the event default, because there are two events that need to be\n * listened for.\n */\n disableDefaultRightClickBehaviour?: boolean;\n\n readOnly?: boolean;\n\n hideInputEndAdornment?: boolean;\n};\n\n/**\n * A wrapper around MUI's Autocomplete component, specifically for use with live\n * as-you-type fetching from an api and styled the way we want it across the app\n * by default.\n */\nexport default function FetchAutocomplete<EntityType extends AutocompleteGenericEntity>({\n lookup = async () => {},\n enableHighlighting = true,\n onChange,\n onInputChange,\n minLength = 0,\n label,\n value,\n 'data-testid': dataTestId,\n sx,\n boxSx,\n textFieldColor,\n textFieldVariant = 'filled',\n textFieldFocused,\n textFieldSx,\n loadingText = 'Loading...',\n noOptionsText = 'No options',\n popupIcon = <DefaultPopupIcon />,\n error = false,\n helperText = '',\n preLoadedOptions = undefined,\n disablePortal = false,\n disableIconFlip = false,\n chipToolTipSlotProps = DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS,\n placeholderText = undefined,\n onRightClick = () => {},\n disableDefaultRightClickBehaviour = false,\n readOnly,\n hideInputEndAdornment,\n}: FetchAutocompleteProps<EntityType>) {\n const [inputValue, setInputValue] = useState('');\n\n const handleDelete = (\n e: SyntheticEvent<Element, Event>,\n deleteValue: AutocompleteGenericEntityIdType\n ) => {\n const newInternalValue = value.filter((x) => x.id !== deleteValue);\n onChange(newInternalValue, 'delete', e);\n };\n\n const { data: options, isLoading } = useAutocompleteOptions({\n inputValue,\n label,\n lookup,\n minLength,\n preLoadedOptions,\n });\n\n const isInputMinimumLength = inputValue.length >= minLength;\n\n return (\n <div data-testid={dataTestId}>\n <Autocomplete\n sx={{\n ...sx,\n ...(disableIconFlip\n ? { '.MuiAutocomplete-popupIndicatorOpen': { transform: 'rotate(0deg)' } }\n : {}),\n }}\n data-testid={dataTestId ? `${dataTestId}:Autocomplete` : undefined}\n disablePortal={disablePortal}\n multiple\n getOptionLabel={(option) => (typeof option === 'string' ? option : option.label)}\n loading={isInputMinimumLength ? isLoading : false}\n // See https://github.com/mui/material-ui/issues/18514\n // TODO: Is this still relevant?\n options={[...value, ...(options ?? [])]}\n // However we hide the selected ones from the dropdown, since most of\n // the time they won't contain what the user typed next\n filterSelectedOptions\n // autoComplete// This doesn't work at time of writing https://github.com/mui-org/material-ui/issues/22648\n includeInputInList\n value={value}\n onChange={(event, newValue, reason) => {\n onChange(newValue as EntityType[], reason, event);\n }}\n onInputChange={(event, newInputValue, reason) => {\n setInputValue(newInputValue);\n if (onInputChange) onInputChange(value, reason, event);\n }}\n noOptionsText={isInputMinimumLength ? noOptionsText : 'Start typing to search'}\n loadingText={loadingText}\n popupIcon={popupIcon}\n renderInput={(params) => (\n <TextField\n {...params}\n label={label}\n fullWidth\n variant={textFieldVariant}\n error={error}\n helperText={helperText}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: hideInputEndAdornment ? undefined : (\n <>\n {isLoading ? <CircularProgress color=\"inherit\" size={20} /> : null}\n {params.InputProps.endAdornment}\n </>\n ),\n },\n }}\n data-testid={dataTestId ? `${dataTestId}:Autocomplete:TextField` : undefined}\n onKeyDown={(event: React.KeyboardEvent) => {\n if (event.key === 'Backspace' || event.key === 'Delete') {\n event.stopPropagation();\n }\n }}\n color={textFieldColor}\n placeholder={placeholderText}\n sx={textFieldSx}\n focused={textFieldFocused}\n />\n )}\n // We render tags/chips below the component\n renderValue={() => null}\n isOptionEqualToValue={(option, v) => option.id === v.id}\n renderOption={(props, option, state) => {\n if (enableHighlighting) {\n const matches = match(option.label, state.inputValue, {\n insideWords: true,\n findAllOccurrences: true,\n });\n const parts = parse(option.label, matches);\n\n return (\n <li\n {...props}\n key={option.id}\n data-testid={\n dataTestId\n ? `${dataTestId}:Autocomplete:option(${option.id.toString()})`\n : undefined\n }\n >\n <div>\n {parts.map((part, index) => (\n <span\n key={index}\n style={{\n fontWeight: part.highlight ? 700 : 400,\n }}\n >\n {part.text}\n </span>\n ))}\n </div>\n </li>\n );\n } else {\n return (\n <li\n {...props}\n key={option.id}\n data-testid={\n dataTestId ? `${dataTestId}:option(${option.id.toString()})` : undefined\n }\n >\n {option.label}\n </li>\n );\n }\n }}\n onMouseDownCapture={(event) => {\n if (event.button === MOUSE_EVENT_BUTTONS.right && disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n }}\n onContextMenuCapture={(event) => {\n if (disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n onRightClick(event);\n }}\n readOnly={readOnly}\n />\n {value.length > 0 && (\n <Box sx={boxSx}>\n {value.map((val) => {\n return (\n <Chip\n key={val.id}\n sx={{\n marginTop: 1,\n marginRight: 1,\n height: 'auto',\n }}\n label={\n <Tooltip\n title={val.tooltipContent ?? ''}\n placement=\"bottom-start\"\n slotProps={chipToolTipSlotProps}\n >\n <Typography style={{ whiteSpace: 'normal' }}>\n {val.chipLabel ? val.chipLabel : val.label}\n </Typography>\n </Tooltip>\n }\n data-testid={dataTestId ? `${dataTestId}:Chip(${val.id.toString()})` : undefined}\n onDelete={(e) => handleDelete(e, val.id)}\n deleteIcon={\n <CancelIcon\n data-testid={\n dataTestId ? `${dataTestId}:Chip(${val.id.toString()}):deleteIcon` : undefined\n }\n />\n }\n />\n );\n })}\n </Box>\n )}\n </div>\n );\n}\n","import {\n Autocomplete,\n AutocompleteChangeReason,\n CircularProgress,\n Stack,\n SxProps,\n TextField,\n Theme,\n} from '@mui/material';\nimport { ReactNode, SyntheticEvent, useState } from 'react';\nimport { useAutocompleteOptions } from '../FetchAutocomplete';\nimport { MOUSE_EVENT_BUTTONS } from '../FetchAutocomplete/const';\nimport { AutocompleteGenericEntity } from '../types';\n\n/**\n * MUI Autocomplete has a harmless warning when the available options do not\n * include the old selected value of the auto complete (its skipped in\n * production). This regex can be used as as suppressConsole('warn',\n * MUI_AUTOCOMPLETE_VALUE_WARNING_REGEX) to avoid it in development\n * environments.\n */\nexport const MUI_AUTOCOMPLETE_VALUE_WARNING_REGEX = /MUI: The value provided to.*is invalid/i;\n\nexport type SingleAutocompleteProps<EntityType extends AutocompleteGenericEntity> = {\n /**\n * Callback fired when the value changes. reason is one of \"createOption\",\n * \"selectOption\", \"removeOption\", \"blur\" or \"clear\". This is passed directly\n * to the underlying Autocomplete, but it is triggered by the Autocomplete's\n * own onChange.\n */\n onChange: (\n event: SyntheticEvent<Element, Event>,\n newValue: EntityType | null,\n reason: AutocompleteChangeReason\n ) => unknown;\n\n /** Generally only useful for testing */\n onInputChange?: (\n newValue: string | null,\n reason: string,\n event: SyntheticEvent<Element, Event>\n ) => void;\n\n value: EntityType | null;\n\n /**\n * A minimum length of characters in the Autocomplete before the lookup is called. If not set,\n * then the lookup is called every time.\n */\n minLength?: number;\n\n /** A nice label for the autocomplete. */\n label: string;\n\n /** The lookup function, for looking up EntityType options from a remote resource. */\n lookup?: (lookupValue: string) => Promise<EntityType[] | undefined | null | void>;\n\n preLoadedOptions?: EntityType[] | undefined;\n\n /**If true, the Popper content will be under the DOM hierarchy of the parent\n * component. Passed directly to underlying MUI Autocomplete component.*/\n disablePortal?: boolean;\n\n /**\n * Used for the data-testid value of the outer most component. The underlying\n * AutoComplete component has the id of this, followed by a colon then\n * 'AutoComplete', while the text field is followed by 'TextField'.\n *\n * Currently has no default to avoid collisions. May change in future to\n * simply be 'FetchAutocomplete' if that is not an issue.\n */\n 'data-testid'?: string;\n\n hideButton?: boolean;\n loadingText?: string;\n noOptionsText?: string;\n sx?: SxProps<Theme>;\n textFieldColor?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';\n textFieldVariant?: 'filled' | 'outlined' | 'standard';\n textFieldFocused?: boolean;\n textFieldSx?: SxProps<Theme>;\n error?: boolean;\n helperText?: ReactNode;\n disabled?: boolean;\n popupIcon?: ReactNode;\n disableIconFlip?: boolean;\n\n placeholderText?: string;\n\n /**\n * Called when a right click is detected.\n */\n onRightClick?: (event: React.MouseEvent) => void;\n\n /**\n * If set to true, the default right click behaviour will be overridden: the\n * dropdown/prompt will not appear AND neither will the browser context menu.\n *\n * Use in combination with onRightClick to override the behaviour.\n *\n * Note: This can't just be done by passing through onRightClick having it\n * prevent the event default, because there are two events that need to be\n * listened for.\n */\n disableDefaultRightClickBehaviour?: boolean;\n\n readOnly?: boolean;\n\n hideInputEndAdornment?: boolean;\n};\n\nconst SingleAutocomplete = <EntityType extends AutocompleteGenericEntity>({\n lookup = async () => {},\n onChange,\n onInputChange,\n label,\n value,\n sx,\n textFieldColor,\n textFieldVariant = 'filled',\n textFieldFocused,\n textFieldSx,\n error = false,\n 'data-testid': dataTestId,\n loadingText = 'Loading...',\n noOptionsText = 'No options',\n minLength = 3,\n disablePortal = false,\n preLoadedOptions,\n helperText = '',\n disabled,\n popupIcon,\n disableIconFlip,\n placeholderText = undefined,\n onRightClick = () => {},\n disableDefaultRightClickBehaviour = false,\n readOnly,\n hideInputEndAdornment,\n}: SingleAutocompleteProps<EntityType>) => {\n const [inputValue, setInputValue] = useState('');\n\n const { data: options, isLoading } = useAutocompleteOptions({\n inputValue,\n label,\n lookup,\n minLength: minLength ?? 0,\n preLoadedOptions,\n });\n\n const isInputMinimumLength = inputValue.length >= minLength;\n\n return (\n <div data-testid={dataTestId}>\n <Stack\n direction=\"row\"\n spacing={1}\n onMouseDownCapture={(event) => {\n if (event.button === MOUSE_EVENT_BUTTONS.right) {\n if (disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n }}\n onContextMenuCapture={(event) => {\n if (disableDefaultRightClickBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n onRightClick(event);\n }}\n >\n <Autocomplete\n sx={{\n ...sx,\n ...(disableIconFlip\n ? { '.MuiAutocomplete-popupIndicatorOpen': { transform: 'rotate(0deg)' } }\n : {}),\n }}\n data-testid={dataTestId ? `${dataTestId}:Autocomplete` : undefined}\n loading={isInputMinimumLength ? isLoading : false}\n options={options ?? []}\n onChange={(event, newValue, reason) => {\n onChange(event, newValue, reason);\n }}\n disablePortal={disablePortal}\n filterOptions={(option) => option}\n value={value}\n noOptionsText={isInputMinimumLength ? noOptionsText : 'Start typing to search'}\n loadingText={loadingText}\n getOptionLabel={(option) => option.label}\n popupIcon={popupIcon}\n renderInput={(params) => (\n <TextField\n data-testid={dataTestId ? `${dataTestId}:Autocomplete:TextField` : undefined}\n {...params}\n variant={textFieldVariant}\n label={label}\n color={textFieldColor}\n error={error}\n helperText={helperText}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: hideInputEndAdornment ? undefined : (\n <>\n {isLoading ? <CircularProgress color=\"inherit\" size={20} /> : null}\n {params.InputProps.endAdornment}\n </>\n ),\n },\n }}\n placeholder={placeholderText}\n sx={textFieldSx}\n focused={textFieldFocused}\n />\n )}\n isOptionEqualToValue={(option, v) => option.id === v.id}\n onInputChange={(event, newInputValue, reason) => {\n setInputValue(newInputValue);\n if (onInputChange) onInputChange(newInputValue, reason, event);\n }}\n renderOption={(props, option) => (\n <li\n {...props}\n key={option.id}\n data-testid={\n dataTestId\n ? `${dataTestId}:Autocomplete:option(${option.id.toString()})`\n : undefined\n }\n >\n {option.label}\n </li>\n )}\n disabled={disabled}\n readOnly={readOnly}\n />\n </Stack>\n </div>\n );\n};\n\nexport default SingleAutocomplete;\n","import { useAuth0 } from '@auth0/auth0-react';\nimport { Buffer } from 'buffer';\n\nimport AgDialog, { AgDialogButtonConfig } from '../AgDialog';\n\n// This gets the auth0 expiry value for a token. If the token cannot be\n// parsed, then -1 is returned.\n//\n// The following code is from here (but has been updated to go from atob\n// to Buffer.from).\n//\n// https://stackoverflow.com/questions/38552003/how-to-decode-jwt-token-in-javascript-without-using-a-library#38552302\n//\n// Note: for confusion, the exp value is in seconds after the epoch:\n// NumericDate\n// A JSON numeric value representing the number of seconds from\n// 1970-01-01T00:00:00Z UTC until the specified UTC date/time,\n// ignoring leap seconds. This is equivalent to the IEEE Std 1003.1,\n// 2013 Edition [POSIX.1] definition \"Seconds Since the Epoch\", in\n// which each day is accounted for by exactly 86400 seconds, other\n// than that non-integer values can be represented. See RFC 3339\n// [RFC3339] for details regarding date/times in general and UTC in\n// particular.\n// https://www.rfc-editor.org/rfc/rfc7519#section-2\n// To use with Date, multiply with 1000.\n\n// A lot of the libraries that we expect in node are not available out\n// of the box with vite, like Buffer. This is why we need to import it\n// seperately. See:\n// https://stackoverflow.com/questions/70714690/buffer-is-not-defined-in-react-vite\n\nexport const getAuth0Expiry = (token: string) => {\n if (!token) {\n return -1;\n }\n try {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n Buffer.from(base64, 'base64')\n .toString('utf8')\n .split('')\n .map(function (c) {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join('')\n );\n const jsonParsedPayload = JSON.parse(jsonPayload);\n if (jsonParsedPayload?.exp) {\n return jsonParsedPayload.exp as number;\n }\n return -1;\n } catch {\n return -1;\n }\n};\n\nexport type SessionExpiryDialogProps = {\n open: boolean;\n closeHandler: () => void;\n setAuth0ExpiryTime: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst SessionExpiryDialog = ({\n open = false,\n closeHandler,\n setAuth0ExpiryTime,\n}: SessionExpiryDialogProps) => {\n const { logout, getAccessTokenSilently } = useAuth0();\n\n const handleDialogClose = async () => {\n logout({ logoutParams: { returnTo: `${window.location.origin}` } });\n };\n\n const handleDialogSuccess = async () => {\n const tokenSecond = await getAccessTokenSilently({ cacheMode: 'off' });\n const tokenExp = getAuth0Expiry(tokenSecond) * 1000;\n setAuth0ExpiryTime(tokenExp);\n closeHandler();\n };\n\n const successButtonConfig = {\n text: 'Continue',\n onClick: handleDialogSuccess,\n disabled: false,\n testId: 'PreferencesDialog',\n buttonColor: 'secondary',\n } as AgDialogButtonConfig;\n\n const cancelButtonConfig = {\n text: 'Log out',\n onClick: handleDialogClose,\n disabled: false,\n testId: 'PreferencesDialog',\n buttonColor: 'secondary',\n } as AgDialogButtonConfig;\n\n return (\n <AgDialog\n isOpen={open}\n primaryButton={successButtonConfig}\n secondaryButton={cancelButtonConfig}\n onClose={closeHandler}\n dialogTitle={'Session expiry'}\n disableCloseOnBackdropOrEscape\n >\n <p style={{ marginBottom: 0 }}>\n Your session is about to time out due to inactivity. Do you want to continue?\n </p>\n </AgDialog>\n );\n};\n\nexport default SessionExpiryDialog;\n","import { OAuthError } from '@auth0/auth0-react';\n\n/**\n * instanceof OAuthError doesn't work in for whatever useAuth0 hook returns, so\n * we use duck typing guard. There are other specified properties too, but only error\n * seems to be guaranteed\n */\nexport function isOAuthError(error: Error): error is OAuthError {\n return 'error' in error;\n}\n\n/**\n * Will only return true if the error looks like it was caused by our custom\n * Application-Access and Role-Based-Application-Access actions in the login\n * flow of auth0 tenant. See README.md for detail\n */\nexport function errorFromApplicationAccessRejection(errorObject: OAuthError) {\n const error = errorObject.error;\n const errorDescription = errorObject?.error_description ?? '';\n\n return (\n error === 'access_denied' &&\n errorDescription.startsWith('You do not have the required authorization')\n );\n}\n\n/**\n * Will only return true if the error looks like it was caused by a user not\n * granting the application access to their profile in the tenant when asked on\n * first login.\n */\nexport function errorFromUserNotAuthorisingApp(errorObject: OAuthError) {\n const error = errorObject.error;\n const errorDescription = errorObject?.error_description ?? '';\n\n return (\n error === 'access_denied' && errorDescription.startsWith('User did not authorize the request')\n );\n}\n\n/**\n * Will only return true if the error looks like it was due to script execution\n * time issue. Specifically, the execution of custom actions in the login flow\n * exceeded the time limit (20s at time of writing). Mostly likely issues\n * syncing user data with AG internal systems.\n */\nexport function errorFromScriptExecutionTimeout(errorObject: OAuthError) {\n const error = errorObject.error;\n const errorDescription = errorObject?.error_description ?? '';\n\n return error === 'access_denied' && errorDescription.match(/Script.*time.*exceeded/);\n}\n","import { AppState, RedirectLoginOptions, useAuth0 } from '@auth0/auth0-react';\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Typography,\n} from '@mui/material';\nimport Skeleton from '@mui/material/Skeleton';\nimport { PropsWithChildren, useEffect, useMemo } from 'react';\n\nimport {\n errorFromApplicationAccessRejection,\n errorFromScriptExecutionTimeout,\n errorFromUserNotAuthorisingApp,\n isOAuthError,\n} from './auth0ErrorParsing';\n\nexport interface AuthGuardProps {\n appName?: string;\n\n /** Defaults to 'unknown'. If set to 'all', will always re-throw the error, so\n * won't display the normal message to user and be handled elsewhere in the\n * app. If set to 'unknown', this will only be done if the failure reason\n * couldn't be inferred from the error description etc or if its a completely\n * unknown error without a description etc.*/\n throwErrors?: 'none' | 'unknown' | 'all';\n\n /** Called in case of an authentication error, regardless of if its recognised\n * or not */\n onError?: (error: Error) => void;\n\n disableConsoleLogging?: boolean;\n}\n\n/**\n * Use as parent of main app (but within Auth0Provider) so when an anonymous\n * user visits the will be redirected to the login page and returned to the page\n * they we're redirected from after login.\n *\n * This is similar to the withAuthenticationRequired HOC from Auth0, which\n * operates on a per-route basis.\n *\n * This component is also responsible for detecting an an authorisation error\n * that is triggered by one of our rules defined for our Auth0 tenant\n *\n * Do not use this if any routes need to be accessible to anonymous users.\n */\nexport default function AuthGuard({\n children,\n appName = 'the app',\n throwErrors = 'none',\n disableConsoleLogging = false,\n onError = () => {},\n}: PropsWithChildren<AuthGuardProps>) {\n const { isAuthenticated, isLoading, error, loginWithRedirect, logout } = useAuth0();\n\n // Wrapped in a useEffect to avoid re-renders doubling it up\n useEffect(() => {\n // The no-pass-data-to-parent rule doesn't apply in this case since we are\n // deliberately converting the first occurrence of an error into an event so\n // the parent can act on it\n // eslint-disable-next-line react-you-might-not-need-an-effect/no-pass-data-to-parent\n if (error) onError(error);\n }, [error, onError]);\n\n const options: RedirectLoginOptions<AppState> = useMemo(\n () => ({\n appState: {\n returnTo: `${window.location.pathname}${window.location.search}`,\n },\n }),\n []\n );\n useEffect(() => {\n if (isLoading || isAuthenticated || error) return;\n\n loginWithRedirect(options);\n }, [isLoading, isAuthenticated, error, loginWithRedirect, onError, options]);\n\n if (error) {\n if (!disableConsoleLogging) {\n console.error(\n `Error detected in AuthGuard [isAuthenticated=${isAuthenticated},isLoading=${isLoading}]`,\n error\n );\n }\n\n if (throwErrors === 'all') {\n throw error;\n } else if (isOAuthError(error)) {\n let title = 'Auth error';\n let message = 'An unknown Auth0 error occurred.';\n\n if (errorFromApplicationAccessRejection(error)) {\n title = 'Unauthorised';\n message = `You are not authorised to access ${appName}.`;\n } else if (errorFromUserNotAuthorisingApp(error)) {\n title = 'App not authorised';\n message = `You have not authorised ${appName} to access your user profile. This is necessary to use ${appName}.`;\n } else if (errorFromScriptExecutionTimeout(error)) {\n title = 'Auth0 script execution time exceeded';\n message = `The Auth0 login flow exceeded the time limit (20s). Try again in a minute by clicking the RELOAD button below.`;\n } else if (error.message === 'Invalid state') {\n const redirectCount = localStorage.getItem('auth0_redirect_count');\n if (!redirectCount) {\n localStorage.setItem('auth0_redirect_count', '1');\n loginWithRedirect(options);\n } else if (redirectCount && parseInt(redirectCount) < 2) {\n localStorage.setItem('auth0_redirect_count', String(parseInt(redirectCount) + 1));\n loginWithRedirect(options);\n }\n } else {\n if (throwErrors === 'unknown') throw error;\n }\n\n return (\n <Dialog open>\n <DialogTitle>{title}</DialogTitle>\n <DialogContent>\n <Typography>{message}</Typography>\n <br />\n <Typography variant=\"subtitle2\">Details from Auth0</Typography>\n <Typography variant=\"body2\">error: {error?.error ?? 'N/A'}</Typography>\n <Typography variant=\"body2\">\n description: {error?.error_description ?? 'N/A'}\n </Typography>\n </DialogContent>\n <DialogActions>\n {title === 'Auth0 script execution time exceeded' && (\n <Button href={window.location.origin + window.location.pathname}>Reload</Button>\n )}\n <Button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>\n Logout\n </Button>\n </DialogActions>\n </Dialog>\n );\n } else {\n if (throwErrors === 'unknown') throw error;\n }\n }\n\n if (isAuthenticated) {\n localStorage.removeItem('auth0_redirect_count');\n return <>{children}</>;\n }\n\n return <Skeleton variant=\"rectangular\" animation=\"pulse\" height=\"100vh\" width=\"100vw\" />;\n}\n","// The default props passed to the underlying Snackbar component\nimport { SnackbarOrigin } from '@mui/material/Snackbar';\n\nexport const defaultSnackbarProps = {\n autoHideDuration: 6000,\n anchorOrigin: { vertical: 'top', horizontal: 'center' } as SnackbarOrigin,\n\n // The default is false. If we prefer timer to continue when window loses\n // focus, change to true\n disableWindowBlurListener: false,\n};\n\nexport const defaultSaladBarProps = {\n shouldClose: (_event: Event | React.SyntheticEvent<Element, Event>, reason: string) => {\n return reason !== 'clickaway';\n },\n};\n\nexport const defaultEnqueueNotificationOptions = {\n message: '',\n severity: 'info',\n variant: 'standard',\n progressIndicator: undefined, // Can use 'circular' or 'linear'\n};\n","import React, { useRef, useState, createContext, useCallback } from 'react';\nimport { Alert, LinearProgress, CircularProgress, Snackbar, SnackbarProps } from '@mui/material';\n\nimport {\n Notification,\n SaladBarCloseReason,\n SaladBarState,\n SaladBarActions,\n SaladBarContext,\n} from './types';\nimport {\n defaultSaladBarProps,\n defaultSnackbarProps,\n defaultEnqueueNotificationOptions,\n} from './defaults';\n\nconst MAX_QUEUE_LENGTH = 100;\nconst MAX_QUEUE_HIT_REPORT_INTERVAL = 2000;\nconst SALADBAR_INDEX = 2000;\n\n// No need to use uuids, just use an incremented value\nconst generateNotificationKey = (() => {\n let previousKey = 0;\n return () => {\n previousKey += 1;\n return previousKey;\n };\n})();\n\nconst alertWithLinearProgressStyle = {\n borderBottomLeftRadius: '0px',\n borderBottomRightRadius: '0px',\n};\n\n// Note: Must be at at this scope, otherwise useEffect will loop infinitely\nconst defaultOverrideState = {};\nconst defaultOverrideActions = {};\n\nexport const Context = createContext<SaladBarContext | null>(null);\n\nexport interface SaladBarProviderProps extends SnackbarProps {\n /** Allow overriding the state of the SaladBar (for tests etc)*/\n overrideState?: Partial<SaladBarState>;\n\n /** Allow overriding the actions of the SaladBar (for tests etc)*/\n overrideActions?: Partial<SaladBarActions>;\n\n /** Called when an event triggers closing of currently displayed snackbar.\n * Default implementation returns false if reason is 'clickaway', otherwise\n * true.*/\n shouldClose?: (\n event: Event | React.SyntheticEvent<Element, Event>,\n reason: SaladBarCloseReason\n ) => boolean;\n}\n\nexport default function SaladBarProvider({\n overrideState = defaultOverrideState,\n overrideActions = defaultOverrideActions,\n shouldClose = defaultSaladBarProps.shouldClose,\n children,\n ...snackbarProps\n}: SaladBarProviderProps) {\n const [{ open }, setSaladBarState] = useState({ open: false });\n\n // We use a ref instead of a state to store the actual data, because we want\n // queue to be persistent across the whole lifetime of component. I considered\n // using yocto-queue because it would be O(1) instead of O(n), but its not\n // designed to access the head without removing it and its not going to make\n // much difference anyway.\n const queueRef = useRef<Notification[]>([]);\n\n const limitLastHitAt = useRef(Date.now());\n const limitHitCountSinceLastReport = useRef(0);\n\n const setOpen = useCallback((newVal: boolean) => {\n setSaladBarState({ open: newVal });\n }, []);\n\n const enqueueNotification = useCallback((notification: Notification = {}) => {\n limitHitCountSinceLastReport.current += 1;\n if (queueRef.current.length >= MAX_QUEUE_LENGTH) {\n // If the queue length is hit, probably stuck in some sort of loop, so\n // don't want to spam logs instantly so space it out\n if (Date.now() - limitLastHitAt.current >= MAX_QUEUE_HIT_REPORT_INTERVAL) {\n limitLastHitAt.current = Date.now();\n console.error(\n `SaladBarProvider: MAX_QUEUE_LENGTH (${MAX_QUEUE_LENGTH}) hit ${limitHitCountSinceLastReport.current} times in last ${MAX_QUEUE_HIT_REPORT_INTERVAL}ms)`\n );\n limitHitCountSinceLastReport.current = 0;\n }\n }\n\n const newNotification = {\n ...defaultEnqueueNotificationOptions,\n key: generateNotificationKey(), // Can be overridden.\n ...notification, // This could result in collisons, but unlikely.\n };\n\n // Add to the end of queue\n queueRef.current.push(newNotification as Notification);\n\n // If the queue was previously empty, then open the snackbar. We don't do it\n // whenever enqueueNotification is called since it will mess up transitions\n if (queueRef.current.length === 1) setSaladBarState({ open: true });\n\n return newNotification.key;\n }, []);\n\n const enqueueSuccessNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'success', ...options });\n\n const enqueueInfoNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'info', ...options });\n\n const enqueueWarningNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'warning', ...options });\n\n const enqueueErrorNotification = (message = '', options = {}) =>\n enqueueNotification({ message, severity: 'error', ...options });\n\n /**\n * Remove the notification with specified key from the queue. If the key is\n * not found, immediately returns null.\n *\n * @param key - The key as returned from enqueue...() function.\n *\n * @returns The removed notification\n */\n const removeNotification = (key: Notification['key']) => {\n const index = queueRef.current.findIndex((x) => x.key === key);\n if (index === -1) return;\n\n if (index === 0) {\n // If its at the front of the queue, it is either currently being\n // displayed or in process of being closed. Either way, we can just set\n // open to false\n setSaladBarState({ open: false });\n return queueRef.current[0];\n }\n // Otherwise we just remove it from the queue, it won't need to transition\n return queueRef.current.splice(index, 1);\n };\n\n const handleClose = (\n event: Event | React.SyntheticEvent<Element, Event>,\n reason: SaladBarCloseReason\n ) => {\n if (shouldClose(event, reason)) setSaladBarState({ open: false });\n };\n\n // Callback fired before the transition is exiting.\n const handleExit = () => {};\n\n // Callback fired when the transition has exited.\n const handleExited = () => {\n // Remove head of queue\n queueRef.current.shift();\n\n // If there is still something on the queue, then re-open\n if (queueRef.current.length > 0) setSaladBarState({ open: true });\n };\n\n // The notification to display is the one at head of queue\n const currentNotification = queueRef.current[0] ?? {\n ...defaultEnqueueNotificationOptions,\n };\n\n // Can also override certain props on a notification level\n const currentNotificationSnackbarProps: { autoHideDuration?: number } = {};\n // Probably a better way of doing this\n if ('autoHideDuration' in currentNotification) {\n currentNotificationSnackbarProps.autoHideDuration = currentNotification.autoHideDuration;\n }\n\n // Note the order of props in Snackbar, we don't allow overriding open and\n // onClose directly.\n const snackbarFinalProps = {\n ...defaultSnackbarProps,\n ...snackbarProps,\n };\n\n const value: SaladBarContext = {\n open,\n setOpen,\n enqueueNotification,\n enqueueSuccessNotification,\n enqueueInfoNotification,\n enqueueWarningNotification,\n enqueueErrorNotification,\n removeNotification,\n ...overrideState,\n ...overrideActions,\n };\n\n return (\n <Context.Provider value={value}>\n {children}\n <Snackbar\n {...snackbarFinalProps}\n {...currentNotificationSnackbarProps}\n open={open}\n onClose={handleClose}\n TransitionProps={{\n onExited: handleExited,\n onExit: handleExit,\n }}\n sx={{ zIndex: SALADBAR_INDEX }}\n >\n <div>\n <Alert\n onClose={(event) => handleClose(event, 'closeAlert')}\n severity={currentNotification.severity}\n variant={'filled'}\n icon={\n currentNotification.progressIndicator === 'circular' ? (\n <CircularProgress size=\"1em\" />\n ) : undefined\n }\n style={\n currentNotification.progressIndicator === 'linear'\n ? alertWithLinearProgressStyle\n : undefined\n }\n >\n {currentNotification.message}\n </Alert>\n {currentNotification.progressIndicator === 'linear' && <LinearProgress color=\"primary\" />}\n </div>\n </Snackbar>\n </Context.Provider>\n );\n}\n","// Superclass for errors involving React context.\nexport class ContextError extends Error {\n static errorName = 'ContextError';\n}\n","import { useContext } from 'react';\n\nimport { ContextError } from '../../errors';\nimport { Context } from './SaladBarContext';\n\n/**\n * Use the `useSaladBar` hook in components to access the enqueueNotification()\n * method to add a snackbar message to queue.\n *\n * Must be used inside a <SaladBarProvider>\n *\n * Example:\n *\n * ```js\n * const {\n * enqueueNotification,\n * enqueueSuccessNotification,\n * enqueueInfoNotification,\n * enqueueWarningNotification,\n * enqueueErrorNotification,\n * } = useSaladBar();\n * ...\n * enqueueNotification({message: 'hello', severity: 'info'});\n * // or\n * enqueueInfoNotification('hello');\n * ```\n */\nexport function useSaladBar() {\n const context = useContext(Context);\n\n if (context === null) {\n throw new ContextError('Error: Tried to useSaladBar outside of a <SaladBarProvider>');\n }\n\n return context;\n}\n","/* eslint-disable react/prop-types */\n/* eslint-disable react/display-name */\nimport { createHelper } from 'souvlaki';\n\nimport SaladBarProvider, { SaladBarProviderProps } from './SaladBarContext';\n\nexport const withSaladBarProvider = createHelper(\n (\n props: SaladBarProviderProps = { autoHideDuration: 1 },\n state: Partial<unknown> = {},\n actions: Partial<unknown> = {}\n ) =>\n ({ children }) => {\n return (\n <SaladBarProvider {...props} overrideState={state} overrideActions={actions}>\n <>{children}</>\n </SaladBarProvider>\n );\n }\n);\n","import { atom } from 'jotai';\nimport { DomainCode } from './DomainCodeDialog';\n\nconst DOMAIN_CODE_KEY = 'domainCode';\n\nconst baseDomainCodeAtom = atom<DomainCode>(\n JSON.parse(localStorage.getItem(DOMAIN_CODE_KEY) ?? '{\"domainCode\": \"\"}').domainCode as DomainCode\n);\n\nexport const domainCodeAtom = atom(\n (get) => get(baseDomainCodeAtom),\n (_, set, newValue: DomainCode) => {\n set(baseDomainCodeAtom, newValue);\n localStorage.setItem(DOMAIN_CODE_KEY, JSON.stringify({ domainCode: newValue }));\n }\n);\n","import {\n Autocomplete,\n CircularProgress,\n FormHelperText,\n TextField,\n Typography,\n} from '@mui/material';\nimport { useAtom } from 'jotai';\nimport { PropsWithChildren, useState } from 'react';\nimport AgDialog from '../components/AgDialog';\nimport { useSaladBar } from '../providers';\nimport { domainCodeAtom } from './hooks';\n\nexport const DOMAIN_CODE_LABELS = {\n act: 'ACT',\n nsw: 'NSW',\n nt: 'NT',\n qld: 'QLD',\n sa: 'SA',\n tas: 'TAS',\n vic: 'VIC',\n wa: 'WA',\n ag: 'AG',\n fedmps: 'FedMPs',\n '': '',\n} as const;\n\nexport type DomainCode = keyof typeof DOMAIN_CODE_LABELS;\n\nexport const getDomainOptionLabel = (domainCode: DomainCode | null) => {\n return domainCode === null ? 'N/A' : (DOMAIN_CODE_LABELS[domainCode] ?? '');\n};\n\ntype Props = PropsWithChildren<{\n isLoading: boolean;\n isOpen: boolean;\n onClose: () => void;\n domainOptions: DomainCode[];\n applicationName: string;\n handleLogout: () => void;\n onDomainChange?: (domainCode: DomainCode) => void;\n}>;\n\nconst DomainCodeDialog = ({\n isLoading,\n isOpen,\n onClose: handleClose,\n onDomainChange,\n domainOptions,\n applicationName,\n handleLogout,\n}: Props) => {\n const [domainCode, setDomainCode] = useAtom(domainCodeAtom);\n const [selectedDomainCode, setSelectedDomainCode] = useState(domainCode);\n const { enqueueSuccessNotification } = useSaladBar();\n\n const userHasNoDomains = domainOptions.length === 0;\n const userHasNoRolesInDomain =\n Boolean(domainCode) &&\n !domainOptions.includes(domainCode) &&\n !domainOptions.includes(selectedDomainCode);\n\n const shouldLogout = !domainCode || userHasNoDomains || userHasNoRolesInDomain;\n\n const handleConfirmDomainCode = async () => {\n if (selectedDomainCode) {\n setDomainCode(selectedDomainCode);\n onDomainChange?.(selectedDomainCode);\n enqueueSuccessNotification(`Set organisation to ${selectedDomainCode}`);\n handleClose();\n } else {\n setDomainCode('');\n onDomainChange?.('');\n }\n };\n\n const handleDialogClose = async () => {\n if (domainCode && !userHasNoDomains && !userHasNoRolesInDomain) {\n setSelectedDomainCode(domainCode);\n handleClose();\n } else if (shouldLogout) {\n handleLogout();\n }\n };\n\n let errorMessage: string | undefined;\n if (userHasNoDomains) {\n errorMessage = 'Unable to retrieve your active organisations. Try logging in again.';\n } else if (userHasNoRolesInDomain) {\n errorMessage =\n 'You no longer have any roles in your chosen organisation. Please choose another.';\n }\n\n return (\n <AgDialog\n isOpen={isOpen}\n dialogTitle=\"Select an organisation\"\n primaryButton={{\n text: 'Confirm',\n onClick: handleConfirmDomainCode,\n disabled: !selectedDomainCode || userHasNoDomains || userHasNoRolesInDomain,\n buttonColor: 'primary',\n }}\n secondaryButton={{\n text: shouldLogout ? 'Logout' : 'Cancel',\n onClick: handleDialogClose,\n }}\n onClose={shouldLogout ? () => {} : handleClose}\n >\n <Typography marginBottom={2}>\n Select the default organisation that you want to use with the {applicationName}.\n </Typography>\n\n <Autocomplete\n loading={isLoading}\n multiple={false}\n disableClearable={false}\n value={selectedDomainCode !== '' ? selectedDomainCode : null}\n onChange={(_, value) => setSelectedDomainCode(value ?? '')}\n getOptionLabel={getDomainOptionLabel}\n options={[...domainOptions.toSorted()]}\n renderInput={(params) => (\n <TextField\n {...params}\n variant=\"filled\"\n label={'Select organisation'}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {isLoading ? (\n <CircularProgress color=\"inherit\" size={20} sx={{ marginTop: '-20px' }} />\n ) : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n />\n )}\n />\n {errorMessage && <FormHelperText error>{errorMessage}</FormHelperText>}\n </AgDialog>\n );\n};\n\nexport default DomainCodeDialog;\n","import { useMediaQuery, useTheme } from '@mui/material';\n\nexport const useSmallScreen = () => {\n const theme = useTheme();\n return useMediaQuery(theme.breakpoints.down('sm'));\n};\n","// export const SIDE_PANEL_DEFAULTS = {\n// titleText: '',\n// flavour: 'push',\n// width: 400,\n// arrowButtons: 'both',\n// startOpen: false,\n// open: undefined,\n// onChangeOpen: undefined,\n// content: <></>,\n// onOpened: undefined,\n// onClosed: undefined,\n// dataTestId: undefined,\n// };\n\n// export const INITIAL_LEFT_PANEL_OPEN = false;\n// export const INITIAL_RIGHT_PANEL_OPEN = false;\n\nexport const DEFAULT_INITIAL_NAV_BAR_OPEN = true;\n\nexport const DEFAULT_TOP_BAR_HEIGHT = 64;\nexport const DEFAULT_NAV_BAR_WIDTH_CLOSED = 72;\nexport const DEFAULT_NAV_BAR_WIDTH_OPEN = 256;\n","import { atom } from 'jotai';\nimport { ReactNode } from 'react';\n\nimport {\n DEFAULT_NAV_BAR_WIDTH_CLOSED,\n DEFAULT_NAV_BAR_WIDTH_OPEN,\n DEFAULT_TOP_BAR_HEIGHT,\n} from './defaults';\n\nexport const navBarOpenAtom = atom(true);\n\nexport const navBarWidthOpenAtom = atom(DEFAULT_NAV_BAR_WIDTH_OPEN);\n\nexport const navBarWidthClosedAtom = atom(DEFAULT_NAV_BAR_WIDTH_CLOSED);\n\nexport const titleTextAtom = atom('');\n\nexport const topBarMiddleAtom = atom<ReactNode>(undefined);\n\nexport const topBarHeightAtom = atom(DEFAULT_TOP_BAR_HEIGHT);\n\n// TODO: Would navBarTop be handled better with a portal?\nexport const navBarTopAtom = atom<ReactNode>(undefined);\n","// import { Link as RouterLink } from 'react-router';\n\nimport { NavBarLink } from './types';\n\nexport interface LinksMenuProps {\n links: NavBarLink[];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function LinksMenu({ links }: LinksMenuProps) {\n return <div>LinksMenu not implemented yet</div>;\n}\n","import { StyledComponent } from '@emotion/styled';\nimport {\n Box,\n BoxProps,\n Collapse,\n CollapseProps,\n Drawer,\n DrawerProps,\n useTheme,\n} from '@mui/material';\nimport { CSSObject, Theme, styled } from '@mui/material/styles';\n\nconst PREFIX = 'Navbar';\n\nexport const classes = {\n root: `${PREFIX}-root`,\n menuButton: `${PREFIX}-menuButton`,\n hide: `${PREFIX}-hide`,\n content: `${PREFIX}-content`,\n // userInfoHolder: `${PREFIX}-userInfoHolder`,\n // settings: `${PREFIX}-settings`,\n // pieChartIcon: `${PREFIX}-pieChartIcon`,\n};\n\n// TODO: Explicit type annotation needed until following issue fixed:\n// https://github.com/microsoft/TypeScript/issues/48212\nexport const Root: StyledComponent<BoxProps> = styled(Box, { name: 'NavBar' })(({ theme }) => ({\n [`&.${classes.root}`]: {\n display: 'flex',\n },\n\n [`& .${classes.menuButton}`]: {\n marginRight: 36,\n },\n\n [`& .${classes.hide}`]: {\n display: 'none',\n },\n\n [`& .${classes.content}`]: {\n flexGrow: 1,\n padding: theme.spacing(3),\n },\n\n // [`& .${classes.userInfoHolder}`]: {\n // height: '148px',\n // marginTop: '64px',\n // marginBottom: '16px',\n // },\n}));\n\nexport const navbarTransition = (\n theme: Theme,\n property: string | string[],\n action: 'entering' | 'leaving'\n) =>\n theme.transitions.create(property, {\n easing: theme.transitions.easing.sharp,\n duration:\n action === 'leaving'\n ? theme.transitions.duration.leavingScreen\n : theme.transitions.duration.enteringScreen,\n });\n\nexport const NavbarCollapse = (props: CollapseProps) => {\n const theme = useTheme();\n return (\n <Collapse\n easing={theme.transitions.easing.sharp}\n timeout={{\n enter: theme.transitions.duration.enteringScreen,\n exit: theme.transitions.duration.leavingScreen,\n }}\n {...props}\n />\n );\n};\n\nconst sharedOverrides = (theme: Theme): CSSObject => ({\n overflowX: 'hidden',\n color: 'inherit',\n backgroundColor: theme?.navBar?.backgroundColor ?? 'white', // Provide default so tests don't need to wrap theme provider\n});\n\nconst openedMixin = (theme: Theme, width: number): CSSObject => ({\n width,\n transition: navbarTransition(theme, 'width', 'entering'),\n ...sharedOverrides(theme),\n});\n\nconst closedMixin = (theme: Theme, width: number): CSSObject => ({\n width,\n transition: navbarTransition(theme, 'width', 'leaving'),\n ...sharedOverrides(theme),\n});\n\ninterface NavDrawerProps {\n open: boolean;\n widthOpen: number;\n widthClosed: number;\n isSmallScreen: boolean;\n}\n\n// TODO: Explicit type annotation needed until following issue fixed:\n// https://github.com/microsoft/TypeScript/issues/48212\n// We also use the second Generic parameter\nexport const NavDrawer: StyledComponent<DrawerProps & NavDrawerProps> = styled(Drawer, {\n shouldForwardProp: (prop) =>\n !['widthOpen', 'widthClosed', 'isSmallScreen'].includes(prop as string),\n})<DrawerProps & NavDrawerProps>(({ theme, open, widthOpen, widthClosed, isSmallScreen }) => ({\n flexShrink: 0,\n whiteSpace: 'nowrap',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n\n ...(open && {\n ...openedMixin(theme, widthOpen),\n backgroundColor: '',\n '& .MuiDrawer-paper': openedMixin(theme, widthOpen),\n }),\n ...(!open && {\n ...closedMixin(theme, isSmallScreen ? widthOpen : widthClosed),\n backgroundColor: '',\n '& .MuiDrawer-paper': closedMixin(theme, isSmallScreen ? widthOpen : widthClosed),\n }),\n}));\n","import { useAuth0 } from '@auth0/auth0-react';\nimport { IdToken } from '@auth0/auth0-spa-js';\nimport { useQuery } from '@tanstack/react-query';\nimport { DomainCode } from 'src/domainCode';\n\nfunction fromKebab(string: string) {\n return string.replace(/(^|-)([a-z])/g, (_, separator, char) =>\n separator === '-' ? ' ' + char.toUpperCase() : char.toUpperCase()\n );\n}\n\nexport function determineUserLevelFromClaims<T extends string>(\n claims: IdToken | undefined,\n domainCode: DomainCode,\n roleMapping: Record<T, string[]>,\n rolePriority: T[]\n) {\n if (!claims) return 'None';\n\n const businessRoleClaimsForDomain = Object.entries(claims).filter(\n ([name, value]) => name.startsWith('https://greens.org.au/roles/') && value.includes(domainCode)\n );\n const roles = businessRoleClaimsForDomain.map(([claimName]) =>\n fromKebab(claimName.split('/').at(-1) ?? '')\n );\n\n return (\n rolePriority.find((userLevel) =>\n roleMapping[userLevel].some((requiredRole) => roles.includes(requiredRole))\n ) ?? 'None'\n );\n}\n\nexport const useValidDomains = (appValidBusinessRoles: string[]) => {\n const { getIdTokenClaims, user } = useAuth0();\n return useQuery({\n queryKey: ['availableDomains', user?.sub],\n queryFn: async (): Promise<DomainCode[]> => {\n const claims = await getIdTokenClaims();\n\n if (!claims) return [];\n\n return Object.entries(claims).reduce((prev, [name, value]) => {\n const roleName = fromKebab(name.split('/').at(-1) ?? '');\n const domains =\n name.startsWith('https://greens.org.au/roles/') &&\n appValidBusinessRoles.includes(roleName)\n ? value\n : [];\n return [...new Set([...prev, ...domains])];\n }, [] as DomainCode[]);\n },\n });\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const getValidBusinessRoles = (roleMapping: Record<any, string[]>) =>\n Object.values(roleMapping).reduce(\n (prev, curr) => [...new Set([...prev, ...curr])],\n [] as string[]\n );\n","type SuppressionFilter = RegExp | ((...data: unknown[]) => boolean);\n\ntype ConsoleFn = 'log' | 'error' | 'warn' | 'info' | 'debug';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst origConsoleFns: Record<ConsoleFn, any> = {\n log: console.warn.bind(console),\n error: console.error.bind(console),\n warn: console.warn.bind(console),\n info: console.info.bind(console),\n debug: console.debug.bind(console),\n};\n\n/**\n * If called, will replace the underlying console function with a wrapper that\n * will prevent the original from being called if a filter matches. A filter can\n * either be a regex or a function that returns true on a match.\n *\n * Motivation: Originally implemented to provide a way to suppress the harmless\n * MUI warnings generated by SingleAutocomplete component\n */\nexport function suppressConsole(fn: ConsoleFn, filters: SuppressionFilter[]) {\n console[fn] = (...data: unknown[]) => {\n // If filtered, skip output\n for (const filter of filters) {\n if (typeof filter === 'function') {\n if (filter(...data)) return;\n } else if (filter instanceof RegExp && data.length > 0) {\n for (const str of data) {\n if (typeof str === 'string' && filter.test(str)) {\n return;\n }\n }\n }\n }\n // Otherwise call original console function\n origConsoleFns[fn](data);\n };\n}\n\n/**\n * Reset console[fn] to original. If fn is not specified, resets all functions\n * (log, error, warn, info, debug)\n *\n * NOTE: Unsure if this will work in most cases\n */\nexport function unsuppressConsole(fn?: ConsoleFn) {\n if (fn) {\n console[fn] = origConsoleFns[fn];\n } else {\n for (const f of Object.keys(origConsoleFns) as ConsoleFn[]) {\n console[f] = origConsoleFns[f];\n }\n }\n}\n","import type { ErrorEvent, EventHint } from '@sentry/react';\n\n/**\n * Checks whether an error is an Auth0 OAuthError with a specific error code.\n * Auth0's OAuthError shape has an `error` string property (the OAuth2 error\n * code) in addition to the standard Error properties.\n */\nfunction isAuth0ErrorWithCode(error: unknown, code: string): boolean {\n return (\n error != null &&\n typeof error === 'object' &&\n 'error' in error &&\n (error as Record<string, unknown>).error === code\n );\n}\n\n/**\n * Sentry beforeSend callback that filters out expected Auth0 errors which are\n * already handled by AuthGuard (e.g. by redirecting to login).\n *\n * The Auth0 SPA SDK can emit unhandled promise rejections for errors that\n * AuthGuard subsequently handles through the React context. These show up in\n * Sentry via the global onunhandledrejection handler but are not actionable.\n *\n * See: LISTMANAGER-FRONTEND-Y2\n */\nexport function sentryBeforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null {\n const error = hint?.originalException;\n\n // Auth0 emits \"login_required\" as an unhandled rejection when a user's\n // session has expired. AuthGuard handles this by redirecting to login.\n if (isAuth0ErrorWithCode(error, 'login_required')) {\n return null;\n }\n\n return event;\n}\n","// https://stackoverflow.com/a/8831937\nexport function simpleHashCode(str: string) {\n let hash = 0;\n for (let i = 0, len = str.length; i < len; i++) {\n const chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n}\n","import { Box, Fade, Avatar as OtherAvatar, Skeleton, Typography, useTheme } from '@mui/material';\nimport Avatar from 'react-avatar';\nimport { DomainCode, getDomainOptionLabel } from '../../../domainCode';\nimport { simpleHashCode } from '../../../utils';\nimport { NavbarCollapse, navbarTransition } from './Styling';\nimport { User } from './types';\n\n// These all have good contrast against our typical navbar background colour\nconst avatarColours = ['#A62A21', '#7e3794', '#0B51C1', '#3A6024', '#A81563', '#B3003C'];\n\nconst extractInitials = (name: string) =>\n name\n .split(/\\s/)\n .map((part) => part.substring(0, 1).toUpperCase())\n .filter((v) => !!v)\n .slice(0, 2)\n .join('')\n .toUpperCase();\n\nexport interface UserInfoProps {\n user?: User;\n domainCode?: DomainCode;\n open: boolean;\n useNewAvatar?: boolean;\n}\n\n/**\n * If user has a defined name and a valid url for picture, the picture will for\n * the avatar image.\n *\n * If there is a defined name but the picture is invalid or undefined, the\n * intials will be used to generate the avatar image. The colour will be random\n * for different names, but always the same for the same name.\n *\n * If user is undefined or the name is undefined, a generic empty avatar image\n * will be displayed.\n *\n *\n */\n\nexport default function UserInfo({ user, domainCode, open, useNewAvatar = false }: UserInfoProps) {\n const theme = useTheme();\n return (\n <Box\n sx={{\n paddingTop: 3,\n display: 'flex',\n alignItems: 'center',\n flexDirection: 'column',\n gap: '0.5rem',\n }}\n >\n {!useNewAvatar && (\n <Box\n sx={{\n width: open ? '5rem' : '2rem',\n transition: open\n ? navbarTransition(theme, ['width', 'height'], 'entering')\n : navbarTransition(theme, ['width', 'height'], 'leaving'),\n aspectRatio: 1,\n }}\n >\n {user?.name ? (\n <>\n <OtherAvatar\n src={user?.picture}\n sx={{\n width: '100%',\n height: '100%',\n bgcolor:\n avatarColours[Math.abs(simpleHashCode(user?.name)) % avatarColours.length],\n }}\n >\n {extractInitials(user?.name)}\n </OtherAvatar>\n </>\n ) : (\n <OtherAvatar sx={{ width: '100%', height: '100%' }} />\n )}\n </Box>\n )}\n {useNewAvatar && (\n <Box\n sx={{\n width: open ? '5rem' : '2rem',\n transition: open\n ? navbarTransition(theme, ['width', 'height'], 'entering')\n : navbarTransition(theme, ['width', 'height'], 'leaving'),\n aspectRatio: 1,\n }}\n >\n {user?.name ? (\n <>\n <Avatar src={user?.picture} name={user?.name} round={true} size={open ? '80' : '32'}>\n {' '}\n {extractInitials(user?.name)} {'ab'}\n </Avatar>\n </>\n ) : (\n <Avatar />\n )}\n </Box>\n )}\n\n <NavbarCollapse sx={{ width: '100%' }} in={open}>\n <Fade in={open}>\n <Box width=\"100%\" display=\"flex\" flexDirection=\"column\" alignItems=\"center\">\n {user?.name ? (\n <Typography>{user?.name}</Typography>\n ) : (\n <Skeleton animation={false} width={'50%'} />\n )}\n {domainCode ? (\n <Typography>{getDomainOptionLabel(domainCode)}</Typography>\n ) : (\n <Skeleton animation={false} width={'25%'} />\n )}\n </Box>\n </Fade>\n </NavbarCollapse>\n </Box>\n );\n}\n","import { Box, Divider, Toolbar } from '@mui/material';\nimport { ReactNode } from 'react';\n\nimport { useSetAtom } from 'jotai';\nimport { DomainCode } from '../../../domainCode';\nimport { useSmallScreen } from '../mobile';\nimport { navBarOpenAtom } from '../stateAtoms';\nimport { LinksMenu } from './LinksMenu';\nimport { NavDrawer, Root, classes } from './Styling';\nimport UserInfo from './UserInfo';\nimport { NavBarLink, User } from './types';\n\nexport interface NavBarProps {\n open: boolean;\n\n offsetTop?: number;\n\n widthOpen: number;\n\n widthClosed: number;\n\n /** Set the datatest-id on the root element for using reactdom's getByTestId()\n * function */\n 'data-testid'?: string;\n\n /** The contents to be displayed at the top, intended to be specific to the\n * current page */\n top?: ReactNode;\n\n /**\n * Display be below the top section, intended to always be the same,\n * regardless of the current route. Can be provided either as a node directly,\n * or an array of objects that will be used to generate a standard navbar menu.\n *\n * @example\n *\n * ```\n * // As a ReactNode\n * <NavBar open: {open} middle={<TheContent}/>\n * ```\n *\n * @example\n *\n * ```\n * // As an Array\n * <NavBar open: {open} middle={[\n * {label: 'foo', destPathname: '/foo', icon: {FooIcon}},\n * {label: 'bar', destPathname: '/bar', icon: {BarIcon}},\n * ]}/>\n * ```\n */\n middle: ReactNode | NavBarLink[];\n\n /** User information displayed at bottom of navabar when it is open*/\n user?: User;\n\n /** Displayed below the user information when available */\n domainCode?: DomainCode;\n\n /**\n * The contents to be displayed at the bottom, intended to always be the\n * same, regardless of current route.\n */\n bottom?: ReactNode;\n\n /* The NavBar can use the old Avatar code, or the new Avatar code. */\n\n useNewAvatar?: boolean;\n}\n\n/**\n * A styled navigation bar. At this point in time its pretty unopinionated, it\n * just renders whatever children it is given. The NavBarLightStyledList\n * component can be used for consistent styling against the background.\n */\nexport default function NavBar({\n open,\n widthClosed,\n widthOpen,\n 'data-testid': dataTestId,\n top,\n middle,\n bottom,\n user,\n domainCode,\n useNewAvatar = false,\n}: NavBarProps) {\n const isSmallScreen = useSmallScreen();\n const setNavBarOpen = useSetAtom(navBarOpenAtom);\n\n return (\n <Root className={classes.root} data-testid={dataTestId}>\n <NavDrawer\n open={open}\n widthOpen={widthOpen}\n widthClosed={widthClosed}\n anchor=\"left\"\n variant={!isSmallScreen ? 'permanent' : 'temporary'}\n PaperProps={{\n component: 'nav',\n }}\n onClose={() => {\n setNavBarOpen(false);\n }}\n isSmallScreen={isSmallScreen}\n >\n {!isSmallScreen && <Toolbar />}\n {top && (\n <Box flexGrow=\"0\">\n {top}\n <Divider variant=\"middle\" sx={{ marginY: '0.5rem' }} />\n </Box>\n )}\n\n <Box flexGrow=\"1\">\n {/* middle is either a ReactNode or an array of NavBarLink objects */}\n {Array.isArray(middle) ? <LinksMenu links={middle as unknown as NavBarLink[]} /> : middle}\n </Box>\n\n <Box flexGrow=\"0\">\n <Divider variant=\"middle\" sx={{ marginY: '0.5rem' }} />\n <UserInfo user={user} domainCode={domainCode} open={open} useNewAvatar={useNewAvatar} />\n\n {bottom && <>{bottom}</>}\n </Box>\n </NavDrawer>\n </Root>\n );\n}\n","import { Box, Container, ContainerProps } from '@mui/material';\nimport { PropsWithChildren } from 'react';\n\n// const NavBarAwareMargins = styled('div', {\n// shouldForwardProp: (prop) => !(['leftPanel', 'rightPanel'] as Array<PropertyKey>).includes(prop),\n// name: 'PanelAwareMargins',\n// })<PanelAwareMarginsProps>(({ theme, leftPanel, rightPanel }) => ({\n// transition: theme.transitions.create('margin', {\n// easing: theme.transitions.easing.sharp,\n// duration: theme.transitions.duration.leavingScreen,\n// }),\n\n// ...(leftPanel?.open && {\n// transition: theme.transitions.create('margin', {\n// easing: theme.transitions.easing.easeOut,\n// duration: theme.transitions.duration.enteringScreen,\n// }),\n// marginLeft: `${leftPanel?.width ?? 0}px`,\n// }),\n// ...(rightPanel?.open && {\n// transition: theme.transitions.create('margin', {\n// easing: theme.transitions.easing.easeOut,\n// duration: theme.transitions.duration.enteringScreen,\n// }),\n// marginRight: `${rightPanel?.width ?? 0}px`,\n// }),\n// }));\n\ninterface PageContainerProps {\n topBarHeight: number;\n\n /** Passed to underlying Container. False be default.*/\n maxWidth?: ContainerProps['maxWidth'];\n noPadding?: boolean;\n}\n\n/**\n * An MUI Container component wrapped in a Box whose height adapts to the\n * topBarHeight and has a stable scrollbar gutter.\n */\nfunction PageContainer({\n children,\n topBarHeight,\n maxWidth = false,\n noPadding,\n}: PropsWithChildren<PageContainerProps>) {\n return (\n <Box\n sx={{\n overflow: 'auto',\n height: `calc(100vh - ${topBarHeight}px)`,\n flexGrow: 1,\n }}\n >\n {noPadding ? (\n <Box component=\"main\" id=\"main-content\" height=\"inherit\">\n {children}\n </Box>\n ) : (\n <Container\n component=\"main\"\n id=\"main-content\"\n maxWidth={maxWidth}\n sx={{ paddingTop: 3, paddingBottom: 3, flexGrow: 1 }}\n >\n {children}\n </Container>\n )}\n </Box>\n );\n}\n\nexport default PageContainer;\n","import { ViewHeadline as HamburgerIcon } from '@mui/icons-material';\nimport { IconButton, Paper, Typography, useTheme } from '@mui/material';\n\nimport { useSetAtom } from 'jotai';\nimport { ReactNode } from 'react';\nimport { useSmallScreen } from './mobile';\nimport { navBarOpenAtom } from './stateAtoms';\n\nconst PREFIX = 'TopBar';\n\nexport interface TopBarProps {\n titleText?: string;\n\n /**\n * The contents to be displayed to the right of the titleText, left aligned to\n * the starting position of the navbar. There is no right content, so at the\n * moment it fills up the remaining space\n */\n middle?: ReactNode;\n\n height: number;\n 'data-testid'?: string;\n}\n\nexport const classes = {\n titleText: `${PREFIX}-titleText`,\n};\n\n/**\n * Top bar of every page, above the content. Works a bit like MUI's AppBar but\n * the scroll bar will not appear for the whole page, instead just the page\n * content\n */\nexport default function TopBar({\n titleText = '',\n height,\n 'data-testid': dataTestId,\n middle,\n}: TopBarProps) {\n const setNavBarOpen = useSetAtom(navBarOpenAtom);\n\n const toggleNavBar = () => setNavBarOpen((prevVal) => !prevVal);\n const theme = useTheme();\n const isSmallScreen = useSmallScreen();\n return (\n <header data-testid={dataTestId}>\n <Paper\n square\n elevation={0}\n sx={{\n width: '100%',\n position: 'sticky',\n color: 'primary.contrastText',\n backgroundColor: 'primary.main',\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n flexShrink: 0,\n height,\n zIndex: isSmallScreen ? 0 : theme.zIndex.drawer + 99,\n }}\n >\n <IconButton\n size=\"medium\"\n color=\"inherit\"\n sx={{ padding: 1.5, marginLeft: '12px' }}\n onClick={toggleNavBar}\n >\n <HamburgerIcon fontSize=\"medium\" />\n </IconButton>\n <Typography className={classes.titleText} variant=\"h6\" component=\"h1\">\n {titleText}\n </Typography>\n\n {middle}\n </Paper>\n </header>\n );\n}\n","import CssBaseline from '@mui/material/CssBaseline';\nimport { ComponentProps, PropsWithChildren } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { useAtom, useAtomValue } from 'jotai';\nimport { useHydrateAtoms } from 'jotai/utils';\nimport NavBar, { NavBarProps } from './NavBar';\nimport PageContainer from './PageContainer';\nimport TopBar from './TopBar';\nimport {\n navBarOpenAtom,\n navBarTopAtom,\n navBarWidthClosedAtom,\n navBarWidthOpenAtom,\n titleTextAtom,\n topBarHeightAtom,\n topBarMiddleAtom,\n} from './stateAtoms';\n\nexport interface BaseAppLayoutProps {\n /** Either an array of objects used to automatically generate the content of\n * the navbar (WIP), or a node to render directly.*/\n navBarMiddle: NavBarProps['middle'];\n\n /** A node to render directly.*/\n navBarBottom: NavBarProps['bottom'];\n\n /**\n * The initial titleText. Shortcut for calling a setter from useAppLayout()\n * hook since its such a common action.\n */\n initialTitleText?: string;\n\n /**\n * The initial open state of the navbar, which is true by default. Shortcut\n * for calling a setter from useAppLayout() hook since its such a common\n * action.\n */\n initialNavBarOpen?: boolean;\n\n /** Props applied to the PageContainer component, which is a styled MUI\n * Container */\n pageContainerProps?: ComponentProps<typeof PageContainer>;\n\n /** Passed directly as prop of TopBar component */\n topBarDataTestId?: string;\n\n /** Passed directly as prop of PageContainer component */\n pageContentDataTestId?: string;\n\n /** Passed down as prop to the root element of the NavBar component */\n navBarDataTestId?: string;\n\n /** Used to display user name and provided picture as avatar or one generated\n * from unitials of the name */\n user?: NavBarProps['user'];\n\n /** Display under the user's name */\n domainCode?: NavBarProps['domainCode'];\n\n //** Do we use the old avatar code or the new one? */\n useNewAvatar?: boolean;\n}\n\ntype AppLayoutProps = PropsWithChildren<BaseAppLayoutProps>;\n\nexport default function AppLayout({\n children,\n initialTitleText,\n initialNavBarOpen,\n pageContainerProps,\n pageContentDataTestId,\n topBarDataTestId,\n navBarDataTestId,\n navBarMiddle,\n navBarBottom,\n user,\n domainCode,\n useNewAvatar = false,\n}: AppLayoutProps) {\n useHydrateAtoms([\n [navBarOpenAtom, initialNavBarOpen ?? true],\n [titleTextAtom, initialTitleText ?? ''],\n ]);\n const navBarOpen = useAtomValue(navBarOpenAtom);\n const [navBarWidthOpen] = useAtom(navBarWidthOpenAtom);\n const [navBarWidthClosed] = useAtom(navBarWidthClosedAtom);\n const titleText = useAtomValue(titleTextAtom);\n const [topBarHeight] = useAtom(topBarHeightAtom);\n const [topBarMiddle] = useAtom(topBarMiddleAtom);\n const [navBarTop] = useAtom(navBarTopAtom);\n\n return (\n <Box>\n <CssBaseline />\n <TopBar\n titleText={titleText}\n data-testid={topBarDataTestId}\n height={topBarHeight}\n middle={topBarMiddle}\n />\n\n <Box sx={{ display: 'flex' }}>\n <NavBar\n open={navBarOpen}\n top={navBarTop}\n middle={navBarMiddle}\n bottom={navBarBottom}\n user={user}\n domainCode={domainCode}\n widthOpen={navBarWidthOpen}\n widthClosed={navBarWidthClosed}\n offsetTop={topBarHeight}\n data-testid={navBarDataTestId}\n useNewAvatar={useNewAvatar}\n />\n\n <PageContainer\n data-testid={pageContentDataTestId}\n topBarHeight={topBarHeight}\n {...pageContainerProps}\n >\n {children}\n </PageContainer>\n </Box>\n </Box>\n );\n}\n","import { createTheme } from '@mui/material/styles';\n\nconst theme = createTheme({\n palette: {\n primary: {\n dark: '#00A651',\n light: '#A3D39C',\n main: '#007236',\n contrastText: '#FFF',\n },\n warning: {\n main: '#F5871F',\n light: '#FCC589',\n dark: '#A2590A',\n contrastText: '#FFF',\n },\n secondary: {\n main: '#662D91',\n light: '#BD8CBF',\n dark: '#440E62',\n contrastText: '#FFF',\n },\n error: {\n main: '#D43C95',\n light: '#8F2064',\n dark: '#F9CDE0',\n contrastText: '#FFF',\n },\n info: {\n main: '#00A88D',\n light: '#ADDCCF',\n dark: '#005243',\n contrastText: '#FFF',\n },\n success: {\n main: '#00A651',\n light: '#A3D39C',\n dark: '#007236',\n contrastText: '#FFF',\n },\n },\n typography: {\n // I couldn't think of what to call this. It is an attempt to match\n // https://www.figma.com/file/atonRPl2YD9A1NCntbDtKR/List-Filter-and-Product-Concept?node-id=1187%3A43730\n // but not sure if line height should be changed\n explainer: {\n fontSize: '14px',\n marginBlockStart: '1em',\n },\n },\n\n navBar: {\n backgroundColor: '#E8E8E8',\n },\n});\n\nexport default theme;\n","import { alpha, createTheme } from '@mui/material/styles';\n\nconst theme = createTheme({\n palette: {\n primary: {\n main: '#007236',\n dark: '#005221',\n light: '#00A04E',\n contrastText: '#FFFFFF',\n },\n secondary: {\n main: '#662D91',\n dark: '#440E62',\n light: '#93268F',\n contrastText: '#FFFFFF',\n },\n error: {\n main: '#D32F2F',\n dark: '#C62828',\n light: '#EF5350',\n },\n info: {\n main: '#0288D1',\n dark: '#01579B',\n light: '#03A9F4',\n },\n success: {\n main: '#0288D1',\n dark: '#01579B',\n light: '#03A9F4',\n },\n },\n components: {\n MuiTextField: {\n defaultProps: { color: 'secondary' },\n },\n MuiToggleButtonGroup: {\n defaultProps: { color: 'secondary' },\n },\n MuiCheckbox: {\n defaultProps: { color: 'secondary' },\n },\n MuiSelect: {\n defaultProps: { color: 'secondary' },\n },\n MuiSwitch: {\n defaultProps: { color: 'secondary' },\n },\n MuiFormControl: {\n defaultProps: { color: 'secondary' },\n },\n MuiMenuItem: {\n // Setting defaultProps for color on MenuItem does not work, so update manually\n styleOverrides: {\n root: ({ theme: origTheme }) => ({\n '&.Mui-selected': {\n backgroundColor: alpha(\n origTheme.palette.secondary.main,\n origTheme.palette.action.selectedOpacity\n ),\n '&:hover': {\n backgroundColor: alpha(\n origTheme.palette.secondary.main,\n origTheme.palette.action.selectedOpacity\n ),\n },\n '&.Mui-focusVisible': {\n backgroundColor: alpha(\n origTheme.palette.secondary.main,\n origTheme.palette.action.focusOpacity\n ),\n },\n },\n }),\n },\n },\n },\n typography: {\n h4: {\n fontSize: '1.88rem',\n fontWeight: 500,\n },\n h5: {\n fontWeight: 500,\n },\n // I couldn't think of what to call this. It is an attempt to match\n // https://www.figma.com/file/atonRPl2YD9A1NCntbDtKR/List-Filter-and-Product-Concept?node-id=1187%3A43730\n // but not sure if line height should be changed\n explainer: {\n fontSize: '14px',\n marginBlockStart: '1em',\n },\n },\n navBar: {\n backgroundColor: '#E8E8E8',\n },\n});\n\nexport default theme;\n"],"names":["ExampleComponent","text","num","setNum","useState","jsxs","Fragment","jsx","Typography","Button","oldNum","Paper","AgDialog","isOpen","dialogTitle","children","maxWidth","primaryButton","secondaryButton","additionalButtons","handleClose","sx","dataTestId","disableCloseOnBackdropOrEscape","isLoading","areButtonsDisabled","setButtonsDisabled","Dialog","_event","reason","__async","LinearProgress","DialogTitle","DialogContent","DialogActions","_a","buttonConfig","idx","DEFAULT_CHIP_TOOL_TIP_SLOT_PROPS","MOUSE_EVENT_BUTTONS","useAutocompleteOptions","minLength","preLoadedOptions","lookup","label","inputValue","useQuery","option","FetchAutocomplete","enableHighlighting","onChange","onInputChange","value","boxSx","textFieldColor","textFieldVariant","textFieldFocused","textFieldSx","loadingText","noOptionsText","popupIcon","DefaultPopupIcon","error","helperText","disablePortal","disableIconFlip","chipToolTipSlotProps","placeholderText","onRightClick","disableDefaultRightClickBehaviour","readOnly","hideInputEndAdornment","setInputValue","handleDelete","e","deleteValue","newInternalValue","x","options","isInputMinimumLength","Autocomplete","__spreadValues","event","newValue","newInputValue","params","TextField","__spreadProps","CircularProgress","v","props","state","matches","match","parts","parse","createElement","part","index","Box","val","Chip","Tooltip","CancelIcon","MUI_AUTOCOMPLETE_VALUE_WARNING_REGEX","SingleAutocomplete","disabled","Stack","getAuth0Expiry","token","base64","jsonPayload","Buffer","c","jsonParsedPayload","SessionExpiryDialog","open","closeHandler","setAuth0ExpiryTime","logout","getAccessTokenSilently","useAuth0","handleDialogClose","successButtonConfig","tokenSecond","tokenExp","cancelButtonConfig","isOAuthError","errorFromApplicationAccessRejection","errorObject","errorDescription","errorFromUserNotAuthorisingApp","errorFromScriptExecutionTimeout","AuthGuard","appName","throwErrors","disableConsoleLogging","onError","isAuthenticated","loginWithRedirect","useEffect","useMemo","title","message","redirectCount","_b","Skeleton","defaultSnackbarProps","defaultSaladBarProps","defaultEnqueueNotificationOptions","MAX_QUEUE_LENGTH","MAX_QUEUE_HIT_REPORT_INTERVAL","SALADBAR_INDEX","generateNotificationKey","previousKey","alertWithLinearProgressStyle","defaultOverrideState","defaultOverrideActions","Context","createContext","SaladBarProvider","overrideState","overrideActions","shouldClose","snackbarProps","__objRest","setSaladBarState","queueRef","useRef","limitLastHitAt","limitHitCountSinceLastReport","setOpen","useCallback","newVal","enqueueNotification","notification","newNotification","enqueueSuccessNotification","enqueueInfoNotification","enqueueWarningNotification","enqueueErrorNotification","removeNotification","key","handleExit","handleExited","currentNotification","currentNotificationSnackbarProps","snackbarFinalProps","Snackbar","Alert","ContextError","__publicField","useSaladBar","context","useContext","withSaladBarProvider","createHelper","actions","DOMAIN_CODE_KEY","baseDomainCodeAtom","atom","domainCodeAtom","get","_","set","DOMAIN_CODE_LABELS","getDomainOptionLabel","domainCode","DomainCodeDialog","onDomainChange","domainOptions","applicationName","handleLogout","setDomainCode","useAtom","selectedDomainCode","setSelectedDomainCode","userHasNoDomains","userHasNoRolesInDomain","shouldLogout","handleConfirmDomainCode","errorMessage","FormHelperText","useSmallScreen","theme","useTheme","useMediaQuery","DEFAULT_TOP_BAR_HEIGHT","DEFAULT_NAV_BAR_WIDTH_CLOSED","DEFAULT_NAV_BAR_WIDTH_OPEN","navBarOpenAtom","navBarWidthOpenAtom","navBarWidthClosedAtom","titleTextAtom","topBarMiddleAtom","topBarHeightAtom","navBarTopAtom","LinksMenu","links","PREFIX","classes","Root","styled","navbarTransition","property","action","NavbarCollapse","Collapse","sharedOverrides","openedMixin","width","closedMixin","NavDrawer","Drawer","prop","widthOpen","widthClosed","isSmallScreen","fromKebab","string","separator","char","determineUserLevelFromClaims","claims","roleMapping","rolePriority","roles","name","claimName","userLevel","requiredRole","useValidDomains","appValidBusinessRoles","getIdTokenClaims","user","prev","roleName","domains","getValidBusinessRoles","curr","origConsoleFns","suppressConsole","fn","filters","data","filter","str","unsuppressConsole","f","isAuth0ErrorWithCode","code","sentryBeforeSend","hint","simpleHashCode","hash","i","len","chr","avatarColours","extractInitials","UserInfo","useNewAvatar","OtherAvatar","Avatar","Fade","NavBar","top","middle","bottom","setNavBarOpen","useSetAtom","Toolbar","Divider","PageContainer","topBarHeight","noPadding","Container","TopBar","titleText","height","toggleNavBar","prevVal","IconButton","HamburgerIcon","AppLayout","initialTitleText","initialNavBarOpen","pageContainerProps","pageContentDataTestId","topBarDataTestId","navBarDataTestId","navBarMiddle","navBarBottom","useHydrateAtoms","navBarOpen","useAtomValue","navBarWidthOpen","navBarWidthClosed","topBarMiddle","navBarTop","CssBaseline","createTheme","origTheme","alpha"],"mappings":"ohDAQA,SAAwBA,GAAiB,CAAE,KAAAC,GAA+B,CACxE,KAAM,CAACC,EAAKC,CAAM,EAAIC,EAAAA,SAAS,CAAC,EAEhC,OACEC,EAAAA,KAAAC,WAAA,CACE,SAAA,CAAAC,EAAAA,IAACC,EAAAA,WAAA,CAAW,QAAQ,KAAK,MAAM,UAAU,UAAU,MAAM,GAAI,CAAE,SAAU,MAAA,EAAU,SAAA,cAEnF,EAEAD,EAAAA,IAACC,EAAAA,YAAW,QAAQ,UAAU,QAAQ,QACpC,SAAAD,EAAAA,IAAC,OAAA,CAAK,SAAA,uEAAA,CAAqE,CAAA,CAC7E,EACAA,EAAAA,IAACE,EAAAA,OAAA,CACC,QAAQ,WACR,QAAS,IAAMN,EAAQO,GAAWA,EAAS,CAAC,EAC5C,aAAW,YACZ,SAAA,qBAAA,CAAA,SAGA,IAAA,CAAE,SAAA,CAAA,sBACkBH,EAAAA,IAAC,QAAM,SAAAN,CAAA,CAAK,CAAA,EACjC,SACCU,EAAAA,MAAA,CAAM,SAAA,CAAA,qDAAmDT,CAAA,CAAA,CAAI,CAAA,EAChE,CAEJ,CCMA,MAAMU,GAAW,CAAC,CAChB,OAAAC,EACA,YAAAC,EACA,SAAAC,EACA,SAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,kBAAAC,EACA,QAASC,EACT,GAAAC,EACA,cAAeC,EACf,+BAAAC,EAAiC,GACjC,UAAAC,EAAY,EACd,IAAqB,SACnB,KAAM,CAACC,EAAoBC,CAAkB,EAAItB,EAAAA,SAAS,EAAK,EAE/D,OACEC,EAAAA,KAACsB,EAAAA,OAAA,CACC,KAAMd,EACN,QAAS,CAAOe,EAAQC,IAAWC,EAAA,sBAE/BP,IACCM,IAAW,iBAAmBA,IAAW,kBAIxCJ,IACAP,GAAA,MAAAA,EAAiB,QACnB,MAAMA,EAAgB,QAAA,EAEtBE,EAAA,EAEJ,GACA,UAAS,GACT,SAAUJ,GAAA,KAAAA,EAAY,KACtB,cAAaM,EACb,GAAAD,EAEC,SAAA,CAAAG,GAAajB,EAAAA,IAACwB,EAAAA,gBAAe,GAAI,CAAE,OAAQ,MAAO,aAAc,QAAU,EAC3ExB,EAAAA,IAACyB,EAAAA,aAAa,SAAAlB,CAAA,CAAY,EAC1BP,MAAC0B,EAAAA,cAAA,CAAc,GAAI,CAAE,kBAAmB,CAAE,aAAc,CAAA,GAAQ,SAAAlB,EAAS,SACxEmB,EAAAA,cAAA,CACC,SAAA,CAAA3B,EAAAA,IAACE,EAAAA,OAAA,CACC,SAAS0B,EAAAjB,GAAA,YAAAA,EAAiB,UAAjB,KAAAiB,EAA4Bf,EACrC,cAAaF,GAAA,YAAAA,EAAiB,OAC9B,UAAUA,GAAA,YAAAA,EAAiB,WAAYO,EACvC,MAAOP,GAAA,YAAAA,EAAiB,YAEvB,6BAAiB,cAAQ,QAAA,CAAA,EAE3BC,GACCA,EAAkB,IAAI,CAACiB,EAAcC,IAAQ,OAC3C,OACE9B,EAAAA,IAACE,EAAAA,OAAA,CAEC,QAAS2B,GAAA,YAAAA,EAAc,QACvB,cAAaA,GAAA,YAAAA,EAAc,OAC3B,UAAUA,GAAA,YAAAA,EAAc,WAAYX,EACpC,MAAOW,GAAA,YAAAA,EAAc,YAEpB,UAAAD,EAAAC,EAAa,OAAb,KAAAD,EAAqB,UAAUE,CAAG,EAAA,EAN9BA,CAAA,CASX,CAAC,EACFpB,GACCV,EAAAA,IAACE,EAAAA,OAAA,CACC,QAAS,IAAYqB,EAAA,4BACnBJ,EAAmB,EAAI,EACvB,MAAMS,EAAAlB,EAAc,UAAd,YAAAkB,EAAA,KAAAlB,GACNS,EAAmB,EAAK,CAC1B,GACA,cAAaT,EAAc,OAC3B,SAAUA,EAAc,UAAYQ,EACpC,MAAOR,GAAA,YAAAA,EAAe,YAErB,SAAAA,EAAc,IAAA,CAAA,CACjB,CAAA,CAEJ,CAAA,CAAA,CAAA,CAGN,ECxHaqB,GAAmC,CAC9C,OAAQ,CACN,UAAW,CACT,CACE,KAAM,SACN,QAAS,CACP,OAAQ,CAAC,IAAK,GAAG,CAAA,CACnB,CACF,CACF,CAEJ,EAEaC,GAAsB,CAGjC,MAAO,CACT,ECQaC,GAAyB,CAA+C,CACnF,UAAAC,EACA,iBAAAC,EACA,OAAAC,EACA,MAAAC,EACA,WAAAC,CACF,IAOSC,YAAS,CACd,QAAS,IACHL,GAAaI,EAAW,OAASJ,EAAkBC,GAAA,KAAAA,EAAoB,CAAA,EACvEA,EACKA,EAAiB,OAAQK,GAC9BA,EAAO,MAAM,cAAc,SAASF,EAAW,YAAA,CAAa,CAAA,EAEzDF,EAAOE,CAAU,EAE1B,SAAU,CAAC,eAAgBD,EAAOC,CAAU,CAAA,CAC7C,EAyGH,SAAwBG,GAAgE,CACtF,OAAAL,EAAS,IAAYb,EAAA,sBAAC,GACtB,mBAAAmB,EAAqB,GACrB,SAAAC,EACA,cAAAC,EACA,UAAAV,EAAY,EACZ,MAAAG,EACA,MAAAQ,EACA,cAAe9B,EACf,GAAAD,EACA,MAAAgC,EACA,eAAAC,EACA,iBAAAC,EAAmB,SACnB,iBAAAC,EACA,YAAAC,EACA,YAAAC,EAAc,aACd,cAAAC,EAAgB,aAChB,UAAAC,QAAaC,GAAAA,cAAA,EAAiB,EAC9B,MAAAC,EAAQ,GACR,WAAAC,EAAa,GACb,iBAAArB,EAAmB,OACnB,cAAAsB,EAAgB,GAChB,gBAAAC,EAAkB,GAClB,qBAAAC,EAAuB5B,GACvB,gBAAA6B,EAAkB,OAClB,aAAAC,EAAe,IAAM,CAAC,EACtB,kCAAAC,EAAoC,GACpC,SAAAC,EACA,sBAAAC,CACF,EAAuC,CACrC,KAAM,CAAC1B,EAAY2B,CAAa,EAAIpE,EAAAA,SAAS,EAAE,EAEzCqE,EAAe,CACnBC,EACAC,IACG,CACH,MAAMC,EAAmBxB,EAAM,OAAQyB,GAAMA,EAAE,KAAOF,CAAW,EACjEzB,EAAS0B,EAAkB,SAAUF,CAAC,CACxC,EAEM,CAAE,KAAMI,EAAS,UAAAtD,CAAA,EAAcgB,GAAuB,CAC1D,WAAAK,EACA,MAAAD,EACA,OAAAD,EACA,UAAAF,EACA,iBAAAC,CAAA,CACD,EAEKqC,EAAuBlC,EAAW,QAAUJ,EAElD,OACEpC,EAAAA,KAAC,MAAA,CAAI,cAAaiB,EAChB,SAAA,CAAAf,EAAAA,IAACyE,EAAAA,aAAA,CACC,GAAIC,IAAA,GACC5D,GACC4C,EACA,CAAE,sCAAuC,CAAE,UAAW,cAAA,CAAe,EACrE,CAAA,GAEN,cAAa3C,EAAa,GAAGA,CAAU,gBAAkB,OACzD,cAAA0C,EACA,SAAQ,GACR,eAAiBjB,GAAY,OAAOA,GAAW,SAAWA,EAASA,EAAO,MAC1E,QAASgC,EAAuBvD,EAAY,GAG5C,QAAS,CAAC,GAAG4B,EAAO,GAAI0B,GAAA,KAAAA,EAAW,CAAA,CAAG,EAGtC,sBAAqB,GAErB,mBAAkB,GAClB,MAAA1B,EACA,SAAU,CAAC8B,EAAOC,EAAUtD,IAAW,CACrCqB,EAASiC,EAA0BtD,EAAQqD,CAAK,CAClD,EACA,cAAe,CAACA,EAAOE,EAAevD,IAAW,CAC/C2C,EAAcY,CAAa,EACvBjC,GAAeA,EAAcC,EAAOvB,EAAQqD,CAAK,CACvD,EACA,cAAeH,EAAuBpB,EAAgB,yBACtD,YAAAD,EACA,UAAAE,EACA,YAAcyB,GACZ9E,EAAAA,IAAC+E,EAAAA,UAAAC,EAAAN,EAAA,GACKI,GADL,CAEC,MAAAzC,EACA,UAAS,GACT,QAASW,EACT,MAAAO,EACA,WAAAC,EACA,UAAW,CACT,MAAOwB,EAAAN,EAAA,GACFI,EAAO,YADL,CAEL,aAAcd,EAAwB,OACpClE,EAAAA,KAAAC,EAAAA,SAAA,CACG,SAAA,CAAAkB,QAAagE,EAAAA,iBAAA,CAAiB,MAAM,UAAU,KAAM,GAAI,EAAK,KAC7DH,EAAO,WAAW,YAAA,CAAA,CACrB,CAAA,EAEJ,EAEF,cAAa/D,EAAa,GAAGA,CAAU,0BAA4B,OACnE,UAAY4D,GAA+B,EACrCA,EAAM,MAAQ,aAAeA,EAAM,MAAQ,WAC7CA,EAAM,gBAAA,CAEV,EACA,MAAO5B,EACP,YAAaa,EACb,GAAIV,EACJ,QAASD,CAAA,EAAA,EAIb,YAAa,IAAM,KACnB,qBAAsB,CAACT,EAAQ0C,IAAM1C,EAAO,KAAO0C,EAAE,GACrD,aAAc,CAACC,EAAO3C,EAAQ4C,IAAU,CACtC,GAAI1C,EAAoB,CACtB,MAAM2C,EAAUC,GAAAA,QAAM9C,EAAO,MAAO4C,EAAM,WAAY,CACpD,YAAa,GACb,mBAAoB,EAAA,CACrB,EACKG,GAAQC,GAAAA,QAAMhD,EAAO,MAAO6C,CAAO,EAEzC,OACEI,EAAAA,cAAC,KAAAT,EAAAN,EAAA,GACKS,GADL,CAEC,IAAK3C,EAAO,GACZ,cACEzB,EACI,GAAGA,CAAU,wBAAwByB,EAAO,GAAG,UAAU,IACzD,MAAA,SAGL,MAAA,CACE,SAAA+C,GAAM,IAAI,CAACG,GAAMC,KAChB3F,EAAAA,IAAC,OAAA,CAEC,MAAO,CACL,WAAY0F,GAAK,UAAY,IAAM,GAAA,EAGpC,SAAAA,GAAK,IAAA,EALDC,EAAA,CAOR,CAAA,CACH,CAAA,CAGN,KACE,QACEF,EAAAA,cAAC,KAAAT,EAAAN,EAAA,GACKS,GADL,CAEC,IAAK3C,EAAO,GACZ,cACEzB,EAAa,GAAGA,CAAU,WAAWyB,EAAO,GAAG,UAAU,IAAM,MAAA,GAGhEA,EAAO,KAAA,CAIhB,EACA,mBAAqBmC,GAAU,CACzBA,EAAM,SAAW3C,GAAoB,OAAS8B,IAChDa,EAAM,eAAA,EACNA,EAAM,gBAAA,EAEV,EACA,qBAAuBA,GAAU,CAC3Bb,IACFa,EAAM,eAAA,EACNA,EAAM,gBAAA,GAERd,EAAac,CAAK,CACpB,EACA,SAAAZ,CAAA,CAAA,EAEDlB,EAAM,OAAS,GACd7C,EAAAA,IAAC4F,EAAAA,IAAA,CAAI,GAAI9C,EACN,SAAAD,EAAM,IAAKgD,GAAQ,OAClB,OACE7F,EAAAA,IAAC8F,EAAAA,KAAA,CAEC,GAAI,CACF,UAAW,EACX,YAAa,EACb,OAAQ,MAAA,EAEV,MACE9F,EAAAA,IAAC+F,EAAAA,QAAA,CACC,OAAOnE,EAAAiE,EAAI,iBAAJ,KAAAjE,EAAsB,GAC7B,UAAU,eACV,UAAW+B,EAEX,SAAA3D,EAAAA,IAACC,EAAAA,WAAA,CAAW,MAAO,CAAE,WAAY,QAAA,EAC9B,SAAA4F,EAAI,UAAYA,EAAI,UAAYA,EAAI,KAAA,CACvC,CAAA,CAAA,EAGJ,cAAa9E,EAAa,GAAGA,CAAU,SAAS8E,EAAI,GAAG,SAAA,CAAU,IAAM,OACvE,SAAW1B,GAAMD,EAAaC,EAAG0B,EAAI,EAAE,EACvC,WACE7F,EAAAA,IAACgG,GAAAA,OAAA,CACC,cACEjF,EAAa,GAAGA,CAAU,SAAS8E,EAAI,GAAG,UAAU,eAAiB,MAAA,CAAA,CAEzE,EAxBGA,EAAI,EAAA,CA4Bf,CAAC,CAAA,CACH,CAAA,EAEJ,CAEJ,CC5VO,MAAMI,GAAuC,0CA0F9CC,GAAqB,CAA+C,CACxE,OAAA9D,EAAS,IAAYb,EAAA,sBAAC,GACtB,SAAAoB,EACA,cAAAC,EACA,MAAAP,EACA,MAAAQ,EACA,GAAA/B,EACA,eAAAiC,EACA,iBAAAC,EAAmB,SACnB,iBAAAC,EACA,YAAAC,EACA,MAAAK,EAAQ,GACR,cAAexC,EACf,YAAAoC,EAAc,aACd,cAAAC,EAAgB,aAChB,UAAAlB,EAAY,EACZ,cAAAuB,EAAgB,GAChB,iBAAAtB,EACA,WAAAqB,EAAa,GACb,SAAA2C,EACA,UAAA9C,EACA,gBAAAK,EACA,gBAAAE,EAAkB,OAClB,aAAAC,EAAe,IAAM,CAAC,EACtB,kCAAAC,EAAoC,GACpC,SAAAC,EACA,sBAAAC,CACF,IAA2C,CACzC,KAAM,CAAC1B,EAAY2B,CAAa,EAAIpE,EAAAA,SAAS,EAAE,EAEzC,CAAE,KAAM0E,EAAS,UAAAtD,CAAA,EAAcgB,GAAuB,CAC1D,WAAAK,EACA,MAAAD,EACA,OAAAD,EACA,UAAWF,GAAA,KAAAA,EAAa,EACxB,iBAAAC,CAAA,CACD,EAEKqC,EAAuBlC,EAAW,QAAUJ,EAElD,OACElC,EAAAA,IAAC,MAAA,CAAI,cAAae,EAChB,SAAAf,EAAAA,IAACoG,EAAAA,MAAA,CACC,UAAU,MACV,QAAS,EACT,mBAAqBzB,GAAU,CACzBA,EAAM,SAAW3C,GAAoB,OACnC8B,IACFa,EAAM,eAAA,EACNA,EAAM,gBAAA,EAGZ,EACA,qBAAuBA,GAAU,CAC3Bb,IACFa,EAAM,eAAA,EACNA,EAAM,gBAAA,GAERd,EAAac,CAAK,CACpB,EAEA,SAAA3E,EAAAA,IAACyE,EAAAA,aAAA,CACC,GAAIC,IAAA,GACC5D,GACC4C,EACA,CAAE,sCAAuC,CAAE,UAAW,cAAA,CAAe,EACrE,CAAA,GAEN,cAAa3C,EAAa,GAAGA,CAAU,gBAAkB,OACzD,QAASyD,EAAuBvD,EAAY,GAC5C,QAASsD,GAAA,KAAAA,EAAW,CAAA,EACpB,SAAU,CAACI,EAAOC,EAAUtD,IAAW,CACrCqB,EAASgC,EAAOC,EAAUtD,CAAM,CAClC,EACA,cAAAmC,EACA,cAAgBjB,GAAWA,EAC3B,MAAAK,EACA,cAAe2B,EAAuBpB,EAAgB,yBACtD,YAAAD,EACA,eAAiBX,GAAWA,EAAO,MACnC,UAAAa,EACA,YAAcyB,GACZ9E,EAAAA,IAAC+E,EAAAA,UAAAC,EAAAN,EAAA,CACC,cAAa3D,EAAa,GAAGA,CAAU,0BAA4B,QAC/D+D,GAFL,CAGC,QAAS9B,EACT,MAAAX,EACA,MAAOU,EACP,MAAAQ,EACA,WAAAC,EACA,UAAW,CACT,MAAOwB,EAAAN,EAAA,GACFI,EAAO,YADL,CAEL,aAAcd,EAAwB,OACpClE,EAAAA,KAAAC,EAAAA,SAAA,CACG,SAAA,CAAAkB,QAAagE,EAAAA,iBAAA,CAAiB,MAAM,UAAU,KAAM,GAAI,EAAK,KAC7DH,EAAO,WAAW,YAAA,CAAA,CACrB,CAAA,EAEJ,EAEF,YAAalB,EACb,GAAIV,EACJ,QAASD,CAAA,EAAA,EAGb,qBAAsB,CAACT,EAAQ0C,IAAM1C,EAAO,KAAO0C,EAAE,GACrD,cAAe,CAACP,EAAOE,EAAevD,IAAW,CAC/C2C,EAAcY,CAAa,EACvBjC,GAAeA,EAAciC,EAAevD,EAAQqD,CAAK,CAC/D,EACA,aAAc,CAACQ,EAAO3C,IACpBiD,EAAAA,cAAC,KAAAT,EAAAN,EAAA,GACKS,GADL,CAEC,IAAK3C,EAAO,GACZ,cACEzB,EACI,GAAGA,CAAU,wBAAwByB,EAAO,GAAG,UAAU,IACzD,MAAA,GAGLA,EAAO,KAAA,EAGZ,SAAA2D,EACA,SAAApC,CAAA,CAAA,CACF,CAAA,EAEJ,CAEJ,EClNasC,GAAkBC,GAAkB,CAC/C,GAAI,CAACA,EACH,MAAO,GAET,GAAI,CAEF,MAAMC,EADYD,EAAM,MAAM,GAAG,EAAE,CAAC,EACX,QAAQ,KAAM,GAAG,EAAE,QAAQ,KAAM,GAAG,EACvDE,EAAc,mBAClBC,GAAAA,OAAO,KAAKF,EAAQ,QAAQ,EACzB,SAAS,MAAM,EACf,MAAM,EAAE,EACR,IAAI,SAAUG,EAAG,CAChB,MAAO,KAAO,KAAOA,EAAE,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAC7D,CAAC,EACA,KAAK,EAAE,CAAA,EAENC,EAAoB,KAAK,MAAMH,CAAW,EAChD,OAAIG,GAAA,MAAAA,EAAmB,IACdA,EAAkB,IAEpB,EACT,OAAQxC,EAAA,CACN,MAAO,EACT,CACF,EAQMyC,GAAsB,CAAC,CAC3B,KAAAC,EAAO,GACP,aAAAC,EACA,mBAAAC,CACF,IAAgC,CAC9B,KAAM,CAAE,OAAAC,EAAQ,uBAAAC,CAAA,EAA2BC,YAAA,EAErCC,EAAoB,IAAY5F,EAAA,sBACpCyF,EAAO,CAAE,aAAc,CAAE,SAAU,GAAG,OAAO,SAAS,MAAM,EAAA,EAAM,CACpE,GASMI,EAAsB,CAC1B,KAAM,WACN,QAT0B,IAAY7F,EAAA,sBACtC,MAAM8F,EAAc,MAAMJ,EAAuB,CAAE,UAAW,MAAO,EAC/DK,EAAWjB,GAAegB,CAAW,EAAI,IAC/CN,EAAmBO,CAAQ,EAC3BR,EAAA,CACF,GAKE,SAAU,GACV,OAAQ,oBACR,YAAa,WAAA,EAGTS,EAAqB,CACzB,KAAM,UACN,QAASJ,EACT,SAAU,GACV,OAAQ,oBACR,YAAa,WAAA,EAGf,OACEnH,EAAAA,IAACK,GAAA,CACC,OAAQwG,EACR,cAAeO,EACf,gBAAiBG,EACjB,QAAST,EACT,YAAa,iBACb,+BAA8B,GAE9B,eAAC,IAAA,CAAE,MAAO,CAAE,aAAc,CAAA,EAAK,SAAA,+EAAA,CAE/B,CAAA,CAAA,CAGN,ECxGO,SAASU,GAAajE,EAAmC,CAC9D,MAAO,UAAWA,CACpB,CAOO,SAASkE,GAAoCC,EAAyB,OAC3E,MAAMnE,EAAQmE,EAAY,MACpBC,GAAmB/F,EAAA8F,GAAA,YAAAA,EAAa,oBAAb,KAAA9F,EAAkC,GAE3D,OACE2B,IAAU,iBACVoE,EAAiB,WAAW,4CAA4C,CAE5E,CAOO,SAASC,GAA+BF,EAAyB,OACtE,MAAMnE,EAAQmE,EAAY,MACpBC,GAAmB/F,EAAA8F,GAAA,YAAAA,EAAa,oBAAb,KAAA9F,EAAkC,GAE3D,OACE2B,IAAU,iBAAmBoE,EAAiB,WAAW,oCAAoC,CAEjG,CAQO,SAASE,GAAgCH,EAAyB,OACvE,MAAMnE,EAAQmE,EAAY,MACpBC,GAAmB/F,EAAA8F,GAAA,YAAAA,EAAa,oBAAb,KAAA9F,EAAkC,GAE3D,OAAO2B,IAAU,iBAAmBoE,EAAiB,MAAM,wBAAwB,CACrF,CCFA,SAAwBG,GAAU,CAChC,SAAAtH,EACA,QAAAuH,EAAU,UACV,YAAAC,EAAc,OACd,sBAAAC,EAAwB,GACxB,QAAAC,EAAU,IAAM,CAAC,CACnB,EAAsC,SACpC,KAAM,CAAE,gBAAAC,EAAiB,UAAAlH,EAAW,MAAAsC,EAAO,kBAAA6E,EAAmB,OAAApB,CAAA,EAAWE,YAAA,EAGzEmB,EAAAA,UAAU,IAAM,CAKV9E,KAAeA,CAAK,CAC1B,EAAG,CAACA,EAAO2E,CAAO,CAAC,EAEnB,MAAM3D,EAA0C+D,EAAAA,QAC9C,KAAO,CACL,SAAU,CACR,SAAU,GAAG,OAAO,SAAS,QAAQ,GAAG,OAAO,SAAS,MAAM,EAAA,CAChE,GAEF,CAAA,CAAC,EAQH,GANAD,EAAAA,UAAU,IAAM,CACVpH,GAAakH,GAAmB5E,GAEpC6E,EAAkB7D,CAAO,CAC3B,EAAG,CAACtD,EAAWkH,EAAiB5E,EAAO6E,EAAmBF,EAAS3D,CAAO,CAAC,EAEvEhB,EAAO,CAQT,GAPK0E,GACH,QAAQ,MACN,gDAAgDE,CAAe,cAAclH,CAAS,IACtFsC,CAAA,EAIAyE,IAAgB,MAClB,MAAMzE,EACR,GAAWiE,GAAajE,CAAK,EAAG,CAC9B,IAAIgF,EAAQ,aACRC,EAAU,mCAEd,GAAIf,GAAoClE,CAAK,EAC3CgF,EAAQ,eACRC,EAAU,oCAAoCT,CAAO,YAC5CH,GAA+BrE,CAAK,EAC7CgF,EAAQ,qBACRC,EAAU,2BAA2BT,CAAO,0DAA0DA,CAAO,YACpGF,GAAgCtE,CAAK,EAC9CgF,EAAQ,uCACRC,EAAU,yHACDjF,EAAM,UAAY,gBAAiB,CAC5C,MAAMkF,EAAgB,aAAa,QAAQ,sBAAsB,EAC5DA,EAGMA,GAAiB,SAASA,CAAa,EAAI,IACpD,aAAa,QAAQ,uBAAwB,OAAO,SAASA,CAAa,EAAI,CAAC,CAAC,EAChFL,EAAkB7D,CAAO,IAJzB,aAAa,QAAQ,uBAAwB,GAAG,EAChD6D,EAAkB7D,CAAO,EAK7B,SACMyD,IAAgB,UAAW,MAAMzE,EAGvC,OACEzD,EAAAA,KAACsB,EAAAA,OAAA,CAAO,KAAI,GACV,SAAA,CAAApB,EAAAA,IAACyB,EAAAA,aAAa,SAAA8G,CAAA,CAAM,SACnB7G,EAAAA,cAAA,CACC,SAAA,CAAA1B,EAAAA,IAACC,EAAAA,YAAY,SAAAuI,CAAA,CAAQ,QACpB,KAAA,EAAG,EACJxI,EAAAA,IAACC,EAAAA,WAAA,CAAW,QAAQ,YAAY,SAAA,qBAAkB,EAClDH,EAAAA,KAACG,EAAAA,WAAA,CAAW,QAAQ,QAAQ,SAAA,CAAA,WAAQ2B,EAAA2B,GAAA,YAAAA,EAAO,QAAP,KAAA3B,EAAgB,KAAA,EAAM,EAC1D9B,EAAAA,KAACG,EAAAA,WAAA,CAAW,QAAQ,QAAQ,SAAA,CAAA,iBACZyI,EAAAnF,GAAA,YAAAA,EAAO,oBAAP,KAAAmF,EAA4B,KAAA,CAAA,CAC5C,CAAA,EACF,SACC/G,EAAAA,cAAA,CACE,SAAA,CAAA4G,IAAU,wCACTvI,EAAAA,IAACE,EAAAA,OAAA,CAAO,KAAM,OAAO,SAAS,OAAS,OAAO,SAAS,SAAU,SAAA,QAAA,CAAM,EAEzEF,EAAAA,IAACE,EAAAA,OAAA,CAAO,QAAS,IAAM8G,EAAO,CAAE,aAAc,CAAE,SAAU,OAAO,SAAS,MAAA,CAAO,CAAG,EAAG,SAAA,QAAA,CAEvF,CAAA,CAAA,CACF,CAAA,EACF,CAEJ,SACMgB,IAAgB,UAAW,MAAMzE,CAEzC,CAEA,OAAI4E,GACF,aAAa,WAAW,sBAAsB,oBACpC,SAAA3H,EAAS,GAGdR,MAAC2I,GAAAA,SAAS,QAAQ,cAAc,UAAU,QAAQ,OAAO,QAAQ,MAAM,OAAA,CAAQ,CACxF,CCnJO,MAAMC,GAAuB,CAClC,iBAAkB,IAClB,aAAc,CAAE,SAAU,MAAO,WAAY,QAAA,EAI7C,0BAA2B,EAC7B,EAEaC,GAAuB,CAClC,YAAa,CAACxH,EAAsDC,IAC3DA,IAAW,WAEtB,EAEawH,GAAoC,CAC/C,QAAS,GACT,SAAU,OACV,QAAS,WACT,kBAAmB,MACrB,ECPMC,GAAmB,IACnBC,GAAgC,IAChCC,GAAiB,IAGjBC,IAA2B,IAAM,CACrC,IAAIC,EAAc,EAClB,MAAO,KACLA,GAAe,EACRA,EAEX,GAAA,EAEMC,GAA+B,CACnC,uBAAwB,MACxB,wBAAyB,KAC3B,EAGMC,GAAuB,CAAA,EACvBC,GAAyB,CAAA,EAElBC,GAAUC,EAAAA,cAAsC,IAAI,EAkBjE,SAAwBC,GAAiB7H,EAMf,CANe,IAAA8G,EAAA9G,EACvC,eAAA8H,EAAgBL,GAChB,gBAAAM,EAAkBL,GAClB,YAAAM,EAAcf,GAAqB,YACnC,SAAArI,GAJuCkI,EAKpCmB,EAAAC,GALoCpB,EAKpC,CAJH,gBACA,kBACA,cACA,mBAGA,KAAM,CAAC,CAAE,KAAA7B,CAAA,EAAQkD,CAAgB,EAAIlK,EAAAA,SAAS,CAAE,KAAM,GAAO,EAOvDmK,EAAWC,EAAAA,OAAuB,EAAE,EAEpCC,EAAiBD,EAAAA,OAAO,KAAK,IAAA,CAAK,EAClCE,EAA+BF,EAAAA,OAAO,CAAC,EAEvCG,EAAUC,cAAaC,GAAoB,CAC/CP,EAAiB,CAAE,KAAMO,EAAQ,CACnC,EAAG,CAAA,CAAE,EAECC,EAAsBF,EAAAA,YAAY,CAACG,EAA6B,CAAA,IAAO,CAC3EL,EAA6B,SAAW,EACpCH,EAAS,QAAQ,QAAUjB,IAGzB,KAAK,IAAA,EAAQmB,EAAe,SAAWlB,KACzCkB,EAAe,QAAU,KAAK,IAAA,EAC9B,QAAQ,MACN,uCAAuCnB,EAAgB,SAASoB,EAA6B,OAAO,kBAAkBnB,EAA6B,KAAA,EAErJmB,EAA6B,QAAU,GAI3C,MAAMM,EAAkB/F,EAAAM,EAAAN,EAAA,GACnBoE,IADmB,CAEtB,IAAKI,GAAA,IACFsB,GAIL,OAAAR,EAAS,QAAQ,KAAKS,CAA+B,EAIjDT,EAAS,QAAQ,SAAW,KAAoB,CAAE,KAAM,GAAM,EAE3DS,EAAgB,GACzB,EAAG,CAAA,CAAE,EAECC,EAA6B,CAAClC,EAAU,GAAIjE,EAAU,CAAA,IAC1DgG,EAAoB7F,EAAA,CAAE,QAAA8D,EAAS,SAAU,WAAcjE,EAAS,EAE5DoG,EAA0B,CAACnC,EAAU,GAAIjE,EAAU,CAAA,IACvDgG,EAAoB7F,EAAA,CAAE,QAAA8D,EAAS,SAAU,QAAWjE,EAAS,EAEzDqG,EAA6B,CAACpC,EAAU,GAAIjE,EAAU,CAAA,IAC1DgG,EAAoB7F,EAAA,CAAE,QAAA8D,EAAS,SAAU,WAAcjE,EAAS,EAE5DsG,EAA2B,CAACrC,EAAU,GAAIjE,EAAU,CAAA,IACxDgG,EAAoB7F,EAAA,CAAE,QAAA8D,EAAS,SAAU,SAAYjE,EAAS,EAU1DuG,EAAsBC,GAA6B,CACvD,MAAMpF,EAAQqE,EAAS,QAAQ,UAAW1F,GAAMA,EAAE,MAAQyG,CAAG,EAC7D,GAAIpF,IAAU,GAEd,OAAIA,IAAU,GAIZoE,EAAiB,CAAE,KAAM,GAAO,EACzBC,EAAS,QAAQ,CAAC,GAGpBA,EAAS,QAAQ,OAAOrE,EAAO,CAAC,CACzC,EAEM9E,EAAc,CAClB8D,EACArD,IACG,CACCsI,EAAYjF,EAAOrD,CAAM,KAAoB,CAAE,KAAM,GAAO,CAClE,EAGM0J,EAAa,IAAM,CAAC,EAGpBC,EAAe,IAAM,CAEzBjB,EAAS,QAAQ,MAAA,EAGbA,EAAS,QAAQ,OAAS,KAAoB,CAAE,KAAM,GAAM,CAClE,EAGMkB,GAAsBtJ,EAAAoI,EAAS,QAAQ,CAAC,IAAlB,KAAApI,EAAuB8C,EAAA,GAC9CoE,IAICqC,EAAkE,CAAA,EAEpE,qBAAsBD,IACxBC,EAAiC,iBAAmBD,EAAoB,kBAK1E,MAAME,EAAqB1G,IAAA,GACtBkE,IACAiB,GAGChH,EAAyB6B,IAAA,CAC7B,KAAAmC,EACA,QAAAuD,EACA,oBAAAG,EACA,2BAAAG,EACA,wBAAAC,EACA,2BAAAC,EACA,yBAAAC,EACA,mBAAAC,GACGpB,GACAC,GAGL,OACE7J,EAAAA,KAACyJ,GAAQ,SAAR,CAAiB,MAAA1G,EACf,SAAA,CAAArC,EACDR,EAAAA,IAACqL,EAAAA,SAAArG,EAAAN,IAAA,GACK0G,GACAD,GAFL,CAGC,KAAAtE,EACA,QAAShG,EACT,gBAAiB,CACf,SAAUoK,EACV,OAAQD,CAAA,EAEV,GAAI,CAAE,OAAQ/B,EAAA,EAEd,gBAAC,MAAA,CACC,SAAA,CAAAjJ,EAAAA,IAACsL,EAAAA,MAAA,CACC,QAAU3G,GAAU9D,EAAY8D,EAAO,YAAY,EACnD,SAAUuG,EAAoB,SAC9B,QAAS,SACT,KACEA,EAAoB,oBAAsB,iBACvCjG,EAAAA,iBAAA,CAAiB,KAAK,MAAM,EAC3B,OAEN,MACEiG,EAAoB,oBAAsB,SACtC9B,GACA,OAGL,SAAA8B,EAAoB,OAAA,CAAA,EAEtBA,EAAoB,oBAAsB,UAAYlL,EAAAA,IAACwB,EAAAA,eAAA,CAAe,MAAM,SAAA,CAAU,CAAA,CAAA,CACzF,CAAA,EAAA,CACF,EACF,CAEJ,CCvOO,MAAM+J,WAAqB,KAAM,CAExC,CADEC,GADWD,GACJ,YAAY,gBCyBd,SAASE,IAAc,CAC5B,MAAMC,EAAUC,EAAAA,WAAWpC,EAAO,EAElC,GAAImC,IAAY,KACd,MAAM,IAAIH,GAAa,6DAA6D,EAGtF,OAAOG,CACT,CC7BO,MAAME,GAAuBC,GAAAA,aAClC,CACE1G,EAA+B,CAAE,iBAAkB,GACnDC,EAA0B,CAAA,EAC1B0G,EAA4B,CAAA,IAE5B,CAAC,CAAE,SAAAtL,KAECR,EAAAA,IAACyJ,GAAAzE,EAAAN,EAAA,GAAqBS,GAArB,CAA4B,cAAeC,EAAO,gBAAiB0G,EAClE,SAAA9L,EAAAA,IAAAD,EAAAA,SAAA,CAAG,SAAAS,CAAA,CAAS,CAAA,EACd,CAGR,EChBMuL,GAAkB,oBAExB,MAAMC,GAAqBC,EAAAA,KACzB,KAAK,OAAMrK,GAAA,aAAa,QAAQmK,EAAe,IAApC,KAAAnK,GAAyC,oBAAoB,EAAE,UAC5E,EAEasK,GAAiBD,EAAAA,KAC3BE,GAAQA,EAAIH,EAAkB,EAC/B,CAACI,EAAGC,EAAKzH,IAAyB,CAChCyH,EAAIL,GAAoBpH,CAAQ,EAChC,aAAa,QAAQmH,GAAiB,KAAK,UAAU,CAAE,WAAYnH,CAAA,CAAU,CAAC,CAChF,CACF,ECFa0H,GAAqB,CAChC,IAAK,MACL,IAAK,MACL,GAAI,KACJ,IAAK,MACL,GAAI,KACJ,IAAK,MACL,IAAK,MACL,GAAI,KACJ,GAAI,KACJ,OAAQ,SACR,GAAI,EACN,EAIaC,GAAwBC,GAAkC,OACrE,OAAOA,IAAe,KAAO,OAAS5K,EAAA0K,GAAmBE,CAAU,IAA7B,KAAA5K,EAAkC,EAC1E,EAYM6K,GAAmB,CAAC,CACxB,UAAAxL,EACA,OAAAX,EACA,QAASO,EACT,eAAA6L,EACA,cAAAC,EACA,gBAAAC,EACA,aAAAC,CACF,IAAa,CACX,KAAM,CAACL,EAAYM,CAAa,EAAIC,EAAAA,QAAQb,EAAc,EACpD,CAACc,EAAoBC,CAAqB,EAAIpN,EAAAA,SAAS2M,CAAU,EACjE,CAAE,2BAAA9B,CAAA,EAA+Be,GAAA,EAEjCyB,EAAmBP,EAAc,SAAW,EAC5CQ,EACJ,EAAQX,GACR,CAACG,EAAc,SAASH,CAAU,GAClC,CAACG,EAAc,SAASK,CAAkB,EAEtCI,EAAe,CAACZ,GAAcU,GAAoBC,EAElDE,EAA0B,IAAY9L,EAAA,sBACtCyL,GACFF,EAAcE,CAAkB,EAChCN,GAAA,MAAAA,EAAiBM,GACjBtC,EAA2B,uBAAuBsC,CAAkB,EAAE,EACtEnM,EAAA,IAEAiM,EAAc,EAAE,EAChBJ,GAAA,MAAAA,EAAiB,IAErB,GAEMvF,EAAoB,IAAY5F,EAAA,sBAChCiL,GAAc,CAACU,GAAoB,CAACC,GACtCF,EAAsBT,CAAU,EAChC3L,EAAA,GACSuM,GACTP,EAAA,CAEJ,GAEA,IAAIS,EACJ,OAAIJ,EACFI,EAAe,sEACNH,IACTG,EACE,oFAIFxN,EAAAA,KAACO,GAAA,CACC,OAAAC,EACA,YAAY,yBACZ,cAAe,CACb,KAAM,UACN,QAAS+M,EACT,SAAU,CAACL,GAAsBE,GAAoBC,EACrD,YAAa,SAAA,EAEf,gBAAiB,CACf,KAAMC,EAAe,SAAW,SAChC,QAASjG,CAAA,EAEX,QAASiG,EAAe,IAAM,CAAC,EAAIvM,EAEnC,SAAA,CAAAf,EAAAA,KAACG,EAAAA,WAAA,CAAW,aAAc,EAAG,SAAA,CAAA,iEACoC2M,EAAgB,GAAA,EACjF,EAEA5M,EAAAA,IAACyE,EAAAA,aAAA,CACC,QAASxD,EACT,SAAU,GACV,iBAAkB,GAClB,MAAO+L,IAAuB,GAAKA,EAAqB,KACxD,SAAU,CAAC,EAAGnK,IAAUoK,EAAsBpK,GAAA,KAAAA,EAAS,EAAE,EACzD,eAAgB0J,GAChB,QAAS,CAAC,GAAGI,EAAc,UAAU,EACrC,YAAc7H,GACZ9E,EAAAA,IAAC+E,EAAAA,UAAAC,EAAAN,EAAA,GACKI,GADL,CAEC,QAAQ,SACR,MAAO,sBACP,WAAYE,EAAAN,EAAA,GACPI,EAAO,YADA,CAEV,aACEhF,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAAkB,EACCjB,EAAAA,IAACiF,EAAAA,iBAAA,CAAiB,MAAM,UAAU,KAAM,GAAI,GAAI,CAAE,UAAW,OAAA,CAAQ,CAAG,EACtE,KACHH,EAAO,WAAW,YAAA,CAAA,CACrB,CAAA,EAEJ,EAAA,CACF,CAAA,EAGHwI,GAAgBtN,EAAAA,IAACuN,iBAAA,CAAe,MAAK,GAAE,SAAAD,CAAA,CAAa,CAAA,CAAA,CAAA,CAG3D,EC7IaE,GAAiB,IAAM,CAClC,MAAMC,EAAQC,EAAAA,SAAA,EACd,OAAOC,EAAAA,cAAcF,EAAM,YAAY,KAAK,IAAI,CAAC,CACnD,ECcaG,GAAyB,GACzBC,GAA+B,GAC/BC,GAA6B,ICZ7BC,EAAiB9B,EAAAA,KAAK,EAAI,EAE1B+B,GAAsB/B,EAAAA,KAAK6B,EAA0B,EAErDG,GAAwBhC,EAAAA,KAAK4B,EAA4B,EAEzDK,GAAgBjC,EAAAA,KAAK,EAAE,EAEvBkC,GAAmBlC,EAAAA,KAAgB,MAAS,EAE5CmC,GAAmBnC,EAAAA,KAAK2B,EAAsB,EAG9CS,GAAgBpC,EAAAA,KAAgB,MAAS,ECb/C,SAASqC,GAAU,CAAE,MAAAC,GAAyB,CACnD,OAAOvO,EAAAA,IAAC,OAAI,SAAA,+BAAA,CAA6B,CAC3C,CCCA,MAAMwO,EAAS,SAEFC,EAAU,CACrB,KAAM,GAAGD,CAAM,QACf,WAAY,GAAGA,CAAM,cACrB,KAAM,GAAGA,CAAM,QACf,QAAS,GAAGA,CAAM,UAIpB,EAIaE,GAAkCC,EAAAA,OAAO/I,EAAAA,IAAK,CAAE,KAAM,SAAU,EAAE,CAAC,CAAE,MAAA6H,MAAa,CAC7F,CAAC,KAAKgB,EAAQ,IAAI,EAAE,EAAG,CACrB,QAAS,MAAA,EAGX,CAAC,MAAMA,EAAQ,UAAU,EAAE,EAAG,CAC5B,YAAa,EAAA,EAGf,CAAC,MAAMA,EAAQ,IAAI,EAAE,EAAG,CACtB,QAAS,MAAA,EAGX,CAAC,MAAMA,EAAQ,OAAO,EAAE,EAAG,CACzB,SAAU,EACV,QAAShB,EAAM,QAAQ,CAAC,CAAA,CAQ5B,EAAE,EAEWmB,EAAmB,CAC9BnB,EACAoB,EACAC,IAEArB,EAAM,YAAY,OAAOoB,EAAU,CACjC,OAAQpB,EAAM,YAAY,OAAO,MACjC,SACEqB,IAAW,UACPrB,EAAM,YAAY,SAAS,cAC3BA,EAAM,YAAY,SAAS,cACnC,CAAC,EAEUsB,GAAkB5J,GAAyB,CACtD,MAAMsI,EAAQC,EAAAA,SAAA,EACd,OACE1N,EAAAA,IAACgP,EAAAA,SAAAtK,EAAA,CACC,OAAQ+I,EAAM,YAAY,OAAO,MACjC,QAAS,CACP,MAAOA,EAAM,YAAY,SAAS,eAClC,KAAMA,EAAM,YAAY,SAAS,aAAA,GAE/BtI,EAAA,CAGV,EAEM8J,GAAmBxB,GAAA,SAA6B,OACpD,UAAW,SACX,MAAO,UACP,iBAAiB/E,GAAA9G,EAAA6L,GAAA,YAAAA,EAAO,SAAP,YAAA7L,EAAe,kBAAf,KAAA8G,EAAkC,OACrD,GAEMwG,GAAc,CAACzB,EAAc0B,IAA8BzK,EAAA,CAC/D,MAAAyK,EACA,WAAYP,EAAiBnB,EAAO,QAAS,UAAU,GACpDwB,GAAgBxB,CAAK,GAGpB2B,GAAc,CAAC3B,EAAc0B,IAA8BzK,EAAA,CAC/D,MAAAyK,EACA,WAAYP,EAAiBnB,EAAO,QAAS,SAAS,GACnDwB,GAAgBxB,CAAK,GAab4B,GAA2DV,EAAAA,OAAOW,SAAQ,CACrF,kBAAoBC,GAClB,CAAC,CAAC,YAAa,cAAe,eAAe,EAAE,SAASA,CAAc,CAC1E,CAAC,EAAgC,CAAC,CAAE,MAAA9B,EAAO,KAAA5G,EAAM,UAAA2I,EAAW,YAAAC,EAAa,cAAAC,KAAqBhL,IAAA,CAC5F,WAAY,EACZ,WAAY,SACZ,UAAW,aACX,QAAS,OACT,cAAe,UAEXmC,GAAQ7B,EAAAN,EAAA,GACPwK,GAAYzB,EAAO+B,CAAS,GADrB,CAEV,gBAAiB,GACjB,qBAAsBN,GAAYzB,EAAO+B,CAAS,CAAA,IAEhD,CAAC3I,GAAQ7B,EAAAN,EAAA,GACR0K,GAAY3B,EAAOiC,EAAgBF,EAAYC,CAAW,GADlD,CAEX,gBAAiB,GACjB,qBAAsBL,GAAY3B,EAAOiC,EAAgBF,EAAYC,CAAW,CAAA,GAElF,ECzHF,SAASE,GAAUC,EAAgB,CACjC,OAAOA,EAAO,QAAQ,gBAAiB,CAACxD,EAAGyD,EAAWC,IACpDD,IAAc,IAAM,IAAMC,EAAK,cAAgBA,EAAK,YAAA,CAAY,CAEpE,CAEO,SAASC,GACdC,EACAxD,EACAyD,EACAC,EACA,OACA,GAAI,CAACF,EAAQ,MAAO,OAKpB,MAAMG,EAH8B,OAAO,QAAQH,CAAM,EAAE,OACzD,CAAC,CAACI,EAAMvN,CAAK,IAAMuN,EAAK,WAAW,8BAA8B,GAAKvN,EAAM,SAAS2J,CAAU,CAAA,EAEvD,IAAI,CAAC,CAAC6D,CAAS,IAAA,OACvD,OAAAV,IAAU/N,EAAAyO,EAAU,MAAM,GAAG,EAAE,GAAG,EAAE,IAA1B,KAAAzO,EAA+B,EAAE,EAAA,EAG7C,OACEA,EAAAsO,EAAa,KAAMI,GACjBL,EAAYK,CAAS,EAAE,KAAMC,GAAiBJ,EAAM,SAASI,CAAY,CAAC,CAAA,IAD5E,KAAA3O,EAEK,MAET,CAEO,MAAM4O,GAAmBC,GAAoC,CAClE,KAAM,CAAE,iBAAAC,EAAkB,KAAAC,CAAA,EAASzJ,YAAA,EACnC,OAAO3E,YAAS,CACd,SAAU,CAAC,mBAAoBoO,GAAA,YAAAA,EAAM,GAAG,EACxC,QAAS,IAAmCpP,EAAA,sBAC1C,MAAMyO,EAAS,MAAMU,EAAA,EAErB,OAAKV,EAEE,OAAO,QAAQA,CAAM,EAAE,OAAO,CAACY,EAAM,CAACR,EAAMvN,CAAK,IAAM,OAC5D,MAAMgO,EAAWlB,IAAU/N,EAAAwO,EAAK,MAAM,GAAG,EAAE,GAAG,EAAE,IAArB,KAAAxO,EAA0B,EAAE,EACjDkP,EACJV,EAAK,WAAW,8BAA8B,GAC9CK,EAAsB,SAASI,CAAQ,EACnChO,EACA,CAAA,EACN,MAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG+N,EAAM,GAAGE,CAAO,CAAC,CAAC,CAC3C,EAAG,CAAA,CAAkB,EAVD,CAAA,CAWtB,EAAA,CACD,CACH,EAGaC,GAAyBd,GACpC,OAAO,OAAOA,CAAW,EAAE,OACzB,CAACW,EAAMI,IAAS,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGJ,EAAM,GAAGI,CAAI,CAAC,CAAC,EAC/C,CAAA,CACF,ECvDIC,EAAyC,CAC7C,IAAK,QAAQ,KAAK,KAAK,OAAO,EAC9B,MAAO,QAAQ,MAAM,KAAK,OAAO,EACjC,KAAM,QAAQ,KAAK,KAAK,OAAO,EAC/B,KAAM,QAAQ,KAAK,KAAK,OAAO,EAC/B,MAAO,QAAQ,MAAM,KAAK,OAAO,CACnC,EAUO,SAASC,GAAgBC,EAAeC,EAA8B,CAC3E,QAAQD,CAAE,EAAI,IAAIE,IAAoB,CAEpC,UAAWC,KAAUF,EACnB,GAAI,OAAOE,GAAW,YACpB,GAAIA,EAAO,GAAGD,CAAI,EAAG,eACZC,aAAkB,QAAUD,EAAK,OAAS,GACnD,UAAWE,KAAOF,EAChB,GAAI,OAAOE,GAAQ,UAAYD,EAAO,KAAKC,CAAG,EAC5C,OAMRN,EAAeE,CAAE,EAAEE,CAAI,CACzB,CACF,CAQO,SAASG,GAAkBL,EAAgB,CAChD,GAAIA,EACF,QAAQA,CAAE,EAAIF,EAAeE,CAAE,MAE/B,WAAWM,KAAK,OAAO,KAAKR,CAAc,EACxC,QAAQQ,CAAC,EAAIR,EAAeQ,CAAC,CAGnC,CC/CA,SAASC,GAAqBnO,EAAgBoO,EAAuB,CACnE,OACEpO,GAAS,MACT,OAAOA,GAAU,UACjB,UAAWA,GACVA,EAAkC,QAAUoO,CAEjD,CAYO,SAASC,GAAiBjN,EAAmBkN,EAAoC,CACtF,MAAMtO,EAAQsO,GAAA,YAAAA,EAAM,kBAIpB,OAAIH,GAAqBnO,EAAO,gBAAgB,EACvC,KAGFoB,CACT,CCnCO,SAASmN,GAAeP,EAAa,CAC1C,IAAIQ,EAAO,EACX,QAASC,EAAI,EAAGC,EAAMV,EAAI,OAAQS,EAAIC,EAAKD,IAAK,CAC9C,MAAME,EAAMX,EAAI,WAAWS,CAAC,EAC5BD,GAAQA,GAAQ,GAAKA,EAAOG,EAC5BH,GAAQ,CACV,CACA,OAAOA,CACT,CCDA,MAAMI,GAAgB,CAAC,UAAW,UAAW,UAAW,UAAW,UAAW,SAAS,EAEjFC,GAAmBhC,GACvBA,EACG,MAAM,IAAI,EACV,IAAK1K,GAASA,EAAK,UAAU,EAAG,CAAC,EAAE,YAAA,CAAa,EAChD,OAAQR,GAAM,CAAC,CAACA,CAAC,EACjB,MAAM,EAAG,CAAC,EACV,KAAK,EAAE,EACP,YAAA,EAuBL,SAAwBmN,GAAS,CAAE,KAAA1B,EAAM,WAAAnE,EAAY,KAAA3F,EAAM,aAAAyL,EAAe,IAAwB,CAChG,MAAM7E,EAAQC,EAAAA,SAAA,EACd,OACE5N,EAAAA,KAAC8F,EAAAA,IAAA,CACC,GAAI,CACF,WAAY,EACZ,QAAS,OACT,WAAY,SACZ,cAAe,SACf,IAAK,QAAA,EAGN,SAAA,CAAA,CAAC0M,GACAtS,EAAAA,IAAC4F,EAAAA,IAAA,CACC,GAAI,CACF,MAAOiB,EAAO,OAAS,OACvB,WAAYA,EACR+H,EAAiBnB,EAAO,CAAC,QAAS,QAAQ,EAAG,UAAU,EACvDmB,EAAiBnB,EAAO,CAAC,QAAS,QAAQ,EAAG,SAAS,EAC1D,YAAa,CAAA,EAGd,SAAAkD,GAAA,MAAAA,EAAM,KACL3Q,EAAAA,IAAAD,EAAAA,SAAA,CACE,SAAAC,EAAAA,IAACuS,EAAAA,OAAA,CACC,IAAK5B,GAAA,YAAAA,EAAM,QACX,GAAI,CACF,MAAO,OACP,OAAQ,OACR,QACEwB,GAAc,KAAK,IAAIL,GAAenB,GAAA,YAAAA,EAAM,IAAI,CAAC,EAAIwB,GAAc,MAAM,CAAA,EAG5E,SAAAC,GAAgBzB,GAAA,YAAAA,EAAM,IAAI,CAAA,CAAA,EAE/B,EAEA3Q,MAACuS,EAAAA,OAAA,CAAY,GAAI,CAAE,MAAO,OAAQ,OAAQ,OAAO,CAAG,CAAA,CAAA,EAIzDD,GACCtS,EAAAA,IAAC4F,EAAAA,IAAA,CACC,GAAI,CACF,MAAOiB,EAAO,OAAS,OACvB,WAAYA,EACR+H,EAAiBnB,EAAO,CAAC,QAAS,QAAQ,EAAG,UAAU,EACvDmB,EAAiBnB,EAAO,CAAC,QAAS,QAAQ,EAAG,SAAS,EAC1D,YAAa,CAAA,EAGd,oBAAM,KACLzN,MAAAD,EAAAA,SAAA,CACE,SAAAD,EAAAA,KAAC0S,WAAA,CAAO,IAAK7B,GAAA,YAAAA,EAAM,QAAS,KAAMA,GAAA,YAAAA,EAAM,KAAM,MAAO,GAAM,KAAM9J,EAAO,KAAO,KAC5E,SAAA,CAAA,IACAuL,GAAgBzB,GAAA,YAAAA,EAAM,IAAI,EAAE,IAAE,IAAA,CAAA,CACjC,CAAA,CACF,EAEA3Q,EAAAA,IAACwS,GAAAA,QAAA,CAAA,CAAO,CAAA,CAAA,EAKdxS,EAAAA,IAAC+O,IAAe,GAAI,CAAE,MAAO,MAAA,EAAU,GAAIlI,EACzC,SAAA7G,MAACyS,EAAAA,KAAA,CAAK,GAAI5L,EACR,SAAA/G,EAAAA,KAAC8F,EAAAA,KAAI,MAAM,OAAO,QAAQ,OAAO,cAAc,SAAS,WAAW,SAChE,SAAA,CAAA+K,GAAA,MAAAA,EAAM,KACL3Q,EAAAA,IAACC,EAAAA,WAAA,CAAY,SAAA0Q,GAAA,YAAAA,EAAM,IAAA,CAAK,EAExB3Q,EAAAA,IAAC2I,EAAAA,SAAA,CAAS,UAAW,GAAO,MAAO,MAAO,EAE3C6D,EACCxM,EAAAA,IAACC,EAAAA,WAAA,CAAY,SAAAsM,GAAqBC,CAAU,CAAA,CAAE,EAE9CxM,EAAAA,IAAC2I,EAAAA,SAAA,CAAS,UAAW,GAAO,MAAO,KAAA,CAAO,CAAA,CAAA,CAE9C,EACF,CAAA,CACF,CAAA,CAAA,CAAA,CAGN,CC/CA,SAAwB+J,GAAO,CAC7B,KAAA7L,EACA,YAAA4I,EACA,UAAAD,EACA,cAAezO,EACf,IAAA4R,EACA,OAAAC,EACA,OAAAC,EACA,KAAAlC,EACA,WAAAnE,EACA,aAAA8F,EAAe,EACjB,EAAgB,CACd,MAAM5C,EAAgBlC,GAAA,EAChBsF,EAAgBC,EAAAA,WAAWhF,CAAc,EAE/C,aACGW,GAAA,CAAK,UAAWD,EAAQ,KAAM,cAAa1N,EAC1C,SAAAjB,EAAAA,KAACuP,GAAA,CACC,KAAAxI,EACA,UAAA2I,EACA,YAAAC,EACA,OAAO,OACP,QAAUC,EAA8B,YAAd,YAC1B,WAAY,CACV,UAAW,KAAA,EAEb,QAAS,IAAM,CACboD,EAAc,EAAK,CACrB,EACA,cAAApD,EAEC,SAAA,CAAA,CAACA,SAAkBsD,EAAAA,QAAA,EAAQ,EAC3BL,GACC7S,EAAAA,KAAC8F,EAAAA,IAAA,CAAI,SAAS,IACX,SAAA,CAAA+M,EACD3S,MAACiT,EAAAA,SAAQ,QAAQ,SAAS,GAAI,CAAE,QAAS,SAAS,CAAG,CAAA,EACvD,EAGFjT,EAAAA,IAAC4F,EAAAA,IAAA,CAAI,SAAS,IAEX,SAAA,MAAM,QAAQgN,CAAM,EAAI5S,EAAAA,IAACsO,GAAA,CAAU,MAAOsE,CAAA,CAAmC,EAAKA,EACrF,EAEA9S,EAAAA,KAAC8F,EAAAA,IAAA,CAAI,SAAS,IACZ,SAAA,CAAA5F,MAACiT,EAAAA,SAAQ,QAAQ,SAAS,GAAI,CAAE,QAAS,UAAY,EACrDjT,EAAAA,IAACqS,GAAA,CAAS,KAAA1B,EAAY,WAAAnE,EAAwB,KAAA3F,EAAY,aAAAyL,EAA4B,EAErFO,qBAAa,SAAAA,CAAA,CAAO,CAAA,CAAA,CACvB,CAAA,CAAA,CAAA,EAEJ,CAEJ,CCxFA,SAASK,GAAc,CACrB,SAAA1S,EACA,aAAA2S,EACA,SAAA1S,EAAW,GACX,UAAA2S,CACF,EAA0C,CACxC,OACEpT,EAAAA,IAAC4F,EAAAA,IAAA,CACC,GAAI,CACF,SAAU,OACV,OAAQ,gBAAgBuN,CAAY,MACpC,SAAU,CAAA,EAGX,SAAAC,EACCpT,EAAAA,IAAC4F,EAAAA,IAAA,CAAI,UAAU,OAAO,GAAG,eAAe,OAAO,UAC5C,SAAApF,CAAA,CACH,EAEAR,EAAAA,IAACqT,EAAAA,UAAA,CACC,UAAU,OACV,GAAG,eACH,SAAA5S,EACA,GAAI,CAAE,WAAY,EAAG,cAAe,EAAG,SAAU,CAAA,EAEhD,SAAAD,CAAA,CAAA,CACH,CAAA,CAIR,CC9DA,MAAMgO,GAAS,SAgBFC,GAAU,CACrB,UAAW,GAAGD,EAAM,YACtB,EAOA,SAAwB8E,GAAO,CAC7B,UAAAC,EAAY,GACZ,OAAAC,EACA,cAAezS,EACf,OAAA6R,CACF,EAAgB,CACd,MAAME,EAAgBC,EAAAA,WAAWhF,CAAc,EAEzC0F,EAAe,IAAMX,EAAeY,GAAY,CAACA,CAAO,EACxDjG,EAAQC,EAAAA,SAAA,EACRgC,EAAgBlC,GAAA,EACtB,OACExN,EAAAA,IAAC,SAAA,CAAO,cAAae,EACnB,SAAAjB,EAAAA,KAACM,EAAAA,MAAA,CACC,OAAM,GACN,UAAW,EACX,GAAI,CACF,MAAO,OACP,SAAU,SACV,MAAO,uBACP,gBAAiB,eACjB,QAAS,OACT,WAAY,SACZ,IAAK,EACL,WAAY,EACZ,OAAAoT,EACA,OAAQ9D,EAAgB,EAAIjC,EAAM,OAAO,OAAS,EAAA,EAGpD,SAAA,CAAAzN,EAAAA,IAAC2T,EAAAA,WAAA,CACC,KAAK,SACL,MAAM,UACN,GAAI,CAAE,QAAS,IAAK,WAAY,MAAA,EAChC,QAASF,EAET,SAAAzT,EAAAA,IAAC4T,GAAAA,aAAA,CAAc,SAAS,QAAA,CAAS,CAAA,CAAA,EAEnC5T,EAAAA,IAACC,EAAAA,YAAW,UAAWwO,GAAQ,UAAW,QAAQ,KAAK,UAAU,KAC9D,SAAA8E,CAAA,CACH,EAECX,CAAA,CAAA,CAAA,EAEL,CAEJ,CCZA,SAAwBiB,GAAU,CAChC,SAAArT,EACA,iBAAAsT,EACA,kBAAAC,EACA,mBAAAC,EACA,sBAAAC,EACA,iBAAAC,EACA,iBAAAC,EACA,aAAAC,EACA,aAAAC,EACA,KAAA1D,EACA,WAAAnE,EACA,aAAA8F,EAAe,EACjB,EAAmB,CACjBgC,mBAAgB,CACd,CAACvG,EAAgBgG,GAAA,KAAAA,EAAqB,EAAI,EAC1C,CAAC7F,GAAe4F,GAAA,KAAAA,EAAoB,EAAE,CAAA,CACvC,EACD,MAAMS,EAAaC,EAAAA,aAAazG,CAAc,EACxC,CAAC0G,CAAe,EAAI1H,EAAAA,QAAQiB,EAAmB,EAC/C,CAAC0G,CAAiB,EAAI3H,EAAAA,QAAQkB,EAAqB,EACnDsF,EAAYiB,EAAAA,aAAatG,EAAa,EACtC,CAACiF,CAAY,EAAIpG,EAAAA,QAAQqB,EAAgB,EACzC,CAACuG,CAAY,EAAI5H,EAAAA,QAAQoB,EAAgB,EACzC,CAACyG,CAAS,EAAI7H,EAAAA,QAAQsB,EAAa,EAEzC,cACGzI,WAAA,CACC,SAAA,CAAA5F,EAAAA,IAAC6U,GAAAA,QAAA,EAAY,EACb7U,EAAAA,IAACsT,GAAA,CACC,UAAAC,EACA,cAAaW,EACb,OAAQf,EACR,OAAQwB,CAAA,CAAA,SAGT/O,GAAAA,QAAA,CAAI,GAAI,CAAE,QAAS,QAClB,SAAA,CAAA5F,EAAAA,IAAC0S,GAAA,CACC,KAAM6B,EACN,IAAKK,EACL,OAAQR,EACR,OAAQC,EACR,KAAA1D,EACA,WAAAnE,EACA,UAAWiI,EACX,YAAaC,EACb,UAAWvB,EACX,cAAagB,EACb,aAAA7B,CAAA,CAAA,EAGFtS,EAAAA,IAACkT,GAAAlO,EAAAN,EAAA,CACC,cAAauP,EACb,aAAAd,GACIa,GAHL,CAKE,SAAAxT,CAAA,EAAA,CACH,CAAA,CACF,CAAA,EACF,CAEJ,CC7HA,MAAMiN,GAAQqH,EAAAA,YAAY,CACxB,QAAS,CACP,QAAS,CACP,KAAM,UACN,MAAO,UACP,KAAM,UACN,aAAc,MAAA,EAEhB,QAAS,CACP,KAAM,UACN,MAAO,UACP,KAAM,UACN,aAAc,MAAA,EAEhB,UAAW,CACT,KAAM,UACN,MAAO,UACP,KAAM,UACN,aAAc,MAAA,EAEhB,MAAO,CACL,KAAM,UACN,MAAO,UACP,KAAM,UACN,aAAc,MAAA,EAEhB,KAAM,CACJ,KAAM,UACN,MAAO,UACP,KAAM,UACN,aAAc,MAAA,EAEhB,QAAS,CACP,KAAM,UACN,MAAO,UACP,KAAM,UACN,aAAc,MAAA,CAChB,EAEF,WAAY,CAIV,UAAW,CACT,SAAU,OACV,iBAAkB,KAAA,CACpB,EAGF,OAAQ,CACN,gBAAiB,SAAA,CAErB,CAAC,ECpDKrH,GAAQqH,EAAAA,YAAY,CACxB,QAAS,CACP,QAAS,CACP,KAAM,UACN,KAAM,UACN,MAAO,UACP,aAAc,SAAA,EAEhB,UAAW,CACT,KAAM,UACN,KAAM,UACN,MAAO,UACP,aAAc,SAAA,EAEhB,MAAO,CACL,KAAM,UACN,KAAM,UACN,MAAO,SAAA,EAET,KAAM,CACJ,KAAM,UACN,KAAM,UACN,MAAO,SAAA,EAET,QAAS,CACP,KAAM,UACN,KAAM,UACN,MAAO,SAAA,CACT,EAEF,WAAY,CACV,aAAc,CACZ,aAAc,CAAE,MAAO,WAAA,CAAY,EAErC,qBAAsB,CACpB,aAAc,CAAE,MAAO,WAAA,CAAY,EAErC,YAAa,CACX,aAAc,CAAE,MAAO,WAAA,CAAY,EAErC,UAAW,CACT,aAAc,CAAE,MAAO,WAAA,CAAY,EAErC,UAAW,CACT,aAAc,CAAE,MAAO,WAAA,CAAY,EAErC,eAAgB,CACd,aAAc,CAAE,MAAO,WAAA,CAAY,EAErC,YAAa,CAEX,eAAgB,CACd,KAAM,CAAC,CAAE,MAAOC,MAAiB,CAC/B,iBAAkB,CAChB,gBAAiBC,EAAAA,MACfD,EAAU,QAAQ,UAAU,KAC5BA,EAAU,QAAQ,OAAO,eAAA,EAE3B,UAAW,CACT,gBAAiBC,EAAAA,MACfD,EAAU,QAAQ,UAAU,KAC5BA,EAAU,QAAQ,OAAO,eAAA,CAC3B,EAEF,qBAAsB,CACpB,gBAAiBC,EAAAA,MACfD,EAAU,QAAQ,UAAU,KAC5BA,EAAU,QAAQ,OAAO,YAAA,CAC3B,CACF,CACF,EACF,CACF,CACF,EAEF,WAAY,CACV,GAAI,CACF,SAAU,UACV,WAAY,GAAA,EAEd,GAAI,CACF,WAAY,GAAA,EAKd,UAAW,CACT,SAAU,OACV,iBAAkB,KAAA,CACpB,EAEF,OAAQ,CACN,gBAAiB,SAAA,CAErB,CAAC"}