@taskctrl/canvas-timeline 0.4.5 → 0.5.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.cjs.js","sources":["../src/types.ts","../src/core/ViewState.ts","../src/core/IntervalTree.ts","../src/core/LayoutEngine.ts","../src/core/HierarchyEngine.ts","../src/canvas/defaultSummaryRenderer.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 parentId?: 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 summaryRenderer?: CanvasItemRenderer\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, childMoves?: { itemId: number; newStart: 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 /** Dev-only: show a version + build-time badge in the top-left corner.\n * Wire to your app's dev flag, e.g. `devBadge={import.meta.env.DEV}`. */\n devBadge?: boolean\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'\nimport type { HierarchyEngine } from './HierarchyEngine'\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, hierarchy?: HierarchyEngine): Map<number, ItemLayout> {\n this.layoutCache = new Map()\n this.groupMaxStack = new Map()\n\n const itemHeight = this.lineHeight * this.itemHeightRatio\n const summaryHeight = itemHeight * 0.6\n\n if (!stackItems) {\n for (const item of items) {\n const isSummary = hierarchy?.isParent(item.id) ?? false\n this.layoutCache.set(item.id, { stackLevel: 0, itemHeight: isSummary ? summaryHeight : 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 for (const [groupId, groupItems] of byGroup) {\n if (hierarchy) {\n this.computeHierarchyLayout(groupItems, hierarchy, itemHeight, summaryHeight, groupId)\n } else {\n this.computeFlatLayout(groupItems, itemHeight, groupId)\n }\n }\n\n return this.layoutCache\n }\n\n private computeFlatLayout(groupItems: Item[], itemHeight: number, groupId: string | number): void {\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 private computeHierarchyLayout(\n groupItems: Item[],\n hierarchy: HierarchyEngine,\n itemHeight: number,\n summaryHeight: number,\n groupId: string | number,\n ): void {\n // Separate leaf items from parents\n const leaves: Item[] = []\n const parents: Item[] = []\n for (const item of groupItems) {\n if (hierarchy.isParent(item.id)) {\n parents.push(item)\n } else {\n leaves.push(item)\n }\n }\n\n // Stack leaves first using sweep-line\n leaves.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 leaves) {\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 // Stack parents above leaves, sorted by nesting depth\n // Deepest parents first (closest to children), shallowest last (on top)\n parents.sort((a, b) => hierarchy.getNestingDepth(b.id) - hierarchy.getNestingDepth(a.id))\n\n let nextLevel = leaves.length > 0 ? maxLevel + 1 : 0\n for (const parent of parents) {\n this.layoutCache.set(parent.id, { stackLevel: nextLevel, itemHeight: summaryHeight })\n if (nextLevel > maxLevel) maxLevel = nextLevel\n nextLevel++\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\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","interface HierarchyItem {\n id: number\n start_time: number\n end_time: number\n parentId?: number\n}\n\nexport class HierarchyEngine {\n private parentToChildren: Map<number, number[]> = new Map()\n private childToParent: Map<number, number> = new Map()\n private itemMap: Map<number, HierarchyItem> = new Map()\n private depthCache: Map<number, number> = new Map()\n\n rebuild(items: HierarchyItem[]): void {\n this.parentToChildren = new Map()\n this.childToParent = new Map()\n this.itemMap = new Map()\n this.depthCache = new Map()\n\n for (const item of items) {\n this.itemMap.set(item.id, item)\n }\n\n for (const item of items) {\n if (item.parentId !== undefined && this.itemMap.has(item.parentId)) {\n this.childToParent.set(item.id, item.parentId)\n let children = this.parentToChildren.get(item.parentId)\n if (!children) {\n children = []\n this.parentToChildren.set(item.parentId, children)\n }\n children.push(item.id)\n }\n }\n\n // Detect and break cycles\n for (const id of this.childToParent.keys()) {\n const visited = new Set<number>()\n let current: number | undefined = id\n while (current !== undefined) {\n if (visited.has(current)) {\n const parentId = this.childToParent.get(id)!\n this.childToParent.delete(id)\n const siblings = this.parentToChildren.get(parentId)\n if (siblings) {\n const idx = siblings.indexOf(id)\n if (idx !== -1) siblings.splice(idx, 1)\n if (siblings.length === 0) this.parentToChildren.delete(parentId)\n }\n break\n }\n visited.add(current)\n current = this.childToParent.get(current)\n }\n }\n }\n\n isParent(itemId: number): boolean {\n const children = this.parentToChildren.get(itemId)\n return children !== undefined && children.length > 0\n }\n\n getParent(itemId: number): number | undefined {\n return this.childToParent.get(itemId)\n }\n\n getChildren(itemId: number): number[] {\n return this.parentToChildren.get(itemId) ?? []\n }\n\n getDescendants(itemId: number): number[] {\n const result: number[] = []\n const stack = [...this.getChildren(itemId)]\n while (stack.length > 0) {\n const id = stack.pop()!\n result.push(id)\n const children = this.parentToChildren.get(id)\n if (children) stack.push(...children)\n }\n return result\n }\n\n getEffectiveSpan(itemId: number): { start: number; end: number } {\n const item = this.itemMap.get(itemId)\n if (!item) return { start: 0, end: 0 }\n\n let start = item.start_time\n let end = item.end_time\n\n const descendants = this.getDescendants(itemId)\n for (const descId of descendants) {\n const desc = this.itemMap.get(descId)\n if (!desc) continue\n if (desc.start_time < start) start = desc.start_time\n if (desc.end_time > end) end = desc.end_time\n }\n\n return { start, end }\n }\n\n getNestingDepth(itemId: number): number {\n const cached = this.depthCache.get(itemId)\n if (cached !== undefined) return cached\n\n let depth = 0\n let current = this.childToParent.get(itemId)\n while (current !== undefined) {\n depth++\n current = this.childToParent.get(current)\n }\n this.depthCache.set(itemId, depth)\n return depth\n }\n\n getMoveDelta(itemId: number, newStart: number): { itemId: number; newStart: number }[] {\n const item = this.itemMap.get(itemId)\n if (!item) return []\n\n const delta = newStart - item.start_time\n const descendants = this.getDescendants(itemId)\n return descendants.map(descId => {\n const desc = this.itemMap.get(descId)!\n return { itemId: descId, newStart: desc.start_time + delta }\n })\n }\n\n getResizeConstraint(itemId: number, edge: 'left' | 'right'): { min: number; max: number } {\n const children = this.getDescendants(itemId)\n if (children.length === 0) {\n return edge === 'left'\n ? { min: -Infinity, max: Infinity }\n : { min: -Infinity, max: Infinity }\n }\n\n if (edge === 'left') {\n let minChildStart = Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.start_time < minChildStart) {\n minChildStart = child.start_time\n }\n }\n return { min: -Infinity, max: minChildStart }\n } else {\n let maxChildEnd = -Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.end_time > maxChildEnd) {\n maxChildEnd = child.end_time\n }\n }\n return { min: maxChildEnd, max: Infinity }\n }\n }\n}\n","import type { Item, ItemBounds, ItemState, DrawHelpers, TimelineTheme } from '../types'\n\nexport function defaultSummaryRenderer(\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n _helpers: DrawHelpers,\n theme: TimelineTheme,\n): void {\n const { x, y, width, height } = bounds\n const color = theme.primary\n\n // Semi-transparent fill\n ctx.globalAlpha = 0.15\n ctx.fillStyle = color\n ctx.fillRect(x, y, width, height)\n ctx.globalAlpha = 1\n\n // Border\n ctx.strokeStyle = color\n ctx.lineWidth = 1.5\n ctx.strokeRect(x, y, width, height)\n\n // Diamond marker at start edge\n const diamondSize = Math.min(height * 0.5, 6)\n const midY = y + height / 2\n\n ctx.fillStyle = color\n // Left diamond\n ctx.beginPath()\n ctx.moveTo(x, midY)\n ctx.lineTo(x + diamondSize, midY - diamondSize)\n ctx.lineTo(x + diamondSize * 2, midY)\n ctx.lineTo(x + diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Right diamond\n ctx.beginPath()\n ctx.moveTo(x + width, midY)\n ctx.lineTo(x + width - diamondSize, midY - diamondSize)\n ctx.lineTo(x + width - diamondSize * 2, midY)\n ctx.lineTo(x + width - diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Title text centered\n const title = (item as { title?: string }).title\n if (title && width > 30) {\n ctx.fillStyle = theme.item.text\n ctx.font = '500 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n const textWidth = ctx.measureText(title).width\n const maxTextWidth = width - diamondSize * 4 - 4\n if (maxTextWidth > 20) {\n const displayText = textWidth > maxTextWidth\n ? title.slice(0, Math.floor(title.length * maxTextWidth / textWidth)) + '...'\n : title\n ctx.fillText(displayText, x + width / 2 - Math.min(textWidth, maxTextWidth) / 2, midY)\n }\n }\n\n // Selected ring\n if (state.selected) {\n ctx.strokeStyle = theme.item.selectedRing\n ctx.lineWidth = 2\n ctx.strokeRect(x - 1, y - 1, width + 2, height + 2)\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 type { HierarchyEngine } from '../core/HierarchyEngine'\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 summaryRenderer?: CanvasItemRenderer,\n hierarchy?: HierarchyEngine,\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 let renderer: CanvasItemRenderer\n if (summaryRenderer && hierarchy?.isParent(item.id)) {\n renderer = summaryRenderer\n } else if (groupRenderer && (item.type === 'control_area_group' || item.type === 'construction_train')) {\n renderer = groupRenderer\n } else {\n renderer = itemRenderer\n }\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 Item,\n ItemBounds,\n ItemState,\n DrawHelpers,\n} from './types'\nimport { DEFAULT_THEME } from './types'\nimport { ViewState } from './core/ViewState'\nimport { IntervalTree } from './core/IntervalTree'\nimport { LayoutEngine } from './core/LayoutEngine'\nimport { HierarchyEngine } from './core/HierarchyEngine'\nimport { defaultSummaryRenderer } from './canvas/defaultSummaryRenderer'\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 devBadge,\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 // --- PAN STATE ---\n const panRef = useRef<{ startX: number; startY: number; lastX: number; lastY: number } | null>(null)\n const didPanRef = useRef(false)\n const PAN_THRESHOLD = 4\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 hierarchyEngine = useMemo(() => {\n const engine = new HierarchyEngine()\n engine.rebuild(items)\n return engine\n }, [items])\n\n const intervalTree = useMemo(() => {\n const tree = new IntervalTree<(typeof items)[0]>()\n tree.buildFromItems(\n items,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).start,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).end,\n )\n return tree\n }, [items, hierarchyEngine])\n\n const layoutEngine = useMemo(() => {\n const engine = new LayoutEngine(lineHeight, itemHeightRatio)\n engine.computeLayout(items, stackItems, hierarchyEngine)\n return engine\n }, [items, lineHeight, itemHeightRatio, stackItems, hierarchyEngine])\n\n const resolvedSummaryRenderer = useMemo(() => {\n if (props.summaryRenderer) return props.summaryRenderer\n return (ctx: CanvasRenderingContext2D, item: Item, bounds: ItemBounds, state: ItemState, helpers: DrawHelpers) => {\n defaultSummaryRenderer(ctx, item, bounds, state, helpers, theme)\n }\n }, [props.summaryRenderer, theme])\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 summaryRenderer: resolvedSummaryRenderer, hierarchyEngine,\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 summaryRenderer: resolvedSummaryRenderer, hierarchyEngine,\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 p.summaryRenderer, p.hierarchyEngine,\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 — snap the edge being dragged, not the start\n const edgeTime = mode === 'resize-right'\n ? item.end_time + deltaMs\n : item.start_time + deltaMs\n const snapped = Math.round(edgeTime / 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 // --- Pan mode (drag on empty canvas) ---\n if (panRef.current) {\n const dx = e.clientX - panRef.current.startX\n const dy = e.clientY - panRef.current.startY\n if (!didPanRef.current && (Math.abs(dx) >= PAN_THRESHOLD || Math.abs(dy) >= PAN_THRESHOLD)) {\n didPanRef.current = true\n el.style.cursor = 'grabbing'\n el.setPointerCapture(e.pointerId)\n }\n if (didPanRef.current) {\n const moveDeltaX = e.clientX - panRef.current.lastX\n const moveDeltaY = e.clientY - panRef.current.lastY\n panRef.current.lastX = e.clientX\n panRef.current.lastY = e.clientY\n if (Math.abs(moveDeltaX) > 0) handleHorizontalScroll(-moveDeltaX)\n if (Math.abs(moveDeltaY) > 0) handleVerticalScroll(-moveDeltaY)\n }\n return\n }\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, handleHorizontalScroll, handleVerticalScroll])\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\n if (!item) {\n // Start pan on empty canvas\n panRef.current = { startX: e.clientX, startY: e.clientY, lastX: e.clientX, lastY: e.clientY }\n didPanRef.current = false\n return\n }\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\n // --- End pan mode ---\n if (panRef.current) {\n const wasPanning = didPanRef.current\n panRef.current = null\n didPanRef.current = false\n el.style.cursor = 'default'\n if (wasPanning) return // suppress click after pan\n }\n\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 const childMoves = propsRef.current.hierarchyEngine.getMoveDelta(state.item.id, validatedTime)\n propsRef.current.onItemMove?.(state.item.id, validatedTime, result.newGroupId, childMoves.length > 0 ? childMoves : undefined)\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 let constrainedTime = snap !== null ? vs.xToTime(snap) : result.newTime\n // Apply hierarchy resize constraints\n const constraint = propsRef.current.hierarchyEngine.getResizeConstraint(state.item.id, result.edge)\n if (result.edge === 'left' && constrainedTime > constraint.max) {\n constrainedTime = constraint.max\n } else if (result.edge === 'right' && constrainedTime < constraint.min) {\n constrainedTime = constraint.min\n }\n\n const validatedTime = validator ? validator('resize', state.item.id, constrainedTime, result.edge) : constrainedTime\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 panRef.current = null\n didPanRef.current = false\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 p.summaryRenderer, p.hierarchyEngine,\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 p.summaryRenderer, p.hierarchyEngine)\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%', position: 'relative' }}>\n {(__LIB_DEV__ || devBadge) ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 9999,\n padding: '2px 6px',\n fontSize: 10,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n lineHeight: 1.4,\n color: '#fff',\n background: 'rgba(17, 24, 39, 0.78)',\n borderBottomRightRadius: 4,\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n v{__LIB_VERSION__} · {__LIB_BUILD__}\n </div>\n ) : null}\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","hierarchy","itemHeight","summaryHeight","isSummary","byGroup","arr","groupId","groupItems","b","d","levelEnds","maxLevel","level","i","leaves","parents","a","nextLevel","parent","itemId","HierarchyEngine","children","id","visited","current","parentId","siblings","idx","result","stack","descendants","descId","desc","cached","depth","newStart","delta","edge","minChildStart","childId","child","maxChildEnd","defaultSummaryRenderer","ctx","bounds","state","_helpers","theme","width","height","color","diamondSize","midY","title","textWidth","maxTextWidth","displayText","hitTest","canvasX","canvasY","view","tree","layout","groups","groupIndexMap","candidates","topItem","topY","groupIndex","itemLayout","hitTestGroup","detectEdge","threshold","leftX","rightX","setupCanvas","canvas","dpr","targetW","targetH","clearCanvas","RenderScheduler","drawCallback","layer","flags","GridLayer","dayStyle","rowStyle","highlights","group","bgColor","customRow","h","x1","x2","w","opacity","r","g","visibleStart","visibleEnd","dayPixelWidth","stepUnit","dayjs","batchColor","batchOpacity","batchStartX","customBorderLines","flushBatch","endX","date","custom","dow","line","padding","badgeWidth","badgeHeight","badgeX","badgeY","ITEM_FONT","createDrawHelpers","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","summaryRenderer","queryStart","queryEnd","visibleItems","selectedSet","itemBoundsMap","yMin","yMax","helpers","renderer","depItemIds","dep","itemMap","boundsMap","fromBounds","toBounds","isHighlighted","startX","startY","endY","dx","cpOffset","arrowSize","OverlayLayer","options","cursorX","snapX","markers","interaction","marker","maxBadgeWidth","MAX_DELTA","normalizeDelta","e","ZoomHandler","onZoom","visibleTimeStart","visibleTimeEnd","minZoom","maxZoom","cursorRatio","speed","scale","currentDuration","newDuration","newEnd","ACTIVATION_THRESHOLD","InteractionHandler","dragSnap","mode","pixelsPerMs","deltaMs","newStartTime","snapped","newGroupId","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","devBadge","useMemo","getGroupIndex","grps","selectedKey","gridCanvasRef","itemsCanvasRef","overlayCanvasRef","interactionRef","outerRef","containerWidth","setContainerWidth","useState","container","obs","entries","entry","canvasWidth","viewStateRef","cursorXRef","hoveredItemIdRef","panRef","didPanRef","PAN_THRESHOLD","headerTimeStart","setHeaderTimeStart","headerTimeEnd","setHeaderTimeEnd","sidebarScrollTop","setSidebarScrollTop","headerTimerRef","syncHeaderState","vs","scheduleHeaderSync","hierarchyEngine","engine","intervalTree","layoutEngine","resolvedSummaryRenderer","gridLayer","itemsLayer","overlayLayer","interactionHandler","markerConfigs","configs","displayName","markersKey","m","markersRef","todayMarkerInterval","interval","propsRef","drawGrid","p","drawItems","calculateSnapX","deltaX","draggedEdgeXs","otherEdges","edgeX","edgeTime","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","dy","moveDeltaX","moveDeltaY","newHoveredId","cr","handlePointerDown","handlePointerUp","wasPanning","validator","draggedStartX","draggedEndX","snappedStartTime","startSnap","endSnap","duration","validatedTime","childMoves","snap","constrainedTime","constraint","_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","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":[15,21]}
|
|
1
|
+
{"version":3,"file":"canvas-timeline.cjs.js","sources":["../src/types.ts","../src/core/ViewState.ts","../src/core/IntervalTree.ts","../src/core/LayoutEngine.ts","../src/core/HierarchyEngine.ts","../src/canvas/defaultSummaryRenderer.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 parentId?: 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 summaryRenderer?: CanvasItemRenderer\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, childMoves?: { itemId: number; newStart: 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 /** Dev-only: show a version + build-time badge in the top-left corner.\n * Wire to your app's dev flag, e.g. `devBadge={import.meta.env.DEV}`. */\n devBadge?: boolean\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 groupHeights?: 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 groupHeights: number[] | null\n\n private visibleDuration: number\n private pixelsPerMs: number\n // Cumulative top-edge offsets per group: length = groupCount + 1,\n // groupYOffsets[i] = sum of heights[0..i-1]; groupYOffsets[groupCount] = total.\n private groupYOffsets: 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 this.groupHeights = config.groupHeights ?? null\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n this.groupYOffsets = []\n this.recomputeGroupYOffsets()\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 if (params.groupHeights !== undefined) this.groupHeights = params.groupHeights ?? null\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n this.recomputeGroupYOffsets()\n }\n\n private recomputeGroupYOffsets(): void {\n const offsets = new Array<number>(this.groupCount + 1)\n offsets[0] = 0\n for (let i = 0; i < this.groupCount; i++) {\n const h = this.groupHeights?.[i] ?? this.lineHeight\n offsets[i + 1] = offsets[i] + h\n }\n this.groupYOffsets = offsets\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 if (this.groupCount === 0) return 0\n const target = y + this.scrollTop\n if (target <= 0) return 0\n if (target >= this.groupYOffsets[this.groupCount]) return this.groupCount - 1\n // Binary search: smallest i where groupYOffsets[i + 1] > target.\n let lo = 0\n let hi = this.groupCount - 1\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (this.groupYOffsets[mid + 1] > target) hi = mid\n else lo = mid + 1\n }\n return lo\n }\n\n groupIndexToY(index: number): number {\n if (index < 0) return -this.scrollTop\n if (index >= this.groupCount) {\n return (this.groupYOffsets[this.groupCount] ?? 0) - this.scrollTop\n }\n return this.groupYOffsets[index] - this.scrollTop\n }\n\n groupIndexToHeight(index: number): number {\n if (index < 0 || index >= this.groupCount) return this.lineHeight\n return this.groupHeights?.[index] ?? this.lineHeight\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 if (this.groupCount === 0) return { firstVisible: 0, lastVisible: -1 }\n const firstVisible = this.yToGroupIndex(0)\n const lastVisible = this.yToGroupIndex(this.canvasHeight)\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.groupYOffsets[this.groupCount] ?? 0\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'\nimport type { HierarchyEngine } from './HierarchyEngine'\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, hierarchy?: HierarchyEngine): Map<number, ItemLayout> {\n this.layoutCache = new Map()\n this.groupMaxStack = new Map()\n\n const itemHeight = this.lineHeight * this.itemHeightRatio\n const summaryHeight = itemHeight * 0.6\n\n if (!stackItems) {\n for (const item of items) {\n const isSummary = hierarchy?.isParent(item.id) ?? false\n this.layoutCache.set(item.id, { stackLevel: 0, itemHeight: isSummary ? summaryHeight : 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 for (const [groupId, groupItems] of byGroup) {\n if (hierarchy) {\n this.computeHierarchyLayout(groupItems, hierarchy, itemHeight, summaryHeight, groupId)\n } else {\n this.computeFlatLayout(groupItems, itemHeight, groupId)\n }\n }\n\n return this.layoutCache\n }\n\n private computeFlatLayout(groupItems: Item[], itemHeight: number, groupId: string | number): void {\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 private computeHierarchyLayout(\n groupItems: Item[],\n hierarchy: HierarchyEngine,\n itemHeight: number,\n summaryHeight: number,\n groupId: string | number,\n ): void {\n // Separate leaf items from parents\n const leaves: Item[] = []\n const parents: Item[] = []\n for (const item of groupItems) {\n if (hierarchy.isParent(item.id)) {\n parents.push(item)\n } else {\n leaves.push(item)\n }\n }\n\n // Stack leaves first using sweep-line\n leaves.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 leaves) {\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 // Stack parents above leaves, sorted by nesting depth\n // Deepest parents first (closest to children), shallowest last (on top)\n parents.sort((a, b) => hierarchy.getNestingDepth(b.id) - hierarchy.getNestingDepth(a.id))\n\n let nextLevel = leaves.length > 0 ? maxLevel + 1 : 0\n for (const parent of parents) {\n this.layoutCache.set(parent.id, { stackLevel: nextLevel, itemHeight: summaryHeight })\n if (nextLevel > maxLevel) maxLevel = nextLevel\n nextLevel++\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\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","interface HierarchyItem {\n id: number\n start_time: number\n end_time: number\n parentId?: number\n}\n\nexport class HierarchyEngine {\n private parentToChildren: Map<number, number[]> = new Map()\n private childToParent: Map<number, number> = new Map()\n private itemMap: Map<number, HierarchyItem> = new Map()\n private depthCache: Map<number, number> = new Map()\n\n rebuild(items: HierarchyItem[]): void {\n this.parentToChildren = new Map()\n this.childToParent = new Map()\n this.itemMap = new Map()\n this.depthCache = new Map()\n\n for (const item of items) {\n this.itemMap.set(item.id, item)\n }\n\n for (const item of items) {\n if (item.parentId !== undefined && this.itemMap.has(item.parentId)) {\n this.childToParent.set(item.id, item.parentId)\n let children = this.parentToChildren.get(item.parentId)\n if (!children) {\n children = []\n this.parentToChildren.set(item.parentId, children)\n }\n children.push(item.id)\n }\n }\n\n // Detect and break cycles\n for (const id of this.childToParent.keys()) {\n const visited = new Set<number>()\n let current: number | undefined = id\n while (current !== undefined) {\n if (visited.has(current)) {\n const parentId = this.childToParent.get(id)!\n this.childToParent.delete(id)\n const siblings = this.parentToChildren.get(parentId)\n if (siblings) {\n const idx = siblings.indexOf(id)\n if (idx !== -1) siblings.splice(idx, 1)\n if (siblings.length === 0) this.parentToChildren.delete(parentId)\n }\n break\n }\n visited.add(current)\n current = this.childToParent.get(current)\n }\n }\n }\n\n isParent(itemId: number): boolean {\n const children = this.parentToChildren.get(itemId)\n return children !== undefined && children.length > 0\n }\n\n getParent(itemId: number): number | undefined {\n return this.childToParent.get(itemId)\n }\n\n getChildren(itemId: number): number[] {\n return this.parentToChildren.get(itemId) ?? []\n }\n\n getDescendants(itemId: number): number[] {\n const result: number[] = []\n const stack = [...this.getChildren(itemId)]\n while (stack.length > 0) {\n const id = stack.pop()!\n result.push(id)\n const children = this.parentToChildren.get(id)\n if (children) stack.push(...children)\n }\n return result\n }\n\n getEffectiveSpan(itemId: number): { start: number; end: number } {\n const item = this.itemMap.get(itemId)\n if (!item) return { start: 0, end: 0 }\n\n let start = item.start_time\n let end = item.end_time\n\n const descendants = this.getDescendants(itemId)\n for (const descId of descendants) {\n const desc = this.itemMap.get(descId)\n if (!desc) continue\n if (desc.start_time < start) start = desc.start_time\n if (desc.end_time > end) end = desc.end_time\n }\n\n return { start, end }\n }\n\n getNestingDepth(itemId: number): number {\n const cached = this.depthCache.get(itemId)\n if (cached !== undefined) return cached\n\n let depth = 0\n let current = this.childToParent.get(itemId)\n while (current !== undefined) {\n depth++\n current = this.childToParent.get(current)\n }\n this.depthCache.set(itemId, depth)\n return depth\n }\n\n getMoveDelta(itemId: number, newStart: number): { itemId: number; newStart: number }[] {\n const item = this.itemMap.get(itemId)\n if (!item) return []\n\n const delta = newStart - item.start_time\n const descendants = this.getDescendants(itemId)\n return descendants.map(descId => {\n const desc = this.itemMap.get(descId)!\n return { itemId: descId, newStart: desc.start_time + delta }\n })\n }\n\n getResizeConstraint(itemId: number, edge: 'left' | 'right'): { min: number; max: number } {\n const children = this.getDescendants(itemId)\n if (children.length === 0) {\n return edge === 'left'\n ? { min: -Infinity, max: Infinity }\n : { min: -Infinity, max: Infinity }\n }\n\n if (edge === 'left') {\n let minChildStart = Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.start_time < minChildStart) {\n minChildStart = child.start_time\n }\n }\n return { min: -Infinity, max: minChildStart }\n } else {\n let maxChildEnd = -Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.end_time > maxChildEnd) {\n maxChildEnd = child.end_time\n }\n }\n return { min: maxChildEnd, max: Infinity }\n }\n }\n}\n","import type { Item, ItemBounds, ItemState, DrawHelpers, TimelineTheme } from '../types'\n\nexport function defaultSummaryRenderer(\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n _helpers: DrawHelpers,\n theme: TimelineTheme,\n): void {\n const { x, y, width, height } = bounds\n const color = theme.primary\n\n // Semi-transparent fill\n ctx.globalAlpha = 0.15\n ctx.fillStyle = color\n ctx.fillRect(x, y, width, height)\n ctx.globalAlpha = 1\n\n // Border\n ctx.strokeStyle = color\n ctx.lineWidth = 1.5\n ctx.strokeRect(x, y, width, height)\n\n // Diamond marker at start edge\n const diamondSize = Math.min(height * 0.5, 6)\n const midY = y + height / 2\n\n ctx.fillStyle = color\n // Left diamond\n ctx.beginPath()\n ctx.moveTo(x, midY)\n ctx.lineTo(x + diamondSize, midY - diamondSize)\n ctx.lineTo(x + diamondSize * 2, midY)\n ctx.lineTo(x + diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Right diamond\n ctx.beginPath()\n ctx.moveTo(x + width, midY)\n ctx.lineTo(x + width - diamondSize, midY - diamondSize)\n ctx.lineTo(x + width - diamondSize * 2, midY)\n ctx.lineTo(x + width - diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Title text centered\n const title = (item as { title?: string }).title\n if (title && width > 30) {\n ctx.fillStyle = theme.item.text\n ctx.font = '500 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n const textWidth = ctx.measureText(title).width\n const maxTextWidth = width - diamondSize * 4 - 4\n if (maxTextWidth > 20) {\n const displayText = textWidth > maxTextWidth\n ? title.slice(0, Math.floor(title.length * maxTextWidth / textWidth)) + '...'\n : title\n ctx.fillText(displayText, x + width / 2 - Math.min(textWidth, maxTextWidth) / 2, midY)\n }\n }\n\n // Selected ring\n if (state.selected) {\n ctx.strokeStyle = theme.item.selectedRing\n ctx.lineWidth = 2\n ctx.strokeRect(x - 1, y - 1, width + 2, height + 2)\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 rowHeight = view.groupIndexToHeight(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, rowHeight)\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 + rowHeight)\n ctx.lineTo(view.canvasWidth, y + rowHeight)\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 type { HierarchyEngine } from '../core/HierarchyEngine'\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 summaryRenderer?: CanvasItemRenderer,\n hierarchy?: HierarchyEngine,\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 let renderer: CanvasItemRenderer\n if (summaryRenderer && hierarchy?.isParent(item.id)) {\n renderer = summaryRenderer\n } else if (groupRenderer && (item.type === 'control_area_group' || item.type === 'construction_train')) {\n renderer = groupRenderer\n } else {\n renderer = itemRenderer\n }\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, useMemo } from 'react'\nimport type { Group, TimelineTheme } from '../types'\n\ninterface SidebarProps {\n groups: Group[]\n width: number\n lineHeight: number\n groupHeights?: 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_PX = 200\n\nexport function Sidebar({\n groups, width, lineHeight, groupHeights, scrollTop, canvasHeight, theme, groupRenderer, onScroll,\n}: SidebarProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false)\n\n // Cumulative top-edge offsets per group: length = groups.length + 1.\n const offsets = useMemo(() => {\n const arr = new Array<number>(groups.length + 1)\n arr[0] = 0\n for (let i = 0; i < groups.length; i++) {\n arr[i + 1] = arr[i] + (groupHeights?.[i] ?? lineHeight)\n }\n return arr\n }, [groups.length, groupHeights, lineHeight])\n\n const totalHeight = offsets[groups.length] ?? 0\n const displayHeight = canvasHeight\n\n // Binary search for the group containing a given y; clamped to [0, groups.length - 1].\n const groupAtY = useCallback((y: number): number => {\n if (groups.length === 0) return 0\n if (y <= 0) return 0\n if (y >= totalHeight) return groups.length - 1\n let lo = 0\n let hi = groups.length - 1\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (offsets[mid + 1] > y) hi = mid\n else lo = mid + 1\n }\n return lo\n }, [groups.length, offsets, totalHeight])\n\n const firstVisible = groupAtY(scrollTop - OVERSCAN_PX)\n const lastVisible = groupAtY(scrollTop + canvasHeight + OVERSCAN_PX)\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 const top = offsets[i]\n const height = offsets[i + 1] - top\n visibleGroups.push(\n <div\n key={group.id}\n style={{\n position: 'absolute',\n top,\n height,\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 Item,\n ItemBounds,\n ItemState,\n DrawHelpers,\n} from './types'\nimport { DEFAULT_THEME } from './types'\nimport { ViewState } from './core/ViewState'\nimport { IntervalTree } from './core/IntervalTree'\nimport { LayoutEngine } from './core/LayoutEngine'\nimport { HierarchyEngine } from './core/HierarchyEngine'\nimport { defaultSummaryRenderer } from './canvas/defaultSummaryRenderer'\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 devBadge,\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\n // --- CORE DATA STRUCTURES ---\n const hierarchyEngine = useMemo(() => {\n const engine = new HierarchyEngine()\n engine.rebuild(items)\n return engine\n }, [items])\n\n const intervalTree = useMemo(() => {\n const tree = new IntervalTree<(typeof items)[0]>()\n tree.buildFromItems(\n items,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).start,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).end,\n )\n return tree\n }, [items, hierarchyEngine])\n\n const layoutEngine = useMemo(() => {\n const engine = new LayoutEngine(lineHeight, itemHeightRatio)\n engine.computeLayout(items, stackItems, hierarchyEngine)\n return engine\n }, [items, lineHeight, itemHeightRatio, stackItems, hierarchyEngine])\n\n const groupHeights = useMemo(\n () => groups.map((g) => layoutEngine.getGroupHeight(g.id)),\n [groups, layoutEngine],\n )\n const canvasHeight = useMemo(\n () => groupHeights.reduce((a, b) => a + b, 0),\n [groupHeights],\n )\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 groupHeights,\n }),\n )\n\n const cursorXRef = useRef<number | null>(null)\n const hoveredItemIdRef = useRef<number | undefined>(undefined)\n\n // --- PAN STATE ---\n const panRef = useRef<{ startX: number; startY: number; lastX: number; lastY: number } | null>(null)\n const didPanRef = useRef(false)\n const PAN_THRESHOLD = 4\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 const resolvedSummaryRenderer = useMemo(() => {\n if (props.summaryRenderer) return props.summaryRenderer\n return (ctx: CanvasRenderingContext2D, item: Item, bounds: ItemBounds, state: ItemState, helpers: DrawHelpers) => {\n defaultSummaryRenderer(ctx, item, bounds, state, helpers, theme)\n }\n }, [props.summaryRenderer, theme])\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 summaryRenderer: resolvedSummaryRenderer, hierarchyEngine,\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 summaryRenderer: resolvedSummaryRenderer, hierarchyEngine,\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 p.summaryRenderer, p.hierarchyEngine,\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 — snap the edge being dragged, not the start\n const edgeTime = mode === 'resize-right'\n ? item.end_time + deltaMs\n : item.start_time + deltaMs\n const snapped = Math.round(edgeTime / 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({\n canvasWidth, canvasHeight, sidebarWidth, lineHeight,\n groupCount: groups.length, groupHeights,\n })\n scheduler.markAllDirty()\n }, [canvasWidth, canvasHeight, sidebarWidth, lineHeight, groups.length, groupHeights, 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.getTotalHeight()\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 // Some browsers (Chrome/Edge on macOS) pre-translate shift + external mouse wheel\n // into deltaX with deltaY=0; trackpads keep the raw deltaY. Use whichever is non-zero.\n handleHorizontalScroll(e.deltaY || e.deltaX)\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 // --- Pan mode (drag on empty canvas) ---\n if (panRef.current) {\n const dx = e.clientX - panRef.current.startX\n const dy = e.clientY - panRef.current.startY\n if (!didPanRef.current && (Math.abs(dx) >= PAN_THRESHOLD || Math.abs(dy) >= PAN_THRESHOLD)) {\n didPanRef.current = true\n el.style.cursor = 'grabbing'\n el.setPointerCapture(e.pointerId)\n }\n if (didPanRef.current) {\n const moveDeltaX = e.clientX - panRef.current.lastX\n const moveDeltaY = e.clientY - panRef.current.lastY\n panRef.current.lastX = e.clientX\n panRef.current.lastY = e.clientY\n if (Math.abs(moveDeltaX) > 0) handleHorizontalScroll(-moveDeltaX)\n if (Math.abs(moveDeltaY) > 0) handleVerticalScroll(-moveDeltaY)\n }\n return\n }\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, handleHorizontalScroll, handleVerticalScroll])\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\n if (!item) {\n // Start pan on empty canvas\n panRef.current = { startX: e.clientX, startY: e.clientY, lastX: e.clientX, lastY: e.clientY }\n didPanRef.current = false\n return\n }\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\n // --- End pan mode ---\n if (panRef.current) {\n const wasPanning = didPanRef.current\n panRef.current = null\n didPanRef.current = false\n el.style.cursor = 'default'\n if (wasPanning) return // suppress click after pan\n }\n\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 const childMoves = propsRef.current.hierarchyEngine.getMoveDelta(state.item.id, validatedTime)\n propsRef.current.onItemMove?.(state.item.id, validatedTime, result.newGroupId, childMoves.length > 0 ? childMoves : undefined)\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 let constrainedTime = snap !== null ? vs.xToTime(snap) : result.newTime\n // Apply hierarchy resize constraints\n const constraint = propsRef.current.hierarchyEngine.getResizeConstraint(state.item.id, result.edge)\n if (result.edge === 'left' && constrainedTime > constraint.max) {\n constrainedTime = constraint.max\n } else if (result.edge === 'right' && constrainedTime < constraint.min) {\n constrainedTime = constraint.min\n }\n\n const validatedTime = validator ? validator('resize', state.item.id, constrainedTime, result.edge) : constrainedTime\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 panRef.current = null\n didPanRef.current = false\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 printGroupHeights = p.groups.map((g) => p.layoutEngine.getGroupHeight(g.id))\n const printGroupOffsets: number[] = [0]\n for (let i = 0; i < printGroupHeights.length; i++) {\n printGroupOffsets.push(printGroupOffsets[i] + printGroupHeights[i])\n }\n const totalHeight = printGroupOffsets[printGroupHeights.length]\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 rowHeight = printGroupHeights[i]\n const y = headerHeight + printGroupOffsets[i]\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, rowHeight)\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 + rowHeight / 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 groupHeights: printGroupHeights,\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 p.summaryRenderer, p.hierarchyEngine,\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 printGroupHeights = p.groups.map((g) => p.layoutEngine.getGroupHeight(g.id))\n const printGroupOffsets: number[] = [0]\n for (let i = 0; i < printGroupHeights.length; i++) {\n printGroupOffsets.push(printGroupOffsets[i] + printGroupHeights[i])\n }\n const totalHeight = printGroupOffsets[printGroupHeights.length]\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 rowHeight = printGroupHeights[i]\n const y = headerHeight + printGroupOffsets[i]\n const rs = p.rowStyle?.(group)\n ctx.fillStyle = rs?.backgroundColor ?? (i % 2 === 0 ? '#FFFFFF' : '#F7F7F7')\n ctx.fillRect(0, y, printSidebarWidth, rowHeight)\n ctx.strokeStyle = '#E5E5E5'\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + rowHeight)\n ctx.lineTo(printSidebarWidth, y + rowHeight)\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 + rowHeight / 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 groupHeights: printGroupHeights,\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 p.summaryRenderer, p.hierarchyEngine)\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%', position: 'relative' }}>\n {(__LIB_DEV__ || devBadge) ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 9999,\n padding: '2px 6px',\n fontSize: 10,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n lineHeight: 1.4,\n color: '#fff',\n background: 'rgba(17, 24, 39, 0.78)',\n borderBottomRightRadius: 4,\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n v{__LIB_VERSION__} · {__LIB_BUILD__}\n </div>\n ) : null}\n {headerChildren}\n <div ref={containerRef} style={{ display: 'flex', overflow: 'hidden' }}>\n <Sidebar\n groups={groups}\n width={sidebarWidth}\n lineHeight={lineHeight}\n groupHeights={groupHeights}\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 groupHeights={groupHeights}\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","offsets","i","h","_a","time","x","y","target","lo","hi","mid","index","extend","firstVisible","lastVisible","scrollXOffset","bufferPixels","IntervalTree","items","getStart","getEnd","intervals","item","min","max","iv","center","leftIntervals","rightIntervals","overlapping","start","end","results","node","LayoutEngine","lineHeight","itemHeightRatio","stackItems","hierarchy","itemHeight","summaryHeight","isSummary","byGroup","arr","groupId","groupItems","a","b","d","levelEnds","maxLevel","level","leaves","parents","nextLevel","parent","itemId","HierarchyEngine","children","id","visited","current","parentId","siblings","idx","result","stack","descendants","descId","desc","cached","depth","newStart","delta","edge","minChildStart","childId","child","maxChildEnd","defaultSummaryRenderer","ctx","bounds","state","_helpers","theme","width","height","color","diamondSize","midY","title","textWidth","maxTextWidth","displayText","hitTest","canvasX","canvasY","view","tree","layout","groups","groupIndexMap","candidates","topItem","topY","groupIndex","itemLayout","hitTestGroup","detectEdge","threshold","leftX","rightX","setupCanvas","canvas","dpr","targetW","targetH","clearCanvas","RenderScheduler","drawCallback","layer","flags","GridLayer","dayStyle","rowStyle","highlights","rowHeight","group","bgColor","customRow","x1","x2","w","opacity","r","g","visibleStart","visibleEnd","dayPixelWidth","stepUnit","dayjs","batchColor","batchOpacity","batchStartX","customBorderLines","flushBatch","endX","date","custom","dow","line","padding","badgeWidth","badgeHeight","badgeX","badgeY","ITEM_FONT","createDrawHelpers","radius","text","maxWidth","candidate","color1","color2","grad","type","size","half","cx","cy","fillColor","stemW","stemX","paddingH","pillHeight","pillWidth","ItemsLayer","itemRenderer","groupRenderer","selected","hoveredItemId","dependencies","summaryRenderer","queryStart","queryEnd","visibleItems","selectedSet","itemBoundsMap","yMin","yMax","helpers","renderer","depItemIds","dep","itemMap","boundsMap","fromBounds","toBounds","isHighlighted","startX","startY","endY","dx","cpOffset","arrowSize","OverlayLayer","options","cursorX","snapX","markers","interaction","marker","maxBadgeWidth","MAX_DELTA","normalizeDelta","e","ZoomHandler","onZoom","visibleTimeStart","visibleTimeEnd","minZoom","maxZoom","cursorRatio","speed","scale","currentDuration","newDuration","newEnd","ACTIVATION_THRESHOLD","InteractionHandler","dragSnap","mode","pixelsPerMs","deltaMs","newStartTime","snapped","newGroupId","newTime","collectItemEdges","excludeItemId","timeToX","edges","findSnapTarget","currentX","edgeXPositions","thresholdPx","_pixelsPerMs","_dragSnap","closestX","closestDist","dist","t","module","this","s","n","o","u","OVERSCAN_PX","Sidebar","groupHeights","scrollTop","canvasHeight","onScroll","containerRef","useRef","isScrollingRef","useMemo","totalHeight","displayHeight","groupAtY","useCallback","handleScroll","useEffect","visibleGroups","top","_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","devBadge","getGroupIndex","grps","selectedKey","gridCanvasRef","itemsCanvasRef","overlayCanvasRef","interactionRef","outerRef","containerWidth","setContainerWidth","useState","container","obs","entries","entry","canvasWidth","hierarchyEngine","engine","intervalTree","layoutEngine","viewStateRef","cursorXRef","hoveredItemIdRef","panRef","didPanRef","PAN_THRESHOLD","headerTimeStart","setHeaderTimeStart","headerTimeEnd","setHeaderTimeEnd","sidebarScrollTop","setSidebarScrollTop","headerTimerRef","syncHeaderState","vs","scheduleHeaderSync","resolvedSummaryRenderer","gridLayer","itemsLayer","overlayLayer","interactionHandler","markerConfigs","configs","displayName","markersKey","m","markersRef","todayMarkerInterval","interval","propsRef","drawGrid","p","drawItems","calculateSnapX","deltaX","draggedEdgeXs","otherEdges","edgeX","edgeTime","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","dy","moveDeltaX","moveDeltaY","newHoveredId","cr","handlePointerDown","handlePointerUp","wasPanning","validator","draggedStartX","draggedEndX","snappedStartTime","startSnap","endSnap","duration","validatedTime","childMoves","snap","constrainedTime","constraint","_d","_f","_e","handleDoubleClick","handleContextMenu","handlePointerLeave","headerChildren","headers","childProps","initialDrawDone","useImperativeHandle","timeStart","timeEnd","printSidebarWidth","headerRowHeight","headerHeight","printGroupHeights","printGroupOffsets","currentPixelsPerMs","printDuration","timelineWidth","compositeWidth","compositeHeight","style","groupType","fontWeight","indent","drawHeaderRow","rowY","getLabel","unit","cursor","pxPerMs","nextCursor","printViewState","api","fullWidth","fullHeight","rs","gt","fw","fs","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":[15,21]}
|