@taskctrl/canvas-timeline 0.1.2 → 0.2.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":"canvas-timeline.es.js","sources":["../src/types.ts","../src/core/ViewState.ts","../src/core/IntervalTree.ts","../src/core/LayoutEngine.ts","../src/core/HitTest.ts","../src/canvas/CanvasManager.ts","../src/canvas/GridLayer.ts","../src/canvas/DrawHelpers.ts","../src/canvas/ItemsLayer.ts","../src/canvas/OverlayLayer.ts","../src/interaction/ZoomHandler.ts","../src/interaction/InteractionHandler.ts","../node_modules/dayjs/plugin/isoWeek.js","../src/dom/Sidebar.tsx","../src/dom/TodayMarker.tsx","../src/dom/CustomMarker.tsx","../src/CanvasTimeline.tsx","../src/dom/TimelineHeaders.tsx","../node_modules/dayjs/plugin/weekOfYear.js","../src/dom/DateHeader.tsx","../src/dom/SidebarHeader.tsx","../src/dom/CustomHeader.tsx"],"sourcesContent":["import type React from 'react'\n\nexport interface Group {\n id: number | string\n title: string\n type?: string\n hierarchy?: string\n root?: boolean\n [key: string]: unknown\n}\n\nexport interface Item {\n id: number\n group: number | string\n start_time: number\n end_time: number\n type?: string\n [key: string]: unknown\n}\n\nexport interface ItemBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface ItemState {\n selected: boolean\n hovered: boolean\n dragging: boolean\n filtered: boolean\n}\n\nexport interface DrawHelpers {\n roundRect(x: number, y: number, w: number, h: number, radius?: number): void\n fillText(text: string, x: number, y: number, maxWidth?: number): void\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient\n leftBar(color: string, width?: number): void\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size?: number): void\n badge(text: string, x: number, y: number, bgColor: string): void\n}\n\nexport type CanvasItemRenderer = (\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n helpers: DrawHelpers,\n) => void\n\nexport type CanvasGroupItemRenderer = CanvasItemRenderer\n\nexport interface DayStyle {\n backgroundColor?: string\n borderColor?: string\n opacity?: number\n}\n\nexport interface RowStyle {\n backgroundColor?: string\n borderBottomColor?: string\n}\n\nexport interface Dependency {\n fromItemId: number\n toItemId: number\n type?: 'finish-to-start' | 'start-to-start' | 'finish-to-finish'\n color?: string\n}\n\nexport interface TimelineTheme {\n primary: string\n trainColors: Record<string, string>\n status: { red: string; yellow: string; green: string }\n grid: { line: string; rowAlt: string; weekend: string }\n item: { radius: number; text: string; selectedRing: string }\n marker: { today: string; milestone: string; cursor: string }\n sidebar: { bg: string; border: string; text: string }\n header: { bg: string; border: string; text: string }\n}\n\nexport const DEFAULT_THEME: TimelineTheme = {\n primary: '#269bf7',\n trainColors: {},\n status: { red: '#EF5350', yellow: '#FBBF24', green: '#31c48d' },\n grid: { line: '#E5E5E5', rowAlt: '#F7F7F7', weekend: 'rgba(0,0,0,0.03)' },\n item: { radius: 3, text: '#374151', selectedRing: '#a3a3a3' },\n marker: { today: '#FD7171', milestone: '#3B82F6', cursor: '#269bf7' },\n sidebar: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n header: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n}\n\nexport interface MarkerConfig {\n date: number\n color: string\n width: number\n label?: string\n}\n\nexport interface CanvasTimelineProps {\n groups: Group[]\n items: Item[]\n defaultTimeStart: number\n defaultTimeEnd: number\n visibleTimeStart?: number\n visibleTimeEnd?: number\n sidebarWidth: number\n lineHeight: number\n itemHeightRatio: number\n stackItems: boolean\n buffer?: number\n canMove: boolean\n canResize: false | 'left' | 'right' | 'both'\n canChangeGroup: boolean\n dragSnap: number\n minZoom: number\n maxZoom: number\n theme?: Partial<TimelineTheme>\n dayStyle?: (date: Date) => DayStyle | null\n rowStyle?: (group: Group) => RowStyle | null\n showCursorLine?: boolean\n itemRenderer: CanvasItemRenderer\n groupRenderer?: CanvasGroupItemRenderer\n sidebarGroupRenderer: (group: Group) => React.ReactNode\n rightSidebarWidth?: number\n rightSidebarGroupRenderer?: (group: Group) => React.ReactNode\n dependencies?: Dependency[]\n onItemClick?: (itemId: number, e: PointerEvent) => void\n onItemDoubleClick?: (itemId: number, e: PointerEvent) => void\n onItemContextMenu?: (itemId: number, e: PointerEvent) => void\n onItemMove?: (itemId: number, newStartTime: number, newGroupId: string | number) => void\n onItemResize?: (itemId: number, newTime: number, edge: 'left' | 'right') => void\n /** Validate and optionally constrain move/resize. Return the (possibly modified) time. */\n moveResizeValidator?: (action: 'move' | 'resize', itemId: number, time: number, edge?: 'left' | 'right') => number\n onItemHover?: (itemId: number | null, e: PointerEvent) => void\n onCanvasDoubleClick?: (groupId: number, time: number) => void\n onCanvasContextMenu?: (groupId: number, time: number, e: PointerEvent) => void\n onTimeChange?: (start: number, end: number) => void\n onZoom?: (start: number, end: number) => void\n selected?: number[]\n /** Called when the timeline is ready, providing the capture API */\n onReady?: (api: CanvasTimelineRef) => void\n children?: React.ReactNode\n}\n\nexport interface CaptureOptions {\n timeStart: number\n timeEnd: number\n scale: number\n sidebarWidth: number\n}\n\nexport interface CanvasTimelineRef {\n captureToCanvas(options: CaptureOptions): HTMLCanvasElement\n}\n","export interface ViewStateConfig {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n}\n\nexport class ViewState {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n\n private visibleDuration: number\n private pixelsPerMs: number\n\n constructor(config: ViewStateConfig) {\n this.visibleTimeStart = config.visibleTimeStart\n this.visibleTimeEnd = config.visibleTimeEnd\n this.canvasWidth = config.canvasWidth\n this.canvasHeight = config.canvasHeight\n this.sidebarWidth = config.sidebarWidth\n this.lineHeight = config.lineHeight\n this.groupCount = config.groupCount\n this.buffer = config.buffer\n this.scrollTop = config.scrollTop\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n }\n\n update(params: Partial<ViewStateConfig>): void {\n if (params.visibleTimeStart !== undefined) this.visibleTimeStart = params.visibleTimeStart\n if (params.visibleTimeEnd !== undefined) this.visibleTimeEnd = params.visibleTimeEnd\n if (params.canvasWidth !== undefined) this.canvasWidth = params.canvasWidth\n if (params.canvasHeight !== undefined) this.canvasHeight = params.canvasHeight\n if (params.sidebarWidth !== undefined) this.sidebarWidth = params.sidebarWidth\n if (params.lineHeight !== undefined) this.lineHeight = params.lineHeight\n if (params.groupCount !== undefined) this.groupCount = params.groupCount\n if (params.buffer !== undefined) this.buffer = params.buffer\n if (params.scrollTop !== undefined) this.scrollTop = params.scrollTop\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n }\n\n timeToX(time: number): number {\n return (time - this.visibleTimeStart) * this.pixelsPerMs\n }\n\n xToTime(x: number): number {\n return this.visibleTimeStart + x / this.pixelsPerMs\n }\n\n yToGroupIndex(y: number): number {\n const raw = Math.floor((y + this.scrollTop) / this.lineHeight)\n return Math.max(0, Math.min(raw, this.groupCount - 1))\n }\n\n groupIndexToY(index: number): number {\n return index * this.lineHeight - this.scrollTop\n }\n\n getBufferBounds(): { bufferStart: number; bufferEnd: number } {\n const extend = this.visibleDuration * 1.5\n return {\n bufferStart: this.visibleTimeStart - extend,\n bufferEnd: this.visibleTimeEnd + extend,\n }\n }\n\n getVisibleGroupRange(): { firstVisible: number; lastVisible: number } {\n const firstVisible = Math.max(0, Math.floor(this.scrollTop / this.lineHeight))\n const visibleCount = Math.ceil(this.canvasHeight / this.lineHeight)\n const lastVisible = Math.min(this.groupCount - 1, firstVisible + visibleCount)\n return { firstVisible, lastVisible }\n }\n\n isScrollInBuffer(scrollXOffset: number): boolean {\n const bufferPixels = this.visibleDuration * 1.5 * this.pixelsPerMs\n return Math.abs(scrollXOffset) < bufferPixels\n }\n\n getTotalHeight(): number {\n return this.groupCount * this.lineHeight\n }\n}\n","interface TreeNode<T> {\n center: number\n left: TreeNode<T> | null\n right: TreeNode<T> | null\n overlapping: Array<{ item: T; start: number; end: number }>\n}\n\nexport class IntervalTree<T> {\n private root: TreeNode<T> | null = null\n\n buildFromItems(\n items: T[],\n getStart: (item: T) => number,\n getEnd: (item: T) => number,\n ): void {\n const intervals = items.map((item) => ({\n item,\n start: getStart(item),\n end: getEnd(item),\n }))\n this.root = this.buildNode(intervals)\n }\n\n private buildNode(\n intervals: Array<{ item: T; start: number; end: number }>,\n ): TreeNode<T> | null {\n if (intervals.length === 0) return null\n\n let min = Infinity\n let max = -Infinity\n for (const iv of intervals) {\n if (iv.start < min) min = iv.start\n if (iv.end > max) max = iv.end\n }\n const center = (min + max) / 2\n\n const leftIntervals: Array<{ item: T; start: number; end: number }> = []\n const rightIntervals: Array<{ item: T; start: number; end: number }> = []\n const overlapping: Array<{ item: T; start: number; end: number }> = []\n\n for (const iv of intervals) {\n if (iv.end < center) {\n leftIntervals.push(iv)\n } else if (iv.start > center) {\n rightIntervals.push(iv)\n } else {\n overlapping.push(iv)\n }\n }\n\n return {\n center,\n left: this.buildNode(leftIntervals),\n right: this.buildNode(rightIntervals),\n overlapping,\n }\n }\n\n query(start: number, end: number): T[] {\n const results: T[] = []\n this.queryNode(this.root, start, end, results)\n return results\n }\n\n private queryNode(\n node: TreeNode<T> | null,\n start: number,\n end: number,\n results: T[],\n ): void {\n if (node === null) return\n\n for (const iv of node.overlapping) {\n if (iv.start <= end && iv.end >= start) {\n results.push(iv.item)\n }\n }\n\n if (start <= node.center && node.left !== null) {\n this.queryNode(node.left, start, end, results)\n }\n\n if (end >= node.center && node.right !== null) {\n this.queryNode(node.right, start, end, results)\n }\n }\n}\n","import type { Item } from '../types'\n\nexport interface ItemLayout {\n stackLevel: number\n itemHeight: number\n}\n\nexport class LayoutEngine {\n private readonly lineHeight: number\n private readonly itemHeightRatio: number\n private layoutCache: Map<number, ItemLayout> = new Map()\n private groupMaxStack: Map<string | number, number> = new Map()\n\n constructor(lineHeight: number, itemHeightRatio: number) {\n this.lineHeight = lineHeight\n this.itemHeightRatio = itemHeightRatio\n }\n\n computeLayout(items: Item[], stackItems: boolean): Map<number, ItemLayout> {\n this.layoutCache = new Map()\n this.groupMaxStack = new Map()\n\n if (!stackItems) {\n const itemHeight = this.lineHeight * this.itemHeightRatio\n for (const item of items) {\n this.layoutCache.set(item.id, { stackLevel: 0, itemHeight })\n this.groupMaxStack.set(item.group, 0)\n }\n return this.layoutCache\n }\n\n // Group items by group id\n const byGroup = new Map<string | number, Item[]>()\n for (const item of items) {\n let arr = byGroup.get(item.group)\n if (!arr) {\n arr = []\n byGroup.set(item.group, arr)\n }\n arr.push(item)\n }\n\n const itemHeight = this.lineHeight * this.itemHeightRatio\n\n for (const [groupId, groupItems] of byGroup) {\n groupItems.sort((a, b) => {\n const d = a.start_time - b.start_time\n if (d !== 0) return d\n return (b.end_time - b.start_time) - (a.end_time - a.start_time)\n })\n\n const levelEnds: number[] = []\n let maxLevel = 0\n\n for (const item of groupItems) {\n let level = -1\n for (let i = 0; i < levelEnds.length; i++) {\n if (levelEnds[i] <= item.start_time) {\n level = i\n break\n }\n }\n\n if (level === -1) {\n level = levelEnds.length\n levelEnds.push(item.end_time)\n } else {\n levelEnds[level] = item.end_time\n }\n\n if (level > maxLevel) maxLevel = level\n\n this.layoutCache.set(item.id, { stackLevel: level, itemHeight })\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\n }\n\n return this.layoutCache\n }\n\n getLayout(itemId: number): ItemLayout | undefined {\n return this.layoutCache.get(itemId)\n }\n\n getGroupHeight(groupId: string | number): number {\n const maxStack = this.groupMaxStack.get(groupId) ?? 0\n return (maxStack + 1) * this.lineHeight\n }\n}\n","import type { Item, Group } from '../types'\nimport type { ViewState } from './ViewState'\nimport type { IntervalTree } from './IntervalTree'\nimport type { LayoutEngine } from './LayoutEngine'\n\nexport function hitTest(\n canvasX: number,\n canvasY: number,\n view: ViewState,\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n groups: Group[],\n): Item | null {\n const time = view.xToTime(canvasX)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const candidates = tree.query(time, time)\n\n let topItem: Item | null = null\n let topY = -Infinity\n\n for (const item of candidates) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n if (canvasX < x || canvasX > x + width) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n const height = itemLayout.itemHeight\n\n if (canvasY < y || canvasY > y + height) continue\n\n if (y > topY) {\n topY = y\n topItem = item\n }\n }\n\n return topItem\n}\n\nexport function hitTestGroup(\n canvasY: number,\n view: ViewState,\n groups: Group[],\n): Group | null {\n const groupIndex = view.yToGroupIndex(canvasY)\n return groups[groupIndex] ?? null\n}\n\nexport function detectEdge(\n canvasX: number,\n item: Item,\n view: ViewState,\n threshold: number = 6,\n): 'left' | 'right' | 'body' {\n const leftX = view.timeToX(item.start_time)\n const rightX = view.timeToX(item.end_time)\n if (canvasX - leftX <= threshold) return 'left'\n if (rightX - canvasX <= threshold) return 'right'\n return 'body'\n}\n","/**\n * Resize the canvas buffer only when dimensions actually change.\n * Setting canvas.width/height is destructive (clears buffer + resets state),\n * so we avoid it unless necessary.\n */\nexport function setupCanvas(\n canvas: HTMLCanvasElement,\n width: number,\n height: number,\n): CanvasRenderingContext2D {\n const dpr = window.devicePixelRatio || 1\n const targetW = Math.round(width * dpr)\n const targetH = Math.round(height * dpr)\n\n if (canvas.width !== targetW || canvas.height !== targetH) {\n canvas.width = targetW\n canvas.height = targetH\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n }\n\n const ctx = canvas.getContext('2d')!\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n return ctx\n}\n\nexport function clearCanvas(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement): void {\n const dpr = window.devicePixelRatio || 1\n ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr)\n}\n\nexport type LayerName = 'grid' | 'items' | 'overlay'\n\nexport interface DirtyFlags {\n grid: boolean\n items: boolean\n overlay: boolean\n}\n\nexport class RenderScheduler {\n private dirty: DirtyFlags = { grid: false, items: false, overlay: false }\n private rafId: number | null = null\n private drawCallback: (flags: DirtyFlags) => void\n\n constructor(drawCallback: (flags: DirtyFlags) => void) {\n this.drawCallback = drawCallback\n }\n\n markDirty(layer: LayerName): void {\n this.dirty[layer] = true\n this.schedule()\n }\n\n markAllDirty(): void {\n this.dirty.grid = true\n this.dirty.items = true\n this.dirty.overlay = true\n this.schedule()\n }\n\n dispose(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n private schedule(): void {\n if (this.rafId !== null) return\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n const flags = { ...this.dirty }\n this.dirty.grid = false\n this.dirty.items = false\n this.dirty.overlay = false\n this.drawCallback(flags)\n })\n }\n}\n","import dayjs from 'dayjs'\nimport type { Group, TimelineTheme, DayStyle, RowStyle } from '../types'\nimport type { ViewState } from '../core/ViewState'\n\nexport class GridLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n theme: TimelineTheme,\n dayStyle?: (date: Date) => DayStyle | null,\n rowStyle?: (group: Group) => RowStyle | null,\n ): void {\n const { firstVisible, lastVisible } = view.getVisibleGroupRange()\n\n // Draw row backgrounds\n for (let i = firstVisible; i <= lastVisible; i++) {\n const y = view.groupIndexToY(i)\n const group = groups[i]\n if (!group) continue\n\n let bgColor: string\n const customRow = rowStyle?.(group)\n if (customRow?.backgroundColor) {\n bgColor = customRow.backgroundColor\n } else {\n bgColor = i % 2 === 0 ? '#FFFFFF' : theme.grid.rowAlt\n }\n\n ctx.fillStyle = bgColor\n ctx.fillRect(0, y, view.canvasWidth, view.lineHeight)\n\n // Row separator\n ctx.strokeStyle = customRow?.borderBottomColor ?? theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + view.lineHeight)\n ctx.lineTo(view.canvasWidth, y + view.lineHeight)\n ctx.stroke()\n }\n\n // Draw day columns, backgrounds, and vertical grid lines\n const visibleStart = view.visibleTimeStart\n const visibleEnd = view.visibleTimeEnd\n const visibleDuration = visibleEnd - visibleStart\n const dayMs = 86400000\n const dayPixelWidth = (dayMs / visibleDuration) * view.canvasWidth\n\n // Determine grid line interval based on zoom level\n let stepUnit: 'day' | 'week' | 'month' = 'day'\n if (dayPixelWidth < 2) stepUnit = 'month'\n else if (dayPixelWidth < 8) stepUnit = 'week'\n\n // Draw day backgrounds (dayStyle + weekends) — batch consecutive same-style days\n if (dayStyle || true) { // always draw weekends\n let current = dayjs(visibleStart).startOf('day')\n const end = dayjs(visibleEnd).endOf('day')\n\n // Batch: track current fill color and start x\n let batchColor: string | null = null\n let batchOpacity = 1\n let batchStartX = 0\n const customBorderLines: { x: number; color: string }[] = []\n\n const flushBatch = (endX: number) => {\n if (batchColor !== null) {\n ctx.fillStyle = batchColor\n if (batchOpacity !== 1) ctx.globalAlpha = batchOpacity\n ctx.fillRect(batchStartX, 0, endX - batchStartX, view.canvasHeight)\n if (batchOpacity !== 1) ctx.globalAlpha = 1\n batchColor = null\n batchOpacity = 1\n }\n }\n\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n\n const date = current.toDate()\n const custom = dayStyle?.(date)\n let color: string | null = null\n let opacity = 1\n\n if (custom?.backgroundColor) {\n color = custom.backgroundColor\n opacity = custom.opacity ?? 1\n } else {\n const dow = current.day()\n if (dow === 0 || dow === 6) {\n color = theme.grid.weekend\n }\n }\n\n // Collect custom border colors for later drawing\n if (custom?.borderColor) {\n customBorderLines.push({ x, color: custom.borderColor })\n }\n\n // Batch consecutive same-color fills\n if (color === batchColor && opacity === batchOpacity) {\n // extend batch\n } else {\n flushBatch(x)\n if (color !== null) {\n batchColor = color\n batchOpacity = opacity\n batchStartX = x\n }\n }\n\n current = current.add(1, 'day')\n }\n // Flush remaining batch\n if (batchColor !== null) {\n flushBatch(view.timeToX(current.valueOf()))\n }\n\n // Draw custom border lines from dayStyle\n for (const line of customBorderLines) {\n ctx.strokeStyle = line.color\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(line.x, 0)\n ctx.lineTo(line.x, view.canvasHeight)\n ctx.stroke()\n }\n }\n\n // Draw vertical grid lines at appropriate interval\n let current = dayjs(visibleStart).startOf(stepUnit)\n const end = dayjs(visibleEnd).add(1, stepUnit)\n\n ctx.strokeStyle = theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n ctx.moveTo(x, 0)\n ctx.lineTo(x, view.canvasHeight)\n current = current.add(1, stepUnit)\n }\n ctx.stroke()\n }\n}\n","import type { DrawHelpers, ItemBounds } from '../types'\n\nconst ITEM_FONT = '500 12px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n\n/**\n * Creates a DrawHelpers object bound to the given canvas context and optional item bounds.\n * These helpers are passed to every itemRenderer call to simplify common canvas operations.\n */\nexport function createDrawHelpers(\n ctx: CanvasRenderingContext2D,\n bounds?: ItemBounds,\n): DrawHelpers {\n return {\n /**\n * Draws a filled rounded rectangle.\n * Default corner radius is 3px.\n */\n roundRect(x: number, y: number, w: number, h: number, radius = 3): void {\n ctx.beginPath()\n ctx.roundRect(x, y, w, h, radius)\n ctx.fill()\n },\n\n /**\n * Draws text at (x, y) using the standard item font.\n * If maxWidth is provided and the text is too wide, binary-search truncates it\n * and appends '...' so it fits within maxWidth.\n */\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n ctx.font = ITEM_FONT\n\n if (maxWidth !== undefined && ctx.measureText(text).width > maxWidth) {\n // Binary-search for the longest prefix that fits with '...' appended\n let lo = 0\n let hi = text.length\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n const candidate = text.slice(0, mid) + '...'\n if (ctx.measureText(candidate).width <= maxWidth) {\n lo = mid\n } else {\n hi = mid - 1\n }\n }\n ctx.fillText(text.slice(0, lo) + '...', x, y)\n } else {\n ctx.fillText(text, x, y)\n }\n },\n\n /**\n * Creates a 50/50 linear gradient from color1 (0%–50%) to color2 (50%–100%)\n * spanning the given x position and width.\n */\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient {\n const grad = ctx.createLinearGradient(x, 0, x + w, 0)\n grad.addColorStop(0, color1)\n grad.addColorStop(0.5, color1)\n grad.addColorStop(0.5, color2)\n grad.addColorStop(1, color2)\n return grad\n },\n\n /**\n * Draws a vertical colored bar on the left edge of the item bounds.\n * Does nothing if no bounds were provided.\n */\n leftBar(color: string, width = 3): void {\n if (!bounds) return\n ctx.save()\n ctx.fillStyle = color\n ctx.fillRect(bounds.x, bounds.y, width, bounds.height)\n ctx.restore()\n },\n\n /**\n * Draws a vector icon centered at (x, y).\n * Supported types: 'check', 'danger-red', 'danger-yellow'.\n * Default size is 14px.\n */\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size = 14): void {\n ctx.save()\n const half = size / 2\n\n if (type === 'check') {\n // Green circle with white checkmark\n ctx.fillStyle = '#31c48d'\n ctx.beginPath()\n ctx.arc(x + half, y + half, half, 0, Math.PI * 2)\n ctx.fill()\n\n // Draw checkmark path\n ctx.strokeStyle = '#ffffff'\n ctx.lineWidth = size * 0.12\n ctx.beginPath()\n const cx = x + half\n const cy = y + half\n ctx.moveTo(cx - half * 0.45, cy)\n ctx.lineTo(cx - half * 0.1, cy + half * 0.42)\n ctx.lineTo(cx + half * 0.45, cy - half * 0.35)\n ctx.stroke()\n } else if (type === 'danger-red' || type === 'danger-yellow') {\n const fillColor = type === 'danger-red' ? '#EF5350' : '#FBBF24'\n\n // Triangle background\n ctx.fillStyle = fillColor\n ctx.beginPath()\n ctx.moveTo(x + half, y) // top-center\n ctx.lineTo(x + size, y + size) // bottom-right\n ctx.lineTo(x, y + size) // bottom-left\n ctx.closePath()\n ctx.fill()\n\n // Exclamation mark stem\n ctx.fillStyle = '#ffffff'\n const stemW = size * 0.12\n const stemX = x + half - stemW / 2\n ctx.fillRect(stemX, y + size * 0.35, stemW, size * 0.35)\n\n // Exclamation mark dot\n ctx.beginPath()\n ctx.arc(x + half, y + size * 0.82, stemW * 0.7, 0, Math.PI * 2)\n ctx.fill()\n }\n\n ctx.restore()\n },\n\n /**\n * Draws a pill-shaped badge with centered white text on a colored background.\n */\n badge(text: string, x: number, y: number, bgColor: string): void {\n ctx.save()\n\n // Measure text to size the pill\n ctx.font = ITEM_FONT\n const textMetrics = ctx.measureText(text)\n const textWidth = textMetrics.width\n const paddingH = 8\n const paddingV = 3\n const pillHeight = 12 + paddingV * 2\n const pillWidth = textWidth + paddingH * 2\n const radius = pillHeight / 2\n\n // Draw pill background\n ctx.fillStyle = bgColor\n ctx.beginPath()\n ctx.roundRect(x, y, pillWidth, pillHeight, radius)\n ctx.fill()\n\n // Draw centered white text\n ctx.fillStyle = '#ffffff'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(text, x + pillWidth / 2, y + pillHeight / 2)\n\n ctx.restore()\n },\n }\n}\n","import type {\n Item, Group, TimelineTheme, CanvasItemRenderer, CanvasGroupItemRenderer,\n Dependency, ItemBounds, ItemState,\n} from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { IntervalTree } from '../core/IntervalTree'\nimport type { LayoutEngine } from '../core/LayoutEngine'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport class ItemsLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n _items: Item[],\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n itemRenderer: CanvasItemRenderer,\n groupRenderer: CanvasGroupItemRenderer | undefined,\n theme: TimelineTheme,\n selected: number[],\n hoveredItemId: number | undefined,\n dependencies?: Dependency[],\n ): void {\n // Query only visible time range + small padding (not the full 4x buffer)\n const padding = (view.visibleTimeEnd - view.visibleTimeStart) * 0.1\n const queryStart = view.visibleTimeStart - padding\n const queryEnd = view.visibleTimeEnd + padding\n const visibleItems = tree.query(queryStart, queryEnd)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const selectedSet = new Set(selected)\n const itemBoundsMap = new Map<number, ItemBounds>()\n\n // Vertical culling bounds\n const yMin = -view.lineHeight\n const yMax = view.canvasHeight + view.lineHeight\n\n for (const item of visibleItems) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n\n // Skip items that are entirely off-screen vertically\n const height = itemLayout.itemHeight\n if (y + height < yMin || y > yMax) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n const bounds: ItemBounds = { x, y, width, height }\n itemBoundsMap.set(item.id, bounds)\n\n const state: ItemState = {\n selected: selectedSet.has(item.id),\n hovered: hoveredItemId === item.id,\n dragging: false,\n filtered: item.filtered !== false,\n }\n\n ctx.save()\n const helpers = createDrawHelpers(ctx, bounds)\n const renderer = groupRenderer && (item.type === 'control_area_group' || item.type === 'construction_train')\n ? groupRenderer\n : itemRenderer\n renderer(ctx, item, bounds, state, helpers)\n ctx.restore()\n }\n\n if (dependencies && dependencies.length > 0) {\n this.drawDependencies(ctx, dependencies, itemBoundsMap, hoveredItemId, theme)\n }\n }\n\n private drawDependencies(\n ctx: CanvasRenderingContext2D,\n dependencies: Dependency[],\n boundsMap: Map<number, ItemBounds>,\n hoveredItemId: number | undefined,\n theme: TimelineTheme,\n ): void {\n for (const dep of dependencies) {\n const fromBounds = boundsMap.get(dep.fromItemId)\n const toBounds = boundsMap.get(dep.toItemId)\n if (!fromBounds || !toBounds) continue\n\n const isHighlighted = hoveredItemId === dep.fromItemId || hoveredItemId === dep.toItemId\n\n ctx.strokeStyle = isHighlighted ? theme.primary : (dep.color ?? '#94A3B8')\n ctx.lineWidth = isHighlighted ? 2 : 1.5\n ctx.setLineDash([])\n\n const startX = fromBounds.x + fromBounds.width\n const startY = fromBounds.y + fromBounds.height / 2\n const endX = toBounds.x\n const endY = toBounds.y + toBounds.height / 2\n\n const dx = Math.abs(endX - startX)\n const cpOffset = Math.max(dx * 0.4, 30)\n\n ctx.beginPath()\n ctx.moveTo(startX, startY)\n ctx.bezierCurveTo(startX + cpOffset, startY, endX - cpOffset, endY, endX, endY)\n ctx.stroke()\n\n // Arrowhead\n const arrowSize = 6\n ctx.fillStyle = ctx.strokeStyle\n ctx.beginPath()\n ctx.moveTo(endX, endY)\n ctx.lineTo(endX - arrowSize, endY - arrowSize / 2)\n ctx.lineTo(endX - arrowSize, endY + arrowSize / 2)\n ctx.closePath()\n ctx.fill()\n }\n }\n}\n","import type { TimelineTheme, MarkerConfig, ItemBounds, Item, CanvasItemRenderer } from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { InteractionMode } from '../interaction/InteractionHandler'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport interface InteractionRenderState {\n item: Item\n mode: InteractionMode\n bounds: ItemBounds\n renderer: CanvasItemRenderer\n targetGroupY?: number\n groupChanged?: boolean\n}\n\nexport interface OverlayDrawOptions {\n cursorX: number | null\n snapX?: number | null\n markers?: MarkerConfig[]\n interaction?: InteractionRenderState | null\n}\n\nexport class OverlayLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n theme: TimelineTheme,\n options: OverlayDrawOptions,\n ): void {\n const { cursorX, snapX, markers, interaction } = options\n\n // Draw markers\n if (markers) {\n for (const marker of markers) {\n const x = view.timeToX(marker.date)\n\n ctx.fillStyle = marker.color\n ctx.fillRect(x - marker.width / 2, 0, marker.width, view.canvasHeight)\n\n if (marker.label) {\n ctx.save()\n ctx.font = '500 10px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n const textWidth = ctx.measureText(marker.label).width\n const padding = 8\n const maxBadgeWidth = 200\n const badgeWidth = Math.min(textWidth + padding * 2, maxBadgeWidth)\n const badgeHeight = 20\n const badgeX = x - badgeWidth / 2\n const badgeY = 4\n\n ctx.fillStyle = marker.color\n ctx.beginPath()\n ctx.roundRect(badgeX, badgeY, badgeWidth, badgeHeight, 3)\n ctx.fill()\n\n ctx.fillStyle = '#FFFFFF'\n ctx.textBaseline = 'middle'\n const maxTextWidth = maxBadgeWidth - padding * 2\n const displayText = textWidth > maxTextWidth\n ? marker.label.slice(0, Math.floor(marker.label.length * maxTextWidth / textWidth)) + '…'\n : marker.label\n ctx.fillText(displayText, badgeX + padding, badgeY + badgeHeight / 2)\n ctx.restore()\n }\n }\n }\n\n // Draw cursor line\n if (cursorX !== null && cursorX !== undefined) {\n ctx.strokeStyle = theme.marker.cursor\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(cursorX, 0)\n ctx.lineTo(cursorX, view.canvasHeight)\n ctx.stroke()\n }\n\n // Draw snap guide line\n if (snapX !== null && snapX !== undefined) {\n ctx.strokeStyle = theme.primary\n ctx.lineWidth = 1\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(snapX, 0)\n ctx.lineTo(snapX, view.canvasHeight)\n ctx.stroke()\n ctx.setLineDash([])\n }\n\n // Draw interaction ghost (move, resize-left, resize-right)\n if (interaction) {\n // Group highlight band when moving to a different group\n if (interaction.groupChanged && interaction.targetGroupY !== undefined) {\n ctx.fillStyle = 'rgba(59, 130, 246, 0.08)'\n ctx.fillRect(0, interaction.targetGroupY, view.canvasWidth, view.lineHeight)\n }\n\n ctx.save()\n ctx.globalAlpha = 0.5\n const helpers = createDrawHelpers(ctx, interaction.bounds)\n interaction.renderer(\n ctx, interaction.item, interaction.bounds,\n { selected: false, hovered: false, dragging: true, filtered: true },\n helpers,\n )\n ctx.restore()\n }\n }\n}\n","const MAX_DELTA = 120\n\n/**\n * Normalize wheel delta across browsers/platforms.\n * deltaMode 0 = pixels, 1 = lines (×15), 2 = pages (×800).\n * Clamp to ±120 to prevent erratic jumps.\n */\nfunction normalizeDelta(e: WheelEvent): number {\n let delta = e.deltaY || e.deltaX\n if (e.deltaMode === 1) delta *= 15\n else if (e.deltaMode === 2) delta *= 800\n return Math.max(-MAX_DELTA, Math.min(MAX_DELTA, delta))\n}\n\nexport class ZoomHandler {\n private onZoom: (newStart: number, newEnd: number) => void\n private visibleTimeStart: number\n private visibleTimeEnd: number\n private minZoom: number\n private maxZoom: number\n\n constructor(\n onZoom: (newStart: number, newEnd: number) => void,\n visibleTimeStart: number,\n visibleTimeEnd: number,\n minZoom: number,\n maxZoom: number,\n ) {\n this.onZoom = onZoom\n this.visibleTimeStart = visibleTimeStart\n this.visibleTimeEnd = visibleTimeEnd\n this.minZoom = minZoom\n this.maxZoom = maxZoom\n }\n\n updateBounds(start: number, end: number): void {\n this.visibleTimeStart = start\n this.visibleTimeEnd = end\n }\n\n handleWheelZoom(e: WheelEvent, cursorRatio: number): void {\n const delta = normalizeDelta(e)\n // Speed: ctrlKey (trackpad pinch) = 10, metaKey = 3, altKey = 1\n const speed = e.ctrlKey ? 10 : e.metaKey ? 3 : 1\n\n // Reciprocal formula for symmetric zoom-in / zoom-out\n const scale = delta > 0\n ? 1.0 + (speed * delta) / 500\n : 1.0 / (1.0 + (speed * -delta) / 500)\n\n const currentDuration = this.visibleTimeEnd - this.visibleTimeStart\n let newDuration = Math.round(currentDuration * scale)\n newDuration = Math.max(this.minZoom, Math.min(this.maxZoom, newDuration))\n\n const newStart = Math.round(this.visibleTimeStart + (currentDuration - newDuration) * cursorRatio)\n const newEnd = newStart + newDuration\n\n this.onZoom(newStart, newEnd)\n }\n}\n","import type { Item } from '../types'\n\nconst ACTIVATION_THRESHOLD = 4\n\nexport type InteractionMode = 'move' | 'resize-left' | 'resize-right'\n\nexport interface InteractionState {\n item: Item\n mode: InteractionMode\n startX: number\n startY: number\n currentX: number\n currentY: number\n deltaX: number\n originalGroup: string | number\n currentGroup: string | number\n}\n\nexport class InteractionHandler {\n private state: InteractionState | null = null\n private dragSnap: number\n private activated = false\n\n constructor(dragSnap: number) {\n this.dragSnap = dragSnap\n }\n\n startInteraction(item: Item, mode: InteractionMode, x: number, y: number): void {\n this.state = {\n item, mode, startX: x, startY: y, currentX: x, currentY: y,\n deltaX: 0, originalGroup: item.group, currentGroup: item.group,\n }\n this.activated = false\n }\n\n update(x: number, y: number): void {\n if (!this.state) return\n this.state.currentX = x\n this.state.currentY = y\n this.state.deltaX = x - this.state.startX\n if (!this.activated && Math.abs(this.state.deltaX) >= ACTIVATION_THRESHOLD) {\n this.activated = true\n }\n }\n\n setCurrentGroup(groupId: string | number): void {\n if (this.state) this.state.currentGroup = groupId\n }\n\n endMove(pixelsPerMs: number): { newStartTime: number; newGroupId: string | number } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const newStartTime = this.state.item.start_time + deltaMs\n const snapped = Math.round(newStartTime / this.dragSnap) * this.dragSnap\n const newGroupId = this.state.currentGroup\n this.state = null\n this.activated = false\n return { newStartTime: snapped, newGroupId }\n }\n\n endResize(pixelsPerMs: number): { newTime: number; edge: 'left' | 'right' } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const edge = this.state.mode === 'resize-left' ? 'left' as const : 'right' as const\n const baseTime = edge === 'left' ? this.state.item.start_time : this.state.item.end_time\n const newTime = baseTime + deltaMs\n const snapped = Math.round(newTime / this.dragSnap) * this.dragSnap\n this.state = null\n this.activated = false\n return { newTime: snapped, edge }\n }\n\n cancel(): void {\n this.state = null\n this.activated = false\n }\n\n getState(): InteractionState | null {\n return this.state\n }\n\n getMode(): InteractionMode | null {\n return this.state?.mode ?? null\n }\n\n isActive(): boolean {\n return this.state !== null && this.activated\n }\n\n isPending(): boolean {\n return this.state !== null\n }\n}\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_isoWeek=t()}(this,(function(){\"use strict\";var e=\"day\";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf(\"year\"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,\"week\")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return\"isoweek\"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf(\"day\"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf(\"day\"):n.bind(this)(e,t)}}}));","import React, { useRef, useCallback, useEffect } from 'react'\nimport type { Group, TimelineTheme } from '../types'\n\ninterface SidebarProps {\n groups: Group[]\n width: number\n lineHeight: number\n scrollTop: number\n canvasHeight: number\n theme: TimelineTheme\n groupRenderer: (group: Group) => React.ReactNode\n onScroll: (scrollTop: number) => void\n}\n\nconst OVERSCAN = 5\n\nexport function Sidebar({\n groups, width, lineHeight, scrollTop, canvasHeight, theme, groupRenderer, onScroll,\n}: SidebarProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false)\n const totalHeight = groups.length * lineHeight\n const displayHeight = canvasHeight\n\n const firstVisible = Math.max(0, Math.floor(scrollTop / lineHeight) - OVERSCAN)\n const lastVisible = Math.min(groups.length - 1, Math.ceil((scrollTop + canvasHeight) / lineHeight) + OVERSCAN)\n\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n if (isScrollingRef.current) return\n onScroll(e.currentTarget.scrollTop)\n }, [onScroll])\n\n useEffect(() => {\n if (containerRef.current) {\n isScrollingRef.current = true\n containerRef.current.scrollTop = scrollTop\n requestAnimationFrame(() => { isScrollingRef.current = false })\n }\n }, [scrollTop])\n\n const visibleGroups = []\n for (let i = firstVisible; i <= lastVisible; i++) {\n const group = groups[i]\n if (!group) continue\n visibleGroups.push(\n <div\n key={group.id}\n style={{\n position: 'absolute',\n top: i * lineHeight,\n height: lineHeight,\n width: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'stretch',\n borderBottom: `1px solid ${theme.grid?.line ?? '#E5E5E5'}`,\n boxSizing: 'border-box',\n }}\n >\n {groupRenderer(group)}\n </div>,\n )\n }\n\n return (\n <div\n ref={containerRef}\n onScroll={handleScroll}\n style={{\n width,\n height: displayHeight,\n overflowY: totalHeight > canvasHeight ? 'auto' : 'hidden',\n overflowX: 'hidden',\n position: 'relative',\n borderRight: `1px solid ${theme.sidebar.border}`,\n backgroundColor: theme.sidebar.bg,\n }}\n >\n <div style={{ height: totalHeight, position: 'relative' }}>{visibleGroups}</div>\n </div>\n )\n}\n","import type { MarkerConfig } from '../types'\n\ninterface TodayMarkerProps {\n color?: string\n width?: number\n label?: string\n /** Auto-update interval in ms. Default 10000 (10s). Set 0 to disable. */\n interval?: number\n}\n\nexport function TodayMarker(_props: TodayMarkerProps) { return null }\nTodayMarker.displayName = 'TodayMarker'\n\nexport function getTodayMarkerConfig(props: TodayMarkerProps): MarkerConfig {\n // Snap to current minute to avoid unnecessary redraws\n const now = Math.floor(Date.now() / 60000) * 60000\n return { date: now, color: props.color ?? '#FD7171', width: props.width ?? 6, label: props.label }\n}\n\nexport function getTodayMarkerInterval(props: TodayMarkerProps): number {\n return props.interval ?? 10000\n}\n","import type { MarkerConfig } from '../types'\n\ninterface CustomMarkerProps {\n date: number\n color?: string\n width?: number\n label?: string\n}\n\nexport function CustomMarker(_props: CustomMarkerProps) { return null }\nCustomMarker.displayName = 'CustomMarker'\n\nexport function getCustomMarkerConfig(props: CustomMarkerProps): MarkerConfig {\n return {\n date: props.date,\n color: props.color ?? '#3B82F6',\n width: props.width ?? 4,\n label: props.label,\n }\n}\n","import React, { useRef, useEffect, useState, useCallback, useMemo, useImperativeHandle, forwardRef } from 'react'\nimport { flushSync } from 'react-dom'\nimport type {\n CanvasTimelineProps,\n CanvasTimelineRef,\n MarkerConfig,\n TimelineTheme,\n} from './types'\nimport { DEFAULT_THEME } from './types'\nimport { ViewState } from './core/ViewState'\nimport { IntervalTree } from './core/IntervalTree'\nimport { LayoutEngine } from './core/LayoutEngine'\nimport { hitTest, hitTestGroup } from './core/HitTest'\nimport { setupCanvas, clearCanvas, RenderScheduler } from './canvas/CanvasManager'\nimport { GridLayer } from './canvas/GridLayer'\nimport { ItemsLayer } from './canvas/ItemsLayer'\nimport { OverlayLayer } from './canvas/OverlayLayer'\nimport { ZoomHandler } from './interaction/ZoomHandler'\nimport { InteractionHandler } from './interaction/InteractionHandler'\nimport { detectEdge } from './core/HitTest'\nimport dayjs from 'dayjs'\nimport isoWeek from 'dayjs/plugin/isoWeek'\nimport { Sidebar } from './dom/Sidebar'\nimport { getTodayMarkerConfig, getTodayMarkerInterval } from './dom/TodayMarker'\nimport { getCustomMarkerConfig } from './dom/CustomMarker'\n\ndayjs.extend(isoWeek)\n\nfunction mergeTheme(partial?: Partial<TimelineTheme>): TimelineTheme {\n if (!partial) return DEFAULT_THEME\n return {\n ...DEFAULT_THEME,\n ...partial,\n status: { ...DEFAULT_THEME.status, ...partial.status },\n grid: { ...DEFAULT_THEME.grid, ...partial.grid },\n item: { ...DEFAULT_THEME.item, ...partial.item },\n marker: { ...DEFAULT_THEME.marker, ...partial.marker },\n sidebar: { ...DEFAULT_THEME.sidebar, ...partial.sidebar },\n header: { ...DEFAULT_THEME.header, ...partial.header },\n }\n}\n\nconst HEADER_THROTTLE_MS = 32\n\nexport const CanvasTimeline = React.memo(forwardRef<CanvasTimelineRef, CanvasTimelineProps>(function CanvasTimeline(props, ref) {\n const {\n groups,\n items,\n defaultTimeStart,\n defaultTimeEnd,\n sidebarWidth,\n lineHeight,\n itemHeightRatio,\n stackItems,\n canMove,\n canChangeGroup,\n canResize,\n dragSnap,\n minZoom,\n maxZoom,\n theme: themePartial,\n dayStyle,\n rowStyle,\n showCursorLine,\n itemRenderer,\n groupRenderer,\n sidebarGroupRenderer,\n dependencies,\n onItemClick,\n onItemDoubleClick,\n onItemContextMenu,\n onItemMove,\n onItemResize,\n moveResizeValidator,\n onItemHover,\n onCanvasDoubleClick,\n onCanvasContextMenu,\n onTimeChange,\n onZoom,\n selected: selectedProp = [],\n rightSidebarWidth,\n rightSidebarGroupRenderer,\n onReady,\n children,\n } = props\n\n const theme = useMemo(() => mergeTheme(themePartial), [themePartial])\n\n const getGroupIndex = useCallback((groupId: string | number, grps: typeof groups) => {\n for (let i = 0; i < grps.length; i++) {\n if (grps[i].id === groupId) return i\n }\n return 0\n }, [])\n\n const selectedKey = selectedProp.join(',')\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const selected = useMemo(() => selectedProp, [selectedKey])\n\n const gridCanvasRef = useRef<HTMLCanvasElement>(null)\n const itemsCanvasRef = useRef<HTMLCanvasElement>(null)\n const overlayCanvasRef = useRef<HTMLCanvasElement>(null)\n const interactionRef = useRef<HTMLDivElement>(null)\n const outerRef = useRef<HTMLDivElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const [containerSize, setContainerSize] = useState({ width: 800, height: 600 })\n\n useEffect(() => {\n const container = outerRef.current\n if (!container) return\n const obs = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) {\n setContainerSize({ width: entry.contentRect.width, height: entry.contentRect.height })\n }\n })\n obs.observe(container)\n return () => obs.disconnect()\n }, [])\n\n const canvasWidth = Math.max(0, containerSize.width - sidebarWidth - (rightSidebarWidth ?? 0))\n const canvasHeight = groups.length * lineHeight || containerSize.height\n\n // --- MUTABLE VIEW STATE (hot path) ---\n const viewStateRef = useRef<ViewState>(\n new ViewState({\n visibleTimeStart: props.visibleTimeStart ?? defaultTimeStart,\n visibleTimeEnd: props.visibleTimeEnd ?? defaultTimeEnd,\n canvasWidth,\n canvasHeight,\n sidebarWidth,\n lineHeight,\n groupCount: groups.length,\n buffer: props.buffer ?? 3,\n scrollTop: 0,\n }),\n )\n\n const cursorXRef = useRef<number | null>(null)\n const hoveredItemIdRef = useRef<number | undefined>(undefined)\n\n // --- THROTTLED HEADER STATE ---\n const [headerTimeStart, setHeaderTimeStart] = useState(props.visibleTimeStart ?? defaultTimeStart)\n const [headerTimeEnd, setHeaderTimeEnd] = useState(props.visibleTimeEnd ?? defaultTimeEnd)\n const [sidebarScrollTop, setSidebarScrollTop] = useState(0)\n const headerTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const syncHeaderState = useCallback(() => {\n const vs = viewStateRef.current\n setHeaderTimeStart(vs.visibleTimeStart)\n setHeaderTimeEnd(vs.visibleTimeEnd)\n setSidebarScrollTop(vs.scrollTop)\n headerTimerRef.current = null\n }, [])\n\n const scheduleHeaderSync = useCallback(() => {\n if (headerTimerRef.current !== null) return\n headerTimerRef.current = setTimeout(syncHeaderState, HEADER_THROTTLE_MS)\n }, [syncHeaderState])\n\n useEffect(() => {\n return () => { if (headerTimerRef.current !== null) clearTimeout(headerTimerRef.current) }\n }, [])\n\n // --- CORE DATA STRUCTURES ---\n const intervalTree = useMemo(() => {\n const tree = new IntervalTree<(typeof items)[0]>()\n tree.buildFromItems(items, (i) => i.start_time, (i) => i.end_time)\n return tree\n }, [items])\n\n const layoutEngine = useMemo(() => {\n const engine = new LayoutEngine(lineHeight, itemHeightRatio)\n engine.computeLayout(items, stackItems)\n return engine\n }, [items, lineHeight, itemHeightRatio, stackItems])\n\n const gridLayer = useMemo(() => new GridLayer(), [])\n const itemsLayer = useMemo(() => new ItemsLayer(), [])\n const overlayLayer = useMemo(() => new OverlayLayer(), [])\n const interactionHandler = useMemo(() => new InteractionHandler(dragSnap), [dragSnap])\n\n // --- MARKERS ---\n const markerConfigs = useMemo(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n return configs\n }, [children])\n const markersKey = useMemo(() => markerConfigs.map(m => `${m.date}|${m.color}|${m.width}|${m.label ?? ''}`).join(';'), [markerConfigs])\n const markersRef = useRef(markerConfigs)\n markersRef.current = markerConfigs\n\n // TodayMarker auto-update: refresh overlay on interval\n const todayMarkerInterval = useMemo(() => {\n let interval = 0\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n interval = getTodayMarkerInterval(child.props as { interval?: number })\n }\n })\n return interval\n }, [children])\n\n // --- PROPS REF ---\n const propsRef = useRef({\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n })\n propsRef.current = {\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n }\n\n // --- DRAW FUNCTIONS ---\n const drawGrid = useCallback(() => {\n const canvas = gridCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n gridLayer.draw(ctx, viewStateRef.current, p.groups, p.theme, p.dayStyle, p.rowStyle)\n }, [gridLayer])\n\n const drawItems = useCallback(() => {\n const canvas = itemsCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n itemsLayer.draw(\n ctx, viewStateRef.current, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, hoveredItemIdRef.current, p.dependencies,\n )\n }, [itemsLayer])\n\n const calculateSnapX = useCallback((item: (typeof items)[0], deltaX: number) => {\n const vs = viewStateRef.current\n const p = propsRef.current\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n const newStart = item.start_time + deltaMs\n const snapped = Math.round(newStart / p.dragSnap) * p.dragSnap\n return vs.timeToX(snapped)\n }, [])\n\n const drawOverlay = useCallback(() => {\n const canvas = overlayCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n\n const vs = viewStateRef.current\n const state = interactionHandler.getState()\n let interactionRender = null\n if (state) {\n const origX = vs.timeToX(state.item.start_time)\n const origWidth = vs.timeToX(state.item.end_time) - origX\n let x: number, width: number\n if (state.mode === 'resize-left') {\n x = origX + state.deltaX\n width = origWidth - state.deltaX\n } else if (state.mode === 'resize-right') {\n x = origX\n width = origWidth + state.deltaX\n } else {\n // move\n x = origX + state.deltaX\n width = origWidth\n }\n const groupIndex = getGroupIndex(state.currentGroup, p.groups)\n const targetGroupY = vs.groupIndexToY(groupIndex)\n const groupChanged = state.currentGroup !== state.originalGroup\n interactionRender = {\n item: state.item,\n mode: state.mode,\n bounds: { x, y: targetGroupY + (p.lineHeight - p.lineHeight * p.itemHeightRatio) / 2, width, height: p.lineHeight * p.itemHeightRatio },\n renderer: p.itemRenderer,\n targetGroupY,\n groupChanged,\n }\n }\n\n overlayLayer.draw(ctx, vs, p.theme, {\n cursorX: p.showCursorLine ? cursorXRef.current : null,\n snapX: state ? calculateSnapX(state.item, state.deltaX) : null,\n markers: markersRef.current,\n interaction: interactionRender,\n })\n }, [overlayLayer, interactionHandler, calculateSnapX, getGroupIndex])\n\n // --- RENDER SCHEDULER ---\n const schedulerRef = useRef<RenderScheduler | null>(null)\n if (!schedulerRef.current) {\n schedulerRef.current = new RenderScheduler((flags) => {\n if (flags.grid) drawGrid()\n if (flags.items) drawItems()\n if (flags.overlay) drawOverlay()\n })\n }\n const scheduler = schedulerRef.current\n\n useEffect(() => {\n return () => scheduler.dispose()\n }, [scheduler])\n\n // --- TODAY MARKER AUTO-UPDATE ---\n useEffect(() => {\n if (!todayMarkerInterval) return\n const timer = setInterval(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n markersRef.current = configs\n scheduler.markDirty('overlay')\n }, todayMarkerInterval)\n return () => clearInterval(timer)\n }, [todayMarkerInterval, children, scheduler])\n\n // --- SYNC ON DIMENSION/DATA CHANGES ---\n useEffect(() => {\n viewStateRef.current.update({ canvasWidth, canvasHeight, sidebarWidth, lineHeight, groupCount: groups.length })\n scheduler.markAllDirty()\n }, [canvasWidth, canvasHeight, sidebarWidth, lineHeight, groups.length, scheduler])\n\n useEffect(() => {\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n }, [items, groups, selected, theme, dayStyle, rowStyle, intervalTree, layoutEngine, scheduler])\n\n const prevMarkersKey = useRef(markersKey)\n useEffect(() => {\n if (markersKey !== prevMarkersKey.current) {\n prevMarkersKey.current = markersKey\n scheduler.markDirty('overlay')\n }\n }, [markersKey, scheduler])\n\n // --- CONTROLLED MODE ---\n const prevControlledStart = useRef(props.visibleTimeStart)\n const prevControlledEnd = useRef(props.visibleTimeEnd)\n if (props.visibleTimeStart !== undefined && props.visibleTimeStart !== prevControlledStart.current) {\n prevControlledStart.current = props.visibleTimeStart\n viewStateRef.current.update({ visibleTimeStart: props.visibleTimeStart })\n scheduler.markAllDirty()\n }\n if (props.visibleTimeEnd !== undefined && props.visibleTimeEnd !== prevControlledEnd.current) {\n prevControlledEnd.current = props.visibleTimeEnd\n viewStateRef.current.update({ visibleTimeEnd: props.visibleTimeEnd })\n scheduler.markAllDirty()\n }\n\n // --- THROTTLED PARENT CALLBACKS ---\n const callbackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const scheduleCallbacks = useCallback((type: 'zoom' | 'scroll') => {\n if (callbackTimerRef.current !== null) return\n callbackTimerRef.current = setTimeout(() => {\n callbackTimerRef.current = null\n const vs = viewStateRef.current\n const p = propsRef.current\n if (type === 'zoom') {\n p.onZoom?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n } else {\n p.onTimeChange?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n }\n }, HEADER_THROTTLE_MS)\n }, [])\n\n useEffect(() => {\n return () => { if (callbackTimerRef.current !== null) clearTimeout(callbackTimerRef.current) }\n }, [])\n\n // --- ZOOM HANDLER ---\n const zoomHandlerRef = useRef<ZoomHandler | null>(null)\n const zoomHandler = useMemo(() => {\n return new ZoomHandler(\n (newStart, newEnd) => {\n viewStateRef.current.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n },\n defaultTimeStart,\n defaultTimeEnd,\n minZoom,\n maxZoom,\n )\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n zoomHandlerRef.current = zoomHandler\n\n // --- WHEEL HANDLER ---\n const handleVerticalScroll = useCallback((deltaY: number) => {\n const vs = viewStateRef.current\n const totalHeight = vs.groupCount * vs.lineHeight\n const maxScroll = Math.max(0, totalHeight - vs.canvasHeight)\n const newScrollTop = Math.max(0, Math.min(maxScroll, vs.scrollTop + deltaY))\n if (newScrollTop === vs.scrollTop) return\n vs.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }, [scheduler])\n\n const handleHorizontalScroll = useCallback((deltaX: number) => {\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n const newStart = vs.visibleTimeStart + deltaMs\n const newEnd = vs.visibleTimeEnd + deltaMs\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n flushSync(() => syncHeaderState())\n propsRef.current.onTimeChange?.(newStart, newEnd)\n }, [scheduler, syncHeaderState])\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n const handleWheel = (e: WheelEvent) => {\n if (e.ctrlKey || e.metaKey || e.altKey) {\n e.preventDefault()\n const rect = el.getBoundingClientRect()\n const cursorRatio = (e.clientX - rect.left) / rect.width\n zoomHandler.handleWheelZoom(e, cursorRatio)\n } else if (e.shiftKey) {\n e.preventDefault()\n handleHorizontalScroll(e.deltaY)\n } else {\n const deltaX = e.deltaX\n if (deltaX !== 0 && Math.abs(deltaX) > Math.abs(e.deltaY)) {\n e.preventDefault()\n handleHorizontalScroll(deltaX)\n } else if (e.deltaY !== 0) {\n handleVerticalScroll(e.deltaY)\n }\n }\n }\n el.addEventListener('wheel', handleWheel, { passive: false })\n return () => el.removeEventListener('wheel', handleWheel)\n }, [zoomHandler, handleVerticalScroll, handleHorizontalScroll])\n\n // --- TOUCH PINCH-TO-ZOOM ---\n const touchRef = useRef<{ lastDistance: number | null; lastCenter: number | null }>({ lastDistance: null, lastCenter: null })\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n\n const getDistance = (t1: Touch, t2: Touch) => Math.abs(t1.clientX - t2.clientX)\n const getCenter = (t1: Touch, t2: Touch, rect: DOMRect) => ((t1.clientX + t2.clientX) / 2) - rect.left\n\n const handleTouchStart = (e: TouchEvent) => {\n if (e.touches.length === 2) {\n e.preventDefault()\n touchRef.current.lastDistance = getDistance(e.touches[0], e.touches[1])\n touchRef.current.lastCenter = null\n }\n }\n\n const handleTouchMove = (e: TouchEvent) => {\n if (e.touches.length === 2 && touchRef.current.lastDistance !== null) {\n e.preventDefault()\n const newDistance = getDistance(e.touches[0], e.touches[1])\n const rect = el.getBoundingClientRect()\n const center = getCenter(e.touches[0], e.touches[1], rect)\n const cursorRatio = center / rect.width\n\n if (newDistance !== 0 && touchRef.current.lastDistance !== 0) {\n const scale = touchRef.current.lastDistance / newDistance\n const vs = viewStateRef.current\n const currentDuration = vs.visibleTimeEnd - vs.visibleTimeStart\n let newDuration = currentDuration * scale\n newDuration = Math.max(minZoom, Math.min(maxZoom, newDuration))\n\n const cursorTime = vs.visibleTimeStart + currentDuration * cursorRatio\n const newStart = cursorTime - newDuration * cursorRatio\n const newEnd = cursorTime + newDuration * (1 - cursorRatio)\n\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n }\n touchRef.current.lastDistance = newDistance\n }\n }\n\n const handleTouchEnd = () => {\n touchRef.current.lastDistance = null\n touchRef.current.lastCenter = null\n }\n\n el.addEventListener('touchstart', handleTouchStart, { passive: false })\n el.addEventListener('touchmove', handleTouchMove, { passive: false })\n el.addEventListener('touchend', handleTouchEnd)\n return () => {\n el.removeEventListener('touchstart', handleTouchStart)\n el.removeEventListener('touchmove', handleTouchMove)\n el.removeEventListener('touchend', handleTouchEnd)\n }\n }, [scheduler, scheduleHeaderSync, scheduleCallbacks])\n\n // --- POINTER HANDLERS ---\n const handlePointerMove = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n cursorXRef.current = x\n\n if (interactionHandler.isPending()) {\n interactionHandler.update(x, y)\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n if (state && state.mode === 'move' && propsRef.current.canChangeGroup) {\n const group = hitTestGroup(y, viewStateRef.current, propsRef.current.groups)\n if (group) interactionHandler.setCurrentGroup(group.id)\n }\n scheduler.markDirty('overlay')\n }\n return\n }\n\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n const newHoveredId = item?.id\n if (newHoveredId !== hoveredItemIdRef.current) {\n hoveredItemIdRef.current = newHoveredId\n scheduler.markDirty('items')\n p.onItemHover?.(newHoveredId ?? null, e.nativeEvent as unknown as PointerEvent)\n }\n\n // Cursor management\n if (item) {\n const edge = detectEdge(x, item, viewStateRef.current)\n const cr = p.canResize\n if (edge === 'left' && (cr === 'left' || cr === 'both')) {\n el.style.cursor = 'col-resize'\n } else if (edge === 'right' && (cr === 'right' || cr === 'both')) {\n el.style.cursor = 'col-resize'\n } else if (p.canMove) {\n el.style.cursor = 'grab'\n } else {\n el.style.cursor = 'default'\n }\n } else {\n el.style.cursor = 'default'\n }\n }, [interactionHandler, scheduler])\n\n const handlePointerDown = useCallback((e: React.PointerEvent) => {\n const p = propsRef.current\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (!item) return\n\n const edge = detectEdge(x, item, viewStateRef.current)\n const cr = p.canResize\n\n if (edge === 'left' && (cr === 'left' || cr === 'both')) {\n interactionHandler.startInteraction(item, 'resize-left', x, y)\n } else if (edge === 'right' && (cr === 'right' || cr === 'both')) {\n interactionHandler.startInteraction(item, 'resize-right', x, y)\n } else if (p.canMove) {\n interactionHandler.startInteraction(item, 'move', x, y)\n }\n }, [interactionHandler])\n\n const handlePointerUp = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n if (state) {\n const validator = propsRef.current.moveResizeValidator\n if (state.mode === 'move') {\n const result = interactionHandler.endMove(pixelsPerMs)\n if (result) {\n const validatedTime = validator ? validator('move', state.item.id, result.newStartTime) : result.newStartTime\n propsRef.current.onItemMove?.(state.item.id, validatedTime, result.newGroupId)\n }\n } else {\n const result = interactionHandler.endResize(pixelsPerMs)\n if (result) {\n const validatedTime = validator ? validator('resize', state.item.id, result.newTime, result.edge) : result.newTime\n propsRef.current.onItemResize?.(state.item.id, validatedTime, result.edge)\n }\n }\n }\n el.style.cursor = 'default'\n scheduler.markDirty('overlay')\n return\n }\n if (interactionHandler.isPending()) interactionHandler.cancel()\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, propsRef.current.intervalTree, propsRef.current.layoutEngine, propsRef.current.groups)\n if (item) propsRef.current.onItemClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n }, [interactionHandler, scheduler])\n\n const handleDoubleClick = useCallback((e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemDoubleClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasDoubleClick?.(group.id as number, time)\n }\n }, [])\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemContextMenu?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasContextMenu?.(group.id as number, time, e.nativeEvent as unknown as PointerEvent)\n }\n }, [])\n\n const handlePointerLeave = useCallback(() => {\n cursorXRef.current = null\n if (interactionRef.current) interactionRef.current.style.cursor = 'default'\n if (hoveredItemIdRef.current !== undefined) {\n hoveredItemIdRef.current = undefined\n scheduler.markDirty('items')\n propsRef.current.onItemHover?.(null, new PointerEvent('pointerleave'))\n }\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n }, [scheduler])\n\n // --- HEADER CHILDREN ---\n const headerChildren = useMemo(() => {\n const headers: React.ReactNode[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TimelineHeaders') {\n const childProps = child.props as Record<string, unknown>\n headers.push(\n React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? headerTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? headerTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n sidebarWidth: childProps.sidebarWidth ?? sidebarWidth,\n theme: childProps.theme ?? theme,\n onZoomToInterval: childProps.onZoomToInterval ?? ((start: number, end: number) => {\n viewStateRef.current.update({ visibleTimeStart: start, visibleTimeEnd: end })\n scheduler.markAllDirty()\n syncHeaderState()\n propsRef.current.onTimeChange?.(start, end)\n propsRef.current.onZoom?.(start, end)\n }),\n }),\n )\n }\n })\n return headers\n }, [children, headerTimeStart, headerTimeEnd, canvasWidth, sidebarWidth, theme, scheduler, syncHeaderState])\n\n // --- INITIAL DRAW ---\n const initialDrawDone = useRef(false)\n useEffect(() => {\n if (!initialDrawDone.current) {\n initialDrawDone.current = true\n scheduler.markAllDirty()\n }\n }, [scheduler])\n\n // --- IMPERATIVE HANDLE (print capture) ---\n useImperativeHandle(ref, () => ({\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const totalHeight = p.groups.length * p.lineHeight\n\n // Preserve the current zoom level (pixels per ms) from the on-screen view\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n\n const compositeWidth = (printSidebarWidth + timelineWidth) * scale\n const compositeHeight = (headerHeight + totalHeight) * scale\n\n const canvas = document.createElement('canvas')\n canvas.width = compositeWidth\n canvas.height = compositeHeight\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n\n // --- Draw sidebar ---\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const y = headerHeight + i * p.lineHeight\n\n // Row background from rowStyle\n if (p.rowStyle) {\n const style = p.rowStyle(group)\n if (style?.backgroundColor) {\n ctx.fillStyle = style.backgroundColor\n ctx.fillRect(0, y, printSidebarWidth, p.lineHeight)\n }\n }\n\n // Group title\n const groupType = group.type as string | undefined\n let fontWeight = '400'\n let indent = 8\n if (groupType === 'project') {\n fontWeight = '700'\n } else if (groupType === 'CAG') {\n fontWeight = '600'\n } else if (groupType === 'CA') {\n fontWeight = '400'\n indent = 24\n }\n\n ctx.fillStyle = '#111'\n ctx.font = `${fontWeight} 12px sans-serif`\n ctx.textBaseline = 'middle'\n ctx.fillText(group.title, indent, y + p.lineHeight / 2, printSidebarWidth - indent - 4)\n }\n\n // --- Draw headers ---\n const drawHeaderRow = (rowY: number, getLabel: (time: dayjs.Dayjs) => string, unit: dayjs.ManipulateType) => {\n ctx.fillStyle = p.theme.header?.bg ?? '#f5f5f5'\n ctx.fillRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n ctx.strokeStyle = p.theme.grid?.line ?? '#e0e0e0'\n ctx.lineWidth = 1\n ctx.strokeRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n\n let cursor = dayjs(timeStart).startOf(unit)\n if (cursor.valueOf() < timeStart) cursor = cursor.add(1, unit)\n\n const pxPerMs = timelineWidth / (timeEnd - timeStart)\n\n while (cursor.valueOf() < timeEnd) {\n const nextCursor = cursor.add(1, unit)\n const x = printSidebarWidth + (cursor.valueOf() - timeStart) * pxPerMs\n const endX = printSidebarWidth + (Math.min(nextCursor.valueOf(), timeEnd) - timeStart) * pxPerMs\n const width = endX - x\n\n // Vertical divider\n ctx.beginPath()\n ctx.moveTo(x, rowY)\n ctx.lineTo(x, rowY + headerRowHeight)\n ctx.stroke()\n\n // Label\n ctx.fillStyle = '#333'\n ctx.font = '600 11px sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n ctx.fillText(getLabel(cursor), x + width / 2, rowY + headerRowHeight / 2, width - 4)\n\n cursor = nextCursor\n }\n ctx.textAlign = 'start' // reset\n }\n\n drawHeaderRow(0, (d) => d.format('YYYY'), 'year')\n drawHeaderRow(headerRowHeight, (d) => d.format('MM'), 'month')\n drawHeaderRow(headerRowHeight * 2, (d) => String(d.isoWeek()), 'week')\n\n // --- Draw timeline layers ---\n const printViewState = new ViewState({\n visibleTimeStart: timeStart,\n visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth,\n canvasHeight: totalHeight,\n sidebarWidth: 0,\n lineHeight: p.lineHeight,\n groupCount: p.groups.length,\n buffer: 1,\n scrollTop: 0,\n })\n\n // Offset context for timeline area\n ctx.save()\n ctx.translate(printSidebarWidth, headerHeight)\n\n // Clip to timeline area\n ctx.beginPath()\n ctx.rect(0, 0, timelineWidth, totalHeight)\n ctx.clip()\n\n gridLayer.draw(ctx, printViewState, p.groups, p.theme, p.dayStyle, p.rowStyle)\n itemsLayer.draw(\n ctx, printViewState, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies,\n )\n overlayLayer.draw(ctx, printViewState, p.theme, {\n cursorX: null,\n snapX: null,\n markers: markersRef.current,\n interaction: null,\n })\n\n ctx.restore()\n\n return canvas\n },\n }), [gridLayer, itemsLayer, overlayLayer])\n\n // --- ON READY CALLBACK ---\n useEffect(() => {\n const api: CanvasTimelineRef = {\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const totalHeight = p.groups.length * p.lineHeight\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n const fullWidth = printSidebarWidth + timelineWidth\n const fullHeight = headerHeight + totalHeight\n\n const canvas = document.createElement('canvas')\n canvas.width = fullWidth * scale\n canvas.height = fullHeight * scale\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n ctx.fillStyle = '#FFFFFF'\n ctx.fillRect(0, 0, fullWidth, fullHeight)\n\n // Sidebar\n ctx.save()\n ctx.beginPath()\n ctx.rect(0, 0, printSidebarWidth, fullHeight)\n ctx.clip()\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(0, 0, printSidebarWidth, headerHeight)\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.strokeRect(0, 0, printSidebarWidth, headerHeight)\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const y = headerHeight + i * p.lineHeight\n const rs = p.rowStyle?.(group)\n ctx.fillStyle = rs?.backgroundColor ?? (i % 2 === 0 ? '#FFFFFF' : '#F7F7F7')\n ctx.fillRect(0, y, printSidebarWidth, p.lineHeight)\n ctx.strokeStyle = '#E5E5E5'\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + p.lineHeight)\n ctx.lineTo(printSidebarWidth, y + p.lineHeight)\n ctx.stroke()\n const gt = (group.type as string) ?? ''\n let indent = 8, fw = '400', fs = 11\n if (gt === 'project') { fw = '700'; fs = 12 }\n else if (gt === 'control_area_group') { fw = '600' }\n else if (gt === 'control_area') { indent = 24 }\n ctx.fillStyle = '#374151'\n ctx.font = `${fw} ${fs}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif`\n ctx.textBaseline = 'middle'\n const title = typeof group.title === 'string' ? group.title : String(group.title)\n ctx.fillText(title, indent, y + p.lineHeight / 2, printSidebarWidth - indent - 8)\n }\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(printSidebarWidth, 0)\n ctx.lineTo(printSidebarWidth, fullHeight)\n ctx.stroke()\n ctx.restore()\n\n // Headers\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, 0, timelineWidth, headerHeight)\n ctx.clip()\n const duration = timeEnd - timeStart\n const units: Array<{ unit: 'year' | 'month' | 'week'; row: number }> = [\n { unit: 'year', row: 0 }, { unit: 'month', row: 1 }, { unit: 'week', row: 2 },\n ]\n for (const { unit, row } of units) {\n const hy = row * headerRowHeight\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(printSidebarWidth, hy, timelineWidth, headerRowHeight)\n let cur = dayjs(timeStart).startOf(unit)\n const endBound = dayjs(timeEnd).add(1, unit)\n while (cur.isBefore(endBound)) {\n const next = cur.add(1, unit)\n const sx = printSidebarWidth + ((cur.valueOf() - timeStart) / duration) * timelineWidth\n const w = ((next.valueOf() - cur.valueOf()) / duration) * timelineWidth\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 0.5\n ctx.strokeRect(sx, hy, w, headerRowHeight)\n let label: string\n if (unit === 'year') label = cur.format('YYYY')\n else if (unit === 'month') label = cur.format('MM')\n else label = `${cur.week()}`\n ctx.fillStyle = '#6c737f'\n ctx.font = unit === 'year'\n ? '600 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n : '400 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n if (w > 20) ctx.fillText(label, sx + w / 2, hy + headerRowHeight / 2)\n cur = next\n }\n }\n ctx.textAlign = 'start'\n ctx.restore()\n\n // Timeline\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, headerHeight, timelineWidth, totalHeight)\n ctx.clip()\n ctx.translate(printSidebarWidth, headerHeight)\n const pv = new ViewState({\n visibleTimeStart: timeStart, visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth, canvasHeight: totalHeight,\n sidebarWidth: 0, lineHeight: p.lineHeight,\n groupCount: p.groups.length, buffer: 1, scrollTop: 0,\n })\n gridLayer.draw(ctx, pv, p.groups, p.theme, p.dayStyle, p.rowStyle)\n itemsLayer.draw(ctx, pv, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies)\n overlayLayer.draw(ctx, pv, p.theme, { cursorX: null, markers: markersRef.current })\n ctx.restore()\n\n return canvas\n },\n }\n onReady?.(api)\n }, [onReady, gridLayer, itemsLayer, overlayLayer])\n\n // --- RENDER ---\n const canvasContainerStyle: React.CSSProperties = {\n position: 'relative',\n width: canvasWidth,\n height: canvasHeight,\n overflow: 'hidden',\n cursor: 'default',\n }\n\n const canvasStyle: React.CSSProperties = { position: 'absolute', top: 0, left: 0 }\n\n return (\n <div ref={outerRef} style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>\n {headerChildren}\n <div ref={containerRef} style={{ display: 'flex', overflow: 'hidden' }}>\n <Sidebar\n groups={groups}\n width={sidebarWidth}\n lineHeight={lineHeight}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={sidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n <div\n ref={interactionRef}\n style={canvasContainerStyle}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onPointerLeave={handlePointerLeave}\n >\n <canvas ref={gridCanvasRef} style={{ ...canvasStyle, zIndex: 0 }} />\n <canvas ref={itemsCanvasRef} style={{ ...canvasStyle, zIndex: 1 }} />\n <canvas ref={overlayCanvasRef} style={{ ...canvasStyle, zIndex: 2 }} />\n </div>\n {rightSidebarWidth && rightSidebarGroupRenderer ? (\n <Sidebar\n groups={groups}\n width={rightSidebarWidth}\n lineHeight={lineHeight}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={rightSidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n ) : null}\n </div>\n </div>\n )\n}))\n","import React from 'react'\nimport type { TimelineTheme } from '../types'\n\nexport interface TimelineHeadersProps {\n children: React.ReactNode\n theme?: TimelineTheme\n className?: string\n classNames?: string\n style?: React.CSSProperties\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n sidebarWidth?: number\n onZoomToInterval?: (start: number, end: number) => void\n}\n\nexport function TimelineHeaders({ children, theme, className, classNames: _classNames, style, visibleTimeStart, visibleTimeEnd, canvasWidth, sidebarWidth = 0, onZoomToInterval }: TimelineHeadersProps) {\n const enhancedChildren = React.Children.map(children, (child) => {\n if (!React.isValidElement(child)) return child\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'DateHeader') {\n const childProps = child.props as Record<string, unknown>\n const enhanced = React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? visibleTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? visibleTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n theme: childProps.theme ?? theme,\n onZoomToInterval: childProps.onIntervalClick ?? childProps.onZoomToInterval ?? onZoomToInterval,\n })\n return (\n <div style={{ display: 'flex' }}>\n <div style={{ width: sidebarWidth, flexShrink: 0 }} />\n <div style={{ flex: 1, overflow: 'hidden' }}>{enhanced}</div>\n </div>\n )\n }\n return child\n })\n\n return (\n <div className={className} style={{\n position: 'sticky', top: 0, zIndex: 20, display: 'flex', flexDirection: 'column',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n borderTop: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n ...style,\n }}>\n {enhancedChildren}\n </div>\n )\n}\nTimelineHeaders.displayName = 'TimelineHeaders'\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_weekOfYear=t()}(this,(function(){\"use strict\";var e=\"week\",t=\"year\";return function(i,n,r){var f=n.prototype;f.week=function(i){if(void 0===i&&(i=null),null!==i)return this.add(7*(i-this.week()),\"day\");var n=this.$locale().yearStart||1;if(11===this.month()&&this.date()>25){var f=r(this).startOf(t).add(1,t).date(n),s=r(this).endOf(e);if(f.isBefore(s))return 1}var a=r(this).startOf(t).date(n).startOf(e).subtract(1,\"millisecond\"),o=this.diff(a,e,!0);return o<0?r(this).startOf(\"week\").week():Math.ceil(o)},f.weeks=function(e){return void 0===e&&(e=null),this.week(e)}}}));","import { useMemo, useCallback } from 'react'\nimport dayjs from 'dayjs'\nimport weekOfYear from 'dayjs/plugin/weekOfYear'\nimport type { TimelineTheme } from '../types'\n\ndayjs.extend(weekOfYear)\n\nexport type DateUnit = 'year' | 'month' | 'week' | 'day' | 'hour'\n\n// Minimum cell width in pixels before the header auto-hides\nconst DEFAULT_MIN_CELL_WIDTH: Record<DateUnit, number> = {\n year: 30,\n month: 30,\n week: 20,\n day: 15,\n hour: 30,\n}\n\nexport interface DateHeaderProps {\n unit: DateUnit\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n theme?: TimelineTheme\n height?: number\n className?: string\n labelFormat?: string | ((start: Date, end: Date, unit: DateUnit) => string)\n onIntervalClick?: (startTime: number, endTime: number) => void\n /** Minimum cell width in pixels. Header auto-hides when cells are narrower. Set to 0 to disable. */\n minCellWidth?: number\n // Called by TimelineHeaders to inject zoom behavior\n onZoomToInterval?: (start: number, end: number) => void\n}\n\nexport function DateHeader({\n unit,\n visibleTimeStart = 0,\n visibleTimeEnd = 0,\n canvasWidth = 0,\n theme,\n height = 28,\n className,\n labelFormat,\n onIntervalClick,\n minCellWidth,\n onZoomToInterval,\n}: DateHeaderProps) {\n const intervals = useMemo(() => {\n if (!visibleTimeStart || !visibleTimeEnd || !canvasWidth) return []\n\n const duration = visibleTimeEnd - visibleTimeStart\n\n // Check average cell width — auto-hide if too narrow\n const minWidth = minCellWidth ?? DEFAULT_MIN_CELL_WIDTH[unit]\n if (minWidth > 0) {\n const sampleStart = dayjs(visibleTimeStart).startOf(unit)\n const sampleEnd = sampleStart.add(1, unit)\n const avgCellWidth = ((sampleEnd.valueOf() - sampleStart.valueOf()) / duration) * canvasWidth\n if (avgCellWidth < minWidth) return []\n }\n\n const result: Array<{ start: number; end: number; label: string; left: number; width: number }> = []\n // Add buffer: 1 extra unit before and after visible range\n let current = dayjs(visibleTimeStart).startOf(unit).subtract(1, unit)\n const endBound = dayjs(visibleTimeEnd).add(2, unit).valueOf()\n\n while (current.valueOf() < endBound) {\n const next = current.add(1, unit)\n const start = current.valueOf()\n const end = next.valueOf()\n const left = ((start - visibleTimeStart) / duration) * canvasWidth\n const width = ((end - start) / duration) * canvasWidth\n const label = formatLabel(current, next, unit, labelFormat, width)\n result.push({ start, end, label, left, width })\n current = next\n }\n return result\n }, [visibleTimeStart, visibleTimeEnd, canvasWidth, unit, labelFormat, minCellWidth])\n\n const handleClick = useCallback((start: number, end: number) => {\n if (onIntervalClick) {\n onIntervalClick(start, end)\n } else if (onZoomToInterval) {\n onZoomToInterval(start, end)\n }\n }, [onIntervalClick, onZoomToInterval])\n\n // Auto-hide: return nothing if no intervals (cells too narrow)\n if (intervals.length === 0) return null\n\n return (\n <div style={{ display: 'flex', position: 'relative', height, overflow: 'hidden' }}>\n {intervals.map((interval) => (\n <div\n key={interval.start}\n className={className}\n onClick={() => handleClick(interval.start, interval.end)}\n style={{\n position: 'absolute',\n left: interval.left,\n width: interval.width,\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRight: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n fontSize: 12,\n color: theme?.header.text ?? '#6c737f',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n cursor: 'pointer',\n userSelect: 'none',\n padding: '0 4px',\n boxSizing: 'border-box',\n }}\n >\n <span>{interval.label}</span>\n </div>\n ))}\n </div>\n )\n}\nDateHeader.displayName = 'DateHeader'\n\nfunction formatLabel(\n start: dayjs.Dayjs,\n end: dayjs.Dayjs,\n unit: DateUnit,\n labelFormat: string | ((start: Date, end: Date, unit: DateUnit) => string) | undefined,\n _width: number,\n): string {\n if (typeof labelFormat === 'function') {\n return labelFormat(start.toDate(), end.toDate(), unit)\n }\n if (typeof labelFormat === 'string') {\n return start.format(labelFormat)\n }\n return formatDefault(start, unit)\n}\n\nfunction formatDefault(d: dayjs.Dayjs, unit: DateUnit): string {\n switch (unit) {\n case 'year': return d.format('YYYY')\n case 'month': return d.format('MM')\n case 'week': return `${d.week()}`\n case 'day': return d.format('D')\n case 'hour': return d.format('HH:mm')\n }\n}\n","import React from 'react'\n\ninterface SidebarHeaderProps {\n width: number\n children?: (props: { getRootProps: () => React.HTMLAttributes<HTMLDivElement> }) => React.ReactNode\n style?: React.CSSProperties\n}\n\nexport function SidebarHeader({ width, children, style }: SidebarHeaderProps) {\n const getRootProps = (): React.HTMLAttributes<HTMLDivElement> => ({ style: { width, ...style } })\n if (children) return <>{children({ getRootProps })}</>\n return <div style={{ width }} />\n}\nSidebarHeader.displayName = 'SidebarHeader'\n","import React from 'react'\ninterface CustomHeaderProps { children: React.ReactNode }\nexport function CustomHeader({ children }: CustomHeaderProps) { return <>{children}</> }\nCustomHeader.displayName = 'CustomHeader'\n"],"names":["DEFAULT_THEME","ViewState","config","params","time","x","y","raw","index","extend","firstVisible","visibleCount","lastVisible","scrollXOffset","bufferPixels","IntervalTree","items","getStart","getEnd","intervals","item","min","max","iv","center","leftIntervals","rightIntervals","overlapping","start","end","results","node","LayoutEngine","lineHeight","itemHeightRatio","stackItems","itemHeight","byGroup","arr","groupId","groupItems","a","b","d","levelEnds","maxLevel","level","i","itemId","hitTest","canvasX","canvasY","view","tree","layout","groups","groupIndexMap","candidates","topItem","topY","groupIndex","itemLayout","width","height","hitTestGroup","detectEdge","threshold","leftX","rightX","setupCanvas","canvas","dpr","targetW","targetH","ctx","clearCanvas","RenderScheduler","drawCallback","layer","flags","GridLayer","theme","dayStyle","rowStyle","group","bgColor","customRow","visibleStart","visibleEnd","dayPixelWidth","stepUnit","current","dayjs","batchColor","batchOpacity","batchStartX","customBorderLines","flushBatch","endX","date","custom","color","opacity","dow","line","ITEM_FONT","createDrawHelpers","bounds","w","h","radius","text","maxWidth","lo","hi","mid","candidate","color1","color2","grad","type","size","half","cx","cy","fillColor","stemW","stemX","textWidth","paddingH","pillHeight","pillWidth","ItemsLayer","_items","itemRenderer","groupRenderer","selected","hoveredItemId","dependencies","padding","queryStart","queryEnd","visibleItems","selectedSet","itemBoundsMap","yMin","yMax","state","helpers","boundsMap","dep","fromBounds","toBounds","isHighlighted","startX","startY","endY","dx","cpOffset","arrowSize","OverlayLayer","options","cursorX","snapX","markers","interaction","marker","maxBadgeWidth","badgeWidth","badgeHeight","badgeX","badgeY","maxTextWidth","displayText","MAX_DELTA","normalizeDelta","e","delta","ZoomHandler","onZoom","visibleTimeStart","visibleTimeEnd","minZoom","maxZoom","cursorRatio","speed","scale","currentDuration","newDuration","newStart","newEnd","ACTIVATION_THRESHOLD","InteractionHandler","dragSnap","mode","pixelsPerMs","deltaMs","newStartTime","snapped","newGroupId","edge","newTime","_a","t","module","this","s","n","o","r","u","OVERSCAN","Sidebar","scrollTop","canvasHeight","onScroll","containerRef","useRef","isScrollingRef","totalHeight","displayHeight","handleScroll","useCallback","useEffect","visibleGroups","_jsx","TodayMarker","_props","getTodayMarkerConfig","props","getTodayMarkerInterval","CustomMarker","getCustomMarkerConfig","isoWeek","mergeTheme","partial","HEADER_THROTTLE_MS","CanvasTimeline","React","forwardRef","ref","defaultTimeStart","defaultTimeEnd","sidebarWidth","canMove","canChangeGroup","canResize","themePartial","showCursorLine","sidebarGroupRenderer","onItemClick","onItemDoubleClick","onItemContextMenu","onItemMove","onItemResize","moveResizeValidator","onItemHover","onCanvasDoubleClick","onCanvasContextMenu","onTimeChange","selectedProp","rightSidebarWidth","rightSidebarGroupRenderer","onReady","children","useMemo","getGroupIndex","grps","selectedKey","gridCanvasRef","itemsCanvasRef","overlayCanvasRef","interactionRef","outerRef","containerSize","setContainerSize","useState","container","obs","entries","entry","canvasWidth","viewStateRef","cursorXRef","hoveredItemIdRef","headerTimeStart","setHeaderTimeStart","headerTimeEnd","setHeaderTimeEnd","sidebarScrollTop","setSidebarScrollTop","headerTimerRef","syncHeaderState","vs","scheduleHeaderSync","intervalTree","layoutEngine","engine","gridLayer","itemsLayer","overlayLayer","interactionHandler","markerConfigs","configs","child","displayName","markersKey","m","markersRef","todayMarkerInterval","interval","propsRef","drawGrid","p","drawItems","calculateSnapX","deltaX","drawOverlay","interactionRender","origX","origWidth","targetGroupY","groupChanged","schedulerRef","scheduler","timer","prevMarkersKey","prevControlledStart","prevControlledEnd","callbackTimerRef","scheduleCallbacks","_b","zoomHandlerRef","zoomHandler","handleVerticalScroll","deltaY","maxScroll","newScrollTop","handleHorizontalScroll","flushSync","_c","el","handleWheel","rect","touchRef","getDistance","t1","t2","getCenter","handleTouchStart","handleTouchMove","newDistance","cursorTime","handleTouchEnd","handlePointerMove","newHoveredId","cr","handlePointerDown","handlePointerUp","validator","result","validatedTime","_d","_f","_e","handleDoubleClick","handleContextMenu","handlePointerLeave","headerChildren","headers","childProps","initialDrawDone","useImperativeHandle","timeStart","timeEnd","printSidebarWidth","headerRowHeight","headerHeight","currentPixelsPerMs","printDuration","timelineWidth","compositeWidth","compositeHeight","style","groupType","fontWeight","indent","drawHeaderRow","rowY","getLabel","unit","cursor","pxPerMs","nextCursor","printViewState","api","fullWidth","fullHeight","rs","gt","fw","fs","title","duration","units","row","hy","cur","endBound","next","sx","label","pv","canvasContainerStyle","canvasStyle","_jsxs","TimelineHeaders","className","_classNames","onZoomToInterval","enhancedChildren","enhanced","f","weekOfYear","DEFAULT_MIN_CELL_WIDTH","DateHeader","labelFormat","onIntervalClick","minCellWidth","minWidth","sampleStart","left","formatLabel","handleClick","_width","formatDefault","SidebarHeader","getRootProps","_Fragment","CustomHeader"],"mappings":"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","x_google_ignoreList":[12,18]}
1
+ {"version":3,"file":"canvas-timeline.es.js","sources":["../src/types.ts","../src/core/ViewState.ts","../src/core/IntervalTree.ts","../src/core/LayoutEngine.ts","../src/core/HitTest.ts","../src/canvas/CanvasManager.ts","../src/canvas/GridLayer.ts","../src/canvas/DrawHelpers.ts","../src/canvas/ItemsLayer.ts","../src/canvas/OverlayLayer.ts","../src/interaction/ZoomHandler.ts","../src/interaction/InteractionHandler.ts","../src/interaction/snapUtils.ts","../node_modules/dayjs/plugin/isoWeek.js","../src/dom/Sidebar.tsx","../src/dom/TodayMarker.tsx","../src/dom/CustomMarker.tsx","../src/CanvasTimeline.tsx","../src/dom/TimelineHeaders.tsx","../node_modules/dayjs/plugin/weekOfYear.js","../src/dom/DateHeader.tsx","../src/dom/SidebarHeader.tsx","../src/dom/CustomHeader.tsx"],"sourcesContent":["import type React from 'react'\n\nexport interface Group {\n id: number | string\n title: string\n type?: string\n hierarchy?: string\n root?: boolean\n [key: string]: unknown\n}\n\nexport interface Item {\n id: number\n group: number | string\n start_time: number\n end_time: number\n type?: string\n [key: string]: unknown\n}\n\nexport interface ItemBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface ItemState {\n selected: boolean\n hovered: boolean\n dragging: boolean\n filtered: boolean\n}\n\nexport interface DrawHelpers {\n roundRect(x: number, y: number, w: number, h: number, radius?: number): void\n fillText(text: string, x: number, y: number, maxWidth?: number): void\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient\n leftBar(color: string, width?: number): void\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size?: number): void\n badge(text: string, x: number, y: number, bgColor: string): void\n}\n\nexport type CanvasItemRenderer = (\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n helpers: DrawHelpers,\n) => void\n\nexport type CanvasGroupItemRenderer = CanvasItemRenderer\n\nexport interface DayStyle {\n backgroundColor?: string\n borderColor?: string\n opacity?: number\n}\n\nexport interface RowStyle {\n backgroundColor?: string\n borderBottomColor?: string\n}\n\nexport interface Dependency {\n fromItemId: number\n toItemId: number\n type?: 'finish-to-start' | 'start-to-start' | 'finish-to-finish'\n color?: string\n}\n\nexport interface TimeRangeHighlight {\n start: number\n end: number\n color: string\n label?: string\n opacity?: number\n}\n\nexport interface TimelineTheme {\n primary: string\n trainColors: Record<string, string>\n status: { red: string; yellow: string; green: string }\n grid: { line: string; rowAlt: string; weekend: string }\n item: { radius: number; text: string; selectedRing: string }\n marker: { today: string; milestone: string; cursor: string }\n sidebar: { bg: string; border: string; text: string }\n header: { bg: string; border: string; text: string }\n}\n\nexport const DEFAULT_THEME: TimelineTheme = {\n primary: '#269bf7',\n trainColors: {},\n status: { red: '#EF5350', yellow: '#FBBF24', green: '#31c48d' },\n grid: { line: '#E5E5E5', rowAlt: '#F7F7F7', weekend: 'rgba(0,0,0,0.03)' },\n item: { radius: 3, text: '#374151', selectedRing: '#a3a3a3' },\n marker: { today: '#FD7171', milestone: '#3B82F6', cursor: '#269bf7' },\n sidebar: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n header: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n}\n\nexport interface MarkerConfig {\n date: number\n color: string\n width: number\n label?: string\n}\n\nexport interface CanvasTimelineProps {\n groups: Group[]\n items: Item[]\n defaultTimeStart: number\n defaultTimeEnd: number\n visibleTimeStart?: number\n visibleTimeEnd?: number\n sidebarWidth: number\n lineHeight: number\n itemHeightRatio: number\n stackItems: boolean\n buffer?: number\n canMove: boolean\n canResize: false | 'left' | 'right' | 'both'\n canChangeGroup: boolean\n dragSnap: number\n minZoom: number\n maxZoom: number\n theme?: Partial<TimelineTheme>\n dayStyle?: (date: Date) => DayStyle | null\n rowStyle?: (group: Group) => RowStyle | null\n showCursorLine?: boolean\n itemRenderer: CanvasItemRenderer\n groupRenderer?: CanvasGroupItemRenderer\n sidebarGroupRenderer: (group: Group) => React.ReactNode\n rightSidebarWidth?: number\n rightSidebarGroupRenderer?: (group: Group) => React.ReactNode\n dependencies?: Dependency[]\n highlights?: TimeRangeHighlight[]\n onItemClick?: (itemId: number, e: PointerEvent) => void\n onItemDoubleClick?: (itemId: number, e: PointerEvent) => void\n onItemContextMenu?: (itemId: number, e: PointerEvent) => void\n onItemMove?: (itemId: number, newStartTime: number, newGroupId: string | number) => void\n onItemResize?: (itemId: number, newTime: number, edge: 'left' | 'right') => void\n /** Validate and optionally constrain move/resize. Return the (possibly modified) time. */\n moveResizeValidator?: (action: 'move' | 'resize', itemId: number, time: number, edge?: 'left' | 'right') => number\n onItemHover?: (itemId: number | null, e: PointerEvent) => void\n onCanvasDoubleClick?: (groupId: number, time: number) => void\n onCanvasContextMenu?: (groupId: number, time: number, e: PointerEvent) => void\n onTimeChange?: (start: number, end: number) => void\n onZoom?: (start: number, end: number) => void\n selected?: number[]\n /** Called when the timeline is ready, providing the capture API */\n onReady?: (api: CanvasTimelineRef) => void\n children?: React.ReactNode\n}\n\nexport interface CaptureOptions {\n timeStart: number\n timeEnd: number\n scale: number\n sidebarWidth: number\n}\n\nexport interface CanvasTimelineRef {\n captureToCanvas(options: CaptureOptions): HTMLCanvasElement\n}\n","export interface ViewStateConfig {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n}\n\nexport class ViewState {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n\n private visibleDuration: number\n private pixelsPerMs: number\n\n constructor(config: ViewStateConfig) {\n this.visibleTimeStart = config.visibleTimeStart\n this.visibleTimeEnd = config.visibleTimeEnd\n this.canvasWidth = config.canvasWidth\n this.canvasHeight = config.canvasHeight\n this.sidebarWidth = config.sidebarWidth\n this.lineHeight = config.lineHeight\n this.groupCount = config.groupCount\n this.buffer = config.buffer\n this.scrollTop = config.scrollTop\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n }\n\n update(params: Partial<ViewStateConfig>): void {\n if (params.visibleTimeStart !== undefined) this.visibleTimeStart = params.visibleTimeStart\n if (params.visibleTimeEnd !== undefined) this.visibleTimeEnd = params.visibleTimeEnd\n if (params.canvasWidth !== undefined) this.canvasWidth = params.canvasWidth\n if (params.canvasHeight !== undefined) this.canvasHeight = params.canvasHeight\n if (params.sidebarWidth !== undefined) this.sidebarWidth = params.sidebarWidth\n if (params.lineHeight !== undefined) this.lineHeight = params.lineHeight\n if (params.groupCount !== undefined) this.groupCount = params.groupCount\n if (params.buffer !== undefined) this.buffer = params.buffer\n if (params.scrollTop !== undefined) this.scrollTop = params.scrollTop\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n }\n\n timeToX(time: number): number {\n return (time - this.visibleTimeStart) * this.pixelsPerMs\n }\n\n xToTime(x: number): number {\n return this.visibleTimeStart + x / this.pixelsPerMs\n }\n\n yToGroupIndex(y: number): number {\n const raw = Math.floor((y + this.scrollTop) / this.lineHeight)\n return Math.max(0, Math.min(raw, this.groupCount - 1))\n }\n\n groupIndexToY(index: number): number {\n return index * this.lineHeight - this.scrollTop\n }\n\n getBufferBounds(): { bufferStart: number; bufferEnd: number } {\n const extend = this.visibleDuration * 1.5\n return {\n bufferStart: this.visibleTimeStart - extend,\n bufferEnd: this.visibleTimeEnd + extend,\n }\n }\n\n getVisibleGroupRange(): { firstVisible: number; lastVisible: number } {\n const firstVisible = Math.max(0, Math.floor(this.scrollTop / this.lineHeight))\n const visibleCount = Math.ceil(this.canvasHeight / this.lineHeight)\n const lastVisible = Math.min(this.groupCount - 1, firstVisible + visibleCount)\n return { firstVisible, lastVisible }\n }\n\n isScrollInBuffer(scrollXOffset: number): boolean {\n const bufferPixels = this.visibleDuration * 1.5 * this.pixelsPerMs\n return Math.abs(scrollXOffset) < bufferPixels\n }\n\n getTotalHeight(): number {\n return this.groupCount * this.lineHeight\n }\n}\n","interface TreeNode<T> {\n center: number\n left: TreeNode<T> | null\n right: TreeNode<T> | null\n overlapping: Array<{ item: T; start: number; end: number }>\n}\n\nexport class IntervalTree<T> {\n private root: TreeNode<T> | null = null\n\n buildFromItems(\n items: T[],\n getStart: (item: T) => number,\n getEnd: (item: T) => number,\n ): void {\n const intervals = items.map((item) => ({\n item,\n start: getStart(item),\n end: getEnd(item),\n }))\n this.root = this.buildNode(intervals)\n }\n\n private buildNode(\n intervals: Array<{ item: T; start: number; end: number }>,\n ): TreeNode<T> | null {\n if (intervals.length === 0) return null\n\n let min = Infinity\n let max = -Infinity\n for (const iv of intervals) {\n if (iv.start < min) min = iv.start\n if (iv.end > max) max = iv.end\n }\n const center = (min + max) / 2\n\n const leftIntervals: Array<{ item: T; start: number; end: number }> = []\n const rightIntervals: Array<{ item: T; start: number; end: number }> = []\n const overlapping: Array<{ item: T; start: number; end: number }> = []\n\n for (const iv of intervals) {\n if (iv.end < center) {\n leftIntervals.push(iv)\n } else if (iv.start > center) {\n rightIntervals.push(iv)\n } else {\n overlapping.push(iv)\n }\n }\n\n return {\n center,\n left: this.buildNode(leftIntervals),\n right: this.buildNode(rightIntervals),\n overlapping,\n }\n }\n\n query(start: number, end: number): T[] {\n const results: T[] = []\n this.queryNode(this.root, start, end, results)\n return results\n }\n\n private queryNode(\n node: TreeNode<T> | null,\n start: number,\n end: number,\n results: T[],\n ): void {\n if (node === null) return\n\n for (const iv of node.overlapping) {\n if (iv.start <= end && iv.end >= start) {\n results.push(iv.item)\n }\n }\n\n if (start <= node.center && node.left !== null) {\n this.queryNode(node.left, start, end, results)\n }\n\n if (end >= node.center && node.right !== null) {\n this.queryNode(node.right, start, end, results)\n }\n }\n}\n","import type { Item } from '../types'\n\nexport interface ItemLayout {\n stackLevel: number\n itemHeight: number\n}\n\nexport class LayoutEngine {\n private readonly lineHeight: number\n private readonly itemHeightRatio: number\n private layoutCache: Map<number, ItemLayout> = new Map()\n private groupMaxStack: Map<string | number, number> = new Map()\n\n constructor(lineHeight: number, itemHeightRatio: number) {\n this.lineHeight = lineHeight\n this.itemHeightRatio = itemHeightRatio\n }\n\n computeLayout(items: Item[], stackItems: boolean): Map<number, ItemLayout> {\n this.layoutCache = new Map()\n this.groupMaxStack = new Map()\n\n if (!stackItems) {\n const itemHeight = this.lineHeight * this.itemHeightRatio\n for (const item of items) {\n this.layoutCache.set(item.id, { stackLevel: 0, itemHeight })\n this.groupMaxStack.set(item.group, 0)\n }\n return this.layoutCache\n }\n\n // Group items by group id\n const byGroup = new Map<string | number, Item[]>()\n for (const item of items) {\n let arr = byGroup.get(item.group)\n if (!arr) {\n arr = []\n byGroup.set(item.group, arr)\n }\n arr.push(item)\n }\n\n const itemHeight = this.lineHeight * this.itemHeightRatio\n\n for (const [groupId, groupItems] of byGroup) {\n groupItems.sort((a, b) => {\n const d = a.start_time - b.start_time\n if (d !== 0) return d\n return (b.end_time - b.start_time) - (a.end_time - a.start_time)\n })\n\n const levelEnds: number[] = []\n let maxLevel = 0\n\n for (const item of groupItems) {\n let level = -1\n for (let i = 0; i < levelEnds.length; i++) {\n if (levelEnds[i] <= item.start_time) {\n level = i\n break\n }\n }\n\n if (level === -1) {\n level = levelEnds.length\n levelEnds.push(item.end_time)\n } else {\n levelEnds[level] = item.end_time\n }\n\n if (level > maxLevel) maxLevel = level\n\n this.layoutCache.set(item.id, { stackLevel: level, itemHeight })\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\n }\n\n return this.layoutCache\n }\n\n getLayout(itemId: number): ItemLayout | undefined {\n return this.layoutCache.get(itemId)\n }\n\n getGroupHeight(groupId: string | number): number {\n const maxStack = this.groupMaxStack.get(groupId) ?? 0\n return (maxStack + 1) * this.lineHeight\n }\n}\n","import type { Item, Group } from '../types'\nimport type { ViewState } from './ViewState'\nimport type { IntervalTree } from './IntervalTree'\nimport type { LayoutEngine } from './LayoutEngine'\n\nexport function hitTest(\n canvasX: number,\n canvasY: number,\n view: ViewState,\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n groups: Group[],\n): Item | null {\n const time = view.xToTime(canvasX)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const candidates = tree.query(time, time)\n\n let topItem: Item | null = null\n let topY = -Infinity\n\n for (const item of candidates) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n if (canvasX < x || canvasX > x + width) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n const height = itemLayout.itemHeight\n\n if (canvasY < y || canvasY > y + height) continue\n\n if (y > topY) {\n topY = y\n topItem = item\n }\n }\n\n return topItem\n}\n\nexport function hitTestGroup(\n canvasY: number,\n view: ViewState,\n groups: Group[],\n): Group | null {\n const groupIndex = view.yToGroupIndex(canvasY)\n return groups[groupIndex] ?? null\n}\n\nexport function detectEdge(\n canvasX: number,\n item: Item,\n view: ViewState,\n threshold: number = 6,\n): 'left' | 'right' | 'body' {\n const leftX = view.timeToX(item.start_time)\n const rightX = view.timeToX(item.end_time)\n if (canvasX - leftX <= threshold) return 'left'\n if (rightX - canvasX <= threshold) return 'right'\n return 'body'\n}\n","/**\n * Resize the canvas buffer only when dimensions actually change.\n * Setting canvas.width/height is destructive (clears buffer + resets state),\n * so we avoid it unless necessary.\n */\nexport function setupCanvas(\n canvas: HTMLCanvasElement,\n width: number,\n height: number,\n): CanvasRenderingContext2D {\n const dpr = window.devicePixelRatio || 1\n const targetW = Math.round(width * dpr)\n const targetH = Math.round(height * dpr)\n\n if (canvas.width !== targetW || canvas.height !== targetH) {\n canvas.width = targetW\n canvas.height = targetH\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n }\n\n const ctx = canvas.getContext('2d')!\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n return ctx\n}\n\nexport function clearCanvas(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement): void {\n const dpr = window.devicePixelRatio || 1\n ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr)\n}\n\nexport type LayerName = 'grid' | 'items' | 'overlay'\n\nexport interface DirtyFlags {\n grid: boolean\n items: boolean\n overlay: boolean\n}\n\nexport class RenderScheduler {\n private dirty: DirtyFlags = { grid: false, items: false, overlay: false }\n private rafId: number | null = null\n private drawCallback: (flags: DirtyFlags) => void\n\n constructor(drawCallback: (flags: DirtyFlags) => void) {\n this.drawCallback = drawCallback\n }\n\n markDirty(layer: LayerName): void {\n this.dirty[layer] = true\n this.schedule()\n }\n\n markAllDirty(): void {\n this.dirty.grid = true\n this.dirty.items = true\n this.dirty.overlay = true\n this.schedule()\n }\n\n dispose(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n private schedule(): void {\n if (this.rafId !== null) return\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n const flags = { ...this.dirty }\n this.dirty.grid = false\n this.dirty.items = false\n this.dirty.overlay = false\n this.drawCallback(flags)\n })\n }\n}\n","import dayjs from 'dayjs'\nimport type { Group, TimelineTheme, DayStyle, RowStyle, TimeRangeHighlight } from '../types'\nimport type { ViewState } from '../core/ViewState'\n\nexport class GridLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n theme: TimelineTheme,\n dayStyle?: (date: Date) => DayStyle | null,\n rowStyle?: (group: Group) => RowStyle | null,\n highlights?: TimeRangeHighlight[],\n ): void {\n const { firstVisible, lastVisible } = view.getVisibleGroupRange()\n\n // Draw row backgrounds\n for (let i = firstVisible; i <= lastVisible; i++) {\n const y = view.groupIndexToY(i)\n const group = groups[i]\n if (!group) continue\n\n let bgColor: string\n const customRow = rowStyle?.(group)\n if (customRow?.backgroundColor) {\n bgColor = customRow.backgroundColor\n } else {\n bgColor = i % 2 === 0 ? '#FFFFFF' : theme.grid.rowAlt\n }\n\n ctx.fillStyle = bgColor\n ctx.fillRect(0, y, view.canvasWidth, view.lineHeight)\n\n // Row separator\n ctx.strokeStyle = customRow?.borderBottomColor ?? theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + view.lineHeight)\n ctx.lineTo(view.canvasWidth, y + view.lineHeight)\n ctx.stroke()\n }\n\n // Draw time range highlight backgrounds (under grid lines)\n if (highlights && highlights.length > 0) {\n for (const h of highlights) {\n const x1 = view.timeToX(h.start)\n const x2 = view.timeToX(h.end)\n if (x2 < 0 || x1 > view.canvasWidth) continue\n\n const x = Math.max(0, x1)\n const w = Math.min(view.canvasWidth, x2) - x\n\n const opacity = h.opacity ?? 0.12\n const r = parseInt(h.color.slice(1, 3), 16)\n const g = parseInt(h.color.slice(3, 5), 16)\n const b = parseInt(h.color.slice(5, 7), 16)\n ctx.fillStyle = `rgb(${Math.round(r * opacity + 255 * (1 - opacity))},${Math.round(g * opacity + 255 * (1 - opacity))},${Math.round(b * opacity + 255 * (1 - opacity))})`\n ctx.fillRect(x, 0, w, view.canvasHeight)\n }\n }\n\n // Draw day columns, backgrounds, and vertical grid lines\n const visibleStart = view.visibleTimeStart\n const visibleEnd = view.visibleTimeEnd\n const visibleDuration = visibleEnd - visibleStart\n const dayMs = 86400000\n const dayPixelWidth = (dayMs / visibleDuration) * view.canvasWidth\n\n // Determine grid line interval based on zoom level\n let stepUnit: 'day' | 'week' | 'month' = 'day'\n if (dayPixelWidth < 2) stepUnit = 'month'\n else if (dayPixelWidth < 8) stepUnit = 'week'\n\n // Draw day backgrounds (dayStyle + weekends) — batch consecutive same-style days\n if (dayStyle || true) { // always draw weekends\n let current = dayjs(visibleStart).startOf('day')\n const end = dayjs(visibleEnd).endOf('day')\n\n // Batch: track current fill color and start x\n let batchColor: string | null = null\n let batchOpacity = 1\n let batchStartX = 0\n const customBorderLines: { x: number; color: string }[] = []\n\n const flushBatch = (endX: number) => {\n if (batchColor !== null) {\n ctx.fillStyle = batchColor\n if (batchOpacity !== 1) ctx.globalAlpha = batchOpacity\n ctx.fillRect(batchStartX, 0, endX - batchStartX, view.canvasHeight)\n if (batchOpacity !== 1) ctx.globalAlpha = 1\n batchColor = null\n batchOpacity = 1\n }\n }\n\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n\n const date = current.toDate()\n const custom = dayStyle?.(date)\n let color: string | null = null\n let opacity = 1\n\n if (custom?.backgroundColor) {\n color = custom.backgroundColor\n opacity = custom.opacity ?? 1\n } else {\n const dow = current.day()\n if (dow === 0 || dow === 6) {\n color = theme.grid.weekend\n }\n }\n\n // Collect custom border colors for later drawing\n if (custom?.borderColor) {\n customBorderLines.push({ x, color: custom.borderColor })\n }\n\n // Batch consecutive same-color fills\n if (color === batchColor && opacity === batchOpacity) {\n // extend batch\n } else {\n flushBatch(x)\n if (color !== null) {\n batchColor = color\n batchOpacity = opacity\n batchStartX = x\n }\n }\n\n current = current.add(1, 'day')\n }\n // Flush remaining batch\n if (batchColor !== null) {\n flushBatch(view.timeToX(current.valueOf()))\n }\n\n // Draw custom border lines from dayStyle\n for (const line of customBorderLines) {\n ctx.strokeStyle = line.color\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(line.x, 0)\n ctx.lineTo(line.x, view.canvasHeight)\n ctx.stroke()\n }\n }\n\n // Draw vertical grid lines at appropriate interval\n let current = dayjs(visibleStart).startOf(stepUnit)\n const end = dayjs(visibleEnd).add(1, stepUnit)\n\n ctx.strokeStyle = theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n ctx.moveTo(x, 0)\n ctx.lineTo(x, view.canvasHeight)\n current = current.add(1, stepUnit)\n }\n ctx.stroke()\n\n // Draw time range highlight edge lines and labels (after grid lines so they render on top)\n if (highlights && highlights.length > 0) {\n for (const h of highlights) {\n const x1 = view.timeToX(h.start)\n const x2 = view.timeToX(h.end)\n if (x2 < 0 || x1 > view.canvasWidth) continue\n\n // Edge lines\n ctx.strokeStyle = h.color\n ctx.globalAlpha = 0.4\n ctx.lineWidth = 1\n ctx.beginPath()\n if (x1 >= 0 && x1 <= view.canvasWidth) {\n ctx.moveTo(x1, 0)\n ctx.lineTo(x1, view.canvasHeight)\n }\n if (x2 >= 0 && x2 <= view.canvasWidth) {\n ctx.moveTo(x2, 0)\n ctx.lineTo(x2, view.canvasHeight)\n }\n ctx.stroke()\n ctx.globalAlpha = 1\n\n // Label badge\n if (h.label) {\n const x = Math.max(0, x1)\n const w = Math.min(view.canvasWidth, x2) - x\n\n ctx.save()\n ctx.font = '600 10px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n const textWidth = ctx.measureText(h.label).width\n const padding = 6\n const badgeWidth = textWidth + padding * 2\n const badgeHeight = 18\n const badgeX = x + (w - badgeWidth) / 2\n const badgeY = 4\n\n ctx.fillStyle = h.color\n ctx.globalAlpha = 0.9\n ctx.beginPath()\n ctx.roundRect(badgeX, badgeY, badgeWidth, badgeHeight, 3)\n ctx.fill()\n\n ctx.globalAlpha = 1\n ctx.fillStyle = '#FFFFFF'\n ctx.textBaseline = 'middle'\n ctx.fillText(h.label, badgeX + padding, badgeY + badgeHeight / 2)\n ctx.restore()\n }\n }\n }\n }\n}\n","import type { DrawHelpers, ItemBounds } from '../types'\n\nconst ITEM_FONT = '500 12px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n\n/**\n * Creates a DrawHelpers object bound to the given canvas context and optional item bounds.\n * These helpers are passed to every itemRenderer call to simplify common canvas operations.\n */\nexport function createDrawHelpers(\n ctx: CanvasRenderingContext2D,\n bounds?: ItemBounds,\n): DrawHelpers {\n return {\n /**\n * Draws a filled rounded rectangle.\n * Default corner radius is 3px.\n */\n roundRect(x: number, y: number, w: number, h: number, radius = 3): void {\n ctx.beginPath()\n ctx.roundRect(x, y, w, h, radius)\n ctx.fill()\n },\n\n /**\n * Draws text at (x, y) using the standard item font.\n * If maxWidth is provided and the text is too wide, binary-search truncates it\n * and appends '...' so it fits within maxWidth.\n */\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n ctx.font = ITEM_FONT\n\n if (maxWidth !== undefined && ctx.measureText(text).width > maxWidth) {\n // Binary-search for the longest prefix that fits with '...' appended\n let lo = 0\n let hi = text.length\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n const candidate = text.slice(0, mid) + '...'\n if (ctx.measureText(candidate).width <= maxWidth) {\n lo = mid\n } else {\n hi = mid - 1\n }\n }\n ctx.fillText(text.slice(0, lo) + '...', x, y)\n } else {\n ctx.fillText(text, x, y)\n }\n },\n\n /**\n * Creates a 50/50 linear gradient from color1 (0%–50%) to color2 (50%–100%)\n * spanning the given x position and width.\n */\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient {\n const grad = ctx.createLinearGradient(x, 0, x + w, 0)\n grad.addColorStop(0, color1)\n grad.addColorStop(0.5, color1)\n grad.addColorStop(0.5, color2)\n grad.addColorStop(1, color2)\n return grad\n },\n\n /**\n * Draws a vertical colored bar on the left edge of the item bounds.\n * Does nothing if no bounds were provided.\n */\n leftBar(color: string, width = 3): void {\n if (!bounds) return\n ctx.save()\n ctx.fillStyle = color\n ctx.fillRect(bounds.x, bounds.y, width, bounds.height)\n ctx.restore()\n },\n\n /**\n * Draws a vector icon centered at (x, y).\n * Supported types: 'check', 'danger-red', 'danger-yellow'.\n * Default size is 14px.\n */\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size = 14): void {\n ctx.save()\n const half = size / 2\n\n if (type === 'check') {\n // Green circle with white checkmark\n ctx.fillStyle = '#31c48d'\n ctx.beginPath()\n ctx.arc(x + half, y + half, half, 0, Math.PI * 2)\n ctx.fill()\n\n // Draw checkmark path\n ctx.strokeStyle = '#ffffff'\n ctx.lineWidth = size * 0.12\n ctx.beginPath()\n const cx = x + half\n const cy = y + half\n ctx.moveTo(cx - half * 0.45, cy)\n ctx.lineTo(cx - half * 0.1, cy + half * 0.42)\n ctx.lineTo(cx + half * 0.45, cy - half * 0.35)\n ctx.stroke()\n } else if (type === 'danger-red' || type === 'danger-yellow') {\n const fillColor = type === 'danger-red' ? '#EF5350' : '#FBBF24'\n\n // Triangle background\n ctx.fillStyle = fillColor\n ctx.beginPath()\n ctx.moveTo(x + half, y) // top-center\n ctx.lineTo(x + size, y + size) // bottom-right\n ctx.lineTo(x, y + size) // bottom-left\n ctx.closePath()\n ctx.fill()\n\n // Exclamation mark stem\n ctx.fillStyle = '#ffffff'\n const stemW = size * 0.12\n const stemX = x + half - stemW / 2\n ctx.fillRect(stemX, y + size * 0.35, stemW, size * 0.35)\n\n // Exclamation mark dot\n ctx.beginPath()\n ctx.arc(x + half, y + size * 0.82, stemW * 0.7, 0, Math.PI * 2)\n ctx.fill()\n }\n\n ctx.restore()\n },\n\n /**\n * Draws a pill-shaped badge with centered white text on a colored background.\n */\n badge(text: string, x: number, y: number, bgColor: string): void {\n ctx.save()\n\n // Measure text to size the pill\n ctx.font = ITEM_FONT\n const textMetrics = ctx.measureText(text)\n const textWidth = textMetrics.width\n const paddingH = 8\n const paddingV = 3\n const pillHeight = 12 + paddingV * 2\n const pillWidth = textWidth + paddingH * 2\n const radius = pillHeight / 2\n\n // Draw pill background\n ctx.fillStyle = bgColor\n ctx.beginPath()\n ctx.roundRect(x, y, pillWidth, pillHeight, radius)\n ctx.fill()\n\n // Draw centered white text\n ctx.fillStyle = '#ffffff'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(text, x + pillWidth / 2, y + pillHeight / 2)\n\n ctx.restore()\n },\n }\n}\n","import type {\n Item, Group, TimelineTheme, CanvasItemRenderer, CanvasGroupItemRenderer,\n Dependency, ItemBounds, ItemState,\n} from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { IntervalTree } from '../core/IntervalTree'\nimport type { LayoutEngine } from '../core/LayoutEngine'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport class ItemsLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n items: Item[],\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n itemRenderer: CanvasItemRenderer,\n groupRenderer: CanvasGroupItemRenderer | undefined,\n theme: TimelineTheme,\n selected: number[],\n hoveredItemId: number | undefined,\n dependencies?: Dependency[],\n ): void {\n // Query only visible time range + small padding (not the full 4x buffer)\n const padding = (view.visibleTimeEnd - view.visibleTimeStart) * 0.1\n const queryStart = view.visibleTimeStart - padding\n const queryEnd = view.visibleTimeEnd + padding\n const visibleItems = tree.query(queryStart, queryEnd)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const selectedSet = new Set(selected)\n const itemBoundsMap = new Map<number, ItemBounds>()\n\n // Vertical culling bounds\n const yMin = -view.lineHeight\n const yMax = view.canvasHeight + view.lineHeight\n\n for (const item of visibleItems) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n\n // Skip items that are entirely off-screen vertically\n const height = itemLayout.itemHeight\n if (y + height < yMin || y > yMax) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n const bounds: ItemBounds = { x, y, width, height }\n itemBoundsMap.set(item.id, bounds)\n\n const state: ItemState = {\n selected: selectedSet.has(item.id),\n hovered: hoveredItemId === item.id,\n dragging: false,\n filtered: item.filtered !== false,\n }\n\n ctx.save()\n const helpers = createDrawHelpers(ctx, bounds)\n const renderer = groupRenderer && (item.type === 'control_area_group' || item.type === 'construction_train')\n ? groupRenderer\n : itemRenderer\n renderer(ctx, item, bounds, state, helpers)\n ctx.restore()\n }\n\n if (dependencies && dependencies.length > 0) {\n // Build a full item map for dependency endpoint lookup (off-screen items too)\n const depItemIds = new Set<number>()\n for (const dep of dependencies) {\n if (!itemBoundsMap.has(dep.fromItemId)) depItemIds.add(dep.fromItemId)\n if (!itemBoundsMap.has(dep.toItemId)) depItemIds.add(dep.toItemId)\n }\n if (depItemIds.size > 0) {\n const itemMap = new Map<number, Item>()\n for (const item of items) {\n if (depItemIds.has(item.id)) itemMap.set(item.id, item)\n }\n for (const [id, item] of itemMap) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n const itemLayout = layout.getLayout(id)\n if (!itemLayout) continue\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n itemBoundsMap.set(id, { x, y, width, height: itemLayout.itemHeight })\n }\n }\n this.drawDependencies(ctx, dependencies, itemBoundsMap, hoveredItemId, theme)\n }\n }\n\n private drawDependencies(\n ctx: CanvasRenderingContext2D,\n dependencies: Dependency[],\n boundsMap: Map<number, ItemBounds>,\n hoveredItemId: number | undefined,\n theme: TimelineTheme,\n ): void {\n for (const dep of dependencies) {\n const fromBounds = boundsMap.get(dep.fromItemId)\n const toBounds = boundsMap.get(dep.toItemId)\n if (!fromBounds || !toBounds) continue\n\n const isHighlighted = hoveredItemId === dep.fromItemId || hoveredItemId === dep.toItemId\n\n ctx.strokeStyle = isHighlighted ? theme.primary : (dep.color ?? '#94A3B8')\n ctx.lineWidth = isHighlighted ? 2 : 1.5\n ctx.setLineDash([])\n\n const startX = fromBounds.x + fromBounds.width\n const startY = fromBounds.y + fromBounds.height / 2\n const endX = toBounds.x\n const endY = toBounds.y + toBounds.height / 2\n\n const dx = Math.abs(endX - startX)\n const cpOffset = Math.max(dx * 0.4, 30)\n\n ctx.beginPath()\n ctx.moveTo(startX, startY)\n ctx.bezierCurveTo(startX + cpOffset, startY, endX - cpOffset, endY, endX, endY)\n ctx.stroke()\n\n // Arrowhead\n const arrowSize = 6\n ctx.fillStyle = ctx.strokeStyle\n ctx.beginPath()\n ctx.moveTo(endX, endY)\n ctx.lineTo(endX - arrowSize, endY - arrowSize / 2)\n ctx.lineTo(endX - arrowSize, endY + arrowSize / 2)\n ctx.closePath()\n ctx.fill()\n }\n }\n}\n","import type { TimelineTheme, MarkerConfig, ItemBounds, Item, CanvasItemRenderer } from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { InteractionMode } from '../interaction/InteractionHandler'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport interface InteractionRenderState {\n item: Item\n mode: InteractionMode\n bounds: ItemBounds\n renderer: CanvasItemRenderer\n targetGroupY?: number\n groupChanged?: boolean\n}\n\nexport interface OverlayDrawOptions {\n cursorX: number | null\n snapX?: number | null\n markers?: MarkerConfig[]\n\n interaction?: InteractionRenderState | null\n}\n\nexport class OverlayLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n theme: TimelineTheme,\n options: OverlayDrawOptions,\n ): void {\n const { cursorX, snapX, markers, interaction } = options\n\n // Draw markers\n if (markers) {\n for (const marker of markers) {\n const x = view.timeToX(marker.date)\n\n ctx.fillStyle = marker.color\n ctx.fillRect(x - marker.width / 2, 0, marker.width, view.canvasHeight)\n\n if (marker.label) {\n ctx.save()\n ctx.font = '500 10px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n const textWidth = ctx.measureText(marker.label).width\n const padding = 8\n const maxBadgeWidth = 200\n const badgeWidth = Math.min(textWidth + padding * 2, maxBadgeWidth)\n const badgeHeight = 20\n const badgeX = x - badgeWidth / 2\n const badgeY = 4\n\n ctx.fillStyle = marker.color\n ctx.beginPath()\n ctx.roundRect(badgeX, badgeY, badgeWidth, badgeHeight, 3)\n ctx.fill()\n\n ctx.fillStyle = '#FFFFFF'\n ctx.textBaseline = 'middle'\n const maxTextWidth = maxBadgeWidth - padding * 2\n const displayText = textWidth > maxTextWidth\n ? marker.label.slice(0, Math.floor(marker.label.length * maxTextWidth / textWidth)) + '…'\n : marker.label\n ctx.fillText(displayText, badgeX + padding, badgeY + badgeHeight / 2)\n ctx.restore()\n }\n }\n }\n\n // Draw cursor line\n if (cursorX !== null && cursorX !== undefined) {\n ctx.strokeStyle = theme.marker.cursor\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(cursorX, 0)\n ctx.lineTo(cursorX, view.canvasHeight)\n ctx.stroke()\n }\n\n // Draw snap guide line\n if (snapX !== null && snapX !== undefined) {\n ctx.strokeStyle = theme.primary\n ctx.lineWidth = 1\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(snapX, 0)\n ctx.lineTo(snapX, view.canvasHeight)\n ctx.stroke()\n ctx.setLineDash([])\n }\n\n // Draw interaction ghost (move, resize-left, resize-right)\n if (interaction) {\n // Group highlight band when moving to a different group\n if (interaction.groupChanged && interaction.targetGroupY !== undefined) {\n ctx.fillStyle = 'rgba(59, 130, 246, 0.08)'\n ctx.fillRect(0, interaction.targetGroupY, view.canvasWidth, view.lineHeight)\n }\n\n ctx.save()\n ctx.globalAlpha = 0.5\n const helpers = createDrawHelpers(ctx, interaction.bounds)\n interaction.renderer(\n ctx, interaction.item, interaction.bounds,\n { selected: false, hovered: false, dragging: true, filtered: true },\n helpers,\n )\n ctx.restore()\n }\n }\n}\n","const MAX_DELTA = 120\n\n/**\n * Normalize wheel delta across browsers/platforms.\n * deltaMode 0 = pixels, 1 = lines (×15), 2 = pages (×800).\n * Clamp to ±120 to prevent erratic jumps.\n */\nfunction normalizeDelta(e: WheelEvent): number {\n let delta = e.deltaY || e.deltaX\n if (e.deltaMode === 1) delta *= 15\n else if (e.deltaMode === 2) delta *= 800\n return Math.max(-MAX_DELTA, Math.min(MAX_DELTA, delta))\n}\n\nexport class ZoomHandler {\n private onZoom: (newStart: number, newEnd: number) => void\n private visibleTimeStart: number\n private visibleTimeEnd: number\n private minZoom: number\n private maxZoom: number\n\n constructor(\n onZoom: (newStart: number, newEnd: number) => void,\n visibleTimeStart: number,\n visibleTimeEnd: number,\n minZoom: number,\n maxZoom: number,\n ) {\n this.onZoom = onZoom\n this.visibleTimeStart = visibleTimeStart\n this.visibleTimeEnd = visibleTimeEnd\n this.minZoom = minZoom\n this.maxZoom = maxZoom\n }\n\n updateBounds(start: number, end: number): void {\n this.visibleTimeStart = start\n this.visibleTimeEnd = end\n }\n\n handleWheelZoom(e: WheelEvent, cursorRatio: number): void {\n const delta = normalizeDelta(e)\n // Speed: ctrlKey (trackpad pinch) = 10, metaKey = 3, altKey = 1\n const speed = e.ctrlKey ? 10 : e.metaKey ? 3 : 1\n\n // Reciprocal formula for symmetric zoom-in / zoom-out\n const scale = delta > 0\n ? 1.0 + (speed * delta) / 500\n : 1.0 / (1.0 + (speed * -delta) / 500)\n\n const currentDuration = this.visibleTimeEnd - this.visibleTimeStart\n let newDuration = Math.round(currentDuration * scale)\n newDuration = Math.max(this.minZoom, Math.min(this.maxZoom, newDuration))\n\n const newStart = Math.round(this.visibleTimeStart + (currentDuration - newDuration) * cursorRatio)\n const newEnd = newStart + newDuration\n\n this.onZoom(newStart, newEnd)\n }\n}\n","import type { Item } from '../types'\n\nconst ACTIVATION_THRESHOLD = 4\n\nexport type InteractionMode = 'move' | 'resize-left' | 'resize-right'\n\nexport interface InteractionState {\n item: Item\n mode: InteractionMode\n startX: number\n startY: number\n currentX: number\n currentY: number\n deltaX: number\n originalGroup: string | number\n currentGroup: string | number\n}\n\nexport class InteractionHandler {\n private state: InteractionState | null = null\n private dragSnap: number\n private activated = false\n\n constructor(dragSnap: number) {\n this.dragSnap = dragSnap\n }\n\n startInteraction(item: Item, mode: InteractionMode, x: number, y: number): void {\n this.state = {\n item, mode, startX: x, startY: y, currentX: x, currentY: y,\n deltaX: 0, originalGroup: item.group, currentGroup: item.group,\n }\n this.activated = false\n }\n\n update(x: number, y: number): void {\n if (!this.state) return\n this.state.currentX = x\n this.state.currentY = y\n this.state.deltaX = x - this.state.startX\n if (!this.activated && Math.abs(this.state.deltaX) >= ACTIVATION_THRESHOLD) {\n this.activated = true\n }\n }\n\n setCurrentGroup(groupId: string | number): void {\n if (this.state) this.state.currentGroup = groupId\n }\n\n endMove(pixelsPerMs: number): { newStartTime: number; newGroupId: string | number } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const newStartTime = this.state.item.start_time + deltaMs\n const snapped = Math.round(newStartTime / this.dragSnap) * this.dragSnap\n const newGroupId = this.state.currentGroup\n this.state = null\n this.activated = false\n return { newStartTime: snapped, newGroupId }\n }\n\n endResize(pixelsPerMs: number): { newTime: number; edge: 'left' | 'right' } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const edge = this.state.mode === 'resize-left' ? 'left' as const : 'right' as const\n const baseTime = edge === 'left' ? this.state.item.start_time : this.state.item.end_time\n const newTime = baseTime + deltaMs\n const snapped = Math.round(newTime / this.dragSnap) * this.dragSnap\n this.state = null\n this.activated = false\n return { newTime: snapped, edge }\n }\n\n cancel(): void {\n this.state = null\n this.activated = false\n }\n\n getState(): InteractionState | null {\n return this.state\n }\n\n getMode(): InteractionMode | null {\n return this.state?.mode ?? null\n }\n\n isActive(): boolean {\n return this.state !== null && this.activated\n }\n\n isPending(): boolean {\n return this.state !== null\n }\n}\n","interface SnapItem {\n id: number\n start_time: number\n end_time: number\n}\n\n/**\n * Collect start and end X positions from all items except the dragged item.\n */\nexport function collectItemEdges(\n items: SnapItem[],\n excludeItemId: number,\n timeToX: (time: number) => number,\n): number[] {\n const edges: number[] = []\n for (const item of items) {\n if (item.id === excludeItemId) continue\n edges.push(timeToX(item.start_time))\n edges.push(timeToX(item.end_time))\n }\n return edges\n}\n\n/**\n * Find the best snap target from a list of edge X positions.\n * Returns the snapped X position if an edge is within threshold, or null to fall back to time-grid snap.\n */\nexport function findSnapTarget(\n currentX: number,\n edgeXPositions: number[],\n thresholdPx: number,\n _pixelsPerMs: number,\n _dragSnap: number,\n): number | null {\n if (edgeXPositions.length === 0) return null\n\n let closestX = edgeXPositions[0]\n let closestDist = Math.abs(currentX - closestX)\n\n for (let i = 1; i < edgeXPositions.length; i++) {\n const dist = Math.abs(currentX - edgeXPositions[i])\n if (dist < closestDist) {\n closestDist = dist\n closestX = edgeXPositions[i]\n }\n }\n\n if (closestDist <= thresholdPx) {\n return closestX\n }\n\n return null\n}\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_isoWeek=t()}(this,(function(){\"use strict\";var e=\"day\";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf(\"year\"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,\"week\")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return\"isoweek\"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf(\"day\"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf(\"day\"):n.bind(this)(e,t)}}}));","import React, { useRef, useCallback, useEffect } from 'react'\nimport type { Group, TimelineTheme } from '../types'\n\ninterface SidebarProps {\n groups: Group[]\n width: number\n lineHeight: number\n scrollTop: number\n canvasHeight: number\n theme: TimelineTheme\n groupRenderer: (group: Group) => React.ReactNode\n onScroll: (scrollTop: number) => void\n}\n\nconst OVERSCAN = 5\n\nexport function Sidebar({\n groups, width, lineHeight, scrollTop, canvasHeight, theme, groupRenderer, onScroll,\n}: SidebarProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false)\n const totalHeight = groups.length * lineHeight\n const displayHeight = canvasHeight\n\n const firstVisible = Math.max(0, Math.floor(scrollTop / lineHeight) - OVERSCAN)\n const lastVisible = Math.min(groups.length - 1, Math.ceil((scrollTop + canvasHeight) / lineHeight) + OVERSCAN)\n\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n if (isScrollingRef.current) return\n onScroll(e.currentTarget.scrollTop)\n }, [onScroll])\n\n useEffect(() => {\n if (containerRef.current) {\n isScrollingRef.current = true\n containerRef.current.scrollTop = scrollTop\n requestAnimationFrame(() => { isScrollingRef.current = false })\n }\n }, [scrollTop])\n\n const visibleGroups = []\n for (let i = firstVisible; i <= lastVisible; i++) {\n const group = groups[i]\n if (!group) continue\n visibleGroups.push(\n <div\n key={group.id}\n style={{\n position: 'absolute',\n top: i * lineHeight,\n height: lineHeight,\n width: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'stretch',\n borderBottom: `1px solid ${theme.grid?.line ?? '#E5E5E5'}`,\n boxSizing: 'border-box',\n }}\n >\n {groupRenderer(group)}\n </div>,\n )\n }\n\n return (\n <div\n ref={containerRef}\n onScroll={handleScroll}\n style={{\n width,\n height: displayHeight,\n overflowY: totalHeight > canvasHeight ? 'auto' : 'hidden',\n overflowX: 'hidden',\n position: 'relative',\n borderRight: `1px solid ${theme.sidebar.border}`,\n backgroundColor: theme.sidebar.bg,\n }}\n >\n <div style={{ height: totalHeight, position: 'relative' }}>{visibleGroups}</div>\n </div>\n )\n}\n","import type { MarkerConfig } from '../types'\n\ninterface TodayMarkerProps {\n color?: string\n width?: number\n label?: string\n /** Auto-update interval in ms. Default 10000 (10s). Set 0 to disable. */\n interval?: number\n}\n\nexport function TodayMarker(_props: TodayMarkerProps) { return null }\nTodayMarker.displayName = 'TodayMarker'\n\nexport function getTodayMarkerConfig(props: TodayMarkerProps): MarkerConfig {\n // Snap to current minute to avoid unnecessary redraws\n const now = Math.floor(Date.now() / 60000) * 60000\n return { date: now, color: props.color ?? '#FD7171', width: props.width ?? 6, label: props.label }\n}\n\nexport function getTodayMarkerInterval(props: TodayMarkerProps): number {\n return props.interval ?? 10000\n}\n","import type { MarkerConfig } from '../types'\n\ninterface CustomMarkerProps {\n date: number\n color?: string\n width?: number\n label?: string\n}\n\nexport function CustomMarker(_props: CustomMarkerProps) { return null }\nCustomMarker.displayName = 'CustomMarker'\n\nexport function getCustomMarkerConfig(props: CustomMarkerProps): MarkerConfig {\n return {\n date: props.date,\n color: props.color ?? '#3B82F6',\n width: props.width ?? 4,\n label: props.label,\n }\n}\n","import React, { useRef, useEffect, useState, useCallback, useMemo, useImperativeHandle, forwardRef } from 'react'\nimport { flushSync } from 'react-dom'\nimport type {\n CanvasTimelineProps,\n CanvasTimelineRef,\n MarkerConfig,\n TimelineTheme,\n} from './types'\nimport { DEFAULT_THEME } from './types'\nimport { ViewState } from './core/ViewState'\nimport { IntervalTree } from './core/IntervalTree'\nimport { LayoutEngine } from './core/LayoutEngine'\nimport { hitTest, hitTestGroup } from './core/HitTest'\nimport { setupCanvas, clearCanvas, RenderScheduler } from './canvas/CanvasManager'\nimport { GridLayer } from './canvas/GridLayer'\nimport { ItemsLayer } from './canvas/ItemsLayer'\nimport { OverlayLayer } from './canvas/OverlayLayer'\nimport { ZoomHandler } from './interaction/ZoomHandler'\nimport { InteractionHandler } from './interaction/InteractionHandler'\nimport type { InteractionMode } from './interaction/InteractionHandler'\nimport { findSnapTarget, collectItemEdges } from './interaction/snapUtils'\nimport { detectEdge } from './core/HitTest'\nimport dayjs from 'dayjs'\nimport isoWeek from 'dayjs/plugin/isoWeek'\nimport { Sidebar } from './dom/Sidebar'\nimport { getTodayMarkerConfig, getTodayMarkerInterval } from './dom/TodayMarker'\nimport { getCustomMarkerConfig } from './dom/CustomMarker'\n\ndayjs.extend(isoWeek)\n\nfunction mergeTheme(partial?: Partial<TimelineTheme>): TimelineTheme {\n if (!partial) return DEFAULT_THEME\n return {\n ...DEFAULT_THEME,\n ...partial,\n status: { ...DEFAULT_THEME.status, ...partial.status },\n grid: { ...DEFAULT_THEME.grid, ...partial.grid },\n item: { ...DEFAULT_THEME.item, ...partial.item },\n marker: { ...DEFAULT_THEME.marker, ...partial.marker },\n sidebar: { ...DEFAULT_THEME.sidebar, ...partial.sidebar },\n header: { ...DEFAULT_THEME.header, ...partial.header },\n }\n}\n\nconst HEADER_THROTTLE_MS = 32\n\nexport const CanvasTimeline = React.memo(forwardRef<CanvasTimelineRef, CanvasTimelineProps>(function CanvasTimeline(props, ref) {\n const {\n groups,\n items,\n defaultTimeStart,\n defaultTimeEnd,\n sidebarWidth,\n lineHeight,\n itemHeightRatio,\n stackItems,\n canMove,\n canChangeGroup,\n canResize,\n dragSnap,\n minZoom,\n maxZoom,\n theme: themePartial,\n dayStyle,\n rowStyle,\n showCursorLine,\n itemRenderer,\n groupRenderer,\n sidebarGroupRenderer,\n dependencies,\n highlights,\n onItemClick,\n onItemDoubleClick,\n onItemContextMenu,\n onItemMove,\n onItemResize,\n moveResizeValidator,\n onItemHover,\n onCanvasDoubleClick,\n onCanvasContextMenu,\n onTimeChange,\n onZoom,\n selected: selectedProp = [],\n rightSidebarWidth,\n rightSidebarGroupRenderer,\n onReady,\n children,\n } = props\n\n const theme = useMemo(() => mergeTheme(themePartial), [themePartial])\n\n const getGroupIndex = useCallback((groupId: string | number, grps: typeof groups) => {\n for (let i = 0; i < grps.length; i++) {\n if (grps[i].id === groupId) return i\n }\n return 0\n }, [])\n\n const selectedKey = selectedProp.join(',')\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const selected = useMemo(() => selectedProp, [selectedKey])\n\n const gridCanvasRef = useRef<HTMLCanvasElement>(null)\n const itemsCanvasRef = useRef<HTMLCanvasElement>(null)\n const overlayCanvasRef = useRef<HTMLCanvasElement>(null)\n const interactionRef = useRef<HTMLDivElement>(null)\n const outerRef = useRef<HTMLDivElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const [containerWidth, setContainerWidth] = useState(800)\n\n useEffect(() => {\n const container = outerRef.current\n if (!container) return\n const obs = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) {\n setContainerWidth(entry.contentRect.width)\n }\n })\n obs.observe(container)\n return () => obs.disconnect()\n }, [])\n\n const canvasWidth = Math.max(0, containerWidth - sidebarWidth - (rightSidebarWidth ?? 0))\n const canvasHeight = groups.length * lineHeight\n\n // --- MUTABLE VIEW STATE (hot path) ---\n const viewStateRef = useRef<ViewState>(\n new ViewState({\n visibleTimeStart: props.visibleTimeStart ?? defaultTimeStart,\n visibleTimeEnd: props.visibleTimeEnd ?? defaultTimeEnd,\n canvasWidth,\n canvasHeight,\n sidebarWidth,\n lineHeight,\n groupCount: groups.length,\n buffer: props.buffer ?? 3,\n scrollTop: 0,\n }),\n )\n\n const cursorXRef = useRef<number | null>(null)\n const hoveredItemIdRef = useRef<number | undefined>(undefined)\n\n // --- THROTTLED HEADER STATE ---\n const [headerTimeStart, setHeaderTimeStart] = useState(props.visibleTimeStart ?? defaultTimeStart)\n const [headerTimeEnd, setHeaderTimeEnd] = useState(props.visibleTimeEnd ?? defaultTimeEnd)\n const [sidebarScrollTop, setSidebarScrollTop] = useState(0)\n const headerTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const syncHeaderState = useCallback(() => {\n const vs = viewStateRef.current\n setHeaderTimeStart(vs.visibleTimeStart)\n setHeaderTimeEnd(vs.visibleTimeEnd)\n setSidebarScrollTop(vs.scrollTop)\n headerTimerRef.current = null\n }, [])\n\n const scheduleHeaderSync = useCallback(() => {\n if (headerTimerRef.current !== null) return\n headerTimerRef.current = setTimeout(syncHeaderState, HEADER_THROTTLE_MS)\n }, [syncHeaderState])\n\n useEffect(() => {\n return () => { if (headerTimerRef.current !== null) clearTimeout(headerTimerRef.current) }\n }, [])\n\n // --- CORE DATA STRUCTURES ---\n const intervalTree = useMemo(() => {\n const tree = new IntervalTree<(typeof items)[0]>()\n tree.buildFromItems(items, (i) => i.start_time, (i) => i.end_time)\n return tree\n }, [items])\n\n const layoutEngine = useMemo(() => {\n const engine = new LayoutEngine(lineHeight, itemHeightRatio)\n engine.computeLayout(items, stackItems)\n return engine\n }, [items, lineHeight, itemHeightRatio, stackItems])\n\n const gridLayer = useMemo(() => new GridLayer(), [])\n const itemsLayer = useMemo(() => new ItemsLayer(), [])\n const overlayLayer = useMemo(() => new OverlayLayer(), [])\n const interactionHandler = useMemo(() => new InteractionHandler(dragSnap), [dragSnap])\n\n // --- MARKERS ---\n const markerConfigs = useMemo(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n return configs\n }, [children])\n const markersKey = useMemo(() => markerConfigs.map(m => `${m.date}|${m.color}|${m.width}|${m.label ?? ''}`).join(';'), [markerConfigs])\n const markersRef = useRef(markerConfigs)\n markersRef.current = markerConfigs\n\n // TodayMarker auto-update: refresh overlay on interval\n const todayMarkerInterval = useMemo(() => {\n let interval = 0\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n interval = getTodayMarkerInterval(child.props as { interval?: number })\n }\n })\n return interval\n }, [children])\n\n // --- PROPS REF ---\n const propsRef = useRef({\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, highlights, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n })\n propsRef.current = {\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, highlights, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n }\n\n // --- DRAW FUNCTIONS ---\n const drawGrid = useCallback(() => {\n const canvas = gridCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n gridLayer.draw(ctx, viewStateRef.current, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights)\n }, [gridLayer])\n\n const drawItems = useCallback(() => {\n const canvas = itemsCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n itemsLayer.draw(\n ctx, viewStateRef.current, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, hoveredItemIdRef.current, p.dependencies,\n )\n }, [itemsLayer])\n\n const calculateSnapX = useCallback((item: (typeof items)[0], deltaX: number, mode: InteractionMode) => {\n const vs = viewStateRef.current\n const p = propsRef.current\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n\n // Determine which edges of the dragged item to check\n const draggedEdgeXs: number[] = []\n if (mode === 'move') {\n draggedEdgeXs.push(vs.timeToX(item.start_time + deltaMs))\n draggedEdgeXs.push(vs.timeToX(item.end_time + deltaMs))\n } else if (mode === 'resize-left') {\n draggedEdgeXs.push(vs.timeToX(item.start_time + deltaMs))\n } else {\n draggedEdgeXs.push(vs.timeToX(item.end_time + deltaMs))\n }\n\n // Collect other items' edges\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, item.id, (t) => vs.timeToX(t))\n\n // Check each dragged edge against other items' edges\n for (const edgeX of draggedEdgeXs) {\n const snapX = findSnapTarget(edgeX, otherEdges, 8, pixelsPerMs, p.dragSnap)\n if (snapX !== null) return snapX\n }\n\n // Fall back to time grid snap\n const newStart = item.start_time + deltaMs\n const snapped = Math.round(newStart / p.dragSnap) * p.dragSnap\n return vs.timeToX(snapped)\n }, [])\n\n const drawOverlay = useCallback(() => {\n const canvas = overlayCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n\n const vs = viewStateRef.current\n const state = interactionHandler.getState()\n let interactionRender = null\n if (state) {\n const origX = vs.timeToX(state.item.start_time)\n const origWidth = vs.timeToX(state.item.end_time) - origX\n let x: number, width: number\n if (state.mode === 'resize-left') {\n x = origX + state.deltaX\n width = origWidth - state.deltaX\n } else if (state.mode === 'resize-right') {\n x = origX\n width = origWidth + state.deltaX\n } else {\n // move\n x = origX + state.deltaX\n width = origWidth\n }\n const groupIndex = getGroupIndex(state.currentGroup, p.groups)\n const targetGroupY = vs.groupIndexToY(groupIndex)\n const groupChanged = state.currentGroup !== state.originalGroup\n interactionRender = {\n item: state.item,\n mode: state.mode,\n bounds: { x, y: targetGroupY + (p.lineHeight - p.lineHeight * p.itemHeightRatio) / 2, width, height: p.lineHeight * p.itemHeightRatio },\n renderer: p.itemRenderer,\n targetGroupY,\n groupChanged,\n }\n }\n\n overlayLayer.draw(ctx, vs, p.theme, {\n cursorX: p.showCursorLine ? cursorXRef.current : null,\n snapX: state ? calculateSnapX(state.item, state.deltaX, state.mode) : null,\n markers: markersRef.current,\n interaction: interactionRender,\n })\n }, [overlayLayer, interactionHandler, calculateSnapX, getGroupIndex])\n\n // --- RENDER SCHEDULER ---\n const schedulerRef = useRef<RenderScheduler | null>(null)\n if (!schedulerRef.current) {\n schedulerRef.current = new RenderScheduler((flags) => {\n if (flags.grid) drawGrid()\n if (flags.items) drawItems()\n if (flags.overlay) drawOverlay()\n })\n }\n const scheduler = schedulerRef.current\n\n useEffect(() => {\n return () => scheduler.dispose()\n }, [scheduler])\n\n // --- TODAY MARKER AUTO-UPDATE ---\n useEffect(() => {\n if (!todayMarkerInterval) return\n const timer = setInterval(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n markersRef.current = configs\n scheduler.markDirty('overlay')\n }, todayMarkerInterval)\n return () => clearInterval(timer)\n }, [todayMarkerInterval, children, scheduler])\n\n // --- SYNC ON DIMENSION/DATA CHANGES ---\n useEffect(() => {\n viewStateRef.current.update({ canvasWidth, canvasHeight, sidebarWidth, lineHeight, groupCount: groups.length })\n scheduler.markAllDirty()\n }, [canvasWidth, canvasHeight, sidebarWidth, lineHeight, groups.length, scheduler])\n\n useEffect(() => {\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n }, [items, groups, selected, theme, dayStyle, rowStyle, intervalTree, layoutEngine, scheduler])\n\n const highlightsKey = useMemo(\n () => props.highlights?.map(h => `${h.start}|${h.end}|${h.color}|${h.label ?? ''}|${h.opacity ?? ''}`).join(';') ?? '',\n [props.highlights],\n )\n\n const prevHighlightsKey = useRef(highlightsKey)\n useEffect(() => {\n if (highlightsKey !== prevHighlightsKey.current) {\n prevHighlightsKey.current = highlightsKey\n scheduler.markDirty('grid')\n }\n }, [highlightsKey, scheduler])\n\n const prevMarkersKey = useRef(markersKey)\n useEffect(() => {\n if (markersKey !== prevMarkersKey.current) {\n prevMarkersKey.current = markersKey\n scheduler.markDirty('overlay')\n }\n }, [markersKey, scheduler])\n\n // --- CONTROLLED MODE ---\n const prevControlledStart = useRef(props.visibleTimeStart)\n const prevControlledEnd = useRef(props.visibleTimeEnd)\n if (props.visibleTimeStart !== undefined && props.visibleTimeStart !== prevControlledStart.current) {\n prevControlledStart.current = props.visibleTimeStart\n viewStateRef.current.update({ visibleTimeStart: props.visibleTimeStart })\n scheduler.markAllDirty()\n }\n if (props.visibleTimeEnd !== undefined && props.visibleTimeEnd !== prevControlledEnd.current) {\n prevControlledEnd.current = props.visibleTimeEnd\n viewStateRef.current.update({ visibleTimeEnd: props.visibleTimeEnd })\n scheduler.markAllDirty()\n }\n\n // --- THROTTLED PARENT CALLBACKS ---\n const callbackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const scheduleCallbacks = useCallback((type: 'zoom' | 'scroll') => {\n if (callbackTimerRef.current !== null) return\n callbackTimerRef.current = setTimeout(() => {\n callbackTimerRef.current = null\n const vs = viewStateRef.current\n const p = propsRef.current\n if (type === 'zoom') {\n p.onZoom?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n } else {\n p.onTimeChange?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n }\n }, HEADER_THROTTLE_MS)\n }, [])\n\n useEffect(() => {\n return () => { if (callbackTimerRef.current !== null) clearTimeout(callbackTimerRef.current) }\n }, [])\n\n // --- ZOOM HANDLER ---\n const zoomHandlerRef = useRef<ZoomHandler | null>(null)\n const zoomHandler = useMemo(() => {\n return new ZoomHandler(\n (newStart, newEnd) => {\n viewStateRef.current.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n },\n defaultTimeStart,\n defaultTimeEnd,\n minZoom,\n maxZoom,\n )\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n zoomHandlerRef.current = zoomHandler\n\n // --- WHEEL HANDLER ---\n const handleVerticalScroll = useCallback((deltaY: number) => {\n const vs = viewStateRef.current\n const totalHeight = vs.groupCount * vs.lineHeight\n const maxScroll = Math.max(0, totalHeight - vs.canvasHeight)\n const newScrollTop = Math.max(0, Math.min(maxScroll, vs.scrollTop + deltaY))\n if (newScrollTop === vs.scrollTop) return\n vs.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }, [scheduler])\n\n const handleHorizontalScroll = useCallback((deltaX: number) => {\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n const newStart = vs.visibleTimeStart + deltaMs\n const newEnd = vs.visibleTimeEnd + deltaMs\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n flushSync(() => syncHeaderState())\n propsRef.current.onTimeChange?.(newStart, newEnd)\n }, [scheduler, syncHeaderState])\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n const handleWheel = (e: WheelEvent) => {\n if (e.ctrlKey || e.metaKey || e.altKey) {\n e.preventDefault()\n const rect = el.getBoundingClientRect()\n const cursorRatio = (e.clientX - rect.left) / rect.width\n zoomHandler.handleWheelZoom(e, cursorRatio)\n } else if (e.shiftKey) {\n e.preventDefault()\n handleHorizontalScroll(e.deltaY)\n } else {\n const deltaX = e.deltaX\n if (deltaX !== 0 && Math.abs(deltaX) > Math.abs(e.deltaY)) {\n e.preventDefault()\n handleHorizontalScroll(deltaX)\n } else if (e.deltaY !== 0) {\n handleVerticalScroll(e.deltaY)\n }\n }\n }\n el.addEventListener('wheel', handleWheel, { passive: false })\n return () => el.removeEventListener('wheel', handleWheel)\n }, [zoomHandler, handleVerticalScroll, handleHorizontalScroll])\n\n // --- TOUCH PINCH-TO-ZOOM ---\n const touchRef = useRef<{ lastDistance: number | null; lastCenter: number | null }>({ lastDistance: null, lastCenter: null })\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n\n const getDistance = (t1: Touch, t2: Touch) => Math.abs(t1.clientX - t2.clientX)\n const getCenter = (t1: Touch, t2: Touch, rect: DOMRect) => ((t1.clientX + t2.clientX) / 2) - rect.left\n\n const handleTouchStart = (e: TouchEvent) => {\n if (e.touches.length === 2) {\n e.preventDefault()\n touchRef.current.lastDistance = getDistance(e.touches[0], e.touches[1])\n touchRef.current.lastCenter = null\n }\n }\n\n const handleTouchMove = (e: TouchEvent) => {\n if (e.touches.length === 2 && touchRef.current.lastDistance !== null) {\n e.preventDefault()\n const newDistance = getDistance(e.touches[0], e.touches[1])\n const rect = el.getBoundingClientRect()\n const center = getCenter(e.touches[0], e.touches[1], rect)\n const cursorRatio = center / rect.width\n\n if (newDistance !== 0 && touchRef.current.lastDistance !== 0) {\n const scale = touchRef.current.lastDistance / newDistance\n const vs = viewStateRef.current\n const currentDuration = vs.visibleTimeEnd - vs.visibleTimeStart\n let newDuration = currentDuration * scale\n newDuration = Math.max(minZoom, Math.min(maxZoom, newDuration))\n\n const cursorTime = vs.visibleTimeStart + currentDuration * cursorRatio\n const newStart = cursorTime - newDuration * cursorRatio\n const newEnd = cursorTime + newDuration * (1 - cursorRatio)\n\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n }\n touchRef.current.lastDistance = newDistance\n }\n }\n\n const handleTouchEnd = () => {\n touchRef.current.lastDistance = null\n touchRef.current.lastCenter = null\n }\n\n el.addEventListener('touchstart', handleTouchStart, { passive: false })\n el.addEventListener('touchmove', handleTouchMove, { passive: false })\n el.addEventListener('touchend', handleTouchEnd)\n return () => {\n el.removeEventListener('touchstart', handleTouchStart)\n el.removeEventListener('touchmove', handleTouchMove)\n el.removeEventListener('touchend', handleTouchEnd)\n }\n }, [scheduler, scheduleHeaderSync, scheduleCallbacks])\n\n // --- POINTER HANDLERS ---\n const handlePointerMove = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n cursorXRef.current = x\n\n if (interactionHandler.isPending()) {\n interactionHandler.update(x, y)\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n if (state && state.mode === 'move' && propsRef.current.canChangeGroup) {\n const group = hitTestGroup(y, viewStateRef.current, propsRef.current.groups)\n if (group) interactionHandler.setCurrentGroup(group.id)\n }\n scheduler.markDirty('overlay')\n }\n return\n }\n\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n const newHoveredId = item?.id\n if (newHoveredId !== hoveredItemIdRef.current) {\n hoveredItemIdRef.current = newHoveredId\n scheduler.markDirty('items')\n p.onItemHover?.(newHoveredId ?? null, e.nativeEvent as unknown as PointerEvent)\n }\n\n // Cursor management\n if (item) {\n const edge = detectEdge(x, item, viewStateRef.current)\n const cr = p.canResize\n if (edge === 'left' && (cr === 'left' || cr === 'both')) {\n el.style.cursor = 'col-resize'\n } else if (edge === 'right' && (cr === 'right' || cr === 'both')) {\n el.style.cursor = 'col-resize'\n } else if (p.canMove) {\n el.style.cursor = 'grab'\n } else {\n el.style.cursor = 'default'\n }\n } else {\n el.style.cursor = 'default'\n }\n }, [interactionHandler, scheduler])\n\n const handlePointerDown = useCallback((e: React.PointerEvent) => {\n const p = propsRef.current\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (!item) return\n\n const edge = detectEdge(x, item, viewStateRef.current)\n const cr = p.canResize\n\n if (edge === 'left' && (cr === 'left' || cr === 'both')) {\n interactionHandler.startInteraction(item, 'resize-left', x, y)\n } else if (edge === 'right' && (cr === 'right' || cr === 'both')) {\n interactionHandler.startInteraction(item, 'resize-right', x, y)\n } else if (p.canMove) {\n interactionHandler.startInteraction(item, 'move', x, y)\n }\n }, [interactionHandler])\n\n const handlePointerUp = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n if (state) {\n const validator = propsRef.current.moveResizeValidator\n if (state.mode === 'move') {\n const result = interactionHandler.endMove(pixelsPerMs)\n if (result) {\n // Check for item-to-item snap\n const vs = viewStateRef.current\n const p = propsRef.current\n const deltaMs = state.deltaX / pixelsPerMs\n const draggedStartX = vs.timeToX(state.item.start_time + deltaMs)\n const draggedEndX = vs.timeToX(state.item.end_time + deltaMs)\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, state.item.id, (t: number) => vs.timeToX(t))\n\n let snappedStartTime = result.newStartTime\n // Check start edge\n const startSnap = findSnapTarget(draggedStartX, otherEdges, 8, pixelsPerMs, p.dragSnap)\n if (startSnap !== null) {\n snappedStartTime = vs.xToTime(startSnap)\n } else {\n // Check end edge\n const endSnap = findSnapTarget(draggedEndX, otherEdges, 8, pixelsPerMs, p.dragSnap)\n if (endSnap !== null) {\n const duration = state.item.end_time - state.item.start_time\n snappedStartTime = vs.xToTime(endSnap) - duration\n }\n }\n\n const validatedTime = validator ? validator('move', state.item.id, snappedStartTime) : snappedStartTime\n propsRef.current.onItemMove?.(state.item.id, validatedTime, result.newGroupId)\n }\n } else {\n const result = interactionHandler.endResize(pixelsPerMs)\n if (result) {\n const vs = viewStateRef.current\n const p = propsRef.current\n const deltaMs = state.deltaX / pixelsPerMs\n const edgeTime = result.edge === 'left' ? state.item.start_time + deltaMs : state.item.end_time + deltaMs\n const edgeX = vs.timeToX(edgeTime)\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, state.item.id, (t: number) => vs.timeToX(t))\n\n const snap = findSnapTarget(edgeX, otherEdges, 8, pixelsPerMs, p.dragSnap)\n const snappedTime = snap !== null ? vs.xToTime(snap) : result.newTime\n\n const validatedTime = validator ? validator('resize', state.item.id, snappedTime, result.edge) : snappedTime\n propsRef.current.onItemResize?.(state.item.id, validatedTime, result.edge)\n }\n }\n }\n el.style.cursor = 'default'\n scheduler.markDirty('overlay')\n return\n }\n if (interactionHandler.isPending()) interactionHandler.cancel()\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, propsRef.current.intervalTree, propsRef.current.layoutEngine, propsRef.current.groups)\n if (item) propsRef.current.onItemClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n }, [interactionHandler, scheduler])\n\n const handleDoubleClick = useCallback((e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemDoubleClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasDoubleClick?.(group.id as number, time)\n }\n }, [])\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemContextMenu?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasContextMenu?.(group.id as number, time, e.nativeEvent as unknown as PointerEvent)\n }\n }, [])\n\n const handlePointerLeave = useCallback(() => {\n cursorXRef.current = null\n if (interactionRef.current) interactionRef.current.style.cursor = 'default'\n if (hoveredItemIdRef.current !== undefined) {\n hoveredItemIdRef.current = undefined\n scheduler.markDirty('items')\n propsRef.current.onItemHover?.(null, new PointerEvent('pointerleave'))\n }\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n }, [scheduler])\n\n // --- HEADER CHILDREN ---\n const headerChildren = useMemo(() => {\n const headers: React.ReactNode[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TimelineHeaders') {\n const childProps = child.props as Record<string, unknown>\n headers.push(\n React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? headerTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? headerTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n sidebarWidth: childProps.sidebarWidth ?? sidebarWidth,\n theme: childProps.theme ?? theme,\n onZoomToInterval: childProps.onZoomToInterval ?? ((start: number, end: number) => {\n viewStateRef.current.update({ visibleTimeStart: start, visibleTimeEnd: end })\n scheduler.markAllDirty()\n syncHeaderState()\n propsRef.current.onTimeChange?.(start, end)\n propsRef.current.onZoom?.(start, end)\n }),\n }),\n )\n }\n })\n return headers\n }, [children, headerTimeStart, headerTimeEnd, canvasWidth, sidebarWidth, theme, scheduler, syncHeaderState])\n\n // --- INITIAL DRAW ---\n const initialDrawDone = useRef(false)\n useEffect(() => {\n if (!initialDrawDone.current) {\n initialDrawDone.current = true\n scheduler.markAllDirty()\n }\n }, [scheduler])\n\n // --- IMPERATIVE HANDLE (print capture) ---\n useImperativeHandle(ref, () => ({\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const totalHeight = p.groups.length * p.lineHeight\n\n // Preserve the current zoom level (pixels per ms) from the on-screen view\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n\n const compositeWidth = (printSidebarWidth + timelineWidth) * scale\n const compositeHeight = (headerHeight + totalHeight) * scale\n\n const canvas = document.createElement('canvas')\n canvas.width = compositeWidth\n canvas.height = compositeHeight\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n\n // --- Draw sidebar ---\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const y = headerHeight + i * p.lineHeight\n\n // Row background from rowStyle\n if (p.rowStyle) {\n const style = p.rowStyle(group)\n if (style?.backgroundColor) {\n ctx.fillStyle = style.backgroundColor\n ctx.fillRect(0, y, printSidebarWidth, p.lineHeight)\n }\n }\n\n // Group title\n const groupType = group.type as string | undefined\n let fontWeight = '400'\n let indent = 8\n if (groupType === 'project') {\n fontWeight = '700'\n } else if (groupType === 'CAG') {\n fontWeight = '600'\n } else if (groupType === 'CA') {\n fontWeight = '400'\n indent = 24\n }\n\n ctx.fillStyle = '#111'\n ctx.font = `${fontWeight} 12px sans-serif`\n ctx.textBaseline = 'middle'\n ctx.fillText(group.title, indent, y + p.lineHeight / 2, printSidebarWidth - indent - 4)\n }\n\n // --- Draw headers ---\n const drawHeaderRow = (rowY: number, getLabel: (time: dayjs.Dayjs) => string, unit: dayjs.ManipulateType) => {\n ctx.fillStyle = p.theme.header?.bg ?? '#f5f5f5'\n ctx.fillRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n ctx.strokeStyle = p.theme.grid?.line ?? '#e0e0e0'\n ctx.lineWidth = 1\n ctx.strokeRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n\n let cursor = dayjs(timeStart).startOf(unit)\n if (cursor.valueOf() < timeStart) cursor = cursor.add(1, unit)\n\n const pxPerMs = timelineWidth / (timeEnd - timeStart)\n\n while (cursor.valueOf() < timeEnd) {\n const nextCursor = cursor.add(1, unit)\n const x = printSidebarWidth + (cursor.valueOf() - timeStart) * pxPerMs\n const endX = printSidebarWidth + (Math.min(nextCursor.valueOf(), timeEnd) - timeStart) * pxPerMs\n const width = endX - x\n\n // Vertical divider\n ctx.beginPath()\n ctx.moveTo(x, rowY)\n ctx.lineTo(x, rowY + headerRowHeight)\n ctx.stroke()\n\n // Label\n ctx.fillStyle = '#333'\n ctx.font = '600 11px sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n ctx.fillText(getLabel(cursor), x + width / 2, rowY + headerRowHeight / 2, width - 4)\n\n cursor = nextCursor\n }\n ctx.textAlign = 'start' // reset\n }\n\n drawHeaderRow(0, (d) => d.format('YYYY'), 'year')\n drawHeaderRow(headerRowHeight, (d) => d.format('MM'), 'month')\n drawHeaderRow(headerRowHeight * 2, (d) => String(d.isoWeek()), 'week')\n\n // --- Draw timeline layers ---\n const printViewState = new ViewState({\n visibleTimeStart: timeStart,\n visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth,\n canvasHeight: totalHeight,\n sidebarWidth: 0,\n lineHeight: p.lineHeight,\n groupCount: p.groups.length,\n buffer: 1,\n scrollTop: 0,\n })\n\n // Offset context for timeline area\n ctx.save()\n ctx.translate(printSidebarWidth, headerHeight)\n\n // Clip to timeline area\n ctx.beginPath()\n ctx.rect(0, 0, timelineWidth, totalHeight)\n ctx.clip()\n\n gridLayer.draw(ctx, printViewState, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights)\n itemsLayer.draw(\n ctx, printViewState, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies,\n )\n overlayLayer.draw(ctx, printViewState, p.theme, {\n cursorX: null,\n snapX: null,\n markers: markersRef.current,\n interaction: null,\n })\n\n ctx.restore()\n\n return canvas\n },\n }), [gridLayer, itemsLayer, overlayLayer])\n\n // --- ON READY CALLBACK ---\n useEffect(() => {\n const api: CanvasTimelineRef = {\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const totalHeight = p.groups.length * p.lineHeight\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n const fullWidth = printSidebarWidth + timelineWidth\n const fullHeight = headerHeight + totalHeight\n\n const canvas = document.createElement('canvas')\n canvas.width = fullWidth * scale\n canvas.height = fullHeight * scale\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n ctx.fillStyle = '#FFFFFF'\n ctx.fillRect(0, 0, fullWidth, fullHeight)\n\n // Sidebar\n ctx.save()\n ctx.beginPath()\n ctx.rect(0, 0, printSidebarWidth, fullHeight)\n ctx.clip()\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(0, 0, printSidebarWidth, headerHeight)\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.strokeRect(0, 0, printSidebarWidth, headerHeight)\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const y = headerHeight + i * p.lineHeight\n const rs = p.rowStyle?.(group)\n ctx.fillStyle = rs?.backgroundColor ?? (i % 2 === 0 ? '#FFFFFF' : '#F7F7F7')\n ctx.fillRect(0, y, printSidebarWidth, p.lineHeight)\n ctx.strokeStyle = '#E5E5E5'\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + p.lineHeight)\n ctx.lineTo(printSidebarWidth, y + p.lineHeight)\n ctx.stroke()\n const gt = (group.type as string) ?? ''\n let indent = 8, fw = '400', fs = 11\n if (gt === 'project') { fw = '700'; fs = 12 }\n else if (gt === 'control_area_group') { fw = '600' }\n else if (gt === 'control_area') { indent = 24 }\n ctx.fillStyle = '#374151'\n ctx.font = `${fw} ${fs}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif`\n ctx.textBaseline = 'middle'\n const title = typeof group.title === 'string' ? group.title : String(group.title)\n ctx.fillText(title, indent, y + p.lineHeight / 2, printSidebarWidth - indent - 8)\n }\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(printSidebarWidth, 0)\n ctx.lineTo(printSidebarWidth, fullHeight)\n ctx.stroke()\n ctx.restore()\n\n // Headers\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, 0, timelineWidth, headerHeight)\n ctx.clip()\n const duration = timeEnd - timeStart\n const units: Array<{ unit: 'year' | 'month' | 'week'; row: number }> = [\n { unit: 'year', row: 0 }, { unit: 'month', row: 1 }, { unit: 'week', row: 2 },\n ]\n for (const { unit, row } of units) {\n const hy = row * headerRowHeight\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(printSidebarWidth, hy, timelineWidth, headerRowHeight)\n let cur = dayjs(timeStart).startOf(unit)\n const endBound = dayjs(timeEnd).add(1, unit)\n while (cur.isBefore(endBound)) {\n const next = cur.add(1, unit)\n const sx = printSidebarWidth + ((cur.valueOf() - timeStart) / duration) * timelineWidth\n const w = ((next.valueOf() - cur.valueOf()) / duration) * timelineWidth\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 0.5\n ctx.strokeRect(sx, hy, w, headerRowHeight)\n let label: string\n if (unit === 'year') label = cur.format('YYYY')\n else if (unit === 'month') label = cur.format('MM')\n else label = `${cur.week()}`\n ctx.fillStyle = '#6c737f'\n ctx.font = unit === 'year'\n ? '600 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n : '400 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n if (w > 20) ctx.fillText(label, sx + w / 2, hy + headerRowHeight / 2)\n cur = next\n }\n }\n ctx.textAlign = 'start'\n ctx.restore()\n\n // Timeline\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, headerHeight, timelineWidth, totalHeight)\n ctx.clip()\n ctx.translate(printSidebarWidth, headerHeight)\n const pv = new ViewState({\n visibleTimeStart: timeStart, visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth, canvasHeight: totalHeight,\n sidebarWidth: 0, lineHeight: p.lineHeight,\n groupCount: p.groups.length, buffer: 1, scrollTop: 0,\n })\n gridLayer.draw(ctx, pv, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights)\n itemsLayer.draw(ctx, pv, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies)\n overlayLayer.draw(ctx, pv, p.theme, { cursorX: null, markers: markersRef.current })\n ctx.restore()\n\n return canvas\n },\n }\n onReady?.(api)\n }, [onReady, gridLayer, itemsLayer, overlayLayer])\n\n // --- RENDER ---\n const canvasContainerStyle: React.CSSProperties = {\n position: 'relative',\n width: canvasWidth,\n height: canvasHeight,\n overflow: 'hidden',\n cursor: 'default',\n }\n\n const canvasStyle: React.CSSProperties = { position: 'absolute', top: 0, left: 0 }\n\n return (\n <div ref={outerRef} style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>\n {headerChildren}\n <div ref={containerRef} style={{ display: 'flex', overflow: 'hidden' }}>\n <Sidebar\n groups={groups}\n width={sidebarWidth}\n lineHeight={lineHeight}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={sidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n <div\n ref={interactionRef}\n style={canvasContainerStyle}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onPointerLeave={handlePointerLeave}\n >\n <canvas ref={gridCanvasRef} style={{ ...canvasStyle, zIndex: 0 }} />\n <canvas ref={itemsCanvasRef} style={{ ...canvasStyle, zIndex: 1 }} />\n <canvas ref={overlayCanvasRef} style={{ ...canvasStyle, zIndex: 2 }} />\n </div>\n {rightSidebarWidth && rightSidebarGroupRenderer ? (\n <Sidebar\n groups={groups}\n width={rightSidebarWidth}\n lineHeight={lineHeight}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={rightSidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n ) : null}\n </div>\n </div>\n )\n}))\n","import React from 'react'\nimport type { TimelineTheme } from '../types'\n\nexport interface TimelineHeadersProps {\n children: React.ReactNode\n theme?: TimelineTheme\n className?: string\n classNames?: string\n style?: React.CSSProperties\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n sidebarWidth?: number\n onZoomToInterval?: (start: number, end: number) => void\n}\n\nexport function TimelineHeaders({ children, theme, className, classNames: _classNames, style, visibleTimeStart, visibleTimeEnd, canvasWidth, sidebarWidth = 0, onZoomToInterval }: TimelineHeadersProps) {\n const enhancedChildren = React.Children.map(children, (child) => {\n if (!React.isValidElement(child)) return child\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'DateHeader') {\n const childProps = child.props as Record<string, unknown>\n const enhanced = React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? visibleTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? visibleTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n theme: childProps.theme ?? theme,\n onZoomToInterval: childProps.onIntervalClick ?? childProps.onZoomToInterval ?? onZoomToInterval,\n })\n return (\n <div style={{ display: 'flex' }}>\n <div style={{ width: sidebarWidth, flexShrink: 0 }} />\n <div style={{ flex: 1, overflow: 'hidden' }}>{enhanced}</div>\n </div>\n )\n }\n return child\n })\n\n return (\n <div className={className} style={{\n position: 'sticky', top: 0, zIndex: 20, display: 'flex', flexDirection: 'column',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n borderTop: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n ...style,\n }}>\n {enhancedChildren}\n </div>\n )\n}\nTimelineHeaders.displayName = 'TimelineHeaders'\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_weekOfYear=t()}(this,(function(){\"use strict\";var e=\"week\",t=\"year\";return function(i,n,r){var f=n.prototype;f.week=function(i){if(void 0===i&&(i=null),null!==i)return this.add(7*(i-this.week()),\"day\");var n=this.$locale().yearStart||1;if(11===this.month()&&this.date()>25){var f=r(this).startOf(t).add(1,t).date(n),s=r(this).endOf(e);if(f.isBefore(s))return 1}var a=r(this).startOf(t).date(n).startOf(e).subtract(1,\"millisecond\"),o=this.diff(a,e,!0);return o<0?r(this).startOf(\"week\").week():Math.ceil(o)},f.weeks=function(e){return void 0===e&&(e=null),this.week(e)}}}));","import { useMemo, useCallback } from 'react'\nimport dayjs from 'dayjs'\nimport weekOfYear from 'dayjs/plugin/weekOfYear'\nimport type { TimelineTheme } from '../types'\n\ndayjs.extend(weekOfYear)\n\nexport type DateUnit = 'year' | 'month' | 'week' | 'day' | 'hour'\n\n// Minimum cell width in pixels before the header auto-hides\nconst DEFAULT_MIN_CELL_WIDTH: Record<DateUnit, number> = {\n year: 30,\n month: 30,\n week: 20,\n day: 15,\n hour: 30,\n}\n\nexport interface DateHeaderProps {\n unit: DateUnit\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n theme?: TimelineTheme\n height?: number\n className?: string\n labelFormat?: string | ((start: Date, end: Date, unit: DateUnit) => string)\n onIntervalClick?: (startTime: number, endTime: number) => void\n /** Minimum cell width in pixels. Header auto-hides when cells are narrower. Set to 0 to disable. */\n minCellWidth?: number\n // Called by TimelineHeaders to inject zoom behavior\n onZoomToInterval?: (start: number, end: number) => void\n}\n\nexport function DateHeader({\n unit,\n visibleTimeStart = 0,\n visibleTimeEnd = 0,\n canvasWidth = 0,\n theme,\n height = 28,\n className,\n labelFormat,\n onIntervalClick,\n minCellWidth,\n onZoomToInterval,\n}: DateHeaderProps) {\n const intervals = useMemo(() => {\n if (!visibleTimeStart || !visibleTimeEnd || !canvasWidth) return []\n\n const duration = visibleTimeEnd - visibleTimeStart\n\n // Check average cell width — auto-hide if too narrow\n const minWidth = minCellWidth ?? DEFAULT_MIN_CELL_WIDTH[unit]\n if (minWidth > 0) {\n const sampleStart = dayjs(visibleTimeStart).startOf(unit)\n const sampleEnd = sampleStart.add(1, unit)\n const avgCellWidth = ((sampleEnd.valueOf() - sampleStart.valueOf()) / duration) * canvasWidth\n if (avgCellWidth < minWidth) return []\n }\n\n const result: Array<{ start: number; end: number; label: string; left: number; width: number }> = []\n // Add buffer: 1 extra unit before and after visible range\n let current = dayjs(visibleTimeStart).startOf(unit).subtract(1, unit)\n const endBound = dayjs(visibleTimeEnd).add(2, unit).valueOf()\n\n while (current.valueOf() < endBound) {\n const next = current.add(1, unit)\n const start = current.valueOf()\n const end = next.valueOf()\n const left = ((start - visibleTimeStart) / duration) * canvasWidth\n const width = ((end - start) / duration) * canvasWidth\n const label = formatLabel(current, next, unit, labelFormat, width)\n result.push({ start, end, label, left, width })\n current = next\n }\n return result\n }, [visibleTimeStart, visibleTimeEnd, canvasWidth, unit, labelFormat, minCellWidth])\n\n const handleClick = useCallback((start: number, end: number) => {\n if (onIntervalClick) {\n onIntervalClick(start, end)\n } else if (onZoomToInterval) {\n onZoomToInterval(start, end)\n }\n }, [onIntervalClick, onZoomToInterval])\n\n // Auto-hide: return nothing if no intervals (cells too narrow)\n if (intervals.length === 0) return null\n\n return (\n <div style={{ display: 'flex', position: 'relative', height, overflow: 'hidden' }}>\n {intervals.map((interval) => (\n <div\n key={interval.start}\n className={className}\n onClick={() => handleClick(interval.start, interval.end)}\n style={{\n position: 'absolute',\n left: interval.left,\n width: interval.width,\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRight: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n fontSize: 12,\n color: theme?.header.text ?? '#6c737f',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n cursor: 'pointer',\n userSelect: 'none',\n padding: '0 4px',\n boxSizing: 'border-box',\n }}\n >\n <span>{interval.label}</span>\n </div>\n ))}\n </div>\n )\n}\nDateHeader.displayName = 'DateHeader'\n\nfunction formatLabel(\n start: dayjs.Dayjs,\n end: dayjs.Dayjs,\n unit: DateUnit,\n labelFormat: string | ((start: Date, end: Date, unit: DateUnit) => string) | undefined,\n _width: number,\n): string {\n if (typeof labelFormat === 'function') {\n return labelFormat(start.toDate(), end.toDate(), unit)\n }\n if (typeof labelFormat === 'string') {\n return start.format(labelFormat)\n }\n return formatDefault(start, unit)\n}\n\nfunction formatDefault(d: dayjs.Dayjs, unit: DateUnit): string {\n switch (unit) {\n case 'year': return d.format('YYYY')\n case 'month': return d.format('MM')\n case 'week': return `${d.week()}`\n case 'day': return d.format('D')\n case 'hour': return d.format('HH:mm')\n }\n}\n","import React from 'react'\n\ninterface SidebarHeaderProps {\n width: number\n children?: (props: { getRootProps: () => React.HTMLAttributes<HTMLDivElement> }) => React.ReactNode\n style?: React.CSSProperties\n}\n\nexport function SidebarHeader({ width, children, style }: SidebarHeaderProps) {\n const getRootProps = (): React.HTMLAttributes<HTMLDivElement> => ({ style: { width, ...style } })\n if (children) return <>{children({ getRootProps })}</>\n return <div style={{ width }} />\n}\nSidebarHeader.displayName = 'SidebarHeader'\n","import React from 'react'\ninterface CustomHeaderProps { children: React.ReactNode }\nexport function CustomHeader({ children }: CustomHeaderProps) { return <>{children}</> }\nCustomHeader.displayName = 'CustomHeader'\n"],"names":["DEFAULT_THEME","ViewState","config","params","time","x","y","raw","index","extend","firstVisible","visibleCount","lastVisible","scrollXOffset","bufferPixels","IntervalTree","items","getStart","getEnd","intervals","item","min","max","iv","center","leftIntervals","rightIntervals","overlapping","start","end","results","node","LayoutEngine","lineHeight","itemHeightRatio","stackItems","itemHeight","byGroup","arr","groupId","groupItems","a","b","d","levelEnds","maxLevel","level","i","itemId","hitTest","canvasX","canvasY","view","tree","layout","groups","groupIndexMap","candidates","topItem","topY","groupIndex","itemLayout","width","height","hitTestGroup","detectEdge","threshold","leftX","rightX","setupCanvas","canvas","dpr","targetW","targetH","ctx","clearCanvas","RenderScheduler","drawCallback","layer","flags","GridLayer","theme","dayStyle","rowStyle","highlights","group","bgColor","customRow","h","x1","x2","opacity","r","g","visibleStart","visibleEnd","dayPixelWidth","stepUnit","current","dayjs","batchColor","batchOpacity","batchStartX","customBorderLines","flushBatch","endX","date","custom","color","dow","line","textWidth","padding","badgeWidth","badgeHeight","badgeX","badgeY","ITEM_FONT","createDrawHelpers","bounds","w","radius","text","maxWidth","lo","hi","mid","candidate","color1","color2","grad","type","size","half","cx","cy","fillColor","stemW","stemX","paddingH","pillHeight","pillWidth","ItemsLayer","itemRenderer","groupRenderer","selected","hoveredItemId","dependencies","queryStart","queryEnd","visibleItems","selectedSet","itemBoundsMap","yMin","yMax","state","helpers","depItemIds","dep","itemMap","id","boundsMap","fromBounds","toBounds","isHighlighted","startX","startY","endY","dx","cpOffset","arrowSize","OverlayLayer","options","cursorX","snapX","markers","interaction","marker","maxBadgeWidth","maxTextWidth","displayText","MAX_DELTA","normalizeDelta","e","delta","ZoomHandler","onZoom","visibleTimeStart","visibleTimeEnd","minZoom","maxZoom","cursorRatio","speed","scale","currentDuration","newDuration","newStart","newEnd","ACTIVATION_THRESHOLD","InteractionHandler","dragSnap","mode","pixelsPerMs","deltaMs","newStartTime","snapped","newGroupId","edge","newTime","_a","collectItemEdges","excludeItemId","timeToX","edges","findSnapTarget","currentX","edgeXPositions","thresholdPx","_pixelsPerMs","_dragSnap","closestX","closestDist","dist","t","module","this","s","n","o","u","OVERSCAN","Sidebar","scrollTop","canvasHeight","onScroll","containerRef","useRef","isScrollingRef","totalHeight","displayHeight","handleScroll","useCallback","useEffect","visibleGroups","_jsx","TodayMarker","_props","getTodayMarkerConfig","props","getTodayMarkerInterval","CustomMarker","getCustomMarkerConfig","isoWeek","mergeTheme","partial","HEADER_THROTTLE_MS","CanvasTimeline","React","forwardRef","ref","defaultTimeStart","defaultTimeEnd","sidebarWidth","canMove","canChangeGroup","canResize","themePartial","showCursorLine","sidebarGroupRenderer","onItemClick","onItemDoubleClick","onItemContextMenu","onItemMove","onItemResize","moveResizeValidator","onItemHover","onCanvasDoubleClick","onCanvasContextMenu","onTimeChange","selectedProp","rightSidebarWidth","rightSidebarGroupRenderer","onReady","children","useMemo","getGroupIndex","grps","selectedKey","gridCanvasRef","itemsCanvasRef","overlayCanvasRef","interactionRef","outerRef","containerWidth","setContainerWidth","useState","container","obs","entries","entry","canvasWidth","viewStateRef","cursorXRef","hoveredItemIdRef","headerTimeStart","setHeaderTimeStart","headerTimeEnd","setHeaderTimeEnd","sidebarScrollTop","setSidebarScrollTop","headerTimerRef","syncHeaderState","vs","scheduleHeaderSync","intervalTree","layoutEngine","engine","gridLayer","itemsLayer","overlayLayer","interactionHandler","markerConfigs","configs","child","displayName","markersKey","m","markersRef","todayMarkerInterval","interval","propsRef","drawGrid","p","drawItems","calculateSnapX","deltaX","draggedEdgeXs","otherEdges","edgeX","drawOverlay","interactionRender","origX","origWidth","targetGroupY","groupChanged","schedulerRef","scheduler","timer","highlightsKey","prevHighlightsKey","prevMarkersKey","prevControlledStart","prevControlledEnd","callbackTimerRef","scheduleCallbacks","_b","zoomHandlerRef","zoomHandler","handleVerticalScroll","deltaY","maxScroll","newScrollTop","handleHorizontalScroll","flushSync","_c","el","handleWheel","rect","touchRef","getDistance","t1","t2","getCenter","handleTouchStart","handleTouchMove","newDistance","cursorTime","handleTouchEnd","handlePointerMove","newHoveredId","cr","handlePointerDown","handlePointerUp","validator","result","draggedStartX","draggedEndX","snappedStartTime","startSnap","endSnap","duration","validatedTime","edgeTime","snap","snappedTime","_d","_f","_e","handleDoubleClick","handleContextMenu","handlePointerLeave","headerChildren","headers","childProps","initialDrawDone","useImperativeHandle","timeStart","timeEnd","printSidebarWidth","headerRowHeight","headerHeight","currentPixelsPerMs","printDuration","timelineWidth","compositeWidth","compositeHeight","style","groupType","fontWeight","indent","drawHeaderRow","rowY","getLabel","unit","cursor","pxPerMs","nextCursor","printViewState","api","fullWidth","fullHeight","rs","gt","fw","fs","title","units","row","hy","cur","endBound","next","sx","label","pv","canvasContainerStyle","canvasStyle","_jsxs","TimelineHeaders","className","_classNames","onZoomToInterval","enhancedChildren","enhanced","f","weekOfYear","DEFAULT_MIN_CELL_WIDTH","DateHeader","labelFormat","onIntervalClick","minCellWidth","minWidth","sampleStart","left","formatLabel","handleClick","_width","formatDefault","SidebarHeader","getRootProps","_Fragment","CustomHeader"],"mappings":"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","x_google_ignoreList":[13,19]}