{"version":3,"file":"datagrid-model.cjs","names":[],"sources":["../../../src/inputs/datagrid/datagrid-model.ts"],"sourcesContent":["import { computed, type Readable, signal, watch } from '@vielzeug/ripple';\n\nexport type SortDirection = 'asc' | 'desc' | 'none';\n\nexport type SortState = {\n  direction: SortDirection;\n  key: string;\n};\n\nexport type DataGridColumn<T = Record<string, unknown>> = {\n  align?: 'left' | 'center' | 'right';\n  cell?: (item: T) => string;\n  headerLabel?: string;\n  key: string;\n  label: string;\n  renderExpanded?: (item: T) => string;\n  resizable?: boolean;\n  sortable?: boolean;\n  sortValue?: (item: T) => number | string;\n  width?: string;\n};\n\nexport type SelectionMode = 'multi' | 'none' | 'single';\n\nexport type FilterOption = {\n  key: string;\n  label: string;\n  operators?: { label: string; value: string }[];\n  options: { label?: string; value: string }[];\n};\n\nexport type FilterOperator = 'contains' | 'equals' | 'gt' | 'lt';\n\nexport type FilterRule = {\n  operator: FilterOperator;\n  values: Set<string>;\n};\n\nexport type DataGridView = {\n  id: string;\n  label: string;\n};\n\nexport type DataGridModelOptions<T = Record<string, unknown>> = {\n  clientSide: Readable<boolean>;\n  columns: Readable<DataGridColumn<T>[]>;\n  filterOptions: Readable<FilterOption[] | undefined>;\n  getRowKey: (item: T) => string;\n  items: Readable<T[]>;\n  onSelectionChange?: (keys: Set<string>) => void;\n  onSortChange?: (sort: SortState) => void;\n  pageSize: Readable<number>;\n  selectionMode: Readable<SelectionMode>;\n  sortMode: Readable<'client' | 'server'>;\n};\n\nexport type DataGridModel<T = Record<string, unknown>> = {\n  activateFilterKey(key: string): void;\n  clearAllFilters(): void;\n  clearSelection(): void;\n  readonly currentPageItems: Readable<T[]>;\n  readonly filterDefs: Readable<FilterOption[]>;\n  readonly filteredRows: Readable<T[]>;\n  readonly filterValues: Readable<Map<string, FilterRule>>;\n  goToPage(index: number): void;\n  readonly hasNextPage: Readable<boolean>;\n  readonly hasPrevPage: Readable<boolean>;\n  readonly hiddenColumns: Readable<Set<string>>;\n  isAllSelected(): boolean;\n  nextPage(): void;\n  readonly pageCount: Readable<number>;\n  readonly pageIndex: Readable<number>;\n  prevPage(): void;\n  removeFilter(key: string): void;\n  resetFilters(): void;\n  resetSearch(): void;\n  readonly searchActive: Readable<boolean>;\n  readonly searchQuery: Readable<string>;\n  selectAll(): void;\n  readonly selectedKeys: Readable<ReadonlySet<string>>;\n  readonly selectedRows: Readable<T[]>;\n  setActiveFilterKeys(keys: string[]): void;\n  setFilter(key: string, values: string[]): void;\n  setFilterOperator(key: string, operator: FilterOperator): void;\n  setSearchQuery(query: string): void;\n  setSelection(keys: Set<string>): void;\n  sortBy(key: string): void;\n  readonly sortState: Readable<SortState>;\n  sortTo(key: string, direction: SortDirection): void;\n  toggleColumnVisibility(key: string): void;\n  toggleRow(key: string): void;\n  toggleSearch(): void;\n  readonly totalItems: Readable<number>;\n  readonly visibleColumns: Readable<DataGridColumn<T>[]>;\n};\n\nconst DEFAULT_OPERATORS: { label: string; value: FilterOperator }[] = [\n  { label: 'Contains', value: 'contains' },\n  { label: 'Equals', value: 'equals' },\n  { label: 'Greater than', value: 'gt' },\n  { label: 'Less than', value: 'lt' },\n];\n\n/**\n * Feature-owned state and transform pipeline for `ore-datagrid`.\n *\n * Rows flow through query, filters, sorting, and pagination in order. Selection\n * and column visibility share the same model so every interactive grid concern\n * has one reactive owner. Source-backed grids retain their server-owned rows by\n * setting `clientSide` to false.\n */\nexport const createDataGridModel = <T extends Record<string, unknown>>(\n  options: DataGridModelOptions<T>,\n): DataGridModel<T> => {\n  const searchQuery = signal('');\n  const searchActive = signal(false);\n  const hiddenColumns = signal(new Set<string>());\n  const activeFilterKeys = signal(new Set<string>());\n  const filterValues = signal(new Map<string, FilterRule>());\n  const sortKey = signal('');\n  const sortDirection = signal<SortDirection>('none');\n  const selectedKeys = signal(new Set<string>());\n  const pageIndex = signal(0);\n\n  const columnKeys = computed(() => new Set(options.columns.value.map((column) => column.key)));\n  const visibleColumns = computed(() => options.columns.value.filter((column) => !hiddenColumns.value.has(column.key)));\n\n  const colOptions = computed(() => {\n    const externalKeys = new Set((options.filterOptions.value ?? []).map((filter) => filter.key));\n    const activeKeys = [...activeFilterKeys.value].filter((key) => !externalKeys.has(key));\n\n    if (!activeKeys.length) return new Map<string, { label: string; value: string }[]>();\n\n    const derived = new Map<string, { label: string; value: string }[]>();\n\n    for (const key of activeKeys) {\n      const seen = new Set<string>();\n      const values: { label: string; value: string }[] = [];\n\n      for (const row of options.items.value) {\n        const value = row[key];\n        const stringValue = value == null ? '' : String(value);\n\n        if (!seen.has(stringValue)) {\n          seen.add(stringValue);\n          values.push({ label: stringValue || '(empty)', value: stringValue });\n        }\n      }\n\n      derived.set(key, values);\n    }\n\n    return derived;\n  });\n\n  const filterDefs = computed<FilterOption[]>(() => {\n    const provided = options.filterOptions.value ?? [];\n    const providedKeys = new Set(provided.map((filter) => filter.key));\n    const derived = [...activeFilterKeys.value]\n      .filter((key) => !providedKeys.has(key))\n      .map((key) => {\n        const column = options.columns.value.find((candidate) => candidate.key === key);\n\n        return {\n          key,\n          label: column?.label ?? key,\n          operators: DEFAULT_OPERATORS,\n          options: colOptions.value.get(key) ?? [],\n        };\n      });\n\n    return [...provided.map((filter) => ({ ...filter, operators: filter.operators ?? DEFAULT_OPERATORS })), ...derived];\n  });\n\n  const searchedRows = computed(() => {\n    const rows = options.items.value;\n\n    if (!options.clientSide.value) return rows;\n\n    const query = searchQuery.value.trim().toLowerCase();\n\n    if (!query) return rows;\n\n    return rows.filter((row) =>\n      Object.values(row).some((value) => value != null && String(value).toLowerCase().includes(query)),\n    );\n  });\n\n  const filteredRows = computed(() => {\n    const rows = searchedRows.value;\n\n    if (!options.clientSide.value || !filterValues.value.size) return rows;\n\n    return rows.filter((row) => {\n      for (const [key, rule] of filterValues.value) {\n        if (!rule.values.size || !columnKeys.value.has(key)) continue;\n\n        const value = row[key];\n        const stringValue = value == null ? '' : String(value);\n\n        if (rule.operator === 'equals' && !rule.values.has(stringValue)) return false;\n\n        if (\n          rule.operator === 'contains' &&\n          ![...rule.values].some((target) => stringValue.toLowerCase().includes(target.toLowerCase()))\n        ) {\n          return false;\n        }\n\n        if (rule.operator === 'gt' || rule.operator === 'lt') {\n          const numericValue = parseFloat(stringValue);\n          const targets = [...rule.values].map(parseFloat).filter((target) => !Number.isNaN(target));\n\n          if (!targets.length) continue;\n\n          if (rule.operator === 'gt' && !targets.some((target) => numericValue > target)) return false;\n\n          if (rule.operator === 'lt' && !targets.some((target) => numericValue < target)) return false;\n        }\n      }\n\n      return true;\n    });\n  });\n\n  const sortState = computed<SortState>(() => ({ direction: sortDirection.value, key: sortKey.value }));\n  const sortedRows = computed(() => {\n    const rows = filteredRows.value;\n\n    if (!options.clientSide.value || options.sortMode.value === 'server') return rows;\n\n    const { direction, key } = sortState.value;\n\n    if (!key || direction === 'none') return rows;\n\n    const column = options.columns.value.find((candidate) => candidate.key === key);\n\n    return rows.slice().sort((a, b) => {\n      const aValue = column?.sortValue ? column.sortValue(a) : (a[key] as number | string);\n      const bValue = column?.sortValue ? column.sortValue(b) : (b[key] as number | string);\n      const comparison =\n        typeof aValue === 'number' && typeof bValue === 'number'\n          ? aValue - bValue\n          : String(aValue ?? '').localeCompare(String(bValue ?? ''));\n\n      return direction === 'asc' ? comparison : -comparison;\n    });\n  });\n\n  const totalItems = computed(() => sortedRows.value.length);\n  const pageCount = computed(() => {\n    const size = options.pageSize.value;\n\n    return Math.ceil(totalItems.value / (size <= 0 ? Number.MAX_SAFE_INTEGER : size));\n  });\n  const safePageIndex = computed(() => (pageCount.value ? Math.min(pageIndex.value, pageCount.value - 1) : -1));\n  const currentPageItems = computed(() => {\n    const size = options.pageSize.value;\n\n    if (size <= 0) return sortedRows.value;\n\n    const start = safePageIndex.value * size;\n\n    return sortedRows.value.slice(start, start + size);\n  });\n  const hasNextPage = computed(() => pageCount.value > 0 && safePageIndex.value < pageCount.value - 1);\n  const hasPrevPage = computed(() => safePageIndex.value > 0);\n  const selectedRows = computed(() =>\n    options.items.value.filter((item) => selectedKeys.value.has(options.getRowKey(item))),\n  );\n\n  watch(\n    columnKeys,\n    (keys) => {\n      const nextActiveKeys = new Set([...activeFilterKeys.value].filter((key) => keys.has(key)));\n      const nextValues = new Map([...filterValues.value].filter(([key]) => keys.has(key)));\n\n      if (nextActiveKeys.size !== activeFilterKeys.value.size) activeFilterKeys.value = nextActiveKeys;\n\n      if (nextValues.size !== filterValues.value.size) filterValues.value = nextValues;\n    },\n    { immediate: false },\n  );\n\n  watch(sortedRows, () => {\n    pageIndex.value = 0;\n  });\n\n  const commitSelection = (next: Set<string>): void => {\n    selectedKeys.value = next;\n    options.onSelectionChange?.(next);\n  };\n\n  const setFilter = (key: string, values: string[]): void => {\n    const next = new Map(filterValues.value);\n\n    if (values.length) {\n      next.set(key, { operator: next.get(key)?.operator ?? 'contains', values: new Set(values) });\n    } else {\n      next.delete(key);\n    }\n\n    filterValues.value = next;\n  };\n\n  const setFilterOperator = (key: string, operator: FilterOperator): void => {\n    const rule = filterValues.value.get(key);\n\n    if (rule) filterValues.value = new Map(filterValues.value).set(key, { ...rule, operator });\n  };\n\n  const sortTo = (key: string, direction: SortDirection): void => {\n    sortKey.value = direction === 'none' ? '' : key;\n    sortDirection.value = direction;\n    pageIndex.value = 0;\n    options.onSortChange?.(sortState.value);\n  };\n\n  return {\n    activateFilterKey: (key) => {\n      if (!activeFilterKeys.value.has(key)) activeFilterKeys.value = new Set([...activeFilterKeys.value, key]);\n    },\n    clearAllFilters: () => {\n      activeFilterKeys.value = new Set();\n      filterValues.value = new Map();\n    },\n    clearSelection: () => commitSelection(new Set()),\n    currentPageItems,\n    filterDefs,\n    filteredRows,\n    filterValues,\n    goToPage: (index) => {\n      if (Number.isFinite(index)) pageIndex.value = Math.max(0, index);\n    },\n    hasNextPage,\n    hasPrevPage,\n    hiddenColumns,\n    isAllSelected: () => {\n      const page = currentPageItems.value;\n\n      return page.length > 0 && page.every((item) => selectedKeys.value.has(options.getRowKey(item)));\n    },\n    nextPage: () => {\n      if (hasNextPage.value) pageIndex.value = safePageIndex.value + 1;\n    },\n    pageCount,\n    pageIndex: safePageIndex,\n    prevPage: () => {\n      if (hasPrevPage.value) pageIndex.value = safePageIndex.value - 1;\n    },\n    removeFilter: (key) => {\n      const nextActiveKeys = new Set(activeFilterKeys.value);\n\n      nextActiveKeys.delete(key);\n      activeFilterKeys.value = nextActiveKeys;\n\n      const nextValues = new Map(filterValues.value);\n\n      nextValues.delete(key);\n      filterValues.value = nextValues;\n    },\n    resetFilters: () => {\n      activeFilterKeys.value = new Set();\n      filterValues.value = new Map();\n    },\n    resetSearch: () => {\n      searchQuery.value = '';\n      searchActive.value = false;\n    },\n    searchActive,\n    searchQuery,\n    selectAll: () => {\n      if (options.selectionMode.value !== 'multi') return;\n\n      const next = new Set(selectedKeys.value);\n\n      if (currentPageItems.value.every((item) => next.has(options.getRowKey(item)))) {\n        for (const item of currentPageItems.value) next.delete(options.getRowKey(item));\n      } else {\n        for (const item of currentPageItems.value) next.add(options.getRowKey(item));\n      }\n\n      commitSelection(next);\n    },\n    selectedKeys: computed(() => new Set(selectedKeys.value)),\n    selectedRows,\n    setActiveFilterKeys: (keys) => {\n      const nextActiveKeys = new Set(keys);\n\n      activeFilterKeys.value = nextActiveKeys;\n      filterValues.value = new Map([...filterValues.value].filter(([key]) => nextActiveKeys.has(key)));\n    },\n    setFilter,\n    setFilterOperator,\n    setSearchQuery: (query) => {\n      searchQuery.value = query;\n    },\n    setSelection: (keys) => commitSelection(new Set(keys)),\n    sortBy: (key) => {\n      const nextDirection =\n        sortKey.value !== key\n          ? 'asc'\n          : sortDirection.value === 'asc'\n            ? 'desc'\n            : sortDirection.value === 'desc'\n              ? 'none'\n              : 'asc';\n\n      sortTo(nextDirection === 'none' ? '' : key, nextDirection);\n    },\n    sortState,\n    sortTo,\n    toggleColumnVisibility: (key) => {\n      const next = new Set(hiddenColumns.value);\n\n      if (next.has(key)) next.delete(key);\n      else next.add(key);\n\n      hiddenColumns.value = next;\n    },\n    toggleRow: (key) => {\n      if (options.selectionMode.value === 'none') return;\n\n      const next = new Set(selectedKeys.value);\n\n      if (next.has(key)) next.delete(key);\n      else {\n        if (options.selectionMode.value === 'single') next.clear();\n\n        next.add(key);\n      }\n\n      commitSelection(next);\n    },\n    toggleSearch: () => {\n      if (searchActive.value) searchQuery.value = '';\n\n      searchActive.value = !searchActive.value;\n    },\n    totalItems,\n    visibleColumns,\n  };\n};\n"],"mappings":"kCAgGA,IAAM,EAAgE,CACpE,CAAE,MAAO,WAAY,MAAO,UAAW,EACvC,CAAE,MAAO,SAAU,MAAO,QAAS,EACnC,CAAE,MAAO,eAAgB,MAAO,IAAK,EACrC,CAAE,MAAO,YAAa,MAAO,IAAK,CACpC,EAUa,EACX,GACqB,CACrB,IAAM,GAAA,EAAc,EAAA,OAAA,CAAO,EAAE,EACvB,GAAA,EAAe,EAAA,OAAA,CAAO,EAAK,EAC3B,GAAA,EAAgB,EAAA,OAAA,CAAO,IAAI,GAAa,EACxC,GAAA,EAAmB,EAAA,OAAA,CAAO,IAAI,GAAa,EAC3C,GAAA,EAAe,EAAA,OAAA,CAAO,IAAI,GAAyB,EACnD,GAAA,EAAU,EAAA,OAAA,CAAO,EAAE,EACnB,GAAA,EAAgB,EAAA,OAAA,CAAsB,MAAM,EAC5C,GAAA,EAAe,EAAA,OAAA,CAAO,IAAI,GAAa,EACvC,GAAA,EAAY,EAAA,OAAA,CAAO,CAAC,EAEpB,GAAA,EAAa,EAAA,SAAA,KAAe,IAAI,IAAI,EAAQ,QAAQ,MAAM,IAAK,GAAW,EAAO,GAAG,CAAC,CAAC,EACtF,GAAA,EAAiB,EAAA,SAAA,KAAe,EAAQ,QAAQ,MAAM,OAAQ,GAAW,CAAC,EAAc,MAAM,IAAI,EAAO,GAAG,CAAC,CAAC,EAE9G,GAAA,EAAa,EAAA,SAAA,KAAe,CAChC,IAAM,EAAe,IAAI,KAAK,EAAQ,cAAc,OAAS,CAAC,EAAA,CAAG,IAAK,GAAW,EAAO,GAAG,CAAC,EACtF,EAAa,CAAC,GAAG,EAAiB,KAAK,CAAC,CAAC,OAAQ,GAAQ,CAAC,EAAa,IAAI,CAAG,CAAC,EAErF,GAAI,CAAC,EAAW,OAAQ,OAAO,IAAI,IAEnC,IAAM,EAAU,IAAI,IAEpB,IAAK,IAAM,KAAO,EAAY,CAC5B,IAAM,EAAO,IAAI,IACX,EAA6C,CAAC,EAEpD,IAAK,IAAM,KAAO,EAAQ,MAAM,MAAO,CACrC,IAAM,EAAQ,EAAI,GACZ,EAAc,GAAS,KAAO,GAAK,OAAO,CAAK,EAEhD,EAAK,IAAI,CAAW,IACvB,EAAK,IAAI,CAAW,EACpB,EAAO,KAAK,CAAE,MAAO,GAAe,UAAW,MAAO,CAAY,CAAC,EAEvE,CAEA,EAAQ,IAAI,EAAK,CAAM,CACzB,CAEA,OAAO,CACT,CAAC,EAEK,GAAA,EAAa,EAAA,SAAA,KAA+B,CAChD,IAAM,EAAW,EAAQ,cAAc,OAAS,CAAC,EAC3C,EAAe,IAAI,IAAI,EAAS,IAAK,GAAW,EAAO,GAAG,CAAC,EAC3D,EAAU,CAAC,GAAG,EAAiB,KAAK,CAAC,CACxC,OAAQ,GAAQ,CAAC,EAAa,IAAI,CAAG,CAAC,CAAC,CACvC,IAAK,IAGG,CACL,MACA,MAJa,EAAQ,QAAQ,MAAM,KAAM,GAAc,EAAU,MAAQ,CAIlE,CAAA,EAAQ,OAAS,EACxB,UAAW,EACX,QAAS,EAAW,MAAM,IAAI,CAAG,GAAK,CAAC,CACzC,EACD,EAEH,MAAO,CAAC,GAAG,EAAS,IAAK,IAAY,CAAE,GAAG,EAAQ,UAAW,EAAO,WAAa,CAAkB,EAAE,EAAG,GAAG,CAAO,CACpH,CAAC,EAEK,GAAA,EAAe,EAAA,SAAA,KAAe,CAClC,IAAM,EAAO,EAAQ,MAAM,MAE3B,GAAI,CAAC,EAAQ,WAAW,MAAO,OAAO,EAEtC,IAAM,EAAQ,EAAY,MAAM,KAAK,CAAC,CAAC,YAAY,EAInD,OAFK,EAEE,EAAK,OAAQ,GAClB,OAAO,OAAO,CAAG,CAAC,CAAC,KAAM,GAAU,GAAS,MAAQ,OAAO,CAAK,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,CAAK,CAAC,CACjG,EAJmB,CAKrB,CAAC,EAEK,GAAA,EAAe,EAAA,SAAA,KAAe,CAClC,IAAM,EAAO,EAAa,MAI1B,MAFI,CAAC,EAAQ,WAAW,OAAS,CAAC,EAAa,MAAM,KAAa,EAE3D,EAAK,OAAQ,GAAQ,CAC1B,IAAK,GAAM,CAAC,EAAK,KAAS,EAAa,MAAO,CAC5C,GAAI,CAAC,EAAK,OAAO,MAAQ,CAAC,EAAW,MAAM,IAAI,CAAG,EAAG,SAErD,IAAM,EAAQ,EAAI,GACZ,EAAc,GAAS,KAAO,GAAK,OAAO,CAAK,EAIrD,GAFI,EAAK,WAAa,UAAY,CAAC,EAAK,OAAO,IAAI,CAAW,GAG5D,EAAK,WAAa,YAClB,CAAC,CAAC,GAAG,EAAK,MAAM,CAAC,CAAC,KAAM,GAAW,EAAY,YAAY,CAAC,CAAC,SAAS,EAAO,YAAY,CAAC,CAAC,EAE3F,MAAO,GAGT,GAAI,EAAK,WAAa,MAAQ,EAAK,WAAa,KAAM,CACpD,IAAM,EAAe,WAAW,CAAW,EACrC,EAAU,CAAC,GAAG,EAAK,MAAM,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,OAAQ,GAAW,CAAC,OAAO,MAAM,CAAM,CAAC,EAEzF,GAAI,CAAC,EAAQ,OAAQ,SAIrB,GAFI,EAAK,WAAa,MAAQ,CAAC,EAAQ,KAAM,GAAW,EAAe,CAAM,GAEzE,EAAK,WAAa,MAAQ,CAAC,EAAQ,KAAM,GAAW,EAAe,CAAM,EAAG,MAAO,EACzF,CACF,CAEA,MAAO,EACT,CAAC,CACH,CAAC,EAEK,GAAA,EAAY,EAAA,SAAA,MAA2B,CAAE,UAAW,EAAc,MAAO,IAAK,EAAQ,KAAM,EAAE,EAC9F,GAAA,EAAa,EAAA,SAAA,KAAe,CAChC,IAAM,EAAO,EAAa,MAE1B,GAAI,CAAC,EAAQ,WAAW,OAAS,EAAQ,SAAS,QAAU,SAAU,OAAO,EAE7E,GAAM,CAAE,YAAW,OAAQ,EAAU,MAErC,GAAI,CAAC,GAAO,IAAc,OAAQ,OAAO,EAEzC,IAAM,EAAS,EAAQ,QAAQ,MAAM,KAAM,GAAc,EAAU,MAAQ,CAAG,EAE9E,OAAO,EAAK,MAAM,CAAC,CAAC,MAAM,EAAG,IAAM,CACjC,IAAM,EAAS,GAAQ,UAAY,EAAO,UAAU,CAAC,EAAK,EAAE,GACtD,EAAS,GAAQ,UAAY,EAAO,UAAU,CAAC,EAAK,EAAE,GACtD,EACJ,OAAO,GAAW,UAAY,OAAO,GAAW,SAC5C,EAAS,EACT,OAAO,GAAU,EAAE,CAAC,CAAC,cAAc,OAAO,GAAU,EAAE,CAAC,EAE7D,OAAO,IAAc,MAAQ,EAAa,CAAC,CAC7C,CAAC,CACH,CAAC,EAEK,GAAA,EAAa,EAAA,SAAA,KAAe,EAAW,MAAM,MAAM,EACnD,GAAA,EAAY,EAAA,SAAA,KAAe,CAC/B,IAAM,EAAO,EAAQ,SAAS,MAE9B,OAAO,KAAK,KAAK,EAAW,OAAS,GAAQ,UAA8B,EAAK,CAClF,CAAC,EACK,GAAA,EAAgB,EAAA,SAAA,KAAgB,EAAU,MAAQ,KAAK,IAAI,EAAU,MAAO,EAAU,MAAQ,CAAC,EAAI,EAAG,EACtG,GAAA,EAAmB,EAAA,SAAA,KAAe,CACtC,IAAM,EAAO,EAAQ,SAAS,MAE9B,GAAI,GAAQ,EAAG,OAAO,EAAW,MAEjC,IAAM,EAAQ,EAAc,MAAQ,EAEpC,OAAO,EAAW,MAAM,MAAM,EAAO,EAAQ,CAAI,CACnD,CAAC,EACK,GAAA,EAAc,EAAA,SAAA,KAAe,EAAU,MAAQ,GAAK,EAAc,MAAQ,EAAU,MAAQ,CAAC,EAC7F,GAAA,EAAc,EAAA,SAAA,KAAe,EAAc,MAAQ,CAAC,EACpD,GAAA,EAAe,EAAA,SAAA,KACnB,EAAQ,MAAM,MAAM,OAAQ,GAAS,EAAa,MAAM,IAAI,EAAQ,UAAU,CAAI,CAAC,CAAC,CACtF,GAEA,EAAA,EAAA,MAAA,CACE,EACC,GAAS,CACR,IAAM,EAAiB,IAAI,IAAI,CAAC,GAAG,EAAiB,KAAK,CAAC,CAAC,OAAQ,GAAQ,EAAK,IAAI,CAAG,CAAC,CAAC,EACnF,EAAa,IAAI,IAAI,CAAC,GAAG,EAAa,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAS,EAAK,IAAI,CAAG,CAAC,CAAC,EAE/E,EAAe,OAAS,EAAiB,MAAM,OAAM,EAAiB,MAAQ,GAE9E,EAAW,OAAS,EAAa,MAAM,OAAM,EAAa,MAAQ,EACxE,EACA,CAAE,UAAW,EAAM,CACrB,GAEA,EAAA,EAAA,MAAA,CAAM,MAAkB,CACtB,EAAU,MAAQ,CACpB,CAAC,EAED,IAAM,EAAmB,GAA4B,CACnD,EAAa,MAAQ,EACrB,EAAQ,oBAAoB,CAAI,CAClC,EAEM,GAAa,EAAa,IAA2B,CACzD,IAAM,EAAO,IAAI,IAAI,EAAa,KAAK,EAEnC,EAAO,OACT,EAAK,IAAI,EAAK,CAAE,SAAU,EAAK,IAAI,CAAG,CAAC,EAAE,UAAY,WAAY,OAAQ,IAAI,IAAI,CAAM,CAAE,CAAC,EAE1F,EAAK,OAAO,CAAG,EAGjB,EAAa,MAAQ,CACvB,EAEM,GAAqB,EAAa,IAAmC,CACzE,IAAM,EAAO,EAAa,MAAM,IAAI,CAAG,EAEnC,IAAM,EAAa,MAAQ,IAAI,IAAI,EAAa,KAAK,CAAC,CAAC,IAAI,EAAK,CAAE,GAAG,EAAM,UAAS,CAAC,EAC3F,EAEM,GAAU,EAAa,IAAmC,CAC9D,EAAQ,MAAQ,IAAc,OAAS,GAAK,EAC5C,EAAc,MAAQ,EACtB,EAAU,MAAQ,EAClB,EAAQ,eAAe,EAAU,KAAK,CACxC,EAEA,MAAO,CACL,kBAAoB,GAAQ,CACrB,EAAiB,MAAM,IAAI,CAAG,IAAG,EAAiB,MAAQ,IAAI,IAAI,CAAC,GAAG,EAAiB,MAAO,CAAG,CAAC,EACzG,EACA,oBAAuB,CACrB,EAAiB,MAAQ,IAAI,IAC7B,EAAa,MAAQ,IAAI,GAC3B,EACA,mBAAsB,EAAgB,IAAI,GAAK,EAC/C,mBACA,aACA,eACA,eACA,SAAW,GAAU,CACf,OAAO,SAAS,CAAK,IAAG,EAAU,MAAQ,KAAK,IAAI,EAAG,CAAK,EACjE,EACA,cACA,cACA,gBACA,kBAAqB,CACnB,IAAM,EAAO,EAAiB,MAE9B,OAAO,EAAK,OAAS,GAAK,EAAK,MAAO,GAAS,EAAa,MAAM,IAAI,EAAQ,UAAU,CAAI,CAAC,CAAC,CAChG,EACA,aAAgB,CACV,EAAY,QAAO,EAAU,MAAQ,EAAc,MAAQ,EACjE,EACA,YACA,UAAW,EACX,aAAgB,CACV,EAAY,QAAO,EAAU,MAAQ,EAAc,MAAQ,EACjE,EACA,aAAe,GAAQ,CACrB,IAAM,EAAiB,IAAI,IAAI,EAAiB,KAAK,EAErD,EAAe,OAAO,CAAG,EACzB,EAAiB,MAAQ,EAEzB,IAAM,EAAa,IAAI,IAAI,EAAa,KAAK,EAE7C,EAAW,OAAO,CAAG,EACrB,EAAa,MAAQ,CACvB,EACA,iBAAoB,CAClB,EAAiB,MAAQ,IAAI,IAC7B,EAAa,MAAQ,IAAI,GAC3B,EACA,gBAAmB,CACjB,EAAY,MAAQ,GACpB,EAAa,MAAQ,EACvB,EACA,eACA,cACA,cAAiB,CACf,GAAI,EAAQ,cAAc,QAAU,QAAS,OAE7C,IAAM,EAAO,IAAI,IAAI,EAAa,KAAK,EAEvC,GAAI,EAAiB,MAAM,MAAO,GAAS,EAAK,IAAI,EAAQ,UAAU,CAAI,CAAC,CAAC,EAC1E,IAAK,IAAM,KAAQ,EAAiB,MAAO,EAAK,OAAO,EAAQ,UAAU,CAAI,CAAC,OAE9E,IAAK,IAAM,KAAQ,EAAiB,MAAO,EAAK,IAAI,EAAQ,UAAU,CAAI,CAAC,EAG7E,EAAgB,CAAI,CACtB,EACA,cAAA,EAAc,EAAA,SAAA,KAAe,IAAI,IAAI,EAAa,KAAK,CAAC,EACxD,eACA,oBAAsB,GAAS,CAC7B,IAAM,EAAiB,IAAI,IAAI,CAAI,EAEnC,EAAiB,MAAQ,EACzB,EAAa,MAAQ,IAAI,IAAI,CAAC,GAAG,EAAa,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAS,EAAe,IAAI,CAAG,CAAC,CAAC,CACjG,EACA,YACA,oBACA,eAAiB,GAAU,CACzB,EAAY,MAAQ,CACtB,EACA,aAAe,GAAS,EAAgB,IAAI,IAAI,CAAI,CAAC,EACrD,OAAS,GAAQ,CACf,IAAM,EACJ,EAAQ,QAAU,EAEd,EAAc,QAAU,MACtB,OACA,EAAc,QAAU,OACtB,OACA,MALJ,MAON,EAAO,IAAkB,OAAS,GAAK,EAAK,CAAa,CAC3D,EACA,YACA,SACA,uBAAyB,GAAQ,CAC/B,IAAM,EAAO,IAAI,IAAI,EAAc,KAAK,EAEpC,EAAK,IAAI,CAAG,EAAG,EAAK,OAAO,CAAG,EAC7B,EAAK,IAAI,CAAG,EAEjB,EAAc,MAAQ,CACxB,EACA,UAAY,GAAQ,CAClB,GAAI,EAAQ,cAAc,QAAU,OAAQ,OAE5C,IAAM,EAAO,IAAI,IAAI,EAAa,KAAK,EAEnC,EAAK,IAAI,CAAG,EAAG,EAAK,OAAO,CAAG,GAE5B,EAAQ,cAAc,QAAU,UAAU,EAAK,MAAM,EAEzD,EAAK,IAAI,CAAG,GAGd,EAAgB,CAAI,CACtB,EACA,iBAAoB,CACd,EAAa,QAAO,EAAY,MAAQ,IAE5C,EAAa,MAAQ,CAAC,EAAa,KACrC,EACA,aACA,gBACF,CACF"}