@ganttloom/gantt-core 0.2.0 → 0.2.1
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.
- package/README.md +51 -0
- package/dist/index.cjs +52 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +52 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/critical-path.ts","../src/date-utils.ts","../src/calendar.ts","../src/layout.ts","../src/history.ts","../src/event-emitter.ts","../src/csv.ts","../src/renderer.ts","../src/auto-color.ts","../src/constraints.ts","../src/wbs.ts","../src/resource-histogram.ts","../src/filter.ts","../src/resource-leveling.ts","../src/interactions.ts"],"sourcesContent":["export * from \"./types\";\nexport { DEFAULT_THEME, mergeTheme, themeToCssVars } from \"./theme\";\nexport { computeLayout } from \"./layout\";\nexport { computeCriticalPath } from \"./critical-path\";\nexport { HistoryManager, type Command } from \"./history\";\nexport { EventEmitter } from \"./event-emitter\";\nexport { tasksToCSV, tasksFromCSV } from \"./csv\";\nexport * as dateUtils from \"./date-utils\";\nexport { isSafeHref } from \"./renderer\";\nexport {\n isWorkingDay,\n isHoliday,\n isWithinWorkingHours,\n isWorkingTime,\n nextWorkingDay,\n previousWorkingDay,\n shiftToWorkingDay,\n shiftToWorkingTime,\n} from \"./calendar\";\nexport { colorByField, applyColorByField, DEFAULT_PALETTE } from \"./auto-color\";\nexport { DENSITY_PRESETS, type Density } from \"./theme\";\nexport { applyConstraint } from \"./constraints\";\nexport { computeWBSCodes } from \"./wbs\";\nexport {\n computeResourceHistogram,\n renderResourceHistogramSVG,\n type ResourceHistogramOptions,\n type ResourceLoadBucket,\n} from \"./resource-histogram\";\nexport { filterTasks, type FilterTasksOptions, type FilterTasksResult } from \"./filter\";\nexport {\n levelResources,\n type ResourceLevelingOptions,\n type ResourceLevelingResult,\n} from \"./resource-leveling\";\n\nimport { shiftToWorkingDay, shiftToWorkingTime } from \"./calendar\";\nimport { applyConstraint } from \"./constraints\";\nimport { approxUnitMs, isValidDate, pxPerMs, snapToGrid, MS_PER_DAY } from \"./date-utils\";\nimport { HistoryManager, type Command } from \"./history\";\nimport { EventEmitter } from \"./event-emitter\";\nimport { computeLayout } from \"./layout\";\nimport { computeResourceHistogram, type ResourceHistogramOptions } from \"./resource-histogram\";\nimport { levelResources, type ResourceLevelingOptions } from \"./resource-leveling\";\nimport { GanttRenderer } from \"./renderer\";\nimport { InteractionController } from \"./interactions\";\nimport { mergeTheme } from \"./theme\";\nimport type {\n GanttColumn,\n GanttDependency,\n GanttEventMap,\n GanttOptions,\n GanttRenderModel,\n GanttTask,\n GanttTheme,\n ViewMode,\n} from \"./types\";\n\nconst HAS_DOM = typeof document !== \"undefined\" && typeof window !== \"undefined\";\n\nconst DEFAULT_COLUMNS: GanttColumn[] = [{ id: \"name\", title: \"Name\" }];\n\nfunction cloneTask(task: GanttTask): GanttTask {\n return { ...task };\n}\n\nexport class GanttChart {\n private tasks: GanttTask[];\n private dependencies: GanttDependency[];\n private options: Required<\n Pick<\n GanttOptions,\n | \"viewMode\"\n | \"readonly\"\n | \"showProgress\"\n | \"showDependencies\"\n | \"gridPanelWidth\"\n | \"showCriticalPath\"\n | \"showBaseline\"\n | \"showDeadlines\"\n | \"showAssigneeAvatars\"\n | \"enableHistory\"\n | \"keyboardAccessible\"\n | \"virtualScroll\"\n | \"autoSchedule\"\n | \"autoRollupProgress\"\n | \"selectable\"\n >\n > & {\n columnWidth?: number;\n theme?: Partial<GanttTheme>;\n columns?: GanttColumn[];\n calendar?: GanttOptions[\"calendar\"];\n markers?: GanttOptions[\"markers\"];\n pagination?: { pageSize: number; page: number };\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n onDateChange?: GanttOptions[\"onDateChange\"];\n onProgressChange?: GanttOptions[\"onProgressChange\"];\n onDependencyCreate?: GanttOptions[\"onDependencyCreate\"];\n onDependencyRemove?: GanttOptions[\"onDependencyRemove\"];\n onDependencyDblClick?: GanttOptions[\"onDependencyDblClick\"];\n onTaskClick?: GanttOptions[\"onTaskClick\"];\n onGroupToggle?: GanttOptions[\"onGroupToggle\"];\n onContextMenu?: GanttOptions[\"onContextMenu\"];\n onTaskCreate?: GanttOptions[\"onTaskCreate\"];\n onColumnResize?: GanttOptions[\"onColumnResize\"];\n onColumnReorder?: GanttOptions[\"onColumnReorder\"];\n onTaskReorder?: GanttOptions[\"onTaskReorder\"];\n onSelectionChange?: GanttOptions[\"onSelectionChange\"];\n };\n private theme: GanttTheme;\n private colorScheme: \"light\" | \"dark\" | \"auto\";\n private darkMediaQuery: MediaQueryList | null = null;\n private handleSchemeChange = (): void => {\n if (this.colorScheme !== \"auto\") return;\n this.theme = mergeTheme(this.explicitTheme, \"auto\");\n this.scheduleRender();\n };\n private explicitTheme?: Partial<GanttTheme>;\n private columns: GanttColumn[];\n private columnWidth: number;\n private emitter = new EventEmitter<GanttEventMap>();\n private history: HistoryManager | null = null;\n private renderer: GanttRenderer | null = null;\n private interactions: InteractionController | null = null;\n private renderModel: GanttRenderModel | null = null;\n private rafHandle: number | null = null;\n private currentPage = 1;\n private selectedTaskIds = new Set<string>();\n private lastSelectedId: string | null = null;\n\n constructor(\n private container: HTMLElement,\n tasks: GanttTask[],\n dependencies: GanttDependency[] = [],\n options: GanttOptions = {}\n ) {\n this.tasks = tasks.map(cloneTask);\n this.dependencies = dependencies.map((d) => ({ ...d }));\n this.colorScheme = options.colorScheme ?? \"auto\";\n this.explicitTheme = options.theme;\n this.theme = mergeTheme(options.theme, this.colorScheme);\n this.columns = options.columns ?? DEFAULT_COLUMNS;\n this.columnWidth = options.columnWidth ?? 32;\n this.currentPage = options.pagination?.page ?? 1;\n\n this.options = {\n viewMode: options.viewMode ?? \"day\",\n readonly: options.readonly ?? false,\n showProgress: options.showProgress ?? true,\n showDependencies: options.showDependencies ?? true,\n gridPanelWidth: options.gridPanelWidth ?? 260,\n showCriticalPath: options.showCriticalPath ?? false,\n showBaseline: options.showBaseline ?? false,\n showDeadlines: options.showDeadlines ?? true,\n showAssigneeAvatars: options.showAssigneeAvatars ?? false,\n enableHistory: options.enableHistory ?? false,\n keyboardAccessible: options.keyboardAccessible ?? false,\n virtualScroll: options.virtualScroll ?? true,\n autoSchedule: options.autoSchedule ?? false,\n autoRollupProgress: options.autoRollupProgress ?? false,\n selectable: options.selectable ?? false,\n columnWidth: options.columnWidth,\n theme: options.theme,\n columns: options.columns,\n calendar: options.calendar,\n markers: options.markers,\n pagination: options.pagination,\n snapToUnit: options.snapToUnit,\n onDateChange: options.onDateChange,\n onProgressChange: options.onProgressChange,\n onDependencyCreate: options.onDependencyCreate,\n onDependencyRemove: options.onDependencyRemove,\n onDependencyDblClick: options.onDependencyDblClick,\n onTaskClick: options.onTaskClick,\n onGroupToggle: options.onGroupToggle,\n onContextMenu: options.onContextMenu,\n onTaskCreate: options.onTaskCreate,\n onColumnResize: options.onColumnResize,\n onColumnReorder: options.onColumnReorder,\n onTaskReorder: options.onTaskReorder,\n onSelectionChange: options.onSelectionChange,\n };\n\n if (this.options.enableHistory) {\n this.history = new HistoryManager((state) => this.emitter.emit(\"history-change\", state));\n }\n\n if (HAS_DOM) {\n this.setupDom();\n }\n\n this.scheduleRender(true);\n }\n\n private setupDom(): void {\n this.container.style.setProperty(\"--gantt-grid-panel-width\", `${this.options.gridPanelWidth}px`);\n if (typeof window.matchMedia === \"function\") {\n this.darkMediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n this.darkMediaQuery.addEventListener?.(\"change\", this.handleSchemeChange);\n }\n this.renderer = new GanttRenderer(this.container, {\n keyboardAccessible: this.options.keyboardAccessible,\n showAssigneeAvatars: this.options.showAssigneeAvatars,\n virtualScroll: this.options.virtualScroll,\n onRenameCommit: (taskId, name) => this.updateTask(taskId, { name }),\n onColumnResize: this.options.onColumnResize\n ? (columnId, width) => this.handleColumnResize(columnId, width)\n : undefined,\n onColumnReorder: this.options.onColumnReorder\n ? (order) => this.handleColumnReorder(order)\n : undefined,\n onRowReorder: this.options.onTaskReorder\n ? (draggedId, targetId, position) => this.handleRowReorder(draggedId, targetId, position)\n : undefined,\n });\n\n this.interactions = new InteractionController(\n this.renderer.svg,\n this.renderer.gridPanel,\n {\n onMove: (taskId, dxMs) => this.handleMove(taskId, dxMs),\n onResize: (taskId, edge, dxMs) => this.handleResize(taskId, edge, dxMs),\n onLinkStart: () => {},\n onLinkComplete: (fromId, toId) => this.handleLinkComplete(fromId, toId),\n onLinkCancel: () => {},\n onToggleCollapse: (taskId) => this.toggleGroup(taskId),\n onBarClick: (taskId, modifiers) => this.handleBarClick(taskId, modifiers),\n onProgressDrag: (taskId, newProgress) => this.handleProgressDrag(taskId, newProgress),\n // Only wired when the consumer opted in via onTaskCreate - like onContextMenu below,\n // this keeps drag-to-create off by default instead of silently mutating task state.\n onCreateTaskDrag: this.options.onTaskCreate\n ? (rowTaskId, startXPx, endXPx) => this.handleCreateTaskDrag(rowTaskId, startXPx, endXPx)\n : undefined,\n onLinkDblClick: this.options.onDependencyDblClick\n ? (fromId, toId) => {\n const dep = this.dependencies.find((d) => d.fromId === fromId && d.toId === toId);\n if (dep) this.options.onDependencyDblClick?.(dep);\n }\n : undefined,\n onContextMenu: this.options.onContextMenu\n ? (taskId, evt) => {\n const task = this.tasks.find((t) => t.id === taskId);\n if (task) this.emitter.emit(\"context-menu\", { task, evt });\n this.options.onContextMenu?.(task ?? ({ id: taskId } as GanttTask), evt);\n }\n : undefined,\n onSelectAll: this.options.selectable ? () => this.selectAllVisible() : undefined,\n onJumpToStart: () => this.scrollToRangeStart(),\n onJumpToEnd: () => this.scrollToRangeEnd(),\n },\n {\n readonly: this.options.readonly,\n isTaskReadonly: (taskId) => !!this.tasks.find((t) => t.id === taskId)?.readonly,\n keyboardAccessible: this.options.keyboardAccessible,\n snapToUnit: this.options.snapToUnit,\n pxPerMs: () => pxPerMs(this.options.viewMode, this.columnWidth),\n }\n );\n }\n\n private handleMove(taskId: string, dxMs: number): void {\n if (dxMs === 0) return;\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task || task.readonly || this.options.readonly) return;\n const newStart = new Date(task.start.getTime() + dxMs);\n const newEnd = new Date(task.end.getTime() + dxMs);\n const newSegments = task.segments?.map((s) => ({\n start: new Date(s.start.getTime() + dxMs),\n end: new Date(s.end.getTime() + dxMs),\n }));\n this.applyDateChange(taskId, newStart, newEnd, newSegments);\n }\n\n private handleResize(taskId: string, edge: \"left\" | \"right\", dxMs: number): void {\n if (dxMs === 0) return;\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task || task.readonly || this.options.readonly) return;\n const newStart = edge === \"left\" ? new Date(task.start.getTime() + dxMs) : task.start;\n const newEnd = edge === \"right\" ? new Date(task.end.getTime() + dxMs) : task.end;\n if (newEnd.getTime() <= newStart.getTime()) return;\n let newSegments = task.segments?.map((s) => ({ ...s }));\n if (newSegments && newSegments.length > 0) {\n if (edge === \"left\") newSegments[0] = { ...newSegments[0]!, start: newStart };\n else newSegments[newSegments.length - 1] = { ...newSegments[newSegments.length - 1]!, end: newEnd };\n }\n this.applyDateChange(taskId, newStart, newEnd, newSegments);\n }\n\n private applyDateChange(\n taskId: string,\n newStart: Date,\n newEnd: Date,\n newSegments?: { start: Date; end: Date }[]\n ): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task) return;\n const before: { id: string; start: Date; end: Date; segments?: { start: Date; end: Date }[] }[] = [\n { id: taskId, start: task.start, end: task.end, segments: task.segments },\n ];\n const after: { id: string; start: Date; end: Date; segments?: { start: Date; end: Date }[] }[] = [\n { id: taskId, start: newStart, end: newEnd, segments: newSegments },\n ];\n\n if (this.options.autoSchedule) {\n const cascade = this.computeCascade(taskId, newStart, newEnd);\n for (const c of cascade) {\n before.push({ id: c.id, start: c.oldStart, end: c.oldEnd });\n after.push({ id: c.id, start: c.newStart, end: c.newEnd });\n }\n }\n\n const applyState = (state: typeof before) => {\n for (const s of state) {\n const t = this.tasks.find((tt) => tt.id === s.id);\n if (t) {\n t.start = s.start;\n t.end = s.end;\n if (s.segments !== undefined) t.segments = s.segments;\n }\n }\n };\n\n const cmd: Command = {\n label: \"move-or-resize\",\n do: () => {\n applyState(after);\n this.emitDateChangeEvents(after.map((a) => a.id));\n },\n undo: () => {\n applyState(before);\n this.emitDateChangeEvents(before.map((b) => b.id));\n },\n };\n this.runCommand(cmd);\n }\n\n private emitDateChangeEvents(ids: string[]): void {\n for (const id of ids) {\n const t = this.tasks.find((tt) => tt.id === id);\n if (!t) continue;\n this.emitter.emit(\"date-change\", { task: t, start: t.start, end: t.end });\n this.options.onDateChange?.(t, t.start, t.end);\n }\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n /** Shift successors that would violate their dependency constraint after `taskId` moves to [newStart, newEnd]. */\n private computeCascade(\n taskId: string,\n newStart: Date,\n newEnd: Date\n ): { id: string; oldStart: Date; oldEnd: Date; newStart: Date; newEnd: Date }[] {\n const results: { id: string; oldStart: Date; oldEnd: Date; newStart: Date; newEnd: Date }[] = [];\n const simulated = new Map<string, { start: Date; end: Date }>();\n simulated.set(taskId, { start: newStart, end: newEnd });\n\n const outgoing = new Map<string, GanttDependency[]>();\n for (const dep of this.dependencies) {\n const list = outgoing.get(dep.fromId) ?? [];\n list.push(dep);\n outgoing.set(dep.fromId, list);\n }\n\n const queue = [taskId];\n const visited = new Set<string>();\n let ops = 0;\n const maxOps = this.tasks.length * 2 + 5;\n\n while (queue.length > 0 && ops++ < maxOps) {\n const currentId = queue.shift();\n if (currentId === undefined) break;\n const currentState = simulated.get(currentId);\n if (!currentState) continue;\n\n for (const dep of outgoing.get(currentId) ?? []) {\n if (visited.has(dep.toId) && !simulated.has(dep.toId)) continue;\n const succTask = this.tasks.find((t) => t.id === dep.toId);\n if (!succTask) continue;\n const succState = simulated.get(dep.toId) ?? { start: succTask.start, end: succTask.end };\n const lag = dep.lagMs ?? 0;\n const duration = succState.end.getTime() - succState.start.getTime();\n\n let requiredStart: number | null = null;\n let requiredEnd: number | null = null;\n if (dep.type === \"FS\") requiredStart = currentState.end.getTime() + lag;\n else if (dep.type === \"SS\") requiredStart = currentState.start.getTime() + lag;\n else if (dep.type === \"FF\") requiredEnd = currentState.end.getTime() + lag;\n else if (dep.type === \"SF\") requiredEnd = currentState.start.getTime() + lag;\n\n let newSuccStart = succState.start.getTime();\n let newSuccEnd = succState.end.getTime();\n let violated = false;\n if (requiredStart !== null && succState.start.getTime() < requiredStart) {\n newSuccStart = requiredStart;\n newSuccEnd = requiredStart + duration;\n violated = true;\n } else if (requiredEnd !== null && succState.end.getTime() < requiredEnd) {\n newSuccEnd = requiredEnd;\n newSuccStart = requiredEnd - duration;\n violated = true;\n }\n\n if (violated && !visited.has(dep.toId)) {\n visited.add(dep.toId);\n let newState = { start: new Date(newSuccStart), end: new Date(newSuccEnd) };\n newState = applyConstraint(newState, succTask.constraintType, succTask.constraintDate);\n if (this.options.calendar) {\n const shiftedStart = this.options.calendar.workingHours\n ? shiftToWorkingTime(newState.start, this.options.calendar, 1)\n : shiftToWorkingDay(newState.start, this.options.calendar, 1);\n if (shiftedStart.getTime() !== newState.start.getTime()) {\n const dur = newState.end.getTime() - newState.start.getTime();\n newState = { start: shiftedStart, end: new Date(shiftedStart.getTime() + dur) };\n }\n }\n simulated.set(dep.toId, newState);\n results.push({\n id: dep.toId,\n oldStart: succTask.start,\n oldEnd: succTask.end,\n newStart: newState.start,\n newEnd: newState.end,\n });\n queue.push(dep.toId);\n }\n }\n }\n\n return results;\n }\n\n private handleLinkComplete(fromId: string, toId: string): void {\n const dep: GanttDependency = { fromId, toId, type: \"FS\" };\n const cmd: Command = {\n label: \"link-create\",\n do: () => {\n this.dependencies.push(dep);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n undo: () => {\n this.dependencies = this.dependencies.filter((d) => d !== dep);\n this.emitter.emit(\"dependency-remove\", dep);\n this.options.onDependencyRemove?.(dep);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n removeDependency(fromId: string, toId: string): void {\n const dep = this.dependencies.find((d) => d.fromId === fromId && d.toId === toId);\n if (!dep) return;\n const cmd: Command = {\n label: \"link-remove\",\n do: () => {\n this.dependencies = this.dependencies.filter((d) => d !== dep);\n this.emitter.emit(\"dependency-remove\", dep);\n this.options.onDependencyRemove?.(dep);\n this.scheduleRender();\n },\n undo: () => {\n this.dependencies.push(dep);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n /** Update a dependency's type/lag in place (e.g. from your own \"edit this link\" UI opened via onDependencyDblClick). Undoable. */\n updateDependency(fromId: string, toId: string, partial: Partial<GanttDependency>): void {\n const dep = this.dependencies.find((d) => d.fromId === fromId && d.toId === toId);\n if (!dep) return;\n const before = { ...dep };\n const after = { ...dep, ...partial, fromId: dep.fromId, toId: dep.toId };\n const cmd: Command = {\n label: \"link-update\",\n do: () => {\n Object.assign(dep, after);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n undo: () => {\n Object.assign(dep, before);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private handleProgressDrag(taskId: string, newProgress: number): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task || task.readonly || this.options.readonly) return;\n const oldProgress = task.progress ?? 0;\n const clamped = Math.min(100, Math.max(0, newProgress));\n const cmd: Command = {\n label: \"progress-change\",\n do: () => {\n task.progress = clamped;\n this.emitter.emit(\"progress-change\", { task, progress: clamped });\n this.options.onProgressChange?.(task, clamped);\n this.scheduleRender();\n },\n undo: () => {\n task.progress = oldProgress;\n this.emitter.emit(\"progress-change\", { task, progress: oldProgress });\n this.options.onProgressChange?.(task, oldProgress);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private handleCreateTaskDrag(rowTaskId: string, startXPx: number, endXPx: number): void {\n if (!this.renderModel) return;\n const scale = pxPerMs(this.options.viewMode, this.columnWidth);\n if (scale <= 0) return;\n const rangeStartMs = this.renderModel.rangeStart.getTime();\n let start = new Date(rangeStartMs + startXPx / scale);\n let end = new Date(rangeStartMs + endXPx / scale);\n if (this.options.snapToUnit) {\n start = snapToGrid(start, this.options.snapToUnit as ViewMode);\n end = snapToGrid(end, this.options.snapToUnit as ViewMode);\n }\n if (end.getTime() <= start.getTime()) end = new Date(start.getTime() + MS_PER_DAY);\n\n const rowTask = this.tasks.find((t) => t.id === rowTaskId);\n const newTask: GanttTask = {\n id: `task-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\n name: \"New task\",\n start,\n end,\n parentId: rowTask?.parentId ?? null,\n };\n\n const cmd: Command = {\n label: \"task-create\",\n do: () => {\n const index = this.tasks.findIndex((t) => t.id === rowTaskId);\n if (index >= 0) this.tasks.splice(index + 1, 0, newTask);\n else this.tasks.push(newTask);\n this.emitter.emit(\"task-create\", { task: newTask });\n this.options.onTaskCreate?.(newTask);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n undo: () => {\n this.tasks = this.tasks.filter((t) => t.id !== newTask.id);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private handleBarClick(\n taskId: string,\n modifiers?: { ctrlKey: boolean; metaKey: boolean; shiftKey: boolean }\n ): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task) return;\n\n if (this.options.selectable) {\n if (modifiers?.shiftKey && this.lastSelectedId && this.renderModel) {\n const ids = this.renderModel.rows.map((r) => r.taskId);\n const i1 = ids.indexOf(this.lastSelectedId);\n const i2 = ids.indexOf(taskId);\n if (i1 >= 0 && i2 >= 0) {\n const [lo, hi] = i1 < i2 ? [i1, i2] : [i2, i1];\n this.selectedTaskIds = new Set(ids.slice(lo, hi + 1));\n }\n } else if (modifiers?.ctrlKey || modifiers?.metaKey) {\n if (this.selectedTaskIds.has(taskId)) this.selectedTaskIds.delete(taskId);\n else this.selectedTaskIds.add(taskId);\n this.lastSelectedId = taskId;\n } else {\n this.selectedTaskIds = new Set([taskId]);\n this.lastSelectedId = taskId;\n }\n this.emitter.emit(\"selection-change\", { taskIds: this.getSelectedTaskIds() });\n this.options.onSelectionChange?.(this.getSelectedTaskIds());\n this.scheduleRender();\n }\n\n this.emitter.emit(\"task-click\", { task });\n this.options.onTaskClick?.(task);\n }\n\n /** Replace (default) or add to (`additive: true`) the current selection. Requires `selectable`. */\n selectTask(id: string, options: { additive?: boolean } = {}): void {\n if (!options.additive) this.selectedTaskIds.clear();\n this.selectedTaskIds.add(id);\n this.lastSelectedId = id;\n this.emitter.emit(\"selection-change\", { taskIds: this.getSelectedTaskIds() });\n this.options.onSelectionChange?.(this.getSelectedTaskIds());\n this.scheduleRender();\n }\n\n clearSelection(): void {\n this.selectedTaskIds.clear();\n this.lastSelectedId = null;\n this.emitter.emit(\"selection-change\", { taskIds: [] });\n this.options.onSelectionChange?.([]);\n this.scheduleRender();\n }\n\n getSelectedTaskIds(): string[] {\n return Array.from(this.selectedTaskIds);\n }\n\n /** Shift every selected task's start/end by `deltaMs`. Single undoable step. */\n bulkShiftDates(deltaMs: number): void {\n if (deltaMs === 0 || this.selectedTaskIds.size === 0) return;\n const ids = Array.from(this.selectedTaskIds);\n const before = ids\n .map((id) => this.tasks.find((t) => t.id === id))\n .filter((t): t is GanttTask => !!t)\n .map((t) => ({ id: t.id, start: t.start, end: t.end }));\n const after = before.map((b) => ({\n id: b.id,\n start: new Date(b.start.getTime() + deltaMs),\n end: new Date(b.end.getTime() + deltaMs),\n }));\n const applyState = (state: typeof before) => {\n for (const s of state) {\n const t = this.tasks.find((tt) => tt.id === s.id);\n if (t) {\n t.start = s.start;\n t.end = s.end;\n }\n }\n };\n const cmd: Command = {\n label: \"bulk-shift\",\n do: () => {\n applyState(after);\n this.emitDateChangeEvents(after.map((a) => a.id));\n },\n undo: () => {\n applyState(before);\n this.emitDateChangeEvents(before.map((b) => b.id));\n },\n };\n this.runCommand(cmd);\n }\n\n /** Delete every selected task (and any dependency touching one). Single undoable step. */\n bulkDelete(): void {\n if (this.selectedTaskIds.size === 0) return;\n const ids = Array.from(this.selectedTaskIds);\n const idSet = new Set(ids);\n const removedTasks = this.tasks.filter((t) => idSet.has(t.id));\n const removedIndices = removedTasks.map((t) => this.tasks.indexOf(t));\n const removedDeps = this.dependencies.filter((d) => idSet.has(d.fromId) || idSet.has(d.toId));\n\n const cmd: Command = {\n label: \"bulk-delete\",\n do: () => {\n this.tasks = this.tasks.filter((t) => !idSet.has(t.id));\n this.dependencies = this.dependencies.filter((d) => !idSet.has(d.fromId) && !idSet.has(d.toId));\n this.selectedTaskIds.clear();\n this.emitter.emit(\"selection-change\", { taskIds: [] });\n this.options.onSelectionChange?.([]);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n undo: () => {\n const combined = [...this.tasks];\n removedTasks.forEach((t, i) => {\n const at = Math.min(removedIndices[i] ?? combined.length, combined.length);\n combined.splice(at, 0, t);\n });\n this.tasks = combined;\n this.dependencies.push(...removedDeps);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private runCommand(cmd: Command): void {\n if (this.history) {\n this.history.push(cmd);\n } else {\n cmd.do();\n }\n }\n\n private handleColumnResize(columnId: string, width: number): void {\n const col = this.columns.find((c) => c.id === columnId);\n if (!col) return;\n col.width = width;\n this.emitter.emit(\"column-resize\", { columnId, width });\n this.options.onColumnResize?.(columnId, width);\n this.scheduleRender();\n }\n\n private handleColumnReorder(order: string[]): void {\n const byId = new Map(this.columns.map((c) => [c.id, c]));\n const reordered = order.map((id) => byId.get(id)).filter((c): c is GanttColumn => !!c);\n if (reordered.length !== this.columns.length) return;\n this.columns = reordered;\n this.emitter.emit(\"column-reorder\", { order });\n this.options.onColumnReorder?.(order);\n this.scheduleRender();\n }\n\n private handleRowReorder(\n draggedId: string,\n targetId: string,\n position: \"before\" | \"after\" | \"inside\"\n ): void {\n const draggedIndex = this.tasks.findIndex((t) => t.id === draggedId);\n const targetIndex = this.tasks.findIndex((t) => t.id === targetId);\n if (draggedIndex < 0 || targetIndex < 0) return;\n const dragged = this.tasks[draggedIndex];\n const target = this.tasks[targetIndex];\n if (!dragged || !target) return;\n\n // Refuse to make a task its own descendant's child.\n let cursor: GanttTask | undefined = target;\n while (cursor) {\n if (cursor.id === draggedId) return;\n cursor = cursor.parentId ? this.tasks.find((t) => t.id === cursor!.parentId) : undefined;\n }\n\n this.tasks.splice(draggedIndex, 1);\n const newTargetIndex = this.tasks.findIndex((t) => t.id === targetId);\n if (position === \"inside\") {\n dragged.parentId = target.id;\n this.tasks.splice(newTargetIndex + 1, 0, dragged);\n } else {\n dragged.parentId = target.parentId ?? null;\n this.tasks.splice(position === \"before\" ? newTargetIndex : newTargetIndex + 1, 0, dragged);\n }\n\n this.emitter.emit(\"task-reorder\", { draggedTaskId: draggedId, targetTaskId: targetId, position });\n this.options.onTaskReorder?.(draggedId, targetId, position);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n toggleGroup(taskId: string): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task) return;\n task.collapsed = !task.collapsed;\n this.emitter.emit(\"group-toggle\", { task, collapsed: !!task.collapsed });\n this.options.onGroupToggle?.(task, !!task.collapsed);\n this.scheduleRender();\n }\n\n expandAll(): void {\n for (const t of this.tasks) t.collapsed = false;\n this.scheduleRender();\n }\n\n collapseAll(): void {\n for (const t of this.tasks) if (t.isGroup) t.collapsed = true;\n this.scheduleRender();\n }\n\n setTasks(tasks: GanttTask[]): void {\n this.tasks = tasks.map(cloneTask);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n getTasks(): GanttTask[] {\n return this.tasks.map(cloneTask);\n }\n\n setDependencies(deps: GanttDependency[]): void {\n this.dependencies = deps.map((d) => ({ ...d }));\n this.scheduleRender();\n }\n\n updateTask(id: string, partial: Partial<GanttTask>): void {\n const task = this.tasks.find((t) => t.id === id);\n if (!task) return;\n Object.assign(task, partial);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n setViewMode(mode: ViewMode): void {\n this.options.viewMode = mode;\n this.scheduleRender();\n }\n\n setOptions(partial: Partial<GanttOptions>): void {\n if (partial.colorScheme !== undefined) this.colorScheme = partial.colorScheme;\n if (partial.theme !== undefined) this.explicitTheme = partial.theme;\n if (partial.theme !== undefined || partial.colorScheme !== undefined) {\n this.theme = mergeTheme(this.explicitTheme, this.colorScheme);\n }\n if (partial.columns) this.columns = partial.columns;\n if (partial.columnWidth !== undefined) this.columnWidth = partial.columnWidth;\n Object.assign(this.options, partial);\n this.scheduleRender();\n }\n\n /** Scroll the timeline so \"today\" is centered in the viewport. No-op without a DOM / today column visible. */\n scrollToToday(): void {\n if (!HAS_DOM || !this.renderer || !this.renderModel) return;\n const todayTick = this.renderModel.ticks.find((t) => t.isToday);\n if (!todayTick) return;\n const scrollEl = this.renderer.timelineScroll;\n const viewportWidth = scrollEl.clientWidth || 0;\n scrollEl.scrollLeft = Math.max(0, todayTick.x - viewportWidth / 2);\n }\n\n /** Scroll the timeline to the very start of the project's date range. Also the Home-key shortcut when keyboardAccessible. */\n scrollToRangeStart(): void {\n if (!HAS_DOM || !this.renderer) return;\n this.renderer.timelineScroll.scrollLeft = 0;\n }\n\n /** Scroll the timeline to the very end of the project's date range. Also the End-key shortcut when keyboardAccessible. */\n scrollToRangeEnd(): void {\n if (!HAS_DOM || !this.renderer || !this.renderModel) return;\n this.renderer.timelineScroll.scrollLeft = this.renderModel.width;\n }\n\n /** Select every currently visible task. Also the Ctrl/Cmd+A shortcut when both `selectable` and `keyboardAccessible` are on. */\n selectAllVisible(): void {\n if (!this.options.selectable || !this.renderModel) return;\n this.selectedTaskIds = new Set(this.renderModel.rows.map((r) => r.taskId));\n this.emitter.emit(\"selection-change\", { taskIds: this.getSelectedTaskIds() });\n this.options.onSelectionChange?.(this.getSelectedTaskIds());\n this.scheduleRender();\n }\n\n fitToViewport(containerWidthPx: number): void {\n let min: number | null = null;\n let max: number | null = null;\n for (const t of this.tasks) {\n if (!isValidDate(t.start) || !isValidDate(t.end)) continue;\n min = min === null ? t.start.getTime() : Math.min(min, t.start.getTime());\n max = max === null ? t.end.getTime() : Math.max(max, t.end.getTime());\n }\n if (min === null || max === null || max <= min) return;\n const rangeMs = max - min;\n const unitMs = approxUnitMs(this.options.viewMode);\n const newColumnWidth = Math.max(4, (containerWidthPx * unitMs) / rangeMs);\n this.columnWidth = newColumnWidth;\n this.scheduleRender();\n }\n\n private static readonly MIN_COLUMN_WIDTH = 4;\n private static readonly MAX_COLUMN_WIDTH = 400;\n\n /** Zoom in by `factor` (default 1.25x), clamped to a sane minimum column width. */\n zoomIn(factor = 1.25): void {\n this.columnWidth = Math.min(GanttChart.MAX_COLUMN_WIDTH, this.columnWidth * factor);\n this.scheduleRender();\n }\n\n /** Zoom out by `factor` (default 1.25x), clamped to a sane maximum column width. */\n zoomOut(factor = 1.25): void {\n this.columnWidth = Math.max(GanttChart.MIN_COLUMN_WIDTH, this.columnWidth / factor);\n this.scheduleRender();\n }\n\n /** Current zoom level, expressed as px per grid-unit column (same unit as the `columnWidth` option). */\n getZoomLevel(): number {\n return this.columnWidth;\n }\n\n /** Per-assignee daily workload, computed from the current tasks. See computeResourceHistogram. */\n getResourceHistogram(options: ResourceHistogramOptions = {}) {\n return computeResourceHistogram(this.tasks, { calendar: this.options.calendar, ...options });\n }\n\n /** Resolve resource overallocation by delaying tasks. Doesn't mutate state - call setTasks(result.tasks) to apply it. See levelResources. */\n getLeveledTasks(options: ResourceLevelingOptions = {}) {\n return levelResources(this.tasks, this.dependencies, { calendar: this.options.calendar, ...options });\n }\n\n getPageCount(): number {\n const pageSize = this.options.pagination?.pageSize;\n if (!pageSize || pageSize <= 0) return 1;\n const rootCount = this.tasks.filter((t) => !t.parentId).length;\n return Math.max(1, Math.ceil(rootCount / pageSize));\n }\n\n setPage(page: number): void {\n const pageCount = this.getPageCount();\n const clamped = Math.min(Math.max(1, page), pageCount);\n this.currentPage = clamped;\n if (this.options.pagination) this.options.pagination.page = clamped;\n this.emitter.emit(\"page-change\", { page: clamped, pageCount });\n this.scheduleRender();\n }\n\n getRenderModel(): GanttRenderModel {\n if (!this.renderModel) this.renderModel = this.computeModel();\n return this.renderModel;\n }\n\n private computeModel(): GanttRenderModel {\n const pagination = this.options.pagination\n ? { pageSize: this.options.pagination.pageSize, page: this.currentPage }\n : undefined;\n return computeLayout({\n tasks: this.tasks,\n dependencies: this.dependencies,\n viewMode: this.options.viewMode,\n columnWidth: this.columnWidth,\n theme: this.theme,\n columns: this.columns,\n showCriticalPath: this.options.showCriticalPath,\n showBaseline: this.options.showBaseline,\n showDeadlines: this.options.showDeadlines,\n showAssigneeAvatars: this.options.showAssigneeAvatars,\n calendar: this.options.calendar,\n markers: this.options.markers,\n autoRollupProgress: this.options.autoRollupProgress,\n selectedTaskIds: this.options.selectable ? this.selectedTaskIds : undefined,\n pagination,\n });\n }\n\n private scheduleRender(immediate = false): void {\n if (immediate || !HAS_DOM) {\n this.doRender();\n return;\n }\n if (this.rafHandle !== null) return;\n this.rafHandle = requestAnimationFrame(() => {\n this.rafHandle = null;\n this.doRender();\n });\n }\n\n private doRender(): void {\n this.renderModel = this.computeModel();\n this.renderer?.render(this.renderModel, this.tasks, this.columns, this.explicitTheme);\n if (this.renderer && this.colorScheme !== \"auto\") {\n this.renderer.root.setAttribute(\"data-gantt-theme\", this.colorScheme);\n } else {\n this.renderer?.root.removeAttribute(\"data-gantt-theme\");\n }\n }\n\n undo(): void {\n this.history?.undo();\n }\n\n redo(): void {\n this.history?.redo();\n }\n\n get canUndo(): boolean {\n return this.history?.canUndo ?? false;\n }\n\n get canRedo(): boolean {\n return this.history?.canRedo ?? false;\n }\n\n on<K extends keyof GanttEventMap>(event: K, listener: (payload: GanttEventMap[K]) => void): void {\n this.emitter.on(event, listener);\n }\n\n off<K extends keyof GanttEventMap>(event: K, listener: (payload: GanttEventMap[K]) => void): void {\n this.emitter.off(event, listener);\n }\n\n toSVGString(): string {\n return this.renderer?.toSVGString() ?? \"\";\n }\n\n private async rasterizeSVG(svgString: string, width: number, height: number): Promise<string> {\n const svgBlob = new Blob([svgString], { type: \"image/svg+xml;charset=utf-8\" });\n const url = URL.createObjectURL(svgBlob);\n try {\n return await new Promise<string>((resolve, reject) => {\n const image = new Image();\n image.onload = () => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = image.width || width || 800;\n canvas.height = image.height || height || 600;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"2D canvas context unavailable\"));\n return;\n }\n ctx.drawImage(image, 0, 0);\n resolve(canvas.toDataURL(\"image/png\"));\n };\n image.onerror = () => reject(new Error(\"Failed to rasterize SVG\"));\n image.src = url;\n });\n } finally {\n URL.revokeObjectURL(url);\n }\n }\n\n async toPNGDataURL(): Promise<string> {\n if (!HAS_DOM || !this.renderer) {\n throw new Error(\"toPNGDataURL requires a browser DOM environment\");\n }\n const svgString = this.renderer.toSVGString();\n return this.rasterizeSVG(svgString, this.renderer.svg.clientWidth, this.renderer.svg.clientHeight);\n }\n\n /**\n * Like toPNGDataURL, but tiles a chart larger than `pageWidthPx`/`pageHeightPx`\n * into multiple images (row-major order) instead of one oversized raster -\n * useful for charts too big to comfortably rasterize/view as a single PNG.\n * Reuses the full rendered SVG (so every page renders at full fidelity);\n * defaults to the chart's actual size, i.e. a single image, when omitted.\n */\n async toPNGDataURLs(options: { pageWidthPx?: number; pageHeightPx?: number } = {}): Promise<string[]> {\n if (!HAS_DOM || !this.renderer || !this.renderModel) {\n throw new Error(\"toPNGDataURLs requires a browser DOM environment\");\n }\n const svgString = this.renderer.toSVGString();\n const totalWidth = this.renderModel.width;\n const totalHeight = this.renderModel.headerHeight + this.renderModel.height;\n const pageWidth = Math.max(1, options.pageWidthPx ?? totalWidth);\n const pageHeight = Math.max(1, options.pageHeightPx ?? totalHeight);\n const cols = Math.max(1, Math.ceil(totalWidth / pageWidth));\n const rows = Math.max(1, Math.ceil(totalHeight / pageHeight));\n\n const results: string[] = [];\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tx = c * pageWidth;\n const ty = r * pageHeight;\n const tw = Math.min(pageWidth, totalWidth - tx);\n const th = Math.min(pageHeight, totalHeight - ty);\n // Re-window the same full-resolution SVG onto this tile's region: swapping\n // width/height/viewBox on the outer <svg> crops+repositions without re-serializing content.\n const tileSvg = svgString.replace(/<svg([^>]*)>/, (_match, attrs: string) => {\n const cleaned = attrs\n .replace(/\\swidth=\"[^\"]*\"/, \"\")\n .replace(/\\sheight=\"[^\"]*\"/, \"\")\n .replace(/\\sviewBox=\"[^\"]*\"/, \"\");\n return `<svg${cleaned} width=\"${tw}\" height=\"${th}\" viewBox=\"${tx} ${ty} ${tw} ${th}\">`;\n });\n results.push(await this.rasterizeSVG(tileSvg, tw, th));\n }\n }\n return results;\n }\n\n destroy(): void {\n if (this.rafHandle !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(this.rafHandle);\n }\n this.darkMediaQuery?.removeEventListener?.(\"change\", this.handleSchemeChange);\n this.emitter.removeAllListeners();\n this.interactions?.destroy();\n this.renderer?.destroy();\n }\n}\n\n","import type { GanttTheme } from \"./types\";\n\nexport const DEFAULT_THEME: GanttTheme = {\n rowHeight: 36,\n barHeight: 22,\n headerHeight: 50,\n gridColor: \"#e5e7eb\",\n weekendColor: \"#f3f4f6\",\n todayColor: \"#ef4444\",\n barColor: \"#3b82f6\",\n barProgressColor: \"#2563eb\",\n groupBarColor: \"#64748b\",\n linkColor: \"#94a3b8\",\n criticalColor: \"#dc2626\",\n baselineColor: \"#9ca3af\",\n deadlineColor: \"#f59e0b\",\n markerColor: \"#8b5cf6\",\n selectionColor: \"#0ea5e9\",\n textColor: \"#1f2937\",\n backgroundColor: \"#ffffff\",\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n fontSize: 12,\n borderRadius: 4,\n};\n\nexport const DARK_THEME: GanttTheme = {\n ...DEFAULT_THEME,\n gridColor: \"#2d3341\",\n weekendColor: \"#252a35\",\n todayColor: \"#f87171\",\n barColor: \"#60a5fa\",\n barProgressColor: \"#3b82f6\",\n groupBarColor: \"#94a3b8\",\n linkColor: \"#64748b\",\n criticalColor: \"#f87171\",\n baselineColor: \"#4b5563\",\n deadlineColor: \"#fbbf24\",\n markerColor: \"#a78bfa\",\n selectionColor: \"#38bdf8\",\n textColor: \"#e5e7eb\",\n backgroundColor: \"#181c24\",\n};\n\nexport type ColorScheme = \"light\" | \"dark\" | \"auto\";\n\nexport type Density = \"compact\" | \"comfortable\" | \"spacious\";\n\n/**\n * Row/bar/header/font sizing presets. Not wired into any option - spread one\n * into your `theme` prop/option (explicit fields you also set win, since\n * object spread is left-to-right):\n *\n * theme: { ...DENSITY_PRESETS.compact, barColor: \"#...\" }\n */\nexport const DENSITY_PRESETS: Record<Density, Pick<GanttTheme, \"rowHeight\" | \"barHeight\" | \"headerHeight\" | \"fontSize\">> = {\n compact: { rowHeight: 26, barHeight: 16, headerHeight: 38, fontSize: 11 },\n comfortable: { rowHeight: 36, barHeight: 22, headerHeight: 50, fontSize: 12 },\n spacious: { rowHeight: 48, barHeight: 30, headerHeight: 60, fontSize: 13 },\n};\n\nfunction prefersDark(): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n );\n}\n\n/** Resolve the base theme for a `colorScheme` setting; \"auto\" reads the OS/browser preference (falls back to light without a DOM). */\nexport function baseThemeForScheme(scheme: ColorScheme = \"auto\"): GanttTheme {\n if (scheme === \"dark\") return DARK_THEME;\n if (scheme === \"light\") return DEFAULT_THEME;\n return prefersDark() ? DARK_THEME : DEFAULT_THEME;\n}\n\nexport function mergeTheme(partial?: Partial<GanttTheme>, scheme: ColorScheme = \"light\"): GanttTheme {\n const base = scheme === \"light\" ? DEFAULT_THEME : baseThemeForScheme(scheme);\n return { ...base, ...partial };\n}\n\nconst CSS_VAR_NAMES: Record<keyof GanttTheme, string> = {\n rowHeight: \"--gantt-row-height\",\n barHeight: \"--gantt-bar-height\",\n headerHeight: \"--gantt-header-height\",\n gridColor: \"--gantt-grid-color\",\n weekendColor: \"--gantt-weekend-color\",\n todayColor: \"--gantt-today-color\",\n barColor: \"--gantt-bar-color\",\n barProgressColor: \"--gantt-bar-progress-color\",\n groupBarColor: \"--gantt-group-bar-color\",\n linkColor: \"--gantt-link-color\",\n criticalColor: \"--gantt-critical-color\",\n baselineColor: \"--gantt-baseline-color\",\n deadlineColor: \"--gantt-deadline-color\",\n markerColor: \"--gantt-marker-color\",\n selectionColor: \"--gantt-selection-color\",\n textColor: \"--gantt-text-color\",\n backgroundColor: \"--gantt-background-color\",\n fontFamily: \"--gantt-font-family\",\n fontSize: \"--gantt-font-size\",\n borderRadius: \"--gantt-border-radius\",\n};\n\nconst PX_FIELDS = new Set<keyof GanttTheme>([\n \"rowHeight\",\n \"barHeight\",\n \"headerHeight\",\n \"fontSize\",\n \"borderRadius\",\n]);\n\nexport function themeToCssVars(theme: GanttTheme): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const key of Object.keys(CSS_VAR_NAMES) as (keyof GanttTheme)[]) {\n const varName = CSS_VAR_NAMES[key];\n const value = theme[key];\n vars[varName] = PX_FIELDS.has(key) ? `${value}px` : String(value);\n }\n return vars;\n}\n\nexport function cssVarName(key: keyof GanttTheme): string {\n return CSS_VAR_NAMES[key];\n}\n\n/**\n * Only the fields the consumer explicitly set via the JS `theme` option, as inline CSS vars.\n * Unset fields are deliberately left undeclared on .gantt-root so a consumer's own stylesheet\n * (or our shipped light/dark defaults) controls them — inline styles would otherwise always\n * beat external CSS and defeat \"theme via CSS variables\" for anyone not using the JS API.\n */\nexport function explicitThemeToCssVars(partial?: Partial<GanttTheme>): Record<string, string> {\n if (!partial) return {};\n const vars: Record<string, string> = {};\n for (const key of Object.keys(partial) as (keyof GanttTheme)[]) {\n const value = partial[key];\n if (value === undefined) continue;\n vars[CSS_VAR_NAMES[key]] = PX_FIELDS.has(key) ? `${value}px` : String(value);\n }\n return vars;\n}\n\n/** `var(--gantt-x, resolvedFallback)` — lets external CSS win, while still painting correctly with zero CSS present. */\nexport function themedFill(key: keyof GanttTheme, resolvedValue: string): string {\n return `var(${CSS_VAR_NAMES[key]}, ${resolvedValue})`;\n}\n","import type { GanttDependency, GanttTask } from \"./types\";\n\nexport interface CriticalPathResult {\n criticalTasks: Set<string>;\n criticalLinks: Set<string>;\n}\n\nfunction linkKey(fromId: string, toId: string): string {\n return `${fromId}->${toId}`;\n}\n\nfunction isValidTask(task: GanttTask): boolean {\n return (\n task.start instanceof Date &&\n task.end instanceof Date &&\n !Number.isNaN(task.start.getTime()) &&\n !Number.isNaN(task.end.getTime())\n );\n}\n\nfunction durationOf(task: GanttTask): number {\n const d = task.end.getTime() - task.start.getTime();\n return d > 0 ? d : 0;\n}\n\n/**\n * Longest-duration-chain (CPM-style forward/backward pass) through the dependency DAG.\n * Task dates in a Gantt chart are already fixed (this isn't an auto-scheduler), so the\n * dependency `type` and `lagMs` are folded into a single edge weight rather than\n * recomputing actual start/end dates - the goal is only to flag which tasks/links sit\n * on the longest chain, not to move anything.\n */\nexport function computeCriticalPath(\n tasks: GanttTask[],\n dependencies: GanttDependency[]\n): CriticalPathResult {\n const empty: CriticalPathResult = { criticalTasks: new Set(), criticalLinks: new Set() };\n\n const leafTasks = tasks.filter((t) => !t.isGroup && isValidTask(t));\n const leafIds = new Set(leafTasks.map((t) => t.id));\n if (leafTasks.length === 0) return empty;\n\n const edges = dependencies.filter(\n (d) => leafIds.has(d.fromId) && leafIds.has(d.toId) && d.fromId !== d.toId\n );\n\n const outgoing = new Map<string, GanttDependency[]>();\n const incoming = new Map<string, GanttDependency[]>();\n for (const id of leafIds) {\n outgoing.set(id, []);\n incoming.set(id, []);\n }\n for (const e of edges) {\n outgoing.get(e.fromId)?.push(e);\n incoming.get(e.fromId) === undefined ? undefined : undefined;\n incoming.get(e.toId)?.push(e);\n }\n\n // Kahn's algorithm with a hard iteration cap so a malformed/cyclic dependency\n // list can never spin the render thread - a visited-set alone can't bound\n // work when nodes get revisited, so cap total dequeue operations explicitly.\n const inDegree = new Map<string, number>();\n for (const id of leafIds) inDegree.set(id, incoming.get(id)?.length ?? 0);\n const queue: string[] = [];\n for (const id of leafIds) {\n if ((inDegree.get(id) ?? 0) === 0) queue.push(id);\n }\n const topoOrder: string[] = [];\n const maxOps = leafIds.size + edges.length + 1;\n let ops = 0;\n let qi = 0;\n while (qi < queue.length) {\n if (ops++ > maxOps) return empty; // cycle guard tripped\n const nodeId = queue[qi++];\n if (nodeId === undefined) break;\n topoOrder.push(nodeId);\n for (const e of outgoing.get(nodeId) ?? []) {\n const nextDeg = (inDegree.get(e.toId) ?? 0) - 1;\n inDegree.set(e.toId, nextDeg);\n if (nextDeg === 0) queue.push(e.toId);\n }\n }\n\n if (topoOrder.length !== leafIds.size) {\n // Cycle detected: skip critical path computation entirely.\n return empty;\n }\n\n const taskById = new Map(leafTasks.map((t) => [t.id, t]));\n\n const es = new Map<string, number>();\n const ef = new Map<string, number>();\n for (const id of topoOrder) {\n const task = taskById.get(id);\n if (!task) continue;\n let start = 0;\n for (const e of incoming.get(id) ?? []) {\n const predEf = ef.get(e.fromId);\n if (predEf === undefined) continue;\n const lag = e.lagMs ?? 0;\n start = Math.max(start, predEf + lag);\n }\n es.set(id, start);\n ef.set(id, start + durationOf(task));\n }\n\n let projectEnd = 0;\n for (const id of topoOrder) {\n projectEnd = Math.max(projectEnd, ef.get(id) ?? 0);\n }\n\n const lf = new Map<string, number>();\n const ls = new Map<string, number>();\n for (let i = topoOrder.length - 1; i >= 0; i--) {\n const id = topoOrder[i];\n if (id === undefined) continue;\n const task = taskById.get(id);\n if (!task) continue;\n const succs = outgoing.get(id) ?? [];\n let finish = projectEnd;\n if (succs.length > 0) {\n finish = Infinity;\n for (const e of succs) {\n const succLs = ls.get(e.toId);\n if (succLs === undefined) continue;\n const lag = e.lagMs ?? 0;\n finish = Math.min(finish, succLs - lag);\n }\n if (!Number.isFinite(finish)) finish = projectEnd;\n }\n lf.set(id, finish);\n ls.set(id, finish - durationOf(task));\n }\n\n const EPSILON = 1;\n const criticalTasks = new Set<string>();\n for (const id of topoOrder) {\n const slack = (ls.get(id) ?? 0) - (es.get(id) ?? 0);\n if (Math.abs(slack) < EPSILON) criticalTasks.add(id);\n }\n\n const criticalLinks = new Set<string>();\n for (const e of edges) {\n if (!criticalTasks.has(e.fromId) || !criticalTasks.has(e.toId)) continue;\n const predEf = ef.get(e.fromId) ?? 0;\n const succEs = es.get(e.toId) ?? 0;\n const lag = e.lagMs ?? 0;\n if (Math.abs(succEs - (predEf + lag)) < EPSILON) {\n criticalLinks.add(linkKey(e.fromId, e.toId));\n }\n }\n\n const taskMap = new Map(tasks.map((t) => [t.id, t]));\n for (const task of tasks) {\n if (!task.isGroup) continue;\n let hasCriticalDescendant = false;\n let cur: GanttTask | undefined = task;\n const descendantStack = [task.id];\n const visited = new Set<string>();\n while (descendantStack.length > 0) {\n const id = descendantStack.pop();\n if (id === undefined || visited.has(id)) continue;\n visited.add(id);\n for (const t of tasks) {\n if (t.parentId === id) {\n if (criticalTasks.has(t.id)) hasCriticalDescendant = true;\n descendantStack.push(t.id);\n }\n }\n }\n if (hasCriticalDescendant) criticalTasks.add(task.id);\n void cur;\n void taskMap;\n }\n\n return { criticalTasks, criticalLinks };\n}\n","import { isNonWorkingDay, isWorkingTime, type WorkingCalendar } from \"./calendar\";\nimport type { ViewMode } from \"./types\";\n\nconst MS_PER_HOUR = 60 * 60 * 1000;\nconst MS_PER_DAY = 24 * MS_PER_HOUR;\nconst MS_PER_WEEK = 7 * MS_PER_DAY;\n\nconst WEEKDAY_LABELS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst MONTH_LABELS = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n];\n\n/** Approximate duration of one grid unit for the given view mode, used only for pixel scaling. */\nexport function approxUnitMs(viewMode: ViewMode): number {\n switch (viewMode) {\n case \"hour\":\n return MS_PER_HOUR;\n case \"day\":\n return MS_PER_DAY;\n case \"week\":\n return MS_PER_WEEK;\n case \"month\":\n return 30 * MS_PER_DAY;\n case \"quarter\":\n return 91 * MS_PER_DAY;\n case \"year\":\n return 365 * MS_PER_DAY;\n }\n}\n\n/** Pixels per millisecond, derived from how many px represent one grid unit. */\nexport function pxPerMs(viewMode: ViewMode, columnWidth: number): number {\n return columnWidth / approxUnitMs(viewMode);\n}\n\nexport function dateToX(\n date: Date,\n rangeStart: Date,\n viewMode: ViewMode,\n columnWidth: number\n): number {\n return (date.getTime() - rangeStart.getTime()) * pxPerMs(viewMode, columnWidth);\n}\n\nexport function isWeekend(date: Date): boolean {\n const day = date.getDay();\n return day === 0 || day === 6;\n}\n\nexport function isValidDate(date: unknown): date is Date {\n return date instanceof Date && !Number.isNaN(date.getTime());\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction startOfWeek(date: Date): Date {\n const d = startOfDay(date);\n const day = d.getDay();\n const diff = (day + 6) % 7; // Monday as start of week\n d.setDate(d.getDate() - diff);\n return d;\n}\n\nfunction startOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n}\n\nfunction startOfQuarter(date: Date): Date {\n const q = Math.floor(date.getMonth() / 3);\n return new Date(date.getFullYear(), q * 3, 1);\n}\n\nfunction startOfYear(date: Date): Date {\n return new Date(date.getFullYear(), 0, 1);\n}\n\nfunction startOfHour(date: Date): Date {\n return new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate(),\n date.getHours()\n );\n}\n\n/** Snap the given date down to the start of the grid unit for the view mode. */\nexport function startOfUnit(date: Date, viewMode: ViewMode): Date {\n switch (viewMode) {\n case \"hour\":\n return startOfHour(date);\n case \"day\":\n return startOfDay(date);\n case \"week\":\n return startOfWeek(date);\n case \"month\":\n return startOfMonth(date);\n case \"quarter\":\n return startOfQuarter(date);\n case \"year\":\n return startOfYear(date);\n }\n}\n\n/** Advance (or, with a negative count, go back) `count` grid units, calendar-aware. */\nexport function addUnit(date: Date, viewMode: ViewMode, count: number): Date {\n const d = new Date(date.getTime());\n switch (viewMode) {\n case \"hour\":\n d.setHours(d.getHours() + count);\n return d;\n case \"day\":\n d.setDate(d.getDate() + count);\n return d;\n case \"week\":\n d.setDate(d.getDate() + count * 7);\n return d;\n case \"month\":\n d.setMonth(d.getMonth() + count);\n return d;\n case \"quarter\":\n d.setMonth(d.getMonth() + count * 3);\n return d;\n case \"year\":\n d.setFullYear(d.getFullYear() + count);\n return d;\n }\n}\n\n/** Snap an arbitrary date to the nearest grid-unit boundary. */\nexport function snapToGrid(date: Date, viewMode: ViewMode): Date {\n const floor = startOfUnit(date, viewMode);\n const ceil = addUnit(floor, viewMode, 1);\n const mid = (floor.getTime() + ceil.getTime()) / 2;\n return date.getTime() < mid ? floor : ceil;\n}\n\nfunction isMajorBoundary(date: Date, viewMode: ViewMode): boolean {\n switch (viewMode) {\n case \"hour\":\n return date.getHours() === 0;\n case \"day\":\n return date.getDate() === 1;\n case \"week\":\n return date.getDate() <= 7 && date.getDay() === 1;\n case \"month\":\n return date.getMonth() === 0;\n case \"quarter\":\n return date.getMonth() === 0;\n case \"year\":\n return false;\n }\n}\n\nfunction labelFor(date: Date, viewMode: ViewMode): string {\n switch (viewMode) {\n case \"hour\": {\n const h = date.getHours();\n const period = h >= 12 ? \"PM\" : \"AM\";\n const h12 = h % 12 === 0 ? 12 : h % 12;\n return `${h12} ${period}`;\n }\n case \"day\":\n return `${WEEKDAY_LABELS[date.getDay()]} ${date.getDate()}`;\n case \"week\":\n return `${MONTH_LABELS[date.getMonth()]} ${date.getDate()}`;\n case \"month\":\n return `${MONTH_LABELS[date.getMonth()]} ${date.getFullYear()}`;\n case \"quarter\": {\n const q = Math.floor(date.getMonth() / 3) + 1;\n return `Q${q} ${date.getFullYear()}`;\n }\n case \"year\":\n return `${date.getFullYear()}`;\n }\n}\n\nexport interface GeneratedTick {\n date: Date;\n x: number;\n label: string;\n isWeekend: boolean;\n isNonWorking: boolean;\n isToday: boolean;\n isMajorBoundary: boolean;\n}\n\n/**\n * Generate header ticks spanning [rangeStart, rangeEnd], one per grid unit.\n * `x` is relative to rangeStart (the caller offsets it if the model has left padding).\n */\nexport function generateTicks(\n rangeStart: Date,\n rangeEnd: Date,\n viewMode: ViewMode,\n columnWidth: number,\n today: Date = new Date(),\n calendar?: WorkingCalendar\n): GeneratedTick[] {\n if (!isValidDate(rangeStart) || !isValidDate(rangeEnd)) return [];\n const ticks: GeneratedTick[] = [];\n let cursor = startOfUnit(rangeStart, viewMode);\n const scale = pxPerMs(viewMode, columnWidth);\n let guard = 0;\n const MAX_TICKS = 2000;\n const dayLevel = viewMode === \"day\" || viewMode === \"hour\";\n while (cursor.getTime() < rangeEnd.getTime() && guard < MAX_TICKS) {\n guard++;\n const x = (cursor.getTime() - rangeStart.getTime()) * scale;\n ticks.push({\n date: new Date(cursor.getTime()),\n x,\n label: labelFor(cursor, viewMode),\n isWeekend: dayLevel ? isWeekend(cursor) : false,\n isNonWorking:\n viewMode === \"hour\" && calendar?.workingHours\n ? !isWorkingTime(cursor, calendar)\n : dayLevel\n ? isNonWorkingDay(cursor, calendar)\n : false,\n isToday: isSameDay(cursor, today) && dayLevel,\n isMajorBoundary: isMajorBoundary(cursor, viewMode),\n });\n cursor = addUnit(cursor, viewMode, 1);\n }\n return ticks;\n}\n\nexport { MS_PER_HOUR, MS_PER_DAY, MS_PER_WEEK };\n","import { MS_PER_DAY } from \"./date-utils\";\n\n/**\n * Global working-time definition: which weekdays are worked, plus a list of\n * one-off non-working dates (holidays). Both are optional — an unset\n * `workingDays` defaults to Mon-Fri, an unset `holidays` list is empty.\n */\nexport interface WorkingCalendar {\n /** index 0 = Sunday ... 6 = Saturday. Defaults to Mon-Fri working. */\n workingDays?: boolean[];\n /** ISO \"YYYY-MM-DD\" dates that are non-working regardless of weekday. */\n holidays?: string[];\n /**\n * Daily working window, hour-of-day 0-24 (e.g. { start: 9, end: 17 }).\n * Only affects `isWorkingTime`/`shiftToWorkingTime` and hour-level tick\n * shading - task durations stay wall-clock (a 3-day task is still 3\n * calendar days, not 3 working-window days); this narrows *anchor\n * points* to the working window, it doesn't re-derive duration math.\n */\n workingHours?: { start: number; end: number };\n}\n\nconst DEFAULT_WORKING_DAYS = [false, true, true, true, true, true, false];\n\nfunction workingDaysOf(calendar?: WorkingCalendar): boolean[] {\n return calendar?.workingDays ?? DEFAULT_WORKING_DAYS;\n}\n\nfunction toISODate(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n}\n\nexport function isHoliday(date: Date, calendar?: WorkingCalendar): boolean {\n if (!calendar?.holidays || calendar.holidays.length === 0) return false;\n const iso = toISODate(date);\n return calendar.holidays.includes(iso);\n}\n\nexport function isWorkingDay(date: Date, calendar?: WorkingCalendar): boolean {\n const days = workingDaysOf(calendar);\n const dow = date.getDay();\n if (!days[dow]) return false;\n return !isHoliday(date, calendar);\n}\n\nexport function isNonWorkingDay(date: Date, calendar?: WorkingCalendar): boolean {\n return !isWorkingDay(date, calendar);\n}\n\n/** Next working day at/after `date` (same time-of-day), scanning forward at most 366 days. */\nexport function nextWorkingDay(date: Date, calendar?: WorkingCalendar): Date {\n let cursor = new Date(date.getTime());\n let guard = 0;\n while (!isWorkingDay(cursor, calendar) && guard++ < 366) {\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n }\n return cursor;\n}\n\n/** Previous working day at/before `date` (same time-of-day), scanning backward at most 366 days. */\nexport function previousWorkingDay(date: Date, calendar?: WorkingCalendar): Date {\n let cursor = new Date(date.getTime());\n let guard = 0;\n while (!isWorkingDay(cursor, calendar) && guard++ < 366) {\n cursor = new Date(cursor.getTime() - MS_PER_DAY);\n }\n return cursor;\n}\n\n/**\n * Nudge `date` onto a working day if it isn't already, moving in `direction`\n * (1 = forward, -1 = backward). No-op (besides cloning) when no calendar is given\n * or `date` is already a working day.\n */\nexport function shiftToWorkingDay(date: Date, calendar: WorkingCalendar | undefined, direction: 1 | -1): Date {\n if (!calendar) return new Date(date.getTime());\n return direction === 1 ? nextWorkingDay(date, calendar) : previousWorkingDay(date, calendar);\n}\n\nfunction hourOfDay(date: Date): number {\n return date.getHours() + date.getMinutes() / 60 + date.getSeconds() / 3600;\n}\n\nexport function isWithinWorkingHours(date: Date, calendar?: WorkingCalendar): boolean {\n const hours = calendar?.workingHours;\n if (!hours) return true;\n const h = hourOfDay(date);\n return h >= hours.start && h < hours.end;\n}\n\n/** Working day AND (no workingHours set, or within them). */\nexport function isWorkingTime(date: Date, calendar?: WorkingCalendar): boolean {\n return isWorkingDay(date, calendar) && isWithinWorkingHours(date, calendar);\n}\n\nfunction applyHour(date: Date, hour: number): void {\n const wholeHours = Math.floor(hour);\n const minutes = Math.round((hour - wholeHours) * 60);\n date.setHours(wholeHours, minutes, 0, 0);\n}\n\n/**\n * Like shiftToWorkingDay, but also snaps onto the daily working-hours window\n * when one is configured: forward past a day's end (or on a non-working day)\n * moves to the next working day's start; backward before a day's start (or\n * on a non-working day) moves to the previous working day's end. No-op\n * without a calendar.\n */\nexport function shiftToWorkingTime(\n date: Date,\n calendar: WorkingCalendar | undefined,\n direction: 1 | -1\n): Date {\n if (!calendar) return new Date(date.getTime());\n const wh = calendar.workingHours;\n let guard = 0;\n let cursor = new Date(date.getTime());\n\n while (guard++ < 400) {\n if (!isWorkingDay(cursor, calendar)) {\n cursor = direction === 1 ? nextWorkingDay(cursor, calendar) : previousWorkingDay(cursor, calendar);\n if (wh) applyHour(cursor, direction === 1 ? wh.start : wh.end);\n continue;\n }\n if (!wh) return cursor;\n\n const h = hourOfDay(cursor);\n if (h < wh.start) {\n if (direction === 1) {\n applyHour(cursor, wh.start);\n return cursor;\n }\n cursor = previousWorkingDay(new Date(cursor.getTime() - MS_PER_DAY), calendar);\n applyHour(cursor, wh.end);\n // an instant before end is still \"within\" [start, end); nudge back 1ms to land inside the window\n return new Date(cursor.getTime() - 1);\n }\n if (h >= wh.end) {\n if (direction === 1) {\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n applyHour(cursor, wh.start);\n continue;\n }\n applyHour(cursor, wh.end);\n return new Date(cursor.getTime() - 1);\n }\n return cursor;\n }\n return cursor;\n}\n","import type { WorkingCalendar } from \"./calendar\";\nimport { computeCriticalPath } from \"./critical-path\";\nimport { addUnit, dateToX, generateTicks, isValidDate } from \"./date-utils\";\nimport type {\n GanttColumn,\n GanttDependency,\n GanttMarker,\n GanttRenderBar,\n GanttRenderLink,\n GanttRenderModel,\n GanttRenderRow,\n GanttTask,\n GanttTheme,\n ViewMode,\n} from \"./types\";\n\nexport interface LayoutInput {\n tasks: GanttTask[];\n dependencies: GanttDependency[];\n viewMode: ViewMode;\n columnWidth: number;\n theme: GanttTheme;\n columns: GanttColumn[];\n showCriticalPath?: boolean;\n showBaseline?: boolean;\n showDeadlines?: boolean;\n showAssigneeAvatars?: boolean;\n calendar?: WorkingCalendar;\n markers?: GanttMarker[];\n /** a group task with no explicit `progress` gets a duration-weighted average of its children's progress instead of 0 */\n autoRollupProgress?: boolean;\n selectedTaskIds?: Set<string>;\n /** restrict layout to a page of top-level rows, in document order (1-indexed) */\n pagination?: { pageSize: number; page: number };\n}\n\ninterface TreeNode {\n task: GanttTask;\n children: TreeNode[];\n computedStart: Date | null;\n computedEnd: Date | null;\n computedProgress: number;\n}\n\nfunction buildTree(tasks: GanttTask[]): { roots: TreeNode[]; nodeById: Map<string, TreeNode> } {\n const nodeById = new Map<string, TreeNode>();\n for (const task of tasks) {\n nodeById.set(task.id, { task, children: [], computedStart: null, computedEnd: null, computedProgress: 0 });\n }\n const roots: TreeNode[] = [];\n for (const task of tasks) {\n const node = nodeById.get(task.id);\n if (!node) continue;\n const parent = task.parentId ? nodeById.get(task.parentId) : undefined;\n if (parent) {\n parent.children.push(node);\n } else {\n roots.push(node);\n }\n }\n return { roots, nodeById };\n}\n\n/** Post-order: fills in computedStart/computedEnd for group nodes lacking explicit valid dates. */\nfunction computeSpans(node: TreeNode): void {\n for (const child of node.children) computeSpans(child);\n\n const hasExplicit = isValidDate(node.task.start) && isValidDate(node.task.end);\n if (hasExplicit) {\n node.computedStart = node.task.start;\n node.computedEnd = node.task.end;\n return;\n }\n if (node.children.length === 0) {\n node.computedStart = null;\n node.computedEnd = null;\n return;\n }\n let min: number | null = null;\n let max: number | null = null;\n for (const child of node.children) {\n if (child.computedStart) {\n const t = child.computedStart.getTime();\n min = min === null ? t : Math.min(min, t);\n }\n if (child.computedEnd) {\n const t = child.computedEnd.getTime();\n max = max === null ? t : Math.max(max, t);\n }\n }\n node.computedStart = min === null ? null : new Date(min);\n node.computedEnd = max === null ? null : new Date(max);\n}\n\n/** Post-order: fills in computedProgress for group nodes with no explicit `progress`, duration-weighted over children. */\nfunction computeProgressRollup(node: TreeNode): void {\n for (const child of node.children) computeProgressRollup(child);\n\n if (node.task.progress !== undefined) {\n node.computedProgress = Math.min(100, Math.max(0, node.task.progress));\n return;\n }\n if (node.children.length === 0) {\n node.computedProgress = 0;\n return;\n }\n let weightedSum = 0;\n let totalWeight = 0;\n for (const child of node.children) {\n const duration =\n child.computedStart && child.computedEnd\n ? Math.max(1, child.computedEnd.getTime() - child.computedStart.getTime())\n : 1;\n weightedSum += child.computedProgress * duration;\n totalWeight += duration;\n }\n node.computedProgress = totalWeight > 0 ? weightedSum / totalWeight : 0;\n}\n\ninterface FlatRow {\n node: TreeNode;\n depth: number;\n visible: boolean;\n}\n\n/** O(n) document-order flatten, skipping descendants of collapsed groups. */\nfunction flatten(roots: TreeNode[]): FlatRow[] {\n const out: FlatRow[] = [];\n const stack: { node: TreeNode; depth: number; parentCollapsed: boolean }[] = [];\n for (let i = roots.length - 1; i >= 0; i--) {\n const r = roots[i];\n if (r) stack.push({ node: r, depth: 0, parentCollapsed: false });\n }\n while (stack.length > 0) {\n const item = stack.pop();\n if (!item) continue;\n const { node, depth, parentCollapsed } = item;\n if (parentCollapsed) continue;\n out.push({ node, depth, visible: true });\n const collapsedHere = !!node.task.collapsed;\n for (let i = node.children.length - 1; i >= 0; i--) {\n const child = node.children[i];\n if (child) stack.push({ node: child, depth: depth + 1, parentCollapsed: collapsedHere });\n }\n }\n return out;\n}\n\nfunction anchorPoint(\n bar: { x: number; y: number; width: number; height: number },\n side: \"start\" | \"end\"\n): { x: number; y: number } {\n const y = bar.y + bar.height / 2;\n return side === \"start\" ? { x: bar.x, y } : { x: bar.x + bar.width, y };\n}\n\nfunction devWarn(message: string): void {\n const isProd =\n typeof process !== \"undefined\" && process.env && process.env.NODE_ENV === \"production\";\n if (!isProd) console.warn(`[gantt-core] ${message}`);\n}\n\nfunction validateInputs(tasks: GanttTask[], dependencies: GanttDependency[]): void {\n const ids = new Set(tasks.map((t) => t.id));\n for (const dep of dependencies) {\n if (!ids.has(dep.fromId) || !ids.has(dep.toId)) {\n devWarn(\n `dependency references a non-existent task: ${dep.fromId} -> ${dep.toId}`\n );\n }\n }\n for (const task of tasks) {\n if (isValidDate(task.start) && isValidDate(task.end) && task.end < task.start) {\n devWarn(`task \"${task.id}\" has end date before start date`);\n }\n }\n\n const outgoing = new Map<string, string[]>();\n for (const dep of dependencies) {\n if (!ids.has(dep.fromId) || !ids.has(dep.toId)) continue;\n const list = outgoing.get(dep.fromId) ?? [];\n list.push(dep.toId);\n outgoing.set(dep.fromId, list);\n }\n const indegree = new Map<string, number>();\n for (const id of ids) indegree.set(id, 0);\n for (const [, targets] of outgoing) {\n for (const t of targets) indegree.set(t, (indegree.get(t) ?? 0) + 1);\n }\n const queue: string[] = [];\n for (const [id, deg] of indegree) if (deg === 0) queue.push(id);\n let visited = 0;\n let qi = 0;\n const maxOps = ids.size + dependencies.length + 1;\n let ops = 0;\n while (qi < queue.length && ops++ <= maxOps) {\n const id = queue[qi++];\n if (id === undefined) break;\n visited++;\n for (const next of outgoing.get(id) ?? []) {\n const d = (indegree.get(next) ?? 0) - 1;\n indegree.set(next, d);\n if (d === 0) queue.push(next);\n }\n }\n if (visited !== ids.size) {\n devWarn(\"circular dependency detected; critical path / scheduling for affected tasks is skipped\");\n }\n}\n\nfunction linkPath(from: { x: number; y: number }, to: { x: number; y: number }): string {\n const dx = Math.max(20, Math.abs(to.x - from.x) / 2);\n const c1x = from.x + dx;\n const c1y = from.y;\n const c2x = to.x - dx;\n const c2y = to.y;\n return `M ${from.x} ${from.y} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${to.x} ${to.y}`;\n}\n\nexport function computeLayout(input: LayoutInput): GanttRenderModel {\n const {\n tasks,\n dependencies,\n viewMode,\n columnWidth,\n theme,\n columns,\n showCriticalPath = false,\n showBaseline = false,\n showDeadlines = true,\n calendar,\n markers = [],\n autoRollupProgress = false,\n selectedTaskIds,\n pagination,\n } = input;\n\n validateInputs(tasks, dependencies);\n\n const { roots, nodeById } = buildTree(tasks);\n for (const root of roots) computeSpans(root);\n if (autoRollupProgress) {\n for (const root of roots) computeProgressRollup(root);\n }\n\n let visibleRoots = roots;\n if (pagination && pagination.pageSize > 0) {\n const start = Math.max(0, (pagination.page - 1) * pagination.pageSize);\n visibleRoots = roots.slice(start, start + pagination.pageSize);\n }\n\n const flatRows = flatten(visibleRoots);\n const visibleIds = new Set(flatRows.map((f) => f.node.task.id));\n\n const { criticalTasks, criticalLinks } = showCriticalPath\n ? computeCriticalPath(tasks, dependencies)\n : { criticalTasks: new Set<string>(), criticalLinks: new Set<string>() };\n\n let rangeMin: number | null = null;\n let rangeMax: number | null = null;\n for (const row of flatRows) {\n const s = row.node.computedStart;\n const e = row.node.computedEnd;\n if (s) rangeMin = rangeMin === null ? s.getTime() : Math.min(rangeMin, s.getTime());\n if (e) rangeMax = rangeMax === null ? e.getTime() : Math.max(rangeMax, e.getTime());\n }\n const now = Date.now();\n const rawRangeStart = rangeMin === null ? new Date(now) : new Date(rangeMin);\n const rawRangeEnd = rangeMax === null ? new Date(now + 1) : new Date(rangeMax);\n const paddedStart = addUnit(rawRangeStart, viewMode, -1);\n const paddedEnd = addUnit(rawRangeEnd, viewMode, 1);\n\n const rows: GanttRenderRow[] = [];\n const bars: GanttRenderBar[] = [];\n const barByTaskId = new Map<string, GanttRenderBar>();\n\n flatRows.forEach((row, index) => {\n const { task } = row.node;\n const y = index * theme.rowHeight;\n rows.push({\n taskId: task.id,\n y,\n height: theme.rowHeight,\n isGroup: !!task.isGroup,\n collapsed: !!task.collapsed,\n depth: row.depth,\n hasChildren: row.node.children.length > 0,\n });\n\n const start = row.node.computedStart;\n const end = row.node.computedEnd;\n if (!start || !end) return;\n\n const x = dateToX(start, paddedStart, viewMode, columnWidth);\n const width = Math.max(0, dateToX(end, paddedStart, viewMode, columnWidth) - x);\n if (!Number.isFinite(x) || !Number.isFinite(width)) return;\n\n const progress =\n task.progress !== undefined\n ? Math.min(100, Math.max(0, task.progress))\n : autoRollupProgress\n ? row.node.computedProgress\n : 0;\n const barHeight = theme.barHeight;\n const barY = y + (theme.rowHeight - barHeight) / 2;\n\n const color = task.color ?? (task.isGroup ? theme.groupBarColor : theme.barColor);\n const progressColor = task.progressColor ?? theme.barProgressColor;\n\n const bar: GanttRenderBar = {\n taskId: task.id,\n x,\n y: barY,\n width,\n height: barHeight,\n progressWidth: (width * progress) / 100,\n color,\n progressColor,\n label: task.name,\n isCritical: showCriticalPath && criticalTasks.has(task.id),\n isMilestone: task.isMilestone ?? start.getTime() === end.getTime(),\n isSelected: selectedTaskIds?.has(task.id) ?? false,\n };\n\n if (task.segments && task.segments.length > 0) {\n const validSegments = task.segments.filter(\n (s) => isValidDate(s.start) && isValidDate(s.end) && s.end.getTime() > s.start.getTime()\n );\n if (validSegments.length > 0) {\n bar.segments = validSegments.map((s) => {\n const sx = dateToX(s.start, paddedStart, viewMode, columnWidth);\n const sw = Math.max(0, dateToX(s.end, paddedStart, viewMode, columnWidth) - sx);\n return { x: sx - x, width: sw, progressWidth: (sw * progress) / 100 };\n });\n }\n }\n\n if (showBaseline && isValidDate(task.baselineStart) && isValidDate(task.baselineEnd)) {\n const bx = dateToX(task.baselineStart, paddedStart, viewMode, columnWidth);\n const bw = Math.max(\n 0,\n dateToX(task.baselineEnd, paddedStart, viewMode, columnWidth) - bx\n );\n if (Number.isFinite(bx) && Number.isFinite(bw)) {\n bar.baseline = { x: bx, width: bw };\n }\n }\n\n if (showBaseline && task.baselines && task.baselines.length > 0) {\n bar.baselines = task.baselines\n .filter((b) => isValidDate(b.start) && isValidDate(b.end))\n .map((b) => {\n const bx = dateToX(b.start, paddedStart, viewMode, columnWidth);\n const bw = Math.max(0, dateToX(b.end, paddedStart, viewMode, columnWidth) - bx);\n return { label: b.label, x: bx, width: bw };\n })\n .filter((b) => Number.isFinite(b.x) && Number.isFinite(b.width));\n }\n\n if (showDeadlines && isValidDate(task.deadline)) {\n const dx = dateToX(task.deadline, paddedStart, viewMode, columnWidth);\n if (Number.isFinite(dx)) {\n bar.deadlineX = dx;\n bar.isOverdue = end.getTime() > task.deadline.getTime();\n }\n }\n\n bars.push(bar);\n barByTaskId.set(task.id, bar);\n });\n\n function nearestVisibleAncestorId(taskId: string): string | null {\n let currentId: string | null = taskId;\n const guard = new Set<string>();\n while (currentId !== null && !guard.has(currentId)) {\n guard.add(currentId);\n if (visibleIds.has(currentId)) return currentId;\n const node = nodeById.get(currentId);\n currentId = node?.task.parentId ?? null;\n }\n return null;\n }\n\n const links: GanttRenderLink[] = [];\n for (const dep of dependencies) {\n if (!nodeById.has(dep.fromId) || !nodeById.has(dep.toId)) continue;\n const fromVisibleId = nearestVisibleAncestorId(dep.fromId);\n const toVisibleId = nearestVisibleAncestorId(dep.toId);\n if (!fromVisibleId || !toVisibleId || fromVisibleId === toVisibleId) continue;\n const fromBar = barByTaskId.get(fromVisibleId);\n const toBar = barByTaskId.get(toVisibleId);\n if (!fromBar || !toBar) continue;\n\n const fromSide = dep.type === \"SS\" || dep.type === \"SF\" ? \"start\" : \"end\";\n const toSide = dep.type === \"FF\" || dep.type === \"SF\" ? \"end\" : \"start\";\n const from = anchorPoint(fromBar, fromSide);\n const to = anchorPoint(toBar, toSide);\n\n links.push({\n fromId: dep.fromId,\n toId: dep.toId,\n type: dep.type,\n path: linkPath(from, to),\n isCritical: showCriticalPath && criticalLinks.has(`${dep.fromId}->${dep.toId}`),\n });\n }\n\n const ticks = generateTicks(paddedStart, paddedEnd, viewMode, columnWidth, new Date(), calendar).map(\n (t) => ({\n x: t.x,\n label: t.label,\n isWeekend: t.isWeekend,\n isNonWorking: t.isNonWorking,\n isToday: t.isToday,\n isMajorBoundary: t.isMajorBoundary,\n })\n );\n\n const renderMarkers = markers\n .filter((m) => isValidDate(m.date))\n .map((m) => ({\n x: dateToX(m.date, paddedStart, viewMode, columnWidth),\n label: m.label ?? \"\",\n color: m.color ?? theme.markerColor,\n }))\n .filter((m) => Number.isFinite(m.x));\n\n let width = 0;\n for (const tick of ticks) width = Math.max(width, tick.x);\n for (const bar of bars) width = Math.max(width, bar.x + bar.width);\n width += columnWidth;\n\n const height = rows.length * theme.rowHeight;\n\n return {\n width,\n height,\n rowHeight: theme.rowHeight,\n headerHeight: theme.headerHeight,\n rows,\n bars,\n links,\n ticks,\n columns,\n theme,\n markers: renderMarkers,\n rangeStart: paddedStart,\n };\n}\n","export interface Command {\n do(): void;\n undo(): void;\n label?: string;\n}\n\nexport type HistoryChangeListener = (state: { canUndo: boolean; canRedo: boolean }) => void;\n\nexport class HistoryManager {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private onChange?: HistoryChangeListener;\n\n constructor(onChange?: HistoryChangeListener) {\n this.onChange = onChange;\n }\n\n push(cmd: Command): void {\n cmd.do();\n this.undoStack.push(cmd);\n this.redoStack = [];\n this.notify();\n }\n\n undo(): boolean {\n const cmd = this.undoStack.pop();\n if (!cmd) return false;\n cmd.undo();\n this.redoStack.push(cmd);\n this.notify();\n return true;\n }\n\n redo(): boolean {\n const cmd = this.redoStack.pop();\n if (!cmd) return false;\n cmd.do();\n this.undoStack.push(cmd);\n this.notify();\n return true;\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n private notify(): void {\n this.onChange?.({ canUndo: this.canUndo, canRedo: this.canRedo });\n }\n}\n","export type Listener<TPayload> = (payload: TPayload) => void;\n\nexport class EventEmitter<TEventMap extends Record<string, unknown>> {\n private listeners: { [K in keyof TEventMap]?: Set<Listener<TEventMap[K]>> } = {};\n\n on<K extends keyof TEventMap>(event: K, listener: Listener<TEventMap[K]>): void {\n let set = this.listeners[event];\n if (!set) {\n set = new Set();\n this.listeners[event] = set;\n }\n set.add(listener);\n }\n\n off<K extends keyof TEventMap>(event: K, listener: Listener<TEventMap[K]>): void {\n this.listeners[event]?.delete(listener);\n }\n\n once<K extends keyof TEventMap>(event: K, listener: Listener<TEventMap[K]>): void {\n const wrapper: Listener<TEventMap[K]> = (payload) => {\n this.off(event, wrapper);\n listener(payload);\n };\n this.on(event, wrapper);\n }\n\n emit<K extends keyof TEventMap>(event: K, payload: TEventMap[K]): void {\n const set = this.listeners[event];\n if (!set) return;\n for (const listener of Array.from(set)) {\n listener(payload);\n }\n }\n\n removeAllListeners(): void {\n this.listeners = {};\n }\n}\n","import type { GanttTask } from \"./types\";\n\nconst CSV_COLUMNS = [\"id\", \"name\", \"start\", \"end\", \"progress\", \"parentId\"] as const;\n\nfunction escapeCsvField(value: string): string {\n if (/[\",\\n]/.test(value)) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\nfunction parseCsvLine(line: string): string[] {\n const fields: string[] = [];\n let current = \"\";\n let inQuotes = false;\n for (let i = 0; i < line.length; i++) {\n const char = line[i] ?? \"\";\n if (inQuotes) {\n if (char === '\"') {\n if (line[i + 1] === '\"') {\n current += '\"';\n i++;\n } else {\n inQuotes = false;\n }\n } else {\n current += char;\n }\n } else if (char === '\"') {\n inQuotes = true;\n } else if (char === \",\") {\n fields.push(current);\n current = \"\";\n } else {\n current += char;\n }\n }\n fields.push(current);\n return fields;\n}\n\nexport function tasksToCSV(tasks: GanttTask[]): string {\n const lines = [CSV_COLUMNS.join(\",\")];\n for (const task of tasks) {\n const row = [\n task.id,\n task.name,\n task.start instanceof Date ? task.start.toISOString() : \"\",\n task.end instanceof Date ? task.end.toISOString() : \"\",\n task.progress !== undefined ? String(task.progress) : \"\",\n task.parentId ?? \"\",\n ].map((v) => escapeCsvField(String(v)));\n lines.push(row.join(\",\"));\n }\n return lines.join(\"\\n\");\n}\n\nexport function tasksFromCSV(csv: string): GanttTask[] {\n const lines = csv.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length === 0) return [];\n const header = parseCsvLine(lines[0] ?? \"\");\n const colIndex = new Map(header.map((h, i) => [h.trim(), i]));\n\n const tasks: GanttTask[] = [];\n for (let i = 1; i < lines.length; i++) {\n const fields = parseCsvLine(lines[i] ?? \"\");\n const get = (col: string): string => {\n const idx = colIndex.get(col);\n return idx === undefined ? \"\" : fields[idx] ?? \"\";\n };\n const id = get(\"id\");\n if (!id) continue;\n const progressRaw = get(\"progress\");\n const parentIdRaw = get(\"parentId\");\n tasks.push({\n id,\n name: get(\"name\"),\n start: new Date(get(\"start\")),\n end: new Date(get(\"end\")),\n progress: progressRaw ? Number(progressRaw) : undefined,\n parentId: parentIdRaw || null,\n });\n }\n return tasks;\n}\n","import { explicitThemeToCssVars, themedFill } from \"./theme\";\nimport type {\n GanttColumn,\n GanttRenderBar,\n GanttRenderModel,\n GanttRenderRow,\n GanttTask,\n GanttTheme,\n} from \"./types\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\nexport interface RendererOptions {\n keyboardAccessible?: boolean;\n showAssigneeAvatars?: boolean;\n virtualScroll?: boolean;\n overscan?: number;\n onRenameCommit?: (taskId: string, name: string) => void;\n onColumnResize?: (columnId: string, width: number) => void;\n onColumnReorder?: (order: string[]) => void;\n onRowReorder?: (draggedTaskId: string, targetTaskId: string, position: \"before\" | \"after\" | \"inside\") => void;\n}\n\n/**\n * Only http(s), mailto, and scheme-relative/relative URLs are allowed in a getHref() cell -\n * anything else (javascript:, data:, vbscript:, etc.) renders as plain text instead of a link.\n */\nexport function isSafeHref(url: string): boolean {\n try {\n const base =\n typeof location !== \"undefined\" && location.origin ? location.origin : \"http://localhost\";\n const parsed = new URL(url, base);\n return (\n parsed.protocol === \"http:\" || parsed.protocol === \"https:\" || parsed.protocol === \"mailto:\"\n );\n } catch {\n return false;\n }\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className?: string\n): HTMLElementTagNameMap[K] {\n const e = document.createElement(tag);\n if (className) e.className = className;\n return e;\n}\n\nfunction svgEl<K extends keyof SVGElementTagNameMap>(tag: K): SVGElementTagNameMap[K] {\n return document.createElementNS(SVG_NS, tag) as SVGElementTagNameMap[K];\n}\n\nfunction initials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n const first = parts[0]?.[0] ?? \"\";\n const last = parts.length > 1 ? parts[parts.length - 1]?.[0] ?? \"\" : \"\";\n return (first + last).toUpperCase();\n}\n\nexport class GanttRenderer {\n readonly root: HTMLElement;\n readonly gridPanel: HTMLElement;\n readonly timelineScroll: HTMLElement;\n readonly svg: SVGSVGElement;\n private markerDefsId: string;\n private scrollListener?: () => void;\n private lastModel: GanttRenderModel | null = null;\n private lastTasks: GanttTask[] = [];\n private lastColumns: GanttColumn[] = [];\n\n constructor(\n private container: HTMLElement,\n private options: RendererOptions = {}\n ) {\n this.markerDefsId = `gantt-arrow-${Math.random().toString(36).slice(2)}`;\n this.root = el(\"div\", \"gantt-root\");\n this.gridPanel = el(\"div\", \"gantt-grid-panel\");\n this.timelineScroll = el(\"div\", \"gantt-timeline-scroll\");\n this.svg = svgEl(\"svg\");\n this.svg.classList.add(\"gantt-svg\");\n this.timelineScroll.appendChild(this.svg);\n this.root.appendChild(this.gridPanel);\n this.root.appendChild(this.timelineScroll);\n this.container.appendChild(this.root);\n\n if (options.virtualScroll !== false && typeof document !== \"undefined\") {\n this.scrollListener = () => this.rerenderVisibleOnly();\n this.timelineScroll.addEventListener(\"scroll\", this.scrollListener);\n }\n\n this.gridPanel.addEventListener(\"dblclick\", this.onGridDoubleClick);\n }\n\n private onGridDoubleClick = (evt: MouseEvent): void => {\n if (!this.options.onRenameCommit) return;\n const target = evt.target as HTMLElement;\n const cell = target.closest<HTMLElement>(\"[data-gantt-name-cell]\");\n if (!cell || cell.querySelector(\"input\")) return;\n const taskId = cell.dataset.ganttNameCell;\n if (!taskId) return;\n const currentText = cell.dataset.ganttNameValue ?? \"\";\n cell.replaceChildren();\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.value = currentText;\n input.className = \"gantt-rename-input\";\n cell.appendChild(input);\n input.focus();\n input.select();\n\n const commit = () => {\n this.options.onRenameCommit?.(taskId, input.value);\n };\n const cancel = () => {\n this.rerenderVisibleOnly();\n };\n input.addEventListener(\"keydown\", (kEvt) => {\n if (kEvt.key === \"Enter\") {\n kEvt.preventDefault();\n commit();\n } else if (kEvt.key === \"Escape\") {\n kEvt.preventDefault();\n cancel();\n }\n });\n input.addEventListener(\"blur\", commit, { once: true });\n };\n\n render(\n model: GanttRenderModel,\n tasks: GanttTask[],\n columns: GanttColumn[],\n explicitTheme?: Partial<GanttTheme>\n ): void {\n this.lastModel = model;\n this.lastTasks = tasks;\n this.lastColumns = columns;\n\n // Only inline the fields the consumer explicitly set via the JS `theme` option.\n // Everything else is left undeclared here so external CSS (or our shipped\n // light/dark defaults in styles.css) controls it via var(--gantt-x, fallback)\n // on the painted elements below — an inline style on .gantt-root would otherwise\n // always beat a plain (non-!important) external stylesheet rule.\n const cssVars = explicitThemeToCssVars(explicitTheme);\n for (const key of Object.keys(cssVars)) {\n this.root.style.setProperty(key, cssVars[key] as string);\n }\n\n this.renderGridPanel(model, tasks, columns);\n this.renderTimeline(model, tasks);\n }\n\n private getViewportRowRange(model: GanttRenderModel): { startY: number; endY: number } {\n if (this.options.virtualScroll === false) {\n return { startY: -Infinity, endY: Infinity };\n }\n const overscan = (this.options.overscan ?? 5) * model.rowHeight;\n const scrollTop = this.timelineScroll.scrollTop || 0;\n const viewportHeight = this.timelineScroll.clientHeight || model.height;\n return {\n startY: scrollTop - overscan,\n endY: scrollTop + viewportHeight + overscan,\n };\n }\n\n private rerenderVisibleOnly(): void {\n if (!this.lastModel) return;\n this.renderGridPanel(this.lastModel, this.lastTasks, this.lastColumns);\n this.renderTimeline(this.lastModel, this.lastTasks);\n }\n\n private renderGridPanel(\n model: GanttRenderModel,\n tasks: GanttTask[],\n columns: GanttColumn[]\n ): void {\n this.gridPanel.replaceChildren();\n const taskById = new Map(tasks.map((t) => [t.id, t]));\n const { startY, endY } = this.getViewportRowRange(model);\n\n const header = el(\"div\", \"gantt-grid-header-row\");\n header.style.height = `${model.headerHeight}px`;\n for (const col of columns) {\n header.appendChild(this.renderHeaderCell(col, columns));\n }\n this.gridPanel.appendChild(header);\n\n const body = el(\"div\", \"gantt-grid-body\");\n body.style.height = `${model.height}px`;\n\n model.rows.forEach((row, index) => {\n if (row.y + row.height < startY || row.y > endY) return;\n const task = taskById.get(row.taskId);\n if (!task) return;\n body.appendChild(this.renderGridRow(row, task, columns, index));\n });\n\n this.gridPanel.appendChild(body);\n }\n\n private renderHeaderCell(col: GanttColumn, columns: GanttColumn[]): HTMLElement {\n const cell = el(\"div\", \"gantt-grid-header-cell\");\n cell.style.position = \"relative\";\n if (col.width) cell.style.width = `${col.width}px`;\n cell.textContent = col.title;\n\n if (this.options.onColumnReorder) {\n cell.draggable = true;\n cell.style.cursor = \"grab\";\n cell.addEventListener(\"dragstart\", (evt) => {\n evt.dataTransfer?.setData(\"text/plain\", col.id);\n });\n cell.addEventListener(\"dragover\", (evt) => evt.preventDefault());\n cell.addEventListener(\"drop\", (evt) => {\n evt.preventDefault();\n const draggedId = evt.dataTransfer?.getData(\"text/plain\");\n if (!draggedId || draggedId === col.id) return;\n const order = columns.map((c) => c.id).filter((id) => id !== draggedId);\n const targetIndex = order.indexOf(col.id);\n order.splice(targetIndex, 0, draggedId);\n this.options.onColumnReorder?.(order);\n });\n }\n\n if (this.options.onColumnResize) {\n const handle = el(\"div\", \"gantt-col-resize-handle\");\n handle.style.position = \"absolute\";\n handle.style.right = \"0\";\n handle.style.top = \"0\";\n handle.style.bottom = \"0\";\n handle.style.width = \"6px\";\n handle.style.cursor = \"col-resize\";\n handle.addEventListener(\"pointerdown\", (evt) => {\n evt.preventDefault();\n evt.stopPropagation();\n const startX = evt.clientX;\n const startWidth = col.width ?? cell.getBoundingClientRect().width;\n const onMove = (moveEvt: PointerEvent) => {\n const newWidth = Math.max(30, startWidth + (moveEvt.clientX - startX));\n cell.style.width = `${newWidth}px`;\n };\n const onUp = (upEvt: PointerEvent) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n const newWidth = Math.max(30, startWidth + (upEvt.clientX - startX));\n this.options.onColumnResize?.(col.id, newWidth);\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n });\n cell.appendChild(handle);\n }\n\n return cell;\n }\n\n private renderGridRow(\n row: GanttRenderRow,\n task: GanttTask,\n columns: GanttColumn[],\n firstColumnIndex: number\n ): HTMLElement {\n const rowEl = el(\"div\", \"gantt-grid-row\");\n rowEl.style.position = \"absolute\";\n rowEl.style.top = `${row.y}px`;\n rowEl.style.height = `${row.height}px`;\n rowEl.dataset.ganttRow = task.id;\n if (this.options.keyboardAccessible) {\n rowEl.setAttribute(\"role\", \"row\");\n }\n\n if (this.options.onRowReorder) {\n rowEl.draggable = true;\n rowEl.style.cursor = \"grab\";\n rowEl.addEventListener(\"dragstart\", (evt) => {\n evt.dataTransfer?.setData(\"text/plain\", task.id);\n evt.stopPropagation();\n });\n rowEl.addEventListener(\"dragover\", (evt) => {\n evt.preventDefault();\n evt.stopPropagation();\n });\n rowEl.addEventListener(\"drop\", (evt) => {\n evt.preventDefault();\n evt.stopPropagation();\n const draggedId = evt.dataTransfer?.getData(\"text/plain\");\n if (!draggedId || draggedId === task.id) return;\n const bounds = rowEl.getBoundingClientRect();\n const fraction = (evt.clientY - bounds.top) / bounds.height;\n const position = fraction < 0.25 ? \"before\" : fraction > 0.75 ? \"after\" : \"inside\";\n this.options.onRowReorder?.(draggedId, task.id, position);\n });\n }\n\n columns.forEach((col, colIndex) => {\n const cell = el(\"div\", \"gantt-grid-cell\");\n if (col.width) cell.style.width = `${col.width}px`;\n if (col.align) cell.style.textAlign = col.align;\n\n const rawValue = col.accessor ? col.accessor(task) : colIndex === 0 ? task.name : \"\";\n const textValue = rawValue === null || rawValue === undefined ? \"\" : String(rawValue);\n\n if (colIndex === 0) {\n cell.dataset.ganttNameCell = task.id;\n cell.dataset.ganttNameValue = textValue;\n const indent = el(\"span\", \"gantt-indent\");\n indent.style.width = `${row.depth * 16}px`;\n cell.appendChild(indent);\n if (row.hasChildren) {\n const toggle = el(\"button\", \"gantt-toggle\");\n toggle.type = \"button\";\n toggle.dataset.ganttToggle = task.id;\n toggle.setAttribute(\"aria-label\", row.collapsed ? \"Expand\" : \"Collapse\");\n toggle.textContent = row.collapsed ? \"▸\" : \"▾\";\n cell.appendChild(toggle);\n }\n }\n\n const rendered = col.render ? col.render(task) : undefined;\n if (rendered instanceof HTMLElement) {\n cell.appendChild(rendered);\n } else if (typeof rendered === \"string\") {\n cell.appendChild(document.createTextNode(rendered));\n } else {\n const href = col.getHref ? col.getHref(task) : null;\n if (href && isSafeHref(href)) {\n const anchor = document.createElement(\"a\");\n anchor.href = href;\n anchor.target = col.linkTarget ?? \"_blank\";\n anchor.rel = \"noopener noreferrer\";\n anchor.textContent = textValue;\n cell.appendChild(anchor);\n } else {\n const textNode = document.createTextNode(textValue);\n cell.appendChild(textNode);\n }\n }\n\n rowEl.appendChild(cell);\n });\n\n void firstColumnIndex;\n return rowEl;\n }\n\n private renderTimeline(model: GanttRenderModel, tasks: GanttTask[]): void {\n this.svg.replaceChildren();\n this.svg.setAttribute(\"width\", String(model.width));\n this.svg.setAttribute(\"height\", String(model.headerHeight + model.height));\n this.svg.setAttribute(\"viewBox\", `0 0 ${model.width} ${model.headerHeight + model.height}`);\n\n const defs = svgEl(\"defs\");\n const marker = svgEl(\"marker\");\n marker.setAttribute(\"id\", this.markerDefsId);\n marker.setAttribute(\"markerWidth\", \"8\");\n marker.setAttribute(\"markerHeight\", \"8\");\n marker.setAttribute(\"refX\", \"6\");\n marker.setAttribute(\"refY\", \"3\");\n marker.setAttribute(\"orient\", \"auto\");\n const arrowPath = svgEl(\"path\");\n arrowPath.setAttribute(\"d\", \"M0,0 L6,3 L0,6 Z\");\n arrowPath.style.fill = themedFill(\"linkColor\", model.theme.linkColor);\n marker.appendChild(arrowPath);\n defs.appendChild(marker);\n this.svg.appendChild(defs);\n\n const { startY, endY } = this.getViewportRowRange(model);\n\n const bodyGroup = svgEl(\"g\");\n bodyGroup.setAttribute(\"transform\", `translate(0, ${model.headerHeight})`);\n\n this.renderGridLines(bodyGroup, model);\n this.renderRowBackgrounds(bodyGroup, model, startY, endY);\n this.renderBars(bodyGroup, model, tasks, startY, endY);\n this.renderLinks(bodyGroup, model, startY, endY);\n this.renderMarkers(bodyGroup, model);\n this.svg.appendChild(bodyGroup);\n\n this.renderHeader(model);\n }\n\n private renderGridLines(group: SVGGElement, model: GanttRenderModel): void {\n for (const tick of model.ticks) {\n if (tick.isNonWorking) {\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", String(tick.x));\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", \"1\");\n rect.setAttribute(\"height\", String(model.height));\n rect.style.fill = themedFill(\"weekendColor\", model.theme.weekendColor);\n group.appendChild(rect);\n }\n const line = svgEl(\"line\");\n line.setAttribute(\"x1\", String(tick.x));\n line.setAttribute(\"x2\", String(tick.x));\n line.setAttribute(\"y1\", \"0\");\n line.setAttribute(\"y2\", String(model.height));\n line.style.stroke = themedFill(\"gridColor\", model.theme.gridColor);\n line.setAttribute(\"stroke-width\", tick.isMajorBoundary ? \"1.5\" : \"1\");\n group.appendChild(line);\n\n if (tick.isToday) {\n const todayLine = svgEl(\"line\");\n todayLine.setAttribute(\"x1\", String(tick.x));\n todayLine.setAttribute(\"x2\", String(tick.x));\n todayLine.setAttribute(\"y1\", \"0\");\n todayLine.setAttribute(\"y2\", String(model.height));\n todayLine.style.stroke = themedFill(\"todayColor\", model.theme.todayColor);\n todayLine.setAttribute(\"stroke-width\", \"2\");\n group.appendChild(todayLine);\n }\n }\n }\n\n private renderMarkers(group: SVGGElement, model: GanttRenderModel): void {\n for (const marker of model.markers) {\n const line = svgEl(\"line\");\n line.setAttribute(\"x1\", String(marker.x));\n line.setAttribute(\"x2\", String(marker.x));\n line.setAttribute(\"y1\", \"0\");\n line.setAttribute(\"y2\", String(model.height));\n line.setAttribute(\"stroke\", marker.color);\n line.setAttribute(\"stroke-width\", \"1.5\");\n line.setAttribute(\"stroke-dasharray\", \"3 3\");\n line.dataset.ganttMarker = marker.label;\n group.appendChild(line);\n\n if (marker.label) {\n const label = svgEl(\"text\");\n label.setAttribute(\"x\", String(marker.x + 4));\n label.setAttribute(\"y\", \"12\");\n label.setAttribute(\"fill\", marker.color);\n label.setAttribute(\"font-size\", String(model.theme.fontSize));\n label.setAttribute(\"font-family\", model.theme.fontFamily);\n label.textContent = marker.label;\n group.appendChild(label);\n }\n }\n }\n\n private renderHeader(model: GanttRenderModel): void {\n let headerGroup = this.svg.querySelector<SVGGElement>(\".gantt-header-group\");\n if (headerGroup) headerGroup.remove();\n headerGroup = svgEl(\"g\");\n headerGroup.setAttribute(\"class\", \"gantt-header-group\");\n const bg = svgEl(\"rect\");\n bg.setAttribute(\"x\", \"0\");\n bg.setAttribute(\"y\", \"0\");\n bg.setAttribute(\"width\", String(model.width));\n bg.setAttribute(\"height\", String(model.headerHeight));\n bg.style.fill = themedFill(\"backgroundColor\", model.theme.backgroundColor);\n headerGroup.appendChild(bg);\n\n for (const tick of model.ticks) {\n const text = svgEl(\"text\");\n text.setAttribute(\"x\", String(tick.x + 4));\n text.setAttribute(\"y\", String(model.headerHeight - 8));\n text.style.fill = themedFill(\"textColor\", model.theme.textColor);\n text.setAttribute(\"font-size\", String(model.theme.fontSize));\n text.setAttribute(\"font-family\", model.theme.fontFamily);\n text.textContent = tick.label;\n headerGroup.appendChild(text);\n }\n this.svg.appendChild(headerGroup);\n }\n\n /**\n * Invisible full-width hit-test rects, one per row, behind the bars. Lets\n * drag-to-create (InteractionController) find \"which row / empty timeline\n * space was this pointerdown on\" without needing its own copy of the\n * layout math - a bar drawn on top naturally wins the hit test where one exists.\n */\n private renderRowBackgrounds(\n group: SVGGElement,\n model: GanttRenderModel,\n startY: number,\n endY: number\n ): void {\n for (const row of model.rows) {\n if (row.y + row.height < startY || row.y > endY) continue;\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", String(row.y));\n rect.setAttribute(\"width\", String(model.width));\n rect.setAttribute(\"height\", String(row.height));\n rect.setAttribute(\"fill\", \"transparent\");\n rect.style.pointerEvents = \"all\";\n rect.dataset.ganttRowBg = row.taskId;\n group.appendChild(rect);\n }\n }\n\n private renderBars(\n group: SVGGElement,\n model: GanttRenderModel,\n tasks: GanttTask[],\n startY: number,\n endY: number\n ): void {\n const taskById = new Map(tasks.map((t) => [t.id, t]));\n for (const bar of model.bars) {\n if (bar.y + bar.height < startY || bar.y > endY) continue;\n const task = taskById.get(bar.taskId);\n group.appendChild(this.renderBar(bar, task, model));\n }\n }\n\n private renderBar(\n bar: GanttRenderBar,\n task: GanttTask | undefined,\n model: GanttRenderModel\n ): SVGGElement {\n const g = svgEl(\"g\");\n g.setAttribute(\"class\", \"gantt-bar\");\n g.dataset.ganttBar = bar.taskId;\n g.setAttribute(\"transform\", `translate(${bar.x}, ${bar.y})`);\n\n if (task?.notes) {\n const title = svgEl(\"title\");\n title.textContent = task.notes;\n g.appendChild(title);\n }\n\n if (this.options.keyboardAccessible) {\n g.setAttribute(\"tabindex\", \"0\");\n g.setAttribute(\"role\", \"button\");\n if (task) {\n const progress = Math.round(task.progress ?? 0);\n const label = `${task.name}, ${task.start.toDateString()} to ${task.end.toDateString()}, ${progress}% complete`;\n g.setAttribute(\"aria-label\", label);\n }\n }\n\n if (bar.baseline) {\n const baseline = svgEl(\"rect\");\n baseline.setAttribute(\"x\", String(bar.baseline.x - bar.x));\n baseline.setAttribute(\"y\", \"-2\");\n baseline.setAttribute(\"width\", String(bar.baseline.width));\n baseline.setAttribute(\"height\", String(bar.height + 4));\n baseline.style.fill = themedFill(\"baselineColor\", model.theme.baselineColor);\n baseline.setAttribute(\"opacity\", \"0.35\");\n baseline.setAttribute(\"rx\", String(model.theme.borderRadius));\n g.appendChild(baseline);\n }\n\n if (bar.baselines && bar.baselines.length > 0) {\n // Oldest snapshot stacked furthest back (largest offset), most recent nearest the live bar.\n bar.baselines.forEach((b, i) => {\n const offset = (bar.baselines!.length - i) * 2;\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", String(b.x - bar.x));\n rect.setAttribute(\"y\", String(-2 - offset));\n rect.setAttribute(\"width\", String(b.width));\n rect.setAttribute(\"height\", \"3\");\n rect.style.fill = themedFill(\"baselineColor\", model.theme.baselineColor);\n rect.setAttribute(\"opacity\", String(Math.max(0.15, 0.4 - i * 0.08)));\n if (b.label) {\n const title = svgEl(\"title\");\n title.textContent = b.label;\n rect.appendChild(title);\n }\n g.appendChild(rect);\n });\n }\n\n // task.color/progressColor are per-task JS overrides baked in by layout.ts — keep those\n // literal (highest priority, per-element). A bar left at the theme default is routed\n // through var(--gantt-x, default) instead, so plain CSS can restyle \"every default bar\".\n const isDefaultBarColor = bar.color === (task?.isGroup ? model.theme.groupBarColor : model.theme.barColor);\n const isDefaultProgressColor = bar.progressColor === model.theme.barProgressColor;\n const fillColor = bar.isCritical\n ? themedFill(\"criticalColor\", model.theme.criticalColor)\n : isDefaultBarColor\n ? themedFill(task?.isGroup ? \"groupBarColor\" : \"barColor\", bar.color)\n : bar.color;\n\n if (bar.isMilestone) {\n const size = bar.height * 0.8;\n const diamond = svgEl(\"rect\");\n diamond.setAttribute(\"x\", String(-size / 2));\n diamond.setAttribute(\"y\", String((bar.height - size) / 2));\n diamond.setAttribute(\"width\", String(size));\n diamond.setAttribute(\"height\", String(size));\n diamond.style.fill = fillColor;\n diamond.setAttribute(\n \"transform\",\n `rotate(45, 0, ${bar.height / 2})`\n );\n g.appendChild(diamond);\n const label = svgEl(\"text\");\n label.setAttribute(\"x\", String(size / 2 + 8));\n label.setAttribute(\"y\", String(bar.height / 2 + 4));\n label.style.fill = themedFill(\"textColor\", model.theme.textColor);\n label.setAttribute(\"font-size\", String(model.theme.fontSize));\n label.setAttribute(\"font-family\", model.theme.fontFamily);\n label.textContent = bar.label;\n g.appendChild(label);\n return g;\n }\n\n if (bar.segments && bar.segments.length > 0) {\n // Split task: draw each segment as its own body+progress rect, joined by a thin dashed connector.\n bar.segments.forEach((seg, i) => {\n const segRect = svgEl(\"rect\");\n segRect.setAttribute(\"x\", String(seg.x));\n segRect.setAttribute(\"y\", \"0\");\n segRect.setAttribute(\"width\", String(seg.width));\n segRect.setAttribute(\"height\", String(bar.height));\n segRect.setAttribute(\"rx\", String(model.theme.borderRadius));\n segRect.style.fill = fillColor;\n if (bar.isCritical) {\n segRect.style.stroke = themedFill(\"criticalColor\", model.theme.criticalColor);\n segRect.setAttribute(\"stroke-width\", \"1.5\");\n }\n g.appendChild(segRect);\n\n if (seg.progressWidth > 0) {\n const segProgress = svgEl(\"rect\");\n segProgress.setAttribute(\"x\", String(seg.x));\n segProgress.setAttribute(\"y\", \"0\");\n segProgress.setAttribute(\"width\", String(seg.progressWidth));\n segProgress.setAttribute(\"height\", String(bar.height));\n segProgress.setAttribute(\"rx\", String(model.theme.borderRadius));\n segProgress.style.fill = isDefaultProgressColor\n ? themedFill(\"barProgressColor\", bar.progressColor)\n : bar.progressColor;\n g.appendChild(segProgress);\n }\n\n const next = bar.segments![i + 1];\n if (next) {\n const connector = svgEl(\"line\");\n connector.setAttribute(\"x1\", String(seg.x + seg.width));\n connector.setAttribute(\"x2\", String(next.x));\n connector.setAttribute(\"y1\", String(bar.height / 2));\n connector.setAttribute(\"y2\", String(bar.height / 2));\n connector.style.stroke = fillColor;\n connector.setAttribute(\"stroke-width\", \"1.5\");\n connector.setAttribute(\"stroke-dasharray\", \"3 2\");\n g.appendChild(connector);\n }\n });\n } else {\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", String(bar.width));\n rect.setAttribute(\"height\", String(bar.height));\n rect.setAttribute(\"rx\", String(model.theme.borderRadius));\n rect.style.fill = fillColor;\n if (bar.isCritical) {\n rect.style.stroke = themedFill(\"criticalColor\", model.theme.criticalColor);\n rect.setAttribute(\"stroke-width\", \"1.5\");\n }\n g.appendChild(rect);\n\n if (bar.progressWidth > 0) {\n const progressRect = svgEl(\"rect\");\n progressRect.setAttribute(\"x\", \"0\");\n progressRect.setAttribute(\"y\", \"0\");\n progressRect.setAttribute(\"width\", String(bar.progressWidth));\n progressRect.setAttribute(\"height\", String(bar.height));\n progressRect.setAttribute(\"rx\", String(model.theme.borderRadius));\n progressRect.style.fill = isDefaultProgressColor\n ? themedFill(\"barProgressColor\", bar.progressColor)\n : bar.progressColor;\n g.appendChild(progressRect);\n }\n }\n\n if (bar.isSelected) {\n const selectionOutline = svgEl(\"rect\");\n selectionOutline.setAttribute(\"x\", \"-2\");\n selectionOutline.setAttribute(\"y\", \"-2\");\n selectionOutline.setAttribute(\"width\", String(bar.width + 4));\n selectionOutline.setAttribute(\"height\", String(bar.height + 4));\n selectionOutline.setAttribute(\"rx\", String(model.theme.borderRadius + 2));\n selectionOutline.setAttribute(\"fill\", \"none\");\n selectionOutline.style.stroke = themedFill(\"selectionColor\", model.theme.selectionColor);\n selectionOutline.setAttribute(\"stroke-width\", \"2\");\n g.appendChild(selectionOutline);\n }\n\n const handleWidth = 6;\n const leftHandle = svgEl(\"rect\");\n leftHandle.setAttribute(\"x\", \"0\");\n leftHandle.setAttribute(\"y\", \"0\");\n leftHandle.setAttribute(\"width\", String(handleWidth));\n leftHandle.setAttribute(\"height\", String(bar.height));\n leftHandle.setAttribute(\"fill\", \"transparent\");\n leftHandle.dataset.ganttHandle = \"left\";\n leftHandle.dataset.ganttHandleFor = bar.taskId;\n leftHandle.style.cursor = \"ew-resize\";\n g.appendChild(leftHandle);\n\n const rightHandle = svgEl(\"rect\");\n rightHandle.setAttribute(\"x\", String(Math.max(0, bar.width - handleWidth)));\n rightHandle.setAttribute(\"y\", \"0\");\n rightHandle.setAttribute(\"width\", String(handleWidth));\n rightHandle.setAttribute(\"height\", String(bar.height));\n rightHandle.setAttribute(\"fill\", \"transparent\");\n rightHandle.dataset.ganttHandle = \"right\";\n rightHandle.dataset.ganttHandleFor = bar.taskId;\n rightHandle.style.cursor = \"ew-resize\";\n g.appendChild(rightHandle);\n\n const connector = svgEl(\"circle\");\n connector.setAttribute(\"cx\", String(bar.width));\n connector.setAttribute(\"cy\", String(bar.height / 2));\n connector.setAttribute(\"r\", \"4\");\n connector.style.fill = themedFill(\"linkColor\", model.theme.linkColor);\n connector.dataset.ganttConnector = bar.taskId;\n connector.dataset.ganttConnectorSide = \"right\";\n connector.style.cursor = \"crosshair\";\n g.appendChild(connector);\n\n const label = svgEl(\"text\");\n label.setAttribute(\"x\", String(bar.width + 6));\n label.setAttribute(\"y\", String(bar.height / 2 + 4));\n label.style.fill = themedFill(\"textColor\", model.theme.textColor);\n label.setAttribute(\"font-size\", String(model.theme.fontSize));\n label.setAttribute(\"font-family\", model.theme.fontFamily);\n label.textContent = bar.label;\n g.appendChild(label);\n\n if (bar.deadlineX !== undefined) {\n const markerX = bar.deadlineX - bar.x;\n const flag = svgEl(\"g\");\n flag.setAttribute(\"transform\", `translate(${markerX}, -6)`);\n const pole = svgEl(\"line\");\n pole.setAttribute(\"x1\", \"0\");\n pole.setAttribute(\"x2\", \"0\");\n pole.setAttribute(\"y1\", \"0\");\n pole.setAttribute(\"y2\", String(bar.height + 6));\n const deadlineColor = bar.isOverdue\n ? themedFill(\"criticalColor\", model.theme.criticalColor)\n : themedFill(\"deadlineColor\", model.theme.deadlineColor);\n pole.style.stroke = deadlineColor;\n pole.setAttribute(\"stroke-width\", \"1.5\");\n flag.appendChild(pole);\n const pennant = svgEl(\"path\");\n pennant.setAttribute(\"d\", \"M0,0 L7,3 L0,6 Z\");\n pennant.style.fill = deadlineColor;\n flag.appendChild(pennant);\n g.appendChild(flag);\n }\n\n if (this.options.showAssigneeAvatars && task?.assignees?.length) {\n let ax = -10;\n for (const assignee of task.assignees.slice(0, 3)) {\n const avatarGroup = svgEl(\"g\");\n avatarGroup.setAttribute(\"transform\", `translate(${ax}, ${bar.height / 2})`);\n if (assignee.avatarUrl) {\n const image = svgEl(\"image\");\n image.setAttribute(\"href\", assignee.avatarUrl);\n image.setAttribute(\"x\", \"-8\");\n image.setAttribute(\"y\", \"-8\");\n image.setAttribute(\"width\", \"16\");\n image.setAttribute(\"height\", \"16\");\n image.setAttribute(\"clip-path\", \"circle(8px at 8px 8px)\");\n avatarGroup.appendChild(image);\n } else {\n const circle = svgEl(\"circle\");\n circle.setAttribute(\"r\", \"8\");\n circle.style.fill = assignee.color ?? themedFill(\"groupBarColor\", model.theme.groupBarColor);\n avatarGroup.appendChild(circle);\n const text = svgEl(\"text\");\n text.setAttribute(\"text-anchor\", \"middle\");\n text.setAttribute(\"y\", \"3\");\n text.setAttribute(\"font-size\", \"8\");\n text.setAttribute(\"fill\", \"#fff\");\n text.textContent = initials(assignee.name);\n avatarGroup.appendChild(text);\n }\n g.appendChild(avatarGroup);\n ax -= 18;\n }\n }\n\n return g;\n }\n\n private renderLinks(\n group: SVGGElement,\n model: GanttRenderModel,\n startY: number,\n endY: number\n ): void {\n const barByTaskId = new Map(model.bars.map((b) => [b.taskId, b]));\n for (const link of model.links) {\n const fromBar = barByTaskId.get(link.fromId);\n const toBar = barByTaskId.get(link.toId);\n const relevantY = toBar?.y ?? fromBar?.y ?? 0;\n if (relevantY < startY || relevantY > endY) continue;\n\n const path = svgEl(\"path\");\n path.setAttribute(\"d\", link.path);\n path.setAttribute(\"fill\", \"none\");\n path.style.stroke = link.isCritical\n ? themedFill(\"criticalColor\", model.theme.criticalColor)\n : themedFill(\"linkColor\", model.theme.linkColor);\n path.setAttribute(\"stroke-width\", link.isCritical ? \"2\" : \"1.5\");\n path.setAttribute(\"marker-end\", `url(#${this.markerDefsId})`);\n path.dataset.ganttLink = `${link.fromId}->${link.toId}`;\n group.appendChild(path);\n }\n }\n\n toSVGString(): string {\n return new XMLSerializer().serializeToString(this.svg);\n }\n\n destroy(): void {\n if (this.scrollListener) {\n this.timelineScroll.removeEventListener(\"scroll\", this.scrollListener);\n }\n this.gridPanel.removeEventListener(\"dblclick\", this.onGridDoubleClick);\n this.root.remove();\n }\n}\n","import type { GanttTask } from \"./types\";\n\n/** A readable, colorblind-considerate categorical palette; cycles if there are more distinct values than colors. */\nexport const DEFAULT_PALETTE = [\n \"#3b82f6\", // blue\n \"#f59e0b\", // amber\n \"#10b981\", // emerald\n \"#ef4444\", // red\n \"#8b5cf6\", // violet\n \"#06b6d4\", // cyan\n \"#f97316\", // orange\n \"#84cc16\", // lime\n \"#ec4899\", // pink\n \"#64748b\", // slate\n];\n\n/**\n * Assign a stable color to each distinct value of `field(task)` across `tasks`,\n * cycling through `palette` in first-seen order. Pure - returns a lookup map,\n * doesn't touch the tasks themselves (use with `applyColorByField` or your own\n * `task.color = colors.get(field(task))` loop).\n */\nexport function colorByField(\n tasks: GanttTask[],\n field: (task: GanttTask) => string | null | undefined,\n palette: string[] = DEFAULT_PALETTE\n): Map<string, string> {\n const colors = new Map<string, string>();\n if (palette.length === 0) return colors;\n for (const task of tasks) {\n const value = field(task);\n if (value === null || value === undefined || colors.has(value)) continue;\n colors.set(value, palette[colors.size % palette.length]!);\n }\n return colors;\n}\n\n/** Convenience wrapper: returns a new tasks array with `.color` set from `colorByField`'s result (a task's existing `.color` wins if already set). */\nexport function applyColorByField(\n tasks: GanttTask[],\n field: (task: GanttTask) => string | null | undefined,\n palette: string[] = DEFAULT_PALETTE\n): GanttTask[] {\n const colors = colorByField(tasks, field, palette);\n return tasks.map((task) => {\n if (task.color) return task;\n const value = field(task);\n const color = value === null || value === undefined ? undefined : colors.get(value);\n return color ? { ...task, color } : task;\n });\n}\n","/**\n * MSP-style task constraint types.\n *\n * \"asap\" and \"alap\" are intentionally no-ops in this engine: a true ALAP\n * (as-late-as-possible) schedule requires a backward pass from the project\n * end date, which isn't something a purely local, per-drag/per-cascade\n * engine can do without a full re-solve. The other six are hard date\n * constraints applied locally, which fit the same incremental model used\n * by dependency cascading.\n */\nexport type ConstraintType =\n | \"asap\"\n | \"alap\"\n | \"snet\" // start no earlier than\n | \"snlt\" // start no later than\n | \"fnet\" // finish no earlier than\n | \"fnlt\" // finish no later than\n | \"mso\" // must start on\n | \"mfo\"; // must finish on\n\nexport interface DateRange {\n start: Date;\n end: Date;\n}\n\n/**\n * Adjust [start, end] to satisfy a constraint, preserving the task's\n * duration. No-op if `constraintType` or `constraintDate` is unset, or the\n * range already satisfies the constraint.\n */\nexport function applyConstraint(\n range: DateRange,\n constraintType: ConstraintType | undefined,\n constraintDate: Date | undefined\n): DateRange {\n if (!constraintType || !constraintDate) return range;\n const duration = range.end.getTime() - range.start.getTime();\n const cd = constraintDate.getTime();\n\n switch (constraintType) {\n case \"mso\":\n return { start: new Date(cd), end: new Date(cd + duration) };\n case \"mfo\":\n return { start: new Date(cd - duration), end: new Date(cd) };\n case \"snet\":\n if (range.start.getTime() >= cd) return range;\n return { start: new Date(cd), end: new Date(cd + duration) };\n case \"snlt\":\n if (range.start.getTime() <= cd) return range;\n return { start: new Date(cd), end: new Date(cd + duration) };\n case \"fnet\":\n if (range.end.getTime() >= cd) return range;\n return { start: new Date(cd - duration), end: new Date(cd) };\n case \"fnlt\":\n if (range.end.getTime() <= cd) return range;\n return { start: new Date(cd - duration), end: new Date(cd) };\n case \"asap\":\n case \"alap\":\n return range;\n }\n}\n","import type { GanttTask } from \"./types\";\n\n/**\n * Compute Work Breakdown Structure codes (\"1\", \"1.1\", \"1.2\", \"2\", ...) from\n * task parent/child nesting, in document (array) order among siblings.\n *\n * Returned as a plain Map rather than mutating tasks, matching the library's\n * \"everything is a plain object, the chart never owns your state\" principle -\n * wire it into a grid column via `column.accessor` if you want it displayed:\n *\n * const wbs = computeWBSCodes(tasks);\n * columns: [{ id: \"wbs\", title: \"WBS\", accessor: (t) => wbs.get(t.id) }]\n *\n * A task whose `parentId` doesn't resolve to another task in the list is\n * treated as a root, same as an unset `parentId`.\n */\nexport function computeWBSCodes(tasks: GanttTask[]): Map<string, string> {\n const ids = new Set(tasks.map((t) => t.id));\n const effectiveParent = (task: GanttTask): string | null =>\n task.parentId && ids.has(task.parentId) ? task.parentId : null;\n\n const childrenByParent = new Map<string | null, GanttTask[]>();\n for (const task of tasks) {\n const key = effectiveParent(task);\n const list = childrenByParent.get(key) ?? [];\n list.push(task);\n childrenByParent.set(key, list);\n }\n\n const codes = new Map<string, string>();\n function assign(parentId: string | null, prefix: string): void {\n const children = childrenByParent.get(parentId) ?? [];\n children.forEach((task, index) => {\n const code = prefix ? `${prefix}.${index + 1}` : `${index + 1}`;\n codes.set(task.id, code);\n assign(task.id, code);\n });\n }\n assign(null, \"\");\n\n return codes;\n}\n","import { isWorkingDay, type WorkingCalendar } from \"./calendar\";\nimport { MS_PER_DAY } from \"./date-utils\";\nimport type { GanttTask } from \"./types\";\n\nexport interface ResourceHistogramOptions {\n /** hours a resource is assumed available per working day. Default 8. */\n capacityHoursPerDay?: number;\n /** governs which days count as \"working\" for allocation purposes. Non-working days get 0 load. */\n calendar?: WorkingCalendar;\n}\n\nexport interface ResourceLoadBucket {\n assigneeId: string;\n assigneeName: string;\n /** start of the day this bucket represents */\n date: Date;\n /** hours allocated to this assignee across all tasks spanning this day */\n allocatedHours: number;\n capacityHours: number;\n overallocated: boolean;\n}\n\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/**\n * Bucket every task's assignees by calendar day, summing one full day's\n * capacity worth of allocation per assignee per working day the task spans\n * (milestones and non-working days contribute nothing). This is a simple\n * \"fully allocated while active\" model, not a percent-effort model - tasks\n * don't carry an effort/FTE field, so it's the only allocation the plain\n * task/assignee data can support without inventing new required fields.\n */\nexport function computeResourceHistogram(\n tasks: GanttTask[],\n options: ResourceHistogramOptions = {}\n): ResourceLoadBucket[] {\n const capacityHours = options.capacityHoursPerDay ?? 8;\n const buckets = new Map<string, ResourceLoadBucket>(); // key: `${assigneeId}|${isoDay}`\n\n for (const task of tasks) {\n if (!task.assignees || task.assignees.length === 0) continue;\n if (!(task.start instanceof Date) || !(task.end instanceof Date)) continue;\n if (task.end.getTime() <= task.start.getTime()) continue; // milestone or zero-length\n\n let cursor = startOfDay(task.start);\n const end = task.end;\n let guard = 0;\n while (cursor.getTime() < end.getTime() && guard++ < 3660) {\n if (isWorkingDay(cursor, options.calendar)) {\n for (const assignee of task.assignees) {\n const key = `${assignee.id}|${cursor.getTime()}`;\n const existing = buckets.get(key);\n if (existing) {\n existing.allocatedHours += capacityHours;\n } else {\n buckets.set(key, {\n assigneeId: assignee.id,\n assigneeName: assignee.name,\n date: new Date(cursor.getTime()),\n allocatedHours: capacityHours,\n capacityHours,\n overallocated: false,\n });\n }\n }\n }\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n }\n }\n\n const result = Array.from(buckets.values());\n for (const bucket of result) {\n bucket.overallocated = bucket.allocatedHours > bucket.capacityHours;\n }\n result.sort((a, b) => a.date.getTime() - b.date.getTime() || a.assigneeId.localeCompare(b.assigneeId));\n return result;\n}\n\n/**\n * Render a resource histogram as a standalone SVG string: one grouped column\n * of stacked bars per day, one bar per assignee, red when overallocated.\n * Framework-agnostic like the rest of gantt-core - drop the string into an\n * `<div>` via `innerHTML` or a data URI, no DOM dependency required to call it.\n */\nexport function renderResourceHistogramSVG(\n buckets: ResourceLoadBucket[],\n options: { width?: number; barWidth?: number; maxBarHeight?: number; overallocatedColor?: string; barColor?: string } = {}\n): string {\n const barWidth = options.barWidth ?? 14;\n const gap = 4;\n const maxBarHeight = options.maxBarHeight ?? 120;\n const barColor = options.barColor ?? \"#3b82f6\";\n const overColor = options.overallocatedColor ?? \"#dc2626\";\n\n const days = Array.from(new Set(buckets.map((b) => b.date.getTime()))).sort((a, b) => a - b);\n const assigneesByDay = new Map<number, ResourceLoadBucket[]>();\n for (const b of buckets) {\n const list = assigneesByDay.get(b.date.getTime()) ?? [];\n list.push(b);\n assigneesByDay.set(b.date.getTime(), list);\n }\n\n const maxHours = buckets.reduce((m, b) => Math.max(m, b.allocatedHours), 1);\n const dayWidth = (assigneesByDay.get(days[0] ?? 0)?.length ?? 1) * (barWidth + gap) + gap;\n const width = options.width ?? Math.max(dayWidth * days.length, 100);\n const height = maxBarHeight + 24;\n\n const parts: string[] = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">`,\n ];\n\n days.forEach((day, dayIndex) => {\n const dayBuckets = assigneesByDay.get(day) ?? [];\n dayBuckets.forEach((b, i) => {\n const x = dayIndex * dayWidth + gap + i * (barWidth + gap);\n const barHeight = Math.min(maxBarHeight, (b.allocatedHours / maxHours) * maxBarHeight);\n const y = maxBarHeight - barHeight;\n const fill = b.overallocated ? overColor : barColor;\n parts.push(\n `<rect x=\"${x}\" y=\"${y}\" width=\"${barWidth}\" height=\"${barHeight}\" fill=\"${fill}\"><title>${escapeXml(\n b.assigneeName\n )}: ${b.allocatedHours}h</title></rect>`\n );\n });\n });\n\n parts.push(`</svg>`);\n return parts.join(\"\");\n}\n\nfunction escapeXml(text: string): string {\n return text.replace(/[&<>\"']/g, (c) => {\n switch (c) {\n case \"&\":\n return \"&\";\n case \"<\":\n return \"<\";\n case \">\":\n return \">\";\n case '\"':\n return \""\";\n default:\n return \"'\";\n }\n });\n}\n","import type { GanttTask } from \"./types\";\n\nexport interface FilterTasksOptions {\n /** keep ancestors of a matched task so its tree path stays intact. Default true. */\n includeAncestors?: boolean;\n /** keep descendants of a matched task (e.g. a matched group's children). Default true. */\n includeDescendants?: boolean;\n}\n\nexport interface FilterTasksResult {\n /** the subset of `tasks` to keep, in original order - pass straight to the chart's `tasks` prop/setTasks to hide the rest */\n tasks: GanttTask[];\n /** ids that satisfied `predicate` directly, as opposed to being pulled in via includeAncestors/includeDescendants - use to dim rows that are shown only for tree context */\n matchedIds: Set<string>;\n}\n\n/**\n * Filter tasks by a predicate while keeping the tree intact: a matched\n * task's ancestors stay (so it doesn't vanish along with a non-matching\n * parent) and, by default, its descendants stay too (so a matched group\n * doesn't show with its children silently missing).\n *\n * This only computes the subset - hook it up by passing `result.tasks` as\n * the chart's `tasks` (non-matches are hidden because they're no longer in\n * the array, same as any other plain-data filter), and optionally use\n * `result.matchedIds` to visually dim tasks that are present only for tree\n * context (e.g. via a `column.accessor` or `task.color` override).\n */\nexport function filterTasks(\n tasks: GanttTask[],\n predicate: (task: GanttTask) => boolean,\n options: FilterTasksOptions = {}\n): FilterTasksResult {\n const includeAncestors = options.includeAncestors ?? true;\n const includeDescendants = options.includeDescendants ?? true;\n\n const byId = new Map(tasks.map((t) => [t.id, t]));\n const matchedIds = new Set(tasks.filter(predicate).map((t) => t.id));\n const keep = new Set(matchedIds);\n\n if (includeAncestors) {\n for (const id of matchedIds) {\n let current = byId.get(id);\n while (current?.parentId) {\n const parent = byId.get(current.parentId);\n if (!parent || keep.has(parent.id)) break;\n keep.add(parent.id);\n current = parent;\n }\n }\n }\n\n if (includeDescendants) {\n const childrenByParent = new Map<string, GanttTask[]>();\n for (const t of tasks) {\n if (!t.parentId) continue;\n const list = childrenByParent.get(t.parentId) ?? [];\n list.push(t);\n childrenByParent.set(t.parentId, list);\n }\n const stack = Array.from(matchedIds);\n while (stack.length > 0) {\n const id = stack.pop();\n if (id === undefined) continue;\n for (const child of childrenByParent.get(id) ?? []) {\n if (keep.has(child.id)) continue;\n keep.add(child.id);\n stack.push(child.id);\n }\n }\n }\n\n return { tasks: tasks.filter((t) => keep.has(t.id)), matchedIds };\n}\n","import { isWorkingDay, type WorkingCalendar } from \"./calendar\";\nimport { MS_PER_DAY } from \"./date-utils\";\nimport type { GanttDependency, GanttTask } from \"./types\";\n\nexport interface ResourceLevelingOptions {\n calendar?: WorkingCalendar;\n}\n\nexport interface ResourceLevelingResult {\n /** same tasks, same order - shifted ones are shallow clones with new start/end (duration preserved) */\n tasks: GanttTask[];\n shifted: { taskId: string; delayMs: number }[];\n}\n\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction workingDaySpan(start: Date, end: Date, calendar?: WorkingCalendar): number[] {\n const days: number[] = [];\n let cursor = startOfDay(start);\n let guard = 0;\n while (cursor.getTime() < end.getTime() && guard++ < 3660) {\n if (isWorkingDay(cursor, calendar)) days.push(cursor.getTime());\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n }\n return days;\n}\n\n/**\n * Resolve resource overallocation by delaying tasks (never pulling them\n * earlier) so no assignee is placed on more than one task on the same\n * working day - the same \"fully allocated while active\" model\n * computeResourceHistogram uses, so a leveled schedule always shows zero\n * `overallocated` buckets afterward.\n *\n * Tasks are processed in an order that respects FS (\"finish-to-start\")\n * dependencies (a task never gets placed before its FS predecessors\n * finish); SS/FF/SF dependencies aren't specifically enforced by the\n * leveler - a reasonable, documented scope limit rather than a full\n * constraint solver.\n */\nexport function levelResources(\n tasks: GanttTask[],\n dependencies: GanttDependency[],\n options: ResourceLevelingOptions = {}\n): ResourceLevelingResult {\n const calendar = options.calendar;\n const byId = new Map(tasks.map((t) => [t.id, t]));\n\n const fsPredecessors = new Map<string, string[]>();\n const fsSuccessors = new Map<string, string[]>();\n for (const dep of dependencies) {\n if (dep.type !== \"FS\") continue;\n if (!byId.has(dep.fromId) || !byId.has(dep.toId)) continue;\n const preds = fsPredecessors.get(dep.toId) ?? [];\n preds.push(dep.fromId);\n fsPredecessors.set(dep.toId, preds);\n const succs = fsSuccessors.get(dep.fromId) ?? [];\n succs.push(dep.toId);\n fsSuccessors.set(dep.fromId, succs);\n }\n\n // Kahn's-algorithm topological order over the FS subgraph, ties broken by original start date.\n const indegree = new Map<string, number>();\n for (const t of tasks) indegree.set(t.id, (fsPredecessors.get(t.id) ?? []).length);\n const queue = tasks.filter((t) => indegree.get(t.id) === 0);\n const order: GanttTask[] = [];\n const seen = new Set<string>();\n let guard = 0;\n while (queue.length > 0 && guard++ < tasks.length * 2 + 10) {\n queue.sort((a, b) => a.start.getTime() - b.start.getTime());\n const t = queue.shift();\n if (!t || seen.has(t.id)) continue;\n seen.add(t.id);\n order.push(t);\n for (const nextId of fsSuccessors.get(t.id) ?? []) {\n const d = (indegree.get(nextId) ?? 0) - 1;\n indegree.set(nextId, d);\n if (d === 0) {\n const nt = byId.get(nextId);\n if (nt) queue.push(nt);\n }\n }\n }\n for (const t of tasks) if (!seen.has(t.id)) order.push(t); // cycle fallback: keep original order\n\n const placedById = new Map<string, { start: Date; end: Date }>();\n const occupiedDays = new Map<string, Set<number>>(); // assigneeId -> set of working-day timestamps\n const shifted: ResourceLevelingResult[\"shifted\"] = [];\n\n for (const task of order) {\n const duration = task.end.getTime() - task.start.getTime();\n let start = new Date(task.start.getTime());\n\n for (const predId of fsPredecessors.get(task.id) ?? []) {\n const placed = placedById.get(predId);\n if (placed && placed.end.getTime() > start.getTime()) start = new Date(placed.end.getTime());\n }\n\n if (task.assignees && task.assignees.length > 0 && duration > 0) {\n let levelGuard = 0;\n while (levelGuard++ < 400) {\n const end = new Date(start.getTime() + duration);\n const days = workingDaySpan(start, end, calendar);\n const conflict = task.assignees.some((a) => {\n const set = occupiedDays.get(a.id);\n return set && days.some((d) => set.has(d));\n });\n if (!conflict) break;\n start = new Date(start.getTime() + MS_PER_DAY);\n while (!isWorkingDay(start, calendar)) start = new Date(start.getTime() + MS_PER_DAY);\n }\n const end = new Date(start.getTime() + duration);\n const days = workingDaySpan(start, end, calendar);\n for (const a of task.assignees) {\n const set = occupiedDays.get(a.id) ?? new Set<number>();\n for (const d of days) set.add(d);\n occupiedDays.set(a.id, set);\n }\n }\n\n const end = new Date(start.getTime() + duration);\n placedById.set(task.id, { start, end });\n const delayMs = start.getTime() - task.start.getTime();\n if (delayMs !== 0) shifted.push({ taskId: task.id, delayMs });\n }\n\n const resultById = new Map<string, GanttTask>();\n for (const task of order) {\n const placed = placedById.get(task.id);\n resultById.set(task.id, placed && placed.start.getTime() !== task.start.getTime() ? { ...task, ...placed } : task);\n }\n\n return { tasks: tasks.map((t) => resultById.get(t.id) ?? t), shifted };\n}\n","import { addUnit, MS_PER_DAY } from \"./date-utils\";\nimport type { ViewMode } from \"./types\";\n\nexport interface InteractionCallbacks {\n onMove(taskId: string, dxMs: number): void;\n onResize(taskId: string, edge: \"left\" | \"right\", dxMs: number): void;\n onLinkStart(taskId: string, anchor: \"left\" | \"right\"): void;\n onLinkComplete(fromId: string, toId: string): void;\n onLinkCancel(): void;\n onToggleCollapse(taskId: string): void;\n onBarClick(taskId: string, modifiers?: { ctrlKey: boolean; metaKey: boolean; shiftKey: boolean }): void;\n onProgressDrag(taskId: string, newProgress: number): void;\n onContextMenu?(taskId: string, evt: PointerEvent): void;\n /** fired on pointerup after a drag-to-create gesture on an empty row; x's are svg-relative px */\n onCreateTaskDrag?(rowTaskId: string, startXPx: number, endXPx: number): void;\n /** fired on double-click of a dependency link path */\n onLinkDblClick?(fromId: string, toId: string): void;\n /** Ctrl/Cmd+A anywhere in the chart, when keyboardAccessible */\n onSelectAll?(): void;\n /** Home anywhere in the chart, when keyboardAccessible */\n onJumpToStart?(): void;\n /** End anywhere in the chart, when keyboardAccessible */\n onJumpToEnd?(): void;\n}\n\nexport interface InteractionOptions {\n readonly?: boolean;\n isTaskReadonly?: (taskId: string) => boolean;\n keyboardAccessible?: boolean;\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n pxPerMs: () => number;\n}\n\ntype DragMode = \"move\" | \"resize-left\" | \"resize-right\" | \"link\" | \"create\" | null;\n\nfunction snapDeltaMs(dxMs: number, snapToUnit: InteractionOptions[\"snapToUnit\"]): number {\n if (!snapToUnit) return dxMs;\n const base = new Date(0);\n const unitMs = addUnit(base, snapToUnit as ViewMode, 1).getTime() - base.getTime();\n if (unitMs <= 0) return dxMs;\n return Math.round(dxMs / unitMs) * unitMs;\n}\n\nexport class InteractionController {\n private dragMode: DragMode = null;\n private dragTaskId: string | null = null;\n private dragStartX = 0;\n private linkFromId: string | null = null;\n private linkFromAnchor: \"left\" | \"right\" | null = null;\n private tempLinkEl: SVGLineElement | null = null;\n private rafHandle: number | null = null;\n private pendingDxMs = 0;\n private pendingMode: \"move\" | \"resize-left\" | \"resize-right\" | null = null;\n\n constructor(\n private svg: SVGSVGElement,\n private gridPanel: HTMLElement,\n private callbacks: InteractionCallbacks,\n private options: InteractionOptions\n ) {\n this.attach();\n }\n\n private isReadonly(taskId: string): boolean {\n if (this.options.readonly) return true;\n return this.options.isTaskReadonly?.(taskId) ?? false;\n }\n\n private attach(): void {\n this.svg.addEventListener(\"pointerdown\", this.onPointerDown);\n this.gridPanel.addEventListener(\"click\", this.onGridClick);\n if (typeof document !== \"undefined\") {\n this.svg.addEventListener(\"contextmenu\", this.onContextMenu);\n this.svg.addEventListener(\"dblclick\", this.onSvgDoubleClick);\n this.svg.addEventListener(\"keydown\", this.onKeyDown);\n }\n }\n\n destroy(): void {\n this.svg.removeEventListener(\"pointerdown\", this.onPointerDown);\n this.gridPanel.removeEventListener(\"click\", this.onGridClick);\n this.svg.removeEventListener(\"contextmenu\", this.onContextMenu);\n this.svg.removeEventListener(\"dblclick\", this.onSvgDoubleClick);\n this.svg.removeEventListener(\"keydown\", this.onKeyDown);\n if (this.rafHandle !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(this.rafHandle);\n }\n }\n\n private onGridClick = (evt: MouseEvent): void => {\n const target = evt.target as HTMLElement;\n const toggleId = target.closest<HTMLElement>(\"[data-gantt-toggle]\")?.dataset.ganttToggle;\n if (toggleId) {\n this.callbacks.onToggleCollapse(toggleId);\n }\n };\n\n private onContextMenu = (evt: Event): void => {\n const pointerEvt = evt as PointerEvent;\n const target = pointerEvt.target as Element;\n const barGroup = target.closest<SVGGElement>(\"[data-gantt-bar]\");\n const taskId = barGroup?.dataset.ganttBar;\n if (taskId && this.callbacks.onContextMenu) {\n pointerEvt.preventDefault();\n this.callbacks.onContextMenu(taskId, pointerEvt);\n }\n };\n\n private onSvgDoubleClick = (evt: MouseEvent): void => {\n if (!this.callbacks.onLinkDblClick) return;\n const target = evt.target as Element;\n const linkPath = target.closest<SVGPathElement>(\"[data-gantt-link]\");\n const key = linkPath?.dataset.ganttLink;\n if (!key) return;\n const [fromId, toId] = key.split(\"->\");\n if (fromId && toId) this.callbacks.onLinkDblClick(fromId, toId);\n };\n\n private onPointerDown = (evt: PointerEvent): void => {\n const target = evt.target as Element;\n\n const connector = target.closest<SVGCircleElement>(\"[data-gantt-connector]\");\n if (connector) {\n const taskId = connector.dataset.ganttConnector;\n const side = (connector.dataset.ganttConnectorSide as \"left\" | \"right\") ?? \"right\";\n if (taskId) this.startLinkDrag(evt, taskId, side);\n return;\n }\n\n const handle = target.closest<SVGRectElement>(\"[data-gantt-handle]\");\n if (handle) {\n const taskId = handle.dataset.ganttHandleFor;\n const edge = handle.dataset.ganttHandle as \"left\" | \"right\";\n if (taskId && !this.isReadonly(taskId)) this.startResize(evt, taskId, edge);\n return;\n }\n\n const barGroup = target.closest<SVGGElement>(\"[data-gantt-bar]\");\n if (barGroup) {\n const taskId = barGroup.dataset.ganttBar;\n if (taskId) this.startMove(evt, taskId, barGroup);\n return;\n }\n\n const rowBg = target.closest<SVGRectElement>(\"[data-gantt-row-bg]\");\n if (rowBg && this.callbacks.onCreateTaskDrag && !this.options.readonly) {\n const taskId = rowBg.dataset.ganttRowBg;\n if (taskId) this.startCreateDrag(evt, taskId, rowBg);\n }\n };\n\n private startMove(evt: PointerEvent, taskId: string, barGroup: SVGGElement): void {\n if (this.isReadonly(taskId)) return;\n this.dragMode = \"move\";\n this.dragTaskId = taskId;\n this.dragStartX = evt.clientX;\n let moved = false;\n barGroup.setPointerCapture(evt.pointerId);\n\n const onMove = (moveEvt: PointerEvent) => {\n const dx = moveEvt.clientX - this.dragStartX;\n if (Math.abs(dx) > 2) moved = true;\n this.scheduleDeltaEmit(taskId, \"move\", dx);\n };\n const onUp = (upEvt: PointerEvent) => {\n barGroup.removeEventListener(\"pointermove\", onMove);\n barGroup.removeEventListener(\"pointerup\", onUp);\n this.flushPending();\n this.dragMode = null;\n this.dragTaskId = null;\n if (!moved) {\n this.callbacks.onBarClick(taskId, {\n ctrlKey: upEvt.ctrlKey,\n metaKey: upEvt.metaKey,\n shiftKey: upEvt.shiftKey,\n });\n }\n };\n barGroup.addEventListener(\"pointermove\", onMove);\n barGroup.addEventListener(\"pointerup\", onUp);\n }\n\n private startResize(evt: PointerEvent, taskId: string, edge: \"left\" | \"right\"): void {\n this.dragMode = edge === \"left\" ? \"resize-left\" : \"resize-right\";\n this.dragTaskId = taskId;\n this.dragStartX = evt.clientX;\n const target = evt.currentTarget as Element;\n const capture = target instanceof Element ? target : this.svg;\n (capture as SVGRectElement).setPointerCapture?.(evt.pointerId);\n\n const onMove = (moveEvt: PointerEvent) => {\n const dx = moveEvt.clientX - this.dragStartX;\n this.scheduleDeltaEmit(taskId, edge === \"left\" ? \"resize-left\" : \"resize-right\", dx);\n };\n const onUp = () => {\n this.svg.removeEventListener(\"pointermove\", onMove);\n this.svg.removeEventListener(\"pointerup\", onUp);\n this.flushPending();\n this.dragMode = null;\n this.dragTaskId = null;\n };\n this.svg.addEventListener(\"pointermove\", onMove);\n this.svg.addEventListener(\"pointerup\", onUp);\n }\n\n private scheduleDeltaEmit(\n taskId: string,\n mode: \"move\" | \"resize-left\" | \"resize-right\",\n dxPx: number\n ): void {\n const pxPerMs = this.options.pxPerMs();\n const dxMs = pxPerMs > 0 ? dxPx / pxPerMs : 0;\n this.pendingDxMs = snapDeltaMs(dxMs, this.options.snapToUnit);\n this.pendingMode = mode;\n if (this.rafHandle !== null) return;\n const raf =\n typeof requestAnimationFrame !== \"undefined\" ? requestAnimationFrame : (cb: () => void) => {\n cb();\n return 0;\n };\n this.rafHandle = raf(() => {\n this.rafHandle = null;\n if (!this.dragTaskId || !this.pendingMode) return;\n if (this.pendingMode === \"move\") {\n this.callbacks.onMove(taskId, this.pendingDxMs);\n } else {\n this.callbacks.onResize(\n taskId,\n this.pendingMode === \"resize-left\" ? \"left\" : \"right\",\n this.pendingDxMs\n );\n }\n });\n }\n\n private flushPending(): void {\n if (this.rafHandle !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(this.rafHandle);\n this.rafHandle = null;\n }\n }\n\n private startLinkDrag(evt: PointerEvent, taskId: string, anchor: \"left\" | \"right\"): void {\n this.dragMode = \"link\";\n this.linkFromId = taskId;\n this.linkFromAnchor = anchor;\n this.callbacks.onLinkStart(taskId, anchor);\n\n const svgPoint = (clientX: number, clientY: number) => {\n const rect = this.svg.getBoundingClientRect();\n return { x: clientX - rect.left + this.svg.scrollLeft, y: clientY - rect.top };\n };\n\n const startPos = svgPoint(evt.clientX, evt.clientY);\n const line = document.createElementNS(\"http://www.w3.org/2000/svg\", \"line\");\n line.setAttribute(\"x1\", String(startPos.x));\n line.setAttribute(\"y1\", String(startPos.y));\n line.setAttribute(\"x2\", String(startPos.x));\n line.setAttribute(\"y2\", String(startPos.y));\n line.setAttribute(\"stroke\", \"#94a3b8\");\n line.setAttribute(\"stroke-dasharray\", \"4 3\");\n line.classList.add(\"gantt-temp-link\");\n this.svg.appendChild(line);\n this.tempLinkEl = line;\n\n const onMove = (moveEvt: PointerEvent) => {\n const pos = svgPoint(moveEvt.clientX, moveEvt.clientY);\n line.setAttribute(\"x2\", String(pos.x));\n line.setAttribute(\"y2\", String(pos.y));\n };\n const onUp = (upEvt: PointerEvent) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n this.tempLinkEl?.remove();\n this.tempLinkEl = null;\n\n const target = document.elementFromPoint(upEvt.clientX, upEvt.clientY);\n const connector = target?.closest<SVGCircleElement>(\"[data-gantt-connector]\");\n const toId = connector?.dataset.ganttConnector;\n if (toId && this.linkFromId && toId !== this.linkFromId) {\n this.callbacks.onLinkComplete(this.linkFromId, toId);\n } else {\n this.callbacks.onLinkCancel();\n }\n this.dragMode = null;\n this.linkFromId = null;\n this.linkFromAnchor = null;\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }\n\n private startCreateDrag(evt: PointerEvent, rowTaskId: string, rowBg: SVGRectElement): void {\n this.dragMode = \"create\";\n const parent = rowBg.parentNode as SVGGElement | null;\n const rowY = Number(rowBg.getAttribute(\"y\") ?? \"0\");\n const rowHeight = Number(rowBg.getAttribute(\"height\") ?? \"0\");\n\n const svgX = (clientX: number): number => {\n const rect = this.svg.getBoundingClientRect();\n return clientX - rect.left + this.svg.scrollLeft;\n };\n\n const startX = svgX(evt.clientX);\n let moved = false;\n\n const preview = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n preview.setAttribute(\"y\", String(rowY + 2));\n preview.setAttribute(\"height\", String(Math.max(0, rowHeight - 4)));\n preview.setAttribute(\"x\", String(startX));\n preview.setAttribute(\"width\", \"0\");\n preview.setAttribute(\"fill\", \"currentColor\");\n preview.setAttribute(\"opacity\", \"0.25\");\n preview.classList.add(\"gantt-create-preview\");\n parent?.appendChild(preview);\n\n const onMove = (moveEvt: PointerEvent) => {\n const currentX = svgX(moveEvt.clientX);\n if (Math.abs(currentX - startX) > 2) moved = true;\n const x1 = Math.min(startX, currentX);\n const x2 = Math.max(startX, currentX);\n preview.setAttribute(\"x\", String(x1));\n preview.setAttribute(\"width\", String(x2 - x1));\n };\n const onUp = (upEvt: PointerEvent) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n preview.remove();\n this.dragMode = null;\n if (moved) {\n const endX = svgX(upEvt.clientX);\n this.callbacks.onCreateTaskDrag?.(rowTaskId, Math.min(startX, endX), Math.max(startX, endX));\n }\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }\n\n /**\n * Delegates to handleBarKeyDown when a focused bar dispatched the event\n * (bars get tabindex=\"0\" when keyboardAccessible, so native Tab/Shift+Tab\n * traversal between them already works without any code here), and\n * otherwise checks the chart-wide shortcuts (Ctrl/Cmd+A, Home, End).\n */\n private onKeyDown = (evt: KeyboardEvent): void => {\n if (!this.options.keyboardAccessible) return;\n const target = evt.target as Element;\n const barGroup = target.closest?.(\"[data-gantt-bar]\");\n const taskId = barGroup?.getAttribute(\"data-gantt-bar\");\n if (taskId) {\n this.handleBarKeyDown(taskId, evt);\n return;\n }\n if ((evt.ctrlKey || evt.metaKey) && evt.key.toLowerCase() === \"a\") {\n evt.preventDefault();\n this.callbacks.onSelectAll?.();\n } else if (evt.key === \"Home\") {\n evt.preventDefault();\n this.callbacks.onJumpToStart?.();\n } else if (evt.key === \"End\") {\n evt.preventDefault();\n this.callbacks.onJumpToEnd?.();\n }\n };\n\n handleBarKeyDown(taskId: string, evt: KeyboardEvent): void {\n if (!this.options.keyboardAccessible) return;\n if (this.isReadonly(taskId)) return;\n if (evt.key === \"ArrowLeft\") {\n evt.preventDefault();\n this.callbacks.onMove(taskId, -MS_PER_DAY);\n } else if (evt.key === \"ArrowRight\") {\n evt.preventDefault();\n this.callbacks.onMove(taskId, MS_PER_DAY);\n } else if (evt.key === \"Enter\") {\n evt.preventDefault();\n this.callbacks.onBarClick(taskId);\n }\n }\n}\n"],"mappings":"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","names":["width","label","connector","startOfDay","startOfDay","end","days","linkPath","pxPerMs"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/critical-path.ts","../src/date-utils.ts","../src/calendar.ts","../src/layout.ts","../src/history.ts","../src/event-emitter.ts","../src/csv.ts","../src/renderer.ts","../src/auto-color.ts","../src/constraints.ts","../src/wbs.ts","../src/resource-histogram.ts","../src/filter.ts","../src/resource-leveling.ts","../src/interactions.ts"],"sourcesContent":["export * from \"./types\";\nexport { DEFAULT_THEME, mergeTheme, themeToCssVars } from \"./theme\";\nexport { computeLayout } from \"./layout\";\nexport { computeCriticalPath } from \"./critical-path\";\nexport { HistoryManager, type Command } from \"./history\";\nexport { EventEmitter } from \"./event-emitter\";\nexport { tasksToCSV, tasksFromCSV } from \"./csv\";\nexport * as dateUtils from \"./date-utils\";\nexport { isSafeHref } from \"./renderer\";\nexport {\n isWorkingDay,\n isHoliday,\n isWithinWorkingHours,\n isWorkingTime,\n nextWorkingDay,\n previousWorkingDay,\n shiftToWorkingDay,\n shiftToWorkingTime,\n} from \"./calendar\";\nexport { colorByField, applyColorByField, DEFAULT_PALETTE } from \"./auto-color\";\nexport { DENSITY_PRESETS, type Density } from \"./theme\";\nexport { applyConstraint } from \"./constraints\";\nexport { computeWBSCodes } from \"./wbs\";\nexport {\n computeResourceHistogram,\n renderResourceHistogramSVG,\n type ResourceHistogramOptions,\n type ResourceLoadBucket,\n} from \"./resource-histogram\";\nexport { filterTasks, type FilterTasksOptions, type FilterTasksResult } from \"./filter\";\nexport {\n levelResources,\n type ResourceLevelingOptions,\n type ResourceLevelingResult,\n} from \"./resource-leveling\";\n\nimport { shiftToWorkingDay, shiftToWorkingTime } from \"./calendar\";\nimport { applyConstraint } from \"./constraints\";\nimport { approxUnitMs, isValidDate, pxPerMs, snapToGrid, MS_PER_DAY } from \"./date-utils\";\nimport { HistoryManager, type Command } from \"./history\";\nimport { EventEmitter } from \"./event-emitter\";\nimport { computeLayout } from \"./layout\";\nimport { computeResourceHistogram, type ResourceHistogramOptions } from \"./resource-histogram\";\nimport { levelResources, type ResourceLevelingOptions } from \"./resource-leveling\";\nimport { GanttRenderer } from \"./renderer\";\nimport { InteractionController } from \"./interactions\";\nimport { mergeTheme } from \"./theme\";\nimport type {\n GanttColumn,\n GanttDependency,\n GanttEventMap,\n GanttOptions,\n GanttRenderModel,\n GanttTask,\n GanttTheme,\n ViewMode,\n} from \"./types\";\n\nconst HAS_DOM = typeof document !== \"undefined\" && typeof window !== \"undefined\";\n\nconst DEFAULT_COLUMNS: GanttColumn[] = [{ id: \"name\", title: \"Name\" }];\n\nfunction cloneTask(task: GanttTask): GanttTask {\n return { ...task };\n}\n\nexport class GanttChart {\n private tasks: GanttTask[];\n private dependencies: GanttDependency[];\n private options: Required<\n Pick<\n GanttOptions,\n | \"viewMode\"\n | \"readonly\"\n | \"showProgress\"\n | \"showDependencies\"\n | \"gridPanelWidth\"\n | \"showCriticalPath\"\n | \"showBaseline\"\n | \"showDeadlines\"\n | \"showAssigneeAvatars\"\n | \"enableHistory\"\n | \"keyboardAccessible\"\n | \"virtualScroll\"\n | \"autoSchedule\"\n | \"autoRollupProgress\"\n | \"selectable\"\n >\n > & {\n columnWidth?: number;\n theme?: Partial<GanttTheme>;\n columns?: GanttColumn[];\n calendar?: GanttOptions[\"calendar\"];\n markers?: GanttOptions[\"markers\"];\n pagination?: { pageSize: number; page: number };\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n onDateChange?: GanttOptions[\"onDateChange\"];\n onProgressChange?: GanttOptions[\"onProgressChange\"];\n onDependencyCreate?: GanttOptions[\"onDependencyCreate\"];\n onDependencyRemove?: GanttOptions[\"onDependencyRemove\"];\n onDependencyDblClick?: GanttOptions[\"onDependencyDblClick\"];\n onTaskClick?: GanttOptions[\"onTaskClick\"];\n onGroupToggle?: GanttOptions[\"onGroupToggle\"];\n onContextMenu?: GanttOptions[\"onContextMenu\"];\n onTaskCreate?: GanttOptions[\"onTaskCreate\"];\n onColumnResize?: GanttOptions[\"onColumnResize\"];\n onColumnReorder?: GanttOptions[\"onColumnReorder\"];\n onTaskReorder?: GanttOptions[\"onTaskReorder\"];\n onSelectionChange?: GanttOptions[\"onSelectionChange\"];\n };\n private theme: GanttTheme;\n private colorScheme: \"light\" | \"dark\" | \"auto\";\n private darkMediaQuery: MediaQueryList | null = null;\n private handleSchemeChange = (): void => {\n if (this.colorScheme !== \"auto\") return;\n this.theme = mergeTheme(this.explicitTheme, \"auto\");\n this.scheduleRender();\n };\n private explicitTheme?: Partial<GanttTheme>;\n private columns: GanttColumn[];\n private columnWidth: number;\n private emitter = new EventEmitter<GanttEventMap>();\n private history: HistoryManager | null = null;\n private renderer: GanttRenderer | null = null;\n private interactions: InteractionController | null = null;\n private renderModel: GanttRenderModel | null = null;\n private rafHandle: number | null = null;\n private currentPage = 1;\n private selectedTaskIds = new Set<string>();\n private lastSelectedId: string | null = null;\n\n constructor(\n private container: HTMLElement,\n tasks: GanttTask[],\n dependencies: GanttDependency[] = [],\n options: GanttOptions = {}\n ) {\n this.tasks = tasks.map(cloneTask);\n this.dependencies = dependencies.map((d) => ({ ...d }));\n this.colorScheme = options.colorScheme ?? \"auto\";\n this.explicitTheme = options.theme;\n this.theme = mergeTheme(options.theme, this.colorScheme);\n this.columns = options.columns ?? DEFAULT_COLUMNS;\n this.columnWidth = options.columnWidth ?? 32;\n this.currentPage = options.pagination?.page ?? 1;\n\n this.options = {\n viewMode: options.viewMode ?? \"day\",\n readonly: options.readonly ?? false,\n showProgress: options.showProgress ?? true,\n showDependencies: options.showDependencies ?? true,\n gridPanelWidth: options.gridPanelWidth ?? 260,\n showCriticalPath: options.showCriticalPath ?? false,\n showBaseline: options.showBaseline ?? false,\n showDeadlines: options.showDeadlines ?? true,\n showAssigneeAvatars: options.showAssigneeAvatars ?? false,\n enableHistory: options.enableHistory ?? false,\n keyboardAccessible: options.keyboardAccessible ?? false,\n virtualScroll: options.virtualScroll ?? true,\n autoSchedule: options.autoSchedule ?? false,\n autoRollupProgress: options.autoRollupProgress ?? false,\n selectable: options.selectable ?? false,\n columnWidth: options.columnWidth,\n theme: options.theme,\n columns: options.columns,\n calendar: options.calendar,\n markers: options.markers,\n pagination: options.pagination,\n snapToUnit: options.snapToUnit,\n onDateChange: options.onDateChange,\n onProgressChange: options.onProgressChange,\n onDependencyCreate: options.onDependencyCreate,\n onDependencyRemove: options.onDependencyRemove,\n onDependencyDblClick: options.onDependencyDblClick,\n onTaskClick: options.onTaskClick,\n onGroupToggle: options.onGroupToggle,\n onContextMenu: options.onContextMenu,\n onTaskCreate: options.onTaskCreate,\n onColumnResize: options.onColumnResize,\n onColumnReorder: options.onColumnReorder,\n onTaskReorder: options.onTaskReorder,\n onSelectionChange: options.onSelectionChange,\n };\n\n if (this.options.enableHistory) {\n this.history = new HistoryManager((state) => this.emitter.emit(\"history-change\", state));\n }\n\n if (HAS_DOM) {\n this.setupDom();\n }\n\n this.scheduleRender(true);\n }\n\n private setupDom(): void {\n this.container.style.setProperty(\"--gantt-grid-panel-width\", `${this.options.gridPanelWidth}px`);\n if (typeof window.matchMedia === \"function\") {\n this.darkMediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n this.darkMediaQuery.addEventListener?.(\"change\", this.handleSchemeChange);\n }\n this.renderer = new GanttRenderer(this.container, {\n keyboardAccessible: this.options.keyboardAccessible,\n showAssigneeAvatars: this.options.showAssigneeAvatars,\n virtualScroll: this.options.virtualScroll,\n onRenameCommit: (taskId, name) => this.updateTask(taskId, { name }),\n onColumnResize: this.options.onColumnResize\n ? (columnId, width) => this.handleColumnResize(columnId, width)\n : undefined,\n onColumnReorder: this.options.onColumnReorder\n ? (order) => this.handleColumnReorder(order)\n : undefined,\n onRowReorder: this.options.onTaskReorder\n ? (draggedId, targetId, position) => this.handleRowReorder(draggedId, targetId, position)\n : undefined,\n });\n\n this.interactions = new InteractionController(\n this.renderer.svg,\n this.renderer.gridPanel,\n {\n onMove: (taskId, dxMs) => this.handleMove(taskId, dxMs),\n onResize: (taskId, edge, dxMs) => this.handleResize(taskId, edge, dxMs),\n onLinkStart: () => {},\n onLinkComplete: (fromId, toId) => this.handleLinkComplete(fromId, toId),\n onLinkCancel: () => {},\n onToggleCollapse: (taskId) => this.toggleGroup(taskId),\n onBarClick: (taskId, modifiers) => this.handleBarClick(taskId, modifiers),\n onProgressDrag: (taskId, newProgress) => this.handleProgressDrag(taskId, newProgress),\n // Only wired when the consumer opted in via onTaskCreate - like onContextMenu below,\n // this keeps drag-to-create off by default instead of silently mutating task state.\n onCreateTaskDrag: this.options.onTaskCreate\n ? (rowTaskId, startXPx, endXPx) => this.handleCreateTaskDrag(rowTaskId, startXPx, endXPx)\n : undefined,\n onLinkDblClick: this.options.onDependencyDblClick\n ? (fromId, toId) => {\n const dep = this.dependencies.find((d) => d.fromId === fromId && d.toId === toId);\n if (dep) this.options.onDependencyDblClick?.(dep);\n }\n : undefined,\n onContextMenu: this.options.onContextMenu\n ? (taskId, evt) => {\n const task = this.tasks.find((t) => t.id === taskId);\n if (task) this.emitter.emit(\"context-menu\", { task, evt });\n this.options.onContextMenu?.(task ?? ({ id: taskId } as GanttTask), evt);\n }\n : undefined,\n onSelectAll: this.options.selectable ? () => this.selectAllVisible() : undefined,\n onJumpToStart: () => this.scrollToRangeStart(),\n onJumpToEnd: () => this.scrollToRangeEnd(),\n },\n {\n readonly: this.options.readonly,\n isTaskReadonly: (taskId) => !!this.tasks.find((t) => t.id === taskId)?.readonly,\n keyboardAccessible: this.options.keyboardAccessible,\n snapToUnit: this.options.snapToUnit,\n pxPerMs: () => pxPerMs(this.options.viewMode, this.columnWidth),\n }\n );\n }\n\n private handleMove(taskId: string, dxMs: number): void {\n if (dxMs === 0) return;\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task || task.readonly || this.options.readonly) return;\n const newStart = new Date(task.start.getTime() + dxMs);\n const newEnd = new Date(task.end.getTime() + dxMs);\n const newSegments = task.segments?.map((s) => ({\n start: new Date(s.start.getTime() + dxMs),\n end: new Date(s.end.getTime() + dxMs),\n }));\n this.applyDateChange(taskId, newStart, newEnd, newSegments);\n }\n\n private handleResize(taskId: string, edge: \"left\" | \"right\", dxMs: number): void {\n if (dxMs === 0) return;\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task || task.readonly || this.options.readonly) return;\n const newStart = edge === \"left\" ? new Date(task.start.getTime() + dxMs) : task.start;\n const newEnd = edge === \"right\" ? new Date(task.end.getTime() + dxMs) : task.end;\n if (newEnd.getTime() <= newStart.getTime()) return;\n const newSegments = task.segments?.map((s) => ({ ...s }));\n if (newSegments && newSegments.length > 0) {\n if (edge === \"left\") newSegments[0] = { ...newSegments[0]!, start: newStart };\n else newSegments[newSegments.length - 1] = { ...newSegments[newSegments.length - 1]!, end: newEnd };\n }\n this.applyDateChange(taskId, newStart, newEnd, newSegments);\n }\n\n private applyDateChange(\n taskId: string,\n newStart: Date,\n newEnd: Date,\n newSegments?: { start: Date; end: Date }[]\n ): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task) return;\n const before: { id: string; start: Date; end: Date; segments?: { start: Date; end: Date }[] }[] = [\n { id: taskId, start: task.start, end: task.end, segments: task.segments },\n ];\n const after: { id: string; start: Date; end: Date; segments?: { start: Date; end: Date }[] }[] = [\n { id: taskId, start: newStart, end: newEnd, segments: newSegments },\n ];\n\n if (this.options.autoSchedule) {\n const cascade = this.computeCascade(taskId, newStart, newEnd);\n for (const c of cascade) {\n before.push({ id: c.id, start: c.oldStart, end: c.oldEnd });\n after.push({ id: c.id, start: c.newStart, end: c.newEnd });\n }\n }\n\n const applyState = (state: typeof before) => {\n for (const s of state) {\n const t = this.tasks.find((tt) => tt.id === s.id);\n if (t) {\n t.start = s.start;\n t.end = s.end;\n if (s.segments !== undefined) t.segments = s.segments;\n }\n }\n };\n\n const cmd: Command = {\n label: \"move-or-resize\",\n do: () => {\n applyState(after);\n this.emitDateChangeEvents(after.map((a) => a.id));\n },\n undo: () => {\n applyState(before);\n this.emitDateChangeEvents(before.map((b) => b.id));\n },\n };\n this.runCommand(cmd);\n }\n\n private emitDateChangeEvents(ids: string[]): void {\n for (const id of ids) {\n const t = this.tasks.find((tt) => tt.id === id);\n if (!t) continue;\n this.emitter.emit(\"date-change\", { task: t, start: t.start, end: t.end });\n this.options.onDateChange?.(t, t.start, t.end);\n }\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n /** Shift successors that would violate their dependency constraint after `taskId` moves to [newStart, newEnd]. */\n private computeCascade(\n taskId: string,\n newStart: Date,\n newEnd: Date\n ): { id: string; oldStart: Date; oldEnd: Date; newStart: Date; newEnd: Date }[] {\n const results: { id: string; oldStart: Date; oldEnd: Date; newStart: Date; newEnd: Date }[] = [];\n const simulated = new Map<string, { start: Date; end: Date }>();\n simulated.set(taskId, { start: newStart, end: newEnd });\n\n const outgoing = new Map<string, GanttDependency[]>();\n for (const dep of this.dependencies) {\n const list = outgoing.get(dep.fromId) ?? [];\n list.push(dep);\n outgoing.set(dep.fromId, list);\n }\n\n const queue = [taskId];\n const visited = new Set<string>();\n let ops = 0;\n const maxOps = this.tasks.length * 2 + 5;\n\n while (queue.length > 0 && ops++ < maxOps) {\n const currentId = queue.shift();\n if (currentId === undefined) break;\n const currentState = simulated.get(currentId);\n if (!currentState) continue;\n\n for (const dep of outgoing.get(currentId) ?? []) {\n if (visited.has(dep.toId) && !simulated.has(dep.toId)) continue;\n const succTask = this.tasks.find((t) => t.id === dep.toId);\n if (!succTask) continue;\n const succState = simulated.get(dep.toId) ?? { start: succTask.start, end: succTask.end };\n const lag = dep.lagMs ?? 0;\n const duration = succState.end.getTime() - succState.start.getTime();\n\n let requiredStart: number | null = null;\n let requiredEnd: number | null = null;\n if (dep.type === \"FS\") requiredStart = currentState.end.getTime() + lag;\n else if (dep.type === \"SS\") requiredStart = currentState.start.getTime() + lag;\n else if (dep.type === \"FF\") requiredEnd = currentState.end.getTime() + lag;\n else if (dep.type === \"SF\") requiredEnd = currentState.start.getTime() + lag;\n\n let newSuccStart = succState.start.getTime();\n let newSuccEnd = succState.end.getTime();\n let violated = false;\n if (requiredStart !== null && succState.start.getTime() < requiredStart) {\n newSuccStart = requiredStart;\n newSuccEnd = requiredStart + duration;\n violated = true;\n } else if (requiredEnd !== null && succState.end.getTime() < requiredEnd) {\n newSuccEnd = requiredEnd;\n newSuccStart = requiredEnd - duration;\n violated = true;\n }\n\n if (violated && !visited.has(dep.toId)) {\n visited.add(dep.toId);\n let newState = { start: new Date(newSuccStart), end: new Date(newSuccEnd) };\n newState = applyConstraint(newState, succTask.constraintType, succTask.constraintDate);\n if (this.options.calendar) {\n const shiftedStart = this.options.calendar.workingHours\n ? shiftToWorkingTime(newState.start, this.options.calendar, 1)\n : shiftToWorkingDay(newState.start, this.options.calendar, 1);\n if (shiftedStart.getTime() !== newState.start.getTime()) {\n const dur = newState.end.getTime() - newState.start.getTime();\n newState = { start: shiftedStart, end: new Date(shiftedStart.getTime() + dur) };\n }\n }\n simulated.set(dep.toId, newState);\n results.push({\n id: dep.toId,\n oldStart: succTask.start,\n oldEnd: succTask.end,\n newStart: newState.start,\n newEnd: newState.end,\n });\n queue.push(dep.toId);\n }\n }\n }\n\n return results;\n }\n\n private handleLinkComplete(fromId: string, toId: string): void {\n const dep: GanttDependency = { fromId, toId, type: \"FS\" };\n const cmd: Command = {\n label: \"link-create\",\n do: () => {\n this.dependencies.push(dep);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n undo: () => {\n this.dependencies = this.dependencies.filter((d) => d !== dep);\n this.emitter.emit(\"dependency-remove\", dep);\n this.options.onDependencyRemove?.(dep);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n removeDependency(fromId: string, toId: string): void {\n const dep = this.dependencies.find((d) => d.fromId === fromId && d.toId === toId);\n if (!dep) return;\n const cmd: Command = {\n label: \"link-remove\",\n do: () => {\n this.dependencies = this.dependencies.filter((d) => d !== dep);\n this.emitter.emit(\"dependency-remove\", dep);\n this.options.onDependencyRemove?.(dep);\n this.scheduleRender();\n },\n undo: () => {\n this.dependencies.push(dep);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n /** Update a dependency's type/lag in place (e.g. from your own \"edit this link\" UI opened via onDependencyDblClick). Undoable. */\n updateDependency(fromId: string, toId: string, partial: Partial<GanttDependency>): void {\n const dep = this.dependencies.find((d) => d.fromId === fromId && d.toId === toId);\n if (!dep) return;\n const before = { ...dep };\n const after = { ...dep, ...partial, fromId: dep.fromId, toId: dep.toId };\n const cmd: Command = {\n label: \"link-update\",\n do: () => {\n Object.assign(dep, after);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n undo: () => {\n Object.assign(dep, before);\n this.emitter.emit(\"dependency-create\", dep);\n this.options.onDependencyCreate?.(dep);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private handleProgressDrag(taskId: string, newProgress: number): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task || task.readonly || this.options.readonly) return;\n const oldProgress = task.progress ?? 0;\n const clamped = Math.min(100, Math.max(0, newProgress));\n const cmd: Command = {\n label: \"progress-change\",\n do: () => {\n task.progress = clamped;\n this.emitter.emit(\"progress-change\", { task, progress: clamped });\n this.options.onProgressChange?.(task, clamped);\n this.scheduleRender();\n },\n undo: () => {\n task.progress = oldProgress;\n this.emitter.emit(\"progress-change\", { task, progress: oldProgress });\n this.options.onProgressChange?.(task, oldProgress);\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private handleCreateTaskDrag(rowTaskId: string, startXPx: number, endXPx: number): void {\n if (!this.renderModel) return;\n const scale = pxPerMs(this.options.viewMode, this.columnWidth);\n if (scale <= 0) return;\n const rangeStartMs = this.renderModel.rangeStart.getTime();\n let start = new Date(rangeStartMs + startXPx / scale);\n let end = new Date(rangeStartMs + endXPx / scale);\n if (this.options.snapToUnit) {\n start = snapToGrid(start, this.options.snapToUnit as ViewMode);\n end = snapToGrid(end, this.options.snapToUnit as ViewMode);\n }\n if (end.getTime() <= start.getTime()) end = new Date(start.getTime() + MS_PER_DAY);\n\n const rowTask = this.tasks.find((t) => t.id === rowTaskId);\n const newTask: GanttTask = {\n id: `task-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\n name: \"New task\",\n start,\n end,\n parentId: rowTask?.parentId ?? null,\n };\n\n const cmd: Command = {\n label: \"task-create\",\n do: () => {\n const index = this.tasks.findIndex((t) => t.id === rowTaskId);\n if (index >= 0) this.tasks.splice(index + 1, 0, newTask);\n else this.tasks.push(newTask);\n this.emitter.emit(\"task-create\", { task: newTask });\n this.options.onTaskCreate?.(newTask);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n undo: () => {\n this.tasks = this.tasks.filter((t) => t.id !== newTask.id);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private handleBarClick(\n taskId: string,\n modifiers?: { ctrlKey: boolean; metaKey: boolean; shiftKey: boolean }\n ): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task) return;\n\n if (this.options.selectable) {\n if (modifiers?.shiftKey && this.lastSelectedId && this.renderModel) {\n const ids = this.renderModel.rows.map((r) => r.taskId);\n const i1 = ids.indexOf(this.lastSelectedId);\n const i2 = ids.indexOf(taskId);\n if (i1 >= 0 && i2 >= 0) {\n const [lo, hi] = i1 < i2 ? [i1, i2] : [i2, i1];\n this.selectedTaskIds = new Set(ids.slice(lo, hi + 1));\n }\n } else if (modifiers?.ctrlKey || modifiers?.metaKey) {\n if (this.selectedTaskIds.has(taskId)) this.selectedTaskIds.delete(taskId);\n else this.selectedTaskIds.add(taskId);\n this.lastSelectedId = taskId;\n } else {\n this.selectedTaskIds = new Set([taskId]);\n this.lastSelectedId = taskId;\n }\n this.emitter.emit(\"selection-change\", { taskIds: this.getSelectedTaskIds() });\n this.options.onSelectionChange?.(this.getSelectedTaskIds());\n this.scheduleRender();\n }\n\n this.emitter.emit(\"task-click\", { task });\n this.options.onTaskClick?.(task);\n }\n\n /** Replace (default) or add to (`additive: true`) the current selection. Requires `selectable`. */\n selectTask(id: string, options: { additive?: boolean } = {}): void {\n if (!options.additive) this.selectedTaskIds.clear();\n this.selectedTaskIds.add(id);\n this.lastSelectedId = id;\n this.emitter.emit(\"selection-change\", { taskIds: this.getSelectedTaskIds() });\n this.options.onSelectionChange?.(this.getSelectedTaskIds());\n this.scheduleRender();\n }\n\n clearSelection(): void {\n this.selectedTaskIds.clear();\n this.lastSelectedId = null;\n this.emitter.emit(\"selection-change\", { taskIds: [] });\n this.options.onSelectionChange?.([]);\n this.scheduleRender();\n }\n\n getSelectedTaskIds(): string[] {\n return Array.from(this.selectedTaskIds);\n }\n\n /** Shift every selected task's start/end by `deltaMs`. Single undoable step. */\n bulkShiftDates(deltaMs: number): void {\n if (deltaMs === 0 || this.selectedTaskIds.size === 0) return;\n const ids = Array.from(this.selectedTaskIds);\n const before = ids\n .map((id) => this.tasks.find((t) => t.id === id))\n .filter((t): t is GanttTask => !!t)\n .map((t) => ({ id: t.id, start: t.start, end: t.end }));\n const after = before.map((b) => ({\n id: b.id,\n start: new Date(b.start.getTime() + deltaMs),\n end: new Date(b.end.getTime() + deltaMs),\n }));\n const applyState = (state: typeof before) => {\n for (const s of state) {\n const t = this.tasks.find((tt) => tt.id === s.id);\n if (t) {\n t.start = s.start;\n t.end = s.end;\n }\n }\n };\n const cmd: Command = {\n label: \"bulk-shift\",\n do: () => {\n applyState(after);\n this.emitDateChangeEvents(after.map((a) => a.id));\n },\n undo: () => {\n applyState(before);\n this.emitDateChangeEvents(before.map((b) => b.id));\n },\n };\n this.runCommand(cmd);\n }\n\n /** Delete every selected task (and any dependency touching one). Single undoable step. */\n bulkDelete(): void {\n if (this.selectedTaskIds.size === 0) return;\n const ids = Array.from(this.selectedTaskIds);\n const idSet = new Set(ids);\n const removedTasks = this.tasks.filter((t) => idSet.has(t.id));\n const removedIndices = removedTasks.map((t) => this.tasks.indexOf(t));\n const removedDeps = this.dependencies.filter((d) => idSet.has(d.fromId) || idSet.has(d.toId));\n\n const cmd: Command = {\n label: \"bulk-delete\",\n do: () => {\n this.tasks = this.tasks.filter((t) => !idSet.has(t.id));\n this.dependencies = this.dependencies.filter((d) => !idSet.has(d.fromId) && !idSet.has(d.toId));\n this.selectedTaskIds.clear();\n this.emitter.emit(\"selection-change\", { taskIds: [] });\n this.options.onSelectionChange?.([]);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n undo: () => {\n const combined = [...this.tasks];\n removedTasks.forEach((t, i) => {\n const at = Math.min(removedIndices[i] ?? combined.length, combined.length);\n combined.splice(at, 0, t);\n });\n this.tasks = combined;\n this.dependencies.push(...removedDeps);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n },\n };\n this.runCommand(cmd);\n }\n\n private runCommand(cmd: Command): void {\n if (this.history) {\n this.history.push(cmd);\n } else {\n cmd.do();\n }\n }\n\n private handleColumnResize(columnId: string, width: number): void {\n const col = this.columns.find((c) => c.id === columnId);\n if (!col) return;\n col.width = width;\n this.emitter.emit(\"column-resize\", { columnId, width });\n this.options.onColumnResize?.(columnId, width);\n this.scheduleRender();\n }\n\n private handleColumnReorder(order: string[]): void {\n const byId = new Map(this.columns.map((c) => [c.id, c]));\n const reordered = order.map((id) => byId.get(id)).filter((c): c is GanttColumn => !!c);\n if (reordered.length !== this.columns.length) return;\n this.columns = reordered;\n this.emitter.emit(\"column-reorder\", { order });\n this.options.onColumnReorder?.(order);\n this.scheduleRender();\n }\n\n private handleRowReorder(\n draggedId: string,\n targetId: string,\n position: \"before\" | \"after\" | \"inside\"\n ): void {\n const draggedIndex = this.tasks.findIndex((t) => t.id === draggedId);\n const targetIndex = this.tasks.findIndex((t) => t.id === targetId);\n if (draggedIndex < 0 || targetIndex < 0) return;\n const dragged = this.tasks[draggedIndex];\n const target = this.tasks[targetIndex];\n if (!dragged || !target) return;\n\n // Refuse to make a task its own descendant's child.\n let cursor: GanttTask | undefined = target;\n while (cursor) {\n if (cursor.id === draggedId) return;\n cursor = cursor.parentId ? this.tasks.find((t) => t.id === cursor!.parentId) : undefined;\n }\n\n this.tasks.splice(draggedIndex, 1);\n const newTargetIndex = this.tasks.findIndex((t) => t.id === targetId);\n if (position === \"inside\") {\n dragged.parentId = target.id;\n this.tasks.splice(newTargetIndex + 1, 0, dragged);\n } else {\n dragged.parentId = target.parentId ?? null;\n this.tasks.splice(position === \"before\" ? newTargetIndex : newTargetIndex + 1, 0, dragged);\n }\n\n this.emitter.emit(\"task-reorder\", { draggedTaskId: draggedId, targetTaskId: targetId, position });\n this.options.onTaskReorder?.(draggedId, targetId, position);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n toggleGroup(taskId: string): void {\n const task = this.tasks.find((t) => t.id === taskId);\n if (!task) return;\n task.collapsed = !task.collapsed;\n this.emitter.emit(\"group-toggle\", { task, collapsed: !!task.collapsed });\n this.options.onGroupToggle?.(task, !!task.collapsed);\n this.scheduleRender();\n }\n\n expandAll(): void {\n for (const t of this.tasks) t.collapsed = false;\n this.scheduleRender();\n }\n\n collapseAll(): void {\n for (const t of this.tasks) if (t.isGroup) t.collapsed = true;\n this.scheduleRender();\n }\n\n setTasks(tasks: GanttTask[]): void {\n this.tasks = tasks.map(cloneTask);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n getTasks(): GanttTask[] {\n return this.tasks.map(cloneTask);\n }\n\n setDependencies(deps: GanttDependency[]): void {\n this.dependencies = deps.map((d) => ({ ...d }));\n this.scheduleRender();\n }\n\n updateTask(id: string, partial: Partial<GanttTask>): void {\n const task = this.tasks.find((t) => t.id === id);\n if (!task) return;\n Object.assign(task, partial);\n this.emitter.emit(\"tasks-change\", { tasks: this.getTasks() });\n this.scheduleRender();\n }\n\n setViewMode(mode: ViewMode): void {\n this.options.viewMode = mode;\n this.scheduleRender();\n }\n\n setOptions(partial: Partial<GanttOptions>): void {\n if (partial.colorScheme !== undefined) this.colorScheme = partial.colorScheme;\n if (partial.theme !== undefined) this.explicitTheme = partial.theme;\n if (partial.theme !== undefined || partial.colorScheme !== undefined) {\n this.theme = mergeTheme(this.explicitTheme, this.colorScheme);\n }\n if (partial.columns) this.columns = partial.columns;\n if (partial.columnWidth !== undefined) this.columnWidth = partial.columnWidth;\n Object.assign(this.options, partial);\n this.scheduleRender();\n }\n\n /** Scroll the timeline so \"today\" is centered in the viewport. No-op without a DOM / today column visible. */\n scrollToToday(): void {\n if (!HAS_DOM || !this.renderer || !this.renderModel) return;\n const todayTick = this.renderModel.ticks.find((t) => t.isToday);\n if (!todayTick) return;\n const scrollEl = this.renderer.timelineScroll;\n const viewportWidth = scrollEl.clientWidth || 0;\n scrollEl.scrollLeft = Math.max(0, todayTick.x - viewportWidth / 2);\n }\n\n /** Scroll the timeline to the very start of the project's date range. Also the Home-key shortcut when keyboardAccessible. */\n scrollToRangeStart(): void {\n if (!HAS_DOM || !this.renderer) return;\n this.renderer.timelineScroll.scrollLeft = 0;\n }\n\n /** Scroll the timeline to the very end of the project's date range. Also the End-key shortcut when keyboardAccessible. */\n scrollToRangeEnd(): void {\n if (!HAS_DOM || !this.renderer || !this.renderModel) return;\n this.renderer.timelineScroll.scrollLeft = this.renderModel.width;\n }\n\n /** Select every currently visible task. Also the Ctrl/Cmd+A shortcut when both `selectable` and `keyboardAccessible` are on. */\n selectAllVisible(): void {\n if (!this.options.selectable || !this.renderModel) return;\n this.selectedTaskIds = new Set(this.renderModel.rows.map((r) => r.taskId));\n this.emitter.emit(\"selection-change\", { taskIds: this.getSelectedTaskIds() });\n this.options.onSelectionChange?.(this.getSelectedTaskIds());\n this.scheduleRender();\n }\n\n fitToViewport(containerWidthPx: number): void {\n let min: number | null = null;\n let max: number | null = null;\n for (const t of this.tasks) {\n if (!isValidDate(t.start) || !isValidDate(t.end)) continue;\n min = min === null ? t.start.getTime() : Math.min(min, t.start.getTime());\n max = max === null ? t.end.getTime() : Math.max(max, t.end.getTime());\n }\n if (min === null || max === null || max <= min) return;\n const rangeMs = max - min;\n const unitMs = approxUnitMs(this.options.viewMode);\n const newColumnWidth = Math.max(4, (containerWidthPx * unitMs) / rangeMs);\n this.columnWidth = newColumnWidth;\n this.scheduleRender();\n }\n\n private static readonly MIN_COLUMN_WIDTH = 4;\n private static readonly MAX_COLUMN_WIDTH = 400;\n\n /** Zoom in by `factor` (default 1.25x), clamped to a sane minimum column width. */\n zoomIn(factor = 1.25): void {\n this.columnWidth = Math.min(GanttChart.MAX_COLUMN_WIDTH, this.columnWidth * factor);\n this.scheduleRender();\n }\n\n /** Zoom out by `factor` (default 1.25x), clamped to a sane maximum column width. */\n zoomOut(factor = 1.25): void {\n this.columnWidth = Math.max(GanttChart.MIN_COLUMN_WIDTH, this.columnWidth / factor);\n this.scheduleRender();\n }\n\n /** Current zoom level, expressed as px per grid-unit column (same unit as the `columnWidth` option). */\n getZoomLevel(): number {\n return this.columnWidth;\n }\n\n /** Per-assignee daily workload, computed from the current tasks. See computeResourceHistogram. */\n getResourceHistogram(options: ResourceHistogramOptions = {}) {\n return computeResourceHistogram(this.tasks, { calendar: this.options.calendar, ...options });\n }\n\n /** Resolve resource overallocation by delaying tasks. Doesn't mutate state - call setTasks(result.tasks) to apply it. See levelResources. */\n getLeveledTasks(options: ResourceLevelingOptions = {}) {\n return levelResources(this.tasks, this.dependencies, { calendar: this.options.calendar, ...options });\n }\n\n getPageCount(): number {\n const pageSize = this.options.pagination?.pageSize;\n if (!pageSize || pageSize <= 0) return 1;\n const rootCount = this.tasks.filter((t) => !t.parentId).length;\n return Math.max(1, Math.ceil(rootCount / pageSize));\n }\n\n setPage(page: number): void {\n const pageCount = this.getPageCount();\n const clamped = Math.min(Math.max(1, page), pageCount);\n this.currentPage = clamped;\n if (this.options.pagination) this.options.pagination.page = clamped;\n this.emitter.emit(\"page-change\", { page: clamped, pageCount });\n this.scheduleRender();\n }\n\n getRenderModel(): GanttRenderModel {\n if (!this.renderModel) this.renderModel = this.computeModel();\n return this.renderModel;\n }\n\n private computeModel(): GanttRenderModel {\n const pagination = this.options.pagination\n ? { pageSize: this.options.pagination.pageSize, page: this.currentPage }\n : undefined;\n return computeLayout({\n tasks: this.tasks,\n dependencies: this.dependencies,\n viewMode: this.options.viewMode,\n columnWidth: this.columnWidth,\n theme: this.theme,\n columns: this.columns,\n showCriticalPath: this.options.showCriticalPath,\n showBaseline: this.options.showBaseline,\n showDeadlines: this.options.showDeadlines,\n showAssigneeAvatars: this.options.showAssigneeAvatars,\n calendar: this.options.calendar,\n markers: this.options.markers,\n autoRollupProgress: this.options.autoRollupProgress,\n selectedTaskIds: this.options.selectable ? this.selectedTaskIds : undefined,\n pagination,\n });\n }\n\n private scheduleRender(immediate = false): void {\n if (immediate || !HAS_DOM) {\n this.doRender();\n return;\n }\n if (this.rafHandle !== null) return;\n this.rafHandle = requestAnimationFrame(() => {\n this.rafHandle = null;\n this.doRender();\n });\n }\n\n private doRender(): void {\n this.renderModel = this.computeModel();\n this.renderer?.render(this.renderModel, this.tasks, this.columns, this.explicitTheme);\n if (this.renderer && this.colorScheme !== \"auto\") {\n this.renderer.root.setAttribute(\"data-gantt-theme\", this.colorScheme);\n } else {\n this.renderer?.root.removeAttribute(\"data-gantt-theme\");\n }\n }\n\n undo(): void {\n this.history?.undo();\n }\n\n redo(): void {\n this.history?.redo();\n }\n\n get canUndo(): boolean {\n return this.history?.canUndo ?? false;\n }\n\n get canRedo(): boolean {\n return this.history?.canRedo ?? false;\n }\n\n on<K extends keyof GanttEventMap>(event: K, listener: (payload: GanttEventMap[K]) => void): void {\n this.emitter.on(event, listener);\n }\n\n off<K extends keyof GanttEventMap>(event: K, listener: (payload: GanttEventMap[K]) => void): void {\n this.emitter.off(event, listener);\n }\n\n toSVGString(): string {\n return this.renderer?.toSVGString() ?? \"\";\n }\n\n private async rasterizeSVG(svgString: string, width: number, height: number): Promise<string> {\n const svgBlob = new Blob([svgString], { type: \"image/svg+xml;charset=utf-8\" });\n const url = URL.createObjectURL(svgBlob);\n try {\n return await new Promise<string>((resolve, reject) => {\n const image = new Image();\n image.onload = () => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = image.width || width || 800;\n canvas.height = image.height || height || 600;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"2D canvas context unavailable\"));\n return;\n }\n ctx.drawImage(image, 0, 0);\n resolve(canvas.toDataURL(\"image/png\"));\n };\n image.onerror = () => reject(new Error(\"Failed to rasterize SVG\"));\n image.src = url;\n });\n } finally {\n URL.revokeObjectURL(url);\n }\n }\n\n async toPNGDataURL(): Promise<string> {\n if (!HAS_DOM || !this.renderer) {\n throw new Error(\"toPNGDataURL requires a browser DOM environment\");\n }\n const svgString = this.renderer.toSVGString();\n return this.rasterizeSVG(svgString, this.renderer.svg.clientWidth, this.renderer.svg.clientHeight);\n }\n\n /**\n * Like toPNGDataURL, but tiles a chart larger than `pageWidthPx`/`pageHeightPx`\n * into multiple images (row-major order) instead of one oversized raster -\n * useful for charts too big to comfortably rasterize/view as a single PNG.\n * Reuses the full rendered SVG (so every page renders at full fidelity);\n * defaults to the chart's actual size, i.e. a single image, when omitted.\n */\n async toPNGDataURLs(options: { pageWidthPx?: number; pageHeightPx?: number } = {}): Promise<string[]> {\n if (!HAS_DOM || !this.renderer || !this.renderModel) {\n throw new Error(\"toPNGDataURLs requires a browser DOM environment\");\n }\n const svgString = this.renderer.toSVGString();\n const totalWidth = this.renderModel.width;\n const totalHeight = this.renderModel.headerHeight + this.renderModel.height;\n const pageWidth = Math.max(1, options.pageWidthPx ?? totalWidth);\n const pageHeight = Math.max(1, options.pageHeightPx ?? totalHeight);\n const cols = Math.max(1, Math.ceil(totalWidth / pageWidth));\n const rows = Math.max(1, Math.ceil(totalHeight / pageHeight));\n\n const results: string[] = [];\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tx = c * pageWidth;\n const ty = r * pageHeight;\n const tw = Math.min(pageWidth, totalWidth - tx);\n const th = Math.min(pageHeight, totalHeight - ty);\n // Re-window the same full-resolution SVG onto this tile's region: swapping\n // width/height/viewBox on the outer <svg> crops+repositions without re-serializing content.\n const tileSvg = svgString.replace(/<svg([^>]*)>/, (_match, attrs: string) => {\n const cleaned = attrs\n .replace(/\\swidth=\"[^\"]*\"/, \"\")\n .replace(/\\sheight=\"[^\"]*\"/, \"\")\n .replace(/\\sviewBox=\"[^\"]*\"/, \"\");\n return `<svg${cleaned} width=\"${tw}\" height=\"${th}\" viewBox=\"${tx} ${ty} ${tw} ${th}\">`;\n });\n results.push(await this.rasterizeSVG(tileSvg, tw, th));\n }\n }\n return results;\n }\n\n destroy(): void {\n if (this.rafHandle !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(this.rafHandle);\n }\n this.darkMediaQuery?.removeEventListener?.(\"change\", this.handleSchemeChange);\n this.emitter.removeAllListeners();\n this.interactions?.destroy();\n this.renderer?.destroy();\n }\n}\n\n","import type { GanttTheme } from \"./types\";\n\nexport const DEFAULT_THEME: GanttTheme = {\n rowHeight: 36,\n barHeight: 22,\n headerHeight: 50,\n gridColor: \"#e5e7eb\",\n weekendColor: \"#f3f4f6\",\n todayColor: \"#ef4444\",\n barColor: \"#3b82f6\",\n barProgressColor: \"#2563eb\",\n groupBarColor: \"#64748b\",\n linkColor: \"#94a3b8\",\n criticalColor: \"#dc2626\",\n baselineColor: \"#9ca3af\",\n deadlineColor: \"#f59e0b\",\n markerColor: \"#8b5cf6\",\n selectionColor: \"#0ea5e9\",\n textColor: \"#1f2937\",\n backgroundColor: \"#ffffff\",\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n fontSize: 12,\n borderRadius: 4,\n};\n\nexport const DARK_THEME: GanttTheme = {\n ...DEFAULT_THEME,\n gridColor: \"#2d3341\",\n weekendColor: \"#252a35\",\n todayColor: \"#f87171\",\n barColor: \"#60a5fa\",\n barProgressColor: \"#3b82f6\",\n groupBarColor: \"#94a3b8\",\n linkColor: \"#64748b\",\n criticalColor: \"#f87171\",\n baselineColor: \"#4b5563\",\n deadlineColor: \"#fbbf24\",\n markerColor: \"#a78bfa\",\n selectionColor: \"#38bdf8\",\n textColor: \"#e5e7eb\",\n backgroundColor: \"#181c24\",\n};\n\nexport type ColorScheme = \"light\" | \"dark\" | \"auto\";\n\nexport type Density = \"compact\" | \"comfortable\" | \"spacious\";\n\n/**\n * Row/bar/header/font sizing presets. Not wired into any option - spread one\n * into your `theme` prop/option (explicit fields you also set win, since\n * object spread is left-to-right):\n *\n * theme: { ...DENSITY_PRESETS.compact, barColor: \"#...\" }\n */\nexport const DENSITY_PRESETS: Record<Density, Pick<GanttTheme, \"rowHeight\" | \"barHeight\" | \"headerHeight\" | \"fontSize\">> = {\n compact: { rowHeight: 26, barHeight: 16, headerHeight: 38, fontSize: 11 },\n comfortable: { rowHeight: 36, barHeight: 22, headerHeight: 50, fontSize: 12 },\n spacious: { rowHeight: 48, barHeight: 30, headerHeight: 60, fontSize: 13 },\n};\n\nfunction prefersDark(): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n );\n}\n\n/** Resolve the base theme for a `colorScheme` setting; \"auto\" reads the OS/browser preference (falls back to light without a DOM). */\nexport function baseThemeForScheme(scheme: ColorScheme = \"auto\"): GanttTheme {\n if (scheme === \"dark\") return DARK_THEME;\n if (scheme === \"light\") return DEFAULT_THEME;\n return prefersDark() ? DARK_THEME : DEFAULT_THEME;\n}\n\nexport function mergeTheme(partial?: Partial<GanttTheme>, scheme: ColorScheme = \"light\"): GanttTheme {\n const base = scheme === \"light\" ? DEFAULT_THEME : baseThemeForScheme(scheme);\n return { ...base, ...partial };\n}\n\nconst CSS_VAR_NAMES: Record<keyof GanttTheme, string> = {\n rowHeight: \"--gantt-row-height\",\n barHeight: \"--gantt-bar-height\",\n headerHeight: \"--gantt-header-height\",\n gridColor: \"--gantt-grid-color\",\n weekendColor: \"--gantt-weekend-color\",\n todayColor: \"--gantt-today-color\",\n barColor: \"--gantt-bar-color\",\n barProgressColor: \"--gantt-bar-progress-color\",\n groupBarColor: \"--gantt-group-bar-color\",\n linkColor: \"--gantt-link-color\",\n criticalColor: \"--gantt-critical-color\",\n baselineColor: \"--gantt-baseline-color\",\n deadlineColor: \"--gantt-deadline-color\",\n markerColor: \"--gantt-marker-color\",\n selectionColor: \"--gantt-selection-color\",\n textColor: \"--gantt-text-color\",\n backgroundColor: \"--gantt-background-color\",\n fontFamily: \"--gantt-font-family\",\n fontSize: \"--gantt-font-size\",\n borderRadius: \"--gantt-border-radius\",\n};\n\nconst PX_FIELDS = new Set<keyof GanttTheme>([\n \"rowHeight\",\n \"barHeight\",\n \"headerHeight\",\n \"fontSize\",\n \"borderRadius\",\n]);\n\nexport function themeToCssVars(theme: GanttTheme): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const key of Object.keys(CSS_VAR_NAMES) as (keyof GanttTheme)[]) {\n const varName = CSS_VAR_NAMES[key];\n const value = theme[key];\n vars[varName] = PX_FIELDS.has(key) ? `${value}px` : String(value);\n }\n return vars;\n}\n\nexport function cssVarName(key: keyof GanttTheme): string {\n return CSS_VAR_NAMES[key];\n}\n\n/**\n * Only the fields the consumer explicitly set via the JS `theme` option, as inline CSS vars.\n * Unset fields are deliberately left undeclared on .gantt-root so a consumer's own stylesheet\n * (or our shipped light/dark defaults) controls them — inline styles would otherwise always\n * beat external CSS and defeat \"theme via CSS variables\" for anyone not using the JS API.\n */\nexport function explicitThemeToCssVars(partial?: Partial<GanttTheme>): Record<string, string> {\n if (!partial) return {};\n const vars: Record<string, string> = {};\n for (const key of Object.keys(partial) as (keyof GanttTheme)[]) {\n const value = partial[key];\n if (value === undefined) continue;\n vars[CSS_VAR_NAMES[key]] = PX_FIELDS.has(key) ? `${value}px` : String(value);\n }\n return vars;\n}\n\n/** `var(--gantt-x, resolvedFallback)` — lets external CSS win, while still painting correctly with zero CSS present. */\nexport function themedFill(key: keyof GanttTheme, resolvedValue: string): string {\n return `var(${CSS_VAR_NAMES[key]}, ${resolvedValue})`;\n}\n","import type { GanttDependency, GanttTask } from \"./types\";\n\nexport interface CriticalPathResult {\n criticalTasks: Set<string>;\n criticalLinks: Set<string>;\n}\n\nfunction linkKey(fromId: string, toId: string): string {\n return `${fromId}->${toId}`;\n}\n\nfunction isValidTask(task: GanttTask): boolean {\n return (\n task.start instanceof Date &&\n task.end instanceof Date &&\n !Number.isNaN(task.start.getTime()) &&\n !Number.isNaN(task.end.getTime())\n );\n}\n\nfunction durationOf(task: GanttTask): number {\n const d = task.end.getTime() - task.start.getTime();\n return d > 0 ? d : 0;\n}\n\n/**\n * Longest-duration-chain (CPM-style forward/backward pass) through the dependency DAG.\n * Task dates in a Gantt chart are already fixed (this isn't an auto-scheduler), so the\n * dependency `type` and `lagMs` are folded into a single edge weight rather than\n * recomputing actual start/end dates - the goal is only to flag which tasks/links sit\n * on the longest chain, not to move anything.\n */\nexport function computeCriticalPath(\n tasks: GanttTask[],\n dependencies: GanttDependency[]\n): CriticalPathResult {\n const empty: CriticalPathResult = { criticalTasks: new Set(), criticalLinks: new Set() };\n\n const leafTasks = tasks.filter((t) => !t.isGroup && isValidTask(t));\n const leafIds = new Set(leafTasks.map((t) => t.id));\n if (leafTasks.length === 0) return empty;\n\n const edges = dependencies.filter(\n (d) => leafIds.has(d.fromId) && leafIds.has(d.toId) && d.fromId !== d.toId\n );\n\n const outgoing = new Map<string, GanttDependency[]>();\n const incoming = new Map<string, GanttDependency[]>();\n for (const id of leafIds) {\n outgoing.set(id, []);\n incoming.set(id, []);\n }\n for (const e of edges) {\n outgoing.get(e.fromId)?.push(e);\n incoming.get(e.toId)?.push(e);\n }\n\n // Kahn's algorithm with a hard iteration cap so a malformed/cyclic dependency\n // list can never spin the render thread - a visited-set alone can't bound\n // work when nodes get revisited, so cap total dequeue operations explicitly.\n const inDegree = new Map<string, number>();\n for (const id of leafIds) inDegree.set(id, incoming.get(id)?.length ?? 0);\n const queue: string[] = [];\n for (const id of leafIds) {\n if ((inDegree.get(id) ?? 0) === 0) queue.push(id);\n }\n const topoOrder: string[] = [];\n const maxOps = leafIds.size + edges.length + 1;\n let ops = 0;\n let qi = 0;\n while (qi < queue.length) {\n if (ops++ > maxOps) return empty; // cycle guard tripped\n const nodeId = queue[qi++];\n if (nodeId === undefined) break;\n topoOrder.push(nodeId);\n for (const e of outgoing.get(nodeId) ?? []) {\n const nextDeg = (inDegree.get(e.toId) ?? 0) - 1;\n inDegree.set(e.toId, nextDeg);\n if (nextDeg === 0) queue.push(e.toId);\n }\n }\n\n if (topoOrder.length !== leafIds.size) {\n // Cycle detected: skip critical path computation entirely.\n return empty;\n }\n\n const taskById = new Map(leafTasks.map((t) => [t.id, t]));\n\n const es = new Map<string, number>();\n const ef = new Map<string, number>();\n for (const id of topoOrder) {\n const task = taskById.get(id);\n if (!task) continue;\n let start = 0;\n for (const e of incoming.get(id) ?? []) {\n const predEf = ef.get(e.fromId);\n if (predEf === undefined) continue;\n const lag = e.lagMs ?? 0;\n start = Math.max(start, predEf + lag);\n }\n es.set(id, start);\n ef.set(id, start + durationOf(task));\n }\n\n let projectEnd = 0;\n for (const id of topoOrder) {\n projectEnd = Math.max(projectEnd, ef.get(id) ?? 0);\n }\n\n const lf = new Map<string, number>();\n const ls = new Map<string, number>();\n for (let i = topoOrder.length - 1; i >= 0; i--) {\n const id = topoOrder[i];\n if (id === undefined) continue;\n const task = taskById.get(id);\n if (!task) continue;\n const succs = outgoing.get(id) ?? [];\n let finish = projectEnd;\n if (succs.length > 0) {\n finish = Infinity;\n for (const e of succs) {\n const succLs = ls.get(e.toId);\n if (succLs === undefined) continue;\n const lag = e.lagMs ?? 0;\n finish = Math.min(finish, succLs - lag);\n }\n if (!Number.isFinite(finish)) finish = projectEnd;\n }\n lf.set(id, finish);\n ls.set(id, finish - durationOf(task));\n }\n\n const EPSILON = 1;\n const criticalTasks = new Set<string>();\n for (const id of topoOrder) {\n const slack = (ls.get(id) ?? 0) - (es.get(id) ?? 0);\n if (Math.abs(slack) < EPSILON) criticalTasks.add(id);\n }\n\n const criticalLinks = new Set<string>();\n for (const e of edges) {\n if (!criticalTasks.has(e.fromId) || !criticalTasks.has(e.toId)) continue;\n const predEf = ef.get(e.fromId) ?? 0;\n const succEs = es.get(e.toId) ?? 0;\n const lag = e.lagMs ?? 0;\n if (Math.abs(succEs - (predEf + lag)) < EPSILON) {\n criticalLinks.add(linkKey(e.fromId, e.toId));\n }\n }\n\n for (const task of tasks) {\n if (!task.isGroup) continue;\n let hasCriticalDescendant = false;\n const descendantStack = [task.id];\n const visited = new Set<string>();\n while (descendantStack.length > 0) {\n const id = descendantStack.pop();\n if (id === undefined || visited.has(id)) continue;\n visited.add(id);\n for (const t of tasks) {\n if (t.parentId === id) {\n if (criticalTasks.has(t.id)) hasCriticalDescendant = true;\n descendantStack.push(t.id);\n }\n }\n }\n if (hasCriticalDescendant) criticalTasks.add(task.id);\n }\n\n return { criticalTasks, criticalLinks };\n}\n","import { isNonWorkingDay, isWorkingTime, type WorkingCalendar } from \"./calendar\";\nimport type { ViewMode } from \"./types\";\n\nconst MS_PER_HOUR = 60 * 60 * 1000;\nconst MS_PER_DAY = 24 * MS_PER_HOUR;\nconst MS_PER_WEEK = 7 * MS_PER_DAY;\n\nconst WEEKDAY_LABELS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst MONTH_LABELS = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n];\n\n/** Approximate duration of one grid unit for the given view mode, used only for pixel scaling. */\nexport function approxUnitMs(viewMode: ViewMode): number {\n switch (viewMode) {\n case \"hour\":\n return MS_PER_HOUR;\n case \"day\":\n return MS_PER_DAY;\n case \"week\":\n return MS_PER_WEEK;\n case \"month\":\n return 30 * MS_PER_DAY;\n case \"quarter\":\n return 91 * MS_PER_DAY;\n case \"year\":\n return 365 * MS_PER_DAY;\n }\n}\n\n/** Pixels per millisecond, derived from how many px represent one grid unit. */\nexport function pxPerMs(viewMode: ViewMode, columnWidth: number): number {\n return columnWidth / approxUnitMs(viewMode);\n}\n\nexport function dateToX(\n date: Date,\n rangeStart: Date,\n viewMode: ViewMode,\n columnWidth: number\n): number {\n return (date.getTime() - rangeStart.getTime()) * pxPerMs(viewMode, columnWidth);\n}\n\nexport function isWeekend(date: Date): boolean {\n const day = date.getDay();\n return day === 0 || day === 6;\n}\n\nexport function isValidDate(date: unknown): date is Date {\n return date instanceof Date && !Number.isNaN(date.getTime());\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction startOfWeek(date: Date): Date {\n const d = startOfDay(date);\n const day = d.getDay();\n const diff = (day + 6) % 7; // Monday as start of week\n d.setDate(d.getDate() - diff);\n return d;\n}\n\nfunction startOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n}\n\nfunction startOfQuarter(date: Date): Date {\n const q = Math.floor(date.getMonth() / 3);\n return new Date(date.getFullYear(), q * 3, 1);\n}\n\nfunction startOfYear(date: Date): Date {\n return new Date(date.getFullYear(), 0, 1);\n}\n\nfunction startOfHour(date: Date): Date {\n return new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate(),\n date.getHours()\n );\n}\n\n/** Snap the given date down to the start of the grid unit for the view mode. */\nexport function startOfUnit(date: Date, viewMode: ViewMode): Date {\n switch (viewMode) {\n case \"hour\":\n return startOfHour(date);\n case \"day\":\n return startOfDay(date);\n case \"week\":\n return startOfWeek(date);\n case \"month\":\n return startOfMonth(date);\n case \"quarter\":\n return startOfQuarter(date);\n case \"year\":\n return startOfYear(date);\n }\n}\n\n/** Advance (or, with a negative count, go back) `count` grid units, calendar-aware. */\nexport function addUnit(date: Date, viewMode: ViewMode, count: number): Date {\n const d = new Date(date.getTime());\n switch (viewMode) {\n case \"hour\":\n d.setHours(d.getHours() + count);\n return d;\n case \"day\":\n d.setDate(d.getDate() + count);\n return d;\n case \"week\":\n d.setDate(d.getDate() + count * 7);\n return d;\n case \"month\":\n d.setMonth(d.getMonth() + count);\n return d;\n case \"quarter\":\n d.setMonth(d.getMonth() + count * 3);\n return d;\n case \"year\":\n d.setFullYear(d.getFullYear() + count);\n return d;\n }\n}\n\n/** Snap an arbitrary date to the nearest grid-unit boundary. */\nexport function snapToGrid(date: Date, viewMode: ViewMode): Date {\n const floor = startOfUnit(date, viewMode);\n const ceil = addUnit(floor, viewMode, 1);\n const mid = (floor.getTime() + ceil.getTime()) / 2;\n return date.getTime() < mid ? floor : ceil;\n}\n\nfunction isMajorBoundary(date: Date, viewMode: ViewMode): boolean {\n switch (viewMode) {\n case \"hour\":\n return date.getHours() === 0;\n case \"day\":\n return date.getDate() === 1;\n case \"week\":\n return date.getDate() <= 7 && date.getDay() === 1;\n case \"month\":\n return date.getMonth() === 0;\n case \"quarter\":\n return date.getMonth() === 0;\n case \"year\":\n return false;\n }\n}\n\nfunction labelFor(date: Date, viewMode: ViewMode): string {\n switch (viewMode) {\n case \"hour\": {\n const h = date.getHours();\n const period = h >= 12 ? \"PM\" : \"AM\";\n const h12 = h % 12 === 0 ? 12 : h % 12;\n return `${h12} ${period}`;\n }\n case \"day\":\n return `${WEEKDAY_LABELS[date.getDay()]} ${date.getDate()}`;\n case \"week\":\n return `${MONTH_LABELS[date.getMonth()]} ${date.getDate()}`;\n case \"month\":\n return `${MONTH_LABELS[date.getMonth()]} ${date.getFullYear()}`;\n case \"quarter\": {\n const q = Math.floor(date.getMonth() / 3) + 1;\n return `Q${q} ${date.getFullYear()}`;\n }\n case \"year\":\n return `${date.getFullYear()}`;\n }\n}\n\nexport interface GeneratedTick {\n date: Date;\n x: number;\n label: string;\n isWeekend: boolean;\n isNonWorking: boolean;\n isToday: boolean;\n isMajorBoundary: boolean;\n}\n\n/**\n * Generate header ticks spanning [rangeStart, rangeEnd], one per grid unit.\n * `x` is relative to rangeStart (the caller offsets it if the model has left padding).\n */\nexport function generateTicks(\n rangeStart: Date,\n rangeEnd: Date,\n viewMode: ViewMode,\n columnWidth: number,\n today: Date = new Date(),\n calendar?: WorkingCalendar\n): GeneratedTick[] {\n if (!isValidDate(rangeStart) || !isValidDate(rangeEnd)) return [];\n const ticks: GeneratedTick[] = [];\n let cursor = startOfUnit(rangeStart, viewMode);\n const scale = pxPerMs(viewMode, columnWidth);\n let guard = 0;\n const MAX_TICKS = 2000;\n const dayLevel = viewMode === \"day\" || viewMode === \"hour\";\n while (cursor.getTime() < rangeEnd.getTime() && guard < MAX_TICKS) {\n guard++;\n const x = (cursor.getTime() - rangeStart.getTime()) * scale;\n ticks.push({\n date: new Date(cursor.getTime()),\n x,\n label: labelFor(cursor, viewMode),\n isWeekend: dayLevel ? isWeekend(cursor) : false,\n isNonWorking:\n viewMode === \"hour\" && calendar?.workingHours\n ? !isWorkingTime(cursor, calendar)\n : dayLevel\n ? isNonWorkingDay(cursor, calendar)\n : false,\n isToday: isSameDay(cursor, today) && dayLevel,\n isMajorBoundary: isMajorBoundary(cursor, viewMode),\n });\n cursor = addUnit(cursor, viewMode, 1);\n }\n return ticks;\n}\n\nexport { MS_PER_HOUR, MS_PER_DAY, MS_PER_WEEK };\n","import { MS_PER_DAY } from \"./date-utils\";\n\n/**\n * Global working-time definition: which weekdays are worked, plus a list of\n * one-off non-working dates (holidays). Both are optional — an unset\n * `workingDays` defaults to Mon-Fri, an unset `holidays` list is empty.\n */\nexport interface WorkingCalendar {\n /** index 0 = Sunday ... 6 = Saturday. Defaults to Mon-Fri working. */\n workingDays?: boolean[];\n /** ISO \"YYYY-MM-DD\" dates that are non-working regardless of weekday. */\n holidays?: string[];\n /**\n * Daily working window, hour-of-day 0-24 (e.g. { start: 9, end: 17 }).\n * Only affects `isWorkingTime`/`shiftToWorkingTime` and hour-level tick\n * shading - task durations stay wall-clock (a 3-day task is still 3\n * calendar days, not 3 working-window days); this narrows *anchor\n * points* to the working window, it doesn't re-derive duration math.\n */\n workingHours?: { start: number; end: number };\n}\n\nconst DEFAULT_WORKING_DAYS = [false, true, true, true, true, true, false];\n\nfunction workingDaysOf(calendar?: WorkingCalendar): boolean[] {\n return calendar?.workingDays ?? DEFAULT_WORKING_DAYS;\n}\n\nfunction toISODate(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n}\n\nexport function isHoliday(date: Date, calendar?: WorkingCalendar): boolean {\n if (!calendar?.holidays || calendar.holidays.length === 0) return false;\n const iso = toISODate(date);\n return calendar.holidays.includes(iso);\n}\n\nexport function isWorkingDay(date: Date, calendar?: WorkingCalendar): boolean {\n const days = workingDaysOf(calendar);\n const dow = date.getDay();\n if (!days[dow]) return false;\n return !isHoliday(date, calendar);\n}\n\nexport function isNonWorkingDay(date: Date, calendar?: WorkingCalendar): boolean {\n return !isWorkingDay(date, calendar);\n}\n\n/** Next working day at/after `date` (same time-of-day), scanning forward at most 366 days. */\nexport function nextWorkingDay(date: Date, calendar?: WorkingCalendar): Date {\n let cursor = new Date(date.getTime());\n let guard = 0;\n while (!isWorkingDay(cursor, calendar) && guard++ < 366) {\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n }\n return cursor;\n}\n\n/** Previous working day at/before `date` (same time-of-day), scanning backward at most 366 days. */\nexport function previousWorkingDay(date: Date, calendar?: WorkingCalendar): Date {\n let cursor = new Date(date.getTime());\n let guard = 0;\n while (!isWorkingDay(cursor, calendar) && guard++ < 366) {\n cursor = new Date(cursor.getTime() - MS_PER_DAY);\n }\n return cursor;\n}\n\n/**\n * Nudge `date` onto a working day if it isn't already, moving in `direction`\n * (1 = forward, -1 = backward). No-op (besides cloning) when no calendar is given\n * or `date` is already a working day.\n */\nexport function shiftToWorkingDay(date: Date, calendar: WorkingCalendar | undefined, direction: 1 | -1): Date {\n if (!calendar) return new Date(date.getTime());\n return direction === 1 ? nextWorkingDay(date, calendar) : previousWorkingDay(date, calendar);\n}\n\nfunction hourOfDay(date: Date): number {\n return date.getHours() + date.getMinutes() / 60 + date.getSeconds() / 3600;\n}\n\nexport function isWithinWorkingHours(date: Date, calendar?: WorkingCalendar): boolean {\n const hours = calendar?.workingHours;\n if (!hours) return true;\n const h = hourOfDay(date);\n return h >= hours.start && h < hours.end;\n}\n\n/** Working day AND (no workingHours set, or within them). */\nexport function isWorkingTime(date: Date, calendar?: WorkingCalendar): boolean {\n return isWorkingDay(date, calendar) && isWithinWorkingHours(date, calendar);\n}\n\nfunction applyHour(date: Date, hour: number): void {\n const wholeHours = Math.floor(hour);\n const minutes = Math.round((hour - wholeHours) * 60);\n date.setHours(wholeHours, minutes, 0, 0);\n}\n\n/**\n * Like shiftToWorkingDay, but also snaps onto the daily working-hours window\n * when one is configured: forward past a day's end (or on a non-working day)\n * moves to the next working day's start; backward before a day's start (or\n * on a non-working day) moves to the previous working day's end. No-op\n * without a calendar.\n */\nexport function shiftToWorkingTime(\n date: Date,\n calendar: WorkingCalendar | undefined,\n direction: 1 | -1\n): Date {\n if (!calendar) return new Date(date.getTime());\n const wh = calendar.workingHours;\n let guard = 0;\n let cursor = new Date(date.getTime());\n\n while (guard++ < 400) {\n if (!isWorkingDay(cursor, calendar)) {\n cursor = direction === 1 ? nextWorkingDay(cursor, calendar) : previousWorkingDay(cursor, calendar);\n if (wh) applyHour(cursor, direction === 1 ? wh.start : wh.end);\n continue;\n }\n if (!wh) return cursor;\n\n const h = hourOfDay(cursor);\n if (h < wh.start) {\n if (direction === 1) {\n applyHour(cursor, wh.start);\n return cursor;\n }\n cursor = previousWorkingDay(new Date(cursor.getTime() - MS_PER_DAY), calendar);\n applyHour(cursor, wh.end);\n // an instant before end is still \"within\" [start, end); nudge back 1ms to land inside the window\n return new Date(cursor.getTime() - 1);\n }\n if (h >= wh.end) {\n if (direction === 1) {\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n applyHour(cursor, wh.start);\n continue;\n }\n applyHour(cursor, wh.end);\n return new Date(cursor.getTime() - 1);\n }\n return cursor;\n }\n return cursor;\n}\n","import type { WorkingCalendar } from \"./calendar\";\nimport { computeCriticalPath } from \"./critical-path\";\nimport { addUnit, dateToX, generateTicks, isValidDate } from \"./date-utils\";\nimport type {\n GanttColumn,\n GanttDependency,\n GanttMarker,\n GanttRenderBar,\n GanttRenderLink,\n GanttRenderModel,\n GanttRenderRow,\n GanttTask,\n GanttTheme,\n ViewMode,\n} from \"./types\";\n\nexport interface LayoutInput {\n tasks: GanttTask[];\n dependencies: GanttDependency[];\n viewMode: ViewMode;\n columnWidth: number;\n theme: GanttTheme;\n columns: GanttColumn[];\n showCriticalPath?: boolean;\n showBaseline?: boolean;\n showDeadlines?: boolean;\n showAssigneeAvatars?: boolean;\n calendar?: WorkingCalendar;\n markers?: GanttMarker[];\n /** a group task with no explicit `progress` gets a duration-weighted average of its children's progress instead of 0 */\n autoRollupProgress?: boolean;\n selectedTaskIds?: Set<string>;\n /** restrict layout to a page of top-level rows, in document order (1-indexed) */\n pagination?: { pageSize: number; page: number };\n}\n\ninterface TreeNode {\n task: GanttTask;\n children: TreeNode[];\n computedStart: Date | null;\n computedEnd: Date | null;\n computedProgress: number;\n}\n\nfunction buildTree(tasks: GanttTask[]): { roots: TreeNode[]; nodeById: Map<string, TreeNode> } {\n const nodeById = new Map<string, TreeNode>();\n for (const task of tasks) {\n nodeById.set(task.id, { task, children: [], computedStart: null, computedEnd: null, computedProgress: 0 });\n }\n const roots: TreeNode[] = [];\n for (const task of tasks) {\n const node = nodeById.get(task.id);\n if (!node) continue;\n const parent = task.parentId ? nodeById.get(task.parentId) : undefined;\n if (parent) {\n parent.children.push(node);\n } else {\n roots.push(node);\n }\n }\n return { roots, nodeById };\n}\n\n/** Post-order: fills in computedStart/computedEnd for group nodes lacking explicit valid dates. */\nfunction computeSpans(node: TreeNode): void {\n for (const child of node.children) computeSpans(child);\n\n const hasExplicit = isValidDate(node.task.start) && isValidDate(node.task.end);\n if (hasExplicit) {\n node.computedStart = node.task.start;\n node.computedEnd = node.task.end;\n return;\n }\n if (node.children.length === 0) {\n node.computedStart = null;\n node.computedEnd = null;\n return;\n }\n let min: number | null = null;\n let max: number | null = null;\n for (const child of node.children) {\n if (child.computedStart) {\n const t = child.computedStart.getTime();\n min = min === null ? t : Math.min(min, t);\n }\n if (child.computedEnd) {\n const t = child.computedEnd.getTime();\n max = max === null ? t : Math.max(max, t);\n }\n }\n node.computedStart = min === null ? null : new Date(min);\n node.computedEnd = max === null ? null : new Date(max);\n}\n\n/** Post-order: fills in computedProgress for group nodes with no explicit `progress`, duration-weighted over children. */\nfunction computeProgressRollup(node: TreeNode): void {\n for (const child of node.children) computeProgressRollup(child);\n\n if (node.task.progress !== undefined) {\n node.computedProgress = Math.min(100, Math.max(0, node.task.progress));\n return;\n }\n if (node.children.length === 0) {\n node.computedProgress = 0;\n return;\n }\n let weightedSum = 0;\n let totalWeight = 0;\n for (const child of node.children) {\n const duration =\n child.computedStart && child.computedEnd\n ? Math.max(1, child.computedEnd.getTime() - child.computedStart.getTime())\n : 1;\n weightedSum += child.computedProgress * duration;\n totalWeight += duration;\n }\n node.computedProgress = totalWeight > 0 ? weightedSum / totalWeight : 0;\n}\n\ninterface FlatRow {\n node: TreeNode;\n depth: number;\n visible: boolean;\n}\n\n/** O(n) document-order flatten, skipping descendants of collapsed groups. */\nfunction flatten(roots: TreeNode[]): FlatRow[] {\n const out: FlatRow[] = [];\n const stack: { node: TreeNode; depth: number; parentCollapsed: boolean }[] = [];\n for (let i = roots.length - 1; i >= 0; i--) {\n const r = roots[i];\n if (r) stack.push({ node: r, depth: 0, parentCollapsed: false });\n }\n while (stack.length > 0) {\n const item = stack.pop();\n if (!item) continue;\n const { node, depth, parentCollapsed } = item;\n if (parentCollapsed) continue;\n out.push({ node, depth, visible: true });\n const collapsedHere = !!node.task.collapsed;\n for (let i = node.children.length - 1; i >= 0; i--) {\n const child = node.children[i];\n if (child) stack.push({ node: child, depth: depth + 1, parentCollapsed: collapsedHere });\n }\n }\n return out;\n}\n\n/**\n * Rough glyph-width heuristic (no DOM measurement available at layout time)\n * for sizing the canvas to fit bar labels drawn past the end of short bars.\n * Deliberately generous — overestimating just adds a little trailing\n * whitespace, underestimating clips real content.\n */\nfunction estimateTextWidth(text: string, fontSize: number): number {\n return text.length * fontSize * 0.62;\n}\n\nfunction anchorPoint(\n bar: { x: number; y: number; width: number; height: number },\n side: \"start\" | \"end\"\n): { x: number; y: number } {\n const y = bar.y + bar.height / 2;\n return side === \"start\" ? { x: bar.x, y } : { x: bar.x + bar.width, y };\n}\n\nfunction devWarn(message: string): void {\n const isProd =\n typeof process !== \"undefined\" && process.env && process.env.NODE_ENV === \"production\";\n if (!isProd) console.warn(`[gantt-core] ${message}`);\n}\n\nfunction validateInputs(tasks: GanttTask[], dependencies: GanttDependency[]): void {\n const ids = new Set(tasks.map((t) => t.id));\n for (const dep of dependencies) {\n if (!ids.has(dep.fromId) || !ids.has(dep.toId)) {\n devWarn(\n `dependency references a non-existent task: ${dep.fromId} -> ${dep.toId}`\n );\n }\n }\n for (const task of tasks) {\n if (isValidDate(task.start) && isValidDate(task.end) && task.end < task.start) {\n devWarn(`task \"${task.id}\" has end date before start date`);\n }\n }\n\n const outgoing = new Map<string, string[]>();\n for (const dep of dependencies) {\n if (!ids.has(dep.fromId) || !ids.has(dep.toId)) continue;\n const list = outgoing.get(dep.fromId) ?? [];\n list.push(dep.toId);\n outgoing.set(dep.fromId, list);\n }\n const indegree = new Map<string, number>();\n for (const id of ids) indegree.set(id, 0);\n for (const [, targets] of outgoing) {\n for (const t of targets) indegree.set(t, (indegree.get(t) ?? 0) + 1);\n }\n const queue: string[] = [];\n for (const [id, deg] of indegree) if (deg === 0) queue.push(id);\n let visited = 0;\n let qi = 0;\n const maxOps = ids.size + dependencies.length + 1;\n let ops = 0;\n while (qi < queue.length && ops++ <= maxOps) {\n const id = queue[qi++];\n if (id === undefined) break;\n visited++;\n for (const next of outgoing.get(id) ?? []) {\n const d = (indegree.get(next) ?? 0) - 1;\n indegree.set(next, d);\n if (d === 0) queue.push(next);\n }\n }\n if (visited !== ids.size) {\n devWarn(\"circular dependency detected; critical path / scheduling for affected tasks is skipped\");\n }\n}\n\nfunction linkPath(from: { x: number; y: number }, to: { x: number; y: number }): string {\n const dx = Math.max(20, Math.abs(to.x - from.x) / 2);\n const c1x = from.x + dx;\n const c1y = from.y;\n const c2x = to.x - dx;\n const c2y = to.y;\n return `M ${from.x} ${from.y} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${to.x} ${to.y}`;\n}\n\nexport function computeLayout(input: LayoutInput): GanttRenderModel {\n const {\n tasks,\n dependencies,\n viewMode,\n columnWidth,\n theme,\n columns,\n showCriticalPath = false,\n showBaseline = false,\n showDeadlines = true,\n calendar,\n markers = [],\n autoRollupProgress = false,\n selectedTaskIds,\n pagination,\n } = input;\n\n validateInputs(tasks, dependencies);\n\n const { roots, nodeById } = buildTree(tasks);\n for (const root of roots) computeSpans(root);\n if (autoRollupProgress) {\n for (const root of roots) computeProgressRollup(root);\n }\n\n let visibleRoots = roots;\n if (pagination && pagination.pageSize > 0) {\n const start = Math.max(0, (pagination.page - 1) * pagination.pageSize);\n visibleRoots = roots.slice(start, start + pagination.pageSize);\n }\n\n const flatRows = flatten(visibleRoots);\n const visibleIds = new Set(flatRows.map((f) => f.node.task.id));\n\n const { criticalTasks, criticalLinks } = showCriticalPath\n ? computeCriticalPath(tasks, dependencies)\n : { criticalTasks: new Set<string>(), criticalLinks: new Set<string>() };\n\n let rangeMin: number | null = null;\n let rangeMax: number | null = null;\n for (const row of flatRows) {\n const s = row.node.computedStart;\n const e = row.node.computedEnd;\n if (s) rangeMin = rangeMin === null ? s.getTime() : Math.min(rangeMin, s.getTime());\n if (e) rangeMax = rangeMax === null ? e.getTime() : Math.max(rangeMax, e.getTime());\n }\n const now = Date.now();\n const rawRangeStart = rangeMin === null ? new Date(now) : new Date(rangeMin);\n const rawRangeEnd = rangeMax === null ? new Date(now + 1) : new Date(rangeMax);\n const paddedStart = addUnit(rawRangeStart, viewMode, -1);\n const paddedEnd = addUnit(rawRangeEnd, viewMode, 1);\n\n const rows: GanttRenderRow[] = [];\n const bars: GanttRenderBar[] = [];\n const barByTaskId = new Map<string, GanttRenderBar>();\n\n flatRows.forEach((row, index) => {\n const { task } = row.node;\n const y = index * theme.rowHeight;\n rows.push({\n taskId: task.id,\n y,\n height: theme.rowHeight,\n isGroup: !!task.isGroup,\n collapsed: !!task.collapsed,\n depth: row.depth,\n hasChildren: row.node.children.length > 0,\n });\n\n const start = row.node.computedStart;\n const end = row.node.computedEnd;\n if (!start || !end) return;\n\n const x = dateToX(start, paddedStart, viewMode, columnWidth);\n const rawWidth = Math.max(0, dateToX(end, paddedStart, viewMode, columnWidth) - x);\n if (!Number.isFinite(x) || !Number.isFinite(rawWidth)) return;\n // A real (non-instant) task should stay visible as a sliver even when zoomed\n // out far enough that its true duration rounds to a handful of pixels.\n const width = rawWidth > 0 ? Math.max(rawWidth, 3) : rawWidth;\n\n const progress =\n task.progress !== undefined\n ? Math.min(100, Math.max(0, task.progress))\n : autoRollupProgress\n ? row.node.computedProgress\n : 0;\n const barHeight = theme.barHeight;\n const barY = y + (theme.rowHeight - barHeight) / 2;\n\n const color = task.color ?? (task.isGroup ? theme.groupBarColor : theme.barColor);\n const progressColor = task.progressColor ?? theme.barProgressColor;\n\n const bar: GanttRenderBar = {\n taskId: task.id,\n x,\n y: barY,\n width,\n height: barHeight,\n progressWidth: (width * progress) / 100,\n color,\n progressColor,\n label: task.name,\n isCritical: showCriticalPath && criticalTasks.has(task.id),\n isMilestone: task.isMilestone ?? start.getTime() === end.getTime(),\n isSelected: selectedTaskIds?.has(task.id) ?? false,\n };\n\n if (task.segments && task.segments.length > 0) {\n const validSegments = task.segments.filter(\n (s) => isValidDate(s.start) && isValidDate(s.end) && s.end.getTime() > s.start.getTime()\n );\n if (validSegments.length > 0) {\n bar.segments = validSegments.map((s) => {\n const sx = dateToX(s.start, paddedStart, viewMode, columnWidth);\n const sw = Math.max(0, dateToX(s.end, paddedStart, viewMode, columnWidth) - sx);\n return { x: sx - x, width: sw, progressWidth: (sw * progress) / 100 };\n });\n }\n }\n\n if (showBaseline && isValidDate(task.baselineStart) && isValidDate(task.baselineEnd)) {\n const bx = dateToX(task.baselineStart, paddedStart, viewMode, columnWidth);\n const bw = Math.max(\n 0,\n dateToX(task.baselineEnd, paddedStart, viewMode, columnWidth) - bx\n );\n if (Number.isFinite(bx) && Number.isFinite(bw)) {\n bar.baseline = { x: bx, width: bw };\n }\n }\n\n if (showBaseline && task.baselines && task.baselines.length > 0) {\n bar.baselines = task.baselines\n .filter((b) => isValidDate(b.start) && isValidDate(b.end))\n .map((b) => {\n const bx = dateToX(b.start, paddedStart, viewMode, columnWidth);\n const bw = Math.max(0, dateToX(b.end, paddedStart, viewMode, columnWidth) - bx);\n return { label: b.label, x: bx, width: bw };\n })\n .filter((b) => Number.isFinite(b.x) && Number.isFinite(b.width));\n }\n\n if (showDeadlines && isValidDate(task.deadline)) {\n const dx = dateToX(task.deadline, paddedStart, viewMode, columnWidth);\n if (Number.isFinite(dx)) {\n bar.deadlineX = dx;\n bar.isOverdue = end.getTime() > task.deadline.getTime();\n }\n }\n\n bars.push(bar);\n barByTaskId.set(task.id, bar);\n });\n\n function nearestVisibleAncestorId(taskId: string): string | null {\n let currentId: string | null = taskId;\n const guard = new Set<string>();\n while (currentId !== null && !guard.has(currentId)) {\n guard.add(currentId);\n if (visibleIds.has(currentId)) return currentId;\n const node = nodeById.get(currentId);\n currentId = node?.task.parentId ?? null;\n }\n return null;\n }\n\n const links: GanttRenderLink[] = [];\n for (const dep of dependencies) {\n if (!nodeById.has(dep.fromId) || !nodeById.has(dep.toId)) continue;\n const fromVisibleId = nearestVisibleAncestorId(dep.fromId);\n const toVisibleId = nearestVisibleAncestorId(dep.toId);\n if (!fromVisibleId || !toVisibleId || fromVisibleId === toVisibleId) continue;\n const fromBar = barByTaskId.get(fromVisibleId);\n const toBar = barByTaskId.get(toVisibleId);\n if (!fromBar || !toBar) continue;\n\n const fromSide = dep.type === \"SS\" || dep.type === \"SF\" ? \"start\" : \"end\";\n const toSide = dep.type === \"FF\" || dep.type === \"SF\" ? \"end\" : \"start\";\n const from = anchorPoint(fromBar, fromSide);\n const to = anchorPoint(toBar, toSide);\n\n links.push({\n fromId: dep.fromId,\n toId: dep.toId,\n type: dep.type,\n path: linkPath(from, to),\n isCritical: showCriticalPath && criticalLinks.has(`${dep.fromId}->${dep.toId}`),\n });\n }\n\n const ticks = generateTicks(paddedStart, paddedEnd, viewMode, columnWidth, new Date(), calendar).map(\n (t) => ({\n x: t.x,\n label: t.label,\n isWeekend: t.isWeekend,\n isNonWorking: t.isNonWorking,\n isToday: t.isToday,\n isMajorBoundary: t.isMajorBoundary,\n })\n );\n\n const renderMarkers = markers\n .filter((m) => isValidDate(m.date))\n .map((m) => ({\n x: dateToX(m.date, paddedStart, viewMode, columnWidth),\n label: m.label ?? \"\",\n color: m.color ?? theme.markerColor,\n }))\n .filter((m) => Number.isFinite(m.x));\n\n let width = 0;\n for (const tick of ticks) width = Math.max(width, tick.x);\n for (const bar of bars) {\n width = Math.max(width, bar.x + bar.width);\n if (bar.label) {\n const labelOffset = bar.isMilestone ? theme.barHeight * 0.4 + 8 : bar.width + 6;\n width = Math.max(width, bar.x + labelOffset + estimateTextWidth(bar.label, theme.fontSize));\n }\n }\n width += columnWidth;\n\n const height = rows.length * theme.rowHeight;\n\n return {\n width,\n height,\n rowHeight: theme.rowHeight,\n headerHeight: theme.headerHeight,\n rows,\n bars,\n links,\n ticks,\n columns,\n theme,\n markers: renderMarkers,\n rangeStart: paddedStart,\n };\n}\n","export interface Command {\n do(): void;\n undo(): void;\n label?: string;\n}\n\nexport type HistoryChangeListener = (state: { canUndo: boolean; canRedo: boolean }) => void;\n\nexport class HistoryManager {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private onChange?: HistoryChangeListener;\n\n constructor(onChange?: HistoryChangeListener) {\n this.onChange = onChange;\n }\n\n push(cmd: Command): void {\n cmd.do();\n this.undoStack.push(cmd);\n this.redoStack = [];\n this.notify();\n }\n\n undo(): boolean {\n const cmd = this.undoStack.pop();\n if (!cmd) return false;\n cmd.undo();\n this.redoStack.push(cmd);\n this.notify();\n return true;\n }\n\n redo(): boolean {\n const cmd = this.redoStack.pop();\n if (!cmd) return false;\n cmd.do();\n this.undoStack.push(cmd);\n this.notify();\n return true;\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n private notify(): void {\n this.onChange?.({ canUndo: this.canUndo, canRedo: this.canRedo });\n }\n}\n","export type Listener<TPayload> = (payload: TPayload) => void;\n\nexport class EventEmitter<TEventMap extends Record<string, unknown>> {\n private listeners: { [K in keyof TEventMap]?: Set<Listener<TEventMap[K]>> } = {};\n\n on<K extends keyof TEventMap>(event: K, listener: Listener<TEventMap[K]>): void {\n let set = this.listeners[event];\n if (!set) {\n set = new Set();\n this.listeners[event] = set;\n }\n set.add(listener);\n }\n\n off<K extends keyof TEventMap>(event: K, listener: Listener<TEventMap[K]>): void {\n this.listeners[event]?.delete(listener);\n }\n\n once<K extends keyof TEventMap>(event: K, listener: Listener<TEventMap[K]>): void {\n const wrapper: Listener<TEventMap[K]> = (payload) => {\n this.off(event, wrapper);\n listener(payload);\n };\n this.on(event, wrapper);\n }\n\n emit<K extends keyof TEventMap>(event: K, payload: TEventMap[K]): void {\n const set = this.listeners[event];\n if (!set) return;\n for (const listener of Array.from(set)) {\n listener(payload);\n }\n }\n\n removeAllListeners(): void {\n this.listeners = {};\n }\n}\n","import type { GanttTask } from \"./types\";\n\nconst CSV_COLUMNS = [\"id\", \"name\", \"start\", \"end\", \"progress\", \"parentId\"] as const;\n\nfunction escapeCsvField(value: string): string {\n if (/[\",\\n]/.test(value)) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\nfunction parseCsvLine(line: string): string[] {\n const fields: string[] = [];\n let current = \"\";\n let inQuotes = false;\n for (let i = 0; i < line.length; i++) {\n const char = line[i] ?? \"\";\n if (inQuotes) {\n if (char === '\"') {\n if (line[i + 1] === '\"') {\n current += '\"';\n i++;\n } else {\n inQuotes = false;\n }\n } else {\n current += char;\n }\n } else if (char === '\"') {\n inQuotes = true;\n } else if (char === \",\") {\n fields.push(current);\n current = \"\";\n } else {\n current += char;\n }\n }\n fields.push(current);\n return fields;\n}\n\nexport function tasksToCSV(tasks: GanttTask[]): string {\n const lines = [CSV_COLUMNS.join(\",\")];\n for (const task of tasks) {\n const row = [\n task.id,\n task.name,\n task.start instanceof Date ? task.start.toISOString() : \"\",\n task.end instanceof Date ? task.end.toISOString() : \"\",\n task.progress !== undefined ? String(task.progress) : \"\",\n task.parentId ?? \"\",\n ].map((v) => escapeCsvField(String(v)));\n lines.push(row.join(\",\"));\n }\n return lines.join(\"\\n\");\n}\n\nexport function tasksFromCSV(csv: string): GanttTask[] {\n const lines = csv.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length === 0) return [];\n const header = parseCsvLine(lines[0] ?? \"\");\n const colIndex = new Map(header.map((h, i) => [h.trim(), i]));\n\n const tasks: GanttTask[] = [];\n for (let i = 1; i < lines.length; i++) {\n const fields = parseCsvLine(lines[i] ?? \"\");\n const get = (col: string): string => {\n const idx = colIndex.get(col);\n return idx === undefined ? \"\" : fields[idx] ?? \"\";\n };\n const id = get(\"id\");\n if (!id) continue;\n const progressRaw = get(\"progress\");\n const parentIdRaw = get(\"parentId\");\n tasks.push({\n id,\n name: get(\"name\"),\n start: new Date(get(\"start\")),\n end: new Date(get(\"end\")),\n progress: progressRaw ? Number(progressRaw) : undefined,\n parentId: parentIdRaw || null,\n });\n }\n return tasks;\n}\n","import { explicitThemeToCssVars, themedFill } from \"./theme\";\nimport type {\n GanttColumn,\n GanttRenderBar,\n GanttRenderModel,\n GanttRenderRow,\n GanttTask,\n GanttTheme,\n} from \"./types\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\nexport interface RendererOptions {\n keyboardAccessible?: boolean;\n showAssigneeAvatars?: boolean;\n virtualScroll?: boolean;\n overscan?: number;\n onRenameCommit?: (taskId: string, name: string) => void;\n onColumnResize?: (columnId: string, width: number) => void;\n onColumnReorder?: (order: string[]) => void;\n onRowReorder?: (draggedTaskId: string, targetTaskId: string, position: \"before\" | \"after\" | \"inside\") => void;\n}\n\n/**\n * Only http(s), mailto, and scheme-relative/relative URLs are allowed in a getHref() cell -\n * anything else (javascript:, data:, vbscript:, etc.) renders as plain text instead of a link.\n */\nexport function isSafeHref(url: string): boolean {\n try {\n const base =\n typeof location !== \"undefined\" && location.origin ? location.origin : \"http://localhost\";\n const parsed = new URL(url, base);\n return (\n parsed.protocol === \"http:\" || parsed.protocol === \"https:\" || parsed.protocol === \"mailto:\"\n );\n } catch {\n return false;\n }\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className?: string\n): HTMLElementTagNameMap[K] {\n const e = document.createElement(tag);\n if (className) e.className = className;\n return e;\n}\n\nfunction svgEl<K extends keyof SVGElementTagNameMap>(tag: K): SVGElementTagNameMap[K] {\n return document.createElementNS(SVG_NS, tag) as SVGElementTagNameMap[K];\n}\n\nfunction initials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n const first = parts[0]?.[0] ?? \"\";\n const last = parts.length > 1 ? parts[parts.length - 1]?.[0] ?? \"\" : \"\";\n return (first + last).toUpperCase();\n}\n\nexport class GanttRenderer {\n readonly root: HTMLElement;\n readonly gridPanel: HTMLElement;\n readonly timelineScroll: HTMLElement;\n readonly svg: SVGSVGElement;\n private markerDefsId: string;\n private scrollListener?: () => void;\n private lastModel: GanttRenderModel | null = null;\n private lastTasks: GanttTask[] = [];\n private lastColumns: GanttColumn[] = [];\n\n constructor(\n private container: HTMLElement,\n private options: RendererOptions = {}\n ) {\n this.markerDefsId = `gantt-arrow-${Math.random().toString(36).slice(2)}`;\n this.root = el(\"div\", \"gantt-root\");\n this.gridPanel = el(\"div\", \"gantt-grid-panel\");\n this.timelineScroll = el(\"div\", \"gantt-timeline-scroll\");\n this.svg = svgEl(\"svg\");\n this.svg.classList.add(\"gantt-svg\");\n this.timelineScroll.appendChild(this.svg);\n this.root.appendChild(this.gridPanel);\n this.root.appendChild(this.timelineScroll);\n this.container.appendChild(this.root);\n\n if (options.virtualScroll !== false && typeof document !== \"undefined\") {\n this.scrollListener = () => this.rerenderVisibleOnly();\n this.timelineScroll.addEventListener(\"scroll\", this.scrollListener);\n }\n\n this.gridPanel.addEventListener(\"dblclick\", this.onGridDoubleClick);\n }\n\n private onGridDoubleClick = (evt: MouseEvent): void => {\n if (!this.options.onRenameCommit) return;\n const target = evt.target as HTMLElement;\n const cell = target.closest<HTMLElement>(\"[data-gantt-name-cell]\");\n if (!cell || cell.querySelector(\"input\")) return;\n const taskId = cell.dataset.ganttNameCell;\n if (!taskId) return;\n const currentText = cell.dataset.ganttNameValue ?? \"\";\n cell.replaceChildren();\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.value = currentText;\n input.className = \"gantt-rename-input\";\n cell.appendChild(input);\n input.focus();\n input.select();\n\n const commit = () => {\n this.options.onRenameCommit?.(taskId, input.value);\n };\n const cancel = () => {\n this.rerenderVisibleOnly();\n };\n input.addEventListener(\"keydown\", (kEvt) => {\n if (kEvt.key === \"Enter\") {\n kEvt.preventDefault();\n commit();\n } else if (kEvt.key === \"Escape\") {\n kEvt.preventDefault();\n cancel();\n }\n });\n input.addEventListener(\"blur\", commit, { once: true });\n };\n\n render(\n model: GanttRenderModel,\n tasks: GanttTask[],\n columns: GanttColumn[],\n explicitTheme?: Partial<GanttTheme>\n ): void {\n this.lastModel = model;\n this.lastTasks = tasks;\n this.lastColumns = columns;\n\n // Only inline the fields the consumer explicitly set via the JS `theme` option.\n // Everything else is left undeclared here so external CSS (or our shipped\n // light/dark defaults in styles.css) controls it via var(--gantt-x, fallback)\n // on the painted elements below — an inline style on .gantt-root would otherwise\n // always beat a plain (non-!important) external stylesheet rule.\n const cssVars = explicitThemeToCssVars(explicitTheme);\n for (const key of Object.keys(cssVars)) {\n this.root.style.setProperty(key, cssVars[key] as string);\n }\n\n this.renderGridPanel(model, tasks, columns);\n this.renderTimeline(model, tasks);\n }\n\n private getViewportRowRange(model: GanttRenderModel): { startY: number; endY: number } {\n if (this.options.virtualScroll === false) {\n return { startY: -Infinity, endY: Infinity };\n }\n const overscan = (this.options.overscan ?? 5) * model.rowHeight;\n const scrollTop = this.timelineScroll.scrollTop || 0;\n const viewportHeight = this.timelineScroll.clientHeight || model.height;\n return {\n startY: scrollTop - overscan,\n endY: scrollTop + viewportHeight + overscan,\n };\n }\n\n private rerenderVisibleOnly(): void {\n if (!this.lastModel) return;\n this.renderGridPanel(this.lastModel, this.lastTasks, this.lastColumns);\n this.renderTimeline(this.lastModel, this.lastTasks);\n }\n\n private renderGridPanel(\n model: GanttRenderModel,\n tasks: GanttTask[],\n columns: GanttColumn[]\n ): void {\n this.gridPanel.replaceChildren();\n const taskById = new Map(tasks.map((t) => [t.id, t]));\n const { startY, endY } = this.getViewportRowRange(model);\n\n const header = el(\"div\", \"gantt-grid-header-row\");\n header.style.height = `${model.headerHeight}px`;\n for (const col of columns) {\n header.appendChild(this.renderHeaderCell(col, columns));\n }\n this.gridPanel.appendChild(header);\n\n const body = el(\"div\", \"gantt-grid-body\");\n body.style.height = `${model.height}px`;\n\n model.rows.forEach((row, index) => {\n if (row.y + row.height < startY || row.y > endY) return;\n const task = taskById.get(row.taskId);\n if (!task) return;\n body.appendChild(this.renderGridRow(row, task, columns, index));\n });\n\n this.gridPanel.appendChild(body);\n }\n\n private renderHeaderCell(col: GanttColumn, columns: GanttColumn[]): HTMLElement {\n const cell = el(\"div\", \"gantt-grid-header-cell\");\n cell.style.position = \"relative\";\n if (col.width) cell.style.width = `${col.width}px`;\n cell.textContent = col.title;\n\n if (this.options.onColumnReorder) {\n cell.draggable = true;\n cell.style.cursor = \"grab\";\n cell.addEventListener(\"dragstart\", (evt) => {\n evt.dataTransfer?.setData(\"text/plain\", col.id);\n });\n cell.addEventListener(\"dragover\", (evt) => evt.preventDefault());\n cell.addEventListener(\"drop\", (evt) => {\n evt.preventDefault();\n const draggedId = evt.dataTransfer?.getData(\"text/plain\");\n if (!draggedId || draggedId === col.id) return;\n const order = columns.map((c) => c.id).filter((id) => id !== draggedId);\n const targetIndex = order.indexOf(col.id);\n order.splice(targetIndex, 0, draggedId);\n this.options.onColumnReorder?.(order);\n });\n }\n\n if (this.options.onColumnResize) {\n const handle = el(\"div\", \"gantt-col-resize-handle\");\n handle.style.position = \"absolute\";\n handle.style.right = \"0\";\n handle.style.top = \"0\";\n handle.style.bottom = \"0\";\n handle.style.width = \"6px\";\n handle.style.cursor = \"col-resize\";\n handle.addEventListener(\"pointerdown\", (evt) => {\n evt.preventDefault();\n evt.stopPropagation();\n const startX = evt.clientX;\n const startWidth = col.width ?? cell.getBoundingClientRect().width;\n const onMove = (moveEvt: PointerEvent) => {\n const newWidth = Math.max(30, startWidth + (moveEvt.clientX - startX));\n cell.style.width = `${newWidth}px`;\n };\n const onUp = (upEvt: PointerEvent) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n const newWidth = Math.max(30, startWidth + (upEvt.clientX - startX));\n this.options.onColumnResize?.(col.id, newWidth);\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n });\n cell.appendChild(handle);\n }\n\n return cell;\n }\n\n private renderGridRow(\n row: GanttRenderRow,\n task: GanttTask,\n columns: GanttColumn[],\n firstColumnIndex: number\n ): HTMLElement {\n const rowEl = el(\"div\", \"gantt-grid-row\");\n rowEl.style.position = \"absolute\";\n rowEl.style.top = `${row.y}px`;\n rowEl.style.height = `${row.height}px`;\n rowEl.dataset.ganttRow = task.id;\n if (this.options.keyboardAccessible) {\n rowEl.setAttribute(\"role\", \"row\");\n }\n\n if (this.options.onRowReorder) {\n rowEl.draggable = true;\n rowEl.style.cursor = \"grab\";\n rowEl.addEventListener(\"dragstart\", (evt) => {\n evt.dataTransfer?.setData(\"text/plain\", task.id);\n evt.stopPropagation();\n });\n rowEl.addEventListener(\"dragover\", (evt) => {\n evt.preventDefault();\n evt.stopPropagation();\n });\n rowEl.addEventListener(\"drop\", (evt) => {\n evt.preventDefault();\n evt.stopPropagation();\n const draggedId = evt.dataTransfer?.getData(\"text/plain\");\n if (!draggedId || draggedId === task.id) return;\n const bounds = rowEl.getBoundingClientRect();\n const fraction = (evt.clientY - bounds.top) / bounds.height;\n const position = fraction < 0.25 ? \"before\" : fraction > 0.75 ? \"after\" : \"inside\";\n this.options.onRowReorder?.(draggedId, task.id, position);\n });\n }\n\n columns.forEach((col, colIndex) => {\n const cell = el(\"div\", \"gantt-grid-cell\");\n if (col.width) cell.style.width = `${col.width}px`;\n if (col.align) cell.style.textAlign = col.align;\n\n const rawValue = col.accessor ? col.accessor(task) : colIndex === 0 ? task.name : \"\";\n const textValue = rawValue === null || rawValue === undefined ? \"\" : String(rawValue);\n\n if (colIndex === 0) {\n cell.dataset.ganttNameCell = task.id;\n cell.dataset.ganttNameValue = textValue;\n const indent = el(\"span\", \"gantt-indent\");\n indent.style.width = `${row.depth * 16}px`;\n cell.appendChild(indent);\n if (row.hasChildren) {\n const toggle = el(\"button\", \"gantt-toggle\");\n toggle.type = \"button\";\n toggle.dataset.ganttToggle = task.id;\n toggle.setAttribute(\"aria-label\", row.collapsed ? \"Expand\" : \"Collapse\");\n toggle.textContent = row.collapsed ? \"▸\" : \"▾\";\n cell.appendChild(toggle);\n }\n }\n\n const rendered = col.render ? col.render(task) : undefined;\n if (rendered instanceof HTMLElement) {\n cell.appendChild(rendered);\n } else if (typeof rendered === \"string\") {\n cell.appendChild(document.createTextNode(rendered));\n } else {\n const href = col.getHref ? col.getHref(task) : null;\n if (href && isSafeHref(href)) {\n const anchor = document.createElement(\"a\");\n anchor.href = href;\n anchor.target = col.linkTarget ?? \"_blank\";\n anchor.rel = \"noopener noreferrer\";\n anchor.textContent = textValue;\n cell.appendChild(anchor);\n } else {\n const textNode = document.createTextNode(textValue);\n cell.appendChild(textNode);\n }\n }\n\n rowEl.appendChild(cell);\n });\n\n void firstColumnIndex;\n return rowEl;\n }\n\n private renderTimeline(model: GanttRenderModel, tasks: GanttTask[]): void {\n this.svg.replaceChildren();\n this.svg.setAttribute(\"width\", String(model.width));\n this.svg.setAttribute(\"height\", String(model.headerHeight + model.height));\n this.svg.setAttribute(\"viewBox\", `0 0 ${model.width} ${model.headerHeight + model.height}`);\n\n const defs = svgEl(\"defs\");\n const marker = svgEl(\"marker\");\n marker.setAttribute(\"id\", this.markerDefsId);\n marker.setAttribute(\"markerWidth\", \"8\");\n marker.setAttribute(\"markerHeight\", \"8\");\n marker.setAttribute(\"refX\", \"6\");\n marker.setAttribute(\"refY\", \"3\");\n marker.setAttribute(\"orient\", \"auto\");\n const arrowPath = svgEl(\"path\");\n arrowPath.setAttribute(\"d\", \"M0,0 L6,3 L0,6 Z\");\n arrowPath.style.fill = themedFill(\"linkColor\", model.theme.linkColor);\n marker.appendChild(arrowPath);\n defs.appendChild(marker);\n this.svg.appendChild(defs);\n\n const { startY, endY } = this.getViewportRowRange(model);\n\n const bodyGroup = svgEl(\"g\");\n bodyGroup.setAttribute(\"transform\", `translate(0, ${model.headerHeight})`);\n\n this.renderGridLines(bodyGroup, model);\n this.renderRowBackgrounds(bodyGroup, model, startY, endY);\n this.renderBars(bodyGroup, model, tasks, startY, endY);\n this.renderLinks(bodyGroup, model, startY, endY);\n this.renderMarkers(bodyGroup, model);\n this.svg.appendChild(bodyGroup);\n\n this.renderHeader(model);\n }\n\n private renderGridLines(group: SVGGElement, model: GanttRenderModel): void {\n for (const tick of model.ticks) {\n if (tick.isNonWorking) {\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", String(tick.x));\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", \"1\");\n rect.setAttribute(\"height\", String(model.height));\n rect.style.fill = themedFill(\"weekendColor\", model.theme.weekendColor);\n group.appendChild(rect);\n }\n const line = svgEl(\"line\");\n line.setAttribute(\"x1\", String(tick.x));\n line.setAttribute(\"x2\", String(tick.x));\n line.setAttribute(\"y1\", \"0\");\n line.setAttribute(\"y2\", String(model.height));\n line.style.stroke = themedFill(\"gridColor\", model.theme.gridColor);\n line.setAttribute(\"stroke-width\", tick.isMajorBoundary ? \"1.5\" : \"1\");\n group.appendChild(line);\n\n if (tick.isToday) {\n const todayLine = svgEl(\"line\");\n todayLine.setAttribute(\"x1\", String(tick.x));\n todayLine.setAttribute(\"x2\", String(tick.x));\n todayLine.setAttribute(\"y1\", \"0\");\n todayLine.setAttribute(\"y2\", String(model.height));\n todayLine.style.stroke = themedFill(\"todayColor\", model.theme.todayColor);\n todayLine.setAttribute(\"stroke-width\", \"2\");\n group.appendChild(todayLine);\n }\n }\n }\n\n private renderMarkers(group: SVGGElement, model: GanttRenderModel): void {\n // Sorted so each label can be clipped to the space before the next marker,\n // the same way renderHeader clips tick labels to their column — otherwise\n // two markers close together at a coarse zoom garble into overlapping text.\n const sorted = [...model.markers].sort((a, b) => a.x - b.x);\n let defs: SVGDefsElement | null = null;\n sorted.forEach((marker, i) => {\n const line = svgEl(\"line\");\n line.setAttribute(\"x1\", String(marker.x));\n line.setAttribute(\"x2\", String(marker.x));\n line.setAttribute(\"y1\", \"0\");\n line.setAttribute(\"y2\", String(model.height));\n line.setAttribute(\"stroke\", marker.color);\n line.setAttribute(\"stroke-width\", \"1.5\");\n line.setAttribute(\"stroke-dasharray\", \"3 3\");\n line.dataset.ganttMarker = marker.label;\n group.appendChild(line);\n\n if (marker.label) {\n const nextX = sorted[i + 1]?.x ?? model.width;\n const cellWidth = Math.max(0, nextX - marker.x);\n if (!defs) {\n defs = svgEl(\"defs\");\n group.insertBefore(defs, group.firstChild);\n }\n const clipId = `${this.markerDefsId}-marker-${i}`;\n const clipPath = svgEl(\"clipPath\");\n clipPath.setAttribute(\"id\", clipId);\n const clipRect = svgEl(\"rect\");\n clipRect.setAttribute(\"x\", String(marker.x));\n clipRect.setAttribute(\"y\", \"0\");\n clipRect.setAttribute(\"width\", String(cellWidth));\n clipRect.setAttribute(\"height\", String(model.height));\n clipPath.appendChild(clipRect);\n defs.appendChild(clipPath);\n\n const label = svgEl(\"text\");\n label.setAttribute(\"x\", String(marker.x + 4));\n label.setAttribute(\"y\", \"12\");\n label.setAttribute(\"clip-path\", `url(#${clipId})`);\n label.setAttribute(\"fill\", marker.color);\n label.setAttribute(\"font-size\", String(model.theme.fontSize));\n label.setAttribute(\"font-family\", model.theme.fontFamily);\n label.textContent = marker.label;\n group.appendChild(label);\n }\n });\n }\n\n private renderHeader(model: GanttRenderModel): void {\n let headerGroup = this.svg.querySelector<SVGGElement>(\".gantt-header-group\");\n if (headerGroup) headerGroup.remove();\n headerGroup = svgEl(\"g\");\n headerGroup.setAttribute(\"class\", \"gantt-header-group\");\n const bg = svgEl(\"rect\");\n bg.setAttribute(\"x\", \"0\");\n bg.setAttribute(\"y\", \"0\");\n bg.setAttribute(\"width\", String(model.width));\n bg.setAttribute(\"height\", String(model.headerHeight));\n bg.style.fill = themedFill(\"backgroundColor\", model.theme.backgroundColor);\n headerGroup.appendChild(bg);\n\n const defs = svgEl(\"defs\");\n const ticks = model.ticks;\n for (let i = 0; i < ticks.length; i++) {\n const tick = ticks[i]!;\n // Clip each label to its own column so adjacent labels never bleed\n // into one another when the column is narrower than the label text\n // (e.g. week/month/year zoom, or narrow day columns).\n const cellWidth = (ticks[i + 1]?.x ?? model.width) - tick.x;\n const clipId = `${this.markerDefsId}-tick-${i}`;\n const clipPath = svgEl(\"clipPath\");\n clipPath.setAttribute(\"id\", clipId);\n const clipRect = svgEl(\"rect\");\n clipRect.setAttribute(\"x\", String(tick.x));\n clipRect.setAttribute(\"y\", \"0\");\n clipRect.setAttribute(\"width\", String(Math.max(0, cellWidth)));\n clipRect.setAttribute(\"height\", String(model.headerHeight));\n clipPath.appendChild(clipRect);\n defs.appendChild(clipPath);\n\n const text = svgEl(\"text\");\n text.setAttribute(\"x\", String(tick.x + 4));\n text.setAttribute(\"y\", String(model.headerHeight - 8));\n text.setAttribute(\"clip-path\", `url(#${clipId})`);\n text.style.fill = themedFill(\"textColor\", model.theme.textColor);\n text.setAttribute(\"font-size\", String(model.theme.fontSize));\n text.setAttribute(\"font-family\", model.theme.fontFamily);\n text.textContent = tick.label;\n headerGroup.appendChild(text);\n }\n headerGroup.insertBefore(defs, headerGroup.firstChild);\n this.svg.appendChild(headerGroup);\n }\n\n /**\n * Invisible full-width hit-test rects, one per row, behind the bars. Lets\n * drag-to-create (InteractionController) find \"which row / empty timeline\n * space was this pointerdown on\" without needing its own copy of the\n * layout math - a bar drawn on top naturally wins the hit test where one exists.\n */\n private renderRowBackgrounds(\n group: SVGGElement,\n model: GanttRenderModel,\n startY: number,\n endY: number\n ): void {\n for (const row of model.rows) {\n if (row.y + row.height < startY || row.y > endY) continue;\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", String(row.y));\n rect.setAttribute(\"width\", String(model.width));\n rect.setAttribute(\"height\", String(row.height));\n rect.setAttribute(\"fill\", \"transparent\");\n rect.style.pointerEvents = \"all\";\n rect.dataset.ganttRowBg = row.taskId;\n group.appendChild(rect);\n }\n }\n\n private renderBars(\n group: SVGGElement,\n model: GanttRenderModel,\n tasks: GanttTask[],\n startY: number,\n endY: number\n ): void {\n const taskById = new Map(tasks.map((t) => [t.id, t]));\n for (const bar of model.bars) {\n if (bar.y + bar.height < startY || bar.y > endY) continue;\n const task = taskById.get(bar.taskId);\n group.appendChild(this.renderBar(bar, task, model));\n }\n }\n\n private renderBar(\n bar: GanttRenderBar,\n task: GanttTask | undefined,\n model: GanttRenderModel\n ): SVGGElement {\n const g = svgEl(\"g\");\n g.setAttribute(\"class\", \"gantt-bar\");\n g.dataset.ganttBar = bar.taskId;\n g.setAttribute(\"transform\", `translate(${bar.x}, ${bar.y})`);\n\n if (task?.notes) {\n const title = svgEl(\"title\");\n title.textContent = task.notes;\n g.appendChild(title);\n }\n\n if (this.options.keyboardAccessible) {\n g.setAttribute(\"tabindex\", \"0\");\n g.setAttribute(\"role\", \"button\");\n if (task) {\n const progress = Math.round(task.progress ?? 0);\n const label = `${task.name}, ${task.start.toDateString()} to ${task.end.toDateString()}, ${progress}% complete`;\n g.setAttribute(\"aria-label\", label);\n }\n }\n\n if (bar.baseline) {\n const baseline = svgEl(\"rect\");\n baseline.setAttribute(\"x\", String(bar.baseline.x - bar.x));\n baseline.setAttribute(\"y\", \"-2\");\n baseline.setAttribute(\"width\", String(bar.baseline.width));\n baseline.setAttribute(\"height\", String(bar.height + 4));\n baseline.style.fill = themedFill(\"baselineColor\", model.theme.baselineColor);\n baseline.setAttribute(\"opacity\", \"0.35\");\n baseline.setAttribute(\"rx\", String(model.theme.borderRadius));\n g.appendChild(baseline);\n }\n\n if (bar.baselines && bar.baselines.length > 0) {\n // Oldest snapshot stacked furthest back (largest offset), most recent nearest the live bar.\n bar.baselines.forEach((b, i) => {\n const offset = (bar.baselines!.length - i) * 2;\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", String(b.x - bar.x));\n rect.setAttribute(\"y\", String(-2 - offset));\n rect.setAttribute(\"width\", String(b.width));\n rect.setAttribute(\"height\", \"3\");\n rect.style.fill = themedFill(\"baselineColor\", model.theme.baselineColor);\n rect.setAttribute(\"opacity\", String(Math.max(0.15, 0.4 - i * 0.08)));\n if (b.label) {\n const title = svgEl(\"title\");\n title.textContent = b.label;\n rect.appendChild(title);\n }\n g.appendChild(rect);\n });\n }\n\n // task.color/progressColor are per-task JS overrides baked in by layout.ts — keep those\n // literal (highest priority, per-element). A bar left at the theme default is routed\n // through var(--gantt-x, default) instead, so plain CSS can restyle \"every default bar\".\n const isDefaultBarColor = bar.color === (task?.isGroup ? model.theme.groupBarColor : model.theme.barColor);\n const isDefaultProgressColor = bar.progressColor === model.theme.barProgressColor;\n const fillColor = bar.isCritical\n ? themedFill(\"criticalColor\", model.theme.criticalColor)\n : isDefaultBarColor\n ? themedFill(task?.isGroup ? \"groupBarColor\" : \"barColor\", bar.color)\n : bar.color;\n\n if (bar.isMilestone) {\n const size = bar.height * 0.8;\n const diamond = svgEl(\"rect\");\n diamond.setAttribute(\"x\", String(-size / 2));\n diamond.setAttribute(\"y\", String((bar.height - size) / 2));\n diamond.setAttribute(\"width\", String(size));\n diamond.setAttribute(\"height\", String(size));\n diamond.style.fill = fillColor;\n diamond.setAttribute(\n \"transform\",\n `rotate(45, 0, ${bar.height / 2})`\n );\n g.appendChild(diamond);\n const label = svgEl(\"text\");\n label.setAttribute(\"x\", String(size / 2 + 8));\n label.setAttribute(\"y\", String(bar.height / 2 + 4));\n label.style.fill = themedFill(\"textColor\", model.theme.textColor);\n label.setAttribute(\"font-size\", String(model.theme.fontSize));\n label.setAttribute(\"font-family\", model.theme.fontFamily);\n label.textContent = bar.label;\n g.appendChild(label);\n return g;\n }\n\n if (bar.segments && bar.segments.length > 0) {\n // Split task: draw each segment as its own body+progress rect, joined by a thin dashed connector.\n bar.segments.forEach((seg, i) => {\n const segRect = svgEl(\"rect\");\n segRect.setAttribute(\"x\", String(seg.x));\n segRect.setAttribute(\"y\", \"0\");\n segRect.setAttribute(\"width\", String(seg.width));\n segRect.setAttribute(\"height\", String(bar.height));\n segRect.setAttribute(\"rx\", String(model.theme.borderRadius));\n segRect.style.fill = fillColor;\n if (bar.isCritical) {\n segRect.style.stroke = themedFill(\"criticalColor\", model.theme.criticalColor);\n segRect.setAttribute(\"stroke-width\", \"1.5\");\n }\n g.appendChild(segRect);\n\n if (seg.progressWidth > 0) {\n const segProgress = svgEl(\"rect\");\n segProgress.setAttribute(\"x\", String(seg.x));\n segProgress.setAttribute(\"y\", \"0\");\n segProgress.setAttribute(\"width\", String(seg.progressWidth));\n segProgress.setAttribute(\"height\", String(bar.height));\n segProgress.setAttribute(\"rx\", String(model.theme.borderRadius));\n segProgress.style.fill = isDefaultProgressColor\n ? themedFill(\"barProgressColor\", bar.progressColor)\n : bar.progressColor;\n g.appendChild(segProgress);\n }\n\n const next = bar.segments![i + 1];\n if (next) {\n const connector = svgEl(\"line\");\n connector.setAttribute(\"x1\", String(seg.x + seg.width));\n connector.setAttribute(\"x2\", String(next.x));\n connector.setAttribute(\"y1\", String(bar.height / 2));\n connector.setAttribute(\"y2\", String(bar.height / 2));\n connector.style.stroke = fillColor;\n connector.setAttribute(\"stroke-width\", \"1.5\");\n connector.setAttribute(\"stroke-dasharray\", \"3 2\");\n g.appendChild(connector);\n }\n });\n } else {\n const rect = svgEl(\"rect\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n rect.setAttribute(\"width\", String(bar.width));\n rect.setAttribute(\"height\", String(bar.height));\n rect.setAttribute(\"rx\", String(model.theme.borderRadius));\n rect.style.fill = fillColor;\n if (bar.isCritical) {\n rect.style.stroke = themedFill(\"criticalColor\", model.theme.criticalColor);\n rect.setAttribute(\"stroke-width\", \"1.5\");\n }\n g.appendChild(rect);\n\n if (bar.progressWidth > 0) {\n const progressRect = svgEl(\"rect\");\n progressRect.setAttribute(\"x\", \"0\");\n progressRect.setAttribute(\"y\", \"0\");\n progressRect.setAttribute(\"width\", String(bar.progressWidth));\n progressRect.setAttribute(\"height\", String(bar.height));\n progressRect.setAttribute(\"rx\", String(model.theme.borderRadius));\n progressRect.style.fill = isDefaultProgressColor\n ? themedFill(\"barProgressColor\", bar.progressColor)\n : bar.progressColor;\n g.appendChild(progressRect);\n }\n }\n\n if (bar.isSelected) {\n const selectionOutline = svgEl(\"rect\");\n selectionOutline.setAttribute(\"x\", \"-2\");\n selectionOutline.setAttribute(\"y\", \"-2\");\n selectionOutline.setAttribute(\"width\", String(bar.width + 4));\n selectionOutline.setAttribute(\"height\", String(bar.height + 4));\n selectionOutline.setAttribute(\"rx\", String(model.theme.borderRadius + 2));\n selectionOutline.setAttribute(\"fill\", \"none\");\n selectionOutline.style.stroke = themedFill(\"selectionColor\", model.theme.selectionColor);\n selectionOutline.setAttribute(\"stroke-width\", \"2\");\n g.appendChild(selectionOutline);\n }\n\n const handleWidth = 6;\n const leftHandle = svgEl(\"rect\");\n leftHandle.setAttribute(\"x\", \"0\");\n leftHandle.setAttribute(\"y\", \"0\");\n leftHandle.setAttribute(\"width\", String(handleWidth));\n leftHandle.setAttribute(\"height\", String(bar.height));\n leftHandle.setAttribute(\"fill\", \"transparent\");\n leftHandle.dataset.ganttHandle = \"left\";\n leftHandle.dataset.ganttHandleFor = bar.taskId;\n leftHandle.style.cursor = \"ew-resize\";\n g.appendChild(leftHandle);\n\n const rightHandle = svgEl(\"rect\");\n rightHandle.setAttribute(\"x\", String(Math.max(0, bar.width - handleWidth)));\n rightHandle.setAttribute(\"y\", \"0\");\n rightHandle.setAttribute(\"width\", String(handleWidth));\n rightHandle.setAttribute(\"height\", String(bar.height));\n rightHandle.setAttribute(\"fill\", \"transparent\");\n rightHandle.dataset.ganttHandle = \"right\";\n rightHandle.dataset.ganttHandleFor = bar.taskId;\n rightHandle.style.cursor = \"ew-resize\";\n g.appendChild(rightHandle);\n\n const connector = svgEl(\"circle\");\n connector.setAttribute(\"cx\", String(bar.width));\n connector.setAttribute(\"cy\", String(bar.height / 2));\n connector.setAttribute(\"r\", \"4\");\n connector.style.fill = themedFill(\"linkColor\", model.theme.linkColor);\n connector.dataset.ganttConnector = bar.taskId;\n connector.dataset.ganttConnectorSide = \"right\";\n connector.style.cursor = \"crosshair\";\n g.appendChild(connector);\n\n const label = svgEl(\"text\");\n label.setAttribute(\"x\", String(bar.width + 6));\n label.setAttribute(\"y\", String(bar.height / 2 + 4));\n label.style.fill = themedFill(\"textColor\", model.theme.textColor);\n label.setAttribute(\"font-size\", String(model.theme.fontSize));\n label.setAttribute(\"font-family\", model.theme.fontFamily);\n label.textContent = bar.label;\n g.appendChild(label);\n\n if (bar.deadlineX !== undefined) {\n const markerX = bar.deadlineX - bar.x;\n const flag = svgEl(\"g\");\n flag.setAttribute(\"transform\", `translate(${markerX}, -6)`);\n const pole = svgEl(\"line\");\n pole.setAttribute(\"x1\", \"0\");\n pole.setAttribute(\"x2\", \"0\");\n pole.setAttribute(\"y1\", \"0\");\n pole.setAttribute(\"y2\", String(bar.height + 6));\n const deadlineColor = bar.isOverdue\n ? themedFill(\"criticalColor\", model.theme.criticalColor)\n : themedFill(\"deadlineColor\", model.theme.deadlineColor);\n pole.style.stroke = deadlineColor;\n pole.setAttribute(\"stroke-width\", \"1.5\");\n flag.appendChild(pole);\n const pennant = svgEl(\"path\");\n pennant.setAttribute(\"d\", \"M0,0 L7,3 L0,6 Z\");\n pennant.style.fill = deadlineColor;\n flag.appendChild(pennant);\n g.appendChild(flag);\n }\n\n if (this.options.showAssigneeAvatars && task?.assignees?.length) {\n let ax = -10;\n for (const assignee of task.assignees.slice(0, 3)) {\n const avatarGroup = svgEl(\"g\");\n avatarGroup.setAttribute(\"transform\", `translate(${ax}, ${bar.height / 2})`);\n if (assignee.avatarUrl) {\n const image = svgEl(\"image\");\n image.setAttribute(\"href\", assignee.avatarUrl);\n image.setAttribute(\"x\", \"-8\");\n image.setAttribute(\"y\", \"-8\");\n image.setAttribute(\"width\", \"16\");\n image.setAttribute(\"height\", \"16\");\n image.setAttribute(\"clip-path\", \"circle(8px at 8px 8px)\");\n avatarGroup.appendChild(image);\n } else {\n const circle = svgEl(\"circle\");\n circle.setAttribute(\"r\", \"8\");\n circle.style.fill = assignee.color ?? themedFill(\"groupBarColor\", model.theme.groupBarColor);\n avatarGroup.appendChild(circle);\n const text = svgEl(\"text\");\n text.setAttribute(\"text-anchor\", \"middle\");\n text.setAttribute(\"y\", \"3\");\n text.setAttribute(\"font-size\", \"8\");\n text.setAttribute(\"fill\", \"#fff\");\n text.textContent = initials(assignee.name);\n avatarGroup.appendChild(text);\n }\n g.appendChild(avatarGroup);\n ax -= 18;\n }\n }\n\n return g;\n }\n\n private renderLinks(\n group: SVGGElement,\n model: GanttRenderModel,\n startY: number,\n endY: number\n ): void {\n const barByTaskId = new Map(model.bars.map((b) => [b.taskId, b]));\n for (const link of model.links) {\n const fromBar = barByTaskId.get(link.fromId);\n const toBar = barByTaskId.get(link.toId);\n const relevantY = toBar?.y ?? fromBar?.y ?? 0;\n if (relevantY < startY || relevantY > endY) continue;\n\n const path = svgEl(\"path\");\n path.setAttribute(\"d\", link.path);\n path.setAttribute(\"fill\", \"none\");\n path.style.stroke = link.isCritical\n ? themedFill(\"criticalColor\", model.theme.criticalColor)\n : themedFill(\"linkColor\", model.theme.linkColor);\n path.setAttribute(\"stroke-width\", link.isCritical ? \"2\" : \"1.5\");\n path.setAttribute(\"marker-end\", `url(#${this.markerDefsId})`);\n path.dataset.ganttLink = `${link.fromId}->${link.toId}`;\n group.appendChild(path);\n }\n }\n\n toSVGString(): string {\n return new XMLSerializer().serializeToString(this.svg);\n }\n\n destroy(): void {\n if (this.scrollListener) {\n this.timelineScroll.removeEventListener(\"scroll\", this.scrollListener);\n }\n this.gridPanel.removeEventListener(\"dblclick\", this.onGridDoubleClick);\n this.root.remove();\n }\n}\n","import type { GanttTask } from \"./types\";\n\n/** A readable, colorblind-considerate categorical palette; cycles if there are more distinct values than colors. */\nexport const DEFAULT_PALETTE = [\n \"#3b82f6\", // blue\n \"#f59e0b\", // amber\n \"#10b981\", // emerald\n \"#ef4444\", // red\n \"#8b5cf6\", // violet\n \"#06b6d4\", // cyan\n \"#f97316\", // orange\n \"#84cc16\", // lime\n \"#ec4899\", // pink\n \"#64748b\", // slate\n];\n\n/**\n * Assign a stable color to each distinct value of `field(task)` across `tasks`,\n * cycling through `palette` in first-seen order. Pure - returns a lookup map,\n * doesn't touch the tasks themselves (use with `applyColorByField` or your own\n * `task.color = colors.get(field(task))` loop).\n */\nexport function colorByField(\n tasks: GanttTask[],\n field: (task: GanttTask) => string | null | undefined,\n palette: string[] = DEFAULT_PALETTE\n): Map<string, string> {\n const colors = new Map<string, string>();\n if (palette.length === 0) return colors;\n for (const task of tasks) {\n const value = field(task);\n if (value === null || value === undefined || colors.has(value)) continue;\n colors.set(value, palette[colors.size % palette.length]!);\n }\n return colors;\n}\n\n/** Convenience wrapper: returns a new tasks array with `.color` set from `colorByField`'s result (a task's existing `.color` wins if already set). */\nexport function applyColorByField(\n tasks: GanttTask[],\n field: (task: GanttTask) => string | null | undefined,\n palette: string[] = DEFAULT_PALETTE\n): GanttTask[] {\n const colors = colorByField(tasks, field, palette);\n return tasks.map((task) => {\n if (task.color) return task;\n const value = field(task);\n const color = value === null || value === undefined ? undefined : colors.get(value);\n return color ? { ...task, color } : task;\n });\n}\n","/**\n * MSP-style task constraint types.\n *\n * \"asap\" and \"alap\" are intentionally no-ops in this engine: a true ALAP\n * (as-late-as-possible) schedule requires a backward pass from the project\n * end date, which isn't something a purely local, per-drag/per-cascade\n * engine can do without a full re-solve. The other six are hard date\n * constraints applied locally, which fit the same incremental model used\n * by dependency cascading.\n */\nexport type ConstraintType =\n | \"asap\"\n | \"alap\"\n | \"snet\" // start no earlier than\n | \"snlt\" // start no later than\n | \"fnet\" // finish no earlier than\n | \"fnlt\" // finish no later than\n | \"mso\" // must start on\n | \"mfo\"; // must finish on\n\nexport interface DateRange {\n start: Date;\n end: Date;\n}\n\n/**\n * Adjust [start, end] to satisfy a constraint, preserving the task's\n * duration. No-op if `constraintType` or `constraintDate` is unset, or the\n * range already satisfies the constraint.\n */\nexport function applyConstraint(\n range: DateRange,\n constraintType: ConstraintType | undefined,\n constraintDate: Date | undefined\n): DateRange {\n if (!constraintType || !constraintDate) return range;\n const duration = range.end.getTime() - range.start.getTime();\n const cd = constraintDate.getTime();\n\n switch (constraintType) {\n case \"mso\":\n return { start: new Date(cd), end: new Date(cd + duration) };\n case \"mfo\":\n return { start: new Date(cd - duration), end: new Date(cd) };\n case \"snet\":\n if (range.start.getTime() >= cd) return range;\n return { start: new Date(cd), end: new Date(cd + duration) };\n case \"snlt\":\n if (range.start.getTime() <= cd) return range;\n return { start: new Date(cd), end: new Date(cd + duration) };\n case \"fnet\":\n if (range.end.getTime() >= cd) return range;\n return { start: new Date(cd - duration), end: new Date(cd) };\n case \"fnlt\":\n if (range.end.getTime() <= cd) return range;\n return { start: new Date(cd - duration), end: new Date(cd) };\n case \"asap\":\n case \"alap\":\n return range;\n }\n}\n","import type { GanttTask } from \"./types\";\n\n/**\n * Compute Work Breakdown Structure codes (\"1\", \"1.1\", \"1.2\", \"2\", ...) from\n * task parent/child nesting, in document (array) order among siblings.\n *\n * Returned as a plain Map rather than mutating tasks, matching the library's\n * \"everything is a plain object, the chart never owns your state\" principle -\n * wire it into a grid column via `column.accessor` if you want it displayed:\n *\n * const wbs = computeWBSCodes(tasks);\n * columns: [{ id: \"wbs\", title: \"WBS\", accessor: (t) => wbs.get(t.id) }]\n *\n * A task whose `parentId` doesn't resolve to another task in the list is\n * treated as a root, same as an unset `parentId`.\n */\nexport function computeWBSCodes(tasks: GanttTask[]): Map<string, string> {\n const ids = new Set(tasks.map((t) => t.id));\n const effectiveParent = (task: GanttTask): string | null =>\n task.parentId && ids.has(task.parentId) ? task.parentId : null;\n\n const childrenByParent = new Map<string | null, GanttTask[]>();\n for (const task of tasks) {\n const key = effectiveParent(task);\n const list = childrenByParent.get(key) ?? [];\n list.push(task);\n childrenByParent.set(key, list);\n }\n\n const codes = new Map<string, string>();\n function assign(parentId: string | null, prefix: string): void {\n const children = childrenByParent.get(parentId) ?? [];\n children.forEach((task, index) => {\n const code = prefix ? `${prefix}.${index + 1}` : `${index + 1}`;\n codes.set(task.id, code);\n assign(task.id, code);\n });\n }\n assign(null, \"\");\n\n return codes;\n}\n","import { isWorkingDay, type WorkingCalendar } from \"./calendar\";\nimport { MS_PER_DAY } from \"./date-utils\";\nimport type { GanttTask } from \"./types\";\n\nexport interface ResourceHistogramOptions {\n /** hours a resource is assumed available per working day. Default 8. */\n capacityHoursPerDay?: number;\n /** governs which days count as \"working\" for allocation purposes. Non-working days get 0 load. */\n calendar?: WorkingCalendar;\n}\n\nexport interface ResourceLoadBucket {\n assigneeId: string;\n assigneeName: string;\n /** start of the day this bucket represents */\n date: Date;\n /** hours allocated to this assignee across all tasks spanning this day */\n allocatedHours: number;\n capacityHours: number;\n overallocated: boolean;\n}\n\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/**\n * Bucket every task's assignees by calendar day, summing one full day's\n * capacity worth of allocation per assignee per working day the task spans\n * (milestones and non-working days contribute nothing). This is a simple\n * \"fully allocated while active\" model, not a percent-effort model - tasks\n * don't carry an effort/FTE field, so it's the only allocation the plain\n * task/assignee data can support without inventing new required fields.\n */\nexport function computeResourceHistogram(\n tasks: GanttTask[],\n options: ResourceHistogramOptions = {}\n): ResourceLoadBucket[] {\n const capacityHours = options.capacityHoursPerDay ?? 8;\n const buckets = new Map<string, ResourceLoadBucket>(); // key: `${assigneeId}|${isoDay}`\n\n for (const task of tasks) {\n if (!task.assignees || task.assignees.length === 0) continue;\n if (!(task.start instanceof Date) || !(task.end instanceof Date)) continue;\n if (task.end.getTime() <= task.start.getTime()) continue; // milestone or zero-length\n\n let cursor = startOfDay(task.start);\n const end = task.end;\n let guard = 0;\n while (cursor.getTime() < end.getTime() && guard++ < 3660) {\n if (isWorkingDay(cursor, options.calendar)) {\n for (const assignee of task.assignees) {\n const key = `${assignee.id}|${cursor.getTime()}`;\n const existing = buckets.get(key);\n if (existing) {\n existing.allocatedHours += capacityHours;\n } else {\n buckets.set(key, {\n assigneeId: assignee.id,\n assigneeName: assignee.name,\n date: new Date(cursor.getTime()),\n allocatedHours: capacityHours,\n capacityHours,\n overallocated: false,\n });\n }\n }\n }\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n }\n }\n\n const result = Array.from(buckets.values());\n for (const bucket of result) {\n bucket.overallocated = bucket.allocatedHours > bucket.capacityHours;\n }\n result.sort((a, b) => a.date.getTime() - b.date.getTime() || a.assigneeId.localeCompare(b.assigneeId));\n return result;\n}\n\n/**\n * Render a resource histogram as a standalone SVG string: one grouped column\n * of stacked bars per day, one bar per assignee, red when overallocated.\n * Framework-agnostic like the rest of gantt-core - drop the string into an\n * `<div>` via `innerHTML` or a data URI, no DOM dependency required to call it.\n */\nexport function renderResourceHistogramSVG(\n buckets: ResourceLoadBucket[],\n options: { width?: number; barWidth?: number; maxBarHeight?: number; overallocatedColor?: string; barColor?: string } = {}\n): string {\n const barWidth = options.barWidth ?? 14;\n const gap = 4;\n const maxBarHeight = options.maxBarHeight ?? 120;\n const barColor = options.barColor ?? \"#3b82f6\";\n const overColor = options.overallocatedColor ?? \"#dc2626\";\n\n const days = Array.from(new Set(buckets.map((b) => b.date.getTime()))).sort((a, b) => a - b);\n const assigneesByDay = new Map<number, ResourceLoadBucket[]>();\n for (const b of buckets) {\n const list = assigneesByDay.get(b.date.getTime()) ?? [];\n list.push(b);\n assigneesByDay.set(b.date.getTime(), list);\n }\n\n const maxHours = buckets.reduce((m, b) => Math.max(m, b.allocatedHours), 1);\n const dayWidth = (assigneesByDay.get(days[0] ?? 0)?.length ?? 1) * (barWidth + gap) + gap;\n const width = options.width ?? Math.max(dayWidth * days.length, 100);\n const height = maxBarHeight + 24;\n\n const parts: string[] = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\">`,\n ];\n\n days.forEach((day, dayIndex) => {\n const dayBuckets = assigneesByDay.get(day) ?? [];\n dayBuckets.forEach((b, i) => {\n const x = dayIndex * dayWidth + gap + i * (barWidth + gap);\n const barHeight = Math.min(maxBarHeight, (b.allocatedHours / maxHours) * maxBarHeight);\n const y = maxBarHeight - barHeight;\n const fill = b.overallocated ? overColor : barColor;\n parts.push(\n `<rect x=\"${x}\" y=\"${y}\" width=\"${barWidth}\" height=\"${barHeight}\" fill=\"${fill}\"><title>${escapeXml(\n b.assigneeName\n )}: ${b.allocatedHours}h</title></rect>`\n );\n });\n });\n\n parts.push(`</svg>`);\n return parts.join(\"\");\n}\n\nfunction escapeXml(text: string): string {\n return text.replace(/[&<>\"']/g, (c) => {\n switch (c) {\n case \"&\":\n return \"&\";\n case \"<\":\n return \"<\";\n case \">\":\n return \">\";\n case '\"':\n return \""\";\n default:\n return \"'\";\n }\n });\n}\n","import type { GanttTask } from \"./types\";\n\nexport interface FilterTasksOptions {\n /** keep ancestors of a matched task so its tree path stays intact. Default true. */\n includeAncestors?: boolean;\n /** keep descendants of a matched task (e.g. a matched group's children). Default true. */\n includeDescendants?: boolean;\n}\n\nexport interface FilterTasksResult {\n /** the subset of `tasks` to keep, in original order - pass straight to the chart's `tasks` prop/setTasks to hide the rest */\n tasks: GanttTask[];\n /** ids that satisfied `predicate` directly, as opposed to being pulled in via includeAncestors/includeDescendants - use to dim rows that are shown only for tree context */\n matchedIds: Set<string>;\n}\n\n/**\n * Filter tasks by a predicate while keeping the tree intact: a matched\n * task's ancestors stay (so it doesn't vanish along with a non-matching\n * parent) and, by default, its descendants stay too (so a matched group\n * doesn't show with its children silently missing).\n *\n * This only computes the subset - hook it up by passing `result.tasks` as\n * the chart's `tasks` (non-matches are hidden because they're no longer in\n * the array, same as any other plain-data filter), and optionally use\n * `result.matchedIds` to visually dim tasks that are present only for tree\n * context (e.g. via a `column.accessor` or `task.color` override).\n */\nexport function filterTasks(\n tasks: GanttTask[],\n predicate: (task: GanttTask) => boolean,\n options: FilterTasksOptions = {}\n): FilterTasksResult {\n const includeAncestors = options.includeAncestors ?? true;\n const includeDescendants = options.includeDescendants ?? true;\n\n const byId = new Map(tasks.map((t) => [t.id, t]));\n const matchedIds = new Set(tasks.filter(predicate).map((t) => t.id));\n const keep = new Set(matchedIds);\n\n if (includeAncestors) {\n for (const id of matchedIds) {\n let current = byId.get(id);\n while (current?.parentId) {\n const parent = byId.get(current.parentId);\n if (!parent || keep.has(parent.id)) break;\n keep.add(parent.id);\n current = parent;\n }\n }\n }\n\n if (includeDescendants) {\n const childrenByParent = new Map<string, GanttTask[]>();\n for (const t of tasks) {\n if (!t.parentId) continue;\n const list = childrenByParent.get(t.parentId) ?? [];\n list.push(t);\n childrenByParent.set(t.parentId, list);\n }\n const stack = Array.from(matchedIds);\n while (stack.length > 0) {\n const id = stack.pop();\n if (id === undefined) continue;\n for (const child of childrenByParent.get(id) ?? []) {\n if (keep.has(child.id)) continue;\n keep.add(child.id);\n stack.push(child.id);\n }\n }\n }\n\n return { tasks: tasks.filter((t) => keep.has(t.id)), matchedIds };\n}\n","import { isWorkingDay, type WorkingCalendar } from \"./calendar\";\nimport { MS_PER_DAY } from \"./date-utils\";\nimport type { GanttDependency, GanttTask } from \"./types\";\n\nexport interface ResourceLevelingOptions {\n calendar?: WorkingCalendar;\n}\n\nexport interface ResourceLevelingResult {\n /** same tasks, same order - shifted ones are shallow clones with new start/end (duration preserved) */\n tasks: GanttTask[];\n shifted: { taskId: string; delayMs: number }[];\n}\n\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction workingDaySpan(start: Date, end: Date, calendar?: WorkingCalendar): number[] {\n const days: number[] = [];\n let cursor = startOfDay(start);\n let guard = 0;\n while (cursor.getTime() < end.getTime() && guard++ < 3660) {\n if (isWorkingDay(cursor, calendar)) days.push(cursor.getTime());\n cursor = new Date(cursor.getTime() + MS_PER_DAY);\n }\n return days;\n}\n\n/**\n * Resolve resource overallocation by delaying tasks (never pulling them\n * earlier) so no assignee is placed on more than one task on the same\n * working day - the same \"fully allocated while active\" model\n * computeResourceHistogram uses, so a leveled schedule always shows zero\n * `overallocated` buckets afterward.\n *\n * Tasks are processed in an order that respects FS (\"finish-to-start\")\n * dependencies (a task never gets placed before its FS predecessors\n * finish); SS/FF/SF dependencies aren't specifically enforced by the\n * leveler - a reasonable, documented scope limit rather than a full\n * constraint solver.\n */\nexport function levelResources(\n tasks: GanttTask[],\n dependencies: GanttDependency[],\n options: ResourceLevelingOptions = {}\n): ResourceLevelingResult {\n const calendar = options.calendar;\n const byId = new Map(tasks.map((t) => [t.id, t]));\n\n const fsPredecessors = new Map<string, string[]>();\n const fsSuccessors = new Map<string, string[]>();\n for (const dep of dependencies) {\n if (dep.type !== \"FS\") continue;\n if (!byId.has(dep.fromId) || !byId.has(dep.toId)) continue;\n const preds = fsPredecessors.get(dep.toId) ?? [];\n preds.push(dep.fromId);\n fsPredecessors.set(dep.toId, preds);\n const succs = fsSuccessors.get(dep.fromId) ?? [];\n succs.push(dep.toId);\n fsSuccessors.set(dep.fromId, succs);\n }\n\n // Kahn's-algorithm topological order over the FS subgraph, ties broken by original start date.\n const indegree = new Map<string, number>();\n for (const t of tasks) indegree.set(t.id, (fsPredecessors.get(t.id) ?? []).length);\n const queue = tasks.filter((t) => indegree.get(t.id) === 0);\n const order: GanttTask[] = [];\n const seen = new Set<string>();\n let guard = 0;\n while (queue.length > 0 && guard++ < tasks.length * 2 + 10) {\n queue.sort((a, b) => a.start.getTime() - b.start.getTime());\n const t = queue.shift();\n if (!t || seen.has(t.id)) continue;\n seen.add(t.id);\n order.push(t);\n for (const nextId of fsSuccessors.get(t.id) ?? []) {\n const d = (indegree.get(nextId) ?? 0) - 1;\n indegree.set(nextId, d);\n if (d === 0) {\n const nt = byId.get(nextId);\n if (nt) queue.push(nt);\n }\n }\n }\n for (const t of tasks) if (!seen.has(t.id)) order.push(t); // cycle fallback: keep original order\n\n const placedById = new Map<string, { start: Date; end: Date }>();\n const occupiedDays = new Map<string, Set<number>>(); // assigneeId -> set of working-day timestamps\n const shifted: ResourceLevelingResult[\"shifted\"] = [];\n\n for (const task of order) {\n const duration = task.end.getTime() - task.start.getTime();\n let start = new Date(task.start.getTime());\n\n for (const predId of fsPredecessors.get(task.id) ?? []) {\n const placed = placedById.get(predId);\n if (placed && placed.end.getTime() > start.getTime()) start = new Date(placed.end.getTime());\n }\n\n if (task.assignees && task.assignees.length > 0 && duration > 0) {\n let levelGuard = 0;\n while (levelGuard++ < 400) {\n const end = new Date(start.getTime() + duration);\n const days = workingDaySpan(start, end, calendar);\n const conflict = task.assignees.some((a) => {\n const set = occupiedDays.get(a.id);\n return set && days.some((d) => set.has(d));\n });\n if (!conflict) break;\n start = new Date(start.getTime() + MS_PER_DAY);\n while (!isWorkingDay(start, calendar)) start = new Date(start.getTime() + MS_PER_DAY);\n }\n const end = new Date(start.getTime() + duration);\n const days = workingDaySpan(start, end, calendar);\n for (const a of task.assignees) {\n const set = occupiedDays.get(a.id) ?? new Set<number>();\n for (const d of days) set.add(d);\n occupiedDays.set(a.id, set);\n }\n }\n\n const end = new Date(start.getTime() + duration);\n placedById.set(task.id, { start, end });\n const delayMs = start.getTime() - task.start.getTime();\n if (delayMs !== 0) shifted.push({ taskId: task.id, delayMs });\n }\n\n const resultById = new Map<string, GanttTask>();\n for (const task of order) {\n const placed = placedById.get(task.id);\n resultById.set(task.id, placed && placed.start.getTime() !== task.start.getTime() ? { ...task, ...placed } : task);\n }\n\n return { tasks: tasks.map((t) => resultById.get(t.id) ?? t), shifted };\n}\n","import { addUnit, MS_PER_DAY } from \"./date-utils\";\nimport type { ViewMode } from \"./types\";\n\nexport interface InteractionCallbacks {\n onMove(taskId: string, dxMs: number): void;\n onResize(taskId: string, edge: \"left\" | \"right\", dxMs: number): void;\n onLinkStart(taskId: string, anchor: \"left\" | \"right\"): void;\n onLinkComplete(fromId: string, toId: string): void;\n onLinkCancel(): void;\n onToggleCollapse(taskId: string): void;\n onBarClick(taskId: string, modifiers?: { ctrlKey: boolean; metaKey: boolean; shiftKey: boolean }): void;\n onProgressDrag(taskId: string, newProgress: number): void;\n onContextMenu?(taskId: string, evt: PointerEvent): void;\n /** fired on pointerup after a drag-to-create gesture on an empty row; x's are svg-relative px */\n onCreateTaskDrag?(rowTaskId: string, startXPx: number, endXPx: number): void;\n /** fired on double-click of a dependency link path */\n onLinkDblClick?(fromId: string, toId: string): void;\n /** Ctrl/Cmd+A anywhere in the chart, when keyboardAccessible */\n onSelectAll?(): void;\n /** Home anywhere in the chart, when keyboardAccessible */\n onJumpToStart?(): void;\n /** End anywhere in the chart, when keyboardAccessible */\n onJumpToEnd?(): void;\n}\n\nexport interface InteractionOptions {\n readonly?: boolean;\n isTaskReadonly?: (taskId: string) => boolean;\n keyboardAccessible?: boolean;\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n pxPerMs: () => number;\n}\n\ntype DragMode = \"move\" | \"resize-left\" | \"resize-right\" | \"link\" | \"create\" | null;\n\nfunction snapDeltaMs(dxMs: number, snapToUnit: InteractionOptions[\"snapToUnit\"]): number {\n if (!snapToUnit) return dxMs;\n const base = new Date(0);\n const unitMs = addUnit(base, snapToUnit as ViewMode, 1).getTime() - base.getTime();\n if (unitMs <= 0) return dxMs;\n return Math.round(dxMs / unitMs) * unitMs;\n}\n\nexport class InteractionController {\n private dragMode: DragMode = null;\n private dragTaskId: string | null = null;\n private dragStartX = 0;\n private linkFromId: string | null = null;\n private linkFromAnchor: \"left\" | \"right\" | null = null;\n private tempLinkEl: SVGLineElement | null = null;\n private rafHandle: number | null = null;\n private pendingDxMs = 0;\n private pendingMode: \"move\" | \"resize-left\" | \"resize-right\" | null = null;\n\n constructor(\n private svg: SVGSVGElement,\n private gridPanel: HTMLElement,\n private callbacks: InteractionCallbacks,\n private options: InteractionOptions\n ) {\n this.attach();\n }\n\n private isReadonly(taskId: string): boolean {\n if (this.options.readonly) return true;\n return this.options.isTaskReadonly?.(taskId) ?? false;\n }\n\n private attach(): void {\n this.svg.addEventListener(\"pointerdown\", this.onPointerDown);\n this.gridPanel.addEventListener(\"click\", this.onGridClick);\n if (typeof document !== \"undefined\") {\n this.svg.addEventListener(\"contextmenu\", this.onContextMenu);\n this.svg.addEventListener(\"dblclick\", this.onSvgDoubleClick);\n this.svg.addEventListener(\"keydown\", this.onKeyDown);\n }\n }\n\n destroy(): void {\n this.svg.removeEventListener(\"pointerdown\", this.onPointerDown);\n this.gridPanel.removeEventListener(\"click\", this.onGridClick);\n this.svg.removeEventListener(\"contextmenu\", this.onContextMenu);\n this.svg.removeEventListener(\"dblclick\", this.onSvgDoubleClick);\n this.svg.removeEventListener(\"keydown\", this.onKeyDown);\n if (this.rafHandle !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(this.rafHandle);\n }\n }\n\n private onGridClick = (evt: MouseEvent): void => {\n const target = evt.target as HTMLElement;\n const toggleId = target.closest<HTMLElement>(\"[data-gantt-toggle]\")?.dataset.ganttToggle;\n if (toggleId) {\n this.callbacks.onToggleCollapse(toggleId);\n }\n };\n\n private onContextMenu = (evt: Event): void => {\n const pointerEvt = evt as PointerEvent;\n const target = pointerEvt.target as Element;\n const barGroup = target.closest<SVGGElement>(\"[data-gantt-bar]\");\n const taskId = barGroup?.dataset.ganttBar;\n if (taskId && this.callbacks.onContextMenu) {\n pointerEvt.preventDefault();\n this.callbacks.onContextMenu(taskId, pointerEvt);\n }\n };\n\n private onSvgDoubleClick = (evt: MouseEvent): void => {\n if (!this.callbacks.onLinkDblClick) return;\n const target = evt.target as Element;\n const linkPath = target.closest<SVGPathElement>(\"[data-gantt-link]\");\n const key = linkPath?.dataset.ganttLink;\n if (!key) return;\n const [fromId, toId] = key.split(\"->\");\n if (fromId && toId) this.callbacks.onLinkDblClick(fromId, toId);\n };\n\n private onPointerDown = (evt: PointerEvent): void => {\n const target = evt.target as Element;\n\n const connector = target.closest<SVGCircleElement>(\"[data-gantt-connector]\");\n if (connector) {\n const taskId = connector.dataset.ganttConnector;\n const side = (connector.dataset.ganttConnectorSide as \"left\" | \"right\") ?? \"right\";\n if (taskId) this.startLinkDrag(evt, taskId, side);\n return;\n }\n\n const handle = target.closest<SVGRectElement>(\"[data-gantt-handle]\");\n if (handle) {\n const taskId = handle.dataset.ganttHandleFor;\n const edge = handle.dataset.ganttHandle as \"left\" | \"right\";\n if (taskId && !this.isReadonly(taskId)) this.startResize(evt, taskId, edge);\n return;\n }\n\n const barGroup = target.closest<SVGGElement>(\"[data-gantt-bar]\");\n if (barGroup) {\n const taskId = barGroup.dataset.ganttBar;\n if (taskId) this.startMove(evt, taskId, barGroup);\n return;\n }\n\n const rowBg = target.closest<SVGRectElement>(\"[data-gantt-row-bg]\");\n if (rowBg && this.callbacks.onCreateTaskDrag && !this.options.readonly) {\n const taskId = rowBg.dataset.ganttRowBg;\n if (taskId) this.startCreateDrag(evt, taskId, rowBg);\n }\n };\n\n private startMove(evt: PointerEvent, taskId: string, barGroup: SVGGElement): void {\n if (this.isReadonly(taskId)) return;\n this.dragMode = \"move\";\n this.dragTaskId = taskId;\n this.dragStartX = evt.clientX;\n let moved = false;\n barGroup.setPointerCapture(evt.pointerId);\n\n const onMove = (moveEvt: PointerEvent) => {\n const dx = moveEvt.clientX - this.dragStartX;\n if (Math.abs(dx) > 2) moved = true;\n this.scheduleDeltaEmit(taskId, \"move\", dx);\n };\n const onUp = (upEvt: PointerEvent) => {\n barGroup.removeEventListener(\"pointermove\", onMove);\n barGroup.removeEventListener(\"pointerup\", onUp);\n this.flushPending();\n this.dragMode = null;\n this.dragTaskId = null;\n if (!moved) {\n this.callbacks.onBarClick(taskId, {\n ctrlKey: upEvt.ctrlKey,\n metaKey: upEvt.metaKey,\n shiftKey: upEvt.shiftKey,\n });\n }\n };\n barGroup.addEventListener(\"pointermove\", onMove);\n barGroup.addEventListener(\"pointerup\", onUp);\n }\n\n private startResize(evt: PointerEvent, taskId: string, edge: \"left\" | \"right\"): void {\n this.dragMode = edge === \"left\" ? \"resize-left\" : \"resize-right\";\n this.dragTaskId = taskId;\n this.dragStartX = evt.clientX;\n const target = evt.currentTarget as Element;\n const capture = target instanceof Element ? target : this.svg;\n (capture as SVGRectElement).setPointerCapture?.(evt.pointerId);\n\n const onMove = (moveEvt: PointerEvent) => {\n const dx = moveEvt.clientX - this.dragStartX;\n this.scheduleDeltaEmit(taskId, edge === \"left\" ? \"resize-left\" : \"resize-right\", dx);\n };\n const onUp = () => {\n this.svg.removeEventListener(\"pointermove\", onMove);\n this.svg.removeEventListener(\"pointerup\", onUp);\n this.flushPending();\n this.dragMode = null;\n this.dragTaskId = null;\n };\n this.svg.addEventListener(\"pointermove\", onMove);\n this.svg.addEventListener(\"pointerup\", onUp);\n }\n\n private scheduleDeltaEmit(\n taskId: string,\n mode: \"move\" | \"resize-left\" | \"resize-right\",\n dxPx: number\n ): void {\n const pxPerMs = this.options.pxPerMs();\n const dxMs = pxPerMs > 0 ? dxPx / pxPerMs : 0;\n this.pendingDxMs = snapDeltaMs(dxMs, this.options.snapToUnit);\n this.pendingMode = mode;\n if (this.rafHandle !== null) return;\n const raf =\n typeof requestAnimationFrame !== \"undefined\" ? requestAnimationFrame : (cb: () => void) => {\n cb();\n return 0;\n };\n this.rafHandle = raf(() => {\n this.rafHandle = null;\n if (!this.dragTaskId || !this.pendingMode) return;\n if (this.pendingMode === \"move\") {\n this.callbacks.onMove(taskId, this.pendingDxMs);\n } else {\n this.callbacks.onResize(\n taskId,\n this.pendingMode === \"resize-left\" ? \"left\" : \"right\",\n this.pendingDxMs\n );\n }\n });\n }\n\n private flushPending(): void {\n if (this.rafHandle !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(this.rafHandle);\n this.rafHandle = null;\n }\n }\n\n private startLinkDrag(evt: PointerEvent, taskId: string, anchor: \"left\" | \"right\"): void {\n this.dragMode = \"link\";\n this.linkFromId = taskId;\n this.linkFromAnchor = anchor;\n this.callbacks.onLinkStart(taskId, anchor);\n\n const svgPoint = (clientX: number, clientY: number) => {\n const rect = this.svg.getBoundingClientRect();\n return { x: clientX - rect.left + this.svg.scrollLeft, y: clientY - rect.top };\n };\n\n const startPos = svgPoint(evt.clientX, evt.clientY);\n const line = document.createElementNS(\"http://www.w3.org/2000/svg\", \"line\");\n line.setAttribute(\"x1\", String(startPos.x));\n line.setAttribute(\"y1\", String(startPos.y));\n line.setAttribute(\"x2\", String(startPos.x));\n line.setAttribute(\"y2\", String(startPos.y));\n line.setAttribute(\"stroke\", \"#94a3b8\");\n line.setAttribute(\"stroke-dasharray\", \"4 3\");\n line.classList.add(\"gantt-temp-link\");\n this.svg.appendChild(line);\n this.tempLinkEl = line;\n\n const onMove = (moveEvt: PointerEvent) => {\n const pos = svgPoint(moveEvt.clientX, moveEvt.clientY);\n line.setAttribute(\"x2\", String(pos.x));\n line.setAttribute(\"y2\", String(pos.y));\n };\n const onUp = (upEvt: PointerEvent) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n this.tempLinkEl?.remove();\n this.tempLinkEl = null;\n\n const target = document.elementFromPoint(upEvt.clientX, upEvt.clientY);\n const connector = target?.closest<SVGCircleElement>(\"[data-gantt-connector]\");\n const toId = connector?.dataset.ganttConnector;\n if (toId && this.linkFromId && toId !== this.linkFromId) {\n this.callbacks.onLinkComplete(this.linkFromId, toId);\n } else {\n this.callbacks.onLinkCancel();\n }\n this.dragMode = null;\n this.linkFromId = null;\n this.linkFromAnchor = null;\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }\n\n private startCreateDrag(evt: PointerEvent, rowTaskId: string, rowBg: SVGRectElement): void {\n this.dragMode = \"create\";\n const parent = rowBg.parentNode as SVGGElement | null;\n const rowY = Number(rowBg.getAttribute(\"y\") ?? \"0\");\n const rowHeight = Number(rowBg.getAttribute(\"height\") ?? \"0\");\n\n const svgX = (clientX: number): number => {\n const rect = this.svg.getBoundingClientRect();\n return clientX - rect.left + this.svg.scrollLeft;\n };\n\n const startX = svgX(evt.clientX);\n let moved = false;\n\n const preview = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n preview.setAttribute(\"y\", String(rowY + 2));\n preview.setAttribute(\"height\", String(Math.max(0, rowHeight - 4)));\n preview.setAttribute(\"x\", String(startX));\n preview.setAttribute(\"width\", \"0\");\n preview.setAttribute(\"fill\", \"currentColor\");\n preview.setAttribute(\"opacity\", \"0.25\");\n preview.classList.add(\"gantt-create-preview\");\n parent?.appendChild(preview);\n\n const onMove = (moveEvt: PointerEvent) => {\n const currentX = svgX(moveEvt.clientX);\n if (Math.abs(currentX - startX) > 2) moved = true;\n const x1 = Math.min(startX, currentX);\n const x2 = Math.max(startX, currentX);\n preview.setAttribute(\"x\", String(x1));\n preview.setAttribute(\"width\", String(x2 - x1));\n };\n const onUp = (upEvt: PointerEvent) => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n preview.remove();\n this.dragMode = null;\n if (moved) {\n const endX = svgX(upEvt.clientX);\n this.callbacks.onCreateTaskDrag?.(rowTaskId, Math.min(startX, endX), Math.max(startX, endX));\n }\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }\n\n /**\n * Delegates to handleBarKeyDown when a focused bar dispatched the event\n * (bars get tabindex=\"0\" when keyboardAccessible, so native Tab/Shift+Tab\n * traversal between them already works without any code here), and\n * otherwise checks the chart-wide shortcuts (Ctrl/Cmd+A, Home, End).\n */\n private onKeyDown = (evt: KeyboardEvent): void => {\n if (!this.options.keyboardAccessible) return;\n const target = evt.target as Element;\n const barGroup = target.closest?.(\"[data-gantt-bar]\");\n const taskId = barGroup?.getAttribute(\"data-gantt-bar\");\n if (taskId) {\n this.handleBarKeyDown(taskId, evt);\n return;\n }\n if ((evt.ctrlKey || evt.metaKey) && evt.key.toLowerCase() === \"a\") {\n evt.preventDefault();\n this.callbacks.onSelectAll?.();\n } else if (evt.key === \"Home\") {\n evt.preventDefault();\n this.callbacks.onJumpToStart?.();\n } else if (evt.key === \"End\") {\n evt.preventDefault();\n this.callbacks.onJumpToEnd?.();\n }\n };\n\n handleBarKeyDown(taskId: string, evt: KeyboardEvent): void {\n if (!this.options.keyboardAccessible) return;\n if (this.isReadonly(taskId)) return;\n if (evt.key === \"ArrowLeft\") {\n evt.preventDefault();\n this.callbacks.onMove(taskId, -MS_PER_DAY);\n } else if (evt.key === \"ArrowRight\") {\n evt.preventDefault();\n this.callbacks.onMove(taskId, MS_PER_DAY);\n } else if (evt.key === \"Enter\") {\n evt.preventDefault();\n this.callbacks.onBarClick(taskId);\n }\n }\n}\n"],"mappings":"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","names":["width","label","connector","startOfDay","startOfDay","end","days","linkPath","pxPerMs"]}
|