mgh-components 1.1.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/hooks/useResponsive.ts","../src/components/CustomNoRowsOverlay/CustomNoRowsOverlay.tsx","../src/components/MGHDataGrid/MGHDataGrid.tsx","../src/components/iconify/iconify.tsx","../src/components/Label/styles.ts","../src/components/Label/Label.tsx","../src/components/MGHGrid/utils.ts","../src/components/MGHGrid/MGHGrid.styles.ts","../src/components/MGHGrid/context.tsx","../src/components/MGHGrid/hooks.ts","../src/components/MGHGrid/export.ts","../src/components/MGHGrid/print.ts","../src/components/MGHGrid/grouping.ts","../src/components/MGHGrid/icons.tsx","../src/components/MGHGrid/components/primitives.tsx","../src/components/MGHGrid/components/Toolbar.tsx","../src/components/MGHGrid/components/Footer.tsx","../src/components/MGHGrid/components/ColumnsPanel.tsx","../src/components/MGHGrid/components/FilterPanel.tsx","../src/components/MGHGrid/components/ColumnMenu.tsx","../src/components/MGHGrid/components/Overlays.tsx","../src/components/MGHGrid/components/ActionsCell.tsx","../src/components/MGHGrid/MGHGrid.tsx","../src/components/Confirm-Dialog/confirm-dialog.tsx","../src/components/CustomGridToolbarExport/CustomGridToolbarExport.tsx","../src/components/Exporting/Exporting-Dialog.tsx"],"sourcesContent":["import useMediaQuery from '@mui/material/useMediaQuery';\nimport { useTheme, Breakpoint } from '@mui/material/styles';\n\n// ----------------------------------------------------------------------\n\ntype ReturnType = boolean;\n\nexport type Query = 'up' | 'down' | 'between' | 'only';\n\nexport type Value = Breakpoint | number;\n\nexport function useResponsive(query: Query, start?: Value, end?: Value): ReturnType {\n const theme = useTheme();\n\n const mediaUp = useMediaQuery(theme.breakpoints.up(start as Value));\n\n const mediaDown = useMediaQuery(theme.breakpoints.down(start as Value));\n\n const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Value, end as Value));\n\n const mediaOnly = useMediaQuery(theme.breakpoints.only(start as Breakpoint));\n\n if (query === 'up') {\n return mediaUp;\n }\n\n if (query === 'down') {\n return mediaDown;\n }\n\n if (query === 'between') {\n return mediaBetween;\n }\n\n return mediaOnly;\n}\n\n// ----------------------------------------------------------------------\n\ntype BreakpointOrNull = Breakpoint | null;\n\nexport function useWidth() {\n const theme = useTheme();\n\n const keys = [...theme.breakpoints.keys].reverse();\n\n return (\n keys.reduce((output: BreakpointOrNull, key: Breakpoint) => {\n const matches = useMediaQuery(theme.breakpoints.up(key));\n\n return !output && matches ? key : output;\n }, null) || 'xs'\n );\n}\n","import styled from '@emotion/styled';\n\nimport { Box } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n// import { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n\nimport React from 'react';\n// import { NoRowsOverlayPropsOverrides } from './CustomNoRowsOverlay.types';\n\n/// ---------------------------------------------------------------------------------------\n\ndeclare module '@mui/x-data-grid-premium' {\n export interface NoRowsOverlayPropsOverrides {\n text: string;\n useSettingsContext?: () => { themeMode?: string };\n }\n}\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomNoRowsOverlay({ text, useSettingsContext }: NoRowsOverlayPropsOverrides) {\n const theme = useTheme();\n const themeMode = useSettingsContext?.()?.themeMode ?? theme.palette.mode ?? 'light';\n\n const StyledGridOverlay = styled('div')(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n '& .ant-empty-img-1': {\n fill: themeMode === 'light' ? '#aeb8c2' : '#262626',\n },\n '& .ant-empty-img-2': {\n fill: themeMode === 'light' ? '#f5f5f7' : '#595959',\n },\n '& .ant-empty-img-3': {\n fill: themeMode === 'light' ? '#dce0e6' : '#434343',\n },\n '& .ant-empty-img-4': {\n fill: themeMode === 'light' ? '#fff' : '#1c1c1c',\n },\n '& .ant-empty-img-5': {\n fillOpacity: themeMode === 'light' ? '0.8' : '0.08',\n fill: themeMode === 'light' ? '#f5f5f5' : '#fff',\n },\n }));\n return (\n <StyledGridOverlay>\n <Box\n component=\"img\"\n alt=\"empty content\"\n src=\"/assets/icons/empty/ic_content.svg\"\n sx={{ width: 50, maxWidth: 160 }}\n />\n <Box sx={{ mb: 0 }}>{text}</Box>\n </StyledGridOverlay>\n );\n}\n","import React, { JSX } from 'react';\nimport dayjs from 'dayjs';\n\nimport { DateRange } from '@mui/x-date-pickers-pro';\n// `GridInitialStatePremium` itself only lives under an internal (non-exported) subpath; the\n// package re-exports it under this name from its public entry point instead.\nimport { GridInitialState as GridInitialStatePremium } from '@mui/x-data-grid-premium';\nimport { Box, Card, Theme, Badge, styled, SxProps, Tooltip, TextField, CardHeader, InputAdornment } from '@mui/material';\nimport {\n Toolbar,\n GridColDef,\n QuickFilter,\n GridRowParams,\n ToolbarButton,\n GridCloseIcon,\n GridSearchIcon,\n DataGridPremium,\n GridToolbarProps,\n QuickFilterClear,\n GridEventListener,\n GridSlotsComponent,\n FilterPanelTrigger,\n GridViewColumnIcon,\n GridFilterListIcon,\n QuickFilterControl,\n QuickFilterTrigger,\n GridCallbackDetails,\n ColumnsPanelTrigger,\n GridRowHeightParams,\n GridCsvExportOptions,\n GridRowSelectionModel,\n GridCsvExportMenuItem,\n ToolbarPropsOverrides,\n GridRowClassNameParams,\n GridExcelExportOptions,\n GridPrintExportOptions,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n GridSlotsComponentsProps,\n GridExportDisplayOptions,\n GridRowHeightReturnValue,\n GridColumnVisibilityModel,\n GridToolbarExportContainer,\n GridPinnedRowsProp,\n} from '@mui/x-data-grid-premium';\nimport { useResponsive } from '../../hooks/useResponsive';\nimport CustomNoRowsOverlay from '../CustomNoRowsOverlay/CustomNoRowsOverlay';\n\ninterface CustomToolbarProps {\n dateValues: React.SetStateAction<DateRange<dayjs.Dayjs>>;\n setDateValues: React.Dispatch<React.SetStateAction<DateRange<dayjs.Dayjs>>>;\n renderDateRange?: React.ReactNode;\n customMenuItem?: JSX.Element[];\n currentParentFolderKey?: number | null;\n types?: any;\n typeKey?: number;\n setTypeKey?: React.Dispatch<React.SetStateAction<number>>;\n userData?: unknown;\n exporting?: boolean;\n setExporting?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\ninterface MGHDataGridProps {\n rows: any[];\n columns: GridColDef[];\n onRowClick?: GridEventListener<'rowClick'>;\n onRowDoubleClick?: GridEventListener<'rowDoubleClick'>;\n header: string;\n pagination?: boolean;\n pageSize?: number;\n pageSizeOptions?: number[];\n slots?: Partial<GridSlotsComponent>;\n slotProps?: GridSlotsComponentsProps & {\n toolbar?: Partial<GridToolbarProps & ToolbarPropsOverrides & CustomToolbarProps>;\n };\n toolbarProps?: any;\n initialState?: GridInitialStatePremium;\n sx?: SxProps<Theme>;\n cardSx?: SxProps<Theme>;\n boxSx?: SxProps<Theme>;\n columnVisibilityModel?: GridColumnVisibilityModel;\n onColumnVisibilityModelChange?: (model: GridColumnVisibilityModel, details: GridCallbackDetails) => void;\n columnVisibilityStorageKey?: string;\n columnOrderStorageKey?: string;\n disableDensitySelector?: boolean;\n disableRowSelectionOnClick?: boolean;\n disableColumnFilter?: boolean;\n disableColumnMenu?: boolean;\n disableColumnSelector?: boolean;\n renderHeaderEndContent?: JSX.Element;\n renderHeaderCenterContent?: JSX.Element;\n noRowsText?: string;\n checkboxSelection?: boolean;\n checkboxSelectionVisibleOnly?: boolean;\n onRowSelectionModelChange?:\n | ((rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails<any>) => void)\n | undefined;\n rowSelectionModel?: GridRowSelectionModel | undefined;\n getRowClassName?: ((params: GridRowClassNameParams<any>) => string) | undefined;\n getDetailPanelContent?: (params: GridRowParams<any>) => React.ReactNode;\n getDetailPanelHeight?: () => number;\n loading?: boolean;\n isRowSelectable?: (params: GridRowParams<any>) => boolean;\n getRowHeight?: ((params: GridRowHeightParams) => GridRowHeightReturnValue) | undefined;\n showToolbar?: boolean;\n hideFooterRowCount?: boolean;\n onColumnOrderChange?: GridEventListener<'columnOrderChange'> | undefined;\n defaultGroupingExpansionDepth?: number;\n pinnedRows?: GridPinnedRowsProp;\n keepNonExistentRowsSelected?: boolean;\n}\n\nconst canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nconst readLocalStorage = <T,>(key: string): T | null => {\n if (!canUseLocalStorage()) {\n return null;\n }\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nconst writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) {\n return;\n }\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n return;\n }\n};\n\nconst normalizeOrderedFields = (orderedFields: string[] | null, columns: GridColDef[]) => {\n if (!orderedFields || orderedFields.length === 0) {\n return undefined;\n }\n const columnFields = new Set(columns.map((column) => column.field));\n return orderedFields.filter((field) => columnFields.has(field));\n};\n\nexport default function MGHDataGrid({\n header,\n rows,\n columns,\n onRowClick,\n onRowDoubleClick,\n pagination = true,\n pageSize = 25,\n slots = {},\n slotProps = {},\n toolbarProps = {},\n initialState = {},\n pageSizeOptions = [10, 25, 50, 100],\n sx = {},\n cardSx = { flexGrow: 1 },\n boxSx = { flexGrow: 1 },\n columnVisibilityModel,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n disableDensitySelector = false,\n disableRowSelectionOnClick = true,\n disableColumnFilter = false,\n disableColumnMenu = false,\n disableColumnSelector = false,\n checkboxSelectionVisibleOnly = false,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n noRowsText = 'No data found within selected parameters.',\n checkboxSelection = false,\n onRowSelectionModelChange = undefined,\n rowSelectionModel = undefined,\n getRowClassName = undefined,\n getDetailPanelContent,\n getDetailPanelHeight,\n loading = false,\n isRowSelectable = undefined,\n getRowHeight,\n showToolbar = true,\n hideFooterRowCount = false,\n onColumnOrderChange = undefined,\n defaultGroupingExpansionDepth = undefined,\n pinnedRows = undefined,\n keepNonExistentRowsSelected = true,\n}: MGHDataGridProps) {\n const smDown = useResponsive('down', 'sm');\n const persistedColumnVisibilityModel = React.useMemo(() => {\n if (!columnVisibilityStorageKey) {\n return undefined;\n }\n return readLocalStorage<GridColumnVisibilityModel>(columnVisibilityStorageKey) ?? undefined;\n }, [columnVisibilityStorageKey]);\n\n const persistedOrderedFields = React.useMemo(() => {\n if (!columnOrderStorageKey) {\n return undefined;\n }\n const storedOrder = readLocalStorage<string[]>(columnOrderStorageKey);\n return normalizeOrderedFields(storedOrder, columns);\n }, [columnOrderStorageKey, columns]);\n\n const resolvedColumnVisibilityModel =\n columnVisibilityModel !== undefined ? columnVisibilityModel : persistedColumnVisibilityModel;\n\n const handleColumnVisibilityModelChange = React.useCallback(\n (model: GridColumnVisibilityModel, details: GridCallbackDetails) => {\n if (columnVisibilityStorageKey) {\n writeLocalStorage(columnVisibilityStorageKey, model);\n }\n onColumnVisibilityModelChange?.(model, details);\n },\n [columnVisibilityStorageKey, onColumnVisibilityModelChange]\n );\n\n const handleColumnOrderChange = React.useCallback<GridEventListener<'columnOrderChange'>>(\n (params, event, details) => {\n if (columnOrderStorageKey) {\n const orderedFields = details.api.getAllColumns().map((column) => column.field);\n writeLocalStorage(columnOrderStorageKey, orderedFields);\n }\n onColumnOrderChange?.(params, event, details);\n },\n [columnOrderStorageKey, onColumnOrderChange]\n );\n\n const mergedInitialState: GridInitialStatePremium = {\n density: 'compact',\n pagination: { paginationModel: { pageSize } },\n filter: {\n filterModel: {\n items: [],\n quickFilterExcludeHiddenColumns: false,\n },\n },\n ...initialState,\n columns: {\n ...initialState?.columns,\n columnVisibilityModel: resolvedColumnVisibilityModel ?? initialState?.columns?.columnVisibilityModel,\n orderedFields: persistedOrderedFields ?? initialState?.columns?.orderedFields,\n },\n };\n\n return (\n <Card sx={{ height: 'auto', ...cardSx }}>\n <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', pr: 1 }}>\n <CardHeader title={header} sx={{ mb: 2 }} />\n {renderHeaderCenterContent}\n <Box\n sx={{\n display: 'flex',\n gap: smDown ? 1 : 2,\n alignItems: 'center',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n }}\n >\n {renderHeaderEndContent}\n </Box>\n </Box>\n <Box component=\"div\" sx={{ display: 'flex', flexDirection: 'column', flexGrow: 1, ...boxSx }}>\n <DataGridPremium\n loading={loading}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n rows={rows}\n columns={columns}\n pagination={pagination}\n disableDensitySelector={disableDensitySelector}\n disableRowSelectionOnClick={disableRowSelectionOnClick}\n disableColumnFilter={disableColumnFilter}\n disableColumnMenu={disableColumnMenu}\n disableColumnSelector={disableColumnSelector}\n slots={{ noRowsOverlay: CustomNoRowsOverlay, toolbar: MGHGridToolbar, ...slots }}\n slotProps={{ noRowsOverlay: { text: noRowsText }, toolbar: toolbarProps, ...slotProps }}\n initialState={mergedInitialState}\n pageSizeOptions={pageSizeOptions}\n sx={{\n '& .MuiDataGrid-row:hover': {\n cursor: onRowClick || onRowDoubleClick ? 'pointer' : 'default',\n },\n ...sx,\n }}\n \n onColumnVisibilityModelChange={handleColumnVisibilityModelChange}\n checkboxSelection={checkboxSelection}\n onRowSelectionModelChange={onRowSelectionModelChange}\n rowSelectionModel={rowSelectionModel}\n isRowSelectable={isRowSelectable}\n getRowClassName={getRowClassName}\n getDetailPanelContent={getDetailPanelContent}\n getDetailPanelHeight={getDetailPanelHeight}\n checkboxSelectionVisibleOnly={checkboxSelectionVisibleOnly}\n disableRowSelectionExcludeModel\n showToolbar={showToolbar}\n hideFooterRowCount={hideFooterRowCount}\n getRowHeight={getRowHeight}\n onColumnOrderChange={handleColumnOrderChange}\n defaultGroupingExpansionDepth={defaultGroupingExpansionDepth}\n pinnedRows={pinnedRows}\n keepNonExistentRowsSelected={keepNonExistentRowsSelected}\n />\n </Box>\n </Card>\n );\n}\n\ninterface MGHGridToolbarProps {\n showColumnsButton?: boolean;\n showFilterButton?: boolean;\n showExportButton?: boolean;\n showQuickFilter?: boolean;\n renderOtherButtons?: JSX.Element;\n renderDateRange?: JSX.Element;\n customMenuItem?: JSX.Element[];\n showCsvOption?: boolean;\n}\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n showCsvOption = true,\n}: MGHGridToolbarProps) {\n return (\n <Toolbar style={{ display: 'flex', justifyContent: 'space-between' }}>\n <div>\n {showColumnsButton && (\n <Tooltip title=\"Columns\">\n <ColumnsPanelTrigger render={<ToolbarButton />}>\n <GridViewColumnIcon fontSize=\"small\" />\n </ColumnsPanelTrigger>\n </Tooltip>\n )}\n {showFilterButton && (\n <Tooltip title=\"Filters\">\n <FilterPanelTrigger\n render={(props, state) => (\n <ToolbarButton {...props} color=\"default\">\n <Badge badgeContent={state.filterCount} color=\"primary\" variant=\"dot\">\n <GridFilterListIcon fontSize=\"small\" />\n </Badge>\n </ToolbarButton>\n )}\n />\n </Tooltip>\n )}\n {showExportButton && (\n <CustomGridToolbarExport customMenuItem={customMenuItem} showCsvOption={showCsvOption} />\n )}\n </div>\n\n {renderDateRange}\n\n <div>\n {renderOtherButtons}\n {showQuickFilter && <DataGridQuickFilter />}\n </div>\n </Toolbar>\n );\n}\n\ninterface ExportContainerProps {\n csvOptions?: GridCsvExportOptions & GridExportDisplayOptions;\n excelOptions?: GridExcelExportOptions & GridExportDisplayOptions;\n printOptions?: GridPrintExportOptions & GridExportDisplayOptions;\n customMenuItem?: JSX.Element[] | undefined;\n showCsvOption?: boolean;\n}\nexport const CustomGridToolbarExport = ({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n customMenuItem,\n showCsvOption = true,\n ...other\n}: ExportContainerProps) => (\n <GridToolbarExportContainer {...other}>\n {customMenuItem?.map((el) => el)}\n {showCsvOption && <GridCsvExportMenuItem options={csvOptions} />}\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n);\n\nexport function DataGridQuickFilter() {\n type OwnerState = {\n expanded: boolean;\n };\n\n const StyledQuickFilter = styled(QuickFilter)({\n display: 'grid',\n alignItems: 'center',\n });\n\n const StyledToolbarButton = styled(ToolbarButton)<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n width: 'min-content',\n height: 'min-content',\n zIndex: 1,\n opacity: ownerState.expanded ? 0 : 1,\n pointerEvents: ownerState.expanded ? 'none' : 'auto',\n transition: theme.transitions.create(['opacity']),\n }));\n\n const StyledTextField = styled(TextField)<{\n ownerState: OwnerState;\n }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n overflowX: 'clip',\n width: ownerState.expanded ? 260 : 'var(--trigger-width)',\n opacity: ownerState.expanded ? 1 : 0,\n transition: theme.transitions.create(['width', 'opacity']),\n }));\n\n return (\n <StyledQuickFilter>\n <QuickFilterTrigger\n render={(triggerProps, state) => (\n <Tooltip title=\"Search\" enterDelay={0}>\n <StyledToolbarButton\n {...triggerProps}\n ownerState={{ expanded: state.expanded }}\n color=\"default\"\n aria-disabled={state.expanded}\n >\n <GridSearchIcon fontSize=\"small\" />\n </StyledToolbarButton>\n </Tooltip>\n )}\n />\n <QuickFilterControl\n render={({ ref, ...controlProps }, state) => (\n <StyledTextField\n {...controlProps}\n ownerState={{ expanded: state.expanded }}\n inputRef={ref}\n aria-label=\"Search\"\n placeholder=\"Search...\"\n size=\"small\"\n slotProps={{\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <GridSearchIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n endAdornment: state.value ? (\n <InputAdornment position=\"end\">\n <QuickFilterClear\n edge=\"end\"\n size=\"small\"\n aria-label=\"Clear search\"\n material={{ sx: { marginRight: -0.75 } }}\n >\n <GridCloseIcon fontSize=\"small\" />\n </QuickFilterClear>\n </InputAdornment>\n ) : null,\n ...controlProps.slotProps?.input,\n },\n ...controlProps.slotProps,\n }}\n />\n )}\n />\n </StyledQuickFilter>\n );\n}\n","import { forwardRef } from 'react';\nimport { Icon } from '@iconify/react';\n\nimport { IconifyProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\ninterface Props {\n icon: IconifyProps;\n width?: number;\n height?: number;\n sx?: any;\n}\n\nconst Iconify = forwardRef<SVGElement, Props>(({ icon, width = 20, sx, ...other }, ref) => (\n <Icon icon={icon} style={{ width: 20, height: width ?? 20, ...sx }} />\n));\n\nexport default Iconify;\n","import type { ComponentProps, ComponentType } from 'react';\nimport Box from '@mui/material/Box';\nimport { alpha, styled, useTheme } from '@mui/material/styles';\nimport { LabelColor, LabelVariant } from './types';\n\n// ----------------------------------------------------------------------\n\ninterface StyledLabelOwnerState {\n color: LabelColor;\n variant: LabelVariant;\n}\n\n// Explicitly annotated so TS doesn't need to synthesize (and re-print) an anonymous type that\n// references @mui/system's install path — under pnpm that path is store-relative and triggers\n// TS2742 (\"inferred type cannot be named without a reference to ...\") during declaration emit.\nexport const StyledLabel = styled(Box)(({\n // theme,\n ownerState,\n}: {\n // theme: Theme;\n ownerState: StyledLabelOwnerState;\n}) => {\n const theme = useTheme();\n\n const lightMode = theme.palette.mode === 'light';\n\n const filledVariant = ownerState.variant === 'filled';\n\n const outlinedVariant = ownerState.variant === 'outlined';\n\n const softVariant = ownerState.variant === 'soft';\n\n const defaultStyle = {\n ...(ownerState.color === 'default' && {\n // FILLED\n ...(filledVariant && {\n color: lightMode ? theme.palette.common.white : theme.palette.grey[800],\n backgroundColor: theme.palette.text.primary,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette.text.primary,\n border: `2px solid ${theme.palette.text.primary}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.grey[500], 0.16),\n }),\n }),\n };\n\n const colorStyle = {\n ...(ownerState.color !== 'default' && {\n // FILLED\n ...(filledVariant && {\n color: theme.palette[ownerState.color].contrastText,\n backgroundColor: theme.palette[ownerState.color].main,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette[ownerState.color].main,\n border: `2px solid ${theme.palette[ownerState.color].main}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette[ownerState.color][lightMode ? 'dark' : 'light'],\n backgroundColor: alpha(theme.palette[ownerState.color].main, 0.16),\n }),\n }),\n };\n\n return {\n height: 24,\n minWidth: 24,\n lineHeight: 0,\n borderRadius: 6,\n cursor: 'default',\n alignItems: 'center',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n justifyContent: 'center',\n textTransform: 'capitalize',\n padding: theme.spacing(0, 0.75),\n fontSize: theme.typography.pxToRem(12),\n fontWeight: theme.typography.fontWeightBold,\n transition: theme.transitions.create('all', {\n duration: theme.transitions.duration.shorter,\n }),\n ...defaultStyle,\n ...colorStyle,\n };\n}) as ComponentType<ComponentProps<typeof Box> & { ownerState: StyledLabelOwnerState }>;\n","import { forwardRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { LabelProps } from './types';\nimport { StyledLabel } from './styles';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nconst Label = forwardRef<HTMLSpanElement, LabelProps>(\n ({ children, color = 'default', variant = 'soft', startIcon, endIcon, sx, ...other }, ref) => {\n // const theme = useTheme();\n\n const iconStyles = {\n width: 16,\n height: 16,\n '& svg, img': { width: 1, height: 1, objectFit: 'cover' },\n };\n\n return (\n <StyledLabel\n ref={ref}\n // component=\"span\"\n ownerState={{ color, variant }}\n sx={{\n ...(startIcon && { pl: 0.75 }),\n ...(endIcon && { pr: 0.75 }),\n ...sx,\n }}\n // theme={theme}\n {...other}\n >\n {startIcon && <Box sx={{ mr: 0.75, ...iconStyles }}> {startIcon} </Box>}\n\n {children}\n\n {endIcon && <Box sx={{ ml: 0.75, ...iconStyles }}> {endIcon} </Box>}\n </StyledLabel>\n );\n }\n);\n\nexport default Label;\n","import dayjs from 'dayjs';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridColType,\n MGHGridComparatorFn,\n MGHGridFilterItem,\n MGHGridFilterOperator,\n MGHGridLocaleText,\n MGHGridRowId,\n MGHGridRowSelectionModel,\n MGHGridRowSelectionModelInput,\n MGHGridValidRowModel,\n MGHGridValueOption,\n MGHGridValueOptionObject,\n} from './MGHGrid.types';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * ----------------------------------------------------------------------------------------------- */\n\nexport const GROUPING_COLUMN_FIELD = '__row_group_by_columns_group__';\nexport const CHECKBOX_FIELD = '__check__';\nexport const DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';\nexport const AGGREGATION_FOOTER_ID = '__aggregation_footer__';\nexport const INTERNAL_FIELDS = new Set<string>([CHECKBOX_FIELD, DETAIL_PANEL_TOGGLE_FIELD]);\n\nexport const DENSITY_FACTORS = { compact: 0.7, standard: 1, comfortable: 1.3 } as const;\nexport const DEFAULT_ROW_HEIGHT = 52;\nexport const DEFAULT_HEADER_HEIGHT = 56;\nexport const DEFAULT_COLUMN_WIDTH = 100;\nexport const DEFAULT_COLUMN_MIN_WIDTH = 50;\nexport const CHECKBOX_COLUMN_WIDTH = 50;\nexport const DETAIL_TOGGLE_COLUMN_WIDTH = 50;\nexport const GROUPING_COLUMN_WIDTH = 220;\n\nexport const isInternalField = (field: string) => INTERNAL_FIELDS.has(field) || field === GROUPING_COLUMN_FIELD;\n\n/* -------------------------------------------------------------------------------------------------\n * Generic helpers\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isEmptyValue = (value: unknown) => isNil(value) || value === '' || (Array.isArray(value) && value.length === 0);\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const arraysEqual = <T>(a: T[] | undefined, b: T[] | undefined) => {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\nexport const moveItem = <T>(list: T[], from: number, to: number): T[] => {\n const next = list.slice();\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next;\n};\n\nexport const uniqueId = (() => {\n let counter = 0;\n return (prefix = 'mgh') => {\n counter += 1;\n return `${prefix}-${counter}`;\n };\n})();\n\n/* -------------------------------------------------------------------------------------------------\n * Local storage\n * ----------------------------------------------------------------------------------------------- */\n\nexport const canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nexport const readLocalStorage = <T>(key: string): T | null => {\n if (!canUseLocalStorage()) return null;\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nexport const writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore quota / privacy errors */\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Rows\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getRowIdFromRow = <R extends MGHGridValidRowModel>(row: R, getRowId?: (row: R) => MGHGridRowId) =>\n getRowId ? getRowId(row) : (row.id as MGHGridRowId);\n\nexport const normalizeSelectionModel = (\n input: MGHGridRowSelectionModelInput | undefined,\n allIds?: MGHGridRowId[]\n): MGHGridRowSelectionModel => {\n if (!input) return { type: 'include', ids: new Set() };\n if (Array.isArray(input)) return { type: 'include', ids: new Set(input) };\n if (input instanceof Set) return { type: 'include', ids: new Set(input) };\n if (input.type === 'exclude' && allIds) {\n const ids = new Set<MGHGridRowId>();\n allIds.forEach((id) => {\n if (!input.ids.has(id)) ids.add(id);\n });\n return { type: 'include', ids };\n }\n return { type: 'include', ids: new Set(input.ids) };\n};\n\nexport const selectionModelsEqual = (a: MGHGridRowSelectionModel, b: MGHGridRowSelectionModel) => {\n if (a.ids.size !== b.ids.size) return false;\n let equal = true;\n a.ids.forEach((id) => {\n if (!b.ids.has(id)) equal = false;\n });\n return equal;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Dates\n * ----------------------------------------------------------------------------------------------- */\n\nexport const toDate = (value: unknown): Date | null => {\n if (isNil(value) || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n if (dayjs.isDayjs(value)) return value.isValid() ? value.toDate() : null;\n if (typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n if (typeof value === 'string') {\n const parsed = dayjs(value);\n return parsed.isValid() ? parsed.toDate() : null;\n }\n return null;\n};\n\nexport const formatDate = (value: unknown, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n return dayjs(date).format(withTime ? 'M/D/YYYY h:mm A' : 'M/D/YYYY');\n};\n\nconst startOfUnit = (date: Date, withTime: boolean) =>\n withTime ? dayjs(date).startOf('minute').valueOf() : dayjs(date).startOf('day').valueOf();\n\n/* -------------------------------------------------------------------------------------------------\n * Value options (singleSelect)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isValueOptionObject = (option: MGHGridValueOption): option is MGHGridValueOptionObject =>\n typeof option === 'object' && option !== null;\n\nexport const getOptionValue = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionValue ? col.getOptionValue(option) : isValueOptionObject(option) ? option.value : option;\n\nexport const getOptionLabel = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionLabel ? col.getOptionLabel(option) : isValueOptionObject(option) ? option.label : String(option);\n\nexport const resolveValueOptions = (col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (!col.valueOptions) return [] as MGHGridValueOption[];\n return typeof col.valueOptions === 'function' ? col.valueOptions({ field: col.field, row, id }) : col.valueOptions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Cell values\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getCellValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n const raw = row ? row[col.field] : undefined;\n return col.valueGetter ? col.valueGetter(raw, row, col, api) : raw;\n};\n\nexport const getGroupingValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n if (col.groupingValueGetter) return col.groupingValueGetter(row[col.field], row, col, api);\n return getCellValue(row, col, api);\n};\n\nexport const defaultFormatValue = (value: any, col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (isNil(value)) return '';\n switch (col.type) {\n case 'date':\n return formatDate(value, false);\n case 'dateTime':\n return formatDate(value, true);\n case 'boolean':\n return value ? 'Yes' : 'No';\n case 'singleSelect': {\n const options = resolveValueOptions(col, row, id);\n const match = options.find((option) => getOptionValue(col, option) === value);\n return match !== undefined ? getOptionLabel(col, match) : String(value);\n }\n case 'number':\n return typeof value === 'number' ? (Number.isFinite(value) ? String(value) : '') : String(value);\n default:\n if (value instanceof Date) return formatDate(value, true);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n }\n};\n\nexport const getFormattedValue = (\n value: any,\n row: MGHGridValidRowModel,\n col: MGHGridColDef,\n api: MGHGridApi,\n id?: MGHGridRowId\n) => {\n if (col.valueFormatter) return col.valueFormatter(value, row, col, api);\n return defaultFormatValue(value, col, row, id);\n};\n\nexport const formattedValueToString = (formatted: any): string => {\n if (isNil(formatted)) return '';\n if (typeof formatted === 'string') return formatted;\n if (typeof formatted === 'number' || typeof formatted === 'boolean') return String(formatted);\n if (formatted instanceof Date) return formatDate(formatted, true);\n if (typeof formatted === 'object' && 'props' in formatted) return '';\n return String(formatted);\n};\n\nexport const parseEditValue = (raw: any, col: MGHGridColDef) => {\n switch (col.type) {\n case 'number': {\n if (raw === '' || isNil(raw)) return null;\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case 'boolean':\n return Boolean(raw);\n case 'date':\n case 'dateTime': {\n if (raw === '' || isNil(raw)) return null;\n const d = toDate(raw);\n return d ?? raw;\n }\n default:\n return raw;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Sorting\n * ----------------------------------------------------------------------------------------------- */\n\nconst collator = typeof Intl !== 'undefined' ? new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }) : null;\n\nconst nilFirst = (v1: any, v2: any): number | null => {\n const n1 = isNil(v1) || v1 === '';\n const n2 = isNil(v2) || v2 === '';\n if (n1 && n2) return 0;\n if (n1) return -1;\n if (n2) return 1;\n return null;\n};\n\nexport const numberComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(v1) - Number(v2);\n};\n\nexport const stringComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n const s1 = String(v1);\n const s2 = String(v2);\n if (collator) return collator.compare(s1, s2);\n return s1 < s2 ? -1 : s1 > s2 ? 1 : 0;\n};\n\nexport const stringOrNumberComparator: MGHGridComparatorFn = (v1, v2, p1, p2) => {\n if (typeof v1 === 'number' && typeof v2 === 'number') return numberComparator(v1, v2, p1, p2);\n return stringComparator(v1, v2, p1, p2);\n};\n\nexport const dateComparator: MGHGridComparatorFn = (v1, v2) => {\n const d1 = toDate(v1);\n const d2 = toDate(v2);\n const nil = nilFirst(d1, d2);\n if (nil !== null) return nil;\n return (d1 as Date).getTime() - (d2 as Date).getTime();\n};\n\nexport const booleanComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(Boolean(v1)) - Number(Boolean(v2));\n};\n\nexport const getDefaultComparator = (type: MGHGridColType | undefined): MGHGridComparatorFn => {\n switch (type) {\n case 'number':\n return numberComparator;\n case 'date':\n case 'dateTime':\n return dateComparator;\n case 'boolean':\n return booleanComparator;\n default:\n return stringOrNumberComparator;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Filter operators\n * ----------------------------------------------------------------------------------------------- */\n\nconst lower = (value: unknown) => (isNil(value) ? '' : String(value).toLowerCase());\n\nconst hasValue = (item: MGHGridFilterItem) => !isEmptyValue(item.value);\n\nexport const stringFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'contains',\n label: 'contains',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) !== -1;\n },\n },\n {\n value: 'doesNotContain',\n label: 'does not contain',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === -1;\n },\n },\n {\n value: 'equals',\n label: 'equals',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) === needle;\n },\n },\n {\n value: 'doesNotEqual',\n label: 'does not equal',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) !== needle;\n },\n },\n {\n value: 'startsWith',\n label: 'starts with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === 0;\n },\n },\n {\n value: 'endsWith',\n label: 'ends with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => {\n const s = lower(value);\n return s.length >= needle.length && s.lastIndexOf(needle) === s.length - needle.length;\n };\n },\n },\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(lower));\n return (value) => set.has(lower(value));\n },\n },\n];\n\nconst numberOperator = (\n value: string,\n label: string,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: 'number',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterValue = Number(item.value);\n if (Number.isNaN(filterValue)) return null;\n return (cell) => {\n if (isNil(cell) || cell === '') return false;\n const n = Number(cell);\n return !Number.isNaN(n) && compare(n, filterValue);\n };\n },\n});\n\nexport const numberFilterOperators: MGHGridFilterOperator[] = [\n numberOperator('=', '=', (a, b) => a === b),\n numberOperator('!=', '!=', (a, b) => a !== b),\n numberOperator('>', '>', (a, b) => a > b),\n numberOperator('>=', '>=', (a, b) => a >= b),\n numberOperator('<', '<', (a, b) => a < b),\n numberOperator('<=', '<=', (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map((v: any) => Number(v)));\n return (value) => !isNil(value) && set.has(Number(value));\n },\n },\n];\n\nconst dateOperator = (\n value: string,\n label: string,\n withTime: boolean,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: withTime ? 'datetime-local' : 'date',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterDate = toDate(item.value);\n if (!filterDate) return null;\n const filterTime = startOfUnit(filterDate, withTime);\n return (cell) => {\n const cellDate = toDate(cell);\n if (!cellDate) return false;\n return compare(startOfUnit(cellDate, withTime), filterTime);\n };\n },\n});\n\nexport const getDateFilterOperators = (withTime: boolean): MGHGridFilterOperator[] => [\n dateOperator('is', 'is', withTime, (a, b) => a === b),\n dateOperator('not', 'is not', withTime, (a, b) => a !== b),\n dateOperator('after', 'is after', withTime, (a, b) => a > b),\n dateOperator('onOrAfter', 'is on or after', withTime, (a, b) => a >= b),\n dateOperator('before', 'is before', withTime, (a, b) => a < b),\n dateOperator('onOrBefore', 'is on or before', withTime, (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) === null,\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) !== null,\n },\n];\n\nexport const booleanFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'boolean',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '' || item.value === 'any') return null;\n const expected = item.value === true || item.value === 'true';\n return (value) => Boolean(value) === expected;\n },\n },\n];\n\nexport const singleSelectFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) === String(item.value);\n },\n },\n {\n value: 'not',\n label: 'is not',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) !== String(item.value);\n },\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(String));\n return (value) => set.has(String(value));\n },\n },\n];\n\nexport const getDefaultFilterOperators = (type: MGHGridColType | undefined): MGHGridFilterOperator[] => {\n switch (type) {\n case 'number':\n return numberFilterOperators;\n case 'date':\n return getDateFilterOperators(false);\n case 'dateTime':\n return getDateFilterOperators(true);\n case 'boolean':\n return booleanFilterOperators;\n case 'singleSelect':\n return singleSelectFilterOperators;\n case 'actions':\n return [];\n default:\n return stringFilterOperators;\n }\n};\n\nexport const getColumnFilterOperators = (col: MGHGridColDef) => col.filterOperators ?? getDefaultFilterOperators(col.type);\n\n/* -------------------------------------------------------------------------------------------------\n * Column normalisation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const normalizeColumn = <R extends MGHGridValidRowModel>(col: MGHGridColDef<R>): MGHGridColDef<R> => {\n const type = col.type ?? 'string';\n const isNumber = type === 'number';\n const isBoolean = type === 'boolean';\n const isActions = type === 'actions';\n return {\n ...col,\n type,\n headerName: col.headerName ?? col.field,\n width: col.width ?? (isActions ? 100 : isBoolean ? 100 : DEFAULT_COLUMN_WIDTH),\n minWidth: col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n align: col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n headerAlign: col.headerAlign ?? col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n sortable: isActions ? false : (col.sortable ?? true),\n filterable: isActions ? false : (col.filterable ?? true),\n hideable: col.hideable ?? true,\n resizable: col.resizable ?? true,\n pinnable: col.pinnable ?? true,\n groupable: isActions ? false : (col.groupable ?? true),\n aggregable: isActions ? false : (col.aggregable ?? true),\n editable: col.editable ?? false,\n disableColumnMenu: col.disableColumnMenu ?? isActions,\n disableExport: col.disableExport ?? isActions,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Internal (auto-generated) columns\n * ----------------------------------------------------------------------------------------------- */\n\nconst internalColumn = (field: string, width: number): MGHGridColDef =>\n normalizeColumn({\n field,\n headerName: '',\n width,\n minWidth: width,\n maxWidth: width,\n sortable: false,\n filterable: false,\n hideable: false,\n resizable: false,\n pinnable: false,\n groupable: false,\n aggregable: false,\n disableColumnMenu: true,\n disableExport: true,\n disableReorder: true,\n align: 'center',\n headerAlign: 'center',\n });\n\n/** Definition of the checkbox-selection column (equivalent of MUI's GRID_CHECKBOX_SELECTION_COL_DEF). */\nexport const CHECKBOX_COLUMN_DEF: MGHGridColDef = internalColumn(CHECKBOX_FIELD, CHECKBOX_COLUMN_WIDTH);\n/** Definition of the detail-panel toggle column (equivalent of MUI's GRID_DETAIL_PANEL_TOGGLE_COL_DEF). */\nexport const DETAIL_PANEL_TOGGLE_COLUMN_DEF: MGHGridColDef = internalColumn(\n DETAIL_PANEL_TOGGLE_FIELD,\n DETAIL_TOGGLE_COLUMN_WIDTH\n);\n\n/* -------------------------------------------------------------------------------------------------\n * sx -> scoped CSS\n * ----------------------------------------------------------------------------------------------- */\n\nconst UNITLESS_PROPERTIES = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n]);\n\n/** Keys that are CSS selectors / at-rules rather than CSS properties. */\nexport const isSelectorKey = (key: string) => /[&.:#>\\[\\s*~+,@]/.test(key);\n\nconst toKebabCase = (property: string) => {\n if (property.indexOf('--') === 0) return property;\n const kebab = property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n return kebab.indexOf('ms-') === 0 ? `-${kebab}` : kebab;\n};\n\nconst formatCssValue = (property: string, value: string | number) =>\n typeof value === 'number' && value !== 0 && !UNITLESS_PROPERTIES.has(property) && property.indexOf('--') !== 0\n ? `${value}px`\n : String(value);\n\nconst serializeDeclarations = (block: Record<string, unknown>) =>\n Object.keys(block)\n .filter((key) => {\n const value = block[key];\n return !isSelectorKey(key) && (typeof value === 'string' || typeof value === 'number');\n })\n .map((key) => `${toKebabCase(key)}:${formatCssValue(key, block[key] as string | number)}`)\n .join(';');\n\nconst scopeSelector = (scope: string, selector: string) =>\n selector\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => (part.indexOf('&') !== -1 ? part.replace(/&/g, scope) : `${scope} ${part}`))\n .join(',');\n\n/**\n * Compiles the nested-selector part of an `sx`-like object into CSS scoped under `scope`.\n * Top-level plain properties are ignored here (they are applied as inline styles instead).\n */\nexport const buildScopedCss = (scope: string, sx: Record<string, unknown> | undefined, out: string[] = []): string[] => {\n if (!sx) return out;\n Object.keys(sx).forEach((key) => {\n const value = sx[key];\n if (!value || typeof value !== 'object') return;\n const block = value as Record<string, unknown>;\n if (key.charAt(0) === '@') {\n const inner: string[] = [];\n const declarations = serializeDeclarations(block);\n if (declarations) inner.push(`${scope}{${declarations}}`);\n buildScopedCss(scope, block, inner);\n if (inner.length) out.push(`${key}{${inner.join('')}}`);\n return;\n }\n const selector = scopeSelector(scope, key);\n const declarations = serializeDeclarations(block);\n if (declarations) out.push(`${selector}{${declarations}}`);\n buildScopedCss(selector, block, out);\n });\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nconst numericValues = (values: any[]) =>\n values.map((v) => (typeof v === 'number' ? v : Number(v))).filter((n) => !Number.isNaN(n) && n !== null);\n\nexport const BUILT_IN_AGGREGATION_FUNCTIONS: Record<string, MGHGridAggregationFunction> = {\n sum: {\n label: 'sum',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0);\n },\n },\n avg: {\n label: 'avg',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0) / nums.length;\n },\n },\n min: {\n label: 'min',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.min(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.min(...dates.map((d) => (d as Date).getTime())));\n }\n return defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any))[0];\n },\n },\n max: {\n label: 'max',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.max(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.max(...dates.map((d) => (d as Date).getTime())));\n }\n const sorted = defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any));\n return sorted[sorted.length - 1];\n },\n },\n size: {\n label: 'size',\n apply: ({ values }) => values.length,\n },\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Locale\n * ----------------------------------------------------------------------------------------------- */\n\nexport const DEFAULT_LOCALE_TEXT: MGHGridLocaleText = {\n noRowsLabel: 'No rows',\n loadingLabel: 'Loading…',\n toolbarColumns: 'Columns',\n toolbarFilters: 'Filters',\n toolbarExport: 'Export',\n toolbarDensity: 'Density',\n toolbarQuickFilterPlaceholder: 'Search...',\n toolbarQuickFilterLabel: 'Search',\n toolbarExportCSV: 'Download as CSV',\n toolbarExportExcel: 'Download as Excel',\n toolbarExportPrint: 'Print',\n densityCompact: 'Compact',\n densityStandard: 'Standard',\n densityComfortable: 'Comfortable',\n columnsPanelSearchPlaceholder: 'Search',\n columnsPanelShowAll: 'Show all',\n columnsPanelHideAll: 'Hide all',\n columnsPanelReset: 'Reset',\n filterPanelAddFilter: 'Add filter',\n filterPanelRemoveAll: 'Remove all',\n filterPanelDeleteIcon: 'Delete',\n filterPanelColumns: 'Columns',\n filterPanelOperator: 'Operator',\n filterPanelValue: 'Value',\n filterPanelInputPlaceholder: 'Filter value',\n filterPanelLogicOperator: 'Logic operator',\n filterPanelOperatorAnd: 'And',\n filterPanelOperatorOr: 'Or',\n columnMenuSortAsc: 'Sort by ASC',\n columnMenuSortDesc: 'Sort by DESC',\n columnMenuUnsort: 'Unsort',\n columnMenuFilter: 'Filter',\n columnMenuHideColumn: 'Hide column',\n columnMenuManageColumns: 'Manage columns',\n columnMenuPinLeft: 'Pin to left',\n columnMenuPinRight: 'Pin to right',\n columnMenuUnpin: 'Unpin',\n columnMenuGroup: (name) => `Group by ${name}`,\n columnMenuUngroup: (name) => `Stop grouping by ${name}`,\n columnMenuAggregation: 'Aggregation',\n aggregationMenuItemHeader: 'Aggregation',\n aggregationFunctionLabelNone: 'none',\n aggregationFunctionLabelSum: 'sum',\n aggregationFunctionLabelAvg: 'avg',\n aggregationFunctionLabelMin: 'min',\n aggregationFunctionLabelMax: 'max',\n aggregationFunctionLabelSize: 'size',\n footerRowSelected: (count) => (count === 1 ? '1 row selected' : `${count.toLocaleString()} rows selected`),\n footerTotalRows: 'Total Rows:',\n footerPaginationRowsPerPage: 'Rows per page:',\n footerPaginationDisplayedRows: (from, to, count) => `${from}–${to} of ${count.toLocaleString()}`,\n footerPaginationFirstPage: 'First page',\n footerPaginationPreviousPage: 'Previous page',\n footerPaginationNextPage: 'Next page',\n footerPaginationLastPage: 'Last page',\n checkboxSelectionHeaderName: 'Checkbox selection',\n checkboxSelectionSelectAllRows: 'Select all rows',\n checkboxSelectionUnselectAllRows: 'Unselect all rows',\n checkboxSelectionSelectRow: 'Select row',\n checkboxSelectionUnselectRow: 'Unselect row',\n booleanCellTrueLabel: 'yes',\n booleanCellFalseLabel: 'no',\n detailPanelToggle: 'Detail panel toggle',\n expandDetailPanel: 'Expand',\n collapseDetailPanel: 'Collapse',\n groupingColumnHeaderName: 'Group',\n groupColumn: (name) => `Group by ${name}`,\n unGroupColumn: (name) => `Stop grouping by ${name}`,\n actionsCellMore: 'more',\n columnHeaderSortIconLabel: 'Sort',\n columnMenuLabel: 'Menu',\n clearSearch: 'Clear search',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Text measurement (used for autosize)\n * ----------------------------------------------------------------------------------------------- */\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nexport const measureText = (text: string, font: string) => {\n if (typeof document === 'undefined') return text.length * 8;\n if (measureContext === undefined) {\n const canvas = document.createElement('canvas');\n measureContext = canvas.getContext('2d');\n }\n if (!measureContext) return text.length * 8;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Downloads\n * ----------------------------------------------------------------------------------------------- */\n\nexport const downloadBlob = (blob: Blob, fileName: string) => {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n window.setTimeout(() => {\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n }, 0);\n};\n","import React from 'react';\n\nexport const MGH_GRID_STYLE_ID = 'mgh-grid-styles';\n\n/**\n * Stylesheet for MGHGrid. It is injected once into <head> the first time a grid mounts,\n * so consumers do not need a CSS loader. All colours are CSS variables so the look can be\n * customised globally (by redefining `--mgh-grid-*` on `.mgh-grid-card`) or per instance\n * through the `themeVars` prop.\n */\nexport const MGH_GRID_CSS = `\n.mgh-grid-card {\n --mgh-grid-font-family: inherit;\n --mgh-grid-font-size: 14px;\n --mgh-grid-radius: 16px;\n --mgh-grid-inner-radius: 4px;\n --mgh-grid-paper: #ffffff;\n --mgh-grid-bg: #ffffff;\n --mgh-grid-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-fg-secondary: rgba(0, 0, 0, 0.6);\n --mgh-grid-fg-disabled: rgba(0, 0, 0, 0.38);\n --mgh-grid-border: rgba(224, 224, 224, 1);\n --mgh-grid-header-bg: #ffffff;\n --mgh-grid-header-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-hover: rgba(0, 0, 0, 0.04);\n --mgh-grid-hover-strong: rgba(0, 0, 0, 0.08);\n --mgh-grid-selected: rgba(25, 118, 210, 0.08);\n --mgh-grid-selected-hover: rgba(25, 118, 210, 0.12);\n --mgh-grid-primary: #1976d2;\n --mgh-grid-primary-contrast: #ffffff;\n --mgh-grid-focus: #1976d2;\n --mgh-grid-shadow: 0 0 2px rgba(145, 158, 171, 0.2), 0 12px 24px -4px rgba(145, 158, 171, 0.12);\n --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n --mgh-grid-overlay: rgba(255, 255, 255, 0.6);\n --mgh-grid-input-bg: transparent;\n --mgh-grid-input-border: rgba(0, 0, 0, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.12);\n --mgh-grid-group-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-footer-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-badge: #1976d2;\n --mgh-grid-scrollbar: rgba(0, 0, 0, 0.3);\n\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n background: var(--mgh-grid-paper);\n color: var(--mgh-grid-fg);\n border-radius: var(--mgh-grid-radius);\n box-shadow: var(--mgh-grid-shadow);\n font-family: var(--mgh-grid-font-family);\n font-size: var(--mgh-grid-font-size);\n line-height: 1.5;\n overflow: hidden;\n box-sizing: border-box;\n}\n.mgh-grid-card[data-mgh-theme=\"dark\"] {\n --mgh-grid-paper: #212b36;\n --mgh-grid-bg: #212b36;\n --mgh-grid-fg: #ffffff;\n --mgh-grid-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-grid-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-grid-border: rgba(81, 81, 81, 1);\n --mgh-grid-header-bg: #212b36;\n --mgh-grid-header-fg: #ffffff;\n --mgh-grid-hover: rgba(255, 255, 255, 0.08);\n --mgh-grid-hover-strong: rgba(255, 255, 255, 0.16);\n --mgh-grid-selected: rgba(144, 202, 249, 0.16);\n --mgh-grid-selected-hover: rgba(144, 202, 249, 0.24);\n --mgh-grid-primary: #90caf9;\n --mgh-grid-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-grid-focus: #90caf9;\n --mgh-grid-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 12px 24px -4px rgba(0, 0, 0, 0.12);\n --mgh-grid-overlay: rgba(33, 43, 54, 0.6);\n --mgh-grid-input-border: rgba(255, 255, 255, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.5);\n --mgh-grid-group-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-footer-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-badge: #90caf9;\n --mgh-grid-scrollbar: rgba(255, 255, 255, 0.3);\n}\n/* Only our own elements get the border-box reset. A blanket descendant reset would leak into\n consumer content rendered through slots (e.g. MUI TextField inputs rely on content-box). */\n[class*=\"mgh-grid\"], [class*=\"mgh-grid\"]::before, [class*=\"mgh-grid\"]::after { box-sizing: border-box; }\n.mgh-grid-card--plain { box-shadow: none; border-radius: 0; background: transparent; }\n\n/* ---- card header ---- */\n/* Title stays on its row; only the end-content group wraps internally (like the legacy MUI card). */\n.mgh-grid-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 16px 16px 0; flex-wrap: nowrap; }\n.mgh-grid-card-title { flex: 0 0 auto; padding: 8px 24px; margin: 0; font-size: 1.125rem; font-weight: 700; line-height: 1.5556; }\n/* Children are auto-sized so space-between leaves equal gaps title|center|end (like the legacy MUI card).\n Only the end group shrinks (and wraps internally); the centre content keeps its natural width. */\n.mgh-grid-card-header-center { flex: 0 0 auto; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }\n.mgh-grid-card-header-end { flex: 0 1 auto; min-width: 0; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }\n.mgh-grid-card-header-end:first-child { margin-left: auto; }\n@media (max-width: 599.95px) {\n .mgh-grid-card-header { flex-wrap: wrap; }\n .mgh-grid-card-header-end { gap: 8px; }\n}\n\n/* ---- box + root ---- */\n.mgh-grid-box { display: flex; flex-direction: column; flex-grow: 1; min-height: 0; min-width: 0; }\n.mgh-grid {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n border: 1px solid var(--mgh-grid-border);\n border-radius: var(--mgh-grid-inner-radius);\n background: var(--mgh-grid-bg);\n color: var(--mgh-grid-fg);\n outline: none;\n}\n.mgh-grid--auto-height { flex: 0 0 auto; }\n\n/* ---- toolbar ---- */\n.mgh-grid-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 45px; padding: 4px 8px; border-bottom: 1px solid var(--mgh-grid-border); flex-wrap: wrap; }\n.mgh-grid-toolbar-group { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }\n.mgh-grid-toolbar-center { display: flex; align-items: center; flex: 1 1 auto; justify-content: center; }\n\n/* ---- buttons ---- */\n.mgh-grid-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-grid-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; text-transform: none; white-space: nowrap; }\n.mgh-grid-btn:hover { background: var(--mgh-grid-hover); color: var(--mgh-grid-fg); }\n.mgh-grid-btn:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 1px; }\n.mgh-grid-btn:disabled { color: var(--mgh-grid-fg-disabled); cursor: default; background: transparent; }\n.mgh-grid-btn--icon { padding: 6px; border-radius: 50%; width: 32px; height: 32px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small { width: 26px; height: 26px; padding: 3px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small .mgh-grid-icon { width: 18px; height: 18px; }\n.mgh-grid-btn--primary { color: var(--mgh-grid-primary); }\n.mgh-grid-btn--primary:hover { background: var(--mgh-grid-selected); color: var(--mgh-grid-primary); }\n.mgh-grid-btn--contained { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); }\n.mgh-grid-btn--contained:hover { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); filter: brightness(0.92); }\n.mgh-grid-btn--active { color: var(--mgh-grid-primary); }\n\n/* ---- badge ---- */\n.mgh-grid-badge { position: relative; display: inline-flex; }\n.mgh-grid-badge-dot { position: absolute; top: 0; right: 0; min-width: 8px; height: 8px; border-radius: 4px; background: var(--mgh-grid-badge); transform: translate(50%, -50%); }\n.mgh-grid-badge-count { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--mgh-grid-badge); color: var(--mgh-grid-primary-contrast); font-size: 10px; font-weight: 600; line-height: 16px; text-align: center; transform: translate(50%, -50%); }\n\n/* ---- inputs ---- */\n.mgh-grid-input, .mgh-grid-select { font: inherit; font-size: 0.875rem; color: var(--mgh-grid-fg); background: var(--mgh-grid-input-bg); border: 1px solid var(--mgh-grid-input-border); border-radius: 6px; padding: 6px 10px; height: 36px; min-width: 0; outline: none; transition: border-color .15s, box-shadow .15s; }\n.mgh-grid-input:hover, .mgh-grid-select:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-input:focus, .mgh-grid-select:focus { border-color: var(--mgh-grid-focus); box-shadow: 0 0 0 1px var(--mgh-grid-focus); }\n.mgh-grid-input::placeholder { color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-input--small, .mgh-grid-select--small { height: 32px; padding: 4px 8px; font-size: 0.8125rem; }\n.mgh-grid-select { appearance: none; -webkit-appearance: none; padding-right: 28px; background-image: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23888'><path d='M7 10l5 5 5-5z'/></svg>\"); background-repeat: no-repeat; background-position: right 6px center; background-size: 18px; cursor: pointer; }\n.mgh-grid-select option { color: initial; background: initial; }\n.mgh-grid-card[data-mgh-theme=\"dark\"] .mgh-grid-select option, .mgh-grid-popover[data-mgh-theme=\"dark\"] .mgh-grid-select option { color: #fff; background: #212b36; }\n.mgh-grid-select[multiple] { height: auto; min-height: 36px; background-image: none; padding-right: 10px; }\n.mgh-grid-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.mgh-grid-field-label { font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-input-adorned { position: relative; display: flex; align-items: center; }\n.mgh-grid-input-adorned .mgh-grid-input { width: 100%; padding-left: 34px; }\n.mgh-grid-input-adorned--clearable .mgh-grid-input { padding-right: 34px; }\n.mgh-grid-input-adornment { position: absolute; left: 10px; display: inline-flex; color: var(--mgh-grid-fg-secondary); pointer-events: none; }\n.mgh-grid-input-adornment--end { left: auto; right: 4px; pointer-events: auto; }\n\n/* ---- checkbox ---- */\n.mgh-grid-checkbox { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 0; border: 2px solid var(--mgh-grid-fg-secondary); border-radius: 3px; background: transparent; cursor: pointer; display: inline-grid; place-content: center; position: relative; flex: 0 0 auto; transition: background-color .12s, border-color .12s; }\n.mgh-grid-checkbox:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-checkbox:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 2px; }\n.mgh-grid-checkbox:checked, .mgh-grid-checkbox:indeterminate { background: var(--mgh-grid-primary); border-color: var(--mgh-grid-primary); }\n.mgh-grid-checkbox:checked::after { content: \"\"; width: 5px; height: 10px; border: solid var(--mgh-grid-primary-contrast); border-width: 0 2px 2px 0; transform: translateY(-1px) rotate(45deg); }\n.mgh-grid-checkbox:indeterminate::after { content: \"\"; width: 10px; height: 2px; background: var(--mgh-grid-primary-contrast); }\n.mgh-grid-checkbox:disabled { opacity: 0.4; cursor: default; }\n.mgh-grid-checkbox-label { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.875rem; padding: 6px 4px; border-radius: 4px; }\n.mgh-grid-checkbox-label:hover { background: var(--mgh-grid-hover); }\n\n/* ---- quick filter ---- */\n.mgh-grid-quick-filter { display: grid; align-items: center; }\n.mgh-grid-quick-filter-trigger { grid-area: 1 / 1; z-index: 1; transition: opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-trigger { opacity: 0; pointer-events: none; }\n.mgh-grid-quick-filter-control { grid-area: 1 / 1; width: 32px; opacity: 0; overflow: hidden; transition: width .2s, opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 260px; opacity: 1; }\n@media (max-width: 599.95px) { .mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 180px; } }\n\n/* ---- main / scroller ---- */\n.mgh-grid-main { position: relative; display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden; }\n.mgh-grid--auto-height .mgh-grid-main { flex: 0 0 auto; }\n.mgh-grid-scroller { position: relative; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: auto; outline: none; scrollbar-width: thin; }\n.mgh-grid--auto-height .mgh-grid-scroller { overflow-y: hidden; }\n.mgh-grid-scroller::-webkit-scrollbar { width: 10px; height: 10px; }\n.mgh-grid-scroller::-webkit-scrollbar-thumb { background: var(--mgh-grid-scrollbar); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }\n\n/* ---- column headers ---- */\n.mgh-grid-columns { position: sticky; top: 0; z-index: 3; background: var(--mgh-grid-header-bg); border-bottom: 1px solid var(--mgh-grid-border); min-width: 100%; width: max-content; }\n.mgh-grid-header-row { display: flex; min-width: 100%; }\n.mgh-grid-header-cell { position: relative; display: flex; align-items: center; flex: 0 0 auto; height: var(--mgh-grid-header-height); padding: 0 10px; font-weight: 600; font-size: 0.875rem; color: var(--mgh-grid-header-fg); background: var(--mgh-grid-header-bg); white-space: nowrap; overflow: hidden; user-select: none; outline: none; }\n.mgh-grid-header-cell--sortable { cursor: pointer; }\n.mgh-grid-header-cell:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; }\n.mgh-grid-header-cell--align-center { justify-content: center; }\n.mgh-grid-header-cell--align-right { justify-content: flex-end; }\n.mgh-grid-header-cell--align-right .mgh-grid-header-title-container { flex-direction: row-reverse; }\n.mgh-grid-header-title-container { display: flex; align-items: center; gap: 2px; min-width: 0; flex: 1 1 auto; overflow: hidden; }\n.mgh-grid-header-cell--align-center .mgh-grid-header-title-container { flex: 0 1 auto; }\n.mgh-grid-header-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.mgh-grid-sort-icon { display: inline-flex; align-items: center; color: var(--mgh-grid-fg-secondary); opacity: 0; transition: opacity .15s; flex: 0 0 auto; }\n.mgh-grid-header-cell:hover .mgh-grid-sort-icon, .mgh-grid-sort-icon--active { opacity: 1; }\n.mgh-grid-sort-index { font-size: 10px; margin-left: -2px; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-header-menu-btn { position: absolute; right: 2px; opacity: 0; transition: opacity .15s; background: var(--mgh-grid-header-bg); }\n.mgh-grid-header-cell--align-right .mgh-grid-header-menu-btn { right: auto; left: 2px; }\n.mgh-grid-header-cell:hover .mgh-grid-header-menu-btn, .mgh-grid-header-menu-btn--open, .mgh-grid-header-cell:focus-within .mgh-grid-header-menu-btn { opacity: 1; }\n.mgh-grid-header-cell--menu-open { background: var(--mgh-grid-hover); }\n.mgh-grid-resize-handle { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 2; display: flex; justify-content: center; touch-action: none; }\n.mgh-grid-resize-handle::after { content: \"\"; width: 1px; height: 60%; margin-top: 20%; background: var(--mgh-grid-border); transition: background .15s, width .15s; }\n.mgh-grid-resize-handle:hover::after, .mgh-grid-resize-handle--active::after { background: var(--mgh-grid-primary); width: 2px; }\n.mgh-grid-header-cell--last .mgh-grid-resize-handle { right: 0; }\n.mgh-grid-header-cell--dragging { opacity: 0.5; }\n.mgh-grid-header-cell--drop-left::before, .mgh-grid-header-cell--drop-right::before { content: \"\"; position: absolute; top: 4px; bottom: 4px; width: 2px; background: var(--mgh-grid-primary); z-index: 3; }\n.mgh-grid-header-cell--drop-left::before { left: 0; }\n.mgh-grid-header-cell--drop-right::before { right: 0; }\n.mgh-grid-header-filler { flex: 1 1 auto; background: var(--mgh-grid-header-bg); }\n\n/* ---- pinned cells ---- */\n.mgh-grid-cell--pinned-left, .mgh-grid-header-cell--pinned-left { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-cell--pinned-right, .mgh-grid-header-cell--pinned-right { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-header-cell--pinned-left, .mgh-grid-header-cell--pinned-right { z-index: 4; background-color: var(--mgh-grid-header-bg); }\n.mgh-grid-cell--pinned-left-last, .mgh-grid-header-cell--pinned-left-last { box-shadow: 2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-cell--pinned-right-first, .mgh-grid-header-cell--pinned-right-first { box-shadow: -2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid--no-pinned-shadow .mgh-grid-cell--pinned-left-last, .mgh-grid--no-pinned-shadow .mgh-grid-header-cell--pinned-left-last { box-shadow: none; }\n\n/* ---- body & rows ---- */\n.mgh-grid-body { position: relative; min-width: 100%; width: max-content; }\n.mgh-grid-body--flow { display: flex; flex-direction: column; }\n.mgh-grid-row-block { min-width: 100%; }\n.mgh-grid-body--virtual .mgh-grid-row-block { position: absolute; left: 0; }\n.mgh-grid-row { display: flex; min-width: 100%; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); position: relative; }\n.mgh-grid-row--auto-height { align-items: stretch; }\n.mgh-grid-row:hover { background: var(--mgh-grid-hover); }\n.mgh-grid-row--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-row--selected:hover { background: var(--mgh-grid-selected-hover); }\n.mgh-grid-row--clickable { cursor: pointer; }\n.mgh-grid-row--group { background: var(--mgh-grid-group-bg); }\n.mgh-grid-row--pinned { background: var(--mgh-grid-bg); }\n.mgh-grid-row--footer { background: var(--mgh-grid-footer-bg); font-weight: 600; }\n.mgh-grid-row:hover .mgh-grid-cell--pinned-left, .mgh-grid-row:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-hover), var(--mgh-grid-hover)); }\n.mgh-grid-row--selected .mgh-grid-cell--pinned-left, .mgh-grid-row--selected .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected), var(--mgh-grid-selected)); }\n.mgh-grid-row--selected:hover .mgh-grid-cell--pinned-left, .mgh-grid-row--selected:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected-hover), var(--mgh-grid-selected-hover)); }\n.mgh-grid-row--group .mgh-grid-cell--pinned-left, .mgh-grid-row--group .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-group-bg), var(--mgh-grid-group-bg)); }\n.mgh-grid-row--footer .mgh-grid-cell--pinned-left, .mgh-grid-row--footer .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-footer-bg), var(--mgh-grid-footer-bg)); }\n.mgh-grid-row-filler { flex: 1 1 auto; }\n\n.mgh-grid-cell { display: flex; align-items: center; flex: 0 0 auto; padding: 0 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 0.875rem; outline: none; min-height: 100%; }\n.mgh-grid-cell > .mgh-grid-cell-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.mgh-grid-row--auto-height .mgh-grid-cell { white-space: normal; align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }\n.mgh-grid-row--auto-height .mgh-grid-cell > .mgh-grid-cell-text { white-space: normal; word-break: break-word; }\n.mgh-grid-cell--align-center { justify-content: center; }\n.mgh-grid-cell--align-right { justify-content: flex-end; }\n.mgh-grid-cell--focused { outline: 1px solid var(--mgh-grid-focus); outline-offset: -1px; }\n.mgh-grid-cell--editable { cursor: text; }\n.mgh-grid-cell--editing { padding: 0 4px; outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; background: var(--mgh-grid-bg); }\n.mgh-grid-cell--editing .mgh-grid-input, .mgh-grid-cell--editing .mgh-grid-select { width: 100%; height: calc(100% - 6px); border: 0; box-shadow: none; padding: 0 6px; background: transparent; }\n.mgh-grid-cell--checkbox, .mgh-grid-header-cell--checkbox, .mgh-grid-cell--detail-toggle, .mgh-grid-header-cell--detail-toggle { justify-content: center; padding: 0; }\n.mgh-grid-cell--boolean .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-cell--actions { gap: 2px; justify-content: center; }\n.mgh-grid-cell--aggregation { flex-direction: column; align-items: stretch; justify-content: center; line-height: 1.2; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-right { align-items: flex-end; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-center { align-items: center; }\n.mgh-grid-aggregation-label { font-size: 0.65rem; font-weight: 500; text-transform: uppercase; color: var(--mgh-grid-fg-secondary); letter-spacing: .04em; }\n.mgh-grid-group-cell { display: flex; align-items: center; gap: 4px; min-width: 0; }\n.mgh-grid-group-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }\n.mgh-grid-group-count { color: var(--mgh-grid-fg-secondary); margin-left: 2px; }\n.mgh-grid-group-toggle { flex: 0 0 auto; }\n.mgh-grid-group-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-group-toggle--expanded .mgh-grid-icon { transform: rotate(90deg); }\n.mgh-grid-detail-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-detail-toggle--expanded .mgh-grid-icon { transform: rotate(180deg); }\n\n/* ---- pinned rows ---- */\n.mgh-grid-pinned-rows { position: sticky; z-index: 2; min-width: 100%; width: max-content; background: var(--mgh-grid-bg); }\n.mgh-grid-pinned-rows--top { box-shadow: 0 2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom { bottom: 0; box-shadow: 0 -2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom .mgh-grid-row { border-bottom: 0; border-top: 1px solid var(--mgh-grid-border); }\n\n/* ---- detail panel ---- */\n.mgh-grid-detail-panel { position: sticky; left: 0; overflow: auto; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); z-index: 1; }\n\n/* ---- overlays ---- */\n.mgh-grid-overlay { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; z-index: 5; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; pointer-events: none; }\n.mgh-grid-overlay--loading { background: var(--mgh-grid-overlay); pointer-events: auto; }\n.mgh-grid-no-rows { display: flex; align-items: center; justify-content: center; gap: 8px; height: 100%; text-align: center; padding: 16px; }\n.mgh-grid-no-rows img, .mgh-grid-no-rows .mgh-grid-icon { width: 50px; height: 50px; color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-spinner { width: 36px; height: 36px; border-radius: 50%; border: 3px solid var(--mgh-grid-selected); border-top-color: var(--mgh-grid-primary); animation: mgh-grid-spin .8s linear infinite; }\n@keyframes mgh-grid-spin { to { transform: rotate(360deg); } }\n\n/* ---- footer ---- */\n.mgh-grid-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 52px; padding: 0 8px 0 16px; border-top: 1px solid var(--mgh-grid-border); font-size: 0.875rem; color: var(--mgh-grid-fg-secondary); flex-wrap: wrap; }\n.mgh-grid-footer-left { display: flex; align-items: center; gap: 16px; }\n.mgh-grid-pagination { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }\n.mgh-grid-pagination-select { height: 32px; padding: 2px 24px 2px 8px; font-size: 0.875rem; border-color: transparent; }\n.mgh-grid-pagination-select:hover { border-color: transparent; background-color: var(--mgh-grid-hover); }\n.mgh-grid-pagination-actions { display: inline-flex; align-items: center; }\n\n/* ---- popover / menu / panels ---- */\n.mgh-grid-popover {\n --mgh-grid-font-family: inherit; --mgh-grid-font-size: 14px; --mgh-grid-paper: #ffffff; --mgh-grid-bg: #fff; --mgh-grid-fg: rgba(0,0,0,.87); --mgh-grid-fg-secondary: rgba(0,0,0,.6); --mgh-grid-fg-disabled: rgba(0,0,0,.38); --mgh-grid-border: rgba(224,224,224,1); --mgh-grid-hover: rgba(0,0,0,.04); --mgh-grid-selected: rgba(25,118,210,.08); --mgh-grid-primary: #1976d2; --mgh-grid-primary-contrast: #fff; --mgh-grid-focus: #1976d2; --mgh-grid-input-bg: transparent; --mgh-grid-input-border: rgba(0,0,0,.23); --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n position: fixed; z-index: 1300; background: var(--mgh-grid-paper); color: var(--mgh-grid-fg); border-radius: 8px; box-shadow: var(--mgh-grid-popover-shadow); font-family: var(--mgh-grid-font-family); font-size: var(--mgh-grid-font-size); line-height: 1.5; outline: none; max-height: calc(100vh - 16px); overflow: auto; animation: mgh-grid-pop .12s ease-out;\n}\n.mgh-grid-popover[data-mgh-theme=\"dark\"] { --mgh-grid-paper: #212b36; --mgh-grid-bg: #212b36; --mgh-grid-fg: #fff; --mgh-grid-fg-secondary: rgba(255,255,255,.7); --mgh-grid-fg-disabled: rgba(255,255,255,.5); --mgh-grid-border: rgba(81,81,81,1); --mgh-grid-hover: rgba(255,255,255,.08); --mgh-grid-selected: rgba(144,202,249,.16); --mgh-grid-primary: #90caf9; --mgh-grid-primary-contrast: rgba(0,0,0,.87); --mgh-grid-focus: #90caf9; --mgh-grid-input-border: rgba(255,255,255,.23); }\n@keyframes mgh-grid-pop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }\n.mgh-grid-menu { list-style: none; margin: 0; padding: 6px 0; min-width: 180px; }\n.mgh-grid-menu-item { display: flex; align-items: center; gap: 12px; padding: 6px 16px; min-height: 36px; font-size: 0.875rem; cursor: pointer; white-space: nowrap; color: var(--mgh-grid-fg); background: transparent; border: 0; width: 100%; text-align: left; font-family: inherit; outline: none; }\n.mgh-grid-menu-item:hover, .mgh-grid-menu-item:focus-visible { background: var(--mgh-grid-hover); }\n.mgh-grid-menu-item--disabled { color: var(--mgh-grid-fg-disabled); cursor: default; pointer-events: none; }\n.mgh-grid-menu-item--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-menu-item .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); flex: 0 0 auto; }\n.mgh-grid-menu-divider { height: 1px; margin: 6px 0; background: var(--mgh-grid-border); border: 0; }\n.mgh-grid-menu-header { padding: 6px 16px 2px; font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); text-transform: uppercase; letter-spacing: .04em; }\n.mgh-grid-menu-section { padding: 4px 16px 8px; display: flex; flex-direction: column; gap: 4px; }\n.mgh-grid-panel { display: flex; flex-direction: column; min-width: 300px; max-width: min(640px, calc(100vw - 16px)); }\n.mgh-grid-panel-header { padding: 12px 12px 4px; }\n.mgh-grid-panel-content { padding: 4px 12px; overflow: auto; max-height: 360px; }\n.mgh-grid-panel-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; }\n.mgh-grid-columns-list { display: flex; flex-direction: column; }\n.mgh-grid-filter-row { display: grid; grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); gap: 8px; align-items: end; margin-bottom: 8px; }\n.mgh-grid-filter-row--first { grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row--with-logic { grid-template-columns: 32px 80px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row .mgh-grid-btn--icon { margin-bottom: 4px; }\n.mgh-grid-filter-empty { padding: 8px 4px; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; }\n@media (max-width: 599.95px) { .mgh-grid-filter-row, .mgh-grid-filter-row--with-logic { grid-template-columns: 1fr; } }\n\n/* ---- misc ---- */\n.mgh-grid-tooltip-anchor { display: inline-flex; }\n.mgh-grid-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }\n@media print { .mgh-grid-toolbar, .mgh-grid-footer { display: none !important; } }\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_GRID_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_GRID_STYLE_ID;\n style.setAttribute('data-mgh-grid', 'true');\n style.textContent = MGH_GRID_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHGrid stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHGridStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridLocaleText,\n MGHGridState,\n MGHGridThemeMode,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\n\nexport interface MGHGridRootProps {\n header?: React.ReactNode;\n pagination: boolean;\n pageSizeOptions: number[];\n hideFooterPagination: boolean;\n hideFooterRowCount: boolean;\n hideFooterSelectedRowCount: boolean;\n disableColumnFilter: boolean;\n disableColumnSelector: boolean;\n disableDensitySelector: boolean;\n disableColumnPinning: boolean;\n disableColumnSorting: boolean;\n disableMultipleColumnsSorting: boolean;\n disableMultipleColumnsFiltering: boolean;\n disableRowGrouping: boolean;\n disableAggregation: boolean;\n checkboxSelection: boolean;\n aggregationFunctions: Record<string, MGHGridAggregationFunction>;\n quickFilterDebounceMs: number;\n}\n\nexport interface MGHGridContextValue {\n api: MGHGridApi;\n state: MGHGridState;\n localeText: MGHGridLocaleText;\n themeMode: MGHGridThemeMode;\n rootProps: MGHGridRootProps;\n /** All user columns (ordered, including hidden). */\n columns: MGHGridColDef[];\n /** Visible user columns. */\n visibleColumns: MGHGridColDef[];\n}\n\nexport const MGHGridContext = React.createContext<MGHGridContextValue | null>(null);\nMGHGridContext.displayName = 'MGHGridContext';\n\nexport const useMGHGridContext = () => {\n const ctx = React.useContext(MGHGridContext);\n if (!ctx) {\n throw new Error('MGHGrid: this component must be rendered inside an <MGHGrid /> (e.g. through a slot).');\n }\n return ctx;\n};\n\n/** Access the grid API from custom toolbars, menu items, cells, etc. */\nexport const useMGHGridApiContext = <R extends MGHGridValidRowModel = any>() => useMGHGridContext().api as MGHGridApi<R>;\n\nexport const useMGHGridLocaleText = () => useMGHGridContext().localeText;\n\n/** Creates a ref to hold the grid API; pass it to `<MGHGrid apiRef={apiRef} />`. */\nexport const useMGHGridApiRef = <R extends MGHGridValidRowModel = any>() =>\n React.useRef<MGHGridApi<R> | null>(null) as React.MutableRefObject<MGHGridApi<R> | null>;\n","import React from 'react';\n\n/** Keeps a ref always pointing at the latest value (assigned during render). */\nexport function useLatestRef<T>(value: T) {\n const ref = React.useRef(value);\n ref.current = value;\n return ref;\n}\n\n/** Returns a stable function that always calls the latest `fn`. */\nexport function useEventCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useLatestRef(fn);\n return React.useCallback(((...args: any[]) => ref.current(...args)) as T, []);\n}\n\n/**\n * Controlled / uncontrolled state helper. When `controlled` is defined the internal state is\n * ignored and every change is reported through `onChange` only.\n */\nexport function useControlledState<T>(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void\n): [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = controlled !== undefined;\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : internal;\n const valueRef = useLatestRef(value);\n const controlledRef = useLatestRef(isControlled);\n const onChangeRef = useLatestRef(onChange);\n\n const setValue = React.useCallback((next: T | ((prev: T) => T)) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(valueRef.current) : next;\n if (Object.is(resolved, valueRef.current)) return;\n valueRef.current = resolved;\n if (!controlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [value, setValue];\n}\n\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n/** Observes the client size of an element. */\nexport function useElementSize<T extends HTMLElement>(ref: React.RefObject<T | null>, enabled = true): ElementSize {\n const [size, setSize] = React.useState<ElementSize>({ width: 0, height: 0 });\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !enabled) return undefined;\n const update = () => {\n const width = el.clientWidth;\n const height = el.clientHeight;\n setSize((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n };\n update();\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return size;\n}\n\n/** `window.matchMedia` as a hook. Always false on the server. */\nexport function useMediaQuery(query: string) {\n const getMatch = () =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false;\n const [matches, setMatches] = React.useState(getMatch);\n\n React.useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return undefined;\n const media = window.matchMedia(query);\n const listener = () => setMatches(media.matches);\n listener();\n if (media.addEventListener) {\n media.addEventListener('change', listener);\n return () => media.removeEventListener('change', listener);\n }\n media.addListener(listener);\n return () => media.removeListener(listener);\n }, [query]);\n\n return matches;\n}\n\n/** Debounced version of a callback. The returned function is stable. */\nexport function useDebouncedCallback<T extends (...args: any[]) => void>(fn: T, delay: number) {\n const fnRef = useLatestRef(fn);\n const timerRef = React.useRef<number | null>(null);\n\n React.useEffect(\n () => () => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n },\n []\n );\n\n return React.useCallback(\n (...args: Parameters<T>) => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n timerRef.current = window.setTimeout(() => {\n timerRef.current = null;\n fnRef.current(...args);\n }, delay);\n },\n [delay]\n );\n}\n\nexport function useForceUpdate() {\n const [, setTick] = React.useState(0);\n return React.useCallback(() => setTick((t) => t + 1), []);\n}\n\nlet idCounter = 0;\n/** Stable unique id per component instance (React.useId fallback for older Reacts). */\nexport function useStableId(prefix: string) {\n const reactUseId = (React as any).useId as undefined | (() => string);\n if (reactUseId) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const id = reactUseId();\n return `${prefix}-${id.replace(/:/g, '')}`;\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const ref = React.useRef<string | null>(null);\n if (ref.current === null) {\n idCounter += 1;\n ref.current = `${prefix}-${idCounter}`;\n }\n return ref.current;\n}\n","import {\n MGHGridApi,\n MGHGridColDef,\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridExportOptions,\n MGHGridPrintExportOptions,\n MGHGridRowId,\n} from './MGHGrid.types';\nimport {\n downloadBlob,\n formattedValueToString,\n getCellValue,\n getFormattedValue,\n isInternalField,\n isNil,\n toDate,\n} from './utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Shared: resolve the columns & rows to export\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ExportCell {\n raw: any;\n formatted: string;\n col: MGHGridColDef;\n}\n\nexport interface ExportTable {\n columns: MGHGridColDef[];\n headers: string[];\n rows: ExportCell[][];\n}\n\nexport const resolveExportColumns = (api: MGHGridApi, options: MGHGridExportOptions): MGHGridColDef[] => {\n const all = api.getAllColumns();\n let columns: MGHGridColDef[];\n if (options.fields) {\n const byField = new Map<string, MGHGridColDef>();\n all.forEach((c) => byField.set(c.field, c));\n columns = options.fields.map((f) => byField.get(f)).filter(Boolean) as MGHGridColDef[];\n } else if (options.allColumns) {\n columns = all;\n } else {\n columns = api.getVisibleColumns();\n }\n return columns.filter((c) => !c.disableExport && !isInternalField(c.field) && c.type !== 'actions');\n};\n\nexport const buildExportTable = (api: MGHGridApi, options: MGHGridExportOptions): ExportTable => {\n const columns = resolveExportColumns(api, options);\n const ids: MGHGridRowId[] = options.getRowsToExport ? options.getRowsToExport({ api }) : api.getSortedRowIds();\n const rows: ExportCell[][] = [];\n ids.forEach((id) => {\n const row = api.getRow(id);\n if (!row) return;\n rows.push(\n columns.map((col) => {\n const raw = getCellValue(row, col, api);\n const formatted = formattedValueToString(getFormattedValue(raw, row, col, api, id));\n return { raw, formatted, col };\n })\n );\n });\n return { columns, headers: columns.map((c) => c.headerName ?? c.field), rows };\n};\n\nconst sanitizeFileName = (name: string | undefined, fallback: string, extension: string) => {\n const base = (name && name.trim()) || fallback;\n return base.toLowerCase().endsWith(`.${extension}`) ? base : `${base}.${extension}`;\n};\n\nconst defaultFileBase = () => {\n const title = typeof document !== 'undefined' && document.title ? document.title.trim() : '';\n return (title || 'export').replace(/[\\\\/:*?\"<>|]+/g, '-');\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CSV\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeCsvCell = (value: string, delimiter: string) => {\n let text = value;\n // Guard against formula injection when opening in spreadsheet software.\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n if (text.indexOf('\"') !== -1 || text.indexOf(delimiter) !== -1 || /[\\r\\n]/.test(text)) {\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n }\n return text;\n};\n\nexport const getDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const delimiter = options.delimiter ?? ',';\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const lines: string[] = [];\n if (includeHeaders) {\n lines.push(table.headers.map((h) => escapeCsvCell(h, delimiter)).join(delimiter));\n }\n table.rows.forEach((cells) => {\n lines.push(\n cells\n .map((cell) => {\n const text = options.useRawValues ? (isNil(cell.raw) ? '' : String(cell.raw)) : cell.formatted;\n return escapeCsvCell(text, delimiter);\n })\n .join(delimiter)\n );\n });\n return lines.join('\\r\\n');\n};\n\nconst UTF8_BOM = String.fromCharCode(0xfeff);\n\nexport const exportDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const csv = getDataAsCsv(api, options);\n const bom = options.utf8WithBom ? UTF8_BOM : '';\n const blob = new Blob([bom + csv], { type: 'text/csv;charset=utf-8;' });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'csv'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * XLSX (minimal OOXML writer + store-only ZIP, no dependencies)\n * ----------------------------------------------------------------------------------------------- */\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n += 1) {\n let c = n;\n for (let k = 0; k < 8; k += 1) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nconst crc32 = (bytes: Uint8Array) => {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i += 1) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n};\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst encodeUtf8 = (text: string): Uint8Array => {\n if (textEncoder) return textEncoder.encode(text);\n // Fallback for very old environments.\n const utf8 = unescape(encodeURIComponent(text));\n const out = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i += 1) out[i] = utf8.charCodeAt(i);\n return out;\n};\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nconst concatBytes = (chunks: Uint8Array[]) => {\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n chunks.forEach((c) => {\n out.set(c, offset);\n offset += c.length;\n });\n return out;\n};\n\nconst zipStore = (entries: ZipEntry[]): Uint8Array => {\n const localChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n // 1980-01-01 00:00 in DOS date/time format.\n const dosTime = 0;\n const dosDate = (1 << 5) | 1;\n\n entries.forEach((entry) => {\n const nameBytes = encodeUtf8(entry.name);\n const crc = crc32(entry.data);\n const size = entry.data.length;\n\n const local = new Uint8Array(30 + nameBytes.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0x0800, true); // UTF-8 names\n lv.setUint16(8, 0, true); // store\n lv.setUint16(10, dosTime, true);\n lv.setUint16(12, dosDate, true);\n lv.setUint32(14, crc, true);\n lv.setUint32(18, size, true);\n lv.setUint32(22, size, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0x0800, true);\n cv.setUint16(10, 0, true);\n cv.setUint16(12, dosTime, true);\n cv.setUint16(14, dosDate, true);\n cv.setUint32(16, crc, true);\n cv.setUint32(20, size, true);\n cv.setUint32(24, size, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, offset, true);\n central.set(nameBytes, 46);\n\n localChunks.push(local, entry.data);\n centralChunks.push(central);\n offset += local.length + size;\n });\n\n const centralDirectory = concatBytes(centralChunks);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDirectory.length, true);\n ev.setUint32(16, offset, true);\n ev.setUint16(20, 0, true);\n\n return concatBytes(localChunks.concat([centralDirectory, eocd]));\n};\n\n// Characters that are illegal in XML 1.0 (built without literal control characters in source).\nconst INVALID_XML_CHARS = new RegExp(\n '[' +\n String.fromCharCode(0x00) +\n '-' +\n String.fromCharCode(0x08) +\n String.fromCharCode(0x0b) +\n String.fromCharCode(0x0c) +\n String.fromCharCode(0x0e) +\n '-' +\n String.fromCharCode(0x1f) +\n String.fromCharCode(0xfffe) +\n String.fromCharCode(0xffff) +\n ']',\n 'g'\n);\nconst stripInvalidXml = (text: string) => text.replace(INVALID_XML_CHARS, '');\n\nconst escapeXml = (text: string) =>\n stripInvalidXml(text)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n\nconst columnLetter = (index: number) => {\n let n = index + 1;\n let letters = '';\n while (n > 0) {\n const rem = (n - 1) % 26;\n letters = String.fromCharCode(65 + rem) + letters;\n n = Math.floor((n - 1) / 26);\n }\n return letters;\n};\n\nconst sanitizeSheetName = (name: string | undefined) => {\n const cleaned = (name || 'Sheet1').replace(/[\\[\\]:*?/\\\\]/g, ' ').trim() || 'Sheet1';\n return cleaned.length > 31 ? cleaned.slice(0, 31) : cleaned;\n};\n\nconst XML_HEADER = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n\nconst buildSheetXml = (table: ExportTable, includeHeaders: boolean, columnWidths: number[]) => {\n const rowsXml: string[] = [];\n let rowIndex = 1;\n\n const inlineString = (ref: string, text: string, style?: number) =>\n `<c r=\"${ref}\" t=\"inlineStr\"${style ? ` s=\"${style}\"` : ''}><is><t xml:space=\"preserve\">${escapeXml(\n text\n )}</t></is></c>`;\n\n if (includeHeaders) {\n const cells = table.headers.map((h, i) => inlineString(`${columnLetter(i)}${rowIndex}`, h, 1)).join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${cells}</row>`);\n rowIndex += 1;\n }\n\n table.rows.forEach((cells) => {\n const xmlCells = cells\n .map((cell, i) => {\n const ref = `${columnLetter(i)}${rowIndex}`;\n const type = cell.col.type;\n if (isNil(cell.raw) || cell.raw === '') return '';\n if (type === 'number' && typeof cell.raw === 'number' && Number.isFinite(cell.raw)) {\n return `<c r=\"${ref}\"><v>${cell.raw}</v></c>`;\n }\n if (type === 'boolean') {\n return `<c r=\"${ref}\" t=\"b\"><v>${cell.raw ? 1 : 0}</v></c>`;\n }\n if ((type === 'date' || type === 'dateTime') && toDate(cell.raw)) {\n // Excel serial date (days since 1899-12-30), written in local time with a date style.\n const d = toDate(cell.raw) as Date;\n const utc = Date.UTC(\n d.getFullYear(),\n d.getMonth(),\n d.getDate(),\n d.getHours(),\n d.getMinutes(),\n d.getSeconds()\n );\n const serial = utc / 86400000 + 25569;\n return `<c r=\"${ref}\" s=\"${type === 'dateTime' ? 3 : 2}\"><v>${serial}</v></c>`;\n }\n return inlineString(ref, cell.formatted);\n })\n .join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${xmlCells}</row>`);\n rowIndex += 1;\n });\n\n const lastCol = columnLetter(Math.max(table.columns.length - 1, 0));\n const lastRow = Math.max(rowIndex - 1, 1);\n const cols = columnWidths.map((w, i) => `<col min=\"${i + 1}\" max=\"${i + 1}\" width=\"${w}\" customWidth=\"1\"/>`).join('');\n\n return (\n XML_HEADER +\n '<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<dimension ref=\"A1:${lastCol}${lastRow}\"/>` +\n '<sheetViews><sheetView workbookViewId=\"0\">' +\n (includeHeaders ? '<pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/>' : '') +\n '</sheetView></sheetViews>' +\n '<sheetFormatPr defaultRowHeight=\"15\"/>' +\n (cols ? `<cols>${cols}</cols>` : '') +\n `<sheetData>${rowsXml.join('')}</sheetData>` +\n (includeHeaders && table.rows.length > 0 ? `<autoFilter ref=\"A1:${lastCol}${lastRow}\"/>` : '') +\n '</worksheet>'\n );\n};\n\nconst STYLES_XML =\n XML_HEADER +\n '<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n '<numFmts count=\"2\"><numFmt numFmtId=\"164\" formatCode=\"m/d/yyyy\"/><numFmt numFmtId=\"165\" formatCode=\"m/d/yyyy h:mm AM/PM\"/></numFmts>' +\n '<fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts>' +\n '<fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills>' +\n '<borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>' +\n '<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>' +\n '<cellXfs count=\"4\">' +\n '<xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>' +\n '<xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>' +\n '<xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"165\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '</cellXfs>' +\n '<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>' +\n '</styleSheet>';\n\nconst CONTENT_TYPES_XML =\n XML_HEADER +\n '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n '<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>' +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n '<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>' +\n '<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>' +\n '</Types>';\n\nconst ROOT_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>' +\n '<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>' +\n '</Relationships>';\n\nconst WORKBOOK_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>' +\n '</Relationships>';\n\nconst buildWorkbookXml = (sheetName: string) =>\n XML_HEADER +\n '<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<sheets><sheet name=\"${escapeXml(sheetName)}\" sheetId=\"1\" r:id=\"rId1\"/></sheets>` +\n '</workbook>';\n\nconst buildCoreXml = () => {\n const now = new Date().toISOString();\n return (\n XML_HEADER +\n '<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" ' +\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" ' +\n 'xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n '<dc:creator>MGH Grid</dc:creator>' +\n `<dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>` +\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>` +\n '</cp:coreProperties>'\n );\n};\n\nconst APP_XML =\n XML_HEADER +\n '<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" ' +\n 'xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">' +\n '<Application>MGH Grid</Application></Properties>';\n\nexport const buildXlsx = (api: MGHGridApi, options: MGHGridExcelExportOptions = {}): Uint8Array => {\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const widths = table.columns.map((col, i) => {\n const explicit = options.columnsStyles?.[col.field]?.width;\n if (explicit) return explicit;\n let max = table.headers[i].length;\n for (let r = 0; r < Math.min(table.rows.length, 500); r += 1) {\n const len = table.rows[r][i].formatted.length;\n if (len > max) max = len;\n }\n return Math.min(Math.max(max + 2, 8), 60);\n });\n const sheetName = sanitizeSheetName(options.sheetName);\n const entries: ZipEntry[] = [\n { name: '[Content_Types].xml', data: encodeUtf8(CONTENT_TYPES_XML) },\n { name: '_rels/.rels', data: encodeUtf8(ROOT_RELS_XML) },\n { name: 'docProps/core.xml', data: encodeUtf8(buildCoreXml()) },\n { name: 'docProps/app.xml', data: encodeUtf8(APP_XML) },\n { name: 'xl/workbook.xml', data: encodeUtf8(buildWorkbookXml(sheetName)) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(WORKBOOK_RELS_XML) },\n { name: 'xl/styles.xml', data: encodeUtf8(STYLES_XML) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(buildSheetXml(table, includeHeaders, widths)) },\n ];\n return zipStore(entries);\n};\n\nexport const exportDataAsExcel = async (api: MGHGridApi, options: MGHGridExcelExportOptions = {}) => {\n const bytes = buildXlsx(api, options);\n const blob = new Blob([bytes as BlobPart], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'xlsx'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Print\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Legacy value-based print (plain HTML table). The grid's `exportDataAsPrint` prints the live DOM instead. */\nexport const exportDataAsPrintTable = (api: MGHGridApi, options: MGHGridPrintExportOptions = {}) => {\n if (typeof document === 'undefined') return;\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const title = options.title ?? options.fileName ?? document.title ?? '';\n\n const headerHtml = includeHeaders\n ? `<thead><tr>${table.headers\n .map((h, i) => `<th class=\"${table.columns[i].align ?? 'left'}\">${escapeHtml(h)}</th>`)\n .join('')}</tr></thead>`\n : '';\n const bodyHtml = `<tbody>${table.rows\n .map(\n (cells) =>\n `<tr>${cells\n .map((cell) => `<td class=\"${cell.col.align ?? 'left'}\">${escapeHtml(cell.formatted)}</td>`)\n .join('')}</tr>`\n )\n .join('')}</tbody>`;\n\n const html =\n '<!doctype html><html><head><meta charset=\"utf-8\" />' +\n `<title>${escapeHtml(title)}</title>` +\n '<style>' +\n 'body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;font-size:12px;color:#111;margin:16px;}' +\n 'h1{font-size:16px;margin:0 0 12px;}' +\n 'table{border-collapse:collapse;width:100%;}' +\n 'th,td{border:1px solid #ccc;padding:4px 8px;text-align:left;vertical-align:top;}' +\n 'th{background:#f3f3f3;font-weight:600;}' +\n 'td.right,th.right{text-align:right;} td.center,th.center{text-align:center;}' +\n 'tr{page-break-inside:avoid;} thead{display:table-header-group;}' +\n (options.pageStyle ?? '') +\n '</style></head><body>' +\n (title ? `<h1>${escapeHtml(title)}</h1>` : '') +\n `<table>${headerHtml}${bodyHtml}</table>` +\n '</body></html>';\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = '0';\n iframe.style.opacity = '0';\n document.body.appendChild(iframe);\n\n const cleanup = () => {\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 1000);\n };\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (!win) {\n cleanup();\n return;\n }\n try {\n win.focus();\n win.onafterprint = cleanup;\n win.print();\n } catch {\n cleanup();\n }\n };\n\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\n if (doc) {\n doc.open();\n doc.write(html);\n doc.close();\n } else {\n iframe.srcdoc = html;\n }\n};\n","import { MGHGridPrintExportOptions } from './MGHGrid.types';\n\n/**\n * Prints the grid \"as seen on screen\": the live DOM of the grid card is cloned into a hidden iframe\n * together with the page's stylesheets, so anything rendered by `renderCell` (images, chips,\n * links, custom components) prints exactly as displayed. The grid itself must already be rendered\n * in print mode (all rows, no virtualization) when this is called.\n */\n\nconst PRINT_CSS = `\n@page { margin: 10mm; }\nhtml, body { margin: 0; padding: 0; background: #fff; }\n.mgh-grid-print-title { margin: 0 0 12px; font: 600 16px/1.4 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif; }\n.mgh-grid-card { box-shadow: none !important; border-radius: 0 !important; height: auto !important; max-height: none !important; overflow: visible !important; background: transparent !important; }\n.mgh-grid-box { height: auto !important; max-height: none !important; flex: none !important; }\n.mgh-grid { height: auto !important; max-height: none !important; border-radius: 0 !important; }\n.mgh-grid-main, .mgh-grid-scroller { overflow: visible !important; height: auto !important; max-height: none !important; }\n.mgh-grid-columns, .mgh-grid-pinned-rows, .mgh-grid-detail-panel { position: static !important; box-shadow: none !important; }\n.mgh-grid-header-cell, .mgh-grid-cell { position: static !important; box-shadow: none !important; background-image: none !important; }\n.mgh-grid-detail-panel { width: auto !important; }\n.mgh-grid-body { min-height: 0 !important; }\n.mgh-grid-row, .mgh-grid-row-block, .mgh-grid-detail-panel { break-inside: avoid; page-break-inside: avoid; }\n.mgh-grid-columns { break-after: avoid; page-break-after: avoid; }\n.mgh-grid-header-menu-btn, .mgh-grid-resize-handle, .mgh-grid-overlay, .mgh-grid-sort-icon:not(.mgh-grid-sort-icon--active) { display: none !important; }\n.mgh-grid-popover { display: none !important; }\n`;\n\nconst collectStyles = (doc: Document) => {\n const styles: string[] = [];\n const links: string[] = [];\n Array.from(doc.styleSheets).forEach((sheet) => {\n try {\n const rules = Array.from(sheet.cssRules)\n .map((rule) => rule.cssText)\n .join('\\n');\n if (rules) styles.push(rules);\n } catch {\n // Cross-origin stylesheet: reference it instead of inlining.\n if (sheet.href) links.push(sheet.href);\n }\n });\n return { styles, links };\n};\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Copies live form-control state (cloneNode does not copy `checked` / `value`). */\nconst syncFormState = (source: HTMLElement, target: HTMLElement) => {\n const sourceInputs = Array.from(source.querySelectorAll('input, select, textarea'));\n const targetInputs = Array.from(target.querySelectorAll('input, select, textarea'));\n sourceInputs.forEach((el, i) => {\n const t = targetInputs[i];\n if (!t || t.tagName !== el.tagName) return;\n // Tag-name checks instead of `instanceof`: the elements may belong to different documents.\n if (el.tagName === 'INPUT') {\n const src = el as HTMLInputElement;\n const dst = t as HTMLInputElement;\n if (src.type === 'checkbox' || src.type === 'radio') {\n dst.checked = src.checked;\n if (src.checked) dst.setAttribute('checked', '');\n dst.indeterminate = src.indeterminate;\n } else {\n dst.value = src.value;\n dst.setAttribute('value', src.value);\n }\n } else if (el.tagName === 'SELECT') {\n (t as HTMLSelectElement).value = (el as HTMLSelectElement).value;\n } else if (el.tagName === 'TEXTAREA') {\n (t as HTMLTextAreaElement).value = (el as HTMLTextAreaElement).value;\n t.textContent = (el as HTMLTextAreaElement).value;\n }\n });\n // Canvases lose their bitmap when cloned: replace them with images.\n const sourceCanvases = Array.from(source.querySelectorAll('canvas'));\n const targetCanvases = Array.from(target.querySelectorAll('canvas'));\n sourceCanvases.forEach((canvas, i) => {\n const t = targetCanvases[i];\n if (!t) return;\n try {\n const img = t.ownerDocument.createElement('img');\n img.src = canvas.toDataURL();\n img.width = canvas.width;\n img.height = canvas.height;\n img.style.cssText = t.style.cssText;\n t.replaceWith(img);\n } catch {\n /* tainted canvas – leave as is */\n }\n });\n};\n\nconst waitForImages = (doc: Document, timeoutMs: number) =>\n new Promise<void>((resolve) => {\n const images = Array.from(doc.images).filter((img) => !img.complete);\n if (images.length === 0) {\n resolve();\n return;\n }\n let remaining = images.length;\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n resolve();\n };\n const timer = window.setTimeout(finish, timeoutMs);\n images.forEach((img) => {\n const onSettled = () => {\n remaining -= 1;\n if (remaining <= 0) {\n window.clearTimeout(timer);\n finish();\n }\n };\n img.addEventListener('load', onSettled, { once: true });\n img.addEventListener('error', onSettled, { once: true });\n });\n });\n\nexport interface PrintGridParams {\n /** The `.mgh-grid-card` element (already rendered in print mode). */\n cardElement: HTMLElement;\n options: MGHGridPrintExportOptions;\n /** Called once the print dialog has been handed off (or failed) so the grid can leave print mode. */\n onDone: () => void;\n}\n\nexport const printGridElement = (params: PrintGridParams) => {\n let done = false;\n const onDone = () => {\n if (done) return;\n done = true;\n params.onDone();\n };\n try {\n printGridElementUnsafe({ ...params, onDone });\n } catch (error) {\n console.error('MGHGrid: print failed', error);\n onDone();\n }\n};\n\nconst printGridElementUnsafe = ({ cardElement, options, onDone }: PrintGridParams) => {\n if (typeof document === 'undefined') {\n onDone();\n return;\n }\n const hideToolbar = options.hideToolbar ?? true;\n const hideFooter = options.hideFooter ?? false;\n const includeHeaders = options.includeHeaders ?? true;\n const copyStyles = options.copyStyles ?? true;\n\n const clone = cardElement.cloneNode(true) as HTMLElement;\n syncFormState(cardElement, clone);\n clone.querySelectorAll('.mgh-grid-card-header').forEach((el) => el.remove());\n if (hideToolbar) clone.querySelectorAll('.mgh-grid-toolbar').forEach((el) => el.remove());\n if (hideFooter) clone.querySelectorAll('.mgh-grid-footer').forEach((el) => el.remove());\n if (!includeHeaders) clone.querySelectorAll('.mgh-grid-columns').forEach((el) => el.remove());\n clone.classList.add('mgh-grid-card--plain');\n // Remove ids to avoid duplicates and drop inline sizing coming from cardStyle/boxStyle.\n clone.querySelectorAll('[id]').forEach((el) => el.removeAttribute('id'));\n clone.style.height = 'auto';\n clone.style.flexGrow = '0';\n\n const title = options.title ?? '';\n const { styles, links } = copyStyles ? collectStyles(document) : { styles: [], links: [] };\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.setAttribute('data-mgh-grid-print', 'true');\n iframe.style.cssText = 'position:fixed;right:0;bottom:0;width:0;height:0;border:0;opacity:0;pointer-events:none;';\n document.body.appendChild(iframe);\n\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 500);\n onDone();\n };\n\n const win = iframe.contentWindow;\n const doc = iframe.contentDocument || win?.document;\n if (!win || !doc) {\n finish();\n return;\n }\n\n doc.open();\n doc.write(\n `<!doctype html><html><head><meta charset=\"utf-8\" /><title>${escapeHtml(title || document.title || 'Print')}</title>` +\n links.map((href) => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\" />`).join('') +\n `</head><body></body></html>`\n );\n doc.close();\n\n styles.forEach((css) => {\n const style = doc.createElement('style');\n style.textContent = css;\n doc.head.appendChild(style);\n });\n const printStyle = doc.createElement('style');\n printStyle.textContent = PRINT_CSS + (options.pageStyle ?? '');\n doc.head.appendChild(printStyle);\n\n if (title) {\n const h1 = doc.createElement('h1');\n h1.className = 'mgh-grid-print-title';\n h1.textContent = title;\n doc.body.appendChild(h1);\n }\n doc.body.appendChild(doc.adoptNode(clone));\n\n const run = async () => {\n try {\n await waitForImages(doc, 4000);\n if (options.onBeforePrint) await options.onBeforePrint(doc);\n win.onafterprint = finish;\n win.focus();\n win.print();\n // Most browsers block on print(); if afterprint never fires, still restore the grid.\n window.setTimeout(finish, 1000);\n } catch {\n finish();\n }\n };\n void run();\n};\n","import {\n MGHGridAggregationFunction,\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridColDef,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridRowId,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport { formattedValueToString, getCellValue, getFormattedValue, getGroupingValue, isNil } from './utils';\n\nexport interface RowEntry<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n row: R;\n}\n\n/** Internal tree node used while grouping. */\nexport interface GroupTreeNode<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n depth: number;\n parent: MGHGridRowId | null;\n groupingField: string;\n groupingKey: any;\n groupingLabel: string;\n childGroups: GroupTreeNode<R>[];\n /** Direct leaf children (only populated at the deepest level). */\n leaves: RowEntry<R>[];\n /** Every descendant leaf, in display order after sorting. */\n descendants: RowEntry<R>[];\n}\n\nexport interface DisplayRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n type: 'leaf' | 'group';\n row: R | null;\n node: MGHGridLeafNode | MGHGridGroupNode;\n depth: number;\n group?: GroupTreeNode<R>;\n}\n\nexport const GROUP_ID_PREFIX = 'auto-generated-row-';\n\nconst keyToString = (key: any) => (isNil(key) ? '' : key instanceof Date ? String(key.getTime()) : String(key));\n\nexport const buildGroupTree = <R extends MGHGridValidRowModel>(\n entries: RowEntry<R>[],\n groupingFields: string[],\n columnsByField: Map<string, MGHGridColDef<R>>,\n api: MGHGridApi<R>,\n emptyLabel = '(empty)'\n): GroupTreeNode<R>[] => {\n const build = (items: RowEntry<R>[], depth: number, parentId: MGHGridRowId | null, path: string): GroupTreeNode<R>[] => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return [];\n const buckets = new Map<string, GroupTreeNode<R>>();\n items.forEach((entry) => {\n const key = getGroupingValue(entry.row, col, api);\n const keyStr = keyToString(key);\n let node = buckets.get(keyStr);\n if (!node) {\n const label = formattedValueToString(getFormattedValue(key, entry.row, col, api, entry.id)) || emptyLabel;\n const id = `${GROUP_ID_PREFIX}${path}${field}/${keyStr}`;\n node = {\n id,\n depth,\n parent: parentId,\n groupingField: field,\n groupingKey: key,\n groupingLabel: label,\n childGroups: [],\n leaves: [],\n descendants: [],\n };\n buckets.set(keyStr, node);\n }\n node.leaves.push(entry);\n });\n const nodes: GroupTreeNode<R>[] = [];\n buckets.forEach((node) => {\n if (depth < groupingFields.length - 1) {\n node.childGroups = build(\n node.leaves,\n depth + 1,\n node.id,\n `${path}${field}/${keyToString(node.groupingKey)}|`\n );\n node.descendants = node.leaves;\n node.leaves = [];\n } else {\n node.descendants = node.leaves;\n }\n nodes.push(node);\n });\n return nodes;\n };\n return build(entries, 0, null, '');\n};\n\nexport type GroupComparator<R extends MGHGridValidRowModel = any> = (a: GroupTreeNode<R>, b: GroupTreeNode<R>) => number;\n\n/** Sorts groups (with the given comparator) and leaves (with the given sorter), recursively. */\nexport const sortGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n compareGroups: ((depth: number) => GroupComparator<R> | null) | null,\n sortLeaves: (leaves: RowEntry<R>[]) => RowEntry<R>[]\n): GroupTreeNode<R>[] => {\n const sortLevel = (nodes: GroupTreeNode<R>[], depth: number): GroupTreeNode<R>[] => {\n const comparator = compareGroups ? compareGroups(depth) : null;\n const sorted = comparator\n ? nodes\n .map((node, index) => ({ node, index }))\n .sort((a, b) => comparator(a.node, b.node) || a.index - b.index)\n .map((item) => item.node)\n : nodes;\n sorted.forEach((node) => {\n if (node.childGroups.length > 0) {\n node.childGroups = sortLevel(node.childGroups, depth + 1);\n const descendants: RowEntry<R>[] = [];\n node.childGroups.forEach((child) => child.descendants.forEach((d) => descendants.push(d)));\n node.descendants = descendants;\n } else {\n node.leaves = sortLeaves(node.leaves);\n node.descendants = node.leaves;\n }\n });\n return sorted;\n };\n return sortLevel(roots, 0);\n};\n\nexport const collectTreeLeaves = <R extends MGHGridValidRowModel>(roots: GroupTreeNode<R>[]): RowEntry<R>[] => {\n const out: RowEntry<R>[] = [];\n roots.forEach((root) => root.descendants.forEach((d) => out.push(d)));\n return out;\n};\n\nexport const toGroupNode = <R extends MGHGridValidRowModel>(\n node: GroupTreeNode<R>,\n isExpanded: boolean\n): MGHGridGroupNode => ({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: node.childGroups.length > 0 ? node.childGroups.map((c) => c.id) : node.leaves.map((l) => l.id),\n leafIds: node.descendants.map((d) => d.id),\n isExpanded,\n});\n\n/** Flattens the tree into display rows, honouring expansion state. Also fills `nodesById` with every node. */\nexport const flattenGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n isExpanded: (node: GroupTreeNode<R>) => boolean,\n nodesById: Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>,\n groupsById: Map<MGHGridRowId, GroupTreeNode<R>>\n): DisplayRow<R>[] => {\n const out: DisplayRow<R>[] = [];\n const visit = (nodes: GroupTreeNode<R>[], visible: boolean) => {\n nodes.forEach((node) => {\n const expanded = isExpanded(node);\n const groupNode = toGroupNode(node, expanded);\n nodesById.set(node.id, groupNode);\n groupsById.set(node.id, node);\n if (visible)\n out.push({ id: node.id, type: 'group', row: null, node: groupNode, depth: node.depth, group: node });\n const childVisible = visible && expanded;\n if (node.childGroups.length > 0) {\n visit(node.childGroups, childVisible);\n } else {\n node.leaves.forEach((leaf) => {\n const leafNode: MGHGridLeafNode = { type: 'leaf', id: leaf.id, depth: node.depth + 1, parent: node.id };\n nodesById.set(leaf.id, leafNode);\n if (childVisible)\n out.push({ id: leaf.id, type: 'leaf', row: leaf.row, node: leafNode, depth: node.depth + 1 });\n });\n }\n });\n };\n visit(roots, true);\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const aggregateRows = <R extends MGHGridValidRowModel>(\n rows: R[],\n aggregationModel: MGHGridAggregationModel,\n columnsByField: Map<string, MGHGridColDef<R>>,\n functions: Record<string, MGHGridAggregationFunction>,\n api: MGHGridApi<R>\n): Record<string, { value: any; fn: string }> => {\n const result: Record<string, { value: any; fn: string }> = {};\n Object.keys(aggregationModel).forEach((field) => {\n const fnName = aggregationModel[field];\n const fn = functions[fnName];\n const col = columnsByField.get(field);\n if (!fn || !col || col.aggregable === false) return;\n const values = rows.map((row) => getCellValue(row, col, api));\n result[field] = { value: fn.apply({ values, field }), fn: fnName };\n });\n return result;\n};\n","import React from 'react';\n\n/* Small inline SVG icon set (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHGridIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHGridIconProps>(({ size = 20, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-grid-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const ViewColumnIcon = createIcon(\n <path d=\"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z\" />,\n 'ViewColumnIcon'\n);\nexport const FilterListIcon = createIcon(<path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\" />, 'FilterListIcon');\nexport const SearchIcon = createIcon(\n <path d=\"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" />,\n 'SearchIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\nexport const DownloadIcon = createIcon(\n <path d=\"M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67 2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2z\" />,\n 'DownloadIcon'\n);\nexport const ArrowUpwardIcon = createIcon(\n <path d=\"m4 12 1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />,\n 'ArrowUpwardIcon'\n);\nexport const ArrowDownwardIcon = createIcon(\n <path d=\"m20 12-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\" />,\n 'ArrowDownwardIcon'\n);\nexport const MoreVertIcon = createIcon(\n <path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'MoreVertIcon'\n);\nexport const CheckIcon = createIcon(<path d=\"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />, 'CheckIcon');\nexport const ExpandMoreIcon = createIcon(<path d=\"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z\" />, 'ExpandMoreIcon');\nexport const ChevronRightIcon = createIcon(<path d=\"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" />, 'ChevronRightIcon');\nexport const ChevronLeftIcon = createIcon(<path d=\"M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />, 'ChevronLeftIcon');\nexport const FirstPageIcon = createIcon(\n <path d=\"M18.41 16.59 13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z\" />,\n 'FirstPageIcon'\n);\nexport const LastPageIcon = createIcon(\n <path d=\"M5.59 7.41 10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z\" />,\n 'LastPageIcon'\n);\nexport const PushPinIcon = createIcon(\n <path d=\"M16 9V4h1c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1h1v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z\" />,\n 'PushPinIcon'\n);\nexport const DeleteIcon = createIcon(\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />,\n 'DeleteIcon'\n);\nexport const AddIcon = createIcon(<path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />, 'AddIcon');\nexport const DensitySmallIcon = createIcon(\n <path d=\"M3 2h18v2H3zm0 18h18v2H3zm0-6h18v2H3zm0-6h18v2H3z\" />,\n 'DensitySmallIcon'\n);\nexport const DensityMediumIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3zm0-8h18v2H3z\" />, 'DensityMediumIcon');\nexport const DensityLargeIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3z\" />, 'DensityLargeIcon');\nexport const DragIndicatorIcon = createIcon(\n <path d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'DragIndicatorIcon'\n);\nexport const PrintIcon = createIcon(\n <path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\" />,\n 'PrintIcon'\n);\nexport const TableChartIcon = createIcon(\n <path d=\"M10 10.02h5V21h-5zM17 21h3c1.1 0 2-.9 2-2v-9h-5v11zm3-18H5c-1.1 0-2 .9-2 2v3h19V5c0-1.1-.9-2-2-2zM3 19c0 1.1.9 2 2 2h3V10H3v9z\" />,\n 'TableChartIcon'\n);\nexport const DescriptionIcon = createIcon(\n <path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\" />,\n 'DescriptionIcon'\n);\nexport const VisibilityOffIcon = createIcon(\n <path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\" />,\n 'VisibilityOffIcon'\n);\nexport const FunctionsIcon = createIcon(<path d=\"M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z\" />, 'FunctionsIcon');\nexport const WorkspacesIcon = createIcon(\n <path d=\"M6 13c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-10C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 10c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z\" />,\n 'WorkspacesIcon'\n);\nexport const EmptyBoxIcon = createIcon(\n <>\n <path\n d=\"M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2z\"\n opacity=\".25\"\n />\n <path d=\"M4 8h16v11H4z\" opacity=\".15\" />\n </>,\n 'EmptyBoxIcon'\n);\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { clamp, cx } from '../utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Button / IconButton\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'text' | 'primary' | 'contained';\n size?: 'small' | 'medium';\n startIcon?: React.ReactNode;\n endIcon?: React.ReactNode;\n active?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { variant = 'text', size = 'medium', startIcon, endIcon, active, className, children, type = 'button', ...rest },\n ref\n ) => (\n <button\n ref={ref}\n type={type}\n className={cx(\n 'mgh-grid-btn',\n variant === 'primary' && 'mgh-grid-btn--primary',\n variant === 'contained' && 'mgh-grid-btn--contained',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {startIcon}\n {children}\n {endIcon}\n </button>\n )\n);\nButton.displayName = 'MGHGridButton';\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n size?: 'small' | 'medium';\n active?: boolean;\n /** Tooltip (native title) and aria-label. */\n label?: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ size = 'medium', active, label, className, children, type = 'button', ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n title={label}\n aria-label={label}\n className={cx(\n 'mgh-grid-btn mgh-grid-btn--icon',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n )\n);\nIconButton.displayName = 'MGHGridIconButton';\n\n/* -------------------------------------------------------------------------------------------------\n * Badge\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface BadgeProps {\n count?: number;\n variant?: 'dot' | 'count';\n children: React.ReactNode;\n}\n\nexport const Badge = ({ count = 0, variant = 'dot', children }: BadgeProps) => (\n <span className=\"mgh-grid-badge\">\n {children}\n {count > 0 &&\n (variant === 'dot' ? (\n <span className=\"mgh-grid-badge-dot\" />\n ) : (\n <span className=\"mgh-grid-badge-count\">{count > 99 ? '99+' : count}</span>\n ))}\n </span>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Inputs\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(\n ({ size = 'medium', className, ...rest }, ref) => (\n <input\n ref={ref}\n className={cx('mgh-grid-input', size === 'small' && 'mgh-grid-input--small', className)}\n {...rest}\n />\n )\n);\nTextInput.displayName = 'MGHGridTextInput';\n\nexport interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(({ size = 'medium', className, ...rest }, ref) => (\n <select ref={ref} className={cx('mgh-grid-select', size === 'small' && 'mgh-grid-select--small', className)} {...rest} />\n));\nSelect.displayName = 'MGHGridSelect';\n\nexport interface FieldProps {\n label?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n htmlFor?: string;\n}\n\nexport const Field = ({ label, children, className, htmlFor }: FieldProps) => (\n <div className={cx('mgh-grid-field', className)}>\n {label && (\n <label className=\"mgh-grid-field-label\" htmlFor={htmlFor}>\n {label}\n </label>\n )}\n {children}\n </div>\n);\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n indeterminate?: boolean;\n label?: string;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ indeterminate = false, label, className, ...rest }, forwardedRef) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const setRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [forwardedRef]\n );\n React.useEffect(() => {\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n return (\n <input\n ref={setRef}\n type=\"checkbox\"\n title={label}\n aria-label={label}\n className={cx('mgh-grid-checkbox', className)}\n {...rest}\n />\n );\n }\n);\nCheckbox.displayName = 'MGHGridCheckbox';\n\n/* -------------------------------------------------------------------------------------------------\n * Spinner\n * ----------------------------------------------------------------------------------------------- */\n\nexport const Spinner = ({ className }: { className?: string }) => (\n <div className={cx('mgh-grid-spinner', className)} role=\"progressbar\" aria-label=\"Loading\" />\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover (portal, anchored)\n * ----------------------------------------------------------------------------------------------- */\n\nexport type PopoverPlacement = 'bottom-start' | 'bottom-end' | 'bottom' | 'right-start';\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null | undefined;\n onClose: (reason: 'backdrop' | 'escape') => void;\n children: React.ReactNode;\n placement?: PopoverPlacement;\n themeMode?: MGHGridThemeMode;\n className?: string;\n style?: React.CSSProperties;\n offset?: number;\n role?: string;\n autoFocus?: boolean;\n /** Additional elements considered \"inside\" for outside-click detection. */\n ignoreOutsideClickOn?: Array<React.RefObject<HTMLElement | null>>;\n}\n\nexport function Popover({\n open,\n anchorEl,\n onClose,\n children,\n placement = 'bottom-start',\n themeMode = 'light',\n className,\n style,\n offset = 4,\n role = 'dialog',\n autoFocus = false,\n ignoreOutsideClickOn,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState<{ top: number; left: number; ready: boolean }>({\n top: 0,\n left: 0,\n ready: false,\n });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n if (placement === 'right-start') {\n top = a.top;\n left = a.right + offset;\n if (left + w > vw - 8) left = a.left - offset - w;\n } else {\n top = a.bottom + offset;\n if (top + h > vh - 8 && a.top - offset - h >= 8) top = a.top - offset - h;\n left =\n placement === 'bottom-end'\n ? a.right - w\n : placement === 'bottom'\n ? a.left + a.width / 2 - w / 2\n : a.left;\n }\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement, offset]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n if (ignoreOutsideClickOn?.some((r) => r.current?.contains(target))) return;\n // Clicks inside other popovers (nested menus) should not close this one.\n if ((target as HTMLElement).closest?.('.mgh-grid-popover')) return;\n onClose('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onClose, anchorEl, ignoreOutsideClickOn]);\n\n React.useEffect(() => {\n if (open && autoFocus && ref.current) {\n const focusable = ref.current.querySelector<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])'\n );\n (focusable ?? ref.current).focus();\n }\n }, [open, autoFocus]);\n\n if (!open || typeof document === 'undefined') return null;\n\n const stop = (event: React.SyntheticEvent) => event.stopPropagation();\n\n return createPortal(\n <div\n ref={ref}\n role={role}\n tabIndex={-1}\n className={cx('mgh-grid-popover', className)}\n data-mgh-theme={themeMode}\n style={{\n top: position.top,\n left: position.left,\n visibility: position.ready ? 'visible' : 'hidden',\n ...style,\n }}\n onClick={stop}\n onDoubleClick={stop}\n onMouseDown={stop}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onClose('escape');\n return;\n }\n event.stopPropagation();\n }}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {\n children: React.ReactNode;\n}\n\nexport const Menu = ({ children, className, onKeyDown, ...rest }: MenuProps) => {\n const ref = React.useRef<HTMLUListElement | null>(null);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {\n onKeyDown?.(event);\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' && event.key !== 'Home' && event.key !== 'End') return;\n const items = Array.from(\n ref.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])') ?? []\n );\n if (items.length === 0) return;\n event.preventDefault();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n let next = 0;\n if (event.key === 'ArrowDown') next = currentIndex < 0 ? 0 : (currentIndex + 1) % items.length;\n else if (event.key === 'ArrowUp')\n next = currentIndex < 0 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;\n else if (event.key === 'Home') next = 0;\n else next = items.length - 1;\n items[next].focus();\n };\n\n React.useEffect(() => {\n const first = ref.current?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])');\n first?.focus();\n }, []);\n\n return (\n <ul ref={ref} role=\"menu\" className={cx('mgh-grid-menu', className)} onKeyDown={handleKeyDown} {...rest}>\n {children}\n </ul>\n );\n};\n\nexport interface MenuItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {\n icon?: React.ReactNode;\n selected?: boolean;\n /** Injected by menus that should close after the click. */\n hideMenu?: () => void;\n}\n\nexport const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ icon, selected, disabled, className, children, onClick, hideMenu, ...rest }, ref) => (\n <li role=\"none\">\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n disabled={disabled}\n tabIndex={-1}\n className={cx(\n 'mgh-grid-menu-item',\n disabled && 'mgh-grid-menu-item--disabled',\n selected && 'mgh-grid-menu-item--selected',\n className\n )}\n onClick={(event) => {\n if (disabled) return;\n onClick?.(event);\n hideMenu?.();\n }}\n {...rest}\n >\n {icon}\n <span>{children}</span>\n </button>\n </li>\n )\n);\nMenuItem.displayName = 'MGHGridMenuItem';\n\nexport const MenuDivider = () => <li role=\"separator\" className=\"mgh-grid-menu-divider\" />;\n\nexport const MenuHeader = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-header\">\n {children}\n </li>\n);\n\nexport const MenuSection = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-section\">\n {children}\n </li>\n);\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport {\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridPrintExportOptions,\n MGHGridToolbarProps,\n} from '../MGHGrid.types';\nimport {\n CloseIcon,\n DensityLargeIcon,\n DensityMediumIcon,\n DensitySmallIcon,\n DescriptionIcon,\n DownloadIcon,\n FilterListIcon,\n PrintIcon,\n SearchIcon,\n TableChartIcon,\n ViewColumnIcon,\n} from '../icons';\nimport { cx } from '../utils';\nimport { Badge, IconButton, Menu, MenuItem, MenuItemProps, Popover, TextInput } from './primitives';\n\n/* -------------------------------------------------------------------------------------------------\n * Buttons\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridColumnsButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'columns';\n return (\n <IconButton\n label={localeText.toolbarColumns}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('columns', event.currentTarget))}\n >\n <ViewColumnIcon />\n </IconButton>\n );\n}\n\nexport function MGHGridFiltersButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'filters';\n return (\n <IconButton\n label={localeText.toolbarFilters}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('filters', event.currentTarget))}\n >\n <Badge count={state.filterCount} variant=\"dot\">\n <FilterListIcon />\n </Badge>\n </IconButton>\n );\n}\n\nexport function MGHGridDensitySelector() {\n const { api, state, localeText, themeMode } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const options = [\n { value: 'compact', label: localeText.densityCompact, icon: <DensitySmallIcon /> },\n { value: 'standard', label: localeText.densityStandard, icon: <DensityMediumIcon /> },\n { value: 'comfortable', label: localeText.densityComfortable, icon: <DensityLargeIcon /> },\n ] as const;\n const current = options.find((o) => o.value === state.density) ?? options[1];\n return (\n <>\n <IconButton\n label={localeText.toolbarDensity}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n {current.icon}\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n role=\"menu\"\n >\n <Menu>\n {options.map((option) => (\n <MenuItem\n key={option.value}\n icon={option.icon}\n selected={option.value === state.density}\n onClick={() => api.setDensity(option.value)}\n hideMenu={() => setAnchor(null)}\n >\n {option.label}\n </MenuItem>\n ))}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Export menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridExportMenuItemProps extends MenuItemProps {\n /** Injected by MGHGridExportMenu; call it to close the menu after your action. */\n hideMenu?: () => void;\n}\n\n/** Menu item for custom export actions. Drop-in for MUI's GridExportMenuItemProps pattern. */\nexport const MGHGridExportMenuItem = MenuItem as React.ForwardRefExoticComponent<\n MGHGridExportMenuItemProps & React.RefAttributes<HTMLButtonElement>\n>;\n\nexport interface MGHGridExportMenuProps {\n csvOptions?: MGHGridCsvExportOptions;\n excelOptions?: MGHGridExcelExportOptions;\n printOptions?: MGHGridPrintExportOptions;\n showCsvOption?: boolean;\n showExcelOption?: boolean;\n showPrintOption?: boolean;\n customMenuItem?: React.ReactNode;\n}\n\nexport function MGHGridExportMenu({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n customMenuItem,\n}: MGHGridExportMenuProps) {\n const { api, localeText, themeMode, rootProps } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const hideMenu = () => setAnchor(null);\n\n const customItems = React.Children.map(customMenuItem, (child) =>\n React.isValidElement(child) ? React.cloneElement(child as React.ReactElement<any>, { hideMenu }) : child\n );\n\n const resolvedPrintOptions: MGHGridPrintExportOptions = {\n title: typeof rootProps.header === 'string' ? rootProps.header : undefined,\n ...printOptions,\n };\n\n return (\n <>\n <IconButton\n label={localeText.toolbarExport}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n <DownloadIcon />\n </IconButton>\n <Popover open={Boolean(anchor)} anchorEl={anchor} onClose={hideMenu} themeMode={themeMode} role=\"menu\">\n <Menu>\n {customItems}\n {showCsvOption && (\n <MenuItem\n icon={<DescriptionIcon />}\n onClick={() => api.exportDataAsCsv(csvOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportCSV}\n </MenuItem>\n )}\n {showExcelOption && (\n <MenuItem\n icon={<TableChartIcon />}\n onClick={() => {\n void api.exportDataAsExcel(excelOptions);\n }}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportExcel}\n </MenuItem>\n )}\n {showPrintOption && (\n <MenuItem\n icon={<PrintIcon />}\n onClick={() => api.exportDataAsPrint(resolvedPrintOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportPrint}\n </MenuItem>\n )}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Quick filter\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridQuickFilterProps {\n placeholder?: string;\n debounceMs?: number;\n /** Always show the expanded input. */\n alwaysExpanded?: boolean;\n}\n\nexport function MGHGridQuickFilter({ placeholder, debounceMs, alwaysExpanded = false }: MGHGridQuickFilterProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const externalValue = (state.quickFilterValues ?? []).join(' ');\n const [text, setText] = React.useState(externalValue);\n const [expanded, setExpanded] = React.useState(alwaysExpanded || externalValue !== '');\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const timer = React.useRef<number | null>(null);\n const delay = debounceMs ?? rootProps.quickFilterDebounceMs;\n\n // Sync when the model is changed from outside (e.g. api.setQuickFilterValues).\n const lastExternal = React.useRef(externalValue);\n React.useEffect(() => {\n if (externalValue !== lastExternal.current) {\n lastExternal.current = externalValue;\n setText(externalValue);\n if (externalValue !== '') setExpanded(true);\n }\n }, [externalValue]);\n\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n\n const commit = (value: string) => {\n const values = value.split(/\\s+/).filter((v) => v !== '');\n lastExternal.current = values.join(' ');\n api.setQuickFilterValues(values);\n };\n\n const handleChange = (value: string) => {\n setText(value);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => commit(value), delay);\n };\n\n const clear = () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n setText('');\n commit('');\n inputRef.current?.focus();\n };\n\n const expand = () => {\n setExpanded(true);\n window.setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const isExpanded = alwaysExpanded || expanded;\n\n return (\n <div className={cx('mgh-grid-quick-filter', isExpanded && 'mgh-grid-quick-filter--expanded')}>\n <IconButton\n className=\"mgh-grid-quick-filter-trigger\"\n label={localeText.toolbarQuickFilterLabel}\n aria-disabled={isExpanded}\n tabIndex={isExpanded ? -1 : 0}\n onClick={expand}\n >\n <SearchIcon />\n </IconButton>\n <div\n className={cx(\n 'mgh-grid-quick-filter-control mgh-grid-input-adorned',\n text && 'mgh-grid-input-adorned--clearable'\n )}\n >\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n ref={inputRef}\n size=\"small\"\n type=\"search\"\n value={text}\n tabIndex={isExpanded ? 0 : -1}\n placeholder={placeholder ?? localeText.toolbarQuickFilterPlaceholder}\n aria-label={localeText.toolbarQuickFilterLabel}\n onChange={(event) => handleChange(event.target.value)}\n onBlur={() => {\n if (!alwaysExpanded && text.trim() === '') setExpanded(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n if (text) clear();\n else if (!alwaysExpanded) {\n setExpanded(false);\n inputRef.current?.blur();\n }\n }\n if (event.key === 'Enter') {\n if (timer.current !== null) window.clearTimeout(timer.current);\n commit(text);\n }\n }}\n />\n {text && (\n <span className=\"mgh-grid-input-adornment mgh-grid-input-adornment--end\">\n <IconButton size=\"small\" label={localeText.clearSearch} onClick={clear} tabIndex={-1}>\n <CloseIcon />\n </IconButton>\n </span>\n )}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Default toolbar\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n showDensitySelector = false,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n csvOptions,\n excelOptions,\n printOptions,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n quickFilterPlaceholder,\n quickFilterDebounceMs,\n}: MGHGridToolbarProps) {\n const { rootProps } = useMGHGridContext();\n const showColumns = showColumnsButton && !rootProps.disableColumnSelector;\n const showFilters = showFilterButton && !rootProps.disableColumnFilter;\n const showDensity = showDensitySelector && !rootProps.disableDensitySelector;\n\n return (\n <div className=\"mgh-grid-toolbar\" role=\"toolbar\">\n <div className=\"mgh-grid-toolbar-group\">\n {showColumns && <MGHGridColumnsButton />}\n {showFilters && <MGHGridFiltersButton />}\n {showDensity && <MGHGridDensitySelector />}\n {showExportButton && (\n <MGHGridExportMenu\n csvOptions={csvOptions}\n excelOptions={excelOptions}\n printOptions={printOptions}\n showCsvOption={showCsvOption}\n showExcelOption={showExcelOption}\n showPrintOption={showPrintOption}\n customMenuItem={customMenuItem}\n />\n )}\n </div>\n {renderDateRange && <div className=\"mgh-grid-toolbar-center\">{renderDateRange}</div>}\n <div className=\"mgh-grid-toolbar-group\">\n {renderOtherButtons}\n {showQuickFilter && (\n <MGHGridQuickFilter placeholder={quickFilterPlaceholder} debounceMs={quickFilterDebounceMs} />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { ChevronLeftIcon, ChevronRightIcon, FirstPageIcon, LastPageIcon } from '../icons';\nimport { IconButton, Select } from './primitives';\n\nexport function MGHGridPagination() {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const { page, pageSize } = state.paginationModel;\n const count = state.rowCount;\n const pageCount = state.pageCount;\n const from = count === 0 ? 0 : page * pageSize + 1;\n const to = Math.min(count, (page + 1) * pageSize);\n const options =\n rootProps.pageSizeOptions.indexOf(pageSize) === -1\n ? rootProps.pageSizeOptions.concat([pageSize]).sort((a, b) => a - b)\n : rootProps.pageSizeOptions;\n\n return (\n <div className=\"mgh-grid-pagination\" role=\"navigation\" aria-label=\"Pagination\">\n <span>{localeText.footerPaginationRowsPerPage}</span>\n <Select\n className=\"mgh-grid-pagination-select\"\n value={pageSize}\n aria-label={localeText.footerPaginationRowsPerPage}\n onChange={(event) => api.setPageSize(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </Select>\n <span>{localeText.footerPaginationDisplayedRows(from, to, count)}</span>\n <div className=\"mgh-grid-pagination-actions\">\n <IconButton label={localeText.footerPaginationFirstPage} disabled={page <= 0} onClick={() => api.setPage(0)}>\n <FirstPageIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationPreviousPage}\n disabled={page <= 0}\n onClick={() => api.setPage(page - 1)}\n >\n <ChevronLeftIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationNextPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(page + 1)}\n >\n <ChevronRightIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationLastPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(Math.max(pageCount - 1, 0))}\n >\n <LastPageIcon />\n </IconButton>\n </div>\n </div>\n );\n}\n\nexport function MGHGridFooter() {\n const { state, localeText, rootProps } = useMGHGridContext();\n const selectedCount = state.rowSelectionModel.ids.size;\n const showSelected = selectedCount > 0 && !rootProps.hideFooterSelectedRowCount;\n const showPagination = rootProps.pagination && !rootProps.hideFooterPagination;\n const showRowCount = !showPagination && !rootProps.hideFooterRowCount;\n\n return (\n <div className=\"mgh-grid-footer\">\n <div className=\"mgh-grid-footer-left\">\n {showSelected && <span>{localeText.footerRowSelected(selectedCount)}</span>}\n </div>\n {showRowCount && (\n <span>\n {localeText.footerTotalRows} {state.rowCount.toLocaleString()}\n </span>\n )}\n {showPagination && <MGHGridPagination />}\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { SearchIcon } from '../icons';\nimport { Button, Checkbox, TextInput } from './primitives';\n\nexport function MGHGridColumnsPanel() {\n const { api, state, localeText, columns, visibleColumns } = useMGHGridContext();\n const visibleFields = React.useMemo(() => new Set(visibleColumns.map((col) => col.field)), [visibleColumns]);\n const [search, setSearch] = React.useState('');\n const model = state.columnVisibilityModel;\n\n const hideable = columns.filter((col) => col.hideable !== false);\n const needle = search.trim().toLowerCase();\n const filtered = needle\n ? hideable.filter((col) => (col.headerName ?? col.field).toLowerCase().indexOf(needle) !== -1)\n : hideable;\n\n const setAll = (visible: boolean) => {\n const next = { ...model };\n hideable.forEach((col) => {\n next[col.field] = visible;\n });\n api.setColumnVisibilityModel(next);\n };\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarColumns}>\n <div className=\"mgh-grid-panel-header\">\n <div className=\"mgh-grid-input-adorned\">\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n autoFocus\n size=\"small\"\n value={search}\n placeholder={localeText.columnsPanelSearchPlaceholder}\n aria-label={localeText.columnsPanelSearchPlaceholder}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n </div>\n <div className=\"mgh-grid-panel-content\">\n <div className=\"mgh-grid-columns-list\">\n {filtered.map((col) => {\n const visible = visibleFields.has(col.field);\n return (\n <label key={col.field} className=\"mgh-grid-checkbox-label\">\n <Checkbox checked={visible} onChange={() => api.setColumnVisibility(col.field, !visible)} />\n <span>{col.headerName ?? col.field}</span>\n </label>\n );\n })}\n {filtered.length === 0 && <div className=\"mgh-grid-filter-empty\">No columns</div>}\n </div>\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(true)}>\n {localeText.columnsPanelShowAll}\n </Button>\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(false)}>\n {localeText.columnsPanelHideAll}\n </Button>\n <Button size=\"small\" onClick={() => api.setColumnVisibilityModel({})}>\n {localeText.columnsPanelReset}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridFilterItem, MGHGridFilterOperator } from '../MGHGrid.types';\nimport { AddIcon, DeleteIcon } from '../icons';\nimport { getColumnFilterOperators, getOptionLabel, getOptionValue, resolveValueOptions, uniqueId } from '../utils';\nimport { Button, Field, IconButton, Select, TextInput } from './primitives';\n\ninterface FilterValueInputProps {\n item: MGHGridFilterItem;\n column: MGHGridColDef;\n operator: MGHGridFilterOperator | undefined;\n onChange: (value: any) => void;\n placeholder: string;\n}\n\nconst useDebouncedValue = (value: any, onCommit: (value: any) => void, delay = 250) => {\n const [local, setLocal] = React.useState(value ?? '');\n const timer = React.useRef<number | null>(null);\n React.useEffect(() => {\n setLocal(value ?? '');\n }, [value]);\n const update = (next: any) => {\n setLocal(next);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => onCommit(next), delay);\n };\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n return [local, update] as const;\n};\n\nfunction TextValueInput({ item, onChange, placeholder, type }: FilterValueInputProps & { type: string }) {\n const [local, update] = useDebouncedValue(item.value, onChange);\n return (\n <TextInput\n size=\"small\"\n type={type}\n value={local}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction MultiValueInput({ item, column, onChange, placeholder }: FilterValueInputProps) {\n const joined = Array.isArray(item.value) ? item.value.join(', ') : (item.value ?? '');\n const [local, update] = useDebouncedValue(joined, (text: string) =>\n onChange(\n String(text)\n .split(',')\n .map((v) => v.trim())\n .filter((v) => v !== '')\n )\n );\n if (column.type === 'singleSelect') {\n const options = resolveValueOptions(column);\n const selected: string[] = Array.isArray(item.value) ? item.value.map(String) : [];\n return (\n <Select\n multiple\n size=\"small\"\n value={selected}\n aria-label={placeholder}\n onChange={(event) => {\n const values = Array.from(event.target.selectedOptions).map((option) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === option.value);\n return match !== undefined ? getOptionValue(column, match) : option.value;\n });\n onChange(values);\n }}\n >\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n return (\n <TextInput\n size=\"small\"\n value={local}\n placeholder=\"Comma separated values\"\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction FilterValueInput(props: FilterValueInputProps) {\n const { item, column, operator, onChange, placeholder } = props;\n const { api } = useMGHGridContext();\n const inputType = operator?.inputType ?? 'text';\n\n if (operator?.InputComponent) {\n const Component = operator.InputComponent;\n return <Component item={item} column={column} applyValue={(next) => onChange(next.value)} api={api} />;\n }\n\n switch (inputType) {\n case 'none':\n return <div />;\n case 'boolean':\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n >\n <option value=\"\">any</option>\n <option value=\"true\">yes</option>\n <option value=\"false\">no</option>\n </Select>\n );\n case 'select': {\n const options = resolveValueOptions(column);\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === event.target.value);\n onChange(\n event.target.value === ''\n ? undefined\n : match !== undefined\n ? getOptionValue(column, match)\n : event.target.value\n );\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'multiselect':\n return <MultiValueInput {...props} />;\n case 'number':\n return <TextValueInput {...props} type=\"number\" />;\n case 'date':\n return <TextValueInput {...props} type=\"date\" />;\n case 'datetime-local':\n return <TextValueInput {...props} type=\"datetime-local\" />;\n default:\n return <TextValueInput {...props} type=\"text\" />;\n }\n}\n\nconst createFilterItem = (column: MGHGridColDef | undefined): MGHGridFilterItem => ({\n id: uniqueId('filter'),\n field: column?.field ?? '',\n operator: column ? (getColumnFilterOperators(column)[0]?.value ?? 'contains') : 'contains',\n value: undefined,\n});\n\nexport function MGHGridFilterPanel() {\n const { api, state, localeText, columns, rootProps } = useMGHGridContext();\n const filterableColumns = React.useMemo(() => columns.filter((col) => col.filterable !== false), [columns]);\n const byField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n filterableColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [filterableColumns]);\n\n const items = state.filterModel.items;\n const logicOperator = state.filterModel.logicOperator ?? 'and';\n const targetField = state.preferencePanel.targetField;\n\n // Ensure at least one (possibly empty) item is displayed when the panel opens, like MUI does.\n const seeded = React.useRef(false);\n React.useEffect(() => {\n if (seeded.current) return;\n seeded.current = true;\n if (targetField && byField.has(targetField)) {\n const existing = items.find((item) => item.field === targetField);\n if (!existing) api.upsertFilterItem(createFilterItem(byField.get(targetField)));\n } else if (items.length === 0 && filterableColumns.length > 0) {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n }\n }, [api, byField, filterableColumns, items, targetField]);\n\n const updateItem = (item: MGHGridFilterItem, patch: Partial<MGHGridFilterItem>) => {\n api.upsertFilterItem({ ...item, ...patch });\n };\n\n const addItem = () => {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n };\n\n const canAddMore = !rootProps.disableMultipleColumnsFiltering || items.length === 0;\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarFilters}>\n <div className=\"mgh-grid-panel-content\" style={{ paddingTop: 12 }}>\n {items.length === 0 && <div className=\"mgh-grid-filter-empty\">No filters</div>}\n {items.map((item, index) => {\n const column = byField.get(item.field) ?? filterableColumns[0];\n const operators = column ? getColumnFilterOperators(column) : [];\n const operator = operators.find((op) => op.value === item.operator) ?? operators[0];\n const showLogic = items.length > 1;\n return (\n <div\n key={String(item.id ?? index)}\n className={\n showLogic ? 'mgh-grid-filter-row mgh-grid-filter-row--with-logic' : 'mgh-grid-filter-row'\n }\n >\n <IconButton\n size=\"small\"\n label={localeText.filterPanelDeleteIcon}\n onClick={() => api.deleteFilterItem(item)}\n >\n <DeleteIcon />\n </IconButton>\n {showLogic && (\n <Field label={index === 1 ? localeText.filterPanelLogicOperator : ' '}>\n {index === 0 ? (\n <div style={{ height: 32 }} />\n ) : (\n <Select\n size=\"small\"\n value={logicOperator}\n disabled={index > 1}\n aria-label={localeText.filterPanelLogicOperator}\n onChange={(event) =>\n api.setFilterLogicOperator(event.target.value as 'and' | 'or')\n }\n >\n <option value=\"and\">{localeText.filterPanelOperatorAnd}</option>\n <option value=\"or\">{localeText.filterPanelOperatorOr}</option>\n </Select>\n )}\n </Field>\n )}\n <Field label={localeText.filterPanelColumns}>\n <Select\n size=\"small\"\n value={column?.field ?? ''}\n aria-label={localeText.filterPanelColumns}\n onChange={(event) => {\n const nextColumn = byField.get(event.target.value);\n const nextOperators = nextColumn ? getColumnFilterOperators(nextColumn) : [];\n const keepOperator = nextOperators.some((op) => op.value === item.operator);\n updateItem(item, {\n field: event.target.value,\n operator: keepOperator ? item.operator : (nextOperators[0]?.value ?? 'contains'),\n value: undefined,\n });\n }}\n >\n {filterableColumns.map((col) => (\n <option key={col.field} value={col.field}>\n {col.headerName ?? col.field}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelOperator}>\n <Select\n size=\"small\"\n value={operator?.value ?? ''}\n aria-label={localeText.filterPanelOperator}\n onChange={(event) => {\n const nextOperator = operators.find((op) => op.value === event.target.value);\n const nextIsMulti = nextOperator?.inputType === 'multiselect';\n const currentIsMulti = operator?.inputType === 'multiselect';\n updateItem(item, {\n operator: event.target.value,\n value: nextIsMulti !== currentIsMulti ? undefined : item.value,\n });\n }}\n >\n {operators.map((op) => (\n <option key={op.value} value={op.value}>\n {op.label ?? op.value}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelValue}>\n {column ? (\n <FilterValueInput\n item={item}\n column={column}\n operator={operator}\n placeholder={localeText.filterPanelInputPlaceholder}\n onChange={(value) => updateItem(item, { value })}\n />\n ) : (\n <div />\n )}\n </Field>\n </div>\n );\n })}\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button\n variant=\"primary\"\n size=\"small\"\n startIcon={<AddIcon size={18} />}\n onClick={addItem}\n disabled={!canAddMore}\n >\n {localeText.filterPanelAddFilter}\n </Button>\n <Button\n size=\"small\"\n startIcon={<DeleteIcon size={18} />}\n disabled={items.length === 0}\n onClick={() => api.setFilterModel({ ...state.filterModel, items: [] })}\n >\n {localeText.filterPanelRemoveAll}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridThemeMode } from '../MGHGrid.types';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n FilterListIcon,\n FunctionsIcon,\n PushPinIcon,\n ViewColumnIcon,\n VisibilityOffIcon,\n WorkspacesIcon,\n} from '../icons';\nimport { GROUPING_COLUMN_FIELD } from '../utils';\nimport { Menu, MenuDivider, MenuItem, MenuSection, Popover, Select } from './primitives';\n\nexport interface MGHGridColumnMenuProps {\n column: MGHGridColDef;\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n themeMode: MGHGridThemeMode;\n /** Anchor for panels opened from the menu (usually the toolbar button or the header cell). */\n panelAnchorEl?: HTMLElement | null;\n}\n\nexport function MGHGridColumnMenu({ column, anchorEl, open, onClose, themeMode, panelAnchorEl }: MGHGridColumnMenuProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const field = column.field;\n const isGroupingColumn = field === GROUPING_COLUMN_FIELD;\n const sortItem = state.sortModel.find((item) => item.field === field);\n const pinned = api.isColumnPinned(field);\n const isGrouped = state.rowGroupingModel.indexOf(field) !== -1;\n const aggregation = state.aggregationModel[field];\n\n const canSort = column.sortable !== false && !rootProps.disableColumnSorting;\n const canFilter = column.filterable !== false && !rootProps.disableColumnFilter && !isGroupingColumn;\n const canHide = column.hideable !== false;\n const canPin = column.pinnable !== false && !rootProps.disableColumnPinning;\n const canGroup = column.groupable !== false && !rootProps.disableRowGrouping && !isGroupingColumn;\n const aggregationFunctions = Object.keys(rootProps.aggregationFunctions).filter((name) => {\n const fn = rootProps.aggregationFunctions[name];\n if (column.availableAggregationFunctions && column.availableAggregationFunctions.indexOf(name) === -1) return false;\n if (fn.columnTypes && column.type && fn.columnTypes.indexOf(column.type) === -1) return false;\n return true;\n });\n const canAggregate =\n column.aggregable !== false && !rootProps.disableAggregation && !isGroupingColumn && aggregationFunctions.length > 0;\n\n const anchorForPanel = panelAnchorEl ?? anchorEl;\n const name = column.headerName ?? column.field;\n\n return (\n <Popover open={open} anchorEl={anchorEl} onClose={onClose} themeMode={themeMode} placement=\"bottom-end\" role=\"menu\">\n <Menu aria-label={localeText.columnMenuLabel}>\n {canSort && (\n <>\n <MenuItem\n icon={<ArrowUpwardIcon />}\n selected={sortItem?.sort === 'asc'}\n onClick={() => api.sortColumn(field, 'asc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortAsc}\n </MenuItem>\n <MenuItem\n icon={<ArrowDownwardIcon />}\n selected={sortItem?.sort === 'desc'}\n onClick={() => api.sortColumn(field, 'desc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortDesc}\n </MenuItem>\n {sortItem && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.sortColumn(field, null)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnsort}\n </MenuItem>\n )}\n </>\n )}\n {canFilter && (\n <>\n {canSort && <MenuDivider />}\n <MenuItem\n icon={<FilterListIcon />}\n onClick={() => api.showFilterPanel(field, anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuFilter}\n </MenuItem>\n </>\n )}\n {(canHide || !rootProps.disableColumnSelector) && (\n <>\n {(canSort || canFilter) && <MenuDivider />}\n {canHide && (\n <MenuItem\n icon={<VisibilityOffIcon />}\n onClick={() => api.setColumnVisibility(field, false)}\n hideMenu={onClose}\n >\n {localeText.columnMenuHideColumn}\n </MenuItem>\n )}\n {!rootProps.disableColumnSelector && (\n <MenuItem\n icon={<ViewColumnIcon />}\n onClick={() => api.showPreferences('columns', anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuManageColumns}\n </MenuItem>\n )}\n </>\n )}\n {canPin && (\n <>\n <MenuDivider />\n {pinned !== 'left' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(30deg)' }} />}\n onClick={() => api.pinColumn(field, 'left')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinLeft}\n </MenuItem>\n )}\n {pinned !== 'right' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(-30deg)' }} />}\n onClick={() => api.pinColumn(field, 'right')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinRight}\n </MenuItem>\n )}\n {pinned && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.unpinColumn(field)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnpin}\n </MenuItem>\n )}\n </>\n )}\n {canGroup && (\n <>\n <MenuDivider />\n <MenuItem\n icon={<WorkspacesIcon />}\n onClick={() =>\n isGrouped ? api.removeRowGroupingCriteria(field) : api.addRowGroupingCriteria(field)\n }\n hideMenu={onClose}\n >\n {isGrouped ? localeText.columnMenuUngroup(name) : localeText.columnMenuGroup(name)}\n </MenuItem>\n </>\n )}\n {canAggregate && (\n <>\n <MenuDivider />\n <MenuSection>\n <label\n className=\"mgh-grid-field-label\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <FunctionsIcon size={16} /> {localeText.columnMenuAggregation}\n </label>\n <Select\n size=\"small\"\n value={aggregation ?? ''}\n aria-label={localeText.columnMenuAggregation}\n onChange={(event) => {\n const next = { ...state.aggregationModel };\n if (event.target.value === '') delete next[field];\n else next[field] = event.target.value;\n api.setAggregationModel(next);\n }}\n >\n <option value=\"\">{localeText.aggregationFunctionLabelNone}</option>\n {aggregationFunctions.map((fnName) => (\n <option key={fnName} value={fnName}>\n {rootProps.aggregationFunctions[fnName].label ?? fnName}\n </option>\n ))}\n </Select>\n </MenuSection>\n </>\n )}\n </Menu>\n </Popover>\n );\n}\n","import React from 'react';\nimport { MGHGridLoadingOverlayProps, MGHGridNoRowsOverlayProps } from '../MGHGrid.types';\nimport { EmptyBoxIcon } from '../icons';\nimport { Spinner } from './primitives';\n\n/** Default \"no rows\" overlay. Mirrors the legacy CustomNoRowsOverlay but has no MUI dependency. */\nexport function MGHGridNoRowsOverlay({ text = 'No rows', imageSrc }: MGHGridNoRowsOverlayProps) {\n return (\n <div className=\"mgh-grid-no-rows\" role=\"status\">\n {imageSrc ? <img alt=\"\" src={imageSrc} /> : <EmptyBoxIcon size={50} />}\n <div>{text}</div>\n </div>\n );\n}\n\nexport function MGHGridLoadingOverlay({ text }: MGHGridLoadingOverlayProps) {\n return (\n <>\n <Spinner />\n {text && <div>{text}</div>}\n </>\n );\n}\n","import React from 'react';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { MoreVertIcon } from '../icons';\nimport { IconButton, Menu, MenuItem, Popover } from './primitives';\n\nexport interface MGHGridActionsCellItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n icon?: React.ReactElement;\n label: string;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Render the action inside the \"more\" menu instead of inline. */\n showInMenu?: boolean;\n disabled?: boolean;\n}\n\n/** Drop-in replacement for MUI's GridActionsCellItem. Use it from `colDef.getActions`. */\nexport function MGHGridActionsCellItem({\n icon,\n label,\n onClick,\n showInMenu,\n disabled,\n className,\n ...rest\n}: MGHGridActionsCellItemProps) {\n return (\n <IconButton\n size=\"small\"\n label={label}\n disabled={disabled}\n className={className}\n onClick={(event) => {\n event.stopPropagation();\n onClick?.(event);\n }}\n {...rest}\n >\n {icon}\n </IconButton>\n );\n}\nMGHGridActionsCellItem.displayName = 'MGHGridActionsCellItem';\n\ninterface ActionsCellProps {\n actions: React.ReactElement[];\n themeMode: MGHGridThemeMode;\n moreLabel: string;\n}\n\nexport function ActionsCell({ actions, themeMode, moreLabel }: ActionsCellProps) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const inline: React.ReactElement[] = [];\n const inMenu: React.ReactElement[] = [];\n actions.forEach((action) => {\n if (!React.isValidElement(action)) return;\n if ((action.props as MGHGridActionsCellItemProps)?.showInMenu) inMenu.push(action);\n else inline.push(action);\n });\n\n return (\n <>\n {inline.map((action, index) => (\n <React.Fragment key={action.key ?? index}>{action}</React.Fragment>\n ))}\n {inMenu.length > 0 && (\n <>\n <IconButton\n size=\"small\"\n label={moreLabel}\n active={Boolean(anchor)}\n onClick={(event) => {\n event.stopPropagation();\n setAnchor((prev) => (prev ? null : event.currentTarget));\n }}\n >\n <MoreVertIcon />\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n placement=\"bottom-end\"\n role=\"menu\"\n >\n <Menu>\n {inMenu.map((action, index) => {\n const props = action.props as MGHGridActionsCellItemProps;\n return (\n <MenuItem\n key={action.key ?? index}\n icon={props.icon}\n disabled={props.disabled}\n onClick={(event) => {\n props.onClick?.(event);\n setAnchor(null);\n }}\n >\n {props.label}\n </MenuItem>\n );\n })}\n </Menu>\n </Popover>\n </>\n )}\n </>\n );\n}\n","import React from 'react';\nimport {\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridApplyFilterFn,\n MGHGridCallbackDetails,\n MGHGridCellParams,\n MGHGridColDef,\n MGHGridColumnVisibilityModel,\n MGHGridDensity,\n MGHGridFilterItem,\n MGHGridFilterModel,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridLocaleText,\n MGHGridPaginationModel,\n MGHGridPinnedColumns,\n MGHGridPinnedSide,\n MGHGridPreferencePanelState,\n MGHGridPrintExportOptions,\n MGHGridProps,\n MGHGridRowGroupingModel,\n MGHGridRowId,\n MGHGridRowNode,\n MGHGridRowParams,\n MGHGridRowSelectionModel,\n MGHGridSortDirection,\n MGHGridSortModel,\n MGHGridState,\n MGHGridSxProps,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport {\n AGGREGATION_FOOTER_ID,\n BUILT_IN_AGGREGATION_FUNCTIONS,\n CHECKBOX_COLUMN_DEF,\n CHECKBOX_FIELD,\n DEFAULT_COLUMN_MIN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_LOCALE_TEXT,\n DEFAULT_ROW_HEIGHT,\n DENSITY_FACTORS,\n DETAIL_PANEL_TOGGLE_COLUMN_DEF,\n DETAIL_PANEL_TOGGLE_FIELD,\n GROUPING_COLUMN_FIELD,\n GROUPING_COLUMN_WIDTH,\n clamp,\n cx,\n defaultFormatValue,\n formattedValueToString,\n getCellValue,\n getColumnFilterOperators,\n getDefaultComparator,\n getFormattedValue,\n getOptionLabel,\n getOptionValue,\n getRowIdFromRow,\n buildScopedCss,\n isInternalField,\n isNil,\n isSelectorKey,\n measureText,\n moveItem,\n normalizeColumn,\n normalizeSelectionModel,\n parseEditValue,\n readLocalStorage,\n resolveValueOptions,\n selectionModelsEqual,\n toDate,\n writeLocalStorage,\n} from './utils';\nimport { useMGHGridStyles } from './MGHGrid.styles';\nimport { MGHGridContext, MGHGridContextValue, MGHGridRootProps } from './context';\nimport { useControlledState, useElementSize, useForceUpdate, useLatestRef, useStableId } from './hooks';\nimport { exportDataAsCsv, exportDataAsExcel, getDataAsCsv } from './export';\nimport { printGridElement } from './print';\nimport {\n DisplayRow,\n GroupTreeNode,\n RowEntry,\n aggregateRows,\n buildGroupTree,\n collectTreeLeaves,\n flattenGroupTree,\n sortGroupTree,\n} from './grouping';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n CheckIcon,\n ChevronRightIcon,\n CloseIcon,\n ExpandMoreIcon,\n MoreVertIcon,\n} from './icons';\nimport { Checkbox, IconButton, Popover, Select, TextInput } from './components/primitives';\nimport { MGHGridToolbar } from './components/Toolbar';\nimport { MGHGridFooter } from './components/Footer';\nimport { MGHGridColumnsPanel } from './components/ColumnsPanel';\nimport { MGHGridFilterPanel } from './components/FilterPanel';\nimport { MGHGridColumnMenu } from './components/ColumnMenu';\nimport { MGHGridLoadingOverlay, MGHGridNoRowsOverlay } from './components/Overlays';\nimport { ActionsCell } from './components/ActionsCell';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants & helpers\n * ----------------------------------------------------------------------------------------------- */\n\nconst EMPTY_ARRAY: any[] = [];\nconst EMPTY_OBJECT: Record<string, any> = {};\nconst EMPTY_MAP = new Map<any, any>();\nconst DEFAULT_SORTING_ORDER: MGHGridSortDirection[] = ['asc', 'desc', null];\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\nconst DEFAULT_FILTER_MODEL: MGHGridFilterModel = { items: [], quickFilterExcludeHiddenColumns: false };\nconst OVERSCAN_ROWS = 6;\nconst DEFAULT_DETAIL_PANEL_HEIGHT = 500;\n\ninterface ColumnLayout {\n col: MGHGridColDef;\n width: number;\n pinned: MGHGridPinnedSide | null;\n /** Sticky offset (left or right) for pinned columns. */\n offset: number;\n /** X position from the start of the row. */\n x: number;\n isLastLeft: boolean;\n isFirstRight: boolean;\n}\n\ntype RenderRowKind = 'leaf' | 'group' | 'pinnedRow' | 'footer';\n\ninterface RenderRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n kind: RenderRowKind;\n row: R | null;\n node: MGHGridRowNode;\n depth: number;\n group?: GroupTreeNode<R>;\n aggregates?: Record<string, { value: any; fn: string }>;\n}\n\ninterface CellCoords {\n id: MGHGridRowId;\n field: string;\n}\n\n/** Keeps only the inline-applicable part of an sx-like object (nested selectors are compiled to CSS). */\nconst sanitizeStyle = (style: MGHGridSxProps | undefined): React.CSSProperties | undefined => {\n if (!style) return undefined;\n const out: Record<string, any> = {};\n Object.keys(style).forEach((key) => {\n if (isSelectorKey(key)) return;\n const value = (style as any)[key];\n if (typeof value !== 'string' && typeof value !== 'number') return;\n out[key] = value;\n });\n return out;\n};\n\nconst computeWidths = (cols: MGHGridColDef[], available: number, overrides: Record<string, number>) => {\n const result: Array<number | null> = cols.map((col) => {\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const override = overrides[col.field];\n if (override) return clamp(override, min, max);\n if (col.flex && col.flex > 0) return null;\n return clamp(col.width ?? 100, min, max);\n });\n const pool: number[] = [];\n let fixedTotal = 0;\n result.forEach((w, i) => {\n if (w === null) pool.push(i);\n else fixedTotal += w;\n });\n if (pool.length > 0) {\n let remainingSpace = Math.max(0, available - fixedTotal);\n let remainingFlex = pool.reduce((acc, i) => acc + (cols[i].flex as number), 0);\n let active = pool.slice();\n let changed = true;\n while (changed && active.length > 0) {\n changed = false;\n for (let k = 0; k < active.length; k += 1) {\n const i = active[k];\n const col = cols[i];\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const share = remainingFlex > 0 ? (remainingSpace * (col.flex as number)) / remainingFlex : 0;\n if (share < min || share > max) {\n const fixed = share < min ? min : max;\n result[i] = fixed;\n remainingSpace = Math.max(0, remainingSpace - fixed);\n remainingFlex -= col.flex as number;\n active = active.filter((idx) => idx !== i);\n changed = true;\n break;\n }\n }\n }\n active.forEach((i) => {\n const col = cols[i];\n result[i] =\n remainingFlex > 0\n ? Math.floor((remainingSpace * (col.flex as number)) / remainingFlex)\n : (col.minWidth ?? 50);\n });\n }\n return result as number[];\n};\n\nconst toDateInputValue = (value: any, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n return withTime ? `${base}T${pad(date.getHours())}:${pad(date.getMinutes())}` : base;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Component\n * ----------------------------------------------------------------------------------------------- */\n\nexport default function MGHGrid<R extends MGHGridValidRowModel = any>(props: MGHGridProps<R>) {\n const {\n rows,\n columns: columnsProp,\n getRowId,\n loading = false,\n header,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n disableCard = false,\n className,\n cardClassName,\n boxClassName,\n cardStyle,\n cardSx,\n boxStyle,\n boxSx,\n style,\n sx,\n themeMode = 'light',\n themeVars,\n showToolbar = true,\n toolbarProps,\n slots = EMPTY_OBJECT,\n slotProps = EMPTY_OBJECT,\n noRowsText = 'No data found within selected parameters.',\n localeText: localeTextProp,\n rowHeight: rowHeightProp = DEFAULT_ROW_HEIGHT,\n columnHeaderHeight = DEFAULT_HEADER_HEIGHT,\n getRowHeight,\n autoHeight = false,\n disableVirtualization = false,\n density: densityProp,\n onDensityChange,\n disableDensitySelector = false,\n pagination = true,\n pageSize = 25,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationModel: paginationModelProp,\n onPaginationModelChange,\n hideFooter = false,\n hideFooterPagination = false,\n hideFooterRowCount = false,\n hideFooterSelectedRowCount = false,\n sortModel: sortModelProp,\n onSortModelChange,\n sortingOrder = DEFAULT_SORTING_ORDER,\n disableMultipleColumnsSorting = false,\n disableColumnSorting = false,\n filterModel: filterModelProp,\n onFilterModelChange,\n disableColumnFilter = false,\n disableMultipleColumnsFiltering = false,\n quickFilterDebounceMs = 150,\n columnVisibilityModel: columnVisibilityModelProp,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n columnWidthStorageKey,\n pinnedColumnsStorageKey,\n onColumnOrderChange,\n onColumnWidthChange,\n disableColumnMenu = false,\n disableColumnSelector = false,\n disableColumnResize = false,\n disableColumnReorder = false,\n disableColumnPinning = false,\n pinnedColumns: pinnedColumnsProp,\n onPinnedColumnsChange,\n checkboxSelection = false,\n checkboxSelectionVisibleOnly = false,\n disableRowSelectionOnClick = true,\n disableMultipleRowSelection = false,\n rowSelectionModel: rowSelectionModelProp,\n onRowSelectionModelChange,\n isRowSelectable,\n keepNonExistentRowsSelected = true,\n getRowClassName,\n onRowClick,\n onRowDoubleClick,\n onCellClick,\n onCellDoubleClick,\n pinnedRows,\n getDetailPanelContent,\n getDetailPanelHeight,\n detailPanelExpandedRowIds: detailPanelExpandedRowIdsProp,\n onDetailPanelExpandedRowIdsChange,\n rowGroupingModel: rowGroupingModelProp,\n onRowGroupingModelChange,\n defaultGroupingExpansionDepth = 0,\n groupingColDef,\n disableRowGrouping = false,\n isGroupExpandedByDefault,\n aggregationModel: aggregationModelProp,\n onAggregationModelChange,\n aggregationFunctions: aggregationFunctionsProp,\n disableAggregation = false,\n aggregationPosition = 'both',\n processRowUpdate,\n onProcessRowUpdateError,\n onCellEditStop,\n isCellEditable,\n initialState,\n apiRef,\n onStateChange,\n } = props;\n\n useMGHGridStyles();\n\n const gridId = useStableId('mgh-grid');\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const cardRef = React.useRef<HTMLDivElement | null>(null);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const toolbarRef = React.useRef<HTMLDivElement | null>(null);\n const forceUpdate = useForceUpdate();\n\n const localeText = React.useMemo<MGHGridLocaleText>(\n () => ({ ...DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n\n /* ------------------------------------------------------------------ latest ref + api shell */\n\n const latest = React.useRef<any>({});\n const getDetails = React.useCallback((): MGHGridCallbackDetails => ({ api: latest.current.api }), []);\n\n const apiObject = React.useMemo<MGHGridApi<R>>(() => {\n const L = () => latest.current;\n const apiImpl: MGHGridApi<R> = {\n getRow: (id) => L().rowsById.get(id) ?? null,\n getRowModels: () => new Map(L().rowsById),\n getAllRowIds: () => L().rowEntries.map((e: RowEntry<R>) => e.id),\n getRowNode: (id) => L().nodesById.get(id) ?? null,\n getSortedRows: () => L().sortedLeaves.map((e: RowEntry<R>) => e.row),\n getSortedRowIds: () => L().sortedLeaves.map((e: RowEntry<R>) => e.id),\n getVisibleRows: () =>\n L()\n .pagedRows.filter((dr: DisplayRow<R>) => dr.type === 'leaf' && dr.row)\n .map((dr: DisplayRow<R>) => ({ id: dr.id, model: dr.row as R })),\n getRowIndexRelativeToVisibleRows: (id) => L().pagedRows.findIndex((dr: DisplayRow<R>) => dr.id === id),\n updateRows: (updates) => {\n updates.forEach((update) => {\n const id = getRowIdFromRow(update as R, L().getRowId);\n const existing = L().rowsById.get(id);\n if (existing) L().setRowOverride(id, { ...existing, ...update });\n });\n },\n\n getAllColumns: () => L().orderedUserColumns,\n getVisibleColumns: () => L().visibleUserColumns,\n getColumn: (field) => L().getColumn(field),\n getColumnIndex: (field, useVisibleColumns = true) =>\n (useVisibleColumns ? L().visibleUserColumns : L().orderedUserColumns).findIndex(\n (c: MGHGridColDef) => c.field === field\n ),\n getColumnVisibilityModel: () => L().columnVisibilityModel,\n setColumnVisibility: (field, isVisible) =>\n L().setColumnVisibilityModel({ ...L().columnVisibilityModel, [field]: isVisible }),\n setColumnVisibilityModel: (model) => L().setColumnVisibilityModel(model),\n setColumnWidth: (field, width) => L().setColumnWidth(field, width),\n setColumnIndex: (field, targetIndex) => L().setColumnIndex(field, targetIndex),\n autosizeColumns: (options) => L().autosizeColumns(options),\n pinColumn: (field, side) => L().pinColumn(field, side),\n unpinColumn: (field) => L().unpinColumn(field),\n isColumnPinned: (field) => L().isColumnPinned(field),\n getPinnedColumns: () => L().pinnedColumns,\n setPinnedColumns: (model) => L().setPinnedColumns(model),\n\n getSortModel: () => L().sortModel,\n setSortModel: (model) => L().setSortModel(model),\n sortColumn: (field, direction, allowMultipleSorting) => L().sortColumn(field, direction, allowMultipleSorting),\n\n getFilterModel: () => L().filterModel,\n setFilterModel: (model) => L().setFilterModel(model),\n upsertFilterItem: (item) => L().upsertFilterItems([item]),\n upsertFilterItems: (items) => L().upsertFilterItems(items),\n deleteFilterItem: (item) => L().deleteFilterItem(item),\n setFilterLogicOperator: (operator) => L().setFilterModel({ ...L().filterModel, logicOperator: operator }),\n setQuickFilterValues: (values) => L().setFilterModel({ ...L().filterModel, quickFilterValues: values }),\n showFilterPanel: (targetColumnField, anchorEl) => L().showPreferences('filters', anchorEl, targetColumnField),\n hideFilterPanel: () => L().hidePreferences(),\n showPreferences: (panel, anchorEl, targetField) => L().showPreferences(panel, anchorEl, targetField),\n hidePreferences: () => L().hidePreferences(),\n\n getSelectedRows: () => {\n const map = new Map<MGHGridRowId, R>();\n L().selectedIds.forEach((id: MGHGridRowId) => {\n const row = L().rowsById.get(id);\n if (row) map.set(id, row);\n });\n return map;\n },\n getRowSelectionModel: () => ({ type: 'include', ids: L().selectedIds }),\n setRowSelectionModel: (model) => {\n const normalized = normalizeSelectionModel(\n model,\n L().rowEntries.map((e: RowEntry<R>) => e.id)\n );\n L().setSelectedIds(normalized.ids);\n },\n selectRow: (id, isSelected = true, resetSelection = false) => L().selectRows([id], isSelected, resetSelection),\n selectRows: (ids, isSelected = true, resetSelection = false) => L().selectRows(ids, isSelected, resetSelection),\n isRowSelected: (id) => L().selectedIds.has(id),\n isRowSelectable: (id) => L().isRowSelectableFn(id, L().rowsById.get(id)),\n\n setPage: (nextPage) => L().setPaginationModel({ ...L().paginationModel, page: Math.max(0, nextPage) }),\n setPageSize: (nextPageSize) => L().setPaginationModel({ page: 0, pageSize: Math.max(1, nextPageSize) }),\n setPaginationModel: (model) => L().setPaginationModel(model),\n\n setDensity: (value) => L().setDensity(value),\n\n getDataAsCsv: (options) => getDataAsCsv(apiImpl, options),\n exportDataAsCsv: (options) => exportDataAsCsv(apiImpl, options),\n exportDataAsExcel: (options) => exportDataAsExcel(apiImpl, options),\n exportDataAsPrint: (options) => L().startPrint(options),\n\n toggleDetailPanel: (id) => L().toggleDetailPanel(id),\n setExpandedDetailPanels: (ids) => L().setExpandedDetailPanels(new Set(ids)),\n getExpandedDetailPanels: () => Array.from(L().expandedDetailPanels as Set<MGHGridRowId>),\n\n getRowGroupingModel: () => L().rowGroupingModel,\n setRowGroupingModel: (model) => L().setRowGroupingModel(model),\n addRowGroupingCriteria: (field, groupingIndex) => {\n const current: string[] = L().rowGroupingModel.filter((f: string) => f !== field);\n if (groupingIndex === undefined) current.push(field);\n else current.splice(clamp(groupingIndex, 0, current.length), 0, field);\n L().setRowGroupingModel(current);\n },\n removeRowGroupingCriteria: (field) =>\n L().setRowGroupingModel(L().rowGroupingModel.filter((f: string) => f !== field)),\n setRowChildrenExpansion: (id, isExpanded) => L().setRowChildrenExpansion(id, isExpanded),\n getRowGroupChildren: ({ groupId }) => {\n const group = L().groupsById.get(groupId) as GroupTreeNode<R> | undefined;\n return group ? group.descendants.map((d) => d.id) : [];\n },\n\n getAggregationModel: () => L().aggregationModel,\n setAggregationModel: (model) => L().setAggregationModel(model),\n\n startCellEditMode: ({ id, field }) => L().startCellEditMode(id, field),\n stopCellEditMode: ({ id, field, ignoreModifications }) =>\n L().stopCellEditMode(id, field, ignoreModifications, 'api'),\n getCellMode: (id, field) => {\n const editing = L().editingCell as CellCoords | null;\n return editing && editing.id === id && editing.field === field ? 'edit' : 'view';\n },\n setEditCellValue: ({ id, field, value }) => {\n const editing = L().editingCell as CellCoords | null;\n if (editing && editing.id === id && editing.field === field) L().setEditValue(value);\n },\n\n getCellValue: (id, field) => {\n const row = L().rowsById.get(id);\n const col = L().getColumn(field);\n return row && col ? getCellValue(row, col, apiImpl) : undefined;\n },\n getCellParams: (id, field) => {\n const row = L().rowsById.get(id);\n return L().buildCellParams(\n id,\n field,\n row,\n L().nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null }\n );\n },\n setCellFocus: (id, field) => {\n pendingFocusRef.current = true;\n L().setFocusedCell({ id, field });\n },\n\n scrollToIndexes: (params) => L().scrollToIndexes(params),\n scroll: ({ left, top }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n if (left !== undefined) scroller.scrollLeft = left;\n if (top !== undefined) scroller.scrollTop = top;\n },\n getScrollPosition: () => ({\n left: scrollerRef.current?.scrollLeft ?? 0,\n top: scrollerRef.current?.scrollTop ?? 0,\n }),\n\n get state() {\n return L().state as MGHGridState;\n },\n forceUpdate: () => L().forceUpdate(),\n rootElementRef: rootRef,\n };\n return apiImpl;\n }, []);\n if (!latest.current.api) latest.current.api = apiObject;\n\n /* ------------------------------------------------------------------ persisted state */\n\n const persisted = React.useMemo(\n () => ({\n visibility: columnVisibilityStorageKey\n ? readLocalStorage<MGHGridColumnVisibilityModel>(columnVisibilityStorageKey)\n : null,\n order: columnOrderStorageKey ? readLocalStorage<string[]>(columnOrderStorageKey) : null,\n widths: columnWidthStorageKey ? readLocalStorage<Record<string, number>>(columnWidthStorageKey) : null,\n pinned: pinnedColumnsStorageKey ? readLocalStorage<MGHGridPinnedColumns>(pinnedColumnsStorageKey) : null,\n }),\n [columnVisibilityStorageKey, columnOrderStorageKey, columnWidthStorageKey, pinnedColumnsStorageKey]\n );\n\n /* ------------------------------------------------------------------ models */\n\n const [sortModel, setSortModel] = useControlledState<MGHGridSortModel>(\n sortModelProp,\n initialState?.sorting?.sortModel ?? EMPTY_ARRAY,\n (model) => onSortModelChange?.(model, getDetails())\n );\n\n const [filterModel, setFilterModel] = useControlledState<MGHGridFilterModel>(\n filterModelProp,\n initialState?.filter?.filterModel ?? DEFAULT_FILTER_MODEL,\n (model) => onFilterModelChange?.(model, getDetails())\n );\n\n const [paginationModel, setPaginationModel] = useControlledState<MGHGridPaginationModel>(\n paginationModelProp,\n {\n page: initialState?.pagination?.paginationModel?.page ?? 0,\n pageSize: initialState?.pagination?.paginationModel?.pageSize ?? pageSize,\n },\n (model) => onPaginationModelChange?.(model, getDetails())\n );\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useControlledState<MGHGridColumnVisibilityModel>(\n columnVisibilityModelProp,\n persisted.visibility ?? initialState?.columns?.columnVisibilityModel ?? EMPTY_OBJECT,\n (model) => {\n if (columnVisibilityStorageKey) writeLocalStorage(columnVisibilityStorageKey, model);\n onColumnVisibilityModelChange?.(model, getDetails());\n }\n );\n\n const [density, setDensity] = useControlledState<MGHGridDensity>(\n densityProp,\n initialState?.density ?? 'compact',\n (value) => onDensityChange?.(value, getDetails())\n );\n\n const [pinnedColumns, setPinnedColumns] = useControlledState<MGHGridPinnedColumns>(\n pinnedColumnsProp,\n persisted.pinned ?? initialState?.pinnedColumns ?? EMPTY_OBJECT,\n (model) => {\n if (pinnedColumnsStorageKey) writeLocalStorage(pinnedColumnsStorageKey, model);\n onPinnedColumnsChange?.(model, getDetails());\n }\n );\n\n const [rowGroupingModel, setRowGroupingModel] = useControlledState<MGHGridRowGroupingModel>(\n rowGroupingModelProp,\n initialState?.rowGrouping?.model ?? EMPTY_ARRAY,\n (model) => onRowGroupingModelChange?.(model, getDetails())\n );\n\n const [aggregationModel, setAggregationModel] = useControlledState<MGHGridAggregationModel>(\n aggregationModelProp,\n initialState?.aggregation?.model ?? EMPTY_OBJECT,\n (model) => onAggregationModelChange?.(model, getDetails())\n );\n\n const controlledExpandedDetail = React.useMemo(\n () => (detailPanelExpandedRowIdsProp ? new Set<MGHGridRowId>(detailPanelExpandedRowIdsProp) : undefined),\n [detailPanelExpandedRowIdsProp]\n );\n const [expandedDetailPanels, setExpandedDetailPanels] = useControlledState<Set<MGHGridRowId>>(\n controlledExpandedDetail,\n React.useMemo(() => new Set<MGHGridRowId>(initialState?.detailPanel?.expandedRowIds ?? []), []),\n (ids) => onDetailPanelExpandedRowIdsChange?.(Array.from(ids), getDetails())\n );\n\n const controlledSelection = React.useMemo(\n () => (rowSelectionModelProp !== undefined ? normalizeSelectionModel(rowSelectionModelProp).ids : undefined),\n [rowSelectionModelProp]\n );\n const [selectedIds, setSelectedIds] = useControlledState<Set<MGHGridRowId>>(\n controlledSelection,\n React.useMemo(() => new Set<MGHGridRowId>(), []),\n (ids) => onRowSelectionModelChange?.({ type: 'include', ids }, getDetails())\n );\n\n /* ------------------------------------------------------------------ internal state */\n\n const [orderedFields, setOrderedFields] = React.useState<string[] | null>(\n () => persisted.order ?? initialState?.columns?.orderedFields ?? null\n );\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>(() => {\n if (persisted.widths) return persisted.widths;\n const dims = initialState?.columns?.dimensions;\n if (!dims) return {};\n const out: Record<string, number> = {};\n Object.keys(dims).forEach((field) => {\n if (dims[field].width) out[field] = dims[field].width as number;\n });\n return out;\n });\n const [groupExpansion, setGroupExpansion] = React.useState<Map<MGHGridRowId, boolean>>(() => new Map());\n const [editingCell, setEditingCell] = React.useState<CellCoords | null>(null);\n const [editValue, setEditValue] = React.useState<any>(undefined);\n const [focusedCell, setFocusedCell] = React.useState<CellCoords | null>(null);\n const pendingFocusRef = React.useRef(false);\n const [preferencePanel, setPreferencePanel] = React.useState<\n MGHGridPreferencePanelState & { anchorEl: HTMLElement | null }\n >({\n open: false,\n anchorEl: null,\n });\n const [columnMenu, setColumnMenu] = React.useState<{ field: string; anchorEl: HTMLElement } | null>(null);\n const [resizingField, setResizingField] = React.useState<string | null>(null);\n // While set, the grid renders every row (no pagination / virtualization) so the DOM can be printed.\n const [printState, setPrintState] = React.useState<MGHGridPrintExportOptions | null>(null);\n const printing = printState !== null;\n const [drag, setDrag] = React.useState<{ field: string; overField: string | null; side: 'left' | 'right' } | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const scrollRaf = React.useRef(0);\n const lastClickedIdRef = React.useRef<MGHGridRowId | null>(null);\n\n // Row updates (editing / api.updateRows) are kept until the `rows` prop identity changes.\n const [overrideState, setOverrideState] = React.useState<{ rows: R[]; map: Map<MGHGridRowId, R> }>(() => ({\n rows,\n map: new Map(),\n }));\n const rowOverrides: Map<MGHGridRowId, R> = overrideState.rows === rows ? overrideState.map : EMPTY_MAP;\n const setRowOverride = React.useCallback(\n (id: MGHGridRowId, row: R) => {\n setOverrideState((prev) => {\n const map = new Map(prev.rows === rows ? prev.map : []);\n map.set(id, row);\n return { rows, map };\n });\n },\n [rows]\n );\n\n /* ------------------------------------------------------------------ sizes */\n\n const { width: viewportWidth, height: viewportHeight } = useElementSize(scrollerRef);\n const densityFactor = DENSITY_FACTORS[density] ?? 1;\n const rowHeight = Math.round(rowHeightProp * densityFactor);\n const headerHeight = Math.round(columnHeaderHeight * densityFactor);\n\n /* ------------------------------------------------------------------ rows */\n\n const rowEntries = React.useMemo<RowEntry<R>[]>(() => {\n const out: RowEntry<R>[] = [];\n rows.forEach((raw) => {\n const id = getRowIdFromRow(raw, getRowId);\n if (id === undefined || id === null) return;\n out.push({ id, row: rowOverrides.get(id) ?? raw });\n });\n return out;\n }, [rows, getRowId, rowOverrides]);\n\n const rowsById = React.useMemo(() => {\n const map = new Map<MGHGridRowId, R>();\n rowEntries.forEach((entry) => map.set(entry.id, entry.row));\n (pinnedRows?.top ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n (pinnedRows?.bottom ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n return map;\n }, [rowEntries, pinnedRows, getRowId]);\n\n /* ------------------------------------------------------------------ columns */\n\n const userColumns = React.useMemo(() => columnsProp.map((col) => normalizeColumn(col)), [columnsProp]);\n\n const columnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef<R>>();\n userColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [userColumns]);\n\n const groupingFields = React.useMemo(\n () => (disableRowGrouping ? [] : rowGroupingModel.filter((field) => columnsByField.has(field))),\n [rowGroupingModel, columnsByField, disableRowGrouping]\n );\n const groupingActive = groupingFields.length > 0;\n\n const groupingColumn = React.useMemo<MGHGridColDef<R> | null>(() => {\n if (!groupingActive) return null;\n const single = groupingFields.length === 1 ? columnsByField.get(groupingFields[0]) : undefined;\n return normalizeColumn<R>({\n field: GROUPING_COLUMN_FIELD,\n headerName: single ? (single.headerName ?? single.field) : localeText.groupingColumnHeaderName,\n width: GROUPING_COLUMN_WIDTH,\n minWidth: 120,\n sortable: true,\n filterable: false,\n hideable: false,\n groupable: false,\n aggregable: false,\n editable: false,\n disableExport: true,\n disableReorder: true,\n ...(groupingColDef as any),\n });\n }, [groupingActive, groupingFields, columnsByField, localeText.groupingColumnHeaderName, groupingColDef]);\n\n const orderedUserColumns = React.useMemo(() => {\n if (!orderedFields || orderedFields.length === 0) return userColumns;\n const seen = new Set<string>();\n const out: MGHGridColDef<R>[] = [];\n orderedFields.forEach((field) => {\n const col = columnsByField.get(field);\n if (col && !seen.has(field)) {\n seen.add(field);\n out.push(col);\n }\n });\n userColumns.forEach((col) => {\n if (!seen.has(col.field)) out.push(col);\n });\n return out;\n }, [orderedFields, userColumns, columnsByField]);\n\n const isColumnVisible = React.useCallback(\n (field: string) => {\n const value = columnVisibilityModel[field];\n if (value === false) return false;\n if (value === undefined && groupingFields.indexOf(field) !== -1) return false;\n return true;\n },\n [columnVisibilityModel, groupingFields]\n );\n\n const visibleUserColumns = React.useMemo(() => {\n if (printState) {\n let cols = orderedUserColumns.filter((col) => isColumnVisible(col.field));\n if (printState.fields) {\n const wanted = new Set(printState.fields);\n cols = orderedUserColumns.filter((col) => wanted.has(col.field));\n } else if (printState.allColumns) {\n cols = orderedUserColumns;\n }\n return cols.filter((col) => !col.disableExport);\n }\n return orderedUserColumns.filter((col) => isColumnVisible(col.field));\n }, [orderedUserColumns, isColumnVisible, printState]);\n\n const layout = React.useMemo(() => {\n const internal: MGHGridColDef[] = [];\n if (checkboxSelection) internal.push(CHECKBOX_COLUMN_DEF);\n if (getDetailPanelContent) internal.push(DETAIL_PANEL_TOGGLE_COLUMN_DEF);\n const leftFields = disableColumnPinning ? [] : (pinnedColumns.left ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const rightFields = disableColumnPinning\n ? []\n : (pinnedColumns.right ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const visibleByField = new Map<string, MGHGridColDef>();\n visibleUserColumns.forEach((col) => visibleByField.set(col.field, col));\n const left: MGHGridColDef[] = internal.slice();\n if (groupingColumn) left.push(groupingColumn);\n leftFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col) left.push(col);\n });\n const right: MGHGridColDef[] = [];\n rightFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col && leftFields.indexOf(f) === -1) right.push(col);\n });\n const center = visibleUserColumns.filter(\n (col) => leftFields.indexOf(col.field) === -1 && rightFields.indexOf(col.field) === -1\n );\n const ordered = left.concat(center, right);\n const widths = computeWidths(ordered, viewportWidth, columnWidths);\n const hasPinning = left.length > internal.length + (groupingColumn ? 1 : 0) || right.length > 0;\n const columns: ColumnLayout[] = [];\n let x = 0;\n let leftOffset = 0;\n ordered.forEach((col, i) => {\n const width = widths[i];\n const isLeft = i < left.length;\n const isRight = i >= left.length + center.length;\n columns.push({\n col,\n width,\n pinned: isLeft ? 'left' : isRight ? 'right' : null,\n offset: isLeft ? leftOffset : 0,\n x,\n isLastLeft: isLeft && i === left.length - 1,\n isFirstRight: isRight && i === left.length + center.length,\n });\n if (isLeft) leftOffset += width;\n x += width;\n });\n let rightOffset = 0;\n for (let i = columns.length - 1; i >= 0; i -= 1) {\n if (columns[i].pinned !== 'right') break;\n columns[i].offset = rightOffset;\n rightOffset += columns[i].width;\n }\n return { columns, totalWidth: x, hasPinning, leftCount: left.length, rightCount: right.length };\n }, [\n checkboxSelection,\n getDetailPanelContent,\n pinnedColumns,\n disableColumnPinning,\n visibleUserColumns,\n groupingColumn,\n viewportWidth,\n columnWidths,\n ]);\n\n const allDisplayColumnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n layout.columns.forEach((c) => map.set(c.col.field, c.col));\n if (groupingColumn) map.set(GROUPING_COLUMN_FIELD, groupingColumn);\n return map;\n }, [layout.columns, groupingColumn]);\n\n const getColumn = React.useCallback(\n (field: string): MGHGridColDef<R> | undefined =>\n columnsByField.get(field) ?? (allDisplayColumnsByField.get(field) as any),\n [columnsByField, allDisplayColumnsByField]\n );\n\n /* ------------------------------------------------------------------ filtering */\n\n const activeFilters = React.useMemo(() => {\n const out: Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }> = [];\n filterModel.items.forEach((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.filterable === false) return;\n const operator = getColumnFilterOperators(col).find((op) => op.value === item.operator);\n if (!operator) return;\n const fn = operator.getApplyFilterFn(item, col);\n if (fn) out.push({ col, fn });\n });\n return out;\n }, [filterModel.items, columnsByField]);\n\n const quickFilterValues = React.useMemo(\n () => (filterModel.quickFilterValues ?? []).map((v) => String(v).trim()).filter((v) => v !== ''),\n [filterModel.quickFilterValues]\n );\n\n const quickFilterColumns = React.useMemo(() => {\n const base = filterModel.quickFilterExcludeHiddenColumns ? visibleUserColumns : orderedUserColumns;\n return base.filter((col) => col.filterable !== false && col.type !== 'actions');\n }, [filterModel.quickFilterExcludeHiddenColumns, visibleUserColumns, orderedUserColumns]);\n\n const filteredEntries = React.useMemo(() => {\n if (activeFilters.length === 0 && quickFilterValues.length === 0) return rowEntries;\n const logicAnd = (filterModel.logicOperator ?? 'and') === 'and';\n const quickAnd = (filterModel.quickFilterLogicOperator ?? 'and') === 'and';\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const quickFns = quickFilterValues.map((needle) => {\n const lowered = needle.toLowerCase();\n const perColumn = quickFilterColumns.map((col) => {\n if (col.getApplyQuickFilterFn) {\n const custom = col.getApplyQuickFilterFn(needle, col, apiRefLocal);\n return custom ? { col, fn: custom } : null;\n }\n const fn: MGHGridApplyFilterFn<R> = (value, row) => {\n if (isNil(value)) return false;\n const formatted = formattedValueToString(getFormattedValue(value, row, col, apiRefLocal)).toLowerCase();\n if (formatted.indexOf(lowered) !== -1) return true;\n const raw = typeof value === 'object' ? '' : String(value).toLowerCase();\n return raw.indexOf(lowered) !== -1;\n };\n return { col, fn };\n });\n const active = perColumn.filter(Boolean) as Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }>;\n return (row: R) => active.some(({ col, fn }) => fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal));\n });\n return rowEntries.filter(({ row }) => {\n if (activeFilters.length > 0) {\n const results = activeFilters.map(({ col, fn }) =>\n fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal)\n );\n const pass = logicAnd ? results.every(Boolean) : results.some(Boolean);\n if (!pass) return false;\n }\n if (quickFns.length > 0) {\n const results = quickFns.map((fn) => fn(row));\n return quickAnd ? results.every(Boolean) : results.some(Boolean);\n }\n return true;\n });\n }, [\n rowEntries,\n activeFilters,\n quickFilterValues,\n quickFilterColumns,\n filterModel.logicOperator,\n filterModel.quickFilterLogicOperator,\n ]);\n\n /* ------------------------------------------------------------------ sorting */\n\n const compareEntries = React.useMemo(() => {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sorters = sortModel\n .filter((item) => item.sort && item.field !== GROUPING_COLUMN_FIELD)\n .map((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.sortable === false) return null;\n return {\n col,\n dir: item.sort === 'desc' ? -1 : 1,\n comparator: col.sortComparator ?? getDefaultComparator(col.type),\n };\n })\n .filter(Boolean) as Array<{ col: MGHGridColDef<R>; dir: number; comparator: any }>;\n if (sorters.length === 0) return null;\n return (a: RowEntry<R>, b: RowEntry<R>) => {\n for (let i = 0; i < sorters.length; i += 1) {\n const { col, dir, comparator } = sorters[i];\n const v1 = getCellValue(a.row, col, apiRefLocal);\n const v2 = getCellValue(b.row, col, apiRefLocal);\n const result = comparator(\n v1,\n v2,\n { id: a.id, field: col.field, value: v1, row: a.row, api: apiRefLocal },\n { id: b.id, field: col.field, value: v2, row: b.row, api: apiRefLocal }\n );\n if (result !== 0) return result * dir;\n }\n return 0;\n };\n }, [sortModel, columnsByField]);\n\n const sortEntries = React.useCallback(\n (entries: RowEntry<R>[]) => {\n if (!compareEntries) return entries;\n return entries\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => compareEntries(a.entry, b.entry) || a.index - b.index)\n .map((item) => item.entry);\n },\n [compareEntries]\n );\n\n /* ------------------------------------------------------------------ grouping + display rows */\n\n const aggregationFunctions = React.useMemo(\n () => ({ ...BUILT_IN_AGGREGATION_FUNCTIONS, ...aggregationFunctionsProp }),\n [aggregationFunctionsProp]\n );\n const aggregationActive = !disableAggregation && Object.keys(aggregationModel).length > 0;\n\n const isGroupExpanded = React.useCallback(\n (node: GroupTreeNode<R>) => {\n const override = groupExpansion.get(node.id);\n if (override !== undefined) return override;\n if (isGroupExpandedByDefault) {\n return isGroupExpandedByDefault({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: [],\n leafIds: [],\n isExpanded: false,\n });\n }\n return defaultGroupingExpansionDepth === -1 || node.depth < defaultGroupingExpansionDepth;\n },\n [groupExpansion, isGroupExpandedByDefault, defaultGroupingExpansionDepth]\n );\n\n const processed = React.useMemo(() => {\n const nodesById = new Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>();\n const groupsById = new Map<MGHGridRowId, GroupTreeNode<R>>();\n if (!groupingActive) {\n const sorted = sortEntries(filteredEntries);\n const displayRows: DisplayRow<R>[] = sorted.map((entry) => {\n const node: MGHGridLeafNode = { type: 'leaf', id: entry.id, depth: 0, parent: null };\n nodesById.set(entry.id, node);\n return { id: entry.id, type: 'leaf', row: entry.row, node, depth: 0 };\n });\n return { displayRows, sortedLeaves: sorted, nodesById, groupsById, tree: [] as GroupTreeNode<R>[] };\n }\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n let tree = buildGroupTree(filteredEntries, groupingFields, columnsByField, apiRefLocal);\n const groupingSort = sortModel.find((item) => item.field === GROUPING_COLUMN_FIELD && item.sort);\n const compareGroups = (depth: number) => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return null;\n const sortItem = groupingSort ?? sortModel.find((item) => item.field === field && item.sort);\n if (!sortItem) return null;\n const comparator = col.sortComparator ?? getDefaultComparator(col.type);\n const dir = sortItem.sort === 'desc' ? -1 : 1;\n return (a: GroupTreeNode<R>, b: GroupTreeNode<R>) =>\n comparator(\n a.groupingKey,\n b.groupingKey,\n { id: a.id, field, value: a.groupingKey, row: a.descendants[0]?.row, api: apiRefLocal },\n { id: b.id, field, value: b.groupingKey, row: b.descendants[0]?.row, api: apiRefLocal }\n ) * dir;\n };\n tree = sortGroupTree(tree, compareGroups, sortEntries);\n const displayRows = flattenGroupTree(tree, isGroupExpanded, nodesById, groupsById);\n return { displayRows, sortedLeaves: collectTreeLeaves(tree), nodesById, groupsById, tree };\n }, [groupingActive, filteredEntries, sortEntries, groupingFields, columnsByField, sortModel, isGroupExpanded]);\n\n const { displayRows, sortedLeaves, nodesById, groupsById } = processed;\n\n /* ------------------------------------------------------------------ pagination */\n\n const totalDisplayRows = displayRows.length;\n const paginate = pagination && !printing;\n const pageCount = pagination ? Math.max(1, Math.ceil(totalDisplayRows / Math.max(paginationModel.pageSize, 1))) : 1;\n const page = pagination ? clamp(paginationModel.page, 0, pageCount - 1) : 0;\n\n React.useEffect(() => {\n if (pagination && paginationModel.page !== page) {\n setPaginationModel({ ...paginationModel, page });\n }\n }, [pagination, paginationModel, page, setPaginationModel]);\n\n const pagedRows = React.useMemo(\n () =>\n paginate\n ? displayRows.slice(page * paginationModel.pageSize, (page + 1) * paginationModel.pageSize)\n : displayRows,\n [displayRows, paginate, page, paginationModel.pageSize]\n );\n\n /* ------------------------------------------------------------------ aggregation values */\n\n const footerAggregates = React.useMemo(() => {\n if (!aggregationActive || aggregationPosition === 'inline') return null;\n const rowsForFooter = sortedLeaves.map((entry) => entry.row);\n return aggregateRows(rowsForFooter, aggregationModel, columnsByField, aggregationFunctions, latest.current.api);\n }, [aggregationActive, aggregationPosition, sortedLeaves, aggregationModel, columnsByField, aggregationFunctions]);\n\n const groupAggregatesCache = React.useMemo(\n () => new Map<MGHGridRowId, Record<string, { value: any; fn: string }>>(),\n [pagedRows, aggregationModel, aggregationFunctions]\n );\n const getGroupAggregates = (group: GroupTreeNode<R>) => {\n if (!aggregationActive || aggregationPosition === 'footer') return undefined;\n let cached = groupAggregatesCache.get(group.id);\n if (!cached) {\n cached = aggregateRows(\n group.descendants.map((d) => d.row),\n aggregationModel,\n columnsByField,\n aggregationFunctions,\n latest.current.api\n );\n groupAggregatesCache.set(group.id, cached);\n }\n return cached;\n };\n\n /* ------------------------------------------------------------------ row heights + virtualization */\n\n const heights = React.useMemo(() => {\n const rowHeights: number[] = [];\n const detailHeights: number[] = [];\n const offsets: number[] = [];\n let total = 0;\n let hasAuto = autoHeight || disableVirtualization || printing;\n pagedRows.forEach((dr) => {\n let h = rowHeight;\n if (getRowHeight && dr.type === 'leaf' && dr.row) {\n const result = getRowHeight({ id: dr.id, model: dr.row, densityFactor });\n if (result === 'auto') hasAuto = true;\n else if (typeof result === 'number' && result > 0) h = result;\n }\n let d = 0;\n if (dr.type === 'leaf' && getDetailPanelContent && expandedDetailPanels.has(dr.id) && dr.row) {\n const dh = getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row })\n : DEFAULT_DETAIL_PANEL_HEIGHT;\n if (dh === 'auto') hasAuto = true;\n else d = dh;\n }\n rowHeights.push(h);\n detailHeights.push(d);\n offsets.push(total);\n total += h + d;\n });\n return { rowHeights, detailHeights, offsets, total, hasAuto };\n }, [\n pagedRows,\n rowHeight,\n getRowHeight,\n densityFactor,\n getDetailPanelContent,\n getDetailPanelHeight,\n expandedDetailPanels,\n autoHeight,\n disableVirtualization,\n printing,\n ]);\n\n const virtual = !heights.hasAuto;\n\n /* ------------------------------------------------------------------ print */\n\n const startPrint = (options: MGHGridPrintExportOptions = {}) => {\n if (printState) return;\n const resolved: MGHGridPrintExportOptions = {\n title: typeof header === 'string' ? header : undefined,\n ...options,\n };\n if (!cardRef.current || typeof window === 'undefined') return;\n setPrintState(resolved);\n };\n\n React.useEffect(() => {\n if (!printState) return undefined;\n // The un-virtualized rows are already committed when this effect runs; a short timeout lets the\n // browser lay them out first. (A timeout rather than rAF so it also fires in hidden/background tabs.)\n const timer = window.setTimeout(() => {\n if (!cardRef.current) return;\n printGridElement({\n cardElement: cardRef.current,\n options: printState,\n onDone: () => setPrintState(null),\n });\n }, 50);\n return () => window.clearTimeout(timer);\n }, [printState]);\n\n const virtualRange = React.useMemo(() => {\n const count = pagedRows.length;\n if (!virtual || count === 0) return { start: 0, end: count };\n const overscan = OVERSCAN_ROWS * rowHeight;\n const viewTop = Math.max(0, scrollTop - headerHeight - overscan);\n const viewBottom = scrollTop + Math.max(viewportHeight, rowHeight) + overscan;\n const { offsets } = heights;\n let lo = 0;\n let hi = count - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] + heights.rowHeights[mid] + heights.detailHeights[mid] < viewTop) lo = mid + 1;\n else hi = mid;\n }\n const start = lo;\n let end = start;\n while (end < count && offsets[end] < viewBottom) end += 1;\n return { start, end };\n }, [virtual, pagedRows.length, scrollTop, viewportHeight, rowHeight, headerHeight, heights]);\n\n const handleScroll = React.useCallback(() => {\n if (!latest.current.virtual) return;\n if (scrollRaf.current) return;\n scrollRaf.current = window.requestAnimationFrame(() => {\n scrollRaf.current = 0;\n if (scrollerRef.current) setScrollTop(scrollerRef.current.scrollTop);\n });\n }, []);\n\n React.useEffect(\n () => () => {\n if (scrollRaf.current) window.cancelAnimationFrame(scrollRaf.current);\n },\n []\n );\n\n /* ------------------------------------------------------------------ selection */\n\n const isRowSelectableFn = React.useCallback(\n (id: MGHGridRowId, row: R | null | undefined) => {\n if (!row) return false;\n if (!isRowSelectable) return true;\n return isRowSelectable({ id, row, columns: orderedUserColumns, api: latest.current.api });\n },\n [isRowSelectable, orderedUserColumns]\n );\n\n const selectionCandidates = React.useMemo(() => {\n const source: RowEntry<R>[] = checkboxSelectionVisibleOnly\n ? (pagedRows\n .filter((dr) => dr.type === 'leaf' && dr.row)\n .map((dr) => ({ id: dr.id, row: dr.row as R })) as RowEntry<R>[])\n : sortedLeaves;\n return source.filter((entry) => isRowSelectableFn(entry.id, entry.row)).map((entry) => entry.id);\n }, [checkboxSelectionVisibleOnly, pagedRows, sortedLeaves, isRowSelectableFn]);\n\n const selectedCandidateCount = React.useMemo(\n () => selectionCandidates.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0),\n [selectionCandidates, selectedIds]\n );\n const allCandidatesSelected = selectionCandidates.length > 0 && selectedCandidateCount === selectionCandidates.length;\n const someCandidatesSelected = selectedCandidateCount > 0 && !allCandidatesSelected;\n\n const updateSelection = React.useCallback(\n (updater: (prev: Set<MGHGridRowId>) => Set<MGHGridRowId>) => {\n setSelectedIds((prev) => {\n const next = updater(prev);\n return selectionModelsEqual({ type: 'include', ids: prev }, { type: 'include', ids: next }) ? prev : next;\n });\n },\n [setSelectedIds]\n );\n\n const selectRows = React.useCallback(\n (ids: MGHGridRowId[], isSelected = true, resetSelection = false) => {\n updateSelection((prev) => {\n const next = resetSelection ? new Set<MGHGridRowId>() : new Set(prev);\n ids.forEach((id) => {\n if (isSelected) {\n if (isRowSelectableFn(id, rowsById.get(id))) next.add(id);\n } else next.delete(id);\n });\n if (disableMultipleRowSelection && next.size > 1) {\n const lastId = ids[ids.length - 1];\n return new Set<MGHGridRowId>(isSelected && next.has(lastId) ? [lastId] : []);\n }\n return next;\n });\n },\n [updateSelection, isRowSelectableFn, rowsById, disableMultipleRowSelection]\n );\n\n React.useEffect(() => {\n if (keepNonExistentRowsSelected || selectedIds.size === 0) return;\n let changed = false;\n const next = new Set<MGHGridRowId>();\n selectedIds.forEach((id) => {\n if (rowsById.has(id)) next.add(id);\n else changed = true;\n });\n if (changed) setSelectedIds(next);\n }, [rowsById, keepNonExistentRowsSelected, selectedIds, setSelectedIds]);\n\n const toggleAllCandidates = () => {\n if (allCandidatesSelected) selectRows(selectionCandidates, false);\n else selectRows(selectionCandidates, true);\n };\n\n const handleRowSelectionClick = (renderRow: RenderRow<R>, event: React.MouseEvent) => {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const allSelected = leafIds.every((id) => selectedIds.has(id));\n selectRows(leafIds, !allSelected, false);\n return;\n }\n if (renderRow.kind !== 'leaf') return;\n const id = renderRow.id;\n if (!isRowSelectableFn(id, renderRow.row)) return;\n const multiple = !disableMultipleRowSelection;\n if (event.shiftKey && multiple && lastClickedIdRef.current !== null) {\n const ids = pagedRows.filter((dr) => dr.type === 'leaf').map((dr) => dr.id);\n const from = ids.indexOf(lastClickedIdRef.current);\n const to = ids.indexOf(id);\n if (from !== -1 && to !== -1) {\n const [a, b] = from < to ? [from, to] : [to, from];\n selectRows(ids.slice(a, b + 1), true, !checkboxSelection && !event.ctrlKey && !event.metaKey);\n return;\n }\n }\n lastClickedIdRef.current = id;\n const isSelected = selectedIds.has(id);\n const resetSelection = !checkboxSelection && !event.ctrlKey && !event.metaKey;\n if (resetSelection) {\n if (isSelected && selectedIds.size === 1) selectRows([id], false, true);\n else selectRows([id], true, true);\n } else {\n selectRows([id], !isSelected, false);\n }\n };\n\n /* ------------------------------------------------------------------ sorting helpers */\n\n const sortColumn = (field: string, direction?: MGHGridSortDirection, allowMultiple = false) => {\n const col = getColumn(field);\n if (!col || col.sortable === false || disableColumnSorting) return;\n const current = sortModel.find((item) => item.field === field);\n let next: MGHGridSortDirection;\n if (direction === undefined) {\n const order = col.sortingOrder ?? sortingOrder;\n const index = order.indexOf(current?.sort ?? null);\n next = order[(index + 1) % order.length];\n } else {\n next = direction;\n }\n let model: MGHGridSortModel;\n if (allowMultiple && !disableMultipleColumnsSorting) {\n model = sortModel.filter((item) => item.field !== field);\n if (next)\n model = current\n ? sortModel.map((item) => (item.field === field ? { field, sort: next } : item))\n : model.concat([{ field, sort: next }]);\n } else {\n model = next ? [{ field, sort: next }] : [];\n }\n setSortModel(model);\n };\n\n /* ------------------------------------------------------------------ column helpers */\n\n const persistOrder = (fields: string[]) => {\n if (columnOrderStorageKey) writeLocalStorage(columnOrderStorageKey, fields);\n };\n\n const persistWidths = (widths: Record<string, number>) => {\n if (columnWidthStorageKey) writeLocalStorage(columnWidthStorageKey, widths);\n };\n\n const setColumnIndex = (field: string, targetIndex: number, event: React.DragEvent | null = null) => {\n const fields = orderedUserColumns.map((c) => c.field);\n const oldIndex = fields.indexOf(field);\n if (oldIndex === -1) return;\n const next = moveItem(fields, oldIndex, clamp(targetIndex, 0, fields.length - 1));\n setOrderedFields(next);\n persistOrder(next);\n const col = columnsByField.get(field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex, oldIndex }, event, getDetails());\n };\n\n const setColumnWidth = (field: string, width: number) => {\n const col = getColumn(field);\n if (!col) return;\n const clamped = clamp(width, col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n setColumnWidths((prev) => {\n const next = { ...prev, [field]: clamped };\n persistWidths(next);\n return next;\n });\n onColumnWidthChange?.({ colDef: col, width: clamped }, getDetails());\n };\n\n const autosizeColumns = (options: { columns?: string[]; includeHeaders?: boolean; expand?: boolean } = {}) => {\n const includeHeaders = options.includeHeaders ?? true;\n const targets = layout.columns.filter(\n (lc) => !isInternalField(lc.col.field) && (!options.columns || options.columns.indexOf(lc.col.field) !== -1)\n );\n if (targets.length === 0) return;\n const root = rootRef.current;\n const computed = root && typeof window !== 'undefined' ? window.getComputedStyle(root) : null;\n const fontFamily = computed?.fontFamily || 'sans-serif';\n const cellFont = `400 14px ${fontFamily}`;\n const headerFont = `600 14px ${fontFamily}`;\n const sample = sortedLeaves.slice(0, 500);\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const next = { ...columnWidths };\n targets.forEach(({ col }) => {\n let max = includeHeaders ? measureText(col.headerName ?? col.field, headerFont) + 64 : 0;\n sample.forEach((entry) => {\n const value = getCellValue(entry.row, col, apiRefLocal);\n const text = formattedValueToString(getFormattedValue(value, entry.row, col, apiRefLocal, entry.id));\n const w = measureText(text, cellFont) + 24;\n if (w > max) max = w;\n });\n next[col.field] = clamp(Math.ceil(max), col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n });\n setColumnWidths(next);\n persistWidths(next);\n };\n\n const pinColumn = (field: string, side: MGHGridPinnedSide) => {\n if (disableColumnPinning) return;\n const left = (pinnedColumns.left ?? []).filter((f) => f !== field);\n const right = (pinnedColumns.right ?? []).filter((f) => f !== field);\n if (side === 'left') left.push(field);\n else right.unshift(field);\n setPinnedColumns({ left, right });\n };\n\n const unpinColumn = (field: string) => {\n setPinnedColumns({\n left: (pinnedColumns.left ?? []).filter((f) => f !== field),\n right: (pinnedColumns.right ?? []).filter((f) => f !== field),\n });\n };\n\n const isColumnPinned = (field: string): MGHGridPinnedSide | false => {\n if (disableColumnPinning) return false;\n if ((pinnedColumns.left ?? []).indexOf(field) !== -1) return 'left';\n if ((pinnedColumns.right ?? []).indexOf(field) !== -1) return 'right';\n return false;\n };\n\n /* ------------------------------------------------------------------ filter helpers */\n\n const upsertFilterItems = (items: MGHGridFilterItem[]) => {\n let nextItems = filterModel.items.slice();\n items.forEach((item) => {\n const withId =\n item.id === undefined ? { ...item, id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}` } : item;\n const index = nextItems.findIndex((existing) => existing.id !== undefined && existing.id === withId.id);\n if (index === -1) nextItems.push(withId);\n else nextItems[index] = withId;\n });\n if (disableMultipleColumnsFiltering && nextItems.length > 1) nextItems = nextItems.slice(-1);\n setFilterModel({ ...filterModel, items: nextItems });\n };\n\n const deleteFilterItem = (item: MGHGridFilterItem) => {\n setFilterModel({\n ...filterModel,\n items: filterModel.items.filter((existing) =>\n item.id !== undefined ? existing.id !== item.id : existing !== item\n ),\n });\n };\n\n const showPreferences = (panel: 'columns' | 'filters', anchorEl?: HTMLElement | null, targetField?: string) => {\n setColumnMenu(null);\n setPreferencePanel({\n open: true,\n openedPanelValue: panel,\n targetField,\n anchorEl: anchorEl ?? toolbarRef.current ?? rootRef.current,\n });\n };\n\n const hidePreferences = React.useCallback(() => {\n setPreferencePanel((prev) => (prev.open ? { open: false, anchorEl: null } : prev));\n }, []);\n\n /* ------------------------------------------------------------------ editing */\n\n const isCellEditableFn = (params: MGHGridCellParams<R>) => {\n if (!params.colDef.editable) return false;\n if (params.rowNode.type !== 'leaf') return false;\n return isCellEditable ? isCellEditable(params) : true;\n };\n\n const startCellEditMode = (id: MGHGridRowId, field: string) => {\n const row = rowsById.get(id);\n const col = getColumn(field);\n if (!row || !col) return;\n const params = buildCellParams(id, field, row, nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null });\n if (!isCellEditableFn(params)) return;\n setEditingCell({ id, field });\n setEditValue(params.value);\n setFocusedCell({ id, field });\n };\n\n const applyRowUpdate = (id: MGHGridRowId, newRow: R, oldRow: R) => {\n if (processRowUpdate) {\n Promise.resolve()\n .then(() => processRowUpdate(newRow, oldRow, { rowId: id }))\n .then((result) => setRowOverride(id, (result ?? newRow) as R))\n .catch((error) => {\n if (onProcessRowUpdateError) onProcessRowUpdateError(error);\n else console.error('MGHGrid: processRowUpdate failed', error);\n });\n } else {\n setRowOverride(id, newRow);\n }\n };\n\n const stopCellEditMode = (\n id: MGHGridRowId,\n field: string,\n ignoreModifications = false,\n reason: 'enterKeyDown' | 'escapeKeyDown' | 'cellFocusOut' | 'tabKeyDown' | 'api' = 'api'\n ) => {\n if (!editingCell || editingCell.id !== id || editingCell.field !== field) return;\n const row = rowsById.get(id);\n const col = getColumn(field);\n setEditingCell(null);\n if (!row || !col) return;\n if (!ignoreModifications) {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const parsed = col.valueParser\n ? col.valueParser(editValue, row, col, apiRefLocal)\n : parseEditValue(editValue, col);\n const currentValue = getCellValue(row, col, apiRefLocal);\n if (!Object.is(parsed, currentValue)) {\n const newRow = col.valueSetter\n ? col.valueSetter(parsed, row, col, apiRefLocal)\n : ({ ...row, [field]: parsed } as R);\n applyRowUpdate(id, newRow, row);\n }\n }\n onCellEditStop?.({ id, field, row, reason }, getDetails());\n pendingFocusRef.current = true;\n setFocusedCell({ id, field });\n };\n\n /* ------------------------------------------------------------------ detail panel & grouping helpers */\n\n const toggleDetailPanel = (id: MGHGridRowId) => {\n setExpandedDetailPanels((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const setRowChildrenExpansion = (id: MGHGridRowId, isExpanded: boolean) => {\n setGroupExpansion((prev) => {\n const next = new Map(prev);\n next.set(id, isExpanded);\n return next;\n });\n };\n\n const groupingKey = groupingFields.join('|');\n const previousGroupingKey = React.useRef(groupingKey);\n React.useEffect(() => {\n if (previousGroupingKey.current === groupingKey) return;\n previousGroupingKey.current = groupingKey;\n setGroupExpansion(new Map());\n }, [groupingKey]);\n\n /* ------------------------------------------------------------------ cell params */\n\n const buildCellParams = (id: MGHGridRowId, field: string, row: R, node: MGHGridRowNode): MGHGridCellParams<R> => {\n const col = getColumn(field) as MGHGridColDef<R>;\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const value = getCellValue(row, col, apiRefLocal);\n const formattedValue = getFormattedValue(value, row, col, apiRefLocal, id);\n const hasFocus = Boolean(focusedCell && focusedCell.id === id && focusedCell.field === field);\n const cellMode = editingCell && editingCell.id === id && editingCell.field === field ? 'edit' : 'view';\n return {\n id,\n field,\n value,\n formattedValue,\n row,\n rowNode: node,\n colDef: col,\n api: apiRefLocal,\n hasFocus,\n tabIndex: hasFocus ? 0 : -1,\n cellMode,\n isEditable: Boolean(col.editable) && node.type === 'leaf',\n };\n };\n\n const buildRowParams = (id: MGHGridRowId, row: R): MGHGridRowParams<R> => ({\n id,\n row,\n columns: orderedUserColumns,\n api: latest.current.api,\n });\n\n /* ------------------------------------------------------------------ keyboard navigation */\n\n React.useEffect(() => {\n if (!pendingFocusRef.current || !focusedCell || !rootRef.current) return;\n pendingFocusRef.current = false;\n const selector = `[data-mgh-row-id=\"${String(focusedCell.id).replace(/\"/g, '\\\\\"')}\"] [data-mgh-field=\"${focusedCell.field.replace(/\"/g, '\\\\\"')}\"]`;\n const el = rootRef.current.querySelector<HTMLElement>(selector);\n if (el && document.activeElement !== el && !el.contains(document.activeElement)) el.focus({ preventScroll: true });\n }, [focusedCell, virtualRange.start, virtualRange.end]);\n\n const scrollToIndexes = (params: { rowIndex?: number; colIndex?: number }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return false;\n if (params.rowIndex !== undefined && virtual) {\n const index = clamp(params.rowIndex, 0, Math.max(pagedRows.length - 1, 0));\n const top = heights.offsets[index] ?? 0;\n const bottom = top + (heights.rowHeights[index] ?? rowHeight);\n const visibleTop = scroller.scrollTop;\n const visibleBottom = scroller.scrollTop + scroller.clientHeight - headerHeight;\n if (top < visibleTop) scroller.scrollTop = top;\n else if (bottom > visibleBottom) scroller.scrollTop = bottom - (scroller.clientHeight - headerHeight);\n } else if (params.rowIndex !== undefined) {\n const el = scroller.querySelector(`[data-mgh-row-index=\"${params.rowIndex}\"]`) as HTMLElement | null | undefined;\n el?.scrollIntoView?.({ block: 'nearest' });\n }\n if (params.colIndex !== undefined) {\n const lc = layout.columns[clamp(params.colIndex, 0, layout.columns.length - 1)];\n if (lc && !lc.pinned) {\n const leftPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'left')\n .reduce((acc, c) => acc + c.width, 0);\n const rightPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'right')\n .reduce((acc, c) => acc + c.width, 0);\n const visibleLeft = scroller.scrollLeft + leftPinnedWidth;\n const visibleRight = scroller.scrollLeft + scroller.clientWidth - rightPinnedWidth;\n if (lc.x < visibleLeft) scroller.scrollLeft = lc.x - leftPinnedWidth;\n else if (lc.x + lc.width > visibleRight)\n scroller.scrollLeft = lc.x + lc.width - scroller.clientWidth + rightPinnedWidth;\n }\n }\n return true;\n };\n\n const moveFocus = (\n rowDelta: number,\n colDelta: number,\n absolute?: { row?: 'first' | 'last'; col?: 'first' | 'last' }\n ) => {\n if (pagedRows.length === 0 || layout.columns.length === 0) return;\n let rowIndex = focusedCell ? pagedRows.findIndex((dr) => dr.id === focusedCell.id) : -1;\n let colIndex = focusedCell ? layout.columns.findIndex((lc) => lc.col.field === focusedCell.field) : -1;\n if (rowIndex === -1) rowIndex = 0;\n if (colIndex === -1) colIndex = 0;\n if (absolute?.row === 'first') rowIndex = 0;\n else if (absolute?.row === 'last') rowIndex = pagedRows.length - 1;\n else rowIndex = clamp(rowIndex + rowDelta, 0, pagedRows.length - 1);\n if (absolute?.col === 'first') colIndex = 0;\n else if (absolute?.col === 'last') colIndex = layout.columns.length - 1;\n else colIndex = clamp(colIndex + colDelta, 0, layout.columns.length - 1);\n const target = { id: pagedRows[rowIndex].id, field: layout.columns[colIndex].col.field };\n pendingFocusRef.current = true;\n setFocusedCell(target);\n scrollToIndexes({ rowIndex, colIndex });\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (editingCell) return;\n const target = event.target as HTMLElement;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'SELECT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'BUTTON')\n ) {\n return;\n }\n const pageRows = Math.max(1, Math.floor(Math.max(viewportHeight - headerHeight, rowHeight) / rowHeight));\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1, 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1, 0);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(0, -1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(0, 1);\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(pageRows, 0);\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(-pageRows, 0);\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'first', col: 'first' } : { col: 'first' });\n break;\n case 'End':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'last', col: 'last' } : { col: 'last' });\n break;\n case 'Enter':\n case 'F2':\n if (focusedCell) {\n const node = nodesById.get(focusedCell.id);\n if (node?.type === 'group' && focusedCell.field === GROUPING_COLUMN_FIELD) {\n const group = groupsById.get(focusedCell.id);\n if (group) setRowChildrenExpansion(group.id, !isGroupExpanded(group));\n } else {\n event.preventDefault();\n startCellEditMode(focusedCell.id, focusedCell.field);\n }\n }\n break;\n case ' ':\n if (focusedCell && (checkboxSelection || !disableRowSelectionOnClick)) {\n const dr = pagedRows.find((r) => r.id === focusedCell.id);\n if (dr && dr.type === 'leaf' && dr.row) {\n event.preventDefault();\n selectRows([dr.id], !selectedIds.has(dr.id), false);\n }\n }\n break;\n case 'Escape':\n if (preferencePanel.open) hidePreferences();\n if (columnMenu) setColumnMenu(null);\n break;\n default:\n if (\n (event.ctrlKey || event.metaKey) &&\n event.key.toLowerCase() === 'a' &&\n checkboxSelection &&\n !disableMultipleRowSelection\n ) {\n event.preventDefault();\n selectRows(selectionCandidates, true);\n }\n }\n };\n\n /* ------------------------------------------------------------------ drag & drop (reorder) */\n\n const canReorder = (col: MGHGridColDef) => !disableColumnReorder && !col.disableReorder && !isInternalField(col.field);\n\n const handleDrop = (targetLc: ColumnLayout, event: React.DragEvent) => {\n event.preventDefault();\n const current = drag;\n setDrag(null);\n if (!current || current.field === targetLc.col.field) return;\n const sourceLc = layout.columns.find((lc) => lc.col.field === current.field);\n if (!sourceLc || sourceLc.pinned !== targetLc.pinned || !canReorder(targetLc.col)) return;\n const side = current.side;\n if (sourceLc.pinned) {\n const key = sourceLc.pinned;\n const list = (pinnedColumns[key] ?? []).slice();\n const from = list.indexOf(current.field);\n let to = list.indexOf(targetLc.col.field);\n if (from === -1 || to === -1) return;\n list.splice(from, 1);\n to = list.indexOf(targetLc.col.field);\n list.splice(side === 'right' ? to + 1 : to, 0, current.field);\n setPinnedColumns({ ...pinnedColumns, [key]: list });\n return;\n }\n const fields = orderedUserColumns.map((c) => c.field);\n const from = fields.indexOf(current.field);\n const without = fields.filter((f) => f !== current.field);\n let to = without.indexOf(targetLc.col.field);\n if (side === 'right') to += 1;\n without.splice(to, 0, current.field);\n setOrderedFields(without);\n persistOrder(without);\n const col = columnsByField.get(current.field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex: to, oldIndex: from }, event, getDetails());\n };\n\n /* ------------------------------------------------------------------ resize */\n\n const resizeRef = React.useRef<{\n field: string;\n startX: number;\n startWidth: number;\n lastWidth: number;\n min: number;\n max: number;\n } | null>(null);\n\n const handleResizeStart = (lc: ColumnLayout, event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n field: lc.col.field,\n startX: event.clientX,\n startWidth: lc.width,\n lastWidth: lc.width,\n min: lc.col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n max: lc.col.maxWidth ?? Infinity,\n };\n setResizingField(lc.col.field);\n const onMove = (e: PointerEvent) => {\n const r = resizeRef.current;\n if (!r) return;\n const width = clamp(r.startWidth + (e.clientX - r.startX), r.min, r.max);\n r.lastWidth = width;\n setColumnWidths((prev) => (prev[r.field] === width ? prev : { ...prev, [r.field]: width }));\n };\n const onUp = () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n const r = resizeRef.current;\n resizeRef.current = null;\n setResizingField(null);\n if (!r) return;\n const next = { ...(latest.current.columnWidths as Record<string, number>), [r.field]: r.lastWidth };\n setColumnWidths(next);\n persistWidths(next);\n const col = latest.current.getColumn(r.field);\n if (col && r.lastWidth !== r.startWidth)\n onColumnWidthChange?.({ colDef: col, width: r.lastWidth }, getDetails());\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n };\n\n /* ------------------------------------------------------------------ state snapshot & API */\n\n const filterCount = activeFilters.length;\n const rowCount = groupingActive ? totalDisplayRows : filteredEntries.length;\n\n const state = React.useMemo<MGHGridState>(\n () => ({\n sortModel,\n filterModel,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n pageCount,\n rowCount,\n totalRowCount: rowEntries.length,\n columnVisibilityModel,\n orderedFields: orderedUserColumns.map((c) => c.field),\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n rowSelectionModel: { type: 'include', ids: selectedIds },\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel: {\n open: preferencePanel.open,\n openedPanelValue: preferencePanel.openedPanelValue,\n targetField: preferencePanel.targetField,\n },\n filterCount,\n quickFilterValues,\n }),\n [\n sortModel,\n filterModel,\n page,\n paginationModel.pageSize,\n pageCount,\n rowCount,\n rowEntries.length,\n columnVisibilityModel,\n orderedUserColumns,\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n selectedIds,\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel.open,\n preferencePanel.openedPanelValue,\n preferencePanel.targetField,\n filterCount,\n quickFilterValues,\n ]\n );\n\n latest.current = {\n api: apiObject,\n state,\n rowsById,\n rowEntries,\n nodesById,\n groupsById,\n sortedLeaves,\n pagedRows,\n getRowId,\n setRowOverride,\n orderedUserColumns,\n visibleUserColumns,\n getColumn,\n columnVisibilityModel,\n setColumnVisibilityModel,\n setColumnWidth,\n setColumnIndex,\n columnWidths,\n autosizeColumns,\n pinColumn,\n unpinColumn,\n isColumnPinned,\n pinnedColumns,\n setPinnedColumns,\n sortModel,\n setSortModel,\n sortColumn,\n filterModel,\n setFilterModel,\n upsertFilterItems,\n deleteFilterItem,\n showPreferences,\n hidePreferences,\n selectedIds,\n setSelectedIds,\n selectRows,\n isRowSelectableFn,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n setPaginationModel,\n setDensity,\n toggleDetailPanel,\n expandedDetailPanels,\n setExpandedDetailPanels,\n rowGroupingModel,\n setRowGroupingModel,\n setRowChildrenExpansion,\n aggregationModel,\n setAggregationModel,\n startCellEditMode,\n stopCellEditMode,\n editingCell,\n setEditValue,\n buildCellParams,\n setFocusedCell,\n scrollToIndexes,\n forceUpdate,\n virtual,\n startPrint,\n };\n\n if (apiRef) apiRef.current = apiObject;\n\n React.useEffect(() => {\n onStateChange?.(state, { api: apiObject });\n }, [state, onStateChange, apiObject]);\n\n /* ------------------------------------------------------------------ context */\n\n const rootProps = React.useMemo<MGHGridRootProps>(\n () => ({\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n }),\n [\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n ]\n );\n\n const contextValue = React.useMemo<MGHGridContextValue>(\n () => ({\n api: apiObject,\n state,\n localeText,\n themeMode,\n rootProps,\n columns: orderedUserColumns,\n visibleColumns: visibleUserColumns,\n }),\n [apiObject, state, localeText, themeMode, rootProps, orderedUserColumns, visibleUserColumns]\n );\n\n /* ------------------------------------------------------------------ rendering: cells */\n\n const renderEditor = (params: MGHGridCellParams<R>) => {\n const col = params.colDef;\n const commit = (reason: 'enterKeyDown' | 'cellFocusOut' | 'tabKeyDown') =>\n stopCellEditMode(params.id, params.field, false, reason);\n const cancel = () => stopCellEditMode(params.id, params.field, true, 'escapeKeyDown');\n const keyHandler = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n commit('enterKeyDown');\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n } else if (event.key === 'Tab') {\n commit('tabKeyDown');\n } else {\n event.stopPropagation();\n }\n };\n if (col.renderEditCell) {\n return col.renderEditCell({\n ...params,\n editValue,\n onValueChange: setEditValue,\n commit: () => commit('enterKeyDown'),\n cancel,\n });\n }\n const common = {\n autoFocus: true,\n onKeyDown: keyHandler,\n onBlur: () => commit('cellFocusOut'),\n onClick: (event: React.MouseEvent) => event.stopPropagation(),\n };\n switch (col.type) {\n case 'boolean':\n return (\n <Checkbox\n {...common}\n checked={Boolean(editValue)}\n onChange={(event) => setEditValue(event.target.checked)}\n />\n );\n case 'singleSelect': {\n const options = resolveValueOptions(col, params.row, params.id);\n return (\n <Select\n {...common}\n size=\"small\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(col, o)) === event.target.value);\n setEditValue(match !== undefined ? getOptionValue(col, match) : event.target.value);\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(col, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(col, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'number':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"number\"\n value={editValue === undefined || editValue === null ? '' : editValue}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n case 'date':\n case 'dateTime':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type={col.type === 'date' ? 'date' : 'datetime-local'}\n value={\n typeof editValue === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(editValue)\n ? editValue\n : toDateInputValue(editValue, col.type === 'dateTime')\n }\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n default:\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"text\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n }\n };\n\n const renderCellContent = (lc: ColumnLayout, renderRow: RenderRow<R>): React.ReactNode => {\n const { col } = lc;\n const field = col.field;\n\n if (field === CHECKBOX_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const selectedCount = leafIds.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0);\n return (\n <Checkbox\n checked={leafIds.length > 0 && selectedCount === leafIds.length}\n indeterminate={selectedCount > 0 && selectedCount < leafIds.length}\n label={localeText.checkboxSelectionSelectRow}\n onClick={(event) => event.stopPropagation()}\n onChange={() => selectRows(leafIds, selectedCount !== leafIds.length, false)}\n />\n );\n }\n if (renderRow.kind !== 'leaf') return null;\n const selectable = isRowSelectableFn(renderRow.id, renderRow.row);\n const checked = selectedIds.has(renderRow.id);\n return (\n <Checkbox\n checked={checked}\n disabled={!selectable}\n label={checked ? localeText.checkboxSelectionUnselectRow : localeText.checkboxSelectionSelectRow}\n tabIndex={-1}\n onClick={(event) => event.stopPropagation()}\n onChange={() => {\n lastClickedIdRef.current = renderRow.id;\n selectRows([renderRow.id], !checked, disableMultipleRowSelection);\n }}\n />\n );\n }\n\n if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n if (renderRow.kind !== 'leaf' || !renderRow.row) return null;\n const expanded = expandedDetailPanels.has(renderRow.id);\n const content = getDetailPanelContent?.(buildRowParams(renderRow.id, renderRow.row));\n if (content === null || content === undefined || content === false) return null;\n return (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-detail-toggle', expanded && 'mgh-grid-detail-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n toggleDetailPanel(renderRow.id);\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n );\n }\n\n if (field === GROUPING_COLUMN_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const group = renderRow.group;\n const expanded = isGroupExpanded(group);\n const hideCount = (groupingColDef as any)?.hideDescendantCount;\n return (\n <div className=\"mgh-grid-group-cell\" style={{ paddingLeft: renderRow.depth * 20 }}>\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-group-toggle', expanded && 'mgh-grid-group-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setRowChildrenExpansion(group.id, !expanded);\n }}\n >\n <ChevronRightIcon />\n </IconButton>\n <span className=\"mgh-grid-group-label\" title={group.groupingLabel}>\n {group.groupingLabel}\n </span>\n {!hideCount && <span className=\"mgh-grid-group-count\">({group.descendants.length})</span>}\n </div>\n );\n }\n return null;\n }\n\n if (renderRow.kind === 'group' || renderRow.kind === 'footer') {\n const agg = renderRow.aggregates?.[field];\n if (!agg || isNil(agg.value)) return null;\n const fn = aggregationFunctions[agg.fn];\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sampleRow = (renderRow.group?.descendants[0]?.row ?? latest.current.sortedLeaves[0]?.row ?? {}) as R;\n const formatted = fn?.valueFormatter\n ? fn.valueFormatter(agg.value)\n : col.valueFormatter\n ? col.valueFormatter(agg.value, sampleRow, col as MGHGridColDef<R>, apiRefLocal)\n : defaultFormatValue(agg.value, col);\n return (\n <>\n <span className=\"mgh-grid-aggregation-label\">{fn?.label ?? agg.fn}</span>\n <span className=\"mgh-grid-cell-text\">{formattedValueToString(formatted)}</span>\n </>\n );\n }\n\n if (!renderRow.row) return null;\n const params = buildCellParams(renderRow.id, field, renderRow.row, renderRow.node);\n\n if (params.cellMode === 'edit') return renderEditor(params);\n\n if (col.renderCell) return col.renderCell(params);\n\n if (col.type === 'actions') {\n const actions = col.getActions ? col.getActions(buildRowParams(renderRow.id, renderRow.row)) : [];\n return <ActionsCell actions={actions} themeMode={themeMode} moreLabel={localeText.actionsCellMore} />;\n }\n\n if (col.type === 'boolean') {\n if (isNil(params.value)) return null;\n return params.value ? (\n <CheckIcon aria-label={localeText.booleanCellTrueLabel} />\n ) : (\n <CloseIcon aria-label={localeText.booleanCellFalseLabel} />\n );\n }\n\n const formatted = params.formattedValue;\n if (formatted === null || formatted === undefined) return null;\n if (React.isValidElement(formatted)) return formatted;\n const text = formattedValueToString(formatted);\n return (\n <span className=\"mgh-grid-cell-text\" title={text.length > 20 ? text : undefined}>\n {text}\n </span>\n );\n };\n\n const cellStyle = (lc: ColumnLayout): React.CSSProperties => ({\n width: lc.width,\n minWidth: lc.width,\n maxWidth: lc.width,\n left: lc.pinned === 'left' ? lc.offset : undefined,\n right: lc.pinned === 'right' ? lc.offset : undefined,\n });\n\n const pinnedClasses = (lc: ColumnLayout, prefix: string) =>\n cx(\n lc.pinned === 'left' && `${prefix}--pinned-left`,\n lc.pinned === 'right' && `${prefix}--pinned-right`,\n lc.isLastLeft && layout.hasPinning && `${prefix}--pinned-left-last`,\n lc.isFirstRight && `${prefix}--pinned-right-first`\n );\n\n const renderCell = (lc: ColumnLayout, renderRow: RenderRow<R>, isAutoRow: boolean) => {\n const { col } = lc;\n const field = col.field;\n const isFocused = Boolean(focusedCell && focusedCell.id === renderRow.id && focusedCell.field === field);\n const isEditing = Boolean(editingCell && editingCell.id === renderRow.id && editingCell.field === field);\n const isAggregation =\n (renderRow.kind === 'group' || renderRow.kind === 'footer') && Boolean(renderRow.aggregates?.[field]);\n const params =\n renderRow.kind === 'leaf' && renderRow.row\n ? buildCellParams(renderRow.id, field, renderRow.row, renderRow.node)\n : null;\n const editable = params ? isCellEditableFn(params) : false;\n const customClass =\n params && col.cellClassName\n ? typeof col.cellClassName === 'function'\n ? col.cellClassName(params)\n : col.cellClassName\n : undefined;\n const isCheckbox = field === CHECKBOX_FIELD;\n const isDetailToggle = field === DETAIL_PANEL_TOGGLE_FIELD;\n return (\n <div\n key={field}\n role=\"gridcell\"\n data-mgh-field={field}\n data-mgh-colindex={layout.columns.indexOf(lc)}\n tabIndex={isFocused ? 0 : -1}\n aria-selected={renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : undefined}\n className={cx(\n 'mgh-grid-cell',\n `mgh-grid-cell--align-${col.align ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-cell'),\n isFocused && !isEditing && 'mgh-grid-cell--focused',\n isEditing && 'mgh-grid-cell--editing',\n editable && !isEditing && 'mgh-grid-cell--editable',\n col.type === 'boolean' && 'mgh-grid-cell--boolean',\n col.type === 'actions' && 'mgh-grid-cell--actions',\n isCheckbox && 'mgh-grid-cell--checkbox',\n isDetailToggle && 'mgh-grid-cell--detail-toggle',\n isAggregation && 'mgh-grid-cell--aggregation',\n customClass\n )}\n style={cellStyle(lc)}\n onMouseDown={() => {\n if (renderRow.kind === 'leaf' || renderRow.kind === 'group') {\n if (!isFocused) setFocusedCell({ id: renderRow.id, field });\n }\n }}\n onClick={(event) => {\n if (params && onCellClick) onCellClick(params, event, getDetails());\n }}\n onDoubleClick={(event) => {\n if (params) {\n onCellDoubleClick?.(params, event, getDetails());\n if (editable && !isEditing) {\n event.stopPropagation();\n startCellEditMode(renderRow.id, field);\n }\n }\n }}\n >\n {renderCellContent(lc, renderRow)}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: rows */\n\n const rowIsClickable = Boolean(onRowClick || onRowDoubleClick || !disableRowSelectionOnClick);\n\n const renderRowElement = (\n renderRow: RenderRow<R>,\n options: { height?: number; index: number; isFirst: boolean; isLast: boolean; isAuto: boolean }\n ) => {\n const isSelected = renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : false;\n const customClass =\n renderRow.kind === 'leaf' && renderRow.row && getRowClassName\n ? getRowClassName({\n ...buildRowParams(renderRow.id, renderRow.row),\n indexRelativeToCurrentPage: options.index,\n isFirstVisible: options.isFirst,\n isLastVisible: options.isLast,\n rowNode: renderRow.node,\n })\n : undefined;\n return (\n <div\n role=\"row\"\n aria-rowindex={options.index + 2}\n aria-selected={renderRow.kind === 'leaf' ? isSelected : undefined}\n data-mgh-row-id={String(renderRow.id)}\n data-mgh-row-index={options.index}\n className={cx(\n 'mgh-grid-row',\n isSelected && 'mgh-grid-row--selected',\n rowIsClickable && renderRow.kind === 'leaf' && 'mgh-grid-row--clickable',\n renderRow.kind === 'group' && 'mgh-grid-row--group',\n renderRow.kind === 'pinnedRow' && 'mgh-grid-row--pinned',\n renderRow.kind === 'footer' && 'mgh-grid-row--footer',\n options.isAuto && 'mgh-grid-row--auto-height',\n customClass\n )}\n style={{\n width: layout.totalWidth,\n height: options.isAuto ? undefined : options.height,\n minHeight: options.isAuto ? rowHeight : undefined,\n }}\n onClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n if (!disableRowSelectionOnClick) handleRowSelectionClick(renderRow, event);\n onRowClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n } else if (renderRow.kind === 'group' && renderRow.group) {\n setRowChildrenExpansion(renderRow.group.id, !isGroupExpanded(renderRow.group));\n }\n }}\n onDoubleClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n onRowDoubleClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n }\n }}\n >\n {layout.columns.map((lc) => renderCell(lc, renderRow, options.isAuto))}\n <div className=\"mgh-grid-row-filler\" />\n </div>\n );\n };\n\n const toRenderRow = (dr: DisplayRow<R>): RenderRow<R> => ({\n id: dr.id,\n kind: dr.type,\n row: dr.row,\n node: dr.node,\n depth: dr.depth,\n group: dr.group,\n aggregates: dr.type === 'group' && dr.group ? getGroupAggregates(dr.group) : undefined,\n });\n\n const renderBodyRows = () => {\n const { start, end } = virtualRange;\n const items: React.ReactNode[] = [];\n for (let i = start; i < end; i += 1) {\n const dr = pagedRows[i];\n const renderRow = toRenderRow(dr);\n const detailHeight = heights.detailHeights[i];\n const isExpanded =\n dr.type === 'leaf' && Boolean(dr.row) && Boolean(getDetailPanelContent) && expandedDetailPanels.has(dr.id);\n const detailContent = isExpanded && dr.row ? getDetailPanelContent?.(buildRowParams(dr.id, dr.row)) : null;\n const detailAuto =\n isExpanded && dr.row && getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row }) === 'auto'\n : false;\n const rowAuto =\n !virtual &&\n (getRowHeight && dr.type === 'leaf' && dr.row\n ? getRowHeight({ id: dr.id, model: dr.row, densityFactor }) === 'auto'\n : false);\n items.push(\n <div\n key={String(dr.id)}\n className=\"mgh-grid-row-block\"\n style={virtual ? { top: heights.offsets[i], width: layout.totalWidth } : { width: layout.totalWidth }}\n >\n {renderRowElement(renderRow, {\n height: heights.rowHeights[i],\n index: i,\n isFirst: i === 0,\n isLast: i === pagedRows.length - 1,\n isAuto: rowAuto,\n })}\n {isExpanded && detailContent !== null && detailContent !== undefined && detailContent !== false && (\n <div\n className=\"mgh-grid-detail-panel\"\n style={{\n height: detailAuto ? undefined : detailHeight || undefined,\n width: viewportWidth || undefined,\n }}\n onClick={(event) => event.stopPropagation()}\n >\n {detailContent}\n </div>\n )}\n </div>\n );\n }\n return items;\n };\n\n const renderPinnedRows = (list: R[] | undefined, position: 'top' | 'bottom') => {\n const items: React.ReactNode[] = [];\n (list ?? []).forEach((row, index) => {\n const id = getRowIdFromRow(row, getRowId);\n const renderRow: RenderRow<R> = {\n id,\n kind: 'pinnedRow',\n row,\n node: { type: 'pinnedRow', id, depth: 0, parent: null, position },\n depth: 0,\n };\n items.push(\n <React.Fragment key={String(id)}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: index,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n });\n if (position === 'bottom' && footerAggregates) {\n const renderRow: RenderRow<R> = {\n id: AGGREGATION_FOOTER_ID,\n kind: 'footer',\n row: null,\n node: { type: 'footer', id: AGGREGATION_FOOTER_ID, depth: 0, parent: null },\n depth: 0,\n aggregates: footerAggregates,\n };\n items.push(\n <React.Fragment key={AGGREGATION_FOOTER_ID}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: 0,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n }\n return items;\n };\n\n /* ------------------------------------------------------------------ rendering: header */\n\n const renderHeaderCell = (lc: ColumnLayout, index: number) => {\n const { col } = lc;\n const field = col.field;\n const sortIndex = sortModel.findIndex((item) => item.field === field && item.sort);\n const sortItem = sortIndex !== -1 ? sortModel[sortIndex] : undefined;\n const sortable =\n (col.sortable !== false && !disableColumnSorting && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && col.sortable !== false);\n const showMenu =\n (!disableColumnMenu && !col.disableColumnMenu && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnMenu);\n const resizable =\n (!disableColumnResize && col.resizable !== false && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnResize);\n const draggable = canReorder(col);\n const isDragging = drag?.field === field;\n const isDropTarget = drag && drag.overField === field && drag.field !== field;\n const menuOpen = columnMenu?.field === field;\n const headerParams = { field, colDef: col as MGHGridColDef<R>, api: apiObject };\n const customClass = col.headerClassName\n ? typeof col.headerClassName === 'function'\n ? col.headerClassName(headerParams)\n : col.headerClassName\n : undefined;\n\n let content: React.ReactNode;\n if (field === CHECKBOX_FIELD) {\n content = disableMultipleRowSelection ? null : (\n <Checkbox\n checked={allCandidatesSelected}\n indeterminate={someCandidatesSelected}\n disabled={selectionCandidates.length === 0}\n label={\n allCandidatesSelected\n ? localeText.checkboxSelectionUnselectAllRows\n : localeText.checkboxSelectionSelectAllRows\n }\n onChange={toggleAllCandidates}\n onClick={(event) => event.stopPropagation()}\n />\n );\n } else if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n content = null;\n } else {\n content = col.renderHeader ? (\n col.renderHeader(headerParams)\n ) : (\n <span className=\"mgh-grid-header-title\">{col.headerName ?? field}</span>\n );\n }\n\n return (\n <div\n key={field}\n role=\"columnheader\"\n aria-colindex={index + 1}\n aria-sort={sortItem ? (sortItem.sort === 'asc' ? 'ascending' : 'descending') : sortable ? 'none' : undefined}\n data-mgh-field={field}\n title={col.description}\n tabIndex={-1}\n draggable={draggable}\n className={cx(\n 'mgh-grid-header-cell',\n `mgh-grid-header-cell--align-${col.headerAlign ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-header-cell'),\n sortable && 'mgh-grid-header-cell--sortable',\n field === CHECKBOX_FIELD && 'mgh-grid-header-cell--checkbox',\n field === DETAIL_PANEL_TOGGLE_FIELD && 'mgh-grid-header-cell--detail-toggle',\n index === layout.columns.length - 1 && 'mgh-grid-header-cell--last',\n isDragging && 'mgh-grid-header-cell--dragging',\n isDropTarget && drag?.side === 'left' && 'mgh-grid-header-cell--drop-left',\n isDropTarget && drag?.side === 'right' && 'mgh-grid-header-cell--drop-right',\n menuOpen && 'mgh-grid-header-cell--menu-open',\n customClass\n )}\n style={cellStyle(lc)}\n onClick={(event) => {\n if (!sortable || resizingField) return;\n sortColumn(field, undefined, event.shiftKey);\n }}\n onDragStart={(event) => {\n if (!draggable) return;\n event.dataTransfer.effectAllowed = 'move';\n try {\n event.dataTransfer.setData('text/plain', field);\n } catch {\n /* ignore */\n }\n setDrag({ field, overField: null, side: 'left' });\n }}\n onDragOver={(event) => {\n if (!drag || drag.field === field) return;\n const sourceLc = layout.columns.find((c) => c.col.field === drag.field);\n if (!sourceLc || sourceLc.pinned !== lc.pinned || !canReorder(col)) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n const rect = event.currentTarget.getBoundingClientRect();\n const side = event.clientX < rect.left + rect.width / 2 ? 'left' : 'right';\n if (drag.overField !== field || drag.side !== side) setDrag({ ...drag, overField: field, side });\n }}\n onDragLeave={() => {\n if (drag && drag.overField === field) setDrag({ ...drag, overField: null });\n }}\n onDrop={(event) => handleDrop(lc, event)}\n onDragEnd={() => setDrag(null)}\n >\n <div className=\"mgh-grid-header-title-container\">\n {content}\n {sortable && (\n <span\n className={cx('mgh-grid-sort-icon', sortItem && 'mgh-grid-sort-icon--active')}\n aria-hidden=\"true\"\n >\n {sortItem?.sort === 'desc' ? <ArrowDownwardIcon size={18} /> : <ArrowUpwardIcon size={18} />}\n {sortItem && sortModel.filter((s) => s.sort).length > 1 && (\n <span className=\"mgh-grid-sort-index\">{sortIndex + 1}</span>\n )}\n </span>\n )}\n </div>\n {showMenu && (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-header-menu-btn', menuOpen && 'mgh-grid-header-menu-btn--open')}\n label={localeText.columnMenuLabel}\n aria-haspopup=\"menu\"\n aria-expanded={menuOpen}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setColumnMenu((prev) =>\n prev?.field === field ? null : { field, anchorEl: event.currentTarget }\n );\n }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n {resizable && (\n <div\n className={cx('mgh-grid-resize-handle', resizingField === field && 'mgh-grid-resize-handle--active')}\n role=\"separator\"\n aria-orientation=\"vertical\"\n onPointerDown={(event) => handleResizeStart(lc, event)}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => {\n event.stopPropagation();\n autosizeColumns({ columns: [field] });\n }}\n draggable={false}\n onDragStart={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n />\n )}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: slots */\n\n const ToolbarSlot = slots.toolbar === null ? null : (slots.toolbar ?? MGHGridToolbar);\n const FooterSlot = slots.footer === null ? null : (slots.footer ?? MGHGridFooter);\n const NoRowsOverlaySlot = slots.noRowsOverlay ?? MGHGridNoRowsOverlay;\n const LoadingOverlaySlot = slots.loadingOverlay ?? MGHGridLoadingOverlay;\n const mergedToolbarProps = { ...toolbarProps, ...slotProps.toolbar };\n const noRowsProps = { text: noRowsText, ...slotProps.noRowsOverlay };\n const loadingProps = { ...slotProps.loadingOverlay };\n\n const showNoRows = !loading && pagedRows.length === 0;\n const menuColumn = columnMenu ? getColumn(columnMenu.field) : undefined;\n\n const cardStyles: React.CSSProperties = {\n height: 'auto',\n flexGrow: 1,\n ...sanitizeStyle(cardSx),\n ...sanitizeStyle(cardStyle),\n ...(themeVars as any),\n };\n const boxStyles: React.CSSProperties = { flexGrow: 1, ...sanitizeStyle(boxSx), ...sanitizeStyle(boxStyle) };\n const rootStyles: React.CSSProperties = {\n ...sanitizeStyle(sx),\n ...sanitizeStyle(style),\n ['--mgh-grid-header-height' as any]: `${headerHeight}px`,\n ['--mgh-grid-row-height' as any]: `${rowHeight}px`,\n };\n\n // Nested selectors from sx/style props become a <style> block scoped to this grid instance.\n const scopedCss = React.useMemo(() => {\n const css: string[] = [];\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, sx, css);\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, style, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardSx, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardStyle, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxSx, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxStyle, css);\n return css.join('\\n');\n }, [gridId, sx, style, cardSx, cardStyle, boxSx, boxStyle]);\n\n const smDown = viewportWidth > 0 && viewportWidth < 600;\n\n const grid = (\n <div\n ref={rootRef}\n id={gridId}\n data-mgh-grid-id={gridId}\n role=\"grid\"\n aria-rowcount={rowCount + 1}\n aria-colcount={layout.columns.length}\n aria-multiselectable={checkboxSelection && !disableMultipleRowSelection ? true : undefined}\n aria-busy={loading || undefined}\n className={cx(\n 'mgh-grid',\n (autoHeight || printing) && 'mgh-grid--auto-height',\n printing && 'mgh-grid--printing',\n !layout.hasPinning && 'mgh-grid--no-pinned-shadow',\n className\n )}\n style={rootStyles}\n onKeyDown={handleKeyDown}\n >\n {showToolbar && ToolbarSlot && (\n <div ref={toolbarRef}>\n <ToolbarSlot {...mergedToolbarProps} />\n </div>\n )}\n <div className=\"mgh-grid-main\">\n <div ref={scrollerRef} className=\"mgh-grid-scroller\" onScroll={handleScroll} tabIndex={-1}>\n <div className=\"mgh-grid-columns\" role=\"rowgroup\" style={{ width: layout.totalWidth }}>\n <div className=\"mgh-grid-header-row\" role=\"row\" aria-rowindex={1} style={{ height: headerHeight }}>\n {layout.columns.map((lc, index) => renderHeaderCell(lc, index))}\n <div className=\"mgh-grid-header-filler\" />\n </div>\n </div>\n {pinnedRows?.top && pinnedRows.top.length > 0 && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--top\"\n role=\"rowgroup\"\n style={{ top: headerHeight, width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows.top, 'top')}\n </div>\n )}\n <div\n className={cx('mgh-grid-body', virtual ? 'mgh-grid-body--virtual' : 'mgh-grid-body--flow')}\n role=\"rowgroup\"\n style={\n virtual\n ? { height: heights.total, width: layout.totalWidth }\n : { width: layout.totalWidth, minHeight: showNoRows || loading ? 120 : undefined }\n }\n >\n {renderBodyRows()}\n </div>\n {((pinnedRows?.bottom && pinnedRows.bottom.length > 0) || footerAggregates) && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--bottom\"\n role=\"rowgroup\"\n style={{ width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows?.bottom, 'bottom')}\n </div>\n )}\n </div>\n {loading && (\n <div className=\"mgh-grid-overlay mgh-grid-overlay--loading\" style={{ top: headerHeight }}>\n <LoadingOverlaySlot {...loadingProps} />\n </div>\n )}\n {showNoRows && (\n <div className=\"mgh-grid-overlay\" style={{ top: headerHeight }}>\n <NoRowsOverlaySlot {...noRowsProps} />\n </div>\n )}\n </div>\n {!hideFooter && FooterSlot && <FooterSlot {...slotProps.footer} />}\n\n <Popover\n open={preferencePanel.open}\n anchorEl={preferencePanel.anchorEl}\n onClose={hidePreferences}\n themeMode={themeMode}\n placement=\"bottom-start\"\n autoFocus\n >\n {preferencePanel.openedPanelValue === 'columns' ? <MGHGridColumnsPanel /> : <MGHGridFilterPanel />}\n </Popover>\n\n {menuColumn && columnMenu && (\n <MGHGridColumnMenu\n column={menuColumn}\n anchorEl={columnMenu.anchorEl}\n open\n onClose={() => setColumnMenu(null)}\n themeMode={themeMode}\n panelAnchorEl={toolbarRef.current}\n />\n )}\n </div>\n );\n\n return (\n <MGHGridContext.Provider value={contextValue}>\n <div\n ref={cardRef}\n className={cx('mgh-grid-card', disableCard && 'mgh-grid-card--plain', cardClassName)}\n data-mgh-theme={themeMode}\n data-mgh-grid-card={gridId}\n style={cardStyles}\n >\n {scopedCss && <style data-mgh-grid-sx={gridId}>{scopedCss}</style>}\n {!disableCard && (header !== undefined || renderHeaderCenterContent || renderHeaderEndContent) && (\n <div className=\"mgh-grid-card-header\">\n {header !== undefined && <h3 className=\"mgh-grid-card-title\">{header}</h3>}\n {renderHeaderCenterContent && (\n <div className=\"mgh-grid-card-header-center\">{renderHeaderCenterContent}</div>\n )}\n <div className=\"mgh-grid-card-header-end\" style={{ gap: smDown ? 8 : 16 }}>\n {renderHeaderEndContent}\n </div>\n </div>\n )}\n <div className={cx('mgh-grid-box', boxClassName)} data-mgh-grid-box={gridId} style={boxStyles}>\n {grid}\n </div>\n </div>\n </MGHGridContext.Provider>\n );\n}\n\nMGHGrid.displayName = 'MGHGrid';\n","import Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\n\nimport { ConfirmDialogProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nexport default function ConfirmDialog({ title, content, action, open, onClose, ...other }: ConfirmDialogProps) {\n return (\n <Dialog fullWidth maxWidth=\"xs\" open={open} onClose={onClose} {...other}>\n <DialogTitle sx={{ pb: 2 }}>{title}</DialogTitle>\n\n {content && <DialogContent sx={{ typography: 'body2' }}> {content} </DialogContent>}\n\n <DialogActions>\n <Button onClick={onClose}>Cancel</Button>\n {action}\n </DialogActions>\n </Dialog>\n );\n}\n","import {\n GridToolbarExportContainer,\n GridCsvExportMenuItem,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n} from '@mui/x-data-grid-premium';\nimport React from 'react';\nimport { ExportContainerProps } from './CustomGridToolbarExport.types';\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomGridToolbarExport({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n // color,\n customMenuItem,\n ...other\n}: ExportContainerProps) {\n return (\n <GridToolbarExportContainer\n {...other}\n // color={color}\n >\n {customMenuItem}\n <GridCsvExportMenuItem options={csvOptions} />\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n );\n}\n","import { JSX } from 'react';\n\nimport { Dialog, Typography, DialogContent, CircularProgress } from '@mui/material';\nimport React from 'react';\n\n/// ---------------------------------------------------------------------------------------\n\ninterface ExportingProps {\n open: boolean;\n text?: JSX.Element | string;\n}\nexport default function ExportingDialog({\n open,\n text = (\n <>\n Your export is currently being built. Some larger exports can take a couple of minutes to complete. <br />\n <br />\n Please do not close your browser or refresh the page.\n </>\n ),\n}: ExportingProps) {\n return (\n <Dialog open={open} fullWidth sx={{ p: 4 }}>\n <DialogContent sx={{ p: 4, textAlign: 'center' }}>\n <Typography variant=\"subtitle1\" sx={{ mb: 3 }}>\n {text}\n </Typography>\n <CircularProgress />\n </DialogContent>\n </Dialog>\n );\n}\n"],"names":["useResponsive","query","start","end","theme","useTheme","mediaUp","useMediaQuery","breakpoints","up","mediaDown","down","mediaBetween","between","mediaOnly","only","CustomNoRowsOverlay","text","useSettingsContext","themeMode","palette","mode","StyledGridOverlay","styled","display","alignItems","justifyContent","height","fill","fillOpacity","React","createElement","Box","component","alt","src","sx","width","maxWidth","mb","canUseLocalStorage","window","localStorage","readLocalStorage","key","value","getItem","JSON","parse","writeLocalStorage","setItem","stringify","MGHGridToolbar","showColumnsButton","showFilterButton","showExportButton","showQuickFilter","renderOtherButtons","renderDateRange","customMenuItem","showCsvOption","Toolbar","style","Tooltip","title","ColumnsPanelTrigger","render","ToolbarButton","GridViewColumnIcon","fontSize","FilterPanelTrigger","props","state","color","Badge","badgeContent","filterCount","variant","GridFilterListIcon","CustomGridToolbarExport","DataGridQuickFilter","csvOptions","allColumns","excelOptions","printOptions","other","GridToolbarExportContainer","map","el","GridCsvExportMenuItem","options","GridExcelExportMenuItem","GridPrintExportMenuItem","StyledQuickFilter","QuickFilter","StyledToolbarButton","ownerState","gridArea","zIndex","opacity","expanded","pointerEvents","transition","transitions","create","StyledTextField","TextField","overflowX","QuickFilterTrigger","triggerProps","enterDelay","GridSearchIcon","QuickFilterControl","ref","controlProps","inputRef","placeholder","size","slotProps","input","startAdornment","InputAdornment","position","endAdornment","QuickFilterClear","edge","material","marginRight","GridCloseIcon","Iconify","forwardRef","icon","Icon","StyledLabel","lightMode","filledVariant","outlinedVariant","softVariant","defaultStyle","common","white","grey","backgroundColor","primary","border","secondary","alpha","colorStyle","contrastText","main","minWidth","lineHeight","borderRadius","cursor","whiteSpace","textTransform","padding","spacing","typography","pxToRem","fontWeight","fontWeightBold","duration","shorter","Label","children","startIcon","endIcon","iconStyles","objectFit","pl","pr","mr","ml","GROUPING_COLUMN_FIELD","CHECKBOX_FIELD","DETAIL_PANEL_TOGGLE_FIELD","AGGREGATION_FOOTER_ID","INTERNAL_FIELDS","Set","DENSITY_FACTORS","compact","standard","comfortable","DEFAULT_ROW_HEIGHT","DEFAULT_HEADER_HEIGHT","DEFAULT_COLUMN_MIN_WIDTH","isInternalField","field","has","isNil","isEmptyValue","Array","isArray","length","clamp","min","max","Math","cx","classNames","filter","Boolean","join","uniqueId","counter","prefix","getRowIdFromRow","row","getRowId","id","normalizeSelectionModel","allIds","type","ids","forEach","add","toDate","Date","Number","isNaN","getTime","dayjs","isDayjs","isValid","d","parsed","formatDate","withTime","date","format","startOfUnit","startOf","valueOf","isValueOptionObject","option","getOptionValue","col","getOptionLabel","label","String","resolveValueOptions","valueOptions","getCellValue","api","raw","undefined","valueGetter","defaultFormatValue","match","find","isFinite","getFormattedValue","valueFormatter","formattedValueToString","formatted","collator","Intl","Collator","numeric","sensitivity","nilFirst","v1","v2","n1","n2","numberComparator","nil","stringComparator","s1","s2","compare","stringOrNumberComparator","p1","p2","dateComparator","d1","d2","booleanComparator","getDefaultComparator","lower","toLowerCase","hasValue","item","stringFilterOperators","inputType","getApplyFilterFn","needle","indexOf","s","lastIndexOf","requiresFilterValue","set","numberOperator","filterValue","cell","n","numberFilterOperators","a","b","v","dateOperator","filterDate","filterTime","cellDate","getDateFilterOperators","booleanFilterOperators","expected","singleSelectFilterOperators","getColumnFilterOperators","filterOperators","getDefaultFilterOperators","normalizeColumn","isNumber","isBoolean","isActions","headerName","align","headerAlign","sortable","filterable","hideable","resizable","pinnable","groupable","aggregable","editable","disableColumnMenu","disableExport","internalColumn","disableReorder","CHECKBOX_COLUMN_DEF","DETAIL_PANEL_TOGGLE_COLUMN_DEF","UNITLESS_PROPERTIES","isSelectorKey","test","serializeDeclarations","block","Object","keys","property","kebab","replace","m","toKebabCase","formatCssValue","buildScopedCss","scope","out","charAt","inner","declarations","push","selector","scopeSelector","split","part","trim","numericValues","values","BUILT_IN_AGGREGATION_FUNCTIONS","sum","columnTypes","apply","nums","reduce","acc","avg","defined","every","dates","slice","sort","sorted","DEFAULT_LOCALE_TEXT","noRowsLabel","loadingLabel","toolbarColumns","toolbarFilters","toolbarExport","toolbarDensity","toolbarQuickFilterPlaceholder","toolbarQuickFilterLabel","toolbarExportCSV","toolbarExportExcel","toolbarExportPrint","densityCompact","densityStandard","densityComfortable","columnsPanelSearchPlaceholder","columnsPanelShowAll","columnsPanelHideAll","columnsPanelReset","filterPanelAddFilter","filterPanelRemoveAll","filterPanelDeleteIcon","filterPanelColumns","filterPanelOperator","filterPanelValue","filterPanelInputPlaceholder","filterPanelLogicOperator","filterPanelOperatorAnd","filterPanelOperatorOr","columnMenuSortAsc","columnMenuSortDesc","columnMenuUnsort","columnMenuFilter","columnMenuHideColumn","columnMenuManageColumns","columnMenuPinLeft","columnMenuPinRight","columnMenuUnpin","columnMenuGroup","name","columnMenuUngroup","columnMenuAggregation","aggregationMenuItemHeader","aggregationFunctionLabelNone","aggregationFunctionLabelSum","aggregationFunctionLabelAvg","aggregationFunctionLabelMin","aggregationFunctionLabelMax","aggregationFunctionLabelSize","footerRowSelected","count","toLocaleString","footerTotalRows","footerPaginationRowsPerPage","footerPaginationDisplayedRows","from","to","footerPaginationFirstPage","footerPaginationPreviousPage","footerPaginationNextPage","footerPaginationLastPage","checkboxSelectionHeaderName","checkboxSelectionSelectAllRows","checkboxSelectionUnselectAllRows","checkboxSelectionSelectRow","checkboxSelectionUnselectRow","booleanCellTrueLabel","booleanCellFalseLabel","detailPanelToggle","expandDetailPanel","collapseDetailPanel","groupingColumnHeaderName","groupColumn","unGroupColumn","actionsCellMore","columnHeaderSortIconLabel","columnMenuLabel","clearSearch","measureContext","measureText","font","document","canvas","getContext","downloadBlob","blob","fileName","url","URL","createObjectURL","anchor","href","download","body","appendChild","click","setTimeout","removeChild","revokeObjectURL","MGH_GRID_STYLE_ID","MGH_GRID_CSS","injected","useInsertion","useInsertionEffect","useLayoutEffect","useEffect","useMGHGridStyles","injectStyles","getElementById","setAttribute","textContent","head","MGHGridContext","createContext","displayName","useMGHGridContext","ctx","useContext","Error","useLatestRef","useRef","current","useControlledState","controlled","defaultValue","onChange","isControlled","internal","setInternal","useState","valueRef","controlledRef","onChangeRef","useCallback","next","resolved","is","idCounter","buildExportTable","columns","resolveExportColumns","all","getAllColumns","fields","byField","Map","c","f","get","getVisibleColumns","getRowsToExport","getSortedRowIds","rows","getRow","headers","sanitizeFileName","fallback","extension","base","endsWith","defaultFileBase","escapeCsvCell","delimiter","getDataAsCsv","includeHeaders","table","lines","h","cells","useRawValues","UTF8_BOM","fromCharCode","CRC_TABLE","Uint32Array","k","textEncoder","TextEncoder","encodeUtf8","encode","utf8","unescape","encodeURIComponent","Uint8Array","i","charCodeAt","concatBytes","chunks","total","offset","zipStore","entries","localChunks","centralChunks","entry","nameBytes","crc","bytes","crc32","data","local","lv","DataView","buffer","setUint32","setUint16","central","cv","centralDirectory","eocd","ev","concat","INVALID_XML_CHARS","RegExp","escapeXml","stripInvalidXml","columnLetter","index","letters","rem","floor","XML_HEADER","buildSheetXml","columnWidths","rowsXml","rowIndex","inlineString","xmlCells","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","lastCol","lastRow","cols","w","STYLES_XML","CONTENT_TYPES_XML","ROOT_RELS_XML","WORKBOOK_RELS_XML","buildWorkbookXml","sheetName","buildCoreXml","now","toISOString","APP_XML","buildXlsx","widths","explicit","columnsStyles","r","len","cleaned","sanitizeSheetName","escapeHtml","printGridElement","params","done","onDone","printGridElementUnsafe","error","console","cardElement","hideToolbar","hideFooter","copyStyles","clone","cloneNode","syncFormState","source","target","sourceInputs","querySelectorAll","targetInputs","t","tagName","dst","checked","indeterminate","sourceCanvases","targetCanvases","img","ownerDocument","toDataURL","cssText","replaceWith","remove","classList","removeAttribute","flexGrow","styles","links","doc","styleSheets","sheet","rules","cssRules","rule","collectStyles","iframe","finished","finish","parentNode","win","contentWindow","contentDocument","open","write","close","css","printStyle","pageStyle","h1","className","adoptNode","async","waitForImages","timeoutMs","Promise","resolve","images","complete","remaining","timer","onSettled","clearTimeout","addEventListener","once","onBeforePrint","onafterprint","focus","print","run","keyToString","buildGroupTree","groupingFields","columnsByField","emptyLabel","build","items","depth","parentId","path","buckets","getGroupingValue","groupingValueGetter","keyStr","node","parent","groupingField","groupingKey","groupingLabel","childGroups","leaves","descendants","nodes","collectTreeLeaves","roots","root","aggregateRows","aggregationModel","functions","result","fnName","fn","createIcon","rest","viewBox","focusable","ViewColumnIcon","FilterListIcon","SearchIcon","CloseIcon","DownloadIcon","ArrowUpwardIcon","ArrowDownwardIcon","MoreVertIcon","CheckIcon","ExpandMoreIcon","ChevronRightIcon","ChevronLeftIcon","FirstPageIcon","LastPageIcon","PushPinIcon","DeleteIcon","AddIcon","DensitySmallIcon","DensityMediumIcon","DensityLargeIcon","DragIndicatorIcon","PrintIcon","TableChartIcon","DescriptionIcon","VisibilityOffIcon","FunctionsIcon","WorkspacesIcon","EmptyBoxIcon","Fragment","Button","active","IconButton","TextInput","Select","Field","htmlFor","Checkbox","forwardedRef","innerRef","setRef","Spinner","role","Popover","anchorEl","onClose","placement","autoFocus","ignoreOutsideClickOn","setPosition","top","left","ready","update","vw","innerWidth","vh","innerHeight","offsetWidth","offsetHeight","isConnected","getBoundingClientRect","right","bottom","prev","observer","ResizeObserver","observe","removeEventListener","disconnect","handlePointerDown","event","contains","some","closest","handleKeyDown","querySelector","stop","stopPropagation","createPortal","tabIndex","visibility","onClick","onDoubleClick","onMouseDown","onKeyDown","Menu","first","preventDefault","currentIndex","activeElement","MenuItem","selected","disabled","hideMenu","MenuDivider","MenuSection","MGHGridColumnsButton","localeText","isOpen","preferencePanel","openedPanelValue","hidePreferences","showPreferences","currentTarget","MGHGridFiltersButton","MGHGridDensitySelector","setAnchor","o","density","setDensity","MGHGridExportMenuItem","MGHGridExportMenu","showExcelOption","showPrintOption","rootProps","customItems","Children","child","isValidElement","cloneElement","resolvedPrintOptions","header","exportDataAsCsv","exportDataAsExcel","exportDataAsPrint","MGHGridQuickFilter","debounceMs","alwaysExpanded","externalValue","quickFilterValues","setText","setExpanded","delay","quickFilterDebounceMs","lastExternal","commit","setQuickFilterValues","clear","isExpanded","expand","handleChange","onBlur","blur","showDensitySelector","quickFilterPlaceholder","showColumns","disableColumnSelector","showFilters","disableColumnFilter","showDensity","disableDensitySelector","MGHGridPagination","page","pageSize","paginationModel","rowCount","pageCount","pageSizeOptions","setPageSize","setPage","MGHGridFooter","selectedCount","rowSelectionModel","showSelected","hideFooterSelectedRowCount","showPagination","pagination","hideFooterPagination","showRowCount","hideFooterRowCount","MGHGridColumnsPanel","visibleColumns","visibleFields","useMemo","search","setSearch","model","columnVisibilityModel","filtered","setAll","visible","setColumnVisibilityModel","setColumnVisibility","useDebouncedValue","onCommit","setLocal","TextValueInput","MultiValueInput","column","joined","multiple","selectedOptions","FilterValueInput","operator","InputComponent","Component","applyValue","createFilterItem","MGHGridFilterPanel","filterableColumns","filterModel","logicOperator","targetField","seeded","upsertFilterItem","updateItem","patch","canAddMore","disableMultipleColumnsFiltering","paddingTop","operators","op","showLogic","deleteFilterItem","setFilterLogicOperator","nextColumn","nextOperators","keepOperator","nextOperator","nextIsMulti","currentIsMulti","addItem","setFilterModel","MGHGridColumnMenu","panelAnchorEl","isGroupingColumn","sortItem","sortModel","pinned","isColumnPinned","isGrouped","rowGroupingModel","aggregation","canSort","disableColumnSorting","canFilter","canHide","canPin","disableColumnPinning","canGroup","disableRowGrouping","aggregationFunctions","availableAggregationFunctions","canAggregate","disableAggregation","anchorForPanel","sortColumn","showFilterPanel","transform","pinColumn","unpinColumn","removeRowGroupingCriteria","addRowGroupingCriteria","gap","setAggregationModel","MGHGridNoRowsOverlay","imageSrc","MGHGridLoadingOverlay","MGHGridActionsCellItem","showInMenu","ActionsCell","actions","moreLabel","inline","inMenu","action","EMPTY_ARRAY","EMPTY_OBJECT","EMPTY_MAP","DEFAULT_SORTING_ORDER","DEFAULT_PAGE_SIZE_OPTIONS","DEFAULT_FILTER_MODEL","quickFilterExcludeHiddenColumns","sanitizeStyle","toDateInputValue","pad","padStart","MGHGrid","columnsProp","loading","renderHeaderEndContent","renderHeaderCenterContent","disableCard","cardClassName","boxClassName","cardStyle","cardSx","boxStyle","boxSx","themeVars","showToolbar","toolbarProps","slots","noRowsText","localeTextProp","rowHeight","rowHeightProp","columnHeaderHeight","getRowHeight","autoHeight","disableVirtualization","densityProp","onDensityChange","paginationModelProp","onPaginationModelChange","sortModelProp","onSortModelChange","sortingOrder","disableMultipleColumnsSorting","filterModelProp","onFilterModelChange","columnVisibilityModelProp","onColumnVisibilityModelChange","columnVisibilityStorageKey","columnOrderStorageKey","columnWidthStorageKey","pinnedColumnsStorageKey","onColumnOrderChange","onColumnWidthChange","disableColumnResize","disableColumnReorder","pinnedColumns","pinnedColumnsProp","onPinnedColumnsChange","checkboxSelection","checkboxSelectionVisibleOnly","disableRowSelectionOnClick","disableMultipleRowSelection","rowSelectionModelProp","onRowSelectionModelChange","isRowSelectable","keepNonExistentRowsSelected","getRowClassName","onRowClick","onRowDoubleClick","onCellClick","onCellDoubleClick","pinnedRows","getDetailPanelContent","getDetailPanelHeight","detailPanelExpandedRowIds","detailPanelExpandedRowIdsProp","onDetailPanelExpandedRowIdsChange","rowGroupingModelProp","onRowGroupingModelChange","defaultGroupingExpansionDepth","groupingColDef","isGroupExpandedByDefault","aggregationModelProp","onAggregationModelChange","aggregationFunctionsProp","aggregationPosition","processRowUpdate","onProcessRowUpdateError","onCellEditStop","isCellEditable","initialState","apiRef","onStateChange","gridId","reactUseId","useId","useStableId","rootRef","cardRef","scrollerRef","toolbarRef","forceUpdate","setTick","useForceUpdate","latest","getDetails","apiObject","L","apiImpl","rowsById","getRowModels","getAllRowIds","rowEntries","e","getRowNode","nodesById","getSortedRows","sortedLeaves","getVisibleRows","pagedRows","dr","getRowIndexRelativeToVisibleRows","findIndex","updateRows","updates","existing","setRowOverride","orderedUserColumns","visibleUserColumns","getColumn","getColumnIndex","useVisibleColumns","getColumnVisibilityModel","isVisible","setColumnWidth","setColumnIndex","targetIndex","autosizeColumns","side","getPinnedColumns","setPinnedColumns","getSortModel","setSortModel","direction","allowMultipleSorting","getFilterModel","upsertFilterItems","targetColumnField","hideFilterPanel","panel","getSelectedRows","selectedIds","getRowSelectionModel","setRowSelectionModel","normalized","setSelectedIds","selectRow","isSelected","resetSelection","selectRows","isRowSelected","isRowSelectableFn","nextPage","setPaginationModel","nextPageSize","csv","bom","utf8WithBom","Blob","startPrint","toggleDetailPanel","setExpandedDetailPanels","getExpandedDetailPanels","expandedDetailPanels","getRowGroupingModel","setRowGroupingModel","groupingIndex","splice","setRowChildrenExpansion","getRowGroupChildren","groupId","group","groupsById","getAggregationModel","startCellEditMode","stopCellEditMode","ignoreModifications","getCellMode","editing","editingCell","setEditCellValue","setEditValue","getCellParams","buildCellParams","setCellFocus","pendingFocusRef","setFocusedCell","scrollToIndexes","scroll","scroller","scrollLeft","scrollTop","getScrollPosition","rootElementRef","persisted","order","sorting","rowGrouping","controlledExpandedDetail","detailPanel","expandedRowIds","controlledSelection","orderedFields","setOrderedFields","setColumnWidths","dims","dimensions","groupExpansion","setGroupExpansion","setEditingCell","editValue","focusedCell","setPreferencePanel","columnMenu","setColumnMenu","resizingField","setResizingField","printState","setPrintState","printing","drag","setDrag","setScrollTop","scrollRaf","lastClickedIdRef","overrideState","setOverrideState","rowOverrides","viewportWidth","viewportHeight","enabled","setSize","clientWidth","clientHeight","useElementSize","densityFactor","round","headerHeight","userColumns","groupingActive","groupingColumn","single","seen","isColumnVisible","wanted","layout","leftFields","rightFields","visibleByField","center","ordered","computeWidths","available","overrides","Infinity","override","flex","pool","fixedTotal","remainingSpace","remainingFlex","changed","share","fixed","idx","hasPinning","x","leftOffset","isLeft","isRight","isLastLeft","isFirstRight","rightOffset","totalWidth","leftCount","rightCount","allDisplayColumnsByField","activeFilters","quickFilterColumns","filteredEntries","logicAnd","quickAnd","quickFilterLogicOperator","apiRefLocal","quickFns","lowered","getApplyQuickFilterFn","custom","results","compareEntries","sorters","dir","comparator","sortComparator","sortEntries","aggregationActive","isGroupExpanded","leafIds","processed","displayRows","tree","groupingSort","sortGroupTree","compareGroups","sortLeaves","sortLevel","flattenGroupTree","visit","groupNode","toGroupNode","l","childVisible","leaf","leafNode","totalDisplayRows","paginate","ceil","footerAggregates","rowsForFooter","groupAggregatesCache","getGroupAggregates","cached","heights","rowHeights","detailHeights","offsets","hasAuto","dh","virtual","virtualRange","overscan","viewTop","viewBottom","lo","hi","mid","handleScroll","requestAnimationFrame","cancelAnimationFrame","selectionCandidates","selectedCandidateCount","allCandidatesSelected","someCandidatesSelected","updateSelection","updater","selectionModelsEqual","equal","delete","lastId","toggleAllCandidates","allowMultiple","persistOrder","persistWidths","targets","lc","computed","getComputedStyle","fontFamily","cellFont","headerFont","sample","isCellEditableFn","colDef","rowNode","reason","valueParser","parseEditValue","currentValue","applyRowUpdate","newRow","oldRow","then","rowId","catch","valueSetter","previousGroupingKey","formattedValue","hasFocus","cellMode","isEditable","buildRowParams","preventScroll","visibleTop","visibleBottom","scrollIntoView","colIndex","leftPinnedWidth","rightPinnedWidth","visibleLeft","visibleRight","moveFocus","rowDelta","colDelta","absolute","canReorder","resizeRef","totalRowCount","clamped","oldIndex","moveItem","list","unshift","nextItems","withId","random","toString","contextValue","renderCellContent","renderRow","kind","selectable","content","hideCount","hideDescendantCount","paddingLeft","agg","aggregates","sampleRow","cancel","renderEditCell","onValueChange","renderEditor","renderCell","getActions","cellStyle","pinnedClasses","rowIsClickable","renderRowElement","customClass","indexRelativeToCurrentPage","isFirstVisible","isFirst","isLastVisible","isLast","isAuto","minHeight","handleRowSelectionClick","allSelected","shiftKey","ctrlKey","metaKey","isFocused","isEditing","isAggregation","cellClassName","isCheckbox","isDetailToggle","toRenderRow","renderPinnedRows","renderHeaderCell","sortIndex","showMenu","draggable","isDragging","isDropTarget","overField","menuOpen","headerParams","headerClassName","renderHeader","description","onDragStart","dataTransfer","effectAllowed","setData","onDragOver","sourceLc","dropEffect","rect","clientX","onDragLeave","onDrop","handleDrop","targetLc","without","onDragEnd","onPointerDown","handleResizeStart","startX","startWidth","lastWidth","onMove","onUp","ToolbarSlot","toolbar","FooterSlot","footer","NoRowsOverlaySlot","noRowsOverlay","LoadingOverlaySlot","loadingOverlay","mergedToolbarProps","noRowsProps","loadingProps","showNoRows","menuColumn","cardStyles","boxStyles","rootStyles","scopedCss","smDown","grid","pageRows","onScroll","renderBodyRows","detailHeight","detailContent","detailAuto","rowAuto","Provider","Dialog","fullWidth","DialogTitle","pb","DialogContent","DialogActions","p","textAlign","Typography","CircularProgress","persistedColumnVisibilityModel","persistedOrderedFields","normalizeOrderedFields","columnFields","resolvedColumnVisibilityModel","handleColumnVisibilityModelChange","details","handleColumnOrderChange","mergedInitialState","Card","CardHeader","flexWrap","flexDirection","DataGridPremium","disableRowSelectionExcludeModel","exportDataAsPrintTable","headerHtml","bodyHtml","html","cleanup","onload","srcdoc","useMGHGridApiContext","useMGHGridApiRef","useMGHGridLocaleText"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/components/iconify/iconify.tsx","../src/components/Label/styles.ts","../src/components/Label/Label.tsx","../src/components/MGHGrid/utils.ts","../src/components/MGHGrid/MGHGrid.styles.ts","../src/components/MGHGrid/context.tsx","../src/components/MGHGrid/hooks.ts","../src/components/MGHGrid/export.ts","../src/components/MGHGrid/print.ts","../src/components/MGHGrid/grouping.ts","../src/components/MGHGrid/icons.tsx","../src/components/MGHGrid/components/primitives.tsx","../src/components/MGHGrid/components/Toolbar.tsx","../src/components/MGHGrid/components/Footer.tsx","../src/components/MGHGrid/components/ColumnsPanel.tsx","../src/components/MGHGrid/components/FilterPanel.tsx","../src/components/MGHGrid/components/ColumnMenu.tsx","../src/components/MGHGrid/components/Overlays.tsx","../src/components/MGHGrid/components/ActionsCell.tsx","../src/components/MGHGrid/MGHGrid.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.styles.ts","../src/components/MGHDateRangePicker/icons.tsx","../src/components/MGHDateRangePicker/utils.ts","../src/components/MGHDateRangePicker/MGHDateRangeCalendar.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.tsx","../src/components/Confirm-Dialog/confirm-dialog.tsx","../src/components/CustomGridToolbarExport/CustomGridToolbarExport.tsx","../src/components/CustomNoRowsOverlay/CustomNoRowsOverlay.tsx","../src/components/Exporting/Exporting-Dialog.tsx","../src/hooks/useResponsive.ts"],"sourcesContent":["import { forwardRef } from 'react';\nimport { Icon } from '@iconify/react';\n\nimport { IconifyProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\ninterface Props {\n icon: IconifyProps;\n width?: number;\n height?: number;\n sx?: any;\n}\n\nconst Iconify = forwardRef<SVGElement, Props>(({ icon, width = 20, sx, ...other }, ref) => (\n <Icon icon={icon} style={{ width: 20, height: width ?? 20, ...sx }} />\n));\n\nexport default Iconify;\n","import type { ComponentProps, ComponentType } from 'react';\nimport Box from '@mui/material/Box';\nimport { alpha, styled, useTheme } from '@mui/material/styles';\nimport { LabelColor, LabelVariant } from './types';\n\n// ----------------------------------------------------------------------\n\ninterface StyledLabelOwnerState {\n color: LabelColor;\n variant: LabelVariant;\n}\n\n// Explicitly annotated so TS doesn't need to synthesize (and re-print) an anonymous type that\n// references @mui/system's install path — under pnpm that path is store-relative and triggers\n// TS2742 (\"inferred type cannot be named without a reference to ...\") during declaration emit.\nexport const StyledLabel = styled(Box)(({\n // theme,\n ownerState,\n}: {\n // theme: Theme;\n ownerState: StyledLabelOwnerState;\n}) => {\n const theme = useTheme();\n\n const lightMode = theme.palette.mode === 'light';\n\n const filledVariant = ownerState.variant === 'filled';\n\n const outlinedVariant = ownerState.variant === 'outlined';\n\n const softVariant = ownerState.variant === 'soft';\n\n const defaultStyle = {\n ...(ownerState.color === 'default' && {\n // FILLED\n ...(filledVariant && {\n color: lightMode ? theme.palette.common.white : theme.palette.grey[800],\n backgroundColor: theme.palette.text.primary,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette.text.primary,\n border: `2px solid ${theme.palette.text.primary}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.grey[500], 0.16),\n }),\n }),\n };\n\n const colorStyle = {\n ...(ownerState.color !== 'default' && {\n // FILLED\n ...(filledVariant && {\n color: theme.palette[ownerState.color].contrastText,\n backgroundColor: theme.palette[ownerState.color].main,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette[ownerState.color].main,\n border: `2px solid ${theme.palette[ownerState.color].main}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette[ownerState.color][lightMode ? 'dark' : 'light'],\n backgroundColor: alpha(theme.palette[ownerState.color].main, 0.16),\n }),\n }),\n };\n\n return {\n height: 24,\n minWidth: 24,\n lineHeight: 0,\n borderRadius: 6,\n cursor: 'default',\n alignItems: 'center',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n justifyContent: 'center',\n textTransform: 'capitalize',\n padding: theme.spacing(0, 0.75),\n fontSize: theme.typography.pxToRem(12),\n fontWeight: theme.typography.fontWeightBold,\n transition: theme.transitions.create('all', {\n duration: theme.transitions.duration.shorter,\n }),\n ...defaultStyle,\n ...colorStyle,\n };\n}) as ComponentType<ComponentProps<typeof Box> & { ownerState: StyledLabelOwnerState }>;\n","import { forwardRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { LabelProps } from './types';\nimport { StyledLabel } from './styles';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nconst Label = forwardRef<HTMLSpanElement, LabelProps>(\n ({ children, color = 'default', variant = 'soft', startIcon, endIcon, sx, ...other }, ref) => {\n // const theme = useTheme();\n\n const iconStyles = {\n width: 16,\n height: 16,\n '& svg, img': { width: 1, height: 1, objectFit: 'cover' },\n };\n\n return (\n <StyledLabel\n ref={ref}\n // component=\"span\"\n ownerState={{ color, variant }}\n sx={{\n ...(startIcon && { pl: 0.75 }),\n ...(endIcon && { pr: 0.75 }),\n ...sx,\n }}\n // theme={theme}\n {...other}\n >\n {startIcon && <Box sx={{ mr: 0.75, ...iconStyles }}> {startIcon} </Box>}\n\n {children}\n\n {endIcon && <Box sx={{ ml: 0.75, ...iconStyles }}> {endIcon} </Box>}\n </StyledLabel>\n );\n }\n);\n\nexport default Label;\n","import dayjs from 'dayjs';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridColType,\n MGHGridComparatorFn,\n MGHGridFilterItem,\n MGHGridFilterOperator,\n MGHGridLocaleText,\n MGHGridRowId,\n MGHGridRowSelectionModel,\n MGHGridRowSelectionModelInput,\n MGHGridValidRowModel,\n MGHGridValueOption,\n MGHGridValueOptionObject,\n} from './MGHGrid.types';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * ----------------------------------------------------------------------------------------------- */\n\nexport const GROUPING_COLUMN_FIELD = '__row_group_by_columns_group__';\nexport const CHECKBOX_FIELD = '__check__';\nexport const DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';\nexport const AGGREGATION_FOOTER_ID = '__aggregation_footer__';\nexport const INTERNAL_FIELDS = new Set<string>([CHECKBOX_FIELD, DETAIL_PANEL_TOGGLE_FIELD]);\n\nexport const DENSITY_FACTORS = { compact: 0.7, standard: 1, comfortable: 1.3 } as const;\nexport const DEFAULT_ROW_HEIGHT = 52;\nexport const DEFAULT_HEADER_HEIGHT = 56;\nexport const DEFAULT_COLUMN_WIDTH = 100;\nexport const DEFAULT_COLUMN_MIN_WIDTH = 50;\nexport const CHECKBOX_COLUMN_WIDTH = 50;\nexport const DETAIL_TOGGLE_COLUMN_WIDTH = 50;\nexport const GROUPING_COLUMN_WIDTH = 220;\n\nexport const isInternalField = (field: string) => INTERNAL_FIELDS.has(field) || field === GROUPING_COLUMN_FIELD;\n\n/* -------------------------------------------------------------------------------------------------\n * Generic helpers\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isEmptyValue = (value: unknown) => isNil(value) || value === '' || (Array.isArray(value) && value.length === 0);\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const arraysEqual = <T>(a: T[] | undefined, b: T[] | undefined) => {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\nexport const moveItem = <T>(list: T[], from: number, to: number): T[] => {\n const next = list.slice();\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next;\n};\n\nexport const uniqueId = (() => {\n let counter = 0;\n return (prefix = 'mgh') => {\n counter += 1;\n return `${prefix}-${counter}`;\n };\n})();\n\n/* -------------------------------------------------------------------------------------------------\n * Local storage\n * ----------------------------------------------------------------------------------------------- */\n\nexport const canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nexport const readLocalStorage = <T>(key: string): T | null => {\n if (!canUseLocalStorage()) return null;\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nexport const writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore quota / privacy errors */\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Rows\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getRowIdFromRow = <R extends MGHGridValidRowModel>(row: R, getRowId?: (row: R) => MGHGridRowId) =>\n getRowId ? getRowId(row) : (row.id as MGHGridRowId);\n\nexport const normalizeSelectionModel = (\n input: MGHGridRowSelectionModelInput | undefined,\n allIds?: MGHGridRowId[]\n): MGHGridRowSelectionModel => {\n if (!input) return { type: 'include', ids: new Set() };\n if (Array.isArray(input)) return { type: 'include', ids: new Set(input) };\n if (input instanceof Set) return { type: 'include', ids: new Set(input) };\n if (input.type === 'exclude' && allIds) {\n const ids = new Set<MGHGridRowId>();\n allIds.forEach((id) => {\n if (!input.ids.has(id)) ids.add(id);\n });\n return { type: 'include', ids };\n }\n return { type: 'include', ids: new Set(input.ids) };\n};\n\nexport const selectionModelsEqual = (a: MGHGridRowSelectionModel, b: MGHGridRowSelectionModel) => {\n if (a.ids.size !== b.ids.size) return false;\n let equal = true;\n a.ids.forEach((id) => {\n if (!b.ids.has(id)) equal = false;\n });\n return equal;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Dates\n * ----------------------------------------------------------------------------------------------- */\n\nexport const toDate = (value: unknown): Date | null => {\n if (isNil(value) || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n if (dayjs.isDayjs(value)) return value.isValid() ? value.toDate() : null;\n if (typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n if (typeof value === 'string') {\n const parsed = dayjs(value);\n return parsed.isValid() ? parsed.toDate() : null;\n }\n return null;\n};\n\nexport const formatDate = (value: unknown, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n return dayjs(date).format(withTime ? 'M/D/YYYY h:mm A' : 'M/D/YYYY');\n};\n\nconst startOfUnit = (date: Date, withTime: boolean) =>\n withTime ? dayjs(date).startOf('minute').valueOf() : dayjs(date).startOf('day').valueOf();\n\n/* -------------------------------------------------------------------------------------------------\n * Value options (singleSelect)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isValueOptionObject = (option: MGHGridValueOption): option is MGHGridValueOptionObject =>\n typeof option === 'object' && option !== null;\n\nexport const getOptionValue = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionValue ? col.getOptionValue(option) : isValueOptionObject(option) ? option.value : option;\n\nexport const getOptionLabel = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionLabel ? col.getOptionLabel(option) : isValueOptionObject(option) ? option.label : String(option);\n\nexport const resolveValueOptions = (col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (!col.valueOptions) return [] as MGHGridValueOption[];\n return typeof col.valueOptions === 'function' ? col.valueOptions({ field: col.field, row, id }) : col.valueOptions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Cell values\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getCellValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n const raw = row ? row[col.field] : undefined;\n return col.valueGetter ? col.valueGetter(raw, row, col, api) : raw;\n};\n\nexport const getGroupingValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n if (col.groupingValueGetter) return col.groupingValueGetter(row[col.field], row, col, api);\n return getCellValue(row, col, api);\n};\n\nexport const defaultFormatValue = (value: any, col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (isNil(value)) return '';\n switch (col.type) {\n case 'date':\n return formatDate(value, false);\n case 'dateTime':\n return formatDate(value, true);\n case 'boolean':\n return value ? 'Yes' : 'No';\n case 'singleSelect': {\n const options = resolveValueOptions(col, row, id);\n const match = options.find((option) => getOptionValue(col, option) === value);\n return match !== undefined ? getOptionLabel(col, match) : String(value);\n }\n case 'number':\n return typeof value === 'number' ? (Number.isFinite(value) ? String(value) : '') : String(value);\n default:\n if (value instanceof Date) return formatDate(value, true);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n }\n};\n\nexport const getFormattedValue = (\n value: any,\n row: MGHGridValidRowModel,\n col: MGHGridColDef,\n api: MGHGridApi,\n id?: MGHGridRowId\n) => {\n if (col.valueFormatter) return col.valueFormatter(value, row, col, api);\n return defaultFormatValue(value, col, row, id);\n};\n\nexport const formattedValueToString = (formatted: any): string => {\n if (isNil(formatted)) return '';\n if (typeof formatted === 'string') return formatted;\n if (typeof formatted === 'number' || typeof formatted === 'boolean') return String(formatted);\n if (formatted instanceof Date) return formatDate(formatted, true);\n if (typeof formatted === 'object' && 'props' in formatted) return '';\n return String(formatted);\n};\n\nexport const parseEditValue = (raw: any, col: MGHGridColDef) => {\n switch (col.type) {\n case 'number': {\n if (raw === '' || isNil(raw)) return null;\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case 'boolean':\n return Boolean(raw);\n case 'date':\n case 'dateTime': {\n if (raw === '' || isNil(raw)) return null;\n const d = toDate(raw);\n return d ?? raw;\n }\n default:\n return raw;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Sorting\n * ----------------------------------------------------------------------------------------------- */\n\nconst collator = typeof Intl !== 'undefined' ? new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }) : null;\n\nconst nilFirst = (v1: any, v2: any): number | null => {\n const n1 = isNil(v1) || v1 === '';\n const n2 = isNil(v2) || v2 === '';\n if (n1 && n2) return 0;\n if (n1) return -1;\n if (n2) return 1;\n return null;\n};\n\nexport const numberComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(v1) - Number(v2);\n};\n\nexport const stringComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n const s1 = String(v1);\n const s2 = String(v2);\n if (collator) return collator.compare(s1, s2);\n return s1 < s2 ? -1 : s1 > s2 ? 1 : 0;\n};\n\nexport const stringOrNumberComparator: MGHGridComparatorFn = (v1, v2, p1, p2) => {\n if (typeof v1 === 'number' && typeof v2 === 'number') return numberComparator(v1, v2, p1, p2);\n return stringComparator(v1, v2, p1, p2);\n};\n\nexport const dateComparator: MGHGridComparatorFn = (v1, v2) => {\n const d1 = toDate(v1);\n const d2 = toDate(v2);\n const nil = nilFirst(d1, d2);\n if (nil !== null) return nil;\n return (d1 as Date).getTime() - (d2 as Date).getTime();\n};\n\nexport const booleanComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(Boolean(v1)) - Number(Boolean(v2));\n};\n\nexport const getDefaultComparator = (type: MGHGridColType | undefined): MGHGridComparatorFn => {\n switch (type) {\n case 'number':\n return numberComparator;\n case 'date':\n case 'dateTime':\n return dateComparator;\n case 'boolean':\n return booleanComparator;\n default:\n return stringOrNumberComparator;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Filter operators\n * ----------------------------------------------------------------------------------------------- */\n\nconst lower = (value: unknown) => (isNil(value) ? '' : String(value).toLowerCase());\n\nconst hasValue = (item: MGHGridFilterItem) => !isEmptyValue(item.value);\n\nexport const stringFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'contains',\n label: 'contains',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) !== -1;\n },\n },\n {\n value: 'doesNotContain',\n label: 'does not contain',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === -1;\n },\n },\n {\n value: 'equals',\n label: 'equals',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) === needle;\n },\n },\n {\n value: 'doesNotEqual',\n label: 'does not equal',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) !== needle;\n },\n },\n {\n value: 'startsWith',\n label: 'starts with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === 0;\n },\n },\n {\n value: 'endsWith',\n label: 'ends with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => {\n const s = lower(value);\n return s.length >= needle.length && s.lastIndexOf(needle) === s.length - needle.length;\n };\n },\n },\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(lower));\n return (value) => set.has(lower(value));\n },\n },\n];\n\nconst numberOperator = (\n value: string,\n label: string,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: 'number',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterValue = Number(item.value);\n if (Number.isNaN(filterValue)) return null;\n return (cell) => {\n if (isNil(cell) || cell === '') return false;\n const n = Number(cell);\n return !Number.isNaN(n) && compare(n, filterValue);\n };\n },\n});\n\nexport const numberFilterOperators: MGHGridFilterOperator[] = [\n numberOperator('=', '=', (a, b) => a === b),\n numberOperator('!=', '!=', (a, b) => a !== b),\n numberOperator('>', '>', (a, b) => a > b),\n numberOperator('>=', '>=', (a, b) => a >= b),\n numberOperator('<', '<', (a, b) => a < b),\n numberOperator('<=', '<=', (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map((v: any) => Number(v)));\n return (value) => !isNil(value) && set.has(Number(value));\n },\n },\n];\n\nconst dateOperator = (\n value: string,\n label: string,\n withTime: boolean,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: withTime ? 'datetime-local' : 'date',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterDate = toDate(item.value);\n if (!filterDate) return null;\n const filterTime = startOfUnit(filterDate, withTime);\n return (cell) => {\n const cellDate = toDate(cell);\n if (!cellDate) return false;\n return compare(startOfUnit(cellDate, withTime), filterTime);\n };\n },\n});\n\nexport const getDateFilterOperators = (withTime: boolean): MGHGridFilterOperator[] => [\n dateOperator('is', 'is', withTime, (a, b) => a === b),\n dateOperator('not', 'is not', withTime, (a, b) => a !== b),\n dateOperator('after', 'is after', withTime, (a, b) => a > b),\n dateOperator('onOrAfter', 'is on or after', withTime, (a, b) => a >= b),\n dateOperator('before', 'is before', withTime, (a, b) => a < b),\n dateOperator('onOrBefore', 'is on or before', withTime, (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) === null,\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) !== null,\n },\n];\n\nexport const booleanFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'boolean',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '' || item.value === 'any') return null;\n const expected = item.value === true || item.value === 'true';\n return (value) => Boolean(value) === expected;\n },\n },\n];\n\nexport const singleSelectFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) === String(item.value);\n },\n },\n {\n value: 'not',\n label: 'is not',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) !== String(item.value);\n },\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(String));\n return (value) => set.has(String(value));\n },\n },\n];\n\nexport const getDefaultFilterOperators = (type: MGHGridColType | undefined): MGHGridFilterOperator[] => {\n switch (type) {\n case 'number':\n return numberFilterOperators;\n case 'date':\n return getDateFilterOperators(false);\n case 'dateTime':\n return getDateFilterOperators(true);\n case 'boolean':\n return booleanFilterOperators;\n case 'singleSelect':\n return singleSelectFilterOperators;\n case 'actions':\n return [];\n default:\n return stringFilterOperators;\n }\n};\n\nexport const getColumnFilterOperators = (col: MGHGridColDef) => col.filterOperators ?? getDefaultFilterOperators(col.type);\n\n/* -------------------------------------------------------------------------------------------------\n * Column normalisation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const normalizeColumn = <R extends MGHGridValidRowModel>(col: MGHGridColDef<R>): MGHGridColDef<R> => {\n const type = col.type ?? 'string';\n const isNumber = type === 'number';\n const isBoolean = type === 'boolean';\n const isActions = type === 'actions';\n return {\n ...col,\n type,\n headerName: col.headerName ?? col.field,\n width: col.width ?? (isActions ? 100 : isBoolean ? 100 : DEFAULT_COLUMN_WIDTH),\n minWidth: col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n align: col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n headerAlign: col.headerAlign ?? col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n sortable: isActions ? false : (col.sortable ?? true),\n filterable: isActions ? false : (col.filterable ?? true),\n hideable: col.hideable ?? true,\n resizable: col.resizable ?? true,\n pinnable: col.pinnable ?? true,\n groupable: isActions ? false : (col.groupable ?? true),\n aggregable: isActions ? false : (col.aggregable ?? true),\n editable: col.editable ?? false,\n disableColumnMenu: col.disableColumnMenu ?? isActions,\n disableExport: col.disableExport ?? isActions,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Internal (auto-generated) columns\n * ----------------------------------------------------------------------------------------------- */\n\nconst internalColumn = (field: string, width: number): MGHGridColDef =>\n normalizeColumn({\n field,\n headerName: '',\n width,\n minWidth: width,\n maxWidth: width,\n sortable: false,\n filterable: false,\n hideable: false,\n resizable: false,\n pinnable: false,\n groupable: false,\n aggregable: false,\n disableColumnMenu: true,\n disableExport: true,\n disableReorder: true,\n align: 'center',\n headerAlign: 'center',\n });\n\n/** Definition of the checkbox-selection column (equivalent of MUI's GRID_CHECKBOX_SELECTION_COL_DEF). */\nexport const CHECKBOX_COLUMN_DEF: MGHGridColDef = internalColumn(CHECKBOX_FIELD, CHECKBOX_COLUMN_WIDTH);\n/** Definition of the detail-panel toggle column (equivalent of MUI's GRID_DETAIL_PANEL_TOGGLE_COL_DEF). */\nexport const DETAIL_PANEL_TOGGLE_COLUMN_DEF: MGHGridColDef = internalColumn(\n DETAIL_PANEL_TOGGLE_FIELD,\n DETAIL_TOGGLE_COLUMN_WIDTH\n);\n\n/* -------------------------------------------------------------------------------------------------\n * sx -> scoped CSS\n * ----------------------------------------------------------------------------------------------- */\n\nconst UNITLESS_PROPERTIES = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n]);\n\n/** Keys that are CSS selectors / at-rules rather than CSS properties. */\nexport const isSelectorKey = (key: string) => /[&.:#>\\[\\s*~+,@]/.test(key);\n\nconst toKebabCase = (property: string) => {\n if (property.indexOf('--') === 0) return property;\n const kebab = property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n return kebab.indexOf('ms-') === 0 ? `-${kebab}` : kebab;\n};\n\nconst formatCssValue = (property: string, value: string | number) =>\n typeof value === 'number' && value !== 0 && !UNITLESS_PROPERTIES.has(property) && property.indexOf('--') !== 0\n ? `${value}px`\n : String(value);\n\nconst serializeDeclarations = (block: Record<string, unknown>) =>\n Object.keys(block)\n .filter((key) => {\n const value = block[key];\n return !isSelectorKey(key) && (typeof value === 'string' || typeof value === 'number');\n })\n .map((key) => `${toKebabCase(key)}:${formatCssValue(key, block[key] as string | number)}`)\n .join(';');\n\nconst scopeSelector = (scope: string, selector: string) =>\n selector\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => (part.indexOf('&') !== -1 ? part.replace(/&/g, scope) : `${scope} ${part}`))\n .join(',');\n\n/**\n * Compiles the nested-selector part of an `sx`-like object into CSS scoped under `scope`.\n * Top-level plain properties are ignored here (they are applied as inline styles instead).\n */\nexport const buildScopedCss = (scope: string, sx: Record<string, unknown> | undefined, out: string[] = []): string[] => {\n if (!sx) return out;\n Object.keys(sx).forEach((key) => {\n const value = sx[key];\n if (!value || typeof value !== 'object') return;\n const block = value as Record<string, unknown>;\n if (key.charAt(0) === '@') {\n const inner: string[] = [];\n const declarations = serializeDeclarations(block);\n if (declarations) inner.push(`${scope}{${declarations}}`);\n buildScopedCss(scope, block, inner);\n if (inner.length) out.push(`${key}{${inner.join('')}}`);\n return;\n }\n const selector = scopeSelector(scope, key);\n const declarations = serializeDeclarations(block);\n if (declarations) out.push(`${selector}{${declarations}}`);\n buildScopedCss(selector, block, out);\n });\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nconst numericValues = (values: any[]) =>\n values.map((v) => (typeof v === 'number' ? v : Number(v))).filter((n) => !Number.isNaN(n) && n !== null);\n\nexport const BUILT_IN_AGGREGATION_FUNCTIONS: Record<string, MGHGridAggregationFunction> = {\n sum: {\n label: 'sum',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0);\n },\n },\n avg: {\n label: 'avg',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0) / nums.length;\n },\n },\n min: {\n label: 'min',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.min(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.min(...dates.map((d) => (d as Date).getTime())));\n }\n return defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any))[0];\n },\n },\n max: {\n label: 'max',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.max(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.max(...dates.map((d) => (d as Date).getTime())));\n }\n const sorted = defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any));\n return sorted[sorted.length - 1];\n },\n },\n size: {\n label: 'size',\n apply: ({ values }) => values.length,\n },\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Locale\n * ----------------------------------------------------------------------------------------------- */\n\nexport const DEFAULT_LOCALE_TEXT: MGHGridLocaleText = {\n noRowsLabel: 'No rows',\n loadingLabel: 'Loading…',\n toolbarColumns: 'Columns',\n toolbarFilters: 'Filters',\n toolbarExport: 'Export',\n toolbarDensity: 'Density',\n toolbarQuickFilterPlaceholder: 'Search...',\n toolbarQuickFilterLabel: 'Search',\n toolbarExportCSV: 'Download as CSV',\n toolbarExportExcel: 'Download as Excel',\n toolbarExportPrint: 'Print',\n densityCompact: 'Compact',\n densityStandard: 'Standard',\n densityComfortable: 'Comfortable',\n columnsPanelSearchPlaceholder: 'Search',\n columnsPanelShowAll: 'Show all',\n columnsPanelHideAll: 'Hide all',\n columnsPanelReset: 'Reset',\n filterPanelAddFilter: 'Add filter',\n filterPanelRemoveAll: 'Remove all',\n filterPanelDeleteIcon: 'Delete',\n filterPanelColumns: 'Columns',\n filterPanelOperator: 'Operator',\n filterPanelValue: 'Value',\n filterPanelInputPlaceholder: 'Filter value',\n filterPanelLogicOperator: 'Logic operator',\n filterPanelOperatorAnd: 'And',\n filterPanelOperatorOr: 'Or',\n columnMenuSortAsc: 'Sort by ASC',\n columnMenuSortDesc: 'Sort by DESC',\n columnMenuUnsort: 'Unsort',\n columnMenuFilter: 'Filter',\n columnMenuHideColumn: 'Hide column',\n columnMenuManageColumns: 'Manage columns',\n columnMenuPinLeft: 'Pin to left',\n columnMenuPinRight: 'Pin to right',\n columnMenuUnpin: 'Unpin',\n columnMenuGroup: (name) => `Group by ${name}`,\n columnMenuUngroup: (name) => `Stop grouping by ${name}`,\n columnMenuAggregation: 'Aggregation',\n aggregationMenuItemHeader: 'Aggregation',\n aggregationFunctionLabelNone: 'none',\n aggregationFunctionLabelSum: 'sum',\n aggregationFunctionLabelAvg: 'avg',\n aggregationFunctionLabelMin: 'min',\n aggregationFunctionLabelMax: 'max',\n aggregationFunctionLabelSize: 'size',\n footerRowSelected: (count) => (count === 1 ? '1 row selected' : `${count.toLocaleString()} rows selected`),\n footerTotalRows: 'Total Rows:',\n footerPaginationRowsPerPage: 'Rows per page:',\n footerPaginationDisplayedRows: (from, to, count) => `${from}–${to} of ${count.toLocaleString()}`,\n footerPaginationFirstPage: 'First page',\n footerPaginationPreviousPage: 'Previous page',\n footerPaginationNextPage: 'Next page',\n footerPaginationLastPage: 'Last page',\n checkboxSelectionHeaderName: 'Checkbox selection',\n checkboxSelectionSelectAllRows: 'Select all rows',\n checkboxSelectionUnselectAllRows: 'Unselect all rows',\n checkboxSelectionSelectRow: 'Select row',\n checkboxSelectionUnselectRow: 'Unselect row',\n booleanCellTrueLabel: 'yes',\n booleanCellFalseLabel: 'no',\n detailPanelToggle: 'Detail panel toggle',\n expandDetailPanel: 'Expand',\n collapseDetailPanel: 'Collapse',\n groupingColumnHeaderName: 'Group',\n groupColumn: (name) => `Group by ${name}`,\n unGroupColumn: (name) => `Stop grouping by ${name}`,\n actionsCellMore: 'more',\n columnHeaderSortIconLabel: 'Sort',\n columnMenuLabel: 'Menu',\n clearSearch: 'Clear search',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Text measurement (used for autosize)\n * ----------------------------------------------------------------------------------------------- */\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nexport const measureText = (text: string, font: string) => {\n if (typeof document === 'undefined') return text.length * 8;\n if (measureContext === undefined) {\n const canvas = document.createElement('canvas');\n measureContext = canvas.getContext('2d');\n }\n if (!measureContext) return text.length * 8;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Downloads\n * ----------------------------------------------------------------------------------------------- */\n\nexport const downloadBlob = (blob: Blob, fileName: string) => {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n window.setTimeout(() => {\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n }, 0);\n};\n","import React from 'react';\n\nexport const MGH_GRID_STYLE_ID = 'mgh-grid-styles';\n\n/**\n * Stylesheet for MGHGrid. It is injected once into <head> the first time a grid mounts,\n * so consumers do not need a CSS loader. All colours are CSS variables so the look can be\n * customised globally (by redefining `--mgh-grid-*` on `.mgh-grid-card`) or per instance\n * through the `themeVars` prop.\n */\nexport const MGH_GRID_CSS = `\n.mgh-grid-card {\n --mgh-grid-font-family: inherit;\n --mgh-grid-font-size: 14px;\n --mgh-grid-radius: 16px;\n --mgh-grid-inner-radius: 4px;\n --mgh-grid-paper: #ffffff;\n --mgh-grid-bg: #ffffff;\n --mgh-grid-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-fg-secondary: rgba(0, 0, 0, 0.6);\n --mgh-grid-fg-disabled: rgba(0, 0, 0, 0.38);\n --mgh-grid-border: rgba(224, 224, 224, 1);\n --mgh-grid-header-bg: #ffffff;\n --mgh-grid-header-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-hover: rgba(0, 0, 0, 0.04);\n --mgh-grid-hover-strong: rgba(0, 0, 0, 0.08);\n --mgh-grid-selected: rgba(25, 118, 210, 0.08);\n --mgh-grid-selected-hover: rgba(25, 118, 210, 0.12);\n --mgh-grid-primary: #1976d2;\n --mgh-grid-primary-contrast: #ffffff;\n --mgh-grid-focus: #1976d2;\n --mgh-grid-shadow: 0 0 2px rgba(145, 158, 171, 0.2), 0 12px 24px -4px rgba(145, 158, 171, 0.12);\n --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n --mgh-grid-overlay: rgba(255, 255, 255, 0.6);\n --mgh-grid-input-bg: transparent;\n --mgh-grid-input-border: rgba(0, 0, 0, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.12);\n --mgh-grid-group-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-footer-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-badge: #1976d2;\n --mgh-grid-scrollbar: rgba(0, 0, 0, 0.3);\n\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n background: var(--mgh-grid-paper);\n color: var(--mgh-grid-fg);\n border-radius: var(--mgh-grid-radius);\n box-shadow: var(--mgh-grid-shadow);\n font-family: var(--mgh-grid-font-family);\n font-size: var(--mgh-grid-font-size);\n line-height: 1.5;\n overflow: hidden;\n box-sizing: border-box;\n}\n.mgh-grid-card[data-mgh-theme=\"dark\"] {\n --mgh-grid-paper: #212b36;\n --mgh-grid-bg: #212b36;\n --mgh-grid-fg: #ffffff;\n --mgh-grid-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-grid-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-grid-border: rgba(81, 81, 81, 1);\n --mgh-grid-header-bg: #212b36;\n --mgh-grid-header-fg: #ffffff;\n --mgh-grid-hover: rgba(255, 255, 255, 0.08);\n --mgh-grid-hover-strong: rgba(255, 255, 255, 0.16);\n --mgh-grid-selected: rgba(144, 202, 249, 0.16);\n --mgh-grid-selected-hover: rgba(144, 202, 249, 0.24);\n --mgh-grid-primary: #90caf9;\n --mgh-grid-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-grid-focus: #90caf9;\n --mgh-grid-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 12px 24px -4px rgba(0, 0, 0, 0.12);\n --mgh-grid-overlay: rgba(33, 43, 54, 0.6);\n --mgh-grid-input-border: rgba(255, 255, 255, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.5);\n --mgh-grid-group-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-footer-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-badge: #90caf9;\n --mgh-grid-scrollbar: rgba(255, 255, 255, 0.3);\n}\n/* Only our own elements get the border-box reset. A blanket descendant reset would leak into\n consumer content rendered through slots (e.g. MUI TextField inputs rely on content-box). */\n[class*=\"mgh-grid\"], [class*=\"mgh-grid\"]::before, [class*=\"mgh-grid\"]::after { box-sizing: border-box; }\n.mgh-grid-card--plain { box-shadow: none; border-radius: 0; background: transparent; }\n\n/* ---- card header ---- */\n/* Title stays on its row; only the end-content group wraps internally (like the legacy MUI card). */\n.mgh-grid-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 16px 16px 0; flex-wrap: nowrap; }\n.mgh-grid-card-title { flex: 0 0 auto; padding: 8px 24px; margin: 0; font-size: 1.125rem; font-weight: 700; line-height: 1.5556; }\n/* Children are auto-sized so space-between leaves equal gaps title|center|end (like the legacy MUI card).\n Only the end group shrinks (and wraps internally); the centre content keeps its natural width. */\n.mgh-grid-card-header-center { flex: 0 0 auto; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }\n.mgh-grid-card-header-end { flex: 0 1 auto; min-width: 0; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }\n.mgh-grid-card-header-end:first-child { margin-left: auto; }\n@media (max-width: 599.95px) {\n .mgh-grid-card-header { flex-wrap: wrap; }\n .mgh-grid-card-header-end { gap: 8px; }\n}\n\n/* ---- box + root ---- */\n.mgh-grid-box { display: flex; flex-direction: column; flex-grow: 1; min-height: 0; min-width: 0; }\n.mgh-grid {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n border: 1px solid var(--mgh-grid-border);\n border-radius: var(--mgh-grid-inner-radius);\n background: var(--mgh-grid-bg);\n color: var(--mgh-grid-fg);\n outline: none;\n}\n.mgh-grid--auto-height { flex: 0 0 auto; }\n\n/* ---- toolbar ---- */\n.mgh-grid-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 45px; padding: 4px 8px; border-bottom: 1px solid var(--mgh-grid-border); flex-wrap: wrap; }\n.mgh-grid-toolbar-group { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }\n.mgh-grid-toolbar-center { display: flex; align-items: center; flex: 1 1 auto; justify-content: center; }\n\n/* ---- buttons ---- */\n.mgh-grid-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-grid-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; text-transform: none; white-space: nowrap; }\n.mgh-grid-btn:hover { background: var(--mgh-grid-hover); color: var(--mgh-grid-fg); }\n.mgh-grid-btn:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 1px; }\n.mgh-grid-btn:disabled { color: var(--mgh-grid-fg-disabled); cursor: default; background: transparent; }\n.mgh-grid-btn--icon { padding: 6px; border-radius: 50%; width: 32px; height: 32px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small { width: 26px; height: 26px; padding: 3px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small .mgh-grid-icon { width: 18px; height: 18px; }\n.mgh-grid-btn--primary { color: var(--mgh-grid-primary); }\n.mgh-grid-btn--primary:hover { background: var(--mgh-grid-selected); color: var(--mgh-grid-primary); }\n.mgh-grid-btn--contained { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); }\n.mgh-grid-btn--contained:hover { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); filter: brightness(0.92); }\n.mgh-grid-btn--active { color: var(--mgh-grid-primary); }\n\n/* ---- badge ---- */\n.mgh-grid-badge { position: relative; display: inline-flex; }\n.mgh-grid-badge-dot { position: absolute; top: 0; right: 0; min-width: 8px; height: 8px; border-radius: 4px; background: var(--mgh-grid-badge); transform: translate(50%, -50%); }\n.mgh-grid-badge-count { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--mgh-grid-badge); color: var(--mgh-grid-primary-contrast); font-size: 10px; font-weight: 600; line-height: 16px; text-align: center; transform: translate(50%, -50%); }\n\n/* ---- inputs ---- */\n.mgh-grid-input, .mgh-grid-select { font: inherit; font-size: 0.875rem; color: var(--mgh-grid-fg); background: var(--mgh-grid-input-bg); border: 1px solid var(--mgh-grid-input-border); border-radius: 6px; padding: 6px 10px; height: 36px; min-width: 0; outline: none; transition: border-color .15s, box-shadow .15s; }\n.mgh-grid-input:hover, .mgh-grid-select:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-input:focus, .mgh-grid-select:focus { border-color: var(--mgh-grid-focus); box-shadow: 0 0 0 1px var(--mgh-grid-focus); }\n.mgh-grid-input::placeholder { color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-input--small, .mgh-grid-select--small { height: 32px; padding: 4px 8px; font-size: 0.8125rem; }\n.mgh-grid-select { appearance: none; -webkit-appearance: none; padding-right: 28px; background-image: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23888'><path d='M7 10l5 5 5-5z'/></svg>\"); background-repeat: no-repeat; background-position: right 6px center; background-size: 18px; cursor: pointer; }\n.mgh-grid-select option { color: initial; background: initial; }\n.mgh-grid-card[data-mgh-theme=\"dark\"] .mgh-grid-select option, .mgh-grid-popover[data-mgh-theme=\"dark\"] .mgh-grid-select option { color: #fff; background: #212b36; }\n.mgh-grid-select[multiple] { height: auto; min-height: 36px; background-image: none; padding-right: 10px; }\n.mgh-grid-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.mgh-grid-field-label { font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-input-adorned { position: relative; display: flex; align-items: center; }\n.mgh-grid-input-adorned .mgh-grid-input { width: 100%; padding-left: 34px; }\n.mgh-grid-input-adorned--clearable .mgh-grid-input { padding-right: 34px; }\n.mgh-grid-input-adornment { position: absolute; left: 10px; display: inline-flex; color: var(--mgh-grid-fg-secondary); pointer-events: none; }\n.mgh-grid-input-adornment--end { left: auto; right: 4px; pointer-events: auto; }\n\n/* ---- checkbox ---- */\n.mgh-grid-checkbox { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 0; border: 2px solid var(--mgh-grid-fg-secondary); border-radius: 3px; background: transparent; cursor: pointer; display: inline-grid; place-content: center; position: relative; flex: 0 0 auto; transition: background-color .12s, border-color .12s; }\n.mgh-grid-checkbox:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-checkbox:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 2px; }\n.mgh-grid-checkbox:checked, .mgh-grid-checkbox:indeterminate { background: var(--mgh-grid-primary); border-color: var(--mgh-grid-primary); }\n.mgh-grid-checkbox:checked::after { content: \"\"; width: 5px; height: 10px; border: solid var(--mgh-grid-primary-contrast); border-width: 0 2px 2px 0; transform: translateY(-1px) rotate(45deg); }\n.mgh-grid-checkbox:indeterminate::after { content: \"\"; width: 10px; height: 2px; background: var(--mgh-grid-primary-contrast); }\n.mgh-grid-checkbox:disabled { opacity: 0.4; cursor: default; }\n.mgh-grid-checkbox-label { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.875rem; padding: 6px 4px; border-radius: 4px; }\n.mgh-grid-checkbox-label:hover { background: var(--mgh-grid-hover); }\n\n/* ---- quick filter ---- */\n.mgh-grid-quick-filter { display: grid; align-items: center; }\n.mgh-grid-quick-filter-trigger { grid-area: 1 / 1; z-index: 1; transition: opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-trigger { opacity: 0; pointer-events: none; }\n.mgh-grid-quick-filter-control { grid-area: 1 / 1; width: 32px; opacity: 0; overflow: hidden; transition: width .2s, opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 260px; opacity: 1; }\n@media (max-width: 599.95px) { .mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 180px; } }\n\n/* ---- main / scroller ---- */\n.mgh-grid-main { position: relative; display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden; }\n.mgh-grid--auto-height .mgh-grid-main { flex: 0 0 auto; }\n.mgh-grid-scroller { position: relative; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: auto; outline: none; scrollbar-width: thin; }\n.mgh-grid--auto-height .mgh-grid-scroller { overflow-y: hidden; }\n.mgh-grid-scroller::-webkit-scrollbar { width: 10px; height: 10px; }\n.mgh-grid-scroller::-webkit-scrollbar-thumb { background: var(--mgh-grid-scrollbar); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }\n\n/* ---- column headers ---- */\n.mgh-grid-columns { position: sticky; top: 0; z-index: 3; background: var(--mgh-grid-header-bg); border-bottom: 1px solid var(--mgh-grid-border); min-width: 100%; width: max-content; }\n.mgh-grid-header-row { display: flex; min-width: 100%; }\n.mgh-grid-header-cell { position: relative; display: flex; align-items: center; flex: 0 0 auto; height: var(--mgh-grid-header-height); padding: 0 10px; font-weight: 600; font-size: 0.875rem; color: var(--mgh-grid-header-fg); background: var(--mgh-grid-header-bg); white-space: nowrap; overflow: hidden; user-select: none; outline: none; }\n.mgh-grid-header-cell--sortable { cursor: pointer; }\n.mgh-grid-header-cell:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; }\n.mgh-grid-header-cell--align-center { justify-content: center; }\n.mgh-grid-header-cell--align-right { justify-content: flex-end; }\n.mgh-grid-header-cell--align-right .mgh-grid-header-title-container { flex-direction: row-reverse; }\n.mgh-grid-header-title-container { display: flex; align-items: center; gap: 2px; min-width: 0; flex: 1 1 auto; overflow: hidden; }\n.mgh-grid-header-cell--align-center .mgh-grid-header-title-container { flex: 0 1 auto; }\n.mgh-grid-header-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.mgh-grid-sort-icon { display: inline-flex; align-items: center; color: var(--mgh-grid-fg-secondary); opacity: 0; transition: opacity .15s; flex: 0 0 auto; }\n.mgh-grid-header-cell:hover .mgh-grid-sort-icon, .mgh-grid-sort-icon--active { opacity: 1; }\n.mgh-grid-sort-index { font-size: 10px; margin-left: -2px; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-header-menu-btn { position: absolute; right: 2px; opacity: 0; transition: opacity .15s; background: var(--mgh-grid-header-bg); }\n.mgh-grid-header-cell--align-right .mgh-grid-header-menu-btn { right: auto; left: 2px; }\n.mgh-grid-header-cell:hover .mgh-grid-header-menu-btn, .mgh-grid-header-menu-btn--open, .mgh-grid-header-cell:focus-within .mgh-grid-header-menu-btn { opacity: 1; }\n.mgh-grid-header-cell--menu-open { background: var(--mgh-grid-hover); }\n.mgh-grid-resize-handle { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 2; display: flex; justify-content: center; touch-action: none; }\n.mgh-grid-resize-handle::after { content: \"\"; width: 1px; height: 60%; margin-top: 20%; background: var(--mgh-grid-border); transition: background .15s, width .15s; }\n.mgh-grid-resize-handle:hover::after, .mgh-grid-resize-handle--active::after { background: var(--mgh-grid-primary); width: 2px; }\n.mgh-grid-header-cell--last .mgh-grid-resize-handle { right: 0; }\n.mgh-grid-header-cell--dragging { opacity: 0.5; }\n.mgh-grid-header-cell--drop-left::before, .mgh-grid-header-cell--drop-right::before { content: \"\"; position: absolute; top: 4px; bottom: 4px; width: 2px; background: var(--mgh-grid-primary); z-index: 3; }\n.mgh-grid-header-cell--drop-left::before { left: 0; }\n.mgh-grid-header-cell--drop-right::before { right: 0; }\n.mgh-grid-header-filler { flex: 1 1 auto; background: var(--mgh-grid-header-bg); }\n\n/* ---- pinned cells ---- */\n.mgh-grid-cell--pinned-left, .mgh-grid-header-cell--pinned-left { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-cell--pinned-right, .mgh-grid-header-cell--pinned-right { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-header-cell--pinned-left, .mgh-grid-header-cell--pinned-right { z-index: 4; background-color: var(--mgh-grid-header-bg); }\n.mgh-grid-cell--pinned-left-last, .mgh-grid-header-cell--pinned-left-last { box-shadow: 2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-cell--pinned-right-first, .mgh-grid-header-cell--pinned-right-first { box-shadow: -2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid--no-pinned-shadow .mgh-grid-cell--pinned-left-last, .mgh-grid--no-pinned-shadow .mgh-grid-header-cell--pinned-left-last { box-shadow: none; }\n\n/* ---- body & rows ---- */\n.mgh-grid-body { position: relative; min-width: 100%; width: max-content; }\n.mgh-grid-body--flow { display: flex; flex-direction: column; }\n.mgh-grid-row-block { min-width: 100%; }\n.mgh-grid-body--virtual .mgh-grid-row-block { position: absolute; left: 0; }\n.mgh-grid-row { display: flex; min-width: 100%; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); position: relative; }\n.mgh-grid-row--auto-height { align-items: stretch; }\n.mgh-grid-row:hover { background: var(--mgh-grid-hover); }\n.mgh-grid-row--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-row--selected:hover { background: var(--mgh-grid-selected-hover); }\n.mgh-grid-row--clickable { cursor: pointer; }\n.mgh-grid-row--group { background: var(--mgh-grid-group-bg); }\n.mgh-grid-row--pinned { background: var(--mgh-grid-bg); }\n.mgh-grid-row--footer { background: var(--mgh-grid-footer-bg); font-weight: 600; }\n.mgh-grid-row:hover .mgh-grid-cell--pinned-left, .mgh-grid-row:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-hover), var(--mgh-grid-hover)); }\n.mgh-grid-row--selected .mgh-grid-cell--pinned-left, .mgh-grid-row--selected .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected), var(--mgh-grid-selected)); }\n.mgh-grid-row--selected:hover .mgh-grid-cell--pinned-left, .mgh-grid-row--selected:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected-hover), var(--mgh-grid-selected-hover)); }\n.mgh-grid-row--group .mgh-grid-cell--pinned-left, .mgh-grid-row--group .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-group-bg), var(--mgh-grid-group-bg)); }\n.mgh-grid-row--footer .mgh-grid-cell--pinned-left, .mgh-grid-row--footer .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-footer-bg), var(--mgh-grid-footer-bg)); }\n.mgh-grid-row-filler { flex: 1 1 auto; }\n\n.mgh-grid-cell { display: flex; align-items: center; flex: 0 0 auto; padding: 0 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 0.875rem; outline: none; min-height: 100%; }\n.mgh-grid-cell > .mgh-grid-cell-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.mgh-grid-row--auto-height .mgh-grid-cell { white-space: normal; align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }\n.mgh-grid-row--auto-height .mgh-grid-cell > .mgh-grid-cell-text { white-space: normal; word-break: break-word; }\n.mgh-grid-cell--align-center { justify-content: center; }\n.mgh-grid-cell--align-right { justify-content: flex-end; }\n.mgh-grid-cell--focused { outline: 1px solid var(--mgh-grid-focus); outline-offset: -1px; }\n.mgh-grid-cell--editable { cursor: text; }\n.mgh-grid-cell--editing { padding: 0 4px; outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; background: var(--mgh-grid-bg); }\n.mgh-grid-cell--editing .mgh-grid-input, .mgh-grid-cell--editing .mgh-grid-select { width: 100%; height: calc(100% - 6px); border: 0; box-shadow: none; padding: 0 6px; background: transparent; }\n.mgh-grid-cell--checkbox, .mgh-grid-header-cell--checkbox, .mgh-grid-cell--detail-toggle, .mgh-grid-header-cell--detail-toggle { justify-content: center; padding: 0; }\n.mgh-grid-cell--boolean .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-cell--actions { gap: 2px; justify-content: center; }\n.mgh-grid-cell--aggregation { flex-direction: column; align-items: stretch; justify-content: center; line-height: 1.2; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-right { align-items: flex-end; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-center { align-items: center; }\n.mgh-grid-aggregation-label { font-size: 0.65rem; font-weight: 500; text-transform: uppercase; color: var(--mgh-grid-fg-secondary); letter-spacing: .04em; }\n.mgh-grid-group-cell { display: flex; align-items: center; gap: 4px; min-width: 0; }\n.mgh-grid-group-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }\n.mgh-grid-group-count { color: var(--mgh-grid-fg-secondary); margin-left: 2px; }\n.mgh-grid-group-toggle { flex: 0 0 auto; }\n.mgh-grid-group-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-group-toggle--expanded .mgh-grid-icon { transform: rotate(90deg); }\n.mgh-grid-detail-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-detail-toggle--expanded .mgh-grid-icon { transform: rotate(180deg); }\n\n/* ---- pinned rows ---- */\n.mgh-grid-pinned-rows { position: sticky; z-index: 2; min-width: 100%; width: max-content; background: var(--mgh-grid-bg); }\n.mgh-grid-pinned-rows--top { box-shadow: 0 2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom { bottom: 0; box-shadow: 0 -2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom .mgh-grid-row { border-bottom: 0; border-top: 1px solid var(--mgh-grid-border); }\n\n/* ---- detail panel ---- */\n.mgh-grid-detail-panel { position: sticky; left: 0; overflow: auto; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); z-index: 1; }\n\n/* ---- overlays ---- */\n.mgh-grid-overlay { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; z-index: 5; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; pointer-events: none; }\n.mgh-grid-overlay--loading { background: var(--mgh-grid-overlay); pointer-events: auto; }\n.mgh-grid-no-rows { display: flex; align-items: center; justify-content: center; gap: 8px; height: 100%; text-align: center; padding: 16px; }\n.mgh-grid-no-rows img, .mgh-grid-no-rows .mgh-grid-icon { width: 50px; height: 50px; color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-spinner { width: 36px; height: 36px; border-radius: 50%; border: 3px solid var(--mgh-grid-selected); border-top-color: var(--mgh-grid-primary); animation: mgh-grid-spin .8s linear infinite; }\n@keyframes mgh-grid-spin { to { transform: rotate(360deg); } }\n\n/* ---- footer ---- */\n.mgh-grid-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 52px; padding: 0 8px 0 16px; border-top: 1px solid var(--mgh-grid-border); font-size: 0.875rem; color: var(--mgh-grid-fg-secondary); flex-wrap: wrap; }\n.mgh-grid-footer-left { display: flex; align-items: center; gap: 16px; }\n.mgh-grid-pagination { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }\n.mgh-grid-pagination-select { height: 32px; padding: 2px 24px 2px 8px; font-size: 0.875rem; border-color: transparent; }\n.mgh-grid-pagination-select:hover { border-color: transparent; background-color: var(--mgh-grid-hover); }\n.mgh-grid-pagination-actions { display: inline-flex; align-items: center; }\n\n/* ---- popover / menu / panels ---- */\n.mgh-grid-popover {\n --mgh-grid-font-family: inherit; --mgh-grid-font-size: 14px; --mgh-grid-paper: #ffffff; --mgh-grid-bg: #fff; --mgh-grid-fg: rgba(0,0,0,.87); --mgh-grid-fg-secondary: rgba(0,0,0,.6); --mgh-grid-fg-disabled: rgba(0,0,0,.38); --mgh-grid-border: rgba(224,224,224,1); --mgh-grid-hover: rgba(0,0,0,.04); --mgh-grid-selected: rgba(25,118,210,.08); --mgh-grid-primary: #1976d2; --mgh-grid-primary-contrast: #fff; --mgh-grid-focus: #1976d2; --mgh-grid-input-bg: transparent; --mgh-grid-input-border: rgba(0,0,0,.23); --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n position: fixed; z-index: 1300; background: var(--mgh-grid-paper); color: var(--mgh-grid-fg); border-radius: 8px; box-shadow: var(--mgh-grid-popover-shadow); font-family: var(--mgh-grid-font-family); font-size: var(--mgh-grid-font-size); line-height: 1.5; outline: none; max-height: calc(100vh - 16px); overflow: auto; animation: mgh-grid-pop .12s ease-out;\n}\n.mgh-grid-popover[data-mgh-theme=\"dark\"] { --mgh-grid-paper: #212b36; --mgh-grid-bg: #212b36; --mgh-grid-fg: #fff; --mgh-grid-fg-secondary: rgba(255,255,255,.7); --mgh-grid-fg-disabled: rgba(255,255,255,.5); --mgh-grid-border: rgba(81,81,81,1); --mgh-grid-hover: rgba(255,255,255,.08); --mgh-grid-selected: rgba(144,202,249,.16); --mgh-grid-primary: #90caf9; --mgh-grid-primary-contrast: rgba(0,0,0,.87); --mgh-grid-focus: #90caf9; --mgh-grid-input-border: rgba(255,255,255,.23); }\n@keyframes mgh-grid-pop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }\n.mgh-grid-menu { list-style: none; margin: 0; padding: 6px 0; min-width: 180px; }\n.mgh-grid-menu-item { display: flex; align-items: center; gap: 12px; padding: 6px 16px; min-height: 36px; font-size: 0.875rem; cursor: pointer; white-space: nowrap; color: var(--mgh-grid-fg); background: transparent; border: 0; width: 100%; text-align: left; font-family: inherit; outline: none; }\n.mgh-grid-menu-item:hover, .mgh-grid-menu-item:focus-visible { background: var(--mgh-grid-hover); }\n.mgh-grid-menu-item--disabled { color: var(--mgh-grid-fg-disabled); cursor: default; pointer-events: none; }\n.mgh-grid-menu-item--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-menu-item .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); flex: 0 0 auto; }\n.mgh-grid-menu-divider { height: 1px; margin: 6px 0; background: var(--mgh-grid-border); border: 0; }\n.mgh-grid-menu-header { padding: 6px 16px 2px; font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); text-transform: uppercase; letter-spacing: .04em; }\n.mgh-grid-menu-section { padding: 4px 16px 8px; display: flex; flex-direction: column; gap: 4px; }\n.mgh-grid-panel { display: flex; flex-direction: column; min-width: 300px; max-width: min(640px, calc(100vw - 16px)); }\n.mgh-grid-panel-header { padding: 12px 12px 4px; }\n.mgh-grid-panel-content { padding: 4px 12px; overflow: auto; max-height: 360px; }\n.mgh-grid-panel-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; }\n.mgh-grid-columns-list { display: flex; flex-direction: column; }\n.mgh-grid-filter-row { display: grid; grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); gap: 8px; align-items: end; margin-bottom: 8px; }\n.mgh-grid-filter-row--first { grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row--with-logic { grid-template-columns: 32px 80px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row .mgh-grid-btn--icon { margin-bottom: 4px; }\n.mgh-grid-filter-empty { padding: 8px 4px; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; }\n@media (max-width: 599.95px) { .mgh-grid-filter-row, .mgh-grid-filter-row--with-logic { grid-template-columns: 1fr; } }\n\n/* ---- misc ---- */\n.mgh-grid-tooltip-anchor { display: inline-flex; }\n.mgh-grid-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }\n@media print { .mgh-grid-toolbar, .mgh-grid-footer { display: none !important; } }\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_GRID_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_GRID_STYLE_ID;\n style.setAttribute('data-mgh-grid', 'true');\n style.textContent = MGH_GRID_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHGrid stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHGridStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridLocaleText,\n MGHGridState,\n MGHGridThemeMode,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\n\nexport interface MGHGridRootProps {\n header?: React.ReactNode;\n pagination: boolean;\n pageSizeOptions: number[];\n hideFooterPagination: boolean;\n hideFooterRowCount: boolean;\n hideFooterSelectedRowCount: boolean;\n disableColumnFilter: boolean;\n disableColumnSelector: boolean;\n disableDensitySelector: boolean;\n disableColumnPinning: boolean;\n disableColumnSorting: boolean;\n disableMultipleColumnsSorting: boolean;\n disableMultipleColumnsFiltering: boolean;\n disableRowGrouping: boolean;\n disableAggregation: boolean;\n checkboxSelection: boolean;\n aggregationFunctions: Record<string, MGHGridAggregationFunction>;\n quickFilterDebounceMs: number;\n}\n\nexport interface MGHGridContextValue {\n api: MGHGridApi;\n state: MGHGridState;\n localeText: MGHGridLocaleText;\n themeMode: MGHGridThemeMode;\n rootProps: MGHGridRootProps;\n /** All user columns (ordered, including hidden). */\n columns: MGHGridColDef[];\n /** Visible user columns. */\n visibleColumns: MGHGridColDef[];\n}\n\nexport const MGHGridContext = React.createContext<MGHGridContextValue | null>(null);\nMGHGridContext.displayName = 'MGHGridContext';\n\nexport const useMGHGridContext = () => {\n const ctx = React.useContext(MGHGridContext);\n if (!ctx) {\n throw new Error('MGHGrid: this component must be rendered inside an <MGHGrid /> (e.g. through a slot).');\n }\n return ctx;\n};\n\n/** Access the grid API from custom toolbars, menu items, cells, etc. */\nexport const useMGHGridApiContext = <R extends MGHGridValidRowModel = any>() => useMGHGridContext().api as MGHGridApi<R>;\n\nexport const useMGHGridLocaleText = () => useMGHGridContext().localeText;\n\n/** Creates a ref to hold the grid API; pass it to `<MGHGrid apiRef={apiRef} />`. */\nexport const useMGHGridApiRef = <R extends MGHGridValidRowModel = any>() =>\n React.useRef<MGHGridApi<R> | null>(null) as React.MutableRefObject<MGHGridApi<R> | null>;\n","import React from 'react';\n\n/** Keeps a ref always pointing at the latest value (assigned during render). */\nexport function useLatestRef<T>(value: T) {\n const ref = React.useRef(value);\n ref.current = value;\n return ref;\n}\n\n/** Returns a stable function that always calls the latest `fn`. */\nexport function useEventCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useLatestRef(fn);\n return React.useCallback(((...args: any[]) => ref.current(...args)) as T, []);\n}\n\n/**\n * Controlled / uncontrolled state helper. When `controlled` is defined the internal state is\n * ignored and every change is reported through `onChange` only.\n */\nexport function useControlledState<T>(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void\n): [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = controlled !== undefined;\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : internal;\n const valueRef = useLatestRef(value);\n const controlledRef = useLatestRef(isControlled);\n const onChangeRef = useLatestRef(onChange);\n\n const setValue = React.useCallback((next: T | ((prev: T) => T)) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(valueRef.current) : next;\n if (Object.is(resolved, valueRef.current)) return;\n valueRef.current = resolved;\n if (!controlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [value, setValue];\n}\n\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n/** Observes the client size of an element. */\nexport function useElementSize<T extends HTMLElement>(ref: React.RefObject<T | null>, enabled = true): ElementSize {\n const [size, setSize] = React.useState<ElementSize>({ width: 0, height: 0 });\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !enabled) return undefined;\n const update = () => {\n const width = el.clientWidth;\n const height = el.clientHeight;\n setSize((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n };\n update();\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return size;\n}\n\n/** `window.matchMedia` as a hook. Always false on the server. */\nexport function useMediaQuery(query: string) {\n const getMatch = () =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false;\n const [matches, setMatches] = React.useState(getMatch);\n\n React.useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return undefined;\n const media = window.matchMedia(query);\n const listener = () => setMatches(media.matches);\n listener();\n if (media.addEventListener) {\n media.addEventListener('change', listener);\n return () => media.removeEventListener('change', listener);\n }\n media.addListener(listener);\n return () => media.removeListener(listener);\n }, [query]);\n\n return matches;\n}\n\n/** Debounced version of a callback. The returned function is stable. */\nexport function useDebouncedCallback<T extends (...args: any[]) => void>(fn: T, delay: number) {\n const fnRef = useLatestRef(fn);\n const timerRef = React.useRef<number | null>(null);\n\n React.useEffect(\n () => () => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n },\n []\n );\n\n return React.useCallback(\n (...args: Parameters<T>) => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n timerRef.current = window.setTimeout(() => {\n timerRef.current = null;\n fnRef.current(...args);\n }, delay);\n },\n [delay]\n );\n}\n\nexport function useForceUpdate() {\n const [, setTick] = React.useState(0);\n return React.useCallback(() => setTick((t) => t + 1), []);\n}\n\nlet idCounter = 0;\n/** Stable unique id per component instance (React.useId fallback for older Reacts). */\nexport function useStableId(prefix: string) {\n const reactUseId = (React as any).useId as undefined | (() => string);\n if (reactUseId) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const id = reactUseId();\n return `${prefix}-${id.replace(/:/g, '')}`;\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const ref = React.useRef<string | null>(null);\n if (ref.current === null) {\n idCounter += 1;\n ref.current = `${prefix}-${idCounter}`;\n }\n return ref.current;\n}\n","import {\n MGHGridApi,\n MGHGridColDef,\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridExportOptions,\n MGHGridPrintExportOptions,\n MGHGridRowId,\n} from './MGHGrid.types';\nimport {\n downloadBlob,\n formattedValueToString,\n getCellValue,\n getFormattedValue,\n isInternalField,\n isNil,\n toDate,\n} from './utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Shared: resolve the columns & rows to export\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ExportCell {\n raw: any;\n formatted: string;\n col: MGHGridColDef;\n}\n\nexport interface ExportTable {\n columns: MGHGridColDef[];\n headers: string[];\n rows: ExportCell[][];\n}\n\nexport const resolveExportColumns = (api: MGHGridApi, options: MGHGridExportOptions): MGHGridColDef[] => {\n const all = api.getAllColumns();\n let columns: MGHGridColDef[];\n if (options.fields) {\n const byField = new Map<string, MGHGridColDef>();\n all.forEach((c) => byField.set(c.field, c));\n columns = options.fields.map((f) => byField.get(f)).filter(Boolean) as MGHGridColDef[];\n } else if (options.allColumns) {\n columns = all;\n } else {\n columns = api.getVisibleColumns();\n }\n return columns.filter((c) => !c.disableExport && !isInternalField(c.field) && c.type !== 'actions');\n};\n\nexport const buildExportTable = (api: MGHGridApi, options: MGHGridExportOptions): ExportTable => {\n const columns = resolveExportColumns(api, options);\n const ids: MGHGridRowId[] = options.getRowsToExport ? options.getRowsToExport({ api }) : api.getSortedRowIds();\n const rows: ExportCell[][] = [];\n ids.forEach((id) => {\n const row = api.getRow(id);\n if (!row) return;\n rows.push(\n columns.map((col) => {\n const raw = getCellValue(row, col, api);\n const formatted = formattedValueToString(getFormattedValue(raw, row, col, api, id));\n return { raw, formatted, col };\n })\n );\n });\n return { columns, headers: columns.map((c) => c.headerName ?? c.field), rows };\n};\n\nconst sanitizeFileName = (name: string | undefined, fallback: string, extension: string) => {\n const base = (name && name.trim()) || fallback;\n return base.toLowerCase().endsWith(`.${extension}`) ? base : `${base}.${extension}`;\n};\n\nconst defaultFileBase = () => {\n const title = typeof document !== 'undefined' && document.title ? document.title.trim() : '';\n return (title || 'export').replace(/[\\\\/:*?\"<>|]+/g, '-');\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CSV\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeCsvCell = (value: string, delimiter: string) => {\n let text = value;\n // Guard against formula injection when opening in spreadsheet software.\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n if (text.indexOf('\"') !== -1 || text.indexOf(delimiter) !== -1 || /[\\r\\n]/.test(text)) {\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n }\n return text;\n};\n\nexport const getDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const delimiter = options.delimiter ?? ',';\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const lines: string[] = [];\n if (includeHeaders) {\n lines.push(table.headers.map((h) => escapeCsvCell(h, delimiter)).join(delimiter));\n }\n table.rows.forEach((cells) => {\n lines.push(\n cells\n .map((cell) => {\n const text = options.useRawValues ? (isNil(cell.raw) ? '' : String(cell.raw)) : cell.formatted;\n return escapeCsvCell(text, delimiter);\n })\n .join(delimiter)\n );\n });\n return lines.join('\\r\\n');\n};\n\nconst UTF8_BOM = String.fromCharCode(0xfeff);\n\nexport const exportDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const csv = getDataAsCsv(api, options);\n const bom = options.utf8WithBom ? UTF8_BOM : '';\n const blob = new Blob([bom + csv], { type: 'text/csv;charset=utf-8;' });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'csv'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * XLSX (minimal OOXML writer + store-only ZIP, no dependencies)\n * ----------------------------------------------------------------------------------------------- */\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n += 1) {\n let c = n;\n for (let k = 0; k < 8; k += 1) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nconst crc32 = (bytes: Uint8Array) => {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i += 1) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n};\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst encodeUtf8 = (text: string): Uint8Array => {\n if (textEncoder) return textEncoder.encode(text);\n // Fallback for very old environments.\n const utf8 = unescape(encodeURIComponent(text));\n const out = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i += 1) out[i] = utf8.charCodeAt(i);\n return out;\n};\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nconst concatBytes = (chunks: Uint8Array[]) => {\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n chunks.forEach((c) => {\n out.set(c, offset);\n offset += c.length;\n });\n return out;\n};\n\nconst zipStore = (entries: ZipEntry[]): Uint8Array => {\n const localChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n // 1980-01-01 00:00 in DOS date/time format.\n const dosTime = 0;\n const dosDate = (1 << 5) | 1;\n\n entries.forEach((entry) => {\n const nameBytes = encodeUtf8(entry.name);\n const crc = crc32(entry.data);\n const size = entry.data.length;\n\n const local = new Uint8Array(30 + nameBytes.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0x0800, true); // UTF-8 names\n lv.setUint16(8, 0, true); // store\n lv.setUint16(10, dosTime, true);\n lv.setUint16(12, dosDate, true);\n lv.setUint32(14, crc, true);\n lv.setUint32(18, size, true);\n lv.setUint32(22, size, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0x0800, true);\n cv.setUint16(10, 0, true);\n cv.setUint16(12, dosTime, true);\n cv.setUint16(14, dosDate, true);\n cv.setUint32(16, crc, true);\n cv.setUint32(20, size, true);\n cv.setUint32(24, size, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, offset, true);\n central.set(nameBytes, 46);\n\n localChunks.push(local, entry.data);\n centralChunks.push(central);\n offset += local.length + size;\n });\n\n const centralDirectory = concatBytes(centralChunks);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDirectory.length, true);\n ev.setUint32(16, offset, true);\n ev.setUint16(20, 0, true);\n\n return concatBytes(localChunks.concat([centralDirectory, eocd]));\n};\n\n// Characters that are illegal in XML 1.0 (built without literal control characters in source).\nconst INVALID_XML_CHARS = new RegExp(\n '[' +\n String.fromCharCode(0x00) +\n '-' +\n String.fromCharCode(0x08) +\n String.fromCharCode(0x0b) +\n String.fromCharCode(0x0c) +\n String.fromCharCode(0x0e) +\n '-' +\n String.fromCharCode(0x1f) +\n String.fromCharCode(0xfffe) +\n String.fromCharCode(0xffff) +\n ']',\n 'g'\n);\nconst stripInvalidXml = (text: string) => text.replace(INVALID_XML_CHARS, '');\n\nconst escapeXml = (text: string) =>\n stripInvalidXml(text)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n\nconst columnLetter = (index: number) => {\n let n = index + 1;\n let letters = '';\n while (n > 0) {\n const rem = (n - 1) % 26;\n letters = String.fromCharCode(65 + rem) + letters;\n n = Math.floor((n - 1) / 26);\n }\n return letters;\n};\n\nconst sanitizeSheetName = (name: string | undefined) => {\n const cleaned = (name || 'Sheet1').replace(/[\\[\\]:*?/\\\\]/g, ' ').trim() || 'Sheet1';\n return cleaned.length > 31 ? cleaned.slice(0, 31) : cleaned;\n};\n\nconst XML_HEADER = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n\nconst buildSheetXml = (table: ExportTable, includeHeaders: boolean, columnWidths: number[]) => {\n const rowsXml: string[] = [];\n let rowIndex = 1;\n\n const inlineString = (ref: string, text: string, style?: number) =>\n `<c r=\"${ref}\" t=\"inlineStr\"${style ? ` s=\"${style}\"` : ''}><is><t xml:space=\"preserve\">${escapeXml(\n text\n )}</t></is></c>`;\n\n if (includeHeaders) {\n const cells = table.headers.map((h, i) => inlineString(`${columnLetter(i)}${rowIndex}`, h, 1)).join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${cells}</row>`);\n rowIndex += 1;\n }\n\n table.rows.forEach((cells) => {\n const xmlCells = cells\n .map((cell, i) => {\n const ref = `${columnLetter(i)}${rowIndex}`;\n const type = cell.col.type;\n if (isNil(cell.raw) || cell.raw === '') return '';\n if (type === 'number' && typeof cell.raw === 'number' && Number.isFinite(cell.raw)) {\n return `<c r=\"${ref}\"><v>${cell.raw}</v></c>`;\n }\n if (type === 'boolean') {\n return `<c r=\"${ref}\" t=\"b\"><v>${cell.raw ? 1 : 0}</v></c>`;\n }\n if ((type === 'date' || type === 'dateTime') && toDate(cell.raw)) {\n // Excel serial date (days since 1899-12-30), written in local time with a date style.\n const d = toDate(cell.raw) as Date;\n const utc = Date.UTC(\n d.getFullYear(),\n d.getMonth(),\n d.getDate(),\n d.getHours(),\n d.getMinutes(),\n d.getSeconds()\n );\n const serial = utc / 86400000 + 25569;\n return `<c r=\"${ref}\" s=\"${type === 'dateTime' ? 3 : 2}\"><v>${serial}</v></c>`;\n }\n return inlineString(ref, cell.formatted);\n })\n .join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${xmlCells}</row>`);\n rowIndex += 1;\n });\n\n const lastCol = columnLetter(Math.max(table.columns.length - 1, 0));\n const lastRow = Math.max(rowIndex - 1, 1);\n const cols = columnWidths.map((w, i) => `<col min=\"${i + 1}\" max=\"${i + 1}\" width=\"${w}\" customWidth=\"1\"/>`).join('');\n\n return (\n XML_HEADER +\n '<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<dimension ref=\"A1:${lastCol}${lastRow}\"/>` +\n '<sheetViews><sheetView workbookViewId=\"0\">' +\n (includeHeaders ? '<pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/>' : '') +\n '</sheetView></sheetViews>' +\n '<sheetFormatPr defaultRowHeight=\"15\"/>' +\n (cols ? `<cols>${cols}</cols>` : '') +\n `<sheetData>${rowsXml.join('')}</sheetData>` +\n (includeHeaders && table.rows.length > 0 ? `<autoFilter ref=\"A1:${lastCol}${lastRow}\"/>` : '') +\n '</worksheet>'\n );\n};\n\nconst STYLES_XML =\n XML_HEADER +\n '<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n '<numFmts count=\"2\"><numFmt numFmtId=\"164\" formatCode=\"m/d/yyyy\"/><numFmt numFmtId=\"165\" formatCode=\"m/d/yyyy h:mm AM/PM\"/></numFmts>' +\n '<fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts>' +\n '<fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills>' +\n '<borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>' +\n '<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>' +\n '<cellXfs count=\"4\">' +\n '<xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>' +\n '<xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>' +\n '<xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"165\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '</cellXfs>' +\n '<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>' +\n '</styleSheet>';\n\nconst CONTENT_TYPES_XML =\n XML_HEADER +\n '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n '<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>' +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n '<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>' +\n '<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>' +\n '</Types>';\n\nconst ROOT_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>' +\n '<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>' +\n '</Relationships>';\n\nconst WORKBOOK_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>' +\n '</Relationships>';\n\nconst buildWorkbookXml = (sheetName: string) =>\n XML_HEADER +\n '<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<sheets><sheet name=\"${escapeXml(sheetName)}\" sheetId=\"1\" r:id=\"rId1\"/></sheets>` +\n '</workbook>';\n\nconst buildCoreXml = () => {\n const now = new Date().toISOString();\n return (\n XML_HEADER +\n '<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" ' +\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" ' +\n 'xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n '<dc:creator>MGH Grid</dc:creator>' +\n `<dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>` +\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>` +\n '</cp:coreProperties>'\n );\n};\n\nconst APP_XML =\n XML_HEADER +\n '<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" ' +\n 'xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">' +\n '<Application>MGH Grid</Application></Properties>';\n\nexport const buildXlsx = (api: MGHGridApi, options: MGHGridExcelExportOptions = {}): Uint8Array => {\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const widths = table.columns.map((col, i) => {\n const explicit = options.columnsStyles?.[col.field]?.width;\n if (explicit) return explicit;\n let max = table.headers[i].length;\n for (let r = 0; r < Math.min(table.rows.length, 500); r += 1) {\n const len = table.rows[r][i].formatted.length;\n if (len > max) max = len;\n }\n return Math.min(Math.max(max + 2, 8), 60);\n });\n const sheetName = sanitizeSheetName(options.sheetName);\n const entries: ZipEntry[] = [\n { name: '[Content_Types].xml', data: encodeUtf8(CONTENT_TYPES_XML) },\n { name: '_rels/.rels', data: encodeUtf8(ROOT_RELS_XML) },\n { name: 'docProps/core.xml', data: encodeUtf8(buildCoreXml()) },\n { name: 'docProps/app.xml', data: encodeUtf8(APP_XML) },\n { name: 'xl/workbook.xml', data: encodeUtf8(buildWorkbookXml(sheetName)) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(WORKBOOK_RELS_XML) },\n { name: 'xl/styles.xml', data: encodeUtf8(STYLES_XML) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(buildSheetXml(table, includeHeaders, widths)) },\n ];\n return zipStore(entries);\n};\n\nexport const exportDataAsExcel = async (api: MGHGridApi, options: MGHGridExcelExportOptions = {}) => {\n const bytes = buildXlsx(api, options);\n const blob = new Blob([bytes as BlobPart], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'xlsx'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Print\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Legacy value-based print (plain HTML table). The grid's `exportDataAsPrint` prints the live DOM instead. */\nexport const exportDataAsPrintTable = (api: MGHGridApi, options: MGHGridPrintExportOptions = {}) => {\n if (typeof document === 'undefined') return;\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const title = options.title ?? options.fileName ?? document.title ?? '';\n\n const headerHtml = includeHeaders\n ? `<thead><tr>${table.headers\n .map((h, i) => `<th class=\"${table.columns[i].align ?? 'left'}\">${escapeHtml(h)}</th>`)\n .join('')}</tr></thead>`\n : '';\n const bodyHtml = `<tbody>${table.rows\n .map(\n (cells) =>\n `<tr>${cells\n .map((cell) => `<td class=\"${cell.col.align ?? 'left'}\">${escapeHtml(cell.formatted)}</td>`)\n .join('')}</tr>`\n )\n .join('')}</tbody>`;\n\n const html =\n '<!doctype html><html><head><meta charset=\"utf-8\" />' +\n `<title>${escapeHtml(title)}</title>` +\n '<style>' +\n 'body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;font-size:12px;color:#111;margin:16px;}' +\n 'h1{font-size:16px;margin:0 0 12px;}' +\n 'table{border-collapse:collapse;width:100%;}' +\n 'th,td{border:1px solid #ccc;padding:4px 8px;text-align:left;vertical-align:top;}' +\n 'th{background:#f3f3f3;font-weight:600;}' +\n 'td.right,th.right{text-align:right;} td.center,th.center{text-align:center;}' +\n 'tr{page-break-inside:avoid;} thead{display:table-header-group;}' +\n (options.pageStyle ?? '') +\n '</style></head><body>' +\n (title ? `<h1>${escapeHtml(title)}</h1>` : '') +\n `<table>${headerHtml}${bodyHtml}</table>` +\n '</body></html>';\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = '0';\n iframe.style.opacity = '0';\n document.body.appendChild(iframe);\n\n const cleanup = () => {\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 1000);\n };\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (!win) {\n cleanup();\n return;\n }\n try {\n win.focus();\n win.onafterprint = cleanup;\n win.print();\n } catch {\n cleanup();\n }\n };\n\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\n if (doc) {\n doc.open();\n doc.write(html);\n doc.close();\n } else {\n iframe.srcdoc = html;\n }\n};\n","import { MGHGridPrintExportOptions } from './MGHGrid.types';\n\n/**\n * Prints the grid \"as seen on screen\": the live DOM of the grid card is cloned into a hidden iframe\n * together with the page's stylesheets, so anything rendered by `renderCell` (images, chips,\n * links, custom components) prints exactly as displayed. The grid itself must already be rendered\n * in print mode (all rows, no virtualization) when this is called.\n */\n\nconst PRINT_CSS = `\n@page { margin: 10mm; }\nhtml, body { margin: 0; padding: 0; background: #fff; }\n.mgh-grid-print-title { margin: 0 0 12px; font: 600 16px/1.4 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif; }\n.mgh-grid-card { box-shadow: none !important; border-radius: 0 !important; height: auto !important; max-height: none !important; overflow: visible !important; background: transparent !important; }\n.mgh-grid-box { height: auto !important; max-height: none !important; flex: none !important; }\n.mgh-grid { height: auto !important; max-height: none !important; border-radius: 0 !important; }\n.mgh-grid-main, .mgh-grid-scroller { overflow: visible !important; height: auto !important; max-height: none !important; }\n.mgh-grid-columns, .mgh-grid-pinned-rows, .mgh-grid-detail-panel { position: static !important; box-shadow: none !important; }\n.mgh-grid-header-cell, .mgh-grid-cell { position: static !important; box-shadow: none !important; background-image: none !important; }\n.mgh-grid-detail-panel { width: auto !important; }\n.mgh-grid-body { min-height: 0 !important; }\n.mgh-grid-row, .mgh-grid-row-block, .mgh-grid-detail-panel { break-inside: avoid; page-break-inside: avoid; }\n.mgh-grid-columns { break-after: avoid; page-break-after: avoid; }\n.mgh-grid-header-menu-btn, .mgh-grid-resize-handle, .mgh-grid-overlay, .mgh-grid-sort-icon:not(.mgh-grid-sort-icon--active) { display: none !important; }\n.mgh-grid-popover { display: none !important; }\n`;\n\nconst collectStyles = (doc: Document) => {\n const styles: string[] = [];\n const links: string[] = [];\n Array.from(doc.styleSheets).forEach((sheet) => {\n try {\n const rules = Array.from(sheet.cssRules)\n .map((rule) => rule.cssText)\n .join('\\n');\n if (rules) styles.push(rules);\n } catch {\n // Cross-origin stylesheet: reference it instead of inlining.\n if (sheet.href) links.push(sheet.href);\n }\n });\n return { styles, links };\n};\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Copies live form-control state (cloneNode does not copy `checked` / `value`). */\nconst syncFormState = (source: HTMLElement, target: HTMLElement) => {\n const sourceInputs = Array.from(source.querySelectorAll('input, select, textarea'));\n const targetInputs = Array.from(target.querySelectorAll('input, select, textarea'));\n sourceInputs.forEach((el, i) => {\n const t = targetInputs[i];\n if (!t || t.tagName !== el.tagName) return;\n // Tag-name checks instead of `instanceof`: the elements may belong to different documents.\n if (el.tagName === 'INPUT') {\n const src = el as HTMLInputElement;\n const dst = t as HTMLInputElement;\n if (src.type === 'checkbox' || src.type === 'radio') {\n dst.checked = src.checked;\n if (src.checked) dst.setAttribute('checked', '');\n dst.indeterminate = src.indeterminate;\n } else {\n dst.value = src.value;\n dst.setAttribute('value', src.value);\n }\n } else if (el.tagName === 'SELECT') {\n (t as HTMLSelectElement).value = (el as HTMLSelectElement).value;\n } else if (el.tagName === 'TEXTAREA') {\n (t as HTMLTextAreaElement).value = (el as HTMLTextAreaElement).value;\n t.textContent = (el as HTMLTextAreaElement).value;\n }\n });\n // Canvases lose their bitmap when cloned: replace them with images.\n const sourceCanvases = Array.from(source.querySelectorAll('canvas'));\n const targetCanvases = Array.from(target.querySelectorAll('canvas'));\n sourceCanvases.forEach((canvas, i) => {\n const t = targetCanvases[i];\n if (!t) return;\n try {\n const img = t.ownerDocument.createElement('img');\n img.src = canvas.toDataURL();\n img.width = canvas.width;\n img.height = canvas.height;\n img.style.cssText = t.style.cssText;\n t.replaceWith(img);\n } catch {\n /* tainted canvas – leave as is */\n }\n });\n};\n\nconst waitForImages = (doc: Document, timeoutMs: number) =>\n new Promise<void>((resolve) => {\n const images = Array.from(doc.images).filter((img) => !img.complete);\n if (images.length === 0) {\n resolve();\n return;\n }\n let remaining = images.length;\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n resolve();\n };\n const timer = window.setTimeout(finish, timeoutMs);\n images.forEach((img) => {\n const onSettled = () => {\n remaining -= 1;\n if (remaining <= 0) {\n window.clearTimeout(timer);\n finish();\n }\n };\n img.addEventListener('load', onSettled, { once: true });\n img.addEventListener('error', onSettled, { once: true });\n });\n });\n\nexport interface PrintGridParams {\n /** The `.mgh-grid-card` element (already rendered in print mode). */\n cardElement: HTMLElement;\n options: MGHGridPrintExportOptions;\n /** Called once the print dialog has been handed off (or failed) so the grid can leave print mode. */\n onDone: () => void;\n}\n\nexport const printGridElement = (params: PrintGridParams) => {\n let done = false;\n const onDone = () => {\n if (done) return;\n done = true;\n params.onDone();\n };\n try {\n printGridElementUnsafe({ ...params, onDone });\n } catch (error) {\n console.error('MGHGrid: print failed', error);\n onDone();\n }\n};\n\nconst printGridElementUnsafe = ({ cardElement, options, onDone }: PrintGridParams) => {\n if (typeof document === 'undefined') {\n onDone();\n return;\n }\n const hideToolbar = options.hideToolbar ?? true;\n const hideFooter = options.hideFooter ?? false;\n const includeHeaders = options.includeHeaders ?? true;\n const copyStyles = options.copyStyles ?? true;\n\n const clone = cardElement.cloneNode(true) as HTMLElement;\n syncFormState(cardElement, clone);\n clone.querySelectorAll('.mgh-grid-card-header').forEach((el) => el.remove());\n if (hideToolbar) clone.querySelectorAll('.mgh-grid-toolbar').forEach((el) => el.remove());\n if (hideFooter) clone.querySelectorAll('.mgh-grid-footer').forEach((el) => el.remove());\n if (!includeHeaders) clone.querySelectorAll('.mgh-grid-columns').forEach((el) => el.remove());\n clone.classList.add('mgh-grid-card--plain');\n // Remove ids to avoid duplicates and drop inline sizing coming from cardStyle/boxStyle.\n clone.querySelectorAll('[id]').forEach((el) => el.removeAttribute('id'));\n clone.style.height = 'auto';\n clone.style.flexGrow = '0';\n\n const title = options.title ?? '';\n const { styles, links } = copyStyles ? collectStyles(document) : { styles: [], links: [] };\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.setAttribute('data-mgh-grid-print', 'true');\n iframe.style.cssText = 'position:fixed;right:0;bottom:0;width:0;height:0;border:0;opacity:0;pointer-events:none;';\n document.body.appendChild(iframe);\n\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 500);\n onDone();\n };\n\n const win = iframe.contentWindow;\n const doc = iframe.contentDocument || win?.document;\n if (!win || !doc) {\n finish();\n return;\n }\n\n doc.open();\n doc.write(\n `<!doctype html><html><head><meta charset=\"utf-8\" /><title>${escapeHtml(title || document.title || 'Print')}</title>` +\n links.map((href) => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\" />`).join('') +\n `</head><body></body></html>`\n );\n doc.close();\n\n styles.forEach((css) => {\n const style = doc.createElement('style');\n style.textContent = css;\n doc.head.appendChild(style);\n });\n const printStyle = doc.createElement('style');\n printStyle.textContent = PRINT_CSS + (options.pageStyle ?? '');\n doc.head.appendChild(printStyle);\n\n if (title) {\n const h1 = doc.createElement('h1');\n h1.className = 'mgh-grid-print-title';\n h1.textContent = title;\n doc.body.appendChild(h1);\n }\n doc.body.appendChild(doc.adoptNode(clone));\n\n const run = async () => {\n try {\n await waitForImages(doc, 4000);\n if (options.onBeforePrint) await options.onBeforePrint(doc);\n win.onafterprint = finish;\n win.focus();\n win.print();\n // Most browsers block on print(); if afterprint never fires, still restore the grid.\n window.setTimeout(finish, 1000);\n } catch {\n finish();\n }\n };\n void run();\n};\n","import {\n MGHGridAggregationFunction,\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridColDef,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridRowId,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport { formattedValueToString, getCellValue, getFormattedValue, getGroupingValue, isNil } from './utils';\n\nexport interface RowEntry<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n row: R;\n}\n\n/** Internal tree node used while grouping. */\nexport interface GroupTreeNode<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n depth: number;\n parent: MGHGridRowId | null;\n groupingField: string;\n groupingKey: any;\n groupingLabel: string;\n childGroups: GroupTreeNode<R>[];\n /** Direct leaf children (only populated at the deepest level). */\n leaves: RowEntry<R>[];\n /** Every descendant leaf, in display order after sorting. */\n descendants: RowEntry<R>[];\n}\n\nexport interface DisplayRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n type: 'leaf' | 'group';\n row: R | null;\n node: MGHGridLeafNode | MGHGridGroupNode;\n depth: number;\n group?: GroupTreeNode<R>;\n}\n\nexport const GROUP_ID_PREFIX = 'auto-generated-row-';\n\nconst keyToString = (key: any) => (isNil(key) ? '' : key instanceof Date ? String(key.getTime()) : String(key));\n\nexport const buildGroupTree = <R extends MGHGridValidRowModel>(\n entries: RowEntry<R>[],\n groupingFields: string[],\n columnsByField: Map<string, MGHGridColDef<R>>,\n api: MGHGridApi<R>,\n emptyLabel = '(empty)'\n): GroupTreeNode<R>[] => {\n const build = (items: RowEntry<R>[], depth: number, parentId: MGHGridRowId | null, path: string): GroupTreeNode<R>[] => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return [];\n const buckets = new Map<string, GroupTreeNode<R>>();\n items.forEach((entry) => {\n const key = getGroupingValue(entry.row, col, api);\n const keyStr = keyToString(key);\n let node = buckets.get(keyStr);\n if (!node) {\n const label = formattedValueToString(getFormattedValue(key, entry.row, col, api, entry.id)) || emptyLabel;\n const id = `${GROUP_ID_PREFIX}${path}${field}/${keyStr}`;\n node = {\n id,\n depth,\n parent: parentId,\n groupingField: field,\n groupingKey: key,\n groupingLabel: label,\n childGroups: [],\n leaves: [],\n descendants: [],\n };\n buckets.set(keyStr, node);\n }\n node.leaves.push(entry);\n });\n const nodes: GroupTreeNode<R>[] = [];\n buckets.forEach((node) => {\n if (depth < groupingFields.length - 1) {\n node.childGroups = build(\n node.leaves,\n depth + 1,\n node.id,\n `${path}${field}/${keyToString(node.groupingKey)}|`\n );\n node.descendants = node.leaves;\n node.leaves = [];\n } else {\n node.descendants = node.leaves;\n }\n nodes.push(node);\n });\n return nodes;\n };\n return build(entries, 0, null, '');\n};\n\nexport type GroupComparator<R extends MGHGridValidRowModel = any> = (a: GroupTreeNode<R>, b: GroupTreeNode<R>) => number;\n\n/** Sorts groups (with the given comparator) and leaves (with the given sorter), recursively. */\nexport const sortGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n compareGroups: ((depth: number) => GroupComparator<R> | null) | null,\n sortLeaves: (leaves: RowEntry<R>[]) => RowEntry<R>[]\n): GroupTreeNode<R>[] => {\n const sortLevel = (nodes: GroupTreeNode<R>[], depth: number): GroupTreeNode<R>[] => {\n const comparator = compareGroups ? compareGroups(depth) : null;\n const sorted = comparator\n ? nodes\n .map((node, index) => ({ node, index }))\n .sort((a, b) => comparator(a.node, b.node) || a.index - b.index)\n .map((item) => item.node)\n : nodes;\n sorted.forEach((node) => {\n if (node.childGroups.length > 0) {\n node.childGroups = sortLevel(node.childGroups, depth + 1);\n const descendants: RowEntry<R>[] = [];\n node.childGroups.forEach((child) => child.descendants.forEach((d) => descendants.push(d)));\n node.descendants = descendants;\n } else {\n node.leaves = sortLeaves(node.leaves);\n node.descendants = node.leaves;\n }\n });\n return sorted;\n };\n return sortLevel(roots, 0);\n};\n\nexport const collectTreeLeaves = <R extends MGHGridValidRowModel>(roots: GroupTreeNode<R>[]): RowEntry<R>[] => {\n const out: RowEntry<R>[] = [];\n roots.forEach((root) => root.descendants.forEach((d) => out.push(d)));\n return out;\n};\n\nexport const toGroupNode = <R extends MGHGridValidRowModel>(\n node: GroupTreeNode<R>,\n isExpanded: boolean\n): MGHGridGroupNode => ({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: node.childGroups.length > 0 ? node.childGroups.map((c) => c.id) : node.leaves.map((l) => l.id),\n leafIds: node.descendants.map((d) => d.id),\n isExpanded,\n});\n\n/** Flattens the tree into display rows, honouring expansion state. Also fills `nodesById` with every node. */\nexport const flattenGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n isExpanded: (node: GroupTreeNode<R>) => boolean,\n nodesById: Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>,\n groupsById: Map<MGHGridRowId, GroupTreeNode<R>>\n): DisplayRow<R>[] => {\n const out: DisplayRow<R>[] = [];\n const visit = (nodes: GroupTreeNode<R>[], visible: boolean) => {\n nodes.forEach((node) => {\n const expanded = isExpanded(node);\n const groupNode = toGroupNode(node, expanded);\n nodesById.set(node.id, groupNode);\n groupsById.set(node.id, node);\n if (visible)\n out.push({ id: node.id, type: 'group', row: null, node: groupNode, depth: node.depth, group: node });\n const childVisible = visible && expanded;\n if (node.childGroups.length > 0) {\n visit(node.childGroups, childVisible);\n } else {\n node.leaves.forEach((leaf) => {\n const leafNode: MGHGridLeafNode = { type: 'leaf', id: leaf.id, depth: node.depth + 1, parent: node.id };\n nodesById.set(leaf.id, leafNode);\n if (childVisible)\n out.push({ id: leaf.id, type: 'leaf', row: leaf.row, node: leafNode, depth: node.depth + 1 });\n });\n }\n });\n };\n visit(roots, true);\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const aggregateRows = <R extends MGHGridValidRowModel>(\n rows: R[],\n aggregationModel: MGHGridAggregationModel,\n columnsByField: Map<string, MGHGridColDef<R>>,\n functions: Record<string, MGHGridAggregationFunction>,\n api: MGHGridApi<R>\n): Record<string, { value: any; fn: string }> => {\n const result: Record<string, { value: any; fn: string }> = {};\n Object.keys(aggregationModel).forEach((field) => {\n const fnName = aggregationModel[field];\n const fn = functions[fnName];\n const col = columnsByField.get(field);\n if (!fn || !col || col.aggregable === false) return;\n const values = rows.map((row) => getCellValue(row, col, api));\n result[field] = { value: fn.apply({ values, field }), fn: fnName };\n });\n return result;\n};\n","import React from 'react';\n\n/* Small inline SVG icon set (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHGridIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHGridIconProps>(({ size = 20, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-grid-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const ViewColumnIcon = createIcon(\n <path d=\"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z\" />,\n 'ViewColumnIcon'\n);\nexport const FilterListIcon = createIcon(<path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\" />, 'FilterListIcon');\nexport const SearchIcon = createIcon(\n <path d=\"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" />,\n 'SearchIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\nexport const DownloadIcon = createIcon(\n <path d=\"M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67 2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2z\" />,\n 'DownloadIcon'\n);\nexport const ArrowUpwardIcon = createIcon(\n <path d=\"m4 12 1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />,\n 'ArrowUpwardIcon'\n);\nexport const ArrowDownwardIcon = createIcon(\n <path d=\"m20 12-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\" />,\n 'ArrowDownwardIcon'\n);\nexport const MoreVertIcon = createIcon(\n <path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'MoreVertIcon'\n);\nexport const CheckIcon = createIcon(<path d=\"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />, 'CheckIcon');\nexport const ExpandMoreIcon = createIcon(<path d=\"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z\" />, 'ExpandMoreIcon');\nexport const ChevronRightIcon = createIcon(<path d=\"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" />, 'ChevronRightIcon');\nexport const ChevronLeftIcon = createIcon(<path d=\"M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />, 'ChevronLeftIcon');\nexport const FirstPageIcon = createIcon(\n <path d=\"M18.41 16.59 13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z\" />,\n 'FirstPageIcon'\n);\nexport const LastPageIcon = createIcon(\n <path d=\"M5.59 7.41 10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z\" />,\n 'LastPageIcon'\n);\nexport const PushPinIcon = createIcon(\n <path d=\"M16 9V4h1c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1h1v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z\" />,\n 'PushPinIcon'\n);\nexport const DeleteIcon = createIcon(\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />,\n 'DeleteIcon'\n);\nexport const AddIcon = createIcon(<path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />, 'AddIcon');\nexport const DensitySmallIcon = createIcon(\n <path d=\"M3 2h18v2H3zm0 18h18v2H3zm0-6h18v2H3zm0-6h18v2H3z\" />,\n 'DensitySmallIcon'\n);\nexport const DensityMediumIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3zm0-8h18v2H3z\" />, 'DensityMediumIcon');\nexport const DensityLargeIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3z\" />, 'DensityLargeIcon');\nexport const DragIndicatorIcon = createIcon(\n <path d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'DragIndicatorIcon'\n);\nexport const PrintIcon = createIcon(\n <path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\" />,\n 'PrintIcon'\n);\nexport const TableChartIcon = createIcon(\n <path d=\"M10 10.02h5V21h-5zM17 21h3c1.1 0 2-.9 2-2v-9h-5v11zm3-18H5c-1.1 0-2 .9-2 2v3h19V5c0-1.1-.9-2-2-2zM3 19c0 1.1.9 2 2 2h3V10H3v9z\" />,\n 'TableChartIcon'\n);\nexport const DescriptionIcon = createIcon(\n <path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\" />,\n 'DescriptionIcon'\n);\nexport const VisibilityOffIcon = createIcon(\n <path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\" />,\n 'VisibilityOffIcon'\n);\nexport const FunctionsIcon = createIcon(<path d=\"M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z\" />, 'FunctionsIcon');\nexport const WorkspacesIcon = createIcon(\n <path d=\"M6 13c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-10C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 10c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z\" />,\n 'WorkspacesIcon'\n);\nexport const EmptyBoxIcon = createIcon(\n <>\n <path\n d=\"M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2z\"\n opacity=\".25\"\n />\n <path d=\"M4 8h16v11H4z\" opacity=\".15\" />\n </>,\n 'EmptyBoxIcon'\n);\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { clamp, cx } from '../utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Button / IconButton\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'text' | 'primary' | 'contained';\n size?: 'small' | 'medium';\n startIcon?: React.ReactNode;\n endIcon?: React.ReactNode;\n active?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { variant = 'text', size = 'medium', startIcon, endIcon, active, className, children, type = 'button', ...rest },\n ref\n ) => (\n <button\n ref={ref}\n type={type}\n className={cx(\n 'mgh-grid-btn',\n variant === 'primary' && 'mgh-grid-btn--primary',\n variant === 'contained' && 'mgh-grid-btn--contained',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {startIcon}\n {children}\n {endIcon}\n </button>\n )\n);\nButton.displayName = 'MGHGridButton';\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n size?: 'small' | 'medium';\n active?: boolean;\n /** Tooltip (native title) and aria-label. */\n label?: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ size = 'medium', active, label, className, children, type = 'button', ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n title={label}\n aria-label={label}\n className={cx(\n 'mgh-grid-btn mgh-grid-btn--icon',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n )\n);\nIconButton.displayName = 'MGHGridIconButton';\n\n/* -------------------------------------------------------------------------------------------------\n * Badge\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface BadgeProps {\n count?: number;\n variant?: 'dot' | 'count';\n children: React.ReactNode;\n}\n\nexport const Badge = ({ count = 0, variant = 'dot', children }: BadgeProps) => (\n <span className=\"mgh-grid-badge\">\n {children}\n {count > 0 &&\n (variant === 'dot' ? (\n <span className=\"mgh-grid-badge-dot\" />\n ) : (\n <span className=\"mgh-grid-badge-count\">{count > 99 ? '99+' : count}</span>\n ))}\n </span>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Inputs\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(\n ({ size = 'medium', className, ...rest }, ref) => (\n <input\n ref={ref}\n className={cx('mgh-grid-input', size === 'small' && 'mgh-grid-input--small', className)}\n {...rest}\n />\n )\n);\nTextInput.displayName = 'MGHGridTextInput';\n\nexport interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(({ size = 'medium', className, ...rest }, ref) => (\n <select ref={ref} className={cx('mgh-grid-select', size === 'small' && 'mgh-grid-select--small', className)} {...rest} />\n));\nSelect.displayName = 'MGHGridSelect';\n\nexport interface FieldProps {\n label?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n htmlFor?: string;\n}\n\nexport const Field = ({ label, children, className, htmlFor }: FieldProps) => (\n <div className={cx('mgh-grid-field', className)}>\n {label && (\n <label className=\"mgh-grid-field-label\" htmlFor={htmlFor}>\n {label}\n </label>\n )}\n {children}\n </div>\n);\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n indeterminate?: boolean;\n label?: string;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ indeterminate = false, label, className, ...rest }, forwardedRef) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const setRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [forwardedRef]\n );\n React.useEffect(() => {\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n return (\n <input\n ref={setRef}\n type=\"checkbox\"\n title={label}\n aria-label={label}\n className={cx('mgh-grid-checkbox', className)}\n {...rest}\n />\n );\n }\n);\nCheckbox.displayName = 'MGHGridCheckbox';\n\n/* -------------------------------------------------------------------------------------------------\n * Spinner\n * ----------------------------------------------------------------------------------------------- */\n\nexport const Spinner = ({ className }: { className?: string }) => (\n <div className={cx('mgh-grid-spinner', className)} role=\"progressbar\" aria-label=\"Loading\" />\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover (portal, anchored)\n * ----------------------------------------------------------------------------------------------- */\n\nexport type PopoverPlacement = 'bottom-start' | 'bottom-end' | 'bottom' | 'right-start';\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null | undefined;\n onClose: (reason: 'backdrop' | 'escape') => void;\n children: React.ReactNode;\n placement?: PopoverPlacement;\n themeMode?: MGHGridThemeMode;\n className?: string;\n style?: React.CSSProperties;\n offset?: number;\n role?: string;\n autoFocus?: boolean;\n /** Additional elements considered \"inside\" for outside-click detection. */\n ignoreOutsideClickOn?: Array<React.RefObject<HTMLElement | null>>;\n}\n\nexport function Popover({\n open,\n anchorEl,\n onClose,\n children,\n placement = 'bottom-start',\n themeMode = 'light',\n className,\n style,\n offset = 4,\n role = 'dialog',\n autoFocus = false,\n ignoreOutsideClickOn,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState<{ top: number; left: number; ready: boolean }>({\n top: 0,\n left: 0,\n ready: false,\n });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n if (placement === 'right-start') {\n top = a.top;\n left = a.right + offset;\n if (left + w > vw - 8) left = a.left - offset - w;\n } else {\n top = a.bottom + offset;\n if (top + h > vh - 8 && a.top - offset - h >= 8) top = a.top - offset - h;\n left =\n placement === 'bottom-end'\n ? a.right - w\n : placement === 'bottom'\n ? a.left + a.width / 2 - w / 2\n : a.left;\n }\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement, offset]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n if (ignoreOutsideClickOn?.some((r) => r.current?.contains(target))) return;\n // Clicks inside other popovers (nested menus) should not close this one.\n if ((target as HTMLElement).closest?.('.mgh-grid-popover')) return;\n onClose('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onClose, anchorEl, ignoreOutsideClickOn]);\n\n React.useEffect(() => {\n if (open && autoFocus && ref.current) {\n const focusable = ref.current.querySelector<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])'\n );\n (focusable ?? ref.current).focus();\n }\n }, [open, autoFocus]);\n\n if (!open || typeof document === 'undefined') return null;\n\n const stop = (event: React.SyntheticEvent) => event.stopPropagation();\n\n return createPortal(\n <div\n ref={ref}\n role={role}\n tabIndex={-1}\n className={cx('mgh-grid-popover', className)}\n data-mgh-theme={themeMode}\n style={{\n top: position.top,\n left: position.left,\n visibility: position.ready ? 'visible' : 'hidden',\n ...style,\n }}\n onClick={stop}\n onDoubleClick={stop}\n onMouseDown={stop}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onClose('escape');\n return;\n }\n event.stopPropagation();\n }}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {\n children: React.ReactNode;\n}\n\nexport const Menu = ({ children, className, onKeyDown, ...rest }: MenuProps) => {\n const ref = React.useRef<HTMLUListElement | null>(null);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {\n onKeyDown?.(event);\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' && event.key !== 'Home' && event.key !== 'End') return;\n const items = Array.from(\n ref.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])') ?? []\n );\n if (items.length === 0) return;\n event.preventDefault();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n let next = 0;\n if (event.key === 'ArrowDown') next = currentIndex < 0 ? 0 : (currentIndex + 1) % items.length;\n else if (event.key === 'ArrowUp')\n next = currentIndex < 0 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;\n else if (event.key === 'Home') next = 0;\n else next = items.length - 1;\n items[next].focus();\n };\n\n React.useEffect(() => {\n const first = ref.current?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])');\n first?.focus();\n }, []);\n\n return (\n <ul ref={ref} role=\"menu\" className={cx('mgh-grid-menu', className)} onKeyDown={handleKeyDown} {...rest}>\n {children}\n </ul>\n );\n};\n\nexport interface MenuItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {\n icon?: React.ReactNode;\n selected?: boolean;\n /** Injected by menus that should close after the click. */\n hideMenu?: () => void;\n}\n\nexport const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ icon, selected, disabled, className, children, onClick, hideMenu, ...rest }, ref) => (\n <li role=\"none\">\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n disabled={disabled}\n tabIndex={-1}\n className={cx(\n 'mgh-grid-menu-item',\n disabled && 'mgh-grid-menu-item--disabled',\n selected && 'mgh-grid-menu-item--selected',\n className\n )}\n onClick={(event) => {\n if (disabled) return;\n onClick?.(event);\n hideMenu?.();\n }}\n {...rest}\n >\n {icon}\n <span>{children}</span>\n </button>\n </li>\n )\n);\nMenuItem.displayName = 'MGHGridMenuItem';\n\nexport const MenuDivider = () => <li role=\"separator\" className=\"mgh-grid-menu-divider\" />;\n\nexport const MenuHeader = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-header\">\n {children}\n </li>\n);\n\nexport const MenuSection = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-section\">\n {children}\n </li>\n);\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport {\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridPrintExportOptions,\n MGHGridToolbarProps,\n} from '../MGHGrid.types';\nimport {\n CloseIcon,\n DensityLargeIcon,\n DensityMediumIcon,\n DensitySmallIcon,\n DescriptionIcon,\n DownloadIcon,\n FilterListIcon,\n PrintIcon,\n SearchIcon,\n TableChartIcon,\n ViewColumnIcon,\n} from '../icons';\nimport { cx } from '../utils';\nimport { Badge, IconButton, Menu, MenuItem, MenuItemProps, Popover, TextInput } from './primitives';\n\n/* -------------------------------------------------------------------------------------------------\n * Buttons\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridColumnsButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'columns';\n return (\n <IconButton\n label={localeText.toolbarColumns}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('columns', event.currentTarget))}\n >\n <ViewColumnIcon />\n </IconButton>\n );\n}\n\nexport function MGHGridFiltersButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'filters';\n return (\n <IconButton\n label={localeText.toolbarFilters}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('filters', event.currentTarget))}\n >\n <Badge count={state.filterCount} variant=\"dot\">\n <FilterListIcon />\n </Badge>\n </IconButton>\n );\n}\n\nexport function MGHGridDensitySelector() {\n const { api, state, localeText, themeMode } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const options = [\n { value: 'compact', label: localeText.densityCompact, icon: <DensitySmallIcon /> },\n { value: 'standard', label: localeText.densityStandard, icon: <DensityMediumIcon /> },\n { value: 'comfortable', label: localeText.densityComfortable, icon: <DensityLargeIcon /> },\n ] as const;\n const current = options.find((o) => o.value === state.density) ?? options[1];\n return (\n <>\n <IconButton\n label={localeText.toolbarDensity}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n {current.icon}\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n role=\"menu\"\n >\n <Menu>\n {options.map((option) => (\n <MenuItem\n key={option.value}\n icon={option.icon}\n selected={option.value === state.density}\n onClick={() => api.setDensity(option.value)}\n hideMenu={() => setAnchor(null)}\n >\n {option.label}\n </MenuItem>\n ))}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Export menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridExportMenuItemProps extends MenuItemProps {\n /** Injected by MGHGridExportMenu; call it to close the menu after your action. */\n hideMenu?: () => void;\n}\n\n/** Menu item for custom export actions. Drop-in for MUI's GridExportMenuItemProps pattern. */\nexport const MGHGridExportMenuItem = MenuItem as React.ForwardRefExoticComponent<\n MGHGridExportMenuItemProps & React.RefAttributes<HTMLButtonElement>\n>;\n\nexport interface MGHGridExportMenuProps {\n csvOptions?: MGHGridCsvExportOptions;\n excelOptions?: MGHGridExcelExportOptions;\n printOptions?: MGHGridPrintExportOptions;\n showCsvOption?: boolean;\n showExcelOption?: boolean;\n showPrintOption?: boolean;\n customMenuItem?: React.ReactNode;\n}\n\nexport function MGHGridExportMenu({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n customMenuItem,\n}: MGHGridExportMenuProps) {\n const { api, localeText, themeMode, rootProps } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const hideMenu = () => setAnchor(null);\n\n const customItems = React.Children.map(customMenuItem, (child) =>\n React.isValidElement(child) ? React.cloneElement(child as React.ReactElement<any>, { hideMenu }) : child\n );\n\n const resolvedPrintOptions: MGHGridPrintExportOptions = {\n title: typeof rootProps.header === 'string' ? rootProps.header : undefined,\n ...printOptions,\n };\n\n return (\n <>\n <IconButton\n label={localeText.toolbarExport}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n <DownloadIcon />\n </IconButton>\n <Popover open={Boolean(anchor)} anchorEl={anchor} onClose={hideMenu} themeMode={themeMode} role=\"menu\">\n <Menu>\n {customItems}\n {showCsvOption && (\n <MenuItem\n icon={<DescriptionIcon />}\n onClick={() => api.exportDataAsCsv(csvOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportCSV}\n </MenuItem>\n )}\n {showExcelOption && (\n <MenuItem\n icon={<TableChartIcon />}\n onClick={() => {\n void api.exportDataAsExcel(excelOptions);\n }}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportExcel}\n </MenuItem>\n )}\n {showPrintOption && (\n <MenuItem\n icon={<PrintIcon />}\n onClick={() => api.exportDataAsPrint(resolvedPrintOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportPrint}\n </MenuItem>\n )}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Quick filter\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridQuickFilterProps {\n placeholder?: string;\n debounceMs?: number;\n /** Always show the expanded input. */\n alwaysExpanded?: boolean;\n}\n\nexport function MGHGridQuickFilter({ placeholder, debounceMs, alwaysExpanded = false }: MGHGridQuickFilterProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const externalValue = (state.quickFilterValues ?? []).join(' ');\n const [text, setText] = React.useState(externalValue);\n const [expanded, setExpanded] = React.useState(alwaysExpanded || externalValue !== '');\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const timer = React.useRef<number | null>(null);\n const delay = debounceMs ?? rootProps.quickFilterDebounceMs;\n\n // Sync when the model is changed from outside (e.g. api.setQuickFilterValues).\n const lastExternal = React.useRef(externalValue);\n React.useEffect(() => {\n if (externalValue !== lastExternal.current) {\n lastExternal.current = externalValue;\n setText(externalValue);\n if (externalValue !== '') setExpanded(true);\n }\n }, [externalValue]);\n\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n\n const commit = (value: string) => {\n const values = value.split(/\\s+/).filter((v) => v !== '');\n lastExternal.current = values.join(' ');\n api.setQuickFilterValues(values);\n };\n\n const handleChange = (value: string) => {\n setText(value);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => commit(value), delay);\n };\n\n const clear = () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n setText('');\n commit('');\n inputRef.current?.focus();\n };\n\n const expand = () => {\n setExpanded(true);\n window.setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const isExpanded = alwaysExpanded || expanded;\n\n return (\n <div className={cx('mgh-grid-quick-filter', isExpanded && 'mgh-grid-quick-filter--expanded')}>\n <IconButton\n className=\"mgh-grid-quick-filter-trigger\"\n label={localeText.toolbarQuickFilterLabel}\n aria-disabled={isExpanded}\n tabIndex={isExpanded ? -1 : 0}\n onClick={expand}\n >\n <SearchIcon />\n </IconButton>\n <div\n className={cx(\n 'mgh-grid-quick-filter-control mgh-grid-input-adorned',\n text && 'mgh-grid-input-adorned--clearable'\n )}\n >\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n ref={inputRef}\n size=\"small\"\n type=\"search\"\n value={text}\n tabIndex={isExpanded ? 0 : -1}\n placeholder={placeholder ?? localeText.toolbarQuickFilterPlaceholder}\n aria-label={localeText.toolbarQuickFilterLabel}\n onChange={(event) => handleChange(event.target.value)}\n onBlur={() => {\n if (!alwaysExpanded && text.trim() === '') setExpanded(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n if (text) clear();\n else if (!alwaysExpanded) {\n setExpanded(false);\n inputRef.current?.blur();\n }\n }\n if (event.key === 'Enter') {\n if (timer.current !== null) window.clearTimeout(timer.current);\n commit(text);\n }\n }}\n />\n {text && (\n <span className=\"mgh-grid-input-adornment mgh-grid-input-adornment--end\">\n <IconButton size=\"small\" label={localeText.clearSearch} onClick={clear} tabIndex={-1}>\n <CloseIcon />\n </IconButton>\n </span>\n )}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Default toolbar\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n showDensitySelector = false,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n csvOptions,\n excelOptions,\n printOptions,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n quickFilterPlaceholder,\n quickFilterDebounceMs,\n}: MGHGridToolbarProps) {\n const { rootProps } = useMGHGridContext();\n const showColumns = showColumnsButton && !rootProps.disableColumnSelector;\n const showFilters = showFilterButton && !rootProps.disableColumnFilter;\n const showDensity = showDensitySelector && !rootProps.disableDensitySelector;\n\n return (\n <div className=\"mgh-grid-toolbar\" role=\"toolbar\">\n <div className=\"mgh-grid-toolbar-group\">\n {showColumns && <MGHGridColumnsButton />}\n {showFilters && <MGHGridFiltersButton />}\n {showDensity && <MGHGridDensitySelector />}\n {showExportButton && (\n <MGHGridExportMenu\n csvOptions={csvOptions}\n excelOptions={excelOptions}\n printOptions={printOptions}\n showCsvOption={showCsvOption}\n showExcelOption={showExcelOption}\n showPrintOption={showPrintOption}\n customMenuItem={customMenuItem}\n />\n )}\n </div>\n {renderDateRange && <div className=\"mgh-grid-toolbar-center\">{renderDateRange}</div>}\n <div className=\"mgh-grid-toolbar-group\">\n {renderOtherButtons}\n {showQuickFilter && (\n <MGHGridQuickFilter placeholder={quickFilterPlaceholder} debounceMs={quickFilterDebounceMs} />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { ChevronLeftIcon, ChevronRightIcon, FirstPageIcon, LastPageIcon } from '../icons';\nimport { IconButton, Select } from './primitives';\n\nexport function MGHGridPagination() {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const { page, pageSize } = state.paginationModel;\n const count = state.rowCount;\n const pageCount = state.pageCount;\n const from = count === 0 ? 0 : page * pageSize + 1;\n const to = Math.min(count, (page + 1) * pageSize);\n const options =\n rootProps.pageSizeOptions.indexOf(pageSize) === -1\n ? rootProps.pageSizeOptions.concat([pageSize]).sort((a, b) => a - b)\n : rootProps.pageSizeOptions;\n\n return (\n <div className=\"mgh-grid-pagination\" role=\"navigation\" aria-label=\"Pagination\">\n <span>{localeText.footerPaginationRowsPerPage}</span>\n <Select\n className=\"mgh-grid-pagination-select\"\n value={pageSize}\n aria-label={localeText.footerPaginationRowsPerPage}\n onChange={(event) => api.setPageSize(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </Select>\n <span>{localeText.footerPaginationDisplayedRows(from, to, count)}</span>\n <div className=\"mgh-grid-pagination-actions\">\n <IconButton label={localeText.footerPaginationFirstPage} disabled={page <= 0} onClick={() => api.setPage(0)}>\n <FirstPageIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationPreviousPage}\n disabled={page <= 0}\n onClick={() => api.setPage(page - 1)}\n >\n <ChevronLeftIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationNextPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(page + 1)}\n >\n <ChevronRightIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationLastPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(Math.max(pageCount - 1, 0))}\n >\n <LastPageIcon />\n </IconButton>\n </div>\n </div>\n );\n}\n\nexport function MGHGridFooter() {\n const { state, localeText, rootProps } = useMGHGridContext();\n const selectedCount = state.rowSelectionModel.ids.size;\n const showSelected = selectedCount > 0 && !rootProps.hideFooterSelectedRowCount;\n const showPagination = rootProps.pagination && !rootProps.hideFooterPagination;\n const showRowCount = !showPagination && !rootProps.hideFooterRowCount;\n\n return (\n <div className=\"mgh-grid-footer\">\n <div className=\"mgh-grid-footer-left\">\n {showSelected && <span>{localeText.footerRowSelected(selectedCount)}</span>}\n </div>\n {showRowCount && (\n <span>\n {localeText.footerTotalRows} {state.rowCount.toLocaleString()}\n </span>\n )}\n {showPagination && <MGHGridPagination />}\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { SearchIcon } from '../icons';\nimport { Button, Checkbox, TextInput } from './primitives';\n\nexport function MGHGridColumnsPanel() {\n const { api, state, localeText, columns, visibleColumns } = useMGHGridContext();\n const visibleFields = React.useMemo(() => new Set(visibleColumns.map((col) => col.field)), [visibleColumns]);\n const [search, setSearch] = React.useState('');\n const model = state.columnVisibilityModel;\n\n const hideable = columns.filter((col) => col.hideable !== false);\n const needle = search.trim().toLowerCase();\n const filtered = needle\n ? hideable.filter((col) => (col.headerName ?? col.field).toLowerCase().indexOf(needle) !== -1)\n : hideable;\n\n const setAll = (visible: boolean) => {\n const next = { ...model };\n hideable.forEach((col) => {\n next[col.field] = visible;\n });\n api.setColumnVisibilityModel(next);\n };\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarColumns}>\n <div className=\"mgh-grid-panel-header\">\n <div className=\"mgh-grid-input-adorned\">\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n autoFocus\n size=\"small\"\n value={search}\n placeholder={localeText.columnsPanelSearchPlaceholder}\n aria-label={localeText.columnsPanelSearchPlaceholder}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n </div>\n <div className=\"mgh-grid-panel-content\">\n <div className=\"mgh-grid-columns-list\">\n {filtered.map((col) => {\n const visible = visibleFields.has(col.field);\n return (\n <label key={col.field} className=\"mgh-grid-checkbox-label\">\n <Checkbox checked={visible} onChange={() => api.setColumnVisibility(col.field, !visible)} />\n <span>{col.headerName ?? col.field}</span>\n </label>\n );\n })}\n {filtered.length === 0 && <div className=\"mgh-grid-filter-empty\">No columns</div>}\n </div>\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(true)}>\n {localeText.columnsPanelShowAll}\n </Button>\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(false)}>\n {localeText.columnsPanelHideAll}\n </Button>\n <Button size=\"small\" onClick={() => api.setColumnVisibilityModel({})}>\n {localeText.columnsPanelReset}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridFilterItem, MGHGridFilterOperator } from '../MGHGrid.types';\nimport { AddIcon, DeleteIcon } from '../icons';\nimport { getColumnFilterOperators, getOptionLabel, getOptionValue, resolveValueOptions, uniqueId } from '../utils';\nimport { Button, Field, IconButton, Select, TextInput } from './primitives';\n\ninterface FilterValueInputProps {\n item: MGHGridFilterItem;\n column: MGHGridColDef;\n operator: MGHGridFilterOperator | undefined;\n onChange: (value: any) => void;\n placeholder: string;\n}\n\nconst useDebouncedValue = (value: any, onCommit: (value: any) => void, delay = 250) => {\n const [local, setLocal] = React.useState(value ?? '');\n const timer = React.useRef<number | null>(null);\n React.useEffect(() => {\n setLocal(value ?? '');\n }, [value]);\n const update = (next: any) => {\n setLocal(next);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => onCommit(next), delay);\n };\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n return [local, update] as const;\n};\n\nfunction TextValueInput({ item, onChange, placeholder, type }: FilterValueInputProps & { type: string }) {\n const [local, update] = useDebouncedValue(item.value, onChange);\n return (\n <TextInput\n size=\"small\"\n type={type}\n value={local}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction MultiValueInput({ item, column, onChange, placeholder }: FilterValueInputProps) {\n const joined = Array.isArray(item.value) ? item.value.join(', ') : (item.value ?? '');\n const [local, update] = useDebouncedValue(joined, (text: string) =>\n onChange(\n String(text)\n .split(',')\n .map((v) => v.trim())\n .filter((v) => v !== '')\n )\n );\n if (column.type === 'singleSelect') {\n const options = resolveValueOptions(column);\n const selected: string[] = Array.isArray(item.value) ? item.value.map(String) : [];\n return (\n <Select\n multiple\n size=\"small\"\n value={selected}\n aria-label={placeholder}\n onChange={(event) => {\n const values = Array.from(event.target.selectedOptions).map((option) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === option.value);\n return match !== undefined ? getOptionValue(column, match) : option.value;\n });\n onChange(values);\n }}\n >\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n return (\n <TextInput\n size=\"small\"\n value={local}\n placeholder=\"Comma separated values\"\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction FilterValueInput(props: FilterValueInputProps) {\n const { item, column, operator, onChange, placeholder } = props;\n const { api } = useMGHGridContext();\n const inputType = operator?.inputType ?? 'text';\n\n if (operator?.InputComponent) {\n const Component = operator.InputComponent;\n return <Component item={item} column={column} applyValue={(next) => onChange(next.value)} api={api} />;\n }\n\n switch (inputType) {\n case 'none':\n return <div />;\n case 'boolean':\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n >\n <option value=\"\">any</option>\n <option value=\"true\">yes</option>\n <option value=\"false\">no</option>\n </Select>\n );\n case 'select': {\n const options = resolveValueOptions(column);\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === event.target.value);\n onChange(\n event.target.value === ''\n ? undefined\n : match !== undefined\n ? getOptionValue(column, match)\n : event.target.value\n );\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'multiselect':\n return <MultiValueInput {...props} />;\n case 'number':\n return <TextValueInput {...props} type=\"number\" />;\n case 'date':\n return <TextValueInput {...props} type=\"date\" />;\n case 'datetime-local':\n return <TextValueInput {...props} type=\"datetime-local\" />;\n default:\n return <TextValueInput {...props} type=\"text\" />;\n }\n}\n\nconst createFilterItem = (column: MGHGridColDef | undefined): MGHGridFilterItem => ({\n id: uniqueId('filter'),\n field: column?.field ?? '',\n operator: column ? (getColumnFilterOperators(column)[0]?.value ?? 'contains') : 'contains',\n value: undefined,\n});\n\nexport function MGHGridFilterPanel() {\n const { api, state, localeText, columns, rootProps } = useMGHGridContext();\n const filterableColumns = React.useMemo(() => columns.filter((col) => col.filterable !== false), [columns]);\n const byField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n filterableColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [filterableColumns]);\n\n const items = state.filterModel.items;\n const logicOperator = state.filterModel.logicOperator ?? 'and';\n const targetField = state.preferencePanel.targetField;\n\n // Ensure at least one (possibly empty) item is displayed when the panel opens, like MUI does.\n const seeded = React.useRef(false);\n React.useEffect(() => {\n if (seeded.current) return;\n seeded.current = true;\n if (targetField && byField.has(targetField)) {\n const existing = items.find((item) => item.field === targetField);\n if (!existing) api.upsertFilterItem(createFilterItem(byField.get(targetField)));\n } else if (items.length === 0 && filterableColumns.length > 0) {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n }\n }, [api, byField, filterableColumns, items, targetField]);\n\n const updateItem = (item: MGHGridFilterItem, patch: Partial<MGHGridFilterItem>) => {\n api.upsertFilterItem({ ...item, ...patch });\n };\n\n const addItem = () => {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n };\n\n const canAddMore = !rootProps.disableMultipleColumnsFiltering || items.length === 0;\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarFilters}>\n <div className=\"mgh-grid-panel-content\" style={{ paddingTop: 12 }}>\n {items.length === 0 && <div className=\"mgh-grid-filter-empty\">No filters</div>}\n {items.map((item, index) => {\n const column = byField.get(item.field) ?? filterableColumns[0];\n const operators = column ? getColumnFilterOperators(column) : [];\n const operator = operators.find((op) => op.value === item.operator) ?? operators[0];\n const showLogic = items.length > 1;\n return (\n <div\n key={String(item.id ?? index)}\n className={\n showLogic ? 'mgh-grid-filter-row mgh-grid-filter-row--with-logic' : 'mgh-grid-filter-row'\n }\n >\n <IconButton\n size=\"small\"\n label={localeText.filterPanelDeleteIcon}\n onClick={() => api.deleteFilterItem(item)}\n >\n <DeleteIcon />\n </IconButton>\n {showLogic && (\n <Field label={index === 1 ? localeText.filterPanelLogicOperator : ' '}>\n {index === 0 ? (\n <div style={{ height: 32 }} />\n ) : (\n <Select\n size=\"small\"\n value={logicOperator}\n disabled={index > 1}\n aria-label={localeText.filterPanelLogicOperator}\n onChange={(event) =>\n api.setFilterLogicOperator(event.target.value as 'and' | 'or')\n }\n >\n <option value=\"and\">{localeText.filterPanelOperatorAnd}</option>\n <option value=\"or\">{localeText.filterPanelOperatorOr}</option>\n </Select>\n )}\n </Field>\n )}\n <Field label={localeText.filterPanelColumns}>\n <Select\n size=\"small\"\n value={column?.field ?? ''}\n aria-label={localeText.filterPanelColumns}\n onChange={(event) => {\n const nextColumn = byField.get(event.target.value);\n const nextOperators = nextColumn ? getColumnFilterOperators(nextColumn) : [];\n const keepOperator = nextOperators.some((op) => op.value === item.operator);\n updateItem(item, {\n field: event.target.value,\n operator: keepOperator ? item.operator : (nextOperators[0]?.value ?? 'contains'),\n value: undefined,\n });\n }}\n >\n {filterableColumns.map((col) => (\n <option key={col.field} value={col.field}>\n {col.headerName ?? col.field}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelOperator}>\n <Select\n size=\"small\"\n value={operator?.value ?? ''}\n aria-label={localeText.filterPanelOperator}\n onChange={(event) => {\n const nextOperator = operators.find((op) => op.value === event.target.value);\n const nextIsMulti = nextOperator?.inputType === 'multiselect';\n const currentIsMulti = operator?.inputType === 'multiselect';\n updateItem(item, {\n operator: event.target.value,\n value: nextIsMulti !== currentIsMulti ? undefined : item.value,\n });\n }}\n >\n {operators.map((op) => (\n <option key={op.value} value={op.value}>\n {op.label ?? op.value}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelValue}>\n {column ? (\n <FilterValueInput\n item={item}\n column={column}\n operator={operator}\n placeholder={localeText.filterPanelInputPlaceholder}\n onChange={(value) => updateItem(item, { value })}\n />\n ) : (\n <div />\n )}\n </Field>\n </div>\n );\n })}\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button\n variant=\"primary\"\n size=\"small\"\n startIcon={<AddIcon size={18} />}\n onClick={addItem}\n disabled={!canAddMore}\n >\n {localeText.filterPanelAddFilter}\n </Button>\n <Button\n size=\"small\"\n startIcon={<DeleteIcon size={18} />}\n disabled={items.length === 0}\n onClick={() => api.setFilterModel({ ...state.filterModel, items: [] })}\n >\n {localeText.filterPanelRemoveAll}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridThemeMode } from '../MGHGrid.types';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n FilterListIcon,\n FunctionsIcon,\n PushPinIcon,\n ViewColumnIcon,\n VisibilityOffIcon,\n WorkspacesIcon,\n} from '../icons';\nimport { GROUPING_COLUMN_FIELD } from '../utils';\nimport { Menu, MenuDivider, MenuItem, MenuSection, Popover, Select } from './primitives';\n\nexport interface MGHGridColumnMenuProps {\n column: MGHGridColDef;\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n themeMode: MGHGridThemeMode;\n /** Anchor for panels opened from the menu (usually the toolbar button or the header cell). */\n panelAnchorEl?: HTMLElement | null;\n}\n\nexport function MGHGridColumnMenu({ column, anchorEl, open, onClose, themeMode, panelAnchorEl }: MGHGridColumnMenuProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const field = column.field;\n const isGroupingColumn = field === GROUPING_COLUMN_FIELD;\n const sortItem = state.sortModel.find((item) => item.field === field);\n const pinned = api.isColumnPinned(field);\n const isGrouped = state.rowGroupingModel.indexOf(field) !== -1;\n const aggregation = state.aggregationModel[field];\n\n const canSort = column.sortable !== false && !rootProps.disableColumnSorting;\n const canFilter = column.filterable !== false && !rootProps.disableColumnFilter && !isGroupingColumn;\n const canHide = column.hideable !== false;\n const canPin = column.pinnable !== false && !rootProps.disableColumnPinning;\n const canGroup = column.groupable !== false && !rootProps.disableRowGrouping && !isGroupingColumn;\n const aggregationFunctions = Object.keys(rootProps.aggregationFunctions).filter((name) => {\n const fn = rootProps.aggregationFunctions[name];\n if (column.availableAggregationFunctions && column.availableAggregationFunctions.indexOf(name) === -1) return false;\n if (fn.columnTypes && column.type && fn.columnTypes.indexOf(column.type) === -1) return false;\n return true;\n });\n const canAggregate =\n column.aggregable !== false && !rootProps.disableAggregation && !isGroupingColumn && aggregationFunctions.length > 0;\n\n const anchorForPanel = panelAnchorEl ?? anchorEl;\n const name = column.headerName ?? column.field;\n\n return (\n <Popover open={open} anchorEl={anchorEl} onClose={onClose} themeMode={themeMode} placement=\"bottom-end\" role=\"menu\">\n <Menu aria-label={localeText.columnMenuLabel}>\n {canSort && (\n <>\n <MenuItem\n icon={<ArrowUpwardIcon />}\n selected={sortItem?.sort === 'asc'}\n onClick={() => api.sortColumn(field, 'asc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortAsc}\n </MenuItem>\n <MenuItem\n icon={<ArrowDownwardIcon />}\n selected={sortItem?.sort === 'desc'}\n onClick={() => api.sortColumn(field, 'desc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortDesc}\n </MenuItem>\n {sortItem && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.sortColumn(field, null)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnsort}\n </MenuItem>\n )}\n </>\n )}\n {canFilter && (\n <>\n {canSort && <MenuDivider />}\n <MenuItem\n icon={<FilterListIcon />}\n onClick={() => api.showFilterPanel(field, anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuFilter}\n </MenuItem>\n </>\n )}\n {(canHide || !rootProps.disableColumnSelector) && (\n <>\n {(canSort || canFilter) && <MenuDivider />}\n {canHide && (\n <MenuItem\n icon={<VisibilityOffIcon />}\n onClick={() => api.setColumnVisibility(field, false)}\n hideMenu={onClose}\n >\n {localeText.columnMenuHideColumn}\n </MenuItem>\n )}\n {!rootProps.disableColumnSelector && (\n <MenuItem\n icon={<ViewColumnIcon />}\n onClick={() => api.showPreferences('columns', anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuManageColumns}\n </MenuItem>\n )}\n </>\n )}\n {canPin && (\n <>\n <MenuDivider />\n {pinned !== 'left' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(30deg)' }} />}\n onClick={() => api.pinColumn(field, 'left')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinLeft}\n </MenuItem>\n )}\n {pinned !== 'right' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(-30deg)' }} />}\n onClick={() => api.pinColumn(field, 'right')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinRight}\n </MenuItem>\n )}\n {pinned && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.unpinColumn(field)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnpin}\n </MenuItem>\n )}\n </>\n )}\n {canGroup && (\n <>\n <MenuDivider />\n <MenuItem\n icon={<WorkspacesIcon />}\n onClick={() =>\n isGrouped ? api.removeRowGroupingCriteria(field) : api.addRowGroupingCriteria(field)\n }\n hideMenu={onClose}\n >\n {isGrouped ? localeText.columnMenuUngroup(name) : localeText.columnMenuGroup(name)}\n </MenuItem>\n </>\n )}\n {canAggregate && (\n <>\n <MenuDivider />\n <MenuSection>\n <label\n className=\"mgh-grid-field-label\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <FunctionsIcon size={16} /> {localeText.columnMenuAggregation}\n </label>\n <Select\n size=\"small\"\n value={aggregation ?? ''}\n aria-label={localeText.columnMenuAggregation}\n onChange={(event) => {\n const next = { ...state.aggregationModel };\n if (event.target.value === '') delete next[field];\n else next[field] = event.target.value;\n api.setAggregationModel(next);\n }}\n >\n <option value=\"\">{localeText.aggregationFunctionLabelNone}</option>\n {aggregationFunctions.map((fnName) => (\n <option key={fnName} value={fnName}>\n {rootProps.aggregationFunctions[fnName].label ?? fnName}\n </option>\n ))}\n </Select>\n </MenuSection>\n </>\n )}\n </Menu>\n </Popover>\n );\n}\n","import React from 'react';\nimport { MGHGridLoadingOverlayProps, MGHGridNoRowsOverlayProps } from '../MGHGrid.types';\nimport { EmptyBoxIcon } from '../icons';\nimport { Spinner } from './primitives';\n\n/** Default \"no rows\" overlay. Mirrors the legacy CustomNoRowsOverlay but has no MUI dependency. */\nexport function MGHGridNoRowsOverlay({ text = 'No rows', imageSrc }: MGHGridNoRowsOverlayProps) {\n return (\n <div className=\"mgh-grid-no-rows\" role=\"status\">\n {imageSrc ? <img alt=\"\" src={imageSrc} /> : <EmptyBoxIcon size={50} />}\n <div>{text}</div>\n </div>\n );\n}\n\nexport function MGHGridLoadingOverlay({ text }: MGHGridLoadingOverlayProps) {\n return (\n <>\n <Spinner />\n {text && <div>{text}</div>}\n </>\n );\n}\n","import React from 'react';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { MoreVertIcon } from '../icons';\nimport { IconButton, Menu, MenuItem, Popover } from './primitives';\n\nexport interface MGHGridActionsCellItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n icon?: React.ReactElement;\n label: string;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Render the action inside the \"more\" menu instead of inline. */\n showInMenu?: boolean;\n disabled?: boolean;\n}\n\n/** Drop-in replacement for MUI's GridActionsCellItem. Use it from `colDef.getActions`. */\nexport function MGHGridActionsCellItem({\n icon,\n label,\n onClick,\n showInMenu,\n disabled,\n className,\n ...rest\n}: MGHGridActionsCellItemProps) {\n return (\n <IconButton\n size=\"small\"\n label={label}\n disabled={disabled}\n className={className}\n onClick={(event) => {\n event.stopPropagation();\n onClick?.(event);\n }}\n {...rest}\n >\n {icon}\n </IconButton>\n );\n}\nMGHGridActionsCellItem.displayName = 'MGHGridActionsCellItem';\n\ninterface ActionsCellProps {\n actions: React.ReactElement[];\n themeMode: MGHGridThemeMode;\n moreLabel: string;\n}\n\nexport function ActionsCell({ actions, themeMode, moreLabel }: ActionsCellProps) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const inline: React.ReactElement[] = [];\n const inMenu: React.ReactElement[] = [];\n actions.forEach((action) => {\n if (!React.isValidElement(action)) return;\n if ((action.props as MGHGridActionsCellItemProps)?.showInMenu) inMenu.push(action);\n else inline.push(action);\n });\n\n return (\n <>\n {inline.map((action, index) => (\n <React.Fragment key={action.key ?? index}>{action}</React.Fragment>\n ))}\n {inMenu.length > 0 && (\n <>\n <IconButton\n size=\"small\"\n label={moreLabel}\n active={Boolean(anchor)}\n onClick={(event) => {\n event.stopPropagation();\n setAnchor((prev) => (prev ? null : event.currentTarget));\n }}\n >\n <MoreVertIcon />\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n placement=\"bottom-end\"\n role=\"menu\"\n >\n <Menu>\n {inMenu.map((action, index) => {\n const props = action.props as MGHGridActionsCellItemProps;\n return (\n <MenuItem\n key={action.key ?? index}\n icon={props.icon}\n disabled={props.disabled}\n onClick={(event) => {\n props.onClick?.(event);\n setAnchor(null);\n }}\n >\n {props.label}\n </MenuItem>\n );\n })}\n </Menu>\n </Popover>\n </>\n )}\n </>\n );\n}\n","import React from 'react';\nimport {\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridApplyFilterFn,\n MGHGridCallbackDetails,\n MGHGridCellParams,\n MGHGridColDef,\n MGHGridColumnVisibilityModel,\n MGHGridDensity,\n MGHGridFilterItem,\n MGHGridFilterModel,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridLocaleText,\n MGHGridPaginationModel,\n MGHGridPinnedColumns,\n MGHGridPinnedSide,\n MGHGridPreferencePanelState,\n MGHGridPrintExportOptions,\n MGHGridProps,\n MGHGridRowGroupingModel,\n MGHGridRowId,\n MGHGridRowNode,\n MGHGridRowParams,\n MGHGridRowSelectionModel,\n MGHGridSortDirection,\n MGHGridSortModel,\n MGHGridState,\n MGHGridSxProps,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport {\n AGGREGATION_FOOTER_ID,\n BUILT_IN_AGGREGATION_FUNCTIONS,\n CHECKBOX_COLUMN_DEF,\n CHECKBOX_FIELD,\n DEFAULT_COLUMN_MIN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_LOCALE_TEXT,\n DEFAULT_ROW_HEIGHT,\n DENSITY_FACTORS,\n DETAIL_PANEL_TOGGLE_COLUMN_DEF,\n DETAIL_PANEL_TOGGLE_FIELD,\n GROUPING_COLUMN_FIELD,\n GROUPING_COLUMN_WIDTH,\n clamp,\n cx,\n defaultFormatValue,\n formattedValueToString,\n getCellValue,\n getColumnFilterOperators,\n getDefaultComparator,\n getFormattedValue,\n getOptionLabel,\n getOptionValue,\n getRowIdFromRow,\n buildScopedCss,\n isInternalField,\n isNil,\n isSelectorKey,\n measureText,\n moveItem,\n normalizeColumn,\n normalizeSelectionModel,\n parseEditValue,\n readLocalStorage,\n resolveValueOptions,\n selectionModelsEqual,\n toDate,\n writeLocalStorage,\n} from './utils';\nimport { useMGHGridStyles } from './MGHGrid.styles';\nimport { MGHGridContext, MGHGridContextValue, MGHGridRootProps } from './context';\nimport { useControlledState, useElementSize, useForceUpdate, useLatestRef, useStableId } from './hooks';\nimport { exportDataAsCsv, exportDataAsExcel, getDataAsCsv } from './export';\nimport { printGridElement } from './print';\nimport {\n DisplayRow,\n GroupTreeNode,\n RowEntry,\n aggregateRows,\n buildGroupTree,\n collectTreeLeaves,\n flattenGroupTree,\n sortGroupTree,\n} from './grouping';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n CheckIcon,\n ChevronRightIcon,\n CloseIcon,\n ExpandMoreIcon,\n MoreVertIcon,\n} from './icons';\nimport { Checkbox, IconButton, Popover, Select, TextInput } from './components/primitives';\nimport { MGHGridToolbar } from './components/Toolbar';\nimport { MGHGridFooter } from './components/Footer';\nimport { MGHGridColumnsPanel } from './components/ColumnsPanel';\nimport { MGHGridFilterPanel } from './components/FilterPanel';\nimport { MGHGridColumnMenu } from './components/ColumnMenu';\nimport { MGHGridLoadingOverlay, MGHGridNoRowsOverlay } from './components/Overlays';\nimport { ActionsCell } from './components/ActionsCell';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants & helpers\n * ----------------------------------------------------------------------------------------------- */\n\nconst EMPTY_ARRAY: any[] = [];\nconst EMPTY_OBJECT: Record<string, any> = {};\nconst EMPTY_MAP = new Map<any, any>();\nconst DEFAULT_SORTING_ORDER: MGHGridSortDirection[] = ['asc', 'desc', null];\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\nconst DEFAULT_FILTER_MODEL: MGHGridFilterModel = { items: [], quickFilterExcludeHiddenColumns: false };\nconst OVERSCAN_ROWS = 6;\nconst DEFAULT_DETAIL_PANEL_HEIGHT = 500;\n\ninterface ColumnLayout {\n col: MGHGridColDef;\n width: number;\n pinned: MGHGridPinnedSide | null;\n /** Sticky offset (left or right) for pinned columns. */\n offset: number;\n /** X position from the start of the row. */\n x: number;\n isLastLeft: boolean;\n isFirstRight: boolean;\n}\n\ntype RenderRowKind = 'leaf' | 'group' | 'pinnedRow' | 'footer';\n\ninterface RenderRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n kind: RenderRowKind;\n row: R | null;\n node: MGHGridRowNode;\n depth: number;\n group?: GroupTreeNode<R>;\n aggregates?: Record<string, { value: any; fn: string }>;\n}\n\ninterface CellCoords {\n id: MGHGridRowId;\n field: string;\n}\n\n/** Keeps only the inline-applicable part of an sx-like object (nested selectors are compiled to CSS). */\nconst sanitizeStyle = (style: MGHGridSxProps | undefined): React.CSSProperties | undefined => {\n if (!style) return undefined;\n const out: Record<string, any> = {};\n Object.keys(style).forEach((key) => {\n if (isSelectorKey(key)) return;\n const value = (style as any)[key];\n if (typeof value !== 'string' && typeof value !== 'number') return;\n out[key] = value;\n });\n return out;\n};\n\nconst computeWidths = (cols: MGHGridColDef[], available: number, overrides: Record<string, number>) => {\n const result: Array<number | null> = cols.map((col) => {\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const override = overrides[col.field];\n if (override) return clamp(override, min, max);\n if (col.flex && col.flex > 0) return null;\n return clamp(col.width ?? 100, min, max);\n });\n const pool: number[] = [];\n let fixedTotal = 0;\n result.forEach((w, i) => {\n if (w === null) pool.push(i);\n else fixedTotal += w;\n });\n if (pool.length > 0) {\n let remainingSpace = Math.max(0, available - fixedTotal);\n let remainingFlex = pool.reduce((acc, i) => acc + (cols[i].flex as number), 0);\n let active = pool.slice();\n let changed = true;\n while (changed && active.length > 0) {\n changed = false;\n for (let k = 0; k < active.length; k += 1) {\n const i = active[k];\n const col = cols[i];\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const share = remainingFlex > 0 ? (remainingSpace * (col.flex as number)) / remainingFlex : 0;\n if (share < min || share > max) {\n const fixed = share < min ? min : max;\n result[i] = fixed;\n remainingSpace = Math.max(0, remainingSpace - fixed);\n remainingFlex -= col.flex as number;\n active = active.filter((idx) => idx !== i);\n changed = true;\n break;\n }\n }\n }\n active.forEach((i) => {\n const col = cols[i];\n result[i] =\n remainingFlex > 0\n ? Math.floor((remainingSpace * (col.flex as number)) / remainingFlex)\n : (col.minWidth ?? 50);\n });\n }\n return result as number[];\n};\n\nconst toDateInputValue = (value: any, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n return withTime ? `${base}T${pad(date.getHours())}:${pad(date.getMinutes())}` : base;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Component\n * ----------------------------------------------------------------------------------------------- */\n\nexport default function MGHGrid<R extends MGHGridValidRowModel = any>(props: MGHGridProps<R>) {\n const {\n rows,\n columns: columnsProp,\n getRowId,\n loading = false,\n header,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n disableCard = false,\n className,\n cardClassName,\n boxClassName,\n cardStyle,\n cardSx,\n boxStyle,\n boxSx,\n style,\n sx,\n themeMode = 'light',\n themeVars,\n showToolbar = true,\n toolbarProps,\n slots = EMPTY_OBJECT,\n slotProps = EMPTY_OBJECT,\n noRowsText = 'No data found within selected parameters.',\n localeText: localeTextProp,\n rowHeight: rowHeightProp = DEFAULT_ROW_HEIGHT,\n columnHeaderHeight = DEFAULT_HEADER_HEIGHT,\n getRowHeight,\n autoHeight = false,\n disableVirtualization = false,\n density: densityProp,\n onDensityChange,\n disableDensitySelector = false,\n pagination = true,\n pageSize = 25,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationModel: paginationModelProp,\n onPaginationModelChange,\n hideFooter = false,\n hideFooterPagination = false,\n hideFooterRowCount = false,\n hideFooterSelectedRowCount = false,\n sortModel: sortModelProp,\n onSortModelChange,\n sortingOrder = DEFAULT_SORTING_ORDER,\n disableMultipleColumnsSorting = false,\n disableColumnSorting = false,\n filterModel: filterModelProp,\n onFilterModelChange,\n disableColumnFilter = false,\n disableMultipleColumnsFiltering = false,\n quickFilterDebounceMs = 150,\n columnVisibilityModel: columnVisibilityModelProp,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n columnWidthStorageKey,\n pinnedColumnsStorageKey,\n onColumnOrderChange,\n onColumnWidthChange,\n disableColumnMenu = false,\n disableColumnSelector = false,\n disableColumnResize = false,\n disableColumnReorder = false,\n disableColumnPinning = false,\n pinnedColumns: pinnedColumnsProp,\n onPinnedColumnsChange,\n checkboxSelection = false,\n checkboxSelectionVisibleOnly = false,\n disableRowSelectionOnClick = true,\n disableMultipleRowSelection = false,\n rowSelectionModel: rowSelectionModelProp,\n onRowSelectionModelChange,\n isRowSelectable,\n keepNonExistentRowsSelected = true,\n getRowClassName,\n onRowClick,\n onRowDoubleClick,\n onCellClick,\n onCellDoubleClick,\n pinnedRows,\n getDetailPanelContent,\n getDetailPanelHeight,\n detailPanelExpandedRowIds: detailPanelExpandedRowIdsProp,\n onDetailPanelExpandedRowIdsChange,\n rowGroupingModel: rowGroupingModelProp,\n onRowGroupingModelChange,\n defaultGroupingExpansionDepth = 0,\n groupingColDef,\n disableRowGrouping = false,\n isGroupExpandedByDefault,\n aggregationModel: aggregationModelProp,\n onAggregationModelChange,\n aggregationFunctions: aggregationFunctionsProp,\n disableAggregation = false,\n aggregationPosition = 'both',\n processRowUpdate,\n onProcessRowUpdateError,\n onCellEditStop,\n isCellEditable,\n initialState,\n apiRef,\n onStateChange,\n } = props;\n\n useMGHGridStyles();\n\n const gridId = useStableId('mgh-grid');\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const cardRef = React.useRef<HTMLDivElement | null>(null);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const toolbarRef = React.useRef<HTMLDivElement | null>(null);\n const forceUpdate = useForceUpdate();\n\n const localeText = React.useMemo<MGHGridLocaleText>(\n () => ({ ...DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n\n /* ------------------------------------------------------------------ latest ref + api shell */\n\n const latest = React.useRef<any>({});\n const getDetails = React.useCallback((): MGHGridCallbackDetails => ({ api: latest.current.api }), []);\n\n const apiObject = React.useMemo<MGHGridApi<R>>(() => {\n const L = () => latest.current;\n const apiImpl: MGHGridApi<R> = {\n getRow: (id) => L().rowsById.get(id) ?? null,\n getRowModels: () => new Map(L().rowsById),\n getAllRowIds: () => L().rowEntries.map((e: RowEntry<R>) => e.id),\n getRowNode: (id) => L().nodesById.get(id) ?? null,\n getSortedRows: () => L().sortedLeaves.map((e: RowEntry<R>) => e.row),\n getSortedRowIds: () => L().sortedLeaves.map((e: RowEntry<R>) => e.id),\n getVisibleRows: () =>\n L()\n .pagedRows.filter((dr: DisplayRow<R>) => dr.type === 'leaf' && dr.row)\n .map((dr: DisplayRow<R>) => ({ id: dr.id, model: dr.row as R })),\n getRowIndexRelativeToVisibleRows: (id) => L().pagedRows.findIndex((dr: DisplayRow<R>) => dr.id === id),\n updateRows: (updates) => {\n updates.forEach((update) => {\n const id = getRowIdFromRow(update as R, L().getRowId);\n const existing = L().rowsById.get(id);\n if (existing) L().setRowOverride(id, { ...existing, ...update });\n });\n },\n\n getAllColumns: () => L().orderedUserColumns,\n getVisibleColumns: () => L().visibleUserColumns,\n getColumn: (field) => L().getColumn(field),\n getColumnIndex: (field, useVisibleColumns = true) =>\n (useVisibleColumns ? L().visibleUserColumns : L().orderedUserColumns).findIndex(\n (c: MGHGridColDef) => c.field === field\n ),\n getColumnVisibilityModel: () => L().columnVisibilityModel,\n setColumnVisibility: (field, isVisible) =>\n L().setColumnVisibilityModel({ ...L().columnVisibilityModel, [field]: isVisible }),\n setColumnVisibilityModel: (model) => L().setColumnVisibilityModel(model),\n setColumnWidth: (field, width) => L().setColumnWidth(field, width),\n setColumnIndex: (field, targetIndex) => L().setColumnIndex(field, targetIndex),\n autosizeColumns: (options) => L().autosizeColumns(options),\n pinColumn: (field, side) => L().pinColumn(field, side),\n unpinColumn: (field) => L().unpinColumn(field),\n isColumnPinned: (field) => L().isColumnPinned(field),\n getPinnedColumns: () => L().pinnedColumns,\n setPinnedColumns: (model) => L().setPinnedColumns(model),\n\n getSortModel: () => L().sortModel,\n setSortModel: (model) => L().setSortModel(model),\n sortColumn: (field, direction, allowMultipleSorting) => L().sortColumn(field, direction, allowMultipleSorting),\n\n getFilterModel: () => L().filterModel,\n setFilterModel: (model) => L().setFilterModel(model),\n upsertFilterItem: (item) => L().upsertFilterItems([item]),\n upsertFilterItems: (items) => L().upsertFilterItems(items),\n deleteFilterItem: (item) => L().deleteFilterItem(item),\n setFilterLogicOperator: (operator) => L().setFilterModel({ ...L().filterModel, logicOperator: operator }),\n setQuickFilterValues: (values) => L().setFilterModel({ ...L().filterModel, quickFilterValues: values }),\n showFilterPanel: (targetColumnField, anchorEl) => L().showPreferences('filters', anchorEl, targetColumnField),\n hideFilterPanel: () => L().hidePreferences(),\n showPreferences: (panel, anchorEl, targetField) => L().showPreferences(panel, anchorEl, targetField),\n hidePreferences: () => L().hidePreferences(),\n\n getSelectedRows: () => {\n const map = new Map<MGHGridRowId, R>();\n L().selectedIds.forEach((id: MGHGridRowId) => {\n const row = L().rowsById.get(id);\n if (row) map.set(id, row);\n });\n return map;\n },\n getRowSelectionModel: () => ({ type: 'include', ids: L().selectedIds }),\n setRowSelectionModel: (model) => {\n const normalized = normalizeSelectionModel(\n model,\n L().rowEntries.map((e: RowEntry<R>) => e.id)\n );\n L().setSelectedIds(normalized.ids);\n },\n selectRow: (id, isSelected = true, resetSelection = false) => L().selectRows([id], isSelected, resetSelection),\n selectRows: (ids, isSelected = true, resetSelection = false) => L().selectRows(ids, isSelected, resetSelection),\n isRowSelected: (id) => L().selectedIds.has(id),\n isRowSelectable: (id) => L().isRowSelectableFn(id, L().rowsById.get(id)),\n\n setPage: (nextPage) => L().setPaginationModel({ ...L().paginationModel, page: Math.max(0, nextPage) }),\n setPageSize: (nextPageSize) => L().setPaginationModel({ page: 0, pageSize: Math.max(1, nextPageSize) }),\n setPaginationModel: (model) => L().setPaginationModel(model),\n\n setDensity: (value) => L().setDensity(value),\n\n getDataAsCsv: (options) => getDataAsCsv(apiImpl, options),\n exportDataAsCsv: (options) => exportDataAsCsv(apiImpl, options),\n exportDataAsExcel: (options) => exportDataAsExcel(apiImpl, options),\n exportDataAsPrint: (options) => L().startPrint(options),\n\n toggleDetailPanel: (id) => L().toggleDetailPanel(id),\n setExpandedDetailPanels: (ids) => L().setExpandedDetailPanels(new Set(ids)),\n getExpandedDetailPanels: () => Array.from(L().expandedDetailPanels as Set<MGHGridRowId>),\n\n getRowGroupingModel: () => L().rowGroupingModel,\n setRowGroupingModel: (model) => L().setRowGroupingModel(model),\n addRowGroupingCriteria: (field, groupingIndex) => {\n const current: string[] = L().rowGroupingModel.filter((f: string) => f !== field);\n if (groupingIndex === undefined) current.push(field);\n else current.splice(clamp(groupingIndex, 0, current.length), 0, field);\n L().setRowGroupingModel(current);\n },\n removeRowGroupingCriteria: (field) =>\n L().setRowGroupingModel(L().rowGroupingModel.filter((f: string) => f !== field)),\n setRowChildrenExpansion: (id, isExpanded) => L().setRowChildrenExpansion(id, isExpanded),\n getRowGroupChildren: ({ groupId }) => {\n const group = L().groupsById.get(groupId) as GroupTreeNode<R> | undefined;\n return group ? group.descendants.map((d) => d.id) : [];\n },\n\n getAggregationModel: () => L().aggregationModel,\n setAggregationModel: (model) => L().setAggregationModel(model),\n\n startCellEditMode: ({ id, field }) => L().startCellEditMode(id, field),\n stopCellEditMode: ({ id, field, ignoreModifications }) =>\n L().stopCellEditMode(id, field, ignoreModifications, 'api'),\n getCellMode: (id, field) => {\n const editing = L().editingCell as CellCoords | null;\n return editing && editing.id === id && editing.field === field ? 'edit' : 'view';\n },\n setEditCellValue: ({ id, field, value }) => {\n const editing = L().editingCell as CellCoords | null;\n if (editing && editing.id === id && editing.field === field) L().setEditValue(value);\n },\n\n getCellValue: (id, field) => {\n const row = L().rowsById.get(id);\n const col = L().getColumn(field);\n return row && col ? getCellValue(row, col, apiImpl) : undefined;\n },\n getCellParams: (id, field) => {\n const row = L().rowsById.get(id);\n return L().buildCellParams(\n id,\n field,\n row,\n L().nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null }\n );\n },\n setCellFocus: (id, field) => {\n pendingFocusRef.current = true;\n L().setFocusedCell({ id, field });\n },\n\n scrollToIndexes: (params) => L().scrollToIndexes(params),\n scroll: ({ left, top }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n if (left !== undefined) scroller.scrollLeft = left;\n if (top !== undefined) scroller.scrollTop = top;\n },\n getScrollPosition: () => ({\n left: scrollerRef.current?.scrollLeft ?? 0,\n top: scrollerRef.current?.scrollTop ?? 0,\n }),\n\n get state() {\n return L().state as MGHGridState;\n },\n forceUpdate: () => L().forceUpdate(),\n rootElementRef: rootRef,\n };\n return apiImpl;\n }, []);\n if (!latest.current.api) latest.current.api = apiObject;\n\n /* ------------------------------------------------------------------ persisted state */\n\n const persisted = React.useMemo(\n () => ({\n visibility: columnVisibilityStorageKey\n ? readLocalStorage<MGHGridColumnVisibilityModel>(columnVisibilityStorageKey)\n : null,\n order: columnOrderStorageKey ? readLocalStorage<string[]>(columnOrderStorageKey) : null,\n widths: columnWidthStorageKey ? readLocalStorage<Record<string, number>>(columnWidthStorageKey) : null,\n pinned: pinnedColumnsStorageKey ? readLocalStorage<MGHGridPinnedColumns>(pinnedColumnsStorageKey) : null,\n }),\n [columnVisibilityStorageKey, columnOrderStorageKey, columnWidthStorageKey, pinnedColumnsStorageKey]\n );\n\n /* ------------------------------------------------------------------ models */\n\n const [sortModel, setSortModel] = useControlledState<MGHGridSortModel>(\n sortModelProp,\n initialState?.sorting?.sortModel ?? EMPTY_ARRAY,\n (model) => onSortModelChange?.(model, getDetails())\n );\n\n const [filterModel, setFilterModel] = useControlledState<MGHGridFilterModel>(\n filterModelProp,\n initialState?.filter?.filterModel ?? DEFAULT_FILTER_MODEL,\n (model) => onFilterModelChange?.(model, getDetails())\n );\n\n const [paginationModel, setPaginationModel] = useControlledState<MGHGridPaginationModel>(\n paginationModelProp,\n {\n page: initialState?.pagination?.paginationModel?.page ?? 0,\n pageSize: initialState?.pagination?.paginationModel?.pageSize ?? pageSize,\n },\n (model) => onPaginationModelChange?.(model, getDetails())\n );\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useControlledState<MGHGridColumnVisibilityModel>(\n columnVisibilityModelProp,\n persisted.visibility ?? initialState?.columns?.columnVisibilityModel ?? EMPTY_OBJECT,\n (model) => {\n if (columnVisibilityStorageKey) writeLocalStorage(columnVisibilityStorageKey, model);\n onColumnVisibilityModelChange?.(model, getDetails());\n }\n );\n\n const [density, setDensity] = useControlledState<MGHGridDensity>(\n densityProp,\n initialState?.density ?? 'compact',\n (value) => onDensityChange?.(value, getDetails())\n );\n\n const [pinnedColumns, setPinnedColumns] = useControlledState<MGHGridPinnedColumns>(\n pinnedColumnsProp,\n persisted.pinned ?? initialState?.pinnedColumns ?? EMPTY_OBJECT,\n (model) => {\n if (pinnedColumnsStorageKey) writeLocalStorage(pinnedColumnsStorageKey, model);\n onPinnedColumnsChange?.(model, getDetails());\n }\n );\n\n const [rowGroupingModel, setRowGroupingModel] = useControlledState<MGHGridRowGroupingModel>(\n rowGroupingModelProp,\n initialState?.rowGrouping?.model ?? EMPTY_ARRAY,\n (model) => onRowGroupingModelChange?.(model, getDetails())\n );\n\n const [aggregationModel, setAggregationModel] = useControlledState<MGHGridAggregationModel>(\n aggregationModelProp,\n initialState?.aggregation?.model ?? EMPTY_OBJECT,\n (model) => onAggregationModelChange?.(model, getDetails())\n );\n\n const controlledExpandedDetail = React.useMemo(\n () => (detailPanelExpandedRowIdsProp ? new Set<MGHGridRowId>(detailPanelExpandedRowIdsProp) : undefined),\n [detailPanelExpandedRowIdsProp]\n );\n const [expandedDetailPanels, setExpandedDetailPanels] = useControlledState<Set<MGHGridRowId>>(\n controlledExpandedDetail,\n React.useMemo(() => new Set<MGHGridRowId>(initialState?.detailPanel?.expandedRowIds ?? []), []),\n (ids) => onDetailPanelExpandedRowIdsChange?.(Array.from(ids), getDetails())\n );\n\n const controlledSelection = React.useMemo(\n () => (rowSelectionModelProp !== undefined ? normalizeSelectionModel(rowSelectionModelProp).ids : undefined),\n [rowSelectionModelProp]\n );\n const [selectedIds, setSelectedIds] = useControlledState<Set<MGHGridRowId>>(\n controlledSelection,\n React.useMemo(() => new Set<MGHGridRowId>(), []),\n (ids) => onRowSelectionModelChange?.({ type: 'include', ids }, getDetails())\n );\n\n /* ------------------------------------------------------------------ internal state */\n\n const [orderedFields, setOrderedFields] = React.useState<string[] | null>(\n () => persisted.order ?? initialState?.columns?.orderedFields ?? null\n );\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>(() => {\n if (persisted.widths) return persisted.widths;\n const dims = initialState?.columns?.dimensions;\n if (!dims) return {};\n const out: Record<string, number> = {};\n Object.keys(dims).forEach((field) => {\n if (dims[field].width) out[field] = dims[field].width as number;\n });\n return out;\n });\n const [groupExpansion, setGroupExpansion] = React.useState<Map<MGHGridRowId, boolean>>(() => new Map());\n const [editingCell, setEditingCell] = React.useState<CellCoords | null>(null);\n const [editValue, setEditValue] = React.useState<any>(undefined);\n const [focusedCell, setFocusedCell] = React.useState<CellCoords | null>(null);\n const pendingFocusRef = React.useRef(false);\n const [preferencePanel, setPreferencePanel] = React.useState<\n MGHGridPreferencePanelState & { anchorEl: HTMLElement | null }\n >({\n open: false,\n anchorEl: null,\n });\n const [columnMenu, setColumnMenu] = React.useState<{ field: string; anchorEl: HTMLElement } | null>(null);\n const [resizingField, setResizingField] = React.useState<string | null>(null);\n // While set, the grid renders every row (no pagination / virtualization) so the DOM can be printed.\n const [printState, setPrintState] = React.useState<MGHGridPrintExportOptions | null>(null);\n const printing = printState !== null;\n const [drag, setDrag] = React.useState<{ field: string; overField: string | null; side: 'left' | 'right' } | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const scrollRaf = React.useRef(0);\n const lastClickedIdRef = React.useRef<MGHGridRowId | null>(null);\n\n // Row updates (editing / api.updateRows) are kept until the `rows` prop identity changes.\n const [overrideState, setOverrideState] = React.useState<{ rows: R[]; map: Map<MGHGridRowId, R> }>(() => ({\n rows,\n map: new Map(),\n }));\n const rowOverrides: Map<MGHGridRowId, R> = overrideState.rows === rows ? overrideState.map : EMPTY_MAP;\n const setRowOverride = React.useCallback(\n (id: MGHGridRowId, row: R) => {\n setOverrideState((prev) => {\n const map = new Map(prev.rows === rows ? prev.map : []);\n map.set(id, row);\n return { rows, map };\n });\n },\n [rows]\n );\n\n /* ------------------------------------------------------------------ sizes */\n\n const { width: viewportWidth, height: viewportHeight } = useElementSize(scrollerRef);\n const densityFactor = DENSITY_FACTORS[density] ?? 1;\n const rowHeight = Math.round(rowHeightProp * densityFactor);\n const headerHeight = Math.round(columnHeaderHeight * densityFactor);\n\n /* ------------------------------------------------------------------ rows */\n\n const rowEntries = React.useMemo<RowEntry<R>[]>(() => {\n const out: RowEntry<R>[] = [];\n rows.forEach((raw) => {\n const id = getRowIdFromRow(raw, getRowId);\n if (id === undefined || id === null) return;\n out.push({ id, row: rowOverrides.get(id) ?? raw });\n });\n return out;\n }, [rows, getRowId, rowOverrides]);\n\n const rowsById = React.useMemo(() => {\n const map = new Map<MGHGridRowId, R>();\n rowEntries.forEach((entry) => map.set(entry.id, entry.row));\n (pinnedRows?.top ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n (pinnedRows?.bottom ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n return map;\n }, [rowEntries, pinnedRows, getRowId]);\n\n /* ------------------------------------------------------------------ columns */\n\n const userColumns = React.useMemo(() => columnsProp.map((col) => normalizeColumn(col)), [columnsProp]);\n\n const columnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef<R>>();\n userColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [userColumns]);\n\n const groupingFields = React.useMemo(\n () => (disableRowGrouping ? [] : rowGroupingModel.filter((field) => columnsByField.has(field))),\n [rowGroupingModel, columnsByField, disableRowGrouping]\n );\n const groupingActive = groupingFields.length > 0;\n\n const groupingColumn = React.useMemo<MGHGridColDef<R> | null>(() => {\n if (!groupingActive) return null;\n const single = groupingFields.length === 1 ? columnsByField.get(groupingFields[0]) : undefined;\n return normalizeColumn<R>({\n field: GROUPING_COLUMN_FIELD,\n headerName: single ? (single.headerName ?? single.field) : localeText.groupingColumnHeaderName,\n width: GROUPING_COLUMN_WIDTH,\n minWidth: 120,\n sortable: true,\n filterable: false,\n hideable: false,\n groupable: false,\n aggregable: false,\n editable: false,\n disableExport: true,\n disableReorder: true,\n ...(groupingColDef as any),\n });\n }, [groupingActive, groupingFields, columnsByField, localeText.groupingColumnHeaderName, groupingColDef]);\n\n const orderedUserColumns = React.useMemo(() => {\n if (!orderedFields || orderedFields.length === 0) return userColumns;\n const seen = new Set<string>();\n const out: MGHGridColDef<R>[] = [];\n orderedFields.forEach((field) => {\n const col = columnsByField.get(field);\n if (col && !seen.has(field)) {\n seen.add(field);\n out.push(col);\n }\n });\n userColumns.forEach((col) => {\n if (!seen.has(col.field)) out.push(col);\n });\n return out;\n }, [orderedFields, userColumns, columnsByField]);\n\n const isColumnVisible = React.useCallback(\n (field: string) => {\n const value = columnVisibilityModel[field];\n if (value === false) return false;\n if (value === undefined && groupingFields.indexOf(field) !== -1) return false;\n return true;\n },\n [columnVisibilityModel, groupingFields]\n );\n\n const visibleUserColumns = React.useMemo(() => {\n if (printState) {\n let cols = orderedUserColumns.filter((col) => isColumnVisible(col.field));\n if (printState.fields) {\n const wanted = new Set(printState.fields);\n cols = orderedUserColumns.filter((col) => wanted.has(col.field));\n } else if (printState.allColumns) {\n cols = orderedUserColumns;\n }\n return cols.filter((col) => !col.disableExport);\n }\n return orderedUserColumns.filter((col) => isColumnVisible(col.field));\n }, [orderedUserColumns, isColumnVisible, printState]);\n\n const layout = React.useMemo(() => {\n const internal: MGHGridColDef[] = [];\n if (checkboxSelection) internal.push(CHECKBOX_COLUMN_DEF);\n if (getDetailPanelContent) internal.push(DETAIL_PANEL_TOGGLE_COLUMN_DEF);\n const leftFields = disableColumnPinning ? [] : (pinnedColumns.left ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const rightFields = disableColumnPinning\n ? []\n : (pinnedColumns.right ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const visibleByField = new Map<string, MGHGridColDef>();\n visibleUserColumns.forEach((col) => visibleByField.set(col.field, col));\n const left: MGHGridColDef[] = internal.slice();\n if (groupingColumn) left.push(groupingColumn);\n leftFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col) left.push(col);\n });\n const right: MGHGridColDef[] = [];\n rightFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col && leftFields.indexOf(f) === -1) right.push(col);\n });\n const center = visibleUserColumns.filter(\n (col) => leftFields.indexOf(col.field) === -1 && rightFields.indexOf(col.field) === -1\n );\n const ordered = left.concat(center, right);\n const widths = computeWidths(ordered, viewportWidth, columnWidths);\n const hasPinning = left.length > internal.length + (groupingColumn ? 1 : 0) || right.length > 0;\n const columns: ColumnLayout[] = [];\n let x = 0;\n let leftOffset = 0;\n ordered.forEach((col, i) => {\n const width = widths[i];\n const isLeft = i < left.length;\n const isRight = i >= left.length + center.length;\n columns.push({\n col,\n width,\n pinned: isLeft ? 'left' : isRight ? 'right' : null,\n offset: isLeft ? leftOffset : 0,\n x,\n isLastLeft: isLeft && i === left.length - 1,\n isFirstRight: isRight && i === left.length + center.length,\n });\n if (isLeft) leftOffset += width;\n x += width;\n });\n let rightOffset = 0;\n for (let i = columns.length - 1; i >= 0; i -= 1) {\n if (columns[i].pinned !== 'right') break;\n columns[i].offset = rightOffset;\n rightOffset += columns[i].width;\n }\n return { columns, totalWidth: x, hasPinning, leftCount: left.length, rightCount: right.length };\n }, [\n checkboxSelection,\n getDetailPanelContent,\n pinnedColumns,\n disableColumnPinning,\n visibleUserColumns,\n groupingColumn,\n viewportWidth,\n columnWidths,\n ]);\n\n const allDisplayColumnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n layout.columns.forEach((c) => map.set(c.col.field, c.col));\n if (groupingColumn) map.set(GROUPING_COLUMN_FIELD, groupingColumn);\n return map;\n }, [layout.columns, groupingColumn]);\n\n const getColumn = React.useCallback(\n (field: string): MGHGridColDef<R> | undefined =>\n columnsByField.get(field) ?? (allDisplayColumnsByField.get(field) as any),\n [columnsByField, allDisplayColumnsByField]\n );\n\n /* ------------------------------------------------------------------ filtering */\n\n const activeFilters = React.useMemo(() => {\n const out: Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }> = [];\n filterModel.items.forEach((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.filterable === false) return;\n const operator = getColumnFilterOperators(col).find((op) => op.value === item.operator);\n if (!operator) return;\n const fn = operator.getApplyFilterFn(item, col);\n if (fn) out.push({ col, fn });\n });\n return out;\n }, [filterModel.items, columnsByField]);\n\n const quickFilterValues = React.useMemo(\n () => (filterModel.quickFilterValues ?? []).map((v) => String(v).trim()).filter((v) => v !== ''),\n [filterModel.quickFilterValues]\n );\n\n const quickFilterColumns = React.useMemo(() => {\n const base = filterModel.quickFilterExcludeHiddenColumns ? visibleUserColumns : orderedUserColumns;\n return base.filter((col) => col.filterable !== false && col.type !== 'actions');\n }, [filterModel.quickFilterExcludeHiddenColumns, visibleUserColumns, orderedUserColumns]);\n\n const filteredEntries = React.useMemo(() => {\n if (activeFilters.length === 0 && quickFilterValues.length === 0) return rowEntries;\n const logicAnd = (filterModel.logicOperator ?? 'and') === 'and';\n const quickAnd = (filterModel.quickFilterLogicOperator ?? 'and') === 'and';\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const quickFns = quickFilterValues.map((needle) => {\n const lowered = needle.toLowerCase();\n const perColumn = quickFilterColumns.map((col) => {\n if (col.getApplyQuickFilterFn) {\n const custom = col.getApplyQuickFilterFn(needle, col, apiRefLocal);\n return custom ? { col, fn: custom } : null;\n }\n const fn: MGHGridApplyFilterFn<R> = (value, row) => {\n if (isNil(value)) return false;\n const formatted = formattedValueToString(getFormattedValue(value, row, col, apiRefLocal)).toLowerCase();\n if (formatted.indexOf(lowered) !== -1) return true;\n const raw = typeof value === 'object' ? '' : String(value).toLowerCase();\n return raw.indexOf(lowered) !== -1;\n };\n return { col, fn };\n });\n const active = perColumn.filter(Boolean) as Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }>;\n return (row: R) => active.some(({ col, fn }) => fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal));\n });\n return rowEntries.filter(({ row }) => {\n if (activeFilters.length > 0) {\n const results = activeFilters.map(({ col, fn }) =>\n fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal)\n );\n const pass = logicAnd ? results.every(Boolean) : results.some(Boolean);\n if (!pass) return false;\n }\n if (quickFns.length > 0) {\n const results = quickFns.map((fn) => fn(row));\n return quickAnd ? results.every(Boolean) : results.some(Boolean);\n }\n return true;\n });\n }, [\n rowEntries,\n activeFilters,\n quickFilterValues,\n quickFilterColumns,\n filterModel.logicOperator,\n filterModel.quickFilterLogicOperator,\n ]);\n\n /* ------------------------------------------------------------------ sorting */\n\n const compareEntries = React.useMemo(() => {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sorters = sortModel\n .filter((item) => item.sort && item.field !== GROUPING_COLUMN_FIELD)\n .map((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.sortable === false) return null;\n return {\n col,\n dir: item.sort === 'desc' ? -1 : 1,\n comparator: col.sortComparator ?? getDefaultComparator(col.type),\n };\n })\n .filter(Boolean) as Array<{ col: MGHGridColDef<R>; dir: number; comparator: any }>;\n if (sorters.length === 0) return null;\n return (a: RowEntry<R>, b: RowEntry<R>) => {\n for (let i = 0; i < sorters.length; i += 1) {\n const { col, dir, comparator } = sorters[i];\n const v1 = getCellValue(a.row, col, apiRefLocal);\n const v2 = getCellValue(b.row, col, apiRefLocal);\n const result = comparator(\n v1,\n v2,\n { id: a.id, field: col.field, value: v1, row: a.row, api: apiRefLocal },\n { id: b.id, field: col.field, value: v2, row: b.row, api: apiRefLocal }\n );\n if (result !== 0) return result * dir;\n }\n return 0;\n };\n }, [sortModel, columnsByField]);\n\n const sortEntries = React.useCallback(\n (entries: RowEntry<R>[]) => {\n if (!compareEntries) return entries;\n return entries\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => compareEntries(a.entry, b.entry) || a.index - b.index)\n .map((item) => item.entry);\n },\n [compareEntries]\n );\n\n /* ------------------------------------------------------------------ grouping + display rows */\n\n const aggregationFunctions = React.useMemo(\n () => ({ ...BUILT_IN_AGGREGATION_FUNCTIONS, ...aggregationFunctionsProp }),\n [aggregationFunctionsProp]\n );\n const aggregationActive = !disableAggregation && Object.keys(aggregationModel).length > 0;\n\n const isGroupExpanded = React.useCallback(\n (node: GroupTreeNode<R>) => {\n const override = groupExpansion.get(node.id);\n if (override !== undefined) return override;\n if (isGroupExpandedByDefault) {\n return isGroupExpandedByDefault({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: [],\n leafIds: [],\n isExpanded: false,\n });\n }\n return defaultGroupingExpansionDepth === -1 || node.depth < defaultGroupingExpansionDepth;\n },\n [groupExpansion, isGroupExpandedByDefault, defaultGroupingExpansionDepth]\n );\n\n const processed = React.useMemo(() => {\n const nodesById = new Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>();\n const groupsById = new Map<MGHGridRowId, GroupTreeNode<R>>();\n if (!groupingActive) {\n const sorted = sortEntries(filteredEntries);\n const displayRows: DisplayRow<R>[] = sorted.map((entry) => {\n const node: MGHGridLeafNode = { type: 'leaf', id: entry.id, depth: 0, parent: null };\n nodesById.set(entry.id, node);\n return { id: entry.id, type: 'leaf', row: entry.row, node, depth: 0 };\n });\n return { displayRows, sortedLeaves: sorted, nodesById, groupsById, tree: [] as GroupTreeNode<R>[] };\n }\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n let tree = buildGroupTree(filteredEntries, groupingFields, columnsByField, apiRefLocal);\n const groupingSort = sortModel.find((item) => item.field === GROUPING_COLUMN_FIELD && item.sort);\n const compareGroups = (depth: number) => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return null;\n const sortItem = groupingSort ?? sortModel.find((item) => item.field === field && item.sort);\n if (!sortItem) return null;\n const comparator = col.sortComparator ?? getDefaultComparator(col.type);\n const dir = sortItem.sort === 'desc' ? -1 : 1;\n return (a: GroupTreeNode<R>, b: GroupTreeNode<R>) =>\n comparator(\n a.groupingKey,\n b.groupingKey,\n { id: a.id, field, value: a.groupingKey, row: a.descendants[0]?.row, api: apiRefLocal },\n { id: b.id, field, value: b.groupingKey, row: b.descendants[0]?.row, api: apiRefLocal }\n ) * dir;\n };\n tree = sortGroupTree(tree, compareGroups, sortEntries);\n const displayRows = flattenGroupTree(tree, isGroupExpanded, nodesById, groupsById);\n return { displayRows, sortedLeaves: collectTreeLeaves(tree), nodesById, groupsById, tree };\n }, [groupingActive, filteredEntries, sortEntries, groupingFields, columnsByField, sortModel, isGroupExpanded]);\n\n const { displayRows, sortedLeaves, nodesById, groupsById } = processed;\n\n /* ------------------------------------------------------------------ pagination */\n\n const totalDisplayRows = displayRows.length;\n const paginate = pagination && !printing;\n const pageCount = pagination ? Math.max(1, Math.ceil(totalDisplayRows / Math.max(paginationModel.pageSize, 1))) : 1;\n const page = pagination ? clamp(paginationModel.page, 0, pageCount - 1) : 0;\n\n React.useEffect(() => {\n if (pagination && paginationModel.page !== page) {\n setPaginationModel({ ...paginationModel, page });\n }\n }, [pagination, paginationModel, page, setPaginationModel]);\n\n const pagedRows = React.useMemo(\n () =>\n paginate\n ? displayRows.slice(page * paginationModel.pageSize, (page + 1) * paginationModel.pageSize)\n : displayRows,\n [displayRows, paginate, page, paginationModel.pageSize]\n );\n\n /* ------------------------------------------------------------------ aggregation values */\n\n const footerAggregates = React.useMemo(() => {\n if (!aggregationActive || aggregationPosition === 'inline') return null;\n const rowsForFooter = sortedLeaves.map((entry) => entry.row);\n return aggregateRows(rowsForFooter, aggregationModel, columnsByField, aggregationFunctions, latest.current.api);\n }, [aggregationActive, aggregationPosition, sortedLeaves, aggregationModel, columnsByField, aggregationFunctions]);\n\n const groupAggregatesCache = React.useMemo(\n () => new Map<MGHGridRowId, Record<string, { value: any; fn: string }>>(),\n [pagedRows, aggregationModel, aggregationFunctions]\n );\n const getGroupAggregates = (group: GroupTreeNode<R>) => {\n if (!aggregationActive || aggregationPosition === 'footer') return undefined;\n let cached = groupAggregatesCache.get(group.id);\n if (!cached) {\n cached = aggregateRows(\n group.descendants.map((d) => d.row),\n aggregationModel,\n columnsByField,\n aggregationFunctions,\n latest.current.api\n );\n groupAggregatesCache.set(group.id, cached);\n }\n return cached;\n };\n\n /* ------------------------------------------------------------------ row heights + virtualization */\n\n const heights = React.useMemo(() => {\n const rowHeights: number[] = [];\n const detailHeights: number[] = [];\n const offsets: number[] = [];\n let total = 0;\n let hasAuto = autoHeight || disableVirtualization || printing;\n pagedRows.forEach((dr) => {\n let h = rowHeight;\n if (getRowHeight && dr.type === 'leaf' && dr.row) {\n const result = getRowHeight({ id: dr.id, model: dr.row, densityFactor });\n if (result === 'auto') hasAuto = true;\n else if (typeof result === 'number' && result > 0) h = result;\n }\n let d = 0;\n if (dr.type === 'leaf' && getDetailPanelContent && expandedDetailPanels.has(dr.id) && dr.row) {\n const dh = getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row })\n : DEFAULT_DETAIL_PANEL_HEIGHT;\n if (dh === 'auto') hasAuto = true;\n else d = dh;\n }\n rowHeights.push(h);\n detailHeights.push(d);\n offsets.push(total);\n total += h + d;\n });\n return { rowHeights, detailHeights, offsets, total, hasAuto };\n }, [\n pagedRows,\n rowHeight,\n getRowHeight,\n densityFactor,\n getDetailPanelContent,\n getDetailPanelHeight,\n expandedDetailPanels,\n autoHeight,\n disableVirtualization,\n printing,\n ]);\n\n const virtual = !heights.hasAuto;\n\n /* ------------------------------------------------------------------ print */\n\n const startPrint = (options: MGHGridPrintExportOptions = {}) => {\n if (printState) return;\n const resolved: MGHGridPrintExportOptions = {\n title: typeof header === 'string' ? header : undefined,\n ...options,\n };\n if (!cardRef.current || typeof window === 'undefined') return;\n setPrintState(resolved);\n };\n\n React.useEffect(() => {\n if (!printState) return undefined;\n // The un-virtualized rows are already committed when this effect runs; a short timeout lets the\n // browser lay them out first. (A timeout rather than rAF so it also fires in hidden/background tabs.)\n const timer = window.setTimeout(() => {\n if (!cardRef.current) return;\n printGridElement({\n cardElement: cardRef.current,\n options: printState,\n onDone: () => setPrintState(null),\n });\n }, 50);\n return () => window.clearTimeout(timer);\n }, [printState]);\n\n const virtualRange = React.useMemo(() => {\n const count = pagedRows.length;\n if (!virtual || count === 0) return { start: 0, end: count };\n const overscan = OVERSCAN_ROWS * rowHeight;\n const viewTop = Math.max(0, scrollTop - headerHeight - overscan);\n const viewBottom = scrollTop + Math.max(viewportHeight, rowHeight) + overscan;\n const { offsets } = heights;\n let lo = 0;\n let hi = count - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] + heights.rowHeights[mid] + heights.detailHeights[mid] < viewTop) lo = mid + 1;\n else hi = mid;\n }\n const start = lo;\n let end = start;\n while (end < count && offsets[end] < viewBottom) end += 1;\n return { start, end };\n }, [virtual, pagedRows.length, scrollTop, viewportHeight, rowHeight, headerHeight, heights]);\n\n const handleScroll = React.useCallback(() => {\n if (!latest.current.virtual) return;\n if (scrollRaf.current) return;\n scrollRaf.current = window.requestAnimationFrame(() => {\n scrollRaf.current = 0;\n if (scrollerRef.current) setScrollTop(scrollerRef.current.scrollTop);\n });\n }, []);\n\n React.useEffect(\n () => () => {\n if (scrollRaf.current) window.cancelAnimationFrame(scrollRaf.current);\n },\n []\n );\n\n /* ------------------------------------------------------------------ selection */\n\n const isRowSelectableFn = React.useCallback(\n (id: MGHGridRowId, row: R | null | undefined) => {\n if (!row) return false;\n if (!isRowSelectable) return true;\n return isRowSelectable({ id, row, columns: orderedUserColumns, api: latest.current.api });\n },\n [isRowSelectable, orderedUserColumns]\n );\n\n const selectionCandidates = React.useMemo(() => {\n const source: RowEntry<R>[] = checkboxSelectionVisibleOnly\n ? (pagedRows\n .filter((dr) => dr.type === 'leaf' && dr.row)\n .map((dr) => ({ id: dr.id, row: dr.row as R })) as RowEntry<R>[])\n : sortedLeaves;\n return source.filter((entry) => isRowSelectableFn(entry.id, entry.row)).map((entry) => entry.id);\n }, [checkboxSelectionVisibleOnly, pagedRows, sortedLeaves, isRowSelectableFn]);\n\n const selectedCandidateCount = React.useMemo(\n () => selectionCandidates.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0),\n [selectionCandidates, selectedIds]\n );\n const allCandidatesSelected = selectionCandidates.length > 0 && selectedCandidateCount === selectionCandidates.length;\n const someCandidatesSelected = selectedCandidateCount > 0 && !allCandidatesSelected;\n\n const updateSelection = React.useCallback(\n (updater: (prev: Set<MGHGridRowId>) => Set<MGHGridRowId>) => {\n setSelectedIds((prev) => {\n const next = updater(prev);\n return selectionModelsEqual({ type: 'include', ids: prev }, { type: 'include', ids: next }) ? prev : next;\n });\n },\n [setSelectedIds]\n );\n\n const selectRows = React.useCallback(\n (ids: MGHGridRowId[], isSelected = true, resetSelection = false) => {\n updateSelection((prev) => {\n const next = resetSelection ? new Set<MGHGridRowId>() : new Set(prev);\n ids.forEach((id) => {\n if (isSelected) {\n if (isRowSelectableFn(id, rowsById.get(id))) next.add(id);\n } else next.delete(id);\n });\n if (disableMultipleRowSelection && next.size > 1) {\n const lastId = ids[ids.length - 1];\n return new Set<MGHGridRowId>(isSelected && next.has(lastId) ? [lastId] : []);\n }\n return next;\n });\n },\n [updateSelection, isRowSelectableFn, rowsById, disableMultipleRowSelection]\n );\n\n React.useEffect(() => {\n if (keepNonExistentRowsSelected || selectedIds.size === 0) return;\n let changed = false;\n const next = new Set<MGHGridRowId>();\n selectedIds.forEach((id) => {\n if (rowsById.has(id)) next.add(id);\n else changed = true;\n });\n if (changed) setSelectedIds(next);\n }, [rowsById, keepNonExistentRowsSelected, selectedIds, setSelectedIds]);\n\n const toggleAllCandidates = () => {\n if (allCandidatesSelected) selectRows(selectionCandidates, false);\n else selectRows(selectionCandidates, true);\n };\n\n const handleRowSelectionClick = (renderRow: RenderRow<R>, event: React.MouseEvent) => {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const allSelected = leafIds.every((id) => selectedIds.has(id));\n selectRows(leafIds, !allSelected, false);\n return;\n }\n if (renderRow.kind !== 'leaf') return;\n const id = renderRow.id;\n if (!isRowSelectableFn(id, renderRow.row)) return;\n const multiple = !disableMultipleRowSelection;\n if (event.shiftKey && multiple && lastClickedIdRef.current !== null) {\n const ids = pagedRows.filter((dr) => dr.type === 'leaf').map((dr) => dr.id);\n const from = ids.indexOf(lastClickedIdRef.current);\n const to = ids.indexOf(id);\n if (from !== -1 && to !== -1) {\n const [a, b] = from < to ? [from, to] : [to, from];\n selectRows(ids.slice(a, b + 1), true, !checkboxSelection && !event.ctrlKey && !event.metaKey);\n return;\n }\n }\n lastClickedIdRef.current = id;\n const isSelected = selectedIds.has(id);\n const resetSelection = !checkboxSelection && !event.ctrlKey && !event.metaKey;\n if (resetSelection) {\n if (isSelected && selectedIds.size === 1) selectRows([id], false, true);\n else selectRows([id], true, true);\n } else {\n selectRows([id], !isSelected, false);\n }\n };\n\n /* ------------------------------------------------------------------ sorting helpers */\n\n const sortColumn = (field: string, direction?: MGHGridSortDirection, allowMultiple = false) => {\n const col = getColumn(field);\n if (!col || col.sortable === false || disableColumnSorting) return;\n const current = sortModel.find((item) => item.field === field);\n let next: MGHGridSortDirection;\n if (direction === undefined) {\n const order = col.sortingOrder ?? sortingOrder;\n const index = order.indexOf(current?.sort ?? null);\n next = order[(index + 1) % order.length];\n } else {\n next = direction;\n }\n let model: MGHGridSortModel;\n if (allowMultiple && !disableMultipleColumnsSorting) {\n model = sortModel.filter((item) => item.field !== field);\n if (next)\n model = current\n ? sortModel.map((item) => (item.field === field ? { field, sort: next } : item))\n : model.concat([{ field, sort: next }]);\n } else {\n model = next ? [{ field, sort: next }] : [];\n }\n setSortModel(model);\n };\n\n /* ------------------------------------------------------------------ column helpers */\n\n const persistOrder = (fields: string[]) => {\n if (columnOrderStorageKey) writeLocalStorage(columnOrderStorageKey, fields);\n };\n\n const persistWidths = (widths: Record<string, number>) => {\n if (columnWidthStorageKey) writeLocalStorage(columnWidthStorageKey, widths);\n };\n\n const setColumnIndex = (field: string, targetIndex: number, event: React.DragEvent | null = null) => {\n const fields = orderedUserColumns.map((c) => c.field);\n const oldIndex = fields.indexOf(field);\n if (oldIndex === -1) return;\n const next = moveItem(fields, oldIndex, clamp(targetIndex, 0, fields.length - 1));\n setOrderedFields(next);\n persistOrder(next);\n const col = columnsByField.get(field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex, oldIndex }, event, getDetails());\n };\n\n const setColumnWidth = (field: string, width: number) => {\n const col = getColumn(field);\n if (!col) return;\n const clamped = clamp(width, col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n setColumnWidths((prev) => {\n const next = { ...prev, [field]: clamped };\n persistWidths(next);\n return next;\n });\n onColumnWidthChange?.({ colDef: col, width: clamped }, getDetails());\n };\n\n const autosizeColumns = (options: { columns?: string[]; includeHeaders?: boolean; expand?: boolean } = {}) => {\n const includeHeaders = options.includeHeaders ?? true;\n const targets = layout.columns.filter(\n (lc) => !isInternalField(lc.col.field) && (!options.columns || options.columns.indexOf(lc.col.field) !== -1)\n );\n if (targets.length === 0) return;\n const root = rootRef.current;\n const computed = root && typeof window !== 'undefined' ? window.getComputedStyle(root) : null;\n const fontFamily = computed?.fontFamily || 'sans-serif';\n const cellFont = `400 14px ${fontFamily}`;\n const headerFont = `600 14px ${fontFamily}`;\n const sample = sortedLeaves.slice(0, 500);\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const next = { ...columnWidths };\n targets.forEach(({ col }) => {\n let max = includeHeaders ? measureText(col.headerName ?? col.field, headerFont) + 64 : 0;\n sample.forEach((entry) => {\n const value = getCellValue(entry.row, col, apiRefLocal);\n const text = formattedValueToString(getFormattedValue(value, entry.row, col, apiRefLocal, entry.id));\n const w = measureText(text, cellFont) + 24;\n if (w > max) max = w;\n });\n next[col.field] = clamp(Math.ceil(max), col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n });\n setColumnWidths(next);\n persistWidths(next);\n };\n\n const pinColumn = (field: string, side: MGHGridPinnedSide) => {\n if (disableColumnPinning) return;\n const left = (pinnedColumns.left ?? []).filter((f) => f !== field);\n const right = (pinnedColumns.right ?? []).filter((f) => f !== field);\n if (side === 'left') left.push(field);\n else right.unshift(field);\n setPinnedColumns({ left, right });\n };\n\n const unpinColumn = (field: string) => {\n setPinnedColumns({\n left: (pinnedColumns.left ?? []).filter((f) => f !== field),\n right: (pinnedColumns.right ?? []).filter((f) => f !== field),\n });\n };\n\n const isColumnPinned = (field: string): MGHGridPinnedSide | false => {\n if (disableColumnPinning) return false;\n if ((pinnedColumns.left ?? []).indexOf(field) !== -1) return 'left';\n if ((pinnedColumns.right ?? []).indexOf(field) !== -1) return 'right';\n return false;\n };\n\n /* ------------------------------------------------------------------ filter helpers */\n\n const upsertFilterItems = (items: MGHGridFilterItem[]) => {\n let nextItems = filterModel.items.slice();\n items.forEach((item) => {\n const withId =\n item.id === undefined ? { ...item, id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}` } : item;\n const index = nextItems.findIndex((existing) => existing.id !== undefined && existing.id === withId.id);\n if (index === -1) nextItems.push(withId);\n else nextItems[index] = withId;\n });\n if (disableMultipleColumnsFiltering && nextItems.length > 1) nextItems = nextItems.slice(-1);\n setFilterModel({ ...filterModel, items: nextItems });\n };\n\n const deleteFilterItem = (item: MGHGridFilterItem) => {\n setFilterModel({\n ...filterModel,\n items: filterModel.items.filter((existing) =>\n item.id !== undefined ? existing.id !== item.id : existing !== item\n ),\n });\n };\n\n const showPreferences = (panel: 'columns' | 'filters', anchorEl?: HTMLElement | null, targetField?: string) => {\n setColumnMenu(null);\n setPreferencePanel({\n open: true,\n openedPanelValue: panel,\n targetField,\n anchorEl: anchorEl ?? toolbarRef.current ?? rootRef.current,\n });\n };\n\n const hidePreferences = React.useCallback(() => {\n setPreferencePanel((prev) => (prev.open ? { open: false, anchorEl: null } : prev));\n }, []);\n\n /* ------------------------------------------------------------------ editing */\n\n const isCellEditableFn = (params: MGHGridCellParams<R>) => {\n if (!params.colDef.editable) return false;\n if (params.rowNode.type !== 'leaf') return false;\n return isCellEditable ? isCellEditable(params) : true;\n };\n\n const startCellEditMode = (id: MGHGridRowId, field: string) => {\n const row = rowsById.get(id);\n const col = getColumn(field);\n if (!row || !col) return;\n const params = buildCellParams(id, field, row, nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null });\n if (!isCellEditableFn(params)) return;\n setEditingCell({ id, field });\n setEditValue(params.value);\n setFocusedCell({ id, field });\n };\n\n const applyRowUpdate = (id: MGHGridRowId, newRow: R, oldRow: R) => {\n if (processRowUpdate) {\n Promise.resolve()\n .then(() => processRowUpdate(newRow, oldRow, { rowId: id }))\n .then((result) => setRowOverride(id, (result ?? newRow) as R))\n .catch((error) => {\n if (onProcessRowUpdateError) onProcessRowUpdateError(error);\n else console.error('MGHGrid: processRowUpdate failed', error);\n });\n } else {\n setRowOverride(id, newRow);\n }\n };\n\n const stopCellEditMode = (\n id: MGHGridRowId,\n field: string,\n ignoreModifications = false,\n reason: 'enterKeyDown' | 'escapeKeyDown' | 'cellFocusOut' | 'tabKeyDown' | 'api' = 'api'\n ) => {\n if (!editingCell || editingCell.id !== id || editingCell.field !== field) return;\n const row = rowsById.get(id);\n const col = getColumn(field);\n setEditingCell(null);\n if (!row || !col) return;\n if (!ignoreModifications) {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const parsed = col.valueParser\n ? col.valueParser(editValue, row, col, apiRefLocal)\n : parseEditValue(editValue, col);\n const currentValue = getCellValue(row, col, apiRefLocal);\n if (!Object.is(parsed, currentValue)) {\n const newRow = col.valueSetter\n ? col.valueSetter(parsed, row, col, apiRefLocal)\n : ({ ...row, [field]: parsed } as R);\n applyRowUpdate(id, newRow, row);\n }\n }\n onCellEditStop?.({ id, field, row, reason }, getDetails());\n pendingFocusRef.current = true;\n setFocusedCell({ id, field });\n };\n\n /* ------------------------------------------------------------------ detail panel & grouping helpers */\n\n const toggleDetailPanel = (id: MGHGridRowId) => {\n setExpandedDetailPanels((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const setRowChildrenExpansion = (id: MGHGridRowId, isExpanded: boolean) => {\n setGroupExpansion((prev) => {\n const next = new Map(prev);\n next.set(id, isExpanded);\n return next;\n });\n };\n\n const groupingKey = groupingFields.join('|');\n const previousGroupingKey = React.useRef(groupingKey);\n React.useEffect(() => {\n if (previousGroupingKey.current === groupingKey) return;\n previousGroupingKey.current = groupingKey;\n setGroupExpansion(new Map());\n }, [groupingKey]);\n\n /* ------------------------------------------------------------------ cell params */\n\n const buildCellParams = (id: MGHGridRowId, field: string, row: R, node: MGHGridRowNode): MGHGridCellParams<R> => {\n const col = getColumn(field) as MGHGridColDef<R>;\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const value = getCellValue(row, col, apiRefLocal);\n const formattedValue = getFormattedValue(value, row, col, apiRefLocal, id);\n const hasFocus = Boolean(focusedCell && focusedCell.id === id && focusedCell.field === field);\n const cellMode = editingCell && editingCell.id === id && editingCell.field === field ? 'edit' : 'view';\n return {\n id,\n field,\n value,\n formattedValue,\n row,\n rowNode: node,\n colDef: col,\n api: apiRefLocal,\n hasFocus,\n tabIndex: hasFocus ? 0 : -1,\n cellMode,\n isEditable: Boolean(col.editable) && node.type === 'leaf',\n };\n };\n\n const buildRowParams = (id: MGHGridRowId, row: R): MGHGridRowParams<R> => ({\n id,\n row,\n columns: orderedUserColumns,\n api: latest.current.api,\n });\n\n /* ------------------------------------------------------------------ keyboard navigation */\n\n React.useEffect(() => {\n if (!pendingFocusRef.current || !focusedCell || !rootRef.current) return;\n pendingFocusRef.current = false;\n const selector = `[data-mgh-row-id=\"${String(focusedCell.id).replace(/\"/g, '\\\\\"')}\"] [data-mgh-field=\"${focusedCell.field.replace(/\"/g, '\\\\\"')}\"]`;\n const el = rootRef.current.querySelector<HTMLElement>(selector);\n if (el && document.activeElement !== el && !el.contains(document.activeElement)) el.focus({ preventScroll: true });\n }, [focusedCell, virtualRange.start, virtualRange.end]);\n\n const scrollToIndexes = (params: { rowIndex?: number; colIndex?: number }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return false;\n if (params.rowIndex !== undefined && virtual) {\n const index = clamp(params.rowIndex, 0, Math.max(pagedRows.length - 1, 0));\n const top = heights.offsets[index] ?? 0;\n const bottom = top + (heights.rowHeights[index] ?? rowHeight);\n const visibleTop = scroller.scrollTop;\n const visibleBottom = scroller.scrollTop + scroller.clientHeight - headerHeight;\n if (top < visibleTop) scroller.scrollTop = top;\n else if (bottom > visibleBottom) scroller.scrollTop = bottom - (scroller.clientHeight - headerHeight);\n } else if (params.rowIndex !== undefined) {\n const el = scroller.querySelector(`[data-mgh-row-index=\"${params.rowIndex}\"]`) as HTMLElement | null | undefined;\n el?.scrollIntoView?.({ block: 'nearest' });\n }\n if (params.colIndex !== undefined) {\n const lc = layout.columns[clamp(params.colIndex, 0, layout.columns.length - 1)];\n if (lc && !lc.pinned) {\n const leftPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'left')\n .reduce((acc, c) => acc + c.width, 0);\n const rightPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'right')\n .reduce((acc, c) => acc + c.width, 0);\n const visibleLeft = scroller.scrollLeft + leftPinnedWidth;\n const visibleRight = scroller.scrollLeft + scroller.clientWidth - rightPinnedWidth;\n if (lc.x < visibleLeft) scroller.scrollLeft = lc.x - leftPinnedWidth;\n else if (lc.x + lc.width > visibleRight)\n scroller.scrollLeft = lc.x + lc.width - scroller.clientWidth + rightPinnedWidth;\n }\n }\n return true;\n };\n\n const moveFocus = (\n rowDelta: number,\n colDelta: number,\n absolute?: { row?: 'first' | 'last'; col?: 'first' | 'last' }\n ) => {\n if (pagedRows.length === 0 || layout.columns.length === 0) return;\n let rowIndex = focusedCell ? pagedRows.findIndex((dr) => dr.id === focusedCell.id) : -1;\n let colIndex = focusedCell ? layout.columns.findIndex((lc) => lc.col.field === focusedCell.field) : -1;\n if (rowIndex === -1) rowIndex = 0;\n if (colIndex === -1) colIndex = 0;\n if (absolute?.row === 'first') rowIndex = 0;\n else if (absolute?.row === 'last') rowIndex = pagedRows.length - 1;\n else rowIndex = clamp(rowIndex + rowDelta, 0, pagedRows.length - 1);\n if (absolute?.col === 'first') colIndex = 0;\n else if (absolute?.col === 'last') colIndex = layout.columns.length - 1;\n else colIndex = clamp(colIndex + colDelta, 0, layout.columns.length - 1);\n const target = { id: pagedRows[rowIndex].id, field: layout.columns[colIndex].col.field };\n pendingFocusRef.current = true;\n setFocusedCell(target);\n scrollToIndexes({ rowIndex, colIndex });\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (editingCell) return;\n const target = event.target as HTMLElement;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'SELECT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'BUTTON')\n ) {\n return;\n }\n const pageRows = Math.max(1, Math.floor(Math.max(viewportHeight - headerHeight, rowHeight) / rowHeight));\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1, 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1, 0);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(0, -1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(0, 1);\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(pageRows, 0);\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(-pageRows, 0);\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'first', col: 'first' } : { col: 'first' });\n break;\n case 'End':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'last', col: 'last' } : { col: 'last' });\n break;\n case 'Enter':\n case 'F2':\n if (focusedCell) {\n const node = nodesById.get(focusedCell.id);\n if (node?.type === 'group' && focusedCell.field === GROUPING_COLUMN_FIELD) {\n const group = groupsById.get(focusedCell.id);\n if (group) setRowChildrenExpansion(group.id, !isGroupExpanded(group));\n } else {\n event.preventDefault();\n startCellEditMode(focusedCell.id, focusedCell.field);\n }\n }\n break;\n case ' ':\n if (focusedCell && (checkboxSelection || !disableRowSelectionOnClick)) {\n const dr = pagedRows.find((r) => r.id === focusedCell.id);\n if (dr && dr.type === 'leaf' && dr.row) {\n event.preventDefault();\n selectRows([dr.id], !selectedIds.has(dr.id), false);\n }\n }\n break;\n case 'Escape':\n if (preferencePanel.open) hidePreferences();\n if (columnMenu) setColumnMenu(null);\n break;\n default:\n if (\n (event.ctrlKey || event.metaKey) &&\n event.key.toLowerCase() === 'a' &&\n checkboxSelection &&\n !disableMultipleRowSelection\n ) {\n event.preventDefault();\n selectRows(selectionCandidates, true);\n }\n }\n };\n\n /* ------------------------------------------------------------------ drag & drop (reorder) */\n\n const canReorder = (col: MGHGridColDef) => !disableColumnReorder && !col.disableReorder && !isInternalField(col.field);\n\n const handleDrop = (targetLc: ColumnLayout, event: React.DragEvent) => {\n event.preventDefault();\n const current = drag;\n setDrag(null);\n if (!current || current.field === targetLc.col.field) return;\n const sourceLc = layout.columns.find((lc) => lc.col.field === current.field);\n if (!sourceLc || sourceLc.pinned !== targetLc.pinned || !canReorder(targetLc.col)) return;\n const side = current.side;\n if (sourceLc.pinned) {\n const key = sourceLc.pinned;\n const list = (pinnedColumns[key] ?? []).slice();\n const from = list.indexOf(current.field);\n let to = list.indexOf(targetLc.col.field);\n if (from === -1 || to === -1) return;\n list.splice(from, 1);\n to = list.indexOf(targetLc.col.field);\n list.splice(side === 'right' ? to + 1 : to, 0, current.field);\n setPinnedColumns({ ...pinnedColumns, [key]: list });\n return;\n }\n const fields = orderedUserColumns.map((c) => c.field);\n const from = fields.indexOf(current.field);\n const without = fields.filter((f) => f !== current.field);\n let to = without.indexOf(targetLc.col.field);\n if (side === 'right') to += 1;\n without.splice(to, 0, current.field);\n setOrderedFields(without);\n persistOrder(without);\n const col = columnsByField.get(current.field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex: to, oldIndex: from }, event, getDetails());\n };\n\n /* ------------------------------------------------------------------ resize */\n\n const resizeRef = React.useRef<{\n field: string;\n startX: number;\n startWidth: number;\n lastWidth: number;\n min: number;\n max: number;\n } | null>(null);\n\n const handleResizeStart = (lc: ColumnLayout, event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n field: lc.col.field,\n startX: event.clientX,\n startWidth: lc.width,\n lastWidth: lc.width,\n min: lc.col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n max: lc.col.maxWidth ?? Infinity,\n };\n setResizingField(lc.col.field);\n const onMove = (e: PointerEvent) => {\n const r = resizeRef.current;\n if (!r) return;\n const width = clamp(r.startWidth + (e.clientX - r.startX), r.min, r.max);\n r.lastWidth = width;\n setColumnWidths((prev) => (prev[r.field] === width ? prev : { ...prev, [r.field]: width }));\n };\n const onUp = () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n const r = resizeRef.current;\n resizeRef.current = null;\n setResizingField(null);\n if (!r) return;\n const next = { ...(latest.current.columnWidths as Record<string, number>), [r.field]: r.lastWidth };\n setColumnWidths(next);\n persistWidths(next);\n const col = latest.current.getColumn(r.field);\n if (col && r.lastWidth !== r.startWidth)\n onColumnWidthChange?.({ colDef: col, width: r.lastWidth }, getDetails());\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n };\n\n /* ------------------------------------------------------------------ state snapshot & API */\n\n const filterCount = activeFilters.length;\n const rowCount = groupingActive ? totalDisplayRows : filteredEntries.length;\n\n const state = React.useMemo<MGHGridState>(\n () => ({\n sortModel,\n filterModel,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n pageCount,\n rowCount,\n totalRowCount: rowEntries.length,\n columnVisibilityModel,\n orderedFields: orderedUserColumns.map((c) => c.field),\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n rowSelectionModel: { type: 'include', ids: selectedIds },\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel: {\n open: preferencePanel.open,\n openedPanelValue: preferencePanel.openedPanelValue,\n targetField: preferencePanel.targetField,\n },\n filterCount,\n quickFilterValues,\n }),\n [\n sortModel,\n filterModel,\n page,\n paginationModel.pageSize,\n pageCount,\n rowCount,\n rowEntries.length,\n columnVisibilityModel,\n orderedUserColumns,\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n selectedIds,\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel.open,\n preferencePanel.openedPanelValue,\n preferencePanel.targetField,\n filterCount,\n quickFilterValues,\n ]\n );\n\n latest.current = {\n api: apiObject,\n state,\n rowsById,\n rowEntries,\n nodesById,\n groupsById,\n sortedLeaves,\n pagedRows,\n getRowId,\n setRowOverride,\n orderedUserColumns,\n visibleUserColumns,\n getColumn,\n columnVisibilityModel,\n setColumnVisibilityModel,\n setColumnWidth,\n setColumnIndex,\n columnWidths,\n autosizeColumns,\n pinColumn,\n unpinColumn,\n isColumnPinned,\n pinnedColumns,\n setPinnedColumns,\n sortModel,\n setSortModel,\n sortColumn,\n filterModel,\n setFilterModel,\n upsertFilterItems,\n deleteFilterItem,\n showPreferences,\n hidePreferences,\n selectedIds,\n setSelectedIds,\n selectRows,\n isRowSelectableFn,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n setPaginationModel,\n setDensity,\n toggleDetailPanel,\n expandedDetailPanels,\n setExpandedDetailPanels,\n rowGroupingModel,\n setRowGroupingModel,\n setRowChildrenExpansion,\n aggregationModel,\n setAggregationModel,\n startCellEditMode,\n stopCellEditMode,\n editingCell,\n setEditValue,\n buildCellParams,\n setFocusedCell,\n scrollToIndexes,\n forceUpdate,\n virtual,\n startPrint,\n };\n\n if (apiRef) apiRef.current = apiObject;\n\n React.useEffect(() => {\n onStateChange?.(state, { api: apiObject });\n }, [state, onStateChange, apiObject]);\n\n /* ------------------------------------------------------------------ context */\n\n const rootProps = React.useMemo<MGHGridRootProps>(\n () => ({\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n }),\n [\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n ]\n );\n\n const contextValue = React.useMemo<MGHGridContextValue>(\n () => ({\n api: apiObject,\n state,\n localeText,\n themeMode,\n rootProps,\n columns: orderedUserColumns,\n visibleColumns: visibleUserColumns,\n }),\n [apiObject, state, localeText, themeMode, rootProps, orderedUserColumns, visibleUserColumns]\n );\n\n /* ------------------------------------------------------------------ rendering: cells */\n\n const renderEditor = (params: MGHGridCellParams<R>) => {\n const col = params.colDef;\n const commit = (reason: 'enterKeyDown' | 'cellFocusOut' | 'tabKeyDown') =>\n stopCellEditMode(params.id, params.field, false, reason);\n const cancel = () => stopCellEditMode(params.id, params.field, true, 'escapeKeyDown');\n const keyHandler = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n commit('enterKeyDown');\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n } else if (event.key === 'Tab') {\n commit('tabKeyDown');\n } else {\n event.stopPropagation();\n }\n };\n if (col.renderEditCell) {\n return col.renderEditCell({\n ...params,\n editValue,\n onValueChange: setEditValue,\n commit: () => commit('enterKeyDown'),\n cancel,\n });\n }\n const common = {\n autoFocus: true,\n onKeyDown: keyHandler,\n onBlur: () => commit('cellFocusOut'),\n onClick: (event: React.MouseEvent) => event.stopPropagation(),\n };\n switch (col.type) {\n case 'boolean':\n return (\n <Checkbox\n {...common}\n checked={Boolean(editValue)}\n onChange={(event) => setEditValue(event.target.checked)}\n />\n );\n case 'singleSelect': {\n const options = resolveValueOptions(col, params.row, params.id);\n return (\n <Select\n {...common}\n size=\"small\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(col, o)) === event.target.value);\n setEditValue(match !== undefined ? getOptionValue(col, match) : event.target.value);\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(col, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(col, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'number':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"number\"\n value={editValue === undefined || editValue === null ? '' : editValue}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n case 'date':\n case 'dateTime':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type={col.type === 'date' ? 'date' : 'datetime-local'}\n value={\n typeof editValue === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(editValue)\n ? editValue\n : toDateInputValue(editValue, col.type === 'dateTime')\n }\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n default:\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"text\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n }\n };\n\n const renderCellContent = (lc: ColumnLayout, renderRow: RenderRow<R>): React.ReactNode => {\n const { col } = lc;\n const field = col.field;\n\n if (field === CHECKBOX_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const selectedCount = leafIds.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0);\n return (\n <Checkbox\n checked={leafIds.length > 0 && selectedCount === leafIds.length}\n indeterminate={selectedCount > 0 && selectedCount < leafIds.length}\n label={localeText.checkboxSelectionSelectRow}\n onClick={(event) => event.stopPropagation()}\n onChange={() => selectRows(leafIds, selectedCount !== leafIds.length, false)}\n />\n );\n }\n if (renderRow.kind !== 'leaf') return null;\n const selectable = isRowSelectableFn(renderRow.id, renderRow.row);\n const checked = selectedIds.has(renderRow.id);\n return (\n <Checkbox\n checked={checked}\n disabled={!selectable}\n label={checked ? localeText.checkboxSelectionUnselectRow : localeText.checkboxSelectionSelectRow}\n tabIndex={-1}\n onClick={(event) => event.stopPropagation()}\n onChange={() => {\n lastClickedIdRef.current = renderRow.id;\n selectRows([renderRow.id], !checked, disableMultipleRowSelection);\n }}\n />\n );\n }\n\n if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n if (renderRow.kind !== 'leaf' || !renderRow.row) return null;\n const expanded = expandedDetailPanels.has(renderRow.id);\n const content = getDetailPanelContent?.(buildRowParams(renderRow.id, renderRow.row));\n if (content === null || content === undefined || content === false) return null;\n return (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-detail-toggle', expanded && 'mgh-grid-detail-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n toggleDetailPanel(renderRow.id);\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n );\n }\n\n if (field === GROUPING_COLUMN_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const group = renderRow.group;\n const expanded = isGroupExpanded(group);\n const hideCount = (groupingColDef as any)?.hideDescendantCount;\n return (\n <div className=\"mgh-grid-group-cell\" style={{ paddingLeft: renderRow.depth * 20 }}>\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-group-toggle', expanded && 'mgh-grid-group-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setRowChildrenExpansion(group.id, !expanded);\n }}\n >\n <ChevronRightIcon />\n </IconButton>\n <span className=\"mgh-grid-group-label\" title={group.groupingLabel}>\n {group.groupingLabel}\n </span>\n {!hideCount && <span className=\"mgh-grid-group-count\">({group.descendants.length})</span>}\n </div>\n );\n }\n return null;\n }\n\n if (renderRow.kind === 'group' || renderRow.kind === 'footer') {\n const agg = renderRow.aggregates?.[field];\n if (!agg || isNil(agg.value)) return null;\n const fn = aggregationFunctions[agg.fn];\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sampleRow = (renderRow.group?.descendants[0]?.row ?? latest.current.sortedLeaves[0]?.row ?? {}) as R;\n const formatted = fn?.valueFormatter\n ? fn.valueFormatter(agg.value)\n : col.valueFormatter\n ? col.valueFormatter(agg.value, sampleRow, col as MGHGridColDef<R>, apiRefLocal)\n : defaultFormatValue(agg.value, col);\n return (\n <>\n <span className=\"mgh-grid-aggregation-label\">{fn?.label ?? agg.fn}</span>\n <span className=\"mgh-grid-cell-text\">{formattedValueToString(formatted)}</span>\n </>\n );\n }\n\n if (!renderRow.row) return null;\n const params = buildCellParams(renderRow.id, field, renderRow.row, renderRow.node);\n\n if (params.cellMode === 'edit') return renderEditor(params);\n\n if (col.renderCell) return col.renderCell(params);\n\n if (col.type === 'actions') {\n const actions = col.getActions ? col.getActions(buildRowParams(renderRow.id, renderRow.row)) : [];\n return <ActionsCell actions={actions} themeMode={themeMode} moreLabel={localeText.actionsCellMore} />;\n }\n\n if (col.type === 'boolean') {\n if (isNil(params.value)) return null;\n return params.value ? (\n <CheckIcon aria-label={localeText.booleanCellTrueLabel} />\n ) : (\n <CloseIcon aria-label={localeText.booleanCellFalseLabel} />\n );\n }\n\n const formatted = params.formattedValue;\n if (formatted === null || formatted === undefined) return null;\n if (React.isValidElement(formatted)) return formatted;\n const text = formattedValueToString(formatted);\n return (\n <span className=\"mgh-grid-cell-text\" title={text.length > 20 ? text : undefined}>\n {text}\n </span>\n );\n };\n\n const cellStyle = (lc: ColumnLayout): React.CSSProperties => ({\n width: lc.width,\n minWidth: lc.width,\n maxWidth: lc.width,\n left: lc.pinned === 'left' ? lc.offset : undefined,\n right: lc.pinned === 'right' ? lc.offset : undefined,\n });\n\n const pinnedClasses = (lc: ColumnLayout, prefix: string) =>\n cx(\n lc.pinned === 'left' && `${prefix}--pinned-left`,\n lc.pinned === 'right' && `${prefix}--pinned-right`,\n lc.isLastLeft && layout.hasPinning && `${prefix}--pinned-left-last`,\n lc.isFirstRight && `${prefix}--pinned-right-first`\n );\n\n const renderCell = (lc: ColumnLayout, renderRow: RenderRow<R>, isAutoRow: boolean) => {\n const { col } = lc;\n const field = col.field;\n const isFocused = Boolean(focusedCell && focusedCell.id === renderRow.id && focusedCell.field === field);\n const isEditing = Boolean(editingCell && editingCell.id === renderRow.id && editingCell.field === field);\n const isAggregation =\n (renderRow.kind === 'group' || renderRow.kind === 'footer') && Boolean(renderRow.aggregates?.[field]);\n const params =\n renderRow.kind === 'leaf' && renderRow.row\n ? buildCellParams(renderRow.id, field, renderRow.row, renderRow.node)\n : null;\n const editable = params ? isCellEditableFn(params) : false;\n const customClass =\n params && col.cellClassName\n ? typeof col.cellClassName === 'function'\n ? col.cellClassName(params)\n : col.cellClassName\n : undefined;\n const isCheckbox = field === CHECKBOX_FIELD;\n const isDetailToggle = field === DETAIL_PANEL_TOGGLE_FIELD;\n return (\n <div\n key={field}\n role=\"gridcell\"\n data-mgh-field={field}\n data-mgh-colindex={layout.columns.indexOf(lc)}\n tabIndex={isFocused ? 0 : -1}\n aria-selected={renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : undefined}\n className={cx(\n 'mgh-grid-cell',\n `mgh-grid-cell--align-${col.align ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-cell'),\n isFocused && !isEditing && 'mgh-grid-cell--focused',\n isEditing && 'mgh-grid-cell--editing',\n editable && !isEditing && 'mgh-grid-cell--editable',\n col.type === 'boolean' && 'mgh-grid-cell--boolean',\n col.type === 'actions' && 'mgh-grid-cell--actions',\n isCheckbox && 'mgh-grid-cell--checkbox',\n isDetailToggle && 'mgh-grid-cell--detail-toggle',\n isAggregation && 'mgh-grid-cell--aggregation',\n customClass\n )}\n style={cellStyle(lc)}\n onMouseDown={() => {\n if (renderRow.kind === 'leaf' || renderRow.kind === 'group') {\n if (!isFocused) setFocusedCell({ id: renderRow.id, field });\n }\n }}\n onClick={(event) => {\n if (params && onCellClick) onCellClick(params, event, getDetails());\n }}\n onDoubleClick={(event) => {\n if (params) {\n onCellDoubleClick?.(params, event, getDetails());\n if (editable && !isEditing) {\n event.stopPropagation();\n startCellEditMode(renderRow.id, field);\n }\n }\n }}\n >\n {renderCellContent(lc, renderRow)}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: rows */\n\n const rowIsClickable = Boolean(onRowClick || onRowDoubleClick || !disableRowSelectionOnClick);\n\n const renderRowElement = (\n renderRow: RenderRow<R>,\n options: { height?: number; index: number; isFirst: boolean; isLast: boolean; isAuto: boolean }\n ) => {\n const isSelected = renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : false;\n const customClass =\n renderRow.kind === 'leaf' && renderRow.row && getRowClassName\n ? getRowClassName({\n ...buildRowParams(renderRow.id, renderRow.row),\n indexRelativeToCurrentPage: options.index,\n isFirstVisible: options.isFirst,\n isLastVisible: options.isLast,\n rowNode: renderRow.node,\n })\n : undefined;\n return (\n <div\n role=\"row\"\n aria-rowindex={options.index + 2}\n aria-selected={renderRow.kind === 'leaf' ? isSelected : undefined}\n data-mgh-row-id={String(renderRow.id)}\n data-mgh-row-index={options.index}\n className={cx(\n 'mgh-grid-row',\n isSelected && 'mgh-grid-row--selected',\n rowIsClickable && renderRow.kind === 'leaf' && 'mgh-grid-row--clickable',\n renderRow.kind === 'group' && 'mgh-grid-row--group',\n renderRow.kind === 'pinnedRow' && 'mgh-grid-row--pinned',\n renderRow.kind === 'footer' && 'mgh-grid-row--footer',\n options.isAuto && 'mgh-grid-row--auto-height',\n customClass\n )}\n style={{\n width: layout.totalWidth,\n height: options.isAuto ? undefined : options.height,\n minHeight: options.isAuto ? rowHeight : undefined,\n }}\n onClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n if (!disableRowSelectionOnClick) handleRowSelectionClick(renderRow, event);\n onRowClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n } else if (renderRow.kind === 'group' && renderRow.group) {\n setRowChildrenExpansion(renderRow.group.id, !isGroupExpanded(renderRow.group));\n }\n }}\n onDoubleClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n onRowDoubleClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n }\n }}\n >\n {layout.columns.map((lc) => renderCell(lc, renderRow, options.isAuto))}\n <div className=\"mgh-grid-row-filler\" />\n </div>\n );\n };\n\n const toRenderRow = (dr: DisplayRow<R>): RenderRow<R> => ({\n id: dr.id,\n kind: dr.type,\n row: dr.row,\n node: dr.node,\n depth: dr.depth,\n group: dr.group,\n aggregates: dr.type === 'group' && dr.group ? getGroupAggregates(dr.group) : undefined,\n });\n\n const renderBodyRows = () => {\n const { start, end } = virtualRange;\n const items: React.ReactNode[] = [];\n for (let i = start; i < end; i += 1) {\n const dr = pagedRows[i];\n const renderRow = toRenderRow(dr);\n const detailHeight = heights.detailHeights[i];\n const isExpanded =\n dr.type === 'leaf' && Boolean(dr.row) && Boolean(getDetailPanelContent) && expandedDetailPanels.has(dr.id);\n const detailContent = isExpanded && dr.row ? getDetailPanelContent?.(buildRowParams(dr.id, dr.row)) : null;\n const detailAuto =\n isExpanded && dr.row && getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row }) === 'auto'\n : false;\n const rowAuto =\n !virtual &&\n (getRowHeight && dr.type === 'leaf' && dr.row\n ? getRowHeight({ id: dr.id, model: dr.row, densityFactor }) === 'auto'\n : false);\n items.push(\n <div\n key={String(dr.id)}\n className=\"mgh-grid-row-block\"\n style={virtual ? { top: heights.offsets[i], width: layout.totalWidth } : { width: layout.totalWidth }}\n >\n {renderRowElement(renderRow, {\n height: heights.rowHeights[i],\n index: i,\n isFirst: i === 0,\n isLast: i === pagedRows.length - 1,\n isAuto: rowAuto,\n })}\n {isExpanded && detailContent !== null && detailContent !== undefined && detailContent !== false && (\n <div\n className=\"mgh-grid-detail-panel\"\n style={{\n height: detailAuto ? undefined : detailHeight || undefined,\n width: viewportWidth || undefined,\n }}\n onClick={(event) => event.stopPropagation()}\n >\n {detailContent}\n </div>\n )}\n </div>\n );\n }\n return items;\n };\n\n const renderPinnedRows = (list: R[] | undefined, position: 'top' | 'bottom') => {\n const items: React.ReactNode[] = [];\n (list ?? []).forEach((row, index) => {\n const id = getRowIdFromRow(row, getRowId);\n const renderRow: RenderRow<R> = {\n id,\n kind: 'pinnedRow',\n row,\n node: { type: 'pinnedRow', id, depth: 0, parent: null, position },\n depth: 0,\n };\n items.push(\n <React.Fragment key={String(id)}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: index,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n });\n if (position === 'bottom' && footerAggregates) {\n const renderRow: RenderRow<R> = {\n id: AGGREGATION_FOOTER_ID,\n kind: 'footer',\n row: null,\n node: { type: 'footer', id: AGGREGATION_FOOTER_ID, depth: 0, parent: null },\n depth: 0,\n aggregates: footerAggregates,\n };\n items.push(\n <React.Fragment key={AGGREGATION_FOOTER_ID}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: 0,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n }\n return items;\n };\n\n /* ------------------------------------------------------------------ rendering: header */\n\n const renderHeaderCell = (lc: ColumnLayout, index: number) => {\n const { col } = lc;\n const field = col.field;\n const sortIndex = sortModel.findIndex((item) => item.field === field && item.sort);\n const sortItem = sortIndex !== -1 ? sortModel[sortIndex] : undefined;\n const sortable =\n (col.sortable !== false && !disableColumnSorting && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && col.sortable !== false);\n const showMenu =\n (!disableColumnMenu && !col.disableColumnMenu && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnMenu);\n const resizable =\n (!disableColumnResize && col.resizable !== false && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnResize);\n const draggable = canReorder(col);\n const isDragging = drag?.field === field;\n const isDropTarget = drag && drag.overField === field && drag.field !== field;\n const menuOpen = columnMenu?.field === field;\n const headerParams = { field, colDef: col as MGHGridColDef<R>, api: apiObject };\n const customClass = col.headerClassName\n ? typeof col.headerClassName === 'function'\n ? col.headerClassName(headerParams)\n : col.headerClassName\n : undefined;\n\n let content: React.ReactNode;\n if (field === CHECKBOX_FIELD) {\n content = disableMultipleRowSelection ? null : (\n <Checkbox\n checked={allCandidatesSelected}\n indeterminate={someCandidatesSelected}\n disabled={selectionCandidates.length === 0}\n label={\n allCandidatesSelected\n ? localeText.checkboxSelectionUnselectAllRows\n : localeText.checkboxSelectionSelectAllRows\n }\n onChange={toggleAllCandidates}\n onClick={(event) => event.stopPropagation()}\n />\n );\n } else if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n content = null;\n } else {\n content = col.renderHeader ? (\n col.renderHeader(headerParams)\n ) : (\n <span className=\"mgh-grid-header-title\">{col.headerName ?? field}</span>\n );\n }\n\n return (\n <div\n key={field}\n role=\"columnheader\"\n aria-colindex={index + 1}\n aria-sort={sortItem ? (sortItem.sort === 'asc' ? 'ascending' : 'descending') : sortable ? 'none' : undefined}\n data-mgh-field={field}\n title={col.description}\n tabIndex={-1}\n draggable={draggable}\n className={cx(\n 'mgh-grid-header-cell',\n `mgh-grid-header-cell--align-${col.headerAlign ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-header-cell'),\n sortable && 'mgh-grid-header-cell--sortable',\n field === CHECKBOX_FIELD && 'mgh-grid-header-cell--checkbox',\n field === DETAIL_PANEL_TOGGLE_FIELD && 'mgh-grid-header-cell--detail-toggle',\n index === layout.columns.length - 1 && 'mgh-grid-header-cell--last',\n isDragging && 'mgh-grid-header-cell--dragging',\n isDropTarget && drag?.side === 'left' && 'mgh-grid-header-cell--drop-left',\n isDropTarget && drag?.side === 'right' && 'mgh-grid-header-cell--drop-right',\n menuOpen && 'mgh-grid-header-cell--menu-open',\n customClass\n )}\n style={cellStyle(lc)}\n onClick={(event) => {\n if (!sortable || resizingField) return;\n sortColumn(field, undefined, event.shiftKey);\n }}\n onDragStart={(event) => {\n if (!draggable) return;\n event.dataTransfer.effectAllowed = 'move';\n try {\n event.dataTransfer.setData('text/plain', field);\n } catch {\n /* ignore */\n }\n setDrag({ field, overField: null, side: 'left' });\n }}\n onDragOver={(event) => {\n if (!drag || drag.field === field) return;\n const sourceLc = layout.columns.find((c) => c.col.field === drag.field);\n if (!sourceLc || sourceLc.pinned !== lc.pinned || !canReorder(col)) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n const rect = event.currentTarget.getBoundingClientRect();\n const side = event.clientX < rect.left + rect.width / 2 ? 'left' : 'right';\n if (drag.overField !== field || drag.side !== side) setDrag({ ...drag, overField: field, side });\n }}\n onDragLeave={() => {\n if (drag && drag.overField === field) setDrag({ ...drag, overField: null });\n }}\n onDrop={(event) => handleDrop(lc, event)}\n onDragEnd={() => setDrag(null)}\n >\n <div className=\"mgh-grid-header-title-container\">\n {content}\n {sortable && (\n <span\n className={cx('mgh-grid-sort-icon', sortItem && 'mgh-grid-sort-icon--active')}\n aria-hidden=\"true\"\n >\n {sortItem?.sort === 'desc' ? <ArrowDownwardIcon size={18} /> : <ArrowUpwardIcon size={18} />}\n {sortItem && sortModel.filter((s) => s.sort).length > 1 && (\n <span className=\"mgh-grid-sort-index\">{sortIndex + 1}</span>\n )}\n </span>\n )}\n </div>\n {showMenu && (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-header-menu-btn', menuOpen && 'mgh-grid-header-menu-btn--open')}\n label={localeText.columnMenuLabel}\n aria-haspopup=\"menu\"\n aria-expanded={menuOpen}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setColumnMenu((prev) =>\n prev?.field === field ? null : { field, anchorEl: event.currentTarget }\n );\n }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n {resizable && (\n <div\n className={cx('mgh-grid-resize-handle', resizingField === field && 'mgh-grid-resize-handle--active')}\n role=\"separator\"\n aria-orientation=\"vertical\"\n onPointerDown={(event) => handleResizeStart(lc, event)}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => {\n event.stopPropagation();\n autosizeColumns({ columns: [field] });\n }}\n draggable={false}\n onDragStart={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n />\n )}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: slots */\n\n const ToolbarSlot = slots.toolbar === null ? null : (slots.toolbar ?? MGHGridToolbar);\n const FooterSlot = slots.footer === null ? null : (slots.footer ?? MGHGridFooter);\n const NoRowsOverlaySlot = slots.noRowsOverlay ?? MGHGridNoRowsOverlay;\n const LoadingOverlaySlot = slots.loadingOverlay ?? MGHGridLoadingOverlay;\n const mergedToolbarProps = { ...toolbarProps, ...slotProps.toolbar };\n const noRowsProps = { text: noRowsText, ...slotProps.noRowsOverlay };\n const loadingProps = { ...slotProps.loadingOverlay };\n\n const showNoRows = !loading && pagedRows.length === 0;\n const menuColumn = columnMenu ? getColumn(columnMenu.field) : undefined;\n\n const cardStyles: React.CSSProperties = {\n height: 'auto',\n flexGrow: 1,\n ...sanitizeStyle(cardSx),\n ...sanitizeStyle(cardStyle),\n ...(themeVars as any),\n };\n const boxStyles: React.CSSProperties = { flexGrow: 1, ...sanitizeStyle(boxSx), ...sanitizeStyle(boxStyle) };\n const rootStyles: React.CSSProperties = {\n ...sanitizeStyle(sx),\n ...sanitizeStyle(style),\n ['--mgh-grid-header-height' as any]: `${headerHeight}px`,\n ['--mgh-grid-row-height' as any]: `${rowHeight}px`,\n };\n\n // Nested selectors from sx/style props become a <style> block scoped to this grid instance.\n const scopedCss = React.useMemo(() => {\n const css: string[] = [];\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, sx, css);\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, style, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardSx, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardStyle, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxSx, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxStyle, css);\n return css.join('\\n');\n }, [gridId, sx, style, cardSx, cardStyle, boxSx, boxStyle]);\n\n const smDown = viewportWidth > 0 && viewportWidth < 600;\n\n const grid = (\n <div\n ref={rootRef}\n id={gridId}\n data-mgh-grid-id={gridId}\n role=\"grid\"\n aria-rowcount={rowCount + 1}\n aria-colcount={layout.columns.length}\n aria-multiselectable={checkboxSelection && !disableMultipleRowSelection ? true : undefined}\n aria-busy={loading || undefined}\n className={cx(\n 'mgh-grid',\n (autoHeight || printing) && 'mgh-grid--auto-height',\n printing && 'mgh-grid--printing',\n !layout.hasPinning && 'mgh-grid--no-pinned-shadow',\n className\n )}\n style={rootStyles}\n onKeyDown={handleKeyDown}\n >\n {showToolbar && ToolbarSlot && (\n <div ref={toolbarRef}>\n <ToolbarSlot {...mergedToolbarProps} />\n </div>\n )}\n <div className=\"mgh-grid-main\">\n <div ref={scrollerRef} className=\"mgh-grid-scroller\" onScroll={handleScroll} tabIndex={-1}>\n <div className=\"mgh-grid-columns\" role=\"rowgroup\" style={{ width: layout.totalWidth }}>\n <div className=\"mgh-grid-header-row\" role=\"row\" aria-rowindex={1} style={{ height: headerHeight }}>\n {layout.columns.map((lc, index) => renderHeaderCell(lc, index))}\n <div className=\"mgh-grid-header-filler\" />\n </div>\n </div>\n {pinnedRows?.top && pinnedRows.top.length > 0 && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--top\"\n role=\"rowgroup\"\n style={{ top: headerHeight, width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows.top, 'top')}\n </div>\n )}\n <div\n className={cx('mgh-grid-body', virtual ? 'mgh-grid-body--virtual' : 'mgh-grid-body--flow')}\n role=\"rowgroup\"\n style={\n virtual\n ? {\n height: pagedRows.length === 0 ? Math.max(heights.total, 120) : heights.total,\n width: layout.totalWidth,\n }\n : { width: layout.totalWidth, minHeight: showNoRows || loading ? 120 : undefined }\n }\n >\n {renderBodyRows()}\n </div>\n {((pinnedRows?.bottom && pinnedRows.bottom.length > 0) || footerAggregates) && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--bottom\"\n role=\"rowgroup\"\n style={{ width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows?.bottom, 'bottom')}\n </div>\n )}\n </div>\n {loading && (\n <div className=\"mgh-grid-overlay mgh-grid-overlay--loading\" style={{ top: headerHeight }}>\n <LoadingOverlaySlot {...loadingProps} />\n </div>\n )}\n {showNoRows && (\n <div className=\"mgh-grid-overlay\" style={{ top: headerHeight }}>\n <NoRowsOverlaySlot {...noRowsProps} />\n </div>\n )}\n </div>\n {!hideFooter && FooterSlot && <FooterSlot {...slotProps.footer} />}\n\n <Popover\n open={preferencePanel.open}\n anchorEl={preferencePanel.anchorEl}\n onClose={hidePreferences}\n themeMode={themeMode}\n placement=\"bottom-start\"\n autoFocus\n >\n {preferencePanel.openedPanelValue === 'columns' ? <MGHGridColumnsPanel /> : <MGHGridFilterPanel />}\n </Popover>\n\n {menuColumn && columnMenu && (\n <MGHGridColumnMenu\n column={menuColumn}\n anchorEl={columnMenu.anchorEl}\n open\n onClose={() => setColumnMenu(null)}\n themeMode={themeMode}\n panelAnchorEl={toolbarRef.current}\n />\n )}\n </div>\n );\n\n return (\n <MGHGridContext.Provider value={contextValue}>\n <div\n ref={cardRef}\n className={cx('mgh-grid-card', disableCard && 'mgh-grid-card--plain', cardClassName)}\n data-mgh-theme={themeMode}\n data-mgh-grid-card={gridId}\n style={cardStyles}\n >\n {scopedCss && <style data-mgh-grid-sx={gridId}>{scopedCss}</style>}\n {!disableCard && (header !== undefined || renderHeaderCenterContent || renderHeaderEndContent) && (\n <div className=\"mgh-grid-card-header\">\n {header !== undefined && <h3 className=\"mgh-grid-card-title\">{header}</h3>}\n {renderHeaderCenterContent && (\n <div className=\"mgh-grid-card-header-center\">{renderHeaderCenterContent}</div>\n )}\n <div className=\"mgh-grid-card-header-end\" style={{ gap: smDown ? 8 : 16 }}>\n {renderHeaderEndContent}\n </div>\n </div>\n )}\n <div className={cx('mgh-grid-box', boxClassName)} data-mgh-grid-box={gridId} style={boxStyles}>\n {grid}\n </div>\n </div>\n </MGHGridContext.Provider>\n );\n}\n\nMGHGrid.displayName = 'MGHGrid';\n","import React from 'react';\n\nexport const MGH_DATE_RANGE_PICKER_STYLE_ID = 'mgh-drp-styles';\n\n/**\n * Stylesheet for MGHDateRangePicker. Injected once into <head> the first time a picker mounts.\n * Colours are CSS variables (`--mgh-drp-*`). When the picker is rendered inside an MGHGrid card\n * it inherits the grid palette (`--mgh-grid-*`) automatically.\n */\nexport const MGH_DATE_RANGE_PICKER_CSS = `\n.mgh-drp, .mgh-drp-popover, .mgh-drp-calendars {\n --mgh-drp-font-family: var(--mgh-grid-font-family, inherit);\n --mgh-drp-font-size: var(--mgh-grid-font-size, 14px);\n --mgh-drp-paper: var(--mgh-grid-paper, #ffffff);\n --mgh-drp-fg: var(--mgh-grid-fg, rgba(0, 0, 0, 0.87));\n --mgh-drp-fg-secondary: var(--mgh-grid-fg-secondary, rgba(0, 0, 0, 0.6));\n --mgh-drp-fg-disabled: var(--mgh-grid-fg-disabled, rgba(0, 0, 0, 0.38));\n --mgh-drp-border: var(--mgh-grid-border, rgba(224, 224, 224, 1));\n --mgh-drp-input-border: var(--mgh-grid-input-border, rgba(0, 0, 0, 0.23));\n --mgh-drp-hover: var(--mgh-grid-hover, rgba(0, 0, 0, 0.04));\n --mgh-drp-primary: var(--mgh-grid-primary, #1976d2);\n --mgh-drp-primary-contrast: var(--mgh-grid-primary-contrast, #ffffff);\n --mgh-drp-focus: var(--mgh-grid-focus, #1976d2);\n --mgh-drp-selected: var(--mgh-grid-selected, rgba(25, 118, 210, 0.12));\n --mgh-drp-preview: rgba(0, 0, 0, 0.06);\n --mgh-drp-error: #d32f2f;\n --mgh-drp-radius: 4px;\n --mgh-drp-popover-radius: 8px;\n --mgh-drp-popover-shadow: var(--mgh-grid-popover-shadow, 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12));\n --mgh-drp-day-size: 36px;\n --mgh-drp-day-margin: 2px;\n font-family: var(--mgh-drp-font-family);\n font-size: var(--mgh-drp-font-size);\n color: var(--mgh-drp-fg);\n line-height: 1.5;\n}\n/* Dark values also apply to a calendar nested inside a dark picker / popover, so the calendar's own\n defaults (declared above for standalone use) never reset the colours back to light. */\n.mgh-drp[data-mgh-theme=\"dark\"], .mgh-drp-popover[data-mgh-theme=\"dark\"], .mgh-drp-calendars[data-mgh-theme=\"dark\"],\n.mgh-drp[data-mgh-theme=\"dark\"] .mgh-drp-calendars, .mgh-drp-popover[data-mgh-theme=\"dark\"] .mgh-drp-calendars {\n --mgh-drp-paper: #212b36;\n --mgh-drp-fg: #ffffff;\n --mgh-drp-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-drp-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-drp-border: rgba(81, 81, 81, 1);\n --mgh-drp-input-border: rgba(255, 255, 255, 0.23);\n --mgh-drp-hover: rgba(255, 255, 255, 0.08);\n --mgh-drp-primary: #90caf9;\n --mgh-drp-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-drp-focus: #90caf9;\n --mgh-drp-selected: rgba(144, 202, 249, 0.16);\n --mgh-drp-preview: rgba(255, 255, 255, 0.08);\n --mgh-drp-error: #f44336;\n}\n[class*=\"mgh-drp\"], [class*=\"mgh-drp\"]::before, [class*=\"mgh-drp\"]::after { box-sizing: border-box; }\n\n/* ---- root / multi-input layout ---- */\n.mgh-drp { display: inline-flex; flex-direction: column; vertical-align: top; min-width: 0; }\n.mgh-drp--full-width { display: flex; width: 100%; }\n.mgh-drp-fields { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }\n.mgh-drp-fields .mgh-drp-field { flex: 1 1 0; min-width: 0; }\n.mgh-drp-fields-separator { align-self: center; color: var(--mgh-drp-fg-secondary); padding: 0 2px; }\n\n/* ---- outlined text field (MUI TextField look-alike) ---- */\n.mgh-drp-field { position: relative; display: inline-flex; align-items: center; min-width: 0; width: 100%; border-radius: var(--mgh-drp-radius); color: var(--mgh-drp-fg); }\n.mgh-drp-field--medium { height: 56px; }\n.mgh-drp-field--small { height: 40px; }\n.mgh-drp-field:not(.mgh-drp-field--full-width) { width: 260px; }\n.mgh-drp-field--multi:not(.mgh-drp-field--full-width) { width: 170px; }\n.mgh-drp-field--full-width { width: 100%; }\n.mgh-drp-input { flex: 1 1 auto; min-width: 0; width: 100%; height: 100%; margin: 0; border: 0; outline: none; background: transparent; color: inherit; font: inherit; font-size: 1rem; letter-spacing: inherit; padding: 16.5px 14px; }\n.mgh-drp-field--small .mgh-drp-input { padding: 8.5px 14px; }\n.mgh-drp-field--adorned .mgh-drp-input { padding-right: 0; }\n.mgh-drp-input::placeholder { color: var(--mgh-drp-fg-disabled); opacity: 1; }\n.mgh-drp-input::-webkit-calendar-picker-indicator { display: none; }\n.mgh-drp-field--disabled .mgh-drp-input { color: var(--mgh-drp-fg-disabled); -webkit-text-fill-color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-field--disabled { cursor: default; }\n.mgh-drp-field--clickable .mgh-drp-input { cursor: pointer; }\n.mgh-drp-adornment { display: flex; align-items: center; gap: 0; margin-right: 6px; flex: 0 0 auto; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-field--small .mgh-drp-adornment { margin-right: 4px; }\n\n/* notched outline */\n.mgh-drp-outline { position: absolute; inset: -5px 0 0 0; margin: 0; padding: 0 8px; pointer-events: none; border: 1px solid var(--mgh-drp-input-border); border-radius: inherit; min-width: 0; overflow: hidden; text-align: left; transition: border-color .15s; }\n.mgh-drp-outline legend { float: unset; width: auto; padding: 0; height: 11px; font-size: 0.75em; visibility: hidden; max-width: 0.01px; white-space: nowrap; transition: max-width 50ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; overflow: hidden; display: block; line-height: 11px; }\n.mgh-drp-outline legend > span { padding-left: 5px; padding-right: 5px; display: inline-block; opacity: 0; visibility: visible; }\n.mgh-drp-field--shrink .mgh-drp-outline legend { max-width: 100%; transition: max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms; }\n.mgh-drp-field--no-label .mgh-drp-outline legend { display: none; }\n.mgh-drp-field:hover:not(.mgh-drp-field--disabled) .mgh-drp-outline { border-color: var(--mgh-drp-fg); }\n.mgh-drp-field--focused .mgh-drp-outline, .mgh-drp-field--focused:hover .mgh-drp-outline { border-color: var(--mgh-drp-focus); border-width: 2px; }\n.mgh-drp-field--error .mgh-drp-outline, .mgh-drp-field--error:hover .mgh-drp-outline { border-color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-outline { border-color: var(--mgh-drp-fg-disabled); }\n\n/* floating label */\n.mgh-drp-label { position: absolute; left: 0; top: 0; transform-origin: top left; transform: translate(14px, 16px) scale(1); color: var(--mgh-drp-fg-secondary); font-size: 1rem; line-height: 1.4375em; pointer-events: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: calc(100% - 24px); transition: color .15s, transform .15s cubic-bezier(0.0, 0, 0.2, 1), max-width .15s; z-index: 1; }\n.mgh-drp-field--small .mgh-drp-label { transform: translate(14px, 9px) scale(1); }\n.mgh-drp-field--shrink .mgh-drp-label, .mgh-drp-field--small.mgh-drp-field--shrink .mgh-drp-label { transform: translate(14px, -9px) scale(0.75); max-width: calc(133% - 32px); }\n.mgh-drp-field--focused .mgh-drp-label { color: var(--mgh-drp-focus); }\n.mgh-drp-field--error .mgh-drp-label { color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-label { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-label-asterisk { margin-left: 2px; }\n\n.mgh-drp-helper { margin: 3px 14px 0; font-size: 0.75rem; line-height: 1.66; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-helper--error { color: var(--mgh-drp-error); }\n\n/* ---- buttons ---- */\n.mgh-drp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-drp-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; white-space: nowrap; text-transform: uppercase; }\n.mgh-drp-btn:hover { background: var(--mgh-drp-hover); color: var(--mgh-drp-fg); }\n.mgh-drp-btn:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-btn:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-btn--primary { color: var(--mgh-drp-primary); }\n.mgh-drp-btn--primary:hover { background: var(--mgh-drp-selected); color: var(--mgh-drp-primary); }\n.mgh-drp-btn--icon { padding: 8px; border-radius: 50%; width: 40px; height: 40px; text-transform: none; }\n.mgh-drp-btn--icon.mgh-drp-btn--small { width: 32px; height: 32px; padding: 4px; }\n.mgh-drp-icon { flex: 0 0 auto; }\n\n/* ---- popover ---- */\n.mgh-drp-popover { position: fixed; z-index: 1300; display: flex; flex-direction: column; background: var(--mgh-drp-paper); color: var(--mgh-drp-fg); border-radius: var(--mgh-drp-popover-radius); box-shadow: var(--mgh-drp-popover-shadow); outline: none; max-height: calc(100vh - 16px); max-width: calc(100vw - 16px); overflow: auto; animation: mgh-drp-pop .12s ease-out; }\n@keyframes mgh-drp-pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }\n.mgh-drp-layout { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-layout--with-toolbar { flex-direction: column; }\n.mgh-drp-layout-main { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-toolbar { padding: 16px 24px 0; }\n.mgh-drp-toolbar-title { font-size: 0.75rem; text-transform: uppercase; letter-spacing: .08em; color: var(--mgh-drp-fg-secondary); margin: 0 0 8px; }\n.mgh-drp-toolbar-range { display: flex; align-items: center; gap: 8px; font-size: 1.5rem; font-weight: 400; line-height: 1.334; }\n.mgh-drp-toolbar-range button { border: 0; background: transparent; padding: 0 2px; font: inherit; color: var(--mgh-drp-fg-secondary); cursor: pointer; border-radius: 4px; }\n.mgh-drp-toolbar-range button.mgh-drp-toolbar-range--active { color: var(--mgh-drp-fg); }\n.mgh-drp-toolbar-range button:hover { background: var(--mgh-drp-hover); }\n\n/* shortcuts (left column) */\n.mgh-drp-shortcuts { list-style: none; margin: 0; padding: 8px 0; min-width: 140px; max-height: 340px; overflow: auto; border-right: 1px solid var(--mgh-drp-border); display: flex; flex-direction: column; gap: 4px; padding-left: 8px; padding-right: 8px; }\n.mgh-drp-shortcut { display: inline-flex; align-items: center; height: 32px; padding: 0 12px; border-radius: 16px; border: 1px solid var(--mgh-drp-input-border); background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.8125rem; cursor: pointer; white-space: nowrap; justify-content: flex-start; transition: background-color .15s; }\n.mgh-drp-shortcut:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-shortcut:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-shortcut:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; }\n.mgh-drp-shortcut--selected { background: var(--mgh-drp-selected); border-color: var(--mgh-drp-primary); color: var(--mgh-drp-primary); }\n\n/* ---- calendars ---- */\n.mgh-drp-calendars { display: flex; flex-direction: row; align-items: flex-start; }\n.mgh-drp-calendar { display: flex; flex-direction: column; width: calc(7 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)) + 24px); padding: 0 12px 8px; }\n.mgh-drp-calendar + .mgh-drp-calendar { border-left: 1px solid var(--mgh-drp-border); }\n.mgh-drp-calendar-header { display: flex; align-items: center; justify-content: space-between; min-height: 40px; margin: 12px 0 8px; padding: 0 4px; }\n.mgh-drp-calendar-label { flex: 1 1 auto; text-align: center; font-size: 1rem; font-weight: 500; }\n.mgh-drp-calendar-header .mgh-drp-btn--icon { color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-calendar-nav-spacer { width: 40px; height: 40px; flex: 0 0 auto; }\n.mgh-drp-weekdays, .mgh-drp-week { display: flex; justify-content: center; }\n.mgh-drp-weekday { width: var(--mgh-drp-day-size); height: 40px; margin: 0 var(--mgh-drp-day-margin); display: flex; align-items: center; justify-content: center; font-size: 0.75rem; color: var(--mgh-drp-fg-secondary); font-weight: 400; }\n.mgh-drp-weeks { display: flex; flex-direction: column; min-height: calc(6 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin))); }\n.mgh-drp-week { margin: var(--mgh-drp-day-margin) 0; }\n\n/* day cell: the outer wrapper carries the range highlight, the inner button the day itself */\n.mgh-drp-day-wrap { position: relative; width: calc(var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)); height: var(--mgh-drp-day-size); display: flex; align-items: center; justify-content: center; }\n.mgh-drp-day-wrap--in-range { background: var(--mgh-drp-selected); }\n.mgh-drp-day-wrap--range-start { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--range-end { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--preview { border-top: 1px dashed var(--mgh-drp-fg-secondary); border-bottom: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--preview-start { border-left: 1px dashed var(--mgh-drp-fg-secondary); border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--preview-end { border-right: 1px dashed var(--mgh-drp-fg-secondary); border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; border-left: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; border-right: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day { width: var(--mgh-drp-day-size); height: var(--mgh-drp-day-size); border-radius: 50%; border: 0; margin: 0; padding: 0; background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.75rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background-color .15s, color .15s; position: relative; }\n.mgh-drp-day:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-day:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: -1px; }\n.mgh-drp-day--today:not(.mgh-drp-day--selected) { border: 1px solid var(--mgh-drp-fg-secondary); }\n.mgh-drp-day--outside { color: var(--mgh-drp-fg-secondary); opacity: .6; }\n.mgh-drp-day--hidden { visibility: hidden; pointer-events: none; }\n.mgh-drp-day--disabled, .mgh-drp-day--disabled:hover { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-day--selected, .mgh-drp-day--selected:hover { background: var(--mgh-drp-primary); color: var(--mgh-drp-primary-contrast); font-weight: 500; }\n.mgh-drp-day--selected:focus-visible { outline-offset: 2px; }\n.mgh-drp-calendar--read-only .mgh-drp-day, .mgh-drp-calendar--disabled .mgh-drp-day { cursor: default; }\n.mgh-drp-calendar--disabled .mgh-drp-day { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-calendar--disabled .mgh-drp-day--selected { opacity: .6; }\n\n/* ---- action bar ---- */\n.mgh-drp-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 8px; border-top: 1px solid var(--mgh-drp-border); }\n.mgh-drp-actions--spread { justify-content: space-between; }\n.mgh-drp-actions-group { display: flex; gap: 8px; }\n\n@media (max-width: 599.95px) {\n .mgh-drp-layout-main { flex-direction: column; }\n .mgh-drp-shortcuts { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--mgh-drp-border); max-height: none; }\n .mgh-drp-calendars { flex-direction: column; align-items: center; }\n .mgh-drp-calendar + .mgh-drp-calendar { border-left: 0; border-top: 1px solid var(--mgh-drp-border); }\n}\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_DATE_RANGE_PICKER_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_DATE_RANGE_PICKER_STYLE_ID;\n style.setAttribute('data-mgh-drp', 'true');\n style.textContent = MGH_DATE_RANGE_PICKER_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHDateRangePicker stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHDateRangePickerStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\n\n/* Inline SVG icons (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHDateRangeIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHDateRangeIconProps>(({ size = 24, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-drp-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const DateRangeIcon = createIcon(\n <path d=\"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\" />,\n 'DateRangeIcon'\n);\nexport const ChevronLeftIcon = createIcon(\n <path d=\"M15.41 16.59 10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z\" />,\n 'ChevronLeftIcon'\n);\nexport const ChevronRightIcon = createIcon(\n <path d=\"M8.59 16.59 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\" />,\n 'ChevronRightIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\n","import dayjs, { Dayjs } from 'dayjs';\nimport customParseFormat from 'dayjs/plugin/customParseFormat';\nimport type {\n MGHDateRange,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\n\ndayjs.extend(customParseFormat);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const EMPTY_RANGE: MGHDateRange = [null, null];\n\n/** Coerces Dayjs / Date / ISO string / timestamp into a valid Dayjs (or null). */\nexport const toDayjs = (value: unknown): Dayjs | null => {\n if (value == null || value === '') return null;\n if (dayjs.isDayjs(value)) return value.isValid() ? value : null;\n if (value instanceof Date || typeof value === 'number' || typeof value === 'string') {\n const parsed = dayjs(value as Date | number | string);\n return parsed.isValid() ? parsed : null;\n }\n return null;\n};\n\nexport const isSameDay = (a: Dayjs | null | undefined, b: Dayjs | null | undefined) => !!a && !!b && a.isSame(b, 'day');\nexport const isBeforeDay = (a: Dayjs, b: Dayjs) => a.isBefore(b, 'day');\nexport const isAfterDay = (a: Dayjs, b: Dayjs) => a.isAfter(b, 'day');\nexport const isWithinRange = (day: Dayjs, start: Dayjs | null, end: Dayjs | null) =>\n !!start && !!end && !isBeforeDay(day, start) && !isAfterDay(day, end);\n\nexport const isRangeEqual = (a: MGHDateRange | undefined, b: MGHDateRange | undefined) => {\n if (a === b) return true;\n if (!a || !b) return false;\n const same = (x: Dayjs | null, y: Dayjs | null) => (x == null && y == null) || (!!x && !!y && x.isSame(y, 'day'));\n return same(a[0], b[0]) && same(a[1], b[1]);\n};\n\nexport const normalizeRange = (value: unknown): MGHDateRange => {\n if (!Array.isArray(value)) return EMPTY_RANGE;\n return [toDayjs(value[0]), toDayjs(value[1])];\n};\n\n/** Strict parse with the display format first, then a handful of forgiving fallbacks. */\nexport const parseDateText = (text: string, format: string): Dayjs | null => {\n const trimmed = text.trim();\n if (!trimmed) return null;\n const strict = dayjs(trimmed, format, true);\n if (strict.isValid()) return strict;\n const fallbacks = [\n format.replace(/MM/g, 'M').replace(/DD/g, 'D'),\n 'M/D/YYYY',\n 'M/D/YY',\n 'YYYY-MM-DD',\n 'MM-DD-YYYY',\n 'M-D-YYYY',\n ];\n for (const f of fallbacks) {\n const parsed = dayjs(trimmed, f, true);\n if (parsed.isValid()) return parsed;\n }\n return null;\n};\n\nexport const formatDate = (value: Dayjs | null, format: string) => (value && value.isValid() ? value.format(format) : '');\n\n/** Splits \"start – end\" text typed into the single-input field. */\nexport const splitRangeText = (text: string): [string, string] => {\n const parts = text.split(/\\s+[–—-]\\s+|\\s*–\\s*|\\s*—\\s*|\\s+to\\s+/i);\n if (parts.length >= 2) return [parts[0], parts.slice(1).join(' ')];\n return [text, ''];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validation (mirrors MUI's DateRangeValidationError semantics)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface DateValidationOptions {\n minDate?: Dayjs | null;\n maxDate?: Dayjs | null;\n disablePast?: boolean;\n disableFuture?: boolean;\n shouldDisableDate?: (day: Dayjs, position: MGHDateRangePosition) => boolean;\n}\n\nexport const validateDay = (\n day: Dayjs | null,\n position: MGHDateRangePosition,\n options: DateValidationOptions,\n now: Dayjs = dayjs()\n): MGHDateRangeValidationError => {\n if (day == null) return null;\n if (!day.isValid()) return 'invalidDate';\n if (options.disablePast && isBeforeDay(day, now)) return 'disablePast';\n if (options.disableFuture && isAfterDay(day, now)) return 'disableFuture';\n if (options.minDate && isBeforeDay(day, options.minDate)) return 'minDate';\n if (options.maxDate && isAfterDay(day, options.maxDate)) return 'maxDate';\n if (options.shouldDisableDate?.(day, position)) return 'shouldDisableDate';\n return null;\n};\n\nexport const validateRange = (\n value: MGHDateRange,\n options: DateValidationOptions\n): [MGHDateRangeValidationError, MGHDateRangeValidationError] => {\n const now = dayjs();\n const startError = validateDay(value[0], 'start', options, now);\n const endError = validateDay(value[1], 'end', options, now);\n if (!startError && !endError && value[0] && value[1] && isAfterDay(value[0], value[1])) {\n return ['invalidRange', 'invalidRange'];\n }\n return [startError, endError];\n};\n\nexport const isDayDisabled = (day: Dayjs, position: MGHDateRangePosition, options: DateValidationOptions) =>\n validateDay(day, position, options) != null;\n\n/* -------------------------------------------------------------------------------------------------\n * Calendar grid\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface CalendarWeek {\n key: string;\n days: Array<{ day: Dayjs; outsideMonth: boolean }>;\n}\n\n/**\n * Builds the weeks of `month`. Weeks start on the locale's first day of the week (Sunday for `en`).\n * Pass `fixedWeekNumber` (usually 6) to always render the same number of rows.\n */\nexport const getMonthWeeks = (month: Dayjs, fixedWeekNumber?: number): CalendarWeek[] => {\n const firstOfMonth = month.startOf('month');\n const start = firstOfMonth.startOf('week');\n const weeksInMonth = Math.ceil(firstOfMonth.endOf('month').diff(start, 'day') / 7 + 1 / 7);\n const weekCount = fixedWeekNumber && fixedWeekNumber > 0 ? fixedWeekNumber : Math.max(weeksInMonth, 1);\n const weeks: CalendarWeek[] = [];\n for (let w = 0; w < weekCount; w += 1) {\n const weekStart = start.add(w * 7, 'day');\n weeks.push({\n key: weekStart.format('YYYY-MM-DD'),\n days: Array.from({ length: 7 }, (_, d) => {\n const day = weekStart.add(d, 'day');\n return { day, outsideMonth: !day.isSame(firstOfMonth, 'month') };\n }),\n });\n }\n return weeks;\n};\n\nexport const getWeekDayLabels = (formatter: (day: Dayjs) => string) => {\n const start = dayjs().startOf('week');\n return Array.from({ length: 7 }, (_, i) => {\n const day = start.add(i, 'day');\n return { key: day.format('dd'), label: formatter(day), full: day.format('dddd') };\n });\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Shortcuts (same shape as MUI's PickersShortcuts items)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const MGH_DATE_RANGE_DEFAULT_SHORTCUTS: MGHDateRangeShortcut[] = [\n {\n label: 'This Week',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('week'), today.endOf('week')];\n },\n },\n {\n label: 'Last Week',\n getValue: () => {\n const prev = dayjs().subtract(7, 'day');\n return [prev.startOf('week'), prev.endOf('week')];\n },\n },\n {\n label: 'Last 7 Days',\n getValue: () => {\n const today = dayjs();\n return [today.subtract(7, 'day'), today];\n },\n },\n {\n label: 'Current Month',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('month'), today.endOf('month')];\n },\n },\n {\n label: 'Next Month',\n getValue: () => {\n const next = dayjs().add(1, 'month');\n return [next.startOf('month'), next.endOf('month')];\n },\n },\n { label: 'Reset', getValue: () => [null, null] },\n];\n","import React from 'react';\nimport dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateRange, MGHDateRangeCalendarProps, MGHDateRangePosition } from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { ChevronLeftIcon, ChevronRightIcon } from './icons';\nimport {\n EMPTY_RANGE,\n cx,\n getMonthWeeks,\n getWeekDayLabels,\n isAfterDay,\n isBeforeDay,\n isDayDisabled,\n isSameDay,\n isWithinRange,\n normalizeRange,\n} from './utils';\n\nconst defaultDayOfWeekFormatter = (day: Dayjs) => day.format('dd').charAt(0).toUpperCase();\n\n/**\n * Pure-React port of MUI X's `DateRangeCalendar`: one to three months side by side with range\n * highlighting, hover preview, keyboard navigation and min/max/disabled-day validation.\n */\nexport function MGHDateRangeCalendar({\n value: valueProp,\n defaultValue,\n onChange,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth = false,\n fixedWeekNumber,\n dayOfWeekFormatter = defaultDayOfWeekFormatter,\n disableHighlightToday = false,\n showRangePreview = true,\n autoFocus = false,\n onMonthChange,\n localeText,\n themeMode,\n className,\n style,\n}: MGHDateRangeCalendarProps) {\n useMGHDateRangePickerStyles();\n\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n\n // Month displayed by the first calendar.\n const [currentMonth, setCurrentMonth] = React.useState<Dayjs>(() =>\n (start ?? end ?? referenceDate ?? dayjs()).startOf('month')\n );\n const visibleMonths = React.useMemo(\n () => Array.from({ length: calendars }, (_, i) => currentMonth.add(i, 'month')),\n [currentMonth, calendars]\n );\n const lastVisibleMonth = visibleMonths[visibleMonths.length - 1];\n\n const changeMonth = React.useCallback(\n (month: Dayjs) => {\n const next = month.startOf('month');\n setCurrentMonth((prev) => {\n if (prev.isSame(next, 'month')) return prev;\n onMonthChange?.(next);\n return next;\n });\n },\n [onMonthChange]\n );\n\n const ensureVisible = React.useCallback(\n (day: Dayjs) => {\n if (isBeforeDay(day, currentMonth.startOf('month'))) changeMonth(day);\n else if (isAfterDay(day, lastVisibleMonth.endOf('month'))) changeMonth(day.subtract(calendars - 1, 'month'));\n },\n [currentMonth, lastVisibleMonth, calendars, changeMonth]\n );\n\n // When a value arrives from outside (typed in the field / shortcut) scroll to it.\n const lastSeenRef = React.useRef<MGHDateRange>(value);\n React.useEffect(() => {\n const prev = lastSeenRef.current;\n lastSeenRef.current = value;\n const target = rangePosition === 'end' ? (end ?? start) : (start ?? end);\n if (!target) return;\n const changed = !isSameDay(prev[0], start) || !isSameDay(prev[1], end);\n if (changed) ensureVisible(target);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [start, end]);\n\n const canGoPrev = !minDate || currentMonth.isAfter(minDate, 'month');\n const canGoNext = !maxDate || lastVisibleMonth.isBefore(maxDate, 'month');\n\n /* ---- hover preview ---- */\n const [hoveredDay, setHoveredDay] = React.useState<Dayjs | null>(null);\n const preview = React.useMemo<MGHDateRange>(() => {\n if (!showRangePreview || !hoveredDay || disabled || readOnly) return EMPTY_RANGE;\n if (rangePosition === 'end' && start && !end) {\n return isBeforeDay(hoveredDay, start) ? EMPTY_RANGE : [start, hoveredDay];\n }\n if (rangePosition === 'start' && end && !start) {\n return isAfterDay(hoveredDay, end) ? EMPTY_RANGE : [hoveredDay, end];\n }\n return EMPTY_RANGE;\n }, [showRangePreview, hoveredDay, rangePosition, start, end, disabled, readOnly]);\n\n /* ---- selection (MUI semantics) ---- */\n const selectDay = React.useCallback(\n (day: Dayjs) => {\n if (disabled || readOnly) return;\n if (isDayDisabled(day, rangePosition, validation)) return;\n let next: MGHDateRange;\n let nextPosition: MGHDateRangePosition;\n if (rangePosition === 'start') {\n // Picking a start after the current end resets the end (MUI behaviour).\n next = [day, end && isAfterDay(day, end) ? null : end];\n nextPosition = 'end';\n } else if (start && isBeforeDay(day, start)) {\n // An \"end\" before the start becomes the new start; keep asking for the end.\n next = [day, null];\n nextPosition = 'end';\n } else {\n next = [start, day];\n nextPosition = 'start';\n }\n if (!isControlled) setInternalValue(next);\n onChange?.(next, day, rangePosition);\n setRangePosition(nextPosition);\n },\n [disabled, readOnly, rangePosition, validation, end, start, isControlled, onChange, setRangePosition]\n );\n\n /* ---- keyboard navigation (roving tabindex) ---- */\n const [focusedDay, setFocusedDay] = React.useState<Dayjs>(() => start ?? end ?? referenceDate ?? dayjs());\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef(autoFocus);\n\n const focusDay = React.useCallback((day: Dayjs) => {\n const key = day.format('YYYY-MM-DD');\n const el = rootRef.current?.querySelector<HTMLButtonElement>(`[data-day=\"${key}\"]`);\n el?.focus();\n }, []);\n\n React.useEffect(() => {\n if (!pendingFocusRef.current) return;\n pendingFocusRef.current = false;\n const target = focusedDay;\n ensureVisible(target);\n // Wait for a potential month change to render.\n const id = window.setTimeout(() => focusDay(target), 0);\n return () => window.clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const moveFocus = (day: Dayjs) => {\n setFocusedDay(day);\n ensureVisible(day);\n window.setTimeout(() => focusDay(day), 0);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>, day: Dayjs) => {\n let next: Dayjs | null = null;\n switch (event.key) {\n case 'ArrowLeft':\n next = day.subtract(1, 'day');\n break;\n case 'ArrowRight':\n next = day.add(1, 'day');\n break;\n case 'ArrowUp':\n next = day.subtract(7, 'day');\n break;\n case 'ArrowDown':\n next = day.add(7, 'day');\n break;\n case 'Home':\n next = day.startOf('week');\n break;\n case 'End':\n next = day.endOf('week');\n break;\n case 'PageUp':\n next = event.shiftKey ? day.subtract(1, 'year') : day.subtract(1, 'month');\n break;\n case 'PageDown':\n next = event.shiftKey ? day.add(1, 'year') : day.add(1, 'month');\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n selectDay(day);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (next) moveFocus(next);\n };\n\n const weekDays = React.useMemo(() => getWeekDayLabels(dayOfWeekFormatter), [dayOfWeekFormatter]);\n const today = dayjs();\n const previewStart = preview[0];\n const previewEnd = preview[1];\n const isRangeComplete = !!start && !!end;\n\n const renderMonth = (month: Dayjs, index: number) => {\n const weeks = getMonthWeeks(month, fixedWeekNumber);\n const isFirst = index === 0;\n const isLast = index === visibleMonths.length - 1;\n const focusedInMonth = focusedDay.isSame(month, 'month') ? focusedDay : null;\n const tabbableDay =\n focusedInMonth ??\n (start && start.isSame(month, 'month') ? start : null) ??\n (end && end.isSame(month, 'month') ? end : null) ??\n (isFirst && !visibleMonths.some((m) => focusedDay.isSame(m, 'month')) ? month.startOf('month') : null);\n\n return (\n <div\n key={month.format('YYYY-MM')}\n className=\"mgh-drp-calendar\"\n role=\"group\"\n aria-label={month.format('MMMM YYYY')}\n >\n <div className=\"mgh-drp-calendar-header\">\n {isFirst ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.previousMonth ?? 'Previous month'}\n title={localeText?.previousMonth ?? 'Previous month'}\n disabled={disabled || !canGoPrev}\n onClick={() => changeMonth(currentMonth.subtract(1, 'month'))}\n >\n <ChevronLeftIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n <div className=\"mgh-drp-calendar-label\" aria-live=\"polite\">\n {month.format('MMMM YYYY')}\n </div>\n {isLast ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.nextMonth ?? 'Next month'}\n title={localeText?.nextMonth ?? 'Next month'}\n disabled={disabled || !canGoNext}\n onClick={() => changeMonth(currentMonth.add(1, 'month'))}\n >\n <ChevronRightIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n </div>\n <div className=\"mgh-drp-weekdays\" role=\"row\">\n {weekDays.map((wd) => (\n <span key={wd.key} className=\"mgh-drp-weekday\" role=\"columnheader\" aria-label={wd.full}>\n {wd.label}\n </span>\n ))}\n </div>\n <div className=\"mgh-drp-weeks\" role=\"grid\" aria-label={month.format('MMMM YYYY')}>\n {weeks.map((week) => (\n <div key={week.key} className=\"mgh-drp-week\" role=\"row\">\n {week.days.map(({ day, outsideMonth }, dayIndex) => {\n const hidden = outsideMonth && !showDaysOutsideCurrentMonth;\n const isStart = isSameDay(day, start);\n const isEnd = isSameDay(day, end);\n const selected = isStart || isEnd;\n const inRange = !hidden && isRangeComplete && isWithinRange(day, start, end);\n const inPreview =\n !hidden &&\n !!previewStart &&\n !!previewEnd &&\n isWithinRange(day, previewStart, previewEnd);\n const dayDisabled = disabled || isDayDisabled(day, rangePosition, validation);\n const isTabbable = !!tabbableDay && isSameDay(day, tabbableDay) && !hidden;\n const firstVisible = dayIndex === 0 || (!showDaysOutsideCurrentMonth && day.date() === 1);\n const lastVisible =\n dayIndex === 6 || (!showDaysOutsideCurrentMonth && day.date() === day.daysInMonth());\n return (\n <div\n key={day.format('YYYY-MM-DD')}\n role=\"gridcell\"\n aria-selected={selected || undefined}\n className={cx(\n 'mgh-drp-day-wrap',\n inRange && 'mgh-drp-day-wrap--in-range',\n inRange && isStart && 'mgh-drp-day-wrap--range-start',\n inRange && isEnd && 'mgh-drp-day-wrap--range-end',\n inPreview && 'mgh-drp-day-wrap--preview',\n inPreview && isSameDay(day, previewStart) && 'mgh-drp-day-wrap--preview-start',\n inPreview && isSameDay(day, previewEnd) && 'mgh-drp-day-wrap--preview-end',\n firstVisible && 'mgh-drp-day-wrap--first-visible',\n lastVisible && 'mgh-drp-day-wrap--last-visible'\n )}\n >\n <button\n type=\"button\"\n data-day={day.format('YYYY-MM-DD')}\n tabIndex={isTabbable ? 0 : -1}\n aria-label={day.format('dddd, MMMM D, YYYY')}\n aria-current={\n !disableHighlightToday && isSameDay(day, today) ? 'date' : undefined\n }\n aria-disabled={dayDisabled || undefined}\n disabled={hidden}\n className={cx(\n 'mgh-drp-day',\n hidden && 'mgh-drp-day--hidden',\n outsideMonth && !hidden && 'mgh-drp-day--outside',\n selected && 'mgh-drp-day--selected',\n !disableHighlightToday && isSameDay(day, today) && 'mgh-drp-day--today',\n dayDisabled && 'mgh-drp-day--disabled'\n )}\n onClick={() => selectDay(day)}\n onMouseEnter={() => setHoveredDay(day)}\n onMouseLeave={() =>\n setHoveredDay((prev) => (prev && isSameDay(prev, day) ? null : prev))\n }\n onFocus={() => setFocusedDay(day)}\n onKeyDown={(event) => handleKeyDown(event, day)}\n >\n {day.date()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={rootRef}\n className={cx(\n 'mgh-drp-calendars',\n disabled && 'mgh-drp-calendar--disabled',\n readOnly && 'mgh-drp-calendar--read-only',\n className\n )}\n data-mgh-theme={themeMode}\n data-range-position={rangePosition}\n style={style}\n onMouseLeave={() => setHoveredDay(null)}\n >\n {visibleMonths.map(renderMonth)}\n </div>\n );\n}\n\nexport default MGHDateRangeCalendar;\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport dayjs from 'dayjs';\nimport type {\n MGHDateRange,\n MGHDateRangeChangeContext,\n MGHDateRangePickerLocaleText,\n MGHDateRangePickerProps,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { MGHDateRangeCalendar } from './MGHDateRangeCalendar';\nimport { CloseIcon, DateRangeIcon } from './icons';\nimport {\n EMPTY_RANGE,\n clamp,\n cx,\n formatDate,\n isRangeEqual,\n normalizeRange,\n parseDateText,\n splitRangeText,\n validateRange,\n} from './utils';\n\nexport const MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT: MGHDateRangePickerLocaleText = {\n start: 'Start',\n end: 'End',\n fieldSeparator: '–',\n openPicker: 'Choose date range',\n clear: 'Clear',\n today: 'Today',\n cancel: 'Cancel',\n accept: 'OK',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n toolbarTitle: 'Select date range',\n};\n\nconst DEFAULT_FORMAT = 'MM/DD/YYYY';\n\n/* -------------------------------------------------------------------------------------------------\n * Anchored popover (portal)\n * ----------------------------------------------------------------------------------------------- */\n\ninterface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null;\n placement: 'bottom-start' | 'bottom-end' | 'bottom';\n onDismiss: (reason: 'backdrop' | 'escape') => void;\n themeMode?: 'light' | 'dark';\n className?: string;\n style?: React.CSSProperties;\n labelledBy?: string;\n children: React.ReactNode;\n}\n\nfunction Popover({ open, anchorEl, placement, onDismiss, themeMode, className, style, labelledBy, children }: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState({ top: 0, left: 0, ready: false });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n top = a.bottom + 4;\n if (top + h > vh - 8 && a.top - 4 - h >= 8) top = a.top - 4 - h;\n left = placement === 'bottom-end' ? a.right - w : placement === 'bottom' ? a.left + a.width / 2 - w / 2 : a.left;\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n onDismiss('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onDismiss('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onDismiss, anchorEl]);\n\n if (!open || typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={labelledBy}\n tabIndex={-1}\n className={cx('mgh-drp-popover', className)}\n data-mgh-theme={themeMode}\n style={{ top: position.top, left: position.left, visibility: position.ready ? 'visible' : 'hidden', ...style }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Outlined text field (MUI TextField look-alike, no dependency)\n * ----------------------------------------------------------------------------------------------- */\n\ninterface TextFieldProps {\n id: string;\n label?: React.ReactNode;\n value: string;\n placeholder?: string;\n size: 'small' | 'medium';\n fullWidth?: boolean;\n multi?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n error?: boolean;\n focused?: boolean;\n clickable?: boolean;\n name?: string;\n autoFocus?: boolean;\n inputRef?: React.Ref<HTMLInputElement>;\n adornment?: React.ReactNode;\n ariaLabel?: string;\n onChange: (text: string) => void;\n onFocus: () => void;\n onBlur: () => void;\n onClick?: () => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nconst TextField = React.forwardRef<HTMLDivElement, TextFieldProps>(function TextField(\n {\n id,\n label,\n value,\n placeholder,\n size,\n fullWidth,\n multi,\n disabled,\n readOnly,\n required,\n error,\n focused,\n clickable,\n name,\n autoFocus,\n inputRef,\n adornment,\n ariaLabel,\n onChange,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n },\n ref\n) {\n const hasLabel = label != null && label !== '';\n const shrink = focused || value !== '' || !hasLabel;\n return (\n <div\n ref={ref}\n className={cx(\n 'mgh-drp-field',\n `mgh-drp-field--${size}`,\n fullWidth && 'mgh-drp-field--full-width',\n multi && 'mgh-drp-field--multi',\n shrink && 'mgh-drp-field--shrink',\n focused && 'mgh-drp-field--focused',\n disabled && 'mgh-drp-field--disabled',\n error && 'mgh-drp-field--error',\n clickable && 'mgh-drp-field--clickable',\n !hasLabel && 'mgh-drp-field--no-label',\n !!adornment && 'mgh-drp-field--adorned'\n )}\n onClick={onClick}\n >\n {hasLabel && (\n <label className=\"mgh-drp-label\" htmlFor={id}>\n {label}\n {required && (\n <span className=\"mgh-drp-label-asterisk\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <input\n id={id}\n ref={inputRef}\n name={name}\n className=\"mgh-drp-input\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"off\"\n spellCheck={false}\n value={value}\n placeholder={shrink ? placeholder : undefined}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n aria-label={ariaLabel}\n aria-invalid={error || undefined}\n onChange={(event) => onChange(event.target.value)}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n />\n {adornment && <div className=\"mgh-drp-adornment\">{adornment}</div>}\n <fieldset aria-hidden=\"true\" className=\"mgh-drp-outline\">\n <legend>\n <span>\n {hasLabel ? label : ''}\n {hasLabel && required ? ' *' : ''}\n </span>\n </legend>\n </fieldset>\n </div>\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * MGHDateRangePicker\n * ----------------------------------------------------------------------------------------------- */\n\ntype FocusedInput = 'single' | 'start' | 'end' | null;\n\n/**\n * MUI-free port of MUI X Pro's `DateRangePicker` (desktop variant): an outlined text field with a\n * calendar button that opens a two-month range calendar, optional shortcuts and an action bar.\n * Values are dayjs `[start, end]` tuples so existing `DateRange<Dayjs>` state works unchanged.\n */\nexport const MGHDateRangePicker = React.forwardRef<HTMLDivElement, MGHDateRangePickerProps>(function MGHDateRangePicker(\n {\n value: valueProp,\n defaultValue,\n onChange,\n onAccept,\n onError,\n open: openProp,\n onOpen,\n onClose,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n label,\n format = DEFAULT_FORMAT,\n fieldVariant = 'single',\n size = 'small',\n fullWidth = false,\n clearable = false,\n openOnClick,\n disableOpenPicker = false,\n closeOnSelect,\n shortcuts,\n actions = [],\n showToolbar = false,\n localeText: localeTextProp,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth,\n fixedWeekNumber,\n dayOfWeekFormatter,\n disableHighlightToday,\n showRangePreview,\n onMonthChange,\n name,\n id: idProp,\n placeholder: placeholderProp,\n required,\n error: errorProp,\n helperText,\n autoFocus,\n inputRef,\n themeMode,\n themeVars,\n className,\n style,\n popoverClassName,\n popoverStyle,\n placement = 'bottom-start',\n },\n ref\n) {\n useMGHDateRangePickerStyles();\n\n const localeText = React.useMemo(\n () => ({ ...MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n const datePlaceholder = localeText.datePlaceholder ?? format;\n const isMulti = fieldVariant === 'multi';\n const resolvedOpenOnClick = openOnClick ?? isMulti;\n const resolvedCloseOnSelect = closeOnSelect ?? !actions.includes('accept');\n\n const reactId = React.useId();\n const baseId = idProp ?? `mgh-drp-${reactId.replace(/:/g, '')}`;\n const startId = isMulti ? `${baseId}-start` : baseId;\n const endId = `${baseId}-end`;\n const dialogTitleId = `${baseId}-title`;\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n const validationError = React.useMemo(() => validateRange(value, validation), [value, validation]);\n const isValid = React.useCallback(\n (range: MGHDateRange) => validateRange(range, validation).every((e) => e == null),\n [validation]\n );\n\n const lastErrorRef = React.useRef<[MGHDateRangeValidationError, MGHDateRangeValidationError] | null>(null);\n React.useEffect(() => {\n const prev = lastErrorRef.current;\n if (prev && prev[0] === validationError[0] && prev[1] === validationError[1]) return;\n if (prev !== null || validationError[0] || validationError[1]) onError?.(validationError, value);\n lastErrorRef.current = validationError;\n }, [validationError, value, onError]);\n\n const setValue = React.useCallback(\n (next: MGHDateRange, shortcut?: MGHDateRangeShortcut) => {\n if (!isControlled) setInternalValue(next);\n const context: MGHDateRangeChangeContext = { validationError: validateRange(next, validation) };\n if (shortcut) context.shortcut = shortcut;\n onChange?.(next, context);\n },\n [isControlled, onChange, validation]\n );\n\n /* ---- range position ---- */\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n /* ---- open / close ---- */\n const isOpenControlled = openProp !== undefined;\n const [internalOpen, setInternalOpen] = React.useState(false);\n const open = isOpenControlled ? !!openProp : internalOpen;\n const valueAtOpenRef = React.useRef<MGHDateRange>(value);\n const lastAcceptedRef = React.useRef<MGHDateRange>(value);\n\n /** Fires `onAccept` only when the value differs from the last accepted one (MUI semantics). */\n const accept = React.useCallback(\n (next: MGHDateRange, force = false) => {\n if (!force && isRangeEqual(next, lastAcceptedRef.current)) return;\n lastAcceptedRef.current = next;\n onAccept?.(next);\n },\n [onAccept]\n );\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n // Without an explicit `themeMode`, follow the closest `[data-mgh-theme]` ancestor (e.g. a dark MGHGrid card)\n // so the portaled popover matches the surface the field sits on.\n const [inheritedTheme, setInheritedTheme] = React.useState<'light' | 'dark' | undefined>(undefined);\n React.useEffect(() => {\n if (themeMode !== undefined) return;\n const attr = rootRef.current?.parentElement?.closest('[data-mgh-theme]')?.getAttribute('data-mgh-theme');\n setInheritedTheme(attr === 'dark' ? 'dark' : attr === 'light' ? 'light' : undefined);\n });\n const effectiveThemeMode = themeMode ?? inheritedTheme;\n\n const setRootRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [ref]\n );\n\n const openPicker = React.useCallback(\n (position?: MGHDateRangePosition) => {\n if (disabled || readOnly || open) return;\n valueAtOpenRef.current = value;\n restoreFocusRef.current = (document.activeElement as HTMLElement | null) ?? null;\n setRangePosition(position ?? (start && !end ? 'end' : 'start'));\n if (!isOpenControlled) setInternalOpen(true);\n onOpen?.();\n },\n [disabled, readOnly, open, value, start, end, setRangePosition, isOpenControlled, onOpen]\n );\n\n const closePicker = React.useCallback(() => {\n if (!open) return;\n if (!isOpenControlled) setInternalOpen(false);\n onClose?.();\n const target = toggleRef.current ?? restoreFocusRef.current;\n window.setTimeout(() => target?.focus?.(), 0);\n }, [open, isOpenControlled, onClose]);\n\n const acceptAndClose = React.useCallback(\n (next: MGHDateRange) => {\n accept(next, true);\n closePicker();\n },\n [accept, closePicker]\n );\n\n const handleDismiss = React.useCallback(() => {\n // Clicking away / Escape keeps whatever was picked (MUI fires onAccept when the value changed).\n accept(value);\n closePicker();\n }, [value, accept, closePicker]);\n\n const handleCalendarChange = React.useCallback(\n (next: MGHDateRange, _day: dayjs.Dayjs, position: MGHDateRangePosition) => {\n setValue(next);\n if (position === 'end' && next[0] && next[1] && resolvedCloseOnSelect) acceptAndClose(next);\n },\n [setValue, resolvedCloseOnSelect, acceptAndClose]\n );\n\n const handleShortcut = (shortcut: MGHDateRangeShortcut) => {\n const next = normalizeRange(shortcut.getValue({ isValid }));\n setValue(next, shortcut);\n setRangePosition('start');\n acceptAndClose(next);\n };\n\n const handleAction = (action: 'clear' | 'today' | 'cancel' | 'accept') => {\n switch (action) {\n case 'clear': {\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n acceptAndClose(EMPTY_RANGE);\n break;\n }\n case 'today': {\n const today = dayjs().startOf('day');\n const next: MGHDateRange = [today, today];\n setValue(next);\n setRangePosition('start');\n if (resolvedCloseOnSelect) acceptAndClose(next);\n break;\n }\n case 'cancel': {\n if (!isRangeEqual(value, valueAtOpenRef.current)) setValue(valueAtOpenRef.current);\n closePicker();\n break;\n }\n case 'accept':\n default:\n acceptAndClose(value);\n }\n };\n\n /* ---- text fields ---- */\n const [focusedInput, setFocusedInput] = React.useState<FocusedInput>(null);\n const formatSingle = React.useCallback(\n (range: MGHDateRange) => {\n const [s, e] = range;\n if (!s && !e) return '';\n return `${s ? formatDate(s, format) : datePlaceholder} ${localeText.fieldSeparator} ${e ? formatDate(e, format) : datePlaceholder}`;\n },\n [format, datePlaceholder, localeText.fieldSeparator]\n );\n\n const [singleText, setSingleText] = React.useState(() => formatSingle(value));\n const [startText, setStartText] = React.useState(() => formatDate(start, format));\n const [endText, setEndText] = React.useState(() => formatDate(end, format));\n const [inputInvalid, setInputInvalid] = React.useState<{ single: boolean; start: boolean; end: boolean }>({\n single: false,\n start: false,\n end: false,\n });\n\n // Keep the text in sync with the value unless the user is typing in that input.\n React.useEffect(() => {\n if (focusedInput !== 'single') {\n setSingleText(formatSingle(value));\n setInputInvalid((prev) => (prev.single ? { ...prev, single: false } : prev));\n }\n if (focusedInput !== 'start') {\n setStartText(formatDate(start, format));\n setInputInvalid((prev) => (prev.start ? { ...prev, start: false } : prev));\n }\n if (focusedInput !== 'end') {\n setEndText(formatDate(end, format));\n setInputInvalid((prev) => (prev.end ? { ...prev, end: false } : prev));\n }\n }, [value, start, end, focusedInput, format, formatSingle]);\n\n const parseSegment = (text: string): { date: dayjs.Dayjs | null; invalid: boolean } => {\n const trimmed = text.trim();\n if (!trimmed || trimmed.toUpperCase() === datePlaceholder.toUpperCase()) return { date: null, invalid: false };\n const parsed = parseDateText(trimmed, format);\n return { date: parsed, invalid: parsed == null };\n };\n\n const handleSingleChange = (text: string) => {\n setSingleText(text);\n const [s, e] = splitRangeText(text);\n const ps = parseSegment(s);\n const pe = parseSegment(e);\n const invalid = ps.invalid || pe.invalid;\n setInputInvalid((prev) => ({ ...prev, single: invalid }));\n if (invalid) return;\n const next: MGHDateRange = [ps.date, pe.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleSideChange = (side: 'start' | 'end', text: string) => {\n if (side === 'start') setStartText(text);\n else setEndText(text);\n const parsed = parseSegment(text);\n setInputInvalid((prev) => ({ ...prev, [side]: parsed.invalid }));\n if (parsed.invalid) return;\n const next: MGHDateRange = side === 'start' ? [parsed.date, end] : [start, parsed.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleBlur = (input: Exclude<FocusedInput, null>) => {\n setFocusedInput((prev) => (prev === input ? null : prev));\n // Re-format on blur unless the text could not be parsed (keep it so the user sees the error).\n if (input === 'single' && !inputInvalid.single) setSingleText(formatSingle(value));\n if (input === 'start' && !inputInvalid.start) setStartText(formatDate(start, format));\n if (input === 'end' && !inputInvalid.end) setEndText(formatDate(end, format));\n // Leaving the field commits a typed value (like pressing Enter).\n if (!open) accept(value);\n };\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>, position: MGHDateRangePosition) => {\n if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n openPicker(position);\n } else if (event.key === 'Enter') {\n event.preventDefault();\n if (!open) accept(value);\n }\n };\n\n const clear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n accept(EMPTY_RANGE);\n };\n\n const hasValue = !!start || !!end;\n const hasValidationError = validationError.some((e) => e != null);\n const showError = !!errorProp || hasValidationError || inputInvalid.single || inputInvalid.start || inputInvalid.end;\n\n const openButton = !disableOpenPicker && (\n <button\n ref={toggleRef}\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.openPicker}\n title={localeText.openPicker}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (open) handleDismiss();\n else openPicker();\n }}\n >\n <DateRangeIcon size={size === 'small' ? 20 : 24} />\n </button>\n );\n\n const clearButton = clearable && hasValue && !disabled && !readOnly && (\n <button\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.clear}\n title={localeText.clear}\n onClick={clear}\n >\n <CloseIcon size={size === 'small' ? 18 : 20} />\n </button>\n );\n\n const themeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...style }),\n [themeVars, style]\n );\n const popoverThemeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...popoverStyle }),\n [themeVars, popoverStyle]\n );\n\n /* ---- shortcuts / actions / toolbar ---- */\n const shortcutItems = React.useMemo(\n () =>\n (shortcuts ?? []).map((shortcut, index) => {\n let shortcutValue: MGHDateRange = EMPTY_RANGE;\n try {\n shortcutValue = normalizeRange(shortcut.getValue({ isValid }));\n } catch {\n /* ignore */\n }\n return { shortcut, key: shortcut.id ?? `${shortcut.label}-${index}`, value: shortcutValue };\n }),\n [shortcuts, isValid]\n );\n\n const renderToolbar = () => (\n <div className=\"mgh-drp-toolbar\">\n <p className=\"mgh-drp-toolbar-title\" id={dialogTitleId}>\n {localeText.toolbarTitle}\n </p>\n <div className=\"mgh-drp-toolbar-range\">\n <button\n type=\"button\"\n className={cx(rangePosition === 'start' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('start')}\n >\n {start ? formatDate(start, format) : localeText.start}\n </button>\n <span>{localeText.fieldSeparator}</span>\n <button\n type=\"button\"\n className={cx(rangePosition === 'end' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('end')}\n >\n {end ? formatDate(end, format) : localeText.end}\n </button>\n </div>\n </div>\n );\n\n const renderActions = () =>\n actions.length > 0 && (\n <div className=\"mgh-drp-actions\">\n {actions.map((action) => (\n <button\n key={action}\n type=\"button\"\n className={cx('mgh-drp-btn', (action === 'accept' || action === 'today') && 'mgh-drp-btn--primary')}\n onClick={() => handleAction(action)}\n >\n {localeText[action]}\n </button>\n ))}\n </div>\n );\n\n const calendar = (\n <MGHDateRangeCalendar\n value={value}\n onChange={handleCalendarChange}\n rangePosition={rangePosition}\n onRangePositionChange={setRangePosition}\n calendars={calendars}\n referenceDate={referenceDate}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n showDaysOutsideCurrentMonth={showDaysOutsideCurrentMonth}\n fixedWeekNumber={fixedWeekNumber}\n dayOfWeekFormatter={dayOfWeekFormatter}\n disableHighlightToday={disableHighlightToday}\n showRangePreview={showRangePreview}\n onMonthChange={onMonthChange}\n localeText={localeText}\n themeMode={effectiveThemeMode}\n autoFocus\n />\n );\n\n /* ---- render ---- */\n const commonFieldProps = {\n size,\n fullWidth,\n disabled,\n readOnly,\n required,\n error: showError,\n };\n\n return (\n <div\n ref={setRootRef}\n className={cx('mgh-drp', fullWidth && 'mgh-drp--full-width', isMulti && 'mgh-drp--multi', className)}\n data-mgh-theme={effectiveThemeMode}\n style={themeStyle}\n >\n {isMulti ? (\n <div className=\"mgh-drp-fields\">\n <TextField\n {...commonFieldProps}\n multi\n id={startId}\n name={name ? `${name}-start` : undefined}\n label={localeText.start}\n value={startText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'start'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n onChange={(text) => handleSideChange('start', text)}\n onFocus={() => {\n setFocusedInput('start');\n setRangePosition('start');\n }}\n onBlur={() => handleBlur('start')}\n onClick={() => resolvedOpenOnClick && openPicker('start')}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n <span className=\"mgh-drp-fields-separator\" aria-hidden=\"true\">\n {localeText.fieldSeparator}\n </span>\n <TextField\n {...commonFieldProps}\n multi\n id={endId}\n name={name ? `${name}-end` : undefined}\n label={localeText.end}\n value={endText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'end'}\n clickable={resolvedOpenOnClick}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={(text) => handleSideChange('end', text)}\n onFocus={() => {\n setFocusedInput('end');\n setRangePosition('end');\n }}\n onBlur={() => handleBlur('end')}\n onClick={() => resolvedOpenOnClick && openPicker('end')}\n onKeyDown={(event) => handleInputKeyDown(event, 'end')}\n />\n </div>\n ) : (\n <TextField\n {...commonFieldProps}\n id={startId}\n name={name}\n label={label}\n value={singleText}\n placeholder={placeholderProp ?? `${datePlaceholder} ${localeText.fieldSeparator} ${datePlaceholder}`}\n focused={focusedInput === 'single'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n ariaLabel={label == null ? localeText.toolbarTitle : undefined}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={handleSingleChange}\n onFocus={() => setFocusedInput('single')}\n onBlur={() => handleBlur('single')}\n onClick={() => resolvedOpenOnClick && openPicker()}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n )}\n {helperText != null && helperText !== '' && (\n <div className={cx('mgh-drp-helper', showError && 'mgh-drp-helper--error')}>{helperText}</div>\n )}\n\n <Popover\n open={open}\n anchorEl={rootRef.current}\n placement={placement}\n onDismiss={handleDismiss}\n themeMode={effectiveThemeMode}\n className={popoverClassName}\n style={popoverThemeStyle}\n labelledBy={showToolbar ? dialogTitleId : undefined}\n >\n <div className={cx('mgh-drp-layout', showToolbar && 'mgh-drp-layout--with-toolbar')}>\n {showToolbar && renderToolbar()}\n <div className=\"mgh-drp-layout-main\">\n {shortcutItems.length > 0 && (\n <ul className=\"mgh-drp-shortcuts\" aria-label=\"Shortcuts\">\n {shortcutItems.map(({ shortcut, key, value: shortcutValue }) => (\n <li key={key}>\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-shortcut',\n hasValue &&\n isRangeEqual(shortcutValue, value) &&\n 'mgh-drp-shortcut--selected'\n )}\n disabled={disabled || readOnly}\n onClick={() => handleShortcut(shortcut)}\n >\n {shortcut.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n {calendar}\n </div>\n {renderActions()}\n </div>\n </Popover>\n </div>\n );\n});\n\nMGHDateRangePicker.displayName = 'MGHDateRangePicker';\n\nexport default MGHDateRangePicker;\n","import Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\n\nimport { ConfirmDialogProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nexport default function ConfirmDialog({ title, content, action, open, onClose, ...other }: ConfirmDialogProps) {\n return (\n <Dialog fullWidth maxWidth=\"xs\" open={open} onClose={onClose} {...other}>\n <DialogTitle sx={{ pb: 2 }}>{title}</DialogTitle>\n\n {content && <DialogContent sx={{ typography: 'body2' }}> {content} </DialogContent>}\n\n <DialogActions>\n <Button onClick={onClose}>Cancel</Button>\n {action}\n </DialogActions>\n </Dialog>\n );\n}\n","import {\n GridToolbarExportContainer,\n GridCsvExportMenuItem,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n} from '@mui/x-data-grid-premium';\nimport React from 'react';\nimport { ExportContainerProps } from './CustomGridToolbarExport.types';\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomGridToolbarExport({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n // color,\n customMenuItem,\n ...other\n}: ExportContainerProps) {\n return (\n <GridToolbarExportContainer\n {...other}\n // color={color}\n >\n {customMenuItem}\n <GridCsvExportMenuItem options={csvOptions} />\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n );\n}\n","import styled from '@emotion/styled';\n\nimport { Box } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n// import { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n\nimport React from 'react';\n// import { NoRowsOverlayPropsOverrides } from './CustomNoRowsOverlay.types';\n\n/// ---------------------------------------------------------------------------------------\n\ndeclare module '@mui/x-data-grid-premium' {\n export interface NoRowsOverlayPropsOverrides {\n text: string;\n useSettingsContext?: () => { themeMode?: string };\n }\n}\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomNoRowsOverlay({ text, useSettingsContext }: NoRowsOverlayPropsOverrides) {\n const theme = useTheme();\n const themeMode = useSettingsContext?.()?.themeMode ?? theme.palette.mode ?? 'light';\n\n const StyledGridOverlay = styled('div')(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n '& .ant-empty-img-1': {\n fill: themeMode === 'light' ? '#aeb8c2' : '#262626',\n },\n '& .ant-empty-img-2': {\n fill: themeMode === 'light' ? '#f5f5f7' : '#595959',\n },\n '& .ant-empty-img-3': {\n fill: themeMode === 'light' ? '#dce0e6' : '#434343',\n },\n '& .ant-empty-img-4': {\n fill: themeMode === 'light' ? '#fff' : '#1c1c1c',\n },\n '& .ant-empty-img-5': {\n fillOpacity: themeMode === 'light' ? '0.8' : '0.08',\n fill: themeMode === 'light' ? '#f5f5f5' : '#fff',\n },\n }));\n return (\n <StyledGridOverlay>\n <Box\n component=\"img\"\n alt=\"empty content\"\n src=\"/assets/icons/empty/ic_content.svg\"\n sx={{ width: 50, maxWidth: 160 }}\n />\n <Box sx={{ mb: 0 }}>{text}</Box>\n </StyledGridOverlay>\n );\n}\n","import { JSX } from 'react';\n\nimport { Dialog, Typography, DialogContent, CircularProgress } from '@mui/material';\nimport React from 'react';\n\n/// ---------------------------------------------------------------------------------------\n\ninterface ExportingProps {\n open: boolean;\n text?: JSX.Element | string;\n}\nexport default function ExportingDialog({\n open,\n text = (\n <>\n Your export is currently being built. Some larger exports can take a couple of minutes to complete. <br />\n <br />\n Please do not close your browser or refresh the page.\n </>\n ),\n}: ExportingProps) {\n return (\n <Dialog open={open} fullWidth sx={{ p: 4 }}>\n <DialogContent sx={{ p: 4, textAlign: 'center' }}>\n <Typography variant=\"subtitle1\" sx={{ mb: 3 }}>\n {text}\n </Typography>\n <CircularProgress />\n </DialogContent>\n </Dialog>\n );\n}\n","import useMediaQuery from '@mui/material/useMediaQuery';\nimport { useTheme, Breakpoint } from '@mui/material/styles';\n\n// ----------------------------------------------------------------------\n\ntype ReturnType = boolean;\n\nexport type Query = 'up' | 'down' | 'between' | 'only';\n\nexport type Value = Breakpoint | number;\n\nexport function useResponsive(query: Query, start?: Value, end?: Value): ReturnType {\n const theme = useTheme();\n\n const mediaUp = useMediaQuery(theme.breakpoints.up(start as Value));\n\n const mediaDown = useMediaQuery(theme.breakpoints.down(start as Value));\n\n const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Value, end as Value));\n\n const mediaOnly = useMediaQuery(theme.breakpoints.only(start as Breakpoint));\n\n if (query === 'up') {\n return mediaUp;\n }\n\n if (query === 'down') {\n return mediaDown;\n }\n\n if (query === 'between') {\n return mediaBetween;\n }\n\n return mediaOnly;\n}\n\n// ----------------------------------------------------------------------\n\ntype BreakpointOrNull = Breakpoint | null;\n\nexport function useWidth() {\n const theme = useTheme();\n\n const keys = [...theme.breakpoints.keys].reverse();\n\n return (\n keys.reduce((output: BreakpointOrNull, key: Breakpoint) => {\n const matches = useMediaQuery(theme.breakpoints.up(key));\n\n return !output && matches ? key : output;\n }, null) || 'xs'\n );\n}\n"],"names":["Iconify","forwardRef","icon","width","sx","other","ref","React","createElement","Icon","style","height","StyledLabel","styled","Box","ownerState","theme","useTheme","lightMode","palette","mode","filledVariant","variant","outlinedVariant","softVariant","defaultStyle","color","common","white","grey","backgroundColor","text","primary","border","secondary","alpha","colorStyle","contrastText","main","minWidth","lineHeight","borderRadius","cursor","alignItems","whiteSpace","display","justifyContent","textTransform","padding","spacing","fontSize","typography","pxToRem","fontWeight","fontWeightBold","transition","transitions","create","duration","shorter","Label","children","startIcon","endIcon","iconStyles","objectFit","pl","pr","mr","ml","GROUPING_COLUMN_FIELD","CHECKBOX_FIELD","DETAIL_PANEL_TOGGLE_FIELD","AGGREGATION_FOOTER_ID","INTERNAL_FIELDS","Set","DENSITY_FACTORS","compact","standard","comfortable","DEFAULT_ROW_HEIGHT","DEFAULT_HEADER_HEIGHT","DEFAULT_COLUMN_MIN_WIDTH","isInternalField","field","has","isNil","value","isEmptyValue","Array","isArray","length","clamp","min","max","Math","cx","classNames","filter","Boolean","join","uniqueId","counter","prefix","canUseLocalStorage","window","localStorage","readLocalStorage","key","getItem","JSON","parse","writeLocalStorage","setItem","stringify","getRowIdFromRow","row","getRowId","id","normalizeSelectionModel","input","allIds","type","ids","forEach","add","toDate","Date","Number","isNaN","getTime","dayjs","isDayjs","isValid","d","parsed","formatDate","withTime","date","format","startOfUnit","startOf","valueOf","isValueOptionObject","option","getOptionValue","col","getOptionLabel","label","String","resolveValueOptions","valueOptions","getCellValue","api","raw","undefined","valueGetter","defaultFormatValue","match","find","isFinite","getFormattedValue","valueFormatter","formattedValueToString","formatted","collator","Intl","Collator","numeric","sensitivity","nilFirst","v1","v2","n1","n2","numberComparator","nil","stringComparator","s1","s2","compare","stringOrNumberComparator","p1","p2","dateComparator","d1","d2","booleanComparator","getDefaultComparator","lower","toLowerCase","hasValue","item","stringFilterOperators","inputType","getApplyFilterFn","needle","indexOf","s","lastIndexOf","requiresFilterValue","set","map","numberOperator","filterValue","cell","n","numberFilterOperators","a","b","v","dateOperator","filterDate","filterTime","cellDate","getDateFilterOperators","booleanFilterOperators","expected","singleSelectFilterOperators","getColumnFilterOperators","filterOperators","getDefaultFilterOperators","normalizeColumn","isNumber","isBoolean","isActions","headerName","align","headerAlign","sortable","filterable","hideable","resizable","pinnable","groupable","aggregable","editable","disableColumnMenu","disableExport","internalColumn","maxWidth","disableReorder","CHECKBOX_COLUMN_DEF","DETAIL_PANEL_TOGGLE_COLUMN_DEF","UNITLESS_PROPERTIES","isSelectorKey","test","serializeDeclarations","block","Object","keys","property","kebab","replace","m","toKebabCase","formatCssValue","buildScopedCss","scope","out","charAt","inner","declarations","push","selector","scopeSelector","split","part","trim","numericValues","values","BUILT_IN_AGGREGATION_FUNCTIONS","sum","columnTypes","apply","nums","reduce","acc","avg","defined","every","dates","slice","sort","sorted","size","DEFAULT_LOCALE_TEXT","noRowsLabel","loadingLabel","toolbarColumns","toolbarFilters","toolbarExport","toolbarDensity","toolbarQuickFilterPlaceholder","toolbarQuickFilterLabel","toolbarExportCSV","toolbarExportExcel","toolbarExportPrint","densityCompact","densityStandard","densityComfortable","columnsPanelSearchPlaceholder","columnsPanelShowAll","columnsPanelHideAll","columnsPanelReset","filterPanelAddFilter","filterPanelRemoveAll","filterPanelDeleteIcon","filterPanelColumns","filterPanelOperator","filterPanelValue","filterPanelInputPlaceholder","filterPanelLogicOperator","filterPanelOperatorAnd","filterPanelOperatorOr","columnMenuSortAsc","columnMenuSortDesc","columnMenuUnsort","columnMenuFilter","columnMenuHideColumn","columnMenuManageColumns","columnMenuPinLeft","columnMenuPinRight","columnMenuUnpin","columnMenuGroup","name","columnMenuUngroup","columnMenuAggregation","aggregationMenuItemHeader","aggregationFunctionLabelNone","aggregationFunctionLabelSum","aggregationFunctionLabelAvg","aggregationFunctionLabelMin","aggregationFunctionLabelMax","aggregationFunctionLabelSize","footerRowSelected","count","toLocaleString","footerTotalRows","footerPaginationRowsPerPage","footerPaginationDisplayedRows","from","to","footerPaginationFirstPage","footerPaginationPreviousPage","footerPaginationNextPage","footerPaginationLastPage","checkboxSelectionHeaderName","checkboxSelectionSelectAllRows","checkboxSelectionUnselectAllRows","checkboxSelectionSelectRow","checkboxSelectionUnselectRow","booleanCellTrueLabel","booleanCellFalseLabel","detailPanelToggle","expandDetailPanel","collapseDetailPanel","groupingColumnHeaderName","groupColumn","unGroupColumn","actionsCellMore","columnHeaderSortIconLabel","columnMenuLabel","clearSearch","measureContext","measureText","font","document","canvas","getContext","downloadBlob","blob","fileName","url","URL","createObjectURL","anchor","href","download","body","appendChild","click","setTimeout","removeChild","revokeObjectURL","MGH_GRID_STYLE_ID","MGH_GRID_CSS","injected","useInsertion","useInsertionEffect","useLayoutEffect","useEffect","useMGHGridStyles","injectStyles","getElementById","setAttribute","textContent","head","MGHGridContext","createContext","displayName","useMGHGridContext","ctx","useContext","Error","useLatestRef","useRef","current","useControlledState","controlled","defaultValue","onChange","isControlled","internal","setInternal","useState","valueRef","controlledRef","onChangeRef","useCallback","next","resolved","is","idCounter","buildExportTable","options","columns","resolveExportColumns","all","getAllColumns","fields","byField","Map","c","f","get","allColumns","getVisibleColumns","getRowsToExport","getSortedRowIds","rows","getRow","headers","sanitizeFileName","fallback","extension","base","endsWith","defaultFileBase","title","escapeCsvCell","delimiter","getDataAsCsv","includeHeaders","table","lines","h","cells","useRawValues","UTF8_BOM","fromCharCode","CRC_TABLE","Uint32Array","k","textEncoder","TextEncoder","encodeUtf8","encode","utf8","unescape","encodeURIComponent","Uint8Array","i","charCodeAt","concatBytes","chunks","total","offset","zipStore","entries","localChunks","centralChunks","entry","nameBytes","crc","bytes","crc32","data","local","lv","DataView","buffer","setUint32","setUint16","central","cv","centralDirectory","eocd","ev","concat","INVALID_XML_CHARS","RegExp","escapeXml","stripInvalidXml","columnLetter","index","letters","rem","floor","XML_HEADER","buildSheetXml","columnWidths","rowsXml","rowIndex","inlineString","xmlCells","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","lastCol","lastRow","cols","w","STYLES_XML","CONTENT_TYPES_XML","ROOT_RELS_XML","WORKBOOK_RELS_XML","buildWorkbookXml","sheetName","buildCoreXml","now","toISOString","APP_XML","buildXlsx","widths","explicit","columnsStyles","r","len","cleaned","sanitizeSheetName","escapeHtml","printGridElement","params","done","onDone","printGridElementUnsafe","error","console","cardElement","hideToolbar","hideFooter","copyStyles","clone","cloneNode","syncFormState","source","target","sourceInputs","querySelectorAll","targetInputs","el","t","tagName","src","dst","checked","indeterminate","sourceCanvases","targetCanvases","img","ownerDocument","toDataURL","cssText","replaceWith","remove","classList","removeAttribute","flexGrow","styles","links","doc","styleSheets","sheet","rules","cssRules","rule","collectStyles","iframe","finished","finish","parentNode","win","contentWindow","contentDocument","open","write","close","css","printStyle","pageStyle","h1","className","adoptNode","async","waitForImages","timeoutMs","Promise","resolve","images","complete","remaining","timer","onSettled","clearTimeout","addEventListener","once","onBeforePrint","onafterprint","focus","print","run","keyToString","buildGroupTree","groupingFields","columnsByField","emptyLabel","build","items","depth","parentId","path","buckets","getGroupingValue","groupingValueGetter","keyStr","node","parent","groupingField","groupingKey","groupingLabel","childGroups","leaves","descendants","nodes","collectTreeLeaves","roots","root","aggregateRows","aggregationModel","functions","result","fnName","fn","createIcon","rest","viewBox","fill","focusable","ViewColumnIcon","FilterListIcon","SearchIcon","CloseIcon","DownloadIcon","ArrowUpwardIcon","ArrowDownwardIcon","MoreVertIcon","CheckIcon","ExpandMoreIcon","ChevronRightIcon","ChevronLeftIcon","FirstPageIcon","LastPageIcon","PushPinIcon","DeleteIcon","AddIcon","DensitySmallIcon","DensityMediumIcon","DensityLargeIcon","DragIndicatorIcon","PrintIcon","TableChartIcon","DescriptionIcon","VisibilityOffIcon","FunctionsIcon","WorkspacesIcon","EmptyBoxIcon","Fragment","opacity","Button","active","IconButton","Badge","TextInput","Select","Field","htmlFor","Checkbox","forwardedRef","innerRef","setRef","Spinner","role","Popover","anchorEl","onClose","placement","themeMode","autoFocus","ignoreOutsideClickOn","position","setPosition","top","left","ready","update","vw","innerWidth","vh","innerHeight","offsetWidth","offsetHeight","isConnected","getBoundingClientRect","right","bottom","prev","observer","ResizeObserver","observe","removeEventListener","disconnect","handlePointerDown","event","contains","some","closest","handleKeyDown","querySelector","stop","stopPropagation","createPortal","tabIndex","visibility","onClick","onDoubleClick","onMouseDown","onKeyDown","Menu","first","preventDefault","currentIndex","activeElement","MenuItem","selected","disabled","hideMenu","MenuDivider","MenuSection","MGHGridColumnsButton","state","localeText","isOpen","preferencePanel","openedPanelValue","hidePreferences","showPreferences","currentTarget","MGHGridFiltersButton","filterCount","MGHGridDensitySelector","setAnchor","o","density","setDensity","MGHGridExportMenuItem","MGHGridExportMenu","csvOptions","excelOptions","printOptions","showCsvOption","showExcelOption","showPrintOption","customMenuItem","rootProps","customItems","Children","child","isValidElement","cloneElement","resolvedPrintOptions","header","exportDataAsCsv","exportDataAsExcel","exportDataAsPrint","MGHGridQuickFilter","placeholder","debounceMs","alwaysExpanded","externalValue","quickFilterValues","setText","expanded","setExpanded","inputRef","delay","quickFilterDebounceMs","lastExternal","commit","setQuickFilterValues","clear","isExpanded","expand","handleChange","onBlur","blur","MGHGridToolbar","showColumnsButton","showFilterButton","showExportButton","showQuickFilter","showDensitySelector","renderOtherButtons","renderDateRange","quickFilterPlaceholder","showColumns","disableColumnSelector","showFilters","disableColumnFilter","showDensity","disableDensitySelector","MGHGridPagination","page","pageSize","paginationModel","rowCount","pageCount","pageSizeOptions","setPageSize","setPage","MGHGridFooter","selectedCount","rowSelectionModel","showSelected","hideFooterSelectedRowCount","showPagination","pagination","hideFooterPagination","showRowCount","hideFooterRowCount","MGHGridColumnsPanel","visibleColumns","visibleFields","useMemo","search","setSearch","model","columnVisibilityModel","filtered","setAll","visible","setColumnVisibilityModel","setColumnVisibility","useDebouncedValue","onCommit","setLocal","TextValueInput","MultiValueInput","column","joined","multiple","selectedOptions","FilterValueInput","props","operator","InputComponent","Component","applyValue","createFilterItem","MGHGridFilterPanel","filterableColumns","filterModel","logicOperator","targetField","seeded","upsertFilterItem","updateItem","patch","canAddMore","disableMultipleColumnsFiltering","paddingTop","operators","op","showLogic","deleteFilterItem","setFilterLogicOperator","nextColumn","nextOperators","keepOperator","nextOperator","nextIsMulti","currentIsMulti","addItem","setFilterModel","MGHGridColumnMenu","panelAnchorEl","isGroupingColumn","sortItem","sortModel","pinned","isColumnPinned","isGrouped","rowGroupingModel","aggregation","canSort","disableColumnSorting","canFilter","canHide","canPin","disableColumnPinning","canGroup","disableRowGrouping","aggregationFunctions","availableAggregationFunctions","canAggregate","disableAggregation","anchorForPanel","sortColumn","showFilterPanel","transform","pinColumn","unpinColumn","removeRowGroupingCriteria","addRowGroupingCriteria","gap","setAggregationModel","MGHGridNoRowsOverlay","imageSrc","alt","MGHGridLoadingOverlay","MGHGridActionsCellItem","showInMenu","ActionsCell","actions","moreLabel","inline","inMenu","action","EMPTY_ARRAY","EMPTY_OBJECT","EMPTY_MAP","DEFAULT_SORTING_ORDER","DEFAULT_PAGE_SIZE_OPTIONS","DEFAULT_FILTER_MODEL","quickFilterExcludeHiddenColumns","sanitizeStyle","toDateInputValue","pad","padStart","MGHGrid","columnsProp","loading","renderHeaderEndContent","renderHeaderCenterContent","disableCard","cardClassName","boxClassName","cardStyle","cardSx","boxStyle","boxSx","themeVars","showToolbar","toolbarProps","slots","slotProps","noRowsText","localeTextProp","rowHeight","rowHeightProp","columnHeaderHeight","getRowHeight","autoHeight","disableVirtualization","densityProp","onDensityChange","paginationModelProp","onPaginationModelChange","sortModelProp","onSortModelChange","sortingOrder","disableMultipleColumnsSorting","filterModelProp","onFilterModelChange","columnVisibilityModelProp","onColumnVisibilityModelChange","columnVisibilityStorageKey","columnOrderStorageKey","columnWidthStorageKey","pinnedColumnsStorageKey","onColumnOrderChange","onColumnWidthChange","disableColumnResize","disableColumnReorder","pinnedColumns","pinnedColumnsProp","onPinnedColumnsChange","checkboxSelection","checkboxSelectionVisibleOnly","disableRowSelectionOnClick","disableMultipleRowSelection","rowSelectionModelProp","onRowSelectionModelChange","isRowSelectable","keepNonExistentRowsSelected","getRowClassName","onRowClick","onRowDoubleClick","onCellClick","onCellDoubleClick","pinnedRows","getDetailPanelContent","getDetailPanelHeight","detailPanelExpandedRowIds","detailPanelExpandedRowIdsProp","onDetailPanelExpandedRowIdsChange","rowGroupingModelProp","onRowGroupingModelChange","defaultGroupingExpansionDepth","groupingColDef","isGroupExpandedByDefault","aggregationModelProp","onAggregationModelChange","aggregationFunctionsProp","aggregationPosition","processRowUpdate","onProcessRowUpdateError","onCellEditStop","isCellEditable","initialState","apiRef","onStateChange","gridId","reactUseId","useId","useStableId","rootRef","cardRef","scrollerRef","toolbarRef","forceUpdate","setTick","useForceUpdate","latest","getDetails","apiObject","L","apiImpl","rowsById","getRowModels","getAllRowIds","rowEntries","e","getRowNode","nodesById","getSortedRows","sortedLeaves","getVisibleRows","pagedRows","dr","getRowIndexRelativeToVisibleRows","findIndex","updateRows","updates","existing","setRowOverride","orderedUserColumns","visibleUserColumns","getColumn","getColumnIndex","useVisibleColumns","getColumnVisibilityModel","isVisible","setColumnWidth","setColumnIndex","targetIndex","autosizeColumns","side","getPinnedColumns","setPinnedColumns","getSortModel","setSortModel","direction","allowMultipleSorting","getFilterModel","upsertFilterItems","targetColumnField","hideFilterPanel","panel","getSelectedRows","selectedIds","getRowSelectionModel","setRowSelectionModel","normalized","setSelectedIds","selectRow","isSelected","resetSelection","selectRows","isRowSelected","isRowSelectableFn","nextPage","setPaginationModel","nextPageSize","csv","bom","utf8WithBom","Blob","startPrint","toggleDetailPanel","setExpandedDetailPanels","getExpandedDetailPanels","expandedDetailPanels","getRowGroupingModel","setRowGroupingModel","groupingIndex","splice","setRowChildrenExpansion","getRowGroupChildren","groupId","group","groupsById","getAggregationModel","startCellEditMode","stopCellEditMode","ignoreModifications","getCellMode","editing","editingCell","setEditCellValue","setEditValue","getCellParams","buildCellParams","setCellFocus","pendingFocusRef","setFocusedCell","scrollToIndexes","scroll","scroller","scrollLeft","scrollTop","getScrollPosition","rootElementRef","persisted","order","sorting","rowGrouping","controlledExpandedDetail","detailPanel","expandedRowIds","controlledSelection","orderedFields","setOrderedFields","setColumnWidths","dims","dimensions","groupExpansion","setGroupExpansion","setEditingCell","editValue","focusedCell","setPreferencePanel","columnMenu","setColumnMenu","resizingField","setResizingField","printState","setPrintState","printing","drag","setDrag","setScrollTop","scrollRaf","lastClickedIdRef","overrideState","setOverrideState","rowOverrides","viewportWidth","viewportHeight","enabled","setSize","clientWidth","clientHeight","useElementSize","densityFactor","round","headerHeight","userColumns","groupingActive","groupingColumn","single","seen","isColumnVisible","wanted","layout","leftFields","rightFields","visibleByField","center","ordered","computeWidths","available","overrides","Infinity","override","flex","pool","fixedTotal","remainingSpace","remainingFlex","changed","share","fixed","idx","hasPinning","x","leftOffset","isLeft","isRight","isLastLeft","isFirstRight","rightOffset","totalWidth","leftCount","rightCount","allDisplayColumnsByField","activeFilters","quickFilterColumns","filteredEntries","logicAnd","quickAnd","quickFilterLogicOperator","apiRefLocal","quickFns","lowered","getApplyQuickFilterFn","custom","results","compareEntries","sorters","dir","comparator","sortComparator","sortEntries","aggregationActive","isGroupExpanded","leafIds","processed","displayRows","tree","groupingSort","sortGroupTree","compareGroups","sortLeaves","sortLevel","flattenGroupTree","visit","groupNode","toGroupNode","l","childVisible","leaf","leafNode","totalDisplayRows","paginate","ceil","footerAggregates","rowsForFooter","groupAggregatesCache","getGroupAggregates","cached","heights","rowHeights","detailHeights","offsets","hasAuto","dh","virtual","virtualRange","start","end","overscan","viewTop","viewBottom","lo","hi","mid","handleScroll","requestAnimationFrame","cancelAnimationFrame","selectionCandidates","selectedCandidateCount","allCandidatesSelected","someCandidatesSelected","updateSelection","updater","selectionModelsEqual","equal","delete","lastId","toggleAllCandidates","allowMultiple","persistOrder","persistWidths","targets","lc","computed","getComputedStyle","fontFamily","cellFont","headerFont","sample","isCellEditableFn","colDef","rowNode","reason","valueParser","parseEditValue","currentValue","applyRowUpdate","newRow","oldRow","then","rowId","catch","valueSetter","previousGroupingKey","formattedValue","hasFocus","cellMode","isEditable","buildRowParams","preventScroll","visibleTop","visibleBottom","scrollIntoView","colIndex","leftPinnedWidth","rightPinnedWidth","visibleLeft","visibleRight","moveFocus","rowDelta","colDelta","absolute","canReorder","resizeRef","totalRowCount","clamped","oldIndex","moveItem","list","unshift","nextItems","withId","random","toString","contextValue","renderCellContent","renderRow","kind","selectable","content","hideCount","hideDescendantCount","paddingLeft","agg","aggregates","sampleRow","cancel","renderEditCell","onValueChange","renderEditor","renderCell","getActions","cellStyle","pinnedClasses","rowIsClickable","renderRowElement","customClass","indexRelativeToCurrentPage","isFirstVisible","isFirst","isLastVisible","isLast","isAuto","minHeight","handleRowSelectionClick","allSelected","shiftKey","ctrlKey","metaKey","isFocused","isEditing","isAggregation","cellClassName","isCheckbox","isDetailToggle","toRenderRow","renderPinnedRows","renderHeaderCell","sortIndex","showMenu","draggable","isDragging","isDropTarget","overField","menuOpen","headerParams","headerClassName","renderHeader","description","onDragStart","dataTransfer","effectAllowed","setData","onDragOver","sourceLc","dropEffect","rect","clientX","onDragLeave","onDrop","handleDrop","targetLc","without","onDragEnd","onPointerDown","handleResizeStart","startX","startWidth","lastWidth","onMove","onUp","ToolbarSlot","toolbar","FooterSlot","footer","NoRowsOverlaySlot","noRowsOverlay","LoadingOverlaySlot","loadingOverlay","mergedToolbarProps","noRowsProps","loadingProps","showNoRows","menuColumn","cardStyles","boxStyles","rootStyles","scopedCss","smDown","grid","pageRows","onScroll","renderBodyRows","detailHeight","detailContent","detailAuto","rowAuto","Provider","MGH_DATE_RANGE_PICKER_STYLE_ID","MGH_DATE_RANGE_PICKER_CSS","useMGHDateRangePickerStyles","DateRangeIcon","extend","customParseFormat","EMPTY_RANGE","toDayjs","isSameDay","isSame","isBeforeDay","isBefore","isAfterDay","isAfter","isWithinRange","day","isRangeEqual","same","y","normalizeRange","parseDateText","trimmed","strict","fallbacks","validateDay","disablePast","disableFuture","minDate","maxDate","shouldDisableDate","validateRange","startError","endError","isDayDisabled","MGH_DATE_RANGE_DEFAULT_SHORTCUTS","getValue","today","endOf","subtract","defaultDayOfWeekFormatter","toUpperCase","MGHDateRangeCalendar","valueProp","rangePosition","rangePositionProp","onRangePositionChange","calendars","referenceDate","readOnly","showDaysOutsideCurrentMonth","fixedWeekNumber","dayOfWeekFormatter","disableHighlightToday","showRangePreview","onMonthChange","internalValue","setInternalValue","internalPosition","setInternalPosition","setRangePosition","validation","currentMonth","setCurrentMonth","visibleMonths","_","lastVisibleMonth","changeMonth","month","ensureVisible","lastSeenRef","canGoPrev","canGoNext","hoveredDay","setHoveredDay","preview","selectDay","nextPosition","focusedDay","setFocusedDay","focusDay","weekDays","formatter","full","getWeekDayLabels","previewStart","previewEnd","isRangeComplete","onMouseLeave","renderMonth","weeks","getMonthWeeks","firstOfMonth","weeksInMonth","diff","weekCount","weekStart","days","outsideMonth","tabbableDay","previousMonth","nextMonth","wd","week","dayIndex","hidden","isStart","isEnd","inRange","inPreview","dayDisabled","isTabbable","firstVisible","lastVisible","daysInMonth","onMouseEnter","onFocus","MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT","fieldSeparator","openPicker","accept","toolbarTitle","onDismiss","labelledBy","TextField","fullWidth","multi","required","focused","clickable","adornment","ariaLabel","hasLabel","shrink","inputMode","autoComplete","spellCheck","MGHDateRangePicker","onAccept","onError","openProp","onOpen","fieldVariant","clearable","openOnClick","disableOpenPicker","closeOnSelect","shortcuts","idProp","placeholderProp","errorProp","helperText","popoverClassName","popoverStyle","datePlaceholder","isMulti","resolvedOpenOnClick","resolvedCloseOnSelect","includes","reactId","baseId","startId","endId","dialogTitleId","validationError","range","lastErrorRef","setValue","shortcut","context","isOpenControlled","internalOpen","setInternalOpen","valueAtOpenRef","lastAcceptedRef","force","toggleRef","restoreFocusRef","inheritedTheme","setInheritedTheme","attr","parentElement","getAttribute","effectiveThemeMode","setRootRef","closePicker","acceptAndClose","handleDismiss","handleCalendarChange","_day","focusedInput","setFocusedInput","formatSingle","singleText","setSingleText","startText","setStartText","endText","setEndText","inputInvalid","setInputInvalid","parseSegment","invalid","handleSideChange","handleBlur","handleInputKeyDown","altKey","hasValidationError","showError","openButton","clearButton","themeStyle","popoverThemeStyle","shortcutItems","shortcutValue","calendar","commonFieldProps","parts","splitRangeText","ps","pe","handleShortcut","handleAction","Dialog","DialogTitle","pb","DialogContent","DialogActions","GridToolbarExportContainer","GridCsvExportMenuItem","GridExcelExportMenuItem","GridPrintExportMenuItem","useSettingsContext","StyledGridOverlay","fillOpacity","component","mb","p","textAlign","Typography","CircularProgress","exportDataAsPrintTable","headerHtml","bodyHtml","html","cleanup","onload","srcdoc","useMGHGridApiContext","useMGHGridApiRef","useMGHGridLocaleText","query","mediaUp","useMediaQuery","breakpoints","up","mediaDown","down","mediaBetween","between","mediaOnly","only"],"mappings":"2hBAeA,MAAMA,EAAUC,EAAAA,WAA8B,EAAGC,OAAMC,QAAQ,GAAIC,QAAOC,GAASC,IACjFC,EAAAC,cAACC,OAAI,CAACP,KAAMA,EAAMQ,MAAO,CAAEP,MAAO,GAAIQ,OAAQR,GAAS,MAAOC,MCDnDQ,EAAcC,EAAAA,OAAOC,EAAPD,CAAY,EAEnCE,iBAKA,MAAMC,EAAQC,EAAAA,WAERC,EAAmC,UAAvBF,EAAMG,QAAQC,KAE1BC,EAAuC,WAAvBN,EAAWO,QAE3BC,EAAyC,aAAvBR,EAAWO,QAE7BE,EAAqC,SAAvBT,EAAWO,QAEzBG,EAAe,IACQ,YAArBV,EAAWW,OAAuB,IAE9BL,GAAiB,CACjBK,MAAOR,EAAYF,EAAMG,QAAQQ,OAAOC,MAAQZ,EAAMG,QAAQU,KAAK,KACnEC,gBAAiBd,EAAMG,QAAQY,KAAKC,YAGpCT,GAAmB,CACnBO,gBAAiB,cACjBJ,MAAOV,EAAMG,QAAQY,KAAKC,QAC1BC,OAAQ,aAAajB,EAAMG,QAAQY,KAAKC,cAGxCR,GAAe,CACfE,MAAOV,EAAMG,QAAQY,KAAKG,UAC1BJ,gBAAiBK,EAAAA,MAAMnB,EAAMG,QAAQU,KAAK,KAAM,QAKtDO,EAAa,IACU,YAArBrB,EAAWW,OAAuB,IAE9BL,GAAiB,CACjBK,MAAOV,EAAMG,QAAQJ,EAAWW,OAAOW,aACvCP,gBAAiBd,EAAMG,QAAQJ,EAAWW,OAAOY,SAGjDf,GAAmB,CACnBO,gBAAiB,cACjBJ,MAAOV,EAAMG,QAAQJ,EAAWW,OAAOY,KACvCL,OAAQ,aAAajB,EAAMG,QAAQJ,EAAWW,OAAOY,WAGrDd,GAAe,CACfE,MAAOV,EAAMG,QAAQJ,EAAWW,OAAOR,EAAY,OAAS,SAC5DY,gBAAiBK,EAAAA,MAAMnB,EAAMG,QAAQJ,EAAWW,OAAOY,KAAM,QAKzE,MAAO,CACH3B,OAAQ,GACR4B,SAAU,GACVC,WAAY,EACZC,aAAc,EACdC,OAAQ,UACRC,WAAY,SACZC,WAAY,SACZC,QAAS,cACTC,eAAgB,SAChBC,cAAe,aACfC,QAAShC,EAAMiC,QAAQ,EAAG,KAC1BC,SAAUlC,EAAMmC,WAAWC,QAAQ,IACnCC,WAAYrC,EAAMmC,WAAWG,eAC7BC,WAAYvC,EAAMwC,YAAYC,OAAO,MAAO,CACxCC,SAAU1C,EAAMwC,YAAYE,SAASC,aAEtClC,KACAW,KCnFLwB,EAAQ3D,EAAAA,WACZ,EAAG4D,WAAUnC,QAAQ,UAAWJ,UAAU,OAAQwC,YAAWC,UAAS3D,QAAOC,GAASC,KAGpF,MAAM0D,EAAa,CACjB7D,MAAO,GACPQ,OAAQ,GACR,aAAc,CAAER,MAAO,EAAGQ,OAAQ,EAAGsD,UAAW,UAGlD,OACE1D,EAAAC,cAACI,EAAW,CACVN,IAAKA,EAELS,WAAY,CAAEW,QAAOJ,WACrBlB,GAAI,IACE0D,GAAa,CAAEI,GAAI,QACnBH,GAAW,CAAEI,GAAI,QAClB/D,MAGDC,GAEHyD,GAAavD,EAAAC,cAACM,EAAG,CAACV,GAAI,CAAEgE,GAAI,OAASJ,QAAgBF,EAAiB,KAEtED,EAEAE,GAAWxD,EAAAC,cAACM,EAAG,CAACV,GAAI,CAAEiE,GAAI,OAASL,QAAgBD,EAAe,QCdpE,MAAMO,EAAwB,iCACxBC,EAAiB,YACjBC,EAA4B,0BAC5BC,EAAwB,yBACxBC,EAAkB,IAAIC,IAAY,CAACJ,EAAgBC,IAEnDI,EAAkB,CAAEC,QAAS,GAAKC,SAAU,EAAGC,YAAa,KAC5DC,EAAqB,GACrBC,EAAwB,GAExBC,EAA2B,GAK3BC,EAAmBC,GAAkBV,EAAgBW,IAAID,IAAUA,IAAUd,EAM7EgB,EAASC,GAA8CA,QAEvDC,EAAgBD,GAAmBD,EAAMC,IAAoB,KAAVA,GAAiBE,MAAMC,QAAQH,IAA2B,IAAjBA,EAAMI,OAElGC,EAAQA,CAACL,EAAeM,EAAaC,IAAgBC,KAAKF,IAAIE,KAAKD,IAAIP,EAAOM,GAAMC,GAEpFE,EAAKA,IAAIC,IAAyDA,EAAWC,OAAOC,SAASC,KAAK,KAkBlGC,EAAW,MACpB,IAAIC,EAAU,EACd,MAAO,CAACC,EAAS,SACbD,GAAW,EACJ,GAAGC,KAAUD,IAE3B,EANuB,GAYXE,EAAqBA,IAAwB,oBAAXC,aAAyD,IAAxBA,OAAOC,aAE1EC,EAAuBC,IAChC,IAAKJ,IAAsB,OAAO,KAClC,IACI,MAAMjB,EAAQkB,OAAOC,aAAaG,QAAQD,GAC1C,OAAOrB,EAASuB,KAAKC,MAAMxB,GAAe,IAC9C,CAAE,MACE,OAAO,IACX,GAGSyB,EAAoBA,CAACJ,EAAarB,KAC3C,GAAKiB,IACL,IACIC,OAAOC,aAAaO,QAAQL,EAAKE,KAAKI,UAAU3B,GACpD,CAAE,MACE,GAQK4B,EAAkBA,CAAiCC,EAAQC,IACpEA,EAAWA,EAASD,GAAQA,EAAIE,GAEvBC,EAA0BA,CACnCC,EACAC,KAEA,IAAKD,EAAO,MAAO,CAAEE,KAAM,UAAWC,IAAK,IAAIhD,KAC/C,GAAIc,MAAMC,QAAQ8B,GAAQ,MAAO,CAAEE,KAAM,UAAWC,IAAK,IAAIhD,IAAI6C,IACjE,GAAIA,aAAiB7C,IAAK,MAAO,CAAE+C,KAAM,UAAWC,IAAK,IAAIhD,IAAI6C,IACjE,GAAmB,YAAfA,EAAME,MAAsBD,EAAQ,CACpC,MAAME,EAAM,IAAIhD,IAIhB,OAHA8C,EAAOG,QAASN,IACPE,EAAMG,IAAItC,IAAIiC,IAAKK,EAAIE,IAAIP,KAE7B,CAAEI,KAAM,UAAWC,MAC9B,CACA,MAAO,CAAED,KAAM,UAAWC,IAAK,IAAIhD,IAAI6C,EAAMG,OAgBpCG,EAAUvC,IACnB,GAAID,EAAMC,IAAoB,KAAVA,EAAc,OAAO,KACzC,GAAIA,aAAiBwC,KAAM,OAAOC,OAAOC,MAAM1C,EAAM2C,WAAa,KAAO3C,EACzE,GAAI4C,EAAMC,QAAQ7C,GAAQ,OAAOA,EAAM8C,UAAY9C,EAAMuC,SAAW,KACpE,GAAqB,iBAAVvC,EAAoB,CAC3B,MAAM+C,EAAI,IAAIP,KAAKxC,GACnB,OAAOyC,OAAOC,MAAMK,EAAEJ,WAAa,KAAOI,CAC9C,CACA,GAAqB,iBAAV/C,EAAoB,CAC3B,MAAMgD,EAASJ,EAAM5C,GACrB,OAAOgD,EAAOF,UAAYE,EAAOT,SAAW,IAChD,CACA,OAAO,MAGEU,EAAaA,CAACjD,EAAgBkD,KACvC,MAAMC,EAAOZ,EAAOvC,GACpB,OAAKmD,EACEP,EAAMO,GAAMC,OAAOF,EAAW,kBAAoB,YADvC,IAIhBG,EAAcA,CAACF,EAAYD,IAC7BA,EAAWN,EAAMO,GAAMG,QAAQ,UAAUC,UAAYX,EAAMO,GAAMG,QAAQ,OAAOC,UAMvEC,EAAuBC,GACd,iBAAXA,GAAkC,OAAXA,EAErBC,EAAiBA,CAACC,EAAoBF,IAC/CE,EAAID,eAAiBC,EAAID,eAAeD,GAAUD,EAAoBC,GAAUA,EAAOzD,MAAQyD,EAEtFG,EAAiBA,CAACD,EAAoBF,IAC/CE,EAAIC,eAAiBD,EAAIC,eAAeH,GAAUD,EAAoBC,GAAUA,EAAOI,MAAQC,OAAOL,GAE7FM,EAAsBA,CAACJ,EAAoB9B,EAA4BE,IAC3E4B,EAAIK,aAC0B,mBAArBL,EAAIK,aAA8BL,EAAIK,aAAa,CAAEnE,MAAO8D,EAAI9D,MAAOgC,MAAKE,OAAQ4B,EAAIK,aADxE,GAQrBC,EAAeA,CAACpC,EAA2B8B,EAAoBO,KACxE,MAAMC,EAAMtC,EAAMA,EAAI8B,EAAI9D,YAASuE,EACnC,OAAOT,EAAIU,YAAcV,EAAIU,YAAYF,EAAKtC,EAAK8B,EAAKO,GAAOC,GAQtDG,EAAqBA,CAACtE,EAAY2D,EAAoB9B,EAA4BE,KAC3F,GAAIhC,EAAMC,GAAQ,MAAO,GACzB,OAAQ2D,EAAIxB,MACR,IAAK,OACD,OAAOc,EAAWjD,GAAO,GAC7B,IAAK,WACD,OAAOiD,EAAWjD,GAAO,GAC7B,IAAK,UACD,OAAOA,EAAQ,MAAQ,KAC3B,IAAK,eAAgB,CACjB,MACMuE,EADUR,EAAoBJ,EAAK9B,EAAKE,GACxByC,KAAMf,GAAWC,EAAeC,EAAKF,KAAYzD,GACvE,YAAiBoE,IAAVG,EAAsBX,EAAeD,EAAKY,GAAST,OAAO9D,EACrE,CACA,IAAK,SACD,MAAwB,iBAAVA,EAAsByC,OAAOgC,SAASzE,GAAS8D,OAAO9D,GAAS,GAAM8D,OAAO9D,GAC9F,QACI,GAAIA,aAAiBwC,KAAM,OAAOS,EAAWjD,GAAO,GACpD,GAAqB,iBAAVA,EACP,IACI,OAAOuB,KAAKI,UAAU3B,EAC1B,CAAE,MACE,OAAO8D,OAAO9D,EAClB,CAEJ,OAAO8D,OAAO9D,KAIb0E,EAAoBA,CAC7B1E,EACA6B,EACA8B,EACAO,EACAnC,IAEI4B,EAAIgB,eAAuBhB,EAAIgB,eAAe3E,EAAO6B,EAAK8B,EAAKO,GAC5DI,EAAmBtE,EAAO2D,EAAK9B,EAAKE,GAGlC6C,EAA0BC,GAC/B9E,EAAM8E,GAAmB,GACJ,iBAAdA,EAA+BA,EACjB,iBAAdA,GAA+C,kBAAdA,EAAgCf,OAAOe,GAC/EA,aAAqBrC,KAAaS,EAAW4B,GAAW,GACnC,iBAAdA,GAA0B,UAAWA,EAAkB,GAC3Df,OAAOe,GA2BZC,EAA2B,oBAATC,KAAuB,IAAIA,KAAKC,cAASZ,EAAW,CAAEa,SAAS,EAAMC,YAAa,SAAY,KAEhHC,EAAWA,CAACC,EAASC,KACvB,MAAMC,EAAKvF,EAAMqF,IAAc,KAAPA,EAClBG,EAAKxF,EAAMsF,IAAc,KAAPA,EACxB,OAAIC,GAAMC,EAAW,EACjBD,GAAW,EACXC,EAAW,EACR,MAGEC,EAAwCA,CAACJ,EAAIC,KACtD,MAAMI,EAAMN,EAASC,EAAIC,GACzB,OAAY,OAARI,EAAqBA,EAClBhD,OAAO2C,GAAM3C,OAAO4C,IAGlBK,EAAwCA,CAACN,EAAIC,KACtD,MAAMI,EAAMN,EAASC,EAAIC,GACzB,GAAY,OAARI,EAAc,OAAOA,EACzB,MAAME,EAAK7B,OAAOsB,GACZQ,EAAK9B,OAAOuB,GAClB,OAAIP,EAAiBA,EAASe,QAAQF,EAAIC,GACnCD,EAAKC,GAAK,EAAKD,EAAKC,EAAK,EAAI,GAG3BE,GAAgDA,CAACV,EAAIC,EAAIU,EAAIC,IACpD,iBAAPZ,GAAiC,iBAAPC,EAAwBG,EAAiBJ,EAAIC,GAC3EK,EAAiBN,EAAIC,GAGnBY,GAAsCA,CAACb,EAAIC,KACpD,MAAMa,EAAK3D,EAAO6C,GACZe,EAAK5D,EAAO8C,GACZI,EAAMN,EAASe,EAAIC,GACzB,OAAY,OAARV,EAAqBA,EACjBS,EAAYvD,UAAawD,EAAYxD,WAGpCyD,GAAyCA,CAAChB,EAAIC,KACvD,MAAMI,EAAMN,EAASC,EAAIC,GACzB,OAAY,OAARI,EAAqBA,EAClBhD,OAAO7B,QAAQwE,IAAO3C,OAAO7B,QAAQyE,KAGnCgB,GAAwBlE,IACjC,OAAQA,GACJ,IAAK,SACD,OAAOqD,EACX,IAAK,OACL,IAAK,WACD,OAAOS,GACX,IAAK,UACD,OAAOG,GACX,QACI,OAAON,KAQbQ,GAAStG,GAAoBD,EAAMC,GAAS,GAAK8D,OAAO9D,GAAOuG,cAE/DC,GAAYC,IAA6BxG,EAAawG,EAAKzG,OAEpD0G,GAAiD,CAC1D,CACI1G,MAAO,WACP6D,MAAO,WACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAKzG,OAC1B,OAAQA,IAA2C,IAAjCsG,GAAMtG,GAAO8G,QAAQD,KAG/C,CACI7G,MAAO,iBACP6D,MAAO,mBACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAKzG,OAC1B,OAAQA,IAA2C,IAAjCsG,GAAMtG,GAAO8G,QAAQD,KAG/C,CACI7G,MAAO,SACP6D,MAAO,SACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAKzG,OAC1B,OAAQA,GAAUsG,GAAMtG,KAAW6G,IAG3C,CACI7G,MAAO,eACP6D,MAAO,iBACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAKzG,OAC1B,OAAQA,GAAUsG,GAAMtG,KAAW6G,IAG3C,CACI7G,MAAO,aACP6D,MAAO,cACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAKzG,OAC1B,OAAQA,GAA2C,IAAjCsG,GAAMtG,GAAO8G,QAAQD,KAG/C,CACI7G,MAAO,WACP6D,MAAO,YACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAKzG,OAC1B,OAAQA,IACJ,MAAM+G,EAAIT,GAAMtG,GAChB,OAAO+G,EAAE3G,QAAUyG,EAAOzG,QAAU2G,EAAEC,YAAYH,KAAYE,EAAE3G,OAASyG,EAAOzG,UAI5F,CACIJ,MAAO,UACP6D,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAO5G,GAAUC,EAAaD,IAEpD,CACIA,MAAO,aACP6D,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAO5G,IAAWC,EAAaD,IAErD,CACIA,MAAO,UACP6D,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAKvG,MAAMC,QAAQsG,EAAKzG,QAAgC,IAAtByG,EAAKzG,MAAMI,OAAc,OAAO,KAClE,MAAM8G,EAAM,IAAI9H,IAAIqH,EAAKzG,MAAMmH,IAAIb,KACnC,OAAQtG,GAAUkH,EAAIpH,IAAIwG,GAAMtG,OAKtCoH,GAAiBA,CACnBpH,EACA6D,EACAgC,KAAkD,CAElD7F,QACA6D,QACA8C,UAAW,SACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMY,EAAc5E,OAAOgE,EAAKzG,OAChC,OAAIyC,OAAOC,MAAM2E,GAAqB,KAC9BC,IACJ,GAAIvH,EAAMuH,IAAkB,KAATA,EAAa,OAAO,EACvC,MAAMC,EAAI9E,OAAO6E,GACjB,OAAQ7E,OAAOC,MAAM6E,IAAM1B,EAAQ0B,EAAGF,OAKrCG,GAAiD,CAC1DJ,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,IAAMC,GACzCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,IAAMC,GAC3CN,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,EAAIC,GACvCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,GAAKC,GAC1CN,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,EAAIC,GACvCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,GAAKC,GAC1C,CACI1H,MAAO,UACP6D,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAO5G,GAAUC,EAAaD,IAEpD,CACIA,MAAO,aACP6D,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAO5G,IAAWC,EAAaD,IAErD,CACIA,MAAO,UACP6D,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAKvG,MAAMC,QAAQsG,EAAKzG,QAAgC,IAAtByG,EAAKzG,MAAMI,OAAc,OAAO,KAClE,MAAM8G,EAAM,IAAI9H,IAAIqH,EAAKzG,MAAMmH,IAAKQ,GAAWlF,OAAOkF,KACtD,OAAQ3H,IAAWD,EAAMC,IAAUkH,EAAIpH,IAAI2C,OAAOzC,OAKxD4H,GAAeA,CACjB5H,EACA6D,EACAX,EACA2C,KAAkD,CAElD7F,QACA6D,QACA8C,UAAWzD,EAAW,iBAAmB,OACzC0D,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMoB,EAAatF,EAAOkE,EAAKzG,OAC/B,IAAK6H,EAAY,OAAO,KACxB,MAAMC,EAAazE,EAAYwE,EAAY3E,GAC3C,OAAQoE,IACJ,MAAMS,EAAWxF,EAAO+E,GACxB,QAAKS,GACElC,EAAQxC,EAAY0E,EAAU7E,GAAW4E,OAK/CE,GAA0B9E,GAA+C,CAClF0E,GAAa,KAAM,KAAM1E,EAAU,CAACuE,EAAGC,IAAMD,IAAMC,GACnDE,GAAa,MAAO,SAAU1E,EAAU,CAACuE,EAAGC,IAAMD,IAAMC,GACxDE,GAAa,QAAS,WAAY1E,EAAU,CAACuE,EAAGC,IAAMD,EAAIC,GAC1DE,GAAa,YAAa,iBAAkB1E,EAAU,CAACuE,EAAGC,IAAMD,GAAKC,GACrEE,GAAa,SAAU,YAAa1E,EAAU,CAACuE,EAAGC,IAAMD,EAAIC,GAC5DE,GAAa,aAAc,kBAAmB1E,EAAU,CAACuE,EAAGC,IAAMD,GAAKC,GACvE,CACI1H,MAAO,UACP6D,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAO5G,GAA4B,OAAlBuC,EAAOvC,IAE9C,CACIA,MAAO,aACP6D,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAO5G,GAA4B,OAAlBuC,EAAOvC,KAIrCiI,GAAkD,CAC3D,CACIjI,MAAO,KACP6D,MAAO,KACP8C,UAAW,UACXC,iBAAmBH,IACf,GAAI1G,EAAM0G,EAAKzG,QAAyB,KAAfyG,EAAKzG,OAA+B,QAAfyG,EAAKzG,MAAiB,OAAO,KAC3E,MAAMkI,GAA0B,IAAfzB,EAAKzG,OAAiC,SAAfyG,EAAKzG,MAC7C,OAAQA,GAAUY,QAAQZ,KAAWkI,KAKpCC,GAAuD,CAChE,CACInI,MAAO,KACP6D,MAAO,KACP8C,UAAW,SACXC,iBAAmBH,GACX1G,EAAM0G,EAAKzG,QAAyB,KAAfyG,EAAKzG,MAAqB,KAC3CA,GAAU8D,OAAO9D,KAAW8D,OAAO2C,EAAKzG,QAGxD,CACIA,MAAO,MACP6D,MAAO,SACP8C,UAAW,SACXC,iBAAmBH,GACX1G,EAAM0G,EAAKzG,QAAyB,KAAfyG,EAAKzG,MAAqB,KAC3CA,GAAU8D,OAAO9D,KAAW8D,OAAO2C,EAAKzG,QAGxD,CACIA,MAAO,UACP6D,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAKvG,MAAMC,QAAQsG,EAAKzG,QAAgC,IAAtByG,EAAKzG,MAAMI,OAAc,OAAO,KAClE,MAAM8G,EAAM,IAAI9H,IAAIqH,EAAKzG,MAAMmH,IAAIrD,SACnC,OAAQ9D,GAAUkH,EAAIpH,IAAIgE,OAAO9D,OAwBhCoI,GAA4BzE,GAAuBA,EAAI0E,iBAnB1BlG,KACtC,OAAQA,GACJ,IAAK,SACD,OAAOqF,GACX,IAAK,OACD,OAAOQ,IAAuB,GAClC,IAAK,WACD,OAAOA,IAAuB,GAClC,IAAK,UACD,OAAOC,GACX,IAAK,eACD,OAAOE,GACX,IAAK,UACD,MAAO,GACX,QACI,OAAOzB,KAIoE4B,CAA0B3E,EAAIxB,MAMxGoG,GAAmD5E,IAC5D,MAAMxB,EAAOwB,EAAIxB,MAAQ,SACnBqG,EAAoB,WAATrG,EACXsG,EAAqB,YAATtG,EACZuG,EAAqB,YAATvG,EAClB,MAAO,IACAwB,EACHxB,OACAwG,WAAYhF,EAAIgF,YAAchF,EAAI9D,MAClCjF,MAAO+I,EAAI/I,OAAsB,IACjCoC,SAAU2G,EAAI3G,UAAY2C,EAC1BiJ,MAAOjF,EAAIiF,QAAUJ,EAAW,QAAUC,GAAaC,EAAY,SAAW,QAC9EG,YAAalF,EAAIkF,aAAelF,EAAIiF,QAAUJ,EAAW,QAAUC,GAAaC,EAAY,SAAW,QACvGI,UAAUJ,IAAqB/E,EAAImF,WAAY,GAC/CC,YAAYL,IAAqB/E,EAAIoF,aAAc,GACnDC,SAAUrF,EAAIqF,WAAY,EAC1BC,UAAWtF,EAAIsF,YAAa,EAC5BC,SAAUvF,EAAIuF,WAAY,EAC1BC,WAAWT,IAAqB/E,EAAIwF,YAAa,GACjDC,YAAYV,IAAqB/E,EAAIyF,aAAc,GACnDC,SAAU1F,EAAI0F,WAAY,EAC1BC,kBAAmB3F,EAAI2F,mBAAqBZ,EAC5Ca,cAAe5F,EAAI4F,eAAiBb,IAQtCc,GAAiBA,CAAC3J,EAAejF,IACnC2N,GAAgB,CACZ1I,QACA8I,WAAY,GACZ/N,QACAoC,SAAUpC,EACV6O,SAAU7O,EACVkO,UAAU,EACVC,YAAY,EACZC,UAAU,EACVC,WAAW,EACXC,UAAU,EACVC,WAAW,EACXC,YAAY,EACZE,mBAAmB,EACnBC,eAAe,EACfG,gBAAgB,EAChBd,MAAO,SACPC,YAAa,WAIRc,GAAqCH,GAAexK,EAjmB5B,IAmmBxB4K,GAAgDJ,GACzDvK,EAnmBsC,IA2mBpC4K,GAAsB,IAAIzK,IAAI,CAChC,0BACA,oBACA,mBACA,mBACA,UACA,eACA,kBACA,cACA,UACA,OACA,WACA,eACA,aACA,eACA,YACA,WACA,UACA,aACA,cACA,eACA,aACA,gBACA,iBACA,kBACA,aACA,YACA,aACA,UACA,QACA,UACA,UACA,SACA,SACA,OACA,cACA,eACA,cACA,kBACA,mBACA,mBACA,gBACA,gBAIS0K,GAAiBzI,GAAgB,mBAAmB0I,KAAK1I,GAahE2I,GAAyBC,GAC3BC,OAAOC,KAAKF,GACPtJ,OAAQU,IACL,MAAMrB,EAAQiK,EAAM5I,GACpB,OAAQyI,GAAczI,KAA0B,iBAAVrB,GAAuC,iBAAVA,KAEtEmH,IAAK9F,IAAQ,SAjBD+I,KACjB,GAA+B,IAA3BA,EAAStD,QAAQ,MAAa,OAAOsD,EACzC,MAAMC,EAAQD,EAASE,QAAQ,SAAWC,GAAM,IAAIA,EAAEhE,iBACtD,OAAgC,IAAzB8D,EAAMvD,QAAQ,OAAe,IAAIuD,IAAUA,GAc7BG,CAAYnJ,MAXb+I,EAWoC/I,EAXlBrB,EAWuBiK,EAAM5I,GAVlD,iBAAVrB,GAAgC,IAAVA,GAAgB6J,GAAoB/J,IAAIsK,IAAwC,IAA3BA,EAAStD,QAAQ,MAE7FhD,OAAO9D,GADP,GAAGA,QAFUyK,IAACL,EAAkBpK,IAYjCa,KAAK,KAcD6J,GAAiBA,CAACC,EAAe9P,EAAyC+P,EAAgB,KAC9F/P,GACLqP,OAAOC,KAAKtP,GAAIwH,QAAShB,IACrB,MAAMrB,EAAQnF,EAAGwG,GACjB,IAAKrB,GAA0B,iBAAVA,EAAoB,OACzC,MAAMiK,EAAQjK,EACd,GAAsB,MAAlBqB,EAAIwJ,OAAO,GAAY,CACvB,MAAMC,EAAkB,GAClBC,EAAef,GAAsBC,GAI3C,OAHIc,GAAcD,EAAME,KAAK,GAAGL,KAASI,MACzCL,GAAeC,EAAOV,EAAOa,QACzBA,EAAM1K,QAAQwK,EAAII,KAAK,GAAG3J,KAAOyJ,EAAMjK,KAAK,QAEpD,CACA,MAAMoK,EA1BQC,EAACP,EAAeM,IAClCA,EACKE,MAAM,KACNhE,IAAKiE,GAASA,EAAKC,QACnB1K,OAAOC,SACPuG,IAAKiE,IAAgC,IAAtBA,EAAKtE,QAAQ,KAAcsE,EAAKd,QAAQ,KAAMK,GAAS,GAAGA,KAASS,KAClFvK,KAAK,KAoBWqK,CAAcP,EAAOtJ,GAChC0J,EAAef,GAAsBC,GACvCc,GAAcH,EAAII,KAAK,GAAGC,KAAYF,MAC1CL,GAAeO,EAAUhB,EAAOW,KAE7BA,GAlBSA,EAyBdU,GAAiBC,GACnBA,EAAOpE,IAAKQ,GAAoB,iBAANA,EAAiBA,EAAIlF,OAAOkF,IAAKhH,OAAQ4G,IAAO9E,OAAOC,MAAM6E,IAAY,OAANA,GAEpFiE,GAA6E,CACtFC,IAAK,CACD5H,MAAO,MACP6H,YAAa,CAAC,UACdC,MAAOA,EAAGJ,aACN,MAAMK,EAAON,GAAcC,EAAO5K,OAAQgH,IAAO5H,EAAM4H,IAAY,KAANA,IAC7D,OAAoB,IAAhBiE,EAAKxL,OAAqB,KACvBwL,EAAKC,OAAO,CAACC,EAAKvE,IAAMuE,EAAMvE,EAAG,KAGhDwE,IAAK,CACDlI,MAAO,MACP6H,YAAa,CAAC,UACdC,MAAOA,EAAGJ,aACN,MAAMK,EAAON,GAAcC,EAAO5K,OAAQgH,IAAO5H,EAAM4H,IAAY,KAANA,IAC7D,OAAoB,IAAhBiE,EAAKxL,OAAqB,KACvBwL,EAAKC,OAAO,CAACC,EAAKvE,IAAMuE,EAAMvE,EAAG,GAAKqE,EAAKxL,SAG1DE,IAAK,CACDuD,MAAO,MACP6H,YAAa,CAAC,SAAU,OAAQ,YAChCC,MAAOA,EAAGJ,aACN,MAAMS,EAAUT,EAAO5K,OAAQgH,IAAO5H,EAAM4H,IAAY,KAANA,GAClD,GAAuB,IAAnBqE,EAAQ5L,OAAc,OAAO,KACjC,GAAI4L,EAAQC,MAAOtE,GAAmB,iBAANA,GAAiB,OAAOnH,KAAKF,OAAQ0L,GACrE,MAAME,EAAQF,EAAQ7E,IAAI5E,GAC1B,OAAI2J,EAAMD,MAAOlJ,GAAY,OAANA,GACZ,IAAIP,KAAKhC,KAAKF,OAAO4L,EAAM/E,IAAKpE,GAAOA,EAAWJ,aAEtDqJ,EAAQG,QAAQC,KAAK,CAAC3E,EAAGC,IAAMhC,EAAiB+B,EAAGC,IAA8B,KAGhGnH,IAAK,CACDsD,MAAO,MACP6H,YAAa,CAAC,SAAU,OAAQ,YAChCC,MAAOA,EAAGJ,aACN,MAAMS,EAAUT,EAAO5K,OAAQgH,IAAO5H,EAAM4H,IAAY,KAANA,GAClD,GAAuB,IAAnBqE,EAAQ5L,OAAc,OAAO,KACjC,GAAI4L,EAAQC,MAAOtE,GAAmB,iBAANA,GAAiB,OAAOnH,KAAKD,OAAQyL,GACrE,MAAME,EAAQF,EAAQ7E,IAAI5E,GAC1B,GAAI2J,EAAMD,MAAOlJ,GAAY,OAANA,GACnB,OAAO,IAAIP,KAAKhC,KAAKD,OAAO2L,EAAM/E,IAAKpE,GAAOA,EAAWJ,aAE7D,MAAM0J,EAASL,EAAQG,QAAQC,KAAK,CAAC3E,EAAGC,IAAMhC,EAAiB+B,EAAGC,IAClE,OAAO2E,EAAOA,EAAOjM,OAAS,KAGtCkM,KAAM,CACFzI,MAAO,OACP8H,MAAOA,EAAGJ,YAAaA,EAAOnL,SAQzBmM,GAAyC,CAClDC,YAAa,UACbC,aAAc,WACdC,eAAgB,UAChBC,eAAgB,UAChBC,cAAe,SACfC,eAAgB,UAChBC,8BAA+B,YAC/BC,wBAAyB,SACzBC,iBAAkB,kBAClBC,mBAAoB,oBACpBC,mBAAoB,QACpBC,eAAgB,UAChBC,gBAAiB,WACjBC,mBAAoB,cACpBC,8BAA+B,SAC/BC,oBAAqB,WACrBC,oBAAqB,WACrBC,kBAAmB,QACnBC,qBAAsB,aACtBC,qBAAsB,aACtBC,sBAAuB,SACvBC,mBAAoB,UACpBC,oBAAqB,WACrBC,iBAAkB,QAClBC,4BAA6B,eAC7BC,yBAA0B,iBAC1BC,uBAAwB,MACxBC,sBAAuB,KACvBC,kBAAmB,cACnBC,mBAAoB,eACpBC,iBAAkB,SAClBC,iBAAkB,SAClBC,qBAAsB,cACtBC,wBAAyB,iBACzBC,kBAAmB,cACnBC,mBAAoB,eACpBC,gBAAiB,QACjBC,gBAAkBC,GAAS,YAAYA,IACvCC,kBAAoBD,GAAS,oBAAoBA,IACjDE,sBAAuB,cACvBC,0BAA2B,cAC3BC,6BAA8B,OAC9BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,6BAA8B,OAC9BC,kBAAoBC,GAAqB,IAAVA,EAAc,iBAAmB,GAAGA,EAAMC,iCACzEC,gBAAiB,cACjBC,4BAA6B,iBAC7BC,8BAA+BA,CAACC,EAAMC,EAAIN,IAAU,GAAGK,KAAQC,QAASN,EAAMC,mBAC9EM,0BAA2B,aAC3BC,6BAA8B,gBAC9BC,yBAA0B,YAC1BC,yBAA0B,YAC1BC,4BAA6B,qBAC7BC,+BAAgC,kBAChCC,iCAAkC,oBAClCC,2BAA4B,aAC5BC,6BAA8B,eAC9BC,qBAAsB,MACtBC,sBAAuB,KACvBC,kBAAmB,sBACnBC,kBAAmB,SACnBC,oBAAqB,WACrBC,yBAA0B,QAC1BC,YAAcjC,GAAS,YAAYA,IACnCkC,cAAgBlC,GAAS,oBAAoBA,IAC7CmC,gBAAiB,OACjBC,0BAA2B,OAC3BC,gBAAiB,OACjBC,YAAa,gBAOjB,IAAIC,GAEG,MAAMC,GAAcA,CAAC9U,EAAc+U,KACtC,GAAwB,oBAAbC,SAA0B,OAAqB,EAAdhV,EAAK4D,OACjD,QAAuBgE,IAAnBiN,GAA8B,CAC9B,MAAMI,EAASD,SAASvW,cAAc,UACtCoW,GAAiBI,EAAOC,WAAW,KACvC,CACA,OAAKL,IACLA,GAAeE,KAAOA,EACfF,GAAeC,YAAY9U,GAAM5B,OAFE,EAAd4B,EAAK4D,QASxBuR,GAAeA,CAACC,EAAYC,KACrC,GAAwB,oBAAbL,SAA0B,OACrC,MAAMM,EAAMC,IAAIC,gBAAgBJ,GAC1BK,EAAST,SAASvW,cAAc,KACtCgX,EAAOC,KAAOJ,EACdG,EAAOE,SAAWN,EAClBI,EAAO9W,MAAMmC,QAAU,OACvBkU,SAASY,KAAKC,YAAYJ,GAC1BA,EAAOK,QACPpR,OAAOqR,WAAW,KACdf,SAASY,KAAKI,YAAYP,GAC1BF,IAAIU,gBAAgBX,IACrB,IC95BMY,GAAoB,kBAQpBC,GAAe,mj1BA+T5B,IAAIC,IAAW,EAEf,MAcMC,GACD7X,EAAc8X,qBAAyC,oBAAX5R,OAAyBlG,EAAM+X,gBAAkB/X,EAAMgY,WAG3FC,GAAmBA,KAC5BJ,GAAa,KAnBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAeT,IAExB,YADAE,IAAW,GAGf,MAAMzX,EAAQqW,SAASvW,cAAc,SACrCE,EAAM4G,GAAK2Q,GACXvX,EAAMiY,aAAa,gBAAiB,QACpCjY,EAAMkY,YAAcV,GACpBnB,SAAS8B,KAAKjB,YAAYlX,GAC1ByX,IAAW,GASPM,IACD,KCpTMK,GAAiBvY,EAAMwY,cAA0C,MAC9ED,GAAeE,YAAc,iBAEtB,MAAMC,GAAoBA,KAC7B,MAAMC,EAAM3Y,EAAM4Y,WAAWL,IAC7B,IAAKI,EACD,MAAM,IAAIE,MAAM,yFAEpB,OAAOF,GCjDL,SAAUG,GAAgB9T,GAC5B,MAAMjF,EAAMC,EAAM+Y,OAAO/T,GAEzB,OADAjF,EAAIiZ,QAAUhU,EACPjF,CACX,UAYgBkZ,GACZC,EACAC,EACAC,GAEA,MAAMC,OAA8BjQ,IAAf8P,GACdI,EAAUC,GAAevZ,EAAMwZ,SAAYL,GAC5CnU,EAAQqU,EAAgBH,EAAmBI,EAC3CG,EAAWX,GAAa9T,GACxB0U,EAAgBZ,GAAaO,GAC7BM,EAAcb,GAAaM,GAUjC,MAAO,CAACpU,EARShF,EAAM4Z,YAAaC,IAChC,MAAMC,EAA2B,mBAATD,EAAuBA,EAAwBJ,EAAST,SAAWa,EACvF3K,OAAO6K,GAAGD,EAAUL,EAAST,WACjCS,EAAST,QAAUc,EACdJ,EAAcV,SAASO,EAAYO,GACxCH,EAAYX,UAAUc,KACvB,IAGP,CAmFA,IAAIE,GAAY,ECxFT,MAeMC,GAAmBA,CAAC/Q,EAAiBgR,KAC9C,MAAMC,EAhB0BC,EAAClR,EAAiBgR,KAClD,MAAMG,EAAMnR,EAAIoR,gBAChB,IAAIH,EACJ,GAAID,EAAQK,OAAQ,CAChB,MAAMC,EAAU,IAAIC,IACpBJ,EAAIhT,QAASqT,GAAMF,EAAQtO,IAAIwO,EAAE7V,MAAO6V,IACxCP,EAAUD,EAAQK,OAAOpO,IAAKwO,GAAMH,EAAQI,IAAID,IAAIhV,OAAOC,QAC/D,MACIuU,EADOD,EAAQW,WACLR,EAEAnR,EAAI4R,oBAElB,OAAOX,EAAQxU,OAAQ+U,IAAOA,EAAEnM,gBAAkB3J,EAAgB8V,EAAE7V,QAAqB,YAAX6V,EAAEvT,OAIhEiT,CAAqBlR,EAAKgR,GACpC9S,EAAsB8S,EAAQa,gBAAkBb,EAAQa,gBAAgB,CAAE7R,QAASA,EAAI8R,kBACvFC,EAAuB,GAY7B,OAXA7T,EAAIC,QAASN,IACT,MAAMF,EAAMqC,EAAIgS,OAAOnU,GAClBF,GACLoU,EAAKjL,KACDmK,EAAQhO,IAAKxD,IACT,MAAMQ,EAAMF,EAAapC,EAAK8B,EAAKO,GAEnC,MAAO,CAAEC,MAAKU,UADID,EAAuBF,EAAkBP,EAAKtC,EAAK8B,EAAKO,EAAKnC,IACtD4B,YAI9B,CAAEwR,UAASgB,QAAShB,EAAQhO,IAAKuO,GAAMA,EAAE/M,YAAc+M,EAAE7V,OAAQoW,SAGtEG,GAAmBA,CAACtH,EAA0BuH,EAAkBC,KAClE,MAAMC,EAAQzH,GAAQA,EAAKzD,QAAWgL,EACtC,OAAOE,EAAKhQ,cAAciQ,SAAS,IAAIF,KAAeC,EAAO,GAAGA,KAAQD,KAGtEG,GAAkBA,MACc,oBAAbjF,UAA4BA,SAASkF,MAAQlF,SAASkF,MAAMrL,OAAS,KACzE,UAAUf,QAAQ,iBAAkB,KAOnDqM,GAAgBA,CAAC3W,EAAe4W,KAClC,IAAIpa,EAAOwD,EAGX,MADI,eAAe+J,KAAKvN,KAAOA,EAAO,IAAIA,MAChB,IAAtBA,EAAKsK,QAAQ,OAA2C,IAA5BtK,EAAKsK,QAAQ8P,IAAqB,SAAS7M,KAAKvN,GACrE,IAAIA,EAAK8N,QAAQ,KAAM,SAE3B9N,GAGEqa,GAAeA,CAAC3S,EAAiBgR,EAAmC,MAC7E,MAAM0B,EAAY1B,EAAQ0B,WAAa,IACjCE,EAAiB5B,EAAQ4B,iBAAkB,EAC3CC,EAAQ9B,GAAiB/Q,EAAKgR,GAC9B8B,EAAkB,GAcxB,OAbIF,GACAE,EAAMhM,KAAK+L,EAAMZ,QAAQhP,IAAK8P,GAAMN,GAAcM,EAAGL,IAAY/V,KAAK+V,IAE1EG,EAAMd,KAAK5T,QAAS6U,IAChBF,EAAMhM,KACFkM,EACK/P,IAAKG,IACF,MAAM9K,EAAO0Y,EAAQiC,aAAgBpX,EAAMuH,EAAKnD,KAAO,GAAKL,OAAOwD,EAAKnD,KAAQmD,EAAKzC,UACrF,OAAO8R,GAAcna,EAAMoa,KAE9B/V,KAAK+V,MAGXI,EAAMnW,KAAK,SAGhBuW,GAAWtT,OAAOuT,aAAa,OAa/BC,GAAY,MACd,MAAMP,EAAQ,IAAIQ,YAAY,KAC9B,IAAK,IAAIhQ,EAAI,EAAGA,EAAI,IAAKA,GAAK,EAAG,CAC7B,IAAImO,EAAInO,EACR,IAAK,IAAIiQ,EAAI,EAAGA,EAAI,EAAGA,GAAK,EACxB9B,EAAQ,EAAJA,EAAQ,WAAcA,IAAM,EAAKA,IAAM,EAE/CqB,EAAMxP,GAAKmO,IAAM,CACrB,CACA,OAAOqB,CACV,EAViB,GAoBZU,GAAqC,oBAAhBC,YAA8B,IAAIA,YAAgB,KAEvEC,GAAcnb,IAChB,GAAIib,GAAa,OAAOA,GAAYG,OAAOpb,GAE3C,MAAMqb,EAAOC,SAASC,mBAAmBvb,IACnCoO,EAAM,IAAIoN,WAAWH,EAAKzX,QAChC,IAAK,IAAI6X,EAAI,EAAGA,EAAIJ,EAAKzX,OAAQ6X,GAAK,EAAGrN,EAAIqN,GAAKJ,EAAKK,WAAWD,GAClE,OAAOrN,GAQLuN,GAAeC,IACjB,MAAMC,EAAQD,EAAOvM,OAAO,CAACC,EAAK4J,IAAM5J,EAAM4J,EAAEtV,OAAQ,GAClDwK,EAAM,IAAIoN,WAAWK,GAC3B,IAAIC,EAAS,EAKb,OAJAF,EAAO/V,QAASqT,IACZ9K,EAAI1D,IAAIwO,EAAG4C,GACXA,GAAU5C,EAAEtV,SAETwK,GAGL2N,GAAYC,IACd,MAAMC,EAA4B,GAC5BC,EAA8B,GACpC,IAAIJ,EAAS,EAKbE,EAAQnW,QAASsW,IACb,MAAMC,EAAYjB,GAAWgB,EAAM7J,MAC7B+J,EA7CCC,KACX,IAAID,EAAM,WACV,IAAK,IAAIZ,EAAI,EAAGA,EAAIa,EAAM1Y,OAAQ6X,GAAK,EACnCY,EAAMvB,GAA6B,KAAlBuB,EAAMC,EAAMb,KAAeY,IAAQ,EAExD,OAAc,WAANA,KAAsB,GAwCdE,CAAMJ,EAAMK,MAClB1M,EAAOqM,EAAMK,KAAK5Y,OAElB6Y,EAAQ,IAAIjB,WAAW,GAAKY,EAAUxY,QACtC8Y,EAAK,IAAIC,SAASF,EAAMG,QAC9BF,EAAGG,UAAU,EAAG,UAAY,GAC5BH,EAAGI,UAAU,EAAG,IAAI,GACpBJ,EAAGI,UAAU,EAAG,MAAQ,GACxBJ,EAAGI,UAAU,EAAG,GAAG,GACnBJ,EAAGI,UAAU,GAdD,GAcc,GAC1BJ,EAAGI,UAAU,GAdA,IAca,GAC1BJ,EAAGG,UAAU,GAAIR,GAAK,GACtBK,EAAGG,UAAU,GAAI/M,GAAM,GACvB4M,EAAGG,UAAU,GAAI/M,GAAM,GACvB4M,EAAGI,UAAU,GAAIV,EAAUxY,QAAQ,GACnC8Y,EAAGI,UAAU,GAAI,GAAG,GACpBL,EAAM/R,IAAI0R,EAAW,IAErB,MAAMW,EAAU,IAAIvB,WAAW,GAAKY,EAAUxY,QACxCoZ,EAAK,IAAIL,SAASI,EAAQH,QAChCI,EAAGH,UAAU,EAAG,UAAY,GAC5BG,EAAGF,UAAU,EAAG,IAAI,GACpBE,EAAGF,UAAU,EAAG,IAAI,GACpBE,EAAGF,UAAU,EAAG,MAAQ,GACxBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GA9BD,GA8Bc,GAC1BE,EAAGF,UAAU,GA9BA,IA8Ba,GAC1BE,EAAGH,UAAU,GAAIR,GAAK,GACtBW,EAAGH,UAAU,GAAI/M,GAAM,GACvBkN,EAAGH,UAAU,GAAI/M,GAAM,GACvBkN,EAAGF,UAAU,GAAIV,EAAUxY,QAAQ,GACnCoZ,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGH,UAAU,GAAI,GAAG,GACpBG,EAAGH,UAAU,GAAIf,GAAQ,GACzBiB,EAAQrS,IAAI0R,EAAW,IAEvBH,EAAYzN,KAAKiO,EAAON,EAAMK,MAC9BN,EAAc1N,KAAKuO,GACnBjB,GAAUW,EAAM7Y,OAASkM,IAG7B,MAAMmN,EAAmBtB,GAAYO,GAC/BgB,EAAO,IAAI1B,WAAW,IACtB2B,EAAK,IAAIR,SAASO,EAAKN,QAU7B,OATAO,EAAGN,UAAU,EAAG,WAAY,GAC5BM,EAAGL,UAAU,EAAG,GAAG,GACnBK,EAAGL,UAAU,EAAG,GAAG,GACnBK,EAAGL,UAAU,EAAGd,EAAQpY,QAAQ,GAChCuZ,EAAGL,UAAU,GAAId,EAAQpY,QAAQ,GACjCuZ,EAAGN,UAAU,GAAII,EAAiBrZ,QAAQ,GAC1CuZ,EAAGN,UAAU,GAAIf,GAAQ,GACzBqB,EAAGL,UAAU,GAAI,GAAG,GAEbnB,GAAYM,EAAYmB,OAAO,CAACH,EAAkBC,MAIvDG,GAAoB,IAAIC,OAC1B,IACIhW,OAAOuT,aAAa,GACpB,IACAvT,OAAOuT,aAAa,GACpBvT,OAAOuT,aAAa,IACpBvT,OAAOuT,aAAa,IACpBvT,OAAOuT,aAAa,IACpB,IACAvT,OAAOuT,aAAa,IACpBvT,OAAOuT,aAAa,OACpBvT,OAAOuT,aAAa,OACpB,IACJ,KAIE0C,GAAavd,GAFMA,IAAiBA,EAAK8N,QAAQuP,GAAmB,IAGtEG,CAAgBxd,GACX8N,QAAQ,KAAM,SACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,UACdA,QAAQ,KAAM,UAEjB2P,GAAgBC,IAClB,IAAI3S,EAAI2S,EAAQ,EACZC,EAAU,GACd,KAAO5S,EAAI,GAAG,CACV,MAAM6S,GAAO7S,EAAI,GAAK,GACtB4S,EAAUrW,OAAOuT,aAAa,GAAK+C,GAAOD,EAC1C5S,EAAI/G,KAAK6Z,OAAO9S,EAAI,GAAK,GAC7B,CACA,OAAO4S,GAQLG,GAAa,4DAEbC,GAAgBA,CAACxD,EAAoBD,EAAyB0D,KAChE,MAAMC,EAAoB,GAC1B,IAAIC,EAAW,EAEf,MAAMC,EAAeA,CAAC5f,EAAayB,EAAcrB,IAC7C,SAASJ,mBAAqBI,EAAQ,OAAOA,KAAW,kCAAkC4e,GACtFvd,kBAGR,GAAIsa,EAAgB,CAChB,MAAMI,EAAQH,EAAMZ,QAAQhP,IAAI,CAAC8P,EAAGgB,IAAM0C,EAAa,GAAGV,GAAahC,KAAKyC,IAAYzD,EAAG,IAAIpW,KAAK,IACpG4Z,EAAQzP,KAAK,WAAW0P,MAAaxD,WACrCwD,GAAY,CAChB,CAEA3D,EAAMd,KAAK5T,QAAS6U,IAChB,MAAM0D,EAAW1D,EACZ/P,IAAI,CAACG,EAAM2Q,KACR,MAAMld,EAAM,GAAGkf,GAAahC,KAAKyC,IAC3BvY,EAAOmF,EAAK3D,IAAIxB,KACtB,GAAIpC,EAAMuH,EAAKnD,MAAqB,KAAbmD,EAAKnD,IAAY,MAAO,GAC/C,GAAa,WAAThC,GAAyC,iBAAbmF,EAAKnD,KAAoB1B,OAAOgC,SAAS6C,EAAKnD,KAC1E,MAAO,SAASpJ,SAAWuM,EAAKnD,cAEpC,GAAa,YAAThC,EACA,MAAO,SAASpH,eAAiBuM,EAAKnD,IAAM,EAAI,YAEpD,IAAc,SAAThC,GAA4B,aAATA,IAAwBI,EAAO+E,EAAKnD,KAAM,CAE9D,MAAMpB,EAAIR,EAAO+E,EAAKnD,KAUtB,MAAO,SAASpJ,SAAoB,aAAToH,EAAsB,EAAI,SATzCK,KAAKqY,IACb9X,EAAE+X,cACF/X,EAAEgY,WACFhY,EAAEiY,UACFjY,EAAEkY,WACFlY,EAAEmY,aACFnY,EAAEoY,cAEe,MAAW,eAEpC,CACA,OAAOR,EAAa5f,EAAKuM,EAAKzC,aAEjChE,KAAK,IACV4Z,EAAQzP,KAAK,WAAW0P,MAAaE,WACrCF,GAAY,IAGhB,MAAMU,EAAUnB,GAAazZ,KAAKD,IAAIwW,EAAM5B,QAAQ/U,OAAS,EAAG,IAC1Dib,EAAU7a,KAAKD,IAAIma,EAAW,EAAG,GACjCY,EAAOd,EAAarT,IAAI,CAACoU,EAAGtD,IAAM,aAAaA,EAAI,WAAWA,EAAI,aAAasD,wBAAwB1a,KAAK,IAElH,OACIyZ,iKAGA,sBAAsBc,IAAUC,kDAE/BvE,EAAiB,6EAA+E,IALjGwD,mEAQCgB,EAAO,SAASA,WAAgB,IACjC,cAAcb,EAAQ5Z,KAAK,mBAC1BiW,GAAkBC,EAAMd,KAAK7V,OAAS,EAAI,uBAAuBgb,IAAUC,OAAe,IAC3F,gBAIFG,GACFlB,ojCAgBEmB,GACFnB,o2BAWEoB,GACFpB,yhBAOEqB,GACFrB,sXAMEsB,GAAoBC,GACtBvB,gKAGA,wBAAwBP,GAAU8B,oDAGhCC,GAAeA,KACjB,MAAMC,GAAM,IAAIvZ,MAAOwZ,cACvB,OACI1B,uUAKA,8CAA8CyB,sBAC9C,+CAA+CA,4CAKjDE,GACF3B,oOAKS4B,GAAYA,CAAChY,EAAiBgR,EAAqC,MAC5E,MAAM4B,EAAiB5B,EAAQ4B,iBAAkB,EAC3CC,EAAQ9B,GAAiB/Q,EAAKgR,GAC9BiH,EAASpF,EAAM5B,QAAQhO,IAAI,CAACxD,EAAKsU,KACnC,MAAMmE,EAAWlH,EAAQmH,gBAAgB1Y,EAAI9D,QAAQjF,MACrD,GAAIwhB,EAAU,OAAOA,EACrB,IAAI7b,EAAMwW,EAAMZ,QAAQ8B,GAAG7X,OAC3B,IAAK,IAAIkc,EAAI,EAAGA,EAAI9b,KAAKF,IAAIyW,EAAMd,KAAK7V,OAAQ,KAAMkc,GAAK,EAAG,CAC1D,MAAMC,EAAMxF,EAAMd,KAAKqG,GAAGrE,GAAGpT,UAAUzE,OACnCmc,EAAMhc,IAAKA,EAAMgc,EACzB,CACA,OAAO/b,KAAKF,IAAIE,KAAKD,IAAIA,EAAM,EAAG,GAAI,MAEpCsb,EA/JiB/M,KACvB,MAAM0N,GAAW1N,GAAQ,UAAUxE,QAAQ,gBAAiB,KAAKe,QAAU,SAC3E,OAAOmR,EAAQpc,OAAS,GAAKoc,EAAQrQ,MAAM,EAAG,IAAMqQ,GA6JlCC,CAAkBvH,EAAQ2G,WACtCrD,EAAsB,CACxB,CAAE1J,KAAM,sBAAuBkK,KAAMrB,GAAW8D,KAChD,CAAE3M,KAAM,cAAekK,KAAMrB,GAAW+D,KACxC,CAAE5M,KAAM,oBAAqBkK,KAAMrB,GAAWmE,OAC9C,CAAEhN,KAAM,mBAAoBkK,KAAMrB,GAAWsE,KAC7C,CAAEnN,KAAM,kBAAmBkK,KAAMrB,GAAWiE,GAAiBC,KAC7D,CAAE/M,KAAM,6BAA8BkK,KAAMrB,GAAWgE,KACvD,CAAE7M,KAAM,gBAAiBkK,KAAMrB,GAAW6D,KAC1C,CAAE1M,KAAM,2BAA4BkK,KAAMrB,GAAW4C,GAAcxD,EAAOD,EAAgBqF,MAE9F,OAAO5D,GAASC,IAedkE,GAAclgB,GAChBA,EAAK8N,QAAQ,KAAM,SAASA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,UCrapFoS,GAAclgB,GAChBA,EAAK8N,QAAQ,KAAM,SAASA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,UAmF7EqS,GAAoBC,IAC7B,IAAIC,GAAO,EACX,MAAMC,EAASA,KACPD,IACJA,GAAO,EACPD,EAAOE,WAEX,IACIC,GAAuB,IAAKH,EAAQE,UACxC,CAAE,MAAOE,GACLC,QAAQD,MAAM,wBAAyBA,GACvCF,GACJ,GAGEC,GAAyBA,EAAGG,cAAahI,UAAS4H,aACpD,GAAwB,oBAAbtL,SAEP,YADAsL,IAGJ,MAAMK,EAAcjI,EAAQiI,cAAe,EACrCC,EAAalI,EAAQkI,aAAc,EACnCtG,EAAiB5B,EAAQ4B,iBAAkB,EAC3CuG,EAAanI,EAAQmI,aAAc,EAEnCC,EAAQJ,EAAYK,WAAU,GAzGlBC,EAACC,EAAqBC,KACxC,MAAMC,EAAezd,MAAM4P,KAAK2N,EAAOG,iBAAiB,4BAClDC,EAAe3d,MAAM4P,KAAK4N,EAAOE,iBAAiB,4BACxDD,EAAatb,QAAQ,CAACyb,EAAI7F,KACtB,MAAM8F,EAAIF,EAAa5F,GACvB,GAAK8F,GAAKA,EAAEC,UAAYF,EAAGE,QAE3B,GAAmB,UAAfF,EAAGE,QAAqB,CACxB,MAAMC,EAAMH,EACNI,EAAMH,EACK,aAAbE,EAAI9b,MAAoC,UAAb8b,EAAI9b,MAC/B+b,EAAIC,QAAUF,EAAIE,QACdF,EAAIE,SAASD,EAAI9K,aAAa,UAAW,IAC7C8K,EAAIE,cAAgBH,EAAIG,gBAExBF,EAAIle,MAAQie,EAAIje,MAChBke,EAAI9K,aAAa,QAAS6K,EAAIje,OAEtC,KAA0B,WAAf8d,EAAGE,QACTD,EAAwB/d,MAAS8d,EAAyB9d,MACrC,aAAf8d,EAAGE,UACTD,EAA0B/d,MAAS8d,EAA2B9d,MAC/D+d,EAAE1K,YAAeyK,EAA2B9d,SAIpD,MAAMqe,EAAiBne,MAAM4P,KAAK2N,EAAOG,iBAAiB,WACpDU,EAAiBpe,MAAM4P,KAAK4N,EAAOE,iBAAiB,WAC1DS,EAAehc,QAAQ,CAACoP,EAAQwG,KAC5B,MAAM8F,EAAIO,EAAerG,GACzB,GAAK8F,EACL,IACI,MAAMQ,EAAMR,EAAES,cAAcvjB,cAAc,OAC1CsjB,EAAIN,IAAMxM,EAAOgN,YACjBF,EAAI3jB,MAAQ6W,EAAO7W,MACnB2jB,EAAInjB,OAASqW,EAAOrW,OACpBmjB,EAAIpjB,MAAMujB,QAAUX,EAAE5iB,MAAMujB,QAC5BX,EAAEY,YAAYJ,EAClB,CAAE,MACE,KAmERf,CAAcN,EAAaI,GAC3BA,EAAMM,iBAAiB,yBAAyBvb,QAASyb,GAAOA,EAAGc,UAC/DzB,GAAaG,EAAMM,iBAAiB,qBAAqBvb,QAASyb,GAAOA,EAAGc,UAC5ExB,GAAYE,EAAMM,iBAAiB,oBAAoBvb,QAASyb,GAAOA,EAAGc,UACzE9H,GAAgBwG,EAAMM,iBAAiB,qBAAqBvb,QAASyb,GAAOA,EAAGc,UACpFtB,EAAMuB,UAAUvc,IAAI,wBAEpBgb,EAAMM,iBAAiB,QAAQvb,QAASyb,GAAOA,EAAGgB,gBAAgB,OAClExB,EAAMniB,MAAMC,OAAS,OACrBkiB,EAAMniB,MAAM4jB,SAAW,IAEvB,MAAMrI,EAAQxB,EAAQwB,OAAS,IACzBsI,OAAEA,EAAMC,MAAEA,GAAU5B,EA3IP6B,KACnB,MAAMF,EAAmB,GACnBC,EAAkB,GAYxB,OAXA/e,MAAM4P,KAAKoP,EAAIC,aAAa9c,QAAS+c,IACjC,IACI,MAAMC,EAAQnf,MAAM4P,KAAKsP,EAAME,UAC1BnY,IAAKoY,GAASA,EAAKb,SACnB7d,KAAK,MACNwe,GAAOL,EAAOhU,KAAKqU,EAC3B,CAAE,MAEMD,EAAMlN,MAAM+M,EAAMjU,KAAKoU,EAAMlN,KACrC,IAEG,CAAE8M,SAAQC,UA6HsBO,CAAchO,UAAY,CAAEwN,OAAQ,GAAIC,MAAO,IAEhFQ,EAASjO,SAASvW,cAAc,UACtCwkB,EAAOrM,aAAa,cAAe,QACnCqM,EAAOrM,aAAa,sBAAuB,QAC3CqM,EAAOtkB,MAAMujB,QAAU,2FACvBlN,SAASY,KAAKC,YAAYoN,GAE1B,IAAIC,GAAW,EACf,MAAMC,EAASA,KACPD,IACJA,GAAW,EACXxe,OAAOqR,WAAW,KACVkN,EAAOG,YAAYH,EAAOG,WAAWpN,YAAYiN,IACtD,KACH3C,MAGE+C,EAAMJ,EAAOK,cACbZ,EAAMO,EAAOM,iBAAmBF,GAAKrO,SAC3C,IAAKqO,IAAQX,EAET,YADAS,IAIJT,EAAIc,OACJd,EAAIe,MACA,6DAA6DvD,GAAWhG,GAASlF,SAASkF,OAAS,mBAC/FuI,EAAM9X,IAAK+K,GAAS,gCAAgCwK,GAAWxK,UAAarR,KAAK,IACjF,+BAERqe,EAAIgB,QAEJlB,EAAO3c,QAAS8d,IACZ,MAAMhlB,EAAQ+jB,EAAIjkB,cAAc,SAChCE,EAAMkY,YAAc8M,EACpBjB,EAAI5L,KAAKjB,YAAYlX,KAEzB,MAAMilB,EAAalB,EAAIjkB,cAAc,SAIrC,GAHAmlB,EAAW/M,YApMG,09CAoMwB6B,EAAQmL,WAAa,IAC3DnB,EAAI5L,KAAKjB,YAAY+N,GAEjB1J,EAAO,CACP,MAAM4J,EAAKpB,EAAIjkB,cAAc,MAC7BqlB,EAAGC,UAAY,uBACfD,EAAGjN,YAAcqD,EACjBwI,EAAI9M,KAAKC,YAAYiO,EACzB,CACApB,EAAI9M,KAAKC,YAAY6M,EAAIsB,UAAUlD,IAEvBmD,WACR,SA7HcC,EAACxB,EAAeyB,IAClC,IAAIC,QAAeC,IACf,MAAMC,EAAS5gB,MAAM4P,KAAKoP,EAAI4B,QAAQngB,OAAQ4d,IAASA,EAAIwC,UAC3D,GAAsB,IAAlBD,EAAO1gB,OAEP,YADAygB,IAGJ,IAAIG,EAAYF,EAAO1gB,OACnByc,GAAO,EACX,MAAM8C,EAASA,KACP9C,IACJA,GAAO,EACPgE,MAEEI,EAAQ/f,OAAOqR,WAAWoN,EAAQgB,GACxCG,EAAOze,QAASkc,IACZ,MAAM2C,EAAYA,KACdF,GAAa,EACTA,GAAa,IACb9f,OAAOigB,aAAaF,GACpBtB,MAGRpB,EAAI6C,iBAAiB,OAAQF,EAAW,CAAEG,MAAM,IAChD9C,EAAI6C,iBAAiB,QAASF,EAAW,CAAEG,MAAM,QAsG3CX,CAAcxB,EAAK,KACrBhK,EAAQoM,qBAAqBpM,EAAQoM,cAAcpC,GACvDW,EAAI0B,aAAe5B,EACnBE,EAAI2B,QACJ3B,EAAI4B,QAEJvgB,OAAOqR,WAAWoN,EAAQ,IAC9B,CAAE,MACEA,GACJ,GAEC+B,IC1LHC,GAAetgB,GAActB,EAAMsB,GAAO,GAAKA,aAAemB,KAAOsB,OAAOzC,EAAIsB,WAAamB,OAAOzC,GAE7FugB,GAAiBA,CAC1BpJ,EACAqJ,EACAC,EACA5d,EACA6d,EAAa,aAEb,MAAMC,EAAQA,CAACC,EAAsBC,EAAeC,EAA+BC,KAC/E,MAAMviB,EAAQgiB,EAAeK,GACvBve,EAAMme,EAAelM,IAAI/V,GAC/B,IAAK8D,EAAK,MAAO,GACjB,MAAM0e,EAAU,IAAI5M,IACpBwM,EAAM5f,QAASsW,IACX,MAAMtX,ENkIcihB,EAACzgB,EAA2B8B,EAAoBO,IACxEP,EAAI4e,oBAA4B5e,EAAI4e,oBAAoB1gB,EAAI8B,EAAI9D,OAAQgC,EAAK8B,EAAKO,GAC/ED,EAAapC,EAAK8B,EAAKO,GMpIVoe,CAAiB3J,EAAM9W,IAAK8B,EAAKO,GACvCse,EAASb,GAAYtgB,GAC3B,IAAIohB,EAAOJ,EAAQzM,IAAI4M,GACvB,IAAKC,EAAM,CACP,MAAM5e,EAAQe,EAAuBF,EAAkBrD,EAAKsX,EAAM9W,IAAK8B,EAAKO,EAAKyU,EAAM5W,MAAQggB,EAE/FU,EAAO,CACH1gB,GAFO,sBAAqBqgB,IAAOviB,KAAS2iB,IAG5CN,QACAQ,OAAQP,EACRQ,cAAe9iB,EACf+iB,YAAavhB,EACbwhB,cAAehf,EACfif,YAAa,GACbC,OAAQ,GACRC,YAAa,IAEjBX,EAAQnb,IAAIsb,EAAQC,EACxB,CACAA,EAAKM,OAAO/X,KAAK2N,KAErB,MAAMsK,EAA4B,GAgBlC,OAfAZ,EAAQhgB,QAASogB,IACTP,EAAQL,EAAezhB,OAAS,GAChCqiB,EAAKK,YAAcd,EACfS,EAAKM,OACLb,EAAQ,EACRO,EAAK1gB,GACL,GAAGqgB,IAAOviB,KAAS8hB,GAAYc,EAAKG,iBAExCH,EAAKO,YAAcP,EAAKM,OACxBN,EAAKM,OAAS,IAEdN,EAAKO,YAAcP,EAAKM,OAE5BE,EAAMjY,KAAKyX,KAERQ,GAEX,OAAOjB,EAAMxJ,EAAS,EAAG,KAAM,KAmCtB0K,GAAqDC,IAC9D,MAAMvY,EAAqB,GAE3B,OADAuY,EAAM9gB,QAAS+gB,GAASA,EAAKJ,YAAY3gB,QAASU,GAAM6H,EAAII,KAAKjI,KAC1D6H,GAwDEyY,GAAgBA,CACzBpN,EACAqN,EACAxB,EACAyB,EACArf,KAEA,MAAMsf,EAAqD,CAAA,EAS3D,OARAtZ,OAAOC,KAAKmZ,GAAkBjhB,QAASxC,IACnC,MAAM4jB,EAASH,EAAiBzjB,GAC1B6jB,EAAKH,EAAUE,GACf9f,EAAMme,EAAelM,IAAI/V,GAC/B,IAAK6jB,IAAO/f,IAA0B,IAAnBA,EAAIyF,WAAsB,OAC7C,MAAMmC,EAAS0K,EAAK9O,IAAKtF,GAAQoC,EAAapC,EAAK8B,EAAKO,IACxDsf,EAAO3jB,GAAS,CAAEG,MAAO0jB,EAAG/X,MAAM,CAAEJ,SAAQ1L,UAAU6jB,GAAID,KAEvDD,GCvMLG,GAAaA,CAACvB,EAAuB3O,KACvC,MAAMvY,EAAOF,EAAMN,WAA4C,EAAG4R,OAAO,GAAIiU,YAAWplB,WAAUyoB,GAAQ7oB,IACtGC,EAAAC,cAAA,MAAA,CACIF,IAAKA,EACL8oB,QAAQ,YACRjpB,MAAO0R,EACPlR,OAAQkR,EACRwX,KAAK,eACLC,UAAU,QAAO,cACL,OACZxD,UAAW,CAAC,gBAAiBA,GAAW5f,OAAOC,SAASC,KAAK,KAC7D1F,MAAOA,KACHyoB,GAEHxB,IAIT,OADAlnB,EAAKuY,YAAcA,EACZvY,GAGE8oB,GAAiBL,GAC1B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,sEACR,kBAESkhB,GAAiBN,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,mDAAqD,kBACzFmhB,GAAaP,GACtB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,+MACR,cAESohB,GAAYR,GACrB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,0GACR,aAESqhB,GAAeT,GACxB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,uHACR,gBAESshB,GAAkBV,GAC3B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,gEACR,mBAESuhB,GAAoBX,GAC7B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,kEACR,qBAESwhB,GAAeZ,GACxB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,sJACR,gBAESyhB,GAAYb,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,sDAAwD,aACvF0hB,GAAiBd,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,iDAAmD,kBACvF2hB,GAAmBf,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,mDAAqD,oBAC3F4hB,GAAkBhB,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,kDAAoD,mBACzF6hB,GAAgBjB,GACzB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,+DACR,iBAES8hB,GAAelB,GACxB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,+DACR,gBAES+hB,GAAcnB,GACvB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,0IACR,eAESgiB,GAAapB,GACtB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,kFACR,cAESiiB,GAAUrB,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,wCAA0C,WACvEkiB,GAAmBtB,GAC5B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,sDACR,oBAESmiB,GAAoBvB,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,0CAA4C,qBACnFoiB,GAAmBxB,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,8BAAgC,oBACtEqiB,GAAoBzB,GAC7B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,wSACR,qBAESsiB,GAAY1B,GACrB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,sJACR,aAESuiB,GAAiB3B,GAC1B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,mIACR,kBAESwiB,GAAkB5B,GAC3B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,mIACR,mBAESyiB,GAAoB7B,GAC7B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,8fACR,qBAES0iB,GAAgB9B,GAAW3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,+CAAiD,iBACpF2iB,GAAiB/B,GAC1B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,mKACR,kBAES4iB,GAAehC,GACxB3oB,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAAA,OAAA,CACI8H,EAAE,2NACF8iB,QAAQ,QAEZ7qB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,gBAAgB8iB,QAAQ,SAEpC,+hBCrGSC,GAAS9qB,EAAMN,WACxB,EACMqB,UAAU,OAAQuQ,OAAO,SAAU/N,YAAWC,UAASunB,SAAQxF,YAAWjiB,WAAU6D,OAAO,YAAayhB,GAC1G7oB,IAEAC,EAAAC,cAAA,SAAA,CACIF,IAAKA,EACLoH,KAAMA,EACNoe,UAAW9f,EACP,eACY,YAAZ1E,GAAyB,wBACb,cAAZA,GAA2B,0BAClB,UAATuQ,GAAoB,sBACpByZ,GAAU,uBACVxF,MAEAqD,GAEHrlB,EACAD,EACAE,IAIbsnB,GAAOrS,YAAc,sBASRuS,GAAahrB,EAAMN,WAC5B,EAAG4R,OAAO,SAAUyZ,SAAQliB,QAAO0c,YAAWjiB,WAAU6D,OAAO,YAAayhB,GAAQ7oB,IAChFC,EAAAC,cAAA,SAAA,CACIF,IAAKA,EACLoH,KAAMA,EACNuU,MAAO7S,EAAK,aACAA,EACZ0c,UAAW9f,EACP,kCACS,UAAT6L,GAAoB,sBACpByZ,GAAU,uBACVxF,MAEAqD,GAEHtlB,IAIb0nB,GAAWvS,YAAc,oBAYlB,MAAMwS,GAAQA,EAAGxW,QAAQ,EAAG1T,UAAU,MAAOuC,cAChDtD,EAAAC,cAAA,OAAA,CAAMslB,UAAU,kBACXjiB,EACAmR,EAAQ,IACQ,QAAZ1T,EACGf,EAAAC,cAAA,OAAA,CAAMslB,UAAU,uBAEhBvlB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,wBAAwB9Q,EAAQ,GAAK,MAAQA,KAahEyW,GAAYlrB,EAAMN,WAC3B,EAAG4R,OAAO,SAAUiU,eAAcqD,GAAQ7oB,IACtCC,EAAAC,cAAA,QAAA,CACIF,IAAKA,EACLwlB,UAAW9f,EAAG,iBAA2B,UAAT6L,GAAoB,wBAAyBiU,MACzEqD,KAIhBsC,GAAUzS,YAAc,yBAMX0S,GAASnrB,EAAMN,WAA2C,EAAG4R,OAAO,SAAUiU,eAAcqD,GAAQ7oB,IAC7GC,EAAAC,cAAA,SAAA,CAAQF,IAAKA,EAAKwlB,UAAW9f,EAAG,kBAA4B,UAAT6L,GAAoB,yBAA0BiU,MAAgBqD,KAErHuC,GAAO1S,YAAc,gBASd,MAAM2S,GAAQA,EAAGviB,QAAOvF,WAAUiiB,YAAW8F,aAChDrrB,EAAAC,cAAA,MAAA,CAAKslB,UAAW9f,EAAG,iBAAkB8f,IAChC1c,GACG7I,EAAAC,cAAA,QAAA,CAAOslB,UAAU,uBAAuB8F,QAASA,GAC5CxiB,GAGRvF,GASIgoB,GAAWtrB,EAAMN,WAC1B,EAAG0jB,iBAAgB,EAAOva,QAAO0c,eAAcqD,GAAQ2C,KACnD,MAAMC,EAAWxrB,EAAM+Y,OAAgC,MACjD0S,EAASzrB,EAAM4Z,YAChB6N,IACG+D,EAASxS,QAAUyO,EACS,mBAAjB8D,EAA6BA,EAAa9D,GAC5C8D,IAAeA,EAAiEvS,QAAUyO,IAEvG,CAAC8D,IAKL,OAHAvrB,EAAMgY,UAAU,KACRwT,EAASxS,UAASwS,EAASxS,QAAQoK,cAAgBA,IACxD,CAACA,IAEApjB,EAAAC,cAAA,QAAA,CACIF,IAAK0rB,EACLtkB,KAAK,WACLuU,MAAO7S,EAAK,aACAA,EACZ0c,UAAW9f,EAAG,oBAAqB8f,MAC/BqD,MAKpB0C,GAAS7S,YAAc,kBAMhB,MAAMiT,GAAUA,EAAGnG,eACtBvlB,EAAAC,cAAA,MAAA,CAAKslB,UAAW9f,EAAG,mBAAoB8f,GAAYoG,KAAK,cAAa,aAAY,qBAyBrEC,IAAQ5G,KACpBA,EAAI6G,SACJA,EAAQC,QACRA,EAAOxoB,SACPA,EAAQyoB,UACRA,EAAY,eAAcC,UAC1BA,EAAY,QAAOzG,UACnBA,EAASplB,MACTA,EAAKmd,OACLA,EAAS,EAACqO,KACVA,EAAO,SAAQM,UACfA,GAAY,EAAKC,qBACjBA,IAEA,MAAMnsB,EAAMC,EAAM+Y,OAA8B,OACzCoT,EAAUC,GAAepsB,EAAMwZ,SAAwD,CAC1F6S,IAAK,EACLC,KAAM,EACNC,OAAO,IAGLC,EAASxsB,EAAM4Z,YAAY,KAC7B,MAAMkJ,EAAK/iB,EAAIiZ,QACf,IAAK8J,EAAI,OACT,MAAM2J,EAAKvmB,OAAOwmB,WACZC,EAAKzmB,OAAO0mB,YACZrM,EAAIuC,EAAG+J,YACP5Q,EAAI6G,EAAGgK,aACb,IAAIT,EACAC,EACJ,GAAIT,GAAYA,EAASkB,YAAa,CAClC,MAAMtgB,EAAIof,EAASmB,wBACD,gBAAdjB,GACAM,EAAM5f,EAAE4f,IACRC,EAAO7f,EAAEwgB,MAAQ3P,EACbgP,EAAO/L,EAAIkM,EAAK,IAAGH,EAAO7f,EAAE6f,KAAOhP,EAASiD,KAEhD8L,EAAM5f,EAAEygB,OAAS5P,EACb+O,EAAMpQ,EAAI0Q,EAAK,GAAKlgB,EAAE4f,IAAM/O,EAASrB,GAAK,IAAGoQ,EAAM5f,EAAE4f,IAAM/O,EAASrB,GACxEqQ,EACkB,eAAdP,EACMtf,EAAEwgB,MAAQ1M,EACI,WAAdwL,EACEtf,EAAE6f,KAAO7f,EAAE7M,MAAQ,EAAI2gB,EAAI,EAC3B9T,EAAE6f,KAEtB,MACID,EAAMM,EAAK,EAAI1Q,EAAI,EACnBqQ,EAAOG,EAAK,EAAIlM,EAAI,EAExB8L,EAAMhnB,EAAMgnB,EAAK,EAAG7mB,KAAKD,IAAI,EAAGonB,EAAK1Q,EAAI,IACzCqQ,EAAOjnB,EAAMinB,EAAM,EAAG9mB,KAAKD,IAAI,EAAGknB,EAAKlM,EAAI,IAC3C6L,EAAae,GAAUA,EAAKZ,OAASY,EAAKd,MAAQA,GAAOc,EAAKb,OAASA,EAAOa,EAAO,CAAEd,MAAKC,OAAMC,OAAO,KAC1G,CAACV,EAAUE,EAAWzO,IAwDzB,GAtDAtd,EAAM+X,gBAAgB,KAClB,IAAKiN,EAED,YADAoH,EAAae,GAAUA,EAAKZ,MAAQ,IAAKY,EAAMZ,OAAO,GAAUY,GAGpEX,IACAtmB,OAAOkgB,iBAAiB,SAAUoG,GAClCtmB,OAAOkgB,iBAAiB,SAAUoG,GAAQ,GAC1C,IAAIY,EAAkC,KAKtC,MAJ8B,oBAAnBC,gBAAkCttB,EAAIiZ,UAC7CoU,EAAW,IAAIC,eAAe,IAAMb,KACpCY,EAASE,QAAQvtB,EAAIiZ,UAElB,KACH9S,OAAOqnB,oBAAoB,SAAUf,GACrCtmB,OAAOqnB,oBAAoB,SAAUf,GAAQ,GAC7CY,GAAUI,eAEf,CAACxI,EAAMwH,IAEVxsB,EAAMgY,UAAU,KACZ,IAAKgN,EAAM,OACX,MAAMyI,EAAqBC,IACvB,MAAMhL,EAASgL,EAAMhL,OAChBA,IACD3iB,EAAIiZ,SAAS2U,SAASjL,IACtBmJ,GAAU8B,SAASjL,IACnBwJ,GAAsB0B,KAAMtM,GAAMA,EAAEtI,SAAS2U,SAASjL,KAErDA,EAAuBmL,UAAU,sBACtC/B,EAAQ,cAENgC,EAAiBJ,IACD,WAAdA,EAAMrnB,KAAkBylB,EAAQ,WAKxC,OAHAtV,SAAS4P,iBAAiB,YAAaqH,GAAmB,GAC1DjX,SAAS4P,iBAAiB,aAAcqH,GAAmB,GAC3DjX,SAAS4P,iBAAiB,UAAW0H,GAC9B,KACHtX,SAAS+W,oBAAoB,YAAaE,GAAmB,GAC7DjX,SAAS+W,oBAAoB,aAAcE,GAAmB,GAC9DjX,SAAS+W,oBAAoB,UAAWO,KAE7C,CAAC9I,EAAM8G,EAASD,EAAUK,IAE7BlsB,EAAMgY,UAAU,KACZ,GAAIgN,GAAQiH,GAAalsB,EAAIiZ,QAAS,EAChBjZ,EAAIiZ,QAAQ+U,cAC1B,qEAEUhuB,EAAIiZ,SAASwN,OAC/B,GACD,CAACxB,EAAMiH,KAELjH,GAA4B,oBAAbxO,SAA0B,OAAO,KAErD,MAAMwX,EAAQN,GAAgCA,EAAMO,kBAEpD,OAAOC,eACHluB,EAAAC,cAAA,MAAA,CACIF,IAAKA,EACL4rB,KAAMA,EACNwC,UAAU,EACV5I,UAAW9f,EAAG,mBAAoB8f,GAAU,iBAC5ByG,EAChB7rB,MAAO,CACHksB,IAAKF,EAASE,IACdC,KAAMH,EAASG,KACf8B,WAAYjC,EAASI,MAAQ,UAAY,YACtCpsB,GAEPkuB,QAASL,EACTM,cAAeN,EACfO,YAAaP,EACbQ,UAAYd,IACR,GAAkB,WAAdA,EAAMrnB,IAGN,OAFAqnB,EAAMO,uBACNnC,EAAQ,UAGZ4B,EAAMO,oBAGT3qB,GAELkT,SAASY,KAEjB,CAUO,MAAMqX,GAAOA,EAAGnrB,WAAUiiB,YAAWiJ,eAAc5F,MACtD,MAAM7oB,EAAMC,EAAM+Y,OAAgC,MAyBlD,OALA/Y,EAAMgY,UAAU,KACZ,MAAM0W,EAAQ3uB,EAAIiZ,SAAS+U,cAA2B,iDACtDW,GAAOlI,SACR,IAGCxmB,EAAAC,cAAA,KAAA,CAAIF,IAAKA,EAAK4rB,KAAK,OAAOpG,UAAW9f,EAAG,gBAAiB8f,GAAYiJ,UAxBlDd,IAEnB,GADAc,IAAYd,GACM,cAAdA,EAAMrnB,KAAqC,YAAdqnB,EAAMrnB,KAAmC,SAAdqnB,EAAMrnB,KAAgC,QAAdqnB,EAAMrnB,IAAe,OACzG,MAAM4gB,EAAQ/hB,MAAM4P,KAChB/U,EAAIiZ,SAAS4J,iBAA8B,kDAAoD,IAEnG,GAAqB,IAAjBqE,EAAM7hB,OAAc,OACxBsoB,EAAMiB,iBACN,MAAMC,EAAe3H,EAAMnb,QAAQ0K,SAASqY,eAC5C,IAAIhV,EAAO,EACoBA,EAAb,cAAd6T,EAAMrnB,IAA4BuoB,EAAe,EAAI,GAAKA,EAAe,GAAK3H,EAAM7hB,OACjE,YAAdsoB,EAAMrnB,IACJuoB,EAAe,EAAI3H,EAAM7hB,OAAS,GAAKwpB,EAAe,EAAI3H,EAAM7hB,QAAU6hB,EAAM7hB,OACpE,SAAdsoB,EAAMrnB,IAAuB,EAC1B4gB,EAAM7hB,OAAS,EAC3B6hB,EAAMpN,GAAM2M,YASuFoC,GAC9FtlB,IAYAwrB,GAAW9uB,EAAMN,WAC1B,EAAGC,OAAMovB,WAAUC,WAAUzJ,YAAWjiB,WAAU+qB,UAASY,cAAarG,GAAQ7oB,IAC5EC,EAAAC,cAAA,KAAA,CAAI0rB,KAAK,QACL3rB,EAAAC,cAAA,SAAA,CACIF,IAAKA,EACLoH,KAAK,SACLwkB,KAAK,WAAU,gBACAqD,QAAY5lB,EAC3B4lB,SAAUA,EACVb,UAAU,EACV5I,UAAW9f,EACP,qBACAupB,GAAY,+BACZD,GAAY,+BACZxJ,GAEJ8I,QAAUX,IACFsB,IACJX,IAAUX,GACVuB,WAEArG,GAEHjpB,EACDK,EAAAC,cAAA,OAAA,KAAOqD,MAKvBwrB,GAASrW,YAAc,kBAEhB,MAAMyW,GAAcA,IAAMlvB,EAAAC,cAAA,KAAA,CAAI0rB,KAAK,YAAYpG,UAAU,0BAQnD4J,GAAcA,EAAG7rB,cAC1BtD,sBAAI2rB,KAAK,eAAepG,UAAU,yBAC7BjiB,YCvZO8rB,KACZ,MAAMlmB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,GAAe5W,KAC7B6W,EAASF,EAAMG,gBAAgBxK,MAAmD,YAA3CqK,EAAMG,gBAAgBC,iBACnE,OACIzvB,gBAACgrB,GAAU,CACPniB,MAAOymB,EAAW5d,eAClBqZ,OAAQwE,kBACM,SAAQ,gBACPA,EACflB,QAAUX,GAAW6B,EAASrmB,EAAIwmB,kBAAoBxmB,EAAIymB,gBAAgB,UAAWjC,EAAMkC,gBAE3F5vB,EAAAC,cAAC+oB,GAAc,MAG3B,UAEgB6G,KACZ,MAAM3mB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,GAAe5W,KAC7B6W,EAASF,EAAMG,gBAAgBxK,MAAmD,YAA3CqK,EAAMG,gBAAgBC,iBACnE,OACIzvB,gBAACgrB,GAAU,CACPniB,MAAOymB,EAAW3d,eAClBoZ,OAAQwE,kBACM,SAAQ,gBACPA,EACflB,QAAUX,GAAW6B,EAASrmB,EAAIwmB,kBAAoBxmB,EAAIymB,gBAAgB,UAAWjC,EAAMkC,gBAE3F5vB,EAAAC,cAACgrB,GAAK,CAACxW,MAAO4a,EAAMS,YAAa/uB,QAAQ,OACrCf,EAAAC,cAACgpB,GAAc,OAI/B,UAEgB8G,KACZ,MAAM7mB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,EAAUtD,UAAEA,GAActT,MACvCzB,EAAQ+Y,GAAahwB,EAAMwZ,SAA6B,MACzDU,EAAU,CACZ,CAAElV,MAAO,UAAW6D,MAAOymB,EAAWnd,eAAgBxS,KAAMK,EAAAC,cAACgqB,UAC7D,CAAEjlB,MAAO,WAAY6D,MAAOymB,EAAWld,gBAAiBzS,KAAMK,EAAAC,cAACiqB,UAC/D,CAAEllB,MAAO,cAAe6D,MAAOymB,EAAWjd,mBAAoB1S,KAAMK,EAAAC,cAACkqB,WAEnEnR,EAAUkB,EAAQ1Q,KAAMymB,GAAMA,EAAEjrB,QAAUqqB,EAAMa,UAAYhW,EAAQ,GAC1E,OACIla,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAAC+qB,IACGniB,MAAOymB,EAAWzd,eAClBkZ,OAAQnlB,QAAQqR,mBACF,OACdoX,QAAUX,GAAUsC,EAAW7C,GAAUA,EAAO,KAAOO,EAAMkC,gBAE5D5W,EAAQrZ,MAEbK,EAAAC,cAAC2rB,GAAO,CACJ5G,KAAMpf,QAAQqR,GACd4U,SAAU5U,EACV6U,QAASA,IAAMkE,EAAU,MACzBhE,UAAWA,EACXL,KAAK,QAEL3rB,EAAAC,cAACwuB,GAAI,KACAvU,EAAQ/N,IAAK1D,GACVzI,EAAAC,cAAC6uB,GAAQ,CACLzoB,IAAKoC,EAAOzD,MACZrF,KAAM8I,EAAO9I,KACbovB,SAAUtmB,EAAOzD,QAAUqqB,EAAMa,QACjC7B,QAASA,IAAMnlB,EAAIinB,WAAW1nB,EAAOzD,OACrCiqB,SAAUA,IAAMe,EAAU,OAEzBvnB,EAAOI,UAOpC,CAYO,MAAMunB,GAAwBtB,GAc/B,SAAUuB,IAAkBC,WAC9BA,EAAa,CAAEzV,YAAY,GAAM0V,aACjCA,EAAe,CAAE1V,YAAY,GAAM2V,aACnCA,EAAYC,cACZA,GAAgB,EAAIC,gBACpBA,GAAkB,EAAIC,gBACtBA,GAAkB,EAAIC,eACtBA,IAEA,MAAM1nB,IAAEA,EAAGomB,WAAEA,EAAUtD,UAAEA,EAAS6E,UAAEA,GAAcnY,MAC3CzB,EAAQ+Y,GAAahwB,EAAMwZ,SAA6B,MACzDyV,EAAWA,IAAMe,EAAU,MAE3Bc,EAAc9wB,EAAM+wB,SAAS5kB,IAAIykB,EAAiBI,GACpDhxB,EAAMixB,eAAeD,GAAShxB,EAAMkxB,aAAaF,EAAkC,CAAE/B,aAAc+B,GAGjGG,EAAkD,CACpDzV,MAAmC,iBAArBmV,EAAUO,OAAsBP,EAAUO,YAAShoB,KAC9DonB,GAGP,OACIxwB,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAAC+qB,IACGniB,MAAOymB,EAAW1d,cAClBmZ,OAAQnlB,QAAQqR,GAAO,gBACT,OACdoX,QAAUX,GAAUsC,EAAW7C,GAAUA,EAAO,KAAOO,EAAMkC,gBAE7D5vB,EAAAC,cAACmpB,UAELppB,EAAAC,cAAC2rB,IAAQ5G,KAAMpf,QAAQqR,GAAS4U,SAAU5U,EAAQ6U,QAASmD,EAAUjD,UAAWA,EAAWL,KAAK,QAC5F3rB,EAAAC,cAACwuB,GAAI,KACAqC,EACAL,GACGzwB,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAACsqB,GAAe,MACtB8D,QAASA,IAAMnlB,EAAImoB,gBAAgBf,GACnCrB,SAAUA,GAETK,EAAWtd,kBAGnB0e,GACG1wB,EAAAC,cAAC6uB,IACGnvB,KAAMK,EAAAC,cAACqqB,GAAc,MACrB+D,QAASA,KACAnlB,EAAIooB,kBAAkBf,IAE/BtB,SAAUA,GAETK,EAAWrd,oBAGnB0e,GACG3wB,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAACoqB,GAAS,MAChBgE,QAASA,IAAMnlB,EAAIqoB,kBAAkBJ,GACrClC,SAAUA,GAETK,EAAWpd,sBAOxC,CAaM,SAAUsf,IAAmBC,YAAEA,EAAWC,WAAEA,EAAUC,eAAEA,GAAiB,IAC3E,MAAMzoB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,EAAUuB,UAAEA,GAAcnY,KACxCkZ,GAAiBvC,EAAMwC,mBAAqB,IAAIhsB,KAAK,MACpDrE,EAAMswB,GAAW9xB,EAAMwZ,SAASoY,IAChCG,EAAUC,GAAehyB,EAAMwZ,SAASmY,GAAoC,KAAlBC,GAC3DK,EAAWjyB,EAAM+Y,OAAgC,MACjDkN,EAAQjmB,EAAM+Y,OAAsB,MACpCmZ,EAAQR,GAAcb,EAAUsB,sBAGhCC,EAAepyB,EAAM+Y,OAAO6Y,GAClC5xB,EAAMgY,UAAU,KACR4Z,IAAkBQ,EAAapZ,UAC/BoZ,EAAapZ,QAAU4Y,EACvBE,EAAQF,GACc,KAAlBA,GAAsBI,GAAY,KAE3C,CAACJ,IAEJ5xB,EAAMgY,UACF,IAAM,KACoB,OAAlBiO,EAAMjN,SAAkB9S,OAAOigB,aAAaF,EAAMjN,UAE1D,IAGJ,MAAMqZ,EAAUrtB,IACZ,MAAMuL,EAASvL,EAAMmL,MAAM,OAAOxK,OAAQgH,GAAY,KAANA,GAChDylB,EAAapZ,QAAUzI,EAAO1K,KAAK,KACnCqD,EAAIopB,qBAAqB/hB,IASvBgiB,EAAQA,KACY,OAAlBtM,EAAMjN,SAAkB9S,OAAOigB,aAAaF,EAAMjN,SACtD8Y,EAAQ,IACRO,EAAO,IACPJ,EAASjZ,SAASwN,SAQhBgM,EAAab,GAAkBI,EAErC,OACI/xB,EAAAC,cAAA,MAAA,CAAKslB,UAAW9f,EAAG,wBAAyB+sB,GAAc,oCACtDxyB,EAAAC,cAAC+qB,GAAU,CACPzF,UAAU,gCACV1c,MAAOymB,EAAWvd,wBAAuB,gBAC1BygB,EACfrE,SAAUqE,GAAa,EAAK,EAC5BnE,QAdGoE,KACXT,GAAY,GACZ9rB,OAAOqR,WAAW,IAAM0a,EAASjZ,SAASwN,QAAS,KAc3CxmB,EAAAC,cAACipB,UAELlpB,EAAAC,cAAA,MAAA,CACIslB,UAAW9f,EACP,uDACAjE,GAAQ,sCAGZxB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,4BACZvlB,EAAAC,cAACipB,GAAU,CAAC5X,KAAM,MAEtBtR,EAAAC,cAACirB,GAAS,CACNnrB,IAAKkyB,EACL3gB,KAAK,QACLnK,KAAK,SACLnC,MAAOxD,EACP2sB,SAAUqE,EAAa,GAAI,EAC3Bf,YAAaA,GAAenC,EAAWxd,8BAA6B,aACxDwd,EAAWvd,wBACvBqH,SAAWsU,IAAUgF,OAhDf1tB,EAgD4B0oB,EAAMhL,OAAO1d,MA/C3D8sB,EAAQ9sB,GACc,OAAlBihB,EAAMjN,SAAkB9S,OAAOigB,aAAaF,EAAMjN,cACtDiN,EAAMjN,QAAU9S,OAAOqR,WAAW,IAAM8a,EAAOrtB,GAAQktB,IAHrCltB,OAiDN2tB,OAAQA,KACChB,GAAkC,KAAhBnwB,EAAK6O,QAAe2hB,GAAY,IAE3DxD,UAAYd,IACU,WAAdA,EAAMrnB,MACNqnB,EAAMO,kBACFzsB,EAAM+wB,IACAZ,IACNK,GAAY,GACZC,EAASjZ,SAAS4Z,SAGR,UAAdlF,EAAMrnB,MACgB,OAAlB4f,EAAMjN,SAAkB9S,OAAOigB,aAAaF,EAAMjN,SACtDqZ,EAAO7wB,OAIlBA,GACGxB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,0DACZvlB,EAAAC,cAAC+qB,GAAU,CAAC1Z,KAAK,QAAQzI,MAAOymB,EAAWlZ,YAAaiY,QAASkE,EAAOpE,UAAU,GAC9EnuB,EAAAC,cAACkpB,YAO7B,CAMM,SAAU0J,IAAeC,kBAC3BA,GAAoB,EAAIC,iBACxBA,GAAmB,EAAIC,iBACvBA,GAAmB,EAAIC,gBACvBA,GAAkB,EAAIC,oBACtBA,GAAsB,EAAKzC,cAC3BA,GAAgB,EAAIC,gBACpBA,GAAkB,EAAIC,gBACtBA,GAAkB,EAAIL,WACtBA,EAAUC,aACVA,EAAYC,aACZA,EAAY2C,mBACZA,EAAkBC,gBAClBA,EAAexC,eACfA,EAAcyC,uBACdA,EAAsBlB,sBACtBA,IAEA,MAAMtB,UAAEA,GAAcnY,KAChB4a,EAAcR,IAAsBjC,EAAU0C,sBAC9CC,EAAcT,IAAqBlC,EAAU4C,oBAC7CC,EAAcR,IAAwBrC,EAAU8C,uBAEtD,OACI3zB,uBAAKulB,UAAU,mBAAmBoG,KAAK,WACnC3rB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,0BACV+N,GAAetzB,EAAAC,cAACmvB,GAAoB,MACpCoE,GAAexzB,EAAAC,cAAC4vB,GAAoB,MACpC6D,GAAe1zB,EAAAC,cAAC8vB,GAAsB,MACtCiD,GACGhzB,EAAAC,cAACowB,IACGC,WAAYA,EACZC,aAAcA,EACdC,aAAcA,EACdC,cAAeA,EACfC,gBAAiBA,EACjBC,gBAAiBA,EACjBC,eAAgBA,KAI3BwC,GAAmBpzB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,2BAA2B6N,GAC9DpzB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,0BACV4N,EACAF,GACGjzB,EAAAC,cAACuxB,GAAkB,CAACC,YAAa4B,EAAwB3B,WAAYS,KAKzF,UCnXgByB,KACZ,MAAM1qB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,EAAUuB,UAAEA,GAAcnY,MACxCmb,KAAEA,EAAIC,SAAEA,GAAazE,EAAM0E,gBAC3Btf,EAAQ4a,EAAM2E,SACdC,EAAY5E,EAAM4E,UAClBnf,EAAiB,IAAVL,EAAc,EAAIof,EAAOC,EAAW,EAC3C/e,EAAKvP,KAAKF,IAAImP,GAAQof,EAAO,GAAKC,GAClC5Z,GAC8C,IAAhD2W,EAAUqD,gBAAgBpoB,QAAQgoB,GAC5BjD,EAAUqD,gBAAgBtV,OAAO,CAACkV,IAAW1iB,KAAK,CAAC3E,EAAGC,IAAMD,EAAIC,GAChEmkB,EAAUqD,gBAEpB,OACIl0B,EAAAC,cAAA,MAAA,CAAKslB,UAAU,sBAAsBoG,KAAK,aAAY,aAAY,cAC9D3rB,EAAAC,cAAA,OAAA,KAAOqvB,EAAW1a,6BAClB5U,EAAAC,cAACkrB,GAAM,CACH5F,UAAU,6BACVvgB,MAAO8uB,EAAQ,aACHxE,EAAW1a,4BACvBwE,SAAWsU,GAAUxkB,EAAIirB,YAAY1sB,OAAOimB,EAAMhL,OAAO1d,SAExDkV,EAAQ/N,IAAK1D,GACVzI,EAAAC,cAAA,SAAA,CAAQoG,IAAKoC,EAAQzD,MAAOyD,GACvBA,KAIbzI,EAAAC,cAAA,OAAA,KAAOqvB,EAAWza,8BAA8BC,EAAMC,EAAIN,IAC1DzU,EAAAC,cAAA,MAAA,CAAKslB,UAAU,+BACXvlB,EAAAC,cAAC+qB,GAAU,CAACniB,MAAOymB,EAAWta,0BAA2Bga,SAAU6E,GAAQ,EAAGxF,QAASA,IAAMnlB,EAAIkrB,QAAQ,IACrGp0B,EAAAC,cAAC2pB,UAEL5pB,EAAAC,cAAC+qB,GAAU,CACPniB,MAAOymB,EAAWra,6BAClB+Z,SAAU6E,GAAQ,EAClBxF,QAASA,IAAMnlB,EAAIkrB,QAAQP,EAAO,IAElC7zB,EAAAC,cAAC0pB,UAEL3pB,EAAAC,cAAC+qB,GAAU,CACPniB,MAAOymB,EAAWpa,yBAClB8Z,SAAU6E,GAAQI,EAAY,EAC9B5F,QAASA,IAAMnlB,EAAIkrB,QAAQP,EAAO,IAElC7zB,EAAAC,cAACypB,UAEL1pB,EAAAC,cAAC+qB,GAAU,CACPniB,MAAOymB,EAAWna,yBAClB6Z,SAAU6E,GAAQI,EAAY,EAC9B5F,QAASA,IAAMnlB,EAAIkrB,QAAQ5uB,KAAKD,IAAI0uB,EAAY,EAAG,KAEnDj0B,EAAAC,cAAC4pB,GAAY,QAKjC,UAEgBwK,KACZ,MAAMhF,MAAEA,EAAKC,WAAEA,EAAUuB,UAAEA,GAAcnY,KACnC4b,EAAgBjF,EAAMkF,kBAAkBntB,IAAIkK,KAC5CkjB,EAAeF,EAAgB,IAAMzD,EAAU4D,2BAC/CC,EAAiB7D,EAAU8D,aAAe9D,EAAU+D,qBACpDC,GAAgBH,IAAmB7D,EAAUiE,mBAEnD,OACI90B,EAAAC,cAAA,MAAA,CAAKslB,UAAU,mBACXvlB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,wBACViP,GAAgBx0B,EAAAC,cAAA,OAAA,KAAOqvB,EAAW9a,kBAAkB8f,KAExDO,GACG70B,EAAAC,cAAA,OAAA,KACKqvB,EAAW3a,oBAAkB0a,EAAM2E,SAAStf,kBAGpDggB,GAAkB10B,EAAAC,cAAC2zB,GAAiB,MAGjD,UC9EgBmB,KACZ,MAAM7rB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,EAAUnV,QAAEA,EAAO6a,eAAEA,GAAmBtc,KACtDuc,EAAgBj1B,EAAMk1B,QAAQ,IAAM,IAAI9wB,IAAI4wB,EAAe7oB,IAAKxD,GAAQA,EAAI9D,QAAS,CAACmwB,KACrFG,EAAQC,GAAap1B,EAAMwZ,SAAS,IACrC6b,EAAQhG,EAAMiG,sBAEdtnB,EAAWmM,EAAQxU,OAAQgD,IAAyB,IAAjBA,EAAIqF,UACvCnC,EAASspB,EAAO9kB,OAAO9E,cACvBgqB,EAAW1pB,EACXmC,EAASrI,OAAQgD,IAAwE,KAA/DA,EAAIgF,YAAchF,EAAI9D,OAAO0G,cAAcO,QAAQD,IAC7EmC,EAEAwnB,EAAUC,IACZ,MAAM5b,EAAO,IAAKwb,GAClBrnB,EAAS3G,QAASsB,IACdkR,EAAKlR,EAAI9D,OAAS4wB,IAEtBvsB,EAAIwsB,yBAAyB7b,IAGjC,OACI7Z,EAAAC,cAAA,MAAA,CAAKslB,UAAU,iBAAiBoG,KAAK,QAAO,aAAa2D,EAAW5d,gBAChE1R,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBACXvlB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,0BACXvlB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,4BACZvlB,EAAAC,cAACipB,GAAU,CAAC5X,KAAM,MAEtBtR,EAAAC,cAACirB,GAAS,CACNe,WAAS,EACT3a,KAAK,QACLtM,MAAOmwB,EACP1D,YAAanC,EAAWhd,8BAA6B,aACzCgd,EAAWhd,8BACvB8G,SAAWsU,GAAU0H,EAAU1H,EAAMhL,OAAO1d,WAIxDhF,EAAAC,cAAA,MAAA,CAAKslB,UAAU,0BACXvlB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBACVgQ,EAASppB,IAAKxD,IACX,MAAM8sB,EAAUR,EAAcnwB,IAAI6D,EAAI9D,OACtC,OACI7E,EAAAC,cAAA,QAAA,CAAOoG,IAAKsC,EAAI9D,MAAO0gB,UAAU,2BAC7BvlB,EAAAC,cAACqrB,IAASnI,QAASsS,EAASrc,SAAUA,IAAMlQ,EAAIysB,oBAAoBhtB,EAAI9D,OAAQ4wB,KAChFz1B,EAAAC,cAAA,OAAA,KAAO0I,EAAIgF,YAAchF,EAAI9D,UAIpB,IAApB0wB,EAASnwB,QAAgBpF,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBAAuB,gBAGxEvlB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBACXvlB,EAAAC,cAAC6qB,IAAO/pB,QAAQ,UAAUuQ,KAAK,QAAQ+c,QAASA,IAAMmH,GAAO,IACxDlG,EAAW/c,qBAEhBvS,EAAAC,cAAC6qB,IAAO/pB,QAAQ,UAAUuQ,KAAK,QAAQ+c,QAASA,IAAMmH,GAAO,IACxDlG,EAAW9c,qBAEhBxS,EAAAC,cAAC6qB,GAAM,CAACxZ,KAAK,QAAQ+c,QAASA,IAAMnlB,EAAIwsB,yBAAyB,CAAA,IAC5DpG,EAAW7c,oBAKhC,CCtDA,MAAMmjB,GAAoBA,CAAC5wB,EAAY6wB,EAAgC3D,EAAQ,OAC3E,MAAOjU,EAAO6X,GAAY91B,EAAMwZ,SAASxU,GAAS,IAC5CihB,EAAQjmB,EAAM+Y,OAAsB,MAC1C/Y,EAAMgY,UAAU,KACZ8d,EAAS9wB,GAAS,KACnB,CAACA,IAYJ,OANAhF,EAAMgY,UACF,IAAM,KACoB,OAAlBiO,EAAMjN,SAAkB9S,OAAOigB,aAAaF,EAAMjN,UAE1D,IAEG,CAACiF,EAXQpE,IACZic,EAASjc,GACa,OAAlBoM,EAAMjN,SAAkB9S,OAAOigB,aAAaF,EAAMjN,SACtDiN,EAAMjN,QAAU9S,OAAOqR,WAAW,IAAMse,EAAShc,GAAOqY,MAWhE,SAAS6D,IAAetqB,KAAEA,EAAI2N,SAAEA,EAAQqY,YAAEA,EAAWtqB,KAAEA,IACnD,MAAO8W,EAAOuO,GAAUoJ,GAAkBnqB,EAAKzG,MAAOoU,GACtD,OACIpZ,EAAAC,cAACirB,GAAS,CACN5Z,KAAK,QACLnK,KAAMA,EACNnC,MAAOiZ,EACPwT,YAAaA,EAAW,aACZA,EACZrY,SAAWsU,GAAUlB,EAAOkB,EAAMhL,OAAO1d,QAGrD,CAEA,SAASgxB,IAAgBvqB,KAAEA,EAAIwqB,OAAEA,EAAM7c,SAAEA,EAAQqY,YAAEA,IAC/C,MAAMyE,EAAShxB,MAAMC,QAAQsG,EAAKzG,OAASyG,EAAKzG,MAAMa,KAAK,MAAS4F,EAAKzG,OAAS,IAC3EiZ,EAAOuO,GAAUoJ,GAAkBM,EAAS10B,GAC/C4X,EACItQ,OAAOtH,GACF2O,MAAM,KACNhE,IAAKQ,GAAMA,EAAE0D,QACb1K,OAAQgH,GAAY,KAANA,KAG3B,GAAoB,iBAAhBspB,EAAO9uB,KAAyB,CAChC,MAAM+S,EAAUnR,EAAoBktB,GAC9BlH,EAAqB7pB,MAAMC,QAAQsG,EAAKzG,OAASyG,EAAKzG,MAAMmH,IAAIrD,QAAU,GAChF,OACI9I,gBAACmrB,GAAM,CACHgL,UAAQ,EACR7kB,KAAK,QACLtM,MAAO+pB,eACK0C,EACZrY,SAAWsU,IACP,MAAMnd,EAASrL,MAAM4P,KAAK4Y,EAAMhL,OAAO0T,iBAAiBjqB,IAAK1D,IACzD,MAAMc,EAAQ2Q,EAAQ1Q,KAAMymB,GAAMnnB,OAAOJ,EAAeutB,EAAQhG,MAAQxnB,EAAOzD,OAC/E,YAAiBoE,IAAVG,EAAsBb,EAAeutB,EAAQ1sB,GAASd,EAAOzD,QAExEoU,EAAS7I,KAGZ2J,EAAQ/N,IAAK1D,IACV,MAAMzD,EAAQ0D,EAAeutB,EAAQxtB,GACrC,OACIzI,EAAAC,cAAA,SAAA,CAAQoG,IAAKyC,OAAO9D,GAAQA,MAAO8D,OAAO9D,IACrC4D,EAAeqtB,EAAQxtB,MAMhD,CACA,OACIzI,EAAAC,cAACirB,GAAS,CACN5Z,KAAK,QACLtM,MAAOiZ,EACPwT,YAAY,yBAAwB,aACxBA,EACZrY,SAAWsU,GAAUlB,EAAOkB,EAAMhL,OAAO1d,QAGrD,CAEA,SAASqxB,GAAiBC,GACtB,MAAM7qB,KAAEA,EAAIwqB,OAAEA,EAAMM,SAAEA,EAAQnd,SAAEA,EAAQqY,YAAEA,GAAgB6E,GACpDptB,IAAEA,GAAQwP,KACV/M,EAAY4qB,GAAU5qB,WAAa,OAEzC,GAAI4qB,GAAUC,eAAgB,CAC1B,MAAMC,EAAYF,EAASC,eAC3B,OAAOx2B,EAAAC,cAACw2B,EAAS,CAAChrB,KAAMA,EAAMwqB,OAAQA,EAAQS,WAAa7c,GAAST,EAASS,EAAK7U,OAAQkE,IAAKA,GACnG,CAEA,OAAQyC,GACJ,IAAK,OACD,OAAO3L,4BACX,IAAK,UACD,OACIA,EAAAC,cAACkrB,GAAM,CACH7Z,KAAK,QACLtM,WAAsBoE,IAAfqC,EAAKzG,OAAsC,OAAfyG,EAAKzG,MAAiB,GAAK8D,OAAO2C,EAAKzG,OAAM,aACpEysB,EACZrY,SAAWsU,GAAUtU,EAAgC,KAAvBsU,EAAMhL,OAAO1d,WAAeoE,EAAYskB,EAAMhL,OAAO1d,QAEnFhF,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,IAAE,OAChBhF,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,QAAM,OACpBhF,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,SAAO,OAGjC,IAAK,SAAU,CACX,MAAMkV,EAAUnR,EAAoBktB,GACpC,OACIj2B,EAAAC,cAACkrB,IACG7Z,KAAK,QACLtM,WAAsBoE,IAAfqC,EAAKzG,OAAsC,OAAfyG,EAAKzG,MAAiB,GAAK8D,OAAO2C,EAAKzG,OAAM,aACpEysB,EACZrY,SAAWsU,IACP,MAAMnkB,EAAQ2Q,EAAQ1Q,KAAMymB,GAAMnnB,OAAOJ,EAAeutB,EAAQhG,MAAQvC,EAAMhL,OAAO1d,OACrFoU,EAC2B,KAAvBsU,EAAMhL,OAAO1d,WACPoE,OACUA,IAAVG,EACEb,EAAeutB,EAAQ1sB,GACvBmkB,EAAMhL,OAAO1d,SAI7BhF,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,KACbkV,EAAQ/N,IAAK1D,IACV,MAAMzD,EAAQ0D,EAAeutB,EAAQxtB,GACrC,OACIzI,EAAAC,cAAA,SAAA,CAAQoG,IAAKyC,OAAO9D,GAAQA,MAAO8D,OAAO9D,IACrC4D,EAAeqtB,EAAQxtB,MAMhD,CACA,IAAK,cACD,OAAOzI,EAAAC,cAAC+1B,GAAe,IAAKM,IAChC,IAAK,SACD,OAAOt2B,EAAAC,cAAC81B,GAAc,IAAKO,EAAOnvB,KAAK,WAC3C,IAAK,OACD,OAAOnH,EAAAC,cAAC81B,GAAc,IAAKO,EAAOnvB,KAAK,SAC3C,IAAK,iBACD,OAAOnH,EAAAC,cAAC81B,GAAc,IAAKO,EAAOnvB,KAAK,mBAC3C,QACI,OAAOnH,EAAAC,cAAC81B,GAAc,IAAKO,EAAOnvB,KAAK,SAEnD,CAEA,MAAMwvB,GAAoBV,IAAiC,CACvDlvB,GAAIjB,EAAS,UACbjB,MAAOoxB,GAAQpxB,OAAS,GACxB0xB,SAAUN,EAAU7oB,GAAyB6oB,GAAQ,IAAIjxB,OAAS,WAAc,WAChFA,WAAOoE,aAGKwtB,KACZ,MAAM1tB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,EAAUnV,QAAEA,EAAO0W,UAAEA,GAAcnY,KACjDme,EAAoB72B,EAAMk1B,QAAQ,IAAM/a,EAAQxU,OAAQgD,IAA2B,IAAnBA,EAAIoF,YAAuB,CAACoM,IAC5FK,EAAUxa,EAAMk1B,QAAQ,KAC1B,MAAM/oB,EAAM,IAAIsO,IAEhB,OADAoc,EAAkBxvB,QAASsB,GAAQwD,EAAID,IAAIvD,EAAI9D,MAAO8D,IAC/CwD,GACR,CAAC0qB,IAEE5P,EAAQoI,EAAMyH,YAAY7P,MAC1B8P,EAAgB1H,EAAMyH,YAAYC,eAAiB,MACnDC,EAAc3H,EAAMG,gBAAgBwH,YAGpCC,EAASj3B,EAAM+Y,QAAO,GAC5B/Y,EAAMgY,UAAU,KACZ,IAAIif,EAAOje,QAEX,GADAie,EAAOje,SAAU,EACbge,GAAexc,EAAQ1V,IAAIkyB,GAAc,CACxB/P,EAAMzd,KAAMiC,GAASA,EAAK5G,QAAUmyB,IACtC9tB,EAAIguB,iBAAiBP,GAAiBnc,EAAQI,IAAIoc,IACrE,MAA4B,IAAjB/P,EAAM7hB,QAAgByxB,EAAkBzxB,OAAS,GACxD8D,EAAIguB,iBAAiBP,GAAiBE,EAAkB,MAE7D,CAAC3tB,EAAKsR,EAASqc,EAAmB5P,EAAO+P,IAE5C,MAAMG,EAAaA,CAAC1rB,EAAyB2rB,KACzCluB,EAAIguB,iBAAiB,IAAKzrB,KAAS2rB,KAOjCC,GAAcxG,EAAUyG,iCAAoD,IAAjBrQ,EAAM7hB,OAEvE,OACIpF,EAAAC,cAAA,MAAA,CAAKslB,UAAU,iBAAiBoG,KAAK,QAAO,aAAa2D,EAAW3d,gBAChE3R,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBAAyBplB,MAAO,CAAEo3B,WAAY,KACvC,IAAjBtQ,EAAM7hB,QAAgBpF,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBAAuB,cAC5D0B,EAAM9a,IAAI,CAACV,EAAMyT,KACd,MAAM+W,EAASzb,EAAQI,IAAInP,EAAK5G,QAAUgyB,EAAkB,GACtDW,EAAYvB,EAAS7oB,GAAyB6oB,GAAU,GACxDM,EAAWiB,EAAUhuB,KAAMiuB,GAAOA,EAAGzyB,QAAUyG,EAAK8qB,WAAaiB,EAAU,GAC3EE,EAAYzQ,EAAM7hB,OAAS,EACjC,OACIpF,uBACIqG,IAAKyC,OAAO2C,EAAK1E,IAAMmY,GACvBqG,UACImS,EAAY,sDAAwD,uBAGxE13B,EAAAC,cAAC+qB,IACG1Z,KAAK,QACLzI,MAAOymB,EAAW1c,sBAClByb,QAASA,IAAMnlB,EAAIyuB,iBAAiBlsB,IAEpCzL,EAAAC,cAAC8pB,UAEJ2N,GACG13B,EAAAC,cAACmrB,GAAK,CAACviB,MAAiB,IAAVqW,EAAcoQ,EAAWrc,yBAA2B,KACnD,IAAViM,EACGlf,EAAAC,cAAA,MAAA,CAAKE,MAAO,CAAEC,OAAQ,MAEtBJ,EAAAC,cAACkrB,GAAM,CACH7Z,KAAK,QACLtM,MAAO+xB,EACP/H,SAAU9P,EAAQ,EAAC,aACPoQ,EAAWrc,yBACvBmG,SAAWsU,GACPxkB,EAAI0uB,uBAAuBlK,EAAMhL,OAAO1d,QAG5ChF,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,OAAOsqB,EAAWpc,wBAChClT,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,MAAMsqB,EAAWnc,yBAK/CnT,EAAAC,cAACmrB,GAAK,CAACviB,MAAOymB,EAAWzc,oBACrB7S,EAAAC,cAACkrB,IACG7Z,KAAK,QACLtM,MAAOixB,GAAQpxB,OAAS,GAAE,aACdyqB,EAAWzc,mBACvBuG,SAAWsU,IACP,MAAMmK,EAAard,EAAQI,IAAI8S,EAAMhL,OAAO1d,OACtC8yB,EAAgBD,EAAazqB,GAAyByqB,GAAc,GACpEE,EAAeD,EAAclK,KAAM6J,GAAOA,EAAGzyB,QAAUyG,EAAK8qB,UAClEY,EAAW1rB,EAAM,CACb5G,MAAO6oB,EAAMhL,OAAO1d,MACpBuxB,SAAUwB,EAAetsB,EAAK8qB,SAAYuB,EAAc,IAAI9yB,OAAS,WACrEA,WAAOoE,MAIdytB,EAAkB1qB,IAAKxD,GACpB3I,EAAAC,cAAA,SAAA,CAAQoG,IAAKsC,EAAI9D,MAAOG,MAAO2D,EAAI9D,OAC9B8D,EAAIgF,YAAchF,EAAI9D,UAKvC7E,EAAAC,cAACmrB,GAAK,CAACviB,MAAOymB,EAAWxc,qBACrB9S,EAAAC,cAACkrB,IACG7Z,KAAK,QACLtM,MAAOuxB,GAAUvxB,OAAS,GAAE,aAChBsqB,EAAWxc,oBACvBsG,SAAWsU,IACP,MAAMsK,EAAeR,EAAUhuB,KAAMiuB,GAAOA,EAAGzyB,QAAU0oB,EAAMhL,OAAO1d,OAChEizB,EAA0C,gBAA5BD,GAAcrsB,UAC5BusB,EAAyC,gBAAxB3B,GAAU5qB,UACjCwrB,EAAW1rB,EAAM,CACb8qB,SAAU7I,EAAMhL,OAAO1d,MACvBA,MAAOizB,IAAgBC,OAAiB9uB,EAAYqC,EAAKzG,UAIhEwyB,EAAUrrB,IAAKsrB,GACZz3B,EAAAC,cAAA,SAAA,CAAQoG,IAAKoxB,EAAGzyB,MAAOA,MAAOyyB,EAAGzyB,OAC5ByyB,EAAG5uB,OAAS4uB,EAAGzyB,UAKhChF,EAAAC,cAACmrB,GAAK,CAACviB,MAAOymB,EAAWvc,kBACpBkjB,EACGj2B,EAAAC,cAACo2B,GAAgB,CACb5qB,KAAMA,EACNwqB,OAAQA,EACRM,SAAUA,EACV9E,YAAanC,EAAWtc,4BACxBoG,SAAWpU,GAAUmyB,EAAW1rB,EAAM,CAAEzG,YAG5ChF,EAAAC,cAAA,MAAA,WAOxBD,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBACXvlB,EAAAC,cAAC6qB,GAAM,CACH/pB,QAAQ,UACRuQ,KAAK,QACL/N,UAAWvD,EAAAC,cAAC+pB,GAAO,CAAC1Y,KAAM,KAC1B+c,QApHA8J,KACZjvB,EAAIguB,iBAAiBP,GAAiBE,EAAkB,MAoH5C7H,UAAWqI,GAEV/H,EAAW5c,sBAEhB1S,EAAAC,cAAC6qB,GAAM,CACHxZ,KAAK,QACL/N,UAAWvD,EAAAC,cAAC8pB,GAAU,CAACzY,KAAM,KAC7B0d,SAA2B,IAAjB/H,EAAM7hB,OAChBipB,QAASA,IAAMnlB,EAAIkvB,eAAe,IAAK/I,EAAMyH,YAAa7P,MAAO,MAEhEqI,EAAW3c,uBAKhC,CCtTM,SAAU0lB,IAAkBpC,OAAEA,EAAMpK,SAAEA,EAAQ7G,KAAEA,EAAI8G,QAAEA,EAAOE,UAAEA,EAASsM,cAAEA,IAC5E,MAAMpvB,IAAEA,EAAGmmB,MAAEA,EAAKC,WAAEA,EAAUuB,UAAEA,GAAcnY,KACxC7T,EAAQoxB,EAAOpxB,MACf0zB,EAAmB1zB,IAAUd,EAC7By0B,EAAWnJ,EAAMoJ,UAAUjvB,KAAMiC,GAASA,EAAK5G,QAAUA,GACzD6zB,EAASxvB,EAAIyvB,eAAe9zB,GAC5B+zB,GAAsD,IAA1CvJ,EAAMwJ,iBAAiB/sB,QAAQjH,GAC3Ci0B,EAAczJ,EAAM/G,iBAAiBzjB,GAErCk0B,GAA8B,IAApB9C,EAAOnoB,WAAuB+iB,EAAUmI,qBAClDC,GAAkC,IAAtBhD,EAAOloB,aAAyB8iB,EAAU4C,sBAAwB8E,EAC9EW,GAA8B,IAApBjD,EAAOjoB,SACjBmrB,GAA6B,IAApBlD,EAAO/nB,WAAuB2iB,EAAUuI,qBACjDC,GAAgC,IAArBpD,EAAO9nB,YAAwB0iB,EAAUyI,qBAAuBf,EAC3EgB,EAAuBrqB,OAAOC,KAAK0hB,EAAU0I,sBAAsB5zB,OAAQmO,IAC7E,MAAM4U,EAAKmI,EAAU0I,qBAAqBzlB,GAC1C,QAAImiB,EAAOuD,gCAAwF,IAAvDvD,EAAOuD,8BAA8B1tB,QAAQgI,OACrF4U,EAAGhY,cAAeulB,EAAO9uB,OAAgD,IAAxCuhB,EAAGhY,YAAY5E,QAAQmqB,EAAO9uB,SAGjEsyB,GACoB,IAAtBxD,EAAO7nB,aAAyByiB,EAAU6I,qBAAuBnB,GAAoBgB,EAAqBn0B,OAAS,EAEjHu0B,EAAiBrB,GAAiBzM,EAClC/X,EAAOmiB,EAAOtoB,YAAcsoB,EAAOpxB,MAEzC,OACI7E,EAAAC,cAAC2rB,GAAO,CAAC5G,KAAMA,EAAM6G,SAAUA,EAAUC,QAASA,EAASE,UAAWA,EAAWD,UAAU,aAAaJ,KAAK,QACzG3rB,EAAAC,cAACwuB,GAAI,CAAA,aAAaa,EAAWnZ,iBACxB4iB,GACG/4B,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAACopB,GAAe,MACtB0F,SAA6B,QAAnByJ,GAAUpnB,KACpBid,QAASA,IAAMnlB,EAAI0wB,WAAW/0B,EAAO,OACrCoqB,SAAUnD,GAETwD,EAAWlc,mBAEhBpT,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAACqpB,GAAiB,MACxByF,SAA6B,SAAnByJ,GAAUpnB,KACpBid,QAASA,IAAMnlB,EAAI0wB,WAAW/0B,EAAO,QACrCoqB,SAAUnD,GAETwD,EAAWjc,oBAEfmlB,GACGx4B,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAAA,OAAA,CAAME,MAAO,CAAEP,MAAO,MAC5ByuB,QAASA,IAAMnlB,EAAI0wB,WAAW/0B,EAAO,MACrCoqB,SAAUnD,GAETwD,EAAWhc,mBAK3B2lB,GACGj5B,EAAAC,cAAAD,EAAA4qB,SAAA,KACKmO,GAAW/4B,EAAAC,cAACivB,GAAW,MACxBlvB,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAACgpB,GAAc,MACrBoF,QAASA,IAAMnlB,EAAI2wB,gBAAgBh1B,EAAO80B,GAC1C1K,SAAUnD,GAETwD,EAAW/b,oBAItB2lB,IAAYrI,EAAU0C,wBACpBvzB,EAAAC,cAAAD,EAAA4qB,SAAA,MACMmO,GAAWE,IAAcj5B,EAAAC,cAACivB,GAAW,MACtCgK,GACGl5B,EAAAC,cAAC6uB,IACGnvB,KAAMK,EAAAC,cAACuqB,GAAiB,MACxB6D,QAASA,IAAMnlB,EAAIysB,oBAAoB9wB,GAAO,GAC9CoqB,SAAUnD,GAETwD,EAAW9b,uBAGlBqd,EAAU0C,uBACRvzB,gBAAC8uB,GAAQ,CACLnvB,KAAMK,gBAACgpB,GAAc,MACrBqF,QAASA,IAAMnlB,EAAIymB,gBAAgB,UAAWgK,GAC9C1K,SAAUnD,GAETwD,EAAW7b,0BAK3B0lB,GACGn5B,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAACivB,GAAW,MACA,SAAXwJ,GACG14B,EAAAC,cAAC6uB,IACGnvB,KAAMK,gBAAC8pB,GAAW,CAAC3pB,MAAO,CAAE25B,UAAW,mBACvCzL,QAASA,IAAMnlB,EAAI6wB,UAAUl1B,EAAO,QACpCoqB,SAAUnD,GAETwD,EAAW5b,mBAGR,UAAXglB,GACG14B,EAAAC,cAAC6uB,IACGnvB,KAAMK,gBAAC8pB,GAAW,CAAC3pB,MAAO,CAAE25B,UAAW,oBACvCzL,QAASA,IAAMnlB,EAAI6wB,UAAUl1B,EAAO,SACpCoqB,SAAUnD,GAETwD,EAAW3b,oBAGnB+kB,GACG14B,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAAA,OAAA,CAAME,MAAO,CAAEP,MAAO,MAC5ByuB,QAASA,IAAMnlB,EAAI8wB,YAAYn1B,GAC/BoqB,SAAUnD,GAETwD,EAAW1b,kBAK3BylB,GACGr5B,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAACivB,GAAW,MACZlvB,EAAAC,cAAC6uB,GAAQ,CACLnvB,KAAMK,EAAAC,cAACyqB,GAAc,MACrB2D,QAASA,IACLuK,EAAY1vB,EAAI+wB,0BAA0Bp1B,GAASqE,EAAIgxB,uBAAuBr1B,GAElFoqB,SAAUnD,GAET8M,EAAYtJ,EAAWvb,kBAAkBD,GAAQwb,EAAWzb,gBAAgBC,KAIxF2lB,GACGz5B,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAACivB,GAAW,MACZlvB,EAAAC,cAACkvB,GAAW,KACRnvB,EAAAC,cAAA,QAAA,CACIslB,UAAU,uBACVplB,MAAO,CAAEmC,QAAS,OAAQF,WAAY,SAAU+3B,IAAK,IAErDn6B,EAAAC,cAACwqB,GAAa,CAACnZ,KAAM,SAAQge,EAAWtb,uBAE5ChU,EAAAC,cAACkrB,IACG7Z,KAAK,QACLtM,MAAO8zB,GAAe,GAAE,aACZxJ,EAAWtb,sBACvBoF,SAAWsU,IACP,MAAM7T,EAAO,IAAKwV,EAAM/G,kBACG,KAAvBoF,EAAMhL,OAAO1d,aAAqB6U,EAAKhV,GACtCgV,EAAKhV,GAAS6oB,EAAMhL,OAAO1d,MAChCkE,EAAIkxB,oBAAoBvgB,KAG5B7Z,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,IAAIsqB,EAAWpb,8BAC5BqlB,EAAqBptB,IAAKsc,GACvBzoB,EAAAC,cAAA,SAAA,CAAQoG,IAAKoiB,EAAQzjB,MAAOyjB,GACvBoI,EAAU0I,qBAAqB9Q,GAAQ5f,OAAS4f,QAUzF,CCjMM,SAAU4R,IAAqB74B,KAAEA,EAAO,UAAS84B,SAAEA,IACrD,OACIt6B,uBAAKulB,UAAU,mBAAmBoG,KAAK,UAClC2O,EAAWt6B,EAAAC,cAAA,MAAA,CAAKs6B,IAAI,GAAGtX,IAAKqX,IAAet6B,EAAAC,cAAC0qB,GAAY,CAACrZ,KAAM,KAChEtR,EAAAC,cAAA,MAAA,KAAMuB,GAGlB,CAEM,SAAUg5B,IAAsBh5B,KAAEA,IACpC,OACIxB,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAACyrB,GAAO,MACPlqB,GAAQxB,EAAAC,cAAA,MAAA,KAAMuB,GAG3B,UCPgBi5B,IAAuB96B,KACnCA,EAAIkJ,MACJA,EAAKwlB,QACLA,EAAOqM,WACPA,EAAU1L,SACVA,EAAQzJ,UACRA,KACGqD,IAEH,OACI5oB,EAAAC,cAAC+qB,GAAU,CACP1Z,KAAK,QACLzI,MAAOA,EACPmmB,SAAUA,EACVzJ,UAAWA,EACX8I,QAAUX,IACNA,EAAMO,kBACNI,IAAUX,OAEV9E,GAEHjpB,EAGb,CASM,SAAUg7B,IAAYC,QAAEA,EAAO5O,UAAEA,EAAS6O,UAAEA,IAC9C,MAAO5jB,EAAQ+Y,GAAahwB,EAAMwZ,SAA6B,MACzDshB,EAA+B,GAC/BC,EAA+B,GAOrC,OANAH,EAAQvzB,QAAS2zB,IACRh7B,EAAMixB,eAAe+J,KACrBA,EAAO1E,OAAuCoE,WAAYK,EAAO/qB,KAAKgrB,GACtEF,EAAO9qB,KAAKgrB,MAIjBh7B,EAAAC,cAAAD,EAAA4qB,SAAA,KACKkQ,EAAO3uB,IAAI,CAAC6uB,EAAQ9b,IACjBlf,EAAAC,cAACD,EAAM4qB,SAAQ,CAACvkB,IAAK20B,EAAO30B,KAAO6Y,GAAQ8b,IAE9CD,EAAO31B,OAAS,GACbpF,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAAC+qB,IACG1Z,KAAK,QACLzI,MAAOgyB,EACP9P,OAAQnlB,QAAQqR,GAChBoX,QAAUX,IACNA,EAAMO,kBACN+B,EAAW7C,GAAUA,EAAO,KAAOO,EAAMkC,iBAG7C5vB,EAAAC,cAACspB,UAELvpB,EAAAC,cAAC2rB,GAAO,CACJ5G,KAAMpf,QAAQqR,GACd4U,SAAU5U,EACV6U,QAASA,IAAMkE,EAAU,MACzBhE,UAAWA,EACXD,UAAU,aACVJ,KAAK,QAEL3rB,EAAAC,cAACwuB,GAAI,KACAsM,EAAO5uB,IAAI,CAAC6uB,EAAQ9b,KACjB,MAAMoX,EAAQ0E,EAAO1E,MACrB,OACIt2B,EAAAC,cAAC6uB,GAAQ,CACLzoB,IAAK20B,EAAO30B,KAAO6Y,EACnBvf,KAAM22B,EAAM32B,KACZqvB,SAAUsH,EAAMtH,SAChBX,QAAUX,IACN4I,EAAMjI,UAAUX,GAChBsC,EAAU,QAGbsG,EAAMztB,YAU/C,CAnEA4xB,GAAuBhiB,YAAc,yBCqErC,MAAMwiB,GAAqB,GACrBC,GAAoC,CAAA,EACpCC,GAAY,IAAI1gB,IAChB2gB,GAAgD,CAAC,MAAO,OAAQ,MAChEC,GAA4B,CAAC,GAAI,GAAI,GAAI,KACzCC,GAA2C,CAAErU,MAAO,GAAIsU,iCAAiC,GAkCzFC,GAAiBr7B,IACnB,IAAKA,EAAO,OACZ,MAAMyP,EAA2B,CAAA,EAOjC,OANAV,OAAOC,KAAKhP,GAAOkH,QAAShB,IACxB,GAAIyI,GAAczI,GAAM,OACxB,MAAMrB,EAAS7E,EAAckG,GACR,iBAAVrB,GAAuC,iBAAVA,IACxC4K,EAAIvJ,GAAOrB,KAER4K,GAqDL6rB,GAAmBA,CAACz2B,EAAYkD,KAClC,MAAMC,EAAOZ,EAAOvC,GACpB,IAAKmD,EAAM,MAAO,GAClB,MAAMuzB,EAAOnvB,GAAczD,OAAOyD,GAAGovB,SAAS,EAAG,KAC3CpgB,EAAO,GAAGpT,EAAK2X,iBAAiB4b,EAAIvzB,EAAK4X,WAAa,MAAM2b,EAAIvzB,EAAK6X,aAC3E,OAAO9X,EAAW,GAAGqT,KAAQmgB,EAAIvzB,EAAK8X,eAAeyb,EAAIvzB,EAAK+X,gBAAkB3E,GAOtE,SAAUqgB,GAA8CtF,GAClE,MAAMrb,KACFA,EACAd,QAAS0hB,EAAW/0B,SACpBA,EAAQg1B,QACRA,GAAU,EAAK1K,OACfA,EAAM2K,uBACNA,EAAsBC,0BACtBA,EAAyBC,YACzBA,GAAc,EAAK1W,UACnBA,EAAS2W,cACTA,EAAaC,aACbA,EAAYC,UACZA,EAASC,OACTA,EAAMC,SACNA,EAAQC,MACRA,EAAKp8B,MACLA,EAAKN,GACLA,EAAEmsB,UACFA,EAAY,QAAOwQ,UACnBA,EAASC,YACTA,GAAc,EAAIC,aAClBA,EAAYC,MACZA,EAAQzB,GAAY0B,UACpBA,EAAY1B,GAAY2B,WACxBA,EAAa,4CACbvN,WAAYwN,EACZC,UAAWC,EAAgBv4B,EAAkBw4B,mBAC7CA,EAAqBv4B,EAAqBw4B,aAC1CA,EAAYC,WACZA,IAAa,EAAKC,sBAClBA,IAAwB,EACxBlN,QAASmN,GAAWC,gBACpBA,GAAe3J,uBACfA,IAAyB,EAAKgB,WAC9BA,IAAa,EAAIb,SACjBA,GAAW,GAAEI,gBACbA,GAAkBmH,GAClBtH,gBAAiBwJ,GAAmBC,wBACpCA,GAAuBpb,WACvBA,IAAa,EAAKwS,qBAClBA,IAAuB,EAAKE,mBAC5BA,IAAqB,EAAKL,2BAC1BA,IAA6B,EAC7BgE,UAAWgF,GAAaC,kBACxBA,GAAiBC,aACjBA,GAAevC,GAAqBwC,8BACpCA,IAAgC,EAAK5E,qBACrCA,IAAuB,EACvBlC,YAAa+G,GAAeC,oBAC5BA,GAAmBrK,oBACnBA,IAAsB,EAAK6D,gCAC3BA,IAAkC,EAAKnF,sBACvCA,GAAwB,IACxBmD,sBAAuByI,GAAyBC,8BAChDA,GAA6BC,2BAC7BA,GAA0BC,sBAC1BA,GAAqBC,sBACrBA,GAAqBC,wBACrBA,GAAuBC,oBACvBA,GAAmBC,oBACnBA,GAAmBhwB,kBACnBA,IAAoB,EAAKilB,sBACzBA,IAAwB,EAAKgL,oBAC7BA,IAAsB,EAAKC,qBAC3BA,IAAuB,EAAKpF,qBAC5BA,IAAuB,EACvBqF,cAAeC,GAAiBC,sBAChCA,GAAqBC,kBACrBA,IAAoB,EAAKC,6BACzBA,IAA+B,EAAKC,2BACpCA,IAA6B,EAAIC,4BACjCA,IAA8B,EAC9BxK,kBAAmByK,GAAqBC,0BACxCA,GAAyBC,gBACzBA,GAAeC,4BACfA,IAA8B,EAAIC,gBAClCA,GAAeC,WACfA,GAAUC,iBACVA,GAAgBC,YAChBA,GAAWC,kBACXA,GAAiBC,WACjBA,GAAUC,sBACVA,GAAqBC,qBACrBA,GACAC,0BAA2BC,GAA6BC,kCACxDA,GACAjH,iBAAkBkH,GAAoBC,yBACtCA,GAAwBC,8BACxBA,GAAgC,EAACC,eACjCA,GAAc5G,mBACdA,IAAqB,EAAK6G,yBAC1BA,GACA7X,iBAAkB8X,GAAoBC,yBACtCA,GACA9G,qBAAsB+G,GAAwB5G,mBAC9CA,IAAqB,EAAK6G,oBAC1BA,GAAsB,OAAMC,iBAC5BA,GAAgBC,wBAChBA,GAAuBC,eACvBA,GAAcC,eACdA,GAAcC,aACdA,GAAYC,OACZA,GAAMC,cACNA,IACAxK,EAEJre,KAEA,MAAM8oB,Gb9MJ,SAAsB/6B,GACxB,MAAMg7B,EAAchhC,EAAcihC,MAClC,GAAID,EAGA,MAAO,GAAGh7B,KADCg7B,IACY1xB,QAAQ,KAAM,MAGzC,MAAMvP,EAAMC,EAAM+Y,OAAsB,MAKxC,OAJoB,OAAhBhZ,EAAIiZ,UACJgB,IAAa,EACbja,EAAIiZ,QAAU,GAAGhT,KAAUgU,MAExBja,EAAIiZ,OACf,CagMmBkoB,CAAY,YACrBC,GAAUnhC,EAAM+Y,OAA8B,MAC9CqoB,GAAUphC,EAAM+Y,OAA8B,MAC9CsoB,GAAcrhC,EAAM+Y,OAA8B,MAClDuoB,GAAathC,EAAM+Y,OAA8B,MACjDwoB,cbzNN,MAAM,CAAGC,GAAWxhC,EAAMwZ,SAAS,GACnC,OAAOxZ,EAAM4Z,YAAY,IAAM4nB,EAASze,GAAMA,EAAI,GAAI,GAC1D,CauNwB0e,GAEdnS,GAAatvB,EAAMk1B,QACrB,KAAA,IAAY3jB,MAAwBurB,IACpC,CAACA,IAKC4E,GAAS1hC,EAAM+Y,OAAY,IAC3B4oB,GAAa3hC,EAAM4Z,YAAY,KAAA,CAAiC1Q,IAAKw4B,GAAO1oB,QAAQ9P,MAAQ,IAE5F04B,GAAY5hC,EAAMk1B,QAAuB,KAC3C,MAAM2M,EAAIA,IAAMH,GAAO1oB,QACjB8oB,EAAyB,CAC3B5mB,OAASnU,GAAO86B,IAAIE,SAASnnB,IAAI7T,IAAO,KACxCi7B,aAAcA,IAAM,IAAIvnB,IAAIonB,IAAIE,UAChCE,aAAcA,IAAMJ,IAAIK,WAAW/1B,IAAKg2B,GAAmBA,EAAEp7B,IAC7Dq7B,WAAar7B,GAAO86B,IAAIQ,UAAUznB,IAAI7T,IAAO,KAC7Cu7B,cAAeA,IAAMT,IAAIU,aAAap2B,IAAKg2B,GAAmBA,EAAEt7B,KAChEmU,gBAAiBA,IAAM6mB,IAAIU,aAAap2B,IAAKg2B,GAAmBA,EAAEp7B,IAClEy7B,eAAgBA,IACZX,IACKY,UAAU98B,OAAQ+8B,GAAkC,SAAZA,EAAGv7B,MAAmBu7B,EAAG77B,KACjEsF,IAAKu2B,IAAiB,CAAQ37B,GAAI27B,EAAG37B,GAAIsuB,MAAOqN,EAAG77B,OAC5D87B,iCAAmC57B,GAAO86B,IAAIY,UAAUG,UAAWF,GAAsBA,EAAG37B,KAAOA,GACnG87B,WAAaC,IACTA,EAAQz7B,QAASmlB,IACb,MAAMzlB,EAAKH,EAAgB4lB,EAAaqV,IAAI/6B,UACtCi8B,EAAWlB,IAAIE,SAASnnB,IAAI7T,GAC9Bg8B,GAAUlB,IAAImB,eAAej8B,EAAI,IAAKg8B,KAAavW,OAI/DlS,cAAeA,IAAMunB,IAAIoB,mBACzBnoB,kBAAmBA,IAAM+mB,IAAIqB,mBAC7BC,UAAYt+B,GAAUg9B,IAAIsB,UAAUt+B,GACpCu+B,eAAgBA,CAACv+B,EAAOw+B,GAAoB,KACvCA,EAAoBxB,IAAIqB,mBAAqBrB,IAAIoB,oBAAoBL,UACjEloB,GAAqBA,EAAE7V,QAAUA,GAE1Cy+B,yBAA0BA,IAAMzB,IAAIvM,sBACpCK,oBAAqBA,CAAC9wB,EAAO0+B,IACzB1B,IAAInM,yBAAyB,IAAKmM,IAAIvM,sBAAuBzwB,CAACA,GAAQ0+B,IAC1E7N,yBAA2BL,GAAUwM,IAAInM,yBAAyBL,GAClEmO,eAAgBA,CAAC3+B,EAAOjF,IAAUiiC,IAAI2B,eAAe3+B,EAAOjF,GAC5D6jC,eAAgBA,CAAC5+B,EAAO6+B,IAAgB7B,IAAI4B,eAAe5+B,EAAO6+B,GAClEC,gBAAkBzpB,GAAY2nB,IAAI8B,gBAAgBzpB,GAClD6f,UAAWA,CAACl1B,EAAO++B,IAAS/B,IAAI9H,UAAUl1B,EAAO++B,GACjD5J,YAAcn1B,GAAUg9B,IAAI7H,YAAYn1B,GACxC8zB,eAAiB9zB,GAAUg9B,IAAIlJ,eAAe9zB,GAC9Cg/B,iBAAkBA,IAAMhC,IAAIpD,cAC5BqF,iBAAmBzO,GAAUwM,IAAIiC,iBAAiBzO,GAElD0O,aAAcA,IAAMlC,IAAIpJ,UACxBuL,aAAe3O,GAAUwM,IAAImC,aAAa3O,GAC1CuE,WAAYA,CAAC/0B,EAAOo/B,EAAWC,IAAyBrC,IAAIjI,WAAW/0B,EAAOo/B,EAAWC,GAEzFC,eAAgBA,IAAMtC,IAAI/K,YAC1BsB,eAAiB/C,GAAUwM,IAAIzJ,eAAe/C,GAC9C6B,iBAAmBzrB,GAASo2B,IAAIuC,kBAAkB,CAAC34B,IACnD24B,kBAAoBnd,GAAU4a,IAAIuC,kBAAkBnd,GACpD0Q,iBAAmBlsB,GAASo2B,IAAIlK,iBAAiBlsB,GACjDmsB,uBAAyBrB,GAAasL,IAAIzJ,eAAe,IAAKyJ,IAAI/K,YAAaC,cAAeR,IAC9FjE,qBAAuB/hB,GAAWsxB,IAAIzJ,eAAe,IAAKyJ,IAAI/K,YAAajF,kBAAmBthB,IAC9FspB,gBAAiBA,CAACwK,EAAmBxY,IAAagW,IAAIlS,gBAAgB,UAAW9D,EAAUwY,GAC3FC,gBAAiBA,IAAMzC,IAAInS,kBAC3BC,gBAAiBA,CAAC4U,EAAO1Y,EAAUmL,IAAgB6K,IAAIlS,gBAAgB4U,EAAO1Y,EAAUmL,GACxFtH,gBAAiBA,IAAMmS,IAAInS,kBAE3B8U,gBAAiBA,KACb,MAAMr4B,EAAM,IAAIsO,IAKhB,OAJAonB,IAAI4C,YAAYp9B,QAASN,IACrB,MAAMF,EAAMg7B,IAAIE,SAASnnB,IAAI7T,GACzBF,GAAKsF,EAAID,IAAInF,EAAIF,KAElBsF,GAEXu4B,qBAAsBA,KAAAA,CAASv9B,KAAM,UAAWC,IAAKy6B,IAAI4C,cACzDE,qBAAuBtP,IACnB,MAAMuP,EAAa59B,EACfquB,EACAwM,IAAIK,WAAW/1B,IAAKg2B,GAAmBA,EAAEp7B,KAE7C86B,IAAIgD,eAAeD,EAAWx9B,MAElC09B,UAAWA,CAAC/9B,EAAIg+B,GAAa,EAAMC,GAAiB,IAAUnD,IAAIoD,WAAW,CAACl+B,GAAKg+B,EAAYC,GAC/FC,WAAYA,CAAC79B,EAAK29B,GAAa,EAAMC,GAAiB,IAAUnD,IAAIoD,WAAW79B,EAAK29B,EAAYC,GAChGE,cAAgBn+B,GAAO86B,IAAI4C,YAAY3/B,IAAIiC,GAC3Cm4B,gBAAkBn4B,GAAO86B,IAAIsD,kBAAkBp+B,EAAI86B,IAAIE,SAASnnB,IAAI7T,IAEpEqtB,QAAUgR,GAAavD,IAAIwD,mBAAmB,IAAKxD,IAAI9N,gBAAiBF,KAAMruB,KAAKD,IAAI,EAAG6/B,KAC1FjR,YAAcmR,GAAiBzD,IAAIwD,mBAAmB,CAAExR,KAAM,EAAGC,SAAUtuB,KAAKD,IAAI,EAAG+/B,KACvFD,mBAAqBhQ,GAAUwM,IAAIwD,mBAAmBhQ,GAEtDlF,WAAanrB,GAAU68B,IAAI1R,WAAWnrB,GAEtC6W,aAAe3B,GAAY2B,GAAaimB,EAAS5nB,GACjDmX,gBAAkBnX,GZ/TCmX,EAACnoB,EAAiBgR,EAAmC,MAChF,MAAMqrB,EAAM1pB,GAAa3S,EAAKgR,GACxBsrB,EAAMtrB,EAAQurB,YAAcrpB,GAAW,GACvCxF,EAAO,IAAI8uB,KAAK,CAACF,EAAMD,GAAM,CAAEp+B,KAAM,4BAC3CwP,GAAaC,EAAMwE,GAAiBlB,EAAQrD,SAAU4E,KAAmB,SY2TnC4V,CAAgByQ,EAAS5nB,GACvDoX,kBAAoBpX,GZiBCuL,OAAOvc,EAAiBgR,EAAqC,MAC1F,MAAM4D,EAAQoD,GAAUhY,EAAKgR,GACvBtD,EAAO,IAAI8uB,KAAK,CAAC5nB,GAAoB,CACvC3W,KAAM,sEAEVwP,GAAaC,EAAMwE,GAAiBlB,EAAQrD,SAAU4E,KAAmB,UYtBjC6V,CAAkBwQ,EAAS5nB,GAC3DqX,kBAAoBrX,GAAY2nB,IAAI8D,WAAWzrB,GAE/C0rB,kBAAoB7+B,GAAO86B,IAAI+D,kBAAkB7+B,GACjD8+B,wBAA0Bz+B,GAAQy6B,IAAIgE,wBAAwB,IAAIzhC,IAAIgD,IACtE0+B,wBAAyBA,IAAM5gC,MAAM4P,KAAK+sB,IAAIkE,sBAE9CC,oBAAqBA,IAAMnE,IAAIhJ,iBAC/BoN,oBAAsB5Q,GAAUwM,IAAIoE,oBAAoB5Q,GACxD6E,uBAAwBA,CAACr1B,EAAOqhC,KAC5B,MAAMltB,EAAoB6oB,IAAIhJ,iBAAiBlzB,OAAQgV,GAAcA,IAAM9V,QACrDuE,IAAlB88B,EAA6BltB,EAAQhJ,KAAKnL,GACzCmU,EAAQmtB,OAAO9gC,EAAM6gC,EAAe,EAAGltB,EAAQ5T,QAAS,EAAGP,GAChEg9B,IAAIoE,oBAAoBjtB,IAE5BihB,0BAA4Bp1B,GACxBg9B,IAAIoE,oBAAoBpE,IAAIhJ,iBAAiBlzB,OAAQgV,GAAcA,IAAM9V,IAC7EuhC,wBAAyBA,CAACr/B,EAAIyrB,IAAeqP,IAAIuE,wBAAwBr/B,EAAIyrB,GAC7E6T,oBAAqBA,EAAGC,cACpB,MAAMC,EAAQ1E,IAAI2E,WAAW5rB,IAAI0rB,GACjC,OAAOC,EAAQA,EAAMve,YAAY7b,IAAKpE,GAAMA,EAAEhB,IAAM,IAGxD0/B,oBAAqBA,IAAM5E,IAAIvZ,iBAC/B8R,oBAAsB/E,GAAUwM,IAAIzH,oBAAoB/E,GAExDqR,kBAAmBA,EAAG3/B,KAAIlC,WAAYg9B,IAAI6E,kBAAkB3/B,EAAIlC,GAChE8hC,iBAAkBA,EAAG5/B,KAAIlC,QAAO+hC,yBAC5B/E,IAAI8E,iBAAiB5/B,EAAIlC,EAAO+hC,EAAqB,OACzDC,YAAaA,CAAC9/B,EAAIlC,KACd,MAAMiiC,EAAUjF,IAAIkF,YACpB,OAAOD,GAAWA,EAAQ//B,KAAOA,GAAM+/B,EAAQjiC,QAAUA,EAAQ,OAAS,QAE9EmiC,iBAAkBA,EAAGjgC,KAAIlC,QAAOG,YAC5B,MAAM8hC,EAAUjF,IAAIkF,YAChBD,GAAWA,EAAQ//B,KAAOA,GAAM+/B,EAAQjiC,QAAUA,GAAOg9B,IAAIoF,aAAajiC,IAGlFiE,aAAcA,CAAClC,EAAIlC,KACf,MAAMgC,EAAMg7B,IAAIE,SAASnnB,IAAI7T,GACvB4B,EAAMk5B,IAAIsB,UAAUt+B,GAC1B,OAAOgC,GAAO8B,EAAMM,EAAapC,EAAK8B,EAAKm5B,QAAW14B,GAE1D89B,cAAeA,CAACngC,EAAIlC,KAChB,MAAMgC,EAAMg7B,IAAIE,SAASnnB,IAAI7T,GAC7B,OAAO86B,IAAIsF,gBACPpgC,EACAlC,EACAgC,EACAg7B,IAAIQ,UAAUznB,IAAI7T,IAAO,CAAEI,KAAM,OAAQJ,KAAImgB,MAAO,EAAGQ,OAAQ,QAGvE0f,aAAcA,CAACrgC,EAAIlC,KACfwiC,GAAgBruB,SAAU,EAC1B6oB,IAAIyF,eAAe,CAAEvgC,KAAIlC,WAG7B0iC,gBAAkB3lB,GAAWigB,IAAI0F,gBAAgB3lB,GACjD4lB,OAAQA,EAAGlb,OAAMD,UACb,MAAMob,EAAWpG,GAAYroB,QACxByuB,SACQr+B,IAATkjB,IAAoBmb,EAASC,WAAapb,QAClCljB,IAARijB,IAAmBob,EAASE,UAAYtb,KAEhDub,kBAAmBA,KAAAA,CACftb,KAAM+U,GAAYroB,SAAS0uB,YAAc,EACzCrb,IAAKgV,GAAYroB,SAAS2uB,WAAa,IAG3C,SAAItY,GACA,OAAOwS,IAAIxS,KACf,EACAkS,YAAaA,IAAMM,IAAIN,cACvBsG,eAAgB1G,IAEpB,OAAOW,GACR,IACEJ,GAAO1oB,QAAQ9P,MAAKw4B,GAAO1oB,QAAQ9P,IAAM04B,IAI9C,MAAMkG,GAAY9nC,EAAMk1B,QACpB,KAAA,CACI9G,WAAY6P,GACN73B,EAA+C63B,IAC/C,KACN8J,MAAO7J,GAAwB93B,EAA2B83B,IAAyB,KACnF/c,OAAQgd,GAAwB/3B,EAAyC+3B,IAAyB,KAClGzF,OAAQ0F,GAA0Bh4B,EAAuCg4B,IAA2B,OAExG,CAACH,GAA4BC,GAAuBC,GAAuBC,MAKxE3F,GAAWuL,IAAgB/qB,GAC9BwkB,GACAmD,IAAcoH,SAASvP,WAAawC,GACnC5F,GAAUqI,KAAoBrI,EAAOsM,QAGnC7K,GAAasB,IAAkBnf,GAClC4kB,GACA+C,IAAcj7B,QAAQmxB,aAAewE,GACpCjG,GAAUyI,KAAsBzI,EAAOsM,QAGrC5N,GAAiBsR,IAAsBpsB,GAC1CskB,GACA,CACI1J,KAAM+M,IAAcjM,YAAYZ,iBAAiBF,MAAQ,EACzDC,SAAU8M,IAAcjM,YAAYZ,iBAAiBD,UAAYA,IAEpEuB,GAAUmI,KAA0BnI,EAAOsM,QAGzCrM,GAAuBI,IAA4Bzc,GACtD8kB,GACA+J,GAAU1Z,YAAcwS,IAAczmB,SAASmb,uBAAyB4F,GACvE7F,IACO4I,IAA4Bx3B,EAAkBw3B,GAA4B5I,GAC9E2I,KAAgC3I,EAAOsM,SAIxCzR,GAASC,IAAclX,GAC1BokB,GACAuD,IAAc1Q,SAAW,UACxBlrB,GAAUs4B,KAAkBt4B,EAAO28B,QAGjClD,GAAeqF,IAAoB7qB,GACtCylB,GACAoJ,GAAUpP,QAAUkI,IAAcnC,eAAiBvD,GAClD7F,IACO+I,IAAyB33B,EAAkB23B,GAAyB/I,GACxEsJ,KAAwBtJ,EAAOsM,SAIhC9I,GAAkBoN,IAAuBhtB,GAC5C8mB,GACAa,IAAcqH,aAAa5S,OAAS4F,GACnC5F,GAAU2K,KAA2B3K,EAAOsM,QAG1CrZ,GAAkB8R,IAAuBnhB,GAC5CmnB,GACAQ,IAAc9H,aAAazD,OAAS6F,GACnC7F,GAAUgL,KAA2BhL,EAAOsM,OAG3CuG,GAA2BloC,EAAMk1B,QACnC,IAAO2K,GAAgC,IAAIz7B,IAAkBy7B,SAAiCz2B,EAC9F,CAACy2B,MAEEkG,GAAsBF,IAA2B5sB,GACpDivB,GACAloC,EAAMk1B,QAAQ,IAAM,IAAI9wB,IAAkBw8B,IAAcuH,aAAaC,gBAAkB,IAAK,IAC3FhhC,GAAQ04B,KAAoC56B,MAAM4P,KAAK1N,GAAMu6B,OAG5D0G,GAAsBroC,EAAMk1B,QAC9B,SAAiC9rB,IAA1B41B,GAAsCh4B,EAAwBg4B,IAAuB53B,SAAMgC,EAClG,CAAC41B,MAEEyF,GAAaI,IAAkB5rB,GAClCovB,GACAroC,EAAMk1B,QAAQ,IAAM,IAAI9wB,IAAqB,IAC5CgD,GAAQ63B,KAA4B,CAAE93B,KAAM,UAAWC,OAAOu6B,QAK5D2G,GAAeC,IAAoBvoC,EAAMwZ,SAC5C,IAAMsuB,GAAUC,OAASnH,IAAczmB,SAASmuB,eAAiB,OAE9D9oB,GAAcgpB,IAAmBxoC,EAAMwZ,SAAiC,KAC3E,GAAIsuB,GAAU3mB,OAAQ,OAAO2mB,GAAU3mB,OACvC,MAAMsnB,EAAO7H,IAAczmB,SAASuuB,WACpC,IAAKD,EAAM,MAAO,CAAA,EAClB,MAAM74B,EAA8B,CAAA,EAIpC,OAHAV,OAAOC,KAAKs5B,GAAMphC,QAASxC,IACnB4jC,EAAK5jC,GAAOjF,QAAOgQ,EAAI/K,GAAS4jC,EAAK5jC,GAAOjF,SAE7CgQ,KAEJ+4B,GAAgBC,IAAqB5oC,EAAMwZ,SAAqC,IAAM,IAAIiB,MAC1FssB,GAAa8B,IAAkB7oC,EAAMwZ,SAA4B,OACjEsvB,GAAW7B,IAAgBjnC,EAAMwZ,cAAcpQ,IAC/C2/B,GAAazB,IAAkBtnC,EAAMwZ,SAA4B,MAClE6tB,GAAkBrnC,EAAM+Y,QAAO,IAC9ByW,GAAiBwZ,IAAsBhpC,EAAMwZ,SAElD,CACEwL,MAAM,EACN6G,SAAU,QAEPod,GAAYC,IAAiBlpC,EAAMwZ,SAA0D,OAC7F2vB,GAAeC,IAAoBppC,EAAMwZ,SAAwB,OAEjE6vB,GAAYC,IAAiBtpC,EAAMwZ,SAA2C,MAC/E+vB,GAA0B,OAAfF,IACVG,GAAMC,IAAWzpC,EAAMwZ,SAAqF,OAC5GmuB,GAAW+B,IAAgB1pC,EAAMwZ,SAAS,GAC3CmwB,GAAY3pC,EAAM+Y,OAAO,GACzB6wB,GAAmB5pC,EAAM+Y,OAA4B,OAGpD8wB,GAAeC,IAAoB9pC,EAAMwZ,SAAmD,KAAA,CAC/FyB,OACA9O,IAAK,IAAIsO,OAEPsvB,GAAqCF,GAAc5uB,OAASA,EAAO4uB,GAAc19B,IAAMgvB,GACvF6H,GAAiBhjC,EAAM4Z,YACzB,CAAC7S,EAAkBF,KACfijC,GAAkB3c,IACd,MAAMhhB,EAAM,IAAIsO,IAAI0S,EAAKlS,OAASA,EAAOkS,EAAKhhB,IAAM,IAEpD,OADAA,EAAID,IAAInF,EAAIF,GACL,CAAEoU,OAAM9O,UAGvB,CAAC8O,KAKGrb,MAAOoqC,GAAe5pC,OAAQ6pC,abtmBYlqC,EAAgCmqC,GAAU,GAC5F,MAAO54B,EAAM64B,GAAWnqC,EAAMwZ,SAAsB,CAAE5Z,MAAO,EAAGQ,OAAQ,IAoBxE,OAlBAJ,EAAM+X,gBAAgB,KAClB,MAAM+K,EAAK/iB,EAAIiZ,QACf,IAAK8J,IAAOonB,EAAS,OACrB,MAAM1d,EAASA,KACX,MAAM5sB,EAAQkjB,EAAGsnB,YACXhqC,EAAS0iB,EAAGunB,aAClBF,EAAShd,GAAUA,EAAKvtB,QAAUA,GAASutB,EAAK/sB,SAAWA,EAAS+sB,EAAO,CAAEvtB,QAAOQ,YAGxF,GADAosB,IAC8B,oBAAnBa,eAEP,OADAnnB,OAAOkgB,iBAAiB,SAAUoG,GAC3B,IAAMtmB,OAAOqnB,oBAAoB,SAAUf,GAEtD,MAAMY,EAAW,IAAIC,eAAeb,GAEpC,OADAY,EAASE,QAAQxK,GACV,IAAMsK,EAASI,cACvB,CAACztB,EAAKmqC,IAEF54B,CACX,CaglB6Dg5B,CAAejJ,IAClEkJ,GAAgBlmC,EAAgB6rB,KAAY,EAC5C6M,GAAYv3B,KAAKglC,MAAMxN,EAAgBuN,IACvCE,GAAejlC,KAAKglC,MAAMvN,EAAqBsN,IAI/CrI,GAAaliC,EAAMk1B,QAAuB,KAC5C,MAAMtlB,EAAqB,GAM3B,OALAqL,EAAK5T,QAAS8B,IACV,MAAMpC,EAAKH,EAAgBuC,EAAKrC,GAC5BC,SACJ6I,EAAII,KAAK,CAAEjJ,KAAIF,IAAKkjC,GAAanvB,IAAI7T,IAAOoC,MAEzCyG,GACR,CAACqL,EAAMnU,EAAUijC,KAEdhI,GAAW/hC,EAAMk1B,QAAQ,KAC3B,MAAM/oB,EAAM,IAAIsO,IAIhB,OAHAynB,GAAW76B,QAASsW,GAAUxR,EAAID,IAAIyR,EAAM5W,GAAI4W,EAAM9W,OACrD44B,IAAYpT,KAAO,IAAIhlB,QAASR,GAAQsF,EAAID,IAAItF,EAAgBC,EAAKC,GAAWD,KAChF44B,IAAYvS,QAAU,IAAI7lB,QAASR,GAAQsF,EAAID,IAAItF,EAAgBC,EAAKC,GAAWD,IAC7EsF,GACR,CAAC+1B,GAAYzC,GAAY34B,IAItB4jC,GAAc1qC,EAAMk1B,QAAQ,IAAM2G,EAAY1vB,IAAKxD,GAAQ4E,GAAgB5E,IAAO,CAACkzB,IAEnF/U,GAAiB9mB,EAAMk1B,QAAQ,KACjC,MAAM/oB,EAAM,IAAIsO,IAEhB,OADAiwB,GAAYrjC,QAASsB,GAAQwD,EAAID,IAAIvD,EAAI9D,MAAO8D,IACzCwD,GACR,CAACu+B,KAEE7jB,GAAiB7mB,EAAMk1B,QACzB,IAAOoE,GAAqB,GAAKT,GAAiBlzB,OAAQd,GAAUiiB,GAAehiB,IAAID,IACvF,CAACg0B,GAAkB/R,GAAgBwS,KAEjCqR,GAAiB9jB,GAAezhB,OAAS,EAEzCwlC,GAAiB5qC,EAAMk1B,QAAiC,KAC1D,IAAKyV,GAAgB,OAAO,KAC5B,MAAME,EAAmC,IAA1BhkB,GAAezhB,OAAe0hB,GAAelM,IAAIiM,GAAe,SAAMzd,EACrF,OAAOmE,GAAmB,CACtB1I,MAAOd,EACP4J,WAAYk9B,EAAUA,EAAOl9B,YAAck9B,EAAOhmC,MAASyqB,GAAWxZ,yBACtElW,MhBlqByB,IgBmqBzBoC,SAAU,IACV8L,UAAU,EACVC,YAAY,EACZC,UAAU,EACVG,WAAW,EACXC,YAAY,EACZC,UAAU,EACVE,eAAe,EACfG,gBAAgB,KACZwxB,MAET,CAACyK,GAAgB9jB,GAAgBC,GAAgBwI,GAAWxZ,yBAA0BoqB,KAEnF+C,GAAqBjjC,EAAMk1B,QAAQ,KACrC,IAAKoT,IAA0C,IAAzBA,GAAcljC,OAAc,OAAOslC,GACzD,MAAMI,EAAO,IAAI1mC,IACXwL,EAA0B,GAWhC,OAVA04B,GAAcjhC,QAASxC,IACnB,MAAM8D,EAAMme,GAAelM,IAAI/V,GAC3B8D,IAAQmiC,EAAKhmC,IAAID,KACjBimC,EAAKxjC,IAAIzC,GACT+K,EAAII,KAAKrH,MAGjB+hC,GAAYrjC,QAASsB,IACZmiC,EAAKhmC,IAAI6D,EAAI9D,QAAQ+K,EAAII,KAAKrH,KAEhCiH,GACR,CAAC04B,GAAeoC,GAAa5jB,KAE1BikB,GAAkB/qC,EAAM4Z,YACzB/U,IACG,MAAMG,EAAQswB,GAAsBzwB,GACpC,OAAc,IAAVG,SACUoE,IAAVpE,IAAyD,IAAlC6hB,GAAe/a,QAAQjH,KAGtD,CAACywB,GAAuBzO,KAGtBqc,GAAqBljC,EAAMk1B,QAAQ,KACrC,GAAImU,GAAY,CACZ,IAAI/oB,EAAO2iB,GAAmBt9B,OAAQgD,GAAQoiC,GAAgBpiC,EAAI9D,QAClE,GAAIwkC,GAAW9uB,OAAQ,CACnB,MAAMywB,EAAS,IAAI5mC,IAAIilC,GAAW9uB,QAClC+F,EAAO2iB,GAAmBt9B,OAAQgD,GAAQqiC,EAAOlmC,IAAI6D,EAAI9D,OAC7D,MAAWwkC,GAAWxuB,aAClByF,EAAO2iB,IAEX,OAAO3iB,EAAK3a,OAAQgD,IAASA,EAAI4F,cACrC,CACA,OAAO00B,GAAmBt9B,OAAQgD,GAAQoiC,GAAgBpiC,EAAI9D,SAC/D,CAACo+B,GAAoB8H,GAAiB1B,KAEnC4B,GAASjrC,EAAMk1B,QAAQ,KACzB,MAAM5b,EAA4B,GAC9BslB,IAAmBtlB,EAAStJ,KAAKrB,IACjC+wB,IAAuBpmB,EAAStJ,KAAKpB,IACzC,MAAMs8B,EAAa9R,GAAuB,IAAMqF,GAAcnS,MAAQ,IAAI3mB,OAAQgV,GAAMA,IAAM5W,GACxFonC,EAAc/R,GACd,IACCqF,GAAcxR,OAAS,IAAItnB,OAAQgV,GAAMA,IAAM5W,GAChDqnC,EAAiB,IAAI3wB,IAC3ByoB,GAAmB77B,QAASsB,GAAQyiC,EAAel/B,IAAIvD,EAAI9D,MAAO8D,IAClE,MAAM2jB,EAAwBhT,EAASnI,QACnCy5B,IAAgBte,EAAKtc,KAAK46B,IAC9BM,EAAW7jC,QAASsT,IAChB,MAAMhS,EAAMyiC,EAAexwB,IAAID,GAC3BhS,GAAK2jB,EAAKtc,KAAKrH,KAEvB,MAAMskB,EAAyB,GAC/Bke,EAAY9jC,QAASsT,IACjB,MAAMhS,EAAMyiC,EAAexwB,IAAID,GAC3BhS,QAAOuiC,EAAWp/B,QAAQ6O,IAAWsS,EAAMjd,KAAKrH,KAExD,MAAM0iC,EAASnI,GAAmBv9B,OAC7BgD,IAA0C,IAAlCuiC,EAAWp/B,QAAQnD,EAAI9D,aAAiBsmC,EAAYr/B,QAAQnD,EAAI9D,QAEvEymC,EAAUhf,EAAK1N,OAAOysB,EAAQpe,GAC9B9L,EArnBQoqB,EAACjrB,EAAuBkrB,EAAmBC,KAC7D,MAAMjjB,EAA+BlI,EAAKnU,IAAKxD,IAC3C,MAAMrD,EAAMqD,EAAI3G,UAAY2C,EACtBY,EAAMoD,EAAI8F,UAAYi9B,IACtBC,EAAWF,EAAU9iC,EAAI9D,OAC/B,OAAI8mC,EAAiBtmC,EAAMsmC,EAAUrmC,EAAKC,GACtCoD,EAAIijC,MAAQjjC,EAAIijC,KAAO,EAAU,KAC9BvmC,EAAMsD,EAAI/I,OAAS,IAAK0F,EAAKC,KAElCsmC,EAAiB,GACvB,IAAIC,EAAa,EAKjB,GAJAtjB,EAAOnhB,QAAQ,CAACkZ,EAAGtD,KACL,OAANsD,EAAYsrB,EAAK77B,KAAKiN,GACrB6uB,GAAcvrB,IAEnBsrB,EAAKzmC,OAAS,EAAG,CACjB,IAAI2mC,EAAiBvmC,KAAKD,IAAI,EAAGimC,EAAYM,GACzCE,EAAgBH,EAAKh7B,OAAO,CAACC,EAAKmM,IAAMnM,EAAOwP,EAAKrD,GAAG2uB,KAAiB,GACxE7gB,EAAS8gB,EAAK16B,QACd86B,GAAU,EACd,KAAOA,GAAWlhB,EAAO3lB,OAAS,GAAG,CACjC6mC,GAAU,EACV,IAAK,IAAIzvB,EAAI,EAAGA,EAAIuO,EAAO3lB,OAAQoX,GAAK,EAAG,CACvC,MAAMS,EAAI8N,EAAOvO,GACX7T,EAAM2X,EAAKrD,GACX3X,EAAMqD,EAAI3G,UAAY2C,EACtBY,EAAMoD,EAAI8F,UAAYi9B,IACtBQ,EAAQF,EAAgB,EAAKD,EAAkBpjC,EAAIijC,KAAmBI,EAAgB,EAC5F,GAAIE,EAAQ5mC,GAAO4mC,EAAQ3mC,EAAK,CAC5B,MAAM4mC,EAAQD,EAAQ5mC,EAAMA,EAAMC,EAClCijB,EAAOvL,GAAKkvB,EACZJ,EAAiBvmC,KAAKD,IAAI,EAAGwmC,EAAiBI,GAC9CH,GAAiBrjC,EAAIijC,KACrB7gB,EAASA,EAAOplB,OAAQymC,GAAQA,IAAQnvB,GACxCgvB,GAAU,EACV,KACJ,CACJ,CACJ,CACAlhB,EAAO1jB,QAAS4V,IACZ,MAAMtU,EAAM2X,EAAKrD,GACjBuL,EAAOvL,GACH+uB,EAAgB,EACVxmC,KAAK6Z,MAAO0sB,EAAkBpjC,EAAIijC,KAAmBI,GACpDrjC,EAAI3G,UAAY,IAEnC,CACA,OAAOwmB,GAskBY+iB,CAAcD,EAAStB,GAAexqB,IAC/C6sB,EAAa/f,EAAKlnB,OAASkU,EAASlU,QAAUwlC,GAAiB,EAAI,IAAM3d,EAAM7nB,OAAS,EACxF+U,EAA0B,GAChC,IAAImyB,EAAI,EACJC,EAAa,EACjBjB,EAAQjkC,QAAQ,CAACsB,EAAKsU,KAClB,MAAMrd,EAAQuhB,EAAOlE,GACfuvB,EAASvvB,EAAIqP,EAAKlnB,OAClBqnC,EAAUxvB,GAAKqP,EAAKlnB,OAASimC,EAAOjmC,OAC1C+U,EAAQnK,KAAK,CACTrH,MACA/I,QACA84B,OAAQ8T,EAAS,OAASC,EAAU,QAAU,KAC9CnvB,OAAQkvB,EAASD,EAAa,EAC9BD,IACAI,WAAYF,GAAUvvB,IAAMqP,EAAKlnB,OAAS,EAC1CunC,aAAcF,GAAWxvB,IAAMqP,EAAKlnB,OAASimC,EAAOjmC,SAEpDonC,IAAQD,GAAc3sC,GAC1B0sC,GAAK1sC,IAET,IAAIgtC,EAAc,EAClB,IAAK,IAAI3vB,EAAI9C,EAAQ/U,OAAS,EAAG6X,GAAK,GACR,UAAtB9C,EAAQ8C,GAAGyb,OADsBzb,GAAK,EAE1C9C,EAAQ8C,GAAGK,OAASsvB,EACpBA,GAAezyB,EAAQ8C,GAAGrd,MAE9B,MAAO,CAAEua,UAAS0yB,WAAYP,EAAGD,aAAYS,UAAWxgB,EAAKlnB,OAAQ2nC,WAAY9f,EAAM7nB,SACxF,CACCw5B,GACAc,GACAjB,GACArF,GACA8J,GACA0H,GACAZ,GACAxqB,KAGEwtB,GAA2BhtC,EAAMk1B,QAAQ,KAC3C,MAAM/oB,EAAM,IAAIsO,IAGhB,OAFAwwB,GAAO9wB,QAAQ9S,QAASqT,GAAMvO,EAAID,IAAIwO,EAAE/R,IAAI9D,MAAO6V,EAAE/R,MACjDiiC,IAAgBz+B,EAAID,IAAInI,EAAuB6mC,IAC5Cz+B,GACR,CAAC8+B,GAAO9wB,QAASywB,KAEdzH,GAAYnjC,EAAM4Z,YACnB/U,GACGiiB,GAAelM,IAAI/V,IAAWmoC,GAAyBpyB,IAAI/V,GAC/D,CAACiiB,GAAgBkmB,KAKfC,GAAgBjtC,EAAMk1B,QAAQ,KAChC,MAAMtlB,EAAqE,GAS3E,OARAknB,GAAY7P,MAAM5f,QAASoE,IACvB,MAAM9C,EAAMme,GAAelM,IAAInP,EAAK5G,OACpC,IAAK8D,IAA0B,IAAnBA,EAAIoF,WAAsB,OACtC,MAAMwoB,EAAWnpB,GAAyBzE,GAAKa,KAAMiuB,GAAOA,EAAGzyB,QAAUyG,EAAK8qB,UAC9E,IAAKA,EAAU,OACf,MAAM7N,EAAK6N,EAAS3qB,iBAAiBH,EAAM9C,GACvC+f,GAAI9Y,EAAII,KAAK,CAAErH,MAAK+f,SAErB9Y,GACR,CAACknB,GAAY7P,MAAOH,KAEjB+K,GAAoB7xB,EAAMk1B,QAC5B,KAAO4B,GAAYjF,mBAAqB,IAAI1lB,IAAKQ,GAAM7D,OAAO6D,GAAG0D,QAAQ1K,OAAQgH,GAAY,KAANA,GACvF,CAACmqB,GAAYjF,oBAGXqb,GAAqBltC,EAAMk1B,QAAQ,KACxB4B,GAAYyE,gCAAkC2H,GAAqBD,IACpEt9B,OAAQgD,IAA2B,IAAnBA,EAAIoF,YAAqC,YAAbpF,EAAIxB,MAC7D,CAAC2vB,GAAYyE,gCAAiC2H,GAAoBD,KAE/DkK,GAAkBntC,EAAMk1B,QAAQ,KAClC,GAA6B,IAAzB+X,GAAc7nC,QAA6C,IAA7BysB,GAAkBzsB,OAAc,OAAO88B,GACzE,MAAMkL,EAAoD,SAAxCtW,GAAYC,eAAiB,OACzCsW,EAA+D,SAAnDvW,GAAYwW,0BAA4B,OACpDC,EAAc7L,GAAO1oB,QAAQ9P,IAC7BskC,EAAW3b,GAAkB1lB,IAAKN,IACpC,MAAM4hC,EAAU5hC,EAAON,cAejBwf,EAdYmiB,GAAmB/gC,IAAKxD,IACtC,GAAIA,EAAI+kC,sBAAuB,CAC3B,MAAMC,EAAShlC,EAAI+kC,sBAAsB7hC,EAAQlD,EAAK4kC,GACtD,OAAOI,EAAS,CAAEhlC,MAAK+f,GAAIilB,GAAW,IAC1C,CAQA,MAAO,CAAEhlC,MAAK+f,GAPsBA,CAAC1jB,EAAO6B,KACxC,GAAI9B,EAAMC,GAAQ,OAAO,EAEzB,IAAmC,IADjB4E,EAAuBF,EAAkB1E,EAAO6B,EAAK8B,EAAK4kC,IAAchiC,cAC5EO,QAAQ2hC,GAAiB,OAAO,EAE9C,OAAgC,KADH,iBAAVzoC,EAAqB,GAAK8D,OAAO9D,GAAOuG,eAChDO,QAAQ2hC,OAIF9nC,OAAOC,SAChC,OAAQiB,GAAWkkB,EAAO6C,KAAK,EAAGjlB,MAAK+f,QAASA,EAAGzf,EAAapC,EAAK8B,EAAK4kC,GAAc1mC,EAAK8B,EAAK4kC,MAEtG,OAAOrL,GAAWv8B,OAAO,EAAGkB,UACxB,GAAIomC,GAAc7nC,OAAS,EAAG,CAC1B,MAAMwoC,EAAUX,GAAc9gC,IAAI,EAAGxD,MAAK+f,QACtCA,EAAGzf,EAAapC,EAAK8B,EAAK4kC,GAAc1mC,EAAK8B,EAAK4kC,IAGtD,KADaH,EAAWQ,EAAQ38B,MAAMrL,SAAWgoC,EAAQhgB,KAAKhoB,UACnD,OAAO,CACtB,CACA,GAAI4nC,EAASpoC,OAAS,EAAG,CACrB,MAAMwoC,EAAUJ,EAASrhC,IAAKuc,GAAOA,EAAG7hB,IACxC,OAAOwmC,EAAWO,EAAQ38B,MAAMrL,SAAWgoC,EAAQhgB,KAAKhoB,QAC5D,CACA,OAAO,KAEZ,CACCs8B,GACA+K,GACApb,GACAqb,GACApW,GAAYC,cACZD,GAAYwW,2BAKVO,GAAiB7tC,EAAMk1B,QAAQ,KACjC,MAAMqY,EAAc7L,GAAO1oB,QAAQ9P,IAC7B4kC,EAAUrV,GACX9yB,OAAQ8F,GAASA,EAAK2F,MAAQ3F,EAAK5G,QAAUd,GAC7CoI,IAAKV,IACF,MAAM9C,EAAMme,GAAelM,IAAInP,EAAK5G,OACpC,OAAK8D,IAAwB,IAAjBA,EAAImF,SACT,CACHnF,MACAolC,IAAmB,SAAdtiC,EAAK2F,MAAkB,EAAK,EACjC48B,WAAYrlC,EAAIslC,gBAAkB5iC,GAAqB1C,EAAIxB,OAJpB,OAO9CxB,OAAOC,SACZ,OAAuB,IAAnBkoC,EAAQ1oC,OAAqB,KAC1B,CAACqH,EAAgBC,KACpB,IAAK,IAAIuQ,EAAI,EAAGA,EAAI6wB,EAAQ1oC,OAAQ6X,GAAK,EAAG,CACxC,MAAMtU,IAAEA,EAAGolC,IAAEA,EAAGC,WAAEA,GAAeF,EAAQ7wB,GACnC7S,EAAKnB,EAAawD,EAAE5F,IAAK8B,EAAK4kC,GAC9BljC,EAAKpB,EAAayD,EAAE7F,IAAK8B,EAAK4kC,GAC9B/kB,EAASwlB,EACX5jC,EACAC,EACA,CAAEtD,GAAI0F,EAAE1F,GAAIlC,MAAO8D,EAAI9D,MAAOG,MAAOoF,EAAIvD,IAAK4F,EAAE5F,IAAKqC,IAAKqkC,GAC1D,CAAExmC,GAAI2F,EAAE3F,GAAIlC,MAAO8D,EAAI9D,MAAOG,MAAOqF,EAAIxD,IAAK6F,EAAE7F,IAAKqC,IAAKqkC,IAE9D,GAAe,IAAX/kB,EAAc,OAAOA,EAASulB,CACtC,CACA,OAAO,IAEZ,CAACtV,GAAW3R,KAETonB,GAAcluC,EAAM4Z,YACrB4D,GACQqwB,GACErwB,EACFrR,IAAI,CAACwR,EAAOuB,KAAK,CAAQvB,QAAOuB,WAChC9N,KAAK,CAAC3E,EAAGC,IAAMmhC,GAAephC,EAAEkR,MAAOjR,EAAEiR,QAAUlR,EAAEyS,MAAQxS,EAAEwS,OAC/D/S,IAAKV,GAASA,EAAKkS,OAJIH,EAMhC,CAACqwB,KAKCtU,GAAuBv5B,EAAMk1B,QAC/B,KAAA,IAAY1kB,MAAmC8vB,KAC/C,CAACA,KAEC6N,IAAqBzU,IAAsBxqB,OAAOC,KAAKmZ,IAAkBljB,OAAS,EAElFgpC,GAAkBpuC,EAAM4Z,YACzB6N,IACG,MAAMkkB,EAAWhD,GAAe/tB,IAAI6M,EAAK1gB,IACzC,YAAiBqC,IAAbuiC,EAA+BA,EAC/BxL,GACOA,GAAyB,CAC5Bh5B,KAAM,QACNJ,GAAI0gB,EAAK1gB,GACTmgB,MAAOO,EAAKP,MACZQ,OAAQD,EAAKC,OACbC,cAAeF,EAAKE,cACpBC,YAAaH,EAAKG,YAClBC,cAAeJ,EAAKI,cACpBvkB,SAAU,GACV+qC,QAAS,GACT7b,YAAY,KAGqB,IAAlCyN,IAAwCxY,EAAKP,MAAQ+Y,IAEhE,CAAC0I,GAAgBxI,GAA0BF,KAGzCqO,GAAYtuC,EAAMk1B,QAAQ,KAC5B,MAAMmN,EAAY,IAAI5nB,IAChB+rB,EAAa,IAAI/rB,IACvB,IAAKkwB,GAAgB,CACjB,MAAMt5B,EAAS68B,GAAYf,IAM3B,MAAO,CAAEoB,YAL4Bl9B,EAAOlF,IAAKwR,IAC7C,MAAM8J,EAAwB,CAAEtgB,KAAM,OAAQJ,GAAI4W,EAAM5W,GAAImgB,MAAO,EAAGQ,OAAQ,MAE9E,OADA2a,EAAUn2B,IAAIyR,EAAM5W,GAAI0gB,GACjB,CAAE1gB,GAAI4W,EAAM5W,GAAII,KAAM,OAAQN,IAAK8W,EAAM9W,IAAK4gB,OAAMP,MAAO,KAEhDqb,aAAclxB,EAAQgxB,YAAWmE,aAAYgI,KAAM,GAC7E,CACA,MAAMjB,EAAc7L,GAAO1oB,QAAQ9P,IACnC,IAAIslC,EAAO5nB,GAAeumB,GAAiBtmB,GAAgBC,GAAgBymB,GAC3E,MAAMkB,EAAehW,GAAUjvB,KAAMiC,GAASA,EAAK5G,QAAUd,GAAyB0H,EAAK2F,MAiB3Fo9B,EVr5BqBE,EACzBvmB,EACAwmB,EACAC,KAEA,MAAMC,EAAYA,CAAC5mB,EAA2Bf,KAC1C,MAAM8mB,EAAaW,EAAgBA,EAAcznB,GAAS,KACpD7V,EAAS28B,EACT/lB,EACK9b,IAAI,CAACsb,EAAMvI,KAAK,CAAQuI,OAAMvI,WAC9B9N,KAAK,CAAC3E,EAAGC,IAAMshC,EAAWvhC,EAAEgb,KAAM/a,EAAE+a,OAAShb,EAAEyS,MAAQxS,EAAEwS,OACzD/S,IAAKV,GAASA,EAAKgc,MACxBQ,EAYN,OAXA5W,EAAOhK,QAASogB,IACZ,GAAIA,EAAKK,YAAY1iB,OAAS,EAAG,CAC7BqiB,EAAKK,YAAc+mB,EAAUpnB,EAAKK,YAAaZ,EAAQ,GACvD,MAAMc,EAA6B,GACnCP,EAAKK,YAAYzgB,QAAS2pB,GAAUA,EAAMhJ,YAAY3gB,QAASU,GAAMigB,EAAYhY,KAAKjI,KACtF0f,EAAKO,YAAcA,CACvB,MACIP,EAAKM,OAAS6mB,EAAWnnB,EAAKM,QAC9BN,EAAKO,YAAcP,EAAKM,SAGzB1W,GAEX,OAAOw9B,EAAU1mB,EAAO,IU23BbumB,CAAcF,EAhBEtnB,IACnB,MAAMriB,EAAQgiB,GAAeK,GACvBve,EAAMme,GAAelM,IAAI/V,GAC/B,IAAK8D,EAAK,OAAO,KACjB,MAAM6vB,EAAWiW,GAAgBhW,GAAUjvB,KAAMiC,GAASA,EAAK5G,QAAUA,GAAS4G,EAAK2F,MACvF,IAAKonB,EAAU,OAAO,KACtB,MAAMwV,EAAarlC,EAAIslC,gBAAkB5iC,GAAqB1C,EAAIxB,MAC5D4mC,EAAwB,SAAlBvV,EAASpnB,MAAkB,EAAK,EAC5C,MAAO,CAAC3E,EAAqBC,IACzBshC,EACIvhC,EAAEmb,YACFlb,EAAEkb,YACF,CAAE7gB,GAAI0F,EAAE1F,GAAIlC,QAAOG,MAAOyH,EAAEmb,YAAa/gB,IAAK4F,EAAEub,YAAY,IAAInhB,IAAKqC,IAAKqkC,GAC1E,CAAExmC,GAAI2F,EAAE3F,GAAIlC,QAAOG,MAAO0H,EAAEkb,YAAa/gB,IAAK6F,EAAEsb,YAAY,IAAInhB,IAAKqC,IAAKqkC,IAC1EQ,GAE8BG,IAC1C,MAAMK,EVl2BkBO,EAC5B3mB,EACAqK,EACA6P,EACAmE,KAEA,MAAM52B,EAAuB,GACvBm/B,EAAQA,CAAC9mB,EAA2BwN,KACtCxN,EAAM5gB,QAASogB,IACX,MAAMsK,EAAWS,EAAW/K,GACtBunB,EA3BSC,EACvBxnB,EACA+K,KAAmB,CAEnBrrB,KAAM,QACNJ,GAAI0gB,EAAK1gB,GACTmgB,MAAOO,EAAKP,MACZQ,OAAQD,EAAKC,OACbC,cAAeF,EAAKE,cACpBC,YAAaH,EAAKG,YAClBC,cAAeJ,EAAKI,cACpBvkB,SAAUmkB,EAAKK,YAAY1iB,OAAS,EAAIqiB,EAAKK,YAAY3b,IAAKuO,GAAMA,EAAE3T,IAAM0gB,EAAKM,OAAO5b,IAAK+iC,GAAMA,EAAEnoC,IACrGsnC,QAAS5mB,EAAKO,YAAY7b,IAAKpE,GAAMA,EAAEhB,IACvCyrB,eAc0Byc,CAAYxnB,EAAMsK,GACpCsQ,EAAUn2B,IAAIub,EAAK1gB,GAAIioC,GACvBxI,EAAWt6B,IAAIub,EAAK1gB,GAAI0gB,GACpBgO,GACA7lB,EAAII,KAAK,CAAEjJ,GAAI0gB,EAAK1gB,GAAII,KAAM,QAASN,IAAK,KAAM4gB,KAAMunB,EAAW9nB,MAAOO,EAAKP,MAAOqf,MAAO9e,IACjG,MAAM0nB,EAAe1Z,GAAW1D,EAC5BtK,EAAKK,YAAY1iB,OAAS,EAC1B2pC,EAAMtnB,EAAKK,YAAaqnB,GAExB1nB,EAAKM,OAAO1gB,QAAS+nC,IACjB,MAAMC,EAA4B,CAAEloC,KAAM,OAAQJ,GAAIqoC,EAAKroC,GAAImgB,MAAOO,EAAKP,MAAQ,EAAGQ,OAAQD,EAAK1gB,IACnGs7B,EAAUn2B,IAAIkjC,EAAKroC,GAAIsoC,GACnBF,GACAv/B,EAAII,KAAK,CAAEjJ,GAAIqoC,EAAKroC,GAAII,KAAM,OAAQN,IAAKuoC,EAAKvoC,IAAK4gB,KAAM4nB,EAAUnoB,MAAOO,EAAKP,MAAQ,SAM7G,OADA6nB,EAAM5mB,GAAO,GACNvY,GUq0BiBk/B,CAAiBN,EAAMJ,GAAiB/L,EAAWmE,GACvE,MAAO,CAAE+H,cAAahM,aAAcra,GAAkBsmB,GAAOnM,YAAWmE,aAAYgI,SACrF,CAAC7D,GAAgBwC,GAAiBe,GAAarnB,GAAgBC,GAAgB2R,GAAW2V,MAEvFG,YAAEA,GAAWhM,aAAEA,GAAYF,UAAEA,GAASmE,WAAEA,IAAe8H,GAIvDgB,GAAmBf,GAAYnpC,OAC/BmqC,GAAW5a,KAAe4U,GAC1BtV,GAAYU,GAAanvB,KAAKD,IAAI,EAAGC,KAAKgqC,KAAKF,GAAmB9pC,KAAKD,IAAIwuB,GAAgBD,SAAU,KAAO,EAC5GD,GAAOc,GAAatvB,EAAM0uB,GAAgBF,KAAM,EAAGI,GAAY,GAAK,EAE1Ej0B,EAAMgY,UAAU,KACR2c,IAAcZ,GAAgBF,OAASA,IACvCwR,GAAmB,IAAKtR,GAAiBF,WAE9C,CAACc,GAAYZ,GAAiBF,GAAMwR,KAEvC,MAAM5C,GAAYziC,EAAMk1B,QACpB,IACIqa,GACMhB,GAAYp9B,MAAM0iB,GAAOE,GAAgBD,UAAWD,GAAO,GAAKE,GAAgBD,UAChFya,GACV,CAACA,GAAagB,GAAU1b,GAAME,GAAgBD,WAK5C2b,GAAmBzvC,EAAMk1B,QAAQ,KACnC,IAAKiZ,IAA6C,WAAxB5N,GAAkC,OAAO,KACnE,MAAMmP,EAAgBnN,GAAap2B,IAAKwR,GAAUA,EAAM9W,KACxD,OAAOwhB,GAAcqnB,EAAepnB,GAAkBxB,GAAgByS,GAAsBmI,GAAO1oB,QAAQ9P,MAC5G,CAACilC,GAAmB5N,GAAqBgC,GAAcja,GAAkBxB,GAAgByS,KAEtFoW,GAAuB3vC,EAAMk1B,QAC/B,IAAM,IAAIza,IACV,CAACgoB,GAAWna,GAAkBiR,KAE5BqW,GAAsBrJ,IACxB,IAAK4H,IAA6C,WAAxB5N,GAAkC,OAC5D,IAAIsP,EAASF,GAAqB/0B,IAAI2rB,EAAMx/B,IAW5C,OAVK8oC,IACDA,EAASxnB,GACLke,EAAMve,YAAY7b,IAAKpE,GAAMA,EAAElB,KAC/ByhB,GACAxB,GACAyS,GACAmI,GAAO1oB,QAAQ9P,KAEnBymC,GAAqBzjC,IAAIq6B,EAAMx/B,GAAI8oC,IAEhCA,GAKLC,GAAU9vC,EAAMk1B,QAAQ,KAC1B,MAAM6a,EAAuB,GACvBC,EAA0B,GAC1BC,EAAoB,GAC1B,IAAI5yB,EAAQ,EACR6yB,EAAU/S,IAAcC,IAAyBmM,GAqBrD,OApBA9G,GAAUp7B,QAASq7B,IACf,IAAIzmB,EAAI8gB,GACR,GAAIG,GAA4B,SAAZwF,EAAGv7B,MAAmBu7B,EAAG77B,IAAK,CAC9C,MAAM2hB,EAAS0U,EAAa,CAAEn2B,GAAI27B,EAAG37B,GAAIsuB,MAAOqN,EAAG77B,IAAK0jC,mBACzC,SAAX/hB,EAAmB0nB,GAAU,EACN,iBAAX1nB,GAAuBA,EAAS,IAAGvM,EAAIuM,EAC3D,CACA,IAAIzgB,EAAI,EACR,GAAgB,SAAZ26B,EAAGv7B,MAAmBu4B,IAAyBqG,GAAqBjhC,IAAI49B,EAAG37B,KAAO27B,EAAG77B,IAAK,CAC1F,MAAMspC,EAAKxQ,GACLA,GAAqB,CAAE54B,GAAI27B,EAAG37B,GAAIF,IAAK67B,EAAG77B,MAl9B5B,IAo9BT,SAAPspC,EAAeD,GAAU,EACxBnoC,EAAIooC,CACb,CACAJ,EAAW//B,KAAKiM,GAChB+zB,EAAchgC,KAAKjI,GACnBkoC,EAAQjgC,KAAKqN,GACbA,GAASpB,EAAIlU,IAEV,CAAEgoC,aAAYC,gBAAeC,UAAS5yB,QAAO6yB,YACrD,CACCzN,GACA1F,GACAG,EACAqN,GACA7K,GACAC,GACAoG,GACA5I,GACAC,GACAmM,KAGE6G,IAAWN,GAAQI,QAczBlwC,EAAMgY,UAAU,KACZ,IAAKqxB,GAAY,OAGjB,MAAMpjB,EAAQ/f,OAAOqR,WAAW,KACvB6pB,GAAQpoB,SACb2I,GAAiB,CACbO,YAAakf,GAAQpoB,QACrBkB,QAASmvB,GACTvnB,OAAQA,IAAMwnB,GAAc,SAEjC,IACH,MAAO,IAAMpjC,OAAOigB,aAAaF,IAClC,CAACojB,KAEJ,MAAMgH,GAAerwC,EAAMk1B,QAAQ,KAC/B,MAAMzgB,EAAQguB,GAAUr9B,OACxB,IAAKgrC,IAAqB,IAAV37B,EAAa,MAAO,CAAE67B,MAAO,EAAGC,IAAK97B,GACrD,MAAM+7B,EA3gCQ,EA2gCmBzT,GAC3B0T,EAAUjrC,KAAKD,IAAI,EAAGoiC,GAAY8C,GAAe+F,GACjDE,EAAa/I,GAAYniC,KAAKD,IAAI0kC,GAAgBlN,IAAayT,GAC/DP,QAAEA,GAAYH,GACpB,IAAIa,EAAK,EACLC,EAAKn8B,EAAQ,EACjB,KAAOk8B,EAAKC,GAAI,CACZ,MAAMC,EAAOF,EAAKC,GAAO,EACrBX,EAAQY,GAAOf,GAAQC,WAAWc,GAAOf,GAAQE,cAAca,GAAOJ,EAASE,EAAKE,EAAM,EACzFD,EAAKC,CACd,CACA,MAAMP,EAAQK,EACd,IAAIJ,EAAMD,EACV,KAAOC,EAAM97B,GAASw7B,EAAQM,GAAOG,GAAYH,GAAO,EACxD,MAAO,CAAED,QAAOC,QACjB,CAACH,GAAS3N,GAAUr9B,OAAQuiC,GAAWsC,GAAgBlN,GAAW0N,GAAcqF,KAE7EgB,GAAe9wC,EAAM4Z,YAAY,KAC9B8nB,GAAO1oB,QAAQo3B,UAChBzG,GAAU3wB,UACd2wB,GAAU3wB,QAAU9S,OAAO6qC,sBAAsB,KAC7CpH,GAAU3wB,QAAU,EAChBqoB,GAAYroB,SAAS0wB,GAAarI,GAAYroB,QAAQ2uB,gBAE/D,IAEH3nC,EAAMgY,UACF,IAAM,KACE2xB,GAAU3wB,SAAS9S,OAAO8qC,qBAAqBrH,GAAU3wB,UAEjE,IAKJ,MAAMmsB,GAAoBnlC,EAAM4Z,YAC5B,CAAC7S,EAAkBF,MACVA,KACAq4B,IACEA,GAAgB,CAAEn4B,KAAIF,MAAKsT,QAAS8oB,GAAoB/5B,IAAKw4B,GAAO1oB,QAAQ9P,OAEvF,CAACg2B,GAAiB+D,KAGhBgO,GAAsBjxC,EAAMk1B,QAAQ,KACR2J,GACvB4D,GACI98B,OAAQ+8B,GAAmB,SAAZA,EAAGv7B,MAAmBu7B,EAAG77B,KACxCsF,IAAKu2B,IAAE,CAAQ37B,GAAI27B,EAAG37B,GAAIF,IAAK67B,EAAG77B,OACvC07B,IACQ58B,OAAQgY,GAAUwnB,GAAkBxnB,EAAM5W,GAAI4W,EAAM9W,MAAMsF,IAAKwR,GAAUA,EAAM5W,IAC9F,CAAC83B,GAA8B4D,GAAWF,GAAc4C,KAErD+L,GAAyBlxC,EAAMk1B,QACjC,IAAM+b,GAAoBpgC,OAAe,CAACC,EAAK/J,IAAO+J,GAAO2zB,GAAY3/B,IAAIiC,GAAM,EAAI,GAAI,GAC3F,CAACkqC,GAAqBxM,KAEpB0M,GAAwBF,GAAoB7rC,OAAS,GAAK8rC,KAA2BD,GAAoB7rC,OACzGgsC,GAAyBF,GAAyB,IAAMC,GAExDE,GAAkBrxC,EAAM4Z,YACzB03B,IACGzM,GAAgB1X,IACZ,MAAMtT,EAAOy3B,EAAQnkB,GACrB,MhBlkCoBokB,EAAC9kC,EAA6BC,KAC9D,GAAID,EAAErF,IAAIkK,OAAS5E,EAAEtF,IAAIkK,KAAM,OAAO,EACtC,IAAIkgC,GAAQ,EAIZ,OAHA/kC,EAAErF,IAAIC,QAASN,IACN2F,EAAEtF,IAAItC,IAAIiC,KAAKyqC,GAAQ,KAEzBA,GgB4jCYD,CAAqB,CAAmBnqC,IAAK+lB,GAAQ,CAAmB/lB,IAAKyS,IAAUsT,EAAOtT,KAG7G,CAACgrB,KAGCI,GAAajlC,EAAM4Z,YACrB,CAACxS,EAAqB29B,GAAa,EAAMC,GAAiB,KACtDqM,GAAiBlkB,IACb,MAAMtT,EAAOmrB,EAAiB,IAAI5gC,IAAsB,IAAIA,IAAI+oB,GAMhE,GALA/lB,EAAIC,QAASN,IACLg+B,EACII,GAAkBp+B,EAAIg7B,GAASnnB,IAAI7T,KAAM8S,EAAKvS,IAAIP,GACnD8S,EAAK43B,OAAO1qC,KAEnBg4B,IAA+BllB,EAAKvI,KAAO,EAAG,CAC9C,MAAMogC,EAAStqC,EAAIA,EAAIhC,OAAS,GAChC,OAAO,IAAIhB,IAAkB2gC,GAAclrB,EAAK/U,IAAI4sC,GAAU,CAACA,GAAU,GAC7E,CACA,OAAO73B,KAGf,CAACw3B,GAAiBlM,GAAmBpD,GAAUhD,KAGnD/+B,EAAMgY,UAAU,KACZ,GAAImnB,IAAoD,IAArBsF,GAAYnzB,KAAY,OAC3D,IAAI26B,GAAU,EACd,MAAMpyB,EAAO,IAAIzV,IACjBqgC,GAAYp9B,QAASN,IACbg7B,GAASj9B,IAAIiC,GAAK8S,EAAKvS,IAAIP,GAC1BklC,GAAU,IAEfA,GAASpH,GAAehrB,IAC7B,CAACkoB,GAAU5C,GAA6BsF,GAAaI,KAExD,MAAM8M,GAAsBA,KACG1M,GAAWgM,IAAlCE,KAsCFvX,GAAaA,CAAC/0B,EAAeo/B,EAAkC2N,GAAgB,KACjF,MAAMjpC,EAAMw6B,GAAUt+B,GACtB,IAAK8D,IAAwB,IAAjBA,EAAImF,UAAsBkrB,GAAsB,OAC5D,MAAMhgB,EAAUyf,GAAUjvB,KAAMiC,GAASA,EAAK5G,QAAUA,GACxD,IAAIgV,EAQAwb,EAPJ,QAAkBjsB,IAAd66B,EAAyB,CACzB,MAAM8D,EAAQp/B,EAAIg1B,cAAgBA,GAC5Bze,EAAQ6oB,EAAMj8B,QAAQkN,GAAS5H,MAAQ,MAC7CyI,EAAOkuB,GAAO7oB,EAAQ,GAAK6oB,EAAM3iC,OACrC,MACIyU,EAAOoqB,EAGP2N,IAAkBhU,IAClBvI,EAAQoD,GAAU9yB,OAAQ8F,GAASA,EAAK5G,QAAUA,GAC9CgV,IACAwb,EAAQrc,EACFyf,GAAUtsB,IAAKV,GAAUA,EAAK5G,QAAUA,EAAQ,CAAEA,QAAOuM,KAAMyI,GAASpO,GACxE4pB,EAAMzW,OAAO,CAAC,CAAE/Z,QAAOuM,KAAMyI,OAEvCwb,EAAQxb,EAAO,CAAC,CAAEhV,QAAOuM,KAAMyI,IAAU,GAE7CmqB,GAAa3O,IAKXwc,GAAgBt3B,IACd2jB,IAAuBz3B,EAAkBy3B,GAAuB3jB,IAGlEu3B,GAAiB3wB,IACfgd,IAAuB13B,EAAkB03B,GAAuBhd,IA0BlEwiB,GAAkBA,CAACzpB,EAA8E,MACnG,MAAM4B,EAAiB5B,EAAQ4B,iBAAkB,EAC3Ci2B,EAAU9G,GAAO9wB,QAAQxU,OAC1BqsC,KAAQptC,EAAgBotC,EAAGrpC,IAAI9D,QAAYqV,EAAQC,UAAqD,IAA1CD,EAAQC,QAAQrO,QAAQkmC,EAAGrpC,IAAI9D,SAElG,GAAuB,IAAnBktC,EAAQ3sC,OAAc,OAC1B,MAAMgjB,EAAO+Y,GAAQnoB,QACfi5B,EAAW7pB,GAA0B,oBAAXliB,OAAyBA,OAAOgsC,iBAAiB9pB,GAAQ,KACnF+pB,EAAaF,GAAUE,YAAc,aACrCC,EAAW,YAAYD,IACvBE,EAAa,YAAYF,IACzBG,EAAS/P,GAAapxB,MAAM,EAAG,KAC/Bo8B,EAAc7L,GAAO1oB,QAAQ9P,IAC7B2Q,EAAO,IAAK2F,IAClBuyB,EAAQ1qC,QAAQ,EAAGsB,UACf,IAAIpD,EAAMuW,EAAiBxF,GAAY3N,EAAIgF,YAAchF,EAAI9D,MAAOwtC,GAAc,GAAK,EACvFC,EAAOjrC,QAASsW,IACZ,MAAM3Y,EAAQiE,EAAa0U,EAAM9W,IAAK8B,EAAK4kC,GACrC/rC,EAAOoI,EAAuBF,EAAkB1E,EAAO2Y,EAAM9W,IAAK8B,EAAK4kC,EAAa5vB,EAAM5W,KAC1FwZ,EAAIjK,GAAY9U,EAAM4wC,GAAY,GACpC7xB,EAAIhb,IAAKA,EAAMgb,KAEvB1G,EAAKlR,EAAI9D,OAASQ,EAAMG,KAAKgqC,KAAKjqC,GAAMoD,EAAI3G,UAAY2C,EAA0BgE,EAAI8F,UAAYi9B,OAEtGlD,GAAgB3uB,GAChBi4B,GAAcj4B,IA4DZ6V,GAAkB1vB,EAAM4Z,YAAY,KACtCovB,GAAoB7b,GAAUA,EAAKnI,KAAO,CAAEA,MAAM,EAAO6G,SAAU,MAASsB,IAC7E,IAIGolB,GAAoB3wB,KACjBA,EAAO4wB,OAAOnkC,WACS,SAAxBuT,EAAO6wB,QAAQtrC,QACZw5B,IAAiBA,GAAe/e,KAGrC8kB,GAAoBA,CAAC3/B,EAAkBlC,KACzC,MAAMgC,EAAMk7B,GAASnnB,IAAI7T,GACnB4B,EAAMw6B,GAAUt+B,GACtB,IAAKgC,IAAQ8B,EAAK,OAClB,MAAMiZ,EAASulB,GAAgBpgC,EAAIlC,EAAOgC,EAAKw7B,GAAUznB,IAAI7T,IAAO,CAAEI,KAAM,OAAQJ,KAAImgB,MAAO,EAAGQ,OAAQ,OACrG6qB,GAAiB3wB,KACtBinB,GAAe,CAAE9hC,KAAIlC,UACrBoiC,GAAarlB,EAAO5c,OACpBsiC,GAAe,CAAEvgC,KAAIlC,YAiBnB8hC,GAAmBA,CACrB5/B,EACAlC,EACA+hC,GAAsB,EACtB8L,EAAmF,SAEnF,IAAK3L,IAAeA,GAAYhgC,KAAOA,GAAMggC,GAAYliC,QAAUA,EAAO,OAC1E,MAAMgC,EAAMk7B,GAASnnB,IAAI7T,GACnB4B,EAAMw6B,GAAUt+B,GAEtB,GADAgkC,GAAe,MACVhiC,GAAQ8B,EAAb,CACA,IAAKi+B,EAAqB,CACtB,MAAM2G,EAAc7L,GAAO1oB,QAAQ9P,IAC7BlB,EAASW,EAAIgqC,YACbhqC,EAAIgqC,YAAY7J,GAAWjiC,EAAK8B,EAAK4kC,GhBztCzBqF,EAACzpC,EAAUR,KACrC,OAAQA,EAAIxB,MACR,IAAK,SAAU,CACX,GAAY,KAARgC,GAAcpE,EAAMoE,GAAM,OAAO,KACrC,MAAMoD,EAAI9E,OAAO0B,GACjB,OAAO1B,OAAOC,MAAM6E,GAAKpD,EAAMoD,CACnC,CACA,IAAK,UACD,OAAO3G,QAAQuD,GACnB,IAAK,OACL,IAAK,WACD,MAAY,KAARA,GAAcpE,EAAMoE,GAAa,KAC3B5B,EAAO4B,IACLA,EAEhB,QACI,OAAOA,IgB0sCDypC,CAAe9J,GAAWngC,GAC1BkqC,EAAe5pC,EAAapC,EAAK8B,EAAK4kC,GAC5C,IAAKr+B,OAAO6K,GAAG/R,EAAQ6qC,GAAe,CA/BvBC,EAAC/rC,EAAkBgsC,EAAWC,KAC7CxS,GACA5a,QAAQC,UACHotB,KAAK,IAAMzS,GAAiBuS,EAAQC,EAAQ,CAAEE,MAAOnsC,KACrDksC,KAAMzqB,GAAWwa,GAAej8B,EAAKyhB,GAAUuqB,IAC/CI,MAAOnxB,IACAye,GAAyBA,GAAwBze,GAChDC,QAAQD,MAAM,mCAAoCA,KAG/DghB,GAAej8B,EAAIgsC,IAyBfD,CAAe/rC,EAHA4B,EAAIyqC,YACbzqC,EAAIyqC,YAAYprC,EAAQnB,EAAK8B,EAAK4kC,GACjC,IAAK1mC,EAAKhC,CAACA,GAAQmD,GACCnB,EAC/B,CACJ,CACA65B,KAAiB,CAAE35B,KAAIlC,QAAOgC,MAAK6rC,UAAU/Q,MAC7C0F,GAAgBruB,SAAU,EAC1BsuB,GAAe,CAAEvgC,KAAIlC,SAhBH,GAqBhB+gC,GAAqB7+B,IACvB8+B,GAAyB1Y,IACrB,MAAMtT,EAAO,IAAIzV,IAAI+oB,GAGrB,OAFItT,EAAK/U,IAAIiC,GAAK8S,EAAK43B,OAAO1qC,GACzB8S,EAAKvS,IAAIP,GACP8S,KAITusB,GAA0BA,CAACr/B,EAAkByrB,KAC/CoW,GAAmBzb,IACf,MAAMtT,EAAO,IAAIY,IAAI0S,GAErB,OADAtT,EAAK3N,IAAInF,EAAIyrB,GACN3Y,KAIT+N,GAAcf,GAAehhB,KAAK,KAClCwtC,GAAsBrzC,EAAM+Y,OAAO6O,IACzC5nB,EAAMgY,UAAU,KACRq7B,GAAoBr6B,UAAY4O,KACpCyrB,GAAoBr6B,QAAU4O,GAC9BghB,GAAkB,IAAInuB,OACvB,CAACmN,KAIJ,MAAMuf,GAAkBA,CAACpgC,EAAkBlC,EAAegC,EAAQ4gB,KAC9D,MAAM9e,EAAMw6B,GAAUt+B,GAChB0oC,EAAc7L,GAAO1oB,QAAQ9P,IAC7BlE,EAAQiE,EAAapC,EAAK8B,EAAK4kC,GAC/B+F,EAAiB5pC,EAAkB1E,EAAO6B,EAAK8B,EAAK4kC,EAAaxmC,GACjEwsC,EAAW3tC,QAAQmjC,IAAeA,GAAYhiC,KAAOA,GAAMgiC,GAAYlkC,QAAUA,GAEvF,MAAO,CACHkC,KACAlC,QACAG,QACAsuC,iBACAzsC,MACA4rC,QAAShrB,EACT+qB,OAAQ7pC,EACRO,IAAKqkC,EACLgG,WACAplB,SAAUolB,EAAW,GAAI,EACzBC,SAZazM,IAAeA,GAAYhgC,KAAOA,GAAMggC,GAAYliC,QAAUA,EAAQ,OAAS,OAa5F4uC,WAAY7tC,QAAQ+C,EAAI0F,WAA2B,SAAdoZ,EAAKtgB,OAI5CusC,GAAiBA,CAAC3sC,EAAkBF,KAAM,CAC5CE,KACAF,MACAsT,QAAS8oB,GACT/5B,IAAKw4B,GAAO1oB,QAAQ9P,MAKxBlJ,EAAMgY,UAAU,KACZ,IAAKqvB,GAAgBruB,UAAY+vB,KAAgB5H,GAAQnoB,QAAS,OAClEquB,GAAgBruB,SAAU,EAC1B,MAAM/I,EAAW,qBAAqBnH,OAAOigC,GAAYhiC,IAAIuI,QAAQ,KAAM,6BAA6By5B,GAAYlkC,MAAMyK,QAAQ,KAAM,WAClIwT,EAAKqe,GAAQnoB,QAAQ+U,cAA2B9d,GAClD6S,GAAMtM,SAASqY,gBAAkB/L,IAAOA,EAAG6K,SAASnX,SAASqY,gBAAgB/L,EAAG0D,MAAM,CAAEmtB,eAAe,KAC5G,CAAC5K,GAAasH,GAAaC,MAAOD,GAAaE,MAElD,MAAMhJ,GAAmB3lB,IACrB,MAAM6lB,EAAWpG,GAAYroB,QAC7B,IAAKyuB,EAAU,OAAO,EACtB,QAAwBr+B,IAApBwY,EAAOlC,UAA0B0wB,GAAS,CAC1C,MAAMlxB,EAAQ7Z,EAAMuc,EAAOlC,SAAU,EAAGla,KAAKD,IAAIk9B,GAAUr9B,OAAS,EAAG,IACjEinB,EAAMyjB,GAAQG,QAAQ/wB,IAAU,EAChCgO,EAASb,GAAOyjB,GAAQC,WAAW7wB,IAAU6d,IAC7C6W,EAAanM,EAASE,UACtBkM,EAAgBpM,EAASE,UAAYF,EAAS4C,aAAeI,GAC/Dpe,EAAMunB,EAAYnM,EAASE,UAAYtb,EAClCa,EAAS2mB,IAAepM,EAASE,UAAYza,GAAUua,EAAS4C,aAAeI,IAC5F,MAAO,QAAwBrhC,IAApBwY,EAAOlC,SAAwB,CACtC,MAAMoD,EAAK2kB,EAAS1Z,cAAc,wBAAwBnM,EAAOlC,cACjEoD,GAAIgxB,iBAAiB,CAAE7kC,MAAO,WAClC,CACA,QAAwB7F,IAApBwY,EAAOmyB,SAAwB,CAC/B,MAAM/B,EAAK/G,GAAO9wB,QAAQ9U,EAAMuc,EAAOmyB,SAAU,EAAG9I,GAAO9wB,QAAQ/U,OAAS,IAC5E,GAAI4sC,IAAOA,EAAGtZ,OAAQ,CAClB,MAAMsb,EAAkB/I,GAAO9wB,QAC1BxU,OAAQ+U,GAAmB,SAAbA,EAAEge,QAChB7nB,OAAO,CAACC,EAAK4J,IAAM5J,EAAM4J,EAAE9a,MAAO,GACjCq0C,EAAmBhJ,GAAO9wB,QAC3BxU,OAAQ+U,GAAmB,UAAbA,EAAEge,QAChB7nB,OAAO,CAACC,EAAK4J,IAAM5J,EAAM4J,EAAE9a,MAAO,GACjCs0C,EAAczM,EAASC,WAAasM,EACpCG,EAAe1M,EAASC,WAAaD,EAAS2C,YAAc6J,EAC9DjC,EAAG1F,EAAI4H,EAAazM,EAASC,WAAasK,EAAG1F,EAAI0H,EAC5ChC,EAAG1F,EAAI0F,EAAGpyC,MAAQu0C,IACvB1M,EAASC,WAAasK,EAAG1F,EAAI0F,EAAGpyC,MAAQ6nC,EAAS2C,YAAc6J,EACvE,CACJ,CACA,OAAO,GAGLG,GAAYA,CACdC,EACAC,EACAC,KAEA,GAAyB,IAArB9R,GAAUr9B,QAA0C,IAA1B6lC,GAAO9wB,QAAQ/U,OAAc,OAC3D,IAAIsa,EAAWqpB,GAActG,GAAUG,UAAWF,GAAOA,EAAG37B,KAAOgiC,GAAYhiC,KAAM,EACjFgtC,EAAWhL,GAAckC,GAAO9wB,QAAQyoB,UAAWoP,GAAOA,EAAGrpC,IAAI9D,QAAUkkC,GAAYlkC,QAAS,OAChG6a,IAAiBA,EAAW,QAC5Bq0B,IAAiBA,EAAW,GACDr0B,EAAT,UAAlB60B,GAAU1tC,IAA4B,EACf,SAAlB0tC,GAAU1tC,IAA2B47B,GAAUr9B,OAAS,EACjDC,EAAMqa,EAAW20B,EAAU,EAAG5R,GAAUr9B,OAAS,GAClC2uC,EAAT,UAAlBQ,GAAU5rC,IAA4B,EACf,SAAlB4rC,GAAU5rC,IAA2BsiC,GAAO9wB,QAAQ/U,OAAS,EACtDC,EAAM0uC,EAAWO,EAAU,EAAGrJ,GAAO9wB,QAAQ/U,OAAS,GACtE,MAAMsd,EAAS,CAAE3b,GAAI07B,GAAU/iB,GAAU3Y,GAAIlC,MAAOomC,GAAO9wB,QAAQ45B,GAAUprC,IAAI9D,OACjFwiC,GAAgBruB,SAAU,EAC1BsuB,GAAe5kB,GACf6kB,GAAgB,CAAE7nB,WAAUq0B,cA0F1BS,GAAc7rC,IAAwB61B,KAAyB71B,EAAI+F,iBAAmB9J,EAAgB+D,EAAI9D,OAoC1G4vC,GAAYz0C,EAAM+Y,OAOd,MAyCJ+W,GAAcmd,GAAc7nC,OAC5B4uB,GAAW2W,GAAiB2E,GAAmBnC,GAAgB/nC,OAE/DiqB,GAAQrvB,EAAMk1B,QAChB,KAAA,CACIuD,aACA3B,eACA/C,gBAAiB,CAAEF,QAAMC,SAAUC,GAAgBD,UACnDG,aACAD,YACA0gB,cAAexS,GAAW98B,OAC1BkwB,yBACAgT,cAAerF,GAAmB92B,IAAKuO,GAAMA,EAAE7V,OAC/C2a,gBACAif,iBACAvO,WACAqa,iBACAhW,kBAAmB,CAAEptB,KAAM,UAAWC,IAAKq9B,IAC3C5L,oBACAvQ,oBACAyd,wBACAvW,gBAAiB,CACbxK,KAAMwK,GAAgBxK,KACtByK,iBAAkBD,GAAgBC,iBAClCuH,YAAaxH,GAAgBwH,aAEjClH,eACA+B,uBAEJ,CACI4G,GACA3B,GACAjD,GACAE,GAAgBD,SAChBG,GACAD,GACAkO,GAAW98B,OACXkwB,GACA2N,GACAzjB,GACAif,GACAvO,GACAqa,GACA9F,GACA5L,GACAvQ,GACAyd,GACAvW,GAAgBxK,KAChBwK,GAAgBC,iBAChBD,GAAgBwH,YAChBlH,GACA+B,KAIR6P,GAAO1oB,QAAU,CACb9P,IAAK04B,GACLvS,SACA0S,YACAG,cACAG,aACAmE,cACAjE,gBACAE,aACA37B,WACAk8B,kBACAC,sBACAC,sBACAC,aACA7N,yBACAI,4BACA8N,eAlhBmBA,CAAC3+B,EAAejF,KACnC,MAAM+I,EAAMw6B,GAAUt+B,GACtB,IAAK8D,EAAK,OACV,MAAMgsC,EAAUtvC,EAAMzF,EAAO+I,EAAI3G,UAAY2C,EAA0BgE,EAAI8F,UAAYi9B,KACvFlD,GAAiBrb,IACb,MAAMtT,EAAO,IAAKsT,EAAMtoB,CAACA,GAAQ8vC,GAEjC,OADA7C,GAAcj4B,GACPA,IAEXykB,KAAsB,CAAEkU,OAAQ7pC,EAAK/I,MAAO+0C,GAAWhT,OA0gBvD8B,eA9hBmBA,CAAC5+B,EAAe6+B,EAAqBhW,EAAgC,QACxF,MAAMnT,EAAS0oB,GAAmB92B,IAAKuO,GAAMA,EAAE7V,OACzC+vC,EAAWr6B,EAAOzO,QAAQjH,GAChC,IAAiB,IAAb+vC,EAAiB,OACrB,MAAM/6B,EhBpvCUg7B,EAAIC,EAAWhgC,EAAcC,KACjD,MAAM8E,EAAOi7B,EAAK3jC,SACX1F,GAAQoO,EAAKssB,OAAOrxB,EAAM,GAEjC,OADA+E,EAAKssB,OAAOpxB,EAAI,EAAGtJ,GACZoO,GgBgvCUg7B,CAASt6B,EAAQq6B,EAAUvvC,EAAMq+B,EAAa,EAAGnpB,EAAOnV,OAAS,IAC9EmjC,GAAiB1uB,GACjBg4B,GAAah4B,GACb,MAAMlR,EAAMme,GAAelM,IAAI/V,GAC3B8D,GAAK01B,KAAsB,CAAEpI,OAAQttB,EAAK+6B,cAAakR,YAAYlnB,EAAOiU,OAuhB9EniB,gBACAmkB,mBACA5J,UA9ecA,CAACl1B,EAAe++B,KAC9B,GAAIxK,GAAsB,OAC1B,MAAM9M,GAAQmS,GAAcnS,MAAQ,IAAI3mB,OAAQgV,GAAMA,IAAM9V,GACtDooB,GAASwR,GAAcxR,OAAS,IAAItnB,OAAQgV,GAAMA,IAAM9V,GACjD,SAAT++B,EAAiBtX,EAAKtc,KAAKnL,GAC1BooB,EAAM8nB,QAAQlwC,GACnBi/B,GAAiB,CAAExX,OAAMW,WAyezB+M,YAteiBn1B,IACjBi/B,GAAiB,CACbxX,MAAOmS,GAAcnS,MAAQ,IAAI3mB,OAAQgV,GAAMA,IAAM9V,GACrDooB,OAAQwR,GAAcxR,OAAS,IAAItnB,OAAQgV,GAAMA,IAAM9V,MAoe3D8zB,eAheoB9zB,IAChBu0B,MAC8C,KAA7CqF,GAAcnS,MAAQ,IAAIxgB,QAAQjH,GAAsB,QACV,KAA9C45B,GAAcxR,OAAS,IAAInhB,QAAQjH,IAAsB,SA8d9D45B,iBACAqF,oBACArL,aACAuL,gBACApK,cACA9C,eACAsB,kBACAgM,kBA/duBnd,IACvB,IAAI+tB,EAAYle,GAAY7P,MAAM9V,QAClC8V,EAAM5f,QAASoE,IACX,MAAMwpC,OACU7rC,IAAZqC,EAAK1E,GAAmB,IAAK0E,EAAM1E,GAAI,GAAGS,KAAKuZ,SAASvb,KAAK0vC,SAASC,SAAS,IAAIhkC,MAAM,EAAG,MAAS1F,EACnGyT,EAAQ81B,EAAUpS,UAAWG,QAA6B35B,IAAhB25B,EAASh8B,IAAoBg8B,EAASh8B,KAAOkuC,EAAOluC,SAChGmY,EAAc81B,EAAUhlC,KAAKilC,GAC5BD,EAAU91B,GAAS+1B,IAExB3d,IAAmC0d,EAAU5vC,OAAS,IAAG4vC,EAAYA,EAAU7jC,WACnFinB,GAAe,IAAKtB,GAAa7P,MAAO+tB,KAsdxCrd,iBAndsBlsB,IACtB2sB,GAAe,IACRtB,GACH7P,MAAO6P,GAAY7P,MAAMthB,OAAQo9B,QACjB35B,IAAZqC,EAAK1E,GAAmBg8B,EAASh8B,KAAO0E,EAAK1E,GAAKg8B,IAAat3B,MAgdvEkkB,gBA3coBA,CAAC4U,EAA8B1Y,EAA+BmL,KAClFkS,GAAc,MACdF,GAAmB,CACfhkB,MAAM,EACNyK,iBAAkB8U,EAClBvN,cACAnL,SAAUA,GAAYyV,GAAWtoB,SAAWmoB,GAAQnoB,WAscxD0W,mBACA+U,eACAI,kBACAI,cACAE,qBACApR,gBAAiB,CAAEF,QAAMC,SAAUC,GAAgBD,UACnDuR,sBACAlV,cACAyV,qBACAG,wBACAF,2BACAhN,oBACAoN,uBACAG,2BACA9d,oBACA8R,uBACAsM,qBACAC,oBACAI,eACAE,gBACAE,mBACAG,kBACAC,mBACAhG,eACA6O,WACAzK,WAjxBeA,CAACzrB,EAAqC,MACrD,GAAImvB,GAAY,OAChB,MAAMvvB,EAAsC,CACxC4B,MAAyB,iBAAX0V,EAAsBA,OAAShoB,KAC1C8Q,GAEFknB,GAAQpoB,SAA6B,oBAAX9S,QAC/BojC,GAAcxvB,KA6wBd+mB,KAAQA,GAAO7nB,QAAU4oB,IAE7B5hC,EAAMgY,UAAU,KACZ8oB,KAAgBzR,GAAO,CAAEnmB,IAAK04B,MAC/B,CAACvS,GAAOyR,GAAec,KAI1B,MAAM/Q,GAAY7wB,EAAMk1B,QACpB,KAAA,CACI9D,SACAuD,cACAT,mBACAU,wBACAE,sBACAL,8BACAhB,uBACAF,yBACAI,0BACAyF,wBACAJ,wBACA4E,iCACAtG,mCACAgC,sBACAI,sBACAkF,qBACArF,wBACApH,2BAEJ,CACIf,EACAuD,GACAT,GACAU,GACAE,GACAL,GACAhB,GACAF,GACAI,GACAyF,GACAJ,GACA4E,GACAtG,GACAgC,GACAI,GACAkF,GACArF,GACApH,KAIFijB,GAAep1C,EAAMk1B,QACvB,KAAA,CACIhsB,IAAK04B,GACLvS,SACAC,cACAtD,YACA6E,aACA1W,QAAS8oB,GACTjO,eAAgBkO,KAEpB,CAACtB,GAAWvS,GAAOC,GAAYtD,EAAW6E,GAAWoS,GAAoBC,KA+GvEmS,GAAoBA,CAACrD,EAAkBsD,KACzC,MAAM3sC,IAAEA,GAAQqpC,EACVntC,EAAQ8D,EAAI9D,MAElB,GAAIA,IAAUb,EAAgB,CAC1B,GAAuB,UAAnBsxC,EAAUC,MAAoBD,EAAU/O,MAAO,CAC/C,MAAM8H,EAAUiH,EAAU/O,MAAMve,YAAY7b,IAAKpE,GAAMA,EAAEhB,IACnDutB,EAAgB+Z,EAAQx9B,OAAe,CAACC,EAAK/J,IAAO+J,GAAO2zB,GAAY3/B,IAAIiC,GAAM,EAAI,GAAI,GAC/F,OACI/G,EAAAC,cAACqrB,GAAQ,CACLnI,QAASkrB,EAAQjpC,OAAS,GAAKkvB,IAAkB+Z,EAAQjpC,OACzDge,cAAekR,EAAgB,GAAKA,EAAgB+Z,EAAQjpC,OAC5DyD,MAAOymB,GAAW/Z,2BAClB8Y,QAAUX,GAAUA,EAAMO,kBAC1B7U,SAAUA,IAAM6rB,GAAWoJ,EAAS/Z,IAAkB+Z,EAAQjpC,QAAQ,IAGlF,CACA,GAAuB,SAAnBkwC,EAAUC,KAAiB,OAAO,KACtC,MAAMC,EAAarQ,GAAkBmQ,EAAUvuC,GAAIuuC,EAAUzuC,KACvDsc,EAAUshB,GAAY3/B,IAAIwwC,EAAUvuC,IAC1C,OACI/G,gBAACsrB,GAAQ,CACLnI,QAASA,EACT6L,UAAWwmB,EACX3sC,MAAOsa,EAAUmM,GAAW9Z,6BAA+B8Z,GAAW/Z,2BACtE4Y,UAAU,EACVE,QAAUX,GAAUA,EAAMO,kBAC1B7U,SAAUA,KACNwwB,GAAiB5wB,QAAUs8B,EAAUvuC,GACrCk+B,GAAW,CAACqQ,EAAUvuC,KAAMoc,EAAS4b,MAIrD,CAEA,GAAIl6B,IAAUZ,EAA2B,CACrC,GAAuB,SAAnBqxC,EAAUC,OAAoBD,EAAUzuC,IAAK,OAAO,KACxD,MAAMkrB,EAAWgU,GAAqBjhC,IAAIwwC,EAAUvuC,IAC9C0uC,EAAU/V,KAAwBgU,GAAe4B,EAAUvuC,GAAIuuC,EAAUzuC,MAC/E,OAAI4uC,UAAyD,IAAZA,EAA0B,KAEvEz1C,gBAACgrB,GAAU,CACP1Z,KAAK,QACLiU,UAAW9f,EAAG,yBAA0BssB,GAAY,oCACpDlpB,MAAOkpB,EAAWzC,GAAWzZ,oBAAsByZ,GAAW1Z,kBAAiB,gBAChEmc,EACf5D,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACN2X,GAAkB0P,EAAUvuC,MAGhC/G,EAAAC,cAACwpB,GAAc,MAG3B,CAEA,GAAI5kB,IAAUd,EAAuB,CACjC,GAAuB,UAAnBuxC,EAAUC,MAAoBD,EAAU/O,MAAO,CAC/C,MAAMA,EAAQ+O,EAAU/O,MAClBxU,EAAWqc,GAAgB7H,GAC3BmP,EAAaxV,IAAwByV,oBAC3C,OACI31C,EAAAC,cAAA,MAAA,CAAKslB,UAAU,sBAAsBplB,MAAO,CAAEy1C,YAA+B,GAAlBN,EAAUpuB,QACjElnB,EAAAC,cAAC+qB,IACG1Z,KAAK,QACLiU,UAAW9f,EAAG,wBAAyBssB,GAAY,mCACnDlpB,MAAOkpB,EAAWzC,GAAWzZ,oBAAsByZ,GAAW1Z,kBAAiB,gBAChEmc,EACf5D,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACNmY,GAAwBG,EAAMx/B,IAAKgrB,KAGvC/xB,EAAAC,cAACypB,UAEL1pB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,uBAAuB7J,MAAO6qB,EAAM1e,eAC/C0e,EAAM1e,gBAET6tB,GAAa11C,EAAAC,cAAA,OAAA,CAAMslB,UAAU,4BAAyBghB,EAAMve,YAAY5iB,OAAe,KAGrG,CACA,OAAO,IACX,CAEA,GAAuB,UAAnBkwC,EAAUC,MAAuC,WAAnBD,EAAUC,KAAmB,CAC3D,MAAMM,EAAMP,EAAUQ,aAAajxC,GACnC,IAAKgxC,GAAO9wC,EAAM8wC,EAAI7wC,OAAQ,OAAO,KACrC,MAAM0jB,EAAK6Q,GAAqBsc,EAAIntB,IAC9B6kB,EAAc7L,GAAO1oB,QAAQ9P,IAC7B6sC,EAAaT,EAAU/O,OAAOve,YAAY,IAAInhB,KAAO66B,GAAO1oB,QAAQupB,aAAa,IAAI17B,KAAO,CAAA,EAC5FgD,EAAY6e,GAAI/e,eAChB+e,EAAG/e,eAAeksC,EAAI7wC,OACtB2D,EAAIgB,eACFhB,EAAIgB,eAAeksC,EAAI7wC,MAAO+wC,EAAWptC,EAAyB4kC,GAClEjkC,EAAmBusC,EAAI7wC,MAAO2D,GACtC,OACI3I,EAAAC,cAAAD,EAAA4qB,SAAA,KACI5qB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,8BAA8BmD,GAAI7f,OAASgtC,EAAIntB,IAC/D1oB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,sBAAsB3b,EAAuBC,IAGzE,CAEA,IAAKyrC,EAAUzuC,IAAK,OAAO,KAC3B,MAAM+a,EAASulB,GAAgBmO,EAAUvuC,GAAIlC,EAAOywC,EAAUzuC,IAAKyuC,EAAU7tB,MAE7E,GAAwB,SAApB7F,EAAO4xB,SAAqB,MAxNd5xB,KAClB,MAAMjZ,EAAMiZ,EAAO4wB,OACbngB,EAAUqgB,GACZ/L,GAAiB/kB,EAAO7a,GAAI6a,EAAO/c,OAAO,EAAO6tC,GAC/CsD,EAASA,IAAMrP,GAAiB/kB,EAAO7a,GAAI6a,EAAO/c,OAAO,EAAM,iBAgBrE,GAAI8D,EAAIstC,eACJ,OAAOttC,EAAIstC,eAAe,IACnBr0B,EACHknB,aACAoN,cAAejP,GACf5U,OAAQA,IAAMA,EAAO,gBACrB2jB,WAGR,MAAM50C,EAAS,CACX6qB,WAAW,EACXuC,UA1BgBd,IACE,UAAdA,EAAMrnB,KACNqnB,EAAMiB,iBACNjB,EAAMO,kBACNoE,EAAO,iBACc,WAAd3E,EAAMrnB,KACbqnB,EAAMiB,iBACNjB,EAAMO,kBACN+nB,KACqB,QAAdtoB,EAAMrnB,IACbgsB,EAAO,cAEP3E,EAAMO,mBAeV0E,OAAQA,IAAMN,EAAO,gBACrBhE,QAAUX,GAA4BA,EAAMO,mBAEhD,OAAQtlB,EAAIxB,MACR,IAAK,UACD,OACInH,EAAAC,cAACqrB,GAAQ,IACDlqB,EACJ+hB,QAASvd,QAAQkjC,IACjB1vB,SAAWsU,GAAUuZ,GAAavZ,EAAMhL,OAAOS,WAG3D,IAAK,eAAgB,CACjB,MAAMjJ,EAAUnR,EAAoBJ,EAAKiZ,EAAO/a,IAAK+a,EAAO7a,IAC5D,OACI/G,EAAAC,cAACkrB,GAAM,IACC/pB,EACJkQ,KAAK,QACLtM,MAAO8jC,SAAgD,GAAKhgC,OAAOggC,IACnE1vB,SAAWsU,IACP,MAAMnkB,EAAQ2Q,EAAQ1Q,KAAMymB,GAAMnnB,OAAOJ,EAAeC,EAAKsnB,MAAQvC,EAAMhL,OAAO1d,OAClFiiC,QAAuB79B,IAAVG,EAAsBb,EAAeC,EAAKY,GAASmkB,EAAMhL,OAAO1d,SAGjFhF,EAAAC,cAAA,SAAA,CAAQ+E,MAAM,KACbkV,EAAQ/N,IAAK1D,IACV,MAAMzD,EAAQ0D,EAAeC,EAAKF,GAClC,OACIzI,EAAAC,cAAA,SAAA,CAAQoG,IAAKyC,OAAO9D,GAAQA,MAAO8D,OAAO9D,IACrC4D,EAAeD,EAAKF,MAM7C,CACA,IAAK,SACD,OACIzI,gBAACkrB,GAAS,IACF9pB,EACJkQ,KAAK,QACLnK,KAAK,SACLnC,MAAO8jC,SAAgD,GAAKA,GAC5D1vB,SAAWsU,GAAUuZ,GAAavZ,EAAMhL,OAAO1d,SAG3D,IAAK,OACL,IAAK,WACD,OACIhF,EAAAC,cAACirB,GAAS,IACF9pB,EACJkQ,KAAK,QACLnK,KAAmB,SAAbwB,EAAIxB,KAAkB,OAAS,iBACrCnC,MACyB,iBAAd8jC,IAA0B,qBAAqB/5B,KAAK+5B,IACrDA,GACArN,GAAiBqN,GAAwB,aAAbngC,EAAIxB,MAE1CiS,SAAWsU,GAAUuZ,GAAavZ,EAAMhL,OAAO1d,SAG3D,QACI,OACIhF,EAAAC,cAACirB,GAAS,IACF9pB,EACJkQ,KAAK,QACLnK,KAAK,OACLnC,MAAO8jC,SAAgD,GAAKhgC,OAAOggC,IACnE1vB,SAAWsU,GAAUuZ,GAAavZ,EAAMhL,OAAO1d,WAoHxBmxC,CAAav0B,GAEpD,GAAIjZ,EAAIytC,WAAY,OAAOztC,EAAIytC,WAAWx0B,GAE1C,GAAiB,YAAbjZ,EAAIxB,KAAoB,CACxB,MAAMyzB,EAAUjyB,EAAI0tC,WAAa1tC,EAAI0tC,WAAW3C,GAAe4B,EAAUvuC,GAAIuuC,EAAUzuC,MAAQ,GAC/F,OAAO7G,gBAAC26B,GAAW,CAACC,QAASA,EAAS5O,UAAWA,EAAW6O,UAAWvL,GAAWrZ,iBACtF,CAEA,GAAiB,YAAbtN,EAAIxB,KACJ,OAAIpC,EAAM6c,EAAO5c,OAAe,KACzB4c,EAAO5c,MACVhF,EAAAC,cAACupB,GAAS,CAAA,aAAa8F,GAAW7Z,uBAElCzV,EAAAC,cAACkpB,GAAS,CAAA,aAAamG,GAAW5Z,wBAI1C,MAAM7L,EAAY+X,EAAO0xB,eACzB,GAAIzpC,QAA+C,OAAO,KAC1D,GAAI7J,EAAMixB,eAAepnB,GAAY,OAAOA,EAC5C,MAAMrI,EAAOoI,EAAuBC,GACpC,OACI7J,EAAAC,cAAA,OAAA,CAAMslB,UAAU,qBAAqB7J,MAAOla,EAAK4D,OAAS,GAAK5D,OAAO4H,GACjE5H,IAKP80C,GAAatE,IAAgB,CAC/BpyC,MAAOoyC,EAAGpyC,MACVoC,SAAUgwC,EAAGpyC,MACb6O,SAAUujC,EAAGpyC,MACb0sB,KAAoB,SAAd0lB,EAAGtZ,OAAoBsZ,EAAG10B,YAASlU,EACzC6jB,MAAqB,UAAd+kB,EAAGtZ,OAAqBsZ,EAAG10B,YAASlU,IAGzCmtC,GAAgBA,CAACvE,EAAkBhsC,IACrCP,EACkB,SAAdusC,EAAGtZ,QAAqB,GAAG1yB,iBACb,UAAdgsC,EAAGtZ,QAAsB,GAAG1yB,kBAC5BgsC,EAAGtF,YAAczB,GAAOoB,YAAc,GAAGrmC,sBACzCgsC,EAAGrF,cAAgB,GAAG3mC,yBAuExBwwC,GAAiB5wC,QAAQy5B,IAAcC,KAAqBR,IAE5D2X,GAAmBA,CACrBnB,EACAp7B,KAEA,MAAM6qB,EAAgC,SAAnBuQ,EAAUC,MAAkB9Q,GAAY3/B,IAAIwwC,EAAUvuC,IACnE2vC,EACiB,SAAnBpB,EAAUC,MAAmBD,EAAUzuC,KAAOu4B,GACxCA,GAAgB,IACTsU,GAAe4B,EAAUvuC,GAAIuuC,EAAUzuC,KAC1C8vC,2BAA4Bz8B,EAAQgF,MACpC03B,eAAgB18B,EAAQ28B,QACxBC,cAAe58B,EAAQ68B,OACvBtE,QAAS6C,EAAU7tB,YAEvBre,EACV,OACIpJ,EAAAC,cAAA,MAAA,CACI0rB,KAAK,MAAK,gBACKzR,EAAQgF,MAAQ,EAAC,gBACE,SAAnBo2B,EAAUC,KAAkBxQ,OAAa37B,EAAS,kBAChDN,OAAOwsC,EAAUvuC,IAAG,qBACjBmT,EAAQgF,MAC5BqG,UAAW9f,EACP,eACAs/B,GAAc,yBACdyR,IAAqC,SAAnBlB,EAAUC,MAAmB,0BAC5B,UAAnBD,EAAUC,MAAoB,sBACX,cAAnBD,EAAUC,MAAwB,uBACf,WAAnBD,EAAUC,MAAqB,uBAC/Br7B,EAAQ88B,QAAU,4BAClBN,GAEJv2C,MAAO,CACHP,MAAOqrC,GAAO4B,WACdzsC,OAAQ8Z,EAAQ88B,YAAS5tC,EAAY8Q,EAAQ9Z,OAC7C62C,UAAW/8B,EAAQ88B,OAASja,QAAY3zB,GAE5CilB,QAAUX,IACiB,SAAnB4nB,EAAUC,MAAmBD,EAAUzuC,KAClCi4B,IAnkCOoY,EAAC5B,EAAyB5nB,KACtD,GAAuB,UAAnB4nB,EAAUC,MAAoBD,EAAU/O,MAAO,CAC/C,MAAM8H,EAAUiH,EAAU/O,MAAMve,YAAY7b,IAAKpE,GAAMA,EAAEhB,IACnDowC,EAAc9I,EAAQp9B,MAAOlK,GAAO09B,GAAY3/B,IAAIiC,IAE1D,YADAk+B,GAAWoJ,GAAU8I,GAAa,EAEtC,CACA,GAAuB,SAAnB7B,EAAUC,KAAiB,OAC/B,MAAMxuC,EAAKuuC,EAAUvuC,GACrB,IAAKo+B,GAAkBp+B,EAAIuuC,EAAUzuC,KAAM,OAC3C,MAAMsvB,GAAY4I,GAClB,GAAIrR,EAAM0pB,UAAYjhB,GAAyC,OAA7ByT,GAAiB5wB,QAAkB,CACjE,MAAM5R,EAAMq7B,GAAU98B,OAAQ+8B,GAAmB,SAAZA,EAAGv7B,MAAiBgF,IAAKu2B,GAAOA,EAAG37B,IAClE+N,EAAO1N,EAAI0E,QAAQ89B,GAAiB5wB,SACpCjE,EAAK3N,EAAI0E,QAAQ/E,GACvB,IAAa,IAAT+N,QAAeC,EAAW,CAC1B,MAAOtI,EAAGC,GAAKoI,EAAOC,EAAK,CAACD,EAAMC,GAAM,CAACA,EAAID,GAE7C,YADAmwB,GAAW79B,EAAI+J,MAAM1E,EAAGC,EAAI,IAAI,GAAOkyB,KAAsBlR,EAAM2pB,UAAY3pB,EAAM4pB,QAEzF,CACJ,CACA1N,GAAiB5wB,QAAUjS,EAC3B,MAAMg+B,EAAaN,GAAY3/B,IAAIiC,GACX63B,IAAsBlR,EAAM2pB,SAAY3pB,EAAM4pB,QAKlErS,GAAW,CAACl+B,IAAMg+B,GAAY,GAH1BA,GAAmC,IAArBN,GAAYnzB,KAAY2zB,GAAW,CAACl+B,IAAK,GAAO,GAC7Dk+B,GAAW,CAACl+B,IAAK,GAAM,IAyiCiBmwC,CAAwB5B,EAAW5nB,GACpE2R,KAAaqU,GAAe4B,EAAUvuC,GAAIuuC,EAAUzuC,KAAM6mB,EAAOiU,OACvC,UAAnB2T,EAAUC,MAAoBD,EAAU/O,OAC/CH,GAAwBkP,EAAU/O,MAAMx/B,IAAKqnC,GAAgBkH,EAAU/O,SAG/EjY,cAAgBZ,IACW,SAAnB4nB,EAAUC,MAAmBD,EAAUzuC,KACvCy4B,KAAmBoU,GAAe4B,EAAUvuC,GAAIuuC,EAAUzuC,KAAM6mB,EAAOiU,QAI9EsJ,GAAO9wB,QAAQhO,IAAK6lC,GAzHdoE,EAACpE,EAAkBsD,KAClC,MAAM3sC,IAAEA,GAAQqpC,EACVntC,EAAQ8D,EAAI9D,MACZ0yC,EAAY3xC,QAAQmjC,IAAeA,GAAYhiC,KAAOuuC,EAAUvuC,IAAMgiC,GAAYlkC,QAAUA,GAC5F2yC,EAAY5xC,QAAQmhC,IAAeA,GAAYhgC,KAAOuuC,EAAUvuC,IAAMggC,GAAYliC,QAAUA,GAC5F4yC,GACkB,UAAnBnC,EAAUC,MAAuC,WAAnBD,EAAUC,OAAsB3vC,QAAQ0vC,EAAUQ,aAAajxC,IAC5F+c,EACiB,SAAnB0zB,EAAUC,MAAmBD,EAAUzuC,IACjCsgC,GAAgBmO,EAAUvuC,GAAIlC,EAAOywC,EAAUzuC,IAAKyuC,EAAU7tB,MAC9D,KACJpZ,IAAWuT,GAAS2wB,GAAiB3wB,GACrC80B,EACF90B,GAAUjZ,EAAI+uC,cACqB,mBAAtB/uC,EAAI+uC,cACP/uC,EAAI+uC,cAAc91B,GAClBjZ,EAAI+uC,mBACRtuC,EACJuuC,EAAa9yC,IAAUb,EACvB4zC,EAAiB/yC,IAAUZ,EACjC,OACIjE,EAAAC,cAAA,MAAA,CACIoG,IAAKxB,EACL8mB,KAAK,WAAU,iBACC9mB,EAAK,oBACFomC,GAAO9wB,QAAQrO,QAAQkmC,GAC1C7jB,SAAUopB,EAAY,GAAI,EAAE,gBACM,SAAnBjC,EAAUC,KAAkB9Q,GAAY3/B,IAAIwwC,EAAUvuC,SAAMqC,EAC3Emc,UAAW9f,EACP,gBACA,wBAAwBkD,EAAIiF,OAAS,SACrC2oC,GAAcvE,EAAI,iBAClBuF,IAAcC,GAAa,yBAC3BA,GAAa,yBACbnpC,IAAampC,GAAa,0BACb,YAAb7uC,EAAIxB,MAAsB,yBACb,YAAbwB,EAAIxB,MAAsB,yBAC1BwwC,GAAc,0BACdC,GAAkB,+BAClBH,GAAiB,6BACjBf,GAEJv2C,MAAOm2C,GAAUtE,GACjBzjB,YAAaA,KACc,SAAnB+mB,EAAUC,MAAsC,UAAnBD,EAAUC,MAClCgC,GAAWjQ,GAAe,CAAEvgC,GAAIuuC,EAAUvuC,GAAIlC,WAG3DwpB,QAAUX,IACF9L,GAAU2d,IAAaA,GAAY3d,EAAQ8L,EAAOiU,OAE1DrT,cAAgBZ,IACR9L,IACA4d,KAAoB5d,EAAQ8L,EAAOiU,MAC/BtzB,IAAampC,IACb9pB,EAAMO,kBACNyY,GAAkB4O,EAAUvuC,GAAIlC,OAK3CwwC,GAAkBrD,EAAIsD,KA4DKc,CAAWpE,EAAIsD,EAAWp7B,EAAQ88B,SAC9Dh3C,EAAAC,cAAA,MAAA,CAAKslB,UAAU,0BAKrBsyB,GAAenV,IAAiB,CAClC37B,GAAI27B,EAAG37B,GACPwuC,KAAM7S,EAAGv7B,KACTN,IAAK67B,EAAG77B,IACR4gB,KAAMib,EAAGjb,KACTP,MAAOwb,EAAGxb,MACVqf,MAAO7D,EAAG6D,MACVuP,WAAwB,UAAZpT,EAAGv7B,MAAoBu7B,EAAG6D,MAAQqJ,GAAmBlN,EAAG6D,YAASn9B,IAqD3E0uC,GAAmBA,CAAChD,EAAuB3oB,KAC7C,MAAMlF,EAA2B,GAsBjC,IArBC6tB,GAAQ,IAAIztC,QAAQ,CAACR,EAAKqY,KACvB,MAAMnY,EAAKH,EAAgBC,EAAKC,GAC1BwuC,EAA0B,CAC5BvuC,KACAwuC,KAAM,YACN1uC,MACA4gB,KAAM,CAAEtgB,KAAM,YAAaJ,KAAImgB,MAAO,EAAGQ,OAAQ,KAAMyE,YACvDjF,MAAO,GAEXD,EAAMjX,KACFhQ,gBAACA,EAAM4qB,SAAQ,CAACvkB,IAAKyC,OAAO/B,IACvB0vC,GAAiBnB,EAAW,CACzBl1C,OAAQ28B,GACR7d,MAAOA,EACP23B,SAAS,EACTE,QAAQ,EACRC,QAAQ,QAKP,WAAb7qB,GAAyBsjB,GAAkB,CAC3C,MAAM6F,EAA0B,CAC5BvuC,GAAI7C,EACJqxC,KAAM,SACN1uC,IAAK,KACL4gB,KAAM,CAAEtgB,KAAM,SAAUJ,GAAI7C,EAAuBgjB,MAAO,EAAGQ,OAAQ,MACrER,MAAO,EACP4uB,WAAYrG,IAEhBxoB,EAAMjX,KACFhQ,EAAAC,cAACD,EAAM4qB,SAAQ,CAACvkB,IAAKnC,GAChBuyC,GAAiBnB,EAAW,CACzBl1C,OAAQ28B,GACR7d,MAAO,EACP23B,SAAS,EACTE,QAAQ,EACRC,QAAQ,KAIxB,CACA,OAAO/vB,GAKL8wB,GAAmBA,CAAC/F,EAAkB9yB,KACxC,MAAMvW,IAAEA,GAAQqpC,EACVntC,EAAQ8D,EAAI9D,MACZmzC,EAAYvf,GAAUmK,UAAWn3B,GAASA,EAAK5G,QAAUA,GAAS4G,EAAK2F,MACvEonB,GAAyB,IAAdwf,EAAmBvf,GAAUuf,QAAa5uC,EACrD0E,GACgB,IAAjBnF,EAAImF,WAAuBkrB,KAAyBp0B,EAAgBC,IACpEA,IAAUd,IAA0C,IAAjB4E,EAAImF,SACtCmqC,GACA3pC,KAAsB3F,EAAI2F,oBAAsB1J,EAAgBC,IACjEA,IAAUd,IAA0BuK,GACnCL,GACAswB,KAAyC,IAAlB51B,EAAIsF,YAAwBrJ,EAAgBC,IACpEA,IAAUd,IAA0Bw6B,GACnC2Z,EAAY1D,GAAW7rC,GACvBwvC,EAAa3O,IAAM3kC,QAAUA,EAC7BuzC,EAAe5O,IAAQA,GAAK6O,YAAcxzC,GAAS2kC,GAAK3kC,QAAUA,EAClEyzC,EAAWrP,IAAYpkC,QAAUA,EACjC0zC,EAAe,CAAE1zC,QAAO2tC,OAAQ7pC,EAAyBO,IAAK04B,IAC9D8U,EAAc/tC,EAAI6vC,gBACa,mBAAxB7vC,EAAI6vC,gBACP7vC,EAAI6vC,gBAAgBD,GACpB5vC,EAAI6vC,qBACRpvC,EAEN,IAAIqsC,EA0BJ,OAxBIA,EADA5wC,IAAUb,EACA+6B,GAA8B,KACpC/+B,EAAAC,cAACqrB,IACGnI,QAASguB,GACT/tB,cAAeguB,GACfpiB,SAAyC,IAA/BiiB,GAAoB7rC,OAC9ByD,MACIsoC,GACM7hB,GAAWha,iCACXga,GAAWja,+BAErB+D,SAAUu4B,GACVtjB,QAAUX,GAAUA,EAAMO,oBAG3BppB,IAAUZ,EACP,KAEA0E,EAAI8vC,aACV9vC,EAAI8vC,aAAaF,GAEjBv4C,EAAAC,cAAA,OAAA,CAAMslB,UAAU,yBAAyB5c,EAAIgF,YAAc9I,GAK/D7E,EAAAC,cAAA,MAAA,CACIoG,IAAKxB,EACL8mB,KAAK,+BACUzM,EAAQ,EAAC,YACbsZ,EAA8B,QAAlBA,EAASpnB,KAAiB,YAAc,aAAgBtD,EAAW,YAAS1E,EAAS,iBAC5FvE,EAChB6W,MAAO/S,EAAI+vC,YACXvqB,UAAU,EACV+pB,UAAWA,EACX3yB,UAAW9f,EACP,uBACA,+BAA+BkD,EAAIkF,aAAe,SAClD0oC,GAAcvE,EAAI,wBAClBlkC,GAAY,iCACZjJ,IAAUb,GAAkB,iCAC5Ba,IAAUZ,GAA6B,sCACvCib,IAAU+rB,GAAO9wB,QAAQ/U,OAAS,GAAK,6BACvC+yC,GAAc,iCACdC,GAA+B,SAAf5O,IAAM5F,MAAmB,kCACzCwU,GAA+B,UAAf5O,IAAM5F,MAAoB,mCAC1C0U,GAAY,kCACZ5B,GAEJv2C,MAAOm2C,GAAUtE,GACjB3jB,QAAUX,IACD5f,IAAYq7B,IACjBvP,GAAW/0B,OAAOuE,EAAWskB,EAAM0pB,WAEvCuB,YAAcjrB,IACV,GAAKwqB,EAAL,CACAxqB,EAAMkrB,aAAaC,cAAgB,OACnC,IACInrB,EAAMkrB,aAAaE,QAAQ,aAAcj0C,EAC7C,CAAE,MACE,CAEJ4kC,GAAQ,CAAE5kC,QAAOwzC,UAAW,KAAMzU,KAAM,QAPxB,GASpBmV,WAAarrB,IACT,IAAK8b,IAAQA,GAAK3kC,QAAUA,EAAO,OACnC,MAAMm0C,EAAW/N,GAAO9wB,QAAQ3Q,KAAMkR,GAAMA,EAAE/R,IAAI9D,QAAU2kC,GAAK3kC,OACjE,IAAKm0C,GAAYA,EAAStgB,SAAWsZ,EAAGtZ,SAAW8b,GAAW7rC,GAAM,OACpE+kB,EAAMiB,iBACNjB,EAAMkrB,aAAaK,WAAa,OAChC,MAAMC,EAAOxrB,EAAMkC,cAAc5C,wBAC3B4W,EAAOlW,EAAMyrB,QAAUD,EAAK5sB,KAAO4sB,EAAKt5C,MAAQ,EAAI,OAAS,QAC/D4pC,GAAK6O,YAAcxzC,GAAS2kC,GAAK5F,OAASA,GAAM6F,GAAQ,IAAKD,GAAM6O,UAAWxzC,EAAO++B,UAE7FwV,YAAaA,KACL5P,IAAQA,GAAK6O,YAAcxzC,GAAO4kC,GAAQ,IAAKD,GAAM6O,UAAW,QAExEgB,OAAS3rB,GAh2BF4rB,EAACC,EAAwB7rB,KACxCA,EAAMiB,iBACN,MAAM3V,EAAUwwB,GAEhB,GADAC,GAAQ,OACHzwB,GAAWA,EAAQnU,QAAU00C,EAAS5wC,IAAI9D,MAAO,OACtD,MAAMm0C,EAAW/N,GAAO9wB,QAAQ3Q,KAAMwoC,GAAOA,EAAGrpC,IAAI9D,QAAUmU,EAAQnU,OACtE,IAAKm0C,GAAYA,EAAStgB,SAAW6gB,EAAS7gB,SAAW8b,GAAW+E,EAAS5wC,KAAM,OACnF,MAAMi7B,EAAO5qB,EAAQ4qB,KACrB,GAAIoV,EAAStgB,OAAQ,CACjB,MAAMryB,EAAM2yC,EAAStgB,OACfoc,GAAQrW,GAAcp4B,IAAQ,IAAI8K,QAClC2D,EAAOggC,EAAKhpC,QAAQkN,EAAQnU,OAClC,IAAIkQ,EAAK+/B,EAAKhpC,QAAQytC,EAAS5wC,IAAI9D,OACnC,IAAa,IAATiQ,QAAeC,EAAW,OAK9B,OAJA+/B,EAAK3O,OAAOrxB,EAAM,GAClBC,EAAK+/B,EAAKhpC,QAAQytC,EAAS5wC,IAAI9D,OAC/BiwC,EAAK3O,OAAgB,UAATvC,EAAmB7uB,EAAK,EAAIA,EAAI,EAAGiE,EAAQnU,YACvDi/B,GAAiB,IAAKrF,GAAep4B,CAACA,GAAMyuC,GAEhD,CACA,MAAMv6B,EAAS0oB,GAAmB92B,IAAKuO,GAAMA,EAAE7V,OACzCiQ,EAAOyF,EAAOzO,QAAQkN,EAAQnU,OAC9B20C,EAAUj/B,EAAO5U,OAAQgV,GAAMA,IAAM3B,EAAQnU,OACnD,IAAIkQ,EAAKykC,EAAQ1tC,QAAQytC,EAAS5wC,IAAI9D,OACzB,UAAT++B,IAAkB7uB,GAAM,GAC5BykC,EAAQrT,OAAOpxB,EAAI,EAAGiE,EAAQnU,OAC9B0jC,GAAiBiR,GACjB3H,GAAa2H,GACb,MAAM7wC,EAAMme,GAAelM,IAAI5B,EAAQnU,OACnC8D,GAAK01B,KAAsB,CAAEpI,OAAQttB,EAAK+6B,YAAa3uB,EAAI6/B,SAAU9/B,GAAQ4Y,EAAOiU,OAm0B7D2X,CAAWtH,EAAItkB,GAClC+rB,UAAWA,IAAMhQ,GAAQ,OAEzBzpC,EAAAC,cAAA,MAAA,CAAKslB,UAAU,mCACVkwB,EACA3nC,GACG9N,EAAAC,cAAA,OAAA,CACIslB,UAAW9f,EAAG,qBAAsB+yB,GAAY,4CACpC,QAEQ,SAAnBA,GAAUpnB,KAAkBpR,EAAAC,cAACqpB,GAAiB,CAAChY,KAAM,KAAStR,EAAAC,cAACopB,GAAe,CAAC/X,KAAM,KACrFknB,GAAYC,GAAU9yB,OAAQoG,GAAMA,EAAEqF,MAAMhM,OAAS,GAClDpF,EAAAC,cAAA,OAAA,CAAMslB,UAAU,uBAAuByyB,EAAY,KAKlEC,GACGj4C,EAAAC,cAAC+qB,GAAU,CACP1Z,KAAK,QACLiU,UAAW9f,EAAG,2BAA4B6yC,GAAY,kCACtDzvC,MAAOymB,GAAWnZ,gCACJ,OAAM,gBACLmiC,EACfnqB,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACNib,GAAe/b,GACXA,GAAMtoB,QAAUA,EAAQ,KAAO,CAAEA,QAAOgnB,SAAU6B,EAAMkC,iBAGhErB,YAAcb,GAAUA,EAAMO,mBAE9BjuB,EAAAC,cAACspB,GAAY,OAGpBtb,GACGjO,EAAAC,cAAA,MAAA,CACIslB,UAAW9f,EAAG,yBAA0B0jC,KAAkBtkC,GAAS,kCACnE8mB,KAAK,+BACY,WACjB+tB,cAAgBhsB,GA91BVisB,EAAC3H,EAAkBtkB,KACzCA,EAAMiB,iBACNjB,EAAMO,kBACNwmB,GAAUz7B,QAAU,CAChBnU,MAAOmtC,EAAGrpC,IAAI9D,MACd+0C,OAAQlsB,EAAMyrB,QACdU,WAAY7H,EAAGpyC,MACfk6C,UAAW9H,EAAGpyC,MACd0F,IAAK0sC,EAAGrpC,IAAI3G,UAAY2C,EACxBY,IAAKysC,EAAGrpC,IAAI8F,UAAYi9B,KAE5BtC,GAAiB4I,EAAGrpC,IAAI9D,OACxB,MAAMk1C,EAAU5X,IACZ,MAAM7gB,EAAImzB,GAAUz7B,QACpB,IAAKsI,EAAG,OACR,MAAM1hB,EAAQyF,EAAMic,EAAEu4B,YAAc1X,EAAEgX,QAAU73B,EAAEs4B,QAASt4B,EAAEhc,IAAKgc,EAAE/b,KACpE+b,EAAEw4B,UAAYl6C,EACd4oC,GAAiBrb,GAAUA,EAAK7L,EAAEzc,SAAWjF,EAAQutB,EAAO,IAAKA,EAAM,CAAC7L,EAAEzc,OAAQjF,KAEhFo6C,EAAOA,KACT9zC,OAAOqnB,oBAAoB,cAAewsB,GAC1C7zC,OAAOqnB,oBAAoB,YAAaysB,GACxC,MAAM14B,EAAImzB,GAAUz7B,QAGpB,GAFAy7B,GAAUz7B,QAAU,KACpBowB,GAAiB,OACZ9nB,EAAG,OACR,MAAMzH,EAAO,IAAM6nB,GAAO1oB,QAAQwG,aAAyC,CAAC8B,EAAEzc,OAAQyc,EAAEw4B,WACxFtR,GAAgB3uB,GAChBi4B,GAAcj4B,GACd,MAAMlR,EAAM+4B,GAAO1oB,QAAQmqB,UAAU7hB,EAAEzc,OACnC8D,GAAO2Y,EAAEw4B,YAAcx4B,EAAEu4B,YACzBvb,KAAsB,CAAEkU,OAAQ7pC,EAAK/I,MAAO0hB,EAAEw4B,WAAanY,OAEnEz7B,OAAOkgB,iBAAiB,cAAe2zB,GACvC7zC,OAAOkgB,iBAAiB,YAAa4zB,IA4zBKL,CAAkB3H,EAAItkB,GAChDW,QAAUX,GAAUA,EAAMO,kBAC1BK,cAAgBZ,IACZA,EAAMO,kBACN0V,GAAgB,CAAExpB,QAAS,CAACtV,MAEhCqzC,WAAW,EACXS,YAAcjrB,IACVA,EAAMiB,iBACNjB,EAAMO,uBAUxBgsB,GAAgC,OAAlBtd,EAAMud,QAAmB,KAAQvd,EAAMud,SAAWrnB,GAChEsnB,GAA8B,OAAjBxd,EAAMyd,OAAkB,KAAQzd,EAAMyd,QAAU/lB,GAC7DgmB,GAAoB1d,EAAM2d,eAAiBjgB,GAC3CkgB,GAAqB5d,EAAM6d,gBAAkBhgB,GAC7CigB,GAAqB,IAAK/d,KAAiBE,EAAUsd,SACrDQ,GAAc,CAAEl5C,KAAMq7B,KAAeD,EAAU0d,eAC/CK,GAAe,IAAK/d,EAAU4d,gBAE9BI,IAAc9e,GAAgC,IAArB2G,GAAUr9B,OACnCy1C,GAAa5R,GAAa9F,GAAU8F,GAAWpkC,YAASuE,EAExD0xC,GAAkC,CACpC16C,OAAQ,OACR2jB,SAAU,KACPyX,GAAca,MACdb,GAAcY,MACbI,GAEFue,GAAiC,CAAEh3B,SAAU,KAAMyX,GAAce,MAAWf,GAAcc,IAC1F0e,GAAkC,IACjCxf,GAAc37B,MACd27B,GAAcr7B,GACjB,2BAAqC,GAAGsqC,OACxC,wBAAkC,GAAG1N,QAInCke,GAAYj7C,EAAMk1B,QAAQ,KAC5B,MAAM/P,EAAgB,GAOtB,OANAzV,GAAe,sBAAsBqxB,OAAYlhC,EAAIslB,GACrDzV,GAAe,sBAAsBqxB,OAAY5gC,EAAOglB,GACxDzV,GAAe,wBAAwBqxB,OAAY1E,EAAQlX,GAC3DzV,GAAe,wBAAwBqxB,OAAY3E,EAAWjX,GAC9DzV,GAAe,uBAAuBqxB,OAAYxE,EAAOpX,GACzDzV,GAAe,uBAAuBqxB,OAAYzE,EAAUnX,GACrDA,EAAItf,KAAK,OACjB,CAACk7B,GAAQlhC,EAAIM,EAAOk8B,EAAQD,EAAWG,EAAOD,IAE3C4e,GAASlR,GAAgB,GAAKA,GAAgB,IAE9CmR,GACFn7C,EAAAC,cAAA,MAAA,CACIF,IAAKohC,GACLp6B,GAAIg6B,GAAM,mBACQA,GAClBpV,KAAK,OAAM,gBACIqI,GAAW,EAAC,gBACZiX,GAAO9wB,QAAQ/U,OAAM,0BACdw5B,IAAsBG,UAAqC31B,EAAS,YAC/E0yB,QAAW1yB,EACtBmc,UAAW9f,EACP,YACC03B,IAAcoM,KAAa,wBAC5BA,IAAY,sBACX0B,GAAOoB,YAAc,6BACtB9mB,GAEJplB,MAAO66C,GACPxsB,UA/iCed,IACnB,GAAIqZ,GAAa,OACjB,MAAMrkB,EAASgL,EAAMhL,OACrB,GACIA,IACoB,UAAnBA,EAAOM,SACe,WAAnBN,EAAOM,SACY,aAAnBN,EAAOM,SACY,WAAnBN,EAAOM,SAEX,OAEJ,MAAMo4B,EAAW51C,KAAKD,IAAI,EAAGC,KAAK6Z,MAAM7Z,KAAKD,IAAI0kC,GAAiBQ,GAAc1N,IAAaA,KAC7F,OAAQrP,EAAMrnB,KACV,IAAK,YACDqnB,EAAMiB,iBACNylB,GAAU,EAAG,GACb,MACJ,IAAK,UACD1mB,EAAMiB,iBACNylB,IAAU,EAAI,GACd,MACJ,IAAK,YACD1mB,EAAMiB,iBACNylB,GAAU,MACV,MACJ,IAAK,aACD1mB,EAAMiB,iBACNylB,GAAU,EAAG,GACb,MACJ,IAAK,WACD1mB,EAAMiB,iBACNylB,GAAUgH,EAAU,GACpB,MACJ,IAAK,SACD1tB,EAAMiB,iBACNylB,IAAWgH,EAAU,GACrB,MACJ,IAAK,OACD1tB,EAAMiB,iBACNylB,GAAU,EAAG,EAAG1mB,EAAM2pB,SAAW3pB,EAAM4pB,QAAU,CAAEzwC,IAAK,QAAS8B,IAAK,SAAY,CAAEA,IAAK,UACzF,MACJ,IAAK,MACD+kB,EAAMiB,iBACNylB,GAAU,EAAG,EAAG1mB,EAAM2pB,SAAW3pB,EAAM4pB,QAAU,CAAEzwC,IAAK,OAAQ8B,IAAK,QAAW,CAAEA,IAAK,SACvF,MACJ,IAAK,QACL,IAAK,KACD,GAAIogC,GAAa,CACb,MAAMthB,EAAO4a,GAAUznB,IAAImuB,GAAYhiC,IACvC,GAAmB,UAAf0gB,GAAMtgB,MAAoB4hC,GAAYlkC,QAAUd,EAAuB,CACvE,MAAMwiC,EAAQC,GAAW5rB,IAAImuB,GAAYhiC,IACrCw/B,GAAOH,GAAwBG,EAAMx/B,IAAKqnC,GAAgB7H,GAClE,MACI7Y,EAAMiB,iBACN+X,GAAkBqC,GAAYhiC,GAAIgiC,GAAYlkC,MAEtD,CACA,MACJ,IAAK,IACD,GAAIkkC,KAAgBnK,KAAsBE,IAA6B,CACnE,MAAM4D,EAAKD,GAAUj5B,KAAM8X,GAAMA,EAAEva,KAAOgiC,GAAYhiC,IAClD27B,GAAkB,SAAZA,EAAGv7B,MAAmBu7B,EAAG77B,MAC/B6mB,EAAMiB,iBACNsW,GAAW,CAACvC,EAAG37B,KAAM09B,GAAY3/B,IAAI49B,EAAG37B,KAAK,GAErD,CACA,MACJ,IAAK,SACGyoB,GAAgBxK,MAAM0K,KACtBuZ,IAAYC,GAAc,MAC9B,MACJ,SAESxb,EAAM2pB,SAAW3pB,EAAM4pB,UACI,MAA5B5pB,EAAMrnB,IAAIkF,eACVqzB,KACCG,KAEDrR,EAAMiB,iBACNsW,GAAWgM,IAAqB,OAi+BvCxU,GAAewd,IACZj6C,EAAAC,cAAA,MAAA,CAAKF,IAAKuhC,IACNthC,EAAAC,cAACg6C,GAAW,IAAKQ,MAGzBz6C,EAAAC,cAAA,MAAA,CAAKslB,UAAU,iBACXvlB,EAAAC,cAAA,MAAA,CAAKF,IAAKshC,GAAa9b,UAAU,oBAAoB81B,SAAUvK,GAAc3iB,UAAU,GACnFnuB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,mBAAmBoG,KAAK,WAAWxrB,MAAO,CAAEP,MAAOqrC,GAAO4B,aACrE7sC,EAAAC,cAAA,MAAA,CAAKslB,UAAU,sBAAsBoG,KAAK,MAAK,gBAAgB,EAAGxrB,MAAO,CAAEC,OAAQqqC,KAC9EQ,GAAO9wB,QAAQhO,IAAI,CAAC6lC,EAAI9yB,IAAU64B,GAAiB/F,EAAI9yB,IACxDlf,EAAAC,cAAA,MAAA,CAAKslB,UAAU,6BAGtBka,IAAYpT,KAAOoT,GAAWpT,IAAIjnB,OAAS,GACxCpF,EAAAC,cAAA,MAAA,CACIslB,UAAU,iDACVoG,KAAK,WACLxrB,MAAO,CAAEksB,IAAKoe,GAAc7qC,MAAOqrC,GAAO4B,aAEzCiL,GAAiBrY,GAAWpT,IAAK,QAG1CrsB,EAAAC,cAAA,MAAA,CACIslB,UAAW9f,EAAG,gBAAiB2qC,GAAU,yBAA2B,uBACpEzkB,KAAK,WACLxrB,MACIiwC,GACM,CACIhwC,OAA6B,IAArBqiC,GAAUr9B,OAAeI,KAAKD,IAAIuqC,GAAQzyB,MAAO,KAAOyyB,GAAQzyB,MACxEzd,MAAOqrC,GAAO4B,YAElB,CAAEjtC,MAAOqrC,GAAO4B,WAAYoK,UAAW2D,IAAc9e,EAAU,SAAM1yB,IAjW5EkyC,MACnB,MAAMhL,MAAEA,EAAKC,IAAEA,GAAQF,GACjBppB,EAA2B,GACjC,IAAK,IAAIhK,EAAIqzB,EAAOrzB,EAAIszB,EAAKtzB,GAAK,EAAG,CACjC,MAAMylB,EAAKD,GAAUxlB,GACfq4B,EAAYuC,GAAYnV,GACxB6Y,EAAezL,GAAQE,cAAc/yB,GACrCuV,EACU,SAAZkQ,EAAGv7B,MAAmBvB,QAAQ88B,EAAG77B,MAAQjB,QAAQ85B,KAA0BqG,GAAqBjhC,IAAI49B,EAAG37B,IACrGy0C,EAAgBhpB,GAAckQ,EAAG77B,IAAM64B,KAAwBgU,GAAehR,EAAG37B,GAAI27B,EAAG77B,MAAQ,KAChG40C,KACFjpB,GAAckQ,EAAG77B,KAAO84B,KACmC,SAArDA,GAAqB,CAAE54B,GAAI27B,EAAG37B,GAAIF,IAAK67B,EAAG77B,MAE9C60C,IACDtL,KACAlT,GAA4B,SAAZwF,EAAGv7B,OAAmBu7B,EAAG77B,KAC0B,SAA9Dq2B,EAAa,CAAEn2B,GAAI27B,EAAG37B,GAAIsuB,MAAOqN,EAAG77B,IAAK0jC,oBAEnDtjB,EAAMjX,KACFhQ,EAAAC,cAAA,MAAA,CACIoG,IAAKyC,OAAO45B,EAAG37B,IACfwe,UAAU,qBACVplB,MAAOiwC,GAAU,CAAE/jB,IAAKyjB,GAAQG,QAAQhzB,GAAIrd,MAAOqrC,GAAO4B,YAAe,CAAEjtC,MAAOqrC,GAAO4B,aAExF4J,GAAiBnB,EAAW,CACzBl1C,OAAQ0vC,GAAQC,WAAW9yB,GAC3BiC,MAAOjC,EACP45B,QAAe,IAAN55B,EACT85B,OAAQ95B,IAAMwlB,GAAUr9B,OAAS,EACjC4xC,OAAQ0E,IAEXlpB,SAAcgpB,IAA2E,IAAlBA,GACpEx7C,EAAAC,cAAA,MAAA,CACIslB,UAAU,wBACVplB,MAAO,CACHC,OAAQq7C,OAAaryC,EAAYmyC,QAAgBnyC,EACjDxJ,MAAOoqC,SAAiB5gC,GAE5BilB,QAAUX,GAAUA,EAAMO,mBAEzButB,IAKrB,CACA,OAAOv0B,GAqTUq0B,KAEF7b,IAAYvS,QAAUuS,GAAWvS,OAAO9nB,OAAS,GAAMqqC,KACtDzvC,EAAAC,cAAA,MAAA,CACIslB,UAAU,oDACVoG,KAAK,WACLxrB,MAAO,CAAEP,MAAOqrC,GAAO4B,aAEtBiL,GAAiBrY,IAAYvS,OAAQ,YAIjD4O,GACG97B,EAAAC,cAAA,MAAA,CAAKslB,UAAU,6CAA6CplB,MAAO,CAAEksB,IAAKoe,KACtEzqC,EAAAC,cAACs6C,GAAkB,IAAKI,MAG/BC,IACG56C,EAAAC,cAAA,MAAA,CAAKslB,UAAU,mBAAmBplB,MAAO,CAAEksB,IAAKoe,KAC5CzqC,EAAAC,cAACo6C,GAAiB,IAAKK,QAIjCt4B,IAAc+3B,IAAcn6C,EAAAC,cAACk6C,GAAU,IAAKvd,EAAUwd,SAExDp6C,EAAAC,cAAC2rB,IACG5G,KAAMwK,GAAgBxK,KACtB6G,SAAU2D,GAAgB3D,SAC1BC,QAAS4D,GACT1D,UAAWA,EACXD,UAAU,eACVE,WAAS,GAE6B,YAArCuD,GAAgBC,iBAAiCzvB,EAAAC,cAAC80B,GAAmB,MAAM/0B,EAAAC,cAAC22B,GAAkB,OAGlGikB,IAAc5R,IACXjpC,EAAAC,cAACo4B,IACGpC,OAAQ4kB,GACRhvB,SAAUod,GAAWpd,SACrB7G,QACA8G,QAASA,IAAMod,GAAc,MAC7Bld,UAAWA,EACXsM,cAAegJ,GAAWtoB,WAM1C,OACIhZ,gBAACuY,GAAeojC,SAAQ,CAAC32C,MAAOowC,IAC5Bp1C,EAAAC,cAAA,MAAA,CACIF,IAAKqhC,GACL7b,UAAW9f,EAAG,gBAAiBw2B,GAAe,uBAAwBC,GAAc,iBACpElQ,uBACI+U,GACpB5gC,MAAO26C,IAENG,IAAaj7C,EAAAC,cAAA,QAAA,CAAA,mBAAyB8gC,IAASka,KAC9Chf,SAA2B7yB,IAAXgoB,GAAwB4K,GAA6BD,IACnE/7B,EAAAC,cAAA,MAAA,CAAKslB,UAAU,6BACCnc,IAAXgoB,GAAwBpxB,EAAAC,cAAA,KAAA,CAAIslB,UAAU,uBAAuB6L,GAC7D4K,GACGh8B,EAAAC,cAAA,MAAA,CAAKslB,UAAU,+BAA+ByW,GAElDh8B,EAAAC,cAAA,MAAA,CAAKslB,UAAU,2BAA2BplB,MAAO,CAAEg6B,IAAK+gB,GAAS,EAAI,KAChEnf,IAIb/7B,EAAAC,cAAA,MAAA,CAAKslB,UAAW9f,EAAG,eAAgB02B,GAAa,oBAAqB4E,GAAQ5gC,MAAO46C,IAC/EI,KAKrB,CAEAvf,GAAQnjB,YAAc,UCtvFf,MAAMmjC,GAAiC,iBAOjCC,GAA4B,gweAkLzC,IAAIjkC,IAAW,EAEf,MAcMC,GACD7X,EAAc8X,qBAAyC,oBAAX5R,OAAyBlG,EAAM+X,gBAAkB/X,EAAMgY,WAG3F8jC,GAA8BA,KACvCjkC,GAAa,KAnBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAeyjC,IAExB,YADAhkC,IAAW,GAGf,MAAMzX,EAAQqW,SAASvW,cAAc,SACrCE,EAAM4G,GAAK60C,GACXz7C,EAAMiY,aAAa,eAAgB,QACnCjY,EAAMkY,YAAcwjC,GACpBrlC,SAAS8B,KAAKjB,YAAYlX,GAC1ByX,IAAW,GASPM,IACD,KC1MDyQ,GAAaA,CAACvB,EAAuB3O,KACvC,MAAMvY,EAAOF,EAAMN,WAAiD,EAAG4R,OAAO,GAAIiU,YAAWplB,WAAUyoB,GAAQ7oB,IAC3GC,EAAAC,cAAA,MAAA,CACIF,IAAKA,EACL8oB,QAAQ,YACRjpB,MAAO0R,EACPlR,OAAQkR,EACRwX,KAAK,eACLC,UAAU,QAAO,cACL,OACZxD,UAAW,CAAC,eAAgBA,GAAW5f,OAAOC,SAASC,KAAK,KAC5D1F,MAAOA,KACHyoB,GAEHxB,IAIT,OADAlnB,EAAKuY,YAAcA,EACZvY,GAGE67C,GAAgBpzB,GACzB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,uKACR,iBAES4hB,GAAkBhB,GAC3B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,6DACR,mBAES2hB,GAAmBf,GAC5B3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,2DACR,oBAESohB,GAAYR,GACrB3oB,EAAAC,cAAA,OAAA,CAAM8H,EAAE,0GACR,yHClCJH,EAAMo0C,OAAOC,GAEN,MAAMx2C,GAAKA,IAAIC,IAAyDA,EAAWC,OAAOC,SAASC,KAAK,KAElGR,GAAQA,CAACL,EAAeM,EAAaC,IAAgBC,KAAKF,IAAIE,KAAKD,IAAIP,EAAOM,GAAMC,GAEpF22C,GAA4B,CAAC,KAAM,MAGnCC,GAAWn3C,IACpB,GAAa,MAATA,GAA2B,KAAVA,EAAc,OAAO,KAC1C,GAAI4C,EAAMC,QAAQ7C,GAAQ,OAAOA,EAAM8C,UAAY9C,EAAQ,KAC3D,GAAIA,aAAiBwC,MAAyB,iBAAVxC,GAAuC,iBAAVA,EAAoB,CACjF,MAAMgD,EAASJ,EAAM5C,GACrB,OAAOgD,EAAOF,UAAYE,EAAS,IACvC,CACA,OAAO,MAGEo0C,GAAYA,CAAC3vC,EAA6BC,MAAkCD,KAAOC,GAAKD,EAAE4vC,OAAO3vC,EAAG,OACpG4vC,GAAcA,CAAC7vC,EAAUC,IAAaD,EAAE8vC,SAAS7vC,EAAG,OACpD8vC,GAAaA,CAAC/vC,EAAUC,IAAaD,EAAEgwC,QAAQ/vC,EAAG,OAClDgwC,GAAgBA,CAACC,EAAYrM,EAAqBC,OACzDD,IAAWC,GAAQ+L,GAAYK,EAAKrM,IAAWkM,GAAWG,EAAKpM,IAExDqM,GAAeA,CAACnwC,EAA6BC,KACtD,GAAID,IAAMC,EAAG,OAAO,EACpB,IAAKD,IAAMC,EAAG,OAAO,EACrB,MAAMmwC,EAAOA,CAACvQ,EAAiBwQ,IAA0B,MAALxQ,GAAkB,MAALwQ,KAAiBxQ,KAAOwQ,GAAKxQ,EAAE+P,OAAOS,EAAG,OAC1G,OAAOD,EAAKpwC,EAAE,GAAIC,EAAE,KAAOmwC,EAAKpwC,EAAE,GAAIC,EAAE,KAG/BqwC,GAAkB/3C,GACtBE,MAAMC,QAAQH,GACZ,CAACm3C,GAAQn3C,EAAM,IAAKm3C,GAAQn3C,EAAM,KADPk3C,GAKzBc,GAAgBA,CAACx7C,EAAc4G,KACxC,MAAM60C,EAAUz7C,EAAK6O,OACrB,IAAK4sC,EAAS,OAAO,KACrB,MAAMC,EAASt1C,EAAMq1C,EAAS70C,GAAQ,GACtC,GAAI80C,EAAOp1C,UAAW,OAAOo1C,EAC7B,MAAMC,EAAY,CACd/0C,EAAOkH,QAAQ,MAAO,KAAKA,QAAQ,MAAO,KAC1C,WACA,SACA,aACA,aACA,YAEJ,IAAK,MAAMqL,KAAKwiC,EAAW,CACvB,MAAMn1C,EAASJ,EAAMq1C,EAAStiC,GAAG,GACjC,GAAI3S,EAAOF,UAAW,OAAOE,CACjC,CACA,OAAO,MAGEC,GAAaA,CAACjD,EAAqBoD,IAAoBpD,GAASA,EAAM8C,UAAY9C,EAAMoD,OAAOA,GAAU,GAqBzGg1C,GAAcA,CACvBT,EACAxwB,EACAjS,EACA6G,EAAanZ,MAEF,MAAP+0C,EAAoB,KACnBA,EAAI70C,UACLoS,EAAQmjC,aAAef,GAAYK,EAAK57B,GAAa,cACrD7G,EAAQojC,eAAiBd,GAAWG,EAAK57B,GAAa,gBACtD7G,EAAQqjC,SAAWjB,GAAYK,EAAKziC,EAAQqjC,SAAiB,UAC7DrjC,EAAQsjC,SAAWhB,GAAWG,EAAKziC,EAAQsjC,SAAiB,UAC5DtjC,EAAQujC,oBAAoBd,EAAKxwB,GAAkB,oBAChD,KANoB,cASlBuxB,GAAgBA,CACzB14C,EACAkV,KAEA,MAAM6G,EAAMnZ,IACN+1C,EAAaP,GAAYp4C,EAAM,GAAI,QAASkV,EAAS6G,GACrD68B,EAAWR,GAAYp4C,EAAM,GAAI,MAAOkV,EAAS6G,GACvD,OAAK48B,IAAeC,GAAY54C,EAAM,IAAMA,EAAM,IAAMw3C,GAAWx3C,EAAM,GAAIA,EAAM,IACxE,CAAC,eAAgB,gBAErB,CAAC24C,EAAYC,IAGXC,GAAgBA,CAAClB,EAAYxwB,EAAgCjS,IAC/B,MAAvCkjC,GAAYT,EAAKxwB,EAAUjS,GA8ClB4jC,GAA2D,CACpE,CACIj1C,MAAO,YACPk1C,SAAUA,KACN,MAAMC,EAAQp2C,IACd,MAAO,CAACo2C,EAAM11C,QAAQ,QAAS01C,EAAMC,MAAM,WAGnD,CACIp1C,MAAO,YACPk1C,SAAUA,KACN,MAAM5wB,EAAOvlB,IAAQs2C,SAAS,EAAG,OACjC,MAAO,CAAC/wB,EAAK7kB,QAAQ,QAAS6kB,EAAK8wB,MAAM,WAGjD,CACIp1C,MAAO,cACPk1C,SAAUA,KACN,MAAMC,EAAQp2C,IACd,MAAO,CAACo2C,EAAME,SAAS,EAAG,OAAQF,KAG1C,CACIn1C,MAAO,gBACPk1C,SAAUA,KACN,MAAMC,EAAQp2C,IACd,MAAO,CAACo2C,EAAM11C,QAAQ,SAAU01C,EAAMC,MAAM,YAGpD,CACIp1C,MAAO,aACPk1C,SAAUA,KACN,MAAMlkC,EAAOjS,IAAQN,IAAI,EAAG,SAC5B,MAAO,CAACuS,EAAKvR,QAAQ,SAAUuR,EAAKokC,MAAM,YAGlD,CAAEp1C,MAAO,QAASk1C,SAAUA,IAAM,CAAC,KAAM,QCtLvCI,GAA6BxB,GAAeA,EAAIv0C,OAAO,MAAMyH,OAAO,GAAGuuC,cAMvE,SAAUC,IACZr5C,MAAOs5C,EAASnlC,aAChBA,EAAYC,SACZA,EACAmlC,cAAeC,EAAiBC,sBAChCA,EAAqBC,UACrBA,EAAY,EAACC,cACbA,EAAapB,QACbA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiBzuB,SACjBA,GAAW,EAAK4vB,SAChBA,GAAW,EAAKC,4BAChBA,GAA8B,EAAKC,gBACnCA,EAAeC,mBACfA,EAAqBZ,GAAyBa,sBAC9CA,GAAwB,EAAKC,iBAC7BA,GAAmB,EAAIhzB,UACvBA,GAAY,EAAKizB,cACjBA,EAAa5vB,WACbA,EAAUtD,UACVA,EAASzG,UACTA,EAASplB,MACTA,IAEA27C,KAEA,MAAMziC,OAA6BjQ,IAAdk1C,GACda,EAAeC,GAAoBp/C,EAAMwZ,SAAuB,IACnEujC,GAAe5jC,GAAgB+iC,KAE7Bl3C,EAAQhF,EAAMk1B,QAChB,IAAO7b,EAAe0jC,GAAeuB,GAAaa,EAClD,CAAC9lC,EAAcilC,EAAWa,KAEvB7O,EAAOC,GAAOvrC,GAEdq6C,EAAkBC,GAAuBt/C,EAAMwZ,SAA+B,SAC/E+kC,EAAgBC,GAAqBa,EACrCE,EAAmBv/C,EAAM4Z,YAC1BuS,SAC6B/iB,IAAtBo1C,GAAiCc,EAAoBnzB,GACzDsyB,IAAwBtyB,IAE5B,CAACqyB,EAAmBC,IAGlBe,EAAax/C,EAAMk1B,QACrB,KAAA,CAASqoB,UAASC,UAASH,cAAaC,gBAAeG,sBACvD,CAACF,EAASC,EAASH,EAAaC,EAAeG,KAI5CgC,EAAcC,GAAmB1/C,EAAMwZ,SAAgB,KACzD82B,GAASC,GAAOoO,GAAiB/2C,KAASU,QAAQ,UAEjDq3C,EAAgB3/C,EAAMk1B,QACxB,IAAMhwB,MAAM4P,KAAK,CAAE1P,OAAQs5C,GAAa,CAACkB,EAAG3iC,IAAMwiC,EAAan4C,IAAI2V,EAAG,UACtE,CAACwiC,EAAcf,IAEbmB,EAAmBF,EAAcA,EAAcv6C,OAAS,GAExD06C,EAAc9/C,EAAM4Z,YACrBmmC,IACG,MAAMlmC,EAAOkmC,EAAMz3C,QAAQ,SAC3Bo3C,EAAiBvyB,GACTA,EAAKkvB,OAAOxiC,EAAM,SAAiBsT,GACvC+xB,IAAgBrlC,GACTA,KAGf,CAACqlC,IAGCc,EAAgBhgD,EAAM4Z,YACvB+iC,IACOL,GAAYK,EAAK8C,EAAan3C,QAAQ,UAAWw3C,EAAYnD,GACxDH,GAAWG,EAAKkD,EAAiB5B,MAAM,WAAW6B,EAAYnD,EAAIuB,SAASQ,EAAY,EAAG,WAEvG,CAACe,EAAcI,EAAkBnB,EAAWoB,IAI1CG,EAAcjgD,EAAM+Y,OAAqB/T,GAC/ChF,EAAMgY,UAAU,KACZ,MAAMmV,EAAO8yB,EAAYjnC,QACzBinC,EAAYjnC,QAAUhU,EACtB,MAAM0d,EAA2B,QAAlB67B,EAA2BhO,GAAOD,EAAUA,GAASC,EACpE,IAAK7tB,EAAQ,SACI05B,GAAUjvB,EAAK,GAAImjB,KAAW8L,GAAUjvB,EAAK,GAAIojB,KACrDyP,EAAct9B,IAE5B,CAAC4tB,EAAOC,IAEX,MAAM2P,GAAa3C,GAAWkC,EAAahD,QAAQc,EAAS,SACtD4C,GAAa3C,GAAWqC,EAAiBtD,SAASiB,EAAS,UAG1D4C,EAAYC,GAAiBrgD,EAAMwZ,SAAuB,MAC3D8mC,EAAUtgD,EAAMk1B,QAAsB,KACnC+pB,IAAqBmB,GAAcpxB,GAAY4vB,EAAiB1C,GAC/C,QAAlBqC,GAA2BjO,IAAUC,EAC9B+L,GAAY8D,EAAY9P,GAAS4L,GAAc,CAAC5L,EAAO8P,GAE5C,UAAlB7B,GAA6BhO,IAAQD,EAC9BkM,GAAW4D,EAAY7P,GAAO2L,GAAc,CAACkE,EAAY7P,GAE7D2L,GACR,CAAC+C,EAAkBmB,EAAY7B,EAAejO,EAAOC,EAAKvhB,EAAU4vB,IAGjE2B,EAAYvgD,EAAM4Z,YACnB+iC,IACG,GAAI3tB,GAAY4vB,EAAU,OAC1B,GAAIf,GAAclB,EAAK4B,EAAeiB,GAAa,OACnD,IAAI3lC,EACA2mC,EACkB,UAAlBjC,GAEA1kC,EAAO,CAAC8iC,EAAKpM,GAAOiM,GAAWG,EAAKpM,GAAO,KAAOA,GAClDiQ,EAAe,OACRlQ,GAASgM,GAAYK,EAAKrM,IAEjCz2B,EAAO,CAAC8iC,EAAK,MACb6D,EAAe,QAEf3mC,EAAO,CAACy2B,EAAOqM,GACf6D,EAAe,SAEdnnC,GAAc+lC,EAAiBvlC,GACpCT,IAAWS,EAAM8iC,EAAK4B,GACtBgB,EAAiBiB,IAErB,CAACxxB,EAAU4vB,EAAUL,EAAeiB,EAAYjP,EAAKD,EAAOj3B,EAAcD,EAAUmmC,KAIjFkB,EAAYC,GAAiB1gD,EAAMwZ,SAAgB,IAAM82B,GAASC,GAAOoO,GAAiB/2C,KAC3Fu5B,EAAUnhC,EAAM+Y,OAA8B,MAC9CsuB,GAAkBrnC,EAAM+Y,OAAOkT,GAE/B00B,GAAW3gD,EAAM4Z,YAAa+iC,IAChC,MAAMt2C,EAAMs2C,EAAIv0C,OAAO,cACjB0a,EAAKqe,EAAQnoB,SAAS+U,cAAiC,cAAc1nB,OAC3Eyc,GAAI0D,SACL,IAEHxmB,EAAMgY,UAAU,KACZ,IAAKqvB,GAAgBruB,QAAS,OAC9BquB,GAAgBruB,SAAU,EAC1B,MAAM0J,EAAS+9B,EACfT,EAAct9B,GAEd,MAAM3b,EAAKb,OAAOqR,WAAW,IAAMopC,GAASj+B,GAAS,GACrD,MAAO,IAAMxc,OAAOigB,aAAapf,IAElC,IAEH,MAMM+mB,GAAgBA,CAACJ,EAAyCivB,KAC5D,IAAI9iC,EAAqB,KACzB,OAAQ6T,EAAMrnB,KACV,IAAK,YACDwT,EAAO8iC,EAAIuB,SAAS,EAAG,OACvB,MACJ,IAAK,aACDrkC,EAAO8iC,EAAIr1C,IAAI,EAAG,OAClB,MACJ,IAAK,UACDuS,EAAO8iC,EAAIuB,SAAS,EAAG,OACvB,MACJ,IAAK,YACDrkC,EAAO8iC,EAAIr1C,IAAI,EAAG,OAClB,MACJ,IAAK,OACDuS,EAAO8iC,EAAIr0C,QAAQ,QACnB,MACJ,IAAK,MACDuR,EAAO8iC,EAAIsB,MAAM,QACjB,MACJ,IAAK,SACDpkC,EAAO6T,EAAM0pB,SAAWuF,EAAIuB,SAAS,EAAG,QAAUvB,EAAIuB,SAAS,EAAG,SAClE,MACJ,IAAK,WACDrkC,EAAO6T,EAAM0pB,SAAWuF,EAAIr1C,IAAI,EAAG,QAAUq1C,EAAIr1C,IAAI,EAAG,SACxD,MACJ,IAAK,QACL,IAAK,IAGD,OAFAomB,EAAMiB,sBACN4xB,EAAU5D,GAEd,QACI,OAERjvB,EAAMiB,iBACF9U,GA1CW8iC,KACf+D,EAAc/D,GACdqD,EAAcrD,GACdz2C,OAAOqR,WAAW,IAAMopC,GAAShE,GAAM,IAuC7BvI,CAAUv6B,IAGlB+mC,GAAW5gD,EAAMk1B,QAAQ,ID7EF2rB,KAC7B,MAAMvQ,EAAQ1oC,IAAQU,QAAQ,QAC9B,OAAOpD,MAAM4P,KAAK,CAAE1P,OAAQ,GAAK,CAACw6C,EAAG3iC,KACjC,MAAM0/B,EAAMrM,EAAMhpC,IAAI2V,EAAG,OACzB,MAAO,CAAE5W,IAAKs2C,EAAIv0C,OAAO,MAAOS,MAAOg4C,EAAUlE,GAAMmE,KAAMnE,EAAIv0C,OAAO,YCyEvC24C,CAAiBhC,GAAqB,CAACA,IACtEf,GAAQp2C,IACRo5C,GAAeV,EAAQ,GACvBW,GAAaX,EAAQ,GACrBY,KAAoB5Q,KAAWC,EAsIrC,OACIvwC,uBACID,IAAKohC,EACL5b,UAAW9f,GACP,oBACAupB,GAAY,6BACZ4vB,GAAY,8BACZr5B,GACH,iBACeyG,wBACKuyB,EACrBp+C,MAAOA,EACPghD,aAAcA,IAAMd,EAAc,OAEjCV,EAAcxzC,IAlJHi1C,CAACrB,EAAc7gC,KAC/B,MAAMmiC,EDvGeC,EAACvB,EAAcjB,KACxC,MAAMyC,EAAexB,EAAMz3C,QAAQ,SAC7BgoC,EAAQiR,EAAaj5C,QAAQ,QAC7Bk5C,EAAeh8C,KAAKgqC,KAAK+R,EAAatD,MAAM,SAASwD,KAAKnR,EAAO,OAAS,EAAI,EAAI,GAClFoR,EAAY5C,GAAmBA,EAAkB,EAAIA,EAAkBt5C,KAAKD,IAAIi8C,EAAc,GAC9FH,EAAwB,GAC9B,IAAK,IAAI9gC,EAAI,EAAGA,EAAImhC,EAAWnhC,GAAK,EAAG,CACnC,MAAMohC,EAAYrR,EAAMhpC,IAAQ,EAAJiZ,EAAO,OACnC8gC,EAAMrxC,KAAK,CACP3J,IAAKs7C,EAAUv5C,OAAO,cACtBw5C,KAAM18C,MAAM4P,KAAK,CAAE1P,OAAQ,GAAK,CAACw6C,EAAG73C,KAChC,MAAM40C,EAAMgF,EAAUr6C,IAAIS,EAAG,OAC7B,MAAO,CAAE40C,MAAKkF,cAAelF,EAAIN,OAAOkF,EAAc,aAGlE,CACA,OAAOF,GCuFWC,CAAcvB,EAAOjB,GAC7BjI,EAAoB,IAAV33B,EACV63B,EAAS73B,IAAUygC,EAAcv6C,OAAS,EAE1C08C,GADiBrB,EAAWpE,OAAO0D,EAAO,SAAWU,EAAa,QAGnEnQ,GAASA,EAAM+L,OAAO0D,EAAO,SAAWzP,EAAQ,QAChDC,GAAOA,EAAI8L,OAAO0D,EAAO,SAAWxP,EAAM,QAC1CsG,IAAY8I,EAAc/xB,KAAMre,GAAMkxC,EAAWpE,OAAO9sC,EAAG,UAAYwwC,EAAMz3C,QAAQ,SAAW,MAErG,OACItI,EAAAC,cAAA,MAAA,CACIoG,IAAK05C,EAAM33C,OAAO,WAClBmd,UAAU,mBACVoG,KAAK,QAAO,aACAo0B,EAAM33C,OAAO,cAEzBpI,EAAAC,cAAA,MAAA,CAAKslB,UAAU,2BACVsxB,EACG72C,0BACImH,KAAK,SACLoe,UAAU,gCAA+B,aAC7B+J,GAAYyyB,eAAiB,iBACzCrmC,MAAO4T,GAAYyyB,eAAiB,iBACpC/yB,SAAUA,IAAakxB,EACvB7xB,QAASA,IAAMyxB,EAAYL,EAAavB,SAAS,EAAG,WAEpDl+C,EAAAC,cAAC0pB,GAAe,OAGpB3pB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,gCAEpBvlB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBAAwB,YAAW,UAC7Cw6B,EAAM33C,OAAO,cAEjB2uC,EACG/2C,0BACImH,KAAK,SACLoe,UAAU,gCAA+B,aAC7B+J,GAAY0yB,WAAa,aACrCtmC,MAAO4T,GAAY0yB,WAAa,aAChChzB,SAAUA,IAAamxB,EACvB9xB,QAASA,IAAMyxB,EAAYL,EAAan4C,IAAI,EAAG,WAE/CtH,EAAAC,cAACypB,GAAgB,OAGrB1pB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,iCAGxBvlB,EAAAC,cAAA,MAAA,CAAKslB,UAAU,mBAAmBoG,KAAK,OAClCi1B,GAASz0C,IAAK81C,GACXjiD,wBAAMqG,IAAK47C,EAAG57C,IAAKkf,UAAU,kBAAkBoG,KAAK,eAAc,aAAas2B,EAAGnB,MAC7EmB,EAAGp5C,SAIhB7I,EAAAC,cAAA,MAAA,CAAKslB,UAAU,gBAAgBoG,KAAK,OAAM,aAAao0B,EAAM33C,OAAO,cAC/Di5C,EAAMl1C,IAAK+1C,GACRliD,EAAAC,cAAA,MAAA,CAAKoG,IAAK67C,EAAK77C,IAAKkf,UAAU,eAAeoG,KAAK,OAC7Cu2B,EAAKN,KAAKz1C,IAAI,EAAGwwC,MAAKkF,gBAAgBM,KACnC,MAAMC,EAASP,IAAiBhD,EAC1BwD,EAAUjG,GAAUO,EAAKrM,GACzBgS,EAAQlG,GAAUO,EAAKpM,GACvBxhB,EAAWszB,GAAWC,EACtBC,GAAWH,GAAUlB,IAAmBxE,GAAcC,EAAKrM,EAAOC,GAClEiS,GACDJ,KACCpB,MACAC,IACFvE,GAAcC,EAAKqE,GAAcC,IAC/BwB,EAAczzB,GAAY6uB,GAAclB,EAAK4B,EAAeiB,GAC5DkD,IAAeZ,GAAe1F,GAAUO,EAAKmF,KAAiBM,EAC9DO,EAA4B,IAAbR,IAAoBtD,GAA8C,IAAflC,EAAIx0C,OACtEy6C,EACW,IAAbT,IAAoBtD,GAA+BlC,EAAIx0C,SAAWw0C,EAAIkG,cAC1E,OACI7iD,EAAAC,cAAA,MAAA,CACIoG,IAAKs2C,EAAIv0C,OAAO,cAChBujB,KAAK,2BACUoD,QAAY3lB,EAC3Bmc,UAAW9f,GACP,mBACA88C,GAAW,6BACXA,GAAWF,GAAW,gCACtBE,GAAWD,GAAS,8BACpBE,GAAa,4BACbA,GAAapG,GAAUO,EAAKqE,KAAiB,kCAC7CwB,GAAapG,GAAUO,EAAKsE,KAAe,gCAC3C0B,GAAgB,kCAChBC,GAAe,mCAGnB5iD,EAAAC,cAAA,SAAA,CACIkH,KAAK,oBACKw1C,EAAIv0C,OAAO,cACrB+lB,SAAUu0B,EAAa,GAAI,EAAE,aACjB/F,EAAIv0C,OAAO,sBAAqB,gBAEvC42C,GAAyB5C,GAAUO,EAAKqB,IAAS,YAAS50C,kBAEhDq5C,QAAer5C,EAC9B4lB,SAAUozB,EACV78B,UAAW9f,GACP,cACA28C,GAAU,sBACVP,IAAiBO,GAAU,uBAC3BrzB,GAAY,yBACXiwB,GAAyB5C,GAAUO,EAAKqB,KAAU,qBACnDyE,GAAe,yBAEnBp0B,QAASA,IAAMkyB,EAAU5D,GACzBmG,aAAcA,IAAMzC,EAAc1D,GAClCwE,aAAcA,IACVd,EAAelzB,GAAUA,GAAQivB,GAAUjvB,EAAMwvB,GAAO,KAAOxvB,GAEnE41B,QAASA,IAAMrC,EAAc/D,GAC7BnuB,UAAYd,GAAUI,GAAcJ,EAAOivB,IAE1CA,EAAIx0C,iBA6BjD,CCrWO,MAAM66C,GAA0E,CACnF1S,MAAO,QACPC,IAAK,MACL0S,eAAgB,IAChBC,WAAY,oBACZ3wB,MAAO,QACPyrB,MAAO,QACPhI,OAAQ,SACRmN,OAAQ,KACRpB,cAAe,iBACfC,UAAW,aACXoB,aAAc,qBAqBlB,SAASx3B,IAAQ5G,KAAEA,EAAI6G,SAAEA,EAAQE,UAAEA,EAASs3B,UAAEA,EAASr3B,UAAEA,EAASzG,UAAEA,EAASplB,MAAEA,EAAKmjD,WAAEA,EAAUhgD,SAAEA,IAC9F,MAAMvD,EAAMC,EAAM+Y,OAA8B,OACzCoT,EAAUC,GAAepsB,EAAMwZ,SAAS,CAAE6S,IAAK,EAAGC,KAAM,EAAGC,OAAO,IAEnEC,EAASxsB,EAAM4Z,YAAY,KAC7B,MAAMkJ,EAAK/iB,EAAIiZ,QACf,IAAK8J,EAAI,OACT,MAAM2J,EAAKvmB,OAAOwmB,WACZC,EAAKzmB,OAAO0mB,YACZrM,EAAIuC,EAAG+J,YACP5Q,EAAI6G,EAAGgK,aACb,IAAIT,EACAC,EACJ,GAAIT,GAAYA,EAASkB,YAAa,CAClC,MAAMtgB,EAAIof,EAASmB,wBACnBX,EAAM5f,EAAEygB,OAAS,EACbb,EAAMpQ,EAAI0Q,EAAK,GAAKlgB,EAAE4f,IAAM,EAAIpQ,GAAK,IAAGoQ,EAAM5f,EAAE4f,IAAM,EAAIpQ,GAC9DqQ,EAAqB,eAAdP,EAA6Btf,EAAEwgB,MAAQ1M,EAAkB,WAAdwL,EAAyBtf,EAAE6f,KAAO7f,EAAE7M,MAAQ,EAAI2gB,EAAI,EAAI9T,EAAE6f,IAChH,MACID,EAAMM,EAAK,EAAI1Q,EAAI,EACnBqQ,EAAOG,EAAK,EAAIlM,EAAI,EAExB8L,EAAMhnB,GAAMgnB,EAAK,EAAG7mB,KAAKD,IAAI,EAAGonB,EAAK1Q,EAAI,IACzCqQ,EAAOjnB,GAAMinB,EAAM,EAAG9mB,KAAKD,IAAI,EAAGknB,EAAKlM,EAAI,IAC3C6L,EAAae,GAAUA,EAAKZ,OAASY,EAAKd,MAAQA,GAAOc,EAAKb,OAASA,EAAOa,EAAO,CAAEd,MAAKC,OAAMC,OAAO,KAC1G,CAACV,EAAUE,IA4Cd,OA1CA/rB,EAAM+X,gBAAgB,KAClB,IAAKiN,EAED,YADAoH,EAAae,GAAUA,EAAKZ,MAAQ,IAAKY,EAAMZ,OAAO,GAAUY,GAGpEX,IACAtmB,OAAOkgB,iBAAiB,SAAUoG,GAClCtmB,OAAOkgB,iBAAiB,SAAUoG,GAAQ,GAC1C,IAAIY,EAAkC,KAKtC,MAJ8B,oBAAnBC,gBAAkCttB,EAAIiZ,UAC7CoU,EAAW,IAAIC,eAAe,IAAMb,KACpCY,EAASE,QAAQvtB,EAAIiZ,UAElB,KACH9S,OAAOqnB,oBAAoB,SAAUf,GACrCtmB,OAAOqnB,oBAAoB,SAAUf,GAAQ,GAC7CY,GAAUI,eAEf,CAACxI,EAAMwH,IAEVxsB,EAAMgY,UAAU,KACZ,IAAKgN,EAAM,OACX,MAAMyI,EAAqBC,IACvB,MAAMhL,EAASgL,EAAMhL,OAChBA,IACD3iB,EAAIiZ,SAAS2U,SAASjL,IACtBmJ,GAAU8B,SAASjL,IACvB2gC,EAAU,cAERv1B,EAAiBJ,IACD,WAAdA,EAAMrnB,KAAkBg9C,EAAU,WAK1C,OAHA7sC,SAAS4P,iBAAiB,YAAaqH,GAAmB,GAC1DjX,SAAS4P,iBAAiB,aAAcqH,GAAmB,GAC3DjX,SAAS4P,iBAAiB,UAAW0H,GAC9B,KACHtX,SAAS+W,oBAAoB,YAAaE,GAAmB,GAC7DjX,SAAS+W,oBAAoB,aAAcE,GAAmB,GAC9DjX,SAAS+W,oBAAoB,UAAWO,KAE7C,CAAC9I,EAAMq+B,EAAWx3B,IAEhB7G,GAA4B,oBAAbxO,SAEb0X,eACHluB,EAAAC,cAAA,MAAA,CACIF,IAAKA,EACL4rB,KAAK,sBACM,QAAO,kBACD23B,EACjBn1B,UAAU,EACV5I,UAAW9f,GAAG,kBAAmB8f,GAAU,iBAC3ByG,EAChB7rB,MAAO,CAAEksB,IAAKF,EAASE,IAAKC,KAAMH,EAASG,KAAM8B,WAAYjC,EAASI,MAAQ,UAAY,YAAapsB,GACvGouB,YAAcb,GAAUA,EAAMO,mBAE7B3qB,GAELkT,SAASY,MAhBwC,IAkBzD,CAgCA,MAAMmsC,GAAYvjD,EAAMN,WAA2C,UAC/DqH,GACIA,EAAE8B,MACFA,EAAK7D,MACLA,EAAKysB,YACLA,EAAWngB,KACXA,EAAIkyC,UACJA,EAASC,MACTA,EAAKz0B,SACLA,EAAQ4vB,SACRA,EAAQ8E,SACRA,EAAQ1hC,MACRA,EAAK2hC,QACLA,EAAOC,UACPA,EAAS9vC,KACTA,EAAImY,UACJA,EAASgG,SACTA,EAAQ4xB,UACRA,EAASC,UACTA,EAAS1qC,SACTA,EAAQ2pC,QACRA,EAAOpwB,OACPA,EAAMtE,QACNA,EAAOG,UACPA,GAEJzuB,GAEA,MAAMgkD,EAAoB,MAATl7C,GAA2B,KAAVA,EAC5Bm7C,EAASL,GAAqB,KAAV3+C,IAAiB++C,EAC3C,OACI/jD,EAAAC,cAAA,MAAA,CACIF,IAAKA,EACLwlB,UAAW9f,GACP,gBACA,kBAAkB6L,IAClBkyC,GAAa,4BACbC,GAAS,uBACTO,GAAU,wBACVL,GAAW,yBACX30B,GAAY,0BACZhN,GAAS,uBACT4hC,GAAa,4BACZG,GAAY,4BACXF,GAAa,0BAEnBx1B,QAASA,GAER01B,GACG/jD,EAAAC,cAAA,QAAA,CAAOslB,UAAU,gBAAgB8F,QAAStkB,GACrC8B,EACA66C,GACG1jD,EAAAC,cAAA,OAAA,CAAMslB,UAAU,yBAAwB,cAAa,QAAM,MAMvEvlB,EAAAC,cAAA,QAAA,CACI8G,GAAIA,EACJhH,IAAKkyB,EACLne,KAAMA,EACNyR,UAAU,gBACVpe,KAAK,OACL88C,UAAU,UACVC,aAAa,MACbC,YAAY,EACZn/C,MAAOA,EACPysB,YAAauyB,EAASvyB,OAAcroB,EACpC4lB,SAAUA,EACV4vB,SAAUA,EACV8E,SAAUA,EACVz3B,UAAWA,eACC63B,EAAS,eACP9hC,QAAS5Y,EACvBgQ,SAAWsU,GAAUtU,EAASsU,EAAMhL,OAAO1d,OAC3C+9C,QAASA,EACTpwB,OAAQA,EACRnE,UAAWA,IAEdq1B,GAAa7jD,EAAAC,cAAA,MAAA,CAAKslB,UAAU,qBAAqBs+B,GAClD7jD,EAAAC,cAAA,WAAA,CAAA,cAAsB,OAAOslB,UAAU,mBACnCvlB,EAAAC,cAAA,SAAA,KACID,EAAAC,cAAA,OAAA,KACK8jD,EAAWl7C,EAAQ,GACnBk7C,GAAYL,EAAW,KAAO,MAMvD,GAaaU,GAAqBpkD,EAAMN,WAAoD,UAEpFsF,MAAOs5C,EAASnlC,aAChBA,EAAYC,SACZA,EAAQirC,SACRA,EAAQC,QACRA,EACAt/B,KAAMu/B,EAAQC,OACdA,EAAM14B,QACNA,EACAyyB,cAAeC,EAAiBC,sBAChCA,EAAqB51C,MACrBA,EAAKT,OACLA,EA9Pe,aA8PQq8C,aACvBA,EAAe,SAAQnzC,KACvBA,EAAO,QAAOkyC,UACdA,GAAY,EAAKkB,UACjBA,GAAY,EAAKC,YACjBA,EAAWC,kBACXA,GAAoB,EAAKC,cACzBA,EAAaC,UACbA,EAASlqB,QACTA,EAAU,GAAE6B,YACZA,GAAc,EACdnN,WAAYwN,EAAc4hB,UAC1BA,EAAY,EAACC,cACbA,EAAapB,QACbA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiBzuB,SACjBA,GAAW,EAAK4vB,SAChBA,GAAW,EAAKC,4BAChBA,EAA2BC,gBAC3BA,EAAeC,mBACfA,EAAkBC,sBAClBA,EAAqBC,iBACrBA,EAAgBC,cAChBA,EAAaprC,KACbA,EACA/M,GAAIg+C,EACJtzB,YAAauzB,EAAetB,SAC5BA,EACA1hC,MAAOijC,EAASC,WAChBA,EAAUj5B,UACVA,EAASgG,SACTA,EAAQjG,UACRA,EAASwQ,UACTA,EAASjX,UACTA,EAASplB,MACTA,EAAKglD,iBACLA,EAAgBC,aAChBA,EAAYr5B,UACZA,GAAY,gBAEhBhsB,IAEA+7C,KAEA,MAAMxsB,GAAatvB,EAAMk1B,QACrB,KAAA,IAAY8tB,MAA8ClmB,IAC1D,CAACA,IAECuoB,GAAkB/1B,GAAW+1B,iBAAmBj9C,EAChDk9C,GAA2B,UAAjBb,EACVc,GAAsBZ,GAAeW,GACrCE,GAAwBX,IAAkBjqB,EAAQ6qB,SAAS,UAE3DC,GAAU1lD,EAAMihC,QAChB0kB,GAASZ,GAAU,WAAWW,GAAQp2C,QAAQ,KAAM,MACpDs2C,GAAUN,GAAU,GAAGK,WAAiBA,GACxCE,GAAQ,GAAGF,SACXG,GAAgB,GAAGH,WAGnBtsC,QAA6BjQ,IAAdk1C,GACda,GAAeC,IAAoBp/C,EAAMwZ,SAAuB,IACnEujC,GAAe5jC,GAAgB+iC,KAE7Bl3C,GAAQhF,EAAMk1B,QAChB,IAAO7b,GAAe0jC,GAAeuB,GAAaa,GAClD,CAAC9lC,GAAcilC,EAAWa,MAEvB7O,GAAOC,IAAOvrC,GAEfw6C,GAAax/C,EAAMk1B,QACrB,KAAA,CAASqoB,UAASC,UAASH,cAAaC,gBAAeG,sBACvD,CAACF,EAASC,EAASH,EAAaC,EAAeG,IAE7CsI,GAAkB/lD,EAAMk1B,QAAQ,IAAMwoB,GAAc14C,GAAOw6C,IAAa,CAACx6C,GAAOw6C,KAChF13C,GAAU9H,EAAM4Z,YACjBosC,GAAwBtI,GAAcsI,EAAOxG,IAAYvuC,MAAOkxB,GAAW,MAALA,GACvE,CAACqd,KAGCyG,GAAejmD,EAAM+Y,OAA0E,MACrG/Y,EAAMgY,UAAU,KACZ,MAAMmV,EAAO84B,GAAajtC,QACtBmU,GAAQA,EAAK,KAAO44B,GAAgB,IAAM54B,EAAK,KAAO44B,GAAgB,MAC7D,OAAT54B,GAAiB44B,GAAgB,IAAMA,GAAgB,KAAIzB,IAAUyB,GAAiB/gD,IAC1FihD,GAAajtC,QAAU+sC,KACxB,CAACA,GAAiB/gD,GAAOs/C,IAE5B,MAAM4B,GAAWlmD,EAAM4Z,YACnB,CAACC,EAAoBssC,KACZ9sC,IAAc+lC,GAAiBvlC,GACpC,MAAMusC,EAAqC,CAAEL,gBAAiBrI,GAAc7jC,EAAM2lC,KAC9E2G,IAAUC,EAAQD,SAAWA,GACjC/sC,IAAWS,EAAMusC,IAErB,CAAC/sC,GAAcD,EAAUomC,MAItBH,GAAkBC,IAAuBt/C,EAAMwZ,SAA+B,SAC/E+kC,GAAgBC,GAAqBa,GACrCE,GAAmBv/C,EAAM4Z,YAC1BuS,SAC6B/iB,IAAtBo1C,GAAiCc,GAAoBnzB,GACzDsyB,IAAwBtyB,IAE5B,CAACqyB,EAAmBC,IAIlB4H,QAAgCj9C,IAAbm7C,GAClB+B,GAAcC,IAAmBvmD,EAAMwZ,UAAS,GACjDwL,GAAOqhC,KAAqB9B,EAAW+B,GACvCE,GAAiBxmD,EAAM+Y,OAAqB/T,IAC5CyhD,GAAkBzmD,EAAM+Y,OAAqB/T,IAG7Cm+C,GAASnjD,EAAM4Z,YACjB,CAACC,EAAoB6sC,GAAQ,MACpBA,GAAS9J,GAAa/iC,EAAM4sC,GAAgBztC,WACjDytC,GAAgBztC,QAAUa,EAC1BwqC,IAAWxqC,KAEf,CAACwqC,IAECljB,GAAUnhC,EAAM+Y,OAA8B,MAC9C4tC,GAAY3mD,EAAM+Y,OAAiC,MACnD6tC,GAAkB5mD,EAAM+Y,OAA2B,OAIlD8tC,GAAgBC,IAAqB9mD,EAAMwZ,cAAuCpQ,GACzFpJ,EAAMgY,UAAU,KACZ,QAAkB5O,IAAd4iB,EAAyB,OAC7B,MAAM+6B,EAAO5lB,GAAQnoB,SAASguC,eAAen5B,QAAQ,qBAAqBo5B,aAAa,kBACvFH,GAA2B,SAATC,EAAkB,OAAkB,UAATA,EAAmB,aAAU39C,KAE9E,MAAM89C,GAAqBl7B,GAAa66B,GAElCM,GAAannD,EAAM4Z,YACpB6N,IACG0Z,GAAQnoB,QAAUyO,EACC,mBAAR1nB,GAAoBA,GAAI0nB,GAC1B1nB,KAAMA,GAAsDiZ,QAAUyO,IAEnF,CAAC1nB,KAGCmjD,GAAaljD,EAAM4Z,YACpBuS,IACO6C,GAAY4vB,GAAY55B,KAC5BwhC,GAAextC,QAAUhU,GACzB4hD,GAAgB5tC,QAAWxC,SAASqY,eAAwC,KAC5E0wB,GAAiBpzB,IAAamkB,KAAUC,GAAM,MAAQ,UACjD8V,IAAkBE,IAAgB,GACvC/B,QAEJ,CAACx1B,EAAU4vB,EAAU55B,GAAMhgB,GAAOsrC,GAAOC,GAAKgP,GAAkB8G,GAAkB7B,IAGhF4C,GAAcpnD,EAAM4Z,YAAY,KAClC,IAAKoL,GAAM,OACNqhC,IAAkBE,IAAgB,GACvCz6B,MACA,MAAMpJ,EAASikC,GAAU3tC,SAAW4tC,GAAgB5tC,QACpD9S,OAAOqR,WAAW,IAAMmL,GAAQ8D,UAAW,IAC5C,CAACxB,GAAMqhC,GAAkBv6B,IAEtBu7B,GAAiBrnD,EAAM4Z,YACxBC,IACGspC,GAAOtpC,GAAM,GACbutC,MAEJ,CAACjE,GAAQiE,KAGPE,GAAgBtnD,EAAM4Z,YAAY,KAEpCupC,GAAOn+C,IACPoiD,MACD,CAACpiD,GAAOm+C,GAAQiE,KAEbG,GAAuBvnD,EAAM4Z,YAC/B,CAACC,EAAoB2tC,EAAmBr7B,KACpC+5B,GAASrsC,GACQ,QAAbsS,GAAsBtS,EAAK,IAAMA,EAAK,IAAM2rC,IAAuB6B,GAAextC,IAE1F,CAACqsC,GAAUV,GAAuB6B,MAsC/BI,GAAcC,IAAmB1nD,EAAMwZ,SAAuB,MAC/DmuC,GAAe3nD,EAAM4Z,YACtBosC,IACG,MAAOj6C,EAAGo2B,GAAK6jB,EACf,OAAKj6C,GAAMo2B,EACJ,GAAGp2B,EAAI9D,GAAW8D,EAAG3D,GAAUi9C,MAAmB/1B,GAAW2zB,kBAAkB9gB,EAAIl6B,GAAWk6B,EAAG/5B,GAAUi9C,KAD7F,IAGzB,CAACj9C,EAAQi9C,GAAiB/1B,GAAW2zB,kBAGlC2E,GAAYC,IAAiB7nD,EAAMwZ,SAAS,IAAMmuC,GAAa3iD,MAC/D8iD,GAAWC,IAAgB/nD,EAAMwZ,SAAS,IAAMvR,GAAWqoC,GAAOloC,KAClE4/C,GAASC,IAAcjoD,EAAMwZ,SAAS,IAAMvR,GAAWsoC,GAAKnoC,KAC5D8/C,GAAcC,IAAmBnoD,EAAMwZ,SAA4D,CACtGqxB,QAAQ,EACRyF,OAAO,EACPC,KAAK,IAITvwC,EAAMgY,UAAU,KACS,WAAjByvC,KACAI,GAAcF,GAAa3iD,KAC3BmjD,GAAiBh7B,GAAUA,EAAK0d,OAAS,IAAK1d,EAAM0d,QAAQ,GAAU1d,IAErD,UAAjBs6B,KACAM,GAAa9/C,GAAWqoC,GAAOloC,IAC/B+/C,GAAiBh7B,GAAUA,EAAKmjB,MAAQ,IAAKnjB,EAAMmjB,OAAO,GAAUnjB,IAEnD,QAAjBs6B,KACAQ,GAAWhgD,GAAWsoC,GAAKnoC,IAC3B+/C,GAAiBh7B,GAAUA,EAAKojB,IAAM,IAAKpjB,EAAMojB,KAAK,GAAUpjB,KAErE,CAACnoB,GAAOsrC,GAAOC,GAAKkX,GAAcr/C,EAAQu/C,KAE7C,MAAMS,GAAgB5mD,IAClB,MAAMy7C,EAAUz7C,EAAK6O,OACrB,IAAK4sC,GAAWA,EAAQmB,gBAAkBiH,GAAgBjH,cAAe,MAAO,CAAEj2C,KAAM,KAAMkgD,SAAS,GACvG,MAAMrgD,EAASg1C,GAAcC,EAAS70C,GACtC,MAAO,CAAED,KAAMH,EAAQqgD,QAAmB,MAAVrgD,IAe9BsgD,GAAmBA,CAAC1kB,EAAuBpiC,KAChC,UAAToiC,EAAkBmkB,GAAavmD,GAC9BymD,GAAWzmD,GAChB,MAAMwG,EAASogD,GAAa5mD,GAE5B,GADA2mD,GAAiBh7B,IAAI,IAAWA,EAAMyW,CAACA,GAAO57B,EAAOqgD,WACjDrgD,EAAOqgD,QAAS,OACpB,MAAMxuC,EAA8B,UAAT+pB,EAAmB,CAAC57B,EAAOG,KAAMooC,IAAO,CAACD,GAAOtoC,EAAOG,MAC7Ey0C,GAAa/iC,EAAM7U,KAAQkhD,GAASrsC,IAGvC0uC,GAActhD,IAChBygD,GAAiBv6B,GAAUA,IAASlmB,EAAQ,KAAOkmB,GAErC,WAAVlmB,GAAuBihD,GAAard,QAAQgd,GAAcF,GAAa3iD,KAC7D,UAAViC,GAAsBihD,GAAa5X,OAAOyX,GAAa9/C,GAAWqoC,GAAOloC,IAC/D,QAAVnB,GAAoBihD,GAAa3X,KAAK0X,GAAWhgD,GAAWsoC,GAAKnoC,IAEhE4c,IAAMm+B,GAAOn+C,KAGhBwjD,GAAqBA,CAAC96B,EAA8CvB,KACpD,cAAduB,EAAMrnB,KAAwBqnB,EAAM+6B,OAGf,UAAd/6B,EAAMrnB,MACbqnB,EAAMiB,iBACD3J,IAAMm+B,GAAOn+C,MAJlB0oB,EAAMiB,iBACNu0B,GAAW/2B,KAcb3gB,KAAa8kC,MAAWC,GACxBmY,GAAqB3C,GAAgBn4B,KAAMuU,GAAW,MAALA,GACjDwmB,KAAc1D,GAAayD,IAAsBR,GAAard,QAAUqd,GAAa5X,OAAS4X,GAAa3X,IAE3GqY,IAAchE,GAChB5kD,EAAAC,cAAA,SAAA,CACIF,IAAK4mD,GACLx/C,KAAK,SACLoe,UAAW9f,GAAG,gCAA0C,UAAT6L,GAAoB,sBAAqB,aAC5Ege,GAAW4zB,WACvBxnC,MAAO4T,GAAW4zB,WAAU,gBACd,yBACCl+B,GACfgK,SAAUA,EACVX,QAAUX,IACNA,EAAMO,kBACFjJ,GAAMsiC,KACLpE,OAGTljD,EAAAC,cAAC87C,GAAa,CAACzqC,KAAe,UAATA,EAAmB,GAAK,MAI/Cu3C,GAAcnE,GAAal5C,KAAawjB,IAAa4vB,GACvD5+C,EAAAC,cAAA,SAAA,CACIkH,KAAK,SACLoe,UAAW9f,GAAG,gCAA0C,UAAT6L,GAAoB,mCACvDge,GAAWiD,MACvB7W,MAAO4T,GAAWiD,MAClBlE,QArCOX,IACXA,EAAMO,kBACNi4B,GAAShK,IACTqD,GAAiB,SACjB4D,GAAOjH,MAmCHl8C,EAAAC,cAACkpB,GAAS,CAAC7X,KAAe,UAATA,EAAmB,GAAK,MAI3Cw3C,GAAa9oD,EAAMk1B,QACrB,KAAA,IAAasH,KAAkDr8B,IAC/D,CAACq8B,EAAWr8B,IAEV4oD,GAAoB/oD,EAAMk1B,QAC5B,KAAA,IAAasH,KAAkD4oB,IAC/D,CAAC5oB,EAAW4oB,IAIV4D,GAAgBhpD,EAAMk1B,QACxB,KACK4vB,GAAa,IAAI34C,IAAI,CAACg6C,EAAUjnC,KAC7B,IAAI+pC,EAA8B/M,GAClC,IACI+M,EAAgBlM,GAAeoJ,EAASpI,SAAS,CAAEj2C,aACvD,CAAE,MACE,CAEJ,MAAO,CAAEq+C,WAAU9/C,IAAK8/C,EAASp/C,IAAM,GAAGo/C,EAASt9C,SAASqW,IAASla,MAAOikD,KAEpF,CAACnE,EAAWh9C,KA4CVohD,GACFlpD,gBAACq+C,GAAoB,CACjBr5C,MAAOA,GACPoU,SAAUmuC,GACVhJ,cAAeA,GACfE,sBAAuBc,GACvBb,UAAWA,EACXC,cAAeA,EACfpB,QAASA,EACTC,QAASA,EACTH,YAAaA,EACbC,cAAeA,EACfG,kBAAmBA,EACnBoB,4BAA6BA,EAC7BC,gBAAiBA,EACjBC,mBAAoBA,EACpBC,sBAAuBA,EACvBC,iBAAkBA,EAClBC,cAAeA,EACf5vB,WAAYA,GACZtD,UAAWk7B,GACXj7B,WAAS,IAKXk9B,GAAmB,CACrB73C,OACAkyC,YACAx0B,WACA4vB,WACA8E,WACA1hC,MAAO2mC,IAGX,OACI3oD,EAAAC,cAAA,MAAA,CACIF,IAAKonD,GACL5hC,UAAW9f,GAAG,UAAW+9C,GAAa,sBAAuB8B,IAAW,iBAAkB//B,GAAU,iBACpF2hC,GAChB/mD,MAAO2oD,IAENxD,GACGtlD,EAAAC,cAAA,MAAA,CAAKslB,UAAU,kBACXvlB,EAAAC,cAACsjD,GAAS,IACF4F,GACJ1F,OAAK,EACL18C,GAAI6+C,GACJ9xC,KAAMA,EAAO,GAAGA,eAAe1K,EAC/BP,MAAOymB,GAAWghB,MAClBtrC,MAAO8iD,GACPr2B,YAAauzB,GAAmBK,GAChC1B,QAA0B,UAAjB8D,GACT7D,UAAW2B,GACXt5B,UAAWA,EACXgG,SAAUA,EACV7Y,SAAW5X,GAAS8mD,GAAiB,QAAS9mD,GAC9CuhD,QAASA,KACL2E,GAAgB,SAChBnI,GAAiB,UAErB5sB,OAAQA,IAAM41B,GAAW,SACzBl6B,QAASA,IAAMk3B,IAAuBrC,GAAW,SACjD10B,UAAYd,GAAU86B,GAAmB96B,EAAO,WAEpD1tB,EAAAC,cAAA,OAAA,CAAMslB,UAAU,2BAA0B,cAAa,QAClD+J,GAAW2zB,gBAEhBjjD,EAAAC,cAACsjD,OACO4F,GACJ1F,OAAK,EACL18C,GAAI8+C,GACJ/xC,KAAMA,EAAO,GAAGA,aAAa1K,EAC7BP,MAAOymB,GAAWihB,IAClBvrC,MAAOgjD,GACPv2B,YAAauzB,GAAmBK,GAChC1B,QAA0B,QAAjB8D,GACT7D,UAAW2B,GACX1B,UACI7jD,EAAAC,cAAAD,EAAA4qB,SAAA,KACKi+B,GACAD,IAGTxvC,SAAW5X,GAAS8mD,GAAiB,MAAO9mD,GAC5CuhD,QAASA,KACL2E,GAAgB,OAChBnI,GAAiB,QAErB5sB,OAAQA,IAAM41B,GAAW,OACzBl6B,QAASA,IAAMk3B,IAAuBrC,GAAW,OACjD10B,UAAYd,GAAU86B,GAAmB96B,EAAO,UAIxD1tB,EAAAC,cAACsjD,GAAS,IACF4F,GACJpiD,GAAI6+C,GACJ9xC,KAAMA,EACNjL,MAAOA,EACP7D,MAAO4iD,GACPn2B,YAAauzB,GAAmB,GAAGK,MAAmB/1B,GAAW2zB,kBAAkBoC,KACnF1B,QAA0B,WAAjB8D,GACT7D,UAAW2B,GACXt5B,UAAWA,EACXgG,SAAUA,EACV6xB,UAAoB,MAATj7C,EAAgBymB,GAAW8zB,kBAAeh6C,EACrDy6C,UACI7jD,EAAAC,cAAAD,EAAA4qB,SAAA,KACKi+B,GACAD,IAGTxvC,SAvQY5X,IACxBqmD,GAAcrmD,GACd,MAAOuK,EAAGo2B,GFjfa3gC,KAC3B,MAAM4nD,EAAQ5nD,EAAK2O,MAAM,yCACzB,OAAIi5C,EAAMhkD,QAAU,EAAU,CAACgkD,EAAM,GAAIA,EAAMj4C,MAAM,GAAGtL,KAAK,MACtD,CAACrE,EAAM,KE8eK6nD,CAAe7nD,GACxB8nD,EAAKlB,GAAar8C,GAClBw9C,EAAKnB,GAAajmB,GAClBkmB,EAAUiB,EAAGjB,SAAWkB,EAAGlB,QAEjC,GADAF,GAAiBh7B,IAAI,IAAWA,EAAM0d,OAAQwd,KAC1CA,EAAS,OACb,MAAMxuC,EAAqB,CAACyvC,EAAGnhD,KAAMohD,EAAGphD,MACnCy0C,GAAa/iC,EAAM7U,KAAQkhD,GAASrsC,IA+P7BkpC,QAASA,IAAM2E,GAAgB,UAC/B/0B,OAAQA,IAAM41B,GAAW,UACzBl6B,QAASA,IAAMk3B,IAAuBrC,KACtC10B,UAAYd,GAAU86B,GAAmB96B,EAAO,WAGzC,MAAdw3B,GAAqC,KAAfA,GACnBllD,EAAAC,cAAA,MAAA,CAAKslB,UAAW9f,GAAG,iBAAkBkjD,IAAa,0BAA2BzD,GAGjFllD,EAAAC,cAAC2rB,GAAO,CACJ5G,KAAMA,GACN6G,SAAUsV,GAAQnoB,QAClB+S,UAAWA,GACXs3B,UAAWiE,GACXt7B,UAAWk7B,GACX3hC,UAAW4/B,EACXhlD,MAAO4oD,GACPzF,WAAY7mB,EAAcqpB,QAAgB18C,GAE1CpJ,EAAAC,cAAA,MAAA,CAAKslB,UAAW9f,GAAG,iBAAkBg3B,GAAe,iCAC/CA,GA/Kbz8B,EAAAC,cAAA,MAAA,CAAKslB,UAAU,mBACXvlB,EAAAC,cAAA,IAAA,CAAGslB,UAAU,wBAAwBxe,GAAI++C,IACpCx2B,GAAW8zB,cAEhBpjD,EAAAC,cAAA,MAAA,CAAKslB,UAAU,yBACXvlB,EAAAC,cAAA,SAAA,CACIkH,KAAK,SACLoe,UAAW9f,GAAqB,UAAlB84C,IAA6B,iCAC3ClwB,QAASA,IAAMkxB,GAAiB,UAE/BjP,GAAQroC,GAAWqoC,GAAOloC,GAAUknB,GAAWghB,OAEpDtwC,EAAAC,cAAA,OAAA,KAAOqvB,GAAW2zB,gBAClBjjD,EAAAC,cAAA,SAAA,CACIkH,KAAK,SACLoe,UAAW9f,GAAqB,QAAlB84C,IAA2B,iCACzClwB,QAASA,IAAMkxB,GAAiB,QAE/BhP,GAAMtoC,GAAWsoC,GAAKnoC,GAAUknB,GAAWihB,OA8J5CvwC,EAAAC,cAAA,MAAA,CAAKslB,UAAU,uBACVyjC,GAAc5jD,OAAS,GACpBpF,EAAAC,cAAA,KAAA,CAAIslB,UAAU,oBAAmB,aAAY,aACxCyjC,GAAc78C,IAAI,EAAGg6C,WAAU9/C,MAAKrB,MAAOikD,KACxCjpD,EAAAC,cAAA,KAAA,CAAIoG,IAAKA,GACLrG,EAAAC,cAAA,SAAA,CACIkH,KAAK,SACLoe,UAAW9f,GACP,mBACA+F,IACIoxC,GAAaqM,EAAejkD,KAC5B,8BAERgqB,SAAUA,GAAY4vB,EACtBvwB,QAASA,IAzXzB83B,KACpB,MAAMtsC,EAAOkjC,GAAeoJ,EAASpI,SAAS,CAAEj2C,cAChDo+C,GAASrsC,EAAMssC,GACf5G,GAAiB,SACjB8H,GAAextC,IAqXoC2vC,CAAerD,IAE7BA,EAASt9C,UAM7BqgD,IA7KjBtuB,EAAQx1B,OAAS,GACbpF,EAAAC,cAAA,MAAA,CAAKslB,UAAU,mBACVqV,EAAQzuB,IAAK6uB,GACVh7B,EAAAC,cAAA,SAAA,CACIoG,IAAK20B,EACL7zB,KAAK,SACLoe,UAAW9f,GAAG,eAA2B,WAAXu1B,GAAkC,UAAXA,IAAuB,wBAC5E3M,QAASA,IApNP2M,KAClB,OAAQA,GACJ,IAAK,QACDkrB,GAAShK,IACTqD,GAAiB,SACjB8H,GAAenL,IACf,MAEJ,IAAK,QAAS,CACV,MAAM8B,EAAQp2C,IAAQU,QAAQ,OACxBuR,EAAqB,CAACmkC,EAAOA,GACnCkI,GAASrsC,GACT0lC,GAAiB,SACbiG,IAAuB6B,GAAextC,GAC1C,KACJ,CACA,IAAK,SACI+iC,GAAa53C,GAAOwhD,GAAextC,UAAUktC,GAASM,GAAextC,SAC1EouC,KACA,MAGJ,QACIC,GAAeriD,MA6LQykD,CAAazuB,IAE3B1L,GAAW0L,QA2KpC,GAEAopB,GAAmB3rC,YAAc,2CCv2BnB,UAAwBiD,MAAEA,EAAK+5B,QAAEA,EAAOza,OAAEA,EAAMhW,KAAEA,EAAI8G,QAAEA,KAAYhsB,IAChF,OACEE,EAAAC,cAACypD,GAAOlG,WAAS,EAAC/0C,SAAS,KAAKuW,KAAMA,EAAM8G,QAASA,KAAahsB,GAChEE,EAAAC,cAAC0pD,EAAW,CAAC9pD,GAAI,CAAE+pD,GAAI,IAAMluC,GAE5B+5B,GAAWz1C,EAAAC,cAAC4pD,EAAa,CAAChqD,GAAI,CAAE+C,WAAY,cAAa6yC,EAAyB,KAEnFz1C,EAAAC,cAAC6pD,EAAa,KACZ9pD,EAAAC,cAAC6qB,EAAM,CAACuD,QAASvC,GAAO,UACvBkP,GAIT,kCCbc,UAAkC1K,WAC5CA,EAAa,CAAEzV,YAAY,GAAM0V,aACjCA,EAAe,CAAE1V,YAAY,GAAM2V,aACnCA,EAAYI,eAEZA,KACG9wB,IAEH,OACIE,EAAAC,cAAC8pD,6BAA0B,IACnBjqD,GAGH8wB,EACD5wB,EAAAC,cAAC+pD,wBAAqB,CAAC9vC,QAASoW,IAChCtwB,EAAAC,cAACgqD,0BAAuB,CAAC/vC,QAASqW,IAClCvwB,EAAAC,cAACiqD,2BAAwBhwC,QAASsW,IAG9C,8BCTc,UAA8BhvB,KAAEA,EAAI2oD,mBAAEA,IAChD,MAAM1pD,EAAQC,EAAAA,WACRsrB,EAAYm+B,OAAwBn+B,WAAavrB,EAAMG,QAAQC,MAAQ,QAEvEupD,EAAoB9pD,EAAO,MAAPA,CAAc,KAAA,CACpCgC,QAAS,OACTF,WAAY,SACZG,eAAgB,SAChBnC,OAAQ,OACR,qBAAsB,CAClB0oB,KAAoB,UAAdkD,EAAwB,UAAY,WAE9C,qBAAsB,CAClBlD,KAAoB,UAAdkD,EAAwB,UAAY,WAE9C,qBAAsB,CAClBlD,KAAoB,UAAdkD,EAAwB,UAAY,WAE9C,qBAAsB,CAClBlD,KAAoB,UAAdkD,EAAwB,OAAS,WAE3C,qBAAsB,CAClBq+B,YAA2B,UAAdr+B,EAAwB,MAAQ,OAC7ClD,KAAoB,UAAdkD,EAAwB,UAAY,WAGlD,OACIhsB,gBAACoqD,EAAiB,KACdpqD,EAAAC,cAACM,MAAG,CACA+pD,UAAU,MACV/vB,IAAI,gBACJtX,IAAI,qCACJpjB,GAAI,CAAED,MAAO,GAAI6O,SAAU,OAE/BzO,EAAAC,cAACM,MAAG,CAACV,GAAI,CAAE0qD,GAAI,IAAM/oD,GAGjC,0BC/Cc,UAA0BwjB,KACtCA,EAAIxjB,KACJA,EACExB,EAAAC,cAAAD,EAAA4qB,SAAA,4GACsG5qB,EAAAC,cAAA,KAAA,MACpGD,EAAAC,cAAA,KAAA,MAEC,2DAGL,OACED,EAAAC,cAACypD,SAAM,CAAC1kC,KAAMA,EAAMw+B,WAAS,EAAC3jD,GAAI,CAAE2qD,EAAG,IACrCxqD,EAAAC,cAAC4pD,gBAAa,CAAChqD,GAAI,CAAE2qD,EAAG,EAAGC,UAAW,WACpCzqD,EAAAC,cAACyqD,aAAU,CAAC3pD,QAAQ,YAAYlB,GAAI,CAAE0qD,GAAI,IACvC/oD,GAEHxB,EAAAC,cAAC0qD,EAAAA,iBAAgB,OAIzB,u/DrBqbsCC,CAAC1hD,EAAiBgR,EAAqC,MACzF,GAAwB,oBAAb1D,SAA0B,OACrC,MAAMsF,EAAiB5B,EAAQ4B,iBAAkB,EAC3CC,EAAQ9B,GAAiB/Q,EAAKgR,GAC9BwB,EAAQxB,EAAQwB,OAASxB,EAAQrD,UAAYL,SAASkF,OAAS,GAE/DmvC,EAAa/uC,EACb,cAAcC,EAAMZ,QACfhP,IAAI,CAAC8P,EAAGgB,IAAM,cAAclB,EAAM5B,QAAQ8C,GAAGrP,OAAS,WAAW8T,GAAWzF,WAC5EpW,KAAK,mBACV,GACAilD,EAAW,UAAU/uC,EAAMd,KAC5B9O,IACI+P,GACG,OAAOA,EACF/P,IAAKG,GAAS,cAAcA,EAAK3D,IAAIiF,OAAS,WAAW8T,GAAWpV,EAAKzC,mBACzEhE,KAAK,YAEjBA,KAAK,cAEJklD,EAEF,6DAAUrpC,GAAWhG,2eASpBxB,EAAQmL,WAAa,IACtB,yBACC3J,EAAQ,OAAOgG,GAAWhG,UAAgB,IAC3C,UAAUmvC,IAAaC,0BAGrBrmC,EAASjO,SAASvW,cAAc,UACtCwkB,EAAOrM,aAAa,cAAe,QACnCqM,EAAOtkB,MAAMgsB,SAAW,QACxB1H,EAAOtkB,MAAM8sB,MAAQ,IACrBxI,EAAOtkB,MAAM+sB,OAAS,IACtBzI,EAAOtkB,MAAMP,MAAQ,IACrB6kB,EAAOtkB,MAAMC,OAAS,IACtBqkB,EAAOtkB,MAAMuB,OAAS,IACtB+iB,EAAOtkB,MAAM0qB,QAAU,IACvBrU,SAASY,KAAKC,YAAYoN,GAE1B,MAAMumC,EAAUA,KACZ9kD,OAAOqR,WAAW,KACVkN,EAAOG,YAAYH,EAAOG,WAAWpN,YAAYiN,IACtD,MAGPA,EAAOwmC,OAAS,KACZ,MAAMpmC,EAAMJ,EAAOK,cACnB,GAAKD,EAIL,IACIA,EAAI2B,QACJ3B,EAAI0B,aAAeykC,EACnBnmC,EAAI4B,OACR,CAAE,MACEukC,GACJ,MATIA,KAYR,MAAM9mC,EAAMO,EAAOM,iBAAmBN,EAAOK,eAAetO,SACxD0N,GACAA,EAAIc,OACJd,EAAIe,MAAM8lC,GACV7mC,EAAIgB,SAEJT,EAAOymC,OAASH,6JFveYI,IAA4CzyC,KAAoBxP,6BAKpEkiD,IAC5BprD,EAAM+Y,OAA6B,gEAJHsyC,IAAM3yC,KAAoB4W,sEwB/ChCg8B,EAAchb,EAAeC,GACvD,MAAM9vC,EAAQC,EAAAA,WAER6qD,EAAUC,EAAc/qD,EAAMgrD,YAAYC,GAAGpb,IAE7Cqb,EAAYH,EAAc/qD,EAAMgrD,YAAYG,KAAKtb,IAEjDub,EAAeL,EAAc/qD,EAAMgrD,YAAYK,QAAQxb,EAAgBC,IAEvEwb,EAAYP,EAAc/qD,EAAMgrD,YAAYO,KAAK1b,IAEvD,MAAc,OAAVgb,EACOC,EAGG,SAAVD,EACOK,EAGG,YAAVL,EACOO,EAGJE,CACX"}