{"version":3,"file":"get-renderable-month-event-segments.cjs","names":["getVisibleColumnMap"],"sources":["../../../src/components/MonthView/get-renderable-month-event-segments.ts"],"sourcesContent":["import { DateStringValue, MonthEventPositionData, MonthPositionedEventData } from '../../types';\nimport { getVisibleColumnMap } from './get-visible-columns';\n\nconst DAYS_IN_WEEK = 7;\nconst DAY_WIDTH = 100 / DAYS_IN_WEEK;\n\ninterface GetRenderableMonthEventSegmentsInput {\n  events: MonthPositionedEventData[];\n  groupedByDay: Record<string, MonthPositionedEventData[]>;\n  maxEventsPerDay: number;\n  week: DateStringValue[];\n\n  /** Week-relative indices (0–6) of hidden columns, e.g. weekend days */\n  hiddenColumns?: number[];\n\n  /** Number of visible columns, defaults to 7 */\n  columnsCount?: number;\n}\n\ninterface EventDayRange {\n  startDayIndex: number;\n  endDayIndex: number;\n}\n\ninterface SegmentRange extends EventDayRange {\n  row: number;\n}\n\nexport interface RenderableMonthEventSegment {\n  event: MonthPositionedEventData;\n  position: MonthEventPositionData;\n  clipStart: boolean;\n  clipEnd: boolean;\n  key: string;\n}\n\nfunction getEventDayRange(event: MonthPositionedEventData): EventDayRange {\n  const startDayIndex = Math.max(0, Math.round(event.position.startOffset / DAY_WIDTH));\n  const daysSpanned = Math.max(1, Math.round(event.position.width / DAY_WIDTH));\n\n  return {\n    startDayIndex,\n    endDayIndex: Math.min(DAYS_IN_WEEK - 1, startDayIndex + daysSpanned - 1),\n  };\n}\n\nfunction getFirstAvailableRow(usedRows: Set<number>, maxEventsPerDay: number): number | null {\n  for (let row = 0; row < maxEventsPerDay; row += 1) {\n    if (!usedRows.has(row)) {\n      return row;\n    }\n  }\n\n  return null;\n}\n\nfunction getSegmentHanging(\n  originalHanging: MonthEventPositionData['hanging'],\n  touchesStart: boolean,\n  touchesEnd: boolean\n): MonthEventPositionData['hanging'] {\n  const hangsFromStart =\n    touchesStart && (originalHanging === 'start' || originalHanging === 'both');\n  const hangsFromEnd = touchesEnd && (originalHanging === 'end' || originalHanging === 'both');\n\n  if (hangsFromStart && hangsFromEnd) {\n    return 'both';\n  }\n\n  if (hangsFromStart) {\n    return 'start';\n  }\n\n  if (hangsFromEnd) {\n    return 'end';\n  }\n\n  return 'none';\n}\n\nfunction getSegmentPosition(\n  event: MonthPositionedEventData,\n  segment: SegmentRange,\n  eventRange: EventDayRange,\n  visibleColumnMap: number[],\n  columnsCount: number\n): MonthEventPositionData {\n  const touchesStart = segment.startDayIndex === eventRange.startDayIndex;\n  const touchesEnd = segment.endDayIndex === eventRange.endDayIndex;\n  const startColumn = visibleColumnMap[segment.startDayIndex];\n  const endColumn = visibleColumnMap[segment.endDayIndex];\n\n  return {\n    ...event.position,\n    startOffset: (startColumn / columnsCount) * 100,\n    width: ((endColumn - startColumn + 1) / columnsCount) * 100,\n    row: segment.row,\n    hanging: getSegmentHanging(event.position.hanging, touchesStart, touchesEnd),\n  };\n}\n\nfunction getEventKey(event: MonthPositionedEventData): string | number {\n  return event.id;\n}\n\nexport function getRenderableMonthEventSegments({\n  events,\n  groupedByDay,\n  maxEventsPerDay,\n  week,\n  hiddenColumns = [],\n  columnsCount = DAYS_IN_WEEK,\n}: GetRenderableMonthEventSegmentsInput): RenderableMonthEventSegment[] {\n  const hiddenColumnSet = new Set(hiddenColumns);\n  const visibleColumnMap = getVisibleColumnMap(hiddenColumns);\n  const eventIndexes = new Map<MonthPositionedEventData, number>();\n  const eventRanges = new Map<MonthPositionedEventData, EventDayRange>();\n  const renderRows = new Map<MonthPositionedEventData, Map<number, number>>();\n\n  events.forEach((event, index) => {\n    eventIndexes.set(event, index);\n    eventRanges.set(event, getEventDayRange(event));\n  });\n\n  const setRenderRow = (event: MonthPositionedEventData, dayIndex: number, row: number) => {\n    if (!renderRows.has(event)) {\n      renderRows.set(event, new Map());\n    }\n\n    renderRows.get(event)!.set(dayIndex, row);\n  };\n\n  // Each event remembers the row it was last placed on, so a multi-day bar reuses that row on every\n  // day it covers and stays continuous instead of jumping rows between adjacent days. A different row\n  // is only picked when the preferred one is already taken on that day.\n  const lastRow = new Map<MonthPositionedEventData, number>();\n\n  for (let dayIndex = 0; dayIndex < week.length; dayIndex += 1) {\n    if (hiddenColumnSet.has(dayIndex)) {\n      continue;\n    }\n\n    const dayEvents = groupedByDay[week[dayIndex]] || [];\n    const dayEventIds = new Set(dayEvents.map((event) => getEventKey(event)));\n    const dayWeekEvents = events.filter((event) => {\n      const range = eventRanges.get(event)!;\n      return (\n        dayEventIds.has(getEventKey(event)) &&\n        dayIndex >= range.startDayIndex &&\n        dayIndex <= range.endDayIndex\n      );\n    });\n\n    // On a truncated day only the events whose stable row fits are shown; the rest collapse into the\n    // \"+N more\" indicator. Other days show every event, compacting overflow rows down to fit.\n    const candidates =\n      dayEvents.length > maxEventsPerDay\n        ? dayWeekEvents.filter((event) => event.position.row < maxEventsPerDay)\n        : dayWeekEvents;\n\n    const usedRows = new Set<number>();\n    const sortedDayEvents = [...candidates].sort((a, b) => {\n      const rowDiff = a.position.row - b.position.row;\n      return rowDiff !== 0 ? rowDiff : eventIndexes.get(a)! - eventIndexes.get(b)!;\n    });\n\n    sortedDayEvents.forEach((event) => {\n      let row = lastRow.get(event) ?? event.position.row;\n\n      if (row >= maxEventsPerDay || usedRows.has(row)) {\n        const availableRow = getFirstAvailableRow(usedRows, maxEventsPerDay);\n\n        if (availableRow === null) {\n          return;\n        }\n\n        row = availableRow;\n      }\n\n      usedRows.add(row);\n      setRenderRow(event, dayIndex, row);\n      lastRow.set(event, row);\n    });\n  }\n\n  return events.flatMap((event) => {\n    const eventRange = eventRanges.get(event)!;\n    const eventRenderRows = renderRows.get(event);\n    const segments: RenderableMonthEventSegment[] = [];\n    let currentSegment: SegmentRange | null = null;\n\n    const addSegment = (segment: SegmentRange) => {\n      const position = getSegmentPosition(\n        event,\n        segment,\n        eventRange,\n        visibleColumnMap,\n        columnsCount\n      );\n\n      segments.push({\n        event,\n        position,\n        clipStart: segment.startDayIndex > eventRange.startDayIndex,\n        clipEnd: segment.endDayIndex < eventRange.endDayIndex,\n        key: `${event.id}-${event.position.weekIndex}-${segment.startDayIndex}-${segment.endDayIndex}-${segment.row}`,\n      });\n    };\n\n    for (\n      let dayIndex = eventRange.startDayIndex;\n      dayIndex <= eventRange.endDayIndex;\n      dayIndex += 1\n    ) {\n      const row = eventRenderRows?.get(dayIndex);\n\n      if (row === undefined) {\n        if (currentSegment) {\n          addSegment(currentSegment);\n          currentSegment = null;\n        }\n\n        continue;\n      }\n\n      if (currentSegment && currentSegment.row === row) {\n        currentSegment.endDayIndex = dayIndex;\n      } else {\n        if (currentSegment) {\n          addSegment(currentSegment);\n        }\n\n        currentSegment = {\n          startDayIndex: dayIndex,\n          endDayIndex: dayIndex,\n          row,\n        };\n      }\n    }\n\n    if (currentSegment) {\n      addSegment(currentSegment);\n    }\n\n    return segments;\n  });\n}\n"],"mappings":"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"}