{"version":3,"file":"utils.cjs","sources":["../../../../src/components/Table/utils.ts"],"sourcesContent":["import { Property } from 'csstype';\nimport { clone, sampleSize } from 'lodash';\nimport memoize from 'micro-memoize';\nimport { HeaderGroup, Row } from 'react-table';\nimport tinycolor from 'tinycolor2';\n\nimport {\n  ActionModel,\n  DataFrame,\n  DisplayValue,\n  DisplayValueAlignmentFactors,\n  Field,\n  FieldConfigSource,\n  fieldReducers,\n  FieldType,\n  formattedValueToString,\n  getDisplayProcessor,\n  getFieldDisplayName,\n  GrafanaTheme2,\n  isDataFrame,\n  isDataFrameWithValue,\n  isTimeSeriesFrame,\n  LinkModel,\n  reduceField,\n  SelectableValue,\n} from '@grafana/data';\nimport {\n  BarGaugeDisplayMode,\n  TableAutoCellOptions,\n  TableCellBackgroundDisplayMode,\n  TableCellDisplayMode,\n} from '@grafana/schema';\n\nimport { getTextColorForAlphaBackground } from '../../utils/colors';\n\nimport { ActionsCell } from './ActionsCell';\nimport { BarGaugeCell } from './Cells/BarGaugeCell';\nimport { DataLinksCell } from './Cells/DataLinksCell';\nimport { DefaultCell } from './Cells/DefaultCell';\nimport { GeoCell } from './Cells/GeoCell';\nimport { ImageCell } from './Cells/ImageCell';\nimport { JSONViewCell } from './Cells/JSONViewCell';\nimport { SparklineCell } from './Cells/SparklineCell';\nimport { getFooterValue } from './TableRT/FooterRow';\nimport { RowExpander } from './TableRT/RowExpander';\nimport {\n  CellColors,\n  CellComponent,\n  FooterItem,\n  GrafanaTableColumn,\n  TableCellOptions,\n  TableFieldOptions,\n  TableFooterCalc,\n} from './types';\n\nexport const EXPANDER_WIDTH = 50;\n\nexport function getTextAlign(field?: Field): Property.JustifyContent {\n  if (!field) {\n    return 'flex-start';\n  }\n\n  if (field.config.custom) {\n    const custom: TableFieldOptions = field.config.custom;\n\n    switch (custom.align) {\n      case 'right':\n        return 'flex-end';\n      case 'left':\n        return 'flex-start';\n      case 'center':\n        return 'center';\n    }\n  }\n\n  if (field.type === FieldType.number) {\n    return 'flex-end';\n  }\n\n  return 'flex-start';\n}\n\nexport function getColumns(\n  data: DataFrame,\n  availableWidth: number,\n  columnMinWidth: number,\n  expander: boolean,\n  footerValues?: FooterItem[],\n  isCountRowsSet?: boolean\n): GrafanaTableColumn[] {\n  const columns: GrafanaTableColumn[] = [];\n  let fieldCountWithoutWidth = 0;\n\n  if (expander) {\n    columns.push({\n      // Make an expander cell\n      Header: () => null, // No header\n      id: 'expander', // It needs an ID\n      // @ts-expect-error\n      // TODO fix type error here\n      Cell: RowExpander,\n      width: EXPANDER_WIDTH,\n      minWidth: EXPANDER_WIDTH,\n      filter: (_rows: Row[], _id: string, _filterValues?: SelectableValue[]) => {\n        return [];\n      },\n      justifyContent: 'left',\n      field: data.fields[0],\n      sortType: 'basic',\n    });\n\n    availableWidth -= EXPANDER_WIDTH;\n  }\n\n  for (const [fieldIndex, field] of data.fields.entries()) {\n    const fieldTableOptions: TableFieldOptions = field.config.custom || {};\n    if (\n      // @ts-ignore this was the former hidden option; we support it for legacy use cases while TableRT is being sunset.\n      fieldTableOptions.hidden ||\n      fieldTableOptions.hideFrom?.viz ||\n      field.type === FieldType.nestedFrames\n    ) {\n      continue;\n    }\n\n    if (fieldTableOptions.width) {\n      availableWidth -= fieldTableOptions.width;\n    } else {\n      fieldCountWithoutWidth++;\n    }\n\n    const selectSortType = (type: FieldType) => {\n      switch (type) {\n        case FieldType.number:\n        case FieldType.frame:\n          return 'number';\n        case FieldType.time:\n          return 'basic';\n        default:\n          return 'alphanumeric-insensitive';\n      }\n    };\n\n    const Cell = getCellComponent(fieldTableOptions.cellOptions?.type, field);\n    columns.push({\n      // @ts-expect-error\n      // TODO fix type error here\n      Cell,\n      id: fieldIndex.toString(),\n      field: field,\n      Header: fieldTableOptions.hideHeader ? '' : getFieldDisplayName(field, data),\n      accessor: (_row, i) => field.values[i],\n      sortType: selectSortType(field.type),\n      width: fieldTableOptions.width,\n      minWidth: fieldTableOptions.minWidth ?? columnMinWidth,\n      filter: memoize(filterByValue(field)),\n      justifyContent: getTextAlign(field),\n      Footer: getFooterValue(fieldIndex, footerValues, isCountRowsSet),\n    });\n  }\n\n  // set columns that are at minimum width\n  let sharedWidth = availableWidth / fieldCountWithoutWidth;\n  for (let i = fieldCountWithoutWidth; i > 0; i--) {\n    for (const column of columns) {\n      if (!column.width && column.minWidth > sharedWidth) {\n        column.width = column.minWidth;\n        availableWidth -= column.width;\n        fieldCountWithoutWidth -= 1;\n        sharedWidth = availableWidth / fieldCountWithoutWidth;\n      }\n    }\n  }\n\n  // divide up the rest of the space\n  for (const column of columns) {\n    if (!column.width) {\n      column.width = sharedWidth;\n    }\n    column.minWidth = 50;\n  }\n\n  return columns;\n}\n\nexport function getCellComponent(displayMode: TableCellDisplayMode, field: Field): CellComponent {\n  switch (displayMode) {\n    case TableCellDisplayMode.Custom:\n    case TableCellDisplayMode.ColorText:\n    case TableCellDisplayMode.ColorBackground:\n      return DefaultCell;\n    case TableCellDisplayMode.Image:\n      return ImageCell;\n    case TableCellDisplayMode.Gauge:\n      return BarGaugeCell;\n    case TableCellDisplayMode.Sparkline:\n      return SparklineCell;\n    case TableCellDisplayMode.JSONView:\n      return JSONViewCell;\n    case TableCellDisplayMode.DataLinks:\n      return DataLinksCell;\n    case TableCellDisplayMode.Actions:\n      return ActionsCell;\n    case TableCellDisplayMode.Pill:\n      return DefaultCell; // Legacy table doesn't support pill cells, fallback to default\n  }\n\n  if (field.type === FieldType.geo) {\n    return GeoCell;\n  }\n\n  if (field.type === FieldType.frame) {\n    const firstValue = field.values[0];\n    if (isDataFrame(firstValue) && isTimeSeriesFrame(firstValue)) {\n      return SparklineCell;\n    }\n\n    return JSONViewCell;\n  }\n\n  // Default or Auto\n  if (field.type === FieldType.other) {\n    return JSONViewCell;\n  }\n\n  return DefaultCell;\n}\n\nexport function filterByValue(field?: Field) {\n  return function (rows: Row[], id: string, filterValues?: SelectableValue[]) {\n    if (rows.length === 0) {\n      return rows;\n    }\n\n    if (!filterValues) {\n      return rows;\n    }\n\n    if (!field) {\n      return rows;\n    }\n\n    return rows.filter((row) => {\n      if (!row.values.hasOwnProperty(id)) {\n        return false;\n      }\n      const value = rowToFieldValue(row, field);\n      return filterValues.find((filter) => filter.value === value) !== undefined;\n    });\n  };\n}\n\nexport function calculateUniqueFieldValues(rows: any[], field?: Field) {\n  if (!field || rows.length === 0) {\n    return {};\n  }\n\n  const set: Record<string, string> = {};\n\n  for (let index = 0; index < rows.length; index++) {\n    const value = rowToFieldValue(rows[index], field);\n    set[value || '(Blanks)'] = value;\n  }\n\n  return set;\n}\n\nexport function rowToFieldValue(row: any, field?: Field): string {\n  if (!field || !row) {\n    return '';\n  }\n\n  const fieldValue = field.values[row.index];\n  const displayValue = field.display ? field.display(fieldValue) : fieldValue;\n  const value = field.display ? formattedValueToString(displayValue) : displayValue;\n\n  return value;\n}\n\nexport function valuesToOptions(unique: Record<string, unknown>): SelectableValue[] {\n  return Object.keys(unique)\n    .reduce<SelectableValue[]>((all, key) => all.concat({ value: unique[key], label: key }), [])\n    .sort(sortOptions);\n}\n\nexport function sortOptions(a: SelectableValue, b: SelectableValue): number {\n  if (a.label === undefined && b.label === undefined) {\n    return 0;\n  }\n\n  if (a.label === undefined && b.label !== undefined) {\n    return -1;\n  }\n\n  if (a.label !== undefined && b.label === undefined) {\n    return 1;\n  }\n\n  if (a.label! < b.label!) {\n    return -1;\n  }\n\n  if (a.label! > b.label!) {\n    return 1;\n  }\n\n  return 0;\n}\n\nexport function getFilteredOptions(options: SelectableValue[], filterValues?: SelectableValue[]): SelectableValue[] {\n  if (!filterValues) {\n    return [];\n  }\n\n  return options.filter((option) => filterValues.some((filtered) => filtered.value === option.value));\n}\n\nexport function sortCaseInsensitive(a: Row, b: Row, id: string) {\n  return String(a.values[id]).localeCompare(String(b.values[id]), undefined, { sensitivity: 'base' });\n}\n\n// sortNumber needs to have great performance as it is called a lot\nexport function sortNumber(rowA: Row, rowB: Row, id: string) {\n  const a = toNumber(rowA.values[id]);\n  const b = toNumber(rowB.values[id]);\n  return a === b ? 0 : a > b ? 1 : -1;\n}\n\nfunction toNumber(value: any): number {\n  if (isDataFrameWithValue(value)) {\n    return value.value ?? Number.NEGATIVE_INFINITY;\n  }\n\n  if (value === null || value === undefined || value === '' || isNaN(value)) {\n    return Number.NEGATIVE_INFINITY;\n  }\n\n  if (typeof value === 'number') {\n    return value;\n  }\n\n  return Number(value);\n}\n\nexport function getFooterItems(\n  filterFields: Array<{ id: string; field?: Field } | undefined>,\n  values: any[number],\n  options: TableFooterCalc,\n  theme2: GrafanaTheme2\n): FooterItem[] {\n  /*\n    The FooterItems[] are calculated using both the `headerGroups[0].headers`\n    (filterFields) and `rows` (values) destructured from the useTable() hook.\n    This cacluation is based on the data from each index in `filterFields`\n    array as well as the corresponding index in the `values` array.\n    When the user hides a column through an override, the getColumns()\n    hook is invoked, removes said hidden column, sends the updated column\n    data to the useTable() hook, which then builds `headerGroups[0].headers`\n    without the hidden column. However, it doesn't remove the hidden column\n    from the `row` data, instead it substututes the hidden column row data\n    with an `undefined` value. Therefore, the `row` array length never changes,\n    despite the `headerGroups[0].headers` length changing at every column removal.\n    This makes all footer reduce calculations AFTER the first hidden column\n    in the `headerGroups[0].headers` break, since the indexing of both\n    arrays is no longer in parity.\n\n    So, here we simply recursively test for the \"hidden\" columns\n    from `headerGroups[0].headers`. Each column has an ID property that corresponds\n    to its own index, therefore if (`filterField.id` !== `String(index)`),\n    we know there is one or more hidden columns; at which point we update\n    the index with an ersatz placeholder with just an `id` property.\n  */\n  addMissingColumnIndex(filterFields);\n\n  return filterFields.map((data, i) => {\n    // Then test for numerical data - this will filter out placeholder `filterFields` as well.\n    if (data?.field?.type !== FieldType.number) {\n      // Show the reducer in the first column\n      if (i === 0 && options.reducer && options.reducer.length > 0) {\n        const reducer = fieldReducers.get(options.reducer[0]);\n        return reducer.name;\n      }\n      // Render an <EmptyCell />.\n      return undefined;\n    }\n\n    let newField = clone(data.field);\n    newField.values = values[data.id];\n    newField.state = undefined;\n\n    data.field = newField;\n\n    if (options.fields && options.fields.length > 0) {\n      const f = options.fields.find((f) => f === data?.field?.name);\n      if (f) {\n        return getFormattedValue(data.field, options.reducer, theme2);\n      }\n      return undefined;\n    }\n    return getFormattedValue(data.field, options.reducer || [], theme2);\n  });\n}\n\nfunction getFormattedValue(field: Field, reducer: string[], theme: GrafanaTheme2) {\n  // If we don't have anything to return then we display nothing\n  const calc = reducer[0];\n  if (calc === undefined) {\n    return '';\n  }\n\n  // Calculate the reduction\n  const format = field.display ?? getDisplayProcessor({ field, theme });\n  const fieldCalcValue = reduceField({ field, reducers: reducer })[calc];\n\n  // If the reducer preserves units then format the\n  // end value with the field display processor\n  const reducerInfo = fieldReducers.get(calc);\n  if (reducerInfo.preservesUnits) {\n    return formattedValueToString(format(fieldCalcValue));\n  }\n\n  // Otherwise we simply return the formatted string\n  return formattedValueToString({ text: fieldCalcValue });\n}\n\n// This strips the raw vales from the `rows` object.\nexport function createFooterCalculationValues(rows: Row[]): any[number] {\n  const values: any[number] = [];\n\n  for (const key in rows) {\n    for (const [valKey, val] of Object.entries(rows[key].values)) {\n      if (values[valKey] === undefined) {\n        values[valKey] = [];\n      }\n      values[valKey].push(val);\n    }\n  }\n\n  return values;\n}\n\nconst defaultCellOptions: TableAutoCellOptions = { type: TableCellDisplayMode.Auto };\n\nexport function getCellOptions(field: Field): TableCellOptions {\n  if (field.config.custom?.displayMode) {\n    return migrateTableDisplayModeToCellOptions(field.config.custom?.displayMode);\n  }\n\n  if (!field.config.custom?.cellOptions) {\n    return defaultCellOptions;\n  }\n\n  return field.config.custom.cellOptions;\n}\n\n/**\n * Migrates table cell display mode to new object format.\n *\n * @param displayMode The display mode of the cell\n * @returns TableCellOptions object in the correct format\n * relative to the old display mode.\n */\nexport function migrateTableDisplayModeToCellOptions(displayMode: TableCellDisplayMode): TableCellOptions {\n  switch (displayMode) {\n    // In the case of the gauge we move to a different option\n    case 'basic':\n    case 'gradient-gauge':\n    case 'lcd-gauge':\n      let gaugeMode = BarGaugeDisplayMode.Basic;\n\n      if (displayMode === 'gradient-gauge') {\n        gaugeMode = BarGaugeDisplayMode.Gradient;\n      } else if (displayMode === 'lcd-gauge') {\n        gaugeMode = BarGaugeDisplayMode.Lcd;\n      }\n\n      return {\n        type: TableCellDisplayMode.Gauge,\n        mode: gaugeMode,\n      };\n    // Also true in the case of the color background\n    case 'color-background':\n    case 'color-background-solid':\n      let mode = TableCellBackgroundDisplayMode.Basic;\n\n      // Set the new mode field, somewhat confusingly the\n      // color-background mode is for gradient display\n      if (displayMode === 'color-background') {\n        mode = TableCellBackgroundDisplayMode.Gradient;\n      }\n\n      return {\n        type: TableCellDisplayMode.ColorBackground,\n        mode: mode,\n      };\n    default:\n      return {\n        // @ts-ignore\n        type: displayMode,\n      };\n  }\n}\n\n/**\n * This recurses through an array of `filterFields` (Array<{ id: string; field?: Field } | undefined>)\n * and adds back the missing indecies that are removed due to hiding a column through an panel override.\n * This is necessary to create Array.length parity between the `filterFields` array and the `values` array (any[number]),\n * since the footer value calculations are based on the corresponding index values of both arrays.\n *\n * @remarks\n * This function uses the splice() method, and therefore mutates the array.\n *\n * @param columns - An array of `filterFields` (Array<{ id: string; field?: Field } | undefined>).\n * @returns void; this function returns nothing; it only mutates values as a side effect.\n */\nfunction addMissingColumnIndex(columns: Array<{ id: string; field?: Field } | undefined>): void {\n  const missingIndex = columns.findIndex((field, index) => field?.id !== String(index));\n\n  // Base case\n  if (missingIndex === -1 || columns[missingIndex]?.id === 'expander') {\n    return;\n  }\n\n  // Splice in missing column\n  columns.splice(missingIndex, 0, { id: String(missingIndex) });\n\n  // Recurse\n  addMissingColumnIndex(columns);\n}\n\n/**\n * Getting gauge or sparkline values to align is very tricky without looking at all values and passing them through display processor.\n * For very large tables that could pretty expensive. So this is kind of a compromise. We look at the first 1000 rows and cache the longest value.\n * If we have a cached value we just check if the current value is longer and update the alignmentFactor. This can obviously still lead to\n * unaligned gauges but it should a lot less common.\n **/\nexport function getAlignmentFactor(\n  field: Field,\n  displayValue: DisplayValue,\n  rowIndex: number\n): DisplayValueAlignmentFactors {\n  let alignmentFactor = field.state?.alignmentFactors;\n\n  if (alignmentFactor) {\n    // check if current alignmentFactor is still the longest\n    if (formattedValueToString(alignmentFactor).length < formattedValueToString(displayValue).length) {\n      alignmentFactor = { ...displayValue };\n      field.state!.alignmentFactors = alignmentFactor;\n    }\n    return alignmentFactor;\n  } else {\n    // look at the next 1000 rows\n    alignmentFactor = { ...displayValue };\n    const maxIndex = Math.min(field.values.length, rowIndex + 1000);\n\n    for (let i = rowIndex + 1; i < maxIndex; i++) {\n      const nextDisplayValue = field.display!(field.values[i]);\n      if (formattedValueToString(alignmentFactor).length > formattedValueToString(nextDisplayValue).length) {\n        alignmentFactor.text = displayValue.text;\n      }\n    }\n\n    if (field.state) {\n      field.state.alignmentFactors = alignmentFactor;\n    } else {\n      field.state = { alignmentFactors: alignmentFactor };\n    }\n\n    return alignmentFactor;\n  }\n}\n\n// since the conversion from timeseries panel crosshair to time is pixel based, we need\n// to set a threshold where the table row highlights when the crosshair is hovered over a certain point\n// because multiple pixels (converted to times) may represent the same point/row in table\nexport function isPointTimeValAroundTableTimeVal(pointTime: number, rowTime: number, threshold: number) {\n  return Math.abs(Math.floor(pointTime) - rowTime) < threshold;\n}\n\n// calculate the threshold for which we consider a point in a chart\n// to match a row in a table based on a time value\nexport function calculateAroundPointThreshold(timeField: Field): number {\n  let max = -Number.MAX_VALUE;\n  let min = Number.MAX_VALUE;\n\n  if (timeField.values.length < 2) {\n    return 0;\n  }\n\n  for (let i = 0; i < timeField.values.length; i++) {\n    const value = timeField.values[i];\n    if (value > max) {\n      max = value;\n    }\n    if (value < min) {\n      min = value;\n    }\n  }\n\n  return (max - min) / timeField.values.length;\n}\n\n/**\n * Retrieve colors for a table cell (or table row).\n *\n * @param tableStyles\n *  Styles for the table\n * @param cellOptions\n *  Table cell configuration options\n * @param displayValue\n *  The value that will be displayed\n * @returns CellColors\n */\nexport function getCellColors(\n  theme: GrafanaTheme2,\n  cellOptions: TableCellOptions,\n  displayValue: DisplayValue\n): CellColors {\n  // How much to darken elements depends upon if we're in dark mode\n  const darkeningFactor = theme.isDark ? 1 : -0.7;\n\n  // Setup color variables\n  let textColor: string | undefined = undefined;\n  let bgColor: string | undefined = undefined;\n  let bgHoverColor: string | undefined = undefined;\n\n  if (cellOptions.type === TableCellDisplayMode.ColorText) {\n    textColor = displayValue.color;\n  } else if (cellOptions.type === TableCellDisplayMode.ColorBackground) {\n    const mode = cellOptions.mode ?? TableCellBackgroundDisplayMode.Gradient;\n\n    if (mode === TableCellBackgroundDisplayMode.Basic) {\n      textColor = getTextColorForAlphaBackground(displayValue.color!, theme.isDark);\n      bgColor = tinycolor(displayValue.color).toRgbString();\n      bgHoverColor = tinycolor(displayValue.color).setAlpha(1).toRgbString();\n    } else if (mode === TableCellBackgroundDisplayMode.Gradient) {\n      const hoverColor = tinycolor(displayValue.color).setAlpha(1).toRgbString();\n      const bgColor2 = tinycolor(displayValue.color)\n        .darken(10 * darkeningFactor)\n        .spin(5);\n      textColor = getTextColorForAlphaBackground(displayValue.color!, theme.isDark);\n      bgColor = `linear-gradient(120deg, ${bgColor2.toRgbString()}, ${displayValue.color})`;\n      bgHoverColor = `linear-gradient(120deg, ${bgColor2.setAlpha(1).toRgbString()}, ${hoverColor})`;\n    }\n  }\n\n  return { textColor, bgColor, bgHoverColor };\n}\n\n/**\n * Calculate an estimated bounding box for a block\n * of text using an offscreen canvas.\n */\nexport function guessTextBoundingBox(\n  text: string,\n  headerGroup: HeaderGroup,\n  osContext: OffscreenCanvasRenderingContext2D | null,\n  lineHeight: number,\n  defaultRowHeight: number,\n  padding = 0\n) {\n  const width = Number(headerGroup?.width ?? 300);\n  const LINE_SCALE_FACTOR = 1.17;\n  const LOW_LINE_PAD = 42;\n  const PADDING = padding * 2;\n\n  if (osContext !== null && typeof text === 'string') {\n    const words = text.split(/\\s/);\n    const lines = [];\n    let currentLine = '';\n    let wordCount = 0;\n    let extraLines = 0;\n\n    // Let's just wrap the lines and see how well the measurement works\n    for (let i = 0; i < words.length; i++) {\n      const currentWord = words[i];\n      let lineWidth = osContext.measureText(currentLine + ' ' + currentWord).width;\n\n      if (lineWidth < width - PADDING) {\n        currentLine += ' ' + currentWord;\n        wordCount++;\n      } else {\n        lines.push({\n          width: lineWidth,\n          line: currentLine,\n        });\n\n        currentLine = currentWord;\n        wordCount = 0;\n      }\n    }\n\n    // We can have extra long strings, for these\n    // we estimate if it overshoots the line by\n    // at least one other line\n    for (let i = 0; i < lines.length; i++) {\n      if (lines[i].width > width) {\n        let extra = Math.floor(lines[i].width / width) - 1;\n        extraLines += extra;\n      }\n    }\n\n    // Estimated height would be lines multiplied\n    // by the line height\n    let lineNumber = lines.length + extraLines;\n    let height = 38;\n    if (lineNumber > 5) {\n      height = lineNumber * lineHeight * LINE_SCALE_FACTOR;\n    } else {\n      height = lineNumber * lineHeight + LOW_LINE_PAD;\n    }\n    height += PADDING;\n\n    return { width, height };\n  }\n\n  return { width, height: defaultRowHeight };\n}\n\n/**\n * A function to guess at which field has the longest text.\n * To do this we either select a single record if there aren't many records\n * or we select records at random and sample their size.\n */\nexport function guessLongestField(fieldConfig: FieldConfigSource, data: DataFrame) {\n  let longestField = undefined;\n  const SAMPLE_SIZE = 3;\n\n  // If the default field option is set to allow text wrapping\n  // we determine the field to wrap text with here and then\n  // pass it to the RowsList\n  if (fieldConfig.defaults.custom?.cellOptions?.wrapText) {\n    const stringFields = data.fields.filter((field: Field) => field.type === FieldType.string);\n\n    if (stringFields.length >= 1 && stringFields[0].values.length > 0) {\n      const numValues = stringFields[0].values.length;\n      let longestLength = 0;\n\n      // If we have less than 30 values we assume that the first\n      // non-null record is representative of the overall data\n      if (numValues <= 30) {\n        for (const field of stringFields) {\n          const fieldLength = field.values.find((v) => v != null)?.length ?? 0;\n          if (fieldLength > longestLength) {\n            longestLength = fieldLength;\n            longestField = field;\n          }\n        }\n      }\n      // Otherwise we randomly sample SAMPLE_SIZE values and take\n      // the mean length\n      else {\n        for (const field of stringFields) {\n          // This could result in duplicate values but\n          // that should be fairly unlikely. This could potentially\n          // be improved using a Set datastructure but\n          // going to leave that one as an exercise for\n          // the reader to contemplate and possibly code\n          const vals = sampleSize(field.values, SAMPLE_SIZE);\n          const meanLength = (vals[0]?.length + vals[1]?.length + vals[2]?.length) / 3;\n\n          if (meanLength > longestLength) {\n            longestLength = meanLength;\n            longestField = field;\n          }\n        }\n      }\n    }\n  }\n\n  return longestField;\n}\n\nexport interface DataLinksActionsTooltipState {\n  coords: DataLinksActionsTooltipCoords;\n  links?: LinkModel[];\n  actions?: ActionModel[];\n}\n\nexport interface DataLinksActionsTooltipCoords {\n  clientX: number;\n  clientY: number;\n}\n\nexport const getDataLinksActionsTooltipUtils = (links: LinkModel[], actions?: ActionModel[]) => {\n  const hasMultipleLinksOrActions = links.length > 1 || Boolean(actions?.length);\n  const shouldShowLink = links.length === 1 && !Boolean(actions?.length);\n\n  return { shouldShowLink, hasMultipleLinksOrActions };\n};\n\nconst shouldTriggerTooltip = (event: React.MouseEvent<HTMLElement>): boolean => {\n  return event.target === event.currentTarget;\n};\n\n/**\n * Creates an onClick handler for table cells that only triggers tooltip when clicking directly on the cell\n * @param setTooltipCoords - function to set tooltip coordinates\n * @returns onClick handler\n */\nexport const tooltipOnClickHandler = (setTooltipCoords: (coords: DataLinksActionsTooltipCoords) => void) => {\n  return (event: React.MouseEvent<HTMLElement>) => {\n    if (shouldTriggerTooltip(event)) {\n      const { clientX, clientY } = event;\n      setTooltipCoords({ clientX, clientY });\n    }\n  };\n};\n"],"names":["FieldType","data","RowExpander","getFieldDisplayName","memoize","getFooterValue","TableCellDisplayMode","DefaultCell","ImageCell","BarGaugeCell","SparklineCell","JSONViewCell","DataLinksCell","ActionsCell","GeoCell","isDataFrame","isTimeSeriesFrame","formattedValueToString","isDataFrameWithValue","fieldReducers","clone","f","_a","getDisplayProcessor","reduceField","BarGaugeDisplayMode","TableCellBackgroundDisplayMode","getTextColorForAlphaBackground","tinycolor","sampleSize"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDO,MAAM,cAAA,GAAiB;AAEvB,SAAS,aAAa,KAAA,EAAwC;AACnE,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,YAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,OAAO,MAAA,EAAQ;AACvB,IAAA,MAAM,MAAA,GAA4B,MAAM,MAAA,CAAO,MAAA;AAE/C,IAAA,QAAQ,OAAO,KAAA;AAAO,MACpB,KAAK,OAAA;AACH,QAAA,OAAO,UAAA;AAAA,MACT,KAAK,MAAA;AACH,QAAA,OAAO,YAAA;AAAA,MACT,KAAK,QAAA;AACH,QAAA,OAAO,QAAA;AAAA;AACX,EACF;AAEA,EAAA,IAAI,KAAA,CAAM,IAAA,KAASA,cAAA,CAAU,MAAA,EAAQ;AACnC,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,OAAO,YAAA;AACT;AAEO,SAAS,WACdC,MAAA,EACA,cAAA,EACA,cAAA,EACA,QAAA,EACA,cACA,cAAA,EACsB;AAzFxB,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA0FE,EAAA,MAAM,UAAgC,EAAC;AACvC,EAAA,IAAI,sBAAA,GAAyB,CAAA;AAE7B,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA;AAAA,MAEX,QAAQ,MAAM,IAAA;AAAA;AAAA,MACd,EAAA,EAAI,UAAA;AAAA;AAAA;AAAA;AAAA,MAGJ,IAAA,EAAMC,uBAAA;AAAA,MACN,KAAA,EAAO,cAAA;AAAA,MACP,QAAA,EAAU,cAAA;AAAA,MACV,MAAA,EAAQ,CAAC,KAAA,EAAc,GAAA,EAAa,aAAA,KAAsC;AACxE,QAAA,OAAO,EAAC;AAAA,MACV,CAAA;AAAA,MACA,cAAA,EAAgB,MAAA;AAAA,MAChB,KAAA,EAAOD,MAAA,CAAK,MAAA,CAAO,CAAC,CAAA;AAAA,MACpB,QAAA,EAAU;AAAA,KACX,CAAA;AAED,IAAA,cAAA,IAAkB,cAAA;AAAA,EACpB;AAEA,EAAA,KAAA,MAAW,CAAC,UAAA,EAAY,KAAK,KAAKA,MAAA,CAAK,MAAA,CAAO,SAAQ,EAAG;AACvD,IAAA,MAAM,iBAAA,GAAuC,KAAA,CAAM,MAAA,CAAO,MAAA,IAAU,EAAC;AACrE,IAAA;AAAA;AAAA,MAEE,iBAAA,CAAkB,YAClB,EAAA,GAAA,iBAAA,CAAkB,QAAA,KAAlB,mBAA4B,GAAA,CAAA,IAC5B,KAAA,CAAM,SAASD,cAAA,CAAU;AAAA,MACzB;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,kBAAkB,KAAA,EAAO;AAC3B,MAAA,cAAA,IAAkB,iBAAA,CAAkB,KAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,sBAAA,EAAA;AAAA,IACF;AAEA,IAAA,MAAM,cAAA,GAAiB,CAAC,IAAA,KAAoB;AAC1C,MAAA,QAAQ,IAAA;AAAM,QACZ,KAAKA,cAAA,CAAU,MAAA;AAAA,QACf,KAAKA,cAAA,CAAU,KAAA;AACb,UAAA,OAAO,QAAA;AAAA,QACT,KAAKA,cAAA,CAAU,IAAA;AACb,UAAA,OAAO,OAAA;AAAA,QACT;AACE,UAAA,OAAO,0BAAA;AAAA;AACX,IACF,CAAA;AAEA,IAAA,MAAM,OAAO,gBAAA,CAAA,CAAiB,EAAA,GAAA,iBAAA,CAAkB,WAAA,KAAlB,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAA+B,MAAM,KAAK,CAAA;AACxE,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA;AAAA;AAAA,MAGX,IAAA;AAAA,MACA,EAAA,EAAI,WAAW,QAAA,EAAS;AAAA,MACxB,KAAA;AAAA,MACA,QAAQ,iBAAA,CAAkB,UAAA,GAAa,EAAA,GAAKG,wBAAA,CAAoB,OAAOF,MAAI,CAAA;AAAA,MAC3E,UAAU,CAAC,IAAA,EAAM,CAAA,KAAM,KAAA,CAAM,OAAO,CAAC,CAAA;AAAA,MACrC,QAAA,EAAU,cAAA,CAAe,KAAA,CAAM,IAAI,CAAA;AAAA,MACnC,OAAO,iBAAA,CAAkB,KAAA;AAAA,MACzB,QAAA,EAAA,CAAU,EAAA,GAAA,iBAAA,CAAkB,QAAA,KAAlB,IAAA,GAAA,EAAA,GAA8B,cAAA;AAAA,MACxC,MAAA,EAAQG,wBAAA,CAAQ,aAAA,CAAc,KAAK,CAAC,CAAA;AAAA,MACpC,cAAA,EAAgB,aAAa,KAAK,CAAA;AAAA,MAClC,MAAA,EAAQC,wBAAA,CAAe,UAAA,EAAY,YAAA,EAAc,cAAc;AAAA,KAChE,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,cAAc,cAAA,GAAiB,sBAAA;AACnC,EAAA,KAAA,IAAS,CAAA,GAAI,sBAAA,EAAwB,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC/C,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,WAAW,WAAA,EAAa;AAClD,QAAA,MAAA,CAAO,QAAQ,MAAA,CAAO,QAAA;AACtB,QAAA,cAAA,IAAkB,MAAA,CAAO,KAAA;AACzB,QAAA,sBAAA,IAA0B,CAAA;AAC1B,QAAA,WAAA,GAAc,cAAA,GAAiB,sBAAA;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAI,CAAC,OAAO,KAAA,EAAO;AACjB,MAAA,MAAA,CAAO,KAAA,GAAQ,WAAA;AAAA,IACjB;AACA,IAAA,MAAA,CAAO,QAAA,GAAW,EAAA;AAAA,EACpB;AAEA,EAAA,OAAO,OAAA;AACT;AAEO,SAAS,gBAAA,CAAiB,aAAmC,KAAA,EAA6B;AAC/F,EAAA,QAAQ,WAAA;AAAa,IACnB,KAAKC,2BAAA,CAAqB,MAAA;AAAA,IAC1B,KAAKA,2BAAA,CAAqB,SAAA;AAAA,IAC1B,KAAKA,2BAAA,CAAqB,eAAA;AACxB,MAAA,OAAOC,uBAAA;AAAA,IACT,KAAKD,2BAAA,CAAqB,KAAA;AACxB,MAAA,OAAOE,mBAAA;AAAA,IACT,KAAKF,2BAAA,CAAqB,KAAA;AACxB,MAAA,OAAOG,yBAAA;AAAA,IACT,KAAKH,2BAAA,CAAqB,SAAA;AACxB,MAAA,OAAOI,2BAAA;AAAA,IACT,KAAKJ,2BAAA,CAAqB,QAAA;AACxB,MAAA,OAAOK,yBAAA;AAAA,IACT,KAAKL,2BAAA,CAAqB,SAAA;AACxB,MAAA,OAAOM,2BAAA;AAAA,IACT,KAAKN,2BAAA,CAAqB,OAAA;AACxB,MAAA,OAAOO,uBAAA;AAAA,IACT,KAAKP,2BAAA,CAAqB,IAAA;AACxB,MAAA,OAAOC,uBAAA;AAAA;AAGX,EAAA,IAAI,KAAA,CAAM,IAAA,KAASP,cAAA,CAAU,GAAA,EAAK;AAChC,IAAA,OAAOc,eAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,IAAA,KAASd,cAAA,CAAU,KAAA,EAAO;AAClC,IAAA,MAAM,UAAA,GAAa,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA;AACjC,IAAA,IAAIe,gBAAA,CAAY,UAAU,CAAA,IAAKC,sBAAA,CAAkB,UAAU,CAAA,EAAG;AAC5D,MAAA,OAAON,2BAAA;AAAA,IACT;AAEA,IAAA,OAAOC,yBAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,CAAM,IAAA,KAASX,cAAA,CAAU,KAAA,EAAO;AAClC,IAAA,OAAOW,yBAAA;AAAA,EACT;AAEA,EAAA,OAAOJ,uBAAA;AACT;AAEO,SAAS,cAAc,KAAA,EAAe;AAC3C,EAAA,OAAO,SAAU,IAAA,EAAa,EAAA,EAAY,YAAA,EAAkC;AAC1E,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,CAAC,GAAA,KAAQ;AAC1B,MAAA,IAAI,CAAC,GAAA,CAAI,MAAA,CAAO,cAAA,CAAe,EAAE,CAAA,EAAG;AAClC,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,GAAA,EAAK,KAAK,CAAA;AACxC,MAAA,OAAO,aAAa,IAAA,CAAK,CAAC,WAAW,MAAA,CAAO,KAAA,KAAU,KAAK,CAAA,KAAM,KAAA,CAAA;AAAA,IACnE,CAAC,CAAA;AAAA,EACH,CAAA;AACF;AAEO,SAAS,0BAAA,CAA2B,MAAa,KAAA,EAAe;AACrE,EAAA,IAAI,CAAC,KAAA,IAAS,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAC/B,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,MAA8B,EAAC;AAErC,EAAA,KAAA,IAAS,KAAA,GAAQ,CAAA,EAAG,KAAA,GAAQ,IAAA,CAAK,QAAQ,KAAA,EAAA,EAAS;AAChD,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,IAAA,CAAK,KAAK,GAAG,KAAK,CAAA;AAChD,IAAA,GAAA,CAAI,KAAA,IAAS,UAAU,CAAA,GAAI,KAAA;AAAA,EAC7B;AAEA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,eAAA,CAAgB,KAAU,KAAA,EAAuB;AAC/D,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,GAAA,EAAK;AAClB,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACzC,EAAA,MAAM,eAAe,KAAA,CAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,GAAI,UAAA;AACjE,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAUU,2BAAA,CAAuB,YAAY,CAAA,GAAI,YAAA;AAErE,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,gBAAgB,MAAA,EAAoD;AAClF,EAAA,OAAO,MAAA,CAAO,KAAK,MAAM,CAAA,CACtB,OAA0B,CAAC,GAAA,EAAK,GAAA,KAAQ,GAAA,CAAI,MAAA,CAAO,EAAE,OAAO,MAAA,CAAO,GAAG,CAAA,EAAG,KAAA,EAAO,GAAA,EAAK,GAAG,EAAE,CAAA,CAC1F,IAAA,CAAK,WAAW,CAAA;AACrB;AAEO,SAAS,WAAA,CAAY,GAAoB,CAAA,EAA4B;AAC1E,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,KAAA,CAAA,IAAa,CAAA,CAAE,UAAU,KAAA,CAAA,EAAW;AAClD,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,KAAA,CAAA,IAAa,CAAA,CAAE,UAAU,KAAA,CAAA,EAAW;AAClD,IAAA,OAAO,CAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,KAAA,CAAA,IAAa,CAAA,CAAE,UAAU,KAAA,CAAA,EAAW;AAClD,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAA,CAAE,KAAA,GAAS,CAAA,CAAE,KAAA,EAAQ;AACvB,IAAA,OAAO,CAAA,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAA,CAAE,KAAA,GAAS,CAAA,CAAE,KAAA,EAAQ;AACvB,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,OAAO,CAAA;AACT;AAEO,SAAS,kBAAA,CAAmB,SAA4B,YAAA,EAAqD;AAClH,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAW,YAAA,CAAa,IAAA,CAAK,CAAC,QAAA,KAAa,QAAA,CAAS,KAAA,KAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AACpG;AAEO,SAAS,mBAAA,CAAoB,CAAA,EAAQ,CAAA,EAAQ,EAAA,EAAY;AAC9D,EAAA,OAAO,OAAO,CAAA,CAAE,MAAA,CAAO,EAAE,CAAC,EAAE,aAAA,CAAc,MAAA,CAAO,CAAA,CAAE,MAAA,CAAO,EAAE,CAAC,CAAA,EAAG,QAAW,EAAE,WAAA,EAAa,QAAQ,CAAA;AACpG;AAGO,SAAS,UAAA,CAAW,IAAA,EAAW,IAAA,EAAW,EAAA,EAAY;AAC3D,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,IAAA,CAAK,MAAA,CAAO,EAAE,CAAC,CAAA;AAClC,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,IAAA,CAAK,MAAA,CAAO,EAAE,CAAC,CAAA;AAClC,EAAA,OAAO,CAAA,KAAM,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,IAAI,CAAA,GAAI,CAAA,CAAA;AACnC;AAEA,SAAS,SAAS,KAAA,EAAoB;AAxUtC,EAAA,IAAA,EAAA;AAyUE,EAAA,IAAIC,yBAAA,CAAqB,KAAK,CAAA,EAAG;AAC/B,IAAA,OAAA,CAAO,EAAA,GAAA,KAAA,CAAM,KAAA,KAAN,IAAA,GAAA,EAAA,GAAe,MAAA,CAAO,iBAAA;AAAA,EAC/B;AAEA,EAAA,IAAI,KAAA,KAAU,QAAQ,KAAA,KAAU,KAAA,CAAA,IAAa,UAAU,EAAA,IAAM,KAAA,CAAM,KAAK,CAAA,EAAG;AACzE,IAAA,OAAO,MAAA,CAAO,iBAAA;AAAA,EAChB;AAEA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AAEO,SAAS,cAAA,CACd,YAAA,EACA,MAAA,EACA,OAAA,EACA,MAAA,EACc;AAuBd,EAAA,qBAAA,CAAsB,YAAY,CAAA;AAElC,EAAA,OAAO,YAAA,CAAa,GAAA,CAAI,CAACjB,MAAA,EAAM,CAAA,KAAM;AAtXvC,IAAA,IAAA,EAAA;AAwXI,IAAA,IAAA,CAAA,CAAI,EAAA,GAAAA,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,MAAA,CAAM,KAAA,KAAN,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAa,IAAA,MAASD,eAAU,MAAA,EAAQ;AAE1C,MAAA,IAAI,MAAM,CAAA,IAAK,OAAA,CAAQ,WAAW,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC5D,QAAA,MAAM,UAAUmB,kBAAA,CAAc,GAAA,CAAI,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAC,CAAA;AACpD,QAAA,OAAO,OAAA,CAAQ,IAAA;AAAA,MACjB;AAEA,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AAEA,IAAA,IAAI,QAAA,GAAWC,YAAA,CAAMnB,MAAA,CAAK,KAAK,CAAA;AAC/B,IAAA,QAAA,CAAS,MAAA,GAAS,MAAA,CAAOA,MAAA,CAAK,EAAE,CAAA;AAChC,IAAA,QAAA,CAAS,KAAA,GAAQ,KAAA,CAAA;AAEjB,IAAAA,MAAA,CAAK,KAAA,GAAQ,QAAA;AAEb,IAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAG;AAC/C,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,CAACoB,EAAAA,KAAG;AAzYxC,QAAA,IAAAC,GAAAA;AAyY2C,QAAA,OAAAD,EAAAA,MAAAA,CAAMC,GAAAA,GAAArB,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,MAAA,CAAM,KAAA,KAAN,gBAAAqB,GAAAA,CAAa,IAAA,CAAA;AAAA,MAAA,CAAI,CAAA;AAC5D,MAAA,IAAI,CAAA,EAAG;AACL,QAAA,OAAO,iBAAA,CAAkBrB,MAAA,CAAK,KAAA,EAAO,OAAA,CAAQ,SAAS,MAAM,CAAA;AAAA,MAC9D;AACA,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AACA,IAAA,OAAO,kBAAkBA,MAAA,CAAK,KAAA,EAAO,QAAQ,OAAA,IAAW,IAAI,MAAM,CAAA;AAAA,EACpE,CAAC,CAAA;AACH;AAEA,SAAS,iBAAA,CAAkB,KAAA,EAAc,OAAA,EAAmB,KAAA,EAAsB;AAnZlF,EAAA,IAAA,EAAA;AAqZE,EAAA,MAAM,IAAA,GAAO,QAAQ,CAAC,CAAA;AACtB,EAAA,IAAI,SAAS,KAAA,CAAA,EAAW;AACtB,IAAA,OAAO,EAAA;AAAA,EACT;AAGA,EAAA,MAAM,MAAA,GAAA,CAAS,WAAM,OAAA,KAAN,IAAA,GAAA,EAAA,GAAiBsB,yBAAoB,EAAE,KAAA,EAAO,OAAO,CAAA;AACpE,EAAA,MAAM,cAAA,GAAiBC,iBAAY,EAAE,KAAA,EAAO,UAAU,OAAA,EAAS,EAAE,IAAI,CAAA;AAIrE,EAAA,MAAM,WAAA,GAAcL,kBAAA,CAAc,GAAA,CAAI,IAAI,CAAA;AAC1C,EAAA,IAAI,YAAY,cAAA,EAAgB;AAC9B,IAAA,OAAOF,2BAAA,CAAuB,MAAA,CAAO,cAAc,CAAC,CAAA;AAAA,EACtD;AAGA,EAAA,OAAOA,2BAAA,CAAuB,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA;AACxD;AAGO,SAAS,8BAA8B,IAAA,EAA0B;AACtE,EAAA,MAAM,SAAsB,EAAC;AAE7B,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,GAAG,CAAA,IAAK,MAAA,CAAO,QAAQ,IAAA,CAAK,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG;AAC5D,MAAA,IAAI,MAAA,CAAO,MAAM,CAAA,KAAM,KAAA,CAAA,EAAW;AAChC,QAAA,MAAA,CAAO,MAAM,IAAI,EAAC;AAAA,MACpB;AACA,MAAA,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,IACzB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,MAAM,kBAAA,GAA2C,EAAE,IAAA,EAAMX,2BAAA,CAAqB,IAAA,EAAK;AAE5E,SAAS,eAAe,KAAA,EAAgC;AA3b/D,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA4bE,EAAA,IAAA,CAAI,EAAA,GAAA,KAAA,CAAM,MAAA,CAAO,MAAA,KAAb,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAqB,WAAA,EAAa;AACpC,IAAA,OAAO,oCAAA,CAAA,CAAqC,EAAA,GAAA,KAAA,CAAM,MAAA,CAAO,MAAA,KAAb,mBAAqB,WAAW,CAAA;AAAA,EAC9E;AAEA,EAAA,IAAI,EAAA,CAAC,EAAA,GAAA,KAAA,CAAM,MAAA,CAAO,MAAA,KAAb,mBAAqB,WAAA,CAAA,EAAa;AACrC,IAAA,OAAO,kBAAA;AAAA,EACT;AAEA,EAAA,OAAO,KAAA,CAAM,OAAO,MAAA,CAAO,WAAA;AAC7B;AASO,SAAS,qCAAqC,WAAA,EAAqD;AACxG,EAAA,QAAQ,WAAA;AAAa;AAAA,IAEnB,KAAK,OAAA;AAAA,IACL,KAAK,gBAAA;AAAA,IACL,KAAK,WAAA;AACH,MAAA,IAAI,YAAYmB,0BAAA,CAAoB,KAAA;AAEpC,MAAA,IAAI,gBAAgB,gBAAA,EAAkB;AACpC,QAAA,SAAA,GAAYA,0BAAA,CAAoB,QAAA;AAAA,MAClC,CAAA,MAAA,IAAW,gBAAgB,WAAA,EAAa;AACtC,QAAA,SAAA,GAAYA,0BAAA,CAAoB,GAAA;AAAA,MAClC;AAEA,MAAA,OAAO;AAAA,QACL,MAAMnB,2BAAA,CAAqB,KAAA;AAAA,QAC3B,IAAA,EAAM;AAAA,OACR;AAAA;AAAA,IAEF,KAAK,kBAAA;AAAA,IACL,KAAK,wBAAA;AACH,MAAA,IAAI,OAAOoB,qCAAA,CAA+B,KAAA;AAI1C,MAAA,IAAI,gBAAgB,kBAAA,EAAoB;AACtC,QAAA,IAAA,GAAOA,qCAAA,CAA+B,QAAA;AAAA,MACxC;AAEA,MAAA,OAAO;AAAA,QACL,MAAMpB,2BAAA,CAAqB,eAAA;AAAA,QAC3B;AAAA,OACF;AAAA,IACF;AACE,MAAA,OAAO;AAAA;AAAA,QAEL,IAAA,EAAM;AAAA,OACR;AAAA;AAEN;AAcA,SAAS,sBAAsB,OAAA,EAAiE;AAngBhG,EAAA,IAAA,EAAA;AAogBE,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,SAAA,CAAU,CAAC,KAAA,EAAO,WAAU,KAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAO,EAAA,MAAO,MAAA,CAAO,KAAK,CAAC,CAAA;AAGpF,EAAA,IAAI,iBAAiB,CAAA,CAAA,IAAA,CAAA,CAAM,EAAA,GAAA,OAAA,CAAQ,YAAY,CAAA,KAApB,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAuB,QAAO,UAAA,EAAY;AACnE,IAAA;AAAA,EACF;AAGA,EAAA,OAAA,CAAQ,MAAA,CAAO,cAAc,CAAA,EAAG,EAAE,IAAI,MAAA,CAAO,YAAY,GAAG,CAAA;AAG5D,EAAA,qBAAA,CAAsB,OAAO,CAAA;AAC/B;AAQO,SAAS,kBAAA,CACd,KAAA,EACA,YAAA,EACA,QAAA,EAC8B;AA5hBhC,EAAA,IAAA,EAAA;AA6hBE,EAAA,IAAI,eAAA,GAAA,CAAkB,EAAA,GAAA,KAAA,CAAM,KAAA,KAAN,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAa,gBAAA;AAEnC,EAAA,IAAI,eAAA,EAAiB;AAEnB,IAAA,IAAIW,4BAAuB,eAAe,CAAA,CAAE,SAASA,2BAAA,CAAuB,YAAY,EAAE,MAAA,EAAQ;AAChG,MAAA,eAAA,GAAkB,EAAE,GAAG,YAAA,EAAa;AACpC,MAAA,KAAA,CAAM,MAAO,gBAAA,GAAmB,eAAA;AAAA,IAClC;AACA,IAAA,OAAO,eAAA;AAAA,EACT,CAAA,MAAO;AAEL,IAAA,eAAA,GAAkB,EAAE,GAAG,YAAA,EAAa;AACpC,IAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,MAAM,MAAA,CAAO,MAAA,EAAQ,WAAW,GAAI,CAAA;AAE9D,IAAA,KAAA,IAAS,CAAA,GAAI,QAAA,GAAW,CAAA,EAAG,CAAA,GAAI,UAAU,CAAA,EAAA,EAAK;AAC5C,MAAA,MAAM,mBAAmB,KAAA,CAAM,OAAA,CAAS,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAA;AACvD,MAAA,IAAIA,4BAAuB,eAAe,CAAA,CAAE,SAASA,2BAAA,CAAuB,gBAAgB,EAAE,MAAA,EAAQ;AACpG,QAAA,eAAA,CAAgB,OAAO,YAAA,CAAa,IAAA;AAAA,MACtC;AAAA,IACF;AAEA,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,KAAA,CAAM,MAAM,gBAAA,GAAmB,eAAA;AAAA,IACjC,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAA,GAAQ,EAAE,gBAAA,EAAkB,eAAA,EAAgB;AAAA,IACpD;AAEA,IAAA,OAAO,eAAA;AAAA,EACT;AACF;AAKO,SAAS,gCAAA,CAAiC,SAAA,EAAmB,OAAA,EAAiB,SAAA,EAAmB;AACtG,EAAA,OAAO,KAAK,GAAA,CAAI,IAAA,CAAK,MAAM,SAAS,CAAA,GAAI,OAAO,CAAA,GAAI,SAAA;AACrD;AAIO,SAAS,8BAA8B,SAAA,EAA0B;AACtE,EAAA,IAAI,GAAA,GAAM,CAAC,MAAA,CAAO,SAAA;AAClB,EAAA,IAAI,MAAM,MAAA,CAAO,SAAA;AAEjB,EAAA,IAAI,SAAA,CAAU,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AAC/B,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AAChD,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA;AAChC,IAAA,IAAI,QAAQ,GAAA,EAAK;AACf,MAAA,GAAA,GAAM,KAAA;AAAA,IACR;AACA,IAAA,IAAI,QAAQ,GAAA,EAAK;AACf,MAAA,GAAA,GAAM,KAAA;AAAA,IACR;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,GAAA,GAAM,GAAA,IAAO,SAAA,CAAU,MAAA,CAAO,MAAA;AACxC;AAaO,SAAS,aAAA,CACd,KAAA,EACA,WAAA,EACA,YAAA,EACY;AAzmBd,EAAA,IAAA,EAAA;AA2mBE,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,CAAA,GAAA;AAG3C,EAAA,IAAI,SAAA,GAAgC,KAAA,CAAA;AACpC,EAAA,IAAI,OAAA,GAA8B,KAAA,CAAA;AAClC,EAAA,IAAI,YAAA,GAAmC,KAAA,CAAA;AAEvC,EAAA,IAAI,WAAA,CAAY,IAAA,KAASX,2BAAA,CAAqB,SAAA,EAAW;AACvD,IAAA,SAAA,GAAY,YAAA,CAAa,KAAA;AAAA,EAC3B,CAAA,MAAA,IAAW,WAAA,CAAY,IAAA,KAASA,2BAAA,CAAqB,eAAA,EAAiB;AACpE,IAAA,MAAM,IAAA,GAAA,CAAO,EAAA,GAAA,WAAA,CAAY,IAAA,KAAZ,IAAA,GAAA,EAAA,GAAoBoB,qCAAA,CAA+B,QAAA;AAEhE,IAAA,IAAI,IAAA,KAASA,sCAA+B,KAAA,EAAO;AACjD,MAAA,SAAA,GAAYC,qCAAA,CAA+B,YAAA,CAAa,KAAA,EAAQ,KAAA,CAAM,MAAM,CAAA;AAC5E,MAAA,OAAA,GAAUC,0BAAA,CAAU,YAAA,CAAa,KAAK,CAAA,CAAE,WAAA,EAAY;AACpD,MAAA,YAAA,GAAeA,2BAAU,YAAA,CAAa,KAAK,EAAE,QAAA,CAAS,CAAC,EAAE,WAAA,EAAY;AAAA,IACvE,CAAA,MAAA,IAAW,IAAA,KAASF,qCAAA,CAA+B,QAAA,EAAU;AAC3D,MAAA,MAAM,UAAA,GAAaE,2BAAU,YAAA,CAAa,KAAK,EAAE,QAAA,CAAS,CAAC,EAAE,WAAA,EAAY;AACzE,MAAA,MAAM,QAAA,GAAWA,0BAAA,CAAU,YAAA,CAAa,KAAK,CAAA,CAC1C,OAAO,EAAA,GAAK,eAAe,CAAA,CAC3B,IAAA,CAAK,CAAC,CAAA;AACT,MAAA,SAAA,GAAYD,qCAAA,CAA+B,YAAA,CAAa,KAAA,EAAQ,KAAA,CAAM,MAAM,CAAA;AAC5E,MAAA,OAAA,GAAU,2BAA2B,QAAA,CAAS,WAAA,EAAa,CAAA,EAAA,EAAK,aAAa,KAAK,CAAA,CAAA,CAAA;AAClF,MAAA,YAAA,GAAe,CAAA,wBAAA,EAA2B,SAAS,QAAA,CAAS,CAAC,EAAE,WAAA,EAAa,KAAK,UAAU,CAAA,CAAA,CAAA;AAAA,IAC7F;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,SAAA,EAAW,OAAA,EAAS,YAAA,EAAa;AAC5C;AAMO,SAAS,qBACd,IAAA,EACA,WAAA,EACA,WACA,UAAA,EACA,gBAAA,EACA,UAAU,CAAA,EACV;AAppBF,EAAA,IAAA,EAAA;AAqpBE,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAA,CAAO,EAAA,GAAA,WAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,WAAA,CAAa,KAAA,KAAb,YAAsB,GAAG,CAAA;AAC9C,EAAA,MAAM,iBAAA,GAAoB,IAAA;AAC1B,EAAA,MAAM,YAAA,GAAe,EAAA;AACrB,EAAA,MAAM,UAAU,OAAA,GAAU,CAAA;AAE1B,EAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AAClD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7B,IAAA,MAAM,QAAQ,EAAC;AACf,IAAA,IAAI,WAAA,GAAc,EAAA;AAClB,IAAA,IAAI,SAAA,GAAY,CAAA;AAChB,IAAA,IAAI,UAAA,GAAa,CAAA;AAGjB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,MAAM,WAAA,GAAc,MAAM,CAAC,CAAA;AAC3B,MAAA,IAAI,YAAY,SAAA,CAAU,WAAA,CAAY,WAAA,GAAc,GAAA,GAAM,WAAW,CAAA,CAAE,KAAA;AAEvE,MAAA,IAAI,SAAA,GAAY,QAAQ,OAAA,EAAS;AAC/B,QAAA,WAAA,IAAe,GAAA,GAAM,WAAA;AACrB,QAAA,SAAA,EAAA;AAAA,MACF,CAAA,MAAO;AACL,QAAA,KAAA,CAAM,IAAA,CAAK;AAAA,UACT,KAAA,EAAO,SAAA;AAAA,UACP,IAAA,EAAM;AAAA,SACP,CAAA;AAED,QAAA,WAAA,GAAc,WAAA;AACd,QAAA,SAAA,GAAY,CAAA;AAAA,MACd;AAAA,IACF;AAKA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,IAAI,KAAA,CAAM,CAAC,CAAA,CAAE,KAAA,GAAQ,KAAA,EAAO;AAC1B,QAAA,IAAI,KAAA,GAAQ,KAAK,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,CAAE,KAAA,GAAQ,KAAK,CAAA,GAAI,CAAA;AACjD,QAAA,UAAA,IAAc,KAAA;AAAA,MAChB;AAAA,IACF;AAIA,IAAA,IAAI,UAAA,GAAa,MAAM,MAAA,GAAS,UAAA;AAChC,IAAA,IAAI,MAAA,GAAS,EAAA;AACb,IAAA,IAAI,aAAa,CAAA,EAAG;AAClB,MAAA,MAAA,GAAS,aAAa,UAAA,GAAa,iBAAA;AAAA,IACrC,CAAA,MAAO;AACL,MAAA,MAAA,GAAS,aAAa,UAAA,GAAa,YAAA;AAAA,IACrC;AACA,IAAA,MAAA,IAAU,OAAA;AAEV,IAAA,OAAO,EAAE,OAAO,MAAA,EAAO;AAAA,EACzB;AAEA,EAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,gBAAA,EAAiB;AAC3C;AAOO,SAAS,iBAAA,CAAkB,aAAgC1B,MAAA,EAAiB;AAptBnF,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAqtBE,EAAA,IAAI,YAAA,GAAe,KAAA,CAAA;AACnB,EAAA,MAAM,WAAA,GAAc,CAAA;AAKpB,EAAA,IAAA,CAAI,uBAAY,QAAA,CAAS,MAAA,KAArB,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAA6B,WAAA,KAA7B,mBAA0C,QAAA,EAAU;AACtD,IAAA,MAAM,YAAA,GAAeA,OAAK,MAAA,CAAO,MAAA,CAAO,CAAC,KAAA,KAAiB,KAAA,CAAM,IAAA,KAASD,cAAA,CAAU,MAAM,CAAA;AAEzF,IAAA,IAAI,YAAA,CAAa,UAAU,CAAA,IAAK,YAAA,CAAa,CAAC,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA,EAAG;AACjE,MAAA,MAAM,SAAA,GAAY,YAAA,CAAa,CAAC,CAAA,CAAE,MAAA,CAAO,MAAA;AACzC,MAAA,IAAI,aAAA,GAAgB,CAAA;AAIpB,MAAA,IAAI,aAAa,EAAA,EAAI;AACnB,QAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAChC,UAAA,MAAM,WAAA,GAAA,CAAc,EAAA,GAAA,CAAA,EAAA,GAAA,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,IAAK,IAAI,CAAA,KAAlC,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAqC,MAAA,KAArC,IAAA,GAAA,EAAA,GAA+C,CAAA;AACnE,UAAA,IAAI,cAAc,aAAA,EAAe;AAC/B,YAAA,aAAA,GAAgB,WAAA;AAChB,YAAA,YAAA,GAAe,KAAA;AAAA,UACjB;AAAA,QACF;AAAA,MACF,CAAA,MAGK;AACH,QAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAMhC,UAAA,MAAM,IAAA,GAAO6B,iBAAA,CAAW,KAAA,CAAM,MAAA,EAAQ,WAAW,CAAA;AACjD,UAAA,MAAM,UAAA,GAAA,CAAA,CAAA,CAAc,EAAA,GAAA,IAAA,CAAK,CAAC,CAAA,KAAN,mBAAS,MAAA,KAAA,CAAS,EAAA,GAAA,IAAA,CAAK,CAAC,CAAA,KAAN,mBAAS,MAAA,CAAA,IAAA,CAAS,EAAA,GAAA,IAAA,CAAK,CAAC,CAAA,KAAN,mBAAS,MAAA,CAAA,IAAU,CAAA;AAE3E,UAAA,IAAI,aAAa,aAAA,EAAe;AAC9B,YAAA,aAAA,GAAgB,UAAA;AAChB,YAAA,YAAA,GAAe,KAAA;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,YAAA;AACT;AAaO,MAAM,+BAAA,GAAkC,CAAC,KAAA,EAAoB,OAAA,KAA4B;AAC9F,EAAA,MAAM,4BAA4B,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,OAAA,CAAQ,mCAAS,MAAM,CAAA;AAC7E,EAAA,MAAM,iBAAiB,KAAA,CAAM,MAAA,KAAW,KAAK,CAAC,OAAA,CAAQ,mCAAS,MAAM,CAAA;AAErE,EAAA,OAAO,EAAE,gBAAgB,yBAAA,EAA0B;AACrD;AAEA,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAkD;AAC9E,EAAA,OAAO,KAAA,CAAM,WAAW,KAAA,CAAM,aAAA;AAChC,CAAA;AAOO,MAAM,qBAAA,GAAwB,CAAC,gBAAA,KAAsE;AAC1G,EAAA,OAAO,CAAC,KAAA,KAAyC;AAC/C,IAAA,IAAI,oBAAA,CAAqB,KAAK,CAAA,EAAG;AAC/B,MAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,KAAA;AAC7B,MAAA,gBAAA,CAAiB,EAAE,OAAA,EAAS,OAAA,EAAS,CAAA;AAAA,IACvC;AAAA,EACF,CAAA;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;"}